Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d255b095 authored by Jeeja KP's avatar Jeeja KP Committed by Mark Brown
Browse files

ASoC: Intel: Skylake: Add dsp and ipc init helpers



This helper function will be used by the Skylake driver for dsp and
ipc initialization if processing pipe capability is supported.

Signed-off-by: default avatarJeeja KP <jeeja.kp@intel.com>
Signed-off-by: default avatarVinod Koul <vinod.koul@intel.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
parent 473eb87a
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o
snd-soc-skl-objs := skl.o skl-pcm.o skl-nhlt.o skl-messages.o


obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += snd-soc-skl.o


+133 −0
Original line number Original line Diff line number Diff line
/*
 *  skl-message.c - HDA DSP interface for FW registration, Pipe and Module
 *  configurations
 *
 *  Copyright (C) 2015 Intel Corp
 *  Author:Rafal Redzimski <rafal.f.redzimski@intel.com>
 *	   Jeeja KP <jeeja.kp@intel.com>
 *  ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as version 2, as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 */

#include <linux/slab.h>
#include <linux/pci.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include "skl-sst-dsp.h"
#include "skl-sst-ipc.h"
#include "skl.h"
#include "../common/sst-dsp.h"
#include "../common/sst-dsp-priv.h"

static int skl_alloc_dma_buf(struct device *dev,
		struct snd_dma_buffer *dmab, size_t size)
{
	struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
	struct hdac_bus *bus = ebus_to_hbus(ebus);

	if (!bus)
		return -ENODEV;

	return  bus->io_ops->dma_alloc_pages(bus, SNDRV_DMA_TYPE_DEV, size, dmab);
}

static int skl_free_dma_buf(struct device *dev, struct snd_dma_buffer *dmab)
{
	struct hdac_ext_bus *ebus = dev_get_drvdata(dev);
	struct hdac_bus *bus = ebus_to_hbus(ebus);

	if (!bus)
		return -ENODEV;

	bus->io_ops->dma_free_pages(bus, dmab);

	return 0;
}

int skl_init_dsp(struct skl *skl)
{
	void __iomem *mmio_base;
	struct hdac_ext_bus *ebus = &skl->ebus;
	struct hdac_bus *bus = ebus_to_hbus(ebus);
	int irq = bus->irq;
	struct skl_dsp_loader_ops loader_ops;
	int ret;

	loader_ops.alloc_dma_buf = skl_alloc_dma_buf;
	loader_ops.free_dma_buf = skl_free_dma_buf;

	/* enable ppcap interrupt */
	snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
	snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);

	/* read the BAR of the ADSP MMIO */
	mmio_base = pci_ioremap_bar(skl->pci, 4);
	if (mmio_base == NULL) {
		dev_err(bus->dev, "ioremap error\n");
		return -ENXIO;
	}

	ret = skl_sst_dsp_init(bus->dev, mmio_base, irq,
			loader_ops, &skl->skl_sst);

	dev_dbg(bus->dev, "dsp registration status=%d\n", ret);

	return ret;
}

void skl_free_dsp(struct skl *skl)
{
	struct hdac_ext_bus *ebus = &skl->ebus;
	struct hdac_bus *bus = ebus_to_hbus(ebus);
	struct skl_sst *ctx =  skl->skl_sst;

	/* disable  ppcap interrupt */
	snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);

	skl_sst_dsp_cleanup(bus->dev, ctx);
	if (ctx->dsp->addr.lpe)
		iounmap(ctx->dsp->addr.lpe);
}

int skl_suspend_dsp(struct skl *skl)
{
	struct skl_sst *ctx = skl->skl_sst;
	int ret;

	/* if ppcap is not supported return 0 */
	if (!skl->ebus.ppcap)
		return 0;

	ret = skl_dsp_sleep(ctx->dsp);
	if (ret < 0)
		return ret;

	/* disable ppcap interrupt */
	snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, false);
	snd_hdac_ext_bus_ppcap_enable(&skl->ebus, false);

	return 0;
}

int skl_resume_dsp(struct skl *skl)
{
	struct skl_sst *ctx = skl->skl_sst;

	/* if ppcap is not supported return 0 */
	if (!skl->ebus.ppcap)
		return 0;

	/* enable ppcap interrupt */
	snd_hdac_ext_bus_ppcap_enable(&skl->ebus, true);
	snd_hdac_ext_bus_ppcap_int_enable(&skl->ebus, true);

	return skl_dsp_wake(ctx->dsp);
}
+6 −0
Original line number Original line Diff line number Diff line
@@ -56,6 +56,7 @@ struct skl {
	struct platform_device *dmic_dev;
	struct platform_device *dmic_dev;


	void __iomem *nhlt; /* nhlt ptr */
	void __iomem *nhlt; /* nhlt ptr */
	struct skl_sst *skl_sst; /* sst skl ctx */
};
};


#define skl_to_ebus(s)	(&(s)->ebus)
#define skl_to_ebus(s)	(&(s)->ebus)
@@ -75,4 +76,9 @@ void __iomem *skl_nhlt_init(struct device *dev);
void skl_nhlt_free(void __iomem *addr);
void skl_nhlt_free(void __iomem *addr);
struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
struct nhlt_specific_cfg *skl_get_ep_blob(struct skl *skl, u32 instance,
			u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn);
			u8 link_type, u8 s_fmt, u8 no_ch, u32 s_rate, u8 dirn);

int skl_init_dsp(struct skl *skl);
void skl_free_dsp(struct skl *skl);
int skl_suspend_dsp(struct skl *skl);
int skl_resume_dsp(struct skl *skl);
#endif /* __SOUND_SOC_SKL_H */
#endif /* __SOUND_SOC_SKL_H */