brintos

brintos / linux-shallow public Read only

0
0
Text · 5.6 KiB · ac1936a Raw
225 lines · c
1/* SPDX-License-Identifier: GPL-2.0+ */2/*3 * AMD ALSA SoC PCM Driver4 *5 * Copyright (C) 2021 Advanced Micro Devices, Inc. All rights reserved.6 */7 8#include "vg_chip_offset_byte.h"9#include <sound/pcm.h>10 11#define ACP5x_PHY_BASE_ADDRESS 0x124000012#define ACP_DEVICE_ID 0x15E213#define ACP_SOFT_RESET_SOFTRESET_AUDDONE_MASK	0x0001000114 15#define ACP_PGFSM_CNTL_POWER_ON_MASK	0x0116#define ACP_PGFSM_CNTL_POWER_OFF_MASK	0x0017#define ACP_PGFSM_STATUS_MASK		0x0318#define ACP_POWERED_ON			0x0019#define ACP_POWER_ON_IN_PROGRESS	0x0120#define ACP_POWERED_OFF			0x0221#define ACP_POWER_OFF_IN_PROGRESS	0x0322 23#define ACP_ERR_INTR_MASK	0x2000000024#define ACP_EXT_INTR_STAT_CLEAR_MASK 0xFFFFFFFF25 26#define ACP5x_DEVS 427#define	ACP5x_REG_START	0x124000028#define	ACP5x_REG_END	0x125020029#define ACP5x_I2STDM_REG_START	0x124240030#define ACP5x_I2STDM_REG_END	0x124241031#define ACP5x_HS_TDM_REG_START	0x124281432#define ACP5x_HS_TDM_REG_END	0x124282433#define I2S_MODE 034#define ACP5x_I2S_MODE 135#define ACP5x_RES 436#define	I2S_RX_THRESHOLD 2737#define	I2S_TX_THRESHOLD 2838#define	HS_TX_THRESHOLD 2439#define	HS_RX_THRESHOLD 2340 41#define I2S_SP_INSTANCE                 142#define I2S_HS_INSTANCE                 243 44#define ACP_SRAM_PTE_OFFSET	0x0205000045#define ACP_SRAM_SP_PB_PTE_OFFSET	0x046#define ACP_SRAM_SP_CP_PTE_OFFSET	0x10047#define ACP_SRAM_HS_PB_PTE_OFFSET	0x20048#define ACP_SRAM_HS_CP_PTE_OFFSET	0x30049#define PAGE_SIZE_4K_ENABLE 0x250#define I2S_SP_TX_MEM_WINDOW_START	0x400000051#define I2S_SP_RX_MEM_WINDOW_START	0x402000052#define I2S_HS_TX_MEM_WINDOW_START	0x404000053#define I2S_HS_RX_MEM_WINDOW_START	0x406000054 55#define SP_PB_FIFO_ADDR_OFFSET		0x50056#define SP_CAPT_FIFO_ADDR_OFFSET	0x70057#define HS_PB_FIFO_ADDR_OFFSET		0x90058#define HS_CAPT_FIFO_ADDR_OFFSET	0xB0059#define PLAYBACK_MIN_NUM_PERIODS    260#define PLAYBACK_MAX_NUM_PERIODS    861#define PLAYBACK_MAX_PERIOD_SIZE    819262#define PLAYBACK_MIN_PERIOD_SIZE    102463#define CAPTURE_MIN_NUM_PERIODS     264#define CAPTURE_MAX_NUM_PERIODS     865#define CAPTURE_MAX_PERIOD_SIZE     819266#define CAPTURE_MIN_PERIOD_SIZE     102467 68#define MAX_BUFFER (PLAYBACK_MAX_PERIOD_SIZE * PLAYBACK_MAX_NUM_PERIODS)69#define MIN_BUFFER MAX_BUFFER70#define FIFO_SIZE 0x10071#define DMA_SIZE 0x4072#define FRM_LEN 0x10073 74#define I2S_MASTER_MODE_ENABLE 175#define I2S_MASTER_MODE_DISABLE 076 77#define SLOT_WIDTH_8 878#define SLOT_WIDTH_16 1679#define SLOT_WIDTH_24 2480#define SLOT_WIDTH_32 3281#define TDM_ENABLE 182#define TDM_DISABLE 083#define ACP5x_ITER_IRER_SAMP_LEN_MASK	0x3884 85struct i2s_dev_data {86	bool tdm_mode;87	bool master_mode;88	int i2s_irq;89	u16 i2s_instance;90	u32 tdm_fmt;91	void __iomem *acp5x_base;92	struct snd_pcm_substream *play_stream;93	struct snd_pcm_substream *capture_stream;94	struct snd_pcm_substream *i2ssp_play_stream;95	struct snd_pcm_substream *i2ssp_capture_stream;96};97 98struct i2s_stream_instance {99	u16 num_pages;100	u16 i2s_instance;101	u16 direction;102	u16 channels;103	u32 xfer_resolution;104	u32 val;105	dma_addr_t dma_addr;106	u64 bytescount;107	void __iomem *acp5x_base;108	u32 lrclk_div;109	u32 bclk_div;110};111 112union acp_dma_count {113	struct {114		u32 low;115		u32 high;116	} bcount;117	u64 bytescount;118};119 120struct acp5x_platform_info {121	u16 play_i2s_instance;122	u16 cap_i2s_instance;123};124 125union acp_i2stdm_mstrclkgen {126	struct {127		u32 i2stdm_master_mode : 1;128		u32 i2stdm_format_mode : 1;129		u32 i2stdm_lrclk_div_val : 9;130		u32 i2stdm_bclk_div_val : 11;131		u32:10;132	} bitfields, bits;133	u32  u32_all;134};135 136/* common header file uses exact offset rather than relative137 * offset which requires subtraction logic from base_addr138 * for accessing ACP5x MMIO space registers139 */140static inline u32 acp_readl(void __iomem *base_addr)141{142	return readl(base_addr - ACP5x_PHY_BASE_ADDRESS);143}144 145static inline void acp_writel(u32 val, void __iomem *base_addr)146{147	writel(val, base_addr - ACP5x_PHY_BASE_ADDRESS);148}149 150int snd_amd_acp_find_config(struct pci_dev *pci);151 152static inline u64 acp_get_byte_count(struct i2s_stream_instance *rtd,153				     int direction)154{155	union acp_dma_count byte_count;156 157	if (direction == SNDRV_PCM_STREAM_PLAYBACK) {158		switch (rtd->i2s_instance) {159		case I2S_HS_INSTANCE:160			byte_count.bcount.high =161				acp_readl(rtd->acp5x_base +162					  ACP_HS_TX_LINEARPOSCNTR_HIGH);163			byte_count.bcount.low =164				acp_readl(rtd->acp5x_base +165					  ACP_HS_TX_LINEARPOSCNTR_LOW);166			break;167		case I2S_SP_INSTANCE:168		default:169			byte_count.bcount.high =170				acp_readl(rtd->acp5x_base +171					  ACP_I2S_TX_LINEARPOSCNTR_HIGH);172			byte_count.bcount.low =173				acp_readl(rtd->acp5x_base +174					  ACP_I2S_TX_LINEARPOSCNTR_LOW);175		}176	} else {177		switch (rtd->i2s_instance) {178		case I2S_HS_INSTANCE:179			byte_count.bcount.high =180				acp_readl(rtd->acp5x_base +181					  ACP_HS_RX_LINEARPOSCNTR_HIGH);182			byte_count.bcount.low =183				acp_readl(rtd->acp5x_base +184					  ACP_HS_RX_LINEARPOSCNTR_LOW);185			break;186		case I2S_SP_INSTANCE:187		default:188			byte_count.bcount.high =189				acp_readl(rtd->acp5x_base +190					  ACP_I2S_RX_LINEARPOSCNTR_HIGH);191			byte_count.bcount.low =192				acp_readl(rtd->acp5x_base +193					  ACP_I2S_RX_LINEARPOSCNTR_LOW);194		}195	}196	return byte_count.bytescount;197}198 199static inline void acp5x_set_i2s_clk(struct i2s_dev_data *adata,200				     struct i2s_stream_instance *rtd)201{202	union acp_i2stdm_mstrclkgen mclkgen;203	u32 master_reg;204 205	switch (rtd->i2s_instance) {206	case I2S_HS_INSTANCE:207		master_reg = ACP_I2STDM2_MSTRCLKGEN;208		break;209	case I2S_SP_INSTANCE:210	default:211		master_reg = ACP_I2STDM0_MSTRCLKGEN;212		break;213	}214 215	mclkgen.bits.i2stdm_master_mode = 0x1;216	if (adata->tdm_mode)217		mclkgen.bits.i2stdm_format_mode = 0x01;218	else219		mclkgen.bits.i2stdm_format_mode = 0x00;220 221	mclkgen.bits.i2stdm_bclk_div_val = rtd->bclk_div;222	mclkgen.bits.i2stdm_lrclk_div_val = rtd->lrclk_div;223	acp_writel(mclkgen.u32_all, rtd->acp5x_base + master_reg);224}225