rmi_f34v7.c 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383
  1. /*
  2. * Copyright (c) 2016, Zodiac Inflight Innovations
  3. * Copyright (c) 2007-2016, Synaptics Incorporated
  4. * Copyright (C) 2012 Alexandra Chin <alexandra.chin@tw.synaptics.com>
  5. * Copyright (C) 2012 Scott Lin <scott.lin@tw.synaptics.com>
  6. *
  7. * This program is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License version 2 as published by
  9. * the Free Software Foundation.
  10. */
  11. #include <linux/kernel.h>
  12. #include <linux/rmi.h>
  13. #include <linux/firmware.h>
  14. #include <asm/unaligned.h>
  15. #include <linux/delay.h>
  16. #include <linux/slab.h>
  17. #include "rmi_driver.h"
  18. #include "rmi_f34.h"
  19. static int rmi_f34v7_read_flash_status(struct f34_data *f34)
  20. {
  21. u8 status;
  22. u8 command;
  23. int ret;
  24. ret = rmi_read_block(f34->fn->rmi_dev,
  25. f34->fn->fd.data_base_addr + f34->v7.off.flash_status,
  26. &status,
  27. sizeof(status));
  28. if (ret < 0) {
  29. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  30. "%s: Failed to read flash status\n", __func__);
  31. return ret;
  32. }
  33. f34->v7.in_bl_mode = status >> 7;
  34. f34->v7.flash_status = status & 0x1f;
  35. if (f34->v7.flash_status != 0x00) {
  36. dev_err(&f34->fn->dev, "%s: status=%d, command=0x%02x\n",
  37. __func__, f34->v7.flash_status, f34->v7.command);
  38. }
  39. ret = rmi_read_block(f34->fn->rmi_dev,
  40. f34->fn->fd.data_base_addr + f34->v7.off.flash_cmd,
  41. &command,
  42. sizeof(command));
  43. if (ret < 0) {
  44. dev_err(&f34->fn->dev, "%s: Failed to read flash command\n",
  45. __func__);
  46. return ret;
  47. }
  48. f34->v7.command = command;
  49. return 0;
  50. }
  51. static int rmi_f34v7_wait_for_idle(struct f34_data *f34, int timeout_ms)
  52. {
  53. int count = 0;
  54. int timeout_count = ((timeout_ms * 1000) / MAX_SLEEP_TIME_US) + 1;
  55. do {
  56. usleep_range(MIN_SLEEP_TIME_US, MAX_SLEEP_TIME_US);
  57. count++;
  58. rmi_f34v7_read_flash_status(f34);
  59. if ((f34->v7.command == v7_CMD_IDLE)
  60. && (f34->v7.flash_status == 0x00)) {
  61. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  62. "Idle status detected\n");
  63. return 0;
  64. }
  65. } while (count < timeout_count);
  66. dev_err(&f34->fn->dev,
  67. "%s: Timed out waiting for idle status\n", __func__);
  68. return -ETIMEDOUT;
  69. }
  70. static int rmi_f34v7_write_command_single_transaction(struct f34_data *f34,
  71. u8 cmd)
  72. {
  73. int ret;
  74. u8 base;
  75. struct f34v7_data_1_5 data_1_5;
  76. base = f34->fn->fd.data_base_addr;
  77. memset(&data_1_5, 0, sizeof(data_1_5));
  78. switch (cmd) {
  79. case v7_CMD_ERASE_ALL:
  80. data_1_5.partition_id = CORE_CODE_PARTITION;
  81. data_1_5.command = CMD_V7_ERASE_AP;
  82. break;
  83. case v7_CMD_ERASE_UI_FIRMWARE:
  84. data_1_5.partition_id = CORE_CODE_PARTITION;
  85. data_1_5.command = CMD_V7_ERASE;
  86. break;
  87. case v7_CMD_ERASE_BL_CONFIG:
  88. data_1_5.partition_id = GLOBAL_PARAMETERS_PARTITION;
  89. data_1_5.command = CMD_V7_ERASE;
  90. break;
  91. case v7_CMD_ERASE_UI_CONFIG:
  92. data_1_5.partition_id = CORE_CONFIG_PARTITION;
  93. data_1_5.command = CMD_V7_ERASE;
  94. break;
  95. case v7_CMD_ERASE_DISP_CONFIG:
  96. data_1_5.partition_id = DISPLAY_CONFIG_PARTITION;
  97. data_1_5.command = CMD_V7_ERASE;
  98. break;
  99. case v7_CMD_ERASE_FLASH_CONFIG:
  100. data_1_5.partition_id = FLASH_CONFIG_PARTITION;
  101. data_1_5.command = CMD_V7_ERASE;
  102. break;
  103. case v7_CMD_ERASE_GUEST_CODE:
  104. data_1_5.partition_id = GUEST_CODE_PARTITION;
  105. data_1_5.command = CMD_V7_ERASE;
  106. break;
  107. case v7_CMD_ENABLE_FLASH_PROG:
  108. data_1_5.partition_id = BOOTLOADER_PARTITION;
  109. data_1_5.command = CMD_V7_ENTER_BL;
  110. break;
  111. }
  112. data_1_5.payload[0] = f34->bootloader_id[0];
  113. data_1_5.payload[1] = f34->bootloader_id[1];
  114. ret = rmi_write_block(f34->fn->rmi_dev,
  115. base + f34->v7.off.partition_id,
  116. &data_1_5, sizeof(data_1_5));
  117. if (ret < 0) {
  118. dev_err(&f34->fn->dev,
  119. "%s: Failed to write single transaction command\n",
  120. __func__);
  121. return ret;
  122. }
  123. return 0;
  124. }
  125. static int rmi_f34v7_write_command(struct f34_data *f34, u8 cmd)
  126. {
  127. int ret;
  128. u8 base;
  129. u8 command;
  130. base = f34->fn->fd.data_base_addr;
  131. switch (cmd) {
  132. case v7_CMD_WRITE_FW:
  133. case v7_CMD_WRITE_CONFIG:
  134. case v7_CMD_WRITE_GUEST_CODE:
  135. command = CMD_V7_WRITE;
  136. break;
  137. case v7_CMD_READ_CONFIG:
  138. command = CMD_V7_READ;
  139. break;
  140. case v7_CMD_ERASE_ALL:
  141. command = CMD_V7_ERASE_AP;
  142. break;
  143. case v7_CMD_ERASE_UI_FIRMWARE:
  144. case v7_CMD_ERASE_BL_CONFIG:
  145. case v7_CMD_ERASE_UI_CONFIG:
  146. case v7_CMD_ERASE_DISP_CONFIG:
  147. case v7_CMD_ERASE_FLASH_CONFIG:
  148. case v7_CMD_ERASE_GUEST_CODE:
  149. command = CMD_V7_ERASE;
  150. break;
  151. case v7_CMD_ENABLE_FLASH_PROG:
  152. command = CMD_V7_ENTER_BL;
  153. break;
  154. default:
  155. dev_err(&f34->fn->dev, "%s: Invalid command 0x%02x\n",
  156. __func__, cmd);
  157. return -EINVAL;
  158. }
  159. f34->v7.command = command;
  160. switch (cmd) {
  161. case v7_CMD_ERASE_ALL:
  162. case v7_CMD_ERASE_UI_FIRMWARE:
  163. case v7_CMD_ERASE_BL_CONFIG:
  164. case v7_CMD_ERASE_UI_CONFIG:
  165. case v7_CMD_ERASE_DISP_CONFIG:
  166. case v7_CMD_ERASE_FLASH_CONFIG:
  167. case v7_CMD_ERASE_GUEST_CODE:
  168. case v7_CMD_ENABLE_FLASH_PROG:
  169. ret = rmi_f34v7_write_command_single_transaction(f34, cmd);
  170. if (ret < 0)
  171. return ret;
  172. else
  173. return 0;
  174. default:
  175. break;
  176. }
  177. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: writing cmd %02X\n",
  178. __func__, command);
  179. ret = rmi_write_block(f34->fn->rmi_dev,
  180. base + f34->v7.off.flash_cmd,
  181. &command, sizeof(command));
  182. if (ret < 0) {
  183. dev_err(&f34->fn->dev, "%s: Failed to write flash command\n",
  184. __func__);
  185. return ret;
  186. }
  187. return 0;
  188. }
  189. static int rmi_f34v7_write_partition_id(struct f34_data *f34, u8 cmd)
  190. {
  191. int ret;
  192. u8 base;
  193. u8 partition;
  194. base = f34->fn->fd.data_base_addr;
  195. switch (cmd) {
  196. case v7_CMD_WRITE_FW:
  197. partition = CORE_CODE_PARTITION;
  198. break;
  199. case v7_CMD_WRITE_CONFIG:
  200. case v7_CMD_READ_CONFIG:
  201. if (f34->v7.config_area == v7_UI_CONFIG_AREA)
  202. partition = CORE_CONFIG_PARTITION;
  203. else if (f34->v7.config_area == v7_DP_CONFIG_AREA)
  204. partition = DISPLAY_CONFIG_PARTITION;
  205. else if (f34->v7.config_area == v7_PM_CONFIG_AREA)
  206. partition = GUEST_SERIALIZATION_PARTITION;
  207. else if (f34->v7.config_area == v7_BL_CONFIG_AREA)
  208. partition = GLOBAL_PARAMETERS_PARTITION;
  209. else if (f34->v7.config_area == v7_FLASH_CONFIG_AREA)
  210. partition = FLASH_CONFIG_PARTITION;
  211. break;
  212. case v7_CMD_WRITE_GUEST_CODE:
  213. partition = GUEST_CODE_PARTITION;
  214. break;
  215. case v7_CMD_ERASE_ALL:
  216. partition = CORE_CODE_PARTITION;
  217. break;
  218. case v7_CMD_ERASE_BL_CONFIG:
  219. partition = GLOBAL_PARAMETERS_PARTITION;
  220. break;
  221. case v7_CMD_ERASE_UI_CONFIG:
  222. partition = CORE_CONFIG_PARTITION;
  223. break;
  224. case v7_CMD_ERASE_DISP_CONFIG:
  225. partition = DISPLAY_CONFIG_PARTITION;
  226. break;
  227. case v7_CMD_ERASE_FLASH_CONFIG:
  228. partition = FLASH_CONFIG_PARTITION;
  229. break;
  230. case v7_CMD_ERASE_GUEST_CODE:
  231. partition = GUEST_CODE_PARTITION;
  232. break;
  233. case v7_CMD_ENABLE_FLASH_PROG:
  234. partition = BOOTLOADER_PARTITION;
  235. break;
  236. default:
  237. dev_err(&f34->fn->dev, "%s: Invalid command 0x%02x\n",
  238. __func__, cmd);
  239. return -EINVAL;
  240. }
  241. ret = rmi_write_block(f34->fn->rmi_dev,
  242. base + f34->v7.off.partition_id,
  243. &partition, sizeof(partition));
  244. if (ret < 0) {
  245. dev_err(&f34->fn->dev, "%s: Failed to write partition ID\n",
  246. __func__);
  247. return ret;
  248. }
  249. return 0;
  250. }
  251. static int rmi_f34v7_read_f34v7_partition_table(struct f34_data *f34)
  252. {
  253. int ret;
  254. u8 base;
  255. __le16 length;
  256. u16 block_number = 0;
  257. base = f34->fn->fd.data_base_addr;
  258. f34->v7.config_area = v7_FLASH_CONFIG_AREA;
  259. ret = rmi_f34v7_write_partition_id(f34, v7_CMD_READ_CONFIG);
  260. if (ret < 0)
  261. return ret;
  262. ret = rmi_write_block(f34->fn->rmi_dev,
  263. base + f34->v7.off.block_number,
  264. &block_number, sizeof(block_number));
  265. if (ret < 0) {
  266. dev_err(&f34->fn->dev, "%s: Failed to write block number\n",
  267. __func__);
  268. return ret;
  269. }
  270. put_unaligned_le16(f34->v7.flash_config_length, &length);
  271. ret = rmi_write_block(f34->fn->rmi_dev,
  272. base + f34->v7.off.transfer_length,
  273. &length, sizeof(length));
  274. if (ret < 0) {
  275. dev_err(&f34->fn->dev, "%s: Failed to write transfer length\n",
  276. __func__);
  277. return ret;
  278. }
  279. ret = rmi_f34v7_write_command(f34, v7_CMD_READ_CONFIG);
  280. if (ret < 0) {
  281. dev_err(&f34->fn->dev, "%s: Failed to write command\n",
  282. __func__);
  283. return ret;
  284. }
  285. ret = rmi_f34v7_wait_for_idle(f34, WRITE_WAIT_MS);
  286. if (ret < 0) {
  287. dev_err(&f34->fn->dev, "%s: Failed to wait for idle status\n",
  288. __func__);
  289. return ret;
  290. }
  291. ret = rmi_read_block(f34->fn->rmi_dev,
  292. base + f34->v7.off.payload,
  293. f34->v7.read_config_buf,
  294. f34->v7.partition_table_bytes);
  295. if (ret < 0) {
  296. dev_err(&f34->fn->dev, "%s: Failed to read block data\n",
  297. __func__);
  298. return ret;
  299. }
  300. return 0;
  301. }
  302. static void rmi_f34v7_parse_partition_table(struct f34_data *f34,
  303. const void *partition_table,
  304. struct block_count *blkcount,
  305. struct physical_address *phyaddr)
  306. {
  307. int i;
  308. int index;
  309. u16 partition_length;
  310. u16 physical_address;
  311. const struct partition_table *ptable;
  312. for (i = 0; i < f34->v7.partitions; i++) {
  313. index = i * 8 + 2;
  314. ptable = partition_table + index;
  315. partition_length = le16_to_cpu(ptable->partition_length);
  316. physical_address = le16_to_cpu(ptable->start_physical_address);
  317. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  318. "%s: Partition entry %d: %*ph\n",
  319. __func__, i, sizeof(struct partition_table), ptable);
  320. switch (ptable->partition_id & 0x1f) {
  321. case CORE_CODE_PARTITION:
  322. blkcount->ui_firmware = partition_length;
  323. phyaddr->ui_firmware = physical_address;
  324. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  325. "%s: Core code block count: %d\n",
  326. __func__, blkcount->ui_firmware);
  327. break;
  328. case CORE_CONFIG_PARTITION:
  329. blkcount->ui_config = partition_length;
  330. phyaddr->ui_config = physical_address;
  331. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  332. "%s: Core config block count: %d\n",
  333. __func__, blkcount->ui_config);
  334. break;
  335. case DISPLAY_CONFIG_PARTITION:
  336. blkcount->dp_config = partition_length;
  337. phyaddr->dp_config = physical_address;
  338. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  339. "%s: Display config block count: %d\n",
  340. __func__, blkcount->dp_config);
  341. break;
  342. case FLASH_CONFIG_PARTITION:
  343. blkcount->fl_config = partition_length;
  344. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  345. "%s: Flash config block count: %d\n",
  346. __func__, blkcount->fl_config);
  347. break;
  348. case GUEST_CODE_PARTITION:
  349. blkcount->guest_code = partition_length;
  350. phyaddr->guest_code = physical_address;
  351. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  352. "%s: Guest code block count: %d\n",
  353. __func__, blkcount->guest_code);
  354. break;
  355. case GUEST_SERIALIZATION_PARTITION:
  356. blkcount->pm_config = partition_length;
  357. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  358. "%s: Guest serialization block count: %d\n",
  359. __func__, blkcount->pm_config);
  360. break;
  361. case GLOBAL_PARAMETERS_PARTITION:
  362. blkcount->bl_config = partition_length;
  363. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  364. "%s: Global parameters block count: %d\n",
  365. __func__, blkcount->bl_config);
  366. break;
  367. case DEVICE_CONFIG_PARTITION:
  368. blkcount->lockdown = partition_length;
  369. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  370. "%s: Device config block count: %d\n",
  371. __func__, blkcount->lockdown);
  372. break;
  373. }
  374. }
  375. }
  376. static int rmi_f34v7_read_queries_bl_version(struct f34_data *f34)
  377. {
  378. int ret;
  379. u8 base;
  380. int offset;
  381. u8 query_0;
  382. struct f34v7_query_1_7 query_1_7;
  383. base = f34->fn->fd.query_base_addr;
  384. ret = rmi_read_block(f34->fn->rmi_dev,
  385. base,
  386. &query_0,
  387. sizeof(query_0));
  388. if (ret < 0) {
  389. dev_err(&f34->fn->dev,
  390. "%s: Failed to read query 0\n", __func__);
  391. return ret;
  392. }
  393. offset = (query_0 & 0x7) + 1;
  394. ret = rmi_read_block(f34->fn->rmi_dev,
  395. base + offset,
  396. &query_1_7,
  397. sizeof(query_1_7));
  398. if (ret < 0) {
  399. dev_err(&f34->fn->dev, "%s: Failed to read queries 1 to 7\n",
  400. __func__);
  401. return ret;
  402. }
  403. f34->bootloader_id[0] = query_1_7.bl_minor_revision;
  404. f34->bootloader_id[1] = query_1_7.bl_major_revision;
  405. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "Bootloader V%d.%d\n",
  406. f34->bootloader_id[1], f34->bootloader_id[0]);
  407. return 0;
  408. }
  409. static int rmi_f34v7_read_queries(struct f34_data *f34)
  410. {
  411. int ret;
  412. int i, j;
  413. u8 base;
  414. int offset;
  415. u8 *ptable;
  416. u8 query_0;
  417. struct f34v7_query_1_7 query_1_7;
  418. base = f34->fn->fd.query_base_addr;
  419. ret = rmi_read_block(f34->fn->rmi_dev,
  420. base,
  421. &query_0,
  422. sizeof(query_0));
  423. if (ret < 0) {
  424. dev_err(&f34->fn->dev,
  425. "%s: Failed to read query 0\n", __func__);
  426. return ret;
  427. }
  428. offset = (query_0 & 0x07) + 1;
  429. ret = rmi_read_block(f34->fn->rmi_dev,
  430. base + offset,
  431. &query_1_7,
  432. sizeof(query_1_7));
  433. if (ret < 0) {
  434. dev_err(&f34->fn->dev, "%s: Failed to read queries 1 to 7\n",
  435. __func__);
  436. return ret;
  437. }
  438. f34->bootloader_id[0] = query_1_7.bl_minor_revision;
  439. f34->bootloader_id[1] = query_1_7.bl_major_revision;
  440. f34->v7.block_size = le16_to_cpu(query_1_7.block_size);
  441. f34->v7.flash_config_length =
  442. le16_to_cpu(query_1_7.flash_config_length);
  443. f34->v7.payload_length = le16_to_cpu(query_1_7.payload_length);
  444. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: f34->v7.block_size = %d\n",
  445. __func__, f34->v7.block_size);
  446. f34->v7.off.flash_status = V7_FLASH_STATUS_OFFSET;
  447. f34->v7.off.partition_id = V7_PARTITION_ID_OFFSET;
  448. f34->v7.off.block_number = V7_BLOCK_NUMBER_OFFSET;
  449. f34->v7.off.transfer_length = V7_TRANSFER_LENGTH_OFFSET;
  450. f34->v7.off.flash_cmd = V7_COMMAND_OFFSET;
  451. f34->v7.off.payload = V7_PAYLOAD_OFFSET;
  452. f34->v7.has_display_cfg = query_1_7.partition_support[1] & HAS_DISP_CFG;
  453. f34->v7.has_guest_code =
  454. query_1_7.partition_support[1] & HAS_GUEST_CODE;
  455. if (query_0 & HAS_CONFIG_ID) {
  456. char f34_ctrl[CONFIG_ID_SIZE];
  457. int i = 0;
  458. u8 *p = f34->configuration_id;
  459. *p = '\0';
  460. ret = rmi_read_block(f34->fn->rmi_dev,
  461. f34->fn->fd.control_base_addr,
  462. f34_ctrl,
  463. sizeof(f34_ctrl));
  464. if (ret)
  465. return ret;
  466. /* Eat leading zeros */
  467. while (i < sizeof(f34_ctrl) && !f34_ctrl[i])
  468. i++;
  469. for (; i < sizeof(f34_ctrl); i++)
  470. p += snprintf(p, f34->configuration_id
  471. + sizeof(f34->configuration_id) - p,
  472. "%02X", f34_ctrl[i]);
  473. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "Configuration ID: %s\n",
  474. f34->configuration_id);
  475. }
  476. f34->v7.partitions = 0;
  477. for (i = 0; i < sizeof(query_1_7.partition_support); i++)
  478. for (j = 0; j < 8; j++)
  479. if (query_1_7.partition_support[i] & (1 << j))
  480. f34->v7.partitions++;
  481. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: Supported partitions: %*ph\n",
  482. __func__, sizeof(query_1_7.partition_support),
  483. query_1_7.partition_support);
  484. f34->v7.partition_table_bytes = f34->v7.partitions * 8 + 2;
  485. f34->v7.read_config_buf = devm_kzalloc(&f34->fn->dev,
  486. f34->v7.partition_table_bytes,
  487. GFP_KERNEL);
  488. if (!f34->v7.read_config_buf) {
  489. f34->v7.read_config_buf_size = 0;
  490. return -ENOMEM;
  491. }
  492. f34->v7.read_config_buf_size = f34->v7.partition_table_bytes;
  493. ptable = f34->v7.read_config_buf;
  494. ret = rmi_f34v7_read_f34v7_partition_table(f34);
  495. if (ret < 0) {
  496. dev_err(&f34->fn->dev, "%s: Failed to read partition table\n",
  497. __func__);
  498. return ret;
  499. }
  500. rmi_f34v7_parse_partition_table(f34, ptable,
  501. &f34->v7.blkcount, &f34->v7.phyaddr);
  502. return 0;
  503. }
  504. static int rmi_f34v7_check_ui_firmware_size(struct f34_data *f34)
  505. {
  506. u16 block_count;
  507. block_count = f34->v7.img.ui_firmware.size / f34->v7.block_size;
  508. f34->update_size += block_count;
  509. if (block_count != f34->v7.blkcount.ui_firmware) {
  510. dev_err(&f34->fn->dev,
  511. "UI firmware size mismatch: %d != %d\n",
  512. block_count, f34->v7.blkcount.ui_firmware);
  513. return -EINVAL;
  514. }
  515. return 0;
  516. }
  517. static int rmi_f34v7_check_ui_config_size(struct f34_data *f34)
  518. {
  519. u16 block_count;
  520. block_count = f34->v7.img.ui_config.size / f34->v7.block_size;
  521. f34->update_size += block_count;
  522. if (block_count != f34->v7.blkcount.ui_config) {
  523. dev_err(&f34->fn->dev, "UI config size mismatch\n");
  524. return -EINVAL;
  525. }
  526. return 0;
  527. }
  528. static int rmi_f34v7_check_dp_config_size(struct f34_data *f34)
  529. {
  530. u16 block_count;
  531. block_count = f34->v7.img.dp_config.size / f34->v7.block_size;
  532. f34->update_size += block_count;
  533. if (block_count != f34->v7.blkcount.dp_config) {
  534. dev_err(&f34->fn->dev, "Display config size mismatch\n");
  535. return -EINVAL;
  536. }
  537. return 0;
  538. }
  539. static int rmi_f34v7_check_guest_code_size(struct f34_data *f34)
  540. {
  541. u16 block_count;
  542. block_count = f34->v7.img.guest_code.size / f34->v7.block_size;
  543. f34->update_size += block_count;
  544. if (block_count != f34->v7.blkcount.guest_code) {
  545. dev_err(&f34->fn->dev, "Guest code size mismatch\n");
  546. return -EINVAL;
  547. }
  548. return 0;
  549. }
  550. static int rmi_f34v7_check_bl_config_size(struct f34_data *f34)
  551. {
  552. u16 block_count;
  553. block_count = f34->v7.img.bl_config.size / f34->v7.block_size;
  554. f34->update_size += block_count;
  555. if (block_count != f34->v7.blkcount.bl_config) {
  556. dev_err(&f34->fn->dev, "Bootloader config size mismatch\n");
  557. return -EINVAL;
  558. }
  559. return 0;
  560. }
  561. static int rmi_f34v7_erase_config(struct f34_data *f34)
  562. {
  563. int ret;
  564. dev_info(&f34->fn->dev, "Erasing config...\n");
  565. switch (f34->v7.config_area) {
  566. case v7_UI_CONFIG_AREA:
  567. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_CONFIG);
  568. if (ret < 0)
  569. return ret;
  570. break;
  571. case v7_DP_CONFIG_AREA:
  572. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_DISP_CONFIG);
  573. if (ret < 0)
  574. return ret;
  575. break;
  576. case v7_BL_CONFIG_AREA:
  577. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_BL_CONFIG);
  578. if (ret < 0)
  579. return ret;
  580. break;
  581. }
  582. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  583. if (ret < 0)
  584. return ret;
  585. return ret;
  586. }
  587. static int rmi_f34v7_erase_guest_code(struct f34_data *f34)
  588. {
  589. int ret;
  590. dev_info(&f34->fn->dev, "Erasing guest code...\n");
  591. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_GUEST_CODE);
  592. if (ret < 0)
  593. return ret;
  594. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  595. if (ret < 0)
  596. return ret;
  597. return 0;
  598. }
  599. static int rmi_f34v7_erase_all(struct f34_data *f34)
  600. {
  601. int ret;
  602. dev_info(&f34->fn->dev, "Erasing firmware...\n");
  603. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_FIRMWARE);
  604. if (ret < 0)
  605. return ret;
  606. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  607. if (ret < 0)
  608. return ret;
  609. f34->v7.config_area = v7_UI_CONFIG_AREA;
  610. ret = rmi_f34v7_erase_config(f34);
  611. if (ret < 0)
  612. return ret;
  613. if (f34->v7.has_display_cfg) {
  614. f34->v7.config_area = v7_DP_CONFIG_AREA;
  615. ret = rmi_f34v7_erase_config(f34);
  616. if (ret < 0)
  617. return ret;
  618. }
  619. if (f34->v7.new_partition_table && f34->v7.has_guest_code) {
  620. ret = rmi_f34v7_erase_guest_code(f34);
  621. if (ret < 0)
  622. return ret;
  623. }
  624. return 0;
  625. }
  626. static int rmi_f34v7_read_f34v7_blocks(struct f34_data *f34, u16 block_cnt,
  627. u8 command)
  628. {
  629. int ret;
  630. u8 base;
  631. __le16 length;
  632. u16 transfer;
  633. u16 max_transfer;
  634. u16 remaining = block_cnt;
  635. u16 block_number = 0;
  636. u16 index = 0;
  637. base = f34->fn->fd.data_base_addr;
  638. ret = rmi_f34v7_write_partition_id(f34, command);
  639. if (ret < 0)
  640. return ret;
  641. ret = rmi_write_block(f34->fn->rmi_dev,
  642. base + f34->v7.off.block_number,
  643. &block_number, sizeof(block_number));
  644. if (ret < 0) {
  645. dev_err(&f34->fn->dev, "%s: Failed to write block number\n",
  646. __func__);
  647. return ret;
  648. }
  649. max_transfer = min(f34->v7.payload_length,
  650. (u16)(PAGE_SIZE / f34->v7.block_size));
  651. do {
  652. transfer = min(remaining, max_transfer);
  653. put_unaligned_le16(transfer, &length);
  654. ret = rmi_write_block(f34->fn->rmi_dev,
  655. base + f34->v7.off.transfer_length,
  656. &length, sizeof(length));
  657. if (ret < 0) {
  658. dev_err(&f34->fn->dev,
  659. "%s: Write transfer length fail (%d remaining)\n",
  660. __func__, remaining);
  661. return ret;
  662. }
  663. ret = rmi_f34v7_write_command(f34, command);
  664. if (ret < 0)
  665. return ret;
  666. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  667. if (ret < 0) {
  668. dev_err(&f34->fn->dev,
  669. "%s: Wait for idle failed (%d blks remaining)\n",
  670. __func__, remaining);
  671. return ret;
  672. }
  673. ret = rmi_read_block(f34->fn->rmi_dev,
  674. base + f34->v7.off.payload,
  675. &f34->v7.read_config_buf[index],
  676. transfer * f34->v7.block_size);
  677. if (ret < 0) {
  678. dev_err(&f34->fn->dev,
  679. "%s: Read block failed (%d blks remaining)\n",
  680. __func__, remaining);
  681. return ret;
  682. }
  683. index += (transfer * f34->v7.block_size);
  684. remaining -= transfer;
  685. } while (remaining);
  686. return 0;
  687. }
  688. static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
  689. const void *block_ptr, u16 block_cnt,
  690. u8 command)
  691. {
  692. int ret;
  693. u8 base;
  694. __le16 length;
  695. u16 transfer;
  696. u16 max_transfer;
  697. u16 remaining = block_cnt;
  698. u16 block_number = 0;
  699. base = f34->fn->fd.data_base_addr;
  700. ret = rmi_f34v7_write_partition_id(f34, command);
  701. if (ret < 0)
  702. return ret;
  703. ret = rmi_write_block(f34->fn->rmi_dev,
  704. base + f34->v7.off.block_number,
  705. &block_number, sizeof(block_number));
  706. if (ret < 0) {
  707. dev_err(&f34->fn->dev, "%s: Failed to write block number\n",
  708. __func__);
  709. return ret;
  710. }
  711. if (f34->v7.payload_length > (PAGE_SIZE / f34->v7.block_size))
  712. max_transfer = PAGE_SIZE / f34->v7.block_size;
  713. else
  714. max_transfer = f34->v7.payload_length;
  715. do {
  716. transfer = min(remaining, max_transfer);
  717. put_unaligned_le16(transfer, &length);
  718. ret = rmi_write_block(f34->fn->rmi_dev,
  719. base + f34->v7.off.transfer_length,
  720. &length, sizeof(length));
  721. if (ret < 0) {
  722. dev_err(&f34->fn->dev,
  723. "%s: Write transfer length fail (%d remaining)\n",
  724. __func__, remaining);
  725. return ret;
  726. }
  727. ret = rmi_f34v7_write_command(f34, command);
  728. if (ret < 0)
  729. return ret;
  730. ret = rmi_write_block(f34->fn->rmi_dev,
  731. base + f34->v7.off.payload,
  732. block_ptr, transfer * f34->v7.block_size);
  733. if (ret < 0) {
  734. dev_err(&f34->fn->dev,
  735. "%s: Failed writing data (%d blks remaining)\n",
  736. __func__, remaining);
  737. return ret;
  738. }
  739. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  740. if (ret < 0) {
  741. dev_err(&f34->fn->dev,
  742. "%s: Failed wait for idle (%d blks remaining)\n",
  743. __func__, remaining);
  744. return ret;
  745. }
  746. block_ptr += (transfer * f34->v7.block_size);
  747. remaining -= transfer;
  748. f34->update_progress += transfer;
  749. f34->update_status = (f34->update_progress * 100) /
  750. f34->update_size;
  751. } while (remaining);
  752. return 0;
  753. }
  754. static int rmi_f34v7_write_config(struct f34_data *f34)
  755. {
  756. return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.config_data,
  757. f34->v7.config_block_count,
  758. v7_CMD_WRITE_CONFIG);
  759. }
  760. static int rmi_f34v7_write_ui_config(struct f34_data *f34)
  761. {
  762. f34->v7.config_area = v7_UI_CONFIG_AREA;
  763. f34->v7.config_data = f34->v7.img.ui_config.data;
  764. f34->v7.config_size = f34->v7.img.ui_config.size;
  765. f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
  766. return rmi_f34v7_write_config(f34);
  767. }
  768. static int rmi_f34v7_write_dp_config(struct f34_data *f34)
  769. {
  770. f34->v7.config_area = v7_DP_CONFIG_AREA;
  771. f34->v7.config_data = f34->v7.img.dp_config.data;
  772. f34->v7.config_size = f34->v7.img.dp_config.size;
  773. f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
  774. return rmi_f34v7_write_config(f34);
  775. }
  776. static int rmi_f34v7_write_guest_code(struct f34_data *f34)
  777. {
  778. return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.img.guest_code.data,
  779. f34->v7.img.guest_code.size /
  780. f34->v7.block_size,
  781. v7_CMD_WRITE_GUEST_CODE);
  782. }
  783. static int rmi_f34v7_write_flash_config(struct f34_data *f34)
  784. {
  785. int ret;
  786. f34->v7.config_area = v7_FLASH_CONFIG_AREA;
  787. f34->v7.config_data = f34->v7.img.fl_config.data;
  788. f34->v7.config_size = f34->v7.img.fl_config.size;
  789. f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
  790. if (f34->v7.config_block_count != f34->v7.blkcount.fl_config) {
  791. dev_err(&f34->fn->dev, "%s: Flash config size mismatch\n",
  792. __func__);
  793. return -EINVAL;
  794. }
  795. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_FLASH_CONFIG);
  796. if (ret < 0)
  797. return ret;
  798. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  799. "%s: Erase flash config command written\n", __func__);
  800. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  801. if (ret < 0)
  802. return ret;
  803. ret = rmi_f34v7_write_config(f34);
  804. if (ret < 0)
  805. return ret;
  806. return 0;
  807. }
  808. static int rmi_f34v7_write_partition_table(struct f34_data *f34)
  809. {
  810. u16 block_count;
  811. int ret;
  812. block_count = f34->v7.blkcount.bl_config;
  813. f34->v7.config_area = v7_BL_CONFIG_AREA;
  814. f34->v7.config_size = f34->v7.block_size * block_count;
  815. devm_kfree(&f34->fn->dev, f34->v7.read_config_buf);
  816. f34->v7.read_config_buf = devm_kzalloc(&f34->fn->dev,
  817. f34->v7.config_size, GFP_KERNEL);
  818. if (!f34->v7.read_config_buf) {
  819. f34->v7.read_config_buf_size = 0;
  820. return -ENOMEM;
  821. }
  822. f34->v7.read_config_buf_size = f34->v7.config_size;
  823. ret = rmi_f34v7_read_f34v7_blocks(f34, block_count, v7_CMD_READ_CONFIG);
  824. if (ret < 0)
  825. return ret;
  826. ret = rmi_f34v7_erase_config(f34);
  827. if (ret < 0)
  828. return ret;
  829. ret = rmi_f34v7_write_flash_config(f34);
  830. if (ret < 0)
  831. return ret;
  832. f34->v7.config_area = v7_BL_CONFIG_AREA;
  833. f34->v7.config_data = f34->v7.read_config_buf;
  834. f34->v7.config_size = f34->v7.img.bl_config.size;
  835. f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
  836. ret = rmi_f34v7_write_config(f34);
  837. if (ret < 0)
  838. return ret;
  839. return 0;
  840. }
  841. static int rmi_f34v7_write_firmware(struct f34_data *f34)
  842. {
  843. u16 blk_count;
  844. blk_count = f34->v7.img.ui_firmware.size / f34->v7.block_size;
  845. return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.img.ui_firmware.data,
  846. blk_count, v7_CMD_WRITE_FW);
  847. }
  848. static void rmi_f34v7_compare_partition_tables(struct f34_data *f34)
  849. {
  850. if (f34->v7.phyaddr.ui_firmware != f34->v7.img.phyaddr.ui_firmware) {
  851. f34->v7.new_partition_table = true;
  852. return;
  853. }
  854. if (f34->v7.phyaddr.ui_config != f34->v7.img.phyaddr.ui_config) {
  855. f34->v7.new_partition_table = true;
  856. return;
  857. }
  858. if (f34->v7.has_display_cfg &&
  859. f34->v7.phyaddr.dp_config != f34->v7.img.phyaddr.dp_config) {
  860. f34->v7.new_partition_table = true;
  861. return;
  862. }
  863. if (f34->v7.has_guest_code &&
  864. f34->v7.phyaddr.guest_code != f34->v7.img.phyaddr.guest_code) {
  865. f34->v7.new_partition_table = true;
  866. return;
  867. }
  868. f34->v7.new_partition_table = false;
  869. }
  870. static void rmi_f34v7_parse_img_header_10_bl_container(struct f34_data *f34,
  871. const void *image)
  872. {
  873. int i;
  874. int num_of_containers;
  875. unsigned int addr;
  876. unsigned int container_id;
  877. unsigned int length;
  878. const void *content;
  879. const struct container_descriptor *descriptor;
  880. num_of_containers = f34->v7.img.bootloader.size / 4 - 1;
  881. for (i = 1; i <= num_of_containers; i++) {
  882. addr = get_unaligned_le32(f34->v7.img.bootloader.data + i * 4);
  883. descriptor = image + addr;
  884. container_id = le16_to_cpu(descriptor->container_id);
  885. content = image + le32_to_cpu(descriptor->content_address);
  886. length = le32_to_cpu(descriptor->content_length);
  887. switch (container_id) {
  888. case BL_CONFIG_CONTAINER:
  889. case GLOBAL_PARAMETERS_CONTAINER:
  890. f34->v7.img.bl_config.data = content;
  891. f34->v7.img.bl_config.size = length;
  892. break;
  893. case BL_LOCKDOWN_INFO_CONTAINER:
  894. case DEVICE_CONFIG_CONTAINER:
  895. f34->v7.img.lockdown.data = content;
  896. f34->v7.img.lockdown.size = length;
  897. break;
  898. default:
  899. break;
  900. }
  901. }
  902. }
  903. static void rmi_f34v7_parse_image_header_10(struct f34_data *f34)
  904. {
  905. unsigned int i;
  906. unsigned int num_of_containers;
  907. unsigned int addr;
  908. unsigned int offset;
  909. unsigned int container_id;
  910. unsigned int length;
  911. const void *image = f34->v7.image;
  912. const u8 *content;
  913. const struct container_descriptor *descriptor;
  914. const struct image_header_10 *header = image;
  915. f34->v7.img.checksum = le32_to_cpu(header->checksum);
  916. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: f34->v7.img.checksum=%X\n",
  917. __func__, f34->v7.img.checksum);
  918. /* address of top level container */
  919. offset = le32_to_cpu(header->top_level_container_start_addr);
  920. descriptor = image + offset;
  921. /* address of top level container content */
  922. offset = le32_to_cpu(descriptor->content_address);
  923. num_of_containers = le32_to_cpu(descriptor->content_length) / 4;
  924. for (i = 0; i < num_of_containers; i++) {
  925. addr = get_unaligned_le32(image + offset);
  926. offset += 4;
  927. descriptor = image + addr;
  928. container_id = le16_to_cpu(descriptor->container_id);
  929. content = image + le32_to_cpu(descriptor->content_address);
  930. length = le32_to_cpu(descriptor->content_length);
  931. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  932. "%s: container_id=%d, length=%d\n", __func__,
  933. container_id, length);
  934. switch (container_id) {
  935. case UI_CONTAINER:
  936. case CORE_CODE_CONTAINER:
  937. f34->v7.img.ui_firmware.data = content;
  938. f34->v7.img.ui_firmware.size = length;
  939. break;
  940. case UI_CONFIG_CONTAINER:
  941. case CORE_CONFIG_CONTAINER:
  942. f34->v7.img.ui_config.data = content;
  943. f34->v7.img.ui_config.size = length;
  944. break;
  945. case BL_CONTAINER:
  946. f34->v7.img.bl_version = *content;
  947. f34->v7.img.bootloader.data = content;
  948. f34->v7.img.bootloader.size = length;
  949. rmi_f34v7_parse_img_header_10_bl_container(f34, image);
  950. break;
  951. case GUEST_CODE_CONTAINER:
  952. f34->v7.img.contains_guest_code = true;
  953. f34->v7.img.guest_code.data = content;
  954. f34->v7.img.guest_code.size = length;
  955. break;
  956. case DISPLAY_CONFIG_CONTAINER:
  957. f34->v7.img.contains_display_cfg = true;
  958. f34->v7.img.dp_config.data = content;
  959. f34->v7.img.dp_config.size = length;
  960. break;
  961. case FLASH_CONFIG_CONTAINER:
  962. f34->v7.img.contains_flash_config = true;
  963. f34->v7.img.fl_config.data = content;
  964. f34->v7.img.fl_config.size = length;
  965. break;
  966. case GENERAL_INFORMATION_CONTAINER:
  967. f34->v7.img.contains_firmware_id = true;
  968. f34->v7.img.firmware_id =
  969. get_unaligned_le32(content + 4);
  970. break;
  971. default:
  972. break;
  973. }
  974. }
  975. }
  976. static int rmi_f34v7_parse_image_info(struct f34_data *f34)
  977. {
  978. const struct image_header_10 *header = f34->v7.image;
  979. memset(&f34->v7.img, 0x00, sizeof(f34->v7.img));
  980. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  981. "%s: header->major_header_version = %d\n",
  982. __func__, header->major_header_version);
  983. switch (header->major_header_version) {
  984. case IMAGE_HEADER_VERSION_10:
  985. rmi_f34v7_parse_image_header_10(f34);
  986. break;
  987. default:
  988. dev_err(&f34->fn->dev, "Unsupported image file format %02X\n",
  989. header->major_header_version);
  990. return -EINVAL;
  991. }
  992. if (!f34->v7.img.contains_flash_config) {
  993. dev_err(&f34->fn->dev, "%s: No flash config in fw image\n",
  994. __func__);
  995. return -EINVAL;
  996. }
  997. rmi_f34v7_parse_partition_table(f34, f34->v7.img.fl_config.data,
  998. &f34->v7.img.blkcount, &f34->v7.img.phyaddr);
  999. rmi_f34v7_compare_partition_tables(f34);
  1000. return 0;
  1001. }
  1002. int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw)
  1003. {
  1004. int ret;
  1005. rmi_f34v7_read_queries_bl_version(f34);
  1006. f34->v7.image = fw->data;
  1007. f34->update_progress = 0;
  1008. f34->update_size = 0;
  1009. ret = rmi_f34v7_parse_image_info(f34);
  1010. if (ret < 0)
  1011. goto fail;
  1012. if (!f34->v7.new_partition_table) {
  1013. ret = rmi_f34v7_check_ui_firmware_size(f34);
  1014. if (ret < 0)
  1015. goto fail;
  1016. ret = rmi_f34v7_check_ui_config_size(f34);
  1017. if (ret < 0)
  1018. goto fail;
  1019. if (f34->v7.has_display_cfg &&
  1020. f34->v7.img.contains_display_cfg) {
  1021. ret = rmi_f34v7_check_dp_config_size(f34);
  1022. if (ret < 0)
  1023. goto fail;
  1024. }
  1025. if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) {
  1026. ret = rmi_f34v7_check_guest_code_size(f34);
  1027. if (ret < 0)
  1028. goto fail;
  1029. }
  1030. } else {
  1031. ret = rmi_f34v7_check_bl_config_size(f34);
  1032. if (ret < 0)
  1033. goto fail;
  1034. }
  1035. ret = rmi_f34v7_erase_all(f34);
  1036. if (ret < 0)
  1037. goto fail;
  1038. if (f34->v7.new_partition_table) {
  1039. ret = rmi_f34v7_write_partition_table(f34);
  1040. if (ret < 0)
  1041. goto fail;
  1042. dev_info(&f34->fn->dev, "%s: Partition table programmed\n",
  1043. __func__);
  1044. }
  1045. dev_info(&f34->fn->dev, "Writing firmware (%d bytes)...\n",
  1046. f34->v7.img.ui_firmware.size);
  1047. ret = rmi_f34v7_write_firmware(f34);
  1048. if (ret < 0)
  1049. goto fail;
  1050. dev_info(&f34->fn->dev, "Writing config (%d bytes)...\n",
  1051. f34->v7.img.ui_config.size);
  1052. f34->v7.config_area = v7_UI_CONFIG_AREA;
  1053. ret = rmi_f34v7_write_ui_config(f34);
  1054. if (ret < 0)
  1055. goto fail;
  1056. if (f34->v7.has_display_cfg && f34->v7.img.contains_display_cfg) {
  1057. dev_info(&f34->fn->dev, "Writing display config...\n");
  1058. ret = rmi_f34v7_write_dp_config(f34);
  1059. if (ret < 0)
  1060. goto fail;
  1061. }
  1062. if (f34->v7.new_partition_table) {
  1063. if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) {
  1064. dev_info(&f34->fn->dev, "Writing guest code...\n");
  1065. ret = rmi_f34v7_write_guest_code(f34);
  1066. if (ret < 0)
  1067. goto fail;
  1068. }
  1069. }
  1070. fail:
  1071. return ret;
  1072. }
  1073. static int rmi_f34v7_enter_flash_prog(struct f34_data *f34)
  1074. {
  1075. int ret;
  1076. ret = rmi_f34v7_read_flash_status(f34);
  1077. if (ret < 0)
  1078. return ret;
  1079. if (f34->v7.in_bl_mode)
  1080. return 0;
  1081. ret = rmi_f34v7_write_command(f34, v7_CMD_ENABLE_FLASH_PROG);
  1082. if (ret < 0)
  1083. return ret;
  1084. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  1085. if (ret < 0)
  1086. return ret;
  1087. if (!f34->v7.in_bl_mode) {
  1088. dev_err(&f34->fn->dev, "%s: BL mode not entered\n", __func__);
  1089. return -EINVAL;
  1090. }
  1091. return 0;
  1092. }
  1093. int rmi_f34v7_start_reflash(struct f34_data *f34, const struct firmware *fw)
  1094. {
  1095. int ret = 0;
  1096. f34->v7.config_area = v7_UI_CONFIG_AREA;
  1097. f34->v7.image = fw->data;
  1098. ret = rmi_f34v7_parse_image_info(f34);
  1099. if (ret < 0)
  1100. goto exit;
  1101. if (!f34->v7.force_update && f34->v7.new_partition_table) {
  1102. dev_err(&f34->fn->dev, "%s: Partition table mismatch\n",
  1103. __func__);
  1104. ret = -EINVAL;
  1105. goto exit;
  1106. }
  1107. dev_info(&f34->fn->dev, "Firmware image OK\n");
  1108. ret = rmi_f34v7_read_flash_status(f34);
  1109. if (ret < 0)
  1110. goto exit;
  1111. if (f34->v7.in_bl_mode) {
  1112. dev_info(&f34->fn->dev, "%s: Device in bootloader mode\n",
  1113. __func__);
  1114. }
  1115. rmi_f34v7_enter_flash_prog(f34);
  1116. return 0;
  1117. exit:
  1118. return ret;
  1119. }
  1120. int rmi_f34v7_probe(struct f34_data *f34)
  1121. {
  1122. int ret;
  1123. /* Read bootloader version */
  1124. ret = rmi_read_block(f34->fn->rmi_dev,
  1125. f34->fn->fd.query_base_addr + V7_BOOTLOADER_ID_OFFSET,
  1126. f34->bootloader_id,
  1127. sizeof(f34->bootloader_id));
  1128. if (ret < 0) {
  1129. dev_err(&f34->fn->dev, "%s: Failed to read bootloader ID\n",
  1130. __func__);
  1131. return ret;
  1132. }
  1133. if (f34->bootloader_id[1] == '5') {
  1134. f34->bl_version = 5;
  1135. } else if (f34->bootloader_id[1] == '6') {
  1136. f34->bl_version = 6;
  1137. } else if (f34->bootloader_id[1] == 7) {
  1138. f34->bl_version = 7;
  1139. } else {
  1140. dev_err(&f34->fn->dev, "%s: Unrecognized bootloader version\n",
  1141. __func__);
  1142. return -EINVAL;
  1143. }
  1144. memset(&f34->v7.blkcount, 0x00, sizeof(f34->v7.blkcount));
  1145. memset(&f34->v7.phyaddr, 0x00, sizeof(f34->v7.phyaddr));
  1146. rmi_f34v7_read_queries(f34);
  1147. f34->v7.force_update = false;
  1148. return 0;
  1149. }