1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (c) 2023, Intel Corporation.
4 * Intel Visual Sensing Controller Transport Layer Linux driver
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>
18 #include <linux/unaligned.h>
22 #define VSC_MAGIC_NUM 0x49505343 /* IPSC */
23 #define VSC_MAGIC_FW 0x49574653 /* IWFS */
24 #define VSC_MAGIC_FILE 0x46564353 /* FVCS */
26 #define VSC_ADDR_BASE 0xE0030000
27 #define VSC_EFUSE_ADDR (VSC_ADDR_BASE + 0x038)
28 #define VSC_STRAP_ADDR (VSC_ADDR_BASE + 0x100)
30 #define VSC_MAINSTEPPING_VERSION_MASK GENMASK(7, 4)
31 #define VSC_MAINSTEPPING_VERSION_A 0
33 #define VSC_SUBSTEPPING_VERSION_MASK GENMASK(3, 0)
34 #define VSC_SUBSTEPPING_VERSION_0 0
35 #define VSC_SUBSTEPPING_VERSION_1 2
37 #define VSC_BOOT_IMG_OPTION_MASK GENMASK(15, 0)
39 #define VSC_SKU_CFG_LOCATION 0x5001A000
40 #define VSC_SKU_MAX_SIZE 4100u
42 #define VSC_ACE_IMG_CNT 2
43 #define VSC_CSI_IMG_CNT 4
44 #define VSC_IMG_CNT_MAX 6
46 #define VSC_ROM_PKG_SIZE 256u
47 #define VSC_FW_PKG_SIZE 512u
49 #define VSC_IMAGE_DIR "intel/vsc/"
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"
55 #define VSC_IMAGE_PATH_MAX_LEN 64
57 #define VSC_SENSOR_NAME_MAX_LEN 16
67 VSC_CMD_CAM_BOOT = 10,
70 /* command ack token */
72 VSC_TOKEN_BOOTLOADER_REQ = 1,
73 VSC_TOKEN_DUMP_RESP = 4,
79 VSC_IMG_BOOTLOADER_TYPE = 1,
80 VSC_IMG_CSI_EM7D_TYPE,
82 VSC_IMG_CSI_RUNTIME_TYPE,
83 VSC_IMG_ACE_VISION_TYPE,
90 VSC_IMG_BOOTLOADER_FRAG,
92 VSC_IMG_CSI_RUNTIME_FRAG,
93 VSC_IMG_ACE_VISION_FRAG,
95 VSC_IMG_CSI_EM7D_FRAG,
111 DECLARE_FLEX_ARRAY(__u8, res);
117 DECLARE_FLEX_ARRAY(__le32, payload);
119 /* download continue */
123 /* 8 is the offset of payload */
124 __u8 payload[VSC_ROM_PKG_SIZE - 8];
131 DECLARE_FLEX_ARRAY(__u8, payload);
133 /* 5 is the offset of padding */
134 __u8 padding[VSC_ROM_PKG_SIZE - 5];
138 struct vsc_rom_cmd_ack {
156 DECLARE_FLEX_ARRAY(__u8, res);
161 DECLARE_FLEX_ARRAY(__le32, payload);
166 DECLARE_FLEX_ARRAY(__u8, payload);
171 DECLARE_FLEX_ARRAY(__u8, payload);
173 /* 5 is the offset of padding */
174 __u8 padding[VSC_FW_PKG_SIZE - 5];
182 __le32 image_location[VSC_IMG_CNT_MAX];
191 struct vsc_image_code_data {
198 struct vsc_img_frag {
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
214 * @option: command option
215 * @count: total image count
216 * @sensor_name: camera sensor name
217 * @frags: image fragments
219 struct vsc_fw_loader {
223 const struct firmware *csi;
224 const struct firmware *ace;
225 const struct firmware *cfg;
233 char sensor_name[VSC_SENSOR_NAME_MAX_LEN];
235 struct vsc_img_frag frags[VSC_IMG_FRAG_MAX];
238 static inline u32 vsc_sum_crc(void *data, size_t size)
243 for (i = 0; i < size; i++)
244 crc += *((u8 *)data + i);
249 /* get sensor name to construct image name */
250 static int vsc_get_sensor_name(struct vsc_fw_loader *fw_loader,
253 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER };
254 union acpi_object obj = {
255 .integer.type = ACPI_TYPE_INTEGER,
258 struct acpi_object_list arg_list = {
262 union acpi_object *ret_obj;
267 handle = ACPI_HANDLE(dev);
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);
277 ret_obj = buffer.pointer;
279 dev_err(dev, "can't locate ACPI buffer\n");
283 if (ret_obj->type != ACPI_TYPE_STRING) {
284 dev_err(dev, "found non-string entry\n");
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");
296 memcpy(fw_loader->sensor_name, ret_obj->string.pointer,
297 ret_obj->string.length);
299 string_lower(fw_loader->sensor_name, fw_loader->sensor_name);
302 ACPI_FREE(buffer.pointer);
307 static int vsc_identify_silicon(struct vsc_fw_loader *fw_loader)
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;
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;
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;
333 version = FIELD_GET(VSC_MAINSTEPPING_VERSION_MASK, ack->payload[0]);
334 sub_version = FIELD_GET(VSC_SUBSTEPPING_VERSION_MASK, ack->payload[0]);
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);
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);
349 dev_info(fw_loader->dev, "silicon stepping version is %u:%u\n",
350 version, sub_version);
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);
360 if (ack->token == VSC_TOKEN_ERROR)
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);
368 if (ack->token != VSC_TOKEN_DUMP_RESP)
374 static int vsc_identify_csi_image(struct vsc_fw_loader *fw_loader)
376 const struct firmware *image;
377 struct vsc_fw_sign *sign;
382 ret = request_firmware(&image, VSC_CSI_IMAGE_NAME, fw_loader->dev);
386 img = (struct vsc_img *)image->data;
389 goto err_release_image;
392 if (le32_to_cpu(img->magic) != VSC_MAGIC_FILE) {
394 goto err_release_image;
397 if (le32_to_cpu(img->image_count) != VSC_CSI_IMG_CNT) {
399 goto err_release_image;
401 fw_loader->count += le32_to_cpu(img->image_count) - 1;
404 FIELD_GET(VSC_BOOT_IMG_OPTION_MASK, le32_to_cpu(img->option));
406 sign = (struct vsc_fw_sign *)
407 (img->image_location + le32_to_cpu(img->image_count));
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 },
417 struct vsc_img_frag *frag;
419 if ((u8 *)sign + sizeof(*sign) > image->data + image->size) {
421 goto err_release_image;
424 if (le32_to_cpu(sign->magic) != VSC_MAGIC_FW) {
426 goto err_release_image;
429 if (!le32_to_cpu(img->image_location[i])) {
431 goto err_release_image;
434 frag = &fw_loader->frags[csi_image_map[i].frag_index];
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;
441 sign = (struct vsc_fw_sign *)
442 (sign->image + le32_to_cpu(sign->image_size));
445 fw_loader->csi = image;
450 release_firmware(image);
455 static int vsc_identify_ace_image(struct vsc_fw_loader *fw_loader)
457 char path[VSC_IMAGE_PATH_MAX_LEN];
458 const struct firmware *image;
459 struct vsc_fw_sign *sign;
464 snprintf(path, sizeof(path), VSC_ACE_IMAGE_NAME_FMT,
465 fw_loader->sensor_name);
467 ret = request_firmware(&image, path, fw_loader->dev);
471 img = (struct vsc_img *)image->data;
474 goto err_release_image;
477 if (le32_to_cpu(img->magic) != VSC_MAGIC_FILE) {
479 goto err_release_image;
482 if (le32_to_cpu(img->image_count) != VSC_ACE_IMG_CNT) {
484 goto err_release_image;
486 fw_loader->count += le32_to_cpu(img->image_count);
488 sign = (struct vsc_fw_sign *)
489 (img->image_location + le32_to_cpu(img->image_count));
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 },
497 struct vsc_img_frag *frag, *last_frag;
500 if ((u8 *)sign + sizeof(*sign) > image->data + image->size) {
502 goto err_release_image;
505 if (le32_to_cpu(sign->magic) != VSC_MAGIC_FW) {
507 goto err_release_image;
510 frag_index = ace_image_map[i].frag_index;
511 frag = &fw_loader->frags[frag_index];
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;
518 if (!frag->location) {
519 last_frag = &fw_loader->frags[frag_index - 1];
521 ALIGN(last_frag->location + last_frag->size, SZ_4K);
524 sign = (struct vsc_fw_sign *)
525 (sign->image + le32_to_cpu(sign->image_size));
528 fw_loader->ace = image;
533 release_firmware(image);
538 static int vsc_identify_cfg_image(struct vsc_fw_loader *fw_loader)
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;
546 snprintf(path, sizeof(path), VSC_CFG_IMAGE_NAME_FMT,
547 fw_loader->sensor_name);
549 ret = request_firmware(&image, path, fw_loader->dev);
553 /* identify image size */
554 if (image->size <= sizeof(u32) || image->size > VSC_SKU_MAX_SIZE) {
556 goto err_release_image;
559 size = le32_to_cpu(*((__le32 *)image->data)) + sizeof(u32);
560 if (image->size != size) {
562 goto err_release_image;
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;
570 fw_loader->cfg = image;
575 release_firmware(image);
580 static int vsc_download_bootloader(struct vsc_fw_loader *fw_loader)
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;
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);
595 if (ack->token != VSC_TOKEN_DUMP_RESP &&
596 ack->token != VSC_TOKEN_BOOTLOADER_REQ)
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);
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));
609 ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_ROM_PKG_SIZE);
616 /* download image data */
618 len = min(remain, sizeof(cmd->data.dl_cont.payload));
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);
626 ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_ROM_PKG_SIZE);
637 static int vsc_download_firmware(struct vsc_fw_loader *fw_loader)
639 struct vsc_fw_cmd *cmd = fw_loader->tx_buf;
640 unsigned int i, index = 0;
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);
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];
652 cmd->data.dl_set.payload[index++] = cpu_to_le32(frag->location);
653 cmd->data.dl_set.payload[index++] = cpu_to_le32(frag->size);
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));
659 ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
663 for (i = VSC_IMG_CSI_SEM_FRAG; i < VSC_IMG_FRAG_MAX; i++) {
664 struct vsc_img_frag *frag = &fw_loader->frags[i];
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);
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));
678 ret = vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
685 /* download image data */
687 u32 len = min(remain, VSC_FW_PKG_SIZE);
689 memcpy(fw_loader->tx_buf, p, len);
690 memset(fw_loader->tx_buf + len, 0, VSC_FW_PKG_SIZE - len);
692 ret = vsc_tp_rom_xfer(fw_loader->tp, fw_loader->tx_buf,
693 NULL, VSC_FW_PKG_SIZE);
702 cmd->magic = cpu_to_le32(VSC_MAGIC_NUM);
703 cmd->cmd_id = VSC_CMD_CAM_BOOT;
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));
708 return vsc_tp_rom_xfer(fw_loader->tp, cmd, NULL, VSC_FW_PKG_SIZE);
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
717 int vsc_tp_init(struct vsc_tp *tp, struct device *dev)
719 struct vsc_fw_loader *fw_loader __free(kfree) = NULL;
720 void *tx_buf __free(kfree) = NULL;
721 void *rx_buf __free(kfree) = NULL;
724 fw_loader = kzalloc(sizeof(*fw_loader), GFP_KERNEL);
728 tx_buf = kzalloc(VSC_FW_PKG_SIZE, GFP_KERNEL);
732 rx_buf = kzalloc(VSC_FW_PKG_SIZE, GFP_KERNEL);
736 fw_loader->tx_buf = tx_buf;
737 fw_loader->rx_buf = rx_buf;
740 fw_loader->dev = dev;
742 ret = vsc_get_sensor_name(fw_loader, dev);
746 ret = vsc_identify_silicon(fw_loader);
750 ret = vsc_identify_csi_image(fw_loader);
754 ret = vsc_identify_ace_image(fw_loader);
756 goto err_release_csi;
758 ret = vsc_identify_cfg_image(fw_loader);
760 goto err_release_ace;
762 ret = vsc_download_bootloader(fw_loader);
764 ret = vsc_download_firmware(fw_loader);
766 release_firmware(fw_loader->cfg);
769 release_firmware(fw_loader->ace);
772 release_firmware(fw_loader->csi);
776 EXPORT_SYMBOL_NS_GPL(vsc_tp_init, "VSC_TP");