1
0
Fork 0

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
  ...
hifive-unleashed-5.1
Linus Torvalds 2015-04-21 09:24:09 -07:00
commit e98bf5cedf
107 changed files with 13215 additions and 837 deletions

View File

@ -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.

View File

@ -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";
};

View File

@ -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";
};

View File

@ -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)

View File

@ -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

View File

@ -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 */
};

View File

@ -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"

View File

@ -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.

View File

@ -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/

View File

@ -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---

View File

@ -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/

View File

@ -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;

View File

@ -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,

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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");

View File

@ -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,

View File

@ -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,

View File

@ -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)

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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};

View File

@ -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

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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,

View File

@ -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; \

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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, &reg);
ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, &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, &reg);
ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, &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, &reg);
ret = regmap_read(rcg->clkr.regmap, rcg->bank_reg, &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, &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,

View File

@ -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;
};

View File

@ -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;

View File

@ -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)
{

View File

@ -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);

View File

@ -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 = {

View File

@ -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[] = {

View File

@ -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

View File

@ -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[] = {

View File

@ -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 = {

View File

@ -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,
},
},
};

View File

@ -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[] = {

View File

@ -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[] = {

View File

@ -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[] = {

View File

@ -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[] = {

View File

@ -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",

View File

@ -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",

View File

@ -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;

View File

@ -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)

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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

View File

@ -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",

View File

@ -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

View File

@ -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 },
{}

View File

@ -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,

View File

@ -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 \

View File

@ -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",
};

View File

@ -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);

View File

@ -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)
{

View File

@ -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;

View File

@ -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 \
}

View File

@ -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);

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
}

View File

@ -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),

View File

@ -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"),

View File

@ -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"),

View File

@ -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 },
};

View File

@ -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 },
};

View File

@ -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", },
{},
};

View File

@ -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;

View File

@ -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" },
{ }
};

View File

@ -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"
};

View File

@ -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;

View File

@ -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;
}

View File

@ -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,

View File

@ -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);

View File

@ -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))

View File

@ -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))

View File

@ -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;
}

View File

@ -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", },
{}
};

View File

@ -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,

View File

@ -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