Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

SOF HDA/HDMI enabling -- Part1 #101

Merged
merged 12 commits into from
Aug 31, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions include/sound/hdaudio.h
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,7 @@ void snd_hdac_bus_queue_event(struct hdac_bus *bus, u32 res, u32 res_ex);
int snd_hdac_bus_add_device(struct hdac_bus *bus, struct hdac_device *codec);
void snd_hdac_bus_remove_device(struct hdac_bus *bus,
struct hdac_device *codec);
void snd_hdac_bus_process_unsol_events(struct work_struct *work);

static inline void snd_hdac_codec_link_up(struct hdac_device *codec)
{
Expand Down
22 changes: 7 additions & 15 deletions sound/hda/ext/hdac_ext_stream.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,7 +146,8 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_stream_decouple);
*/
void snd_hdac_ext_link_stream_start(struct hdac_ext_stream *stream)
{
snd_hdac_updatel(stream->pplc_addr, AZX_REG_PPLCCTL, 0, AZX_PPLCCTL_RUN);
snd_hdac_updatel(stream->pplc_addr, AZX_REG_PPLCCTL,
AZX_PPLCCTL_RUN, AZX_PPLCCTL_RUN);
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_link_stream_start);

Expand All @@ -171,7 +172,8 @@ void snd_hdac_ext_link_stream_reset(struct hdac_ext_stream *stream)

snd_hdac_ext_link_stream_clear(stream);

snd_hdac_updatel(stream->pplc_addr, AZX_REG_PPLCCTL, 0, AZX_PPLCCTL_STRST);
snd_hdac_updatel(stream->pplc_addr, AZX_REG_PPLCCTL,
AZX_PPLCCTL_STRST, AZX_PPLCCTL_STRST);
udelay(3);
timeout = 50;
do {
Expand Down Expand Up @@ -242,7 +244,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_ext_link_set_stream_id);
void snd_hdac_ext_link_clear_stream_id(struct hdac_ext_link *link,
int stream)
{
snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, 0, (1 << stream));
snd_hdac_updatew(link->ml_addr, AZX_REG_ML_LOSIDV, (1 << stream), 0);
}
EXPORT_SYMBOL_GPL(snd_hdac_ext_link_clear_stream_id);

Expand Down Expand Up @@ -415,7 +417,6 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *bus,
bool enable, int index)
{
u32 mask = 0;
u32 register_mask = 0;

if (!bus->spbcap) {
dev_err(bus->dev, "Address of SPB capability is NULL\n");
Expand All @@ -424,12 +425,8 @@ void snd_hdac_ext_stream_spbcap_enable(struct hdac_bus *bus,

mask |= (1 << index);

register_mask = readl(bus->spbcap + AZX_REG_SPB_SPBFCCTL);

mask |= register_mask;

if (enable)
snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, 0, mask);
snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, mask);
else
snd_hdac_updatel(bus->spbcap, AZX_REG_SPB_SPBFCCTL, mask, 0);
}
Expand Down Expand Up @@ -503,7 +500,6 @@ void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,
bool enable, int index)
{
u32 mask = 0;
u32 register_mask = 0;

if (!bus->drsmcap) {
dev_err(bus->dev, "Address of DRSM capability is NULL\n");
Expand All @@ -512,12 +508,8 @@ void snd_hdac_ext_stream_drsm_enable(struct hdac_bus *bus,

mask |= (1 << index);

register_mask = readl(bus->drsmcap + AZX_REG_SPB_SPBFCCTL);

mask |= register_mask;

if (enable)
snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, 0, mask);
snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, mask);
else
snd_hdac_updatel(bus->drsmcap, AZX_REG_DRSM_CTL, mask, 0);
}
Expand Down
7 changes: 3 additions & 4 deletions sound/hda/hdac_bus.c
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@
#include <sound/hdaudio.h>
#include "trace.h"

static void process_unsol_events(struct work_struct *work);

static const struct hdac_bus_ops default_ops = {
.command = snd_hdac_bus_send_cmd,
.get_response = snd_hdac_bus_get_response,
Expand All @@ -37,7 +35,7 @@ int snd_hdac_bus_init(struct hdac_bus *bus, struct device *dev,
bus->io_ops = io_ops;
INIT_LIST_HEAD(&bus->stream_list);
INIT_LIST_HEAD(&bus->codec_list);
INIT_WORK(&bus->unsol_work, process_unsol_events);
INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events);
spin_lock_init(&bus->reg_lock);
mutex_init(&bus->cmd_mutex);
bus->irq = -1;
Expand Down Expand Up @@ -148,7 +146,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_bus_queue_event);
/*
* process queued unsolicited events
*/
static void process_unsol_events(struct work_struct *work)
void snd_hdac_bus_process_unsol_events(struct work_struct *work)
{
struct hdac_bus *bus = container_of(work, struct hdac_bus, unsol_work);
struct hdac_device *codec;
Expand All @@ -171,6 +169,7 @@ static void process_unsol_events(struct work_struct *work)
drv->unsol_event(codec, res);
}
}
EXPORT_SYMBOL_GPL(snd_hdac_bus_process_unsol_events);

/**
* snd_hdac_bus_add_device - Add a codec to bus
Expand Down
2 changes: 1 addition & 1 deletion sound/soc/sof/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -289,7 +289,7 @@ static int sof_probe(struct platform_device *pdev)
}

/* load the firmware */
ret = snd_sof_load_firmware(sdev, plat_data->fw, true);
ret = snd_sof_load_firmware(sdev, true);
if (ret < 0) {
dev_err(sdev->dev, "error: failed to load DSP firmware %d\n",
ret);
Expand Down
12 changes: 12 additions & 0 deletions sound/soc/sof/intel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,16 @@ config SND_SOC_SOF_HDA_COMMON
select SND_SOC_SOF_PCI
select SND_SOC_ACPI_INTEL_MATCH

config SND_SOC_SOF_HDA
tristate "SOF support for HDA Links(HDA/HDMI)"
depends on SND_SOC_SOF_HDA_COMMON
select SND_HDA_EXT_CORE
select SND_SOC_HDAC_HDA
select SND_SOC_HDAC_HDMI
help
This adds support for HDA links(HDA/HDMI) with Sound Open Firmware
for Intel(R) platforms.
Say Y if you want to enble HDA links with SOF.
If unsure select "N".

endif ## SND_SOC_SOF_INTEL
6 changes: 5 additions & 1 deletion sound/soc/sof/intel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,14 @@ snd-sof-intel-byt-objs := byt.o
snd-sof-intel-hsw-objs := hsw.o
snd-sof-intel-bdw-objs := bdw.o
snd-sof-intel-hda-common-objs := hda.o hda-loader.o hda-stream.o hda-trace.o \
hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o hda-dai.o\
hda-dsp.o hda-ipc.o hda-ctrl.o hda-pcm.o \
hda-dai.o hda-bus.o \
skl.o apl.o cnl.o

snd-sof-intel-hda-objs := hda-codec.o

obj-$(CONFIG_SND_SOC_SOF_BAYTRAIL) += snd-sof-intel-byt.o
obj-$(CONFIG_SND_SOC_SOF_HASWELL) += snd-sof-intel-hsw.o
obj-$(CONFIG_SND_SOC_SOF_BROADWELL) += snd-sof-intel-bdw.o
obj-$(CONFIG_SND_SOC_SOF_HDA_COMMON) += snd-sof-intel-hda-common.o
obj-$(CONFIG_SND_SOC_SOF_HDA) += snd-sof-intel-hda.o
108 changes: 108 additions & 0 deletions sound/soc/sof/intel/hda-bus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
// SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause)
/*
* This file is provided under a dual BSD/GPLv2 license. When using or
* redistributing this file, you may do so under either license.
*
* Copyright(c) 2018 Intel Corporation. All rights reserved.
*
* Authors: Jeeja KP <jeeja.kp@intel.com>
* Keyon Jie <yang.jie@linux.intel.com>
*/

#include <sound/hdaudio.h>

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)

static const struct hdac_bus_ops bus_ops = {
.command = snd_hdac_bus_send_cmd,
.get_response = snd_hdac_bus_get_response,
};

#endif

static void sof_hda_writel(u32 value, u32 __iomem *addr)
{
writel(value, addr);
}

static u32 sof_hda_readl(u32 __iomem *addr)
{
return readl(addr);
}

static void sof_hda_writew(u16 value, u16 __iomem *addr)
{
writew(value, addr);
}

static u16 sof_hda_readw(u16 __iomem *addr)
{
return readw(addr);
}

static void sof_hda_writeb(u8 value, u8 __iomem *addr)
{
writeb(value, addr);
}

static u8 sof_hda_readb(u8 __iomem *addr)
{
return readb(addr);
}

static int sof_hda_dma_alloc_pages(struct hdac_bus *bus, int type,
size_t size, struct snd_dma_buffer *buf)
{
return snd_dma_alloc_pages(type, bus->dev, size, buf);
}

static void sof_hda_dma_free_pages(struct hdac_bus *bus,
struct snd_dma_buffer *buf)
{
snd_dma_free_pages(buf);
}

static const struct hdac_io_ops io_ops = {
.reg_writel = sof_hda_writel,
.reg_readl = sof_hda_readl,
.reg_writew = sof_hda_writew,
.reg_readw = sof_hda_readw,
.reg_writeb = sof_hda_writeb,
.reg_readb = sof_hda_readb,
.dma_alloc_pages = sof_hda_dma_alloc_pages,
.dma_free_pages = sof_hda_dma_free_pages,
};

/*
* This can be used for both with/without hda link support.
* Returns 0 if successful, or a negative error code.
*/
int sof_hda_bus_init(struct hdac_bus *bus, struct device *dev,
const struct hdac_ext_bus_ops *ext_ops)
{
static int idx;

memset(bus, 0, sizeof(*bus));
bus->dev = dev;

bus->io_ops = &io_ops;
INIT_LIST_HEAD(&bus->stream_list);
INIT_LIST_HEAD(&bus->codec_list);

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
bus->ops = &bus_ops;
INIT_WORK(&bus->unsol_work, snd_hdac_bus_process_unsol_events);
#endif
spin_lock_init(&bus->reg_lock);
mutex_init(&bus->cmd_mutex);
bus->irq = -1;

bus->ext_ops = ext_ops;
INIT_LIST_HEAD(&bus->hlink_list);
bus->idx = idx++;

mutex_init(&bus->lock);
bus->cmd_dma_state = true;

return 0;
}
Loading