clk: ux500: Set sdmmc clock to 100MHz
Subsystems (4)
cover clk: ux500: Set sdmmc clock to 100MHz
From: Ulf Hansson <[email protected]>
The reason behind this change is that we would like to enable all the mmc/sd/sdio features from a hardware perspective (ARM PL18x). It is then required that the frequency must be 100MHz.
Ulf Hansson (3):
mfd: dbx500: Export prmcu_request_ape_opp_100_voltage
clk: ux500: Support prcmu ape opp voltage clock
clk: ux500: Update sdmmc clock to 100MHz for u8500
drivers/clk/ux500/clk-prcmu.c | 55 ++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 6 +++++ drivers/clk/ux500/u8500_clk.c | 5 ++-- drivers/mfd/db8500-prcmu.c | 4 +-- include/linux/mfd/db8500-prcmu.h | 4 +-- include/linux/mfd/dbx500-prcmu.h | 10 +++++++ 6 files changed, 78 insertions(+), 6 deletions(-)
Signature · 1 line
1.7.10
PATCH 1/3 mfd: dbx500: Export prmcu_request_ape_opp_100_voltage
From: Ulf Hansson <[email protected]>
This function needs to be exported to let clients be able to request the ape opp 100 voltage.
--- drivers/mfd/db8500-prcmu.c | 4 ++-- include/linux/mfd/db8500-prcmu.h | 4 ++-- include/linux/mfd/dbx500-prcmu.h | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-)
drivers/mfd/db8500-prcmu.c +2 -2
@@ -1167,12 +1167,12 @@ int db8500_prcmu_get_ape_opp(void) }/** -* prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage +* db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage * @enable: true to request the higher voltage, false to drop a request. * * Calls to this function to enable and disable requests must be balanced. */ -int prcmu_request_ape_opp_100_voltage (bool enable) +int db8500_prcmu_request_ape_opp_100_voltage (bool enable) {int r =0 ;u8 header;
include/linux/mfd/db8500-prcmu.h +2 -2
@@ -515,7 +515,6 @@ enum romcode_read prcmu_get_rc_p2a(void);enum ap_pwrst prcmu_get_xp70_current_state (void );bool prcmu_has_arm_maxopp (void );struct prcmu_fw_version *prcmu_get_fw_version (void ); -int prcmu_request_ape_opp_100_voltage (bool enable);int prcmu_release_usb_wakeup_state (void );void prcmu_configure_auto_pm (struct prcmu_auto_pm_config *sleep,struct prcmu_auto_pm_config *idle);
@@ -564,6 +563,7 @@ int db8500_prcmu_set_arm_opp(u8 opp);int db8500_prcmu_get_arm_opp (void );int db8500_prcmu_set_ape_opp (u8 opp);int db8500_prcmu_get_ape_opp (void ); +int db8500_prcmu_request_ape_opp_100_voltage (bool enable);int db8500_prcmu_set_ddr_opp (u8 opp);int db8500_prcmu_get_ddr_opp (void );
@@ -610,7 +610,7 @@ static inline int db8500_prcmu_get_ape_opp(void)return APE_100_OPP ; } -static inline int prcmu_request_ape_opp_100_voltage (bool enable) +static inline int db8500_prcmu_request_ape_opp_100_voltage (bool enable) {return 0 ; }
include/linux/mfd/dbx500-prcmu.h +10 -0
@@ -336,6 +336,11 @@ static inline int prcmu_get_ape_opp(void)return db8500_prcmu_get_ape_opp (); } +static inline int prcmu_request_ape_opp_100_voltage (bool enable) +{ +return db8500_prcmu_request_ape_opp_100_voltage (enable); +} +static inline void prcmu_system_reset (u16 reset_code) {return db8500_prcmu_system_reset (reset_code);
@@ -507,6 +512,11 @@ static inline int prcmu_get_ape_opp(void)return APE_100_OPP ; } +static inline int prcmu_request_ape_opp_100_voltage (bool enable) +{ +return 0 ; +} +static inline int prcmu_set_arm_opp (u8 opp) {return 0 ;
Signature · 1 line
1.7.10
Re: [PATCH 1/3] mfd: dbx500: Export prmcu_request_ape_opp_100_voltage
Hi Sam and Linus,
Do you see any issues with this patch? Can we advise Mike to merge it though his clock tree?
Kind regards
Ulf Hansson
Quoted 92 lines · Ulf Hansson
From: Ulf Hansson <[email protected]>
This function needs to be exported to let clients be able to request the ape opp 100 voltage.
Cc Samuel Ortiz <[email protected]>Signed-off-by Ulf Hansson <[email protected]>--- drivers/mfd/db8500-prcmu.c | 4 ++-- include/linux/mfd/db8500-prcmu.h | 4 ++-- include/linux/mfd/dbx500-prcmu.h | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-)drivers/mfd/db8500-prcmu.c +2
-2@@ -1167,12 +1167,12 @@ int db8500_prcmu_get_ape_opp(void) }/** -* prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage +* db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage * @enable: true to request the higher voltage, false to drop a request. * * Calls to this function to enable and disable requests must be balanced. */ -int prcmu_request_ape_opp_100_voltage (bool enable) +int db8500_prcmu_request_ape_opp_100_voltage (bool enable) {int r =0 ;u8 header;include/linux/mfd/db8500-prcmu.h +2
-2@@ -515,7 +515,6 @@ enum romcode_read prcmu_get_rc_p2a(void);enum ap_pwrst prcmu_get_xp70_current_state (void );bool prcmu_has_arm_maxopp (void );struct prcmu_fw_version *prcmu_get_fw_version (void ); -int prcmu_request_ape_opp_100_voltage (bool enable);int prcmu_release_usb_wakeup_state (void );void prcmu_configure_auto_pm (struct prcmu_auto_pm_config *sleep,struct prcmu_auto_pm_config *idle);@@ -564,6 +563,7 @@ int db8500_prcmu_set_arm_opp(u8 opp);int db8500_prcmu_get_arm_opp (void );int db8500_prcmu_set_ape_opp (u8 opp);int db8500_prcmu_get_ape_opp (void ); +int db8500_prcmu_request_ape_opp_100_voltage (bool enable);int db8500_prcmu_set_ddr_opp (u8 opp);int db8500_prcmu_get_ddr_opp (void );@@ -610,7 +610,7 @@ static inline int db8500_prcmu_get_ape_opp(void)return APE_100_OPP ; } -static inline int prcmu_request_ape_opp_100_voltage (bool enable) +static inline int db8500_prcmu_request_ape_opp_100_voltage (bool enable) {return 0 ; }include/linux/mfd/dbx500-prcmu.h +10
-1@@ -336,6 +336,11 @@ static inline int prcmu_get_ape_opp(void)return db8500_prcmu_get_ape_opp (); } +static inline int prcmu_request_ape_opp_100_voltage (bool enable) +{ +return db8500_prcmu_request_ape_opp_100_voltage (enable); +} +static inline void prcmu_system_reset (u16 reset_code) {return db8500_prcmu_system_reset (reset_code);@@ -507,6 +512,11 @@ static inline int prcmu_get_ape_opp(void)return APE_100_OPP ; } +static inline int prcmu_request_ape_opp_100_voltage (bool enable) +{ +return 0 ; +} +static inline int prcmu_set_arm_opp (u8 opp) {return 0 ; --1.7.10
Re: [PATCH 1/3] mfd: dbx500: Export prmcu_request_ape_opp_100_voltage
Quoting Ulf Hansson (2012-10-04 05:03:05)
Quoted 5 lines
Hi Sam and Linus,
Do you see any issues with this patch? Can we advise Mike to merge it though his clock tree?
Thanks for the re-ping and gathering Ack's. I'll pull into my clk-next as soon as I push out a new branch towards 3.8.
Regards,
Mike
Quoted 96 lines
Kind regards
Ulf HanssonQuoted 92 lines · Ulf Hansson
From: Ulf Hansson <[email protected]>
This function needs to be exported to let clients be able to request the ape opp 100 voltage.
Cc Samuel Ortiz <[email protected]>Signed-off-by Ulf Hansson <[email protected]>--- drivers/mfd/db8500-prcmu.c | 4 ++-- include/linux/mfd/db8500-prcmu.h | 4 ++-- include/linux/mfd/dbx500-prcmu.h | 10 ++++++++++ 3 files changed, 14 insertions(+), 4 deletions(-)drivers/mfd/db8500-prcmu.c +2
-2@@ -1167,12 +1167,12 @@ int db8500_prcmu_get_ape_opp(void) }/** -* prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage +* db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage * @enable: true to request the higher voltage, false to drop a request. * * Calls to this function to enable and disable requests must be balanced. */ -int prcmu_request_ape_opp_100_voltage (bool enable) +int db8500_prcmu_request_ape_opp_100_voltage (bool enable) {int r =0 ;u8 header;include/linux/mfd/db8500-prcmu.h +2
-2@@ -515,7 +515,6 @@ enum romcode_read prcmu_get_rc_p2a(void);enum ap_pwrst prcmu_get_xp70_current_state (void );bool prcmu_has_arm_maxopp (void );struct prcmu_fw_version *prcmu_get_fw_version (void ); -int prcmu_request_ape_opp_100_voltage (bool enable);int prcmu_release_usb_wakeup_state (void );void prcmu_configure_auto_pm (struct prcmu_auto_pm_config *sleep,struct prcmu_auto_pm_config *idle);@@ -564,6 +563,7 @@ int db8500_prcmu_set_arm_opp(u8 opp);int db8500_prcmu_get_arm_opp (void );int db8500_prcmu_set_ape_opp (u8 opp);int db8500_prcmu_get_ape_opp (void ); +int db8500_prcmu_request_ape_opp_100_voltage (bool enable);int db8500_prcmu_set_ddr_opp (u8 opp);int db8500_prcmu_get_ddr_opp (void );@@ -610,7 +610,7 @@ static inline int db8500_prcmu_get_ape_opp(void)return APE_100_OPP ; } -static inline int prcmu_request_ape_opp_100_voltage (bool enable) +static inline int db8500_prcmu_request_ape_opp_100_voltage (bool enable) {return 0 ; }include/linux/mfd/dbx500-prcmu.h +10
-1@@ -336,6 +336,11 @@ static inline int prcmu_get_ape_opp(void)return db8500_prcmu_get_ape_opp (); } +static inline int prcmu_request_ape_opp_100_voltage (bool enable) +{ +return db8500_prcmu_request_ape_opp_100_voltage (enable); +} +static inline void prcmu_system_reset (u16 reset_code) {return db8500_prcmu_system_reset (reset_code);@@ -507,6 +512,11 @@ static inline int prcmu_get_ape_opp(void)return APE_100_OPP ; } +static inline int prcmu_request_ape_opp_100_voltage (bool enable) +{ +return 0 ; +} +static inline int prcmu_set_arm_opp (u8 opp) {return 0 ; --1.7.10
Re: [PATCH 1/3] mfd: dbx500: Export prmcu_request_ape_opp_100_voltage
In reply to Ulf HanssonHi Ulf,
Quoted 7 lines · Ulf Hansson
From: Ulf Hansson <[email protected]>
This function needs to be exported to let clients be able to request the ape opp 100 voltage.
Cc Samuel Ortiz <[email protected]>Signed-off-by Ulf Hansson <[email protected]>
Cheers,
Samuel.
Signature · 2 lines
Intel Open Source Technology Centre http://oss.intel.com/
Re: [PATCH 1/3] mfd: dbx500: Export prmcu_request_ape_opp_100_voltage
In reply to Ulf HanssonQuoted 7 lines · Ulf Hansson
From: Ulf Hansson <[email protected]>
This function needs to be exported to let clients be able to request the ape opp 100 voltage.
Cc Samuel Ortiz <[email protected]>Signed-off-by Ulf Hansson <[email protected]>
Yours,
Linus Walleij
PATCH 2/3 clk: ux500: Support prcmu ape opp voltage clock
In reply to Ulf HanssonFrom: Ulf Hansson <[email protected]>
Some scalable prcmu clocks needs to be handled in conjuction with the ape opp 100 voltage. A new prcmu clock type clk_prcmu_opp_volt_scalable is implemented to handle this.
--- drivers/clk/ux500/clk-prcmu.c | 55 +++++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 6 +++++ 2 files changed, 61 insertions(+)
drivers/clk/ux500/clk-prcmu.c +55 -0
@@ -133,6 +133,40 @@ out_error: hw->init->name); } +static int clk_prcmu_opp_volt_prepare (struct clk_hw *hw) +{ +int err; +struct clk_prcmu *clk =to_clk_prcmu (hw); + + err =prcmu_request_ape_opp_100_voltage (true); +if (err) { +pr_err ("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n" , + __func__, hw->init->name); +return err; + } + + err =prcmu_request_clock (clk->cg_sel, true); +if (err) +prcmu_request_ape_opp_100_voltage (false); + +return err; +} + +static void clk_prcmu_opp_volt_unprepare (struct clk_hw *hw) +{ +struct clk_prcmu *clk =to_clk_prcmu (hw); + +if (prcmu_request_clock (clk->cg_sel, false)) + goto out_error; +if (prcmu_request_ape_opp_100_voltage (false)) + goto out_error; +return ; + +out_error: +pr_err ("clk_prcmu: %s failed to disable %s.\n" , __func__, + hw->init->name); +} +static struct clk_ops clk_prcmu_scalable_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare,
@@ -167,6 +201,17 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { .recalc_rate = clk_prcmu_recalc_rate, }; +static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { + .prepare = clk_prcmu_opp_volt_prepare, + .unprepare = clk_prcmu_opp_volt_unprepare, + .enable = clk_prcmu_enable, + .disable = clk_prcmu_disable, + .is_enabled = clk_prcmu_is_enabled, + .recalc_rate = clk_prcmu_recalc_rate, + .round_rate = clk_prcmu_round_rate, + .set_rate = clk_prcmu_set_rate, +}; + static struct clk *clk_reg_prcmu(const char *name, const char *parent_name, u8 cg_sel,
@@ -250,3 +295,13 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,return clk_reg_prcmu (name, parent_name, cg_sel,0 , flags, &clk_prcmu_opp_gate_ops); } + +struct clk *clk_reg_prcmu_opp_volt_scalable (const char *name, +const char *parent_name, +u8 cg_sel, +unsigned long rate, +unsigned long flags) +{ +return clk_reg_prcmu (name, parent_name, cg_sel, rate, flags, + &clk_prcmu_opp_volt_scalable_ops); +}
drivers/clk/ux500/clk.h +6 -0
@@ -45,4 +45,10 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,u8 cg_sel, unsigned long flags); +struct clk *clk_reg_prcmu_opp_volt_scalable (const char *name, +const char *parent_name, +u8 cg_sel, +unsigned long rate, +unsigned long flags); +#endif /* __UX500_CLK_H */
Signature · 1 line
1.7.10
Re: [PATCH 2/3] clk: ux500: Support prcmu ape opp voltage clock
Quoting Ulf Hansson (2012-09-24 07:43:18)
Quoted 43 lines
From: Ulf Hansson <[email protected]>
Some scalable prcmu clocks needs to be handled in conjuction with the ape opp 100 voltage. A new prcmu clock type
clk_prcmu_opp_volt_scalableis implemented to handle this.Signed-off-by Ulf Hansson <[email protected]>--- drivers/clk/ux500/clk-prcmu.c | 55 +++++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 6 +++++ 2 files changed, 61 insertions(+)drivers/clk/ux500/clk-prcmu.c +23
-0@@ -133,6 +133,40 @@ out_error: hw->init->name); } +static int clk_prcmu_opp_volt_prepare (struct clk_hw *hw) +{ +int err; +struct clk_prcmu *clk =to_clk_prcmu (hw); + + err =prcmu_request_ape_opp_100_voltage (true); +if (err) { +pr_err ("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n" , + __func__, hw->init->name); +return err; + } + + err =prcmu_request_clock (clk->cg_sel, true); +if (err) +prcmu_request_ape_opp_100_voltage (false); + +return err; +} + +static void clk_prcmu_opp_volt_unprepare (struct clk_hw *hw) +{ +struct clk_prcmu *clk =to_clk_prcmu (hw); +
drivers/clk/ux500/clk-prcmu.c out_error: · line 168
Quoted 10 lines
drivers/clk/ux500/clk-prcmu.c +10
-0+if (prcmu_request_clock (clk->cg_sel, false)) + goto out_error; +if (prcmu_request_ape_opp_100_voltage (false)) + goto out_error; +return ; + +out_error: +pr_err ("clk_prcmu: %s failed to disable %s.\n" , __func__, + hw->init->name); +}
Hello Ulf,
I was hoping to use the rate-change notifiers for voltage scaling, as in my clk reentrancy/dvfs RFCs. Using prepare/unprepare to set voltage for non-scalable clocks is probably OK; do you plan to scale voltage when your clocks change rate? If so then you will need more than just prepare/unprepare.
Regards,
Mike
Quoted 53 lines
drivers/clk/ux500/clk-prcmu.c +22
-0+static struct clk_ops clk_prcmu_scalable_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare,@@ -167,6 +201,17 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { .recalc_rate = clk_prcmu_recalc_rate, }; +static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { + .prepare = clk_prcmu_opp_volt_prepare, + .unprepare = clk_prcmu_opp_volt_unprepare, + .enable = clk_prcmu_enable, + .disable = clk_prcmu_disable, + .is_enabled = clk_prcmu_is_enabled, + .recalc_rate = clk_prcmu_recalc_rate, + .round_rate = clk_prcmu_round_rate, + .set_rate = clk_prcmu_set_rate, +}; + static struct clk *clk_reg_prcmu(const char *name, const char *parent_name, u8 cg_sel,@@ -250,3 +295,13 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,return clk_reg_prcmu (name, parent_name, cg_sel,0 , flags, &clk_prcmu_opp_gate_ops); } + +struct clk *clk_reg_prcmu_opp_volt_scalable (const char *name, +const char *parent_name, +u8 cg_sel, +unsigned long rate, +unsigned long flags) +{ +return clk_reg_prcmu (name, parent_name, cg_sel, rate, flags, + &clk_prcmu_opp_volt_scalable_ops); +}drivers/clk/ux500/clk.h +6
-0@@ -45,4 +45,10 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,u8 cg_sel, unsigned long flags); +struct clk *clk_reg_prcmu_opp_volt_scalable (const char *name, +const char *parent_name, +u8 cg_sel, +unsigned long rate, +unsigned long flags); +#endif /* __UX500_CLK_H */ Signature · 1 line
1.7.10
Re: [PATCH 2/3] clk: ux500: Support prcmu ape opp voltage clock
Hi Mike,
Thanks for your input!
Quoted 57 lines · Mike Turquette
Quoting Ulf Hansson (2012-09-24 07:43:18)
Quoted 43 lines
From: Ulf Hansson <[email protected]>
Some scalable prcmu clocks needs to be handled in conjuction with the ape opp 100 voltage. A new prcmu clock type
clk_prcmu_opp_volt_scalableis implemented to handle this.Signed-off-by Ulf Hansson <[email protected]>--- drivers/clk/ux500/clk-prcmu.c | 55 +++++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 6 +++++ 2 files changed, 61 insertions(+)drivers/clk/ux500/clk-prcmu.c +23
-0@@ -133,6 +133,40 @@ out_error: hw->init->name); } +static int clk_prcmu_opp_volt_prepare (struct clk_hw *hw) +{ +int err; +struct clk_prcmu *clk =to_clk_prcmu (hw); + + err =prcmu_request_ape_opp_100_voltage (true); +if (err) { +pr_err ("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n" , + __func__, hw->init->name); +return err; + } + + err =prcmu_request_clock (clk->cg_sel, true); +if (err) +prcmu_request_ape_opp_100_voltage (false); + +return err; +} + +static void clk_prcmu_opp_volt_unprepare (struct clk_hw *hw) +{ +struct clk_prcmu *clk =to_clk_prcmu (hw); +drivers/clk/ux500/clk-prcmu.c out_error: · line 168
Quoted 10 lines
drivers/clk/ux500/clk-prcmu.c +10
-0+if (prcmu_request_clock (clk->cg_sel, false)) + goto out_error; +if (prcmu_request_ape_opp_100_voltage (false)) + goto out_error; +return ; + +out_error: +pr_err ("clk_prcmu: %s failed to disable %s.\n" , __func__, + hw->init->name); +}Hello Ulf,
Quoted 5 lines
I was hoping to use the rate-change notifiers for voltage scaling, as in my clk reentrancy/dvfs RFCs. Using prepare/unprepare to set voltage for non-scalable clocks is probably OK; do you plan to scale voltage when your clocks change rate? If so then you will need more than just prepare/unprepare.
I see, you have a good point here. Although right now this clock will never change rate except during "init". Prepare/unprepare is thus enough.
For the u8500 platform the sdmmc clock is the parent for all the mmc/sd/sdio controllers. So, to no introduce a very complex clockhandling mechanism (using rate-change notifiers would help a bit, but is not enough), the clock is not supposed to be changed after init. Proper dividing of the clock is handled internally by each controller instead.
Quoted 48 lines
Regards,
MikeQuoted 44 lines
drivers/clk/ux500/clk-prcmu.c +22
-0+static struct clk_ops clk_prcmu_scalable_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare,@@ -167,6 +201,17 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { .recalc_rate = clk_prcmu_recalc_rate, }; +static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { + .prepare = clk_prcmu_opp_volt_prepare, + .unprepare = clk_prcmu_opp_volt_unprepare, + .enable = clk_prcmu_enable, + .disable = clk_prcmu_disable, + .is_enabled = clk_prcmu_is_enabled, + .recalc_rate = clk_prcmu_recalc_rate, + .round_rate = clk_prcmu_round_rate, + .set_rate = clk_prcmu_set_rate, +}; + static struct clk *clk_reg_prcmu(const char *name, const char *parent_name, u8 cg_sel,@@ -250,3 +295,13 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,return clk_reg_prcmu (name, parent_name, cg_sel,0 , flags, &clk_prcmu_opp_gate_ops); } + +struct clk *clk_reg_prcmu_opp_volt_scalable (const char *name, +const char *parent_name, +u8 cg_sel, +unsigned long rate, +unsigned long flags) +{ +return clk_reg_prcmu (name, parent_name, cg_sel, rate, flags, + &clk_prcmu_opp_volt_scalable_ops); +}drivers/clk/ux500/clk.h +0
-0@@ -45,4 +45,10 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,u8 cg_sel, unsigned long flags);
Quoted 9 lines
Quoted 9 lines
drivers/clk/ux500/clk.h +6
-1+struct clk *clk_reg_prcmu_opp_volt_scalable (const char *name, +const char *parent_name, +u8 cg_sel, +unsigned long rate, +unsigned long flags); +#endif /* __UX500_CLK_H */ --1.7.10
Kind regards
Ulf Hansson
PATCH 2/3 clk: ux500: Support prcmu ape opp voltage clock
Quoting Ulf Hansson (2012-09-25 00:56:56)
Quoted 72 lines
Hi Mike,
Thanks for your input!
Quoted 57 lines · Mike Turquette
Quoting Ulf Hansson (2012-09-24 07:43:18)
Quoted 43 lines
From: Ulf Hansson <[email protected]>
Some scalable prcmu clocks needs to be handled in conjuction with the ape opp 100 voltage. A new prcmu clock type
clk_prcmu_opp_volt_scalableis implemented to handle this.Signed-off-by Ulf Hansson <[email protected]>--- drivers/clk/ux500/clk-prcmu.c | 55 +++++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 6 +++++ 2 files changed, 61 insertions(+)drivers/clk/ux500/clk-prcmu.c +23
-0@@ -133,6 +133,40 @@ out_error: hw->init->name); } +static int clk_prcmu_opp_volt_prepare (struct clk_hw *hw) +{ +int err; +struct clk_prcmu *clk =to_clk_prcmu (hw); + + err =prcmu_request_ape_opp_100_voltage (true); +if (err) { +pr_err ("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n" , + __func__, hw->init->name); +return err; + } + + err =prcmu_request_clock (clk->cg_sel, true); +if (err) +prcmu_request_ape_opp_100_voltage (false); + +return err; +} + +static void clk_prcmu_opp_volt_unprepare (struct clk_hw *hw) +{ +struct clk_prcmu *clk =to_clk_prcmu (hw); +drivers/clk/ux500/clk-prcmu.c out_error: · line 168
Quoted 10 lines
drivers/clk/ux500/clk-prcmu.c +10
-0+if (prcmu_request_clock (clk->cg_sel, false)) + goto out_error; +if (prcmu_request_ape_opp_100_voltage (false)) + goto out_error; +return ; + +out_error: +pr_err ("clk_prcmu: %s failed to disable %s.\n" , __func__, + hw->init->name); +}Hello Ulf,
Quoted 5 lines
I was hoping to use the rate-change notifiers for voltage scaling, as in my clk reentrancy/dvfs RFCs. Using prepare/unprepare to set voltage for non-scalable clocks is probably OK; do you plan to scale voltage when your clocks change rate? If so then you will need more than just prepare/unprepare.
I see, you have a good point here. Although right now this clock will never change rate except during "init". Prepare/unprepare is thus enough.
Quoted 7 lines
For the u8500 platform the sdmmc clock is the parent for all the mmc/sd/sdio controllers. So, to no introduce a very complex clockhandling mechanism (using rate-change notifiers would help a bit, but is not enough), the clock is not supposed to be changed after init. Proper dividing of the clock is handled internally by each controller instead.
The internal dividers could be modeled as clk nodes, which themselves could have notifier handlers that scale voltage. So perhaps the MMC controller driver for your platform should define the appropriate leaf clks?
Regards,
Mike
Quoted 61 lines
Quoted 49 lines
Regards,
MikeQuoted 44 lines
drivers/clk/ux500/clk-prcmu.c +22
-0+static struct clk_ops clk_prcmu_scalable_ops = { .prepare = clk_prcmu_prepare, .unprepare = clk_prcmu_unprepare,@@ -167,6 +201,17 @@ static struct clk_ops clk_prcmu_opp_gate_ops = { .recalc_rate = clk_prcmu_recalc_rate, }; +static struct clk_ops clk_prcmu_opp_volt_scalable_ops = { + .prepare = clk_prcmu_opp_volt_prepare, + .unprepare = clk_prcmu_opp_volt_unprepare, + .enable = clk_prcmu_enable, + .disable = clk_prcmu_disable, + .is_enabled = clk_prcmu_is_enabled, + .recalc_rate = clk_prcmu_recalc_rate, + .round_rate = clk_prcmu_round_rate, + .set_rate = clk_prcmu_set_rate, +}; + static struct clk *clk_reg_prcmu(const char *name, const char *parent_name, u8 cg_sel,@@ -250,3 +295,13 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,return clk_reg_prcmu (name, parent_name, cg_sel,0 , flags, &clk_prcmu_opp_gate_ops); } + +struct clk *clk_reg_prcmu_opp_volt_scalable (const char *name, +const char *parent_name, +u8 cg_sel, +unsigned long rate, +unsigned long flags) +{ +return clk_reg_prcmu (name, parent_name, cg_sel, rate, flags, + &clk_prcmu_opp_volt_scalable_ops); +}drivers/clk/ux500/clk.h +0
-0@@ -45,4 +45,10 @@ struct clk *clk_reg_prcmu_opp_gate(const char *name,u8 cg_sel, unsigned long flags);Quoted 9 lines
Quoted 9 lines
drivers/clk/ux500/clk.h +6
-1+struct clk *clk_reg_prcmu_opp_volt_scalable (const char *name, +const char *parent_name, +u8 cg_sel, +unsigned long rate, +unsigned long flags); +#endif /* __UX500_CLK_H */ --1.7.10
Kind regards
Ulf Hansson
Re: [PATCH 2/3] clk: ux500: Support prcmu ape opp voltage clock
Hi Mike,
Quoted 81 lines · Mike Turquette
Quoting Ulf Hansson (2012-09-25 00:56:56)
Quoted 72 lines
Hi Mike,
Thanks for your input!
Quoted 57 lines · Mike Turquette
Quoting Ulf Hansson (2012-09-24 07:43:18)
Quoted 43 lines
From: Ulf Hansson <[email protected]>
Some scalable prcmu clocks needs to be handled in conjuction with the ape opp 100 voltage. A new prcmu clock type
clk_prcmu_opp_volt_scalableis implemented to handle this.Signed-off-by Ulf Hansson <[email protected]>--- drivers/clk/ux500/clk-prcmu.c | 55 +++++++++++++++++++++++++++++++++++++++++ drivers/clk/ux500/clk.h | 6 +++++ 2 files changed, 61 insertions(+)drivers/clk/ux500/clk-prcmu.c +23
-0@@ -133,6 +133,40 @@ out_error: hw->init->name); } +static int clk_prcmu_opp_volt_prepare (struct clk_hw *hw) +{ +int err; +struct clk_prcmu *clk =to_clk_prcmu (hw); + + err =prcmu_request_ape_opp_100_voltage (true); +if (err) { +pr_err ("clk_prcmu: %s failed to request APE OPP VOLT for %s.\n" , + __func__, hw->init->name); +return err; + } + + err =prcmu_request_clock (clk->cg_sel, true); +if (err) +prcmu_request_ape_opp_100_voltage (false); + +return err; +} + +static void clk_prcmu_opp_volt_unprepare (struct clk_hw *hw) +{ +struct clk_prcmu *clk =to_clk_prcmu (hw); +drivers/clk/ux500/clk-prcmu.c out_error: · line 168
Quoted 10 lines
drivers/clk/ux500/clk-prcmu.c +10
-0+if (prcmu_request_clock (clk->cg_sel, false)) + goto out_error; +if (prcmu_request_ape_opp_100_voltage (false)) + goto out_error; +return ; + +out_error: +pr_err ("clk_prcmu: %s failed to disable %s.\n" , __func__, + hw->init->name); +}Hello Ulf,
Quoted 5 lines
I was hoping to use the rate-change notifiers for voltage scaling, as in my clk reentrancy/dvfs RFCs. Using prepare/unprepare to set voltage for non-scalable clocks is probably OK; do you plan to scale voltage when your clocks change rate? If so then you will need more than just prepare/unprepare.
I see, you have a good point here. Although right now this clock will never change rate except during "init". Prepare/unprepare is thus enough.
Quoted 7 lines
For the u8500 platform the sdmmc clock is the parent for all the mmc/sd/sdio controllers. So, to no introduce a very complex clockhandling mechanism (using rate-change notifiers would help a bit, but is not enough), the clock is not supposed to be changed after init. Proper dividing of the clock is handled internally by each controller instead.
Quoted 4 lines
The internal dividers could be modeled as clk nodes, which themselves could have notifier handlers that scale voltage. So perhaps the MMC controller driver for your platform should define the appropriate leaf clks?
I am not sure I completely follow you here, but let me try to answer your suggestions.
The internal dividers are supposed to be handled only by the mmc host driver since it is IP specific. I don't think it is viable to add another clock type/node for this, but maybe that is not what you are suggesting either. :-)
In my case for ux500 we use the mmci host driver. It is an ARM cross SoC device driver, and I believe adding clock notifiers in the driver to handle the voltage scale would complicate things quite a bit. It seems a lot easier to let the clock driver handle this, especially since the frequency will remain fixed after initialization. So in the end I see now need and benefit for adding the clock notifiers in the mmci host driver.
Kind regards
Ulf Hansson
Re: [PATCH 2/3] clk: ux500: Support prcmu ape opp voltage clock
Quoted 7 lines · Ulf Hansson
In my case for ux500 we use the mmci host driver. It is an ARM cross SoC device driver, and I believe adding clock notifiers in the driver to handle the voltage scale would complicate things quite a bit. It seems a lot easier to let the clock driver handle this, especially since the frequency will remain fixed after initialization. So in the end I see now need and benefit for adding the clock notifiers in the mmci host driver.
Right now it certainly cannot be done anyway, because some of the clients to this driver does not implement the generic clock framework, and thus it just won't compile anymore for them if we introduce that.
The patch does raise the issue of how to handle OPP requests though.
Yours,
Linus Walleij
PATCH 3/3 clk: ux500: Update sdmmc clock to 100MHz for u8500
In reply to Ulf HanssonFrom: Ulf Hansson <[email protected]>
For u8500 and using 100MHz as the frequency also requires the ape opp 100 voltage, thus use the prcmu_opp_volt_scalable clock type.
--- drivers/clk/ux500/u8500_clk.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/clk/ux500/u8500_clk.c +3 -2
@@ -170,10 +170,11 @@ void u8500_clk_init(void)clk_register_clkdev (clk,NULL ,"mtu0" );clk_register_clkdev (clk,NULL ,"mtu1" ); - clk =clk_reg_prcmu_gate ("sdmmcclk" ,NULL ,PRCMU_SDMMCCLK ,CLK_IS_ROOT ); + clk =clk_reg_prcmu_opp_volt_scalable ("sdmmcclk" ,NULL ,PRCMU_SDMMCCLK , +100000000 , +CLK_IS_ROOT |CLK_SET_RATE_GATE );clk_register_clkdev (clk,NULL ,"sdmmc" ); - clk =clk_reg_prcmu_scalable ("dsi_pll" ,"hdmiclk" ,PRCMU_PLLDSI ,0 ,CLK_SET_RATE_GATE );clk_register_clkdev (clk,"dsihs2" ,"mcde" );
Signature · 1 line
1.7.10