Merge branches 'clk-imx6-mmdc', 'clk-qcom-krait', 'clk-rockchip' and 'clk-smp2s11-match' into clk-next

- iMX6 MMDC clks
  - Qualcomm Krait CPU clk support

* clk-imx6-mmdc:
  clk: imx6q: add mmdc0 ipg clock
  clk: imx6sl: add mmdc ipg clocks
  clk: imx6sll: add mmdc1 ipg clock
  clk: imx6sx: add mmdc1 ipg clock
  clk: imx6ul: add mmdc1 ipg clock

* clk-qcom-krait:
  clk: qcom: Add safe switch hook for krait mux clocks
  dt-bindings: clock: Document qcom,krait-cc
  clk: qcom: Add Krait clock controller driver
  dt-bindings: arm: Document qcom,kpss-gcc
  clk: qcom: Add KPSS ACC/GCC driver
  clk: qcom: Add support for Krait clocks
  clk: qcom: Add IPQ806X's HFPLLs
  clk: qcom: Add MSM8960/APQ8064's HFPLLs
  dt-bindings: clock: Document qcom,hfpll
  clk: qcom: Add HFPLL driver
  clk: qcom: Add support for High-Frequency PLLs (HFPLLs)
  ARM: Add Krait L2 register accessor functions

* clk-rockchip:
  clk: rockchip: Fix static checker warning in rockchip_ddrclk_get_parent call
  clk: rockchip: use the newly added clock-id for hdmi on RK3066
  clk: rockchip: add clock-id for HCLK_HDMI on rk3066
  clk: rockchip: fix wrong mmc sample phase shift for rk3328
  clk: rockchip: improve rk3288 pll rates for better hdmi output

* clk-smp2s11-match:
  clk: s2mps11: Add used attribute to s2mps11_dt_match
  clk: s2mps11: Fix matching when built as module and DT node contains compatible
This commit is contained in:
Stephen Boyd 2018-10-18 15:44:01 -07:00
36 changed files with 1620 additions and 19 deletions

View File

@ -21,10 +21,29 @@ PROPERTIES
the register region. An optional second element specifies the register region. An optional second element specifies
the base address and size of the alias register region. the base address and size of the alias register region.
- clocks:
Usage: required
Value type: <prop-encoded-array>
Definition: reference to the pll parents.
- clock-names:
Usage: required
Value type: <stringlist>
Definition: must be "pll8_vote", "pxo".
- clock-output-names:
Usage: optional
Value type: <string>
Definition: Name of the output clock. Typically acpuX_aux where X is a
CPU number starting at 0.
Example: Example:
clock-controller@2088000 { clock-controller@2088000 {
compatible = "qcom,kpss-acc-v2"; compatible = "qcom,kpss-acc-v2";
reg = <0x02088000 0x1000>, reg = <0x02088000 0x1000>,
<0x02008000 0x1000>; <0x02008000 0x1000>;
clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>;
clock-names = "pll8_vote", "pxo";
clock-output-names = "acpu0_aux";
}; };

View File

@ -0,0 +1,44 @@
Krait Processor Sub-system (KPSS) Global Clock Controller (GCC)
PROPERTIES
- compatible:
Usage: required
Value type: <string>
Definition: should be one of the following. The generic compatible
"qcom,kpss-gcc" should also be included.
"qcom,kpss-gcc-ipq8064", "qcom,kpss-gcc"
"qcom,kpss-gcc-apq8064", "qcom,kpss-gcc"
"qcom,kpss-gcc-msm8974", "qcom,kpss-gcc"
"qcom,kpss-gcc-msm8960", "qcom,kpss-gcc"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: base address and size of the register region
- clocks:
Usage: required
Value type: <prop-encoded-array>
Definition: reference to the pll parents.
- clock-names:
Usage: required
Value type: <stringlist>
Definition: must be "pll8_vote", "pxo".
- clock-output-names:
Usage: required
Value type: <string>
Definition: Name of the output clock. Typically acpu_l2_aux indicating
an L2 cache auxiliary clock.
Example:
l2cc: clock-controller@2011000 {
compatible = "qcom,kpss-gcc-ipq8064", "qcom,kpss-gcc";
reg = <0x2011000 0x1000>;
clocks = <&gcc PLL8_VOTE>, <&gcc PXO_SRC>;
clock-names = "pll8_vote", "pxo";
clock-output-names = "acpu_l2_aux";
};

View File

@ -0,0 +1,60 @@
High-Frequency PLL (HFPLL)
PROPERTIES
- compatible:
Usage: required
Value type: <string>:
shall contain only one of the following. The generic
compatible "qcom,hfpll" should be also included.
"qcom,hfpll-ipq8064", "qcom,hfpll"
"qcom,hfpll-apq8064", "qcom,hfpll"
"qcom,hfpll-msm8974", "qcom,hfpll"
"qcom,hfpll-msm8960", "qcom,hfpll"
- reg:
Usage: required
Value type: <prop-encoded-array>
Definition: address and size of HPLL registers. An optional second
element specifies the address and size of the alias
register region.
- clocks:
Usage: required
Value type: <prop-encoded-array>
Definition: reference to the xo clock.
- clock-names:
Usage: required
Value type: <stringlist>
Definition: must be "xo".
- clock-output-names:
Usage: required
Value type: <string>
Definition: Name of the PLL. Typically hfpllX where X is a CPU number
starting at 0. Otherwise hfpll_Y where Y is more specific
such as "l2".
Example:
1) An HFPLL for the L2 cache.
clock-controller@f9016000 {
compatible = "qcom,hfpll-ipq8064", "qcom,hfpll";
reg = <0xf9016000 0x30>;
clocks = <&xo_board>;
clock-names = "xo";
clock-output-names = "hfpll_l2";
};
2) An HFPLL for CPU0. This HFPLL has the alias register region.
clock-controller@f908a000 {
compatible = "qcom,hfpll-ipq8064", "qcom,hfpll";
reg = <0xf908a000 0x30>, <0xf900a000 0x30>;
clocks = <&xo_board>;
clock-names = "xo";
clock-output-names = "hfpll0";
};

View File

@ -0,0 +1,34 @@
Krait Clock Controller
PROPERTIES
- compatible:
Usage: required
Value type: <string>
Definition: must be one of:
"qcom,krait-cc-v1"
"qcom,krait-cc-v2"
- #clock-cells:
Usage: required
Value type: <u32>
Definition: must be 1
- clocks:
Usage: required
Value type: <prop-encoded-array>
Definition: reference to the clock parents of hfpll, secondary muxes.
- clock-names:
Usage: required
Value type: <stringlist>
Definition: must be "hfpll0", "hfpll1", "acpu0_aux", "acpu1_aux", "qsb".
Example:
kraitcc: clock-controller {
compatible = "qcom,krait-cc-v1";
clocks = <&hfpll0>, <&hfpll1>, <&acpu0_aux>, <&acpu1_aux>, <qsb>;
clock-names = "hfpll0", "hfpll1", "acpu0_aux", "acpu1_aux", "qsb";
#clock-cells = <1>;
};

View File

@ -7,6 +7,9 @@ config DMABOUNCE
bool bool
select ZONE_DMA select ZONE_DMA
config KRAIT_L2_ACCESSORS
bool
config SHARP_LOCOMO config SHARP_LOCOMO
bool bool

View File

@ -7,6 +7,7 @@ obj-y += firmware.o
obj-$(CONFIG_SA1111) += sa1111.o obj-$(CONFIG_SA1111) += sa1111.o
obj-$(CONFIG_DMABOUNCE) += dmabounce.o obj-$(CONFIG_DMABOUNCE) += dmabounce.o
obj-$(CONFIG_KRAIT_L2_ACCESSORS) += krait-l2-accessors.o
obj-$(CONFIG_SHARP_LOCOMO) += locomo.o obj-$(CONFIG_SHARP_LOCOMO) += locomo.o
obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o obj-$(CONFIG_SHARP_PARAM) += sharpsl_param.o
obj-$(CONFIG_SHARP_SCOOP) += scoop.o obj-$(CONFIG_SHARP_SCOOP) += scoop.o

View File

@ -0,0 +1,48 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018, The Linux Foundation. All rights reserved.
#include <linux/spinlock.h>
#include <linux/export.h>
#include <asm/barrier.h>
#include <asm/krait-l2-accessors.h>
static DEFINE_RAW_SPINLOCK(krait_l2_lock);
void krait_set_l2_indirect_reg(u32 addr, u32 val)
{
unsigned long flags;
raw_spin_lock_irqsave(&krait_l2_lock, flags);
/*
* Select the L2 window by poking l2cpselr, then write to the window
* via l2cpdr.
*/
asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
isb();
asm volatile ("mcr p15, 3, %0, c15, c0, 7 @ l2cpdr" : : "r" (val));
isb();
raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
}
EXPORT_SYMBOL(krait_set_l2_indirect_reg);
u32 krait_get_l2_indirect_reg(u32 addr)
{
u32 val;
unsigned long flags;
raw_spin_lock_irqsave(&krait_l2_lock, flags);
/*
* Select the L2 window by poking l2cpselr, then read from the window
* via l2cpdr.
*/
asm volatile ("mcr p15, 3, %0, c15, c0, 6 @ l2cpselr" : : "r" (addr));
isb();
asm volatile ("mrc p15, 3, %0, c15, c0, 7 @ l2cpdr" : "=r" (val));
raw_spin_unlock_irqrestore(&krait_l2_lock, flags);
return val;
}
EXPORT_SYMBOL(krait_get_l2_indirect_reg);

View File

@ -0,0 +1,9 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __ASMARM_KRAIT_L2_ACCESSORS_H
#define __ASMARM_KRAIT_L2_ACCESSORS_H
extern void krait_set_l2_indirect_reg(u32 addr, u32 val);
extern u32 krait_get_l2_indirect_reg(u32 addr);
#endif

View File

@ -229,6 +229,36 @@ static const struct platform_device_id s2mps11_clk_id[] = {
}; };
MODULE_DEVICE_TABLE(platform, s2mps11_clk_id); MODULE_DEVICE_TABLE(platform, s2mps11_clk_id);
#ifdef CONFIG_OF
/*
* Device is instantiated through parent MFD device and device matching is done
* through platform_device_id.
*
* However if device's DT node contains proper clock compatible and driver is
* built as a module, then the *module* matching will be done trough DT aliases.
* This requires of_device_id table. In the same time this will not change the
* actual *device* matching so do not add .of_match_table.
*/
static const struct of_device_id s2mps11_dt_match[] __used = {
{
.compatible = "samsung,s2mps11-clk",
.data = (void *)S2MPS11X,
}, {
.compatible = "samsung,s2mps13-clk",
.data = (void *)S2MPS13X,
}, {
.compatible = "samsung,s2mps14-clk",
.data = (void *)S2MPS14X,
}, {
.compatible = "samsung,s5m8767-clk",
.data = (void *)S5M8767X,
}, {
/* Sentinel */
},
};
MODULE_DEVICE_TABLE(of, s2mps11_dt_match);
#endif
static struct platform_driver s2mps11_clk_driver = { static struct platform_driver s2mps11_clk_driver = {
.driver = { .driver = {
.name = "s2mps11-clk", .name = "s2mps11-clk",

View File

@ -789,6 +789,7 @@ static void __init imx6q_clocks_init(struct device_node *ccm_node)
clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18); clk[IMX6QDL_CLK_MLB] = imx_clk_gate2("mlb", "axi", base + 0x74, 18);
clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2_flags("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20, CLK_IS_CRITICAL); clk[IMX6QDL_CLK_MMDC_CH0_AXI] = imx_clk_gate2_flags("mmdc_ch0_axi", "mmdc_ch0_axi_podf", base + 0x74, 20, CLK_IS_CRITICAL);
clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22); clk[IMX6QDL_CLK_MMDC_CH1_AXI] = imx_clk_gate2("mmdc_ch1_axi", "mmdc_ch1_axi_podf", base + 0x74, 22);
clk[IMX6QDL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL);
clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28); clk[IMX6QDL_CLK_OCRAM] = imx_clk_gate2("ocram", "ahb", base + 0x74, 28);
clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30); clk[IMX6QDL_CLK_OPENVG_AXI] = imx_clk_gate2("openvg_axi", "axi", base + 0x74, 30);
clk[IMX6QDL_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0); clk[IMX6QDL_CLK_PCIE_AXI] = imx_clk_gate2("pcie_axi", "pcie_axi_sel", base + 0x78, 0);

View File

@ -386,6 +386,8 @@ static void __init imx6sl_clocks_init(struct device_node *ccm_node)
clks[IMX6SL_CLK_LCDIF_AXI] = imx_clk_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6); clks[IMX6SL_CLK_LCDIF_AXI] = imx_clk_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6);
clks[IMX6SL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8); clks[IMX6SL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8);
clks[IMX6SL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10); clks[IMX6SL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10);
clks[IMX6SL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL);
clks[IMX6SL_CLK_MMDC_P1_IPG] = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26);
clks[IMX6SL_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28); clks[IMX6SL_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
clks[IMX6SL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16); clks[IMX6SL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
clks[IMX6SL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18); clks[IMX6SL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);

View File

@ -293,6 +293,7 @@ static void __init imx6sll_clocks_init(struct device_node *ccm_node)
clks[IMX6SLL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); clks[IMX6SLL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16);
clks[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); clks[IMX6SLL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL);
clks[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); clks[IMX6SLL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL);
clks[IMX6SLL_CLK_MMDC_P1_IPG] = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26);
clks[IMX6SLL_CLK_OCRAM] = imx_clk_gate_flags("ocram","ahb", base + 0x74, 28, CLK_IS_CRITICAL); clks[IMX6SLL_CLK_OCRAM] = imx_clk_gate_flags("ocram","ahb", base + 0x74, 28, CLK_IS_CRITICAL);
/* CCGR4 */ /* CCGR4 */

View File

@ -431,6 +431,7 @@ static void __init imx6sx_clocks_init(struct device_node *ccm_node)
clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18); clks[IMX6SX_CLK_MLB] = imx_clk_gate2("mlb", "ahb", base + 0x74, 18);
clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); clks[IMX6SX_CLK_MMDC_P0_FAST] = imx_clk_gate2_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL);
clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); clks[IMX6SX_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL);
clks[IMX6SX_CLK_MMDC_P1_IPG] = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26);
clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2_flags("ocram", "ocram_podf", base + 0x74, 28, CLK_IS_CRITICAL); clks[IMX6SX_CLK_OCRAM] = imx_clk_gate2_flags("ocram", "ocram_podf", base + 0x74, 28, CLK_IS_CRITICAL);
/* CCGR4 */ /* CCGR4 */

View File

@ -408,6 +408,7 @@ static void __init imx6ul_clocks_init(struct device_node *ccm_node)
clks[IMX6UL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16); clks[IMX6UL_CLK_WDOG1] = imx_clk_gate2("wdog1", "ipg", base + 0x74, 16);
clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL); clks[IMX6UL_CLK_MMDC_P0_FAST] = imx_clk_gate_flags("mmdc_p0_fast", "mmdc_podf", base + 0x74, 20, CLK_IS_CRITICAL);
clks[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL); clks[IMX6UL_CLK_MMDC_P0_IPG] = imx_clk_gate2_flags("mmdc_p0_ipg", "ipg", base + 0x74, 24, CLK_IS_CRITICAL);
clks[IMX6UL_CLK_MMDC_P1_IPG] = imx_clk_gate2("mmdc_p1_ipg", "ipg", base + 0x74, 26);
clks[IMX6UL_CLK_AXI] = imx_clk_gate_flags("axi", "axi_podf", base + 0x74, 28, CLK_IS_CRITICAL); clks[IMX6UL_CLK_AXI] = imx_clk_gate_flags("axi", "axi_podf", base + 0x74, 28, CLK_IS_CRITICAL);
/* CCGR4 */ /* CCGR4 */

View File

@ -1,3 +1,7 @@
config KRAIT_CLOCKS
bool
select KRAIT_L2_ACCESSORS
config QCOM_GDSC config QCOM_GDSC
bool bool
select PM_GENERIC_DOMAINS if PM select PM_GENERIC_DOMAINS if PM
@ -297,3 +301,27 @@ config SPMI_PMIC_CLKDIV
Technologies, Inc. SPMI PMIC. It configures the frequency of Technologies, Inc. SPMI PMIC. It configures the frequency of
clkdiv outputs of the PMIC. These clocks are typically wired clkdiv outputs of the PMIC. These clocks are typically wired
through alternate functions on GPIO pins. through alternate functions on GPIO pins.
config QCOM_HFPLL
tristate "High-Frequency PLL (HFPLL) Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the high-frequency PLLs present on Qualcomm devices.
Say Y if you want to support CPU frequency scaling on devices
such as MSM8974, APQ8084, etc.
config KPSS_XCC
tristate "KPSS Clock Controller"
depends on COMMON_CLK_QCOM
help
Support for the Krait ACC and GCC clock controllers. Say Y
if you want to support CPU frequency scaling on devices such
as MSM8960, APQ8064, etc.
config KRAITCC
tristate "Krait Clock Controller"
depends on COMMON_CLK_QCOM && ARM
select KRAIT_CLOCKS
help
Support for the Krait CPU clocks on Qualcomm devices.
Say Y if you want to support CPU frequency scaling.

View File

@ -11,6 +11,8 @@ clk-qcom-y += clk-branch.o
clk-qcom-y += clk-regmap-divider.o clk-qcom-y += clk-regmap-divider.o
clk-qcom-y += clk-regmap-mux.o clk-qcom-y += clk-regmap-mux.o
clk-qcom-y += clk-regmap-mux-div.o clk-qcom-y += clk-regmap-mux-div.o
clk-qcom-$(CONFIG_KRAIT_CLOCKS) += clk-krait.o
clk-qcom-y += clk-hfpll.o
clk-qcom-y += reset.o clk-qcom-y += reset.o
clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o clk-qcom-$(CONFIG_QCOM_GDSC) += gdsc.o
@ -46,3 +48,6 @@ obj-$(CONFIG_SDM_GCC_660) += gcc-sdm660.o
obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o obj-$(CONFIG_SDM_GCC_845) += gcc-sdm845.o
obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o obj-$(CONFIG_SDM_VIDEOCC_845) += videocc-sdm845.o
obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o obj-$(CONFIG_SPMI_PMIC_CLKDIV) += clk-spmi-pmic-div.o
obj-$(CONFIG_KPSS_XCC) += kpss-xcc.o
obj-$(CONFIG_QCOM_HFPLL) += hfpll.o
obj-$(CONFIG_KRAITCC) += krait-cc.o

View File

@ -0,0 +1,244 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018, The Linux Foundation. All rights reserved.
#include <linux/kernel.h>
#include <linux/export.h>
#include <linux/regmap.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk-provider.h>
#include <linux/spinlock.h>
#include "clk-regmap.h"
#include "clk-hfpll.h"
#define PLL_OUTCTRL BIT(0)
#define PLL_BYPASSNL BIT(1)
#define PLL_RESET_N BIT(2)
/* Initialize a HFPLL at a given rate and enable it. */
static void __clk_hfpll_init_once(struct clk_hw *hw)
{
struct clk_hfpll *h = to_clk_hfpll(hw);
struct hfpll_data const *hd = h->d;
struct regmap *regmap = h->clkr.regmap;
if (likely(h->init_done))
return;
/* Configure PLL parameters for integer mode. */
if (hd->config_val)
regmap_write(regmap, hd->config_reg, hd->config_val);
regmap_write(regmap, hd->m_reg, 0);
regmap_write(regmap, hd->n_reg, 1);
if (hd->user_reg) {
u32 regval = hd->user_val;
unsigned long rate;
rate = clk_hw_get_rate(hw);
/* Pick the right VCO. */
if (hd->user_vco_mask && rate > hd->low_vco_max_rate)
regval |= hd->user_vco_mask;
regmap_write(regmap, hd->user_reg, regval);
}
if (hd->droop_reg)
regmap_write(regmap, hd->droop_reg, hd->droop_val);
h->init_done = true;
}
static void __clk_hfpll_enable(struct clk_hw *hw)
{
struct clk_hfpll *h = to_clk_hfpll(hw);
struct hfpll_data const *hd = h->d;
struct regmap *regmap = h->clkr.regmap;
u32 val;
__clk_hfpll_init_once(hw);
/* Disable PLL bypass mode. */
regmap_update_bits(regmap, hd->mode_reg, PLL_BYPASSNL, PLL_BYPASSNL);
/*
* H/W requires a 5us delay between disabling the bypass and
* de-asserting the reset. Delay 10us just to be safe.
*/
udelay(10);
/* De-assert active-low PLL reset. */
regmap_update_bits(regmap, hd->mode_reg, PLL_RESET_N, PLL_RESET_N);
/* Wait for PLL to lock. */
if (hd->status_reg) {
do {
regmap_read(regmap, hd->status_reg, &val);
} while (!(val & BIT(hd->lock_bit)));
} else {
udelay(60);
}
/* Enable PLL output. */
regmap_update_bits(regmap, hd->mode_reg, PLL_OUTCTRL, PLL_OUTCTRL);
}
/* Enable an already-configured HFPLL. */
static int clk_hfpll_enable(struct clk_hw *hw)
{
unsigned long flags;
struct clk_hfpll *h = to_clk_hfpll(hw);
struct hfpll_data const *hd = h->d;
struct regmap *regmap = h->clkr.regmap;
u32 mode;
spin_lock_irqsave(&h->lock, flags);
regmap_read(regmap, hd->mode_reg, &mode);
if (!(mode & (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)))
__clk_hfpll_enable(hw);
spin_unlock_irqrestore(&h->lock, flags);
return 0;
}
static void __clk_hfpll_disable(struct clk_hfpll *h)
{
struct hfpll_data const *hd = h->d;
struct regmap *regmap = h->clkr.regmap;
/*
* Disable the PLL output, disable test mode, enable the bypass mode,
* and assert the reset.
*/
regmap_update_bits(regmap, hd->mode_reg,
PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL, 0);
}
static void clk_hfpll_disable(struct clk_hw *hw)
{
struct clk_hfpll *h = to_clk_hfpll(hw);
unsigned long flags;
spin_lock_irqsave(&h->lock, flags);
__clk_hfpll_disable(h);
spin_unlock_irqrestore(&h->lock, flags);
}
static long clk_hfpll_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
struct clk_hfpll *h = to_clk_hfpll(hw);
struct hfpll_data const *hd = h->d;
unsigned long rrate;
rate = clamp(rate, hd->min_rate, hd->max_rate);
rrate = DIV_ROUND_UP(rate, *parent_rate) * *parent_rate;
if (rrate > hd->max_rate)
rrate -= *parent_rate;
return rrate;
}
/*
* For optimization reasons, assumes no downstream clocks are actively using
* it.
*/
static int clk_hfpll_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct clk_hfpll *h = to_clk_hfpll(hw);
struct hfpll_data const *hd = h->d;
struct regmap *regmap = h->clkr.regmap;
unsigned long flags;
u32 l_val, val;
bool enabled;
l_val = rate / parent_rate;
spin_lock_irqsave(&h->lock, flags);
enabled = __clk_is_enabled(hw->clk);
if (enabled)
__clk_hfpll_disable(h);
/* Pick the right VCO. */
if (hd->user_reg && hd->user_vco_mask) {
regmap_read(regmap, hd->user_reg, &val);
if (rate <= hd->low_vco_max_rate)
val &= ~hd->user_vco_mask;
else
val |= hd->user_vco_mask;
regmap_write(regmap, hd->user_reg, val);
}
regmap_write(regmap, hd->l_reg, l_val);
if (enabled)
__clk_hfpll_enable(hw);
spin_unlock_irqrestore(&h->lock, flags);
return 0;
}
static unsigned long clk_hfpll_recalc_rate(struct clk_hw *hw,
unsigned long parent_rate)
{
struct clk_hfpll *h = to_clk_hfpll(hw);
struct hfpll_data const *hd = h->d;
struct regmap *regmap = h->clkr.regmap;
u32 l_val;
regmap_read(regmap, hd->l_reg, &l_val);
return l_val * parent_rate;
}
static void clk_hfpll_init(struct clk_hw *hw)
{
struct clk_hfpll *h = to_clk_hfpll(hw);
struct hfpll_data const *hd = h->d;
struct regmap *regmap = h->clkr.regmap;
u32 mode, status;
regmap_read(regmap, hd->mode_reg, &mode);
if (mode != (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL)) {
__clk_hfpll_init_once(hw);
return;
}
if (hd->status_reg) {
regmap_read(regmap, hd->status_reg, &status);
if (!(status & BIT(hd->lock_bit))) {
WARN(1, "HFPLL %s is ON, but not locked!\n",
__clk_get_name(hw->clk));
clk_hfpll_disable(hw);
__clk_hfpll_init_once(hw);
}
}
}
static int hfpll_is_enabled(struct clk_hw *hw)
{
struct clk_hfpll *h = to_clk_hfpll(hw);
struct hfpll_data const *hd = h->d;
struct regmap *regmap = h->clkr.regmap;
u32 mode;
regmap_read(regmap, hd->mode_reg, &mode);
mode &= 0x7;
return mode == (PLL_BYPASSNL | PLL_RESET_N | PLL_OUTCTRL);
}
const struct clk_ops clk_ops_hfpll = {
.enable = clk_hfpll_enable,
.disable = clk_hfpll_disable,
.is_enabled = hfpll_is_enabled,
.round_rate = clk_hfpll_round_rate,
.set_rate = clk_hfpll_set_rate,
.recalc_rate = clk_hfpll_recalc_rate,
.init = clk_hfpll_init,
};
EXPORT_SYMBOL_GPL(clk_ops_hfpll);

View File

@ -0,0 +1,44 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __QCOM_CLK_HFPLL_H__
#define __QCOM_CLK_HFPLL_H__
#include <linux/clk-provider.h>
#include <linux/spinlock.h>
#include "clk-regmap.h"
struct hfpll_data {
u32 mode_reg;
u32 l_reg;
u32 m_reg;
u32 n_reg;
u32 user_reg;
u32 droop_reg;
u32 config_reg;
u32 status_reg;
u8 lock_bit;
u32 droop_val;
u32 config_val;
u32 user_val;
u32 user_vco_mask;
unsigned long low_vco_max_rate;
unsigned long min_rate;
unsigned long max_rate;
};
struct clk_hfpll {
struct hfpll_data const *d;
int init_done;
struct clk_regmap clkr;
spinlock_t lock;
};
#define to_clk_hfpll(_hw) \
container_of(to_clk_regmap(_hw), struct clk_hfpll, clkr)
extern const struct clk_ops clk_ops_hfpll;
#endif

View File

@ -0,0 +1,126 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018, The Linux Foundation. All rights reserved.
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk-provider.h>
#include <linux/spinlock.h>
#include <asm/krait-l2-accessors.h>
#include "clk-krait.h"
/* Secondary and primary muxes share the same cp15 register */
static DEFINE_SPINLOCK(krait_clock_reg_lock);
#define LPL_SHIFT 8
static void __krait_mux_set_sel(struct krait_mux_clk *mux, int sel)
{
unsigned long flags;
u32 regval;
spin_lock_irqsave(&krait_clock_reg_lock, flags);
regval = krait_get_l2_indirect_reg(mux->offset);
regval &= ~(mux->mask << mux->shift);
regval |= (sel & mux->mask) << mux->shift;
if (mux->lpl) {
regval &= ~(mux->mask << (mux->shift + LPL_SHIFT));
regval |= (sel & mux->mask) << (mux->shift + LPL_SHIFT);
}
krait_set_l2_indirect_reg(mux->offset, regval);
spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
/* Wait for switch to complete. */
mb();
udelay(1);
}
static int krait_mux_set_parent(struct clk_hw *hw, u8 index)
{
struct krait_mux_clk *mux = to_krait_mux_clk(hw);
u32 sel;
sel = clk_mux_index_to_val(mux->parent_map, 0, index);
mux->en_mask = sel;
/* Don't touch mux if CPU is off as it won't work */
if (__clk_is_enabled(hw->clk))
__krait_mux_set_sel(mux, sel);
mux->reparent = true;
return 0;
}
static u8 krait_mux_get_parent(struct clk_hw *hw)
{
struct krait_mux_clk *mux = to_krait_mux_clk(hw);
u32 sel;
sel = krait_get_l2_indirect_reg(mux->offset);
sel >>= mux->shift;
sel &= mux->mask;
mux->en_mask = sel;
return clk_mux_val_to_index(hw, mux->parent_map, 0, sel);
}
const struct clk_ops krait_mux_clk_ops = {
.set_parent = krait_mux_set_parent,
.get_parent = krait_mux_get_parent,
.determine_rate = __clk_mux_determine_rate_closest,
};
EXPORT_SYMBOL_GPL(krait_mux_clk_ops);
/* The divider can divide by 2, 4, 6 and 8. But we only really need div-2. */
static long krait_div2_round_rate(struct clk_hw *hw, unsigned long rate,
unsigned long *parent_rate)
{
*parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), rate * 2);
return DIV_ROUND_UP(*parent_rate, 2);
}
static int krait_div2_set_rate(struct clk_hw *hw, unsigned long rate,
unsigned long parent_rate)
{
struct krait_div2_clk *d = to_krait_div2_clk(hw);
unsigned long flags;
u32 val;
u32 mask = BIT(d->width) - 1;
if (d->lpl)
mask = mask << (d->shift + LPL_SHIFT) | mask << d->shift;
spin_lock_irqsave(&krait_clock_reg_lock, flags);
val = krait_get_l2_indirect_reg(d->offset);
val &= ~mask;
krait_set_l2_indirect_reg(d->offset, val);
spin_unlock_irqrestore(&krait_clock_reg_lock, flags);
return 0;
}
static unsigned long
krait_div2_recalc_rate(struct clk_hw *hw, unsigned long parent_rate)
{
struct krait_div2_clk *d = to_krait_div2_clk(hw);
u32 mask = BIT(d->width) - 1;
u32 div;
div = krait_get_l2_indirect_reg(d->offset);
div >>= d->shift;
div &= mask;
div = (div + 1) * 2;
return DIV_ROUND_UP(parent_rate, div);
}
const struct clk_ops krait_div2_clk_ops = {
.round_rate = krait_div2_round_rate,
.set_rate = krait_div2_set_rate,
.recalc_rate = krait_div2_recalc_rate,
};
EXPORT_SYMBOL_GPL(krait_div2_clk_ops);

View File

@ -0,0 +1,40 @@
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef __QCOM_CLK_KRAIT_H
#define __QCOM_CLK_KRAIT_H
#include <linux/clk-provider.h>
struct krait_mux_clk {
unsigned int *parent_map;
u32 offset;
u32 mask;
u32 shift;
u32 en_mask;
bool lpl;
u8 safe_sel;
u8 old_index;
bool reparent;
struct clk_hw hw;
struct notifier_block clk_nb;
};
#define to_krait_mux_clk(_hw) container_of(_hw, struct krait_mux_clk, hw)
extern const struct clk_ops krait_mux_clk_ops;
struct krait_div2_clk {
u32 offset;
u8 width;
u32 shift;
bool lpl;
struct clk_hw hw;
};
#define to_krait_div2_clk(_hw) container_of(_hw, struct krait_div2_clk, hw)
extern const struct clk_ops krait_div2_clk_ops;
#endif

View File

@ -30,6 +30,7 @@
#include "clk-pll.h" #include "clk-pll.h"
#include "clk-rcg.h" #include "clk-rcg.h"
#include "clk-branch.h" #include "clk-branch.h"
#include "clk-hfpll.h"
#include "reset.h" #include "reset.h"
static struct clk_pll pll0 = { static struct clk_pll pll0 = {
@ -113,6 +114,84 @@ static struct clk_regmap pll8_vote = {
}, },
}; };
static struct hfpll_data hfpll0_data = {
.mode_reg = 0x3200,
.l_reg = 0x3208,
.m_reg = 0x320c,
.n_reg = 0x3210,
.config_reg = 0x3204,
.status_reg = 0x321c,
.config_val = 0x7845c665,
.droop_reg = 0x3214,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct clk_hfpll hfpll0 = {
.d = &hfpll0_data,
.clkr.hw.init = &(struct clk_init_data){
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.name = "hfpll0",
.ops = &clk_ops_hfpll,
.flags = CLK_IGNORE_UNUSED,
},
.lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock),
};
static struct hfpll_data hfpll1_data = {
.mode_reg = 0x3240,
.l_reg = 0x3248,
.m_reg = 0x324c,
.n_reg = 0x3250,
.config_reg = 0x3244,
.status_reg = 0x325c,
.config_val = 0x7845c665,
.droop_reg = 0x3314,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct clk_hfpll hfpll1 = {
.d = &hfpll1_data,
.clkr.hw.init = &(struct clk_init_data){
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.name = "hfpll1",
.ops = &clk_ops_hfpll,
.flags = CLK_IGNORE_UNUSED,
},
.lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock),
};
static struct hfpll_data hfpll_l2_data = {
.mode_reg = 0x3300,
.l_reg = 0x3308,
.m_reg = 0x330c,
.n_reg = 0x3310,
.config_reg = 0x3304,
.status_reg = 0x331c,
.config_val = 0x7845c665,
.droop_reg = 0x3314,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct clk_hfpll hfpll_l2 = {
.d = &hfpll_l2_data,
.clkr.hw.init = &(struct clk_init_data){
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.name = "hfpll_l2",
.ops = &clk_ops_hfpll,
.flags = CLK_IGNORE_UNUSED,
},
.lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
};
static struct clk_pll pll14 = { static struct clk_pll pll14 = {
.l_reg = 0x31c4, .l_reg = 0x31c4,
.m_reg = 0x31c8, .m_reg = 0x31c8,
@ -2797,6 +2876,9 @@ static struct clk_regmap *gcc_ipq806x_clks[] = {
[UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr, [UBI32_CORE2_CLK_SRC] = &ubi32_core2_src_clk.clkr,
[NSSTCM_CLK_SRC] = &nss_tcm_src.clkr, [NSSTCM_CLK_SRC] = &nss_tcm_src.clkr,
[NSSTCM_CLK] = &nss_tcm_clk.clkr, [NSSTCM_CLK] = &nss_tcm_clk.clkr,
[PLL9] = &hfpll0.clkr,
[PLL10] = &hfpll1.clkr,
[PLL12] = &hfpll_l2.clkr,
}; };
static const struct qcom_reset_map gcc_ipq806x_resets[] = { static const struct qcom_reset_map gcc_ipq806x_resets[] = {

View File

@ -30,6 +30,7 @@
#include "clk-pll.h" #include "clk-pll.h"
#include "clk-rcg.h" #include "clk-rcg.h"
#include "clk-branch.h" #include "clk-branch.h"
#include "clk-hfpll.h"
#include "reset.h" #include "reset.h"
static struct clk_pll pll3 = { static struct clk_pll pll3 = {
@ -86,6 +87,164 @@ static struct clk_regmap pll8_vote = {
}, },
}; };
static struct hfpll_data hfpll0_data = {
.mode_reg = 0x3200,
.l_reg = 0x3208,
.m_reg = 0x320c,
.n_reg = 0x3210,
.config_reg = 0x3204,
.status_reg = 0x321c,
.config_val = 0x7845c665,
.droop_reg = 0x3214,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct clk_hfpll hfpll0 = {
.d = &hfpll0_data,
.clkr.hw.init = &(struct clk_init_data){
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.name = "hfpll0",
.ops = &clk_ops_hfpll,
.flags = CLK_IGNORE_UNUSED,
},
.lock = __SPIN_LOCK_UNLOCKED(hfpll0.lock),
};
static struct hfpll_data hfpll1_8064_data = {
.mode_reg = 0x3240,
.l_reg = 0x3248,
.m_reg = 0x324c,
.n_reg = 0x3250,
.config_reg = 0x3244,
.status_reg = 0x325c,
.config_val = 0x7845c665,
.droop_reg = 0x3254,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct hfpll_data hfpll1_data = {
.mode_reg = 0x3300,
.l_reg = 0x3308,
.m_reg = 0x330c,
.n_reg = 0x3310,
.config_reg = 0x3304,
.status_reg = 0x331c,
.config_val = 0x7845c665,
.droop_reg = 0x3314,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct clk_hfpll hfpll1 = {
.d = &hfpll1_data,
.clkr.hw.init = &(struct clk_init_data){
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.name = "hfpll1",
.ops = &clk_ops_hfpll,
.flags = CLK_IGNORE_UNUSED,
},
.lock = __SPIN_LOCK_UNLOCKED(hfpll1.lock),
};
static struct hfpll_data hfpll2_data = {
.mode_reg = 0x3280,
.l_reg = 0x3288,
.m_reg = 0x328c,
.n_reg = 0x3290,
.config_reg = 0x3284,
.status_reg = 0x329c,
.config_val = 0x7845c665,
.droop_reg = 0x3294,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct clk_hfpll hfpll2 = {
.d = &hfpll2_data,
.clkr.hw.init = &(struct clk_init_data){
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.name = "hfpll2",
.ops = &clk_ops_hfpll,
.flags = CLK_IGNORE_UNUSED,
},
.lock = __SPIN_LOCK_UNLOCKED(hfpll2.lock),
};
static struct hfpll_data hfpll3_data = {
.mode_reg = 0x32c0,
.l_reg = 0x32c8,
.m_reg = 0x32cc,
.n_reg = 0x32d0,
.config_reg = 0x32c4,
.status_reg = 0x32dc,
.config_val = 0x7845c665,
.droop_reg = 0x32d4,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct clk_hfpll hfpll3 = {
.d = &hfpll3_data,
.clkr.hw.init = &(struct clk_init_data){
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.name = "hfpll3",
.ops = &clk_ops_hfpll,
.flags = CLK_IGNORE_UNUSED,
},
.lock = __SPIN_LOCK_UNLOCKED(hfpll3.lock),
};
static struct hfpll_data hfpll_l2_8064_data = {
.mode_reg = 0x3300,
.l_reg = 0x3308,
.m_reg = 0x330c,
.n_reg = 0x3310,
.config_reg = 0x3304,
.status_reg = 0x331c,
.config_val = 0x7845c665,
.droop_reg = 0x3314,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct hfpll_data hfpll_l2_data = {
.mode_reg = 0x3400,
.l_reg = 0x3408,
.m_reg = 0x340c,
.n_reg = 0x3410,
.config_reg = 0x3404,
.status_reg = 0x341c,
.config_val = 0x7845c665,
.droop_reg = 0x3414,
.droop_val = 0x0108c000,
.min_rate = 600000000UL,
.max_rate = 1800000000UL,
};
static struct clk_hfpll hfpll_l2 = {
.d = &hfpll_l2_data,
.clkr.hw.init = &(struct clk_init_data){
.parent_names = (const char *[]){ "pxo" },
.num_parents = 1,
.name = "hfpll_l2",
.ops = &clk_ops_hfpll,
.flags = CLK_IGNORE_UNUSED,
},
.lock = __SPIN_LOCK_UNLOCKED(hfpll_l2.lock),
};
static struct clk_pll pll14 = { static struct clk_pll pll14 = {
.l_reg = 0x31c4, .l_reg = 0x31c4,
.m_reg = 0x31c8, .m_reg = 0x31c8,
@ -3107,6 +3266,9 @@ static struct clk_regmap *gcc_msm8960_clks[] = {
[PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr, [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
[PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr, [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
[RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr, [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
[PLL9] = &hfpll0.clkr,
[PLL10] = &hfpll1.clkr,
[PLL12] = &hfpll_l2.clkr,
}; };
static const struct qcom_reset_map gcc_msm8960_resets[] = { static const struct qcom_reset_map gcc_msm8960_resets[] = {
@ -3318,6 +3480,11 @@ static struct clk_regmap *gcc_apq8064_clks[] = {
[PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr, [PMIC_ARB1_H_CLK] = &pmic_arb1_h_clk.clkr,
[PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr, [PMIC_SSBI2_CLK] = &pmic_ssbi2_clk.clkr,
[RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr, [RPM_MSG_RAM_H_CLK] = &rpm_msg_ram_h_clk.clkr,
[PLL9] = &hfpll0.clkr,
[PLL10] = &hfpll1.clkr,
[PLL12] = &hfpll_l2.clkr,
[PLL16] = &hfpll2.clkr,
[PLL17] = &hfpll3.clkr,
}; };
static const struct qcom_reset_map gcc_apq8064_resets[] = { static const struct qcom_reset_map gcc_apq8064_resets[] = {
@ -3477,6 +3644,11 @@ static int gcc_msm8960_probe(struct platform_device *pdev)
if (ret) if (ret)
return ret; return ret;
if (match->data == &gcc_apq8064_desc) {
hfpll1.d = &hfpll1_8064_data;
hfpll_l2.d = &hfpll_l2_8064_data;
}
tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1, tsens = platform_device_register_data(&pdev->dev, "qcom-tsens", -1,
NULL, 0); NULL, 0);
if (IS_ERR(tsens)) if (IS_ERR(tsens))

96
drivers/clk/qcom/hfpll.c Normal file
View File

@ -0,0 +1,96 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018, The Linux Foundation. All rights reserved.
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/of.h>
#include <linux/clk.h>
#include <linux/clk-provider.h>
#include <linux/regmap.h>
#include "clk-regmap.h"
#include "clk-hfpll.h"
static const struct hfpll_data hdata = {
.mode_reg = 0x00,
.l_reg = 0x04,
.m_reg = 0x08,
.n_reg = 0x0c,
.user_reg = 0x10,
.config_reg = 0x14,
.config_val = 0x430405d,
.status_reg = 0x1c,
.lock_bit = 16,
.user_val = 0x8,
.user_vco_mask = 0x100000,
.low_vco_max_rate = 1248000000,
.min_rate = 537600000UL,
.max_rate = 2900000000UL,
};
static const struct of_device_id qcom_hfpll_match_table[] = {
{ .compatible = "qcom,hfpll" },
{ }
};
MODULE_DEVICE_TABLE(of, qcom_hfpll_match_table);
static const struct regmap_config hfpll_regmap_config = {
.reg_bits = 32,
.reg_stride = 4,
.val_bits = 32,
.max_register = 0x30,
.fast_io = true,
};
static int qcom_hfpll_probe(struct platform_device *pdev)
{
struct resource *res;
struct device *dev = &pdev->dev;
void __iomem *base;
struct regmap *regmap;
struct clk_hfpll *h;
struct clk_init_data init = {
.parent_names = (const char *[]){ "xo" },
.num_parents = 1,
.ops = &clk_ops_hfpll,
};
h = devm_kzalloc(dev, sizeof(*h), GFP_KERNEL);
if (!h)
return -ENOMEM;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
regmap = devm_regmap_init_mmio(&pdev->dev, base, &hfpll_regmap_config);
if (IS_ERR(regmap))
return PTR_ERR(regmap);
if (of_property_read_string_index(dev->of_node, "clock-output-names",
0, &init.name))
return -ENODEV;
h->d = &hdata;
h->clkr.hw.init = &init;
spin_lock_init(&h->lock);
return devm_clk_register_regmap(&pdev->dev, &h->clkr);
}
static struct platform_driver qcom_hfpll_driver = {
.probe = qcom_hfpll_probe,
.driver = {
.name = "qcom-hfpll",
.of_match_table = qcom_hfpll_match_table,
},
};
module_platform_driver(qcom_hfpll_driver);
MODULE_DESCRIPTION("QCOM HFPLL Clock Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:qcom-hfpll");

View File

@ -0,0 +1,87 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018, The Linux Foundation. All rights reserved.
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.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>
static const char *aux_parents[] = {
"pll8_vote",
"pxo",
};
static unsigned int aux_parent_map[] = {
3,
0,
};
static const struct of_device_id kpss_xcc_match_table[] = {
{ .compatible = "qcom,kpss-acc-v1", .data = (void *)1UL },
{ .compatible = "qcom,kpss-gcc" },
{}
};
MODULE_DEVICE_TABLE(of, kpss_xcc_match_table);
static int kpss_xcc_driver_probe(struct platform_device *pdev)
{
const struct of_device_id *id;
struct clk *clk;
struct resource *res;
void __iomem *base;
const char *name;
id = of_match_device(kpss_xcc_match_table, &pdev->dev);
if (!id)
return -ENODEV;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
base = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(base))
return PTR_ERR(base);
if (id->data) {
if (of_property_read_string_index(pdev->dev.of_node,
"clock-output-names",
0, &name))
return -ENODEV;
base += 0x14;
} else {
name = "acpu_l2_aux";
base += 0x28;
}
clk = clk_register_mux_table(&pdev->dev, name, aux_parents,
ARRAY_SIZE(aux_parents), 0, base, 0, 0x3,
0, aux_parent_map, NULL);
platform_set_drvdata(pdev, clk);
return PTR_ERR_OR_ZERO(clk);
}
static int kpss_xcc_driver_remove(struct platform_device *pdev)
{
clk_unregister_mux(platform_get_drvdata(pdev));
return 0;
}
static struct platform_driver kpss_xcc_driver = {
.probe = kpss_xcc_driver_probe,
.remove = kpss_xcc_driver_remove,
.driver = {
.name = "kpss-xcc",
.of_match_table = kpss_xcc_match_table,
},
};
module_platform_driver(kpss_xcc_driver);
MODULE_DESCRIPTION("Krait Processor Sub System (KPSS) Clock Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:kpss-xcc");

397
drivers/clk/qcom/krait-cc.c Normal file
View File

@ -0,0 +1,397 @@
// SPDX-License-Identifier: GPL-2.0
// Copyright (c) 2018, The Linux Foundation. All rights reserved.
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.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>
#include "clk-krait.h"
static unsigned int sec_mux_map[] = {
2,
0,
};
static unsigned int pri_mux_map[] = {
1,
2,
0,
};
/*
* Notifier function for switching the muxes to safe parent
* while the hfpll is getting reprogrammed.
*/
static int krait_notifier_cb(struct notifier_block *nb,
unsigned long event,
void *data)
{
int ret = 0;
struct krait_mux_clk *mux = container_of(nb, struct krait_mux_clk,
clk_nb);
/* Switch to safe parent */
if (event == PRE_RATE_CHANGE) {
mux->old_index = krait_mux_clk_ops.get_parent(&mux->hw);
ret = krait_mux_clk_ops.set_parent(&mux->hw, mux->safe_sel);
mux->reparent = false;
/*
* By the time POST_RATE_CHANGE notifier is called,
* clk framework itself would have changed the parent for the new rate.
* Only otherwise, put back to the old parent.
*/
} else if (event == POST_RATE_CHANGE) {
if (!mux->reparent)
ret = krait_mux_clk_ops.set_parent(&mux->hw,
mux->old_index);
}
return notifier_from_errno(ret);
}
static int krait_notifier_register(struct device *dev, struct clk *clk,
struct krait_mux_clk *mux)
{
int ret = 0;
mux->clk_nb.notifier_call = krait_notifier_cb;
ret = clk_notifier_register(clk, &mux->clk_nb);
if (ret)
dev_err(dev, "failed to register clock notifier: %d\n", ret);
return ret;
}
static int
krait_add_div(struct device *dev, int id, const char *s, unsigned int offset)
{
struct krait_div2_clk *div;
struct clk_init_data init = {
.num_parents = 1,
.ops = &krait_div2_clk_ops,
.flags = CLK_SET_RATE_PARENT,
};
const char *p_names[1];
struct clk *clk;
div = devm_kzalloc(dev, sizeof(*div), GFP_KERNEL);
if (!div)
return -ENOMEM;
div->width = 2;
div->shift = 6;
div->lpl = id >= 0;
div->offset = offset;
div->hw.init = &init;
init.name = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
if (!init.name)
return -ENOMEM;
init.parent_names = p_names;
p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
if (!p_names[0]) {
kfree(init.name);
return -ENOMEM;
}
clk = devm_clk_register(dev, &div->hw);
kfree(p_names[0]);
kfree(init.name);
return PTR_ERR_OR_ZERO(clk);
}
static int
krait_add_sec_mux(struct device *dev, int id, const char *s,
unsigned int offset, bool unique_aux)
{
int ret;
struct krait_mux_clk *mux;
static const char *sec_mux_list[] = {
"acpu_aux",
"qsb",
};
struct clk_init_data init = {
.parent_names = sec_mux_list,
.num_parents = ARRAY_SIZE(sec_mux_list),
.ops = &krait_mux_clk_ops,
.flags = CLK_SET_RATE_PARENT,
};
struct clk *clk;
mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
if (!mux)
return -ENOMEM;
mux->offset = offset;
mux->lpl = id >= 0;
mux->mask = 0x3;
mux->shift = 2;
mux->parent_map = sec_mux_map;
mux->hw.init = &init;
mux->safe_sel = 0;
init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
if (!init.name)
return -ENOMEM;
if (unique_aux) {
sec_mux_list[0] = kasprintf(GFP_KERNEL, "acpu%s_aux", s);
if (!sec_mux_list[0]) {
clk = ERR_PTR(-ENOMEM);
goto err_aux;
}
}
clk = devm_clk_register(dev, &mux->hw);
ret = krait_notifier_register(dev, clk, mux);
if (ret)
goto unique_aux;
unique_aux:
if (unique_aux)
kfree(sec_mux_list[0]);
err_aux:
kfree(init.name);
return PTR_ERR_OR_ZERO(clk);
}
static struct clk *
krait_add_pri_mux(struct device *dev, int id, const char *s,
unsigned int offset)
{
int ret;
struct krait_mux_clk *mux;
const char *p_names[3];
struct clk_init_data init = {
.parent_names = p_names,
.num_parents = ARRAY_SIZE(p_names),
.ops = &krait_mux_clk_ops,
.flags = CLK_SET_RATE_PARENT,
};
struct clk *clk;
mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
if (!mux)
return ERR_PTR(-ENOMEM);
mux->mask = 0x3;
mux->shift = 0;
mux->offset = offset;
mux->lpl = id >= 0;
mux->parent_map = pri_mux_map;
mux->hw.init = &init;
mux->safe_sel = 2;
init.name = kasprintf(GFP_KERNEL, "krait%s_pri_mux", s);
if (!init.name)
return ERR_PTR(-ENOMEM);
p_names[0] = kasprintf(GFP_KERNEL, "hfpll%s", s);
if (!p_names[0]) {
clk = ERR_PTR(-ENOMEM);
goto err_p0;
}
p_names[1] = kasprintf(GFP_KERNEL, "hfpll%s_div", s);
if (!p_names[1]) {
clk = ERR_PTR(-ENOMEM);
goto err_p1;
}
p_names[2] = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s);
if (!p_names[2]) {
clk = ERR_PTR(-ENOMEM);
goto err_p2;
}
clk = devm_clk_register(dev, &mux->hw);
ret = krait_notifier_register(dev, clk, mux);
if (ret)
goto err_p3;
err_p3:
kfree(p_names[2]);
err_p2:
kfree(p_names[1]);
err_p1:
kfree(p_names[0]);
err_p0:
kfree(init.name);
return clk;
}
/* id < 0 for L2, otherwise id == physical CPU number */
static struct clk *krait_add_clks(struct device *dev, int id, bool unique_aux)
{
int ret;
unsigned int offset;
void *p = NULL;
const char *s;
struct clk *clk;
if (id >= 0) {
offset = 0x4501 + (0x1000 * id);
s = p = kasprintf(GFP_KERNEL, "%d", id);
if (!s)
return ERR_PTR(-ENOMEM);
} else {
offset = 0x500;
s = "_l2";
}
ret = krait_add_div(dev, id, s, offset);
if (ret) {
clk = ERR_PTR(ret);
goto err;
}
ret = krait_add_sec_mux(dev, id, s, offset, unique_aux);
if (ret) {
clk = ERR_PTR(ret);
goto err;
}
clk = krait_add_pri_mux(dev, id, s, offset);
err:
kfree(p);
return clk;
}
static struct clk *krait_of_get(struct of_phandle_args *clkspec, void *data)
{
unsigned int idx = clkspec->args[0];
struct clk **clks = data;
if (idx >= 5) {
pr_err("%s: invalid clock index %d\n", __func__, idx);
return ERR_PTR(-EINVAL);
}
return clks[idx] ? : ERR_PTR(-ENODEV);
}
static const struct of_device_id krait_cc_match_table[] = {
{ .compatible = "qcom,krait-cc-v1", (void *)1UL },
{ .compatible = "qcom,krait-cc-v2" },
{}
};
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 *clk;
struct clk **clks;
struct clk *l2_pri_mux_clk;
id = of_match_device(krait_cc_match_table, dev);
if (!id)
return -ENODEV;
/* 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) {
clk = clk_register_fixed_factor(dev, "acpu_aux",
"gpll0_vote", 0, 1, 2);
if (IS_ERR(clk))
return PTR_ERR(clk);
}
/* Krait configurations have at most 4 CPUs and one L2 */
clks = devm_kcalloc(dev, 5, sizeof(*clks), GFP_KERNEL);
if (!clks)
return -ENOMEM;
for_each_possible_cpu(cpu) {
clk = krait_add_clks(dev, cpu, id->data);
if (IS_ERR(clk))
return PTR_ERR(clk);
clks[cpu] = clk;
}
l2_pri_mux_clk = krait_add_clks(dev, -1, id->data);
if (IS_ERR(l2_pri_mux_clk))
return PTR_ERR(l2_pri_mux_clk);
clks[4] = l2_pri_mux_clk;
/*
* We don't want the CPU or L2 clocks to be turned off at late init
* if CPUFREQ or HOTPLUG configs are disabled. So, bump up the
* refcount of these clocks. Any cpufreq/hotplug manager can assume
* that the clocks have already been prepared and enabled by the time
* they take over.
*/
for_each_online_cpu(cpu) {
clk_prepare_enable(l2_pri_mux_clk);
WARN(clk_prepare_enable(clks[cpu]),
"Unable to turn on CPU%d clock", cpu);
}
/*
* Force reinit of HFPLLs and muxes to overwrite any potential
* incorrect configuration of HFPLLs and muxes by the bootloader.
* While at it, also make sure the cores are running at known rates
* and print the current rate.
*
* The clocks are set to aux clock rate first to make sure the
* secondary mux is not sourcing off of QSB. The rate is then set to
* two different rates to force a HFPLL reinit under all
* circumstances.
*/
cur_rate = clk_get_rate(l2_pri_mux_clk);
aux_rate = 384000000;
if (cur_rate == 1) {
pr_info("L2 @ QSB rate. Forcing new rate.\n");
cur_rate = aux_rate;
}
clk_set_rate(l2_pri_mux_clk, aux_rate);
clk_set_rate(l2_pri_mux_clk, 2);
clk_set_rate(l2_pri_mux_clk, cur_rate);
pr_info("L2 @ %lu KHz\n", clk_get_rate(l2_pri_mux_clk) / 1000);
for_each_possible_cpu(cpu) {
clk = clks[cpu];
cur_rate = clk_get_rate(clk);
if (cur_rate == 1) {
pr_info("CPU%d @ QSB rate. Forcing new rate.\n", cpu);
cur_rate = aux_rate;
}
clk_set_rate(clk, aux_rate);
clk_set_rate(clk, 2);
clk_set_rate(clk, cur_rate);
pr_info("CPU%d @ %lu KHz\n", cpu, clk_get_rate(clk) / 1000);
}
of_clk_add_provider(dev->of_node, krait_of_get, clks);
return 0;
}
static struct platform_driver krait_cc_driver = {
.probe = krait_cc_probe,
.driver = {
.name = "krait-cc",
.of_match_table = krait_cc_match_table,
},
};
module_platform_driver(krait_cc_driver);
MODULE_DESCRIPTION("Krait CPU Clock Driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:krait-cc");

View File

@ -80,16 +80,12 @@ static long rockchip_ddrclk_sip_round_rate(struct clk_hw *hw,
static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw) static u8 rockchip_ddrclk_get_parent(struct clk_hw *hw)
{ {
struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw); struct rockchip_ddrclk *ddrclk = to_rockchip_ddrclk_hw(hw);
int num_parents = clk_hw_get_num_parents(hw);
u32 val; u32 val;
val = clk_readl(ddrclk->reg_base + val = clk_readl(ddrclk->reg_base +
ddrclk->mux_offset) >> ddrclk->mux_shift; ddrclk->mux_offset) >> ddrclk->mux_shift;
val &= GENMASK(ddrclk->mux_width - 1, 0); val &= GENMASK(ddrclk->mux_width - 1, 0);
if (val >= num_parents)
return -EINVAL;
return val; return val;
} }

View File

@ -645,7 +645,7 @@ static struct rockchip_clk_branch rk3066a_clk_branches[] __initdata = {
GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS), GATE(HCLK_I2S1, "hclk_i2s1", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 3, GFLAGS),
GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS), GATE(HCLK_I2S2, "hclk_i2s2", "hclk_cpu", 0, RK2928_CLKGATE_CON(7), 4, GFLAGS),
GATE(HCLK_CIF1, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS), GATE(HCLK_CIF1, "hclk_cif1", "hclk_cpu", 0, RK2928_CLKGATE_CON(6), 6, GFLAGS),
GATE(0, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS), GATE(HCLK_HDMI, "hclk_hdmi", "hclk_cpu", 0, RK2928_CLKGATE_CON(4), 14, GFLAGS),
GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED, GATE(HCLK_OTG1, "hclk_usbotg1", "hclk_peri", CLK_IGNORE_UNUSED,
RK2928_CLKGATE_CON(5), 14, GFLAGS), RK2928_CLKGATE_CON(5), 14, GFLAGS),

View File

@ -83,22 +83,43 @@ static struct rockchip_pll_rate_table rk3288_pll_rates[] = {
RK3066_PLL_RATE( 768000000, 1, 64, 2), RK3066_PLL_RATE( 768000000, 1, 64, 2),
RK3066_PLL_RATE( 742500000, 8, 495, 2), RK3066_PLL_RATE( 742500000, 8, 495, 2),
RK3066_PLL_RATE( 696000000, 1, 58, 2), RK3066_PLL_RATE( 696000000, 1, 58, 2),
RK3066_PLL_RATE_NB(621000000, 1, 207, 8, 1),
RK3066_PLL_RATE( 600000000, 1, 50, 2), RK3066_PLL_RATE( 600000000, 1, 50, 2),
RK3066_PLL_RATE_NB(594000000, 1, 198, 8, 1), RK3066_PLL_RATE_NB(594000000, 1, 198, 8, 1),
RK3066_PLL_RATE( 552000000, 1, 46, 2), RK3066_PLL_RATE( 552000000, 1, 46, 2),
RK3066_PLL_RATE( 504000000, 1, 84, 4), RK3066_PLL_RATE( 504000000, 1, 84, 4),
RK3066_PLL_RATE( 500000000, 3, 125, 2), RK3066_PLL_RATE( 500000000, 3, 125, 2),
RK3066_PLL_RATE( 456000000, 1, 76, 4), RK3066_PLL_RATE( 456000000, 1, 76, 4),
RK3066_PLL_RATE( 428000000, 1, 107, 6),
RK3066_PLL_RATE( 408000000, 1, 68, 4), RK3066_PLL_RATE( 408000000, 1, 68, 4),
RK3066_PLL_RATE( 400000000, 3, 100, 2), RK3066_PLL_RATE( 400000000, 3, 100, 2),
RK3066_PLL_RATE_NB( 394000000, 1, 197, 12, 1),
RK3066_PLL_RATE( 384000000, 2, 128, 4), RK3066_PLL_RATE( 384000000, 2, 128, 4),
RK3066_PLL_RATE( 360000000, 1, 60, 4), RK3066_PLL_RATE( 360000000, 1, 60, 4),
RK3066_PLL_RATE_NB( 356000000, 1, 178, 12, 1),
RK3066_PLL_RATE_NB( 324000000, 1, 189, 14, 1),
RK3066_PLL_RATE( 312000000, 1, 52, 4), RK3066_PLL_RATE( 312000000, 1, 52, 4),
RK3066_PLL_RATE( 300000000, 1, 50, 4), RK3066_PLL_RATE_NB( 308000000, 1, 154, 12, 1),
RK3066_PLL_RATE( 297000000, 2, 198, 8), RK3066_PLL_RATE_NB( 303000000, 1, 202, 16, 1),
RK3066_PLL_RATE( 300000000, 1, 75, 6),
RK3066_PLL_RATE_NB( 297750000, 2, 397, 16, 1),
RK3066_PLL_RATE_NB( 293250000, 2, 391, 16, 1),
RK3066_PLL_RATE_NB( 292500000, 1, 195, 16, 1),
RK3066_PLL_RATE( 273600000, 1, 114, 10),
RK3066_PLL_RATE_NB( 273000000, 1, 182, 16, 1),
RK3066_PLL_RATE_NB( 270000000, 1, 180, 16, 1),
RK3066_PLL_RATE_NB( 266250000, 2, 355, 16, 1),
RK3066_PLL_RATE_NB( 256500000, 1, 171, 16, 1),
RK3066_PLL_RATE( 252000000, 1, 84, 8), RK3066_PLL_RATE( 252000000, 1, 84, 8),
RK3066_PLL_RATE( 216000000, 1, 72, 8), RK3066_PLL_RATE_NB( 250500000, 1, 167, 16, 1),
RK3066_PLL_RATE( 148500000, 2, 99, 8), RK3066_PLL_RATE_NB( 243428571, 1, 142, 14, 1),
RK3066_PLL_RATE( 238000000, 1, 119, 12),
RK3066_PLL_RATE_NB( 219750000, 2, 293, 16, 1),
RK3066_PLL_RATE_NB( 216000000, 1, 144, 16, 1),
RK3066_PLL_RATE_NB( 213000000, 1, 142, 16, 1),
RK3066_PLL_RATE( 195428571, 1, 114, 14),
RK3066_PLL_RATE( 160000000, 1, 80, 12),
RK3066_PLL_RATE( 157500000, 1, 105, 16),
RK3066_PLL_RATE( 126000000, 1, 84, 16), RK3066_PLL_RATE( 126000000, 1, 84, 16),
RK3066_PLL_RATE( 48000000, 1, 64, 32), RK3066_PLL_RATE( 48000000, 1, 64, 32),
{ /* sentinel */ }, { /* sentinel */ },

View File

@ -813,22 +813,22 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc", MMC(SCLK_SDMMC_DRV, "sdmmc_drv", "clk_sdmmc",
RK3328_SDMMC_CON0, 1), RK3328_SDMMC_CON0, 1),
MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc", MMC(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "clk_sdmmc",
RK3328_SDMMC_CON1, 1), RK3328_SDMMC_CON1, 0),
MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio", MMC(SCLK_SDIO_DRV, "sdio_drv", "clk_sdio",
RK3328_SDIO_CON0, 1), RK3328_SDIO_CON0, 1),
MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio", MMC(SCLK_SDIO_SAMPLE, "sdio_sample", "clk_sdio",
RK3328_SDIO_CON1, 1), RK3328_SDIO_CON1, 0),
MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc", MMC(SCLK_EMMC_DRV, "emmc_drv", "clk_emmc",
RK3328_EMMC_CON0, 1), RK3328_EMMC_CON0, 1),
MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc", MMC(SCLK_EMMC_SAMPLE, "emmc_sample", "clk_emmc",
RK3328_EMMC_CON1, 1), RK3328_EMMC_CON1, 0),
MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "clk_sdmmc_ext", MMC(SCLK_SDMMC_EXT_DRV, "sdmmc_ext_drv", "clk_sdmmc_ext",
RK3328_SDMMC_EXT_CON0, 1), RK3328_SDMMC_EXT_CON0, 1),
MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "clk_sdmmc_ext", MMC(SCLK_SDMMC_EXT_SAMPLE, "sdmmc_ext_sample", "clk_sdmmc_ext",
RK3328_SDMMC_EXT_CON1, 1), RK3328_SDMMC_EXT_CON1, 0),
}; };
static const char *const rk3328_critical_clocks[] __initconst = { static const char *const rk3328_critical_clocks[] __initconst = {

View File

@ -273,6 +273,7 @@
#define IMX6QDL_CLK_MLB_PODF 260 #define IMX6QDL_CLK_MLB_PODF 260
#define IMX6QDL_CLK_EPIT1 261 #define IMX6QDL_CLK_EPIT1 261
#define IMX6QDL_CLK_EPIT2 262 #define IMX6QDL_CLK_EPIT2 262
#define IMX6QDL_CLK_END 263 #define IMX6QDL_CLK_MMDC_P0_IPG 263
#define IMX6QDL_CLK_END 264
#endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */ #endif /* __DT_BINDINGS_CLOCK_IMX6QDL_H */

View File

@ -175,6 +175,8 @@
#define IMX6SL_CLK_SSI2_IPG 162 #define IMX6SL_CLK_SSI2_IPG 162
#define IMX6SL_CLK_SSI3_IPG 163 #define IMX6SL_CLK_SSI3_IPG 163
#define IMX6SL_CLK_SPDIF_GCLK 164 #define IMX6SL_CLK_SPDIF_GCLK 164
#define IMX6SL_CLK_END 165 #define IMX6SL_CLK_MMDC_P0_IPG 165
#define IMX6SL_CLK_MMDC_P1_IPG 166
#define IMX6SL_CLK_END 167
#endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */ #endif /* __DT_BINDINGS_CLOCK_IMX6SL_H */

View File

@ -203,7 +203,8 @@
#define IMX6SLL_CLK_GPIO4 176 #define IMX6SLL_CLK_GPIO4 176
#define IMX6SLL_CLK_GPIO5 177 #define IMX6SLL_CLK_GPIO5 177
#define IMX6SLL_CLK_GPIO6 178 #define IMX6SLL_CLK_GPIO6 178
#define IMX6SLL_CLK_MMDC_P1_IPG 179
#define IMX6SLL_CLK_END 179 #define IMX6SLL_CLK_END 180
#endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */ #endif /* __DT_BINDINGS_CLOCK_IMX6SLL_H */

View File

@ -279,6 +279,7 @@
#define IMX6SX_CLK_LVDS2_OUT 266 #define IMX6SX_CLK_LVDS2_OUT 266
#define IMX6SX_CLK_LVDS2_IN 267 #define IMX6SX_CLK_LVDS2_IN 267
#define IMX6SX_CLK_ANACLK2 268 #define IMX6SX_CLK_ANACLK2 268
#define IMX6SX_CLK_CLK_END 269 #define IMX6SX_CLK_MMDC_P1_IPG 269
#define IMX6SX_CLK_CLK_END 270
#endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */ #endif /* __DT_BINDINGS_CLOCK_IMX6SX_H */

View File

@ -259,7 +259,8 @@
#define IMX6UL_CLK_GPIO3 246 #define IMX6UL_CLK_GPIO3 246
#define IMX6UL_CLK_GPIO4 247 #define IMX6UL_CLK_GPIO4 247
#define IMX6UL_CLK_GPIO5 248 #define IMX6UL_CLK_GPIO5 248
#define IMX6UL_CLK_MMDC_P1_IPG 249
#define IMX6UL_CLK_END 249 #define IMX6UL_CLK_END 250
#endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */ #endif /* __DT_BINDINGS_CLOCK_IMX6UL_H */

View File

@ -319,5 +319,7 @@
#define CE3_SRC 303 #define CE3_SRC 303
#define CE3_CORE_CLK 304 #define CE3_CORE_CLK 304
#define CE3_H_CLK 305 #define CE3_H_CLK 305
#define PLL16 306
#define PLL17 307
#endif #endif

View File

@ -139,8 +139,9 @@
#define HCLK_CIF1 470 #define HCLK_CIF1 470
#define HCLK_VEPU 471 #define HCLK_VEPU 471
#define HCLK_VDPU 472 #define HCLK_VDPU 472
#define HCLK_HDMI 473
#define CLK_NR_CLKS (HCLK_VDPU + 1) #define CLK_NR_CLKS (HCLK_HDMI + 1)
/* soft-reset indices */ /* soft-reset indices */
#define SRST_MCORE 2 #define SRST_MCORE 2