vsc-fw-loader.c 18 KB

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