From nobody Thu Apr 2 18:29:46 2026 Received: from out28-136.mail.aliyun.com (out28-136.mail.aliyun.com [115.124.28.136]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 13A5F3D5651; Fri, 27 Mar 2026 08:16:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=115.124.28.136 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774599411; cv=none; b=IoGPF3udhblmX0d07mhxTkrTnh101poJIAFA5sOA+Wy8waVwbn2OhWJuKIKMKfcPgMlMY71TcAUuyTZai6kOi+lp8YjrLg0wB2GOvK+jbQsDEf8e7jrAkWq74y7jttDPDTj2H2zf+mjVpN/5Kn3YTja8h1Hfu1TtRZ/P8AWtYhA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1774599411; c=relaxed/simple; bh=/nxndo//ast7P75ncXLL86cDTV+NCxVD2lEMWPd79lw=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=H+JEa3oYjvOPuG7jspQ9PVgDdiS+rZeeYXFA1p1F3nyeLZdPBqlgqqITlVYdHszdovvDEVBueXZxLJAxl/6LX83VAHKJM8xWXRR+ICOFTxRyvLAE6fBq/rfgVAoaflfhvkfJ9Zsx1rJPwssr0Lg63MXaStoDSLsh4htndBOeznA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=open-hieco.net; spf=pass smtp.mailfrom=open-hieco.net; arc=none smtp.client-ip=115.124.28.136 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=open-hieco.net Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=open-hieco.net X-Alimail-AntiSpam: AC=CONTINUE;BC=0.07436259|-1;CH=blue;DM=|OVERLOAD|false|;DS=CONTINUE|ham_system_inform|0.00344733-0.00060156-0.995951;FP=13132325447127404178|3|1|1|0|-1|-1|-1;HT=maildocker-contentspam033037025160;MF=fuhao@open-hieco.net;NM=1;PH=DS;RN=5;RT=5;SR=0;TI=SMTPD_---.h.Byuum_1774599079; Received: from higon..(mailfrom:fuhao@open-hieco.net fp:SMTPD_---.h.Byuum_1774599079 cluster:ay29) by smtp.aliyun-inc.com; Fri, 27 Mar 2026 16:11:25 +0800 From: Fu Hao To: perex@perex.cz, tiwai@suse.com Cc: linux-kernel@vger.kernel.org, linux-sound@vger.kernel.org, Fu Hao Subject: [PATCH 7/8] ALSA: hda: Fix single byte writing issue for Hygon family 18h model 5h Date: Fri, 27 Mar 2026 16:11:13 +0800 Message-Id: X-Mailer: git-send-email 2.34.1 In-Reply-To: References: Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" On Hygon family 18h model 5h controller, some registers such as GCTL, SD_CTL and SD_CTL_3B should be accessed in dword, or the writing will fail. Signed-off-by: Fu Hao --- include/sound/hdaudio.h | 1 + sound/hda/controllers/intel.c | 4 ++++ sound/hda/core/controller.c | 10 +++++++-- sound/hda/core/stream.c | 42 ++++++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/include/sound/hdaudio.h b/include/sound/hdaudio.h index f11bfc6b9..57a144fec 100644 --- a/include/sound/hdaudio.h +++ b/include/sound/hdaudio.h @@ -352,6 +352,7 @@ struct hdac_bus { bool not_use_interrupts:1; /* prohibiting the RIRB IRQ */ bool access_sdnctl_in_dword:1; /* accessing the sdnctl register by dword = */ bool use_pio_for_commands:1; /* Use PIO instead of CORB for commands */ + bool hygon_dword_access:1; =20 int poll_count; =20 diff --git a/sound/hda/controllers/intel.c b/sound/hda/controllers/intel.c index eb5d48d90..6b27248dc 100644 --- a/sound/hda/controllers/intel.c +++ b/sound/hda/controllers/intel.c @@ -1885,6 +1885,10 @@ static int azx_first_init(struct azx *chip) if (chip->driver_type =3D=3D AZX_DRIVER_ZHAOXINHDMI) bus->polling_mode =3D 1; =20 + if (chip->driver_type =3D=3D AZX_DRIVER_HYGON && + chip->pci->device =3D=3D PCI_DEVICE_ID_HYGON_18H_M05H_HDA) + bus->hygon_dword_access =3D 1; + bus->remap_addr =3D pcim_iomap_region(pci, 0, "ICH HD audio"); if (IS_ERR(bus->remap_addr)) return PTR_ERR(bus->remap_addr); diff --git a/sound/hda/core/controller.c b/sound/hda/core/controller.c index 69e11d62b..bfe817045 100644 --- a/sound/hda/core/controller.c +++ b/sound/hda/core/controller.c @@ -511,7 +511,10 @@ void snd_hdac_bus_exit_link_reset(struct hdac_bus *bus) { unsigned long timeout; =20 - snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET); + if (bus->hygon_dword_access) + snd_hdac_chip_updatel(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET); + else + snd_hdac_chip_updateb(bus, GCTL, AZX_GCTL_RESET, AZX_GCTL_RESET); =20 timeout =3D jiffies + msecs_to_jiffies(100); while (!snd_hdac_chip_readb(bus, GCTL) && time_before(jiffies, timeout)) @@ -576,7 +579,10 @@ static void azx_int_disable(struct hdac_bus *bus) =20 /* disable interrupts in stream descriptor */ list_for_each_entry(azx_dev, &bus->stream_list, list) - snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0); + if (bus->hygon_dword_access) + snd_hdac_stream_updatel(azx_dev, SD_CTL, SD_INT_MASK, 0); + else + snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_INT_MASK, 0); =20 /* disable SIE for all streams & disable controller CIE and GIE */ snd_hdac_chip_writel(bus, INTCTL, 0); diff --git a/sound/hda/core/stream.c b/sound/hda/core/stream.c index b471a038b..ccc0003a8 100644 --- a/sound/hda/core/stream.c +++ b/sound/hda/core/stream.c @@ -146,11 +146,15 @@ void snd_hdac_stream_start(struct hdac_stream *azx_de= v) stripe_ctl =3D snd_hdac_get_stream_stripe_ctl(bus, azx_dev->substream); else stripe_ctl =3D 0; - snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, - stripe_ctl); + if (bus->hygon_dword_access) + snd_hdac_stream_updatel(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, + stripe_ctl); + else + snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, + stripe_ctl); } /* set DMA start and interrupt mask */ - if (bus->access_sdnctl_in_dword) + if (bus->access_sdnctl_in_dword || bus->hygon_dword_access) snd_hdac_stream_updatel(azx_dev, SD_CTL, 0, SD_CTL_DMA_START | SD_INT_MASK); else @@ -166,11 +170,22 @@ EXPORT_SYMBOL_GPL(snd_hdac_stream_start); */ static void snd_hdac_stream_clear(struct hdac_stream *azx_dev) { - snd_hdac_stream_updateb(azx_dev, SD_CTL, - SD_CTL_DMA_START | SD_INT_MASK, 0); - snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */ - if (azx_dev->stripe) - snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0); + struct hdac_bus *bus =3D azx_dev->bus; + + if (bus->hygon_dword_access) { + snd_hdac_stream_updatel(azx_dev, SD_CTL, + SD_CTL_DMA_START | SD_INT_MASK, 0); + snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */ + if (azx_dev->stripe) + snd_hdac_stream_updatel(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0); + } else { + snd_hdac_stream_updateb(azx_dev, SD_CTL, + SD_CTL_DMA_START | SD_INT_MASK, 0); + snd_hdac_stream_writeb(azx_dev, SD_STS, SD_INT_MASK); /* to be sure */ + if (azx_dev->stripe) + snd_hdac_stream_updateb(azx_dev, SD_CTL_3B, SD_CTL_STRIPE_MASK, 0); + } + azx_dev->running =3D false; } =20 @@ -225,12 +240,16 @@ void snd_hdac_stream_reset(struct hdac_stream *azx_de= v) { unsigned char val; int dma_run_state; + struct hdac_bus *bus =3D azx_dev->bus; =20 snd_hdac_stream_clear(azx_dev); =20 dma_run_state =3D snd_hdac_stream_readb(azx_dev, SD_CTL) & SD_CTL_DMA_STA= RT; =20 - snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET); + if (bus->hygon_dword_access) + snd_hdac_stream_updatel(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET); + else + snd_hdac_stream_updateb(azx_dev, SD_CTL, 0, SD_CTL_STREAM_RESET); =20 /* wait for hardware to report that the stream entered reset */ snd_hdac_stream_readb_poll(azx_dev, SD_CTL, val, (val & SD_CTL_STREAM_RES= ET), 3, 300); @@ -238,7 +257,10 @@ void snd_hdac_stream_reset(struct hdac_stream *azx_dev) if (azx_dev->bus->dma_stop_delay && dma_run_state) udelay(azx_dev->bus->dma_stop_delay); =20 - snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_CTL_STREAM_RESET, 0); + if (bus->hygon_dword_access) + snd_hdac_stream_updatel(azx_dev, SD_CTL, SD_CTL_STREAM_RESET, 0); + else + snd_hdac_stream_updateb(azx_dev, SD_CTL, SD_CTL_STREAM_RESET, 0); =20 /* wait for hardware to report that the stream is out of reset */ snd_hdac_stream_readb_poll(azx_dev, SD_CTL, val, !(val & SD_CTL_STREAM_RE= SET), 3, 300); --=20 2.34.1