Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 645ebb1d authored by Stephen Boyd's avatar Stephen Boyd
Browse files

Merge branch 'clk-imx7', 'clk-bcm2835' into clk-next

* clk-imx7:
  clk: imx7d: Add the OCOTP clock

* clk-bcm2835:
  clk: bcm2835: Add leaf clock measurement support, disabled by default
  clk: bcm2835: Register the DSI0/DSI1 pixel clocks.
  clk: bcm2835: Don't rate change PLLs on behalf of DSI PLL dividers.
Loading
Loading
Loading
Loading
+14 −1
Original line number Diff line number Diff line
@@ -16,7 +16,20 @@ Required properties:
- #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
- clocks:	The external oscillator clock phandle
- clocks:	phandles to the parent clocks used as input to the module, in
		  the following order:

		  - External oscillator
		  - DSI0 byte clock
		  - DSI0 DDR2 clock
		  - DSI0 DDR clock
		  - DSI1 byte clock
		  - DSI1 DDR2 clock
		  - DSI1 DDR clock

		  Only external oscillator is required.  The DSI clocks may
		  not be present, in which case their children will be
		  unusable.

Example:

+254 −49
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@
#include <linux/clk.h>
#include <linux/clk/bcm2835.h>
#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -98,7 +99,8 @@
#define CM_SMIDIV		0x0b4
/* no definition for 0x0b8  and 0x0bc */
#define CM_TCNTCTL		0x0c0
#define CM_TCNTDIV		0x0c4
# define CM_TCNT_SRC1_SHIFT		12
#define CM_TCNTCNT		0x0c4
#define CM_TECCTL		0x0c8
#define CM_TECDIV		0x0cc
#define CM_TD0CTL		0x0d0
@@ -297,11 +299,32 @@
#define LOCK_TIMEOUT_NS		100000000
#define BCM2835_MAX_FB_RATE	1750000000u

/*
 * 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
 * the clocks node in the DT references external clocks.
 */
static const char *const cprman_parent_names[] = {
	"xosc",
	"dsi0_byte",
	"dsi0_ddr2",
	"dsi0_ddr",
	"dsi1_byte",
	"dsi1_ddr2",
	"dsi1_ddr",
};

struct bcm2835_cprman {
	struct device *dev;
	void __iomem *regs;
	spinlock_t regs_lock; /* spinlock for all clocks */
	const char *osc_name;

	/*
	 * Real names of cprman clock parents looked up through
	 * of_clk_get_parent_name(), which will be used in the
	 * parent_names[] arrays for clock registration.
	 */
	const char *real_parent_names[ARRAY_SIZE(cprman_parent_names)];

	/* Must be last */
	struct clk_hw_onecell_data onecell;
@@ -317,6 +340,61 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg)
	return readl(cprman->regs + reg);
}

/* Does a cycle of measuring a clock through the TCNT clock, which may
 * source from many other clocks in the system.
 */
static unsigned long bcm2835_measure_tcnt_mux(struct bcm2835_cprman *cprman,
					      u32 tcnt_mux)
{
	u32 osccount = 19200; /* 1ms */
	u32 count;
	ktime_t timeout;

	spin_lock(&cprman->regs_lock);

	cprman_write(cprman, CM_TCNTCTL, CM_KILL);

	cprman_write(cprman, CM_TCNTCTL,
		     (tcnt_mux & CM_SRC_MASK) |
		     (tcnt_mux >> CM_SRC_BITS) << CM_TCNT_SRC1_SHIFT);

	cprman_write(cprman, CM_OSCCOUNT, osccount);

	/* do a kind delay at the start */
	mdelay(1);

	/* Finish off whatever is left of OSCCOUNT */
	timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
	while (cprman_read(cprman, CM_OSCCOUNT)) {
		if (ktime_after(ktime_get(), timeout)) {
			dev_err(cprman->dev, "timeout waiting for OSCCOUNT\n");
			count = 0;
			goto out;
		}
		cpu_relax();
	}

	/* Wait for BUSY to clear. */
	timeout = ktime_add_ns(ktime_get(), LOCK_TIMEOUT_NS);
	while (cprman_read(cprman, CM_TCNTCTL) & CM_BUSY) {
		if (ktime_after(ktime_get(), timeout)) {
			dev_err(cprman->dev, "timeout waiting for !BUSY\n");
			count = 0;
			goto out;
		}
		cpu_relax();
	}

	count = cprman_read(cprman, CM_TCNTCNT);

	cprman_write(cprman, CM_TCNTCTL, 0);

out:
	spin_unlock(&cprman->regs_lock);

	return count * 1000;
}

static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
				  struct debugfs_reg32 *regs, size_t nregs,
				  struct dentry *dentry)
@@ -428,6 +506,7 @@ struct bcm2835_pll_divider_data {
	u32 load_mask;
	u32 hold_mask;
	u32 fixed_divider;
	u32 flags;
};

struct bcm2835_clock_data {
@@ -451,6 +530,8 @@ struct bcm2835_clock_data {

	bool is_vpu_clock;
	bool is_mash_clock;

	u32 tcnt_mux;
};

struct bcm2835_gate_data {
@@ -906,6 +987,9 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
	const struct bcm2835_clock_data *data = clock->data;
	u64 temp;

	if (data->int_bits == 0 && data->frac_bits == 0)
		return parent_rate;

	/*
	 * The divisor is a 12.12 fixed point field, but only some of
	 * the bits are populated in any given clock.
@@ -929,7 +1013,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw,
	struct bcm2835_clock *clock = bcm2835_clock_from_hw(hw);
	struct bcm2835_cprman *cprman = clock->cprman;
	const struct bcm2835_clock_data *data = clock->data;
	u32 div = cprman_read(cprman, data->div_reg);
	u32 div;

	if (data->int_bits == 0 && data->frac_bits == 0)
		return parent_rate;

	div = cprman_read(cprman, data->div_reg);

	return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
}
@@ -978,6 +1067,17 @@ static int bcm2835_clock_on(struct clk_hw *hw)
		     CM_GATE);
	spin_unlock(&cprman->regs_lock);

	/* Debug code to measure the clock once it's turned on to see
	 * if it's ticking at the rate we expect.
	 */
	if (data->tcnt_mux && false) {
		dev_info(cprman->dev,
			 "clk %s: rate %ld, measure %ld\n",
			 data->name,
			 clk_hw_get_rate(hw),
			 bcm2835_measure_tcnt_mux(cprman, data->tcnt_mux));
	}

	return 0;
}

@@ -1208,7 +1308,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
	memset(&init, 0, sizeof(init));

	/* All of the PLLs derive from the external oscillator. */
	init.parent_names = &cprman->osc_name;
	init.parent_names = &cprman->real_parent_names[0];
	init.num_parents = 1;
	init.name = data->name;
	init.ops = &bcm2835_pll_clk_ops;
@@ -1252,7 +1352,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
	init.num_parents = 1;
	init.name = divider_name;
	init.ops = &bcm2835_pll_divider_clk_ops;
	init.flags = CLK_SET_RATE_PARENT | CLK_IGNORE_UNUSED;
	init.flags = data->flags | CLK_IGNORE_UNUSED;

	divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL);
	if (!divider)
@@ -1294,18 +1394,22 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
	struct bcm2835_clock *clock;
	struct clk_init_data init;
	const char *parents[1 << CM_SRC_BITS];
	size_t i;
	size_t i, j;
	int ret;

	/*
	 * Replace our "xosc" references with the oscillator's
	 * actual name.
	 * Replace our strings referencing parent clocks with the
	 * actual clock-output-name of the parent.
	 */
	for (i = 0; i < data->num_mux_parents; i++) {
		if (strcmp(data->parents[i], "xosc") == 0)
			parents[i] = cprman->osc_name;
		else
		parents[i] = data->parents[i];

		for (j = 0; j < ARRAY_SIZE(cprman_parent_names); j++) {
			if (strcmp(parents[i], cprman_parent_names[j]) == 0) {
				parents[i] = cprman->real_parent_names[j];
				break;
			}
		}
	}

	memset(&init, 0, sizeof(init));
@@ -1431,6 +1535,47 @@ static const char *const bcm2835_clock_vpu_parents[] = {
	.parents = bcm2835_clock_vpu_parents,				\
	__VA_ARGS__)

/*
 * DSI parent clocks.  The DSI byte/DDR/DDR2 clocks come from the DSI
 * analog PHY.  The _inv variants are generated internally to cprman,
 * but we don't use them so they aren't hooked up.
 */
static const char *const bcm2835_clock_dsi0_parents[] = {
	"gnd",
	"xosc",
	"testdebug0",
	"testdebug1",
	"dsi0_ddr",
	"dsi0_ddr_inv",
	"dsi0_ddr2",
	"dsi0_ddr2_inv",
	"dsi0_byte",
	"dsi0_byte_inv",
};

static const char *const bcm2835_clock_dsi1_parents[] = {
	"gnd",
	"xosc",
	"testdebug0",
	"testdebug1",
	"dsi1_ddr",
	"dsi1_ddr_inv",
	"dsi1_ddr2",
	"dsi1_ddr2_inv",
	"dsi1_byte",
	"dsi1_byte_inv",
};

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

#define REGISTER_DSI1_CLK(...)	REGISTER_CLK(				\
	.num_mux_parents = ARRAY_SIZE(bcm2835_clock_dsi1_parents),	\
	.parents = bcm2835_clock_dsi1_parents,				\
	__VA_ARGS__)

/*
 * the real definition of all the pll, pll_dividers and clocks
 * these make use of the above REGISTER_* macros
@@ -1466,7 +1611,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLA_CORE,
		.load_mask = CM_PLLA_LOADCORE,
		.hold_mask = CM_PLLA_HOLDCORE,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLA_PER]	= REGISTER_PLL_DIV(
		.name = "plla_per",
		.source_pll = "plla",
@@ -1474,7 +1620,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLA_PER,
		.load_mask = CM_PLLA_LOADPER,
		.hold_mask = CM_PLLA_HOLDPER,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLA_DSI0]	= REGISTER_PLL_DIV(
		.name = "plla_dsi0",
		.source_pll = "plla",
@@ -1490,7 +1637,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLA_CCP2,
		.load_mask = CM_PLLA_LOADCCP2,
		.hold_mask = CM_PLLA_HOLDCCP2,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),

	/* PLLB is used for the ARM's clock. */
	[BCM2835_PLLB]		= REGISTER_PLL(
@@ -1514,7 +1662,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLB_ARM,
		.load_mask = CM_PLLB_LOADARM,
		.hold_mask = CM_PLLB_HOLDARM,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),

	/*
	 * PLLC is the core PLL, used to drive the core VPU clock.
@@ -1543,7 +1692,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLC_CORE0,
		.load_mask = CM_PLLC_LOADCORE0,
		.hold_mask = CM_PLLC_HOLDCORE0,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLC_CORE1]	= REGISTER_PLL_DIV(
		.name = "pllc_core1",
		.source_pll = "pllc",
@@ -1551,7 +1701,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLC_CORE1,
		.load_mask = CM_PLLC_LOADCORE1,
		.hold_mask = CM_PLLC_HOLDCORE1,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLC_CORE2]	= REGISTER_PLL_DIV(
		.name = "pllc_core2",
		.source_pll = "pllc",
@@ -1559,7 +1710,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLC_CORE2,
		.load_mask = CM_PLLC_LOADCORE2,
		.hold_mask = CM_PLLC_HOLDCORE2,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLC_PER]	= REGISTER_PLL_DIV(
		.name = "pllc_per",
		.source_pll = "pllc",
@@ -1567,7 +1719,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLC_PER,
		.load_mask = CM_PLLC_LOADPER,
		.hold_mask = CM_PLLC_HOLDPER,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),

	/*
	 * PLLD is the display PLL, used to drive DSI display panels.
@@ -1596,7 +1749,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLD_CORE,
		.load_mask = CM_PLLD_LOADCORE,
		.hold_mask = CM_PLLD_HOLDCORE,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLD_PER]	= REGISTER_PLL_DIV(
		.name = "plld_per",
		.source_pll = "plld",
@@ -1604,7 +1758,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLD_PER,
		.load_mask = CM_PLLD_LOADPER,
		.hold_mask = CM_PLLD_HOLDPER,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLD_DSI0]	= REGISTER_PLL_DIV(
		.name = "plld_dsi0",
		.source_pll = "plld",
@@ -1649,7 +1804,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLH_RCAL,
		.load_mask = CM_PLLH_LOADRCAL,
		.hold_mask = 0,
		.fixed_divider = 10),
		.fixed_divider = 10,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLH_AUX]	= REGISTER_PLL_DIV(
		.name = "pllh_aux",
		.source_pll = "pllh",
@@ -1657,7 +1813,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLH_AUX,
		.load_mask = CM_PLLH_LOADAUX,
		.hold_mask = 0,
		.fixed_divider = 1),
		.fixed_divider = 1,
		.flags = CLK_SET_RATE_PARENT),
	[BCM2835_PLLH_PIX]	= REGISTER_PLL_DIV(
		.name = "pllh_pix",
		.source_pll = "pllh",
@@ -1665,7 +1822,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.a2w_reg = A2W_PLLH_PIX,
		.load_mask = CM_PLLH_LOADPIX,
		.hold_mask = 0,
		.fixed_divider = 10),
		.fixed_divider = 10,
		.flags = CLK_SET_RATE_PARENT),

	/* the clocks */

@@ -1677,7 +1835,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.ctl_reg = CM_OTPCTL,
		.div_reg = CM_OTPDIV,
		.int_bits = 4,
		.frac_bits = 0),
		.frac_bits = 0,
		.tcnt_mux = 6),
	/*
	 * Used for a 1Mhz clock for the system clocksource, and also used
	 * bythe watchdog timer and the camera pulse generator.
@@ -1711,13 +1870,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.ctl_reg = CM_H264CTL,
		.div_reg = CM_H264DIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 1),
	[BCM2835_CLOCK_ISP]	= REGISTER_VPU_CLK(
		.name = "isp",
		.ctl_reg = CM_ISPCTL,
		.div_reg = CM_ISPDIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 2),

	/*
	 * Secondary SDRAM clock.  Used for low-voltage modes when the PLL
@@ -1728,13 +1889,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.ctl_reg = CM_SDCCTL,
		.div_reg = CM_SDCDIV,
		.int_bits = 6,
		.frac_bits = 0),
		.frac_bits = 0,
		.tcnt_mux = 3),
	[BCM2835_CLOCK_V3D]	= REGISTER_VPU_CLK(
		.name = "v3d",
		.ctl_reg = CM_V3DCTL,
		.div_reg = CM_V3DDIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 4),
	/*
	 * VPU clock.  This doesn't have an enable bit, since it drives
	 * the bus for everything else, and is special so it doesn't need
@@ -1748,7 +1911,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.int_bits = 12,
		.frac_bits = 8,
		.flags = CLK_IS_CRITICAL,
		.is_vpu_clock = true),
		.is_vpu_clock = true,
		.tcnt_mux = 5),

	/* clocks with per parent mux */
	[BCM2835_CLOCK_AVEO]	= REGISTER_PER_CLK(
@@ -1756,19 +1920,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.ctl_reg = CM_AVEOCTL,
		.div_reg = CM_AVEODIV,
		.int_bits = 4,
		.frac_bits = 0),
		.frac_bits = 0,
		.tcnt_mux = 38),
	[BCM2835_CLOCK_CAM0]	= REGISTER_PER_CLK(
		.name = "cam0",
		.ctl_reg = CM_CAM0CTL,
		.div_reg = CM_CAM0DIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 14),
	[BCM2835_CLOCK_CAM1]	= REGISTER_PER_CLK(
		.name = "cam1",
		.ctl_reg = CM_CAM1CTL,
		.div_reg = CM_CAM1DIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 15),
	[BCM2835_CLOCK_DFT]	= REGISTER_PER_CLK(
		.name = "dft",
		.ctl_reg = CM_DFTCTL,
@@ -1780,7 +1947,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.ctl_reg = CM_DPICTL,
		.div_reg = CM_DPIDIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 17),

	/* Arasan EMMC clock */
	[BCM2835_CLOCK_EMMC]	= REGISTER_PER_CLK(
@@ -1788,7 +1956,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.ctl_reg = CM_EMMCCTL,
		.div_reg = CM_EMMCDIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 39),

	/* General purpose (GPIO) clocks */
	[BCM2835_CLOCK_GP0]	= REGISTER_PER_CLK(
@@ -1797,7 +1966,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.div_reg = CM_GP0DIV,
		.int_bits = 12,
		.frac_bits = 12,
		.is_mash_clock = true),
		.is_mash_clock = true,
		.tcnt_mux = 20),
	[BCM2835_CLOCK_GP1]	= REGISTER_PER_CLK(
		.name = "gp1",
		.ctl_reg = CM_GP1CTL,
@@ -1805,7 +1975,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.int_bits = 12,
		.frac_bits = 12,
		.flags = CLK_IS_CRITICAL,
		.is_mash_clock = true),
		.is_mash_clock = true,
		.tcnt_mux = 21),
	[BCM2835_CLOCK_GP2]	= REGISTER_PER_CLK(
		.name = "gp2",
		.ctl_reg = CM_GP2CTL,
@@ -1820,40 +1991,46 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.ctl_reg = CM_HSMCTL,
		.div_reg = CM_HSMDIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 22),
	[BCM2835_CLOCK_PCM]	= REGISTER_PER_CLK(
		.name = "pcm",
		.ctl_reg = CM_PCMCTL,
		.div_reg = CM_PCMDIV,
		.int_bits = 12,
		.frac_bits = 12,
		.is_mash_clock = true),
		.is_mash_clock = true,
		.tcnt_mux = 23),
	[BCM2835_CLOCK_PWM]	= REGISTER_PER_CLK(
		.name = "pwm",
		.ctl_reg = CM_PWMCTL,
		.div_reg = CM_PWMDIV,
		.int_bits = 12,
		.frac_bits = 12,
		.is_mash_clock = true),
		.is_mash_clock = true,
		.tcnt_mux = 24),
	[BCM2835_CLOCK_SLIM]	= REGISTER_PER_CLK(
		.name = "slim",
		.ctl_reg = CM_SLIMCTL,
		.div_reg = CM_SLIMDIV,
		.int_bits = 12,
		.frac_bits = 12,
		.is_mash_clock = true),
		.is_mash_clock = true,
		.tcnt_mux = 25),
	[BCM2835_CLOCK_SMI]	= REGISTER_PER_CLK(
		.name = "smi",
		.ctl_reg = CM_SMICTL,
		.div_reg = CM_SMIDIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 27),
	[BCM2835_CLOCK_UART]	= REGISTER_PER_CLK(
		.name = "uart",
		.ctl_reg = CM_UARTCTL,
		.div_reg = CM_UARTDIV,
		.int_bits = 10,
		.frac_bits = 12),
		.frac_bits = 12,
		.tcnt_mux = 28),

	/* TV encoder clock.  Only operating frequency is 108Mhz.  */
	[BCM2835_CLOCK_VEC]	= REGISTER_PER_CLK(
@@ -1866,7 +2043,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		 * Allow rate change propagation only on PLLH_AUX which is
		 * assigned index 7 in the parent array.
		 */
		.set_rate_parent = BIT(7)),
		.set_rate_parent = BIT(7),
		.tcnt_mux = 29),

	/* dsi clocks */
	[BCM2835_CLOCK_DSI0E]	= REGISTER_PER_CLK(
@@ -1874,13 +2052,29 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
		.ctl_reg = CM_DSI0ECTL,
		.div_reg = CM_DSI0EDIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 18),
	[BCM2835_CLOCK_DSI1E]	= REGISTER_PER_CLK(
		.name = "dsi1e",
		.ctl_reg = CM_DSI1ECTL,
		.div_reg = CM_DSI1EDIV,
		.int_bits = 4,
		.frac_bits = 8),
		.frac_bits = 8,
		.tcnt_mux = 19),
	[BCM2835_CLOCK_DSI0P]	= REGISTER_DSI0_CLK(
		.name = "dsi0p",
		.ctl_reg = CM_DSI0PCTL,
		.div_reg = CM_DSI0PDIV,
		.int_bits = 0,
		.frac_bits = 0,
		.tcnt_mux = 12),
	[BCM2835_CLOCK_DSI1P]	= REGISTER_DSI1_CLK(
		.name = "dsi1p",
		.ctl_reg = CM_DSI1PCTL,
		.div_reg = CM_DSI1PDIV,
		.int_bits = 0,
		.frac_bits = 0,
		.tcnt_mux = 13),

	/* the gates */

@@ -1939,8 +2133,19 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
	if (IS_ERR(cprman->regs))
		return PTR_ERR(cprman->regs);

	cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0);
	if (!cprman->osc_name)
	memcpy(cprman->real_parent_names, cprman_parent_names,
	       sizeof(cprman_parent_names));
	of_clk_parent_fill(dev->of_node, cprman->real_parent_names,
			   ARRAY_SIZE(cprman_parent_names));

	/*
	 * Make sure the external oscillator has been registered.
	 *
	 * The other (DSI) clocks are not present on older device
	 * trees, which we still need to support for backwards
	 * compatibility.
	 */
	if (!cprman->real_parent_names[0])
		return -ENODEV;

	platform_set_drvdata(pdev, cprman);
+1 −0
Original line number Diff line number Diff line
@@ -803,6 +803,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node)
	clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
	clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
	clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
	clks[IMX7D_OCOTP_CLK] = imx_clk_gate4("ocotp_clk", "ipg_root_clk", base + 0x4230, 0);
	clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
	clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
	clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
+2 −0
Original line number Diff line number Diff line
@@ -64,3 +64,5 @@
#define BCM2835_CLOCK_CAM1		46
#define BCM2835_CLOCK_DSI0E		47
#define BCM2835_CLOCK_DSI1E		48
#define BCM2835_CLOCK_DSI0P		49
#define BCM2835_CLOCK_DSI1P		50
+2 −1
Original line number Diff line number Diff line
@@ -449,5 +449,6 @@
#define IMX7D_ADC_ROOT_CLK		436
#define IMX7D_CLK_ARM			437
#define IMX7D_CKIL			438
#define IMX7D_CLK_END			439
#define IMX7D_OCOTP_CLK			439
#define IMX7D_CLK_END			440
#endif /* __DT_BINDINGS_CLOCK_IMX7D_H */