Skip to content

Commit

Permalink
clk: qcom: Introduce parent_map tables
Browse files Browse the repository at this point in the history
In the current parent mapping code, we can get duplicate or inconsistent
indexes, which leads to discrepancy between the number of elements in the
array and the number of parents. Until now, this was solved with some
reordering but this is not always possible.

This patch introduces index tables that are used to define the relations
between the PLL source and the hardware mux configuration value.
To accomplish this, here we do the following:
 - Define a parent_map struct to map the relations between PLL source index
 and register configuration value.
 - Add a qcom_find_src_index() function for finding the index of a clock
 matching the specific PLL configuration.
 - Update the {set,get}_parent RCG functions use the newly introduced
 parent_map struct.
 - Convert all existing drivers to the new parent_map tables.

Signed-off-by: Georgi Djakov <georgi.djakov@linaro.org>
Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
  • Loading branch information
Georgi Djakov authored and Stephen Boyd committed Mar 23, 2015
1 parent fae507a commit 293d2e9
Show file tree
Hide file tree
Showing 15 changed files with 338 additions and 286 deletions.
13 changes: 8 additions & 5 deletions drivers/clk/qcom/clk-rcg.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ static u8 clk_rcg_get_parent(struct clk_hw *hw)
goto err;
ns = ns_to_src(&rcg->s, ns);
for (i = 0; i < num_parents; i++)
if (ns == rcg->s.parent_map[i])
if (ns == rcg->s.parent_map[i].cfg)
return i;

err:
Expand Down Expand Up @@ -90,7 +90,7 @@ static u8 clk_dyn_rcg_get_parent(struct clk_hw *hw)
ns = ns_to_src(s, ns);

for (i = 0; i < num_parents; i++)
if (ns == s->parent_map[i])
if (ns == s->parent_map[i].cfg)
return i;

err:
Expand All @@ -105,7 +105,7 @@ static int clk_rcg_set_parent(struct clk_hw *hw, u8 index)
u32 ns;

regmap_read(rcg->clkr.regmap, rcg->ns_reg, &ns);
ns = src_to_ns(&rcg->s, rcg->s.parent_map[index], ns);
ns = src_to_ns(&rcg->s, rcg->s.parent_map[index].cfg, ns);
regmap_write(rcg->clkr.regmap, rcg->ns_reg, ns);

return 0;
Expand Down Expand Up @@ -206,7 +206,7 @@ static u32 mn_to_reg(struct mn *mn, u32 m, u32 n, u32 val)
static int configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
{
u32 ns, md, reg;
int bank, new_bank, ret;
int bank, new_bank, ret, index;
struct mn *mn;
struct pre_div *p;
struct src_sel *s;
Expand Down Expand Up @@ -276,7 +276,10 @@ static int configure_bank(struct clk_dyn_rcg *rcg, const struct freq_tbl *f)
}

s = &rcg->s[new_bank];
ns = src_to_ns(s, s->parent_map[f->src], ns);
index = qcom_find_src_index(hw, s->parent_map, f->src);
if (index < 0)
return index;
ns = src_to_ns(s, s->parent_map[index].cfg, ns);
ret = regmap_write(rcg->clkr.regmap, ns_reg, ns);
if (ret)
return ret;
Expand Down
14 changes: 12 additions & 2 deletions drivers/clk/qcom/clk-rcg.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,16 @@ struct freq_tbl {
u16 n;
};

/**
* struct parent_map - map table for PLL source select configuration values
* @src: source PLL
* @cfg: configuration value
*/
struct parent_map {
u8 src;
u8 cfg;
};

/**
* struct mn - M/N:D counter
* @mnctr_en_bit: bit to enable mn counter
Expand Down Expand Up @@ -65,7 +75,7 @@ struct pre_div {
struct src_sel {
u8 src_sel_shift;
#define SRC_SEL_MASK 0x7
const u8 *parent_map;
const struct parent_map *parent_map;
};

/**
Expand Down Expand Up @@ -151,7 +161,7 @@ struct clk_rcg2 {
u32 cmd_rcgr;
u8 mnd_width;
u8 hid_width;
const u8 *parent_map;
const struct parent_map *parent_map;
const struct freq_tbl *freq_tbl;
struct clk_regmap clkr;
};
Expand Down
14 changes: 9 additions & 5 deletions drivers/clk/qcom/clk-rcg2.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ static u8 clk_rcg2_get_parent(struct clk_hw *hw)
cfg >>= CFG_SRC_SEL_SHIFT;

for (i = 0; i < num_parents; i++)
if (cfg == rcg->parent_map[i])
if (cfg == rcg->parent_map[i].cfg)
return i;

err:
Expand Down Expand Up @@ -114,10 +114,10 @@ static int clk_rcg2_set_parent(struct clk_hw *hw, u8 index)
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
int ret;
u32 cfg = rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;

ret = regmap_update_bits(rcg->clkr.regmap, rcg->cmd_rcgr + CFG_REG,
CFG_SRC_SEL_MASK,
rcg->parent_map[index] << CFG_SRC_SEL_SHIFT);
CFG_SRC_SEL_MASK, cfg);
if (ret)
return ret;

Expand Down Expand Up @@ -222,7 +222,11 @@ static long clk_rcg2_determine_rate(struct clk_hw *hw, unsigned long rate,
static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
{
u32 cfg, mask;
int ret;
struct clk_hw *hw = &rcg->clkr.hw;
int ret, index = qcom_find_src_index(hw, rcg->parent_map, f->src);

if (index < 0)
return index;

if (rcg->mnd_width && f->n) {
mask = BIT(rcg->mnd_width) - 1;
Expand All @@ -245,7 +249,7 @@ static int clk_rcg2_configure(struct clk_rcg2 *rcg, const struct freq_tbl *f)
mask = BIT(rcg->hid_width) - 1;
mask |= CFG_SRC_SEL_MASK | CFG_MODE_MASK;
cfg = f->pre_div << CFG_SRC_DIV_SHIFT;
cfg |= rcg->parent_map[f->src] << CFG_SRC_SEL_SHIFT;
cfg |= rcg->parent_map[index].cfg << CFG_SRC_SEL_SHIFT;
if (rcg->mnd_width && f->n && (f->m != f->n))
cfg |= CFG_MODE_DUAL_EDGE;
ret = regmap_update_bits(rcg->clkr.regmap,
Expand Down
12 changes: 12 additions & 0 deletions drivers/clk/qcom/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,18 @@ struct freq_tbl *qcom_find_freq(const struct freq_tbl *f, unsigned long rate)
}
EXPORT_SYMBOL_GPL(qcom_find_freq);

int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map, u8 src)
{
int i, num_parents = __clk_get_num_parents(hw->clk);

for (i = 0; i < num_parents; i++)
if (src == map[i].src)
return i;

return -ENOENT;
}
EXPORT_SYMBOL_GPL(qcom_find_src_index);

struct regmap *
qcom_cc_map(struct platform_device *pdev, const struct qcom_cc_desc *desc)
{
Expand Down
4 changes: 4 additions & 0 deletions drivers/clk/qcom/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ struct clk_regmap;
struct qcom_reset_map;
struct regmap;
struct freq_tbl;
struct clk_hw;
struct parent_map;

struct qcom_cc_desc {
const struct regmap_config *config;
Expand All @@ -30,6 +32,8 @@ struct qcom_cc_desc {

extern const struct freq_tbl *qcom_find_freq(const struct freq_tbl *f,
unsigned long rate);
extern int qcom_find_src_index(struct clk_hw *hw, const struct parent_map *map,
u8 src);

extern struct regmap *qcom_cc_map(struct platform_device *pdev,
const struct qcom_cc_desc *desc);
Expand Down
62 changes: 32 additions & 30 deletions drivers/clk/qcom/gcc-apq8084.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,29 +32,31 @@
#include "clk-branch.h"
#include "reset.h"

#define P_XO 0
#define P_GPLL0 1
#define P_GPLL1 1
#define P_GPLL4 2
#define P_PCIE_0_1_PIPE_CLK 1
#define P_SATA_ASIC0_CLK 1
#define P_SATA_RX_CLK 1
#define P_SLEEP_CLK 1
enum {
P_XO,
P_GPLL0,
P_GPLL1,
P_GPLL4,
P_PCIE_0_1_PIPE_CLK,
P_SATA_ASIC0_CLK,
P_SATA_RX_CLK,
P_SLEEP_CLK,
};

static const u8 gcc_xo_gpll0_map[] = {
[P_XO] = 0,
[P_GPLL0] = 1,
static const struct parent_map gcc_xo_gpll0_map[] = {
{ P_XO, 0 },
{ P_GPLL0, 1 }
};

static const char *gcc_xo_gpll0[] = {
"xo",
"gpll0_vote",
};

static const u8 gcc_xo_gpll0_gpll4_map[] = {
[P_XO] = 0,
[P_GPLL0] = 1,
[P_GPLL4] = 5,
static const struct parent_map gcc_xo_gpll0_gpll4_map[] = {
{ P_XO, 0 },
{ P_GPLL0, 1 },
{ P_GPLL4, 5 }
};

static const char *gcc_xo_gpll0_gpll4[] = {
Expand All @@ -63,39 +65,39 @@ static const char *gcc_xo_gpll0_gpll4[] = {
"gpll4_vote",
};

static const u8 gcc_xo_sata_asic0_map[] = {
[P_XO] = 0,
[P_SATA_ASIC0_CLK] = 2,
static const struct parent_map gcc_xo_sata_asic0_map[] = {
{ P_XO, 0 },
{ P_SATA_ASIC0_CLK, 2 }
};

static const char *gcc_xo_sata_asic0[] = {
"xo",
"sata_asic0_clk",
};

static const u8 gcc_xo_sata_rx_map[] = {
[P_XO] = 0,
[P_SATA_RX_CLK] = 2,
static const struct parent_map gcc_xo_sata_rx_map[] = {
{ P_XO, 0 },
{ P_SATA_RX_CLK, 2}
};

static const char *gcc_xo_sata_rx[] = {
"xo",
"sata_rx_clk",
};

static const u8 gcc_xo_pcie_map[] = {
[P_XO] = 0,
[P_PCIE_0_1_PIPE_CLK] = 2,
static const struct parent_map gcc_xo_pcie_map[] = {
{ P_XO, 0 },
{ P_PCIE_0_1_PIPE_CLK, 2 }
};

static const char *gcc_xo_pcie[] = {
"xo",
"pcie_pipe",
};

static const u8 gcc_xo_pcie_sleep_map[] = {
[P_XO] = 0,
[P_SLEEP_CLK] = 6,
static const struct parent_map gcc_xo_pcie_sleep_map[] = {
{ P_XO, 0 },
{ P_SLEEP_CLK, 6 }
};

static const char *gcc_xo_pcie_sleep[] = {
Expand Down Expand Up @@ -1263,9 +1265,9 @@ static const struct freq_tbl ftbl_gcc_usb_hsic_clk[] = {
{ }
};

static u8 usb_hsic_clk_src_map[] = {
[P_XO] = 0,
[P_GPLL1] = 4,
static const struct parent_map usb_hsic_clk_src_map[] = {
{ P_XO, 0 },
{ P_GPLL1, 4 }
};

static struct clk_rcg2 usb_hsic_clk_src = {
Expand Down
46 changes: 24 additions & 22 deletions drivers/clk/qcom/gcc-ipq806x.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,26 +140,28 @@ static struct clk_regmap pll14_vote = {
},
};

#define P_PXO 0
#define P_PLL8 1
#define P_PLL3 1
#define P_PLL0 2
#define P_CXO 2
enum {
P_PXO,
P_PLL8,
P_PLL3,
P_PLL0,
P_CXO,
};

static const u8 gcc_pxo_pll8_map[] = {
[P_PXO] = 0,
[P_PLL8] = 3,
static const struct parent_map gcc_pxo_pll8_map[] = {
{ P_PXO, 0 },
{ P_PLL8, 3 }
};

static const char *gcc_pxo_pll8[] = {
"pxo",
"pll8_vote",
};

static const u8 gcc_pxo_pll8_cxo_map[] = {
[P_PXO] = 0,
[P_PLL8] = 3,
[P_CXO] = 5,
static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
{ P_PXO, 0 },
{ P_PLL8, 3 },
{ P_CXO, 5 }
};

static const char *gcc_pxo_pll8_cxo[] = {
Expand All @@ -168,25 +170,25 @@ static const char *gcc_pxo_pll8_cxo[] = {
"cxo",
};

static const u8 gcc_pxo_pll3_map[] = {
[P_PXO] = 0,
[P_PLL3] = 1,
static const struct parent_map gcc_pxo_pll3_map[] = {
{ P_PXO, 0 },
{ P_PLL3, 1 }
};

static const u8 gcc_pxo_pll3_sata_map[] = {
[P_PXO] = 0,
[P_PLL3] = 6,
static const struct parent_map gcc_pxo_pll3_sata_map[] = {
{ P_PXO, 0 },
{ P_PLL3, 6 }
};

static const char *gcc_pxo_pll3[] = {
"pxo",
"pll3",
};

static const u8 gcc_pxo_pll8_pll0[] = {
[P_PXO] = 0,
[P_PLL8] = 3,
[P_PLL0] = 2,
static const struct parent_map gcc_pxo_pll8_pll0[] = {
{ P_PXO, 0 },
{ P_PLL8, 3 },
{ P_PLL0, 2 }
};

static const char *gcc_pxo_pll8_pll0_map[] = {
Expand Down
22 changes: 12 additions & 10 deletions drivers/clk/qcom/gcc-msm8660.c
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,26 @@ static struct clk_regmap pll8_vote = {
},
};

#define P_PXO 0
#define P_PLL8 1
#define P_CXO 2
enum {
P_PXO,
P_PLL8,
P_CXO,
};

static const u8 gcc_pxo_pll8_map[] = {
[P_PXO] = 0,
[P_PLL8] = 3,
static const struct parent_map gcc_pxo_pll8_map[] = {
{ P_PXO, 0 },
{ P_PLL8, 3 }
};

static const char *gcc_pxo_pll8[] = {
"pxo",
"pll8_vote",
};

static const u8 gcc_pxo_pll8_cxo_map[] = {
[P_PXO] = 0,
[P_PLL8] = 3,
[P_CXO] = 5,
static const struct parent_map gcc_pxo_pll8_cxo_map[] = {
{ P_PXO, 0 },
{ P_PLL8, 3 },
{ P_CXO, 5 }
};

static const char *gcc_pxo_pll8_cxo[] = {
Expand Down
Loading

0 comments on commit 293d2e9

Please sign in to comment.