Commit 8a02fcf8 authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge tag 'sunxi-clk-for-4.13' of...

Merge tag 'sunxi-clk-for-4.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux into clk-next

Pull Allwinner clock patches from Maxime Ripard:

Some new clock units are supported, for the display clocks unsed in the
newer SoCs, and the A83T PRCM.

There is also a bunch of minor fixes for clocks that are not used by
anyone, and reworks needed by drivers that will land in 4.13.

* tag 'sunxi-clk-for-4.13' of https://git.kernel.org/pub/scm/linux/kernel/git/sunxi/linux: (21 commits)
  clk: sunxi-ng: Move all clock types to a library
  clk: sunxi-ng: a83t: Add support for A83T's PRCM
  dt-bindings: clock: sunxi-ccu: Add compatible string for A83T PRCM
  clk: sunxi-ng: select SUNXI_CCU_MULT for sun8i-a83t
  clk: sunxi-ng: a83t: Fix audio PLL divider offset
  clk: sunxi-ng: a83t: Fix PLL lock status register offset
  clk: sunxi-ng: Add driver for A83T CCU
  clk: sunxi-ng: Support multiple variable pre-dividers
  dt-bindings: clock: sunxi-ccu: Add compatible string for A83T CCU
  clk: sunxi-ng: de2: fix wrong pointer passed to PTR_ERR()
  clk: sunxi-ng: sun5i: Export video PLLs
  clk: sunxi-ng: mux: Re-adjust parent rate
  clk: sunxi-ng: mux: Change pre-divider application function prototype
  clk: sunxi-ng: mux: split out the pre-divider computation code
  clk: sunxi-ng: mux: Don't just rely on the parent for CLK_SET_RATE_PARENT
  clk: sunxi-ng: div: Switch to divider_round_rate
  clk: sunxi-ng: Pass the parent and a pointer to the clocks round rate
  clk: divider: Make divider_round_rate take the parent clock
  clk: sunxi-ng: explicitly include linux/spinlock.h
  clk: sunxi-ng: add support for DE2 CCU
  ...
parents 9c861f33 06e226c7
Loading
Loading
Loading
Loading
+31 −0
Original line number Diff line number Diff line
Allwinner Display Engine 2.0 Clock Control Binding
--------------------------------------------------

Required properties :
- compatible: must contain one of the following compatibles:
		- "allwinner,sun8i-a83t-de2-clk"
		- "allwinner,sun8i-v3s-de2-clk"
		- "allwinner,sun50i-h5-de2-clk"

- reg: Must contain the registers base address and length
- clocks: phandle to the clocks feeding the display engine subsystem.
	  Three are needed:
  - "mod": the display engine module clock
  - "bus": the bus clock for the whole display engine subsystem
- clock-names: Must contain the clock names described just above
- resets: phandle to the reset control for the display engine subsystem.
- #clock-cells : must contain 1
- #reset-cells : must contain 1

Example:
de2_clocks: clock@1000000 {
	compatible = "allwinner,sun8i-a83t-de2-clk";
	reg = <0x01000000 0x100000>;
	clocks = <&ccu CLK_BUS_DE>,
		 <&ccu CLK_DE>;
	clock-names = "bus",
		      "mod";
	resets = <&ccu RST_BUS_DE>;
	#clock-cells = <1>;
	#reset-cells = <1>;
};
+4 −1
Original line number Diff line number Diff line
@@ -6,6 +6,8 @@ Required properties :
		- "allwinner,sun6i-a31-ccu"
		- "allwinner,sun8i-a23-ccu"
		- "allwinner,sun8i-a33-ccu"
		- "allwinner,sun8i-a83t-ccu"
		- "allwinner,sun8i-a83t-r-ccu"
		- "allwinner,sun8i-h3-ccu"
		- "allwinner,sun8i-h3-r-ccu"
		- "allwinner,sun8i-v3s-ccu"
@@ -18,11 +20,12 @@ Required properties :
- clocks: phandle to the oscillators feeding the CCU. Two are needed:
  - "hosc": the high frequency oscillator (usually at 24MHz)
  - "losc": the low frequency oscillator (usually at 32kHz)
	    On the A83T, this is the internal 16MHz oscillator divided by 512
- clock-names: Must contain the clock names described just above
- #clock-cells : must contain 1
- #reset-cells : must contain 1

For the PRCM CCUs on H3/A64, two more clocks are needed:
For the PRCM CCUs on A83T/H3/A64, two more clocks are needed:
- "pll-periph": the SoC's peripheral PLL from the main CCU
- "iosc": the SoC's internal frequency oscillator

+10 −9
Original line number Diff line number Diff line
@@ -275,7 +275,8 @@ static int _next_div(const struct clk_div_table *table, int div,
	return div;
}

static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
static int clk_divider_bestdiv(struct clk_hw *hw, struct clk_hw *parent,
			       unsigned long rate,
			       unsigned long *best_parent_rate,
			       const struct clk_div_table *table, u8 width,
			       unsigned long flags)
@@ -314,8 +315,7 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,
			*best_parent_rate = parent_rate_saved;
			return i;
		}
		parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw),
					       rate * i);
		parent_rate = clk_hw_round_rate(parent, rate * i);
		now = DIV_ROUND_UP_ULL((u64)parent_rate, i);
		if (_is_best_div(rate, now, best, flags)) {
			bestdiv = i;
@@ -326,23 +326,24 @@ static int clk_divider_bestdiv(struct clk_hw *hw, unsigned long rate,

	if (!bestdiv) {
		bestdiv = _get_maxdiv(table, width, flags);
		*best_parent_rate = clk_hw_round_rate(clk_hw_get_parent(hw), 1);
		*best_parent_rate = clk_hw_round_rate(parent, 1);
	}

	return bestdiv;
}

long divider_round_rate(struct clk_hw *hw, unsigned long rate,
			unsigned long *prate, const struct clk_div_table *table,
long divider_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)
{
	int div;

	div = clk_divider_bestdiv(hw, rate, prate, table, width, flags);
	div = clk_divider_bestdiv(hw, parent, rate, prate, table, width, flags);

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

static long clk_divider_round_rate(struct clk_hw *hw, unsigned long rate,
				unsigned long *prate)
+7 −109
Original line number Diff line number Diff line
@@ -6,157 +6,55 @@ config SUNXI_CCU

if SUNXI_CCU

# Base clock types

config SUNXI_CCU_DIV
	bool
	select SUNXI_CCU_MUX

config SUNXI_CCU_FRAC
	bool

config SUNXI_CCU_GATE
	def_bool y

config SUNXI_CCU_MUX
	bool

config SUNXI_CCU_MULT
	bool
	select SUNXI_CCU_MUX

config SUNXI_CCU_PHASE
	bool

# Multi-factor clocks

config SUNXI_CCU_NK
	bool
	select SUNXI_CCU_GATE

config SUNXI_CCU_NKM
	bool
	select SUNXI_CCU_GATE

config SUNXI_CCU_NKMP
	bool
	select SUNXI_CCU_GATE

config SUNXI_CCU_NM
	bool
	select SUNXI_CCU_FRAC
	select SUNXI_CCU_GATE

config SUNXI_CCU_MP
	bool
	select SUNXI_CCU_GATE
	select SUNXI_CCU_MUX

# SoC Drivers

config SUN50I_A64_CCU
	bool "Support for the Allwinner A64 CCU"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_NK
	select SUNXI_CCU_NKM
	select SUNXI_CCU_NKMP
	select SUNXI_CCU_NM
	select SUNXI_CCU_MP
	select SUNXI_CCU_PHASE
	default ARM64 && ARCH_SUNXI
	depends on (ARM64 && ARCH_SUNXI) || COMPILE_TEST

config SUN5I_CCU
	bool "Support for the Allwinner sun5i family CCM"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_MULT
	select SUNXI_CCU_NK
	select SUNXI_CCU_NKM
	select SUNXI_CCU_NM
	select SUNXI_CCU_MP
	select SUNXI_CCU_PHASE
	default MACH_SUN5I
	depends on MACH_SUN5I || COMPILE_TEST

config SUN6I_A31_CCU
	bool "Support for the Allwinner A31/A31s CCU"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_NK
	select SUNXI_CCU_NKM
	select SUNXI_CCU_NKMP
	select SUNXI_CCU_NM
	select SUNXI_CCU_MP
	select SUNXI_CCU_PHASE
	default MACH_SUN6I
	depends on MACH_SUN6I || COMPILE_TEST

config SUN8I_A23_CCU
	bool "Support for the Allwinner A23 CCU"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_MULT
	select SUNXI_CCU_NK
	select SUNXI_CCU_NKM
	select SUNXI_CCU_NKMP
	select SUNXI_CCU_NM
	select SUNXI_CCU_MP
	select SUNXI_CCU_PHASE
	default MACH_SUN8I
	depends on MACH_SUN8I || COMPILE_TEST

config SUN8I_A33_CCU
	bool "Support for the Allwinner A33 CCU"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_MULT
	select SUNXI_CCU_NK
	select SUNXI_CCU_NKM
	select SUNXI_CCU_NKMP
	select SUNXI_CCU_NM
	select SUNXI_CCU_MP
	select SUNXI_CCU_PHASE
	default MACH_SUN8I
	depends on MACH_SUN8I || COMPILE_TEST

config SUN8I_A83T_CCU
	bool "Support for the Allwinner A83T CCU"
	default MACH_SUN8I

config SUN8I_H3_CCU
	bool "Support for the Allwinner H3 CCU"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_NK
	select SUNXI_CCU_NKM
	select SUNXI_CCU_NKMP
	select SUNXI_CCU_NM
	select SUNXI_CCU_MP
	select SUNXI_CCU_PHASE
	default MACH_SUN8I || (ARM64 && ARCH_SUNXI)
	depends on MACH_SUN8I || (ARM64 && ARCH_SUNXI) || COMPILE_TEST

config SUN8I_V3S_CCU
	bool "Support for the Allwinner V3s CCU"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_NK
	select SUNXI_CCU_NKM
	select SUNXI_CCU_NKMP
	select SUNXI_CCU_NM
	select SUNXI_CCU_MP
	select SUNXI_CCU_PHASE
	default MACH_SUN8I
	depends on MACH_SUN8I || COMPILE_TEST

config SUN8I_DE2_CCU
	bool "Support for the Allwinner SoCs DE2 CCU"

config SUN9I_A80_CCU
	bool "Support for the Allwinner A80 CCU"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_MULT
	select SUNXI_CCU_GATE
	select SUNXI_CCU_NKMP
	select SUNXI_CCU_NM
	select SUNXI_CCU_MP
	select SUNXI_CCU_PHASE
	default MACH_SUN9I
	depends on MACH_SUN9I || COMPILE_TEST

config SUN8I_R_CCU
	bool "Support for Allwinner SoCs' PRCM CCUs"
	select SUNXI_CCU_DIV
	select SUNXI_CCU_GATE
	select SUNXI_CCU_MP
	default MACH_SUN8I || (ARCH_SUNXI && ARM64)

endif
+24 −13
Original line number Diff line number Diff line
# Common objects
obj-$(CONFIG_SUNXI_CCU)		+= ccu_common.o
obj-$(CONFIG_SUNXI_CCU)		+= ccu_reset.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_common.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_reset.o

# Base clock types
obj-$(CONFIG_SUNXI_CCU_DIV)	+= ccu_div.o
obj-$(CONFIG_SUNXI_CCU_FRAC)	+= ccu_frac.o
obj-$(CONFIG_SUNXI_CCU_GATE)	+= ccu_gate.o
obj-$(CONFIG_SUNXI_CCU_MUX)	+= ccu_mux.o
obj-$(CONFIG_SUNXI_CCU_MULT)	+= ccu_mult.o
obj-$(CONFIG_SUNXI_CCU_PHASE)	+= ccu_phase.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_div.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_frac.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_gate.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_mux.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_mult.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_phase.o

# Multi-factor clocks
obj-$(CONFIG_SUNXI_CCU_NK)	+= ccu_nk.o
obj-$(CONFIG_SUNXI_CCU_NKM)	+= ccu_nkm.o
obj-$(CONFIG_SUNXI_CCU_NKMP)	+= ccu_nkmp.o
obj-$(CONFIG_SUNXI_CCU_NM)	+= ccu_nm.o
obj-$(CONFIG_SUNXI_CCU_MP)	+= ccu_mp.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_nk.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_nkm.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_nkmp.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_nm.o
lib-$(CONFIG_SUNXI_CCU)		+= ccu_mp.o

# SoC support
obj-$(CONFIG_SUN50I_A64_CCU)	+= ccu-sun50i-a64.o
@@ -23,9 +23,20 @@ obj-$(CONFIG_SUN5I_CCU) += ccu-sun5i.o
obj-$(CONFIG_SUN6I_A31_CCU)	+= ccu-sun6i-a31.o
obj-$(CONFIG_SUN8I_A23_CCU)	+= ccu-sun8i-a23.o
obj-$(CONFIG_SUN8I_A33_CCU)	+= ccu-sun8i-a33.o
obj-$(CONFIG_SUN8I_A83T_CCU)	+= ccu-sun8i-a83t.o
obj-$(CONFIG_SUN8I_H3_CCU)	+= ccu-sun8i-h3.o
obj-$(CONFIG_SUN8I_V3S_CCU)	+= ccu-sun8i-v3s.o
obj-$(CONFIG_SUN8I_DE2_CCU)	+= ccu-sun8i-de2.o
obj-$(CONFIG_SUN8I_R_CCU)	+= ccu-sun8i-r.o
obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80.o
obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-de.o
obj-$(CONFIG_SUN9I_A80_CCU)	+= ccu-sun9i-a80-usb.o

# The lib-y file goals is supposed to work only in arch/*/lib or lib/. In our
# case, we want to use that goal, but even though lib.a will be properly
# generated, it will not be linked in, eventually resulting in a linker error
# for missing symbols.
#
# We can work around that by explicitly adding lib.a to the obj-y goal. This is
# an undocumented behaviour, but works well for now.
obj-$(CONFIG_SUNXI_CCU)		+= lib.a
Loading