162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Skylake SST DSP Support
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2014-15, Intel Corporation.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#ifndef __SKL_SST_DSP_H__
962306a36Sopenharmony_ci#define __SKL_SST_DSP_H__
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include <linux/interrupt.h>
1262306a36Sopenharmony_ci#include <linux/uuid.h>
1362306a36Sopenharmony_ci#include <linux/firmware.h>
1462306a36Sopenharmony_ci#include <sound/memalloc.h>
1562306a36Sopenharmony_ci#include "skl-sst-cldma.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_cistruct sst_dsp;
1862306a36Sopenharmony_cistruct sst_dsp_device;
1962306a36Sopenharmony_cistruct skl_lib_info;
2062306a36Sopenharmony_cistruct skl_dev;
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci/* Intel HD Audio General DSP Registers */
2362306a36Sopenharmony_ci#define SKL_ADSP_GEN_BASE		0x0
2462306a36Sopenharmony_ci#define SKL_ADSP_REG_ADSPCS		(SKL_ADSP_GEN_BASE + 0x04)
2562306a36Sopenharmony_ci#define SKL_ADSP_REG_ADSPIC		(SKL_ADSP_GEN_BASE + 0x08)
2662306a36Sopenharmony_ci#define SKL_ADSP_REG_ADSPIS		(SKL_ADSP_GEN_BASE + 0x0C)
2762306a36Sopenharmony_ci#define SKL_ADSP_REG_ADSPIC2		(SKL_ADSP_GEN_BASE + 0x10)
2862306a36Sopenharmony_ci#define SKL_ADSP_REG_ADSPIS2		(SKL_ADSP_GEN_BASE + 0x14)
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/* Intel HD Audio Inter-Processor Communication Registers */
3162306a36Sopenharmony_ci#define SKL_ADSP_IPC_BASE		0x40
3262306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCT		(SKL_ADSP_IPC_BASE + 0x00)
3362306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCTE		(SKL_ADSP_IPC_BASE + 0x04)
3462306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCI		(SKL_ADSP_IPC_BASE + 0x08)
3562306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCIE		(SKL_ADSP_IPC_BASE + 0x0C)
3662306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCCTL		(SKL_ADSP_IPC_BASE + 0x10)
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/*  HIPCI */
3962306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCI_BUSY		BIT(31)
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/* HIPCIE */
4262306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCIE_DONE	BIT(30)
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci/* HIPCCTL */
4562306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCCTL_DONE	BIT(1)
4662306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCCTL_BUSY	BIT(0)
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci/* HIPCT */
4962306a36Sopenharmony_ci#define SKL_ADSP_REG_HIPCT_BUSY		BIT(31)
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci/* FW base IDs */
5262306a36Sopenharmony_ci#define SKL_INSTANCE_ID			0
5362306a36Sopenharmony_ci#define SKL_BASE_FW_MODULE_ID		0
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci/* Intel HD Audio SRAM Window 1 */
5662306a36Sopenharmony_ci#define SKL_ADSP_SRAM1_BASE		0xA000
5762306a36Sopenharmony_ci
5862306a36Sopenharmony_ci#define SKL_ADSP_MMIO_LEN		0x10000
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci#define SKL_ADSP_W0_STAT_SZ		0x1000
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci#define SKL_ADSP_W0_UP_SZ		0x1000
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci#define SKL_ADSP_W1_SZ			0x1000
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_ci#define SKL_FW_STS_MASK			0xf
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_ci#define SKL_FW_INIT			0x1
6962306a36Sopenharmony_ci#define SKL_FW_RFW_START		0xf
7062306a36Sopenharmony_ci#define BXT_FW_ROM_INIT_RETRY		3
7162306a36Sopenharmony_ci#define BXT_INIT_TIMEOUT		300
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci#define SKL_ADSPIC_IPC			1
7462306a36Sopenharmony_ci#define SKL_ADSPIS_IPC			1
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/* Core ID of core0 */
7762306a36Sopenharmony_ci#define SKL_DSP_CORE0_ID		0
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/* Mask for a given core index, c = 0.. number of supported cores - 1 */
8062306a36Sopenharmony_ci#define SKL_DSP_CORE_MASK(c)		BIT(c)
8162306a36Sopenharmony_ci
8262306a36Sopenharmony_ci/*
8362306a36Sopenharmony_ci * Core 0 mask = SKL_DSP_CORE_MASK(0); Defined separately
8462306a36Sopenharmony_ci * since Core0 is primary core and it is used often
8562306a36Sopenharmony_ci */
8662306a36Sopenharmony_ci#define SKL_DSP_CORE0_MASK		BIT(0)
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci/*
8962306a36Sopenharmony_ci * Mask for a given number of cores
9062306a36Sopenharmony_ci * nc = number of supported cores
9162306a36Sopenharmony_ci */
9262306a36Sopenharmony_ci#define SKL_DSP_CORES_MASK(nc)	GENMASK((nc - 1), 0)
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci/* ADSPCS - Audio DSP Control & Status */
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_ci/*
9762306a36Sopenharmony_ci * Core Reset - asserted high
9862306a36Sopenharmony_ci * CRST Mask for a given core mask pattern, cm
9962306a36Sopenharmony_ci */
10062306a36Sopenharmony_ci#define SKL_ADSPCS_CRST_SHIFT		0
10162306a36Sopenharmony_ci#define SKL_ADSPCS_CRST_MASK(cm)	((cm) << SKL_ADSPCS_CRST_SHIFT)
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/*
10462306a36Sopenharmony_ci * Core run/stall - when set to '1' core is stalled
10562306a36Sopenharmony_ci * CSTALL Mask for a given core mask pattern, cm
10662306a36Sopenharmony_ci */
10762306a36Sopenharmony_ci#define SKL_ADSPCS_CSTALL_SHIFT		8
10862306a36Sopenharmony_ci#define SKL_ADSPCS_CSTALL_MASK(cm)	((cm) << SKL_ADSPCS_CSTALL_SHIFT)
10962306a36Sopenharmony_ci
11062306a36Sopenharmony_ci/*
11162306a36Sopenharmony_ci * Set Power Active - when set to '1' turn cores on
11262306a36Sopenharmony_ci * SPA Mask for a given core mask pattern, cm
11362306a36Sopenharmony_ci */
11462306a36Sopenharmony_ci#define SKL_ADSPCS_SPA_SHIFT		16
11562306a36Sopenharmony_ci#define SKL_ADSPCS_SPA_MASK(cm)		((cm) << SKL_ADSPCS_SPA_SHIFT)
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci/*
11862306a36Sopenharmony_ci * Current Power Active - power status of cores, set by hardware
11962306a36Sopenharmony_ci * CPA Mask for a given core mask pattern, cm
12062306a36Sopenharmony_ci */
12162306a36Sopenharmony_ci#define SKL_ADSPCS_CPA_SHIFT		24
12262306a36Sopenharmony_ci#define SKL_ADSPCS_CPA_MASK(cm)		((cm) << SKL_ADSPCS_CPA_SHIFT)
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci/* DSP Core state */
12562306a36Sopenharmony_cienum skl_dsp_states {
12662306a36Sopenharmony_ci	SKL_DSP_RUNNING = 1,
12762306a36Sopenharmony_ci	/* Running in D0i3 state; can be in streaming or non-streaming D0i3 */
12862306a36Sopenharmony_ci	SKL_DSP_RUNNING_D0I3, /* Running in D0i3 state*/
12962306a36Sopenharmony_ci	SKL_DSP_RESET,
13062306a36Sopenharmony_ci};
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci/* D0i3 substates */
13362306a36Sopenharmony_cienum skl_dsp_d0i3_states {
13462306a36Sopenharmony_ci	SKL_DSP_D0I3_NONE = -1, /* No D0i3 */
13562306a36Sopenharmony_ci	SKL_DSP_D0I3_NON_STREAMING = 0,
13662306a36Sopenharmony_ci	SKL_DSP_D0I3_STREAMING = 1,
13762306a36Sopenharmony_ci};
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_cistruct skl_dsp_fw_ops {
14062306a36Sopenharmony_ci	int (*load_fw)(struct sst_dsp  *ctx);
14162306a36Sopenharmony_ci	/* FW module parser/loader */
14262306a36Sopenharmony_ci	int (*load_library)(struct sst_dsp *ctx,
14362306a36Sopenharmony_ci		struct skl_lib_info *linfo, int lib_count);
14462306a36Sopenharmony_ci	int (*parse_fw)(struct sst_dsp *ctx);
14562306a36Sopenharmony_ci	int (*set_state_D0)(struct sst_dsp *ctx, unsigned int core_id);
14662306a36Sopenharmony_ci	int (*set_state_D3)(struct sst_dsp *ctx, unsigned int core_id);
14762306a36Sopenharmony_ci	int (*set_state_D0i3)(struct sst_dsp *ctx);
14862306a36Sopenharmony_ci	int (*set_state_D0i0)(struct sst_dsp *ctx);
14962306a36Sopenharmony_ci	unsigned int (*get_fw_errcode)(struct sst_dsp *ctx);
15062306a36Sopenharmony_ci	int (*load_mod)(struct sst_dsp *ctx, u16 mod_id, u8 *mod_name);
15162306a36Sopenharmony_ci	int (*unload_mod)(struct sst_dsp *ctx, u16 mod_id);
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci};
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_cistruct skl_dsp_loader_ops {
15662306a36Sopenharmony_ci	int stream_tag;
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_ci	int (*alloc_dma_buf)(struct device *dev,
15962306a36Sopenharmony_ci		struct snd_dma_buffer *dmab, size_t size);
16062306a36Sopenharmony_ci	int (*free_dma_buf)(struct device *dev,
16162306a36Sopenharmony_ci		struct snd_dma_buffer *dmab);
16262306a36Sopenharmony_ci	int (*prepare)(struct device *dev, unsigned int format,
16362306a36Sopenharmony_ci				unsigned int byte_size,
16462306a36Sopenharmony_ci				struct snd_dma_buffer *bufp);
16562306a36Sopenharmony_ci	int (*trigger)(struct device *dev, bool start, int stream_tag);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	int (*cleanup)(struct device *dev, struct snd_dma_buffer *dmab,
16862306a36Sopenharmony_ci				 int stream_tag);
16962306a36Sopenharmony_ci};
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci#define MAX_INSTANCE_BUFF 2
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_cistruct uuid_module {
17462306a36Sopenharmony_ci	guid_t uuid;
17562306a36Sopenharmony_ci	int id;
17662306a36Sopenharmony_ci	int is_loadable;
17762306a36Sopenharmony_ci	int max_instance;
17862306a36Sopenharmony_ci	u64 pvt_id[MAX_INSTANCE_BUFF];
17962306a36Sopenharmony_ci	int *instance_id;
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	struct list_head list;
18262306a36Sopenharmony_ci};
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cistruct skl_load_module_info {
18562306a36Sopenharmony_ci	u16 mod_id;
18662306a36Sopenharmony_ci	const struct firmware *fw;
18762306a36Sopenharmony_ci};
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_cistruct skl_module_table {
19062306a36Sopenharmony_ci	struct skl_load_module_info *mod_info;
19162306a36Sopenharmony_ci	unsigned int usage_cnt;
19262306a36Sopenharmony_ci	struct list_head list;
19362306a36Sopenharmony_ci};
19462306a36Sopenharmony_ci
19562306a36Sopenharmony_civoid skl_cldma_process_intr(struct sst_dsp *ctx);
19662306a36Sopenharmony_civoid skl_cldma_int_disable(struct sst_dsp *ctx);
19762306a36Sopenharmony_ciint skl_cldma_prepare(struct sst_dsp *ctx);
19862306a36Sopenharmony_ciint skl_cldma_wait_interruptible(struct sst_dsp *ctx);
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_civoid skl_dsp_set_state_locked(struct sst_dsp *ctx, int state);
20162306a36Sopenharmony_cistruct sst_dsp *skl_dsp_ctx_init(struct device *dev,
20262306a36Sopenharmony_ci		struct sst_dsp_device *sst_dev, int irq);
20362306a36Sopenharmony_ciint skl_dsp_acquire_irq(struct sst_dsp *sst);
20462306a36Sopenharmony_cibool is_skl_dsp_running(struct sst_dsp *ctx);
20562306a36Sopenharmony_ci
20662306a36Sopenharmony_ciunsigned int skl_dsp_get_enabled_cores(struct sst_dsp *ctx);
20762306a36Sopenharmony_civoid skl_dsp_init_core_state(struct sst_dsp *ctx);
20862306a36Sopenharmony_ciint skl_dsp_enable_core(struct sst_dsp *ctx, unsigned int core_mask);
20962306a36Sopenharmony_ciint skl_dsp_disable_core(struct sst_dsp *ctx, unsigned int core_mask);
21062306a36Sopenharmony_ciint skl_dsp_core_power_up(struct sst_dsp *ctx, unsigned int core_mask);
21162306a36Sopenharmony_ciint skl_dsp_core_power_down(struct sst_dsp *ctx, unsigned int core_mask);
21262306a36Sopenharmony_ciint skl_dsp_core_unset_reset_state(struct sst_dsp *ctx,
21362306a36Sopenharmony_ci					unsigned int core_mask);
21462306a36Sopenharmony_ciint skl_dsp_start_core(struct sst_dsp *ctx, unsigned int core_mask);
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ciirqreturn_t skl_dsp_sst_interrupt(int irq, void *dev_id);
21762306a36Sopenharmony_ciint skl_dsp_wake(struct sst_dsp *ctx);
21862306a36Sopenharmony_ciint skl_dsp_sleep(struct sst_dsp *ctx);
21962306a36Sopenharmony_civoid skl_dsp_free(struct sst_dsp *dsp);
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ciint skl_dsp_get_core(struct sst_dsp *ctx, unsigned int core_id);
22262306a36Sopenharmony_ciint skl_dsp_put_core(struct sst_dsp *ctx, unsigned int core_id);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ciint skl_dsp_boot(struct sst_dsp *ctx);
22562306a36Sopenharmony_ciint skl_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
22662306a36Sopenharmony_ci		const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
22762306a36Sopenharmony_ci		struct skl_dev **dsp);
22862306a36Sopenharmony_ciint bxt_sst_dsp_init(struct device *dev, void __iomem *mmio_base, int irq,
22962306a36Sopenharmony_ci		const char *fw_name, struct skl_dsp_loader_ops dsp_ops,
23062306a36Sopenharmony_ci		struct skl_dev **dsp);
23162306a36Sopenharmony_ciint skl_sst_init_fw(struct device *dev, struct skl_dev *skl);
23262306a36Sopenharmony_ciint bxt_sst_init_fw(struct device *dev, struct skl_dev *skl);
23362306a36Sopenharmony_civoid skl_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
23462306a36Sopenharmony_civoid bxt_sst_dsp_cleanup(struct device *dev, struct skl_dev *skl);
23562306a36Sopenharmony_ci
23662306a36Sopenharmony_ciint snd_skl_parse_uuids(struct sst_dsp *ctx, const struct firmware *fw,
23762306a36Sopenharmony_ci				unsigned int offset, int index);
23862306a36Sopenharmony_ciint skl_get_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int instance_id);
23962306a36Sopenharmony_ciint skl_put_pvt_id(struct skl_dev *skl, guid_t *uuid_mod, int *pvt_id);
24062306a36Sopenharmony_ciint skl_get_pvt_instance_id_map(struct skl_dev *skl,
24162306a36Sopenharmony_ci				int module_id, int instance_id);
24262306a36Sopenharmony_civoid skl_freeup_uuid_list(struct skl_dev *skl);
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ciint skl_dsp_strip_extended_manifest(struct firmware *fw);
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_civoid skl_dsp_set_astate_cfg(struct skl_dev *skl, u32 cnt, void *data);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ciint skl_sst_ctx_init(struct device *dev, int irq, const char *fw_name,
24962306a36Sopenharmony_ci		struct skl_dsp_loader_ops dsp_ops, struct skl_dev **dsp,
25062306a36Sopenharmony_ci		struct sst_dsp_device *skl_dev);
25162306a36Sopenharmony_ciint skl_prepare_lib_load(struct skl_dev *skl, struct skl_lib_info *linfo,
25262306a36Sopenharmony_ci			struct firmware *stripped_fw,
25362306a36Sopenharmony_ci			unsigned int hdr_offset, int index);
25462306a36Sopenharmony_civoid skl_release_library(struct skl_lib_info *linfo, int lib_count);
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci#endif /*__SKL_SST_DSP_H__*/
257