Merge branches 'clk-ti', 'clk-allwinner', 'clk-qcom', 'clk-sa' and 'clk-aspeed' into clk-next

- Qualcomm MSM8998 GPU clk controllers
 - Qualcomm SC7180 GCC and RPMH clk controllers
 - Qualcomm QCS404 Q6SSTOP clk controllers
 - Use struct_size() some more in various clk drivers

* clk-ti:
  clk/ti/adpll: allocate room for terminating null
  ARM: dts: omap3: fix DPLL4 M4 divider max value
  clk: ti: divider: convert to use min,max,mask instead of width
  clk: ti: divider: cleanup ti_clk_parse_divider_data API
  clk: ti: divider: cleanup _register_divider and ti_clk_get_div_table
  clk: ti: am43xx: drop idlest polling from gfx clock
  clk: ti: am33xx: drop idlest polling from gfx clock
  clk: ti: am33xx: drop idlest polling from pruss clkctrl clock
  clk: ti: am43xx: drop idlest polling from pruss clkctrl clock
  clk: ti: omap5: Drop idlest polling from IPU & DSP clkctrl clocks
  clk: ti: omap4: Drop idlest polling from IPU & DSP clkctrl clocks
  clk: ti: dra7xx: Drop idlest polling from IPU & DSP clkctrl clocks
  clk: ti: omap5: add IVA subsystem clkctrl data
  dt-bindings: clk: add omap5 iva clkctrl definitions
  clk: ti: clkctrl: add new exported API for checking standby info
  clk: ti: clkctrl: convert to use bit helper macros instead of bitops
  clk: ti: clkctrl: fix setting up clkctrl clocks

* clk-allwinner:
  clk: sunxi-ng: h3: Export MBUS clock
  clk: sunxi-ng: h6: Allow GPU to change parent rate
  clk: sunxi-ng: h6: Use sigma-delta modulation for audio PLL

* clk-qcom:
  clk: qcom: rpmh: Reuse sdm845 clks for sm8150
  clk: qcom: Add MSM8998 GPU Clock Controller (GPUCC) driver
  clk: qcom: Allow constant ratio freq tables for rcg
  clk: qcom: smd: Add missing pnoc clock
  clk: qcom: Enumerate clocks and reset needed to boot the 8998 modem
  clk: qcom: clk-rpmh: Add support for RPMHCC for SC7180
  dt-bindings: clock: Introduce RPMHCC bindings for SC7180
  dt-bindings: clock: Add YAML schemas for the QCOM RPMHCC clock bindings
  clk: qcom: Add Global Clock controller (GCC) driver for SC7180
  dt-bindings: clock: Add sc7180 GCC clock binding
  dt-bindings: clock: Add YAML schemas for the QCOM GCC clock bindings
  clk: qcom: common: Return NULL from clk_hw OF provider
  clk: qcom: rcg: update the DFS macro for RCG
  clk: qcom: remove unneeded semicolon
  clk: qcom: Add Q6SSTOP clock controller for QCS404
  dt-bindings: clock: qcom: Add QCOM Q6SSTOP clock controller bindings

* clk-sa:
  drivers/clk: convert VL struct to struct_size

* clk-aspeed:
  clk: aspeed: Add RMII RCLK gates for both AST2500 MACs
  clk: ast2600: Add RMII RCLK gates for all four MACs
  dt-bindings: clock: Add AST2600 RMII RCLK gate definitions
  dt-bindings: clock: Add AST2500 RMII RCLK definitions
This commit is contained in:
Stephen Boyd 2019-11-27 08:14:38 -08:00
47 changed files with 3957 additions and 421 deletions

View File

@ -1,94 +0,0 @@
Qualcomm Global Clock & Reset Controller Binding
------------------------------------------------
Required properties :
- compatible : shall contain only one of the following:
"qcom,gcc-apq8064"
"qcom,gcc-apq8084"
"qcom,gcc-ipq8064"
"qcom,gcc-ipq4019"
"qcom,gcc-ipq8074"
"qcom,gcc-msm8660"
"qcom,gcc-msm8916"
"qcom,gcc-msm8960"
"qcom,gcc-msm8974"
"qcom,gcc-msm8974pro"
"qcom,gcc-msm8974pro-ac"
"qcom,gcc-msm8994"
"qcom,gcc-msm8996"
"qcom,gcc-msm8998"
"qcom,gcc-mdm9615"
"qcom,gcc-qcs404"
"qcom,gcc-sdm630"
"qcom,gcc-sdm660"
"qcom,gcc-sdm845"
"qcom,gcc-sm8150"
- reg : shall contain base register location and length
- #clock-cells : shall contain 1
- #reset-cells : shall contain 1
Optional properties :
- #power-domain-cells : shall contain 1
- Qualcomm TSENS (thermal sensor device) on some devices can
be part of GCC and hence the TSENS properties can also be
part of the GCC/clock-controller node.
For more details on the TSENS properties please refer
Documentation/devicetree/bindings/thermal/qcom-tsens.txt
- protected-clocks : Protected clock specifier list as per common clock
binding.
For SM8150 only:
- clocks: a list of phandles and clock-specifier pairs,
one for each entry in clock-names.
- clock-names: "bi_tcxo" (required)
"sleep_clk" (optional)
"aud_ref_clock" (optional)
Example:
clock-controller@900000 {
compatible = "qcom,gcc-msm8960";
reg = <0x900000 0x4000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
Example of GCC with TSENS properties:
clock-controller@900000 {
compatible = "qcom,gcc-apq8064";
reg = <0x00900000 0x4000>;
nvmem-cells = <&tsens_calib>, <&tsens_backup>;
nvmem-cell-names = "calib", "calib_backup";
#clock-cells = <1>;
#reset-cells = <1>;
#thermal-sensor-cells = <1>;
};
Example of GCC with protected-clocks properties:
clock-controller@100000 {
compatible = "qcom,gcc-sdm845";
reg = <0x100000 0x1f0000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
protected-clocks = <GCC_QSPI_CORE_CLK>,
<GCC_QSPI_CORE_CLK_SRC>,
<GCC_QSPI_CNOC_PERIPH_AHB_CLK>,
<GCC_LPASS_Q6_AXI_CLK>,
<GCC_LPASS_SWAY_CLK>;
};
Example of GCC with clocks
gcc: clock-controller@100000 {
compatible = "qcom,gcc-sm8150";
reg = <0x00100000 0x1f0000>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
clock-names = "bi_tcxo",
"sleep_clk";
clocks = <&rpmcc RPM_SMD_XO_CLK_SRC>,
<&sleep_clk>;
};

View File

@ -0,0 +1,188 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/bindings/clock/qcom,gcc.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.
properties:
compatible :
enum:
- qcom,gcc-apq8064
- qcom,gcc-apq8084
- qcom,gcc-ipq8064
- qcom,gcc-ipq4019
- qcom,gcc-ipq8074
- qcom,gcc-msm8660
- qcom,gcc-msm8916
- qcom,gcc-msm8960
- qcom,gcc-msm8974
- qcom,gcc-msm8974pro
- qcom,gcc-msm8974pro-ac
- qcom,gcc-msm8994
- qcom,gcc-msm8996
- qcom,gcc-msm8998
- qcom,gcc-mdm9615
- qcom,gcc-qcs404
- qcom,gcc-sc7180
- qcom,gcc-sdm630
- qcom,gcc-sdm660
- qcom,gcc-sdm845
- qcom,gcc-sm8150
clocks:
minItems: 1
maxItems: 3
items:
- description: Board XO source
- description: Board active XO source
- description: Sleep clock source
clock-names:
minItems: 1
maxItems: 3
items:
- const: bi_tcxo
- const: bi_tcxo_ao
- const: sleep_clk
'#clock-cells':
const: 1
'#reset-cells':
const: 1
'#power-domain-cells':
const: 1
reg:
maxItems: 1
nvmem-cells:
minItems: 1
maxItems: 2
description:
Qualcomm TSENS (thermal sensor device) on some devices can
be part of GCC and hence the TSENS properties can also be part
of the GCC/clock-controller node.
For more details on the TSENS properties please refer
Documentation/devicetree/bindings/thermal/qcom-tsens.txt
nvmem-cell-names:
minItems: 1
maxItems: 2
description:
Names for each nvmem-cells specified.
items:
- const: calib
- const: calib_backup
'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'
if:
properties:
compatible:
contains:
const: qcom,gcc-apq8064
then:
required:
- nvmem-cells
- nvmem-cell-names
- '#thermal-sensor-cells'
else:
if:
properties:
compatible:
contains:
enum:
- qcom,gcc-sm8150
- qcom,gcc-sc7180
then:
required:
- clocks
- clock-names
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>;
};
# Example of GCC with TSENS properties:
- |
clock-controller@900000 {
compatible = "qcom,gcc-apq8064";
reg = <0x00900000 0x4000>;
nvmem-cells = <&tsens_calib>, <&tsens_backup>;
nvmem-cell-names = "calib", "calib_backup";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
#thermal-sensor-cells = <1>;
};
# Example of GCC with protected-clocks properties:
- |
clock-controller@100000 {
compatible = "qcom,gcc-sdm845";
reg = <0x100000 0x1f0000>;
protected-clocks = <187>, <188>, <189>, <190>, <191>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
# Example of GCC with clock node properties for SM8150:
- |
clock-controller@100000 {
compatible = "qcom,gcc-sm8150";
reg = <0x00100000 0x1f0000>;
clocks = <&rpmhcc 0>, <&rpmhcc 1>, <&sleep_clk>;
clock-names = "bi_tcxo", "bi_tcxo_ao", "sleep_clk";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
# Example of GCC with clock nodes properties for SC7180:
- |
clock-controller@100000 {
compatible = "qcom,gcc-sc7180";
reg = <0x100000 0x1f0000>;
clocks = <&rpmhcc 0>, <&rpmhcc 1>;
clock-names = "bi_tcxo", "bi_tcxo_ao";
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...

View File

@ -0,0 +1,43 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,q6sstopcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Q6SSTOP clock Controller
maintainers:
- Govind Singh <govinds@codeaurora.org>
properties:
compatible:
const: "qcom,qcs404-q6sstopcc"
reg:
items:
- description: Q6SSTOP clocks register region
- description: Q6SSTOP_TCSR register region
clocks:
items:
- description: ahb clock for the q6sstopCC
'#clock-cells':
const: 1
required:
- compatible
- reg
- clocks
- '#clock-cells'
additionalProperties: false
examples:
- |
q6sstopcc: clock-controller@7500000 {
compatible = "qcom,qcs404-q6sstopcc";
reg = <0x07500000 0x4e000>, <0x07550000 0x10000>;
clocks = <&gcc 141>;
#clock-cells = <1>;
};

View File

@ -1,27 +0,0 @@
Qualcomm Technologies, Inc. RPMh Clocks
-------------------------------------------------------
Resource Power Manager Hardened (RPMh) manages shared resources on
some Qualcomm Technologies Inc. SoCs. It accepts clock requests from
other hardware subsystems via RSC to control clocks.
Required properties :
- compatible : must be one of:
"qcom,sdm845-rpmh-clk"
"qcom,sm8150-rpmh-clk"
- #clock-cells : must contain 1
- clocks: a list of phandles and clock-specifier pairs,
one for each entry in clock-names.
- clock-names: Parent board clock: "xo".
Example :
#include <dt-bindings/clock/qcom,rpmh.h>
&apps_rsc {
rpmhcc: clock-controller {
compatible = "qcom,sdm845-rpmh-clk";
#clock-cells = <1>;
};
};

View File

@ -0,0 +1,49 @@
# SPDX-License-Identifier: GPL-2.0-only
%YAML 1.2
---
$id: http://devicetree.org/schemas/bindings/clock/qcom,rpmhcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Technologies, Inc. RPMh Clocks Bindings
maintainers:
- Taniya Das <tdas@codeaurora.org>
description: |
Resource Power Manager Hardened (RPMh) manages shared resources on
some Qualcomm Technologies Inc. SoCs. It accepts clock requests from
other hardware subsystems via RSC to control clocks.
properties:
compatible:
enum:
- qcom,sc7180-rpmh-clk
- qcom,sdm845-rpmh-clk
- qcom,sm8150-rpmh-clk
clocks:
maxItems: 1
clock-names:
items:
- const: xo
'#clock-cells':
const: 1
required:
- compatible
- '#clock-cells'
examples:
# Example for GCC for SDM845: The below node should be defined inside
# &apps_rsc node.
- |
#include <dt-bindings/clock/qcom,rpmh.h>
rpmhcc: clock-controller {
compatible = "qcom,sdm845-rpmh-clk";
clocks = <&xo_board>;
clock-names = "xo";
#clock-cells = <1>;
};
...

View File

@ -105,3 +105,7 @@ per_clkdm: per_clkdm {
<&mcbsp4_ick>, <&uart4_fck>;
};
};
&dpll4_m4_ck {
ti,max-div = <31>;
};

View File

@ -416,7 +416,7 @@ dpll4_m4_ck: dpll4_m4_ck@e40 {
#clock-cells = <0>;
compatible = "ti,divider-clock";
clocks = <&dpll4_ck>;
ti,max-div = <32>;
ti,max-div = <16>;
reg = <0x0e40>;
ti,index-starts-at-one;
};

View File

@ -478,8 +478,7 @@ static void __init of_sam9x60_sckc_setup(struct device_node *np)
if (IS_ERR(slow_osc))
goto unregister_slow_rc;
clk_data = kzalloc(sizeof(*clk_data) + (2 * sizeof(struct clk_hw *)),
GFP_KERNEL);
clk_data = kzalloc(struct_size(clk_data, hws, 2), GFP_KERNEL);
if (!clk_data)
goto unregister_slow_osc;

View File

@ -14,7 +14,7 @@
#include "clk-aspeed.h"
#define ASPEED_NUM_CLKS 36
#define ASPEED_NUM_CLKS 38
#define ASPEED_RESET2_OFFSET 32
@ -28,6 +28,7 @@
#define AST2400_HPLL_BYPASS_EN BIT(17)
#define ASPEED_MISC_CTRL 0x2c
#define UART_DIV13_EN BIT(12)
#define ASPEED_MAC_CLK_DLY 0x48
#define ASPEED_STRAP 0x70
#define CLKIN_25MHZ_EN BIT(23)
#define AST2400_CLK_SOURCE_SEL BIT(18)
@ -462,6 +463,30 @@ static int aspeed_clk_probe(struct platform_device *pdev)
return PTR_ERR(hw);
aspeed_clk_data->hws[ASPEED_CLK_MAC] = hw;
if (of_device_is_compatible(pdev->dev.of_node, "aspeed,ast2500-scu")) {
/* RMII 50MHz RCLK */
hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0,
50000000);
if (IS_ERR(hw))
return PTR_ERR(hw);
/* RMII1 50MHz (RCLK) output enable */
hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0,
scu_base + ASPEED_MAC_CLK_DLY, 29, 0,
&aspeed_clk_lock);
if (IS_ERR(hw))
return PTR_ERR(hw);
aspeed_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw;
/* RMII2 50MHz (RCLK) output enable */
hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0,
scu_base + ASPEED_MAC_CLK_DLY, 30, 0,
&aspeed_clk_lock);
if (IS_ERR(hw))
return PTR_ERR(hw);
aspeed_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw;
}
/* LPC Host (LHCLK) clock divider */
hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0,
scu_base + ASPEED_CLK_SELECTION, 20, 3, 0,

View File

@ -15,7 +15,7 @@
#include "clk-aspeed.h"
#define ASPEED_G6_NUM_CLKS 67
#define ASPEED_G6_NUM_CLKS 71
#define ASPEED_G6_SILICON_REV 0x004
@ -40,6 +40,9 @@
#define ASPEED_G6_STRAP1 0x500
#define ASPEED_MAC12_CLK_DLY 0x340
#define ASPEED_MAC34_CLK_DLY 0x350
/* Globally visible clocks */
static DEFINE_SPINLOCK(aspeed_g6_clk_lock);
@ -483,6 +486,11 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_SDIO] = hw;
/* MAC1/2 RMII 50MHz RCLK */
hw = clk_hw_register_fixed_rate(dev, "mac12rclk", "hpll", 0, 50000000);
if (IS_ERR(hw))
return PTR_ERR(hw);
/* MAC1/2 AHB bus clock divider */
hw = clk_hw_register_divider_table(dev, "mac12", "hpll", 0,
scu_g6_base + ASPEED_G6_CLK_SELECTION1, 16, 3, 0,
@ -492,6 +500,27 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_MAC12] = hw;
/* RMII1 50MHz (RCLK) output enable */
hw = clk_hw_register_gate(dev, "mac1rclk", "mac12rclk", 0,
scu_g6_base + ASPEED_MAC12_CLK_DLY, 29, 0,
&aspeed_g6_clk_lock);
if (IS_ERR(hw))
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_MAC1RCLK] = hw;
/* RMII2 50MHz (RCLK) output enable */
hw = clk_hw_register_gate(dev, "mac2rclk", "mac12rclk", 0,
scu_g6_base + ASPEED_MAC12_CLK_DLY, 30, 0,
&aspeed_g6_clk_lock);
if (IS_ERR(hw))
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_MAC2RCLK] = hw;
/* MAC1/2 RMII 50MHz RCLK */
hw = clk_hw_register_fixed_rate(dev, "mac34rclk", "hclk", 0, 50000000);
if (IS_ERR(hw))
return PTR_ERR(hw);
/* MAC3/4 AHB bus clock divider */
hw = clk_hw_register_divider_table(dev, "mac34", "hpll", 0,
scu_g6_base + 0x310, 24, 3, 0,
@ -501,6 +530,22 @@ static int aspeed_g6_clk_probe(struct platform_device *pdev)
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_MAC34] = hw;
/* RMII3 50MHz (RCLK) output enable */
hw = clk_hw_register_gate(dev, "mac3rclk", "mac34rclk", 0,
scu_g6_base + ASPEED_MAC34_CLK_DLY, 29, 0,
&aspeed_g6_clk_lock);
if (IS_ERR(hw))
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_MAC3RCLK] = hw;
/* RMII4 50MHz (RCLK) output enable */
hw = clk_hw_register_gate(dev, "mac4rclk", "mac34rclk", 0,
scu_g6_base + ASPEED_MAC34_CLK_DLY, 30, 0,
&aspeed_g6_clk_lock);
if (IS_ERR(hw))
return PTR_ERR(hw);
aspeed_g6_clk_data->hws[ASPEED_CLK_MAC4RCLK] = hw;
/* LPC Host (LHCLK) clock divider */
hw = clk_hw_register_divider_table(dev, "lhclk", "hpll", 0,
scu_g6_base + ASPEED_G6_CLK_SELECTION1, 20, 3, 0,

View File

@ -58,8 +58,7 @@ static void __init clk_boston_setup(struct device_node *np)
cpu_div = ext_field(mmcmdiv, BOSTON_PLAT_MMCMDIV_CLK1DIV);
cpu_freq = mult_frac(in_freq, mul, cpu_div);
onecell = kzalloc(sizeof(*onecell) +
(BOSTON_CLK_COUNT * sizeof(struct clk_hw *)),
onecell = kzalloc(struct_size(onecell, hws, BOSTON_CLK_COUNT),
GFP_KERNEL);
if (!onecell)
return;

View File

@ -358,8 +358,7 @@ static int __init ingenic_tcu_probe(struct device_node *np)
}
}
tcu->clocks = kzalloc(sizeof(*tcu->clocks) +
sizeof(*tcu->clocks->hws) * TCU_CLK_COUNT,
tcu->clocks = kzalloc(struct_size(tcu->clocks, hws, TCU_CLK_COUNT),
GFP_KERNEL);
if (!tcu->clocks) {
ret = -ENOMEM;

View File

@ -274,8 +274,8 @@ static int ap_cpu_clock_probe(struct platform_device *pdev)
if (!ap_cpu_clk)
return -ENOMEM;
ap_cpu_data = devm_kzalloc(dev, sizeof(*ap_cpu_data) +
sizeof(struct clk_hw *) * nclusters,
ap_cpu_data = devm_kzalloc(dev, struct_size(ap_cpu_data, hws,
nclusters),
GFP_KERNEL);
if (!ap_cpu_data)
return -ENOMEM;

View File

@ -235,8 +235,8 @@ static int cp110_syscon_common_probe(struct platform_device *pdev,
if (ret)
return ret;
cp110_clk_data = devm_kzalloc(dev, sizeof(*cp110_clk_data) +
sizeof(struct clk_hw *) * CP110_CLK_NUM,
cp110_clk_data = devm_kzalloc(dev, struct_size(cp110_clk_data, hws,
CP110_CLK_NUM),
GFP_KERNEL);
if (!cp110_clk_data)
return -ENOMEM;

View File

@ -220,6 +220,15 @@ config MSM_GCC_8998
Say Y if you want to use peripheral devices such as UART, SPI,
i2c, USB, UFS, SD/eMMC, PCIe, etc.
config MSM_GPUCC_8998
tristate "MSM8998 Graphics Clock Controller"
select MSM_GCC_8998
select QCOM_GDSC
help
Support for the graphics clock controller on MSM8998 devices.
Say Y if you want to support graphics controller devices and
functionality such as 3D graphics.
config QCS_GCC_404
tristate "QCS404 Global Clock Controller"
help
@ -227,6 +236,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_GCC_7180
tristate "SC7180 Global Clock Controller"
select QCOM_GDSC
depends on COMMON_CLK_QCOM
help
Support for the global clock controller on SC7180 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
I2C, USB, UFS, SDCC, etc.
config SDM_CAMCC_845
tristate "SDM845 Camera Clock Controller"
select SDM_GCC_845
@ -248,6 +266,14 @@ config QCS_TURING_404
Support for the Turing Clock Controller on QCS404, provides clocks
and resets for the Turing subsystem.
config QCS_Q6SSTOP_404
tristate "QCS404 Q6SSTOP Clock Controller"
select QCS_GCC_404
help
Support for the Q6SSTOP clock controller on QCS404 devices.
Say Y if you want to use the Q6SSTOP branch clocks of the WCSS clock
controller to reset the Q6SSTOP subsystem.
config SDM_GCC_845
tristate "SDM845 Global Clock Controller"
select QCOM_GDSC

View File

@ -33,6 +33,7 @@ obj-$(CONFIG_MSM_GCC_8994) += gcc-msm8994.o
obj-$(CONFIG_MSM_GCC_8996) += gcc-msm8996.o
obj-$(CONFIG_MSM_LCC_8960) += lcc-msm8960.o
obj-$(CONFIG_MSM_GCC_8998) += gcc-msm8998.o
obj-$(CONFIG_MSM_GPUCC_8998) += gpucc-msm8998.o
obj-$(CONFIG_MSM_MMCC_8960) += mmcc-msm8960.o
obj-$(CONFIG_MSM_MMCC_8974) += mmcc-msm8974.o
obj-$(CONFIG_MSM_MMCC_8996) += mmcc-msm8996.o
@ -42,7 +43,9 @@ 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_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_GCC_7180) += gcc-sc7180.o
obj-$(CONFIG_SDM_CAMCC_845) += camcc-sdm845.o
obj-$(CONFIG_SDM_DISPCC_845) += dispcc-sdm845.o
obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o

View File

@ -168,7 +168,7 @@ struct clk_rcg_dfs_data {
};
#define DEFINE_RCG_DFS(r) \
{ .rcg = &r##_src, .init = &r##_init }
{ .rcg = &r, .init = &r##_init }
extern int qcom_cc_register_rcg_dfs(struct regmap *regmap,
const struct clk_rcg_dfs_data *rcgs,

View File

@ -206,7 +206,7 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
break;
default:
return -EINVAL;
};
}
if (!f)
return -EINVAL;
@ -220,6 +220,8 @@ static int _freq_tbl_determine_rate(struct clk_hw *hw, const struct freq_tbl *f,
if (clk_flags & CLK_SET_RATE_PARENT) {
rate = f->freq;
if (f->pre_div) {
if (!rate)
rate = req->rate;
rate /= 2;
rate *= f->pre_div + 1;
}
@ -319,7 +321,7 @@ static int __clk_rcg2_set_rate(struct clk_hw *hw, unsigned long rate,
break;
default:
return -EINVAL;
};
}
if (!f)
return -EINVAL;

View File

@ -334,13 +334,14 @@ static const struct clk_ops clk_rpmh_bcm_ops = {
.recalc_rate = clk_rpmh_bcm_recalc_rate,
};
/* Resource name must match resource id present in cmd-db. */
/* Resource name must match resource id present in cmd-db */
DEFINE_CLK_RPMH_ARC(sdm845, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2);
DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2);
DEFINE_CLK_RPMH_VRM(sdm845, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2);
DEFINE_CLK_RPMH_VRM(sdm845, rf_clk1, rf_clk1_ao, "rfclka1", 1);
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");
static struct clk_hw *sdm845_rpmh_clocks[] = {
@ -364,26 +365,19 @@ static const struct clk_rpmh_desc clk_rpmh_sdm845 = {
.num_clks = ARRAY_SIZE(sdm845_rpmh_clocks),
};
DEFINE_CLK_RPMH_ARC(sm8150, bi_tcxo, bi_tcxo_ao, "xo.lvl", 0x3, 2);
DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk2, ln_bb_clk2_ao, "lnbclka2", 2);
DEFINE_CLK_RPMH_VRM(sm8150, ln_bb_clk3, ln_bb_clk3_ao, "lnbclka3", 2);
DEFINE_CLK_RPMH_VRM(sm8150, rf_clk1, rf_clk1_ao, "rfclka1", 1);
DEFINE_CLK_RPMH_VRM(sm8150, rf_clk2, rf_clk2_ao, "rfclka2", 1);
DEFINE_CLK_RPMH_VRM(sm8150, rf_clk3, rf_clk3_ao, "rfclka3", 1);
static struct clk_hw *sm8150_rpmh_clocks[] = {
[RPMH_CXO_CLK] = &sm8150_bi_tcxo.hw,
[RPMH_CXO_CLK_A] = &sm8150_bi_tcxo_ao.hw,
[RPMH_LN_BB_CLK2] = &sm8150_ln_bb_clk2.hw,
[RPMH_LN_BB_CLK2_A] = &sm8150_ln_bb_clk2_ao.hw,
[RPMH_LN_BB_CLK3] = &sm8150_ln_bb_clk3.hw,
[RPMH_LN_BB_CLK3_A] = &sm8150_ln_bb_clk3_ao.hw,
[RPMH_RF_CLK1] = &sm8150_rf_clk1.hw,
[RPMH_RF_CLK1_A] = &sm8150_rf_clk1_ao.hw,
[RPMH_RF_CLK2] = &sm8150_rf_clk2.hw,
[RPMH_RF_CLK2_A] = &sm8150_rf_clk2_ao.hw,
[RPMH_RF_CLK3] = &sm8150_rf_clk3.hw,
[RPMH_RF_CLK3_A] = &sm8150_rf_clk3_ao.hw,
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
[RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
[RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
[RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
[RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
[RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
[RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
[RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
[RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
[RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
[RPMH_RF_CLK3] = &sdm845_rf_clk3.hw,
[RPMH_RF_CLK3_A] = &sdm845_rf_clk3_ao.hw,
};
static const struct clk_rpmh_desc clk_rpmh_sm8150 = {
@ -391,6 +385,24 @@ static const struct clk_rpmh_desc clk_rpmh_sm8150 = {
.num_clks = ARRAY_SIZE(sm8150_rpmh_clocks),
};
static struct clk_hw *sc7180_rpmh_clocks[] = {
[RPMH_CXO_CLK] = &sdm845_bi_tcxo.hw,
[RPMH_CXO_CLK_A] = &sdm845_bi_tcxo_ao.hw,
[RPMH_LN_BB_CLK2] = &sdm845_ln_bb_clk2.hw,
[RPMH_LN_BB_CLK2_A] = &sdm845_ln_bb_clk2_ao.hw,
[RPMH_LN_BB_CLK3] = &sdm845_ln_bb_clk3.hw,
[RPMH_LN_BB_CLK3_A] = &sdm845_ln_bb_clk3_ao.hw,
[RPMH_RF_CLK1] = &sdm845_rf_clk1.hw,
[RPMH_RF_CLK1_A] = &sdm845_rf_clk1_ao.hw,
[RPMH_RF_CLK2] = &sdm845_rf_clk2.hw,
[RPMH_RF_CLK2_A] = &sdm845_rf_clk2_ao.hw,
};
static const struct clk_rpmh_desc clk_rpmh_sc7180 = {
.clks = sc7180_rpmh_clocks,
.num_clks = ARRAY_SIZE(sc7180_rpmh_clocks),
};
static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
void *data)
{
@ -471,6 +483,7 @@ static int clk_rpmh_probe(struct platform_device *pdev)
static const struct of_device_id clk_rpmh_match_table[] = {
{ .compatible = "qcom,sdm845-rpmh-clk", .data = &clk_rpmh_sdm845},
{ .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
{ .compatible = "qcom,sc7180-rpmh-clk", .data = &clk_rpmh_sc7180},
{ }
};
MODULE_DEVICE_TABLE(of, clk_rpmh_match_table);

View File

@ -648,6 +648,7 @@ static const struct rpm_smd_clk_desc rpm_clk_qcs404 = {
};
/* msm8998 */
DEFINE_CLK_SMD_RPM(msm8998, pcnoc_clk, pcnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 0);
DEFINE_CLK_SMD_RPM(msm8998, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1);
DEFINE_CLK_SMD_RPM(msm8998, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2);
DEFINE_CLK_SMD_RPM(msm8998, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0);
@ -670,6 +671,8 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5);
DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6);
DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6);
static struct clk_smd_rpm *msm8998_clks[] = {
[RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk,
[RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk,
[RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk,
[RPM_SMD_SNOC_A_CLK] = &msm8998_snoc_a_clk,
[RPM_SMD_CNOC_CLK] = &msm8998_cnoc_clk,

View File

@ -29,6 +29,9 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate)
if (!f)
return NULL;
if (!f->freq)
return f;
for (; f->freq; f++)
if (rate <= f->freq)
return f;
@ -218,7 +221,7 @@ static struct clk_hw *qcom_cc_clk_hw_get(struct of_phandle_args *clkspec,
return ERR_PTR(-EINVAL);
}
return cc->rclks[idx] ? &cc->rclks[idx]->hw : ERR_PTR(-ENOENT);
return cc->rclks[idx] ? &cc->rclks[idx]->hw : NULL;
}
int qcom_cc_really_probe(struct platform_device *pdev,

View File

@ -1266,6 +1266,72 @@ static struct clk_branch gcc_bimc_mss_q6_axi_clk = {
},
};
static struct clk_branch gcc_mss_cfg_ahb_clk = {
.halt_reg = 0x8a000,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x8a000,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_cfg_ahb_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_mss_snoc_axi_clk = {
.halt_reg = 0x8a03c,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x8a03c,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_snoc_axi_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
.halt_reg = 0x8a004,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x8a004,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_mnoc_bimc_axi_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_boot_rom_ahb_clk = {
.halt_reg = 0x38004,
.halt_check = BRANCH_HALT_VOTED,
.hwcg_reg = 0x38004,
.hwcg_bit = 1,
.clkr = {
.enable_reg = 0x52004,
.enable_mask = BIT(10),
.hw.init = &(struct clk_init_data){
.name = "gcc_boot_rom_ahb_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_mss_gpll0_div_clk_src = {
.halt_check = BRANCH_HALT_DELAY,
.clkr = {
.enable_reg = 0x5200c,
.enable_mask = BIT(2),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_gpll0_div_clk_src",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_blsp1_ahb_clk = {
.halt_reg = 0x17004,
.halt_check = BRANCH_HALT_VOTED,
@ -2832,6 +2898,11 @@ static struct clk_regmap *gcc_msm8998_clocks[] = {
[GCC_USB3_CLKREF_CLK] = &gcc_usb3_clkref_clk.clkr,
[GCC_PCIE_CLKREF_CLK] = &gcc_pcie_clkref_clk.clkr,
[GCC_RX1_USB2_CLKREF_CLK] = &gcc_rx1_usb2_clkref_clk.clkr,
[GCC_MSS_CFG_AHB_CLK] = &gcc_mss_cfg_ahb_clk.clkr,
[GCC_BOOT_ROM_AHB_CLK] = &gcc_boot_rom_ahb_clk.clkr,
[GCC_MSS_GPLL0_DIV_CLK_SRC] = &gcc_mss_gpll0_div_clk_src.clkr,
[GCC_MSS_SNOC_AXI_CLK] = &gcc_mss_snoc_axi_clk.clkr,
[GCC_MSS_MNOC_BIMC_AXI_CLK] = &gcc_mss_mnoc_bimc_axi_clk.clkr,
};
static struct gdsc *gcc_msm8998_gdscs[] = {
@ -2928,6 +2999,7 @@ static const struct qcom_reset_map gcc_msm8998_resets[] = {
[GCC_GPU_BCR] = { 0x71000 },
[GCC_SPSS_BCR] = { 0x72000 },
[GCC_OBT_ODT_BCR] = { 0x73000 },
[GCC_MSS_RESTART] = { 0x79000 },
[GCC_VS_BCR] = { 0x7a000 },
[GCC_MSS_VS_RESET] = { 0x7a100 },
[GCC_GPU_VS_RESET] = { 0x7a104 },

File diff suppressed because it is too large Load Diff

View File

@ -408,7 +408,7 @@ static const struct freq_tbl ftbl_gcc_qupv3_wrap0_s0_clk_src[] = {
{ }
};
static struct clk_init_data gcc_qupv3_wrap0_s0_clk_init = {
static struct clk_init_data gcc_qupv3_wrap0_s0_clk_src_init = {
.name = "gcc_qupv3_wrap0_s0_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -421,10 +421,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s0_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap0_s0_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s1_clk_init = {
static struct clk_init_data gcc_qupv3_wrap0_s1_clk_src_init = {
.name = "gcc_qupv3_wrap0_s1_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -437,10 +437,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s1_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap0_s1_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s2_clk_init = {
static struct clk_init_data gcc_qupv3_wrap0_s2_clk_src_init = {
.name = "gcc_qupv3_wrap0_s2_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -453,10 +453,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s2_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap0_s2_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s3_clk_init = {
static struct clk_init_data gcc_qupv3_wrap0_s3_clk_src_init = {
.name = "gcc_qupv3_wrap0_s3_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -469,10 +469,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s3_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap0_s3_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s4_clk_init = {
static struct clk_init_data gcc_qupv3_wrap0_s4_clk_src_init = {
.name = "gcc_qupv3_wrap0_s4_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -485,10 +485,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s4_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap0_s4_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s5_clk_init = {
static struct clk_init_data gcc_qupv3_wrap0_s5_clk_src_init = {
.name = "gcc_qupv3_wrap0_s5_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -501,10 +501,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s5_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap0_s5_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s6_clk_init = {
static struct clk_init_data gcc_qupv3_wrap0_s6_clk_src_init = {
.name = "gcc_qupv3_wrap0_s6_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -517,10 +517,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s6_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap0_s6_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap0_s7_clk_init = {
static struct clk_init_data gcc_qupv3_wrap0_s7_clk_src_init = {
.name = "gcc_qupv3_wrap0_s7_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -533,10 +533,10 @@ static struct clk_rcg2 gcc_qupv3_wrap0_s7_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap0_s7_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s0_clk_init = {
static struct clk_init_data gcc_qupv3_wrap1_s0_clk_src_init = {
.name = "gcc_qupv3_wrap1_s0_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -549,10 +549,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s0_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap1_s0_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s1_clk_init = {
static struct clk_init_data gcc_qupv3_wrap1_s1_clk_src_init = {
.name = "gcc_qupv3_wrap1_s1_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -565,10 +565,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s1_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap1_s1_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s2_clk_init = {
static struct clk_init_data gcc_qupv3_wrap1_s2_clk_src_init = {
.name = "gcc_qupv3_wrap1_s2_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -581,10 +581,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s2_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap1_s2_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s3_clk_init = {
static struct clk_init_data gcc_qupv3_wrap1_s3_clk_src_init = {
.name = "gcc_qupv3_wrap1_s3_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -597,10 +597,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s3_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap1_s3_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s4_clk_init = {
static struct clk_init_data gcc_qupv3_wrap1_s4_clk_src_init = {
.name = "gcc_qupv3_wrap1_s4_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -613,10 +613,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s4_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap1_s4_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s5_clk_init = {
static struct clk_init_data gcc_qupv3_wrap1_s5_clk_src_init = {
.name = "gcc_qupv3_wrap1_s5_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -629,10 +629,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s5_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap1_s5_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s6_clk_init = {
static struct clk_init_data gcc_qupv3_wrap1_s6_clk_src_init = {
.name = "gcc_qupv3_wrap1_s6_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -645,10 +645,10 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s6_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap1_s6_clk_src_init,
};
static struct clk_init_data gcc_qupv3_wrap1_s7_clk_init = {
static struct clk_init_data gcc_qupv3_wrap1_s7_clk_src_init = {
.name = "gcc_qupv3_wrap1_s7_clk_src",
.parent_names = gcc_parent_names_0,
.num_parents = 4,
@ -661,7 +661,7 @@ static struct clk_rcg2 gcc_qupv3_wrap1_s7_clk_src = {
.hid_width = 5,
.parent_map = gcc_parent_map_0,
.freq_tbl = ftbl_gcc_qupv3_wrap0_s0_clk_src,
.clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_init,
.clkr.hw.init = &gcc_qupv3_wrap1_s7_clk_src_init,
};
static const struct freq_tbl ftbl_gcc_sdcc2_apps_clk_src[] = {
@ -3577,22 +3577,22 @@ static const struct of_device_id gcc_sdm845_match_table[] = {
MODULE_DEVICE_TABLE(of, gcc_sdm845_match_table);
static const struct clk_rcg_dfs_data gcc_dfs_clocks[] = {
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s0_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s1_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s2_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s3_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s4_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s5_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s6_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap0_s7_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s0_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s1_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s2_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s3_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s4_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s5_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s6_clk_src),
DEFINE_RCG_DFS(gcc_qupv3_wrap1_s7_clk_src),
};
static int gcc_sdm845_probe(struct platform_device *pdev)

View File

@ -0,0 +1,338 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2019, Jeffrey Hugo
*/
#include <linux/kernel.h>
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>
#include <dt-bindings/clock/qcom,gpucc-msm8998.h>
#include "common.h"
#include "clk-regmap.h"
#include "clk-regmap-divider.h"
#include "clk-alpha-pll.h"
#include "clk-rcg.h"
#include "clk-branch.h"
#include "reset.h"
#include "gdsc.h"
enum {
P_XO,
P_GPLL0,
P_GPUPLL0_OUT_EVEN,
};
/* Instead of going directly to the block, XO is routed through this branch */
static struct clk_branch gpucc_cxo_clk = {
.halt_reg = 0x1020,
.clkr = {
.enable_reg = 0x1020,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gpucc_cxo_clk",
.parent_data = &(const struct clk_parent_data){
.fw_name = "xo",
.name = "xo"
},
.num_parents = 1,
.ops = &clk_branch2_ops,
.flags = CLK_IS_CRITICAL,
},
},
};
static const struct clk_div_table post_div_table_fabia_even[] = {
{ 0x0, 1 },
{ 0x1, 2 },
{ 0x3, 4 },
{ 0x7, 8 },
{ }
};
static struct clk_alpha_pll gpupll0 = {
.offset = 0x0,
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
.clkr.hw.init = &(struct clk_init_data){
.name = "gpupll0",
.parent_hws = (const struct clk_hw *[]){ &gpucc_cxo_clk.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_fixed_fabia_ops,
},
};
static struct clk_alpha_pll_postdiv gpupll0_out_even = {
.offset = 0x0,
.post_div_shift = 8,
.post_div_table = post_div_table_fabia_even,
.num_post_div = ARRAY_SIZE(post_div_table_fabia_even),
.width = 4,
.regs = clk_alpha_pll_regs[CLK_ALPHA_PLL_TYPE_FABIA],
.clkr.hw.init = &(struct clk_init_data){
.name = "gpupll0_out_even",
.parent_hws = (const struct clk_hw *[]){ &gpupll0.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_fabia_ops,
},
};
static const struct parent_map gpu_xo_gpll0_map[] = {
{ P_XO, 0 },
{ P_GPLL0, 5 },
};
static const struct clk_parent_data gpu_xo_gpll0[] = {
{ .hw = &gpucc_cxo_clk.clkr.hw },
{ .fw_name = "gpll0", .name = "gpll0" },
};
static const struct parent_map gpu_xo_gpupll0_map[] = {
{ P_XO, 0 },
{ P_GPUPLL0_OUT_EVEN, 1 },
};
static const struct clk_parent_data gpu_xo_gpupll0[] = {
{ .hw = &gpucc_cxo_clk.clkr.hw },
{ .hw = &gpupll0_out_even.clkr.hw },
};
static const struct freq_tbl ftbl_rbcpr_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(50000000, P_GPLL0, 12, 0, 0),
{ }
};
static struct clk_rcg2 rbcpr_clk_src = {
.cmd_rcgr = 0x1030,
.hid_width = 5,
.parent_map = gpu_xo_gpll0_map,
.freq_tbl = ftbl_rbcpr_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "rbcpr_clk_src",
.parent_data = gpu_xo_gpll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
},
};
static const struct freq_tbl ftbl_gfx3d_clk_src[] = {
{ .src = P_GPUPLL0_OUT_EVEN, .pre_div = 3 },
{ }
};
static struct clk_rcg2 gfx3d_clk_src = {
.cmd_rcgr = 0x1070,
.hid_width = 5,
.parent_map = gpu_xo_gpupll0_map,
.freq_tbl = ftbl_gfx3d_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "gfx3d_clk_src",
.parent_data = gpu_xo_gpupll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
.flags = CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE,
},
};
static const struct freq_tbl ftbl_rbbmtimer_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
{ }
};
static struct clk_rcg2 rbbmtimer_clk_src = {
.cmd_rcgr = 0x10b0,
.hid_width = 5,
.parent_map = gpu_xo_gpll0_map,
.freq_tbl = ftbl_rbbmtimer_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "rbbmtimer_clk_src",
.parent_data = gpu_xo_gpll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
},
};
static const struct freq_tbl ftbl_gfx3d_isense_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(40000000, P_GPLL0, 15, 0, 0),
F(200000000, P_GPLL0, 3, 0, 0),
F(300000000, P_GPLL0, 2, 0, 0),
{ }
};
static struct clk_rcg2 gfx3d_isense_clk_src = {
.cmd_rcgr = 0x1100,
.hid_width = 5,
.parent_map = gpu_xo_gpll0_map,
.freq_tbl = ftbl_gfx3d_isense_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "gfx3d_isense_clk_src",
.parent_data = gpu_xo_gpll0,
.num_parents = 2,
.ops = &clk_rcg2_ops,
},
};
static struct clk_branch rbcpr_clk = {
.halt_reg = 0x1054,
.clkr = {
.enable_reg = 0x1054,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "rbcpr_clk",
.parent_hws = (const struct clk_hw *[]){ &rbcpr_clk_src.clkr.hw },
.num_parents = 1,
.ops = &clk_branch2_ops,
.flags = CLK_SET_RATE_PARENT,
},
},
};
static struct clk_branch gfx3d_clk = {
.halt_reg = 0x1098,
.clkr = {
.enable_reg = 0x1098,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gfx3d_clk",
.parent_hws = (const struct clk_hw *[]){ &gfx3d_clk_src.clkr.hw },
.num_parents = 1,
.ops = &clk_branch2_ops,
.flags = CLK_SET_RATE_PARENT,
},
},
};
static struct clk_branch rbbmtimer_clk = {
.halt_reg = 0x10d0,
.clkr = {
.enable_reg = 0x10d0,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "rbbmtimer_clk",
.parent_hws = (const struct clk_hw *[]){ &rbbmtimer_clk_src.clkr.hw },
.num_parents = 1,
.ops = &clk_branch2_ops,
.flags = CLK_SET_RATE_PARENT,
},
},
};
static struct clk_branch gfx3d_isense_clk = {
.halt_reg = 0x1124,
.clkr = {
.enable_reg = 0x1124,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gfx3d_isense_clk",
.parent_hws = (const struct clk_hw *[]){ &gfx3d_isense_clk_src.clkr.hw },
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
static struct gdsc gpu_cx_gdsc = {
.gdscr = 0x1004,
.pd = {
.name = "gpu_cx",
},
.pwrsts = PWRSTS_OFF_ON,
};
static struct gdsc gpu_gx_gdsc = {
.gdscr = 0x1094,
.clamp_io_ctrl = 0x130,
.pd = {
.name = "gpu_gx",
},
.parent = &gpu_cx_gdsc.pd,
.pwrsts = PWRSTS_OFF_ON,
.flags = CLAMP_IO | AON_RESET,
};
static struct clk_regmap *gpucc_msm8998_clocks[] = {
[GPUPLL0] = &gpupll0.clkr,
[GPUPLL0_OUT_EVEN] = &gpupll0_out_even.clkr,
[RBCPR_CLK_SRC] = &rbcpr_clk_src.clkr,
[GFX3D_CLK_SRC] = &gfx3d_clk_src.clkr,
[RBBMTIMER_CLK_SRC] = &rbbmtimer_clk_src.clkr,
[GFX3D_ISENSE_CLK_SRC] = &gfx3d_isense_clk_src.clkr,
[RBCPR_CLK] = &rbcpr_clk.clkr,
[GFX3D_CLK] = &gfx3d_clk.clkr,
[RBBMTIMER_CLK] = &rbbmtimer_clk.clkr,
[GFX3D_ISENSE_CLK] = &gfx3d_isense_clk.clkr,
[GPUCC_CXO_CLK] = &gpucc_cxo_clk.clkr,
};
static struct gdsc *gpucc_msm8998_gdscs[] = {
[GPU_CX_GDSC] = &gpu_cx_gdsc,
[GPU_GX_GDSC] = &gpu_gx_gdsc,
};
static const struct qcom_reset_map gpucc_msm8998_resets[] = {
[GPU_CX_BCR] = { 0x1000 },
[RBCPR_BCR] = { 0x1050 },
[GPU_GX_BCR] = { 0x1090 },
[GPU_ISENSE_BCR] = { 0x1120 },
};
static const struct regmap_config gpucc_msm8998_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = 0x9000,
.fast_io = true,
};
static const struct qcom_cc_desc gpucc_msm8998_desc = {
.config = &gpucc_msm8998_regmap_config,
.clks = gpucc_msm8998_clocks,
.num_clks = ARRAY_SIZE(gpucc_msm8998_clocks),
.resets = gpucc_msm8998_resets,
.num_resets = ARRAY_SIZE(gpucc_msm8998_resets),
.gdscs = gpucc_msm8998_gdscs,
.num_gdscs = ARRAY_SIZE(gpucc_msm8998_gdscs),
};
static const struct of_device_id gpucc_msm8998_match_table[] = {
{ .compatible = "qcom,msm8998-gpucc" },
{ }
};
MODULE_DEVICE_TABLE(of, gpucc_msm8998_match_table);
static int gpucc_msm8998_probe(struct platform_device *pdev)
{
struct regmap *regmap;
regmap = qcom_cc_map(pdev, &gpucc_msm8998_desc);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
/* force periph logic on to avoid perf counter corruption */
regmap_write_bits(regmap, gfx3d_clk.clkr.enable_reg, BIT(13), BIT(13));
/* tweak droop detector (GPUCC_GPU_DD_WRAP_CTRL) to reduce leakage */
regmap_write_bits(regmap, gfx3d_clk.clkr.enable_reg, BIT(0), BIT(0));
return qcom_cc_really_probe(pdev, &gpucc_msm8998_desc, regmap);
}
static struct platform_driver gpucc_msm8998_driver = {
.probe = gpucc_msm8998_probe,
.driver = {
.name = "gpucc-msm8998",
.of_match_table = gpucc_msm8998_match_table,
},
};
module_platform_driver(gpucc_msm8998_driver);
MODULE_DESCRIPTION("QCOM GPUCC MSM8998 Driver");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,223 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/pm_clock.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,q6sstopcc-qcs404.h>
#include "clk-regmap.h"
#include "clk-branch.h"
#include "common.h"
#include "reset.h"
static struct clk_branch lcc_ahbfabric_cbc_clk = {
.halt_reg = 0x1b004,
.halt_check = BRANCH_HALT,
.clkr = {
.enable_reg = 0x1b004,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "lcc_ahbfabric_cbc_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch lcc_q6ss_ahbs_cbc_clk = {
.halt_reg = 0x22000,
.halt_check = BRANCH_VOTED,
.clkr = {
.enable_reg = 0x22000,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "lcc_q6ss_ahbs_cbc_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch lcc_q6ss_tcm_slave_cbc_clk = {
.halt_reg = 0x1c000,
.halt_check = BRANCH_VOTED,
.clkr = {
.enable_reg = 0x1c000,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "lcc_q6ss_tcm_slave_cbc_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch lcc_q6ss_ahbm_cbc_clk = {
.halt_reg = 0x22004,
.halt_check = BRANCH_VOTED,
.clkr = {
.enable_reg = 0x22004,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "lcc_q6ss_ahbm_cbc_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch lcc_q6ss_axim_cbc_clk = {
.halt_reg = 0x1c004,
.halt_check = BRANCH_VOTED,
.clkr = {
.enable_reg = 0x1c004,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "lcc_q6ss_axim_cbc_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch lcc_q6ss_bcr_sleep_clk = {
.halt_reg = 0x6004,
.halt_check = BRANCH_VOTED,
.clkr = {
.enable_reg = 0x6004,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "lcc_q6ss_bcr_sleep_clk",
.ops = &clk_branch2_ops,
},
},
};
/* TCSR clock */
static struct clk_branch tcsr_lcc_csr_cbcr_clk = {
.halt_reg = 0x8008,
.halt_check = BRANCH_VOTED,
.clkr = {
.enable_reg = 0x8008,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "tcsr_lcc_csr_cbcr_clk",
.ops = &clk_branch2_ops,
},
},
};
static struct regmap_config q6sstop_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.fast_io = true,
};
static struct clk_regmap *q6sstop_qcs404_clocks[] = {
[LCC_AHBFABRIC_CBC_CLK] = &lcc_ahbfabric_cbc_clk.clkr,
[LCC_Q6SS_AHBS_CBC_CLK] = &lcc_q6ss_ahbs_cbc_clk.clkr,
[LCC_Q6SS_TCM_SLAVE_CBC_CLK] = &lcc_q6ss_tcm_slave_cbc_clk.clkr,
[LCC_Q6SS_AHBM_CBC_CLK] = &lcc_q6ss_ahbm_cbc_clk.clkr,
[LCC_Q6SS_AXIM_CBC_CLK] = &lcc_q6ss_axim_cbc_clk.clkr,
[LCC_Q6SS_BCR_SLEEP_CLK] = &lcc_q6ss_bcr_sleep_clk.clkr,
};
static const struct qcom_reset_map q6sstop_qcs404_resets[] = {
[Q6SSTOP_BCR_RESET] = { 0x6000 },
};
static const struct qcom_cc_desc q6sstop_qcs404_desc = {
.config = &q6sstop_regmap_config,
.clks = q6sstop_qcs404_clocks,
.num_clks = ARRAY_SIZE(q6sstop_qcs404_clocks),
.resets = q6sstop_qcs404_resets,
.num_resets = ARRAY_SIZE(q6sstop_qcs404_resets),
};
static struct clk_regmap *tcsr_qcs404_clocks[] = {
[TCSR_Q6SS_LCC_CBCR_CLK] = &tcsr_lcc_csr_cbcr_clk.clkr,
};
static const struct qcom_cc_desc tcsr_qcs404_desc = {
.config = &q6sstop_regmap_config,
.clks = tcsr_qcs404_clocks,
.num_clks = ARRAY_SIZE(tcsr_qcs404_clocks),
};
static const struct of_device_id q6sstopcc_qcs404_match_table[] = {
{ .compatible = "qcom,qcs404-q6sstopcc" },
{ }
};
MODULE_DEVICE_TABLE(of, q6sstopcc_qcs404_match_table);
static int q6sstopcc_qcs404_probe(struct platform_device *pdev)
{
const struct qcom_cc_desc *desc;
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, NULL);
if (ret < 0) {
dev_err(&pdev->dev, "failed to acquire iface clock\n");
goto destroy_pm_clk;
}
q6sstop_regmap_config.name = "q6sstop_tcsr";
desc = &tcsr_qcs404_desc;
ret = qcom_cc_probe_by_index(pdev, 1, desc);
if (ret)
goto destroy_pm_clk;
q6sstop_regmap_config.name = "q6sstop_cc";
desc = &q6sstop_qcs404_desc;
ret = qcom_cc_probe_by_index(pdev, 0, desc);
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 int q6sstopcc_qcs404_remove(struct platform_device *pdev)
{
pm_clk_destroy(&pdev->dev);
pm_runtime_disable(&pdev->dev);
return 0;
}
static const struct dev_pm_ops q6sstopcc_pm_ops = {
SET_RUNTIME_PM_OPS(pm_clk_suspend, pm_clk_resume, NULL)
};
static struct platform_driver q6sstopcc_qcs404_driver = {
.probe = q6sstopcc_qcs404_probe,
.remove = q6sstopcc_qcs404_remove,
.driver = {
.name = "qcs404-q6sstopcc",
.of_match_table = q6sstopcc_qcs404_match_table,
.pm = &q6sstopcc_pm_ops,
},
};
module_platform_driver(q6sstopcc_qcs404_driver);
MODULE_DESCRIPTION("QTI QCS404 Q6SSTOP Clock Controller Driver");
MODULE_LICENSE("GPL v2");

View File

@ -60,8 +60,7 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np,
struct samsung_clk_provider *ctx;
int i;
ctx = kzalloc(sizeof(struct samsung_clk_provider) +
sizeof(*ctx->clk_data.hws) * nr_clks, GFP_KERNEL);
ctx = kzalloc(struct_size(ctx, clk_data.hws, nr_clks), GFP_KERNEL);
if (!ctx)
panic("could not allocate clock provider context.\n");

View File

@ -203,12 +203,21 @@ static struct ccu_nkmp pll_hsic_clk = {
* hardcode it to match with the clock names.
*/
#define SUN50I_H6_PLL_AUDIO_REG 0x078
static struct ccu_sdm_setting pll_audio_sdm_table[] = {
{ .rate = 541900800, .pattern = 0xc001288d, .m = 1, .n = 22 },
{ .rate = 589824000, .pattern = 0xc00126e9, .m = 1, .n = 24 },
};
static struct ccu_nm pll_audio_base_clk = {
.enable = BIT(31),
.lock = BIT(28),
.n = _SUNXI_CCU_MULT_MIN(8, 8, 12),
.m = _SUNXI_CCU_DIV(1, 1), /* input divider */
.sdm = _SUNXI_CCU_SDM(pll_audio_sdm_table,
BIT(24), 0x178, BIT(31)),
.common = {
.features = CCU_FEATURE_SIGMA_DELTA_MOD,
.reg = 0x078,
.hw.init = CLK_HW_INIT("pll-audio-base", "osc24M",
&ccu_nm_ops,
@ -290,7 +299,7 @@ static SUNXI_CCU_M_WITH_MUX_GATE(gpu_clk, "gpu", gpu_parents, 0x670,
0, 3, /* M */
24, 1, /* mux */
BIT(31), /* gate */
0);
CLK_SET_RATE_PARENT);
static SUNXI_CCU_GATE(bus_gpu_clk, "bus-gpu", "psi-ahb1-ahb2",
0x67c, BIT(0), 0);
@ -753,12 +762,12 @@ static const struct clk_hw *clk_parent_pll_audio[] = {
};
/*
* The divider of pll-audio is fixed to 8 now, as pll-audio-4x has a
* fixed post-divider 2.
* The divider of pll-audio is fixed to 24 for now, so 24576000 and 22579200
* rates can be set exactly in conjunction with sigma-delta modulation.
*/
static CLK_FIXED_FACTOR_HWS(pll_audio_clk, "pll-audio",
clk_parent_pll_audio,
8, 1, CLK_SET_RATE_PARENT);
24, 1, CLK_SET_RATE_PARENT);
static CLK_FIXED_FACTOR_HWS(pll_audio_2x_clk, "pll-audio-2x",
clk_parent_pll_audio,
4, 1, CLK_SET_RATE_PARENT);
@ -1215,12 +1224,12 @@ static int sun50i_h6_ccu_probe(struct platform_device *pdev)
}
/*
* Force the post-divider of pll-audio to 8 and the output divider
* of it to 1, to make the clock name represents the real frequency.
* Force the post-divider of pll-audio to 12 and the output divider
* of it to 2, so 24576000 and 22579200 rates can be set exactly.
*/
val = readl(reg + SUN50I_H6_PLL_AUDIO_REG);
val &= ~(GENMASK(21, 16) | BIT(0));
writel(val | (7 << 16), reg + SUN50I_H6_PLL_AUDIO_REG);
writel(val | (11 << 16) | BIT(0), reg + SUN50I_H6_PLL_AUDIO_REG);
/*
* First clock parent (osc32K) is unusable for CEC. But since there

View File

@ -48,10 +48,6 @@
/* Some more module clocks are exported */
#define CLK_MBUS 113
/* And the GPU module clock is exported */
#define CLK_NUMBER_H3 (CLK_GPU + 1)
#define CLK_NUMBER_H5 (CLK_BUS_SCR1 + 1)

View File

@ -194,15 +194,8 @@ static const char *ti_adpll_clk_get_name(struct ti_adpll_data *d,
if (err)
return NULL;
} else {
const char *base_name = "adpll";
char *buf;
buf = devm_kzalloc(d->dev, 8 + 1 + strlen(base_name) + 1 +
strlen(postfix), GFP_KERNEL);
if (!buf)
return NULL;
sprintf(buf, "%08lx.%s.%s", d->pa, base_name, postfix);
name = buf;
name = devm_kasprintf(d->dev, GFP_KERNEL, "%08lx.adpll.%s",
d->pa, postfix);
}
return name;

View File

@ -107,7 +107,7 @@ static const struct omap_clkctrl_reg_data am3_l4hs_clkctrl_regs[] __initconst =
};
static const struct omap_clkctrl_reg_data am3_pruss_ocp_clkctrl_regs[] __initconst = {
{ AM3_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" },
{ AM3_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "pruss_ocp_gclk" },
{ 0 },
};
@ -217,7 +217,7 @@ static const struct omap_clkctrl_reg_data am3_l4_rtc_clkctrl_regs[] __initconst
};
static const struct omap_clkctrl_reg_data am3_gfx_l3_clkctrl_regs[] __initconst = {
{ AM3_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" },
{ AM3_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "gfx_fck_div_ck" },
{ 0 },
};

View File

@ -73,7 +73,7 @@ static const struct omap_clkctrl_reg_data am4_mpu_clkctrl_regs[] __initconst = {
};
static const struct omap_clkctrl_reg_data am4_gfx_l3_clkctrl_regs[] __initconst = {
{ AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP, "gfx_fck_div_ck" },
{ AM4_GFX_L3_GFX_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "gfx_fck_div_ck" },
{ 0 },
};
@ -126,7 +126,7 @@ static const struct omap_clkctrl_reg_data am4_l3s_clkctrl_regs[] __initconst = {
};
static const struct omap_clkctrl_reg_data am4_pruss_ocp_clkctrl_regs[] __initconst = {
{ AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP, "pruss_ocp_gclk" },
{ AM4_PRUSS_OCP_PRUSS_CLKCTRL, NULL, CLKF_SW_SUP | CLKF_NO_IDLEST, "pruss_ocp_gclk" },
{ 0 },
};

View File

@ -37,7 +37,7 @@ static const struct omap_clkctrl_reg_data omap4_mpuss_clkctrl_regs[] __initconst
};
static const struct omap_clkctrl_reg_data omap4_tesla_clkctrl_regs[] __initconst = {
{ OMAP4_DSP_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_m4x2_ck" },
{ OMAP4_DSP_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_iva_m4x2_ck" },
{ 0 },
};
@ -219,7 +219,7 @@ static const struct omap_clkctrl_reg_data omap4_l3_2_clkctrl_regs[] __initconst
};
static const struct omap_clkctrl_reg_data omap4_ducati_clkctrl_regs[] __initconst = {
{ OMAP4_IPU_CLKCTRL, NULL, CLKF_HW_SUP, "ducati_clk_mux_ck" },
{ OMAP4_IPU_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "ducati_clk_mux_ck" },
{ 0 },
};

View File

@ -31,7 +31,7 @@ static const struct omap_clkctrl_reg_data omap5_mpu_clkctrl_regs[] __initconst =
};
static const struct omap_clkctrl_reg_data omap5_dsp_clkctrl_regs[] __initconst = {
{ OMAP5_MMU_DSP_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h11x2_ck" },
{ OMAP5_MMU_DSP_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_iva_h11x2_ck" },
{ 0 },
};
@ -145,7 +145,7 @@ static const struct omap_clkctrl_reg_data omap5_l3main2_clkctrl_regs[] __initcon
};
static const struct omap_clkctrl_reg_data omap5_ipu_clkctrl_regs[] __initconst = {
{ OMAP5_MMU_IPU_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h22x2_ck" },
{ OMAP5_MMU_IPU_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_core_h22x2_ck" },
{ 0 },
};
@ -286,6 +286,12 @@ static const struct omap_clkctrl_reg_data omap5_l4per_clkctrl_regs[] __initconst
{ 0 },
};
static const struct omap_clkctrl_reg_data omap5_iva_clkctrl_regs[] __initconst = {
{ OMAP5_IVA_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h12x2_ck" },
{ OMAP5_SL2IF_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_iva_h12x2_ck" },
{ 0 },
};
static const char * const omap5_dss_dss_clk_parents[] __initconst = {
"dpll_per_h12x2_ck",
NULL,
@ -502,6 +508,7 @@ const struct omap_clkctrl_data omap5_clkctrl_data[] __initconst = {
{ 0x4a008d20, omap5_l4cfg_clkctrl_regs },
{ 0x4a008e20, omap5_l3instr_clkctrl_regs },
{ 0x4a009020, omap5_l4per_clkctrl_regs },
{ 0x4a009220, omap5_iva_clkctrl_regs },
{ 0x4a009420, omap5_dss_clkctrl_regs },
{ 0x4a009520, omap5_gpu_clkctrl_regs },
{ 0x4a009620, omap5_l3init_clkctrl_regs },

View File

@ -25,7 +25,7 @@ static const struct omap_clkctrl_reg_data dra7_mpu_clkctrl_regs[] __initconst =
};
static const struct omap_clkctrl_reg_data dra7_dsp1_clkctrl_regs[] __initconst = {
{ DRA7_DSP1_MMU0_DSP1_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" },
{ DRA7_DSP1_MMU0_DSP1_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_dsp_m2_ck" },
{ 0 },
};
@ -41,7 +41,7 @@ static const struct omap_clkctrl_bit_data dra7_mmu_ipu1_bit_data[] __initconst =
};
static const struct omap_clkctrl_reg_data dra7_ipu1_clkctrl_regs[] __initconst = {
{ DRA7_IPU1_MMU_IPU1_CLKCTRL, dra7_mmu_ipu1_bit_data, CLKF_HW_SUP, "ipu1-clkctrl:0000:24" },
{ DRA7_IPU1_MMU_IPU1_CLKCTRL, dra7_mmu_ipu1_bit_data, CLKF_HW_SUP | CLKF_NO_IDLEST, "ipu1-clkctrl:0000:24" },
{ 0 },
};
@ -137,7 +137,7 @@ static const struct omap_clkctrl_reg_data dra7_ipu_clkctrl_regs[] __initconst =
};
static const struct omap_clkctrl_reg_data dra7_dsp2_clkctrl_regs[] __initconst = {
{ DRA7_DSP2_MMU0_DSP2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_dsp_m2_ck" },
{ DRA7_DSP2_MMU0_DSP2_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_dsp_m2_ck" },
{ 0 },
};
@ -164,7 +164,7 @@ static const struct omap_clkctrl_reg_data dra7_l3main1_clkctrl_regs[] __initcons
};
static const struct omap_clkctrl_reg_data dra7_ipu2_clkctrl_regs[] __initconst = {
{ DRA7_IPU2_MMU_IPU2_CLKCTRL, NULL, CLKF_HW_SUP, "dpll_core_h22x2_ck" },
{ DRA7_IPU2_MMU_IPU2_CLKCTRL, NULL, CLKF_HW_SUP | CLKF_NO_IDLEST, "dpll_core_h22x2_ck" },
{ 0 },
};

View File

@ -24,7 +24,7 @@
#include <linux/timekeeping.h>
#include "clock.h"
#define NO_IDLEST 0x1
#define NO_IDLEST 0
#define OMAP4_MODULEMODE_MASK 0x3
@ -34,6 +34,9 @@
#define OMAP4_IDLEST_MASK (0x3 << 16)
#define OMAP4_IDLEST_SHIFT 16
#define OMAP4_STBYST_MASK BIT(18)
#define OMAP4_STBYST_SHIFT 18
#define CLKCTRL_IDLEST_FUNCTIONAL 0x0
#define CLKCTRL_IDLEST_INTERFACE_IDLE 0x2
#define CLKCTRL_IDLEST_DISABLED 0x3
@ -158,7 +161,7 @@ static int _omap4_clkctrl_clk_enable(struct clk_hw *hw)
ti_clk_ll_ops->clk_writel(val, &clk->enable_reg);
if (clk->flags & NO_IDLEST)
if (test_bit(NO_IDLEST, &clk->flags))
return 0;
/* Wait until module is enabled */
@ -187,7 +190,7 @@ static void _omap4_clkctrl_clk_disable(struct clk_hw *hw)
ti_clk_ll_ops->clk_writel(val, &clk->enable_reg);
if (clk->flags & NO_IDLEST)
if (test_bit(NO_IDLEST, &clk->flags))
goto exit;
/* Wait until module is disabled */
@ -380,7 +383,7 @@ _ti_clkctrl_setup_div(struct omap_clkctrl_provider *provider,
if (ti_clk_parse_divider_data((int *)div_data->dividers, 0,
div_data->max_div, div_flags,
&div->width, &div->table)) {
div)) {
pr_err("%s: Data parsing for %pOF:%04x:%d failed\n", __func__,
node, offset, data->bit);
kfree(div);
@ -596,7 +599,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
if (reg_data->flags & CLKF_HW_SUP)
hw->enable_bit = MODULEMODE_HWCTRL;
if (reg_data->flags & CLKF_NO_IDLEST)
hw->flags |= NO_IDLEST;
set_bit(NO_IDLEST, &hw->flags);
if (reg_data->clkdm_name)
hw->clkdm_name = reg_data->clkdm_name;
@ -622,7 +625,7 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
init.ops = &omap4_clkctrl_clk_ops;
hw->hw.init = &init;
clk = ti_clk_register(NULL, &hw->hw, init.name);
clk = ti_clk_register_omap_hw(NULL, &hw->hw, init.name);
if (IS_ERR_OR_NULL(clk))
goto cleanup;
@ -647,3 +650,33 @@ static void __init _ti_omap4_clkctrl_setup(struct device_node *node)
}
CLK_OF_DECLARE(ti_omap4_clkctrl_clock, "ti,clkctrl",
_ti_omap4_clkctrl_setup);
/**
* ti_clk_is_in_standby - Check if clkctrl clock is in standby or not
* @clk: clock to check standby status for
*
* Finds whether the provided clock is in standby mode or not. Returns
* true if the provided clock is a clkctrl type clock and it is in standby,
* false otherwise.
*/
bool ti_clk_is_in_standby(struct clk *clk)
{
struct clk_hw *hw;
struct clk_hw_omap *hwclk;
u32 val;
hw = __clk_get_hw(clk);
if (!omap2_clk_is_hw_omap(hw))
return false;
hwclk = to_clk_hw_omap(hw);
val = ti_clk_ll_ops->clk_readl(&hwclk->enable_reg);
if (val & OMAP4_STBYST_MASK)
return true;
return false;
}
EXPORT_SYMBOL_GPL(ti_clk_is_in_standby);

View File

@ -20,9 +20,11 @@ struct clk_omap_divider {
struct clk_hw hw;
struct clk_omap_reg reg;
u8 shift;
u8 width;
u8 flags;
s8 latch;
u16 min;
u16 max;
u16 mask;
const struct clk_div_table *table;
u32 context;
};
@ -220,8 +222,7 @@ void ti_clk_latch(struct clk_omap_reg *reg, s8 shift);
struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup);
int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
u8 flags, u8 *width,
const struct clk_div_table **table);
u8 flags, struct clk_omap_divider *div);
int ti_clk_get_reg_addr(struct device_node *node, int index,
struct clk_omap_reg *reg);

View File

@ -26,30 +26,6 @@
#undef pr_fmt
#define pr_fmt(fmt) "%s: " fmt, __func__
#define div_mask(d) ((1 << ((d)->width)) - 1)
static unsigned int _get_table_maxdiv(const struct clk_div_table *table)
{
unsigned int maxdiv = 0;
const struct clk_div_table *clkt;
for (clkt = table; clkt->div; clkt++)
if (clkt->div > maxdiv)
maxdiv = clkt->div;
return maxdiv;
}
static unsigned int _get_maxdiv(struct clk_omap_divider *divider)
{
if (divider->flags & CLK_DIVIDER_ONE_BASED)
return div_mask(divider);
if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
return 1 << div_mask(divider);
if (divider->table)
return _get_table_maxdiv(divider->table);
return div_mask(divider) + 1;
}
static unsigned int _get_table_div(const struct clk_div_table *table,
unsigned int val)
{
@ -61,6 +37,34 @@ static unsigned int _get_table_div(const struct clk_div_table *table,
return 0;
}
static void _setup_mask(struct clk_omap_divider *divider)
{
u16 mask;
u32 max_val;
const struct clk_div_table *clkt;
if (divider->table) {
max_val = 0;
for (clkt = divider->table; clkt->div; clkt++)
if (clkt->val > max_val)
max_val = clkt->val;
} else {
max_val = divider->max;
if (!(divider->flags & CLK_DIVIDER_ONE_BASED) &&
!(divider->flags & CLK_DIVIDER_POWER_OF_TWO))
max_val--;
}
if (divider->flags & CLK_DIVIDER_POWER_OF_TWO)
mask = fls(max_val) - 1;
else
mask = max_val;
divider->mask = (1 << fls(mask)) - 1;
}
static unsigned int _get_div(struct clk_omap_divider *divider, unsigned int val)
{
if (divider->flags & CLK_DIVIDER_ONE_BASED)
@ -101,7 +105,7 @@ static unsigned long ti_clk_divider_recalc_rate(struct clk_hw *hw,
unsigned int div, val;
val = ti_clk_ll_ops->clk_readl(&divider->reg) >> divider->shift;
val &= div_mask(divider);
val &= divider->mask;
div = _get_div(divider, val);
if (!div) {
@ -180,7 +184,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
if (!rate)
rate = 1;
maxdiv = _get_maxdiv(divider);
maxdiv = divider->max;
if (!(clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT)) {
parent_rate = *best_parent_rate;
@ -219,7 +223,7 @@ static int ti_clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
}
if (!bestdiv) {
bestdiv = _get_maxdiv(divider);
bestdiv = divider->max;
*best_parent_rate =
clk_hw_round_rate(clk_hw_get_parent(hw), 1);
}
@ -249,17 +253,16 @@ static int ti_clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
divider = to_clk_omap_divider(hw);
div = DIV_ROUND_UP(parent_rate, rate);
if (div > divider->max)
div = divider->max;
if (div < divider->min)
div = divider->min;
value = _get_val(divider, div);
if (value > div_mask(divider))
value = div_mask(divider);
if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
val = div_mask(divider) << (divider->shift + 16);
} else {
val = ti_clk_ll_ops->clk_readl(&divider->reg);
val &= ~(div_mask(divider) << divider->shift);
}
val = ti_clk_ll_ops->clk_readl(&divider->reg);
val &= ~(divider->mask << divider->shift);
val |= value << divider->shift;
ti_clk_ll_ops->clk_writel(val, &divider->reg);
@ -280,7 +283,7 @@ static int clk_divider_save_context(struct clk_hw *hw)
u32 val;
val = ti_clk_ll_ops->clk_readl(&divider->reg) >> divider->shift;
divider->context = val & div_mask(divider);
divider->context = val & divider->mask;
return 0;
}
@ -297,7 +300,7 @@ static void clk_divider_restore_context(struct clk_hw *hw)
u32 val;
val = ti_clk_ll_ops->clk_readl(&divider->reg);
val &= ~(div_mask(divider) << divider->shift);
val &= ~(divider->mask << divider->shift);
val |= divider->context << divider->shift;
ti_clk_ll_ops->clk_writel(val, &divider->reg);
}
@ -310,47 +313,26 @@ const struct clk_ops ti_clk_divider_ops = {
.restore_context = clk_divider_restore_context,
};
static struct clk *_register_divider(struct device *dev, const char *name,
const char *parent_name,
unsigned long flags,
struct clk_omap_reg *reg,
u8 shift, u8 width, s8 latch,
u8 clk_divider_flags,
const struct clk_div_table *table)
static struct clk *_register_divider(struct device_node *node,
u32 flags,
struct clk_omap_divider *div)
{
struct clk_omap_divider *div;
struct clk *clk;
struct clk_init_data init;
const char *parent_name;
if (clk_divider_flags & CLK_DIVIDER_HIWORD_MASK) {
if (width + shift > 16) {
pr_warn("divider value exceeds LOWORD field\n");
return ERR_PTR(-EINVAL);
}
}
parent_name = of_clk_get_parent_name(node, 0);
/* allocate the divider */
div = kzalloc(sizeof(*div), GFP_KERNEL);
if (!div)
return ERR_PTR(-ENOMEM);
init.name = name;
init.name = node->name;
init.ops = &ti_clk_divider_ops;
init.flags = flags;
init.parent_names = (parent_name ? &parent_name : NULL);
init.num_parents = (parent_name ? 1 : 0);
/* struct clk_divider assignments */
memcpy(&div->reg, reg, sizeof(*reg));
div->shift = shift;
div->width = width;
div->latch = latch;
div->flags = clk_divider_flags;
div->hw.init = &init;
div->table = table;
/* register the clock */
clk = ti_clk_register(dev, &div->hw, name);
clk = ti_clk_register(NULL, &div->hw, node->name);
if (IS_ERR(clk))
kfree(div);
@ -359,34 +341,17 @@ static struct clk *_register_divider(struct device *dev, const char *name,
}
int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
u8 flags, u8 *width,
const struct clk_div_table **table)
u8 flags, struct clk_omap_divider *divider)
{
int valid_div = 0;
u32 val;
int div;
int i;
struct clk_div_table *tmp;
u16 min_div = 0;
if (!div_table) {
if (flags & CLKF_INDEX_STARTS_AT_ONE)
val = 1;
else
val = 0;
div = 1;
while (div < max_div) {
if (flags & CLKF_INDEX_POWER_OF_TWO)
div <<= 1;
else
div++;
val++;
}
*width = fls(val);
*table = NULL;
divider->min = 1;
divider->max = max_div;
_setup_mask(divider);
return 0;
}
@ -403,30 +368,32 @@ int ti_clk_parse_divider_data(int *div_table, int num_dividers, int max_div,
num_dividers = i;
tmp = kcalloc(valid_div + 1, sizeof(*tmp), GFP_KERNEL);
if (!tmp) {
*table = ERR_PTR(-ENOMEM);
if (!tmp)
return -ENOMEM;
}
valid_div = 0;
*width = 0;
for (i = 0; i < num_dividers; i++)
if (div_table[i] > 0) {
tmp[valid_div].div = div_table[i];
tmp[valid_div].val = i;
valid_div++;
*width = i;
if (div_table[i] > max_div)
max_div = div_table[i];
if (!min_div || div_table[i] < min_div)
min_div = div_table[i];
}
*width = fls(*width);
*table = tmp;
divider->min = min_div;
divider->max = max_div;
divider->table = tmp;
_setup_mask(divider);
return 0;
}
static struct clk_div_table *
__init ti_clk_get_div_table(struct device_node *node)
static int __init ti_clk_get_div_table(struct device_node *node,
struct clk_omap_divider *div)
{
struct clk_div_table *table;
const __be32 *divspec;
@ -438,7 +405,7 @@ __init ti_clk_get_div_table(struct device_node *node)
divspec = of_get_property(node, "ti,dividers", &num_div);
if (!divspec)
return NULL;
return 0;
num_div /= 4;
@ -453,13 +420,12 @@ __init ti_clk_get_div_table(struct device_node *node)
if (!valid_div) {
pr_err("no valid dividers for %pOFn table\n", node);
return ERR_PTR(-EINVAL);
return -EINVAL;
}
table = kcalloc(valid_div + 1, sizeof(*table), GFP_KERNEL);
if (!table)
return ERR_PTR(-ENOMEM);
return -ENOMEM;
valid_div = 0;
@ -472,19 +438,20 @@ __init ti_clk_get_div_table(struct device_node *node)
}
}
return table;
div->table = table;
return 0;
}
static int _get_divider_width(struct device_node *node,
const struct clk_div_table *table,
u8 flags)
static int _populate_divider_min_max(struct device_node *node,
struct clk_omap_divider *divider)
{
u32 min_div;
u32 max_div;
u32 val = 0;
u32 div;
u32 min_div = 0;
u32 max_div = 0;
u32 val;
const struct clk_div_table *clkt;
if (!table) {
if (!divider->table) {
/* Clk divider table not provided, determine min/max divs */
if (of_property_read_u32(node, "ti,min-div", &min_div))
min_div = 1;
@ -493,75 +460,62 @@ static int _get_divider_width(struct device_node *node,
pr_err("no max-div for %pOFn!\n", node);
return -EINVAL;
}
/* Determine bit width for the field */
if (flags & CLK_DIVIDER_ONE_BASED)
val = 1;
div = min_div;
while (div < max_div) {
if (flags & CLK_DIVIDER_POWER_OF_TWO)
div <<= 1;
else
div++;
val++;
}
} else {
div = 0;
while (table[div].div) {
val = table[div].val;
div++;
for (clkt = divider->table; clkt->div; clkt++) {
val = clkt->div;
if (val > max_div)
max_div = val;
if (!min_div || val < min_div)
min_div = val;
}
}
return fls(val);
divider->min = min_div;
divider->max = max_div;
_setup_mask(divider);
return 0;
}
static int __init ti_clk_divider_populate(struct device_node *node,
struct clk_omap_reg *reg, const struct clk_div_table **table,
u32 *flags, u8 *div_flags, u8 *width, u8 *shift, s8 *latch)
struct clk_omap_divider *div,
u32 *flags)
{
u32 val;
int ret;
ret = ti_clk_get_reg_addr(node, 0, reg);
ret = ti_clk_get_reg_addr(node, 0, &div->reg);
if (ret)
return ret;
if (!of_property_read_u32(node, "ti,bit-shift", &val))
*shift = val;
div->shift = val;
else
*shift = 0;
div->shift = 0;
if (latch) {
if (!of_property_read_u32(node, "ti,latch-bit", &val))
*latch = val;
else
*latch = -EINVAL;
}
if (!of_property_read_u32(node, "ti,latch-bit", &val))
div->latch = val;
else
div->latch = -EINVAL;
*flags = 0;
*div_flags = 0;
div->flags = 0;
if (of_property_read_bool(node, "ti,index-starts-at-one"))
*div_flags |= CLK_DIVIDER_ONE_BASED;
div->flags |= CLK_DIVIDER_ONE_BASED;
if (of_property_read_bool(node, "ti,index-power-of-two"))
*div_flags |= CLK_DIVIDER_POWER_OF_TWO;
div->flags |= CLK_DIVIDER_POWER_OF_TWO;
if (of_property_read_bool(node, "ti,set-rate-parent"))
*flags |= CLK_SET_RATE_PARENT;
*table = ti_clk_get_div_table(node);
ret = ti_clk_get_div_table(node, div);
if (ret)
return ret;
if (IS_ERR(*table))
return PTR_ERR(*table);
*width = _get_divider_width(node, *table, *div_flags);
return 0;
return _populate_divider_min_max(node, div);
}
/**
@ -573,24 +527,17 @@ static int __init ti_clk_divider_populate(struct device_node *node,
static void __init of_ti_divider_clk_setup(struct device_node *node)
{
struct clk *clk;
const char *parent_name;
struct clk_omap_reg reg;
u8 clk_divider_flags = 0;
u8 width = 0;
u8 shift = 0;
s8 latch = -EINVAL;
const struct clk_div_table *table = NULL;
u32 flags = 0;
struct clk_omap_divider *div;
parent_name = of_clk_get_parent_name(node, 0);
div = kzalloc(sizeof(*div), GFP_KERNEL);
if (!div)
return;
if (ti_clk_divider_populate(node, &reg, &table, &flags,
&clk_divider_flags, &width, &shift, &latch))
if (ti_clk_divider_populate(node, div, &flags))
goto cleanup;
clk = _register_divider(NULL, node->name, parent_name, flags, &reg,
shift, width, latch, clk_divider_flags, table);
clk = _register_divider(node, flags, div);
if (!IS_ERR(clk)) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
of_ti_clk_autoidle_setup(node);
@ -598,22 +545,21 @@ static void __init of_ti_divider_clk_setup(struct device_node *node)
}
cleanup:
kfree(table);
kfree(div->table);
kfree(div);
}
CLK_OF_DECLARE(divider_clk, "ti,divider-clock", of_ti_divider_clk_setup);
static void __init of_ti_composite_divider_clk_setup(struct device_node *node)
{
struct clk_omap_divider *div;
u32 val;
u32 tmp;
div = kzalloc(sizeof(*div), GFP_KERNEL);
if (!div)
return;
if (ti_clk_divider_populate(node, &div->reg, &div->table, &val,
&div->flags, &div->width, &div->shift,
NULL) < 0)
if (ti_clk_divider_populate(node, div, &tmp))
goto cleanup;
if (!ti_clk_add_component(node, &div->hw, CLK_COMPONENT_TYPE_DIVIDER))

View File

@ -64,8 +64,7 @@ static int uniphier_clk_probe(struct platform_device *pdev)
for (p = data; p->name; p++)
clk_num = max(clk_num, p->idx + 1);
hw_data = devm_kzalloc(dev,
sizeof(*hw_data) + clk_num * sizeof(struct clk_hw *),
hw_data = devm_kzalloc(dev, struct_size(hw_data, hws, clk_num),
GFP_KERNEL);
if (!hw_data)
return -ENOMEM;

View File

@ -39,6 +39,8 @@
#define ASPEED_CLK_BCLK 33
#define ASPEED_CLK_MPLL 34
#define ASPEED_CLK_24M 35
#define ASPEED_CLK_MAC1RCLK 36
#define ASPEED_CLK_MAC2RCLK 37
#define ASPEED_RESET_XDMA 0
#define ASPEED_RESET_MCTP 1

View File

@ -83,6 +83,10 @@
#define ASPEED_CLK_MAC12 64
#define ASPEED_CLK_MAC34 65
#define ASPEED_CLK_USBPHY_40M 66
#define ASPEED_CLK_MAC1RCLK 67
#define ASPEED_CLK_MAC2RCLK 68
#define ASPEED_CLK_MAC3RCLK 69
#define ASPEED_CLK_MAC4RCLK 70
/* Only list resets here that are not part of a gate */
#define ASPEED_RESET_ADC 55

View File

@ -86,6 +86,10 @@
#define OMAP5_UART5_CLKCTRL OMAP5_CLKCTRL_INDEX(0x170)
#define OMAP5_UART6_CLKCTRL OMAP5_CLKCTRL_INDEX(0x178)
/* iva clocks */
#define OMAP5_IVA_CLKCTRL OMAP5_CLKCTRL_INDEX(0x20)
#define OMAP5_SL2IF_CLKCTRL OMAP5_CLKCTRL_INDEX(0x28)
/* dss clocks */
#define OMAP5_DSS_CORE_CLKCTRL OMAP5_CLKCTRL_INDEX(0x20)

View File

@ -177,6 +177,11 @@
#define GCC_UFS_CLKREF_CLK 168
#define GCC_PCIE_CLKREF_CLK 169
#define GCC_RX1_USB2_CLKREF_CLK 170
#define GCC_MSS_CFG_AHB_CLK 171
#define GCC_BOOT_ROM_AHB_CLK 172
#define GCC_MSS_GPLL0_DIV_CLK_SRC 173
#define GCC_MSS_SNOC_AXI_CLK 174
#define GCC_MSS_MNOC_BIMC_AXI_CLK 175
#define PCIE_0_GDSC 0
#define UFS_GDSC 1
@ -290,5 +295,6 @@
#define GCC_MSMPU_BCR 105
#define GCC_QUSB2PHY_PRIM_BCR 106
#define GCC_QUSB2PHY_SEC_BCR 107
#define GCC_MSS_RESTART 108
#endif

View File

@ -0,0 +1,155 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
*/
#ifndef _DT_BINDINGS_CLK_QCOM_GCC_SC7180_H
#define _DT_BINDINGS_CLK_QCOM_GCC_SC7180_H
/* GCC clocks */
#define GCC_GPLL0_MAIN_DIV_CDIV 0
#define GPLL0 1
#define GPLL0_OUT_EVEN 2
#define GPLL1 3
#define GPLL4 4
#define GPLL6 5
#define GPLL7 6
#define GCC_AGGRE_UFS_PHY_AXI_CLK 7
#define GCC_AGGRE_USB3_PRIM_AXI_CLK 8
#define GCC_BOOT_ROM_AHB_CLK 9
#define GCC_CAMERA_AHB_CLK 10
#define GCC_CAMERA_HF_AXI_CLK 11
#define GCC_CAMERA_THROTTLE_HF_AXI_CLK 12
#define GCC_CAMERA_XO_CLK 13
#define GCC_CE1_AHB_CLK 14
#define GCC_CE1_AXI_CLK 15
#define GCC_CE1_CLK 16
#define GCC_CFG_NOC_USB3_PRIM_AXI_CLK 17
#define GCC_CPUSS_AHB_CLK 18
#define GCC_CPUSS_AHB_CLK_SRC 19
#define GCC_CPUSS_GNOC_CLK 20
#define GCC_CPUSS_RBCPR_CLK 21
#define GCC_DDRSS_GPU_AXI_CLK 22
#define GCC_DISP_AHB_CLK 23
#define GCC_DISP_GPLL0_CLK_SRC 24
#define GCC_DISP_GPLL0_DIV_CLK_SRC 25
#define GCC_DISP_HF_AXI_CLK 26
#define GCC_DISP_THROTTLE_HF_AXI_CLK 27
#define GCC_DISP_XO_CLK 28
#define GCC_GP1_CLK 29
#define GCC_GP1_CLK_SRC 30
#define GCC_GP2_CLK 31
#define GCC_GP2_CLK_SRC 32
#define GCC_GP3_CLK 33
#define GCC_GP3_CLK_SRC 34
#define GCC_GPU_CFG_AHB_CLK 35
#define GCC_GPU_GPLL0_CLK_SRC 36
#define GCC_GPU_GPLL0_DIV_CLK_SRC 37
#define GCC_GPU_MEMNOC_GFX_CLK 38
#define GCC_GPU_SNOC_DVM_GFX_CLK 39
#define GCC_NPU_AXI_CLK 40
#define GCC_NPU_BWMON_AXI_CLK 41
#define GCC_NPU_BWMON_DMA_CFG_AHB_CLK 42
#define GCC_NPU_BWMON_DSP_CFG_AHB_CLK 43
#define GCC_NPU_CFG_AHB_CLK 44
#define GCC_NPU_DMA_CLK 45
#define GCC_NPU_GPLL0_CLK_SRC 46
#define GCC_NPU_GPLL0_DIV_CLK_SRC 47
#define GCC_PDM2_CLK 48
#define GCC_PDM2_CLK_SRC 49
#define GCC_PDM_AHB_CLK 50
#define GCC_PDM_XO4_CLK 51
#define GCC_PRNG_AHB_CLK 52
#define GCC_QSPI_CNOC_PERIPH_AHB_CLK 53
#define GCC_QSPI_CORE_CLK 54
#define GCC_QSPI_CORE_CLK_SRC 55
#define GCC_QUPV3_WRAP0_CORE_2X_CLK 56
#define GCC_QUPV3_WRAP0_CORE_CLK 57
#define GCC_QUPV3_WRAP0_S0_CLK 58
#define GCC_QUPV3_WRAP0_S0_CLK_SRC 59
#define GCC_QUPV3_WRAP0_S1_CLK 60
#define GCC_QUPV3_WRAP0_S1_CLK_SRC 61
#define GCC_QUPV3_WRAP0_S2_CLK 62
#define GCC_QUPV3_WRAP0_S2_CLK_SRC 63
#define GCC_QUPV3_WRAP0_S3_CLK 64
#define GCC_QUPV3_WRAP0_S3_CLK_SRC 65
#define GCC_QUPV3_WRAP0_S4_CLK 66
#define GCC_QUPV3_WRAP0_S4_CLK_SRC 67
#define GCC_QUPV3_WRAP0_S5_CLK 68
#define GCC_QUPV3_WRAP0_S5_CLK_SRC 69
#define GCC_QUPV3_WRAP1_CORE_2X_CLK 70
#define GCC_QUPV3_WRAP1_CORE_CLK 71
#define GCC_QUPV3_WRAP1_S0_CLK 72
#define GCC_QUPV3_WRAP1_S0_CLK_SRC 73
#define GCC_QUPV3_WRAP1_S1_CLK 74
#define GCC_QUPV3_WRAP1_S1_CLK_SRC 75
#define GCC_QUPV3_WRAP1_S2_CLK 76
#define GCC_QUPV3_WRAP1_S2_CLK_SRC 77
#define GCC_QUPV3_WRAP1_S3_CLK 78
#define GCC_QUPV3_WRAP1_S3_CLK_SRC 79
#define GCC_QUPV3_WRAP1_S4_CLK 80
#define GCC_QUPV3_WRAP1_S4_CLK_SRC 81
#define GCC_QUPV3_WRAP1_S5_CLK 82
#define GCC_QUPV3_WRAP1_S5_CLK_SRC 83
#define GCC_QUPV3_WRAP_0_M_AHB_CLK 84
#define GCC_QUPV3_WRAP_0_S_AHB_CLK 85
#define GCC_QUPV3_WRAP_1_M_AHB_CLK 86
#define GCC_QUPV3_WRAP_1_S_AHB_CLK 87
#define GCC_SDCC1_AHB_CLK 88
#define GCC_SDCC1_APPS_CLK 89
#define GCC_SDCC1_APPS_CLK_SRC 90
#define GCC_SDCC1_ICE_CORE_CLK 91
#define GCC_SDCC1_ICE_CORE_CLK_SRC 92
#define GCC_SDCC2_AHB_CLK 93
#define GCC_SDCC2_APPS_CLK 94
#define GCC_SDCC2_APPS_CLK_SRC 95
#define GCC_SYS_NOC_CPUSS_AHB_CLK 96
#define GCC_UFS_MEM_CLKREF_CLK 97
#define GCC_UFS_PHY_AHB_CLK 98
#define GCC_UFS_PHY_AXI_CLK 99
#define GCC_UFS_PHY_AXI_CLK_SRC 100
#define GCC_UFS_PHY_ICE_CORE_CLK 101
#define GCC_UFS_PHY_ICE_CORE_CLK_SRC 102
#define GCC_UFS_PHY_PHY_AUX_CLK 103
#define GCC_UFS_PHY_PHY_AUX_CLK_SRC 104
#define GCC_UFS_PHY_RX_SYMBOL_0_CLK 105
#define GCC_UFS_PHY_TX_SYMBOL_0_CLK 106
#define GCC_UFS_PHY_UNIPRO_CORE_CLK 107
#define GCC_UFS_PHY_UNIPRO_CORE_CLK_SRC 108
#define GCC_USB30_PRIM_MASTER_CLK 109
#define GCC_USB30_PRIM_MASTER_CLK_SRC 110
#define GCC_USB30_PRIM_MOCK_UTMI_CLK 111
#define GCC_USB30_PRIM_MOCK_UTMI_CLK_SRC 112
#define GCC_USB30_PRIM_SLEEP_CLK 113
#define GCC_USB3_PRIM_CLKREF_CLK 114
#define GCC_USB3_PRIM_PHY_AUX_CLK 115
#define GCC_USB3_PRIM_PHY_AUX_CLK_SRC 116
#define GCC_USB3_PRIM_PHY_COM_AUX_CLK 117
#define GCC_USB3_PRIM_PHY_PIPE_CLK 118
#define GCC_USB_PHY_CFG_AHB2PHY_CLK 119
#define GCC_VIDEO_AHB_CLK 120
#define GCC_VIDEO_AXI_CLK 121
#define GCC_VIDEO_GPLL0_DIV_CLK_SRC 122
#define GCC_VIDEO_THROTTLE_AXI_CLK 123
#define GCC_VIDEO_XO_CLK 124
/* GCC resets */
#define GCC_QUSB2PHY_PRIM_BCR 0
#define GCC_QUSB2PHY_SEC_BCR 1
#define GCC_UFS_PHY_BCR 2
#define GCC_USB30_PRIM_BCR 3
#define GCC_USB3_DP_PHY_PRIM_BCR 4
#define GCC_USB3_DP_PHY_SEC_BCR 5
#define GCC_USB3_PHY_PRIM_BCR 6
#define GCC_USB3_PHY_SEC_BCR 7
#define GCC_USB3PHY_PHY_PRIM_BCR 8
#define GCC_USB3PHY_PHY_SEC_BCR 9
#define GCC_USB_PHY_CFG_AHB2PHY_BCR 10
/* GCC GDSCRs */
#define UFS_PHY_GDSC 0
#define USB30_PRIM_GDSC 1
#define HLOS1_VOTE_MMNOC_MMU_TBU_HF0_GDSC 2
#define HLOS1_VOTE_MMNOC_MMU_TBU_SF_GDSC 3
#endif

View File

@ -0,0 +1,18 @@
/* SPDX-License-Identifier: GPL-2.0 */
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
*/
#ifndef _DT_BINDINGS_CLK_Q6SSTOP_QCS404_H
#define _DT_BINDINGS_CLK_Q6SSTOP_QCS404_H
#define LCC_AHBFABRIC_CBC_CLK 0
#define LCC_Q6SS_AHBS_CBC_CLK 1
#define LCC_Q6SS_TCM_SLAVE_CBC_CLK 2
#define LCC_Q6SS_AHBM_CBC_CLK 3
#define LCC_Q6SS_AXIM_CBC_CLK 4
#define LCC_Q6SS_BCR_SLEEP_CLK 5
#define TCSR_Q6SS_LCC_CBCR_CLK 6
#define Q6SSTOP_BCR_RESET 1
#endif

View File

@ -143,7 +143,7 @@
#define CLK_AVS 110
#define CLK_HDMI 111
#define CLK_HDMI_DDC 112
#define CLK_MBUS 113
#define CLK_GPU 114
/* New clocks imported in H5 */

View File

@ -153,7 +153,7 @@ struct clk_hw_omap {
u8 fixed_div;
struct clk_omap_reg enable_reg;
u8 enable_bit;
u8 flags;
unsigned long flags;
struct clk_omap_reg clksel_reg;
struct dpll_data *dpll_data;
const char *clkdm_name;
@ -298,6 +298,7 @@ struct ti_clk_features {
void ti_clk_setup_features(struct ti_clk_features *features);
const struct ti_clk_features *ti_clk_get_features(void);
bool ti_clk_is_in_standby(struct clk *clk);
int omap3_noncore_dpll_save_context(struct clk_hw *hw);
void omap3_noncore_dpll_restore_context(struct clk_hw *hw);