clk: qcom: Fix pre-divider usage for pixel RCG
Subsystems (3)
PATCH 1/1 clk: qcom: Fix pre-divider usage for pixel RCG
The clk_rcg_pixel_set_rate clk_op sets up the pre-divider by reading its current value from the NS register.
Using the pre-divider wasn't really intended when creating these ops. The pixel RCG was only intended to achieve fractional multiplication provided in the pixel_table array. Leaving the pre-divider to the existing register value results in a wrong pixel clock when the bootloader sets up the display. This was left unidentified because the IFC6410 Plus board on which this was verified didn't have a bootloader that configured the display.
Don't set the RCG pre-divider in freq_tbl to the existing NS register value. Instead, set it based on the fractional multiplication we want. Prevent using M/N counter when we can just manage with using the pre-divider.
---
John, Vinay, could you please test this on N7 and confirm if it works?
drivers/clk/qcom/clk-rcg.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
drivers/clk/qcom/clk-rcg.c +7 -3
@@ -638,7 +638,6 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,return ret; src =ns_to_src (&rcg->s, ns); - f.pre_div =ns_to_pre_div (&rcg->p, ns) +1 ;for (i =0 ; i < num_parents; i++) {if (src == rcg->s.parent_map[i].cfg) {
@@ -655,8 +654,13 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, (parent_rate > (request + delta)))continue ; - f.m = frac->num; - f.n = frac->den; +/* try to use only the pre-divider if we can */ +if (frac->num ==1 ) { + f.pre_div = frac->den; + }else { + f.m = frac->num; + f.n = frac->den; + }return __clk_rcg_set_rate (rcg, &f); }
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
drivers/clk/qcom/clk-rcg.c static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, · line 659
Quoted 13 lines · Archit Taneja
drivers/clk/qcom/clk-rcg.c +3
-2@@ -655,8 +654,13 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, (parent_rate > (request + delta)))continue ; - f.m = frac->num; - f.n = frac->den; +/* try to use only the pre-divider if we can */ +if (frac->num ==1 ) { + f.pre_div = frac->den;
What if the pre divider can't support the frac->den value? Maybe we should just force the pre divider to be in bypass so that we can use the m/n all the time.
Quoted 7 lines
drivers/clk/qcom/clk-rcg.c +4
-0+ }else { + f.m = frac->num; + f.n = frac->den; + }return __clk_rcg_set_rate (rcg, &f); }
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Quoted 9 lines · Stephen Boyd
Quoted 8 lines · Archit Taneja
drivers/clk/qcom/clk-rcg.c +0
-0@@ -655,8 +654,13 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, (parent_rate > (request + delta)))continue ;
Quoted 9 lines
drivers/clk/qcom/clk-rcg.c static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, · line 659
Quoted 5 lines
drivers/clk/qcom/clk-rcg.c +3
-2- f.m = frac->num; - f.n = frac->den; +/* try to use only the pre-divider if we can */ +if (frac->num ==1 ) { + f.pre_div = frac->den;What if the pre divider can't support the
frac->denvalue? Maybe we should just force the pre divider to be in bypass so that we can use the m/n all the time.
Yeah, for some strange reason it seems like having a pre-divider as 3 itself doesn't seem to work. As you suggested, I'll force the pre divider to 1 and use m/n all the time.
Archit
Quoted 9 lines
Quoted 8 lines
drivers/clk/qcom/clk-rcg.c +4
-0+ }else { + f.m = frac->num; + f.n = frac->den; + }return __clk_rcg_set_rate (rcg, &f); }
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
Quoted 16 lines · Archit Taneja
The
clk_rcg_pixel_set_rateclk_opsets up the pre-divider by reading its current value from the NS register.Using the pre-divider wasn't really intended when creating these ops. The pixel RCG was only intended to achieve fractional multiplication provided in the
pixel_tablearray. Leaving the pre-divider to the existing register value results in a wrong pixel clock when the bootloader sets up the display. This was left unidentified because the IFC6410 Plus board on which this was verified didn't have a bootloader that configured the display.Don't set the RCG pre-divider in
freq_tblto the existing NS register value. Instead, set it based on the fractional multiplication we want. Prevent using M/N counter when we can just manage with using the pre-divider.
Quoted 5 lines
Cc John Stultz <[email protected]>Cc Vinay Simha <[email protected]>Signed-off-by Archit Taneja <[email protected]>---
John, Vinay, could you please test this on N7 and confirm if it works?
Hey Archit,
So this did not work for me. I removed the earlier patch forcing pre_div to 1, and added this, but that ended up with a mostly black screen with a bit of blue slowly scrolling down the side.
With the f.pre_div=1 line re-added, I don't see anything. The screen just goes black and doesn't come back.
Let me know if I can test anything else for you, or add any debug messages.
thanks
-john
Quoted 25 lines · John Stultz
Quoted 16 lines · Archit Taneja
The
clk_rcg_pixel_set_rateclk_opsets up the pre-divider by reading its current value from the NS register.Using the pre-divider wasn't really intended when creating these ops. The pixel RCG was only intended to achieve fractional multiplication provided in the
pixel_tablearray. Leaving the pre-divider to the existing register value results in a wrong pixel clock when the bootloader sets up the display. This was left unidentified because the IFC6410 Plus board on which this was verified didn't have a bootloader that configured the display.Don't set the RCG pre-divider in
freq_tblto the existing NS register value. Instead, set it based on the fractional multiplication we want. Prevent using M/N counter when we can just manage with using the pre-divider.Quoted 5 lines
Cc John Stultz <[email protected]>Cc Vinay Simha <[email protected]>Signed-off-by Archit Taneja <[email protected]>---
John, Vinay, could you please test this on N7 and confirm if it works?Hey Archit,
Quoted 8 lines
So this did not work for me. I removed the earlier patch forcing
pre_divto 1, and added this, but that ended up with a mostly black screen with a bit of blue slowly scrolling down the side.With the f.pre_div=1 line re-added, I don't see anything. The screen just goes black and doesn't come back.
Let me know if I can test anything else for you, or add any debug messages.
Thanks for trying the patch. There was a small optimization which seems to make things worse for us. I'm going to post out a v2 which does the same thing as the earlier patch.
Archit
Quoted 8 lines
thanks
-john
--
To unsubscribe from this list: send the line "unsubscribe linux-arm-msm" in the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
PATCH v2 1/1 clk: qcom: Fix pre-divider usage for pixel RCG
In reply to Archit TanejaThe clk_rcg_pixel_set_rate clk_op sets up the pre-divider by reading its current value from the NS register.
Using the pre-divider wasn't really intended when creating these ops. The pixel RCG was only intended to achieve fractional multiplication provided in the pixel_table array. Leaving the pre-divider to the existing register value results in a wrong pixel clock when the bootloader sets up the display. This was left unidentified because the IFC6410 Plus board on which this was verified didn't have a bootloader that configured the display.
Don't set the RCG pre-divider in freq_tbl to the existing NS register value. Force it to 1 and only use the M/N counter to achieve the desired fractional multiplication.
--- drivers/clk/qcom/clk-rcg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/clk/qcom/clk-rcg.c +3 -1
@@ -638,7 +638,6 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,return ret; src =ns_to_src (&rcg->s, ns); - f.pre_div =ns_to_pre_div (&rcg->p, ns) +1 ;for (i =0 ; i < num_parents; i++) {if (src == rcg->s.parent_map[i].cfg) {
@@ -647,6 +646,9 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, } } +/* bypass the pre divider */ + f.pre_div =1 ; +/* let us find appropriate m/n values for this */ for (; frac->num; frac++) { request = (rate * frac->den) / frac->num;
Signature · 2 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
Quoted 45 lines · Archit Taneja
The
clk_rcg_pixel_set_rateclk_opsets up the pre-divider by reading its current value from the NS register.Using the pre-divider wasn't really intended when creating these ops. The pixel RCG was only intended to achieve fractional multiplication provided in the
pixel_tablearray. Leaving the pre-divider to the existing register value results in a wrong pixel clock when the bootloader sets up the display. This was left unidentified because the IFC6410 Plus board on which this was verified didn't have a bootloader that configured the display.Don't set the RCG pre-divider in
freq_tblto the existing NS register value. Force it to 1 and only use the M/N counter to achieve the desired fractional multiplication.Cc John Stultz <[email protected]>Cc Vinay Simha <[email protected]>Signed-off-by Archit Taneja <[email protected]>--- drivers/clk/qcom/clk-rcg.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)drivers/clk/qcom/clk-rcg.c +3
-2@@ -638,7 +638,6 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate,return ret; src =ns_to_src (&rcg->s, ns); - f.pre_div =ns_to_pre_div (&rcg->p, ns) +1 ;for (i =0 ; i < num_parents; i++) {if (src == rcg->s.parent_map[i].cfg) {@@ -647,6 +646,9 @@ static int clk_rcg_pixel_set_rate(struct clk_hw *hw, unsigned long rate, } } +/* bypass the pre divider */ + f.pre_div =1 ; +/* let us find appropriate m/n values for this */ for (; frac->num; frac++) { request = (rate * frac->den) / frac->num; --
Quoted 3 lines
The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum, hosted by The Linux Foundation
This one works for me on the nexus7
thanks
-john
Stephen Boyd
AppliedQuoted 11 lines · Archit Taneja
The
clk_rcg_pixel_set_rateclk_opsets up the pre-divider by reading its current value from the NS register.Using the pre-divider wasn't really intended when creating these ops. The pixel RCG was only intended to achieve fractional multiplication provided in the
pixel_tablearray. Leaving the pre-divider to the existing register value results in a wrong pixel clock when the bootloader sets up the display. This was left unidentified because the IFC6410 Plus board on which this was verified didn't have a bootloader that configured the display.
Quoted 8 lines
Don't set the RCG pre-divider in
freq_tblto the existing NS register value. Force it to 1 and only use the M/N counter to achieve the desired fractional multiplication.Cc John Stultz <[email protected]>Cc Vinay Simha <[email protected]>Signed-off-by Archit Taneja <[email protected]>---
Applied to clk-next
Signature · 2 lines
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project