/*1* linux/arch/arm/mach-omap2/clock.c2*3* Copyright (C) 2005-2008 Texas Instruments, Inc.4* Copyright (C) 2004-2010 Nokia Corporation5*6* Contacts:7* Richard Woodruff <[email protected]>8* Paul Walmsley9*10* This program is free software; you can redistribute it and/or modify11* it under the terms of the GNU General Public License version 2 as12* published by the Free Software Foundation.13*/14#undef DEBUG1516#include <linux/kernel.h>17#include <linux/list.h>18#include <linux/errno.h>19#include <linux/err.h>20#include <linux/delay.h>21#include <linux/clk.h>22#include <linux/io.h>23#include <linux/bitops.h>24#include <trace/events/power.h>2526#include <asm/cpu.h>27#include <plat/clock.h>28#include "clockdomain.h"29#include <plat/cpu.h>30#include <plat/prcm.h>3132#include "clock.h"33#include "cm2xxx_3xxx.h"34#include "cm-regbits-24xx.h"35#include "cm-regbits-34xx.h"3637u8 cpu_mask;3839/*40* OMAP2+ specific clock functions41*/4243/* Private functions */4445/**46* _omap2_module_wait_ready - wait for an OMAP module to leave IDLE47* @clk: struct clk * belonging to the module48*49* If the necessary clocks for the OMAP hardware IP block that50* corresponds to clock @clk are enabled, then wait for the module to51* indicate readiness (i.e., to leave IDLE). This code does not52* belong in the clock code and will be moved in the medium term to53* module-dependent code. No return value.54*/55static void _omap2_module_wait_ready(struct clk *clk)56{57void __iomem *companion_reg, *idlest_reg;58u8 other_bit, idlest_bit, idlest_val;5960/* Not all modules have multiple clocks that their IDLEST depends on */61if (clk->ops->find_companion) {62clk->ops->find_companion(clk, &companion_reg, &other_bit);63if (!(__raw_readl(companion_reg) & (1 << other_bit)))64return;65}6667clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val);6869omap2_cm_wait_idlest(idlest_reg, (1 << idlest_bit), idlest_val,70clk->name);71}7273/* Public functions */7475/**76* omap2_init_clk_clkdm - look up a clockdomain name, store pointer in clk77* @clk: OMAP clock struct ptr to use78*79* Convert a clockdomain name stored in a struct clk 'clk' into a80* clockdomain pointer, and save it into the struct clk. Intended to be81* called during clk_register(). No return value.82*/83void omap2_init_clk_clkdm(struct clk *clk)84{85struct clockdomain *clkdm;8687if (!clk->clkdm_name)88return;8990clkdm = clkdm_lookup(clk->clkdm_name);91if (clkdm) {92pr_debug("clock: associated clk %s to clkdm %s\n",93clk->name, clk->clkdm_name);94clk->clkdm = clkdm;95} else {96pr_debug("clock: could not associate clk %s to "97"clkdm %s\n", clk->name, clk->clkdm_name);98}99}100101/**102* omap2_clk_dflt_find_companion - find companion clock to @clk103* @clk: struct clk * to find the companion clock of104* @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in105* @other_bit: u8 ** to return the companion clock bit shift in106*107* Note: We don't need special code here for INVERT_ENABLE for the108* time being since INVERT_ENABLE only applies to clocks enabled by109* CM_CLKEN_PLL110*111* Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's112* just a matter of XORing the bits.113*114* Some clocks don't have companion clocks. For example, modules with115* only an interface clock (such as MAILBOXES) don't have a companion116* clock. Right now, this code relies on the hardware exporting a bit117* in the correct companion register that indicates that the118* nonexistent 'companion clock' is active. Future patches will119* associate this type of code with per-module data structures to120* avoid this issue, and remove the casts. No return value.121*/122void omap2_clk_dflt_find_companion(struct clk *clk, void __iomem **other_reg,123u8 *other_bit)124{125u32 r;126127/*128* Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes129* it's just a matter of XORing the bits.130*/131r = ((__force u32)clk->enable_reg ^ (CM_FCLKEN ^ CM_ICLKEN));132133*other_reg = (__force void __iomem *)r;134*other_bit = clk->enable_bit;135}136137/**138* omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk139* @clk: struct clk * to find IDLEST info for140* @idlest_reg: void __iomem ** to return the CM_IDLEST va in141* @idlest_bit: u8 * to return the CM_IDLEST bit shift in142* @idlest_val: u8 * to return the idle status indicator143*144* Return the CM_IDLEST register address and bit shift corresponding145* to the module that "owns" this clock. This default code assumes146* that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that147* the IDLEST register address ID corresponds to the CM_*CLKEN148* register address ID (e.g., that CM_FCLKEN2 corresponds to149* CM_IDLEST2). This is not true for all modules. No return value.150*/151void omap2_clk_dflt_find_idlest(struct clk *clk, void __iomem **idlest_reg,152u8 *idlest_bit, u8 *idlest_val)153{154u32 r;155156r = (((__force u32)clk->enable_reg & ~0xf0) | 0x20);157*idlest_reg = (__force void __iomem *)r;158*idlest_bit = clk->enable_bit;159160/*161* 24xx uses 0 to indicate not ready, and 1 to indicate ready.162* 34xx reverses this, just to keep us on our toes163* AM35xx uses both, depending on the module.164*/165if (cpu_is_omap24xx())166*idlest_val = OMAP24XX_CM_IDLEST_VAL;167else if (cpu_is_omap34xx())168*idlest_val = OMAP34XX_CM_IDLEST_VAL;169else170BUG();171172}173174int omap2_dflt_clk_enable(struct clk *clk)175{176u32 v;177178if (unlikely(clk->enable_reg == NULL)) {179pr_err("clock.c: Enable for %s without enable code\n",180clk->name);181return 0; /* REVISIT: -EINVAL */182}183184v = __raw_readl(clk->enable_reg);185if (clk->flags & INVERT_ENABLE)186v &= ~(1 << clk->enable_bit);187else188v |= (1 << clk->enable_bit);189__raw_writel(v, clk->enable_reg);190v = __raw_readl(clk->enable_reg); /* OCP barrier */191192if (clk->ops->find_idlest)193_omap2_module_wait_ready(clk);194195return 0;196}197198void omap2_dflt_clk_disable(struct clk *clk)199{200u32 v;201202if (!clk->enable_reg) {203/*204* 'Independent' here refers to a clock which is not205* controlled by its parent.206*/207printk(KERN_ERR "clock: clk_disable called on independent "208"clock %s which has no enable_reg\n", clk->name);209return;210}211212v = __raw_readl(clk->enable_reg);213if (clk->flags & INVERT_ENABLE)214v |= (1 << clk->enable_bit);215else216v &= ~(1 << clk->enable_bit);217__raw_writel(v, clk->enable_reg);218/* No OCP barrier needed here since it is a disable operation */219}220221const struct clkops clkops_omap2_dflt_wait = {222.enable = omap2_dflt_clk_enable,223.disable = omap2_dflt_clk_disable,224.find_companion = omap2_clk_dflt_find_companion,225.find_idlest = omap2_clk_dflt_find_idlest,226};227228const struct clkops clkops_omap2_dflt = {229.enable = omap2_dflt_clk_enable,230.disable = omap2_dflt_clk_disable,231};232233/**234* omap2_clk_disable - disable a clock, if the system is not using it235* @clk: struct clk * to disable236*237* Decrements the usecount on struct clk @clk. If there are no users238* left, call the clkops-specific clock disable function to disable it239* in hardware. If the clock is part of a clockdomain (which they all240* should be), request that the clockdomain be disabled. (It too has241* a usecount, and so will not be disabled in the hardware until it no242* longer has any users.) If the clock has a parent clock (most of243* them do), then call ourselves, recursing on the parent clock. This244* can cause an entire branch of the clock tree to be powered off by245* simply disabling one clock. Intended to be called with the clockfw_lock246* spinlock held. No return value.247*/248void omap2_clk_disable(struct clk *clk)249{250if (clk->usecount == 0) {251WARN(1, "clock: %s: omap2_clk_disable() called, but usecount "252"already 0?", clk->name);253return;254}255256pr_debug("clock: %s: decrementing usecount\n", clk->name);257258clk->usecount--;259260if (clk->usecount > 0)261return;262263pr_debug("clock: %s: disabling in hardware\n", clk->name);264265if (clk->ops && clk->ops->disable) {266trace_clock_disable(clk->name, 0, smp_processor_id());267clk->ops->disable(clk);268}269270if (clk->clkdm)271clkdm_clk_disable(clk->clkdm, clk);272273if (clk->parent)274omap2_clk_disable(clk->parent);275}276277/**278* omap2_clk_enable - request that the system enable a clock279* @clk: struct clk * to enable280*281* Increments the usecount on struct clk @clk. If there were no users282* previously, then recurse up the clock tree, enabling all of the283* clock's parents and all of the parent clockdomains, and finally,284* enabling @clk's clockdomain, and @clk itself. Intended to be285* called with the clockfw_lock spinlock held. Returns 0 upon success286* or a negative error code upon failure.287*/288int omap2_clk_enable(struct clk *clk)289{290int ret;291292pr_debug("clock: %s: incrementing usecount\n", clk->name);293294clk->usecount++;295296if (clk->usecount > 1)297return 0;298299pr_debug("clock: %s: enabling in hardware\n", clk->name);300301if (clk->parent) {302ret = omap2_clk_enable(clk->parent);303if (ret) {304WARN(1, "clock: %s: could not enable parent %s: %d\n",305clk->name, clk->parent->name, ret);306goto oce_err1;307}308}309310if (clk->clkdm) {311ret = clkdm_clk_enable(clk->clkdm, clk);312if (ret) {313WARN(1, "clock: %s: could not enable clockdomain %s: "314"%d\n", clk->name, clk->clkdm->name, ret);315goto oce_err2;316}317}318319if (clk->ops && clk->ops->enable) {320trace_clock_enable(clk->name, 1, smp_processor_id());321ret = clk->ops->enable(clk);322if (ret) {323WARN(1, "clock: %s: could not enable: %d\n",324clk->name, ret);325goto oce_err3;326}327}328329return 0;330331oce_err3:332if (clk->clkdm)333clkdm_clk_disable(clk->clkdm, clk);334oce_err2:335if (clk->parent)336omap2_clk_disable(clk->parent);337oce_err1:338clk->usecount--;339340return ret;341}342343/* Given a clock and a rate apply a clock specific rounding function */344long omap2_clk_round_rate(struct clk *clk, unsigned long rate)345{346if (clk->round_rate)347return clk->round_rate(clk, rate);348349return clk->rate;350}351352/* Set the clock rate for a clock source */353int omap2_clk_set_rate(struct clk *clk, unsigned long rate)354{355int ret = -EINVAL;356357pr_debug("clock: set_rate for clock %s to rate %ld\n", clk->name, rate);358359/* dpll_ck, core_ck, virt_prcm_set; plus all clksel clocks */360if (clk->set_rate) {361trace_clock_set_rate(clk->name, rate, smp_processor_id());362ret = clk->set_rate(clk, rate);363}364365return ret;366}367368int omap2_clk_set_parent(struct clk *clk, struct clk *new_parent)369{370if (!clk->clksel)371return -EINVAL;372373if (clk->parent == new_parent)374return 0;375376return omap2_clksel_set_parent(clk, new_parent);377}378379/* OMAP3/4 non-CORE DPLL clkops */380381#if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4)382383const struct clkops clkops_omap3_noncore_dpll_ops = {384.enable = omap3_noncore_dpll_enable,385.disable = omap3_noncore_dpll_disable,386.allow_idle = omap3_dpll_allow_idle,387.deny_idle = omap3_dpll_deny_idle,388};389390const struct clkops clkops_omap3_core_dpll_ops = {391.allow_idle = omap3_dpll_allow_idle,392.deny_idle = omap3_dpll_deny_idle,393};394395#endif396397/*398* OMAP2+ clock reset and init functions399*/400401#ifdef CONFIG_OMAP_RESET_CLOCKS402void omap2_clk_disable_unused(struct clk *clk)403{404u32 regval32, v;405406v = (clk->flags & INVERT_ENABLE) ? (1 << clk->enable_bit) : 0;407408regval32 = __raw_readl(clk->enable_reg);409if ((regval32 & (1 << clk->enable_bit)) == v)410return;411412pr_debug("Disabling unused clock \"%s\"\n", clk->name);413if (cpu_is_omap34xx()) {414omap2_clk_enable(clk);415omap2_clk_disable(clk);416} else {417clk->ops->disable(clk);418}419if (clk->clkdm != NULL)420pwrdm_clkdm_state_switch(clk->clkdm);421}422#endif423424/**425* omap2_clk_switch_mpurate_at_boot - switch ARM MPU rate by boot-time argument426* @mpurate_ck_name: clk name of the clock to change rate427*428* Change the ARM MPU clock rate to the rate specified on the command429* line, if one was specified. @mpurate_ck_name should be430* "virt_prcm_set" on OMAP2xxx and "dpll1_ck" on OMAP34xx/OMAP36xx.431* XXX Does not handle voltage scaling - on OMAP2xxx this is currently432* handled by the virt_prcm_set clock, but this should be handled by433* the OPP layer. XXX This is intended to be handled by the OPP layer434* code in the near future and should be removed from the clock code.435* Returns -EINVAL if 'mpurate' is zero or if clk_set_rate() rejects436* the rate, -ENOENT if the struct clk referred to by @mpurate_ck_name437* cannot be found, or 0 upon success.438*/439int __init omap2_clk_switch_mpurate_at_boot(const char *mpurate_ck_name)440{441struct clk *mpurate_ck;442int r;443444if (!mpurate)445return -EINVAL;446447mpurate_ck = clk_get(NULL, mpurate_ck_name);448if (WARN(IS_ERR(mpurate_ck), "Failed to get %s.\n", mpurate_ck_name))449return -ENOENT;450451r = clk_set_rate(mpurate_ck, mpurate);452if (IS_ERR_VALUE(r)) {453WARN(1, "clock: %s: unable to set MPU rate to %d: %d\n",454mpurate_ck->name, mpurate, r);455return -EINVAL;456}457458calibrate_delay();459recalculate_root_clocks();460461clk_put(mpurate_ck);462463return 0;464}465466/**467* omap2_clk_print_new_rates - print summary of current clock tree rates468* @hfclkin_ck_name: clk name for the off-chip HF oscillator469* @core_ck_name: clk name for the on-chip CORE_CLK470* @mpu_ck_name: clk name for the ARM MPU clock471*472* Prints a short message to the console with the HFCLKIN oscillator473* rate, the rate of the CORE clock, and the rate of the ARM MPU clock.474* Called by the boot-time MPU rate switching code. XXX This is intended475* to be handled by the OPP layer code in the near future and should be476* removed from the clock code. No return value.477*/478void __init omap2_clk_print_new_rates(const char *hfclkin_ck_name,479const char *core_ck_name,480const char *mpu_ck_name)481{482struct clk *hfclkin_ck, *core_ck, *mpu_ck;483unsigned long hfclkin_rate;484485mpu_ck = clk_get(NULL, mpu_ck_name);486if (WARN(IS_ERR(mpu_ck), "clock: failed to get %s.\n", mpu_ck_name))487return;488489core_ck = clk_get(NULL, core_ck_name);490if (WARN(IS_ERR(core_ck), "clock: failed to get %s.\n", core_ck_name))491return;492493hfclkin_ck = clk_get(NULL, hfclkin_ck_name);494if (WARN(IS_ERR(hfclkin_ck), "Failed to get %s.\n", hfclkin_ck_name))495return;496497hfclkin_rate = clk_get_rate(hfclkin_ck);498499pr_info("Switched to new clocking rate (Crystal/Core/MPU): "500"%ld.%01ld/%ld/%ld MHz\n",501(hfclkin_rate / 1000000),502((hfclkin_rate / 100000) % 10),503(clk_get_rate(core_ck) / 1000000),504(clk_get_rate(mpu_ck) / 1000000));505}506507/* Common data */508509struct clk_functions omap2_clk_functions = {510.clk_enable = omap2_clk_enable,511.clk_disable = omap2_clk_disable,512.clk_round_rate = omap2_clk_round_rate,513.clk_set_rate = omap2_clk_set_rate,514.clk_set_parent = omap2_clk_set_parent,515.clk_disable_unused = omap2_clk_disable_unused,516#ifdef CONFIG_CPU_FREQ517/* These will be removed when the OPP code is integrated */518.clk_init_cpufreq_table = omap2_clk_init_cpufreq_table,519.clk_exit_cpufreq_table = omap2_clk_exit_cpufreq_table,520#endif521};522523524525