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

TOMOYO Linux Cross Reference
Linux/sound/soc/intel/catpt/loader.c

Version: ~ [ linux-6.11.5 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.58 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.114 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.169 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.228 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.284 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.322 ] ~ [ 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) 2020 Intel Corporation
  4 //
  5 // Author: Cezary Rojewski <cezary.rojewski@intel.com>
  6 //
  7 
  8 #include <linux/dma-mapping.h>
  9 #include <linux/firmware.h>
 10 #include <linux/slab.h>
 11 #include "core.h"
 12 #include "registers.h"
 13 
 14 /* FW load (200ms) plus operational delays */
 15 #define FW_READY_TIMEOUT_MS     250
 16 
 17 #define FW_SIGNATURE            "$SST"
 18 #define FW_SIGNATURE_SIZE       4
 19 
 20 struct catpt_fw_hdr {
 21         char signature[FW_SIGNATURE_SIZE];
 22         u32 file_size;
 23         u32 modules;
 24         u32 file_format;
 25         u32 reserved[4];
 26 } __packed;
 27 
 28 struct catpt_fw_mod_hdr {
 29         char signature[FW_SIGNATURE_SIZE];
 30         u32 mod_size;
 31         u32 blocks;
 32         u16 slot;
 33         u16 module_id;
 34         u32 entry_point;
 35         u32 persistent_size;
 36         u32 scratch_size;
 37 } __packed;
 38 
 39 enum catpt_ram_type {
 40         CATPT_RAM_TYPE_IRAM = 1,
 41         CATPT_RAM_TYPE_DRAM = 2,
 42         /* DRAM with module's initial state */
 43         CATPT_RAM_TYPE_INSTANCE = 3,
 44 };
 45 
 46 struct catpt_fw_block_hdr {
 47         u32 ram_type;
 48         u32 size;
 49         u32 ram_offset;
 50         u32 rsvd;
 51 } __packed;
 52 
 53 void catpt_sram_init(struct resource *sram, u32 start, u32 size)
 54 {
 55         sram->start = start;
 56         sram->end = start + size - 1;
 57 }
 58 
 59 void catpt_sram_free(struct resource *sram)
 60 {
 61         struct resource *res, *save;
 62 
 63         for (res = sram->child; res;) {
 64                 save = res->sibling;
 65                 release_resource(res);
 66                 kfree(res);
 67                 res = save;
 68         }
 69 }
 70 
 71 struct resource *
 72 catpt_request_region(struct resource *root, resource_size_t size)
 73 {
 74         struct resource *res = root->child;
 75         resource_size_t addr = root->start;
 76 
 77         for (;;) {
 78                 if (res->start - addr >= size)
 79                         break;
 80                 addr = res->end + 1;
 81                 res = res->sibling;
 82                 if (!res)
 83                         return NULL;
 84         }
 85 
 86         return __request_region(root, addr, size, NULL, 0);
 87 }
 88 
 89 int catpt_store_streams_context(struct catpt_dev *cdev, struct dma_chan *chan)
 90 {
 91         struct catpt_stream_runtime *stream;
 92 
 93         list_for_each_entry(stream, &cdev->stream_list, node) {
 94                 u32 off, size;
 95                 int ret;
 96 
 97                 off = stream->persistent->start;
 98                 size = resource_size(stream->persistent);
 99                 dev_dbg(cdev->dev, "storing stream %d ctx: off 0x%08x size %d\n",
100                         stream->info.stream_hw_id, off, size);
101 
102                 ret = catpt_dma_memcpy_fromdsp(cdev, chan,
103                                                cdev->dxbuf_paddr + off,
104                                                cdev->lpe_base + off,
105                                                ALIGN(size, 4));
106                 if (ret) {
107                         dev_err(cdev->dev, "memcpy fromdsp failed: %d\n", ret);
108                         return ret;
109                 }
110         }
111 
112         return 0;
113 }
114 
115 int catpt_store_module_states(struct catpt_dev *cdev, struct dma_chan *chan)
116 {
117         int i;
118 
119         for (i = 0; i < ARRAY_SIZE(cdev->modules); i++) {
120                 struct catpt_module_type *type;
121                 u32 off;
122                 int ret;
123 
124                 type = &cdev->modules[i];
125                 if (!type->loaded || !type->state_size)
126                         continue;
127 
128                 off = type->state_offset;
129                 dev_dbg(cdev->dev, "storing mod %d state: off 0x%08x size %d\n",
130                         i, off, type->state_size);
131 
132                 ret = catpt_dma_memcpy_fromdsp(cdev, chan,
133                                                cdev->dxbuf_paddr + off,
134                                                cdev->lpe_base + off,
135                                                ALIGN(type->state_size, 4));
136                 if (ret) {
137                         dev_err(cdev->dev, "memcpy fromdsp failed: %d\n", ret);
138                         return ret;
139                 }
140         }
141 
142         return 0;
143 }
144 
145 int catpt_store_memdumps(struct catpt_dev *cdev, struct dma_chan *chan)
146 {
147         int i;
148 
149         for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) {
150                 struct catpt_save_meminfo *info;
151                 u32 off;
152                 int ret;
153 
154                 info = &cdev->dx_ctx.meminfo[i];
155                 if (info->source != CATPT_DX_TYPE_MEMORY_DUMP)
156                         continue;
157 
158                 off = catpt_to_host_offset(info->offset);
159                 if (off < cdev->dram.start || off > cdev->dram.end)
160                         continue;
161 
162                 dev_dbg(cdev->dev, "storing memdump: off 0x%08x size %d\n",
163                         off, info->size);
164 
165                 ret = catpt_dma_memcpy_fromdsp(cdev, chan,
166                                                cdev->dxbuf_paddr + off,
167                                                cdev->lpe_base + off,
168                                                ALIGN(info->size, 4));
169                 if (ret) {
170                         dev_err(cdev->dev, "memcpy fromdsp failed: %d\n", ret);
171                         return ret;
172                 }
173         }
174 
175         return 0;
176 }
177 
178 static int
179 catpt_restore_streams_context(struct catpt_dev *cdev, struct dma_chan *chan)
180 {
181         struct catpt_stream_runtime *stream;
182 
183         list_for_each_entry(stream, &cdev->stream_list, node) {
184                 u32 off, size;
185                 int ret;
186 
187                 off = stream->persistent->start;
188                 size = resource_size(stream->persistent);
189                 dev_dbg(cdev->dev, "restoring stream %d ctx: off 0x%08x size %d\n",
190                         stream->info.stream_hw_id, off, size);
191 
192                 ret = catpt_dma_memcpy_todsp(cdev, chan,
193                                              cdev->lpe_base + off,
194                                              cdev->dxbuf_paddr + off,
195                                              ALIGN(size, 4));
196                 if (ret) {
197                         dev_err(cdev->dev, "memcpy fromdsp failed: %d\n", ret);
198                         return ret;
199                 }
200         }
201 
202         return 0;
203 }
204 
205 static int catpt_restore_memdumps(struct catpt_dev *cdev, struct dma_chan *chan)
206 {
207         int i;
208 
209         for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) {
210                 struct catpt_save_meminfo *info;
211                 u32 off;
212                 int ret;
213 
214                 info = &cdev->dx_ctx.meminfo[i];
215                 if (info->source != CATPT_DX_TYPE_MEMORY_DUMP)
216                         continue;
217 
218                 off = catpt_to_host_offset(info->offset);
219                 if (off < cdev->dram.start || off > cdev->dram.end)
220                         continue;
221 
222                 dev_dbg(cdev->dev, "restoring memdump: off 0x%08x size %d\n",
223                         off, info->size);
224 
225                 ret = catpt_dma_memcpy_todsp(cdev, chan,
226                                              cdev->lpe_base + off,
227                                              cdev->dxbuf_paddr + off,
228                                              ALIGN(info->size, 4));
229                 if (ret) {
230                         dev_err(cdev->dev, "restore block failed: %d\n", ret);
231                         return ret;
232                 }
233         }
234 
235         return 0;
236 }
237 
238 static int catpt_restore_fwimage(struct catpt_dev *cdev,
239                                  struct dma_chan *chan, dma_addr_t paddr,
240                                  struct catpt_fw_block_hdr *blk)
241 {
242         struct resource r1, r2, common;
243         int i;
244 
245         print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4,
246                              blk, sizeof(*blk), false);
247 
248         r1.start = cdev->dram.start + blk->ram_offset;
249         r1.end = r1.start + blk->size - 1;
250         /* advance to data area */
251         paddr += sizeof(*blk);
252 
253         for (i = 0; i < cdev->dx_ctx.num_meminfo; i++) {
254                 struct catpt_save_meminfo *info;
255                 u32 off;
256                 int ret;
257 
258                 info = &cdev->dx_ctx.meminfo[i];
259 
260                 if (info->source != CATPT_DX_TYPE_FW_IMAGE)
261                         continue;
262 
263                 off = catpt_to_host_offset(info->offset);
264                 if (off < cdev->dram.start || off > cdev->dram.end)
265                         continue;
266 
267                 r2.start = off;
268                 r2.end = r2.start + info->size - 1;
269 
270                 if (!resource_intersection(&r2, &r1, &common))
271                         continue;
272                 /* calculate start offset of common data area */
273                 off = common.start - r1.start;
274 
275                 dev_dbg(cdev->dev, "restoring fwimage: %pr\n", &common);
276 
277                 ret = catpt_dma_memcpy_todsp(cdev, chan, common.start,
278                                              paddr + off,
279                                              resource_size(&common));
280                 if (ret) {
281                         dev_err(cdev->dev, "memcpy todsp failed: %d\n", ret);
282                         return ret;
283                 }
284         }
285 
286         return 0;
287 }
288 
289 static int catpt_load_block(struct catpt_dev *cdev,
290                             struct dma_chan *chan, dma_addr_t paddr,
291                             struct catpt_fw_block_hdr *blk, bool alloc)
292 {
293         struct resource *sram, *res;
294         dma_addr_t dst_addr;
295         int ret;
296 
297         print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4,
298                              blk, sizeof(*blk), false);
299 
300         switch (blk->ram_type) {
301         case CATPT_RAM_TYPE_IRAM:
302                 sram = &cdev->iram;
303                 break;
304         default:
305                 sram = &cdev->dram;
306                 break;
307         }
308 
309         dst_addr = sram->start + blk->ram_offset;
310         if (alloc) {
311                 res = __request_region(sram, dst_addr, blk->size, NULL, 0);
312                 if (!res)
313                         return -EBUSY;
314         }
315 
316         /* advance to data area */
317         paddr += sizeof(*blk);
318 
319         ret = catpt_dma_memcpy_todsp(cdev, chan, dst_addr, paddr, blk->size);
320         if (ret) {
321                 dev_err(cdev->dev, "memcpy error: %d\n", ret);
322                 __release_region(sram, dst_addr, blk->size);
323         }
324 
325         return ret;
326 }
327 
328 static int catpt_restore_basefw(struct catpt_dev *cdev,
329                                 struct dma_chan *chan, dma_addr_t paddr,
330                                 struct catpt_fw_mod_hdr *basefw)
331 {
332         u32 offset = sizeof(*basefw);
333         int ret, i;
334 
335         print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4,
336                              basefw, sizeof(*basefw), false);
337 
338         /* restore basefw image */
339         for (i = 0; i < basefw->blocks; i++) {
340                 struct catpt_fw_block_hdr *blk;
341 
342                 blk = (struct catpt_fw_block_hdr *)((u8 *)basefw + offset);
343 
344                 switch (blk->ram_type) {
345                 case CATPT_RAM_TYPE_IRAM:
346                         ret = catpt_load_block(cdev, chan, paddr + offset,
347                                                blk, false);
348                         break;
349                 default:
350                         ret = catpt_restore_fwimage(cdev, chan, paddr + offset,
351                                                     blk);
352                         break;
353                 }
354 
355                 if (ret) {
356                         dev_err(cdev->dev, "restore block failed: %d\n", ret);
357                         return ret;
358                 }
359 
360                 offset += sizeof(*blk) + blk->size;
361         }
362 
363         /* then proceed with memory dumps */
364         ret = catpt_restore_memdumps(cdev, chan);
365         if (ret)
366                 dev_err(cdev->dev, "restore memdumps failed: %d\n", ret);
367 
368         return ret;
369 }
370 
371 static int catpt_restore_module(struct catpt_dev *cdev,
372                                 struct dma_chan *chan, dma_addr_t paddr,
373                                 struct catpt_fw_mod_hdr *mod)
374 {
375         u32 offset = sizeof(*mod);
376         int i;
377 
378         print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4,
379                              mod, sizeof(*mod), false);
380 
381         for (i = 0; i < mod->blocks; i++) {
382                 struct catpt_fw_block_hdr *blk;
383                 int ret;
384 
385                 blk = (struct catpt_fw_block_hdr *)((u8 *)mod + offset);
386 
387                 switch (blk->ram_type) {
388                 case CATPT_RAM_TYPE_INSTANCE:
389                         /* restore module state */
390                         ret = catpt_dma_memcpy_todsp(cdev, chan,
391                                         cdev->lpe_base + blk->ram_offset,
392                                         cdev->dxbuf_paddr + blk->ram_offset,
393                                         ALIGN(blk->size, 4));
394                         break;
395                 default:
396                         ret = catpt_load_block(cdev, chan, paddr + offset,
397                                                blk, false);
398                         break;
399                 }
400 
401                 if (ret) {
402                         dev_err(cdev->dev, "restore block failed: %d\n", ret);
403                         return ret;
404                 }
405 
406                 offset += sizeof(*blk) + blk->size;
407         }
408 
409         return 0;
410 }
411 
412 static int catpt_load_module(struct catpt_dev *cdev,
413                              struct dma_chan *chan, dma_addr_t paddr,
414                              struct catpt_fw_mod_hdr *mod)
415 {
416         struct catpt_module_type *type;
417         u32 offset = sizeof(*mod);
418         int i;
419 
420         print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4,
421                              mod, sizeof(*mod), false);
422 
423         type = &cdev->modules[mod->module_id];
424 
425         for (i = 0; i < mod->blocks; i++) {
426                 struct catpt_fw_block_hdr *blk;
427                 int ret;
428 
429                 blk = (struct catpt_fw_block_hdr *)((u8 *)mod + offset);
430 
431                 ret = catpt_load_block(cdev, chan, paddr + offset, blk, true);
432                 if (ret) {
433                         dev_err(cdev->dev, "load block failed: %d\n", ret);
434                         return ret;
435                 }
436 
437                 /*
438                  * Save state window coordinates - these will be
439                  * used to capture module state on D0 exit.
440                  */
441                 if (blk->ram_type == CATPT_RAM_TYPE_INSTANCE) {
442                         type->state_offset = blk->ram_offset;
443                         type->state_size = blk->size;
444                 }
445 
446                 offset += sizeof(*blk) + blk->size;
447         }
448 
449         /* init module type static info */
450         type->loaded = true;
451         /* DSP expects address from module header substracted by 4 */
452         type->entry_point = mod->entry_point - 4;
453         type->persistent_size = mod->persistent_size;
454         type->scratch_size = mod->scratch_size;
455 
456         return 0;
457 }
458 
459 static int catpt_restore_firmware(struct catpt_dev *cdev,
460                                   struct dma_chan *chan, dma_addr_t paddr,
461                                   struct catpt_fw_hdr *fw)
462 {
463         u32 offset = sizeof(*fw);
464         int i;
465 
466         print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4,
467                              fw, sizeof(*fw), false);
468 
469         for (i = 0; i < fw->modules; i++) {
470                 struct catpt_fw_mod_hdr *mod;
471                 int ret;
472 
473                 mod = (struct catpt_fw_mod_hdr *)((u8 *)fw + offset);
474                 if (strncmp(fw->signature, mod->signature,
475                             FW_SIGNATURE_SIZE)) {
476                         dev_err(cdev->dev, "module signature mismatch\n");
477                         return -EINVAL;
478                 }
479 
480                 if (mod->module_id > CATPT_MODID_LAST)
481                         return -EINVAL;
482 
483                 switch (mod->module_id) {
484                 case CATPT_MODID_BASE_FW:
485                         ret = catpt_restore_basefw(cdev, chan, paddr + offset,
486                                                    mod);
487                         break;
488                 default:
489                         ret = catpt_restore_module(cdev, chan, paddr + offset,
490                                                    mod);
491                         break;
492                 }
493 
494                 if (ret) {
495                         dev_err(cdev->dev, "restore module failed: %d\n", ret);
496                         return ret;
497                 }
498 
499                 offset += sizeof(*mod) + mod->mod_size;
500         }
501 
502         return 0;
503 }
504 
505 static int catpt_load_firmware(struct catpt_dev *cdev,
506                                struct dma_chan *chan, dma_addr_t paddr,
507                                struct catpt_fw_hdr *fw)
508 {
509         u32 offset = sizeof(*fw);
510         int i;
511 
512         print_hex_dump_debug(__func__, DUMP_PREFIX_OFFSET, 8, 4,
513                              fw, sizeof(*fw), false);
514 
515         for (i = 0; i < fw->modules; i++) {
516                 struct catpt_fw_mod_hdr *mod;
517                 int ret;
518 
519                 mod = (struct catpt_fw_mod_hdr *)((u8 *)fw + offset);
520                 if (strncmp(fw->signature, mod->signature,
521                             FW_SIGNATURE_SIZE)) {
522                         dev_err(cdev->dev, "module signature mismatch\n");
523                         return -EINVAL;
524                 }
525 
526                 if (mod->module_id > CATPT_MODID_LAST)
527                         return -EINVAL;
528 
529                 ret = catpt_load_module(cdev, chan, paddr + offset, mod);
530                 if (ret) {
531                         dev_err(cdev->dev, "load module failed: %d\n", ret);
532                         return ret;
533                 }
534 
535                 offset += sizeof(*mod) + mod->mod_size;
536         }
537 
538         return 0;
539 }
540 
541 static int catpt_load_image(struct catpt_dev *cdev, struct dma_chan *chan,
542                             const char *name, const char *signature,
543                             bool restore)
544 {
545         struct catpt_fw_hdr *fw;
546         struct firmware *img;
547         dma_addr_t paddr;
548         void *vaddr;
549         int ret;
550 
551         ret = request_firmware((const struct firmware **)&img, name, cdev->dev);
552         if (ret)
553                 return ret;
554 
555         fw = (struct catpt_fw_hdr *)img->data;
556         if (strncmp(fw->signature, signature, FW_SIGNATURE_SIZE)) {
557                 dev_err(cdev->dev, "firmware signature mismatch\n");
558                 ret = -EINVAL;
559                 goto release_fw;
560         }
561 
562         vaddr = dma_alloc_coherent(cdev->dev, img->size, &paddr, GFP_KERNEL);
563         if (!vaddr) {
564                 ret = -ENOMEM;
565                 goto release_fw;
566         }
567 
568         memcpy(vaddr, img->data, img->size);
569         fw = (struct catpt_fw_hdr *)vaddr;
570         if (restore)
571                 ret = catpt_restore_firmware(cdev, chan, paddr, fw);
572         else
573                 ret = catpt_load_firmware(cdev, chan, paddr, fw);
574 
575         dma_free_coherent(cdev->dev, img->size, vaddr, paddr);
576 release_fw:
577         release_firmware(img);
578         return ret;
579 }
580 
581 static int catpt_load_images(struct catpt_dev *cdev, bool restore)
582 {
583         static const char *const names[] = {
584                 "intel/IntcSST1.bin",
585                 "intel/IntcSST2.bin",
586         };
587         struct dma_chan *chan;
588         int ret;
589 
590         chan = catpt_dma_request_config_chan(cdev);
591         if (IS_ERR(chan))
592                 return PTR_ERR(chan);
593 
594         ret = catpt_load_image(cdev, chan, names[cdev->spec->core_id - 1],
595                                FW_SIGNATURE, restore);
596         if (ret)
597                 goto release_dma_chan;
598 
599         if (!restore)
600                 goto release_dma_chan;
601         ret = catpt_restore_streams_context(cdev, chan);
602         if (ret)
603                 dev_err(cdev->dev, "restore streams ctx failed: %d\n", ret);
604 release_dma_chan:
605         dma_release_channel(chan);
606         return ret;
607 }
608 
609 int catpt_boot_firmware(struct catpt_dev *cdev, bool restore)
610 {
611         int ret;
612 
613         catpt_dsp_stall(cdev, true);
614 
615         ret = catpt_load_images(cdev, restore);
616         if (ret) {
617                 dev_err(cdev->dev, "load binaries failed: %d\n", ret);
618                 return ret;
619         }
620 
621         reinit_completion(&cdev->fw_ready);
622         catpt_dsp_stall(cdev, false);
623 
624         ret = wait_for_completion_timeout(&cdev->fw_ready,
625                         msecs_to_jiffies(FW_READY_TIMEOUT_MS));
626         if (!ret) {
627                 dev_err(cdev->dev, "firmware ready timeout\n");
628                 return -ETIMEDOUT;
629         }
630 
631         /* update sram pg & clock once done booting */
632         catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask);
633         catpt_dsp_update_srampge(cdev, &cdev->iram, cdev->spec->iram_mask);
634 
635         return catpt_dsp_update_lpclock(cdev);
636 }
637 
638 int catpt_first_boot_firmware(struct catpt_dev *cdev)
639 {
640         struct resource *res;
641         int ret;
642 
643         ret = catpt_boot_firmware(cdev, false);
644         if (ret) {
645                 dev_err(cdev->dev, "basefw boot failed: %d\n", ret);
646                 return ret;
647         }
648 
649         /* restrict FW Core dump area */
650         __request_region(&cdev->dram, 0, 0x200, NULL, 0);
651         /* restrict entire area following BASE_FW - highest offset in DRAM */
652         for (res = cdev->dram.child; res->sibling; res = res->sibling)
653                 ;
654         __request_region(&cdev->dram, res->end + 1,
655                          cdev->dram.end - res->end, NULL, 0);
656 
657         ret = catpt_ipc_get_mixer_stream_info(cdev, &cdev->mixer);
658         if (ret)
659                 return CATPT_IPC_ERROR(ret);
660 
661         ret = catpt_arm_stream_templates(cdev);
662         if (ret) {
663                 dev_err(cdev->dev, "arm templates failed: %d\n", ret);
664                 return ret;
665         }
666 
667         /* update dram pg for scratch and restricted regions */
668         catpt_dsp_update_srampge(cdev, &cdev->dram, cdev->spec->dram_mask);
669 
670         return 0;
671 }
672 

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