531 lines · c
1/* SPDX-License-Identifier: GPL-2.0-only */2/*3 * sst.h - Intel SST Driver for audio engine4 *5 * Copyright (C) 2008-14 Intel Corporation6 * Authors: Vinod Koul <vinod.koul@intel.com>7 * Harsha Priya <priya.harsha@intel.com>8 * Dharageswari R <dharageswari.r@intel.com>9 * KP Jeeja <jeeja.kp@intel.com>10 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~11 *12 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~13 *14 * Common private declarations for SST15 */16#ifndef __SST_H__17#define __SST_H__18 19#include <linux/firmware.h>20 21/* driver names */22#define SST_DRV_NAME "intel_sst_driver"23 24#define SST_SUSPEND_DELAY 200025#define FW_CONTEXT_MEM (64*1024)26#define SST_ICCM_BOUNDARY 427#define SST_CONFIG_SSP_SIGN 0x7ffe800128 29#define MRFLD_FW_VIRTUAL_BASE 0xC000000030#define MRFLD_FW_DDR_BASE_OFFSET 0x031#define MRFLD_FW_FEATURE_BASE_OFFSET 0x432#define MRFLD_FW_BSS_RESET_BIT 033 34/* SST Shim register map */35#define SST_CSR 0x0036#define SST_ISRX 0x1837#define SST_IMRX 0x2838#define SST_IPCX 0x38 /* IPC IA -> SST */39#define SST_IPCD 0x40 /* IPC SST -> IA */40 41extern const struct dev_pm_ops intel_sst_pm;42enum sst_states {43 SST_FW_LOADING = 1,44 SST_FW_RUNNING,45 SST_RESET,46 SST_SHUTDOWN,47};48 49enum sst_algo_ops {50 SST_SET_ALGO = 0,51 SST_GET_ALGO = 1,52};53 54#define SST_BLOCK_TIMEOUT 100055 56#define FW_SIGNATURE_SIZE 457#define FW_NAME_SIZE 3258 59/* stream states */60enum sst_stream_states {61 STREAM_UN_INIT = 0, /* Freed/Not used stream */62 STREAM_RUNNING = 1, /* Running */63 STREAM_PAUSED = 2, /* Paused stream */64 STREAM_INIT = 3, /* stream init, waiting for data */65};66 67enum sst_ram_type {68 SST_IRAM = 1,69 SST_DRAM = 2,70 SST_DDR = 5,71 SST_CUSTOM_INFO = 7, /* consists of FW binary information */72};73 74/* SST shim registers to structure mapping */75union interrupt_reg {76 struct {77 u64 done_interrupt:1;78 u64 busy_interrupt:1;79 u64 rsvd:62;80 } part;81 u64 full;82};83 84union sst_pisr_reg {85 struct {86 u32 pssp0:1;87 u32 pssp1:1;88 u32 rsvd0:3;89 u32 dmac:1;90 u32 rsvd1:26;91 } part;92 u32 full;93};94 95union sst_pimr_reg {96 struct {97 u32 ssp0:1;98 u32 ssp1:1;99 u32 rsvd0:3;100 u32 dmac:1;101 u32 rsvd1:10;102 u32 ssp0_sc:1;103 u32 ssp1_sc:1;104 u32 rsvd2:3;105 u32 dmac_sc:1;106 u32 rsvd3:10;107 } part;108 u32 full;109};110 111union config_status_reg_mrfld {112 struct {113 u64 lpe_reset:1;114 u64 lpe_reset_vector:1;115 u64 runstall:1;116 u64 pwaitmode:1;117 u64 clk_sel:3;118 u64 rsvd2:1;119 u64 sst_clk:3;120 u64 xt_snoop:1;121 u64 rsvd3:4;122 u64 clk_sel1:6;123 u64 clk_enable:3;124 u64 rsvd4:6;125 u64 slim0baseclk:1;126 u64 rsvd:32;127 } part;128 u64 full;129};130 131union interrupt_reg_mrfld {132 struct {133 u64 done_interrupt:1;134 u64 busy_interrupt:1;135 u64 rsvd:62;136 } part;137 u64 full;138};139 140union sst_imr_reg_mrfld {141 struct {142 u64 done_interrupt:1;143 u64 busy_interrupt:1;144 u64 rsvd:62;145 } part;146 u64 full;147};148 149/**150 * struct sst_block - This structure is used to block a user/fw data call to another151 * fw/user call152 *153 * @condition: condition for blocking check154 * @ret_code: ret code when block is released155 * @data: data ptr156 * @size: size of data157 * @on: block condition158 * @msg_id: msg_id = msgid in mfld/ctp, mrfld = NULL159 * @drv_id: str_id in mfld/ctp, = drv_id in mrfld160 * @node: list head node161 */162struct sst_block {163 bool condition;164 int ret_code;165 void *data;166 u32 size;167 bool on;168 u32 msg_id;169 u32 drv_id;170 struct list_head node;171};172 173/**174 * struct stream_info - structure that holds the stream information175 *176 * @status : stream current state177 * @prev : stream prev state178 * @resume_status : stream current state to restore on resume179 * @resume_prev : stream prev state to restore on resume180 * @lock : stream mutex for protecting state181 * @alloc_param : parameters used for stream (re-)allocation182 * @pcm_substream : PCM substream183 * @period_elapsed : PCM period elapsed callback184 * @sfreq : stream sampling freq185 * @cumm_bytes : cummulative bytes decoded186 */187struct stream_info {188 unsigned int status;189 unsigned int prev;190 unsigned int resume_status;191 unsigned int resume_prev;192 struct mutex lock;193 struct snd_sst_alloc_mrfld alloc_param;194 195 void *pcm_substream;196 void (*period_elapsed)(void *pcm_substream);197 198 unsigned int sfreq;199 u32 cumm_bytes;200 201 void *compr_cb_param;202 void (*compr_cb)(void *compr_cb_param);203 204 void *drain_cb_param;205 void (*drain_notify)(void *drain_cb_param);206 207 unsigned int num_ch;208 unsigned int pipe_id;209 unsigned int task_id;210};211 212#define SST_FW_SIGN "$SST"213#define SST_FW_LIB_SIGN "$LIB"214 215/**216 * struct sst_fw_header - FW file headers217 *218 * @signature : FW signature219 * @file_size: size of fw image220 * @modules : # of modules221 * @file_format : version of header format222 * @reserved : reserved fields223 */224struct sst_fw_header {225 unsigned char signature[FW_SIGNATURE_SIZE];226 u32 file_size;227 u32 modules;228 u32 file_format;229 u32 reserved[4];230};231 232/**233 * struct fw_module_header - module header in FW234 *235 * @signature: module signature236 * @mod_size: size of module237 * @blocks: block count238 * @type: block type239 * @entry_point: module netry point240 */241struct fw_module_header {242 unsigned char signature[FW_SIGNATURE_SIZE];243 u32 mod_size;244 u32 blocks;245 u32 type;246 u32 entry_point;247};248 249/**250 * struct fw_block_info - block header for FW251 *252 * @type: block ram type I/D253 * @size: size of block254 * @ram_offset: offset in ram255 */256struct fw_block_info {257 enum sst_ram_type type;258 u32 size;259 u32 ram_offset;260 u32 rsvd;261};262 263struct sst_runtime_param {264 struct snd_sst_runtime_params param;265};266 267struct sst_sg_list {268 struct scatterlist *src;269 struct scatterlist *dst;270 int list_len;271 unsigned int sg_idx;272};273 274struct sst_memcpy_list {275 struct list_head memcpylist;276 void *dstn;277 const void *src;278 u32 size;279 bool is_io;280};281 282/*Firmware Module Information*/283enum sst_lib_dwnld_status {284 SST_LIB_NOT_FOUND = 0,285 SST_LIB_FOUND,286 SST_LIB_DOWNLOADED,287};288 289struct sst_module_info {290 const char *name; /*Library name*/291 u32 id; /*Module ID*/292 u32 entry_pt; /*Module entry point*/293 u8 status; /*module status*/294 u8 rsvd1;295 u16 rsvd2;296};297 298/*299 * Structure for managing the Library Region(1.5MB)300 * in DDR in Merrifield301 */302struct sst_mem_mgr {303 phys_addr_t current_base;304 int avail;305 unsigned int count;306};307 308struct sst_ipc_reg {309 int ipcx;310 int ipcd;311};312 313struct sst_fw_save {314 void *iram; /* allocated via kvmalloc() */315 void *dram; /* allocated via kvmalloc() */316 void *sram; /* allocated via kvmalloc() */317 void *ddr; /* allocated via kvmalloc() */318};319 320/**321 * struct intel_sst_drv - driver ops322 *323 * @sst_state : current sst device state324 * @dev_id : device identifier, pci_id for pci devices and acpi_id for acpi325 * devices326 * @shim : SST shim pointer327 * @mailbox : SST mailbox pointer328 * @iram : SST IRAM pointer329 * @dram : SST DRAM pointer330 * @pdata : SST info passed as a part of pci platform data331 * @shim_phy_add : SST shim phy addr332 * @ipc_dispatch_list : ipc messages dispatched333 * @rx_list : to copy the process_reply/process_msg from DSP334 * @ipc_post_msg_wq : wq to post IPC messages context335 * @mad_ops : MAD driver operations registered336 * @mad_wq : MAD driver wq337 * @post_msg_wq : wq to post IPC messages338 * @streams : sst stream contexts339 * @list_lock : sst driver list lock (deprecated)340 * @ipc_spin_lock : spin lock to handle audio shim access and ipc queue341 * @block_lock : spin lock to add block to block_list and assign pvt_id342 * @rx_msg_lock : spin lock to handle the rx messages from the DSP343 * @scard_ops : sst card ops344 * @pci : sst pci device struture345 * @dev : pointer to current device struct346 * @sst_lock : sst device lock347 * @pvt_id : sst private id348 * @stream_cnt : total sst active stream count349 * @pb_streams : total active pb streams350 * @cp_streams : total active cp streams351 * @audio_start : audio status352 * @qos : PM Qos struct353 * firmware_name : Firmware / Library name354 */355struct intel_sst_drv {356 int sst_state;357 int irq_num;358 unsigned short dev_id;359 void __iomem *ddr;360 void __iomem *shim;361 void __iomem *mailbox;362 void __iomem *iram;363 void __iomem *dram;364 unsigned int mailbox_add;365 unsigned int iram_base;366 unsigned int dram_base;367 unsigned int shim_phy_add;368 unsigned int iram_end;369 unsigned int dram_end;370 unsigned int ddr_end;371 unsigned int ddr_base;372 unsigned int mailbox_recv_offset;373 struct list_head block_list;374 struct list_head ipc_dispatch_list;375 struct sst_platform_info *pdata;376 struct list_head rx_list;377 struct work_struct ipc_post_msg_wq;378 wait_queue_head_t wait_queue;379 struct workqueue_struct *post_msg_wq;380 unsigned int tstamp;381 /* str_id 0 is not used */382 struct stream_info streams[MAX_NUM_STREAMS+1];383 spinlock_t ipc_spin_lock;384 spinlock_t block_lock;385 spinlock_t rx_msg_lock;386 struct pci_dev *pci;387 struct device *dev;388 volatile long unsigned pvt_id;389 struct mutex sst_lock;390 unsigned int stream_cnt;391 unsigned int csr_value;392 void *fw_in_mem;393 struct sst_sg_list fw_sg_list, library_list;394 struct intel_sst_ops *ops;395 struct sst_info info;396 struct pm_qos_request *qos;397 unsigned int use_dma;398 unsigned int use_lli;399 atomic_t fw_clear_context;400 bool lib_dwnld_reqd;401 struct list_head memcpy_list;402 struct sst_ipc_reg ipc_reg;403 struct sst_mem_mgr lib_mem_mgr;404 /*405 * Holder for firmware name. Due to async call it needs to be406 * persistent till worker thread gets called407 */408 char firmware_name[FW_NAME_SIZE];409 410 struct snd_sst_fw_version fw_version;411 struct sst_fw_save *fw_save;412};413 414/* misc definitions */415#define FW_DWNL_ID 0x01416 417struct intel_sst_ops {418 irqreturn_t (*interrupt)(int, void *);419 irqreturn_t (*irq_thread)(int, void *);420 void (*clear_interrupt)(struct intel_sst_drv *ctx);421 int (*start)(struct intel_sst_drv *ctx);422 int (*reset)(struct intel_sst_drv *ctx);423 void (*process_reply)(struct intel_sst_drv *ctx, struct ipc_post *msg);424 int (*post_message)(struct intel_sst_drv *ctx,425 struct ipc_post *msg, bool sync);426 void (*process_message)(struct ipc_post *msg);427 void (*set_bypass)(bool set);428 int (*save_dsp_context)(struct intel_sst_drv *sst);429 void (*restore_dsp_context)(void);430 int (*alloc_stream)(struct intel_sst_drv *ctx, void *params);431 void (*post_download)(struct intel_sst_drv *sst);432};433 434int sst_realloc_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);435int sst_pause_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);436int sst_resume_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);437int sst_drop_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);438int sst_free_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);439int sst_start_stream(struct intel_sst_drv *sst_drv_ctx, int str_id);440int sst_send_byte_stream_mrfld(struct intel_sst_drv *sst_drv_ctx,441 struct snd_sst_bytes_v2 *bytes);442int sst_set_stream_param(int str_id, struct snd_sst_params *str_param);443int sst_set_metadata(int str_id, char *params);444int sst_get_stream(struct intel_sst_drv *ctx,445 struct snd_sst_params *str_param);446int sst_get_stream_allocated(struct intel_sst_drv *ctx,447 struct snd_sst_params *str_param,448 struct snd_sst_lib_download **lib_dnld);449int sst_drain_stream(struct intel_sst_drv *sst_drv_ctx,450 int str_id, bool partial_drain);451int sst_post_message_mrfld(struct intel_sst_drv *sst_drv_ctx,452 struct ipc_post *ipc_msg, bool sync);453void sst_process_reply_mrfld(struct intel_sst_drv *sst_drv_ctx, struct ipc_post *msg);454int sst_start_mrfld(struct intel_sst_drv *sst_drv_ctx);455int intel_sst_reset_dsp_mrfld(struct intel_sst_drv *sst_drv_ctx);456void intel_sst_clear_intr_mrfld(struct intel_sst_drv *sst_drv_ctx);457 458int sst_load_fw(struct intel_sst_drv *sst_drv_ctx);459int sst_load_library(struct snd_sst_lib_download *lib, u8 ops);460void sst_post_download_mrfld(struct intel_sst_drv *ctx);461int sst_get_block_stream(struct intel_sst_drv *sst_drv_ctx);462void sst_memcpy_free_resources(struct intel_sst_drv *sst_drv_ctx);463 464int sst_wait_interruptible(struct intel_sst_drv *sst_drv_ctx,465 struct sst_block *block);466int sst_wait_timeout(struct intel_sst_drv *sst_drv_ctx,467 struct sst_block *block);468int sst_create_ipc_msg(struct ipc_post **arg, bool large);469int free_stream_context(struct intel_sst_drv *ctx, unsigned int str_id);470void sst_clean_stream(struct stream_info *stream);471int intel_sst_register_compress(struct intel_sst_drv *sst);472int intel_sst_remove_compress(struct intel_sst_drv *sst);473void sst_cdev_fragment_elapsed(struct intel_sst_drv *ctx, int str_id);474int sst_send_sync_msg(int ipc, int str_id);475int sst_get_num_channel(struct snd_sst_params *str_param);476int sst_get_sfreq(struct snd_sst_params *str_param);477int sst_alloc_stream_mrfld(struct intel_sst_drv *sst_drv_ctx, void *params);478void sst_restore_fw_context(void);479struct sst_block *sst_create_block(struct intel_sst_drv *ctx,480 u32 msg_id, u32 drv_id);481int sst_create_block_and_ipc_msg(struct ipc_post **arg, bool large,482 struct intel_sst_drv *sst_drv_ctx, struct sst_block **block,483 u32 msg_id, u32 drv_id);484int sst_free_block(struct intel_sst_drv *ctx, struct sst_block *freed);485int sst_wake_up_block(struct intel_sst_drv *ctx, int result,486 u32 drv_id, u32 ipc, void *data, u32 size);487int sst_request_firmware_async(struct intel_sst_drv *ctx);488int sst_driver_ops(struct intel_sst_drv *sst);489struct sst_platform_info *sst_get_acpi_driver_data(const char *hid);490void sst_firmware_load_cb(const struct firmware *fw, void *context);491int sst_prepare_and_post_msg(struct intel_sst_drv *sst,492 int task_id, int ipc_msg, int cmd_id, int pipe_id,493 size_t mbox_data_len, const void *mbox_data, void **data,494 bool large, bool fill_dsp, bool sync, bool response);495 496void sst_process_pending_msg(struct work_struct *work);497int sst_assign_pvt_id(struct intel_sst_drv *drv);498int sst_validate_strid(struct intel_sst_drv *sst_drv_ctx, int str_id);499struct stream_info *get_stream_info(struct intel_sst_drv *sst_drv_ctx,500 int str_id);501int get_stream_id_mrfld(struct intel_sst_drv *sst_drv_ctx,502 u32 pipe_id);503u32 relocate_imr_addr_mrfld(u32 base_addr);504void sst_add_to_dispatch_list_and_post(struct intel_sst_drv *sst,505 struct ipc_post *msg);506int sst_pm_runtime_put(struct intel_sst_drv *sst_drv);507int sst_shim_write(void __iomem *addr, int offset, int value);508u32 sst_shim_read(void __iomem *addr, int offset);509u64 sst_reg_read64(void __iomem *addr, int offset);510int sst_shim_write64(void __iomem *addr, int offset, u64 value);511u64 sst_shim_read64(void __iomem *addr, int offset);512void sst_set_fw_state_locked(513 struct intel_sst_drv *sst_drv_ctx, int sst_state);514void sst_fill_header_mrfld(union ipc_header_mrfld *header,515 int msg, int task_id, int large, int drv_id);516void sst_fill_header_dsp(struct ipc_dsp_hdr *dsp, int msg,517 int pipe_id, int len);518 519int sst_register(struct device *);520int sst_unregister(struct device *);521 522int sst_alloc_drv_context(struct intel_sst_drv **ctx,523 struct device *dev, unsigned short dev_id);524int sst_context_init(struct intel_sst_drv *ctx);525void sst_context_cleanup(struct intel_sst_drv *ctx);526void sst_configure_runtime_pm(struct intel_sst_drv *ctx);527void memcpy32_toio(void __iomem *dst, const void *src, int count);528void memcpy32_fromio(void *dst, const void __iomem *src, int count);529 530#endif531