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