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.
 
 
 
 
 
 

1452 lines
37 KiB

  1. /***************************************************************************
  2. * Copyright (C) 2007-2008 by unsik Kim <donari75@gmail.com> *
  3. * *
  4. * This program is free software; you can redistribute it and/or modify *
  5. * it under the terms of the GNU General Public License as published by *
  6. * the Free Software Foundation; either version 2 of the License, or *
  7. * (at your option) any later version. *
  8. * *
  9. * This program is distributed in the hope that it will be useful, *
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of *
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
  12. * GNU General Public License for more details. *
  13. * *
  14. * You should have received a copy of the GNU General Public License *
  15. * along with this program; if not, write to the *
  16. * Free Software Foundation, Inc., *
  17. * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
  18. ***************************************************************************/
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include "mflash.h"
  23. #include <target/target.h>
  24. #include <helper/time_support.h>
  25. #include <helper/fileio.h>
  26. #include <helper/log.h>
  27. static int s3c2440_set_gpio_to_output(struct mflash_gpio_num gpio);
  28. static int s3c2440_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val);
  29. static int pxa270_set_gpio_to_output(struct mflash_gpio_num gpio);
  30. static int pxa270_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val);
  31. static struct mflash_bank *mflash_bank;
  32. static struct mflash_gpio_drv pxa270_gpio = {
  33. .name = "pxa270",
  34. .set_gpio_to_output = pxa270_set_gpio_to_output,
  35. .set_gpio_output_val = pxa270_set_gpio_output_val
  36. };
  37. static struct mflash_gpio_drv s3c2440_gpio = {
  38. .name = "s3c2440",
  39. .set_gpio_to_output = s3c2440_set_gpio_to_output,
  40. .set_gpio_output_val = s3c2440_set_gpio_output_val
  41. };
  42. static struct mflash_gpio_drv *mflash_gpio[] = {
  43. &pxa270_gpio,
  44. &s3c2440_gpio,
  45. NULL
  46. };
  47. #define PXA270_GAFR0_L 0x40E00054
  48. #define PXA270_GAFR3_U 0x40E00070
  49. #define PXA270_GAFR3_U_RESERVED_BITS 0xfffc0000u
  50. #define PXA270_GPDR0 0x40E0000C
  51. #define PXA270_GPDR3 0x40E0010C
  52. #define PXA270_GPDR3_RESERVED_BITS 0xfe000000u
  53. #define PXA270_GPSR0 0x40E00018
  54. #define PXA270_GPCR0 0x40E00024
  55. static int pxa270_set_gpio_to_output(struct mflash_gpio_num gpio)
  56. {
  57. uint32_t addr, value, mask;
  58. struct target *target = mflash_bank->target;
  59. int ret;
  60. /* remove alternate function. */
  61. mask = 0x3u << (gpio.num & 0xF)*2;
  62. addr = PXA270_GAFR0_L + (gpio.num >> 4) * 4;
  63. ret = target_read_u32(target, addr, &value);
  64. if (ret != ERROR_OK)
  65. return ret;
  66. value &= ~mask;
  67. if (addr == PXA270_GAFR3_U)
  68. value &= ~PXA270_GAFR3_U_RESERVED_BITS;
  69. ret = target_write_u32(target, addr, value);
  70. if (ret != ERROR_OK)
  71. return ret;
  72. /* set direction to output */
  73. mask = 0x1u << (gpio.num & 0x1F);
  74. addr = PXA270_GPDR0 + (gpio.num >> 5) * 4;
  75. ret = target_read_u32(target, addr, &value);
  76. if (ret != ERROR_OK)
  77. return ret;
  78. value |= mask;
  79. if (addr == PXA270_GPDR3)
  80. value &= ~PXA270_GPDR3_RESERVED_BITS;
  81. ret = target_write_u32(target, addr, value);
  82. return ret;
  83. }
  84. static int pxa270_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val)
  85. {
  86. uint32_t addr, value, mask;
  87. struct target *target = mflash_bank->target;
  88. int ret;
  89. mask = 0x1u << (gpio.num & 0x1F);
  90. if (val)
  91. addr = PXA270_GPSR0 + (gpio.num >> 5) * 4;
  92. else
  93. addr = PXA270_GPCR0 + (gpio.num >> 5) * 4;
  94. ret = target_read_u32(target, addr, &value);
  95. if (ret != ERROR_OK)
  96. return ret;
  97. value |= mask;
  98. ret = target_write_u32(target, addr, value);
  99. return ret;
  100. }
  101. #define S3C2440_GPACON 0x56000000
  102. #define S3C2440_GPADAT 0x56000004
  103. #define S3C2440_GPJCON 0x560000d0
  104. #define S3C2440_GPJDAT 0x560000d4
  105. static int s3c2440_set_gpio_to_output(struct mflash_gpio_num gpio)
  106. {
  107. uint32_t data, mask, gpio_con;
  108. struct target *target = mflash_bank->target;
  109. int ret;
  110. if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h')
  111. gpio_con = S3C2440_GPACON + (gpio.port[0] - 'a') * 0x10;
  112. else if (gpio.port[0] == 'j')
  113. gpio_con = S3C2440_GPJCON;
  114. else {
  115. LOG_ERROR("mflash: invalid port %d%s", gpio.num, gpio.port);
  116. return ERROR_COMMAND_SYNTAX_ERROR;
  117. }
  118. ret = target_read_u32(target, gpio_con, &data);
  119. if (ret == ERROR_OK) {
  120. if (gpio.port[0] == 'a') {
  121. mask = 1 << gpio.num;
  122. data &= ~mask;
  123. } else {
  124. mask = 3 << gpio.num * 2;
  125. data &= ~mask;
  126. data |= (1 << gpio.num * 2);
  127. }
  128. ret = target_write_u32(target, gpio_con, data);
  129. }
  130. return ret;
  131. }
  132. static int s3c2440_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val)
  133. {
  134. uint32_t data, mask, gpio_dat;
  135. struct target *target = mflash_bank->target;
  136. int ret;
  137. if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h')
  138. gpio_dat = S3C2440_GPADAT + (gpio.port[0] - 'a') * 0x10;
  139. else if (gpio.port[0] == 'j')
  140. gpio_dat = S3C2440_GPJDAT;
  141. else {
  142. LOG_ERROR("mflash: invalid port %d%s", gpio.num, gpio.port);
  143. return ERROR_COMMAND_SYNTAX_ERROR;
  144. }
  145. ret = target_read_u32(target, gpio_dat, &data);
  146. if (ret == ERROR_OK) {
  147. mask = 1 << gpio.num;
  148. if (val)
  149. data |= mask;
  150. else
  151. data &= ~mask;
  152. ret = target_write_u32(target, gpio_dat, data);
  153. }
  154. return ret;
  155. }
  156. static int mg_hdrst(uint8_t level)
  157. {
  158. return mflash_bank->gpio_drv->set_gpio_output_val(mflash_bank->rst_pin, level);
  159. }
  160. static int mg_init_gpio(void)
  161. {
  162. int ret;
  163. struct mflash_gpio_drv *gpio_drv = mflash_bank->gpio_drv;
  164. ret = gpio_drv->set_gpio_to_output(mflash_bank->rst_pin);
  165. if (ret != ERROR_OK)
  166. return ret;
  167. ret = gpio_drv->set_gpio_output_val(mflash_bank->rst_pin, 1);
  168. return ret;
  169. }
  170. static int mg_dsk_wait(mg_io_type_wait wait_local, uint32_t time_var)
  171. {
  172. uint8_t status, error;
  173. struct target *target = mflash_bank->target;
  174. uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
  175. int ret;
  176. long long t = 0;
  177. struct duration bench;
  178. duration_start(&bench);
  179. while (time_var) {
  180. ret = target_read_u8(target, mg_task_reg + MG_REG_STATUS, &status);
  181. if (ret != ERROR_OK)
  182. return ret;
  183. if (status & mg_io_rbit_status_busy) {
  184. if (wait_local == mg_io_wait_bsy)
  185. return ERROR_OK;
  186. } else {
  187. switch (wait_local) {
  188. case mg_io_wait_not_bsy:
  189. return ERROR_OK;
  190. case mg_io_wait_rdy_noerr:
  191. if (status & mg_io_rbit_status_ready)
  192. return ERROR_OK;
  193. break;
  194. case mg_io_wait_drq_noerr:
  195. if (status & mg_io_rbit_status_data_req)
  196. return ERROR_OK;
  197. break;
  198. default:
  199. break;
  200. }
  201. /* Now we check the error condition! */
  202. if (status & mg_io_rbit_status_error) {
  203. ret = target_read_u8(target, mg_task_reg + MG_REG_ERROR, &error);
  204. if (ret != ERROR_OK)
  205. return ret;
  206. LOG_ERROR("mflash: io error 0x%02x", error);
  207. return ERROR_MG_IO;
  208. }
  209. switch (wait_local) {
  210. case mg_io_wait_rdy:
  211. if (status & mg_io_rbit_status_ready)
  212. return ERROR_OK;
  213. case mg_io_wait_drq:
  214. if (status & mg_io_rbit_status_data_req)
  215. return ERROR_OK;
  216. default:
  217. break;
  218. }
  219. }
  220. ret = duration_measure(&bench);
  221. if (ERROR_OK == ret)
  222. t = duration_elapsed(&bench) * 1000.0;
  223. else
  224. LOG_ERROR("mflash: duration measurement failed: %d", ret);
  225. if (t > time_var)
  226. break;
  227. }
  228. LOG_ERROR("mflash: timeout occured");
  229. return ERROR_MG_TIMEOUT;
  230. }
  231. static int mg_dsk_srst(uint8_t on)
  232. {
  233. struct target *target = mflash_bank->target;
  234. uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
  235. uint8_t value;
  236. int ret;
  237. ret = target_read_u8(target, mg_task_reg + MG_REG_DRV_CTRL, &value);
  238. if (ret != ERROR_OK)
  239. return ret;
  240. if (on)
  241. value |= (mg_io_rbit_devc_srst);
  242. else
  243. value &= ~mg_io_rbit_devc_srst;
  244. ret = target_write_u8(target, mg_task_reg + MG_REG_DRV_CTRL, value);
  245. return ret;
  246. }
  247. static int mg_dsk_io_cmd(uint32_t sect_num, uint32_t cnt, uint8_t cmd)
  248. {
  249. struct target *target = mflash_bank->target;
  250. uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
  251. uint8_t value;
  252. int ret;
  253. ret = mg_dsk_wait(mg_io_wait_rdy_noerr, MG_OEM_DISK_WAIT_TIME_NORMAL);
  254. if (ret != ERROR_OK)
  255. return ret;
  256. value = mg_io_rval_dev_drv_master | mg_io_rval_dev_lba_mode | ((sect_num >> 24) & 0xf);
  257. ret = target_write_u8(target, mg_task_reg + MG_REG_DRV_HEAD, value);
  258. ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_CNT, (uint8_t)cnt);
  259. ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_NUM, (uint8_t)sect_num);
  260. ret |= target_write_u8(target, mg_task_reg + MG_REG_CYL_LOW, (uint8_t)(sect_num >> 8));
  261. ret |= target_write_u8(target, mg_task_reg + MG_REG_CYL_HIGH, (uint8_t)(sect_num >> 16));
  262. if (ret != ERROR_OK)
  263. return ret;
  264. return target_write_u8(target, mg_task_reg + MG_REG_COMMAND, cmd);
  265. }
  266. static int mg_dsk_drv_info(void)
  267. {
  268. struct target *target = mflash_bank->target;
  269. uint32_t mg_buff = mflash_bank->base + MG_BUFFER_OFFSET;
  270. int ret;
  271. ret = mg_dsk_io_cmd(0, 1, mg_io_cmd_identify);
  272. if (ret != ERROR_OK)
  273. return ret;
  274. ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
  275. if (ret != ERROR_OK)
  276. return ret;
  277. LOG_INFO("mflash: read drive info");
  278. if (!mflash_bank->drv_info)
  279. mflash_bank->drv_info = malloc(sizeof(struct mg_drv_info));
  280. ret = target_read_memory(target, mg_buff, 2,
  281. sizeof(mg_io_type_drv_info) >> 1,
  282. (uint8_t *)&mflash_bank->drv_info->drv_id);
  283. if (ret != ERROR_OK)
  284. return ret;
  285. mflash_bank->drv_info->tot_sects =
  286. (uint32_t)(mflash_bank->drv_info->drv_id.total_user_addressable_sectors_hi << 16)
  287. + mflash_bank->drv_info->drv_id.total_user_addressable_sectors_lo;
  288. return target_write_u8(target,
  289. mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND,
  290. mg_io_cmd_confirm_read);
  291. }
  292. static int mg_mflash_rst(void)
  293. {
  294. int ret;
  295. ret = mg_init_gpio();
  296. if (ret != ERROR_OK)
  297. return ret;
  298. ret = mg_hdrst(0);
  299. if (ret != ERROR_OK)
  300. return ret;
  301. ret = mg_dsk_wait(mg_io_wait_bsy, MG_OEM_DISK_WAIT_TIME_LONG);
  302. if (ret != ERROR_OK)
  303. return ret;
  304. ret = mg_hdrst(1);
  305. if (ret != ERROR_OK)
  306. return ret;
  307. ret = mg_dsk_wait(mg_io_wait_not_bsy, MG_OEM_DISK_WAIT_TIME_LONG);
  308. if (ret != ERROR_OK)
  309. return ret;
  310. ret = mg_dsk_srst(1);
  311. if (ret != ERROR_OK)
  312. return ret;
  313. ret = mg_dsk_wait(mg_io_wait_bsy, MG_OEM_DISK_WAIT_TIME_LONG);
  314. if (ret != ERROR_OK)
  315. return ret;
  316. ret = mg_dsk_srst(0);
  317. if (ret != ERROR_OK)
  318. return ret;
  319. ret = mg_dsk_wait(mg_io_wait_not_bsy, MG_OEM_DISK_WAIT_TIME_LONG);
  320. if (ret != ERROR_OK)
  321. return ret;
  322. LOG_INFO("mflash: reset ok");
  323. return ERROR_OK;
  324. }
  325. static int mg_mflash_probe(void)
  326. {
  327. int ret = mg_mflash_rst();
  328. if (ret != ERROR_OK)
  329. return ret;
  330. return mg_dsk_drv_info();
  331. }
  332. COMMAND_HANDLER(mg_probe_cmd)
  333. {
  334. int ret;
  335. ret = mg_mflash_probe();
  336. if (ret == ERROR_OK) {
  337. command_print(CMD_CTX,
  338. "mflash (total %" PRIu32 " sectors) found at 0x%8.8" PRIx32 "",
  339. mflash_bank->drv_info->tot_sects,
  340. mflash_bank->base);
  341. }
  342. return ret;
  343. }
  344. static int mg_mflash_do_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
  345. {
  346. uint32_t i, address;
  347. int ret;
  348. struct target *target = mflash_bank->target;
  349. uint8_t *buff_ptr = buff;
  350. ret = mg_dsk_io_cmd(sect_num, sect_cnt, mg_io_cmd_read);
  351. if (ret != ERROR_OK)
  352. return ret;
  353. address = mflash_bank->base + MG_BUFFER_OFFSET;
  354. struct duration bench;
  355. duration_start(&bench);
  356. for (i = 0; i < sect_cnt; i++) {
  357. ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
  358. if (ret != ERROR_OK)
  359. return ret;
  360. ret = target_read_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr);
  361. if (ret != ERROR_OK)
  362. return ret;
  363. buff_ptr += MG_MFLASH_SECTOR_SIZE;
  364. ret = target_write_u8(target,
  365. mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND,
  366. mg_io_cmd_confirm_read);
  367. if (ret != ERROR_OK)
  368. return ret;
  369. LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector read", sect_num + i,
  370. (sect_num + i) * MG_MFLASH_SECTOR_SIZE);
  371. ret = duration_measure(&bench);
  372. if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) {
  373. LOG_INFO("mflash: read %" PRIu32 "'th sectors", sect_num + i);
  374. duration_start(&bench);
  375. }
  376. }
  377. return mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_NORMAL);
  378. }
  379. static int mg_mflash_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
  380. {
  381. uint32_t quotient, residue, i;
  382. uint8_t *buff_ptr = buff;
  383. int ret = ERROR_OK;
  384. quotient = sect_cnt >> 8;
  385. residue = sect_cnt % 256;
  386. for (i = 0; i < quotient; i++) {
  387. LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p",
  388. sect_num, buff_ptr);
  389. ret = mg_mflash_do_read_sects(buff_ptr, sect_num, 256);
  390. if (ret != ERROR_OK)
  391. return ret;
  392. sect_num += 256;
  393. buff_ptr += 256 * MG_MFLASH_SECTOR_SIZE;
  394. }
  395. if (residue) {
  396. LOG_DEBUG("mflash: sect num : %" PRIx32 " buff : %p",
  397. sect_num, buff_ptr);
  398. return mg_mflash_do_read_sects(buff_ptr, sect_num, residue);
  399. }
  400. return ret;
  401. }
  402. static int mg_mflash_do_write_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt,
  403. uint8_t cmd)
  404. {
  405. uint32_t i, address;
  406. int ret;
  407. struct target *target = mflash_bank->target;
  408. uint8_t *buff_ptr = buff;
  409. ret = mg_dsk_io_cmd(sect_num, sect_cnt, cmd);
  410. if (ret != ERROR_OK)
  411. return ret;
  412. address = mflash_bank->base + MG_BUFFER_OFFSET;
  413. struct duration bench;
  414. duration_start(&bench);
  415. for (i = 0; i < sect_cnt; i++) {
  416. ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
  417. if (ret != ERROR_OK)
  418. return ret;
  419. ret = target_write_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr);
  420. if (ret != ERROR_OK)
  421. return ret;
  422. buff_ptr += MG_MFLASH_SECTOR_SIZE;
  423. ret = target_write_u8(target,
  424. mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND,
  425. mg_io_cmd_confirm_write);
  426. if (ret != ERROR_OK)
  427. return ret;
  428. LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector write", sect_num + i,
  429. (sect_num + i) * MG_MFLASH_SECTOR_SIZE);
  430. ret = duration_measure(&bench);
  431. if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) {
  432. LOG_INFO("mflash: wrote %" PRIu32 "'th sectors", sect_num + i);
  433. duration_start(&bench);
  434. }
  435. }
  436. if (cmd == mg_io_cmd_write)
  437. ret = mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_NORMAL);
  438. else
  439. ret = mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_LONG);
  440. return ret;
  441. }
  442. static int mg_mflash_write_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
  443. {
  444. uint32_t quotient, residue, i;
  445. uint8_t *buff_ptr = buff;
  446. int ret = ERROR_OK;
  447. quotient = sect_cnt >> 8;
  448. residue = sect_cnt % 256;
  449. for (i = 0; i < quotient; i++) {
  450. LOG_DEBUG("mflash: sect num : %" PRIu32 "buff : %p", sect_num,
  451. buff_ptr);
  452. ret = mg_mflash_do_write_sects(buff_ptr, sect_num, 256, mg_io_cmd_write);
  453. if (ret != ERROR_OK)
  454. return ret;
  455. sect_num += 256;
  456. buff_ptr += 256 * MG_MFLASH_SECTOR_SIZE;
  457. }
  458. if (residue) {
  459. LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p", sect_num,
  460. buff_ptr);
  461. return mg_mflash_do_write_sects(buff_ptr, sect_num, residue, mg_io_cmd_write);
  462. }
  463. return ret;
  464. }
  465. static int mg_mflash_read(uint32_t addr, uint8_t *buff, uint32_t len)
  466. {
  467. uint8_t *buff_ptr = buff;
  468. uint8_t sect_buff[MG_MFLASH_SECTOR_SIZE];
  469. uint32_t cur_addr, next_sec_addr, end_addr, cnt, sect_num;
  470. int ret = ERROR_OK;
  471. cnt = 0;
  472. cur_addr = addr;
  473. end_addr = addr + len;
  474. if (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK) {
  475. next_sec_addr = (cur_addr + MG_MFLASH_SECTOR_SIZE) & ~MG_MFLASH_SECTOR_SIZE_MASK;
  476. sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
  477. ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
  478. if (ret != ERROR_OK)
  479. return ret;
  480. if (end_addr < next_sec_addr) {
  481. memcpy(buff_ptr,
  482. sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK),
  483. end_addr - cur_addr);
  484. LOG_DEBUG(
  485. "mflash: copies %" PRIu32 " byte from sector offset 0x%8.8" PRIx32 "",
  486. end_addr - cur_addr,
  487. cur_addr);
  488. cur_addr = end_addr;
  489. } else {
  490. memcpy(buff_ptr,
  491. sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK),
  492. next_sec_addr - cur_addr);
  493. LOG_DEBUG(
  494. "mflash: copies %" PRIu32 " byte from sector offset 0x%8.8" PRIx32 "",
  495. next_sec_addr - cur_addr,
  496. cur_addr);
  497. buff_ptr += (next_sec_addr - cur_addr);
  498. cur_addr = next_sec_addr;
  499. }
  500. }
  501. if (cur_addr < end_addr) {
  502. sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
  503. next_sec_addr = cur_addr + MG_MFLASH_SECTOR_SIZE;
  504. while (next_sec_addr <= end_addr) {
  505. cnt++;
  506. next_sec_addr += MG_MFLASH_SECTOR_SIZE;
  507. }
  508. if (cnt) {
  509. ret = mg_mflash_read_sects(buff_ptr, sect_num, cnt);
  510. if (ret != ERROR_OK)
  511. return ret;
  512. }
  513. buff_ptr += cnt * MG_MFLASH_SECTOR_SIZE;
  514. cur_addr += cnt * MG_MFLASH_SECTOR_SIZE;
  515. if (cur_addr < end_addr) {
  516. sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
  517. ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
  518. if (ret != ERROR_OK)
  519. return ret;
  520. memcpy(buff_ptr, sect_buff, end_addr - cur_addr);
  521. LOG_DEBUG("mflash: copies %u byte", (unsigned)(end_addr - cur_addr));
  522. }
  523. }
  524. return ret;
  525. }
  526. static int mg_mflash_write(uint32_t addr, uint8_t *buff, uint32_t len)
  527. {
  528. uint8_t *buff_ptr = buff;
  529. uint8_t sect_buff[MG_MFLASH_SECTOR_SIZE];
  530. uint32_t cur_addr, next_sec_addr, end_addr, cnt, sect_num;
  531. int ret = ERROR_OK;
  532. cnt = 0;
  533. cur_addr = addr;
  534. end_addr = addr + len;
  535. if (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK) {
  536. next_sec_addr = (cur_addr + MG_MFLASH_SECTOR_SIZE) & ~MG_MFLASH_SECTOR_SIZE_MASK;
  537. sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
  538. ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
  539. if (ret != ERROR_OK)
  540. return ret;
  541. if (end_addr < next_sec_addr) {
  542. memcpy(sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK),
  543. buff_ptr,
  544. end_addr - cur_addr);
  545. LOG_DEBUG(
  546. "mflash: copies %" PRIu32 " byte to sector offset 0x%8.8" PRIx32 "",
  547. end_addr - cur_addr,
  548. cur_addr);
  549. cur_addr = end_addr;
  550. } else {
  551. memcpy(sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK),
  552. buff_ptr,
  553. next_sec_addr - cur_addr);
  554. LOG_DEBUG(
  555. "mflash: copies %" PRIu32 " byte to sector offset 0x%8.8" PRIx32 "",
  556. next_sec_addr - cur_addr,
  557. cur_addr);
  558. buff_ptr += (next_sec_addr - cur_addr);
  559. cur_addr = next_sec_addr;
  560. }
  561. ret = mg_mflash_write_sects(sect_buff, sect_num, 1);
  562. if (ret != ERROR_OK)
  563. return ret;
  564. }
  565. if (cur_addr < end_addr) {
  566. sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
  567. next_sec_addr = cur_addr + MG_MFLASH_SECTOR_SIZE;
  568. while (next_sec_addr <= end_addr) {
  569. cnt++;
  570. next_sec_addr += MG_MFLASH_SECTOR_SIZE;
  571. }
  572. if (cnt) {
  573. ret = mg_mflash_write_sects(buff_ptr, sect_num, cnt);
  574. if (ret != ERROR_OK)
  575. return ret;
  576. }
  577. buff_ptr += cnt * MG_MFLASH_SECTOR_SIZE;
  578. cur_addr += cnt * MG_MFLASH_SECTOR_SIZE;
  579. if (cur_addr < end_addr) {
  580. sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
  581. ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
  582. if (ret != ERROR_OK)
  583. return ret;
  584. memcpy(sect_buff, buff_ptr, end_addr - cur_addr);
  585. LOG_DEBUG("mflash: copies %" PRIu32 " byte", end_addr - cur_addr);
  586. ret = mg_mflash_write_sects(sect_buff, sect_num, 1);
  587. }
  588. }
  589. return ret;
  590. }
  591. COMMAND_HANDLER(mg_write_cmd)
  592. {
  593. uint32_t address, cnt, res, i;
  594. uint8_t *buffer;
  595. struct fileio *fileio;
  596. int ret;
  597. if (CMD_ARGC != 3)
  598. return ERROR_COMMAND_SYNTAX_ERROR;
  599. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
  600. ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
  601. if (ret != ERROR_OK)
  602. return ret;
  603. size_t filesize;
  604. buffer = malloc(MG_FILEIO_CHUNK);
  605. if (!buffer) {
  606. fileio_close(fileio);
  607. return ERROR_FAIL;
  608. }
  609. int retval = fileio_size(fileio, &filesize);
  610. if (retval != ERROR_OK) {
  611. fileio_close(fileio);
  612. free(buffer);
  613. return retval;
  614. }
  615. cnt = filesize / MG_FILEIO_CHUNK;
  616. res = filesize % MG_FILEIO_CHUNK;
  617. struct duration bench;
  618. duration_start(&bench);
  619. size_t buf_cnt;
  620. for (i = 0; i < cnt; i++) {
  621. ret = fileio_read(fileio, MG_FILEIO_CHUNK, buffer, &buf_cnt);
  622. if (ret != ERROR_OK)
  623. goto mg_write_cmd_err;
  624. ret = mg_mflash_write(address, buffer, MG_FILEIO_CHUNK);
  625. if (ret != ERROR_OK)
  626. goto mg_write_cmd_err;
  627. address += MG_FILEIO_CHUNK;
  628. }
  629. if (res) {
  630. ret = fileio_read(fileio, res, buffer, &buf_cnt);
  631. if (ret != ERROR_OK)
  632. goto mg_write_cmd_err;
  633. ret = mg_mflash_write(address, buffer, res);
  634. if (ret != ERROR_OK)
  635. goto mg_write_cmd_err;
  636. }
  637. if (duration_measure(&bench) == ERROR_OK) {
  638. command_print(CMD_CTX, "wrote %zu bytes from file %s "
  639. "in %fs (%0.3f kB/s)", filesize, CMD_ARGV[1],
  640. duration_elapsed(&bench), duration_kbps(&bench, filesize));
  641. }
  642. free(buffer);
  643. fileio_close(fileio);
  644. return ERROR_OK;
  645. mg_write_cmd_err:
  646. free(buffer);
  647. fileio_close(fileio);
  648. return ret;
  649. }
  650. COMMAND_HANDLER(mg_dump_cmd)
  651. {
  652. uint32_t address, size, cnt, res, i;
  653. uint8_t *buffer;
  654. struct fileio *fileio;
  655. int ret;
  656. if (CMD_ARGC != 4)
  657. return ERROR_COMMAND_SYNTAX_ERROR;
  658. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
  659. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], size);
  660. ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);
  661. if (ret != ERROR_OK)
  662. return ret;
  663. buffer = malloc(MG_FILEIO_CHUNK);
  664. if (!buffer) {
  665. fileio_close(fileio);
  666. return ERROR_FAIL;
  667. }
  668. cnt = size / MG_FILEIO_CHUNK;
  669. res = size % MG_FILEIO_CHUNK;
  670. struct duration bench;
  671. duration_start(&bench);
  672. size_t size_written;
  673. for (i = 0; i < cnt; i++) {
  674. ret = mg_mflash_read(address, buffer, MG_FILEIO_CHUNK);
  675. if (ret != ERROR_OK)
  676. goto mg_dump_cmd_err;
  677. ret = fileio_write(fileio, MG_FILEIO_CHUNK, buffer, &size_written);
  678. if (ret != ERROR_OK)
  679. goto mg_dump_cmd_err;
  680. address += MG_FILEIO_CHUNK;
  681. }
  682. if (res) {
  683. ret = mg_mflash_read(address, buffer, res);
  684. if (ret != ERROR_OK)
  685. goto mg_dump_cmd_err;
  686. ret = fileio_write(fileio, res, buffer, &size_written);
  687. if (ret != ERROR_OK)
  688. goto mg_dump_cmd_err;
  689. }
  690. if (duration_measure(&bench) == ERROR_OK) {
  691. command_print(CMD_CTX, "dump image (address 0x%8.8" PRIx32 " "
  692. "size %" PRIu32 ") to file %s in %fs (%0.3f kB/s)",
  693. address, size, CMD_ARGV[1],
  694. duration_elapsed(&bench), duration_kbps(&bench, size));
  695. }
  696. free(buffer);
  697. fileio_close(fileio);
  698. return ERROR_OK;
  699. mg_dump_cmd_err:
  700. free(buffer);
  701. fileio_close(fileio);
  702. return ret;
  703. }
  704. static int mg_set_feature(mg_feature_id feature, mg_feature_val config)
  705. {
  706. struct target *target = mflash_bank->target;
  707. uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
  708. int ret;
  709. ret = mg_dsk_wait(mg_io_wait_rdy_noerr, MG_OEM_DISK_WAIT_TIME_NORMAL);
  710. if (ret != ERROR_OK)
  711. return ret;
  712. ret = target_write_u8(target, mg_task_reg + MG_REG_FEATURE, feature);
  713. ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_CNT, config);
  714. ret |= target_write_u8(target, mg_task_reg + MG_REG_COMMAND,
  715. mg_io_cmd_set_feature);
  716. return ret;
  717. }
  718. static int mg_is_valid_pll(double XIN, int N, double CLK_OUT, int NO)
  719. {
  720. double v1 = XIN / N;
  721. double v2 = CLK_OUT * NO;
  722. if (v1 < 1000000 || v1 > 15000000 || v2 < 100000000 || v2 > 500000000)
  723. return ERROR_MG_INVALID_PLL;
  724. return ERROR_OK;
  725. }
  726. static int mg_pll_get_M(unsigned short feedback_div)
  727. {
  728. int i, M;
  729. for (i = 1, M = 0; i < 512; i <<= 1, feedback_div >>= 1)
  730. M += (feedback_div & 1) * i;
  731. return M + 2;
  732. }
  733. static int mg_pll_get_N(unsigned char input_div)
  734. {
  735. int i, N;
  736. for (i = 1, N = 0; i < 32; i <<= 1, input_div >>= 1)
  737. N += (input_div & 1) * i;
  738. return N + 2;
  739. }
  740. static int mg_pll_get_NO(unsigned char output_div)
  741. {
  742. int i, NO;
  743. for (i = 0, NO = 1; i < 2; ++i, output_div >>= 1)
  744. if (output_div & 1)
  745. NO = NO << 1;
  746. return NO;
  747. }
  748. static double mg_do_calc_pll(double XIN, mg_pll_t *p_pll_val, int is_approximate)
  749. {
  750. unsigned short i;
  751. unsigned char j, k;
  752. int M, N, NO;
  753. double CLK_OUT;
  754. double DIV = 1;
  755. double ROUND = 0;
  756. if (is_approximate) {
  757. DIV = 1000000;
  758. ROUND = 500000;
  759. }
  760. for (i = 0; i < MG_PLL_MAX_FEEDBACKDIV_VAL; ++i) {
  761. M = mg_pll_get_M(i);
  762. for (j = 0; j < MG_PLL_MAX_INPUTDIV_VAL; ++j) {
  763. N = mg_pll_get_N(j);
  764. for (k = 0; k < MG_PLL_MAX_OUTPUTDIV_VAL; ++k) {
  765. NO = mg_pll_get_NO(k);
  766. CLK_OUT = XIN * ((double)M / N) / NO;
  767. if ((int)((CLK_OUT + ROUND) / DIV)
  768. == (int)(MG_PLL_CLK_OUT / DIV)) {
  769. if (mg_is_valid_pll(XIN, N, CLK_OUT, NO) == ERROR_OK) {
  770. p_pll_val->lock_cyc =
  771. (int)(XIN * MG_PLL_STD_LOCKCYCLE /
  772. MG_PLL_STD_INPUTCLK);
  773. p_pll_val->feedback_div = i;
  774. p_pll_val->input_div = j;
  775. p_pll_val->output_div = k;
  776. return CLK_OUT;
  777. }
  778. }
  779. }
  780. }
  781. }
  782. return 0;
  783. }
  784. static double mg_calc_pll(double XIN, mg_pll_t *p_pll_val)
  785. {
  786. double CLK_OUT;
  787. CLK_OUT = mg_do_calc_pll(XIN, p_pll_val, 0);
  788. if (!CLK_OUT)
  789. return mg_do_calc_pll(XIN, p_pll_val, 1);
  790. else
  791. return CLK_OUT;
  792. }
  793. static int mg_verify_interface(void)
  794. {
  795. uint16_t buff[MG_MFLASH_SECTOR_SIZE >> 1];
  796. uint16_t i, j;
  797. uint32_t address = mflash_bank->base + MG_BUFFER_OFFSET;
  798. struct target *target = mflash_bank->target;
  799. int ret;
  800. for (j = 0; j < 10; j++) {
  801. for (i = 0; i < MG_MFLASH_SECTOR_SIZE >> 1; i++)
  802. buff[i] = i;
  803. ret = target_write_memory(target, address, 2,
  804. MG_MFLASH_SECTOR_SIZE / 2, (uint8_t *)buff);
  805. if (ret != ERROR_OK)
  806. return ret;
  807. memset(buff, 0xff, MG_MFLASH_SECTOR_SIZE);
  808. ret = target_read_memory(target, address, 2,
  809. MG_MFLASH_SECTOR_SIZE / 2, (uint8_t *)buff);
  810. if (ret != ERROR_OK)
  811. return ret;
  812. for (i = 0; i < MG_MFLASH_SECTOR_SIZE >> 1; i++) {
  813. if (buff[i] != i) {
  814. LOG_ERROR("mflash: verify interface fail");
  815. return ERROR_MG_INTERFACE;
  816. }
  817. }
  818. }
  819. LOG_INFO("mflash: verify interface ok");
  820. return ret;
  821. }
  822. static const char g_strSEG_SerialNum[20] = {
  823. 'G', 'm', 'n', 'i', '-', 'e', 'e', 'S', 'g', 'a', 'e', 'l',
  824. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
  825. };
  826. static const char g_strSEG_FWRev[8] = {
  827. 'F', 'X', 'L', 'T', '2', 'v', '0', '.'
  828. };
  829. static const char g_strSEG_ModelNum[40] = {
  830. 'F', 'X', 'A', 'L', 'H', 'S', '2', 0x20, '0', '0', 's', '7',
  831. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  832. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
  833. 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
  834. };
  835. static void mg_gen_ataid(mg_io_type_drv_info *pSegIdDrvInfo)
  836. {
  837. /* b15 is ATA device(0) , b7 is Removable Media Device */
  838. pSegIdDrvInfo->general_configuration = 0x045A;
  839. /* 128MB : Cylinder=> 977 , Heads=> 8 , Sectors=> 32
  840. * 256MB : Cylinder=> 980 , Heads=> 16 , Sectors=> 32
  841. * 384MB : Cylinder=> 745 , Heads=> 16 , Sectors=> 63
  842. */
  843. pSegIdDrvInfo->number_of_cylinders = 0x02E9;
  844. pSegIdDrvInfo->reserved1 = 0x0;
  845. pSegIdDrvInfo->number_of_heads = 0x10;
  846. pSegIdDrvInfo->unformatted_bytes_per_track = 0x0;
  847. pSegIdDrvInfo->unformatted_bytes_per_sector = 0x0;
  848. pSegIdDrvInfo->sectors_per_track = 0x3F;
  849. pSegIdDrvInfo->vendor_unique1[0] = 0x000B;
  850. pSegIdDrvInfo->vendor_unique1[1] = 0x7570;
  851. pSegIdDrvInfo->vendor_unique1[2] = 0x8888;
  852. memcpy(pSegIdDrvInfo->serial_number, g_strSEG_SerialNum, 20);
  853. /* 0x2 : dual buffer */
  854. pSegIdDrvInfo->buffer_type = 0x2;
  855. /* buffer size : 2KB */
  856. pSegIdDrvInfo->buffer_sector_size = 0x800;
  857. pSegIdDrvInfo->number_of_ecc_bytes = 0;
  858. memcpy(pSegIdDrvInfo->firmware_revision, g_strSEG_FWRev, 8);
  859. memcpy(pSegIdDrvInfo->model_number, g_strSEG_ModelNum, 40);
  860. pSegIdDrvInfo->maximum_block_transfer = 0x4;
  861. pSegIdDrvInfo->vendor_unique2 = 0x0;
  862. pSegIdDrvInfo->dword_io = 0x00;
  863. /* b11 : IORDY support(PIO Mode 4), b10 : Disable/Enbale IORDY
  864. * b9 : LBA support, b8 : DMA mode support
  865. */
  866. pSegIdDrvInfo->capabilities = 0x1 << 9;
  867. pSegIdDrvInfo->reserved2 = 0x4000;
  868. pSegIdDrvInfo->vendor_unique3 = 0x00;
  869. /* PIOMode-2 support */
  870. pSegIdDrvInfo->pio_cycle_timing_mode = 0x02;
  871. pSegIdDrvInfo->vendor_unique4 = 0x00;
  872. /* MultiWord-2 support */
  873. pSegIdDrvInfo->dma_cycle_timing_mode = 0x00;
  874. /* b1 : word64~70 is valid
  875. * b0 : word54~58 are valid and reflect the current numofcyls,heads,sectors
  876. * b2 : If device supports Ultra DMA , set to one to vaildate word88
  877. */
  878. pSegIdDrvInfo->translation_fields_valid = (0x1 << 1) | (0x1 << 0);
  879. pSegIdDrvInfo->number_of_current_cylinders = 0x02E9;
  880. pSegIdDrvInfo->number_of_current_heads = 0x10;
  881. pSegIdDrvInfo->current_sectors_per_track = 0x3F;
  882. pSegIdDrvInfo->current_sector_capacity_lo = 0x7570;
  883. pSegIdDrvInfo->current_sector_capacity_hi = 0x000B;
  884. pSegIdDrvInfo->multi_sector_count = 0x04;
  885. /* b8 : Multiple secotr setting valid , b[7:0] num of secotrs per block */
  886. pSegIdDrvInfo->multi_sector_setting_valid = 0x01;
  887. pSegIdDrvInfo->total_user_addressable_sectors_lo = 0x7570;
  888. pSegIdDrvInfo->total_user_addressable_sectors_hi = 0x000B;
  889. pSegIdDrvInfo->single_dma_modes_supported = 0x00;
  890. pSegIdDrvInfo->single_dma_transfer_active = 0x00;
  891. /* b2 :Multi-word DMA mode 2, b1 : Multi-word DMA mode 1 */
  892. pSegIdDrvInfo->multi_dma_modes_supported = (0x1 << 0);
  893. /* b2 :Multi-word DMA mode 2, b1 : Multi-word DMA mode 1 */
  894. pSegIdDrvInfo->multi_dma_transfer_active = (0x1 << 0);
  895. /* b0 : PIO Mode-3 support, b1 : PIO Mode-4 support */
  896. pSegIdDrvInfo->adv_pio_mode = 0x00;
  897. /* 480(0x1E0)nsec for Multi-word DMA mode0
  898. * 150(0x96) nsec for Multi-word DMA mode1
  899. * 120(0x78) nsec for Multi-word DMA mode2
  900. */
  901. pSegIdDrvInfo->min_dma_cyc = 0x1E0;
  902. pSegIdDrvInfo->recommend_dma_cyc = 0x1E0;
  903. pSegIdDrvInfo->min_pio_cyc_no_iordy = 0x1E0;
  904. pSegIdDrvInfo->min_pio_cyc_with_iordy = 0x1E0;
  905. memset(pSegIdDrvInfo->reserved3, 0x00, 22);
  906. /* b7 : ATA/ATAPI-7 ,b6 : ATA/ATAPI-6 ,b5 : ATA/ATAPI-5,b4 : ATA/ATAPI-4 */
  907. pSegIdDrvInfo->major_ver_num = 0x7E;
  908. /* 0x1C : ATA/ATAPI-6 T13 1532D revision1 */
  909. pSegIdDrvInfo->minor_ver_num = 0x19;
  910. /* NOP/READ BUFFER/WRITE BUFFER/Power management feature set support */
  911. pSegIdDrvInfo->feature_cmd_set_suprt0 = 0x7068;
  912. /* Features/command set is valid/Advanced Pwr management/CFA feature set
  913. * not support
  914. */
  915. pSegIdDrvInfo->feature_cmd_set_suprt1 = 0x400C;
  916. pSegIdDrvInfo->feature_cmd_set_suprt2 = 0x4000;
  917. /* READ/WRITE BUFFER/PWR Management enable */
  918. pSegIdDrvInfo->feature_cmd_set_en0 = 0x7000;
  919. /* CFA feature is disabled / Advancde power management disable */
  920. pSegIdDrvInfo->feature_cmd_set_en1 = 0x0;
  921. pSegIdDrvInfo->feature_cmd_set_en2 = 0x4000;
  922. pSegIdDrvInfo->reserved4 = 0x0;
  923. /* 0x1 * 2minutes */
  924. pSegIdDrvInfo->req_time_for_security_er_done = 0x19;
  925. pSegIdDrvInfo->req_time_for_enhan_security_er_done = 0x19;
  926. /* Advanced power management level 1 */
  927. pSegIdDrvInfo->adv_pwr_mgm_lvl_val = 0x0;
  928. pSegIdDrvInfo->reserved5 = 0x0;
  929. memset(pSegIdDrvInfo->reserved6, 0x00, 68);
  930. /* Security mode feature is disabled */
  931. pSegIdDrvInfo->security_stas = 0x0;
  932. memset(pSegIdDrvInfo->vendor_uniq_bytes, 0x00, 62);
  933. /* CFA power mode 1 support in maximum 200mA */
  934. pSegIdDrvInfo->cfa_pwr_mode = 0x0100;
  935. memset(pSegIdDrvInfo->reserved7, 0x00, 190);
  936. }
  937. static int mg_storage_config(void)
  938. {
  939. uint8_t buff[512];
  940. int ret;
  941. ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd);
  942. if (ret != ERROR_OK)
  943. return ret;
  944. mg_gen_ataid((mg_io_type_drv_info *)(void *)buff);
  945. ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_update_stgdrvinfo);
  946. if (ret != ERROR_OK)
  947. return ret;
  948. ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default);
  949. if (ret != ERROR_OK)
  950. return ret;
  951. LOG_INFO("mflash: storage config ok");
  952. return ret;
  953. }
  954. static int mg_boot_config(void)
  955. {
  956. uint8_t buff[512];
  957. int ret;
  958. ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd);
  959. if (ret != ERROR_OK)
  960. return ret;
  961. memset(buff, 0xff, 512);
  962. buff[0] = mg_op_mode_snd; /* operation mode */
  963. buff[1] = MG_UNLOCK_OTP_AREA;
  964. buff[2] = 4; /* boot size */
  965. *((uint32_t *)(void *)(buff + 4)) = 0; /* XIP size */
  966. ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_update_xipinfo);
  967. if (ret != ERROR_OK)
  968. return ret;
  969. ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default);
  970. if (ret != ERROR_OK)
  971. return ret;
  972. LOG_INFO("mflash: boot config ok");
  973. return ret;
  974. }
  975. static int mg_set_pll(mg_pll_t *pll)
  976. {
  977. uint8_t buff[512];
  978. int ret;
  979. memset(buff, 0xff, 512);
  980. /* PLL Lock cycle and Feedback 9bit Divider */
  981. memcpy(buff, &pll->lock_cyc, sizeof(uint32_t));
  982. memcpy(buff + 4, &pll->feedback_div, sizeof(uint16_t));
  983. buff[6] = pll->input_div; /* PLL Input 5bit Divider */
  984. buff[7] = pll->output_div; /* PLL Output Divider */
  985. ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd);
  986. if (ret != ERROR_OK)
  987. return ret;
  988. ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_wr_pll);
  989. if (ret != ERROR_OK)
  990. return ret;
  991. ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default);
  992. if (ret != ERROR_OK)
  993. return ret;
  994. LOG_INFO("mflash: set pll ok");
  995. return ret;
  996. }
  997. static int mg_erase_nand(void)
  998. {
  999. int ret;
  1000. ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd);
  1001. if (ret != ERROR_OK)
  1002. return ret;
  1003. ret = mg_mflash_do_write_sects(NULL, 0, 0, mg_vcmd_purge_nand);
  1004. if (ret != ERROR_OK)
  1005. return ret;
  1006. ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default);
  1007. if (ret != ERROR_OK)
  1008. return ret;
  1009. LOG_INFO("mflash: erase nand ok");
  1010. return ret;
  1011. }
  1012. COMMAND_HANDLER(mg_config_cmd)
  1013. {
  1014. double fin, fout;
  1015. mg_pll_t pll;
  1016. int ret;
  1017. ret = mg_verify_interface();
  1018. if (ret != ERROR_OK)
  1019. return ret;
  1020. ret = mg_mflash_rst();
  1021. if (ret != ERROR_OK)
  1022. return ret;
  1023. switch (CMD_ARGC) {
  1024. case 2:
  1025. if (!strcmp(CMD_ARGV[1], "boot"))
  1026. return mg_boot_config();
  1027. else if (!strcmp(CMD_ARGV[1], "storage"))
  1028. return mg_storage_config();
  1029. else
  1030. return ERROR_COMMAND_NOTFOUND;
  1031. break;
  1032. case 3:
  1033. if (!strcmp(CMD_ARGV[1], "pll")) {
  1034. unsigned long freq;
  1035. COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], freq);
  1036. fin = freq;
  1037. if (fin > MG_PLL_CLK_OUT) {
  1038. LOG_ERROR("mflash: input freq. is too large");
  1039. return ERROR_MG_INVALID_OSC;
  1040. }
  1041. fout = mg_calc_pll(fin, &pll);
  1042. if (!fout) {
  1043. LOG_ERROR("mflash: cannot generate valid pll");
  1044. return ERROR_MG_INVALID_PLL;
  1045. }
  1046. LOG_INFO("mflash: Fout=%" PRIu32 " Hz, feedback=%u,"
  1047. "indiv=%u, outdiv=%u, lock=%u",
  1048. (uint32_t)fout, pll.feedback_div,
  1049. pll.input_div, pll.output_div,
  1050. pll.lock_cyc);
  1051. ret = mg_erase_nand();
  1052. if (ret != ERROR_OK)
  1053. return ret;
  1054. return mg_set_pll(&pll);
  1055. } else
  1056. return ERROR_COMMAND_NOTFOUND;
  1057. break;
  1058. default:
  1059. return ERROR_COMMAND_SYNTAX_ERROR;
  1060. }
  1061. }
  1062. static const struct command_registration mflash_exec_command_handlers[] = {
  1063. {
  1064. .name = "probe",
  1065. .handler = mg_probe_cmd,
  1066. .mode = COMMAND_EXEC,
  1067. .help = "Detect bank configuration information",
  1068. },
  1069. {
  1070. .name = "write",
  1071. .handler = mg_write_cmd,
  1072. .mode = COMMAND_EXEC,
  1073. /* FIXME bank_num is unused */
  1074. .usage = "bank_num filename address",
  1075. .help = "Write binary file at the specified address.",
  1076. },
  1077. {
  1078. .name = "dump",
  1079. .handler = mg_dump_cmd,
  1080. .mode = COMMAND_EXEC,
  1081. /* FIXME bank_num is unused */
  1082. .usage = "bank_num filename address size",
  1083. .help = "Write specified number of bytes from a binary file "
  1084. "to the specified, address.",
  1085. },
  1086. {
  1087. .name = "config",
  1088. .handler = mg_config_cmd,
  1089. .mode = COMMAND_EXEC,
  1090. .help = "Configure MFLASH options.",
  1091. .usage = "('boot'|'storage'|'pll' frequency)",
  1092. },
  1093. COMMAND_REGISTRATION_DONE
  1094. };
  1095. static int mflash_init_drivers(struct command_context *cmd_ctx)
  1096. {
  1097. if (!mflash_bank)
  1098. return ERROR_OK;
  1099. return register_commands(cmd_ctx, NULL, mflash_exec_command_handlers);
  1100. }
  1101. COMMAND_HANDLER(handle_mflash_init_command)
  1102. {
  1103. if (CMD_ARGC != 0)
  1104. return ERROR_COMMAND_SYNTAX_ERROR;
  1105. static bool mflash_initialized;
  1106. if (mflash_initialized) {
  1107. LOG_INFO("'mflash init' has already been called");
  1108. return ERROR_OK;
  1109. }
  1110. mflash_initialized = true;
  1111. LOG_DEBUG("Initializing mflash devices...");
  1112. return mflash_init_drivers(CMD_CTX);
  1113. }
  1114. COMMAND_HANDLER(mg_bank_cmd)
  1115. {
  1116. struct target *target;
  1117. int i;
  1118. if (CMD_ARGC < 4)
  1119. return ERROR_COMMAND_SYNTAX_ERROR;
  1120. target = get_target(CMD_ARGV[3]);
  1121. if (target == NULL) {
  1122. LOG_ERROR("target '%s' not defined", CMD_ARGV[3]);
  1123. return ERROR_FAIL;
  1124. }
  1125. mflash_bank = calloc(sizeof(struct mflash_bank), 1);
  1126. COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], mflash_bank->base);
  1127. /** @todo Verify how this parsing should work, then document it. */
  1128. char *str;
  1129. mflash_bank->rst_pin.num = strtoul(CMD_ARGV[2], &str, 0);
  1130. if (*str)
  1131. mflash_bank->rst_pin.port[0] = (uint16_t)
  1132. tolower((unsigned)str[0]);
  1133. mflash_bank->target = target;
  1134. for (i = 0; mflash_gpio[i]; i++) {
  1135. if (!strcmp(mflash_gpio[i]->name, CMD_ARGV[0]))
  1136. mflash_bank->gpio_drv = mflash_gpio[i];
  1137. }
  1138. if (!mflash_bank->gpio_drv) {
  1139. LOG_ERROR("%s is unsupported soc", CMD_ARGV[0]);
  1140. return ERROR_MG_UNSUPPORTED_SOC;
  1141. }
  1142. return ERROR_OK;
  1143. }
  1144. static const struct command_registration mflash_config_command_handlers[] = {
  1145. {
  1146. .name = "bank",
  1147. .handler = mg_bank_cmd,
  1148. .mode = COMMAND_CONFIG,
  1149. .help = "configure a mflash device bank",
  1150. .usage = "soc_type base_addr pin_id target",
  1151. },
  1152. {
  1153. .name = "init",
  1154. .mode = COMMAND_CONFIG,
  1155. .handler = handle_mflash_init_command,
  1156. .help = "initialize mflash devices",
  1157. .usage = ""
  1158. },
  1159. COMMAND_REGISTRATION_DONE
  1160. };
  1161. static const struct command_registration mflash_command_handler[] = {
  1162. {
  1163. .name = "mflash",
  1164. .mode = COMMAND_ANY,
  1165. .help = "mflash command group",
  1166. .usage = "",
  1167. .chain = mflash_config_command_handlers,
  1168. },
  1169. COMMAND_REGISTRATION_DONE
  1170. };
  1171. int mflash_register_commands(struct command_context *cmd_ctx)
  1172. {
  1173. return register_commands(cmd_ctx, NULL, mflash_command_handler);
  1174. }