[alsa-devel] [RFC PATCH 1/2] ALSA: hda - divide controller and codec dependency on i915 gfx power well
Lin, Mengdong
mengdong.lin at intel.com
Mon Apr 27 09:20:36 CEST 2015
> -----Original Message-----
> From: Takashi Iwai [mailto:tiwai at suse.de]
> Sent: Friday, April 24, 2015 9:53 PM
> > Open questions:
> > - Move the hda_i915 to sound/hda at first? So both legacy and new drivers
> can
> > use it as Takashi suggested?
> > The PCI ID check in haswell_set_bclk will no longer be needed, since it's
> > only called when chip's "need_i915_power" flag is set and so only called
> for
> > Haswell & Broadwell.
>
> I don't mind which comes first.
Okay. I'll keep hda_i915 under sound/pci/hda at first.
> > - move flag "need_i915_power" from struct hda_codec to hdac_device, for
> the
> > same reason as above?
>
> Yes, it makes sense, if the change shall happen sooner or later.
I'll move this flag to hdac_device.
> > - If the audio component moves from struct hda_intel to hdac_bus, how can
> the
> > controller access the component? Need to add "bus" to struct azx?
>
> There are more changes. See my patch series. The hda_bus itself is
> embedded into hda_bus.
>
> Also, the hda_bus_ops was dropped. It's just calling the corresponding
> function instead.
Okay.
> > - implement codec resume/suspend ops to get/put i915 power if only the
> codec
> > needs the power?
>
> I don't understand the question here. Could you elaborate?
Please overlook my question here.
const struct dev_pm_ops hda_codec_driver_pm = {
SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
pm_runtime_force_resume)
SET_RUNTIME_PM_OPS(hda_codec_runtime_suspend, hda_codec_runtime_resume,
NULL)
};
I misunderstood the code above and had though we need to implement suspend/resume ops.
Now I find pm_runtime_force_suspend/resume is good enough to make the codec device is runtime suspended before S3 and active after S3.
> One concern is that you'd likely need to implement a refcount for power switch.
> It makes our life easier.
>
> A few more things:
>
>
> > Signed-off-by: Mengdong Lin <mengdong.lin at intel.com>
> >
> > diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index
> > 2a8aa9d..baa01a0 100644
> > --- a/include/sound/hdaudio.h
> > +++ b/include/sound/hdaudio.h
> > @@ -169,6 +169,8 @@ struct hdac_bus_ops {
> > /* get a response from the last command */
> > int (*get_response)(struct hdac_bus *bus, unsigned int addr,
> > unsigned int *res);
> > + /* request/release display power */
> > + int (*display_power)(struct hdac_bus *bus, bool enable);
> > };
> >
> > #define HDA_UNSOL_QUEUE_SIZE 64
> > @@ -222,6 +224,11 @@ static inline void snd_hdac_codec_link_down(struct
> hdac_device *codec)
> > clear_bit(codec->addr, &codec->bus->codec_powered); }
> >
> > +static inline int snd_hdac_display_power(struct hdac_device *codec,
> > +bool enable) {
> > + return codec->bus->ops->display_power(codec->bus, enable); }
>
> Please give the function description in kerneldoc style.
Okay.
> > +
> > /*
> > * generic array helpers
> > */
> > diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c old
> > mode 100755 new mode 100644 index 18a021a..034488e
> > --- a/sound/pci/hda/hda_codec.c
> > +++ b/sound/pci/hda/hda_codec.c
> > @@ -524,9 +524,21 @@ static int _hda_bus_get_response(struct hdac_bus
> *_bus, unsigned int addr,
> > return bus->rirb_error ? -EIO : 0;
> > }
> >
> > +static int _hda_bus_display_power(struct hdac_bus *_bus, bool enable)
> > +{
> > + struct hda_bus *bus = container_of(_bus, struct hda_bus, core);
> > +
> > + if (bus->ops.display_power)
> > + return bus->ops.display_power(bus, enable);
>
> As mentioned, the bus_ops was dropped. Rebase your patch with the latest
> topic/hda branch of sound git tree.
Okay.
> > + else
> > + return -EINVAL;
> > +
> > +}
> > +
> > static const struct hdac_bus_ops bus_ops = {
> > .command = _hda_bus_command,
> > .get_response = _hda_bus_get_response,
> > + .display_power = _hda_bus_display_power,
> > };
> >
> > /**
> > @@ -949,6 +961,10 @@ void snd_hda_codec_register(struct hda_codec
> *codec)
> > return;
> > if (device_is_registered(hda_codec_dev(codec))) {
> > snd_hda_register_beep_device(codec);
> > +
> > + if (codec->need_i915_power)
> > + snd_hdac_display_power(&codec->core, true);
>
> The question is whether doing here is appropriate.
> This assumes that the power well already enabled in the controller side during
> probing? The verb accesses (reading through the whole topology, widget
> caps, etc) happened already before this point. So the power well has to be
> enabled before this.
Yes, the power well already enabled in the controller side during probing.
If AZX_DCAPS_I915_POWERWELL is set, azx_probe_continue will always request the power.
And if the controller is also in the power well, the power will not be released after probing.
> > pm_runtime_enable(hda_codec_dev(codec));
> > /* it was powered up in snd_hda_codec_new(), now all done */
> > snd_hda_power_down(codec);
> > @@ -3196,6 +3212,9 @@ static int hda_codec_runtime_suspend(struct
> device *dev)
> > if (codec_has_clkstop(codec) && codec_has_epss(codec) &&
> > (state & AC_PWRST_CLK_STOP_OK))
> > snd_hdac_codec_link_down(&codec->core);
> > +
> > + if (codec->need_i915_power)
> > + snd_hdac_display_power(&codec->core, false);
> > return 0;
> > }
> >
> > @@ -3205,6 +3224,9 @@ static int hda_codec_runtime_resume(struct
> > device *dev)
> >
> > printk("amanda: hda_codec_runtime_resume, codec addr %d \n",
> > codec->addr);
> >
>
> I suppose you're working on a local modified tree?
Sorry. I were working on a snapshot of branch for-next two weeks ago. I'll move to the topic/hda branch and remove the printk.
>
> Overall, the code should work well without CONFIG_SND_HDA_I915.
> Please check each commit whether it builds and works with and without it.
Okay, I will.
Thanks for your review!
Mengdong
More information about the Alsa-devel
mailing list