new file mode 100644
@@ -0,0 +1,169 @@
+/*
+ * Intel SST DSP Support
+ *
+ * Copyright (C) 2014-15, Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License 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.
+ *
+ */
+
+#ifndef __HDA_SST_DSP_H__
+#define __HDA_SST_DSP_H__
+
+#include <linux/spinlock.h>
+#include <sound/memalloc.h>
+
+#define ssth_writel_andor(ctx, reg, mask_and, mask_or) \
+ ssth_writel_traced( \
+ ctx, \
+ reg, \
+ (ssth_readl_traced(ctx, (reg)) & (mask_and) | (mask_or)))
+
+#define ssth_readb(ctx, reg) \
+ ssth_readb_traced(ctx, HDA_ADSP_REG_##reg)
+#define ssth_readw(ctx, reg) \
+ ssth_readw_traced(ctx, HDA_ADSP_REG_##reg)
+#define ssth_readl(ctx, reg) \
+ ssth_readl_traced(ctx, HDA_ADSP_REG_##reg)
+#define ssth_readl_alt(ctx, reg) \
+ ssth_readl_traced(ctx, reg)
+
+#define ssth_writeb(ctx, reg, value) \
+ ssth_writeb_traced(ctx, HDA_ADSP_REG_##reg, (value))
+#define ssth_writew(ctx, reg, value) \
+ ssth_writew_traced(ctx, HDA_ADSP_REG_##reg, (value))
+#define ssth_writel(ctx, reg, value) \
+ ssth_writel_traced(ctx, HDA_ADSP_REG_##reg, (value))
+
+#define ssth_updatel(ctx, reg, mask, value) \
+ ssth_updatel_bits(ctx, HDA_ADSP_REG_##reg, reg##_##mask, (value))
+
+#define ssth_updatel_locked(ctx, reg, mask, value) \
+ ssth_updatel_bits_locked(ctx, HDA_ADSP_REG_##reg, \
+ reg##_##mask, (value))
+
+/* Intel HD Audio General DSP Registers */
+#define HDA_ADSP_GEN_BASE 0x0
+#define HDA_ADSP_REG_ADSPCS (HDA_ADSP_GEN_BASE + 0x04)
+#define HDA_ADSP_REG_ADSPIC (HDA_ADSP_GEN_BASE + 0x08)
+#define HDA_ADSP_REG_ADSPIS (HDA_ADSP_GEN_BASE + 0x0C)
+#define HDA_ADSP_REG_ADSPIC2 (HDA_ADSP_GEN_BASE + 0x10)
+#define HDA_ADSP_REG_ADSPIS2 (HDA_ADSP_GEN_BASE + 0x14)
+
+/* Intel HD Audio Inter-Processor Communication Registers */
+#define HDA_ADSP_IPC_BASE 0x40
+#define HDA_ADSP_REG_HIPCT (HDA_ADSP_IPC_BASE + 0x00)
+#define HDA_ADSP_REG_HIPCTE (HDA_ADSP_IPC_BASE + 0x04)
+#define HDA_ADSP_REG_HIPCI (HDA_ADSP_IPC_BASE + 0x08)
+#define HDA_ADSP_REG_HIPCIE (HDA_ADSP_IPC_BASE + 0x0C)
+#define HDA_ADSP_REG_HIPCCTL (HDA_ADSP_IPC_BASE + 0x10)
+
+/* HIPCI */
+#define HDA_ADSP_REG_HIPCI_BUSY BIT(31)
+
+/* HIPCIE */
+#define HDA_ADSP_REG_HIPCIE_DONE BIT(30)
+
+/* HIPCCTL */
+#define HDA_ADSP_REG_HIPCCTL_DONE BIT(1)
+#define HDA_ADSP_REG_HIPCCTL_BUSY BIT(0)
+
+/* HIPCT */
+#define HDA_ADSP_REG_HIPCT_BUSY BIT(31)
+
+/* Intel HD Audio Code Loader DMA Registers */
+#define HDA_ADSP_LOADER_BASE 0x80
+
+/* Intel HD Audio SRAM Window 1 */
+#define HDA_ADSP_SRAM1_BASE 0xA000
+
+/* Intel HD Audio SRAM Window 2 */
+#define HDA_ADSP_SRAM2_BASE 0xC000
+
+/* Intel HD Audio SRAM Window 3 */
+#define HDA_ADSP_SRAM3_BASE 0xE000
+
+#define HDA_ADSP_MMIO_LEN 0x10000
+
+#define WINDOW0_STAT_SIZE 0x800
+
+#define WINDOW0_UP_SIZE 0x800
+
+#define WINDOW1_SIZE 0x1000
+
+#define ADSPIC_IPC 1
+#define ADSPIS_IPC 1
+
+struct ssth_window {
+ void __iomem *w0stat;
+ void __iomem *w0up;
+ void __iomem *w1;
+ size_t w0stat_size;
+ size_t w0up_size;
+ size_t w1_size;
+};
+
+struct ssth_lib {
+ struct device *dev;
+ void __iomem *mmio_base;
+ struct ssth_window window;
+ int irq;
+ struct snd_dma_buffer dsp_fw_buf;
+ int sst_state;
+ struct mutex sst_lock;
+ spinlock_t reg_lock;
+ const struct firmware *fw;
+};
+
+enum ssth_states {
+ SST_DSP_RUNNING = 1,
+ SST_DSP_RESET
+};
+
+static inline void
+ssth_dsp_set_state_locked(struct ssth_lib *ctx, int state)
+{
+ mutex_lock(&ctx->sst_lock);
+ ctx->sst_state = state;
+ mutex_unlock(&ctx->sst_lock);
+}
+
+void ssth_updatel_bits(struct ssth_lib *ctx, u32 offset, u32 mask, u32 value);
+
+void ssth_mailbox_write(struct ssth_lib *ctx, void *message, size_t bytes);
+void ssth_mailbox_read(struct ssth_lib *ctx, void *message, size_t bytes);
+
+u8 ssth_readb_traced(
+ struct ssth_lib *ctx,
+ u32 offset);
+
+u16 ssth_readw_traced(
+ struct ssth_lib *ctx,
+ u32 offset);
+
+u32 ssth_readl_traced(
+ struct ssth_lib *ctx,
+ u32 offset);
+
+void ssth_writeb_traced(
+ struct ssth_lib *ctx,
+ u32 offset,
+ u8 val);
+
+void ssth_writew_traced(
+ struct ssth_lib *ctx,
+ u32 offset, u16 val);
+
+void ssth_writel_traced(
+ struct ssth_lib *ctx,
+ u32 offset,
+ u32 val);
+
+#endif /*__HDA_SST_DSP_H__*/
new file mode 100644
@@ -0,0 +1,139 @@
+/*
+ * soc_hda_sst-dsp.c - HDA DSP library generic function
+ *
+ * Copyright (C) 2014-15 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 published by
+ * the Free Software Foundation; version 2 of the License.
+ *
+ * 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/io.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/spinlock_types.h>
+#include <linux/mutex.h>
+#include <sound/core.h>
+#include <sound/pcm.h>
+#include <sound/memalloc.h>
+#include <sound/soc-hda-sst-dsp.h>
+#include <sound/soc-hda-sst-ipc.h>
+
+u8 ssth_readb_traced(struct ssth_lib *dsp, u32 offset)
+{
+ u8 val;
+
+ val = readb((dsp)->mmio_base + offset);
+ dev_dbg(dsp->dev, "readb offset=%#x val=%#x\n", offset, val);
+
+ return val;
+}
+
+u16 ssth_readw_traced(struct ssth_lib *dsp, u32 offset)
+{
+ u16 val;
+
+ val = readw((dsp)->mmio_base + offset);
+ dev_dbg(dsp->dev, "readw offset=%#x val=%#x\n", offset, val);
+ return val;
+}
+
+u32 ssth_readl_traced(struct ssth_lib *dsp, u32 offset)
+{
+ u32 val;
+
+ val = readl((dsp)->mmio_base + offset);
+ dev_dbg(dsp->dev, "readl offset=%#x val=%#x\n", offset, val);
+ return val;
+}
+
+void ssth_writeb_traced(struct ssth_lib *dsp, u32 offset, u8 val)
+{
+ writeb(val, (dsp)->mmio_base + offset);
+ dev_dbg(dsp->dev, "writeb offset=%#x val=%#x\n", offset, val);
+}
+
+void ssth_writew_traced(struct ssth_lib *dsp, u32 offset, u16 val)
+{
+ dev_dbg(dsp->dev, "writew offset=%#x val=%#x\n", offset, val);
+ writew(val, (dsp)->mmio_base + offset);
+}
+void ssth_writel_traced(struct ssth_lib *dsp, u32 offset, u32 val)
+{
+ dev_dbg(dsp->dev, "writel offset=%#x val=%#x\n", offset, val);
+ writel(val, (dsp)->mmio_base + offset);
+}
+
+void ssth_updatel_bits(
+ struct ssth_lib *ctx,
+ u32 offset, u32 mask, u32 value)
+{
+ u32 val;
+
+ val = (readl((ctx)->mmio_base + offset) & ~mask) | (value & mask);
+
+ writel(val, (ctx)->mmio_base + offset);
+
+ dev_dbg(ctx->dev, "update bits offset=%#x val=%#x\n", offset, val);
+}
+
+static void ssth_updatel_bits_locked(
+ struct ssth_lib *ctx,
+ u32 offset, u32 mask, u32 value)
+{
+ unsigned long flags;
+
+ spin_lock_irqsave(&ctx->reg_lock, flags);
+ ssth_updatel_bits(ctx, offset, mask, value);
+ spin_unlock_irqrestore(&ctx->reg_lock, flags);
+}
+
+static inline void _ssth_memcpy_toio_32(u32 __iomem *dest,
+ u32 *src, size_t bytes)
+{
+
+ /*
+ * __iowrite32_copy uses 32-bit count values so divide by 4 for
+ * right count in words
+ */
+ __iowrite32_copy(dest, src, bytes/4);
+}
+
+static inline void _ssth_memcpy_fromio_32(u32 *dest,
+ __iomem u32 *src, size_t bytes)
+{
+
+ /*
+ * __iowrite32_copy uses 32-bit count values so divide by 4 for
+ * right count in words
+ */
+ __iowrite32_copy(dest, src, bytes/4);
+}
+
+void ssth_mailbox_write(struct ssth_lib *ctx, void *msg, size_t bytes)
+{
+ _ssth_memcpy_toio_32(ctx->window.w1, msg, bytes);
+}
+
+void ssth_mailbox_read(struct ssth_lib *ctx, void *msg, size_t bytes)
+{
+ _ssth_memcpy_fromio_32(msg, ctx->window.w0up, bytes);
+}
+
+MODULE_DESCRIPTION("HDA SST/IPC Library");
+MODULE_LICENSE("GPL v2");