// SPDX-License-Identifier: GPL-2.0-only /* * OMAP2xxx DVFS virtual clock functions * * Copyright (C) 2005-2008, 2012 Texas Instruments, Inc. * Copyright (C) 2004-2010 Nokia Corporation * * Contacts: * Richard Woodruff <r-woodruff2@ti.com> * Paul Walmsley * * Based on earlier work by Tuukka Tikkanen, Tony Lindgren, * Gordon McNutt and RidgeRun, Inc. * * XXX Some of this code should be replaceable by the upcoming OPP layer * code. However, some notion of "rate set" is probably still necessary * for OMAP2xxx at least. Rate sets should be generalized so they can be * used for any OMAP chip, not just OMAP2xxx. In particular, Richard Woodruff * has in the past expressed a preference to use rate sets for OPP changes, * rather than dynamically recalculating the clock tree, so if someone wants * this badly enough to write the code to handle it, we should support it * as an option.
*/ #undef DEBUG
/* * sys_ck_rate: the rate of the external high-frequency clock * oscillator on the board. Set by the SoC-specific clock init code. * Once set during a boot, will not change.
*/ staticunsignedlong sys_ck_rate;
/** * omap2_table_mpu_recalc - just return the MPU speed * @clk: virt_prcm_set struct clk * * Set virt_prcm_set's rate to the mpu_speed field of the current PRCM set.
*/ staticunsignedlong omap2_table_mpu_recalc(struct clk_hw *clk, unsignedlong parent_rate)
{ return curr_prcm_set->mpu_speed;
}
/* * Look for a rate equal or less than the target rate given a configuration set. * * What's not entirely clear is "which" field represents the key field. * Some might argue L3-DDR, others ARM, others IVA. This code is simple and * just uses the ARM rates.
*/ staticlong omap2_round_to_table_rate(struct clk_hw *hw, unsignedlong rate, unsignedlong *parent_rate)
{ conststruct prcm_config *ptr; long highest_rate;
highest_rate = -EINVAL;
for (ptr = rate_table; ptr->mpu_speed; ptr++) { if (!(ptr->flags & cpu_mask)) continue; if (ptr->xtal_speed != sys_ck_rate) continue;
highest_rate = ptr->mpu_speed;
/* Can check only after xtal frequency check */ if (ptr->mpu_speed <= rate) break;
} return highest_rate;
}
/** * omap2xxx_clkt_vps_check_bootloader_rates - determine which of the rate * table sets matches the current CORE DPLL hardware rate * * Check the MPU rate set by bootloader. Sets the 'curr_prcm_set' * global to point to the active rate set when found; otherwise, sets * it to NULL. No return value;
*/ staticvoid omap2xxx_clkt_vps_check_bootloader_rates(void)
{ conststruct prcm_config *prcm = NULL; unsignedlong rate;
rate = omap2xxx_clk_get_core_rate(); for (prcm = rate_table; prcm->mpu_speed; prcm++) { if (!(prcm->flags & cpu_mask)) continue; if (prcm->xtal_speed != sys_ck_rate) continue; if (prcm->dpll_speed <= rate) break;
}
curr_prcm_set = prcm;
}
/** * omap2xxx_clkt_vps_late_init - store a copy of the sys_ck rate * * Store a copy of the sys_ck rate for later use by the OMAP2xxx DVFS * code. (The sys_ck rate does not -- or rather, must not -- change * during kernel runtime.) Must be called after we have a valid * sys_ck rate, but before the virt_prcm_set clock rate is * recalculated. No return value.
*/ staticvoid omap2xxx_clkt_vps_late_init(void)
{ struct clk *c;
c = clk_get(NULL, "sys_ck"); if (IS_ERR(c)) {
WARN(1, "could not locate sys_ck\n");
} else {
sys_ck_rate = clk_get_rate(c);
clk_put(c);
}
}
/** * omap2xxx_clkt_vps_init - initialize virt_prcm_set clock * * Does a manual init for the virtual prcm DVFS clock for OMAP2. This * function is called only from omap2 DT clock init, as the virtual * node is not modelled in the DT clock data.
*/ void omap2xxx_clkt_vps_init(void)
{ struct clk_init_data init = { NULL }; struct clk_hw_omap *hw = NULL; struct clk *clk; constchar *parent_name = "mpu_ck";
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.