Commit c736c9a9 authored by Linus Torvalds's avatar Linus Torvalds

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

Pull clk updates from Stephen Boyd:
 "Only a couple new SoCs have support added this time, primarily for
  Qualcomm SM8650 based on the diffstat. Otherwise this is a collection
  of non-critical fixes and cleanups to various clk drivers and their DT
  bindings.

  Nothing is changed in the core clk framework this time, although
  there's a patch to fix a basic clk type initialization function. In
  general, this pile looks to be on the smaller side.

  New Drivers:
   - Global, display, gpu, tcsr, and rpmh clocks on Qualcomm SM8650
   - Mediatek MT7988 SoC clocks

  Updates:
   - Update Zynqmp driver for Versal NET platforms
   - Add clk driver for Versal clocking wizard IP
   - Support for stm32mp25 clks
   - Add glitch free PLL setting support to si5351 clk driver
   - Add DSI clocks on Amlogic g12/sm1
   - Add CSI and ISP clocks on Amlogic g12/sm1
   - Document bindings for i.MX93 ANATOP clock driver
   - Free clk_node in i.MX SCU driver for resource with different owner
   - Update the LVDS clocks to be compatible with i.MX SCU firmware 1.15
   - Fix the name of the fvco in i.MX pll14xx by renaming it to fout
   - Add EtherNet TSN and PCIe clocks on the Renesas R-Car V4H SoC
   - Add interrupt controller and Ethernet clocks and resets on Renesas
     RZ/G3S
   - Check reset monitor registers on Renesas RZ/G2L-alike SoCs
   - Reuse reset functionality in the Renesas RZ/G2L clock driver
   - Global and RPMh clock support for the Qualcomm X1E80100 SoC
   - Support for the Stromer APCS PLL found in Qualcomm IPQ5018
   - Add a new type of branch clock, with support for controlling
     separate memory control bits, to the Qualcomm clk driver
   - Use above new branch type in Qualcomm ECPRI clk driver for QDU1000
     and QRU1000
   - Add a number of missing clocks related to CSI2 on Qualcomm MSM8939
   - Add support for the camera clock controller on Qualcomm SC8280XP
   - Correct PLL configuration in GPU and video clock controllers for
     Qualcomm SM8150
   - Add runtime PM support and a few missing resets to Qualcomm SM8150
     video clock controller
   - Fix configuration of various GCC GDSCs on Qualcomm SM8550
   - Mark shared RCGs appropriately in the Qualcomm SM8550 GCC driver
   - Fix up GPU and display clock controllers PLL configuration settings
     on Qualcomm SM8550
   - Cleanup variable init in Allwinner nkm module
   - Convert various DT bindings to YAML
   - A few kernel-doc fixes for Samsung SoC clock controllers"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (93 commits)
  clk: mediatek: add drivers for MT7988 SoC
  clk: mediatek: add pcw_chg_bit control for PLLs of MT7988
  dt-bindings: clock: mediatek: add clock controllers of MT7988
  dt-bindings: reset: mediatek: add MT7988 ethwarp reset IDs
  dt-bindings: clock: mediatek: add MT7988 clock IDs
  clk: mediatek: mt8188-topckgen: Refactor parents for top_dp/edp muxes
  clk: mediatek: mt8195-topckgen: Refactor parents for top_dp/edp muxes
  clk: mediatek: clk-mux: Support custom parent indices for muxes
  dt-bindings: clock: sophgo: Add clock controller of CV1800 series SoC
  clk: starfive: jh7100: Add CLK_SET_RATE_PARENT to gmac_tx
  clk: starfive: Add flags argument to JH71X0__MUX macro
  clk: imx: pll14xx: change naming of fvco to fout
  clk: imx: clk-imx8qxp: fix LVDS bypass, pixel and phy clocks
  clk: imx: scu: Fix memory leak in __imx_clk_gpr_scu()
  clk: fixed-rate: fix clk_hw_register_fixed_rate_with_accuracy_parent_hw
  clk: qcom: dispcc-sm8650: Add test_ctl parameters to PLL config
  clk: qcom: gpucc-sm8650: Add test_ctl parameters to PLL config
  clk: qcom: dispcc-sm8550: Use the correct PLL configuration function
  clk: qcom: dispcc-sm8550: Update disp PLL settings
  clk: qcom: gpucc-sm8550: Update GPU PLL settings
  ...
parents 576db734 4f964cfe
Mediatek ethsys controller
============================
The Mediatek ethsys controller provides various clocks to the system.
Required Properties:
- compatible: Should be:
- "mediatek,mt2701-ethsys", "syscon"
- "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
The ethsys controller uses the common clk binding from
Documentation/devicetree/bindings/clock/clock-bindings.txt
The available clocks are defined in dt-bindings/clock/mt*-clk.h.
Example:
ethsys: clock-controller@1b000000 {
compatible = "mediatek,mt2701-ethsys", "syscon";
reg = <0 0x1b000000 0 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
......@@ -30,6 +30,7 @@ properties:
- mediatek,mt7629-infracfg
- mediatek,mt7981-infracfg
- mediatek,mt7986-infracfg
- mediatek,mt7988-infracfg
- mediatek,mt8135-infracfg
- mediatek,mt8167-infracfg
- mediatek,mt8173-infracfg
......
Broadcom Kona Family Clocks
This binding is associated with Broadcom SoCs having "Kona" style
clock control units (CCUs). A CCU is a clock provider that manages
a set of clock signals. Each CCU is represented by a node in the
device tree.
This binding uses the common clock binding:
Documentation/devicetree/bindings/clock/clock-bindings.txt
Required properties:
- compatible
Shall have a value of the form "brcm,<model>-<which>-ccu",
where <model> is a Broadcom SoC model number and <which> is
the name of a defined CCU. For example:
"brcm,bcm11351-root-ccu"
The compatible strings used for each supported SoC family
are defined below.
- reg
Shall define the base and range of the address space
containing clock control registers
- #clock-cells
Shall have value <1>. The permitted clock-specifier values
are defined below.
- clock-output-names
Shall be an ordered list of strings defining the names of
the clocks provided by the CCU.
Device tree example:
slave_ccu: slave_ccu {
compatible = "brcm,bcm11351-slave-ccu";
reg = <0x3e011000 0x0f00>;
#clock-cells = <1>;
clock-output-names = "uartb",
"uartb2",
"uartb3",
"uartb4";
};
ref_crystal_clk: ref_crystal {
#clock-cells = <0>;
compatible = "fixed-clock";
clock-frequency = <26000000>;
};
uart@3e002000 {
compatible = "brcm,bcm11351-dw-apb-uart", "snps,dw-apb-uart";
reg = <0x3e002000 0x1000>;
clocks = <&slave_ccu BCM281XX_SLAVE_CCU_UARTB3>;
interrupts = <GIC_SPI 65 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
reg-io-width = <4>;
};
BCM281XX family
---------------
CCU compatible string values for SoCs in the BCM281XX family are:
"brcm,bcm11351-root-ccu"
"brcm,bcm11351-aon-ccu"
"brcm,bcm11351-hub-ccu"
"brcm,bcm11351-master-ccu"
"brcm,bcm11351-slave-ccu"
The following table defines the set of CCUs and clock specifiers for
BCM281XX family clocks. When a clock consumer references a clocks,
its symbolic specifier (rather than its numeric index value) should
be used. These specifiers are defined in:
"include/dt-bindings/clock/bcm281xx.h"
CCU Clock Type Index Specifier
--- ----- ---- ----- ---------
root frac_1m peri 0 BCM281XX_ROOT_CCU_FRAC_1M
aon hub_timer peri 0 BCM281XX_AON_CCU_HUB_TIMER
aon pmu_bsc peri 1 BCM281XX_AON_CCU_PMU_BSC
aon pmu_bsc_var peri 2 BCM281XX_AON_CCU_PMU_BSC_VAR
hub tmon_1m peri 0 BCM281XX_HUB_CCU_TMON_1M
master sdio1 peri 0 BCM281XX_MASTER_CCU_SDIO1
master sdio2 peri 1 BCM281XX_MASTER_CCU_SDIO2
master sdio3 peri 2 BCM281XX_MASTER_CCU_SDIO3
master sdio4 peri 3 BCM281XX_MASTER_CCU_SDIO4
master dmac peri 4 BCM281XX_MASTER_CCU_DMAC
master usb_ic peri 5 BCM281XX_MASTER_CCU_USB_IC
master hsic2_48m peri 6 BCM281XX_MASTER_CCU_HSIC_48M
master hsic2_12m peri 7 BCM281XX_MASTER_CCU_HSIC_12M
slave uartb peri 0 BCM281XX_SLAVE_CCU_UARTB
slave uartb2 peri 1 BCM281XX_SLAVE_CCU_UARTB2
slave uartb3 peri 2 BCM281XX_SLAVE_CCU_UARTB3
slave uartb4 peri 3 BCM281XX_SLAVE_CCU_UARTB4
slave ssp0 peri 4 BCM281XX_SLAVE_CCU_SSP0
slave ssp2 peri 5 BCM281XX_SLAVE_CCU_SSP2
slave bsc1 peri 6 BCM281XX_SLAVE_CCU_BSC1
slave bsc2 peri 7 BCM281XX_SLAVE_CCU_BSC2
slave bsc3 peri 8 BCM281XX_SLAVE_CCU_BSC3
slave pwm peri 9 BCM281XX_SLAVE_CCU_PWM
BCM21664 family
---------------
CCU compatible string values for SoCs in the BCM21664 family are:
"brcm,bcm21664-root-ccu"
"brcm,bcm21664-aon-ccu"
"brcm,bcm21664-master-ccu"
"brcm,bcm21664-slave-ccu"
The following table defines the set of CCUs and clock specifiers for
BCM21664 family clocks. When a clock consumer references a clocks,
its symbolic specifier (rather than its numeric index value) should
be used. These specifiers are defined in:
"include/dt-bindings/clock/bcm21664.h"
CCU Clock Type Index Specifier
--- ----- ---- ----- ---------
root frac_1m peri 0 BCM21664_ROOT_CCU_FRAC_1M
aon hub_timer peri 0 BCM21664_AON_CCU_HUB_TIMER
master sdio1 peri 0 BCM21664_MASTER_CCU_SDIO1
master sdio2 peri 1 BCM21664_MASTER_CCU_SDIO2
master sdio3 peri 2 BCM21664_MASTER_CCU_SDIO3
master sdio4 peri 3 BCM21664_MASTER_CCU_SDIO4
master sdio1_sleep peri 4 BCM21664_MASTER_CCU_SDIO1_SLEEP
master sdio2_sleep peri 5 BCM21664_MASTER_CCU_SDIO2_SLEEP
master sdio3_sleep peri 6 BCM21664_MASTER_CCU_SDIO3_SLEEP
master sdio4_sleep peri 7 BCM21664_MASTER_CCU_SDIO4_SLEEP
slave uartb peri 0 BCM21664_SLAVE_CCU_UARTB
slave uartb2 peri 1 BCM21664_SLAVE_CCU_UARTB2
slave uartb3 peri 2 BCM21664_SLAVE_CCU_UARTB3
slave uartb4 peri 3 BCM21664_SLAVE_CCU_UARTB4
slave bsc1 peri 4 BCM21664_SLAVE_CCU_BSC1
slave bsc2 peri 5 BCM21664_SLAVE_CCU_BSC2
slave bsc3 peri 6 BCM21664_SLAVE_CCU_BSC3
slave bsc4 peri 7 BCM21664_SLAVE_CCU_BSC4
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/brcm,kona-ccu.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Broadcom Kona family clock control units (CCU)
maintainers:
- Florian Fainelli <florian.fainelli@broadcom.com>
- Ray Jui <rjui@broadcom.com>
- Scott Branden <sbranden@broadcom.com>
description: |
Broadcom "Kona" style clock control unit (CCU) is a clock provider that
manages a set of clock signals.
All available clock IDs are defined in
- include/dt-bindings/clock/bcm281xx.h for BCM281XX family
- include/dt-bindings/clock/bcm21664.h for BCM21664 family
properties:
compatible:
enum:
- brcm,bcm11351-aon-ccu
- brcm,bcm11351-hub-ccu
- brcm,bcm11351-master-ccu
- brcm,bcm11351-root-ccu
- brcm,bcm11351-slave-ccu
- brcm,bcm21664-aon-ccu
- brcm,bcm21664-master-ccu
- brcm,bcm21664-root-ccu
- brcm,bcm21664-slave-ccu
reg:
maxItems: 1
'#clock-cells':
const: 1
clock-output-names:
minItems: 1
maxItems: 10
required:
- compatible
- reg
- '#clock-cells'
- clock-output-names
allOf:
- if:
properties:
compatible:
contains:
const: brcm,bcm11351-aon-ccu
then:
properties:
clock-output-names:
items:
- const: hub_timer
- const: pmu_bsc
- const: pmu_bsc_var
- if:
properties:
compatible:
contains:
const: brcm,bcm11351-hub-ccu
then:
properties:
clock-output-names:
const: tmon_1m
- if:
properties:
compatible:
contains:
const: brcm,bcm11351-master-ccu
then:
properties:
clock-output-names:
items:
- const: sdio1
- const: sdio2
- const: sdio3
- const: sdio4
- const: usb_ic
- const: hsic2_48m
- const: hsic2_12m
- if:
properties:
compatible:
contains:
enum:
- brcm,bcm11351-root-ccu
- brcm,bcm21664-root-ccu
then:
properties:
clock-output-names:
const: frac_1m
- if:
properties:
compatible:
contains:
const: brcm,bcm11351-slave-ccu
then:
properties:
clock-output-names:
items:
- const: uartb
- const: uartb2
- const: uartb3
- const: uartb4
- const: ssp0
- const: ssp2
- const: bsc1
- const: bsc2
- const: bsc3
- const: pwm
- if:
properties:
compatible:
contains:
const: brcm,bcm21664-aon-ccu
then:
properties:
clock-output-names:
const: hub_timer
- if:
properties:
compatible:
contains:
const: brcm,bcm21664-master-ccu
then:
properties:
clock-output-names:
items:
- const: sdio1
- const: sdio2
- const: sdio3
- const: sdio4
- const: sdio1_sleep
- const: sdio2_sleep
- const: sdio3_sleep
- const: sdio4_sleep
- if:
properties:
compatible:
contains:
const: brcm,bcm21664-slave-ccu
then:
properties:
clock-output-names:
items:
- const: uartb
- const: uartb2
- const: uartb3
- const: bsc1
- const: bsc2
- const: bsc3
- const: bsc4
additionalProperties: false
examples:
- |
clock-controller@3e011000 {
compatible = "brcm,bcm11351-slave-ccu";
reg = <0x3e011000 0x0f00>;
#clock-cells = <1>;
clock-output-names = "uartb",
"uartb2",
"uartb3",
"uartb4",
"ssp0",
"ssp2",
"bsc1",
"bsc2",
"bsc3",
"pwm";
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/fsl,imx93-anatop.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: NXP i.MX93 ANATOP Clock Module
maintainers:
- Peng Fan <peng.fan@nxp.com>
description: |
NXP i.MX93 ANATOP module which contains PLL and OSC to Clock Controller
Module.
properties:
compatible:
items:
- const: fsl,imx93-anatop
reg:
maxItems: 1
'#clock-cells':
const: 1
required:
- compatible
- reg
- '#clock-cells'
additionalProperties: false
examples:
- |
clock-controller@44480000 {
compatible = "fsl,imx93-anatop";
reg = <0x44480000 0x2000>;
#clock-cells = <1>;
};
...
......@@ -22,6 +22,7 @@ properties:
- mediatek,mt7622-apmixedsys
- mediatek,mt7981-apmixedsys
- mediatek,mt7986-apmixedsys
- mediatek,mt7988-apmixedsys
- mediatek,mt8135-apmixedsys
- mediatek,mt8173-apmixedsys
- mediatek,mt8516-apmixedsys
......
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/mediatek,ethsys.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Mediatek ethsys controller
description:
The available clocks are defined in dt-bindings/clock/mt*-clk.h.
maintainers:
- James Liao <jamesjj.liao@mediatek.com>
properties:
compatible:
oneOf:
- items:
- enum:
- mediatek,mt2701-ethsys
- mediatek,mt7622-ethsys
- mediatek,mt7629-ethsys
- mediatek,mt7981-ethsys
- mediatek,mt7986-ethsys
- mediatek,mt7988-ethsys
- const: syscon
- items:
- const: mediatek,mt7623-ethsys
- const: mediatek,mt2701-ethsys
- const: syscon
reg:
maxItems: 1
"#clock-cells":
const: 1
"#reset-cells":
const: 1
required:
- reg
- "#clock-cells"
- "#reset-cells"
additionalProperties: false
examples:
- |
clock-controller@1b000000 {
compatible = "mediatek,mt2701-ethsys", "syscon";
reg = <0x1b000000 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/mediatek,mt7988-ethwarp.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek MT7988 ethwarp Controller
maintainers:
- Daniel Golle <daniel@makrotopia.org>
description:
The Mediatek MT7988 ethwarp controller provides clocks and resets for the
Ethernet related subsystems found the MT7988 SoC.
The clock values can be found in <dt-bindings/clock/mt*-clk.h>.
properties:
compatible:
items:
- const: mediatek,mt7988-ethwarp
reg:
maxItems: 1
'#clock-cells':
const: 1
'#reset-cells':
const: 1
required:
- compatible
- reg
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/reset/ti-syscon.h>
soc {
#address-cells = <2>;
#size-cells = <2>;
clock-controller@15031000 {
compatible = "mediatek,mt7988-ethwarp";
reg = <0 0x15031000 0 0x1000>;
#clock-cells = <1>;
#reset-cells = <1>;
};
};
# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/mediatek,mt7988-xfi-pll.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: MediaTek MT7988 XFI PLL Clock Controller
maintainers:
- Daniel Golle <daniel@makrotopia.org>
description:
The MediaTek XFI PLL controller provides the 156.25MHz clock for the
Ethernet SerDes PHY from the 40MHz top_xtal clock.
properties:
compatible:
const: mediatek,mt7988-xfi-pll
reg:
maxItems: 1
resets:
maxItems: 1
'#clock-cells':
const: 1
required:
- compatible
- reg
- resets
- '#clock-cells'
additionalProperties: false
examples:
- |
soc {
#address-cells = <2>;
#size-cells = <2>;
clock-controller@11f40000 {
compatible = "mediatek,mt7988-xfi-pll";
reg = <0 0x11f40000 0 0x1000>;
resets = <&watchdog 16>;
#clock-cells = <1>;
};
};
......@@ -37,6 +37,8 @@ properties:
- mediatek,mt7629-topckgen
- mediatek,mt7981-topckgen
- mediatek,mt7986-topckgen
- mediatek,mt7988-mcusys
- mediatek,mt7988-topckgen
- mediatek,mt8167-topckgen
- mediatek,mt8183-topckgen
- const: syscon
......
......@@ -16,6 +16,7 @@ description:
properties:
compatible:
enum:
- qcom,ipq5018-a53pll
- qcom,ipq5332-a53pll
- qcom,ipq6018-a53pll
- qcom,ipq8074-a53pll
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,gcc-ipq6018.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller on IPQ6018
maintainers:
- Stephen Boyd <sboyd@kernel.org>
- Taniya Das <quic_tdas@quicinc.com>
- Robert Marko <robimarko@gmail.com>
description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on IPQ6018.
See also::
include/dt-bindings/clock/qcom,gcc-ipq6018.h
include/dt-bindings/reset/qcom,gcc-ipq6018.h
allOf:
- $ref: qcom,gcc.yaml#
properties:
compatible:
const: qcom,gcc-ipq6018
clocks:
items:
- description: board XO clock
- description: sleep clock
clock-names:
items:
- const: xo
- const: sleep_clk
required:
- compatible
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
clock-controller@1800000 {
compatible = "qcom,gcc-ipq6018";
reg = <0x01800000 0x80000>;
clocks = <&xo>, <&sleep_clk>;
clock-names = "xo", "sleep_clk";
#clock-cells = <1>;
#power-domain-cells = <1>;
#reset-cells = <1>;
};
...
......@@ -15,8 +15,6 @@ description: |
domains.
See also::
include/dt-bindings/clock/qcom,gcc-ipq6018.h
include/dt-bindings/reset/qcom,gcc-ipq6018.h
include/dt-bindings/clock/qcom,gcc-msm8953.h
include/dt-bindings/clock/qcom,gcc-mdm9607.h
......@@ -26,7 +24,6 @@ allOf:
properties:
compatible:
enum:
- qcom,gcc-ipq6018
- qcom,gcc-mdm9607
required:
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,qdu1000-ecpricc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm ECPRI Clock & Reset Controller for QDU1000 and QRU1000
maintainers:
- Taniya Das <quic_tdas@quicinc.com>
- Imran Shaik <quic_imrashai@quicinc.com>
description: |
Qualcomm ECPRI Specification V2.0 Common Public Radio Interface clock control
module which supports the clocks, resets on QDU1000 and QRU1000
See also:: include/dt-bindings/clock/qcom,qdu1000-ecpricc.h
properties:
compatible:
enum:
- qcom,qdu1000-ecpricc
reg:
maxItems: 1
clocks:
items:
- description: Board XO source
- description: GPLL0 source from GCC
- description: GPLL1 source from GCC
- description: GPLL2 source from GCC
- description: GPLL3 source from GCC
- description: GPLL4 source from GCC
- description: GPLL5 source from GCC
'#clock-cells':
const: 1
'#reset-cells':
const: 1
required:
- compatible
- reg
- clocks
- '#clock-cells'
- '#reset-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,qdu1000-gcc.h>
#include <dt-bindings/clock/qcom,rpmh.h>
clock-controller@280000 {
compatible = "qcom,qdu1000-ecpricc";
reg = <0x00280000 0x31c00>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_ECPRI_CC_GPLL0_CLK_SRC>,
<&gcc GCC_ECPRI_CC_GPLL1_EVEN_CLK_SRC>,
<&gcc GCC_ECPRI_CC_GPLL2_EVEN_CLK_SRC>,
<&gcc GCC_ECPRI_CC_GPLL3_CLK_SRC>,
<&gcc GCC_ECPRI_CC_GPLL4_CLK_SRC>,
<&gcc GCC_ECPRI_CC_GPLL5_EVEN_CLK_SRC>;
#clock-cells = <1>;
#reset-cells = <1>;
};
......@@ -21,6 +21,15 @@ description: |
1 -- DIF1
2 -- DIF2
3 -- DIF3
- 9FGV0841:
0 -- DIF0
1 -- DIF1
2 -- DIF2
3 -- DIF3
4 -- DIF4
5 -- DIF5
6 -- DIF6
7 -- DIF7
maintainers:
- Marek Vasut <marex@denx.de>
......@@ -30,6 +39,7 @@ properties:
enum:
- renesas,9fgv0241
- renesas,9fgv0441
- renesas,9fgv0841
reg:
description: I2C device address
......
Binding for Silicon Labs Si5351a/b/c programmable i2c clock generator.
Reference
[1] Si5351A/B/C Data Sheet
https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/Si5351-B.pdf
The Si5351a/b/c are programmable i2c clock generators with up to 8 output
clocks. Si5351a also has a reduced pin-count package (MSOP10) where only
3 output clocks are accessible. The internal structure of the clock
generators can be found in [1].
==I2C device node==
Required properties:
- compatible: shall be one of the following:
"silabs,si5351a" - Si5351a, QFN20 package
"silabs,si5351a-msop" - Si5351a, MSOP10 package
"silabs,si5351b" - Si5351b, QFN20 package
"silabs,si5351c" - Si5351c, QFN20 package
- reg: i2c device address, shall be 0x60 or 0x61.
- #clock-cells: from common clock binding; shall be set to 1.
- clocks: from common clock binding; list of parent clock
handles, shall be xtal reference clock or xtal and clkin for
si5351c only. Corresponding clock input names are "xtal" and
"clkin" respectively.
- #address-cells: shall be set to 1.
- #size-cells: shall be set to 0.
Optional properties:
- silabs,pll-source: pair of (number, source) for each pll. Allows
to overwrite clock source of pll A (number=0) or B (number=1).
==Child nodes==
Each of the clock outputs can be overwritten individually by
using a child node to the I2C device node. If a child node for a clock
output is not set, the eeprom configuration is not overwritten.
Required child node properties:
- reg: number of clock output.
Optional child node properties:
- silabs,clock-source: source clock of the output divider stage N, shall be
0 = multisynth N
1 = multisynth 0 for output clocks 0-3, else multisynth4
2 = xtal
3 = clkin (si5351c only)
- silabs,drive-strength: output drive strength in mA, shall be one of {2,4,6,8}.
- silabs,multisynth-source: source pll A(0) or B(1) of corresponding multisynth
divider.
- silabs,pll-master: boolean, multisynth can change pll frequency.
- silabs,pll-reset: boolean, clock output can reset its pll.
- silabs,disable-state : clock output disable state, shall be
0 = clock output is driven LOW when disabled
1 = clock output is driven HIGH when disabled
2 = clock output is FLOATING (HIGH-Z) when disabled
3 = clock output is NEVER disabled
==Example==
/* 25MHz reference crystal */
ref25: ref25M {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <25000000>;
};
i2c-master-node {
/* Si5351a msop10 i2c clock generator */
si5351a: clock-generator@60 {
compatible = "silabs,si5351a-msop";
reg = <0x60>;
#address-cells = <1>;
#size-cells = <0>;
#clock-cells = <1>;
/* connect xtal input to 25MHz reference */
clocks = <&ref25>;
clock-names = "xtal";
/* connect xtal input as source of pll0 and pll1 */
silabs,pll-source = <0 0>, <1 0>;
/*
* overwrite clkout0 configuration with:
* - 8mA output drive strength
* - pll0 as clock source of multisynth0
* - multisynth0 as clock source of output divider
* - multisynth0 can change pll0
* - set initial clock frequency of 74.25MHz
*/
clkout0 {
reg = <0>;
silabs,drive-strength = <8>;
silabs,multisynth-source = <0>;
silabs,clock-source = <0>;
silabs,pll-master;
clock-frequency = <74250000>;
};
/*
* overwrite clkout1 configuration with:
* - 4mA output drive strength
* - pll1 as clock source of multisynth1
* - multisynth1 as clock source of output divider
* - multisynth1 can change pll1
*/
clkout1 {
reg = <1>;
silabs,drive-strength = <4>;
silabs,multisynth-source = <1>;
silabs,clock-source = <0>;
pll-master;
};
/*
* overwrite clkout2 configuration with:
* - xtal as clock source of output divider
*/
clkout2 {
reg = <2>;
silabs,clock-source = <2>;
};
};
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/silabs,si5351.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Silicon Labs Si5351A/B/C programmable I2C clock generators
description: |
The Silicon Labs Si5351A/B/C are programmable I2C clock generators with up to
8 outputs. Si5351A also has a reduced pin-count package (10-MSOP) where only 3
output clocks are accessible. The internal structure of the clock generators
can be found in [1].
[1] Si5351A/B/C Data Sheet
https://www.skyworksinc.com/-/media/Skyworks/SL/documents/public/data-sheets/Si5351-B.pdf
maintainers:
- Alvin Šipraga <alsi@bang-olufsen.dk>
properties:
compatible:
enum:
- silabs,si5351a # Si5351A, 20-QFN package
- silabs,si5351a-msop # Si5351A, 10-MSOP package
- silabs,si5351b # Si5351B, 20-QFN package
- silabs,si5351c # Si5351C, 20-QFN package
reg:
enum:
- 0x60
- 0x61
"#address-cells":
const: 1
"#size-cells":
const: 0
"#clock-cells":
const: 1
clocks:
minItems: 1
maxItems: 2
clock-names:
minItems: 1
items:
- const: xtal
- const: clkin
silabs,pll-source:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
description: |
A list of cell pairs containing a PLL index and its source. Allows to
overwrite clock source of the internal PLLs.
items:
items:
- description: PLL A (0) or PLL B (1)
enum: [ 0, 1 ]
- description: PLL source, XTAL (0) or CLKIN (1, Si5351C only).
enum: [ 0, 1 ]
silabs,pll-reset-mode:
$ref: /schemas/types.yaml#/definitions/uint32-matrix
minItems: 1
maxItems: 2
description: A list of cell pairs containing a PLL index and its reset mode.
items:
items:
- description: PLL A (0) or PLL B (1)
enum: [ 0, 1 ]
- description: |
Reset mode for the PLL. Mode can be one of:
0 - reset whenever PLL rate is adjusted (default mode)
1 - do not reset when PLL rate is adjusted
In mode 1, the PLL is only reset if the silabs,pll-reset is
specified in one of the clock output child nodes that also sources
the PLL. This mode may be preferable if output clocks are expected
to be adjusted without glitches.
enum: [ 0, 1 ]
patternProperties:
"^clkout@[0-7]$":
type: object
additionalProperties: false
properties:
reg:
description: Clock output number.
clock-frequency: true
silabs,clock-source:
$ref: /schemas/types.yaml#/definitions/uint32
description: |
Source clock of the this output's divider stage.
0 - use multisynth N for this output, where N is the output number
1 - use either multisynth 0 (if output number is 0-3) or multisynth 4
(otherwise) for this output
2 - use XTAL for this output
3 - use CLKIN for this output (Si5351C only)
silabs,drive-strength:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 2, 4, 6, 8 ]
description: Output drive strength in mA.
silabs,multisynth-source:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 0, 1 ]
description:
Source PLL A (0) or B (1) for the corresponding multisynth divider.
silabs,pll-master:
type: boolean
description: |
The frequency of the source PLL is allowed to be changed by the
multisynth when setting the rate of this clock output.
silabs,pll-reset:
type: boolean
description: Reset the source PLL when enabling this clock output.
silabs,disable-state:
$ref: /schemas/types.yaml#/definitions/uint32
enum: [ 0, 1, 2, 3 ]
description: |
Clock output disable state. The state can be one of:
0 - clock output is driven LOW when disabled
1 - clock output is driven HIGH when disabled
2 - clock output is FLOATING (HIGH-Z) when disabled
3 - clock output is never disabled
allOf:
- if:
properties:
compatible:
contains:
const: silabs,si5351a-msop
then:
properties:
reg:
maximum: 2
else:
properties:
reg:
maximum: 7
- if:
properties:
compatible:
contains:
const: silabs,si5351c
then:
properties:
silabs,clock-source:
enum: [ 0, 1, 2, 3 ]
else:
properties:
silabs,clock-source:
enum: [ 0, 1, 2 ]
required:
- reg
allOf:
- if:
properties:
compatible:
contains:
enum:
- silabs,si5351a
- silabs,si5351a-msop
- silabs,si5351b
then:
properties:
clocks:
maxItems: 1
clock-names:
maxItems: 1
required:
- reg
- "#address-cells"
- "#size-cells"
- "#clock-cells"
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
i2c {
#address-cells = <1>;
#size-cells = <0>;
clock-generator@60 {
compatible = "silabs,si5351a-msop";
reg = <0x60>;
#address-cells = <1>;
#size-cells = <0>;
#clock-cells = <1>;
/* Connect XTAL input to 25MHz reference */
clocks = <&ref25>;
clock-names = "xtal";
/* Use XTAL input as source of PLL0 and PLL1 */
silabs,pll-source = <0 0>, <1 0>;
/* Don't reset PLL1 on rate adjustment */
silabs,pll-reset-mode = <1 1>;
/*
* Overwrite CLK0 configuration with:
* - 8 mA output drive strength
* - PLL0 as clock source of multisynth 0
* - Multisynth 0 as clock source of output divider
* - Multisynth 0 can change PLL0
* - Set initial clock frequency of 74.25MHz
*/
clkout@0 {
reg = <0>;
silabs,drive-strength = <8>;
silabs,multisynth-source = <0>;
silabs,clock-source = <0>;
silabs,pll-master;
clock-frequency = <74250000>;
};
/*
* Overwrite CLK1 configuration with:
* - 4 mA output drive strength
* - PLL1 as clock source of multisynth 1
* - Multisynth 1 as clock source of output divider
* - Multisynth 1 can change PLL1
* - Reset PLL1 when enabling this clock output
*/
clkout@1 {
reg = <1>;
silabs,drive-strength = <4>;
silabs,multisynth-source = <1>;
silabs,clock-source = <0>;
silabs,pll-master;
silabs,pll-reset;
};
/*
* Overwrite CLK2 configuration with:
* - XTAL as clock source of output divider
*/
clkout@2 {
reg = <2>;
silabs,clock-source = <2>;
};
};
};
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/sophgo,cv1800-clk.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Sophgo CV1800 Series Clock Controller
maintainers:
- Inochi Amaoto <inochiama@outlook.com>
properties:
compatible:
enum:
- sophgo,cv1800-clk
- sophgo,cv1810-clk
reg:
maxItems: 1
clocks:
maxItems: 1
"#clock-cells":
const: 1
description:
See <dt-bindings/clock/sophgo,cv1800.h> for valid indices.
required:
- compatible
- reg
- clocks
- "#clock-cells"
additionalProperties: false
examples:
- |
clock-controller@3002000 {
compatible = "sophgo,cv1800-clk";
reg = <0x03002000 0x1000>;
clocks = <&osc>;
#clock-cells = <1>;
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/st,stm32mp25-rcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: STM32MP25 Reset Clock Controller
maintainers:
- Gabriel Fernandez <gabriel.fernandez@foss.st.com>
description: |
The RCC hardware block is both a reset and a clock controller.
RCC makes also power management (resume/supend).
See also::
include/dt-bindings/clock/st,stm32mp25-rcc.h
include/dt-bindings/reset/st,stm32mp25-rcc.h
properties:
compatible:
enum:
- st,stm32mp25-rcc
reg:
maxItems: 1
'#clock-cells':
const: 1
'#reset-cells':
const: 1
clocks:
items:
- description: CK_SCMI_HSE High Speed External oscillator (8 to 48 MHz)
- description: CK_SCMI_HSI High Speed Internal oscillator (~ 64 MHz)
- description: CK_SCMI_MSI Low Power Internal oscillator (~ 4 MHz or ~ 16 MHz)
- description: CK_SCMI_LSE Low Speed External oscillator (32 KHz)
- description: CK_SCMI_LSI Low Speed Internal oscillator (~ 32 KHz)
clock-names:
items:
- const: hse
- const: hsi
- const: msi
- const: lse
- const: lsi
required:
- compatible
- reg
- '#clock-cells'
- '#reset-cells'
- clocks
- clock-names
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/st,stm32mp25-rcc.h>
rcc: clock-controller@44200000 {
compatible = "st,stm32mp25-rcc";
reg = <0x44200000 0x10000>;
#clock-cells = <1>;
#reset-cells = <1>;
clock-names = "hse", "hsi", "msi", "lse", "lsi";
clocks = <&scmi_clk CK_SCMI_HSE>,
<&scmi_clk CK_SCMI_HSI>,
<&scmi_clk CK_SCMI_MSI>,
<&scmi_clk CK_SCMI_LSE>,
<&scmi_clk CK_SCMI_LSI>;
};
...
......@@ -20,6 +20,7 @@ properties:
- xlnx,clocking-wizard
- xlnx,clocking-wizard-v5.2
- xlnx,clocking-wizard-v6.0
- xlnx,versal-clk-wizard
reg:
......
......@@ -31,11 +31,11 @@ properties:
clocks:
description: List of clock specifiers which are external input
clocks to the given clock controller.
minItems: 3
minItems: 2
maxItems: 8
clock-names:
minItems: 3
minItems: 2
maxItems: 8
required:
......@@ -59,15 +59,34 @@ allOf:
clocks:
items:
- description: reference clock
- description: alternate reference clock
- description: alternate reference clock for programmable logic
clock-names:
items:
- const: ref
- const: alt_ref
- const: pl_alt_ref
- if:
properties:
compatible:
contains:
enum:
- xlnx,versal-net-clk
then:
properties:
clocks:
items:
- description: reference clock
- description: alternate reference clock for programmable logic
- description: alternate reference clock
clock-names:
items:
- const: ref
- const: pl_alt_ref
- const: alt_ref
- if:
properties:
compatible:
......@@ -110,8 +129,8 @@ examples:
versal_clk: clock-controller {
#clock-cells = <1>;
compatible = "xlnx,versal-clk";
clocks = <&ref>, <&alt_ref>, <&pl_alt_ref>;
clock-names = "ref", "alt_ref", "pl_alt_ref";
clocks = <&ref>, <&pl_alt_ref>;
clock-names = "ref", "pl_alt_ref";
};
};
};
......
......@@ -95,8 +95,8 @@ examples:
versal_clk: clock-controller {
#clock-cells = <1>;
compatible = "xlnx,versal-clk";
clocks = <&ref>, <&alt_ref>, <&pl_alt_ref>;
clock-names = "ref", "alt_ref", "pl_alt_ref";
clocks = <&ref>, <&pl_alt_ref>;
clock-names = "ref", "pl_alt_ref";
};
};
......
......@@ -15,15 +15,22 @@ description:
properties:
compatible:
items:
- enum:
- mediatek,mt7622-sgmiisys
- mediatek,mt7629-sgmiisys
- mediatek,mt7981-sgmiisys_0
- mediatek,mt7981-sgmiisys_1
- mediatek,mt7986-sgmiisys_0
- mediatek,mt7986-sgmiisys_1
- const: syscon
oneOf:
- items:
- enum:
- mediatek,mt7622-sgmiisys
- mediatek,mt7629-sgmiisys
- mediatek,mt7981-sgmiisys_0
- mediatek,mt7981-sgmiisys_1
- mediatek,mt7986-sgmiisys_0
- mediatek,mt7986-sgmiisys_1
- const: syscon
- items:
- enum:
- mediatek,mt7988-sgmiisys0
- mediatek,mt7988-sgmiisys1
- const: simple-mfd
- const: syscon
reg:
maxItems: 1
......@@ -35,11 +42,51 @@ properties:
description: Invert polarity of the SGMII data lanes
type: boolean
pcs:
type: object
description: MediaTek LynxI HSGMII PCS
properties:
compatible:
const: mediatek,mt7988-sgmii
clocks:
maxItems: 3
clock-names:
items:
- const: sgmii_sel
- const: sgmii_tx
- const: sgmii_rx
required:
- compatible
- clocks
- clock-names
additionalProperties: false
required:
- compatible
- reg
- '#clock-cells'
allOf:
- if:
properties:
compatible:
contains:
enum:
- mediatek,mt7988-sgmiisys0
- mediatek,mt7988-sgmiisys1
then:
required:
- pcs
else:
properties:
pcs: false
additionalProperties: false
examples:
......
......@@ -414,16 +414,6 @@ config COMMON_CLK_VC7
Renesas Versaclock7 is a family of configurable clock generator
and jitter attenuator ICs with fractional and integer dividers.
config COMMON_CLK_STM32MP135
def_bool COMMON_CLK && MACH_STM32MP13
help
Support for stm32mp135 SoC family clocks
config COMMON_CLK_STM32MP157
def_bool COMMON_CLK && MACH_STM32MP157
help
Support for stm32mp157 SoC family clocks
config COMMON_CLK_STM32F
def_bool COMMON_CLK && (MACH_STM32F429 || MACH_STM32F469 || MACH_STM32F746)
help
......@@ -504,6 +494,7 @@ source "drivers/clk/starfive/Kconfig"
source "drivers/clk/sunxi/Kconfig"
source "drivers/clk/sunxi-ng/Kconfig"
source "drivers/clk/tegra/Kconfig"
source "drivers/clk/stm32/Kconfig"
source "drivers/clk/ti/Kconfig"
source "drivers/clk/uniphier/Kconfig"
source "drivers/clk/visconti/Kconfig"
......
......@@ -70,7 +70,6 @@ obj-$(CONFIG_COMMON_CLK_SI570) += clk-si570.o
obj-$(CONFIG_COMMON_CLK_SP7021) += clk-sp7021.o
obj-$(CONFIG_COMMON_CLK_STM32F) += clk-stm32f4.o
obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
obj-$(CONFIG_COMMON_CLK_TPS68470) += clk-tps68470.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
obj-$(CONFIG_CLK_TWL) += clk-twl.o
......
......@@ -7,6 +7,7 @@
* Currently supported:
* - 9FGV0241
* - 9FGV0441
* - 9FGV0841
*
* Copyright (C) 2022 Marek Vasut <marex@denx.de>
*/
......@@ -42,6 +43,7 @@
#define RS9_REG_DID 0x6
#define RS9_REG_BCP 0x7
#define RS9_REG_VID_MASK GENMASK(3, 0)
#define RS9_REG_VID_IDT 0x01
#define RS9_REG_DID_TYPE_FGV (0x0 << RS9_REG_DID_TYPE_SHIFT)
......@@ -49,16 +51,10 @@
#define RS9_REG_DID_TYPE_DMV (0x2 << RS9_REG_DID_TYPE_SHIFT)
#define RS9_REG_DID_TYPE_SHIFT 0x6
/* Supported Renesas 9-series models. */
enum rs9_model {
RENESAS_9FGV0241,
RENESAS_9FGV0441,
};
/* Structure to describe features of a particular 9-series model */
struct rs9_chip_info {
const enum rs9_model model;
unsigned int num_clks;
u8 outshift;
u8 did;
};
......@@ -160,14 +156,12 @@ static const struct regmap_config rs9_regmap_config = {
static u8 rs9_calc_dif(const struct rs9_driver_data *rs9, int idx)
{
enum rs9_model model = rs9->chip_info->model;
if (model == RENESAS_9FGV0241)
return BIT(idx) + 1;
else if (model == RENESAS_9FGV0441)
return BIT(idx);
return 0;
/*
* On 9FGV0241, the DIF OE0 is BIT(1) and DIF OE(1) is BIT(2),
* on 9FGV0441 and 9FGV0841 the DIF OE0 is BIT(0) and so on.
* Increment the index in the 9FGV0241 special case here.
*/
return BIT(idx + rs9->chip_info->outshift);
}
static int rs9_get_output_config(struct rs9_driver_data *rs9, int idx)
......@@ -333,6 +327,7 @@ static int rs9_probe(struct i2c_client *client)
if (ret < 0)
return ret;
vid &= RS9_REG_VID_MASK;
if (vid != RS9_REG_VID_IDT || did != rs9->chip_info->did)
return dev_err_probe(&client->dev, -ENODEV,
"Incorrect VID/DID: %#02x, %#02x. Expected %#02x, %#02x\n",
......@@ -380,20 +375,27 @@ static int __maybe_unused rs9_resume(struct device *dev)
}
static const struct rs9_chip_info renesas_9fgv0241_info = {
.model = RENESAS_9FGV0241,
.num_clks = 2,
.outshift = 1,
.did = RS9_REG_DID_TYPE_FGV | 0x02,
};
static const struct rs9_chip_info renesas_9fgv0441_info = {
.model = RENESAS_9FGV0441,
.num_clks = 4,
.outshift = 0,
.did = RS9_REG_DID_TYPE_FGV | 0x04,
};
static const struct rs9_chip_info renesas_9fgv0841_info = {
.num_clks = 8,
.outshift = 0,
.did = RS9_REG_DID_TYPE_FGV | 0x08,
};
static const struct i2c_device_id rs9_id[] = {
{ "9fgv0241", .driver_data = (kernel_ulong_t)&renesas_9fgv0241_info },
{ "9fgv0441", .driver_data = (kernel_ulong_t)&renesas_9fgv0441_info },
{ "9fgv0841", .driver_data = (kernel_ulong_t)&renesas_9fgv0841_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, rs9_id);
......@@ -401,6 +403,7 @@ MODULE_DEVICE_TABLE(i2c, rs9_id);
static const struct of_device_id clk_rs9_of_match[] = {
{ .compatible = "renesas,9fgv0241", .data = &renesas_9fgv0241_info },
{ .compatible = "renesas,9fgv0441", .data = &renesas_9fgv0441_info },
{ .compatible = "renesas,9fgv0841", .data = &renesas_9fgv0841_info },
{ }
};
MODULE_DEVICE_TABLE(of, clk_rs9_of_match);
......
......@@ -895,10 +895,8 @@ static int si5341_output_clk_set_rate(struct clk_hw *hw, unsigned long rate,
r[0] = r_div ? (r_div & 0xff) : 1;
r[1] = (r_div >> 8) & 0xff;
r[2] = (r_div >> 16) & 0xff;
err = regmap_bulk_write(output->data->regmap,
return regmap_bulk_write(output->data->regmap,
SI5341_OUT_R_REG(output), r, 3);
return 0;
}
static int si5341_output_reparent(struct clk_si5341_output *output, u8 index)
......
......@@ -506,6 +506,8 @@ static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
{
struct si5351_hw_data *hwdata =
container_of(hw, struct si5351_hw_data, hw);
struct si5351_platform_data *pdata =
hwdata->drvdata->client->dev.platform_data;
u8 reg = (hwdata->num == 0) ? SI5351_PLLA_PARAMETERS :
SI5351_PLLB_PARAMETERS;
......@@ -518,9 +520,10 @@ static int si5351_pll_set_rate(struct clk_hw *hw, unsigned long rate,
(hwdata->params.p2 == 0) ? SI5351_CLK_INTEGER_MODE : 0);
/* Do a pll soft reset on the affected pll */
si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET,
hwdata->num == 0 ? SI5351_PLL_RESET_A :
SI5351_PLL_RESET_B);
if (pdata->pll_reset[hwdata->num])
si5351_reg_write(hwdata->drvdata, SI5351_PLL_RESET,
hwdata->num == 0 ? SI5351_PLL_RESET_A :
SI5351_PLL_RESET_B);
dev_dbg(&hwdata->drvdata->client->dev,
"%s - %s: p1 = %lu, p2 = %lu, p3 = %lu, parent_rate = %lu, rate = %lu\n",
......@@ -1222,6 +1225,44 @@ static int si5351_dt_parse(struct i2c_client *client,
}
}
/*
* Parse PLL reset mode. For compatibility with older device trees, the
* default is to always reset a PLL after setting its rate.
*/
pdata->pll_reset[0] = true;
pdata->pll_reset[1] = true;
of_property_for_each_u32(np, "silabs,pll-reset-mode", prop, p, num) {
if (num >= 2) {
dev_err(&client->dev,
"invalid pll %d on pll-reset-mode prop\n", num);
return -EINVAL;
}
p = of_prop_next_u32(prop, p, &val);
if (!p) {
dev_err(&client->dev,
"missing pll-reset-mode for pll %d\n", num);
return -EINVAL;
}
switch (val) {
case 0:
/* Reset PLL whenever its rate is adjusted */
pdata->pll_reset[num] = true;
break;
case 1:
/* Don't reset PLL whenever its rate is adjusted */
pdata->pll_reset[num] = false;
break;
default:
dev_err(&client->dev,
"invalid pll-reset-mode %d for pll %d\n", val,
num);
return -EINVAL;
}
}
/* per clkout properties */
for_each_child_of_node(np, child) {
if (of_property_read_u32(child, "reg", &num)) {
......
......@@ -604,14 +604,14 @@ static int sp7021_clk_probe(struct platform_device *pdev)
int i;
clk_base = devm_platform_ioremap_resource(pdev, 0);
if (!clk_base)
return -ENXIO;
if (IS_ERR(clk_base))
return PTR_ERR(clk_base);
pll_base = devm_platform_ioremap_resource(pdev, 1);
if (!pll_base)
return -ENXIO;
if (IS_ERR(pll_base))
return PTR_ERR(pll_base);
sys_base = devm_platform_ioremap_resource(pdev, 2);
if (!sys_base)
return -ENXIO;
if (IS_ERR(sys_base))
return PTR_ERR(sys_base);
/* enable default clks */
for (i = 0; i < ARRAY_SIZE(sp_clken); i++)
......
This diff is collapsed.
......@@ -466,8 +466,10 @@ static void __init hi3620_mmc_clk_init(struct device_node *node)
return;
clk_data->clks = kcalloc(num, sizeof(*clk_data->clks), GFP_KERNEL);
if (!clk_data->clks)
if (!clk_data->clks) {
kfree(clk_data);
return;
}
for (i = 0; i < num; i++) {
struct hisi_mmc_clock *mmc_clk = &hi3620_mmc_clks[i];
......
......@@ -66,6 +66,22 @@ static const char * const lcd_pxl_sels[] = {
"lcd_pxl_bypass_div_clk",
};
static const char *const lvds0_sels[] = {
"clk_dummy",
"clk_dummy",
"clk_dummy",
"clk_dummy",
"mipi0_lvds_bypass_clk",
};
static const char *const lvds1_sels[] = {
"clk_dummy",
"clk_dummy",
"clk_dummy",
"clk_dummy",
"mipi1_lvds_bypass_clk",
};
static const char * const mipi_sels[] = {
"clk_dummy",
"clk_dummy",
......@@ -207,9 +223,9 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
/* MIPI-LVDS SS */
imx_clk_scu("mipi0_bypass_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu("mipi0_pixel_clk", IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PER);
imx_clk_scu("mipi0_lvds_pixel_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2);
imx_clk_scu("mipi0_lvds_bypass_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu("mipi0_lvds_phy_clk", IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3);
imx_clk_scu2("mipi0_lvds_pixel_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC2);
imx_clk_scu2("mipi0_lvds_phy_clk", lvds0_sels, ARRAY_SIZE(lvds0_sels), IMX_SC_R_LVDS_0, IMX_SC_PM_CLK_MISC3);
imx_clk_scu2("mipi0_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_MST_BUS);
imx_clk_scu2("mipi0_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_SLV_BUS);
imx_clk_scu2("mipi0_dsi_phy_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_0, IMX_SC_PM_CLK_PHY);
......@@ -219,9 +235,9 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
imx_clk_scu("mipi1_bypass_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu("mipi1_pixel_clk", IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_PER);
imx_clk_scu("mipi1_lvds_pixel_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2);
imx_clk_scu("mipi1_lvds_bypass_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu("mipi1_lvds_phy_clk", IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3);
imx_clk_scu2("mipi1_lvds_pixel_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC2);
imx_clk_scu2("mipi1_lvds_phy_clk", lvds1_sels, ARRAY_SIZE(lvds1_sels), IMX_SC_R_LVDS_1, IMX_SC_PM_CLK_MISC3);
imx_clk_scu2("mipi1_dsi_tx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_MST_BUS);
imx_clk_scu2("mipi1_dsi_rx_esc_clk", mipi_sels, ARRAY_SIZE(mipi_sels), IMX_SC_R_MIPI_1, IMX_SC_PM_CLK_SLV_BUS);
......
......@@ -104,15 +104,15 @@ static const struct imx_pll14xx_rate_table *imx_get_pll_settings(
static long pll14xx_calc_rate(struct clk_pll14xx *pll, int mdiv, int pdiv,
int sdiv, int kdiv, unsigned long prate)
{
u64 fvco = prate;
u64 fout = prate;
/* fvco = (m * 65536 + k) * Fin / (p * 65536) */
fvco *= (mdiv * 65536 + kdiv);
/* fout = (m * 65536 + k) * Fin / (p * 65536) / (1 << sdiv) */
fout *= (mdiv * 65536 + kdiv);
pdiv *= 65536;
do_div(fvco, pdiv << sdiv);
do_div(fout, pdiv << sdiv);
return fvco;
return fout;
}
static long pll1443x_calc_kdiv(int mdiv, int pdiv, int sdiv,
......@@ -131,7 +131,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
{
u32 pll_div_ctl0, pll_div_ctl1;
int mdiv, pdiv, sdiv, kdiv;
long fvco, rate_min, rate_max, dist, best = LONG_MAX;
long fout, rate_min, rate_max, dist, best = LONG_MAX;
const struct imx_pll14xx_rate_table *tt;
/*
......@@ -143,6 +143,7 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
* d) -32768 <= k <= 32767
*
* fvco = (m * 65536 + k) * prate / (p * 65536)
* fout = (m * 65536 + k) * prate / (p * 65536) / (1 << sdiv)
*/
/* First try if we can get the desired rate from one of the static entries */
......@@ -173,8 +174,8 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
pr_debug("%s: in=%ld, want=%ld Only adjust kdiv %ld -> %d\n",
clk_hw_get_name(&pll->hw), prate, rate,
FIELD_GET(KDIV_MASK, pll_div_ctl1), kdiv);
fvco = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, prate);
t->rate = (unsigned int)fvco;
fout = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, prate);
t->rate = (unsigned int)fout;
t->mdiv = mdiv;
t->pdiv = pdiv;
t->sdiv = sdiv;
......@@ -190,13 +191,13 @@ static void imx_pll14xx_calc_settings(struct clk_pll14xx *pll, unsigned long rat
mdiv = clamp(mdiv, 64, 1023);
kdiv = pll1443x_calc_kdiv(mdiv, pdiv, sdiv, rate, prate);
fvco = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, prate);
fout = pll14xx_calc_rate(pll, mdiv, pdiv, sdiv, kdiv, prate);
/* best match */
dist = abs((long)rate - (long)fvco);
dist = abs((long)rate - (long)fout);
if (dist < best) {
best = dist;
t->rate = (unsigned int)fvco;
t->rate = (unsigned int)fout;
t->mdiv = mdiv;
t->pdiv = pdiv;
t->sdiv = sdiv;
......
......@@ -886,8 +886,10 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na
return ERR_PTR(-EINVAL);
}
if (!imx_clk_is_resource_owned(rsrc_id))
if (!imx_clk_is_resource_owned(rsrc_id)) {
kfree(clk_node);
return NULL;
}
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk) {
......
......@@ -423,6 +423,15 @@ config COMMON_CLK_MT7986_ETHSYS
This driver adds support for clocks for Ethernet and SGMII
required on MediaTek MT7986 SoC.
config COMMON_CLK_MT7988
tristate "Clock driver for MediaTek MT7988"
depends on ARCH_MEDIATEK || COMPILE_TEST
select COMMON_CLK_MEDIATEK
default ARCH_MEDIATEK
help
This driver supports MediaTek MT7988 basic clocks and clocks
required for various periperals found on this SoC.
config COMMON_CLK_MT8135
tristate "Clock driver for MediaTek MT8135"
depends on (ARCH_MEDIATEK && ARM) || COMPILE_TEST
......
......@@ -62,6 +62,11 @@ 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
obj-$(CONFIG_COMMON_CLK_MT7986_ETHSYS) += clk-mt7986-eth.o
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-apmixed.o
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-topckgen.o
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-infracfg.o
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-eth.o
obj-$(CONFIG_COMMON_CLK_MT7988) += clk-mt7988-xfipll.o
obj-$(CONFIG_COMMON_CLK_MT8135) += clk-mt8135-apmixedsys.o clk-mt8135.o
obj-$(CONFIG_COMMON_CLK_MT8167) += clk-mt8167-apmixedsys.o clk-mt8167.o
obj-$(CONFIG_COMMON_CLK_MT8167_AUDSYS) += clk-mt8167-aud.o
......
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2023 MediaTek Inc.
* Author: Sam Shih <sam.shih@mediatek.com>
* Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
*/
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include "clk-mtk.h"
#include "clk-gate.h"
#include "clk-mux.h"
#include "clk-pll.h"
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
#define MT7988_PLL_FMAX (2500UL * MHZ)
#define MT7988_PCW_CHG_BIT 2
#define PLL(_id, _name, _reg, _pwr_reg, _en_mask, _flags, _rst_bar_mask, _pcwbits, _pd_reg, \
_pd_shift, _tuner_reg, _tuner_en_reg, _tuner_en_bit, _pcw_reg, _pcw_shift, \
_pcw_chg_reg) \
{ \
.id = _id, \
.name = _name, \
.reg = _reg, \
.pwr_reg = _pwr_reg, \
.en_mask = _en_mask, \
.flags = _flags, \
.rst_bar_mask = BIT(_rst_bar_mask), \
.fmax = MT7988_PLL_FMAX, \
.pcwbits = _pcwbits, \
.pd_reg = _pd_reg, \
.pd_shift = _pd_shift, \
.tuner_reg = _tuner_reg, \
.tuner_en_reg = _tuner_en_reg, \
.tuner_en_bit = _tuner_en_bit, \
.pcw_reg = _pcw_reg, \
.pcw_shift = _pcw_shift, \
.pcw_chg_reg = _pcw_chg_reg, \
.pcw_chg_bit = MT7988_PCW_CHG_BIT, \
.parent_name = "clkxtal", \
}
static const struct mtk_pll_data plls[] = {
PLL(CLK_APMIXED_NETSYSPLL, "netsyspll", 0x0104, 0x0110, 0x00000001, 0, 0, 32, 0x0104, 4, 0,
0, 0, 0x0108, 0, 0x0104),
PLL(CLK_APMIXED_MPLL, "mpll", 0x0114, 0x0120, 0xff000001, HAVE_RST_BAR, 23, 32, 0x0114, 4,
0, 0, 0, 0x0118, 0, 0x0114),
PLL(CLK_APMIXED_MMPLL, "mmpll", 0x0124, 0x0130, 0xff000001, HAVE_RST_BAR, 23, 32, 0x0124, 4,
0, 0, 0, 0x0128, 0, 0x0124),
PLL(CLK_APMIXED_APLL2, "apll2", 0x0134, 0x0140, 0x00000001, 0, 0, 32, 0x0134, 4, 0x0704,
0x0700, 1, 0x0138, 0, 0x0134),
PLL(CLK_APMIXED_NET1PLL, "net1pll", 0x0144, 0x0150, 0xff000001, HAVE_RST_BAR, 23, 32,
0x0144, 4, 0, 0, 0, 0x0148, 0, 0x0144),
PLL(CLK_APMIXED_NET2PLL, "net2pll", 0x0154, 0x0160, 0xff000001, (HAVE_RST_BAR | PLL_AO), 23,
32, 0x0154, 4, 0, 0, 0, 0x0158, 0, 0x0154),
PLL(CLK_APMIXED_WEDMCUPLL, "wedmcupll", 0x0164, 0x0170, 0x00000001, 0, 0, 32, 0x0164, 4, 0,
0, 0, 0x0168, 0, 0x0164),
PLL(CLK_APMIXED_SGMPLL, "sgmpll", 0x0174, 0x0180, 0x00000001, 0, 0, 32, 0x0174, 4, 0, 0, 0,
0x0178, 0, 0x0174),
PLL(CLK_APMIXED_ARM_B, "arm_b", 0x0204, 0x0210, 0xff000001, (HAVE_RST_BAR | PLL_AO), 23, 32,
0x0204, 4, 0, 0, 0, 0x0208, 0, 0x0204),
PLL(CLK_APMIXED_CCIPLL2_B, "ccipll2_b", 0x0214, 0x0220, 0xff000001, HAVE_RST_BAR, 23, 32,
0x0214, 4, 0, 0, 0, 0x0218, 0, 0x0214),
PLL(CLK_APMIXED_USXGMIIPLL, "usxgmiipll", 0x0304, 0x0310, 0xff000001, HAVE_RST_BAR, 23, 32,
0x0304, 4, 0, 0, 0, 0x0308, 0, 0x0304),
PLL(CLK_APMIXED_MSDCPLL, "msdcpll", 0x0314, 0x0320, 0x00000001, 0, 0, 32, 0x0314, 4, 0, 0,
0, 0x0318, 0, 0x0314),
};
static const struct of_device_id of_match_clk_mt7988_apmixed[] = {
{ .compatible = "mediatek,mt7988-apmixedsys" },
{ /* sentinel */ }
};
static int clk_mt7988_apmixed_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(ARRAY_SIZE(plls));
if (!clk_data)
return -ENOMEM;
r = mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
if (r)
goto free_apmixed_data;
r = of_clk_add_hw_provider(node, of_clk_hw_onecell_get, clk_data);
if (r)
goto unregister_plls;
return r;
unregister_plls:
mtk_clk_unregister_plls(plls, ARRAY_SIZE(plls), clk_data);
free_apmixed_data:
mtk_free_clk_data(clk_data);
return r;
}
static struct platform_driver clk_mt7988_apmixed_drv = {
.probe = clk_mt7988_apmixed_probe,
.driver = {
.name = "clk-mt7988-apmixed",
.of_match_table = of_match_clk_mt7988_apmixed,
},
};
builtin_platform_driver(clk_mt7988_apmixed_drv);
MODULE_LICENSE("GPL");
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2023 MediaTek Inc.
* Author: Sam Shih <sam.shih@mediatek.com>
* Author: Xiufeng Li <Xiufeng.Li@mediatek.com>
*/
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include "clk-mtk.h"
#include "clk-gate.h"
#include "reset.h"
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
#include <dt-bindings/reset/mediatek,mt7988-resets.h>
static const struct mtk_gate_regs ethdma_cg_regs = {
.set_ofs = 0x30,
.clr_ofs = 0x30,
.sta_ofs = 0x30,
};
#define GATE_ETHDMA(_id, _name, _parent, _shift) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &ethdma_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
static const struct mtk_gate ethdma_clks[] = {
GATE_ETHDMA(CLK_ETHDMA_XGP1_EN, "ethdma_xgp1_en", "top_xtal", 0),
GATE_ETHDMA(CLK_ETHDMA_XGP2_EN, "ethdma_xgp2_en", "top_xtal", 1),
GATE_ETHDMA(CLK_ETHDMA_XGP3_EN, "ethdma_xgp3_en", "top_xtal", 2),
GATE_ETHDMA(CLK_ETHDMA_FE_EN, "ethdma_fe_en", "netsys_2x_sel", 6),
GATE_ETHDMA(CLK_ETHDMA_GP2_EN, "ethdma_gp2_en", "top_xtal", 7),
GATE_ETHDMA(CLK_ETHDMA_GP1_EN, "ethdma_gp1_en", "top_xtal", 8),
GATE_ETHDMA(CLK_ETHDMA_GP3_EN, "ethdma_gp3_en", "top_xtal", 10),
GATE_ETHDMA(CLK_ETHDMA_ESW_EN, "ethdma_esw_en", "netsys_gsw_sel", 16),
GATE_ETHDMA(CLK_ETHDMA_CRYPT0_EN, "ethdma_crypt0_en", "eip197_sel", 29),
};
static const struct mtk_clk_desc ethdma_desc = {
.clks = ethdma_clks,
.num_clks = ARRAY_SIZE(ethdma_clks),
};
static const struct mtk_gate_regs sgmii_cg_regs = {
.set_ofs = 0xe4,
.clr_ofs = 0xe4,
.sta_ofs = 0xe4,
};
#define GATE_SGMII(_id, _name, _parent, _shift) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &sgmii_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
static const struct mtk_gate sgmii0_clks[] = {
GATE_SGMII(CLK_SGM0_TX_EN, "sgm0_tx_en", "top_xtal", 2),
GATE_SGMII(CLK_SGM0_RX_EN, "sgm0_rx_en", "top_xtal", 3),
};
static const struct mtk_clk_desc sgmii0_desc = {
.clks = sgmii0_clks,
.num_clks = ARRAY_SIZE(sgmii0_clks),
};
static const struct mtk_gate sgmii1_clks[] = {
GATE_SGMII(CLK_SGM1_TX_EN, "sgm1_tx_en", "top_xtal", 2),
GATE_SGMII(CLK_SGM1_RX_EN, "sgm1_rx_en", "top_xtal", 3),
};
static const struct mtk_clk_desc sgmii1_desc = {
.clks = sgmii1_clks,
.num_clks = ARRAY_SIZE(sgmii1_clks),
};
static const struct mtk_gate_regs ethwarp_cg_regs = {
.set_ofs = 0x14,
.clr_ofs = 0x14,
.sta_ofs = 0x14,
};
#define GATE_ETHWARP(_id, _name, _parent, _shift) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &ethwarp_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
static const struct mtk_gate ethwarp_clks[] = {
GATE_ETHWARP(CLK_ETHWARP_WOCPU2_EN, "ethwarp_wocpu2_en", "netsys_mcu_sel", 13),
GATE_ETHWARP(CLK_ETHWARP_WOCPU1_EN, "ethwarp_wocpu1_en", "netsys_mcu_sel", 14),
GATE_ETHWARP(CLK_ETHWARP_WOCPU0_EN, "ethwarp_wocpu0_en", "netsys_mcu_sel", 15),
};
static u16 ethwarp_rst_ofs[] = { 0x8 };
static u16 ethwarp_idx_map[] = {
[MT7988_ETHWARP_RST_SWITCH] = 9,
};
static const struct mtk_clk_rst_desc ethwarp_rst_desc = {
.version = MTK_RST_SIMPLE,
.rst_bank_ofs = ethwarp_rst_ofs,
.rst_bank_nr = ARRAY_SIZE(ethwarp_rst_ofs),
.rst_idx_map = ethwarp_idx_map,
.rst_idx_map_nr = ARRAY_SIZE(ethwarp_idx_map),
};
static const struct mtk_clk_desc ethwarp_desc = {
.clks = ethwarp_clks,
.num_clks = ARRAY_SIZE(ethwarp_clks),
.rst_desc = &ethwarp_rst_desc,
};
static const struct of_device_id of_match_clk_mt7988_eth[] = {
{ .compatible = "mediatek,mt7988-ethsys", .data = &ethdma_desc },
{ .compatible = "mediatek,mt7988-sgmiisys0", .data = &sgmii0_desc },
{ .compatible = "mediatek,mt7988-sgmiisys1", .data = &sgmii1_desc },
{ .compatible = "mediatek,mt7988-ethwarp", .data = &ethwarp_desc },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_eth);
static struct platform_driver clk_mt7988_eth_drv = {
.driver = {
.name = "clk-mt7988-eth",
.of_match_table = of_match_clk_mt7988_eth,
},
.probe = mtk_clk_simple_probe,
.remove_new = mtk_clk_simple_remove,
};
module_platform_driver(clk_mt7988_eth_drv);
MODULE_DESCRIPTION("MediaTek MT7988 Ethernet clocks driver");
MODULE_LICENSE("GPL");
This diff is collapsed.
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2023 Daniel Golle <daniel@makrotopia.org>
*/
#include <linux/clk-provider.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include "clk-mtk.h"
#include "clk-gate.h"
#include <dt-bindings/clock/mediatek,mt7988-clk.h>
/* Register to control USXGMII XFI PLL analog */
#define XFI_PLL_ANA_GLB8 0x108
#define RG_XFI_PLL_ANA_SWWA 0x02283248
static const struct mtk_gate_regs xfipll_cg_regs = {
.set_ofs = 0x8,
.clr_ofs = 0x8,
.sta_ofs = 0x8,
};
#define GATE_XFIPLL(_id, _name, _parent, _shift) \
{ \
.id = _id, \
.name = _name, \
.parent_name = _parent, \
.regs = &xfipll_cg_regs, \
.shift = _shift, \
.ops = &mtk_clk_gate_ops_no_setclr_inv, \
}
static const struct mtk_fixed_factor xfipll_divs[] = {
FACTOR(CLK_XFIPLL_PLL, "xfipll_pll", "top_xtal", 125, 32),
};
static const struct mtk_gate xfipll_clks[] = {
GATE_XFIPLL(CLK_XFIPLL_PLL_EN, "xfipll_pll_en", "xfipll_pll", 31),
};
static const struct mtk_clk_desc xfipll_desc = {
.clks = xfipll_clks,
.num_clks = ARRAY_SIZE(xfipll_clks),
.factor_clks = xfipll_divs,
.num_factor_clks = ARRAY_SIZE(xfipll_divs),
};
static int clk_mt7988_xfipll_probe(struct platform_device *pdev)
{
struct device_node *node = pdev->dev.of_node;
void __iomem *base = of_iomap(node, 0);
if (!base)
return -ENOMEM;
/* Apply software workaround for USXGMII PLL TCL issue */
writel(RG_XFI_PLL_ANA_SWWA, base + XFI_PLL_ANA_GLB8);
iounmap(base);
return mtk_clk_simple_probe(pdev);
};
static const struct of_device_id of_match_clk_mt7988_xfipll[] = {
{ .compatible = "mediatek,mt7988-xfi-pll", .data = &xfipll_desc },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, of_match_clk_mt7988_xfipll);
static struct platform_driver clk_mt7988_xfipll_drv = {
.driver = {
.name = "clk-mt7988-xfipll",
.of_match_table = of_match_clk_mt7988_xfipll,
},
.probe = clk_mt7988_xfipll_probe,
.remove_new = mtk_clk_simple_remove,
};
module_platform_driver(clk_mt7988_xfipll_drv);
MODULE_DESCRIPTION("MediaTek MT7988 XFI PLL clock driver");
MODULE_LICENSE("GPL");
......@@ -475,29 +475,28 @@ static const char * const sspm_parents[] = {
"mainpll_d4_d2"
};
/*
* Both DP/eDP can be parented to TVDPLL1 and TVDPLL2, but we force using
* TVDPLL1 on eDP and TVDPLL2 on DP to avoid changing the "other" PLL rate
* in dual output case, which would lead to corruption of functionality loss.
*/
static const char * const dp_parents[] = {
"clk26m",
"tvdpll1_d2",
"tvdpll2_d2",
"tvdpll1_d4",
"tvdpll2_d4",
"tvdpll1_d8",
"tvdpll2_d8",
"tvdpll1_d16",
"tvdpll2_d16"
};
static const u8 dp_parents_idx[] = { 0, 2, 4, 6, 8 };
static const char * const edp_parents[] = {
"clk26m",
"tvdpll1_d2",
"tvdpll2_d2",
"tvdpll1_d4",
"tvdpll2_d4",
"tvdpll1_d8",
"tvdpll2_d8",
"tvdpll1_d16",
"tvdpll2_d16"
"tvdpll1_d16"
};
static const u8 edp_parents_idx[] = { 0, 1, 3, 5, 7 };
static const char * const dpi_parents[] = {
"clk26m",
......@@ -1038,10 +1037,12 @@ static const struct mtk_mux top_mtk_muxes[] = {
MUX_GATE_CLR_SET_UPD(CLK_TOP_SSPM, "top_sspm",
sspm_parents, 0x080, 0x084, 0x088, 24, 4, 31, 0x08, 3),
/* CLK_CFG_9 */
MUX_GATE_CLR_SET_UPD(CLK_TOP_DP, "top_dp",
dp_parents, 0x08C, 0x090, 0x094, 0, 4, 7, 0x08, 4),
MUX_GATE_CLR_SET_UPD(CLK_TOP_EDP, "top_edp",
edp_parents, 0x08C, 0x090, 0x094, 8, 4, 15, 0x08, 5),
MUX_GATE_CLR_SET_UPD_INDEXED(CLK_TOP_DP, "top_dp",
dp_parents, dp_parents_idx, 0x08C, 0x090, 0x094,
0, 4, 7, 0x08, 4),
MUX_GATE_CLR_SET_UPD_INDEXED(CLK_TOP_EDP, "top_edp",
edp_parents, edp_parents_idx, 0x08C, 0x090, 0x094,
8, 4, 15, 0x08, 5),
MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI, "top_dpi",
dpi_parents, 0x08C, 0x090, 0x094, 16, 4, 23, 0x08, 6),
MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM0, "top_disp_pwm0",
......
......@@ -415,17 +415,28 @@ static const char * const pwrmcu_parents[] = {
"mainpll_d4_d2"
};
/*
* Both DP/eDP can be parented to TVDPLL1 and TVDPLL2, but we force using
* TVDPLL1 on eDP and TVDPLL2 on DP to avoid changing the "other" PLL rate
* in dual output case, which would lead to corruption of functionality loss.
*/
static const char * const dp_parents[] = {
"clk26m",
"tvdpll1_d2",
"tvdpll2_d2",
"tvdpll1_d4",
"tvdpll2_d4",
"tvdpll1_d8",
"tvdpll2_d8",
"tvdpll1_d16",
"tvdpll2_d16"
};
static const u8 dp_parents_idx[] = { 0, 2, 4, 6, 8 };
static const char * const edp_parents[] = {
"clk26m",
"tvdpll1_d2",
"tvdpll1_d4",
"tvdpll1_d8",
"tvdpll1_d16"
};
static const u8 edp_parents_idx[] = { 0, 1, 3, 5, 7 };
static const char * const disp_pwm_parents[] = {
"clk26m",
......@@ -957,11 +968,11 @@ static const struct mtk_mux top_mtk_muxes[] = {
MUX_GATE_CLR_SET_UPD_FLAGS(CLK_TOP_PWRMCU, "top_pwrmcu",
pwrmcu_parents, 0x08C, 0x090, 0x094, 16, 3, 23, 0x08, 6,
CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
MUX_GATE_CLR_SET_UPD(CLK_TOP_DP, "top_dp",
dp_parents, 0x08C, 0x090, 0x094, 24, 4, 31, 0x08, 7),
MUX_GATE_CLR_SET_UPD_INDEXED(CLK_TOP_DP, "top_dp",
dp_parents, dp_parents_idx, 0x08C, 0x090, 0x094, 24, 4, 31, 0x08, 7),
/* CLK_CFG_10 */
MUX_GATE_CLR_SET_UPD(CLK_TOP_EDP, "top_edp",
dp_parents, 0x098, 0x09C, 0x0A0, 0, 4, 7, 0x08, 8),
MUX_GATE_CLR_SET_UPD_INDEXED(CLK_TOP_EDP, "top_edp",
edp_parents, edp_parents_idx, 0x098, 0x09C, 0x0A0, 0, 4, 7, 0x08, 8),
MUX_GATE_CLR_SET_UPD(CLK_TOP_DPI, "top_dpi",
dp_parents, 0x098, 0x09C, 0x0A0, 8, 4, 15, 0x08, 9),
MUX_GATE_CLR_SET_UPD(CLK_TOP_DISP_PWM0, "top_disp_pwm0",
......
......@@ -89,6 +89,17 @@ static u8 mtk_clk_mux_get_parent(struct clk_hw *hw)
regmap_read(mux->regmap, mux->data->mux_ofs, &val);
val = (val >> mux->data->mux_shift) & mask;
if (mux->data->parent_index) {
int i;
for (i = 0; i < mux->data->num_parents; i++)
if (mux->data->parent_index[i] == val)
return i;
/* Not found: return an impossible index to generate error */
return mux->data->num_parents + 1;
}
return val;
}
......@@ -104,6 +115,9 @@ static int mtk_clk_mux_set_parent_setclr_lock(struct clk_hw *hw, u8 index)
else
__acquire(mux->lock);
if (mux->data->parent_index)
index = mux->data->parent_index[index];
regmap_read(mux->regmap, mux->data->mux_ofs, &orig);
val = (orig & ~(mask << mux->data->mux_shift))
| (index << mux->data->mux_shift);
......
......@@ -21,6 +21,7 @@ struct mtk_mux {
int id;
const char *name;
const char * const *parent_names;
const u8 *parent_index;
unsigned int flags;
u32 mux_ofs;
......@@ -37,9 +38,10 @@ struct mtk_mux {
signed char num_parents;
};
#define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
_gate, _upd_ofs, _upd, _flags, _ops) { \
#define __GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _paridx, \
_num_parents, _mux_ofs, _mux_set_ofs, \
_mux_clr_ofs, _shift, _width, _gate, _upd_ofs, \
_upd, _flags, _ops) { \
.id = _id, \
.name = _name, \
.mux_ofs = _mux_ofs, \
......@@ -51,11 +53,28 @@ struct mtk_mux {
.gate_shift = _gate, \
.upd_shift = _upd, \
.parent_names = _parents, \
.num_parents = ARRAY_SIZE(_parents), \
.parent_index = _paridx, \
.num_parents = _num_parents, \
.flags = _flags, \
.ops = &_ops, \
}
#define GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, _mux_ofs, \
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
_gate, _upd_ofs, _upd, _flags, _ops) \
__GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
NULL, ARRAY_SIZE(_parents), _mux_ofs, \
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
_gate, _upd_ofs, _upd, _flags, _ops) \
#define GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, _paridx, \
_mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
_width, _gate, _upd_ofs, _upd, _flags, _ops) \
__GATE_CLR_SET_UPD_FLAGS(_id, _name, _parents, \
_paridx, ARRAY_SIZE(_paridx), _mux_ofs, \
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
_gate, _upd_ofs, _upd, _flags, _ops) \
extern const struct clk_ops mtk_mux_clr_set_upd_ops;
extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
......@@ -67,6 +86,14 @@ extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
_gate, _upd_ofs, _upd, _flags, \
mtk_mux_gate_clr_set_upd_ops)
#define MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, \
_paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
_shift, _width, _gate, _upd_ofs, _upd, _flags) \
GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, _parents, \
_paridx, _mux_ofs, _mux_set_ofs, _mux_clr_ofs, \
_shift, _width, _gate, _upd_ofs, _upd, _flags, \
mtk_mux_gate_clr_set_upd_ops)
#define MUX_GATE_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
_gate, _upd_ofs, _upd) \
......@@ -75,6 +102,14 @@ extern const struct clk_ops mtk_mux_gate_clr_set_upd_ops;
_width, _gate, _upd_ofs, _upd, \
CLK_SET_RATE_PARENT)
#define MUX_GATE_CLR_SET_UPD_INDEXED(_id, _name, _parents, _paridx, \
_mux_ofs, _mux_set_ofs, _mux_clr_ofs, _shift, \
_width, _gate, _upd_ofs, _upd) \
MUX_GATE_CLR_SET_UPD_FLAGS_INDEXED(_id, _name, \
_parents, _paridx, _mux_ofs, _mux_set_ofs, \
_mux_clr_ofs, _shift, _width, _gate, _upd_ofs, \
_upd, CLK_SET_RATE_PARENT)
#define MUX_CLR_SET_UPD(_id, _name, _parents, _mux_ofs, \
_mux_set_ofs, _mux_clr_ofs, _shift, _width, \
_upd_ofs, _upd) \
......
......@@ -23,7 +23,7 @@
#define CON0_BASE_EN BIT(0)
#define CON0_PWR_ON BIT(0)
#define CON0_ISO_EN BIT(1)
#define PCW_CHG_MASK BIT(31)
#define PCW_CHG_BIT 31
#define AUDPLL_TUNER_EN BIT(31)
......@@ -114,7 +114,8 @@ static void mtk_pll_set_rate_regs(struct mtk_clk_pll *pll, u32 pcw,
pll->data->pcw_shift);
val |= pcw << pll->data->pcw_shift;
writel(val, pll->pcw_addr);
chg = readl(pll->pcw_chg_addr) | PCW_CHG_MASK;
chg = readl(pll->pcw_chg_addr) |
BIT(pll->data->pcw_chg_bit ? : PCW_CHG_BIT);
writel(chg, pll->pcw_chg_addr);
if (pll->tuner_addr)
writel(val + 1, pll->tuner_addr);
......
......@@ -48,6 +48,7 @@ struct mtk_pll_data {
const char *parent_name;
u32 en_reg;
u8 pll_en_bit; /* Assume 0, indicates BIT(0) by default */
u8 pcw_chg_bit;
};
/*
......
......@@ -3549,6 +3549,22 @@ static struct clk_regmap g12a_cts_encp_sel = {
},
};
static struct clk_regmap g12a_cts_encl_sel = {
.data = &(struct clk_regmap_mux_data){
.offset = HHI_VIID_CLK_DIV,
.mask = 0xf,
.shift = 12,
.table = mux_table_cts_sel,
},
.hw.init = &(struct clk_init_data){
.name = "cts_encl_sel",
.ops = &clk_regmap_mux_ops,
.parent_hws = g12a_cts_parent_hws,
.num_parents = ARRAY_SIZE(g12a_cts_parent_hws),
.flags = CLK_SET_RATE_NO_REPARENT | CLK_GET_RATE_NOCACHE,
},
};
static struct clk_regmap g12a_cts_vdac_sel = {
.data = &(struct clk_regmap_mux_data){
.offset = HHI_VIID_CLK_DIV,
......@@ -3628,6 +3644,22 @@ static struct clk_regmap g12a_cts_encp = {
},
};
static struct clk_regmap g12a_cts_encl = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_VID_CLK_CNTL2,
.bit_idx = 3,
},
.hw.init = &(struct clk_init_data) {
.name = "cts_encl",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12a_cts_encl_sel.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
},
};
static struct clk_regmap g12a_cts_vdac = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_VID_CLK_CNTL2,
......@@ -3722,6 +3754,66 @@ static struct clk_regmap g12a_mipi_dsi_pxclk = {
},
};
/* MIPI ISP Clocks */
static const struct clk_parent_data g12b_mipi_isp_parent_data[] = {
{ .fw_name = "xtal", },
{ .hw = &g12a_gp0_pll.hw },
{ .hw = &g12a_hifi_pll.hw },
{ .hw = &g12a_fclk_div2p5.hw },
{ .hw = &g12a_fclk_div3.hw },
{ .hw = &g12a_fclk_div4.hw },
{ .hw = &g12a_fclk_div5.hw },
{ .hw = &g12a_fclk_div7.hw },
};
static struct clk_regmap g12b_mipi_isp_sel = {
.data = &(struct clk_regmap_mux_data){
.offset = HHI_ISP_CLK_CNTL,
.mask = 7,
.shift = 9,
},
.hw.init = &(struct clk_init_data){
.name = "mipi_isp_sel",
.ops = &clk_regmap_mux_ops,
.parent_data = g12b_mipi_isp_parent_data,
.num_parents = ARRAY_SIZE(g12b_mipi_isp_parent_data),
},
};
static struct clk_regmap g12b_mipi_isp_div = {
.data = &(struct clk_regmap_div_data){
.offset = HHI_ISP_CLK_CNTL,
.shift = 0,
.width = 7,
},
.hw.init = &(struct clk_init_data){
.name = "mipi_isp_div",
.ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12b_mipi_isp_sel.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap g12b_mipi_isp = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_ISP_CLK_CNTL,
.bit_idx = 8,
},
.hw.init = &(struct clk_init_data) {
.name = "mipi_isp",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) {
&g12b_mipi_isp_div.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
/* HDMI Clocks */
static const struct clk_parent_data g12a_hdmi_parent_data[] = {
......@@ -4214,9 +4306,12 @@ static MESON_GATE(g12a_htx_hdcp22, HHI_GCLK_MPEG2, 3);
static MESON_GATE(g12a_htx_pclk, HHI_GCLK_MPEG2, 4);
static MESON_GATE(g12a_bt656, HHI_GCLK_MPEG2, 6);
static MESON_GATE(g12a_usb1_to_ddr, HHI_GCLK_MPEG2, 8);
static MESON_GATE(g12b_mipi_isp_gate, HHI_GCLK_MPEG2, 17);
static MESON_GATE(g12a_mmc_pclk, HHI_GCLK_MPEG2, 11);
static MESON_GATE(g12a_uart2, HHI_GCLK_MPEG2, 15);
static MESON_GATE(g12a_vpu_intr, HHI_GCLK_MPEG2, 25);
static MESON_GATE(g12b_csi_phy1, HHI_GCLK_MPEG2, 28);
static MESON_GATE(g12b_csi_phy0, HHI_GCLK_MPEG2, 29);
static MESON_GATE(g12a_gic, HHI_GCLK_MPEG2, 30);
static MESON_GATE(g12a_vclk2_venci0, HHI_GCLK_OTHER, 1);
......@@ -4407,10 +4502,12 @@ static struct clk_hw *g12a_hw_clks[] = {
[CLKID_VCLK2_DIV12] = &g12a_vclk2_div12.hw,
[CLKID_CTS_ENCI_SEL] = &g12a_cts_enci_sel.hw,
[CLKID_CTS_ENCP_SEL] = &g12a_cts_encp_sel.hw,
[CLKID_CTS_ENCL_SEL] = &g12a_cts_encl_sel.hw,
[CLKID_CTS_VDAC_SEL] = &g12a_cts_vdac_sel.hw,
[CLKID_HDMI_TX_SEL] = &g12a_hdmi_tx_sel.hw,
[CLKID_CTS_ENCI] = &g12a_cts_enci.hw,
[CLKID_CTS_ENCP] = &g12a_cts_encp.hw,
[CLKID_CTS_ENCL] = &g12a_cts_encl.hw,
[CLKID_CTS_VDAC] = &g12a_cts_vdac.hw,
[CLKID_HDMI_TX] = &g12a_hdmi_tx.hw,
[CLKID_HDMI_SEL] = &g12a_hdmi_sel.hw,
......@@ -4632,10 +4729,12 @@ static struct clk_hw *g12b_hw_clks[] = {
[CLKID_VCLK2_DIV12] = &g12a_vclk2_div12.hw,
[CLKID_CTS_ENCI_SEL] = &g12a_cts_enci_sel.hw,
[CLKID_CTS_ENCP_SEL] = &g12a_cts_encp_sel.hw,
[CLKID_CTS_ENCL_SEL] = &g12a_cts_encl_sel.hw,
[CLKID_CTS_VDAC_SEL] = &g12a_cts_vdac_sel.hw,
[CLKID_HDMI_TX_SEL] = &g12a_hdmi_tx_sel.hw,
[CLKID_CTS_ENCI] = &g12a_cts_enci.hw,
[CLKID_CTS_ENCP] = &g12a_cts_encp.hw,
[CLKID_CTS_ENCL] = &g12a_cts_encl.hw,
[CLKID_CTS_VDAC] = &g12a_cts_vdac.hw,
[CLKID_HDMI_TX] = &g12a_hdmi_tx.hw,
[CLKID_HDMI_SEL] = &g12a_hdmi_sel.hw,
......@@ -4729,6 +4828,12 @@ static struct clk_hw *g12b_hw_clks[] = {
[CLKID_MIPI_DSI_PXCLK_SEL] = &g12a_mipi_dsi_pxclk_sel.hw,
[CLKID_MIPI_DSI_PXCLK_DIV] = &g12a_mipi_dsi_pxclk_div.hw,
[CLKID_MIPI_DSI_PXCLK] = &g12a_mipi_dsi_pxclk.hw,
[CLKID_MIPI_ISP_SEL] = &g12b_mipi_isp_sel.hw,
[CLKID_MIPI_ISP_DIV] = &g12b_mipi_isp_div.hw,
[CLKID_MIPI_ISP] = &g12b_mipi_isp.hw,
[CLKID_MIPI_ISP_GATE] = &g12b_mipi_isp_gate.hw,
[CLKID_MIPI_ISP_CSI_PHY0] = &g12b_csi_phy0.hw,
[CLKID_MIPI_ISP_CSI_PHY1] = &g12b_csi_phy1.hw,
};
static struct clk_hw *sm1_hw_clks[] = {
......@@ -4892,10 +4997,12 @@ static struct clk_hw *sm1_hw_clks[] = {
[CLKID_VCLK2_DIV12] = &g12a_vclk2_div12.hw,
[CLKID_CTS_ENCI_SEL] = &g12a_cts_enci_sel.hw,
[CLKID_CTS_ENCP_SEL] = &g12a_cts_encp_sel.hw,
[CLKID_CTS_ENCL_SEL] = &g12a_cts_encl_sel.hw,
[CLKID_CTS_VDAC_SEL] = &g12a_cts_vdac_sel.hw,
[CLKID_HDMI_TX_SEL] = &g12a_hdmi_tx_sel.hw,
[CLKID_CTS_ENCI] = &g12a_cts_enci.hw,
[CLKID_CTS_ENCP] = &g12a_cts_encp.hw,
[CLKID_CTS_ENCL] = &g12a_cts_encl.hw,
[CLKID_CTS_VDAC] = &g12a_cts_vdac.hw,
[CLKID_HDMI_TX] = &g12a_hdmi_tx.hw,
[CLKID_HDMI_SEL] = &g12a_hdmi_sel.hw,
......@@ -5123,10 +5230,12 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
&g12a_vclk2_div12_en,
&g12a_cts_enci_sel,
&g12a_cts_encp_sel,
&g12a_cts_encl_sel,
&g12a_cts_vdac_sel,
&g12a_hdmi_tx_sel,
&g12a_cts_enci,
&g12a_cts_encp,
&g12a_cts_encl,
&g12a_cts_vdac,
&g12a_hdmi_tx,
&g12a_hdmi_sel,
......@@ -5221,6 +5330,12 @@ static struct clk_regmap *const g12a_clk_regmaps[] = {
&g12a_mipi_dsi_pxclk_sel,
&g12a_mipi_dsi_pxclk_div,
&g12a_mipi_dsi_pxclk,
&g12b_mipi_isp_sel,
&g12b_mipi_isp_div,
&g12b_mipi_isp,
&g12b_mipi_isp_gate,
&g12b_csi_phy1,
&g12b_csi_phy0,
};
static const struct reg_sequence g12a_init_regs[] = {
......
......@@ -70,6 +70,7 @@
#define HHI_MALI_CLK_CNTL 0x1b0
#define HHI_VPU_CLKC_CNTL 0x1b4
#define HHI_VPU_CLK_CNTL 0x1bC
#define HHI_ISP_CLK_CNTL 0x1C0
#define HHI_NNA_CLK_CNTL 0x1C8
#define HHI_HDMI_CLK_CNTL 0x1CC
#define HHI_VDEC_CLK_CNTL 0x1E0
......
......@@ -4,8 +4,8 @@
*
* Copyright (C) 2022 Microchip Technology Inc. and its subsidiaries
*/
#include "asm-generic/errno-base.h"
#include <linux/clk-provider.h>
#include <linux/errno.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/platform_device.h>
......
......@@ -308,18 +308,21 @@ static void __init pxa168_clk_init(struct device_node *np)
pxa_unit->mpmu_base = of_iomap(np, 0);
if (!pxa_unit->mpmu_base) {
pr_err("failed to map mpmu registers\n");
kfree(pxa_unit);
return;
}
pxa_unit->apmu_base = of_iomap(np, 1);
if (!pxa_unit->apmu_base) {
pr_err("failed to map apmu registers\n");
kfree(pxa_unit);
return;
}
pxa_unit->apbc_base = of_iomap(np, 2);
if (!pxa_unit->apbc_base) {
pr_err("failed to map apbc registers\n");
kfree(pxa_unit);
return;
}
......
......@@ -20,6 +20,16 @@ menuconfig COMMON_CLK_QCOM
if COMMON_CLK_QCOM
config CLK_X1E80100_GCC
tristate "X1E80100 Global Clock Controller"
depends on ARM64 || COMPILE_TEST
select QCOM_GDSC
help
Support for the global clock controller on Qualcomm Technologies, Inc
X1E80100 devices.
Say Y if you want to use peripheral devices such as UART, SPI, I2C,
USB, UFS, SD/eMMC, PCIe, etc.
config QCOM_A53PLL
tristate "MSM8916 A53 PLL"
help
......@@ -427,6 +437,15 @@ config SC_CAMCC_7280
Say Y if you want to support camera devices and functionality such as
capturing pictures.
config SC_CAMCC_8280XP
tristate "SC8280XP Camera Clock Controller"
select SC_GCC_8280XP
help
Support for the camera clock controller on Qualcomm Technologies, Inc
SC8280XP devices.
Say Y if you want to support camera devices and functionality such as
capturing pictures.
config SC_DISPCC_7180
tristate "SC7180 Display Clock Controller"
depends on ARM64 || COMPILE_TEST
......@@ -668,6 +687,15 @@ config QDU_GCC_1000
QRU1000 devices. Say Y if you want to use peripheral
devices such as UART, SPI, I2C, USB, SD, PCIe, etc.
config QDU_ECPRICC_1000
tristate "QDU1000/QRU1000 ECPRI Clock Controller"
depends on ARM64 || COMPILE_TEST
select QDU_GCC_1000
help
Support for the ECPRI clock controller on QDU1000 and
QRU1000 devices. Say Y if you want to support the ECPRI
clock controller functionality such as Ethernet.
config SDM_GCC_845
tristate "SDM845/SDM670 Global Clock Controller"
depends on ARM64 || COMPILE_TEST
......@@ -843,6 +871,16 @@ config SM_DISPCC_8550
Say Y if you want to support display devices and functionality such as
splash screen.
config SM_DISPCC_8650
tristate "SM8650 Display Clock Controller"
depends on ARM64 || COMPILE_TEST
select SM_GCC_8650
help
Support for the display clock controller on Qualcomm Technologies, Inc
SM8650 devices.
Say Y if you want to support display devices and functionality such as
splash screen.
config SM_GCC_4450
tristate "SM4450 Global Clock Controller"
depends on ARM64 || COMPILE_TEST
......@@ -939,6 +977,15 @@ config SM_GCC_8550
Say Y if you want to use peripheral devices such as UART,
SPI, I2C, USB, SD/UFS, PCIe etc.
config SM_GCC_8650
tristate "SM8650 Global Clock Controller"
depends on ARM64 || COMPILE_TEST
select QCOM_GDSC
help
Support for the global clock controller on SM8650 devices.
Say Y if you want to use peripheral devices such as UART,
SPI, I2C, USB, SD/UFS, PCIe etc.
config SM_GPUCC_6115
tristate "SM6115 Graphics Clock Controller"
select SM_GCC_6115
......@@ -1020,6 +1067,14 @@ config SM_GPUCC_8550
Say Y if you want to support graphics controller devices and
functionality such as 3D graphics.
config SM_GPUCC_8650
tristate "SM8650 Graphics Clock Controller"
select SM_GCC_8650
help
Support for the graphics clock controller on SM8650 devices.
Say Y if you want to support graphics controller devices and
functionality such as 3D graphics.
config SM_TCSRCC_8550
tristate "SM8550 TCSR Clock Controller"
depends on ARM64 || COMPILE_TEST
......@@ -1028,6 +1083,14 @@ config SM_TCSRCC_8550
Support for the TCSR clock controller on SM8550 devices.
Say Y if you want to use peripheral devices such as SD/UFS.
config SM_TCSRCC_8650
tristate "SM8650 TCSR Clock Controller"
depends on ARM64 || COMPILE_TEST
select QCOM_GDSC
help
Support for the TCSR clock controller on SM8650 devices.
Say Y if you want to use peripheral devices such as SD/UFS.
config SM_VIDEOCC_8150
tristate "SM8150 Video Clock Controller"
depends on ARM64 || COMPILE_TEST
......
......@@ -21,6 +21,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
obj-$(CONFIG_APQ_GCC_8084) += gcc-apq8084.o
obj-$(CONFIG_APQ_MMCC_8084) += mmcc-apq8084.o
obj-$(CONFIG_CLK_GFM_LPASS_SM8250) += lpass-gfm-sm8250.o
obj-$(CONFIG_CLK_X1E80100_GCC) += gcc-x1e80100.o
obj-$(CONFIG_IPQ_APSS_PLL) += apss-ipq-pll.o
obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
......@@ -65,9 +66,11 @@ obj-$(CONFIG_QCM_DISPCC_2290) += dispcc-qcm2290.o
obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o
obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o
obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
obj-$(CONFIG_QDU_ECPRICC_1000) += ecpricc-qdu1000.o
obj-$(CONFIG_QDU_GCC_1000) += gcc-qdu1000.o
obj-$(CONFIG_SC_CAMCC_7180) += camcc-sc7180.o
obj-$(CONFIG_SC_CAMCC_7280) += camcc-sc7280.o
obj-$(CONFIG_SC_CAMCC_8280XP) += camcc-sc8280xp.o
obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
obj-$(CONFIG_SC_DISPCC_7280) += dispcc-sc7280.o
obj-$(CONFIG_SC_DISPCC_8280XP) += dispcc-sc8280xp.o
......@@ -110,6 +113,7 @@ obj-$(CONFIG_SM_DISPCC_6375) += dispcc-sm6375.o
obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
obj-$(CONFIG_SM_DISPCC_8450) += dispcc-sm8450.o
obj-$(CONFIG_SM_DISPCC_8550) += dispcc-sm8550.o
obj-$(CONFIG_SM_DISPCC_8650) += dispcc-sm8650.o
obj-$(CONFIG_SM_GCC_4450) += gcc-sm4450.o
obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o
obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o
......@@ -121,6 +125,7 @@ obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o
obj-$(CONFIG_SM_GCC_8450) += gcc-sm8450.o
obj-$(CONFIG_SM_GCC_8550) += gcc-sm8550.o
obj-$(CONFIG_SM_GCC_8650) += gcc-sm8650.o
obj-$(CONFIG_SM_GPUCC_6115) += gpucc-sm6115.o
obj-$(CONFIG_SM_GPUCC_6125) += gpucc-sm6125.o
obj-$(CONFIG_SM_GPUCC_6350) += gpucc-sm6350.o
......@@ -130,7 +135,9 @@ obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o
obj-$(CONFIG_SM_GPUCC_8350) += gpucc-sm8350.o
obj-$(CONFIG_SM_GPUCC_8450) += gpucc-sm8450.o
obj-$(CONFIG_SM_GPUCC_8550) += gpucc-sm8550.o
obj-$(CONFIG_SM_GPUCC_8650) += gpucc-sm8650.o
obj-$(CONFIG_SM_TCSRCC_8550) += tcsrcc-sm8550.o
obj-$(CONFIG_SM_TCSRCC_8650) += tcsrcc-sm8650.o
obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o
obj-$(CONFIG_SM_VIDEOCC_8250) += videocc-sm8250.o
obj-$(CONFIG_SM_VIDEOCC_8350) += videocc-sm8350.o
......
......@@ -73,6 +73,20 @@ static struct clk_alpha_pll ipq_pll_stromer_plus = {
},
};
static const struct alpha_pll_config ipq5018_pll_config = {
.l = 0x32,
.config_ctl_val = 0x4001075b,
.config_ctl_hi_val = 0x304,
.main_output_mask = BIT(0),
.aux_output_mask = BIT(1),
.early_output_mask = BIT(3),
.alpha_en_mask = BIT(24),
.status_val = 0x3,
.status_mask = GENMASK(10, 8),
.lock_det = BIT(2),
.test_ctl_hi_val = 0x00400003,
};
static const struct alpha_pll_config ipq5332_pll_config = {
.l = 0x2d,
.config_ctl_val = 0x4001075b,
......@@ -129,6 +143,12 @@ struct apss_pll_data {
const struct alpha_pll_config *pll_config;
};
static const struct apss_pll_data ipq5018_pll_data = {
.pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
.pll = &ipq_pll_stromer_plus,
.pll_config = &ipq5018_pll_config,
};
static struct apss_pll_data ipq5332_pll_data = {
.pll_type = CLK_ALPHA_PLL_TYPE_STROMER_PLUS,
.pll = &ipq_pll_stromer_plus,
......@@ -195,6 +215,7 @@ static int apss_ipq_pll_probe(struct platform_device *pdev)
}
static const struct of_device_id apss_ipq_pll_match_table[] = {
{ .compatible = "qcom,ipq5018-a53pll", .data = &ipq5018_pll_data },
{ .compatible = "qcom,ipq5332-a53pll", .data = &ipq5332_pll_data },
{ .compatible = "qcom,ipq6018-a53pll", .data = &ipq6018_pll_data },
{ .compatible = "qcom,ipq8074-a53pll", .data = &ipq8074_pll_data },
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2013, The Linux Foundation. All rights reserved.
* Copyright (c) 2023, Qualcomm Innovation Center, Inc. All rights reserved.
*/
#include <linux/kernel.h>
......@@ -134,6 +135,43 @@ static void clk_branch2_disable(struct clk_hw *hw)
clk_branch_toggle(hw, false, clk_branch2_check_halt);
}
static int clk_branch2_mem_enable(struct clk_hw *hw)
{
struct clk_mem_branch *mem_br = to_clk_mem_branch(hw);
struct clk_branch branch = mem_br->branch;
u32 val;
int ret;
regmap_update_bits(branch.clkr.regmap, mem_br->mem_enable_reg,
mem_br->mem_enable_ack_mask, mem_br->mem_enable_ack_mask);
ret = regmap_read_poll_timeout(branch.clkr.regmap, mem_br->mem_ack_reg,
val, val & mem_br->mem_enable_ack_mask, 0, 200);
if (ret) {
WARN(1, "%s mem enable failed\n", clk_hw_get_name(&branch.clkr.hw));
return ret;
}
return clk_branch2_enable(hw);
}
static void clk_branch2_mem_disable(struct clk_hw *hw)
{
struct clk_mem_branch *mem_br = to_clk_mem_branch(hw);
regmap_update_bits(mem_br->branch.clkr.regmap, mem_br->mem_enable_reg,
mem_br->mem_enable_ack_mask, 0);
return clk_branch2_disable(hw);
}
const struct clk_ops clk_branch2_mem_ops = {
.enable = clk_branch2_mem_enable,
.disable = clk_branch2_mem_disable,
.is_enabled = clk_is_enabled_regmap,
};
EXPORT_SYMBOL_GPL(clk_branch2_mem_ops);
const struct clk_ops clk_branch2_ops = {
.enable = clk_branch2_enable,
.disable = clk_branch2_disable,
......
......@@ -38,6 +38,23 @@ struct clk_branch {
struct clk_regmap clkr;
};
/**
* struct clk_mem_branch - gating clock which are associated with memories
*
* @mem_enable_reg: branch clock memory gating register
* @mem_ack_reg: branch clock memory ack register
* @mem_enable_ack_mask: branch clock memory enable and ack field in @mem_ack_reg
* @branch: branch clock gating handle
*
* Clock which can gate its memories.
*/
struct clk_mem_branch {
u32 mem_enable_reg;
u32 mem_ack_reg;
u32 mem_enable_ack_mask;
struct clk_branch branch;
};
/* Branch clock common bits for HLOS-owned clocks */
#define CBCR_CLK_OFF BIT(31)
#define CBCR_NOC_FSM_STATUS GENMASK(30, 28)
......@@ -85,8 +102,12 @@ extern const struct clk_ops clk_branch_ops;
extern const struct clk_ops clk_branch2_ops;
extern const struct clk_ops clk_branch_simple_ops;
extern const struct clk_ops clk_branch2_aon_ops;
extern const struct clk_ops clk_branch2_mem_ops;
#define to_clk_branch(_hw) \
container_of(to_clk_regmap(_hw), struct clk_branch, clkr)
#define to_clk_mem_branch(_hw) \
container_of(to_clk_branch(_hw), struct clk_mem_branch, branch)
#endif
......@@ -372,6 +372,9 @@ DEFINE_CLK_RPMH_VRM(clk3, _a1, "clka3", 1);
DEFINE_CLK_RPMH_VRM(clk4, _a1, "clka4", 1);
DEFINE_CLK_RPMH_VRM(clk5, _a1, "clka5", 1);
DEFINE_CLK_RPMH_VRM(clk3, _a2, "clka3", 2);
DEFINE_CLK_RPMH_VRM(clk4, _a2, "clka4", 2);
DEFINE_CLK_RPMH_VRM(clk5, _a2, "clka5", 2);
DEFINE_CLK_RPMH_VRM(clk6, _a2, "clka6", 2);
DEFINE_CLK_RPMH_VRM(clk7, _a2, "clka7", 2);
DEFINE_CLK_RPMH_VRM(clk8, _a2, "clka8", 2);
......@@ -630,6 +633,37 @@ static const struct clk_rpmh_desc clk_rpmh_sm8550 = {
.num_clks = ARRAY_SIZE(sm8550_rpmh_clocks),
};
static struct clk_hw *sm8650_rpmh_clocks[] = {
[RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw,
[RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw,
[RPMH_LN_BB_CLK1] = &clk_rpmh_clk6_a2.hw,
[RPMH_LN_BB_CLK1_A] = &clk_rpmh_clk6_a2_ao.hw,
[RPMH_LN_BB_CLK2] = &clk_rpmh_clk7_a2.hw,
[RPMH_LN_BB_CLK2_A] = &clk_rpmh_clk7_a2_ao.hw,
[RPMH_LN_BB_CLK3] = &clk_rpmh_clk8_a2.hw,
[RPMH_LN_BB_CLK3_A] = &clk_rpmh_clk8_a2_ao.hw,
[RPMH_RF_CLK1] = &clk_rpmh_clk1_a1.hw,
[RPMH_RF_CLK1_A] = &clk_rpmh_clk1_a1_ao.hw,
[RPMH_RF_CLK2] = &clk_rpmh_clk2_a1.hw,
[RPMH_RF_CLK2_A] = &clk_rpmh_clk2_a1_ao.hw,
/*
* The clka3 RPMh resource is missing in cmd-db
* for current platforms, while the clka3 exists
* on the PMK8550, the clock is unconnected and
* unused.
*/
[RPMH_RF_CLK4] = &clk_rpmh_clk4_a2.hw,
[RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a2_ao.hw,
[RPMH_RF_CLK5] = &clk_rpmh_clk5_a2.hw,
[RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_ao.hw,
[RPMH_IPA_CLK] = &clk_rpmh_ipa.hw,
};
static const struct clk_rpmh_desc clk_rpmh_sm8650 = {
.clks = sm8650_rpmh_clocks,
.num_clks = ARRAY_SIZE(sm8650_rpmh_clocks),
};
static struct clk_hw *sc7280_rpmh_clocks[] = {
[RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div4.hw,
[RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div4_ao.hw,
......@@ -737,6 +771,28 @@ static const struct clk_rpmh_desc clk_rpmh_sm4450 = {
.num_clks = ARRAY_SIZE(sm4450_rpmh_clocks),
};
static struct clk_hw *x1e80100_rpmh_clocks[] = {
[RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div2.hw,
[RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div2_ao.hw,
[RPMH_LN_BB_CLK1] = &clk_rpmh_clk6_a2.hw,
[RPMH_LN_BB_CLK1_A] = &clk_rpmh_clk6_a2_ao.hw,
[RPMH_LN_BB_CLK2] = &clk_rpmh_clk7_a2.hw,
[RPMH_LN_BB_CLK2_A] = &clk_rpmh_clk7_a2_ao.hw,
[RPMH_LN_BB_CLK3] = &clk_rpmh_clk8_a2.hw,
[RPMH_LN_BB_CLK3_A] = &clk_rpmh_clk8_a2_ao.hw,
[RPMH_RF_CLK3] = &clk_rpmh_clk3_a2.hw,
[RPMH_RF_CLK3_A] = &clk_rpmh_clk3_a2_ao.hw,
[RPMH_RF_CLK4] = &clk_rpmh_clk4_a2.hw,
[RPMH_RF_CLK4_A] = &clk_rpmh_clk4_a2_ao.hw,
[RPMH_RF_CLK5] = &clk_rpmh_clk5_a2.hw,
[RPMH_RF_CLK5_A] = &clk_rpmh_clk5_a2_ao.hw,
};
static const struct clk_rpmh_desc clk_rpmh_x1e80100 = {
.clks = x1e80100_rpmh_clocks,
.num_clks = ARRAY_SIZE(x1e80100_rpmh_clocks),
};
static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
void *data)
{
......@@ -837,7 +893,9 @@ static const struct of_device_id clk_rpmh_match_table[] = {
{ .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350},
{ .compatible = "qcom,sm8450-rpmh-clk", .data = &clk_rpmh_sm8450},
{ .compatible = "qcom,sm8550-rpmh-clk", .data = &clk_rpmh_sm8550},
{ .compatible = "qcom,sm8650-rpmh-clk", .data = &clk_rpmh_sm8650},
{ .compatible = "qcom,sc7280-rpmh-clk", .data = &clk_rpmh_sc7280},
{ .compatible = "qcom,x1e80100-rpmh-clk", .data = &clk_rpmh_x1e80100},
{ }
};
MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
......
......@@ -81,6 +81,10 @@ static const struct alpha_pll_config disp_cc_pll0_config = {
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00182261,
.config_ctl_hi1_val = 0x82aa299c,
.test_ctl_val = 0x00000000,
.test_ctl_hi_val = 0x00000003,
.test_ctl_hi1_val = 0x00009000,
.test_ctl_hi2_val = 0x00000034,
.user_ctl_val = 0x00000000,
.user_ctl_hi_val = 0x00000005,
};
......@@ -108,6 +112,10 @@ static const struct alpha_pll_config disp_cc_pll1_config = {
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00182261,
.config_ctl_hi1_val = 0x82aa299c,
.test_ctl_val = 0x00000000,
.test_ctl_hi_val = 0x00000003,
.test_ctl_hi1_val = 0x00009000,
.test_ctl_hi2_val = 0x00000034,
.user_ctl_val = 0x00000000,
.user_ctl_hi_val = 0x00000005,
};
......@@ -1766,8 +1774,8 @@ static int disp_cc_sm8550_probe(struct platform_device *pdev)
goto err_put_rpm;
}
clk_lucid_evo_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
clk_lucid_evo_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
clk_lucid_ole_pll_configure(&disp_cc_pll0, regmap, &disp_cc_pll0_config);
clk_lucid_ole_pll_configure(&disp_cc_pll1, regmap, &disp_cc_pll1_config);
/* Enable clock gating for MDP clocks */
regmap_update_bits(regmap, DISP_CC_MISC_CMD, 0x10, 0x10);
......
This diff is collapsed.
This diff is collapsed.
......@@ -696,7 +696,7 @@ static struct clk_rcg2 apss_ahb_clk_src = {
},
};
static const struct freq_tbl ftbl_gcc_camss_csi0_1_clk[] = {
static const struct freq_tbl ftbl_gcc_camss_csi0_1_2_clk[] = {
F(100000000, P_GPLL0, 8, 0, 0),
F(200000000, P_GPLL0, 4, 0, 0),
{ }
......@@ -706,7 +706,7 @@ static struct clk_rcg2 csi0_clk_src = {
.cmd_rcgr = 0x4e020,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_map,
.freq_tbl = ftbl_gcc_camss_csi0_1_clk,
.freq_tbl = ftbl_gcc_camss_csi0_1_2_clk,
.clkr.hw.init = &(struct clk_init_data){
.name = "csi0_clk_src",
.parent_data = gcc_xo_gpll0_parent_data,
......@@ -719,7 +719,7 @@ static struct clk_rcg2 csi1_clk_src = {
.cmd_rcgr = 0x4f020,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_map,
.freq_tbl = ftbl_gcc_camss_csi0_1_clk,
.freq_tbl = ftbl_gcc_camss_csi0_1_2_clk,
.clkr.hw.init = &(struct clk_init_data){
.name = "csi1_clk_src",
.parent_data = gcc_xo_gpll0_parent_data,
......@@ -728,6 +728,19 @@ static struct clk_rcg2 csi1_clk_src = {
},
};
static struct clk_rcg2 csi2_clk_src = {
.cmd_rcgr = 0x3c020,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_map,
.freq_tbl = ftbl_gcc_camss_csi0_1_2_clk,
.clkr.hw.init = &(struct clk_init_data){
.name = "csi2_clk_src",
.parent_data = gcc_xo_gpll0_parent_data,
.num_parents = ARRAY_SIZE(gcc_xo_gpll0_parent_data),
.ops = &clk_rcg2_ops,
},
};
static const struct freq_tbl ftbl_gcc_oxili_gfx3d_clk[] = {
F(19200000, P_XO, 1, 0, 0),
F(50000000, P_GPLL0, 16, 0, 0),
......@@ -2385,6 +2398,91 @@ static struct clk_branch gcc_camss_csi1rdi_clk = {
},
};
static struct clk_branch gcc_camss_csi2_ahb_clk = {
.halt_reg = 0x3c040,
.clkr = {
.enable_reg = 0x3c040,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camss_csi2_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&camss_ahb_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_camss_csi2_clk = {
.halt_reg = 0x3c03c,
.clkr = {
.enable_reg = 0x3c03c,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camss_csi2_clk",
.parent_hws = (const struct clk_hw*[]){
&csi2_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_camss_csi2phy_clk = {
.halt_reg = 0x3c048,
.clkr = {
.enable_reg = 0x3c048,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camss_csi2phy_clk",
.parent_hws = (const struct clk_hw*[]){
&csi2_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_camss_csi2pix_clk = {
.halt_reg = 0x3c058,
.clkr = {
.enable_reg = 0x3c058,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camss_csi2pix_clk",
.parent_hws = (const struct clk_hw*[]){
&csi2_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_camss_csi2rdi_clk = {
.halt_reg = 0x3c050,
.clkr = {
.enable_reg = 0x3c050,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_camss_csi2rdi_clk",
.parent_hws = (const struct clk_hw*[]){
&csi2_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_camss_csi_vfe0_clk = {
.halt_reg = 0x58050,
.clkr = {
......@@ -3682,6 +3780,7 @@ static struct clk_regmap *gcc_msm8939_clocks[] = {
[APSS_AHB_CLK_SRC] = &apss_ahb_clk_src.clkr,
[CSI0_CLK_SRC] = &csi0_clk_src.clkr,
[CSI1_CLK_SRC] = &csi1_clk_src.clkr,
[CSI2_CLK_SRC] = &csi2_clk_src.clkr,
[GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
[VFE0_CLK_SRC] = &vfe0_clk_src.clkr,
[BLSP1_QUP1_I2C_APPS_CLK_SRC] = &blsp1_qup1_i2c_apps_clk_src.clkr,
......@@ -3751,6 +3850,11 @@ static struct clk_regmap *gcc_msm8939_clocks[] = {
[GCC_CAMSS_CSI1PHY_CLK] = &gcc_camss_csi1phy_clk.clkr,
[GCC_CAMSS_CSI1PIX_CLK] = &gcc_camss_csi1pix_clk.clkr,
[GCC_CAMSS_CSI1RDI_CLK] = &gcc_camss_csi1rdi_clk.clkr,
[GCC_CAMSS_CSI2_AHB_CLK] = &gcc_camss_csi2_ahb_clk.clkr,
[GCC_CAMSS_CSI2_CLK] = &gcc_camss_csi2_clk.clkr,
[GCC_CAMSS_CSI2PHY_CLK] = &gcc_camss_csi2phy_clk.clkr,
[GCC_CAMSS_CSI2PIX_CLK] = &gcc_camss_csi2pix_clk.clkr,
[GCC_CAMSS_CSI2RDI_CLK] = &gcc_camss_csi2rdi_clk.clkr,
[GCC_CAMSS_CSI_VFE0_CLK] = &gcc_camss_csi_vfe0_clk.clkr,
[GCC_CAMSS_GP0_CLK] = &gcc_camss_gp0_clk.clkr,
[GCC_CAMSS_GP1_CLK] = &gcc_camss_gp1_clk.clkr,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -37,8 +37,8 @@ static struct alpha_pll_config gpu_cc_pll1_config = {
.config_ctl_hi_val = 0x00002267,
.config_ctl_hi1_val = 0x00000024,
.test_ctl_val = 0x00000000,
.test_ctl_hi_val = 0x00000002,
.test_ctl_hi1_val = 0x00000000,
.test_ctl_hi_val = 0x00000000,
.test_ctl_hi1_val = 0x00000020,
.user_ctl_val = 0x00000000,
.user_ctl_hi_val = 0x00000805,
.user_ctl_hi1_val = 0x000000d0,
......
......@@ -35,12 +35,12 @@ enum {
};
static const struct pll_vco lucid_ole_vco[] = {
{ 249600000, 2300000000, 0 },
{ 249600000, 2000000000, 0 },
};
static const struct alpha_pll_config gpu_cc_pll0_config = {
.l = 0x0d,
.alpha = 0x0,
.l = 0x1e,
.alpha = 0xbaaa,
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00182261,
.config_ctl_hi1_val = 0x82aa299c,
......
This diff is collapsed.
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
* Copyright (c) 2022, Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2023, Linaro Limited
*/
#include <linux/clk-provider.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,sm8650-tcsr.h>
#include "clk-branch.h"
#include "clk-regmap.h"
#include "common.h"
#include "reset.h"
enum {
DT_BI_TCXO_PAD,
};
static struct clk_branch tcsr_pcie_0_clkref_en = {
.halt_reg = 0x31100,
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x31100,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "tcsr_pcie_0_clkref_en",
.parent_data = &(const struct clk_parent_data){
.index = DT_BI_TCXO_PAD,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch tcsr_pcie_1_clkref_en = {
.halt_reg = 0x31114,
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x31114,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "tcsr_pcie_1_clkref_en",
.parent_data = &(const struct clk_parent_data){
.index = DT_BI_TCXO_PAD,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch tcsr_ufs_clkref_en = {
.halt_reg = 0x31110,
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x31110,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "tcsr_ufs_clkref_en",
.parent_data = &(const struct clk_parent_data){
.index = DT_BI_TCXO_PAD,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch tcsr_ufs_pad_clkref_en = {
.halt_reg = 0x31104,
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x31104,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "tcsr_ufs_pad_clkref_en",
.parent_data = &(const struct clk_parent_data){
.index = DT_BI_TCXO_PAD,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch tcsr_usb2_clkref_en = {
.halt_reg = 0x31118,
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x31118,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "tcsr_usb2_clkref_en",
.parent_data = &(const struct clk_parent_data){
.index = DT_BI_TCXO_PAD,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch tcsr_usb3_clkref_en = {
.halt_reg = 0x31108,
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x31108,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "tcsr_usb3_clkref_en",
.parent_data = &(const struct clk_parent_data){
.index = DT_BI_TCXO_PAD,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_regmap *tcsr_cc_sm8650_clocks[] = {
[TCSR_PCIE_0_CLKREF_EN] = &tcsr_pcie_0_clkref_en.clkr,
[TCSR_PCIE_1_CLKREF_EN] = &tcsr_pcie_1_clkref_en.clkr,
[TCSR_UFS_CLKREF_EN] = &tcsr_ufs_clkref_en.clkr,
[TCSR_UFS_PAD_CLKREF_EN] = &tcsr_ufs_pad_clkref_en.clkr,
[TCSR_USB2_CLKREF_EN] = &tcsr_usb2_clkref_en.clkr,
[TCSR_USB3_CLKREF_EN] = &tcsr_usb3_clkref_en.clkr,
};
static const struct regmap_config tcsr_cc_sm8650_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = 0x3b000,
.fast_io = true,
};
static const struct qcom_cc_desc tcsr_cc_sm8650_desc = {
.config = &tcsr_cc_sm8650_regmap_config,
.clks = tcsr_cc_sm8650_clocks,
.num_clks = ARRAY_SIZE(tcsr_cc_sm8650_clocks),
};
static const struct of_device_id tcsr_cc_sm8650_match_table[] = {
{ .compatible = "qcom,sm8650-tcsr" },
{ }
};
MODULE_DEVICE_TABLE(of, tcsr_cc_sm8650_match_table);
static int tcsr_cc_sm8650_probe(struct platform_device *pdev)
{
return qcom_cc_probe(pdev, &tcsr_cc_sm8650_desc);
}
static struct platform_driver tcsr_cc_sm8650_driver = {
.probe = tcsr_cc_sm8650_probe,
.driver = {
.name = "tcsr_cc-sm8650",
.of_match_table = tcsr_cc_sm8650_match_table,
},
};
static int __init tcsr_cc_sm8650_init(void)
{
return platform_driver_register(&tcsr_cc_sm8650_driver);
}
subsys_initcall(tcsr_cc_sm8650_init);
static void __exit tcsr_cc_sm8650_exit(void)
{
platform_driver_unregister(&tcsr_cc_sm8650_driver);
}
module_exit(tcsr_cc_sm8650_exit);
MODULE_DESCRIPTION("QTI TCSRCC SM8650 Driver");
MODULE_LICENSE("GPL");
......@@ -6,6 +6,7 @@
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,videocc-sm8150.h>
......@@ -33,6 +34,7 @@ static struct alpha_pll_config video_pll0_config = {
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00002267,
.config_ctl_hi1_val = 0x00000024,
.test_ctl_hi1_val = 0x00000020,
.user_ctl_val = 0x00000000,
.user_ctl_hi_val = 0x00000805,
.user_ctl_hi1_val = 0x000000D0,
......@@ -214,6 +216,10 @@ static const struct regmap_config video_cc_sm8150_regmap_config = {
static const struct qcom_reset_map video_cc_sm8150_resets[] = {
[VIDEO_CC_MVSC_CORE_CLK_BCR] = { 0x850, 2 },
[VIDEO_CC_INTERFACE_BCR] = { 0x8f0 },
[VIDEO_CC_MVS0_BCR] = { 0x870 },
[VIDEO_CC_MVS1_BCR] = { 0x8b0 },
[VIDEO_CC_MVSC_BCR] = { 0x810 },
};
static const struct qcom_cc_desc video_cc_sm8150_desc = {
......@@ -235,17 +241,32 @@ MODULE_DEVICE_TABLE(of, video_cc_sm8150_match_table);
static int video_cc_sm8150_probe(struct platform_device *pdev)
{
struct regmap *regmap;
int ret;
ret = devm_pm_runtime_enable(&pdev->dev);
if (ret)
return ret;
ret = pm_runtime_resume_and_get(&pdev->dev);
if (ret)
return ret;
regmap = qcom_cc_map(pdev, &video_cc_sm8150_desc);
if (IS_ERR(regmap))
if (IS_ERR(regmap)) {
pm_runtime_put_sync(&pdev->dev);
return PTR_ERR(regmap);
}
clk_trion_pll_configure(&video_pll0, regmap, &video_pll0_config);
/* Keep VIDEO_CC_XO_CLK ALWAYS-ON */
regmap_update_bits(regmap, 0x984, 0x1, 0x1);
return qcom_cc_really_probe(pdev, &video_cc_sm8150_desc, regmap);
ret = qcom_cc_really_probe(pdev, &video_cc_sm8150_desc, regmap);
pm_runtime_put_sync(&pdev->dev);
return ret;
}
static struct platform_driver video_cc_sm8150_driver = {
......
......@@ -192,6 +192,8 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
DEF_MOD("msi3", 621, R8A779G0_CLK_MSO),
DEF_MOD("msi4", 622, R8A779G0_CLK_MSO),
DEF_MOD("msi5", 623, R8A779G0_CLK_MSO),
DEF_MOD("pciec0", 624, R8A779G0_CLK_S0D2_HSC),
DEF_MOD("pscie1", 625, R8A779G0_CLK_S0D2_HSC),
DEF_MOD("pwm", 628, R8A779G0_CLK_SASYNCPERD4),
DEF_MOD("rpc-if", 629, R8A779G0_CLK_RPCD2),
DEF_MOD("scif0", 702, R8A779G0_CLK_SASYNCPERD4),
......@@ -235,6 +237,7 @@ static const struct mssr_mod_clk r8a779g0_mod_clks[] __initconst = {
DEF_MOD("pfc2", 917, R8A779G0_CLK_CL16M),
DEF_MOD("pfc3", 918, R8A779G0_CLK_CL16M),
DEF_MOD("tsc", 919, R8A779G0_CLK_CL16M),
DEF_MOD("tsn", 2723, R8A779G0_CLK_S0D4_HSC),
DEF_MOD("ssiu", 2926, R8A779G0_CLK_S0D6_PER),
DEF_MOD("ssi", 2927, R8A779G0_CLK_S0D6_PER),
};
......
......@@ -181,13 +181,16 @@ static const struct cpg_core_clk r9a08g045_core_clks[] __initconst = {
DEF_G3S_DIV("P3", R9A08G045_CLK_P3, CLK_PLL3_DIV2_4, DIVPL3C, G3S_DIVPL3C_STS,
dtable_1_32, 0, 0, 0, NULL),
DEF_FIXED("P3_DIV2", CLK_P3_DIV2, R9A08G045_CLK_P3, 1, 2),
DEF_FIXED("ZT", R9A08G045_CLK_ZT, CLK_PLL3_DIV2_8, 1, 1),
DEF_FIXED("S0", R9A08G045_CLK_S0, CLK_SEL_PLL4, 1, 2),
DEF_FIXED("OSC", R9A08G045_OSCCLK, CLK_EXTAL, 1, 1),
DEF_FIXED("OSC2", R9A08G045_OSCCLK2, CLK_EXTAL, 1, 3),
DEF_FIXED("HP", R9A08G045_CLK_HP, CLK_PLL6, 1, 2),
};
static const struct rzg2l_mod_clk r9a08g045_mod_clks[] = {
DEF_MOD("gic_gicclk", R9A08G045_GIC600_GICCLK, R9A08G045_CLK_P1, 0x514, 0),
DEF_MOD("ia55_pclk", R9A08G045_IA55_PCLK, R9A08G045_CLK_P2, 0x518, 0),
DEF_MOD("ia55_clk", R9A08G045_IA55_CLK, R9A08G045_CLK_P1, 0x518, 1),
DEF_MOD("dmac_aclk", R9A08G045_DMAC_ACLK, R9A08G045_CLK_P3, 0x52c, 0),
DEF_MOD("sdhi0_imclk", R9A08G045_SDHI0_IMCLK, CLK_SD0_DIV4, 0x554, 0),
......@@ -202,6 +205,12 @@ static const struct rzg2l_mod_clk r9a08g045_mod_clks[] = {
DEF_MOD("sdhi2_imclk2", R9A08G045_SDHI2_IMCLK2, CLK_SD2_DIV4, 0x554, 9),
DEF_MOD("sdhi2_clk_hs", R9A08G045_SDHI2_CLK_HS, R9A08G045_CLK_SD2, 0x554, 10),
DEF_MOD("sdhi2_aclk", R9A08G045_SDHI2_ACLK, R9A08G045_CLK_P1, 0x554, 11),
DEF_COUPLED("eth0_axi", R9A08G045_ETH0_CLK_AXI, R9A08G045_CLK_M0, 0x57c, 0),
DEF_COUPLED("eth0_chi", R9A08G045_ETH0_CLK_CHI, R9A08G045_CLK_ZT, 0x57c, 0),
DEF_MOD("eth0_refclk", R9A08G045_ETH0_REFCLK, R9A08G045_CLK_HP, 0x57c, 8),
DEF_COUPLED("eth1_axi", R9A08G045_ETH1_CLK_AXI, R9A08G045_CLK_M0, 0x57c, 1),
DEF_COUPLED("eth1_chi", R9A08G045_ETH1_CLK_CHI, R9A08G045_CLK_ZT, 0x57c, 1),
DEF_MOD("eth1_refclk", R9A08G045_ETH1_REFCLK, R9A08G045_CLK_HP, 0x57c, 9),
DEF_MOD("scif0_clk_pck", R9A08G045_SCIF0_CLK_PCK, R9A08G045_CLK_P0, 0x584, 0),
DEF_MOD("gpio_hclk", R9A08G045_GPIO_HCLK, R9A08G045_OSCCLK, 0x598, 0),
};
......@@ -209,9 +218,12 @@ static const struct rzg2l_mod_clk r9a08g045_mod_clks[] = {
static const struct rzg2l_reset r9a08g045_resets[] = {
DEF_RST(R9A08G045_GIC600_GICRESET_N, 0x814, 0),
DEF_RST(R9A08G045_GIC600_DBG_GICRESET_N, 0x814, 1),
DEF_RST(R9A08G045_IA55_RESETN, 0x818, 0),
DEF_RST(R9A08G045_SDHI0_IXRST, 0x854, 0),
DEF_RST(R9A08G045_SDHI1_IXRST, 0x854, 1),
DEF_RST(R9A08G045_SDHI2_IXRST, 0x854, 2),
DEF_RST(R9A08G045_ETH0_RST_HW_N, 0x87c, 0),
DEF_RST(R9A08G045_ETH1_RST_HW_N, 0x87c, 1),
DEF_RST(R9A08G045_SCIF0_RST_SYSTEM_N, 0x884, 0),
DEF_RST(R9A08G045_GPIO_RSTN, 0x898, 0),
DEF_RST(R9A08G045_GPIO_PORT_RESETN, 0x898, 1),
......@@ -220,6 +232,7 @@ static const struct rzg2l_reset r9a08g045_resets[] = {
static const unsigned int r9a08g045_crit_mod_clks[] __initconst = {
MOD_CLK_BASE + R9A08G045_GIC600_GICCLK,
MOD_CLK_BASE + R9A08G045_IA55_PCLK,
MOD_CLK_BASE + R9A08G045_IA55_CLK,
MOD_CLK_BASE + R9A08G045_DMAC_ACLK,
};
......
......@@ -1410,41 +1410,33 @@ rzg2l_cpg_register_mod_clk(const struct rzg2l_mod_clk *mod,
#define rcdev_to_priv(x) container_of(x, struct rzg2l_cpg_priv, rcdev)
static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
const struct rzg2l_cpg_info *info = priv->info;
unsigned int reg = info->resets[id].off;
u32 dis = BIT(info->resets[id].bit);
u32 we = dis << 16;
dev_dbg(rcdev->dev, "reset id:%ld offset:0x%x\n", id, CLK_RST_R(reg));
/* Reset module */
writel(we, priv->base + CLK_RST_R(reg));
/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
udelay(35);
/* Release module from reset state */
writel(we | dis, priv->base + CLK_RST_R(reg));
return 0;
}
static int rzg2l_cpg_assert(struct reset_controller_dev *rcdev,
unsigned long id)
{
struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
const struct rzg2l_cpg_info *info = priv->info;
unsigned int reg = info->resets[id].off;
u32 value = BIT(info->resets[id].bit) << 16;
u32 mask = BIT(info->resets[id].bit);
s8 monbit = info->resets[id].monbit;
u32 value = mask << 16;
dev_dbg(rcdev->dev, "assert id:%ld offset:0x%x\n", id, CLK_RST_R(reg));
writel(value, priv->base + CLK_RST_R(reg));
return 0;
if (info->has_clk_mon_regs) {
reg = CLK_MRST_R(reg);
} else if (monbit >= 0) {
reg = CPG_RST_MON;
mask = BIT(monbit);
} else {
/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
udelay(35);
return 0;
}
return readl_poll_timeout_atomic(priv->base + reg, value,
value & mask, 10, 200);
}
static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev,
......@@ -1453,14 +1445,40 @@ static int rzg2l_cpg_deassert(struct reset_controller_dev *rcdev,
struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
const struct rzg2l_cpg_info *info = priv->info;
unsigned int reg = info->resets[id].off;
u32 dis = BIT(info->resets[id].bit);
u32 value = (dis << 16) | dis;
u32 mask = BIT(info->resets[id].bit);
s8 monbit = info->resets[id].monbit;
u32 value = (mask << 16) | mask;
dev_dbg(rcdev->dev, "deassert id:%ld offset:0x%x\n", id,
CLK_RST_R(reg));
writel(value, priv->base + CLK_RST_R(reg));
return 0;
if (info->has_clk_mon_regs) {
reg = CLK_MRST_R(reg);
} else if (monbit >= 0) {
reg = CPG_RST_MON;
mask = BIT(monbit);
} else {
/* Wait for at least one cycle of the RCLK clock (@ ca. 32 kHz) */
udelay(35);
return 0;
}
return readl_poll_timeout_atomic(priv->base + reg, value,
!(value & mask), 10, 200);
}
static int rzg2l_cpg_reset(struct reset_controller_dev *rcdev,
unsigned long id)
{
int ret;
ret = rzg2l_cpg_assert(rcdev, id);
if (ret)
return ret;
return rzg2l_cpg_deassert(rcdev, id);
}
static int rzg2l_cpg_status(struct reset_controller_dev *rcdev,
......@@ -1468,18 +1486,21 @@ static int rzg2l_cpg_status(struct reset_controller_dev *rcdev,
{
struct rzg2l_cpg_priv *priv = rcdev_to_priv(rcdev);
const struct rzg2l_cpg_info *info = priv->info;
unsigned int reg = info->resets[id].off;
u32 bitmask = BIT(info->resets[id].bit);
s8 monbit = info->resets[id].monbit;
unsigned int reg;
u32 bitmask;
if (info->has_clk_mon_regs) {
return !!(readl(priv->base + CLK_MRST_R(reg)) & bitmask);
reg = CLK_MRST_R(info->resets[id].off);
bitmask = BIT(info->resets[id].bit);
} else if (monbit >= 0) {
u32 monbitmask = BIT(monbit);
return !!(readl(priv->base + CPG_RST_MON) & monbitmask);
reg = CPG_RST_MON;
bitmask = BIT(monbit);
} else {
return -ENOTSUPP;
}
return -ENOTSUPP;
return !!(readl(priv->base + reg) & bitmask);
}
static const struct reset_control_ops rzg2l_cpg_reset_ops = {
......
......@@ -78,7 +78,9 @@ static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
RK3036_PLL_RATE(200000000, 1, 100, 3, 4, 1, 0),
RK3036_PLL_RATE(148500000, 1, 99, 4, 4, 1, 0),
RK3036_PLL_RATE(135000000, 2, 45, 4, 1, 1, 0),
RK3036_PLL_RATE(126400000, 1, 79, 5, 3, 1, 0),
RK3036_PLL_RATE(119000000, 3, 119, 4, 2, 1, 0),
RK3036_PLL_RATE(115200000, 1, 24, 5, 1, 1, 0),
RK3036_PLL_RATE(108000000, 2, 45, 5, 1, 1, 0),
RK3036_PLL_RATE(101000000, 1, 101, 6, 4, 1, 0),
RK3036_PLL_RATE(100000000, 1, 150, 6, 6, 1, 0),
......@@ -1593,6 +1595,7 @@ static const char *const rk3568_cru_critical_clocks[] __initconst = {
"hclk_php",
"pclk_php",
"hclk_usb",
"pclk_usb",
"hclk_vo",
};
......
......@@ -11,10 +11,10 @@
#include "clk.h"
/**
* struct exynos_cpuclk_data: config data to setup cpu clocks.
* @prate: frequency of the primary parent clock (in KHz).
* @div0: value to be programmed in the div_cpu0 register.
* @div1: value to be programmed in the div_cpu1 register.
* struct exynos_cpuclk_cfg_data - config data to setup cpu clocks
* @prate: frequency of the primary parent clock (in KHz)
* @div0: value to be programmed in the div_cpu0 register
* @div1: value to be programmed in the div_cpu1 register
*
* This structure holds the divider configuration data for dividers in the CPU
* clock domain. The parent frequency at which these divider values are valid is
......@@ -29,17 +29,17 @@ struct exynos_cpuclk_cfg_data {
};
/**
* struct exynos_cpuclk: information about clock supplied to a CPU core.
* @hw: handle between CCF and CPU clock.
* @alt_parent: alternate parent clock to use when switching the speed
* of the primary parent clock.
* @ctrl_base: base address of the clock controller.
* @lock: cpu clock domain register access lock.
* @cfg: cpu clock rate configuration data.
* @num_cfgs: number of array elements in @cfg array.
* @clk_nb: clock notifier registered for changes in clock speed of the
* primary parent clock.
* @flags: configuration flags for the CPU clock.
* struct exynos_cpuclk - information about clock supplied to a CPU core
* @hw: handle between CCF and CPU clock
* @alt_parent: alternate parent clock to use when switching the speed
* of the primary parent clock
* @ctrl_base: base address of the clock controller
* @lock: cpu clock domain register access lock
* @cfg: cpu clock rate configuration data
* @num_cfgs: number of array elements in @cfg array
* @clk_nb: clock notifier registered for changes in clock speed of the
* primary parent clock
* @flags: configuration flags for the CPU clock
*
* This structure holds information required for programming the CPU clock for
* various clock speeds.
......
This diff is collapsed.
......@@ -79,7 +79,7 @@ static const struct jh71x0_clk_data jh7100_audclk_data[] = {
JH71X0_GDIV(JH7100_AUDCLK_USB_LPM, "usb_lpm", CLK_IGNORE_UNUSED, 4, JH7100_AUDCLK_USB_APB),
JH71X0_GDIV(JH7100_AUDCLK_USB_STB, "usb_stb", CLK_IGNORE_UNUSED, 3, JH7100_AUDCLK_USB_APB),
JH71X0__DIV(JH7100_AUDCLK_APB_EN, "apb_en", 8, JH7100_AUDCLK_DOM7AHB_BUS),
JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 2,
JH71X0__MUX(JH7100_AUDCLK_VAD_MEM, "vad_mem", 0, 2,
JH7100_AUDCLK_VAD_INTMEM,
JH7100_AUDCLK_AUDIO_12288),
};
......
This diff is collapsed.
......@@ -26,7 +26,7 @@
static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
/* source */
JH71X0__DIV(JH7110_AONCLK_OSC_DIV4, "osc_div4", 4, JH7110_AONCLK_OSC),
JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 2,
JH71X0__MUX(JH7110_AONCLK_APB_FUNC, "apb_func", 0, 2,
JH7110_AONCLK_OSC_DIV4,
JH7110_AONCLK_OSC),
/* gmac0 */
......@@ -39,7 +39,7 @@ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
JH7110_AONCLK_GMAC0_GTXCLK,
JH7110_AONCLK_GMAC0_RMII_RTX),
JH71X0__INV(JH7110_AONCLK_GMAC0_TX_INV, "gmac0_tx_inv", JH7110_AONCLK_GMAC0_TX),
JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 2,
JH71X0__MUX(JH7110_AONCLK_GMAC0_RX, "gmac0_rx", 0, 2,
JH7110_AONCLK_GMAC0_RGMII_RXIN,
JH7110_AONCLK_GMAC0_RMII_RTX),
JH71X0__INV(JH7110_AONCLK_GMAC0_RX_INV, "gmac0_rx_inv", JH7110_AONCLK_GMAC0_RX),
......@@ -48,7 +48,7 @@ static const struct jh71x0_clk_data jh7110_aonclk_data[] = {
/* rtc */
JH71X0_GATE(JH7110_AONCLK_RTC_APB, "rtc_apb", 0, JH7110_AONCLK_APB_BUS),
JH71X0__DIV(JH7110_AONCLK_RTC_INTERNAL, "rtc_internal", 1022, JH7110_AONCLK_OSC),
JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 2,
JH71X0__MUX(JH7110_AONCLK_RTC_32K, "rtc_32k", 0, 2,
JH7110_AONCLK_RTC_OSC,
JH7110_AONCLK_RTC_INTERNAL),
JH71X0_GATE(JH7110_AONCLK_RTC_CAL, "rtc_cal", 0, JH7110_AONCLK_OSC),
......
......@@ -53,7 +53,7 @@ static const struct jh71x0_clk_data jh7110_ispclk_data[] = {
JH7110_ISPCLK_MIPI_RX0_PXL),
JH71X0_GATE(JH7110_ISPCLK_VIN_PIXEL_IF3, "vin_pixel_if3", 0,
JH7110_ISPCLK_MIPI_RX0_PXL),
JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 2,
JH71X0__MUX(JH7110_ISPCLK_VIN_P_AXI_WR, "vin_p_axi_wr", 0, 2,
JH7110_ISPCLK_MIPI_RX0_PXL,
JH7110_ISPCLK_DVP_INV),
/* ispv2_top_wrapper */
......
This diff is collapsed.
This diff is collapsed.
obj-$(CONFIG_COMMON_CLK_STM32MP135) += clk-stm32mp13.o clk-stm32-core.o reset-stm32.o
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o reset-stm32.o
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment