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

initial SOF hdac serials. #47

Merged
merged 7 commits into from
Jul 30, 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: 0 additions & 1 deletion sound/soc/intel/boards/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,6 @@ config SND_SOC_INTEL_SKL_HDA_DSP_GENERIC_MACH
tristate "SKL/KBL/BXT/APL with HDA Codecs"
select SND_SOC_HDAC_HDMI
select SND_SOC_HDAC_HDA
select SND_SOC_SOF_HDA if SND_SOC_SOF_HDA_COMMON
help
This adds support for ASoC machine driver for Intel platforms
SKL/KBL/BXT/APL with iDisp, HDA audio codecs.
Expand Down
10 changes: 9 additions & 1 deletion sound/soc/sof/intel/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,15 @@ config SND_SOC_SOF_HDA_COMMON
select SND_SOC_ACPI_INTEL_MATCH

config SND_SOC_SOF_HDA
tristate
tristate "SOF support for HDA Links(HDA/HDMI)"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this have a help section (check patch complains without one).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let me add it.

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
5 changes: 4 additions & 1 deletion sound/soc/sof/intel/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,13 @@ 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-codec.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
135 changes: 135 additions & 0 deletions sound/soc/sof/intel/hda-bus.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
// 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 <[email protected]>
* Keyon Jie <[email protected]>
*/

#include <sound/hdaudio.h>

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Isn't this implied by Kconfig option

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are you meaning that IS_ENABLED(CONFIG_SND_SOC_SOF_HDA) is true always?
the answer is no for that, it is tristate, we can choose them or not in menuconfig.


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

/*
* process queued unsolicited events
*/
static void hda_process_unsol_events(struct work_struct *work)
{
struct hdac_bus *bus = container_of(work, struct hdac_bus, unsol_work);
struct hdac_device *codec;
struct hdac_driver *drv;
unsigned int rp, caddr, res;

while (bus->unsol_rp != bus->unsol_wp) {
rp = (bus->unsol_rp + 1) % HDA_UNSOL_QUEUE_SIZE;
bus->unsol_rp = rp;
rp <<= 1;
res = bus->unsol_queue[rp];
caddr = bus->unsol_queue[rp + 1];
if (!(caddr & (1 << 4))) /* no unsolicited event? */
continue;
codec = bus->caddr_tbl[caddr & 0x0f];
if (!codec || !codec->dev.driver)
continue;
drv = drv_to_hdac_driver(codec->dev.driver);
if (drv->unsol_event)
drv->unsol_event(codec, res);
}
}

#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;
#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
bus->ops = &bus_ops;
#endif
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)
INIT_WORK(&bus->unsol_work, hda_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;
}
15 changes: 8 additions & 7 deletions sound/soc/sof/intel/hda-codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* 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) 2017 Intel Corporation. All rights reserved.
* Copyright(c) 2018 Intel Corporation. All rights reserved.
*
* Authors: Jeeja KP <[email protected]>
* Keyon Jie <[email protected]>
Expand All @@ -22,7 +22,6 @@
#include <sound/hda_i915.h>
#include <sound/hda_register.h>
#include <sound/hdaudio.h>
#include <sound/hda_i915.h>

#include "../../../pci/hda/hda_codec.h"
#include "../../codecs/hdac_hda.h"
Expand Down Expand Up @@ -51,7 +50,7 @@ static void hda_codec_load_module(struct hda_codec *codec) {}
/* probe individual codec */
static int hda_codec_probe(struct snd_sof_dev *sdev, int addr)
{
struct hda_bus *hbus = sdev->hbus;
struct hda_bus *hbus = sof_to_hbus(sdev);
unsigned int cmd = (addr << 28) | (AC_NODE_ROOT << 20) |
(AC_VERB_PARAMETERS << 8) | AC_PAR_VENDOR_ID;
unsigned int res = -1;
Expand Down Expand Up @@ -92,8 +91,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int addr)
/* Codec initialization */
int hda_codec_probe_bus(struct snd_sof_dev *sdev)
{
struct hda_bus *hbus = sdev->hbus;
struct hdac_bus *bus = &hbus->core;
struct hdac_bus *bus = sof_to_bus(sdev);
int c, max_slots, ret = 0;

max_slots = HDA_MAX_CODECS;
Expand All @@ -113,11 +111,11 @@ int hda_codec_probe_bus(struct snd_sof_dev *sdev)

return 0;
}
EXPORT_SYMBOL(hda_codec_probe_bus);

int hda_codec_i915_init(struct snd_sof_dev *sdev)
{
struct hda_bus *hbus = sdev->hbus;
struct hdac_bus *bus = &hbus->core;
struct hdac_bus *bus = sof_to_bus(sdev);
int ret;

/* i915 exposes a HDA codec for HDMI audio */
Expand All @@ -131,4 +129,7 @@ int hda_codec_i915_init(struct snd_sof_dev *sdev)

return ret;
}
EXPORT_SYMBOL(hda_codec_i915_init);

MODULE_LICENSE("Dual BSD/GPL");

32 changes: 22 additions & 10 deletions sound/soc/sof/intel/hda-ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,9 @@ int hda_dsp_ctrl_link_reset(struct snd_sof_dev *sdev)

int hda_dsp_ctrl_get_caps(struct snd_sof_dev *sdev)
{
struct hdac_bus *bus = sof_to_bus(sdev);
u32 cap, offset, feature;
int ret = -ENODEV, count = 0;
int count = 0;

offset = snd_sof_dsp_read(sdev, HDA_DSP_HDA_BAR, SOF_HDA_LLCH);

Expand All @@ -103,21 +104,30 @@ int hda_dsp_ctrl_get_caps(struct snd_sof_dev *sdev)
case SOF_HDA_PP_CAP_ID:
dev_dbg(sdev->dev, "found DSP capability at 0x%x\n",
offset);
sdev->bar[HDA_DSP_PP_BAR] = sdev->bar[HDA_DSP_HDA_BAR] +
offset;
ret = 0;
bus->ppcap = bus->remap_addr + offset;
sdev->bar[HDA_DSP_PP_BAR] = bus->ppcap;
break;
case SOF_HDA_SPIB_CAP_ID:
dev_dbg(sdev->dev, "found SPIB capability at 0x%x\n",
offset);
sdev->bar[HDA_DSP_SPIB_BAR] =
sdev->bar[HDA_DSP_HDA_BAR] + offset;
bus->spbcap = bus->remap_addr + offset;
sdev->bar[HDA_DSP_SPIB_BAR] = bus->spbcap;
break;
case SOF_HDA_DRSM_CAP_ID:
dev_dbg(sdev->dev, "found DRSM capability at 0x%x\n",
offset);
sdev->bar[HDA_DSP_DRSM_BAR] =
sdev->bar[HDA_DSP_HDA_BAR] + offset;
bus->drsmcap = bus->remap_addr + offset;
sdev->bar[HDA_DSP_DRSM_BAR] = bus->drsmcap;
break;
case SOF_HDA_GTS_CAP_ID:
dev_dbg(sdev->dev, "found GTS capability at 0x%x\n",
offset);
bus->gtscap = bus->remap_addr + offset;
break;
case SOF_HDA_ML_CAP_ID:
dev_dbg(sdev->dev, "found ML capability at 0x%x\n",
offset);
bus->mlcap = bus->remap_addr + offset;
break;
default:
dev_vdbg(sdev->dev, "found capability %d at 0x%x\n",
Expand All @@ -128,7 +138,7 @@ int hda_dsp_ctrl_get_caps(struct snd_sof_dev *sdev)
offset = cap & SOF_HDA_CAP_NEXT_MASK;
} while (count++ <= SOF_HDA_MAX_CAPS && offset);

return ret;
return 0;
}

void hda_dsp_ctrl_enable_miscbdcge(struct snd_sof_dev *sdev, bool enable)
Expand All @@ -138,14 +148,15 @@ void hda_dsp_ctrl_enable_miscbdcge(struct snd_sof_dev *sdev, bool enable)
snd_sof_pci_update_bits(sdev, PCI_CGCTL, PCI_CGCTL_MISCBDCGE_MASK, val);
}

#if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA)
/*
* While performing reset, controller may not come back properly causing
* issues, so recommendation is to set CGCTL.MISCBDCGE to 0 then do reset
* (init chip) and then again set CGCTL.MISCBDCGE to 1
*/
int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)
{
struct hdac_bus *bus = &sdev->hbus->core;
struct hdac_bus *bus = sof_to_bus(sdev);
int ret;

hda_dsp_ctrl_enable_miscbdcge(sdev, false);
Expand All @@ -154,4 +165,5 @@ int hda_dsp_ctrl_init_chip(struct snd_sof_dev *sdev, bool full_reset)

return ret;
}
#endif

Loading