brintos

brintos / linux-shallow public Read only

0
0
Text · 9.1 KiB · 854269f Raw
315 lines · c
1/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */2/*3 * This file is provided under a dual BSD/GPLv2 license. When using or4 * redistributing this file, you may do so under either license.5 *6 * Copyright(c) 2021 Advanced Micro Devices, Inc. All rights reserved.7 *8 * Author: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>9 */10 11#ifndef __AMD_ACP_H12#define __AMD_ACP_H13 14#include <sound/pcm.h>15#include <sound/soc.h>16#include <sound/soc-acpi.h>17#include <sound/soc-dai.h>18 19#include "chip_offset_byte.h"20 21#define ACP3X_DEV			322#define ACP6X_DEV			623#define ACP63_DEV			0x6324#define ACP70_DEV			0x7025#define ACP71_DEV			0x7126 27#define DMIC_INSTANCE			0x0028#define I2S_SP_INSTANCE			0x0129#define I2S_BT_INSTANCE			0x0230#define I2S_HS_INSTANCE			0x0331 32#define MEM_WINDOW_START		0x408000033 34#define ACP_I2S_REG_START		0x124240035#define ACP_I2S_REG_END			0x124281036#define ACP3x_I2STDM_REG_START		0x124240037#define ACP3x_I2STDM_REG_END		0x124241038#define ACP3x_BT_TDM_REG_START		0x124280039#define ACP3x_BT_TDM_REG_END		0x124281040 41#define THRESHOLD(bit, base)	((bit) + (base))42#define I2S_RX_THRESHOLD(base)	THRESHOLD(7, base)43#define I2S_TX_THRESHOLD(base)	THRESHOLD(8, base)44#define BT_TX_THRESHOLD(base)	THRESHOLD(6, base)45#define BT_RX_THRESHOLD(base)	THRESHOLD(5, base)46#define HS_TX_THRESHOLD(base)	THRESHOLD(4, base)47#define HS_RX_THRESHOLD(base)	THRESHOLD(3, base)48 49#define ACP_SRAM_SP_PB_PTE_OFFSET	0x050#define ACP_SRAM_SP_CP_PTE_OFFSET	0x10051#define ACP_SRAM_BT_PB_PTE_OFFSET	0x20052#define ACP_SRAM_BT_CP_PTE_OFFSET	0x30053#define ACP_SRAM_PDM_PTE_OFFSET		0x40054#define ACP_SRAM_HS_PB_PTE_OFFSET       0x50055#define ACP_SRAM_HS_CP_PTE_OFFSET       0x60056#define PAGE_SIZE_4K_ENABLE		0x257 58#define I2S_SP_TX_MEM_WINDOW_START	0x400000059#define I2S_SP_RX_MEM_WINDOW_START	0x402000060#define I2S_BT_TX_MEM_WINDOW_START	0x404000061#define I2S_BT_RX_MEM_WINDOW_START	0x406000062#define I2S_HS_TX_MEM_WINDOW_START      0x40A000063#define I2S_HS_RX_MEM_WINDOW_START      0x40C000064 65#define ACP7x_I2S_SP_TX_MEM_WINDOW_START	0x400000066#define ACP7x_I2S_SP_RX_MEM_WINDOW_START	0x420000067#define ACP7x_I2S_BT_TX_MEM_WINDOW_START	0x440000068#define ACP7x_I2S_BT_RX_MEM_WINDOW_START	0x460000069#define ACP7x_I2S_HS_TX_MEM_WINDOW_START	0x480000070#define ACP7x_I2S_HS_RX_MEM_WINDOW_START	0x4A0000071#define ACP7x_DMIC_MEM_WINDOW_START			0x4C0000072 73#define SP_PB_FIFO_ADDR_OFFSET		0x50074#define SP_CAPT_FIFO_ADDR_OFFSET	0x70075#define BT_PB_FIFO_ADDR_OFFSET		0x90076#define BT_CAPT_FIFO_ADDR_OFFSET	0xB0077#define HS_PB_FIFO_ADDR_OFFSET		0xD0078#define HS_CAPT_FIFO_ADDR_OFFSET	0xF0079#define PLAYBACK_MIN_NUM_PERIODS	280#define PLAYBACK_MAX_NUM_PERIODS	881#define PLAYBACK_MAX_PERIOD_SIZE	819282#define PLAYBACK_MIN_PERIOD_SIZE	102483#define CAPTURE_MIN_NUM_PERIODS		284#define CAPTURE_MAX_NUM_PERIODS		885#define CAPTURE_MAX_PERIOD_SIZE		819286#define CAPTURE_MIN_PERIOD_SIZE		102487 88#define MAX_BUFFER			6553689#define MIN_BUFFER			MAX_BUFFER90#define FIFO_SIZE			0x10091#define DMA_SIZE			0x4092#define FRM_LEN				0x10093 94#define ACP3x_ITER_IRER_SAMP_LEN_MASK	0x3895 96#define ACP_MAX_STREAM			897 98#define TDM_ENABLE	199#define TDM_DISABLE	0100 101#define SLOT_WIDTH_8	0x8102#define SLOT_WIDTH_16	0x10103#define SLOT_WIDTH_24	0x18104#define SLOT_WIDTH_32	0x20105 106#define ACP6X_PGFSM_CONTROL                     0x1024107#define ACP6X_PGFSM_STATUS                      0x1028108 109#define ACP63_PGFSM_CONTROL			ACP6X_PGFSM_CONTROL110#define ACP63_PGFSM_STATUS			ACP6X_PGFSM_STATUS111 112#define ACP70_PGFSM_CONTROL			ACP6X_PGFSM_CONTROL113#define ACP70_PGFSM_STATUS			ACP6X_PGFSM_STATUS114 115#define ACP_ZSC_DSP_CTRL			0x0001014116#define ACP_ZSC_STS				0x0001018117#define ACP_SOFT_RST_DONE_MASK	0x00010001118 119#define ACP_PGFSM_CNTL_POWER_ON_MASK            0xffffffff120#define ACP_PGFSM_CNTL_POWER_OFF_MASK           0x00121#define ACP_PGFSM_STATUS_MASK                   0x03122#define ACP_POWERED_ON                          0x00123#define ACP_POWER_ON_IN_PROGRESS                0x01124#define ACP_POWERED_OFF                         0x02125#define ACP_POWER_OFF_IN_PROGRESS               0x03126 127#define ACP_ERROR_MASK                          0x20000000128#define ACP_EXT_INTR_STAT_CLEAR_MASK            0xffffffff129 130#define ACP_TIMEOUT		500131#define DELAY_US		5132#define ACP_SUSPEND_DELAY_MS   2000133 134#define PDM_DMA_STAT            0x10135#define PDM_DMA_INTR_MASK       0x10000136#define PDM_DEC_64              0x2137#define PDM_CLK_FREQ_MASK       0x07138#define PDM_MISC_CTRL_MASK      0x10139#define PDM_ENABLE              0x01140#define PDM_DISABLE             0x00141#define DMA_EN_MASK             0x02142#define DELAY_US                5143#define PDM_TIMEOUT             1000144#define ACP_REGION2_OFFSET      0x02000000145 146struct acp_chip_info {147	char *name;		/* Platform name */148	unsigned int acp_rev;	/* ACP Revision id */149	void __iomem *base;	/* ACP memory PCI base */150	struct platform_device *chip_pdev;151	unsigned int flag;	/* Distinguish b/w Legacy or Only PDM */152	bool is_pdm_dev;	/* flag set to true when ACP PDM controller exists */153	bool is_pdm_config;	/* flag set to true when PDM configuration is selected from BIOS */154	bool is_i2s_config;	/* flag set to true when I2S configuration is selected from BIOS */155};156 157struct acp_stream {158	struct list_head list;159	struct snd_pcm_substream *substream;160	int irq_bit;161	int dai_id;162	int id;163	int dir;164	u64 bytescount;165	u32 reg_offset;166	u32 pte_offset;167	u32 fifo_offset;168};169 170struct acp_resource {171	int offset;172	int no_of_ctrls;173	int irqp_used;174	bool soc_mclk;175	u32 irq_reg_offset;176	u64 scratch_reg_offset;177	u64 sram_pte_offset;178};179 180struct acp_dev_data {181	char *name;182	struct device *dev;183	void __iomem *acp_base;184	unsigned int i2s_irq;185 186	bool tdm_mode;187	bool is_i2s_config;188	/* SOC specific dais */189	struct snd_soc_dai_driver *dai_driver;190	int num_dai;191 192	struct list_head stream_list;193	spinlock_t acp_lock;194 195	struct snd_soc_acpi_mach *machines;196	struct platform_device *mach_dev;197 198	u32 bclk_div;199	u32 lrclk_div;200 201	struct acp_resource *rsrc;202	u32 ch_mask;203	u32 tdm_tx_fmt[3];204	u32 tdm_rx_fmt[3];205	u32 xfer_tx_resolution[3];206	u32 xfer_rx_resolution[3];207	unsigned int flag;208	unsigned int platform;209};210 211enum acp_config {212	ACP_CONFIG_0 = 0,213	ACP_CONFIG_1,214	ACP_CONFIG_2,215	ACP_CONFIG_3,216	ACP_CONFIG_4,217	ACP_CONFIG_5,218	ACP_CONFIG_6,219	ACP_CONFIG_7,220	ACP_CONFIG_8,221	ACP_CONFIG_9,222	ACP_CONFIG_10,223	ACP_CONFIG_11,224	ACP_CONFIG_12,225	ACP_CONFIG_13,226	ACP_CONFIG_14,227	ACP_CONFIG_15,228	ACP_CONFIG_16,229	ACP_CONFIG_17,230	ACP_CONFIG_18,231	ACP_CONFIG_19,232	ACP_CONFIG_20,233};234 235extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops;236extern const struct snd_soc_dai_ops acp_dmic_dai_ops;237 238int acp_platform_register(struct device *dev);239int acp_platform_unregister(struct device *dev);240 241int acp_machine_select(struct acp_dev_data *adata);242 243int smn_read(struct pci_dev *dev, u32 smn_addr);244int smn_write(struct pci_dev *dev, u32 smn_addr, u32 data);245 246int acp_init(struct acp_chip_info *chip);247int acp_deinit(struct acp_chip_info *chip);248void acp_enable_interrupts(struct acp_dev_data *adata);249void acp_disable_interrupts(struct acp_dev_data *adata);250/* Machine configuration */251int snd_amd_acp_find_config(struct pci_dev *pci);252 253void config_pte_for_stream(struct acp_dev_data *adata, struct acp_stream *stream);254void config_acp_dma(struct acp_dev_data *adata, struct acp_stream *stream, int size);255void restore_acp_pdm_params(struct snd_pcm_substream *substream,256			    struct acp_dev_data *adata);257 258int restore_acp_i2s_params(struct snd_pcm_substream *substream,259			   struct acp_dev_data *adata, struct acp_stream *stream);260 261void check_acp_config(struct pci_dev *pci, struct acp_chip_info *chip);262 263static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction)264{265	u64 byte_count = 0, low = 0, high = 0;266 267	if (direction == SNDRV_PCM_STREAM_PLAYBACK) {268		switch (dai_id) {269		case I2S_BT_INSTANCE:270			high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH(adata));271			low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW(adata));272			break;273		case I2S_SP_INSTANCE:274			high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH(adata));275			low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW(adata));276			break;277		case I2S_HS_INSTANCE:278			high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH);279			low = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW);280			break;281		default:282			dev_err(adata->dev, "Invalid dai id %x\n", dai_id);283			goto POINTER_RETURN_BYTES;284		}285	} else {286		switch (dai_id) {287		case I2S_BT_INSTANCE:288			high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH(adata));289			low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW(adata));290			break;291		case I2S_SP_INSTANCE:292			high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH(adata));293			low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW(adata));294			break;295		case I2S_HS_INSTANCE:296			high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH);297			low = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW);298			break;299		case DMIC_INSTANCE:300			high = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);301			low = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);302			break;303		default:304			dev_err(adata->dev, "Invalid dai id %x\n", dai_id);305			goto POINTER_RETURN_BYTES;306		}307	}308	/* Get 64 bit value from two 32 bit registers */309	byte_count = (high << 32) | low;310 311POINTER_RETURN_BYTES:312	return byte_count;313}314#endif315