You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1190 lines
35 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007,2008 by Christopher Kilgour *
  3. * techie |_at_| whiterocker |_dot_| com *
  4. * *
  5. * This program is free software; you can redistribute it and/or modify *
  6. * it under the terms of the GNU General Public License as published by *
  7. * the Free Software Foundation; either version 2 of the License, or *
  8. * (at your option) any later version. *
  9. * *
  10. * This program is distributed in the hope that it will be useful, *
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  13. * GNU General Public License for more details. *
  14. * *
  15. * You should have received a copy of the GNU General Public License *
  16. * along with this program. If not, see <http://www.gnu.org/licenses/>. *
  17. ***************************************************************************/
  18. #ifdef HAVE_CONFIG_H
  19. #include "config.h"
  20. #endif
  21. #include "imp.h"
  22. /* ----------------------------------------------------------------------
  23. * Internal Support, Helpers
  24. * ---------------------------------------------------------------------- */
  25. struct tms470_flash_bank {
  26. unsigned ordinal;
  27. /* device identification register */
  28. uint32_t device_ident_reg;
  29. uint32_t silicon_version;
  30. uint32_t technology_family;
  31. uint32_t rom_flash;
  32. uint32_t part_number;
  33. const char *part_name;
  34. };
  35. static const struct flash_sector TMS470R1A256_SECTORS[] = {
  36. {0x00000000, 0x00002000, -1, -1},
  37. {0x00002000, 0x00002000, -1, -1},
  38. {0x00004000, 0x00002000, -1, -1},
  39. {0x00006000, 0x00002000, -1, -1},
  40. {0x00008000, 0x00008000, -1, -1},
  41. {0x00010000, 0x00008000, -1, -1},
  42. {0x00018000, 0x00008000, -1, -1},
  43. {0x00020000, 0x00008000, -1, -1},
  44. {0x00028000, 0x00008000, -1, -1},
  45. {0x00030000, 0x00008000, -1, -1},
  46. {0x00038000, 0x00002000, -1, -1},
  47. {0x0003A000, 0x00002000, -1, -1},
  48. {0x0003C000, 0x00002000, -1, -1},
  49. {0x0003E000, 0x00002000, -1, -1},
  50. };
  51. #define TMS470R1A256_NUM_SECTORS \
  52. ARRAY_SIZE(TMS470R1A256_SECTORS)
  53. static const struct flash_sector TMS470R1A288_BANK0_SECTORS[] = {
  54. {0x00000000, 0x00002000, -1, -1},
  55. {0x00002000, 0x00002000, -1, -1},
  56. {0x00004000, 0x00002000, -1, -1},
  57. {0x00006000, 0x00002000, -1, -1},
  58. };
  59. #define TMS470R1A288_BANK0_NUM_SECTORS \
  60. ARRAY_SIZE(TMS470R1A288_BANK0_SECTORS)
  61. static const struct flash_sector TMS470R1A288_BANK1_SECTORS[] = {
  62. {0x00040000, 0x00010000, -1, -1},
  63. {0x00050000, 0x00010000, -1, -1},
  64. {0x00060000, 0x00010000, -1, -1},
  65. {0x00070000, 0x00010000, -1, -1},
  66. };
  67. #define TMS470R1A288_BANK1_NUM_SECTORS \
  68. ARRAY_SIZE(TMS470R1A288_BANK1_SECTORS)
  69. static const struct flash_sector TMS470R1A384_BANK0_SECTORS[] = {
  70. {0x00000000, 0x00002000, -1, -1},
  71. {0x00002000, 0x00002000, -1, -1},
  72. {0x00004000, 0x00004000, -1, -1},
  73. {0x00008000, 0x00004000, -1, -1},
  74. {0x0000C000, 0x00004000, -1, -1},
  75. {0x00010000, 0x00004000, -1, -1},
  76. {0x00014000, 0x00004000, -1, -1},
  77. {0x00018000, 0x00002000, -1, -1},
  78. {0x0001C000, 0x00002000, -1, -1},
  79. {0x0001E000, 0x00002000, -1, -1},
  80. };
  81. #define TMS470R1A384_BANK0_NUM_SECTORS \
  82. ARRAY_SIZE(TMS470R1A384_BANK0_SECTORS)
  83. static const struct flash_sector TMS470R1A384_BANK1_SECTORS[] = {
  84. {0x00020000, 0x00008000, -1, -1},
  85. {0x00028000, 0x00008000, -1, -1},
  86. {0x00030000, 0x00008000, -1, -1},
  87. {0x00038000, 0x00008000, -1, -1},
  88. };
  89. #define TMS470R1A384_BANK1_NUM_SECTORS \
  90. ARRAY_SIZE(TMS470R1A384_BANK1_SECTORS)
  91. static const struct flash_sector TMS470R1A384_BANK2_SECTORS[] = {
  92. {0x00040000, 0x00008000, -1, -1},
  93. {0x00048000, 0x00008000, -1, -1},
  94. {0x00050000, 0x00008000, -1, -1},
  95. {0x00058000, 0x00008000, -1, -1},
  96. };
  97. #define TMS470R1A384_BANK2_NUM_SECTORS \
  98. ARRAY_SIZE(TMS470R1A384_BANK2_SECTORS)
  99. /* ---------------------------------------------------------------------- */
  100. static int tms470_read_part_info(struct flash_bank *bank)
  101. {
  102. struct tms470_flash_bank *tms470_info = bank->driver_priv;
  103. struct target *target = bank->target;
  104. uint32_t device_ident_reg;
  105. uint32_t silicon_version;
  106. uint32_t technology_family;
  107. uint32_t rom_flash;
  108. uint32_t part_number;
  109. const char *part_name;
  110. /* we shall not rely on the caller in this test, this function allocates memory,
  111. thus and executing the code more than once may cause memory leak */
  112. if (tms470_info->device_ident_reg)
  113. return ERROR_OK;
  114. /* read and parse the device identification register */
  115. target_read_u32(target, 0xFFFFFFF0, &device_ident_reg);
  116. LOG_INFO("device_ident_reg = 0x%08" PRIx32 "", device_ident_reg);
  117. if ((device_ident_reg & 7) == 0) {
  118. LOG_WARNING("Cannot identify target as a TMS470 family.");
  119. return ERROR_FLASH_OPERATION_FAILED;
  120. }
  121. silicon_version = (device_ident_reg >> 12) & 0xF;
  122. technology_family = (device_ident_reg >> 11) & 1;
  123. rom_flash = (device_ident_reg >> 10) & 1;
  124. part_number = (device_ident_reg >> 3) & 0x7f;
  125. if (bank->sectors) {
  126. free(bank->sectors);
  127. bank->sectors = NULL;
  128. }
  129. /*
  130. * If the part number is known, determine if the flash bank is valid
  131. * based on the base address being within the known flash bank
  132. * ranges. Then fixup/complete the remaining fields of the flash
  133. * bank structure.
  134. */
  135. switch (part_number) {
  136. case 0x0a:
  137. part_name = "TMS470R1A256";
  138. if (bank->base >= 0x00040000) {
  139. LOG_ERROR("No %s flash bank contains base address 0x%08" PRIx32 ".",
  140. part_name,
  141. bank->base);
  142. return ERROR_FLASH_OPERATION_FAILED;
  143. }
  144. tms470_info->ordinal = 0;
  145. bank->base = 0x00000000;
  146. bank->size = 256 * 1024;
  147. bank->num_sectors = TMS470R1A256_NUM_SECTORS;
  148. bank->sectors = malloc(sizeof(TMS470R1A256_SECTORS));
  149. if (!bank->sectors)
  150. return ERROR_FLASH_OPERATION_FAILED;
  151. (void)memcpy(bank->sectors, TMS470R1A256_SECTORS, sizeof(TMS470R1A256_SECTORS));
  152. break;
  153. case 0x2b:
  154. part_name = "TMS470R1A288";
  155. if (bank->base < 0x00008000) {
  156. tms470_info->ordinal = 0;
  157. bank->base = 0x00000000;
  158. bank->size = 32 * 1024;
  159. bank->num_sectors = TMS470R1A288_BANK0_NUM_SECTORS;
  160. bank->sectors = malloc(sizeof(TMS470R1A288_BANK0_SECTORS));
  161. if (!bank->sectors)
  162. return ERROR_FLASH_OPERATION_FAILED;
  163. (void)memcpy(bank->sectors, TMS470R1A288_BANK0_SECTORS,
  164. sizeof(TMS470R1A288_BANK0_SECTORS));
  165. } else if ((bank->base >= 0x00040000) && (bank->base < 0x00080000)) {
  166. tms470_info->ordinal = 1;
  167. bank->base = 0x00040000;
  168. bank->size = 256 * 1024;
  169. bank->num_sectors = TMS470R1A288_BANK1_NUM_SECTORS;
  170. bank->sectors = malloc(sizeof(TMS470R1A288_BANK1_SECTORS));
  171. if (!bank->sectors)
  172. return ERROR_FLASH_OPERATION_FAILED;
  173. (void)memcpy(bank->sectors, TMS470R1A288_BANK1_SECTORS,
  174. sizeof(TMS470R1A288_BANK1_SECTORS));
  175. } else {
  176. LOG_ERROR("No %s flash bank contains base address 0x%08" PRIx32 ".",
  177. part_name, bank->base);
  178. return ERROR_FLASH_OPERATION_FAILED;
  179. }
  180. break;
  181. case 0x2d:
  182. part_name = "TMS470R1A384";
  183. if (bank->base < 0x00020000) {
  184. tms470_info->ordinal = 0;
  185. bank->base = 0x00000000;
  186. bank->size = 128 * 1024;
  187. bank->num_sectors = TMS470R1A384_BANK0_NUM_SECTORS;
  188. bank->sectors = malloc(sizeof(TMS470R1A384_BANK0_SECTORS));
  189. if (!bank->sectors)
  190. return ERROR_FLASH_OPERATION_FAILED;
  191. (void)memcpy(bank->sectors, TMS470R1A384_BANK0_SECTORS,
  192. sizeof(TMS470R1A384_BANK0_SECTORS));
  193. } else if ((bank->base >= 0x00020000) && (bank->base < 0x00040000)) {
  194. tms470_info->ordinal = 1;
  195. bank->base = 0x00020000;
  196. bank->size = 128 * 1024;
  197. bank->num_sectors = TMS470R1A384_BANK1_NUM_SECTORS;
  198. bank->sectors = malloc(sizeof(TMS470R1A384_BANK1_SECTORS));
  199. if (!bank->sectors)
  200. return ERROR_FLASH_OPERATION_FAILED;
  201. (void)memcpy(bank->sectors, TMS470R1A384_BANK1_SECTORS,
  202. sizeof(TMS470R1A384_BANK1_SECTORS));
  203. } else if ((bank->base >= 0x00040000) && (bank->base < 0x00060000)) {
  204. tms470_info->ordinal = 2;
  205. bank->base = 0x00040000;
  206. bank->size = 128 * 1024;
  207. bank->num_sectors = TMS470R1A384_BANK2_NUM_SECTORS;
  208. bank->sectors = malloc(sizeof(TMS470R1A384_BANK2_SECTORS));
  209. if (!bank->sectors)
  210. return ERROR_FLASH_OPERATION_FAILED;
  211. (void)memcpy(bank->sectors, TMS470R1A384_BANK2_SECTORS,
  212. sizeof(TMS470R1A384_BANK2_SECTORS));
  213. } else {
  214. LOG_ERROR("No %s flash bank contains base address 0x%08" PRIx32 ".",
  215. part_name, bank->base);
  216. return ERROR_FLASH_OPERATION_FAILED;
  217. }
  218. break;
  219. default:
  220. LOG_WARNING("Could not identify part 0x%02x as a member of the TMS470 family.",
  221. (unsigned)part_number);
  222. return ERROR_FLASH_OPERATION_FAILED;
  223. }
  224. /* turn off memory selects */
  225. target_write_u32(target, 0xFFFFFFE4, 0x00000000);
  226. target_write_u32(target, 0xFFFFFFE0, 0x00000000);
  227. bank->chip_width = 32;
  228. bank->bus_width = 32;
  229. LOG_INFO("Identified %s, ver=%d, core=%s, nvmem=%s.",
  230. part_name,
  231. (int)(silicon_version),
  232. (technology_family ? "1.8v" : "3.3v"),
  233. (rom_flash ? "rom" : "flash"));
  234. tms470_info->device_ident_reg = device_ident_reg;
  235. tms470_info->silicon_version = silicon_version;
  236. tms470_info->technology_family = technology_family;
  237. tms470_info->rom_flash = rom_flash;
  238. tms470_info->part_number = part_number;
  239. tms470_info->part_name = part_name;
  240. /*
  241. * Disable reset on address access violation.
  242. */
  243. target_write_u32(target, 0xFFFFFFE0, 0x00004007);
  244. return ERROR_OK;
  245. }
  246. /* ---------------------------------------------------------------------- */
  247. static uint32_t keysSet;
  248. static uint32_t flashKeys[4];
  249. COMMAND_HANDLER(tms470_handle_flash_keyset_command)
  250. {
  251. if (CMD_ARGC > 4)
  252. return ERROR_COMMAND_SYNTAX_ERROR;
  253. else if (CMD_ARGC == 4) {
  254. int i;
  255. for (i = 0; i < 4; i++) {
  256. int start = (0 == strncmp(CMD_ARGV[i], "0x", 2)) ? 2 : 0;
  257. if (1 != sscanf(&CMD_ARGV[i][start], "%" SCNx32 "", &flashKeys[i])) {
  258. command_print(CMD_CTX, "could not process flash key %s",
  259. CMD_ARGV[i]);
  260. LOG_ERROR("could not process flash key %s", CMD_ARGV[i]);
  261. return ERROR_COMMAND_SYNTAX_ERROR;
  262. }
  263. }
  264. keysSet = 1;
  265. } else if (CMD_ARGC != 0) {
  266. command_print(CMD_CTX, "tms470 flash_keyset <key0> <key1> <key2> <key3>");
  267. return ERROR_COMMAND_SYNTAX_ERROR;
  268. }
  269. if (keysSet) {
  270. command_print(CMD_CTX,
  271. "using flash keys 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 ", 0x%08" PRIx32 "",
  272. flashKeys[0],
  273. flashKeys[1],
  274. flashKeys[2],
  275. flashKeys[3]);
  276. } else
  277. command_print(CMD_CTX, "flash keys not set");
  278. return ERROR_OK;
  279. }
  280. static const uint32_t FLASH_KEYS_ALL_ONES[] = { 0xFFFFFFFF, 0xFFFFFFFF,
  281. 0xFFFFFFFF, 0xFFFFFFFF,};
  282. static const uint32_t FLASH_KEYS_ALL_ZEROS[] = { 0x00000000, 0x00000000,
  283. 0x00000000, 0x00000000,};
  284. static const uint32_t FLASH_KEYS_MIX1[] = { 0xf0fff0ff, 0xf0fff0ff,
  285. 0xf0fff0ff, 0xf0fff0ff};
  286. static const uint32_t FLASH_KEYS_MIX2[] = { 0x0000ffff, 0x0000ffff,
  287. 0x0000ffff, 0x0000ffff};
  288. /* ---------------------------------------------------------------------- */
  289. static int oscMHz = 12;
  290. COMMAND_HANDLER(tms470_handle_osc_megahertz_command)
  291. {
  292. if (CMD_ARGC > 1)
  293. return ERROR_COMMAND_SYNTAX_ERROR;
  294. else if (CMD_ARGC == 1)
  295. sscanf(CMD_ARGV[0], "%d", &oscMHz);
  296. if (oscMHz <= 0) {
  297. LOG_ERROR("osc_megahertz must be positive and non-zero!");
  298. command_print(CMD_CTX, "osc_megahertz must be positive and non-zero!");
  299. oscMHz = 12;
  300. return ERROR_COMMAND_SYNTAX_ERROR;
  301. }
  302. command_print(CMD_CTX, "osc_megahertz=%d", oscMHz);
  303. return ERROR_OK;
  304. }
  305. /* ---------------------------------------------------------------------- */
  306. static int plldis;
  307. COMMAND_HANDLER(tms470_handle_plldis_command)
  308. {
  309. if (CMD_ARGC > 1)
  310. return ERROR_COMMAND_SYNTAX_ERROR;
  311. else if (CMD_ARGC == 1) {
  312. sscanf(CMD_ARGV[0], "%d", &plldis);
  313. plldis = plldis ? 1 : 0;
  314. }
  315. command_print(CMD_CTX, "plldis=%d", plldis);
  316. return ERROR_OK;
  317. }
  318. /* ---------------------------------------------------------------------- */
  319. static int tms470_check_flash_unlocked(struct target *target)
  320. {
  321. uint32_t fmbbusy;
  322. target_read_u32(target, 0xFFE89C08, &fmbbusy);
  323. LOG_INFO("tms470 fmbbusy = 0x%08" PRIx32 " -> %s",
  324. fmbbusy,
  325. fmbbusy & 0x8000 ? "unlocked" : "LOCKED");
  326. return fmbbusy & 0x8000 ? ERROR_OK : ERROR_FLASH_OPERATION_FAILED;
  327. }
  328. /* ---------------------------------------------------------------------- */
  329. static int tms470_try_flash_keys(struct target *target, const uint32_t *key_set)
  330. {
  331. uint32_t glbctrl, fmmstat;
  332. int retval = ERROR_FLASH_OPERATION_FAILED;
  333. /* set GLBCTRL.4 */
  334. target_read_u32(target, 0xFFFFFFDC, &glbctrl);
  335. target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
  336. /* only perform the key match when 3VSTAT is clear */
  337. target_read_u32(target, 0xFFE8BC0C, &fmmstat);
  338. if (!(fmmstat & 0x08)) {
  339. unsigned i;
  340. uint32_t fmbptr, fmbac2, orig_fmregopt;
  341. target_write_u32(target, 0xFFE8BC04, fmmstat & ~0x07);
  342. /* wait for pump ready */
  343. do {
  344. target_read_u32(target, 0xFFE8A814, &fmbptr);
  345. alive_sleep(1);
  346. } while (!(fmbptr & 0x0200));
  347. /* force max wait states */
  348. target_read_u32(target, 0xFFE88004, &fmbac2);
  349. target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
  350. /* save current access mode, force normal read mode */
  351. target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
  352. target_write_u32(target, 0xFFE89C00, 0x00);
  353. for (i = 0; i < 4; i++) {
  354. uint32_t tmp;
  355. /* There is no point displaying the value of tmp, it is
  356. * filtered by the chip. The purpose of this read is to
  357. * prime the unlocking logic rather than read out the value.
  358. */
  359. target_read_u32(target, 0x00001FF0 + 4 * i, &tmp);
  360. LOG_INFO("tms470 writing fmpkey = 0x%08" PRIx32 "", key_set[i]);
  361. target_write_u32(target, 0xFFE89C0C, key_set[i]);
  362. }
  363. if (ERROR_OK == tms470_check_flash_unlocked(target)) {
  364. /*
  365. * There seems to be a side-effect of reading the FMPKEY
  366. * register in that it re-enables the protection. So we
  367. * re-enable it.
  368. */
  369. for (i = 0; i < 4; i++) {
  370. uint32_t tmp;
  371. target_read_u32(target, 0x00001FF0 + 4 * i, &tmp);
  372. target_write_u32(target, 0xFFE89C0C, key_set[i]);
  373. }
  374. retval = ERROR_OK;
  375. }
  376. /* restore settings */
  377. target_write_u32(target, 0xFFE89C00, orig_fmregopt);
  378. target_write_u32(target, 0xFFE88004, fmbac2);
  379. }
  380. /* clear config bit */
  381. target_write_u32(target, 0xFFFFFFDC, glbctrl);
  382. return retval;
  383. }
  384. /* ---------------------------------------------------------------------- */
  385. static int tms470_unlock_flash(struct flash_bank *bank)
  386. {
  387. struct target *target = bank->target;
  388. const uint32_t *p_key_sets[5];
  389. unsigned i, key_set_count;
  390. if (keysSet) {
  391. key_set_count = 5;
  392. p_key_sets[0] = flashKeys;
  393. p_key_sets[1] = FLASH_KEYS_ALL_ONES;
  394. p_key_sets[2] = FLASH_KEYS_ALL_ZEROS;
  395. p_key_sets[3] = FLASH_KEYS_MIX1;
  396. p_key_sets[4] = FLASH_KEYS_MIX2;
  397. } else {
  398. key_set_count = 4;
  399. p_key_sets[0] = FLASH_KEYS_ALL_ONES;
  400. p_key_sets[1] = FLASH_KEYS_ALL_ZEROS;
  401. p_key_sets[2] = FLASH_KEYS_MIX1;
  402. p_key_sets[3] = FLASH_KEYS_MIX2;
  403. }
  404. for (i = 0; i < key_set_count; i++) {
  405. if (tms470_try_flash_keys(target, p_key_sets[i]) == ERROR_OK) {
  406. LOG_INFO("tms470 flash is unlocked");
  407. return ERROR_OK;
  408. }
  409. }
  410. LOG_WARNING("tms470 could not unlock flash memory protection level 2");
  411. return ERROR_FLASH_OPERATION_FAILED;
  412. }
  413. /* ---------------------------------------------------------------------- */
  414. static int tms470_flash_initialize_internal_state_machine(struct flash_bank *bank)
  415. {
  416. uint32_t fmmac2, fmmac1, fmmaxep, k, delay, glbctrl, sysclk;
  417. struct target *target = bank->target;
  418. struct tms470_flash_bank *tms470_info = bank->driver_priv;
  419. int result = ERROR_OK;
  420. /*
  421. * Select the desired bank to be programmed by writing BANK[2:0] of
  422. * FMMAC2.
  423. */
  424. target_read_u32(target, 0xFFE8BC04, &fmmac2);
  425. fmmac2 &= ~0x0007;
  426. fmmac2 |= (tms470_info->ordinal & 7);
  427. target_write_u32(target, 0xFFE8BC04, fmmac2);
  428. LOG_DEBUG("set fmmac2 = 0x%04" PRIx32 "", fmmac2);
  429. /*
  430. * Disable level 1 sector protection by setting bit 15 of FMMAC1.
  431. */
  432. target_read_u32(target, 0xFFE8BC00, &fmmac1);
  433. fmmac1 |= 0x8000;
  434. target_write_u32(target, 0xFFE8BC00, fmmac1);
  435. LOG_DEBUG("set fmmac1 = 0x%04" PRIx32 "", fmmac1);
  436. /*
  437. * FMTCREG = 0x2fc0;
  438. */
  439. target_write_u32(target, 0xFFE8BC10, 0x2fc0);
  440. LOG_DEBUG("set fmtcreg = 0x2fc0");
  441. /*
  442. * MAXPP = 50
  443. */
  444. target_write_u32(target, 0xFFE8A07C, 50);
  445. LOG_DEBUG("set fmmaxpp = 50");
  446. /*
  447. * MAXCP = 0xf000 + 2000
  448. */
  449. target_write_u32(target, 0xFFE8A084, 0xf000 + 2000);
  450. LOG_DEBUG("set fmmaxcp = 0x%04x", 0xf000 + 2000);
  451. /*
  452. * configure VHV
  453. */
  454. target_read_u32(target, 0xFFE8A080, &fmmaxep);
  455. if (fmmaxep == 0xf000) {
  456. fmmaxep = 0xf000 + 4095;
  457. target_write_u32(target, 0xFFE8A80C, 0x9964);
  458. LOG_DEBUG("set fmptr3 = 0x9964");
  459. } else {
  460. fmmaxep = 0xa000 + 4095;
  461. target_write_u32(target, 0xFFE8A80C, 0x9b64);
  462. LOG_DEBUG("set fmptr3 = 0x9b64");
  463. }
  464. target_write_u32(target, 0xFFE8A080, fmmaxep);
  465. LOG_DEBUG("set fmmaxep = 0x%04" PRIx32 "", fmmaxep);
  466. /*
  467. * FMPTR4 = 0xa000
  468. */
  469. target_write_u32(target, 0xFFE8A810, 0xa000);
  470. LOG_DEBUG("set fmptr4 = 0xa000");
  471. /*
  472. * FMPESETUP, delay parameter selected based on clock frequency.
  473. *
  474. * According to the TI App Note SPNU257 and flashing code, delay is
  475. * int((sysclk(MHz) + 1) / 2), with a minimum of 5. The system
  476. * clock is usually derived from the ZPLL module, and selected by
  477. * the plldis global.
  478. */
  479. target_read_u32(target, 0xFFFFFFDC, &glbctrl);
  480. sysclk = (plldis ? 1 : (glbctrl & 0x08) ? 4 : 8) * oscMHz / (1 + (glbctrl & 7));
  481. delay = (sysclk > 10) ? (sysclk + 1) / 2 : 5;
  482. target_write_u32(target, 0xFFE8A018, (delay << 4) | (delay << 8));
  483. LOG_DEBUG("set fmpsetup = 0x%04" PRIx32 "", (delay << 4) | (delay << 8));
  484. /*
  485. * FMPVEVACCESS, based on delay.
  486. */
  487. k = delay | (delay << 8);
  488. target_write_u32(target, 0xFFE8A05C, k);
  489. LOG_DEBUG("set fmpvevaccess = 0x%04" PRIx32 "", k);
  490. /*
  491. * FMPCHOLD, FMPVEVHOLD, FMPVEVSETUP, based on delay.
  492. */
  493. k <<= 1;
  494. target_write_u32(target, 0xFFE8A034, k);
  495. LOG_DEBUG("set fmpchold = 0x%04" PRIx32 "", k);
  496. target_write_u32(target, 0xFFE8A040, k);
  497. LOG_DEBUG("set fmpvevhold = 0x%04" PRIx32 "", k);
  498. target_write_u32(target, 0xFFE8A024, k);
  499. LOG_DEBUG("set fmpvevsetup = 0x%04" PRIx32 "", k);
  500. /*
  501. * FMCVACCESS, based on delay.
  502. */
  503. k = delay * 16;
  504. target_write_u32(target, 0xFFE8A060, k);
  505. LOG_DEBUG("set fmcvaccess = 0x%04" PRIx32 "", k);
  506. /*
  507. * FMCSETUP, based on delay.
  508. */
  509. k = 0x3000 | delay * 20;
  510. target_write_u32(target, 0xFFE8A020, k);
  511. LOG_DEBUG("set fmcsetup = 0x%04" PRIx32 "", k);
  512. /*
  513. * FMEHOLD, based on delay.
  514. */
  515. k = (delay * 20) << 2;
  516. target_write_u32(target, 0xFFE8A038, k);
  517. LOG_DEBUG("set fmehold = 0x%04" PRIx32 "", k);
  518. /*
  519. * PWIDTH, CWIDTH, EWIDTH, based on delay.
  520. */
  521. target_write_u32(target, 0xFFE8A050, delay * 8);
  522. LOG_DEBUG("set fmpwidth = 0x%04" PRIx32 "", delay * 8);
  523. target_write_u32(target, 0xFFE8A058, delay * 1000);
  524. LOG_DEBUG("set fmcwidth = 0x%04" PRIx32 "", delay * 1000);
  525. target_write_u32(target, 0xFFE8A054, delay * 5400);
  526. LOG_DEBUG("set fmewidth = 0x%04" PRIx32 "", delay * 5400);
  527. return result;
  528. }
  529. /* ---------------------------------------------------------------------- */
  530. static int tms470_flash_status(struct flash_bank *bank)
  531. {
  532. struct target *target = bank->target;
  533. int result = ERROR_OK;
  534. uint32_t fmmstat;
  535. target_read_u32(target, 0xFFE8BC0C, &fmmstat);
  536. LOG_DEBUG("set fmmstat = 0x%04" PRIx32 "", fmmstat);
  537. if (fmmstat & 0x0080) {
  538. LOG_WARNING("tms470 flash command: erase still active after busy clear.");
  539. result = ERROR_FLASH_OPERATION_FAILED;
  540. }
  541. if (fmmstat & 0x0040) {
  542. LOG_WARNING("tms470 flash command: program still active after busy clear.");
  543. result = ERROR_FLASH_OPERATION_FAILED;
  544. }
  545. if (fmmstat & 0x0020) {
  546. LOG_WARNING("tms470 flash command: invalid data command.");
  547. result = ERROR_FLASH_OPERATION_FAILED;
  548. }
  549. if (fmmstat & 0x0010) {
  550. LOG_WARNING("tms470 flash command: program, erase or validate sector failed.");
  551. result = ERROR_FLASH_OPERATION_FAILED;
  552. }
  553. if (fmmstat & 0x0008) {
  554. LOG_WARNING("tms470 flash command: voltage instability detected.");
  555. result = ERROR_FLASH_OPERATION_FAILED;
  556. }
  557. if (fmmstat & 0x0006) {
  558. LOG_WARNING("tms470 flash command: command suspend detected.");
  559. result = ERROR_FLASH_OPERATION_FAILED;
  560. }
  561. if (fmmstat & 0x0001) {
  562. LOG_WARNING("tms470 flash command: sector was locked.");
  563. result = ERROR_FLASH_OPERATION_FAILED;
  564. }
  565. return result;
  566. }
  567. /* ---------------------------------------------------------------------- */
  568. static int tms470_erase_sector(struct flash_bank *bank, int sector)
  569. {
  570. uint32_t glbctrl, orig_fmregopt, fmbsea, fmbseb, fmmstat;
  571. struct target *target = bank->target;
  572. uint32_t flashAddr = bank->base + bank->sectors[sector].offset;
  573. int result = ERROR_OK;
  574. /*
  575. * Set the bit GLBCTRL4 of the GLBCTRL register (in the System
  576. * module) to enable writing to the flash registers }.
  577. */
  578. target_read_u32(target, 0xFFFFFFDC, &glbctrl);
  579. target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
  580. LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl | 0x10);
  581. /* Force normal read mode. */
  582. target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
  583. target_write_u32(target, 0xFFE89C00, 0);
  584. LOG_DEBUG("set fmregopt = 0x%08x", 0);
  585. (void)tms470_flash_initialize_internal_state_machine(bank);
  586. /*
  587. * Select one or more bits in FMBSEA or FMBSEB to disable Level 1
  588. * protection for the particular sector to be erased/written.
  589. */
  590. if (sector < 16) {
  591. target_read_u32(target, 0xFFE88008, &fmbsea);
  592. target_write_u32(target, 0xFFE88008, fmbsea | (1 << sector));
  593. LOG_DEBUG("set fmbsea = 0x%04" PRIx32 "", fmbsea | (1 << sector));
  594. } else {
  595. target_read_u32(target, 0xFFE8800C, &fmbseb);
  596. target_write_u32(target, 0xFFE8800C, fmbseb | (1 << (sector - 16)));
  597. LOG_DEBUG("set fmbseb = 0x%04" PRIx32 "", fmbseb | (1 << (sector - 16)));
  598. }
  599. bank->sectors[sector].is_protected = 0;
  600. /*
  601. * clear status regiser, sent erase command, kickoff erase
  602. */
  603. target_write_u16(target, flashAddr, 0x0040);
  604. LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0040", flashAddr);
  605. target_write_u16(target, flashAddr, 0x0020);
  606. LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0x0020", flashAddr);
  607. target_write_u16(target, flashAddr, 0xffff);
  608. LOG_DEBUG("write *(uint16_t *)0x%08" PRIx32 "=0xffff", flashAddr);
  609. /*
  610. * Monitor FMMSTAT, busy until clear, then check and other flags for
  611. * ultimate result of the operation.
  612. */
  613. do {
  614. target_read_u32(target, 0xFFE8BC0C, &fmmstat);
  615. if (fmmstat & 0x0100)
  616. alive_sleep(1);
  617. } while (fmmstat & 0x0100);
  618. result = tms470_flash_status(bank);
  619. if (sector < 16) {
  620. target_write_u32(target, 0xFFE88008, fmbsea);
  621. LOG_DEBUG("set fmbsea = 0x%04" PRIx32 "", fmbsea);
  622. bank->sectors[sector].is_protected = fmbsea & (1 << sector) ? 0 : 1;
  623. } else {
  624. target_write_u32(target, 0xFFE8800C, fmbseb);
  625. LOG_DEBUG("set fmbseb = 0x%04" PRIx32 "", fmbseb);
  626. bank->sectors[sector].is_protected = fmbseb & (1 << (sector - 16)) ? 0 : 1;
  627. }
  628. target_write_u32(target, 0xFFE89C00, orig_fmregopt);
  629. LOG_DEBUG("set fmregopt = 0x%08" PRIx32 "", orig_fmregopt);
  630. target_write_u32(target, 0xFFFFFFDC, glbctrl);
  631. LOG_DEBUG("set glbctrl = 0x%08" PRIx32 "", glbctrl);
  632. if (result == ERROR_OK)
  633. bank->sectors[sector].is_erased = 1;
  634. return result;
  635. }
  636. /*----------------------------------------------------------------------
  637. * Implementation of Flash Driver Interfaces
  638. *---------------------------------------------------------------------- */
  639. static const struct command_registration tms470_any_command_handlers[] = {
  640. {
  641. .name = "flash_keyset",
  642. .usage = "<key0> <key1> <key2> <key3>",
  643. .handler = tms470_handle_flash_keyset_command,
  644. .mode = COMMAND_ANY,
  645. .help = "tms470 flash_keyset <key0> <key1> <key2> <key3>",
  646. },
  647. {
  648. .name = "osc_megahertz",
  649. .usage = "<MHz>",
  650. .handler = tms470_handle_osc_megahertz_command,
  651. .mode = COMMAND_ANY,
  652. .help = "tms470 osc_megahertz <MHz>",
  653. },
  654. {
  655. .name = "plldis",
  656. .usage = "<0 | 1>",
  657. .handler = tms470_handle_plldis_command,
  658. .mode = COMMAND_ANY,
  659. .help = "tms470 plldis <0/1>",
  660. },
  661. COMMAND_REGISTRATION_DONE
  662. };
  663. static const struct command_registration tms470_command_handlers[] = {
  664. {
  665. .name = "tms470",
  666. .mode = COMMAND_ANY,
  667. .help = "TI tms470 flash command group",
  668. .usage = "",
  669. .chain = tms470_any_command_handlers,
  670. },
  671. COMMAND_REGISTRATION_DONE
  672. };
  673. /* ---------------------------------------------------------------------- */
  674. static int tms470_erase(struct flash_bank *bank, int first, int last)
  675. {
  676. struct tms470_flash_bank *tms470_info = bank->driver_priv;
  677. int sector, result = ERROR_OK;
  678. if (bank->target->state != TARGET_HALTED) {
  679. LOG_ERROR("Target not halted");
  680. return ERROR_TARGET_NOT_HALTED;
  681. }
  682. tms470_read_part_info(bank);
  683. if ((first < 0) || (first >= bank->num_sectors) || (last < 0) ||
  684. (last >= bank->num_sectors) || (first > last)) {
  685. LOG_ERROR("Sector range %d to %d invalid.", first, last);
  686. return ERROR_FLASH_SECTOR_INVALID;
  687. }
  688. result = tms470_unlock_flash(bank);
  689. if (result != ERROR_OK)
  690. return result;
  691. for (sector = first; sector <= last; sector++) {
  692. LOG_INFO("Erasing tms470 bank %d sector %d...", tms470_info->ordinal, sector);
  693. result = tms470_erase_sector(bank, sector);
  694. if (result != ERROR_OK) {
  695. LOG_ERROR("tms470 could not erase flash sector.");
  696. break;
  697. } else
  698. LOG_INFO("sector erased successfully.");
  699. }
  700. return result;
  701. }
  702. /* ---------------------------------------------------------------------- */
  703. static int tms470_protect(struct flash_bank *bank, int set, int first, int last)
  704. {
  705. struct tms470_flash_bank *tms470_info = bank->driver_priv;
  706. struct target *target = bank->target;
  707. uint32_t fmmac2, fmbsea, fmbseb;
  708. int sector;
  709. if (target->state != TARGET_HALTED) {
  710. LOG_ERROR("Target not halted");
  711. return ERROR_TARGET_NOT_HALTED;
  712. }
  713. tms470_read_part_info(bank);
  714. if ((first < 0) || (first >= bank->num_sectors) || (last < 0) ||
  715. (last >= bank->num_sectors) || (first > last)) {
  716. LOG_ERROR("Sector range %d to %d invalid.", first, last);
  717. return ERROR_FLASH_SECTOR_INVALID;
  718. }
  719. /* enable the appropriate bank */
  720. target_read_u32(target, 0xFFE8BC04, &fmmac2);
  721. target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
  722. /* get the original sector proection flags for this bank */
  723. target_read_u32(target, 0xFFE88008, &fmbsea);
  724. target_read_u32(target, 0xFFE8800C, &fmbseb);
  725. for (sector = 0; sector < bank->num_sectors; sector++) {
  726. if (sector < 16) {
  727. fmbsea = set ? fmbsea & ~(1 << sector) : fmbsea | (1 << sector);
  728. bank->sectors[sector].is_protected = set ? 1 : 0;
  729. } else {
  730. fmbseb = set ? fmbseb &
  731. ~(1 << (sector - 16)) : fmbseb | (1 << (sector - 16));
  732. bank->sectors[sector].is_protected = set ? 1 : 0;
  733. }
  734. }
  735. /* update the protection bits */
  736. target_write_u32(target, 0xFFE88008, fmbsea);
  737. target_write_u32(target, 0xFFE8800C, fmbseb);
  738. return ERROR_OK;
  739. }
  740. /* ---------------------------------------------------------------------- */
  741. static int tms470_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
  742. {
  743. struct target *target = bank->target;
  744. uint32_t glbctrl, fmbac2, orig_fmregopt, fmbsea, fmbseb, fmmaxpp, fmmstat;
  745. int result = ERROR_OK;
  746. uint32_t i;
  747. if (target->state != TARGET_HALTED) {
  748. LOG_ERROR("Target not halted");
  749. return ERROR_TARGET_NOT_HALTED;
  750. }
  751. tms470_read_part_info(bank);
  752. LOG_INFO("Writing %" PRId32 " bytes starting at 0x%08" PRIx32 "", count, bank->base +
  753. offset);
  754. /* set GLBCTRL.4 */
  755. target_read_u32(target, 0xFFFFFFDC, &glbctrl);
  756. target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
  757. (void)tms470_flash_initialize_internal_state_machine(bank);
  758. /* force max wait states */
  759. target_read_u32(target, 0xFFE88004, &fmbac2);
  760. target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
  761. /* save current access mode, force normal read mode */
  762. target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
  763. target_write_u32(target, 0xFFE89C00, 0x00);
  764. /*
  765. * Disable Level 1 protection for all sectors to be erased/written.
  766. */
  767. target_read_u32(target, 0xFFE88008, &fmbsea);
  768. target_write_u32(target, 0xFFE88008, 0xffff);
  769. target_read_u32(target, 0xFFE8800C, &fmbseb);
  770. target_write_u32(target, 0xFFE8800C, 0xffff);
  771. /* read MAXPP */
  772. target_read_u32(target, 0xFFE8A07C, &fmmaxpp);
  773. for (i = 0; i < count; i += 2) {
  774. uint32_t addr = bank->base + offset + i;
  775. uint16_t word = (((uint16_t) buffer[i]) << 8) | (uint16_t) buffer[i + 1];
  776. if (word != 0xffff) {
  777. LOG_INFO("writing 0x%04x at 0x%08" PRIx32 "", word, addr);
  778. /* clear status register */
  779. target_write_u16(target, addr, 0x0040);
  780. /* program flash command */
  781. target_write_u16(target, addr, 0x0010);
  782. /* burn the 16-bit word (big-endian) */
  783. target_write_u16(target, addr, word);
  784. /*
  785. * Monitor FMMSTAT, busy until clear, then check and other flags
  786. * for ultimate result of the operation.
  787. */
  788. do {
  789. target_read_u32(target, 0xFFE8BC0C, &fmmstat);
  790. if (fmmstat & 0x0100)
  791. alive_sleep(1);
  792. } while (fmmstat & 0x0100);
  793. if (fmmstat & 0x3ff) {
  794. LOG_ERROR("fmstat = 0x%04" PRIx32 "", fmmstat);
  795. LOG_ERROR(
  796. "Could not program word 0x%04x at address 0x%08" PRIx32 ".",
  797. word,
  798. addr);
  799. result = ERROR_FLASH_OPERATION_FAILED;
  800. break;
  801. }
  802. } else
  803. LOG_INFO("skipping 0xffff at 0x%08" PRIx32 "", addr);
  804. }
  805. /* restore */
  806. target_write_u32(target, 0xFFE88008, fmbsea);
  807. target_write_u32(target, 0xFFE8800C, fmbseb);
  808. target_write_u32(target, 0xFFE88004, fmbac2);
  809. target_write_u32(target, 0xFFE89C00, orig_fmregopt);
  810. target_write_u32(target, 0xFFFFFFDC, glbctrl);
  811. return result;
  812. }
  813. /* ---------------------------------------------------------------------- */
  814. static int tms470_probe(struct flash_bank *bank)
  815. {
  816. if (bank->target->state != TARGET_HALTED) {
  817. LOG_WARNING("Cannot communicate... target not halted.");
  818. return ERROR_TARGET_NOT_HALTED;
  819. }
  820. return tms470_read_part_info(bank);
  821. }
  822. static int tms470_auto_probe(struct flash_bank *bank)
  823. {
  824. struct tms470_flash_bank *tms470_info = bank->driver_priv;
  825. if (tms470_info->device_ident_reg)
  826. return ERROR_OK;
  827. return tms470_probe(bank);
  828. }
  829. /* ---------------------------------------------------------------------- */
  830. static int tms470_erase_check(struct flash_bank *bank)
  831. {
  832. struct target *target = bank->target;
  833. struct tms470_flash_bank *tms470_info = bank->driver_priv;
  834. int sector, result = ERROR_OK;
  835. uint32_t fmmac2, fmbac2, glbctrl, orig_fmregopt;
  836. static uint8_t buffer[64 * 1024];
  837. if (target->state != TARGET_HALTED) {
  838. LOG_ERROR("Target not halted");
  839. return ERROR_TARGET_NOT_HALTED;
  840. }
  841. if (!tms470_info->device_ident_reg)
  842. tms470_read_part_info(bank);
  843. /* set GLBCTRL.4 */
  844. target_read_u32(target, 0xFFFFFFDC, &glbctrl);
  845. target_write_u32(target, 0xFFFFFFDC, glbctrl | 0x10);
  846. /* save current access mode, force normal read mode */
  847. target_read_u32(target, 0xFFE89C00, &orig_fmregopt);
  848. target_write_u32(target, 0xFFE89C00, 0x00);
  849. /* enable the appropriate bank */
  850. target_read_u32(target, 0xFFE8BC04, &fmmac2);
  851. target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
  852. /* TCR = 0 */
  853. target_write_u32(target, 0xFFE8BC10, 0x2fc0);
  854. /* clear TEZ in fmbrdy */
  855. target_write_u32(target, 0xFFE88010, 0x0b);
  856. /* save current wait states, force max */
  857. target_read_u32(target, 0xFFE88004, &fmbac2);
  858. target_write_u32(target, 0xFFE88004, fmbac2 | 0xff);
  859. /*
  860. * The TI primitives inspect the flash memory by reading one 32-bit
  861. * word at a time. Here we read an entire sector and inspect it in
  862. * an attempt to reduce the JTAG overhead.
  863. */
  864. for (sector = 0; sector < bank->num_sectors; sector++) {
  865. if (bank->sectors[sector].is_erased != 1) {
  866. uint32_t i, addr = bank->base + bank->sectors[sector].offset;
  867. LOG_INFO("checking flash bank %d sector %d", tms470_info->ordinal, sector);
  868. target_read_buffer(target, addr, bank->sectors[sector].size, buffer);
  869. bank->sectors[sector].is_erased = 1;
  870. for (i = 0; i < bank->sectors[sector].size; i++) {
  871. if (buffer[i] != 0xff) {
  872. LOG_WARNING("tms470 bank %d, sector %d, not erased.",
  873. tms470_info->ordinal,
  874. sector);
  875. LOG_WARNING(
  876. "at location 0x%08" PRIx32 ": flash data is 0x%02x.",
  877. addr + i,
  878. buffer[i]);
  879. bank->sectors[sector].is_erased = 0;
  880. break;
  881. }
  882. }
  883. }
  884. if (bank->sectors[sector].is_erased != 1) {
  885. result = ERROR_FLASH_SECTOR_NOT_ERASED;
  886. break;
  887. } else
  888. LOG_INFO("sector erased");
  889. }
  890. /* reset TEZ, wait states, read mode, GLBCTRL.4 */
  891. target_write_u32(target, 0xFFE88010, 0x0f);
  892. target_write_u32(target, 0xFFE88004, fmbac2);
  893. target_write_u32(target, 0xFFE89C00, orig_fmregopt);
  894. target_write_u32(target, 0xFFFFFFDC, glbctrl);
  895. return result;
  896. }
  897. /* ---------------------------------------------------------------------- */
  898. static int tms470_protect_check(struct flash_bank *bank)
  899. {
  900. struct target *target = bank->target;
  901. struct tms470_flash_bank *tms470_info = bank->driver_priv;
  902. int sector, result = ERROR_OK;
  903. uint32_t fmmac2, fmbsea, fmbseb;
  904. if (target->state != TARGET_HALTED) {
  905. LOG_ERROR("Target not halted");
  906. return ERROR_TARGET_NOT_HALTED;
  907. }
  908. if (!tms470_info->device_ident_reg)
  909. tms470_read_part_info(bank);
  910. /* enable the appropriate bank */
  911. target_read_u32(target, 0xFFE8BC04, &fmmac2);
  912. target_write_u32(target, 0xFFE8BC04, (fmmac2 & ~7) | tms470_info->ordinal);
  913. target_read_u32(target, 0xFFE88008, &fmbsea);
  914. target_read_u32(target, 0xFFE8800C, &fmbseb);
  915. for (sector = 0; sector < bank->num_sectors; sector++) {
  916. int protected;
  917. if (sector < 16) {
  918. protected = fmbsea & (1 << sector) ? 0 : 1;
  919. bank->sectors[sector].is_protected = protected;
  920. } else {
  921. protected = fmbseb & (1 << (sector - 16)) ? 0 : 1;
  922. bank->sectors[sector].is_protected = protected;
  923. }
  924. LOG_DEBUG("bank %d sector %d is %s",
  925. tms470_info->ordinal,
  926. sector,
  927. protected ? "protected" : "not protected");
  928. }
  929. return result;
  930. }
  931. /* ---------------------------------------------------------------------- */
  932. static int get_tms470_info(struct flash_bank *bank, char *buf, int buf_size)
  933. {
  934. int used = 0;
  935. struct tms470_flash_bank *tms470_info = bank->driver_priv;
  936. if (!tms470_info->device_ident_reg)
  937. tms470_read_part_info(bank);
  938. if (!tms470_info->device_ident_reg) {
  939. (void)snprintf(buf, buf_size, "Cannot identify target as a TMS470\n");
  940. return ERROR_FLASH_OPERATION_FAILED;
  941. }
  942. used =
  943. snprintf(buf, buf_size, "\ntms470 information: Chip is %s\n",
  944. tms470_info->part_name);
  945. buf += used;
  946. buf_size -= used;
  947. snprintf(buf, buf_size, "Flash protection level 2 is %s\n",
  948. tms470_check_flash_unlocked(bank->target) == ERROR_OK ? "disabled" : "enabled");
  949. return ERROR_OK;
  950. }
  951. /* ---------------------------------------------------------------------- */
  952. /*
  953. * flash bank tms470 <base> <size> <chip_width> <bus_width> <target>
  954. * [options...]
  955. */
  956. FLASH_BANK_COMMAND_HANDLER(tms470_flash_bank_command)
  957. {
  958. bank->driver_priv = malloc(sizeof(struct tms470_flash_bank));
  959. if (!bank->driver_priv)
  960. return ERROR_FLASH_OPERATION_FAILED;
  961. (void)memset(bank->driver_priv, 0, sizeof(struct tms470_flash_bank));
  962. return ERROR_OK;
  963. }
  964. struct flash_driver tms470_flash = {
  965. .name = "tms470",
  966. .commands = tms470_command_handlers,
  967. .flash_bank_command = tms470_flash_bank_command,
  968. .erase = tms470_erase,
  969. .protect = tms470_protect,
  970. .write = tms470_write,
  971. .read = default_flash_read,
  972. .probe = tms470_probe,
  973. .auto_probe = tms470_auto_probe,
  974. .erase_check = tms470_erase_check,
  975. .protect_check = tms470_protect_check,
  976. .info = get_tms470_info,
  977. };