We have one small patch to the clk core this time around. It fixes a corner

case with the CLK_OPS_PARENT_ENABLE flag combined with clk_core_is_enabled()
 where it hangs the system. We'll simply assume the clk is disabled if the
 parent is disabled and the flag is set. Trying to turn on the parent to check
 the enable state of the clk runs into system hangs at boot. We let this bake in
 -next for a couple weeks to make sure there aren't any more issues because the
 last attempt to fix this ran into hangs and had to be reverted.
 
 Note: There were some more patches to the core framework around sync_state and
 disabling unused clks, but I asked for that to be reverted from the qcom PR
 because it isn't ready and we're still discussing the best solution on the
 list.
 
 Outside of the core clk framework, we have the usual collection of clk driver
 updates and support for new SoCs (which seems to never stop). The dirstat is
 dominated by Qualcomm because they added support for quite a few SoCs this time
 around and also migrated quite a few of their drivers to clk_parent_data. The
 other big diff is in the Mediatek clk drivers that saw a significant rework
 this cycle to similarly modernize the code, and we'll see that work continue in
 the next cycle as well. Nothing really jumps out as scary here, except that the
 significant churn in parent data descriptions can have typos that go unnoticed.
 More details below.
 
 Core:
  - Honor CLK_OPS_PARENT_ENABLE in clk_core_is_enabled()
 
 New Drivers:
  - Add a new clk-gpr-mux clock type and use it on i.MX6Q to add ENET ref
    clocks
  - Support for Mediatek MT7891 SoC clks
  - Support for many Qualcomm clk controllers:
    - QDU1000/QRU1000 global clock controller
    - SA8775P global clock controller
    - SM8550 TCSR and display clock controller
    - SM6350 clock controller
    - MSM8996 CBF and APCS clock controllers
 
 Updates:
  - Various cleanups and improvements to Mediatek clk drivers to reduce
    code size and modernize the drivers
  - Support for Versa 5P49V60 clks
  - Disable R-Car H3 ES1.*, as it was only available to an internal
    development group and needed a lot of quirks and workarounds
  - Add PWM, Compare-Match Timer (TIM), USB, SDHI, and eMMC clocks and
    resets on Renesas RZ/V2M
  - Add display clocks on Renesas R-Car V4H
  - Add Camera Receiving Unit (CRU) clocks and resets on Renesas RZ/G2L
  - Free the imx_uart_clocks even if imx_register_uart_clocks returns early
  - Get the stdout clocks count from device tree on i.MX
  - Drop the clock count argument from imx_register_uart_clocks()
  - Keep the uart clocks on i.MX93 for when earlycon is used
  - Fix SPDX comment in i.MX6SLL clocks bindings header
  - Drop some unnecessary spaces from i.MX8ULP clocks bindings header
  - Add imx_obtain_fixed_of_clock() for allowing to add a clock that is
    not configured via devicetree
  - Fix the ENET1 gate configuration for i.MX6UL according to the
    reference manual
  - Add ENET refclock mux support for i.MX6UL
  - Add support for USB host/device configuration on Renesas RZ/N1
  - Add PLL2 programming support, and CAN-FD clocks on Renesas R-Car V4H
  - Add D1 CAN bus gates and resets for Allwinner
  - Mark D1 CPUX clock as critical on Allwinner
  - Reuse D1 driver for Allwinner R528/T113
  - Cleanup sunxi-ng Kconfig
  - Fix sunxi-ng kernel-doc issues
  - Model Allwinner H3/H5 DRAM clock as fixed clock
  - Use .determine_rate() instead of .round_rate() for the dualdiv, mpll,
    sclk-div and cpu-dyn-div amlogic clock drivers
  - DDR clocks were marked as critical in the proper clock driver for each
    AT91 SoC such that drivers/memory/atmel-sdramc.c to be deleted
    in the next releases as it only does clock enablement
  - Patch to avoid compiling dt-compat.o for all AT91 SoCs as only some of
    them may use it
  - Support synchronous power_off requests in the qcom GDSC driver for proper
    GPU power collapse
  - Drop test clocks from various Qualcomm clk drivers
  - Update parent references to use clk_parent_data/clk_hw in various Qualcomm clk drivers
  - Fixes for the Qualcomm MSM8996 CPU clock controller
  - Transition Qualcomm MSM8974 GCC off the externally defined sleep_clk
  - Add GDSCs in the global clock controller for Qualcomm QCS404
  - The SDCC core clocks on Qualcomm SM6115 are moved to floor_ops
  - Programming of clk_dis_wait for GPU CX GDSC on Qualcomm SC7180 and SDM845 are
    moved to use the recently introduced properties in the GDSC struct
  - Qualcomm's RPMh clock driver gains SM8550 and SA8775P clocks, and the IPA clock
    is added on a variety of platforms
  - De-duplicate identical clks in Qualcomm SMD RPM clk driver
  - Add a few missing clocks across msm8998, msm8992, msm8916, qcs404 to
    Qualcomm SDM RPM clk driver
  - Various Qualcomm clk drivers use devm_pm_runtime_enable() to simplify
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmP5L68RHHNib3lkQGtl
 cm5lbC5vcmcACgkQrQKIl8bklSXLxRAAx5C2PBxGnQS5Dqy7yGFBKhoyM6MnD131
 4wsWunTzw/fx3MWTRUBu1FYq7ZN38dmeUNeKVNO7QkfIzXe/Htxa5DJp8oJjeFkA
 WBlJr/S9pnCKJ1+jGgnEJ3AL8rtssc2nasS8Gj66eu3Zs3dA1MlUz1M0wqiGeD/Y
 2crg1nowHurxhsmdUM+6sBRZsCoUz1DxAynqOK25Ip08ygBGYRdkk3aCoyx1bICF
 02RwSTQP9pGykgkO7BMkr1pA000mlcawXflzfbY0bA57GKvITBaXh3PhVWwsAnqk
 utagT3G2/mQNBF+DVX4Xr5rRqYttDeATiS2D0B31x68Ovjw6kaA28QoY19oIjc1p
 D7CabcPnrdK6JFimJL/uEnjIpVnMW2kbTAkTdgGFNKqYUC1O+Mm5ZscKo8RUaiQ7
 8XAgJXnGxG7RlZDIMCj69xiZBR0I0wgyx6E7sqMK5j4/v9ezhUMemj4u/sNe3R1n
 ih43L2vXjftAhl7jlGQb6eFQjPU/n8kf1rte5miJxX2vFBgWqiCfKHnVSe8KSNU+
 gqhar55G9ACnYBjqApmySd/7IFBzmJSyWujXg+fwIu0ZI5ir+ZPr+rQ7RkAUqMij
 QCPvJa6XlRIyl6j54E5GaSFO3ZDc3wAZEs3I2N4yhYTDUGv342G3YdwNU+b0ioHB
 bDW5Gec9u2s=
 =Fle/
 -----END PGP SIGNATURE-----

Merge tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux

Pull clk updates from Stephen Boyd:
 "We have one small patch to the clk core this time around. It fixes a
  corner case with the CLK_OPS_PARENT_ENABLE flag combined with
  clk_core_is_enabled() where it hangs the system. We'll simply assume
  the clk is disabled if the parent is disabled and the flag is set.
  Trying to turn on the parent to check the enable state of the clk runs
  into system hangs at boot. We let this bake in -next for a couple
  weeks to make sure there aren't any more issues because the last
  attempt to fix this ran into hangs and had to be reverted.

  Note: There were some more patches to the core framework around
  sync_state and disabling unused clks, but I asked for that to be
  reverted from the qcom PR because it isn't ready and we're still
  discussing the best solution on the list.

  Outside of the core clk framework, we have the usual collection of clk
  driver updates and support for new SoCs (which seems to never stop).
  The dirstat is dominated by Qualcomm because they added support for
  quite a few SoCs this time around and also migrated quite a few of
  their drivers to clk_parent_data. The other big diff is in the
  Mediatek clk drivers that saw a significant rework this cycle to
  similarly modernize the code, and we'll see that work continue in the
  next cycle as well. Nothing really jumps out as scary here, except
  that the significant churn in parent data descriptions can have typos
  that go unnoticed. More details below.

  Core:
   - Honor CLK_OPS_PARENT_ENABLE in clk_core_is_enabled()

  New Drivers:
   - Add a new clk-gpr-mux clock type and use it on i.MX6Q to add ENET
     ref clocks
   - Support for Mediatek MT7891 SoC clks
   - Support for many Qualcomm clk controllers:
      - QDU1000/QRU1000 global clock controller
      - SA8775P global clock controller
      - SM8550 TCSR and display clock controller
      - SM6350 clock controller
      - MSM8996 CBF and APCS clock controllers

  Updates:
   - Various cleanups and improvements to Mediatek clk drivers to reduce
     code size and modernize the drivers
   - Support for Versa 5P49V60 clks
   - Disable R-Car H3 ES1.*, as it was only available to an internal
     development group and needed a lot of quirks and workarounds
   - Add PWM, Compare-Match Timer (TIM), USB, SDHI, and eMMC clocks and
     resets on Renesas RZ/V2M
   - Add display clocks on Renesas R-Car V4H
   - Add Camera Receiving Unit (CRU) clocks and resets on Renesas RZ/G2L
   - Free the imx_uart_clocks even if imx_register_uart_clocks returns
     early
   - Get the stdout clocks count from device tree on i.MX
   - Drop the clock count argument from imx_register_uart_clocks()
   - Keep the uart clocks on i.MX93 for when earlycon is used
   - Fix SPDX comment in i.MX6SLL clocks bindings header
   - Drop some unnecessary spaces from i.MX8ULP clocks bindings header
   - Add imx_obtain_fixed_of_clock() for allowing to add a clock that is
     not configured via devicetree
   - Fix the ENET1 gate configuration for i.MX6UL according to the
     reference manual
   - Add ENET refclock mux support for i.MX6UL
   - Add support for USB host/device configuration on Renesas RZ/N1
   - Add PLL2 programming support, and CAN-FD clocks on Renesas R-Car
     V4H
   - Add D1 CAN bus gates and resets for Allwinner
   - Mark D1 CPUX clock as critical on Allwinner
   - Reuse D1 driver for Allwinner R528/T113
   - Cleanup sunxi-ng Kconfig
   - Fix sunxi-ng kernel-doc issues
   - Model Allwinner H3/H5 DRAM clock as fixed clock
   - Use .determine_rate() instead of .round_rate() for the dualdiv,
     mpll, sclk-div and cpu-dyn-div amlogic clock drivers
   - DDR clocks were marked as critical in the proper clock driver for
     each AT91 SoC such that drivers/memory/atmel-sdramc.c to be deleted
     in the next releases as it only does clock enablement
   - Patch to avoid compiling dt-compat.o for all AT91 SoCs as only some
     of them may use it
   - Support synchronous power_off requests in the qcom GDSC driver for
     proper GPU power collapse
   - Drop test clocks from various Qualcomm clk drivers
   - Update parent references to use clk_parent_data/clk_hw in various
     Qualcomm clk drivers
   - Fixes for the Qualcomm MSM8996 CPU clock controller
   - Transition Qualcomm MSM8974 GCC off the externally defined
     sleep_clk
   - Add GDSCs in the global clock controller for Qualcomm QCS404
   - The SDCC core clocks on Qualcomm SM6115 are moved to floor_ops
   - Programming of clk_dis_wait for GPU CX GDSC on Qualcomm SC7180 and
     SDM845 are moved to use the recently introduced properties in the
     GDSC struct
   - Qualcomm's RPMh clock driver gains SM8550 and SA8775P clocks, and
     the IPA clock is added on a variety of platforms
   - De-duplicate identical clks in Qualcomm SMD RPM clk driver
   - Add a few missing clocks across msm8998, msm8992, msm8916, qcs404
     to Qualcomm SDM RPM clk driver
   - Various Qualcomm clk drivers use devm_pm_runtime_enable() to
     simplify"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (228 commits)
  clk: qcom: apcs-msm8986: Include bitfield.h for FIELD_PREP
  clk: qcom: Revert sync_state based clk_disable_unused
  clk: imx: pll14xx: fix recalc_rate for negative kdiv
  clk: rs9: Drop unused pin_xin field
  MAINTAINERS: clk: imx: Add Peng Fan as reviewer
  clk: sprd: Add dependency for SPRD_UMS512_CLK
  clk: ralink: fix 'mt7621_gate_is_enabled()' function
  clk: mediatek: clk-mtk: Remove unneeded semicolon
  dt-bindings: clock: remove stih416 bindings
  dt-bindings: clock: add loongson-2 clock
  dt-bindings: clock: add loongson-2 clock include file
  clk: imx: fix compile testing imxrt1050
  clk: Honor CLK_OPS_PARENT_ENABLE in clk_core_is_enabled()
  clk: imx: set imx_clk_gpr_mux_ops storage-class-specifier to static
  clk: renesas: rcar-gen3: Disable R-Car H3 ES1.*
  dt-bindings: clock: Merge qcom,gpucc-sm8350 into qcom,gpucc.yaml
  clk: qcom: gpucc-sdm845: fix clk_dis_wait being programmed for CX GDSC
  clk: qcom: gpucc-sc7180: fix clk_dis_wait being programmed for CX GDSC
  dt-bindings: clock: qcom,sa8775p-gcc: add the power-domains property
  clk: qcom: cpu-8996: add missing cputype include
  ...
This commit is contained in:
Linus Torvalds 2023-02-25 15:16:23 -08:00
commit 1ec35eadc3
249 changed files with 19951 additions and 6330 deletions

View File

@ -10,6 +10,7 @@ Required Properties:
- "mediatek,mt7622-ethsys", "syscon"
- "mediatek,mt7623-ethsys", "mediatek,mt2701-ethsys", "syscon"
- "mediatek,mt7629-ethsys", "syscon"
- "mediatek,mt7981-ethsys", "syscon"
- "mediatek,mt7986-ethsys", "syscon"
- #clock-cells: Must be 1
- #reset-cells: Must be 1

View File

@ -28,6 +28,7 @@ properties:
- mediatek,mt6797-infracfg
- mediatek,mt7622-infracfg
- mediatek,mt7629-infracfg
- mediatek,mt7981-infracfg
- mediatek,mt7986-infracfg
- mediatek,mt8135-infracfg
- mediatek,mt8167-infracfg

View File

@ -28,11 +28,9 @@ properties:
- mediatek,mt8195-imp_iic_wrap_s
- mediatek,mt8195-imp_iic_wrap_w
- mediatek,mt8195-mfgcfg
- mediatek,mt8195-vppsys0
- mediatek,mt8195-wpesys
- mediatek,mt8195-wpesys_vpp0
- mediatek,mt8195-wpesys_vpp1
- mediatek,mt8195-vppsys1
- mediatek,mt8195-imgsys
- mediatek,mt8195-imgsys1_dip_top
- mediatek,mt8195-imgsys1_dip_nr
@ -92,13 +90,6 @@ examples:
#clock-cells = <1>;
};
- |
vppsys0: clock-controller@14000000 {
compatible = "mediatek,mt8195-vppsys0";
reg = <0x14000000 0x1000>;
#clock-cells = <1>;
};
- |
wpesys: clock-controller@14e00000 {
compatible = "mediatek,mt8195-wpesys";
@ -120,13 +111,6 @@ examples:
#clock-cells = <1>;
};
- |
vppsys1: clock-controller@14f00000 {
compatible = "mediatek,mt8195-vppsys1";
reg = <0x14f00000 0x1000>;
#clock-cells = <1>;
};
- |
imgsys: clock-controller@15000000 {
compatible = "mediatek,mt8195-imgsys";

View File

@ -8,6 +8,8 @@ Required Properties:
- compatible: Should be:
- "mediatek,mt7622-sgmiisys", "syscon"
- "mediatek,mt7629-sgmiisys", "syscon"
- "mediatek,mt7981-sgmiisys_0", "syscon"
- "mediatek,mt7981-sgmiisys_1", "syscon"
- "mediatek,mt7986-sgmiisys_0", "syscon"
- "mediatek,mt7986-sgmiisys_1", "syscon"
- #clock-cells: Must be 1

View File

@ -54,6 +54,7 @@ properties:
- idt,5p49v5925
- idt,5p49v5933
- idt,5p49v5935
- idt,5p49v60
- idt,5p49v6901
- idt,5p49v6965
- idt,5p49v6975

View File

@ -108,7 +108,7 @@ examples:
};
- |
clock-controller@30390000 {
clock-controller@30380000 {
compatible = "fsl,imx8mq-ccm";
reg = <0x30380000 0x10000>;
#clock-cells = <1>;

View File

@ -0,0 +1,63 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/loongson,ls2k-clk.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Loongson-2 SoC Clock Control Module
maintainers:
- Yinbo Zhu <zhuyinbo@loongson.cn>
description: |
Loongson-2 SoC clock control module is an integrated clock controller, which
generates and supplies to all modules.
properties:
compatible:
enum:
- loongson,ls2k-clk
reg:
maxItems: 1
clocks:
items:
- description: 100m ref
clock-names:
items:
- const: ref_100m
'#clock-cells':
const: 1
description:
The clock consumer should specify the desired clock by having the clock
ID in its "clocks" phandle cell. See include/dt-bindings/clock/loongson,ls2k-clk.h
for the full list of Loongson-2 SoC clock IDs.
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
additionalProperties: false
examples:
- |
ref_100m: clock-ref-100m {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <100000000>;
clock-output-names = "ref_100m";
};
clk: clock-controller@1fe00480 {
compatible = "loongson,ls2k-clk";
reg = <0x1fe00480 0x58>;
#clock-cells = <1>;
clocks = <&ref_100m>;
clock-names = "ref_100m";
};

View File

@ -20,6 +20,7 @@ properties:
- enum:
- mediatek,mt6797-apmixedsys
- mediatek,mt7622-apmixedsys
- mediatek,mt7981-apmixedsys
- mediatek,mt7986-apmixedsys
- mediatek,mt8135-apmixedsys
- mediatek,mt8173-apmixedsys

View File

@ -35,6 +35,7 @@ properties:
- mediatek,mt6779-topckgen
- mediatek,mt6795-topckgen
- mediatek,mt7629-topckgen
- mediatek,mt7981-topckgen
- mediatek,mt7986-topckgen
- mediatek,mt8167-topckgen
- mediatek,mt8183-topckgen

View File

@ -21,12 +21,16 @@ properties:
clocks:
items:
- description: AHB
- description: Board XO source
- description: Board active XO source
- description: Sleep clock source
clock-names:
items:
- const: iface
- const: bi_tcxo
- const: bi_tcxo_ao
- const: sleep_clk
'#clock-cells':
@ -38,9 +42,18 @@ properties:
'#power-domain-cells':
const: 1
power-domains:
items:
- description: MMCX power domain
reg:
maxItems: 1
required-opps:
maxItems: 1
description:
OPP node describing required MMCX performance point.
required:
- compatible
- reg
@ -54,13 +67,16 @@ additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-sm8250.h>
#include <dt-bindings/clock/qcom,rpmh.h>
clock-controller@ad00000 {
compatible = "qcom,sm8250-camcc";
reg = <0x0ad00000 0x10000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
clocks = <&gcc GCC_CAMERA_AHB_CLK>,
<&rpmhcc RPMH_CXO_CLK>,
<&rpmhcc RPMH_CXO_CLK_A>,
<&sleep_clk>;
clock-names = "bi_tcxo", "sleep_clk";
clock-names = "iface", "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -25,6 +25,30 @@ properties:
compatible:
const: qcom,gcc-apq8084
clocks:
items:
- description: XO source
- description: Sleep clock source
- description: UFS RX symbol 0 clock
- description: UFS RX symbol 1 clock
- description: UFS TX symbol 0 clock
- description: UFS TX symbol 1 clock
- description: SATA ASIC0 clock
- description: SATA RX clock
- description: PCIe PIPE clock
clock-names:
items:
- const: xo
- const: sleep_clk
- const: ufs_rx_symbol_0_clk_src
- const: ufs_rx_symbol_1_clk_src
- const: ufs_tx_symbol_0_clk_src
- const: ufs_tx_symbol_1_clk_src
- const: sata_asic0_clk
- const: sata_rx_clk
- const: pcie_pipe
required:
- compatible
@ -32,11 +56,31 @@ unevaluatedProperties: false
examples:
- |
/* UFS PHY on APQ8084 is not supported (yet), so these bindings just serve an example */
clock-controller@fc400000 {
compatible = "qcom,gcc-apq8084";
reg = <0xfc400000 0x4000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
clocks = <&xo_board>,
<&sleep_clk>,
<&ufsphy 0>,
<&ufsphy 1>,
<&ufsphy 2>,
<&ufsphy 3>,
<&sata 0>,
<&sata 1>,
<&pcie_phy>;
clock-names = "xo",
"sleep_clk",
"ufs_rx_symbol_0_clk_src",
"ufs_rx_symbol_1_clk_src",
"ufs_tx_symbol_0_clk_src",
"ufs_tx_symbol_1_clk_src",
"sata_asic0_clk",
"sata_rx_clk",
"pcie_pipe";
};
...

View File

@ -25,7 +25,6 @@ properties:
- description: Board XO source
- description: Sleep clock source
- description: Audio reference clock (Optional clock)
- description: PLL test clock source (Optional clock)
minItems: 2
clock-names:
@ -33,7 +32,6 @@ properties:
- const: xo
- const: sleep_clk
- const: aud_ref_clk # Optional clock
- const: core_bi_pll_test_se # Optional clock
minItems: 2
required:
@ -57,11 +55,9 @@ examples:
reg = <0x00100000 0xb0000>;
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
<&sleep>,
<0>,
<0>;
clock-names = "xo",
"sleep_clk",
"aud_ref_clk",
"core_bi_pll_test_se";
"aud_ref_clk";
};
...

View File

@ -20,26 +20,31 @@ properties:
compatible:
const: qcom,gcc-qcs404
'#clock-cells':
const: 1
clocks:
items:
- description: XO source
- description: Sleep clock source
- description: PCIe 0 PIPE clock (optional)
- description: DSI phy instance 0 dsi clock
- description: DSI phy instance 0 byte clock
- description: HDMI phy PLL clock
'#reset-cells':
const: 1
reg:
maxItems: 1
protected-clocks:
description:
Protected clock specifier list as per common clock binding.
clock-names:
items:
- const: cxo
- const: sleep_clk
- const: pcie_0_pipe_clk_src
- const: dsi0pll
- const: dsi0pllbyte
- const: hdmi_pll
required:
- compatible
- reg
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
allOf:
- $ref: qcom,gcc.yaml#
unevaluatedProperties: false
examples:
- |
@ -48,5 +53,6 @@ examples:
reg = <0x01800000 0x80000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...

View File

@ -55,6 +55,10 @@ properties:
- description: First EMAC controller reference clock
- description: Second EMAC controller reference clock
power-domains:
items:
- description: CX domain
protected-clocks:
maxItems: 389
@ -70,6 +74,8 @@ unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
clock-controller@100000 {
compatible = "qcom,gcc-sc8280xp";
reg = <0x00100000 0x1f0000>;
@ -106,6 +112,7 @@ examples:
<&pcie4_lane>,
<&rxc0_ref_clk>,
<&rxc1_ref_clk>;
power-domains = <&rpmhpd SC8280XP_CX>;
#clock-cells = <1>;
#reset-cells = <1>;

View File

@ -24,15 +24,11 @@ properties:
items:
- description: Board XO source
- description: Sleep clock source
- description: PLL test clock source (Optional clock)
minItems: 2
clock-names:
items:
- const: bi_tcxo
- const: sleep_clk
- const: core_bi_pll_test_se # Optional clock
minItems: 2
required:
- compatible
@ -51,8 +47,9 @@ examples:
compatible = "qcom,gcc-sdx55";
reg = <0x00100000 0x1f0000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&sleep_clk>, <&pll_test_clk>;
clock-names = "bi_tcxo", "sleep_clk", "core_bi_pll_test_se";
<&sleep_clk>;
clock-names = "bi_tcxo",
"sleep_clk";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -26,8 +26,6 @@ properties:
- description: Sleep clock source
- description: PCIE Pipe clock source
- description: USB3 phy wrapper pipe clock source
- description: PLL test clock source (Optional clock)
minItems: 5
clock-names:
items:
@ -36,8 +34,6 @@ properties:
- const: sleep_clk
- const: pcie_pipe_clk
- const: usb3_phy_wrapper_gcc_usb30_pipe_clk
- const: core_bi_pll_test_se # Optional clock
minItems: 5
required:
- compatible
@ -56,9 +52,9 @@ examples:
compatible = "qcom,gcc-sdx65";
reg = <0x100000 0x1f7400>;
clocks = <&rpmhcc RPMH_CXO_CLK>, <&rpmhcc RPMH_CXO_CLK_A>, <&sleep_clk>,
<&pcie_pipe_clk>, <&usb3_phy_wrapper_gcc_usb30_pipe_clk>, <&pll_test_clk>;
<&pcie_pipe_clk>, <&usb3_phy_wrapper_gcc_usb30_pipe_clk>;
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk",
"pcie_pipe_clk", "usb3_phy_wrapper_gcc_usb30_pipe_clk", "core_bi_pll_test_se";
"pcie_pipe_clk", "usb3_phy_wrapper_gcc_usb30_pipe_clk";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;

View File

@ -23,7 +23,6 @@ properties:
items:
- description: Board XO source
- description: Sleep clock source
- description: PLL test clock source (Optional clock)
- description: PCIE 0 Pipe clock source (Optional clock)
- description: PCIE 1 Pipe clock source (Optional clock)
- description: UFS card Rx symbol 0 clock source (Optional clock)
@ -40,7 +39,6 @@ properties:
items:
- const: bi_tcxo
- const: sleep_clk
- const: core_bi_pll_test_se # Optional clock
- const: pcie_0_pipe_clk # Optional clock
- const: pcie_1_pipe_clk # Optional clock
- const: ufs_card_rx_symbol_0_clk # Optional clock

View File

@ -1,71 +0,0 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,gpucc-sm8350.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Graphics Clock & Reset Controller on SM8350
maintainers:
- Robert Foss <robert.foss@linaro.org>
description: |
Qualcomm graphics clock control module provides the clocks, resets and power
domains on Qualcomm SoCs.
See also:: include/dt-bindings/clock/qcom,gpucc-sm8350.h
properties:
compatible:
enum:
- qcom,sm8350-gpucc
clocks:
items:
- description: Board XO source
- description: GPLL0 main branch source
- description: GPLL0 div branch source
'#clock-cells':
const: 1
'#reset-cells':
const: 1
'#power-domain-cells':
const: 1
reg:
maxItems: 1
required:
- compatible
- reg
- clocks
- '#clock-cells'
- '#reset-cells'
- '#power-domain-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,gcc-sm8350.h>
#include <dt-bindings/clock/qcom,rpmh.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
clock-controller@3d90000 {
compatible = "qcom,sm8350-gpucc";
reg = <0 0x03d90000 0 0x9000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_GPU_GPLL0_CLK_SRC>,
<&gcc GCC_GPU_GPLL0_DIV_CLK_SRC>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
};
...

View File

@ -21,6 +21,7 @@ description: |
include/dt-bindings/clock/qcom,gpucc-sm6350.h
include/dt-bindings/clock/qcom,gpucc-sm8150.h
include/dt-bindings/clock/qcom,gpucc-sm8250.h
include/dt-bindings/clock/qcom,gpucc-sm8350.h
properties:
compatible:
@ -33,6 +34,7 @@ properties:
- qcom,sm6350-gpucc
- qcom,sm8150-gpucc
- qcom,sm8250-gpucc
- qcom,sm8350-gpucc
clocks:
items:

View File

@ -32,11 +32,11 @@ properties:
clocks:
minItems: 8
maxItems: 10
maxItems: 13
clock-names:
minItems: 8
maxItems: 10
maxItems: 13
'#clock-cells':
const: 1
@ -137,6 +137,46 @@ allOf:
- const: edp_link_clk
- const: edp_vco_div
- if:
properties:
compatible:
contains:
enum:
- qcom,mmcc-apq8084
then:
properties:
clocks:
items:
- description: Board XO source
- description: Board sleep source
- description: MMSS GPLL0 voted clock
- description: GPLL0 clock
- description: GPLL0 voted clock
- description: GPLL1 clock
- description: DSI phy instance 0 dsi clock
- description: DSI phy instance 0 byte clock
- description: DSI phy instance 1 dsi clock
- description: DSI phy instance 1 byte clock
- description: HDMI phy PLL clock
- description: eDP phy PLL link clock
- description: eDP phy PLL vco clock
clock-names:
items:
- const: xo
- const: sleep_clk
- const: mmss_gpll0_vote
- const: gpll0
- const: gpll0_vote
- const: gpll1
- const: dsi0pll
- const: dsi0pllbyte
- const: dsi1pll
- const: dsi1pllbyte
- const: hdmipll
- const: edp_link_clk
- const: edp_vco_div
- if:
properties:
compatible:
@ -229,7 +269,6 @@ allOf:
- description: HDMI phy PLL clock
- description: DisplayPort phy PLL link clock
- description: DisplayPort phy PLL vco clock
- description: Test clock
clock-names:
items:
@ -242,7 +281,6 @@ allOf:
- const: hdmipll
- const: dplink
- const: dpvco
- const: core_bi_pll_test_se
- if:
properties:

View File

@ -27,10 +27,12 @@ properties:
clocks:
items:
- description: XO source
- description: SYS APCS AUX clock
clock-names:
items:
- const: xo
- const: sys_apcs_aux
required:
- compatible
@ -48,6 +50,6 @@ examples:
reg = <0x6400000 0x90000>;
#clock-cells = <1>;
clocks = <&xo_board>;
clock-names = "xo";
clocks = <&xo_board>, <&apcs_glb>;
clock-names = "xo", "sys_apcs_aux";
};

View File

@ -0,0 +1,53 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,msm8996-cbf.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm MSM8996 Core Bus Fabric (CBF) clock controller
maintainers:
- Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
description: >
The clock controller for the Qualcomm MSM8996 CBF clock, which drives the
interconnect between two CPU clusters.
properties:
compatible:
const: qcom,msm8996-cbf
reg:
maxItems: 1
clocks:
items:
- description: XO source
- description: SYS APCS AUX clock
'#clock-cells':
const: 0
'#interconnect-cells':
const: 1
required:
- compatible
- reg
- clocks
- '#clock-cells'
- '#interconnect-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmcc.h>
clock-controller@9a11000 {
compatible = "qcom,msm8996-cbf";
reg = <0x09a11000 0x10000>;
clocks = <&rpmcc RPM_SMD_BB_CLK1>, <&apcs_glb>;
#clock-cells = <0>;
#interconnect-cells = <1>;
};
...

View File

@ -18,6 +18,7 @@ properties:
compatible:
enum:
- qcom,qdu1000-rpmh-clk
- qcom,sa8775p-rpmh-clk
- qcom,sc7180-rpmh-clk
- qcom,sc7280-rpmh-clk
- qcom,sc8180x-rpmh-clk
@ -31,6 +32,7 @@ properties:
- qcom,sm8250-rpmh-clk
- qcom,sm8350-rpmh-clk
- qcom,sm8450-rpmh-clk
- qcom,sm8550-rpmh-clk
clocks:
maxItems: 1

View File

@ -0,0 +1,84 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,sa8775p-gcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller on sa8775p
maintainers:
- Bartosz Golaszewski <bartosz.golaszewski@linaro.org>
description: |
Qualcomm global clock control module provides the clocks, resets and
power domains on sa8775p.
See also:: include/dt-bindings/clock/qcom,sa8775p-gcc.h
properties:
compatible:
const: qcom,sa8775p-gcc
clocks:
items:
- description: XO reference clock
- description: Sleep clock
- description: UFS memory first RX symbol clock
- description: UFS memory second RX symbol clock
- description: UFS memory first TX symbol clock
- description: UFS card first RX symbol clock
- description: UFS card second RX symbol clock
- description: UFS card first TX symbol clock
- description: Primary USB3 PHY wrapper pipe clock
- description: Secondary USB3 PHY wrapper pipe clock
- description: PCIe 0 pipe clock
- description: PCIe 1 pipe clock
- description: PCIe PHY clock
- description: First EMAC controller reference clock
- description: Second EMAC controller reference clock
protected-clocks:
maxItems: 240
power-domains:
maxItems: 1
required:
- compatible
- clocks
allOf:
- $ref: qcom,gcc.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
#include <dt-bindings/power/qcom-rpmpd.h>
gcc: clock-controller@100000 {
compatible = "qcom,sa8775p-gcc";
reg = <0x100000 0xc7018>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&sleep_clk>,
<&ufs_phy_rx_symbol_0_clk>,
<&ufs_phy_rx_symbol_1_clk>,
<&ufs_phy_tx_symbol_0_clk>,
<&ufs_card_rx_symbol_0_clk>,
<&ufs_card_rx_symbol_1_clk>,
<&ufs_card_tx_symbol_0_clk>,
<&usb_0_ssphy>,
<&usb_1_ssphy>,
<&pcie_0_pipe_clk>,
<&pcie_1_pipe_clk>,
<&pcie_phy_pipe_clk>,
<&rxc0_ref_clk>,
<&rxc1_ref_clk>;
power-domains = <&rpmhpd SA8775P_CX>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...

View File

@ -32,6 +32,7 @@ properties:
A phandle and PM domain specifier for the MMCX power domain.
required-opps:
maxItems: 1
description:
A phandle to an OPP node describing required MMCX performance point.

View File

@ -1,59 +0,0 @@
Qualcomm Technologies, Inc. SPMI PMIC clock divider (clkdiv)
clkdiv configures the clock frequency of a set of outputs on the PMIC.
These clocks are typically wired through alternate functions on
gpio pins.
=======================
Properties
=======================
- compatible
Usage: required
Value type: <string>
Definition: must be "qcom,spmi-clkdiv".
- reg
Usage: required
Value type: <prop-encoded-array>
Definition: base address of CLKDIV peripherals.
- qcom,num-clkdivs
Usage: required
Value type: <u32>
Definition: number of CLKDIV peripherals.
- clocks:
Usage: required
Value type: <prop-encoded-array>
Definition: reference to the xo clock.
- clock-names:
Usage: required
Value type: <stringlist>
Definition: must be "xo".
- #clock-cells:
Usage: required
Value type: <u32>
Definition: shall contain 1.
=======
Example
=======
pm8998_clk_divs: clock-controller@5b00 {
compatible = "qcom,spmi-clkdiv";
reg = <0x5b00>;
#clock-cells = <1>;
qcom,num-clkdivs = <3>;
clocks = <&xo_board>;
clock-names = "xo";
assigned-clocks = <&pm8998_clk_divs 1>,
<&pm8998_clk_divs 2>,
<&pm8998_clk_divs 3>;
assigned-clock-rates = <9600000>,
<9600000>,
<9600000>;
};

View File

@ -0,0 +1,71 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,spmi-clkdiv.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm SPMI PMIC clock divider
maintainers:
- Bjorn Andersson <andersson@kernel.org>
- Stephen Boyd <sboyd@kernel.org>
description: |
Qualcomm SPMI PMIC clock divider configures the clock frequency of a set of
outputs on the PMIC. These clocks are typically wired through alternate
functions on GPIO pins.
properties:
compatible:
const: qcom,spmi-clkdiv
reg:
maxItems: 1
clocks:
items:
- description: Board XO source
clock-names:
items:
- const: xo
"#clock-cells":
const: 1
qcom,num-clkdivs:
$ref: /schemas/types.yaml#/definitions/uint32
description: Number of CLKDIV peripherals.
required:
- compatible
- reg
- clocks
- clock-names
- "#clock-cells"
- qcom,num-clkdivs
additionalProperties: false
examples:
- |
pmic {
#address-cells = <1>;
#size-cells = <0>;
clock-controller@5b00 {
compatible = "qcom,spmi-clkdiv";
reg = <0x5b00>;
clocks = <&xo_board>;
clock-names = "xo";
#clock-cells = <1>;
qcom,num-clkdivs = <3>;
assigned-clocks = <&pm8998_clk_divs 1>,
<&pm8998_clk_divs 2>,
<&pm8998_clk_divs 3>;
assigned-clock-rates = <9600000>,
<9600000>,
<9600000>;
};
};

View File

@ -12121,6 +12121,13 @@ S: Maintained
F: Documentation/devicetree/bindings/pinctrl/loongson,ls2k-pinctrl.yaml
F: drivers/pinctrl/pinctrl-loongson2.c
LOONGSON-2 SOC SERIES CLOCK DRIVER
M: Yinbo Zhu <zhuyinbo@loongson.cn>
L: linux-clk@vger.kernel.org
S: Maintained
F: Documentation/devicetree/bindings/clock/loongson,ls2k-clk.yaml
F: include/dt-bindings/clock/loongson,ls2k-clk.h
LSILOGIC MPT FUSION DRIVERS (FC/SAS/SPI)
M: Sathya Prakash <sathya.prakash@broadcom.com>
M: Sreekanth Reddy <sreekanth.reddy@broadcom.com>
@ -14958,6 +14965,7 @@ F: drivers/iio/gyro/fxas21002c_spi.c
NXP i.MX CLOCK DRIVERS
M: Abel Vesa <abelvesa@kernel.org>
R: Peng Fan <peng.fan@nxp.com>
L: linux-clk@vger.kernel.org
L: linux-imx@nxp.com
S: Maintained

View File

@ -2293,7 +2293,7 @@
pinctrl-names = "default";
pinctrl-0 = <&rx_swr_active>;
compatible = "qcom,sm8250-lpass-rx-macro";
reg = <0 0x3200000 0 0x1000>;
reg = <0 0x03200000 0 0x1000>;
status = "disabled";
clocks = <&q6afecc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
@ -2310,7 +2310,7 @@
};
swr1: soundwire-controller@3210000 {
reg = <0 0x3210000 0 0x2000>;
reg = <0 0x03210000 0 0x2000>;
compatible = "qcom,soundwire-v1.5.1";
status = "disabled";
interrupts = <GIC_SPI 298 IRQ_TYPE_LEVEL_HIGH>;
@ -2339,7 +2339,7 @@
pinctrl-names = "default";
pinctrl-0 = <&tx_swr_active>;
compatible = "qcom,sm8250-lpass-tx-macro";
reg = <0 0x3220000 0 0x1000>;
reg = <0 0x03220000 0 0x1000>;
status = "disabled";
clocks = <&q6afecc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
@ -2357,7 +2357,7 @@
/* tx macro */
swr2: soundwire-controller@3230000 {
reg = <0 0x3230000 0 0x2000>;
reg = <0 0x03230000 0 0x2000>;
compatible = "qcom,soundwire-v1.5.1";
interrupts-extended = <&intc GIC_SPI 297 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "core";

View File

@ -516,6 +516,31 @@ ktime_t dev_pm_genpd_get_next_hrtimer(struct device *dev)
}
EXPORT_SYMBOL_GPL(dev_pm_genpd_get_next_hrtimer);
/*
* dev_pm_genpd_synced_poweroff - Next power off should be synchronous
*
* @dev: A device that is attached to the genpd.
*
* Allows a consumer of the genpd to notify the provider that the next power off
* should be synchronous.
*
* It is assumed that the users guarantee that the genpd wouldn't be detached
* while this routine is getting called.
*/
void dev_pm_genpd_synced_poweroff(struct device *dev)
{
struct generic_pm_domain *genpd;
genpd = dev_to_genpd_safe(dev);
if (!genpd)
return;
genpd_lock(genpd);
genpd->synced_poweroff = true;
genpd_unlock(genpd);
}
EXPORT_SYMBOL_GPL(dev_pm_genpd_synced_poweroff);
static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
{
unsigned int state_idx = genpd->state_idx;
@ -559,6 +584,7 @@ static int _genpd_power_on(struct generic_pm_domain *genpd, bool timed)
out:
raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_ON, NULL);
genpd->synced_poweroff = false;
return 0;
err:
raw_notifier_call_chain(&genpd->power_notifiers, GENPD_NOTIFY_OFF,

View File

@ -23,7 +23,6 @@ menuconfig COMMON_CLK
depends on !HAVE_LEGACY_CLK
select HAVE_CLK_PREPARE
select HAVE_CLK
select SRCU
select RATIONAL
help
The common clock framework is a single definition of struct

View File

@ -3,7 +3,7 @@
# Makefile for at91 specific clk
#
obj-y += pmc.o sckc.o dt-compat.o
obj-y += pmc.o sckc.o
obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o
obj-y += clk-system.o clk-peripheral.o clk-programmable.o
@ -15,12 +15,12 @@ obj-$(CONFIG_HAVE_AT91_H32MX) += clk-h32mx.o
obj-$(CONFIG_HAVE_AT91_GENERATED_CLK) += clk-generated.o
obj-$(CONFIG_HAVE_AT91_I2S_MUX_CLK) += clk-i2s-mux.o
obj-$(CONFIG_HAVE_AT91_SAM9X60_PLL) += clk-sam9x60-pll.o
obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9g45.o
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9n12.o at91sam9x5.o
obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o dt-compat.o
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9260.o at91sam9rl.o at91sam9x5.o dt-compat.o
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9g45.o dt-compat.o
obj-$(CONFIG_SOC_AT91SAM9) += at91sam9n12.o at91sam9x5.o dt-compat.o
obj-$(CONFIG_SOC_SAM9X60) += sam9x60.o
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o
obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o
obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o
obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o dt-compat.o
obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o dt-compat.o
obj-$(CONFIG_SOC_SAMA5D2) += sama5d2.o dt-compat.o
obj-$(CONFIG_SOC_SAMA7G5) += sama7g5.o

View File

@ -183,7 +183,7 @@ static void __init at91rm9200_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(at91rm9200_systemck); i++) {
hw = at91_clk_register_system(regmap, at91rm9200_systemck[i].n,
at91rm9200_systemck[i].p,
at91rm9200_systemck[i].id);
at91rm9200_systemck[i].id, 0);
if (IS_ERR(hw))
goto err_free;

View File

@ -460,7 +460,7 @@ static void __init at91sam926x_pmc_setup(struct device_node *np,
for (i = 0; i < data->num_sck; i++) {
hw = at91_clk_register_system(regmap, data->sck[i].n,
data->sck[i].p,
data->sck[i].id);
data->sck[i].id, 0);
if (IS_ERR(hw))
goto err_free;

View File

@ -40,9 +40,14 @@ static const struct clk_pll_characteristics plla_characteristics = {
static const struct {
char *n;
char *p;
unsigned long flags;
u8 id;
} at91sam9g45_systemck[] = {
{ .n = "ddrck", .p = "masterck_div", .id = 2 },
/*
* ddrck feeds DDR controller and is enabled by bootloader thus we need
* to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
{ .n = "uhpck", .p = "usbck", .id = 6 },
{ .n = "pck0", .p = "prog0", .id = 8 },
{ .n = "pck1", .p = "prog1", .id = 9 },
@ -198,7 +203,8 @@ static void __init at91sam9g45_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(at91sam9g45_systemck); i++) {
hw = at91_clk_register_system(regmap, at91sam9g45_systemck[i].n,
at91sam9g45_systemck[i].p,
at91sam9g45_systemck[i].id);
at91sam9g45_systemck[i].id,
at91sam9g45_systemck[i].flags);
if (IS_ERR(hw))
goto err_free;

View File

@ -54,9 +54,14 @@ static const struct clk_pll_characteristics pllb_characteristics = {
static const struct {
char *n;
char *p;
unsigned long flags;
u8 id;
} at91sam9n12_systemck[] = {
{ .n = "ddrck", .p = "masterck_div", .id = 2 },
/*
* ddrck feeds DDR controller and is enabled by bootloader thus we need
* to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
{ .n = "lcdck", .p = "masterck_div", .id = 3 },
{ .n = "uhpck", .p = "usbck", .id = 6 },
{ .n = "udpck", .p = "usbck", .id = 7 },
@ -223,7 +228,8 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(at91sam9n12_systemck); i++) {
hw = at91_clk_register_system(regmap, at91sam9n12_systemck[i].n,
at91sam9n12_systemck[i].p,
at91sam9n12_systemck[i].id);
at91sam9n12_systemck[i].id,
at91sam9n12_systemck[i].flags);
if (IS_ERR(hw))
goto err_free;
@ -236,7 +242,7 @@ static void __init at91sam9n12_pmc_setup(struct device_node *np)
at91sam9n12_periphck[i].n,
"masterck_div",
at91sam9n12_periphck[i].id,
&range, INT_MIN);
&range, INT_MIN, 0);
if (IS_ERR(hw))
goto err_free;

View File

@ -160,7 +160,7 @@ static void __init at91sam9rl_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(at91sam9rl_systemck); i++) {
hw = at91_clk_register_system(regmap, at91sam9rl_systemck[i].n,
at91sam9rl_systemck[i].p,
at91sam9rl_systemck[i].id);
at91sam9rl_systemck[i].id, 0);
if (IS_ERR(hw))
goto err_free;

View File

@ -41,9 +41,14 @@ static const struct clk_pll_characteristics plla_characteristics = {
static const struct {
char *n;
char *p;
unsigned long flags;
u8 id;
} at91sam9x5_systemck[] = {
{ .n = "ddrck", .p = "masterck_div", .id = 2 },
/*
* ddrck feeds DDR controller and is enabled by bootloader thus we need
* to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
{ .n = "smdck", .p = "smdclk", .id = 4 },
{ .n = "uhpck", .p = "usbck", .id = 6 },
{ .n = "udpck", .p = "usbck", .id = 7 },
@ -248,7 +253,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
for (i = 0; i < ARRAY_SIZE(at91sam9x5_systemck); i++) {
hw = at91_clk_register_system(regmap, at91sam9x5_systemck[i].n,
at91sam9x5_systemck[i].p,
at91sam9x5_systemck[i].id);
at91sam9x5_systemck[i].id,
at91sam9x5_systemck[i].flags);
if (IS_ERR(hw))
goto err_free;
@ -256,7 +262,8 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
}
if (has_lcdck) {
hw = at91_clk_register_system(regmap, "lcdck", "masterck_div", 3);
hw = at91_clk_register_system(regmap, "lcdck", "masterck_div",
3, 0);
if (IS_ERR(hw))
goto err_free;
@ -269,7 +276,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
at91sam9x5_periphck[i].n,
"masterck_div",
at91sam9x5_periphck[i].id,
&range, INT_MIN);
&range, INT_MIN, 0);
if (IS_ERR(hw))
goto err_free;
@ -282,7 +289,7 @@ static void __init at91sam9x5_pmc_setup(struct device_node *np,
extra_pcks[i].n,
"masterck_div",
extra_pcks[i].id,
&range, INT_MIN);
&range, INT_MIN, 0);
if (IS_ERR(hw))
goto err_free;

View File

@ -445,7 +445,7 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
const struct clk_pcr_layout *layout,
const char *name, const char *parent_name,
u32 id, const struct clk_range *range,
int chg_pid)
int chg_pid, unsigned long flags)
{
struct clk_sam9x5_peripheral *periph;
struct clk_init_data init;
@ -462,12 +462,12 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
init.name = name;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = flags;
if (chg_pid < 0) {
init.flags = 0;
init.ops = &sam9x5_peripheral_ops;
} else {
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT;
init.flags |= CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE |
CLK_SET_RATE_PARENT;
init.ops = &sam9x5_peripheral_chg_ops;
}

View File

@ -105,7 +105,7 @@ static const struct clk_ops system_ops = {
struct clk_hw * __init
at91_clk_register_system(struct regmap *regmap, const char *name,
const char *parent_name, u8 id)
const char *parent_name, u8 id, unsigned long flags)
{
struct clk_system *sys;
struct clk_hw *hw;
@ -123,7 +123,7 @@ at91_clk_register_system(struct regmap *regmap, const char *name,
init.ops = &system_ops;
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = CLK_SET_RATE_PARENT;
init.flags = CLK_SET_RATE_PARENT | flags;
sys->id = id;
sys->hw.init = &init;

View File

@ -493,18 +493,28 @@ of_at91_clk_periph_setup(struct device_node *np, u8 type)
parent_name, id);
} else {
struct clk_range range = CLK_RANGE(0, 0);
unsigned long flags = 0;
of_at91_get_clk_range(periphclknp,
"atmel,clk-output-range",
&range);
/*
* mpddr_clk feed DDR controller and is enabled by
* bootloader thus we need to keep it enabled in case
* there is no Linux consumer for it.
*/
if (!strcmp(periphclknp->name, "mpddr_clk"))
flags = CLK_IS_CRITICAL;
hw = at91_clk_register_sam9x5_peripheral(regmap,
&pmc_pcr_lock,
&dt_pcr_layout,
name,
parent_name,
id, &range,
INT_MIN);
INT_MIN,
flags);
}
if (IS_ERR(hw))
@ -879,6 +889,8 @@ static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
return;
for_each_child_of_node(np, sysclknp) {
unsigned long flags = 0;
if (of_property_read_u32(sysclknp, "reg", &id))
continue;
@ -887,7 +899,16 @@ static void __init of_at91rm9200_clk_sys_setup(struct device_node *np)
parent_name = of_clk_get_parent_name(sysclknp, 0);
hw = at91_clk_register_system(regmap, name, parent_name, id);
/*
* ddrck feeds DDR controller and is enabled by bootloader thus
* we need to keep it enabled in case there is no Linux consumer
* for it.
*/
if (!strcmp(sysclknp->name, "ddrck"))
flags = CLK_IS_CRITICAL;
hw = at91_clk_register_system(regmap, name, parent_name, id,
flags);
if (IS_ERR(hw))
continue;

View File

@ -199,7 +199,7 @@ at91_clk_register_sam9x5_peripheral(struct regmap *regmap, spinlock_t *lock,
const struct clk_pcr_layout *layout,
const char *name, const char *parent_name,
u32 id, const struct clk_range *range,
int chg_pid);
int chg_pid, unsigned long flags);
struct clk_hw * __init
at91_clk_register_pll(struct regmap *regmap, const char *name,
@ -242,7 +242,7 @@ at91sam9x5_clk_register_smd(struct regmap *regmap, const char *name,
struct clk_hw * __init
at91_clk_register_system(struct regmap *regmap, const char *name,
const char *parent_name, u8 id);
const char *parent_name, u8 id, unsigned long flags);
struct clk_hw * __init
at91sam9x5_clk_register_usb(struct regmap *regmap, const char *name,

View File

@ -75,9 +75,14 @@ static const struct clk_pcr_layout sam9x60_pcr_layout = {
static const struct {
char *n;
char *p;
unsigned long flags;
u8 id;
} sam9x60_systemck[] = {
{ .n = "ddrck", .p = "masterck_div", .id = 2 },
/*
* ddrck feeds DDR controller and is enabled by bootloader thus we need
* to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
{ .n = "uhpck", .p = "usbck", .id = 6 },
{ .n = "pck0", .p = "prog0", .id = 8 },
{ .n = "pck1", .p = "prog1", .id = 9 },
@ -86,6 +91,7 @@ static const struct {
static const struct {
char *n;
unsigned long flags;
u8 id;
} sam9x60_periphck[] = {
{ .n = "pioA_clk", .id = 2, },
@ -132,7 +138,11 @@ static const struct {
{ .n = "pioD_clk", .id = 44, },
{ .n = "tcb1_clk", .id = 45, },
{ .n = "dbgu_clk", .id = 47, },
{ .n = "mpddr_clk", .id = 49, },
/*
* mpddr_clk feeds DDR controller and is enabled by bootloader thus we
* need to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "mpddr_clk", .id = 49, .flags = CLK_IS_CRITICAL },
};
static const struct {
@ -315,7 +325,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(sam9x60_systemck); i++) {
hw = at91_clk_register_system(regmap, sam9x60_systemck[i].n,
sam9x60_systemck[i].p,
sam9x60_systemck[i].id);
sam9x60_systemck[i].id,
sam9x60_systemck[i].flags);
if (IS_ERR(hw))
goto err_free;
@ -328,7 +339,8 @@ static void __init sam9x60_pmc_setup(struct device_node *np)
sam9x60_periphck[i].n,
"masterck_div",
sam9x60_periphck[i].id,
&range, INT_MIN);
&range, INT_MIN,
sam9x60_periphck[i].flags);
if (IS_ERR(hw))
goto err_free;

View File

@ -40,9 +40,14 @@ static const struct clk_pcr_layout sama5d2_pcr_layout = {
static const struct {
char *n;
char *p;
unsigned long flags;
u8 id;
} sama5d2_systemck[] = {
{ .n = "ddrck", .p = "masterck_div", .id = 2 },
/*
* ddrck feeds DDR controller and is enabled by bootloader thus we need
* to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
{ .n = "lcdck", .p = "masterck_div", .id = 3 },
{ .n = "uhpck", .p = "usbck", .id = 6 },
{ .n = "udpck", .p = "usbck", .id = 7 },
@ -97,6 +102,7 @@ static const struct {
static const struct {
char *n;
unsigned long flags;
u8 id;
} sama5d2_periphck[] = {
{ .n = "dma0_clk", .id = 6, },
@ -104,7 +110,11 @@ static const struct {
{ .n = "aes_clk", .id = 9, },
{ .n = "aesb_clk", .id = 10, },
{ .n = "sha_clk", .id = 12, },
{ .n = "mpddr_clk", .id = 13, },
/*
* mpddr_clk feeds DDR controller and is enabled by bootloader thus we
* need to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "mpddr_clk", .id = 13, .flags = CLK_IS_CRITICAL },
{ .n = "matrix0_clk", .id = 15, },
{ .n = "sdmmc0_hclk", .id = 31, },
{ .n = "sdmmc1_hclk", .id = 32, },
@ -302,7 +312,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(sama5d2_systemck); i++) {
hw = at91_clk_register_system(regmap, sama5d2_systemck[i].n,
sama5d2_systemck[i].p,
sama5d2_systemck[i].id);
sama5d2_systemck[i].id,
sama5d2_systemck[i].flags);
if (IS_ERR(hw))
goto err_free;
@ -315,7 +326,8 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
sama5d2_periphck[i].n,
"masterck_div",
sama5d2_periphck[i].id,
&range, INT_MIN);
&range, INT_MIN,
sama5d2_periphck[i].flags);
if (IS_ERR(hw))
goto err_free;
@ -329,7 +341,7 @@ static void __init sama5d2_pmc_setup(struct device_node *np)
"h32mxck",
sama5d2_periph32ck[i].id,
&sama5d2_periph32ck[i].r,
INT_MIN);
INT_MIN, 0);
if (IS_ERR(hw))
goto err_free;

View File

@ -40,9 +40,14 @@ static const struct clk_pcr_layout sama5d3_pcr_layout = {
static const struct {
char *n;
char *p;
unsigned long flags;
u8 id;
} sama5d3_systemck[] = {
{ .n = "ddrck", .p = "masterck_div", .id = 2 },
/*
* ddrck feeds DDR controller and is enabled by bootloader thus we need
* to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
{ .n = "lcdck", .p = "masterck_div", .id = 3 },
{ .n = "smdck", .p = "smdclk", .id = 4 },
{ .n = "uhpck", .p = "usbck", .id = 6 },
@ -56,6 +61,7 @@ static const struct {
char *n;
u8 id;
struct clk_range r;
unsigned long flags;
} sama5d3_periphck[] = {
{ .n = "dbgu_clk", .id = 2, },
{ .n = "hsmc_clk", .id = 5, },
@ -99,7 +105,11 @@ static const struct {
{ .n = "tdes_clk", .id = 44, },
{ .n = "trng_clk", .id = 45, },
{ .n = "fuse_clk", .id = 48, },
{ .n = "mpddr_clk", .id = 49, },
/*
* mpddr_clk feeds DDR controller and is enabled by bootloader thus we
* need to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "mpddr_clk", .id = 49, .flags = CLK_IS_CRITICAL },
};
static void __init sama5d3_pmc_setup(struct device_node *np)
@ -222,7 +232,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(sama5d3_systemck); i++) {
hw = at91_clk_register_system(regmap, sama5d3_systemck[i].n,
sama5d3_systemck[i].p,
sama5d3_systemck[i].id);
sama5d3_systemck[i].id,
sama5d3_systemck[i].flags);
if (IS_ERR(hw))
goto err_free;
@ -236,7 +247,8 @@ static void __init sama5d3_pmc_setup(struct device_node *np)
"masterck_div",
sama5d3_periphck[i].id,
&sama5d3_periphck[i].r,
INT_MIN);
INT_MIN,
sama5d3_periphck[i].flags);
if (IS_ERR(hw))
goto err_free;

View File

@ -39,9 +39,14 @@ static const struct clk_pcr_layout sama5d4_pcr_layout = {
static const struct {
char *n;
char *p;
unsigned long flags;
u8 id;
} sama5d4_systemck[] = {
{ .n = "ddrck", .p = "masterck_div", .id = 2 },
/*
* ddrck feeds DDR controller and is enabled by bootloader thus we need
* to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "ddrck", .p = "masterck_div", .id = 2, .flags = CLK_IS_CRITICAL },
{ .n = "lcdck", .p = "masterck_div", .id = 3 },
{ .n = "smdck", .p = "smdclk", .id = 4 },
{ .n = "uhpck", .p = "usbck", .id = 6 },
@ -103,12 +108,17 @@ static const struct {
static const struct {
char *n;
unsigned long flags;
u8 id;
} sama5d4_periphck[] = {
{ .n = "dma0_clk", .id = 8 },
{ .n = "cpkcc_clk", .id = 10 },
{ .n = "aesb_clk", .id = 13 },
{ .n = "mpddr_clk", .id = 16 },
/*
* mpddr_clk feeds DDR controller and is enabled by bootloader thus we
* need to keep it enabled in case there is no Linux consumer for it.
*/
{ .n = "mpddr_clk", .id = 16, .flags = CLK_IS_CRITICAL },
{ .n = "matrix0_clk", .id = 18 },
{ .n = "vdec_clk", .id = 19 },
{ .n = "dma1_clk", .id = 50 },
@ -245,7 +255,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(sama5d4_systemck); i++) {
hw = at91_clk_register_system(regmap, sama5d4_systemck[i].n,
sama5d4_systemck[i].p,
sama5d4_systemck[i].id);
sama5d4_systemck[i].id,
sama5d4_systemck[i].flags);
if (IS_ERR(hw))
goto err_free;
@ -258,7 +269,8 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
sama5d4_periphck[i].n,
"masterck_div",
sama5d4_periphck[i].id,
&range, INT_MIN);
&range, INT_MIN,
sama5d4_periphck[i].flags);
if (IS_ERR(hw))
goto err_free;
@ -271,7 +283,7 @@ static void __init sama5d4_pmc_setup(struct device_node *np)
sama5d4_periph32ck[i].n,
"h32mxck",
sama5d4_periph32ck[i].id,
&range, INT_MIN);
&range, INT_MIN, 0);
if (IS_ERR(hw))
goto err_free;

View File

@ -1068,7 +1068,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
for (i = 0; i < ARRAY_SIZE(sama7g5_systemck); i++) {
hw = at91_clk_register_system(regmap, sama7g5_systemck[i].n,
sama7g5_systemck[i].p,
sama7g5_systemck[i].id);
sama7g5_systemck[i].id, 0);
if (IS_ERR(hw))
goto err_free;
@ -1083,7 +1083,7 @@ static void __init sama7g5_pmc_setup(struct device_node *np)
sama7g5_periphck[i].id,
&sama7g5_periphck[i].r,
sama7g5_periphck[i].chgp ? 0 :
INT_MIN);
INT_MIN, 0);
if (IS_ERR(hw))
goto err_free;

View File

@ -60,7 +60,6 @@ struct rs9_driver_data {
struct i2c_client *client;
struct regmap *regmap;
const struct rs9_chip_info *chip_info;
struct clk *pin_xin;
struct clk_hw *clk_dif[2];
u8 pll_amplitude;
u8 pll_ssc;

View File

@ -122,9 +122,8 @@
#define VC5_GLOBAL_REGISTER 0x76
#define VC5_GLOBAL_REGISTER_GLOBAL_RESET BIT(5)
/* PLL/VCO runs between 2.5 GHz and 3.0 GHz */
/* The minimum VCO frequency is 2.5 GHz. The maximum is variant specific. */
#define VC5_PLL_VCO_MIN 2500000000UL
#define VC5_PLL_VCO_MAX 3000000000UL
/* VC5 Input mux settings */
#define VC5_MUX_IN_XIN BIT(0)
@ -150,6 +149,7 @@ enum vc5_model {
IDT_VC5_5P49V5925,
IDT_VC5_5P49V5933,
IDT_VC5_5P49V5935,
IDT_VC6_5P49V60,
IDT_VC6_5P49V6901,
IDT_VC6_5P49V6965,
IDT_VC6_5P49V6975,
@ -161,6 +161,7 @@ struct vc5_chip_info {
const unsigned int clk_fod_cnt;
const unsigned int clk_out_cnt;
const u32 flags;
const unsigned long vco_max;
};
struct vc5_driver_data;
@ -446,13 +447,11 @@ static long vc5_pll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct vc5_hw_data *hwdata = container_of(hw, struct vc5_hw_data, hw);
struct vc5_driver_data *vc5 = hwdata->vc5;
u32 div_int;
u64 div_frc;
if (rate < VC5_PLL_VCO_MIN)
rate = VC5_PLL_VCO_MIN;
if (rate > VC5_PLL_VCO_MAX)
rate = VC5_PLL_VCO_MAX;
rate = clamp(rate, VC5_PLL_VCO_MIN, vc5->chip_info->vco_max);
/* Determine integer part, which is 12 bit wide */
div_int = rate / *parent_rate;
@ -1212,6 +1211,7 @@ static const struct vc5_chip_info idt_5p49v5923_info = {
.clk_fod_cnt = 2,
.clk_out_cnt = 3,
.flags = 0,
.vco_max = 3000000000UL,
};
static const struct vc5_chip_info idt_5p49v5925_info = {
@ -1219,6 +1219,7 @@ static const struct vc5_chip_info idt_5p49v5925_info = {
.clk_fod_cnt = 4,
.clk_out_cnt = 5,
.flags = 0,
.vco_max = 3000000000UL,
};
static const struct vc5_chip_info idt_5p49v5933_info = {
@ -1226,6 +1227,7 @@ static const struct vc5_chip_info idt_5p49v5933_info = {
.clk_fod_cnt = 2,
.clk_out_cnt = 3,
.flags = VC5_HAS_INTERNAL_XTAL,
.vco_max = 3000000000UL,
};
static const struct vc5_chip_info idt_5p49v5935_info = {
@ -1233,6 +1235,15 @@ static const struct vc5_chip_info idt_5p49v5935_info = {
.clk_fod_cnt = 4,
.clk_out_cnt = 5,
.flags = VC5_HAS_INTERNAL_XTAL,
.vco_max = 3000000000UL,
};
static const struct vc5_chip_info idt_5p49v60_info = {
.model = IDT_VC6_5P49V60,
.clk_fod_cnt = 4,
.clk_out_cnt = 5,
.flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT,
.vco_max = 2700000000UL,
};
static const struct vc5_chip_info idt_5p49v6901_info = {
@ -1240,6 +1251,7 @@ static const struct vc5_chip_info idt_5p49v6901_info = {
.clk_fod_cnt = 4,
.clk_out_cnt = 5,
.flags = VC5_HAS_PFD_FREQ_DBL | VC5_HAS_BYPASS_SYNC_BIT,
.vco_max = 3000000000UL,
};
static const struct vc5_chip_info idt_5p49v6965_info = {
@ -1247,6 +1259,7 @@ static const struct vc5_chip_info idt_5p49v6965_info = {
.clk_fod_cnt = 4,
.clk_out_cnt = 5,
.flags = VC5_HAS_BYPASS_SYNC_BIT,
.vco_max = 3000000000UL,
};
static const struct vc5_chip_info idt_5p49v6975_info = {
@ -1254,6 +1267,7 @@ static const struct vc5_chip_info idt_5p49v6975_info = {
.clk_fod_cnt = 4,
.clk_out_cnt = 5,
.flags = VC5_HAS_BYPASS_SYNC_BIT | VC5_HAS_INTERNAL_XTAL,
.vco_max = 3000000000UL,
};
static const struct i2c_device_id vc5_id[] = {
@ -1261,6 +1275,7 @@ static const struct i2c_device_id vc5_id[] = {
{ "5p49v5925", .driver_data = IDT_VC5_5P49V5925 },
{ "5p49v5933", .driver_data = IDT_VC5_5P49V5933 },
{ "5p49v5935", .driver_data = IDT_VC5_5P49V5935 },
{ "5p49v60", .driver_data = IDT_VC6_5P49V60 },
{ "5p49v6901", .driver_data = IDT_VC6_5P49V6901 },
{ "5p49v6965", .driver_data = IDT_VC6_5P49V6965 },
{ "5p49v6975", .driver_data = IDT_VC6_5P49V6975 },
@ -1273,6 +1288,7 @@ static const struct of_device_id clk_vc5_of_match[] = {
{ .compatible = "idt,5p49v5925", .data = &idt_5p49v5925_info },
{ .compatible = "idt,5p49v5933", .data = &idt_5p49v5933_info },
{ .compatible = "idt,5p49v5935", .data = &idt_5p49v5935_info },
{ .compatible = "idt,5p49v60", .data = &idt_5p49v60_info },
{ .compatible = "idt,5p49v6901", .data = &idt_5p49v6901_info },
{ .compatible = "idt,5p49v6965", .data = &idt_5p49v6965_info },
{ .compatible = "idt,5p49v6975", .data = &idt_5p49v6975_info },

View File

@ -244,6 +244,17 @@ static bool clk_core_is_enabled(struct clk_core *core)
}
}
/*
* This could be called with the enable lock held, or from atomic
* context. If the parent isn't enabled already, we can't do
* anything here. We can also assume this clock isn't enabled.
*/
if ((core->flags & CLK_OPS_PARENT_ENABLE) && core->parent)
if (!clk_core_is_enabled(core->parent)) {
ret = false;
goto done;
}
ret = core->ops->is_enabled(core->hw);
done:
if (core->rpm_enabled)

View File

@ -115,7 +115,7 @@ config CLK_IMX93
config CLK_IMXRT1050
tristate "IMXRT1050 CCM Clock Driver"
depends on SOC_IMXRT
depends on SOC_IMXRT || COMPILE_TEST
select MXC_CLK
help
Build the driver for i.MXRT1050 CCM Clock Driver

View File

@ -22,6 +22,7 @@ mxc-clk-objs += clk-pllv3.o
mxc-clk-objs += clk-pllv4.o
mxc-clk-objs += clk-pll14xx.o
mxc-clk-objs += clk-sscg-pll.o
mxc-clk-objs += clk-gpr-mux.o
obj-$(CONFIG_MXC_CLK) += mxc-clk.o
obj-$(CONFIG_CLK_IMX8MM) += clk-imx8mm.o

View File

@ -0,0 +1,119 @@
// SPDX-License-Identifier: GPL-2.0
/*
*/
#define pr_fmt(fmt) "imx:clk-gpr-mux: " fmt
#include <linux/module.h>
#include <linux/clk-provider.h>
#include <linux/errno.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include "clk.h"
struct imx_clk_gpr {
struct clk_hw hw;
struct regmap *regmap;
u32 mask;
u32 reg;
const u32 *mux_table;
};
static struct imx_clk_gpr *to_imx_clk_gpr(struct clk_hw *hw)
{
return container_of(hw, struct imx_clk_gpr, hw);
}
static u8 imx_clk_gpr_mux_get_parent(struct clk_hw *hw)
{
struct imx_clk_gpr *priv = to_imx_clk_gpr(hw);
unsigned int val;
int ret;
ret = regmap_read(priv->regmap, priv->reg, &val);
if (ret)
goto get_parent_err;
val &= priv->mask;
ret = clk_mux_val_to_index(hw, priv->mux_table, 0, val);
if (ret < 0)
goto get_parent_err;
return ret;
get_parent_err:
pr_err("failed to get parent (%pe)\n", ERR_PTR(ret));
/* return some realistic non negative value. Potentially we could
* give index to some dummy error parent.
*/
return 0;
}
static int imx_clk_gpr_mux_set_parent(struct clk_hw *hw, u8 index)
{
struct imx_clk_gpr *priv = to_imx_clk_gpr(hw);
unsigned int val = clk_mux_index_to_val(priv->mux_table, 0, index);
return regmap_update_bits(priv->regmap, priv->reg, priv->mask, val);
}
static int imx_clk_gpr_mux_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
return clk_mux_determine_rate_flags(hw, req, 0);
}
static const struct clk_ops imx_clk_gpr_mux_ops = {
.get_parent = imx_clk_gpr_mux_get_parent,
.set_parent = imx_clk_gpr_mux_set_parent,
.determine_rate = imx_clk_gpr_mux_determine_rate,
};
struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
u32 reg, const char **parent_names,
u8 num_parents, const u32 *mux_table, u32 mask)
{
struct clk_init_data init = { };
struct imx_clk_gpr *priv;
struct regmap *regmap;
struct clk_hw *hw;
int ret;
regmap = syscon_regmap_lookup_by_compatible(compatible);
if (IS_ERR(regmap)) {
pr_err("failed to find %s regmap\n", compatible);
return ERR_CAST(regmap);
}
priv = kzalloc(sizeof(*priv), GFP_KERNEL);
if (!priv)
return ERR_PTR(-ENOMEM);
init.name = name;
init.ops = &imx_clk_gpr_mux_ops;
init.parent_names = parent_names;
init.num_parents = num_parents;
init.flags = CLK_SET_RATE_GATE | CLK_SET_PARENT_GATE;
priv->hw.init = &init;
priv->regmap = regmap;
priv->mux_table = mux_table;
priv->reg = reg;
priv->mask = mask;
hw = &priv->hw;
ret = clk_hw_register(NULL, &priv->hw);
if (ret) {
kfree(priv);
hw = ERR_PTR(ret);
}
return hw;
}

View File

@ -218,7 +218,7 @@ static int __init __mx25_clocks_init(void __iomem *ccm_base)
*/
clk_set_parent(clk[cko_sel], clk[ipg]);
imx_register_uart_clocks(6);
imx_register_uart_clocks();
return 0;
}

View File

@ -165,7 +165,7 @@ static void __init _mx27_clocks_init(unsigned long fref)
clk_prepare_enable(clk[IMX27_CLK_EMI_AHB_GATE]);
imx_register_uart_clocks(7);
imx_register_uart_clocks();
imx_print_silicon_rev("i.MX27", mx27_revision());
}

View File

@ -235,7 +235,7 @@ static void __init _mx35_clocks_init(void)
*/
clk_prepare_enable(clk[scc_gate]);
imx_register_uart_clocks(4);
imx_register_uart_clocks();
imx_print_silicon_rev("i.MX35", mx35_revision());
}

View File

@ -358,7 +358,7 @@ static void __init mx50_clocks_init(struct device_node *np)
r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
imx_register_uart_clocks(5);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx50_ccm, "fsl,imx50-ccm", mx50_clocks_init);
@ -464,7 +464,7 @@ static void __init mx51_clocks_init(struct device_node *np)
val |= 1 << 23;
writel(val, MXC_CCM_CLPCR);
imx_register_uart_clocks(3);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx51_ccm, "fsl,imx51-ccm", mx51_clocks_init);
@ -609,6 +609,6 @@ static void __init mx53_clocks_init(struct device_node *np)
r = clk_round_rate(clk[IMX5_CLK_USBOH3_PER_GATE], 54000000);
clk_set_rate(clk[IMX5_CLK_USBOH3_PER_GATE], r);
imx_register_uart_clocks(5);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx53_ccm, "fsl,imx53-ccm", mx53_clocks_init);

View File

@ -12,6 +12,7 @@
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
@ -115,6 +116,10 @@ static struct clk_div_table video_div_table[] = {
{ /* sentinel */ }
};
static const char * enet_ref_sels[] = { "enet_ref", "enet_ref_pad", };
static const u32 enet_ref_sels_table[] = { IMX6Q_GPR1_ENET_CLK_SEL_ANATOP, IMX6Q_GPR1_ENET_CLK_SEL_PAD };
static const u32 enet_ref_sels_table_mask = IMX6Q_GPR1_ENET_CLK_SEL_ANATOP;
static unsigned int share_count_esai;
static unsigned int share_count_asrc;
static unsigned int share_count_ssi1;
@ -908,6 +913,12 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
if (clk_on_imx6q() && imx_get_soc_revision() == IMX_CHIP_REVISION_1_0)
hws[IMX6QDL_CLK_GPT_3M] = hws[IMX6QDL_CLK_GPT_IPG_PER];
hws[IMX6QDL_CLK_ENET_REF_PAD] = imx6q_obtain_fixed_clk_hw(ccm_node, "enet_ref_pad", 0);
hws[IMX6QDL_CLK_ENET_REF_SEL] = imx_clk_gpr_mux("enet_ref_sel", "fsl,imx6q-iomuxc-gpr",
IOMUXC_GPR1, enet_ref_sels, ARRAY_SIZE(enet_ref_sels),
enet_ref_sels_table, enet_ref_sels_table_mask);
imx_check_clk_hws(hws, IMX6QDL_CLK_END);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
@ -974,6 +985,8 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
hws[IMX6QDL_CLK_PLL3_USB_OTG]->clk);
}
imx_register_uart_clocks(2);
clk_set_parent(hws[IMX6QDL_CLK_ENET_REF_SEL]->clk, hws[IMX6QDL_CLK_ENET_REF]->clk);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx6q, "fsl,imx6q-ccm", imx6q_clocks_init);

View File

@ -440,6 +440,6 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clk_set_parent(hws[IMX6SL_CLK_LCDIF_AXI_SEL]->clk,
hws[IMX6SL_CLK_PLL2_PFD2]->clk);
imx_register_uart_clocks(2);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx6sl, "fsl,imx6sl-ccm", imx6sl_clocks_init);

View File

@ -340,7 +340,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
imx_register_uart_clocks(5);
imx_register_uart_clocks();
/* Lower the AHB clock rate before changing the clock source. */
clk_set_rate(hws[IMX6SLL_CLK_AHB]->clk, 99000000);

View File

@ -548,6 +548,6 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
clk_set_parent(hws[IMX6SX_CLK_QSPI1_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
clk_set_parent(hws[IMX6SX_CLK_QSPI2_SEL]->clk, hws[IMX6SX_CLK_PLL2_BUS]->clk);
imx_register_uart_clocks(2);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx6sx, "fsl,imx6sx-ccm", imx6sx_clocks_init);

View File

@ -10,6 +10,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/mfd/syscon/imx6q-iomuxc-gpr.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
@ -94,6 +95,17 @@ static const struct clk_div_table video_div_table[] = {
{ }
};
static const char * enet1_ref_sels[] = { "enet1_ref_125m", "enet1_ref_pad", };
static const u32 enet1_ref_sels_table[] = { IMX6UL_GPR1_ENET1_TX_CLK_DIR,
IMX6UL_GPR1_ENET1_CLK_SEL };
static const u32 enet1_ref_sels_table_mask = IMX6UL_GPR1_ENET1_TX_CLK_DIR |
IMX6UL_GPR1_ENET1_CLK_SEL;
static const char * enet2_ref_sels[] = { "enet2_ref_125m", "enet2_ref_pad", };
static const u32 enet2_ref_sels_table[] = { IMX6UL_GPR1_ENET2_TX_CLK_DIR,
IMX6UL_GPR1_ENET2_CLK_SEL };
static const u32 enet2_ref_sels_table_mask = IMX6UL_GPR1_ENET2_TX_CLK_DIR |
IMX6UL_GPR1_ENET2_CLK_SEL;
static u32 share_count_asrc;
static u32 share_count_audio;
static u32 share_count_sai1;
@ -176,7 +188,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
hws[IMX6UL_CLK_PLL3_USB_OTG] = imx_clk_hw_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
hws[IMX6UL_CLK_PLL4_AUDIO] = imx_clk_hw_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
hws[IMX6UL_CLK_PLL5_VIDEO] = imx_clk_hw_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
hws[IMX6UL_CLK_PLL6_ENET] = imx_clk_hw_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
hws[IMX6UL_CLK_PLL6_ENET] = imx_clk_hw_fixed_factor("pll6_enet", "pll6_bypass", 1, 1);
hws[IMX6UL_CLK_PLL7_USB_HOST] = imx_clk_hw_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
/*
@ -205,12 +217,13 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
hws[IMX6UL_CLK_PLL3_PFD2] = imx_clk_hw_pfd("pll3_pfd2_508m", "pll3_usb_otg", base + 0xf0, 2);
hws[IMX6UL_CLK_PLL3_PFD3] = imx_clk_hw_pfd("pll3_pfd3_454m", "pll3_usb_otg", base + 0xf0, 3);
hws[IMX6UL_CLK_ENET_REF] = clk_hw_register_divider_table(NULL, "enet_ref", "pll6_enet", 0,
hws[IMX6UL_CLK_ENET_REF] = clk_hw_register_divider_table(NULL, "enet1_ref", "pll6_enet", 0,
base + 0xe0, 0, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
hws[IMX6UL_CLK_ENET2_REF] = clk_hw_register_divider_table(NULL, "enet2_ref", "pll6_enet", 0,
base + 0xe0, 2, 2, 0, clk_enet_ref_table, &imx_ccm_lock);
hws[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_hw_gate("enet_ref_125m", "enet2_ref", base + 0xe0, 20);
hws[IMX6UL_CLK_ENET1_REF_125M] = imx_clk_hw_gate("enet1_ref_125m", "enet1_ref", base + 0xe0, 13);
hws[IMX6UL_CLK_ENET2_REF_125M] = imx_clk_hw_gate("enet2_ref_125m", "enet2_ref", base + 0xe0, 20);
hws[IMX6UL_CLK_ENET_PTP_REF] = imx_clk_hw_fixed_factor("enet_ptp_ref", "pll6_enet", 1, 20);
hws[IMX6UL_CLK_ENET_PTP] = imx_clk_hw_gate("enet_ptp", "enet_ptp_ref", base + 0xe0, 21);
@ -471,6 +484,17 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
/* mask handshake of mmdc */
imx_mmdc_mask_handshake(base, 0);
hws[IMX6UL_CLK_ENET1_REF_PAD] = imx_obtain_fixed_of_clock(ccm_node, "enet1_ref_pad", 0);
hws[IMX6UL_CLK_ENET1_REF_SEL] = imx_clk_gpr_mux("enet1_ref_sel", "fsl,imx6ul-iomuxc-gpr",
IOMUXC_GPR1, enet1_ref_sels, ARRAY_SIZE(enet1_ref_sels),
enet1_ref_sels_table, enet1_ref_sels_table_mask);
hws[IMX6UL_CLK_ENET2_REF_PAD] = imx_obtain_fixed_of_clock(ccm_node, "enet2_ref_pad", 0);
hws[IMX6UL_CLK_ENET2_REF_SEL] = imx_clk_gpr_mux("enet2_ref_sel", "fsl,imx6ul-iomuxc-gpr",
IOMUXC_GPR1, enet2_ref_sels, ARRAY_SIZE(enet2_ref_sels),
enet2_ref_sels_table, enet2_ref_sels_table_mask);
imx_check_clk_hws(hws, IMX6UL_CLK_END);
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
@ -515,6 +539,9 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clk_set_parent(hws[IMX6ULL_CLK_EPDC_PRE_SEL]->clk, hws[IMX6UL_CLK_PLL3_PFD2]->clk);
clk_set_parent(hws[IMX6UL_CLK_ENFC_SEL]->clk, hws[IMX6UL_CLK_PLL2_PFD2]->clk);
clk_set_parent(hws[IMX6UL_CLK_ENET1_REF_SEL]->clk, hws[IMX6UL_CLK_ENET_REF]->clk);
clk_set_parent(hws[IMX6UL_CLK_ENET2_REF_SEL]->clk, hws[IMX6UL_CLK_ENET2_REF]->clk);
}
CLK_OF_DECLARE(imx6ul, "fsl,imx6ul-ccm", imx6ul_clocks_init);

View File

@ -882,7 +882,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
hws[IMX7D_USB1_MAIN_480M_CLK] = imx_clk_hw_fixed_factor("pll_usb1_main_clk", "osc", 20, 1);
hws[IMX7D_USB_MAIN_480M_CLK] = imx_clk_hw_fixed_factor("pll_usb_main_clk", "osc", 20, 1);
imx_register_uart_clocks(7);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx7d, "fsl,imx7d-ccm", imx7d_clocks_init);

View File

@ -176,7 +176,7 @@ static void __init imx7ulp_clk_pcc2_init(struct device_node *np)
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
imx_register_uart_clocks(2);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx7ulp_clk_pcc2, "fsl,imx7ulp-pcc2", imx7ulp_clk_pcc2_init);
@ -223,7 +223,7 @@ static void __init imx7ulp_clk_pcc3_init(struct device_node *np)
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_data);
imx_register_uart_clocks(7);
imx_register_uart_clocks();
}
CLK_OF_DECLARE(imx7ulp_clk_pcc3, "fsl,imx7ulp-pcc3", imx7ulp_clk_pcc3_init);

View File

@ -609,7 +609,7 @@ static int imx8mm_clocks_probe(struct platform_device *pdev)
goto unregister_hws;
}
imx_register_uart_clocks(4);
imx_register_uart_clocks();
return 0;

View File

@ -602,7 +602,7 @@ static int imx8mn_clocks_probe(struct platform_device *pdev)
goto unregister_hws;
}
imx_register_uart_clocks(4);
imx_register_uart_clocks();
return 0;

View File

@ -723,7 +723,7 @@ static int imx8mp_clocks_probe(struct platform_device *pdev)
of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data);
imx_register_uart_clocks(4);
imx_register_uart_clocks();
return 0;
}

View File

@ -601,7 +601,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
goto unregister_hws;
}
imx_register_uart_clocks(4);
imx_register_uart_clocks();
return 0;

View File

@ -385,7 +385,7 @@ static int imx8ulp_clk_pcc3_init(struct platform_device *pdev)
if (ret)
return ret;
imx_register_uart_clocks(1);
imx_register_uart_clocks();
/* register the pcc3 reset controller */
return imx8ulp_pcc_reset_init(pdev, base, pcc3_resets, ARRAY_SIZE(pcc3_resets));

View File

@ -326,6 +326,8 @@ static int imx93_clocks_probe(struct platform_device *pdev)
goto unregister_hws;
}
imx_register_uart_clocks();
return 0;
unregister_hws:

View File

@ -167,3 +167,7 @@ static struct platform_driver imxrt1050_clk_driver = {
},
};
module_platform_driver(imxrt1050_clk_driver);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("Jesse Taube <Mr.Bossman075@gmail.com>");
MODULE_AUTHOR("Giulio Benetti <giulio.benetti@benettiengineering.com>");

View File

@ -5,6 +5,7 @@
*/
#include <linux/clk-provider.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/slab.h>
#include <linux/err.h>
@ -153,3 +154,4 @@ struct clk_hw *imx_clk_hw_pfd(const char *name, const char *parent_name,
return hw;
}
EXPORT_SYMBOL_GPL(imx_clk_hw_pfd);

View File

@ -256,7 +256,7 @@ static unsigned long clk_pll14xx_recalc_rate(struct clk_hw *hw,
if (pll->type == PLL_1443X) {
pll_div_ctl1 = readl_relaxed(pll->base + DIV_CTL1);
kdiv = FIELD_GET(KDIV_MASK, pll_div_ctl1);
kdiv = (s16)FIELD_GET(KDIV_MASK, pll_div_ctl1);
} else {
kdiv = 0;
}

View File

@ -6,6 +6,7 @@
#include <linux/clk-provider.h>
#include <linux/delay.h>
#include <linux/export.h>
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/slab.h>
@ -486,3 +487,4 @@ struct clk_hw *imx_clk_hw_pllv3(enum imx_pllv3_type type, const char *name,
return hw;
}
EXPORT_SYMBOL_GPL(imx_clk_hw_pllv3);

View File

@ -110,6 +110,20 @@ struct clk_hw *imx_obtain_fixed_clock_hw(
return __clk_get_hw(clk);
}
struct clk_hw *imx_obtain_fixed_of_clock(struct device_node *np,
const char *name, unsigned long rate)
{
struct clk *clk = of_clk_get_by_name(np, name);
struct clk_hw *hw;
if (IS_ERR(clk))
hw = imx_obtain_fixed_clock_hw(name, rate);
else
hw = __clk_get_hw(clk);
return hw;
}
struct clk_hw *imx_get_clk_hw_by_name(struct device_node *np, const char *name)
{
struct clk *clk;
@ -165,8 +179,10 @@ __setup_param("earlycon", imx_keep_uart_earlycon,
__setup_param("earlyprintk", imx_keep_uart_earlyprintk,
imx_keep_uart_clocks_param, 0);
void imx_register_uart_clocks(unsigned int clk_count)
void imx_register_uart_clocks(void)
{
unsigned int num __maybe_unused;
imx_enabled_uart_clocks = 0;
/* i.MX boards use device trees now. For build tests without CONFIG_OF, do nothing */
@ -174,14 +190,18 @@ void imx_register_uart_clocks(unsigned int clk_count)
if (imx_keep_uart_clocks) {
int i;
imx_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL);
if (!imx_uart_clocks)
num = of_clk_get_parent_count(of_stdout);
if (!num)
return;
if (!of_stdout)
return;
for (i = 0; i < clk_count; i++) {
imx_uart_clocks = kcalloc(num, sizeof(struct clk *), GFP_KERNEL);
if (!imx_uart_clocks)
return;
for (i = 0; i < num; i++) {
imx_uart_clocks[imx_enabled_uart_clocks] = of_clk_get(of_stdout, i);
/* Stop if there are no more of_stdout references */
@ -205,9 +225,10 @@ static int __init imx_clk_disable_uart(void)
clk_disable_unprepare(imx_uart_clocks[i]);
clk_put(imx_uart_clocks[i]);
}
kfree(imx_uart_clocks);
}
kfree(imx_uart_clocks);
return 0;
}
late_initcall_sync(imx_clk_disable_uart);

View File

@ -12,9 +12,9 @@ extern bool mcore_booted;
void imx_check_clocks(struct clk *clks[], unsigned int count);
void imx_check_clk_hws(struct clk_hw *clks[], unsigned int count);
#ifndef MODULE
void imx_register_uart_clocks(unsigned int clk_count);
void imx_register_uart_clocks(void);
#else
static inline void imx_register_uart_clocks(unsigned int clk_count)
static inline void imx_register_uart_clocks(void)
{
}
#endif
@ -288,6 +288,9 @@ struct clk * imx_obtain_fixed_clock(
struct clk_hw *imx_obtain_fixed_clock_hw(
const char *name, unsigned long rate);
struct clk_hw *imx_obtain_fixed_of_clock(struct device_node *np,
const char *name, unsigned long rate);
struct clk_hw *imx_get_clk_hw_by_name(struct device_node *np, const char *name);
struct clk_hw *imx_clk_hw_gate_exclusive(const char *name, const char *parent,
@ -458,4 +461,9 @@ struct clk_hw *imx_clk_hw_divider_gate(const char *name, const char *parent_name
unsigned long flags, void __iomem *reg, u8 shift, u8 width,
u8 clk_divider_flags, const struct clk_div_table *table,
spinlock_t *lock);
struct clk_hw *imx_clk_gpr_mux(const char *name, const char *compatible,
u32 reg, const char **parent_names,
u8 num_parents, const u32 *mux_table, u32 mask);
#endif

View File

@ -388,6 +388,23 @@ config COMMON_CLK_MT7629_HIFSYS
This driver supports MediaTek MT7629 HIFSYS clocks providing
to PCI-E and USB.
config COMMON_CLK_MT7981
bool "Clock driver for MediaTek MT7981"
depends on ARCH_MEDIATEK || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK
help
This driver supports MediaTek MT7981 basic clocks and clocks
required for various peripherals found on this SoC.
config COMMON_CLK_MT7981_ETHSYS
tristate "Clock driver for MediaTek MT7981 ETHSYS"
depends on COMMON_CLK_MT7981
default COMMON_CLK_MT7981
help
This driver adds support for clocks for Ethernet and SGMII
required on MediaTek MT7981 SoC.
config COMMON_CLK_MT7986
bool "Clock driver for MediaTek MT7986"
depends on ARCH_MEDIATEK || COMPILE_TEST
@ -457,19 +474,41 @@ config COMMON_CLK_MT8167_VDECSYS
This driver supports MediaTek MT8167 vdecsys clocks.
config COMMON_CLK_MT8173
bool "Clock driver for MediaTek MT8173"
depends on ARCH_MEDIATEK || COMPILE_TEST
tristate "Clock driver for MediaTek MT8173"
depends on ARM64 || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK
help
This driver supports MediaTek MT8173 clocks.
This driver supports MediaTek MT8173 basic clocks and clocks
required for various peripherals found on MediaTek.
config COMMON_CLK_MT8173_MMSYS
bool "Clock driver for MediaTek MT8173 mmsys"
config COMMON_CLK_MT8173_IMGSYS
tristate "Clock driver for MediaTek MT8173 imgsys"
depends on COMMON_CLK_MT8173
default COMMON_CLK_MT8173
help
This driver supports MediaTek MT8173 mmsys clocks.
This driver supports MediaTek MT8173 imgsys clocks.
config COMMON_CLK_MT8173_MMSYS
tristate "Clock driver for MediaTek MT8173 mmsys"
depends on COMMON_CLK_MT8173
default COMMON_CLK_MT8173
help
This driver supports MediaTek MT8173 mmsys clocks.
config COMMON_CLK_MT8173_VDECSYS
tristate "Clock driver for MediaTek MT8173 VDECSYS"
depends on COMMON_CLK_MT8173
default COMMON_CLK_MT8173
help
This driver supports MediaTek MT8173 vdecsys clocks.
config COMMON_CLK_MT8173_VENCSYS
tristate "Clock driver for MediaTek MT8173 VENCSYS"
depends on COMMON_CLK_MT8173
default COMMON_CLK_MT8173
help
This driver supports MediaTek MT8173 vencsys clocks.
config COMMON_CLK_MT8183
bool "Clock driver for MediaTek MT8183"

View File

@ -53,6 +53,10 @@ obj-$(CONFIG_COMMON_CLK_MT7622_AUDSYS) += clk-mt7622-aud.o
obj-$(CONFIG_COMMON_CLK_MT7629) += clk-mt7629.o
obj-$(CONFIG_COMMON_CLK_MT7629_ETHSYS) += clk-mt7629-eth.o
obj-$(CONFIG_COMMON_CLK_MT7629_HIFSYS) += clk-mt7629-hif.o
obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-apmixed.o
obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-topckgen.o
obj-$(CONFIG_COMMON_CLK_MT7981) += clk-mt7981-infracfg.o
obj-$(CONFIG_COMMON_CLK_MT7981_ETHSYS) += clk-mt7981-eth.o
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-apmixed.o
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-topckgen.o
obj-$(CONFIG_COMMON_CLK_MT7986) += clk-mt7986-infracfg.o
@ -64,8 +68,12 @@ obj-$(CONFIG_COMMON_CLK_MT8167_IMGSYS) += clk-mt8167-img.o
obj-$(CONFIG_COMMON_CLK_MT8167_MFGCFG) += clk-mt8167-mfgcfg.o
obj-$(CONFIG_COMMON_CLK_MT8167_MMSYS) += clk-mt8167-mm.o
obj-$(CONFIG_COMMON_CLK_MT8167_VDECSYS) += clk-mt8167-vdec.o
obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173.o
obj-$(CONFIG_COMMON_CLK_MT8173) += clk-mt8173-apmixedsys.o clk-mt8173-infracfg.o \
clk-mt8173-pericfg.o clk-mt8173-topckgen.o
obj-$(CONFIG_COMMON_CLK_MT8173_IMGSYS) += clk-mt8173-img.o
obj-$(CONFIG_COMMON_CLK_MT8173_MMSYS) += clk-mt8173-mm.o
obj-$(CONFIG_COMMON_CLK_MT8173_VDECSYS) += clk-mt8173-vdecsys.o
obj-$(CONFIG_COMMON_CLK_MT8173_VENCSYS) += clk-mt8173-vencsys.o
obj-$(CONFIG_COMMON_CLK_MT8183) += clk-mt8183.o
obj-$(CONFIG_COMMON_CLK_MT8183_AUDIOSYS) += clk-mt8183-audio.o
obj-$(CONFIG_COMMON_CLK_MT8183_CAMSYS) += clk-mt8183-cam.o

View File

@ -58,7 +58,7 @@ static const struct clk_ops clk_cpumux_ops = {
};
static struct clk_hw *
mtk_clk_register_cpumux(const struct mtk_composite *mux,
mtk_clk_register_cpumux(struct device *dev, const struct mtk_composite *mux,
struct regmap *regmap)
{
struct mtk_clk_cpumux *cpumux;
@ -81,7 +81,7 @@ mtk_clk_register_cpumux(const struct mtk_composite *mux,
cpumux->regmap = regmap;
cpumux->hw.init = &init;
ret = clk_hw_register(NULL, &cpumux->hw);
ret = clk_hw_register(dev, &cpumux->hw);
if (ret) {
kfree(cpumux);
return ERR_PTR(ret);
@ -102,7 +102,7 @@ static void mtk_clk_unregister_cpumux(struct clk_hw *hw)
kfree(cpumux);
}
int mtk_clk_register_cpumuxes(struct device_node *node,
int mtk_clk_register_cpumuxes(struct device *dev, struct device_node *node,
const struct mtk_composite *clks, int num,
struct clk_hw_onecell_data *clk_data)
{
@ -125,7 +125,7 @@ int mtk_clk_register_cpumuxes(struct device_node *node,
continue;
}
hw = mtk_clk_register_cpumux(mux, regmap);
hw = mtk_clk_register_cpumux(dev, mux, regmap);
if (IS_ERR(hw)) {
pr_err("Failed to register clk %s: %pe\n", mux->name,
hw);

View File

@ -11,7 +11,7 @@ struct clk_hw_onecell_data;
struct device_node;
struct mtk_composite;
int mtk_clk_register_cpumuxes(struct device_node *node,
int mtk_clk_register_cpumuxes(struct device *dev, struct device_node *node,
const struct mtk_composite *clks, int num,
struct clk_hw_onecell_data *clk_data);

View File

@ -152,12 +152,12 @@ const struct clk_ops mtk_clk_gate_ops_no_setclr_inv = {
};
EXPORT_SYMBOL_GPL(mtk_clk_gate_ops_no_setclr_inv);
static struct clk_hw *mtk_clk_register_gate(const char *name,
static struct clk_hw *mtk_clk_register_gate(struct device *dev, const char *name,
const char *parent_name,
struct regmap *regmap, int set_ofs,
int clr_ofs, int sta_ofs, u8 bit,
const struct clk_ops *ops,
unsigned long flags, struct device *dev)
unsigned long flags)
{
struct mtk_clk_gate *cg;
int ret;
@ -202,10 +202,9 @@ static void mtk_clk_unregister_gate(struct clk_hw *hw)
kfree(cg);
}
int mtk_clk_register_gates_with_dev(struct device_node *node,
const struct mtk_gate *clks, int num,
struct clk_hw_onecell_data *clk_data,
struct device *dev)
int mtk_clk_register_gates(struct device *dev, struct device_node *node,
const struct mtk_gate *clks, int num,
struct clk_hw_onecell_data *clk_data)
{
int i;
struct clk_hw *hw;
@ -229,13 +228,13 @@ int mtk_clk_register_gates_with_dev(struct device_node *node,
continue;
}
hw = mtk_clk_register_gate(gate->name, gate->parent_name,
hw = mtk_clk_register_gate(dev, gate->name, gate->parent_name,
regmap,
gate->regs->set_ofs,
gate->regs->clr_ofs,
gate->regs->sta_ofs,
gate->shift, gate->ops,
gate->flags, dev);
gate->flags);
if (IS_ERR(hw)) {
pr_err("Failed to register clk %s: %pe\n", gate->name,
@ -261,14 +260,6 @@ err:
return PTR_ERR(hw);
}
EXPORT_SYMBOL_GPL(mtk_clk_register_gates_with_dev);
int mtk_clk_register_gates(struct device_node *node,
const struct mtk_gate *clks, int num,
struct clk_hw_onecell_data *clk_data)
{
return mtk_clk_register_gates_with_dev(node, clks, num, clk_data, NULL);
}
EXPORT_SYMBOL_GPL(mtk_clk_register_gates);
void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,

View File

@ -50,15 +50,10 @@ struct mtk_gate {
#define GATE_MTK(_id, _name, _parent, _regs, _shift, _ops) \
GATE_MTK_FLAGS(_id, _name, _parent, _regs, _shift, _ops, 0)
int mtk_clk_register_gates(struct device_node *node,
int mtk_clk_register_gates(struct device *dev, struct device_node *node,
const struct mtk_gate *clks, int num,
struct clk_hw_onecell_data *clk_data);
int mtk_clk_register_gates_with_dev(struct device_node *node,
const struct mtk_gate *clks, int num,
struct clk_hw_onecell_data *clk_data,
struct device *dev);
void mtk_clk_unregister_gates(const struct mtk_gate *clks, int num,
struct clk_hw_onecell_data *clk_data);

View File

@ -76,6 +76,7 @@ static const struct mtk_gate_regs audio3_cg_regs = {
};
static const struct mtk_gate audio_clks[] = {
GATE_DUMMY(CLK_DUMMY, "aud_dummy"),
/* AUDIO0 */
GATE_AUDIO0(CLK_AUD_AFE, "audio_afe", "aud_intbus_sel", 2),
GATE_AUDIO0(CLK_AUD_HDMI, "audio_hdmi", "audpll_sel", 20),
@ -138,29 +139,27 @@ static const struct mtk_gate audio_clks[] = {
GATE_AUDIO3(CLK_AUD_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14),
};
static const struct mtk_clk_desc audio_desc = {
.clks = audio_clks,
.num_clks = ARRAY_SIZE(audio_clks),
};
static const struct of_device_id of_match_clk_mt2701_aud[] = {
{ .compatible = "mediatek,mt2701-audsys", },
{}
{ .compatible = "mediatek,mt2701-audsys", .data = &audio_desc },
{ /* sentinel */ }
};
static int clk_mt2701_aud_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
struct device_node *node = pdev->dev.of_node;
int r;
clk_data = mtk_alloc_clk_data(CLK_AUD_NR);
mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
r = mtk_clk_simple_probe(pdev);
if (r) {
dev_err(&pdev->dev,
"could not register clock provider: %s: %d\n",
pdev->name, r);
goto err_clk_provider;
return r;
}
r = devm_of_platform_populate(&pdev->dev);
@ -170,13 +169,19 @@ static int clk_mt2701_aud_probe(struct platform_device *pdev)
return 0;
err_plat_populate:
of_clk_del_provider(node);
err_clk_provider:
mtk_clk_simple_remove(pdev);
return r;
}
static int clk_mt2701_aud_remove(struct platform_device *pdev)
{
of_platform_depopulate(&pdev->dev);
return mtk_clk_simple_remove(pdev);
}
static struct platform_driver clk_mt2701_aud_drv = {
.probe = clk_mt2701_aud_probe,
.remove = clk_mt2701_aud_remove,
.driver = {
.name = "clk-mt2701-aud",
.of_match_table = of_match_clk_mt2701_aud,

View File

@ -26,6 +26,7 @@ static const struct mtk_gate_regs eth_cg_regs = {
}
static const struct mtk_gate eth_clks[] = {
GATE_DUMMY(CLK_DUMMY, "eth_dummy"),
GATE_ETH(CLK_ETHSYS_HSDMA, "hsdma_clk", "ethif_sel", 5),
GATE_ETH(CLK_ETHSYS_ESW, "esw_clk", "ethpll_500m_ck", 6),
GATE_ETH(CLK_ETHSYS_GP2, "gp2_clk", "trgpll", 7),
@ -44,35 +45,20 @@ static const struct mtk_clk_rst_desc clk_rst_desc = {
.rst_bank_nr = ARRAY_SIZE(rst_ofs),
};
static const struct of_device_id of_match_clk_mt2701_eth[] = {
{ .compatible = "mediatek,mt2701-ethsys", },
{}
static const struct mtk_clk_desc eth_desc = {
.clks = eth_clks,
.num_clks = ARRAY_SIZE(eth_clks),
.rst_desc = &clk_rst_desc,
};
static int clk_mt2701_eth_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
int r;
struct device_node *node = pdev->dev.of_node;
clk_data = mtk_alloc_clk_data(CLK_ETHSYS_NR);
mtk_clk_register_gates(node, eth_clks, ARRAY_SIZE(eth_clks),
clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)
dev_err(&pdev->dev,
"could not register clock provider: %s: %d\n",
pdev->name, r);
mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
return r;
}
static const struct of_device_id of_match_clk_mt2701_eth[] = {
{ .compatible = "mediatek,mt2701-ethsys", .data = &eth_desc },
{ /* sentinel */ }
};
static struct platform_driver clk_mt2701_eth_drv = {
.probe = clk_mt2701_eth_probe,
.probe = mtk_clk_simple_probe,
.remove = mtk_clk_simple_remove,
.driver = {
.name = "clk-mt2701-eth",
.of_match_table = of_match_clk_mt2701_eth,

View File

@ -32,6 +32,7 @@ static const struct mtk_gate_regs g3d_cg_regs = {
};
static const struct mtk_gate g3d_clks[] = {
GATE_DUMMY(CLK_DUMMY, "g3d_dummy"),
GATE_G3D(CLK_G3DSYS_CORE, "g3d_core", "mfg_sel", 0),
};
@ -43,57 +44,20 @@ static const struct mtk_clk_rst_desc clk_rst_desc = {
.rst_bank_nr = ARRAY_SIZE(rst_ofs),
};
static int clk_mt2701_g3dsys_init(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
struct device_node *node = pdev->dev.of_node;
int r;
clk_data = mtk_alloc_clk_data(CLK_G3DSYS_NR);
mtk_clk_register_gates(node, g3d_clks, ARRAY_SIZE(g3d_clks),
clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)
dev_err(&pdev->dev,
"could not register clock provider: %s: %d\n",
pdev->name, r);
mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
return r;
}
static const struct of_device_id of_match_clk_mt2701_g3d[] = {
{
.compatible = "mediatek,mt2701-g3dsys",
.data = clk_mt2701_g3dsys_init,
}, {
/* sentinel */
}
static const struct mtk_clk_desc g3d_desc = {
.clks = g3d_clks,
.num_clks = ARRAY_SIZE(g3d_clks),
.rst_desc = &clk_rst_desc,
};
static int clk_mt2701_g3d_probe(struct platform_device *pdev)
{
int (*clk_init)(struct platform_device *);
int r;
clk_init = of_device_get_match_data(&pdev->dev);
if (!clk_init)
return -EINVAL;
r = clk_init(pdev);
if (r)
dev_err(&pdev->dev,
"could not register clock provider: %s: %d\n",
pdev->name, r);
return r;
}
static const struct of_device_id of_match_clk_mt2701_g3d[] = {
{ .compatible = "mediatek,mt2701-g3dsys", .data = &g3d_desc },
{ /* sentinel */ }
};
static struct platform_driver clk_mt2701_g3d_drv = {
.probe = clk_mt2701_g3d_probe,
.probe = mtk_clk_simple_probe,
.remove = mtk_clk_simple_remove,
.driver = {
.name = "clk-mt2701-g3d",
.of_match_table = of_match_clk_mt2701_g3d,

View File

@ -26,6 +26,7 @@ static const struct mtk_gate_regs hif_cg_regs = {
}
static const struct mtk_gate hif_clks[] = {
GATE_DUMMY(CLK_DUMMY, "hif_dummy"),
GATE_HIF(CLK_HIFSYS_USB0PHY, "usb0_phy_clk", "ethpll_500m_ck", 21),
GATE_HIF(CLK_HIFSYS_USB1PHY, "usb1_phy_clk", "ethpll_500m_ck", 22),
GATE_HIF(CLK_HIFSYS_PCIE0, "pcie0_clk", "ethpll_500m_ck", 24),
@ -41,37 +42,20 @@ static const struct mtk_clk_rst_desc clk_rst_desc = {
.rst_bank_nr = ARRAY_SIZE(rst_ofs),
};
static const struct of_device_id of_match_clk_mt2701_hif[] = {
{ .compatible = "mediatek,mt2701-hifsys", },
{}
static const struct mtk_clk_desc hif_desc = {
.clks = hif_clks,
.num_clks = ARRAY_SIZE(hif_clks),
.rst_desc = &clk_rst_desc,
};
static int clk_mt2701_hif_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
int r;
struct device_node *node = pdev->dev.of_node;
clk_data = mtk_alloc_clk_data(CLK_HIFSYS_NR);
mtk_clk_register_gates(node, hif_clks, ARRAY_SIZE(hif_clks),
clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r) {
dev_err(&pdev->dev,
"could not register clock provider: %s: %d\n",
pdev->name, r);
return r;
}
mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc);
return 0;
}
static const struct of_device_id of_match_clk_mt2701_hif[] = {
{ .compatible = "mediatek,mt2701-hifsys", .data = &hif_desc },
{ /* sentinel */ }
};
static struct platform_driver clk_mt2701_hif_drv = {
.probe = clk_mt2701_hif_probe,
.probe = mtk_clk_simple_probe,
.remove = mtk_clk_simple_remove,
.driver = {
.name = "clk-mt2701-hif",
.of_match_table = of_match_clk_mt2701_hif,

View File

@ -88,8 +88,8 @@ static int clk_mt2701_mm_probe(struct platform_device *pdev)
clk_data = mtk_alloc_clk_data(CLK_MM_NR);
mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, mm_clks,
ARRAY_SIZE(mm_clks), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)

View File

@ -683,14 +683,15 @@ static int mtk_topckgen_init(struct platform_device *pdev)
mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
clk_data);
mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes),
base, &mt2701_clk_lock, clk_data);
mtk_clk_register_composites(&pdev->dev, top_muxes,
ARRAY_SIZE(top_muxes), base,
&mt2701_clk_lock, clk_data);
mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs),
base, &mt2701_clk_lock, clk_data);
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, top_clks,
ARRAY_SIZE(top_clks), clk_data);
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
}
@ -769,7 +770,7 @@ static void __init mtk_infrasys_init_early(struct device_node *node)
mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
infra_clk_data);
mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
mtk_clk_register_cpumuxes(NULL, node, cpu_muxes, ARRAY_SIZE(cpu_muxes),
infra_clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get,
@ -795,8 +796,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
}
}
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
infra_clk_data);
mtk_clk_register_gates(&pdev->dev, node, infra_clks,
ARRAY_SIZE(infra_clks), infra_clk_data);
mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
infra_clk_data);
@ -918,11 +919,12 @@ static int mtk_pericfg_init(struct platform_device *pdev)
clk_data = mtk_alloc_clk_data(CLK_PERI_NR);
mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, peri_clks,
ARRAY_SIZE(peri_clks), clk_data);
mtk_clk_register_composites(peri_muxs, ARRAY_SIZE(peri_muxs), base,
&mt2701_clk_lock, clk_data);
mtk_clk_register_composites(&pdev->dev, peri_muxs,
ARRAY_SIZE(peri_muxs), base,
&mt2701_clk_lock, clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)

View File

@ -135,8 +135,8 @@ static int clk_mt2712_mm_probe(struct platform_device *pdev)
clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, mm_clks,
ARRAY_SIZE(mm_clks), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);

View File

@ -1346,12 +1346,13 @@ static int clk_mt2712_top_probe(struct platform_device *pdev)
mtk_clk_register_factors(top_early_divs, ARRAY_SIZE(top_early_divs),
top_clk_data);
mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), top_clk_data);
mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
&mt2712_clk_lock, top_clk_data);
mtk_clk_register_composites(&pdev->dev, top_muxes,
ARRAY_SIZE(top_muxes), base,
&mt2712_clk_lock, top_clk_data);
mtk_clk_register_dividers(top_adj_divs, ARRAY_SIZE(top_adj_divs), base,
&mt2712_clk_lock, top_clk_data);
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
top_clk_data);
mtk_clk_register_gates(&pdev->dev, node, top_clks,
ARRAY_SIZE(top_clks), top_clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, top_clk_data);
@ -1362,50 +1363,6 @@ static int clk_mt2712_top_probe(struct platform_device *pdev)
return r;
}
static int clk_mt2712_infra_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
int r;
struct device_node *node = pdev->dev.of_node;
clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r != 0)
pr_err("%s(): could not register clock provider: %d\n",
__func__, r);
mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc[0]);
return r;
}
static int clk_mt2712_peri_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
int r;
struct device_node *node = pdev->dev.of_node;
clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
mtk_clk_register_gates(node, peri_clks, ARRAY_SIZE(peri_clks),
clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r != 0)
pr_err("%s(): could not register clock provider: %d\n",
__func__, r);
mtk_register_reset_controller_with_dev(&pdev->dev, &clk_rst_desc[1]);
return r;
}
static int clk_mt2712_mcu_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
@ -1421,8 +1378,11 @@ static int clk_mt2712_mcu_probe(struct platform_device *pdev)
clk_data = mtk_alloc_clk_data(CLK_MCU_NR_CLK);
mtk_clk_register_composites(mcu_muxes, ARRAY_SIZE(mcu_muxes), base,
&mt2712_clk_lock, clk_data);
r = mtk_clk_register_composites(&pdev->dev, mcu_muxes,
ARRAY_SIZE(mcu_muxes), base,
&mt2712_clk_lock, clk_data);
if (r)
dev_err(&pdev->dev, "Could not register composites: %d\n", r);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
@ -1440,12 +1400,6 @@ static const struct of_device_id of_match_clk_mt2712[] = {
}, {
.compatible = "mediatek,mt2712-topckgen",
.data = clk_mt2712_top_probe,
}, {
.compatible = "mediatek,mt2712-infracfg",
.data = clk_mt2712_infra_probe,
}, {
.compatible = "mediatek,mt2712-pericfg",
.data = clk_mt2712_peri_probe,
}, {
.compatible = "mediatek,mt2712-mcucfg",
.data = clk_mt2712_mcu_probe,
@ -1472,6 +1426,33 @@ static int clk_mt2712_probe(struct platform_device *pdev)
return r;
}
static const struct mtk_clk_desc infra_desc = {
.clks = infra_clks,
.num_clks = ARRAY_SIZE(infra_clks),
.rst_desc = &clk_rst_desc[0],
};
static const struct mtk_clk_desc peri_desc = {
.clks = peri_clks,
.num_clks = ARRAY_SIZE(peri_clks),
.rst_desc = &clk_rst_desc[1],
};
static const struct of_device_id of_match_clk_mt2712_simple[] = {
{ .compatible = "mediatek,mt2712-infracfg", .data = &infra_desc },
{ .compatible = "mediatek,mt2712-pericfg", .data = &peri_desc, },
{ /* sentinel */ }
};
static struct platform_driver clk_mt2712_simple_drv = {
.probe = mtk_clk_simple_probe,
.remove = mtk_clk_simple_remove,
.driver = {
.name = "clk-mt2712-simple",
.of_match_table = of_match_clk_mt2712_simple,
},
};
static struct platform_driver clk_mt2712_drv = {
.probe = clk_mt2712_probe,
.driver = {
@ -1482,7 +1463,11 @@ static struct platform_driver clk_mt2712_drv = {
static int __init clk_mt2712_init(void)
{
return platform_driver_register(&clk_mt2712_drv);
int ret = platform_driver_register(&clk_mt2712_drv);
if (ret)
return ret;
return platform_driver_register(&clk_mt2712_simple_drv);
}
arch_initcall(clk_mt2712_init);

View File

@ -789,7 +789,7 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev)
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_gates(node, apmixed_clks,
mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,
ARRAY_SIZE(apmixed_clks), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
@ -826,10 +826,11 @@ static int clk_mt6765_top_probe(struct platform_device *pdev)
clk_data);
mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs),
clk_data);
mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
mtk_clk_register_muxes(&pdev->dev, top_muxes,
ARRAY_SIZE(top_muxes), node,
&mt6765_clk_lock, clk_data);
mtk_clk_register_gates(node, top_clks, ARRAY_SIZE(top_clks),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, top_clks,
ARRAY_SIZE(top_clks), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
@ -862,8 +863,8 @@ static int clk_mt6765_ifr_probe(struct platform_device *pdev)
clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
mtk_clk_register_gates(node, ifr_clks, ARRAY_SIZE(ifr_clks),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, ifr_clks,
ARRAY_SIZE(ifr_clks), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)

View File

@ -93,8 +93,8 @@ static int clk_mt6779_mm_probe(struct platform_device *pdev)
clk_data = mtk_alloc_clk_data(CLK_MM_NR_CLK);
mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, mm_clks,
ARRAY_SIZE(mm_clks), clk_data);
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
}

View File

@ -880,6 +880,7 @@ static const struct mtk_gate_regs infra3_cg_regs = {
&mtk_clk_gate_ops_setclr)
static const struct mtk_gate infra_clks[] = {
GATE_DUMMY(CLK_DUMMY, "ifa_dummy"),
/* INFRA0 */
GATE_INFRA0(CLK_INFRA_PMIC_TMR, "infra_pmic_tmr",
"axi_sel", 0),
@ -1221,7 +1222,7 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev)
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
mtk_clk_register_gates(node, apmixed_clks,
mtk_clk_register_gates(&pdev->dev, node, apmixed_clks,
ARRAY_SIZE(apmixed_clks), clk_data);
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
@ -1244,27 +1245,17 @@ static int clk_mt6779_top_probe(struct platform_device *pdev)
mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes),
node, &mt6779_clk_lock, clk_data);
mtk_clk_register_muxes(&pdev->dev, top_muxes,
ARRAY_SIZE(top_muxes), node,
&mt6779_clk_lock, clk_data);
mtk_clk_register_composites(top_aud_muxes, ARRAY_SIZE(top_aud_muxes),
base, &mt6779_clk_lock, clk_data);
mtk_clk_register_composites(&pdev->dev, top_aud_muxes,
ARRAY_SIZE(top_aud_muxes), base,
&mt6779_clk_lock, clk_data);
mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs),
base, &mt6779_clk_lock, clk_data);
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
}
static int clk_mt6779_infra_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
struct device_node *node = pdev->dev.of_node;
clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
clk_data);
mtk_clk_register_composites(&pdev->dev, top_aud_divs,
ARRAY_SIZE(top_aud_divs), base,
&mt6779_clk_lock, clk_data);
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
}
@ -1276,9 +1267,6 @@ static const struct of_device_id of_match_clk_mt6779[] = {
}, {
.compatible = "mediatek,mt6779-topckgen",
.data = clk_mt6779_top_probe,
}, {
.compatible = "mediatek,mt6779-infracfg_ao",
.data = clk_mt6779_infra_probe,
}, {
/* sentinel */
}
@ -1302,6 +1290,25 @@ static int clk_mt6779_probe(struct platform_device *pdev)
return r;
}
static const struct mtk_clk_desc infra_desc = {
.clks = infra_clks,
.num_clks = ARRAY_SIZE(infra_clks),
};
static const struct of_device_id of_match_clk_mt6779_infra[] = {
{ .compatible = "mediatek,mt6779-infracfg_ao", .data = &infra_desc },
{ /* sentinel */ }
};
static struct platform_driver clk_mt6779_infra_drv = {
.probe = mtk_clk_simple_probe,
.remove = mtk_clk_simple_remove,
.driver = {
.name = "clk-mt6779-infra",
.of_match_table = of_match_clk_mt6779_infra,
},
};
static struct platform_driver clk_mt6779_drv = {
.probe = clk_mt6779_probe,
.driver = {
@ -1312,7 +1319,11 @@ static struct platform_driver clk_mt6779_drv = {
static int __init clk_mt6779_init(void)
{
return platform_driver_register(&clk_mt6779_drv);
int ret = platform_driver_register(&clk_mt6779_drv);
if (ret)
return ret;
return platform_driver_register(&clk_mt6779_infra_drv);
}
arch_initcall(clk_mt6779_init);

View File

@ -101,11 +101,13 @@ static int clk_mt6795_infracfg_probe(struct platform_device *pdev)
if (ret)
goto free_clk_data;
ret = mtk_clk_register_gates(node, infra_gates, ARRAY_SIZE(infra_gates), clk_data);
ret = mtk_clk_register_gates(&pdev->dev, node, infra_gates,
ARRAY_SIZE(infra_gates), clk_data);
if (ret)
goto free_clk_data;
ret = mtk_clk_register_cpumuxes(node, cpu_muxes, ARRAY_SIZE(cpu_muxes), clk_data);
ret = mtk_clk_register_cpumuxes(&pdev->dev, node, cpu_muxes,
ARRAY_SIZE(cpu_muxes), clk_data);
if (ret)
goto unregister_gates;

View File

@ -87,7 +87,8 @@ static int clk_mt6795_mm_probe(struct platform_device *pdev)
if (!clk_data)
return -ENOMEM;
ret = mtk_clk_register_gates(node, mm_gates, ARRAY_SIZE(mm_gates), clk_data);
ret = mtk_clk_register_gates(&pdev->dev, node, mm_gates,
ARRAY_SIZE(mm_gates), clk_data);
if (ret)
goto free_clk_data;

View File

@ -109,11 +109,13 @@ static int clk_mt6795_pericfg_probe(struct platform_device *pdev)
if (ret)
goto free_clk_data;
ret = mtk_clk_register_gates(node, peri_gates, ARRAY_SIZE(peri_gates), clk_data);
ret = mtk_clk_register_gates(&pdev->dev, node, peri_gates,
ARRAY_SIZE(peri_gates), clk_data);
if (ret)
goto free_clk_data;
ret = mtk_clk_register_composites(peri_clks, ARRAY_SIZE(peri_clks), base,
ret = mtk_clk_register_composites(&pdev->dev, peri_clks,
ARRAY_SIZE(peri_clks), base,
&mt6795_peri_clk_lock, clk_data);
if (ret)
goto unregister_gates;

View File

@ -523,86 +523,30 @@ static struct mtk_composite top_aud_divs[] = {
DIV_GATE(CLK_TOP_APLL2_DIV5, "apll2_div5", "apll2_div4", 0x12c, 21, 0x12c, 4, 4),
};
static const struct of_device_id of_match_clk_mt6795_topckgen[] = {
{ .compatible = "mediatek,mt6795-topckgen" },
{ /* sentinel */ }
static const struct mtk_clk_desc topck_desc = {
.fixed_clks = fixed_clks,
.num_fixed_clks = ARRAY_SIZE(fixed_clks),
.factor_clks = top_divs,
.num_factor_clks = ARRAY_SIZE(top_divs),
.mux_clks = top_muxes,
.num_mux_clks = ARRAY_SIZE(top_muxes),
.composite_clks = top_aud_divs,
.num_composite_clks = ARRAY_SIZE(top_aud_divs),
.clk_lock = &mt6795_top_clk_lock,
};
static int clk_mt6795_topckgen_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
struct device_node *node = pdev->dev.of_node;
void __iomem *base;
int ret;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
if (!clk_data)
return -ENOMEM;
ret = mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
if (ret)
goto free_clk_data;
ret = mtk_clk_register_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
if (ret)
goto unregister_fixed_clks;
ret = mtk_clk_register_muxes(top_muxes, ARRAY_SIZE(top_muxes), node,
&mt6795_top_clk_lock, clk_data);
if (ret)
goto unregister_factors;
ret = mtk_clk_register_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs), base,
&mt6795_top_clk_lock, clk_data);
if (ret)
goto unregister_muxes;
ret = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (ret)
goto unregister_composites;
return 0;
unregister_composites:
mtk_clk_unregister_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs), clk_data);
unregister_muxes:
mtk_clk_unregister_muxes(top_muxes, ARRAY_SIZE(top_muxes), clk_data);
unregister_factors:
mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
unregister_fixed_clks:
mtk_clk_unregister_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
free_clk_data:
mtk_free_clk_data(clk_data);
return ret;
}
static int clk_mt6795_topckgen_remove(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
struct clk_hw_onecell_data *clk_data = platform_get_drvdata(pdev);
of_clk_del_provider(node);
mtk_clk_unregister_composites(top_aud_divs, ARRAY_SIZE(top_aud_divs), clk_data);
mtk_clk_unregister_muxes(top_muxes, ARRAY_SIZE(top_muxes), clk_data);
mtk_clk_unregister_factors(top_divs, ARRAY_SIZE(top_divs), clk_data);
mtk_clk_unregister_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks), clk_data);
mtk_free_clk_data(clk_data);
return 0;
}
static const struct of_device_id of_match_clk_mt6795_topckgen[] = {
{ .compatible = "mediatek,mt6795-topckgen", .data = &topck_desc },
{ /* sentinel */ }
};
static struct platform_driver clk_mt6795_topckgen_drv = {
.driver = {
.name = "clk-mt6795-topckgen",
.of_match_table = of_match_clk_mt6795_topckgen,
},
.probe = clk_mt6795_topckgen_probe,
.remove = clk_mt6795_topckgen_remove,
.probe = mtk_clk_simple_probe,
.remove = mtk_clk_simple_remove,
};
module_platform_driver(clk_mt6795_topckgen_drv);

View File

@ -101,8 +101,8 @@ static int clk_mt6797_mm_probe(struct platform_device *pdev)
clk_data = mtk_alloc_clk_data(CLK_MM_NR);
mtk_clk_register_gates(node, mm_clks, ARRAY_SIZE(mm_clks),
clk_data);
mtk_clk_register_gates(&pdev->dev, node, mm_clks,
ARRAY_SIZE(mm_clks), clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)

View File

@ -396,7 +396,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)
mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
clk_data);
mtk_clk_register_composites(top_muxes, ARRAY_SIZE(top_muxes), base,
mtk_clk_register_composites(&pdev->dev, top_muxes,
ARRAY_SIZE(top_muxes), base,
&mt6797_clk_lock, clk_data);
return of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
@ -596,8 +597,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
}
}
mtk_clk_register_gates(node, infra_clks, ARRAY_SIZE(infra_clks),
infra_clk_data);
mtk_clk_register_gates(&pdev->dev, node, infra_clks,
ARRAY_SIZE(infra_clks), infra_clk_data);
mtk_clk_register_factors(infra_fixed_divs, ARRAY_SIZE(infra_fixed_divs),
infra_clk_data);

View File

@ -130,24 +130,22 @@ static const struct mtk_gate audio_clks[] = {
GATE_AUDIO3(CLK_AUDIO_MEM_ASRC5, "audio_mem_asrc5", "asm_h_sel", 14),
};
static int clk_mt7622_audiosys_init(struct platform_device *pdev)
static const struct mtk_clk_desc audio_desc = {
.clks = audio_clks,
.num_clks = ARRAY_SIZE(audio_clks),
};
static int clk_mt7622_aud_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
struct device_node *node = pdev->dev.of_node;
int r;
clk_data = mtk_alloc_clk_data(CLK_AUDIO_NR_CLK);
mtk_clk_register_gates(node, audio_clks, ARRAY_SIZE(audio_clks),
clk_data);
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
r = mtk_clk_simple_probe(pdev);
if (r) {
dev_err(&pdev->dev,
"could not register clock provider: %s: %d\n",
pdev->name, r);
goto err_clk_provider;
return r;
}
r = devm_of_platform_populate(&pdev->dev);
@ -157,40 +155,24 @@ static int clk_mt7622_audiosys_init(struct platform_device *pdev)
return 0;
err_plat_populate:
of_clk_del_provider(node);
err_clk_provider:
mtk_clk_simple_remove(pdev);
return r;
}
static int clk_mt7622_aud_remove(struct platform_device *pdev)
{
of_platform_depopulate(&pdev->dev);
return mtk_clk_simple_remove(pdev);
}
static const struct of_device_id of_match_clk_mt7622_aud[] = {
{
.compatible = "mediatek,mt7622-audsys",
.data = clk_mt7622_audiosys_init,
}, {
/* sentinel */
}
{ .compatible = "mediatek,mt7622-audsys", .data = &audio_desc },
{ /* sentinel */ }
};
static int clk_mt7622_aud_probe(struct platform_device *pdev)
{
int (*clk_init)(struct platform_device *);
int r;
clk_init = of_device_get_match_data(&pdev->dev);
if (!clk_init)
return -EINVAL;
r = clk_init(pdev);
if (r)
dev_err(&pdev->dev,
"could not register clock provider: %s: %d\n",
pdev->name, r);
return r;
}
static struct platform_driver clk_mt7622_aud_drv = {
.probe = clk_mt7622_aud_probe,
.remove = clk_mt7622_aud_remove,
.driver = {
.name = "clk-mt7622-aud",
.of_match_table = of_match_clk_mt7622_aud,

Some files were not shown because too many files have changed in this diff Show More