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>
144 struct qcom_smd_rpm *rpm; member
154 struct qcom_rpm *rpm; member
170 .key = cpu_to_le32(r->rpm_key), in clk_smd_rpm_handoff()
172 .value = cpu_to_le32(r->branch ? 1 : INT_MAX), in clk_smd_rpm_handoff()
175 ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE, in clk_smd_rpm_handoff()
176 r->rpm_res_type, r->rpm_clk_id, &req, in clk_smd_rpm_handoff()
180 ret = qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE, in clk_smd_rpm_handoff()
181 r->rpm_res_type, r->rpm_clk_id, &req, in clk_smd_rpm_handoff()
193 .key = cpu_to_le32(r->rpm_key), in clk_smd_rpm_set_rate_active()
198 return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_ACTIVE_STATE, in clk_smd_rpm_set_rate_active()
199 r->rpm_res_type, r->rpm_clk_id, &req, in clk_smd_rpm_set_rate_active()
207 .key = cpu_to_le32(r->rpm_key), in clk_smd_rpm_set_rate_sleep()
212 return qcom_rpm_smd_write(r->rpm, QCOM_SMD_RPM_SLEEP_STATE, in clk_smd_rpm_set_rate_sleep()
213 r->rpm_res_type, r->rpm_clk_id, &req, in clk_smd_rpm_set_rate_sleep()
223 * Active-only clocks don't care what the rate is during sleep. So, in to_active_sleep()
226 if (r->active_only) in to_active_sleep()
235 struct clk_smd_rpm *peer = r->peer; in clk_smd_rpm_prepare()
243 /* Don't send requests to the RPM if the rate has not been set. */ in clk_smd_rpm_prepare()
244 if (!r->rate) in clk_smd_rpm_prepare()
247 to_active_sleep(r, r->rate, &this_rate, &this_sleep_rate); in clk_smd_rpm_prepare()
250 if (peer->enabled) in clk_smd_rpm_prepare()
251 to_active_sleep(peer, peer->rate, in clk_smd_rpm_prepare()
256 if (r->branch) in clk_smd_rpm_prepare()
264 if (r->branch) in clk_smd_rpm_prepare()
274 r->enabled = true; in clk_smd_rpm_prepare()
284 struct clk_smd_rpm *peer = r->peer; in clk_smd_rpm_unprepare()
291 if (!r->rate) in clk_smd_rpm_unprepare()
295 if (peer->enabled) in clk_smd_rpm_unprepare()
296 to_active_sleep(peer, peer->rate, &peer_rate, in clk_smd_rpm_unprepare()
299 active_rate = r->branch ? !!peer_rate : peer_rate; in clk_smd_rpm_unprepare()
304 sleep_rate = r->branch ? !!peer_sleep_rate : peer_sleep_rate; in clk_smd_rpm_unprepare()
309 r->enabled = false; in clk_smd_rpm_unprepare()
319 struct clk_smd_rpm *peer = r->peer; in clk_smd_rpm_set_rate()
327 if (!r->enabled) in clk_smd_rpm_set_rate()
333 if (peer->enabled) in clk_smd_rpm_set_rate()
334 to_active_sleep(peer, peer->rate, in clk_smd_rpm_set_rate()
347 r->rate = rate; in clk_smd_rpm_set_rate()
359 * RPM handles rate rounding and we don't have a way to in clk_smd_rpm_round_rate()
372 * RPM handles rate rounding and we don't have a way to in clk_smd_rpm_recalc_rate()
376 return r->rate; in clk_smd_rpm_recalc_rate()
379 static int clk_smd_rpm_enable_scaling(struct qcom_smd_rpm *rpm) in clk_smd_rpm_enable_scaling() argument
388 ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_SLEEP_STATE, in clk_smd_rpm_enable_scaling()
392 pr_err("RPM clock scaling (sleep set) not enabled!\n"); in clk_smd_rpm_enable_scaling()
396 ret = qcom_rpm_smd_write(rpm, QCOM_SMD_RPM_ACTIVE_STATE, in clk_smd_rpm_enable_scaling()
400 pr_err("RPM clock scaling (active set) not enabled!\n"); in clk_smd_rpm_enable_scaling()
404 pr_debug("%s: RPM clock scaling is enabled\n", __func__); in clk_smd_rpm_enable_scaling()
1071 { .compatible = "qcom,rpmcc-mdm9607", .data = &rpm_clk_mdm9607 },
1072 { .compatible = "qcom,rpmcc-msm8226", .data = &rpm_clk_msm8974 },
1073 { .compatible = "qcom,rpmcc-msm8916", .data = &rpm_clk_msm8916 },
1074 { .compatible = "qcom,rpmcc-msm8936", .data = &rpm_clk_msm8936 },
1075 { .compatible = "qcom,rpmcc-msm8953", .data = &rpm_clk_msm8953 },
1076 { .compatible = "qcom,rpmcc-msm8974", .data = &rpm_clk_msm8974 },
1077 { .compatible = "qcom,rpmcc-msm8976", .data = &rpm_clk_msm8976 },
1078 { .compatible = "qcom,rpmcc-msm8992", .data = &rpm_clk_msm8992 },
1079 { .compatible = "qcom,rpmcc-msm8994", .data = &rpm_clk_msm8994 },
1080 { .compatible = "qcom,rpmcc-msm8996", .data = &rpm_clk_msm8996 },
1081 { .compatible = "qcom,rpmcc-msm8998", .data = &rpm_clk_msm8998 },
1082 { .compatible = "qcom,rpmcc-qcs404", .data = &rpm_clk_qcs404 },
1083 { .compatible = "qcom,rpmcc-sdm660", .data = &rpm_clk_sdm660 },
1084 { .compatible = "qcom,rpmcc-sm6115", .data = &rpm_clk_sm6115 },
1085 { .compatible = "qcom,rpmcc-sm6125", .data = &rpm_clk_sm6125 },
1094 unsigned int idx = clkspec->args[0]; in qcom_smdrpm_clk_hw_get()
1096 if (idx >= rcc->num_clks) { in qcom_smdrpm_clk_hw_get()
1098 return ERR_PTR(-EINVAL); in qcom_smdrpm_clk_hw_get()
1101 return rcc->clks[idx] ? &rcc->clks[idx]->hw : ERR_PTR(-ENOENT); in qcom_smdrpm_clk_hw_get()
1109 struct qcom_smd_rpm *rpm; in rpm_smd_clk_probe() local
1113 rpm = dev_get_drvdata(pdev->dev.parent); in rpm_smd_clk_probe()
1114 if (!rpm) { in rpm_smd_clk_probe()
1115 dev_err(&pdev->dev, "Unable to retrieve handle to RPM\n"); in rpm_smd_clk_probe()
1116 return -ENODEV; in rpm_smd_clk_probe()
1119 desc = of_device_get_match_data(&pdev->dev); in rpm_smd_clk_probe()
1121 return -EINVAL; in rpm_smd_clk_probe()
1123 rpm_smd_clks = desc->clks; in rpm_smd_clk_probe()
1124 num_clks = desc->num_clks; in rpm_smd_clk_probe()
1126 rcc = devm_kzalloc(&pdev->dev, sizeof(*rcc), GFP_KERNEL); in rpm_smd_clk_probe()
1128 return -ENOMEM; in rpm_smd_clk_probe()
1130 rcc->clks = rpm_smd_clks; in rpm_smd_clk_probe()
1131 rcc->num_clks = num_clks; in rpm_smd_clk_probe()
1137 rpm_smd_clks[i]->rpm = rpm; in rpm_smd_clk_probe()
1144 ret = clk_smd_rpm_enable_scaling(rpm); in rpm_smd_clk_probe()
1152 ret = devm_clk_hw_register(&pdev->dev, &rpm_smd_clks[i]->hw); in rpm_smd_clk_probe()
1157 ret = devm_of_clk_add_hw_provider(&pdev->dev, qcom_smdrpm_clk_hw_get, in rpm_smd_clk_probe()
1164 dev_err(&pdev->dev, "Error registering SMD clock driver (%d)\n", ret); in rpm_smd_clk_probe()
1170 .name = "qcom-clk-smd-rpm",
1188 MODULE_DESCRIPTION("Qualcomm RPM over SMD Clock Controller Driver");
1190 MODULE_ALIAS("platform:qcom-clk-smd-rpm");