diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/clk/clk-si5341.c | 212 | ||||
-rw-r--r-- | drivers/clk/clk.c | 125 | ||||
-rw-r--r-- | drivers/clk/meson/g12a.c | 129 | ||||
-rw-r--r-- | drivers/clk/meson/g12a.h | 6 | ||||
-rw-r--r-- | drivers/clk/meson/gxbb.c | 21 | ||||
-rw-r--r-- | drivers/clk/meson/gxbb.h | 2 | ||||
-rw-r--r-- | drivers/clk/meson/meson8b.c | 21 | ||||
-rw-r--r-- | drivers/clk/rockchip/clk-mmc-phase.c | 4 | ||||
-rw-r--r-- | drivers/clk/samsung/clk.c | 4 | ||||
-rw-r--r-- | drivers/clk/socfpga/clk-gate-s10.c | 40 | ||||
-rw-r--r-- | drivers/clk/socfpga/clk-periph-s10.c | 42 | ||||
-rw-r--r-- | drivers/clk/socfpga/clk-pll-s10.c | 17 | ||||
-rw-r--r-- | drivers/clk/socfpga/clk-s10.c | 29 | ||||
-rw-r--r-- | drivers/clk/socfpga/stratix10-clk.h | 25 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun50i-a64.h | 4 | ||||
-rw-r--r-- | drivers/clk/sunxi-ng/ccu-sun8i-de2.c | 115 |
16 files changed, 567 insertions, 229 deletions
diff --git a/drivers/clk/clk-si5341.c b/drivers/clk/clk-si5341.c index 6e780c2a9e6b..3c228b018116 100644 --- a/drivers/clk/clk-si5341.c +++ b/drivers/clk/clk-si5341.c @@ -16,6 +16,8 @@ #include <linux/slab.h> #include <asm/unaligned.h> +#define SI5341_NUM_INPUTS 4 + #define SI5341_MAX_NUM_OUTPUTS 10 #define SI5340_MAX_NUM_OUTPUTS 4 @@ -56,8 +58,8 @@ struct clk_si5341 { struct i2c_client *i2c_client; struct clk_si5341_synth synth[SI5341_NUM_SYNTH]; struct clk_si5341_output clk[SI5341_MAX_NUM_OUTPUTS]; - struct clk *pxtal; - const char *pxtal_name; + struct clk *input_clk[SI5341_NUM_INPUTS]; + const char *input_clk_name[SI5341_NUM_INPUTS]; const u16 *reg_output_offset; const u16 *reg_rdiv_offset; u64 freq_vco; /* 13500–14256 MHz */ @@ -78,10 +80,25 @@ struct clk_si5341_output_config { #define SI5341_DEVICE_REV 0x0005 #define SI5341_STATUS 0x000C #define SI5341_SOFT_RST 0x001C +#define SI5341_IN_SEL 0x0021 +#define SI5341_XAXB_CFG 0x090E +#define SI5341_IN_EN 0x0949 +#define SI5341_INX_TO_PFD_EN 0x094A + +/* Input selection */ +#define SI5341_IN_SEL_MASK 0x06 +#define SI5341_IN_SEL_SHIFT 1 +#define SI5341_IN_SEL_REGCTRL 0x01 +#define SI5341_INX_TO_PFD_SHIFT 4 + +/* XTAL config bits */ +#define SI5341_XAXB_CFG_EXTCLK_EN BIT(0) +#define SI5341_XAXB_CFG_PDNB BIT(1) /* Input dividers (48-bit) */ #define SI5341_IN_PDIV(x) (0x0208 + ((x) * 10)) #define SI5341_IN_PSET(x) (0x020E + ((x) * 10)) +#define SI5341_PX_UPD 0x0230 /* PLL configuration */ #define SI5341_PLL_M_NUM 0x0235 @@ -120,6 +137,10 @@ struct si5341_reg_default { u8 value; }; +static const char * const si5341_input_clock_names[] = { + "in0", "in1", "in2", "xtal" +}; + /* Output configuration registers 0..9 are not quite logically organized */ static const u16 si5341_reg_output_offset[] = { 0x0108, @@ -390,7 +411,112 @@ static unsigned long si5341_clk_recalc_rate(struct clk_hw *hw, return (unsigned long)res; } +static int si5341_clk_get_selected_input(struct clk_si5341 *data) +{ + int err; + u32 val; + + err = regmap_read(data->regmap, SI5341_IN_SEL, &val); + if (err < 0) + return err; + + return (val & SI5341_IN_SEL_MASK) >> SI5341_IN_SEL_SHIFT; +} + +static u8 si5341_clk_get_parent(struct clk_hw *hw) +{ + struct clk_si5341 *data = to_clk_si5341(hw); + int res = si5341_clk_get_selected_input(data); + + if (res < 0) + return 0; /* Apparently we cannot report errors */ + + return res; +} + +static int si5341_clk_reparent(struct clk_si5341 *data, u8 index) +{ + int err; + u8 val; + + val = (index << SI5341_IN_SEL_SHIFT) & SI5341_IN_SEL_MASK; + /* Enable register-based input selection */ + val |= SI5341_IN_SEL_REGCTRL; + + err = regmap_update_bits(data->regmap, + SI5341_IN_SEL, SI5341_IN_SEL_REGCTRL | SI5341_IN_SEL_MASK, val); + if (err < 0) + return err; + + if (index < 3) { + /* Enable input buffer for selected input */ + err = regmap_update_bits(data->regmap, + SI5341_IN_EN, 0x07, BIT(index)); + if (err < 0) + return err; + + /* Enables the input to phase detector */ + err = regmap_update_bits(data->regmap, SI5341_INX_TO_PFD_EN, + 0x7 << SI5341_INX_TO_PFD_SHIFT, + BIT(index + SI5341_INX_TO_PFD_SHIFT)); + if (err < 0) + return err; + + /* Power down XTAL oscillator and buffer */ + err = regmap_update_bits(data->regmap, SI5341_XAXB_CFG, + SI5341_XAXB_CFG_PDNB, 0); + if (err < 0) + return err; + + /* + * Set the P divider to "1". There's no explanation in the + * datasheet of these registers, but the clockbuilder software + * programs a "1" when the input is being used. + */ + err = regmap_write(data->regmap, SI5341_IN_PDIV(index), 1); + if (err < 0) + return err; + + err = regmap_write(data->regmap, SI5341_IN_PSET(index), 1); + if (err < 0) + return err; + + /* Set update PDIV bit */ + err = regmap_write(data->regmap, SI5341_PX_UPD, BIT(index)); + if (err < 0) + return err; + } else { + /* Disable all input buffers */ + err = regmap_update_bits(data->regmap, SI5341_IN_EN, 0x07, 0); + if (err < 0) + return err; + + /* Disable input to phase detector */ + err = regmap_update_bits(data->regmap, SI5341_INX_TO_PFD_EN, + 0x7 << SI5341_INX_TO_PFD_SHIFT, 0); + if (err < 0) + return err; + + /* Power up XTAL oscillator and buffer */ + err = regmap_update_bits(data->regmap, SI5341_XAXB_CFG, + SI5341_XAXB_CFG_PDNB, SI5341_XAXB_CFG_PDNB); + if (err < 0) + return err; + } + + return 0; +} + +static int si5341_clk_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_si5341 *data = to_clk_si5341(hw); + + return si5341_clk_reparent(data, index); +} + static const struct clk_ops si5341_clk_ops = { + .set_parent = si5341_clk_set_parent, + .get_parent = si5341_clk_get_parent, .recalc_rate = si5341_clk_recalc_rate, }; @@ -985,7 +1111,8 @@ static const struct regmap_range si5341_regmap_volatile_range[] = { regmap_reg_range(0x000C, 0x0012), /* Status */ regmap_reg_range(0x001C, 0x001E), /* reset, finc/fdec */ regmap_reg_range(0x00E2, 0x00FE), /* NVM, interrupts, device ready */ - /* Update bits for synth config */ + /* Update bits for P divider and synth config */ + regmap_reg_range(SI5341_PX_UPD, SI5341_PX_UPD), regmap_reg_range(SI5341_SYNTH_N_UPD(0), SI5341_SYNTH_N_UPD(0)), regmap_reg_range(SI5341_SYNTH_N_UPD(1), SI5341_SYNTH_N_UPD(1)), regmap_reg_range(SI5341_SYNTH_N_UPD(2), SI5341_SYNTH_N_UPD(2)), @@ -1122,6 +1249,7 @@ static int si5341_initialize_pll(struct clk_si5341 *data) struct device_node *np = data->i2c_client->dev.of_node; u32 m_num = 0; u32 m_den = 0; + int sel; if (of_property_read_u32(np, "silabs,pll-m-num", &m_num)) { dev_err(&data->i2c_client->dev, @@ -1135,7 +1263,11 @@ static int si5341_initialize_pll(struct clk_si5341 *data) if (!m_num || !m_den) { dev_err(&data->i2c_client->dev, "PLL configuration invalid, assume 14GHz\n"); - m_den = clk_get_rate(data->pxtal) / 10; + sel = si5341_clk_get_selected_input(data); + if (sel < 0) + return sel; + + m_den = clk_get_rate(data->input_clk[sel]) / 10; m_num = 1400000000; } @@ -1143,11 +1275,52 @@ static int si5341_initialize_pll(struct clk_si5341 *data) SI5341_PLL_M_NUM, m_num, m_den); } +static int si5341_clk_select_active_input(struct clk_si5341 *data) +{ + int res; + int err; + int i; + + res = si5341_clk_get_selected_input(data); + if (res < 0) + return res; + + /* If the current register setting is invalid, pick the first input */ + if (!data->input_clk[res]) { + dev_dbg(&data->i2c_client->dev, + "Input %d not connected, rerouting\n", res); + res = -ENODEV; + for (i = 0; i < SI5341_NUM_INPUTS; ++i) { + if (data->input_clk[i]) { + res = i; + break; + } + } + if (res < 0) { + dev_err(&data->i2c_client->dev, + "No clock input available\n"); + return res; + } + } + + /* Make sure the selected clock is also enabled and routed */ + err = si5341_clk_reparent(data, res); + if (err < 0) + return err; + + err = clk_prepare_enable(data->input_clk[res]); + if (err < 0) + return err; + + return res; +} + static int si5341_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct clk_si5341 *data; struct clk_init_data init; + struct clk *input; const char *root_clock_name; const char *synth_clock_names[SI5341_NUM_SYNTH]; int err; @@ -1161,12 +1334,16 @@ static int si5341_probe(struct i2c_client *client, data->i2c_client = client; - data->pxtal = devm_clk_get(&client->dev, "xtal"); - if (IS_ERR(data->pxtal)) { - if (PTR_ERR(data->pxtal) == -EPROBE_DEFER) - return -EPROBE_DEFER; - - dev_err(&client->dev, "Missing xtal clock input\n"); + for (i = 0; i < SI5341_NUM_INPUTS; ++i) { + input = devm_clk_get(&client->dev, si5341_input_clock_names[i]); + if (IS_ERR(input)) { + if (PTR_ERR(input) == -EPROBE_DEFER) + return -EPROBE_DEFER; + data->input_clk_name[i] = si5341_input_clock_names[i]; + } else { + data->input_clk[i] = input; + data->input_clk_name[i] = __clk_get_name(input); + } } err = si5341_dt_parse_dt(client, config); @@ -1188,9 +1365,6 @@ static int si5341_probe(struct i2c_client *client, if (err < 0) return err; - /* "Activate" the xtal (usually a fixed clock) */ - clk_prepare_enable(data->pxtal); - if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) { initialization_required = true; } else { @@ -1223,7 +1397,14 @@ static int si5341_probe(struct i2c_client *client, ARRAY_SIZE(si5341_reg_defaults)); if (err < 0) return err; + } + + /* Input must be up and running at this point */ + err = si5341_clk_select_active_input(data); + if (err < 0) + return err; + if (initialization_required) { /* PLL configuration is required */ err = si5341_initialize_pll(data); if (err < 0) @@ -1231,9 +1412,8 @@ static int si5341_probe(struct i2c_client *client, } /* Register the PLL */ - data->pxtal_name = __clk_get_name(data->pxtal); - init.parent_names = &data->pxtal_name; - init.num_parents = 1; /* For now, only XTAL input supported */ + init.parent_names = data->input_clk_name; + init.num_parents = SI5341_NUM_INPUTS; init.ops = &si5341_clk_ops; init.flags = 0; data->hw.init = &init; diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c index f0f2b599fd7e..766c3e58becc 100644 --- a/drivers/clk/clk.c +++ b/drivers/clk/clk.c @@ -488,7 +488,7 @@ unsigned long clk_hw_get_rate(const struct clk_hw *hw) } EXPORT_SYMBOL_GPL(clk_hw_get_rate); -static unsigned long __clk_get_accuracy(struct clk_core *core) +static unsigned long clk_core_get_accuracy_no_lock(struct clk_core *core) { if (!core) return 0; @@ -1517,18 +1517,12 @@ static void __clk_recalc_accuracies(struct clk_core *core) __clk_recalc_accuracies(child); } -static long clk_core_get_accuracy(struct clk_core *core) +static long clk_core_get_accuracy_recalc(struct clk_core *core) { - unsigned long accuracy; - - clk_prepare_lock(); if (core && (core->flags & CLK_GET_ACCURACY_NOCACHE)) __clk_recalc_accuracies(core); - accuracy = __clk_get_accuracy(core); - clk_prepare_unlock(); - - return accuracy; + return clk_core_get_accuracy_no_lock(core); } /** @@ -1542,10 +1536,16 @@ static long clk_core_get_accuracy(struct clk_core *core) */ long clk_get_accuracy(struct clk *clk) { + long accuracy; + if (!clk) return 0; - return clk_core_get_accuracy(clk->core); + clk_prepare_lock(); + accuracy = clk_core_get_accuracy_recalc(clk->core); + clk_prepare_unlock(); + + return accuracy; } EXPORT_SYMBOL_GPL(clk_get_accuracy); @@ -1599,19 +1599,12 @@ static void __clk_recalc_rates(struct clk_core *core, unsigned long msg) __clk_recalc_rates(child, msg); } -static unsigned long clk_core_get_rate(struct clk_core *core) +static unsigned long clk_core_get_rate_recalc(struct clk_core *core) { - unsigned long rate; - - clk_prepare_lock(); - if (core && (core->flags & CLK_GET_RATE_NOCACHE)) __clk_recalc_rates(core, 0); - rate = clk_core_get_rate_nolock(core); - clk_prepare_unlock(); - - return rate; + return clk_core_get_rate_nolock(core); } /** @@ -1624,10 +1617,16 @@ static unsigned long clk_core_get_rate(struct clk_core *core) */ unsigned long clk_get_rate(struct clk *clk) { + unsigned long rate; + if (!clk) return 0; - return clk_core_get_rate(clk->core); + clk_prepare_lock(); + rate = clk_core_get_rate_recalc(clk->core); + clk_prepare_unlock(); + + return rate; } EXPORT_SYMBOL_GPL(clk_get_rate); @@ -2660,12 +2659,14 @@ static int clk_core_get_phase(struct clk_core *core) { int ret; - clk_prepare_lock(); + lockdep_assert_held(&prepare_lock); + if (!core->ops->get_phase) + return 0; + /* Always try to update cached phase if possible */ - if (core->ops->get_phase) - core->phase = core->ops->get_phase(core->hw); - ret = core->phase; - clk_prepare_unlock(); + ret = core->ops->get_phase(core->hw); + if (ret >= 0) + core->phase = ret; return ret; } @@ -2679,10 +2680,16 @@ static int clk_core_get_phase(struct clk_core *core) */ int clk_get_phase(struct clk *clk) { + int ret; + if (!clk) return 0; - return clk_core_get_phase(clk->core); + clk_prepare_lock(); + ret = clk_core_get_phase(clk->core); + clk_prepare_unlock(); + + return ret; } EXPORT_SYMBOL_GPL(clk_get_phase); @@ -2896,13 +2903,22 @@ static struct hlist_head *orphan_list[] = { static void clk_summary_show_one(struct seq_file *s, struct clk_core *c, int level) { - seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu %5d %6d\n", + int phase; + + seq_printf(s, "%*s%-*s %7d %8d %8d %11lu %10lu ", level * 3 + 1, "", 30 - level * 3, c->name, c->enable_count, c->prepare_count, c->protect_count, - clk_core_get_rate(c), clk_core_get_accuracy(c), - clk_core_get_phase(c), - clk_core_get_scaled_duty_cycle(c, 100000)); + clk_core_get_rate_recalc(c), + clk_core_get_accuracy_recalc(c)); + + phase = clk_core_get_phase(c); + if (phase >= 0) + seq_printf(s, "%5d", phase); + else + seq_puts(s, "-----"); + + seq_printf(s, " %6d\n", clk_core_get_scaled_duty_cycle(c, 100000)); } static void clk_summary_show_subtree(struct seq_file *s, struct clk_core *c, @@ -2939,6 +2955,7 @@ DEFINE_SHOW_ATTRIBUTE(clk_summary); static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) { + int phase; unsigned long min_rate, max_rate; clk_core_get_boundaries(c, &min_rate, &max_rate); @@ -2948,11 +2965,13 @@ static void clk_dump_one(struct seq_file *s, struct clk_core *c, int level) seq_printf(s, "\"enable_count\": %d,", c->enable_count); seq_printf(s, "\"prepare_count\": %d,", c->prepare_count); seq_printf(s, "\"protect_count\": %d,", c->protect_count); - seq_printf(s, "\"rate\": %lu,", clk_core_get_rate(c)); + seq_printf(s, "\"rate\": %lu,", clk_core_get_rate_recalc(c)); seq_printf(s, "\"min_rate\": %lu,", min_rate); seq_printf(s, "\"max_rate\": %lu,", max_rate); - seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy(c)); - seq_printf(s, "\"phase\": %d,", clk_core_get_phase(c)); + seq_printf(s, "\"accuracy\": %lu,", clk_core_get_accuracy_recalc(c)); + phase = clk_core_get_phase(c); + if (phase >= 0) + seq_printf(s, "\"phase\": %d,", phase); seq_printf(s, "\"duty_cycle\": %u", clk_core_get_scaled_duty_cycle(c, 100000)); } @@ -3323,7 +3342,9 @@ static void clk_core_reparent_orphans_nolock(void) static int __clk_core_init(struct clk_core *core) { int ret; + struct clk_core *parent; unsigned long rate; + int phase; if (!core) return -EINVAL; @@ -3394,7 +3415,7 @@ static int __clk_core_init(struct clk_core *core) goto out; } - core->parent = __clk_init_parent(core); + parent = core->parent = __clk_init_parent(core); /* * Populate core->parent if parent has already been clk_core_init'd. If @@ -3406,10 +3427,9 @@ static int __clk_core_init(struct clk_core *core) * clocks and re-parent any that are children of the clock currently * being clk_init'd. */ - if (core->parent) { - hlist_add_head(&core->child_node, - &core->parent->children); - core->orphan = core->parent->orphan; + if (parent) { + hlist_add_head(&core->child_node, &parent->children); + core->orphan = parent->orphan; } else if (!core->num_parents) { hlist_add_head(&core->child_node, &clk_root_list); core->orphan = false; @@ -3427,21 +3447,24 @@ static int __clk_core_init(struct clk_core *core) */ if (core->ops->recalc_accuracy) core->accuracy = core->ops->recalc_accuracy(core->hw, - __clk_get_accuracy(core->parent)); - else if (core->parent) - core->accuracy = core->parent->accuracy; + clk_core_get_accuracy_no_lock(parent)); + else if (parent) + core->accuracy = parent->accuracy; else core->accuracy = 0; /* - * Set clk's phase. + * Set clk's phase by clk_core_get_phase() caching the phase. * Since a phase is by definition relative to its parent, just * query the current clock phase, or just assume it's in phase. */ - if (core->ops->get_phase) - core->phase = core->ops->get_phase(core->hw); - else - core->phase = 0; + phase = clk_core_get_phase(core); + if (phase < 0) { + ret = phase; + pr_warn("%s: Failed to get phase for clk '%s'\n", __func__, + core->name); + goto out; + } /* * Set clk's duty cycle. @@ -3456,9 +3479,9 @@ static int __clk_core_init(struct clk_core *core) */ if (core->ops->recalc_rate) rate = core->ops->recalc_rate(core->hw, - clk_core_get_rate_nolock(core->parent)); - else if (core->parent) - rate = core->parent->rate; + clk_core_get_rate_nolock(parent)); + else if (parent) + rate = parent->rate; else rate = 0; core->rate = core->req_rate = rate; @@ -4865,8 +4888,8 @@ static int parent_ready(struct device_node *np) * * Return: error code or zero on success */ -int of_clk_detect_critical(struct device_node *np, - int index, unsigned long *flags) +int of_clk_detect_critical(struct device_node *np, int index, + unsigned long *flags) { struct property *prop; const __be32 *cur; diff --git a/drivers/clk/meson/g12a.c b/drivers/clk/meson/g12a.c index d2760a021301..fad616cac01e 100644 --- a/drivers/clk/meson/g12a.c +++ b/drivers/clk/meson/g12a.c @@ -3862,6 +3862,111 @@ static struct clk_regmap g12a_ts = { }, }; +/* SPICC SCLK source clock */ + +static const struct clk_parent_data spicc_sclk_parent_data[] = { + { .fw_name = "xtal", }, + { .hw = &g12a_clk81.hw }, + { .hw = &g12a_fclk_div4.hw }, + { .hw = &g12a_fclk_div3.hw }, + { .hw = &g12a_fclk_div5.hw }, + { .hw = &g12a_fclk_div7.hw }, +}; + +static struct clk_regmap g12a_spicc0_sclk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SPICC_CLK_CNTL, + .mask = 7, + .shift = 7, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc0_sclk_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = spicc_sclk_parent_data, + .num_parents = ARRAY_SIZE(spicc_sclk_parent_data), + }, +}; + +static struct clk_regmap g12a_spicc0_sclk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SPICC_CLK_CNTL, + .shift = 0, + .width = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc0_sclk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_spicc0_sclk_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_spicc0_sclk = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SPICC_CLK_CNTL, + .bit_idx = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc0_sclk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_spicc0_sclk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_spicc1_sclk_sel = { + .data = &(struct clk_regmap_mux_data){ + .offset = HHI_SPICC_CLK_CNTL, + .mask = 7, + .shift = 23, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc1_sclk_sel", + .ops = &clk_regmap_mux_ops, + .parent_data = spicc_sclk_parent_data, + .num_parents = ARRAY_SIZE(spicc_sclk_parent_data), + }, +}; + +static struct clk_regmap g12a_spicc1_sclk_div = { + .data = &(struct clk_regmap_div_data){ + .offset = HHI_SPICC_CLK_CNTL, + .shift = 16, + .width = 6, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc1_sclk_div", + .ops = &clk_regmap_divider_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_spicc1_sclk_sel.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + +static struct clk_regmap g12a_spicc1_sclk = { + .data = &(struct clk_regmap_gate_data){ + .offset = HHI_SPICC_CLK_CNTL, + .bit_idx = 22, + }, + .hw.init = &(struct clk_init_data){ + .name = "spicc1_sclk", + .ops = &clk_regmap_gate_ops, + .parent_hws = (const struct clk_hw *[]) { + &g12a_spicc1_sclk_div.hw + }, + .num_parents = 1, + .flags = CLK_SET_RATE_PARENT, + }, +}; + #define MESON_GATE(_name, _reg, _bit) \ MESON_PCLK(_name, _reg, _bit, &g12a_clk81.hw) @@ -4159,6 +4264,12 @@ static struct clk_hw_onecell_data g12a_hw_onecell_data = { [CLKID_VDEC_HEVCF] = &g12a_vdec_hevcf.hw, [CLKID_TS_DIV] = &g12a_ts_div.hw, [CLKID_TS] = &g12a_ts.hw, + [CLKID_SPICC0_SCLK_SEL] = &g12a_spicc0_sclk_sel.hw, + [CLKID_SPICC0_SCLK_DIV] = &g12a_spicc0_sclk_div.hw, + [CLKID_SPICC0_SCLK] = &g12a_spicc0_sclk.hw, + [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, + [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, + [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -4408,6 +4519,12 @@ static struct clk_hw_onecell_data g12b_hw_onecell_data = { [CLKID_CPUB_CLK_AXI] = &g12b_cpub_clk_axi.hw, [CLKID_CPUB_CLK_TRACE_SEL] = &g12b_cpub_clk_trace_sel.hw, [CLKID_CPUB_CLK_TRACE] = &g12b_cpub_clk_trace.hw, + [CLKID_SPICC0_SCLK_SEL] = &g12a_spicc0_sclk_sel.hw, + [CLKID_SPICC0_SCLK_DIV] = &g12a_spicc0_sclk_div.hw, + [CLKID_SPICC0_SCLK] = &g12a_spicc0_sclk.hw, + [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, + [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, + [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -4642,6 +4759,12 @@ static struct clk_hw_onecell_data sm1_hw_onecell_data = { [CLKID_CPU1_CLK] = &sm1_cpu1_clk.hw, [CLKID_CPU2_CLK] = &sm1_cpu2_clk.hw, [CLKID_CPU3_CLK] = &sm1_cpu3_clk.hw, + [CLKID_SPICC0_SCLK_SEL] = &g12a_spicc0_sclk_sel.hw, + [CLKID_SPICC0_SCLK_DIV] = &g12a_spicc0_sclk_div.hw, + [CLKID_SPICC0_SCLK] = &g12a_spicc0_sclk.hw, + [CLKID_SPICC1_SCLK_SEL] = &g12a_spicc1_sclk_sel.hw, + [CLKID_SPICC1_SCLK_DIV] = &g12a_spicc1_sclk_div.hw, + [CLKID_SPICC1_SCLK] = &g12a_spicc1_sclk.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -4877,6 +5000,12 @@ static struct clk_regmap *const g12a_clk_regmaps[] = { &sm1_cpu1_clk, &sm1_cpu2_clk, &sm1_cpu3_clk, + &g12a_spicc0_sclk_sel, + &g12a_spicc0_sclk_div, + &g12a_spicc0_sclk, + &g12a_spicc1_sclk_sel, + &g12a_spicc1_sclk_div, + &g12a_spicc1_sclk, }; static const struct reg_sequence g12a_init_regs[] = { diff --git a/drivers/clk/meson/g12a.h b/drivers/clk/meson/g12a.h index 9df4068aced1..a8852556836e 100644 --- a/drivers/clk/meson/g12a.h +++ b/drivers/clk/meson/g12a.h @@ -255,8 +255,12 @@ #define CLKID_DSU_CLK_DYN1 249 #define CLKID_DSU_CLK_DYN 250 #define CLKID_DSU_CLK_FINAL 251 +#define CLKID_SPICC0_SCLK_SEL 256 +#define CLKID_SPICC0_SCLK_DIV 257 +#define CLKID_SPICC1_SCLK_SEL 259 +#define CLKID_SPICC1_SCLK_DIV 260 -#define NR_CLKS 256 +#define NR_CLKS 262 /* include the CLKIDs that have been made part of the DT binding */ #include <dt-bindings/clock/g12a-clkc.h> diff --git a/drivers/clk/meson/gxbb.c b/drivers/clk/meson/gxbb.c index 1f9c056e684c..5fd6a574f8c3 100644 --- a/drivers/clk/meson/gxbb.c +++ b/drivers/clk/meson/gxbb.c @@ -2613,19 +2613,12 @@ static MESON_GATE(gxbb_assist_misc, HHI_GCLK_MPEG0, 23); static MESON_GATE(gxbb_emmc_a, HHI_GCLK_MPEG0, 24); static MESON_GATE(gxbb_emmc_b, HHI_GCLK_MPEG0, 25); static MESON_GATE(gxbb_emmc_c, HHI_GCLK_MPEG0, 26); +static MESON_GATE(gxl_acodec, HHI_GCLK_MPEG0, 28); static MESON_GATE(gxbb_spi, HHI_GCLK_MPEG0, 30); static MESON_GATE(gxbb_i2s_spdif, HHI_GCLK_MPEG1, 2); static MESON_GATE(gxbb_eth, HHI_GCLK_MPEG1, 3); static MESON_GATE(gxbb_demux, HHI_GCLK_MPEG1, 4); -static MESON_GATE(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6); -static MESON_GATE(gxbb_iec958, HHI_GCLK_MPEG1, 7); -static MESON_GATE(gxbb_i2s_out, HHI_GCLK_MPEG1, 8); -static MESON_GATE(gxbb_amclk, HHI_GCLK_MPEG1, 9); -static MESON_GATE(gxbb_aififo2, HHI_GCLK_MPEG1, 10); -static MESON_GATE(gxbb_mixer, HHI_GCLK_MPEG1, 11); -static MESON_GATE(gxbb_mixer_iface, HHI_GCLK_MPEG1, 12); -static MESON_GATE(gxbb_adc, HHI_GCLK_MPEG1, 13); static MESON_GATE(gxbb_blkmv, HHI_GCLK_MPEG1, 14); static MESON_GATE(gxbb_aiu, HHI_GCLK_MPEG1, 15); static MESON_GATE(gxbb_uart1, HHI_GCLK_MPEG1, 16); @@ -2680,6 +2673,16 @@ static MESON_GATE(gxbb_ao_ahb_bus, HHI_GCLK_AO, 2); static MESON_GATE(gxbb_ao_iface, HHI_GCLK_AO, 3); static MESON_GATE(gxbb_ao_i2c, HHI_GCLK_AO, 4); +/* AIU gates */ +static MESON_PCLK(gxbb_aiu_glue, HHI_GCLK_MPEG1, 6, &gxbb_aiu.hw); +static MESON_PCLK(gxbb_iec958, HHI_GCLK_MPEG1, 7, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_i2s_out, HHI_GCLK_MPEG1, 8, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_amclk, HHI_GCLK_MPEG1, 9, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_aififo2, HHI_GCLK_MPEG1, 10, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_mixer, HHI_GCLK_MPEG1, 11, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_mixer_iface, HHI_GCLK_MPEG1, 12, &gxbb_aiu_glue.hw); +static MESON_PCLK(gxbb_adc, HHI_GCLK_MPEG1, 13, &gxbb_aiu_glue.hw); + /* Array of all clocks provided by this provider */ static struct clk_hw_onecell_data gxbb_hw_onecell_data = { @@ -3100,6 +3103,7 @@ static struct clk_hw_onecell_data gxl_hw_onecell_data = { [CLKID_HDMI_SEL] = &gxbb_hdmi_sel.hw, [CLKID_HDMI_DIV] = &gxbb_hdmi_div.hw, [CLKID_HDMI] = &gxbb_hdmi.hw, + [CLKID_ACODEC] = &gxl_acodec.hw, [NR_CLKS] = NULL, }, .num = NR_CLKS, @@ -3491,6 +3495,7 @@ static struct clk_regmap *const gxl_clk_regmaps[] = { &gxl_hdmi_pll_od, &gxl_hdmi_pll_od2, &gxl_hdmi_pll_dco, + &gxl_acodec, }; static const struct meson_eeclkc_data gxbb_clkc_data = { diff --git a/drivers/clk/meson/gxbb.h b/drivers/clk/meson/gxbb.h index b53584fe66cf..1ee8cb7e2f5a 100644 --- a/drivers/clk/meson/gxbb.h +++ b/drivers/clk/meson/gxbb.h @@ -188,7 +188,7 @@ #define CLKID_HDMI_SEL 203 #define CLKID_HDMI_DIV 204 -#define NR_CLKS 206 +#define NR_CLKS 207 /* include the CLKIDs that have been made part of the DT binding */ #include <dt-bindings/clock/gxbb-clkc.h> diff --git a/drivers/clk/meson/meson8b.c b/drivers/clk/meson/meson8b.c index 9fd31f23b2a9..34a70c4b4899 100644 --- a/drivers/clk/meson/meson8b.c +++ b/drivers/clk/meson/meson8b.c @@ -2605,14 +2605,6 @@ static MESON_GATE(meson8b_spi, HHI_GCLK_MPEG0, 30); static MESON_GATE(meson8b_i2s_spdif, HHI_GCLK_MPEG1, 2); static MESON_GATE(meson8b_eth, HHI_GCLK_MPEG1, 3); static MESON_GATE(meson8b_demux, HHI_GCLK_MPEG1, 4); -static MESON_GATE(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6); -static MESON_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7); -static MESON_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8); -static MESON_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9); -static MESON_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10); -static MESON_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11); -static MESON_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12); -static MESON_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13); static MESON_GATE(meson8b_blkmv, HHI_GCLK_MPEG1, 14); static MESON_GATE(meson8b_aiu, HHI_GCLK_MPEG1, 15); static MESON_GATE(meson8b_uart1, HHI_GCLK_MPEG1, 16); @@ -2659,6 +2651,19 @@ static MESON_GATE(meson8b_vclk2_vencl, HHI_GCLK_OTHER, 25); static MESON_GATE(meson8b_vclk2_other, HHI_GCLK_OTHER, 26); static MESON_GATE(meson8b_edp, HHI_GCLK_OTHER, 31); +/* AIU gates */ +#define MESON_AIU_GLUE_GATE(_name, _reg, _bit) \ + MESON_PCLK(_name, _reg, _bit, &meson8b_aiu_glue.hw) + +static MESON_PCLK(meson8b_aiu_glue, HHI_GCLK_MPEG1, 6, &meson8b_aiu.hw); +static MESON_AIU_GLUE_GATE(meson8b_iec958, HHI_GCLK_MPEG1, 7); +static MESON_AIU_GLUE_GATE(meson8b_i2s_out, HHI_GCLK_MPEG1, 8); +static MESON_AIU_GLUE_GATE(meson8b_amclk, HHI_GCLK_MPEG1, 9); +static MESON_AIU_GLUE_GATE(meson8b_aififo2, HHI_GCLK_MPEG1, 10); +static MESON_AIU_GLUE_GATE(meson8b_mixer, HHI_GCLK_MPEG1, 11); +static MESON_AIU_GLUE_GATE(meson8b_mixer_iface, HHI_GCLK_MPEG1, 12); +static MESON_AIU_GLUE_GATE(meson8b_adc, HHI_GCLK_MPEG1, 13); + /* Always On (AO) domain gates */ static MESON_GATE(meson8b_ao_media_cpu, HHI_GCLK_AO, 0); diff --git a/drivers/clk/rockchip/clk-mmc-phase.c b/drivers/clk/rockchip/clk-mmc-phase.c index 4abe7ff31f53..975454a3dd72 100644 --- a/drivers/clk/rockchip/clk-mmc-phase.c +++ b/drivers/clk/rockchip/clk-mmc-phase.c @@ -51,9 +51,9 @@ static int rockchip_mmc_get_phase(struct clk_hw *hw) u16 degrees; u32 delay_num = 0; - /* See the comment for rockchip_mmc_set_phase below */ + /* Constant signal, no measurable phase shift */ if (!rate) - return -EINVAL; + return 0; raw_value = readl(mmc_clock->reg) >> (mmc_clock->shift); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index dad31308c071..1949ae7851b2 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -356,10 +356,6 @@ struct samsung_clk_provider * __init samsung_cmu_register_one( } ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); - if (!ctx) { - panic("%s: unable to allocate ctx\n", __func__); - return ctx; - } if (cmu->pll_clks) samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, diff --git a/drivers/clk/socfpga/clk-gate-s10.c b/drivers/clk/socfpga/clk-gate-s10.c index 54a464fa63e0..8be4722f6064 100644 --- a/drivers/clk/socfpga/clk-gate-s10.c +++ b/drivers/clk/socfpga/clk-gate-s10.c @@ -65,54 +65,49 @@ static const struct clk_ops dbgclk_ops = { .get_parent = socfpga_gate_get_parent, }; -struct clk *s10_register_gate(const char *name, const char *parent_name, - const char * const *parent_names, - u8 num_parents, unsigned long flags, - void __iomem *regbase, unsigned long gate_reg, - unsigned long gate_idx, unsigned long div_reg, - unsigned long div_offset, u8 div_width, - unsigned long bypass_reg, u8 bypass_shift, - u8 fixed_div) +struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase) { struct clk *clk; struct socfpga_gate_clk *socfpga_clk; struct clk_init_data init; + const char * const *parent_names = clks->parent_names; + const char *parent_name = clks->parent_name; socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL); if (!socfpga_clk) return NULL; - socfpga_clk->hw.reg = regbase + gate_reg; - socfpga_clk->hw.bit_idx = gate_idx; + socfpga_clk->hw.reg = regbase + clks->gate_reg; + socfpga_clk->hw.bit_idx = clks->gate_idx; gateclk_ops.enable = clk_gate_ops.enable; gateclk_ops.disable = clk_gate_ops.disable; - socfpga_clk->fixed_div = fixed_div; + socfpga_clk->fixed_div = clks->fixed_div; - if (div_reg) - socfpga_clk->div_reg = regbase + div_reg; + if (clks->div_reg) + socfpga_clk->div_reg = regbase + clks->div_reg; else socfpga_clk->div_reg = NULL; - socfpga_clk->width = div_width; - socfpga_clk->shift = div_offset; + socfpga_clk->width = clks->div_width; + socfpga_clk->shift = clks->div_offset; - if (bypass_reg) - socfpga_clk->bypass_reg = regbase + bypass_reg; + if (clks->bypass_reg) + socfpga_clk->bypass_reg = regbase + clks->bypass_reg; else socfpga_clk->bypass_reg = NULL; - socfpga_clk->bypass_shift = bypass_shift; + socfpga_clk->bypass_shift = clks->bypass_shift; - if (streq(name, "cs_pdbg_clk")) + if (streq(clks->name, "cs_pdbg_clk")) init.ops = &dbgclk_ops; else init.ops = &gateclk_ops; - init.name = name; - init.flags = flags; + init.name = clks->name; + init.flags = clks->flags; - init.num_parents = num_parents; + init.num_parents = clks->num_parents; init.parent_names = parent_names ? parent_names : &parent_name; socfpga_clk->hw.hw.init = &init; @@ -121,6 +116,5 @@ struct clk *s10_register_gate(const char *name, const char *parent_name, kfree(socfpga_clk); return NULL; } - return clk; } diff --git a/drivers/clk/socfpga/clk-periph-s10.c b/drivers/clk/socfpga/clk-periph-s10.c index 1a191eeeebba..dd6d4056e9de 100644 --- a/drivers/clk/socfpga/clk-periph-s10.c +++ b/drivers/clk/socfpga/clk-periph-s10.c @@ -73,26 +73,27 @@ static const struct clk_ops peri_cnt_clk_ops = { .get_parent = clk_periclk_get_parent, }; -struct clk *s10_register_periph(const char *name, const char *parent_name, - const char * const *parent_names, - u8 num_parents, unsigned long flags, - void __iomem *reg, unsigned long offset) +struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks, + void __iomem *reg) { struct clk *clk; struct socfpga_periph_clk *periph_clk; struct clk_init_data init; + const char *name = clks->name; + const char *parent_name = clks->parent_name; + const char * const *parent_names = clks->parent_names; periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); if (WARN_ON(!periph_clk)) return NULL; - periph_clk->hw.reg = reg + offset; + periph_clk->hw.reg = reg + clks->offset; init.name = name; init.ops = &peri_c_clk_ops; - init.flags = flags; + init.flags = clks->flags; - init.num_parents = num_parents; + init.num_parents = clks->num_parents; init.parent_names = parent_names ? parent_names : &parent_name; periph_clk->hw.hw.init = &init; @@ -105,38 +106,37 @@ struct clk *s10_register_periph(const char *name, const char *parent_name, return clk; } -struct clk *s10_register_cnt_periph(const char *name, const char *parent_name, - const char * const *parent_names, - u8 num_parents, unsigned long flags, - void __iomem *regbase, unsigned long offset, - u8 fixed_divider, unsigned long bypass_reg, - unsigned long bypass_shift) +struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks, + void __iomem *regbase) { struct clk *clk; struct socfpga_periph_clk *periph_clk; struct clk_init_data init; + const char *name = clks->name; + const char *parent_name = clks->parent_name; + const char * const *parent_names = clks->parent_names; periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL); if (WARN_ON(!periph_clk)) return NULL; - if (offset) - periph_clk->hw.reg = regbase + offset; + if (clks->offset) + periph_clk->hw.reg = regbase + clks->offset; else periph_clk->hw.reg = NULL; - if (bypass_reg) - periph_clk->bypass_reg = regbase + bypass_reg; + if (clks->bypass_reg) + periph_clk->bypass_reg = regbase + clks->bypass_reg; else periph_clk->bypass_reg = NULL; - periph_clk->bypass_shift = bypass_shift; - periph_clk->fixed_div = fixed_divider; + periph_clk->bypass_shift = clks->bypass_shift; + periph_clk->fixed_div = clks->fixed_divider; init.name = name; init.ops = &peri_cnt_clk_ops; - init.flags = flags; + init.flags = clks->flags; - init.num_parents = num_parents; + init.num_parents = clks->num_parents; init.parent_names = parent_names ? parent_names : &parent_name; periph_clk->hw.hw.init = &init; diff --git a/drivers/clk/socfpga/clk-pll-s10.c b/drivers/clk/socfpga/clk-pll-s10.c index 4705eb544f01..a301bb22f36c 100644 --- a/drivers/clk/socfpga/clk-pll-s10.c +++ b/drivers/clk/socfpga/clk-pll-s10.c @@ -39,7 +39,9 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk, /* read VCO1 reg for numerator and denominator */ reg = readl(socfpgaclk->hw.reg); refdiv = (reg & SOCFPGA_PLL_REFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT; - vco_freq = (unsigned long long)parent_rate / refdiv; + + vco_freq = parent_rate; + do_div(vco_freq, refdiv); /* Read mdiv and fdiv from the fdbck register */ reg = readl(socfpgaclk->hw.reg + 0x4); @@ -108,19 +110,20 @@ static struct clk_ops clk_boot_ops = { .prepare = clk_pll_prepare, }; -struct clk *s10_register_pll(const char *name, const char * const *parent_names, - u8 num_parents, unsigned long flags, - void __iomem *reg, unsigned long offset) +struct clk *s10_register_pll(const struct stratix10_pll_clock *clks, + void __iomem *reg) { struct clk *clk; struct socfpga_pll *pll_clk; struct clk_init_data init; + const char *name = clks->name; + const char * const *parent_names = clks->parent_names; pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL); if (WARN_ON(!pll_clk)) return NULL; - pll_clk->hw.reg = reg + offset; + pll_clk->hw.reg = reg + clks->offset; if (streq(name, SOCFPGA_BOOT_CLK)) init.ops = &clk_boot_ops; @@ -128,9 +131,9 @@ struct clk *s10_register_pll(const char *name, const char * const *parent_names, init.ops = &clk_pll_ops; init.name = name; - init.flags = flags; + init.flags = clks->flags; - init.num_parents = num_parents; + init.num_parents = clks->num_parents; init.parent_names = parent_names; pll_clk->hw.hw.init = &init; diff --git a/drivers/clk/socfpga/clk-s10.c b/drivers/clk/socfpga/clk-s10.c index 993f3a73c71e..dea7c6c7d269 100644 --- a/drivers/clk/socfpga/clk-s10.c +++ b/drivers/clk/socfpga/clk-s10.c @@ -177,9 +177,7 @@ static int s10_clk_register_c_perip(const struct stratix10_perip_c_clock *clks, int i; for (i = 0; i < nums; i++) { - clk = s10_register_periph(clks[i].name, clks[i].parent_name, - clks[i].parent_names, clks[i].num_parents, - clks[i].flags, base, clks[i].offset); + clk = s10_register_periph(&clks[i], base); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); @@ -198,14 +196,7 @@ static int s10_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *cl int i; for (i = 0; i < nums; i++) { - clk = s10_register_cnt_periph(clks[i].name, clks[i].parent_name, - clks[i].parent_names, - clks[i].num_parents, - clks[i].flags, base, - clks[i].offset, - clks[i].fixed_divider, - clks[i].bypass_reg, - clks[i].bypass_shift); + clk = s10_register_cnt_periph(&clks[i], base); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); @@ -225,16 +216,7 @@ static int s10_clk_register_gate(const struct stratix10_gate_clock *clks, int i; for (i = 0; i < nums; i++) { - clk = s10_register_gate(clks[i].name, clks[i].parent_name, - clks[i].parent_names, - clks[i].num_parents, - clks[i].flags, base, - clks[i].gate_reg, - clks[i].gate_idx, clks[i].div_reg, - clks[i].div_offset, clks[i].div_width, - clks[i].bypass_reg, - clks[i].bypass_shift, - clks[i].fixed_div); + clk = s10_register_gate(&clks[i], base); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); @@ -254,10 +236,7 @@ static int s10_clk_register_pll(const struct stratix10_pll_clock *clks, int i; for (i = 0; i < nums; i++) { - clk = s10_register_pll(clks[i].name, clks[i].parent_names, - clks[i].num_parents, - clks[i].flags, base, - clks[i].offset); + clk = s10_register_pll(&clks[i], base); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, clks[i].name); diff --git a/drivers/clk/socfpga/stratix10-clk.h b/drivers/clk/socfpga/stratix10-clk.h index e8e121907952..fcabef42249c 100644 --- a/drivers/clk/socfpga/stratix10-clk.h +++ b/drivers/clk/socfpga/stratix10-clk.h @@ -60,21 +60,12 @@ struct stratix10_gate_clock { u8 fixed_div; }; -struct clk *s10_register_pll(const char *, const char *const *, u8, - unsigned long, void __iomem *, unsigned long); - -struct clk *s10_register_periph(const char *, const char *, - const char * const *, u8, unsigned long, - void __iomem *, unsigned long); -struct clk *s10_register_cnt_periph(const char *, const char *, - const char * const *, u8, - unsigned long, void __iomem *, - unsigned long, u8, unsigned long, - unsigned long); -struct clk *s10_register_gate(const char *, const char *, - const char * const *, u8, - unsigned long, void __iomem *, - unsigned long, unsigned long, - unsigned long, unsigned long, u8, - unsigned long, u8, u8); +struct clk *s10_register_pll(const struct stratix10_pll_clock *, + void __iomem *); +struct clk *s10_register_periph(const struct stratix10_perip_c_clock *, + void __iomem *); +struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *, + void __iomem *); +struct clk *s10_register_gate(const struct stratix10_gate_clock *, + void __iomem *); #endif /* __STRATIX10_CLK_H */ diff --git a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h index 116e6f826d04..54d1f96f4b68 100644 --- a/drivers/clk/sunxi-ng/ccu-sun50i-a64.h +++ b/drivers/clk/sunxi-ng/ccu-sun50i-a64.h @@ -55,10 +55,6 @@ /* All the DRAM gates are exported */ -/* Some more module clocks are exported */ - -#define CLK_MBUS 112 - /* And the DSI and GPU module clock is exported */ #define CLK_NUMBER (CLK_GPU + 1) diff --git a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c index d9668493c3f9..524f33275bc7 100644 --- a/drivers/clk/sunxi-ng/ccu-sun8i-de2.c +++ b/drivers/clk/sunxi-ng/ccu-sun8i-de2.c @@ -50,8 +50,10 @@ static SUNXI_CCU_M(mixer1_div_a83_clk, "mixer1-div", "pll-de", 0x0c, 4, 4, CLK_SET_RATE_PARENT); static SUNXI_CCU_M(wb_div_a83_clk, "wb-div", "pll-de", 0x0c, 8, 4, CLK_SET_RATE_PARENT); +static SUNXI_CCU_M(rot_div_a83_clk, "rot-div", "pll-de", 0x0c, 0x0c, 4, + CLK_SET_RATE_PARENT); -static struct ccu_common *sun50i_h6_de3_clks[] = { +static struct ccu_common *sun8i_a83t_de2_clks[] = { &mixer0_clk.common, &mixer1_clk.common, &wb_clk.common, @@ -60,16 +62,16 @@ static struct ccu_common *sun50i_h6_de3_clks[] = { &bus_mixer1_clk.common, &bus_wb_clk.common, - &mixer0_div_clk.common, - &mixer1_div_clk.common, - &wb_div_clk.common, + &mixer0_div_a83_clk.common, + &mixer1_div_a83_clk.common, + &wb_div_a83_clk.common, &bus_rot_clk.common, &rot_clk.common, - &rot_div_clk.common, + &rot_div_a83_clk.common, }; -static struct ccu_common *sun8i_a83t_de2_clks[] = { +static struct ccu_common *sun8i_h3_de2_clks[] = { &mixer0_clk.common, &mixer1_clk.common, &wb_clk.common, @@ -78,34 +80,38 @@ static struct ccu_common *sun8i_a83t_de2_clks[] = { &bus_mixer1_clk.common, &bus_wb_clk.common, - &mixer0_div_a83_clk.common, - &mixer1_div_a83_clk.common, - &wb_div_a83_clk.common, + &mixer0_div_clk.common, + &mixer1_div_clk.common, + &wb_div_clk.common, }; -static struct ccu_common *sun8i_h3_de2_clks[] = { +static struct ccu_common *sun8i_v3s_de2_clks[] = { &mixer0_clk.common, - &mixer1_clk.common, &wb_clk.common, &bus_mixer0_clk.common, - &bus_mixer1_clk.common, &bus_wb_clk.common, &mixer0_div_clk.common, - &mixer1_div_clk.common, &wb_div_clk.common, }; -static struct ccu_common *sun8i_v3s_de2_clks[] = { +static struct ccu_common *sun50i_a64_de2_clks[] = { &mixer0_clk.common, + &mixer1_clk.common, &wb_clk.common, &bus_mixer0_clk.common, + &bus_mixer1_clk.common, &bus_wb_clk.common, &mixer0_div_clk.common, + &mixer1_div_clk.common, &wb_div_clk.common, + + &bus_rot_clk.common, + &rot_clk.common, + &rot_div_clk.common, }; static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = { @@ -113,16 +119,19 @@ static struct clk_hw_onecell_data sun8i_a83t_de2_hw_clks = { [CLK_MIXER0] = &mixer0_clk.common.hw, [CLK_MIXER1] = &mixer1_clk.common.hw, [CLK_WB] = &wb_clk.common.hw, + [CLK_ROT] = &rot_clk.common.hw, [CLK_BUS_MIXER0] = &bus_mixer0_clk.common.hw, [CLK_BUS_MIXER1] = &bus_mixer1_clk.common.hw, [CLK_BUS_WB] = &bus_wb_clk.common.hw, + [CLK_BUS_ROT] = &bus_rot_clk.common.hw, [CLK_MIXER0_DIV] = &mixer0_div_a83_clk.common.hw, [CLK_MIXER1_DIV] = &mixer1_div_a83_clk.common.hw, [CLK_WB_DIV] = &wb_div_a83_clk.common.hw, + [CLK_ROT_DIV] = &rot_div_a83_clk.common.hw, }, - .num = CLK_NUMBER_WITHOUT_ROT, + .num = CLK_NUMBER_WITH_ROT, }; static struct clk_hw_onecell_data sun8i_h3_de2_hw_clks = { @@ -156,7 +165,7 @@ static struct clk_hw_onecell_data sun8i_v3s_de2_hw_clks = { .num = CLK_NUMBER_WITHOUT_ROT, }; -static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = { +static struct clk_hw_onecell_data sun50i_a64_de2_hw_clks = { .hws = { [CLK_MIXER0] = &mixer0_clk.common.hw, [CLK_MIXER1] = &mixer1_clk.common.hw, @@ -179,9 +188,19 @@ static struct clk_hw_onecell_data sun50i_h6_de3_hw_clks = { static struct ccu_reset_map sun8i_a83t_de2_resets[] = { [RST_MIXER0] = { 0x08, BIT(0) }, /* - * For A83T, H3 and R40, mixer1 reset line is shared with wb, so - * only RST_WB is exported here. - * For V3s there's just no mixer1, so it also shares this struct. + * Mixer1 reset line is shared with wb, so only RST_WB is + * exported here. + */ + [RST_WB] = { 0x08, BIT(2) }, + [RST_ROT] = { 0x08, BIT(3) }, +}; + +static struct ccu_reset_map sun8i_h3_de2_resets[] = { + [RST_MIXER0] = { 0x08, BIT(0) }, + /* + * Mixer1 reset line is shared with wb, so only RST_WB is + * exported here. + * V3s doesn't have mixer1, so it also shares this struct. */ [RST_WB] = { 0x08, BIT(2) }, }; @@ -190,13 +209,13 @@ static struct ccu_reset_map sun50i_a64_de2_resets[] = { [RST_MIXER0] = { 0x08, BIT(0) }, [RST_MIXER1] = { 0x08, BIT(1) }, [RST_WB] = { 0x08, BIT(2) }, + [RST_ROT] = { 0x08, BIT(3) }, }; -static struct ccu_reset_map sun50i_h6_de3_resets[] = { +static struct ccu_reset_map sun50i_h5_de2_resets[] = { [RST_MIXER0] = { 0x08, BIT(0) }, [RST_MIXER1] = { 0x08, BIT(1) }, [RST_WB] = { 0x08, BIT(2) }, - [RST_ROT] = { 0x08, BIT(3) }, }; static const struct sunxi_ccu_desc sun8i_a83t_de2_clk_desc = { @@ -215,28 +234,18 @@ static const struct sunxi_ccu_desc sun8i_h3_de2_clk_desc = { .hw_clks = &sun8i_h3_de2_hw_clks, - .resets = sun8i_a83t_de2_resets, - .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), + .resets = sun8i_h3_de2_resets, + .num_resets = ARRAY_SIZE(sun8i_h3_de2_resets), }; -static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = { - .ccu_clks = sun8i_h3_de2_clks, - .num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks), +static const struct sunxi_ccu_desc sun8i_r40_de2_clk_desc = { + .ccu_clks = sun50i_a64_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun50i_a64_de2_clks), - .hw_clks = &sun8i_h3_de2_hw_clks, + .hw_clks = &sun50i_a64_de2_hw_clks, - .resets = sun50i_a64_de2_resets, - .num_resets = ARRAY_SIZE(sun50i_a64_de2_resets), -}; - -static const struct sunxi_ccu_desc sun50i_h6_de3_clk_desc = { - .ccu_clks = sun50i_h6_de3_clks, - .num_ccu_clks = ARRAY_SIZE(sun50i_h6_de3_clks), - - .hw_clks = &sun50i_h6_de3_hw_clks, - - .resets = sun50i_h6_de3_resets, - .num_resets = ARRAY_SIZE(sun50i_h6_de3_resets), + .resets = sun8i_a83t_de2_resets, + .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), }; static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = { @@ -249,6 +258,26 @@ static const struct sunxi_ccu_desc sun8i_v3s_de2_clk_desc = { .num_resets = ARRAY_SIZE(sun8i_a83t_de2_resets), }; +static const struct sunxi_ccu_desc sun50i_a64_de2_clk_desc = { + .ccu_clks = sun50i_a64_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun50i_a64_de2_clks), + + .hw_clks = &sun50i_a64_de2_hw_clks, + + .resets = sun50i_a64_de2_resets, + .num_resets = ARRAY_SIZE(sun50i_a64_de2_resets), +}; + +static const struct sunxi_ccu_desc sun50i_h5_de2_clk_desc = { + .ccu_clks = sun8i_h3_de2_clks, + .num_ccu_clks = ARRAY_SIZE(sun8i_h3_de2_clks), + + .hw_clks = &sun8i_h3_de2_hw_clks, + + .resets = sun50i_h5_de2_resets, + .num_resets = ARRAY_SIZE(sun50i_h5_de2_resets), +}; + static int sunxi_de2_clk_probe(struct platform_device *pdev) { struct resource *res; @@ -338,6 +367,10 @@ static const struct of_device_id sunxi_de2_clk_ids[] = { .data = &sun8i_h3_de2_clk_desc, }, { + .compatible = "allwinner,sun8i-r40-de2-clk", + .data = &sun8i_r40_de2_clk_desc, + }, + { .compatible = "allwinner,sun8i-v3s-de2-clk", .data = &sun8i_v3s_de2_clk_desc, }, @@ -347,11 +380,11 @@ static const struct of_device_id sunxi_de2_clk_ids[] = { }, { .compatible = "allwinner,sun50i-h5-de2-clk", - .data = &sun50i_a64_de2_clk_desc, + .data = &sun50i_h5_de2_clk_desc, }, { .compatible = "allwinner,sun50i-h6-de3-clk", - .data = &sun50i_h6_de3_clk_desc, + .data = &sun50i_h5_de2_clk_desc, }, { } }; |