rmi_f34v7.c 33 KB

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