Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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