Commit c64dd8ea authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-range', 'clk-uniphier', 'clk-apple' and 'clk-qcom' into clk-next

 - Make clk_set_rate_range() re-evaluate the limits each time
 - Introduce various clk_set_rate_range() tests
 - Add clk_drop_range() to drop a previously set range
 - Support for NCO blocks on Apple SoCs

* clk-range:
  clk: Drop the rate range on clk_put()
  clk: test: Test clk_set_rate_range on orphan mux
  clk: Initialize orphan req_rate
  clk: bcm: rpi: Run some clocks at the minimum rate allowed
  clk: bcm: rpi: Set a default minimum rate
  clk: bcm: rpi: Add variant structure
  clk: Add clk_drop_range
  clk: Always set the rate on clk_set_range_rate
  clk: Use clamp instead of open-coding our own
  clk: Always clamp the rounded rate
  clk: Enforce that disjoints limits are invalid
  clk: Introduce Kunit Tests for the framework
  clk: Fix clk_hw_get_clk() when dev is NULL

* clk-uniphier:
  clk: uniphier: Fix fixed-rate initialization

* clk-apple:
  clk: clk-apple-nco: Allow and fix module building
  MAINTAINERS: Add clk-apple-nco under ARM/APPLE MACHINE
  clk: clk-apple-nco: Add driver for Apple NCO
  dt-bindings: clock: Add Apple NCO

* clk-qcom: (61 commits)
  clk: qcom: gcc-msm8994: Fix gpll4 width
  dt-bindings: clock: fix dt_binding_check error for qcom,gcc-other.yaml
  clk: qcom: Add display clock controller driver for SM6125
  dt-bindings: clock: add QCOM SM6125 display clock bindings
  clk: qcom: Fix sorting of SDX_GCC_65 in Makefile and Kconfig
  clk: qcom: gcc: Add emac GDSC support for SM8150
  clk: qcom: gcc: sm8150: Fix some identation issues
  clk: qcom: gcc: Add UFS_CARD and UFS_PHY GDSCs for SM8150
  clk: qcom: gcc: Add PCIe0 and PCIe1 GDSC for SM8150
  clk: qcom: clk-rcg2: Update the frac table for pixel clock
  clk: qcom: clk-rcg2: Update logic to calculate D value for RCG
  clk: qcom: smd: Add missing MSM8998 RPM clocks
  clk: qcom: smd: Add missing RPM clocks for msm8992/4
  dt-bindings: clock: qcom: rpmcc: Add RPM Modem SubSystem (MSS) clocks
  clk: qcom: gcc-ipq806x: add CryptoEngine resets
  dt-bindings: reset: add ipq8064 ce5 resets
  clk: qcom: gcc-ipq806x: add CryptoEngine clocks
  dt-bindings: clock: add ipq8064 ce5 clk define
  clk: qcom: gcc-ipq806x: add additional freq for sdc table
  clk: qcom: clk-rcg: add clk_rcg_floor_ops ops
  ...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/apple,nco.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Apple SoCs' NCO block
maintainers:
- Martin Povišer <povik+lin@cutebit.org>
description: |
The NCO (Numerically Controlled Oscillator) block found on Apple SoCs
such as the t8103 (M1) is a programmable clock generator performing
fractional division of a high frequency input clock.
It carries a number of independent channels and is typically used for
generation of audio bitclocks.
properties:
compatible:
items:
- enum:
- apple,t6000-nco
- apple,t8103-nco
- const: apple,nco
clocks:
description:
Specifies the reference clock from which the output clocks
are derived through fractional division.
maxItems: 1
'#clock-cells':
const: 1
reg:
maxItems: 1
required:
- compatible
- clocks
- '#clock-cells'
- reg
additionalProperties: false
examples:
- |
nco_clkref: clock-ref {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <900000000>;
clock-output-names = "nco-ref";
};
nco: clock-controller@23b044000 {
compatible = "apple,t8103-nco", "apple,nco";
reg = <0x3b044000 0x14000>;
#clock-cells = <1>;
clocks = <&nco_clkref>;
};
......@@ -10,7 +10,7 @@ maintainers:
- Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
description:
The A7 PLL on the Qualcomm platforms like SDX55 is used to provide high
The A7 PLL on the Qualcomm platforms like SDX55, SDX65 is used to provide high
frequency clock to the CPU.
properties:
......
Qualcomm Camera Clock & Reset Controller Binding
------------------------------------------------
Required properties :
- compatible : shall contain "qcom,sdm845-camcc".
- reg : shall contain base register location and length.
- #clock-cells : from common clock binding, shall contain 1.
- #reset-cells : from common reset binding, shall contain 1.
- #power-domain-cells : from generic power domain binding, shall contain 1.
Example:
camcc: clock-controller@ad00000 {
compatible = "qcom,sdm845-camcc";
reg = <0xad00000 0x10000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,dispcc-sm6125.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display Clock Controller Binding for SM6125
maintainers:
- Martin Botka <martin.botka@somainline.org>
description: |
Qualcomm display clock control module which supports the clocks and
power domains on SM6125.
See also:
dt-bindings/clock/qcom,dispcc-sm6125.h
properties:
compatible:
enum:
- qcom,sm6125-dispcc
clocks:
items:
- description: Board XO source
- description: Byte clock from DSI PHY0
- description: Pixel clock from DSI PHY0
- description: Pixel clock from DSI PHY1
- description: Link clock from DP PHY
- description: VCO DIV clock from DP PHY
- description: AHB config clock from GCC
clock-names:
items:
- const: bi_tcxo
- const: dsi0_phy_pll_out_byteclk
- const: dsi0_phy_pll_out_dsiclk
- const: dsi1_phy_pll_out_dsiclk
- const: dp_phy_pll_link_clk
- const: dp_phy_pll_vco_div_clk
- const: cfg_ahb_clk
'#clock-cells':
const: 1
'#power-domain-cells':
const: 1
reg:
maxItems: 1
required:
- compatible
- reg
- clocks
- clock-names
- '#clock-cells'
- '#power-domain-cells'
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmcc.h>
#include <dt-bindings/clock/qcom,gcc-sm6125.h>
clock-controller@5f00000 {
compatible = "qcom,sm6125-dispcc";
reg = <0x5f00000 0x20000>;
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
<&dsi0_phy 0>,
<&dsi0_phy 1>,
<&dsi1_phy 1>,
<&dp_phy 0>,
<&dp_phy 1>,
<&gcc GCC_DISP_AHB_CLK>;
clock-names = "bi_tcxo",
"dsi0_phy_pll_out_byteclk",
"dsi0_phy_pll_out_dsiclk",
"dsi1_phy_pll_out_dsiclk",
"dp_phy_pll_link_clk",
"dp_phy_pll_vco_div_clk",
"cfg_ahb_clk";
#clock-cells = <1>;
#power-domain-cells = <1>;
};
...
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,dispcc-sm6350.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display Clock & Reset Controller Binding for SM6350
maintainers:
- Konrad Dybcio <konrad.dybcio@somainline.org>
description: |
Qualcomm display clock control module which supports the clocks, resets and
power domains on SM6350.
See also dt-bindings/clock/qcom,dispcc-sm6350.h.
properties:
compatible:
const: qcom,sm6350-dispcc
clocks:
items:
- description: Board XO source
- description: GPLL0 source from GCC
- description: Byte clock from DSI PHY
- description: Pixel clock from DSI PHY
- description: Link clock from DP PHY
- description: VCO DIV clock from DP PHY
clock-names:
items:
- const: bi_tcxo
- const: gcc_disp_gpll0_clk
- const: dsi0_phy_pll_out_byteclk
- const: dsi0_phy_pll_out_dsiclk
- const: dp_phy_pll_link_clk
- const: dp_phy_pll_vco_div_clk
'#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-sm6350.h>
#include <dt-bindings/clock/qcom,rpmh.h>
clock-controller@af00000 {
compatible = "qcom,sm6350-dispcc";
reg = <0x0af00000 0x20000>;
clocks = <&rpmhcc RPMH_CXO_CLK>,
<&gcc GCC_DISP_GPLL0_CLK>,
<&dsi_phy 0>,
<&dsi_phy 1>,
<&dp_phy 0>,
<&dp_phy 1>;
clock-names = "bi_tcxo",
"gcc_disp_gpll0_clk",
"dsi0_phy_pll_out_byteclk",
"dsi0_phy_pll_out_dsiclk",
"dp_phy_pll_link_clk",
"dp_phy_pll_vco_div_clk";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...
......@@ -6,6 +6,9 @@ $schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller Binding for APQ8064
allOf:
- $ref: qcom,gcc.yaml#
maintainers:
- Stephen Boyd <sboyd@kernel.org>
- Taniya Das <tdas@codeaurora.org>
......@@ -17,22 +20,12 @@ description: |
See also:
- dt-bindings/clock/qcom,gcc-msm8960.h
- dt-bindings/reset/qcom,gcc-msm8960.h
- dt-bindings/clock/qcom,gcc-apq8084.h
- dt-bindings/reset/qcom,gcc-apq8084.h
properties:
compatible:
const: qcom,gcc-apq8064
'#clock-cells':
const: 1
'#reset-cells':
const: 1
'#power-domain-cells':
const: 1
reg:
maxItems: 1
const: qcom,gcc-apq8084
nvmem-cells:
minItems: 1
......@@ -53,21 +46,13 @@ properties:
'#thermal-sensor-cells':
const: 1
protected-clocks:
description:
Protected clock specifier list as per common clock binding.
required:
- compatible
- reg
- '#clock-cells'
- '#reset-cells'
- '#power-domain-cells'
- nvmem-cells
- nvmem-cell-names
- '#thermal-sensor-cells'
additionalProperties: false
unevaluatedProperties: false
examples:
- |
......
# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,gcc-ipq8064.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller Binding for IPQ8064
allOf:
- $ref: qcom,gcc.yaml#
maintainers:
- Ansuel Smith <ansuelsmth@gmail.com>
description: |
Qualcomm global clock control module which supports the clocks, resets and
power domains on IPQ8064.
See also:
- dt-bindings/clock/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
- dt-bindings/reset/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
properties:
compatible:
items:
- const: qcom,gcc-ipq8064
- const: syscon
clocks:
items:
- description: PXO source
- description: CXO source
clock-names:
items:
- const: pxo
- const: cxo
thermal-sensor:
type: object
allOf:
- $ref: /schemas/thermal/qcom-tsens.yaml#
required:
- compatible
- clocks
- clock-names
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/interrupt-controller/arm-gic.h>
gcc: clock-controller@900000 {
compatible = "qcom,gcc-ipq8064", "syscon";
reg = <0x00900000 0x4000>;
clocks = <&pxo_board>, <&cxo_board>;
clock-names = "pxo", "cxo";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
tsens: thermal-sensor {
compatible = "qcom,ipq8064-tsens";
nvmem-cells = <&tsens_calib>, <&tsens_calib_backup>;
nvmem-cell-names = "calib", "calib_backup";
interrupts = <GIC_SPI 178 IRQ_TYPE_LEVEL_HIGH>;
interrupt-names = "uplow";
#qcom,sensors = <11>;
#thermal-sensor-cells = <1>;
};
};
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,gcc-other.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller Binding
maintainers:
- Stephen Boyd <sboyd@kernel.org>
- Taniya Das <tdas@codeaurora.org>
description: |
Qualcomm global clock control module which supports the clocks, resets and
power domains.
See also:
- dt-bindings/clock/qcom,gcc-ipq4019.h
- dt-bindings/clock/qcom,gcc-ipq6018.h
- dt-bindings/reset/qcom,gcc-ipq6018.h
- dt-bindings/clock/qcom,gcc-msm8939.h
- dt-bindings/clock/qcom,gcc-msm8953.h
- dt-bindings/reset/qcom,gcc-msm8939.h
- dt-bindings/clock/qcom,gcc-msm8660.h
- dt-bindings/reset/qcom,gcc-msm8660.h
- dt-bindings/clock/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974)
- dt-bindings/reset/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974)
- dt-bindings/clock/qcom,gcc-mdm9607.h
- dt-bindings/clock/qcom,gcc-mdm9615.h
- dt-bindings/reset/qcom,gcc-mdm9615.h
- dt-bindings/clock/qcom,gcc-sdm660.h (qcom,gcc-sdm630 and qcom,gcc-sdm660)
allOf:
- $ref: "qcom,gcc.yaml#"
properties:
compatible:
enum:
- qcom,gcc-ipq4019
- qcom,gcc-ipq6018
- qcom,gcc-mdm9607
- qcom,gcc-msm8226
- qcom,gcc-msm8660
- qcom,gcc-msm8916
- qcom,gcc-msm8939
- qcom,gcc-msm8953
- qcom,gcc-msm8960
- qcom,gcc-msm8974
- qcom,gcc-msm8974pro
- qcom,gcc-msm8974pro-ac
- qcom,gcc-mdm9615
- qcom,gcc-sdm630
- qcom,gcc-sdm660
required:
- compatible
unevaluatedProperties: false
examples:
# Example for GCC for MSM8960:
- |
clock-controller@900000 {
compatible = "qcom,gcc-msm8960";
reg = <0x900000 0x4000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...
......@@ -4,57 +4,17 @@
$id: http://devicetree.org/schemas/clock/qcom,gcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller Binding
title: Qualcomm Global Clock & Reset Controller Binding Common Bindings
maintainers:
- Stephen Boyd <sboyd@kernel.org>
- Taniya Das <tdas@codeaurora.org>
description: |
Qualcomm global clock control module which supports the clocks, resets and
power domains.
See also:
- dt-bindings/clock/qcom,gcc-apq8084.h
- dt-bindings/reset/qcom,gcc-apq8084.h
- dt-bindings/clock/qcom,gcc-ipq4019.h
- dt-bindings/clock/qcom,gcc-ipq6018.h
- dt-bindings/reset/qcom,gcc-ipq6018.h
- dt-bindings/clock/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
- dt-bindings/reset/qcom,gcc-ipq806x.h (qcom,gcc-ipq8064)
- dt-bindings/clock/qcom,gcc-msm8939.h
- dt-bindings/clock/qcom,gcc-msm8953.h
- dt-bindings/reset/qcom,gcc-msm8939.h
- dt-bindings/clock/qcom,gcc-msm8660.h
- dt-bindings/reset/qcom,gcc-msm8660.h
- dt-bindings/clock/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974)
- dt-bindings/reset/qcom,gcc-msm8974.h (qcom,gcc-msm8226 and qcom,gcc-msm8974)
- dt-bindings/clock/qcom,gcc-mdm9607.h
- dt-bindings/clock/qcom,gcc-mdm9615.h
- dt-bindings/reset/qcom,gcc-mdm9615.h
- dt-bindings/clock/qcom,gcc-sdm660.h (qcom,gcc-sdm630 and qcom,gcc-sdm660)
Common bindings for Qualcomm global clock control module which supports
the clocks, resets and power domains.
properties:
compatible:
enum:
- qcom,gcc-apq8084
- qcom,gcc-ipq4019
- qcom,gcc-ipq6018
- qcom,gcc-ipq8064
- qcom,gcc-mdm9607
- qcom,gcc-msm8226
- qcom,gcc-msm8660
- qcom,gcc-msm8916
- qcom,gcc-msm8939
- qcom,gcc-msm8953
- qcom,gcc-msm8960
- qcom,gcc-msm8974
- qcom,gcc-msm8974pro
- qcom,gcc-msm8974pro-ac
- qcom,gcc-mdm9615
- qcom,gcc-sdm630
- qcom,gcc-sdm660
'#clock-cells':
const: 1
......@@ -72,22 +32,11 @@ properties:
Protected clock specifier list as per common clock binding.
required:
- compatible
- reg
- '#clock-cells'
- '#reset-cells'
- '#power-domain-cells'
additionalProperties: false
additionalProperties: true
examples:
# Example for GCC for MSM8960:
- |
clock-controller@900000 {
compatible = "qcom,gcc-msm8960";
reg = <0x900000 0x4000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...
......@@ -17,6 +17,7 @@ description: |
dt-bindings/clock/qcom,gpucc-sdm845.h
dt-bindings/clock/qcom,gpucc-sc7180.h
dt-bindings/clock/qcom,gpucc-sc7280.h
dt-bindings/clock/qcom,gpucc-sm6350.h
dt-bindings/clock/qcom,gpucc-sm8150.h
dt-bindings/clock/qcom,gpucc-sm8250.h
......@@ -27,6 +28,7 @@ properties:
- qcom,sc7180-gpucc
- qcom,sc7280-gpucc
- qcom,sc8180x-gpucc
- qcom,sm6350-gpucc
- qcom,sm8150-gpucc
- qcom,sm8250-gpucc
......
......@@ -19,6 +19,7 @@ properties:
enum:
- qcom,mmcc-apq8064
- qcom,mmcc-apq8084
- qcom,mmcc-msm8226
- qcom,mmcc-msm8660
- qcom,mmcc-msm8960
- qcom,mmcc-msm8974
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,qcm2290-dispcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Display Clock & Reset Controller Binding for qcm2290
maintainers:
- Loic Poulain <loic.poulain@linaro.org>
description: |
Qualcomm display clock control module which supports the clocks, resets and
power domains on qcm2290.
See also dt-bindings/clock/qcom,dispcc-qcm2290.h.
properties:
compatible:
const: qcom,qcm2290-dispcc
clocks:
items:
- description: Board XO source
- description: Board active-only XO source
- description: GPLL0 source from GCC
- description: GPLL0 div source from GCC
- description: Byte clock from DSI PHY
- description: Pixel clock from DSI PHY
clock-names:
items:
- const: bi_tcxo
- const: bi_tcxo_ao
- const: gcc_disp_gpll0_clk_src
- const: gcc_disp_gpll0_div_clk_src
- const: dsi0_phy_pll_out_byteclk
- const: dsi0_phy_pll_out_dsiclk
'#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,dispcc-qcm2290.h>
#include <dt-bindings/clock/qcom,gcc-qcm2290.h>
#include <dt-bindings/clock/qcom,rpmcc.h>
clock-controller@5f00000 {
compatible = "qcom,qcm2290-dispcc";
reg = <0x5f00000 0x20000>;
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
<&rpmcc RPM_SMD_XO_A_CLK_SRC>,
<&gcc GCC_DISP_GPLL0_CLK_SRC>,
<&gcc GCC_DISP_GPLL0_DIV_CLK_SRC>,
<&dsi0_phy 0>,
<&dsi0_phy 1>;
clock-names = "bi_tcxo",
"bi_tcxo_ao",
"gcc_disp_gpll0_clk_src",
"gcc_disp_gpll0_div_clk_src",
"dsi0_phy_pll_out_byteclk",
"dsi0_phy_pll_out_dsiclk";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...
......@@ -20,6 +20,7 @@ properties:
- qcom,sc7180-rpmh-clk
- qcom,sc7280-rpmh-clk
- qcom,sc8180x-rpmh-clk
- qcom,sc8280xp-rpmh-clk
- qcom,sdm845-rpmh-clk
- qcom,sdx55-rpmh-clk
- qcom,sdx65-rpmh-clk
......
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,sdm845-camcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Camera Clock & Reset Controller Binding for SDM845
maintainers:
- Bjorn Andersson <bjorn.andersson@linaro.org>
description: |
Qualcomm camera clock control module which supports the clocks, resets and
power domains on SDM845.
See also dt-bindings/clock/qcom,camcc-sm845.h
properties:
compatible:
const: qcom,sdm845-camcc
clocks:
items:
- description: Board XO source
clock-names:
items:
- const: bi_tcxo
'#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,rpmh.h>
clock-controller@ad00000 {
compatible = "qcom,sdm845-camcc";
reg = <0x0ad00000 0x10000>;
clocks = <&rpmhcc RPMH_CXO_CLK>;
clock-names = "bi_tcxo";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...
......@@ -1768,6 +1768,7 @@ C: irc://irc.oftc.net/asahi-dev
T: git https://github.com/AsahiLinux/linux.git
F: Documentation/devicetree/bindings/arm/apple.yaml
F: Documentation/devicetree/bindings/arm/apple/*
F: Documentation/devicetree/bindings/clock/apple,nco.yaml
F: Documentation/devicetree/bindings/i2c/apple,i2c.yaml
F: Documentation/devicetree/bindings/interrupt-controller/apple,aic.yaml
F: Documentation/devicetree/bindings/mailbox/apple,mailbox.yaml
......@@ -1776,6 +1777,7 @@ F: Documentation/devicetree/bindings/pinctrl/apple,pinctrl.yaml
F: Documentation/devicetree/bindings/power/apple*
F: Documentation/devicetree/bindings/watchdog/apple,wdt.yaml
F: arch/arm64/boot/dts/apple/
F: drivers/clk/clk-apple-nco.c
F: drivers/i2c/busses/i2c-pasemi-core.c
F: drivers/i2c/busses/i2c-pasemi-platform.c
F: drivers/irqchip/irq-apple-aic.c
......
CONFIG_KUNIT=y
CONFIG_COMMON_CLK=y
CONFIG_CLK_KUNIT_TEST=y
CONFIG_CLK_GATE_KUNIT_TEST=y
......@@ -59,6 +59,15 @@ config LMK04832
Say yes here to build support for Texas Instruments' LMK04832 Ultra
Low-Noise JESD204B Compliant Clock Jitter Cleaner With Dual Loop PLLs
config COMMON_CLK_APPLE_NCO
tristate "Clock driver for Apple SoC NCOs"
depends on ARCH_APPLE || COMPILE_TEST
default ARCH_APPLE
help
This driver supports NCO (Numerically Controlled Oscillator) blocks
found on Apple SoCs such as t8103 (M1). The blocks are typically
generators of audio clocks.
config COMMON_CLK_MAX77686
tristate "Clock driver for Maxim 77620/77686/77802 MFD"
depends on MFD_MAX77686 || MFD_MAX77620 || COMPILE_TEST
......@@ -438,6 +447,13 @@ source "drivers/clk/xilinx/Kconfig"
source "drivers/clk/zynqmp/Kconfig"
# Kunit test cases
config CLK_KUNIT_TEST
tristate "Basic Clock Framework Kunit Tests" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
help
Kunit tests for the common clock framework.
config CLK_GATE_KUNIT_TEST
tristate "Basic gate type Kunit test" if !KUNIT_ALL_TESTS
depends on KUNIT
......
......@@ -2,6 +2,7 @@
# common clock types
obj-$(CONFIG_HAVE_CLK) += clk-devres.o clk-bulk.o clkdev.o
obj-$(CONFIG_COMMON_CLK) += clk.o
obj-$(CONFIG_CLK_KUNIT_TEST) += clk_test.o
obj-$(CONFIG_COMMON_CLK) += clk-divider.o
obj-$(CONFIG_COMMON_CLK) += clk-fixed-factor.o
obj-$(CONFIG_COMMON_CLK) += clk-fixed-rate.o
......@@ -18,6 +19,7 @@ endif
# hardware specific clock types
# please keep this section sorted lexicographically by file path name
obj-$(CONFIG_COMMON_CLK_APPLE_NCO) += clk-apple-nco.o
obj-$(CONFIG_MACH_ASM9260) += clk-asm9260.o
obj-$(CONFIG_COMMON_CLK_AXI_CLKGEN) += clk-axi-clkgen.o
obj-$(CONFIG_ARCH_AXXIA) += clk-axm5516.o
......
......@@ -56,6 +56,8 @@ static char *rpi_firmware_clk_names[] = {
#define RPI_FIRMWARE_STATE_ENABLE_BIT BIT(0)
#define RPI_FIRMWARE_STATE_WAIT_BIT BIT(1)
struct raspberrypi_clk_variant;
struct raspberrypi_clk {
struct device *dev;
struct rpi_firmware *firmware;
......@@ -66,10 +68,72 @@ struct raspberrypi_clk_data {
struct clk_hw hw;
unsigned int id;
struct raspberrypi_clk_variant *variant;
struct raspberrypi_clk *rpi;
};
struct raspberrypi_clk_variant {
bool export;
char *clkdev;
unsigned long min_rate;
bool minimize;
};
static struct raspberrypi_clk_variant
raspberrypi_clk_variants[RPI_FIRMWARE_NUM_CLK_ID] = {
[RPI_FIRMWARE_ARM_CLK_ID] = {
.export = true,
.clkdev = "cpu0",
},
[RPI_FIRMWARE_CORE_CLK_ID] = {
.export = true,
/*
* The clock is shared between the HVS and the CSI
* controllers, on the BCM2711 and will change depending
* on the pixels composited on the HVS and the capture
* resolution on Unicam.
*
* Since the rate can get quite large, and we need to
* coordinate between both driver instances, let's
* always use the minimum the drivers will let us.
*/
.minimize = true,
},
[RPI_FIRMWARE_M2MC_CLK_ID] = {
.export = true,
/*
* If we boot without any cable connected to any of the
* HDMI connector, the firmware will skip the HSM
* initialization and leave it with a rate of 0,
* resulting in a bus lockup when we're accessing the
* registers even if it's enabled.
*
* Let's put a sensible default so that we don't end up
* in this situation.
*/
.min_rate = 120000000,
/*
* The clock is shared between the two HDMI controllers
* on the BCM2711 and will change depending on the
* resolution output on each. Since the rate can get
* quite large, and we need to coordinate between both
* driver instances, let's always use the minimum the
* drivers will let us.
*/
.minimize = true,
},
[RPI_FIRMWARE_V3D_CLK_ID] = {
.export = true,
},
[RPI_FIRMWARE_PIXEL_BVB_CLK_ID] = {
.export = true,
},
};
/*
* Structure of the message passed to Raspberry Pi's firmware in order to
* change clock rates. The 'disable_turbo' option is only available to the ARM
......@@ -165,12 +229,26 @@ static int raspberrypi_fw_set_rate(struct clk_hw *hw, unsigned long rate,
static int raspberrypi_fw_dumb_determine_rate(struct clk_hw *hw,
struct clk_rate_request *req)
{
struct raspberrypi_clk_data *data =
container_of(hw, struct raspberrypi_clk_data, hw);
struct raspberrypi_clk_variant *variant = data->variant;
/*
* The firmware will do the rounding but that isn't part of
* the interface with the firmware, so we just do our best
* here.
*/
req->rate = clamp(req->rate, req->min_rate, req->max_rate);
/*
* We want to aggressively reduce the clock rate here, so let's
* just ignore the requested rate and return the bare minimum
* rate we can get away with.
*/
if (variant->minimize && req->min_rate > 0)
req->rate = req->min_rate;
return 0;
}
......@@ -183,7 +261,8 @@ static const struct clk_ops raspberrypi_firmware_clk_ops = {
static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
unsigned int parent,
unsigned int id)
unsigned int id,
struct raspberrypi_clk_variant *variant)
{
struct raspberrypi_clk_data *data;
struct clk_init_data init = {};
......@@ -195,6 +274,7 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
return ERR_PTR(-ENOMEM);
data->rpi = rpi;
data->id = id;
data->variant = variant;
init.name = devm_kasprintf(rpi->dev, GFP_KERNEL,
"fw-clk-%s",
......@@ -228,15 +308,28 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi,
clk_hw_set_rate_range(&data->hw, min_rate, max_rate);
if (id == RPI_FIRMWARE_ARM_CLK_ID) {
if (variant->clkdev) {
ret = devm_clk_hw_register_clkdev(rpi->dev, &data->hw,
NULL, "cpu0");
NULL, variant->clkdev);
if (ret) {
dev_err(rpi->dev, "Failed to initialize clkdev\n");
return ERR_PTR(ret);
}
}
if (variant->min_rate) {
unsigned long rate;
clk_hw_set_rate_range(&data->hw, variant->min_rate, max_rate);
rate = raspberrypi_fw_get_rate(&data->hw, 0);
if (rate < variant->min_rate) {
ret = raspberrypi_fw_set_rate(&data->hw, variant->min_rate, 0);
if (ret)
return ERR_PTR(ret);
}
}
return &data->hw;
}
......@@ -264,27 +357,27 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi,
return ret;
while (clks->id) {
struct clk_hw *hw;
switch (clks->id) {
case RPI_FIRMWARE_ARM_CLK_ID:
case RPI_FIRMWARE_CORE_CLK_ID:
case RPI_FIRMWARE_M2MC_CLK_ID:
case RPI_FIRMWARE_V3D_CLK_ID:
case RPI_FIRMWARE_PIXEL_BVB_CLK_ID:
struct raspberrypi_clk_variant *variant;
if (clks->id > RPI_FIRMWARE_NUM_CLK_ID) {
dev_err(rpi->dev, "Unknown clock id: %u", clks->id);
return -EINVAL;
}
variant = &raspberrypi_clk_variants[clks->id];
if (variant->export) {
struct clk_hw *hw;
hw = raspberrypi_clk_register(rpi, clks->parent,
clks->id);
clks->id, variant);
if (IS_ERR(hw))
return PTR_ERR(hw);
data->hws[clks->id] = hw;
data->num = clks->id + 1;
fallthrough;
default:
clks++;
break;
}
clks++;
}
return 0;
......
// SPDX-License-Identifier: GPL-2.0-only OR MIT
/*
* Driver for an SoC block (Numerically Controlled Oscillator)
* found on t8103 (M1) and other Apple chips
*
* Copyright (C) The Asahi Linux Contributors
*/
#include <linux/bits.h>
#include <linux/bitfield.h>
#include <linux/clk-provider.h>
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/math64.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/spinlock.h>
#define NCO_CHANNEL_STRIDE 0x4000
#define NCO_CHANNEL_REGSIZE 20
#define REG_CTRL 0
#define CTRL_ENABLE BIT(31)
#define REG_DIV 4
#define DIV_FINE GENMASK(1, 0)
#define DIV_COARSE GENMASK(12, 2)
#define REG_INC1 8
#define REG_INC2 12
#define REG_ACCINIT 16
/*
* Theory of operation (postulated)
*
* The REG_DIV register indirectly expresses a base integer divisor, roughly
* corresponding to twice the desired ratio of input to output clock. This
* base divisor is adjusted on a cycle-by-cycle basis based on the state of a
* 32-bit phase accumulator to achieve a desired precise clock ratio over the
* long term.
*
* Specifically an output clock cycle is produced after (REG_DIV divisor)/2
* or (REG_DIV divisor + 1)/2 input cycles, the latter taking effect when top
* bit of the 32-bit accumulator is set. The accumulator is incremented each
* produced output cycle, by the value from either REG_INC1 or REG_INC2, which
* of the two is selected depending again on the accumulator's current top bit.
*
* Because the NCO hardware implements counting of input clock cycles in part
* in a Galois linear-feedback shift register, the higher bits of divisor
* are programmed into REG_DIV by picking an appropriate LFSR state. See
* applnco_compute_tables/applnco_div_translate for details on this.
*/
#define LFSR_POLY 0xa01
#define LFSR_INIT 0x7ff
#define LFSR_LEN 11
#define LFSR_PERIOD ((1 << LFSR_LEN) - 1)
#define LFSR_TBLSIZE (1 << LFSR_LEN)
/* The minimal attainable coarse divisor (first value in table) */
#define COARSE_DIV_OFFSET 2
struct applnco_tables {
u16 fwd[LFSR_TBLSIZE];
u16 inv[LFSR_TBLSIZE];
};
struct applnco_channel {
void __iomem *base;
struct applnco_tables *tbl;
struct clk_hw hw;
spinlock_t lock;
};
#define to_applnco_channel(_hw) container_of(_hw, struct applnco_channel, hw)
static void applnco_enable_nolock(struct clk_hw *hw)
{
struct applnco_channel *chan = to_applnco_channel(hw);
u32 val;
val = readl_relaxed(chan->base + REG_CTRL);
writel_relaxed(val | CTRL_ENABLE, chan->base + REG_CTRL);
}
static void applnco_disable_nolock(struct clk_hw *hw)
{
struct applnco_channel *chan = to_applnco_channel(hw);
u32 val;
val = readl_relaxed(chan->base + REG_CTRL);
writel_relaxed(val & ~CTRL_ENABLE, chan->base + REG_CTRL);
}
static int applnco_is_enabled(struct clk_hw *hw)
{
struct applnco_channel *chan = to_applnco_channel(hw);
return (readl_relaxed(chan->base + REG_CTRL) & CTRL_ENABLE) != 0;
}
static void applnco_compute_tables(struct applnco_tables *tbl)
{
int i;
u32 state = LFSR_INIT;
/*
* Go through the states of a Galois LFSR and build
* a coarse divisor translation table.
*/
for (i = LFSR_PERIOD; i > 0; i--) {
if (state & 1)
state = (state >> 1) ^ (LFSR_POLY >> 1);
else
state = (state >> 1);
tbl->fwd[i] = state;
tbl->inv[state] = i;
}
/* Zero value is special-cased */
tbl->fwd[0] = 0;
tbl->inv[0] = 0;
}
static bool applnco_div_out_of_range(unsigned int div)
{
unsigned int coarse = div / 4;
return coarse < COARSE_DIV_OFFSET ||
coarse >= COARSE_DIV_OFFSET + LFSR_TBLSIZE;
}
static u32 applnco_div_translate(struct applnco_tables *tbl, unsigned int div)
{
unsigned int coarse = div / 4;
if (WARN_ON(applnco_div_out_of_range(div)))
return 0;
return FIELD_PREP(DIV_COARSE, tbl->fwd[coarse - COARSE_DIV_OFFSET]) |
FIELD_PREP(DIV_FINE, div % 4);
}
static unsigned int applnco_div_translate_inv(struct applnco_tables *tbl, u32 regval)
{
unsigned int coarse, fine;
coarse = tbl->inv[FIELD_GET(DIV_COARSE, regval)] + COARSE_DIV_OFFSET;
fine = FIELD_GET(DIV_FINE, regval);
return coarse * 4 + fine;
}
static int applnco_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct applnco_channel *chan = to_applnco_channel(hw);
unsigned long flags;
u32 div, inc1, inc2;
bool was_enabled;
div = 2 * parent_rate / rate;
inc1 = 2 * parent_rate - div * rate;
inc2 = inc1 - rate;
if (applnco_div_out_of_range(div))
return -EINVAL;
div = applnco_div_translate(chan->tbl, div);
spin_lock_irqsave(&chan->lock, flags);
was_enabled = applnco_is_enabled(hw);
applnco_disable_nolock(hw);
writel_relaxed(div, chan->base + REG_DIV);
writel_relaxed(inc1, chan->base + REG_INC1);
writel_relaxed(inc2, chan->base + REG_INC2);
/* Presumably a neutral initial value for accumulator */
writel_relaxed(1 << 31, chan->base + REG_ACCINIT);
if (was_enabled)
applnco_enable_nolock(hw);
spin_unlock_irqrestore(&chan->lock, flags);
return 0;
}
static unsigned long applnco_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct applnco_channel *chan = to_applnco_channel(hw);
u32 div, inc1, inc2, incbase;
div = applnco_div_translate_inv(chan->tbl,
readl_relaxed(chan->base + REG_DIV));
inc1 = readl_relaxed(chan->base + REG_INC1);
inc2 = readl_relaxed(chan->base + REG_INC2);
/*
* We don't support wraparound of accumulator
* nor the edge case of both increments being zero
*/
if (inc1 >= (1 << 31) || inc2 < (1 << 31) || (inc1 == 0 && inc2 == 0))
return 0;
/* Scale both sides of division by incbase to maintain precision */
incbase = inc1 - inc2;
return div64_u64(((u64) parent_rate) * 2 * incbase,
((u64) div) * incbase + inc1);
}
static long applnco_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
unsigned long lo = *parent_rate / (COARSE_DIV_OFFSET + LFSR_TBLSIZE) + 1;
unsigned long hi = *parent_rate / COARSE_DIV_OFFSET;
return clamp(rate, lo, hi);
}
static int applnco_enable(struct clk_hw *hw)
{
struct applnco_channel *chan = to_applnco_channel(hw);
unsigned long flags;
spin_lock_irqsave(&chan->lock, flags);
applnco_enable_nolock(hw);
spin_unlock_irqrestore(&chan->lock, flags);
return 0;
}
static void applnco_disable(struct clk_hw *hw)
{
struct applnco_channel *chan = to_applnco_channel(hw);
unsigned long flags;
spin_lock_irqsave(&chan->lock, flags);
applnco_disable_nolock(hw);
spin_unlock_irqrestore(&chan->lock, flags);
}
static const struct clk_ops applnco_ops = {
.set_rate = applnco_set_rate,
.recalc_rate = applnco_recalc_rate,
.round_rate = applnco_round_rate,
.enable = applnco_enable,
.disable = applnco_disable,
.is_enabled = applnco_is_enabled,
};
static int applnco_probe(struct platform_device *pdev)
{
struct device_node *np = pdev->dev.of_node;
struct clk_parent_data pdata = { .index = 0 };
struct clk_init_data init;
struct clk_hw_onecell_data *onecell_data;
void __iomem *base;
struct resource *res;
struct applnco_tables *tbl;
unsigned int nchannels;
int ret, i;
base = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
if (IS_ERR(base))
return PTR_ERR(base);
if (resource_size(res) < NCO_CHANNEL_REGSIZE)
return -EINVAL;
nchannels = (resource_size(res) - NCO_CHANNEL_REGSIZE)
/ NCO_CHANNEL_STRIDE + 1;
onecell_data = devm_kzalloc(&pdev->dev, struct_size(onecell_data, hws,
nchannels), GFP_KERNEL);
if (!onecell_data)
return -ENOMEM;
onecell_data->num = nchannels;
tbl = devm_kzalloc(&pdev->dev, sizeof(*tbl), GFP_KERNEL);
if (!tbl)
return -ENOMEM;
applnco_compute_tables(tbl);
for (i = 0; i < nchannels; i++) {
struct applnco_channel *chan;
chan = devm_kzalloc(&pdev->dev, sizeof(*chan), GFP_KERNEL);
if (!chan)
return -ENOMEM;
chan->base = base + NCO_CHANNEL_STRIDE * i;
chan->tbl = tbl;
spin_lock_init(&chan->lock);
memset(&init, 0, sizeof(init));
init.name = devm_kasprintf(&pdev->dev, GFP_KERNEL,
"%s-%d", np->name, i);
init.ops = &applnco_ops;
init.parent_data = &pdata;
init.num_parents = 1;
init.flags = 0;
chan->hw.init = &init;
ret = devm_clk_hw_register(&pdev->dev, &chan->hw);
if (ret)
return ret;
onecell_data->hws[i] = &chan->hw;
}
return devm_of_clk_add_hw_provider(&pdev->dev, of_clk_hw_onecell_get,
onecell_data);
}
static const struct of_device_id applnco_ids[] = {
{ .compatible = "apple,nco" },
{ }
};
MODULE_DEVICE_TABLE(of, applnco_ids);
static struct platform_driver applnco_driver = {
.driver = {
.name = "apple-nco",
.of_match_table = applnco_ids,
},
.probe = applnco_probe,
};
module_platform_driver(applnco_driver);
MODULE_AUTHOR("Martin Povišer <povik+lin@cutebit.org>");
MODULE_DESCRIPTION("Clock driver for NCO blocks on Apple SoCs");
MODULE_LICENSE("GPL");
......@@ -632,6 +632,24 @@ static void clk_core_get_boundaries(struct clk_core *core,
*max_rate = min(*max_rate, clk_user->max_rate);
}
static bool clk_core_check_boundaries(struct clk_core *core,
unsigned long min_rate,
unsigned long max_rate)
{
struct clk *user;
lockdep_assert_held(&prepare_lock);
if (min_rate > core->max_rate || max_rate < core->min_rate)
return false;
hlist_for_each_entry(user, &core->clks, clks_node)
if (min_rate > user->max_rate || max_rate < user->min_rate)
return false;
return true;
}
void clk_hw_set_rate_range(struct clk_hw *hw, unsigned long min_rate,
unsigned long max_rate)
{
......@@ -1330,6 +1348,8 @@ static int clk_core_determine_round_nolock(struct clk_core *core,
if (!core)
return 0;
req->rate = clamp(req->rate, req->min_rate, req->max_rate);
/*
* At this point, core protection will be disabled
* - if the provider is not protected at all
......@@ -2312,19 +2332,15 @@ int clk_set_rate_exclusive(struct clk *clk, unsigned long rate)
}
EXPORT_SYMBOL_GPL(clk_set_rate_exclusive);
/**
* clk_set_rate_range - set a rate range for a clock source
* @clk: clock source
* @min: desired minimum clock rate in Hz, inclusive
* @max: desired maximum clock rate in Hz, inclusive
*
* Returns success (0) or negative errno.
*/
int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
static int clk_set_rate_range_nolock(struct clk *clk,
unsigned long min,
unsigned long max)
{
int ret = 0;
unsigned long old_min, old_max, rate;
lockdep_assert_held(&prepare_lock);
if (!clk)
return 0;
......@@ -2337,8 +2353,6 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
return -EINVAL;
}
clk_prepare_lock();
if (clk->exclusive_count)
clk_core_rate_unprotect(clk->core);
......@@ -2348,37 +2362,62 @@ int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
clk->min_rate = min;
clk->max_rate = max;
rate = clk_core_get_rate_nolock(clk->core);
if (rate < min || rate > max) {
/*
* FIXME:
* We are in bit of trouble here, current rate is outside the
* the requested range. We are going try to request appropriate
* range boundary but there is a catch. It may fail for the
* usual reason (clock broken, clock protected, etc) but also
* because:
* - round_rate() was not favorable and fell on the wrong
* side of the boundary
* - the determine_rate() callback does not really check for
* this corner case when determining the rate
*/
if (rate < min)
rate = min;
else
rate = max;
if (!clk_core_check_boundaries(clk->core, min, max)) {
ret = -EINVAL;
goto out;
}
ret = clk_core_set_rate_nolock(clk->core, rate);
if (ret) {
/* rollback the changes */
clk->min_rate = old_min;
clk->max_rate = old_max;
}
/*
* Since the boundaries have been changed, let's give the
* opportunity to the provider to adjust the clock rate based on
* the new boundaries.
*
* We also need to handle the case where the clock is currently
* outside of the boundaries. Clamping the last requested rate
* to the current minimum and maximum will also handle this.
*
* FIXME:
* There is a catch. It may fail for the usual reason (clock
* broken, clock protected, etc) but also because:
* - round_rate() was not favorable and fell on the wrong
* side of the boundary
* - the determine_rate() callback does not really check for
* this corner case when determining the rate
*/
rate = clamp(clk->core->req_rate, min, max);
ret = clk_core_set_rate_nolock(clk->core, rate);
if (ret) {
/* rollback the changes */
clk->min_rate = old_min;
clk->max_rate = old_max;
}
out:
if (clk->exclusive_count)
clk_core_rate_protect(clk->core);
return ret;
}
/**
* clk_set_rate_range - set a rate range for a clock source
* @clk: clock source
* @min: desired minimum clock rate in Hz, inclusive
* @max: desired maximum clock rate in Hz, inclusive
*
* Return: 0 for success or negative errno on failure.
*/
int clk_set_rate_range(struct clk *clk, unsigned long min, unsigned long max)
{
int ret;
if (!clk)
return 0;
clk_prepare_lock();
ret = clk_set_rate_range_nolock(clk, min, max);
clk_prepare_unlock();
return ret;
......@@ -3456,6 +3495,19 @@ static void clk_core_reparent_orphans_nolock(void)
__clk_set_parent_after(orphan, parent, NULL);
__clk_recalc_accuracies(orphan);
__clk_recalc_rates(orphan, 0);
/*
* __clk_init_parent() will set the initial req_rate to
* 0 if the clock doesn't have clk_ops::recalc_rate and
* is an orphan when it's registered.
*
* 'req_rate' is used by clk_set_rate_range() and
* clk_put() to trigger a clk_set_rate() call whenever
* the boundaries are modified. Let's make sure
* 'req_rate' is set to something non-zero so that
* clk_set_rate_range() doesn't drop the frequency.
*/
orphan->req_rate = orphan->rate;
}
}
}
......@@ -3773,8 +3825,9 @@ struct clk *clk_hw_create_clk(struct device *dev, struct clk_hw *hw,
struct clk *clk_hw_get_clk(struct clk_hw *hw, const char *con_id)
{
struct device *dev = hw->core->dev;
const char *name = dev ? dev_name(dev) : NULL;
return clk_hw_create_clk(dev, hw, dev_name(dev), con_id);
return clk_hw_create_clk(dev, hw, name, con_id);
}
EXPORT_SYMBOL(clk_hw_get_clk);
......@@ -4366,9 +4419,7 @@ void __clk_put(struct clk *clk)
}
hlist_del(&clk->clks_node);
if (clk->min_rate > clk->core->req_rate ||
clk->max_rate < clk->core->req_rate)
clk_core_set_rate_nolock(clk->core, clk->core->req_rate);
clk_set_rate_range_nolock(clk, 0, ULONG_MAX);
owner = clk->core->owner;
kref_put(&clk->core->ref, __clk_release);
......
This diff is collapsed.
......@@ -29,11 +29,11 @@ config QCOM_A53PLL
devices.
config QCOM_A7PLL
tristate "SDX55 A7 PLL"
tristate "A7 PLL driver for SDX55 and SDX65"
help
Support for the A7 PLL on SDX55 devices. It provides the CPU with
Support for the A7 PLL on SDX55 and SDX65 devices. It provides the CPU with
frequencies above 1GHz.
Say Y if you want to support higher CPU frequencies on SDX55
Say Y if you want to support higher CPU frequencies on SDX55 and SDX65
devices.
config QCOM_CLK_APCS_MSM8916
......@@ -55,13 +55,13 @@ config QCOM_CLK_APCC_MSM8996
drivers for dynamic power management.
config QCOM_CLK_APCS_SDX55
tristate "SDX55 APCS Clock Controller"
tristate "SDX55 and SDX65 APCS Clock Controller"
depends on QCOM_APCS_IPC || COMPILE_TEST
help
Support for the APCS Clock Controller on SDX55 platform. The
Support for the APCS Clock Controller on SDX55, SDX65 platforms. The
APCS is managing the mux and divider which feeds the CPUs.
Say Y if you want to support CPU frequency scaling on devices
such as SDX55.
such as SDX55, SDX65.
config QCOM_CLK_RPM
tristate "RPM based Clock Controller"
......@@ -340,6 +340,15 @@ config QCM_GCC_2290
Say Y if you want to use multimedia devices or peripheral
devices such as UART, SPI, I2C, USB, SD/eMMC etc.
config QCM_DISPCC_2290
tristate "QCM2290 Display Clock Controller"
select QCM_GCC_2290
help
Support for the display clock controller on Qualcomm Technologies, Inc
QCM2290 devices.
Say Y if you want to support display devices and functionality such as
splash screen.
config QCS_GCC_404
tristate "QCS404 Global Clock Controller"
help
......@@ -565,6 +574,14 @@ config SDX_GCC_55
Say Y if you want to use peripheral devices such as UART,
SPI, I2C, USB, SD/UFS, PCIe etc.
config SDX_GCC_65
tristate "SDX65 Global Clock Controller"
select QCOM_GDSC
help
Support for the global clock controller on SDX65 devices.
Say Y if you want to use peripheral devices such as UART,
SPI, I2C, USB, SD/UFS, PCIe etc.
config SM_CAMCC_8250
tristate "SM8250 Camera Clock Controller"
select SM_GCC_8250
......@@ -572,13 +589,14 @@ config SM_CAMCC_8250
Support for the camera clock controller on SM8250 devices.
Say Y if you want to support camera devices and camera functionality.
config SDX_GCC_65
tristate "SDX65 Global Clock Controller"
select QCOM_GDSC
config SM_DISPCC_6125
tristate "SM6125 Display Clock Controller"
depends on SM_GCC_6125
help
Support for the global clock controller on SDX65 devices.
Say Y if you want to use peripheral devices such as UART,
SPI, I2C, USB, SD/UFS, PCIe etc.
Support for the display clock controller on Qualcomm Technologies, Inc
SM6125 devices.
Say Y if you want to support display devices and functionality such as
splash screen
config SM_DISPCC_8250
tristate "SM8150 and SM8250 Display Clock Controller"
......@@ -589,6 +607,15 @@ config SM_DISPCC_8250
Say Y if you want to support display devices and functionality such as
splash screen.
config SM_DISPCC_6350
tristate "SM6350 Display Clock Controller"
depends on SM_GCC_6350
help
Support for the display clock controller on Qualcomm Technologies, Inc
SM6350 devices.
Say Y if you want to support display devices and functionality such as
splash screen.
config SM_GCC_6115
tristate "SM6115 and SM4250 Global Clock Controller"
help
......@@ -642,6 +669,14 @@ config SM_GCC_8450
Say Y if you want to use peripheral devices such as UART,
SPI, I2C, USB, SD/UFS, PCIe etc.
config SM_GPUCC_6350
tristate "SM6350 Graphics Clock Controller"
select SM_GCC_6350
help
Support for the graphics clock controller on SM6350 devices.
Say Y if you want to support graphics controller devices and
functionality such as 3D graphics.
config SM_GPUCC_8150
tristate "SM8150 Graphics Clock Controller"
select SM_GCC_8150
......
......@@ -56,6 +56,7 @@ obj-$(CONFIG_QCOM_CLK_RPM) += clk-rpm.o
obj-$(CONFIG_QCOM_CLK_RPMH) += clk-rpmh.o
obj-$(CONFIG_QCOM_CLK_SMD_RPM) += clk-smd-rpm.o
obj-$(CONFIG_QCM_GCC_2290) += gcc-qcm2290.o
obj-$(CONFIG_QCM_DISPCC_2290) += dispcc-qcm2290.o
obj-$(CONFIG_QCS_GCC_404) += gcc-qcs404.o
obj-$(CONFIG_QCS_Q6SSTOP_404) += q6sstop-qcs404.o
obj-$(CONFIG_QCS_TURING_404) += turingcc-qcs404.o
......@@ -83,8 +84,10 @@ 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_CAMCC_8250) += camcc-sm8250.o
obj-$(CONFIG_SDX_GCC_65) += gcc-sdx65.o
obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o
obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o
obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o
obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o
obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o
......@@ -93,6 +96,7 @@ obj-$(CONFIG_SM_GCC_8150) += gcc-sm8150.o
obj-$(CONFIG_SM_GCC_8250) += gcc-sm8250.o
obj-$(CONFIG_SM_GCC_8350) += gcc-sm8350.o
obj-$(CONFIG_SM_GCC_8450) += gcc-sm8450.o
obj-$(CONFIG_SM_GPUCC_6350) += gpucc-sm6350.o
obj-$(CONFIG_SM_GPUCC_8150) += gpucc-sm8150.o
obj-$(CONFIG_SM_GPUCC_8250) += gpucc-sm8250.o
obj-$(CONFIG_SM_VIDEOCC_8150) += videocc-sm8150.o
......
This diff is collapsed.
This diff is collapsed.
......@@ -526,6 +526,19 @@ static int clk_rcg_set_rate(struct clk_hw *hw, unsigned long rate,
return __clk_rcg_set_rate(rcg, f);
}
static int clk_rcg_set_floor_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_rcg *rcg = to_clk_rcg(hw);
const struct freq_tbl *f;
f = qcom_find_freq_floor(rcg->freq_tbl, rate);
if (!f)
return -EINVAL;
return __clk_rcg_set_rate(rcg, f);
}
static int clk_rcg_bypass_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
......@@ -816,6 +829,17 @@ const struct clk_ops clk_rcg_ops = {
};
EXPORT_SYMBOL_GPL(clk_rcg_ops);
const struct clk_ops clk_rcg_floor_ops = {
.enable = clk_enable_regmap,
.disable = clk_disable_regmap,
.get_parent = clk_rcg_get_parent,
.set_parent = clk_rcg_set_parent,
.recalc_rate = clk_rcg_recalc_rate,
.determine_rate = clk_rcg_determine_rate,
.set_rate = clk_rcg_set_floor_rate,
};
EXPORT_SYMBOL_GPL(clk_rcg_floor_ops);
const struct clk_ops clk_rcg_bypass_ops = {
.enable = clk_enable_regmap,
.disable = clk_disable_regmap,
......
......@@ -86,6 +86,7 @@ struct clk_rcg {
};
extern const struct clk_ops clk_rcg_ops;
extern const struct clk_ops clk_rcg_floor_ops;
extern const struct clk_ops clk_rcg_bypass_ops;
extern const struct clk_ops clk_rcg_bypass2_ops;
extern const struct clk_ops clk_rcg_pixel_ops;
......
......@@ -264,7 +264,7 @@ static int clk_rcg2_determine_floor_rate(struct clk_hw *hw,
static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
{
u32 cfg, mask;
u32 cfg, mask, d_val, not2d_val, n_minus_m;
struct clk_hw *hw = &rcg->clkr.hw;
int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src);
......@@ -283,8 +283,17 @@ static int __clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
if (ret)
return ret;
/* Calculate 2d value */
d_val = f->n;
n_minus_m = f->n - f->m;
n_minus_m *= 2;
d_val = clamp_t(u32, d_val, f->m, n_minus_m);
not2d_val = ~d_val & mask;
ret = regmap_update_bits(rcg->clkr.regmap,
RCG_D_OFFSET(rcg), mask, ~f->n);
RCG_D_OFFSET(rcg), mask, not2d_val);
if (ret)
return ret;
}
......@@ -720,6 +729,7 @@ static const struct frac_entry frac_table_pixel[] = {
{ 2, 9 },
{ 4, 9 },
{ 1, 1 },
{ 2, 3 },
{ }
};
......
......@@ -512,6 +512,23 @@ static const struct clk_rpmh_desc clk_rpmh_sm8350 = {
.num_clks = ARRAY_SIZE(sm8350_rpmh_clocks),
};
DEFINE_CLK_RPMH_VRM(sc8280xp, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2);
static struct clk_hw *sc8280xp_rpmh_clocks[] = {
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
[RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
[RPMH_LN_BB_CLK3] = &sc8280xp_ln_bb_clk3.hw,
[RPMH_LN_BB_CLK3_A] = &sc8280xp_ln_bb_clk3_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_sc8280xp = {
.clks = sc8280xp_rpmh_clocks,
.num_clks = ARRAY_SIZE(sc8280xp_rpmh_clocks),
};
/* Resource name must match resource id present in cmd-db */
DEFINE_CLK_RPMH_ARC(sc7280, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 4);
......@@ -691,6 +708,7 @@ 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,sc8180x-rpmh-clk", .data = &clk_rpmh_sc8180x},
{ .compatible = "qcom,sc8280xp-rpmh-clk", .data = &clk_rpmh_sc8280xp},
{ .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
{ .compatible = "qcom,sdx55-rpmh-clk", .data = &clk_rpmh_sdx55},
{ .compatible = "qcom,sdx65-rpmh-clk", .data = &clk_rpmh_sdx65},
......
......@@ -413,6 +413,7 @@ static const struct clk_ops clk_smd_rpm_branch_ops = {
.recalc_rate = clk_smd_rpm_recalc_rate,
};
DEFINE_CLK_SMD_RPM_BRANCH(sdm660, bi_tcxo, bi_tcxo_a, QCOM_SMD_RPM_MISC_CLK, 0, 19200000);
DEFINE_CLK_SMD_RPM(msm8916, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8916, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
DEFINE_CLK_SMD_RPM(msm8916, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0);
......@@ -604,7 +605,11 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8992, ln_bb_clk, ln_bb_a_clk, 8, 19200000);
DEFINE_CLK_SMD_RPM(msm8992, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8992, ce2_clk, ce2_a_clk, QCOM_SMD_RPM_CE_CLK, 1);
DEFINE_CLK_SMD_RPM_BRANCH(msm8992, mss_cfg_ahb_clk, mss_cfg_ahb_a_clk,
QCOM_SMD_RPM_MCFG_CLK, 0, 19200000);
static struct clk_smd_rpm *msm8992_clks[] = {
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
[RPM_SMD_PNOC_CLK] = &msm8916_pcnoc_clk,
[RPM_SMD_PNOC_A_CLK] = &msm8916_pcnoc_a_clk,
[RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk,
......@@ -637,6 +642,8 @@ static struct clk_smd_rpm *msm8992_clks[] = {
[RPM_SMD_LN_BB_A_CLK] = &msm8992_ln_bb_a_clk,
[RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk,
[RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk,
[RPM_SMD_MSS_CFG_AHB_CLK] = &msm8992_mss_cfg_ahb_clk,
[RPM_SMD_MSS_CFG_AHB_A_CLK] = &msm8992_mss_cfg_ahb_a_clk,
[RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk,
[RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk,
[RPM_SMD_RF_CLK1] = &msm8916_rf_clk1,
......@@ -661,6 +668,8 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8992 = {
DEFINE_CLK_SMD_RPM(msm8994, ce3_clk, ce3_a_clk, QCOM_SMD_RPM_CE_CLK, 2);
static struct clk_smd_rpm *msm8994_clks[] = {
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
[RPM_SMD_PNOC_CLK] = &msm8916_pcnoc_clk,
[RPM_SMD_PNOC_A_CLK] = &msm8916_pcnoc_a_clk,
[RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk,
......@@ -693,6 +702,8 @@ static struct clk_smd_rpm *msm8994_clks[] = {
[RPM_SMD_LN_BB_A_CLK] = &msm8992_ln_bb_a_clk,
[RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk,
[RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk,
[RPM_SMD_MSS_CFG_AHB_CLK] = &msm8992_mss_cfg_ahb_clk,
[RPM_SMD_MSS_CFG_AHB_A_CLK] = &msm8992_mss_cfg_ahb_a_clk,
[RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk,
[RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk,
[RPM_SMD_RF_CLK1] = &msm8916_rf_clk1,
......@@ -805,15 +816,18 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = {
.num_clks = ARRAY_SIZE(qcs404_clks),
};
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, ln_bb_clk3_pin, ln_bb_clk3_a_pin,
3, 19200000);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, ln_bb_clk3, ln_bb_clk3_a, 3, 19200000);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, ln_bb_clk3_pin, ln_bb_clk3_a_pin, 3, 19200000);
DEFINE_CLK_SMD_RPM(msm8998, aggre1_noc_clk, aggre1_noc_a_clk,
QCOM_SMD_RPM_AGGR_CLK, 1);
DEFINE_CLK_SMD_RPM(msm8998, aggre2_noc_clk, aggre2_noc_a_clk,
QCOM_SMD_RPM_AGGR_CLK, 2);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6, 19200000);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6, 19200000);
static struct clk_smd_rpm *msm8998_clks[] = {
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
[RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk,
[RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk,
[RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk,
......@@ -826,12 +840,22 @@ static struct clk_smd_rpm *msm8998_clks[] = {
[RPM_SMD_CE1_A_CLK] = &msm8992_ce1_a_clk,
[RPM_SMD_DIV_CLK1] = &msm8974_div_clk1,
[RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1,
[RPM_SMD_DIV_CLK2] = &msm8974_div_clk2,
[RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2,
[RPM_SMD_DIV_CLK3] = &msm8992_div_clk3,
[RPM_SMD_DIV_A_CLK3] = &msm8992_div_clk3_a,
[RPM_SMD_IPA_CLK] = &msm8976_ipa_clk,
[RPM_SMD_IPA_A_CLK] = &msm8976_ipa_a_clk,
[RPM_SMD_LN_BB_CLK1] = &msm8916_bb_clk1,
[RPM_SMD_LN_BB_CLK1_A] = &msm8916_bb_clk1_a,
[RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2,
[RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a,
[RPM_SMD_LN_BB_CLK3] = &msm8998_ln_bb_clk3,
[RPM_SMD_LN_BB_CLK3_A] = &msm8998_ln_bb_clk3_a,
[RPM_SMD_LN_BB_CLK1_PIN] = &msm8916_bb_clk1_pin,
[RPM_SMD_LN_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin,
[RPM_SMD_LN_BB_CLK2_PIN] = &msm8916_bb_clk2_pin,
[RPM_SMD_LN_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin,
[RPM_SMD_LN_BB_CLK3_PIN] = &msm8998_ln_bb_clk3_pin,
[RPM_SMD_LN_BB_CLK3_A_PIN] = &msm8998_ln_bb_clk3_a_pin,
[RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk,
......@@ -844,10 +868,14 @@ static struct clk_smd_rpm *msm8998_clks[] = {
[RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk,
[RPM_SMD_RF_CLK1] = &msm8916_rf_clk1,
[RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a,
[RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin,
[RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin,
[RPM_SMD_RF_CLK2] = &msm8916_rf_clk2,
[RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a,
[RPM_SMD_RF_CLK3] = &msm8998_rf_clk3,
[RPM_SMD_RF_CLK3_A] = &msm8998_rf_clk3_a,
[RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin,
[RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin,
[RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin,
[RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin,
[RPM_SMD_RF_CLK3_PIN] = &msm8998_rf_clk3_pin,
[RPM_SMD_RF_CLK3_A_PIN] = &msm8998_rf_clk3_a_pin,
};
......@@ -857,11 +885,6 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8998 = {
.num_clks = ARRAY_SIZE(msm8998_clks),
};
DEFINE_CLK_SMD_RPM_BRANCH(sdm660, bi_tcxo, bi_tcxo_a, QCOM_SMD_RPM_MISC_CLK, 0,
19200000);
DEFINE_CLK_SMD_RPM_XO_BUFFER(sdm660, ln_bb_clk3, ln_bb_clk3_a, 3, 19200000);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(sdm660, ln_bb_clk3_pin, ln_bb_clk3_pin_a, 3, 19200000);
static struct clk_smd_rpm *sdm660_clks[] = {
[RPM_SMD_XO_CLK_SRC] = &sdm660_bi_tcxo,
[RPM_SMD_XO_A_CLK_SRC] = &sdm660_bi_tcxo_a,
......@@ -891,16 +914,16 @@ static struct clk_smd_rpm *sdm660_clks[] = {
[RPM_SMD_LN_BB_A_CLK] = &msm8916_bb_clk1_a,
[RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2,
[RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a,
[RPM_SMD_LN_BB_CLK3] = &sdm660_ln_bb_clk3,
[RPM_SMD_LN_BB_CLK3_A] = &sdm660_ln_bb_clk3_a,
[RPM_SMD_LN_BB_CLK3] = &msm8998_ln_bb_clk3,
[RPM_SMD_LN_BB_CLK3_A] = &msm8998_ln_bb_clk3_a,
[RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin,
[RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin,
[RPM_SMD_LN_BB_CLK1_PIN] = &msm8916_bb_clk1_pin,
[RPM_SMD_LN_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin,
[RPM_SMD_LN_BB_CLK2_PIN] = &msm8916_bb_clk2_pin,
[RPM_SMD_LN_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin,
[RPM_SMD_LN_BB_CLK3_PIN] = &sdm660_ln_bb_clk3_pin,
[RPM_SMD_LN_BB_CLK3_A_PIN] = &sdm660_ln_bb_clk3_pin_a,
[RPM_SMD_LN_BB_CLK3_PIN] = &msm8998_ln_bb_clk3_pin,
[RPM_SMD_LN_BB_CLK3_A_PIN] = &msm8998_ln_bb_clk3_a_pin,
};
static const struct rpm_smd_clk_desc rpm_clk_sdm660 = {
......@@ -1002,8 +1025,8 @@ static struct clk_smd_rpm *sm6125_clks[] = {
[RPM_SMD_LN_BB_CLK1_A] = &msm8916_bb_clk1_a,
[RPM_SMD_LN_BB_CLK2] = &msm8916_bb_clk2,
[RPM_SMD_LN_BB_CLK2_A] = &msm8916_bb_clk2_a,
[RPM_SMD_LN_BB_CLK3] = &sdm660_ln_bb_clk3,
[RPM_SMD_LN_BB_CLK3_A] = &sdm660_ln_bb_clk3_a,
[RPM_SMD_LN_BB_CLK3] = &msm8998_ln_bb_clk3,
[RPM_SMD_LN_BB_CLK3_A] = &msm8998_ln_bb_clk3_a,
[RPM_SMD_QUP_CLK] = &sm6125_qup_clk,
[RPM_SMD_QUP_A_CLK] = &sm6125_qup_a_clk,
[RPM_SMD_MMRT_CLK] = &sm6125_mmrt_clk,
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -60,11 +60,6 @@ static const struct parent_map gcc_xo_gpll0_gpll0_out_main_div2_map[] = {
{ P_GPLL0_DIV2, 4 },
};
static const char * const gcc_xo_gpll0[] = {
"xo",
"gpll0",
};
static const struct parent_map gcc_xo_gpll0_map[] = {
{ P_XO, 0 },
{ P_GPLL0, 1 },
......@@ -956,6 +951,11 @@ static struct clk_rcg2 blsp1_uart6_apps_clk_src = {
},
};
static const struct clk_parent_data gcc_xo_gpll0[] = {
{ .fw_name = "xo" },
{ .hw = &gpll0.clkr.hw },
};
static const struct freq_tbl ftbl_pcie_axi_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(200000000, P_GPLL0, 4, 0, 0),
......@@ -969,7 +969,7 @@ static struct clk_rcg2 pcie0_axi_clk_src = {
.parent_map = gcc_xo_gpll0_map,
.clkr.hw.init = &(struct clk_init_data){
.name = "pcie0_axi_clk_src",
.parent_names = gcc_xo_gpll0,
.parent_data = gcc_xo_gpll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
},
......@@ -1016,7 +1016,7 @@ static struct clk_rcg2 pcie1_axi_clk_src = {
.parent_map = gcc_xo_gpll0_map,
.clkr.hw.init = &(struct clk_init_data){
.name = "pcie1_axi_clk_src",
.parent_names = gcc_xo_gpll0,
.parent_data = gcc_xo_gpll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
},
......@@ -1074,7 +1074,7 @@ static struct clk_rcg2 sdcc1_apps_clk_src = {
.name = "sdcc1_apps_clk_src",
.parent_names = gcc_xo_gpll0_gpll2_gpll0_out_main_div2,
.num_parents = 4,
.ops = &clk_rcg2_ops,
.ops = &clk_rcg2_floor_ops,
},
};
......@@ -1330,7 +1330,7 @@ static struct clk_rcg2 nss_ce_clk_src = {
.parent_map = gcc_xo_gpll0_map,
.clkr.hw.init = &(struct clk_init_data){
.name = "nss_ce_clk_src",
.parent_names = gcc_xo_gpll0,
.parent_data = gcc_xo_gpll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
},
......@@ -4329,8 +4329,7 @@ static struct clk_rcg2 pcie0_rchng_clk_src = {
.parent_map = gcc_xo_gpll0_map,
.clkr.hw.init = &(struct clk_init_data){
.name = "pcie0_rchng_clk_src",
.parent_hws = (const struct clk_hw *[]) {
&gpll0.clkr.hw },
.parent_data = gcc_xo_gpll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
},
......
......@@ -77,6 +77,7 @@ static struct clk_alpha_pll gpll4_early = {
static struct clk_alpha_pll_postdiv gpll4 = {
.offset = 0x1dc0,
.width = 4,
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_DEFAULT],
.clkr.hw.init = &(struct clk_init_data){
.name = "gpll4",
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -99,8 +99,8 @@ static struct clk_branch video_cc_vcodec0_core_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_vcodec0_core_clk",
.parent_data = &(const struct clk_parent_data){
.hw = &video_cc_venus_clk_src.clkr.hw,
.parent_hws = (const struct clk_hw*[]){
&video_cc_venus_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
......@@ -143,8 +143,8 @@ static struct clk_branch video_cc_venus_ctl_core_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "video_cc_venus_ctl_core_clk",
.parent_data = &(const struct clk_parent_data){
.hw = &video_cc_venus_clk_src.clkr.hw,
.parent_hws = (const struct clk_hw*[]){
&video_cc_venus_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
......
......@@ -24,6 +24,7 @@ struct clk_hw *uniphier_clk_register_fixed_rate(struct device *dev,
init.name = name;
init.ops = &clk_fixed_rate_ops;
init.flags = 0;
init.parent_names = NULL;
init.num_parents = 0;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment