Commit ea0a1fb7 authored by Stephen Boyd's avatar Stephen Boyd

Merge branches 'clk-samsung', 'clk-formatting', 'clk-si5341' and 'clk-socfpga' into clk-next

* clk-samsung:
  clk: samsung: Remove redundant check in samsung_cmu_register_one

* clk-formatting:
  clk: Fix continuation of of_clk_detect_critical()

* clk-si5341:
  clk, clk-si5341: Support multiple input ports

* clk-socfpga:
  clk: socfpga: stratix10: simplify parameter passing
  clk: stratix10: use do_div() for 64-bit calculation
...@@ -16,6 +16,8 @@ ...@@ -16,6 +16,8 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <asm/unaligned.h> #include <asm/unaligned.h>
#define SI5341_NUM_INPUTS 4
#define SI5341_MAX_NUM_OUTPUTS 10 #define SI5341_MAX_NUM_OUTPUTS 10
#define SI5340_MAX_NUM_OUTPUTS 4 #define SI5340_MAX_NUM_OUTPUTS 4
...@@ -56,8 +58,8 @@ struct clk_si5341 { ...@@ -56,8 +58,8 @@ struct clk_si5341 {
struct i2c_client *i2c_client; struct i2c_client *i2c_client;
struct clk_si5341_synth synth[SI5341_NUM_SYNTH]; struct clk_si5341_synth synth[SI5341_NUM_SYNTH];
struct clk_si5341_output clk[SI5341_MAX_NUM_OUTPUTS]; struct clk_si5341_output clk[SI5341_MAX_NUM_OUTPUTS];
struct clk *pxtal; struct clk *input_clk[SI5341_NUM_INPUTS];
const char *pxtal_name; const char *input_clk_name[SI5341_NUM_INPUTS];
const u16 *reg_output_offset; const u16 *reg_output_offset;
const u16 *reg_rdiv_offset; const u16 *reg_rdiv_offset;
u64 freq_vco; /* 13500–14256 MHz */ u64 freq_vco; /* 13500–14256 MHz */
...@@ -78,10 +80,25 @@ struct clk_si5341_output_config { ...@@ -78,10 +80,25 @@ struct clk_si5341_output_config {
#define SI5341_DEVICE_REV 0x0005 #define SI5341_DEVICE_REV 0x0005
#define SI5341_STATUS 0x000C #define SI5341_STATUS 0x000C
#define SI5341_SOFT_RST 0x001C #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) */ /* Input dividers (48-bit) */
#define SI5341_IN_PDIV(x) (0x0208 + ((x) * 10)) #define SI5341_IN_PDIV(x) (0x0208 + ((x) * 10))
#define SI5341_IN_PSET(x) (0x020E + ((x) * 10)) #define SI5341_IN_PSET(x) (0x020E + ((x) * 10))
#define SI5341_PX_UPD 0x0230
/* PLL configuration */ /* PLL configuration */
#define SI5341_PLL_M_NUM 0x0235 #define SI5341_PLL_M_NUM 0x0235
...@@ -120,6 +137,10 @@ struct si5341_reg_default { ...@@ -120,6 +137,10 @@ struct si5341_reg_default {
u8 value; u8 value;
}; };
static const char * const si5341_input_clock_names[] = {
"in0", "in1", "in2", "xtal"
};
/* Output configuration registers 0..9 are not quite logically organized */ /* Output configuration registers 0..9 are not quite logically organized */
static const u16 si5341_reg_output_offset[] = { static const u16 si5341_reg_output_offset[] = {
0x0108, 0x0108,
...@@ -390,7 +411,112 @@ static unsigned long si5341_clk_recalc_rate(struct clk_hw *hw, ...@@ -390,7 +411,112 @@ static unsigned long si5341_clk_recalc_rate(struct clk_hw *hw,
return (unsigned long)res; 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 = { 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, .recalc_rate = si5341_clk_recalc_rate,
}; };
...@@ -985,7 +1111,8 @@ static const struct regmap_range si5341_regmap_volatile_range[] = { ...@@ -985,7 +1111,8 @@ static const struct regmap_range si5341_regmap_volatile_range[] = {
regmap_reg_range(0x000C, 0x0012), /* Status */ regmap_reg_range(0x000C, 0x0012), /* Status */
regmap_reg_range(0x001C, 0x001E), /* reset, finc/fdec */ regmap_reg_range(0x001C, 0x001E), /* reset, finc/fdec */
regmap_reg_range(0x00E2, 0x00FE), /* NVM, interrupts, device ready */ 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(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(1), SI5341_SYNTH_N_UPD(1)),
regmap_reg_range(SI5341_SYNTH_N_UPD(2), SI5341_SYNTH_N_UPD(2)), 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) ...@@ -1122,6 +1249,7 @@ static int si5341_initialize_pll(struct clk_si5341 *data)
struct device_node *np = data->i2c_client->dev.of_node; struct device_node *np = data->i2c_client->dev.of_node;
u32 m_num = 0; u32 m_num = 0;
u32 m_den = 0; u32 m_den = 0;
int sel;
if (of_property_read_u32(np, "silabs,pll-m-num", &m_num)) { if (of_property_read_u32(np, "silabs,pll-m-num", &m_num)) {
dev_err(&data->i2c_client->dev, dev_err(&data->i2c_client->dev,
...@@ -1135,7 +1263,11 @@ static int si5341_initialize_pll(struct clk_si5341 *data) ...@@ -1135,7 +1263,11 @@ static int si5341_initialize_pll(struct clk_si5341 *data)
if (!m_num || !m_den) { if (!m_num || !m_den) {
dev_err(&data->i2c_client->dev, dev_err(&data->i2c_client->dev,
"PLL configuration invalid, assume 14GHz\n"); "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; m_num = 1400000000;
} }
...@@ -1143,11 +1275,52 @@ static int si5341_initialize_pll(struct clk_si5341 *data) ...@@ -1143,11 +1275,52 @@ static int si5341_initialize_pll(struct clk_si5341 *data)
SI5341_PLL_M_NUM, m_num, m_den); 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, static int si5341_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
struct clk_si5341 *data; struct clk_si5341 *data;
struct clk_init_data init; struct clk_init_data init;
struct clk *input;
const char *root_clock_name; const char *root_clock_name;
const char *synth_clock_names[SI5341_NUM_SYNTH]; const char *synth_clock_names[SI5341_NUM_SYNTH];
int err; int err;
...@@ -1161,12 +1334,16 @@ static int si5341_probe(struct i2c_client *client, ...@@ -1161,12 +1334,16 @@ static int si5341_probe(struct i2c_client *client,
data->i2c_client = client; data->i2c_client = client;
data->pxtal = devm_clk_get(&client->dev, "xtal"); for (i = 0; i < SI5341_NUM_INPUTS; ++i) {
if (IS_ERR(data->pxtal)) { input = devm_clk_get(&client->dev, si5341_input_clock_names[i]);
if (PTR_ERR(data->pxtal) == -EPROBE_DEFER) if (IS_ERR(input)) {
if (PTR_ERR(input) == -EPROBE_DEFER)
return -EPROBE_DEFER; return -EPROBE_DEFER;
data->input_clk_name[i] = si5341_input_clock_names[i];
dev_err(&client->dev, "Missing xtal clock input\n"); } else {
data->input_clk[i] = input;
data->input_clk_name[i] = __clk_get_name(input);
}
} }
err = si5341_dt_parse_dt(client, config); err = si5341_dt_parse_dt(client, config);
...@@ -1188,9 +1365,6 @@ static int si5341_probe(struct i2c_client *client, ...@@ -1188,9 +1365,6 @@ static int si5341_probe(struct i2c_client *client,
if (err < 0) if (err < 0)
return err; 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")) { if (of_property_read_bool(client->dev.of_node, "silabs,reprogram")) {
initialization_required = true; initialization_required = true;
} else { } else {
...@@ -1223,7 +1397,14 @@ static int si5341_probe(struct i2c_client *client, ...@@ -1223,7 +1397,14 @@ static int si5341_probe(struct i2c_client *client,
ARRAY_SIZE(si5341_reg_defaults)); ARRAY_SIZE(si5341_reg_defaults));
if (err < 0) if (err < 0)
return err; 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 */ /* PLL configuration is required */
err = si5341_initialize_pll(data); err = si5341_initialize_pll(data);
if (err < 0) if (err < 0)
...@@ -1231,9 +1412,8 @@ static int si5341_probe(struct i2c_client *client, ...@@ -1231,9 +1412,8 @@ static int si5341_probe(struct i2c_client *client,
} }
/* Register the PLL */ /* Register the PLL */
data->pxtal_name = __clk_get_name(data->pxtal); init.parent_names = data->input_clk_name;
init.parent_names = &data->pxtal_name; init.num_parents = SI5341_NUM_INPUTS;
init.num_parents = 1; /* For now, only XTAL input supported */
init.ops = &si5341_clk_ops; init.ops = &si5341_clk_ops;
init.flags = 0; init.flags = 0;
data->hw.init = &init; data->hw.init = &init;
......
...@@ -4865,8 +4865,8 @@ static int parent_ready(struct device_node *np) ...@@ -4865,8 +4865,8 @@ static int parent_ready(struct device_node *np)
* *
* Return: error code or zero on success * Return: error code or zero on success
*/ */
int of_clk_detect_critical(struct device_node *np, int of_clk_detect_critical(struct device_node *np, int index,
int index, unsigned long *flags) unsigned long *flags)
{ {
struct property *prop; struct property *prop;
const __be32 *cur; const __be32 *cur;
......
...@@ -65,54 +65,49 @@ static const struct clk_ops dbgclk_ops = { ...@@ -65,54 +65,49 @@ static const struct clk_ops dbgclk_ops = {
.get_parent = socfpga_gate_get_parent, .get_parent = socfpga_gate_get_parent,
}; };
struct clk *s10_register_gate(const char *name, const char *parent_name, struct clk *s10_register_gate(const struct stratix10_gate_clock *clks, void __iomem *regbase)
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 *clk; struct clk *clk;
struct socfpga_gate_clk *socfpga_clk; struct socfpga_gate_clk *socfpga_clk;
struct clk_init_data init; 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); socfpga_clk = kzalloc(sizeof(*socfpga_clk), GFP_KERNEL);
if (!socfpga_clk) if (!socfpga_clk)
return NULL; return NULL;
socfpga_clk->hw.reg = regbase + gate_reg; socfpga_clk->hw.reg = regbase + clks->gate_reg;
socfpga_clk->hw.bit_idx = gate_idx; socfpga_clk->hw.bit_idx = clks->gate_idx;
gateclk_ops.enable = clk_gate_ops.enable; gateclk_ops.enable = clk_gate_ops.enable;
gateclk_ops.disable = clk_gate_ops.disable; gateclk_ops.disable = clk_gate_ops.disable;
socfpga_clk->fixed_div = fixed_div; socfpga_clk->fixed_div = clks->fixed_div;
if (div_reg) if (clks->div_reg)
socfpga_clk->div_reg = regbase + div_reg; socfpga_clk->div_reg = regbase + clks->div_reg;
else else
socfpga_clk->div_reg = NULL; socfpga_clk->div_reg = NULL;
socfpga_clk->width = div_width; socfpga_clk->width = clks->div_width;
socfpga_clk->shift = div_offset; socfpga_clk->shift = clks->div_offset;
if (bypass_reg) if (clks->bypass_reg)
socfpga_clk->bypass_reg = regbase + bypass_reg; socfpga_clk->bypass_reg = regbase + clks->bypass_reg;
else else
socfpga_clk->bypass_reg = NULL; 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; init.ops = &dbgclk_ops;
else else
init.ops = &gateclk_ops; init.ops = &gateclk_ops;
init.name = name; init.name = clks->name;
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; init.parent_names = parent_names ? parent_names : &parent_name;
socfpga_clk->hw.hw.init = &init; socfpga_clk->hw.hw.init = &init;
...@@ -121,6 +116,5 @@ struct clk *s10_register_gate(const char *name, const char *parent_name, ...@@ -121,6 +116,5 @@ struct clk *s10_register_gate(const char *name, const char *parent_name,
kfree(socfpga_clk); kfree(socfpga_clk);
return NULL; return NULL;
} }
return clk; return clk;
} }
...@@ -73,26 +73,27 @@ static const struct clk_ops peri_cnt_clk_ops = { ...@@ -73,26 +73,27 @@ static const struct clk_ops peri_cnt_clk_ops = {
.get_parent = clk_periclk_get_parent, .get_parent = clk_periclk_get_parent,
}; };
struct clk *s10_register_periph(const char *name, const char *parent_name, struct clk *s10_register_periph(const struct stratix10_perip_c_clock *clks,
const char * const *parent_names, void __iomem *reg)
u8 num_parents, unsigned long flags,
void __iomem *reg, unsigned long offset)
{ {
struct clk *clk; struct clk *clk;
struct socfpga_periph_clk *periph_clk; struct socfpga_periph_clk *periph_clk;
struct clk_init_data init; 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); periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
if (WARN_ON(!periph_clk)) if (WARN_ON(!periph_clk))
return NULL; return NULL;
periph_clk->hw.reg = reg + offset; periph_clk->hw.reg = reg + clks->offset;
init.name = name; init.name = name;
init.ops = &peri_c_clk_ops; 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; init.parent_names = parent_names ? parent_names : &parent_name;
periph_clk->hw.hw.init = &init; periph_clk->hw.hw.init = &init;
...@@ -105,38 +106,37 @@ struct clk *s10_register_periph(const char *name, const char *parent_name, ...@@ -105,38 +106,37 @@ struct clk *s10_register_periph(const char *name, const char *parent_name,
return clk; return clk;
} }
struct clk *s10_register_cnt_periph(const char *name, const char *parent_name, struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *clks,
const char * const *parent_names, void __iomem *regbase)
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 *clk; struct clk *clk;
struct socfpga_periph_clk *periph_clk; struct socfpga_periph_clk *periph_clk;
struct clk_init_data init; 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); periph_clk = kzalloc(sizeof(*periph_clk), GFP_KERNEL);
if (WARN_ON(!periph_clk)) if (WARN_ON(!periph_clk))
return NULL; return NULL;
if (offset) if (clks->offset)
periph_clk->hw.reg = regbase + offset; periph_clk->hw.reg = regbase + clks->offset;
else else
periph_clk->hw.reg = NULL; periph_clk->hw.reg = NULL;
if (bypass_reg) if (clks->bypass_reg)
periph_clk->bypass_reg = regbase + bypass_reg; periph_clk->bypass_reg = regbase + clks->bypass_reg;
else else
periph_clk->bypass_reg = NULL; periph_clk->bypass_reg = NULL;
periph_clk->bypass_shift = bypass_shift; periph_clk->bypass_shift = clks->bypass_shift;
periph_clk->fixed_div = fixed_divider; periph_clk->fixed_div = clks->fixed_divider;
init.name = name; init.name = name;
init.ops = &peri_cnt_clk_ops; 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; init.parent_names = parent_names ? parent_names : &parent_name;
periph_clk->hw.hw.init = &init; periph_clk->hw.hw.init = &init;
......
...@@ -39,7 +39,9 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk, ...@@ -39,7 +39,9 @@ static unsigned long clk_pll_recalc_rate(struct clk_hw *hwclk,
/* read VCO1 reg for numerator and denominator */ /* read VCO1 reg for numerator and denominator */
reg = readl(socfpgaclk->hw.reg); reg = readl(socfpgaclk->hw.reg);
refdiv = (reg & SOCFPGA_PLL_REFDIV_MASK) >> SOCFPGA_PLL_REFDIV_SHIFT; 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 */ /* Read mdiv and fdiv from the fdbck register */
reg = readl(socfpgaclk->hw.reg + 0x4); reg = readl(socfpgaclk->hw.reg + 0x4);
...@@ -108,19 +110,20 @@ static struct clk_ops clk_boot_ops = { ...@@ -108,19 +110,20 @@ static struct clk_ops clk_boot_ops = {
.prepare = clk_pll_prepare, .prepare = clk_pll_prepare,
}; };
struct clk *s10_register_pll(const char *name, const char * const *parent_names, struct clk *s10_register_pll(const struct stratix10_pll_clock *clks,
u8 num_parents, unsigned long flags, void __iomem *reg)
void __iomem *reg, unsigned long offset)
{ {
struct clk *clk; struct clk *clk;
struct socfpga_pll *pll_clk; struct socfpga_pll *pll_clk;
struct clk_init_data init; 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); pll_clk = kzalloc(sizeof(*pll_clk), GFP_KERNEL);
if (WARN_ON(!pll_clk)) if (WARN_ON(!pll_clk))
return NULL; return NULL;
pll_clk->hw.reg = reg + offset; pll_clk->hw.reg = reg + clks->offset;
if (streq(name, SOCFPGA_BOOT_CLK)) if (streq(name, SOCFPGA_BOOT_CLK))
init.ops = &clk_boot_ops; init.ops = &clk_boot_ops;
...@@ -128,9 +131,9 @@ struct clk *s10_register_pll(const char *name, const char * const *parent_names, ...@@ -128,9 +131,9 @@ struct clk *s10_register_pll(const char *name, const char * const *parent_names,
init.ops = &clk_pll_ops; init.ops = &clk_pll_ops;
init.name = name; 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; init.parent_names = parent_names;
pll_clk->hw.hw.init = &init; pll_clk->hw.hw.init = &init;
......
...@@ -177,9 +177,7 @@ static int s10_clk_register_c_perip(const struct stratix10_perip_c_clock *clks, ...@@ -177,9 +177,7 @@ static int s10_clk_register_c_perip(const struct stratix10_perip_c_clock *clks,
int i; int i;
for (i = 0; i < nums; i++) { for (i = 0; i < nums; i++) {
clk = s10_register_periph(clks[i].name, clks[i].parent_name, clk = s10_register_periph(&clks[i], base);
clks[i].parent_names, clks[i].num_parents,
clks[i].flags, base, clks[i].offset);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name); __func__, clks[i].name);
...@@ -198,14 +196,7 @@ static int s10_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *cl ...@@ -198,14 +196,7 @@ static int s10_clk_register_cnt_perip(const struct stratix10_perip_cnt_clock *cl
int i; int i;
for (i = 0; i < nums; i++) { for (i = 0; i < nums; i++) {
clk = s10_register_cnt_periph(clks[i].name, clks[i].parent_name, clk = s10_register_cnt_periph(&clks[i], base);
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);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name); __func__, clks[i].name);
...@@ -225,16 +216,7 @@ static int s10_clk_register_gate(const struct stratix10_gate_clock *clks, ...@@ -225,16 +216,7 @@ static int s10_clk_register_gate(const struct stratix10_gate_clock *clks,
int i; int i;
for (i = 0; i < nums; i++) { for (i = 0; i < nums; i++) {
clk = s10_register_gate(clks[i].name, clks[i].parent_name, clk = s10_register_gate(&clks[i], base);
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);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name); __func__, clks[i].name);
...@@ -254,10 +236,7 @@ static int s10_clk_register_pll(const struct stratix10_pll_clock *clks, ...@@ -254,10 +236,7 @@ static int s10_clk_register_pll(const struct stratix10_pll_clock *clks,
int i; int i;
for (i = 0; i < nums; i++) { for (i = 0; i < nums; i++) {
clk = s10_register_pll(clks[i].name, clks[i].parent_names, clk = s10_register_pll(&clks[i], base);
clks[i].num_parents,
clks[i].flags, base,
clks[i].offset);
if (IS_ERR(clk)) { if (IS_ERR(clk)) {
pr_err("%s: failed to register clock %s\n", pr_err("%s: failed to register clock %s\n",
__func__, clks[i].name); __func__, clks[i].name);
......
...@@ -60,21 +60,12 @@ struct stratix10_gate_clock { ...@@ -60,21 +60,12 @@ struct stratix10_gate_clock {
u8 fixed_div; u8 fixed_div;
}; };
struct clk *s10_register_pll(const char *, const char *const *, u8, struct clk *s10_register_pll(const struct stratix10_pll_clock *,
unsigned long, void __iomem *, unsigned long); void __iomem *);
struct clk *s10_register_periph(const struct stratix10_perip_c_clock *,
struct clk *s10_register_periph(const char *, const char *, void __iomem *);
const char * const *, u8, unsigned long, struct clk *s10_register_cnt_periph(const struct stratix10_perip_cnt_clock *,
void __iomem *, unsigned long); void __iomem *);
struct clk *s10_register_cnt_periph(const char *, const char *, struct clk *s10_register_gate(const struct stratix10_gate_clock *,
const char * const *, u8, void __iomem *);
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);
#endif /* __STRATIX10_CLK_H */ #endif /* __STRATIX10_CLK_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