Skip to content

Commit

Permalink
clk: meson: split divider and gate part of mpll
Browse files Browse the repository at this point in the history
The mpll clock is a kind of fractional divider which can gate.
When the RW operation have been added, enable/disable ops have been
mistakenly inserted in this driver. These ops are essentially a
poor copy/paste of the generic gate ops.

This change removes the gate ops from the mpll driver and inserts a
generic gate clock on each mpll divider, simplifying the mpll
driver and reducing code duplication.

Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
  • Loading branch information
Jerome Brunet authored and Neil Armstrong committed Mar 13, 2018
1 parent 722825d commit d610b54
Show file tree
Hide file tree
Showing 8 changed files with 197 additions and 118 deletions.
100 changes: 72 additions & 28 deletions drivers/clk/meson/axg.c
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ static struct clk_fixed_factor axg_fclk_div7 = {
},
};

static struct clk_regmap axg_mpll0 = {
static struct clk_regmap axg_mpll0_div = {
.data = &(struct meson_clk_mpll_data){
.sdm = {
.reg_off = HHI_MPLL_CNTL7,
Expand All @@ -313,11 +313,6 @@ static struct clk_regmap axg_mpll0 = {
.shift = 16,
.width = 9,
},
.en = {
.reg_off = HHI_MPLL_CNTL7,
.shift = 14,
.width = 1,
},
.ssen = {
.reg_off = HHI_MPLL_CNTL,
.shift = 25,
Expand All @@ -331,14 +326,28 @@ static struct clk_regmap axg_mpll0 = {
.lock = &meson_clk_lock,
},
.hw.init = &(struct clk_init_data){
.name = "mpll0",
.name = "mpll0_div",
.ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};

static struct clk_regmap axg_mpll1 = {
static struct clk_regmap axg_mpll0 = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_MPLL_CNTL7,
.bit_idx = 14,
},
.hw.init = &(struct clk_init_data){
.name = "mpll0",
.ops = &clk_regmap_gate_ops,
.parent_names = (const char *[]){ "mpll0_div" },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};

static struct clk_regmap axg_mpll1_div = {
.data = &(struct meson_clk_mpll_data){
.sdm = {
.reg_off = HHI_MPLL_CNTL8,
Expand All @@ -355,11 +364,6 @@ static struct clk_regmap axg_mpll1 = {
.shift = 16,
.width = 9,
},
.en = {
.reg_off = HHI_MPLL_CNTL8,
.shift = 14,
.width = 1,
},
.misc = {
.reg_off = HHI_PLL_TOP_MISC,
.shift = 1,
Expand All @@ -368,14 +372,28 @@ static struct clk_regmap axg_mpll1 = {
.lock = &meson_clk_lock,
},
.hw.init = &(struct clk_init_data){
.name = "mpll1",
.name = "mpll1_div",
.ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};

static struct clk_regmap axg_mpll2 = {
static struct clk_regmap axg_mpll1 = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_MPLL_CNTL8,
.bit_idx = 14,
},
.hw.init = &(struct clk_init_data){
.name = "mpll1",
.ops = &clk_regmap_gate_ops,
.parent_names = (const char *[]){ "mpll1_div" },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};

static struct clk_regmap axg_mpll2_div = {
.data = &(struct meson_clk_mpll_data){
.sdm = {
.reg_off = HHI_MPLL_CNTL9,
Expand All @@ -392,11 +410,6 @@ static struct clk_regmap axg_mpll2 = {
.shift = 16,
.width = 9,
},
.en = {
.reg_off = HHI_MPLL_CNTL9,
.shift = 14,
.width = 1,
},
.misc = {
.reg_off = HHI_PLL_TOP_MISC,
.shift = 2,
Expand All @@ -405,14 +418,28 @@ static struct clk_regmap axg_mpll2 = {
.lock = &meson_clk_lock,
},
.hw.init = &(struct clk_init_data){
.name = "mpll2",
.name = "mpll2_div",
.ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};

static struct clk_regmap axg_mpll3 = {
static struct clk_regmap axg_mpll2 = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_MPLL_CNTL9,
.bit_idx = 14,
},
.hw.init = &(struct clk_init_data){
.name = "mpll2",
.ops = &clk_regmap_gate_ops,
.parent_names = (const char *[]){ "mpll2_div" },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};

static struct clk_regmap axg_mpll3_div = {
.data = &(struct meson_clk_mpll_data){
.sdm = {
.reg_off = HHI_MPLL3_CNTL0,
Expand All @@ -429,11 +456,6 @@ static struct clk_regmap axg_mpll3 = {
.shift = 2,
.width = 9,
},
.en = {
.reg_off = HHI_MPLL3_CNTL0,
.shift = 0,
.width = 1,
},
.misc = {
.reg_off = HHI_PLL_TOP_MISC,
.shift = 3,
Expand All @@ -442,13 +464,27 @@ static struct clk_regmap axg_mpll3 = {
.lock = &meson_clk_lock,
},
.hw.init = &(struct clk_init_data){
.name = "mpll3",
.name = "mpll3_div",
.ops = &meson_clk_mpll_ops,
.parent_names = (const char *[]){ "fixed_pll" },
.num_parents = 1,
},
};

static struct clk_regmap axg_mpll3 = {
.data = &(struct clk_regmap_gate_data){
.offset = HHI_MPLL3_CNTL0,
.bit_idx = 0,
},
.hw.init = &(struct clk_init_data){
.name = "mpll3",
.ops = &clk_regmap_gate_ops,
.parent_names = (const char *[]){ "mpll3_div" },
.num_parents = 1,
.flags = CLK_SET_RATE_PARENT,
},
};

static u32 mux_table_clk81[] = { 0, 2, 3, 4, 5, 6, 7 };
static const char * const clk81_parent_names[] = {
"xtal", "fclk_div7", "mpll1", "mpll2", "fclk_div4",
Expand Down Expand Up @@ -722,6 +758,10 @@ static struct clk_hw_onecell_data axg_hw_onecell_data = {
[CLKID_SD_EMMC_C_CLK0_SEL] = &axg_sd_emmc_c_clk0_sel.hw,
[CLKID_SD_EMMC_C_CLK0_DIV] = &axg_sd_emmc_c_clk0_div.hw,
[CLKID_SD_EMMC_C_CLK0] = &axg_sd_emmc_c_clk0.hw,
[CLKID_MPLL0_DIV] = &axg_mpll0_div.hw,
[CLKID_MPLL1_DIV] = &axg_mpll1_div.hw,
[CLKID_MPLL2_DIV] = &axg_mpll2_div.hw,
[CLKID_MPLL3_DIV] = &axg_mpll3_div.hw,
[NR_CLKS] = NULL,
},
.num = NR_CLKS,
Expand Down Expand Up @@ -786,6 +826,10 @@ static struct clk_regmap *const axg_clk_regmaps[] = {
&axg_mpll1,
&axg_mpll2,
&axg_mpll3,
&axg_mpll0_div,
&axg_mpll1_div,
&axg_mpll2_div,
&axg_mpll3_div,
&axg_fixed_pll,
&axg_sys_pll,
&axg_gp0_pll,
Expand Down
6 changes: 5 additions & 1 deletion drivers/clk/meson/axg.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,8 +117,12 @@
#define CLKID_SD_EMMC_B_CLK0_DIV 62
#define CLKID_SD_EMMC_C_CLK0_SEL 63
#define CLKID_SD_EMMC_C_CLK0_DIV 64
#define CLKID_MPLL0_DIV 65
#define CLKID_MPLL1_DIV 66
#define CLKID_MPLL2_DIV 67
#define CLKID_MPLL3_DIV 68

#define NR_CLKS 65
#define NR_CLKS 69

/* include the CLKIDs that have been made part of the DT binding */
#include <dt-bindings/clock/axg-clkc.h>
Expand Down
44 changes: 0 additions & 44 deletions drivers/clk/meson/clk-mpll.c
Original file line number Diff line number Diff line change
Expand Up @@ -170,57 +170,13 @@ static int mpll_set_rate(struct clk_hw *hw,
return 0;
}

static void mpll_enable_core(struct clk_hw *hw, int enable)
{
struct clk_regmap *clk = to_clk_regmap(hw);
struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);
unsigned long flags = 0;

if (mpll->lock)
spin_lock_irqsave(mpll->lock, flags);
else
__acquire(mpll->lock);

meson_parm_write(clk->map, &mpll->en, enable ? 1 : 0);

if (mpll->lock)
spin_unlock_irqrestore(mpll->lock, flags);
else
__release(mpll->lock);
}


static int mpll_enable(struct clk_hw *hw)
{
mpll_enable_core(hw, 1);

return 0;
}

static void mpll_disable(struct clk_hw *hw)
{
mpll_enable_core(hw, 0);
}

static int mpll_is_enabled(struct clk_hw *hw)
{
struct clk_regmap *clk = to_clk_regmap(hw);
struct meson_clk_mpll_data *mpll = meson_clk_mpll_data(clk);

return meson_parm_read(clk->map, &mpll->en);
}

const struct clk_ops meson_clk_mpll_ro_ops = {
.recalc_rate = mpll_recalc_rate,
.round_rate = mpll_round_rate,
.is_enabled = mpll_is_enabled,
};

const struct clk_ops meson_clk_mpll_ops = {
.recalc_rate = mpll_recalc_rate,
.round_rate = mpll_round_rate,
.set_rate = mpll_set_rate,
.enable = mpll_enable,
.disable = mpll_disable,
.is_enabled = mpll_is_enabled,
};
1 change: 0 additions & 1 deletion drivers/clk/meson/clkc.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,6 @@ struct meson_clk_mpll_data {
struct parm sdm;
struct parm sdm_en;
struct parm n2;
struct parm en;
struct parm ssen;
struct parm misc;
spinlock_t *lock;
Expand Down
Loading

0 comments on commit d610b54

Please sign in to comment.