/* * Notifier function for switching the muxes to safe parent * while the hfpll is getting reprogrammed.
*/ staticint krait_notifier_cb(struct notifier_block *nb, unsignedlong event, void *data)
{ int ret = 0; struct krait_mux_clk *mux = container_of(nb, struct krait_mux_clk,
clk_nb); /* Switch to safe parent */ if (event == PRE_RATE_CHANGE) {
mux->old_index = krait_mux_clk_ops.get_parent(&mux->hw);
ret = krait_mux_clk_ops.set_parent(&mux->hw, mux->safe_sel);
mux->reparent = false; /* * By the time POST_RATE_CHANGE notifier is called, * clk framework itself would have changed the parent for the new rate. * Only otherwise, put back to the old parent.
*/
} elseif (event == POST_RATE_CHANGE) { if (!mux->reparent)
ret = krait_mux_clk_ops.set_parent(&mux->hw,
mux->old_index);
}
return notifier_from_errno(ret);
}
staticint krait_notifier_register(struct device *dev, struct clk *clk, struct krait_mux_clk *mux)
{ int ret = 0;
mux->clk_nb.notifier_call = krait_notifier_cb;
ret = devm_clk_notifier_register(dev, clk, &mux->clk_nb); if (ret)
dev_err(dev, "failed to register clock notifier: %d\n", ret);
ret = devm_clk_hw_register(dev, &div->hw); if (ret) {
clk = ERR_PTR(ret); goto err_clk;
}
clk = &div->hw;
/* clk-krait ignore any rate change if mux is not flagged as enabled */ if (id < 0)
for_each_online_cpu(cpu)
clk_prepare_enable(div->hw.clk); else
clk_prepare_enable(div->hw.clk);
/* Checking for qcom,krait-cc-v1 or qcom,krait-cc-v2 is not * enough to limit this to apq/ipq8064. Directly check machine * compatible to correctly handle this errata.
*/ if (of_machine_is_compatible("qcom,ipq8064") ||
of_machine_is_compatible("qcom,apq8064"))
mux->disable_sec_src_gating = true;
init.name = kasprintf(GFP_KERNEL, "krait%s_sec_mux", s); if (!init.name) return ERR_PTR(-ENOMEM);
ret = devm_clk_hw_register(dev, &mux->hw); if (ret) {
clk = ERR_PTR(ret); goto err_clk;
}
clk = &mux->hw;
ret = krait_notifier_register(dev, mux->hw.clk, mux); if (ret) {
clk = ERR_PTR(ret); goto err_clk;
}
/* clk-krait ignore any rate change if mux is not flagged as enabled */ if (id < 0)
for_each_online_cpu(cpu)
clk_prepare_enable(mux->hw.clk); else
clk_prepare_enable(mux->hw.clk);
err_clk: if (unique_aux)
kfree(parent_name);
err_aux:
kfree(init.name); return clk;
}
/* * We don't want the CPU or L2 clocks to be turned off at late init * if CPUFREQ or HOTPLUG configs are disabled. So, bump up the * refcount of these clocks. Any cpufreq/hotplug manager can assume * that the clocks have already been prepared and enabled by the time * they take over.
*/
for_each_online_cpu(cpu) {
clk_prepare_enable(clks[l2_mux]);
WARN(clk_prepare_enable(clks[cpu]), "Unable to turn on CPU%d clock", cpu);
}
/* * Force reinit of HFPLLs and muxes to overwrite any potential * incorrect configuration of HFPLLs and muxes by the bootloader. * While at it, also make sure the cores are running at known rates * and print the current rate. * * The clocks are set to aux clock rate first to make sure the * secondary mux is not sourcing off of QSB. The rate is then set to * two different rates to force a HFPLL reinit under all * circumstances.
*/
cur_rate = clk_get_rate(clks[l2_mux]);
aux_rate = 384000000; if (cur_rate < aux_rate) {
pr_info("L2 @ Undefined rate. Forcing new rate.\n");
cur_rate = aux_rate;
}
clk_set_rate(clks[l2_mux], aux_rate);
clk_set_rate(clks[l2_mux], 2);
clk_set_rate(clks[l2_mux], cur_rate);
pr_info("L2 @ %lu KHz\n", clk_get_rate(clks[l2_mux]) / 1000);
for_each_possible_cpu(cpu) {
clk = clks[cpu];
cur_rate = clk_get_rate(clk); if (cur_rate < aux_rate) {
pr_info("CPU%d @ Undefined rate. Forcing new rate.\n", cpu);
cur_rate = aux_rate;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.