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:
Stephen Boyd 2020-12-20 17:17:01 -08:00
41 changed files with 5124 additions and 390 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

1659
drivers/clk/qcom/gcc-sdx55.c Normal file

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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