2015-04-03 14:00:25

by Georgi Djakov

[permalink] [raw]
Subject: [PATCH] clk: qcom: Fix parent_map translations

When we introduced the parent_map tables, we missed to update some
of the functions where mapping is translated. Fix this.

Signed-off-by: Georgi Djakov <[email protected]>
---
drivers/clk/qcom/clk-rcg.c | 13 ++++++++++---
drivers/clk/qcom/clk-rcg2.c | 20 +++++++++++++++-----
2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c
index 8f2f48071a7a..e30821a3ba68 100644
--- a/drivers/clk/qcom/clk-rcg.c
+++ b/drivers/clk/qcom/clk-rcg.c
@@ -319,7 +319,7 @@ static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
if (banked_p)
f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;

- f.src = index;
+ f.src = qcom_find_src_index(hw, rcg->s[bank].parent_map, index);
return configure_bank(rcg, &f);
}

@@ -411,13 +411,19 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
{
unsigned long clk_flags;
struct clk *p;
+ struct clk_rcg *rcg = to_clk_rcg(hw);
+ int index;

f = qcom_find_freq(f, rate);
if (!f)
return -EINVAL;

+ index = qcom_find_src_index(hw, rcg->s.parent_map, f->src);
+ if (index < 0)
+ return index;
+
clk_flags = __clk_get_flags(hw->clk);
- p = clk_get_parent_by_index(hw->clk, f->src);
+ p = clk_get_parent_by_index(hw->clk, index);
if (clk_flags & CLK_SET_RATE_PARENT) {
rate = rate * f->pre_div;
if (f->n) {
@@ -462,8 +468,9 @@ static long clk_rcg_bypass_determine_rate(struct clk_hw *hw, unsigned long rate,
struct clk_rcg *rcg = to_clk_rcg(hw);
const struct freq_tbl *f = rcg->freq_tbl;
struct clk *p;
+ int index = qcom_find_src_index(hw, rcg->s.parent_map, f->src);

- p = clk_get_parent_by_index(hw->clk, f->src);
+ p = clk_get_parent_by_index(hw->clk, index);
*p_hw = __clk_get_hw(p);
*p_rate = __clk_round_rate(p, rate);

diff --git a/drivers/clk/qcom/clk-rcg2.c b/drivers/clk/qcom/clk-rcg2.c
index 416becce4170..b95d17fbb8d7 100644
--- a/drivers/clk/qcom/clk-rcg2.c
+++ b/drivers/clk/qcom/clk-rcg2.c
@@ -182,13 +182,19 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
{
unsigned long clk_flags;
struct clk *p;
+ struct clk_rcg2 *rcg = to_clk_rcg2(hw);
+ int index;

f = qcom_find_freq(f, rate);
if (!f)
return -EINVAL;

+ index = qcom_find_src_index(hw, rcg->parent_map, f->src);
+ if (index < 0)
+ return index;
+
clk_flags = __clk_get_flags(hw->clk);
- p = clk_get_parent_by_index(hw->clk, f->src);
+ p = clk_get_parent_by_index(hw->clk, index);
if (clk_flags & CLK_SET_RATE_PARENT) {
if (f->pre_div) {
rate /= 2;
@@ -381,9 +387,10 @@ static long clk_edp_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
s64 request;
u32 mask = BIT(rcg->hid_width) - 1;
u32 hid_div;
+ int index = qcom_find_src_index(hw, rcg->parent_map, f->src);

/* Force the correct parent */
- *p = __clk_get_hw(clk_get_parent_by_index(hw->clk, f->src));
+ *p = __clk_get_hw(clk_get_parent_by_index(hw->clk, index));

if (src_rate == 810000000)
frac = frac_table_810m;
@@ -427,6 +434,7 @@ static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
{
struct clk_rcg2 *rcg = to_clk_rcg2(hw);
const struct freq_tbl *f = rcg->freq_tbl;
+ int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
unsigned long parent_rate, div;
u32 mask = BIT(rcg->hid_width) - 1;
struct clk *p;
@@ -434,7 +442,7 @@ static long clk_byte_determine_rate(struct clk_hw *hw, unsigned long rate,
if (rate == 0)
return -EINVAL;

- p = clk_get_parent_by_index(hw->clk, f->src);
+ p = clk_get_parent_by_index(hw->clk, index);
*p_hw = __clk_get_hw(p);
*p_rate = parent_rate = __clk_round_rate(p, rate);

@@ -496,7 +504,8 @@ static long clk_pixel_determine_rate(struct clk_hw *hw, unsigned long rate,
int delta = 100000;
const struct freq_tbl *f = rcg->freq_tbl;
const struct frac_entry *frac = frac_table_pixel;
- struct clk *parent = clk_get_parent_by_index(hw->clk, f->src);
+ int index = qcom_find_src_index(hw, rcg->parent_map, f->src);
+ struct clk *parent = clk_get_parent_by_index(hw->clk, index);

*p = __clk_get_hw(parent);

@@ -525,7 +534,8 @@ static int clk_pixel_set_rate(struct clk_hw *hw, unsigned long rate,
int delta = 100000;
u32 mask = BIT(rcg->hid_width) - 1;
u32 hid_div;
- struct clk *parent = clk_get_parent_by_index(hw->clk, f.src);
+ int index = qcom_find_src_index(hw, rcg->parent_map, f.src);
+ struct clk *parent = clk_get_parent_by_index(hw->clk, index);

for (; frac->num; frac++) {
request = (rate * frac->den) / frac->num;


2015-04-03 14:15:05

by Nicolas Dechesne

[permalink] [raw]
Subject: Re: [PATCH] clk: qcom: Fix parent_map translations

On Fri, Apr 3, 2015 at 4:00 PM, Georgi Djakov <[email protected]> wrote:
> When we introduced the parent_map tables, we missed to update some
> of the functions where mapping is translated. Fix this.
>
> Signed-off-by: Georgi Djakov <[email protected]>

thanks. I've tested this patch on top of [1] which was used when the
initial problem was reported/detected. and this branch had the faulty
commit:

commit 23cdacef13714d17d28b51fa942937b619203f24
Author: Georgi Djakov <[email protected]>
Date: Fri Mar 20 18:30:26 2015 +0200

clk: qcom: Introduce parent_map tables


I've tested sd, emmc, display and gpu, so

Tested-by: Nicolas Dechesne <[email protected]>

[1] https://git.linaro.org/landing-teams/working/qualcomm/kernel.git/shortlog/refs/heads/integration-linux-qcomlt

2015-04-06 20:58:02

by Stephen Boyd

[permalink] [raw]
Subject: Re: [PATCH] clk: qcom: Fix parent_map translations

On 04/03/15 07:00, Georgi Djakov wrote:
> When we introduced the parent_map tables, we missed to update some
> of the functions where mapping is translated. Fix this.
>
> Signed-off-by: Georgi Djakov <[email protected]>
> ---
> drivers/clk/qcom/clk-rcg.c | 13 ++++++++++---
> drivers/clk/qcom/clk-rcg2.c | 20 +++++++++++++++-----
> 2 files changed, 25 insertions(+), 8 deletions(-)
>
> diff --git a/drivers/clk/qcom/clk-rcg.c b/drivers/clk/qcom/clk-rcg.c
> index 8f2f48071a7a..e30821a3ba68 100644
> --- a/drivers/clk/qcom/clk-rcg.c
> +++ b/drivers/clk/qcom/clk-rcg.c
> @@ -319,7 +319,7 @@ static int clk_dyn_rcg_set_parent(struct clk_hw *hw, u8 index)
> if (banked_p)
> f.pre_div = ns_to_pre_div(&rcg->p[bank], ns) + 1;
>
> - f.src = index;
> + f.src = qcom_find_src_index(hw, rcg->s[bank].parent_map, index);
> return configure_bank(rcg, &f);
> }
>
> @@ -411,13 +411,19 @@ static long _freq_tbl_determine_rate(struct clk_hw *hw,
> {
> unsigned long clk_flags;
> struct clk *p;
> + struct clk_rcg *rcg = to_clk_rcg(hw);

This function is called by both clk_dyn_rcg_determine_rate() and
clk_rcg_determine_rate() which means struct clk_hw is wrapped by
different structs. The to_clk_rcg() is wrong here. How about we pass the
parent map to this function?

> + int index;
>
> f = qcom_find_freq(f, rate);
> if (!f)
> return -EINVAL;
>
> + index = qcom_find_src_index(hw, rcg->s.parent_map, f->src);
> + if (index < 0)
> + return index;
> +
> clk_flags = __clk_get_flags(hw->clk);
> - p = clk_get_parent_by_index(hw->clk, f->src);
> + p = clk_get_parent_by_index(hw->clk, index);
> if (clk_flags & CLK_SET_RATE_PARENT) {
> rate = rate * f->pre_div;
> if (f->n) {
>
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project