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 <pierre-louis.bossart@linux.intel.com Reviewed-by: Bard Liao <yung-chuan.liao@linux.intel.com Reviewed-by: Rander Wang <rander.wang@intel.com Reviewed-by: Ranjani Sridharan <ranjani.sridharan@linux.intel.com Link: https://lore.kernel.org/r/20230512174611.84372-7-pierre-louis.bossart@linux.intel.com Signed-off-by: Mark Brown <broonie@kernel.org
This commit is contained in:
Родитель
9643456ec3
Коммит
ccc2f0c1b6
|
@ -44,6 +44,9 @@ int hdac_bus_eml_sdw_power_down_unlocked(struct hdac_bus *bus, int sublink);
|
|||
|
||||
int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num);
|
||||
|
||||
int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
|
||||
int channel_mask, int stream_id, int dir);
|
||||
|
||||
void hda_bus_ml_put_all(struct hdac_bus *bus);
|
||||
void hda_bus_ml_reset_losidv(struct hdac_bus *bus);
|
||||
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
|
|||
static inline int
|
||||
hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num) { return 0; }
|
||||
|
||||
static inline int
|
||||
hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
|
||||
int channel_mask, int stream_id, int dir)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void hda_bus_ml_put_all(struct hdac_bus *bus) { }
|
||||
static inline void hda_bus_ml_reset_losidv(struct hdac_bus *bus) { }
|
||||
static inline int hda_bus_ml_resume(struct hdac_bus *bus) { return 0; }
|
||||
|
|
|
@ -73,6 +73,7 @@ struct hdac_ext2_link {
|
|||
#define AZX_REG_SDW_SHIM_OFFSET 0x0
|
||||
#define AZX_REG_SDW_IP_OFFSET 0x100
|
||||
#define AZX_REG_SDW_VS_SHIM_OFFSET 0x6000
|
||||
#define AZX_REG_SDW_SHIM_PCMSyCM(y) (0x16 + 0x4 * (y))
|
||||
|
||||
/* only one instance supported */
|
||||
#define AZX_REG_INTEL_DMIC_SHIM_OFFSET 0x0
|
||||
|
@ -340,6 +341,21 @@ static void hdaml_link_set_lsdiid(u32 __iomem *lsdiid, int dev_num)
|
|||
writel(val, lsdiid);
|
||||
}
|
||||
|
||||
static void hdaml_shim_map_stream_ch(u16 __iomem *pcmsycm, int lchan, int hchan,
|
||||
int stream_id, int dir)
|
||||
{
|
||||
u16 val;
|
||||
|
||||
val = readw(pcmsycm);
|
||||
|
||||
u16p_replace_bits(&val, lchan, GENMASK(3, 0));
|
||||
u16p_replace_bits(&val, hchan, GENMASK(7, 4));
|
||||
u16p_replace_bits(&val, stream_id, GENMASK(13, 8));
|
||||
u16p_replace_bits(&val, dir, BIT(15));
|
||||
|
||||
writew(val, pcmsycm);
|
||||
}
|
||||
|
||||
static void hdaml_lctl_offload_enable(u32 __iomem *lctl, bool enable)
|
||||
{
|
||||
u32 val = readl(lctl);
|
||||
|
@ -756,6 +772,40 @@ int hdac_bus_eml_sdw_set_lsdiid(struct hdac_bus *bus, int sublink, int dev_num)
|
|||
return 0;
|
||||
} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_set_lsdiid, SND_SOC_SOF_HDA_MLINK);
|
||||
|
||||
/*
|
||||
* the 'y' parameter comes from the PCMSyCM hardware register naming. 'y' refers to the
|
||||
* PDI index, i.e. the FIFO used for RX or TX
|
||||
*/
|
||||
int hdac_bus_eml_sdw_map_stream_ch(struct hdac_bus *bus, int sublink, int y,
|
||||
int channel_mask, int stream_id, int dir)
|
||||
{
|
||||
struct hdac_ext2_link *h2link;
|
||||
u16 __iomem *pcmsycm;
|
||||
u16 val;
|
||||
|
||||
h2link = find_ext2_link(bus, true, AZX_REG_ML_LEPTR_ID_SDW);
|
||||
if (!h2link)
|
||||
return -ENODEV;
|
||||
|
||||
pcmsycm = h2link->base_ptr + h2link->shim_offset +
|
||||
h2link->instance_offset * sublink +
|
||||
AZX_REG_SDW_SHIM_PCMSyCM(y);
|
||||
|
||||
mutex_lock(&h2link->eml_lock);
|
||||
|
||||
hdaml_shim_map_stream_ch(pcmsycm, 0, hweight32(channel_mask),
|
||||
stream_id, dir);
|
||||
|
||||
mutex_unlock(&h2link->eml_lock);
|
||||
|
||||
val = readw(pcmsycm);
|
||||
|
||||
dev_dbg(bus->dev, "channel_mask %#x stream_id %d dir %d pcmscm %#x\n",
|
||||
channel_mask, stream_id, dir, val);
|
||||
|
||||
return 0;
|
||||
} EXPORT_SYMBOL_NS(hdac_bus_eml_sdw_map_stream_ch, SND_SOC_SOF_HDA_MLINK);
|
||||
|
||||
void hda_bus_ml_put_all(struct hdac_bus *bus)
|
||||
{
|
||||
struct hdac_ext_link *hlink;
|
||||
|
|
Загрузка…
Ссылка в новой задаче