Commit 43499134 authored by Mark Brown's avatar Mark Brown

Merge series "ASoC: Intel: Remove obsolete solutions and components" from...

Merge series "ASoC: Intel: Remove obsolete solutions and components" from Cezary Rojewski <cezary.rojewski@intel.com>:

Follow up to catpt series as mentioned in:
[PATCH v10 00/14] ASoC: Intel: Catpt - Lynx and Wildcat point
https://www.spinics.net/lists/alsa-devel/msg116440.html

As catpt is a direct replacement to sound/soc/intel/haswell, it leaves a
lot of code redudant. The second legacy solution - baytrail - is
deprecated for a long time by sound/soc/intel/atom with SOF flavor
available too.

This series addresses the redudancy and removes obsolete code. Along
with the legacy solutions, all orphaned components are removed too.

As a consequence, further cleanups are unlocked: sound/soc/intel/skylake
becomes the sole user of processing code found in
sound/soc/intel/common. Those are not part of this series.

Changes in v2:
- just a rebase so patch 04/13 applies cleanly
- left the tags as no actual changes done in between

Cezary Rojewski (13):
  ASoC: Intel: Remove haswell solution
  ASoC: Intel: Remove max98090 support for baytrail solution
  ASoC: Intel: Remove rt5640 support for baytrail solution
  ASoC: Intel: Remove baytrail solution
  ASoC: Intel: Remove SST ACPI component
  ASoC: Intel: Remove SST firmware components
  ASoC: Intel: Skylake: Unassign ram_read and read_write ops
  ASoC: Intel: Remove unused DSP operations
  ASoC: Intel: Remove unused DSP interface fields
  ASoC: Intel: Remove SST-legacy specific constants
  ASoC: Intel: Make atom components independent of sst-dsp
  ASoC: Intel: Remove sst_pdata structure
  ASoC: Intel: Remove sst_dsp_get_thread_context

 include/sound/soc-acpi-intel-match.h          |    1 -
 include/trace/events/hswadsp.h                |  385 ---
 sound/soc/intel/Kconfig                       |   26 -
 sound/soc/intel/Makefile                      |    1 -
 sound/soc/intel/atom/sst/sst.c                |    1 -
 sound/soc/intel/atom/sst/sst.h                |    7 +
 sound/soc/intel/atom/sst/sst_acpi.c           |    1 -
 sound/soc/intel/atom/sst/sst_drv_interface.c  |    3 -
 sound/soc/intel/atom/sst/sst_ipc.c            |    1 -
 sound/soc/intel/atom/sst/sst_loader.c         |    1 -
 sound/soc/intel/atom/sst/sst_pvt.c            |    1 -
 sound/soc/intel/atom/sst/sst_stream.c         |    1 -
 sound/soc/intel/baytrail/Makefile             |    5 -
 sound/soc/intel/baytrail/sst-baytrail-dsp.c   |  358 ---
 sound/soc/intel/baytrail/sst-baytrail-ipc.c   |  772 ------
 sound/soc/intel/baytrail/sst-baytrail-ipc.h   |   64 -
 sound/soc/intel/baytrail/sst-baytrail-pcm.c   |  459 ----
 sound/soc/intel/boards/Kconfig                |   25 -
 sound/soc/intel/boards/Makefile               |    4 -
 sound/soc/intel/boards/byt-max98090.c         |  182 --
 sound/soc/intel/boards/byt-rt5640.c           |  224 --
 sound/soc/intel/boards/bytcht_es8316.c        |    1 -
 sound/soc/intel/boards/bytcr_rt5640.c         |    1 -
 sound/soc/intel/common/Makefile               |    4 -
 .../intel/common/soc-acpi-intel-byt-match.c   |   15 -
 sound/soc/intel/common/sst-acpi.c             |  236 --
 sound/soc/intel/common/sst-dsp-priv.h         |  284 +--
 sound/soc/intel/common/sst-dsp.c              |  162 --
 sound/soc/intel/common/sst-dsp.h              |  222 --
 sound/soc/intel/common/sst-firmware.c         | 1273 ----------
 sound/soc/intel/common/sst-ipc.c              |   27 -
 sound/soc/intel/common/sst-ipc.h              |    3 -
 sound/soc/intel/haswell/Makefile              |    5 -
 sound/soc/intel/haswell/sst-haswell-dsp.c     |  705 ------
 sound/soc/intel/haswell/sst-haswell-ipc.c     | 2222 -----------------
 sound/soc/intel/haswell/sst-haswell-ipc.h     |  527 ----
 sound/soc/intel/haswell/sst-haswell-pcm.c     | 1369 ----------
 sound/soc/intel/skylake/bxt-sst.c             |    2 -
 sound/soc/intel/skylake/cnl-sst.c             |    4 +-
 sound/soc/intel/skylake/skl-sst-dsp.c         |    2 +-
 sound/soc/intel/skylake/skl-sst-ipc.c         |    2 +-
 sound/soc/intel/skylake/skl-sst.c             |    2 -
 42 files changed, 11 insertions(+), 9579 deletions(-)
 delete mode 100644 include/trace/events/hswadsp.h
 delete mode 100644 sound/soc/intel/baytrail/Makefile
 delete mode 100644 sound/soc/intel/baytrail/sst-baytrail-dsp.c
 delete mode 100644 sound/soc/intel/baytrail/sst-baytrail-ipc.c
 delete mode 100644 sound/soc/intel/baytrail/sst-baytrail-ipc.h
 delete mode 100644 sound/soc/intel/baytrail/sst-baytrail-pcm.c
 delete mode 100644 sound/soc/intel/boards/byt-max98090.c
 delete mode 100644 sound/soc/intel/boards/byt-rt5640.c
 delete mode 100644 sound/soc/intel/common/sst-acpi.c
 delete mode 100644 sound/soc/intel/common/sst-firmware.c
 delete mode 100644 sound/soc/intel/haswell/Makefile
 delete mode 100644 sound/soc/intel/haswell/sst-haswell-dsp.c
 delete mode 100644 sound/soc/intel/haswell/sst-haswell-ipc.c
 delete mode 100644 sound/soc/intel/haswell/sst-haswell-ipc.h
 delete mode 100644 sound/soc/intel/haswell/sst-haswell-pcm.c

--
2.17.1
parents cd7dea5e eb062e47
......@@ -16,7 +16,6 @@
*/
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_haswell_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_broadwell_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_cherrytrail_machines[];
extern struct snd_soc_acpi_mach snd_soc_acpi_intel_skl_machines[];
......
/* SPDX-License-Identifier: GPL-2.0 */
#undef TRACE_SYSTEM
#define TRACE_SYSTEM hswadsp
#if !defined(_TRACE_HSWADSP_H) || defined(TRACE_HEADER_MULTI_READ)
#define _TRACE_HSWADSP_H
#include <linux/types.h>
#include <linux/ktime.h>
#include <linux/tracepoint.h>
struct sst_hsw;
struct sst_hsw_stream;
struct sst_hsw_ipc_stream_free_req;
struct sst_hsw_ipc_volume_req;
struct sst_hsw_ipc_stream_alloc_req;
struct sst_hsw_audio_data_format_ipc;
struct sst_hsw_ipc_stream_info_reply;
struct sst_hsw_ipc_device_config_req;
DECLARE_EVENT_CLASS(sst_irq,
TP_PROTO(uint32_t status, uint32_t mask),
TP_ARGS(status, mask),
TP_STRUCT__entry(
__field( unsigned int, status )
__field( unsigned int, mask )
),
TP_fast_assign(
__entry->status = status;
__entry->mask = mask;
),
TP_printk("status 0x%8.8x mask 0x%8.8x",
(unsigned int)__entry->status, (unsigned int)__entry->mask)
);
DEFINE_EVENT(sst_irq, sst_irq_busy,
TP_PROTO(unsigned int status, unsigned int mask),
TP_ARGS(status, mask)
);
DEFINE_EVENT(sst_irq, sst_irq_done,
TP_PROTO(unsigned int status, unsigned int mask),
TP_ARGS(status, mask)
);
DECLARE_EVENT_CLASS(ipc,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val),
TP_STRUCT__entry(
__string( name, name )
__field( unsigned int, val )
),
TP_fast_assign(
__assign_str(name, name);
__entry->val = val;
),
TP_printk("%s 0x%8.8x", __get_str(name), (unsigned int)__entry->val)
);
DEFINE_EVENT(ipc, ipc_request,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DEFINE_EVENT(ipc, ipc_reply,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DEFINE_EVENT(ipc, ipc_pending_reply,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DEFINE_EVENT(ipc, ipc_notification,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DEFINE_EVENT(ipc, ipc_error,
TP_PROTO(const char *name, int val),
TP_ARGS(name, val)
);
DECLARE_EVENT_CLASS(stream_position,
TP_PROTO(unsigned int id, unsigned int pos),
TP_ARGS(id, pos),
TP_STRUCT__entry(
__field( unsigned int, id )
__field( unsigned int, pos )
),
TP_fast_assign(
__entry->id = id;
__entry->pos = pos;
),
TP_printk("id %d position 0x%x",
(unsigned int)__entry->id, (unsigned int)__entry->pos)
);
DEFINE_EVENT(stream_position, stream_read_position,
TP_PROTO(unsigned int id, unsigned int pos),
TP_ARGS(id, pos)
);
DEFINE_EVENT(stream_position, stream_write_position,
TP_PROTO(unsigned int id, unsigned int pos),
TP_ARGS(id, pos)
);
TRACE_EVENT(hsw_stream_buffer,
TP_PROTO(struct sst_hsw_stream *stream),
TP_ARGS(stream),
TP_STRUCT__entry(
__field( int, id )
__field( int, pt_addr )
__field( int, num_pages )
__field( int, ring_size )
__field( int, ring_offset )
__field( int, first_pfn )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->pt_addr = stream->request.ringinfo.ring_pt_address;
__entry->num_pages = stream->request.ringinfo.num_pages;
__entry->ring_size = stream->request.ringinfo.ring_size;
__entry->ring_offset = stream->request.ringinfo.ring_offset;
__entry->first_pfn = stream->request.ringinfo.ring_first_pfn;
),
TP_printk("stream %d ring addr 0x%x pages %d size 0x%x offset 0x%x PFN 0x%x",
(int) __entry->id, (int)__entry->pt_addr,
(int)__entry->num_pages, (int)__entry->ring_size,
(int)__entry->ring_offset, (int)__entry->first_pfn)
);
TRACE_EVENT(hsw_stream_alloc_reply,
TP_PROTO(struct sst_hsw_stream *stream),
TP_ARGS(stream),
TP_STRUCT__entry(
__field( int, id )
__field( int, stream_id )
__field( int, mixer_id )
__field( int, peak0 )
__field( int, peak1 )
__field( int, vol0 )
__field( int, vol1 )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->stream_id = stream->reply.stream_hw_id;
__entry->mixer_id = stream->reply.mixer_hw_id;
__entry->peak0 = stream->reply.peak_meter_register_address[0];
__entry->peak1 = stream->reply.peak_meter_register_address[1];
__entry->vol0 = stream->reply.volume_register_address[0];
__entry->vol1 = stream->reply.volume_register_address[1];
),
TP_printk("stream %d hw id %d mixer %d peak 0x%x:0x%x vol 0x%x,0x%x",
(int) __entry->id, (int) __entry->stream_id, (int)__entry->mixer_id,
(int)__entry->peak0, (int)__entry->peak1,
(int)__entry->vol0, (int)__entry->vol1)
);
TRACE_EVENT(hsw_mixer_info_reply,
TP_PROTO(struct sst_hsw_ipc_stream_info_reply *reply),
TP_ARGS(reply),
TP_STRUCT__entry(
__field( int, mixer_id )
__field( int, peak0 )
__field( int, peak1 )
__field( int, vol0 )
__field( int, vol1 )
),
TP_fast_assign(
__entry->mixer_id = reply->mixer_hw_id;
__entry->peak0 = reply->peak_meter_register_address[0];
__entry->peak1 = reply->peak_meter_register_address[1];
__entry->vol0 = reply->volume_register_address[0];
__entry->vol1 = reply->volume_register_address[1];
),
TP_printk("mixer id %d peak 0x%x:0x%x vol 0x%x,0x%x",
(int)__entry->mixer_id,
(int)__entry->peak0, (int)__entry->peak1,
(int)__entry->vol0, (int)__entry->vol1)
);
TRACE_EVENT(hsw_stream_data_format,
TP_PROTO(struct sst_hsw_stream *stream,
struct sst_hsw_audio_data_format_ipc *req),
TP_ARGS(stream, req),
TP_STRUCT__entry(
__field( uint32_t, id )
__field( uint32_t, frequency )
__field( uint32_t, bitdepth )
__field( uint32_t, map )
__field( uint32_t, config )
__field( uint32_t, style )
__field( uint8_t, ch_num )
__field( uint8_t, valid_bit )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->frequency = req->frequency;
__entry->bitdepth = req->bitdepth;
__entry->map = req->map;
__entry->config = req->config;
__entry->style = req->style;
__entry->ch_num = req->ch_num;
__entry->valid_bit = req->valid_bit;
),
TP_printk("stream %d freq %d depth %d map 0x%x config 0x%x style 0x%x ch %d bits %d",
(int) __entry->id, (uint32_t)__entry->frequency,
(uint32_t)__entry->bitdepth, (uint32_t)__entry->map,
(uint32_t)__entry->config, (uint32_t)__entry->style,
(uint8_t)__entry->ch_num, (uint8_t)__entry->valid_bit)
);
TRACE_EVENT(hsw_stream_alloc_request,
TP_PROTO(struct sst_hsw_stream *stream,
struct sst_hsw_ipc_stream_alloc_req *req),
TP_ARGS(stream, req),
TP_STRUCT__entry(
__field( uint32_t, id )
__field( uint8_t, path_id )
__field( uint8_t, stream_type )
__field( uint8_t, format_id )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->path_id = req->path_id;
__entry->stream_type = req->stream_type;
__entry->format_id = req->format_id;
),
TP_printk("stream %d path %d type %d format %d",
(int) __entry->id, (uint8_t)__entry->path_id,
(uint8_t)__entry->stream_type, (uint8_t)__entry->format_id)
);
TRACE_EVENT(hsw_stream_free_req,
TP_PROTO(struct sst_hsw_stream *stream,
struct sst_hsw_ipc_stream_free_req *req),
TP_ARGS(stream, req),
TP_STRUCT__entry(
__field( int, id )
__field( int, stream_id )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->stream_id = req->stream_id;
),
TP_printk("stream %d hw id %d",
(int) __entry->id, (int) __entry->stream_id)
);
TRACE_EVENT(hsw_volume_req,
TP_PROTO(struct sst_hsw_stream *stream,
struct sst_hsw_ipc_volume_req *req),
TP_ARGS(stream, req),
TP_STRUCT__entry(
__field( int, id )
__field( uint32_t, channel )
__field( uint32_t, target_volume )
__field( uint64_t, curve_duration )
__field( uint32_t, curve_type )
),
TP_fast_assign(
__entry->id = stream->host_id;
__entry->channel = req->channel;
__entry->target_volume = req->target_volume;
__entry->curve_duration = req->curve_duration;
__entry->curve_type = req->curve_type;
),
TP_printk("stream %d chan 0x%x vol %d duration %llu type %d",
(int) __entry->id, (uint32_t) __entry->channel,
(uint32_t)__entry->target_volume,
(uint64_t)__entry->curve_duration,
(uint32_t)__entry->curve_type)
);
TRACE_EVENT(hsw_device_config_req,
TP_PROTO(struct sst_hsw_ipc_device_config_req *req),
TP_ARGS(req),
TP_STRUCT__entry(
__field( uint32_t, ssp )
__field( uint32_t, clock_freq )
__field( uint32_t, mode )
__field( uint16_t, clock_divider )
),
TP_fast_assign(
__entry->ssp = req->ssp_interface;
__entry->clock_freq = req->clock_frequency;
__entry->mode = req->mode;
__entry->clock_divider = req->clock_divider;
),
TP_printk("SSP %d Freq %d mode %d div %d",
(uint32_t)__entry->ssp,
(uint32_t)__entry->clock_freq, (uint32_t)__entry->mode,
(uint32_t)__entry->clock_divider)
);
#endif /* _TRACE_HSWADSP_H */
/* This part must be outside protection */
#include <trace/define_trace.h>
......@@ -31,22 +31,9 @@ config SND_SST_IPC_ACPI
# This option controls the ACPI-based IPC for HiFi2 platforms
# (Baytrail, Cherrytrail)
config SND_SOC_INTEL_SST_ACPI
tristate
# This option controls ACPI-based probing on
# Haswell/Broadwell/Baytrail legacy and will be set
# when these platforms are enabled
config SND_SOC_INTEL_SST
tristate
config SND_SOC_INTEL_SST_FIRMWARE
tristate
select DW_DMAC_CORE
# This option controls firmware download on
# Haswell/Broadwell/Baytrail legacy and will be set
# when these platforms are enabled
config SND_SOC_INTEL_CATPT
tristate "Haswell and Broadwell"
depends on ACPI || COMPILE_TEST
......@@ -63,19 +50,6 @@ config SND_SOC_INTEL_HASWELL
tristate
select SND_SOC_INTEL_CATPT
config SND_SOC_INTEL_BAYTRAIL
tristate "Baytrail (legacy) Platforms"
depends on DMADEVICES && ACPI && SND_SST_ATOM_HIFI2_PLATFORM=n && SND_SOC_SOF_BAYTRAIL=n
select SND_SOC_INTEL_SST
select SND_SOC_INTEL_SST_ACPI
select SND_SOC_INTEL_SST_FIRMWARE
select SND_SOC_ACPI_INTEL_MATCH
help
If you have a Intel Baytrail platform connected to an I2S codec,
then enable this option by saying Y or m. This was typically used
for Baytrail Chromebooks but this option is now deprecated and is
not recommended, use SND_SST_ATOM_HIFI2_PLATFORM instead.
config SND_SST_ATOM_HIFI2_PLATFORM
tristate
select SND_SOC_COMPRESS
......
......@@ -3,7 +3,6 @@
obj-$(CONFIG_SND_SOC) += common/
# Platform Support
obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += baytrail/
obj-$(CONFIG_SND_SST_ATOM_HIFI2_PLATFORM) += atom/
obj-$(CONFIG_SND_SOC_INTEL_CATPT) += catpt/
obj-$(CONFIG_SND_SOC_INTEL_SKYLAKE) += skylake/
......
......@@ -26,7 +26,6 @@
#include <asm/platform_sst_audio.h>
#include "../sst-mfld-platform.h"
#include "sst.h"
#include "../../common/sst-dsp.h"
MODULE_AUTHOR("Vinod Koul <vinod.koul@intel.com>");
MODULE_AUTHOR("Harsha Priya <priya.harsha@intel.com>");
......
......@@ -34,6 +34,13 @@
#define MRFLD_FW_FEATURE_BASE_OFFSET 0x4
#define MRFLD_FW_BSS_RESET_BIT 0
/* SST Shim register map */
#define SST_CSR 0x00
#define SST_ISRX 0x18
#define SST_IMRX 0x28
#define SST_IPCX 0x38 /* IPC IA -> SST */
#define SST_IPCD 0x40 /* IPC SST -> IA */
extern const struct dev_pm_ops intel_sst_pm;
enum sst_states {
SST_FW_LOADING = 1,
......
......@@ -31,7 +31,6 @@
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
#include "../sst-mfld-platform.h"
#include "../../common/sst-dsp.h"
#include "../../common/soc-intel-quirks.h"
#include "sst.h"
......
......@@ -24,9 +24,6 @@
#include <asm/platform_sst_audio.h>
#include "../sst-mfld-platform.h"
#include "sst.h"
#include "../../common/sst-dsp.h"
#define NUM_CODEC 2
#define MIN_FRAGMENT 2
......
......@@ -24,7 +24,6 @@
#include <asm/platform_sst_audio.h>
#include "../sst-mfld-platform.h"
#include "sst.h"
#include "../../common/sst-dsp.h"
struct sst_block *sst_create_block(struct intel_sst_drv *ctx,
u32 msg_id, u32 drv_id)
......
......@@ -29,7 +29,6 @@
#include <asm/platform_sst_audio.h>
#include "../sst-mfld-platform.h"
#include "sst.h"
#include "../../common/sst-dsp.h"
void memcpy32_toio(void __iomem *dst, const void *src, int count)
{
......
......@@ -26,7 +26,6 @@
#include <asm/platform_sst_audio.h>
#include "../sst-mfld-platform.h"
#include "sst.h"
#include "../../common/sst-dsp.h"
int sst_shim_write(void __iomem *addr, int offset, int value)
{
......
......@@ -23,7 +23,6 @@
#include <asm/platform_sst_audio.h>
#include "../sst-mfld-platform.h"
#include "sst.h"
#include "../../common/sst-dsp.h"
int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params)
{
......
# SPDX-License-Identifier: GPL-2.0-only
snd-soc-sst-baytrail-pcm-objs := \
sst-baytrail-ipc.o sst-baytrail-pcm.o sst-baytrail-dsp.o
obj-$(CONFIG_SND_SOC_INTEL_BAYTRAIL) += snd-soc-sst-baytrail-pcm.o
// SPDX-License-Identifier: GPL-2.0-only
/*
* Intel Baytrail SST DSP driver
* Copyright (c) 2014, Intel Corporation.
*/
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/slab.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
#include <linux/firmware.h>
#include "../common/sst-dsp.h"
#include "../common/sst-dsp-priv.h"
#include "sst-baytrail-ipc.h"
#define SST_BYT_FW_SIGNATURE_SIZE 4
#define SST_BYT_FW_SIGN "$SST"
#define SST_BYT_IRAM_OFFSET 0xC0000
#define SST_BYT_DRAM_OFFSET 0x100000
#define SST_BYT_SHIM_OFFSET 0x140000
enum sst_ram_type {
SST_BYT_IRAM = 1,
SST_BYT_DRAM = 2,
SST_BYT_CACHE = 3,
};
struct dma_block_info {
enum sst_ram_type type; /* IRAM/DRAM */
u32 size; /* Bytes */
u32 ram_offset; /* Offset in I/DRAM */
u32 rsvd; /* Reserved field */
};
struct fw_header {
unsigned char signature[SST_BYT_FW_SIGNATURE_SIZE];
u32 file_size; /* size of fw minus this header */
u32 modules; /* # of modules */
u32 file_format; /* version of header format */
u32 reserved[4];
};
struct sst_byt_fw_module_header {
unsigned char signature[SST_BYT_FW_SIGNATURE_SIZE];
u32 mod_size; /* size of module */
u32 blocks; /* # of blocks */
u32 type; /* codec type, pp lib */
u32 entry_point;
};
static int sst_byt_parse_module(struct sst_dsp *dsp, struct sst_fw *fw,
struct sst_byt_fw_module_header *module)
{
struct dma_block_info *block;
struct sst_module *mod;
struct sst_module_template template;
int count;
memset(&template, 0, sizeof(template));
template.id = module->type;
template.entry = module->entry_point;
mod = sst_module_new(fw, &template, NULL);
if (mod == NULL)
return -ENOMEM;
block = (void *)module + sizeof(*module);
for (count = 0; count < module->blocks; count++) {
if (block->size <= 0) {
dev_err(dsp->dev, "block %d size invalid\n", count);
return -EINVAL;
}
switch (block->type) {
case SST_BYT_IRAM:
mod->offset = block->ram_offset +
dsp->addr.iram_offset;
mod->type = SST_MEM_IRAM;
break;
case SST_BYT_DRAM:
mod->offset = block->ram_offset +
dsp->addr.dram_offset;
mod->type = SST_MEM_DRAM;
break;
case SST_BYT_CACHE:
mod->offset = block->ram_offset +
(dsp->addr.fw_ext - dsp->addr.lpe);
mod->type = SST_MEM_CACHE;
break;
default:
dev_err(dsp->dev, "wrong ram type 0x%x in block0x%x\n",
block->type, count);
return -EINVAL;
}
mod->size = block->size;
mod->data = (void *)block + sizeof(*block);
sst_module_alloc_blocks(mod);
block = (void *)block + sizeof(*block) + block->size;
}
return 0;
}
static int sst_byt_parse_fw_image(struct sst_fw *sst_fw)
{
struct fw_header *header;
struct sst_byt_fw_module_header *module;
struct sst_dsp *dsp = sst_fw->dsp;
int ret, count;
/* Read the header information from the data pointer */
header = (struct fw_header *)sst_fw->dma_buf;
/* verify FW */
if ((strncmp(header->signature, SST_BYT_FW_SIGN, 4) != 0) ||
(sst_fw->size != header->file_size + sizeof(*header))) {
/* Invalid FW signature */
dev_err(dsp->dev, "Invalid FW sign/filesize mismatch\n");
return -EINVAL;
}
dev_dbg(dsp->dev,
"header sign=%4s size=0x%x modules=0x%x fmt=0x%x size=%zu\n",
header->signature, header->file_size, header->modules,
header->file_format, sizeof(*header));
module = (void *)sst_fw->dma_buf + sizeof(*header);
for (count = 0; count < header->modules; count++) {
/* module */
ret = sst_byt_parse_module(dsp, sst_fw, module);
if (ret < 0) {
dev_err(dsp->dev, "invalid module %d\n", count);
return ret;
}
module = (void *)module + sizeof(*module) + module->mod_size;
}
return 0;
}
static void sst_byt_dump_shim(struct sst_dsp *sst)
{
int i;
u64 reg;
for (i = 0; i <= 0xF0; i += 8) {
reg = sst_dsp_shim_read64_unlocked(sst, i);
if (reg)
dev_dbg(sst->dev, "shim 0x%2.2x value 0x%16.16llx\n",
i, reg);
}
for (i = 0x00; i <= 0xff; i += 4) {
reg = readl(sst->addr.pci_cfg + i);
if (reg)
dev_dbg(sst->dev, "pci 0x%2.2x value 0x%8.8x\n",
i, (u32)reg);
}
}
static irqreturn_t sst_byt_irq(int irq, void *context)
{
struct sst_dsp *sst = (struct sst_dsp *) context;
u64 isrx;
irqreturn_t ret = IRQ_NONE;
spin_lock(&sst->spinlock);
isrx = sst_dsp_shim_read64_unlocked(sst, SST_ISRX);
if (isrx & SST_ISRX_DONE) {
/* ADSP has processed the message request from IA */
sst_dsp_shim_update_bits64_unlocked(sst, SST_IPCX,
SST_BYT_IPCX_DONE, 0);
ret = IRQ_WAKE_THREAD;
}
if (isrx & SST_BYT_ISRX_REQUEST) {
/* mask message request from ADSP and do processing later */
sst_dsp_shim_update_bits64_unlocked(sst, SST_IMRX,
SST_BYT_IMRX_REQUEST,
SST_BYT_IMRX_REQUEST);
ret = IRQ_WAKE_THREAD;
}
spin_unlock(&sst->spinlock);
return ret;
}
static void sst_byt_boot(struct sst_dsp *sst)
{
int tries = 10;
/*
* save the physical address of extended firmware block in the first
* 4 bytes of the mailbox
*/
memcpy_toio(sst->addr.lpe + SST_BYT_MAILBOX_OFFSET,
&sst->pdata->fw_base, sizeof(u32));
/* release stall and wait to unstall */
sst_dsp_shim_update_bits64(sst, SST_CSR, SST_BYT_CSR_STALL, 0x0);
while (tries--) {
if (!(sst_dsp_shim_read64(sst, SST_CSR) &
SST_BYT_CSR_PWAITMODE))
break;
msleep(100);
}
if (tries < 0) {
dev_err(sst->dev, "unable to start DSP\n");
sst_byt_dump_shim(sst);
}
}
static void sst_byt_reset(struct sst_dsp *sst)
{
/* put DSP into reset, set reset vector and stall */
sst_dsp_shim_update_bits64(sst, SST_CSR,
SST_BYT_CSR_RST | SST_BYT_CSR_VECTOR_SEL | SST_BYT_CSR_STALL,
SST_BYT_CSR_RST | SST_BYT_CSR_VECTOR_SEL | SST_BYT_CSR_STALL);
udelay(10);
/* take DSP out of reset and keep stalled for FW loading */
sst_dsp_shim_update_bits64(sst, SST_CSR, SST_BYT_CSR_RST, 0);
}
struct sst_adsp_memregion {
u32 start;
u32 end;
int blocks;
enum sst_mem_type type;
};
/* BYT test stuff */
static const struct sst_adsp_memregion byt_region[] = {
{0xC0000, 0x100000, 8, SST_MEM_IRAM}, /* I-SRAM - 8 * 32kB */
{0x100000, 0x140000, 8, SST_MEM_DRAM}, /* D-SRAM0 - 8 * 32kB */
};
static int sst_byt_resource_map(struct sst_dsp *sst, struct sst_pdata *pdata)
{
sst->addr.lpe_base = pdata->lpe_base;
sst->addr.lpe = ioremap(pdata->lpe_base, pdata->lpe_size);
if (!sst->addr.lpe)
return -ENODEV;
/* ADSP PCI MMIO config space */
sst->addr.pci_cfg = ioremap(pdata->pcicfg_base, pdata->pcicfg_size);
if (!sst->addr.pci_cfg) {
iounmap(sst->addr.lpe);
return -ENODEV;
}
/* SST Extended FW allocation */
sst->addr.fw_ext = ioremap(pdata->fw_base, pdata->fw_size);
if (!sst->addr.fw_ext) {
iounmap(sst->addr.pci_cfg);
iounmap(sst->addr.lpe);
return -ENODEV;
}
/* SST Shim */
sst->addr.shim = sst->addr.lpe + sst->addr.shim_offset;
sst_dsp_mailbox_init(sst, SST_BYT_MAILBOX_OFFSET + 0x204,
SST_BYT_IPC_MAX_PAYLOAD_SIZE,
SST_BYT_MAILBOX_OFFSET,
SST_BYT_IPC_MAX_PAYLOAD_SIZE);
sst->irq = pdata->irq;
return 0;
}
static int sst_byt_init(struct sst_dsp *sst, struct sst_pdata *pdata)
{
const struct sst_adsp_memregion *region;
struct device *dev;
int ret = -ENODEV, i, j, region_count;
u32 offset, size;
dev = sst->dev;
switch (sst->id) {
case SST_DEV_ID_BYT:
region = byt_region;
region_count = ARRAY_SIZE(byt_region);
sst->addr.iram_offset = SST_BYT_IRAM_OFFSET;
sst->addr.dram_offset = SST_BYT_DRAM_OFFSET;
sst->addr.shim_offset = SST_BYT_SHIM_OFFSET;
break;
default:
dev_err(dev, "failed to get mem resources\n");
return ret;
}
ret = sst_byt_resource_map(sst, pdata);
if (ret < 0) {
dev_err(dev, "failed to map resources\n");
return ret;
}
ret = dma_coerce_mask_and_coherent(sst->dma_dev, DMA_BIT_MASK(32));
if (ret)
return ret;
/* enable Interrupt from both sides */
sst_dsp_shim_update_bits64(sst, SST_IMRX, 0x3, 0x0);
sst_dsp_shim_update_bits64(sst, SST_IMRD, 0x3, 0x0);
/* register DSP memory blocks - ideally we should get this from ACPI */
for (i = 0; i < region_count; i++) {
offset = region[i].start;
size = (region[i].end - region[i].start) / region[i].blocks;
/* register individual memory blocks */
for (j = 0; j < region[i].blocks; j++) {
sst_mem_block_register(sst, offset, size,
region[i].type, NULL, j, sst);
offset += size;
}
}
return 0;
}
static void sst_byt_free(struct sst_dsp *sst)
{
sst_mem_block_unregister_all(sst);
iounmap(sst->addr.lpe);
iounmap(sst->addr.pci_cfg);
iounmap(sst->addr.fw_ext);
}
struct sst_ops sst_byt_ops = {
.reset = sst_byt_reset,
.boot = sst_byt_boot,
.write = sst_shim32_write,
.read = sst_shim32_read,
.write64 = sst_shim32_write64,
.read64 = sst_shim32_read64,
.ram_read = sst_memcpy_fromio_32,
.ram_write = sst_memcpy_toio_32,
.irq_handler = sst_byt_irq,
.init = sst_byt_init,
.free = sst_byt_free,
.parse_fw = sst_byt_parse_fw_image,
};
This diff is collapsed.
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Intel Baytrail SST IPC Support
* Copyright (c) 2014, Intel Corporation.
*/
#ifndef __SST_BYT_IPC_H
#define __SST_BYT_IPC_H
#include <linux/types.h>
struct sst_byt;
struct sst_byt_stream;
struct sst_pdata;
extern struct sst_ops sst_byt_ops;
#define SST_BYT_MAILBOX_OFFSET 0x144000
#define SST_BYT_TIMESTAMP_OFFSET (SST_BYT_MAILBOX_OFFSET + 0x800)
/**
* Upfront defined maximum message size that is
* expected by the in/out communication pipes in FW.
*/
#define SST_BYT_IPC_MAX_PAYLOAD_SIZE 200
/* stream API */
struct sst_byt_stream *sst_byt_stream_new(struct sst_byt *byt, int id,
uint32_t (*notify_position)(struct sst_byt_stream *stream, void *data),
void *data);
/* stream configuration */
int sst_byt_stream_set_bits(struct sst_byt *byt, struct sst_byt_stream *stream,
int bits);
int sst_byt_stream_set_channels(struct sst_byt *byt,
struct sst_byt_stream *stream, u8 channels);
int sst_byt_stream_set_rate(struct sst_byt *byt, struct sst_byt_stream *stream,
unsigned int rate);
int sst_byt_stream_type(struct sst_byt *byt, struct sst_byt_stream *stream,
int codec_type, int stream_type, int operation);
int sst_byt_stream_buffer(struct sst_byt *byt, struct sst_byt_stream *stream,
uint32_t buffer_addr, uint32_t buffer_size);
int sst_byt_stream_commit(struct sst_byt *byt, struct sst_byt_stream *stream);
int sst_byt_stream_free(struct sst_byt *byt, struct sst_byt_stream *stream);
/* stream ALSA trigger operations */
int sst_byt_stream_start(struct sst_byt *byt, struct sst_byt_stream *stream,
u32 start_offset);
int sst_byt_stream_stop(struct sst_byt *byt, struct sst_byt_stream *stream);
int sst_byt_stream_pause(struct sst_byt *byt, struct sst_byt_stream *stream);
int sst_byt_stream_resume(struct sst_byt *byt, struct sst_byt_stream *stream);
int sst_byt_get_dsp_position(struct sst_byt *byt,
struct sst_byt_stream *stream, int buffer_size);
/* init */
int sst_byt_dsp_init(struct device *dev, struct sst_pdata *pdata);
void sst_byt_dsp_free(struct device *dev, struct sst_pdata *pdata);
struct sst_dsp *sst_byt_get_dsp(struct sst_byt *byt);
int sst_byt_dsp_suspend_late(struct device *dev, struct sst_pdata *pdata);
int sst_byt_dsp_boot(struct device *dev, struct sst_pdata *pdata);
int sst_byt_dsp_wait_for_ready(struct device *dev, struct sst_pdata *pdata);
#endif
This diff is collapsed.
......@@ -85,31 +85,6 @@ config SND_SOC_INTEL_BROADWELL_MACH
If unsure select "N".
endif ## SND_SOC_INTEL_CATPT || SND_SOC_SOF_BROADWELL
if SND_SOC_INTEL_BAYTRAIL
config SND_SOC_INTEL_BYT_MAX98090_MACH
tristate "Baytrail with MAX98090 codec"
depends on I2C
depends on X86_INTEL_LPSS || COMPILE_TEST
select SND_SOC_MAX98090
help
This adds audio driver for Intel Baytrail platform based boards
with the MAX98090 audio codec. This driver is deprecated, use
SND_SOC_INTEL_CHT_BSW_MAX98090_TI_MACH instead for better
functionality.
config SND_SOC_INTEL_BYT_RT5640_MACH
tristate "Baytrail with RT5640 codec"
depends on I2C
depends on X86_INTEL_LPSS || COMPILE_TEST
select SND_SOC_RT5640
help
This adds audio driver for Intel Baytrail platform based boards
with the RT5640 audio codec. This driver is deprecated, use
SND_SOC_INTEL_BYTCR_RT5640_MACH instead for better functionality.
endif ## SND_SOC_INTEL_BAYTRAIL
if SND_SST_ATOM_HIFI2_PLATFORM || SND_SOC_SOF_BAYTRAIL
config SND_SOC_INTEL_BYTCR_RT5640_MACH
......
# SPDX-License-Identifier: GPL-2.0-only
snd-soc-sst-haswell-objs := haswell.o
snd-soc-sst-byt-rt5640-mach-objs := byt-rt5640.o
snd-soc-sst-byt-max98090-mach-objs := byt-max98090.o
snd-soc-sst-bdw-rt5650-mach-objs := bdw-rt5650.o
snd-soc-sst-bdw-rt5677-mach-objs := bdw-rt5677.o
snd-soc-sst-broadwell-objs := broadwell.o
......@@ -43,8 +41,6 @@ snd-soc-sof-sdw-objs += sof_sdw.o \
sof_sdw_dmic.o sof_sdw_hdmi.o hda_dsp_common.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_RT5682_MACH) += snd-soc-sof_rt5682.o
obj-$(CONFIG_SND_SOC_INTEL_HASWELL_MACH) += snd-soc-sst-haswell.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_RT5640_MACH) += snd-soc-sst-byt-rt5640-mach.o
obj-$(CONFIG_SND_SOC_INTEL_BYT_MAX98090_MACH) += snd-soc-sst-byt-max98090-mach.o
obj-$(CONFIG_SND_SOC_INTEL_BXT_DA7219_MAX98357A_COMMON) += snd-soc-sst-bxt-da7219_max98357a.o
obj-$(CONFIG_SND_SOC_INTEL_BXT_RT298_MACH) += snd-soc-sst-bxt-rt298.o
obj-$(CONFIG_SND_SOC_INTEL_SOF_PCM512x_MACH) += snd-soc-sst-sof-pcm512x.o
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Intel Baytrail SST MAX98090 machine driver
* Copyright (c) 2014, Intel Corporation.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include "../../codecs/max98090.h"
struct byt_max98090_private {
struct snd_soc_jack jack;
};
static const struct snd_soc_dapm_widget byt_max98090_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Int Mic", NULL),
SND_SOC_DAPM_SPK("Ext Spk", NULL),
};
static const struct snd_soc_dapm_route byt_max98090_audio_map[] = {
{"IN34", NULL, "Headset Mic"},
{"Headset Mic", NULL, "MICBIAS"},
{"DMICL", NULL, "Int Mic"},
{"Headphone", NULL, "HPL"},
{"Headphone", NULL, "HPR"},
{"Ext Spk", NULL, "SPKL"},
{"Ext Spk", NULL, "SPKR"},
};
static const struct snd_kcontrol_new byt_max98090_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
SOC_DAPM_PIN_SWITCH("Int Mic"),
SOC_DAPM_PIN_SWITCH("Ext Spk"),
};
static struct snd_soc_jack_pin hs_jack_pins[] = {
{
.pin = "Headphone",
.mask = SND_JACK_HEADPHONE,
},
{
.pin = "Headset Mic",
.mask = SND_JACK_MICROPHONE,
},
};
static struct snd_soc_jack_gpio hs_jack_gpios[] = {
{
.name = "hp",
.report = SND_JACK_HEADPHONE | SND_JACK_LINEOUT,
.debounce_time = 200,
},
{
.name = "mic",
.invert = 1,
.report = SND_JACK_MICROPHONE,
.debounce_time = 200,
},
};
static const struct acpi_gpio_params hp_gpios = { 0, 0, false };
static const struct acpi_gpio_params mic_gpios = { 1, 0, false };
static const struct acpi_gpio_mapping acpi_byt_max98090_gpios[] = {
{ "hp-gpios", &hp_gpios, 1 },
{ "mic-gpios", &mic_gpios, 1 },
{},
};
static int byt_max98090_init(struct snd_soc_pcm_runtime *runtime)
{
int ret;
struct snd_soc_card *card = runtime->card;
struct byt_max98090_private *drv = snd_soc_card_get_drvdata(card);
struct snd_soc_jack *jack = &drv->jack;
card->dapm.idle_bias_off = true;
ret = snd_soc_dai_set_sysclk(asoc_rtd_to_codec(runtime, 0),
M98090_REG_SYSTEM_CLOCK,
25000000, SND_SOC_CLOCK_IN);
if (ret < 0) {
dev_err(card->dev, "Can't set codec clock %d\n", ret);
return ret;
}
/* Enable jack detection */
ret = snd_soc_card_jack_new(runtime->card, "Headset",
SND_JACK_LINEOUT | SND_JACK_HEADSET, jack,
hs_jack_pins, ARRAY_SIZE(hs_jack_pins));
if (ret)
return ret;
return snd_soc_jack_add_gpiods(card->dev->parent, jack,
ARRAY_SIZE(hs_jack_gpios),
hs_jack_gpios);
}
SND_SOC_DAILINK_DEFS(baytrail,
DAILINK_COMP_ARRAY(COMP_CPU("baytrail-pcm-audio")),
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-193C9890:00", "HiFi")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("baytrail-pcm-audio")));
static struct snd_soc_dai_link byt_max98090_dais[] = {
{
.name = "Baytrail Audio",
.stream_name = "Audio",
.init = byt_max98090_init,
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
SND_SOC_DAILINK_REG(baytrail),
},
};
static struct snd_soc_card byt_max98090_card = {
.name = "byt-max98090",
.owner = THIS_MODULE,
.dai_link = byt_max98090_dais,
.num_links = ARRAY_SIZE(byt_max98090_dais),
.dapm_widgets = byt_max98090_widgets,
.num_dapm_widgets = ARRAY_SIZE(byt_max98090_widgets),
.dapm_routes = byt_max98090_audio_map,
.num_dapm_routes = ARRAY_SIZE(byt_max98090_audio_map),
.controls = byt_max98090_controls,
.num_controls = ARRAY_SIZE(byt_max98090_controls),
.fully_routed = true,
};
static int byt_max98090_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct byt_max98090_private *priv;
int ret_val;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv) {
dev_err(&pdev->dev, "allocation failed\n");
return -ENOMEM;
}
ret_val = devm_acpi_dev_add_driver_gpios(dev->parent, acpi_byt_max98090_gpios);
if (ret_val)
dev_dbg(dev, "Unable to add GPIO mapping table\n");
byt_max98090_card.dev = &pdev->dev;
snd_soc_card_set_drvdata(&byt_max98090_card, priv);
ret_val = devm_snd_soc_register_card(&pdev->dev, &byt_max98090_card);
if (ret_val) {
dev_err(&pdev->dev,
"snd_soc_register_card failed %d\n", ret_val);
return ret_val;
}
return 0;
}
static struct platform_driver byt_max98090_driver = {
.probe = byt_max98090_probe,
.driver = {
.name = "byt-max98090",
.pm = &snd_soc_pm_ops,
},
};
module_platform_driver(byt_max98090_driver)
MODULE_DESCRIPTION("ASoC Intel(R) Baytrail Machine driver");
MODULE_AUTHOR("Omair Md Abdullah, Jarkko Nikula");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:byt-max98090");
// SPDX-License-Identifier: GPL-2.0-only
/*
* Intel Baytrail SST RT5640 machine driver
* Copyright (c) 2014, Intel Corporation.
*/
#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/dmi.h>
#include <linux/slab.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/jack.h>
#include "../../codecs/rt5640.h"
#include "../common/sst-dsp.h"
static const struct snd_soc_dapm_widget byt_rt5640_widgets[] = {
SND_SOC_DAPM_HP("Headphone", NULL),
SND_SOC_DAPM_MIC("Headset Mic", NULL),
SND_SOC_DAPM_MIC("Internal Mic", NULL),
SND_SOC_DAPM_SPK("Speaker", NULL),
};
static const struct snd_soc_dapm_route byt_rt5640_audio_map[] = {
{"Headset Mic", NULL, "MICBIAS1"},
{"IN2P", NULL, "Headset Mic"},
{"Headphone", NULL, "HPOL"},
{"Headphone", NULL, "HPOR"},
{"Speaker", NULL, "SPOLP"},
{"Speaker", NULL, "SPOLN"},
{"Speaker", NULL, "SPORP"},
{"Speaker", NULL, "SPORN"},
};
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic1_map[] = {
{"DMIC1", NULL, "Internal Mic"},
};
static const struct snd_soc_dapm_route byt_rt5640_intmic_dmic2_map[] = {
{"DMIC2", NULL, "Internal Mic"},
};
static const struct snd_soc_dapm_route byt_rt5640_intmic_in1_map[] = {
{"Internal Mic", NULL, "MICBIAS1"},
{"IN1P", NULL, "Internal Mic"},
};
enum {
BYT_RT5640_DMIC1_MAP,
BYT_RT5640_DMIC2_MAP,
BYT_RT5640_IN1_MAP,
};
#define BYT_RT5640_MAP(quirk) ((quirk) & 0xff)
#define BYT_RT5640_DMIC_EN BIT(16)
static unsigned long byt_rt5640_quirk = BYT_RT5640_DMIC1_MAP |
BYT_RT5640_DMIC_EN;
static const struct snd_kcontrol_new byt_rt5640_controls[] = {
SOC_DAPM_PIN_SWITCH("Headphone"),
SOC_DAPM_PIN_SWITCH("Headset Mic"),
SOC_DAPM_PIN_SWITCH("Internal Mic"),
SOC_DAPM_PIN_SWITCH("Speaker"),
};
static int byt_rt5640_hw_params(struct snd_pcm_substream *substream,
struct snd_pcm_hw_params *params)
{
struct snd_soc_pcm_runtime *rtd = asoc_substream_to_rtd(substream);
struct snd_soc_dai *codec_dai = asoc_rtd_to_codec(rtd, 0);
int ret;
ret = snd_soc_dai_set_sysclk(codec_dai, RT5640_SCLK_S_PLL1,
params_rate(params) * 256,
SND_SOC_CLOCK_IN);
if (ret < 0) {
dev_err(codec_dai->dev, "can't set codec clock %d\n", ret);
return ret;
}
ret = snd_soc_dai_set_pll(codec_dai, 0, RT5640_PLL1_S_BCLK1,
params_rate(params) * 64,
params_rate(params) * 256);
if (ret < 0) {
dev_err(codec_dai->dev, "can't set codec pll: %d\n", ret);
return ret;
}
return 0;
}
static int byt_rt5640_quirk_cb(const struct dmi_system_id *id)
{
byt_rt5640_quirk = (unsigned long)id->driver_data;
return 1;
}
static const struct dmi_system_id byt_rt5640_quirk_table[] = {
{
.callback = byt_rt5640_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "ASUSTeK COMPUTER INC."),
DMI_MATCH(DMI_PRODUCT_NAME, "T100TA"),
},
.driver_data = (unsigned long *)BYT_RT5640_IN1_MAP,
},
{
.callback = byt_rt5640_quirk_cb,
.matches = {
DMI_MATCH(DMI_SYS_VENDOR, "DellInc."),
DMI_MATCH(DMI_PRODUCT_NAME, "Venue 8 Pro 5830"),
},
.driver_data = (unsigned long *)(BYT_RT5640_DMIC2_MAP |
BYT_RT5640_DMIC_EN),
},
{}
};
static int byt_rt5640_init(struct snd_soc_pcm_runtime *runtime)
{
int ret;
struct snd_soc_component *component = asoc_rtd_to_codec(runtime, 0)->component;
struct snd_soc_card *card = runtime->card;
const struct snd_soc_dapm_route *custom_map;
int num_routes;
card->dapm.idle_bias_off = true;
ret = snd_soc_add_card_controls(card, byt_rt5640_controls,
ARRAY_SIZE(byt_rt5640_controls));
if (ret) {
dev_err(card->dev, "unable to add card controls\n");
return ret;
}
dmi_check_system(byt_rt5640_quirk_table);
switch (BYT_RT5640_MAP(byt_rt5640_quirk)) {
case BYT_RT5640_IN1_MAP:
custom_map = byt_rt5640_intmic_in1_map;
num_routes = ARRAY_SIZE(byt_rt5640_intmic_in1_map);
break;
case BYT_RT5640_DMIC2_MAP:
custom_map = byt_rt5640_intmic_dmic2_map;
num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic2_map);
break;
default:
custom_map = byt_rt5640_intmic_dmic1_map;
num_routes = ARRAY_SIZE(byt_rt5640_intmic_dmic1_map);
}
ret = snd_soc_dapm_add_routes(&card->dapm, custom_map, num_routes);
if (ret)
return ret;
if (byt_rt5640_quirk & BYT_RT5640_DMIC_EN) {
ret = rt5640_dmic_enable(component, 0, 0);
if (ret)
return ret;
}
snd_soc_dapm_ignore_suspend(&card->dapm, "Headphone");
snd_soc_dapm_ignore_suspend(&card->dapm, "Speaker");
return ret;
}
static struct snd_soc_ops byt_rt5640_ops = {
.hw_params = byt_rt5640_hw_params,
};
SND_SOC_DAILINK_DEFS(audio,
DAILINK_COMP_ARRAY(COMP_CPU("baytrail-pcm-audio")),
DAILINK_COMP_ARRAY(COMP_CODEC("i2c-10EC5640:00", "rt5640-aif1")),
DAILINK_COMP_ARRAY(COMP_PLATFORM("baytrail-pcm-audio")));
static struct snd_soc_dai_link byt_rt5640_dais[] = {
{
.name = "Baytrail Audio",
.stream_name = "Audio",
.dai_fmt = SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_NB_NF |
SND_SOC_DAIFMT_CBS_CFS,
.init = byt_rt5640_init,
.ops = &byt_rt5640_ops,
SND_SOC_DAILINK_REG(audio),
},
};
static struct snd_soc_card byt_rt5640_card = {
.name = "byt-rt5640",
.owner = THIS_MODULE,
.dai_link = byt_rt5640_dais,
.num_links = ARRAY_SIZE(byt_rt5640_dais),
.dapm_widgets = byt_rt5640_widgets,
.num_dapm_widgets = ARRAY_SIZE(byt_rt5640_widgets),
.dapm_routes = byt_rt5640_audio_map,
.num_dapm_routes = ARRAY_SIZE(byt_rt5640_audio_map),
.fully_routed = true,
};
static int byt_rt5640_probe(struct platform_device *pdev)
{
struct snd_soc_card *card = &byt_rt5640_card;
card->dev = &pdev->dev;
return devm_snd_soc_register_card(&pdev->dev, card);
}
static struct platform_driver byt_rt5640_audio = {
.probe = byt_rt5640_probe,
.driver = {
.name = "byt-rt5640",
.pm = &snd_soc_pm_ops,
},
};
module_platform_driver(byt_rt5640_audio)
MODULE_DESCRIPTION("ASoC Intel(R) Baytrail Machine driver");
MODULE_AUTHOR("Omair Md Abdullah, Jarkko Nikula");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:byt-rt5640");
......@@ -28,7 +28,6 @@
#include <sound/soc.h>
#include <sound/soc-acpi.h>
#include "../atom/sst-atom-controls.h"
#include "../common/sst-dsp.h"
#include "../common/soc-intel-quirks.h"
/* jd-inv + terminating entry */
......
......@@ -28,7 +28,6 @@
#include <dt-bindings/sound/rt5640.h>
#include "../../codecs/rt5640.h"
#include "../atom/sst-atom-controls.h"
#include "../common/sst-dsp.h"
#include "../common/soc-intel-quirks.h"
enum {
......
# SPDX-License-Identifier: GPL-2.0-only
snd-soc-sst-dsp-objs := sst-dsp.o
snd-soc-sst-acpi-objs := sst-acpi.o
snd-soc-sst-ipc-objs := sst-ipc.o
snd-soc-sst-firmware-objs := sst-firmware.o
snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-match.o \
soc-acpi-intel-hsw-bdw-match.o \
soc-acpi-intel-skl-match.o soc-acpi-intel-kbl-match.o \
......@@ -14,6 +12,4 @@ snd-soc-acpi-intel-match-objs := soc-acpi-intel-byt-match.o soc-acpi-intel-cht-m
soc-acpi-intel-hda-match.o
obj-$(CONFIG_SND_SOC_INTEL_SST) += snd-soc-sst-dsp.o snd-soc-sst-ipc.o
obj-$(CONFIG_SND_SOC_INTEL_SST_ACPI) += snd-soc-sst-acpi.o
obj-$(CONFIG_SND_SOC_INTEL_SST_FIRMWARE) += snd-soc-sst-firmware.o
obj-$(CONFIG_SND_SOC_ACPI_INTEL_MATCH) += snd-soc-acpi-intel-match.o
......@@ -120,21 +120,6 @@ static struct snd_soc_acpi_mach *byt_quirk(void *arg)
}
}
struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_legacy_machines[] = {
{
.id = "10EC5640",
.drv_name = "byt-rt5640",
.fw_filename = "intel/fw_sst_0f28.bin-48kHz_i2s_master",
},
{
.id = "193C9890",
.drv_name = "byt-max98090",
.fw_filename = "intel/fw_sst_0f28.bin-48kHz_i2s_master",
},
{}
};
EXPORT_SYMBOL_GPL(snd_soc_acpi_intel_baytrail_legacy_machines);
struct snd_soc_acpi_mach snd_soc_acpi_intel_baytrail_machines[] = {
{
.id = "10EC5640",
......
// SPDX-License-Identifier: GPL-2.0-only
/*
* Intel SST loader on ACPI systems
*
* Copyright (C) 2013, Intel Corporation. All rights reserved.
*/
#include <linux/acpi.h>
#include <linux/device.h>
#include <linux/firmware.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include "sst-dsp.h"
#include <sound/soc-acpi.h>
#include <sound/soc-acpi-intel-match.h>
#define SST_LPT_DSP_DMA_ADDR_OFFSET 0x0F0000
#define SST_WPT_DSP_DMA_ADDR_OFFSET 0x0FE000
#define SST_LPT_DSP_DMA_SIZE (1024 - 1)
/* Descriptor for setting up SST platform data */
struct sst_acpi_desc {
const char *drv_name;
struct snd_soc_acpi_mach *machines;
/* Platform resource indexes. Must set to -1 if not used */
int resindex_lpe_base;
int resindex_pcicfg_base;
int resindex_fw_base;
int irqindex_host_ipc;
int resindex_dma_base;
/* Unique number identifying the SST core on platform */
int sst_id;
/* DMA only valid when resindex_dma_base != -1*/
int dma_engine;
int dma_size;
};
struct sst_acpi_priv {
struct platform_device *pdev_mach;
struct platform_device *pdev_pcm;
struct sst_pdata sst_pdata;
struct sst_acpi_desc *desc;
struct snd_soc_acpi_mach *mach;
};
static void sst_acpi_fw_cb(const struct firmware *fw, void *context)
{
struct platform_device *pdev = context;
struct device *dev = &pdev->dev;
struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev);
struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata;
struct sst_acpi_desc *desc = sst_acpi->desc;
struct snd_soc_acpi_mach *mach = sst_acpi->mach;
sst_pdata->fw = fw;
if (!fw) {
dev_err(dev, "Cannot load firmware %s\n", mach->fw_filename);
return;
}
/* register PCM and DAI driver */
sst_acpi->pdev_pcm =
platform_device_register_data(dev, desc->drv_name, -1,
sst_pdata, sizeof(*sst_pdata));
if (IS_ERR(sst_acpi->pdev_pcm)) {
dev_err(dev, "Cannot register device %s. Error %d\n",
desc->drv_name, (int)PTR_ERR(sst_acpi->pdev_pcm));
}
return;
}
static int sst_acpi_probe(struct platform_device *pdev)
{
const struct acpi_device_id *id;
struct device *dev = &pdev->dev;
struct sst_acpi_priv *sst_acpi;
struct sst_pdata *sst_pdata;
struct snd_soc_acpi_mach *mach;
struct sst_acpi_desc *desc;
struct resource *mmio;
int ret = 0;
sst_acpi = devm_kzalloc(dev, sizeof(*sst_acpi), GFP_KERNEL);
if (sst_acpi == NULL)
return -ENOMEM;
id = acpi_match_device(dev->driver->acpi_match_table, dev);
if (!id)
return -ENODEV;
desc = (struct sst_acpi_desc *)id->driver_data;
mach = snd_soc_acpi_find_machine(desc->machines);
if (mach == NULL) {
dev_err(dev, "No matching ASoC machine driver found\n");
return -ENODEV;
}
sst_pdata = &sst_acpi->sst_pdata;
sst_pdata->id = desc->sst_id;
sst_pdata->dma_dev = dev;
sst_acpi->desc = desc;
sst_acpi->mach = mach;
sst_pdata->resindex_dma_base = desc->resindex_dma_base;
if (desc->resindex_dma_base >= 0) {
sst_pdata->dma_engine = desc->dma_engine;
sst_pdata->dma_base = desc->resindex_dma_base;
sst_pdata->dma_size = desc->dma_size;
}
if (desc->irqindex_host_ipc >= 0)
sst_pdata->irq = platform_get_irq(pdev, desc->irqindex_host_ipc);
if (desc->resindex_lpe_base >= 0) {
mmio = platform_get_resource(pdev, IORESOURCE_MEM,
desc->resindex_lpe_base);
if (mmio) {
sst_pdata->lpe_base = mmio->start;
sst_pdata->lpe_size = resource_size(mmio);
}
}
if (desc->resindex_pcicfg_base >= 0) {
mmio = platform_get_resource(pdev, IORESOURCE_MEM,
desc->resindex_pcicfg_base);
if (mmio) {
sst_pdata->pcicfg_base = mmio->start;
sst_pdata->pcicfg_size = resource_size(mmio);
}
}
if (desc->resindex_fw_base >= 0) {
mmio = platform_get_resource(pdev, IORESOURCE_MEM,
desc->resindex_fw_base);
if (mmio) {
sst_pdata->fw_base = mmio->start;
sst_pdata->fw_size = resource_size(mmio);
}
}
platform_set_drvdata(pdev, sst_acpi);
mach->pdata = sst_pdata;
/* register machine driver */
sst_acpi->pdev_mach =
platform_device_register_data(dev, mach->drv_name, -1,
mach, sizeof(*mach));
if (IS_ERR(sst_acpi->pdev_mach))
return PTR_ERR(sst_acpi->pdev_mach);
/* continue SST probing after firmware is loaded */
ret = request_firmware_nowait(THIS_MODULE, true, mach->fw_filename,
dev, GFP_KERNEL, pdev, sst_acpi_fw_cb);
if (ret)
platform_device_unregister(sst_acpi->pdev_mach);
return ret;
}
static int sst_acpi_remove(struct platform_device *pdev)
{
struct sst_acpi_priv *sst_acpi = platform_get_drvdata(pdev);
struct sst_pdata *sst_pdata = &sst_acpi->sst_pdata;
platform_device_unregister(sst_acpi->pdev_mach);
if (!IS_ERR_OR_NULL(sst_acpi->pdev_pcm))
platform_device_unregister(sst_acpi->pdev_pcm);
release_firmware(sst_pdata->fw);
return 0;
}
static struct sst_acpi_desc sst_acpi_haswell_desc = {
.drv_name = "haswell-pcm-audio",
.machines = snd_soc_acpi_intel_haswell_machines,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = 1,
.resindex_fw_base = -1,
.irqindex_host_ipc = 0,
.sst_id = SST_DEV_ID_LYNX_POINT,
.dma_engine = SST_DMA_TYPE_DW,
.resindex_dma_base = SST_LPT_DSP_DMA_ADDR_OFFSET,
.dma_size = SST_LPT_DSP_DMA_SIZE,
};
static struct sst_acpi_desc sst_acpi_broadwell_desc = {
.drv_name = "haswell-pcm-audio",
.machines = snd_soc_acpi_intel_broadwell_machines,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = 1,
.resindex_fw_base = -1,
.irqindex_host_ipc = 0,
.sst_id = SST_DEV_ID_WILDCAT_POINT,
.dma_engine = SST_DMA_TYPE_DW,
.resindex_dma_base = SST_WPT_DSP_DMA_ADDR_OFFSET,
.dma_size = SST_LPT_DSP_DMA_SIZE,
};
#if !IS_ENABLED(CONFIG_SND_SST_IPC_ACPI)
static struct sst_acpi_desc sst_acpi_baytrail_desc = {
.drv_name = "baytrail-pcm-audio",
.machines = snd_soc_acpi_intel_baytrail_legacy_machines,
.resindex_lpe_base = 0,
.resindex_pcicfg_base = 1,
.resindex_fw_base = 2,
.irqindex_host_ipc = 5,
.sst_id = SST_DEV_ID_BYT,
.resindex_dma_base = -1,
};
#endif
static const struct acpi_device_id sst_acpi_match[] = {
{ "INT33C8", (unsigned long)&sst_acpi_haswell_desc },
{ "INT3438", (unsigned long)&sst_acpi_broadwell_desc },
#if !IS_ENABLED(CONFIG_SND_SST_IPC_ACPI)
{ "80860F28", (unsigned long)&sst_acpi_baytrail_desc },
#endif
{ }
};
MODULE_DEVICE_TABLE(acpi, sst_acpi_match);
static struct platform_driver sst_acpi_driver = {
.probe = sst_acpi_probe,
.remove = sst_acpi_remove,
.driver = {
.name = "sst-acpi",
.acpi_match_table = ACPI_PTR(sst_acpi_match),
},
};
module_platform_driver(sst_acpi_driver);
MODULE_AUTHOR("Jarkko Nikula <jarkko.nikula@linux.intel.com>");
MODULE_DESCRIPTION("Intel SST loader on ACPI systems");
MODULE_LICENSE("GPL v2");
......@@ -15,67 +15,32 @@
#include "../skylake/skl-sst-dsp.h"
struct sst_mem_block;
struct sst_module;
struct sst_fw;
/* do we need to remove or keep */
#define DSP_DRAM_ADDR_OFFSET 0x400000
/*
* DSP Operations exported by platform Audio DSP driver.
*/
struct sst_ops {
/* DSP core boot / reset */
void (*boot)(struct sst_dsp *);
void (*reset)(struct sst_dsp *);
int (*wake)(struct sst_dsp *);
void (*sleep)(struct sst_dsp *);
void (*stall)(struct sst_dsp *);
/* Shim IO */
void (*write)(void __iomem *addr, u32 offset, u32 value);
u32 (*read)(void __iomem *addr, u32 offset);
void (*write64)(void __iomem *addr, u32 offset, u64 value);
u64 (*read64)(void __iomem *addr, u32 offset);
/* DSP I/DRAM IO */
void (*ram_read)(struct sst_dsp *sst, void *dest, void __iomem *src,
size_t bytes);
void (*ram_write)(struct sst_dsp *sst, void __iomem *dest, void *src,
size_t bytes);
void (*dump)(struct sst_dsp *);
/* IRQ handlers */
irqreturn_t (*irq_handler)(int irq, void *context);
/* SST init and free */
int (*init)(struct sst_dsp *sst, struct sst_pdata *pdata);
int (*init)(struct sst_dsp *sst);
void (*free)(struct sst_dsp *sst);
/* FW module parser/loader */
int (*parse_fw)(struct sst_fw *sst_fw);
};
/*
* Audio DSP memory offsets and addresses.
*/
struct sst_addr {
u32 lpe_base;
u32 shim_offset;
u32 iram_offset;
u32 dram_offset;
u32 dsp_iram_offset;
u32 dsp_dram_offset;
u32 sram0_base;
u32 sram1_base;
u32 w0_stat_sz;
u32 w0_up_sz;
void __iomem *lpe;
void __iomem *shim;
void __iomem *pci_cfg;
void __iomem *fw_ext;
};
/*
......@@ -88,168 +53,6 @@ struct sst_mailbox {
size_t out_size;
};
/*
* Audio DSP memory block types.
*/
enum sst_mem_type {
SST_MEM_IRAM = 0,
SST_MEM_DRAM = 1,
SST_MEM_ANY = 2,
SST_MEM_CACHE= 3,
};
/*
* Audio DSP Generic Firmware File.
*
* SST Firmware files can consist of 1..N modules. This generic structure is
* used to manage each firmware file and it's modules regardless of SST firmware
* type. A SST driver may load multiple FW files.
*/
struct sst_fw {
struct sst_dsp *dsp;
/* base addresses of FW file data */
dma_addr_t dmable_fw_paddr; /* physical address of fw data */
void *dma_buf; /* virtual address of fw data */
u32 size; /* size of fw data */
/* lists */
struct list_head list; /* DSP list of FW */
struct list_head module_list; /* FW list of modules */
void *private; /* core doesn't touch this */
};
/*
* Audio DSP Generic Module Template.
*
* Used to define and register a new FW module. This data is extracted from
* FW module header information.
*/
struct sst_module_template {
u32 id;
u32 entry; /* entry point */
u32 scratch_size;
u32 persistent_size;
};
/*
* Block Allocator - Used to allocate blocks of DSP memory.
*/
struct sst_block_allocator {
u32 id;
u32 offset;
int size;
enum sst_mem_type type;
};
/*
* Runtime Module Instance - A module object can be instantiated multiple
* times within the DSP FW.
*/
struct sst_module_runtime {
struct sst_dsp *dsp;
int id;
struct sst_module *module; /* parent module we belong too */
u32 persistent_offset; /* private memory offset */
void *private;
struct list_head list;
struct list_head block_list; /* list of blocks used */
};
/*
* Runtime Module Context - The runtime context must be manually stored by the
* driver prior to enter S3 and restored after leaving S3. This should really be
* part of the memory context saved by the enter D3 message IPC ???
*/
struct sst_module_runtime_context {
dma_addr_t dma_buffer;
u32 *buffer;
};
/*
* Audio DSP Module State
*/
enum sst_module_state {
SST_MODULE_STATE_UNLOADED = 0, /* default state */
SST_MODULE_STATE_LOADED,
SST_MODULE_STATE_INITIALIZED, /* and inactive */
SST_MODULE_STATE_ACTIVE,
};
/*
* Audio DSP Generic Module.
*
* Each Firmware file can consist of 1..N modules. A module can span multiple
* ADSP memory blocks. The simplest FW will be a file with 1 module. A module
* can be instantiated multiple times in the DSP.
*/
struct sst_module {
struct sst_dsp *dsp;
struct sst_fw *sst_fw; /* parent FW we belong too */
/* module configuration */
u32 id;
u32 entry; /* module entry point */
s32 offset; /* module offset in firmware file */
u32 size; /* module size */
u32 scratch_size; /* global scratch memory required */
u32 persistent_size; /* private memory required */
enum sst_mem_type type; /* destination memory type */
u32 data_offset; /* offset in ADSP memory space */
void *data; /* module data */
/* runtime */
u32 usage_count; /* can be unloaded if count == 0 */
void *private; /* core doesn't touch this */
/* lists */
struct list_head block_list; /* Module list of blocks in use */
struct list_head list; /* DSP list of modules */
struct list_head list_fw; /* FW list of modules */
struct list_head runtime_list; /* list of runtime module objects*/
/* state */
enum sst_module_state state;
};
/*
* SST Memory Block operations.
*/
struct sst_block_ops {
int (*enable)(struct sst_mem_block *block);
int (*disable)(struct sst_mem_block *block);
};
/*
* SST Generic Memory Block.
*
* SST ADP memory has multiple IRAM and DRAM blocks. Some ADSP blocks can be
* power gated.
*/
struct sst_mem_block {
struct sst_dsp *dsp;
struct sst_module *module; /* module that uses this block */
/* block config */
u32 offset; /* offset from base */
u32 size; /* block size */
u32 index; /* block index 0..N */
enum sst_mem_type type; /* block memory type IRAM/DRAM */
const struct sst_block_ops *ops;/* block operations, if any */
/* block status */
u32 bytes_used; /* bytes in use by modules */
void *private; /* generic core does not touch this */
int users; /* number of modules using this block */
/* block lists */
struct list_head module_list; /* Module list of blocks */
struct list_head list; /* Map list of free/used blocks */
};
/*
* Generic SST Shim Interface.
*/
......@@ -262,7 +65,6 @@ struct sst_dsp {
spinlock_t spinlock; /* IPC locking */
struct mutex mutex; /* DSP FW lock */
struct device *dev;
struct device *dma_dev;
void *thread_context;
int irq;
u32 id;
......@@ -279,27 +81,8 @@ struct sst_dsp {
/* mailbox */
struct sst_mailbox mailbox;
/* HSW/Byt data */
/* list of free and used ADSP memory blocks */
struct list_head used_block_list;
struct list_head free_block_list;
/* SST FW files loaded and their modules */
struct list_head module_list;
struct list_head fw_list;
/* scratch buffer */
struct list_head scratch_block_list;
u32 scratch_offset;
u32 scratch_size;
/* platform data */
struct sst_pdata *pdata;
/* DMA FW loading */
struct sst_dma *dma;
bool fw_use_dma;
/* SKL data */
......@@ -315,69 +98,4 @@ struct sst_dsp {
struct snd_dma_buffer dmab;
};
/* Size optimised DRAM/IRAM memcpy */
static inline void sst_dsp_write(struct sst_dsp *sst, void *src,
u32 dest_offset, size_t bytes)
{
sst->ops->ram_write(sst, sst->addr.lpe + dest_offset, src, bytes);
}
static inline void sst_dsp_read(struct sst_dsp *sst, void *dest,
u32 src_offset, size_t bytes)
{
sst->ops->ram_read(sst, dest, sst->addr.lpe + src_offset, bytes);
}
static inline void *sst_dsp_get_thread_context(struct sst_dsp *sst)
{
return sst->thread_context;
}
/* Create/Free FW files - can contain multiple modules */
struct sst_fw *sst_fw_new(struct sst_dsp *dsp,
const struct firmware *fw, void *private);
void sst_fw_free(struct sst_fw *sst_fw);
void sst_fw_free_all(struct sst_dsp *dsp);
int sst_fw_reload(struct sst_fw *sst_fw);
void sst_fw_unload(struct sst_fw *sst_fw);
/* Create/Free firmware modules */
struct sst_module *sst_module_new(struct sst_fw *sst_fw,
struct sst_module_template *template, void *private);
void sst_module_free(struct sst_module *sst_module);
struct sst_module *sst_module_get_from_id(struct sst_dsp *dsp, u32 id);
int sst_module_alloc_blocks(struct sst_module *module);
int sst_module_free_blocks(struct sst_module *module);
/* Create/Free firmware module runtime instances */
struct sst_module_runtime *sst_module_runtime_new(struct sst_module *module,
int id, void *private);
void sst_module_runtime_free(struct sst_module_runtime *runtime);
struct sst_module_runtime *sst_module_runtime_get_from_id(
struct sst_module *module, u32 id);
int sst_module_runtime_alloc_blocks(struct sst_module_runtime *runtime,
int offset);
int sst_module_runtime_free_blocks(struct sst_module_runtime *runtime);
int sst_module_runtime_save(struct sst_module_runtime *runtime,
struct sst_module_runtime_context *context);
int sst_module_runtime_restore(struct sst_module_runtime *runtime,
struct sst_module_runtime_context *context);
/* generic block allocation */
int sst_alloc_blocks(struct sst_dsp *dsp, struct sst_block_allocator *ba,
struct list_head *block_list);
int sst_free_blocks(struct sst_dsp *dsp, struct list_head *block_list);
/* scratch allocation */
int sst_block_alloc_scratch(struct sst_dsp *dsp);
void sst_block_free_scratch(struct sst_dsp *dsp);
/* Register the DSPs memory blocks - would be nice to read from ACPI */
struct sst_mem_block *sst_mem_block_register(struct sst_dsp *dsp, u32 offset,
u32 size, enum sst_mem_type type, const struct sst_block_ops *ops,
u32 index, void *private);
void sst_mem_block_unregister_all(struct sst_dsp *dsp);
u32 sst_dsp_get_offset(struct sst_dsp *dsp, u32 offset,
enum sst_mem_type type);
#endif
......@@ -44,38 +44,6 @@ u64 sst_shim32_read64(void __iomem *addr, u32 offset)
}
EXPORT_SYMBOL_GPL(sst_shim32_read64);
static inline void _sst_memcpy_toio_32(volatile u32 __iomem *dest,
u32 *src, size_t bytes)
{
int i, words = bytes >> 2;
for (i = 0; i < words; i++)
writel(src[i], dest + i);
}
static inline void _sst_memcpy_fromio_32(u32 *dest,
const volatile __iomem u32 *src, size_t bytes)
{
int i, words = bytes >> 2;
for (i = 0; i < words; i++)
dest[i] = readl(src + i);
}
void sst_memcpy_toio_32(struct sst_dsp *sst,
void __iomem *dest, void *src, size_t bytes)
{
_sst_memcpy_toio_32(dest, src, bytes);
}
EXPORT_SYMBOL_GPL(sst_memcpy_toio_32);
void sst_memcpy_fromio_32(struct sst_dsp *sst, void *dest,
void __iomem *src, size_t bytes)
{
_sst_memcpy_fromio_32(dest, src, bytes);
}
EXPORT_SYMBOL_GPL(sst_memcpy_fromio_32);
/* Public API */
void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value)
{
......@@ -100,29 +68,6 @@ u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset)
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_read);
void sst_dsp_shim_write64(struct sst_dsp *sst, u32 offset, u64 value)
{
unsigned long flags;
spin_lock_irqsave(&sst->spinlock, flags);
sst->ops->write64(sst->addr.shim, offset, value);
spin_unlock_irqrestore(&sst->spinlock, flags);
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_write64);
u64 sst_dsp_shim_read64(struct sst_dsp *sst, u32 offset)
{
unsigned long flags;
u64 val;
spin_lock_irqsave(&sst->spinlock, flags);
val = sst->ops->read64(sst->addr.shim, offset);
spin_unlock_irqrestore(&sst->spinlock, flags);
return val;
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_read64);
void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value)
{
sst->ops->write(sst->addr.shim, offset, value);
......@@ -135,18 +80,6 @@ u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset)
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_read_unlocked);
void sst_dsp_shim_write64_unlocked(struct sst_dsp *sst, u32 offset, u64 value)
{
sst->ops->write64(sst->addr.shim, offset, value);
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_write64_unlocked);
u64 sst_dsp_shim_read64_unlocked(struct sst_dsp *sst, u32 offset)
{
return sst->ops->read64(sst->addr.shim, offset);
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_read64_unlocked);
int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset,
u32 mask, u32 value)
{
......@@ -167,24 +100,6 @@ int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset,
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits_unlocked);
int sst_dsp_shim_update_bits64_unlocked(struct sst_dsp *sst, u32 offset,
u64 mask, u64 value)
{
bool change;
u64 old, new;
old = sst_dsp_shim_read64_unlocked(sst, offset);
new = (old & (~mask)) | (value & mask);
change = (old != new);
if (change)
sst_dsp_shim_write64_unlocked(sst, offset, new);
return change;
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits64_unlocked);
/* This is for registers bits with attribute RWC */
void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset,
u32 mask, u32 value)
......@@ -214,19 +129,6 @@ int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset,
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits);
int sst_dsp_shim_update_bits64(struct sst_dsp *sst, u32 offset,
u64 mask, u64 value)
{
unsigned long flags;
bool change;
spin_lock_irqsave(&sst->spinlock, flags);
change = sst_dsp_shim_update_bits64_unlocked(sst, offset, mask, value);
spin_unlock_irqrestore(&sst->spinlock, flags);
return change;
}
EXPORT_SYMBOL_GPL(sst_dsp_shim_update_bits64);
/* This is for registers bits with attribute RWC */
void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset,
u32 mask, u32 value)
......@@ -279,70 +181,6 @@ int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
}
EXPORT_SYMBOL_GPL(sst_dsp_register_poll);
void sst_dsp_dump(struct sst_dsp *sst)
{
if (sst->ops->dump)
sst->ops->dump(sst);
}
EXPORT_SYMBOL_GPL(sst_dsp_dump);
void sst_dsp_reset(struct sst_dsp *sst)
{
if (sst->ops->reset)
sst->ops->reset(sst);
}
EXPORT_SYMBOL_GPL(sst_dsp_reset);
int sst_dsp_boot(struct sst_dsp *sst)
{
if (sst->ops->boot)
sst->ops->boot(sst);
return 0;
}
EXPORT_SYMBOL_GPL(sst_dsp_boot);
int sst_dsp_wake(struct sst_dsp *sst)
{
if (sst->ops->wake)
return sst->ops->wake(sst);
return 0;
}
EXPORT_SYMBOL_GPL(sst_dsp_wake);
void sst_dsp_sleep(struct sst_dsp *sst)
{
if (sst->ops->sleep)
sst->ops->sleep(sst);
}
EXPORT_SYMBOL_GPL(sst_dsp_sleep);
void sst_dsp_stall(struct sst_dsp *sst)
{
if (sst->ops->stall)
sst->ops->stall(sst);
}
EXPORT_SYMBOL_GPL(sst_dsp_stall);
void sst_dsp_ipc_msg_tx(struct sst_dsp *dsp, u32 msg)
{
sst_dsp_shim_write_unlocked(dsp, SST_IPCX, msg | SST_IPCX_BUSY);
trace_sst_ipc_msg_tx(msg);
}
EXPORT_SYMBOL_GPL(sst_dsp_ipc_msg_tx);
u32 sst_dsp_ipc_msg_rx(struct sst_dsp *dsp)
{
u32 msg;
msg = sst_dsp_shim_read_unlocked(dsp, SST_IPCX);
trace_sst_ipc_msg_rx(msg);
return msg;
}
EXPORT_SYMBOL_GPL(sst_dsp_ipc_msg_rx);
int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset, size_t inbox_size,
u32 outbox_offset, size_t outbox_size)
{
......
......@@ -12,159 +12,6 @@
#include <linux/types.h>
#include <linux/interrupt.h>
/* SST Device IDs */
#define SST_DEV_ID_LYNX_POINT 0x33C8
#define SST_DEV_ID_WILDCAT_POINT 0x3438
#define SST_DEV_ID_BYT 0x0F28
/* Supported SST DMA Devices */
#define SST_DMA_TYPE_DW 1
/* autosuspend delay 5s*/
#define SST_RUNTIME_SUSPEND_DELAY (5 * 1000)
/* SST Shim register map
* The register naming can differ between products. Some products also
* contain extra functionality.
*/
#define SST_CSR 0x00
#define SST_PISR 0x08
#define SST_PIMR 0x10
#define SST_ISRX 0x18
#define SST_ISRD 0x20
#define SST_IMRX 0x28
#define SST_IMRD 0x30
#define SST_IPCX 0x38 /* IPC IA -> SST */
#define SST_IPCD 0x40 /* IPC SST -> IA */
#define SST_ISRSC 0x48
#define SST_ISRLPESC 0x50
#define SST_IMRSC 0x58
#define SST_IMRLPESC 0x60
#define SST_IPCSC 0x68
#define SST_IPCLPESC 0x70
#define SST_CLKCTL 0x78
#define SST_CSR2 0x80
#define SST_LTRC 0xE0
#define SST_HMDC 0xE8
#define SST_SHIM_BEGIN SST_CSR
#define SST_SHIM_END SST_HDMC
#define SST_DBGO 0xF0
#define SST_SHIM_SIZE 0x100
#define SST_PWMCTRL 0x1000
/* SST Shim Register bits
* The register bit naming can differ between products. Some products also
* contain extra functionality.
*/
/* CSR / CS */
#define SST_CSR_RST (0x1 << 1)
#define SST_CSR_SBCS0 (0x1 << 2)
#define SST_CSR_SBCS1 (0x1 << 3)
#define SST_CSR_DCS(x) (x << 4)
#define SST_CSR_DCS_MASK (0x7 << 4)
#define SST_CSR_STALL (0x1 << 10)
#define SST_CSR_S0IOCS (0x1 << 21)
#define SST_CSR_S1IOCS (0x1 << 23)
#define SST_CSR_LPCS (0x1 << 31)
#define SST_CSR_24MHZ_LPCS (SST_CSR_SBCS0 | SST_CSR_SBCS1 | SST_CSR_LPCS)
#define SST_CSR_24MHZ_NO_LPCS (SST_CSR_SBCS0 | SST_CSR_SBCS1)
#define SST_BYT_CSR_RST (0x1 << 0)
#define SST_BYT_CSR_VECTOR_SEL (0x1 << 1)
#define SST_BYT_CSR_STALL (0x1 << 2)
#define SST_BYT_CSR_PWAITMODE (0x1 << 3)
/* ISRX / ISC */
#define SST_ISRX_BUSY (0x1 << 1)
#define SST_ISRX_DONE (0x1 << 0)
#define SST_BYT_ISRX_REQUEST (0x1 << 1)
/* ISRD / ISD */
#define SST_ISRD_BUSY (0x1 << 1)
#define SST_ISRD_DONE (0x1 << 0)
/* IMRX / IMC */
#define SST_IMRX_BUSY (0x1 << 1)
#define SST_IMRX_DONE (0x1 << 0)
#define SST_BYT_IMRX_REQUEST (0x1 << 1)
/* IMRD / IMD */
#define SST_IMRD_DONE (0x1 << 0)
#define SST_IMRD_BUSY (0x1 << 1)
#define SST_IMRD_SSP0 (0x1 << 16)
#define SST_IMRD_DMAC0 (0x1 << 21)
#define SST_IMRD_DMAC1 (0x1 << 22)
#define SST_IMRD_DMAC (SST_IMRD_DMAC0 | SST_IMRD_DMAC1)
/* IPCX / IPCC */
#define SST_IPCX_DONE (0x1 << 30)
#define SST_IPCX_BUSY (0x1 << 31)
#define SST_BYT_IPCX_DONE ((u64)0x1 << 62)
#define SST_BYT_IPCX_BUSY ((u64)0x1 << 63)
/* IPCD */
#define SST_IPCD_DONE (0x1 << 30)
#define SST_IPCD_BUSY (0x1 << 31)
#define SST_BYT_IPCD_DONE ((u64)0x1 << 62)
#define SST_BYT_IPCD_BUSY ((u64)0x1 << 63)
/* CLKCTL */
#define SST_CLKCTL_SMOS(x) (x << 24)
#define SST_CLKCTL_MASK (3 << 24)
#define SST_CLKCTL_DCPLCG (1 << 18)
#define SST_CLKCTL_SCOE1 (1 << 17)
#define SST_CLKCTL_SCOE0 (1 << 16)
/* CSR2 / CS2 */
#define SST_CSR2_SDFD_SSP0 (1 << 1)
#define SST_CSR2_SDFD_SSP1 (1 << 2)
/* LTRC */
#define SST_LTRC_VAL(x) (x << 0)
/* HMDC */
#define SST_HMDC_HDDA0(x) (x << 0)
#define SST_HMDC_HDDA1(x) (x << 7)
#define SST_HMDC_HDDA_E0_CH0 1
#define SST_HMDC_HDDA_E0_CH1 2
#define SST_HMDC_HDDA_E0_CH2 4
#define SST_HMDC_HDDA_E0_CH3 8
#define SST_HMDC_HDDA_E1_CH0 SST_HMDC_HDDA1(SST_HMDC_HDDA_E0_CH0)
#define SST_HMDC_HDDA_E1_CH1 SST_HMDC_HDDA1(SST_HMDC_HDDA_E0_CH1)
#define SST_HMDC_HDDA_E1_CH2 SST_HMDC_HDDA1(SST_HMDC_HDDA_E0_CH2)
#define SST_HMDC_HDDA_E1_CH3 SST_HMDC_HDDA1(SST_HMDC_HDDA_E0_CH3)
#define SST_HMDC_HDDA_E0_ALLCH (SST_HMDC_HDDA_E0_CH0 | SST_HMDC_HDDA_E0_CH1 | \
SST_HMDC_HDDA_E0_CH2 | SST_HMDC_HDDA_E0_CH3)
#define SST_HMDC_HDDA_E1_ALLCH (SST_HMDC_HDDA_E1_CH0 | SST_HMDC_HDDA_E1_CH1 | \
SST_HMDC_HDDA_E1_CH2 | SST_HMDC_HDDA_E1_CH3)
/* SST Vendor Defined Registers and bits */
#define SST_VDRTCTL0 0xa0
#define SST_VDRTCTL1 0xa4
#define SST_VDRTCTL2 0xa8
#define SST_VDRTCTL3 0xaC
/* VDRTCTL0 */
#define SST_VDRTCL0_D3PGD (1 << 0)
#define SST_VDRTCL0_D3SRAMPGD (1 << 1)
#define SST_VDRTCL0_DSRAMPGE_SHIFT 12
#define SST_VDRTCL0_DSRAMPGE_MASK (0xfffff << SST_VDRTCL0_DSRAMPGE_SHIFT)
#define SST_VDRTCL0_ISRAMPGE_SHIFT 2
#define SST_VDRTCL0_ISRAMPGE_MASK (0x3ff << SST_VDRTCL0_ISRAMPGE_SHIFT)
/* VDRTCTL2 */
#define SST_VDRTCL2_DCLCGE (1 << 1)
#define SST_VDRTCL2_DTCGE (1 << 10)
#define SST_VDRTCL2_APLLSE_MASK (1 << 31)
/* PMCS */
#define SST_PMCS 0x84
#define SST_PMCS_PS_MASK 0x3
struct sst_dsp;
/*
......@@ -179,50 +26,11 @@ struct sst_dsp_device {
void *thread_context;
};
/*
* SST Platform Data.
*/
struct sst_pdata {
/* ACPI data */
u32 lpe_base;
u32 lpe_size;
u32 pcicfg_base;
u32 pcicfg_size;
u32 fw_base;
u32 fw_size;
int irq;
/* Firmware */
const struct firmware *fw;
/* DMA */
int resindex_dma_base; /* other fields invalid if equals to -1 */
u32 dma_base;
u32 dma_size;
int dma_engine;
struct device *dma_dev;
/* DSP */
u32 id;
void *dsp;
};
#if IS_ENABLED(CONFIG_DW_DMAC_CORE)
/* Initialization */
struct sst_dsp *sst_dsp_new(struct device *dev,
struct sst_dsp_device *sst_dev, struct sst_pdata *pdata);
void sst_dsp_free(struct sst_dsp *sst);
#endif
/* SHIM Read / Write */
void sst_dsp_shim_write(struct sst_dsp *sst, u32 offset, u32 value);
u32 sst_dsp_shim_read(struct sst_dsp *sst, u32 offset);
int sst_dsp_shim_update_bits(struct sst_dsp *sst, u32 offset,
u32 mask, u32 value);
void sst_dsp_shim_write64(struct sst_dsp *sst, u32 offset, u64 value);
u64 sst_dsp_shim_read64(struct sst_dsp *sst, u32 offset);
int sst_dsp_shim_update_bits64(struct sst_dsp *sst, u32 offset,
u64 mask, u64 value);
void sst_dsp_shim_update_bits_forced(struct sst_dsp *sst, u32 offset,
u32 mask, u32 value);
......@@ -231,10 +39,6 @@ void sst_dsp_shim_write_unlocked(struct sst_dsp *sst, u32 offset, u32 value);
u32 sst_dsp_shim_read_unlocked(struct sst_dsp *sst, u32 offset);
int sst_dsp_shim_update_bits_unlocked(struct sst_dsp *sst, u32 offset,
u32 mask, u32 value);
void sst_dsp_shim_write64_unlocked(struct sst_dsp *sst, u32 offset, u64 value);
u64 sst_dsp_shim_read64_unlocked(struct sst_dsp *sst, u32 offset);
int sst_dsp_shim_update_bits64_unlocked(struct sst_dsp *sst, u32 offset,
u64 mask, u64 value);
void sst_dsp_shim_update_bits_forced_unlocked(struct sst_dsp *sst, u32 offset,
u32 mask, u32 value);
......@@ -243,29 +47,6 @@ void sst_shim32_write(void __iomem *addr, u32 offset, u32 value);
u32 sst_shim32_read(void __iomem *addr, u32 offset);
void sst_shim32_write64(void __iomem *addr, u32 offset, u64 value);
u64 sst_shim32_read64(void __iomem *addr, u32 offset);
void sst_memcpy_toio_32(struct sst_dsp *sst,
void __iomem *dest, void *src, size_t bytes);
void sst_memcpy_fromio_32(struct sst_dsp *sst,
void *dest, void __iomem *src, size_t bytes);
/* DSP reset & boot */
void sst_dsp_reset(struct sst_dsp *sst);
int sst_dsp_boot(struct sst_dsp *sst);
int sst_dsp_wake(struct sst_dsp *sst);
void sst_dsp_sleep(struct sst_dsp *sst);
void sst_dsp_stall(struct sst_dsp *sst);
/* DMA */
int sst_dsp_dma_get_channel(struct sst_dsp *dsp, int chan_id);
void sst_dsp_dma_put_channel(struct sst_dsp *dsp);
int sst_dsp_dma_copyfrom(struct sst_dsp *sst, dma_addr_t dest_addr,
dma_addr_t src_addr, size_t size);
int sst_dsp_dma_copyto(struct sst_dsp *sst, dma_addr_t dest_addr,
dma_addr_t src_addr, size_t size);
/* Msg IO */
void sst_dsp_ipc_msg_tx(struct sst_dsp *dsp, u32 msg);
u32 sst_dsp_ipc_msg_rx(struct sst_dsp *dsp);
/* Mailbox management */
int sst_dsp_mailbox_init(struct sst_dsp *sst, u32 inbox_offset,
......@@ -277,7 +58,4 @@ void sst_dsp_outbox_read(struct sst_dsp *sst, void *message, size_t bytes);
int sst_dsp_register_poll(struct sst_dsp *ctx, u32 offset, u32 mask,
u32 target, u32 time, char *operation);
/* Debug */
void sst_dsp_dump(struct sst_dsp *sst);
#endif
This diff is collapsed.
......@@ -254,33 +254,6 @@ void sst_ipc_tx_msg_reply_complete(struct sst_generic_ipc *ipc,
}
EXPORT_SYMBOL_GPL(sst_ipc_tx_msg_reply_complete);
void sst_ipc_drop_all(struct sst_generic_ipc *ipc)
{
struct ipc_message *msg, *tmp;
unsigned long flags;
int tx_drop_cnt = 0, rx_drop_cnt = 0;
/* drop all TX and Rx messages before we stall + reset DSP */
spin_lock_irqsave(&ipc->dsp->spinlock, flags);
list_for_each_entry_safe(msg, tmp, &ipc->tx_list, list) {
list_move(&msg->list, &ipc->empty_list);
tx_drop_cnt++;
}
list_for_each_entry_safe(msg, tmp, &ipc->rx_list, list) {
list_move(&msg->list, &ipc->empty_list);
rx_drop_cnt++;
}
spin_unlock_irqrestore(&ipc->dsp->spinlock, flags);
if (tx_drop_cnt || rx_drop_cnt)
dev_err(ipc->dev, "dropped IPC msg RX=%d, TX=%d\n",
tx_drop_cnt, rx_drop_cnt);
}
EXPORT_SYMBOL_GPL(sst_ipc_drop_all);
int sst_ipc_init(struct sst_generic_ipc *ipc)
{
int ret;
......
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment