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

TOMOYO Linux Cross Reference
Linux/sound/soc/intel/avs/icl.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
  2 //
  3 // Copyright(c) 2021-2024 Intel Corporation
  4 //
  5 // Authors: Cezary Rojewski <cezary.rojewski@intel.com>
  6 //          Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
  7 //
  8 
  9 #include <linux/slab.h>
 10 #include <sound/hdaudio.h>
 11 #include <sound/hdaudio_ext.h>
 12 #include "avs.h"
 13 #include "messages.h"
 14 
 15 #define ICL_VS_LTRP_GB_ICCMAX   95
 16 
 17 #ifdef CONFIG_DEBUG_FS
 18 int avs_icl_enable_logs(struct avs_dev *adev, enum avs_log_enable enable, u32 aging_period,
 19                         u32 fifo_full_period, unsigned long resource_mask, u32 *priorities)
 20 {
 21         struct avs_icl_log_state_info *info;
 22         u32 size, num_libs = adev->fw_cfg.max_libs_count;
 23         int i, ret;
 24 
 25         if (fls_long(resource_mask) > num_libs)
 26                 return -EINVAL;
 27         size = struct_size(info, logs_priorities_mask, num_libs);
 28         info = kzalloc(size, GFP_KERNEL);
 29         if (!info)
 30                 return -ENOMEM;
 31 
 32         info->aging_timer_period = aging_period;
 33         info->fifo_full_timer_period = fifo_full_period;
 34         info->enable = enable;
 35         if (enable)
 36                 for_each_set_bit(i, &resource_mask, num_libs)
 37                         info->logs_priorities_mask[i] = *priorities++;
 38 
 39         ret = avs_ipc_set_enable_logs(adev, (u8 *)info, size);
 40         kfree(info);
 41         if (ret)
 42                 return AVS_IPC_RET(ret);
 43 
 44         return 0;
 45 }
 46 #endif
 47 
 48 union avs_icl_memwnd2_slot_type {
 49         u32 val;
 50         struct {
 51                 u32 resource_id:8;
 52                 u32 type:24;
 53         };
 54 } __packed;
 55 static_assert(sizeof(union avs_icl_memwnd2_slot_type) == 4);
 56 
 57 struct avs_icl_memwnd2_desc {
 58         u32 resource_id;
 59         union avs_icl_memwnd2_slot_type slot_id;
 60         u32 vma;
 61 } __packed;
 62 static_assert(sizeof(struct avs_icl_memwnd2_desc) == 12);
 63 
 64 #define AVS_ICL_MEMWND2_SLOTS_COUNT     15
 65 
 66 struct avs_icl_memwnd2 {
 67         union {
 68                 struct avs_icl_memwnd2_desc slot_desc[AVS_ICL_MEMWND2_SLOTS_COUNT];
 69                 u8 rsvd[SZ_4K];
 70         };
 71         u8 slot_array[AVS_ICL_MEMWND2_SLOTS_COUNT][SZ_4K];
 72 } __packed;
 73 static_assert(sizeof(struct avs_icl_memwnd2) == 65536);
 74 
 75 #define AVS_ICL_SLOT_UNUSED \
 76         ((union avs_icl_memwnd2_slot_type) { 0x00000000U })
 77 #define AVS_ICL_SLOT_CRITICAL_LOG \
 78         ((union avs_icl_memwnd2_slot_type) { 0x54524300U })
 79 #define AVS_ICL_SLOT_DEBUG_LOG \
 80         ((union avs_icl_memwnd2_slot_type) { 0x474f4c00U })
 81 #define AVS_ICL_SLOT_GDB_STUB \
 82         ((union avs_icl_memwnd2_slot_type) { 0x42444700U })
 83 #define AVS_ICL_SLOT_BROKEN \
 84         ((union avs_icl_memwnd2_slot_type) { 0x44414544U })
 85 
 86 static int avs_icl_slot_offset(struct avs_dev *adev, union avs_icl_memwnd2_slot_type slot_type)
 87 {
 88         struct avs_icl_memwnd2_desc desc[AVS_ICL_MEMWND2_SLOTS_COUNT];
 89         int i;
 90 
 91         memcpy_fromio(&desc, avs_sram_addr(adev, AVS_DEBUG_WINDOW), sizeof(desc));
 92 
 93         for (i = 0; i < AVS_ICL_MEMWND2_SLOTS_COUNT; i++)
 94                 if (desc[i].slot_id.val == slot_type.val)
 95                         return offsetof(struct avs_icl_memwnd2, slot_array) + i * SZ_4K;
 96         return -ENXIO;
 97 }
 98 
 99 int avs_icl_log_buffer_offset(struct avs_dev *adev, u32 core)
100 {
101         union avs_icl_memwnd2_slot_type slot_type = AVS_ICL_SLOT_DEBUG_LOG;
102         int ret;
103 
104         slot_type.resource_id = core;
105         ret = avs_icl_slot_offset(adev, slot_type);
106         if (ret < 0)
107                 dev_dbg(adev->dev, "No slot offset found for: %x\n",
108                         slot_type.val);
109 
110         return ret;
111 }
112 
113 bool avs_icl_d0ix_toggle(struct avs_dev *adev, struct avs_ipc_msg *tx, bool wake)
114 {
115         /* Full-power when starting DMA engines. */
116         if (tx->glb.set_ppl_state.state == AVS_PPL_STATE_RUNNING)
117                 return true;
118 
119         /* Payload-less IPCs do not take part in d0ix toggling. */
120         return tx->size;
121 }
122 
123 int avs_icl_set_d0ix(struct avs_dev *adev, bool enable)
124 {
125         int ret;
126 
127         ret = avs_ipc_set_d0ix(adev, enable, false);
128         return AVS_IPC_RET(ret);
129 }
130 
131 int avs_icl_load_basefw(struct avs_dev *adev, struct firmware *fw)
132 {
133         struct hdac_bus *bus = &adev->base.core;
134         struct hdac_ext_stream *host_stream;
135         struct snd_pcm_substream substream;
136         struct snd_dma_buffer dmab;
137         unsigned int sd_fmt;
138         u8 ltrp_gb;
139         int ret;
140 
141         /*
142          * ICCMAX:
143          *
144          * For ICL+ platforms, as per HW recommendation LTRP_GB is set to 95us
145          * during FW load. Its original value shall be restored once load completes.
146          *
147          * To avoid DMI/OPIO L1 entry during the load procedure, additional CAPTURE
148          * stream is allocated and set to run.
149          */
150 
151         memset(&substream, 0, sizeof(substream));
152         substream.stream = SNDRV_PCM_STREAM_CAPTURE;
153 
154         host_stream = snd_hdac_ext_stream_assign(bus, &substream, HDAC_EXT_STREAM_TYPE_HOST);
155         if (!host_stream)
156                 return -EBUSY;
157 
158         ltrp_gb = snd_hdac_chip_readb(bus, VS_LTRP) & AZX_REG_VS_LTRP_GB_MASK;
159         /* Carries no real data, use default format. */
160         sd_fmt = snd_hdac_stream_format(1, 32, 48000);
161 
162         ret = snd_hdac_dsp_prepare(hdac_stream(host_stream), sd_fmt, fw->size, &dmab);
163         if (ret < 0)
164                 goto release_stream;
165 
166         snd_hdac_chip_updateb(bus, VS_LTRP, AZX_REG_VS_LTRP_GB_MASK, ICL_VS_LTRP_GB_ICCMAX);
167 
168         spin_lock(&bus->reg_lock);
169         snd_hdac_stream_start(hdac_stream(host_stream));
170         spin_unlock(&bus->reg_lock);
171 
172         ret = avs_hda_load_basefw(adev, fw);
173 
174         spin_lock(&bus->reg_lock);
175         snd_hdac_stream_stop(hdac_stream(host_stream));
176         spin_unlock(&bus->reg_lock);
177 
178         snd_hdac_dsp_cleanup(hdac_stream(host_stream), &dmab);
179 
180 release_stream:
181         snd_hdac_ext_stream_release(host_stream, HDAC_EXT_STREAM_TYPE_HOST);
182         snd_hdac_chip_updateb(bus, VS_LTRP, AZX_REG_VS_LTRP_GB_MASK, ltrp_gb);
183 
184         return ret;
185 }
186 
187 const struct avs_dsp_ops avs_icl_dsp_ops = {
188         .power = avs_dsp_core_power,
189         .reset = avs_dsp_core_reset,
190         .stall = avs_dsp_core_stall,
191         .dsp_interrupt = avs_cnl_dsp_interrupt,
192         .int_control = avs_dsp_interrupt_control,
193         .load_basefw = avs_icl_load_basefw,
194         .load_lib = avs_hda_load_library,
195         .transfer_mods = avs_hda_transfer_modules,
196         .log_buffer_offset = avs_icl_log_buffer_offset,
197         .log_buffer_status = avs_apl_log_buffer_status,
198         .coredump = avs_apl_coredump,
199         .d0ix_toggle = avs_icl_d0ix_toggle,
200         .set_d0ix = avs_icl_set_d0ix,
201         AVS_SET_ENABLE_LOGS_OP(icl)
202 };
203 

~ [ 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