0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011 #ifndef __AMD_ACP_H
0012 #define __AMD_ACP_H
0013
0014 #include <sound/pcm.h>
0015 #include <sound/soc.h>
0016 #include <sound/soc-acpi.h>
0017 #include <sound/soc-dai.h>
0018
0019 #include "chip_offset_byte.h"
0020
0021 #define ACP3X_DEV 3
0022 #define ACP6X_DEV 6
0023
0024 #define I2S_SP_INSTANCE 0x00
0025 #define I2S_BT_INSTANCE 0x01
0026 #define DMIC_INSTANCE 0x02
0027 #define I2S_HS_INSTANCE 0x03
0028
0029 #define MEM_WINDOW_START 0x4080000
0030
0031 #define ACP_I2S_REG_START 0x1242400
0032 #define ACP_I2S_REG_END 0x1242810
0033 #define ACP3x_I2STDM_REG_START 0x1242400
0034 #define ACP3x_I2STDM_REG_END 0x1242410
0035 #define ACP3x_BT_TDM_REG_START 0x1242800
0036 #define ACP3x_BT_TDM_REG_END 0x1242810
0037
0038 #define THRESHOLD(bit, base) ((bit) + (base))
0039 #define I2S_RX_THRESHOLD(base) THRESHOLD(7, base)
0040 #define I2S_TX_THRESHOLD(base) THRESHOLD(8, base)
0041 #define BT_TX_THRESHOLD(base) THRESHOLD(6, base)
0042 #define BT_RX_THRESHOLD(base) THRESHOLD(5, base)
0043 #define HS_TX_THRESHOLD(base) THRESHOLD(4, base)
0044 #define HS_RX_THRESHOLD(base) THRESHOLD(3, base)
0045
0046 #define ACP_SRAM_SP_PB_PTE_OFFSET 0x0
0047 #define ACP_SRAM_SP_CP_PTE_OFFSET 0x100
0048 #define ACP_SRAM_BT_PB_PTE_OFFSET 0x200
0049 #define ACP_SRAM_BT_CP_PTE_OFFSET 0x300
0050 #define ACP_SRAM_PDM_PTE_OFFSET 0x400
0051 #define ACP_SRAM_HS_PB_PTE_OFFSET 0x500
0052 #define ACP_SRAM_HS_CP_PTE_OFFSET 0x600
0053 #define PAGE_SIZE_4K_ENABLE 0x2
0054
0055 #define I2S_SP_TX_MEM_WINDOW_START 0x4000000
0056 #define I2S_SP_RX_MEM_WINDOW_START 0x4020000
0057 #define I2S_BT_TX_MEM_WINDOW_START 0x4040000
0058 #define I2S_BT_RX_MEM_WINDOW_START 0x4060000
0059 #define I2S_HS_TX_MEM_WINDOW_START 0x40A0000
0060 #define I2S_HS_RX_MEM_WINDOW_START 0x40C0000
0061
0062 #define SP_PB_FIFO_ADDR_OFFSET 0x500
0063 #define SP_CAPT_FIFO_ADDR_OFFSET 0x700
0064 #define BT_PB_FIFO_ADDR_OFFSET 0x900
0065 #define BT_CAPT_FIFO_ADDR_OFFSET 0xB00
0066 #define HS_PB_FIFO_ADDR_OFFSET 0xD00
0067 #define HS_CAPT_FIFO_ADDR_OFFSET 0xF00
0068 #define PLAYBACK_MIN_NUM_PERIODS 2
0069 #define PLAYBACK_MAX_NUM_PERIODS 8
0070 #define PLAYBACK_MAX_PERIOD_SIZE 8192
0071 #define PLAYBACK_MIN_PERIOD_SIZE 1024
0072 #define CAPTURE_MIN_NUM_PERIODS 2
0073 #define CAPTURE_MAX_NUM_PERIODS 8
0074 #define CAPTURE_MAX_PERIOD_SIZE 8192
0075 #define CAPTURE_MIN_PERIOD_SIZE 1024
0076
0077 #define MAX_BUFFER 65536
0078 #define MIN_BUFFER MAX_BUFFER
0079 #define FIFO_SIZE 0x100
0080 #define DMA_SIZE 0x40
0081 #define FRM_LEN 0x100
0082
0083 #define ACP3x_ITER_IRER_SAMP_LEN_MASK 0x38
0084
0085 #define ACP_MAX_STREAM 8
0086
0087 struct acp_chip_info {
0088 char *name;
0089 unsigned int acp_rev;
0090 void __iomem *base;
0091 };
0092
0093 struct acp_stream {
0094 struct snd_pcm_substream *substream;
0095 int irq_bit;
0096 int dai_id;
0097 int id;
0098 u64 bytescount;
0099 u32 reg_offset;
0100 u32 pte_offset;
0101 u32 fifo_offset;
0102 };
0103
0104 struct acp_resource {
0105 int offset;
0106 int no_of_ctrls;
0107 int irqp_used;
0108 bool soc_mclk;
0109 u32 irq_reg_offset;
0110 u32 i2s_pin_cfg_offset;
0111 int i2s_mode;
0112 u64 scratch_reg_offset;
0113 u64 sram_pte_offset;
0114 };
0115
0116 struct acp_dev_data {
0117 char *name;
0118 struct device *dev;
0119 void __iomem *acp_base;
0120 unsigned int i2s_irq;
0121
0122
0123 struct snd_soc_dai_driver *dai_driver;
0124 int num_dai;
0125
0126 struct acp_stream *stream[ACP_MAX_STREAM];
0127
0128 struct snd_soc_acpi_mach *machines;
0129 struct platform_device *mach_dev;
0130
0131 u32 bclk_div;
0132 u32 lrclk_div;
0133
0134 struct acp_resource *rsrc;
0135 };
0136
0137 union acp_i2stdm_mstrclkgen {
0138 struct {
0139 u32 i2stdm_master_mode : 1;
0140 u32 i2stdm_format_mode : 1;
0141 u32 i2stdm_lrclk_div_val : 9;
0142 u32 i2stdm_bclk_div_val : 11;
0143 u32:10;
0144 } bitfields, bits;
0145 u32 u32_all;
0146 };
0147
0148 extern const struct snd_soc_dai_ops asoc_acp_cpu_dai_ops;
0149 extern const struct snd_soc_dai_ops acp_dmic_dai_ops;
0150
0151 int asoc_acp_i2s_probe(struct snd_soc_dai *dai);
0152 int acp_platform_register(struct device *dev);
0153 int acp_platform_unregister(struct device *dev);
0154
0155 int acp_machine_select(struct acp_dev_data *adata);
0156
0157
0158 int snd_amd_acp_find_config(struct pci_dev *pci);
0159
0160 static inline u64 acp_get_byte_count(struct acp_dev_data *adata, int dai_id, int direction)
0161 {
0162 u64 byte_count, low = 0, high = 0;
0163
0164 if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
0165 switch (dai_id) {
0166 case I2S_BT_INSTANCE:
0167 high = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_HIGH);
0168 low = readl(adata->acp_base + ACP_BT_TX_LINEARPOSITIONCNTR_LOW);
0169 break;
0170 case I2S_SP_INSTANCE:
0171 high = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_HIGH);
0172 low = readl(adata->acp_base + ACP_I2S_TX_LINEARPOSITIONCNTR_LOW);
0173 break;
0174 case I2S_HS_INSTANCE:
0175 high = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_HIGH);
0176 low = readl(adata->acp_base + ACP_HS_TX_LINEARPOSITIONCNTR_LOW);
0177 break;
0178 default:
0179 dev_err(adata->dev, "Invalid dai id %x\n", dai_id);
0180 return -EINVAL;
0181 }
0182 } else {
0183 switch (dai_id) {
0184 case I2S_BT_INSTANCE:
0185 high = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_HIGH);
0186 low = readl(adata->acp_base + ACP_BT_RX_LINEARPOSITIONCNTR_LOW);
0187 break;
0188 case I2S_SP_INSTANCE:
0189 high = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_HIGH);
0190 low = readl(adata->acp_base + ACP_I2S_RX_LINEARPOSITIONCNTR_LOW);
0191 break;
0192 case I2S_HS_INSTANCE:
0193 high = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_HIGH);
0194 low = readl(adata->acp_base + ACP_HS_RX_LINEARPOSITIONCNTR_LOW);
0195 break;
0196 case DMIC_INSTANCE:
0197 high = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_HIGH);
0198 low = readl(adata->acp_base + ACP_WOV_RX_LINEARPOSITIONCNTR_LOW);
0199 break;
0200 default:
0201 dev_err(adata->dev, "Invalid dai id %x\n", dai_id);
0202 return -EINVAL;
0203 }
0204 }
0205
0206 byte_count = (high << 32) | low;
0207
0208 return byte_count;
0209 }
0210
0211 static inline void acp_set_i2s_clk(struct acp_dev_data *adata, int dai_id)
0212 {
0213 union acp_i2stdm_mstrclkgen mclkgen;
0214 u32 master_reg;
0215
0216 switch (dai_id) {
0217 case I2S_SP_INSTANCE:
0218 master_reg = ACP_I2STDM0_MSTRCLKGEN;
0219 break;
0220 case I2S_BT_INSTANCE:
0221 master_reg = ACP_I2STDM1_MSTRCLKGEN;
0222 break;
0223 case I2S_HS_INSTANCE:
0224 master_reg = ACP_I2STDM2_MSTRCLKGEN;
0225 break;
0226 default:
0227 master_reg = ACP_I2STDM0_MSTRCLKGEN;
0228 break;
0229 }
0230
0231 mclkgen.bits.i2stdm_master_mode = 0x1;
0232 mclkgen.bits.i2stdm_format_mode = 0x00;
0233
0234 mclkgen.bits.i2stdm_bclk_div_val = adata->bclk_div;
0235 mclkgen.bits.i2stdm_lrclk_div_val = adata->lrclk_div;
0236 writel(mclkgen.u32_all, adata->acp_base + master_reg);
0237 }
0238 #endif