diff --git a/arch/arm64/configs/vendor/holi_debug.config b/arch/arm64/configs/vendor/holi_debug.config index 5e5a6dd7d244..a21fca31983f 100644 --- a/arch/arm64/configs/vendor/holi_debug.config +++ b/arch/arm64/configs/vendor/holi_debug.config @@ -108,3 +108,4 @@ CONFIG_MSM_RPM_SMD=y CONFIG_SM_GCC_HOLI=y CONFIG_DEBUG_PANIC_ON_OOM=y CONFIG_KPROBES=y +CONFIG_QCOM_CLK_SMD_RPM=y diff --git a/drivers/clk/qcom/Kconfig b/drivers/clk/qcom/Kconfig index e78e86283efe..a2b7a0ae465a 100644 --- a/drivers/clk/qcom/Kconfig +++ b/drivers/clk/qcom/Kconfig @@ -52,7 +52,7 @@ config QCOM_CLK_RPM config QCOM_CLK_SMD_RPM tristate "RPM over SMD based Clock Controller" - depends on QCOM_SMD_RPM + depends on MSM_RPM_SMD select QCOM_RPMCC help The RPM (Resource Power Manager) is a dedicated hardware engine for diff --git a/drivers/clk/qcom/clk-smd-rpm.c b/drivers/clk/qcom/clk-smd-rpm.c index e5c3db11bf26..61382577f1c1 100644 --- a/drivers/clk/qcom/clk-smd-rpm.c +++ b/drivers/clk/qcom/clk-smd-rpm.c @@ -1,7 +1,7 @@ // SPDX-License-Identifier: GPL-2.0-only /* * Copyright (c) 2016, Linaro Limited - * Copyright (c) 2014, The Linux Foundation. All rights reserved. + * Copyright (c) 2014, 2020, The Linux Foundation. All rights reserved. */ #include @@ -15,10 +15,14 @@ #include #include #include +#include +#include #include #include +#include "clk-debug.h" + #define QCOM_RPM_KEY_SOFTWARE_ENABLE 0x6e657773 #define QCOM_RPM_KEY_PIN_CTRL_CLK_BUFFER_ENABLE_KEY 0x62636370 #define QCOM_RPM_SMD_KEY_RATE 0x007a484b @@ -29,6 +33,8 @@ #define __DEFINE_CLK_SMD_RPM(_platform, _name, _active, type, r_id, stat_id, \ key) \ static struct clk_smd_rpm _platform##_##_active; \ + static unsigned long _name##_##last_active_set_vote; \ + static unsigned long _name##_##last_sleep_set_vote; \ static struct clk_smd_rpm _platform##_##_name = { \ .rpm_res_type = (type), \ .rpm_clk_id = (r_id), \ @@ -36,6 +42,8 @@ .rpm_key = (key), \ .peer = &_platform##_##_active, \ .rate = INT_MAX, \ + .last_active_set_vote = &_name##_##last_active_set_vote, \ + .last_sleep_set_vote = &_name##_##last_sleep_set_vote, \ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_ops, \ .name = #_name, \ @@ -51,6 +59,8 @@ .rpm_key = (key), \ .peer = &_platform##_##_name, \ .rate = INT_MAX, \ + .last_active_set_vote = &_name##_##last_active_set_vote, \ + .last_sleep_set_vote = &_name##_##last_sleep_set_vote, \ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_ops, \ .name = #_active, \ @@ -62,6 +72,8 @@ #define __DEFINE_CLK_SMD_RPM_BRANCH(_platform, _name, _active, type, r_id, \ stat_id, r, key) \ static struct clk_smd_rpm _platform##_##_active; \ + static unsigned long _name##_##last_active_set_vote; \ + static unsigned long _name##_##last_sleep_set_vote; \ static struct clk_smd_rpm _platform##_##_name = { \ .rpm_res_type = (type), \ .rpm_clk_id = (r_id), \ @@ -70,6 +82,8 @@ .branch = true, \ .peer = &_platform##_##_active, \ .rate = (r), \ + .last_active_set_vote = &_name##_##last_active_set_vote, \ + .last_sleep_set_vote = &_name##_##last_sleep_set_vote, \ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_branch_ops, \ .name = #_name, \ @@ -86,6 +100,8 @@ .branch = true, \ .peer = &_platform##_##_name, \ .rate = (r), \ + .last_active_set_vote = &_name##_##last_active_set_vote, \ + .last_sleep_set_vote = &_name##_##last_sleep_set_vote, \ .hw.init = &(struct clk_init_data){ \ .ops = &clk_smd_rpm_branch_ops, \ .name = #_active, \ @@ -129,7 +145,8 @@ struct clk_smd_rpm { struct clk_smd_rpm *peer; struct clk_hw hw; unsigned long rate; - struct qcom_smd_rpm *rpm; + unsigned long *last_active_set_vote; + unsigned long *last_sleep_set_vote; }; struct clk_smd_rpm_req { @@ -138,74 +155,71 @@ struct clk_smd_rpm_req { __le32 value; }; -struct rpm_cc { - struct qcom_rpm *rpm; - struct clk_smd_rpm **clks; - size_t num_clks; -}; - struct rpm_smd_clk_desc { - struct clk_smd_rpm **clks; + struct clk_hw **clks; size_t num_clks; }; static DEFINE_MUTEX(rpm_smd_clk_lock); -static int clk_smd_rpm_handoff(struct clk_smd_rpm *r) +static int clk_smd_rpm_prepare(struct clk_hw *hw); + +static int clk_smd_rpm_handoff(struct clk_hw *hw) { - int ret; - struct clk_smd_rpm_req req = { - .key = cpu_to_le32(r->rpm_key), - .nbytes = cpu_to_le32(sizeof(u32)), - .value = cpu_to_le32(r->branch ? 1 : INT_MAX), - }; - - ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE, - r->rpm_res_type, r->rpm_clk_id, &req, - sizeof(req)); - if (ret) - return ret; - ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE, - r->rpm_res_type, r->rpm_clk_id, &req, - sizeof(req)); - if (ret) - return ret; - - return 0; + return clk_smd_rpm_prepare(hw); } static int clk_smd_rpm_set_rate_active(struct clk_smd_rpm *r, - unsigned long rate) + uint32_t rate) { - struct clk_smd_rpm_req req = { + int ret = 0; + struct msm_rpm_kvp req = { .key = cpu_to_le32(r->rpm_key), - .nbytes = cpu_to_le32(sizeof(u32)), - .value = cpu_to_le32(DIV_ROUND_UP(rate, 1000)), /* to kHz */ + .data = (void *)&rate, + .length = sizeof(rate), }; - return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE, - r->rpm_res_type, r->rpm_clk_id, &req, - sizeof(req)); + if (*r->last_active_set_vote == rate) + return ret; + + ret = msm_rpm_send_message(QCOM_SMD_RPM_ACTIVE_STATE, r->rpm_res_type, + r->rpm_clk_id, &req, 1); + if (ret) + return ret; + + *r->last_active_set_vote = rate; + + return ret; } static int clk_smd_rpm_set_rate_sleep(struct clk_smd_rpm *r, - unsigned long rate) + uint32_t rate) { - struct clk_smd_rpm_req req = { + int ret = 0; + struct msm_rpm_kvp req = { .key = cpu_to_le32(r->rpm_key), - .nbytes = cpu_to_le32(sizeof(u32)), - .value = cpu_to_le32(DIV_ROUND_UP(rate, 1000)), /* to kHz */ + .data = (void *)&rate, + .length = sizeof(rate), }; - return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE, - r->rpm_res_type, r->rpm_clk_id, &req, - sizeof(req)); + if (*r->last_sleep_set_vote == rate) + return ret; + + ret = msm_rpm_send_message(QCOM_SMD_RPM_SLEEP_STATE, r->rpm_res_type, + r->rpm_clk_id, &req, 1); + if (ret) + return ret; + + *r->last_sleep_set_vote = rate; + + return ret; } static void to_active_sleep(struct clk_smd_rpm *r, unsigned long rate, unsigned long *active, unsigned long *sleep) { - *active = rate; + /* Convert the rate (hz) to khz */ + *active = DIV_ROUND_UP(rate, 1000); /* * Active-only clocks don't care what the rate is during sleep. So, @@ -223,17 +237,17 @@ static int clk_smd_rpm_prepare(struct clk_hw *hw) struct clk_smd_rpm *peer = r->peer; unsigned long this_rate = 0, this_sleep_rate = 0; unsigned long peer_rate = 0, peer_sleep_rate = 0; - unsigned long active_rate, sleep_rate; + uint32_t active_rate, sleep_rate; int ret = 0; mutex_lock(&rpm_smd_clk_lock); - /* Don't send requests to the RPM if the rate has not been set. */ - if (!r->rate) - goto out; - to_active_sleep(r, r->rate, &this_rate, &this_sleep_rate); + /* Don't send requests to the RPM if the rate has not been set. */ + if (this_rate == 0) + goto out; + /* Take peer clock's rate into account only if it's enabled. */ if (peer->enabled) to_active_sleep(peer, peer->rate, @@ -271,13 +285,13 @@ static void clk_smd_rpm_unprepare(struct clk_hw *hw) struct clk_smd_rpm *r = to_clk_smd_rpm(hw); struct clk_smd_rpm *peer = r->peer; unsigned long peer_rate = 0, peer_sleep_rate = 0; - unsigned long active_rate, sleep_rate; + uint32_t active_rate, sleep_rate; int ret; mutex_lock(&rpm_smd_clk_lock); if (!r->rate) - goto out; + goto enable; /* Take peer clock's rate into account only if it's enabled. */ if (peer->enabled) @@ -294,6 +308,7 @@ static void clk_smd_rpm_unprepare(struct clk_hw *hw) if (ret) goto out; +enable: r->enabled = false; out: @@ -305,7 +320,7 @@ static int clk_smd_rpm_set_rate(struct clk_hw *hw, unsigned long rate, { struct clk_smd_rpm *r = to_clk_smd_rpm(hw); struct clk_smd_rpm *peer = r->peer; - unsigned long active_rate, sleep_rate; + uint32_t active_rate, sleep_rate; unsigned long this_rate = 0, this_sleep_rate = 0; unsigned long peer_rate = 0, peer_sleep_rate = 0; int ret = 0; @@ -364,33 +379,61 @@ static unsigned long clk_smd_rpm_recalc_rate(struct clk_hw *hw, return r->rate; } -static int clk_smd_rpm_enable_scaling(struct qcom_smd_rpm *rpm) +static int clk_smd_rpm_enable_scaling(void) { - int ret; - struct clk_smd_rpm_req req = { + int ret = 0; + uint32_t value = cpu_to_le32(1); + struct msm_rpm_kvp req = { .key = cpu_to_le32(QCOM_RPM_SMD_KEY_ENABLE), - .nbytes = cpu_to_le32(sizeof(u32)), - .value = cpu_to_le32(1), + .data = (void *)&value, + .length = sizeof(value), }; - ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_SLEEP_STATE, - QCOM_SMD_RPM_MISC_CLK, - QCOM_RPM_SCALING_ENABLE_ID, &req, sizeof(req)); + ret = msm_rpm_send_message(QCOM_SMD_RPM_SLEEP_STATE, + QCOM_SMD_RPM_MISC_CLK, + QCOM_RPM_SCALING_ENABLE_ID, &req, 1); if (ret) { pr_err("RPM clock scaling (sleep set) not enabled!\n"); return ret; } - ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_ACTIVE_STATE, - QCOM_SMD_RPM_MISC_CLK, - QCOM_RPM_SCALING_ENABLE_ID, &req, sizeof(req)); + ret = msm_rpm_send_message(QCOM_SMD_RPM_ACTIVE_STATE, + QCOM_SMD_RPM_MISC_CLK, + QCOM_RPM_SCALING_ENABLE_ID, &req, 1); if (ret) { pr_err("RPM clock scaling (active set) not enabled!\n"); return ret; } pr_debug("%s: RPM clock scaling is enabled\n", __func__); - return 0; + return ret; +} + +static int clk_vote_bimc(struct clk_hw *hw, uint32_t rate) +{ + int ret; + struct clk_smd_rpm *r = to_clk_smd_rpm(hw); + struct msm_rpm_kvp req = { + .key = r->rpm_key, + .data = (void *)&rate, + .length = sizeof(rate), + }; + + ret = msm_rpm_send_message(QCOM_SMD_RPM_ACTIVE_STATE, + r->rpm_res_type, r->rpm_clk_id, &req, 1); + if (ret < 0) { + if (ret != -EPROBE_DEFER) + WARN(1, "BIMC vote not sent!\n"); + } + + return ret; +} + +static int clk_smd_rpm_is_enabled(struct clk_hw *hw) +{ + struct clk_smd_rpm *r = to_clk_smd_rpm(hw); + + return r->enabled; } static const struct clk_ops clk_smd_rpm_ops = { @@ -399,11 +442,17 @@ static const struct clk_ops clk_smd_rpm_ops = { .set_rate = clk_smd_rpm_set_rate, .round_rate = clk_smd_rpm_round_rate, .recalc_rate = clk_smd_rpm_recalc_rate, + .is_enabled = clk_smd_rpm_is_enabled, + .debug_init = clk_debug_measure_add, }; static const struct clk_ops clk_smd_rpm_branch_ops = { .prepare = clk_smd_rpm_prepare, .unprepare = clk_smd_rpm_unprepare, + .round_rate = clk_smd_rpm_round_rate, + .recalc_rate = clk_smd_rpm_recalc_rate, + .is_enabled = clk_smd_rpm_is_enabled, + .debug_init = clk_debug_measure_add, }; /* msm8916 */ @@ -420,31 +469,31 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, bb_clk2_pin, bb_clk2_a_pin, 2); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk1_pin, rf_clk1_a_pin, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8916, rf_clk2_pin, rf_clk2_a_pin, 5); -static struct clk_smd_rpm *msm8916_clks[] = { - [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk, - [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1, - [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a, - [RPM_SMD_BB_CLK2] = &msm8916_bb_clk2, - [RPM_SMD_BB_CLK2_A] = &msm8916_bb_clk2_a, - [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a, - [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2, - [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a, - [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin, - [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin, - [RPM_SMD_BB_CLK2_PIN] = &msm8916_bb_clk2_pin, - [RPM_SMD_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin, - [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin, - [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin, - [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin, - [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin, +static struct clk_hw *msm8916_clks[] = { + [RPM_SMD_PCNOC_CLK] = &msm8916_pcnoc_clk.hw, + [RPM_SMD_PCNOC_A_CLK] = &msm8916_pcnoc_a_clk.hw, + [RPM_SMD_SNOC_CLK] = &msm8916_snoc_clk.hw, + [RPM_SMD_SNOC_A_CLK] = &msm8916_snoc_a_clk.hw, + [RPM_SMD_BIMC_CLK] = &msm8916_bimc_clk.hw, + [RPM_SMD_BIMC_A_CLK] = &msm8916_bimc_a_clk.hw, + [RPM_SMD_QDSS_CLK] = &msm8916_qdss_clk.hw, + [RPM_SMD_QDSS_A_CLK] = &msm8916_qdss_a_clk.hw, + [RPM_SMD_BB_CLK1] = &msm8916_bb_clk1.hw, + [RPM_SMD_BB_CLK1_A] = &msm8916_bb_clk1_a.hw, + [RPM_SMD_BB_CLK2] = &msm8916_bb_clk2.hw, + [RPM_SMD_BB_CLK2_A] = &msm8916_bb_clk2_a.hw, + [RPM_SMD_RF_CLK1] = &msm8916_rf_clk1.hw, + [RPM_SMD_RF_CLK1_A] = &msm8916_rf_clk1_a.hw, + [RPM_SMD_RF_CLK2] = &msm8916_rf_clk2.hw, + [RPM_SMD_RF_CLK2_A] = &msm8916_rf_clk2_a.hw, + [RPM_SMD_BB_CLK1_PIN] = &msm8916_bb_clk1_pin.hw, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8916_bb_clk1_a_pin.hw, + [RPM_SMD_BB_CLK2_PIN] = &msm8916_bb_clk2_pin.hw, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8916_bb_clk2_a_pin.hw, + [RPM_SMD_RF_CLK1_PIN] = &msm8916_rf_clk1_pin.hw, + [RPM_SMD_RF_CLK1_A_PIN] = &msm8916_rf_clk1_a_pin.hw, + [RPM_SMD_RF_CLK2_PIN] = &msm8916_rf_clk2_pin.hw, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8916_rf_clk2_a_pin.hw, }; static const struct rpm_smd_clk_desc rpm_clk_msm8916 = { @@ -475,47 +524,47 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a0_pin, cxo_a0_a_pin, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a1_pin, cxo_a1_a_pin, 5); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8974, cxo_a2_pin, cxo_a2_a_pin, 6); -static struct clk_smd_rpm *msm8974_clks[] = { - [RPM_SMD_PNOC_CLK] = &msm8974_pnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &msm8974_pnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8974_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8974_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk, - [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk, - [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8974_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8974_bimc_a_clk, - [RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk, - [RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8974_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8974_qdss_a_clk, - [RPM_SMD_CXO_D0] = &msm8974_cxo_d0, - [RPM_SMD_CXO_D0_A] = &msm8974_cxo_d0_a, - [RPM_SMD_CXO_D1] = &msm8974_cxo_d1, - [RPM_SMD_CXO_D1_A] = &msm8974_cxo_d1_a, - [RPM_SMD_CXO_A0] = &msm8974_cxo_a0, - [RPM_SMD_CXO_A0_A] = &msm8974_cxo_a0_a, - [RPM_SMD_CXO_A1] = &msm8974_cxo_a1, - [RPM_SMD_CXO_A1_A] = &msm8974_cxo_a1_a, - [RPM_SMD_CXO_A2] = &msm8974_cxo_a2, - [RPM_SMD_CXO_A2_A] = &msm8974_cxo_a2_a, - [RPM_SMD_DIFF_CLK] = &msm8974_diff_clk, - [RPM_SMD_DIFF_A_CLK] = &msm8974_diff_a_clk, - [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1, - [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1, - [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2, - [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2, - [RPM_SMD_CXO_D0_PIN] = &msm8974_cxo_d0_pin, - [RPM_SMD_CXO_D0_A_PIN] = &msm8974_cxo_d0_a_pin, - [RPM_SMD_CXO_D1_PIN] = &msm8974_cxo_d1_pin, - [RPM_SMD_CXO_D1_A_PIN] = &msm8974_cxo_d1_a_pin, - [RPM_SMD_CXO_A0_PIN] = &msm8974_cxo_a0_pin, - [RPM_SMD_CXO_A0_A_PIN] = &msm8974_cxo_a0_a_pin, - [RPM_SMD_CXO_A1_PIN] = &msm8974_cxo_a1_pin, - [RPM_SMD_CXO_A1_A_PIN] = &msm8974_cxo_a1_a_pin, - [RPM_SMD_CXO_A2_PIN] = &msm8974_cxo_a2_pin, - [RPM_SMD_CXO_A2_A_PIN] = &msm8974_cxo_a2_a_pin, +static struct clk_hw *msm8974_clks[] = { + [RPM_SMD_PNOC_CLK] = &msm8974_pnoc_clk.hw, + [RPM_SMD_PNOC_A_CLK] = &msm8974_pnoc_a_clk.hw, + [RPM_SMD_SNOC_CLK] = &msm8974_snoc_clk.hw, + [RPM_SMD_SNOC_A_CLK] = &msm8974_snoc_a_clk.hw, + [RPM_SMD_CNOC_CLK] = &msm8974_cnoc_clk.hw, + [RPM_SMD_CNOC_A_CLK] = &msm8974_cnoc_a_clk.hw, + [RPM_SMD_MMSSNOC_AHB_CLK] = &msm8974_mmssnoc_ahb_clk.hw, + [RPM_SMD_MMSSNOC_AHB_A_CLK] = &msm8974_mmssnoc_ahb_a_clk.hw, + [RPM_SMD_BIMC_CLK] = &msm8974_bimc_clk.hw, + [RPM_SMD_BIMC_A_CLK] = &msm8974_bimc_a_clk.hw, + [RPM_SMD_OCMEMGX_CLK] = &msm8974_ocmemgx_clk.hw, + [RPM_SMD_OCMEMGX_A_CLK] = &msm8974_ocmemgx_a_clk.hw, + [RPM_SMD_QDSS_CLK] = &msm8974_qdss_clk.hw, + [RPM_SMD_QDSS_A_CLK] = &msm8974_qdss_a_clk.hw, + [RPM_SMD_CXO_D0] = &msm8974_cxo_d0.hw, + [RPM_SMD_CXO_D0_A] = &msm8974_cxo_d0_a.hw, + [RPM_SMD_CXO_D1] = &msm8974_cxo_d1.hw, + [RPM_SMD_CXO_D1_A] = &msm8974_cxo_d1_a.hw, + [RPM_SMD_CXO_A0] = &msm8974_cxo_a0.hw, + [RPM_SMD_CXO_A0_A] = &msm8974_cxo_a0_a.hw, + [RPM_SMD_CXO_A1] = &msm8974_cxo_a1.hw, + [RPM_SMD_CXO_A1_A] = &msm8974_cxo_a1_a.hw, + [RPM_SMD_CXO_A2] = &msm8974_cxo_a2.hw, + [RPM_SMD_CXO_A2_A] = &msm8974_cxo_a2_a.hw, + [RPM_SMD_DIFF_CLK] = &msm8974_diff_clk.hw, + [RPM_SMD_DIFF_A_CLK] = &msm8974_diff_a_clk.hw, + [RPM_SMD_DIV_CLK1] = &msm8974_div_clk1.hw, + [RPM_SMD_DIV_A_CLK1] = &msm8974_div_a_clk1.hw, + [RPM_SMD_DIV_CLK2] = &msm8974_div_clk2.hw, + [RPM_SMD_DIV_A_CLK2] = &msm8974_div_a_clk2.hw, + [RPM_SMD_CXO_D0_PIN] = &msm8974_cxo_d0_pin.hw, + [RPM_SMD_CXO_D0_A_PIN] = &msm8974_cxo_d0_a_pin.hw, + [RPM_SMD_CXO_D1_PIN] = &msm8974_cxo_d1_pin.hw, + [RPM_SMD_CXO_D1_A_PIN] = &msm8974_cxo_d1_a_pin.hw, + [RPM_SMD_CXO_A0_PIN] = &msm8974_cxo_a0_pin.hw, + [RPM_SMD_CXO_A0_A_PIN] = &msm8974_cxo_a0_a_pin.hw, + [RPM_SMD_CXO_A1_PIN] = &msm8974_cxo_a1_pin.hw, + [RPM_SMD_CXO_A1_A_PIN] = &msm8974_cxo_a1_a_pin.hw, + [RPM_SMD_CXO_A2_PIN] = &msm8974_cxo_a2_pin.hw, + [RPM_SMD_CXO_A2_A_PIN] = &msm8974_cxo_a2_a_pin.hw, }; static const struct rpm_smd_clk_desc rpm_clk_msm8974 = { @@ -551,51 +600,51 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, bb_clk2_pin, bb_clk2_a_pin, 2); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk1_pin, rf_clk1_a_pin, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8996, rf_clk2_pin, rf_clk2_a_pin, 5); -static struct clk_smd_rpm *msm8996_clks[] = { - [RPM_SMD_PCNOC_CLK] = &msm8996_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &msm8996_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8996_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8996_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &msm8996_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &msm8996_cnoc_a_clk, - [RPM_SMD_BIMC_CLK] = &msm8996_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8996_bimc_a_clk, - [RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk, - [RPM_SMD_MMAXI_A_CLK] = &msm8996_mmssnoc_axi_rpm_a_clk, - [RPM_SMD_IPA_CLK] = &msm8996_ipa_clk, - [RPM_SMD_IPA_A_CLK] = &msm8996_ipa_a_clk, - [RPM_SMD_CE1_CLK] = &msm8996_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &msm8996_ce1_a_clk, - [RPM_SMD_AGGR1_NOC_CLK] = &msm8996_aggre1_noc_clk, - [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8996_aggre1_noc_a_clk, - [RPM_SMD_AGGR2_NOC_CLK] = &msm8996_aggre2_noc_clk, - [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8996_aggre2_noc_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8996_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8996_qdss_a_clk, - [RPM_SMD_BB_CLK1] = &msm8996_bb_clk1, - [RPM_SMD_BB_CLK1_A] = &msm8996_bb_clk1_a, - [RPM_SMD_BB_CLK2] = &msm8996_bb_clk2, - [RPM_SMD_BB_CLK2_A] = &msm8996_bb_clk2_a, - [RPM_SMD_RF_CLK1] = &msm8996_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &msm8996_rf_clk1_a, - [RPM_SMD_RF_CLK2] = &msm8996_rf_clk2, - [RPM_SMD_RF_CLK2_A] = &msm8996_rf_clk2_a, - [RPM_SMD_LN_BB_CLK] = &msm8996_ln_bb_clk, - [RPM_SMD_LN_BB_A_CLK] = &msm8996_ln_bb_a_clk, - [RPM_SMD_DIV_CLK1] = &msm8996_div_clk1, - [RPM_SMD_DIV_A_CLK1] = &msm8996_div_clk1_a, - [RPM_SMD_DIV_CLK2] = &msm8996_div_clk2, - [RPM_SMD_DIV_A_CLK2] = &msm8996_div_clk2_a, - [RPM_SMD_DIV_CLK3] = &msm8996_div_clk3, - [RPM_SMD_DIV_A_CLK3] = &msm8996_div_clk3_a, - [RPM_SMD_BB_CLK1_PIN] = &msm8996_bb_clk1_pin, - [RPM_SMD_BB_CLK1_A_PIN] = &msm8996_bb_clk1_a_pin, - [RPM_SMD_BB_CLK2_PIN] = &msm8996_bb_clk2_pin, - [RPM_SMD_BB_CLK2_A_PIN] = &msm8996_bb_clk2_a_pin, - [RPM_SMD_RF_CLK1_PIN] = &msm8996_rf_clk1_pin, - [RPM_SMD_RF_CLK1_A_PIN] = &msm8996_rf_clk1_a_pin, - [RPM_SMD_RF_CLK2_PIN] = &msm8996_rf_clk2_pin, - [RPM_SMD_RF_CLK2_A_PIN] = &msm8996_rf_clk2_a_pin, +static struct clk_hw *msm8996_clks[] = { + [RPM_SMD_PCNOC_CLK] = &msm8996_pcnoc_clk.hw, + [RPM_SMD_PCNOC_A_CLK] = &msm8996_pcnoc_a_clk.hw, + [RPM_SMD_SNOC_CLK] = &msm8996_snoc_clk.hw, + [RPM_SMD_SNOC_A_CLK] = &msm8996_snoc_a_clk.hw, + [RPM_SMD_CNOC_CLK] = &msm8996_cnoc_clk.hw, + [RPM_SMD_CNOC_A_CLK] = &msm8996_cnoc_a_clk.hw, + [RPM_SMD_BIMC_CLK] = &msm8996_bimc_clk.hw, + [RPM_SMD_BIMC_A_CLK] = &msm8996_bimc_a_clk.hw, + [RPM_SMD_MMAXI_CLK] = &msm8996_mmssnoc_axi_rpm_clk.hw, + [RPM_SMD_MMAXI_A_CLK] = &msm8996_mmssnoc_axi_rpm_a_clk.hw, + [RPM_SMD_IPA_CLK] = &msm8996_ipa_clk.hw, + [RPM_SMD_IPA_A_CLK] = &msm8996_ipa_a_clk.hw, + [RPM_SMD_CE1_CLK] = &msm8996_ce1_clk.hw, + [RPM_SMD_CE1_A_CLK] = &msm8996_ce1_a_clk.hw, + [RPM_SMD_AGGR1_NOC_CLK] = &msm8996_aggre1_noc_clk.hw, + [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8996_aggre1_noc_a_clk.hw, + [RPM_SMD_AGGR2_NOC_CLK] = &msm8996_aggre2_noc_clk.hw, + [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8996_aggre2_noc_a_clk.hw, + [RPM_SMD_QDSS_CLK] = &msm8996_qdss_clk.hw, + [RPM_SMD_QDSS_A_CLK] = &msm8996_qdss_a_clk.hw, + [RPM_SMD_BB_CLK1] = &msm8996_bb_clk1.hw, + [RPM_SMD_BB_CLK1_A] = &msm8996_bb_clk1_a.hw, + [RPM_SMD_BB_CLK2] = &msm8996_bb_clk2.hw, + [RPM_SMD_BB_CLK2_A] = &msm8996_bb_clk2_a.hw, + [RPM_SMD_RF_CLK1] = &msm8996_rf_clk1.hw, + [RPM_SMD_RF_CLK1_A] = &msm8996_rf_clk1_a.hw, + [RPM_SMD_RF_CLK2] = &msm8996_rf_clk2.hw, + [RPM_SMD_RF_CLK2_A] = &msm8996_rf_clk2_a.hw, + [RPM_SMD_LN_BB_CLK] = &msm8996_ln_bb_clk.hw, + [RPM_SMD_LN_BB_CLK_A] = &msm8996_ln_bb_a_clk.hw, + [RPM_SMD_DIV_CLK1] = &msm8996_div_clk1.hw, + [RPM_SMD_DIV_A_CLK1] = &msm8996_div_clk1_a.hw, + [RPM_SMD_DIV_CLK2] = &msm8996_div_clk2.hw, + [RPM_SMD_DIV_A_CLK2] = &msm8996_div_clk2_a.hw, + [RPM_SMD_DIV_CLK3] = &msm8996_div_clk3.hw, + [RPM_SMD_DIV_A_CLK3] = &msm8996_div_clk3_a.hw, + [RPM_SMD_BB_CLK1_PIN] = &msm8996_bb_clk1_pin.hw, + [RPM_SMD_BB_CLK1_A_PIN] = &msm8996_bb_clk1_a_pin.hw, + [RPM_SMD_BB_CLK2_PIN] = &msm8996_bb_clk2_pin.hw, + [RPM_SMD_BB_CLK2_A_PIN] = &msm8996_bb_clk2_a_pin.hw, + [RPM_SMD_RF_CLK1_PIN] = &msm8996_rf_clk1_pin.hw, + [RPM_SMD_RF_CLK1_A_PIN] = &msm8996_rf_clk1_a_pin.hw, + [RPM_SMD_RF_CLK2_PIN] = &msm8996_rf_clk2_pin.hw, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8996_rf_clk2_a_pin.hw, }; static const struct rpm_smd_clk_desc rpm_clk_msm8996 = { @@ -621,25 +670,25 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, rf_clk1_pin, rf_clk1_a_pin, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER(qcs404, ln_bb_clk, ln_bb_a_clk, 8); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(qcs404, ln_bb_clk_pin, ln_bb_clk_a_pin, 8); -static struct clk_smd_rpm *qcs404_clks[] = { - [RPM_SMD_QDSS_CLK] = &qcs404_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &qcs404_qdss_a_clk, - [RPM_SMD_PNOC_CLK] = &qcs404_pnoc_clk, - [RPM_SMD_PNOC_A_CLK] = &qcs404_pnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &qcs404_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &qcs404_snoc_a_clk, - [RPM_SMD_BIMC_CLK] = &qcs404_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &qcs404_bimc_a_clk, - [RPM_SMD_BIMC_GPU_CLK] = &qcs404_bimc_gpu_clk, - [RPM_SMD_BIMC_GPU_A_CLK] = &qcs404_bimc_gpu_a_clk, - [RPM_SMD_QPIC_CLK] = &qcs404_qpic_clk, - [RPM_SMD_QPIC_CLK_A] = &qcs404_qpic_a_clk, - [RPM_SMD_CE1_CLK] = &qcs404_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &qcs404_ce1_a_clk, - [RPM_SMD_RF_CLK1] = &qcs404_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &qcs404_rf_clk1_a, - [RPM_SMD_LN_BB_CLK] = &qcs404_ln_bb_clk, - [RPM_SMD_LN_BB_A_CLK] = &qcs404_ln_bb_a_clk, +static struct clk_hw *qcs404_clks[] = { + [RPM_SMD_QDSS_CLK] = &qcs404_qdss_clk.hw, + [RPM_SMD_QDSS_A_CLK] = &qcs404_qdss_a_clk.hw, + [RPM_SMD_PNOC_CLK] = &qcs404_pnoc_clk.hw, + [RPM_SMD_PNOC_A_CLK] = &qcs404_pnoc_a_clk.hw, + [RPM_SMD_SNOC_CLK] = &qcs404_snoc_clk.hw, + [RPM_SMD_SNOC_A_CLK] = &qcs404_snoc_a_clk.hw, + [RPM_SMD_BIMC_CLK] = &qcs404_bimc_clk.hw, + [RPM_SMD_BIMC_A_CLK] = &qcs404_bimc_a_clk.hw, + [RPM_SMD_BIMC_GPU_CLK] = &qcs404_bimc_gpu_clk.hw, + [RPM_SMD_BIMC_GPU_A_CLK] = &qcs404_bimc_gpu_a_clk.hw, + [RPM_SMD_QPIC_CLK] = &qcs404_qpic_clk.hw, + [RPM_SMD_QPIC_A_CLK] = &qcs404_qpic_a_clk.hw, + [RPM_SMD_CE1_CLK] = &qcs404_ce1_clk.hw, + [RPM_SMD_CE1_A_CLK] = &qcs404_ce1_a_clk.hw, + [RPM_SMD_RF_CLK1] = &qcs404_rf_clk1.hw, + [RPM_SMD_RF_CLK1_A] = &qcs404_rf_clk1_a.hw, + [RPM_SMD_LN_BB_CLK] = &qcs404_ln_bb_clk.hw, + [RPM_SMD_LN_BB_CLK_A] = &qcs404_ln_bb_a_clk.hw, }; static const struct rpm_smd_clk_desc rpm_clk_qcs404 = { @@ -671,43 +720,44 @@ DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk1, rf_clk1_a, 4); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk2_pin, rf_clk2_a_pin, 5); DEFINE_CLK_SMD_RPM_XO_BUFFER(msm8998, rf_clk3, rf_clk3_a, 6); DEFINE_CLK_SMD_RPM_XO_BUFFER_PINCTRL(msm8998, rf_clk3_pin, rf_clk3_a_pin, 6); -static struct clk_smd_rpm *msm8998_clks[] = { - [RPM_SMD_BIMC_CLK] = &msm8998_bimc_clk, - [RPM_SMD_BIMC_A_CLK] = &msm8998_bimc_a_clk, - [RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk, - [RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk, - [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk, - [RPM_SMD_SNOC_A_CLK] = &msm8998_snoc_a_clk, - [RPM_SMD_CNOC_CLK] = &msm8998_cnoc_clk, - [RPM_SMD_CNOC_A_CLK] = &msm8998_cnoc_a_clk, - [RPM_SMD_CE1_CLK] = &msm8998_ce1_clk, - [RPM_SMD_CE1_A_CLK] = &msm8998_ce1_a_clk, - [RPM_SMD_DIV_CLK1] = &msm8998_div_clk1, - [RPM_SMD_DIV_A_CLK1] = &msm8998_div_clk1_a, - [RPM_SMD_IPA_CLK] = &msm8998_ipa_clk, - [RPM_SMD_IPA_A_CLK] = &msm8998_ipa_a_clk, - [RPM_SMD_LN_BB_CLK1] = &msm8998_ln_bb_clk1, - [RPM_SMD_LN_BB_CLK1_A] = &msm8998_ln_bb_clk1_a, - [RPM_SMD_LN_BB_CLK2] = &msm8998_ln_bb_clk2, - [RPM_SMD_LN_BB_CLK2_A] = &msm8998_ln_bb_clk2_a, - [RPM_SMD_LN_BB_CLK3_PIN] = &msm8998_ln_bb_clk3_pin, - [RPM_SMD_LN_BB_CLK3_A_PIN] = &msm8998_ln_bb_clk3_a_pin, - [RPM_SMD_MMAXI_CLK] = &msm8998_mmssnoc_axi_rpm_clk, - [RPM_SMD_MMAXI_A_CLK] = &msm8998_mmssnoc_axi_rpm_a_clk, - [RPM_SMD_AGGR1_NOC_CLK] = &msm8998_aggre1_noc_clk, - [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8998_aggre1_noc_a_clk, - [RPM_SMD_AGGR2_NOC_CLK] = &msm8998_aggre2_noc_clk, - [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8998_aggre2_noc_a_clk, - [RPM_SMD_QDSS_CLK] = &msm8998_qdss_clk, - [RPM_SMD_QDSS_A_CLK] = &msm8998_qdss_a_clk, - [RPM_SMD_RF_CLK1] = &msm8998_rf_clk1, - [RPM_SMD_RF_CLK1_A] = &msm8998_rf_clk1_a, - [RPM_SMD_RF_CLK2_PIN] = &msm8998_rf_clk2_pin, - [RPM_SMD_RF_CLK2_A_PIN] = &msm8998_rf_clk2_a_pin, - [RPM_SMD_RF_CLK3] = &msm8998_rf_clk3, - [RPM_SMD_RF_CLK3_A] = &msm8998_rf_clk3_a, - [RPM_SMD_RF_CLK3_PIN] = &msm8998_rf_clk3_pin, - [RPM_SMD_RF_CLK3_A_PIN] = &msm8998_rf_clk3_a_pin, + +static struct clk_hw *msm8998_clks[] = { + [RPM_SMD_BIMC_CLK] = &msm8998_bimc_clk.hw, + [RPM_SMD_BIMC_A_CLK] = &msm8998_bimc_a_clk.hw, + [RPM_SMD_PCNOC_CLK] = &msm8998_pcnoc_clk.hw, + [RPM_SMD_PCNOC_A_CLK] = &msm8998_pcnoc_a_clk.hw, + [RPM_SMD_SNOC_CLK] = &msm8998_snoc_clk.hw, + [RPM_SMD_SNOC_A_CLK] = &msm8998_snoc_a_clk.hw, + [RPM_SMD_CNOC_CLK] = &msm8998_cnoc_clk.hw, + [RPM_SMD_CNOC_A_CLK] = &msm8998_cnoc_a_clk.hw, + [RPM_SMD_CE1_CLK] = &msm8998_ce1_clk.hw, + [RPM_SMD_CE1_A_CLK] = &msm8998_ce1_a_clk.hw, + [RPM_SMD_DIV_CLK1] = &msm8998_div_clk1.hw, + [RPM_SMD_DIV_A_CLK1] = &msm8998_div_clk1_a.hw, + [RPM_SMD_IPA_CLK] = &msm8998_ipa_clk.hw, + [RPM_SMD_IPA_A_CLK] = &msm8998_ipa_a_clk.hw, + [RPM_SMD_LN_BB_CLK1] = &msm8998_ln_bb_clk1.hw, + [RPM_SMD_LN_BB_CLK1_A] = &msm8998_ln_bb_clk1_a.hw, + [RPM_SMD_LN_BB_CLK2] = &msm8998_ln_bb_clk2.hw, + [RPM_SMD_LN_BB_CLK2_A] = &msm8998_ln_bb_clk2_a.hw, + [RPM_SMD_LN_BB_CLK3_PIN] = &msm8998_ln_bb_clk3_pin.hw, + [RPM_SMD_LN_BB_CLK3_A_PIN] = &msm8998_ln_bb_clk3_a_pin.hw, + [RPM_SMD_MMAXI_CLK] = &msm8998_mmssnoc_axi_rpm_clk.hw, + [RPM_SMD_MMAXI_A_CLK] = &msm8998_mmssnoc_axi_rpm_a_clk.hw, + [RPM_SMD_AGGR1_NOC_CLK] = &msm8998_aggre1_noc_clk.hw, + [RPM_SMD_AGGR1_NOC_A_CLK] = &msm8998_aggre1_noc_a_clk.hw, + [RPM_SMD_AGGR2_NOC_CLK] = &msm8998_aggre2_noc_clk.hw, + [RPM_SMD_AGGR2_NOC_A_CLK] = &msm8998_aggre2_noc_a_clk.hw, + [RPM_SMD_QDSS_CLK] = &msm8998_qdss_clk.hw, + [RPM_SMD_QDSS_A_CLK] = &msm8998_qdss_a_clk.hw, + [RPM_SMD_RF_CLK1] = &msm8998_rf_clk1.hw, + [RPM_SMD_RF_CLK1_A] = &msm8998_rf_clk1_a.hw, + [RPM_SMD_RF_CLK2_PIN] = &msm8998_rf_clk2_pin.hw, + [RPM_SMD_RF_CLK2_A_PIN] = &msm8998_rf_clk2_a_pin.hw, + [RPM_SMD_RF_CLK3] = &msm8998_rf_clk3.hw, + [RPM_SMD_RF_CLK3_A] = &msm8998_rf_clk3_a.hw, + [RPM_SMD_RF_CLK3_PIN] = &msm8998_rf_clk3_pin.hw, + [RPM_SMD_RF_CLK3_A_PIN] = &msm8998_rf_clk3_a_pin.hw, }; static const struct rpm_smd_clk_desc rpm_clk_msm8998 = { @@ -715,100 +765,196 @@ static const struct rpm_smd_clk_desc rpm_clk_msm8998 = { .num_clks = ARRAY_SIZE(msm8998_clks), }; +/* Holi */ +DEFINE_CLK_SMD_RPM_BRANCH(holi, bi_tcxo, bi_tcxo_ao, + QCOM_SMD_RPM_MISC_CLK, 0, 19200000); +DEFINE_CLK_SMD_RPM(holi, cnoc_clk, cnoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 1); +DEFINE_CLK_SMD_RPM(holi, bimc_clk, bimc_a_clk, QCOM_SMD_RPM_MEM_CLK, 0); +DEFINE_CLK_SMD_RPM(holi, snoc_clk, snoc_a_clk, QCOM_SMD_RPM_BUS_CLK, 2); +DEFINE_CLK_SMD_RPM_BRANCH(holi, qdss_clk, qdss_a_clk, + QCOM_SMD_RPM_MISC_CLK, 1, 19200000); +DEFINE_CLK_SMD_RPM(holi, ce1_clk, ce1_a_clk, QCOM_SMD_RPM_CE_CLK, 0); +DEFINE_CLK_SMD_RPM(holi, ipa_clk, ipa_a_clk, QCOM_SMD_RPM_IPA_CLK, 0); +DEFINE_CLK_SMD_RPM(holi, qup_clk, qup_a_clk, QCOM_SMD_RPM_QUP_CLK, 0); +DEFINE_CLK_SMD_RPM(holi, mmnrt_clk, mmnrt_a_clk, QCOM_SMD_RPM_MMXI_CLK, 0); +DEFINE_CLK_SMD_RPM(holi, mmrt_clk, mmrt_a_clk, QCOM_SMD_RPM_MMXI_CLK, 1); +DEFINE_CLK_SMD_RPM(holi, snoc_periph_clk, snoc_periph_a_clk, + QCOM_SMD_RPM_BUS_CLK, 0); +DEFINE_CLK_SMD_RPM(holi, snoc_lpass_clk, snoc_lpass_a_clk, + QCOM_SMD_RPM_BUS_CLK, 5); +DEFINE_CLK_SMD_RPM(holi, hwkm_clk, hwkm_a_clk, QCOM_SMD_RPM_HWKM_CLK, 0); +DEFINE_CLK_SMD_RPM(holi, pka_clk, pka_a_clk, QCOM_SMD_RPM_PKA_CLK, 0); + +/* SMD_XO_BUFFER */ +DEFINE_CLK_SMD_RPM_XO_BUFFER(holi, ln_bb_clk2, ln_bb_clk2_a, 8); +DEFINE_CLK_SMD_RPM_XO_BUFFER(holi, ln_bb_clk3, ln_bb_clk3_a, 9); +DEFINE_CLK_SMD_RPM_XO_BUFFER(holi, rf_clk5, rf_clk5_a, 6); + +/* Holi */ +static struct clk_hw *holi_clks[] = { + [RPM_SMD_XO_CLK_SRC] = &holi_bi_tcxo.hw, + [RPM_SMD_XO_A_CLK_SRC] = &holi_bi_tcxo_ao.hw, + [RPM_SMD_SNOC_CLK] = &holi_snoc_clk.hw, + [RPM_SMD_SNOC_A_CLK] = &holi_snoc_a_clk.hw, + [RPM_SMD_BIMC_CLK] = &holi_bimc_clk.hw, + [RPM_SMD_BIMC_A_CLK] = &holi_bimc_a_clk.hw, + [RPM_SMD_QDSS_CLK] = &holi_qdss_clk.hw, + [RPM_SMD_QDSS_A_CLK] = &holi_qdss_a_clk.hw, + [RPM_SMD_LN_BB_CLK2] = &holi_ln_bb_clk2.hw, + [RPM_SMD_LN_BB_CLK2_A] = &holi_ln_bb_clk2_a.hw, + [RPM_SMD_LN_BB_CLK3] = &holi_ln_bb_clk3.hw, + [RPM_SMD_LN_BB_CLK3_A] = &holi_ln_bb_clk3_a.hw, + [RPM_SMD_RF_CLK5] = &holi_rf_clk5.hw, + [RPM_SMD_RF_CLK5_A] = &holi_rf_clk5_a.hw, + [RPM_SMD_CNOC_CLK] = &holi_cnoc_clk.hw, + [RPM_SMD_CNOC_A_CLK] = &holi_cnoc_a_clk.hw, + [RPM_SMD_IPA_CLK] = &holi_ipa_clk.hw, + [RPM_SMD_IPA_A_CLK] = &holi_ipa_a_clk.hw, + [RPM_SMD_QUP_CLK] = &holi_qup_clk.hw, + [RPM_SMD_QUP_A_CLK] = &holi_qup_a_clk.hw, + [RPM_SMD_MMRT_CLK] = &holi_mmrt_clk.hw, + [RPM_SMD_MMRT_A_CLK] = &holi_mmrt_a_clk.hw, + [RPM_SMD_MMNRT_CLK] = &holi_mmnrt_clk.hw, + [RPM_SMD_MMNRT_A_CLK] = &holi_mmnrt_a_clk.hw, + [RPM_SMD_SNOC_PERIPH_CLK] = &holi_snoc_periph_clk.hw, + [RPM_SMD_SNOC_PERIPH_A_CLK] = &holi_snoc_periph_a_clk.hw, + [RPM_SMD_SNOC_LPASS_CLK] = &holi_snoc_lpass_clk.hw, + [RPM_SMD_SNOC_LPASS_A_CLK] = &holi_snoc_lpass_a_clk.hw, + [RPM_SMD_CE1_CLK] = &holi_ce1_clk.hw, + [RPM_SMD_CE1_A_CLK] = &holi_ce1_a_clk.hw, + [RPM_SMD_HWKM_CLK] = &holi_hwkm_clk.hw, + [RPM_SMD_HWKM_A_CLK] = &holi_hwkm_a_clk.hw, + [RPM_SMD_PKA_CLK] = &holi_pka_clk.hw, + [RPM_SMD_PKA_A_CLK] = &holi_pka_a_clk.hw, +}; + +static const struct rpm_smd_clk_desc rpm_clk_holi = { + .clks = holi_clks, + .num_clks = ARRAY_SIZE(holi_clks), +}; + static const struct of_device_id rpm_smd_clk_match_table[] = { { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 }, { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 }, { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 }, { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 }, { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 }, + { .compatible = "qcom,rpmcc-holi", .data = &rpm_clk_holi}, { } }; MODULE_DEVICE_TABLE(of, rpm_smd_clk_match_table); static struct clk_hw *qcom_smdrpm_clk_hw_get(struct of_phandle_args *clkspec, - void *data) + void *data) { - struct rpm_cc *rcc = data; + struct rpm_smd_clk_desc *rpmcc = data; + struct clk_smd_rpm *c; unsigned int idx = clkspec->args[0]; - if (idx >= rcc->num_clks) { + if (idx >= rpmcc->num_clks) { pr_err("%s: invalid index %u\n", __func__, idx); return ERR_PTR(-EINVAL); } - return rcc->clks[idx] ? &rcc->clks[idx]->hw : ERR_PTR(-ENOENT); + if (!rpmcc->clks[idx]) + return ERR_PTR(-ENOENT); + + c = to_clk_smd_rpm(rpmcc->clks[idx]); + if (!c->rpm_res_type) + return ERR_PTR(-ENODEV); + + return rpmcc->clks[idx]; } static int rpm_smd_clk_probe(struct platform_device *pdev) { - struct rpm_cc *rcc; - int ret; - size_t num_clks, i; - struct qcom_smd_rpm *rpm; - struct clk_smd_rpm **rpm_smd_clks; + struct clk_hw **hw_clks; const struct rpm_smd_clk_desc *desc; - - rpm = dev_get_drvdata(pdev->dev.parent); - if (!rpm) { - dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n"); - return -ENODEV; - } + int ret, i, is_holi; desc = of_device_get_match_data(&pdev->dev); if (!desc) return -EINVAL; - rpm_smd_clks = desc->clks; - num_clks = desc->num_clks; + is_holi = of_device_is_compatible(pdev->dev.of_node, + "qcom,rpmcc-holi"); + if (is_holi) { + ret = clk_vote_bimc(&holi_bimc_clk.hw, INT_MAX); + if (ret < 0) + return ret; + } - rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc), GFP_KERNEL); - if (!rcc) - return -ENOMEM; + hw_clks = desc->clks; - rcc->clks = rpm_smd_clks; - rcc->num_clks = num_clks; - - for (i = 0; i < num_clks; i++) { - if (!rpm_smd_clks[i]) + for (i = 0; i < desc->num_clks; i++) { + if (!hw_clks[i]) continue; - rpm_smd_clks[i]->rpm = rpm; - - ret = clk_smd_rpm_handoff(rpm_smd_clks[i]); + ret = clk_smd_rpm_handoff(hw_clks[i]); if (ret) goto err; } - ret = clk_smd_rpm_enable_scaling(rpm); + ret = clk_smd_rpm_enable_scaling(); if (ret) goto err; - for (i = 0; i < num_clks; i++) { - if (!rpm_smd_clks[i]) + for (i = 0; i < desc->num_clks; i++) { + const char *name; + + if (!hw_clks[i]) continue; - ret = devm_clk_hw_register(&pdev->dev, &rpm_smd_clks[i]->hw); - if (ret) - goto err; + name = hw_clks[i]->init->name; + ret = devm_clk_hw_register(&pdev->dev, hw_clks[i]); + if (ret) { + dev_err(&pdev->dev, "Failed to register %s\n", name); + return ret; + } } ret = devm_of_clk_add_hw_provider(&pdev->dev, qcom_smdrpm_clk_hw_get, - rcc); + (void *)desc); if (ret) goto err; + if (is_holi) { + /* + * Keep an active vote on CXO in case no other driver + * votes for it. + */ + clk_prepare_enable(holi_bi_tcxo_ao.hw.clk); + + /* Hold an active set vote for the cnoc_keepalive_a_clk */ + clk_set_rate(holi_cnoc_a_clk.hw.clk, 19200000); + clk_prepare_enable(holi_cnoc_a_clk.hw.clk); + + /* Hold an active set vote for the snoc_keepalive_a_clk */ + clk_set_rate(holi_snoc_a_clk.hw.clk, 19200000); + clk_prepare_enable(holi_snoc_a_clk.hw.clk); + } + + dev_info(&pdev->dev, "Registered RPM clocks\n"); + return 0; err: dev_err(&pdev->dev, "Error registering SMD clock driver (%d)\n", ret); return ret; } +static int rpm_smd_clk_remove(struct platform_device *pdev) +{ + devm_of_clk_del_provider(&pdev->dev); + return 0; +} + static struct platform_driver rpm_smd_clk_driver = { .driver = { .name = "qcom-clk-smd-rpm", .of_match_table = rpm_smd_clk_match_table, }, .probe = rpm_smd_clk_probe, + .remove = rpm_smd_clk_remove, }; static int __init rpm_smd_clk_init(void)