xref: /linux/drivers/misc/mei/vsc-fw-loader.c (revision 7f71507851fc7764b36a3221839607d3a45c2025)
1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3  * Copyright (c) 2023, Intel Corporation.
4  * Intel Visual Sensing Controller Transport Layer Linux driver
5  */
6 
7 #include <linux/acpi.h>
8 #include <linux/align.h>
9 #include <linux/bitfield.h>
10 #include <linux/bits.h>
11 #include <linux/cleanup.h>
12 #include <linux/firmware.h>
13 #include <linux/sizes.h>
14 #include <linux/slab.h>
15 #include <linux/string_helpers.h>
16 #include <linux/types.h>
17 
18 #include <linux/unaligned.h>
19 
20 #include "vsc-tp.h"
21 
22 #define VSC_MAGIC_NUM			0x49505343 /* IPSC */
23 #define VSC_MAGIC_FW			0x49574653 /* IWFS */
24 #define VSC_MAGIC_FILE			0x46564353 /* FVCS */
25 
26 #define VSC_ADDR_BASE			0xE0030000
27 #define VSC_EFUSE_ADDR			(VSC_ADDR_BASE + 0x038)
28 #define VSC_STRAP_ADDR			(VSC_ADDR_BASE + 0x100)
29 
30 #define VSC_MAINSTEPPING_VERSION_MASK	GENMASK(7, 4)
31 #define VSC_MAINSTEPPING_VERSION_A	0
32 
33 #define VSC_SUBSTEPPING_VERSION_MASK	GENMASK(3, 0)
34 #define VSC_SUBSTEPPING_VERSION_0	0
35 #define VSC_SUBSTEPPING_VERSION_1	2
36 
37 #define VSC_BOOT_IMG_OPTION_MASK	GENMASK(15, 0)
38 
39 #define VSC_SKU_CFG_LOCATION		0x5001A000
40 #define VSC_SKU_MAX_SIZE		4100u
41 
42 #define VSC_ACE_IMG_CNT			2
43 #define VSC_CSI_IMG_CNT			4
44 #define VSC_IMG_CNT_MAX			6
45 
46 #define VSC_ROM_PKG_SIZE		256u
47 #define VSC_FW_PKG_SIZE			512u
48 
49 #define VSC_IMAGE_DIR			"intel/vsc/"
50 
51 #define VSC_CSI_IMAGE_NAME		VSC_IMAGE_DIR "ivsc_fw.bin"
52 #define VSC_ACE_IMAGE_NAME_FMT		VSC_IMAGE_DIR "ivsc_pkg_%s_0.bin"
53 #define VSC_CFG_IMAGE_NAME_FMT		VSC_IMAGE_DIR "ivsc_skucfg_%s_0_1.bin"
54 
55 #define VSC_IMAGE_PATH_MAX_LEN		64
56 
57 #define VSC_SENSOR_NAME_MAX_LEN		16
58 
59 /* command id */
60 enum {
61 	VSC_CMD_QUERY = 0,
62 	VSC_CMD_DL_SET = 1,
63 	VSC_CMD_DL_START = 2,
64 	VSC_CMD_DL_CONT = 3,
65 	VSC_CMD_DUMP_MEM = 4,
66 	VSC_CMD_GET_CONT = 8,
67 	VSC_CMD_CAM_BOOT = 10,
68 };
69 
70 /* command ack token */
71 enum {
72 	VSC_TOKEN_BOOTLOADER_REQ = 1,
73 	VSC_TOKEN_DUMP_RESP = 4,
74 	VSC_TOKEN_ERROR = 7,
75 };
76 
77 /* image type */
78 enum {
79 	VSC_IMG_BOOTLOADER_TYPE = 1,
80 	VSC_IMG_CSI_EM7D_TYPE,
81 	VSC_IMG_CSI_SEM_TYPE,
82 	VSC_IMG_CSI_RUNTIME_TYPE,
83 	VSC_IMG_ACE_VISION_TYPE,
84 	VSC_IMG_ACE_CFG_TYPE,
85 	VSC_IMG_SKU_CFG_TYPE,
86 };
87 
88 /* image fragments */
89 enum {
90 	VSC_IMG_BOOTLOADER_FRAG,
91 	VSC_IMG_CSI_SEM_FRAG,
92 	VSC_IMG_CSI_RUNTIME_FRAG,
93 	VSC_IMG_ACE_VISION_FRAG,
94 	VSC_IMG_ACE_CFG_FRAG,
95 	VSC_IMG_CSI_EM7D_FRAG,
96 	VSC_IMG_SKU_CFG_FRAG,
97 	VSC_IMG_FRAG_MAX
98 };
99 
100 struct vsc_rom_cmd {
101 	__le32 magic;
102 	__u8 cmd_id;
103 	union {
104 		/* download start */
105 		struct {
106 			__u8 img_type;
107 			__le16 option;
108 			__le32 img_len;
109 			__le32 img_loc;
110 			__le32 crc;
111 			DECLARE_FLEX_ARRAY(__u8, res);
112 		} __packed dl_start;
113 		/* download set */
114 		struct {
115 			__u8 option;
116 			__le16 img_cnt;
117 			DECLARE_FLEX_ARRAY(__le32, payload);
118 		} __packed dl_set;
119 		/* download continue */
120 		struct {
121 			__u8 end_flag;
122 			__le16 len;
123 			/* 8 is the offset of payload */
124 			__u8 payload[VSC_ROM_PKG_SIZE - 8];
125 		} __packed dl_cont;
126 		/* dump memory */
127 		struct {
128 			__u8 res;
129 			__le16 len;
130 			__le32 addr;
131 			DECLARE_FLEX_ARRAY(__u8, payload);
132 		} __packed dump_mem;
133 		/* 5 is the offset of padding */
134 		__u8 padding[VSC_ROM_PKG_SIZE - 5];
135 	} data;
136 };
137 
138 struct vsc_rom_cmd_ack {
139 	__le32 magic;
140 	__u8 token;
141 	__u8 type;
142 	__u8 res[2];
143 	__u8 payload[];
144 };
145 
146 struct vsc_fw_cmd {
147 	__le32 magic;
148 	__u8 cmd_id;
149 	union {
150 		struct {
151 			__le16 option;
152 			__u8 img_type;
153 			__le32 img_len;
154 			__le32 img_loc;
155 			__le32 crc;
156 			DECLARE_FLEX_ARRAY(__u8, res);
157 		} __packed dl_start;
158 		struct {
159 			__le16 option;
160 			__u8 img_cnt;
161 			DECLARE_FLEX_ARRAY(__le32, payload);
162 		} __packed dl_set;
163 		struct {
164 			__le32 addr;
165 			__u8 len;
166 			DECLARE_FLEX_ARRAY(__u8, payload);
167 		} __packed dump_mem;
168 		struct {
169 			__u8 resv[3];
170 			__le32 crc;
171 			DECLARE_FLEX_ARRAY(__u8, payload);
172 		} __packed boot;
173 		/* 5 is the offset of padding */
174 		__u8 padding[VSC_FW_PKG_SIZE - 5];
175 	} data;
176 };
177 
178 struct vsc_img {
179 	__le32 magic;
180 	__le32 option;
181 	__le32 image_count;
182 	__le32 image_location[VSC_IMG_CNT_MAX];
183 };
184 
185 struct vsc_fw_sign {
186 	__le32 magic;
187 	__le32 image_size;
188 	__u8 image[];
189 };
190 
191 struct vsc_image_code_data {
192 	/* fragment index */
193 	u8 frag_index;
194 	/* image type */
195 	u8 image_type;
196 };
197 
198 struct vsc_img_frag {
199 	u8 type;
200 	u32 location;
201 	const u8 *data;
202 	u32 size;
203 };
204 
205 /**
206  * struct vsc_fw_loader - represent vsc firmware loader
207  * @dev: device used to request firmware
208  * @tp: transport layer used with the firmware loader
209  * @csi: CSI image
210  * @ace: ACE image
211  * @cfg: config image
212  * @tx_buf: tx buffer
213  * @rx_buf: rx buffer
214  * @option: command option
215  * @count: total image count
216  * @sensor_name: camera sensor name
217  * @frags: image fragments
218  */
219 struct vsc_fw_loader {
220 	struct device *dev;
221 	struct vsc_tp *tp;
222 
223 	const struct firmware *csi;
224 	const struct firmware *ace;
225 	const struct firmware *cfg;
226 
227 	void *tx_buf;
228 	void *rx_buf;
229 
230 	u16 option;
231 	u16 count;
232 
233 	char sensor_name[VSC_SENSOR_NAME_MAX_LEN];
234 
235 	struct vsc_img_frag frags[VSC_IMG_FRAG_MAX];
236 };
237 
238 static inline u32 vsc_sum_crc(void *data, size_t size)
239 {
240 	u32 crc = 0;
241 	size_t i;
242 
243 	for (i = 0; i < size; i++)
244 		crc += *((u8 *)data + i);
245 
246 	return crc;
247 }
248 
249 /* get sensor name to construct image name */
250 static int vsc_get_sensor_name(struct vsc_fw_loader *fw_loader,
251 			       struct device *dev)
252 {
253 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
254 	union acpi_object obj = {
255 		.integer.type = ACPI_TYPE_INTEGER,
256 		.integer.value = 1,
257 	};
258 	struct acpi_object_list arg_list = {
259 		.count = 1,
260 		.pointer = &obj,
261 	};
262 	union acpi_object *ret_obj;
263 	acpi_handle handle;
264 	acpi_status status;
265 	int ret = 0;
266 
267 	handle = ACPI_HANDLE(dev);
268 	if (!handle)
269 		return -EINVAL;
270 
271 	status = acpi_evaluate_object(handle, "SID", &arg_list, &buffer);
272 	if (ACPI_FAILURE(status)) {
273 		dev_err(dev, "can't evaluate SID method: %d\n", status);
274 		return -ENODEV;
275 	}
276 
277 	ret_obj = buffer.pointer;
278 	if (!ret_obj) {
279 		dev_err(dev, "can't locate ACPI buffer\n");
280 		return -ENODEV;
281 	}
282 
283 	if (ret_obj->type != ACPI_TYPE_STRING) {
284 		dev_err(dev, "found non-string entry\n");
285 		ret = -ENODEV;
286 		goto out_free_buff;
287 	}
288 
289 	/* string length excludes trailing NUL */
290 	if (ret_obj->string.length >= sizeof(fw_loader->sensor_name)) {
291 		dev_err(dev, "sensor name buffer too small\n");
292 		ret = -EINVAL;
293 		goto out_free_buff;
294 	}
295 
296 	memcpy(fw_loader->sensor_name, ret_obj->string.pointer,
297 	       ret_obj->string.length);
298 
299 	string_lower(fw_loader->sensor_name, fw_loader->sensor_name);
300 
301 out_free_buff:
302 	ACPI_FREE(buffer.pointer);
303 
304 	return ret;
305 }
306 
307 static int vsc_identify_silicon(struct vsc_fw_loader *fw_loader)
308 {
309 	struct vsc_rom_cmd_ack *ack = fw_loader->rx_buf;
310 	struct vsc_rom_cmd *cmd = fw_loader->tx_buf;
311 	u8 version, sub_version;
312 	int ret;
313 
314 	/* identify stepping information */
315 	cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
316 	cmd->cmd_id = VSC_CMD_DUMP_MEM;
317 	cmd->data.dump_mem.addr = cpu_to_le32(VSC_EFUSE_ADDR);
318 	cmd->data.dump_mem.len = cpu_to_le16(sizeof(__le32));
319 	ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE);
320 	if (ret || ack->token == VSC_TOKEN_ERROR) {
321 		dev_err(fw_loader->dev, "CMD_DUMP_MEM error %d token %d\n", ret, ack->token);
322 		return ret ?: -EINVAL;
323 	}
324 
325 	cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
326 	cmd->cmd_id = VSC_CMD_GET_CONT;
327 	ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE);
328 	if (ret || ack->token != VSC_TOKEN_DUMP_RESP) {
329 		dev_err(fw_loader->dev, "CMD_GETCONT error %d token %d\n", ret, ack->token);
330 		return ret ?: -EINVAL;
331 	}
332 
333 	version = FIELD_GET(VSC_MAINSTEPPING_VERSION_MASK, ack->payload[0]);
334 	sub_version = FIELD_GET(VSC_SUBSTEPPING_VERSION_MASK, ack->payload[0]);
335 
336 	if (version != VSC_MAINSTEPPING_VERSION_A) {
337 		dev_err(fw_loader->dev, "mainstepping mismatch expected %d got %d\n",
338 			VSC_MAINSTEPPING_VERSION_A, version);
339 		return -EINVAL;
340 	}
341 
342 	if (sub_version != VSC_SUBSTEPPING_VERSION_0 &&
343 	    sub_version != VSC_SUBSTEPPING_VERSION_1) {
344 		dev_err(fw_loader->dev, "substepping %d is out of supported range %d - %d\n",
345 			sub_version, VSC_SUBSTEPPING_VERSION_0, VSC_SUBSTEPPING_VERSION_1);
346 		return -EINVAL;
347 	}
348 
349 	dev_info(fw_loader->dev, "silicon stepping version is %u:%u\n",
350 		 version, sub_version);
351 
352 	/* identify strap information */
353 	cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
354 	cmd->cmd_id = VSC_CMD_DUMP_MEM;
355 	cmd->data.dump_mem.addr = cpu_to_le32(VSC_STRAP_ADDR);
356 	cmd->data.dump_mem.len = cpu_to_le16(sizeof(__le32));
357 	ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE);
358 	if (ret)
359 		return ret;
360 	if (ack->token == VSC_TOKEN_ERROR)
361 		return -EINVAL;
362 
363 	cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
364 	cmd->cmd_id = VSC_CMD_GET_CONT;
365 	ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE);
366 	if (ret)
367 		return ret;
368 	if (ack->token != VSC_TOKEN_DUMP_RESP)
369 		return -EINVAL;
370 
371 	return 0;
372 }
373 
374 static int vsc_identify_csi_image(struct vsc_fw_loader *fw_loader)
375 {
376 	const struct firmware *image;
377 	struct vsc_fw_sign *sign;
378 	struct vsc_img *img;
379 	unsigned int i;
380 	int ret;
381 
382 	ret = request_firmware(&image, VSC_CSI_IMAGE_NAME, fw_loader->dev);
383 	if (ret)
384 		return ret;
385 
386 	img = (struct vsc_img *)image->data;
387 	if (!img) {
388 		ret = -ENOENT;
389 		goto err_release_image;
390 	}
391 
392 	if (le32_to_cpu(img->magic) != VSC_MAGIC_FILE) {
393 		ret = -EINVAL;
394 		goto err_release_image;
395 	}
396 
397 	if (le32_to_cpu(img->image_count) != VSC_CSI_IMG_CNT) {
398 		ret = -EINVAL;
399 		goto err_release_image;
400 	}
401 	fw_loader->count += le32_to_cpu(img->image_count) - 1;
402 
403 	fw_loader->option =
404 		FIELD_GET(VSC_BOOT_IMG_OPTION_MASK, le32_to_cpu(img->option));
405 
406 	sign = (struct vsc_fw_sign *)
407 		(img->image_location + le32_to_cpu(img->image_count));
408 
409 	for (i = 0; i < VSC_CSI_IMG_CNT; i++) {
410 		/* mapping from CSI image index to image code data */
411 		static const struct vsc_image_code_data csi_image_map[] = {
412 			{ VSC_IMG_BOOTLOADER_FRAG, VSC_IMG_BOOTLOADER_TYPE },
413 			{ VSC_IMG_CSI_SEM_FRAG, VSC_IMG_CSI_SEM_TYPE },
414 			{ VSC_IMG_CSI_RUNTIME_FRAG, VSC_IMG_CSI_RUNTIME_TYPE },
415 			{ VSC_IMG_CSI_EM7D_FRAG, VSC_IMG_CSI_EM7D_TYPE },
416 		};
417 		struct vsc_img_frag *frag;
418 
419 		if ((u8 *)sign + sizeof(*sign) > image->data + image->size) {
420 			ret = -EINVAL;
421 			goto err_release_image;
422 		}
423 
424 		if (le32_to_cpu(sign->magic) != VSC_MAGIC_FW) {
425 			ret = -EINVAL;
426 			goto err_release_image;
427 		}
428 
429 		if (!le32_to_cpu(img->image_location[i])) {
430 			ret = -EINVAL;
431 			goto err_release_image;
432 		}
433 
434 		frag = &fw_loader->frags[csi_image_map[i].frag_index];
435 
436 		frag->data = sign->image;
437 		frag->size = le32_to_cpu(sign->image_size);
438 		frag->location = le32_to_cpu(img->image_location[i]);
439 		frag->type = csi_image_map[i].image_type;
440 
441 		sign = (struct vsc_fw_sign *)
442 			(sign->image + le32_to_cpu(sign->image_size));
443 	}
444 
445 	fw_loader->csi = image;
446 
447 	return 0;
448 
449 err_release_image:
450 	release_firmware(image);
451 
452 	return ret;
453 }
454 
455 static int vsc_identify_ace_image(struct vsc_fw_loader *fw_loader)
456 {
457 	char path[VSC_IMAGE_PATH_MAX_LEN];
458 	const struct firmware *image;
459 	struct vsc_fw_sign *sign;
460 	struct vsc_img *img;
461 	unsigned int i;
462 	int ret;
463 
464 	snprintf(path, sizeof(path), VSC_ACE_IMAGE_NAME_FMT,
465 		 fw_loader->sensor_name);
466 
467 	ret = request_firmware(&image, path, fw_loader->dev);
468 	if (ret)
469 		return ret;
470 
471 	img = (struct vsc_img *)image->data;
472 	if (!img) {
473 		ret = -ENOENT;
474 		goto err_release_image;
475 	}
476 
477 	if (le32_to_cpu(img->magic) != VSC_MAGIC_FILE) {
478 		ret = -EINVAL;
479 		goto err_release_image;
480 	}
481 
482 	if (le32_to_cpu(img->image_count) != VSC_ACE_IMG_CNT) {
483 		ret = -EINVAL;
484 		goto err_release_image;
485 	}
486 	fw_loader->count += le32_to_cpu(img->image_count);
487 
488 	sign = (struct vsc_fw_sign *)
489 		(img->image_location + le32_to_cpu(img->image_count));
490 
491 	for (i = 0; i < VSC_ACE_IMG_CNT; i++) {
492 		/* mapping from ACE image index to image code data */
493 		static const struct vsc_image_code_data ace_image_map[] = {
494 			{ VSC_IMG_ACE_VISION_FRAG, VSC_IMG_ACE_VISION_TYPE },
495 			{ VSC_IMG_ACE_CFG_FRAG, VSC_IMG_ACE_CFG_TYPE },
496 		};
497 		struct vsc_img_frag *frag, *last_frag;
498 		u8 frag_index;
499 
500 		if ((u8 *)sign + sizeof(*sign) > image->data + image->size) {
501 			ret = -EINVAL;
502 			goto err_release_image;
503 		}
504 
505 		if (le32_to_cpu(sign->magic) != VSC_MAGIC_FW) {
506 			ret = -EINVAL;
507 			goto err_release_image;
508 		}
509 
510 		frag_index = ace_image_map[i].frag_index;
511 		frag = &fw_loader->frags[frag_index];
512 
513 		frag->data = sign->image;
514 		frag->size = le32_to_cpu(sign->image_size);
515 		frag->location = le32_to_cpu(img->image_location[i]);
516 		frag->type = ace_image_map[i].image_type;
517 
518 		if (!frag->location) {
519 			last_frag = &fw_loader->frags[frag_index - 1];
520 			frag->location =
521 				ALIGN(last_frag->location + last_frag->size, SZ_4K);
522 		}
523 
524 		sign = (struct vsc_fw_sign *)
525 			(sign->image + le32_to_cpu(sign->image_size));
526 	}
527 
528 	fw_loader->ace = image;
529 
530 	return 0;
531 
532 err_release_image:
533 	release_firmware(image);
534 
535 	return ret;
536 }
537 
538 static int vsc_identify_cfg_image(struct vsc_fw_loader *fw_loader)
539 {
540 	struct vsc_img_frag *frag = &fw_loader->frags[VSC_IMG_SKU_CFG_FRAG];
541 	char path[VSC_IMAGE_PATH_MAX_LEN];
542 	const struct firmware *image;
543 	u32 size;
544 	int ret;
545 
546 	snprintf(path, sizeof(path), VSC_CFG_IMAGE_NAME_FMT,
547 		 fw_loader->sensor_name);
548 
549 	ret = request_firmware(&image, path, fw_loader->dev);
550 	if (ret)
551 		return ret;
552 
553 	/* identify image size */
554 	if (image->size <= sizeof(u32) || image->size > VSC_SKU_MAX_SIZE) {
555 		ret = -EINVAL;
556 		goto err_release_image;
557 	}
558 
559 	size = le32_to_cpu(*((__le32 *)image->data)) + sizeof(u32);
560 	if (image->size != size) {
561 		ret = -EINVAL;
562 		goto err_release_image;
563 	}
564 
565 	frag->data = image->data;
566 	frag->size = image->size;
567 	frag->type = VSC_IMG_SKU_CFG_TYPE;
568 	frag->location = VSC_SKU_CFG_LOCATION;
569 
570 	fw_loader->cfg = image;
571 
572 	return 0;
573 
574 err_release_image:
575 	release_firmware(image);
576 
577 	return ret;
578 }
579 
580 static int vsc_download_bootloader(struct vsc_fw_loader *fw_loader)
581 {
582 	struct vsc_img_frag *frag = &fw_loader->frags[VSC_IMG_BOOTLOADER_FRAG];
583 	struct vsc_rom_cmd_ack *ack = fw_loader->rx_buf;
584 	struct vsc_rom_cmd *cmd = fw_loader->tx_buf;
585 	u32 len, c_len;
586 	size_t remain;
587 	const u8 *p;
588 	int ret;
589 
590 	cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
591 	cmd->cmd_id = VSC_CMD_QUERY;
592 	ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE);
593 	if (ret)
594 		return ret;
595 	if (ack->token != VSC_TOKEN_DUMP_RESP &&
596 	    ack->token != VSC_TOKEN_BOOTLOADER_REQ)
597 		return -EINVAL;
598 
599 	cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
600 	cmd->cmd_id = VSC_CMD_DL_START;
601 	cmd->data.dl_start.option = cpu_to_le16(fw_loader->option);
602 	cmd->data.dl_start.img_type = frag->type;
603 	cmd->data.dl_start.img_len = cpu_to_le32(frag->size);
604 	cmd->data.dl_start.img_loc = cpu_to_le32(frag->location);
605 
606 	c_len = offsetof(struct vsc_rom_cmd, data.dl_start.crc);
607 	cmd->data.dl_start.crc = cpu_to_le32(vsc_sum_crc(cmd, c_len));
608 
609 	ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_ROM_PKG_SIZE);
610 	if (ret)
611 		return ret;
612 
613 	p = frag->data;
614 	remain = frag->size;
615 
616 	/* download image data */
617 	while (remain > 0) {
618 		len = min(remain, sizeof(cmd->data.dl_cont.payload));
619 
620 		cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
621 		cmd->cmd_id = VSC_CMD_DL_CONT;
622 		cmd->data.dl_cont.len = cpu_to_le16(len);
623 		cmd->data.dl_cont.end_flag = remain == len;
624 		memcpy(cmd->data.dl_cont.payload, p, len);
625 
626 		ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_ROM_PKG_SIZE);
627 		if (ret)
628 			return ret;
629 
630 		p += len;
631 		remain -= len;
632 	}
633 
634 	return 0;
635 }
636 
637 static int vsc_download_firmware(struct vsc_fw_loader *fw_loader)
638 {
639 	struct vsc_fw_cmd *cmd = fw_loader->tx_buf;
640 	unsigned int i, index = 0;
641 	u32 c_len;
642 	int ret;
643 
644 	cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
645 	cmd->cmd_id = VSC_CMD_DL_SET;
646 	cmd->data.dl_set.img_cnt = cpu_to_le16(fw_loader->count);
647 	put_unaligned_le16(fw_loader->option, &cmd->data.dl_set.option);
648 
649 	for (i = VSC_IMG_CSI_SEM_FRAG; i <= VSC_IMG_CSI_EM7D_FRAG; i++) {
650 		struct vsc_img_frag *frag = &fw_loader->frags[i];
651 
652 		cmd->data.dl_set.payload[index++] = cpu_to_le32(frag->location);
653 		cmd->data.dl_set.payload[index++] = cpu_to_le32(frag->size);
654 	}
655 
656 	c_len = offsetof(struct vsc_fw_cmd, data.dl_set.payload[index]);
657 	cmd->data.dl_set.payload[index] = cpu_to_le32(vsc_sum_crc(cmd, c_len));
658 
659 	ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
660 	if (ret)
661 		return ret;
662 
663 	for (i = VSC_IMG_CSI_SEM_FRAG; i < VSC_IMG_FRAG_MAX; i++) {
664 		struct vsc_img_frag *frag = &fw_loader->frags[i];
665 		const u8 *p;
666 		u32 remain;
667 
668 		cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
669 		cmd->cmd_id = VSC_CMD_DL_START;
670 		cmd->data.dl_start.img_type = frag->type;
671 		cmd->data.dl_start.img_len = cpu_to_le32(frag->size);
672 		cmd->data.dl_start.img_loc = cpu_to_le32(frag->location);
673 		put_unaligned_le16(fw_loader->option, &cmd->data.dl_start.option);
674 
675 		c_len = offsetof(struct vsc_fw_cmd, data.dl_start.crc);
676 		cmd->data.dl_start.crc = cpu_to_le32(vsc_sum_crc(cmd, c_len));
677 
678 		ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
679 		if (ret)
680 			return ret;
681 
682 		p = frag->data;
683 		remain = frag->size;
684 
685 		/* download image data */
686 		while (remain > 0) {
687 			u32 len = min(remain, VSC_FW_PKG_SIZE);
688 
689 			memcpy(fw_loader->tx_buf, p, len);
690 			memset(fw_loader->tx_buf + len, 0, VSC_FW_PKG_SIZE - len);
691 
692 			ret = vsc_tp_rom_xfer(fw_loader->tp, fw_loader->tx_buf,
693 					      NULL, VSC_FW_PKG_SIZE);
694 			if (ret)
695 				break;
696 
697 			p += len;
698 			remain -= len;
699 		}
700 	}
701 
702 	cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
703 	cmd->cmd_id = VSC_CMD_CAM_BOOT;
704 
705 	c_len = offsetof(struct vsc_fw_cmd, data.dl_start.crc);
706 	cmd->data.boot.crc = cpu_to_le32(vsc_sum_crc(cmd, c_len));
707 
708 	return vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
709 }
710 
711 /**
712  * vsc_tp_init - init vsc_tp
713  * @tp: vsc_tp device handle
714  * @dev: device node for mei vsc device
715  * Return: 0 in case of success, negative value in case of error
716  */
717 int vsc_tp_init(struct vsc_tp *tp, struct device *dev)
718 {
719 	struct vsc_fw_loader *fw_loader __free(kfree) = NULL;
720 	void *tx_buf __free(kfree) = NULL;
721 	void *rx_buf __free(kfree) = NULL;
722 	int ret;
723 
724 	fw_loader = kzalloc(sizeof(*fw_loader), GFP_KERNEL);
725 	if (!fw_loader)
726 		return -ENOMEM;
727 
728 	tx_buf = kzalloc(VSC_FW_PKG_SIZE, GFP_KERNEL);
729 	if (!tx_buf)
730 		return -ENOMEM;
731 
732 	rx_buf = kzalloc(VSC_FW_PKG_SIZE, GFP_KERNEL);
733 	if (!rx_buf)
734 		return -ENOMEM;
735 
736 	fw_loader->tx_buf = tx_buf;
737 	fw_loader->rx_buf = rx_buf;
738 
739 	fw_loader->tp = tp;
740 	fw_loader->dev = dev;
741 
742 	ret = vsc_get_sensor_name(fw_loader, dev);
743 	if (ret)
744 		return ret;
745 
746 	ret = vsc_identify_silicon(fw_loader);
747 	if (ret)
748 		return ret;
749 
750 	ret = vsc_identify_csi_image(fw_loader);
751 	if (ret)
752 		return ret;
753 
754 	ret = vsc_identify_ace_image(fw_loader);
755 	if (ret)
756 		goto err_release_csi;
757 
758 	ret = vsc_identify_cfg_image(fw_loader);
759 	if (ret)
760 		goto err_release_ace;
761 
762 	ret = vsc_download_bootloader(fw_loader);
763 	if (!ret)
764 		ret = vsc_download_firmware(fw_loader);
765 
766 	release_firmware(fw_loader->cfg);
767 
768 err_release_ace:
769 	release_firmware(fw_loader->ace);
770 
771 err_release_csi:
772 	release_firmware(fw_loader->csi);
773 
774 	return ret;
775 }
776 EXPORT_SYMBOL_NS_GPL(vsc_tp_init, VSC_TP);
777