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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJVNcIIAAoJEKI6nJvDJaTU3a8QAM+fjhDMY5xpI6VIbxZaA2aR VUofw9/rdAtP1UdwtlSKBvCqpwwqt/U7zlMWU9v+UvTjYdHIf9SIDQoJnd+uEtwL roz/kNeB7WOVyxwbTJ2B5fjvPSN+mq8Rm8ANDcL8ZOGxxtt2Mip1IWMAlx2XUnwG tYZhB7EfKzLHZRblOdn2Q4U/4T+KXOFTSO+Gb9o2J0I2sJLI0NRXhcl9Fcoo8KVz G0ACWa0F1WKsbqzBATnhtYiKkuC3BeiS2eMuTVTlkP+Gd6YQ2f1zWLeBfXEiPGZb q0p/qTrUFLHbRoJMMuWaUfaBxb8PeUfM6yllxrzvRxPJU25pbj8OW/O5ZAe9xP8G S17sQ2nhEoWZW9hqbuA39IcLGa6RjT+TD+z3kmXQ9ZvCVDN2Oqqb/4ZNViwAvQq7 t67EfV7hGXty3Q58tS4XE9hHfwY+9YqMDLNIS/ED+hP8rcxTmiLlAIyk+qbT3b0l Q+375Ar7iCgihPPHYxeM5Qe1+Vsfh4NjR9thdAbT245MB3f90ULb+GNP/izUDOgA c/Ot6pStVFEUxTol6RlcLb85PugzrkoBOF/8ZLySdMLhALjPwaFcQZ1sFdcKUKlE tt7sZKQgbbCfqYGS9K264uUfWbdmZh05zhtkH0xUjyQpyIcnrYQsSIIEEnlbYnPp 0D55nooSGROKeud+gyrx =2LMr -----END PGP SIGNATURE----- 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
|
@ -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.
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -393,7 +393,7 @@ static bool si570_regmap_is_writeable(struct device *dev, unsigned int reg)
|
|||
}
|
||||
}
|
||||
|
||||
static struct regmap_config si570_regmap_config = {
|
||||
static const struct regmap_config si570_regmap_config = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
|
|
|
@ -77,13 +77,16 @@ struct clk_core {
|
|||
struct kref ref;
|
||||
};
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#include <trace/events/clk.h>
|
||||
|
||||
struct clk {
|
||||
struct clk_core *core;
|
||||
const char *dev_id;
|
||||
const char *con_id;
|
||||
unsigned long min_rate;
|
||||
unsigned long max_rate;
|
||||
struct hlist_node child_node;
|
||||
struct hlist_node clks_node;
|
||||
};
|
||||
|
||||
/*** locking ***/
|
||||
|
@ -480,6 +483,8 @@ static void clk_unprepare_unused_subtree(struct clk_core *clk)
|
|||
{
|
||||
struct clk_core *child;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
hlist_for_each_entry(child, &clk->children, child_node)
|
||||
clk_unprepare_unused_subtree(child);
|
||||
|
||||
|
@ -490,10 +495,12 @@ static void clk_unprepare_unused_subtree(struct clk_core *clk)
|
|||
return;
|
||||
|
||||
if (clk_core_is_prepared(clk)) {
|
||||
trace_clk_unprepare(clk);
|
||||
if (clk->ops->unprepare_unused)
|
||||
clk->ops->unprepare_unused(clk->hw);
|
||||
else if (clk->ops->unprepare)
|
||||
clk->ops->unprepare(clk->hw);
|
||||
trace_clk_unprepare_complete(clk);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -503,6 +510,8 @@ static void clk_disable_unused_subtree(struct clk_core *clk)
|
|||
struct clk_core *child;
|
||||
unsigned long flags;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
hlist_for_each_entry(child, &clk->children, child_node)
|
||||
clk_disable_unused_subtree(child);
|
||||
|
||||
|
@ -520,10 +529,12 @@ static void clk_disable_unused_subtree(struct clk_core *clk)
|
|||
* back to .disable
|
||||
*/
|
||||
if (clk_core_is_enabled(clk)) {
|
||||
trace_clk_disable(clk);
|
||||
if (clk->ops->disable_unused)
|
||||
clk->ops->disable_unused(clk->hw);
|
||||
else if (clk->ops->disable)
|
||||
clk->ops->disable(clk->hw);
|
||||
trace_clk_disable_complete(clk);
|
||||
}
|
||||
|
||||
unlock_out:
|
||||
|
@ -851,10 +862,10 @@ static void clk_core_get_boundaries(struct clk_core *clk,
|
|||
*min_rate = 0;
|
||||
*max_rate = ULONG_MAX;
|
||||
|
||||
hlist_for_each_entry(clk_user, &clk->clks, child_node)
|
||||
hlist_for_each_entry(clk_user, &clk->clks, clks_node)
|
||||
*min_rate = max(*min_rate, clk_user->min_rate);
|
||||
|
||||
hlist_for_each_entry(clk_user, &clk->clks, child_node)
|
||||
hlist_for_each_entry(clk_user, &clk->clks, clks_node)
|
||||
*max_rate = min(*max_rate, clk_user->max_rate);
|
||||
}
|
||||
|
||||
|
@ -903,9 +914,12 @@ static void clk_core_unprepare(struct clk_core *clk)
|
|||
|
||||
WARN_ON(clk->enable_count > 0);
|
||||
|
||||
trace_clk_unprepare(clk);
|
||||
|
||||
if (clk->ops->unprepare)
|
||||
clk->ops->unprepare(clk->hw);
|
||||
|
||||
trace_clk_unprepare_complete(clk);
|
||||
clk_core_unprepare(clk->parent);
|
||||
}
|
||||
|
||||
|
@ -943,12 +957,16 @@ static int clk_core_prepare(struct clk_core *clk)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (clk->ops->prepare) {
|
||||
trace_clk_prepare(clk);
|
||||
|
||||
if (clk->ops->prepare)
|
||||
ret = clk->ops->prepare(clk->hw);
|
||||
if (ret) {
|
||||
clk_core_unprepare(clk->parent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
trace_clk_prepare_complete(clk);
|
||||
|
||||
if (ret) {
|
||||
clk_core_unprepare(clk->parent);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -995,9 +1013,13 @@ static void clk_core_disable(struct clk_core *clk)
|
|||
if (--clk->enable_count > 0)
|
||||
return;
|
||||
|
||||
trace_clk_disable(clk);
|
||||
|
||||
if (clk->ops->disable)
|
||||
clk->ops->disable(clk->hw);
|
||||
|
||||
trace_clk_disable_complete(clk);
|
||||
|
||||
clk_core_disable(clk->parent);
|
||||
}
|
||||
|
||||
|
@ -1050,12 +1072,16 @@ static int clk_core_enable(struct clk_core *clk)
|
|||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (clk->ops->enable) {
|
||||
trace_clk_enable(clk);
|
||||
|
||||
if (clk->ops->enable)
|
||||
ret = clk->ops->enable(clk->hw);
|
||||
if (ret) {
|
||||
clk_core_disable(clk->parent);
|
||||
return ret;
|
||||
}
|
||||
|
||||
trace_clk_enable_complete(clk);
|
||||
|
||||
if (ret) {
|
||||
clk_core_disable(clk->parent);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1106,6 +1132,8 @@ static unsigned long clk_core_round_rate_nolock(struct clk_core *clk,
|
|||
struct clk_core *parent;
|
||||
struct clk_hw *parent_hw;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
if (!clk)
|
||||
return 0;
|
||||
|
||||
|
@ -1245,6 +1273,8 @@ static void __clk_recalc_accuracies(struct clk_core *clk)
|
|||
unsigned long parent_accuracy = 0;
|
||||
struct clk_core *child;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
if (clk->parent)
|
||||
parent_accuracy = clk->parent->accuracy;
|
||||
|
||||
|
@ -1318,6 +1348,8 @@ static void __clk_recalc_rates(struct clk_core *clk, unsigned long msg)
|
|||
unsigned long parent_rate = 0;
|
||||
struct clk_core *child;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
old_rate = clk->rate;
|
||||
|
||||
if (clk->parent)
|
||||
|
@ -1479,10 +1511,14 @@ static int __clk_set_parent(struct clk_core *clk, struct clk_core *parent,
|
|||
|
||||
old_parent = __clk_set_parent_before(clk, parent);
|
||||
|
||||
trace_clk_set_parent(clk, parent);
|
||||
|
||||
/* change clock input source */
|
||||
if (parent && clk->ops->set_parent)
|
||||
ret = clk->ops->set_parent(clk->hw, p_index);
|
||||
|
||||
trace_clk_set_parent_complete(clk, parent);
|
||||
|
||||
if (ret) {
|
||||
flags = clk_enable_lock();
|
||||
clk_reparent(clk, old_parent);
|
||||
|
@ -1524,6 +1560,8 @@ static int __clk_speculate_rates(struct clk_core *clk,
|
|||
unsigned long new_rate;
|
||||
int ret = NOTIFY_DONE;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
new_rate = clk_recalc(clk, parent_rate);
|
||||
|
||||
/* abort rate change if a driver returns NOTIFY_BAD or NOTIFY_STOP */
|
||||
|
@ -1580,6 +1618,7 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
|
|||
unsigned long min_rate;
|
||||
unsigned long max_rate;
|
||||
int p_index = 0;
|
||||
long ret;
|
||||
|
||||
/* sanity */
|
||||
if (IS_ERR_OR_NULL(clk))
|
||||
|
@ -1595,15 +1634,23 @@ static struct clk_core *clk_calc_new_rates(struct clk_core *clk,
|
|||
/* find the closest rate and parent clk/rate */
|
||||
if (clk->ops->determine_rate) {
|
||||
parent_hw = parent ? parent->hw : NULL;
|
||||
new_rate = clk->ops->determine_rate(clk->hw, rate,
|
||||
min_rate,
|
||||
max_rate,
|
||||
&best_parent_rate,
|
||||
&parent_hw);
|
||||
ret = clk->ops->determine_rate(clk->hw, rate,
|
||||
min_rate,
|
||||
max_rate,
|
||||
&best_parent_rate,
|
||||
&parent_hw);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
new_rate = ret;
|
||||
parent = parent_hw ? parent_hw->core : NULL;
|
||||
} else if (clk->ops->round_rate) {
|
||||
new_rate = clk->ops->round_rate(clk->hw, rate,
|
||||
&best_parent_rate);
|
||||
ret = clk->ops->round_rate(clk->hw, rate,
|
||||
&best_parent_rate);
|
||||
if (ret < 0)
|
||||
return NULL;
|
||||
|
||||
new_rate = ret;
|
||||
if (new_rate < min_rate || new_rate > max_rate)
|
||||
return NULL;
|
||||
} else if (!parent || !(clk->flags & CLK_SET_RATE_PARENT)) {
|
||||
|
@ -1706,6 +1753,7 @@ static void clk_change_rate(struct clk_core *clk)
|
|||
|
||||
if (clk->new_parent && clk->new_parent != clk->parent) {
|
||||
old_parent = __clk_set_parent_before(clk, clk->new_parent);
|
||||
trace_clk_set_parent(clk, clk->new_parent);
|
||||
|
||||
if (clk->ops->set_rate_and_parent) {
|
||||
skip_set_rate = true;
|
||||
|
@ -1716,12 +1764,17 @@ static void clk_change_rate(struct clk_core *clk)
|
|||
clk->ops->set_parent(clk->hw, clk->new_parent_index);
|
||||
}
|
||||
|
||||
trace_clk_set_parent_complete(clk, clk->new_parent);
|
||||
__clk_set_parent_after(clk, clk->new_parent, old_parent);
|
||||
}
|
||||
|
||||
trace_clk_set_rate(clk, clk->new_rate);
|
||||
|
||||
if (!skip_set_rate && clk->ops->set_rate)
|
||||
clk->ops->set_rate(clk->hw, clk->new_rate, best_parent_rate);
|
||||
|
||||
trace_clk_set_rate_complete(clk, clk->new_rate);
|
||||
|
||||
clk->rate = clk_recalc(clk, best_parent_rate);
|
||||
|
||||
if (clk->notifier_count && old_rate != clk->rate)
|
||||
|
@ -2010,16 +2063,18 @@ static int clk_core_set_parent(struct clk_core *clk, struct clk_core *parent)
|
|||
if (!clk)
|
||||
return 0;
|
||||
|
||||
/* verify ops for for multi-parent clks */
|
||||
if ((clk->num_parents > 1) && (!clk->ops->set_parent))
|
||||
return -ENOSYS;
|
||||
|
||||
/* prevent racing with updates to the clock topology */
|
||||
clk_prepare_lock();
|
||||
|
||||
if (clk->parent == parent)
|
||||
goto out;
|
||||
|
||||
/* verify ops for for multi-parent clks */
|
||||
if ((clk->num_parents > 1) && (!clk->ops->set_parent)) {
|
||||
ret = -ENOSYS;
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* check that we are allowed to re-parent if the clock is in use */
|
||||
if ((clk->flags & CLK_SET_PARENT_GATE) && clk->prepare_count) {
|
||||
ret = -EBUSY;
|
||||
|
@ -2110,10 +2165,10 @@ EXPORT_SYMBOL_GPL(clk_set_parent);
|
|||
*/
|
||||
int clk_set_phase(struct clk *clk, int degrees)
|
||||
{
|
||||
int ret = 0;
|
||||
int ret = -EINVAL;
|
||||
|
||||
if (!clk)
|
||||
goto out;
|
||||
return 0;
|
||||
|
||||
/* sanity check degrees */
|
||||
degrees %= 360;
|
||||
|
@ -2122,18 +2177,18 @@ int clk_set_phase(struct clk *clk, int degrees)
|
|||
|
||||
clk_prepare_lock();
|
||||
|
||||
if (!clk->core->ops->set_phase)
|
||||
goto out_unlock;
|
||||
trace_clk_set_phase(clk->core, degrees);
|
||||
|
||||
ret = clk->core->ops->set_phase(clk->core->hw, degrees);
|
||||
if (clk->core->ops->set_phase)
|
||||
ret = clk->core->ops->set_phase(clk->core->hw, degrees);
|
||||
|
||||
trace_clk_set_phase_complete(clk->core, degrees);
|
||||
|
||||
if (!ret)
|
||||
clk->core->phase = degrees;
|
||||
|
||||
out_unlock:
|
||||
clk_prepare_unlock();
|
||||
|
||||
out:
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_set_phase);
|
||||
|
@ -2401,7 +2456,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
|
|||
clk->max_rate = ULONG_MAX;
|
||||
|
||||
clk_prepare_lock();
|
||||
hlist_add_head(&clk->child_node, &hw->core->clks);
|
||||
hlist_add_head(&clk->clks_node, &hw->core->clks);
|
||||
clk_prepare_unlock();
|
||||
|
||||
return clk;
|
||||
|
@ -2410,7 +2465,7 @@ struct clk *__clk_create_clk(struct clk_hw *hw, const char *dev_id,
|
|||
void __clk_free_clk(struct clk *clk)
|
||||
{
|
||||
clk_prepare_lock();
|
||||
hlist_del(&clk->child_node);
|
||||
hlist_del(&clk->clks_node);
|
||||
clk_prepare_unlock();
|
||||
|
||||
kfree(clk);
|
||||
|
@ -2513,6 +2568,8 @@ static void __clk_release(struct kref *ref)
|
|||
struct clk_core *clk = container_of(ref, struct clk_core, ref);
|
||||
int i = clk->num_parents;
|
||||
|
||||
lockdep_assert_held(&prepare_lock);
|
||||
|
||||
kfree(clk->parents);
|
||||
while (--i >= 0)
|
||||
kfree_const(clk->parent_names[i]);
|
||||
|
@ -2688,7 +2745,7 @@ void __clk_put(struct clk *clk)
|
|||
|
||||
clk_prepare_lock();
|
||||
|
||||
hlist_del(&clk->child_node);
|
||||
hlist_del(&clk->clks_node);
|
||||
if (clk->min_rate > clk->core->req_rate ||
|
||||
clk->max_rate < clk->core->req_rate)
|
||||
clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
|
||||
|
@ -2834,17 +2891,6 @@ static const struct of_device_id __clk_of_table_sentinel
|
|||
static LIST_HEAD(of_clk_providers);
|
||||
static DEFINE_MUTEX(of_clk_mutex);
|
||||
|
||||
/* of_clk_provider list locking helpers */
|
||||
void of_clk_lock(void)
|
||||
{
|
||||
mutex_lock(&of_clk_mutex);
|
||||
}
|
||||
|
||||
void of_clk_unlock(void)
|
||||
{
|
||||
mutex_unlock(&of_clk_mutex);
|
||||
}
|
||||
|
||||
struct clk *of_clk_src_simple_get(struct of_phandle_args *clkspec,
|
||||
void *data)
|
||||
{
|
||||
|
@ -2928,7 +2974,11 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
|
|||
struct of_clk_provider *provider;
|
||||
struct clk *clk = ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
if (!clkspec)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* Check if we have such a provider in our array */
|
||||
mutex_lock(&of_clk_mutex);
|
||||
list_for_each_entry(provider, &of_clk_providers, link) {
|
||||
if (provider->node == clkspec->np)
|
||||
clk = provider->get(clkspec, provider->data);
|
||||
|
@ -2944,19 +2994,22 @@ struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
|
|||
break;
|
||||
}
|
||||
}
|
||||
mutex_unlock(&of_clk_mutex);
|
||||
|
||||
return clk;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_clk_get_from_provider() - Lookup a clock from a clock provider
|
||||
* @clkspec: pointer to a clock specifier data structure
|
||||
*
|
||||
* This function looks up a struct clk from the registered list of clock
|
||||
* providers, an input is a clock specifier data structure as returned
|
||||
* from the of_parse_phandle_with_args() function call.
|
||||
*/
|
||||
struct clk *of_clk_get_from_provider(struct of_phandle_args *clkspec)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
mutex_lock(&of_clk_mutex);
|
||||
clk = __of_clk_get_from_provider(clkspec, NULL, __func__);
|
||||
mutex_unlock(&of_clk_mutex);
|
||||
|
||||
return clk;
|
||||
return __of_clk_get_from_provider(clkspec, NULL, __func__);
|
||||
}
|
||||
|
||||
int of_clk_get_parent_count(struct device_node *np)
|
||||
|
|
|
@ -12,11 +12,8 @@
|
|||
struct clk_hw;
|
||||
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
|
||||
struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec);
|
||||
struct clk *__of_clk_get_from_provider(struct of_phandle_args *clkspec,
|
||||
const char *dev_id, const char *con_id);
|
||||
void of_clk_lock(void);
|
||||
void of_clk_unlock(void);
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_COMMON_CLK
|
||||
|
|
|
@ -28,34 +28,6 @@ static LIST_HEAD(clocks);
|
|||
static DEFINE_MUTEX(clocks_mutex);
|
||||
|
||||
#if defined(CONFIG_OF) && defined(CONFIG_COMMON_CLK)
|
||||
|
||||
static struct clk *__of_clk_get_by_clkspec(struct of_phandle_args *clkspec,
|
||||
const char *dev_id, const char *con_id)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
||||
if (!clkspec)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
of_clk_lock();
|
||||
clk = __of_clk_get_from_provider(clkspec, dev_id, con_id);
|
||||
of_clk_unlock();
|
||||
return clk;
|
||||
}
|
||||
|
||||
/**
|
||||
* of_clk_get_by_clkspec() - Lookup a clock form a clock provider
|
||||
* @clkspec: pointer to a clock specifier data structure
|
||||
*
|
||||
* This function looks up a struct clk from the registered list of clock
|
||||
* providers, an input is a clock specifier data structure as returned
|
||||
* from the of_parse_phandle_with_args() function call.
|
||||
*/
|
||||
struct clk *of_clk_get_by_clkspec(struct of_phandle_args *clkspec)
|
||||
{
|
||||
return __of_clk_get_by_clkspec(clkspec, NULL, __func__);
|
||||
}
|
||||
|
||||
static struct clk *__of_clk_get(struct device_node *np, int index,
|
||||
const char *dev_id, const char *con_id)
|
||||
{
|
||||
|
@ -71,7 +43,7 @@ static struct clk *__of_clk_get(struct device_node *np, int index,
|
|||
if (rc)
|
||||
return ERR_PTR(rc);
|
||||
|
||||
clk = __of_clk_get_by_clkspec(&clkspec, dev_id, con_id);
|
||||
clk = __of_clk_get_from_provider(&clkspec, dev_id, con_id);
|
||||
of_node_put(clkspec.np);
|
||||
|
||||
return clk;
|
||||
|
|
|
@ -38,44 +38,44 @@
|
|||
#include "clk.h"
|
||||
|
||||
/* clock parent list */
|
||||
static const char *timer0_mux_p[] __initconst = { "osc32k", "timerclk01", };
|
||||
static const char *timer1_mux_p[] __initconst = { "osc32k", "timerclk01", };
|
||||
static const char *timer2_mux_p[] __initconst = { "osc32k", "timerclk23", };
|
||||
static const char *timer3_mux_p[] __initconst = { "osc32k", "timerclk23", };
|
||||
static const char *timer4_mux_p[] __initconst = { "osc32k", "timerclk45", };
|
||||
static const char *timer5_mux_p[] __initconst = { "osc32k", "timerclk45", };
|
||||
static const char *timer6_mux_p[] __initconst = { "osc32k", "timerclk67", };
|
||||
static const char *timer7_mux_p[] __initconst = { "osc32k", "timerclk67", };
|
||||
static const char *timer8_mux_p[] __initconst = { "osc32k", "timerclk89", };
|
||||
static const char *timer9_mux_p[] __initconst = { "osc32k", "timerclk89", };
|
||||
static const char *uart0_mux_p[] __initconst = { "osc26m", "pclk", };
|
||||
static const char *uart1_mux_p[] __initconst = { "osc26m", "pclk", };
|
||||
static const char *uart2_mux_p[] __initconst = { "osc26m", "pclk", };
|
||||
static const char *uart3_mux_p[] __initconst = { "osc26m", "pclk", };
|
||||
static const char *uart4_mux_p[] __initconst = { "osc26m", "pclk", };
|
||||
static const char *spi0_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
|
||||
static const char *spi1_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
|
||||
static const char *spi2_mux_p[] __initconst = { "osc26m", "rclk_cfgaxi", };
|
||||
static const char *timer0_mux_p[] __initdata = { "osc32k", "timerclk01", };
|
||||
static const char *timer1_mux_p[] __initdata = { "osc32k", "timerclk01", };
|
||||
static const char *timer2_mux_p[] __initdata = { "osc32k", "timerclk23", };
|
||||
static const char *timer3_mux_p[] __initdata = { "osc32k", "timerclk23", };
|
||||
static const char *timer4_mux_p[] __initdata = { "osc32k", "timerclk45", };
|
||||
static const char *timer5_mux_p[] __initdata = { "osc32k", "timerclk45", };
|
||||
static const char *timer6_mux_p[] __initdata = { "osc32k", "timerclk67", };
|
||||
static const char *timer7_mux_p[] __initdata = { "osc32k", "timerclk67", };
|
||||
static const char *timer8_mux_p[] __initdata = { "osc32k", "timerclk89", };
|
||||
static const char *timer9_mux_p[] __initdata = { "osc32k", "timerclk89", };
|
||||
static const char *uart0_mux_p[] __initdata = { "osc26m", "pclk", };
|
||||
static const char *uart1_mux_p[] __initdata = { "osc26m", "pclk", };
|
||||
static const char *uart2_mux_p[] __initdata = { "osc26m", "pclk", };
|
||||
static const char *uart3_mux_p[] __initdata = { "osc26m", "pclk", };
|
||||
static const char *uart4_mux_p[] __initdata = { "osc26m", "pclk", };
|
||||
static const char *spi0_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", };
|
||||
static const char *spi1_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", };
|
||||
static const char *spi2_mux_p[] __initdata = { "osc26m", "rclk_cfgaxi", };
|
||||
/* share axi parent */
|
||||
static const char *saxi_mux_p[] __initconst = { "armpll3", "armpll2", };
|
||||
static const char *pwm0_mux_p[] __initconst = { "osc32k", "osc26m", };
|
||||
static const char *pwm1_mux_p[] __initconst = { "osc32k", "osc26m", };
|
||||
static const char *sd_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *mmc1_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *mmc1_mux2_p[] __initconst = { "osc26m", "mmc1_div", };
|
||||
static const char *g2d_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *venc_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *vdec_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *vpp_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *edc0_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *ldi0_mux_p[] __initconst = { "armpll2", "armpll4",
|
||||
static const char *saxi_mux_p[] __initdata = { "armpll3", "armpll2", };
|
||||
static const char *pwm0_mux_p[] __initdata = { "osc32k", "osc26m", };
|
||||
static const char *pwm1_mux_p[] __initdata = { "osc32k", "osc26m", };
|
||||
static const char *sd_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *mmc1_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *mmc1_mux2_p[] __initdata = { "osc26m", "mmc1_div", };
|
||||
static const char *g2d_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *venc_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *vdec_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *vpp_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *edc0_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *ldi0_mux_p[] __initdata = { "armpll2", "armpll4",
|
||||
"armpll3", "armpll5", };
|
||||
static const char *edc1_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *ldi1_mux_p[] __initconst = { "armpll2", "armpll4",
|
||||
static const char *edc1_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *ldi1_mux_p[] __initdata = { "armpll2", "armpll4",
|
||||
"armpll3", "armpll5", };
|
||||
static const char *rclk_hsic_p[] __initconst = { "armpll3", "armpll2", };
|
||||
static const char *mmc2_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *mmc3_mux_p[] __initconst = { "armpll2", "armpll3", };
|
||||
static const char *rclk_hsic_p[] __initdata = { "armpll3", "armpll2", };
|
||||
static const char *mmc2_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
static const char *mmc3_mux_p[] __initdata = { "armpll2", "armpll3", };
|
||||
|
||||
|
||||
/* fixed rate clocks */
|
||||
|
|
|
@ -46,15 +46,15 @@ static struct hisi_fixed_rate_clock hix5hd2_fixed_rate_clks[] __initdata = {
|
|||
{ HIX5HD2_FIXED_83M, "83m", NULL, CLK_IS_ROOT, 83333333, },
|
||||
};
|
||||
|
||||
static const char *sfc_mux_p[] __initconst = {
|
||||
static const char *sfc_mux_p[] __initdata = {
|
||||
"24m", "150m", "200m", "100m", "75m", };
|
||||
static u32 sfc_mux_table[] = {0, 4, 5, 6, 7};
|
||||
|
||||
static const char *sdio_mux_p[] __initconst = {
|
||||
static const char *sdio_mux_p[] __initdata = {
|
||||
"75m", "100m", "50m", "15m", };
|
||||
static u32 sdio_mux_table[] = {0, 1, 2, 3};
|
||||
|
||||
static const char *fephy_mux_p[] __initconst = { "25m", "125m"};
|
||||
static const char *fephy_mux_p[] __initdata = { "25m", "125m"};
|
||||
static u32 fephy_mux_table[] = {0, 1};
|
||||
|
||||
|
||||
|
|
|
@ -21,6 +21,10 @@ config ARMADA_38X_CLK
|
|||
bool
|
||||
select MVEBU_CLK_COMMON
|
||||
|
||||
config ARMADA_39X_CLK
|
||||
bool
|
||||
select MVEBU_CLK_COMMON
|
||||
|
||||
config ARMADA_XP_CLK
|
||||
bool
|
||||
select MVEBU_CLK_COMMON
|
||||
|
|
|
@ -5,6 +5,7 @@ obj-$(CONFIG_MVEBU_CLK_COREDIV) += clk-corediv.o
|
|||
obj-$(CONFIG_ARMADA_370_CLK) += armada-370.o
|
||||
obj-$(CONFIG_ARMADA_375_CLK) += armada-375.o
|
||||
obj-$(CONFIG_ARMADA_38X_CLK) += armada-38x.o
|
||||
obj-$(CONFIG_ARMADA_39X_CLK) += armada-39x.o
|
||||
obj-$(CONFIG_ARMADA_XP_CLK) += armada-xp.o
|
||||
obj-$(CONFIG_DOVE_CLK) += dove.o
|
||||
obj-$(CONFIG_KIRKWOOD_CLK) += kirkwood.o
|
||||
|
|
|
@ -0,0 +1,156 @@
|
|||
/*
|
||||
* Marvell Armada 39x SoC clocks
|
||||
*
|
||||
* Copyright (C) 2015 Marvell
|
||||
*
|
||||
* Gregory CLEMENT <gregory.clement@free-electrons.com>
|
||||
* Sebastian Hesselbarth <sebastian.hesselbarth@gmail.com>
|
||||
* Andrew Lunn <andrew@lunn.ch>
|
||||
* Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public
|
||||
* License version 2. This program is licensed "as is" without any
|
||||
* warranty of any kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/of.h>
|
||||
#include "common.h"
|
||||
|
||||
/*
|
||||
* SARL[14:10] : Ratios between CPU, NBCLK, HCLK and DCLK.
|
||||
*
|
||||
* SARL[15] : TCLK frequency
|
||||
* 0 = 250 MHz
|
||||
* 1 = 200 MHz
|
||||
*
|
||||
* SARH[0] : Reference clock frequency
|
||||
* 0 = 25 Mhz
|
||||
* 1 = 40 Mhz
|
||||
*/
|
||||
|
||||
#define SARL 0
|
||||
#define SARL_A390_TCLK_FREQ_OPT 15
|
||||
#define SARL_A390_TCLK_FREQ_OPT_MASK 0x1
|
||||
#define SARL_A390_CPU_DDR_L2_FREQ_OPT 10
|
||||
#define SARL_A390_CPU_DDR_L2_FREQ_OPT_MASK 0x1F
|
||||
#define SARH 4
|
||||
#define SARH_A390_REFCLK_FREQ BIT(0)
|
||||
|
||||
static const u32 armada_39x_tclk_frequencies[] __initconst = {
|
||||
250000000,
|
||||
200000000,
|
||||
};
|
||||
|
||||
static u32 __init armada_39x_get_tclk_freq(void __iomem *sar)
|
||||
{
|
||||
u8 tclk_freq_select;
|
||||
|
||||
tclk_freq_select = ((readl(sar + SARL) >> SARL_A390_TCLK_FREQ_OPT) &
|
||||
SARL_A390_TCLK_FREQ_OPT_MASK);
|
||||
return armada_39x_tclk_frequencies[tclk_freq_select];
|
||||
}
|
||||
|
||||
static const u32 armada_39x_cpu_frequencies[] __initconst = {
|
||||
[0x0] = 666 * 1000 * 1000,
|
||||
[0x2] = 800 * 1000 * 1000,
|
||||
[0x3] = 800 * 1000 * 1000,
|
||||
[0x4] = 1066 * 1000 * 1000,
|
||||
[0x5] = 1066 * 1000 * 1000,
|
||||
[0x6] = 1200 * 1000 * 1000,
|
||||
[0x8] = 1332 * 1000 * 1000,
|
||||
[0xB] = 1600 * 1000 * 1000,
|
||||
[0xC] = 1600 * 1000 * 1000,
|
||||
[0x12] = 1800 * 1000 * 1000,
|
||||
[0x1E] = 1800 * 1000 * 1000,
|
||||
};
|
||||
|
||||
static u32 __init armada_39x_get_cpu_freq(void __iomem *sar)
|
||||
{
|
||||
u8 cpu_freq_select;
|
||||
|
||||
cpu_freq_select = ((readl(sar + SARL) >> SARL_A390_CPU_DDR_L2_FREQ_OPT) &
|
||||
SARL_A390_CPU_DDR_L2_FREQ_OPT_MASK);
|
||||
if (cpu_freq_select >= ARRAY_SIZE(armada_39x_cpu_frequencies)) {
|
||||
pr_err("Selected CPU frequency (%d) unsupported\n",
|
||||
cpu_freq_select);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return armada_39x_cpu_frequencies[cpu_freq_select];
|
||||
}
|
||||
|
||||
enum { A390_CPU_TO_NBCLK, A390_CPU_TO_HCLK, A390_CPU_TO_DCLK };
|
||||
|
||||
static const struct coreclk_ratio armada_39x_coreclk_ratios[] __initconst = {
|
||||
{ .id = A390_CPU_TO_NBCLK, .name = "nbclk" },
|
||||
{ .id = A390_CPU_TO_HCLK, .name = "hclk" },
|
||||
{ .id = A390_CPU_TO_DCLK, .name = "dclk" },
|
||||
};
|
||||
|
||||
static void __init armada_39x_get_clk_ratio(
|
||||
void __iomem *sar, int id, int *mult, int *div)
|
||||
{
|
||||
switch (id) {
|
||||
case A390_CPU_TO_NBCLK:
|
||||
*mult = 1;
|
||||
*div = 2;
|
||||
break;
|
||||
case A390_CPU_TO_HCLK:
|
||||
*mult = 1;
|
||||
*div = 4;
|
||||
break;
|
||||
case A390_CPU_TO_DCLK:
|
||||
*mult = 1;
|
||||
*div = 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static u32 __init armada_39x_refclk_ratio(void __iomem *sar)
|
||||
{
|
||||
if (readl(sar + SARH) & SARH_A390_REFCLK_FREQ)
|
||||
return 40 * 1000 * 1000;
|
||||
else
|
||||
return 25 * 1000 * 1000;
|
||||
}
|
||||
|
||||
static const struct coreclk_soc_desc armada_39x_coreclks = {
|
||||
.get_tclk_freq = armada_39x_get_tclk_freq,
|
||||
.get_cpu_freq = armada_39x_get_cpu_freq,
|
||||
.get_clk_ratio = armada_39x_get_clk_ratio,
|
||||
.get_refclk_freq = armada_39x_refclk_ratio,
|
||||
.ratios = armada_39x_coreclk_ratios,
|
||||
.num_ratios = ARRAY_SIZE(armada_39x_coreclk_ratios),
|
||||
};
|
||||
|
||||
static void __init armada_39x_coreclk_init(struct device_node *np)
|
||||
{
|
||||
mvebu_coreclk_setup(np, &armada_39x_coreclks);
|
||||
}
|
||||
CLK_OF_DECLARE(armada_39x_core_clk, "marvell,armada-390-core-clock",
|
||||
armada_39x_coreclk_init);
|
||||
|
||||
/*
|
||||
* Clock Gating Control
|
||||
*/
|
||||
static const struct clk_gating_soc_desc armada_39x_gating_desc[] __initconst = {
|
||||
{ "pex1", NULL, 5 },
|
||||
{ "pex2", NULL, 6 },
|
||||
{ "pex3", NULL, 7 },
|
||||
{ "pex0", NULL, 8 },
|
||||
{ "usb3h0", NULL, 9 },
|
||||
{ "sdio", NULL, 17 },
|
||||
{ "xor0", NULL, 22 },
|
||||
{ "xor1", NULL, 28 },
|
||||
{ }
|
||||
};
|
||||
|
||||
static void __init armada_39x_clk_gating_init(struct device_node *np)
|
||||
{
|
||||
mvebu_clk_gating_setup(np, armada_39x_gating_desc);
|
||||
}
|
||||
CLK_OF_DECLARE(armada_39x_clk_gating, "marvell,armada-390-gating-clock",
|
||||
armada_39x_clk_gating_init);
|
|
@ -121,6 +121,11 @@ void __init mvebu_coreclk_setup(struct device_node *np,
|
|||
|
||||
/* Allocate struct for TCLK, cpu clk, and core ratio clocks */
|
||||
clk_data.clk_num = 2 + desc->num_ratios;
|
||||
|
||||
/* One more clock for the optional refclk */
|
||||
if (desc->get_refclk_freq)
|
||||
clk_data.clk_num += 1;
|
||||
|
||||
clk_data.clks = kzalloc(clk_data.clk_num * sizeof(struct clk *),
|
||||
GFP_KERNEL);
|
||||
if (WARN_ON(!clk_data.clks)) {
|
||||
|
@ -162,6 +167,18 @@ void __init mvebu_coreclk_setup(struct device_node *np,
|
|||
WARN_ON(IS_ERR(clk_data.clks[2+n]));
|
||||
};
|
||||
|
||||
/* Register optional refclk */
|
||||
if (desc->get_refclk_freq) {
|
||||
const char *name = "refclk";
|
||||
of_property_read_string_index(np, "clock-output-names",
|
||||
2 + desc->num_ratios, &name);
|
||||
rate = desc->get_refclk_freq(base);
|
||||
clk_data.clks[2 + desc->num_ratios] =
|
||||
clk_register_fixed_rate(NULL, name, NULL,
|
||||
CLK_IS_ROOT, rate);
|
||||
WARN_ON(IS_ERR(clk_data.clks[2 + desc->num_ratios]));
|
||||
}
|
||||
|
||||
/* SAR register isn't needed anymore */
|
||||
iounmap(base);
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ struct coreclk_soc_desc {
|
|||
u32 (*get_tclk_freq)(void __iomem *sar);
|
||||
u32 (*get_cpu_freq)(void __iomem *sar);
|
||||
void (*get_clk_ratio)(void __iomem *sar, int id, int *mult, int *div);
|
||||
u32 (*get_refclk_freq)(void __iomem *sar);
|
||||
bool (*is_sscg_enabled)(void __iomem *sar);
|
||||
u32 (*fix_sscg_deviation)(u32 system_clk);
|
||||
const struct coreclk_ratio *ratios;
|
||||
|
|
|
@ -77,12 +77,12 @@ static void __init clk_misc_init(void)
|
|||
writel_relaxed(30 << BP_FRAC_IOFRAC, FRAC + SET);
|
||||
}
|
||||
|
||||
static const char *sel_pll[] __initconst = { "pll", "ref_xtal", };
|
||||
static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
|
||||
static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
|
||||
static const char *sel_io[] __initconst = { "ref_io", "ref_xtal", };
|
||||
static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
|
||||
static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
|
||||
static const char *sel_pll[] __initdata = { "pll", "ref_xtal", };
|
||||
static const char *sel_cpu[] __initdata = { "ref_cpu", "ref_xtal", };
|
||||
static const char *sel_pix[] __initdata = { "ref_pix", "ref_xtal", };
|
||||
static const char *sel_io[] __initdata = { "ref_io", "ref_xtal", };
|
||||
static const char *cpu_sels[] __initdata = { "cpu_pll", "cpu_xtal", };
|
||||
static const char *emi_sels[] __initdata = { "emi_pll", "emi_xtal", };
|
||||
|
||||
enum imx23_clk {
|
||||
ref_xtal, pll, ref_cpu, ref_emi, ref_pix, ref_io, saif_sel,
|
||||
|
|
|
@ -125,15 +125,15 @@ static void __init clk_misc_init(void)
|
|||
writel_relaxed(val, FRAC0);
|
||||
}
|
||||
|
||||
static const char *sel_cpu[] __initconst = { "ref_cpu", "ref_xtal", };
|
||||
static const char *sel_io0[] __initconst = { "ref_io0", "ref_xtal", };
|
||||
static const char *sel_io1[] __initconst = { "ref_io1", "ref_xtal", };
|
||||
static const char *sel_pix[] __initconst = { "ref_pix", "ref_xtal", };
|
||||
static const char *sel_gpmi[] __initconst = { "ref_gpmi", "ref_xtal", };
|
||||
static const char *sel_pll0[] __initconst = { "pll0", "ref_xtal", };
|
||||
static const char *cpu_sels[] __initconst = { "cpu_pll", "cpu_xtal", };
|
||||
static const char *emi_sels[] __initconst = { "emi_pll", "emi_xtal", };
|
||||
static const char *ptp_sels[] __initconst = { "ref_xtal", "pll0", };
|
||||
static const char *sel_cpu[] __initdata = { "ref_cpu", "ref_xtal", };
|
||||
static const char *sel_io0[] __initdata = { "ref_io0", "ref_xtal", };
|
||||
static const char *sel_io1[] __initdata = { "ref_io1", "ref_xtal", };
|
||||
static const char *sel_pix[] __initdata = { "ref_pix", "ref_xtal", };
|
||||
static const char *sel_gpmi[] __initdata = { "ref_gpmi", "ref_xtal", };
|
||||
static const char *sel_pll0[] __initdata = { "pll0", "ref_xtal", };
|
||||
static const char *cpu_sels[] __initdata = { "cpu_pll", "cpu_xtal", };
|
||||
static const char *emi_sels[] __initdata = { "emi_pll", "emi_xtal", };
|
||||
static const char *ptp_sels[] __initdata = { "ref_xtal", "pll0", };
|
||||
|
||||
enum imx28_clk {
|
||||
ref_xtal, pll0, pll1, pll2, ref_cpu, ref_emi, ref_io0, ref_io1,
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#define _CLK_PXA_
|
||||
|
||||
#define PARENTS(name) \
|
||||
static const char *name ## _parents[] __initconst
|
||||
static const char *name ## _parents[] __initdata
|
||||
#define MUX_RO_RATE_RO_OPS(name, clk_name) \
|
||||
static struct clk_hw name ## _mux_hw; \
|
||||
static struct clk_hw name ## _rate_hw; \
|
||||
|
|
|
@ -336,6 +336,9 @@ static void __init pxa3xx_base_clocks_init(void)
|
|||
clk_register_clk_pxa3xx_smemc();
|
||||
clk_register_gate(NULL, "CLK_POUT", "osc_13mhz", 0,
|
||||
(void __iomem *)&OSCC, 11, 0, NULL);
|
||||
clkdev_pxa_register(CLK_OSTIMER, "OSTIMER0", NULL,
|
||||
clk_register_fixed_factor(NULL, "os-timer0",
|
||||
"osc_13mhz", 0, 1, 4));
|
||||
}
|
||||
|
||||
int __init pxa3xx_clocks_init(void)
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
config COMMON_CLK_QCOM
|
||||
tristate "Support for Qualcomm's clock controllers"
|
||||
depends on OF
|
||||
depends on ARCH_QCOM || COMPILE_TEST
|
||||
select REGMAP_MMIO
|
||||
select RESET_CONTROLLER
|
||||
|
||||
|
@ -46,6 +47,14 @@ config MSM_GCC_8660
|
|||
Say Y if you want to use peripheral devices such as UART, SPI,
|
||||
i2c, USB, SD/eMMC, etc.
|
||||
|
||||
config MSM_GCC_8916
|
||||
tristate "MSM8916 Global Clock Controller"
|
||||
depends on COMMON_CLK_QCOM
|
||||
help
|
||||
Support for the global clock controller on msm8916 devices.
|
||||
Say Y if you want to use devices such as UART, SPI i2c, USB,
|
||||
SD/eMMC, display, graphics, camera etc.
|
||||
|
||||
config MSM_GCC_8960
|
||||
tristate "APQ8064/MSM8960 Global Clock Controller"
|
||||
depends on COMMON_CLK_QCOM
|
||||
|
|
|
@ -15,6 +15,7 @@ obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
|
|||
obj-$(CONFIG_IPQ_GCC_806X) += gcc-ipq806x.o
|
||||
obj-$(CONFIG_IPQ_LCC_806X) += lcc-ipq806x.o
|
||||
obj-$(CONFIG_MSM_GCC_8660) += gcc-msm8660.o
|
||||
obj-$(CONFIG_MSM_GCC_8916) += gcc-msm8916.o
|
||||
obj-$(CONFIG_MSM_GCC_8960) += gcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
|
||||
obj-$(CONFIG_MSM_GCC_8974) += gcc-msm8974.o
|
||||
|
|
|
@ -71,12 +71,8 @@ static int clk_pll_enable(struct clk_hw *hw)
|
|||
udelay(50);
|
||||
|
||||
/* Enable PLL output. */
|
||||
ret = regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_OUTCTRL,
|
||||
return regmap_update_bits(pll->clkr.regmap, pll->mode_reg, PLL_OUTCTRL,
|
||||
PLL_OUTCTRL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void clk_pll_disable(struct clk_hw *hw)
|
||||
|
|
|
@ -47,15 +47,20 @@ static u8 clk_rcg_get_parent(struct clk_hw *hw)
|
|||
struct clk_rcg *rcg = to_clk_rcg(hw);
|
||||
int num_parents = __clk_get_num_parents(hw->clk);
|
||||
u32 ns;
|
||||
int i;
|
||||
int i, ret;
|
||||
|
||||
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
|
||||
ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
|
||||
if (ret)
|
||||
goto err;
|
||||
ns = ns_to_src(&rcg->s, ns);
|
||||
for (i = 0; i < num_parents; i++)
|
||||
if (ns == rcg->s.parent_map[i])
|
||||
if (ns == rcg->s.parent_map[i].cfg)
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
err:
|
||||
pr_debug("%s: Clock %s has invalid parent, using default.\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int reg_to_bank(struct clk_dyn_rcg *rcg, u32 bank)
|
||||
|
@ -70,21 +75,28 @@ static u8 clk_dyn_rcg_get_parent(struct clk_hw *hw)
|
|||
int num_parents = __clk_get_num_parents(hw->clk);
|
||||
u32 ns, reg;
|
||||
int bank;
|
||||
int i;
|
||||
int i, ret;
|
||||
struct src_sel *s;
|
||||
|
||||
regmap_read(rcg->clkr.regmap, rcg->bank_reg, ®);
|
||||
ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, ®);
|
||||
if (ret)
|
||||
goto err;
|
||||
bank = reg_to_bank(rcg, reg);
|
||||
s = &rcg->s[bank];
|
||||
|
||||
regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
|
||||
ret = regmap_read(rcg->clkr.regmap, rcg->ns_reg[bank], &ns);
|
||||
if (ret)
|
||||
goto err;
|
||||
ns = ns_to_src(s, ns);
|
||||
|
||||
for (i = 0; i < num_parents; i++)
|
||||
if (ns == s->parent_map[i])
|
||||
if (ns == s->parent_map[i].cfg)
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
err:
|
||||
pr_debug("%s: Clock %s has invalid parent, using default.\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_rcg_set_parent(struct clk_hw *hw, u8 index)
|
||||
|
@ -93,7 +105,7 @@ static int clk_rcg_set_parent(struct clk_hw *hw, u8 index)
|
|||
u32 ns;
|
||||
|
||||
regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
|
||||
ns = src_to_ns(&rcg->s, rcg->s.parent_map[index], ns);
|
||||
ns = src_to_ns(&rcg->s, rcg->s.parent_map[index].cfg, ns);
|
||||
regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);
|
||||
|
||||
return 0;
|
||||
|
@ -191,10 +203,10 @@ static u32 mn_to_reg(struct mn *mn, u32 m, u32 n, u32 val)
|
|||
return val;
|
||||
}
|
||||
|
||||
static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
|
||||
static int configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
|
||||
{
|
||||
u32 ns, md, reg;
|
||||
int bank, new_bank;
|
||||
int bank, new_bank, ret, index;
|
||||
struct mn *mn;
|
||||
struct pre_div *p;
|
||||
struct src_sel *s;
|
||||
|
@ -206,38 +218,56 @@ static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
|
|||
|
||||
enabled = __clk_is_enabled(hw->clk);
|
||||
|
||||
regmap_read(rcg->clkr.regmap, rcg->bank_reg, ®);
|
||||
ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
bank = reg_to_bank(rcg, reg);
|
||||
new_bank = enabled ? !bank : bank;
|
||||
|
||||
ns_reg = rcg->ns_reg[new_bank];
|
||||
regmap_read(rcg->clkr.regmap, ns_reg, &ns);
|
||||
ret = regmap_read(rcg->clkr.regmap, ns_reg, &ns);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (banked_mn) {
|
||||
mn = &rcg->mn[new_bank];
|
||||
md_reg = rcg->md_reg[new_bank];
|
||||
|
||||
ns |= BIT(mn->mnctr_reset_bit);
|
||||
regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
regmap_read(rcg->clkr.regmap, md_reg, &md);
|
||||
ret = regmap_read(rcg->clkr.regmap, md_reg, &md);
|
||||
if (ret)
|
||||
return ret;
|
||||
md = mn_to_md(mn, f->m, f->n, md);
|
||||
regmap_write(rcg->clkr.regmap, md_reg, md);
|
||||
|
||||
ret = regmap_write(rcg->clkr.regmap, md_reg, md);
|
||||
if (ret)
|
||||
return ret;
|
||||
ns = mn_to_ns(mn, f->m, f->n, ns);
|
||||
regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Two NS registers means mode control is in NS register */
|
||||
if (rcg->ns_reg[0] != rcg->ns_reg[1]) {
|
||||
ns = mn_to_reg(mn, f->m, f->n, ns);
|
||||
regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
if (ret)
|
||||
return ret;
|
||||
} else {
|
||||
reg = mn_to_reg(mn, f->m, f->n, reg);
|
||||
regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
|
||||
ret = regmap_write(rcg->clkr.regmap, rcg->bank_reg,
|
||||
reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
ns &= ~BIT(mn->mnctr_reset_bit);
|
||||
regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (banked_p) {
|
||||
|
@ -246,14 +276,24 @@ static void configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
|
|||
}
|
||||
|
||||
s = &rcg->s[new_bank];
|
||||
ns = src_to_ns(s, s->parent_map[f->src], ns);
|
||||
regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
index = qcom_find_src_index(hw, s->parent_map, f->src);
|
||||
if (index < 0)
|
||||
return index;
|
||||
ns = src_to_ns(s, s->parent_map[index].cfg, ns);
|
||||
ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (enabled) {
|
||||
regmap_read(rcg->clkr.regmap, rcg->bank_reg, ®);
|
||||
ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, ®);
|
||||
if (ret)
|
||||
return ret;
|
||||
reg ^= BIT(rcg->mux_sel_bit);
|
||||
regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
|
||||
ret = regmap_write(rcg->clkr.regmap, rcg->bank_reg, reg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
|
||||
|
@ -279,10 +319,8 @@ static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
|
|||
if (banked_p)
|
||||
f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
|
||||
|
||||
f.src = index;
|
||||
configure_bank(rcg, &f);
|
||||
|
||||
return 0;
|
||||
f.src = qcom_find_src_index(hw, rcg->s[bank].parent_map, index);
|
||||
return configure_bank(rcg, &f);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -369,17 +407,23 @@ clk_dyn_rcg_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
|
|||
static long _freq_tbl_determine_rate(struct clk_hw *hw,
|
||||
const struct freq_tbl *f, unsigned long rate,
|
||||
unsigned long min_rate, unsigned long max_rate,
|
||||
unsigned long *p_rate, struct clk_hw **p_hw)
|
||||
unsigned long *p_rate, struct clk_hw **p_hw,
|
||||
const struct parent_map *parent_map)
|
||||
{
|
||||
unsigned long clk_flags;
|
||||
struct clk *p;
|
||||
int index;
|
||||
|
||||
f = qcom_find_freq(f, rate);
|
||||
if (!f)
|
||||
return -EINVAL;
|
||||
|
||||
index = qcom_find_src_index(hw, parent_map, f->src);
|
||||
if (index < 0)
|
||||
return index;
|
||||
|
||||
clk_flags = __clk_get_flags(hw->clk);
|
||||
p = clk_get_parent_by_index(hw->clk, f->src);
|
||||
p = clk_get_parent_by_index(hw->clk, index);
|
||||
if (clk_flags & CLK_SET_RATE_PARENT) {
|
||||
rate = rate * f->pre_div;
|
||||
if (f->n) {
|
||||
|
@ -404,7 +448,7 @@ static long clk_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|||
struct clk_rcg *rcg = to_clk_rcg(hw);
|
||||
|
||||
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, min_rate,
|
||||
max_rate, p_rate, p);
|
||||
max_rate, p_rate, p, rcg->s.parent_map);
|
||||
}
|
||||
|
||||
static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
@ -412,9 +456,16 @@ static long clk_dyn_rcg_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|||
unsigned long *p_rate, struct clk_hw **p)
|
||||
{
|
||||
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
|
||||
u32 reg;
|
||||
int bank;
|
||||
struct src_sel *s;
|
||||
|
||||
regmap_read(rcg->clkr.regmap, rcg->bank_reg, ®);
|
||||
bank = reg_to_bank(rcg, reg);
|
||||
s = &rcg->s[bank];
|
||||
|
||||
return _freq_tbl_determine_rate(hw, rcg->freq_tbl, rate, min_rate,
|
||||
max_rate, p_rate, p);
|
||||
max_rate, p_rate, p, s->parent_map);
|
||||
}
|
||||
|
||||
static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
@ -424,8 +475,9 @@ static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|||
struct clk_rcg *rcg = to_clk_rcg(hw);
|
||||
const struct freq_tbl *f = rcg->freq_tbl;
|
||||
struct clk *p;
|
||||
int index = qcom_find_src_index(hw, rcg->s.parent_map, f->src);
|
||||
|
||||
p = clk_get_parent_by_index(hw->clk, f->src);
|
||||
p = clk_get_parent_by_index(hw->clk, index);
|
||||
*p_hw = __clk_get_hw(p);
|
||||
*p_rate = __clk_round_rate(p, rate);
|
||||
|
||||
|
@ -495,6 +547,57 @@ static int clk_rcg_bypass_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
return __clk_rcg_set_rate(rcg, rcg->freq_tbl);
|
||||
}
|
||||
|
||||
/*
|
||||
* This type of clock has a glitch-free mux that switches between the output of
|
||||
* the M/N counter and an always on clock source (XO). When clk_set_rate() is
|
||||
* called we need to make sure that we don't switch to the M/N counter if it
|
||||
* isn't clocking because the mux will get stuck and the clock will stop
|
||||
* outputting a clock. This can happen if the framework isn't aware that this
|
||||
* clock is on and so clk_set_rate() doesn't turn on the new parent. To fix
|
||||
* this we switch the mux in the enable/disable ops and reprogram the M/N
|
||||
* counter in the set_rate op. We also make sure to switch away from the M/N
|
||||
* counter in set_rate if software thinks the clock is off.
|
||||
*/
|
||||
static int clk_rcg_lcc_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct clk_rcg *rcg = to_clk_rcg(hw);
|
||||
const struct freq_tbl *f;
|
||||
int ret;
|
||||
u32 gfm = BIT(10);
|
||||
|
||||
f = qcom_find_freq(rcg->freq_tbl, rate);
|
||||
if (!f)
|
||||
return -EINVAL;
|
||||
|
||||
/* Switch to XO to avoid glitches */
|
||||
regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, 0);
|
||||
ret = __clk_rcg_set_rate(rcg, f);
|
||||
/* Switch back to M/N if it's clocking */
|
||||
if (__clk_is_enabled(hw->clk))
|
||||
regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, gfm);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clk_rcg_lcc_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_rcg *rcg = to_clk_rcg(hw);
|
||||
u32 gfm = BIT(10);
|
||||
|
||||
/* Use M/N */
|
||||
return regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, gfm);
|
||||
}
|
||||
|
||||
static void clk_rcg_lcc_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_rcg *rcg = to_clk_rcg(hw);
|
||||
u32 gfm = BIT(10);
|
||||
|
||||
/* Use XO */
|
||||
regmap_update_bits(rcg->clkr.regmap, rcg->ns_reg, gfm, 0);
|
||||
}
|
||||
|
||||
static int __clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate)
|
||||
{
|
||||
struct clk_dyn_rcg *rcg = to_clk_dyn_rcg(hw);
|
||||
|
@ -504,9 +607,7 @@ static int __clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate)
|
|||
if (!f)
|
||||
return -EINVAL;
|
||||
|
||||
configure_bank(rcg, f);
|
||||
|
||||
return 0;
|
||||
return configure_bank(rcg, f);
|
||||
}
|
||||
|
||||
static int clk_dyn_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
|
@ -543,6 +644,17 @@ const struct clk_ops clk_rcg_bypass_ops = {
|
|||
};
|
||||
EXPORT_SYMBOL_GPL(clk_rcg_bypass_ops);
|
||||
|
||||
const struct clk_ops clk_rcg_lcc_ops = {
|
||||
.enable = clk_rcg_lcc_enable,
|
||||
.disable = clk_rcg_lcc_disable,
|
||||
.get_parent = clk_rcg_get_parent,
|
||||
.set_parent = clk_rcg_set_parent,
|
||||
.recalc_rate = clk_rcg_recalc_rate,
|
||||
.determine_rate = clk_rcg_determine_rate,
|
||||
.set_rate = clk_rcg_lcc_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_rcg_lcc_ops);
|
||||
|
||||
const struct clk_ops clk_dyn_rcg_ops = {
|
||||
.enable = clk_enable_regmap,
|
||||
.is_enabled = clk_is_enabled_regmap,
|
||||
|
|
|
@ -25,6 +25,16 @@ struct freq_tbl {
|
|||
u16 n;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct parent_map - map table for PLL source select configuration values
|
||||
* @src: source PLL
|
||||
* @cfg: configuration value
|
||||
*/
|
||||
struct parent_map {
|
||||
u8 src;
|
||||
u8 cfg;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mn - M/N:D counter
|
||||
* @mnctr_en_bit: bit to enable mn counter
|
||||
|
@ -65,7 +75,7 @@ struct pre_div {
|
|||
struct src_sel {
|
||||
u8 src_sel_shift;
|
||||
#define SRC_SEL_MASK 0x7
|
||||
const u8 *parent_map;
|
||||
const struct parent_map *parent_map;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -96,6 +106,7 @@ struct clk_rcg {
|
|||
|
||||
extern const struct clk_ops clk_rcg_ops;
|
||||
extern const struct clk_ops clk_rcg_bypass_ops;
|
||||
extern const struct clk_ops clk_rcg_lcc_ops;
|
||||
|
||||
#define to_clk_rcg(_hw) container_of(to_clk_regmap(_hw), struct clk_rcg, clkr)
|
||||
|
||||
|
@ -150,7 +161,7 @@ struct clk_rcg2 {
|
|||
u32 cmd_rcgr;
|
||||
u8 mnd_width;
|
||||
u8 hid_width;
|
||||
const u8 *parent_map;
|
||||
const struct parent_map *parent_map;
|
||||
const struct freq_tbl *freq_tbl;
|
||||
struct clk_regmap clkr;
|
||||
};
|
||||
|
|
|
@ -69,16 +69,19 @@ static u8 clk_rcg2_get_parent(struct clk_hw *hw)
|
|||
|
||||
ret = regmap_read(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG, &cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err;
|
||||
|
||||
cfg &= CFG_SRC_SEL_MASK;
|
||||
cfg >>= CFG_SRC_SEL_SHIFT;
|
||||
|
||||
for (i = 0; i < num_parents; i++)
|
||||
if (cfg == rcg->parent_map[i])
|
||||
if (cfg == rcg->parent_map[i].cfg)
|
||||
return i;
|
||||
|
||||
return -EINVAL;
|
||||
err:
|
||||
pr_debug("%s: Clock %s has invalid parent, using default.\n",
|
||||
__func__, __clk_get_name(hw->clk));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int update_config(struct clk_rcg2 *rcg)
|
||||
|
@ -111,10 +114,10 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
|
|||
{
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
int ret;
|
||||
u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
|
||||
|
||||
ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
|
||||
CFG_SRC_SEL_MASK,
|
||||
rcg->parent_map[index] << CFG_SRC_SEL_SHIFT);
|
||||
CFG_SRC_SEL_MASK, cfg);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
|
@ -179,13 +182,19 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
|
|||
{
|
||||
unsigned long clk_flags;
|
||||
struct clk *p;
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
int index;
|
||||
|
||||
f = qcom_find_freq(f, rate);
|
||||
if (!f)
|
||||
return -EINVAL;
|
||||
|
||||
index = qcom_find_src_index(hw, rcg->parent_map, f->src);
|
||||
if (index < 0)
|
||||
return index;
|
||||
|
||||
clk_flags = __clk_get_flags(hw->clk);
|
||||
p = clk_get_parent_by_index(hw->clk, f->src);
|
||||
p = clk_get_parent_by_index(hw->clk, index);
|
||||
if (clk_flags & CLK_SET_RATE_PARENT) {
|
||||
if (f->pre_div) {
|
||||
rate /= 2;
|
||||
|
@ -219,7 +228,11 @@ static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|||
static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
|
||||
{
|
||||
u32 cfg, mask;
|
||||
int ret;
|
||||
struct clk_hw *hw = &rcg->clkr.hw;
|
||||
int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src);
|
||||
|
||||
if (index < 0)
|
||||
return index;
|
||||
|
||||
if (rcg->mnd_width && f->n) {
|
||||
mask = BIT(rcg->mnd_width) - 1;
|
||||
|
@ -242,8 +255,8 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
|
|||
mask = BIT(rcg->hid_width) - 1;
|
||||
mask |= CFG_SRC_SEL_MASK | CFG_MODE_MASK;
|
||||
cfg = f->pre_div << CFG_SRC_DIV_SHIFT;
|
||||
cfg |= rcg->parent_map[f->src] << CFG_SRC_SEL_SHIFT;
|
||||
if (rcg->mnd_width && f->n)
|
||||
cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
|
||||
if (rcg->mnd_width && f->n && (f->m != f->n))
|
||||
cfg |= CFG_MODE_DUAL_EDGE;
|
||||
ret = regmap_update_bits(rcg->clkr.regmap,
|
||||
rcg->cmd_rcgr + CFG_REG, mask, cfg);
|
||||
|
@ -374,9 +387,10 @@ static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|||
s64 request;
|
||||
u32 mask = BIT(rcg->hid_width) - 1;
|
||||
u32 hid_div;
|
||||
int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
|
||||
|
||||
/* Force the correct parent */
|
||||
*p = __clk_get_hw(clk_get_parent_by_index(hw->clk, f->src));
|
||||
*p = __clk_get_hw(clk_get_parent_by_index(hw->clk, index));
|
||||
|
||||
if (src_rate == 810000000)
|
||||
frac = frac_table_810m;
|
||||
|
@ -420,6 +434,7 @@ static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|||
{
|
||||
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
|
||||
const struct freq_tbl *f = rcg->freq_tbl;
|
||||
int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
|
||||
unsigned long parent_rate, div;
|
||||
u32 mask = BIT(rcg->hid_width) - 1;
|
||||
struct clk *p;
|
||||
|
@ -427,7 +442,7 @@ static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|||
if (rate == 0)
|
||||
return -EINVAL;
|
||||
|
||||
p = clk_get_parent_by_index(hw->clk, f->src);
|
||||
p = clk_get_parent_by_index(hw->clk, index);
|
||||
*p_hw = __clk_get_hw(p);
|
||||
*p_rate = parent_rate = __clk_round_rate(p, rate);
|
||||
|
||||
|
@ -489,7 +504,8 @@ static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
|
|||
int delta = 100000;
|
||||
const struct freq_tbl *f = rcg->freq_tbl;
|
||||
const struct frac_entry *frac = frac_table_pixel;
|
||||
struct clk *parent = clk_get_parent_by_index(hw->clk, f->src);
|
||||
int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
|
||||
struct clk *parent = clk_get_parent_by_index(hw->clk, index);
|
||||
|
||||
*p = __clk_get_hw(parent);
|
||||
|
||||
|
@ -518,7 +534,8 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
int delta = 100000;
|
||||
u32 mask = BIT(rcg->hid_width) - 1;
|
||||
u32 hid_div;
|
||||
struct clk *parent = clk_get_parent_by_index(hw->clk, f.src);
|
||||
int index = qcom_find_src_index(hw, rcg->parent_map, f.src);
|
||||
struct clk *parent = clk_get_parent_by_index(hw->clk, index);
|
||||
|
||||
for (; frac->num; frac++) {
|
||||
request = (rate * frac->den) / frac->num;
|
||||
|
|
|
@ -43,6 +43,18 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_find_freq);
|
||||
|
||||
int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src)
|
||||
{
|
||||
int i, num_parents = __clk_get_num_parents(hw->clk);
|
||||
|
||||
for (i = 0; i < num_parents; i++)
|
||||
if (src == map[i].src)
|
||||
return i;
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(qcom_find_src_index);
|
||||
|
||||
struct regmap *
|
||||
qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc)
|
||||
{
|
||||
|
|
|
@ -19,6 +19,8 @@ struct clk_regmap;
|
|||
struct qcom_reset_map;
|
||||
struct regmap;
|
||||
struct freq_tbl;
|
||||
struct clk_hw;
|
||||
struct parent_map;
|
||||
|
||||
struct qcom_cc_desc {
|
||||
const struct regmap_config *config;
|
||||
|
@ -30,6 +32,8 @@ struct qcom_cc_desc {
|
|||
|
||||
extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
|
||||
unsigned long rate);
|
||||
extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
|
||||
u8 src);
|
||||
|
||||
extern struct regmap *qcom_cc_map(struct platform_device *pdev,
|
||||
const struct qcom_cc_desc *desc);
|
||||
|
|
|
@ -32,18 +32,20 @@
|
|||
#include "clk-branch.h"
|
||||
#include "reset.h"
|
||||
|
||||
#define P_XO 0
|
||||
#define P_GPLL0 1
|
||||
#define P_GPLL1 1
|
||||
#define P_GPLL4 2
|
||||
#define P_PCIE_0_1_PIPE_CLK 1
|
||||
#define P_SATA_ASIC0_CLK 1
|
||||
#define P_SATA_RX_CLK 1
|
||||
#define P_SLEEP_CLK 1
|
||||
enum {
|
||||
P_XO,
|
||||
P_GPLL0,
|
||||
P_GPLL1,
|
||||
P_GPLL4,
|
||||
P_PCIE_0_1_PIPE_CLK,
|
||||
P_SATA_ASIC0_CLK,
|
||||
P_SATA_RX_CLK,
|
||||
P_SLEEP_CLK,
|
||||
};
|
||||
|
||||
static const u8 gcc_xo_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_GPLL0] = 1,
|
||||
static const struct parent_map gcc_xo_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL0, 1 }
|
||||
};
|
||||
|
||||
static const char *gcc_xo_gpll0[] = {
|
||||
|
@ -51,10 +53,10 @@ static const char *gcc_xo_gpll0[] = {
|
|||
"gpll0_vote",
|
||||
};
|
||||
|
||||
static const u8 gcc_xo_gpll0_gpll4_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_GPLL0] = 1,
|
||||
[P_GPLL4] = 5,
|
||||
static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL0, 1 },
|
||||
{ P_GPLL4, 5 }
|
||||
};
|
||||
|
||||
static const char *gcc_xo_gpll0_gpll4[] = {
|
||||
|
@ -63,9 +65,9 @@ static const char *gcc_xo_gpll0_gpll4[] = {
|
|||
"gpll4_vote",
|
||||
};
|
||||
|
||||
static const u8 gcc_xo_sata_asic0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_SATA_ASIC0_CLK] = 2,
|
||||
static const struct parent_map gcc_xo_sata_asic0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_SATA_ASIC0_CLK, 2 }
|
||||
};
|
||||
|
||||
static const char *gcc_xo_sata_asic0[] = {
|
||||
|
@ -73,9 +75,9 @@ static const char *gcc_xo_sata_asic0[] = {
|
|||
"sata_asic0_clk",
|
||||
};
|
||||
|
||||
static const u8 gcc_xo_sata_rx_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_SATA_RX_CLK] = 2,
|
||||
static const struct parent_map gcc_xo_sata_rx_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_SATA_RX_CLK, 2}
|
||||
};
|
||||
|
||||
static const char *gcc_xo_sata_rx[] = {
|
||||
|
@ -83,9 +85,9 @@ static const char *gcc_xo_sata_rx[] = {
|
|||
"sata_rx_clk",
|
||||
};
|
||||
|
||||
static const u8 gcc_xo_pcie_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_PCIE_0_1_PIPE_CLK] = 2,
|
||||
static const struct parent_map gcc_xo_pcie_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_PCIE_0_1_PIPE_CLK, 2 }
|
||||
};
|
||||
|
||||
static const char *gcc_xo_pcie[] = {
|
||||
|
@ -93,9 +95,9 @@ static const char *gcc_xo_pcie[] = {
|
|||
"pcie_pipe",
|
||||
};
|
||||
|
||||
static const u8 gcc_xo_pcie_sleep_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_SLEEP_CLK] = 6,
|
||||
static const struct parent_map gcc_xo_pcie_sleep_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_SLEEP_CLK, 6 }
|
||||
};
|
||||
|
||||
static const char *gcc_xo_pcie_sleep[] = {
|
||||
|
@ -1263,9 +1265,9 @@ static const struct freq_tbl ftbl_gcc_usb_hsic_clk[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static u8 usb_hsic_clk_src_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_GPLL1] = 4,
|
||||
static const struct parent_map usb_hsic_clk_src_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL1, 4 }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 usb_hsic_clk_src = {
|
||||
|
|
|
@ -140,15 +140,17 @@ static struct clk_regmap pll14_vote = {
|
|||
},
|
||||
};
|
||||
|
||||
#define P_PXO 0
|
||||
#define P_PLL8 1
|
||||
#define P_PLL3 1
|
||||
#define P_PLL0 2
|
||||
#define P_CXO 2
|
||||
enum {
|
||||
P_PXO,
|
||||
P_PLL8,
|
||||
P_PLL3,
|
||||
P_PLL0,
|
||||
P_CXO,
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 3,
|
||||
static const struct parent_map gcc_pxo_pll8_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 3 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll8[] = {
|
||||
|
@ -156,10 +158,10 @@ static const char *gcc_pxo_pll8[] = {
|
|||
"pll8_vote",
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_cxo_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 3,
|
||||
[P_CXO] = 5,
|
||||
static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 3 },
|
||||
{ P_CXO, 5 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll8_cxo[] = {
|
||||
|
@ -168,14 +170,14 @@ static const char *gcc_pxo_pll8_cxo[] = {
|
|||
"cxo",
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll3_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL3] = 1,
|
||||
static const struct parent_map gcc_pxo_pll3_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL3, 1 }
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll3_sata_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL3] = 6,
|
||||
static const struct parent_map gcc_pxo_pll3_sata_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL3, 6 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll3[] = {
|
||||
|
@ -183,10 +185,10 @@ static const char *gcc_pxo_pll3[] = {
|
|||
"pll3",
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_pll0[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 3,
|
||||
[P_PLL0] = 2,
|
||||
static const struct parent_map gcc_pxo_pll8_pll0[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 3 },
|
||||
{ P_PLL0, 2 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll8_pll0_map[] = {
|
||||
|
@ -525,8 +527,8 @@ static struct freq_tbl clk_tbl_gsbi_qup[] = {
|
|||
{ 10800000, P_PXO, 1, 2, 5 },
|
||||
{ 15060000, P_PLL8, 1, 2, 51 },
|
||||
{ 24000000, P_PLL8, 4, 1, 4 },
|
||||
{ 25000000, P_PXO, 1, 0, 0 },
|
||||
{ 25600000, P_PLL8, 1, 1, 15 },
|
||||
{ 27000000, P_PXO, 1, 0, 0 },
|
||||
{ 48000000, P_PLL8, 4, 1, 2 },
|
||||
{ 51200000, P_PLL8, 1, 2, 15 },
|
||||
{ }
|
||||
|
@ -2170,6 +2172,36 @@ static struct clk_branch usb_fs1_h_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
static struct clk_branch ebi2_clk = {
|
||||
.hwcg_reg = 0x3b00,
|
||||
.hwcg_bit = 6,
|
||||
.halt_reg = 0x2fcc,
|
||||
.halt_bit = 1,
|
||||
.clkr = {
|
||||
.enable_reg = 0x3b00,
|
||||
.enable_mask = BIT(4),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ebi2_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch ebi2_aon_clk = {
|
||||
.halt_reg = 0x2fcc,
|
||||
.halt_bit = 0,
|
||||
.clkr = {
|
||||
.enable_reg = 0x3b00,
|
||||
.enable_mask = BIT(8),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ebi2_always_on_clk",
|
||||
.ops = &clk_branch_ops,
|
||||
.flags = CLK_IS_ROOT,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_regmap *gcc_ipq806x_clks[] = {
|
||||
[PLL0] = &pll0.clkr,
|
||||
[PLL0_VOTE] = &pll0_vote,
|
||||
|
@ -2273,6 +2305,8 @@ static struct clk_regmap *gcc_ipq806x_clks[] = {
|
|||
[USB_FS1_XCVR_SRC] = &usb_fs1_xcvr_clk_src.clkr,
|
||||
[USB_FS1_XCVR_CLK] = &usb_fs1_xcvr_clk.clkr,
|
||||
[USB_FS1_SYSTEM_CLK] = &usb_fs1_sys_clk.clkr,
|
||||
[EBI2_CLK] = &ebi2_clk.clkr,
|
||||
[EBI2_AON_CLK] = &ebi2_aon_clk.clkr,
|
||||
};
|
||||
|
||||
static const struct qcom_reset_map gcc_ipq806x_resets[] = {
|
||||
|
|
|
@ -59,13 +59,15 @@ static struct clk_regmap pll8_vote = {
|
|||
},
|
||||
};
|
||||
|
||||
#define P_PXO 0
|
||||
#define P_PLL8 1
|
||||
#define P_CXO 2
|
||||
enum {
|
||||
P_PXO,
|
||||
P_PLL8,
|
||||
P_CXO,
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 3,
|
||||
static const struct parent_map gcc_pxo_pll8_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 3 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll8[] = {
|
||||
|
@ -73,10 +75,10 @@ static const char *gcc_pxo_pll8[] = {
|
|||
"pll8_vote",
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_cxo_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 3,
|
||||
[P_CXO] = 5,
|
||||
static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 3 },
|
||||
{ P_CXO, 5 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll8_cxo[] = {
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -113,14 +113,16 @@ static struct clk_regmap pll14_vote = {
|
|||
},
|
||||
};
|
||||
|
||||
#define P_PXO 0
|
||||
#define P_PLL8 1
|
||||
#define P_PLL3 2
|
||||
#define P_CXO 2
|
||||
enum {
|
||||
P_PXO,
|
||||
P_PLL8,
|
||||
P_PLL3,
|
||||
P_CXO,
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 3,
|
||||
static const struct parent_map gcc_pxo_pll8_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 3 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll8[] = {
|
||||
|
@ -128,10 +130,10 @@ static const char *gcc_pxo_pll8[] = {
|
|||
"pll8_vote",
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_cxo_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 3,
|
||||
[P_CXO] = 5,
|
||||
static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 3 },
|
||||
{ P_CXO, 5 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll8_cxo[] = {
|
||||
|
@ -140,10 +142,10 @@ static const char *gcc_pxo_pll8_cxo[] = {
|
|||
"cxo",
|
||||
};
|
||||
|
||||
static const u8 gcc_pxo_pll8_pll3_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 3,
|
||||
[P_PLL3] = 6,
|
||||
static const struct parent_map gcc_pxo_pll8_pll3_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 3 },
|
||||
{ P_PLL3, 6 }
|
||||
};
|
||||
|
||||
static const char *gcc_pxo_pll8_pll3[] = {
|
||||
|
|
|
@ -32,14 +32,16 @@
|
|||
#include "clk-branch.h"
|
||||
#include "reset.h"
|
||||
|
||||
#define P_XO 0
|
||||
#define P_GPLL0 1
|
||||
#define P_GPLL1 1
|
||||
#define P_GPLL4 2
|
||||
enum {
|
||||
P_XO,
|
||||
P_GPLL0,
|
||||
P_GPLL1,
|
||||
P_GPLL4,
|
||||
};
|
||||
|
||||
static const u8 gcc_xo_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_GPLL0] = 1,
|
||||
static const struct parent_map gcc_xo_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL0, 1 }
|
||||
};
|
||||
|
||||
static const char *gcc_xo_gpll0[] = {
|
||||
|
@ -47,10 +49,10 @@ static const char *gcc_xo_gpll0[] = {
|
|||
"gpll0_vote",
|
||||
};
|
||||
|
||||
static const u8 gcc_xo_gpll0_gpll4_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_GPLL0] = 1,
|
||||
[P_GPLL4] = 5,
|
||||
static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL0, 1 },
|
||||
{ P_GPLL4, 5 }
|
||||
};
|
||||
|
||||
static const char *gcc_xo_gpll0_gpll4[] = {
|
||||
|
@ -984,9 +986,9 @@ static const struct freq_tbl ftbl_gcc_usb_hsic_clk[] = {
|
|||
{ }
|
||||
};
|
||||
|
||||
static u8 usb_hsic_clk_src_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_GPLL1] = 4,
|
||||
static const struct parent_map usb_hsic_clk_src_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL1, 4 }
|
||||
};
|
||||
|
||||
static struct clk_rcg2 usb_hsic_clk_src = {
|
||||
|
|
|
@ -61,12 +61,14 @@ static const struct pll_config pll4_config = {
|
|||
.main_output_mask = BIT(23),
|
||||
};
|
||||
|
||||
#define P_PXO 0
|
||||
#define P_PLL4 1
|
||||
enum {
|
||||
P_PXO,
|
||||
P_PLL4,
|
||||
};
|
||||
|
||||
static const u8 lcc_pxo_pll4_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL4] = 2,
|
||||
static const struct parent_map lcc_pxo_pll4_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL4, 2 }
|
||||
};
|
||||
|
||||
static const char *lcc_pxo_pll4[] = {
|
||||
|
@ -294,14 +296,14 @@ static struct clk_regmap_mux pcm_clk = {
|
|||
};
|
||||
|
||||
static struct freq_tbl clk_tbl_aif_osr[] = {
|
||||
{ 22050, P_PLL4, 1, 147, 20480 },
|
||||
{ 32000, P_PLL4, 1, 1, 96 },
|
||||
{ 44100, P_PLL4, 1, 147, 10240 },
|
||||
{ 48000, P_PLL4, 1, 1, 64 },
|
||||
{ 88200, P_PLL4, 1, 147, 5120 },
|
||||
{ 96000, P_PLL4, 1, 1, 32 },
|
||||
{ 176400, P_PLL4, 1, 147, 2560 },
|
||||
{ 192000, P_PLL4, 1, 1, 16 },
|
||||
{ 2822400, P_PLL4, 1, 147, 20480 },
|
||||
{ 4096000, P_PLL4, 1, 1, 96 },
|
||||
{ 5644800, P_PLL4, 1, 147, 10240 },
|
||||
{ 6144000, P_PLL4, 1, 1, 64 },
|
||||
{ 11289600, P_PLL4, 1, 147, 5120 },
|
||||
{ 12288000, P_PLL4, 1, 1, 32 },
|
||||
{ 22579200, P_PLL4, 1, 147, 2560 },
|
||||
{ 24576000, P_PLL4, 1, 1, 16 },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -360,7 +362,7 @@ static struct clk_branch spdif_clk = {
|
|||
};
|
||||
|
||||
static struct freq_tbl clk_tbl_ahbix[] = {
|
||||
{ 131072, P_PLL4, 1, 1, 3 },
|
||||
{ 131072000, P_PLL4, 1, 1, 3 },
|
||||
{ },
|
||||
};
|
||||
|
||||
|
@ -386,13 +388,12 @@ static struct clk_rcg ahbix_clk = {
|
|||
.freq_tbl = clk_tbl_ahbix,
|
||||
.clkr = {
|
||||
.enable_reg = 0x38,
|
||||
.enable_mask = BIT(10), /* toggle the gfmux to select mn/pxo */
|
||||
.enable_mask = BIT(11),
|
||||
.hw.init = &(struct clk_init_data){
|
||||
.name = "ahbix",
|
||||
.parent_names = lcc_pxo_pll4,
|
||||
.num_parents = 2,
|
||||
.ops = &clk_rcg_ops,
|
||||
.flags = CLK_SET_RATE_GATE,
|
||||
.ops = &clk_rcg_lcc_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
|
|
@ -47,12 +47,14 @@ static struct clk_pll pll4 = {
|
|||
},
|
||||
};
|
||||
|
||||
#define P_PXO 0
|
||||
#define P_PLL4 1
|
||||
enum {
|
||||
P_PXO,
|
||||
P_PLL4,
|
||||
};
|
||||
|
||||
static const u8 lcc_pxo_pll4_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL4] = 2,
|
||||
static const struct parent_map lcc_pxo_pll4_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL4, 2 }
|
||||
};
|
||||
|
||||
static const char *lcc_pxo_pll4[] = {
|
||||
|
|
|
@ -27,28 +27,30 @@
|
|||
#include "clk-branch.h"
|
||||
#include "reset.h"
|
||||
|
||||
#define P_XO 0
|
||||
#define P_MMPLL0 1
|
||||
#define P_EDPLINK 1
|
||||
#define P_MMPLL1 2
|
||||
#define P_HDMIPLL 2
|
||||
#define P_GPLL0 3
|
||||
#define P_EDPVCO 3
|
||||
#define P_MMPLL4 4
|
||||
#define P_DSI0PLL 4
|
||||
#define P_DSI0PLL_BYTE 4
|
||||
#define P_MMPLL2 4
|
||||
#define P_MMPLL3 4
|
||||
#define P_GPLL1 5
|
||||
#define P_DSI1PLL 5
|
||||
#define P_DSI1PLL_BYTE 5
|
||||
#define P_MMSLEEP 6
|
||||
enum {
|
||||
P_XO,
|
||||
P_MMPLL0,
|
||||
P_EDPLINK,
|
||||
P_MMPLL1,
|
||||
P_HDMIPLL,
|
||||
P_GPLL0,
|
||||
P_EDPVCO,
|
||||
P_MMPLL4,
|
||||
P_DSI0PLL,
|
||||
P_DSI0PLL_BYTE,
|
||||
P_MMPLL2,
|
||||
P_MMPLL3,
|
||||
P_GPLL1,
|
||||
P_DSI1PLL,
|
||||
P_DSI1PLL_BYTE,
|
||||
P_MMSLEEP,
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_mmpll1_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_GPLL0] = 5,
|
||||
static const struct parent_map mmcc_xo_mmpll0_mmpll1_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_mmpll1_gpll0[] = {
|
||||
|
@ -58,13 +60,13 @@ static const char *mmcc_xo_mmpll0_mmpll1_gpll0[] = {
|
|||
"mmss_gpll0_vote",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_dsi_hdmi_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_HDMIPLL] = 4,
|
||||
[P_GPLL0] = 5,
|
||||
[P_DSI0PLL] = 2,
|
||||
[P_DSI1PLL] = 3,
|
||||
static const struct parent_map mmcc_xo_mmpll0_dsi_hdmi_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_HDMIPLL, 4 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_DSI0PLL, 2 },
|
||||
{ P_DSI1PLL, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_dsi_hdmi_gpll0[] = {
|
||||
|
@ -76,12 +78,12 @@ static const char *mmcc_xo_mmpll0_dsi_hdmi_gpll0[] = {
|
|||
"dsi1pll",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_1_2_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_GPLL0] = 5,
|
||||
[P_MMPLL2] = 3,
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_2_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_MMPLL2, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_1_2_gpll0[] = {
|
||||
|
@ -92,12 +94,12 @@ static const char *mmcc_xo_mmpll0_1_2_gpll0[] = {
|
|||
"mmpll2",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_1_3_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_GPLL0] = 5,
|
||||
[P_MMPLL3] = 3,
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_3_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_MMPLL3, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_1_3_gpll0[] = {
|
||||
|
@ -108,13 +110,13 @@ static const char *mmcc_xo_mmpll0_1_3_gpll0[] = {
|
|||
"mmpll3",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_dsi_hdmi_edp_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_EDPLINK] = 4,
|
||||
[P_HDMIPLL] = 3,
|
||||
[P_EDPVCO] = 5,
|
||||
[P_DSI0PLL] = 1,
|
||||
[P_DSI1PLL] = 2,
|
||||
static const struct parent_map mmcc_xo_dsi_hdmi_edp_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_EDPLINK, 4 },
|
||||
{ P_HDMIPLL, 3 },
|
||||
{ P_EDPVCO, 5 },
|
||||
{ P_DSI0PLL, 1 },
|
||||
{ P_DSI1PLL, 2 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_dsi_hdmi_edp[] = {
|
||||
|
@ -126,13 +128,13 @@ static const char *mmcc_xo_dsi_hdmi_edp[] = {
|
|||
"dsi1pll",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_dsi_hdmi_edp_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_EDPLINK] = 4,
|
||||
[P_HDMIPLL] = 3,
|
||||
[P_GPLL0] = 5,
|
||||
[P_DSI0PLL] = 1,
|
||||
[P_DSI1PLL] = 2,
|
||||
static const struct parent_map mmcc_xo_dsi_hdmi_edp_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_EDPLINK, 4 },
|
||||
{ P_HDMIPLL, 3 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_DSI0PLL, 1 },
|
||||
{ P_DSI1PLL, 2 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_dsi_hdmi_edp_gpll0[] = {
|
||||
|
@ -144,13 +146,13 @@ static const char *mmcc_xo_dsi_hdmi_edp_gpll0[] = {
|
|||
"dsi1pll",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_dsibyte_hdmi_edp_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_EDPLINK] = 4,
|
||||
[P_HDMIPLL] = 3,
|
||||
[P_GPLL0] = 5,
|
||||
[P_DSI0PLL_BYTE] = 1,
|
||||
[P_DSI1PLL_BYTE] = 2,
|
||||
static const struct parent_map mmcc_xo_dsibyte_hdmi_edp_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_EDPLINK, 4 },
|
||||
{ P_HDMIPLL, 3 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_DSI0PLL_BYTE, 1 },
|
||||
{ P_DSI1PLL_BYTE, 2 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_dsibyte_hdmi_edp_gpll0[] = {
|
||||
|
@ -162,12 +164,12 @@ static const char *mmcc_xo_dsibyte_hdmi_edp_gpll0[] = {
|
|||
"dsi1pllbyte",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_1_4_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_GPLL0] = 5,
|
||||
[P_MMPLL4] = 3,
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_4_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_MMPLL4, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_1_4_gpll0[] = {
|
||||
|
@ -178,13 +180,13 @@ static const char *mmcc_xo_mmpll0_1_4_gpll0[] = {
|
|||
"gpll0",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_1_4_gpll1_0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_MMPLL4] = 3,
|
||||
[P_GPLL0] = 5,
|
||||
[P_GPLL1] = 4,
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_4_gpll1_0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_MMPLL4, 3 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_GPLL1, 4 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_1_4_gpll1_0[] = {
|
||||
|
@ -196,14 +198,14 @@ static const char *mmcc_xo_mmpll0_1_4_gpll1_0[] = {
|
|||
"gpll0",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_1_4_gpll1_0_sleep_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_MMPLL4] = 3,
|
||||
[P_GPLL0] = 5,
|
||||
[P_GPLL1] = 4,
|
||||
[P_MMSLEEP] = 6,
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_4_gpll1_0_sleep_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_MMPLL4, 3 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_GPLL1, 4 },
|
||||
{ P_MMSLEEP, 6 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_1_4_gpll1_0_sleep[] = {
|
||||
|
|
|
@ -33,18 +33,21 @@
|
|||
#include "clk-branch.h"
|
||||
#include "reset.h"
|
||||
|
||||
#define P_PXO 0
|
||||
#define P_PLL8 1
|
||||
#define P_PLL2 2
|
||||
#define P_PLL3 3
|
||||
#define P_PLL15 3
|
||||
enum {
|
||||
P_PXO,
|
||||
P_PLL8,
|
||||
P_PLL2,
|
||||
P_PLL3,
|
||||
P_PLL15,
|
||||
P_HDMI_PLL,
|
||||
};
|
||||
|
||||
#define F_MN(f, s, _m, _n) { .freq = f, .src = s, .m = _m, .n = _n }
|
||||
|
||||
static u8 mmcc_pxo_pll8_pll2_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 2,
|
||||
[P_PLL2] = 1,
|
||||
static const struct parent_map mmcc_pxo_pll8_pll2_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 2 },
|
||||
{ P_PLL2, 1 }
|
||||
};
|
||||
|
||||
static const char *mmcc_pxo_pll8_pll2[] = {
|
||||
|
@ -53,11 +56,11 @@ static const char *mmcc_pxo_pll8_pll2[] = {
|
|||
"pll2",
|
||||
};
|
||||
|
||||
static u8 mmcc_pxo_pll8_pll2_pll3_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 2,
|
||||
[P_PLL2] = 1,
|
||||
[P_PLL3] = 3,
|
||||
static const struct parent_map mmcc_pxo_pll8_pll2_pll3_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 2 },
|
||||
{ P_PLL2, 1 },
|
||||
{ P_PLL3, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_pxo_pll8_pll2_pll15[] = {
|
||||
|
@ -67,11 +70,11 @@ static const char *mmcc_pxo_pll8_pll2_pll15[] = {
|
|||
"pll15",
|
||||
};
|
||||
|
||||
static u8 mmcc_pxo_pll8_pll2_pll15_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_PLL8] = 2,
|
||||
[P_PLL2] = 1,
|
||||
[P_PLL15] = 3,
|
||||
static const struct parent_map mmcc_pxo_pll8_pll2_pll15_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_PLL8, 2 },
|
||||
{ P_PLL2, 1 },
|
||||
{ P_PLL15, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_pxo_pll8_pll2_pll3[] = {
|
||||
|
@ -1377,11 +1380,9 @@ static struct clk_branch rot_clk = {
|
|||
},
|
||||
};
|
||||
|
||||
#define P_HDMI_PLL 1
|
||||
|
||||
static u8 mmcc_pxo_hdmi_map[] = {
|
||||
[P_PXO] = 0,
|
||||
[P_HDMI_PLL] = 3,
|
||||
static const struct parent_map mmcc_pxo_hdmi_map[] = {
|
||||
{ P_PXO, 0 },
|
||||
{ P_HDMI_PLL, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_pxo_hdmi[] = {
|
||||
|
|
|
@ -32,26 +32,28 @@
|
|||
#include "clk-branch.h"
|
||||
#include "reset.h"
|
||||
|
||||
#define P_XO 0
|
||||
#define P_MMPLL0 1
|
||||
#define P_EDPLINK 1
|
||||
#define P_MMPLL1 2
|
||||
#define P_HDMIPLL 2
|
||||
#define P_GPLL0 3
|
||||
#define P_EDPVCO 3
|
||||
#define P_GPLL1 4
|
||||
#define P_DSI0PLL 4
|
||||
#define P_DSI0PLL_BYTE 4
|
||||
#define P_MMPLL2 4
|
||||
#define P_MMPLL3 4
|
||||
#define P_DSI1PLL 5
|
||||
#define P_DSI1PLL_BYTE 5
|
||||
enum {
|
||||
P_XO,
|
||||
P_MMPLL0,
|
||||
P_EDPLINK,
|
||||
P_MMPLL1,
|
||||
P_HDMIPLL,
|
||||
P_GPLL0,
|
||||
P_EDPVCO,
|
||||
P_GPLL1,
|
||||
P_DSI0PLL,
|
||||
P_DSI0PLL_BYTE,
|
||||
P_MMPLL2,
|
||||
P_MMPLL3,
|
||||
P_DSI1PLL,
|
||||
P_DSI1PLL_BYTE,
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_mmpll1_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_GPLL0] = 5,
|
||||
static const struct parent_map mmcc_xo_mmpll0_mmpll1_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_mmpll1_gpll0[] = {
|
||||
|
@ -61,13 +63,13 @@ static const char *mmcc_xo_mmpll0_mmpll1_gpll0[] = {
|
|||
"mmss_gpll0_vote",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_dsi_hdmi_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_HDMIPLL] = 4,
|
||||
[P_GPLL0] = 5,
|
||||
[P_DSI0PLL] = 2,
|
||||
[P_DSI1PLL] = 3,
|
||||
static const struct parent_map mmcc_xo_mmpll0_dsi_hdmi_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_HDMIPLL, 4 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_DSI0PLL, 2 },
|
||||
{ P_DSI1PLL, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_dsi_hdmi_gpll0[] = {
|
||||
|
@ -79,12 +81,12 @@ static const char *mmcc_xo_mmpll0_dsi_hdmi_gpll0[] = {
|
|||
"dsi1pll",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_1_2_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_GPLL0] = 5,
|
||||
[P_MMPLL2] = 3,
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_2_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_MMPLL2, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_1_2_gpll0[] = {
|
||||
|
@ -95,12 +97,12 @@ static const char *mmcc_xo_mmpll0_1_2_gpll0[] = {
|
|||
"mmpll2",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_1_3_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_GPLL0] = 5,
|
||||
[P_MMPLL3] = 3,
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_3_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_MMPLL3, 3 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_1_3_gpll0[] = {
|
||||
|
@ -111,12 +113,12 @@ static const char *mmcc_xo_mmpll0_1_3_gpll0[] = {
|
|||
"mmpll3",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_mmpll0_1_gpll1_0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_MMPLL0] = 1,
|
||||
[P_MMPLL1] = 2,
|
||||
[P_GPLL0] = 5,
|
||||
[P_GPLL1] = 4,
|
||||
static const struct parent_map mmcc_xo_mmpll0_1_gpll1_0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_MMPLL0, 1 },
|
||||
{ P_MMPLL1, 2 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_GPLL1, 4 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_mmpll0_1_gpll1_0[] = {
|
||||
|
@ -127,13 +129,13 @@ static const char *mmcc_xo_mmpll0_1_gpll1_0[] = {
|
|||
"gpll1_vote",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_dsi_hdmi_edp_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_EDPLINK] = 4,
|
||||
[P_HDMIPLL] = 3,
|
||||
[P_EDPVCO] = 5,
|
||||
[P_DSI0PLL] = 1,
|
||||
[P_DSI1PLL] = 2,
|
||||
static const struct parent_map mmcc_xo_dsi_hdmi_edp_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_EDPLINK, 4 },
|
||||
{ P_HDMIPLL, 3 },
|
||||
{ P_EDPVCO, 5 },
|
||||
{ P_DSI0PLL, 1 },
|
||||
{ P_DSI1PLL, 2 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_dsi_hdmi_edp[] = {
|
||||
|
@ -145,13 +147,13 @@ static const char *mmcc_xo_dsi_hdmi_edp[] = {
|
|||
"dsi1pll",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_dsi_hdmi_edp_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_EDPLINK] = 4,
|
||||
[P_HDMIPLL] = 3,
|
||||
[P_GPLL0] = 5,
|
||||
[P_DSI0PLL] = 1,
|
||||
[P_DSI1PLL] = 2,
|
||||
static const struct parent_map mmcc_xo_dsi_hdmi_edp_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_EDPLINK, 4 },
|
||||
{ P_HDMIPLL, 3 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_DSI0PLL, 1 },
|
||||
{ P_DSI1PLL, 2 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_dsi_hdmi_edp_gpll0[] = {
|
||||
|
@ -163,13 +165,13 @@ static const char *mmcc_xo_dsi_hdmi_edp_gpll0[] = {
|
|||
"dsi1pll",
|
||||
};
|
||||
|
||||
static const u8 mmcc_xo_dsibyte_hdmi_edp_gpll0_map[] = {
|
||||
[P_XO] = 0,
|
||||
[P_EDPLINK] = 4,
|
||||
[P_HDMIPLL] = 3,
|
||||
[P_GPLL0] = 5,
|
||||
[P_DSI0PLL_BYTE] = 1,
|
||||
[P_DSI1PLL_BYTE] = 2,
|
||||
static const struct parent_map mmcc_xo_dsibyte_hdmi_edp_gpll0_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_EDPLINK, 4 },
|
||||
{ P_HDMIPLL, 3 },
|
||||
{ P_GPLL0, 5 },
|
||||
{ P_DSI0PLL_BYTE, 1 },
|
||||
{ P_DSI1PLL_BYTE, 2 }
|
||||
};
|
||||
|
||||
static const char *mmcc_xo_dsibyte_hdmi_edp_gpll0[] = {
|
||||
|
|
|
@ -704,7 +704,7 @@ static struct rockchip_clk_branch rk3188_clk_branches[] __initdata = {
|
|||
GATE(ACLK_GPS, "aclk_gps", "aclk_peri", 0, RK2928_CLKGATE_CON(8), 13, GFLAGS),
|
||||
};
|
||||
|
||||
static const char *rk3188_critical_clocks[] __initconst = {
|
||||
static const char *const rk3188_critical_clocks[] __initconst = {
|
||||
"aclk_cpu",
|
||||
"aclk_peri",
|
||||
"hclk_peri",
|
||||
|
|
|
@ -771,7 +771,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
|||
GATE(0, "pclk_isp_in", "ext_isp", 0, RK3288_CLKGATE_CON(16), 3, GFLAGS),
|
||||
};
|
||||
|
||||
static const char *rk3288_critical_clocks[] __initconst = {
|
||||
static const char *const rk3288_critical_clocks[] __initconst = {
|
||||
"aclk_cpu",
|
||||
"aclk_peri",
|
||||
"hclk_peri",
|
||||
|
|
|
@ -317,7 +317,8 @@ void __init rockchip_clk_register_armclk(unsigned int lookup_id,
|
|||
rockchip_clk_add_lookup(clk, lookup_id);
|
||||
}
|
||||
|
||||
void __init rockchip_clk_protect_critical(const char *clocks[], int nclocks)
|
||||
void __init rockchip_clk_protect_critical(const char *const clocks[],
|
||||
int nclocks)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
|
|
@ -182,7 +182,7 @@ struct clk *rockchip_clk_register_mmc(const char *name,
|
|||
const char **parent_names, u8 num_parents,
|
||||
void __iomem *reg, int shift);
|
||||
|
||||
#define PNAME(x) static const char *x[] __initconst
|
||||
#define PNAME(x) static const char *x[] __initdata
|
||||
|
||||
enum rockchip_clk_branch_type {
|
||||
branch_composite,
|
||||
|
@ -407,7 +407,7 @@ void rockchip_clk_register_armclk(unsigned int lookup_id, const char *name,
|
|||
const struct rockchip_cpuclk_reg_data *reg_data,
|
||||
const struct rockchip_cpuclk_rate_table *rates,
|
||||
int nrates);
|
||||
void rockchip_clk_protect_critical(const char *clocks[], int nclocks);
|
||||
void rockchip_clk_protect_critical(const char *const clocks[], int nclocks);
|
||||
void rockchip_register_restart_notifier(unsigned int reg);
|
||||
|
||||
#define ROCKCHIP_SOFTRST_HIWORD_MASK BIT(0)
|
||||
|
|
|
@ -10,6 +10,7 @@ obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
|
|||
obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS5433) += clk-exynos5433.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o
|
||||
|
|
|
@ -142,6 +142,8 @@ CLK_OF_DECLARE(exynos4212_clkout, "samsung,exynos4212-pmu",
|
|||
exynos4_clkout_init);
|
||||
CLK_OF_DECLARE(exynos4412_clkout, "samsung,exynos4412-pmu",
|
||||
exynos4_clkout_init);
|
||||
CLK_OF_DECLARE(exynos3250_clkout, "samsung,exynos3250-pmu",
|
||||
exynos4_clkout_init);
|
||||
|
||||
static void __init exynos5_clkout_init(struct device_node *node)
|
||||
{
|
||||
|
@ -151,3 +153,5 @@ CLK_OF_DECLARE(exynos5250_clkout, "samsung,exynos5250-pmu",
|
|||
exynos5_clkout_init);
|
||||
CLK_OF_DECLARE(exynos5420_clkout, "samsung,exynos5420-pmu",
|
||||
exynos5_clkout_init);
|
||||
CLK_OF_DECLARE(exynos5433_clkout, "samsung,exynos5433-pmu",
|
||||
exynos5_clkout_init);
|
||||
|
|
|
@ -894,3 +894,166 @@ static void __init exynos3250_cmu_dmc_init(struct device_node *np)
|
|||
}
|
||||
CLK_OF_DECLARE(exynos3250_cmu_dmc, "samsung,exynos3250-cmu-dmc",
|
||||
exynos3250_cmu_dmc_init);
|
||||
|
||||
|
||||
/*
|
||||
* CMU ISP
|
||||
*/
|
||||
|
||||
#define DIV_ISP0 0x300
|
||||
#define DIV_ISP1 0x304
|
||||
#define GATE_IP_ISP0 0x800
|
||||
#define GATE_IP_ISP1 0x804
|
||||
#define GATE_SCLK_ISP 0x900
|
||||
|
||||
static struct samsung_div_clock isp_div_clks[] __initdata = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
* in the User's Manual. When adding new entries, please make sure
|
||||
* that the order is preserved, to avoid merge conflicts and make
|
||||
* further work with defined data easier.
|
||||
*/
|
||||
/* DIV_ISP0 */
|
||||
DIV(CLK_DIV_ISP1, "div_isp1", "mout_aclk_266_sub", DIV_ISP0, 4, 3),
|
||||
DIV(CLK_DIV_ISP0, "div_isp0", "mout_aclk_266_sub", DIV_ISP0, 0, 3),
|
||||
|
||||
/* DIV_ISP1 */
|
||||
DIV(CLK_DIV_MCUISP1, "div_mcuisp1", "mout_aclk_400_mcuisp_sub",
|
||||
DIV_ISP1, 8, 3),
|
||||
DIV(CLK_DIV_MCUISP0, "div_mcuisp0", "mout_aclk_400_mcuisp_sub",
|
||||
DIV_ISP1, 4, 3),
|
||||
DIV(CLK_DIV_MPWM, "div_mpwm", "div_isp1", DIV_ISP1, 0, 3),
|
||||
};
|
||||
|
||||
static struct samsung_gate_clock isp_gate_clks[] __initdata = {
|
||||
/*
|
||||
* NOTE: Following table is sorted by register address in ascending
|
||||
* order and then bitfield shift in descending order, as it is done
|
||||
* in the User's Manual. When adding new entries, please make sure
|
||||
* that the order is preserved, to avoid merge conflicts and make
|
||||
* further work with defined data easier.
|
||||
*/
|
||||
|
||||
/* GATE_IP_ISP0 */
|
||||
GATE(CLK_UART_ISP, "uart_isp", "uart_isp_top",
|
||||
GATE_IP_ISP0, 31, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_WDT_ISP, "wdt_isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 30, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_PWM_ISP, "pwm_isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 28, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_I2C1_ISP, "i2c1_isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 26, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_I2C0_ISP, "i2c0_isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 25, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_MPWM_ISP, "mpwm_isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 24, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_MCUCTL_ISP, "mcuctl_isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 23, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_PPMUISPX, "ppmuispx", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 21, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_PPMUISPMX, "ppmuispmx", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 20, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_QE_LITE1, "qe_lite1", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 18, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_QE_LITE0, "qe_lite0", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 17, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_QE_FD, "qe_fd", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 16, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_QE_DRC, "qe_drc", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 15, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_QE_ISP, "qe_isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 14, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_CSIS1, "csis1", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 13, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SMMU_LITE1, "smmu_lite1", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 12, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SMMU_LITE0, "smmu_lite0", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 11, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SMMU_FD, "smmu_fd", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 10, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SMMU_DRC, "smmu_drc", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 9, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SMMU_ISP, "smmu_isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 8, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_GICISP, "gicisp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 7, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_CSIS0, "csis0", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 6, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_MCUISP, "mcuisp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 5, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_LITE1, "lite1", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 4, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_LITE0, "lite0", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 3, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_FD, "fd", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 2, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_DRC, "drc", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 1, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_ISP, "isp", "mout_aclk_266_sub",
|
||||
GATE_IP_ISP0, 0, CLK_IGNORE_UNUSED, 0),
|
||||
|
||||
/* GATE_IP_ISP1 */
|
||||
GATE(CLK_QE_ISPCX, "qe_ispcx", "uart_isp_top",
|
||||
GATE_IP_ISP0, 21, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_QE_SCALERP, "qe_scalerp", "uart_isp_top",
|
||||
GATE_IP_ISP0, 20, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_QE_SCALERC, "qe_scalerc", "uart_isp_top",
|
||||
GATE_IP_ISP0, 19, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SMMU_SCALERP, "smmu_scalerp", "uart_isp_top",
|
||||
GATE_IP_ISP0, 18, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SMMU_SCALERC, "smmu_scalerc", "uart_isp_top",
|
||||
GATE_IP_ISP0, 17, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SCALERP, "scalerp", "uart_isp_top",
|
||||
GATE_IP_ISP0, 16, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SCALERC, "scalerc", "uart_isp_top",
|
||||
GATE_IP_ISP0, 15, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SPI1_ISP, "spi1_isp", "uart_isp_top",
|
||||
GATE_IP_ISP0, 13, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SPI0_ISP, "spi0_isp", "uart_isp_top",
|
||||
GATE_IP_ISP0, 12, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_SMMU_ISPCX, "smmu_ispcx", "uart_isp_top",
|
||||
GATE_IP_ISP0, 4, CLK_IGNORE_UNUSED, 0),
|
||||
GATE(CLK_ASYNCAXIM, "asyncaxim", "uart_isp_top",
|
||||
GATE_IP_ISP0, 0, CLK_IGNORE_UNUSED, 0),
|
||||
|
||||
/* GATE_SCLK_ISP */
|
||||
GATE(CLK_SCLK_MPWM_ISP, "sclk_mpwm_isp", "div_mpwm",
|
||||
GATE_SCLK_ISP, 0, CLK_IGNORE_UNUSED, 0),
|
||||
};
|
||||
|
||||
static struct samsung_cmu_info isp_cmu_info __initdata = {
|
||||
.div_clks = isp_div_clks,
|
||||
.nr_div_clks = ARRAY_SIZE(isp_div_clks),
|
||||
.gate_clks = isp_gate_clks,
|
||||
.nr_gate_clks = ARRAY_SIZE(isp_gate_clks),
|
||||
.nr_clk_ids = NR_CLKS_ISP,
|
||||
};
|
||||
|
||||
static int __init exynos3250_cmu_isp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
samsung_cmu_register_one(np, &isp_cmu_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id exynos3250_cmu_isp_of_match[] = {
|
||||
{ .compatible = "samsung,exynos3250-cmu-isp", },
|
||||
{ /* sentinel */ }
|
||||
};
|
||||
|
||||
static struct platform_driver exynos3250_cmu_isp_driver = {
|
||||
.driver = {
|
||||
.name = "exynos3250-cmu-isp",
|
||||
.of_match_table = exynos3250_cmu_isp_of_match,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init exynos3250_cmu_platform_init(void)
|
||||
{
|
||||
return platform_driver_probe(&exynos3250_cmu_isp_driver,
|
||||
exynos3250_cmu_isp_probe);
|
||||
}
|
||||
subsys_initcall(exynos3250_cmu_platform_init);
|
||||
|
||||
|
|
|
@ -1354,7 +1354,7 @@ static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = {
|
|||
VPLL_LOCK, VPLL_CON0, NULL),
|
||||
};
|
||||
|
||||
static void __init exynos4_core_down_clock(enum exynos4_soc soc)
|
||||
static void __init exynos4x12_core_down_clock(void)
|
||||
{
|
||||
unsigned int tmp;
|
||||
|
||||
|
@ -1373,11 +1373,9 @@ static void __init exynos4_core_down_clock(enum exynos4_soc soc)
|
|||
__raw_writel(tmp, reg_base + PWR_CTRL1);
|
||||
|
||||
/*
|
||||
* Disable the clock up feature on Exynos4x12, in case it was
|
||||
* enabled by bootloader.
|
||||
* Disable the clock up feature in case it was enabled by bootloader.
|
||||
*/
|
||||
if (exynos4_soc == EXYNOS4X12)
|
||||
__raw_writel(0x0, reg_base + E4X12_PWR_CTRL2);
|
||||
__raw_writel(0x0, reg_base + E4X12_PWR_CTRL2);
|
||||
}
|
||||
|
||||
/* register exynos4 clocks */
|
||||
|
@ -1474,7 +1472,8 @@ static void __init exynos4_clk_init(struct device_node *np,
|
|||
samsung_clk_register_alias(ctx, exynos4_aliases,
|
||||
ARRAY_SIZE(exynos4_aliases));
|
||||
|
||||
exynos4_core_down_clock(soc);
|
||||
if (soc == EXYNOS4X12)
|
||||
exynos4x12_core_down_clock();
|
||||
exynos4_clk_sleep_init();
|
||||
|
||||
samsung_clk_of_add_provider(np, ctx);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -169,44 +169,44 @@ static inline void s5pv210_clk_sleep_init(void) { }
|
|||
#endif
|
||||
|
||||
/* Mux parent lists. */
|
||||
static const char *fin_pll_p[] __initconst = {
|
||||
static const char *fin_pll_p[] __initdata = {
|
||||
"xxti",
|
||||
"xusbxti"
|
||||
};
|
||||
|
||||
static const char *mout_apll_p[] __initconst = {
|
||||
static const char *mout_apll_p[] __initdata = {
|
||||
"fin_pll",
|
||||
"fout_apll"
|
||||
};
|
||||
|
||||
static const char *mout_mpll_p[] __initconst = {
|
||||
static const char *mout_mpll_p[] __initdata = {
|
||||
"fin_pll",
|
||||
"fout_mpll"
|
||||
};
|
||||
|
||||
static const char *mout_epll_p[] __initconst = {
|
||||
static const char *mout_epll_p[] __initdata = {
|
||||
"fin_pll",
|
||||
"fout_epll"
|
||||
};
|
||||
|
||||
static const char *mout_vpllsrc_p[] __initconst = {
|
||||
static const char *mout_vpllsrc_p[] __initdata = {
|
||||
"fin_pll",
|
||||
"sclk_hdmi27m"
|
||||
};
|
||||
|
||||
static const char *mout_vpll_p[] __initconst = {
|
||||
static const char *mout_vpll_p[] __initdata = {
|
||||
"mout_vpllsrc",
|
||||
"fout_vpll"
|
||||
};
|
||||
|
||||
static const char *mout_group1_p[] __initconst = {
|
||||
static const char *mout_group1_p[] __initdata = {
|
||||
"dout_a2m",
|
||||
"mout_mpll",
|
||||
"mout_epll",
|
||||
"mout_vpll"
|
||||
};
|
||||
|
||||
static const char *mout_group2_p[] __initconst = {
|
||||
static const char *mout_group2_p[] __initdata = {
|
||||
"xxti",
|
||||
"xusbxti",
|
||||
"sclk_hdmi27m",
|
||||
|
@ -218,7 +218,7 @@ static const char *mout_group2_p[] __initconst = {
|
|||
"mout_vpll",
|
||||
};
|
||||
|
||||
static const char *mout_audio0_p[] __initconst = {
|
||||
static const char *mout_audio0_p[] __initdata = {
|
||||
"xxti",
|
||||
"pcmcdclk0",
|
||||
"sclk_hdmi27m",
|
||||
|
@ -230,7 +230,7 @@ static const char *mout_audio0_p[] __initconst = {
|
|||
"mout_vpll",
|
||||
};
|
||||
|
||||
static const char *mout_audio1_p[] __initconst = {
|
||||
static const char *mout_audio1_p[] __initdata = {
|
||||
"i2scdclk1",
|
||||
"pcmcdclk1",
|
||||
"sclk_hdmi27m",
|
||||
|
@ -242,7 +242,7 @@ static const char *mout_audio1_p[] __initconst = {
|
|||
"mout_vpll",
|
||||
};
|
||||
|
||||
static const char *mout_audio2_p[] __initconst = {
|
||||
static const char *mout_audio2_p[] __initdata = {
|
||||
"i2scdclk2",
|
||||
"pcmcdclk2",
|
||||
"sclk_hdmi27m",
|
||||
|
@ -254,63 +254,63 @@ static const char *mout_audio2_p[] __initconst = {
|
|||
"mout_vpll",
|
||||
};
|
||||
|
||||
static const char *mout_spdif_p[] __initconst = {
|
||||
static const char *mout_spdif_p[] __initdata = {
|
||||
"dout_audio0",
|
||||
"dout_audio1",
|
||||
"dout_audio3",
|
||||
};
|
||||
|
||||
static const char *mout_group3_p[] __initconst = {
|
||||
static const char *mout_group3_p[] __initdata = {
|
||||
"mout_apll",
|
||||
"mout_mpll"
|
||||
};
|
||||
|
||||
static const char *mout_group4_p[] __initconst = {
|
||||
static const char *mout_group4_p[] __initdata = {
|
||||
"mout_mpll",
|
||||
"dout_a2m"
|
||||
};
|
||||
|
||||
static const char *mout_flash_p[] __initconst = {
|
||||
static const char *mout_flash_p[] __initdata = {
|
||||
"dout_hclkd",
|
||||
"dout_hclkp"
|
||||
};
|
||||
|
||||
static const char *mout_dac_p[] __initconst = {
|
||||
static const char *mout_dac_p[] __initdata = {
|
||||
"mout_vpll",
|
||||
"sclk_hdmiphy"
|
||||
};
|
||||
|
||||
static const char *mout_hdmi_p[] __initconst = {
|
||||
static const char *mout_hdmi_p[] __initdata = {
|
||||
"sclk_hdmiphy",
|
||||
"dout_tblk"
|
||||
};
|
||||
|
||||
static const char *mout_mixer_p[] __initconst = {
|
||||
static const char *mout_mixer_p[] __initdata = {
|
||||
"mout_dac",
|
||||
"mout_hdmi"
|
||||
};
|
||||
|
||||
static const char *mout_vpll_6442_p[] __initconst = {
|
||||
static const char *mout_vpll_6442_p[] __initdata = {
|
||||
"fin_pll",
|
||||
"fout_vpll"
|
||||
};
|
||||
|
||||
static const char *mout_mixer_6442_p[] __initconst = {
|
||||
static const char *mout_mixer_6442_p[] __initdata = {
|
||||
"mout_vpll",
|
||||
"dout_mixer"
|
||||
};
|
||||
|
||||
static const char *mout_d0sync_6442_p[] __initconst = {
|
||||
static const char *mout_d0sync_6442_p[] __initdata = {
|
||||
"mout_dsys",
|
||||
"div_apll"
|
||||
};
|
||||
|
||||
static const char *mout_d1sync_6442_p[] __initconst = {
|
||||
static const char *mout_d1sync_6442_p[] __initdata = {
|
||||
"mout_psys",
|
||||
"div_apll"
|
||||
};
|
||||
|
||||
static const char *mout_group2_6442_p[] __initconst = {
|
||||
static const char *mout_group2_6442_p[] __initdata = {
|
||||
"fin_pll",
|
||||
"none",
|
||||
"none",
|
||||
|
@ -322,7 +322,7 @@ static const char *mout_group2_6442_p[] __initconst = {
|
|||
"mout_vpll",
|
||||
};
|
||||
|
||||
static const char *mout_audio0_6442_p[] __initconst = {
|
||||
static const char *mout_audio0_6442_p[] __initdata = {
|
||||
"fin_pll",
|
||||
"pcmcdclk0",
|
||||
"none",
|
||||
|
@ -334,7 +334,7 @@ static const char *mout_audio0_6442_p[] __initconst = {
|
|||
"mout_vpll",
|
||||
};
|
||||
|
||||
static const char *mout_audio1_6442_p[] __initconst = {
|
||||
static const char *mout_audio1_6442_p[] __initdata = {
|
||||
"i2scdclk1",
|
||||
"pcmcdclk1",
|
||||
"none",
|
||||
|
@ -347,7 +347,7 @@ static const char *mout_audio1_6442_p[] __initconst = {
|
|||
"fin_pll",
|
||||
};
|
||||
|
||||
static const char *mout_clksel_p[] __initconst = {
|
||||
static const char *mout_clksel_p[] __initdata = {
|
||||
"fout_apll_clkout",
|
||||
"fout_mpll_clkout",
|
||||
"fout_epll",
|
||||
|
@ -370,7 +370,7 @@ static const char *mout_clksel_p[] __initconst = {
|
|||
"div_dclk"
|
||||
};
|
||||
|
||||
static const char *mout_clksel_6442_p[] __initconst = {
|
||||
static const char *mout_clksel_6442_p[] __initdata = {
|
||||
"fout_apll_clkout",
|
||||
"fout_mpll_clkout",
|
||||
"fout_epll",
|
||||
|
@ -393,7 +393,7 @@ static const char *mout_clksel_6442_p[] __initconst = {
|
|||
"div_dclk"
|
||||
};
|
||||
|
||||
static const char *mout_clkout_p[] __initconst = {
|
||||
static const char *mout_clkout_p[] __initdata = {
|
||||
"dout_clkout",
|
||||
"none",
|
||||
"xxti",
|
||||
|
|
|
@ -1057,7 +1057,7 @@ static struct clk * __init st_clk_register_quadfs_fsynth(
|
|||
return clk;
|
||||
}
|
||||
|
||||
static struct of_device_id quadfs_of_match[] = {
|
||||
static const struct of_device_id quadfs_of_match[] = {
|
||||
{
|
||||
.compatible = "st,stih416-quadfs216",
|
||||
.data = &st_fs216c65_416
|
||||
|
|
|
@ -341,7 +341,7 @@ static struct clkgena_divmux_data st_divmux_c32odf3 = {
|
|||
.fb_start_bit_idx = 24,
|
||||
};
|
||||
|
||||
static struct of_device_id clkgena_divmux_of_match[] = {
|
||||
static const struct of_device_id clkgena_divmux_of_match[] = {
|
||||
{
|
||||
.compatible = "st,clkgena-divmux-c65-hs",
|
||||
.data = &st_divmux_c65hs,
|
||||
|
@ -479,7 +479,7 @@ static struct clkgena_prediv_data prediv_c32_data = {
|
|||
.table = prediv_table16,
|
||||
};
|
||||
|
||||
static struct of_device_id clkgena_prediv_of_match[] = {
|
||||
static const struct of_device_id clkgena_prediv_of_match[] = {
|
||||
{ .compatible = "st,clkgena-prediv-c65", .data = &prediv_c65_data },
|
||||
{ .compatible = "st,clkgena-prediv-c32", .data = &prediv_c32_data },
|
||||
{}
|
||||
|
@ -586,7 +586,7 @@ static struct clkgen_mux_data stih407_a9_mux_data = {
|
|||
.width = 2,
|
||||
};
|
||||
|
||||
static struct of_device_id mux_of_match[] = {
|
||||
static const struct of_device_id mux_of_match[] = {
|
||||
{
|
||||
.compatible = "st,stih416-clkgenc-vcc-hd",
|
||||
.data = &clkgen_mux_c_vcc_hd_416,
|
||||
|
@ -693,7 +693,7 @@ static struct clkgen_vcc_data st_clkgenf_vcc_416 = {
|
|||
.lock = &clkgenf_lock,
|
||||
};
|
||||
|
||||
static struct of_device_id vcc_of_match[] = {
|
||||
static const struct of_device_id vcc_of_match[] = {
|
||||
{ .compatible = "st,stih416-clkgenc", .data = &st_clkgenc_vcc_416 },
|
||||
{ .compatible = "st,stih416-clkgenf", .data = &st_clkgenf_vcc_416 },
|
||||
{}
|
||||
|
|
|
@ -593,7 +593,7 @@ static struct clk * __init clkgen_odf_register(const char *parent_name,
|
|||
return clk;
|
||||
}
|
||||
|
||||
static struct of_device_id c32_pll_of_match[] = {
|
||||
static const struct of_device_id c32_pll_of_match[] = {
|
||||
{
|
||||
.compatible = "st,plls-c32-a1x-0",
|
||||
.data = &st_pll3200c32_a1x_0,
|
||||
|
@ -708,7 +708,7 @@ err:
|
|||
}
|
||||
CLK_OF_DECLARE(clkgen_c32_pll, "st,clkgen-plls-c32", clkgen_c32_pll_setup);
|
||||
|
||||
static struct of_device_id c32_gpu_pll_of_match[] = {
|
||||
static const struct of_device_id c32_gpu_pll_of_match[] = {
|
||||
{
|
||||
.compatible = "st,stih415-gpu-pll-c32",
|
||||
.data = &st_pll1200c32_gpu_415,
|
||||
|
|
|
@ -9,6 +9,7 @@ obj-y += clk-mod0.o
|
|||
obj-y += clk-sun8i-mbus.o
|
||||
obj-y += clk-sun9i-core.o
|
||||
obj-y += clk-sun9i-mmc.o
|
||||
obj-y += clk-usb.o
|
||||
|
||||
obj-$(CONFIG_MFD_SUN6I_PRCM) += \
|
||||
clk-sun6i-ar100.o clk-sun6i-apb0.o clk-sun6i-apb0-gates.o \
|
||||
|
|
|
@ -481,6 +481,45 @@ static void sun6i_a31_get_pll6_factors(u32 *freq, u32 parent_rate,
|
|||
*n = DIV_ROUND_UP(div, (*k+1)) - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* sun5i_a13_get_ahb_factors() - calculates m, p factors for AHB
|
||||
* AHB rate is calculated as follows
|
||||
* rate = parent_rate >> p
|
||||
*/
|
||||
|
||||
static void sun5i_a13_get_ahb_factors(u32 *freq, u32 parent_rate,
|
||||
u8 *n, u8 *k, u8 *m, u8 *p)
|
||||
{
|
||||
u32 div;
|
||||
|
||||
/* divide only */
|
||||
if (parent_rate < *freq)
|
||||
*freq = parent_rate;
|
||||
|
||||
/*
|
||||
* user manual says valid speed is 8k ~ 276M, but tests show it
|
||||
* can work at speeds up to 300M, just after reparenting to pll6
|
||||
*/
|
||||
if (*freq < 8000)
|
||||
*freq = 8000;
|
||||
if (*freq > 300000000)
|
||||
*freq = 300000000;
|
||||
|
||||
div = order_base_2(DIV_ROUND_UP(parent_rate, *freq));
|
||||
|
||||
/* p = 0 ~ 3 */
|
||||
if (div > 3)
|
||||
div = 3;
|
||||
|
||||
*freq = parent_rate >> div;
|
||||
|
||||
/* we were called to round the frequency, we can now return */
|
||||
if (p == NULL)
|
||||
return;
|
||||
|
||||
*p = div;
|
||||
}
|
||||
|
||||
/**
|
||||
* sun4i_get_apb1_factors() - calculates m, p factors for APB1
|
||||
* APB1 rate is calculated as follows
|
||||
|
@ -616,6 +655,11 @@ static struct clk_factors_config sun6i_a31_pll6_config = {
|
|||
.n_start = 1,
|
||||
};
|
||||
|
||||
static struct clk_factors_config sun5i_a13_ahb_config = {
|
||||
.pshift = 4,
|
||||
.pwidth = 2,
|
||||
};
|
||||
|
||||
static struct clk_factors_config sun4i_apb1_config = {
|
||||
.mshift = 0,
|
||||
.mwidth = 5,
|
||||
|
@ -676,6 +720,13 @@ static const struct factors_data sun6i_a31_pll6_data __initconst = {
|
|||
.name = "pll6x2",
|
||||
};
|
||||
|
||||
static const struct factors_data sun5i_a13_ahb_data __initconst = {
|
||||
.mux = 6,
|
||||
.muxmask = BIT(1) | BIT(0),
|
||||
.table = &sun5i_a13_ahb_config,
|
||||
.getter = sun5i_a13_get_ahb_factors,
|
||||
};
|
||||
|
||||
static const struct factors_data sun4i_apb1_data __initconst = {
|
||||
.mux = 24,
|
||||
.muxmask = BIT(1) | BIT(0),
|
||||
|
@ -837,59 +888,6 @@ static void __init sunxi_divider_clk_setup(struct device_node *node,
|
|||
|
||||
|
||||
|
||||
/**
|
||||
* sunxi_gates_reset... - reset bits in leaf gate clk registers handling
|
||||
*/
|
||||
|
||||
struct gates_reset_data {
|
||||
void __iomem *reg;
|
||||
spinlock_t *lock;
|
||||
struct reset_controller_dev rcdev;
|
||||
};
|
||||
|
||||
static int sunxi_gates_reset_assert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct gates_reset_data *data = container_of(rcdev,
|
||||
struct gates_reset_data,
|
||||
rcdev);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
spin_lock_irqsave(data->lock, flags);
|
||||
|
||||
reg = readl(data->reg);
|
||||
writel(reg & ~BIT(id), data->reg);
|
||||
|
||||
spin_unlock_irqrestore(data->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sunxi_gates_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct gates_reset_data *data = container_of(rcdev,
|
||||
struct gates_reset_data,
|
||||
rcdev);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
spin_lock_irqsave(data->lock, flags);
|
||||
|
||||
reg = readl(data->reg);
|
||||
writel(reg | BIT(id), data->reg);
|
||||
|
||||
spin_unlock_irqrestore(data->lock, flags);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct reset_control_ops sunxi_gates_reset_ops = {
|
||||
.assert = sunxi_gates_reset_assert,
|
||||
.deassert = sunxi_gates_reset_deassert,
|
||||
};
|
||||
|
||||
/**
|
||||
* sunxi_gates_clk_setup() - Setup function for leaf gates on clocks
|
||||
*/
|
||||
|
@ -898,7 +896,6 @@ static struct reset_control_ops sunxi_gates_reset_ops = {
|
|||
|
||||
struct gates_data {
|
||||
DECLARE_BITMAP(mask, SUNXI_GATES_MAX_SIZE);
|
||||
u32 reset_mask;
|
||||
};
|
||||
|
||||
static const struct gates_data sun4i_axi_gates_data __initconst = {
|
||||
|
@ -997,26 +994,10 @@ static const struct gates_data sun8i_a23_apb2_gates_data __initconst = {
|
|||
.mask = {0x1F0007},
|
||||
};
|
||||
|
||||
static const struct gates_data sun4i_a10_usb_gates_data __initconst = {
|
||||
.mask = {0x1C0},
|
||||
.reset_mask = 0x07,
|
||||
};
|
||||
|
||||
static const struct gates_data sun5i_a13_usb_gates_data __initconst = {
|
||||
.mask = {0x140},
|
||||
.reset_mask = 0x03,
|
||||
};
|
||||
|
||||
static const struct gates_data sun6i_a31_usb_gates_data __initconst = {
|
||||
.mask = { BIT(18) | BIT(17) | BIT(16) | BIT(10) | BIT(9) | BIT(8) },
|
||||
.reset_mask = BIT(2) | BIT(1) | BIT(0),
|
||||
};
|
||||
|
||||
static void __init sunxi_gates_clk_setup(struct device_node *node,
|
||||
struct gates_data *data)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct gates_reset_data *reset_data;
|
||||
const char *clk_parent;
|
||||
const char *clk_name;
|
||||
void __iomem *reg;
|
||||
|
@ -1057,21 +1038,6 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
|
|||
clk_data->clk_num = i;
|
||||
|
||||
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
/* Register a reset controler for gates with reset bits */
|
||||
if (data->reset_mask == 0)
|
||||
return;
|
||||
|
||||
reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
|
||||
if (!reset_data)
|
||||
return;
|
||||
|
||||
reset_data->reg = reg;
|
||||
reset_data->lock = &clk_lock;
|
||||
reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1;
|
||||
reset_data->rcdev.ops = &sunxi_gates_reset_ops;
|
||||
reset_data->rcdev.of_node = node;
|
||||
reset_controller_register(&reset_data->rcdev);
|
||||
}
|
||||
|
||||
|
||||
|
@ -1080,13 +1046,20 @@ static void __init sunxi_gates_clk_setup(struct device_node *node,
|
|||
* sunxi_divs_clk_setup() helper data
|
||||
*/
|
||||
|
||||
#define SUNXI_DIVS_MAX_QTY 2
|
||||
#define SUNXI_DIVS_MAX_QTY 4
|
||||
#define SUNXI_DIVISOR_WIDTH 2
|
||||
|
||||
struct divs_data {
|
||||
const struct factors_data *factors; /* data for the factor clock */
|
||||
int ndivs; /* number of children */
|
||||
int ndivs; /* number of outputs */
|
||||
/*
|
||||
* List of outputs. Refer to the diagram for sunxi_divs_clk_setup():
|
||||
* self or base factor clock refers to the output from the pll
|
||||
* itself. The remaining refer to fixed or configurable divider
|
||||
* outputs.
|
||||
*/
|
||||
struct {
|
||||
u8 self; /* is it the base factor clock? (only one) */
|
||||
u8 fixed; /* is it a fixed divisor? if not... */
|
||||
struct clk_div_table *table; /* is it a table based divisor? */
|
||||
u8 shift; /* otherwise it's a normal divisor with this shift */
|
||||
|
@ -1109,23 +1082,27 @@ static const struct divs_data pll5_divs_data __initconst = {
|
|||
.div = {
|
||||
{ .shift = 0, .pow = 0, }, /* M, DDR */
|
||||
{ .shift = 16, .pow = 1, }, /* P, other */
|
||||
/* No output for the base factor clock */
|
||||
}
|
||||
};
|
||||
|
||||
static const struct divs_data pll6_divs_data __initconst = {
|
||||
.factors = &sun4i_pll6_data,
|
||||
.ndivs = 2,
|
||||
.ndivs = 4,
|
||||
.div = {
|
||||
{ .shift = 0, .table = pll6_sata_tbl, .gate = 14 }, /* M, SATA */
|
||||
{ .fixed = 2 }, /* P, other */
|
||||
{ .self = 1 }, /* base factor clock, 2x */
|
||||
{ .fixed = 4 }, /* pll6 / 4, used as ahb input */
|
||||
}
|
||||
};
|
||||
|
||||
static const struct divs_data sun6i_a31_pll6_divs_data __initconst = {
|
||||
.factors = &sun6i_a31_pll6_data,
|
||||
.ndivs = 1,
|
||||
.ndivs = 2,
|
||||
.div = {
|
||||
{ .fixed = 2 }, /* normal output */
|
||||
{ .self = 1 }, /* base factor clock, 2x */
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1156,6 +1133,10 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
|
|||
int ndivs = SUNXI_DIVS_MAX_QTY, i = 0;
|
||||
int flags, clkflags;
|
||||
|
||||
/* if number of children known, use it */
|
||||
if (data->ndivs)
|
||||
ndivs = data->ndivs;
|
||||
|
||||
/* Set up factor clock that we will be dividing */
|
||||
pclk = sunxi_factors_clk_setup(node, data->factors);
|
||||
parent = __clk_get_name(pclk);
|
||||
|
@ -1166,7 +1147,7 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
|
|||
if (!clk_data)
|
||||
return;
|
||||
|
||||
clks = kzalloc((SUNXI_DIVS_MAX_QTY+1) * sizeof(*clks), GFP_KERNEL);
|
||||
clks = kcalloc(ndivs, sizeof(*clks), GFP_KERNEL);
|
||||
if (!clks)
|
||||
goto free_clkdata;
|
||||
|
||||
|
@ -1176,15 +1157,17 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
|
|||
* our RAM clock! */
|
||||
clkflags = !strcmp("pll5", parent) ? 0 : CLK_SET_RATE_PARENT;
|
||||
|
||||
/* if number of children known, use it */
|
||||
if (data->ndivs)
|
||||
ndivs = data->ndivs;
|
||||
|
||||
for (i = 0; i < ndivs; i++) {
|
||||
if (of_property_read_string_index(node, "clock-output-names",
|
||||
i, &clk_name) != 0)
|
||||
break;
|
||||
|
||||
/* If this is the base factor clock, only update clks */
|
||||
if (data->div[i].self) {
|
||||
clk_data->clks[i] = pclk;
|
||||
continue;
|
||||
}
|
||||
|
||||
gate_hw = NULL;
|
||||
rate_hw = NULL;
|
||||
rate_ops = NULL;
|
||||
|
@ -1243,9 +1226,6 @@ static void __init sunxi_divs_clk_setup(struct device_node *node,
|
|||
clk_register_clkdev(clks[i], clk_name, NULL);
|
||||
}
|
||||
|
||||
/* The last clock available on the getter is the parent */
|
||||
clks[i++] = pclk;
|
||||
|
||||
/* Adjust to the real max */
|
||||
clk_data->clk_num = i;
|
||||
|
||||
|
@ -1269,6 +1249,7 @@ static const struct of_device_id clk_factors_match[] __initconst = {
|
|||
{.compatible = "allwinner,sun6i-a31-pll1-clk", .data = &sun6i_a31_pll1_data,},
|
||||
{.compatible = "allwinner,sun8i-a23-pll1-clk", .data = &sun8i_a23_pll1_data,},
|
||||
{.compatible = "allwinner,sun7i-a20-pll4-clk", .data = &sun7i_a20_pll4_data,},
|
||||
{.compatible = "allwinner,sun5i-a13-ahb-clk", .data = &sun5i_a13_ahb_data,},
|
||||
{.compatible = "allwinner,sun4i-a10-apb1-clk", .data = &sun4i_apb1_data,},
|
||||
{.compatible = "allwinner,sun7i-a20-out-clk", .data = &sun7i_a20_out_data,},
|
||||
{}
|
||||
|
@ -1324,9 +1305,6 @@ static const struct of_device_id clk_gates_match[] __initconst = {
|
|||
{.compatible = "allwinner,sun9i-a80-apb1-gates-clk", .data = &sun9i_a80_apb1_gates_data,},
|
||||
{.compatible = "allwinner,sun6i-a31-apb2-gates-clk", .data = &sun6i_a31_apb2_gates_data,},
|
||||
{.compatible = "allwinner,sun8i-a23-apb2-gates-clk", .data = &sun8i_a23_apb2_gates_data,},
|
||||
{.compatible = "allwinner,sun4i-a10-usb-clk", .data = &sun4i_a10_usb_gates_data,},
|
||||
{.compatible = "allwinner,sun5i-a13-usb-clk", .data = &sun5i_a13_usb_gates_data,},
|
||||
{.compatible = "allwinner,sun6i-a31-usb-clk", .data = &sun6i_a31_usb_gates_data,},
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -1348,15 +1326,15 @@ static void __init sunxi_init_clocks(const char *clocks[], int nclocks)
|
|||
{
|
||||
unsigned int i;
|
||||
|
||||
/* Register divided output clocks */
|
||||
of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup);
|
||||
|
||||
/* Register factor clocks */
|
||||
of_sunxi_table_clock_setup(clk_factors_match, sunxi_factors_clk_setup);
|
||||
|
||||
/* Register divider clocks */
|
||||
of_sunxi_table_clock_setup(clk_div_match, sunxi_divider_clk_setup);
|
||||
|
||||
/* Register divided output clocks */
|
||||
of_sunxi_table_clock_setup(clk_divs_match, sunxi_divs_clk_setup);
|
||||
|
||||
/* Register mux clocks */
|
||||
of_sunxi_table_clock_setup(clk_mux_match, sunxi_mux_clk_setup);
|
||||
|
||||
|
@ -1385,6 +1363,7 @@ static void __init sun4i_a10_init_clocks(struct device_node *node)
|
|||
CLK_OF_DECLARE(sun4i_a10_clk_init, "allwinner,sun4i-a10", sun4i_a10_init_clocks);
|
||||
|
||||
static const char *sun5i_critical_clocks[] __initdata = {
|
||||
"cpu",
|
||||
"pll5_ddr",
|
||||
"ahb_sdram",
|
||||
};
|
||||
|
|
|
@ -0,0 +1,233 @@
|
|||
/*
|
||||
* Copyright 2013-2015 Emilio López
|
||||
*
|
||||
* Emilio López <emilio@elopez.com.ar>
|
||||
*
|
||||
* 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; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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/clk-provider.h>
|
||||
#include <linux/clkdev.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/reset-controller.h>
|
||||
#include <linux/spinlock.h>
|
||||
|
||||
|
||||
/**
|
||||
* sunxi_usb_reset... - reset bits in usb clk registers handling
|
||||
*/
|
||||
|
||||
struct usb_reset_data {
|
||||
void __iomem *reg;
|
||||
spinlock_t *lock;
|
||||
struct clk *clk;
|
||||
struct reset_controller_dev rcdev;
|
||||
};
|
||||
|
||||
static int sunxi_usb_reset_assert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct usb_reset_data *data = container_of(rcdev,
|
||||
struct usb_reset_data,
|
||||
rcdev);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
clk_prepare_enable(data->clk);
|
||||
spin_lock_irqsave(data->lock, flags);
|
||||
|
||||
reg = readl(data->reg);
|
||||
writel(reg & ~BIT(id), data->reg);
|
||||
|
||||
spin_unlock_irqrestore(data->lock, flags);
|
||||
clk_disable_unprepare(data->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sunxi_usb_reset_deassert(struct reset_controller_dev *rcdev,
|
||||
unsigned long id)
|
||||
{
|
||||
struct usb_reset_data *data = container_of(rcdev,
|
||||
struct usb_reset_data,
|
||||
rcdev);
|
||||
unsigned long flags;
|
||||
u32 reg;
|
||||
|
||||
clk_prepare_enable(data->clk);
|
||||
spin_lock_irqsave(data->lock, flags);
|
||||
|
||||
reg = readl(data->reg);
|
||||
writel(reg | BIT(id), data->reg);
|
||||
|
||||
spin_unlock_irqrestore(data->lock, flags);
|
||||
clk_disable_unprepare(data->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct reset_control_ops sunxi_usb_reset_ops = {
|
||||
.assert = sunxi_usb_reset_assert,
|
||||
.deassert = sunxi_usb_reset_deassert,
|
||||
};
|
||||
|
||||
/**
|
||||
* sunxi_usb_clk_setup() - Setup function for usb gate clocks
|
||||
*/
|
||||
|
||||
#define SUNXI_USB_MAX_SIZE 32
|
||||
|
||||
struct usb_clk_data {
|
||||
u32 clk_mask;
|
||||
u32 reset_mask;
|
||||
bool reset_needs_clk;
|
||||
};
|
||||
|
||||
static void __init sunxi_usb_clk_setup(struct device_node *node,
|
||||
const struct usb_clk_data *data,
|
||||
spinlock_t *lock)
|
||||
{
|
||||
struct clk_onecell_data *clk_data;
|
||||
struct usb_reset_data *reset_data;
|
||||
const char *clk_parent;
|
||||
const char *clk_name;
|
||||
void __iomem *reg;
|
||||
int qty;
|
||||
int i = 0;
|
||||
int j = 0;
|
||||
|
||||
reg = of_io_request_and_map(node, 0, of_node_full_name(node));
|
||||
if (IS_ERR(reg))
|
||||
return;
|
||||
|
||||
clk_parent = of_clk_get_parent_name(node, 0);
|
||||
if (!clk_parent)
|
||||
return;
|
||||
|
||||
/* Worst-case size approximation and memory allocation */
|
||||
qty = find_last_bit((unsigned long *)&data->clk_mask,
|
||||
SUNXI_USB_MAX_SIZE);
|
||||
|
||||
clk_data = kmalloc(sizeof(struct clk_onecell_data), GFP_KERNEL);
|
||||
if (!clk_data)
|
||||
return;
|
||||
|
||||
clk_data->clks = kzalloc((qty+1) * sizeof(struct clk *), GFP_KERNEL);
|
||||
if (!clk_data->clks) {
|
||||
kfree(clk_data);
|
||||
return;
|
||||
}
|
||||
|
||||
for_each_set_bit(i, (unsigned long *)&data->clk_mask,
|
||||
SUNXI_USB_MAX_SIZE) {
|
||||
of_property_read_string_index(node, "clock-output-names",
|
||||
j, &clk_name);
|
||||
clk_data->clks[i] = clk_register_gate(NULL, clk_name,
|
||||
clk_parent, 0,
|
||||
reg, i, 0, lock);
|
||||
WARN_ON(IS_ERR(clk_data->clks[i]));
|
||||
|
||||
j++;
|
||||
}
|
||||
|
||||
/* Adjust to the real max */
|
||||
clk_data->clk_num = i;
|
||||
|
||||
of_clk_add_provider(node, of_clk_src_onecell_get, clk_data);
|
||||
|
||||
/* Register a reset controller for usb with reset bits */
|
||||
if (data->reset_mask == 0)
|
||||
return;
|
||||
|
||||
reset_data = kzalloc(sizeof(*reset_data), GFP_KERNEL);
|
||||
if (!reset_data)
|
||||
return;
|
||||
|
||||
if (data->reset_needs_clk) {
|
||||
reset_data->clk = of_clk_get(node, 0);
|
||||
if (IS_ERR(reset_data->clk)) {
|
||||
pr_err("Could not get clock for reset controls\n");
|
||||
kfree(reset_data);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
reset_data->reg = reg;
|
||||
reset_data->lock = lock;
|
||||
reset_data->rcdev.nr_resets = __fls(data->reset_mask) + 1;
|
||||
reset_data->rcdev.ops = &sunxi_usb_reset_ops;
|
||||
reset_data->rcdev.of_node = node;
|
||||
reset_controller_register(&reset_data->rcdev);
|
||||
}
|
||||
|
||||
static const struct usb_clk_data sun4i_a10_usb_clk_data __initconst = {
|
||||
.clk_mask = BIT(8) | BIT(7) | BIT(6),
|
||||
.reset_mask = BIT(2) | BIT(1) | BIT(0),
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(sun4i_a10_usb_lock);
|
||||
|
||||
static void __init sun4i_a10_usb_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_usb_clk_setup(node, &sun4i_a10_usb_clk_data, &sun4i_a10_usb_lock);
|
||||
}
|
||||
CLK_OF_DECLARE(sun4i_a10_usb, "allwinner,sun4i-a10-usb-clk", sun4i_a10_usb_setup);
|
||||
|
||||
static const struct usb_clk_data sun5i_a13_usb_clk_data __initconst = {
|
||||
.clk_mask = BIT(8) | BIT(6),
|
||||
.reset_mask = BIT(1) | BIT(0),
|
||||
};
|
||||
|
||||
static void __init sun5i_a13_usb_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_usb_clk_setup(node, &sun5i_a13_usb_clk_data, &sun4i_a10_usb_lock);
|
||||
}
|
||||
CLK_OF_DECLARE(sun5i_a13_usb, "allwinner,sun5i-a13-usb-clk", sun5i_a13_usb_setup);
|
||||
|
||||
static const struct usb_clk_data sun6i_a31_usb_clk_data __initconst = {
|
||||
.clk_mask = BIT(18) | BIT(17) | BIT(16) | BIT(10) | BIT(9) | BIT(8),
|
||||
.reset_mask = BIT(2) | BIT(1) | BIT(0),
|
||||
};
|
||||
|
||||
static void __init sun6i_a31_usb_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_usb_clk_setup(node, &sun6i_a31_usb_clk_data, &sun4i_a10_usb_lock);
|
||||
}
|
||||
CLK_OF_DECLARE(sun6i_a31_usb, "allwinner,sun6i-a31-usb-clk", sun6i_a31_usb_setup);
|
||||
|
||||
static const struct usb_clk_data sun9i_a80_usb_mod_data __initconst = {
|
||||
.clk_mask = BIT(6) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1),
|
||||
.reset_mask = BIT(19) | BIT(18) | BIT(17),
|
||||
.reset_needs_clk = 1,
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(a80_usb_mod_lock);
|
||||
|
||||
static void __init sun9i_a80_usb_mod_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_usb_clk_setup(node, &sun9i_a80_usb_mod_data, &a80_usb_mod_lock);
|
||||
}
|
||||
CLK_OF_DECLARE(sun9i_a80_usb_mod, "allwinner,sun9i-a80-usb-mod-clk", sun9i_a80_usb_mod_setup);
|
||||
|
||||
static const struct usb_clk_data sun9i_a80_usb_phy_data __initconst = {
|
||||
.clk_mask = BIT(10) | BIT(5) | BIT(4) | BIT(3) | BIT(2) | BIT(1),
|
||||
.reset_mask = BIT(21) | BIT(20) | BIT(19) | BIT(18) | BIT(17),
|
||||
.reset_needs_clk = 1,
|
||||
};
|
||||
|
||||
static DEFINE_SPINLOCK(a80_usb_phy_lock);
|
||||
|
||||
static void __init sun9i_a80_usb_phy_setup(struct device_node *node)
|
||||
{
|
||||
sunxi_usb_clk_setup(node, &sun9i_a80_usb_phy_data, &a80_usb_phy_lock);
|
||||
}
|
||||
CLK_OF_DECLARE(sun9i_a80_usb_phy, "allwinner,sun9i-a80-usb-phy-clk", sun9i_a80_usb_phy_setup);
|
|
@ -981,7 +981,7 @@ static int clk_pllxc_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
struct tegra_clk_pll *pll = to_clk_pll(hw);
|
||||
struct tegra_clk_pll_freq_table cfg, old_cfg;
|
||||
unsigned long flags = 0;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
|
||||
ret = _pll_ramp_calc_pll(hw, &cfg, rate, parent_rate);
|
||||
if (ret < 0)
|
||||
|
@ -1005,7 +1005,7 @@ static long clk_pll_ramp_round_rate(struct clk_hw *hw, unsigned long rate,
|
|||
unsigned long *prate)
|
||||
{
|
||||
struct tegra_clk_pll_freq_table cfg;
|
||||
int ret = 0, p_div;
|
||||
int ret, p_div;
|
||||
u64 output_rate = *prate;
|
||||
|
||||
ret = _pll_ramp_calc_pll(hw, &cfg, rate, *prate);
|
||||
|
@ -1073,7 +1073,7 @@ static int clk_pllc_enable(struct clk_hw *hw)
|
|||
{
|
||||
struct tegra_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 val;
|
||||
int ret = 0;
|
||||
int ret;
|
||||
unsigned long flags = 0;
|
||||
|
||||
if (pll->lock)
|
||||
|
@ -1223,6 +1223,7 @@ static long _pllre_calc_rate(struct tegra_clk_pll *pll,
|
|||
|
||||
return output_rate;
|
||||
}
|
||||
|
||||
static int clk_pllre_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
|
|
|
@ -30,13 +30,12 @@
|
|||
#define OSC_CTRL_OSC_FREQ_SHIFT 28
|
||||
#define OSC_CTRL_PLL_REF_DIV_SHIFT 26
|
||||
|
||||
int __init tegra_osc_clk_init(void __iomem *clk_base,
|
||||
struct tegra_clk *tegra_clks,
|
||||
unsigned long *input_freqs, int num,
|
||||
unsigned long *osc_freq,
|
||||
unsigned long *pll_ref_freq)
|
||||
int __init tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
|
||||
unsigned long *input_freqs, unsigned int num,
|
||||
unsigned int clk_m_div, unsigned long *osc_freq,
|
||||
unsigned long *pll_ref_freq)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk *clk, *osc;
|
||||
struct clk **dt_clk;
|
||||
u32 val, pll_ref_div;
|
||||
unsigned osc_idx;
|
||||
|
@ -54,22 +53,25 @@ int __init tegra_osc_clk_init(void __iomem *clk_base,
|
|||
return -EINVAL;
|
||||
}
|
||||
|
||||
dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, tegra_clks);
|
||||
osc = clk_register_fixed_rate(NULL, "osc", NULL, CLK_IS_ROOT,
|
||||
*osc_freq);
|
||||
|
||||
dt_clk = tegra_lookup_dt_id(tegra_clk_clk_m, clks);
|
||||
if (!dt_clk)
|
||||
return 0;
|
||||
|
||||
clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT,
|
||||
*osc_freq);
|
||||
clk = clk_register_fixed_factor(NULL, "clk_m", "osc",
|
||||
0, 1, clk_m_div);
|
||||
*dt_clk = clk;
|
||||
|
||||
/* pll_ref */
|
||||
val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3;
|
||||
pll_ref_div = 1 << val;
|
||||
dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, tegra_clks);
|
||||
dt_clk = tegra_lookup_dt_id(tegra_clk_pll_ref, clks);
|
||||
if (!dt_clk)
|
||||
return 0;
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m",
|
||||
clk = clk_register_fixed_factor(NULL, "pll_ref", "osc",
|
||||
0, 1, pll_ref_div);
|
||||
*dt_clk = clk;
|
||||
|
||||
|
|
|
@ -218,7 +218,7 @@
|
|||
.clk_id = _clk_id, \
|
||||
.p.parent_name = _parent_name, \
|
||||
.periph = TEGRA_CLK_PERIPH(0, 0, 0, 0, 0, 0, 0, \
|
||||
_clk_num, _gate_flags, 0, NULL), \
|
||||
_clk_num, _gate_flags, NULL, NULL), \
|
||||
.flags = _flags \
|
||||
}
|
||||
|
||||
|
|
|
@ -940,36 +940,6 @@ static struct clk **clks;
|
|||
static unsigned long osc_freq;
|
||||
static unsigned long pll_ref_freq;
|
||||
|
||||
static int __init tegra114_osc_clk_init(void __iomem *clk_base)
|
||||
{
|
||||
struct clk *clk;
|
||||
u32 val, pll_ref_div;
|
||||
|
||||
val = readl_relaxed(clk_base + OSC_CTRL);
|
||||
|
||||
osc_freq = tegra114_input_freq[val >> OSC_CTRL_OSC_FREQ_SHIFT];
|
||||
if (!osc_freq) {
|
||||
WARN_ON(1);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* clk_m */
|
||||
clk = clk_register_fixed_rate(NULL, "clk_m", NULL, CLK_IS_ROOT,
|
||||
osc_freq);
|
||||
clks[TEGRA114_CLK_CLK_M] = clk;
|
||||
|
||||
/* pll_ref */
|
||||
val = (val >> OSC_CTRL_PLL_REF_DIV_SHIFT) & 3;
|
||||
pll_ref_div = 1 << val;
|
||||
clk = clk_register_fixed_factor(NULL, "pll_ref", "clk_m",
|
||||
CLK_SET_RATE_PARENT, 1, pll_ref_div);
|
||||
clks[TEGRA114_CLK_PLL_REF] = clk;
|
||||
|
||||
pll_ref_freq = osc_freq / pll_ref_div;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void __init tegra114_fixed_clk_init(void __iomem *clk_base)
|
||||
{
|
||||
struct clk *clk;
|
||||
|
@ -1263,6 +1233,7 @@ static void tegra114_wait_cpu_in_reset(u32 cpu)
|
|||
cpu_relax();
|
||||
} while (!(reg & (1 << cpu))); /* check CPU been reset or not */
|
||||
}
|
||||
|
||||
static void tegra114_disable_cpu_clock(u32 cpu)
|
||||
{
|
||||
/* flow controller would take care in the power sequence. */
|
||||
|
@ -1351,7 +1322,6 @@ static void __init tegra114_clock_apply_init_table(void)
|
|||
tegra_init_from_table(init_table, clks, TEGRA114_CLK_CLK_MAX);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* tegra114_car_barrier - wait for pending writes to the CAR to complete
|
||||
*
|
||||
|
@ -1505,7 +1475,9 @@ static void __init tegra114_clock_init(struct device_node *np)
|
|||
if (!clks)
|
||||
return;
|
||||
|
||||
if (tegra114_osc_clk_init(clk_base) < 0)
|
||||
if (tegra_osc_clk_init(clk_base, tegra114_clks, tegra114_input_freq,
|
||||
ARRAY_SIZE(tegra114_input_freq), 1, &osc_freq,
|
||||
&pll_ref_freq) < 0)
|
||||
return;
|
||||
|
||||
tegra114_fixed_clk_init(clk_base);
|
||||
|
|
|
@ -1014,6 +1014,9 @@ static struct tegra_devclk devclks[] __initdata = {
|
|||
{ .con_id = "fuse", .dt_id = TEGRA124_CLK_FUSE },
|
||||
{ .dev_id = "rtc-tegra", .dt_id = TEGRA124_CLK_RTC },
|
||||
{ .dev_id = "timer", .dt_id = TEGRA124_CLK_TIMER },
|
||||
{ .con_id = "hda", .dt_id = TEGRA124_CLK_HDA },
|
||||
{ .con_id = "hda2codec_2x", .dt_id = TEGRA124_CLK_HDA2CODEC_2X },
|
||||
{ .con_id = "hda2hdmi", .dt_id = TEGRA124_CLK_HDA2HDMI },
|
||||
};
|
||||
|
||||
static struct clk **clks;
|
||||
|
@ -1110,16 +1113,18 @@ static __init void tegra124_periph_clk_init(void __iomem *clk_base,
|
|||
1, 2);
|
||||
clks[TEGRA124_CLK_XUSB_SS_DIV2] = clk;
|
||||
|
||||
clk = clk_register_gate(NULL, "plld_dsi", "plld_out0", 0,
|
||||
clk = clk_register_gate(NULL, "pll_d_dsi_out", "pll_d_out0", 0,
|
||||
clk_base + PLLD_MISC, 30, 0, &pll_d_lock);
|
||||
clks[TEGRA124_CLK_PLLD_DSI] = clk;
|
||||
clks[TEGRA124_CLK_PLL_D_DSI_OUT] = clk;
|
||||
|
||||
clk = tegra_clk_register_periph_gate("dsia", "plld_dsi", 0, clk_base,
|
||||
0, 48, periph_clk_enb_refcnt);
|
||||
clk = tegra_clk_register_periph_gate("dsia", "pll_d_dsi_out", 0,
|
||||
clk_base, 0, 48,
|
||||
periph_clk_enb_refcnt);
|
||||
clks[TEGRA124_CLK_DSIA] = clk;
|
||||
|
||||
clk = tegra_clk_register_periph_gate("dsib", "plld_dsi", 0, clk_base,
|
||||
0, 82, periph_clk_enb_refcnt);
|
||||
clk = tegra_clk_register_periph_gate("dsib", "pll_d_dsi_out", 0,
|
||||
clk_base, 0, 82,
|
||||
periph_clk_enb_refcnt);
|
||||
clks[TEGRA124_CLK_DSIB] = clk;
|
||||
|
||||
/* emc mux */
|
||||
|
@ -1395,6 +1400,8 @@ static struct tegra_clk_init_table common_init_table[] __initdata = {
|
|||
static struct tegra_clk_init_table tegra124_init_table[] __initdata = {
|
||||
{TEGRA124_CLK_SOC_THERM, TEGRA124_CLK_PLL_P, 51000000, 0},
|
||||
{TEGRA124_CLK_CCLK_G, TEGRA124_CLK_CLK_MAX, 0, 1},
|
||||
{TEGRA124_CLK_HDA, TEGRA124_CLK_PLL_P, 102000000, 0},
|
||||
{TEGRA124_CLK_HDA2CODEC_2X, TEGRA124_CLK_PLL_P, 48000000, 0},
|
||||
/* This MUST be the last entry. */
|
||||
{TEGRA124_CLK_CLK_MAX, TEGRA124_CLK_CLK_MAX, 0, 0},
|
||||
};
|
||||
|
@ -1475,7 +1482,8 @@ static void __init tegra124_132_clock_init_pre(struct device_node *np)
|
|||
return;
|
||||
|
||||
if (tegra_osc_clk_init(clk_base, tegra124_clks, tegra124_input_freq,
|
||||
ARRAY_SIZE(tegra124_input_freq), &osc_freq, &pll_ref_freq) < 0)
|
||||
ARRAY_SIZE(tegra124_input_freq), 1, &osc_freq,
|
||||
&pll_ref_freq) < 0)
|
||||
return;
|
||||
|
||||
tegra_fixed_clk_init(tegra124_clks);
|
||||
|
|
|
@ -657,16 +657,16 @@ static struct tegra_devclk devclks[] __initdata = {
|
|||
{ .con_id = "fuse_burn", .dev_id = "fuse-tegra", .dt_id = TEGRA30_CLK_FUSE_BURN },
|
||||
{ .con_id = "apbif", .dev_id = "tegra30-ahub", .dt_id = TEGRA30_CLK_APBIF },
|
||||
{ .con_id = "hda2hdmi", .dev_id = "tegra30-hda", .dt_id = TEGRA30_CLK_HDA2HDMI },
|
||||
{ .dev_id = "tegra-apbdma", .dt_id = TEGRA30_CLK_APBDMA },
|
||||
{ .dev_id = "rtc-tegra", .dt_id = TEGRA30_CLK_RTC },
|
||||
{ .dev_id = "timer", .dt_id = TEGRA30_CLK_TIMER },
|
||||
{ .dev_id = "tegra-kbc", .dt_id = TEGRA30_CLK_KBC },
|
||||
{ .dev_id = "fsl-tegra-udc", .dt_id = TEGRA30_CLK_USBD },
|
||||
{ .dev_id = "tegra-ehci.1", .dt_id = TEGRA30_CLK_USB2 },
|
||||
{ .dev_id = "tegra-ehci.2", .dt_id = TEGRA30_CLK_USB2 },
|
||||
{ .dev_id = "kfuse-tegra", .dt_id = TEGRA30_CLK_KFUSE },
|
||||
{ .dev_id = "tegra_sata_cold", .dt_id = TEGRA30_CLK_SATA_COLD },
|
||||
{ .dev_id = "dtv", .dt_id = TEGRA30_CLK_DTV },
|
||||
{ .dev_id = "tegra-apbdma", .dt_id = TEGRA30_CLK_APBDMA },
|
||||
{ .dev_id = "rtc-tegra", .dt_id = TEGRA30_CLK_RTC },
|
||||
{ .dev_id = "timer", .dt_id = TEGRA30_CLK_TIMER },
|
||||
{ .dev_id = "tegra-kbc", .dt_id = TEGRA30_CLK_KBC },
|
||||
{ .dev_id = "fsl-tegra-udc", .dt_id = TEGRA30_CLK_USBD },
|
||||
{ .dev_id = "tegra-ehci.1", .dt_id = TEGRA30_CLK_USB2 },
|
||||
{ .dev_id = "tegra-ehci.2", .dt_id = TEGRA30_CLK_USB2 },
|
||||
{ .dev_id = "kfuse-tegra", .dt_id = TEGRA30_CLK_KFUSE },
|
||||
{ .dev_id = "tegra_sata_cold", .dt_id = TEGRA30_CLK_SATA_COLD },
|
||||
{ .dev_id = "dtv", .dt_id = TEGRA30_CLK_DTV },
|
||||
{ .dev_id = "tegra30-i2s.0", .dt_id = TEGRA30_CLK_I2S0 },
|
||||
{ .dev_id = "tegra30-i2s.1", .dt_id = TEGRA30_CLK_I2S1 },
|
||||
{ .dev_id = "tegra30-i2s.2", .dt_id = TEGRA30_CLK_I2S2 },
|
||||
|
@ -1434,7 +1434,8 @@ static void __init tegra30_clock_init(struct device_node *np)
|
|||
return;
|
||||
|
||||
if (tegra_osc_clk_init(clk_base, tegra30_clks, tegra30_input_freq,
|
||||
ARRAY_SIZE(tegra30_input_freq), &input_freq, NULL) < 0)
|
||||
ARRAY_SIZE(tegra30_input_freq), 1, &input_freq,
|
||||
NULL) < 0)
|
||||
return;
|
||||
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#define CLK_OUT_ENB_V 0x360
|
||||
#define CLK_OUT_ENB_W 0x364
|
||||
#define CLK_OUT_ENB_X 0x280
|
||||
#define CLK_OUT_ENB_Y 0x298
|
||||
#define CLK_OUT_ENB_SET_L 0x320
|
||||
#define CLK_OUT_ENB_CLR_L 0x324
|
||||
#define CLK_OUT_ENB_SET_H 0x328
|
||||
|
@ -42,6 +43,8 @@
|
|||
#define CLK_OUT_ENB_CLR_W 0x44c
|
||||
#define CLK_OUT_ENB_SET_X 0x284
|
||||
#define CLK_OUT_ENB_CLR_X 0x288
|
||||
#define CLK_OUT_ENB_SET_Y 0x29c
|
||||
#define CLK_OUT_ENB_CLR_Y 0x2a0
|
||||
|
||||
#define RST_DEVICES_L 0x004
|
||||
#define RST_DEVICES_H 0x008
|
||||
|
@ -50,6 +53,7 @@
|
|||
#define RST_DEVICES_V 0x358
|
||||
#define RST_DEVICES_W 0x35C
|
||||
#define RST_DEVICES_X 0x28C
|
||||
#define RST_DEVICES_Y 0x2a4
|
||||
#define RST_DEVICES_SET_L 0x300
|
||||
#define RST_DEVICES_CLR_L 0x304
|
||||
#define RST_DEVICES_SET_H 0x308
|
||||
|
@ -62,6 +66,8 @@
|
|||
#define RST_DEVICES_CLR_W 0x43c
|
||||
#define RST_DEVICES_SET_X 0x290
|
||||
#define RST_DEVICES_CLR_X 0x294
|
||||
#define RST_DEVICES_SET_Y 0x2a8
|
||||
#define RST_DEVICES_CLR_Y 0x2ac
|
||||
|
||||
/* Global data of Tegra CPU CAR ops */
|
||||
static struct tegra_cpu_car_ops dummy_car_ops;
|
||||
|
@ -122,6 +128,14 @@ static struct tegra_clk_periph_regs periph_regs[] = {
|
|||
.rst_set_reg = RST_DEVICES_SET_X,
|
||||
.rst_clr_reg = RST_DEVICES_CLR_X,
|
||||
},
|
||||
[6] = {
|
||||
.enb_reg = CLK_OUT_ENB_Y,
|
||||
.enb_set_reg = CLK_OUT_ENB_SET_Y,
|
||||
.enb_clr_reg = CLK_OUT_ENB_CLR_Y,
|
||||
.rst_reg = RST_DEVICES_Y,
|
||||
.rst_set_reg = RST_DEVICES_SET_Y,
|
||||
.rst_clr_reg = RST_DEVICES_CLR_Y,
|
||||
},
|
||||
};
|
||||
|
||||
static void __iomem *clk_base;
|
||||
|
@ -272,7 +286,7 @@ void __init tegra_add_of_provider(struct device_node *np)
|
|||
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
|
||||
|
||||
rst_ctlr.of_node = np;
|
||||
rst_ctlr.nr_resets = clk_num * 32;
|
||||
rst_ctlr.nr_resets = periph_banks * 32;
|
||||
reset_controller_register(&rst_ctlr);
|
||||
}
|
||||
|
||||
|
|
|
@ -548,7 +548,7 @@ struct clk *tegra_clk_register_super_mux(const char *name,
|
|||
u8 width, u8 pllx_index, u8 div2_index, spinlock_t *lock);
|
||||
|
||||
/**
|
||||
* struct clk_init_tabel - clock initialization table
|
||||
* struct clk_init_table - clock initialization table
|
||||
* @clk_id: clock id as mentioned in device tree bindings
|
||||
* @parent_id: parent clock id as mentioned in device tree bindings
|
||||
* @rate: rate to set
|
||||
|
@ -615,10 +615,10 @@ void tegra_periph_clk_init(void __iomem *clk_base, void __iomem *pmc_base,
|
|||
|
||||
void tegra_pmc_clk_init(void __iomem *pmc_base, struct tegra_clk *tegra_clks);
|
||||
void tegra_fixed_clk_init(struct tegra_clk *tegra_clks);
|
||||
int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *tegra_clks,
|
||||
unsigned long *input_freqs, int num,
|
||||
unsigned long *osc_freq,
|
||||
unsigned long *pll_ref_freq);
|
||||
int tegra_osc_clk_init(void __iomem *clk_base, struct tegra_clk *clks,
|
||||
unsigned long *input_freqs, unsigned int num,
|
||||
unsigned int clk_m_div, unsigned long *osc_freq,
|
||||
unsigned long *pll_ref_freq);
|
||||
void tegra_super_clk_gen4_init(void __iomem *clk_base,
|
||||
void __iomem *pmc_base, struct tegra_clk *tegra_clks,
|
||||
struct tegra_clk_pll_params *pll_params);
|
||||
|
|
|
@ -203,7 +203,7 @@ static void __init of_dra7_apll_setup(struct device_node *node)
|
|||
ad->control_reg = ti_clk_get_reg_addr(node, 0);
|
||||
ad->idlest_reg = ti_clk_get_reg_addr(node, 1);
|
||||
|
||||
if (!ad->control_reg || !ad->idlest_reg)
|
||||
if (IS_ERR(ad->control_reg) || IS_ERR(ad->idlest_reg))
|
||||
goto cleanup;
|
||||
|
||||
ad->idlest_mask = 0x1;
|
||||
|
@ -384,7 +384,8 @@ static void __init of_omap2_apll_setup(struct device_node *node)
|
|||
ad->autoidle_reg = ti_clk_get_reg_addr(node, 1);
|
||||
ad->idlest_reg = ti_clk_get_reg_addr(node, 2);
|
||||
|
||||
if (!ad->control_reg || !ad->autoidle_reg || !ad->idlest_reg)
|
||||
if (IS_ERR(ad->control_reg) || IS_ERR(ad->autoidle_reg) ||
|
||||
IS_ERR(ad->idlest_reg))
|
||||
goto cleanup;
|
||||
|
||||
clk = clk_register(NULL, &clk_hw->hw);
|
||||
|
|
|
@ -119,7 +119,7 @@ int __init of_ti_clk_autoidle_setup(struct device_node *node)
|
|||
clk->name = node->name;
|
||||
clk->reg = ti_clk_get_reg_addr(node, 0);
|
||||
|
||||
if (!clk->reg) {
|
||||
if (IS_ERR(clk->reg)) {
|
||||
kfree(clk);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
|
|
@ -4320,7 +4320,6 @@ static struct ti_clk_alias omap3xxx_clks[] = {
|
|||
CLK(NULL, "dpll3_m3x2_ck", &dpll3_m3x2_ck),
|
||||
CLK("etb", "emu_core_alwon_ck", &emu_core_alwon_ck),
|
||||
CLK(NULL, "sys_altclk", &sys_altclk),
|
||||
CLK(NULL, "mcbsp_clks", &mcbsp_clks),
|
||||
CLK(NULL, "sys_clkout1", &sys_clkout1),
|
||||
CLK(NULL, "dpll3_m2_ck", &dpll3_m2_ck),
|
||||
CLK(NULL, "core_ck", &core_ck),
|
||||
|
@ -4369,8 +4368,6 @@ static struct ti_clk_alias omap3xxx_clks[] = {
|
|||
CLK(NULL, "i2c3_fck", &i2c3_fck),
|
||||
CLK(NULL, "i2c2_fck", &i2c2_fck),
|
||||
CLK(NULL, "i2c1_fck", &i2c1_fck),
|
||||
CLK(NULL, "mcbsp5_fck", &mcbsp5_fck),
|
||||
CLK(NULL, "mcbsp1_fck", &mcbsp1_fck),
|
||||
CLK(NULL, "core_48m_fck", &core_48m_fck),
|
||||
CLK(NULL, "mcspi4_fck", &mcspi4_fck),
|
||||
CLK(NULL, "mcspi3_fck", &mcspi3_fck),
|
||||
|
@ -4409,8 +4406,6 @@ static struct ti_clk_alias omap3xxx_clks[] = {
|
|||
CLK(NULL, "uart1_ick", &uart1_ick),
|
||||
CLK(NULL, "gpt11_ick", &gpt11_ick),
|
||||
CLK(NULL, "gpt10_ick", &gpt10_ick),
|
||||
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick),
|
||||
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick),
|
||||
CLK(NULL, "mcbsp5_ick", &mcbsp5_ick),
|
||||
CLK(NULL, "mcbsp1_ick", &mcbsp1_ick),
|
||||
CLK(NULL, "omapctrl_ick", &omapctrl_ick),
|
||||
|
@ -4467,15 +4462,22 @@ static struct ti_clk_alias omap3xxx_clks[] = {
|
|||
CLK(NULL, "gpt4_ick", &gpt4_ick),
|
||||
CLK(NULL, "gpt3_ick", &gpt3_ick),
|
||||
CLK(NULL, "gpt2_ick", &gpt2_ick),
|
||||
CLK(NULL, "mcbsp_clks", &mcbsp_clks),
|
||||
CLK("omap-mcbsp.1", "ick", &mcbsp1_ick),
|
||||
CLK("omap-mcbsp.2", "ick", &mcbsp2_ick),
|
||||
CLK("omap-mcbsp.3", "ick", &mcbsp3_ick),
|
||||
CLK("omap-mcbsp.4", "ick", &mcbsp4_ick),
|
||||
CLK(NULL, "mcbsp4_ick", &mcbsp2_ick),
|
||||
CLK("omap-mcbsp.5", "ick", &mcbsp5_ick),
|
||||
CLK(NULL, "mcbsp1_ick", &mcbsp1_ick),
|
||||
CLK(NULL, "mcbsp2_ick", &mcbsp2_ick),
|
||||
CLK(NULL, "mcbsp3_ick", &mcbsp3_ick),
|
||||
CLK(NULL, "mcbsp2_ick", &mcbsp4_ick),
|
||||
CLK(NULL, "mcbsp4_ick", &mcbsp4_ick),
|
||||
CLK(NULL, "mcbsp5_ick", &mcbsp5_ick),
|
||||
CLK(NULL, "mcbsp1_fck", &mcbsp1_fck),
|
||||
CLK(NULL, "mcbsp2_fck", &mcbsp2_fck),
|
||||
CLK(NULL, "mcbsp3_fck", &mcbsp3_fck),
|
||||
CLK(NULL, "mcbsp4_fck", &mcbsp4_fck),
|
||||
CLK(NULL, "mcbsp5_fck", &mcbsp5_fck),
|
||||
CLK(NULL, "emu_src_mux_ck", &emu_src_mux_ck),
|
||||
CLK("etb", "emu_src_ck", &emu_src_ck),
|
||||
CLK(NULL, "emu_src_mux_ck", &emu_src_mux_ck),
|
||||
|
|
|
@ -34,7 +34,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
|
|||
DT_CLK(NULL, "omap_96m_alwon_fck", "omap_96m_alwon_fck"),
|
||||
DT_CLK("etb", "emu_core_alwon_ck", "emu_core_alwon_ck"),
|
||||
DT_CLK(NULL, "sys_altclk", "sys_altclk"),
|
||||
DT_CLK(NULL, "mcbsp_clks", "mcbsp_clks"),
|
||||
DT_CLK(NULL, "sys_clkout1", "sys_clkout1"),
|
||||
DT_CLK(NULL, "dpll1_ck", "dpll1_ck"),
|
||||
DT_CLK(NULL, "dpll1_x2_ck", "dpll1_x2_ck"),
|
||||
|
@ -82,8 +81,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
|
|||
DT_CLK(NULL, "i2c3_fck", "i2c3_fck"),
|
||||
DT_CLK(NULL, "i2c2_fck", "i2c2_fck"),
|
||||
DT_CLK(NULL, "i2c1_fck", "i2c1_fck"),
|
||||
DT_CLK(NULL, "mcbsp5_fck", "mcbsp5_fck"),
|
||||
DT_CLK(NULL, "mcbsp1_fck", "mcbsp1_fck"),
|
||||
DT_CLK(NULL, "core_48m_fck", "core_48m_fck"),
|
||||
DT_CLK(NULL, "mcspi4_fck", "mcspi4_fck"),
|
||||
DT_CLK(NULL, "mcspi3_fck", "mcspi3_fck"),
|
||||
|
@ -122,10 +119,6 @@ static struct ti_dt_clk omap3xxx_clks[] = {
|
|||
DT_CLK(NULL, "uart1_ick", "uart1_ick"),
|
||||
DT_CLK(NULL, "gpt11_ick", "gpt11_ick"),
|
||||
DT_CLK(NULL, "gpt10_ick", "gpt10_ick"),
|
||||
DT_CLK("omap-mcbsp.5", "ick", "mcbsp5_ick"),
|
||||
DT_CLK("omap-mcbsp.1", "ick", "mcbsp1_ick"),
|
||||
DT_CLK(NULL, "mcbsp5_ick", "mcbsp5_ick"),
|
||||
DT_CLK(NULL, "mcbsp1_ick", "mcbsp1_ick"),
|
||||
DT_CLK(NULL, "omapctrl_ick", "omapctrl_ick"),
|
||||
DT_CLK(NULL, "dss_tv_fck", "dss_tv_fck"),
|
||||
DT_CLK(NULL, "dss_96m_fck", "dss_96m_fck"),
|
||||
|
@ -179,15 +172,17 @@ static struct ti_dt_clk omap3xxx_clks[] = {
|
|||
DT_CLK(NULL, "gpt4_ick", "gpt4_ick"),
|
||||
DT_CLK(NULL, "gpt3_ick", "gpt3_ick"),
|
||||
DT_CLK(NULL, "gpt2_ick", "gpt2_ick"),
|
||||
DT_CLK("omap-mcbsp.2", "ick", "mcbsp2_ick"),
|
||||
DT_CLK("omap-mcbsp.3", "ick", "mcbsp3_ick"),
|
||||
DT_CLK("omap-mcbsp.4", "ick", "mcbsp4_ick"),
|
||||
DT_CLK(NULL, "mcbsp4_ick", "mcbsp2_ick"),
|
||||
DT_CLK(NULL, "mcbsp_clks", "mcbsp_clks"),
|
||||
DT_CLK(NULL, "mcbsp1_ick", "mcbsp1_ick"),
|
||||
DT_CLK(NULL, "mcbsp2_ick", "mcbsp2_ick"),
|
||||
DT_CLK(NULL, "mcbsp3_ick", "mcbsp3_ick"),
|
||||
DT_CLK(NULL, "mcbsp2_ick", "mcbsp4_ick"),
|
||||
DT_CLK(NULL, "mcbsp4_ick", "mcbsp4_ick"),
|
||||
DT_CLK(NULL, "mcbsp5_ick", "mcbsp5_ick"),
|
||||
DT_CLK(NULL, "mcbsp1_fck", "mcbsp1_fck"),
|
||||
DT_CLK(NULL, "mcbsp2_fck", "mcbsp2_fck"),
|
||||
DT_CLK(NULL, "mcbsp3_fck", "mcbsp3_fck"),
|
||||
DT_CLK(NULL, "mcbsp4_fck", "mcbsp4_fck"),
|
||||
DT_CLK(NULL, "mcbsp5_fck", "mcbsp5_fck"),
|
||||
DT_CLK("etb", "emu_src_ck", "emu_src_ck"),
|
||||
DT_CLK(NULL, "emu_src_ck", "emu_src_ck"),
|
||||
DT_CLK(NULL, "pclk_fck", "pclk_fck"),
|
||||
|
|
|
@ -249,17 +249,6 @@ static struct ti_dt_clk omap44xx_clks[] = {
|
|||
DT_CLK("usbhs_tll", "usbtll_fck", "dummy_ck"),
|
||||
DT_CLK("omap_wdt", "ick", "dummy_ck"),
|
||||
DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
|
||||
DT_CLK("omap_timer.1", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.2", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.3", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.4", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.9", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.10", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.11", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("omap_timer.5", "timer_sys_ck", "syc_clk_div_ck"),
|
||||
DT_CLK("omap_timer.6", "timer_sys_ck", "syc_clk_div_ck"),
|
||||
DT_CLK("omap_timer.7", "timer_sys_ck", "syc_clk_div_ck"),
|
||||
DT_CLK("omap_timer.8", "timer_sys_ck", "syc_clk_div_ck"),
|
||||
DT_CLK("4a318000.timer", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin_ck"),
|
||||
DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin_ck"),
|
||||
|
|
|
@ -208,17 +208,17 @@ static struct ti_dt_clk omap54xx_clks[] = {
|
|||
DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"),
|
||||
DT_CLK("omap_wdt", "ick", "dummy_ck"),
|
||||
DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
|
||||
DT_CLK("omap_timer.1", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.2", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.3", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.4", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.9", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.10", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.11", "sys_ck", "sys_clkin"),
|
||||
DT_CLK("omap_timer.5", "sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("omap_timer.6", "sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("omap_timer.7", "sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("omap_timer.8", "sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48036000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("4803e000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48086000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("48088000.timer", "timer_sys_ck", "sys_clkin"),
|
||||
DT_CLK("40138000.timer", "timer_sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("4013a000.timer", "timer_sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("4013c000.timer", "timer_sys_ck", "dss_syc_gfclk_div"),
|
||||
DT_CLK("4013e000.timer", "timer_sys_ck", "dss_syc_gfclk_div"),
|
||||
{ .node_name = NULL },
|
||||
};
|
||||
|
||||
|
|
|
@ -289,17 +289,21 @@ static struct ti_dt_clk dra7xx_clks[] = {
|
|||
DT_CLK("usbhs_omap", "usbtll_fck", "dummy_ck"),
|
||||
DT_CLK("omap_wdt", "ick", "dummy_ck"),
|
||||
DT_CLK(NULL, "timer_32k_ck", "sys_32k_ck"),
|
||||
DT_CLK("4ae18000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48032000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48034000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48036000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("4803e000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48086000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("48088000.timer", "timer_sys_ck", "sys_clkin2"),
|
||||
DT_CLK("4ae18000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48032000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48034000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48036000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("4803e000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48086000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48088000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48820000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48822000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48824000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48826000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("48828000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("4882a000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("4882c000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK("4882e000.timer", "timer_sys_ck", "timer_sys_clk_div"),
|
||||
DT_CLK(NULL, "sys_clkin", "sys_clkin1"),
|
||||
{ .node_name = NULL },
|
||||
};
|
||||
|
|
|
@ -294,7 +294,7 @@ static int of_dra7_atl_clk_remove(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id of_dra7_atl_clk_match_tbl[] = {
|
||||
static const struct of_device_id of_dra7_atl_clk_match_tbl[] = {
|
||||
{ .compatible = "ti,dra7-atl", },
|
||||
{},
|
||||
};
|
||||
|
|
|
@ -103,7 +103,8 @@ int __init ti_clk_retry_init(struct device_node *node, struct clk_hw *hw,
|
|||
* @index: register index from the clock node
|
||||
*
|
||||
* Builds clock register address from device tree information. This
|
||||
* is a struct of type clk_omap_reg.
|
||||
* is a struct of type clk_omap_reg. Returns a pointer to the register
|
||||
* address, or a pointer error value in failure.
|
||||
*/
|
||||
void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
|
||||
{
|
||||
|
@ -121,14 +122,14 @@ void __iomem *ti_clk_get_reg_addr(struct device_node *node, int index)
|
|||
|
||||
if (i == CLK_MAX_MEMMAPS) {
|
||||
pr_err("clk-provider not found for %s!\n", node->name);
|
||||
return NULL;
|
||||
return ERR_PTR(-ENOENT);
|
||||
}
|
||||
|
||||
reg->index = i;
|
||||
|
||||
if (of_property_read_u32_index(node, "reg", index, &val)) {
|
||||
pr_err("%s must have reg[%d]!\n", node->name, index);
|
||||
return NULL;
|
||||
return ERR_PTR(-EINVAL);
|
||||
}
|
||||
|
||||
reg->offset = val;
|
||||
|
|
|
@ -52,7 +52,7 @@ static void __init of_ti_clockdomain_setup(struct device_node *node)
|
|||
}
|
||||
}
|
||||
|
||||
static struct of_device_id ti_clkdm_match_table[] __initdata = {
|
||||
static const struct of_device_id ti_clkdm_match_table[] __initconst = {
|
||||
{ .compatible = "ti,clockdomain" },
|
||||
{ }
|
||||
};
|
||||
|
|
|
@ -69,7 +69,7 @@ struct component_clk {
|
|||
struct list_head link;
|
||||
};
|
||||
|
||||
static const char * __initconst component_clk_types[] = {
|
||||
static const char * const component_clk_types[] __initconst = {
|
||||
"gate", "divider", "mux"
|
||||
};
|
||||
|
||||
|
|
|
@ -530,8 +530,8 @@ static int __init ti_clk_divider_populate(struct device_node *node,
|
|||
u32 val;
|
||||
|
||||
*reg = ti_clk_get_reg_addr(node, 0);
|
||||
if (!*reg)
|
||||
return -EINVAL;
|
||||
if (IS_ERR(*reg))
|
||||
return PTR_ERR(*reg);
|
||||
|
||||
if (!of_property_read_u32(node, "ti,bit-shift", &val))
|
||||
*shift = val;
|
||||
|
|
|
@ -390,18 +390,18 @@ static void __init of_ti_dpll_setup(struct device_node *node,
|
|||
#endif
|
||||
} else {
|
||||
dd->idlest_reg = ti_clk_get_reg_addr(node, 1);
|
||||
if (!dd->idlest_reg)
|
||||
if (IS_ERR(dd->idlest_reg))
|
||||
goto cleanup;
|
||||
|
||||
dd->mult_div1_reg = ti_clk_get_reg_addr(node, 2);
|
||||
}
|
||||
|
||||
if (!dd->control_reg || !dd->mult_div1_reg)
|
||||
if (IS_ERR(dd->control_reg) || IS_ERR(dd->mult_div1_reg))
|
||||
goto cleanup;
|
||||
|
||||
if (dd->autoidle_mask) {
|
||||
dd->autoidle_reg = ti_clk_get_reg_addr(node, 3);
|
||||
if (!dd->autoidle_reg)
|
||||
if (IS_ERR(dd->autoidle_reg))
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
|
|
@ -11,19 +11,27 @@
|
|||
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/math64.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/clk/ti.h>
|
||||
#include <asm/div64.h>
|
||||
|
||||
/* FAPLL Control Register PLL_CTRL */
|
||||
#define FAPLL_MAIN_MULT_N_SHIFT 16
|
||||
#define FAPLL_MAIN_DIV_P_SHIFT 8
|
||||
#define FAPLL_MAIN_LOCK BIT(7)
|
||||
#define FAPLL_MAIN_PLLEN BIT(3)
|
||||
#define FAPLL_MAIN_BP BIT(2)
|
||||
#define FAPLL_MAIN_LOC_CTL BIT(0)
|
||||
|
||||
#define FAPLL_MAIN_MAX_MULT_N 0xffff
|
||||
#define FAPLL_MAIN_MAX_DIV_P 0xff
|
||||
#define FAPLL_MAIN_CLEAR_MASK \
|
||||
((FAPLL_MAIN_MAX_MULT_N << FAPLL_MAIN_MULT_N_SHIFT) | \
|
||||
(FAPLL_MAIN_DIV_P_SHIFT << FAPLL_MAIN_DIV_P_SHIFT) | \
|
||||
FAPLL_MAIN_LOC_CTL)
|
||||
|
||||
/* FAPLL powerdown register PWD */
|
||||
#define FAPLL_PWD_OFFSET 4
|
||||
|
||||
|
@ -49,6 +57,10 @@
|
|||
/* Synthesizer frequency register */
|
||||
#define SYNTH_LDFREQ BIT(31)
|
||||
|
||||
#define SYNTH_PHASE_K 8
|
||||
#define SYNTH_MAX_INT_DIV 0xf
|
||||
#define SYNTH_MAX_DIV_M 0xff
|
||||
|
||||
struct fapll_data {
|
||||
struct clk_hw hw;
|
||||
void __iomem *base;
|
||||
|
@ -79,6 +91,48 @@ static bool ti_fapll_clock_is_bypass(struct fapll_data *fd)
|
|||
return !!(v & FAPLL_MAIN_BP);
|
||||
}
|
||||
|
||||
static void ti_fapll_set_bypass(struct fapll_data *fd)
|
||||
{
|
||||
u32 v = readl_relaxed(fd->base);
|
||||
|
||||
if (fd->bypass_bit_inverted)
|
||||
v &= ~FAPLL_MAIN_BP;
|
||||
else
|
||||
v |= FAPLL_MAIN_BP;
|
||||
writel_relaxed(v, fd->base);
|
||||
}
|
||||
|
||||
static void ti_fapll_clear_bypass(struct fapll_data *fd)
|
||||
{
|
||||
u32 v = readl_relaxed(fd->base);
|
||||
|
||||
if (fd->bypass_bit_inverted)
|
||||
v |= FAPLL_MAIN_BP;
|
||||
else
|
||||
v &= ~FAPLL_MAIN_BP;
|
||||
writel_relaxed(v, fd->base);
|
||||
}
|
||||
|
||||
static int ti_fapll_wait_lock(struct fapll_data *fd)
|
||||
{
|
||||
int retries = FAPLL_MAX_RETRIES;
|
||||
u32 v;
|
||||
|
||||
while ((v = readl_relaxed(fd->base))) {
|
||||
if (v & FAPLL_MAIN_LOCK)
|
||||
return 0;
|
||||
|
||||
if (retries-- <= 0)
|
||||
break;
|
||||
|
||||
udelay(1);
|
||||
}
|
||||
|
||||
pr_err("%s failed to lock\n", fd->name);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int ti_fapll_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct fapll_data *fd = to_fapll(hw);
|
||||
|
@ -86,6 +140,7 @@ static int ti_fapll_enable(struct clk_hw *hw)
|
|||
|
||||
v |= FAPLL_MAIN_PLLEN;
|
||||
writel_relaxed(v, fd->base);
|
||||
ti_fapll_wait_lock(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -141,12 +196,85 @@ static u8 ti_fapll_get_parent(struct clk_hw *hw)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int ti_fapll_set_div_mult(unsigned long rate,
|
||||
unsigned long parent_rate,
|
||||
u32 *pre_div_p, u32 *mult_n)
|
||||
{
|
||||
/*
|
||||
* So far no luck getting decent clock with PLL divider,
|
||||
* PLL does not seem to lock and the signal does not look
|
||||
* right. It seems the divider can only be used together
|
||||
* with the multiplier?
|
||||
*/
|
||||
if (rate < parent_rate) {
|
||||
pr_warn("FAPLL main divider rates unsupported\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*mult_n = rate / parent_rate;
|
||||
if (*mult_n > FAPLL_MAIN_MAX_MULT_N)
|
||||
return -EINVAL;
|
||||
*pre_div_p = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static long ti_fapll_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
u32 pre_div_p, mult_n;
|
||||
int error;
|
||||
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
|
||||
error = ti_fapll_set_div_mult(rate, *parent_rate,
|
||||
&pre_div_p, &mult_n);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
rate = *parent_rate / pre_div_p;
|
||||
rate *= mult_n;
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int ti_fapll_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct fapll_data *fd = to_fapll(hw);
|
||||
u32 pre_div_p, mult_n, v;
|
||||
int error;
|
||||
|
||||
if (!rate)
|
||||
return -EINVAL;
|
||||
|
||||
error = ti_fapll_set_div_mult(rate, parent_rate,
|
||||
&pre_div_p, &mult_n);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
ti_fapll_set_bypass(fd);
|
||||
v = readl_relaxed(fd->base);
|
||||
v &= ~FAPLL_MAIN_CLEAR_MASK;
|
||||
v |= pre_div_p << FAPLL_MAIN_DIV_P_SHIFT;
|
||||
v |= mult_n << FAPLL_MAIN_MULT_N_SHIFT;
|
||||
writel_relaxed(v, fd->base);
|
||||
if (ti_fapll_is_enabled(hw))
|
||||
ti_fapll_wait_lock(fd);
|
||||
ti_fapll_clear_bypass(fd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk_ops ti_fapll_ops = {
|
||||
.enable = ti_fapll_enable,
|
||||
.disable = ti_fapll_disable,
|
||||
.is_enabled = ti_fapll_is_enabled,
|
||||
.recalc_rate = ti_fapll_recalc_rate,
|
||||
.get_parent = ti_fapll_get_parent,
|
||||
.round_rate = ti_fapll_round_rate,
|
||||
.set_rate = ti_fapll_set_rate,
|
||||
};
|
||||
|
||||
static int ti_fapll_synth_enable(struct clk_hw *hw)
|
||||
|
@ -204,7 +332,7 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw,
|
|||
/*
|
||||
* Synth frequency integer and fractional divider.
|
||||
* Note that the phase output K is 8, so the result needs
|
||||
* to be multiplied by 8.
|
||||
* to be multiplied by SYNTH_PHASE_K.
|
||||
*/
|
||||
if (synth->freq) {
|
||||
u32 v, synth_int_div, synth_frac_div, synth_div_freq;
|
||||
|
@ -215,14 +343,138 @@ static unsigned long ti_fapll_synth_recalc_rate(struct clk_hw *hw,
|
|||
synth_div_freq = (synth_int_div * 10000000) + synth_frac_div;
|
||||
rate *= 10000000;
|
||||
do_div(rate, synth_div_freq);
|
||||
rate *= 8;
|
||||
rate *= SYNTH_PHASE_K;
|
||||
}
|
||||
|
||||
/* Synth ost-divider M */
|
||||
synth_div_m = readl_relaxed(synth->div) & 0xff;
|
||||
do_div(rate, synth_div_m);
|
||||
/* Synth post-divider M */
|
||||
synth_div_m = readl_relaxed(synth->div) & SYNTH_MAX_DIV_M;
|
||||
|
||||
return rate;
|
||||
return DIV_ROUND_UP_ULL(rate, synth_div_m);
|
||||
}
|
||||
|
||||
static unsigned long ti_fapll_synth_get_frac_rate(struct clk_hw *hw,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct fapll_synth *synth = to_synth(hw);
|
||||
unsigned long current_rate, frac_rate;
|
||||
u32 post_div_m;
|
||||
|
||||
current_rate = ti_fapll_synth_recalc_rate(hw, parent_rate);
|
||||
post_div_m = readl_relaxed(synth->div) & SYNTH_MAX_DIV_M;
|
||||
frac_rate = current_rate * post_div_m;
|
||||
|
||||
return frac_rate;
|
||||
}
|
||||
|
||||
static u32 ti_fapll_synth_set_frac_rate(struct fapll_synth *synth,
|
||||
unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
u32 post_div_m, synth_int_div = 0, synth_frac_div = 0, v;
|
||||
|
||||
post_div_m = DIV_ROUND_UP_ULL((u64)parent_rate * SYNTH_PHASE_K, rate);
|
||||
post_div_m = post_div_m / SYNTH_MAX_INT_DIV;
|
||||
if (post_div_m > SYNTH_MAX_DIV_M)
|
||||
return -EINVAL;
|
||||
if (!post_div_m)
|
||||
post_div_m = 1;
|
||||
|
||||
for (; post_div_m < SYNTH_MAX_DIV_M; post_div_m++) {
|
||||
synth_int_div = DIV_ROUND_UP_ULL((u64)parent_rate *
|
||||
SYNTH_PHASE_K *
|
||||
10000000,
|
||||
rate * post_div_m);
|
||||
synth_frac_div = synth_int_div % 10000000;
|
||||
synth_int_div /= 10000000;
|
||||
|
||||
if (synth_int_div <= SYNTH_MAX_INT_DIV)
|
||||
break;
|
||||
}
|
||||
|
||||
if (synth_int_div > SYNTH_MAX_INT_DIV)
|
||||
return -EINVAL;
|
||||
|
||||
v = readl_relaxed(synth->freq);
|
||||
v &= ~0x1fffffff;
|
||||
v |= (synth_int_div & SYNTH_MAX_INT_DIV) << 24;
|
||||
v |= (synth_frac_div & 0xffffff);
|
||||
v |= SYNTH_LDFREQ;
|
||||
writel_relaxed(v, synth->freq);
|
||||
|
||||
return post_div_m;
|
||||
}
|
||||
|
||||
static long ti_fapll_synth_round_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long *parent_rate)
|
||||
{
|
||||
struct fapll_synth *synth = to_synth(hw);
|
||||
struct fapll_data *fd = synth->fd;
|
||||
unsigned long r;
|
||||
|
||||
if (ti_fapll_clock_is_bypass(fd) || !synth->div || !rate)
|
||||
return -EINVAL;
|
||||
|
||||
/* Only post divider m available with no fractional divider? */
|
||||
if (!synth->freq) {
|
||||
unsigned long frac_rate;
|
||||
u32 synth_post_div_m;
|
||||
|
||||
frac_rate = ti_fapll_synth_get_frac_rate(hw, *parent_rate);
|
||||
synth_post_div_m = DIV_ROUND_UP(frac_rate, rate);
|
||||
r = DIV_ROUND_UP(frac_rate, synth_post_div_m);
|
||||
goto out;
|
||||
}
|
||||
|
||||
r = *parent_rate * SYNTH_PHASE_K;
|
||||
if (rate > r)
|
||||
goto out;
|
||||
|
||||
r = DIV_ROUND_UP_ULL(r, SYNTH_MAX_INT_DIV * SYNTH_MAX_DIV_M);
|
||||
if (rate < r)
|
||||
goto out;
|
||||
|
||||
r = rate;
|
||||
out:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int ti_fapll_synth_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long parent_rate)
|
||||
{
|
||||
struct fapll_synth *synth = to_synth(hw);
|
||||
struct fapll_data *fd = synth->fd;
|
||||
unsigned long frac_rate, post_rate = 0;
|
||||
u32 post_div_m = 0, v;
|
||||
|
||||
if (ti_fapll_clock_is_bypass(fd) || !synth->div || !rate)
|
||||
return -EINVAL;
|
||||
|
||||
/* Produce the rate with just post divider M? */
|
||||
frac_rate = ti_fapll_synth_get_frac_rate(hw, parent_rate);
|
||||
if (frac_rate < rate) {
|
||||
if (!synth->freq)
|
||||
return -EINVAL;
|
||||
} else {
|
||||
post_div_m = DIV_ROUND_UP(frac_rate, rate);
|
||||
if (post_div_m && (post_div_m <= SYNTH_MAX_DIV_M))
|
||||
post_rate = DIV_ROUND_UP(frac_rate, post_div_m);
|
||||
if (!synth->freq && !post_rate)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Need to recalculate the fractional divider? */
|
||||
if ((post_rate != rate) && synth->freq)
|
||||
post_div_m = ti_fapll_synth_set_frac_rate(synth,
|
||||
rate,
|
||||
parent_rate);
|
||||
|
||||
v = readl_relaxed(synth->div);
|
||||
v &= ~SYNTH_MAX_DIV_M;
|
||||
v |= post_div_m;
|
||||
v |= SYNTH_LDMDIV1;
|
||||
writel_relaxed(v, synth->div);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct clk_ops ti_fapll_synt_ops = {
|
||||
|
@ -230,6 +482,8 @@ static struct clk_ops ti_fapll_synt_ops = {
|
|||
.disable = ti_fapll_synth_disable,
|
||||
.is_enabled = ti_fapll_synth_is_enabled,
|
||||
.recalc_rate = ti_fapll_synth_recalc_rate,
|
||||
.round_rate = ti_fapll_synth_round_rate,
|
||||
.set_rate = ti_fapll_synth_set_rate,
|
||||
};
|
||||
|
||||
static struct clk * __init ti_fapll_synth_setup(struct fapll_data *fd,
|
||||
|
|
|
@ -225,7 +225,7 @@ static void __init _of_ti_gate_clk_setup(struct device_node *node,
|
|||
|
||||
if (ops != &omap_gate_clkdm_clk_ops) {
|
||||
reg = ti_clk_get_reg_addr(node, 0);
|
||||
if (!reg)
|
||||
if (IS_ERR(reg))
|
||||
return;
|
||||
|
||||
if (!of_property_read_u32(node, "ti,bit-shift", &val))
|
||||
|
@ -264,7 +264,7 @@ _of_ti_composite_gate_clk_setup(struct device_node *node,
|
|||
return;
|
||||
|
||||
gate->enable_reg = ti_clk_get_reg_addr(node, 0);
|
||||
if (!gate->enable_reg)
|
||||
if (IS_ERR(gate->enable_reg))
|
||||
goto cleanup;
|
||||
|
||||
of_property_read_u32(node, "ti,bit-shift", &val);
|
||||
|
|
|
@ -111,7 +111,7 @@ static void __init _of_ti_interface_clk_setup(struct device_node *node,
|
|||
u32 val;
|
||||
|
||||
reg = ti_clk_get_reg_addr(node, 0);
|
||||
if (!reg)
|
||||
if (IS_ERR(reg))
|
||||
return;
|
||||
|
||||
if (!of_property_read_u32(node, "ti,bit-shift", &val))
|
||||
|
|
|
@ -210,7 +210,7 @@ static void of_mux_clk_setup(struct device_node *node)
|
|||
|
||||
reg = ti_clk_get_reg_addr(node, 0);
|
||||
|
||||
if (!reg)
|
||||
if (IS_ERR(reg))
|
||||
goto cleanup;
|
||||
|
||||
of_property_read_u32(node, "ti,bit-shift", &shift);
|
||||
|
@ -283,7 +283,7 @@ static void __init of_ti_composite_mux_clk_setup(struct device_node *node)
|
|||
|
||||
mux->reg = ti_clk_get_reg_addr(node, 0);
|
||||
|
||||
if (!mux->reg)
|
||||
if (IS_ERR(mux->reg))
|
||||
goto cleanup;
|
||||
|
||||
if (!of_property_read_u32(node, "ti,bit-shift", &val))
|
||||
|
|
|
@ -69,7 +69,7 @@ static void __init cm_osc_setup(struct device_node *np,
|
|||
struct device_node *parent;
|
||||
|
||||
parent = of_get_parent(np);
|
||||
if (!np) {
|
||||
if (!parent) {
|
||||
pr_err("no parent on core module clock\n");
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -110,7 +110,7 @@ static int vexpress_osc_probe(struct platform_device *pdev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id vexpress_osc_of_match[] = {
|
||||
static const struct of_device_id vexpress_osc_of_match[] = {
|
||||
{ .compatible = "arm,vexpress-osc", },
|
||||
{}
|
||||
};
|
||||
|
|
|
@ -85,22 +85,22 @@ static DEFINE_SPINLOCK(canmioclk_lock);
|
|||
static DEFINE_SPINLOCK(dbgclk_lock);
|
||||
static DEFINE_SPINLOCK(aperclk_lock);
|
||||
|
||||
static const char *armpll_parents[] __initconst = {"armpll_int", "ps_clk"};
|
||||
static const char *ddrpll_parents[] __initconst = {"ddrpll_int", "ps_clk"};
|
||||
static const char *iopll_parents[] __initconst = {"iopll_int", "ps_clk"};
|
||||
static const char *gem0_mux_parents[] __initconst = {"gem0_div1", "dummy_name"};
|
||||
static const char *gem1_mux_parents[] __initconst = {"gem1_div1", "dummy_name"};
|
||||
static const char *can0_mio_mux2_parents[] __initconst = {"can0_gate",
|
||||
static const char *armpll_parents[] __initdata = {"armpll_int", "ps_clk"};
|
||||
static const char *ddrpll_parents[] __initdata = {"ddrpll_int", "ps_clk"};
|
||||
static const char *iopll_parents[] __initdata = {"iopll_int", "ps_clk"};
|
||||
static const char *gem0_mux_parents[] __initdata = {"gem0_div1", "dummy_name"};
|
||||
static const char *gem1_mux_parents[] __initdata = {"gem1_div1", "dummy_name"};
|
||||
static const char *can0_mio_mux2_parents[] __initdata = {"can0_gate",
|
||||
"can0_mio_mux"};
|
||||
static const char *can1_mio_mux2_parents[] __initconst = {"can1_gate",
|
||||
static const char *can1_mio_mux2_parents[] __initdata = {"can1_gate",
|
||||
"can1_mio_mux"};
|
||||
static const char *dbg_emio_mux_parents[] __initconst = {"dbg_div",
|
||||
static const char *dbg_emio_mux_parents[] __initdata = {"dbg_div",
|
||||
"dummy_name"};
|
||||
|
||||
static const char *dbgtrc_emio_input_names[] __initconst = {"trace_emio_clk"};
|
||||
static const char *gem0_emio_input_names[] __initconst = {"gem0_emio_clk"};
|
||||
static const char *gem1_emio_input_names[] __initconst = {"gem1_emio_clk"};
|
||||
static const char *swdt_ext_clk_input_names[] __initconst = {"swdt_ext_clk"};
|
||||
static const char *dbgtrc_emio_input_names[] __initdata = {"trace_emio_clk"};
|
||||
static const char *gem0_emio_input_names[] __initdata = {"gem0_emio_clk"};
|
||||
static const char *gem1_emio_input_names[] __initdata = {"gem1_emio_clk"};
|
||||
static const char *swdt_ext_clk_input_names[] __initdata = {"swdt_ext_clk"};
|
||||
|
||||
static void __init zynq_clk_register_fclk(enum zynq_clk fclk,
|
||||
const char *clk_name, void __iomem *fclk_ctrl_reg,
|
||||
|
|
|
@ -282,4 +282,65 @@
|
|||
*/
|
||||
#define NR_CLKS_DMC 21
|
||||
|
||||
/*
|
||||
* CMU ISP
|
||||
*/
|
||||
|
||||
/* Dividers */
|
||||
|
||||
#define CLK_DIV_ISP1 1
|
||||
#define CLK_DIV_ISP0 2
|
||||
#define CLK_DIV_MCUISP1 3
|
||||
#define CLK_DIV_MCUISP0 4
|
||||
#define CLK_DIV_MPWM 5
|
||||
|
||||
/* Gates */
|
||||
|
||||
#define CLK_UART_ISP 8
|
||||
#define CLK_WDT_ISP 9
|
||||
#define CLK_PWM_ISP 10
|
||||
#define CLK_I2C1_ISP 11
|
||||
#define CLK_I2C0_ISP 12
|
||||
#define CLK_MPWM_ISP 13
|
||||
#define CLK_MCUCTL_ISP 14
|
||||
#define CLK_PPMUISPX 15
|
||||
#define CLK_PPMUISPMX 16
|
||||
#define CLK_QE_LITE1 17
|
||||
#define CLK_QE_LITE0 18
|
||||
#define CLK_QE_FD 19
|
||||
#define CLK_QE_DRC 20
|
||||
#define CLK_QE_ISP 21
|
||||
#define CLK_CSIS1 22
|
||||
#define CLK_SMMU_LITE1 23
|
||||
#define CLK_SMMU_LITE0 24
|
||||
#define CLK_SMMU_FD 25
|
||||
#define CLK_SMMU_DRC 26
|
||||
#define CLK_SMMU_ISP 27
|
||||
#define CLK_GICISP 28
|
||||
#define CLK_CSIS0 29
|
||||
#define CLK_MCUISP 30
|
||||
#define CLK_LITE1 31
|
||||
#define CLK_LITE0 32
|
||||
#define CLK_FD 33
|
||||
#define CLK_DRC 34
|
||||
#define CLK_ISP 35
|
||||
#define CLK_QE_ISPCX 36
|
||||
#define CLK_QE_SCALERP 37
|
||||
#define CLK_QE_SCALERC 38
|
||||
#define CLK_SMMU_SCALERP 39
|
||||
#define CLK_SMMU_SCALERC 40
|
||||
#define CLK_SCALERP 41
|
||||
#define CLK_SCALERC 42
|
||||
#define CLK_SPI1_ISP 43
|
||||
#define CLK_SPI0_ISP 44
|
||||
#define CLK_SMMU_ISPCX 45
|
||||
#define CLK_ASYNCAXIM 46
|
||||
#define CLK_SCLK_MPWM_ISP 47
|
||||
|
||||
/*
|
||||
* Total number of clocks of CMU_ISP.
|
||||
* NOTE: Must be equal to last clock ID increased by one.
|
||||
*/
|
||||
#define NR_CLKS_ISP 48
|
||||
|
||||
#endif /* _DT_BINDINGS_CLOCK_SAMSUNG_EXYNOS3250_CLOCK_H */
|
||||
|
|
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue