GNU Linux-libre 6.8.7-gnu
[releases.git] / drivers / misc / mei / vsc-fw-loader.c
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 <asm-generic/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                   /*(DEBLOBBED)*/
50
51 #define VSC_CSI_IMAGE_NAME              VSC_IMAGE_DIR "/*(DEBLOBBED)*/"
52 #define VSC_ACE_IMAGE_NAME_FMT          VSC_IMAGE_DIR "/*(DEBLOBBED)*/"
53 #define VSC_CFG_IMAGE_NAME_FMT          VSC_IMAGE_DIR "/*(DEBLOBBED)*/"
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 fimware
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                 .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)
321                 return ret;
322         if (ack->token == VSC_TOKEN_ERROR)
323                 return -EINVAL;
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)
329                 return ret;
330         if (ack->token != VSC_TOKEN_DUMP_RESP)
331                 return -EINVAL;
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                 return -EINVAL;
338
339         if (sub_version != VSC_SUBSTEPPING_VERSION_0 &&
340             sub_version != VSC_SUBSTEPPING_VERSION_1)
341                 return -EINVAL;
342
343         dev_info(fw_loader->dev, "silicon stepping version is %u:%u\n",
344                  version, sub_version);
345
346         /* identify strap information */
347         cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
348         cmd->cmd_id = VSC_CMD_DUMP_MEM;
349         cmd->data.dump_mem.addr = cpu_to_le32(VSC_STRAP_ADDR);
350         cmd->data.dump_mem.len = cpu_to_le16(sizeof(__le32));
351         ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE);
352         if (ret)
353                 return ret;
354         if (ack->token == VSC_TOKEN_ERROR)
355                 return -EINVAL;
356
357         cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
358         cmd->cmd_id = VSC_CMD_GET_CONT;
359         ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE);
360         if (ret)
361                 return ret;
362         if (ack->token != VSC_TOKEN_DUMP_RESP)
363                 return -EINVAL;
364
365         return 0;
366 }
367
368 static int vsc_identify_csi_image(struct vsc_fw_loader *fw_loader)
369 {
370         const struct firmware *image;
371         struct vsc_fw_sign *sign;
372         struct vsc_img *img;
373         unsigned int i;
374         int ret;
375
376         ret = reject_firmware(&image, VSC_CSI_IMAGE_NAME, fw_loader->dev);
377         if (ret)
378                 return ret;
379
380         img = (struct vsc_img *)image->data;
381         if (!img) {
382                 ret = -ENOENT;
383                 goto err_release_image;
384         }
385
386         if (le32_to_cpu(img->magic) != VSC_MAGIC_FILE) {
387                 ret = -EINVAL;
388                 goto err_release_image;
389         }
390
391         if (le32_to_cpu(img->image_count) != VSC_CSI_IMG_CNT) {
392                 ret = -EINVAL;
393                 goto err_release_image;
394         }
395         fw_loader->count += le32_to_cpu(img->image_count) - 1;
396
397         fw_loader->option =
398                 FIELD_GET(VSC_BOOT_IMG_OPTION_MASK, le32_to_cpu(img->option));
399
400         sign = (struct vsc_fw_sign *)
401                 (img->image_location + le32_to_cpu(img->image_count));
402
403         for (i = 0; i < VSC_CSI_IMG_CNT; i++) {
404                 /* mapping from CSI image index to image code data */
405                 static const struct vsc_image_code_data csi_image_map[] = {
406                         { VSC_IMG_BOOTLOADER_FRAG, VSC_IMG_BOOTLOADER_TYPE },
407                         { VSC_IMG_CSI_SEM_FRAG, VSC_IMG_CSI_SEM_TYPE },
408                         { VSC_IMG_CSI_RUNTIME_FRAG, VSC_IMG_CSI_RUNTIME_TYPE },
409                         { VSC_IMG_CSI_EM7D_FRAG, VSC_IMG_CSI_EM7D_TYPE },
410                 };
411                 struct vsc_img_frag *frag;
412
413                 if ((u8 *)sign + sizeof(*sign) > image->data + image->size) {
414                         ret = -EINVAL;
415                         goto err_release_image;
416                 }
417
418                 if (le32_to_cpu(sign->magic) != VSC_MAGIC_FW) {
419                         ret = -EINVAL;
420                         goto err_release_image;
421                 }
422
423                 if (!le32_to_cpu(img->image_location[i])) {
424                         ret = -EINVAL;
425                         goto err_release_image;
426                 }
427
428                 frag = &fw_loader->frags[csi_image_map[i].frag_index];
429
430                 frag->data = sign->image;
431                 frag->size = le32_to_cpu(sign->image_size);
432                 frag->location = le32_to_cpu(img->image_location[i]);
433                 frag->type = csi_image_map[i].image_type;
434
435                 sign = (struct vsc_fw_sign *)
436                         (sign->image + le32_to_cpu(sign->image_size));
437         }
438
439         fw_loader->csi = image;
440
441         return 0;
442
443 err_release_image:
444         release_firmware(image);
445
446         return ret;
447 }
448
449 static int vsc_identify_ace_image(struct vsc_fw_loader *fw_loader)
450 {
451         char path[VSC_IMAGE_PATH_MAX_LEN];
452         const struct firmware *image;
453         struct vsc_fw_sign *sign;
454         struct vsc_img *img;
455         unsigned int i;
456         int ret;
457
458         snprintf(path, sizeof(path), VSC_ACE_IMAGE_NAME_FMT,
459                  fw_loader->sensor_name);
460
461         ret = reject_firmware(&image, path, fw_loader->dev);
462         if (ret)
463                 return ret;
464
465         img = (struct vsc_img *)image->data;
466         if (!img) {
467                 ret = -ENOENT;
468                 goto err_release_image;
469         }
470
471         if (le32_to_cpu(img->magic) != VSC_MAGIC_FILE) {
472                 ret = -EINVAL;
473                 goto err_release_image;
474         }
475
476         if (le32_to_cpu(img->image_count) != VSC_ACE_IMG_CNT) {
477                 ret = -EINVAL;
478                 goto err_release_image;
479         }
480         fw_loader->count += le32_to_cpu(img->image_count);
481
482         sign = (struct vsc_fw_sign *)
483                 (img->image_location + le32_to_cpu(img->image_count));
484
485         for (i = 0; i < VSC_ACE_IMG_CNT; i++) {
486                 /* mapping from ACE image index to image code data */
487                 static const struct vsc_image_code_data ace_image_map[] = {
488                         { VSC_IMG_ACE_VISION_FRAG, VSC_IMG_ACE_VISION_TYPE },
489                         { VSC_IMG_ACE_CFG_FRAG, VSC_IMG_ACE_CFG_TYPE },
490                 };
491                 struct vsc_img_frag *frag, *last_frag;
492                 u8 frag_index;
493
494                 if ((u8 *)sign + sizeof(*sign) > image->data + image->size) {
495                         ret = -EINVAL;
496                         goto err_release_image;
497                 }
498
499                 if (le32_to_cpu(sign->magic) != VSC_MAGIC_FW) {
500                         ret = -EINVAL;
501                         goto err_release_image;
502                 }
503
504                 frag_index = ace_image_map[i].frag_index;
505                 frag = &fw_loader->frags[frag_index];
506
507                 frag->data = sign->image;
508                 frag->size = le32_to_cpu(sign->image_size);
509                 frag->location = le32_to_cpu(img->image_location[i]);
510                 frag->type = ace_image_map[i].image_type;
511
512                 if (!frag->location) {
513                         last_frag = &fw_loader->frags[frag_index - 1];
514                         frag->location =
515                                 ALIGN(last_frag->location + last_frag->size, SZ_4K);
516                 }
517
518                 sign = (struct vsc_fw_sign *)
519                         (sign->image + le32_to_cpu(sign->image_size));
520         }
521
522         fw_loader->ace = image;
523
524         return 0;
525
526 err_release_image:
527         release_firmware(image);
528
529         return ret;
530 }
531
532 static int vsc_identify_cfg_image(struct vsc_fw_loader *fw_loader)
533 {
534         struct vsc_img_frag *frag = &fw_loader->frags[VSC_IMG_SKU_CFG_FRAG];
535         char path[VSC_IMAGE_PATH_MAX_LEN];
536         const struct firmware *image;
537         u32 size;
538         int ret;
539
540         snprintf(path, sizeof(path), VSC_CFG_IMAGE_NAME_FMT,
541                  fw_loader->sensor_name);
542
543         ret = reject_firmware(&image, path, fw_loader->dev);
544         if (ret)
545                 return ret;
546
547         /* identify image size */
548         if (image->size <= sizeof(u32) || image->size > VSC_SKU_MAX_SIZE) {
549                 ret = -EINVAL;
550                 goto err_release_image;
551         }
552
553         size = le32_to_cpu(*((__le32 *)image->data)) + sizeof(u32);
554         if (image->size != size) {
555                 ret = -EINVAL;
556                 goto err_release_image;
557         }
558
559         frag->data = image->data;
560         frag->size = image->size;
561         frag->type = VSC_IMG_SKU_CFG_TYPE;
562         frag->location = VSC_SKU_CFG_LOCATION;
563
564         fw_loader->cfg = image;
565
566         return 0;
567
568 err_release_image:
569         release_firmware(image);
570
571         return ret;
572 }
573
574 static int vsc_download_bootloader(struct vsc_fw_loader *fw_loader)
575 {
576         struct vsc_img_frag *frag = &fw_loader->frags[VSC_IMG_BOOTLOADER_FRAG];
577         struct vsc_rom_cmd_ack *ack = fw_loader->rx_buf;
578         struct vsc_rom_cmd *cmd = fw_loader->tx_buf;
579         u32 len, c_len;
580         size_t remain;
581         const u8 *p;
582         int ret;
583
584         cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
585         cmd->cmd_id = VSC_CMD_QUERY;
586         ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, ack, VSC_ROM_PKG_SIZE);
587         if (ret)
588                 return ret;
589         if (ack->token != VSC_TOKEN_DUMP_RESP &&
590             ack->token != VSC_TOKEN_BOOTLOADER_REQ)
591                 return -EINVAL;
592
593         cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
594         cmd->cmd_id = VSC_CMD_DL_START;
595         cmd->data.dl_start.option = cpu_to_le16(fw_loader->option);
596         cmd->data.dl_start.img_type = frag->type;
597         cmd->data.dl_start.img_len = cpu_to_le32(frag->size);
598         cmd->data.dl_start.img_loc = cpu_to_le32(frag->location);
599
600         c_len = offsetof(struct vsc_rom_cmd, data.dl_start.crc);
601         cmd->data.dl_start.crc = cpu_to_le32(vsc_sum_crc(cmd, c_len));
602
603         ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_ROM_PKG_SIZE);
604         if (ret)
605                 return ret;
606
607         p = frag->data;
608         remain = frag->size;
609
610         /* download image data */
611         while (remain > 0) {
612                 len = min(remain, sizeof(cmd->data.dl_cont.payload));
613
614                 cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
615                 cmd->cmd_id = VSC_CMD_DL_CONT;
616                 cmd->data.dl_cont.len = cpu_to_le16(len);
617                 cmd->data.dl_cont.end_flag = remain == len;
618                 memcpy(cmd->data.dl_cont.payload, p, len);
619
620                 ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_ROM_PKG_SIZE);
621                 if (ret)
622                         return ret;
623
624                 p += len;
625                 remain -= len;
626         }
627
628         return 0;
629 }
630
631 static int vsc_download_firmware(struct vsc_fw_loader *fw_loader)
632 {
633         struct vsc_fw_cmd *cmd = fw_loader->tx_buf;
634         unsigned int i, index = 0;
635         u32 c_len;
636         int ret;
637
638         cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
639         cmd->cmd_id = VSC_CMD_DL_SET;
640         cmd->data.dl_set.img_cnt = cpu_to_le16(fw_loader->count);
641         put_unaligned_le16(fw_loader->option, &cmd->data.dl_set.option);
642
643         for (i = VSC_IMG_CSI_SEM_FRAG; i <= VSC_IMG_CSI_EM7D_FRAG; i++) {
644                 struct vsc_img_frag *frag = &fw_loader->frags[i];
645
646                 cmd->data.dl_set.payload[index++] = cpu_to_le32(frag->location);
647                 cmd->data.dl_set.payload[index++] = cpu_to_le32(frag->size);
648         }
649
650         c_len = offsetof(struct vsc_fw_cmd, data.dl_set.payload[index]);
651         cmd->data.dl_set.payload[index] = cpu_to_le32(vsc_sum_crc(cmd, c_len));
652
653         ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
654         if (ret)
655                 return ret;
656
657         for (i = VSC_IMG_CSI_SEM_FRAG; i < VSC_IMG_FRAG_MAX; i++) {
658                 struct vsc_img_frag *frag = &fw_loader->frags[i];
659                 const u8 *p;
660                 u32 remain;
661
662                 cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
663                 cmd->cmd_id = VSC_CMD_DL_START;
664                 cmd->data.dl_start.img_type = frag->type;
665                 cmd->data.dl_start.img_len = cpu_to_le32(frag->size);
666                 cmd->data.dl_start.img_loc = cpu_to_le32(frag->location);
667                 put_unaligned_le16(fw_loader->option, &cmd->data.dl_start.option);
668
669                 c_len = offsetof(struct vsc_fw_cmd, data.dl_start.crc);
670                 cmd->data.dl_start.crc = cpu_to_le32(vsc_sum_crc(cmd, c_len));
671
672                 ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
673                 if (ret)
674                         return ret;
675
676                 p = frag->data;
677                 remain = frag->size;
678
679                 /* download image data */
680                 while (remain > 0) {
681                         u32 len = min(remain, VSC_FW_PKG_SIZE);
682
683                         memcpy(fw_loader->tx_buf, p, len);
684                         memset(fw_loader->tx_buf + len, 0, VSC_FW_PKG_SIZE - len);
685
686                         ret = vsc_tp_rom_xfer(fw_loader->tp, fw_loader->tx_buf,
687                                               NULL, VSC_FW_PKG_SIZE);
688                         if (ret)
689                                 break;
690
691                         p += len;
692                         remain -= len;
693                 }
694         }
695
696         cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
697         cmd->cmd_id = VSC_CMD_CAM_BOOT;
698
699         c_len = offsetof(struct vsc_fw_cmd, data.dl_start.crc);
700         cmd->data.boot.crc = cpu_to_le32(vsc_sum_crc(cmd, c_len));
701
702         return vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
703 }
704
705 /**
706  * vsc_tp_init - init vsc_tp
707  * @tp: vsc_tp device handle
708  * @dev: device node for mei vsc device
709  * Return: 0 in case of success, negative value in case of error
710  */
711 int vsc_tp_init(struct vsc_tp *tp, struct device *dev)
712 {
713         struct vsc_fw_loader *fw_loader __free(kfree) = NULL;
714         void *tx_buf __free(kfree) = NULL;
715         void *rx_buf __free(kfree) = NULL;
716         int ret;
717
718         fw_loader = kzalloc(sizeof(*fw_loader), GFP_KERNEL);
719         if (!fw_loader)
720                 return -ENOMEM;
721
722         tx_buf = kzalloc(VSC_FW_PKG_SIZE, GFP_KERNEL);
723         if (!tx_buf)
724                 return -ENOMEM;
725
726         rx_buf = kzalloc(VSC_FW_PKG_SIZE, GFP_KERNEL);
727         if (!rx_buf)
728                 return -ENOMEM;
729
730         fw_loader->tx_buf = tx_buf;
731         fw_loader->rx_buf = rx_buf;
732
733         fw_loader->tp = tp;
734         fw_loader->dev = dev;
735
736         ret = vsc_get_sensor_name(fw_loader, dev);
737         if (ret)
738                 return ret;
739
740         ret = vsc_identify_silicon(fw_loader);
741         if (ret)
742                 return ret;
743
744         ret = vsc_identify_csi_image(fw_loader);
745         if (ret)
746                 return ret;
747
748         ret = vsc_identify_ace_image(fw_loader);
749         if (ret)
750                 goto err_release_csi;
751
752         ret = vsc_identify_cfg_image(fw_loader);
753         if (ret)
754                 goto err_release_ace;
755
756         ret = vsc_download_bootloader(fw_loader);
757         if (!ret)
758                 ret = vsc_download_firmware(fw_loader);
759
760         release_firmware(fw_loader->cfg);
761
762 err_release_ace:
763         release_firmware(fw_loader->ace);
764
765 err_release_csi:
766         release_firmware(fw_loader->csi);
767
768         return ret;
769 }
770 EXPORT_SYMBOL_NS_GPL(vsc_tp_init, VSC_TP);