Herein lies a smallish collection of clk driver updates and some core

clk framework changes for the merge window. The core framework changes
 are only improving the debugfs interface to allow phase adjustments and
 report which consumers of a clk there are. These are most likely only of
 interest to kernel developers.
 
 On the clk driver side, it's a ghastly amount of updates with only a
 handful of new clk drivers. We have a couple new clk drivers for
 Qualcomm, per usual, and a driver for Renesas, Amlogic, and TI
 respectively. The updates are spread throughout the clk drivers. Some
 highlights are fixing kunit tests for different configurations like
 lockdep and big-endian, avoiding integer overflow in rate settable clks,
 moving clk_hw_onecell_data to the end of allocations so that drivers
 don't corrupt their private data, and migrating clk drivers to the
 regmap maple tree. Otherwise it's the usual fixes to clk drivers that
 only come along with testing the drivers on real hardware.
 
 New Drivers:
  - Add clock driver for TWL6032
  - Initial support for the Qualcomm SM4450 Global Clock Controller and
    SM4450 RPMh clock controllers
  - Add Camera Clock Controller on Qualcomm SM8550
  - Add support for the Renesas RZ/G3S (R9A08G045) SoC
  - Add Amlogic s4 main clock controller support
 
 Updates:
  - Make clk kunit tests work with lockdep
  - Fix clk gate kunit test for big-endian
  - Convert more than a handful of clk drivers to use regmap maple tree
  - Consider the CLK_FRAC_DIVIDER_ZERO_BASED in fractional divider clk
    implementation
  - Add consumer info to clk debugfs
  - Fix various clk drivers that have clk_hw_onecell_data not at the end
    of an allocation
  - Drop CLK_SET_RATE_PARENT for clocks with fixed-rate GPLLs across a
    variety of Qualcomm IPQ platforms
  - Add missing parent of APCS PLL on Qualcomm IPQ6018
  - Add I2C QUP6 clk on Qualcomm IPQ6018 but mark it critical to avoid
    problems with RPM
  - Implement safe source switching for a53pll and use on Qualcomm
    IPQ5332
  - Add support for Stromer Plus PLLs to Qualcomm clk driver
  - Switch Qualcomm SM8550 Video and GPU clock controllers to use OLE PLL
    configure method
  - Non critical fixes to halt bit checks in Qualcomm clk drivers
  - Add SMMU GDSC for Qualcomm MSM8998
  - Fix possible integer overflow in Qualcomm RCG frequency calculation
    code
  - Remove RPM managed clks from Qualcomm MSM8996 GCC driver
  - Add HFPLL configuration for the three HFPLLs in Qualcomm MSM8976
  - Switch Qualcomm MSM8996 CBF clock driver's remove function to return
    void
  - Fix missing dependency for s4 clock controllers
  - Select MXC_CLK when building in the CLK_IMX8QXP
  - Fixes for error handling paths in i.MX8 ACM driver
  - Move the clocks check in i.MX8 ACM driver in order to log any error
  - Drop the unused return value of clk_imx_acm_detach_pm_domains
  - Drop non-existant IMX8MP_CLK_AUDIOMIX_PDM_ROOT clock
  - Fix error handling in i.MX8MQ clock driver
  - Allow a different LCDIF1 clock parent if DT describes it for i.MX6SX
  - Keep the SCU resource table sorted in the i.MX8DXL rsrc driver
  - Move the elcdif PLL clock registration above lcd_clk, as it is its
    parent
  - Correct some ENET specific clocks for i.MX8DXL platform
  - Drop the VPU_UART and VPUCORE from i.MX8QM as latest HW revision
    doesn't have them
  - Remove "de-featured" MLB support from i.MX8QM/QXP/DXL platforms
  - Skip registering clocks owned by Cortex-A partition SCU-based
    platforms
  - Add CAN_1/2 to i.MX8QM and M4_0, PI_0_PWM_0 and PI_0_I2C_0 to
    i.MX8QXP resources
 -----BEGIN PGP SIGNATURE-----
 
 iQJFBAABCAAvFiEE9L57QeeUxqYDyoaDrQKIl8bklSUFAmVBac4RHHNib3lkQGtl
 cm5lbC5vcmcACgkQrQKIl8bklSUFvg//RG8n63D7wCnCX8AONmbvUzkuF5F3plX7
 1oNbHShAWV1ifu5OSaNW06MHw9UP0YD8HogfniWtVC+AmtC0WxS297+TeIlAwobV
 fs8XpHpTHiQlHbc4Me1p8Q2QkZRRLoZh1+QLK+J1tiVfh3IBOQ64CyQC/bC0S40B
 S470uPcB3duR1fv2IN4EgEojh9b1re2Z1KtqPYQQ+dmB9FifaCL0aF4QPGeG89IK
 LYub+OnPdtrOsSxuJSTyck+PLBM2Tr1ikgyEPyo5m/YoJIOI8V/IpB0aIgfbtJL/
 xAha95iY2kRLjS2hNWwXLDHXr3g7MG9cuIPUm7qApmrQutmlpf1nXg2GkCeHaLd+
 DYtk9qwGObmtBTLzNfezamjaFSQngB0xbhP3dqcvqwmZ7j2voFRKLRUKD5+xWnOl
 67yneGSsPRjDJNdgAtONfr/8KU6aRgHJxSILmj+VjfEbYY8BHq1hFgSnHB54l/vq
 1RtJxep64vejbhteg2lZFCWLQLHiTETBy+pALhfLG1GKhI7J5A8/vHT/oKXUFZm2
 5eUanyMpZJPRzGUZEb1uCarMDjBun/8qPq2tAO9q20di/OEDWWB6egdTzPOkU+Tm
 Uz3Z8FxCmqDYsSIaNd6Akahxae0pBMbygxlYdA939zOGaKUGdcaX66395jKjFkJ1
 v4XYpsQNBhk=
 =ZxE7
 -----END PGP SIGNATURE-----

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

Pull clk driver updates from Stephen Boyd:
 "Herein lies a smallish collection of clk driver updates and some core
  clk framework changes for the merge window. The core framework changes
  are only improving the debugfs interface to allow phase adjustments
  and report which consumers of a clk there are. These are most likely
  only of interest to kernel developers.

  On the clk driver side, it's a ghastly amount of updates with only a
  handful of new clk drivers. We have a couple new clk drivers for
  Qualcomm, per usual, and a driver for Renesas, Amlogic, and TI
  respectively. The updates are spread throughout the clk drivers.

  Some highlights are fixing kunit tests for different configurations
  like lockdep and big-endian, avoiding integer overflow in rate
  settable clks, moving clk_hw_onecell_data to the end of allocations so
  that drivers don't corrupt their private data, and migrating clk
  drivers to the regmap maple tree. Otherwise it's the usual fixes to
  clk drivers that only come along with testing the drivers on real
  hardware.

  New Drivers:
   - Add clock driver for TWL6032
   - Initial support for the Qualcomm SM4450 Global Clock Controller and
     SM4450 RPMh clock controllers
   - Add Camera Clock Controller on Qualcomm SM8550
   - Add support for the Renesas RZ/G3S (R9A08G045) SoC
   - Add Amlogic s4 main clock controller support

Updates:
   - Make clk kunit tests work with lockdep
   - Fix clk gate kunit test for big-endian
   - Convert more than a handful of clk drivers to use regmap maple tree
   - Consider the CLK_FRAC_DIVIDER_ZERO_BASED in fractional divider clk
     implementation
   - Add consumer info to clk debugfs
   - Fix various clk drivers that have clk_hw_onecell_data not at the
     end of an allocation
   - Drop CLK_SET_RATE_PARENT for clocks with fixed-rate GPLLs across a
     variety of Qualcomm IPQ platforms
   - Add missing parent of APCS PLL on Qualcomm IPQ6018
   - Add I2C QUP6 clk on Qualcomm IPQ6018 but mark it critical to avoid
     problems with RPM
   - Implement safe source switching for a53pll and use on Qualcomm
     IPQ5332
   - Add support for Stromer Plus PLLs to Qualcomm clk driver
   - Switch Qualcomm SM8550 Video and GPU clock controllers to use OLE
     PLL configure method
   - Non critical fixes to halt bit checks in Qualcomm clk drivers
   - Add SMMU GDSC for Qualcomm MSM8998
   - Fix possible integer overflow in Qualcomm RCG frequency calculation
     code
   - Remove RPM managed clks from Qualcomm MSM8996 GCC driver
   - Add HFPLL configuration for the three HFPLLs in Qualcomm MSM8976
   - Switch Qualcomm MSM8996 CBF clock driver's remove function to
     return void
   - Fix missing dependency for s4 clock controllers
   - Select MXC_CLK when building in the CLK_IMX8QXP
   - Fixes for error handling paths in i.MX8 ACM driver
   - Move the clocks check in i.MX8 ACM driver in order to log any error
   - Drop the unused return value of clk_imx_acm_detach_pm_domains
   - Drop non-existant IMX8MP_CLK_AUDIOMIX_PDM_ROOT clock
   - Fix error handling in i.MX8MQ clock driver
   - Allow a different LCDIF1 clock parent if DT describes it for
     i.MX6SX
   - Keep the SCU resource table sorted in the i.MX8DXL rsrc driver
   - Move the elcdif PLL clock registration above lcd_clk, as it is its
     parent
   - Correct some ENET specific clocks for i.MX8DXL platform
   - Drop the VPU_UART and VPUCORE from i.MX8QM as latest HW revision
     doesn't have them
   - Remove "de-featured" MLB support from i.MX8QM/QXP/DXL platforms
   - Skip registering clocks owned by Cortex-A partition SCU-based
     platforms
   - Add CAN_1/2 to i.MX8QM and M4_0, PI_0_PWM_0 and PI_0_I2C_0 to
     i.MX8QXP resources"

* tag 'clk-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/clk/linux: (128 commits)
  clk: Fix clk gate kunit test on big-endian CPUs
  clk: si521xx: Increase stack based print buffer size in probe
  clk: mediatek: fix double free in mtk_clk_register_pllfh()
  clk: socfpga: agilex: Add bounds-checking coverage for struct stratix10_clock_data
  clk: socfpga: Fix undefined behavior bug in struct stratix10_clock_data
  clk: sifive: Allow building the driver as a module
  clk: analogbits: Allow building the library as a module
  clk: sprd: Composite driver support offset config
  clk: Allow phase adjustment from debugfs
  clk: Show active consumers of clocks in debugfs
  clk: Use device_get_match_data()
  clk: visconti: Add bounds-checking coverage for struct visconti_pll_provider
  clk: visconti: Fix undefined behavior bug in struct visconti_pll_provider
  clk: cdce925: Extend match support for OF tables
  clk: si570: Simplify probe
  clk: si5351: Simplify probe
  clk: rs9: Use i2c_get_match_data() instead of device_get_match_data()
  clk: clk-si544: Simplify probe() and is_valid_frequency()
  clk: si521xx: Use i2c_get_match_data() instead of device_get_match_data()
  clk: meson: S4: select CONFIG_COMMON_CLK_MESON_CLKC_UTILS
  ...
This commit is contained in:
Linus Torvalds 2023-10-31 18:42:56 -10:00
commit fe4ae2fab0
126 changed files with 14392 additions and 833 deletions

View File

@ -0,0 +1,96 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/amlogic,s4-peripherals-clkc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Amlogic S4 Peripherals Clock Controller
maintainers:
- Yu Tu <yu.tu@amlogic.com>
properties:
compatible:
const: amlogic,s4-peripherals-clkc
reg:
maxItems: 1
clocks:
minItems: 14
items:
- description: input fixed pll div2
- description: input fixed pll div2p5
- description: input fixed pll div3
- description: input fixed pll div4
- description: input fixed pll div5
- description: input fixed pll div7
- description: input hifi pll
- description: input gp0 pll
- description: input mpll0
- description: input mpll1
- description: input mpll2
- description: input mpll3
- description: input hdmi pll
- description: input oscillator (usually at 24MHz)
- description: input external 32kHz reference (optional)
clock-names:
minItems: 14
items:
- const: fclk_div2
- const: fclk_div2p5
- const: fclk_div3
- const: fclk_div4
- const: fclk_div5
- const: fclk_div7
- const: hifi_pll
- const: gp0_pll
- const: mpll0
- const: mpll1
- const: mpll2
- const: mpll3
- const: hdmi_pll
- const: xtal
- const: ext_32k
"#clock-cells":
const: 1
required:
- compatible
- reg
- clocks
- clock-names
- "#clock-cells"
additionalProperties: false
examples:
- |
#include <dt-bindings/clock/amlogic,s4-peripherals-clkc.h>
clkc_periphs: clock-controller@fe000000 {
compatible = "amlogic,s4-peripherals-clkc";
reg = <0xfe000000 0x49c>;
clocks = <&clkc_pll 3>,
<&clkc_pll 13>,
<&clkc_pll 5>,
<&clkc_pll 7>,
<&clkc_pll 9>,
<&clkc_pll 11>,
<&clkc_pll 17>,
<&clkc_pll 15>,
<&clkc_pll 25>,
<&clkc_pll 27>,
<&clkc_pll 29>,
<&clkc_pll 31>,
<&clkc_pll 20>,
<&xtal>;
clock-names = "fclk_div2", "fclk_div2p5", "fclk_div3", "fclk_div4",
"fclk_div5", "fclk_div7", "hifi_pll", "gp0_pll",
"mpll0", "mpll1", "mpll2", "mpll3", "hdmi_pll", "xtal";
#clock-cells = <1>;
};
...

View File

@ -0,0 +1,49 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
# Copyright (C) 2022-2023 Amlogic, Inc. All rights reserved
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/amlogic,s4-pll-clkc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Amlogic S4 PLL Clock Controller
maintainers:
- Yu Tu <yu.tu@amlogic.com>
properties:
compatible:
const: amlogic,s4-pll-clkc
reg:
maxItems: 1
clocks:
maxItems: 1
clock-names:
items:
- const: xtal
"#clock-cells":
const: 1
required:
- compatible
- reg
- clocks
- clock-names
- "#clock-cells"
additionalProperties: false
examples:
- |
clkc_pll: clock-controller@fe008000 {
compatible = "amlogic,s4-pll-clkc";
reg = <0xfe008000 0x1e8>;
clocks = <&xtal>;
clock-names = "xtal";
#clock-cells = <1>;
};
...

View File

@ -12,6 +12,9 @@ PROPERTIES
"qcom,hfpll-apq8064", "qcom,hfpll"
"qcom,hfpll-msm8974", "qcom,hfpll"
"qcom,hfpll-msm8960", "qcom,hfpll"
"qcom,msm8976-hfpll-a53", "qcom,hfpll"
"qcom,msm8976-hfpll-a72", "qcom,hfpll"
"qcom,msm8976-hfpll-cci", "qcom,hfpll"
- reg:
Usage: required

View File

@ -28,6 +28,7 @@ properties:
- qcom,sdx55-rpmh-clk
- qcom,sdx65-rpmh-clk
- qcom,sdx75-rpmh-clk
- qcom,sm4450-rpmh-clk
- qcom,sm6350-rpmh-clk
- qcom,sm8150-rpmh-clk
- qcom,sm8250-rpmh-clk

View File

@ -0,0 +1,55 @@
# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
%YAML 1.2
---
$id: http://devicetree.org/schemas/clock/qcom,sm4450-gcc.yaml#
$schema: http://devicetree.org/meta-schemas/core.yaml#
title: Qualcomm Global Clock & Reset Controller on SM4450
maintainers:
- Ajit Pandey <quic_ajipan@quicinc.com>
- Taniya Das <quic_tdas@quicinc.com>
description: |
Qualcomm global clock control module provides the clocks, resets and power
domains on SM4450
See also:: include/dt-bindings/clock/qcom,sm4450-gcc.h
properties:
compatible:
const: qcom,sm4450-gcc
clocks:
items:
- description: Board XO source
- description: Sleep clock source
- description: UFS Phy Rx symbol 0 clock source
- description: UFS Phy Rx symbol 1 clock source
- description: UFS Phy Tx symbol 0 clock source
- description: USB3 Phy wrapper pipe clock source
required:
- compatible
- clocks
allOf:
- $ref: qcom,gcc.yaml#
unevaluatedProperties: false
examples:
- |
#include <dt-bindings/clock/qcom,rpmh.h>
clock-controller@100000 {
compatible = "qcom,sm4450-gcc";
reg = <0x00100000 0x001f4200>;
clocks = <&rpmhcc RPMH_CXO_CLK>, <&sleep_clk>,
<&ufs_mem_phy 0>, <&ufs_mem_phy 1>,
<&ufs_mem_phy 2>, <&usb_1_qmpphy>;
#clock-cells = <1>;
#reset-cells = <1>;
#power-domain-cells = <1>;
};
...

View File

@ -13,11 +13,15 @@ description: |
Qualcomm camera clock control module provides the clocks, resets and power
domains on SM8450.
See also:: include/dt-bindings/clock/qcom,sm8450-camcc.h
See also::
include/dt-bindings/clock/qcom,sm8450-camcc.h
include/dt-bindings/clock/qcom,sm8550-camcc.h
properties:
compatible:
const: qcom,sm8450-camcc
enum:
- qcom,sm8450-camcc
- qcom,sm8550-camcc
clocks:
items:

View File

@ -27,6 +27,7 @@ properties:
- renesas,r9a07g043-cpg # RZ/G2UL{Type-1,Type-2} and RZ/Five
- renesas,r9a07g044-cpg # RZ/G2{L,LC}
- renesas,r9a07g054-cpg # RZ/V2L
- renesas,r9a08g045-cpg # RZ/G3S
- renesas,r9a09g011-cpg # RZ/V2M
reg:

View File

@ -2,4 +2,5 @@ CONFIG_KUNIT=y
CONFIG_COMMON_CLK=y
CONFIG_CLK_KUNIT_TEST=y
CONFIG_CLK_GATE_KUNIT_TEST=y
CONFIG_CLK_FD_KUNIT_TEST=y
CONFIG_UML_PCI_OVER_VIRTIO=n

View File

@ -277,6 +277,15 @@ config COMMON_CLK_S2MPS11
clock. These multi-function devices have two (S2MPS14) or three
(S2MPS11, S5M8767) fixed-rate oscillators, clocked at 32KHz each.
config CLK_TWL
tristate "Clock driver for the TWL PMIC family"
depends on TWL4030_CORE
help
Enable support for controlling the clock resources on TWL family
PMICs. These devices have some 32K clock outputs which can be
controlled by software. For now, only the TWL6032 clocks are
supported.
config CLK_TWL6040
tristate "External McPDM functional clock from twl6040"
depends on TWL6040_CORE
@ -517,4 +526,11 @@ config CLK_GATE_KUNIT_TEST
help
Kunit test for the basic clk gate type.
config CLK_FD_KUNIT_TEST
tristate "Basic fractional divider type Kunit test" if !KUNIT_ALL_TESTS
depends on KUNIT
default KUNIT_ALL_TESTS
help
Kunit test for the clk-fractional-divider type.
endif

View File

@ -12,6 +12,7 @@ obj-$(CONFIG_COMMON_CLK) += clk-multiplier.o
obj-$(CONFIG_COMMON_CLK) += clk-mux.o
obj-$(CONFIG_COMMON_CLK) += clk-composite.o
obj-$(CONFIG_COMMON_CLK) += clk-fractional-divider.o
obj-$(CONFIG_CLK_FD_KUNIT_TEST) += clk-fractional-divider_test.o
obj-$(CONFIG_COMMON_CLK) += clk-gpio.o
ifeq ($(CONFIG_OF), y)
obj-$(CONFIG_COMMON_CLK) += clk-conf.o
@ -72,6 +73,7 @@ obj-$(CONFIG_COMMON_CLK_STM32H7) += clk-stm32h7.o
obj-$(CONFIG_COMMON_CLK_STM32MP157) += clk-stm32mp1.o
obj-$(CONFIG_COMMON_CLK_TPS68470) += clk-tps68470.o
obj-$(CONFIG_CLK_TWL6040) += clk-twl6040.o
obj-$(CONFIG_CLK_TWL) += clk-twl.o
obj-$(CONFIG_ARCH_VT8500) += clk-vt8500.o
obj-$(CONFIG_COMMON_CLK_RS9_PCIE) += clk-renesas-pcie.o
obj-$(CONFIG_COMMON_CLK_SI521XX) += clk-si521xx.o

View File

@ -1,3 +1,3 @@
# SPDX-License-Identifier: GPL-2.0-only
config CLK_ANALOGBITS_WRPLL_CLN28HPC
bool
tristate

View File

@ -28,6 +28,7 @@
#include <linux/math64.h>
#include <linux/math.h>
#include <linux/minmax.h>
#include <linux/module.h>
#include <linux/clk/analogbits-wrpll-cln28hpc.h>
@ -312,6 +313,7 @@ int wrpll_configure_for_rate(struct wrpll_cfg *c, u32 target_rate,
return 0;
}
EXPORT_SYMBOL_GPL(wrpll_configure_for_rate);
/**
* wrpll_calc_output_rate() - calculate the PLL's target output rate
@ -349,6 +351,7 @@ unsigned long wrpll_calc_output_rate(const struct wrpll_cfg *c,
return n;
}
EXPORT_SYMBOL_GPL(wrpll_calc_output_rate);
/**
* wrpll_calc_max_lock_us() - return the time for the PLL to lock
@ -366,3 +369,8 @@ unsigned int wrpll_calc_max_lock_us(const struct wrpll_cfg *c)
{
return MAX_LOCK_US;
}
EXPORT_SYMBOL_GPL(wrpll_calc_max_lock_us);
MODULE_AUTHOR("Paul Walmsley <paul.walmsley@sifive.com>");
MODULE_DESCRIPTION("Analog Bits Wide-Range PLL library");
MODULE_LICENSE("GPL");

View File

@ -161,13 +161,11 @@ at91_clk_register_utmi_internal(struct regmap *regmap_pmc,
init.name = name;
init.ops = ops;
if (parent_hw) {
init.parent_hws = parent_hw ? (const struct clk_hw **)&parent_hw : NULL;
init.num_parents = parent_hw ? 1 : 0;
} else {
init.parent_names = parent_name ? &parent_name : NULL;
init.num_parents = parent_name ? 1 : 0;
}
if (parent_hw)
init.parent_hws = (const struct clk_hw **)&parent_hw;
else
init.parent_names = &parent_name;
init.num_parents = 1;
init.flags = flags;
utmi->hw.init = &init;

View File

@ -255,7 +255,7 @@ static struct asm9260_mux_clock asm9260_mux_clks[] __initdata = {
static void __init asm9260_acc_init(struct device_node *np)
{
struct clk_hw *hw, *pll_hw;
struct clk_hw *pll_hw;
struct clk_hw **hws;
const char *pll_clk = "pll";
struct clk_parent_data pll_parent_data = { .index = 0 };
@ -283,7 +283,7 @@ static void __init asm9260_acc_init(struct device_node *np)
for (n = 0; n < ARRAY_SIZE(asm9260_mux_clks); n++) {
const struct asm9260_mux_clock *mc = &asm9260_mux_clks[n];
hw = clk_hw_register_mux_table_parent_data(NULL, mc->name, mc->parent_data,
clk_hw_register_mux_table_parent_data(NULL, mc->name, mc->parent_data,
mc->num_parents, mc->flags, base + mc->offset,
0, mc->mask, 0, mc->table, &asm9260_clk_lock);
}
@ -292,7 +292,7 @@ static void __init asm9260_acc_init(struct device_node *np)
for (n = 0; n < ARRAY_SIZE(asm9260_mux_gates); n++) {
const struct asm9260_gate_data *gd = &asm9260_mux_gates[n];
hw = clk_hw_register_gate(NULL, gd->name,
clk_hw_register_gate(NULL, gd->name,
gd->parent_name, gd->flags | CLK_SET_RATE_PARENT,
base + gd->reg, gd->bit_idx, 0, &asm9260_clk_lock);
}

View File

@ -25,25 +25,11 @@
* Model this as 2 PLL clocks which are parents to the outputs.
*/
enum {
CDCE913,
CDCE925,
CDCE937,
CDCE949,
};
struct clk_cdce925_chip_info {
int num_plls;
int num_outputs;
};
static const struct clk_cdce925_chip_info clk_cdce925_chip_info_tbl[] = {
[CDCE913] = { .num_plls = 1, .num_outputs = 3 },
[CDCE925] = { .num_plls = 2, .num_outputs = 5 },
[CDCE937] = { .num_plls = 3, .num_outputs = 7 },
[CDCE949] = { .num_plls = 4, .num_outputs = 9 },
};
#define MAX_NUMBER_OF_PLLS 4
#define MAX_NUMBER_OF_OUTPUTS 9
@ -621,20 +607,10 @@ static struct regmap_bus regmap_cdce925_bus = {
.read = cdce925_regmap_i2c_read,
};
static const struct i2c_device_id cdce925_id[] = {
{ "cdce913", CDCE913 },
{ "cdce925", CDCE925 },
{ "cdce937", CDCE937 },
{ "cdce949", CDCE949 },
{ }
};
MODULE_DEVICE_TABLE(i2c, cdce925_id);
static int cdce925_probe(struct i2c_client *client)
{
struct clk_cdce925_chip *data;
struct device_node *node = client->dev.of_node;
const struct i2c_device_id *id = i2c_match_id(cdce925_id, client);
const char *parent_name;
const char *pll_clk_name[MAX_NUMBER_OF_PLLS] = {NULL,};
struct clk_init_data init;
@ -647,7 +623,7 @@ static int cdce925_probe(struct i2c_client *client)
.name = "configuration0",
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
};
dev_dbg(&client->dev, "%s\n", __func__);
@ -665,7 +641,7 @@ static int cdce925_probe(struct i2c_client *client)
return -ENOMEM;
data->i2c_client = client;
data->chip_info = &clk_cdce925_chip_info_tbl[id->driver_data];
data->chip_info = i2c_get_match_data(client);
config.max_register = CDCE925_OFFSET_PLL +
data->chip_info->num_plls * 0x10 - 1;
data->regmap = devm_regmap_init(&client->dev, &regmap_cdce925_bus,
@ -822,12 +798,41 @@ error:
return err;
}
static const struct clk_cdce925_chip_info clk_cdce913_info = {
.num_plls = 1,
.num_outputs = 3,
};
static const struct clk_cdce925_chip_info clk_cdce925_info = {
.num_plls = 2,
.num_outputs = 5,
};
static const struct clk_cdce925_chip_info clk_cdce937_info = {
.num_plls = 3,
.num_outputs = 7,
};
static const struct clk_cdce925_chip_info clk_cdce949_info = {
.num_plls = 4,
.num_outputs = 9,
};
static const struct i2c_device_id cdce925_id[] = {
{ "cdce913", (kernel_ulong_t)&clk_cdce913_info },
{ "cdce925", (kernel_ulong_t)&clk_cdce925_info },
{ "cdce937", (kernel_ulong_t)&clk_cdce937_info },
{ "cdce949", (kernel_ulong_t)&clk_cdce949_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, cdce925_id);
static const struct of_device_id clk_cdce925_of_match[] = {
{ .compatible = "ti,cdce913" },
{ .compatible = "ti,cdce925" },
{ .compatible = "ti,cdce937" },
{ .compatible = "ti,cdce949" },
{ },
{ .compatible = "ti,cdce913", .data = &clk_cdce913_info },
{ .compatible = "ti,cdce925", .data = &clk_cdce925_info },
{ .compatible = "ti,cdce937", .data = &clk_cdce937_info },
{ .compatible = "ti,cdce949", .data = &clk_cdce949_info },
{ }
};
MODULE_DEVICE_TABLE(of, clk_cdce925_of_match);

View File

@ -123,6 +123,7 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
unsigned long *m, unsigned long *n)
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long max_m, max_n;
/*
* Get rate closer to *parent_rate to guarantee there is no overflow
@ -138,10 +139,17 @@ void clk_fractional_divider_general_approximation(struct clk_hw *hw,
rate <<= scale - fd->nwidth;
}
rational_best_approximation(rate, *parent_rate,
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
m, n);
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
max_m = 1 << fd->mwidth;
max_n = 1 << fd->nwidth;
} else {
max_m = GENMASK(fd->mwidth - 1, 0);
max_n = GENMASK(fd->nwidth - 1, 0);
}
rational_best_approximation(rate, *parent_rate, max_m, max_n, m, n);
}
EXPORT_SYMBOL_GPL(clk_fractional_divider_general_approximation);
static long clk_fd_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
@ -169,13 +177,18 @@ static int clk_fd_set_rate(struct clk_hw *hw, unsigned long rate,
{
struct clk_fractional_divider *fd = to_clk_fd(hw);
unsigned long flags = 0;
unsigned long m, n;
unsigned long m, n, max_m, max_n;
u32 mmask, nmask;
u32 val;
rational_best_approximation(rate, parent_rate,
GENMASK(fd->mwidth - 1, 0), GENMASK(fd->nwidth - 1, 0),
&m, &n);
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
max_m = 1 << fd->mwidth;
max_n = 1 << fd->nwidth;
} else {
max_m = GENMASK(fd->mwidth - 1, 0);
max_n = GENMASK(fd->nwidth - 1, 0);
}
rational_best_approximation(rate, parent_rate, max_m, max_n, &m, &n);
if (fd->flags & CLK_FRAC_DIVIDER_ZERO_BASED) {
m--;

View File

@ -0,0 +1,147 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Kunit test for clock fractional divider
*/
#include <linux/clk-provider.h>
#include <kunit/test.h>
#include "clk-fractional-divider.h"
/*
* Test the maximum denominator case for fd clock without flags.
*
* Expect the highest possible denominator to be used in order to get as close as possible to the
* requested rate.
*/
static void clk_fd_test_approximation_max_denominator(struct kunit *test)
{
struct clk_fractional_divider *fd;
unsigned long rate, parent_rate, parent_rate_before, m, n, max_n;
fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, fd);
fd->mwidth = 3;
fd->nwidth = 3;
max_n = 7;
rate = 240000000;
parent_rate = (max_n + 1) * rate; /* so that it exceeds the maximum divisor */
parent_rate_before = parent_rate;
clk_fractional_divider_general_approximation(&fd->hw, rate, &parent_rate, &m, &n);
KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before);
KUNIT_EXPECT_EQ(test, m, 1);
KUNIT_EXPECT_EQ(test, n, max_n);
}
/*
* Test the maximum numerator case for fd clock without flags.
*
* Expect the highest possible numerator to be used in order to get as close as possible to the
* requested rate.
*/
static void clk_fd_test_approximation_max_numerator(struct kunit *test)
{
struct clk_fractional_divider *fd;
unsigned long rate, parent_rate, parent_rate_before, m, n, max_m;
fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, fd);
fd->mwidth = 3;
max_m = 7;
fd->nwidth = 3;
rate = 240000000;
parent_rate = rate / (max_m + 1); /* so that it exceeds the maximum numerator */
parent_rate_before = parent_rate;
clk_fractional_divider_general_approximation(&fd->hw, rate, &parent_rate, &m, &n);
KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before);
KUNIT_EXPECT_EQ(test, m, max_m);
KUNIT_EXPECT_EQ(test, n, 1);
}
/*
* Test the maximum denominator case for zero based fd clock.
*
* Expect the highest possible denominator to be used in order to get as close as possible to the
* requested rate.
*/
static void clk_fd_test_approximation_max_denominator_zero_based(struct kunit *test)
{
struct clk_fractional_divider *fd;
unsigned long rate, parent_rate, parent_rate_before, m, n, max_n;
fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, fd);
fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
fd->mwidth = 3;
fd->nwidth = 3;
max_n = 8;
rate = 240000000;
parent_rate = (max_n + 1) * rate; /* so that it exceeds the maximum divisor */
parent_rate_before = parent_rate;
clk_fractional_divider_general_approximation(&fd->hw, rate, &parent_rate, &m, &n);
KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before);
KUNIT_EXPECT_EQ(test, m, 1);
KUNIT_EXPECT_EQ(test, n, max_n);
}
/*
* Test the maximum numerator case for zero based fd clock.
*
* Expect the highest possible numerator to be used in order to get as close as possible to the
* requested rate.
*/
static void clk_fd_test_approximation_max_numerator_zero_based(struct kunit *test)
{
struct clk_fractional_divider *fd;
unsigned long rate, parent_rate, parent_rate_before, m, n, max_m;
fd = kunit_kzalloc(test, sizeof(*fd), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, fd);
fd->flags = CLK_FRAC_DIVIDER_ZERO_BASED;
fd->mwidth = 3;
max_m = 8;
fd->nwidth = 3;
rate = 240000000;
parent_rate = rate / (max_m + 1); /* so that it exceeds the maximum numerator */
parent_rate_before = parent_rate;
clk_fractional_divider_general_approximation(&fd->hw, rate, &parent_rate, &m, &n);
KUNIT_ASSERT_EQ(test, parent_rate, parent_rate_before);
KUNIT_EXPECT_EQ(test, m, max_m);
KUNIT_EXPECT_EQ(test, n, 1);
}
static struct kunit_case clk_fd_approximation_test_cases[] = {
KUNIT_CASE(clk_fd_test_approximation_max_denominator),
KUNIT_CASE(clk_fd_test_approximation_max_numerator),
KUNIT_CASE(clk_fd_test_approximation_max_denominator_zero_based),
KUNIT_CASE(clk_fd_test_approximation_max_numerator_zero_based),
{}
};
/*
* Test suite for clk_fractional_divider_general_approximation().
*/
static struct kunit_suite clk_fd_approximation_suite = {
.name = "clk-fd-approximation",
.test_cases = clk_fd_approximation_test_cases,
};
kunit_test_suites(
&clk_fd_approximation_suite
);
MODULE_LICENSE("GPL");

View File

@ -15,7 +15,7 @@
#include <linux/string.h>
/**
* DOC: basic gatable clock which can gate and ungate it's ouput
* DOC: basic gatable clock which can gate and ungate its output
*
* Traits of this clock:
* prepare - clk_(un)prepare only ensures parent is (un)prepared

View File

@ -131,7 +131,7 @@ struct clk_gate_test_context {
void __iomem *fake_mem;
struct clk_hw *hw;
struct clk_hw *parent;
u32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
__le32 fake_reg; /* Keep at end, KASAN can detect out of bounds */
};
static struct clk_gate_test_context *clk_gate_test_alloc_ctx(struct kunit *test)
@ -166,7 +166,7 @@ static void clk_gate_test_enable(struct kunit *test)
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_EXPECT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
@ -183,10 +183,10 @@ static void clk_gate_test_disable(struct kunit *test)
u32 disable_val = 0;
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_ASSERT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
clk_disable_unprepare(clk);
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
KUNIT_EXPECT_EQ(test, disable_val, le32_to_cpu(ctx->fake_reg));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
@ -246,7 +246,7 @@ static void clk_gate_test_invert_enable(struct kunit *test)
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_EXPECT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
@ -263,10 +263,10 @@ static void clk_gate_test_invert_disable(struct kunit *test)
u32 disable_val = BIT(15);
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_ASSERT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
clk_disable_unprepare(clk);
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
KUNIT_EXPECT_EQ(test, disable_val, le32_to_cpu(ctx->fake_reg));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
@ -290,7 +290,7 @@ static int clk_gate_test_invert_init(struct kunit *test)
2000000);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, parent);
ctx->fake_reg = BIT(15); /* Default to off */
ctx->fake_reg = cpu_to_le32(BIT(15)); /* Default to off */
hw = clk_hw_register_gate_parent_hw(NULL, "test_gate", parent, 0,
ctx->fake_mem, 15,
CLK_GATE_SET_TO_DISABLE, NULL);
@ -319,7 +319,7 @@ static void clk_gate_test_hiword_enable(struct kunit *test)
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_EXPECT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_EXPECT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_TRUE(test, clk_hw_is_enabled(parent));
@ -336,10 +336,10 @@ static void clk_gate_test_hiword_disable(struct kunit *test)
u32 disable_val = BIT(9 + 16);
KUNIT_ASSERT_EQ(test, clk_prepare_enable(clk), 0);
KUNIT_ASSERT_EQ(test, enable_val, ctx->fake_reg);
KUNIT_ASSERT_EQ(test, enable_val, le32_to_cpu(ctx->fake_reg));
clk_disable_unprepare(clk);
KUNIT_EXPECT_EQ(test, disable_val, ctx->fake_reg);
KUNIT_EXPECT_EQ(test, disable_val, le32_to_cpu(ctx->fake_reg));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_prepared(hw));
KUNIT_EXPECT_FALSE(test, clk_hw_is_enabled(parent));
@ -387,7 +387,7 @@ static void clk_gate_test_is_enabled(struct kunit *test)
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
ctx->fake_reg = BIT(7);
ctx->fake_reg = cpu_to_le32(BIT(7));
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
@ -402,7 +402,7 @@ static void clk_gate_test_is_disabled(struct kunit *test)
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
ctx->fake_reg = BIT(4);
ctx->fake_reg = cpu_to_le32(BIT(4));
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 7,
0, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
@ -417,7 +417,7 @@ static void clk_gate_test_is_enabled_inverted(struct kunit *test)
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
ctx->fake_reg = BIT(31);
ctx->fake_reg = cpu_to_le32(BIT(31));
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 2,
CLK_GATE_SET_TO_DISABLE, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);
@ -432,7 +432,7 @@ static void clk_gate_test_is_disabled_inverted(struct kunit *test)
struct clk_gate_test_context *ctx;
ctx = clk_gate_test_alloc_ctx(test);
ctx->fake_reg = BIT(29);
ctx->fake_reg = cpu_to_le32(BIT(29));
hw = clk_hw_register_gate(NULL, "test_gate", NULL, 0, ctx->fake_mem, 29,
CLK_GATE_SET_TO_DISABLE, NULL);
KUNIT_ASSERT_NOT_ERR_OR_NULL(test, hw);

View File

@ -12,8 +12,8 @@
#include <linux/device.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/mfd/lochnagar1_regs.h>
@ -242,22 +242,17 @@ static int lochnagar_clk_probe(struct platform_device *pdev)
};
struct device *dev = &pdev->dev;
struct lochnagar_clk_priv *priv;
const struct of_device_id *of_id;
struct lochnagar_clk *lclk;
struct lochnagar_config *conf;
int ret, i;
of_id = of_match_device(lochnagar_of_match, dev);
if (!of_id)
return -EINVAL;
priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->dev = dev;
priv->regmap = dev_get_regmap(dev->parent, NULL);
conf = (struct lochnagar_config *)of_id->data;
conf = (struct lochnagar_config *)device_get_match_data(dev);
memcpy(priv->lclks, conf->clks, sizeof(priv->lclks));

View File

@ -510,7 +510,7 @@ static void __init npcm7xx_clk_init(struct device_node *clk_np)
return;
npcm7xx_init_fail:
kfree(npcm7xx_clk_data->hws);
kfree(npcm7xx_clk_data);
npcm7xx_init_np_err:
iounmap(clk_base);
npcm7xx_init_error:

View File

@ -298,7 +298,7 @@ static int rs9_probe(struct i2c_client *client)
i2c_set_clientdata(client, rs9);
rs9->client = client;
rs9->chip_info = device_get_match_data(&client->dev);
rs9->chip_info = i2c_get_match_data(client);
if (!rs9->chip_info)
return -EINVAL;

View File

@ -321,7 +321,7 @@ static bool si514_regmap_is_writeable(struct device *dev, unsigned int reg)
static const struct regmap_config si514_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = SI514_REG_CONTROL,
.writeable_reg = si514_regmap_is_writeable,
.volatile_reg = si514_regmap_is_volatile,

View File

@ -279,10 +279,10 @@ si521xx_of_clk_get(struct of_phandle_args *clkspec, void *data)
static int si521xx_probe(struct i2c_client *client)
{
const u16 chip_info = (u16)(uintptr_t)device_get_match_data(&client->dev);
const u16 chip_info = (u16)(uintptr_t)i2c_get_match_data(client);
const struct clk_parent_data clk_parent_data = { .index = 0 };
const u8 data[3] = { SI521XX_REG_BC, 1, 1 };
unsigned char name[6] = "DIFF0";
unsigned char name[16] = "DIFF0";
struct clk_init_data init = {};
struct si521xx *si;
int i, ret;
@ -316,7 +316,7 @@ static int si521xx_probe(struct i2c_client *client)
/* Register clock */
for (i = 0; i < hweight16(chip_info); i++) {
memset(&init, 0, sizeof(init));
snprintf(name, 6, "DIFF%d", i);
snprintf(name, sizeof(name), "DIFF%d", i);
init.name = name;
init.ops = &si521xx_diff_clk_ops;
init.parent_data = &clk_parent_data;

View File

@ -1260,7 +1260,7 @@ static int si5341_wait_device_ready(struct i2c_client *client)
static const struct regmap_config si5341_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.ranges = si5341_regmap_ranges,
.num_ranges = ARRAY_SIZE(si5341_regmap_ranges),
.max_register = SI5341_REGISTER_MAX,

View File

@ -206,7 +206,7 @@ static bool si5351_regmap_is_writeable(struct device *dev, unsigned int reg)
static const struct regmap_config si5351_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = 187,
.writeable_reg = si5351_regmap_is_writeable,
.volatile_reg = si5351_regmap_is_volatile,
@ -1385,8 +1385,7 @@ MODULE_DEVICE_TABLE(i2c, si5351_i2c_ids);
static int si5351_i2c_probe(struct i2c_client *client)
{
const struct i2c_device_id *id = i2c_match_id(si5351_i2c_ids, client);
enum si5351_variant variant = (enum si5351_variant)id->driver_data;
enum si5351_variant variant;
struct si5351_platform_data *pdata;
struct si5351_driver_data *drvdata;
struct clk_init_data init;
@ -1394,6 +1393,7 @@ static int si5351_i2c_probe(struct i2c_client *client)
u8 num_parents, num_clocks;
int ret, n;
variant = (enum si5351_variant)(uintptr_t)i2c_get_match_data(client);
ret = si5351_dt_parse(client, variant);
if (ret)
return ret;

View File

@ -56,17 +56,11 @@
#define DELTA_M_FRAC_NUM 19
#define DELTA_M_FRAC_DEN 20000
enum si544_speed_grade {
si544a,
si544b,
si544c,
};
struct clk_si544 {
struct clk_hw hw;
struct regmap *regmap;
struct i2c_client *i2c_client;
enum si544_speed_grade speed_grade;
unsigned long max_freq;
};
#define to_clk_si544(_hw) container_of(_hw, struct clk_si544, hw)
@ -196,24 +190,10 @@ static int si544_set_muldiv(struct clk_si544 *data,
static bool is_valid_frequency(const struct clk_si544 *data,
unsigned long frequency)
{
unsigned long max_freq = 0;
if (frequency < SI544_MIN_FREQ)
return false;
switch (data->speed_grade) {
case si544a:
max_freq = 1500000000;
break;
case si544b:
max_freq = 800000000;
break;
case si544c:
max_freq = 350000000;
break;
}
return frequency <= max_freq;
return frequency <= data->max_freq;
}
/* Calculate divider settings for a given frequency */
@ -446,24 +426,15 @@ static bool si544_regmap_is_volatile(struct device *dev, unsigned int reg)
static const struct regmap_config si544_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = SI544_REG_PAGE_SELECT,
.volatile_reg = si544_regmap_is_volatile,
};
static const struct i2c_device_id si544_id[] = {
{ "si544a", si544a },
{ "si544b", si544b },
{ "si544c", si544c },
{ }
};
MODULE_DEVICE_TABLE(i2c, si544_id);
static int si544_probe(struct i2c_client *client)
{
struct clk_si544 *data;
struct clk_init_data init;
const struct i2c_device_id *id = i2c_match_id(si544_id, client);
int err;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
@ -475,7 +446,7 @@ static int si544_probe(struct i2c_client *client)
init.num_parents = 0;
data->hw.init = &init;
data->i2c_client = client;
data->speed_grade = id->driver_data;
data->max_freq = (uintptr_t)i2c_get_match_data(client);
if (of_property_read_string(client->dev.of_node, "clock-output-names",
&init.name))
@ -507,11 +478,19 @@ static int si544_probe(struct i2c_client *client)
return 0;
}
static const struct i2c_device_id si544_id[] = {
{ "si544a", 1500000000 },
{ "si544b", 800000000 },
{ "si544c", 350000000 },
{ }
};
MODULE_DEVICE_TABLE(i2c, si544_id);
static const struct of_device_id clk_si544_of_match[] = {
{ .compatible = "silabs,si544a" },
{ .compatible = "silabs,si544b" },
{ .compatible = "silabs,si544c" },
{ },
{ .compatible = "silabs,si544a", .data = (void *)1500000000 },
{ .compatible = "silabs,si544b", .data = (void *)800000000 },
{ .compatible = "silabs,si544c", .data = (void *)350000000 },
{ }
};
MODULE_DEVICE_TABLE(of, clk_si544_of_match);

View File

@ -49,12 +49,22 @@
#define SI570_FREEZE_DCO (1 << 4)
/**
* struct clk_si570_info:
* @max_freq: Maximum frequency for this device
* @has_temperature_stability: Device support temperature stability
*/
struct clk_si570_info {
u64 max_freq;
bool has_temperature_stability;
};
/**
* struct clk_si570:
* @hw: Clock hw struct
* @regmap: Device's regmap
* @div_offset: Rgister offset for dividers
* @max_freq: Maximum frequency for this device
* @info: Device info
* @fxtal: Factory xtal frequency
* @n1: Clock divider N1
* @hs_div: Clock divider HSDIV
@ -66,7 +76,7 @@ struct clk_si570 {
struct clk_hw hw;
struct regmap *regmap;
unsigned int div_offset;
u64 max_freq;
const struct clk_si570_info *info;
u64 fxtal;
unsigned int n1;
unsigned int hs_div;
@ -76,11 +86,6 @@ struct clk_si570 {
};
#define to_clk_si570(_hw) container_of(_hw, struct clk_si570, hw)
enum clk_si570_variant {
si57x,
si59x
};
/**
* si570_get_divs() - Read clock dividers from HW
* @data: Pointer to struct clk_si570
@ -341,7 +346,7 @@ static int si570_set_rate(struct clk_hw *hw, unsigned long rate,
struct i2c_client *client = data->i2c_client;
int err;
if (rate < SI570_MIN_FREQ || rate > data->max_freq) {
if (rate < SI570_MIN_FREQ || rate > data->info->max_freq) {
dev_err(&client->dev,
"requested frequency %lu Hz is out of range\n", rate);
return -EINVAL;
@ -392,30 +397,19 @@ static bool si570_regmap_is_writeable(struct device *dev, unsigned int reg)
static const struct regmap_config si570_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = 137,
.writeable_reg = si570_regmap_is_writeable,
.volatile_reg = si570_regmap_is_volatile,
};
static const struct i2c_device_id si570_id[] = {
{ "si570", si57x },
{ "si571", si57x },
{ "si598", si59x },
{ "si599", si59x },
{ }
};
MODULE_DEVICE_TABLE(i2c, si570_id);
static int si570_probe(struct i2c_client *client)
{
struct clk_si570 *data;
struct clk_init_data init;
const struct i2c_device_id *id = i2c_match_id(si570_id, client);
u32 initial_fout, factory_fout, stability;
bool skip_recall;
int err;
enum clk_si570_variant variant = id->driver_data;
data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
if (!data)
@ -427,7 +421,8 @@ static int si570_probe(struct i2c_client *client)
data->hw.init = &init;
data->i2c_client = client;
if (variant == si57x) {
data->info = i2c_get_match_data(client);
if (data->info->has_temperature_stability) {
err = of_property_read_u32(client->dev.of_node,
"temperature-stability", &stability);
if (err) {
@ -438,10 +433,6 @@ static int si570_probe(struct i2c_client *client)
/* adjust register offsets for 7ppm devices */
if (stability == 7)
data->div_offset = SI570_DIV_OFFSET_7PPM;
data->max_freq = SI570_MAX_FREQ;
} else {
data->max_freq = SI598_MAX_FREQ;
}
if (of_property_read_string(client->dev.of_node, "clock-output-names",
@ -496,12 +487,30 @@ static int si570_probe(struct i2c_client *client)
return 0;
}
static const struct clk_si570_info clk_si570_info = {
.max_freq = SI570_MAX_FREQ,
.has_temperature_stability = true,
};
static const struct clk_si570_info clk_si590_info = {
.max_freq = SI598_MAX_FREQ,
};
static const struct i2c_device_id si570_id[] = {
{ "si570", (kernel_ulong_t)&clk_si570_info },
{ "si571", (kernel_ulong_t)&clk_si570_info },
{ "si598", (kernel_ulong_t)&clk_si590_info },
{ "si599", (kernel_ulong_t)&clk_si590_info },
{ }
};
MODULE_DEVICE_TABLE(i2c, si570_id);
static const struct of_device_id clk_si570_of_match[] = {
{ .compatible = "silabs,si570" },
{ .compatible = "silabs,si571" },
{ .compatible = "silabs,si598" },
{ .compatible = "silabs,si599" },
{ },
{ .compatible = "silabs,si570", .data = &clk_si570_info },
{ .compatible = "silabs,si571", .data = &clk_si570_info },
{ .compatible = "silabs,si598", .data = &clk_si590_info },
{ .compatible = "silabs,si599", .data = &clk_si590_info },
{ }
};
MODULE_DEVICE_TABLE(of, clk_si570_of_match);

197
drivers/clk/clk-twl.c Normal file
View File

@ -0,0 +1,197 @@
// SPDX-License-Identifier: GPL-2.0
/*
* Clock driver for twl device.
*
* inspired by the driver for the Palmas device
*/
#include <linux/clk-provider.h>
#include <linux/mfd/twl.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#define VREG_STATE 2
#define TWL6030_CFG_STATE_OFF 0x00
#define TWL6030_CFG_STATE_ON 0x01
#define TWL6030_CFG_STATE_MASK 0x03
struct twl_clock_info {
struct device *dev;
u8 base;
struct clk_hw hw;
};
static inline int
twlclk_read(struct twl_clock_info *info, unsigned int slave_subgp,
unsigned int offset)
{
u8 value;
int status;
status = twl_i2c_read_u8(slave_subgp, &value,
info->base + offset);
return (status < 0) ? status : value;
}
static inline int
twlclk_write(struct twl_clock_info *info, unsigned int slave_subgp,
unsigned int offset, u8 value)
{
return twl_i2c_write_u8(slave_subgp, value,
info->base + offset);
}
static inline struct twl_clock_info *to_twl_clks_info(struct clk_hw *hw)
{
return container_of(hw, struct twl_clock_info, hw);
}
static unsigned long twl_clks_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
return 32768;
}
static int twl6032_clks_prepare(struct clk_hw *hw)
{
struct twl_clock_info *cinfo = to_twl_clks_info(hw);
int ret;
ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
TWL6030_CFG_STATE_ON);
if (ret < 0)
dev_err(cinfo->dev, "clk prepare failed\n");
return ret;
}
static void twl6032_clks_unprepare(struct clk_hw *hw)
{
struct twl_clock_info *cinfo = to_twl_clks_info(hw);
int ret;
ret = twlclk_write(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE,
TWL6030_CFG_STATE_OFF);
if (ret < 0)
dev_err(cinfo->dev, "clk unprepare failed\n");
}
static int twl6032_clks_is_prepared(struct clk_hw *hw)
{
struct twl_clock_info *cinfo = to_twl_clks_info(hw);
int val;
val = twlclk_read(cinfo, TWL_MODULE_PM_RECEIVER, VREG_STATE);
if (val < 0) {
dev_err(cinfo->dev, "clk read failed\n");
return val;
}
val &= TWL6030_CFG_STATE_MASK;
return val == TWL6030_CFG_STATE_ON;
}
static const struct clk_ops twl6032_clks_ops = {
.prepare = twl6032_clks_prepare,
.unprepare = twl6032_clks_unprepare,
.is_prepared = twl6032_clks_is_prepared,
.recalc_rate = twl_clks_recalc_rate,
};
struct twl_clks_data {
struct clk_init_data init;
u8 base;
};
static const struct twl_clks_data twl6032_clks[] = {
{
.init = {
.name = "clk32kg",
.ops = &twl6032_clks_ops,
.flags = CLK_IGNORE_UNUSED,
},
.base = 0x8C,
},
{
.init = {
.name = "clk32kaudio",
.ops = &twl6032_clks_ops,
.flags = CLK_IGNORE_UNUSED,
},
.base = 0x8F,
},
{
/* sentinel */
}
};
static int twl_clks_probe(struct platform_device *pdev)
{
struct clk_hw_onecell_data *clk_data;
const struct twl_clks_data *hw_data;
struct twl_clock_info *cinfo;
int ret;
int i;
int count;
hw_data = twl6032_clks;
for (count = 0; hw_data[count].init.name; count++)
;
clk_data = devm_kzalloc(&pdev->dev,
struct_size(clk_data, hws, count),
GFP_KERNEL);
if (!clk_data)
return -ENOMEM;
clk_data->num = count;
cinfo = devm_kcalloc(&pdev->dev, count, sizeof(*cinfo), GFP_KERNEL);
if (!cinfo)
return -ENOMEM;
for (i = 0; i < count; i++) {
cinfo[i].base = hw_data[i].base;
cinfo[i].dev = &pdev->dev;
cinfo[i].hw.init = &hw_data[i].init;
ret = devm_clk_hw_register(&pdev->dev, &cinfo[i].hw);
if (ret) {
return dev_err_probe(&pdev->dev, ret,
"Fail to register clock %s\n",
hw_data[i].init.name);
}
clk_data->hws[i] = &cinfo[i].hw;
}
ret = devm_of_clk_add_hw_provider(&pdev->dev,
of_clk_hw_onecell_get, clk_data);
if (ret < 0)
return dev_err_probe(&pdev->dev, ret,
"Fail to add clock driver\n");
return 0;
}
static const struct platform_device_id twl_clks_id[] = {
{
.name = "twl6032-clk",
}, {
/* sentinel */
}
};
MODULE_DEVICE_TABLE(platform, twl_clks_id);
static struct platform_driver twl_clks_driver = {
.driver = {
.name = "twl-clk",
},
.probe = twl_clks_probe,
.id_table = twl_clks_id,
};
module_platform_driver(twl_clks_driver);
MODULE_DESCRIPTION("Clock driver for TWL Series Devices");
MODULE_LICENSE("GPL");

View File

@ -585,17 +585,11 @@ static const struct clk_ops vc3_clk_mux_ops = {
.get_parent = vc3_clk_mux_get_parent,
};
static bool vc3_regmap_is_writeable(struct device *dev, unsigned int reg)
{
return true;
}
static const struct regmap_config vc3_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = 0x24,
.writeable_reg = vc3_regmap_is_writeable,
};
static struct vc3_hw_data clk_div[5];

View File

@ -217,7 +217,7 @@ static bool vc5_regmap_is_writeable(struct device *dev, unsigned int reg)
static const struct regmap_config vc5_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.max_register = 0x76,
.writeable_reg = vc5_regmap_is_writeable,
};

View File

@ -1275,7 +1275,7 @@ static const struct regmap_config vc7_regmap_config = {
.ranges = vc7_range_cfg,
.num_ranges = ARRAY_SIZE(vc7_range_cfg),
.volatile_reg = vc7_volatile_reg,
.cache_type = REGCACHE_RBTREE,
.cache_type = REGCACHE_MAPLE,
.can_multi_write = true,
.reg_format_endian = REGMAP_ENDIAN_LITTLE,
.val_format_endian = REGMAP_ENDIAN_LITTLE,

View File

@ -3188,28 +3188,41 @@ static void clk_summary_show_one(struct seq_file *s, struct clk_core *c,
int level)
{
int phase;
struct clk *clk_user;
int multi_node = 0;
seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ",
seq_printf(s, "%*s%-*s %-7d %-8d %-8d %-11lu %-10lu ",
level * 3 + 1, "",
30 - level * 3, c->name,
35 - level * 3, c->name,
c->enable_count, c->prepare_count, c->protect_count,
clk_core_get_rate_recalc(c),
clk_core_get_accuracy_recalc(c));
phase = clk_core_get_phase(c);
if (phase >= 0)
seq_printf(s, "%5d", phase);
seq_printf(s, "%-5d", phase);
else
seq_puts(s, "-----");
seq_printf(s, " %6d", clk_core_get_scaled_duty_cycle(c, 100000));
seq_printf(s, " %-6d", clk_core_get_scaled_duty_cycle(c, 100000));
if (c->ops->is_enabled)
seq_printf(s, " %9c\n", clk_core_is_enabled(c) ? 'Y' : 'N');
seq_printf(s, " %5c ", clk_core_is_enabled(c) ? 'Y' : 'N');
else if (!c->ops->enable)
seq_printf(s, " %9c\n", 'Y');
seq_printf(s, " %5c ", 'Y');
else
seq_printf(s, " %9c\n", '?');
seq_printf(s, " %5c ", '?');
hlist_for_each_entry(clk_user, &c->clks, clks_node) {
seq_printf(s, "%*s%-*s %-25s\n",
level * 3 + 2 + 105 * multi_node, "",
30,
clk_user->dev_id ? clk_user->dev_id : "deviceless",
clk_user->con_id ? clk_user->con_id : "no_connection_id");
multi_node = 1;
}
}
static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c,
@ -3230,9 +3243,10 @@ static int clk_summary_show(struct seq_file *s, void *data)
struct clk_core *c;
struct hlist_head **lists = s->private;
seq_puts(s, " enable prepare protect duty hardware\n");
seq_puts(s, " clock count count count rate accuracy phase cycle enable\n");
seq_puts(s, "-------------------------------------------------------------------------------------------------------\n");
seq_puts(s, " enable prepare protect duty hardware connection\n");
seq_puts(s, " clock count count count rate accuracy phase cycle enable consumer id\n");
seq_puts(s, "---------------------------------------------------------------------------------------------------------------------------------------------\n");
clk_prepare_lock();
@ -3329,6 +3343,21 @@ static int clk_rate_set(void *data, u64 val)
#define clk_rate_mode 0644
static int clk_phase_set(void *data, u64 val)
{
struct clk_core *core = data;
int degrees = do_div(val, 360);
int ret;
clk_prepare_lock();
ret = clk_core_set_phase_nolock(core, degrees);
clk_prepare_unlock();
return ret;
}
#define clk_phase_mode 0644
static int clk_prepare_enable_set(void *data, u64 val)
{
struct clk_core *core = data;
@ -3356,6 +3385,9 @@ DEFINE_DEBUGFS_ATTRIBUTE(clk_prepare_enable_fops, clk_prepare_enable_get,
#else
#define clk_rate_set NULL
#define clk_rate_mode 0444
#define clk_phase_set NULL
#define clk_phase_mode 0644
#endif
static int clk_rate_get(void *data, u64 *val)
@ -3371,6 +3403,16 @@ static int clk_rate_get(void *data, u64 *val)
DEFINE_DEBUGFS_ATTRIBUTE(clk_rate_fops, clk_rate_get, clk_rate_set, "%llu\n");
static int clk_phase_get(void *data, u64 *val)
{
struct clk_core *core = data;
*val = core->phase;
return 0;
}
DEFINE_DEBUGFS_ATTRIBUTE(clk_phase_fops, clk_phase_get, clk_phase_set, "%llu\n");
static const struct {
unsigned long flag;
const char *name;
@ -3564,7 +3606,8 @@ static void clk_debug_create_one(struct clk_core *core, struct dentry *pdentry)
debugfs_create_file("clk_min_rate", 0444, root, core, &clk_min_rate_fops);
debugfs_create_file("clk_max_rate", 0444, root, core, &clk_max_rate_fops);
debugfs_create_ulong("clk_accuracy", 0444, root, &core->accuracy);
debugfs_create_u32("clk_phase", 0444, root, &core->phase);
debugfs_create_file("clk_phase", clk_phase_mode, root, core,
&clk_phase_fops);
debugfs_create_file("clk_flags", 0444, root, core, &clk_flags_fops);
debugfs_create_u32("clk_prepare_count", 0444, root, &core->prepare_count);
debugfs_create_u32("clk_enable_count", 0444, root, &core->enable_count);

View File

@ -10,6 +10,8 @@
#include <kunit/test.h>
static const struct clk_ops empty_clk_ops = { };
#define DUMMY_CLOCK_INIT_RATE (42 * 1000 * 1000)
#define DUMMY_CLOCK_RATE_1 (142 * 1000 * 1000)
#define DUMMY_CLOCK_RATE_2 (242 * 1000 * 1000)
@ -2155,6 +2157,31 @@ static struct kunit_suite clk_range_minimize_test_suite = {
struct clk_leaf_mux_ctx {
struct clk_multiple_parent_ctx mux_ctx;
struct clk_hw hw;
struct clk_hw parent;
struct clk_rate_request *req;
int (*determine_rate_func)(struct clk_hw *hw, struct clk_rate_request *req);
};
static int clk_leaf_mux_determine_rate(struct clk_hw *hw, struct clk_rate_request *req)
{
struct clk_leaf_mux_ctx *ctx = container_of(hw, struct clk_leaf_mux_ctx, hw);
int ret;
struct clk_rate_request *parent_req = ctx->req;
clk_hw_forward_rate_request(hw, req, req->best_parent_hw, parent_req, req->rate);
ret = ctx->determine_rate_func(req->best_parent_hw, parent_req);
if (ret)
return ret;
req->rate = parent_req->rate;
return 0;
}
static const struct clk_ops clk_leaf_mux_set_rate_parent_ops = {
.determine_rate = clk_leaf_mux_determine_rate,
.set_parent = clk_dummy_single_set_parent,
.get_parent = clk_dummy_single_get_parent,
};
static int
@ -2193,8 +2220,14 @@ clk_leaf_mux_set_rate_parent_test_init(struct kunit *test)
if (ret)
return ret;
ctx->hw.init = CLK_HW_INIT_HW("test-clock", &ctx->mux_ctx.hw,
&clk_dummy_single_parent_ops,
ctx->parent.init = CLK_HW_INIT_HW("test-parent", &ctx->mux_ctx.hw,
&empty_clk_ops, CLK_SET_RATE_PARENT);
ret = clk_hw_register(NULL, &ctx->parent);
if (ret)
return ret;
ctx->hw.init = CLK_HW_INIT_HW("test-clock", &ctx->parent,
&clk_leaf_mux_set_rate_parent_ops,
CLK_SET_RATE_PARENT);
ret = clk_hw_register(NULL, &ctx->hw);
if (ret)
@ -2208,32 +2241,94 @@ static void clk_leaf_mux_set_rate_parent_test_exit(struct kunit *test)
struct clk_leaf_mux_ctx *ctx = test->priv;
clk_hw_unregister(&ctx->hw);
clk_hw_unregister(&ctx->parent);
clk_hw_unregister(&ctx->mux_ctx.hw);
clk_hw_unregister(&ctx->mux_ctx.parents_ctx[0].hw);
clk_hw_unregister(&ctx->mux_ctx.parents_ctx[1].hw);
}
struct clk_leaf_mux_set_rate_parent_determine_rate_test_case {
const char *desc;
int (*determine_rate_func)(struct clk_hw *hw, struct clk_rate_request *req);
};
static void
clk_leaf_mux_set_rate_parent_determine_rate_test_case_to_desc(
const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case *t, char *desc)
{
strcpy(desc, t->desc);
}
static const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case
clk_leaf_mux_set_rate_parent_determine_rate_test_cases[] = {
{
/*
* Test that __clk_determine_rate() on the parent that can't
* change rate doesn't return a clk_rate_request structure with
* the best_parent_hw pointer pointing to the parent.
*/
.desc = "clk_leaf_mux_set_rate_parent__clk_determine_rate_proper_parent",
.determine_rate_func = __clk_determine_rate,
},
{
/*
* Test that __clk_mux_determine_rate() on the parent that
* can't change rate doesn't return a clk_rate_request
* structure with the best_parent_hw pointer pointing to
* the parent.
*/
.desc = "clk_leaf_mux_set_rate_parent__clk_mux_determine_rate_proper_parent",
.determine_rate_func = __clk_mux_determine_rate,
},
{
/*
* Test that __clk_mux_determine_rate_closest() on the parent
* that can't change rate doesn't return a clk_rate_request
* structure with the best_parent_hw pointer pointing to
* the parent.
*/
.desc = "clk_leaf_mux_set_rate_parent__clk_mux_determine_rate_closest_proper_parent",
.determine_rate_func = __clk_mux_determine_rate_closest,
},
{
/*
* Test that clk_hw_determine_rate_no_reparent() on the parent
* that can't change rate doesn't return a clk_rate_request
* structure with the best_parent_hw pointer pointing to
* the parent.
*/
.desc = "clk_leaf_mux_set_rate_parent_clk_hw_determine_rate_no_reparent_proper_parent",
.determine_rate_func = clk_hw_determine_rate_no_reparent,
},
};
KUNIT_ARRAY_PARAM(clk_leaf_mux_set_rate_parent_determine_rate_test,
clk_leaf_mux_set_rate_parent_determine_rate_test_cases,
clk_leaf_mux_set_rate_parent_determine_rate_test_case_to_desc)
/*
* Test that, for a clock that will forward any rate request to its
* parent, the rate request structure returned by __clk_determine_rate
* is sane and will be what we expect.
* Test that when a clk that can't change rate itself calls a function like
* __clk_determine_rate() on its parent it doesn't get back a clk_rate_request
* structure that has the best_parent_hw pointer point to the clk_hw passed
* into the determine rate function. See commit 262ca38f4b6e ("clk: Stop
* forwarding clk_rate_requests to the parent") for more background.
*/
static void clk_leaf_mux_set_rate_parent_determine_rate(struct kunit *test)
static void clk_leaf_mux_set_rate_parent_determine_rate_test(struct kunit *test)
{
struct clk_leaf_mux_ctx *ctx = test->priv;
struct clk_hw *hw = &ctx->hw;
struct clk *clk = clk_hw_get_clk(hw, NULL);
struct clk_rate_request req;
unsigned long rate;
int ret;
const struct clk_leaf_mux_set_rate_parent_determine_rate_test_case *test_param;
test_param = test->param_value;
ctx->determine_rate_func = test_param->determine_rate_func;
ctx->req = &req;
rate = clk_get_rate(clk);
KUNIT_ASSERT_EQ(test, rate, DUMMY_CLOCK_RATE_1);
clk_hw_init_rate_request(hw, &req, DUMMY_CLOCK_RATE_2);
ret = __clk_determine_rate(hw, &req);
KUNIT_ASSERT_EQ(test, ret, 0);
KUNIT_ASSERT_EQ(test, DUMMY_CLOCK_RATE_2, clk_round_rate(clk, DUMMY_CLOCK_RATE_2));
KUNIT_EXPECT_EQ(test, req.rate, DUMMY_CLOCK_RATE_2);
KUNIT_EXPECT_EQ(test, req.best_parent_rate, DUMMY_CLOCK_RATE_2);
@ -2243,15 +2338,16 @@ static void clk_leaf_mux_set_rate_parent_determine_rate(struct kunit *test)
}
static struct kunit_case clk_leaf_mux_set_rate_parent_test_cases[] = {
KUNIT_CASE(clk_leaf_mux_set_rate_parent_determine_rate),
KUNIT_CASE_PARAM(clk_leaf_mux_set_rate_parent_determine_rate_test,
clk_leaf_mux_set_rate_parent_determine_rate_test_gen_params),
{}
};
/*
* Test suite for a clock whose parent is a mux with multiple parents.
* The leaf clock has CLK_SET_RATE_PARENT, and will forward rate
* requests to the mux, which will then select which parent is the best
* fit for a given rate.
* Test suite for a clock whose parent is a pass-through clk whose parent is a
* mux with multiple parents. The leaf and pass-through clocks have the
* CLK_SET_RATE_PARENT flag, and will forward rate requests to the mux, which
* will then select which parent is the best fit for a given rate.
*
* These tests exercise the behaviour of muxes, and the proper selection
* of parents.

View File

@ -11,10 +11,10 @@
#include <linux/init.h>
#include <linux/mfd/da8xx-cfgchip.h>
#include <linux/mfd/syscon.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_data/clk-da8xx-cfgchip.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>
@ -744,15 +744,13 @@ static int da8xx_cfgchip_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct da8xx_cfgchip_clk_platform_data *pdata = dev->platform_data;
const struct of_device_id *of_id;
da8xx_cfgchip_init clk_init = NULL;
struct regmap *regmap = NULL;
of_id = of_match_device(da8xx_cfgchip_of_match, dev);
if (of_id) {
clk_init = device_get_match_data(dev);
if (clk_init) {
struct device_node *parent;
clk_init = of_id->data;
parent = of_get_parent(dev->of_node);
regmap = syscon_node_to_regmap(parent);
of_node_put(parent);

View File

@ -18,11 +18,10 @@
#include <linux/kernel.h>
#include <linux/mfd/syscon.h>
#include <linux/notifier.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_data/clk-davinci-pll.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/types.h>
@ -892,14 +891,11 @@ static int davinci_pll_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct davinci_pll_platform_data *pdata;
const struct of_device_id *of_id;
davinci_pll_init pll_init = NULL;
void __iomem *base;
of_id = of_match_device(davinci_pll_of_match, dev);
if (of_id)
pll_init = of_id->data;
else if (pdev->id_entry)
pll_init = device_get_match_data(dev);
if (!pll_init && pdev->id_entry)
pll_init = (void *)pdev->id_entry->driver_data;
if (!pll_init) {

View File

@ -18,10 +18,9 @@
#include <linux/clk/davinci.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/pm_clock.h>
#include <linux/pm_domain.h>
#include <linux/regmap.h>
@ -517,15 +516,12 @@ static const struct platform_device_id davinci_psc_id_table[] = {
static int davinci_psc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *of_id;
const struct davinci_psc_init_data *init_data = NULL;
void __iomem *base;
int ret;
of_id = of_match_device(davinci_psc_of_match, dev);
if (of_id)
init_data = of_id->data;
else if (pdev->id_entry)
init_data = device_get_match_data(dev);
if (!init_data && pdev->id_entry)
init_data = (void *)pdev->id_entry->driver_data;
if (!init_data) {

View File

@ -96,6 +96,7 @@ config CLK_IMX8QXP
depends on (ARCH_MXC && ARM64) || COMPILE_TEST
depends on IMX_SCU && HAVE_ARM_SMCCC
select MXC_CLK_SCU
select MXC_CLK
help
Build the driver for IMX8QXP SCU based clocks.

View File

@ -121,6 +121,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
{
struct device_node *np;
void __iomem *base;
bool lcdif1_assigned_clk;
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
IMX6SX_CLK_CLK_END), GFP_KERNEL);
@ -498,9 +499,16 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
clk_set_parent(hws[IMX6SX_CLK_EIM_SLOW_SEL]->clk, hws[IMX6SX_CLK_PLL2_PFD2]->clk);
clk_set_rate(hws[IMX6SX_CLK_EIM_SLOW]->clk, 132000000);
/* set parent clock for LCDIF1 pixel clock */
clk_set_parent(hws[IMX6SX_CLK_LCDIF1_PRE_SEL]->clk, hws[IMX6SX_CLK_PLL5_VIDEO_DIV]->clk);
clk_set_parent(hws[IMX6SX_CLK_LCDIF1_SEL]->clk, hws[IMX6SX_CLK_LCDIF1_PODF]->clk);
np = of_find_node_by_path("/soc/bus@2200000/spba-bus@2240000/lcdif@2220000");
lcdif1_assigned_clk = of_find_property(np, "assigned-clock-parents", NULL);
/* Set parent clock for LCDIF1 pixel clock if not done via devicetree */
if (!lcdif1_assigned_clk) {
clk_set_parent(hws[IMX6SX_CLK_LCDIF1_PRE_SEL]->clk,
hws[IMX6SX_CLK_PLL5_VIDEO_DIV]->clk);
clk_set_parent(hws[IMX6SX_CLK_LCDIF1_SEL]->clk,
hws[IMX6SX_CLK_LCDIF1_PODF]->clk);
}
/* Set the parent clks of PCIe lvds1 and pcie_axi to be pcie ref, axi */
if (clk_set_parent(hws[IMX6SX_CLK_LVDS1_SEL]->clk, hws[IMX6SX_CLK_PCIE_REF_125M]->clk))

View File

@ -77,7 +77,7 @@ struct imx8_acm_priv {
static const struct clk_parent_data imx8qm_aud_clk_sels[] = {
{ .fw_name = "aud_rec_clk0_lpcg_clk" },
{ .fw_name = "aud_rec_clk1_lpcg_clk" },
{ .fw_name = "mlb_clk" },
{ .fw_name = "dummy" },
{ .fw_name = "hdmi_rx_mclk" },
{ .fw_name = "ext_aud_mclk0" },
{ .fw_name = "ext_aud_mclk1" },
@ -103,7 +103,7 @@ static const struct clk_parent_data imx8qm_aud_clk_sels[] = {
static const struct clk_parent_data imx8qm_mclk_out_sels[] = {
{ .fw_name = "aud_rec_clk0_lpcg_clk" },
{ .fw_name = "aud_rec_clk1_lpcg_clk" },
{ .fw_name = "mlb_clk" },
{ .fw_name = "dummy" },
{ .fw_name = "hdmi_rx_mclk" },
{ .fw_name = "spdif0_rx" },
{ .fw_name = "spdif1_rx" },
@ -122,7 +122,7 @@ static const struct clk_parent_data imx8qm_asrc_mux_clk_sels[] = {
{ .fw_name = "sai4_rx_bclk" },
{ .fw_name = "sai5_tx_bclk" },
{ .index = -1 },
{ .fw_name = "mlb_clk" },
{ .fw_name = "dummy" },
};
@ -279,8 +279,10 @@ static int clk_imx_acm_attach_pm_domains(struct device *dev,
for (i = 0; i < dev_pm->num_domains; i++) {
dev_pm->pd_dev[i] = dev_pm_domain_attach_by_id(dev, i);
if (IS_ERR(dev_pm->pd_dev[i]))
return PTR_ERR(dev_pm->pd_dev[i]);
if (IS_ERR(dev_pm->pd_dev[i])) {
ret = PTR_ERR(dev_pm->pd_dev[i]);
goto detach_pm;
}
dev_pm->pd_dev_link[i] = device_link_add(dev,
dev_pm->pd_dev[i],
@ -308,20 +310,18 @@ detach_pm:
* @dev: deivice pointer
* @dev_pm: multi power domain for device
*/
static int clk_imx_acm_detach_pm_domains(struct device *dev,
struct clk_imx_acm_pm_domains *dev_pm)
static void clk_imx_acm_detach_pm_domains(struct device *dev,
struct clk_imx_acm_pm_domains *dev_pm)
{
int i;
if (dev_pm->num_domains <= 1)
return 0;
return;
for (i = 0; i < dev_pm->num_domains; i++) {
device_link_del(dev_pm->pd_dev_link[i]);
dev_pm_domain_detach(dev_pm->pd_dev[i], false);
}
return 0;
}
static int imx8_acm_clk_probe(struct platform_device *pdev)
@ -371,22 +371,25 @@ static int imx8_acm_clk_probe(struct platform_device *pdev)
sels[i].shift, sels[i].width,
0, NULL, NULL);
if (IS_ERR(hws[sels[i].clkid])) {
pm_runtime_disable(&pdev->dev);
ret = PTR_ERR(hws[sels[i].clkid]);
imx_check_clk_hws(hws, IMX_ADMA_ACM_CLK_END);
goto err_clk_register;
}
}
imx_check_clk_hws(hws, IMX_ADMA_ACM_CLK_END);
ret = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, clk_hw_data);
if (ret < 0) {
dev_err(dev, "failed to register hws for ACM\n");
pm_runtime_disable(&pdev->dev);
goto err_clk_register;
}
err_clk_register:
pm_runtime_put_sync(&pdev->dev);
return 0;
err_clk_register:
pm_runtime_put_sync(&pdev->dev);
pm_runtime_disable(&pdev->dev);
clk_imx_acm_detach_pm_domains(&pdev->dev, &priv->dev_pm);
return ret;
}

View File

@ -47,11 +47,10 @@ static u32 imx8dxl_clk_scu_rsrc_table[] = {
IMX_SC_R_SDHC_2,
IMX_SC_R_ENET_0,
IMX_SC_R_ENET_1,
IMX_SC_R_MLB_0,
IMX_SC_R_USB_1,
IMX_SC_R_NAND,
IMX_SC_R_M4_0_I2C,
IMX_SC_R_M4_0_UART,
IMX_SC_R_M4_0_I2C,
IMX_SC_R_ELCDIF_PLL,
IMX_SC_R_AUDIO_PLL_0,
IMX_SC_R_AUDIO_PLL_1,

View File

@ -288,8 +288,7 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
void __iomem *base;
int err;
clk_hw_data = kzalloc(struct_size(clk_hw_data, hws,
IMX8MQ_CLK_END), GFP_KERNEL);
clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MQ_CLK_END), GFP_KERNEL);
if (WARN_ON(!clk_hw_data))
return -ENOMEM;
@ -306,10 +305,12 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
hws[IMX8MQ_CLK_EXT4] = imx_get_clk_hw_by_name(np, "clk_ext4");
np = of_find_compatible_node(NULL, NULL, "fsl,imx8mq-anatop");
base = of_iomap(np, 0);
base = devm_of_iomap(dev, np, 0, NULL);
of_node_put(np);
if (WARN_ON(!base))
return -ENOMEM;
if (WARN_ON(IS_ERR(base))) {
err = PTR_ERR(base);
goto unregister_hws;
}
hws[IMX8MQ_ARM_PLL_REF_SEL] = imx_clk_hw_mux("arm_pll_ref_sel", base + 0x28, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
hws[IMX8MQ_GPU_PLL_REF_SEL] = imx_clk_hw_mux("gpu_pll_ref_sel", base + 0x18, 16, 2, pll_ref_sels, ARRAY_SIZE(pll_ref_sels));
@ -395,8 +396,10 @@ static int imx8mq_clocks_probe(struct platform_device *pdev)
np = dev->of_node;
base = devm_platform_ioremap_resource(pdev, 0);
if (WARN_ON(IS_ERR(base)))
return PTR_ERR(base);
if (WARN_ON(IS_ERR(base))) {
err = PTR_ERR(base);
goto unregister_hws;
}
/* CORE */
hws[IMX8MQ_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mq_a53_sels, base + 0x8000);

View File

@ -43,6 +43,8 @@ static const u32 imx8qm_clk_scu_rsrc_table[] = {
IMX_SC_R_FTM_0,
IMX_SC_R_FTM_1,
IMX_SC_R_CAN_0,
IMX_SC_R_CAN_1,
IMX_SC_R_CAN_2,
IMX_SC_R_GPU_0_PID0,
IMX_SC_R_GPU_1_PID0,
IMX_SC_R_PWM_0,
@ -65,7 +67,6 @@ static const u32 imx8qm_clk_scu_rsrc_table[] = {
IMX_SC_R_SDHC_2,
IMX_SC_R_ENET_0,
IMX_SC_R_ENET_1,
IMX_SC_R_MLB_0,
IMX_SC_R_USB_2,
IMX_SC_R_NAND,
IMX_SC_R_LVDS_0,
@ -79,8 +80,6 @@ static const u32 imx8qm_clk_scu_rsrc_table[] = {
IMX_SC_R_M4_0_I2C,
IMX_SC_R_M4_1_I2C,
IMX_SC_R_AUDIO_PLL_0,
IMX_SC_R_VPU_UART,
IMX_SC_R_VPUCORE,
IMX_SC_R_MIPI_0,
IMX_SC_R_MIPI_0_PWM_0,
IMX_SC_R_MIPI_0_I2C_0,

View File

@ -42,7 +42,6 @@
#define CONN_ENET_0_LPCG 0x30000
#define CONN_ENET_1_LPCG 0x40000
#define CONN_DTCP_LPCG 0x50000
#define CONN_MLB_LPCG 0x60000
#define CONN_USB_2_LPCG 0x70000
#define CONN_USB_3_LPCG 0x80000
#define CONN_NAND_LPCG 0x90000

View File

@ -54,15 +54,17 @@ static const u32 imx8qxp_clk_scu_rsrc_table[] = {
IMX_SC_R_SDHC_2,
IMX_SC_R_ENET_0,
IMX_SC_R_ENET_1,
IMX_SC_R_MLB_0,
IMX_SC_R_USB_2,
IMX_SC_R_NAND,
IMX_SC_R_LVDS_0,
IMX_SC_R_LVDS_1,
IMX_SC_R_M4_0_UART,
IMX_SC_R_M4_0_I2C,
IMX_SC_R_ELCDIF_PLL,
IMX_SC_R_AUDIO_PLL_0,
IMX_SC_R_PI_0,
IMX_SC_R_PI_0_PWM_0,
IMX_SC_R_PI_0_I2C_0,
IMX_SC_R_PI_0_PLL,
IMX_SC_R_MIPI_0,
IMX_SC_R_MIPI_0_PWM_0,

View File

@ -90,6 +90,11 @@ static const char * const pi_pll0_sels[] = {
"clk_dummy",
};
static inline bool clk_on_imx8dxl(struct device_node *node)
{
return of_device_is_compatible(node, "fsl,imx8dxl-clk");
}
static int imx8qxp_clk_probe(struct platform_device *pdev)
{
struct device_node *ccm_node = pdev->dev.of_node;
@ -147,10 +152,10 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
imx_clk_scu("adc0_clk", IMX_SC_R_ADC_0, IMX_SC_PM_CLK_PER);
imx_clk_scu("adc1_clk", IMX_SC_R_ADC_1, IMX_SC_PM_CLK_PER);
imx_clk_scu("pwm_clk", IMX_SC_R_LCD_0_PWM_0, IMX_SC_PM_CLK_PER);
imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
imx_clk_scu2("lcd_clk", lcd_sels, ARRAY_SIZE(lcd_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_PER);
imx_clk_scu2("lcd_pxl_clk", lcd_pxl_sels, ARRAY_SIZE(lcd_pxl_sels), IMX_SC_R_LCD_0, IMX_SC_PM_CLK_MISC0);
imx_clk_scu("lcd_pxl_bypass_div_clk", IMX_SC_R_LCD_0, IMX_SC_PM_CLK_BYPASS);
imx_clk_scu("elcdif_pll", IMX_SC_R_ELCDIF_PLL, IMX_SC_PM_CLK_PLL);
/* Audio SS */
imx_clk_scu("audio_pll0_clk", IMX_SC_R_AUDIO_PLL_0, IMX_SC_PM_CLK_PLL);
@ -169,13 +174,15 @@ static int imx8qxp_clk_probe(struct platform_device *pdev)
imx_clk_mux_gpr_scu("enet0_rgmii_txc_sel", enet0_rgmii_txc_sels, ARRAY_SIZE(enet0_rgmii_txc_sels), IMX_SC_R_ENET_0, IMX_SC_C_TXCLK);
imx_clk_scu("enet0_bypass_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_BYPASS);
imx_clk_gate_gpr_scu("enet0_ref_50_clk", "clk_dummy", IMX_SC_R_ENET_0, IMX_SC_C_DISABLE_50, true);
imx_clk_scu("enet0_rgmii_rx_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0);
if (!clk_on_imx8dxl(ccm_node)) {
imx_clk_scu("enet0_rgmii_rx_clk", IMX_SC_R_ENET_0, IMX_SC_PM_CLK_MISC0);
imx_clk_scu("enet1_rgmii_rx_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0);
}
imx_clk_scu("enet1_root_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_PER);
imx_clk_divider_gpr_scu("enet1_ref_div", "enet1_root_clk", IMX_SC_R_ENET_1, IMX_SC_C_CLKDIV);
imx_clk_mux_gpr_scu("enet1_rgmii_txc_sel", enet1_rgmii_txc_sels, ARRAY_SIZE(enet1_rgmii_txc_sels), IMX_SC_R_ENET_1, IMX_SC_C_TXCLK);
imx_clk_scu("enet1_bypass_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_BYPASS);
imx_clk_gate_gpr_scu("enet1_ref_50_clk", "clk_dummy", IMX_SC_R_ENET_1, IMX_SC_C_DISABLE_50, true);
imx_clk_scu("enet1_rgmii_rx_clk", IMX_SC_R_ENET_1, IMX_SC_PM_CLK_MISC0);
imx_clk_scu("gpmi_io_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_MST_BUS);
imx_clk_scu("gpmi_bch_clk", IMX_SC_R_NAND, IMX_SC_PM_CLK_PER);
imx_clk_scu("usb3_aclk_div", IMX_SC_R_USB_2, IMX_SC_PM_CLK_PER);

View File

@ -10,10 +10,12 @@
#include <linux/clk-provider.h>
#include <linux/err.h>
#include <linux/of.h>
#include <linux/firmware/imx/svc/rm.h>
#include <linux/platform_device.h>
#include <linux/pm_domain.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <xen/xen.h>
#include "clk-scu.h"
@ -670,6 +672,18 @@ static int imx_clk_scu_attach_pd(struct device *dev, u32 rsrc_id)
return of_genpd_add_device(&genpdspec, dev);
}
static bool imx_clk_is_resource_owned(u32 rsrc)
{
/*
* A-core resources are special. SCFW reports they are not "owned" by
* current partition but linux can still adjust them for cpufreq.
*/
if (rsrc == IMX_SC_R_A53 || rsrc == IMX_SC_R_A72 || rsrc == IMX_SC_R_A35)
return true;
return imx_sc_rm_is_resource_owned(ccm_ipc_handle, rsrc);
}
struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
const char * const *parents,
int num_parents, u32 rsrc_id, u8 clk_type)
@ -687,6 +701,9 @@ struct clk_hw *imx_clk_scu_alloc_dev(const char *name,
if (!imx_scu_clk_is_valid(rsrc_id))
return ERR_PTR(-EINVAL);
if (!imx_clk_is_resource_owned(rsrc_id))
return NULL;
pdev = platform_device_alloc(name, PLATFORM_DEVID_NONE);
if (!pdev) {
pr_err("%s: failed to allocate scu clk dev rsrc %d type %d\n",
@ -869,6 +886,9 @@ struct clk_hw *__imx_clk_gpr_scu(const char *name, const char * const *parent_na
return ERR_PTR(-EINVAL);
}
if (!imx_clk_is_resource_owned(rsrc_id))
return NULL;
clk = kzalloc(sizeof(*clk), GFP_KERNEL);
if (!clk) {
kfree(clk_node);

View File

@ -281,12 +281,13 @@ static void __init of_pll_div_clk_init(struct device_node *node)
clk = clk_register_divider(NULL, clk_name, parent_name, 0, reg, shift,
mask, 0, NULL);
if (clk) {
of_clk_add_provider(node, of_clk_src_simple_get, clk);
} else {
if (IS_ERR(clk)) {
pr_err("%s: error registering divider %s\n", __func__, clk_name);
iounmap(reg);
return;
}
of_clk_add_provider(node, of_clk_src_simple_get, clk);
}
CLK_OF_DECLARE(pll_divider_clock, "ti,keystone,pll-divider-clock", of_pll_div_clk_init);
@ -328,10 +329,12 @@ static void __init of_pll_mux_clk_init(struct device_node *node)
clk = clk_register_mux(NULL, clk_name, (const char **)&parents,
ARRAY_SIZE(parents) , 0, reg, shift, mask,
0, NULL);
if (clk)
of_clk_add_provider(node, of_clk_src_simple_get, clk);
else
if (IS_ERR(clk)) {
pr_err("%s: error registering mux %s\n", __func__, clk_name);
return;
}
of_clk_add_provider(node, of_clk_src_simple_get, clk);
}
CLK_OF_DECLARE(pll_mux_clock, "ti,keystone,pll-mux-clock", of_pll_mux_clk_init);

View File

@ -667,6 +667,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
clk_data);
@ -747,6 +749,8 @@ static void __init mtk_infrasys_init_early(struct device_node *node)
if (!infra_clk_data) {
infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
if (!infra_clk_data)
return;
for (i = 0; i < CLK_INFRA_NR; i++)
infra_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
@ -774,6 +778,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
if (!infra_clk_data) {
infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
if (!infra_clk_data)
return -ENOMEM;
} else {
for (i = 0; i < CLK_INFRA_NR; i++) {
if (infra_clk_data->hws[i] == ERR_PTR(-EPROBE_DEFER))
@ -890,6 +896,8 @@ static int mtk_pericfg_init(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_PERI_NR);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_gates(&pdev->dev, node, peri_clks,
ARRAY_SIZE(peri_clks), clk_data);

View File

@ -737,6 +737,8 @@ static int clk_mt6765_apmixed_probe(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
@ -769,6 +771,8 @@ static int clk_mt6765_top_probe(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_fixed_clks(fixed_clks, ARRAY_SIZE(fixed_clks),
clk_data);
@ -807,6 +811,8 @@ static int clk_mt6765_ifr_probe(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_IFR_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_gates(&pdev->dev, node, ifr_clks,
ARRAY_SIZE(ifr_clks), clk_data);

View File

@ -1217,6 +1217,8 @@ static int clk_mt6779_apmixed_probe(struct platform_device *pdev)
struct device_node *node = pdev->dev.of_node;
clk_data = mtk_alloc_clk_data(CLK_APMIXED_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_plls(node, plls, ARRAY_SIZE(plls), clk_data);
@ -1237,6 +1239,8 @@ static int clk_mt6779_top_probe(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
clk_data);

View File

@ -390,6 +390,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_TOP_NR);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_factors(top_fixed_divs, ARRAY_SIZE(top_fixed_divs),
clk_data);
@ -545,6 +547,8 @@ static void mtk_infrasys_init_early(struct device_node *node)
if (!infra_clk_data) {
infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
if (!infra_clk_data)
return;
for (i = 0; i < CLK_INFRA_NR; i++)
infra_clk_data->hws[i] = ERR_PTR(-EPROBE_DEFER);
@ -570,6 +574,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
if (!infra_clk_data) {
infra_clk_data = mtk_alloc_clk_data(CLK_INFRA_NR);
if (!infra_clk_data)
return -ENOMEM;
} else {
for (i = 0; i < CLK_INFRA_NR; i++) {
if (infra_clk_data->hws[i] == ERR_PTR(-EPROBE_DEFER))

View File

@ -77,6 +77,8 @@ static int clk_mt7629_ethsys_init(struct platform_device *pdev)
int r;
clk_data = mtk_alloc_clk_data(CLK_ETH_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_gates(&pdev->dev, node, eth_clks,
CLK_ETH_NR_CLK, clk_data);
@ -100,6 +102,8 @@ static int clk_mt7629_sgmiisys_init(struct platform_device *pdev)
int r;
clk_data = mtk_alloc_clk_data(CLK_SGMII_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_gates(&pdev->dev, node, sgmii_clks[id++],
CLK_SGMII_NR_CLK, clk_data);

View File

@ -555,6 +555,8 @@ static int mtk_topckgen_init(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_TOP_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_fixed_clks(top_fixed_clks, ARRAY_SIZE(top_fixed_clks),
clk_data);
@ -579,6 +581,8 @@ static int mtk_infrasys_init(struct platform_device *pdev)
struct clk_hw_onecell_data *clk_data;
clk_data = mtk_alloc_clk_data(CLK_INFRA_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_gates(&pdev->dev, node, infra_clks,
ARRAY_SIZE(infra_clks), clk_data);
@ -602,6 +606,8 @@ static int mtk_pericfg_init(struct platform_device *pdev)
return PTR_ERR(base);
clk_data = mtk_alloc_clk_data(CLK_PERI_NR_CLK);
if (!clk_data)
return -ENOMEM;
mtk_clk_register_gates(&pdev->dev, node, peri_clks,
ARRAY_SIZE(peri_clks), clk_data);

View File

@ -321,10 +321,8 @@ struct clk_hw *mtk_clk_register_pll_ops(struct mtk_clk_pll *pll,
ret = clk_hw_register(NULL, &pll->hw);
if (ret) {
kfree(pll);
if (ret)
return ERR_PTR(ret);
}
return &pll->hw;
}
@ -340,6 +338,8 @@ struct clk_hw *mtk_clk_register_pll(const struct mtk_pll_data *data,
return ERR_PTR(-ENOMEM);
hw = mtk_clk_register_pll_ops(pll, data, base, &mtk_pll_ops);
if (IS_ERR(hw))
kfree(pll);
return hw;
}

View File

@ -144,4 +144,29 @@ config COMMON_CLK_G12A
help
Support for the clock controller on Amlogic S905D2, S905X2 and S905Y2
devices, aka g12a. Say Y if you want peripherals to work.
config COMMON_CLK_S4_PLL
tristate "S4 SoC PLL clock controllers support"
depends on ARM64
default y
select COMMON_CLK_MESON_CLKC_UTILS
select COMMON_CLK_MESON_MPLL
select COMMON_CLK_MESON_PLL
select COMMON_CLK_MESON_REGMAP
help
Support for the PLL clock controller on Amlogic S805X2 and S905Y4 devices,
AKA S4. Say Y if you want the board to work, because PLLs are the parent of
most peripherals.
config COMMON_CLK_S4_PERIPHERALS
tristate "S4 SoC peripherals clock controllers support"
depends on ARM64
default y
select COMMON_CLK_MESON_CLKC_UTILS
select COMMON_CLK_MESON_REGMAP
select COMMON_CLK_MESON_DUALDIV
select COMMON_CLK_MESON_VID_PLL_DIV
help
Support for the peripherals clock controller on Amlogic S805X2 and S905Y4
devices, AKA S4. Say Y if you want S4 peripherals clock controller to work.
endmenu

View File

@ -22,3 +22,5 @@ obj-$(CONFIG_COMMON_CLK_A1_PERIPHERALS) += a1-peripherals.o
obj-$(CONFIG_COMMON_CLK_GXBB) += gxbb.o gxbb-aoclk.o
obj-$(CONFIG_COMMON_CLK_G12A) += g12a.o g12a-aoclk.o
obj-$(CONFIG_COMMON_CLK_MESON8B) += meson8b.o meson8-ddr.o
obj-$(CONFIG_COMMON_CLK_S4_PLL) += s4-pll.o
obj-$(CONFIG_COMMON_CLK_S4_PERIPHERALS) += s4-peripherals.o

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,56 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
/*
* Copyright (c) 2022-2023 Amlogic, inc. All rights reserved
* Author: Yu Tu <yu.tu@amlogic.com>
*/
#ifndef __MESON_S4_PERIPHERALS_H__
#define __MESON_S4_PERIPHERALS_H__
#define CLKCTRL_RTC_BY_OSCIN_CTRL0 0x008
#define CLKCTRL_RTC_BY_OSCIN_CTRL1 0x00c
#define CLKCTRL_RTC_CTRL 0x010
#define CLKCTRL_SYS_CLK_CTRL0 0x040
#define CLKCTRL_SYS_CLK_EN0_REG0 0x044
#define CLKCTRL_SYS_CLK_EN0_REG1 0x048
#define CLKCTRL_SYS_CLK_EN0_REG2 0x04c
#define CLKCTRL_SYS_CLK_EN0_REG3 0x050
#define CLKCTRL_CECA_CTRL0 0x088
#define CLKCTRL_CECA_CTRL1 0x08c
#define CLKCTRL_CECB_CTRL0 0x090
#define CLKCTRL_CECB_CTRL1 0x094
#define CLKCTRL_SC_CLK_CTRL 0x098
#define CLKCTRL_CLK12_24_CTRL 0x0a8
#define CLKCTRL_VID_CLK_CTRL 0x0c0
#define CLKCTRL_VID_CLK_CTRL2 0x0c4
#define CLKCTRL_VID_CLK_DIV 0x0c8
#define CLKCTRL_VIID_CLK_DIV 0x0cc
#define CLKCTRL_VIID_CLK_CTRL 0x0d0
#define CLKCTRL_HDMI_CLK_CTRL 0x0e0
#define CLKCTRL_VID_PLL_CLK_DIV 0x0e4
#define CLKCTRL_VPU_CLK_CTRL 0x0e8
#define CLKCTRL_VPU_CLKB_CTRL 0x0ec
#define CLKCTRL_VPU_CLKC_CTRL 0x0f0
#define CLKCTRL_VID_LOCK_CLK_CTRL 0x0f4
#define CLKCTRL_VDIN_MEAS_CLK_CTRL 0x0f8
#define CLKCTRL_VAPBCLK_CTRL 0x0fc
#define CLKCTRL_HDCP22_CTRL 0x100
#define CLKCTRL_VDEC_CLK_CTRL 0x140
#define CLKCTRL_VDEC2_CLK_CTRL 0x144
#define CLKCTRL_VDEC3_CLK_CTRL 0x148
#define CLKCTRL_VDEC4_CLK_CTRL 0x14c
#define CLKCTRL_TS_CLK_CTRL 0x158
#define CLKCTRL_MALI_CLK_CTRL 0x15c
#define CLKCTRL_NAND_CLK_CTRL 0x168
#define CLKCTRL_SD_EMMC_CLK_CTRL 0x16c
#define CLKCTRL_SPICC_CLK_CTRL 0x174
#define CLKCTRL_GEN_CLK_CTRL 0x178
#define CLKCTRL_SAR_CLK_CTRL 0x17c
#define CLKCTRL_PWM_CLK_AB_CTRL 0x180
#define CLKCTRL_PWM_CLK_CD_CTRL 0x184
#define CLKCTRL_PWM_CLK_EF_CTRL 0x188
#define CLKCTRL_PWM_CLK_GH_CTRL 0x18c
#define CLKCTRL_PWM_CLK_IJ_CTRL 0x190
#define CLKCTRL_DEMOD_CLK_CTRL 0x200
#endif /* __MESON_S4_PERIPHERALS_H__ */

867
drivers/clk/meson/s4-pll.c Normal file
View File

@ -0,0 +1,867 @@
// SPDX-License-Identifier: (GPL-2.0-only OR MIT)
/*
* Amlogic S4 PLL Clock Controller Driver
*
* Copyright (c) 2022-2023 Amlogic, inc. All rights reserved
* Author: Yu Tu <yu.tu@amlogic.com>
*/
#include <linux/clk-provider.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include "clk-mpll.h"
#include "clk-pll.h"
#include "clk-regmap.h"
#include "s4-pll.h"
#include "meson-clkc-utils.h"
#include <dt-bindings/clock/amlogic,s4-pll-clkc.h>
static DEFINE_SPINLOCK(meson_clk_lock);
/*
* These clock are a fixed value (fixed_pll is 2GHz) that is initialized by ROMcode.
* The chip was changed fixed pll for security reasons. Fixed PLL registers are not writable
* in the kernel phase. Write of fixed PLL-related register will cause the system to crash.
* Meanwhile, these clock won't ever change at runtime.
* For the above reasons, we can only use ro_ops for fixed PLL related clocks.
*/
static struct clk_regmap s4_fixed_pll_dco = {
.data = &(struct meson_clk_pll_data){
.en = {
.reg_off = ANACTRL_FIXPLL_CTRL0,
.shift = 28,
.width = 1,
},
.m = {
.reg_off = ANACTRL_FIXPLL_CTRL0,
.shift = 0,
.width = 8,
},
.n = {
.reg_off = ANACTRL_FIXPLL_CTRL0,
.shift = 10,
.width = 5,
},
.l = {
.reg_off = ANACTRL_FIXPLL_CTRL0,
.shift = 31,
.width = 1,
},
.rst = {
.reg_off = ANACTRL_FIXPLL_CTRL0,
.shift = 29,
.width = 1,
},
},
.hw.init = &(struct clk_init_data){
.name = "fixed_pll_dco",
.ops = &meson_clk_pll_ro_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", }
},
.num_parents = 1,
},
};
static struct clk_regmap s4_fixed_pll = {
.data = &(struct clk_regmap_div_data){
.offset = ANACTRL_FIXPLL_CTRL0,
.shift = 16,
.width = 2,
.flags = CLK_DIVIDER_POWER_OF_TWO,
},
.hw.init = &(struct clk_init_data){
.name = "fixed_pll",
.ops = &clk_regmap_divider_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fixed_pll_dco.hw
},
.num_parents = 1,
/*
* This clock won't ever change at runtime so
* CLK_SET_RATE_PARENT is not required
*/
},
};
static struct clk_fixed_factor s4_fclk_div2_div = {
.mult = 1,
.div = 2,
.hw.init = &(struct clk_init_data){
.name = "fclk_div2_div",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw },
.num_parents = 1,
},
};
static struct clk_regmap s4_fclk_div2 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_FIXPLL_CTRL1,
.bit_idx = 24,
},
.hw.init = &(struct clk_init_data){
.name = "fclk_div2",
.ops = &clk_regmap_gate_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fclk_div2_div.hw
},
.num_parents = 1,
},
};
static struct clk_fixed_factor s4_fclk_div3_div = {
.mult = 1,
.div = 3,
.hw.init = &(struct clk_init_data){
.name = "fclk_div3_div",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw },
.num_parents = 1,
},
};
static struct clk_regmap s4_fclk_div3 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_FIXPLL_CTRL1,
.bit_idx = 20,
},
.hw.init = &(struct clk_init_data){
.name = "fclk_div3",
.ops = &clk_regmap_gate_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fclk_div3_div.hw
},
.num_parents = 1,
},
};
static struct clk_fixed_factor s4_fclk_div4_div = {
.mult = 1,
.div = 4,
.hw.init = &(struct clk_init_data){
.name = "fclk_div4_div",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw },
.num_parents = 1,
},
};
static struct clk_regmap s4_fclk_div4 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_FIXPLL_CTRL1,
.bit_idx = 21,
},
.hw.init = &(struct clk_init_data){
.name = "fclk_div4",
.ops = &clk_regmap_gate_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fclk_div4_div.hw
},
.num_parents = 1,
},
};
static struct clk_fixed_factor s4_fclk_div5_div = {
.mult = 1,
.div = 5,
.hw.init = &(struct clk_init_data){
.name = "fclk_div5_div",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw },
.num_parents = 1,
},
};
static struct clk_regmap s4_fclk_div5 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_FIXPLL_CTRL1,
.bit_idx = 22,
},
.hw.init = &(struct clk_init_data){
.name = "fclk_div5",
.ops = &clk_regmap_gate_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fclk_div5_div.hw
},
.num_parents = 1,
},
};
static struct clk_fixed_factor s4_fclk_div7_div = {
.mult = 1,
.div = 7,
.hw.init = &(struct clk_init_data){
.name = "fclk_div7_div",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_fixed_pll.hw },
.num_parents = 1,
},
};
static struct clk_regmap s4_fclk_div7 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_FIXPLL_CTRL1,
.bit_idx = 23,
},
.hw.init = &(struct clk_init_data){
.name = "fclk_div7",
.ops = &clk_regmap_gate_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fclk_div7_div.hw
},
.num_parents = 1,
},
};
static struct clk_fixed_factor s4_fclk_div2p5_div = {
.mult = 2,
.div = 5,
.hw.init = &(struct clk_init_data){
.name = "fclk_div2p5_div",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fixed_pll.hw
},
.num_parents = 1,
},
};
static struct clk_regmap s4_fclk_div2p5 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_FIXPLL_CTRL1,
.bit_idx = 25,
},
.hw.init = &(struct clk_init_data){
.name = "fclk_div2p5",
.ops = &clk_regmap_gate_ro_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fclk_div2p5_div.hw
},
.num_parents = 1,
},
};
static const struct pll_mult_range s4_gp0_pll_mult_range = {
.min = 125,
.max = 250,
};
/*
* Internal gp0 pll emulation configuration parameters
*/
static const struct reg_sequence s4_gp0_init_regs[] = {
{ .reg = ANACTRL_GP0PLL_CTRL1, .def = 0x00000000 },
{ .reg = ANACTRL_GP0PLL_CTRL2, .def = 0x00000000 },
{ .reg = ANACTRL_GP0PLL_CTRL3, .def = 0x48681c00 },
{ .reg = ANACTRL_GP0PLL_CTRL4, .def = 0x88770290 },
{ .reg = ANACTRL_GP0PLL_CTRL5, .def = 0x39272000 },
{ .reg = ANACTRL_GP0PLL_CTRL6, .def = 0x56540000 }
};
static struct clk_regmap s4_gp0_pll_dco = {
.data = &(struct meson_clk_pll_data){
.en = {
.reg_off = ANACTRL_GP0PLL_CTRL0,
.shift = 28,
.width = 1,
},
.m = {
.reg_off = ANACTRL_GP0PLL_CTRL0,
.shift = 0,
.width = 8,
},
.n = {
.reg_off = ANACTRL_GP0PLL_CTRL0,
.shift = 10,
.width = 5,
},
.l = {
.reg_off = ANACTRL_GP0PLL_CTRL0,
.shift = 31,
.width = 1,
},
.rst = {
.reg_off = ANACTRL_GP0PLL_CTRL0,
.shift = 29,
.width = 1,
},
.range = &s4_gp0_pll_mult_range,
.init_regs = s4_gp0_init_regs,
.init_count = ARRAY_SIZE(s4_gp0_init_regs),
},
.hw.init = &(struct clk_init_data){
.name = "gp0_pll_dco",
.ops = &meson_clk_pll_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", }
},
.num_parents = 1,
},
};
static struct clk_regmap s4_gp0_pll = {
.data = &(struct clk_regmap_div_data){
.offset = ANACTRL_GP0PLL_CTRL0,
.shift = 16,
.width = 3,
.flags = (CLK_DIVIDER_POWER_OF_TWO |
CLK_DIVIDER_ROUND_CLOSEST),
},
.hw.init = &(struct clk_init_data){
.name = "gp0_pll",
.ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_gp0_pll_dco.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
/*
* Internal hifi pll emulation configuration parameters
*/
static const struct reg_sequence s4_hifi_init_regs[] = {
{ .reg = ANACTRL_HIFIPLL_CTRL1, .def = 0x00010e56 },
{ .reg = ANACTRL_HIFIPLL_CTRL2, .def = 0x00000000 },
{ .reg = ANACTRL_HIFIPLL_CTRL3, .def = 0x6a285c00 },
{ .reg = ANACTRL_HIFIPLL_CTRL4, .def = 0x65771290 },
{ .reg = ANACTRL_HIFIPLL_CTRL5, .def = 0x39272000 },
{ .reg = ANACTRL_HIFIPLL_CTRL6, .def = 0x56540000 }
};
static struct clk_regmap s4_hifi_pll_dco = {
.data = &(struct meson_clk_pll_data){
.en = {
.reg_off = ANACTRL_HIFIPLL_CTRL0,
.shift = 28,
.width = 1,
},
.m = {
.reg_off = ANACTRL_HIFIPLL_CTRL0,
.shift = 0,
.width = 8,
},
.n = {
.reg_off = ANACTRL_HIFIPLL_CTRL0,
.shift = 10,
.width = 5,
},
.l = {
.reg_off = ANACTRL_HIFIPLL_CTRL0,
.shift = 31,
.width = 1,
},
.rst = {
.reg_off = ANACTRL_HIFIPLL_CTRL0,
.shift = 29,
.width = 1,
},
.range = &s4_gp0_pll_mult_range,
.init_regs = s4_hifi_init_regs,
.init_count = ARRAY_SIZE(s4_hifi_init_regs),
.flags = CLK_MESON_PLL_ROUND_CLOSEST,
},
.hw.init = &(struct clk_init_data){
.name = "hifi_pll_dco",
.ops = &meson_clk_pll_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", }
},
.num_parents = 1,
},
};
static struct clk_regmap s4_hifi_pll = {
.data = &(struct clk_regmap_div_data){
.offset = ANACTRL_HIFIPLL_CTRL0,
.shift = 16,
.width = 2,
.flags = (CLK_DIVIDER_POWER_OF_TWO |
CLK_DIVIDER_ROUND_CLOSEST),
},
.hw.init = &(struct clk_init_data){
.name = "hifi_pll",
.ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_hifi_pll_dco.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap s4_hdmi_pll_dco = {
.data = &(struct meson_clk_pll_data){
.en = {
.reg_off = ANACTRL_HDMIPLL_CTRL0,
.shift = 28,
.width = 1,
},
.m = {
.reg_off = ANACTRL_HDMIPLL_CTRL0,
.shift = 0,
.width = 8,
},
.n = {
.reg_off = ANACTRL_HDMIPLL_CTRL0,
.shift = 10,
.width = 5,
},
.l = {
.reg_off = ANACTRL_HDMIPLL_CTRL0,
.shift = 31,
.width = 1,
},
.rst = {
.reg_off = ANACTRL_HDMIPLL_CTRL0,
.shift = 29,
.width = 1,
},
.range = &s4_gp0_pll_mult_range,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll_dco",
.ops = &meson_clk_pll_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", }
},
.num_parents = 1,
},
};
static struct clk_regmap s4_hdmi_pll_od = {
.data = &(struct clk_regmap_div_data){
.offset = ANACTRL_HDMIPLL_CTRL0,
.shift = 16,
.width = 4,
.flags = CLK_DIVIDER_POWER_OF_TWO,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll_od",
.ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_hdmi_pll_dco.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_regmap s4_hdmi_pll = {
.data = &(struct clk_regmap_div_data){
.offset = ANACTRL_HDMIPLL_CTRL0,
.shift = 20,
.width = 2,
.flags = CLK_DIVIDER_POWER_OF_TWO,
},
.hw.init = &(struct clk_init_data){
.name = "hdmi_pll",
.ops = &clk_regmap_divider_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_hdmi_pll_od.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static struct clk_fixed_factor s4_mpll_50m_div = {
.mult = 1,
.div = 80,
.hw.init = &(struct clk_init_data){
.name = "mpll_50m_div",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fixed_pll_dco.hw
},
.num_parents = 1,
},
};
static struct clk_regmap s4_mpll_50m = {
.data = &(struct clk_regmap_mux_data){
.offset = ANACTRL_FIXPLL_CTRL3,
.mask = 0x1,
.shift = 5,
},
.hw.init = &(struct clk_init_data){
.name = "mpll_50m",
.ops = &clk_regmap_mux_ro_ops,
.parent_data = (const struct clk_parent_data []) {
{ .fw_name = "xtal", },
{ .hw = &s4_mpll_50m_div.hw },
},
.num_parents = 2,
},
};
static struct clk_fixed_factor s4_mpll_prediv = {
.mult = 1,
.div = 2,
.hw.init = &(struct clk_init_data){
.name = "mpll_prediv",
.ops = &clk_fixed_factor_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_fixed_pll_dco.hw
},
.num_parents = 1,
},
};
static const struct reg_sequence s4_mpll0_init_regs[] = {
{ .reg = ANACTRL_MPLL_CTRL2, .def = 0x40000033 }
};
static struct clk_regmap s4_mpll0_div = {
.data = &(struct meson_clk_mpll_data){
.sdm = {
.reg_off = ANACTRL_MPLL_CTRL1,
.shift = 0,
.width = 14,
},
.sdm_en = {
.reg_off = ANACTRL_MPLL_CTRL1,
.shift = 30,
.width = 1,
},
.n2 = {
.reg_off = ANACTRL_MPLL_CTRL1,
.shift = 20,
.width = 9,
},
.ssen = {
.reg_off = ANACTRL_MPLL_CTRL1,
.shift = 29,
.width = 1,
},
.lock = &meson_clk_lock,
.init_regs = s4_mpll0_init_regs,
.init_count = ARRAY_SIZE(s4_mpll0_init_regs),
},
.hw.init = &(struct clk_init_data){
.name = "mpll0_div",
.ops = &meson_clk_mpll_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_mpll_prediv.hw
},
.num_parents = 1,
},
};
static struct clk_regmap s4_mpll0 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_MPLL_CTRL1,
.bit_idx = 31,
},
.hw.init = &(struct clk_init_data){
.name = "mpll0",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_mpll0_div.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static const struct reg_sequence s4_mpll1_init_regs[] = {
{ .reg = ANACTRL_MPLL_CTRL4, .def = 0x40000033 }
};
static struct clk_regmap s4_mpll1_div = {
.data = &(struct meson_clk_mpll_data){
.sdm = {
.reg_off = ANACTRL_MPLL_CTRL3,
.shift = 0,
.width = 14,
},
.sdm_en = {
.reg_off = ANACTRL_MPLL_CTRL3,
.shift = 30,
.width = 1,
},
.n2 = {
.reg_off = ANACTRL_MPLL_CTRL3,
.shift = 20,
.width = 9,
},
.ssen = {
.reg_off = ANACTRL_MPLL_CTRL3,
.shift = 29,
.width = 1,
},
.lock = &meson_clk_lock,
.init_regs = s4_mpll1_init_regs,
.init_count = ARRAY_SIZE(s4_mpll1_init_regs),
},
.hw.init = &(struct clk_init_data){
.name = "mpll1_div",
.ops = &meson_clk_mpll_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_mpll_prediv.hw
},
.num_parents = 1,
},
};
static struct clk_regmap s4_mpll1 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_MPLL_CTRL3,
.bit_idx = 31,
},
.hw.init = &(struct clk_init_data){
.name = "mpll1",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_mpll1_div.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static const struct reg_sequence s4_mpll2_init_regs[] = {
{ .reg = ANACTRL_MPLL_CTRL6, .def = 0x40000033 }
};
static struct clk_regmap s4_mpll2_div = {
.data = &(struct meson_clk_mpll_data){
.sdm = {
.reg_off = ANACTRL_MPLL_CTRL5,
.shift = 0,
.width = 14,
},
.sdm_en = {
.reg_off = ANACTRL_MPLL_CTRL5,
.shift = 30,
.width = 1,
},
.n2 = {
.reg_off = ANACTRL_MPLL_CTRL5,
.shift = 20,
.width = 9,
},
.ssen = {
.reg_off = ANACTRL_MPLL_CTRL5,
.shift = 29,
.width = 1,
},
.lock = &meson_clk_lock,
.init_regs = s4_mpll2_init_regs,
.init_count = ARRAY_SIZE(s4_mpll2_init_regs),
},
.hw.init = &(struct clk_init_data){
.name = "mpll2_div",
.ops = &meson_clk_mpll_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_mpll_prediv.hw
},
.num_parents = 1,
},
};
static struct clk_regmap s4_mpll2 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_MPLL_CTRL5,
.bit_idx = 31,
},
.hw.init = &(struct clk_init_data){
.name = "mpll2",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_mpll2_div.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
static const struct reg_sequence s4_mpll3_init_regs[] = {
{ .reg = ANACTRL_MPLL_CTRL8, .def = 0x40000033 }
};
static struct clk_regmap s4_mpll3_div = {
.data = &(struct meson_clk_mpll_data){
.sdm = {
.reg_off = ANACTRL_MPLL_CTRL7,
.shift = 0,
.width = 14,
},
.sdm_en = {
.reg_off = ANACTRL_MPLL_CTRL7,
.shift = 30,
.width = 1,
},
.n2 = {
.reg_off = ANACTRL_MPLL_CTRL7,
.shift = 20,
.width = 9,
},
.ssen = {
.reg_off = ANACTRL_MPLL_CTRL7,
.shift = 29,
.width = 1,
},
.lock = &meson_clk_lock,
.init_regs = s4_mpll3_init_regs,
.init_count = ARRAY_SIZE(s4_mpll3_init_regs),
},
.hw.init = &(struct clk_init_data){
.name = "mpll3_div",
.ops = &meson_clk_mpll_ops,
.parent_hws = (const struct clk_hw *[]) {
&s4_mpll_prediv.hw
},
.num_parents = 1,
},
};
static struct clk_regmap s4_mpll3 = {
.data = &(struct clk_regmap_gate_data){
.offset = ANACTRL_MPLL_CTRL7,
.bit_idx = 31,
},
.hw.init = &(struct clk_init_data){
.name = "mpll3",
.ops = &clk_regmap_gate_ops,
.parent_hws = (const struct clk_hw *[]) { &s4_mpll3_div.hw },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};
/* Array of all clocks provided by this provider */
static struct clk_hw *s4_pll_hw_clks[] = {
[CLKID_FIXED_PLL_DCO] = &s4_fixed_pll_dco.hw,
[CLKID_FIXED_PLL] = &s4_fixed_pll.hw,
[CLKID_FCLK_DIV2_DIV] = &s4_fclk_div2_div.hw,
[CLKID_FCLK_DIV2] = &s4_fclk_div2.hw,
[CLKID_FCLK_DIV3_DIV] = &s4_fclk_div3_div.hw,
[CLKID_FCLK_DIV3] = &s4_fclk_div3.hw,
[CLKID_FCLK_DIV4_DIV] = &s4_fclk_div4_div.hw,
[CLKID_FCLK_DIV4] = &s4_fclk_div4.hw,
[CLKID_FCLK_DIV5_DIV] = &s4_fclk_div5_div.hw,
[CLKID_FCLK_DIV5] = &s4_fclk_div5.hw,
[CLKID_FCLK_DIV7_DIV] = &s4_fclk_div7_div.hw,
[CLKID_FCLK_DIV7] = &s4_fclk_div7.hw,
[CLKID_FCLK_DIV2P5_DIV] = &s4_fclk_div2p5_div.hw,
[CLKID_FCLK_DIV2P5] = &s4_fclk_div2p5.hw,
[CLKID_GP0_PLL_DCO] = &s4_gp0_pll_dco.hw,
[CLKID_GP0_PLL] = &s4_gp0_pll.hw,
[CLKID_HIFI_PLL_DCO] = &s4_hifi_pll_dco.hw,
[CLKID_HIFI_PLL] = &s4_hifi_pll.hw,
[CLKID_HDMI_PLL_DCO] = &s4_hdmi_pll_dco.hw,
[CLKID_HDMI_PLL_OD] = &s4_hdmi_pll_od.hw,
[CLKID_HDMI_PLL] = &s4_hdmi_pll.hw,
[CLKID_MPLL_50M_DIV] = &s4_mpll_50m_div.hw,
[CLKID_MPLL_50M] = &s4_mpll_50m.hw,
[CLKID_MPLL_PREDIV] = &s4_mpll_prediv.hw,
[CLKID_MPLL0_DIV] = &s4_mpll0_div.hw,
[CLKID_MPLL0] = &s4_mpll0.hw,
[CLKID_MPLL1_DIV] = &s4_mpll1_div.hw,
[CLKID_MPLL1] = &s4_mpll1.hw,
[CLKID_MPLL2_DIV] = &s4_mpll2_div.hw,
[CLKID_MPLL2] = &s4_mpll2.hw,
[CLKID_MPLL3_DIV] = &s4_mpll3_div.hw,
[CLKID_MPLL3] = &s4_mpll3.hw,
};
static struct clk_regmap *const s4_pll_clk_regmaps[] = {
&s4_fixed_pll_dco,
&s4_fixed_pll,
&s4_fclk_div2,
&s4_fclk_div3,
&s4_fclk_div4,
&s4_fclk_div5,
&s4_fclk_div7,
&s4_fclk_div2p5,
&s4_gp0_pll_dco,
&s4_gp0_pll,
&s4_hifi_pll_dco,
&s4_hifi_pll,
&s4_hdmi_pll_dco,
&s4_hdmi_pll_od,
&s4_hdmi_pll,
&s4_mpll_50m,
&s4_mpll0_div,
&s4_mpll0,
&s4_mpll1_div,
&s4_mpll1,
&s4_mpll2_div,
&s4_mpll2,
&s4_mpll3_div,
&s4_mpll3,
};
static const struct reg_sequence s4_init_regs[] = {
{ .reg = ANACTRL_MPLL_CTRL0, .def = 0x00000543 },
};
static struct regmap_config clkc_regmap_config = {
.reg_bits = 32,
.val_bits = 32,
.reg_stride = 4,
};
static struct meson_clk_hw_data s4_pll_clks = {
.hws = s4_pll_hw_clks,
.num = ARRAY_SIZE(s4_pll_hw_clks),
};
static int meson_s4_pll_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct regmap *regmap;
void __iomem *base;
int ret, i;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return dev_err_probe(dev, PTR_ERR(base),
"can't ioremap resource\n");
regmap = devm_regmap_init_mmio(dev, base, &clkc_regmap_config);
if (IS_ERR(regmap))
return dev_err_probe(dev, PTR_ERR(regmap),
"can't init regmap mmio region\n");
ret = regmap_multi_reg_write(regmap, s4_init_regs, ARRAY_SIZE(s4_init_regs));
if (ret)
return dev_err_probe(dev, ret,
"Failed to init registers\n");
/* Populate regmap for the regmap backed clocks */
for (i = 0; i < ARRAY_SIZE(s4_pll_clk_regmaps); i++)
s4_pll_clk_regmaps[i]->map = regmap;
/* Register clocks */
for (i = 0; i < s4_pll_clks.num; i++) {
/* array might be sparse */
if (!s4_pll_clks.hws[i])
continue;
ret = devm_clk_hw_register(dev, s4_pll_clks.hws[i]);
if (ret)
return dev_err_probe(dev, ret,
"clock[%d] registration failed\n", i);
}
return devm_of_clk_add_hw_provider(dev, meson_clk_hw_get,
&s4_pll_clks);
}
static const struct of_device_id clkc_match_table[] = {
{
.compatible = "amlogic,s4-pll-clkc",
},
{}
};
static struct platform_driver s4_driver = {
.probe = meson_s4_pll_probe,
.driver = {
.name = "s4-pll-clkc",
.of_match_table = clkc_match_table,
},
};
module_platform_driver(s4_driver);
MODULE_AUTHOR("Yu Tu <yu.tu@amlogic.com>");
MODULE_LICENSE("GPL");

View File

@ -0,0 +1,38 @@
/* SPDX-License-Identifier: (GPL-2.0-only OR MIT) */
/*
* Copyright (c) 2022-2023 Amlogic, inc. All rights reserved
* Author: Yu Tu <yu.tu@amlogic.com>
*/
#ifndef __MESON_S4_PLL_H__
#define __MESON_S4_PLL_H__
#define ANACTRL_FIXPLL_CTRL0 0x040
#define ANACTRL_FIXPLL_CTRL1 0x044
#define ANACTRL_FIXPLL_CTRL3 0x04c
#define ANACTRL_GP0PLL_CTRL0 0x080
#define ANACTRL_GP0PLL_CTRL1 0x084
#define ANACTRL_GP0PLL_CTRL2 0x088
#define ANACTRL_GP0PLL_CTRL3 0x08c
#define ANACTRL_GP0PLL_CTRL4 0x090
#define ANACTRL_GP0PLL_CTRL5 0x094
#define ANACTRL_GP0PLL_CTRL6 0x098
#define ANACTRL_HIFIPLL_CTRL0 0x100
#define ANACTRL_HIFIPLL_CTRL1 0x104
#define ANACTRL_HIFIPLL_CTRL2 0x108
#define ANACTRL_HIFIPLL_CTRL3 0x10c
#define ANACTRL_HIFIPLL_CTRL4 0x110
#define ANACTRL_HIFIPLL_CTRL5 0x114
#define ANACTRL_HIFIPLL_CTRL6 0x118
#define ANACTRL_MPLL_CTRL0 0x180
#define ANACTRL_MPLL_CTRL1 0x184
#define ANACTRL_MPLL_CTRL2 0x188
#define ANACTRL_MPLL_CTRL3 0x18c
#define ANACTRL_MPLL_CTRL4 0x190
#define ANACTRL_MPLL_CTRL5 0x194
#define ANACTRL_MPLL_CTRL6 0x198
#define ANACTRL_MPLL_CTRL7 0x19c
#define ANACTRL_MPLL_CTRL8 0x1a0
#define ANACTRL_HDMIPLL_CTRL0 0x1c0
#endif /* __MESON_S4_PLL_H__ */

View File

@ -131,6 +131,7 @@ config IPQ_APSS_6018
tristate "IPQ APSS Clock Controller"
select IPQ_APSS_PLL
depends on QCOM_APCS_IPC || COMPILE_TEST
depends on QCOM_SMEM
help
Support for APSS clock controller on IPQ platforms. The
APSS clock controller manages the Mux and enable block that feeds the
@ -764,6 +765,13 @@ config SM_CAMCC_8450
Support for the camera clock controller on SM8450 devices.
Say Y if you want to support camera devices and camera functionality.
config SM_CAMCC_8550
tristate "SM8550 Camera Clock Controller"
select SM_GCC_8550
help
Support for the camera clock controller on SM8550 devices.
Say Y if you want to support camera devices and camera functionality.
config SM_DISPCC_6115
tristate "SM6115 Display Clock Controller"
depends on ARM64 || COMPILE_TEST
@ -834,6 +842,15 @@ config SM_DISPCC_8550
Say Y if you want to support display devices and functionality such as
splash screen.
config SM_GCC_4450
tristate "SM4450 Global Clock Controller"
depends on ARM64 || COMPILE_TEST
select QCOM_GDSC
help
Support for the global clock controller on SM4450 devices.
Say Y if you want to use peripheral devices such as UART, SPI,
I2C, USB, SD/UFS, PCIe, etc.
config SM_GCC_6115
tristate "SM6115 and SM4250 Global Clock Controller"
depends on ARM64 || COMPILE_TEST

View File

@ -102,6 +102,7 @@ obj-$(CONFIG_SDX_GCC_75) += gcc-sdx75.o
obj-$(CONFIG_SM_CAMCC_6350) += camcc-sm6350.o
obj-$(CONFIG_SM_CAMCC_8250) += camcc-sm8250.o
obj-$(CONFIG_SM_CAMCC_8450) += camcc-sm8450.o
obj-$(CONFIG_SM_CAMCC_8550) += camcc-sm8550.o
obj-$(CONFIG_SM_DISPCC_6115) += dispcc-sm6115.o
obj-$(CONFIG_SM_DISPCC_6125) += dispcc-sm6125.o
obj-$(CONFIG_SM_DISPCC_6350) += dispcc-sm6350.o
@ -109,6 +110,7 @@ obj-$(CONFIG_SM_DISPCC_6375) += dispcc-sm6375.o
obj-$(CONFIG_SM_DISPCC_8250) += dispcc-sm8250.o
obj-$(CONFIG_SM_DISPCC_8450) += dispcc-sm8450.o
obj-$(CONFIG_SM_DISPCC_8550) += dispcc-sm8550.o
obj-$(CONFIG_SM_GCC_4450) += gcc-sm4450.o
obj-$(CONFIG_SM_GCC_6115) += gcc-sm6115.o
obj-$(CONFIG_SM_GCC_6125) += gcc-sm6125.o
obj-$(CONFIG_SM_GCC_6350) += gcc-sm6350.o

View File

@ -68,13 +68,13 @@ static struct clk_alpha_pll ipq_pll_stromer_plus = {
.fw_name = "xo",
},
.num_parents = 1,
.ops = &clk_alpha_pll_stromer_ops,
.ops = &clk_alpha_pll_stromer_plus_ops,
},
},
};
static const struct alpha_pll_config ipq5332_pll_config = {
.l = 0x3e,
.l = 0x2d,
.config_ctl_val = 0x4001075b,
.config_ctl_hi_val = 0x304,
.main_output_mask = BIT(0),

View File

@ -9,8 +9,11 @@
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include <linux/module.h>
#include <linux/clk.h>
#include <linux/soc/qcom/smem.h>
#include <dt-bindings/clock/qcom,apss-ipq.h>
#include <dt-bindings/arm/qcom,ids.h>
#include "common.h"
#include "clk-regmap.h"
@ -20,16 +23,19 @@
enum {
P_XO,
P_GPLL0,
P_APSS_PLL_EARLY,
};
static const struct clk_parent_data parents_apcs_alias0_clk_src[] = {
{ .fw_name = "xo" },
{ .fw_name = "gpll0" },
{ .fw_name = "pll" },
};
static const struct parent_map parents_apcs_alias0_clk_src_map[] = {
{ P_XO, 0 },
{ P_GPLL0, 4 },
{ P_APSS_PLL_EARLY, 5 },
};
@ -81,15 +87,68 @@ static const struct qcom_cc_desc apss_ipq6018_desc = {
.num_clks = ARRAY_SIZE(apss_ipq6018_clks),
};
static int cpu_clk_notifier_fn(struct notifier_block *nb, unsigned long action,
void *data)
{
struct clk_hw *hw;
u8 index;
int err;
if (action == PRE_RATE_CHANGE)
index = P_GPLL0;
else if (action == POST_RATE_CHANGE || action == ABORT_RATE_CHANGE)
index = P_APSS_PLL_EARLY;
else
return NOTIFY_OK;
hw = &apcs_alias0_clk_src.clkr.hw;
err = clk_rcg2_mux_closest_ops.set_parent(hw, index);
return notifier_from_errno(err);
}
static int apss_ipq6018_probe(struct platform_device *pdev)
{
struct clk_hw *hw = &apcs_alias0_clk_src.clkr.hw;
struct notifier_block *cpu_clk_notifier;
struct regmap *regmap;
u32 soc_id;
int ret;
ret = qcom_smem_get_soc_id(&soc_id);
if (ret)
return ret;
regmap = dev_get_regmap(pdev->dev.parent, NULL);
if (!regmap)
return -ENODEV;
return qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap);
ret = qcom_cc_really_probe(pdev, &apss_ipq6018_desc, regmap);
if (ret)
return ret;
switch (soc_id) {
/* Only below variants of IPQ53xx support scaling */
case QCOM_ID_IPQ5332:
case QCOM_ID_IPQ5322:
case QCOM_ID_IPQ5300:
cpu_clk_notifier = devm_kzalloc(&pdev->dev,
sizeof(*cpu_clk_notifier),
GFP_KERNEL);
if (!cpu_clk_notifier)
return -ENOMEM;
cpu_clk_notifier->notifier_call = cpu_clk_notifier_fn;
ret = devm_clk_notifier_register(&pdev->dev, hw->clk, cpu_clk_notifier);
if (ret)
return ret;
break;
default:
break;
}
return 0;
}
static struct platform_driver apss_ipq6018_driver = {

File diff suppressed because it is too large Load Diff

View File

@ -271,6 +271,7 @@ EXPORT_SYMBOL_GPL(clk_alpha_pll_regs);
#define LUCID_EVO_ENABLE_VOTE_RUN BIT(25)
#define LUCID_EVO_PLL_L_VAL_MASK GENMASK(15, 0)
#define LUCID_EVO_PLL_CAL_L_VAL_SHIFT 16
#define LUCID_OLE_PLL_RINGOSC_CAL_L_VAL_SHIFT 24
/* ZONDA PLL specific */
#define ZONDA_PLL_OUT_MASK 0xf
@ -2119,6 +2120,34 @@ void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regma
}
EXPORT_SYMBOL_GPL(clk_lucid_evo_pll_configure);
void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config)
{
u32 lval = config->l;
lval |= TRION_PLL_CAL_VAL << LUCID_EVO_PLL_CAL_L_VAL_SHIFT;
lval |= TRION_PLL_CAL_VAL << LUCID_OLE_PLL_RINGOSC_CAL_L_VAL_SHIFT;
clk_alpha_pll_write_config(regmap, PLL_L_VAL(pll), lval);
clk_alpha_pll_write_config(regmap, PLL_ALPHA_VAL(pll), config->alpha);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL(pll), config->config_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U(pll), config->config_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_CONFIG_CTL_U1(pll), config->config_ctl_hi1_val);
clk_alpha_pll_write_config(regmap, PLL_USER_CTL(pll), config->user_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_USER_CTL_U(pll), config->user_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL(pll), config->test_ctl_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U(pll), config->test_ctl_hi_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U1(pll), config->test_ctl_hi1_val);
clk_alpha_pll_write_config(regmap, PLL_TEST_CTL_U2(pll), config->test_ctl_hi2_val);
/* Disable PLL output */
regmap_update_bits(regmap, PLL_MODE(pll), PLL_OUTCTRL, 0);
/* Set operation mode to STANDBY and de-assert the reset */
regmap_write(regmap, PLL_OPMODE(pll), PLL_STANDBY);
regmap_update_bits(regmap, PLL_MODE(pll), PLL_RESET_N, PLL_RESET_N);
}
EXPORT_SYMBOL_GPL(clk_lucid_ole_pll_configure);
static int alpha_pll_lucid_evo_enable(struct clk_hw *hw)
{
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
@ -2479,3 +2508,66 @@ const struct clk_ops clk_alpha_pll_stromer_ops = {
.set_rate = clk_alpha_pll_stromer_set_rate,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_ops);
static int clk_alpha_pll_stromer_plus_set_rate(struct clk_hw *hw,
unsigned long rate,
unsigned long prate)
{
struct clk_alpha_pll *pll = to_clk_alpha_pll(hw);
u32 l, alpha_width = pll_alpha_width(pll);
int ret, pll_mode;
u64 a;
rate = alpha_pll_round_rate(rate, prate, &l, &a, alpha_width);
ret = regmap_read(pll->clkr.regmap, PLL_MODE(pll), &pll_mode);
if (ret)
return ret;
regmap_write(pll->clkr.regmap, PLL_MODE(pll), 0);
/* Delay of 2 output clock ticks required until output is disabled */
udelay(1);
regmap_write(pll->clkr.regmap, PLL_L_VAL(pll), l);
if (alpha_width > ALPHA_BITWIDTH)
a <<= alpha_width - ALPHA_BITWIDTH;
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL(pll), a);
regmap_write(pll->clkr.regmap, PLL_ALPHA_VAL_U(pll),
a >> ALPHA_BITWIDTH);
regmap_write(pll->clkr.regmap, PLL_MODE(pll), PLL_BYPASSNL);
/* Wait five micro seconds or more */
udelay(5);
regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_RESET_N,
PLL_RESET_N);
/* The lock time should be less than 50 micro seconds worst case */
usleep_range(50, 60);
ret = wait_for_pll_enable_lock(pll);
if (ret) {
pr_err("Wait for PLL enable lock failed [%s] %d\n",
clk_hw_get_name(hw), ret);
return ret;
}
if (pll_mode & PLL_OUTCTRL)
regmap_update_bits(pll->clkr.regmap, PLL_MODE(pll), PLL_OUTCTRL,
PLL_OUTCTRL);
return 0;
}
const struct clk_ops clk_alpha_pll_stromer_plus_ops = {
.prepare = clk_alpha_pll_enable,
.unprepare = clk_alpha_pll_disable,
.is_enabled = clk_alpha_pll_is_enabled,
.recalc_rate = clk_alpha_pll_recalc_rate,
.determine_rate = clk_alpha_pll_stromer_determine_rate,
.set_rate = clk_alpha_pll_stromer_plus_set_rate,
};
EXPORT_SYMBOL_GPL(clk_alpha_pll_stromer_plus_ops);

View File

@ -152,6 +152,7 @@ extern const struct clk_ops clk_alpha_pll_postdiv_ops;
extern const struct clk_ops clk_alpha_pll_huayra_ops;
extern const struct clk_ops clk_alpha_pll_postdiv_ro_ops;
extern const struct clk_ops clk_alpha_pll_stromer_ops;
extern const struct clk_ops clk_alpha_pll_stromer_plus_ops;
extern const struct clk_ops clk_alpha_pll_fabia_ops;
extern const struct clk_ops clk_alpha_pll_fixed_fabia_ops;
@ -199,6 +200,8 @@ void clk_zonda_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config);
void clk_lucid_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config);
void clk_lucid_ole_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config);
void clk_rivian_evo_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,
const struct alpha_pll_config *config);
void clk_stromer_pll_configure(struct clk_alpha_pll *pll, struct regmap *regmap,

View File

@ -250,13 +250,11 @@ static int qcom_msm8996_cbf_icc_register(struct platform_device *pdev, struct cl
return 0;
}
static int qcom_msm8996_cbf_icc_remove(struct platform_device *pdev)
static void qcom_msm8996_cbf_icc_remove(struct platform_device *pdev)
{
struct icc_provider *provider = platform_get_drvdata(pdev);
icc_clk_unregister(provider);
return 0;
}
#define qcom_msm8996_cbf_icc_sync_state icc_sync_state
#else
@ -266,7 +264,7 @@ static int qcom_msm8996_cbf_icc_register(struct platform_device *pdev, struct c
return 0;
}
#define qcom_msm8996_cbf_icc_remove(pdev) (0)
#define qcom_msm8996_cbf_icc_remove(pdev) { }
#define qcom_msm8996_cbf_icc_sync_state NULL
#endif
@ -340,9 +338,9 @@ static int qcom_msm8996_cbf_probe(struct platform_device *pdev)
return qcom_msm8996_cbf_icc_register(pdev, &cbf_mux.clkr.hw);
}
static int qcom_msm8996_cbf_remove(struct platform_device *pdev)
static void qcom_msm8996_cbf_remove(struct platform_device *pdev)
{
return qcom_msm8996_cbf_icc_remove(pdev);
qcom_msm8996_cbf_icc_remove(pdev);
}
static const struct of_device_id qcom_msm8996_cbf_match_table[] = {
@ -354,7 +352,7 @@ MODULE_DEVICE_TABLE(of, qcom_msm8996_cbf_match_table);
static struct platform_driver qcom_msm8996_cbf_driver = {
.probe = qcom_msm8996_cbf_probe,
.remove = qcom_msm8996_cbf_remove,
.remove_new = qcom_msm8996_cbf_remove,
.driver = {
.name = "qcom-msm8996-cbf",
.of_match_table = qcom_msm8996_cbf_match_table,

View File

@ -44,6 +44,10 @@ static void __clk_hfpll_init_once(struct clk_hw *hw)
regmap_write(regmap, hd->user_reg, regval);
}
/* Write L_VAL from conf if it exist */
if (hd->l_val)
regmap_write(regmap, hd->l_reg, hd->l_val);
if (hd->droop_reg)
regmap_write(regmap, hd->droop_reg, hd->droop_val);

View File

@ -18,6 +18,7 @@ struct hfpll_data {
u32 status_reg;
u8 lock_bit;
u32 l_val;
u32 droop_val;
u32 config_val;
u32 user_val;

View File

@ -158,17 +158,11 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
static unsigned long
calc_rate(unsigned long rate, u32 m, u32 n, u32 mode, u32 hid_div)
{
if (hid_div) {
rate *= 2;
rate /= hid_div + 1;
}
if (hid_div)
rate = mult_frac(rate, 2, hid_div + 1);
if (mode) {
u64 tmp = rate;
tmp *= m;
do_div(tmp, n);
rate = tmp;
}
if (mode)
rate = mult_frac(rate, m, n);
return rate;
}

View File

@ -350,6 +350,7 @@ DEFINE_CLK_RPMH_VRM(ln_bb_clk3, _a2, "lnbclka3", 2);
DEFINE_CLK_RPMH_VRM(ln_bb_clk1, _a4, "lnbclka1", 4);
DEFINE_CLK_RPMH_VRM(ln_bb_clk2, _a4, "lnbclka2", 4);
DEFINE_CLK_RPMH_VRM(ln_bb_clk3, _a4, "lnbclka3", 4);
DEFINE_CLK_RPMH_VRM(ln_bb_clk2, _g4, "lnbclkg2", 4);
DEFINE_CLK_RPMH_VRM(ln_bb_clk3, _g4, "lnbclkg3", 4);
@ -717,6 +718,25 @@ static const struct clk_rpmh_desc clk_rpmh_sdx75 = {
.num_clks = ARRAY_SIZE(sdx75_rpmh_clocks),
};
static struct clk_hw *sm4450_rpmh_clocks[] = {
[RPMH_CXO_CLK] = &clk_rpmh_bi_tcxo_div4.hw,
[RPMH_CXO_CLK_A] = &clk_rpmh_bi_tcxo_div4_ao.hw,
[RPMH_LN_BB_CLK2] = &clk_rpmh_ln_bb_clk2_a4.hw,
[RPMH_LN_BB_CLK2_A] = &clk_rpmh_ln_bb_clk2_a4_ao.hw,
[RPMH_LN_BB_CLK3] = &clk_rpmh_ln_bb_clk3_a4.hw,
[RPMH_LN_BB_CLK3_A] = &clk_rpmh_ln_bb_clk3_a4_ao.hw,
[RPMH_RF_CLK1] = &clk_rpmh_rf_clk1_a.hw,
[RPMH_RF_CLK1_A] = &clk_rpmh_rf_clk1_a_ao.hw,
[RPMH_RF_CLK5] = &clk_rpmh_rf_clk5_a.hw,
[RPMH_RF_CLK5_A] = &clk_rpmh_rf_clk5_a_ao.hw,
[RPMH_IPA_CLK] = &clk_rpmh_ipa.hw,
};
static const struct clk_rpmh_desc clk_rpmh_sm4450 = {
.clks = sm4450_rpmh_clocks,
.num_clks = ARRAY_SIZE(sm4450_rpmh_clocks),
};
static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
void *data)
{
@ -810,6 +830,7 @@ static const struct of_device_id clk_rpmh_match_table[] = {
{ .compatible = "qcom,sdx55-rpmh-clk", .data = &clk_rpmh_sdx55},
{ .compatible = "qcom,sdx65-rpmh-clk", .data = &clk_rpmh_sdx65},
{ .compatible = "qcom,sdx75-rpmh-clk", .data = &clk_rpmh_sdx75},
{ .compatible = "qcom,sm4450-rpmh-clk", .data = &clk_rpmh_sm4450},
{ .compatible = "qcom,sm6350-rpmh-clk", .data = &clk_rpmh_sm6350},
{ .compatible = "qcom,sm8150-rpmh-clk", .data = &clk_rpmh_sm8150},
{ .compatible = "qcom,sm8250-rpmh-clk", .data = &clk_rpmh_sm8250},

View File

@ -574,6 +574,16 @@ static const struct clk_smd_rpm *sm_qnoc_icc_clks[] = {
&clk_smd_rpm_bus_2_snoc_clk,
};
static const struct clk_smd_rpm *qcm2290_icc_clks[] = {
&clk_smd_rpm_bimc_clk,
&clk_smd_rpm_bus_1_cnoc_clk,
&clk_smd_rpm_mmnrt_clk,
&clk_smd_rpm_mmrt_clk,
&clk_smd_rpm_qup_clk,
&clk_smd_rpm_bus_2_snoc_clk,
&clk_smd_rpm_cpuss_gnoc_clk,
};
static struct clk_smd_rpm *msm8909_clks[] = {
[RPM_SMD_QPIC_CLK] = &clk_smd_rpm_qpic_clk,
[RPM_SMD_QPIC_CLK_A] = &clk_smd_rpm_qpic_a_clk,
@ -1189,15 +1199,13 @@ static struct clk_smd_rpm *qcm2290_clks[] = {
[RPM_SMD_PKA_A_CLK] = &clk_smd_rpm_pka_a_clk,
[RPM_SMD_BIMC_GPU_CLK] = &clk_smd_rpm_bimc_gpu_clk,
[RPM_SMD_BIMC_GPU_A_CLK] = &clk_smd_rpm_bimc_gpu_a_clk,
[RPM_SMD_CPUSS_GNOC_CLK] = &clk_smd_rpm_cpuss_gnoc_clk,
[RPM_SMD_CPUSS_GNOC_A_CLK] = &clk_smd_rpm_cpuss_gnoc_a_clk,
};
static const struct rpm_smd_clk_desc rpm_clk_qcm2290 = {
.clks = qcm2290_clks,
.num_clks = ARRAY_SIZE(qcm2290_clks),
.icc_clks = sm_qnoc_icc_clks,
.num_icc_clks = ARRAY_SIZE(sm_qnoc_icc_clks)
.icc_clks = qcm2290_icc_clks,
.num_icc_clks = ARRAY_SIZE(qcm2290_icc_clks)
};
static const struct of_device_id rpm_smd_clk_match_table[] = {

View File

@ -3,8 +3,9 @@
* Copyright (c) 2023, The Linux Foundation. All rights reserved.
*/
#include <linux/clk-provider.h>
#include <linux/mod_devicetable.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <dt-bindings/clock/qcom,gcc-ipq5018.h>
@ -128,7 +129,6 @@ static struct clk_alpha_pll_postdiv gpll0 = {
},
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -143,7 +143,6 @@ static struct clk_alpha_pll_postdiv gpll2 = {
},
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -158,7 +157,6 @@ static struct clk_alpha_pll_postdiv gpll4 = {
},
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};

View File

@ -71,7 +71,6 @@ static struct clk_fixed_factor gpll0_div2 = {
&gpll0_main.clkr.hw },
.num_parents = 1,
.ops = &clk_fixed_factor_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -85,7 +84,6 @@ static struct clk_alpha_pll_postdiv gpll0 = {
&gpll0_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -114,7 +112,6 @@ static struct clk_alpha_pll_postdiv gpll2 = {
&gpll2_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -154,7 +151,6 @@ static struct clk_alpha_pll_postdiv gpll4 = {
&gpll4_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};

View File

@ -72,7 +72,6 @@ static struct clk_fixed_factor gpll0_out_main_div2 = {
&gpll0_main.clkr.hw },
.num_parents = 1,
.ops = &clk_fixed_factor_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -86,7 +85,6 @@ static struct clk_alpha_pll_postdiv gpll0 = {
&gpll0_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -161,7 +159,6 @@ static struct clk_alpha_pll_postdiv gpll6 = {
&gpll6_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -192,7 +189,6 @@ static struct clk_alpha_pll_postdiv gpll4 = {
&gpll4_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -243,7 +239,6 @@ static struct clk_alpha_pll_postdiv gpll2 = {
&gpll2_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -274,7 +269,6 @@ static struct clk_alpha_pll_postdiv nss_crypto_pll = {
&nss_crypto_pll_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -2125,6 +2119,26 @@ static struct clk_branch gcc_blsp1_qup5_spi_apps_clk = {
},
};
static struct clk_branch gcc_blsp1_qup6_i2c_apps_clk = {
.halt_reg = 0x07010,
.clkr = {
.enable_reg = 0x07010,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp1_qup6_i2c_apps_clk",
.parent_hws = (const struct clk_hw *[]){
&blsp1_qup6_i2c_apps_clk_src.clkr.hw },
.num_parents = 1,
/*
* RPM uses QUP6 I2C to communicate with the external
* PMIC so it must not be disabled.
*/
.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch gcc_blsp1_qup6_spi_apps_clk = {
.halt_reg = 0x0700c,
.clkr = {
@ -4281,6 +4295,7 @@ static struct clk_regmap *gcc_ipq6018_clks[] = {
[GCC_BLSP1_QUP4_SPI_APPS_CLK] = &gcc_blsp1_qup4_spi_apps_clk.clkr,
[GCC_BLSP1_QUP5_I2C_APPS_CLK] = &gcc_blsp1_qup5_i2c_apps_clk.clkr,
[GCC_BLSP1_QUP5_SPI_APPS_CLK] = &gcc_blsp1_qup5_spi_apps_clk.clkr,
[GCC_BLSP1_QUP6_I2C_APPS_CLK] = &gcc_blsp1_qup6_i2c_apps_clk.clkr,
[GCC_BLSP1_QUP6_SPI_APPS_CLK] = &gcc_blsp1_qup6_spi_apps_clk.clkr,
[GCC_BLSP1_UART1_APPS_CLK] = &gcc_blsp1_uart1_apps_clk.clkr,
[GCC_BLSP1_UART2_APPS_CLK] = &gcc_blsp1_uart2_apps_clk.clkr,

View File

@ -75,7 +75,6 @@ static struct clk_fixed_factor gpll0_out_main_div2 = {
&gpll0_main.clkr.hw },
.num_parents = 1,
.ops = &clk_fixed_factor_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -121,7 +120,6 @@ static struct clk_alpha_pll_postdiv gpll2 = {
&gpll2_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -154,7 +152,6 @@ static struct clk_alpha_pll_postdiv gpll4 = {
&gpll4_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -188,7 +185,6 @@ static struct clk_alpha_pll_postdiv gpll6 = {
&gpll6_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -201,7 +197,6 @@ static struct clk_fixed_factor gpll6_out_main_div2 = {
&gpll6_main.clkr.hw },
.num_parents = 1,
.ops = &clk_fixed_factor_ops,
.flags = CLK_SET_RATE_PARENT,
},
};
@ -266,7 +261,6 @@ static struct clk_alpha_pll_postdiv nss_crypto_pll = {
&nss_crypto_pll_main.clkr.hw },
.num_parents = 1,
.ops = &clk_alpha_pll_postdiv_ro_ops,
.flags = CLK_SET_RATE_PARENT,
},
};

View File

@ -87,7 +87,6 @@ static struct clk_fixed_factor gpll0_out_main_div2 = {
&gpll0_main.clkr.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_fixed_factor_ops,
},
};
@ -102,7 +101,6 @@ static struct clk_alpha_pll_postdiv gpll0 = {
&gpll0_main.clkr.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_alpha_pll_postdiv_ro_ops,
},
};
@ -132,7 +130,6 @@ static struct clk_alpha_pll_postdiv gpll4 = {
&gpll4_main.clkr.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_alpha_pll_postdiv_ro_ops,
},
};
@ -162,7 +159,6 @@ static struct clk_alpha_pll_postdiv gpll2 = {
&gpll2_main.clkr.hw
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_alpha_pll_postdiv_ro_ops,
},
};

View File

@ -7,9 +7,10 @@
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_platform.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include <linux/reset-controller.h>
@ -3716,14 +3717,10 @@ MODULE_DEVICE_TABLE(of, gcc_msm8960_match_table);
static int gcc_msm8960_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *match;
struct platform_device *tsens;
const struct qcom_cc_desc *desc = device_get_match_data(dev);
int ret;
match = of_match_device(gcc_msm8960_match_table, &pdev->dev);
if (!match)
return -EINVAL;
ret = qcom_cc_register_board_clk(dev, "cxo_board", "cxo", 19200000);
if (ret)
return ret;
@ -3732,11 +3729,11 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
if (ret)
return ret;
ret = qcom_cc_probe(pdev, match->data);
ret = qcom_cc_probe(pdev, desc);
if (ret)
return ret;
if (match->data == &gcc_apq8064_desc) {
if (desc == &gcc_apq8064_desc) {
hfpll1.d = &hfpll1_8064_data;
hfpll_l2.d = &hfpll_l2_8064_data;
}

View File

@ -7,9 +7,9 @@
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/property.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>
@ -2875,14 +2875,10 @@ static int gcc_msm8974_probe(struct platform_device *pdev)
{
int ret;
struct device *dev = &pdev->dev;
const struct of_device_id *id;
id = of_match_device(gcc_msm8974_match_table, dev);
if (!id)
return -ENODEV;
const void *data = device_get_match_data(dev);
if (!of_device_is_compatible(dev->of_node, "qcom,gcc-msm8974")) {
if (id->data == &gcc_msm8226_desc)
if (data == &gcc_msm8226_desc)
msm8226_clock_override();
else
msm8974_pro_clock_override();

View File

@ -244,71 +244,6 @@ static const struct clk_parent_data gcc_xo_gpll0_gpll4_gpll0_early_div[] = {
{ .hw = &gpll0_early_div.hw }
};
static const struct freq_tbl ftbl_system_noc_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(50000000, P_GPLL0_EARLY_DIV, 6, 0, 0),
F(100000000, P_GPLL0, 6, 0, 0),
F(150000000, P_GPLL0, 4, 0, 0),
F(200000000, P_GPLL0, 3, 0, 0),
F(240000000, P_GPLL0, 2.5, 0, 0),
{ }
};
static struct clk_rcg2 system_noc_clk_src = {
.cmd_rcgr = 0x0401c,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_gpll0_early_div_map,
.freq_tbl = ftbl_system_noc_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "system_noc_clk_src",
.parent_data = gcc_xo_gpll0_gpll0_early_div,
.num_parents = ARRAY_SIZE(gcc_xo_gpll0_gpll0_early_div),
.ops = &clk_rcg2_ops,
},
};
static const struct freq_tbl ftbl_config_noc_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(37500000, P_GPLL0, 16, 0, 0),
F(75000000, P_GPLL0, 8, 0, 0),
{ }
};
static struct clk_rcg2 config_noc_clk_src = {
.cmd_rcgr = 0x0500c,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_map,
.freq_tbl = ftbl_config_noc_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "config_noc_clk_src",
.parent_data = gcc_xo_gpll0,
.num_parents = ARRAY_SIZE(gcc_xo_gpll0),
.ops = &clk_rcg2_ops,
},
};
static const struct freq_tbl ftbl_periph_noc_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(37500000, P_GPLL0, 16, 0, 0),
F(50000000, P_GPLL0, 12, 0, 0),
F(75000000, P_GPLL0, 8, 0, 0),
F(100000000, P_GPLL0, 6, 0, 0),
{ }
};
static struct clk_rcg2 periph_noc_clk_src = {
.cmd_rcgr = 0x06014,
.hid_width = 5,
.parent_map = gcc_xo_gpll0_map,
.freq_tbl = ftbl_periph_noc_clk_src,
.clkr.hw.init = &(struct clk_init_data){
.name = "periph_noc_clk_src",
.parent_data = gcc_xo_gpll0,
.num_parents = ARRAY_SIZE(gcc_xo_gpll0),
.ops = &clk_rcg2_ops,
},
};
static const struct freq_tbl ftbl_usb30_master_clk_src[] = {
F(19200000, P_XO, 1, 0, 0),
F(120000000, P_GPLL0, 5, 0, 0),
@ -1297,11 +1232,7 @@ static struct clk_branch gcc_mmss_noc_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mmss_noc_cfg_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED,
.flags = CLK_IGNORE_UNUSED,
.ops = &clk_branch2_ops,
},
},
@ -1464,11 +1395,6 @@ static struct clk_branch gcc_usb_phy_cfg_ahb2phy_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_usb_phy_cfg_ahb2phy_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -1498,11 +1424,6 @@ static struct clk_branch gcc_sdcc1_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc1_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -1549,11 +1470,6 @@ static struct clk_branch gcc_sdcc2_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc2_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -1583,11 +1499,6 @@ static struct clk_branch gcc_sdcc3_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc3_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -1617,11 +1528,6 @@ static struct clk_branch gcc_sdcc4_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_sdcc4_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -1635,11 +1541,6 @@ static struct clk_branch gcc_blsp1_ahb_clk = {
.enable_mask = BIT(17),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp1_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -1977,11 +1878,6 @@ static struct clk_branch gcc_blsp2_ahb_clk = {
.enable_mask = BIT(15),
.hw.init = &(struct clk_init_data){
.name = "gcc_blsp2_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2318,11 +2214,6 @@ static struct clk_branch gcc_pdm_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pdm_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2353,11 +2244,6 @@ static struct clk_branch gcc_prng_ahb_clk = {
.enable_mask = BIT(13),
.hw.init = &(struct clk_init_data){
.name = "gcc_prng_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2370,11 +2256,6 @@ static struct clk_branch gcc_tsif_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_tsif_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2422,11 +2303,6 @@ static struct clk_branch gcc_boot_rom_ahb_clk = {
.enable_mask = BIT(10),
.hw.init = &(struct clk_init_data){
.name = "gcc_boot_rom_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2520,11 +2396,6 @@ static struct clk_branch gcc_pcie_0_slv_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_slv_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2537,11 +2408,6 @@ static struct clk_branch gcc_pcie_0_mstr_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_mstr_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2554,11 +2420,6 @@ static struct clk_branch gcc_pcie_0_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_0_cfg_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2606,11 +2467,6 @@ static struct clk_branch gcc_pcie_1_slv_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_slv_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2623,11 +2479,6 @@ static struct clk_branch gcc_pcie_1_mstr_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_mstr_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2640,11 +2491,6 @@ static struct clk_branch gcc_pcie_1_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_1_cfg_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2692,11 +2538,6 @@ static struct clk_branch gcc_pcie_2_slv_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_2_slv_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2709,11 +2550,6 @@ static struct clk_branch gcc_pcie_2_mstr_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_2_mstr_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2726,11 +2562,6 @@ static struct clk_branch gcc_pcie_2_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_2_cfg_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2778,11 +2609,6 @@ static struct clk_branch gcc_pcie_phy_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_pcie_phy_cfg_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -2829,11 +2655,6 @@ static struct clk_branch gcc_ufs_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_ufs_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -3060,11 +2881,7 @@ static struct clk_branch gcc_aggre0_snoc_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_aggre0_snoc_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
.flags = CLK_IS_CRITICAL,
.ops = &clk_branch2_ops,
},
},
@ -3077,11 +2894,7 @@ static struct clk_branch gcc_aggre0_cnoc_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_aggre0_cnoc_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
.flags = CLK_IS_CRITICAL,
.ops = &clk_branch2_ops,
},
},
@ -3094,11 +2907,7 @@ static struct clk_branch gcc_smmu_aggre0_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_smmu_aggre0_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
.flags = CLK_IS_CRITICAL,
.ops = &clk_branch2_ops,
},
},
@ -3111,11 +2920,7 @@ static struct clk_branch gcc_smmu_aggre0_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_smmu_aggre0_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT | CLK_IS_CRITICAL,
.flags = CLK_IS_CRITICAL,
.ops = &clk_branch2_ops,
},
},
@ -3162,10 +2967,6 @@ static struct clk_branch gcc_dcc_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_dcc_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@ -3178,10 +2979,6 @@ static struct clk_branch gcc_aggre0_noc_mpu_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_aggre0_noc_mpu_cfg_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@ -3194,11 +2991,6 @@ static struct clk_branch gcc_qspi_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_qspi_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&periph_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
.ops = &clk_branch2_ops,
},
},
@ -3347,10 +3139,6 @@ static struct clk_branch gcc_mss_cfg_ahb_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_cfg_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&config_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@ -3363,10 +3151,6 @@ static struct clk_branch gcc_mss_mnoc_bimc_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_mnoc_bimc_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@ -3379,10 +3163,6 @@ static struct clk_branch gcc_mss_snoc_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_snoc_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@ -3395,10 +3175,6 @@ static struct clk_branch gcc_mss_q6_bimc_axi_clk = {
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "gcc_mss_q6_bimc_axi_clk",
.parent_hws = (const struct clk_hw*[]){
&system_noc_clk_src.clkr.hw,
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
@ -3495,9 +3271,6 @@ static struct clk_regmap *gcc_msm8996_clocks[] = {
[GPLL0] = &gpll0.clkr,
[GPLL4_EARLY] = &gpll4_early.clkr,
[GPLL4] = &gpll4.clkr,
[SYSTEM_NOC_CLK_SRC] = &system_noc_clk_src.clkr,
[CONFIG_NOC_CLK_SRC] = &config_noc_clk_src.clkr,
[PERIPH_NOC_CLK_SRC] = &periph_noc_clk_src.clkr,
[USB30_MASTER_CLK_SRC] = &usb30_master_clk_src.clkr,
[USB30_MOCK_UTMI_CLK_SRC] = &usb30_mock_utmi_clk_src.clkr,
[USB3_PHY_AUX_CLK_SRC] = &usb3_phy_aux_clk_src.clkr,

File diff suppressed because it is too large Load Diff

View File

@ -774,7 +774,7 @@ static struct clk_rcg2 gcc_sdcc2_apps_clk_src = {
.name = "gcc_sdcc2_apps_clk_src",
.parent_data = gcc_parents_6,
.num_parents = ARRAY_SIZE(gcc_parents_6),
.flags = CLK_SET_RATE_PARENT,
.flags = CLK_OPS_PARENT_ENABLE,
.ops = &clk_rcg2_floor_ops,
},
};

View File

@ -39,8 +39,7 @@ static const struct pll_vco lucid_ole_vco[] = {
};
static const struct alpha_pll_config gpu_cc_pll0_config = {
/* .l includes RINGOSC_CAL_L_VAL, CAL_L_VAL, L_VAL fields */
.l = 0x4444000d,
.l = 0x0d,
.alpha = 0x0,
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00182261,
@ -71,8 +70,7 @@ static struct clk_alpha_pll gpu_cc_pll0 = {
};
static const struct alpha_pll_config gpu_cc_pll1_config = {
/* .l includes RINGOSC_CAL_L_VAL, CAL_L_VAL, L_VAL fields */
.l = 0x44440016,
.l = 0x16,
.alpha = 0xeaaa,
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00182261,
@ -574,8 +572,8 @@ static int gpu_cc_sm8550_probe(struct platform_device *pdev)
if (IS_ERR(regmap))
return PTR_ERR(regmap);
clk_lucid_evo_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
clk_lucid_evo_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
clk_lucid_ole_pll_configure(&gpu_cc_pll0, regmap, &gpu_cc_pll0_config);
clk_lucid_ole_pll_configure(&gpu_cc_pll1, regmap, &gpu_cc_pll1_config);
/*
* Keep clocks always enabled:

View File

@ -6,6 +6,7 @@
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
@ -31,8 +32,62 @@ static const struct hfpll_data hdata = {
.max_rate = 2900000000UL,
};
static const struct hfpll_data msm8976_a53 = {
.mode_reg = 0x00,
.l_reg = 0x04,
.m_reg = 0x08,
.n_reg = 0x0c,
.user_reg = 0x10,
.config_reg = 0x14,
.config_val = 0x341600,
.status_reg = 0x1c,
.lock_bit = 16,
.l_val = 0x35,
.user_val = 0x109,
.min_rate = 902400000UL,
.max_rate = 1478400000UL,
};
static const struct hfpll_data msm8976_a72 = {
.mode_reg = 0x00,
.l_reg = 0x04,
.m_reg = 0x08,
.n_reg = 0x0c,
.user_reg = 0x10,
.config_reg = 0x14,
.config_val = 0x4e0405d,
.status_reg = 0x1c,
.lock_bit = 16,
.l_val = 0x3e,
.user_val = 0x100109,
.min_rate = 940800000UL,
.max_rate = 2016000000UL,
};
static const struct hfpll_data msm8976_cci = {
.mode_reg = 0x00,
.l_reg = 0x04,
.m_reg = 0x08,
.n_reg = 0x0c,
.user_reg = 0x10,
.config_reg = 0x14,
.config_val = 0x141400,
.status_reg = 0x1c,
.lock_bit = 16,
.l_val = 0x20,
.user_val = 0x100109,
.min_rate = 556800000UL,
.max_rate = 902400000UL,
};
static const struct of_device_id qcom_hfpll_match_table[] = {
{ .compatible = "qcom,hfpll" },
{ .compatible = "qcom,hfpll", .data = &hdata },
{ .compatible = "qcom,msm8976-hfpll-a53", .data = &msm8976_a53 },
{ .compatible = "qcom,msm8976-hfpll-a72", .data = &msm8976_a72 },
{ .compatible = "qcom,msm8976-hfpll-cci", .data = &msm8976_cci },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table);
@ -83,7 +138,7 @@ static int qcom_hfpll_probe(struct platform_device *pdev)
init.parent_data = &pdata;
h->d = &hdata;
h->d = of_device_get_match_data(&pdev->dev);
h->clkr.hw.init = &init;
spin_lock_init(&h->lock);

View File

@ -5,10 +5,10 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
@ -32,20 +32,15 @@ MODULE_DEVICE_TABLE(of, kpss_xcc_match_table);
static int kpss_xcc_driver_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *id;
void __iomem *base;
struct clk_hw *hw;
const char *name;
id = of_match_device(kpss_xcc_match_table, dev);
if (!id)
return -ENODEV;
base = devm_platform_ioremap_resource(pdev, 0);
if (IS_ERR(base))
return PTR_ERR(base);
if (id->data) {
if (device_get_match_data(&pdev->dev)) {
if (of_property_read_string_index(dev->of_node,
"clock-output-names",
0, &name))

View File

@ -5,10 +5,10 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/slab.h>
@ -347,22 +347,18 @@ MODULE_DEVICE_TABLE(of, krait_cc_match_table);
static int krait_cc_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
const struct of_device_id *id;
unsigned long cur_rate, aux_rate;
int cpu;
struct clk_hw *mux, *l2_pri_mux;
struct clk *clk, **clks;
id = of_match_device(krait_cc_match_table, dev);
if (!id)
return -ENODEV;
bool unique_aux = !!device_get_match_data(dev);
/* Rate is 1 because 0 causes problems for __clk_mux_determine_rate */
clk = clk_register_fixed_rate(dev, "qsb", NULL, 0, 1);
if (IS_ERR(clk))
return PTR_ERR(clk);
if (!id->data) {
if (!unique_aux) {
clk = clk_register_fixed_factor(dev, "acpu_aux",
"gpll0_vote", 0, 1, 2);
if (IS_ERR(clk))
@ -375,13 +371,13 @@ static int krait_cc_probe(struct platform_device *pdev)
return -ENOMEM;
for_each_possible_cpu(cpu) {
mux = krait_add_clks(dev, cpu, id->data);
mux = krait_add_clks(dev, cpu, unique_aux);
if (IS_ERR(mux))
return PTR_ERR(mux);
clks[cpu] = mux->clk;
}
l2_pri_mux = krait_add_clks(dev, -1, id->data);
l2_pri_mux = krait_add_clks(dev, -1, unique_aux);
if (IS_ERR(l2_pri_mux))
return PTR_ERR(l2_pri_mux);
clks[l2_mux] = l2_pri_mux->clk;

View File

@ -8,9 +8,9 @@
#include <linux/err.h>
#include <linux/delay.h>
#include <linux/platform_device.h>
#include <linux/property.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
@ -3105,30 +3105,24 @@ MODULE_DEVICE_TABLE(of, mmcc_msm8960_match_table);
static int mmcc_msm8960_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
struct regmap *regmap;
bool is_8064;
struct device *dev = &pdev->dev;
const struct qcom_cc_desc *desc = device_get_match_data(dev);
match = of_match_device(mmcc_msm8960_match_table, dev);
if (!match)
return -EINVAL;
is_8064 = of_device_is_compatible(dev->of_node, "qcom,mmcc-apq8064");
if (is_8064) {
if (desc == &mmcc_apq8064_desc) {
gfx3d_src.freq_tbl = clk_tbl_gfx3d_8064;
gfx3d_src.clkr.hw.init = &gfx3d_8064_init;
gfx3d_src.s[0].parent_map = mmcc_pxo_pll8_pll2_pll15_map;
gfx3d_src.s[1].parent_map = mmcc_pxo_pll8_pll2_pll15_map;
}
regmap = qcom_cc_map(pdev, match->data);
regmap = qcom_cc_map(pdev, desc);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
clk_pll_configure_sr(&pll15, regmap, &pll15_config, false);
return qcom_cc_really_probe(pdev, match->data, regmap);
return qcom_cc_really_probe(pdev, desc, regmap);
}
static struct platform_driver mmcc_msm8960_driver = {

View File

@ -2170,22 +2170,6 @@ static struct clk_branch mmss_s0_axi_clk = {
},
};
static struct clk_branch ocmemcx_ahb_clk = {
.halt_reg = 0x405c,
.clkr = {
.enable_reg = 0x405c,
.enable_mask = BIT(0),
.hw.init = &(struct clk_init_data){
.name = "ocmemcx_ahb_clk",
.parent_hws = (const struct clk_hw*[]){
&mmss_ahb_clk_src.clkr.hw
},
.num_parents = 1,
.ops = &clk_branch2_ops,
},
},
};
static struct clk_branch ocmemcx_ocmemnoc_clk = {
.halt_reg = 0x4058,
.clkr = {
@ -2503,7 +2487,6 @@ static struct clk_regmap *mmcc_msm8226_clocks[] = {
[MMSS_MMSSNOC_BTO_AHB_CLK] = &mmss_mmssnoc_bto_ahb_clk.clkr,
[MMSS_MMSSNOC_AXI_CLK] = &mmss_mmssnoc_axi_clk.clkr,
[MMSS_S0_AXI_CLK] = &mmss_s0_axi_clk.clkr,
[OCMEMCX_AHB_CLK] = &ocmemcx_ahb_clk.clkr,
[OXILI_GFX3D_CLK] = &oxili_gfx3d_clk.clkr,
[OXILICX_AHB_CLK] = &oxilicx_ahb_clk.clkr,
[OXILICX_AXI_CLK] = &oxilicx_axi_clk.clkr,
@ -2660,7 +2643,6 @@ static struct clk_regmap *mmcc_msm8974_clocks[] = {
[MMSS_MMSSNOC_BTO_AHB_CLK] = &mmss_mmssnoc_bto_ahb_clk.clkr,
[MMSS_MMSSNOC_AXI_CLK] = &mmss_mmssnoc_axi_clk.clkr,
[MMSS_S0_AXI_CLK] = &mmss_s0_axi_clk.clkr,
[OCMEMCX_AHB_CLK] = &ocmemcx_ahb_clk.clkr,
[OCMEMCX_OCMEMNOC_CLK] = &ocmemcx_ocmemnoc_clk.clkr,
[OCMEMNOC_CLK] = &ocmemnoc_clk.clkr,
[OXILI_GFX3D_CLK] = &oxili_gfx3d_clk.clkr,

View File

@ -2439,6 +2439,7 @@ static struct clk_branch fd_ahb_clk = {
static struct clk_branch mnoc_ahb_clk = {
.halt_reg = 0x5024,
.halt_check = BRANCH_HALT_SKIP,
.clkr = {
.enable_reg = 0x5024,
.enable_mask = BIT(0),
@ -2454,6 +2455,7 @@ static struct clk_branch mnoc_ahb_clk = {
static struct clk_branch bimc_smmu_ahb_clk = {
.halt_reg = 0xe004,
.halt_check = BRANCH_HALT_SKIP,
.hwcg_reg = 0xe004,
.hwcg_bit = 1,
.clkr = {
@ -2471,6 +2473,7 @@ static struct clk_branch bimc_smmu_ahb_clk = {
static struct clk_branch bimc_smmu_axi_clk = {
.halt_reg = 0xe008,
.halt_check = BRANCH_HALT_SKIP,
.hwcg_reg = 0xe008,
.hwcg_bit = 1,
.clkr = {
@ -2607,11 +2610,13 @@ static struct gdsc camss_cpp_gdsc = {
static struct gdsc bimc_smmu_gdsc = {
.gdscr = 0xe020,
.gds_hw_ctrl = 0xe024,
.cxcs = (unsigned int []){ 0xe008 },
.cxc_count = 1,
.pd = {
.name = "bimc_smmu",
},
.pwrsts = PWRSTS_OFF_ON,
.flags = HW_CTRL | ALWAYS_ON,
.flags = VOTABLE,
};
static struct clk_regmap *mmcc_msm8998_clocks[] = {

View File

@ -9,9 +9,9 @@
#include <linux/bitops.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/property.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>
@ -2828,14 +2828,10 @@ static void sdm630_clock_override(void)
static int mmcc_660_probe(struct platform_device *pdev)
{
const struct of_device_id *id;
struct regmap *regmap;
bool is_sdm630;
id = of_match_device(mmcc_660_match_table, &pdev->dev);
if (!id)
return -ENODEV;
is_sdm630 = !!(id->data);
is_sdm630 = !!device_get_match_data(&pdev->dev);
regmap = qcom_cc_map(pdev, &mmcc_660_desc);
if (IS_ERR(regmap))

View File

@ -36,8 +36,7 @@ static const struct pll_vco lucid_ole_vco[] = {
};
static const struct alpha_pll_config video_cc_pll0_config = {
/* .l includes RINGOSC_CAL_L_VAL, CAL_L_VAL, L_VAL fields */
.l = 0x44440025,
.l = 0x25,
.alpha = 0x8000,
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00182261,
@ -68,8 +67,7 @@ static struct clk_alpha_pll video_cc_pll0 = {
};
static const struct alpha_pll_config video_cc_pll1_config = {
/* .l includes RINGOSC_CAL_L_VAL, CAL_L_VAL, L_VAL fields */
.l = 0x44440036,
.l = 0x36,
.alpha = 0xb000,
.config_ctl_val = 0x20485699,
.config_ctl_hi_val = 0x00182261,
@ -427,8 +425,8 @@ static int video_cc_sm8550_probe(struct platform_device *pdev)
return PTR_ERR(regmap);
}
clk_lucid_evo_pll_configure(&video_cc_pll0, regmap, &video_cc_pll0_config);
clk_lucid_evo_pll_configure(&video_cc_pll1, regmap, &video_cc_pll1_config);
clk_lucid_ole_pll_configure(&video_cc_pll0, regmap, &video_cc_pll0_config);
clk_lucid_ole_pll_configure(&video_cc_pll1, regmap, &video_cc_pll1_config);
/*
* Keep clocks always enabled:

View File

@ -821,6 +821,10 @@ static const struct mtmips_clk_data mt76x8_clk_data = {
};
static const struct of_device_id mtmips_of_match[] = {
{
.compatible = "ralink,rt2880-reset",
.data = NULL,
},
{
.compatible = "ralink,rt2880-sysc",
.data = &rt2880_clk_data,
@ -1088,25 +1092,11 @@ static int mtmips_clk_probe(struct platform_device *pdev)
return 0;
}
static const struct of_device_id mtmips_clk_of_match[] = {
{ .compatible = "ralink,rt2880-reset" },
{ .compatible = "ralink,rt2880-sysc" },
{ .compatible = "ralink,rt3050-sysc" },
{ .compatible = "ralink,rt3052-sysc" },
{ .compatible = "ralink,rt3352-sysc" },
{ .compatible = "ralink,rt3883-sysc" },
{ .compatible = "ralink,rt5350-sysc" },
{ .compatible = "ralink,mt7620-sysc" },
{ .compatible = "ralink,mt7628-sysc" },
{ .compatible = "ralink,mt7688-sysc" },
{}
};
static struct platform_driver mtmips_clk_driver = {
.probe = mtmips_clk_probe,
.driver = {
.name = "mtmips-clk",
.of_match_table = mtmips_clk_of_match,
.of_match_table = mtmips_of_match,
},
};

View File

@ -37,6 +37,7 @@ config CLK_RENESAS
select CLK_R9A07G043 if ARCH_R9A07G043
select CLK_R9A07G044 if ARCH_R9A07G044
select CLK_R9A07G054 if ARCH_R9A07G054
select CLK_R9A08G045 if ARCH_R9A08G045
select CLK_R9A09G011 if ARCH_R9A09G011
select CLK_SH73A0 if ARCH_SH73A0
@ -179,6 +180,10 @@ config CLK_R9A07G054
bool "RZ/V2L clock support" if COMPILE_TEST
select CLK_RZG2L
config CLK_R9A08G045
bool "RZ/G3S clock support" if COMPILE_TEST
select CLK_RZG2L
config CLK_R9A09G011
bool "RZ/V2M clock support" if COMPILE_TEST
select CLK_RZG2L
@ -215,7 +220,7 @@ config CLK_RCAR_USB2_CLOCK_SEL
This is a driver for R-Car USB2 clock selector
config CLK_RZG2L
bool "Renesas RZ/{G2L,G2UL,V2L} family clock support" if COMPILE_TEST
bool "Renesas RZ/{G2L,G2UL,G3S,V2L} family clock support" if COMPILE_TEST
select RESET_CONTROLLER
# Generic

View File

@ -34,6 +34,7 @@ obj-$(CONFIG_CLK_R9A06G032) += r9a06g032-clocks.o
obj-$(CONFIG_CLK_R9A07G043) += r9a07g043-cpg.o
obj-$(CONFIG_CLK_R9A07G044) += r9a07g044-cpg.o
obj-$(CONFIG_CLK_R9A07G054) += r9a07g044-cpg.o
obj-$(CONFIG_CLK_R9A08G045) += r9a08g045-cpg.o
obj-$(CONFIG_CLK_R9A09G011) += r9a09g011-cpg.o
obj-$(CONFIG_CLK_SH73A0) += clk-sh73a0.o

View File

@ -51,7 +51,7 @@ enum clk_ids {
MOD_CLK_BASE
};
static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
static const struct cpg_core_clk r8a7795_core_clks[] __initconst = {
/* External Clock Inputs */
DEF_INPUT("extal", CLK_EXTAL),
DEF_INPUT("extalr", CLK_EXTALR),
@ -128,7 +128,7 @@ static struct cpg_core_clk r8a7795_core_clks[] __initdata = {
DEF_BASE("r", R8A7795_CLK_R, CLK_TYPE_GEN3_R, CLK_RINT),
};
static struct mssr_mod_clk r8a7795_mod_clks[] __initdata = {
static const struct mssr_mod_clk r8a7795_mod_clks[] __initconst = {
DEF_MOD("3dge", 112, R8A7795_CLK_ZG),
DEF_MOD("fdp1-1", 118, R8A7795_CLK_S0D1),
DEF_MOD("fdp1-0", 119, R8A7795_CLK_S0D1),

View File

@ -102,19 +102,22 @@ enum gate_type {
* @source: the ID+1 of the parent clock element.
* Root clock uses ID of ~0 (PARENT_ID);
* @gate: clock enable/disable
* @div_min: smallest permitted clock divider
* @div_max: largest permitted clock divider
* @reg: clock divider register offset, in 32-bit words
* @div_table: optional list of fixed clock divider values;
* @div: substructure for clock divider
* @div.min: smallest permitted clock divider
* @div.max: largest permitted clock divider
* @div.reg: clock divider register offset, in 32-bit words
* @div.table: optional list of fixed clock divider values;
* must be in ascending order, zero for unused
* @div: divisor for fixed-factor clock
* @mul: multiplier for fixed-factor clock
* @group: UART group, 0=UART0/1/2, 1=UART3/4/5/6/7
* @sel: select either g1/r1 or g2/r2 as clock source
* @g1: 1st source gate (clock enable/disable)
* @r1: 1st source reset (module reset)
* @g2: 2nd source gate (clock enable/disable)
* @r2: 2nd source reset (module reset)
* @ffc: substructure for fixed-factor clocks
* @ffc.div: divisor for fixed-factor clock
* @ffc.mul: multiplier for fixed-factor clock
* @dual: substructure for dual clock gates
* @dual.group: UART group, 0=UART0/1/2, 1=UART3/4/5/6/7
* @dual.sel: select either g1/r1 or g2/r2 as clock source
* @dual.g1: 1st source gate (clock enable/disable)
* @dual.r1: 1st source reset (module reset)
* @dual.g2: 2nd source gate (clock enable/disable)
* @dual.r2: 2nd source reset (module reset)
*
* Describes a single element in the clock tree hierarchy.
* As there are quite a large number of clock elements, this
@ -131,13 +134,13 @@ struct r9a06g032_clkdesc {
struct r9a06g032_gate gate;
/* type = K_DIV */
struct {
unsigned int div_min:10, div_max:10, reg:10;
u16 div_table[4];
};
unsigned int min:10, max:10, reg:10;
u16 table[4];
} div;
/* type = K_FFC */
struct {
u16 div, mul;
};
} ffc;
/* type = K_DUALGATE */
struct {
uint16_t group:1;
@ -178,26 +181,26 @@ struct r9a06g032_clkdesc {
.type = K_FFC, \
.index = R9A06G032_##_idx, \
.name = _n, \
.div = _div, \
.mul = _mul \
.ffc.div = _div, \
.ffc.mul = _mul \
}
#define D_FFC(_idx, _n, _src, _div) { \
.type = K_FFC, \
.index = R9A06G032_##_idx, \
.source = 1 + R9A06G032_##_src, \
.name = _n, \
.div = _div, \
.mul = 1 \
.ffc.div = _div, \
.ffc.mul = 1 \
}
#define D_DIV(_idx, _n, _src, _reg, _min, _max, ...) { \
.type = K_DIV, \
.index = R9A06G032_##_idx, \
.source = 1 + R9A06G032_##_src, \
.name = _n, \
.reg = _reg, \
.div_min = _min, \
.div_max = _max, \
.div_table = { __VA_ARGS__ } \
.div.reg = _reg, \
.div.min = _min, \
.div.max = _max, \
.div.table = { __VA_ARGS__ } \
}
#define D_UGATE(_idx, _n, _src, _g, _g1, _r1, _g2, _r2) { \
.type = K_DUALGATE, \
@ -1063,14 +1066,14 @@ r9a06g032_register_div(struct r9a06g032_priv *clocks,
div->clocks = clocks;
div->index = desc->index;
div->reg = desc->reg;
div->reg = desc->div.reg;
div->hw.init = &init;
div->min = desc->div_min;
div->max = desc->div_max;
div->min = desc->div.min;
div->max = desc->div.max;
/* populate (optional) divider table fixed values */
for (i = 0; i < ARRAY_SIZE(div->table) &&
i < ARRAY_SIZE(desc->div_table) && desc->div_table[i]; i++) {
div->table[div->table_size++] = desc->div_table[i];
i < ARRAY_SIZE(desc->div.table) && desc->div.table[i]; i++) {
div->table[div->table_size++] = desc->div.table[i];
}
clk = clk_register(NULL, &div->hw);
@ -1269,11 +1272,10 @@ static void r9a06g032_clocks_del_clk_provider(void *data)
static void __init r9a06g032_init_h2mode(struct r9a06g032_priv *clocks)
{
struct device_node *usbf_np = NULL;
struct device_node *usbf_np;
u32 usb;
while ((usbf_np = of_find_compatible_node(usbf_np, NULL,
"renesas,rzn1-usbf"))) {
for_each_compatible_node(usbf_np, NULL, "renesas,rzn1-usbf") {
if (of_device_is_available(usbf_np))
break;
}
@ -1333,7 +1335,8 @@ static int __init r9a06g032_clocks_probe(struct platform_device *pdev)
case K_FFC:
clk = clk_register_fixed_factor(NULL, d->name,
parent_name, 0,
d->mul, d->div);
d->ffc.mul,
d->ffc.div);
break;
case K_GATE:
clk = r9a06g032_register_gate(clocks, parent_name, d);

View File

@ -14,6 +14,17 @@
#include "rzg2l-cpg.h"
/* Specific registers. */
#define CPG_PL2SDHI_DSEL (0x218)
/* Clock select configuration. */
#define SEL_SDHI0 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 0, 2)
#define SEL_SDHI1 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 4, 2)
/* Clock status configuration. */
#define SEL_SDHI0_STS SEL_PLL_PACK(CPG_CLKSTATUS, 28, 1)
#define SEL_SDHI1_STS SEL_PLL_PACK(CPG_CLKSTATUS, 29, 1)
enum clk_ids {
/* Core Clock Outputs exported to DT */
LAST_DT_CORE_CLK = R9A07G043_CLK_P0_DIV2,
@ -78,6 +89,8 @@ static const char * const sel_pll3_3[] = { ".pll3_533", ".pll3_400" };
static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
static const u32 mtable_sdhi[] = { 1, 2, 3 };
static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
/* External Clock Inputs */
DEF_INPUT("extal", CLK_EXTAL),
@ -123,8 +136,10 @@ static const struct cpg_core_clk r9a07g043_core_clks[] __initconst = {
DEF_MUX("HP", R9A07G043_CLK_HP, SEL_PLL6_2, sel_pll6_2),
DEF_FIXED("SPI0", R9A07G043_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
DEF_FIXED("SPI1", R9A07G043_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, sel_shdi),
DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, sel_shdi),
DEF_SD_MUX("SD0", R9A07G043_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_shdi,
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
DEF_SD_MUX("SD1", R9A07G043_CLK_SD1, SEL_SDHI1, SEL_SDHI0_STS, sel_shdi,
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G043_CLK_SD0, 1, 4),
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G043_CLK_SD1, 1, 4),
};

View File

@ -15,6 +15,17 @@
#include "rzg2l-cpg.h"
/* Specific registers. */
#define CPG_PL2SDHI_DSEL (0x218)
/* Clock select configuration. */
#define SEL_SDHI0 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 0, 2)
#define SEL_SDHI1 SEL_PLL_PACK(CPG_PL2SDHI_DSEL, 4, 2)
/* Clock status configuration. */
#define SEL_SDHI0_STS SEL_PLL_PACK(CPG_CLKSTATUS, 28, 1)
#define SEL_SDHI1_STS SEL_PLL_PACK(CPG_CLKSTATUS, 29, 1)
enum clk_ids {
/* Core Clock Outputs exported to DT */
LAST_DT_CORE_CLK = R9A07G054_CLK_DRP_A,
@ -98,6 +109,8 @@ static const char * const sel_pll6_2[] = { ".pll6_250", ".pll5_250" };
static const char * const sel_shdi[] = { ".clk_533", ".clk_400", ".clk_266" };
static const char * const sel_gpu2[] = { ".pll6", ".pll3_div2_2" };
static const u32 mtable_sdhi[] = { 1, 2, 3 };
static const struct {
struct cpg_core_clk common[56];
#ifdef CONFIG_CLK_R9A07G054
@ -163,8 +176,10 @@ static const struct {
DEF_MUX("HP", R9A07G044_CLK_HP, SEL_PLL6_2, sel_pll6_2),
DEF_FIXED("SPI0", R9A07G044_CLK_SPI0, CLK_DIV_PLL3_C, 1, 2),
DEF_FIXED("SPI1", R9A07G044_CLK_SPI1, CLK_DIV_PLL3_C, 1, 4),
DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, sel_shdi),
DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, sel_shdi),
DEF_SD_MUX("SD0", R9A07G044_CLK_SD0, SEL_SDHI0, SEL_SDHI0_STS, sel_shdi,
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
DEF_SD_MUX("SD1", R9A07G044_CLK_SD1, SEL_SDHI1, SEL_SDHI0_STS, sel_shdi,
mtable_sdhi, 0, rzg2l_cpg_sd_clk_mux_notifier),
DEF_FIXED("SD0_DIV4", CLK_SD0_DIV4, R9A07G044_CLK_SD0, 1, 4),
DEF_FIXED("SD1_DIV4", CLK_SD1_DIV4, R9A07G044_CLK_SD1, 1, 4),
DEF_DIV("G", R9A07G044_CLK_G, CLK_SEL_GPU2, DIVGPU, dtable_1_8),

Some files were not shown because too many files have changed in this diff Show More