mfd: arizona: Export function to control subsystem DVFS
Subsystems (5)
PATCH RESEND v4 1/3 mfd: arizona: Export function to control subsystem DVFS
From: Richard Fitzgerald <[email protected]>
Moving this control from being a side-effect of the LDO1 regulator driver to a specific exported function.
--- drivers/mfd/arizona-core.c | 89 ++++++++++++++++++++++++++++++++++++++ include/linux/mfd/arizona/core.h | 12 +++++ 2 files changed, 101 insertions(+), 0 deletions(-)
drivers/mfd/arizona-core.c +89 -0
@@ -94,6 +94,94 @@ int arizona_clk32k_disable(struct arizona *arizona) }EXPORT_SYMBOL_GPL (arizona_clk32k_disable); +int arizona_dvfs_up (struct arizona *arizona,unsigned int flags) +{ +unsigned int new_flags; +int ret =0 ; + +mutex_lock (&arizona->subsys_max_lock); + + new_flags = arizona->subsys_max_rq | flags; + +if (arizona->subsys_max_rq != new_flags) { +switch (arizona->type) { +case WM5102 : +case WM8997 : + ret =regulator_set_voltage (arizona->dcvdd, +1800000 ,1800000 ); +if (ret !=0 ) { +dev_err (arizona->dev, +"Failed to set DCVDD (DVFS up): %d\n" , + ret); + goto err; + } + + ret =regmap_update_bits (arizona->regmap, +ARIZONA_DYNAMIC_FREQUENCY_SCALING_1 , +ARIZONA_SUBSYS_MAX_FREQ ,1 ); +if (ret !=0 ) { +dev_err (arizona->dev, +"Failed to enable subsys max: %d\n" , + ret); +regulator_set_voltage (arizona->dcvdd, +1200000 ,1800000 ); + goto err; + } +break ; + +default : +break ; + } + + arizona->subsys_max_rq = new_flags; + } +err: +mutex_unlock (&arizona->subsys_max_lock); +return ret; +} +EXPORT_SYMBOL_GPL (arizona_dvfs_up); + +int arizona_dvfs_down (struct arizona *arizona,unsigned int flags) +{ +int ret =0 ; + +mutex_lock (&arizona->subsys_max_lock); + +if ((arizona->subsys_max_rq & flags) != flags) +dev_warn (arizona->dev,"Unbalanced DVFS down: %x\n" , flags); + + arizona->subsys_max_rq &= ~flags; + +if (arizona->subsys_max_rq ==0 ) { +switch (arizona->type) { +case WM5102 : +case WM8997 : + ret =regmap_update_bits (arizona->regmap, +ARIZONA_DYNAMIC_FREQUENCY_SCALING_1 , +ARIZONA_SUBSYS_MAX_FREQ ,0 ); +if (ret !=0 ) +dev_err (arizona->dev, +"Failed to disable subsys max: %d\n" , + ret); + + ret =regulator_set_voltage (arizona->dcvdd, +1200000 ,1800000 ); +if (ret !=0 ) +dev_err (arizona->dev, +"Failed to set DCVDD (DVFS down): %d\n" , + ret); +break ; + +default : +break ; + } + } + +mutex_unlock (&arizona->subsys_max_lock); +return ret; +} +EXPORT_SYMBOL_GPL (arizona_dvfs_down); +static irqreturn_t arizona_clkgen_err (int irq,void *data) {struct arizona *arizona = data;
@@ -641,6 +729,7 @@ int arizona_dev_init(struct arizona *arizona)dev_set_drvdata (arizona->dev, arizona);mutex_init (&arizona->clk_lock); +mutex_init (&arizona->subsys_max_lock);if (dev_get_platdata (arizona->dev)) memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),
include/linux/mfd/arizona/core.h +12 -0
@@ -109,6 +109,9 @@ struct arizona {struct mutex clk_lock;int clk32k_ref; +struct mutex subsys_max_lock; +unsigned int subsys_max_rq; +struct snd_soc_dapm_context *dapm;int tdm_width[ARIZONA_MAX_AIF ];
@@ -118,8 +121,17 @@ struct arizona {uint8_t dac_comp_enabled; }; +#define ARIZONA_DVFS_SR1_RQ 0x00000001 +#define ARIZONA_DVFS_SR2_RQ 0x00000002 +#define ARIZONA_DVFS_SR3_RQ 0x00000004 +#define ARIZONA_DVFS_ASR1_RQ 0x00000010 +#define ARIZONA_DVFS_ASR2_RQ 0x00000020 +#define ARIZONA_DVFS_ADSP1_RQ 0x00010000 +int arizona_clk32k_enable (struct arizona *arizona);int arizona_clk32k_disable (struct arizona *arizona); +int arizona_dvfs_up (struct arizona *arizona,unsigned int mask); +int arizona_dvfs_down (struct arizona *arizona,unsigned int mask);int arizona_request_irq (struct arizona *arizona,int irq,char *name,irq_handler_t handler,void *data);
Signature · 1 line
1.7.2.5
PATCH RESEND v4 2/3 ASoC: wm_adsp: Move DVFS control into codec driver
From: Richard Fitzgerald <[email protected]>
In theory the ADSP driver should not need to know anything about the codec it is part of. But some codecs need DVFS control based on ADSP clocking speed. This was being handled by bundling part of the knowledge of this into the ADSP driver.
This change removes this handling out of the ADSP driver. A new macro WM_ADSP2_E() takes a callback function to be called by the preloader widget in place of the default handler, and this can be used to do codec-specific power control.
The WM5102 driver has been updated to implement the DVFS.
--- drivers/regulator/arizona-ldo1.c | 5 --- sound/soc/codecs/wm5102.c | 47 +++++++++++++++++++++++- sound/soc/codecs/wm5110.c | 2 +- sound/soc/codecs/wm_adsp.c | 73 +------------------------------------- sound/soc/codecs/wm_adsp.h | 13 ++++--- 5 files changed, 54 insertions(+), 86 deletions(-)
drivers/regulator/arizona-ldo1.c +0 -5
@@ -78,11 +78,6 @@ static int arizona_ldo1_hc_set_voltage_sel(struct regulator_dev *rdev,if (ret !=0 )return ret; - ret =regmap_update_bits (regmap,ARIZONA_DYNAMIC_FREQUENCY_SCALING_1 , -ARIZONA_SUBSYS_MAX_FREQ , val); -if (ret !=0 ) -return ret; -if (val)return 0 ;
sound/soc/codecs/wm5102.c +45 -2
65 lines not on this page · raw message
sound/soc/codecs/wm5110.c +1 -1
@@ -1688,7 +1688,7 @@ static int wm5110_probe(struct platform_device *pdev) wm5110->core.adsp[i].num_mems =ARRAY_SIZE (wm5110_dsp1_regions); - ret =wm_adsp2_init (&wm5110->core.adsp[i], false); + ret =wm_adsp2_init (&wm5110->core.adsp[i]);if (ret !=0 )return ret; }
sound/soc/codecs/wm_adsp.c +1 -72
97 lines not on this page · raw message
sound/soc/codecs/wm_adsp.h +7 -6
@@ -56,8 +56,6 @@ struct wm_adsp {int fw;bool running; -struct regulator *dvfs; -struct list_head ctl_list;struct work_struct boot_work;
@@ -67,19 +65,22 @@ struct wm_adsp {SND_SOC_DAPM_PGA_E (wname,SND_SOC_NOPM , num,0 ,NULL ,0 , \ wm_adsp1_event, SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD) -#define WM_ADSP2 (wname, num) \ +#define WM_ADSP2_E (wname, num, event_fn) \ { .id = snd_soc_dapm_dai_link, .name = wname " Preloader", \ - .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_early_event, \ - .event_flags = SND_SOC_DAPM_PRE_PMU }, \ + .reg = SND_SOC_NOPM, .shift = num, .event = event_fn, \ + .event_flags = SND_SOC_DAPM_PRE_PMU | SND_SOC_DAPM_POST_PMD }, \ { .id = snd_soc_dapm_out_drv, .name = wname, \ .reg = SND_SOC_NOPM, .shift = num, .event = wm_adsp2_event, \ .event_flags = SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_PRE_PMD } +#define WM_ADSP2 (wname, num) \ + WM_ADSP2_E(wname, num, wm_adsp2_early_event) +extern const struct snd_kcontrol_new wm_adsp1_fw_controls[];extern const struct snd_kcontrol_new wm_adsp2_fw_controls[];int wm_adsp1_init (struct wm_adsp *adsp); -int wm_adsp2_init (struct wm_adsp *adsp,bool dvfs); +int wm_adsp2_init (struct wm_adsp *adsp);int wm_adsp1_event (struct snd_soc_dapm_widget *w,struct snd_kcontrol *kcontrol,int event); int wm_adsp2_early_event(struct snd_soc_dapm_widget *w,
Signature · 1 line
1.7.2.5
PATCH RESEND v4 3/3 ASoC: arizona: Add DVFS handling for sample rate control
In reply to Richard FitzgeraldFrom: Richard Fitzgerald <[email protected]>
Some codecs need to boost DVFS for higher sample rates.
--- sound/soc/codecs/arizona.c | 22 +++++++++++++++++++++- 1 files changed, 21 insertions(+), 1 deletions(-)
sound/soc/codecs/arizona.c +21 -1
@@ -1185,7 +1185,7 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream,struct arizona_priv *priv =snd_soc_codec_get_drvdata (codec);struct arizona_dai_priv *dai_priv = &priv->dai[dai->id -1 ];int base = dai->driver->base; -int i, sr_val; +int i, sr_val, ret;/* * We will need to be more flexible than this in future,
@@ -1201,6 +1201,26 @@ static int arizona_hw_params_rate(struct snd_pcm_substream *substream, } sr_val = i; +switch (priv->arizona->type) { +case WM5102 : +case WM8997 : +if (arizona_sr_vals[sr_val] >=88200 ) + ret =arizona_dvfs_up (priv->arizona, +ARIZONA_DVFS_SR1_RQ ); +else + ret =arizona_dvfs_down (priv->arizona, +ARIZONA_DVFS_SR1_RQ ); + +if (ret !=0 ) { +arizona_aif_err (dai,"Failed to change DVFS %d\n" , ret); +return ret; + } +break ; + +default : +break ; + } +switch (dai_priv->clk) {case ARIZONA_CLK_SYSCLK :switch (priv->arizona->type) {
Signature · 1 line
1.7.2.5
Re: [PATCH 3/3 v4 RESEND] ASoC: arizona: Add DVFS handling for sample rate control
Quoted 7 lines · Richard Fitzgerald
From: Richard Fitzgerald <[email protected]>
Some codecs need to boost DVFS for higher sample rates.
Signed-off-by Richard Fitzgerald <[email protected]>Signed-off-by Charles Keepax <[email protected]>---
Hi Mark,
Would it be possible to get an Ack for the ASoC patches here, Lee said it would be ok to put the series through the MFD tree once we have an ack? Unless you have any issues with the series?
Thanks,
Charles
Mark Brown
maintainerRe: [PATCH 3/3 v4 RESEND] ASoC: arizona: Add DVFS handling for sample rate control
Quoted 11 lines · Charles Keepax
Quoted 6 lines · Richard Fitzgerald
From: Richard Fitzgerald <[email protected]>
Some codecs need to boost DVFS for higher sample rates.
Signed-off-by Richard Fitzgerald <[email protected]>Signed-off-by Charles Keepax <[email protected]>Would it be possible to get an Ack for the ASoC patches here, Lee said it would be ok to put the series through the MFD tree once we have an ack? Unless you have any issues with the series?
Don't send contentless pings; if you want patches reviewing please send them to the relevant maintainers.
Quoted 11 lines · Richard Fitzgerald
From: Richard Fitzgerald <[email protected]>
Moving this control from being a side-effect of the LDO1 regulator driver to a specific exported function.
Signed-off-by Richard Fitzgerald <[email protected]>Signed-off-by Charles Keepax <[email protected]>--- drivers/mfd/arizona-core.c | 89 ++++++++++++++++++++++++++++++++++++++ include/linux/mfd/arizona/core.h | 12 +++++ 2 files changed, 101 insertions(+), 0 deletions(-)
If this is the same patch I reviewed before:
I guess we're just waiting for maintainer Acks before I can apply the set.
Quoted 139 lines
drivers/mfd/arizona-core.c +89
-0@@ -94,6 +94,94 @@ int arizona_clk32k_disable(struct arizona *arizona) }EXPORT_SYMBOL_GPL (arizona_clk32k_disable); +int arizona_dvfs_up (struct arizona *arizona,unsigned int flags) +{ +unsigned int new_flags; +int ret =0 ; + +mutex_lock (&arizona->subsys_max_lock); + + new_flags = arizona->subsys_max_rq | flags; + +if (arizona->subsys_max_rq != new_flags) { +switch (arizona->type) { +case WM5102 : +case WM8997 : + ret =regulator_set_voltage (arizona->dcvdd, +1800000 ,1800000 ); +if (ret !=0 ) { +dev_err (arizona->dev, +"Failed to set DCVDD (DVFS up): %d\n" , + ret); + goto err; + } + + ret =regmap_update_bits (arizona->regmap, +ARIZONA_DYNAMIC_FREQUENCY_SCALING_1 , +ARIZONA_SUBSYS_MAX_FREQ ,1 ); +if (ret !=0 ) { +dev_err (arizona->dev, +"Failed to enable subsys max: %d\n" , + ret); +regulator_set_voltage (arizona->dcvdd, +1200000 ,1800000 ); + goto err; + } +break ; + +default : +break ; + } + + arizona->subsys_max_rq = new_flags; + } +err: +mutex_unlock (&arizona->subsys_max_lock); +return ret; +} +EXPORT_SYMBOL_GPL (arizona_dvfs_up); + +int arizona_dvfs_down (struct arizona *arizona,unsigned int flags) +{ +int ret =0 ; + +mutex_lock (&arizona->subsys_max_lock); + +if ((arizona->subsys_max_rq & flags) != flags) +dev_warn (arizona->dev,"Unbalanced DVFS down: %x\n" , flags); + + arizona->subsys_max_rq &= ~flags; + +if (arizona->subsys_max_rq ==0 ) { +switch (arizona->type) { +case WM5102 : +case WM8997 : + ret =regmap_update_bits (arizona->regmap, +ARIZONA_DYNAMIC_FREQUENCY_SCALING_1 , +ARIZONA_SUBSYS_MAX_FREQ ,0 ); +if (ret !=0 ) +dev_err (arizona->dev, +"Failed to disable subsys max: %d\n" , + ret); + + ret =regulator_set_voltage (arizona->dcvdd, +1200000 ,1800000 ); +if (ret !=0 ) +dev_err (arizona->dev, +"Failed to set DCVDD (DVFS down): %d\n" , + ret); +break ; + +default : +break ; + } + } + +mutex_unlock (&arizona->subsys_max_lock); +return ret; +} +EXPORT_SYMBOL_GPL (arizona_dvfs_down); +static irqreturn_t arizona_clkgen_err (int irq,void *data) {struct arizona *arizona = data;@@ -641,6 +729,7 @@ int arizona_dev_init(struct arizona *arizona)dev_set_drvdata (arizona->dev, arizona);mutex_init (&arizona->clk_lock); +mutex_init (&arizona->subsys_max_lock);if (dev_get_platdata (arizona->dev)) memcpy(&arizona->pdata, dev_get_platdata(arizona->dev),include/linux/mfd/arizona/core.h +12
-0@@ -109,6 +109,9 @@ struct arizona {struct mutex clk_lock;int clk32k_ref; +struct mutex subsys_max_lock; +unsigned int subsys_max_rq; +struct snd_soc_dapm_context *dapm;int tdm_width[ARIZONA_MAX_AIF ];@@ -118,8 +121,17 @@ struct arizona {uint8_t dac_comp_enabled; }; +#define ARIZONA_DVFS_SR1_RQ 0x00000001 +#define ARIZONA_DVFS_SR2_RQ 0x00000002 +#define ARIZONA_DVFS_SR3_RQ 0x00000004 +#define ARIZONA_DVFS_ASR1_RQ 0x00000010 +#define ARIZONA_DVFS_ASR2_RQ 0x00000020 +#define ARIZONA_DVFS_ADSP1_RQ 0x00010000 +int arizona_clk32k_enable (struct arizona *arizona);int arizona_clk32k_disable (struct arizona *arizona); +int arizona_dvfs_up (struct arizona *arizona,unsigned int mask); +int arizona_dvfs_down (struct arizona *arizona,unsigned int mask);int arizona_request_irq (struct arizona *arizona,int irq,char *name,irq_handler_t handler,void *data);
Signature · 8 lines
Lee Jones Linaro STMicroelectronics Landing Team Lead Linaro.org │ Open source software for ARM SoCs Follow Linaro: Facebook | Twitter | Blog _______________________________________________ Alsa-devel mailing list [email protected] http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Quoted 14 lines · Lee Jones
Quoted 11 lines · Richard Fitzgerald
From: Richard Fitzgerald <[email protected]>
Moving this control from being a side-effect of the LDO1 regulator driver to a specific exported function.
Signed-off-by Richard Fitzgerald <[email protected]>Signed-off-by Charles Keepax <[email protected]>--- drivers/mfd/arizona-core.c | 89 ++++++++++++++++++++++++++++++++++++++ include/linux/mfd/arizona/core.h | 12 +++++ 2 files changed, 101 insertions(+), 0 deletions(-)
Quoted 7 lines
If this is the same patch I reviewed before:
Acked-by Lee Jones <[email protected]>I guess we're just waiting for maintainer Acks before I can apply the set.
Yes it is, and yes we are.
drivers/mfd/arizona-core.c int arizona_clk32k_disable(struct arizona *arizona) · line 151
Quoted 10 lines
drivers/mfd/arizona-core.c +9
-0+ +int arizona_dvfs_down (struct arizona *arizona,unsigned int flags) +{ +int ret =0 ; + +mutex_lock (&arizona->subsys_max_lock); + +if ((arizona->subsys_max_rq & flags) != flags) +dev_warn (arizona->dev,"Unbalanced DVFS down: %x\n" , flags);
This warning is bogus and should be removed. These are just simple on/off bit flags, not a reference count. If a requestor is already at the lower DVFS state we just do nothing.
It was done this way to keep the code simple and lower risk. None of the blocks that need to move the DVFS frequency up and down have multiple users so they are simple either/or cases that don't currently reference count themselves. So having a boolean flag to match the state of each block keeps the change set smaller.
Quoted 33 lines
drivers/mfd/arizona-core.c +33
-0+ + arizona->subsys_max_rq &= ~flags; + +if (arizona->subsys_max_rq ==0 ) { +switch (arizona->type) { +case WM5102 : +case WM8997 : + ret =regmap_update_bits (arizona->regmap, +ARIZONA_DYNAMIC_FREQUENCY_SCALING_1 , +ARIZONA_SUBSYS_MAX_FREQ ,0 ); +if (ret !=0 ) +dev_err (arizona->dev, +"Failed to disable subsys max: %d\n" , + ret); + + ret =regulator_set_voltage (arizona->dcvdd, +1200000 ,1800000 ); +if (ret !=0 ) +dev_err (arizona->dev, +"Failed to set DCVDD (DVFS down): %d\n" , + ret); +break ; + +default : +break ; + } + } + +mutex_unlock (&arizona->subsys_max_lock); +return ret; +} +EXPORT_SYMBOL_GPL (arizona_dvfs_down); +