1*4882a593Smuzhiyun /* SPDX-License-Identifier: GPL-2.0-only */ 2*4882a593Smuzhiyun /* 3*4882a593Smuzhiyun * Skylake SST DSP Support 4*4882a593Smuzhiyun * 5*4882a593Smuzhiyun * Copyright (C) 2014-15, Intel Corporation. 6*4882a593Smuzhiyun */ 7*4882a593Smuzhiyun 8*4882a593Smuzhiyun #ifndef __SKL_SST_DSP_H__ 9*4882a593Smuzhiyun #define __SKL_SST_DSP_H__ 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun #include <linux/interrupt.h> 12*4882a593Smuzhiyun #include <linux/uuid.h> 13*4882a593Smuzhiyun #include <linux/firmware.h> 14*4882a593Smuzhiyun #include <sound/memalloc.h> 15*4882a593Smuzhiyun #include "skl-sst-cldma.h" 16*4882a593Smuzhiyun 17*4882a593Smuzhiyun struct sst_dsp; 18*4882a593Smuzhiyun struct sst_dsp_device; 19*4882a593Smuzhiyun struct skl_lib_info; 20*4882a593Smuzhiyun struct skl_dev; 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun /* Intel HD Audio General DSP Registers */ 23*4882a593Smuzhiyun #define SKL_ADSP_GEN_BASE 0x0 24*4882a593Smuzhiyun #define SKL_ADSP_REG_ADSPCS (SKL_ADSP_GEN_BASE + 0x04) 25*4882a593Smuzhiyun #define SKL_ADSP_REG_ADSPIC (SKL_ADSP_GEN_BASE + 0x08) 26*4882a593Smuzhiyun #define SKL_ADSP_REG_ADSPIS (SKL_ADSP_GEN_BASE + 0x0C) 27*4882a593Smuzhiyun #define SKL_ADSP_REG_ADSPIC2 (SKL_ADSP_GEN_BASE + 0x10) 28*4882a593Smuzhiyun #define SKL_ADSP_REG_ADSPIS2 (SKL_ADSP_GEN_BASE + 0x14) 29*4882a593Smuzhiyun 30*4882a593Smuzhiyun /* Intel HD Audio Inter-Processor Communication Registers */ 31*4882a593Smuzhiyun #define SKL_ADSP_IPC_BASE 0x40 32*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCT (SKL_ADSP_IPC_BASE + 0x00) 33*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCTE (SKL_ADSP_IPC_BASE + 0x04) 34*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCI (SKL_ADSP_IPC_BASE + 0x08) 35*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCIE (SKL_ADSP_IPC_BASE + 0x0C) 36*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCCTL (SKL_ADSP_IPC_BASE + 0x10) 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /* HIPCI */ 39*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCI_BUSY BIT(31) 40*4882a593Smuzhiyun 41*4882a593Smuzhiyun /* HIPCIE */ 42*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCIE_DONE BIT(30) 43*4882a593Smuzhiyun 44*4882a593Smuzhiyun /* HIPCCTL */ 45*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCCTL_DONE BIT(1) 46*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCCTL_BUSY BIT(0) 47*4882a593Smuzhiyun 48*4882a593Smuzhiyun /* HIPCT */ 49*4882a593Smuzhiyun #define SKL_ADSP_REG_HIPCT_BUSY BIT(31) 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun /* FW base IDs */ 52*4882a593Smuzhiyun #define SKL_INSTANCE_ID 0 53*4882a593Smuzhiyun #define SKL_BASE_FW_MODULE_ID 0 54*4882a593Smuzhiyun 55*4882a593Smuzhiyun /* Intel HD Audio SRAM Window 1 */ 56*4882a593Smuzhiyun #define SKL_ADSP_SRAM1_BASE 0xA000 57*4882a593Smuzhiyun 58*4882a593Smuzhiyun #define SKL_ADSP_MMIO_LEN 0x10000 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun #define SKL_ADSP_W0_STAT_SZ 0x1000 61*4882a593Smuzhiyun 62*4882a593Smuzhiyun #define SKL_ADSP_W0_UP_SZ 0x1000 63*4882a593Smuzhiyun 64*4882a593Smuzhiyun #define SKL_ADSP_W1_SZ 0x1000 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun #define SKL_FW_STS_MASK 0xf 67*4882a593Smuzhiyun 68*4882a593Smuzhiyun #define SKL_FW_INIT 0x1 69*4882a593Smuzhiyun #define SKL_FW_RFW_START 0xf 70*4882a593Smuzhiyun #define BXT_FW_ROM_INIT_RETRY 3 71*4882a593Smuzhiyun #define BXT_INIT_TIMEOUT 300 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun #define SKL_ADSPIC_IPC 1 74*4882a593Smuzhiyun #define SKL_ADSPIS_IPC 1 75*4882a593Smuzhiyun 76*4882a593Smuzhiyun /* Core ID of core0 */ 77*4882a593Smuzhiyun #define SKL_DSP_CORE0_ID 0 78*4882a593Smuzhiyun 79*4882a593Smuzhiyun /* Mask for a given core index, c = 0.. number of supported cores - 1 */ 80*4882a593Smuzhiyun #define SKL_DSP_CORE_MASK(c) BIT(c) 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun /* 83*4882a593Smuzhiyun * Core 0 mask = SKL_DSP_CORE_MASK(0); Defined separately 84*4882a593Smuzhiyun * since Core0 is primary core and it is used often 85*4882a593Smuzhiyun */ 86*4882a593Smuzhiyun #define SKL_DSP_CORE0_MASK BIT(0) 87*4882a593Smuzhiyun 88*4882a593Smuzhiyun /* 89*4882a593Smuzhiyun * Mask for a given number of cores 90*4882a593Smuzhiyun * nc = number of supported cores 91*4882a593Smuzhiyun */ 92*4882a593Smuzhiyun #define SKL_DSP_CORES_MASK(nc) GENMASK((nc - 1), 0) 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun /* ADSPCS - Audio DSP Control & Status */ 95*4882a593Smuzhiyun 96*4882a593Smuzhiyun /* 97*4882a593Smuzhiyun * Core Reset - asserted high 98*4882a593Smuzhiyun * CRST Mask for a given core mask pattern, cm 99*4882a593Smuzhiyun */ 100*4882a593Smuzhiyun #define SKL_ADSPCS_CRST_SHIFT 0 101*4882a593Smuzhiyun #define SKL_ADSPCS_CRST_MASK(cm) ((cm) << SKL_ADSPCS_CRST_SHIFT) 102*4882a593Smuzhiyun 103*4882a593Smuzhiyun /* 104*4882a593Smuzhiyun * Core run/stall - when set to '1' core is stalled 105*4882a593Smuzhiyun * CSTALL Mask for a given core mask pattern, cm 106*4882a593Smuzhiyun */ 107*4882a593Smuzhiyun #define SKL_ADSPCS_CSTALL_SHIFT 8 108*4882a593Smuzhiyun #define SKL_ADSPCS_CSTALL_MASK(cm) ((cm) << SKL_ADSPCS_CSTALL_SHIFT) 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun /* 111*4882a593Smuzhiyun * Set Power Active - when set to '1' turn cores on 112*4882a593Smuzhiyun * SPA Mask for a given core mask pattern, cm 113*4882a593Smuzhiyun */ 114*4882a593Smuzhiyun #define SKL_ADSPCS_SPA_SHIFT 16 115*4882a593Smuzhiyun #define SKL_ADSPCS_SPA_MASK(cm) ((cm) << SKL_ADSPCS_SPA_SHIFT) 116*4882a593Smuzhiyun 117*4882a593Smuzhiyun /* 118*4882a593Smuzhiyun * Current Power Active - power status of cores, set by hardware 119*4882a593Smuzhiyun * CPA Mask for a given core mask pattern, cm 120*4882a593Smuzhiyun */ 121*4882a593Smuzhiyun #define SKL_ADSPCS_CPA_SHIFT 24 122*4882a593Smuzhiyun #define SKL_ADSPCS_CPA_MASK(cm) ((cm) << SKL_ADSPCS_CPA_SHIFT) 123*4882a593Smuzhiyun 124*4882a593Smuzhiyun /* DSP Core state */ 125*4882a593Smuzhiyun enum skl_dsp_states { 126*4882a593Smuzhiyun SKL_DSP_RUNNING = 1, 127*4882a593Smuzhiyun /* Running in D0i3 state; can be in streaming or non-streaming D0i3 */ 128*4882a593Smuzhiyun SKL_DSP_RUNNING_D0I3, /* Running in D0i3 state*/ 129*4882a593Smuzhiyun SKL_DSP_RESET, 130*4882a593Smuzhiyun }; 131*4882a593Smuzhiyun 132*4882a593Smuzhiyun /* D0i3 substates */ 133*4882a593Smuzhiyun enum skl_dsp_d0i3_states { 134*4882a593Smuzhiyun SKL_DSP_D0I3_NONE = -1, /* No D0i3 */ 135*4882a593Smuzhiyun SKL_DSP_D0I3_NON_STREAMING = 0, 136*4882a593Smuzhiyun SKL_DSP_D0I3_STREAMING = 1, 137*4882a593Smuzhiyun }; 138*4882a593Smuzhiyun 139*4882a593Smuzhiyun struct skl_dsp_fw_ops { 140*4882a593Smuzhiyun int (*load_fw)(struct sst_dsp *ctx); 141*4882a593Smuzhiyun /* FW module parser/loader */ 142*4882a593Smuzhiyun int (*load_library)(struct sst_dsp *ctx, 143*4882a593Smuzhiyun struct skl_lib_info *linfo, int lib_count); 144*4882a593Smuzhiyun int (*parse_fw)(struct sst_dsp *ctx); 145*4882a593Smuzhiyun int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id); 146*4882a593Smuzhiyun int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id); 147*4882a593Smuzhiyun int (*set_state_D0i3)(struct sst_dsp *ctx); 148*4882a593Smuzhiyun int (*set_state_D0i0)(struct sst_dsp *ctx); 149*4882a593Smuzhiyun unsigned int (*get_fw_errcode)(struct sst_dsp *ctx); 150*4882a593Smuzhiyun int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, u8 *mod_name); 151*4882a593Smuzhiyun int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id); 152*4882a593Smuzhiyun 153*4882a593Smuzhiyun }; 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun struct skl_dsp_loader_ops { 156*4882a593Smuzhiyun int stream_tag; 157*4882a593Smuzhiyun 158*4882a593Smuzhiyun int (*alloc_dma_buf)(struct device *dev, 159*4882a593Smuzhiyun struct snd_dma_buffer *dmab, size_t size); 160*4882a593Smuzhiyun int (*free_dma_buf)(struct device *dev, 161*4882a593Smuzhiyun struct snd_dma_buffer *dmab); 162*4882a593Smuzhiyun int (*prepare)(struct device *dev, unsigned int format, 163*4882a593Smuzhiyun unsigned int byte_size, 164*4882a593Smuzhiyun struct snd_dma_buffer *bufp); 165*4882a593Smuzhiyun int (*trigger)(struct device *dev, bool start, int stream_tag); 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun int (*cleanup)(struct device *dev, struct snd_dma_buffer *dmab, 168*4882a593Smuzhiyun int stream_tag); 169*4882a593Smuzhiyun }; 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun #define MAX_INSTANCE_BUFF 2 172*4882a593Smuzhiyun 173*4882a593Smuzhiyun struct uuid_module { 174*4882a593Smuzhiyun guid_t uuid; 175*4882a593Smuzhiyun int id; 176*4882a593Smuzhiyun int is_loadable; 177*4882a593Smuzhiyun int max_instance; 178*4882a593Smuzhiyun u64 pvt_id[MAX_INSTANCE_BUFF]; 179*4882a593Smuzhiyun int *instance_id; 180*4882a593Smuzhiyun 181*4882a593Smuzhiyun struct list_head list; 182*4882a593Smuzhiyun }; 183*4882a593Smuzhiyun 184*4882a593Smuzhiyun struct skl_load_module_info { 185*4882a593Smuzhiyun u16 mod_id; 186*4882a593Smuzhiyun const struct firmware *fw; 187*4882a593Smuzhiyun }; 188*4882a593Smuzhiyun 189*4882a593Smuzhiyun struct skl_module_table { 190*4882a593Smuzhiyun struct skl_load_module_info *mod_info; 191*4882a593Smuzhiyun unsigned int usage_cnt; 192*4882a593Smuzhiyun struct list_head list; 193*4882a593Smuzhiyun }; 194*4882a593Smuzhiyun 195*4882a593Smuzhiyun void skl_cldma_process_intr(struct sst_dsp *ctx); 196*4882a593Smuzhiyun void skl_cldma_int_disable(struct sst_dsp *ctx); 197*4882a593Smuzhiyun int skl_cldma_prepare(struct sst_dsp *ctx); 198*4882a593Smuzhiyun int skl_cldma_wait_interruptible(struct sst_dsp *ctx); 199*4882a593Smuzhiyun 200*4882a593Smuzhiyun void skl_dsp_set_state_locked(struct sst_dsp *ctx, int state); 201*4882a593Smuzhiyun struct sst_dsp *skl_dsp_ctx_init(struct device *dev, 202*4882a593Smuzhiyun struct sst_dsp_device *sst_dev, int irq); 203*4882a593Smuzhiyun int skl_dsp_acquire_irq(struct sst_dsp *sst); 204*4882a593Smuzhiyun bool is_skl_dsp_running(struct sst_dsp *ctx); 205*4882a593Smuzhiyun 206*4882a593Smuzhiyun unsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx); 207*4882a593Smuzhiyun void skl_dsp_init_core_state(struct sst_dsp *ctx); 208*4882a593Smuzhiyun int skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask); 209*4882a593Smuzhiyun int skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask); 210*4882a593Smuzhiyun int skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask); 211*4882a593Smuzhiyun int skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask); 212*4882a593Smuzhiyun int skl_dsp_core_unset_reset_state(struct sst_dsp *ctx, 213*4882a593Smuzhiyun unsigned int core_mask); 214*4882a593Smuzhiyun int skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask); 215*4882a593Smuzhiyun 216*4882a593Smuzhiyun irqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id); 217*4882a593Smuzhiyun int skl_dsp_wake(struct sst_dsp *ctx); 218*4882a593Smuzhiyun int skl_dsp_sleep(struct sst_dsp *ctx); 219*4882a593Smuzhiyun void skl_dsp_free(struct sst_dsp *dsp); 220*4882a593Smuzhiyun 221*4882a593Smuzhiyun int skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id); 222*4882a593Smuzhiyun int skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id); 223*4882a593Smuzhiyun 224*4882a593Smuzhiyun int skl_dsp_boot(struct sst_dsp *ctx); 225*4882a593Smuzhiyun int skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 226*4882a593Smuzhiyun const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 227*4882a593Smuzhiyun struct skl_dev **dsp); 228*4882a593Smuzhiyun int bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq, 229*4882a593Smuzhiyun const char *fw_name, struct skl_dsp_loader_ops dsp_ops, 230*4882a593Smuzhiyun struct skl_dev **dsp); 231*4882a593Smuzhiyun int skl_sst_init_fw(struct device *dev, struct skl_dev *skl); 232*4882a593Smuzhiyun int bxt_sst_init_fw(struct device *dev, struct skl_dev *skl); 233*4882a593Smuzhiyun void skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl); 234*4882a593Smuzhiyun void bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl); 235*4882a593Smuzhiyun 236*4882a593Smuzhiyun int snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw, 237*4882a593Smuzhiyun unsigned int offset, int index); 238*4882a593Smuzhiyun int skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id); 239*4882a593Smuzhiyun int skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id); 240*4882a593Smuzhiyun int skl_get_pvt_instance_id_map(struct skl_dev *skl, 241*4882a593Smuzhiyun int module_id, int instance_id); 242*4882a593Smuzhiyun void skl_freeup_uuid_list(struct skl_dev *skl); 243*4882a593Smuzhiyun 244*4882a593Smuzhiyun int skl_dsp_strip_extended_manifest(struct firmware *fw); 245*4882a593Smuzhiyun 246*4882a593Smuzhiyun void skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data); 247*4882a593Smuzhiyun 248*4882a593Smuzhiyun int skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name, 249*4882a593Smuzhiyun struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp, 250*4882a593Smuzhiyun struct sst_dsp_device *skl_dev); 251*4882a593Smuzhiyun int skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo, 252*4882a593Smuzhiyun struct firmware *stripped_fw, 253*4882a593Smuzhiyun unsigned int hdr_offset, int index); 254*4882a593Smuzhiyun void skl_release_library(struct skl_lib_info *linfo, int lib_count); 255*4882a593Smuzhiyun 256*4882a593Smuzhiyun #endif /*__SKL_SST_DSP_H__*/ 257