mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git
synced 2024-09-05 18:39:59 +00:00
![Thomas Abraham](/assets/img/avatar_default.png)
The CPU clock provider supplies the clock to the CPU clock domain. The composition and organization of the CPU clock provider could vary among Exynos SoCs. A CPU clock provider can be composed of clock mux, dividers and gates. This patch defines a new clock type for CPU clock provider and adds infrastructure to register the CPU clock providers for Samsung platforms. Changes by Bartlomiej: - fixed issue with setting lower dividers before the parent clock speed was lowered (the issue resulted in lockup on Exynos4210 SoC based Origen board when "ondemand" cpufreq governor was stress tested) - fixed missing spin_unlock on error in exynos_cpuclk_post_rate_change() problem by moving cfg_data search outside of the spin locked area - removed leftover kfree() in exynos_register_cpu_clock() that could result in dereferencing the NULL pointer on error - moved spin_lock earlier in exynos_cpuclk_pre_rate_change() to cover reading of E4210_SRC_CPU and E4210_DIV_CPU1 registers - added missing "last chance" checks to wait_until_divider_stable() and wait_until_mux_stable() (needed in case that IRQ handling took long time to proceed and resulted in function printing incorrect error message about timeout) - moved E4210_CPU_DIV[0,1]() macros just before their only users, this resulted in moving them from patch #2 to patch #3/6 ("clk: samsung: exynos4: add cpu clock configuration data and instantiate cpu clock") - removed E5250_CPU_DIV[0,1](), E5420_EGL_DIV0() and E5420_KFC_DIV() macros for now - added my Copyrights to drivers/clk/samsung/clk-cpu.c Cc: Tomasz Figa <tomasz.figa@gmail.com> Cc: Mike Turquette <mturquette@linaro.org> Cc: Javier Martinez Canillas <javier.martinez@collabora.co.uk> Signed-off-by: Thomas Abraham <thomas.ab@samsung.com> Signed-off-by: Bartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com> Signed-off-by: Michael Turquette <mturquette@baylibre.com>
73 lines
2.5 KiB
C
73 lines
2.5 KiB
C
/*
|
|
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License version 2 as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* Common Clock Framework support for all PLL's in Samsung platforms
|
|
*/
|
|
|
|
#ifndef __SAMSUNG_CLK_CPU_H
|
|
#define __SAMSUNG_CLK_CPU_H
|
|
|
|
#include "clk.h"
|
|
|
|
/**
|
|
* struct exynos_cpuclk_data: config data to setup cpu clocks.
|
|
* @prate: frequency of the primary parent clock (in KHz).
|
|
* @div0: value to be programmed in the div_cpu0 register.
|
|
* @div1: value to be programmed in the div_cpu1 register.
|
|
*
|
|
* This structure holds the divider configuration data for dividers in the CPU
|
|
* clock domain. The parent frequency at which these divider values are valid is
|
|
* specified in @prate. The @prate is the frequency of the primary parent clock.
|
|
* For CPU clock domains that do not have a DIV1 register, the @div1 member
|
|
* value is not used.
|
|
*/
|
|
struct exynos_cpuclk_cfg_data {
|
|
unsigned long prate;
|
|
unsigned long div0;
|
|
unsigned long div1;
|
|
};
|
|
|
|
/**
|
|
* struct exynos_cpuclk: information about clock supplied to a CPU core.
|
|
* @hw: handle between CCF and CPU clock.
|
|
* @alt_parent: alternate parent clock to use when switching the speed
|
|
* of the primary parent clock.
|
|
* @ctrl_base: base address of the clock controller.
|
|
* @lock: cpu clock domain register access lock.
|
|
* @cfg: cpu clock rate configuration data.
|
|
* @num_cfgs: number of array elements in @cfg array.
|
|
* @clk_nb: clock notifier registered for changes in clock speed of the
|
|
* primary parent clock.
|
|
* @flags: configuration flags for the CPU clock.
|
|
*
|
|
* This structure holds information required for programming the CPU clock for
|
|
* various clock speeds.
|
|
*/
|
|
struct exynos_cpuclk {
|
|
struct clk_hw hw;
|
|
struct clk *alt_parent;
|
|
void __iomem *ctrl_base;
|
|
spinlock_t *lock;
|
|
const struct exynos_cpuclk_cfg_data *cfg;
|
|
const unsigned long num_cfgs;
|
|
struct notifier_block clk_nb;
|
|
unsigned long flags;
|
|
|
|
/* The CPU clock registers has DIV1 configuration register */
|
|
#define CLK_CPU_HAS_DIV1 (1 << 0)
|
|
/* When ALT parent is active, debug clocks need safe divider values */
|
|
#define CLK_CPU_NEEDS_DEBUG_ALT_DIV (1 << 1)
|
|
};
|
|
|
|
extern int __init exynos_register_cpu_clock(struct samsung_clk_provider *ctx,
|
|
unsigned int lookup_id, const char *name,
|
|
const char *parent, const char *alt_parent,
|
|
unsigned long offset,
|
|
const struct exynos_cpuclk_cfg_data *cfg,
|
|
unsigned long num_cfgs, unsigned long flags);
|
|
|
|
#endif /* __SAMSUNG_CLK_CPU_H */
|