rmi_f34v7.c 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373
  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. if (block_count != f34->v7.blkcount.ui_firmware) {
  509. dev_err(&f34->fn->dev,
  510. "UI firmware size mismatch: %d != %d\n",
  511. block_count, f34->v7.blkcount.ui_firmware);
  512. return -EINVAL;
  513. }
  514. return 0;
  515. }
  516. static int rmi_f34v7_check_ui_config_size(struct f34_data *f34)
  517. {
  518. u16 block_count;
  519. block_count = f34->v7.img.ui_config.size / f34->v7.block_size;
  520. if (block_count != f34->v7.blkcount.ui_config) {
  521. dev_err(&f34->fn->dev, "UI config size mismatch\n");
  522. return -EINVAL;
  523. }
  524. return 0;
  525. }
  526. static int rmi_f34v7_check_dp_config_size(struct f34_data *f34)
  527. {
  528. u16 block_count;
  529. block_count = f34->v7.img.dp_config.size / f34->v7.block_size;
  530. if (block_count != f34->v7.blkcount.dp_config) {
  531. dev_err(&f34->fn->dev, "Display config size mismatch\n");
  532. return -EINVAL;
  533. }
  534. return 0;
  535. }
  536. static int rmi_f34v7_check_guest_code_size(struct f34_data *f34)
  537. {
  538. u16 block_count;
  539. block_count = f34->v7.img.guest_code.size / f34->v7.block_size;
  540. if (block_count != f34->v7.blkcount.guest_code) {
  541. dev_err(&f34->fn->dev, "Guest code size mismatch\n");
  542. return -EINVAL;
  543. }
  544. return 0;
  545. }
  546. static int rmi_f34v7_check_bl_config_size(struct f34_data *f34)
  547. {
  548. u16 block_count;
  549. block_count = f34->v7.img.bl_config.size / f34->v7.block_size;
  550. if (block_count != f34->v7.blkcount.bl_config) {
  551. dev_err(&f34->fn->dev, "Bootloader config size mismatch\n");
  552. return -EINVAL;
  553. }
  554. return 0;
  555. }
  556. static int rmi_f34v7_erase_config(struct f34_data *f34)
  557. {
  558. int ret;
  559. dev_info(&f34->fn->dev, "Erasing config...\n");
  560. switch (f34->v7.config_area) {
  561. case v7_UI_CONFIG_AREA:
  562. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_CONFIG);
  563. if (ret < 0)
  564. return ret;
  565. break;
  566. case v7_DP_CONFIG_AREA:
  567. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_DISP_CONFIG);
  568. if (ret < 0)
  569. return ret;
  570. break;
  571. case v7_BL_CONFIG_AREA:
  572. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_BL_CONFIG);
  573. if (ret < 0)
  574. return ret;
  575. break;
  576. }
  577. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  578. if (ret < 0)
  579. return ret;
  580. return ret;
  581. }
  582. static int rmi_f34v7_erase_guest_code(struct f34_data *f34)
  583. {
  584. int ret;
  585. dev_info(&f34->fn->dev, "Erasing guest code...\n");
  586. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_GUEST_CODE);
  587. if (ret < 0)
  588. return ret;
  589. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  590. if (ret < 0)
  591. return ret;
  592. return 0;
  593. }
  594. static int rmi_f34v7_erase_all(struct f34_data *f34)
  595. {
  596. int ret;
  597. dev_info(&f34->fn->dev, "Erasing firmware...\n");
  598. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_UI_FIRMWARE);
  599. if (ret < 0)
  600. return ret;
  601. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  602. if (ret < 0)
  603. return ret;
  604. f34->v7.config_area = v7_UI_CONFIG_AREA;
  605. ret = rmi_f34v7_erase_config(f34);
  606. if (ret < 0)
  607. return ret;
  608. if (f34->v7.has_display_cfg) {
  609. f34->v7.config_area = v7_DP_CONFIG_AREA;
  610. ret = rmi_f34v7_erase_config(f34);
  611. if (ret < 0)
  612. return ret;
  613. }
  614. if (f34->v7.new_partition_table && f34->v7.has_guest_code) {
  615. ret = rmi_f34v7_erase_guest_code(f34);
  616. if (ret < 0)
  617. return ret;
  618. }
  619. return 0;
  620. }
  621. static int rmi_f34v7_read_f34v7_blocks(struct f34_data *f34, u16 block_cnt,
  622. u8 command)
  623. {
  624. int ret;
  625. u8 base;
  626. __le16 length;
  627. u16 transfer;
  628. u16 max_transfer;
  629. u16 remaining = block_cnt;
  630. u16 block_number = 0;
  631. u16 index = 0;
  632. base = f34->fn->fd.data_base_addr;
  633. ret = rmi_f34v7_write_partition_id(f34, command);
  634. if (ret < 0)
  635. return ret;
  636. ret = rmi_write_block(f34->fn->rmi_dev,
  637. base + f34->v7.off.block_number,
  638. &block_number, sizeof(block_number));
  639. if (ret < 0) {
  640. dev_err(&f34->fn->dev, "%s: Failed to write block number\n",
  641. __func__);
  642. return ret;
  643. }
  644. max_transfer = min(f34->v7.payload_length,
  645. (u16)(PAGE_SIZE / f34->v7.block_size));
  646. do {
  647. transfer = min(remaining, max_transfer);
  648. put_unaligned_le16(transfer, &length);
  649. ret = rmi_write_block(f34->fn->rmi_dev,
  650. base + f34->v7.off.transfer_length,
  651. &length, sizeof(length));
  652. if (ret < 0) {
  653. dev_err(&f34->fn->dev,
  654. "%s: Write transfer length fail (%d remaining)\n",
  655. __func__, remaining);
  656. return ret;
  657. }
  658. ret = rmi_f34v7_write_command(f34, command);
  659. if (ret < 0)
  660. return ret;
  661. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  662. if (ret < 0) {
  663. dev_err(&f34->fn->dev,
  664. "%s: Wait for idle failed (%d blks remaining)\n",
  665. __func__, remaining);
  666. return ret;
  667. }
  668. ret = rmi_read_block(f34->fn->rmi_dev,
  669. base + f34->v7.off.payload,
  670. &f34->v7.read_config_buf[index],
  671. transfer * f34->v7.block_size);
  672. if (ret < 0) {
  673. dev_err(&f34->fn->dev,
  674. "%s: Read block failed (%d blks remaining)\n",
  675. __func__, remaining);
  676. return ret;
  677. }
  678. index += (transfer * f34->v7.block_size);
  679. remaining -= transfer;
  680. } while (remaining);
  681. return 0;
  682. }
  683. static int rmi_f34v7_write_f34v7_blocks(struct f34_data *f34,
  684. const void *block_ptr, u16 block_cnt,
  685. u8 command)
  686. {
  687. int ret;
  688. u8 base;
  689. __le16 length;
  690. u16 transfer;
  691. u16 max_transfer;
  692. u16 remaining = block_cnt;
  693. u16 block_number = 0;
  694. base = f34->fn->fd.data_base_addr;
  695. ret = rmi_f34v7_write_partition_id(f34, command);
  696. if (ret < 0)
  697. return ret;
  698. ret = rmi_write_block(f34->fn->rmi_dev,
  699. base + f34->v7.off.block_number,
  700. &block_number, sizeof(block_number));
  701. if (ret < 0) {
  702. dev_err(&f34->fn->dev, "%s: Failed to write block number\n",
  703. __func__);
  704. return ret;
  705. }
  706. if (f34->v7.payload_length > (PAGE_SIZE / f34->v7.block_size))
  707. max_transfer = PAGE_SIZE / f34->v7.block_size;
  708. else
  709. max_transfer = f34->v7.payload_length;
  710. do {
  711. transfer = min(remaining, max_transfer);
  712. put_unaligned_le16(transfer, &length);
  713. ret = rmi_write_block(f34->fn->rmi_dev,
  714. base + f34->v7.off.transfer_length,
  715. &length, sizeof(length));
  716. if (ret < 0) {
  717. dev_err(&f34->fn->dev,
  718. "%s: Write transfer length fail (%d remaining)\n",
  719. __func__, remaining);
  720. return ret;
  721. }
  722. ret = rmi_f34v7_write_command(f34, command);
  723. if (ret < 0)
  724. return ret;
  725. ret = rmi_write_block(f34->fn->rmi_dev,
  726. base + f34->v7.off.payload,
  727. block_ptr, transfer * f34->v7.block_size);
  728. if (ret < 0) {
  729. dev_err(&f34->fn->dev,
  730. "%s: Failed writing data (%d blks remaining)\n",
  731. __func__, remaining);
  732. return ret;
  733. }
  734. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  735. if (ret < 0) {
  736. dev_err(&f34->fn->dev,
  737. "%s: Failed wait for idle (%d blks remaining)\n",
  738. __func__, remaining);
  739. return ret;
  740. }
  741. block_ptr += (transfer * f34->v7.block_size);
  742. remaining -= transfer;
  743. } while (remaining);
  744. return 0;
  745. }
  746. static int rmi_f34v7_write_config(struct f34_data *f34)
  747. {
  748. return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.config_data,
  749. f34->v7.config_block_count,
  750. v7_CMD_WRITE_CONFIG);
  751. }
  752. static int rmi_f34v7_write_ui_config(struct f34_data *f34)
  753. {
  754. f34->v7.config_area = v7_UI_CONFIG_AREA;
  755. f34->v7.config_data = f34->v7.img.ui_config.data;
  756. f34->v7.config_size = f34->v7.img.ui_config.size;
  757. f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
  758. return rmi_f34v7_write_config(f34);
  759. }
  760. static int rmi_f34v7_write_dp_config(struct f34_data *f34)
  761. {
  762. f34->v7.config_area = v7_DP_CONFIG_AREA;
  763. f34->v7.config_data = f34->v7.img.dp_config.data;
  764. f34->v7.config_size = f34->v7.img.dp_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_guest_code(struct f34_data *f34)
  769. {
  770. return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.img.guest_code.data,
  771. f34->v7.img.guest_code.size /
  772. f34->v7.block_size,
  773. v7_CMD_WRITE_GUEST_CODE);
  774. }
  775. static int rmi_f34v7_write_flash_config(struct f34_data *f34)
  776. {
  777. int ret;
  778. f34->v7.config_area = v7_FLASH_CONFIG_AREA;
  779. f34->v7.config_data = f34->v7.img.fl_config.data;
  780. f34->v7.config_size = f34->v7.img.fl_config.size;
  781. f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
  782. if (f34->v7.config_block_count != f34->v7.blkcount.fl_config) {
  783. dev_err(&f34->fn->dev, "%s: Flash config size mismatch\n",
  784. __func__);
  785. return -EINVAL;
  786. }
  787. ret = rmi_f34v7_write_command(f34, v7_CMD_ERASE_FLASH_CONFIG);
  788. if (ret < 0)
  789. return ret;
  790. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  791. "%s: Erase flash config command written\n", __func__);
  792. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  793. if (ret < 0)
  794. return ret;
  795. ret = rmi_f34v7_write_config(f34);
  796. if (ret < 0)
  797. return ret;
  798. return 0;
  799. }
  800. static int rmi_f34v7_write_partition_table(struct f34_data *f34)
  801. {
  802. u16 block_count;
  803. int ret;
  804. block_count = f34->v7.blkcount.bl_config;
  805. f34->v7.config_area = v7_BL_CONFIG_AREA;
  806. f34->v7.config_size = f34->v7.block_size * block_count;
  807. devm_kfree(&f34->fn->dev, f34->v7.read_config_buf);
  808. f34->v7.read_config_buf = devm_kzalloc(&f34->fn->dev,
  809. f34->v7.config_size, GFP_KERNEL);
  810. if (!f34->v7.read_config_buf) {
  811. f34->v7.read_config_buf_size = 0;
  812. return -ENOMEM;
  813. }
  814. f34->v7.read_config_buf_size = f34->v7.config_size;
  815. ret = rmi_f34v7_read_f34v7_blocks(f34, block_count, v7_CMD_READ_CONFIG);
  816. if (ret < 0)
  817. return ret;
  818. ret = rmi_f34v7_erase_config(f34);
  819. if (ret < 0)
  820. return ret;
  821. ret = rmi_f34v7_write_flash_config(f34);
  822. if (ret < 0)
  823. return ret;
  824. f34->v7.config_area = v7_BL_CONFIG_AREA;
  825. f34->v7.config_data = f34->v7.read_config_buf;
  826. f34->v7.config_size = f34->v7.img.bl_config.size;
  827. f34->v7.config_block_count = f34->v7.config_size / f34->v7.block_size;
  828. ret = rmi_f34v7_write_config(f34);
  829. if (ret < 0)
  830. return ret;
  831. return 0;
  832. }
  833. static int rmi_f34v7_write_firmware(struct f34_data *f34)
  834. {
  835. u16 blk_count;
  836. blk_count = f34->v7.img.ui_firmware.size / f34->v7.block_size;
  837. return rmi_f34v7_write_f34v7_blocks(f34, f34->v7.img.ui_firmware.data,
  838. blk_count, v7_CMD_WRITE_FW);
  839. }
  840. static void rmi_f34v7_compare_partition_tables(struct f34_data *f34)
  841. {
  842. if (f34->v7.phyaddr.ui_firmware != f34->v7.img.phyaddr.ui_firmware) {
  843. f34->v7.new_partition_table = true;
  844. return;
  845. }
  846. if (f34->v7.phyaddr.ui_config != f34->v7.img.phyaddr.ui_config) {
  847. f34->v7.new_partition_table = true;
  848. return;
  849. }
  850. if (f34->v7.has_display_cfg &&
  851. f34->v7.phyaddr.dp_config != f34->v7.img.phyaddr.dp_config) {
  852. f34->v7.new_partition_table = true;
  853. return;
  854. }
  855. if (f34->v7.has_guest_code &&
  856. f34->v7.phyaddr.guest_code != f34->v7.img.phyaddr.guest_code) {
  857. f34->v7.new_partition_table = true;
  858. return;
  859. }
  860. f34->v7.new_partition_table = false;
  861. }
  862. static void rmi_f34v7_parse_img_header_10_bl_container(struct f34_data *f34,
  863. const void *image)
  864. {
  865. int i;
  866. int num_of_containers;
  867. unsigned int addr;
  868. unsigned int container_id;
  869. unsigned int length;
  870. const void *content;
  871. const struct container_descriptor *descriptor;
  872. num_of_containers = f34->v7.img.bootloader.size / 4 - 1;
  873. for (i = 1; i <= num_of_containers; i++) {
  874. addr = get_unaligned_le32(f34->v7.img.bootloader.data + i * 4);
  875. descriptor = image + addr;
  876. container_id = le16_to_cpu(descriptor->container_id);
  877. content = image + le32_to_cpu(descriptor->content_address);
  878. length = le32_to_cpu(descriptor->content_length);
  879. switch (container_id) {
  880. case BL_CONFIG_CONTAINER:
  881. case GLOBAL_PARAMETERS_CONTAINER:
  882. f34->v7.img.bl_config.data = content;
  883. f34->v7.img.bl_config.size = length;
  884. break;
  885. case BL_LOCKDOWN_INFO_CONTAINER:
  886. case DEVICE_CONFIG_CONTAINER:
  887. f34->v7.img.lockdown.data = content;
  888. f34->v7.img.lockdown.size = length;
  889. break;
  890. default:
  891. break;
  892. }
  893. }
  894. }
  895. static void rmi_f34v7_parse_image_header_10(struct f34_data *f34)
  896. {
  897. unsigned int i;
  898. unsigned int num_of_containers;
  899. unsigned int addr;
  900. unsigned int offset;
  901. unsigned int container_id;
  902. unsigned int length;
  903. const void *image = f34->v7.image;
  904. const u8 *content;
  905. const struct container_descriptor *descriptor;
  906. const struct image_header_10 *header = image;
  907. f34->v7.img.checksum = le32_to_cpu(header->checksum);
  908. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev, "%s: f34->v7.img.checksum=%X\n",
  909. __func__, f34->v7.img.checksum);
  910. /* address of top level container */
  911. offset = le32_to_cpu(header->top_level_container_start_addr);
  912. descriptor = image + offset;
  913. /* address of top level container content */
  914. offset = le32_to_cpu(descriptor->content_address);
  915. num_of_containers = le32_to_cpu(descriptor->content_length) / 4;
  916. for (i = 0; i < num_of_containers; i++) {
  917. addr = get_unaligned_le32(image + offset);
  918. offset += 4;
  919. descriptor = image + addr;
  920. container_id = le16_to_cpu(descriptor->container_id);
  921. content = image + le32_to_cpu(descriptor->content_address);
  922. length = le32_to_cpu(descriptor->content_length);
  923. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  924. "%s: container_id=%d, length=%d\n", __func__,
  925. container_id, length);
  926. switch (container_id) {
  927. case UI_CONTAINER:
  928. case CORE_CODE_CONTAINER:
  929. f34->v7.img.ui_firmware.data = content;
  930. f34->v7.img.ui_firmware.size = length;
  931. break;
  932. case UI_CONFIG_CONTAINER:
  933. case CORE_CONFIG_CONTAINER:
  934. f34->v7.img.ui_config.data = content;
  935. f34->v7.img.ui_config.size = length;
  936. break;
  937. case BL_CONTAINER:
  938. f34->v7.img.bl_version = *content;
  939. f34->v7.img.bootloader.data = content;
  940. f34->v7.img.bootloader.size = length;
  941. rmi_f34v7_parse_img_header_10_bl_container(f34, image);
  942. break;
  943. case GUEST_CODE_CONTAINER:
  944. f34->v7.img.contains_guest_code = true;
  945. f34->v7.img.guest_code.data = content;
  946. f34->v7.img.guest_code.size = length;
  947. break;
  948. case DISPLAY_CONFIG_CONTAINER:
  949. f34->v7.img.contains_display_cfg = true;
  950. f34->v7.img.dp_config.data = content;
  951. f34->v7.img.dp_config.size = length;
  952. break;
  953. case FLASH_CONFIG_CONTAINER:
  954. f34->v7.img.contains_flash_config = true;
  955. f34->v7.img.fl_config.data = content;
  956. f34->v7.img.fl_config.size = length;
  957. break;
  958. case GENERAL_INFORMATION_CONTAINER:
  959. f34->v7.img.contains_firmware_id = true;
  960. f34->v7.img.firmware_id =
  961. get_unaligned_le32(content + 4);
  962. break;
  963. default:
  964. break;
  965. }
  966. }
  967. }
  968. static int rmi_f34v7_parse_image_info(struct f34_data *f34)
  969. {
  970. const struct image_header_10 *header = f34->v7.image;
  971. memset(&f34->v7.img, 0x00, sizeof(f34->v7.img));
  972. rmi_dbg(RMI_DEBUG_FN, &f34->fn->dev,
  973. "%s: header->major_header_version = %d\n",
  974. __func__, header->major_header_version);
  975. switch (header->major_header_version) {
  976. case IMAGE_HEADER_VERSION_10:
  977. rmi_f34v7_parse_image_header_10(f34);
  978. break;
  979. default:
  980. dev_err(&f34->fn->dev, "Unsupported image file format %02X\n",
  981. header->major_header_version);
  982. return -EINVAL;
  983. }
  984. if (!f34->v7.img.contains_flash_config) {
  985. dev_err(&f34->fn->dev, "%s: No flash config in fw image\n",
  986. __func__);
  987. return -EINVAL;
  988. }
  989. rmi_f34v7_parse_partition_table(f34, f34->v7.img.fl_config.data,
  990. &f34->v7.img.blkcount, &f34->v7.img.phyaddr);
  991. rmi_f34v7_compare_partition_tables(f34);
  992. return 0;
  993. }
  994. int rmi_f34v7_do_reflash(struct f34_data *f34, const struct firmware *fw)
  995. {
  996. int ret;
  997. rmi_f34v7_read_queries_bl_version(f34);
  998. f34->v7.image = fw->data;
  999. ret = rmi_f34v7_parse_image_info(f34);
  1000. if (ret < 0)
  1001. goto fail;
  1002. if (!f34->v7.new_partition_table) {
  1003. ret = rmi_f34v7_check_ui_firmware_size(f34);
  1004. if (ret < 0)
  1005. goto fail;
  1006. ret = rmi_f34v7_check_ui_config_size(f34);
  1007. if (ret < 0)
  1008. goto fail;
  1009. if (f34->v7.has_display_cfg &&
  1010. f34->v7.img.contains_display_cfg) {
  1011. ret = rmi_f34v7_check_dp_config_size(f34);
  1012. if (ret < 0)
  1013. goto fail;
  1014. }
  1015. if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) {
  1016. ret = rmi_f34v7_check_guest_code_size(f34);
  1017. if (ret < 0)
  1018. goto fail;
  1019. }
  1020. } else {
  1021. ret = rmi_f34v7_check_bl_config_size(f34);
  1022. if (ret < 0)
  1023. goto fail;
  1024. }
  1025. ret = rmi_f34v7_erase_all(f34);
  1026. if (ret < 0)
  1027. goto fail;
  1028. if (f34->v7.new_partition_table) {
  1029. ret = rmi_f34v7_write_partition_table(f34);
  1030. if (ret < 0)
  1031. goto fail;
  1032. dev_info(&f34->fn->dev, "%s: Partition table programmed\n",
  1033. __func__);
  1034. }
  1035. dev_info(&f34->fn->dev, "Writing firmware (%d bytes)...\n",
  1036. f34->v7.img.ui_firmware.size);
  1037. ret = rmi_f34v7_write_firmware(f34);
  1038. if (ret < 0)
  1039. goto fail;
  1040. dev_info(&f34->fn->dev, "Writing config (%d bytes)...\n",
  1041. f34->v7.img.ui_config.size);
  1042. f34->v7.config_area = v7_UI_CONFIG_AREA;
  1043. ret = rmi_f34v7_write_ui_config(f34);
  1044. if (ret < 0)
  1045. goto fail;
  1046. if (f34->v7.has_display_cfg && f34->v7.img.contains_display_cfg) {
  1047. dev_info(&f34->fn->dev, "Writing display config...\n");
  1048. ret = rmi_f34v7_write_dp_config(f34);
  1049. if (ret < 0)
  1050. goto fail;
  1051. }
  1052. if (f34->v7.new_partition_table) {
  1053. if (f34->v7.has_guest_code && f34->v7.img.contains_guest_code) {
  1054. dev_info(&f34->fn->dev, "Writing guest code...\n");
  1055. ret = rmi_f34v7_write_guest_code(f34);
  1056. if (ret < 0)
  1057. goto fail;
  1058. }
  1059. }
  1060. fail:
  1061. return ret;
  1062. }
  1063. static int rmi_f34v7_enter_flash_prog(struct f34_data *f34)
  1064. {
  1065. int ret;
  1066. ret = rmi_f34v7_read_flash_status(f34);
  1067. if (ret < 0)
  1068. return ret;
  1069. if (f34->v7.in_bl_mode)
  1070. return 0;
  1071. ret = rmi_f34v7_write_command(f34, v7_CMD_ENABLE_FLASH_PROG);
  1072. if (ret < 0)
  1073. return ret;
  1074. ret = rmi_f34v7_wait_for_idle(f34, ENABLE_WAIT_MS);
  1075. if (ret < 0)
  1076. return ret;
  1077. if (!f34->v7.in_bl_mode) {
  1078. dev_err(&f34->fn->dev, "%s: BL mode not entered\n", __func__);
  1079. return -EINVAL;
  1080. }
  1081. return 0;
  1082. }
  1083. int rmi_f34v7_start_reflash(struct f34_data *f34, const struct firmware *fw)
  1084. {
  1085. int ret = 0;
  1086. f34->v7.config_area = v7_UI_CONFIG_AREA;
  1087. f34->v7.image = fw->data;
  1088. ret = rmi_f34v7_parse_image_info(f34);
  1089. if (ret < 0)
  1090. goto exit;
  1091. if (!f34->v7.force_update && f34->v7.new_partition_table) {
  1092. dev_err(&f34->fn->dev, "%s: Partition table mismatch\n",
  1093. __func__);
  1094. ret = -EINVAL;
  1095. goto exit;
  1096. }
  1097. dev_info(&f34->fn->dev, "Firmware image OK\n");
  1098. ret = rmi_f34v7_read_flash_status(f34);
  1099. if (ret < 0)
  1100. goto exit;
  1101. if (f34->v7.in_bl_mode) {
  1102. dev_info(&f34->fn->dev, "%s: Device in bootloader mode\n",
  1103. __func__);
  1104. }
  1105. rmi_f34v7_enter_flash_prog(f34);
  1106. return 0;
  1107. exit:
  1108. return ret;
  1109. }
  1110. int rmi_f34v7_probe(struct f34_data *f34)
  1111. {
  1112. int ret;
  1113. /* Read bootloader version */
  1114. ret = rmi_read_block(f34->fn->rmi_dev,
  1115. f34->fn->fd.query_base_addr + V7_BOOTLOADER_ID_OFFSET,
  1116. f34->bootloader_id,
  1117. sizeof(f34->bootloader_id));
  1118. if (ret < 0) {
  1119. dev_err(&f34->fn->dev, "%s: Failed to read bootloader ID\n",
  1120. __func__);
  1121. return ret;
  1122. }
  1123. if (f34->bootloader_id[1] == '5') {
  1124. f34->bl_version = 5;
  1125. } else if (f34->bootloader_id[1] == '6') {
  1126. f34->bl_version = 6;
  1127. } else if (f34->bootloader_id[1] == 7) {
  1128. f34->bl_version = 7;
  1129. } else {
  1130. dev_err(&f34->fn->dev, "%s: Unrecognized bootloader version\n",
  1131. __func__);
  1132. return -EINVAL;
  1133. }
  1134. memset(&f34->v7.blkcount, 0x00, sizeof(f34->v7.blkcount));
  1135. memset(&f34->v7.phyaddr, 0x00, sizeof(f34->v7.phyaddr));
  1136. rmi_f34v7_read_queries(f34);
  1137. f34->v7.force_update = false;
  1138. return 0;
  1139. }