diff mbox series

[2/4] ALSA: hda: Using polling mode for loongson controller by default

Message ID ad85194e2da2118ff49f127ffd74727e298a3ea5.1685501806.git.siyanteng@loongson.cn
State New
Headers show
Series Add Loongson HD Audio support | expand

Commit Message

Yanteng Si May 31, 2023, 3:21 a.m. UTC
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(-)

Comments

Takashi Iwai June 5, 2023, 7:35 a.m. UTC | #1
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
Yanteng Si June 6, 2023, 12:10 p.m. UTC | #2
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 mbox series

Patch

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);