~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/sound/soc/sof/amd/acp-stream.c

Version: ~ [ linux-6.11-rc3 ] ~ [ linux-6.10.4 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.45 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.104 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.164 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.223 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.281 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.319 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  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 or
  4 // redistributing this file, you may do so under either license.
  5 //
  6 // Copyright(c) 2021 Advanced Micro Devices, Inc.
  7 //
  8 // Authors: Ajit Kumar Pandey <AjitKumar.Pandey@amd.com>
  9 
 10 /*
 11  * Hardware interface for generic AMD audio DSP ACP IP
 12  */
 13 
 14 #include "../ops.h"
 15 #include "acp-dsp-offset.h"
 16 #include "acp.h"
 17 
 18 #define PTE_GRP1_OFFSET         0x00000000
 19 #define PTE_GRP2_OFFSET         0x00800000
 20 #define PTE_GRP3_OFFSET         0x01000000
 21 #define PTE_GRP4_OFFSET         0x01800000
 22 #define PTE_GRP5_OFFSET         0x02000000
 23 #define PTE_GRP6_OFFSET         0x02800000
 24 #define PTE_GRP7_OFFSET         0x03000000
 25 #define PTE_GRP8_OFFSET         0x03800000
 26 
 27 int acp_dsp_stream_config(struct snd_sof_dev *sdev, struct acp_dsp_stream *stream)
 28 {
 29         const struct sof_amd_acp_desc *desc = get_chip_info(sdev->pdata);
 30         unsigned int pte_reg, pte_size, phy_addr_offset, index;
 31         int stream_tag = stream->stream_tag;
 32         u32 low, high, offset, reg_val;
 33         dma_addr_t addr;
 34         int page_idx;
 35 
 36         switch (stream_tag) {
 37         case 1:
 38                 pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_1;
 39                 pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_1;
 40                 offset = offsetof(struct scratch_reg_conf, grp1_pte);
 41                 stream->reg_offset = PTE_GRP1_OFFSET;
 42                 break;
 43         case 2:
 44                 pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_2;
 45                 pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_2;
 46                 offset = offsetof(struct scratch_reg_conf, grp2_pte);
 47                 stream->reg_offset = PTE_GRP2_OFFSET;
 48                 break;
 49         case 3:
 50                 pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_3;
 51                 pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_3;
 52                 offset = offsetof(struct scratch_reg_conf, grp3_pte);
 53                 stream->reg_offset = PTE_GRP3_OFFSET;
 54                 break;
 55         case 4:
 56                 pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_4;
 57                 pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_4;
 58                 offset = offsetof(struct scratch_reg_conf, grp4_pte);
 59                 stream->reg_offset = PTE_GRP4_OFFSET;
 60                 break;
 61         case 5:
 62                 pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_5;
 63                 pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_5;
 64                 offset = offsetof(struct scratch_reg_conf, grp5_pte);
 65                 stream->reg_offset = PTE_GRP5_OFFSET;
 66                 break;
 67         case 6:
 68                 pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_6;
 69                 pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_6;
 70                 offset = offsetof(struct scratch_reg_conf, grp6_pte);
 71                 stream->reg_offset = PTE_GRP6_OFFSET;
 72                 break;
 73         case 7:
 74                 pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_7;
 75                 pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_7;
 76                 offset = offsetof(struct scratch_reg_conf, grp7_pte);
 77                 stream->reg_offset = PTE_GRP7_OFFSET;
 78                 break;
 79         case 8:
 80                 pte_reg = ACPAXI2AXI_ATU_BASE_ADDR_GRP_8;
 81                 pte_size = ACPAXI2AXI_ATU_PAGE_SIZE_GRP_8;
 82                 offset = offsetof(struct scratch_reg_conf, grp8_pte);
 83                 stream->reg_offset = PTE_GRP8_OFFSET;
 84                 break;
 85         default:
 86                 dev_err(sdev->dev, "Invalid stream tag %d\n", stream_tag);
 87                 return -EINVAL;
 88         }
 89 
 90         /* write phy_addr in scratch memory */
 91 
 92         phy_addr_offset = sdev->debug_box.offset +
 93                           offsetof(struct scratch_reg_conf, reg_offset);
 94         index = stream_tag - 1;
 95         phy_addr_offset = phy_addr_offset + index * 4;
 96 
 97         snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 +
 98                           phy_addr_offset, stream->reg_offset);
 99 
100         /* Group Enable */
101         offset = offset + sdev->debug_box.offset;
102         reg_val = desc->sram_pte_offset + offset;
103         snd_sof_dsp_write(sdev, ACP_DSP_BAR, pte_reg, reg_val | BIT(31));
104         snd_sof_dsp_write(sdev, ACP_DSP_BAR, pte_size, PAGE_SIZE_4K_ENABLE);
105 
106         for (page_idx = 0; page_idx < stream->num_pages; page_idx++) {
107                 addr = snd_sgbuf_get_addr(stream->dmab, page_idx * PAGE_SIZE);
108 
109                 /* Load the low address of page int ACP SRAM through SRBM */
110                 low = lower_32_bits(addr);
111                 high = upper_32_bits(addr);
112 
113                 snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + offset, low);
114 
115                 high |= BIT(31);
116                 snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACP_SCRATCH_REG_0 + offset + 4, high);
117                 /* Move to next physically contiguous page */
118                 offset += 8;
119         }
120 
121         /* Flush ATU Cache after PTE Update */
122         snd_sof_dsp_write(sdev, ACP_DSP_BAR, ACPAXI2AXI_ATU_CTRL, ACP_ATU_CACHE_INVALID);
123 
124         return 0;
125 }
126 
127 struct acp_dsp_stream *acp_dsp_stream_get(struct snd_sof_dev *sdev, int tag)
128 {
129         struct acp_dev_data *adata = sdev->pdata->hw_pdata;
130         struct acp_dsp_stream *stream = adata->stream_buf;
131         int i;
132 
133         for (i = 0; i < ACP_MAX_STREAM; i++, stream++) {
134                 if (stream->active)
135                         continue;
136 
137                 /* return stream if tag not specified*/
138                 if (!tag) {
139                         stream->active = 1;
140                         return stream;
141                 }
142 
143                 /* check if this is the requested stream tag */
144                 if (stream->stream_tag == tag) {
145                         stream->active = 1;
146                         return stream;
147                 }
148         }
149 
150         dev_err(sdev->dev, "stream %d active or no inactive stream\n", tag);
151         return NULL;
152 }
153 EXPORT_SYMBOL_NS(acp_dsp_stream_get, SND_SOC_SOF_AMD_COMMON);
154 
155 int acp_dsp_stream_put(struct snd_sof_dev *sdev,
156                        struct acp_dsp_stream *acp_stream)
157 {
158         struct acp_dev_data *adata = sdev->pdata->hw_pdata;
159         struct acp_dsp_stream *stream = adata->stream_buf;
160         int i;
161 
162         /* Free an active stream */
163         for (i = 0; i < ACP_MAX_STREAM; i++, stream++) {
164                 if (stream == acp_stream) {
165                         stream->active = 0;
166                         return 0;
167                 }
168         }
169 
170         dev_err(sdev->dev, "Cannot find active stream tag %d\n", acp_stream->stream_tag);
171         return -EINVAL;
172 }
173 EXPORT_SYMBOL_NS(acp_dsp_stream_put, SND_SOC_SOF_AMD_COMMON);
174 
175 int acp_dsp_stream_init(struct snd_sof_dev *sdev)
176 {
177         struct acp_dev_data *adata = sdev->pdata->hw_pdata;
178         int i;
179 
180         for (i = 0; i < ACP_MAX_STREAM; i++) {
181                 adata->stream_buf[i].sdev = sdev;
182                 adata->stream_buf[i].active = 0;
183                 adata->stream_buf[i].stream_tag = i + 1;
184         }
185         return 0;
186 }
187 EXPORT_SYMBOL_NS(acp_dsp_stream_init, SND_SOC_SOF_AMD_COMMON);
188 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php