Commit ddeac8d9 authored by Thomas Abraham's avatar Thomas Abraham Committed by Michael Turquette

clk: samsung: add infrastructure to register cpu clocks

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: default avatarThomas Abraham <thomas.ab@samsung.com>
Signed-off-by: default avatarBartlomiej Zolnierkiewicz <b.zolnierkie@samsung.com>
Signed-off-by: default avatarMichael Turquette <mturquette@baylibre.com>
parent d8d91987
......@@ -2,7 +2,7 @@
# Samsung Clock specific Makefile
#
obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o
obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o clk-cpu.o
obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o
obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o
obj-$(CONFIG_SOC_EXYNOS4415) += clk-exynos4415.o
......
This diff is collapsed.
/*
* 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 */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment