Merge branches 'clk-amlogic', 'clk-allwinner', 'clk-rockchip' and 'clk-qcom' into clk-next
* clk-amlogic: clk: meson: Do not enable by default during compile testing clk: meson-g12a: add missing fclk_div2 to spicc * clk-allwinner: clk: sunxi-ng: ccu: add Display Engine 3.3 (DE33) support dt-bindings: allwinner: add H616 DE33 clock binding clk: sunxi-ng: h616: Add LVDS reset for LCD TCON dt-bindings: clock: sun50i-h616-ccu: Add LVDS reset clk: sunxi: Do not enable by default during compile testing clk: sunxi-ng: Do not enable by default during compile testing * clk-rockchip: clk: rockchip: rk3528: add slab.h header include clk: rockchip: rk3576: add missing slab.h include clk: rockchip: rename gate-grf clk file clk: rockchip: rename branch_muxgrf to branch_grf_mux clk: rockchip: Pass NULL as reg pointer when registering GRF MMC clocks clk: rockchip: rk3036: mark ddrphy as critical clk: rockchip: rk3036: fix implementation of usb480m clock mux dt-bindings: clock: rk3036: add SCLK_USB480M clock-id clk: rockchip: rk3528: Add SD/SDIO tuning clocks in GRF region clk: rockchip: Support MMC clocks in GRF region dt-bindings: clock: Add GRF clock definition for RK3528 clk: rockchip: add GATE_GRFs for SAI MCLKOUT to rk3576 clk: rockchip: introduce GRF gates clk: rockchip: introduce auxiliary GRFs dt-bindings: clock: rk3576: add IOC gated clocks clk: rockchip: rk3568: Add PLL rate for 33.3MHz clk: rockchip: Drop empty init callback for rk3588 PLL type clk: rockchip: rk3588: Add PLL rate for 1500 MHz * clk-qcom: clk: qcom: gcc-x1e80100: Set FORCE MEM CORE for UFS clocks clk: qcom: gcc: Set FORCE_MEM_CORE_ON for gcc_ufs_axi_clk for 8650/8750 clk: qcom: rpmh: make clkaN optional clk: qcom: Add support for Camera Clock Controller on QCS8300 clk: qcom: gcc-msm8939: Fix mclk0 & mclk1 for 24 MHz dt-bindings: clock: add SM6350 QCOM video clock bindings clk: qcom: gpucc-sm6350: Add *_wait_val values for GDSCs clk: qcom: gcc-sm6350: Add *_wait_val values for GDSCs clk: qcom: dispcc-sm6350: Add *_wait_val values for GDSCs clk: qcom: camcc-sm6350: Add *_wait_val values for GDSCs clk: qcom: Fix missing error check for dev_pm_domain_attach()
This commit is contained in:
@@ -25,6 +25,7 @@ properties:
|
||||
- const: allwinner,sun50i-a64-de2-clk
|
||||
- const: allwinner,sun50i-h5-de2-clk
|
||||
- const: allwinner,sun50i-h6-de3-clk
|
||||
- const: allwinner,sun50i-h616-de33-clk
|
||||
- items:
|
||||
- const: allwinner,sun8i-r40-de2-clk
|
||||
- const: allwinner,sun8i-h3-de2-clk
|
||||
|
||||
@@ -14,6 +14,7 @@ description: |
|
||||
domains on Qualcomm SoCs.
|
||||
|
||||
See also::
|
||||
include/dt-bindings/clock/qcom,sm6350-videocc.h
|
||||
include/dt-bindings/clock/qcom,videocc-sc7180.h
|
||||
include/dt-bindings/clock/qcom,videocc-sc7280.h
|
||||
include/dt-bindings/clock/qcom,videocc-sdm845.h
|
||||
@@ -26,6 +27,7 @@ properties:
|
||||
- qcom,sc7180-videocc
|
||||
- qcom,sc7280-videocc
|
||||
- qcom,sdm845-videocc
|
||||
- qcom,sm6350-videocc
|
||||
- qcom,sm8150-videocc
|
||||
- qcom,sm8250-videocc
|
||||
|
||||
@@ -87,6 +89,24 @@ allOf:
|
||||
- const: bi_tcxo
|
||||
- const: bi_tcxo_ao
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
enum:
|
||||
- qcom,sm6350-videocc
|
||||
then:
|
||||
properties:
|
||||
clocks:
|
||||
items:
|
||||
- description: Video AHB clock from GCC
|
||||
- description: Board XO source
|
||||
- description: Sleep Clock source
|
||||
clock-names:
|
||||
items:
|
||||
- const: iface
|
||||
- const: bi_tcxo
|
||||
- const: sleep_clk
|
||||
|
||||
- if:
|
||||
properties:
|
||||
compatible:
|
||||
|
||||
@@ -55,7 +55,7 @@ config COMMON_CLK_MESON_CPU_DYNDIV
|
||||
config COMMON_CLK_MESON8B
|
||||
bool "Meson8 SoC Clock controller support"
|
||||
depends on ARM
|
||||
default y
|
||||
default ARCH_MESON
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_CLKC_UTILS
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
@@ -70,7 +70,7 @@ config COMMON_CLK_MESON8B
|
||||
config COMMON_CLK_GXBB
|
||||
tristate "GXBB and GXL SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
default ARCH_MESON
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_VID_PLL_DIV
|
||||
@@ -86,7 +86,7 @@ config COMMON_CLK_GXBB
|
||||
config COMMON_CLK_AXG
|
||||
tristate "AXG SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
default ARCH_MESON
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
@@ -136,7 +136,7 @@ config COMMON_CLK_A1_PERIPHERALS
|
||||
config COMMON_CLK_C3_PLL
|
||||
tristate "Amlogic C3 PLL clock controller"
|
||||
depends on ARM64
|
||||
default y
|
||||
default ARCH_MESON
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_PLL
|
||||
select COMMON_CLK_MESON_CLKC_UTILS
|
||||
@@ -149,7 +149,7 @@ config COMMON_CLK_C3_PLL
|
||||
config COMMON_CLK_C3_PERIPHERALS
|
||||
tristate "Amlogic C3 peripherals clock controller"
|
||||
depends on ARM64
|
||||
default y
|
||||
default ARCH_MESON
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_CLKC_UTILS
|
||||
@@ -163,7 +163,7 @@ config COMMON_CLK_C3_PERIPHERALS
|
||||
config COMMON_CLK_G12A
|
||||
tristate "G12 and SM1 SoC clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
default ARCH_MESON
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
@@ -181,7 +181,7 @@ config COMMON_CLK_G12A
|
||||
config COMMON_CLK_S4_PLL
|
||||
tristate "S4 SoC PLL clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
default ARCH_MESON
|
||||
select COMMON_CLK_MESON_CLKC_UTILS
|
||||
select COMMON_CLK_MESON_MPLL
|
||||
select COMMON_CLK_MESON_PLL
|
||||
@@ -194,7 +194,7 @@ config COMMON_CLK_S4_PLL
|
||||
config COMMON_CLK_S4_PERIPHERALS
|
||||
tristate "S4 SoC peripherals clock controllers support"
|
||||
depends on ARM64
|
||||
default y
|
||||
default ARCH_MESON
|
||||
select COMMON_CLK_MESON_CLKC_UTILS
|
||||
select COMMON_CLK_MESON_REGMAP
|
||||
select COMMON_CLK_MESON_DUALDIV
|
||||
|
||||
@@ -4093,6 +4093,7 @@ static const struct clk_parent_data spicc_sclk_parent_data[] = {
|
||||
{ .hw = &g12a_clk81.hw },
|
||||
{ .hw = &g12a_fclk_div4.hw },
|
||||
{ .hw = &g12a_fclk_div3.hw },
|
||||
{ .hw = &g12a_fclk_div2.hw },
|
||||
{ .hw = &g12a_fclk_div5.hw },
|
||||
{ .hw = &g12a_fclk_div7.hw },
|
||||
};
|
||||
|
||||
@@ -111,7 +111,11 @@ static int qcom_apcs_sdx55_clk_probe(struct platform_device *pdev)
|
||||
* driver, there seems to be no better place to do this. So do it here!
|
||||
*/
|
||||
cpu_dev = get_cpu_device(0);
|
||||
dev_pm_domain_attach(cpu_dev, true);
|
||||
ret = dev_pm_domain_attach(cpu_dev, true);
|
||||
if (ret) {
|
||||
dev_err_probe(dev, ret, "can't get PM domain: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
#include <linux/pm_runtime.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
#include <dt-bindings/clock/qcom,sa8775p-camcc.h>
|
||||
#include <dt-bindings/clock/qcom,qcs8300-camcc.h>
|
||||
|
||||
#include "clk-alpha-pll.h"
|
||||
#include "clk-branch.h"
|
||||
@@ -1681,6 +1681,24 @@ static struct clk_branch cam_cc_sm_obs_clk = {
|
||||
},
|
||||
};
|
||||
|
||||
static struct clk_branch cam_cc_titan_top_accu_shift_clk = {
|
||||
.halt_reg = 0x131f0,
|
||||
.halt_check = BRANCH_HALT_VOTED,
|
||||
.clkr = {
|
||||
.enable_reg = 0x131f0,
|
||||
.enable_mask = BIT(0),
|
||||
.hw.init = &(const struct clk_init_data) {
|
||||
.name = "cam_cc_titan_top_accu_shift_clk",
|
||||
.parent_hws = (const struct clk_hw*[]) {
|
||||
&cam_cc_xo_clk_src.clkr.hw,
|
||||
},
|
||||
.num_parents = 1,
|
||||
.flags = CLK_SET_RATE_PARENT,
|
||||
.ops = &clk_branch2_ops,
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
static struct gdsc cam_cc_titan_top_gdsc = {
|
||||
.gdscr = 0x131bc,
|
||||
.en_rest_wait_val = 0x2,
|
||||
@@ -1775,6 +1793,7 @@ static struct clk_regmap *cam_cc_sa8775p_clocks[] = {
|
||||
[CAM_CC_SLEEP_CLK_SRC] = &cam_cc_sleep_clk_src.clkr,
|
||||
[CAM_CC_SLOW_AHB_CLK_SRC] = &cam_cc_slow_ahb_clk_src.clkr,
|
||||
[CAM_CC_SM_OBS_CLK] = &cam_cc_sm_obs_clk.clkr,
|
||||
[CAM_CC_TITAN_TOP_ACCU_SHIFT_CLK] = NULL,
|
||||
[CAM_CC_XO_CLK_SRC] = &cam_cc_xo_clk_src.clkr,
|
||||
[CAM_CC_QDSS_DEBUG_XO_CLK] = &cam_cc_qdss_debug_xo_clk.clkr,
|
||||
};
|
||||
@@ -1811,6 +1830,7 @@ static const struct qcom_cc_desc cam_cc_sa8775p_desc = {
|
||||
};
|
||||
|
||||
static const struct of_device_id cam_cc_sa8775p_match_table[] = {
|
||||
{ .compatible = "qcom,qcs8300-camcc" },
|
||||
{ .compatible = "qcom,sa8775p-camcc" },
|
||||
{ }
|
||||
};
|
||||
@@ -1841,10 +1861,83 @@ static int cam_cc_sa8775p_probe(struct platform_device *pdev)
|
||||
clk_lucid_evo_pll_configure(&cam_cc_pll4, regmap, &cam_cc_pll4_config);
|
||||
clk_lucid_evo_pll_configure(&cam_cc_pll5, regmap, &cam_cc_pll5_config);
|
||||
|
||||
/* Keep some clocks always enabled */
|
||||
qcom_branch_set_clk_en(regmap, 0x13194); /* CAM_CC_CAMNOC_XO_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x131ec); /* CAM_CC_GDSC_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x13208); /* CAM_CC_SLEEP_CLK */
|
||||
if (device_is_compatible(&pdev->dev, "qcom,qcs8300-camcc")) {
|
||||
cam_cc_camnoc_axi_clk_src.cmd_rcgr = 0x13154;
|
||||
cam_cc_camnoc_axi_clk.halt_reg = 0x1316c;
|
||||
cam_cc_camnoc_axi_clk.clkr.enable_reg = 0x1316c;
|
||||
cam_cc_camnoc_dcd_xo_clk.halt_reg = 0x13174;
|
||||
cam_cc_camnoc_dcd_xo_clk.clkr.enable_reg = 0x13174;
|
||||
|
||||
cam_cc_csi0phytimer_clk_src.cmd_rcgr = 0x15054;
|
||||
cam_cc_csi1phytimer_clk_src.cmd_rcgr = 0x15078;
|
||||
cam_cc_csi2phytimer_clk_src.cmd_rcgr = 0x15098;
|
||||
cam_cc_csid_clk_src.cmd_rcgr = 0x13134;
|
||||
|
||||
cam_cc_mclk0_clk_src.cmd_rcgr = 0x15000;
|
||||
cam_cc_mclk1_clk_src.cmd_rcgr = 0x1501c;
|
||||
cam_cc_mclk2_clk_src.cmd_rcgr = 0x15038;
|
||||
|
||||
cam_cc_fast_ahb_clk_src.cmd_rcgr = 0x13104;
|
||||
cam_cc_slow_ahb_clk_src.cmd_rcgr = 0x1311c;
|
||||
cam_cc_xo_clk_src.cmd_rcgr = 0x131b8;
|
||||
cam_cc_sleep_clk_src.cmd_rcgr = 0x131d4;
|
||||
|
||||
cam_cc_core_ahb_clk.halt_reg = 0x131b4;
|
||||
cam_cc_core_ahb_clk.clkr.enable_reg = 0x131b4;
|
||||
|
||||
cam_cc_cpas_ahb_clk.halt_reg = 0x130f4;
|
||||
cam_cc_cpas_ahb_clk.clkr.enable_reg = 0x130f4;
|
||||
cam_cc_cpas_fast_ahb_clk.halt_reg = 0x130fc;
|
||||
cam_cc_cpas_fast_ahb_clk.clkr.enable_reg = 0x130fc;
|
||||
|
||||
cam_cc_csi0phytimer_clk.halt_reg = 0x1506c;
|
||||
cam_cc_csi0phytimer_clk.clkr.enable_reg = 0x1506c;
|
||||
cam_cc_csi1phytimer_clk.halt_reg = 0x15090;
|
||||
cam_cc_csi1phytimer_clk.clkr.enable_reg = 0x15090;
|
||||
cam_cc_csi2phytimer_clk.halt_reg = 0x150b0;
|
||||
cam_cc_csi2phytimer_clk.clkr.enable_reg = 0x150b0;
|
||||
cam_cc_csid_clk.halt_reg = 0x1314c;
|
||||
cam_cc_csid_clk.clkr.enable_reg = 0x1314c;
|
||||
cam_cc_csid_csiphy_rx_clk.halt_reg = 0x15074;
|
||||
cam_cc_csid_csiphy_rx_clk.clkr.enable_reg = 0x15074;
|
||||
cam_cc_csiphy0_clk.halt_reg = 0x15070;
|
||||
cam_cc_csiphy0_clk.clkr.enable_reg = 0x15070;
|
||||
cam_cc_csiphy1_clk.halt_reg = 0x15094;
|
||||
cam_cc_csiphy1_clk.clkr.enable_reg = 0x15094;
|
||||
cam_cc_csiphy2_clk.halt_reg = 0x150b4;
|
||||
cam_cc_csiphy2_clk.clkr.enable_reg = 0x150b4;
|
||||
|
||||
cam_cc_mclk0_clk.halt_reg = 0x15018;
|
||||
cam_cc_mclk0_clk.clkr.enable_reg = 0x15018;
|
||||
cam_cc_mclk1_clk.halt_reg = 0x15034;
|
||||
cam_cc_mclk1_clk.clkr.enable_reg = 0x15034;
|
||||
cam_cc_mclk2_clk.halt_reg = 0x15050;
|
||||
cam_cc_mclk2_clk.clkr.enable_reg = 0x15050;
|
||||
cam_cc_qdss_debug_xo_clk.halt_reg = 0x1319c;
|
||||
cam_cc_qdss_debug_xo_clk.clkr.enable_reg = 0x1319c;
|
||||
|
||||
cam_cc_titan_top_gdsc.gdscr = 0x131a0;
|
||||
|
||||
cam_cc_sa8775p_clocks[CAM_CC_CCI_3_CLK] = NULL;
|
||||
cam_cc_sa8775p_clocks[CAM_CC_CCI_3_CLK_SRC] = NULL;
|
||||
cam_cc_sa8775p_clocks[CAM_CC_CSI3PHYTIMER_CLK] = NULL;
|
||||
cam_cc_sa8775p_clocks[CAM_CC_CSI3PHYTIMER_CLK_SRC] = NULL;
|
||||
cam_cc_sa8775p_clocks[CAM_CC_CSIPHY3_CLK] = NULL;
|
||||
cam_cc_sa8775p_clocks[CAM_CC_MCLK3_CLK] = NULL;
|
||||
cam_cc_sa8775p_clocks[CAM_CC_MCLK3_CLK_SRC] = NULL;
|
||||
cam_cc_sa8775p_clocks[CAM_CC_TITAN_TOP_ACCU_SHIFT_CLK] =
|
||||
&cam_cc_titan_top_accu_shift_clk.clkr;
|
||||
|
||||
/* Keep some clocks always enabled */
|
||||
qcom_branch_set_clk_en(regmap, 0x13178); /* CAM_CC_CAMNOC_XO_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x131d0); /* CAM_CC_GDSC_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x131ec); /* CAM_CC_SLEEP_CLK */
|
||||
} else {
|
||||
/* Keep some clocks always enabled */
|
||||
qcom_branch_set_clk_en(regmap, 0x13194); /* CAM_CC_CAMNOC_XO_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x131ec); /* CAM_CC_GDSC_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x13208); /* CAM_CC_SLEEP_CLK */
|
||||
}
|
||||
|
||||
ret = qcom_cc_really_probe(&pdev->dev, &cam_cc_sa8775p_desc, regmap);
|
||||
|
||||
|
||||
@@ -1695,6 +1695,9 @@ static struct clk_branch camcc_sys_tmr_clk = {
|
||||
|
||||
static struct gdsc bps_gdsc = {
|
||||
.gdscr = 0x6004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "bps_gdsc",
|
||||
},
|
||||
@@ -1704,6 +1707,9 @@ static struct gdsc bps_gdsc = {
|
||||
|
||||
static struct gdsc ipe_0_gdsc = {
|
||||
.gdscr = 0x7004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "ipe_0_gdsc",
|
||||
},
|
||||
@@ -1713,6 +1719,9 @@ static struct gdsc ipe_0_gdsc = {
|
||||
|
||||
static struct gdsc ife_0_gdsc = {
|
||||
.gdscr = 0x9004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "ife_0_gdsc",
|
||||
},
|
||||
@@ -1721,6 +1730,9 @@ static struct gdsc ife_0_gdsc = {
|
||||
|
||||
static struct gdsc ife_1_gdsc = {
|
||||
.gdscr = 0xa004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "ife_1_gdsc",
|
||||
},
|
||||
@@ -1729,6 +1741,9 @@ static struct gdsc ife_1_gdsc = {
|
||||
|
||||
static struct gdsc ife_2_gdsc = {
|
||||
.gdscr = 0xb004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "ife_2_gdsc",
|
||||
},
|
||||
@@ -1737,6 +1752,9 @@ static struct gdsc ife_2_gdsc = {
|
||||
|
||||
static struct gdsc titan_top_gdsc = {
|
||||
.gdscr = 0x14004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "titan_top_gdsc",
|
||||
},
|
||||
|
||||
@@ -66,6 +66,8 @@ struct clk_rpmh {
|
||||
struct clk_rpmh_desc {
|
||||
struct clk_hw **clks;
|
||||
size_t num_clks;
|
||||
/* RPMh clock clkaN are optional for this platform */
|
||||
bool clka_optional;
|
||||
};
|
||||
|
||||
static DEFINE_MUTEX(rpmh_clk_lock);
|
||||
@@ -648,6 +650,7 @@ static struct clk_hw *sm8550_rpmh_clocks[] = {
|
||||
static const struct clk_rpmh_desc clk_rpmh_sm8550 = {
|
||||
.clks = sm8550_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(sm8550_rpmh_clocks),
|
||||
.clka_optional = true,
|
||||
};
|
||||
|
||||
static struct clk_hw *sm8650_rpmh_clocks[] = {
|
||||
@@ -679,6 +682,7 @@ static struct clk_hw *sm8650_rpmh_clocks[] = {
|
||||
static const struct clk_rpmh_desc clk_rpmh_sm8650 = {
|
||||
.clks = sm8650_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(sm8650_rpmh_clocks),
|
||||
.clka_optional = true,
|
||||
};
|
||||
|
||||
static struct clk_hw *sc7280_rpmh_clocks[] = {
|
||||
@@ -847,6 +851,7 @@ static struct clk_hw *sm8750_rpmh_clocks[] = {
|
||||
static const struct clk_rpmh_desc clk_rpmh_sm8750 = {
|
||||
.clks = sm8750_rpmh_clocks,
|
||||
.num_clks = ARRAY_SIZE(sm8750_rpmh_clocks),
|
||||
.clka_optional = true,
|
||||
};
|
||||
|
||||
static struct clk_hw *of_clk_rpmh_hw_get(struct of_phandle_args *clkspec,
|
||||
@@ -890,6 +895,12 @@ static int clk_rpmh_probe(struct platform_device *pdev)
|
||||
rpmh_clk = to_clk_rpmh(hw_clks[i]);
|
||||
res_addr = cmd_db_read_addr(rpmh_clk->res_name);
|
||||
if (!res_addr) {
|
||||
hw_clks[i] = NULL;
|
||||
|
||||
if (desc->clka_optional &&
|
||||
!strncmp(rpmh_clk->res_name, "clka", sizeof("clka") - 1))
|
||||
continue;
|
||||
|
||||
dev_err(&pdev->dev, "missing RPMh resource address for %s\n",
|
||||
rpmh_clk->res_name);
|
||||
return -ENODEV;
|
||||
|
||||
@@ -681,6 +681,9 @@ static struct clk_branch disp_cc_xo_clk = {
|
||||
|
||||
static struct gdsc mdss_gdsc = {
|
||||
.gdscr = 0x1004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "mdss_gdsc",
|
||||
},
|
||||
|
||||
@@ -432,7 +432,7 @@ static const struct parent_map gcc_xo_gpll0_gpll1a_gpll6_sleep_map[] = {
|
||||
{ P_XO, 0 },
|
||||
{ P_GPLL0, 1 },
|
||||
{ P_GPLL1_AUX, 2 },
|
||||
{ P_GPLL6, 2 },
|
||||
{ P_GPLL6, 3 },
|
||||
{ P_SLEEP_CLK, 6 },
|
||||
};
|
||||
|
||||
@@ -1113,7 +1113,7 @@ static struct clk_rcg2 jpeg0_clk_src = {
|
||||
};
|
||||
|
||||
static const struct freq_tbl ftbl_gcc_camss_mclk0_1_clk[] = {
|
||||
F(24000000, P_GPLL0, 1, 1, 45),
|
||||
F(24000000, P_GPLL6, 1, 1, 45),
|
||||
F(66670000, P_GPLL0, 12, 0, 0),
|
||||
{ }
|
||||
};
|
||||
|
||||
@@ -2320,6 +2320,9 @@ static struct clk_branch gcc_video_xo_clk = {
|
||||
|
||||
static struct gdsc usb30_prim_gdsc = {
|
||||
.gdscr = 0x1a004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "usb30_prim_gdsc",
|
||||
},
|
||||
@@ -2328,6 +2331,9 @@ static struct gdsc usb30_prim_gdsc = {
|
||||
|
||||
static struct gdsc ufs_phy_gdsc = {
|
||||
.gdscr = 0x3a004,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0xf,
|
||||
.pd = {
|
||||
.name = "ufs_phy_gdsc",
|
||||
},
|
||||
|
||||
@@ -3817,7 +3817,9 @@ static int gcc_sm8650_probe(struct platform_device *pdev)
|
||||
qcom_branch_set_clk_en(regmap, 0x32004); /* GCC_VIDEO_AHB_CLK */
|
||||
qcom_branch_set_clk_en(regmap, 0x32030); /* GCC_VIDEO_XO_CLK */
|
||||
|
||||
/* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */
|
||||
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
|
||||
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true);
|
||||
|
||||
/* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */
|
||||
regmap_write(regmap, 0x52150, 0x0);
|
||||
|
||||
@@ -3244,8 +3244,9 @@ static int gcc_sm8750_probe(struct platform_device *pdev)
|
||||
regmap_update_bits(regmap, 0x52010, BIT(20), BIT(20));
|
||||
regmap_update_bits(regmap, 0x52010, BIT(21), BIT(21));
|
||||
|
||||
/* FORCE_MEM_CORE_ON for ufs phy ice core clocks */
|
||||
/* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */
|
||||
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
|
||||
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true);
|
||||
|
||||
return qcom_cc_really_probe(&pdev->dev, &gcc_sm8750_desc, regmap);
|
||||
}
|
||||
|
||||
@@ -6753,6 +6753,10 @@ static int gcc_x1e80100_probe(struct platform_device *pdev)
|
||||
/* Clear GDSC_SLEEP_ENA_VOTE to stop votes being auto-removed in sleep. */
|
||||
regmap_write(regmap, 0x52224, 0x0);
|
||||
|
||||
/* FORCE_MEM_CORE_ON for ufs phy ice core and gcc ufs phy axi clocks */
|
||||
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_ice_core_clk, true);
|
||||
qcom_branch_set_force_mem_core(regmap, gcc_ufs_phy_axi_clk, true);
|
||||
|
||||
return qcom_cc_really_probe(&pdev->dev, &gcc_x1e80100_desc, regmap);
|
||||
}
|
||||
|
||||
|
||||
@@ -413,6 +413,9 @@ static struct clk_branch gpu_cc_gx_vsense_clk = {
|
||||
static struct gdsc gpu_cx_gdsc = {
|
||||
.gdscr = 0x106c,
|
||||
.gds_hw_ctrl = 0x1540,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0x8,
|
||||
.pd = {
|
||||
.name = "gpu_cx_gdsc",
|
||||
},
|
||||
@@ -423,6 +426,9 @@ static struct gdsc gpu_cx_gdsc = {
|
||||
static struct gdsc gpu_gx_gdsc = {
|
||||
.gdscr = 0x100c,
|
||||
.clamp_io_ctrl = 0x1508,
|
||||
.en_rest_wait_val = 0x2,
|
||||
.en_few_wait_val = 0x2,
|
||||
.clk_dis_wait_val = 0x2,
|
||||
.pd = {
|
||||
.name = "gpu_gx_gdsc",
|
||||
.power_on = gdsc_gx_do_nothing_enable,
|
||||
|
||||
@@ -8,6 +8,7 @@ obj-$(CONFIG_COMMON_CLK_ROCKCHIP) += clk-rockchip.o
|
||||
clk-rockchip-y += clk.o
|
||||
clk-rockchip-y += clk-pll.o
|
||||
clk-rockchip-y += clk-cpu.o
|
||||
clk-rockchip-y += clk-gate-grf.o
|
||||
clk-rockchip-y += clk-half-divider.o
|
||||
clk-rockchip-y += clk-inverter.o
|
||||
clk-rockchip-y += clk-mmc-phase.o
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||
/*
|
||||
* Copyright (c) 2025 Collabora Ltd.
|
||||
* Author: Nicolas Frattaroli <nicolas.frattaroli@collabora.com>
|
||||
*
|
||||
* Certain clocks on Rockchip are "gated" behind an additional register bit
|
||||
* write in a GRF register, such as the SAI MCLKs on RK3576. This code
|
||||
* implements a clock driver for these types of gates, based on regmaps.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/slab.h>
|
||||
#include "clk.h"
|
||||
|
||||
struct rockchip_gate_grf {
|
||||
struct clk_hw hw;
|
||||
struct regmap *regmap;
|
||||
unsigned int reg;
|
||||
unsigned int shift;
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
#define to_gate_grf(_hw) container_of(_hw, struct rockchip_gate_grf, hw)
|
||||
|
||||
static int rockchip_gate_grf_enable(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_gate_grf *gate = to_gate_grf(hw);
|
||||
u32 val = !(gate->flags & CLK_GATE_SET_TO_DISABLE) ? BIT(gate->shift) : 0;
|
||||
u32 hiword = ((gate->flags & CLK_GATE_HIWORD_MASK) ? 1 : 0) << (gate->shift + 16);
|
||||
int ret;
|
||||
|
||||
ret = regmap_update_bits(gate->regmap, gate->reg,
|
||||
hiword | BIT(gate->shift), hiword | val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void rockchip_gate_grf_disable(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_gate_grf *gate = to_gate_grf(hw);
|
||||
u32 val = !(gate->flags & CLK_GATE_SET_TO_DISABLE) ? 0 : BIT(gate->shift);
|
||||
u32 hiword = ((gate->flags & CLK_GATE_HIWORD_MASK) ? 1 : 0) << (gate->shift + 16);
|
||||
|
||||
regmap_update_bits(gate->regmap, gate->reg,
|
||||
hiword | BIT(gate->shift), hiword | val);
|
||||
}
|
||||
|
||||
static int rockchip_gate_grf_is_enabled(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_gate_grf *gate = to_gate_grf(hw);
|
||||
bool invert = !!(gate->flags & CLK_GATE_SET_TO_DISABLE);
|
||||
int ret;
|
||||
|
||||
ret = regmap_test_bits(gate->regmap, gate->reg, BIT(gate->shift));
|
||||
if (ret < 0)
|
||||
ret = 0;
|
||||
|
||||
return invert ? 1 - ret : ret;
|
||||
|
||||
}
|
||||
|
||||
static const struct clk_ops rockchip_gate_grf_ops = {
|
||||
.enable = rockchip_gate_grf_enable,
|
||||
.disable = rockchip_gate_grf_disable,
|
||||
.is_enabled = rockchip_gate_grf_is_enabled,
|
||||
};
|
||||
|
||||
struct clk *rockchip_clk_register_gate_grf(const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
struct regmap *regmap, unsigned int reg, unsigned int shift,
|
||||
u8 gate_flags)
|
||||
{
|
||||
struct rockchip_gate_grf *gate;
|
||||
struct clk_init_data init;
|
||||
struct clk *clk;
|
||||
|
||||
if (IS_ERR(regmap)) {
|
||||
pr_err("%s: regmap not available\n", __func__);
|
||||
return ERR_PTR(-EOPNOTSUPP);
|
||||
}
|
||||
|
||||
gate = kzalloc(sizeof(*gate), GFP_KERNEL);
|
||||
if (!gate)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
init.name = name;
|
||||
init.flags = flags;
|
||||
init.num_parents = parent_name ? 1 : 0;
|
||||
init.parent_names = parent_name ? &parent_name : NULL;
|
||||
init.ops = &rockchip_gate_grf_ops;
|
||||
|
||||
gate->hw.init = &init;
|
||||
gate->regmap = regmap;
|
||||
gate->reg = reg;
|
||||
gate->shift = shift;
|
||||
gate->flags = gate_flags;
|
||||
|
||||
clk = clk_register(NULL, &gate->hw);
|
||||
if (IS_ERR(clk))
|
||||
kfree(gate);
|
||||
|
||||
return clk;
|
||||
}
|
||||
@@ -9,11 +9,14 @@
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/regmap.h>
|
||||
#include "clk.h"
|
||||
|
||||
struct rockchip_mmc_clock {
|
||||
struct clk_hw hw;
|
||||
void __iomem *reg;
|
||||
struct regmap *grf;
|
||||
int grf_reg;
|
||||
int shift;
|
||||
int cached_phase;
|
||||
struct notifier_block clk_rate_change_nb;
|
||||
@@ -54,7 +57,12 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw)
|
||||
if (!rate)
|
||||
return 0;
|
||||
|
||||
raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift);
|
||||
if (mmc_clock->grf)
|
||||
regmap_read(mmc_clock->grf, mmc_clock->grf_reg, &raw_value);
|
||||
else
|
||||
raw_value = readl(mmc_clock->reg);
|
||||
|
||||
raw_value >>= mmc_clock->shift;
|
||||
|
||||
degrees = (raw_value & ROCKCHIP_MMC_DEGREE_MASK) * 90;
|
||||
|
||||
@@ -134,8 +142,12 @@ static int rockchip_mmc_set_phase(struct clk_hw *hw, int degrees)
|
||||
raw_value = delay_num ? ROCKCHIP_MMC_DELAY_SEL : 0;
|
||||
raw_value |= delay_num << ROCKCHIP_MMC_DELAYNUM_OFFSET;
|
||||
raw_value |= nineties;
|
||||
writel(HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift),
|
||||
mmc_clock->reg);
|
||||
raw_value = HIWORD_UPDATE(raw_value, 0x07ff, mmc_clock->shift);
|
||||
|
||||
if (mmc_clock->grf)
|
||||
regmap_write(mmc_clock->grf, mmc_clock->grf_reg, raw_value);
|
||||
else
|
||||
writel(raw_value, mmc_clock->reg);
|
||||
|
||||
pr_debug("%s->set_phase(%d) delay_nums=%u reg[0x%p]=0x%03x actual_degrees=%d\n",
|
||||
clk_hw_get_name(hw), degrees, delay_num,
|
||||
@@ -189,7 +201,9 @@ static int rockchip_mmc_clk_rate_notify(struct notifier_block *nb,
|
||||
|
||||
struct clk *rockchip_clk_register_mmc(const char *name,
|
||||
const char *const *parent_names, u8 num_parents,
|
||||
void __iomem *reg, int shift)
|
||||
void __iomem *reg,
|
||||
struct regmap *grf, int grf_reg,
|
||||
int shift)
|
||||
{
|
||||
struct clk_init_data init;
|
||||
struct rockchip_mmc_clock *mmc_clock;
|
||||
@@ -208,6 +222,8 @@ struct clk *rockchip_clk_register_mmc(const char *name,
|
||||
|
||||
mmc_clock->hw.init = &init;
|
||||
mmc_clock->reg = reg;
|
||||
mmc_clock->grf = grf;
|
||||
mmc_clock->grf_reg = grf_reg;
|
||||
mmc_clock->shift = shift;
|
||||
|
||||
clk = clk_register(NULL, &mmc_clock->hw);
|
||||
|
||||
@@ -1027,16 +1027,6 @@ static int rockchip_rk3588_pll_is_enabled(struct clk_hw *hw)
|
||||
return !(pllcon & RK3588_PLLCON1_PWRDOWN);
|
||||
}
|
||||
|
||||
static int rockchip_rk3588_pll_init(struct clk_hw *hw)
|
||||
{
|
||||
struct rockchip_clk_pll *pll = to_rockchip_clk_pll(hw);
|
||||
|
||||
if (!(pll->flags & ROCKCHIP_PLL_SYNC_RATE))
|
||||
return 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct clk_ops rockchip_rk3588_pll_clk_norate_ops = {
|
||||
.recalc_rate = rockchip_rk3588_pll_recalc_rate,
|
||||
.enable = rockchip_rk3588_pll_enable,
|
||||
@@ -1051,7 +1041,6 @@ static const struct clk_ops rockchip_rk3588_pll_clk_ops = {
|
||||
.enable = rockchip_rk3588_pll_enable,
|
||||
.disable = rockchip_rk3588_pll_disable,
|
||||
.is_enabled = rockchip_rk3588_pll_is_enabled,
|
||||
.init = rockchip_rk3588_pll_init,
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
@@ -123,6 +123,7 @@ PNAME(mux_timer_p) = { "xin24m", "pclk_peri_src" };
|
||||
PNAME(mux_pll_src_apll_dpll_gpll_usb480m_p) = { "apll", "dpll", "gpll", "usb480m" };
|
||||
PNAME(mux_pll_src_dmyapll_dpll_gpll_xin24_p) = { "dummy_apll", "dpll", "gpll", "xin24m" };
|
||||
|
||||
PNAME(mux_usb480m_p) = { "usb480m_phy", "xin24m" };
|
||||
PNAME(mux_mmc_src_p) = { "apll", "dpll", "gpll", "xin24m" };
|
||||
PNAME(mux_i2s_pre_p) = { "i2s_src", "i2s_frac", "ext_i2s", "xin12m" };
|
||||
PNAME(mux_i2s_clkout_p) = { "i2s_pre", "xin12m" };
|
||||
@@ -423,6 +424,9 @@ static struct rockchip_clk_branch rk3036_clk_branches[] __initdata = {
|
||||
GATE(PCLK_GPIO0, "pclk_gpio0", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 9, GFLAGS),
|
||||
GATE(PCLK_GPIO1, "pclk_gpio1", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 10, GFLAGS),
|
||||
GATE(PCLK_GPIO2, "pclk_gpio2", "pclk_peri", 0, RK2928_CLKGATE_CON(8), 11, GFLAGS),
|
||||
|
||||
MUX(SCLK_USB480M, "usb480m", mux_usb480m_p, CLK_SET_RATE_PARENT,
|
||||
RK2928_MISC_CON, 15, 1, MFLAGS),
|
||||
};
|
||||
|
||||
static const char *const rk3036_critical_clocks[] __initconst = {
|
||||
@@ -431,6 +435,7 @@ static const char *const rk3036_critical_clocks[] __initconst = {
|
||||
"hclk_peri",
|
||||
"pclk_peri",
|
||||
"pclk_ddrupctl",
|
||||
"ddrphy",
|
||||
};
|
||||
|
||||
static void __init rk3036_clk_init(struct device_node *np)
|
||||
@@ -438,7 +443,6 @@ static void __init rk3036_clk_init(struct device_node *np)
|
||||
struct rockchip_clk_provider *ctx;
|
||||
unsigned long clk_nr_clks;
|
||||
void __iomem *reg_base;
|
||||
struct clk *clk;
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
@@ -462,11 +466,6 @@ static void __init rk3036_clk_init(struct device_node *np)
|
||||
return;
|
||||
}
|
||||
|
||||
clk = clk_register_fixed_factor(NULL, "usb480m", "xin24m", 0, 20, 1);
|
||||
if (IS_ERR(clk))
|
||||
pr_warn("%s: could not register clock usb480m: %ld\n",
|
||||
__func__, PTR_ERR(clk));
|
||||
|
||||
rockchip_clk_register_plls(ctx, rk3036_pll_clks,
|
||||
ARRAY_SIZE(rk3036_pll_clks),
|
||||
RK3036_GRF_SOC_STATUS0);
|
||||
|
||||
@@ -418,7 +418,7 @@ static struct rockchip_clk_branch rk3288_clk_branches[] __initdata = {
|
||||
RK3288_CLKSEL_CON(32), 14, 2, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3288_CLKGATE_CON(3), 11, GFLAGS),
|
||||
MUXGRF(0, "aclk_vcodec_pre", mux_aclk_vcodec_pre_p, CLK_SET_RATE_PARENT,
|
||||
RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS),
|
||||
RK3288_GRF_SOC_CON(0), 7, 1, MFLAGS, grf_type_sys),
|
||||
GATE(ACLK_VCODEC, "aclk_vcodec", "aclk_vcodec_pre", 0,
|
||||
RK3288_CLKGATE_CON(9), 0, GFLAGS),
|
||||
|
||||
|
||||
@@ -677,9 +677,9 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
|
||||
RK3328_CLKSEL_CON(27), 15, 1, MFLAGS, 8, 5, DFLAGS,
|
||||
RK3328_CLKGATE_CON(3), 5, GFLAGS),
|
||||
MUXGRF(SCLK_MAC2IO, "clk_mac2io", mux_mac2io_src_p, CLK_SET_RATE_NO_REPARENT,
|
||||
RK3328_GRF_MAC_CON1, 10, 1, MFLAGS),
|
||||
RK3328_GRF_MAC_CON1, 10, 1, MFLAGS, grf_type_sys),
|
||||
MUXGRF(SCLK_MAC2IO_EXT, "clk_mac2io_ext", mux_mac2io_ext_p, CLK_SET_RATE_NO_REPARENT,
|
||||
RK3328_GRF_SOC_CON4, 14, 1, MFLAGS),
|
||||
RK3328_GRF_SOC_CON4, 14, 1, MFLAGS, grf_type_sys),
|
||||
|
||||
COMPOSITE(SCLK_MAC2PHY_SRC, "clk_mac2phy_src", mux_2plls_p, 0,
|
||||
RK3328_CLKSEL_CON(26), 7, 1, MFLAGS, 0, 5, DFLAGS,
|
||||
@@ -692,7 +692,7 @@ static struct rockchip_clk_branch rk3328_clk_branches[] __initdata = {
|
||||
RK3328_CLKSEL_CON(26), 8, 2, DFLAGS,
|
||||
RK3328_CLKGATE_CON(9), 2, GFLAGS),
|
||||
MUXGRF(SCLK_MAC2PHY, "clk_mac2phy", mux_mac2phy_src_p, CLK_SET_RATE_NO_REPARENT,
|
||||
RK3328_GRF_MAC_CON2, 10, 1, MFLAGS),
|
||||
RK3328_GRF_MAC_CON2, 10, 1, MFLAGS, grf_type_sys),
|
||||
|
||||
FACTOR(0, "xin12m", "xin24m", 0, 1, 2),
|
||||
|
||||
|
||||
@@ -10,6 +10,9 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/minmax.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
#include <dt-bindings/clock/rockchip,rk3528-cru.h>
|
||||
|
||||
@@ -1061,23 +1064,65 @@ static struct rockchip_clk_branch rk3528_clk_branches[] __initdata = {
|
||||
0, 1, 1),
|
||||
};
|
||||
|
||||
static struct rockchip_clk_branch rk3528_vo_clk_branches[] __initdata = {
|
||||
MMC_GRF(SCLK_SDMMC_DRV, "sdmmc_drv", "cclk_src_sdmmc0",
|
||||
RK3528_SDMMC_CON(0), 1, grf_type_vo),
|
||||
MMC_GRF(SCLK_SDMMC_SAMPLE, "sdmmc_sample", "cclk_src_sdmmc0",
|
||||
RK3528_SDMMC_CON(1), 1, grf_type_vo),
|
||||
};
|
||||
|
||||
static struct rockchip_clk_branch rk3528_vpu_clk_branches[] __initdata = {
|
||||
MMC_GRF(SCLK_SDIO0_DRV, "sdio0_drv", "cclk_src_sdio0",
|
||||
RK3528_SDIO0_CON(0), 1, grf_type_vpu),
|
||||
MMC_GRF(SCLK_SDIO0_SAMPLE, "sdio0_sample", "cclk_src_sdio0",
|
||||
RK3528_SDIO0_CON(1), 1, grf_type_vpu),
|
||||
MMC_GRF(SCLK_SDIO1_DRV, "sdio1_drv", "cclk_src_sdio1",
|
||||
RK3528_SDIO1_CON(0), 1, grf_type_vpu),
|
||||
MMC_GRF(SCLK_SDIO1_SAMPLE, "sdio1_sample", "cclk_src_sdio1",
|
||||
RK3528_SDIO1_CON(1), 1, grf_type_vpu),
|
||||
};
|
||||
|
||||
static int __init clk_rk3528_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct rockchip_clk_provider *ctx;
|
||||
unsigned long nr_vpu_branches = ARRAY_SIZE(rk3528_vpu_clk_branches);
|
||||
unsigned long nr_vo_branches = ARRAY_SIZE(rk3528_vo_clk_branches);
|
||||
unsigned long nr_branches = ARRAY_SIZE(rk3528_clk_branches);
|
||||
unsigned long nr_clks, nr_vo_clks, nr_vpu_clks;
|
||||
struct rockchip_aux_grf *vo_grf_e, *vpu_grf_e;
|
||||
struct regmap *vo_grf, *vpu_grf;
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *np = dev->of_node;
|
||||
unsigned long nr_branches = ARRAY_SIZE(rk3528_clk_branches);
|
||||
unsigned long nr_clks;
|
||||
struct rockchip_clk_provider *ctx;
|
||||
void __iomem *reg_base;
|
||||
|
||||
nr_clks = rockchip_clk_find_max_clk_id(rk3528_clk_branches,
|
||||
nr_branches) + 1;
|
||||
|
||||
reg_base = devm_platform_ioremap_resource(pdev, 0);
|
||||
if (IS_ERR(reg_base))
|
||||
return dev_err_probe(dev, PTR_ERR(reg_base),
|
||||
"could not map cru region");
|
||||
|
||||
nr_clks = rockchip_clk_find_max_clk_id(rk3528_clk_branches,
|
||||
nr_branches) + 1;
|
||||
|
||||
vo_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3528-vo-grf");
|
||||
if (!IS_ERR(vo_grf)) {
|
||||
nr_vo_clks = rockchip_clk_find_max_clk_id(rk3528_vo_clk_branches,
|
||||
nr_vo_branches) + 1;
|
||||
nr_clks = max(nr_clks, nr_vo_clks);
|
||||
} else if (PTR_ERR(vo_grf) != -ENODEV) {
|
||||
return dev_err_probe(dev, PTR_ERR(vo_grf),
|
||||
"failed to look up VO GRF\n");
|
||||
}
|
||||
|
||||
vpu_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3528-vpu-grf");
|
||||
if (!IS_ERR(vpu_grf)) {
|
||||
nr_vpu_clks = rockchip_clk_find_max_clk_id(rk3528_vpu_clk_branches,
|
||||
nr_vpu_branches) + 1;
|
||||
nr_clks = max(nr_clks, nr_vpu_clks);
|
||||
} else if (PTR_ERR(vpu_grf) != -ENODEV) {
|
||||
return dev_err_probe(dev, PTR_ERR(vpu_grf),
|
||||
"failed to look up VPU GRF\n");
|
||||
}
|
||||
|
||||
ctx = rockchip_clk_init(np, reg_base, nr_clks);
|
||||
if (IS_ERR(ctx))
|
||||
return dev_err_probe(dev, PTR_ERR(ctx),
|
||||
@@ -1092,6 +1137,32 @@ static int __init clk_rk3528_probe(struct platform_device *pdev)
|
||||
ARRAY_SIZE(rk3528_cpuclk_rates));
|
||||
rockchip_clk_register_branches(ctx, rk3528_clk_branches, nr_branches);
|
||||
|
||||
if (!IS_ERR(vo_grf)) {
|
||||
vo_grf_e = devm_kzalloc(dev, sizeof(*vo_grf_e), GFP_KERNEL);
|
||||
if (!vo_grf_e)
|
||||
return -ENOMEM;
|
||||
|
||||
vo_grf_e->grf = vo_grf;
|
||||
vo_grf_e->type = grf_type_vo;
|
||||
hash_add(ctx->aux_grf_table, &vo_grf_e->node, grf_type_vo);
|
||||
|
||||
rockchip_clk_register_branches(ctx, rk3528_vo_clk_branches,
|
||||
nr_vo_branches);
|
||||
}
|
||||
|
||||
if (!IS_ERR(vpu_grf)) {
|
||||
vpu_grf_e = devm_kzalloc(dev, sizeof(*vpu_grf_e), GFP_KERNEL);
|
||||
if (!vpu_grf_e)
|
||||
return -ENOMEM;
|
||||
|
||||
vpu_grf_e->grf = vpu_grf;
|
||||
vpu_grf_e->type = grf_type_vpu;
|
||||
hash_add(ctx->aux_grf_table, &vpu_grf_e->node, grf_type_vpu);
|
||||
|
||||
rockchip_clk_register_branches(ctx, rk3528_vpu_clk_branches,
|
||||
nr_vpu_branches);
|
||||
}
|
||||
|
||||
rk3528_rst_init(np, reg_base);
|
||||
|
||||
rockchip_register_restart_notifier(ctx, RK3528_GLB_SRST_FST, NULL);
|
||||
|
||||
@@ -89,6 +89,7 @@ static struct rockchip_pll_rate_table rk3568_pll_rates[] = {
|
||||
RK3036_PLL_RATE(96000000, 1, 96, 6, 4, 1, 0),
|
||||
RK3036_PLL_RATE(78750000, 4, 315, 6, 4, 1, 0),
|
||||
RK3036_PLL_RATE(74250000, 2, 99, 4, 4, 1, 0),
|
||||
RK3036_PLL_RATE(33300000, 4, 111, 5, 4, 1, 0),
|
||||
{ /* sentinel */ },
|
||||
};
|
||||
|
||||
@@ -590,7 +591,7 @@ static struct rockchip_clk_branch rk3568_clk_branches[] __initdata = {
|
||||
RK3568_CLKSEL_CON(9), 6, 2, MFLAGS, 0, 5, DFLAGS,
|
||||
RK3568_CLKGATE_CON(4), 0, GFLAGS),
|
||||
MUXGRF(CLK_DDR1X, "clk_ddr1x", clk_ddr1x_p, CLK_SET_RATE_PARENT,
|
||||
RK3568_CLKSEL_CON(9), 15, 1, MFLAGS),
|
||||
RK3568_CLKSEL_CON(9), 15, 1, MFLAGS, grf_type_sys),
|
||||
|
||||
COMPOSITE_NOMUX(CLK_MSCH, "clk_msch", "clk_ddr1x", CLK_IGNORE_UNUSED,
|
||||
RK3568_CLKSEL_CON(10), 0, 2, DFLAGS,
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/slab.h>
|
||||
#include <dt-bindings/clock/rockchip,rk3576-cru.h>
|
||||
#include "clk.h"
|
||||
|
||||
#define RK3576_GRF_SOC_STATUS0 0x600
|
||||
#define RK3576_PMU0_GRF_OSC_CON6 0x18
|
||||
#define RK3576_VCCIO_IOC_MISC_CON0 0x6400
|
||||
|
||||
enum rk3576_plls {
|
||||
bpll, lpll, vpll, aupll, cpll, gpll, ppll,
|
||||
@@ -1479,6 +1481,14 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = {
|
||||
RK3576_CLKGATE_CON(10), 0, GFLAGS),
|
||||
GATE(CLK_SAI0_MCLKOUT, "clk_sai0_mclkout", "mclk_sai0_8ch", 0,
|
||||
RK3576_CLKGATE_CON(10), 1, GFLAGS),
|
||||
GATE_GRF(CLK_SAI0_MCLKOUT_TO_IO, "mclk_sai0_to_io", "clk_sai0_mclkout",
|
||||
0, RK3576_VCCIO_IOC_MISC_CON0, 0, GFLAGS, grf_type_ioc),
|
||||
GATE_GRF(CLK_SAI1_MCLKOUT_TO_IO, "mclk_sai1_to_io", "clk_sai1_mclkout",
|
||||
0, RK3576_VCCIO_IOC_MISC_CON0, 1, GFLAGS, grf_type_ioc),
|
||||
GATE_GRF(CLK_SAI2_MCLKOUT_TO_IO, "mclk_sai2_to_io", "clk_sai2_mclkout",
|
||||
0, RK3576_VCCIO_IOC_MISC_CON0, 2, GFLAGS, grf_type_ioc),
|
||||
GATE_GRF(CLK_SAI3_MCLKOUT_TO_IO, "mclk_sai3_to_io", "clk_sai3_mclkout",
|
||||
0, RK3576_VCCIO_IOC_MISC_CON0, 3, GFLAGS, grf_type_ioc),
|
||||
|
||||
/* sdgmac */
|
||||
COMPOSITE_NODIV(HCLK_SDGMAC_ROOT, "hclk_sdgmac_root", mux_200m_100m_50m_24m_p, 0,
|
||||
@@ -1676,13 +1686,13 @@ static struct rockchip_clk_branch rk3576_clk_branches[] __initdata = {
|
||||
|
||||
/* phy ref */
|
||||
MUXGRF(CLK_PHY_REF_SRC, "clk_phy_ref_src", clk_phy_ref_src_p, 0,
|
||||
RK3576_PMU0_GRF_OSC_CON6, 4, 1, MFLAGS),
|
||||
RK3576_PMU0_GRF_OSC_CON6, 4, 1, MFLAGS, grf_type_pmu0),
|
||||
MUXGRF(CLK_USBPHY_REF_SRC, "clk_usbphy_ref_src", clk_usbphy_ref_src_p, 0,
|
||||
RK3576_PMU0_GRF_OSC_CON6, 2, 1, MFLAGS),
|
||||
RK3576_PMU0_GRF_OSC_CON6, 2, 1, MFLAGS, grf_type_pmu0),
|
||||
MUXGRF(CLK_CPLL_REF_SRC, "clk_cpll_ref_src", clk_cpll_ref_src_p, 0,
|
||||
RK3576_PMU0_GRF_OSC_CON6, 1, 1, MFLAGS),
|
||||
RK3576_PMU0_GRF_OSC_CON6, 1, 1, MFLAGS, grf_type_pmu0),
|
||||
MUXGRF(CLK_AUPLL_REF_SRC, "clk_aupll_ref_src", clk_aupll_ref_src_p, 0,
|
||||
RK3576_PMU0_GRF_OSC_CON6, 0, 1, MFLAGS),
|
||||
RK3576_PMU0_GRF_OSC_CON6, 0, 1, MFLAGS, grf_type_pmu0),
|
||||
|
||||
/* secure ns */
|
||||
COMPOSITE_NODIV(ACLK_SECURE_NS, "aclk_secure_ns", mux_350m_175m_116m_24m_p, CLK_IS_CRITICAL,
|
||||
@@ -1725,17 +1735,26 @@ static void __init rk3576_clk_init(struct device_node *np)
|
||||
struct rockchip_clk_provider *ctx;
|
||||
unsigned long clk_nr_clks;
|
||||
void __iomem *reg_base;
|
||||
struct regmap *grf;
|
||||
struct rockchip_aux_grf *ioc_grf_e;
|
||||
struct rockchip_aux_grf *pmu0_grf_e;
|
||||
struct regmap *ioc_grf;
|
||||
struct regmap *pmu0_grf;
|
||||
|
||||
clk_nr_clks = rockchip_clk_find_max_clk_id(rk3576_clk_branches,
|
||||
ARRAY_SIZE(rk3576_clk_branches)) + 1;
|
||||
|
||||
grf = syscon_regmap_lookup_by_compatible("rockchip,rk3576-pmu0-grf");
|
||||
if (IS_ERR(grf)) {
|
||||
pmu0_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3576-pmu0-grf");
|
||||
if (IS_ERR(pmu0_grf)) {
|
||||
pr_err("%s: could not get PMU0 GRF syscon\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
ioc_grf = syscon_regmap_lookup_by_compatible("rockchip,rk3576-ioc-grf");
|
||||
if (IS_ERR(ioc_grf)) {
|
||||
pr_err("%s: could not get IOC GRF syscon\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
reg_base = of_iomap(np, 0);
|
||||
if (!reg_base) {
|
||||
pr_err("%s: could not map cru region\n", __func__);
|
||||
@@ -1745,11 +1764,24 @@ static void __init rk3576_clk_init(struct device_node *np)
|
||||
ctx = rockchip_clk_init(np, reg_base, clk_nr_clks);
|
||||
if (IS_ERR(ctx)) {
|
||||
pr_err("%s: rockchip clk init failed\n", __func__);
|
||||
iounmap(reg_base);
|
||||
return;
|
||||
goto err_unmap;
|
||||
}
|
||||
|
||||
ctx->grf = grf;
|
||||
pmu0_grf_e = kzalloc(sizeof(*pmu0_grf_e), GFP_KERNEL);
|
||||
if (!pmu0_grf_e)
|
||||
goto err_unmap;
|
||||
|
||||
pmu0_grf_e->grf = pmu0_grf;
|
||||
pmu0_grf_e->type = grf_type_pmu0;
|
||||
hash_add(ctx->aux_grf_table, &pmu0_grf_e->node, grf_type_pmu0);
|
||||
|
||||
ioc_grf_e = kzalloc(sizeof(*ioc_grf_e), GFP_KERNEL);
|
||||
if (!ioc_grf_e)
|
||||
goto err_free_pmu0;
|
||||
|
||||
ioc_grf_e->grf = ioc_grf;
|
||||
ioc_grf_e->type = grf_type_ioc;
|
||||
hash_add(ctx->aux_grf_table, &ioc_grf_e->node, grf_type_ioc);
|
||||
|
||||
rockchip_clk_register_plls(ctx, rk3576_pll_clks,
|
||||
ARRAY_SIZE(rk3576_pll_clks),
|
||||
@@ -1772,6 +1804,14 @@ static void __init rk3576_clk_init(struct device_node *np)
|
||||
rockchip_register_restart_notifier(ctx, RK3576_GLB_SRST_FST, NULL);
|
||||
|
||||
rockchip_clk_of_add_provider(np, ctx);
|
||||
|
||||
return;
|
||||
|
||||
err_free_pmu0:
|
||||
kfree(pmu0_grf_e);
|
||||
err_unmap:
|
||||
iounmap(reg_base);
|
||||
return;
|
||||
}
|
||||
|
||||
CLK_OF_DECLARE(rk3576_cru, "rockchip,rk3576-cru", rk3576_clk_init);
|
||||
|
||||
@@ -64,6 +64,7 @@ static struct rockchip_pll_rate_table rk3588_pll_rates[] = {
|
||||
RK3588_PLL_RATE(1560000000, 2, 260, 1, 0),
|
||||
RK3588_PLL_RATE(1536000000, 2, 256, 1, 0),
|
||||
RK3588_PLL_RATE(1512000000, 2, 252, 1, 0),
|
||||
RK3588_PLL_RATE(1500000000, 2, 250, 1, 0),
|
||||
RK3588_PLL_RATE(1488000000, 2, 248, 1, 0),
|
||||
RK3588_PLL_RATE(1464000000, 2, 244, 1, 0),
|
||||
RK3588_PLL_RATE(1440000000, 2, 240, 1, 0),
|
||||
|
||||
@@ -857,7 +857,7 @@ static struct rockchip_clk_branch rv1126_clk_branches[] __initdata = {
|
||||
RV1126_GMAC_CON, 5, 1, MFLAGS),
|
||||
MUXGRF(CLK_GMAC_SRC, "clk_gmac_src", mux_clk_gmac_src_p, CLK_SET_RATE_PARENT |
|
||||
CLK_SET_RATE_NO_REPARENT,
|
||||
RV1126_GRF_IOFUNC_CON1, 12, 1, MFLAGS),
|
||||
RV1126_GRF_IOFUNC_CON1, 12, 1, MFLAGS, grf_type_sys),
|
||||
|
||||
GATE(CLK_GMAC_REF, "clk_gmac_ref", "clk_gmac_src", 0,
|
||||
RV1126_CLKGATE_CON(20), 7, GFLAGS),
|
||||
|
||||
@@ -382,6 +382,8 @@ static struct rockchip_clk_provider *rockchip_clk_init_base(
|
||||
ctx->cru_node = np;
|
||||
spin_lock_init(&ctx->lock);
|
||||
|
||||
hash_init(ctx->aux_grf_table);
|
||||
|
||||
ctx->grf = syscon_regmap_lookup_by_phandle(ctx->cru_node,
|
||||
"rockchip,grf");
|
||||
|
||||
@@ -496,6 +498,8 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
|
||||
struct rockchip_clk_branch *list,
|
||||
unsigned int nr_clk)
|
||||
{
|
||||
struct regmap *grf = ctx->grf;
|
||||
struct rockchip_aux_grf *agrf;
|
||||
struct clk *clk;
|
||||
unsigned int idx;
|
||||
unsigned long flags;
|
||||
@@ -504,6 +508,19 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
|
||||
flags = list->flags;
|
||||
clk = NULL;
|
||||
|
||||
/* for GRF-dependent branches, choose the right grf first */
|
||||
if ((list->branch_type == branch_grf_mux ||
|
||||
list->branch_type == branch_grf_gate ||
|
||||
list->branch_type == branch_grf_mmc) &&
|
||||
list->grf_type != grf_type_sys) {
|
||||
hash_for_each_possible(ctx->aux_grf_table, agrf, node, list->grf_type) {
|
||||
if (agrf->type == list->grf_type) {
|
||||
grf = agrf->grf;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* catch simple muxes */
|
||||
switch (list->branch_type) {
|
||||
case branch_mux:
|
||||
@@ -523,10 +540,10 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
|
||||
list->mux_shift, list->mux_width,
|
||||
list->mux_flags, &ctx->lock);
|
||||
break;
|
||||
case branch_muxgrf:
|
||||
case branch_grf_mux:
|
||||
clk = rockchip_clk_register_muxgrf(list->name,
|
||||
list->parent_names, list->num_parents,
|
||||
flags, ctx->grf, list->muxdiv_offset,
|
||||
flags, grf, list->muxdiv_offset,
|
||||
list->mux_shift, list->mux_width,
|
||||
list->mux_flags);
|
||||
break;
|
||||
@@ -573,6 +590,13 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
|
||||
ctx->reg_base + list->gate_offset,
|
||||
list->gate_shift, list->gate_flags, &ctx->lock);
|
||||
break;
|
||||
case branch_grf_gate:
|
||||
flags |= CLK_SET_RATE_PARENT;
|
||||
clk = rockchip_clk_register_gate_grf(list->name,
|
||||
list->parent_names[0], flags, grf,
|
||||
list->gate_offset, list->gate_shift,
|
||||
list->gate_flags);
|
||||
break;
|
||||
case branch_composite:
|
||||
clk = rockchip_clk_register_branch(list->name,
|
||||
list->parent_names, list->num_parents,
|
||||
@@ -590,6 +614,16 @@ void rockchip_clk_register_branches(struct rockchip_clk_provider *ctx,
|
||||
list->name,
|
||||
list->parent_names, list->num_parents,
|
||||
ctx->reg_base + list->muxdiv_offset,
|
||||
NULL, 0,
|
||||
list->div_shift
|
||||
);
|
||||
break;
|
||||
case branch_grf_mmc:
|
||||
clk = rockchip_clk_register_mmc(
|
||||
list->name,
|
||||
list->parent_names, list->num_parents,
|
||||
NULL,
|
||||
grf, list->muxdiv_offset,
|
||||
list->div_shift
|
||||
);
|
||||
break;
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
|
||||
#include <linux/io.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/hashtable.h>
|
||||
|
||||
struct clk;
|
||||
|
||||
@@ -217,6 +218,9 @@ struct clk;
|
||||
#define RK3528_CLKSEL_CON(x) ((x) * 0x4 + 0x300)
|
||||
#define RK3528_CLKGATE_CON(x) ((x) * 0x4 + 0x800)
|
||||
#define RK3528_SOFTRST_CON(x) ((x) * 0x4 + 0xa00)
|
||||
#define RK3528_SDMMC_CON(x) ((x) * 0x4 + 0x24)
|
||||
#define RK3528_SDIO0_CON(x) ((x) * 0x4 + 0x4)
|
||||
#define RK3528_SDIO1_CON(x) ((x) * 0x4 + 0xc)
|
||||
#define RK3528_PMU_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3528_PMU_CRU_BASE)
|
||||
#define RK3528_PMU_CLKGATE_CON(x) ((x) * 0x4 + 0x800 + RK3528_PMU_CRU_BASE)
|
||||
#define RK3528_PCIE_CLKSEL_CON(x) ((x) * 0x4 + 0x300 + RK3528_PCIE_CRU_BASE)
|
||||
@@ -440,12 +444,37 @@ enum rockchip_pll_type {
|
||||
.k = _k, \
|
||||
}
|
||||
|
||||
enum rockchip_grf_type {
|
||||
grf_type_sys = 0,
|
||||
grf_type_pmu0,
|
||||
grf_type_pmu1,
|
||||
grf_type_ioc,
|
||||
grf_type_vo,
|
||||
grf_type_vpu,
|
||||
};
|
||||
|
||||
/* ceil(sqrt(enums in rockchip_grf_type - 1)) */
|
||||
#define GRF_HASH_ORDER 2
|
||||
|
||||
/**
|
||||
* struct rockchip_aux_grf - entry for the aux_grf_table hashtable
|
||||
* @grf: pointer to the grf this entry references
|
||||
* @type: what type of GRF this is
|
||||
* @node: hlist node
|
||||
*/
|
||||
struct rockchip_aux_grf {
|
||||
struct regmap *grf;
|
||||
enum rockchip_grf_type type;
|
||||
struct hlist_node node;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct rockchip_clk_provider - information about clock provider
|
||||
* @reg_base: virtual address for the register base.
|
||||
* @clk_data: holds clock related data like clk* and number of clocks.
|
||||
* @cru_node: device-node of the clock-provider
|
||||
* @grf: regmap of the general-register-files syscon
|
||||
* @aux_grf_table: hashtable of auxiliary GRF regmaps, indexed by grf_type
|
||||
* @lock: maintains exclusion between callbacks for a given clock-provider.
|
||||
*/
|
||||
struct rockchip_clk_provider {
|
||||
@@ -453,6 +482,7 @@ struct rockchip_clk_provider {
|
||||
struct clk_onecell_data clk_data;
|
||||
struct device_node *cru_node;
|
||||
struct regmap *grf;
|
||||
DECLARE_HASHTABLE(aux_grf_table, GRF_HASH_ORDER);
|
||||
spinlock_t lock;
|
||||
};
|
||||
|
||||
@@ -594,7 +624,9 @@ struct clk *rockchip_clk_register_cpuclk(const char *name,
|
||||
|
||||
struct clk *rockchip_clk_register_mmc(const char *name,
|
||||
const char *const *parent_names, u8 num_parents,
|
||||
void __iomem *reg, int shift);
|
||||
void __iomem *reg,
|
||||
struct regmap *grf, int grf_reg,
|
||||
int shift);
|
||||
|
||||
/*
|
||||
* DDRCLK flags, including method of setting the rate
|
||||
@@ -622,17 +654,24 @@ struct clk *rockchip_clk_register_muxgrf(const char *name,
|
||||
int flags, struct regmap *grf, int reg,
|
||||
int shift, int width, int mux_flags);
|
||||
|
||||
struct clk *rockchip_clk_register_gate_grf(const char *name,
|
||||
const char *parent_name, unsigned long flags,
|
||||
struct regmap *regmap, unsigned int reg,
|
||||
unsigned int shift, u8 gate_flags);
|
||||
|
||||
#define PNAME(x) static const char *const x[] __initconst
|
||||
|
||||
enum rockchip_clk_branch_type {
|
||||
branch_composite,
|
||||
branch_mux,
|
||||
branch_muxgrf,
|
||||
branch_grf_mux,
|
||||
branch_divider,
|
||||
branch_fraction_divider,
|
||||
branch_gate,
|
||||
branch_grf_gate,
|
||||
branch_linked_gate,
|
||||
branch_mmc,
|
||||
branch_grf_mmc,
|
||||
branch_inverter,
|
||||
branch_factor,
|
||||
branch_ddrclk,
|
||||
@@ -660,6 +699,7 @@ struct rockchip_clk_branch {
|
||||
u8 gate_shift;
|
||||
u8 gate_flags;
|
||||
unsigned int linked_clk_id;
|
||||
enum rockchip_grf_type grf_type;
|
||||
struct rockchip_clk_branch *child;
|
||||
};
|
||||
|
||||
@@ -900,10 +940,10 @@ struct rockchip_clk_branch {
|
||||
.mux_table = mt, \
|
||||
}
|
||||
|
||||
#define MUXGRF(_id, cname, pnames, f, o, s, w, mf) \
|
||||
#define MUXGRF(_id, cname, pnames, f, o, s, w, mf, gt) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.branch_type = branch_muxgrf, \
|
||||
.branch_type = branch_grf_mux, \
|
||||
.name = cname, \
|
||||
.parent_names = pnames, \
|
||||
.num_parents = ARRAY_SIZE(pnames), \
|
||||
@@ -913,6 +953,7 @@ struct rockchip_clk_branch {
|
||||
.mux_width = w, \
|
||||
.mux_flags = mf, \
|
||||
.gate_offset = -1, \
|
||||
.grf_type = gt, \
|
||||
}
|
||||
|
||||
#define DIV(_id, cname, pname, f, o, s, w, df) \
|
||||
@@ -958,6 +999,20 @@ struct rockchip_clk_branch {
|
||||
.gate_flags = gf, \
|
||||
}
|
||||
|
||||
#define GATE_GRF(_id, cname, pname, f, o, b, gf, gt) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.branch_type = branch_grf_gate, \
|
||||
.name = cname, \
|
||||
.parent_names = (const char *[]){ pname }, \
|
||||
.num_parents = 1, \
|
||||
.flags = f, \
|
||||
.gate_offset = o, \
|
||||
.gate_shift = b, \
|
||||
.gate_flags = gf, \
|
||||
.grf_type = gt, \
|
||||
}
|
||||
|
||||
#define GATE_LINK(_id, cname, pname, linkedclk, f, o, b, gf) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
@@ -983,6 +1038,18 @@ struct rockchip_clk_branch {
|
||||
.div_shift = shift, \
|
||||
}
|
||||
|
||||
#define MMC_GRF(_id, cname, pname, offset, shift, grftype) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
.branch_type = branch_grf_mmc, \
|
||||
.name = cname, \
|
||||
.parent_names = (const char *[]){ pname }, \
|
||||
.num_parents = 1, \
|
||||
.muxdiv_offset = offset, \
|
||||
.div_shift = shift, \
|
||||
.grf_type = grftype, \
|
||||
}
|
||||
|
||||
#define INVERTER(_id, cname, pname, io, is, if) \
|
||||
{ \
|
||||
.id = _id, \
|
||||
|
||||
@@ -9,123 +9,123 @@ if SUNXI_CCU
|
||||
|
||||
config SUNIV_F1C100S_CCU
|
||||
tristate "Support for the Allwinner newer F1C100s CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUNIV || COMPILE_TEST
|
||||
|
||||
config SUN20I_D1_CCU
|
||||
tristate "Support for the Allwinner D1/R528/T113 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || RISCV || COMPILE_TEST
|
||||
|
||||
config SUN20I_D1_R_CCU
|
||||
tristate "Support for the Allwinner D1/R528/T113 PRCM CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || RISCV || COMPILE_TEST
|
||||
|
||||
config SUN50I_A64_CCU
|
||||
tristate "Support for the Allwinner A64 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN50I_A100_CCU
|
||||
tristate "Support for the Allwinner A100 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN50I_A100_R_CCU
|
||||
tristate "Support for the Allwinner A100 PRCM CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN50I_H6_CCU
|
||||
tristate "Support for the Allwinner H6 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN50I_H616_CCU
|
||||
tristate "Support for the Allwinner H616 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN50I_H6_R_CCU
|
||||
tristate "Support for the Allwinner H6 and H616 PRCM CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN55I_A523_CCU
|
||||
tristate "Support for the Allwinner A523/T527 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN55I_A523_R_CCU
|
||||
tristate "Support for the Allwinner A523/T527 PRCM CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN4I_A10_CCU
|
||||
tristate "Support for the Allwinner A10/A20 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN4I || MACH_SUN7I || COMPILE_TEST
|
||||
|
||||
config SUN5I_CCU
|
||||
bool "Support for the Allwinner sun5i family CCM"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN5I || COMPILE_TEST
|
||||
depends on SUNXI_CCU=y
|
||||
|
||||
config SUN6I_A31_CCU
|
||||
tristate "Support for the Allwinner A31/A31s CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN6I || COMPILE_TEST
|
||||
|
||||
config SUN6I_RTC_CCU
|
||||
tristate "Support for the Allwinner H616/R329 RTC CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || ARM64 || RISCV || COMPILE_TEST
|
||||
|
||||
config SUN8I_A23_CCU
|
||||
tristate "Support for the Allwinner A23 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_A33_CCU
|
||||
tristate "Support for the Allwinner A33 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_A83T_CCU
|
||||
tristate "Support for the Allwinner A83T CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_H3_CCU
|
||||
tristate "Support for the Allwinner H3 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || ARM64 || COMPILE_TEST
|
||||
|
||||
config SUN8I_V3S_CCU
|
||||
tristate "Support for the Allwinner V3s CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN8I_DE2_CCU
|
||||
tristate "Support for the Allwinner SoCs DE2 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || ARM64 || RISCV || COMPILE_TEST
|
||||
|
||||
config SUN8I_R40_CCU
|
||||
tristate "Support for the Allwinner R40 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || COMPILE_TEST
|
||||
|
||||
config SUN9I_A80_CCU
|
||||
tristate "Support for the Allwinner A80 CCU"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN9I || COMPILE_TEST
|
||||
|
||||
config SUN8I_R_CCU
|
||||
tristate "Support for Allwinner SoCs' PRCM CCUs"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
depends on MACH_SUN8I || ARM64 || COMPILE_TEST
|
||||
|
||||
endif
|
||||
|
||||
@@ -1094,6 +1094,7 @@ static const struct ccu_reset_map sun50i_h616_ccu_resets[] = {
|
||||
[RST_BUS_TCON_LCD1] = { 0xb7c, BIT(17) },
|
||||
[RST_BUS_TCON_TV0] = { 0xb9c, BIT(16) },
|
||||
[RST_BUS_TCON_TV1] = { 0xb9c, BIT(17) },
|
||||
[RST_BUS_LVDS] = { 0xbac, BIT(16) },
|
||||
[RST_BUS_TVE_TOP] = { 0xbbc, BIT(16) },
|
||||
[RST_BUS_TVE0] = { 0xbbc, BIT(17) },
|
||||
[RST_BUS_HDCP] = { 0xc4c, BIT(16) },
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/clk-provider.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
@@ -239,6 +240,16 @@ static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = {
|
||||
.num_resets = ARRAY_SIZE(sun50i_h5_de2_resets),
|
||||
};
|
||||
|
||||
static const struct sunxi_ccu_desc sun50i_h616_de33_clk_desc = {
|
||||
.ccu_clks = sun8i_de2_ccu_clks,
|
||||
.num_ccu_clks = ARRAY_SIZE(sun8i_de2_ccu_clks),
|
||||
|
||||
.hw_clks = &sun8i_h3_de2_hw_clks,
|
||||
|
||||
.resets = sun50i_h5_de2_resets,
|
||||
.num_resets = ARRAY_SIZE(sun50i_h5_de2_resets),
|
||||
};
|
||||
|
||||
static int sunxi_de2_clk_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct clk *bus_clk, *mod_clk;
|
||||
@@ -291,6 +302,16 @@ static int sunxi_de2_clk_probe(struct platform_device *pdev)
|
||||
goto err_disable_mod_clk;
|
||||
}
|
||||
|
||||
/*
|
||||
* The DE33 requires these additional (unknown) registers set
|
||||
* during initialisation.
|
||||
*/
|
||||
if (of_device_is_compatible(pdev->dev.of_node,
|
||||
"allwinner,sun50i-h616-de33-clk")) {
|
||||
writel(0, reg + 0x24);
|
||||
writel(0x0000a980, reg + 0x28);
|
||||
}
|
||||
|
||||
ret = devm_sunxi_ccu_probe(&pdev->dev, reg, ccu_desc);
|
||||
if (ret)
|
||||
goto err_assert_reset;
|
||||
@@ -335,6 +356,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = {
|
||||
.compatible = "allwinner,sun50i-h6-de3-clk",
|
||||
.data = &sun50i_h5_de2_clk_desc,
|
||||
},
|
||||
{
|
||||
.compatible = "allwinner,sun50i-h616-de33-clk",
|
||||
.data = &sun50i_h616_de33_clk_desc,
|
||||
},
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, sunxi_de2_clk_ids);
|
||||
|
||||
@@ -2,13 +2,13 @@
|
||||
menuconfig CLK_SUNXI
|
||||
bool "Legacy clock support for Allwinner SoCs"
|
||||
depends on (ARM && ARCH_SUNXI) || COMPILE_TEST
|
||||
default y
|
||||
default (ARM && ARCH_SUNXI)
|
||||
|
||||
if CLK_SUNXI
|
||||
|
||||
config CLK_SUNXI_CLOCKS
|
||||
bool "Legacy clock drivers"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
help
|
||||
Legacy clock drivers being used on older (A10, A13, A20,
|
||||
A23, A31, A80) SoCs. These drivers are kept around for
|
||||
@@ -19,14 +19,14 @@ config CLK_SUNXI_CLOCKS
|
||||
|
||||
config CLK_SUNXI_PRCM_SUN6I
|
||||
bool "Legacy A31 PRCM driver"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
help
|
||||
Legacy clock driver for the A31 PRCM clocks. Those are
|
||||
usually needed for the PMIC communication, mostly.
|
||||
|
||||
config CLK_SUNXI_PRCM_SUN8I
|
||||
bool "Legacy sun8i PRCM driver"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
help
|
||||
Legacy clock driver for the sun8i family PRCM clocks.
|
||||
Those are usually needed for the PMIC communication,
|
||||
@@ -34,7 +34,7 @@ config CLK_SUNXI_PRCM_SUN8I
|
||||
|
||||
config CLK_SUNXI_PRCM_SUN9I
|
||||
bool "Legacy A80 PRCM driver"
|
||||
default y
|
||||
default ARCH_SUNXI
|
||||
help
|
||||
Legacy clock driver for the A80 PRCM clocks. Those are
|
||||
usually needed for the PMIC communication, mostly.
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) */
|
||||
/*
|
||||
* Copyright (c) 2021, The Linux Foundation. All rights reserved.
|
||||
* Copyright (c) 2021, Konrad Dybcio <konrad.dybcio@somainline.org>
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SM6350_H
|
||||
#define _DT_BINDINGS_CLK_QCOM_VIDEO_CC_SM6350_H
|
||||
|
||||
/* VIDEO_CC clocks */
|
||||
#define VIDEO_PLL0 0
|
||||
#define VIDEO_PLL0_OUT_EVEN 1
|
||||
#define VIDEO_CC_IRIS_AHB_CLK 2
|
||||
#define VIDEO_CC_IRIS_CLK_SRC 3
|
||||
#define VIDEO_CC_MVS0_AXI_CLK 4
|
||||
#define VIDEO_CC_MVS0_CORE_CLK 5
|
||||
#define VIDEO_CC_MVSC_CORE_CLK 6
|
||||
#define VIDEO_CC_MVSC_CTL_AXI_CLK 7
|
||||
#define VIDEO_CC_SLEEP_CLK 8
|
||||
#define VIDEO_CC_SLEEP_CLK_SRC 9
|
||||
#define VIDEO_CC_VENUS_AHB_CLK 10
|
||||
|
||||
/* GDSCs */
|
||||
#define MVSC_GDSC 0
|
||||
#define MVS0_GDSC 1
|
||||
|
||||
#endif
|
||||
@@ -47,6 +47,7 @@
|
||||
#define SCLK_MACREF 152
|
||||
#define SCLK_MACPLL 153
|
||||
#define SCLK_SFC 160
|
||||
#define SCLK_USB480M 161
|
||||
|
||||
/* aclk gates */
|
||||
#define ACLK_DMAC2 194
|
||||
|
||||
@@ -414,6 +414,12 @@
|
||||
#define MCLK_I2S2_2CH_SAI_SRC_PRE 402
|
||||
#define MCLK_I2S3_8CH_SAI_SRC_PRE 403
|
||||
#define MCLK_SDPDIF_SRC_PRE 404
|
||||
#define SCLK_SDMMC_DRV 405
|
||||
#define SCLK_SDMMC_SAMPLE 406
|
||||
#define SCLK_SDIO0_DRV 407
|
||||
#define SCLK_SDIO0_SAMPLE 408
|
||||
#define SCLK_SDIO1_DRV 409
|
||||
#define SCLK_SDIO1_SAMPLE 410
|
||||
|
||||
/* scmi-clocks indices */
|
||||
#define SCMI_PCLK_KEYREADER 0
|
||||
|
||||
@@ -594,4 +594,14 @@
|
||||
#define SCMI_ARMCLK_B 11
|
||||
#define SCMI_CLK_GPU 456
|
||||
|
||||
/* IOC-controlled output clocks */
|
||||
#define CLK_SAI0_MCLKOUT_TO_IO 571
|
||||
#define CLK_SAI1_MCLKOUT_TO_IO 572
|
||||
#define CLK_SAI2_MCLKOUT_TO_IO 573
|
||||
#define CLK_SAI3_MCLKOUT_TO_IO 574
|
||||
#define CLK_SAI4_MCLKOUT_TO_IO 575
|
||||
#define CLK_SAI4_MCLKOUT_TO_IO 575
|
||||
#define CLK_FSPI0_TO_IO 576
|
||||
#define CLK_FSPI1_TO_IO 577
|
||||
|
||||
#endif
|
||||
|
||||
@@ -69,5 +69,6 @@
|
||||
#define RST_BUS_GPADC 60
|
||||
#define RST_BUS_TCON_LCD0 61
|
||||
#define RST_BUS_TCON_LCD1 62
|
||||
#define RST_BUS_LVDS 63
|
||||
|
||||
#endif /* _DT_BINDINGS_RESET_SUN50I_H616_H_ */
|
||||
|
||||
Reference in New Issue
Block a user