Lines Matching +full:smd +full:- +full:rpm

1 // SPDX-License-Identifier: GPL-2.0-only
7 #include <linux/clk-provider.h>
17 #include <linux/soc/qcom/smd-rpm.h>
19 #include <dt-bindings/clock/qcom,rpmcc.h>
20 #include <dt-bindings/mfd/qcom-rpm.h>
132 struct qcom_smd_rpm *rpm; member
142 struct qcom_rpm *rpm; member
158 .key = cpu_to_le32(r->rpm_key), in clk_smd_rpm_handoff()
160 .value = cpu_to_le32(r->branch ? 1 : INT_MAX), in clk_smd_rpm_handoff()
163 ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE, in clk_smd_rpm_handoff()
164 r->rpm_res_type, r->rpm_clk_id, &req, in clk_smd_rpm_handoff()
168 ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE, in clk_smd_rpm_handoff()
169 r->rpm_res_type, r->rpm_clk_id, &req, in clk_smd_rpm_handoff()
181 .key = cpu_to_le32(r->rpm_key), in clk_smd_rpm_set_rate_active()
186 return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE, in clk_smd_rpm_set_rate_active()
187 r->rpm_res_type, r->rpm_clk_id, &req, in clk_smd_rpm_set_rate_active()
195 .key = cpu_to_le32(r->rpm_key), in clk_smd_rpm_set_rate_sleep()
200 return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE, in clk_smd_rpm_set_rate_sleep()
201 r->rpm_res_type, r->rpm_clk_id, &req, in clk_smd_rpm_set_rate_sleep()
211 * Active-only clocks don't care what the rate is during sleep. So, in to_active_sleep()
214 if (r->active_only) in to_active_sleep()
223 struct clk_smd_rpm *peer = r->peer; in clk_smd_rpm_prepare()
231 /* Don't send requests to the RPM if the rate has not been set. */ in clk_smd_rpm_prepare()
232 if (!r->rate) in clk_smd_rpm_prepare()
235 to_active_sleep(r, r->rate, &this_rate, &this_sleep_rate); in clk_smd_rpm_prepare()
238 if (peer->enabled) in clk_smd_rpm_prepare()
239 to_active_sleep(peer, peer->rate, in clk_smd_rpm_prepare()
244 if (r->branch) in clk_smd_rpm_prepare()
252 if (r->branch) in clk_smd_rpm_prepare()
262 r->enabled = true; in clk_smd_rpm_prepare()
272 struct clk_smd_rpm *peer = r->peer; in clk_smd_rpm_unprepare()
279 if (!r->rate) in clk_smd_rpm_unprepare()
283 if (peer->enabled) in clk_smd_rpm_unprepare()
284 to_active_sleep(peer, peer->rate, &peer_rate, in clk_smd_rpm_unprepare()
287 active_rate = r->branch ? !!peer_rate : peer_rate; in clk_smd_rpm_unprepare()
292 sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate; in clk_smd_rpm_unprepare()
297 r->enabled = false; in clk_smd_rpm_unprepare()
307 struct clk_smd_rpm *peer = r->peer; in clk_smd_rpm_set_rate()
315 if (!r->enabled) in clk_smd_rpm_set_rate()
321 if (peer->enabled) in clk_smd_rpm_set_rate()
322 to_active_sleep(peer, peer->rate, in clk_smd_rpm_set_rate()
335 r->rate = rate; in clk_smd_rpm_set_rate()
347 * RPM handles rate rounding and we don't have a way to in clk_smd_rpm_round_rate()
360 * RPM handles rate rounding and we don't have a way to in clk_smd_rpm_recalc_rate()
364 return r->rate; in clk_smd_rpm_recalc_rate()
367 static int clk_smd_rpm_enable_scaling(struct qcom_smd_rpm *rpm) in clk_smd_rpm_enable_scaling() argument
376 ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_SLEEP_STATE, in clk_smd_rpm_enable_scaling()
380 pr_err("RPM clock scaling (sleep set) not enabled!\n"); in clk_smd_rpm_enable_scaling()
384 ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_ACTIVE_STATE, in clk_smd_rpm_enable_scaling()
388 pr_err("RPM clock scaling (active set) not enabled!\n"); in clk_smd_rpm_enable_scaling()
392 pr_debug("%s: RPM clock scaling is enabled\n", __func__); in clk_smd_rpm_enable_scaling()
1063 { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
1064 { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 },
1065 { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
1066 { .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 },
1067 { .compatible = "qcom,rpmcc-msm8992", .data = &rpm_clk_msm8992 },
1068 { .compatible = "qcom,rpmcc-msm8994", .data = &rpm_clk_msm8994 },
1069 { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 },
1070 { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 },
1071 { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 },
1072 { .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 },
1081 unsigned int idx = clkspec->args[0]; in qcom_smdrpm_clk_hw_get()
1083 if (idx >= rcc->num_clks) { in qcom_smdrpm_clk_hw_get()
1085 return ERR_PTR(-EINVAL); in qcom_smdrpm_clk_hw_get()
1088 return rcc->clks[idx] ? &rcc->clks[idx]->hw : ERR_PTR(-ENOENT); in qcom_smdrpm_clk_hw_get()
1096 struct qcom_smd_rpm *rpm; in rpm_smd_clk_probe() local
1100 rpm = dev_get_drvdata(pdev->dev.parent); in rpm_smd_clk_probe()
1101 if (!rpm) { in rpm_smd_clk_probe()
1102 dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n"); in rpm_smd_clk_probe()
1103 return -ENODEV; in rpm_smd_clk_probe()
1106 desc = of_device_get_match_data(&pdev->dev); in rpm_smd_clk_probe()
1108 return -EINVAL; in rpm_smd_clk_probe()
1110 rpm_smd_clks = desc->clks; in rpm_smd_clk_probe()
1111 num_clks = desc->num_clks; in rpm_smd_clk_probe()
1113 rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc), GFP_KERNEL); in rpm_smd_clk_probe()
1115 return -ENOMEM; in rpm_smd_clk_probe()
1117 rcc->clks = rpm_smd_clks; in rpm_smd_clk_probe()
1118 rcc->num_clks = num_clks; in rpm_smd_clk_probe()
1124 rpm_smd_clks[i]->rpm = rpm; in rpm_smd_clk_probe()
1131 ret = clk_smd_rpm_enable_scaling(rpm); in rpm_smd_clk_probe()
1139 ret = devm_clk_hw_register(&pdev->dev, &rpm_smd_clks[i]->hw); in rpm_smd_clk_probe()
1144 ret = devm_of_clk_add_hw_provider(&pdev->dev, qcom_smdrpm_clk_hw_get, in rpm_smd_clk_probe()
1151 dev_err(&pdev->dev, "Error registering SMD clock driver (%d)\n", ret); in rpm_smd_clk_probe()
1157 .name = "qcom-clk-smd-rpm",
1175 MODULE_DESCRIPTION("Qualcomm RPM over SMD Clock Controller Driver");
1177 MODULE_ALIAS("platform:qcom-clk-smd-rpm");