162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Default clock type 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (C) 2005-2008, 2015 Texas Instruments, Inc. 662306a36Sopenharmony_ci * Copyright (C) 2004-2010 Nokia Corporation 762306a36Sopenharmony_ci * 862306a36Sopenharmony_ci * Contacts: 962306a36Sopenharmony_ci * Richard Woodruff <r-woodruff2@ti.com> 1062306a36Sopenharmony_ci * Paul Walmsley 1162306a36Sopenharmony_ci * Tero Kristo <t-kristo@ti.com> 1262306a36Sopenharmony_ci */ 1362306a36Sopenharmony_ci 1462306a36Sopenharmony_ci#include <linux/kernel.h> 1562306a36Sopenharmony_ci#include <linux/errno.h> 1662306a36Sopenharmony_ci#include <linux/clk-provider.h> 1762306a36Sopenharmony_ci#include <linux/io.h> 1862306a36Sopenharmony_ci#include <linux/clk/ti.h> 1962306a36Sopenharmony_ci#include <linux/delay.h> 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#include "clock.h" 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* 2462306a36Sopenharmony_ci * MAX_MODULE_ENABLE_WAIT: maximum of number of microseconds to wait 2562306a36Sopenharmony_ci * for a module to indicate that it is no longer in idle 2662306a36Sopenharmony_ci */ 2762306a36Sopenharmony_ci#define MAX_MODULE_ENABLE_WAIT 100000 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci/* 3062306a36Sopenharmony_ci * CM module register offsets, used for calculating the companion 3162306a36Sopenharmony_ci * register addresses. 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ci#define CM_FCLKEN 0x0000 3462306a36Sopenharmony_ci#define CM_ICLKEN 0x0010 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci/** 3762306a36Sopenharmony_ci * _wait_idlest_generic - wait for a module to leave the idle state 3862306a36Sopenharmony_ci * @clk: module clock to wait for (needed for register offsets) 3962306a36Sopenharmony_ci * @reg: virtual address of module IDLEST register 4062306a36Sopenharmony_ci * @mask: value to mask against to determine if the module is active 4162306a36Sopenharmony_ci * @idlest: idle state indicator (0 or 1) for the clock 4262306a36Sopenharmony_ci * @name: name of the clock (for printk) 4362306a36Sopenharmony_ci * 4462306a36Sopenharmony_ci * Wait for a module to leave idle, where its idle-status register is 4562306a36Sopenharmony_ci * not inside the CM module. Returns 1 if the module left idle 4662306a36Sopenharmony_ci * promptly, or 0 if the module did not leave idle before the timeout 4762306a36Sopenharmony_ci * elapsed. XXX Deprecated - should be moved into drivers for the 4862306a36Sopenharmony_ci * individual IP block that the IDLEST register exists in. 4962306a36Sopenharmony_ci */ 5062306a36Sopenharmony_cistatic int _wait_idlest_generic(struct clk_hw_omap *clk, 5162306a36Sopenharmony_ci struct clk_omap_reg *reg, 5262306a36Sopenharmony_ci u32 mask, u8 idlest, const char *name) 5362306a36Sopenharmony_ci{ 5462306a36Sopenharmony_ci int i = 0, ena = 0; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci ena = (idlest) ? 0 : mask; 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci /* Wait until module enters enabled state */ 5962306a36Sopenharmony_ci for (i = 0; i < MAX_MODULE_ENABLE_WAIT; i++) { 6062306a36Sopenharmony_ci if ((ti_clk_ll_ops->clk_readl(reg) & mask) == ena) 6162306a36Sopenharmony_ci break; 6262306a36Sopenharmony_ci udelay(1); 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci if (i < MAX_MODULE_ENABLE_WAIT) 6662306a36Sopenharmony_ci pr_debug("omap clock: module associated with clock %s ready after %d loops\n", 6762306a36Sopenharmony_ci name, i); 6862306a36Sopenharmony_ci else 6962306a36Sopenharmony_ci pr_err("omap clock: module associated with clock %s didn't enable in %d tries\n", 7062306a36Sopenharmony_ci name, MAX_MODULE_ENABLE_WAIT); 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci return (i < MAX_MODULE_ENABLE_WAIT) ? 1 : 0; 7362306a36Sopenharmony_ci} 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/** 7662306a36Sopenharmony_ci * _omap2_module_wait_ready - wait for an OMAP module to leave IDLE 7762306a36Sopenharmony_ci * @clk: struct clk * belonging to the module 7862306a36Sopenharmony_ci * 7962306a36Sopenharmony_ci * If the necessary clocks for the OMAP hardware IP block that 8062306a36Sopenharmony_ci * corresponds to clock @clk are enabled, then wait for the module to 8162306a36Sopenharmony_ci * indicate readiness (i.e., to leave IDLE). This code does not 8262306a36Sopenharmony_ci * belong in the clock code and will be moved in the medium term to 8362306a36Sopenharmony_ci * module-dependent code. No return value. 8462306a36Sopenharmony_ci */ 8562306a36Sopenharmony_cistatic void _omap2_module_wait_ready(struct clk_hw_omap *clk) 8662306a36Sopenharmony_ci{ 8762306a36Sopenharmony_ci struct clk_omap_reg companion_reg, idlest_reg; 8862306a36Sopenharmony_ci u8 other_bit, idlest_bit, idlest_val, idlest_reg_id; 8962306a36Sopenharmony_ci s16 prcm_mod; 9062306a36Sopenharmony_ci int r; 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci /* Not all modules have multiple clocks that their IDLEST depends on */ 9362306a36Sopenharmony_ci if (clk->ops->find_companion) { 9462306a36Sopenharmony_ci clk->ops->find_companion(clk, &companion_reg, &other_bit); 9562306a36Sopenharmony_ci if (!(ti_clk_ll_ops->clk_readl(&companion_reg) & 9662306a36Sopenharmony_ci (1 << other_bit))) 9762306a36Sopenharmony_ci return; 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci clk->ops->find_idlest(clk, &idlest_reg, &idlest_bit, &idlest_val); 10162306a36Sopenharmony_ci r = ti_clk_ll_ops->cm_split_idlest_reg(&idlest_reg, &prcm_mod, 10262306a36Sopenharmony_ci &idlest_reg_id); 10362306a36Sopenharmony_ci if (r) { 10462306a36Sopenharmony_ci /* IDLEST register not in the CM module */ 10562306a36Sopenharmony_ci _wait_idlest_generic(clk, &idlest_reg, (1 << idlest_bit), 10662306a36Sopenharmony_ci idlest_val, clk_hw_get_name(&clk->hw)); 10762306a36Sopenharmony_ci } else { 10862306a36Sopenharmony_ci ti_clk_ll_ops->cm_wait_module_ready(0, prcm_mod, idlest_reg_id, 10962306a36Sopenharmony_ci idlest_bit); 11062306a36Sopenharmony_ci } 11162306a36Sopenharmony_ci} 11262306a36Sopenharmony_ci 11362306a36Sopenharmony_ci/** 11462306a36Sopenharmony_ci * omap2_clk_dflt_find_companion - find companion clock to @clk 11562306a36Sopenharmony_ci * @clk: struct clk * to find the companion clock of 11662306a36Sopenharmony_ci * @other_reg: void __iomem ** to return the companion clock CM_*CLKEN va in 11762306a36Sopenharmony_ci * @other_bit: u8 ** to return the companion clock bit shift in 11862306a36Sopenharmony_ci * 11962306a36Sopenharmony_ci * Note: We don't need special code here for INVERT_ENABLE for the 12062306a36Sopenharmony_ci * time being since INVERT_ENABLE only applies to clocks enabled by 12162306a36Sopenharmony_ci * CM_CLKEN_PLL 12262306a36Sopenharmony_ci * 12362306a36Sopenharmony_ci * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes it's 12462306a36Sopenharmony_ci * just a matter of XORing the bits. 12562306a36Sopenharmony_ci * 12662306a36Sopenharmony_ci * Some clocks don't have companion clocks. For example, modules with 12762306a36Sopenharmony_ci * only an interface clock (such as MAILBOXES) don't have a companion 12862306a36Sopenharmony_ci * clock. Right now, this code relies on the hardware exporting a bit 12962306a36Sopenharmony_ci * in the correct companion register that indicates that the 13062306a36Sopenharmony_ci * nonexistent 'companion clock' is active. Future patches will 13162306a36Sopenharmony_ci * associate this type of code with per-module data structures to 13262306a36Sopenharmony_ci * avoid this issue, and remove the casts. No return value. 13362306a36Sopenharmony_ci */ 13462306a36Sopenharmony_civoid omap2_clk_dflt_find_companion(struct clk_hw_omap *clk, 13562306a36Sopenharmony_ci struct clk_omap_reg *other_reg, 13662306a36Sopenharmony_ci u8 *other_bit) 13762306a36Sopenharmony_ci{ 13862306a36Sopenharmony_ci memcpy(other_reg, &clk->enable_reg, sizeof(*other_reg)); 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci /* 14162306a36Sopenharmony_ci * Convert CM_ICLKEN* <-> CM_FCLKEN*. This conversion assumes 14262306a36Sopenharmony_ci * it's just a matter of XORing the bits. 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_ci other_reg->offset ^= (CM_FCLKEN ^ CM_ICLKEN); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci *other_bit = clk->enable_bit; 14762306a36Sopenharmony_ci} 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci/** 15062306a36Sopenharmony_ci * omap2_clk_dflt_find_idlest - find CM_IDLEST reg va, bit shift for @clk 15162306a36Sopenharmony_ci * @clk: struct clk * to find IDLEST info for 15262306a36Sopenharmony_ci * @idlest_reg: void __iomem ** to return the CM_IDLEST va in 15362306a36Sopenharmony_ci * @idlest_bit: u8 * to return the CM_IDLEST bit shift in 15462306a36Sopenharmony_ci * @idlest_val: u8 * to return the idle status indicator 15562306a36Sopenharmony_ci * 15662306a36Sopenharmony_ci * Return the CM_IDLEST register address and bit shift corresponding 15762306a36Sopenharmony_ci * to the module that "owns" this clock. This default code assumes 15862306a36Sopenharmony_ci * that the CM_IDLEST bit shift is the CM_*CLKEN bit shift, and that 15962306a36Sopenharmony_ci * the IDLEST register address ID corresponds to the CM_*CLKEN 16062306a36Sopenharmony_ci * register address ID (e.g., that CM_FCLKEN2 corresponds to 16162306a36Sopenharmony_ci * CM_IDLEST2). This is not true for all modules. No return value. 16262306a36Sopenharmony_ci */ 16362306a36Sopenharmony_civoid omap2_clk_dflt_find_idlest(struct clk_hw_omap *clk, 16462306a36Sopenharmony_ci struct clk_omap_reg *idlest_reg, u8 *idlest_bit, 16562306a36Sopenharmony_ci u8 *idlest_val) 16662306a36Sopenharmony_ci{ 16762306a36Sopenharmony_ci memcpy(idlest_reg, &clk->enable_reg, sizeof(*idlest_reg)); 16862306a36Sopenharmony_ci 16962306a36Sopenharmony_ci idlest_reg->offset &= ~0xf0; 17062306a36Sopenharmony_ci idlest_reg->offset |= 0x20; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci *idlest_bit = clk->enable_bit; 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /* 17562306a36Sopenharmony_ci * 24xx uses 0 to indicate not ready, and 1 to indicate ready. 17662306a36Sopenharmony_ci * 34xx reverses this, just to keep us on our toes 17762306a36Sopenharmony_ci * AM35xx uses both, depending on the module. 17862306a36Sopenharmony_ci */ 17962306a36Sopenharmony_ci *idlest_val = ti_clk_get_features()->cm_idlest_val; 18062306a36Sopenharmony_ci} 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci/** 18362306a36Sopenharmony_ci * omap2_dflt_clk_enable - enable a clock in the hardware 18462306a36Sopenharmony_ci * @hw: struct clk_hw * of the clock to enable 18562306a36Sopenharmony_ci * 18662306a36Sopenharmony_ci * Enable the clock @hw in the hardware. We first call into the OMAP 18762306a36Sopenharmony_ci * clockdomain code to "enable" the corresponding clockdomain if this 18862306a36Sopenharmony_ci * is the first enabled user of the clockdomain. Then program the 18962306a36Sopenharmony_ci * hardware to enable the clock. Then wait for the IP block that uses 19062306a36Sopenharmony_ci * this clock to leave idle (if applicable). Returns the error value 19162306a36Sopenharmony_ci * from clkdm_clk_enable() if it terminated with an error, or -EINVAL 19262306a36Sopenharmony_ci * if @hw has a null clock enable_reg, or zero upon success. 19362306a36Sopenharmony_ci */ 19462306a36Sopenharmony_ciint omap2_dflt_clk_enable(struct clk_hw *hw) 19562306a36Sopenharmony_ci{ 19662306a36Sopenharmony_ci struct clk_hw_omap *clk; 19762306a36Sopenharmony_ci u32 v; 19862306a36Sopenharmony_ci int ret = 0; 19962306a36Sopenharmony_ci bool clkdm_control; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci if (ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL) 20262306a36Sopenharmony_ci clkdm_control = false; 20362306a36Sopenharmony_ci else 20462306a36Sopenharmony_ci clkdm_control = true; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci clk = to_clk_hw_omap(hw); 20762306a36Sopenharmony_ci 20862306a36Sopenharmony_ci if (clkdm_control && clk->clkdm) { 20962306a36Sopenharmony_ci ret = ti_clk_ll_ops->clkdm_clk_enable(clk->clkdm, hw->clk); 21062306a36Sopenharmony_ci if (ret) { 21162306a36Sopenharmony_ci WARN(1, 21262306a36Sopenharmony_ci "%s: could not enable %s's clockdomain %s: %d\n", 21362306a36Sopenharmony_ci __func__, clk_hw_get_name(hw), 21462306a36Sopenharmony_ci clk->clkdm_name, ret); 21562306a36Sopenharmony_ci return ret; 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci /* FIXME should not have INVERT_ENABLE bit here */ 22062306a36Sopenharmony_ci v = ti_clk_ll_ops->clk_readl(&clk->enable_reg); 22162306a36Sopenharmony_ci if (clk->flags & INVERT_ENABLE) 22262306a36Sopenharmony_ci v &= ~(1 << clk->enable_bit); 22362306a36Sopenharmony_ci else 22462306a36Sopenharmony_ci v |= (1 << clk->enable_bit); 22562306a36Sopenharmony_ci ti_clk_ll_ops->clk_writel(v, &clk->enable_reg); 22662306a36Sopenharmony_ci v = ti_clk_ll_ops->clk_readl(&clk->enable_reg); /* OCP barrier */ 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci if (clk->ops && clk->ops->find_idlest) 22962306a36Sopenharmony_ci _omap2_module_wait_ready(clk); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci return 0; 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci/** 23562306a36Sopenharmony_ci * omap2_dflt_clk_disable - disable a clock in the hardware 23662306a36Sopenharmony_ci * @hw: struct clk_hw * of the clock to disable 23762306a36Sopenharmony_ci * 23862306a36Sopenharmony_ci * Disable the clock @hw in the hardware, and call into the OMAP 23962306a36Sopenharmony_ci * clockdomain code to "disable" the corresponding clockdomain if all 24062306a36Sopenharmony_ci * clocks/hwmods in that clockdomain are now disabled. No return 24162306a36Sopenharmony_ci * value. 24262306a36Sopenharmony_ci */ 24362306a36Sopenharmony_civoid omap2_dflt_clk_disable(struct clk_hw *hw) 24462306a36Sopenharmony_ci{ 24562306a36Sopenharmony_ci struct clk_hw_omap *clk; 24662306a36Sopenharmony_ci u32 v; 24762306a36Sopenharmony_ci 24862306a36Sopenharmony_ci clk = to_clk_hw_omap(hw); 24962306a36Sopenharmony_ci 25062306a36Sopenharmony_ci v = ti_clk_ll_ops->clk_readl(&clk->enable_reg); 25162306a36Sopenharmony_ci if (clk->flags & INVERT_ENABLE) 25262306a36Sopenharmony_ci v |= (1 << clk->enable_bit); 25362306a36Sopenharmony_ci else 25462306a36Sopenharmony_ci v &= ~(1 << clk->enable_bit); 25562306a36Sopenharmony_ci ti_clk_ll_ops->clk_writel(v, &clk->enable_reg); 25662306a36Sopenharmony_ci /* No OCP barrier needed here since it is a disable operation */ 25762306a36Sopenharmony_ci 25862306a36Sopenharmony_ci if (!(ti_clk_get_features()->flags & TI_CLK_DISABLE_CLKDM_CONTROL) && 25962306a36Sopenharmony_ci clk->clkdm) 26062306a36Sopenharmony_ci ti_clk_ll_ops->clkdm_clk_disable(clk->clkdm, hw->clk); 26162306a36Sopenharmony_ci} 26262306a36Sopenharmony_ci 26362306a36Sopenharmony_ci/** 26462306a36Sopenharmony_ci * omap2_dflt_clk_is_enabled - is clock enabled in the hardware? 26562306a36Sopenharmony_ci * @hw: struct clk_hw * to check 26662306a36Sopenharmony_ci * 26762306a36Sopenharmony_ci * Return 1 if the clock represented by @hw is enabled in the 26862306a36Sopenharmony_ci * hardware, or 0 otherwise. Intended for use in the struct 26962306a36Sopenharmony_ci * clk_ops.is_enabled function pointer. 27062306a36Sopenharmony_ci */ 27162306a36Sopenharmony_ciint omap2_dflt_clk_is_enabled(struct clk_hw *hw) 27262306a36Sopenharmony_ci{ 27362306a36Sopenharmony_ci struct clk_hw_omap *clk = to_clk_hw_omap(hw); 27462306a36Sopenharmony_ci u32 v; 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci v = ti_clk_ll_ops->clk_readl(&clk->enable_reg); 27762306a36Sopenharmony_ci 27862306a36Sopenharmony_ci if (clk->flags & INVERT_ENABLE) 27962306a36Sopenharmony_ci v ^= BIT(clk->enable_bit); 28062306a36Sopenharmony_ci 28162306a36Sopenharmony_ci v &= BIT(clk->enable_bit); 28262306a36Sopenharmony_ci 28362306a36Sopenharmony_ci return v ? 1 : 0; 28462306a36Sopenharmony_ci} 28562306a36Sopenharmony_ci 28662306a36Sopenharmony_ciconst struct clk_hw_omap_ops clkhwops_wait = { 28762306a36Sopenharmony_ci .find_idlest = omap2_clk_dflt_find_idlest, 28862306a36Sopenharmony_ci .find_companion = omap2_clk_dflt_find_companion, 28962306a36Sopenharmony_ci}; 290