Commit 15afa044 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge branches 'clk-ti', 'clk-amlogic', 'clk-tegra' and 'clk-samsung' into clk-next

* clk-ti:
  clk: keystone: sci-clk: add support for dynamically probing clocks
  clk: ti: add support for clock latching to mux clocks
  clk: ti: add support for clock latching to divider clocks
  clk: ti: add generic support for clock latching
  clk: ti: add support for register read-modify-write low-level operation
  dt-bindings: clock: ti: add latching support to mux and divider clocks

* clk-amlogic: (50 commits)
  clk: meson: Drop unused local variable and add static
  clk: meson: clean-up clk81 clocks
  clk: meson: add fdiv clock gates
  clk: meson: add mpll pre-divider
  clk: meson: axg: add hifi pll clock
  clk: meson: axg: add hifi clock bindings
  clk: meson: add ROUND_CLOSEST to the pll driver
  clk: meson: add gp0 frac parameter for axg and gxl
  clk: meson: improve pll driver results with frac
  clk: meson: remove special gp0 lock loop
  clk: meson: poke pll CNTL last
  clk: meson: add fractional part of meson8b fixed_pll
  clk: meson: use hhi syscon if available
  clk: meson: remove obsolete cpu_clk
  clk: meson: rework meson8b cpu clock
  clk: meson: split divider and gate part of mpll
  clk: meson: migrate plls clocks to clk_regmap
  clk: meson: migrate the audio divider clock to clk_regmap
  clk: meson: migrate mplls clocks to clk_regmap
  clk: meson: add regmap helpers for parm
  ...

* clk-tegra:
  clk: tegra: Fix pll_u rate configuration
  clk: tegra: Specify VDE clock rate
  clk: tegra20: Correct PLL_C_OUT1 setup
  clk: tegra: Mark HCLK, SCLK and EMC as critical
  clk: tegra: MBIST work around for Tegra210
  clk: tegra: add fence_delay for clock registers
  clk: tegra: Add la clock for Tegra210

* clk-samsung: (22 commits)
  clk: samsung: Mark a few things static
  clk: samsung: Add fout=196608001 Hz EPLL rate entry for exynos4412
  clk: samsung: exynos5250: Add missing clocks for FIMC LITE SYSMMU devices
  clk: samsung: exynos5420: Add more entries to EPLL rate table
  clk: samsung: exynos5420: Add CLK_SET_RATE_PARENT flag to mout_mau_epll_clk
  clk: samsung: exynos5250: Move PD-dependent clocks to Exynos5 sub-CMU
  clk: samsung: exynos5420: Move PD-dependent clocks to Exynos5 sub-CMU
  clk: samsung: Add Exynos5 sub-CMU clock driver
  soc: samsung: pm_domains: Add blacklisting clock handling
  clk: samsung: Add compile time PLL rate validators
  clk: samsung: s3c2410: Fix PLL rates
  clk: samsung: exynos7: Fix PLL rates
  clk: samsung: exynos5433: Fix PLL rates
  clk: samsung: exynos5260: Fix PLL rates
  clk: samsung: exynos5250: Fix PLL rates
  clk: samsung: exynos3250: Fix PLL rates
  clk: exynos5433: Extend list of available AUD_PLL output frequencies
  clk: exynos5433: Add CLK_IGNORE_UNUSED flag to sclk_ioclk_i2s1_bclk
  clk: samsung: Add a git tree entry to MAINTAINERS
  clk: samsung: Remove redundant dev_err call in exynos_audss_clk_probe()
  ...
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -12189,6 +12189,7 @@ M: Tomasz Figa <tomasz.figa@gmail.com>
M:	Chanwoo Choi <cw00.choi@samsung.com>
S:	Supported
L:	linux-samsung-soc@vger.kernel.org (moderated for non-subscribers)
T:	git git://git.kernel.org/pub/scm/linux/kernel/git/snawrocki/clk.git
F:	drivers/clk/samsung/
F:	include/dt-bindings/clock/exynos*.h
F:	Documentation/devicetree/bindings/clock/exynos*.txt
+40 −18
Original line number Diff line number Diff line
@@ -28,12 +28,10 @@
 * parent - fixed parent.  No clk_set_parent support
 */

#define div_mask(width)	((1 << (width)) - 1)

static unsigned int _get_table_maxdiv(const struct clk_div_table *table,
				      u8 width)
{
	unsigned int maxdiv = 0, mask = div_mask(width);
	unsigned int maxdiv = 0, mask = clk_div_mask(width);
	const struct clk_div_table *clkt;

	for (clkt = table; clkt->div; clkt++)
@@ -57,12 +55,12 @@ static unsigned int _get_maxdiv(const struct clk_div_table *table, u8 width,
				unsigned long flags)
{
	if (flags & CLK_DIVIDER_ONE_BASED)
		return div_mask(width);
		return clk_div_mask(width);
	if (flags & CLK_DIVIDER_POWER_OF_TWO)
		return 1 << div_mask(width);
		return 1 << clk_div_mask(width);
	if (table)
		return _get_table_maxdiv(table, width);
	return div_mask(width) + 1;
	return clk_div_mask(width) + 1;
}

static unsigned int _get_table_div(const struct clk_div_table *table,
@@ -84,7 +82,7 @@ static unsigned int _get_div(const struct clk_div_table *table,
	if (flags & CLK_DIVIDER_POWER_OF_TWO)
		return 1 << val;
	if (flags & CLK_DIVIDER_MAX_AT_ZERO)
		return val ? val : div_mask(width) + 1;
		return val ? val : clk_div_mask(width) + 1;
	if (table)
		return _get_table_div(table, val);
	return val + 1;
@@ -109,7 +107,7 @@ static unsigned int _get_val(const struct clk_div_table *table,
	if (flags & CLK_DIVIDER_POWER_OF_TWO)
		return __ffs(div);
	if (flags & CLK_DIVIDER_MAX_AT_ZERO)
		return (div == div_mask(width) + 1) ? 0 : div;
		return (div == clk_div_mask(width) + 1) ? 0 : div;
	if (table)
		return  _get_table_val(table, div);
	return div - 1;
@@ -141,7 +139,7 @@ static unsigned long clk_divider_recalc_rate(struct clk_hw *hw,
	unsigned int val;

	val = clk_readl(divider->reg) >> divider->shift;
	val &= div_mask(divider->width);
	val &= clk_div_mask(divider->width);

	return divider_recalc_rate(hw, parent_rate, val, divider->table,
				   divider->flags, divider->width);
@@ -344,19 +342,43 @@ long divider_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
}
EXPORT_SYMBOL_GPL(divider_round_rate_parent);

long divider_ro_round_rate_parent(struct clk_hw *hw, struct clk_hw *parent,
				  unsigned long rate, unsigned long *prate,
				  const struct clk_div_table *table, u8 width,
				  unsigned long flags, unsigned int val)
{
	int div;

	div = _get_div(table, val, flags, width);

	/* Even a read-only clock can propagate a rate change */
	if (clk_hw_get_flags(hw) & CLK_SET_RATE_PARENT) {
		if (!parent)
			return -EINVAL;

		*prate = clk_hw_round_rate(parent, rate * div);
	}

	return DIV_ROUND_UP_ULL((u64)*prate, div);
}
EXPORT_SYMBOL_GPL(divider_ro_round_rate_parent);


static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long *prate)
{
	struct clk_divider *divider = to_clk_divider(hw);
	int bestdiv;

	/* if read only, just return current value */
	if (divider->flags & CLK_DIVIDER_READ_ONLY) {
		bestdiv = clk_readl(divider->reg) >> divider->shift;
		bestdiv &= div_mask(divider->width);
		bestdiv = _get_div(divider->table, bestdiv, divider->flags,
			divider->width);
		return DIV_ROUND_UP_ULL((u64)*prate, bestdiv);
		u32 val;

		val = clk_readl(divider->reg) >> divider->shift;
		val &= clk_div_mask(divider->width);

		return divider_ro_round_rate(hw, rate, prate, divider->table,
					     divider->width, divider->flags,
					     val);
	}

	return divider_round_rate(hw, rate, prate, divider->table,
@@ -376,7 +398,7 @@ int divider_get_val(unsigned long rate, unsigned long parent_rate,

	value = _get_val(table, div, flags, width);

	return min_t(unsigned int, value, div_mask(width));
	return min_t(unsigned int, value, clk_div_mask(width));
}
EXPORT_SYMBOL_GPL(divider_get_val);

@@ -399,10 +421,10 @@ static int clk_divider_set_rate(struct clk_hw *hw, unsigned long rate,
		__acquire(divider->lock);

	if (divider->flags & CLK_DIVIDER_HIWORD_MASK) {
		val = div_mask(divider->width) << (divider->shift + 16);
		val = clk_div_mask(divider->width) << (divider->shift + 16);
	} else {
		val = clk_readl(divider->reg);
		val &= ~(div_mask(divider->width) << divider->shift);
		val &= ~(clk_div_mask(divider->width) << divider->shift);
	}
	val |= (u32)value << divider->shift;
	clk_writel(val, divider->reg);
+43 −32
Original line number Diff line number Diff line
@@ -26,35 +26,24 @@
 * parent - parent is adjustable through clk_set_parent
 */

static u8 clk_mux_get_parent(struct clk_hw *hw)
int clk_mux_val_to_index(struct clk_hw *hw, u32 *table, unsigned int flags,
			 unsigned int val)
{
	struct clk_mux *mux = to_clk_mux(hw);
	int num_parents = clk_hw_get_num_parents(hw);
	u32 val;

	/*
	 * FIXME need a mux-specific flag to determine if val is bitwise or numeric
	 * e.g. sys_clkin_ck's clksel field is 3 bits wide, but ranges from 0x1
	 * to 0x7 (index starts at one)
	 * OTOH, pmd_trace_clk_mux_ck uses a separate bit for each clock, so
	 * val = 0x4 really means "bit 2, index starts at bit 0"
	 */
	val = clk_readl(mux->reg) >> mux->shift;
	val &= mux->mask;

	if (mux->table) {
	if (table) {
		int i;

		for (i = 0; i < num_parents; i++)
			if (mux->table[i] == val)
			if (table[i] == val)
				return i;
		return -EINVAL;
	}

	if (val && (mux->flags & CLK_MUX_INDEX_BIT))
	if (val && (flags & CLK_MUX_INDEX_BIT))
		val = ffs(val) - 1;

	if (val && (mux->flags & CLK_MUX_INDEX_ONE))
	if (val && (flags & CLK_MUX_INDEX_ONE))
		val--;

	if (val >= num_parents)
@@ -62,36 +51,58 @@ static u8 clk_mux_get_parent(struct clk_hw *hw)

	return val;
}
EXPORT_SYMBOL_GPL(clk_mux_val_to_index);

static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
unsigned int clk_mux_index_to_val(u32 *table, unsigned int flags, u8 index)
{
	unsigned int val = index;

	if (table) {
		val = table[index];
	} else {
		if (flags & CLK_MUX_INDEX_BIT)
			val = 1 << index;

		if (flags & CLK_MUX_INDEX_ONE)
			val++;
	}

	return val;
}
EXPORT_SYMBOL_GPL(clk_mux_index_to_val);

static u8 clk_mux_get_parent(struct clk_hw *hw)
{
	struct clk_mux *mux = to_clk_mux(hw);
	u32 val;
	unsigned long flags = 0;

	if (mux->table) {
		index = mux->table[index];
	} else {
		if (mux->flags & CLK_MUX_INDEX_BIT)
			index = 1 << index;
	val = clk_readl(mux->reg) >> mux->shift;
	val &= mux->mask;

		if (mux->flags & CLK_MUX_INDEX_ONE)
			index++;
	return clk_mux_val_to_index(hw, mux->table, mux->flags, val);
}

static int clk_mux_set_parent(struct clk_hw *hw, u8 index)
{
	struct clk_mux *mux = to_clk_mux(hw);
	u32 val = clk_mux_index_to_val(mux->table, mux->flags, index);
	unsigned long flags = 0;
	u32 reg;

	if (mux->lock)
		spin_lock_irqsave(mux->lock, flags);
	else
		__acquire(mux->lock);

	if (mux->flags & CLK_MUX_HIWORD_MASK) {
		val = mux->mask << (mux->shift + 16);
		reg = mux->mask << (mux->shift + 16);
	} else {
		val = clk_readl(mux->reg);
		val &= ~(mux->mask << mux->shift);
		reg = clk_readl(mux->reg);
		reg &= ~(mux->mask << mux->shift);
	}
	val |= index << mux->shift;
	clk_writel(val, mux->reg);
	val = val << mux->shift;
	reg |= val;
	clk_writel(reg, mux->reg);

	if (mux->lock)
		spin_unlock_irqrestore(mux->lock, flags);
+35 −28
Original line number Diff line number Diff line
@@ -1125,8 +1125,10 @@ static int clk_core_round_rate_nolock(struct clk_core *core,
{
	lockdep_assert_held(&prepare_lock);

	if (!core)
	if (!core) {
		req->rate = 0;
		return 0;
	}

	clk_core_init_rate_req(core, req);

@@ -2927,6 +2929,17 @@ static int __clk_core_init(struct clk_core *core)
		core->orphan = true;
	}

	/*
	 * optional platform-specific magic
	 *
	 * The .init callback is not used by any of the basic clock types, but
	 * exists for weird hardware that must perform initialization magic.
	 * Please consider other ways of solving initialization problems before
	 * using this callback, as its use is discouraged.
	 */
	if (core->ops->init)
		core->ops->init(core->hw);

	/*
	 * Set clk's accuracy.  The preferred method is to use
	 * .recalc_accuracy. For simple clocks and lazy developers the default
@@ -2967,49 +2980,43 @@ static int __clk_core_init(struct clk_core *core)
		rate = 0;
	core->rate = core->req_rate = rate;

	/*
	 * Enable CLK_IS_CRITICAL clocks so newly added critical clocks
	 * don't get accidentally disabled when walking the orphan tree and
	 * reparenting clocks
	 */
	if (core->flags & CLK_IS_CRITICAL) {
		unsigned long flags;

		clk_core_prepare(core);

		flags = clk_enable_lock();
		clk_core_enable(core);
		clk_enable_unlock(flags);
	}

	/*
	 * walk the list of orphan clocks and reparent any that newly finds a
	 * parent.
	 */
	hlist_for_each_entry_safe(orphan, tmp2, &clk_orphan_list, child_node) {
		struct clk_core *parent = __clk_init_parent(orphan);
		unsigned long flags;

		/*
		 * we could call __clk_set_parent, but that would result in a
		 * redundant call to the .set_rate op, if it exists
		 * We need to use __clk_set_parent_before() and _after() to
		 * to properly migrate any prepare/enable count of the orphan
		 * clock. This is important for CLK_IS_CRITICAL clocks, which
		 * are enabled during init but might not have a parent yet.
		 */
		if (parent) {
			/* update the clk tree topology */
			flags = clk_enable_lock();
			clk_reparent(orphan, parent);
			clk_enable_unlock(flags);
			__clk_set_parent_before(orphan, parent);
			__clk_set_parent_after(orphan, parent, NULL);
			__clk_recalc_accuracies(orphan);
			__clk_recalc_rates(orphan, 0);
		}
	}

	/*
	 * optional platform-specific magic
	 *
	 * The .init callback is not used by any of the basic clock types, but
	 * exists for weird hardware that must perform initialization magic.
	 * Please consider other ways of solving initialization problems before
	 * using this callback, as its use is discouraged.
	 */
	if (core->ops->init)
		core->ops->init(core->hw);

	if (core->flags & CLK_IS_CRITICAL) {
		unsigned long flags;

		clk_core_prepare(core);

		flags = clk_enable_lock();
		clk_core_enable(core);
		clk_enable_unlock(flags);
	}

	kref_init(&core->ref);
out:
	clk_pm_runtime_put(core);
+9 −0
Original line number Diff line number Diff line
@@ -3,10 +3,15 @@ config COMMON_CLK_AMLOGIC
	depends on OF
	depends on ARCH_MESON || COMPILE_TEST

config COMMON_CLK_REGMAP_MESON
	bool
	select REGMAP

config COMMON_CLK_MESON8B
	bool
	depends on COMMON_CLK_AMLOGIC
	select RESET_CONTROLLER
	select COMMON_CLK_REGMAP_MESON
	help
	  Support for the clock controller on AmLogic S802 (Meson8),
	  S805 (Meson8b) and S812 (Meson8m2) devices. Say Y if you
@@ -16,6 +21,8 @@ config COMMON_CLK_GXBB
	bool
	depends on COMMON_CLK_AMLOGIC
	select RESET_CONTROLLER
	select COMMON_CLK_REGMAP_MESON
	select MFD_SYSCON
	help
	  Support for the clock controller on AmLogic S905 devices, aka gxbb.
	  Say Y if you want peripherals and CPU frequency scaling to work.
@@ -24,6 +31,8 @@ config COMMON_CLK_AXG
	bool
	depends on COMMON_CLK_AMLOGIC
	select RESET_CONTROLLER
	select COMMON_CLK_REGMAP_MESON
	select MFD_SYSCON
	help
	  Support for the clock controller on AmLogic A113D devices, aka axg.
	  Say Y if you want peripherals and CPU frequency scaling to work.
Loading