Skip to content

Commit ccc2f0c

Browse files
plbossartbroonie
authored andcommitted
ASoC: SOF: Intel: hda-mlink: add helper to program SoundWire PCMSyCM registers
These registers enable the HDaudio DMA hardware to split/merge data from different PDIs, possibly on different links. This capability exists for all types of HDaudio extended links, but for now is only required for SoundWire. In the SSP/DMIC case, the IP is programmed by the DSP firmware. Signed-off-by: Pierre-Louis Bossart <[email protected] Reviewed-by: Bard Liao <[email protected] Reviewed-by: Rander Wang <[email protected] Reviewed-by: Ranjani Sridharan <[email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]
1 parent 9643456 commit ccc2f0c

File tree

2 files changed

+60
-0
lines changed

2 files changed

+60
-0
lines changed

include/sound/hda-mlink.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink);
4444

4545
int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);
4646

47+
int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
48+
int channel_mask, int stream_id, int dir);
49+
4750
void hda_bus_ml_put_all(struct hdac_bus *bus);
4851
void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
4952
int hda_bus_ml_resume(struct hdac_bus *bus);
@@ -145,6 +148,13 @@ hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink) { return
145148
static inline int
146149
hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { return 0; }
147150

151+
static inline int
152+
hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
153+
int channel_mask, int stream_id, int dir)
154+
{
155+
return 0;
156+
}
157+
148158
static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
149159
static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
150160
static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }

sound/soc/sof/intel/hda-mlink.c

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ struct hdac_ext2_link {
7373
#define AZX_REG_SDW_SHIM_OFFSET 0x0
7474
#define AZX_REG_SDW_IP_OFFSET 0x100
7575
#define AZX_REG_SDW_VS_SHIM_OFFSET 0x6000
76+
#define AZX_REG_SDW_SHIM_PCMSyCM(y) (0x16 + 0x4 * (y))
7677

7778
/* only one instance supported */
7879
#define AZX_REG_INTEL_DMIC_SHIM_OFFSET 0x0
@@ -340,6 +341,21 @@ static void hdaml_link_set_lsdiid(u32 __iomem *lsdiid, int dev_num)
340341
writel(val, lsdiid);
341342
}
342343

344+
static void hdaml_shim_map_stream_ch(u16 __iomem *pcmsycm, int lchan, int hchan,
345+
int stream_id, int dir)
346+
{
347+
u16 val;
348+
349+
val = readw(pcmsycm);
350+
351+
u16p_replace_bits(&val, lchan, GENMASK(3, 0));
352+
u16p_replace_bits(&val, hchan, GENMASK(7, 4));
353+
u16p_replace_bits(&val, stream_id, GENMASK(13, 8));
354+
u16p_replace_bits(&val, dir, BIT(15));
355+
356+
writew(val, pcmsycm);
357+
}
358+
343359
static void hdaml_lctl_offload_enable(u32 __iomem *lctl, bool enable)
344360
{
345361
u32 val = readl(lctl);
@@ -756,6 +772,40 @@ int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num)
756772
return 0;
757773
} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_set_lsdiid, SND_SOC_SOF_HDA_MLINK);
758774

775+
/*
776+
* the 'y' parameter comes from the PCMSyCM hardware register naming. 'y' refers to the
777+
* PDI index, i.e. the FIFO used for RX or TX
778+
*/
779+
int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
780+
int channel_mask, int stream_id, int dir)
781+
{
782+
struct hdac_ext2_link *h2link;
783+
u16 __iomem *pcmsycm;
784+
u16 val;
785+
786+
h2link = find_ext2_link(bus, true, AZX_REG_ML_LEPTR_ID_SDW);
787+
if (!h2link)
788+
return -ENODEV;
789+
790+
pcmsycm = h2link->base_ptr + h2link->shim_offset +
791+
h2link->instance_offset * sublink +
792+
AZX_REG_SDW_SHIM_PCMSyCM(y);
793+
794+
mutex_lock(&h2link->eml_lock);
795+
796+
hdaml_shim_map_stream_ch(pcmsycm, 0, hweight32(channel_mask),
797+
stream_id, dir);
798+
799+
mutex_unlock(&h2link->eml_lock);
800+
801+
val = readw(pcmsycm);
802+
803+
dev_dbg(bus->dev, "channel_mask %#x stream_id %d dir %d pcmscm %#x\n",
804+
channel_mask, stream_id, dir, val);
805+
806+
return 0;
807+
} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_map_stream_ch, SND_SOC_SOF_HDA_MLINK);
808+
759809
void hda_bus_ml_put_all(struct hdac_bus *bus)
760810
{
761811
struct hdac_ext_link *hlink;

0 commit comments

Comments
 (0)