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

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.
......@@ -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:
......
......@@ -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];
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);
......
......@@ -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);
......
......@@ -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
......@@ -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 */
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