Commit b6c444de authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge branches 'clk-cdce-regulator', 'clk-bcm', 'clk-evict-parent-cache' and...

Merge branches 'clk-cdce-regulator', 'clk-bcm', 'clk-evict-parent-cache' and 'clk-actions' into clk-next

 - Add regulator support to the cdce925 clk driver
 - Add support for Raspberry Pi 4 bcm2711 SoCs
 - Evict parents from parent cache when they're unregistered

* clk-cdce-regulator:
  clk: clk-cdce925: Add regulator support
  dt-bindings: clock: cdce925: Add regulator documentation

* clk-bcm:
  clk: bcm2835: Mark PLLD_PER as CRITICAL
  clk: bcm2835: Add BCM2711_CLOCK_EMMC2 support
  clk: bcm2835: Introduce SoC specific clock registration
  dt-bindings: bcm2835-cprman: Add bcm2711 support

* clk-evict-parent-cache:
  clk: Evict unregistered clks from parent caches

* clk-actions:
  clk: actions: Fix factor clk struct member access
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -12,7 +12,9 @@ clock generators, but a few (like the ARM or HDMI) will source from
the PLL dividers directly.

Required properties:
- compatible:	Should be "brcm,bcm2835-cprman"
- compatible:	should be one of the following,
	"brcm,bcm2711-cprman"
	"brcm,bcm2835-cprman"
- #clock-cells:	Should be <1>. The permitted clock-specifier values can be
		  found in include/dt-bindings/clock/bcm2835.h
- reg:		Specifies base physical address and size of the registers
+4 −0
Original line number Diff line number Diff line
@@ -24,6 +24,8 @@ Required properties:
Optional properties:
 - xtal-load-pf: Crystal load-capacitor value to fine-tune performance on a
                 board, or to compensate for external influences.
- vdd-supply: A regulator node for Vdd
- vddout-supply: A regulator node for Vddout

For all PLL1, PLL2, ... an optional child node can be used to specify spread
spectrum clocking parameters for a board.
@@ -41,6 +43,8 @@ Example:
		clocks = <&xtal_27Mhz>;
		#clock-cells = <1>;
		xtal-load-pf = <5>;
		vdd-supply = <&1v8-reg>;
		vddout-supply = <&3v3-reg>;
		/* PLL options to get SSC 1% centered */
		PLL2 {
			spread-spectrum = <4>;
+3 −4
Original line number Diff line number Diff line
@@ -64,11 +64,10 @@ static unsigned int _get_table_val(const struct clk_factor_table *table,
	return val;
}

static int clk_val_best(struct clk_hw *hw, unsigned long rate,
static int owl_clk_val_best(const struct owl_factor_hw *factor_hw,
			struct clk_hw *hw, unsigned long rate,
			unsigned long *best_parent_rate)
{
	struct owl_factor *factor = hw_to_owl_factor(hw);
	struct owl_factor_hw *factor_hw = &factor->factor_hw;
	const struct clk_factor_table *clkt = factor_hw->table;
	unsigned long parent_rate, try_parent_rate, best = 0, cur_rate;
	unsigned long parent_rate_saved = *best_parent_rate;
@@ -126,7 +125,7 @@ long owl_factor_helper_round_rate(struct owl_clk_common *common,
	const struct clk_factor_table *clkt = factor_hw->table;
	unsigned int val, mul = 0, div = 1;

	val = clk_val_best(&common->hw, rate, parent_rate);
	val = owl_clk_val_best(factor_hw, &common->hw, rate, parent_rate);
	_get_table_div_mul(clkt, val, &mul, &div);

	return *parent_rate * mul / div;
+120 −18
Original line number Diff line number Diff line
@@ -31,7 +31,7 @@
#include <linux/delay.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <dt-bindings/clock/bcm2835.h>
@@ -114,6 +114,8 @@
#define CM_AVEODIV		0x1bc
#define CM_EMMCCTL		0x1c0
#define CM_EMMCDIV		0x1c4
#define CM_EMMC2CTL		0x1d0
#define CM_EMMC2DIV		0x1d4

/* General bits for the CM_*CTL regs */
# define CM_ENABLE			BIT(4)
@@ -289,6 +291,10 @@
#define LOCK_TIMEOUT_NS		100000000
#define BCM2835_MAX_FB_RATE	1750000000u

#define SOC_BCM2835		BIT(0)
#define SOC_BCM2711		BIT(1)
#define SOC_ALL			(SOC_BCM2835 | SOC_BCM2711)

/*
 * Names of clocks used within the driver that need to be replaced
 * with an external parent's name.  This array is in the order that
@@ -320,6 +326,10 @@ struct bcm2835_cprman {
	struct clk_hw_onecell_data onecell;
};

struct cprman_plat_data {
	unsigned int soc;
};

static inline void cprman_write(struct bcm2835_cprman *cprman, u32 reg, u32 val)
{
	writel(CM_PASSWORD | val, cprman->regs + reg);
@@ -1451,22 +1461,28 @@ typedef struct clk_hw *(*bcm2835_clk_register)(struct bcm2835_cprman *cprman,
					       const void *data);
struct bcm2835_clk_desc {
	bcm2835_clk_register clk_register;
	unsigned int supported;
	const void *data;
};

/* assignment helper macros for different clock types */
#define _REGISTER(f, ...) { .clk_register = (bcm2835_clk_register)f, \
#define _REGISTER(f, s, ...) { .clk_register = (bcm2835_clk_register)f, \
			       .supported = s,				\
			       .data = __VA_ARGS__ }
#define REGISTER_PLL(...)	_REGISTER(&bcm2835_register_pll,	\
#define REGISTER_PLL(s, ...)	_REGISTER(&bcm2835_register_pll,	\
					  s,				\
					  &(struct bcm2835_pll_data)	\
					  {__VA_ARGS__})
#define REGISTER_PLL_DIV(...)	_REGISTER(&bcm2835_register_pll_divider, \
#define REGISTER_PLL_DIV(s, ...) _REGISTER(&bcm2835_register_pll_divider, \
					   s,				  \
					   &(struct bcm2835_pll_divider_data) \
					   {__VA_ARGS__})
#define REGISTER_CLK(...)	_REGISTER(&bcm2835_register_clock,	\
#define REGISTER_CLK(s, ...)	_REGISTER(&bcm2835_register_clock,	\
					  s,				\
					  &(struct bcm2835_clock_data)	\
					  {__VA_ARGS__})
#define REGISTER_GATE(...)	_REGISTER(&bcm2835_register_gate,	\
#define REGISTER_GATE(s, ...)	_REGISTER(&bcm2835_register_gate,	\
					  s,				\
					  &(struct bcm2835_gate_data)	\
					  {__VA_ARGS__})

@@ -1480,7 +1496,8 @@ static const char *const bcm2835_clock_osc_parents[] = {
	"testdebug1"
};

#define REGISTER_OSC_CLK(...)	REGISTER_CLK(				\
#define REGISTER_OSC_CLK(s, ...)	REGISTER_CLK(			\
	s,								\
	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_osc_parents),	\
	.parents = bcm2835_clock_osc_parents,				\
	__VA_ARGS__)
@@ -1497,7 +1514,8 @@ static const char *const bcm2835_clock_per_parents[] = {
	"pllh_aux",
};

#define REGISTER_PER_CLK(...)	REGISTER_CLK(				\
#define REGISTER_PER_CLK(s, ...)	REGISTER_CLK(			\
	s,								\
	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_per_parents),	\
	.parents = bcm2835_clock_per_parents,				\
	__VA_ARGS__)
@@ -1522,7 +1540,8 @@ static const char *const bcm2835_pcm_per_parents[] = {
	"-",
};

#define REGISTER_PCM_CLK(...)	REGISTER_CLK(				\
#define REGISTER_PCM_CLK(s, ...)	REGISTER_CLK(			\
	s,								\
	.num_mux_parents = ARRAY_SIZE(bcm2835_pcm_per_parents),		\
	.parents = bcm2835_pcm_per_parents,				\
	__VA_ARGS__)
@@ -1541,7 +1560,8 @@ static const char *const bcm2835_clock_vpu_parents[] = {
	"pllc_core2",
};

#define REGISTER_VPU_CLK(...)	REGISTER_CLK(				\
#define REGISTER_VPU_CLK(s, ...)	REGISTER_CLK(			\
	s,								\
	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_vpu_parents),	\
	.parents = bcm2835_clock_vpu_parents,				\
	__VA_ARGS__)
@@ -1577,12 +1597,14 @@ static const char *const bcm2835_clock_dsi1_parents[] = {
	"dsi1_byte_inv",
};

#define REGISTER_DSI0_CLK(...)	REGISTER_CLK(				\
#define REGISTER_DSI0_CLK(s, ...)	REGISTER_CLK(			\
	s,								\
	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi0_parents),	\
	.parents = bcm2835_clock_dsi0_parents,				\
	__VA_ARGS__)

#define REGISTER_DSI1_CLK(...)	REGISTER_CLK(				\
#define REGISTER_DSI1_CLK(s, ...)	REGISTER_CLK(			\
	s,								\
	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents),	\
	.parents = bcm2835_clock_dsi1_parents,				\
	__VA_ARGS__)
@@ -1602,6 +1624,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * AUDIO domain is on.
	 */
	[BCM2835_PLLA]		= REGISTER_PLL(
		SOC_ALL,
		.name = "plla",
		.cm_ctrl_reg = CM_PLLA,
		.a2w_ctrl_reg = A2W_PLLA_CTRL,
@@ -1616,6 +1639,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.max_rate = 2400000000u,
		.max_fb_rate = BCM2835_MAX_FB_RATE),
	[BCM2835_PLLA_CORE]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "plla_core",
		.source_pll = "plla",
		.cm_reg = CM_PLLA,
@@ -1625,6 +1649,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLA_PER]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "plla_per",
		.source_pll = "plla",
		.cm_reg = CM_PLLA,
@@ -1634,6 +1659,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLA_DSI0]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "plla_dsi0",
		.source_pll = "plla",
		.cm_reg = CM_PLLA,
@@ -1642,6 +1668,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.hold_mask = CM_PLLA_HOLDDSI0,
		.fixed_divider = 1),
	[BCM2835_PLLA_CCP2]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "plla_ccp2",
		.source_pll = "plla",
		.cm_reg = CM_PLLA,
@@ -1663,6 +1690,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * AUDIO domain is on.
	 */
	[BCM2835_PLLC]		= REGISTER_PLL(
		SOC_ALL,
		.name = "pllc",
		.cm_ctrl_reg = CM_PLLC,
		.a2w_ctrl_reg = A2W_PLLC_CTRL,
@@ -1677,6 +1705,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.max_rate = 3000000000u,
		.max_fb_rate = BCM2835_MAX_FB_RATE),
	[BCM2835_PLLC_CORE0]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "pllc_core0",
		.source_pll = "pllc",
		.cm_reg = CM_PLLC,
@@ -1686,6 +1715,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLC_CORE1]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "pllc_core1",
		.source_pll = "pllc",
		.cm_reg = CM_PLLC,
@@ -1695,6 +1725,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLC_CORE2]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "pllc_core2",
		.source_pll = "pllc",
		.cm_reg = CM_PLLC,
@@ -1704,6 +1735,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLC_PER]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "pllc_per",
		.source_pll = "pllc",
		.cm_reg = CM_PLLC,
@@ -1720,6 +1752,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * AUDIO domain is on.
	 */
	[BCM2835_PLLD]		= REGISTER_PLL(
		SOC_ALL,
		.name = "plld",
		.cm_ctrl_reg = CM_PLLD,
		.a2w_ctrl_reg = A2W_PLLD_CTRL,
@@ -1734,6 +1767,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.max_rate = 2400000000u,
		.max_fb_rate = BCM2835_MAX_FB_RATE),
	[BCM2835_PLLD_CORE]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "plld_core",
		.source_pll = "plld",
		.cm_reg = CM_PLLD,
@@ -1742,7 +1776,13 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.hold_mask = CM_PLLD_HOLDCORE,
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	/*
	 * VPU firmware assumes that PLLD_PER isn't disabled by the ARM core.
	 * Otherwise this could cause firmware lookups. That's why we mark
	 * it as critical.
	 */
	[BCM2835_PLLD_PER]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "plld_per",
		.source_pll = "plld",
		.cm_reg = CM_PLLD,
@@ -1750,8 +1790,9 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.load_mask = CM_PLLD_LOADPER,
		.hold_mask = CM_PLLD_HOLDPER,
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
		.flags = CLK_IS_CRITICAL | CLK_SET_RATE_PARENT),
	[BCM2835_PLLD_DSI0]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "plld_dsi0",
		.source_pll = "plld",
		.cm_reg = CM_PLLD,
@@ -1760,6 +1801,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.hold_mask = CM_PLLD_HOLDDSI0,
		.fixed_divider = 1),
	[BCM2835_PLLD_DSI1]	= REGISTER_PLL_DIV(
		SOC_ALL,
		.name = "plld_dsi1",
		.source_pll = "plld",
		.cm_reg = CM_PLLD,
@@ -1775,6 +1817,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * It is in the HDMI power domain.
	 */
	[BCM2835_PLLH]		= REGISTER_PLL(
		SOC_BCM2835,
		"pllh",
		.cm_ctrl_reg = CM_PLLH,
		.a2w_ctrl_reg = A2W_PLLH_CTRL,
@@ -1789,6 +1832,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.max_rate = 3000000000u,
		.max_fb_rate = BCM2835_MAX_FB_RATE),
	[BCM2835_PLLH_RCAL]	= REGISTER_PLL_DIV(
		SOC_BCM2835,
		.name = "pllh_rcal",
		.source_pll = "pllh",
		.cm_reg = CM_PLLH,
@@ -1798,6 +1842,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.fixed_divider = 10,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLH_AUX]	= REGISTER_PLL_DIV(
		SOC_BCM2835,
		.name = "pllh_aux",
		.source_pll = "pllh",
		.cm_reg = CM_PLLH,
@@ -1807,6 +1852,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLH_PIX]	= REGISTER_PLL_DIV(
		SOC_BCM2835,
		.name = "pllh_pix",
		.source_pll = "pllh",
		.cm_reg = CM_PLLH,
@@ -1822,6 +1868,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

	/* One Time Programmable Memory clock.  Maximum 10Mhz. */
	[BCM2835_CLOCK_OTP]	= REGISTER_OSC_CLK(
		SOC_ALL,
		.name = "otp",
		.ctl_reg = CM_OTPCTL,
		.div_reg = CM_OTPDIV,
@@ -1833,6 +1880,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * bythe watchdog timer and the camera pulse generator.
	 */
	[BCM2835_CLOCK_TIMER]	= REGISTER_OSC_CLK(
		SOC_ALL,
		.name = "timer",
		.ctl_reg = CM_TIMERCTL,
		.div_reg = CM_TIMERDIV,
@@ -1843,12 +1891,14 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * Generally run at 2Mhz, max 5Mhz.
	 */
	[BCM2835_CLOCK_TSENS]	= REGISTER_OSC_CLK(
		SOC_ALL,
		.name = "tsens",
		.ctl_reg = CM_TSENSCTL,
		.div_reg = CM_TSENSDIV,
		.int_bits = 5,
		.frac_bits = 0),
	[BCM2835_CLOCK_TEC]	= REGISTER_OSC_CLK(
		SOC_ALL,
		.name = "tec",
		.ctl_reg = CM_TECCTL,
		.div_reg = CM_TECDIV,
@@ -1857,6 +1907,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

	/* clocks with vpu parent mux */
	[BCM2835_CLOCK_H264]	= REGISTER_VPU_CLK(
		SOC_ALL,
		.name = "h264",
		.ctl_reg = CM_H264CTL,
		.div_reg = CM_H264DIV,
@@ -1864,6 +1915,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 8,
		.tcnt_mux = 1),
	[BCM2835_CLOCK_ISP]	= REGISTER_VPU_CLK(
		SOC_ALL,
		.name = "isp",
		.ctl_reg = CM_ISPCTL,
		.div_reg = CM_ISPDIV,
@@ -1876,6 +1928,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * in the SDRAM controller can't be used.
	 */
	[BCM2835_CLOCK_SDRAM]	= REGISTER_VPU_CLK(
		SOC_ALL,
		.name = "sdram",
		.ctl_reg = CM_SDCCTL,
		.div_reg = CM_SDCDIV,
@@ -1883,6 +1936,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 0,
		.tcnt_mux = 3),
	[BCM2835_CLOCK_V3D]	= REGISTER_VPU_CLK(
		SOC_ALL,
		.name = "v3d",
		.ctl_reg = CM_V3DCTL,
		.div_reg = CM_V3DDIV,
@@ -1896,6 +1950,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * in various hardware documentation.
	 */
	[BCM2835_CLOCK_VPU]	= REGISTER_VPU_CLK(
		SOC_ALL,
		.name = "vpu",
		.ctl_reg = CM_VPUCTL,
		.div_reg = CM_VPUDIV,
@@ -1907,6 +1962,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

	/* clocks with per parent mux */
	[BCM2835_CLOCK_AVEO]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "aveo",
		.ctl_reg = CM_AVEOCTL,
		.div_reg = CM_AVEODIV,
@@ -1914,6 +1970,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 0,
		.tcnt_mux = 38),
	[BCM2835_CLOCK_CAM0]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "cam0",
		.ctl_reg = CM_CAM0CTL,
		.div_reg = CM_CAM0DIV,
@@ -1921,6 +1978,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 8,
		.tcnt_mux = 14),
	[BCM2835_CLOCK_CAM1]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "cam1",
		.ctl_reg = CM_CAM1CTL,
		.div_reg = CM_CAM1DIV,
@@ -1928,12 +1986,14 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 8,
		.tcnt_mux = 15),
	[BCM2835_CLOCK_DFT]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "dft",
		.ctl_reg = CM_DFTCTL,
		.div_reg = CM_DFTDIV,
		.int_bits = 5,
		.frac_bits = 0),
	[BCM2835_CLOCK_DPI]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "dpi",
		.ctl_reg = CM_DPICTL,
		.div_reg = CM_DPIDIV,
@@ -1943,6 +2003,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

	/* Arasan EMMC clock */
	[BCM2835_CLOCK_EMMC]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "emmc",
		.ctl_reg = CM_EMMCCTL,
		.div_reg = CM_EMMCDIV,
@@ -1950,8 +2011,19 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 8,
		.tcnt_mux = 39),

	/* EMMC2 clock (only available for BCM2711) */
	[BCM2711_CLOCK_EMMC2]	= REGISTER_PER_CLK(
		SOC_BCM2711,
		.name = "emmc2",
		.ctl_reg = CM_EMMC2CTL,
		.div_reg = CM_EMMC2DIV,
		.int_bits = 4,
		.frac_bits = 8,
		.tcnt_mux = 42),

	/* General purpose (GPIO) clocks */
	[BCM2835_CLOCK_GP0]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "gp0",
		.ctl_reg = CM_GP0CTL,
		.div_reg = CM_GP0DIV,
@@ -1960,6 +2032,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.is_mash_clock = true,
		.tcnt_mux = 20),
	[BCM2835_CLOCK_GP1]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "gp1",
		.ctl_reg = CM_GP1CTL,
		.div_reg = CM_GP1DIV,
@@ -1969,6 +2042,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.is_mash_clock = true,
		.tcnt_mux = 21),
	[BCM2835_CLOCK_GP2]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "gp2",
		.ctl_reg = CM_GP2CTL,
		.div_reg = CM_GP2DIV,
@@ -1978,6 +2052,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

	/* HDMI state machine */
	[BCM2835_CLOCK_HSM]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "hsm",
		.ctl_reg = CM_HSMCTL,
		.div_reg = CM_HSMDIV,
@@ -1985,6 +2060,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 8,
		.tcnt_mux = 22),
	[BCM2835_CLOCK_PCM]	= REGISTER_PCM_CLK(
		SOC_ALL,
		.name = "pcm",
		.ctl_reg = CM_PCMCTL,
		.div_reg = CM_PCMDIV,
@@ -1994,6 +2070,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.low_jitter = true,
		.tcnt_mux = 23),
	[BCM2835_CLOCK_PWM]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "pwm",
		.ctl_reg = CM_PWMCTL,
		.div_reg = CM_PWMDIV,
@@ -2002,6 +2079,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.is_mash_clock = true,
		.tcnt_mux = 24),
	[BCM2835_CLOCK_SLIM]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "slim",
		.ctl_reg = CM_SLIMCTL,
		.div_reg = CM_SLIMDIV,
@@ -2010,6 +2088,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.is_mash_clock = true,
		.tcnt_mux = 25),
	[BCM2835_CLOCK_SMI]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "smi",
		.ctl_reg = CM_SMICTL,
		.div_reg = CM_SMIDIV,
@@ -2017,6 +2096,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 8,
		.tcnt_mux = 27),
	[BCM2835_CLOCK_UART]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "uart",
		.ctl_reg = CM_UARTCTL,
		.div_reg = CM_UARTDIV,
@@ -2026,6 +2106,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

	/* TV encoder clock.  Only operating frequency is 108Mhz.  */
	[BCM2835_CLOCK_VEC]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "vec",
		.ctl_reg = CM_VECCTL,
		.div_reg = CM_VECDIV,
@@ -2040,6 +2121,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {

	/* dsi clocks */
	[BCM2835_CLOCK_DSI0E]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "dsi0e",
		.ctl_reg = CM_DSI0ECTL,
		.div_reg = CM_DSI0EDIV,
@@ -2047,6 +2129,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 8,
		.tcnt_mux = 18),
	[BCM2835_CLOCK_DSI1E]	= REGISTER_PER_CLK(
		SOC_ALL,
		.name = "dsi1e",
		.ctl_reg = CM_DSI1ECTL,
		.div_reg = CM_DSI1EDIV,
@@ -2054,6 +2137,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 8,
		.tcnt_mux = 19),
	[BCM2835_CLOCK_DSI0P]	= REGISTER_DSI0_CLK(
		SOC_ALL,
		.name = "dsi0p",
		.ctl_reg = CM_DSI0PCTL,
		.div_reg = CM_DSI0PDIV,
@@ -2061,6 +2145,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.frac_bits = 0,
		.tcnt_mux = 12),
	[BCM2835_CLOCK_DSI1P]	= REGISTER_DSI1_CLK(
		SOC_ALL,
		.name = "dsi1p",
		.ctl_reg = CM_DSI1PCTL,
		.div_reg = CM_DSI1PDIV,
@@ -2077,6 +2162,7 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
	 * non-stop vpu clock.
	 */
	[BCM2835_CLOCK_PERI_IMAGE] = REGISTER_GATE(
		SOC_ALL,
		.name = "peri_image",
		.parent = "vpu",
		.ctl_reg = CM_PERIICTL),
@@ -2109,9 +2195,14 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
	struct resource *res;
	const struct bcm2835_clk_desc *desc;
	const size_t asize = ARRAY_SIZE(clk_desc_array);
	const struct cprman_plat_data *pdata;
	size_t i;
	int ret;

	pdata = of_device_get_match_data(&pdev->dev);
	if (!pdata)
		return -ENODEV;

	cprman = devm_kzalloc(dev,
			      struct_size(cprman, onecell.hws, asize),
			      GFP_KERNEL);
@@ -2147,9 +2238,11 @@ static int bcm2835_clk_probe(struct platform_device *pdev)

	for (i = 0; i < asize; i++) {
		desc = &clk_desc_array[i];
		if (desc->clk_register && desc->data)
		if (desc->clk_register && desc->data &&
		    (desc->supported & pdata->soc)) {
			hws[i] = desc->clk_register(cprman, desc->data);
		}
	}

	ret = bcm2835_mark_sdc_parent_critical(hws[BCM2835_CLOCK_SDRAM]->clk);
	if (ret)
@@ -2159,8 +2252,17 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
				      &cprman->onecell);
}

static const struct cprman_plat_data cprman_bcm2835_plat_data = {
	.soc = SOC_BCM2835,
};

static const struct cprman_plat_data cprman_bcm2711_plat_data = {
	.soc = SOC_BCM2711,
};

static const struct of_device_id bcm2835_clk_of_match[] = {
	{ .compatible = "brcm,bcm2835-cprman", },
	{ .compatible = "brcm,bcm2835-cprman", .data = &cprman_bcm2835_plat_data },
	{ .compatible = "brcm,bcm2711-cprman", .data = &cprman_bcm2711_plat_data },
	{}
};
MODULE_DEVICE_TABLE(of, bcm2835_clk_of_match);
+34 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
#include <linux/module.h>
#include <linux/i2c.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include <linux/gcd.h>

@@ -602,6 +603,30 @@ of_clk_cdce925_get(struct of_phandle_args *clkspec, void *_data)
	return &data->clk[idx].hw;
}

static void cdce925_regulator_disable(void *regulator)
{
	regulator_disable(regulator);
}

static int cdce925_regulator_enable(struct device *dev, const char *name)
{
	struct regulator *regulator;
	int err;

	regulator = devm_regulator_get(dev, name);
	if (IS_ERR(regulator))
		return PTR_ERR(regulator);

	err = regulator_enable(regulator);
	if (err) {
		dev_err(dev, "Failed to enable %s: %d\n", name, err);
		return err;
	}

	return devm_add_action_or_reset(dev, cdce925_regulator_disable,
					regulator);
}

/* The CDCE925 uses a funky way to read/write registers. Bulk mode is
 * just weird, so just use the single byte mode exclusively. */
static struct regmap_bus regmap_cdce925_bus = {
@@ -630,6 +655,15 @@ static int cdce925_probe(struct i2c_client *client,
	};

	dev_dbg(&client->dev, "%s\n", __func__);

	err = cdce925_regulator_enable(&client->dev, "vdd");
	if (err)
		return err;

	err = cdce925_regulator_enable(&client->dev, "vddout");
	if (err)
		return err;

	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
	if (!data)
		return -ENOMEM;
Loading