Message ID | ad85194e2da2118ff49f127ffd74727e298a3ea5.1685501806.git.siyanteng@loongson.cn (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | Add Loongson HD Audio support | expand |
On Wed, 31 May 2023 05:21:32 +0200, Yanteng Si wrote: > > On loongson controller, RIRBSTS.RINTFL cannot be cleared, > azx_interrupt() is called all the time. We disable RIRB > interrupt, and use polling mode by default. > > Signed-off-by: Yanteng Si <siyanteng@loongson.cn> > Signed-off-by: Yingkun Meng <mengyingkun@loongson.cn> > --- > sound/hda/hdac_controller.c | 8 +++++++- > 1 file changed, 7 insertions(+), 1 deletion(-) > > diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c > index 3c7af6558249..dbaa19cb8162 100644 > --- a/sound/hda/hdac_controller.c > +++ b/sound/hda/hdac_controller.c > @@ -10,6 +10,7 @@ > #include <sound/hdaudio.h> > #include <sound/hda_register.h> > #include "local.h" > +#include "../pci/hda/hda_controller.h" > > /* clear CORB read pointer properly */ > static void azx_clear_corbrp(struct hdac_bus *bus) > @@ -42,6 +43,8 @@ static void azx_clear_corbrp(struct hdac_bus *bus) > */ > void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) > { > + struct azx *chip = bus_to_azx(bus); You can't convert in this way in the generic HD-audio bus code in sound/hda/*. The struct azx is specific to sound/pci/hda/*. > WARN_ON_ONCE(!bus->rb.area); > > spin_lock_irq(&bus->reg_lock); > @@ -79,7 +82,10 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) > /* set N=1, get RIRB response interrupt for new entry */ > snd_hdac_chip_writew(bus, RINTCNT, 1); > /* enable rirb dma and response irq */ > - snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); > + if (chip->driver_caps & AZX_DCAPS_LOONGSON_WORKAROUND) > + snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN); > + else > + snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); That is, for some device-specific workaround like this, you'd need to introduce a new flag in struct hdac_bus, set up in the sound/pci/hda/hda_intel.c instead. thanks, Takashi
On 2023/6/5 15:35, Takashi Iwai wrote: > On Wed, 31 May 2023 05:21:32 +0200, > Yanteng Si wrote: >> On loongson controller, RIRBSTS.RINTFL cannot be cleared, >> azx_interrupt() is called all the time. We disable RIRB >> interrupt, and use polling mode by default. >> >> Signed-off-by: Yanteng Si <siyanteng@loongson.cn> >> Signed-off-by: Yingkun Meng <mengyingkun@loongson.cn> >> --- >> sound/hda/hdac_controller.c | 8 +++++++- >> 1 file changed, 7 insertions(+), 1 deletion(-) >> >> diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c >> index 3c7af6558249..dbaa19cb8162 100644 >> --- a/sound/hda/hdac_controller.c >> +++ b/sound/hda/hdac_controller.c >> @@ -10,6 +10,7 @@ >> #include <sound/hdaudio.h> >> #include <sound/hda_register.h> >> #include "local.h" >> +#include "../pci/hda/hda_controller.h" >> >> /* clear CORB read pointer properly */ >> static void azx_clear_corbrp(struct hdac_bus *bus) >> @@ -42,6 +43,8 @@ static void azx_clear_corbrp(struct hdac_bus *bus) >> */ >> void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) >> { >> + struct azx *chip = bus_to_azx(bus); > You can't convert in this way in the generic HD-audio bus code in > sound/hda/*. The struct azx is specific to sound/pci/hda/*. I see! > > >> WARN_ON_ONCE(!bus->rb.area); >> >> spin_lock_irq(&bus->reg_lock); >> @@ -79,7 +82,10 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) >> /* set N=1, get RIRB response interrupt for new entry */ >> snd_hdac_chip_writew(bus, RINTCNT, 1); >> /* enable rirb dma and response irq */ >> - snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); >> + if (chip->driver_caps & AZX_DCAPS_LOONGSON_WORKAROUND) >> + snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN); >> + else >> + snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); > That is, for some device-specific workaround like this, you'd need to > introduce a new flag in struct hdac_bus, set up in the > sound/pci/hda/hda_intel.c instead. OK! I will try to put your ideas into practice. Thanks, Yanteng > > > thanks, > > Takashi
diff --git a/sound/hda/hdac_controller.c b/sound/hda/hdac_controller.c index 3c7af6558249..dbaa19cb8162 100644 --- a/sound/hda/hdac_controller.c +++ b/sound/hda/hdac_controller.c @@ -10,6 +10,7 @@ #include <sound/hdaudio.h> #include <sound/hda_register.h> #include "local.h" +#include "../pci/hda/hda_controller.h" /* clear CORB read pointer properly */ static void azx_clear_corbrp(struct hdac_bus *bus) @@ -42,6 +43,8 @@ static void azx_clear_corbrp(struct hdac_bus *bus) */ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) { + struct azx *chip = bus_to_azx(bus); + WARN_ON_ONCE(!bus->rb.area); spin_lock_irq(&bus->reg_lock); @@ -79,7 +82,10 @@ void snd_hdac_bus_init_cmd_io(struct hdac_bus *bus) /* set N=1, get RIRB response interrupt for new entry */ snd_hdac_chip_writew(bus, RINTCNT, 1); /* enable rirb dma and response irq */ - snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); + if (chip->driver_caps & AZX_DCAPS_LOONGSON_WORKAROUND) + snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN); + else + snd_hdac_chip_writeb(bus, RIRBCTL, AZX_RBCTL_DMA_EN | AZX_RBCTL_IRQ_EN); /* Accept unsolicited responses */ snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_UNSOL, AZX_GCTL_UNSOL); spin_unlock_irq(&bus->reg_lock);