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: ...@@ -16,7 +16,20 @@ Required properties:
- #clock-cells: Should be <1>. The permitted clock-specifier values can be - #clock-cells: Should be <1>. The permitted clock-specifier values can be
found in include/dt-bindings/clock/bcm2835.h found in include/dt-bindings/clock/bcm2835.h
- reg: Specifies base physical address and size of the registers - 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: Example:
......
...@@ -39,6 +39,7 @@ ...@@ -39,6 +39,7 @@
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/clk/bcm2835.h> #include <linux/clk/bcm2835.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/module.h> #include <linux/module.h>
#include <linux/of.h> #include <linux/of.h>
#include <linux/platform_device.h> #include <linux/platform_device.h>
...@@ -98,7 +99,8 @@ ...@@ -98,7 +99,8 @@
#define CM_SMIDIV 0x0b4 #define CM_SMIDIV 0x0b4
/* no definition for 0x0b8 and 0x0bc */ /* no definition for 0x0b8 and 0x0bc */
#define CM_TCNTCTL 0x0c0 #define CM_TCNTCTL 0x0c0
#define CM_TCNTDIV 0x0c4 # define CM_TCNT_SRC1_SHIFT 12
#define CM_TCNTCNT 0x0c4
#define CM_TECCTL 0x0c8 #define CM_TECCTL 0x0c8
#define CM_TECDIV 0x0cc #define CM_TECDIV 0x0cc
#define CM_TD0CTL 0x0d0 #define CM_TD0CTL 0x0d0
...@@ -297,11 +299,32 @@ ...@@ -297,11 +299,32 @@
#define LOCK_TIMEOUT_NS 100000000 #define LOCK_TIMEOUT_NS 100000000
#define BCM2835_MAX_FB_RATE 1750000000u #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 bcm2835_cprman {
struct device *dev; struct device *dev;
void __iomem *regs; void __iomem *regs;
spinlock_t regs_lock; /* spinlock for all clocks */ 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 */ /* Must be last */
struct clk_hw_onecell_data onecell; struct clk_hw_onecell_data onecell;
...@@ -317,6 +340,61 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg) ...@@ -317,6 +340,61 @@ static inline u32 cprman_read(struct bcm2835_cprman *cprman, u32 reg)
return readl(cprman->regs + 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, static int bcm2835_debugfs_regset(struct bcm2835_cprman *cprman, u32 base,
struct debugfs_reg32 *regs, size_t nregs, struct debugfs_reg32 *regs, size_t nregs,
struct dentry *dentry) struct dentry *dentry)
...@@ -428,6 +506,7 @@ struct bcm2835_pll_divider_data { ...@@ -428,6 +506,7 @@ struct bcm2835_pll_divider_data {
u32 load_mask; u32 load_mask;
u32 hold_mask; u32 hold_mask;
u32 fixed_divider; u32 fixed_divider;
u32 flags;
}; };
struct bcm2835_clock_data { struct bcm2835_clock_data {
...@@ -451,6 +530,8 @@ struct bcm2835_clock_data { ...@@ -451,6 +530,8 @@ struct bcm2835_clock_data {
bool is_vpu_clock; bool is_vpu_clock;
bool is_mash_clock; bool is_mash_clock;
u32 tcnt_mux;
}; };
struct bcm2835_gate_data { struct bcm2835_gate_data {
...@@ -906,6 +987,9 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock, ...@@ -906,6 +987,9 @@ static long bcm2835_clock_rate_from_divisor(struct bcm2835_clock *clock,
const struct bcm2835_clock_data *data = clock->data; const struct bcm2835_clock_data *data = clock->data;
u64 temp; 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 divisor is a 12.12 fixed point field, but only some of
* the bits are populated in any given clock. * the bits are populated in any given clock.
...@@ -929,7 +1013,12 @@ static unsigned long bcm2835_clock_get_rate(struct clk_hw *hw, ...@@ -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_clock *clock = bcm2835_clock_from_hw(hw);
struct bcm2835_cprman *cprman = clock->cprman; struct bcm2835_cprman *cprman = clock->cprman;
const struct bcm2835_clock_data *data = clock->data; 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); return bcm2835_clock_rate_from_divisor(clock, parent_rate, div);
} }
...@@ -978,6 +1067,17 @@ static int bcm2835_clock_on(struct clk_hw *hw) ...@@ -978,6 +1067,17 @@ static int bcm2835_clock_on(struct clk_hw *hw)
CM_GATE); CM_GATE);
spin_unlock(&cprman->regs_lock); 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; return 0;
} }
...@@ -1208,7 +1308,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman, ...@@ -1208,7 +1308,7 @@ static struct clk_hw *bcm2835_register_pll(struct bcm2835_cprman *cprman,
memset(&init, 0, sizeof(init)); memset(&init, 0, sizeof(init));
/* All of the PLLs derive from the external oscillator. */ /* 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.num_parents = 1;
init.name = data->name; init.name = data->name;
init.ops = &bcm2835_pll_clk_ops; init.ops = &bcm2835_pll_clk_ops;
...@@ -1252,7 +1352,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman, ...@@ -1252,7 +1352,7 @@ bcm2835_register_pll_divider(struct bcm2835_cprman *cprman,
init.num_parents = 1; init.num_parents = 1;
init.name = divider_name; init.name = divider_name;
init.ops = &bcm2835_pll_divider_clk_ops; 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); divider = devm_kzalloc(cprman->dev, sizeof(*divider), GFP_KERNEL);
if (!divider) if (!divider)
...@@ -1294,18 +1394,22 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman, ...@@ -1294,18 +1394,22 @@ static struct clk_hw *bcm2835_register_clock(struct bcm2835_cprman *cprman,
struct bcm2835_clock *clock; struct bcm2835_clock *clock;
struct clk_init_data init; struct clk_init_data init;
const char *parents[1 << CM_SRC_BITS]; const char *parents[1 << CM_SRC_BITS];
size_t i; size_t i, j;
int ret; int ret;
/* /*
* Replace our "xosc" references with the oscillator's * Replace our strings referencing parent clocks with the
* actual name. * actual clock-output-name of the parent.
*/ */
for (i = 0; i < data->num_mux_parents; i++) { for (i = 0; i < data->num_mux_parents; i++) {
if (strcmp(data->parents[i], "xosc") == 0) parents[i] = data->parents[i];
parents[i] = cprman->osc_name;
else for (j = 0; j < ARRAY_SIZE(cprman_parent_names); j++) {
parents[i] = data->parents[i]; if (strcmp(parents[i], cprman_parent_names[j]) == 0) {
parents[i] = cprman->real_parent_names[j];
break;
}
}
} }
memset(&init, 0, sizeof(init)); memset(&init, 0, sizeof(init));
...@@ -1431,6 +1535,47 @@ static const char *const bcm2835_clock_vpu_parents[] = { ...@@ -1431,6 +1535,47 @@ static const char *const bcm2835_clock_vpu_parents[] = {
.parents = bcm2835_clock_vpu_parents, \ .parents = bcm2835_clock_vpu_parents, \
__VA_ARGS__) __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 * the real definition of all the pll, pll_dividers and clocks
* these make use of the above REGISTER_* macros * these make use of the above REGISTER_* macros
...@@ -1466,7 +1611,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1466,7 +1611,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLA_CORE, .a2w_reg = A2W_PLLA_CORE,
.load_mask = CM_PLLA_LOADCORE, .load_mask = CM_PLLA_LOADCORE,
.hold_mask = CM_PLLA_HOLDCORE, .hold_mask = CM_PLLA_HOLDCORE,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLA_PER] = REGISTER_PLL_DIV( [BCM2835_PLLA_PER] = REGISTER_PLL_DIV(
.name = "plla_per", .name = "plla_per",
.source_pll = "plla", .source_pll = "plla",
...@@ -1474,7 +1620,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1474,7 +1620,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLA_PER, .a2w_reg = A2W_PLLA_PER,
.load_mask = CM_PLLA_LOADPER, .load_mask = CM_PLLA_LOADPER,
.hold_mask = CM_PLLA_HOLDPER, .hold_mask = CM_PLLA_HOLDPER,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV( [BCM2835_PLLA_DSI0] = REGISTER_PLL_DIV(
.name = "plla_dsi0", .name = "plla_dsi0",
.source_pll = "plla", .source_pll = "plla",
...@@ -1490,7 +1637,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1490,7 +1637,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLA_CCP2, .a2w_reg = A2W_PLLA_CCP2,
.load_mask = CM_PLLA_LOADCCP2, .load_mask = CM_PLLA_LOADCCP2,
.hold_mask = CM_PLLA_HOLDCCP2, .hold_mask = CM_PLLA_HOLDCCP2,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
/* PLLB is used for the ARM's clock. */ /* PLLB is used for the ARM's clock. */
[BCM2835_PLLB] = REGISTER_PLL( [BCM2835_PLLB] = REGISTER_PLL(
...@@ -1514,7 +1662,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1514,7 +1662,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLB_ARM, .a2w_reg = A2W_PLLB_ARM,
.load_mask = CM_PLLB_LOADARM, .load_mask = CM_PLLB_LOADARM,
.hold_mask = CM_PLLB_HOLDARM, .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. * 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[] = { ...@@ -1543,7 +1692,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLC_CORE0, .a2w_reg = A2W_PLLC_CORE0,
.load_mask = CM_PLLC_LOADCORE0, .load_mask = CM_PLLC_LOADCORE0,
.hold_mask = CM_PLLC_HOLDCORE0, .hold_mask = CM_PLLC_HOLDCORE0,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV( [BCM2835_PLLC_CORE1] = REGISTER_PLL_DIV(
.name = "pllc_core1", .name = "pllc_core1",
.source_pll = "pllc", .source_pll = "pllc",
...@@ -1551,7 +1701,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1551,7 +1701,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLC_CORE1, .a2w_reg = A2W_PLLC_CORE1,
.load_mask = CM_PLLC_LOADCORE1, .load_mask = CM_PLLC_LOADCORE1,
.hold_mask = CM_PLLC_HOLDCORE1, .hold_mask = CM_PLLC_HOLDCORE1,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV( [BCM2835_PLLC_CORE2] = REGISTER_PLL_DIV(
.name = "pllc_core2", .name = "pllc_core2",
.source_pll = "pllc", .source_pll = "pllc",
...@@ -1559,7 +1710,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1559,7 +1710,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLC_CORE2, .a2w_reg = A2W_PLLC_CORE2,
.load_mask = CM_PLLC_LOADCORE2, .load_mask = CM_PLLC_LOADCORE2,
.hold_mask = CM_PLLC_HOLDCORE2, .hold_mask = CM_PLLC_HOLDCORE2,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLC_PER] = REGISTER_PLL_DIV( [BCM2835_PLLC_PER] = REGISTER_PLL_DIV(
.name = "pllc_per", .name = "pllc_per",
.source_pll = "pllc", .source_pll = "pllc",
...@@ -1567,7 +1719,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1567,7 +1719,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLC_PER, .a2w_reg = A2W_PLLC_PER,
.load_mask = CM_PLLC_LOADPER, .load_mask = CM_PLLC_LOADPER,
.hold_mask = CM_PLLC_HOLDPER, .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. * PLLD is the display PLL, used to drive DSI display panels.
...@@ -1596,7 +1749,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1596,7 +1749,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLD_CORE, .a2w_reg = A2W_PLLD_CORE,
.load_mask = CM_PLLD_LOADCORE, .load_mask = CM_PLLD_LOADCORE,
.hold_mask = CM_PLLD_HOLDCORE, .hold_mask = CM_PLLD_HOLDCORE,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLD_PER] = REGISTER_PLL_DIV( [BCM2835_PLLD_PER] = REGISTER_PLL_DIV(
.name = "plld_per", .name = "plld_per",
.source_pll = "plld", .source_pll = "plld",
...@@ -1604,7 +1758,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1604,7 +1758,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLD_PER, .a2w_reg = A2W_PLLD_PER,
.load_mask = CM_PLLD_LOADPER, .load_mask = CM_PLLD_LOADPER,
.hold_mask = CM_PLLD_HOLDPER, .hold_mask = CM_PLLD_HOLDPER,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV( [BCM2835_PLLD_DSI0] = REGISTER_PLL_DIV(
.name = "plld_dsi0", .name = "plld_dsi0",
.source_pll = "plld", .source_pll = "plld",
...@@ -1649,7 +1804,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1649,7 +1804,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLH_RCAL, .a2w_reg = A2W_PLLH_RCAL,
.load_mask = CM_PLLH_LOADRCAL, .load_mask = CM_PLLH_LOADRCAL,
.hold_mask = 0, .hold_mask = 0,
.fixed_divider = 10), .fixed_divider = 10,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLH_AUX] = REGISTER_PLL_DIV( [BCM2835_PLLH_AUX] = REGISTER_PLL_DIV(
.name = "pllh_aux", .name = "pllh_aux",
.source_pll = "pllh", .source_pll = "pllh",
...@@ -1657,7 +1813,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1657,7 +1813,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLH_AUX, .a2w_reg = A2W_PLLH_AUX,
.load_mask = CM_PLLH_LOADAUX, .load_mask = CM_PLLH_LOADAUX,
.hold_mask = 0, .hold_mask = 0,
.fixed_divider = 1), .fixed_divider = 1,
.flags = CLK_SET_RATE_PARENT),
[BCM2835_PLLH_PIX] = REGISTER_PLL_DIV( [BCM2835_PLLH_PIX] = REGISTER_PLL_DIV(
.name = "pllh_pix", .name = "pllh_pix",
.source_pll = "pllh", .source_pll = "pllh",
...@@ -1665,7 +1822,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1665,7 +1822,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.a2w_reg = A2W_PLLH_PIX, .a2w_reg = A2W_PLLH_PIX,
.load_mask = CM_PLLH_LOADPIX, .load_mask = CM_PLLH_LOADPIX,
.hold_mask = 0, .hold_mask = 0,
.fixed_divider = 10), .fixed_divider = 10,
.flags = CLK_SET_RATE_PARENT),
/* the clocks */ /* the clocks */
...@@ -1677,7 +1835,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1677,7 +1835,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_OTPCTL, .ctl_reg = CM_OTPCTL,
.div_reg = CM_OTPDIV, .div_reg = CM_OTPDIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 0), .frac_bits = 0,
.tcnt_mux = 6),
/* /*
* Used for a 1Mhz clock for the system clocksource, and also used * Used for a 1Mhz clock for the system clocksource, and also used
* bythe watchdog timer and the camera pulse generator. * bythe watchdog timer and the camera pulse generator.
...@@ -1711,13 +1870,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1711,13 +1870,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_H264CTL, .ctl_reg = CM_H264CTL,
.div_reg = CM_H264DIV, .div_reg = CM_H264DIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 1),
[BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK( [BCM2835_CLOCK_ISP] = REGISTER_VPU_CLK(
.name = "isp", .name = "isp",
.ctl_reg = CM_ISPCTL, .ctl_reg = CM_ISPCTL,
.div_reg = CM_ISPDIV, .div_reg = CM_ISPDIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 2),
/* /*
* Secondary SDRAM clock. Used for low-voltage modes when the PLL * Secondary SDRAM clock. Used for low-voltage modes when the PLL
...@@ -1728,13 +1889,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1728,13 +1889,15 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_SDCCTL, .ctl_reg = CM_SDCCTL,
.div_reg = CM_SDCDIV, .div_reg = CM_SDCDIV,
.int_bits = 6, .int_bits = 6,
.frac_bits = 0), .frac_bits = 0,
.tcnt_mux = 3),
[BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK( [BCM2835_CLOCK_V3D] = REGISTER_VPU_CLK(
.name = "v3d", .name = "v3d",
.ctl_reg = CM_V3DCTL, .ctl_reg = CM_V3DCTL,
.div_reg = CM_V3DDIV, .div_reg = CM_V3DDIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 4),
/* /*
* VPU clock. This doesn't have an enable bit, since it drives * 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 * 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[] = { ...@@ -1748,7 +1911,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.int_bits = 12, .int_bits = 12,
.frac_bits = 8, .frac_bits = 8,
.flags = CLK_IS_CRITICAL, .flags = CLK_IS_CRITICAL,
.is_vpu_clock = true), .is_vpu_clock = true,
.tcnt_mux = 5),
/* clocks with per parent mux */ /* clocks with per parent mux */
[BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK( [BCM2835_CLOCK_AVEO] = REGISTER_PER_CLK(
...@@ -1756,19 +1920,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1756,19 +1920,22 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_AVEOCTL, .ctl_reg = CM_AVEOCTL,
.div_reg = CM_AVEODIV, .div_reg = CM_AVEODIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 0), .frac_bits = 0,
.tcnt_mux = 38),
[BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK( [BCM2835_CLOCK_CAM0] = REGISTER_PER_CLK(
.name = "cam0", .name = "cam0",
.ctl_reg = CM_CAM0CTL, .ctl_reg = CM_CAM0CTL,
.div_reg = CM_CAM0DIV, .div_reg = CM_CAM0DIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 14),
[BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK( [BCM2835_CLOCK_CAM1] = REGISTER_PER_CLK(
.name = "cam1", .name = "cam1",
.ctl_reg = CM_CAM1CTL, .ctl_reg = CM_CAM1CTL,
.div_reg = CM_CAM1DIV, .div_reg = CM_CAM1DIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 15),
[BCM2835_CLOCK_DFT] = REGISTER_PER_CLK( [BCM2835_CLOCK_DFT] = REGISTER_PER_CLK(
.name = "dft", .name = "dft",
.ctl_reg = CM_DFTCTL, .ctl_reg = CM_DFTCTL,
...@@ -1780,7 +1947,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1780,7 +1947,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_DPICTL, .ctl_reg = CM_DPICTL,
.div_reg = CM_DPIDIV, .div_reg = CM_DPIDIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 17),
/* Arasan EMMC clock */ /* Arasan EMMC clock */
[BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK( [BCM2835_CLOCK_EMMC] = REGISTER_PER_CLK(
...@@ -1788,7 +1956,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1788,7 +1956,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_EMMCCTL, .ctl_reg = CM_EMMCCTL,
.div_reg = CM_EMMCDIV, .div_reg = CM_EMMCDIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 39),
/* General purpose (GPIO) clocks */ /* General purpose (GPIO) clocks */
[BCM2835_CLOCK_GP0] = REGISTER_PER_CLK( [BCM2835_CLOCK_GP0] = REGISTER_PER_CLK(
...@@ -1797,7 +1966,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1797,7 +1966,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.div_reg = CM_GP0DIV, .div_reg = CM_GP0DIV,
.int_bits = 12, .int_bits = 12,
.frac_bits = 12, .frac_bits = 12,
.is_mash_clock = true), .is_mash_clock = true,
.tcnt_mux = 20),
[BCM2835_CLOCK_GP1] = REGISTER_PER_CLK( [BCM2835_CLOCK_GP1] = REGISTER_PER_CLK(
.name = "gp1", .name = "gp1",
.ctl_reg = CM_GP1CTL, .ctl_reg = CM_GP1CTL,
...@@ -1805,7 +1975,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1805,7 +1975,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.int_bits = 12, .int_bits = 12,
.frac_bits = 12, .frac_bits = 12,
.flags = CLK_IS_CRITICAL, .flags = CLK_IS_CRITICAL,
.is_mash_clock = true), .is_mash_clock = true,
.tcnt_mux = 21),
[BCM2835_CLOCK_GP2] = REGISTER_PER_CLK( [BCM2835_CLOCK_GP2] = REGISTER_PER_CLK(
.name = "gp2", .name = "gp2",
.ctl_reg = CM_GP2CTL, .ctl_reg = CM_GP2CTL,
...@@ -1820,40 +1991,46 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1820,40 +1991,46 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_HSMCTL, .ctl_reg = CM_HSMCTL,
.div_reg = CM_HSMDIV, .div_reg = CM_HSMDIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 22),
[BCM2835_CLOCK_PCM] = REGISTER_PER_CLK( [BCM2835_CLOCK_PCM] = REGISTER_PER_CLK(
.name = "pcm", .name = "pcm",
.ctl_reg = CM_PCMCTL, .ctl_reg = CM_PCMCTL,
.div_reg = CM_PCMDIV, .div_reg = CM_PCMDIV,
.int_bits = 12, .int_bits = 12,
.frac_bits = 12, .frac_bits = 12,
.is_mash_clock = true), .is_mash_clock = true,
.tcnt_mux = 23),
[BCM2835_CLOCK_PWM] = REGISTER_PER_CLK( [BCM2835_CLOCK_PWM] = REGISTER_PER_CLK(
.name = "pwm", .name = "pwm",
.ctl_reg = CM_PWMCTL, .ctl_reg = CM_PWMCTL,
.div_reg = CM_PWMDIV, .div_reg = CM_PWMDIV,
.int_bits = 12, .int_bits = 12,
.frac_bits = 12, .frac_bits = 12,
.is_mash_clock = true), .is_mash_clock = true,
.tcnt_mux = 24),
[BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK( [BCM2835_CLOCK_SLIM] = REGISTER_PER_CLK(
.name = "slim", .name = "slim",
.ctl_reg = CM_SLIMCTL, .ctl_reg = CM_SLIMCTL,
.div_reg = CM_SLIMDIV, .div_reg = CM_SLIMDIV,
.int_bits = 12, .int_bits = 12,
.frac_bits = 12, .frac_bits = 12,
.is_mash_clock = true), .is_mash_clock = true,
.tcnt_mux = 25),
[BCM2835_CLOCK_SMI] = REGISTER_PER_CLK( [BCM2835_CLOCK_SMI] = REGISTER_PER_CLK(
.name = "smi", .name = "smi",
.ctl_reg = CM_SMICTL, .ctl_reg = CM_SMICTL,
.div_reg = CM_SMIDIV, .div_reg = CM_SMIDIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 27),
[BCM2835_CLOCK_UART] = REGISTER_PER_CLK( [BCM2835_CLOCK_UART] = REGISTER_PER_CLK(
.name = "uart", .name = "uart",
.ctl_reg = CM_UARTCTL, .ctl_reg = CM_UARTCTL,
.div_reg = CM_UARTDIV, .div_reg = CM_UARTDIV,
.int_bits = 10, .int_bits = 10,
.frac_bits = 12), .frac_bits = 12,
.tcnt_mux = 28),
/* TV encoder clock. Only operating frequency is 108Mhz. */ /* TV encoder clock. Only operating frequency is 108Mhz. */
[BCM2835_CLOCK_VEC] = REGISTER_PER_CLK( [BCM2835_CLOCK_VEC] = REGISTER_PER_CLK(
...@@ -1866,7 +2043,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1866,7 +2043,8 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
* Allow rate change propagation only on PLLH_AUX which is * Allow rate change propagation only on PLLH_AUX which is
* assigned index 7 in the parent array. * assigned index 7 in the parent array.
*/ */
.set_rate_parent = BIT(7)), .set_rate_parent = BIT(7),
.tcnt_mux = 29),
/* dsi clocks */ /* dsi clocks */
[BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK( [BCM2835_CLOCK_DSI0E] = REGISTER_PER_CLK(
...@@ -1874,13 +2052,29 @@ static const struct bcm2835_clk_desc clk_desc_array[] = { ...@@ -1874,13 +2052,29 @@ static const struct bcm2835_clk_desc clk_desc_array[] = {
.ctl_reg = CM_DSI0ECTL, .ctl_reg = CM_DSI0ECTL,
.div_reg = CM_DSI0EDIV, .div_reg = CM_DSI0EDIV,
.int_bits = 4, .int_bits = 4,
.frac_bits = 8), .frac_bits = 8,
.tcnt_mux = 18),
[BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK( [BCM2835_CLOCK_DSI1E] = REGISTER_PER_CLK(
.name = "dsi1e", .name = "dsi1e",
.ctl_reg = CM_DSI1ECTL, .ctl_reg = CM_DSI1ECTL,
.div_reg = CM_DSI1EDIV, .div_reg = CM_DSI1EDIV,
.int_bits = 4, .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 */ /* the gates */
...@@ -1939,8 +2133,19 @@ static int bcm2835_clk_probe(struct platform_device *pdev) ...@@ -1939,8 +2133,19 @@ static int bcm2835_clk_probe(struct platform_device *pdev)
if (IS_ERR(cprman->regs)) if (IS_ERR(cprman->regs))
return PTR_ERR(cprman->regs); return PTR_ERR(cprman->regs);
cprman->osc_name = of_clk_get_parent_name(dev->of_node, 0); memcpy(cprman->real_parent_names, cprman_parent_names,
if (!cprman->osc_name) 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; return -ENODEV;
platform_set_drvdata(pdev, cprman); platform_set_drvdata(pdev, cprman);
......
...@@ -803,6 +803,7 @@ static void __init imx7d_clocks_init(struct device_node *ccm_node) ...@@ -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_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_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_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_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_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); clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
......
...@@ -64,3 +64,5 @@ ...@@ -64,3 +64,5 @@
#define BCM2835_CLOCK_CAM1 46 #define BCM2835_CLOCK_CAM1 46
#define BCM2835_CLOCK_DSI0E 47 #define BCM2835_CLOCK_DSI0E 47
#define BCM2835_CLOCK_DSI1E 48 #define BCM2835_CLOCK_DSI1E 48
#define BCM2835_CLOCK_DSI0P 49
#define BCM2835_CLOCK_DSI1P 50
...@@ -449,5 +449,6 @@ ...@@ -449,5 +449,6 @@
#define IMX7D_ADC_ROOT_CLK 436 #define IMX7D_ADC_ROOT_CLK 436
#define IMX7D_CLK_ARM 437 #define IMX7D_CLK_ARM 437
#define IMX7D_CKIL 438 #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 */ #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