Merge branches 'clk-doc', 'clk-qcom', 'clk-simplify', 'clk-hw', 'clk-renesas' and 'clk-samsung' into clk-next
- Camera clks on Qualcomm SC7180 SoCs - GCC and RPMh clks on Qualcomm SDX55 SoCs - RPMh clks on Qualcomm SM8350 SoCs - LPASS clks on Qualcomm SM8250 SoCs - Add devm variant of clk_notifier_register() - Add clk_hw_get_clk() to generate a struct clk from a struct clk_hw * clk-doc: clk: fix a kernel-doc markup * clk-qcom: (27 commits) clk: qcom: rpmh: add support for SM8350 rpmh clocks dt-bindings: clock: Add RPMHCC bindings for SM8350 clk: qcom: lpasscc: Introduce pm autosuspend for SC7180 clk: qcom: gcc-sc7180: Add 50 MHz clock rate for SDC2 clk: qcom: gcc-sc7180: Use floor ops for sdcc clks clk: qcom: Add GDSC support for SDX55 GCC dt-bindings: clock: Add GDSC in SDX55 GCC clk: qcom: Add support for SDX55 RPMh clocks dt-bindings: clock: Introduce RPMHCC bindings for SDX55 clk: qcom: Add SDX55 GCC support dt-bindings: clock: Add SDX55 GCC clock bindings clk: qcom: Kconfig: Fix spelling mistake "dyanmic" -> "dynamic" clk: qcom: rpmh: Add CE clock on sdm845. dt-bindings: clock: Add entry for crypto engine RPMH clock resource clk: qcom: dispcc-sm8250: handle MMCX power domain clk: qcom: camcc-sc7180: Use runtime PM ops instead of clk ones clk: qcom: lpass-sc7180: Clean up on error in lpass_sc7180_init() clk: qcom: Add support to LPASS AON_CC Glitch Free Mux clocks clk: qcom: Add support to LPASS AUDIO_CC Glitch Free Mux clocks dt-bindings: clock: Add support for LPASS Always ON Controller ... * clk-simplify: clk: remove unneeded dead-store initialization * clk-hw: clk: meson: g12: use devm variant to register notifiers clk: add devm variant of clk_notifier_register clk: meson: g12: drop use of __clk_lookup() clk: add api to get clk consumer from clk_hw clk: avoid devm_clk_release name clash * clk-renesas: dt-bindings: clock: renesas: rcar-usb2-clock-sel: Convert bindings to json-schema clk: renesas: sh73a0: Stop using __raw_*() I/O accessors clk: renesas: r8a774c0: Add RPC clocks clk: renesas: r8a779a0: Fix R and OSC clocks clk: renesas: cpg-mssr: fix kerneldoc of cpg_mssr_priv clk: renesas: rcar-usb2-clock-sel: Replace devm_reset_control_array_get() clk: renesas: r8a774b1: Add RPC clocks clk: renesas: r8a774a1: Add RPC clocks clk: renesas: r8a779a0: Add VIN clocks clk: renesas: r8a779a0: Add CSI4[0-3] clocks MAINTAINERS: Update git repo for Renesas clock drivers clk: renesas: r8a779a0: Make rcar_r8a779a0_cpg_clk_register() static clk: renesas: rcar-gen3: Remove stp_ck handling for SDHI * clk-samsung: clk: samsung: Prevent potential endless loop in the PLL ops clk: samsung: Allow compile testing of Exynos, S3C64xx and S5Pv210
This commit is contained in:
commit
23cae54f52
|
@ -0,0 +1,58 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,aoncc-sm8250.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Clock bindings for LPASS Always ON Clock Controller on SM8250 SoCs
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell.
|
||||
See include/dt-bindings/clock/qcom,sm8250-lpass-aoncc.h for the full list
|
||||
of Audio Clock controller clock IDs.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-aon
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: LPASS Core voting clock
|
||||
- description: Glitch Free Mux register clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: bus
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,sm8250-lpass-aoncc.h>
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
clock-controller@3800000 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "qcom,sm8250-lpass-aon";
|
||||
reg = <0x03380000 0x40000>;
|
||||
clocks = <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6afecc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
|
||||
clock-names = "core", "bus";
|
||||
};
|
|
@ -0,0 +1,58 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,audiocc-sm8250.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Clock bindings for LPASS Audio Clock Controller on SM8250 SoCs
|
||||
|
||||
maintainers:
|
||||
- Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
|
||||
description: |
|
||||
The clock consumer should specify the desired clock by having the clock
|
||||
ID in its "clocks" phandle cell.
|
||||
See include/dt-bindings/clock/qcom,sm8250-lpass-audiocc.h for the full list
|
||||
of Audio Clock controller clock IDs.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sm8250-lpass-audiocc
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: LPASS Core voting clock
|
||||
- description: Glitch Free Mux register clock
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: core
|
||||
- const: bus
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- clocks
|
||||
- clock-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,sm8250-lpass-audiocc.h>
|
||||
#include <dt-bindings/sound/qcom,q6afe.h>
|
||||
clock-controller@3300000 {
|
||||
#clock-cells = <1>;
|
||||
compatible = "qcom,sm8250-lpass-audiocc";
|
||||
reg = <0x03300000 0x30000>;
|
||||
clocks = <&q6afecc LPASS_HW_MACRO_VOTE LPASS_CLK_ATTRIBUTE_COUPLE_NO>,
|
||||
<&q6afecc LPASS_CLK_ID_TX_CORE_MCLK LPASS_CLK_ATTRIBUTE_COUPLE_NO>;
|
||||
clock-names = "core", "bus";
|
||||
};
|
|
@ -0,0 +1,77 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,gcc-sdx55.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Global Clock & Reset Controller Binding for SDX55
|
||||
|
||||
maintainers:
|
||||
- Vinod Koul <vkoul@kernel.org>
|
||||
- Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
|
||||
description: |
|
||||
Qualcomm global clock control module which supports the clocks, resets and
|
||||
power domains on SDX55
|
||||
|
||||
See also:
|
||||
- dt-bindings/clock/qcom,gcc-sdx55.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,gcc-sdx55
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Sleep clock source
|
||||
- description: PLL test clock source (Optional clock)
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
- const: sleep_clk
|
||||
- const: core_bi_pll_test_se # Optional clock
|
||||
minItems: 2
|
||||
maxItems: 3
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- clocks
|
||||
- clock-names
|
||||
- reg
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@100000 {
|
||||
compatible = "qcom,gcc-sdx55";
|
||||
reg = <0x00100000 0x1f0000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&sleep_clk>, <&pll_test_clk>;
|
||||
clock-names = "bi_tcxo", "sleep_clk", "core_bi_pll_test_se";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
|
||||
...
|
|
@ -19,8 +19,10 @@ properties:
|
|||
enum:
|
||||
- qcom,sc7180-rpmh-clk
|
||||
- qcom,sdm845-rpmh-clk
|
||||
- qcom,sdx55-rpmh-clk
|
||||
- qcom,sm8150-rpmh-clk
|
||||
- qcom,sm8250-rpmh-clk
|
||||
- qcom,sm8350-rpmh-clk
|
||||
|
||||
clocks:
|
||||
maxItems: 1
|
||||
|
|
|
@ -0,0 +1,73 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: http://devicetree.org/schemas/clock/qcom,sc7180-camcc.yaml#
|
||||
$schema: http://devicetree.org/meta-schemas/core.yaml#
|
||||
|
||||
title: Qualcomm Camera Clock & Reset Controller Binding for SC7180
|
||||
|
||||
maintainers:
|
||||
- Taniya Das <tdas@codeaurora.org>
|
||||
|
||||
description: |
|
||||
Qualcomm camera clock control module which supports the clocks, resets and
|
||||
power domains on SC7180.
|
||||
|
||||
See also:
|
||||
- dt-bindings/clock/qcom,camcc-sc7180.h
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
const: qcom,sc7180-camcc
|
||||
|
||||
clocks:
|
||||
items:
|
||||
- description: Board XO source
|
||||
- description: Camera_ahb clock from GCC
|
||||
- description: Camera XO clock from GCC
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: bi_tcxo
|
||||
- const: iface
|
||||
- const: xo
|
||||
|
||||
'#clock-cells':
|
||||
const: 1
|
||||
|
||||
'#reset-cells':
|
||||
const: 1
|
||||
|
||||
'#power-domain-cells':
|
||||
const: 1
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- '#reset-cells'
|
||||
- '#power-domain-cells'
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/qcom,gcc-sc7180.h>
|
||||
#include <dt-bindings/clock/qcom,rpmh.h>
|
||||
clock-controller@ad00000 {
|
||||
compatible = "qcom,sc7180-camcc";
|
||||
reg = <0x0ad00000 0x10000>;
|
||||
clocks = <&rpmhcc RPMH_CXO_CLK>,
|
||||
<&gcc GCC_CAMERA_AHB_CLK>,
|
||||
<&gcc GCC_CAMERA_XO_CLK>;
|
||||
clock-names = "bi_tcxo", "iface", "xo";
|
||||
#clock-cells = <1>;
|
||||
#reset-cells = <1>;
|
||||
#power-domain-cells = <1>;
|
||||
};
|
||||
...
|
|
@ -1,68 +0,0 @@
|
|||
* Renesas R-Car USB 2.0 clock selector
|
||||
|
||||
This file provides information on what the device node for the R-Car USB 2.0
|
||||
clock selector.
|
||||
|
||||
If you connect an external clock to the USB_EXTAL pin only, you should set
|
||||
the clock rate to "usb_extal" node only.
|
||||
If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module
|
||||
is not needed because this is default setting. (Of course, you can set the
|
||||
clock rates to both "usb_extal" and "usb_xtal" nodes.
|
||||
|
||||
Case 1: An external clock connects to R-Car SoC
|
||||
+----------+ +--- R-Car ---------------------+
|
||||
|External |---|USB_EXTAL ---> all usb channels|
|
||||
|clock | |USB_XTAL |
|
||||
+----------+ +-------------------------------+
|
||||
In this case, we need this driver with "usb_extal" clock.
|
||||
|
||||
Case 2: An oscillator connects to R-Car SoC
|
||||
+----------+ +--- R-Car ---------------------+
|
||||
|Oscillator|---|USB_EXTAL -+-> all usb channels|
|
||||
| |---|USB_XTAL --+ |
|
||||
+----------+ +-------------------------------+
|
||||
In this case, we don't need this selector.
|
||||
|
||||
Required properties:
|
||||
- compatible: "renesas,r8a7795-rcar-usb2-clock-sel" if the device is a part of
|
||||
an R8A7795 SoC.
|
||||
"renesas,r8a7796-rcar-usb2-clock-sel" if the device if a part of
|
||||
an R8A77960 SoC.
|
||||
"renesas,r8a77961-rcar-usb2-clock-sel" if the device if a part of
|
||||
an R8A77961 SoC.
|
||||
"renesas,rcar-gen3-usb2-clock-sel" for a generic R-Car Gen3
|
||||
compatible device.
|
||||
|
||||
When compatible with the generic version, nodes must list the
|
||||
SoC-specific version corresponding to the platform first
|
||||
followed by the generic version.
|
||||
|
||||
- reg: offset and length of the USB 2.0 clock selector register block.
|
||||
- clocks: A list of phandles and specifier pairs.
|
||||
- clock-names: Name of the clocks.
|
||||
- The functional clock of USB 2.0 host side must be "ehci_ohci"
|
||||
- The functional clock of HS-USB side must be "hs-usb-if"
|
||||
- The USB_EXTAL clock pin must be "usb_extal"
|
||||
- The USB_XTAL clock pin must be "usb_xtal"
|
||||
- #clock-cells: Must be 0
|
||||
- power-domains: A phandle and symbolic PM domain specifier.
|
||||
See power/renesas,rcar-sysc.yaml.
|
||||
- resets: A list of phandles and specifier pairs.
|
||||
- reset-names: Name of the resets.
|
||||
- The reset of USB 2.0 host side must be "ehci_ohci"
|
||||
- The reset of HS-USB side must be "hs-usb-if"
|
||||
|
||||
Example (R-Car H3):
|
||||
|
||||
usb2_clksel: clock-controller@e6590630 {
|
||||
compatible = "renesas,r8a7795-rcar-usb2-clock-sel",
|
||||
"renesas,rcar-gen3-usb2-clock-sel";
|
||||
reg = <0 0xe6590630 0 0x02>;
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>,
|
||||
<&usb_extal>, <&usb_xtal>;
|
||||
clock-names = "ehci_ohci", "hs-usb-if", "usb_extal", "usb_xtal";
|
||||
#clock-cells = <0>;
|
||||
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 703>, <&cpg 704>;
|
||||
reset-names = "ehci_ohci", "hs-usb-if";
|
||||
};
|
|
@ -0,0 +1,100 @@
|
|||
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
|
||||
%YAML 1.2
|
||||
---
|
||||
$id: "http://devicetree.org/schemas/clock/renesas,rcar-usb2-clock-sel.yaml#"
|
||||
$schema: "http://devicetree.org/meta-schemas/core.yaml#"
|
||||
|
||||
title: Renesas R-Car USB 2.0 clock selector
|
||||
|
||||
maintainers:
|
||||
- Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
|
||||
|
||||
description: |
|
||||
If you connect an external clock to the USB_EXTAL pin only, you should set
|
||||
the clock rate to "usb_extal" node only.
|
||||
If you connect an oscillator to both the USB_XTAL and USB_EXTAL, this module
|
||||
is not needed because this is default setting. (Of course, you can set the
|
||||
clock rates to both "usb_extal" and "usb_xtal" nodes.
|
||||
|
||||
Case 1: An external clock connects to R-Car SoC
|
||||
+----------+ +--- R-Car ---------------------+
|
||||
|External |---|USB_EXTAL ---> all usb channels|
|
||||
|clock | |USB_XTAL |
|
||||
+----------+ +-------------------------------+
|
||||
|
||||
In this case, we need this driver with "usb_extal" clock.
|
||||
|
||||
Case 2: An oscillator connects to R-Car SoC
|
||||
+----------+ +--- R-Car ---------------------+
|
||||
|Oscillator|---|USB_EXTAL -+-> all usb channels|
|
||||
| |---|USB_XTAL --+ |
|
||||
+----------+ +-------------------------------+
|
||||
In this case, we don't need this selector.
|
||||
|
||||
properties:
|
||||
compatible:
|
||||
items:
|
||||
- enum:
|
||||
- renesas,r8a7795-rcar-usb2-clock-sel # R-Car H3
|
||||
- renesas,r8a7796-rcar-usb2-clock-sel # R-Car M3-W
|
||||
- renesas,r8a77961-rcar-usb2-clock-sel # R-Car M3-W+
|
||||
- const: renesas,rcar-gen3-usb2-clock-sel
|
||||
|
||||
reg:
|
||||
maxItems: 1
|
||||
|
||||
clocks:
|
||||
minItems: 4
|
||||
maxItems: 4
|
||||
|
||||
clock-names:
|
||||
items:
|
||||
- const: ehci_ohci
|
||||
- const: hs-usb-if
|
||||
- const: usb_extal
|
||||
- const: usb_xtal
|
||||
|
||||
'#clock-cells':
|
||||
const: 0
|
||||
|
||||
power-domains:
|
||||
maxItems: 1
|
||||
|
||||
resets:
|
||||
minItems: 2
|
||||
maxItems: 2
|
||||
|
||||
reset-names:
|
||||
items:
|
||||
- const: ehci_ohci
|
||||
- const: hs-usb-if
|
||||
|
||||
required:
|
||||
- compatible
|
||||
- reg
|
||||
- clocks
|
||||
- clock-names
|
||||
- '#clock-cells'
|
||||
- power-domains
|
||||
- resets
|
||||
- reset-names
|
||||
|
||||
additionalProperties: false
|
||||
|
||||
examples:
|
||||
- |
|
||||
#include <dt-bindings/clock/r8a7795-cpg-mssr.h>
|
||||
#include <dt-bindings/power/r8a7795-sysc.h>
|
||||
|
||||
usb2_clksel: clock-controller@e6590630 {
|
||||
compatible = "renesas,r8a7795-rcar-usb2-clock-sel",
|
||||
"renesas,rcar-gen3-usb2-clock-sel";
|
||||
reg = <0xe6590630 0x02>;
|
||||
clocks = <&cpg CPG_MOD 703>, <&cpg CPG_MOD 704>,
|
||||
<&usb_extal>, <&usb_xtal>;
|
||||
clock-names = "ehci_ohci", "hs-usb-if", "usb_extal", "usb_xtal";
|
||||
#clock-cells = <0>;
|
||||
power-domains = <&sysc R8A7795_PD_ALWAYS_ON>;
|
||||
resets = <&cpg 703>, <&cpg 704>;
|
||||
reset-names = "ehci_ohci", "hs-usb-if";
|
||||
};
|
|
@ -14888,7 +14888,7 @@ RENESAS CLOCK DRIVERS
|
|||
M: Geert Uytterhoeven <geert+renesas@glider.be>
|
||||
L: linux-renesas-soc@vger.kernel.org
|
||||
S: Supported
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git clk-renesas
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/geert/renesas-drivers.git renesas-clk
|
||||
F: Documentation/devicetree/bindings/clock/renesas,*
|
||||
F: drivers/clk/renesas/
|
||||
|
||||
|
|
|
@ -420,7 +420,7 @@ static struct clk_core *clk_core_get(struct clk_core *core, u8 p_index)
|
|||
static void clk_core_fill_parent_index(struct clk_core *core, u8 index)
|
||||
{
|
||||
struct clk_parent_map *entry = &core->parents[index];
|
||||
struct clk_core *parent = ERR_PTR(-ENOENT);
|
||||
struct clk_core *parent;
|
||||
|
||||
if (entry->hw) {
|
||||
parent = entry->hw->core;
|
||||
|
@ -3667,6 +3667,24 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
|
|||
return clk;
|
||||
}
|
||||
|
||||
/**
|
||||
* clk_hw_get_clk - get clk consumer given an clk_hw
|
||||
* @hw: clk_hw associated with the clk being consumed
|
||||
* @con_id: connection ID string on device
|
||||
*
|
||||
* Returns: new clk consumer
|
||||
* This is the function to be used by providers which need
|
||||
* to get a consumer clk and act on the clock element
|
||||
* Calls to this function must be balanced with calls clk_put()
|
||||
*/
|
||||
struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id)
|
||||
{
|
||||
struct device *dev = hw->core->dev;
|
||||
|
||||
return clk_hw_create_clk(dev, hw, dev_name(dev), con_id);
|
||||
}
|
||||
EXPORT_SYMBOL(clk_hw_get_clk);
|
||||
|
||||
static int clk_cpy_name(const char **dst_p, const char *src, bool must_exist)
|
||||
{
|
||||
const char *dst;
|
||||
|
@ -4068,12 +4086,12 @@ void clk_hw_unregister(struct clk_hw *hw)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(clk_hw_unregister);
|
||||
|
||||
static void devm_clk_release(struct device *dev, void *res)
|
||||
static void devm_clk_unregister_cb(struct device *dev, void *res)
|
||||
{
|
||||
clk_unregister(*(struct clk **)res);
|
||||
}
|
||||
|
||||
static void devm_clk_hw_release(struct device *dev, void *res)
|
||||
static void devm_clk_hw_unregister_cb(struct device *dev, void *res)
|
||||
{
|
||||
clk_hw_unregister(*(struct clk_hw **)res);
|
||||
}
|
||||
|
@ -4093,7 +4111,7 @@ struct clk *devm_clk_register(struct device *dev, struct clk_hw *hw)
|
|||
struct clk *clk;
|
||||
struct clk **clkp;
|
||||
|
||||
clkp = devres_alloc(devm_clk_release, sizeof(*clkp), GFP_KERNEL);
|
||||
clkp = devres_alloc(devm_clk_unregister_cb, sizeof(*clkp), GFP_KERNEL);
|
||||
if (!clkp)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
@ -4123,7 +4141,7 @@ int devm_clk_hw_register(struct device *dev, struct clk_hw *hw)
|
|||
struct clk_hw **hwp;
|
||||
int ret;
|
||||
|
||||
hwp = devres_alloc(devm_clk_hw_release, sizeof(*hwp), GFP_KERNEL);
|
||||
hwp = devres_alloc(devm_clk_hw_unregister_cb, sizeof(*hwp), GFP_KERNEL);
|
||||
if (!hwp)
|
||||
return -ENOMEM;
|
||||
|
||||
|
@ -4167,7 +4185,7 @@ static int devm_clk_hw_match(struct device *dev, void *res, void *data)
|
|||
*/
|
||||
void devm_clk_unregister(struct device *dev, struct clk *clk)
|
||||
{
|
||||
WARN_ON(devres_release(dev, devm_clk_release, devm_clk_match, clk));
|
||||
WARN_ON(devres_release(dev, devm_clk_unregister_cb, devm_clk_match, clk));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_unregister);
|
||||
|
||||
|
@ -4182,11 +4200,54 @@ EXPORT_SYMBOL_GPL(devm_clk_unregister);
|
|||
*/
|
||||
void devm_clk_hw_unregister(struct device *dev, struct clk_hw *hw)
|
||||
{
|
||||
WARN_ON(devres_release(dev, devm_clk_hw_release, devm_clk_hw_match,
|
||||
WARN_ON(devres_release(dev, devm_clk_hw_unregister_cb, devm_clk_hw_match,
|
||||
hw));
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_unregister);
|
||||
|
||||
static void devm_clk_release(struct device *dev, void *res)
|
||||
{
|
||||
clk_put(*(struct clk **)res);
|
||||
}
|
||||
|
||||
/**
|
||||
* devm_clk_hw_get_clk - resource managed clk_hw_get_clk()
|
||||
* @dev: device that is registering this clock
|
||||
* @hw: clk_hw associated with the clk being consumed
|
||||
* @con_id: connection ID string on device
|
||||
*
|
||||
* Managed clk_hw_get_clk(). Clocks got with this function are
|
||||
* automatically clk_put() on driver detach. See clk_put()
|
||||
* for more information.
|
||||
*/
|
||||
struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw,
|
||||
const char *con_id)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct clk **clkp;
|
||||
|
||||
/* This should not happen because it would mean we have drivers
|
||||
* passing around clk_hw pointers instead of having the caller use
|
||||
* proper clk_get() style APIs
|
||||
*/
|
||||
WARN_ON_ONCE(dev != hw->core->dev);
|
||||
|
||||
clkp = devres_alloc(devm_clk_release, sizeof(*clkp), GFP_KERNEL);
|
||||
if (!clkp)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
clk = clk_hw_get_clk(hw, con_id);
|
||||
if (!IS_ERR(clk)) {
|
||||
*clkp = clk;
|
||||
devres_add(dev, clkp);
|
||||
} else {
|
||||
devres_free(clkp);
|
||||
}
|
||||
|
||||
return clk;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_hw_get_clk);
|
||||
|
||||
/*
|
||||
* clkdev helpers
|
||||
*/
|
||||
|
@ -4334,6 +4395,42 @@ int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(clk_notifier_unregister);
|
||||
|
||||
struct clk_notifier_devres {
|
||||
struct clk *clk;
|
||||
struct notifier_block *nb;
|
||||
};
|
||||
|
||||
static void devm_clk_notifier_release(struct device *dev, void *res)
|
||||
{
|
||||
struct clk_notifier_devres *devres = res;
|
||||
|
||||
clk_notifier_unregister(devres->clk, devres->nb);
|
||||
}
|
||||
|
||||
int devm_clk_notifier_register(struct device *dev, struct clk *clk,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
struct clk_notifier_devres *devres;
|
||||
int ret;
|
||||
|
||||
devres = devres_alloc(devm_clk_notifier_release,
|
||||
sizeof(*devres), GFP_KERNEL);
|
||||
|
||||
if (!devres)
|
||||
return -ENOMEM;
|
||||
|
||||
ret = clk_notifier_register(clk, nb);
|
||||
if (!ret) {
|
||||
devres->clk = clk;
|
||||
devres->nb = nb;
|
||||
} else {
|
||||
devres_free(devres);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(devm_clk_notifier_register);
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static void clk_core_reparent_orphans(void)
|
||||
{
|
||||
|
|
|
@ -5156,10 +5156,11 @@ static const struct reg_sequence g12a_init_regs[] = {
|
|||
{ .reg = HHI_MPLL_CNTL0, .def = 0x00000543 },
|
||||
};
|
||||
|
||||
static int meson_g12a_dvfs_setup_common(struct platform_device *pdev,
|
||||
#define DVFS_CON_ID "dvfs"
|
||||
|
||||
static int meson_g12a_dvfs_setup_common(struct device *dev,
|
||||
struct clk_hw **hws)
|
||||
{
|
||||
const char *notifier_clk_name;
|
||||
struct clk *notifier_clk;
|
||||
struct clk_hw *xtal;
|
||||
int ret;
|
||||
|
@ -5168,21 +5169,22 @@ static int meson_g12a_dvfs_setup_common(struct platform_device *pdev,
|
|||
|
||||
/* Setup clock notifier for cpu_clk_postmux0 */
|
||||
g12a_cpu_clk_postmux0_nb_data.xtal = xtal;
|
||||
notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_postmux0.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk,
|
||||
&g12a_cpu_clk_postmux0_nb_data.nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk_postmux0.hw,
|
||||
DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12a_cpu_clk_postmux0_nb_data.nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the cpu_clk_postmux0 notifier\n");
|
||||
dev_err(dev, "failed to register the cpu_clk_postmux0 notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup clock notifier for cpu_clk_dyn mux */
|
||||
notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk_dyn.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk_dyn.hw,
|
||||
DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12a_cpu_clk_mux_nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the cpu_clk_dyn notifier\n");
|
||||
dev_err(dev, "failed to register the cpu_clk_dyn notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -5192,33 +5194,34 @@ static int meson_g12a_dvfs_setup_common(struct platform_device *pdev,
|
|||
static int meson_g12b_dvfs_setup(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_hw **hws = g12b_hw_onecell_data.hws;
|
||||
const char *notifier_clk_name;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk *notifier_clk;
|
||||
struct clk_hw *xtal;
|
||||
int ret;
|
||||
|
||||
ret = meson_g12a_dvfs_setup_common(pdev, hws);
|
||||
ret = meson_g12a_dvfs_setup_common(dev, hws);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
xtal = clk_hw_get_parent_by_index(hws[CLKID_CPU_CLK_DYN1_SEL], 0);
|
||||
|
||||
/* Setup clock notifier for cpu_clk mux */
|
||||
notifier_clk_name = clk_hw_get_name(&g12b_cpu_clk.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpu_clk.hw,
|
||||
DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12a_cpu_clk_mux_nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
|
||||
dev_err(dev, "failed to register the cpu_clk notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup clock notifier for sys1_pll */
|
||||
notifier_clk_name = clk_hw_get_name(&g12b_sys1_pll.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk,
|
||||
&g12b_cpu_clk_sys1_pll_nb_data.nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12b_sys1_pll.hw,
|
||||
DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12b_cpu_clk_sys1_pll_nb_data.nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the sys1_pll notifier\n");
|
||||
dev_err(dev, "failed to register the sys1_pll notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -5226,40 +5229,39 @@ static int meson_g12b_dvfs_setup(struct platform_device *pdev)
|
|||
|
||||
/* Setup clock notifier for cpub_clk_postmux0 */
|
||||
g12b_cpub_clk_postmux0_nb_data.xtal = xtal;
|
||||
notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_postmux0.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk,
|
||||
&g12b_cpub_clk_postmux0_nb_data.nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_postmux0.hw,
|
||||
DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12b_cpub_clk_postmux0_nb_data.nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the cpub_clk_postmux0 notifier\n");
|
||||
dev_err(dev, "failed to register the cpub_clk_postmux0 notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup clock notifier for cpub_clk_dyn mux */
|
||||
notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk_dyn.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk_dyn.hw, "dvfs");
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12a_cpu_clk_mux_nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the cpub_clk_dyn notifier\n");
|
||||
dev_err(dev, "failed to register the cpub_clk_dyn notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup clock notifier for cpub_clk mux */
|
||||
notifier_clk_name = clk_hw_get_name(&g12b_cpub_clk.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12b_cpub_clk.hw, DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12a_cpu_clk_mux_nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the cpub_clk notifier\n");
|
||||
dev_err(dev, "failed to register the cpub_clk notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup clock notifier for sys_pll */
|
||||
notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk,
|
||||
&g12b_cpub_clk_sys_pll_nb_data.nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12a_sys_pll.hw, DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12b_cpub_clk_sys_pll_nb_data.nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
|
||||
dev_err(dev, "failed to register the sys_pll notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -5269,29 +5271,29 @@ static int meson_g12b_dvfs_setup(struct platform_device *pdev)
|
|||
static int meson_g12a_dvfs_setup(struct platform_device *pdev)
|
||||
{
|
||||
struct clk_hw **hws = g12a_hw_onecell_data.hws;
|
||||
const char *notifier_clk_name;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk *notifier_clk;
|
||||
int ret;
|
||||
|
||||
ret = meson_g12a_dvfs_setup_common(pdev, hws);
|
||||
ret = meson_g12a_dvfs_setup_common(dev, hws);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Setup clock notifier for cpu_clk mux */
|
||||
notifier_clk_name = clk_hw_get_name(&g12a_cpu_clk.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk, &g12a_cpu_clk_mux_nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12a_cpu_clk.hw, DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12a_cpu_clk_mux_nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the cpu_clk notifier\n");
|
||||
dev_err(dev, "failed to register the cpu_clk notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Setup clock notifier for sys_pll */
|
||||
notifier_clk_name = clk_hw_get_name(&g12a_sys_pll.hw);
|
||||
notifier_clk = __clk_lookup(notifier_clk_name);
|
||||
ret = clk_notifier_register(notifier_clk, &g12a_sys_pll_nb_data.nb);
|
||||
notifier_clk = devm_clk_hw_get_clk(dev, &g12a_sys_pll.hw, DVFS_CON_ID);
|
||||
ret = devm_clk_notifier_register(dev, notifier_clk,
|
||||
&g12a_sys_pll_nb_data.nb);
|
||||
if (ret) {
|
||||
dev_err(&pdev->dev, "failed to register the sys_pll notifier\n");
|
||||
dev_err(dev, "failed to register the sys_pll notifier\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@ config QCOM_CLK_APCC_MSM8996
|
|||
help
|
||||
Support for the CPU clock controller on msm8996 devices.
|
||||
Say Y if you want to support CPU clock scaling using CPUfreq
|
||||
drivers for dyanmic power management.
|
||||
drivers for dynamic power management.
|
||||
|
||||
config QCOM_CLK_RPM
|
||||
tristate "RPM based Clock Controller"
|
||||
|
@ -290,6 +290,15 @@ config QCS_GCC_404
|
|||
Say Y if you want to use multimedia devices or peripheral
|
||||
devices such as UART, SPI, I2C, USB, SD/eMMC, PCIe etc.
|
||||
|
||||
config SC_CAMCC_7180
|
||||
tristate "SC7180 Camera Clock Controller"
|
||||
select SC_GCC_7180
|
||||
help
|
||||
Support for the camera clock controller on Qualcomm Technologies, Inc
|
||||
SC7180 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"
|
||||
select SC_GCC_7180
|
||||
|
@ -413,6 +422,14 @@ config SDM_LPASSCC_845
|
|||
Say Y if you want to use the LPASS branch clocks of the LPASS clock
|
||||
controller to reset the LPASS subsystem.
|
||||
|
||||
config SDX_GCC_55
|
||||
tristate "SDX55 Global Clock Controller"
|
||||
select QCOM_GDSC
|
||||
help
|
||||
Support for the global clock controller on SDX55 devices.
|
||||
Say Y if you want to use peripheral devices such as UART,
|
||||
SPI, I2C, USB, SD/UFS, PCIe etc.
|
||||
|
||||
config SM_DISPCC_8250
|
||||
tristate "SM8150 and SM8250 Display Clock Controller"
|
||||
depends on SM_GCC_8150 || SM_GCC_8250
|
||||
|
@ -502,4 +519,10 @@ config KRAITCC
|
|||
Support for the Krait CPU clocks on Qualcomm devices.
|
||||
Say Y if you want to support CPU frequency scaling.
|
||||
|
||||
config CLK_GFM_LPASS_SM8250
|
||||
tristate "SM8250 GFM LPASS Clocks"
|
||||
help
|
||||
Support for the Glitch Free Mux (GFM) Low power audio
|
||||
subsystem (LPASS) clocks found on SM8250 SoCs.
|
||||
|
||||
endif
|
||||
|
|
|
@ -19,6 +19,7 @@ clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
|
|||
# Keep alphabetically sorted by config
|
||||
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_IPQ_APSS_PLL) += apss-ipq-pll.o
|
||||
obj-$(CONFIG_IPQ_APSS_6018) += apss-ipq6018.o
|
||||
obj-$(CONFIG_IPQ_GCC_4019) += gcc-ipq4019.o
|
||||
|
@ -51,6 +52,7 @@ obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.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_SC_CAMCC_7180) += camcc-sc7180.o
|
||||
obj-$(CONFIG_SC_DISPCC_7180) += dispcc-sc7180.o
|
||||
obj-$(CONFIG_SC_GCC_7180) += gcc-sc7180.o
|
||||
obj-$(CONFIG_SC_GPUCC_7180) += gpucc-sc7180.o
|
||||
|
@ -64,6 +66,7 @@ obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
|
|||
obj-$(CONFIG_SDM_GPUCC_845) += gpucc-sdm845.o
|
||||
obj-$(CONFIG_SDM_LPASSCC_845) += lpasscc-sdm845.o
|
||||
obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
|
||||
obj-$(CONFIG_SDX_GCC_55) += gcc-sdx55.o
|
||||
obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
|
||||
obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
|
||||
obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -116,6 +116,16 @@ const u8 clk_alpha_pll_regs[][PLL_OFF_MAX_REGS] = {
|
|||
[PLL_OFF_OPMODE] = 0x38,
|
||||
[PLL_OFF_ALPHA_VAL] = 0x40,
|
||||
},
|
||||
[CLK_ALPHA_PLL_TYPE_AGERA] = {
|
||||
[PLL_OFF_L_VAL] = 0x04,
|
||||
[PLL_OFF_ALPHA_VAL] = 0x08,
|
||||
[PLL_OFF_USER_CTL] = 0x0c,
|
||||
[PLL_OFF_CONFIG_CTL] = 0x10,
|
||||
[PLL_OFF_CONFIG_CTL_U] = 0x14,
|
||||
[PLL_OFF_TEST_CTL] = 0x18,
|
||||
[PLL_OFF_TEST_CTL_U] = 0x1c,
|
||||
[PLL_OFF_STATUS] = 0x2c,
|
||||
},
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
|
||||
|
||||
|
@ -207,6 +217,13 @@ static int wait_for_pll(struct clk_alpha_pll *pll, u32 mask, bool inverse,
|
|||
#define wait_for_pll_update_ack_clear(pll) \
|
||||
wait_for_pll(pll, ALPHA_PLL_ACK_LATCH, 1, "update_ack_clear")
|
||||
|
||||
static void clk_alpha_pll_write_config(struct regmap *regmap, unsigned int reg,
|
||||
unsigned int val)
|
||||
{
|
||||
if (val)
|
||||
regmap_write(regmap, reg, val);
|
||||
}
|
||||
|
||||
void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config)
|
||||
{
|
||||
|
@ -1004,33 +1021,19 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
|||
{
|
||||
u32 val, mask;
|
||||
|
||||
if (config->l)
|
||||
regmap_write(regmap, PLL_L_VAL(pll), config->l);
|
||||
|
||||
if (config->alpha)
|
||||
regmap_write(regmap, PLL_FRAC(pll), config->alpha);
|
||||
|
||||
if (config->config_ctl_val)
|
||||
regmap_write(regmap, PLL_CONFIG_CTL(pll),
|
||||
clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
|
||||
clk_alpha_pll_write_config(regmap, PLL_FRAC(pll), config->alpha);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
|
||||
config->config_ctl_val);
|
||||
|
||||
if (config->config_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
|
||||
config->config_ctl_hi_val);
|
||||
|
||||
if (config->user_ctl_val)
|
||||
regmap_write(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
|
||||
|
||||
if (config->user_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_USER_CTL_U(pll),
|
||||
clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
|
||||
config->user_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),
|
||||
config->user_ctl_hi_val);
|
||||
|
||||
if (config->test_ctl_val)
|
||||
regmap_write(regmap, PLL_TEST_CTL(pll),
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
|
||||
config->test_ctl_val);
|
||||
|
||||
if (config->test_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_TEST_CTL_U(pll),
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
|
||||
config->test_ctl_hi_val);
|
||||
|
||||
if (config->post_div_mask) {
|
||||
|
@ -1145,25 +1148,38 @@ static unsigned long alpha_pll_fabia_recalc_rate(struct clk_hw *hw,
|
|||
return alpha_pll_calc_rate(parent_rate, l, frac, alpha_width);
|
||||
}
|
||||
|
||||
/*
|
||||
* Due to limited number of bits for fractional rate programming, the
|
||||
* rounded up rate could be marginally higher than the requested rate.
|
||||
*/
|
||||
static int alpha_pll_check_rate_margin(struct clk_hw *hw,
|
||||
unsigned long rrate, unsigned long rate)
|
||||
{
|
||||
unsigned long rate_margin = rate + PLL_RATE_MARGIN;
|
||||
|
||||
if (rrate > rate_margin || rrate < rate) {
|
||||
pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n",
|
||||
clk_hw_get_name(hw), rrate, rate, rate_margin);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int alpha_pll_fabia_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 l, alpha_width = pll_alpha_width(pll);
|
||||
unsigned long rrate;
|
||||
int ret;
|
||||
u64 a;
|
||||
unsigned long rrate, max = rate + PLL_RATE_MARGIN;
|
||||
|
||||
rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
|
||||
|
||||
/*
|
||||
* Due to limited number of bits for fractional rate programming, the
|
||||
* rounded up rate could be marginally higher than the requested rate.
|
||||
*/
|
||||
if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) {
|
||||
pr_err("%s: Rounded rate %lu not within range [%lu, %lu)\n",
|
||||
clk_hw_get_name(hw), rrate, rate, max);
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = alpha_pll_check_rate_margin(hw, rrate, rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
|
||||
regmap_write(pll->clkr.regmap, PLL_FRAC(pll), a);
|
||||
|
@ -1206,12 +1222,10 @@ static int alpha_pll_fabia_prepare(struct clk_hw *hw)
|
|||
|
||||
rrate = alpha_pll_round_rate(cal_freq, clk_hw_get_rate(parent_hw),
|
||||
&cal_l, &a, alpha_width);
|
||||
/*
|
||||
* Due to a limited number of bits for fractional rate programming, the
|
||||
* rounded up rate could be marginally higher than the requested rate.
|
||||
*/
|
||||
if (rrate > (cal_freq + PLL_RATE_MARGIN) || rrate < cal_freq)
|
||||
return -EINVAL;
|
||||
|
||||
ret = alpha_pll_check_rate_margin(hw, rrate, cal_freq);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* Setup PLL for calibration frequency */
|
||||
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), cal_l);
|
||||
|
@ -1388,49 +1402,27 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_fabia_ops);
|
|||
void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config)
|
||||
{
|
||||
if (config->l)
|
||||
regmap_write(regmap, PLL_L_VAL(pll), config->l);
|
||||
|
||||
clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
|
||||
regmap_write(regmap, PLL_CAL_L_VAL(pll), TRION_PLL_CAL_VAL);
|
||||
|
||||
if (config->alpha)
|
||||
regmap_write(regmap, PLL_ALPHA_VAL(pll), config->alpha);
|
||||
|
||||
if (config->config_ctl_val)
|
||||
regmap_write(regmap, PLL_CONFIG_CTL(pll),
|
||||
config->config_ctl_val);
|
||||
|
||||
if (config->config_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_CONFIG_CTL_U(pll),
|
||||
config->config_ctl_hi_val);
|
||||
|
||||
if (config->config_ctl_hi1_val)
|
||||
regmap_write(regmap, PLL_CONFIG_CTL_U1(pll),
|
||||
config->config_ctl_hi1_val);
|
||||
|
||||
if (config->user_ctl_val)
|
||||
regmap_write(regmap, PLL_USER_CTL(pll),
|
||||
config->user_ctl_val);
|
||||
|
||||
if (config->user_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_USER_CTL_U(pll),
|
||||
config->user_ctl_hi_val);
|
||||
|
||||
if (config->user_ctl_hi1_val)
|
||||
regmap_write(regmap, PLL_USER_CTL_U1(pll),
|
||||
config->user_ctl_hi1_val);
|
||||
|
||||
if (config->test_ctl_val)
|
||||
regmap_write(regmap, PLL_TEST_CTL(pll),
|
||||
config->test_ctl_val);
|
||||
|
||||
if (config->test_ctl_hi_val)
|
||||
regmap_write(regmap, PLL_TEST_CTL_U(pll),
|
||||
config->test_ctl_hi_val);
|
||||
|
||||
if (config->test_ctl_hi1_val)
|
||||
regmap_write(regmap, PLL_TEST_CTL_U1(pll),
|
||||
config->test_ctl_hi1_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
|
||||
config->config_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
|
||||
config->config_ctl_hi_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll),
|
||||
config->config_ctl_hi1_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
|
||||
config->user_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll),
|
||||
config->user_ctl_hi_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U1(pll),
|
||||
config->user_ctl_hi1_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
|
||||
config->test_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
|
||||
config->test_ctl_hi_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll),
|
||||
config->test_ctl_hi1_val);
|
||||
|
||||
regmap_update_bits(regmap, PLL_MODE(pll), PLL_UPDATE_BYPASS,
|
||||
PLL_UPDATE_BYPASS);
|
||||
|
@ -1490,14 +1482,9 @@ static int alpha_pll_trion_set_rate(struct clk_hw *hw, unsigned long rate,
|
|||
|
||||
rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
|
||||
|
||||
/*
|
||||
* Due to a limited number of bits for fractional rate programming, the
|
||||
* rounded up rate could be marginally higher than the requested rate.
|
||||
*/
|
||||
if (rrate > (rate + PLL_RATE_MARGIN) || rrate < rate) {
|
||||
pr_err("Call set rate on the PLL with rounded rates!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = alpha_pll_check_rate_margin(hw, rrate, rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
|
||||
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
|
||||
|
@ -1561,3 +1548,55 @@ const struct clk_ops clk_alpha_pll_postdiv_lucid_ops = {
|
|||
.set_rate = clk_alpha_pll_postdiv_fabia_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_postdiv_lucid_ops);
|
||||
|
||||
void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config)
|
||||
{
|
||||
clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), config->l);
|
||||
clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
|
||||
clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll),
|
||||
config->user_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll),
|
||||
config->config_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll),
|
||||
config->config_ctl_hi_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll),
|
||||
config->test_ctl_val);
|
||||
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll),
|
||||
config->test_ctl_hi_val);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(clk_agera_pll_configure);
|
||||
|
||||
static int clk_alpha_pll_agera_set_rate(struct clk_hw *hw, unsigned long rate,
|
||||
unsigned long prate)
|
||||
{
|
||||
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
|
||||
u32 l, alpha_width = pll_alpha_width(pll);
|
||||
int ret;
|
||||
unsigned long rrate;
|
||||
u64 a;
|
||||
|
||||
rrate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
|
||||
ret = alpha_pll_check_rate_margin(hw, rrate, rate);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/* change L_VAL without having to go through the power on sequence */
|
||||
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
|
||||
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
|
||||
|
||||
if (clk_hw_is_enabled(hw))
|
||||
return wait_for_pll_enable_lock(pll);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct clk_ops clk_alpha_pll_agera_ops = {
|
||||
.enable = clk_alpha_pll_enable,
|
||||
.disable = clk_alpha_pll_disable,
|
||||
.is_enabled = clk_alpha_pll_is_enabled,
|
||||
.recalc_rate = alpha_pll_fabia_recalc_rate,
|
||||
.round_rate = clk_alpha_pll_round_rate,
|
||||
.set_rate = clk_alpha_pll_agera_set_rate,
|
||||
};
|
||||
EXPORT_SYMBOL_GPL(clk_alpha_pll_agera_ops);
|
||||
|
|
|
@ -15,6 +15,7 @@ enum {
|
|||
CLK_ALPHA_PLL_TYPE_FABIA,
|
||||
CLK_ALPHA_PLL_TYPE_TRION,
|
||||
CLK_ALPHA_PLL_TYPE_LUCID = CLK_ALPHA_PLL_TYPE_TRION,
|
||||
CLK_ALPHA_PLL_TYPE_AGERA,
|
||||
CLK_ALPHA_PLL_TYPE_MAX,
|
||||
};
|
||||
|
||||
|
@ -141,6 +142,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_trion_ops;
|
|||
extern const struct clk_ops clk_alpha_pll_lucid_ops;
|
||||
#define clk_alpha_pll_fixed_lucid_ops clk_alpha_pll_fixed_trion_ops
|
||||
extern const struct clk_ops clk_alpha_pll_postdiv_lucid_ops;
|
||||
extern const struct clk_ops clk_alpha_pll_agera_ops;
|
||||
|
||||
void clk_alpha_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config);
|
||||
|
@ -148,6 +150,8 @@ void clk_fabia_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
|||
const struct alpha_pll_config *config);
|
||||
void clk_trion_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config);
|
||||
void clk_agera_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
|
||||
const struct alpha_pll_config *config);
|
||||
#define clk_lucid_pll_configure(pll, regmap, config) \
|
||||
clk_trion_pll_configure(pll, regmap, config)
|
||||
|
||||
|
|
|
@ -349,6 +349,7 @@ DEFINE_CLK_RPMH_VRM(sdm845, rf_clk2, rf_clk2_ao, "rfclka2", 1);
|
|||
DEFINE_CLK_RPMH_VRM(sdm845, rf_clk3, rf_clk3_ao, "rfclka3", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1);
|
||||
DEFINE_CLK_RPMH_BCM(sdm845, ipa, "IP0");
|
||||
DEFINE_CLK_RPMH_BCM(sdm845, ce, "CE0");
|
||||
|
||||
static struct clk_hw *sdm845_rpmh_clocks[] = {
|
||||
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
|
||||
|
@ -364,6 +365,7 @@ static struct clk_hw *sdm845_rpmh_clocks[] = {
|
|||
[RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
|
||||
[RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
|
||||
[RPMH_IPA_CLK] = &sdm845_ipa.hw,
|
||||
[RPMH_CE_CLK] = &sdm845_ce.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_sdm845 = {
|
||||
|
@ -371,6 +373,25 @@ static const struct clk_rpmh_desc clk_rpmh_sdm845 = {
|
|||
.num_clks = ARRAY_SIZE(sdm845_rpmh_clocks),
|
||||
};
|
||||
|
||||
DEFINE_CLK_RPMH_VRM(sdx55, rf_clk1, rf_clk1_ao, "rfclkd1", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sdx55, rf_clk2, rf_clk2_ao, "rfclkd2", 1);
|
||||
DEFINE_CLK_RPMH_BCM(sdx55, qpic_clk, "QP0");
|
||||
|
||||
static struct clk_hw *sdx55_rpmh_clocks[] = {
|
||||
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
|
||||
[RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
|
||||
[RPMH_RF_CLK1] = &sdx55_rf_clk1.hw,
|
||||
[RPMH_RF_CLK1_A] = &sdx55_rf_clk1_ao.hw,
|
||||
[RPMH_RF_CLK2] = &sdx55_rf_clk2.hw,
|
||||
[RPMH_RF_CLK2_A] = &sdx55_rf_clk2_ao.hw,
|
||||
[RPMH_QPIC_CLK] = &sdx55_qpic_clk.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_sdx55 = {
|
||||
.clks = sdx55_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(sdx55_rpmh_clocks),
|
||||
};
|
||||
|
||||
static struct clk_hw *sm8150_rpmh_clocks[] = {
|
||||
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
|
||||
[RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
|
||||
|
@ -432,6 +453,39 @@ static const struct clk_rpmh_desc clk_rpmh_sm8250 = {
|
|||
.num_clks = ARRAY_SIZE(sm8250_rpmh_clocks),
|
||||
};
|
||||
|
||||
DEFINE_CLK_RPMH_VRM(sm8350, div_clk1, div_clk1_ao, "divclka1", 2);
|
||||
DEFINE_CLK_RPMH_VRM(sm8350, rf_clk4, rf_clk4_ao, "rfclka4", 1);
|
||||
DEFINE_CLK_RPMH_VRM(sm8350, rf_clk5, rf_clk5_ao, "rfclka5", 1);
|
||||
DEFINE_CLK_RPMH_BCM(sm8350, pka, "PKA0");
|
||||
DEFINE_CLK_RPMH_BCM(sm8350, hwkm, "HK0");
|
||||
|
||||
static struct clk_hw *sm8350_rpmh_clocks[] = {
|
||||
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
|
||||
[RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
|
||||
[RPMH_DIV_CLK1] = &sm8350_div_clk1.hw,
|
||||
[RPMH_DIV_CLK1_A] = &sm8350_div_clk1_ao.hw,
|
||||
[RPMH_LN_BB_CLK1] = &sm8250_ln_bb_clk1.hw,
|
||||
[RPMH_LN_BB_CLK1_A] = &sm8250_ln_bb_clk1_ao.hw,
|
||||
[RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
|
||||
[RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
|
||||
[RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
|
||||
[RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
|
||||
[RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
|
||||
[RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
|
||||
[RPMH_RF_CLK4] = &sm8350_rf_clk4.hw,
|
||||
[RPMH_RF_CLK4_A] = &sm8350_rf_clk4_ao.hw,
|
||||
[RPMH_RF_CLK5] = &sm8350_rf_clk5.hw,
|
||||
[RPMH_RF_CLK5_A] = &sm8350_rf_clk5_ao.hw,
|
||||
[RPMH_IPA_CLK] = &sdm845_ipa.hw,
|
||||
[RPMH_PKA_CLK] = &sm8350_pka.hw,
|
||||
[RPMH_HWKM_CLK] = &sm8350_hwkm.hw,
|
||||
};
|
||||
|
||||
static const struct clk_rpmh_desc clk_rpmh_sm8350 = {
|
||||
.clks = sm8350_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(sm8350_rpmh_clocks),
|
||||
};
|
||||
|
||||
static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
|
||||
void *data)
|
||||
{
|
||||
|
@ -517,8 +571,10 @@ static int clk_rpmh_probe(struct platform_device *pdev)
|
|||
static const struct of_device_id clk_rpmh_match_table[] = {
|
||||
{ .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
|
||||
{ .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
|
||||
{ .compatible = "qcom,sdx55-rpmh-clk", .data = &clk_rpmh_sdx55},
|
||||
{ .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
|
||||
{ .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250},
|
||||
{ .compatible = "qcom,sm8350-rpmh-clk", .data = &clk_rpmh_sm8350},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);
|
||||
|
|
|
@ -963,6 +963,7 @@ static struct gdsc mdss_gdsc = {
|
|||
},
|
||||
.pwrsts = PWRSTS_OFF_ON,
|
||||
.flags = HW_CTRL,
|
||||
.supply = "mmcx",
|
||||
};
|
||||
|
||||
static struct clk_regmap *disp_cc_sm8250_clocks[] = {
|
||||
|
|
|
@ -642,7 +642,7 @@ static struct clk_rcg2 gcc_sdcc1_ice_core_clk_src = {
|
|||
.name = "gcc_sdcc1_ice_core_clk_src",
|
||||
.parent_data = gcc_parent_data_0,
|
||||
.num_parents = 4,
|
||||
.ops = &clk_rcg2_ops,
|
||||
.ops = &clk_rcg2_floor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -651,6 +651,7 @@ static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
|
|||
F(9600000, P_BI_TCXO, 2, 0, 0),
|
||||
F(19200000, P_BI_TCXO, 1, 0, 0),
|
||||
F(25000000, P_GPLL0_OUT_EVEN, 12, 0, 0),
|
||||
F(50000000, P_GPLL0_OUT_EVEN, 6, 0, 0),
|
||||
F(100000000, P_GPLL0_OUT_EVEN, 3, 0, 0),
|
||||
F(202000000, P_GPLL7_OUT_MAIN, 4, 0, 0),
|
||||
{ }
|
||||
|
@ -666,7 +667,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
|
|||
.name = "gcc_sdcc2_apps_clk_src",
|
||||
.parent_data = gcc_parent_data_5,
|
||||
.num_parents = 5,
|
||||
.ops = &clk_rcg2_ops,
|
||||
.ops = &clk_rcg2_floor_ops,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,320 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* LPASS Audio CC and Always ON CC Glitch Free Mux clock driver
|
||||
*
|
||||
* Copyright (c) 2020 Linaro Ltd.
|
||||
* Author: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/pm_clock.h>
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <dt-bindings/clock/qcom,sm8250-lpass-audiocc.h>
|
||||
#include <dt-bindings/clock/qcom,sm8250-lpass-aoncc.h>
|
||||
|
||||
struct lpass_gfm {
|
||||
struct device *dev;
|
||||
void __iomem *base;
|
||||
};
|
||||
|
||||
struct clk_gfm {
|
||||
unsigned int mux_reg;
|
||||
unsigned int mux_mask;
|
||||
struct clk_hw hw;
|
||||
struct lpass_gfm *priv;
|
||||
void __iomem *gfm_mux;
|
||||
};
|
||||
|
||||
#define GFM_MASK BIT(1)
|
||||
#define to_clk_gfm(_hw) container_of(_hw, struct clk_gfm, hw)
|
||||
|
||||
static u8 clk_gfm_get_parent(struct clk_hw *hw)
|
||||
{
|
||||
struct clk_gfm *clk = to_clk_gfm(hw);
|
||||
|
||||
return readl(clk->gfm_mux) & GFM_MASK;
|
||||
}
|
||||
|
||||
static int clk_gfm_set_parent(struct clk_hw *hw, u8 index)
|
||||
{
|
||||
struct clk_gfm *clk = to_clk_gfm(hw);
|
||||
unsigned int val;
|
||||
|
||||
val = readl(clk->gfm_mux);
|
||||
|
||||
if (index)
|
||||
val |= GFM_MASK;
|
||||
else
|
||||
val &= ~GFM_MASK;
|
||||
|
||||
writel(val, clk->gfm_mux);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops clk_gfm_ops = {
|
||||
.get_parent = clk_gfm_get_parent,
|
||||
.set_parent = clk_gfm_set_parent,
|
||||
.determine_rate = __clk_mux_determine_rate,
|
||||
};
|
||||
|
||||
static struct clk_gfm lpass_gfm_va_mclk = {
|
||||
.mux_reg = 0x20000,
|
||||
.mux_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "VA_MCLK",
|
||||
.ops = &clk_gfm_ops,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
.num_parents = 2,
|
||||
.parent_data = (const struct clk_parent_data[]){
|
||||
{
|
||||
.index = 0,
|
||||
.fw_name = "LPASS_CLK_ID_TX_CORE_MCLK",
|
||||
}, {
|
||||
.index = 1,
|
||||
.fw_name = "LPASS_CLK_ID_VA_CORE_MCLK",
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_gfm lpass_gfm_tx_npl = {
|
||||
.mux_reg = 0x20000,
|
||||
.mux_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "TX_NPL",
|
||||
.ops = &clk_gfm_ops,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
.parent_data = (const struct clk_parent_data[]){
|
||||
{
|
||||
.index = 0,
|
||||
.fw_name = "LPASS_CLK_ID_TX_CORE_NPL_MCLK",
|
||||
}, {
|
||||
.index = 1,
|
||||
.fw_name = "LPASS_CLK_ID_VA_CORE_2X_MCLK",
|
||||
},
|
||||
},
|
||||
.num_parents = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_gfm lpass_gfm_wsa_mclk = {
|
||||
.mux_reg = 0x220d8,
|
||||
.mux_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "WSA_MCLK",
|
||||
.ops = &clk_gfm_ops,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
.parent_data = (const struct clk_parent_data[]){
|
||||
{
|
||||
.index = 0,
|
||||
.fw_name = "LPASS_CLK_ID_TX_CORE_MCLK",
|
||||
}, {
|
||||
.index = 1,
|
||||
.fw_name = "LPASS_CLK_ID_WSA_CORE_MCLK",
|
||||
},
|
||||
},
|
||||
.num_parents = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_gfm lpass_gfm_wsa_npl = {
|
||||
.mux_reg = 0x220d8,
|
||||
.mux_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "WSA_NPL",
|
||||
.ops = &clk_gfm_ops,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
.parent_data = (const struct clk_parent_data[]){
|
||||
{
|
||||
.index = 0,
|
||||
.fw_name = "LPASS_CLK_ID_TX_CORE_NPL_MCLK",
|
||||
}, {
|
||||
.index = 1,
|
||||
.fw_name = "LPASS_CLK_ID_WSA_CORE_NPL_MCLK",
|
||||
},
|
||||
},
|
||||
.num_parents = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_gfm lpass_gfm_rx_mclk_mclk2 = {
|
||||
.mux_reg = 0x240d8,
|
||||
.mux_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "RX_MCLK_MCLK2",
|
||||
.ops = &clk_gfm_ops,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
.parent_data = (const struct clk_parent_data[]){
|
||||
{
|
||||
.index = 0,
|
||||
.fw_name = "LPASS_CLK_ID_TX_CORE_MCLK",
|
||||
}, {
|
||||
.index = 1,
|
||||
.fw_name = "LPASS_CLK_ID_RX_CORE_MCLK",
|
||||
},
|
||||
},
|
||||
.num_parents = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_gfm lpass_gfm_rx_npl = {
|
||||
.mux_reg = 0x240d8,
|
||||
.mux_mask = BIT(0),
|
||||
.hw.init = &(struct clk_init_data) {
|
||||
.name = "RX_NPL",
|
||||
.ops = &clk_gfm_ops,
|
||||
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
|
||||
.parent_data = (const struct clk_parent_data[]){
|
||||
{
|
||||
.index = 0,
|
||||
.fw_name = "LPASS_CLK_ID_TX_CORE_NPL_MCLK",
|
||||
}, {
|
||||
.index = 1,
|
||||
.fw_name = "LPASS_CLK_ID_RX_CORE_NPL_MCLK",
|
||||
},
|
||||
},
|
||||
.num_parents = 2,
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_gfm *aoncc_gfm_clks[] = {
|
||||
[LPASS_CDC_VA_MCLK] = &lpass_gfm_va_mclk,
|
||||
[LPASS_CDC_TX_NPL] = &lpass_gfm_tx_npl,
|
||||
};
|
||||
|
||||
static struct clk_hw_onecell_data aoncc_hw_onecell_data = {
|
||||
.hws = {
|
||||
[LPASS_CDC_VA_MCLK] = &lpass_gfm_va_mclk.hw,
|
||||
[LPASS_CDC_TX_NPL] = &lpass_gfm_tx_npl.hw,
|
||||
},
|
||||
.num = ARRAY_SIZE(aoncc_gfm_clks),
|
||||
};
|
||||
|
||||
static struct clk_gfm *audiocc_gfm_clks[] = {
|
||||
[LPASS_CDC_WSA_NPL] = &lpass_gfm_wsa_npl,
|
||||
[LPASS_CDC_WSA_MCLK] = &lpass_gfm_wsa_mclk,
|
||||
[LPASS_CDC_RX_NPL] = &lpass_gfm_rx_npl,
|
||||
[LPASS_CDC_RX_MCLK_MCLK2] = &lpass_gfm_rx_mclk_mclk2,
|
||||
};
|
||||
|
||||
static struct clk_hw_onecell_data audiocc_hw_onecell_data = {
|
||||
.hws = {
|
||||
[LPASS_CDC_WSA_NPL] = &lpass_gfm_wsa_npl.hw,
|
||||
[LPASS_CDC_WSA_MCLK] = &lpass_gfm_wsa_mclk.hw,
|
||||
[LPASS_CDC_RX_NPL] = &lpass_gfm_rx_npl.hw,
|
||||
[LPASS_CDC_RX_MCLK_MCLK2] = &lpass_gfm_rx_mclk_mclk2.hw,
|
||||
},
|
||||
.num = ARRAY_SIZE(audiocc_gfm_clks),
|
||||
};
|
||||
|
||||
struct lpass_gfm_data {
|
||||
struct clk_hw_onecell_data *onecell_data;
|
||||
struct clk_gfm **gfm_clks;
|
||||
};
|
||||
|
||||
static struct lpass_gfm_data audiocc_data = {
|
||||
.onecell_data = &audiocc_hw_onecell_data,
|
||||
.gfm_clks = audiocc_gfm_clks,
|
||||
};
|
||||
|
||||
static struct lpass_gfm_data aoncc_data = {
|
||||
.onecell_data = &aoncc_hw_onecell_data,
|
||||
.gfm_clks = aoncc_gfm_clks,
|
||||
};
|
||||
|
||||
static int lpass_gfm_clk_driver_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct lpass_gfm_data *data;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct clk_gfm *gfm;
|
||||
struct lpass_gfm *cc;
|
||||
int err, i;
|
||||
|
||||
data = of_device_get_match_data(dev);
|
||||
if (!data)
|
||||
return -EINVAL;
|
||||
|
||||
cc = devm_kzalloc(dev, sizeof(*cc), GFP_KERNEL);
|
||||
if (!cc)
|
||||
return -ENOMEM;
|
||||
|
||||
cc->base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(cc->base))
|
||||
return PTR_ERR(cc->base);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
err = pm_clk_create(dev);
|
||||
if (err)
|
||||
goto pm_clk_err;
|
||||
|
||||
err = of_pm_clk_add_clks(dev);
|
||||
if (err < 0) {
|
||||
dev_dbg(dev, "Failed to get lpass core voting clocks\n");
|
||||
goto clk_reg_err;
|
||||
}
|
||||
|
||||
for (i = 0; i < data->onecell_data->num; i++) {
|
||||
if (!data->gfm_clks[i])
|
||||
continue;
|
||||
|
||||
gfm = data->gfm_clks[i];
|
||||
gfm->priv = cc;
|
||||
gfm->gfm_mux = cc->base;
|
||||
gfm->gfm_mux = gfm->gfm_mux + data->gfm_clks[i]->mux_reg;
|
||||
|
||||
err = devm_clk_hw_register(dev, &data->gfm_clks[i]->hw);
|
||||
if (err)
|
||||
goto clk_reg_err;
|
||||
|
||||
}
|
||||
|
||||
err = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get,
|
||||
data->onecell_data);
|
||||
if (err)
|
||||
goto clk_reg_err;
|
||||
|
||||
return 0;
|
||||
|
||||
clk_reg_err:
|
||||
pm_clk_destroy(dev);
|
||||
pm_clk_err:
|
||||
pm_runtime_disable(dev);
|
||||
return err;
|
||||
}
|
||||
|
||||
static const struct of_device_id lpass_gfm_clk_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,sm8250-lpass-aoncc",
|
||||
.data = &aoncc_data,
|
||||
},
|
||||
{
|
||||
.compatible = "qcom,sm8250-lpass-audiocc",
|
||||
.data = &audiocc_data,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lpass_gfm_clk_match_table);
|
||||
|
||||
static const struct dev_pm_ops lpass_gfm_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver lpass_gfm_clk_driver = {
|
||||
.probe = lpass_gfm_clk_driver_probe,
|
||||
.driver = {
|
||||
.name = "lpass-gfm-clk",
|
||||
.of_match_table = lpass_gfm_clk_match_table,
|
||||
.pm = &lpass_gfm_pm_ops,
|
||||
},
|
||||
};
|
||||
module_platform_driver(lpass_gfm_clk_driver);
|
||||
MODULE_LICENSE("GPL v2");
|
|
@ -356,12 +356,52 @@ static const struct qcom_cc_desc lpass_audio_hm_sc7180_desc = {
|
|||
.num_gdscs = ARRAY_SIZE(lpass_audio_hm_sc7180_gdscs),
|
||||
};
|
||||
|
||||
static void lpass_pm_runtime_disable(void *data)
|
||||
{
|
||||
pm_runtime_disable(data);
|
||||
}
|
||||
|
||||
static void lpass_pm_clk_destroy(void *data)
|
||||
{
|
||||
pm_clk_destroy(data);
|
||||
}
|
||||
|
||||
static int lpass_create_pm_clks(struct platform_device *pdev)
|
||||
{
|
||||
int ret;
|
||||
|
||||
pm_runtime_use_autosuspend(&pdev->dev);
|
||||
pm_runtime_set_autosuspend_delay(&pdev->dev, 500);
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
|
||||
ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_runtime_disable, &pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_clk_create(&pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
ret = devm_add_action_or_reset(&pdev->dev, lpass_pm_clk_destroy, &pdev->dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = pm_clk_add(&pdev->dev, "iface");
|
||||
if (ret < 0)
|
||||
dev_err(&pdev->dev, "failed to acquire iface clock\n");
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct qcom_cc_desc *desc;
|
||||
struct regmap *regmap;
|
||||
int ret;
|
||||
|
||||
ret = lpass_create_pm_clks(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
lpass_core_cc_sc7180_regmap_config.name = "lpass_audio_cc";
|
||||
desc = &lpass_audio_hm_sc7180_desc;
|
||||
ret = qcom_cc_probe_by_index(pdev, 1, desc);
|
||||
|
@ -386,12 +426,22 @@ static int lpass_core_cc_sc7180_probe(struct platform_device *pdev)
|
|||
clk_fabia_pll_configure(&lpass_lpaaudio_dig_pll, regmap,
|
||||
&lpass_lpaaudio_dig_pll_config);
|
||||
|
||||
return qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap);
|
||||
ret = qcom_cc_really_probe(pdev, &lpass_core_cc_sc7180_desc, regmap);
|
||||
|
||||
pm_runtime_mark_last_busy(&pdev->dev);
|
||||
pm_runtime_put_autosuspend(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int lpass_hm_core_probe(struct platform_device *pdev)
|
||||
{
|
||||
const struct qcom_cc_desc *desc;
|
||||
int ret;
|
||||
|
||||
ret = lpass_create_pm_clks(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
lpass_core_cc_sc7180_regmap_config.name = "lpass_hm_core";
|
||||
desc = &lpass_core_hm_sc7180_desc;
|
||||
|
@ -399,61 +449,28 @@ static int lpass_hm_core_probe(struct platform_device *pdev)
|
|||
return qcom_cc_probe_by_index(pdev, 0, desc);
|
||||
}
|
||||
|
||||
static const struct of_device_id lpass_core_cc_sc7180_match_table[] = {
|
||||
static const struct of_device_id lpass_hm_sc7180_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,sc7180-lpasshm",
|
||||
.data = lpass_hm_core_probe,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lpass_hm_sc7180_match_table);
|
||||
|
||||
static const struct of_device_id lpass_core_cc_sc7180_match_table[] = {
|
||||
{
|
||||
.compatible = "qcom,sc7180-lpasscorecc",
|
||||
.data = lpass_core_cc_sc7180_probe,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, lpass_core_cc_sc7180_match_table);
|
||||
|
||||
static int lpass_core_sc7180_probe(struct platform_device *pdev)
|
||||
{
|
||||
int (*clk_probe)(struct platform_device *p);
|
||||
int ret;
|
||||
|
||||
pm_runtime_enable(&pdev->dev);
|
||||
ret = pm_clk_create(&pdev->dev);
|
||||
if (ret)
|
||||
goto disable_pm_runtime;
|
||||
|
||||
ret = pm_clk_add(&pdev->dev, "iface");
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "failed to acquire iface clock\n");
|
||||
goto destroy_pm_clk;
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
clk_probe = of_device_get_match_data(&pdev->dev);
|
||||
if (!clk_probe)
|
||||
goto destroy_pm_clk;
|
||||
|
||||
ret = clk_probe(pdev);
|
||||
if (ret)
|
||||
goto destroy_pm_clk;
|
||||
|
||||
return 0;
|
||||
|
||||
destroy_pm_clk:
|
||||
pm_clk_destroy(&pdev->dev);
|
||||
|
||||
disable_pm_runtime:
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dev_pm_ops lpass_core_cc_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
|
||||
};
|
||||
|
||||
static struct platform_driver lpass_core_cc_sc7180_driver = {
|
||||
.probe = lpass_core_sc7180_probe,
|
||||
.probe = lpass_core_cc_sc7180_probe,
|
||||
.driver = {
|
||||
.name = "lpass_core_cc-sc7180",
|
||||
.of_match_table = lpass_core_cc_sc7180_match_table,
|
||||
|
@ -461,17 +478,43 @@ static struct platform_driver lpass_core_cc_sc7180_driver = {
|
|||
},
|
||||
};
|
||||
|
||||
static int __init lpass_core_cc_sc7180_init(void)
|
||||
{
|
||||
return platform_driver_register(&lpass_core_cc_sc7180_driver);
|
||||
}
|
||||
subsys_initcall(lpass_core_cc_sc7180_init);
|
||||
static const struct dev_pm_ops lpass_hm_pm_ops = {
|
||||
SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
|
||||
};
|
||||
|
||||
static void __exit lpass_core_cc_sc7180_exit(void)
|
||||
static struct platform_driver lpass_hm_sc7180_driver = {
|
||||
.probe = lpass_hm_core_probe,
|
||||
.driver = {
|
||||
.name = "lpass_hm-sc7180",
|
||||
.of_match_table = lpass_hm_sc7180_match_table,
|
||||
.pm = &lpass_hm_pm_ops,
|
||||
},
|
||||
};
|
||||
|
||||
static int __init lpass_sc7180_init(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&lpass_core_cc_sc7180_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = platform_driver_register(&lpass_hm_sc7180_driver);
|
||||
if (ret) {
|
||||
platform_driver_unregister(&lpass_core_cc_sc7180_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
subsys_initcall(lpass_sc7180_init);
|
||||
|
||||
static void __exit lpass_sc7180_exit(void)
|
||||
{
|
||||
platform_driver_unregister(&lpass_hm_sc7180_driver);
|
||||
platform_driver_unregister(&lpass_core_cc_sc7180_driver);
|
||||
}
|
||||
module_exit(lpass_core_cc_sc7180_exit);
|
||||
module_exit(lpass_sc7180_exit);
|
||||
|
||||
MODULE_DESCRIPTION("QTI LPASS_CORE_CC SC7180 Driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -121,7 +121,7 @@ sh73a0_cpg_register_clock(struct device_node *np, struct sh73a0_cpg *cpg,
|
|||
(phy_no ? CPG_DSI1PHYCR : CPG_DSI0PHYCR);
|
||||
|
||||
parent_name = phy_no ? "dsi1pck" : "dsi0pck";
|
||||
mult = __raw_readl(dsi_reg);
|
||||
mult = readl(dsi_reg);
|
||||
if (!(mult & 0x8000))
|
||||
mult = 1;
|
||||
else
|
||||
|
|
|
@ -41,6 +41,7 @@ enum clk_ids {
|
|||
CLK_S2,
|
||||
CLK_S3,
|
||||
CLK_SDSRC,
|
||||
CLK_RPCSRC,
|
||||
CLK_RINT,
|
||||
|
||||
/* Module Clocks */
|
||||
|
@ -67,6 +68,12 @@ static const struct cpg_core_clk r8a774a1_core_clks[] __initconst = {
|
|||
DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
|
||||
DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
|
||||
DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
|
||||
DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
|
||||
|
||||
DEF_BASE("rpc", R8A774A1_CLK_RPC, CLK_TYPE_GEN3_RPC,
|
||||
CLK_RPCSRC),
|
||||
DEF_BASE("rpcd2", R8A774A1_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
|
||||
R8A774A1_CLK_RPC),
|
||||
|
||||
DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
|
||||
|
||||
|
@ -200,6 +207,7 @@ static const struct mssr_mod_clk r8a774a1_mod_clks[] __initconst = {
|
|||
DEF_MOD("can-fd", 914, R8A774A1_CLK_S3D2),
|
||||
DEF_MOD("can-if1", 915, R8A774A1_CLK_S3D4),
|
||||
DEF_MOD("can-if0", 916, R8A774A1_CLK_S3D4),
|
||||
DEF_MOD("rpc-if", 917, R8A774A1_CLK_RPCD2),
|
||||
DEF_MOD("i2c6", 918, R8A774A1_CLK_S0D6),
|
||||
DEF_MOD("i2c5", 919, R8A774A1_CLK_S0D6),
|
||||
DEF_MOD("i2c-dvfs", 926, R8A774A1_CLK_CP),
|
||||
|
|
|
@ -40,6 +40,7 @@ enum clk_ids {
|
|||
CLK_S2,
|
||||
CLK_S3,
|
||||
CLK_SDSRC,
|
||||
CLK_RPCSRC,
|
||||
CLK_RINT,
|
||||
|
||||
/* Module Clocks */
|
||||
|
@ -65,6 +66,12 @@ static const struct cpg_core_clk r8a774b1_core_clks[] __initconst = {
|
|||
DEF_FIXED(".s2", CLK_S2, CLK_PLL1_DIV2, 4, 1),
|
||||
DEF_FIXED(".s3", CLK_S3, CLK_PLL1_DIV2, 6, 1),
|
||||
DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1_DIV2, 2, 1),
|
||||
DEF_BASE(".rpcsrc", CLK_RPCSRC, CLK_TYPE_GEN3_RPCSRC, CLK_PLL1),
|
||||
|
||||
DEF_BASE("rpc", R8A774B1_CLK_RPC, CLK_TYPE_GEN3_RPC,
|
||||
CLK_RPCSRC),
|
||||
DEF_BASE("rpcd2", R8A774B1_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
|
||||
R8A774B1_CLK_RPC),
|
||||
|
||||
DEF_GEN3_OSC(".r", CLK_RINT, CLK_EXTAL, 32),
|
||||
|
||||
|
@ -196,6 +203,7 @@ static const struct mssr_mod_clk r8a774b1_mod_clks[] __initconst = {
|
|||
DEF_MOD("can-fd", 914, R8A774B1_CLK_S3D2),
|
||||
DEF_MOD("can-if1", 915, R8A774B1_CLK_S3D4),
|
||||
DEF_MOD("can-if0", 916, R8A774B1_CLK_S3D4),
|
||||
DEF_MOD("rpc-if", 917, R8A774B1_CLK_RPCD2),
|
||||
DEF_MOD("i2c6", 918, R8A774B1_CLK_S0D6),
|
||||
DEF_MOD("i2c5", 919, R8A774B1_CLK_S0D6),
|
||||
DEF_MOD("i2c-dvfs", 926, R8A774B1_CLK_CP),
|
||||
|
|
|
@ -44,6 +44,7 @@ enum clk_ids {
|
|||
CLK_S2,
|
||||
CLK_S3,
|
||||
CLK_SDSRC,
|
||||
CLK_RPCSRC,
|
||||
CLK_RINT,
|
||||
CLK_OCO,
|
||||
|
||||
|
@ -74,6 +75,13 @@ static const struct cpg_core_clk r8a774c0_core_clks[] __initconst = {
|
|||
DEF_FIXED(".s3", CLK_S3, CLK_PLL1, 6, 1),
|
||||
DEF_FIXED(".sdsrc", CLK_SDSRC, CLK_PLL1, 2, 1),
|
||||
|
||||
DEF_FIXED_RPCSRC_E3(".rpcsrc", CLK_RPCSRC, CLK_PLL0, CLK_PLL1),
|
||||
|
||||
DEF_BASE("rpc", R8A774C0_CLK_RPC, CLK_TYPE_GEN3_RPC,
|
||||
CLK_RPCSRC),
|
||||
DEF_BASE("rpcd2", R8A774C0_CLK_RPCD2, CLK_TYPE_GEN3_RPCD2,
|
||||
R8A774C0_CLK_RPC),
|
||||
|
||||
DEF_DIV6_RO(".r", CLK_RINT, CLK_EXTAL, CPG_RCKCR, 32),
|
||||
|
||||
DEF_RATE(".oco", CLK_OCO, 8 * 1000 * 1000),
|
||||
|
@ -199,6 +207,7 @@ static const struct mssr_mod_clk r8a774c0_mod_clks[] __initconst = {
|
|||
DEF_MOD("can-fd", 914, R8A774C0_CLK_S3D2),
|
||||
DEF_MOD("can-if1", 915, R8A774C0_CLK_S3D4),
|
||||
DEF_MOD("can-if0", 916, R8A774C0_CLK_S3D4),
|
||||
DEF_MOD("rpc-if", 917, R8A774C0_CLK_RPCD2),
|
||||
DEF_MOD("i2c6", 918, R8A774C0_CLK_S3D2),
|
||||
DEF_MOD("i2c5", 919, R8A774C0_CLK_S3D2),
|
||||
DEF_MOD("i2c-dvfs", 926, R8A774C0_CLK_CP),
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
#include <dt-bindings/clock/r8a779a0-cpg-mssr.h>
|
||||
|
||||
#include "renesas-cpg-mssr.h"
|
||||
#include "rcar-gen3-cpg.h"
|
||||
|
||||
enum rcar_r8a779a0_clk_types {
|
||||
CLK_TYPE_R8A779A0_MAIN = CLK_TYPE_CUSTOM,
|
||||
|
@ -84,6 +83,14 @@ enum clk_ids {
|
|||
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_PLL2X_3X, CLK_MAIN, \
|
||||
.offset = _offset)
|
||||
|
||||
#define DEF_MDSEL(_name, _id, _md, _parent0, _div0, _parent1, _div1) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_MDSEL, \
|
||||
(_parent0) << 16 | (_parent1), \
|
||||
.div = (_div0) << 16 | (_div1), .offset = _md)
|
||||
|
||||
#define DEF_OSC(_name, _id, _parent, _div) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_R8A779A0_OSC, _parent, .div = _div)
|
||||
|
||||
static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
|
||||
/* External Clock Inputs */
|
||||
DEF_INPUT("extal", CLK_EXTAL),
|
||||
|
@ -136,15 +143,51 @@ static const struct cpg_core_clk r8a779a0_core_clks[] __initconst = {
|
|||
DEF_DIV6P1("canfd", R8A779A0_CLK_CANFD, CLK_PLL5_DIV4, 0x878),
|
||||
DEF_DIV6P1("csi0", R8A779A0_CLK_CSI0, CLK_PLL5_DIV4, 0x880),
|
||||
|
||||
DEF_GEN3_OSC("osc", R8A779A0_CLK_OSC, CLK_EXTAL, 8),
|
||||
DEF_GEN3_MDSEL("r", R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
|
||||
DEF_OSC("osc", R8A779A0_CLK_OSC, CLK_EXTAL, 8),
|
||||
DEF_MDSEL("r", R8A779A0_CLK_R, 29, CLK_EXTALR, 1, CLK_OCO, 1),
|
||||
};
|
||||
|
||||
static const struct mssr_mod_clk r8a779a0_mod_clks[] __initconst = {
|
||||
DEF_MOD("csi40", 331, R8A779A0_CLK_CSI0),
|
||||
DEF_MOD("csi41", 400, R8A779A0_CLK_CSI0),
|
||||
DEF_MOD("csi42", 401, R8A779A0_CLK_CSI0),
|
||||
DEF_MOD("csi43", 402, R8A779A0_CLK_CSI0),
|
||||
DEF_MOD("scif0", 702, R8A779A0_CLK_S1D8),
|
||||
DEF_MOD("scif1", 703, R8A779A0_CLK_S1D8),
|
||||
DEF_MOD("scif3", 704, R8A779A0_CLK_S1D8),
|
||||
DEF_MOD("scif4", 705, R8A779A0_CLK_S1D8),
|
||||
DEF_MOD("vin00", 730, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin01", 731, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin02", 800, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin03", 801, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin04", 802, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin05", 803, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin06", 804, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin07", 805, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin10", 806, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin11", 807, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin12", 808, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin13", 809, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin14", 810, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin15", 811, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin16", 812, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin17", 813, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin20", 814, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin21", 815, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin22", 816, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin23", 817, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin24", 818, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin25", 819, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin26", 820, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin27", 821, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin30", 822, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin31", 823, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin32", 824, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin33", 825, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin34", 826, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin35", 827, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin36", 828, R8A779A0_CLK_S1D1),
|
||||
DEF_MOD("vin37", 829, R8A779A0_CLK_S1D1),
|
||||
};
|
||||
|
||||
static spinlock_t cpg_lock;
|
||||
|
@ -153,7 +196,7 @@ static const struct rcar_r8a779a0_cpg_pll_config *cpg_pll_config __initdata;
|
|||
static unsigned int cpg_clk_extalr __initdata;
|
||||
static u32 cpg_mode __initdata;
|
||||
|
||||
struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
|
||||
static struct clk * __init rcar_r8a779a0_cpg_clk_register(struct device *dev,
|
||||
const struct cpg_core_clk *core, const struct cpg_mssr_info *info,
|
||||
struct clk **clks, void __iomem *base,
|
||||
struct raw_notifier_head *notifiers)
|
||||
|
|
|
@ -224,10 +224,9 @@ static struct clk * __init cpg_z_clk_register(const char *name,
|
|||
#define CPG_SD_STP_MASK (CPG_SD_STP_HCK | CPG_SD_STP_CK)
|
||||
#define CPG_SD_FC_MASK (0x7 << 2 | 0x3 << 0)
|
||||
|
||||
#define CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) \
|
||||
#define CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) \
|
||||
{ \
|
||||
.val = ((stp_hck) ? CPG_SD_STP_HCK : 0) | \
|
||||
((stp_ck) ? CPG_SD_STP_CK : 0) | \
|
||||
((sd_srcfc) << 2) | \
|
||||
((sd_fc) << 0), \
|
||||
.div = (sd_div), \
|
||||
|
@ -247,36 +246,36 @@ struct sd_clock {
|
|||
};
|
||||
|
||||
/* SDn divider
|
||||
* sd_srcfc sd_fc div
|
||||
* stp_hck stp_ck (div) (div) = sd_srcfc x sd_fc
|
||||
*-------------------------------------------------------------------
|
||||
* 0 0 0 (1) 1 (4) 4 : SDR104 / HS200 / HS400 (8 TAP)
|
||||
* 0 0 1 (2) 1 (4) 8 : SDR50
|
||||
* 1 0 2 (4) 1 (4) 16 : HS / SDR25
|
||||
* 1 0 3 (8) 1 (4) 32 : NS / SDR12
|
||||
* 1 0 4 (16) 1 (4) 64
|
||||
* 0 0 0 (1) 0 (2) 2
|
||||
* 0 0 1 (2) 0 (2) 4 : SDR104 / HS200 / HS400 (4 TAP)
|
||||
* 1 0 2 (4) 0 (2) 8
|
||||
* 1 0 3 (8) 0 (2) 16
|
||||
* 1 0 4 (16) 0 (2) 32
|
||||
* sd_srcfc sd_fc div
|
||||
* stp_hck (div) (div) = sd_srcfc x sd_fc
|
||||
*---------------------------------------------------------
|
||||
* 0 0 (1) 1 (4) 4 : SDR104 / HS200 / HS400 (8 TAP)
|
||||
* 0 1 (2) 1 (4) 8 : SDR50
|
||||
* 1 2 (4) 1 (4) 16 : HS / SDR25
|
||||
* 1 3 (8) 1 (4) 32 : NS / SDR12
|
||||
* 1 4 (16) 1 (4) 64
|
||||
* 0 0 (1) 0 (2) 2
|
||||
* 0 1 (2) 0 (2) 4 : SDR104 / HS200 / HS400 (4 TAP)
|
||||
* 1 2 (4) 0 (2) 8
|
||||
* 1 3 (8) 0 (2) 16
|
||||
* 1 4 (16) 0 (2) 32
|
||||
*
|
||||
* NOTE: There is a quirk option to ignore the first row of the dividers
|
||||
* table when searching for suitable settings. This is because HS400 on
|
||||
* early ES versions of H3 and M3-W requires a specific setting to work.
|
||||
*/
|
||||
static const struct sd_div_table cpg_sd_div_table[] = {
|
||||
/* CPG_SD_DIV_TABLE_DATA(stp_hck, stp_ck, sd_srcfc, sd_fc, sd_div) */
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 1, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 1, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 2, 1, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 3, 1, 32),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 4, 1, 64),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 0, 2),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 0, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 2, 0, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 3, 0, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 0, 4, 0, 32),
|
||||
/* CPG_SD_DIV_TABLE_DATA(stp_hck, sd_srcfc, sd_fc, sd_div) */
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 1, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 1, 1, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 2, 1, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 3, 1, 32),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 4, 1, 64),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 0, 0, 2),
|
||||
CPG_SD_DIV_TABLE_DATA(0, 1, 0, 4),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 2, 0, 8),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 3, 0, 16),
|
||||
CPG_SD_DIV_TABLE_DATA(1, 4, 0, 32),
|
||||
};
|
||||
|
||||
#define to_sd_clock(_hw) container_of(_hw, struct sd_clock, hw)
|
||||
|
@ -696,6 +695,34 @@ struct clk * __init rcar_gen3_cpg_clk_register(struct device *dev,
|
|||
cpg_rpcsrc_div_table,
|
||||
&cpg_lock);
|
||||
|
||||
case CLK_TYPE_GEN3_E3_RPCSRC:
|
||||
/*
|
||||
* Register RPCSRC as fixed factor clock based on the
|
||||
* MD[4:1] pins and CPG_RPCCKCR[4:3] register value for
|
||||
* which has been set prior to booting the kernel.
|
||||
*/
|
||||
value = (readl(base + CPG_RPCCKCR) & GENMASK(4, 3)) >> 3;
|
||||
|
||||
switch (value) {
|
||||
case 0:
|
||||
div = 5;
|
||||
break;
|
||||
case 1:
|
||||
div = 3;
|
||||
break;
|
||||
case 2:
|
||||
parent = clks[core->parent >> 16];
|
||||
if (IS_ERR(parent))
|
||||
return ERR_CAST(parent);
|
||||
div = core->div;
|
||||
break;
|
||||
case 3:
|
||||
default:
|
||||
div = 2;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CLK_TYPE_GEN3_RPC:
|
||||
return cpg_rpc_clk_register(core->name, base,
|
||||
__clk_get_name(parent), notifiers);
|
||||
|
|
|
@ -24,6 +24,7 @@ enum rcar_gen3_clk_types {
|
|||
CLK_TYPE_GEN3_OSC, /* OSC EXTAL predivider and fixed divider */
|
||||
CLK_TYPE_GEN3_RCKSEL, /* Select parent/divider using RCKCR.CKSEL */
|
||||
CLK_TYPE_GEN3_RPCSRC,
|
||||
CLK_TYPE_GEN3_E3_RPCSRC,
|
||||
CLK_TYPE_GEN3_RPC,
|
||||
CLK_TYPE_GEN3_RPCD2,
|
||||
|
||||
|
@ -54,6 +55,10 @@ enum rcar_gen3_clk_types {
|
|||
#define DEF_GEN3_Z(_name, _id, _type, _parent, _div, _offset) \
|
||||
DEF_BASE(_name, _id, _type, _parent, .div = _div, .offset = _offset)
|
||||
|
||||
#define DEF_FIXED_RPCSRC_E3(_name, _id, _parent0, _parent1) \
|
||||
DEF_BASE(_name, _id, CLK_TYPE_GEN3_E3_RPCSRC, \
|
||||
(_parent0) << 16 | (_parent1), .div = 8)
|
||||
|
||||
struct rcar_gen3_cpg_pll_config {
|
||||
u8 extal_div;
|
||||
u8 pll1_mult;
|
||||
|
|
|
@ -160,7 +160,7 @@ static int rcar_usb2_clock_sel_probe(struct platform_device *pdev)
|
|||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
priv->rsts = devm_reset_control_array_get(dev, true, false);
|
||||
priv->rsts = devm_reset_control_array_get_shared(dev);
|
||||
if (IS_ERR(priv->rsts))
|
||||
return PTR_ERR(priv->rsts);
|
||||
|
||||
|
|
|
@ -119,7 +119,8 @@ static const u16 srstclr_for_v3u[] = {
|
|||
};
|
||||
|
||||
/**
|
||||
* Clock Pulse Generator / Module Standby and Software Reset Private Data
|
||||
* struct cpg_mssr_priv - Clock Pulse Generator / Module Standby
|
||||
* and Software Reset Private Data
|
||||
*
|
||||
* @rcdev: Optional reset controller entity
|
||||
* @dev: CPG/MSSR device
|
||||
|
|
|
@ -2,10 +2,73 @@
|
|||
# Recent Exynos platforms should just select COMMON_CLK_SAMSUNG:
|
||||
config COMMON_CLK_SAMSUNG
|
||||
bool "Samsung Exynos clock controller support" if COMPILE_TEST
|
||||
# Clocks on ARM64 SoCs (e.g. Exynos5433, Exynos7) are chosen by
|
||||
# EXYNOS_ARM64_COMMON_CLK to avoid building them on ARMv7:
|
||||
select S3C64XX_COMMON_CLK if ARM && ARCH_S3C64XX
|
||||
select S5PV210_COMMON_CLK if ARM && ARCH_S5PV210
|
||||
select EXYNOS_3250_COMMON_CLK if ARM && SOC_EXYNOS3250
|
||||
select EXYNOS_4_COMMON_CLK if ARM && ARCH_EXYNOS4
|
||||
select EXYNOS_5250_COMMON_CLK if ARM && SOC_EXYNOS5250
|
||||
select EXYNOS_5260_COMMON_CLK if ARM && SOC_EXYNOS5260
|
||||
select EXYNOS_5410_COMMON_CLK if ARM && SOC_EXYNOS5410
|
||||
select EXYNOS_5420_COMMON_CLK if ARM && SOC_EXYNOS5420
|
||||
select EXYNOS_ARM64_COMMON_CLK if ARM64 && ARCH_EXYNOS
|
||||
|
||||
config S3C64XX_COMMON_CLK
|
||||
bool "Samsung S3C64xx clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung S3C64xx SoCs.
|
||||
Choose Y here only if you build for this SoC.
|
||||
|
||||
config S5PV210_COMMON_CLK
|
||||
bool "Samsung S5Pv210 clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung S5Pv210 SoCs.
|
||||
Choose Y here only if you build for this SoC.
|
||||
|
||||
config EXYNOS_3250_COMMON_CLK
|
||||
bool "Samsung Exynos3250 clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
Exynos3250 SoCs. Choose Y here only if you build for this SoC.
|
||||
|
||||
config EXYNOS_4_COMMON_CLK
|
||||
bool "Samsung Exynos4 clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
Exynos4212 and Exynos4412 SoCs. Choose Y here only if you build for
|
||||
this SoC.
|
||||
|
||||
config EXYNOS_5250_COMMON_CLK
|
||||
bool "Samsung Exynos5250 clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
Exynos5250 SoCs. Choose Y here only if you build for this SoC.
|
||||
|
||||
config EXYNOS_5260_COMMON_CLK
|
||||
bool "Samsung Exynos5260 clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
Exynos5260 SoCs. Choose Y here only if you build for this SoC.
|
||||
|
||||
config EXYNOS_5410_COMMON_CLK
|
||||
bool "Samsung Exynos5410 clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
Exynos5410 SoCs. Choose Y here only if you build for this SoC.
|
||||
|
||||
config EXYNOS_5420_COMMON_CLK
|
||||
bool "Samsung Exynos5420 clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
help
|
||||
Support for the clock controller present on the Samsung
|
||||
Exynos5420 SoCs. Choose Y here only if you build for this SoC.
|
||||
|
||||
config EXYNOS_ARM64_COMMON_CLK
|
||||
bool "Samsung Exynos ARMv8-family clock controller support" if COMPILE_TEST
|
||||
depends on COMMON_CLK_SAMSUNG
|
||||
|
|
|
@ -4,15 +4,15 @@
|
|||
#
|
||||
|
||||
obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o clk-cpu.o
|
||||
obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4412-isp.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5-subcmu.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o
|
||||
obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5-subcmu.o
|
||||
obj-$(CONFIG_EXYNOS_3250_COMMON_CLK) += clk-exynos3250.o
|
||||
obj-$(CONFIG_EXYNOS_4_COMMON_CLK) += clk-exynos4.o
|
||||
obj-$(CONFIG_EXYNOS_4_COMMON_CLK) += clk-exynos4412-isp.o
|
||||
obj-$(CONFIG_EXYNOS_5250_COMMON_CLK) += clk-exynos5250.o
|
||||
obj-$(CONFIG_EXYNOS_5250_COMMON_CLK) += clk-exynos5-subcmu.o
|
||||
obj-$(CONFIG_EXYNOS_5260_COMMON_CLK) += clk-exynos5260.o
|
||||
obj-$(CONFIG_EXYNOS_5410_COMMON_CLK) += clk-exynos5410.o
|
||||
obj-$(CONFIG_EXYNOS_5420_COMMON_CLK) += clk-exynos5420.o
|
||||
obj-$(CONFIG_EXYNOS_5420_COMMON_CLK) += clk-exynos5-subcmu.o
|
||||
obj-$(CONFIG_EXYNOS_ARM64_COMMON_CLK) += clk-exynos5433.o
|
||||
obj-$(CONFIG_EXYNOS_AUDSS_CLK_CON) += clk-exynos-audss.o
|
||||
obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-clkout.o
|
||||
|
@ -21,5 +21,5 @@ obj-$(CONFIG_S3C2410_COMMON_CLK)+= clk-s3c2410.o
|
|||
obj-$(CONFIG_S3C2410_COMMON_DCLK)+= clk-s3c2410-dclk.o
|
||||
obj-$(CONFIG_S3C2412_COMMON_CLK)+= clk-s3c2412.o
|
||||
obj-$(CONFIG_S3C2443_COMMON_CLK)+= clk-s3c2443.o
|
||||
obj-$(CONFIG_ARCH_S3C64XX) += clk-s3c64xx.o
|
||||
obj-$(CONFIG_ARCH_S5PV210) += clk-s5pv210.o clk-s5pv210-audss.o
|
||||
obj-$(CONFIG_S3C64XX_COMMON_CLK) += clk-s3c64xx.o
|
||||
obj-$(CONFIG_S5PV210_COMMON_CLK) += clk-s5pv210.o clk-s5pv210-audss.o
|
||||
|
|
|
@ -8,14 +8,17 @@
|
|||
|
||||
#include <linux/errno.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/iopoll.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/timekeeping.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include "clk.h"
|
||||
#include "clk-pll.h"
|
||||
|
||||
#define PLL_TIMEOUT_MS 10
|
||||
#define PLL_TIMEOUT_US 20000U
|
||||
#define PLL_TIMEOUT_LOOPS 1000000U
|
||||
|
||||
struct samsung_clk_pll {
|
||||
struct clk_hw hw;
|
||||
|
@ -63,6 +66,53 @@ static long samsung_pll_round_rate(struct clk_hw *hw,
|
|||
return rate_table[i - 1].rate;
|
||||
}
|
||||
|
||||
static bool pll_early_timeout = true;
|
||||
|
||||
static int __init samsung_pll_disable_early_timeout(void)
|
||||
{
|
||||
pll_early_timeout = false;
|
||||
return 0;
|
||||
}
|
||||
arch_initcall(samsung_pll_disable_early_timeout);
|
||||
|
||||
/* Wait until the PLL is locked */
|
||||
static int samsung_pll_lock_wait(struct samsung_clk_pll *pll,
|
||||
unsigned int reg_mask)
|
||||
{
|
||||
int i, ret;
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* This function might be called when the timekeeping API can't be used
|
||||
* to detect timeouts. One situation is when the clocksource is not yet
|
||||
* initialized, another when the timekeeping is suspended. udelay() also
|
||||
* cannot be used when the clocksource is not running on arm64, since
|
||||
* the current timer is used as cycle counter. So a simple busy loop
|
||||
* is used here in that special cases. The limit of iterations has been
|
||||
* derived from experimental measurements of various PLLs on multiple
|
||||
* Exynos SoC variants. Single register read time was usually in range
|
||||
* 0.4...1.5 us, never less than 0.4 us.
|
||||
*/
|
||||
if (pll_early_timeout || timekeeping_suspended) {
|
||||
i = PLL_TIMEOUT_LOOPS;
|
||||
while (i-- > 0) {
|
||||
if (readl_relaxed(pll->con_reg) & reg_mask)
|
||||
return 0;
|
||||
|
||||
cpu_relax();
|
||||
}
|
||||
ret = -ETIMEDOUT;
|
||||
} else {
|
||||
ret = readl_relaxed_poll_timeout_atomic(pll->con_reg, val,
|
||||
val & reg_mask, 0, PLL_TIMEOUT_US);
|
||||
}
|
||||
|
||||
if (ret < 0)
|
||||
pr_err("Could not lock PLL %s\n", clk_hw_get_name(&pll->hw));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int samsung_pll3xxx_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
|
@ -72,13 +122,7 @@ static int samsung_pll3xxx_enable(struct clk_hw *hw)
|
|||
tmp |= BIT(pll->enable_offs);
|
||||
writel_relaxed(tmp, pll->con_reg);
|
||||
|
||||
/* wait lock time */
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & BIT(pll->lock_offs)));
|
||||
|
||||
return 0;
|
||||
return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
|
||||
}
|
||||
|
||||
static void samsung_pll3xxx_disable(struct clk_hw *hw)
|
||||
|
@ -240,13 +284,10 @@ static int samsung_pll35xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
(rate->sdiv << PLL35XX_SDIV_SHIFT);
|
||||
writel_relaxed(tmp, pll->con_reg);
|
||||
|
||||
/* Wait until the PLL is locked if it is enabled. */
|
||||
if (tmp & BIT(pll->enable_offs)) {
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & BIT(pll->lock_offs)));
|
||||
}
|
||||
/* Wait for PLL lock if the PLL is enabled */
|
||||
if (tmp & BIT(pll->enable_offs))
|
||||
return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -318,7 +359,7 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 tmp, pll_con0, pll_con1;
|
||||
u32 pll_con0, pll_con1;
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
|
@ -356,13 +397,8 @@ static int samsung_pll36xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
pll_con1 |= rate->kdiv << PLL36XX_KDIV_SHIFT;
|
||||
writel_relaxed(pll_con1, pll->con_reg + 4);
|
||||
|
||||
/* wait_lock_time */
|
||||
if (pll_con0 & BIT(pll->enable_offs)) {
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & BIT(pll->lock_offs)));
|
||||
}
|
||||
if (pll_con0 & BIT(pll->enable_offs))
|
||||
return samsung_pll_lock_wait(pll, BIT(pll->lock_offs));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -437,7 +473,6 @@ static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
u32 con0, con1;
|
||||
ktime_t start;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
|
@ -488,21 +523,8 @@ static int samsung_pll45xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
writel_relaxed(con1, pll->con_reg + 0x4);
|
||||
writel_relaxed(con0, pll->con_reg);
|
||||
|
||||
/* Wait for locking. */
|
||||
start = ktime_get();
|
||||
while (!(readl_relaxed(pll->con_reg) & PLL45XX_LOCKED)) {
|
||||
ktime_t delta = ktime_sub(ktime_get(), start);
|
||||
|
||||
if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
|
||||
pr_err("%s: could not lock PLL %s\n",
|
||||
__func__, clk_hw_get_name(hw));
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Wait for PLL lock */
|
||||
return samsung_pll_lock_wait(pll, PLL45XX_LOCKED);
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll45xx_clk_ops = {
|
||||
|
@ -588,7 +610,6 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
u32 con0, con1, lock;
|
||||
ktime_t start;
|
||||
|
||||
/* Get required rate settings from table */
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
|
@ -647,21 +668,8 @@ static int samsung_pll46xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
writel_relaxed(con0, pll->con_reg);
|
||||
writel_relaxed(con1, pll->con_reg + 0x4);
|
||||
|
||||
/* Wait for locking. */
|
||||
start = ktime_get();
|
||||
while (!(readl_relaxed(pll->con_reg) & PLL46XX_LOCKED)) {
|
||||
ktime_t delta = ktime_sub(ktime_get(), start);
|
||||
|
||||
if (ktime_to_ms(delta) > PLL_TIMEOUT_MS) {
|
||||
pr_err("%s: could not lock PLL %s\n",
|
||||
__func__, clk_hw_get_name(hw));
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
cpu_relax();
|
||||
}
|
||||
|
||||
return 0;
|
||||
/* Wait for PLL lock */
|
||||
return samsung_pll_lock_wait(pll, PLL46XX_LOCKED);
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll46xx_clk_ops = {
|
||||
|
@ -1035,14 +1043,9 @@ static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
(rate->sdiv << PLL2550XX_S_SHIFT);
|
||||
writel_relaxed(tmp, pll->con_reg);
|
||||
|
||||
/* wait_lock_time */
|
||||
do {
|
||||
cpu_relax();
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & (PLL2550XX_LOCK_STAT_MASK
|
||||
<< PLL2550XX_LOCK_STAT_SHIFT)));
|
||||
|
||||
return 0;
|
||||
/* Wait for PLL lock */
|
||||
return samsung_pll_lock_wait(pll,
|
||||
PLL2550XX_LOCK_STAT_MASK << PLL2550XX_LOCK_STAT_SHIFT);
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll2550xx_clk_ops = {
|
||||
|
@ -1132,13 +1135,9 @@ static int samsung_pll2650x_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
con1 |= ((rate->kdiv & PLL2650X_K_MASK) << PLL2650X_K_SHIFT);
|
||||
writel_relaxed(con1, pll->con_reg + 4);
|
||||
|
||||
do {
|
||||
cpu_relax();
|
||||
con0 = readl_relaxed(pll->con_reg);
|
||||
} while (!(con0 & (PLL2650X_LOCK_STAT_MASK
|
||||
<< PLL2650X_LOCK_STAT_SHIFT)));
|
||||
|
||||
return 0;
|
||||
/* Wait for PLL lock */
|
||||
return samsung_pll_lock_wait(pll,
|
||||
PLL2650X_LOCK_STAT_MASK << PLL2650X_LOCK_STAT_SHIFT);
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll2650x_clk_ops = {
|
||||
|
@ -1196,7 +1195,7 @@ static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
unsigned long parent_rate)
|
||||
{
|
||||
struct samsung_clk_pll *pll = to_clk_pll(hw);
|
||||
u32 tmp, pll_con0, pll_con2;
|
||||
u32 pll_con0, pll_con2;
|
||||
const struct samsung_pll_rate_table *rate;
|
||||
|
||||
rate = samsung_get_pll_settings(pll, drate);
|
||||
|
@ -1229,11 +1228,7 @@ static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate,
|
|||
writel_relaxed(pll_con0, pll->con_reg);
|
||||
writel_relaxed(pll_con2, pll->con_reg + 8);
|
||||
|
||||
do {
|
||||
tmp = readl_relaxed(pll->con_reg);
|
||||
} while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT)));
|
||||
|
||||
return 0;
|
||||
return samsung_pll_lock_wait(pll, 0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT);
|
||||
}
|
||||
|
||||
static const struct clk_ops samsung_pll2650xx_clk_ops = {
|
||||
|
|
|
@ -0,0 +1,121 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Copyright (c) 2020, The Linux Foundation. All rights reserved.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H
|
||||
#define _DT_BINDINGS_CLK_QCOM_CAM_CC_SC7180_H
|
||||
|
||||
/* CAM_CC clocks */
|
||||
#define CAM_CC_PLL2_OUT_EARLY 0
|
||||
#define CAM_CC_PLL0 1
|
||||
#define CAM_CC_PLL1 2
|
||||
#define CAM_CC_PLL2 3
|
||||
#define CAM_CC_PLL2_OUT_AUX 4
|
||||
#define CAM_CC_PLL3 5
|
||||
#define CAM_CC_CAMNOC_AXI_CLK 6
|
||||
#define CAM_CC_CCI_0_CLK 7
|
||||
#define CAM_CC_CCI_0_CLK_SRC 8
|
||||
#define CAM_CC_CCI_1_CLK 9
|
||||
#define CAM_CC_CCI_1_CLK_SRC 10
|
||||
#define CAM_CC_CORE_AHB_CLK 11
|
||||
#define CAM_CC_CPAS_AHB_CLK 12
|
||||
#define CAM_CC_CPHY_RX_CLK_SRC 13
|
||||
#define CAM_CC_CSI0PHYTIMER_CLK 14
|
||||
#define CAM_CC_CSI0PHYTIMER_CLK_SRC 15
|
||||
#define CAM_CC_CSI1PHYTIMER_CLK 16
|
||||
#define CAM_CC_CSI1PHYTIMER_CLK_SRC 17
|
||||
#define CAM_CC_CSI2PHYTIMER_CLK 18
|
||||
#define CAM_CC_CSI2PHYTIMER_CLK_SRC 19
|
||||
#define CAM_CC_CSI3PHYTIMER_CLK 20
|
||||
#define CAM_CC_CSI3PHYTIMER_CLK_SRC 21
|
||||
#define CAM_CC_CSIPHY0_CLK 22
|
||||
#define CAM_CC_CSIPHY1_CLK 23
|
||||
#define CAM_CC_CSIPHY2_CLK 24
|
||||
#define CAM_CC_CSIPHY3_CLK 25
|
||||
#define CAM_CC_FAST_AHB_CLK_SRC 26
|
||||
#define CAM_CC_ICP_APB_CLK 27
|
||||
#define CAM_CC_ICP_ATB_CLK 28
|
||||
#define CAM_CC_ICP_CLK 29
|
||||
#define CAM_CC_ICP_CLK_SRC 30
|
||||
#define CAM_CC_ICP_CTI_CLK 31
|
||||
#define CAM_CC_ICP_TS_CLK 32
|
||||
#define CAM_CC_IFE_0_AXI_CLK 33
|
||||
#define CAM_CC_IFE_0_CLK 34
|
||||
#define CAM_CC_IFE_0_CLK_SRC 35
|
||||
#define CAM_CC_IFE_0_CPHY_RX_CLK 36
|
||||
#define CAM_CC_IFE_0_CSID_CLK 37
|
||||
#define CAM_CC_IFE_0_CSID_CLK_SRC 38
|
||||
#define CAM_CC_IFE_0_DSP_CLK 39
|
||||
#define CAM_CC_IFE_1_AXI_CLK 40
|
||||
#define CAM_CC_IFE_1_CLK 41
|
||||
#define CAM_CC_IFE_1_CLK_SRC 42
|
||||
#define CAM_CC_IFE_1_CPHY_RX_CLK 43
|
||||
#define CAM_CC_IFE_1_CSID_CLK 44
|
||||
#define CAM_CC_IFE_1_CSID_CLK_SRC 45
|
||||
#define CAM_CC_IFE_1_DSP_CLK 46
|
||||
#define CAM_CC_IFE_LITE_CLK 47
|
||||
#define CAM_CC_IFE_LITE_CLK_SRC 48
|
||||
#define CAM_CC_IFE_LITE_CPHY_RX_CLK 49
|
||||
#define CAM_CC_IFE_LITE_CSID_CLK 50
|
||||
#define CAM_CC_IFE_LITE_CSID_CLK_SRC 51
|
||||
#define CAM_CC_IPE_0_AHB_CLK 52
|
||||
#define CAM_CC_IPE_0_AREG_CLK 53
|
||||
#define CAM_CC_IPE_0_AXI_CLK 54
|
||||
#define CAM_CC_IPE_0_CLK 55
|
||||
#define CAM_CC_IPE_0_CLK_SRC 56
|
||||
#define CAM_CC_JPEG_CLK 57
|
||||
#define CAM_CC_JPEG_CLK_SRC 58
|
||||
#define CAM_CC_LRME_CLK 59
|
||||
#define CAM_CC_LRME_CLK_SRC 60
|
||||
#define CAM_CC_MCLK0_CLK 61
|
||||
#define CAM_CC_MCLK0_CLK_SRC 62
|
||||
#define CAM_CC_MCLK1_CLK 63
|
||||
#define CAM_CC_MCLK1_CLK_SRC 64
|
||||
#define CAM_CC_MCLK2_CLK 65
|
||||
#define CAM_CC_MCLK2_CLK_SRC 66
|
||||
#define CAM_CC_MCLK3_CLK 67
|
||||
#define CAM_CC_MCLK3_CLK_SRC 68
|
||||
#define CAM_CC_MCLK4_CLK 69
|
||||
#define CAM_CC_MCLK4_CLK_SRC 70
|
||||
#define CAM_CC_BPS_AHB_CLK 71
|
||||
#define CAM_CC_BPS_AREG_CLK 72
|
||||
#define CAM_CC_BPS_AXI_CLK 73
|
||||
#define CAM_CC_BPS_CLK 74
|
||||
#define CAM_CC_BPS_CLK_SRC 75
|
||||
#define CAM_CC_SLOW_AHB_CLK_SRC 76
|
||||
#define CAM_CC_SOC_AHB_CLK 77
|
||||
#define CAM_CC_SYS_TMR_CLK 78
|
||||
|
||||
/* CAM_CC power domains */
|
||||
#define BPS_GDSC 0
|
||||
#define IFE_0_GDSC 1
|
||||
#define IFE_1_GDSC 2
|
||||
#define IPE_0_GDSC 3
|
||||
#define TITAN_TOP_GDSC 4
|
||||
|
||||
/* CAM_CC resets */
|
||||
#define CAM_CC_BPS_BCR 0
|
||||
#define CAM_CC_CAMNOC_BCR 1
|
||||
#define CAM_CC_CCI_0_BCR 2
|
||||
#define CAM_CC_CCI_1_BCR 3
|
||||
#define CAM_CC_CPAS_BCR 4
|
||||
#define CAM_CC_CSI0PHY_BCR 5
|
||||
#define CAM_CC_CSI1PHY_BCR 6
|
||||
#define CAM_CC_CSI2PHY_BCR 7
|
||||
#define CAM_CC_CSI3PHY_BCR 8
|
||||
#define CAM_CC_ICP_BCR 9
|
||||
#define CAM_CC_IFE_0_BCR 10
|
||||
#define CAM_CC_IFE_1_BCR 11
|
||||
#define CAM_CC_IFE_LITE_BCR 12
|
||||
#define CAM_CC_IPE_0_BCR 13
|
||||
#define CAM_CC_JPEG_BCR 14
|
||||
#define CAM_CC_LRME_BCR 15
|
||||
#define CAM_CC_MCLK0_BCR 16
|
||||
#define CAM_CC_MCLK1_BCR 17
|
||||
#define CAM_CC_MCLK2_BCR 18
|
||||
#define CAM_CC_MCLK3_BCR 19
|
||||
#define CAM_CC_MCLK4_BCR 20
|
||||
#define CAM_CC_TITAN_TOP_BCR 21
|
||||
|
||||
#endif
|
|
@ -0,0 +1,117 @@
|
|||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2020, Linaro Ltd.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SDX55_H
|
||||
#define _DT_BINDINGS_CLK_QCOM_GCC_SDX55_H
|
||||
|
||||
#define GPLL0 3
|
||||
#define GPLL0_OUT_EVEN 4
|
||||
#define GPLL4 5
|
||||
#define GPLL4_OUT_EVEN 6
|
||||
#define GPLL5 7
|
||||
#define GCC_AHB_PCIE_LINK_CLK 8
|
||||
#define GCC_BLSP1_AHB_CLK 9
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CLK 10
|
||||
#define GCC_BLSP1_QUP1_I2C_APPS_CLK_SRC 11
|
||||
#define GCC_BLSP1_QUP1_SPI_APPS_CLK 12
|
||||
#define GCC_BLSP1_QUP1_SPI_APPS_CLK_SRC 13
|
||||
#define GCC_BLSP1_QUP2_I2C_APPS_CLK 14
|
||||
#define GCC_BLSP1_QUP2_I2C_APPS_CLK_SRC 15
|
||||
#define GCC_BLSP1_QUP2_SPI_APPS_CLK 16
|
||||
#define GCC_BLSP1_QUP2_SPI_APPS_CLK_SRC 17
|
||||
#define GCC_BLSP1_QUP3_I2C_APPS_CLK 18
|
||||
#define GCC_BLSP1_QUP3_I2C_APPS_CLK_SRC 19
|
||||
#define GCC_BLSP1_QUP3_SPI_APPS_CLK 20
|
||||
#define GCC_BLSP1_QUP3_SPI_APPS_CLK_SRC 21
|
||||
#define GCC_BLSP1_QUP4_I2C_APPS_CLK 22
|
||||
#define GCC_BLSP1_QUP4_I2C_APPS_CLK_SRC 23
|
||||
#define GCC_BLSP1_QUP4_SPI_APPS_CLK 24
|
||||
#define GCC_BLSP1_QUP4_SPI_APPS_CLK_SRC 25
|
||||
#define GCC_BLSP1_UART1_APPS_CLK 26
|
||||
#define GCC_BLSP1_UART1_APPS_CLK_SRC 27
|
||||
#define GCC_BLSP1_UART2_APPS_CLK 28
|
||||
#define GCC_BLSP1_UART2_APPS_CLK_SRC 29
|
||||
#define GCC_BLSP1_UART3_APPS_CLK 30
|
||||
#define GCC_BLSP1_UART3_APPS_CLK_SRC 31
|
||||
#define GCC_BLSP1_UART4_APPS_CLK 32
|
||||
#define GCC_BLSP1_UART4_APPS_CLK_SRC 33
|
||||
#define GCC_BOOT_ROM_AHB_CLK 34
|
||||
#define GCC_CE1_AHB_CLK 35
|
||||
#define GCC_CE1_AXI_CLK 36
|
||||
#define GCC_CE1_CLK 37
|
||||
#define GCC_CPUSS_AHB_CLK 38
|
||||
#define GCC_CPUSS_AHB_CLK_SRC 39
|
||||
#define GCC_CPUSS_GNOC_CLK 40
|
||||
#define GCC_CPUSS_RBCPR_CLK 41
|
||||
#define GCC_CPUSS_RBCPR_CLK_SRC 42
|
||||
#define GCC_EMAC_CLK_SRC 43
|
||||
#define GCC_EMAC_PTP_CLK_SRC 44
|
||||
#define GCC_ETH_AXI_CLK 45
|
||||
#define GCC_ETH_PTP_CLK 46
|
||||
#define GCC_ETH_RGMII_CLK 47
|
||||
#define GCC_ETH_SLAVE_AHB_CLK 48
|
||||
#define GCC_GP1_CLK 49
|
||||
#define GCC_GP1_CLK_SRC 50
|
||||
#define GCC_GP2_CLK 51
|
||||
#define GCC_GP2_CLK_SRC 52
|
||||
#define GCC_GP3_CLK 53
|
||||
#define GCC_GP3_CLK_SRC 54
|
||||
#define GCC_PCIE_0_CLKREF_CLK 55
|
||||
#define GCC_PCIE_AUX_CLK 56
|
||||
#define GCC_PCIE_AUX_PHY_CLK_SRC 57
|
||||
#define GCC_PCIE_CFG_AHB_CLK 58
|
||||
#define GCC_PCIE_MSTR_AXI_CLK 59
|
||||
#define GCC_PCIE_PIPE_CLK 60
|
||||
#define GCC_PCIE_RCHNG_PHY_CLK 61
|
||||
#define GCC_PCIE_RCHNG_PHY_CLK_SRC 62
|
||||
#define GCC_PCIE_SLEEP_CLK 63
|
||||
#define GCC_PCIE_SLV_AXI_CLK 64
|
||||
#define GCC_PCIE_SLV_Q2A_AXI_CLK 65
|
||||
#define GCC_PDM2_CLK 66
|
||||
#define GCC_PDM2_CLK_SRC 67
|
||||
#define GCC_PDM_AHB_CLK 68
|
||||
#define GCC_PDM_XO4_CLK 69
|
||||
#define GCC_SDCC1_AHB_CLK 70
|
||||
#define GCC_SDCC1_APPS_CLK 71
|
||||
#define GCC_SDCC1_APPS_CLK_SRC 72
|
||||
#define GCC_SYS_NOC_CPUSS_AHB_CLK 73
|
||||
#define GCC_USB30_MASTER_CLK 74
|
||||
#define GCC_USB30_MASTER_CLK_SRC 75
|
||||
#define GCC_USB30_MOCK_UTMI_CLK 76
|
||||
#define GCC_USB30_MOCK_UTMI_CLK_SRC 77
|
||||
#define GCC_USB30_MSTR_AXI_CLK 78
|
||||
#define GCC_USB30_SLEEP_CLK 79
|
||||
#define GCC_USB30_SLV_AHB_CLK 80
|
||||
#define GCC_USB3_PHY_AUX_CLK 81
|
||||
#define GCC_USB3_PHY_AUX_CLK_SRC 82
|
||||
#define GCC_USB3_PHY_PIPE_CLK 83
|
||||
#define GCC_USB3_PRIM_CLKREF_CLK 84
|
||||
#define GCC_USB_PHY_CFG_AHB2PHY_CLK 85
|
||||
#define GCC_XO_DIV4_CLK 86
|
||||
#define GCC_XO_PCIE_LINK_CLK 87
|
||||
|
||||
#define GCC_EMAC_BCR 0
|
||||
#define GCC_PCIE_BCR 1
|
||||
#define GCC_PCIE_LINK_DOWN_BCR 2
|
||||
#define GCC_PCIE_NOCSR_COM_PHY_BCR 3
|
||||
#define GCC_PCIE_PHY_BCR 4
|
||||
#define GCC_PCIE_PHY_CFG_AHB_BCR 5
|
||||
#define GCC_PCIE_PHY_COM_BCR 6
|
||||
#define GCC_PCIE_PHY_NOCSR_COM_PHY_BCR 7
|
||||
#define GCC_PDM_BCR 8
|
||||
#define GCC_QUSB2PHY_BCR 9
|
||||
#define GCC_TCSR_PCIE_BCR 10
|
||||
#define GCC_USB30_BCR 11
|
||||
#define GCC_USB3_PHY_BCR 12
|
||||
#define GCC_USB3PHY_PHY_BCR 13
|
||||
#define GCC_USB_PHY_CFG_AHB2PHY_BCR 14
|
||||
|
||||
/* GCC power domains */
|
||||
#define USB30_GDSC 0
|
||||
#define PCIE_GDSC 1
|
||||
#define EMAC_GDSC 2
|
||||
|
||||
#endif
|
|
@ -21,5 +21,15 @@
|
|||
#define RPMH_IPA_CLK 12
|
||||
#define RPMH_LN_BB_CLK1 13
|
||||
#define RPMH_LN_BB_CLK1_A 14
|
||||
#define RPMH_CE_CLK 15
|
||||
#define RPMH_QPIC_CLK 16
|
||||
#define RPMH_DIV_CLK1 17
|
||||
#define RPMH_DIV_CLK1_A 18
|
||||
#define RPMH_RF_CLK4 19
|
||||
#define RPMH_RF_CLK4_A 20
|
||||
#define RPMH_RF_CLK5 21
|
||||
#define RPMH_RF_CLK5_A 22
|
||||
#define RPMH_PKA_CLK 23
|
||||
#define RPMH_HWKM_CLK 24
|
||||
|
||||
#endif
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_LPASS_AONCC_SM8250_H
|
||||
#define _DT_BINDINGS_CLK_LPASS_AONCC_SM8250_H
|
||||
|
||||
/* from AOCC */
|
||||
#define LPASS_CDC_VA_MCLK 0
|
||||
#define LPASS_CDC_TX_NPL 1
|
||||
#define LPASS_CDC_TX_MCLK 2
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_LPASS_AONCC_SM8250_H */
|
|
@ -0,0 +1,13 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_LPASS_AUDIOCC_SM8250_H
|
||||
#define _DT_BINDINGS_CLK_LPASS_AUDIOCC_SM8250_H
|
||||
|
||||
/* From AudioCC */
|
||||
#define LPASS_CDC_WSA_NPL 0
|
||||
#define LPASS_CDC_WSA_MCLK 1
|
||||
#define LPASS_CDC_RX_MCLK 2
|
||||
#define LPASS_CDC_RX_NPL 3
|
||||
#define LPASS_CDC_RX_MCLK_MCLK2 4
|
||||
|
||||
#endif /* _DT_BINDINGS_CLK_LPASS_AUDIOCC_SM8250_H */
|
|
@ -1088,6 +1088,11 @@ static inline struct clk_hw *__clk_get_hw(struct clk *clk)
|
|||
return (struct clk_hw *)clk;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id);
|
||||
struct clk *devm_clk_hw_get_clk(struct device *dev, struct clk_hw *hw,
|
||||
const char *con_id);
|
||||
|
||||
unsigned int clk_hw_get_num_parents(const struct clk_hw *hw);
|
||||
struct clk_hw *clk_hw_get_parent(const struct clk_hw *hw);
|
||||
struct clk_hw *clk_hw_get_parent_by_index(const struct clk_hw *hw,
|
||||
|
|
|
@ -109,6 +109,17 @@ int clk_notifier_register(struct clk *clk, struct notifier_block *nb);
|
|||
*/
|
||||
int clk_notifier_unregister(struct clk *clk, struct notifier_block *nb);
|
||||
|
||||
/**
|
||||
* devm_clk_notifier_register - register a managed rate-change notifier callback
|
||||
* @dev: device for clock "consumer"
|
||||
* @clk: clock whose rate we are interested in
|
||||
* @nb: notifier block with callback function pointer
|
||||
*
|
||||
* Returns 0 on success, -EERROR otherwise
|
||||
*/
|
||||
int devm_clk_notifier_register(struct device *dev, struct clk *clk,
|
||||
struct notifier_block *nb);
|
||||
|
||||
/**
|
||||
* clk_get_accuracy - obtain the clock accuracy in ppb (parts per billion)
|
||||
* for a clock source.
|
||||
|
@ -186,6 +197,13 @@ static inline int clk_notifier_unregister(struct clk *clk,
|
|||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline int devm_clk_notifier_register(struct device *dev,
|
||||
struct clk *clk,
|
||||
struct notifier_block *nb)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static inline long clk_get_accuracy(struct clk *clk)
|
||||
{
|
||||
return -ENOTSUPP;
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
|
||||
struct device_node;
|
||||
|
||||
#ifdef CONFIG_ARCH_S3C64XX
|
||||
#ifdef CONFIG_S3C64XX_COMMON_CLK
|
||||
void s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f,
|
||||
unsigned long xusbxti_f, bool s3c6400,
|
||||
void __iomem *base);
|
||||
|
@ -19,7 +19,7 @@ static inline void s3c64xx_clk_init(struct device_node *np,
|
|||
unsigned long xtal_f,
|
||||
unsigned long xusbxti_f,
|
||||
bool s3c6400, void __iomem *base) { }
|
||||
#endif /* CONFIG_ARCH_S3C64XX */
|
||||
#endif /* CONFIG_S3C64XX_COMMON_CLK */
|
||||
|
||||
#ifdef CONFIG_S3C2410_COMMON_CLK
|
||||
void s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f,
|
||||
|
|
Loading…
Reference in New Issue