MLK-14997-4: ASoC: fsl: add hifi4 dsp driver
The function of driver is to communicate with hifi firmware. The mu13 is dedicated for hifi communication, driver allocate a share memory for message transfer between driver and firmware. The calling sequence is that LOAD_CODEC,INIT_CODEC,CODEC_OPEN, DECODE_ONE_FRAME, CODEC_CLOSE. Signed-off-by: Shengjiu Wang <shengjiu.wang@freescale.com>
This commit is contained in:
@ -74,6 +74,14 @@ config SND_SOC_FSL_RPMSG_I2S
|
||||
This option is only useful for out-of-tree drivers since
|
||||
in-tree drivers select it automatically.
|
||||
|
||||
config SND_SOC_FSL_HIFI4
|
||||
tristate "hifi 4 module support"
|
||||
help
|
||||
Say Y if you want to add hifi 4 support for the Freescale CPUs.
|
||||
which is a DSP core for audio processing.
|
||||
This option is only useful for out-of-tree drivers since
|
||||
in-tree drivers select it automatically.
|
||||
|
||||
config SND_SOC_FSL_UTILS
|
||||
tristate
|
||||
|
||||
|
||||
@ -15,6 +15,7 @@ obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
|
||||
snd-soc-fsl-acm-objs := fsl_acm.o
|
||||
snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
|
||||
snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
|
||||
snd-soc-fsl-hifi4-objs := fsl_hifi4.o
|
||||
snd-soc-fsl-sai-objs := fsl_sai.o
|
||||
snd-soc-fsl-ssi-y := fsl_ssi.o
|
||||
snd-soc-fsl-ssi-$(CONFIG_DEBUG_FS) += fsl_ssi_dbg.o
|
||||
@ -27,6 +28,7 @@ obj-$(CONFIG_SND_SOC_FSL_ACM) += snd-soc-fsl-acm.o
|
||||
obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
|
||||
snd-soc-fsl-hdmi-objs := fsl_hdmi.o
|
||||
obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
|
||||
obj-$(CONFIG_SND_SOC_FSL_HIFI4) += snd-soc-fsl-hifi4.o
|
||||
obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
|
||||
obj-$(CONFIG_SND_SOC_FSL_SSI) += snd-soc-fsl-ssi.o
|
||||
obj-$(CONFIG_SND_SOC_FSL_SPDIF) += snd-soc-fsl-spdif.o
|
||||
|
||||
1460
sound/soc/fsl/fsl_hifi4.c
Normal file
1460
sound/soc/fsl/fsl_hifi4.c
Normal file
File diff suppressed because it is too large
Load Diff
282
sound/soc/fsl/fsl_hifi4.h
Normal file
282
sound/soc/fsl/fsl_hifi4.h
Normal file
@ -0,0 +1,282 @@
|
||||
/*
|
||||
* Freescale HIFI 4 driver
|
||||
*
|
||||
* Copyright (C) 2017 NXP.
|
||||
*
|
||||
* This file is licensed under the terms of the GNU General Public License
|
||||
* version 2. This program is licensed "as is" without any warranty of any
|
||||
* kind, whether express or implied.
|
||||
*/
|
||||
|
||||
#include <uapi/linux/mxc_hifi4.h>
|
||||
|
||||
|
||||
#define Elf32_Byte unsigned char
|
||||
#define xt_ptr unsigned long
|
||||
#define xt_int int
|
||||
#define xt_uint unsigned int
|
||||
#define xt_ulong unsigned long
|
||||
|
||||
typedef void (*memcpy_func) (void *dest, const void *src, size_t n);
|
||||
typedef void (*memset_func) (void *s, int c, size_t n);
|
||||
struct xtlib_packaged_library;
|
||||
|
||||
|
||||
enum {
|
||||
XTLIB_NO_ERR = 0,
|
||||
XTLIB_NOT_ELF = 1,
|
||||
XTLIB_NOT_DYNAMIC = 2,
|
||||
XTLIB_NOT_STATIC = 3,
|
||||
XTLIB_NO_DYNAMIC_SEGMENT = 4,
|
||||
XTLIB_UNKNOWN_SYMBOL = 5,
|
||||
XTLIB_NOT_ALIGNED = 6,
|
||||
XTLIB_NOT_SPLITLOAD = 7,
|
||||
XTLIB_RELOCATION_ERR = 8
|
||||
};
|
||||
|
||||
struct xtlib_loader_globals {
|
||||
int err;
|
||||
int byteswap;
|
||||
};
|
||||
|
||||
struct timestamp_info_t {
|
||||
u32 offset_last_inp_byt_read_frm_sysram;
|
||||
u32 offset_last_inp_byt_decoded;
|
||||
u32 samples_produced;
|
||||
u32 sample_rate;
|
||||
};
|
||||
|
||||
struct icm_cdc_iobuf_t {
|
||||
u32 proc_id; /* non-zero indicates success; */
|
||||
u32 inp_addr_sysram; /* init by APU */
|
||||
u32 inp_buf_size_max; /* init by APU */
|
||||
u32 inp_cur_offset; /* init by APU, updated by DPU */
|
||||
u32 out_addr_sysram; /* init by APU */
|
||||
u32 out_buf_size_max; /* init by APU */
|
||||
u32 out_cur_offset; /* init by APU, updated by DPU */
|
||||
s32 ret;
|
||||
};
|
||||
|
||||
struct icm_cdc_uinp_t {
|
||||
u32 proc_id; /* audio id */
|
||||
u32 codec_id; /* codec identifier */
|
||||
u32 pcm_wd_sz; /* pcm word size; only 16 or 24 */
|
||||
u32 crc_check; /* 0: disable, 1: enable */
|
||||
};
|
||||
|
||||
struct icm_pcm_prop_t {
|
||||
u32 proc_id; /* audio id */
|
||||
u32 pcmbytes; /* total bytes in the wav file */
|
||||
u32 sfreq; /* sample rate */
|
||||
u32 channels; /* output channels */
|
||||
u32 bits; /* bits per sample */
|
||||
u32 consumed_bytes;
|
||||
s32 ret;
|
||||
};
|
||||
|
||||
struct xtlib_overlay_info {
|
||||
u32 start_addr;
|
||||
u32 codec_type;
|
||||
};
|
||||
|
||||
struct xtlib_pil_info {
|
||||
xt_uint dst_addr;
|
||||
xt_uint src_offs;
|
||||
xt_uint dst_data_addr;
|
||||
xt_uint src_data_offs;
|
||||
xt_uint start_sym;
|
||||
xt_uint text_addr;
|
||||
xt_uint init;
|
||||
xt_uint fini;
|
||||
xt_uint rel;
|
||||
xt_int rela_count;
|
||||
xt_uint hash;
|
||||
xt_uint symtab;
|
||||
xt_uint strtab;
|
||||
xt_int align;
|
||||
};
|
||||
|
||||
union icm_header_t {
|
||||
struct {
|
||||
u32 msg:6;
|
||||
u32 sub_msg:6; /* sub_msg will have ICM_MSG when
|
||||
* msg=ICM_XXX_ACTION_COMPLETE
|
||||
*/
|
||||
u32 rsvd:3; /* reserved */
|
||||
u32 intr:1; /* intr = 1 when sending msg. */
|
||||
u32 size:15; /* =size in bytes (excluding header)
|
||||
* to follow when intr=1,
|
||||
* =response message when ack=1
|
||||
*/
|
||||
u32 ack:1;
|
||||
};
|
||||
u32 allbits;
|
||||
} icm_header_t;
|
||||
|
||||
enum icm_action_t {
|
||||
ICM_CORE_READY = 1,
|
||||
ICM_PI_LIB_MEM_ALLOC,
|
||||
ICM_PI_LIB_INIT,
|
||||
ICM_PI_LIB_UNLOAD,
|
||||
|
||||
ICM_DPU_ACTION_COMPLETE,
|
||||
ICM_APU_ACTION_COMPLETE,
|
||||
|
||||
ICM_OPEN,
|
||||
ICM_EMPTY_THIS_BUFFER,
|
||||
ICM_FILL_THIS_BUFFER,
|
||||
ICM_PAUSE,
|
||||
ICM_CLOSE,
|
||||
|
||||
ICM_GET_PCM_PROP,
|
||||
ICM_SET_PARA_CONFIG,
|
||||
|
||||
ICM_CORE_EXIT,
|
||||
ICM_EXT_MSG_ADDR,
|
||||
};
|
||||
|
||||
enum aud_status_t {
|
||||
AUD_IDLE = 0,
|
||||
AUD_STOPPED,
|
||||
AUD_DECODING,
|
||||
AUD_PAUSED
|
||||
};
|
||||
|
||||
struct icm_open_resp_info_t {
|
||||
u32 proc_id;
|
||||
struct timestamp_info_t *dtstamp;
|
||||
s32 ret;
|
||||
};
|
||||
|
||||
struct lib_dnld_info_t {
|
||||
unsigned long pbuf_code;
|
||||
unsigned long pbuf_data;
|
||||
unsigned int size_code;
|
||||
unsigned int size_data;
|
||||
struct xtlib_pil_info *ppil_inf;
|
||||
unsigned int lib_on_dpu; /* 0: not loaded, 1: loaded. */
|
||||
};
|
||||
|
||||
|
||||
struct icm_pilib_size_t {
|
||||
u32 codec_type;
|
||||
u32 text_size;
|
||||
u32 data_size;
|
||||
};
|
||||
|
||||
struct fsl_hifi4 {
|
||||
struct device *dev;
|
||||
const char *fw_name;
|
||||
void __iomem *regs;
|
||||
void __iomem *mu_base_virtaddr;
|
||||
sc_ipc_t hifi_ipcHandle;
|
||||
sc_ipc_t mu_ipcHandle;
|
||||
unsigned int hifi_mu_id;
|
||||
int hifi_mu_init;
|
||||
unsigned long paddr;
|
||||
unsigned long dram0;
|
||||
unsigned long dram1;
|
||||
unsigned long iram;
|
||||
unsigned long sram;
|
||||
void *msg_buf_virt;
|
||||
dma_addr_t msg_buf_phys;
|
||||
int msg_buf_size;
|
||||
void *in_buf_virt;
|
||||
dma_addr_t in_buf_phys;
|
||||
int in_buf_size;
|
||||
void *out_buf_virt;
|
||||
dma_addr_t out_buf_phys;
|
||||
int out_buf_size;
|
||||
|
||||
void *code_buf_virt;
|
||||
dma_addr_t code_buf_phys;
|
||||
int code_buf_size;
|
||||
void *data_buf_virt;
|
||||
dma_addr_t data_buf_phys;
|
||||
int data_buf_size;
|
||||
void *scratch_buf_virt;
|
||||
dma_addr_t scratch_buf_phys;
|
||||
int scratch_buf_size;
|
||||
|
||||
int is_ready;
|
||||
int is_done;
|
||||
|
||||
struct completion cmd_complete;
|
||||
char *objmem;
|
||||
struct filename *objfile;
|
||||
char objtype;
|
||||
unsigned int start_addr;
|
||||
int ret_status;
|
||||
struct icm_cdc_iobuf_t codec_iobuf_info;
|
||||
struct icm_pcm_prop_t pcm_prop_info;
|
||||
struct xtlib_pil_info pil_info;
|
||||
struct xtlib_loader_globals xtlib_globals;
|
||||
};
|
||||
|
||||
struct fsl_hifi4_engine {
|
||||
struct fsl_hifi4 *hifi4_priv;
|
||||
};
|
||||
|
||||
struct hifi4_ext_msg {
|
||||
u32 phys;
|
||||
u32 size;
|
||||
};
|
||||
|
||||
struct hifi4_mem_msg {
|
||||
u32 ext_msg_phys;
|
||||
u32 ext_msg_size;
|
||||
u32 code_phys;
|
||||
u32 code_size;
|
||||
u32 data_phys;
|
||||
u32 data_size;
|
||||
u32 scratch_phys;
|
||||
u32 scratch_size;
|
||||
};
|
||||
|
||||
#define IRAM_OFFSET 0x10000
|
||||
#define IRAM_SIZE 2048
|
||||
|
||||
#define DRAM0_OFFSET 0x0
|
||||
#define DRAM0_SIZE 0x8000
|
||||
|
||||
#define DRAM1_OFFSET 0x8000
|
||||
#define DRAM1_SIZE 0x8000
|
||||
|
||||
#define SYSRAM_OFFSET 0x18000
|
||||
#define SYSRAM_SIZE 0x40000
|
||||
|
||||
#define SYSROM_OFFSET 0x58000
|
||||
#define SYSROM_SIZE 0x30000
|
||||
|
||||
#define LIBRARY_CODE_OFFSET 0x38000
|
||||
#define LIBRARY_CODE_SIZE 0x50000
|
||||
|
||||
#define MSG_BUF_SIZE 4096
|
||||
#define INPUT_BUF_SIZE 4096
|
||||
#define OUTPUT_BUF_SIZE 16384
|
||||
#define FIRMWARE_DATA_BUF_SIZE 0x100000
|
||||
#define SCRATCH_DATA_BUF_SIZE 0x100000
|
||||
|
||||
static void hifi4_load_firmware(const struct firmware *fw, void *context);
|
||||
u32 icm_intr_send(struct fsl_hifi4 *hifi4_priv, u32 msg);
|
||||
u32 icm_intr_extended_send(struct fsl_hifi4 *hifi4_priv, u32 msg,
|
||||
struct hifi4_ext_msg *ext_msg);
|
||||
long icm_ack_wait(struct fsl_hifi4 *hifi4_priv, u32 msg);
|
||||
|
||||
unsigned int xtlib_split_pi_library_size(
|
||||
struct xtlib_packaged_library *library,
|
||||
unsigned int *code_size,
|
||||
unsigned int *data_size,
|
||||
struct fsl_hifi4 *hifi4_priv);
|
||||
|
||||
xt_ptr xtlib_host_load_split_pi_library(
|
||||
struct xtlib_packaged_library *library,
|
||||
xt_ptr destination_code_address,
|
||||
xt_ptr destination_data_address,
|
||||
struct xtlib_pil_info *lib_info,
|
||||
memcpy_func mcpy_fn,
|
||||
memset_func mset_fn,
|
||||
struct fsl_hifi4 *hifi4_priv);
|
||||
|
||||
void *memcpy_hifi(void *dest, const void *src, size_t count);
|
||||
void *memset_hifi(void *dest, int c, size_t count);
|
||||
Reference in New Issue
Block a user