1 /***************************************************************************
2 * Copyright (C) 2007-2008 by unsik Kim <donari75@gmail.com> *
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. *
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. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
16 ***************************************************************************/
23 #include <target/target.h>
24 #include <helper/time_support.h>
25 #include <helper/fileio.h>
26 #include <helper/log.h>
28 static int s3c2440_set_gpio_to_output(struct mflash_gpio_num gpio);
29 static int s3c2440_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val);
30 static int pxa270_set_gpio_to_output(struct mflash_gpio_num gpio);
31 static int pxa270_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val);
33 static struct mflash_bank *mflash_bank;
35 static struct mflash_gpio_drv pxa270_gpio = {
37 .set_gpio_to_output = pxa270_set_gpio_to_output,
38 .set_gpio_output_val = pxa270_set_gpio_output_val
41 static struct mflash_gpio_drv s3c2440_gpio = {
43 .set_gpio_to_output = s3c2440_set_gpio_to_output,
44 .set_gpio_output_val = s3c2440_set_gpio_output_val
47 static struct mflash_gpio_drv *mflash_gpio[] = {
53 #define PXA270_GAFR0_L 0x40E00054
54 #define PXA270_GAFR3_U 0x40E00070
55 #define PXA270_GAFR3_U_RESERVED_BITS 0xfffc0000u
56 #define PXA270_GPDR0 0x40E0000C
57 #define PXA270_GPDR3 0x40E0010C
58 #define PXA270_GPDR3_RESERVED_BITS 0xfe000000u
59 #define PXA270_GPSR0 0x40E00018
60 #define PXA270_GPCR0 0x40E00024
62 static int pxa270_set_gpio_to_output(struct mflash_gpio_num gpio)
64 uint32_t addr, value, mask;
65 struct target *target = mflash_bank->target;
68 /* remove alternate function. */
69 mask = 0x3u << (gpio.num & 0xF)*2;
71 addr = PXA270_GAFR0_L + (gpio.num >> 4) * 4;
73 ret = target_read_u32(target, addr, &value);
78 if (addr == PXA270_GAFR3_U)
79 value &= ~PXA270_GAFR3_U_RESERVED_BITS;
81 ret = target_write_u32(target, addr, value);
85 /* set direction to output */
86 mask = 0x1u << (gpio.num & 0x1F);
88 addr = PXA270_GPDR0 + (gpio.num >> 5) * 4;
90 ret = target_read_u32(target, addr, &value);
95 if (addr == PXA270_GPDR3)
96 value &= ~PXA270_GPDR3_RESERVED_BITS;
98 ret = target_write_u32(target, addr, value);
102 static int pxa270_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val)
104 uint32_t addr, value, mask;
105 struct target *target = mflash_bank->target;
108 mask = 0x1u << (gpio.num & 0x1F);
111 addr = PXA270_GPSR0 + (gpio.num >> 5) * 4;
113 addr = PXA270_GPCR0 + (gpio.num >> 5) * 4;
115 ret = target_read_u32(target, addr, &value);
121 ret = target_write_u32(target, addr, value);
126 #define S3C2440_GPACON 0x56000000
127 #define S3C2440_GPADAT 0x56000004
128 #define S3C2440_GPJCON 0x560000d0
129 #define S3C2440_GPJDAT 0x560000d4
131 static int s3c2440_set_gpio_to_output(struct mflash_gpio_num gpio)
133 uint32_t data, mask, gpio_con;
134 struct target *target = mflash_bank->target;
137 if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h')
138 gpio_con = S3C2440_GPACON + (gpio.port[0] - 'a') * 0x10;
139 else if (gpio.port[0] == 'j')
140 gpio_con = S3C2440_GPJCON;
142 LOG_ERROR("mflash: invalid port %d%s", gpio.num, gpio.port);
143 return ERROR_COMMAND_SYNTAX_ERROR;
146 ret = target_read_u32(target, gpio_con, &data);
148 if (ret == ERROR_OK) {
149 if (gpio.port[0] == 'a') {
150 mask = 1 << gpio.num;
153 mask = 3 << gpio.num * 2;
155 data |= (1 << gpio.num * 2);
158 ret = target_write_u32(target, gpio_con, data);
163 static int s3c2440_set_gpio_output_val(struct mflash_gpio_num gpio, uint8_t val)
165 uint32_t data, mask, gpio_dat;
166 struct target *target = mflash_bank->target;
169 if (gpio.port[0] >= 'a' && gpio.port[0] <= 'h')
170 gpio_dat = S3C2440_GPADAT + (gpio.port[0] - 'a') * 0x10;
171 else if (gpio.port[0] == 'j')
172 gpio_dat = S3C2440_GPJDAT;
174 LOG_ERROR("mflash: invalid port %d%s", gpio.num, gpio.port);
175 return ERROR_COMMAND_SYNTAX_ERROR;
178 ret = target_read_u32(target, gpio_dat, &data);
180 if (ret == ERROR_OK) {
181 mask = 1 << gpio.num;
187 ret = target_write_u32(target, gpio_dat, data);
192 static int mg_hdrst(uint8_t level)
194 return mflash_bank->gpio_drv->set_gpio_output_val(mflash_bank->rst_pin, level);
197 static int mg_init_gpio(void)
200 struct mflash_gpio_drv *gpio_drv = mflash_bank->gpio_drv;
202 ret = gpio_drv->set_gpio_to_output(mflash_bank->rst_pin);
206 ret = gpio_drv->set_gpio_output_val(mflash_bank->rst_pin, 1);
211 static int mg_dsk_wait(mg_io_type_wait wait_local, uint32_t time_var)
213 uint8_t status, error;
214 struct target *target = mflash_bank->target;
215 uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
219 struct duration bench;
220 duration_start(&bench);
224 ret = target_read_u8(target, mg_task_reg + MG_REG_STATUS, &status);
228 if (status & mg_io_rbit_status_busy) {
229 if (wait_local == mg_io_wait_bsy)
232 switch (wait_local) {
233 case mg_io_wait_not_bsy:
235 case mg_io_wait_rdy_noerr:
236 if (status & mg_io_rbit_status_ready)
239 case mg_io_wait_drq_noerr:
240 if (status & mg_io_rbit_status_data_req)
247 /* Now we check the error condition! */
248 if (status & mg_io_rbit_status_error) {
249 ret = target_read_u8(target, mg_task_reg + MG_REG_ERROR, &error);
253 LOG_ERROR("mflash: io error 0x%02x", error);
258 switch (wait_local) {
260 if (status & mg_io_rbit_status_ready)
264 if (status & mg_io_rbit_status_data_req)
272 ret = duration_measure(&bench);
274 t = duration_elapsed(&bench) * 1000.0;
276 LOG_ERROR("mflash: duration measurement failed: %d", ret);
282 LOG_ERROR("mflash: timeout occured");
283 return ERROR_MG_TIMEOUT;
286 static int mg_dsk_srst(uint8_t on)
288 struct target *target = mflash_bank->target;
289 uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
293 ret = target_read_u8(target, mg_task_reg + MG_REG_DRV_CTRL, &value);
298 value |= (mg_io_rbit_devc_srst);
300 value &= ~mg_io_rbit_devc_srst;
302 ret = target_write_u8(target, mg_task_reg + MG_REG_DRV_CTRL, value);
306 static int mg_dsk_io_cmd(uint32_t sect_num, uint32_t cnt, uint8_t cmd)
308 struct target *target = mflash_bank->target;
309 uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
313 ret = mg_dsk_wait(mg_io_wait_rdy_noerr, MG_OEM_DISK_WAIT_TIME_NORMAL);
317 value = mg_io_rval_dev_drv_master | mg_io_rval_dev_lba_mode | ((sect_num >> 24) & 0xf);
319 ret = target_write_u8(target, mg_task_reg + MG_REG_DRV_HEAD, value);
320 ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_CNT, (uint8_t)cnt);
321 ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_NUM, (uint8_t)sect_num);
322 ret |= target_write_u8(target, mg_task_reg + MG_REG_CYL_LOW, (uint8_t)(sect_num >> 8));
323 ret |= target_write_u8(target, mg_task_reg + MG_REG_CYL_HIGH, (uint8_t)(sect_num >> 16));
328 return target_write_u8(target, mg_task_reg + MG_REG_COMMAND, cmd);
331 static int mg_dsk_drv_info(void)
333 struct target *target = mflash_bank->target;
334 uint32_t mg_buff = mflash_bank->base + MG_BUFFER_OFFSET;
337 ret = mg_dsk_io_cmd(0, 1, mg_io_cmd_identify);
341 ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
345 LOG_INFO("mflash: read drive info");
347 if (!mflash_bank->drv_info)
348 mflash_bank->drv_info = malloc(sizeof(struct mg_drv_info));
350 ret = target_read_memory(target, mg_buff, 2,
351 sizeof(mg_io_type_drv_info) >> 1,
352 (uint8_t *)&mflash_bank->drv_info->drv_id);
356 mflash_bank->drv_info->tot_sects =
357 (uint32_t)(mflash_bank->drv_info->drv_id.total_user_addressable_sectors_hi << 16)
358 + mflash_bank->drv_info->drv_id.total_user_addressable_sectors_lo;
360 return target_write_u8(target,
361 mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND,
362 mg_io_cmd_confirm_read);
365 static int mg_mflash_rst(void)
369 ret = mg_init_gpio();
377 ret = mg_dsk_wait(mg_io_wait_bsy, MG_OEM_DISK_WAIT_TIME_LONG);
385 ret = mg_dsk_wait(mg_io_wait_not_bsy, MG_OEM_DISK_WAIT_TIME_LONG);
389 ret = mg_dsk_srst(1);
393 ret = mg_dsk_wait(mg_io_wait_bsy, MG_OEM_DISK_WAIT_TIME_LONG);
397 ret = mg_dsk_srst(0);
401 ret = mg_dsk_wait(mg_io_wait_not_bsy, MG_OEM_DISK_WAIT_TIME_LONG);
405 LOG_INFO("mflash: reset ok");
410 static int mg_mflash_probe(void)
412 int ret = mg_mflash_rst();
416 return mg_dsk_drv_info();
419 COMMAND_HANDLER(mg_probe_cmd)
423 ret = mg_mflash_probe();
425 if (ret == ERROR_OK) {
426 command_print(CMD_CTX,
427 "mflash (total %" PRIu32 " sectors) found at 0x%8.8" PRIx32 "",
428 mflash_bank->drv_info->tot_sects,
435 static int mg_mflash_do_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
439 struct target *target = mflash_bank->target;
440 uint8_t *buff_ptr = buff;
442 ret = mg_dsk_io_cmd(sect_num, sect_cnt, mg_io_cmd_read);
446 address = mflash_bank->base + MG_BUFFER_OFFSET;
448 struct duration bench;
449 duration_start(&bench);
451 for (i = 0; i < sect_cnt; i++) {
452 ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
456 ret = target_read_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr);
460 buff_ptr += MG_MFLASH_SECTOR_SIZE;
462 ret = target_write_u8(target,
463 mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND,
464 mg_io_cmd_confirm_read);
468 LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector read", sect_num + i,
469 (sect_num + i) * MG_MFLASH_SECTOR_SIZE);
471 ret = duration_measure(&bench);
472 if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) {
473 LOG_INFO("mflash: read %" PRIu32 "'th sectors", sect_num + i);
474 duration_start(&bench);
478 return mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_NORMAL);
481 static int mg_mflash_read_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
483 uint32_t quotient, residue, i;
484 uint8_t *buff_ptr = buff;
487 quotient = sect_cnt >> 8;
488 residue = sect_cnt % 256;
490 for (i = 0; i < quotient; i++) {
491 LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p",
493 ret = mg_mflash_do_read_sects(buff_ptr, sect_num, 256);
498 buff_ptr += 256 * MG_MFLASH_SECTOR_SIZE;
502 LOG_DEBUG("mflash: sect num : %" PRIx32 " buff : %p",
504 return mg_mflash_do_read_sects(buff_ptr, sect_num, residue);
510 static int mg_mflash_do_write_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt,
515 struct target *target = mflash_bank->target;
516 uint8_t *buff_ptr = buff;
518 ret = mg_dsk_io_cmd(sect_num, sect_cnt, cmd);
522 address = mflash_bank->base + MG_BUFFER_OFFSET;
524 struct duration bench;
525 duration_start(&bench);
527 for (i = 0; i < sect_cnt; i++) {
528 ret = mg_dsk_wait(mg_io_wait_drq, MG_OEM_DISK_WAIT_TIME_NORMAL);
532 ret = target_write_memory(target, address, 2, MG_MFLASH_SECTOR_SIZE / 2, buff_ptr);
536 buff_ptr += MG_MFLASH_SECTOR_SIZE;
538 ret = target_write_u8(target,
539 mflash_bank->base + MG_REG_OFFSET + MG_REG_COMMAND,
540 mg_io_cmd_confirm_write);
544 LOG_DEBUG("mflash: %" PRIu32 " (0x%8.8" PRIx32 ") sector write", sect_num + i,
545 (sect_num + i) * MG_MFLASH_SECTOR_SIZE);
547 ret = duration_measure(&bench);
548 if ((ERROR_OK == ret) && (duration_elapsed(&bench) > 3)) {
549 LOG_INFO("mflash: wrote %" PRIu32 "'th sectors", sect_num + i);
550 duration_start(&bench);
554 if (cmd == mg_io_cmd_write)
555 ret = mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_NORMAL);
557 ret = mg_dsk_wait(mg_io_wait_rdy, MG_OEM_DISK_WAIT_TIME_LONG);
562 static int mg_mflash_write_sects(void *buff, uint32_t sect_num, uint32_t sect_cnt)
564 uint32_t quotient, residue, i;
565 uint8_t *buff_ptr = buff;
568 quotient = sect_cnt >> 8;
569 residue = sect_cnt % 256;
571 for (i = 0; i < quotient; i++) {
572 LOG_DEBUG("mflash: sect num : %" PRIu32 "buff : %p", sect_num,
574 ret = mg_mflash_do_write_sects(buff_ptr, sect_num, 256, mg_io_cmd_write);
579 buff_ptr += 256 * MG_MFLASH_SECTOR_SIZE;
583 LOG_DEBUG("mflash: sect num : %" PRIu32 " buff : %p", sect_num,
585 return mg_mflash_do_write_sects(buff_ptr, sect_num, residue, mg_io_cmd_write);
591 static int mg_mflash_read(uint32_t addr, uint8_t *buff, uint32_t len)
593 uint8_t *buff_ptr = buff;
594 uint8_t sect_buff[MG_MFLASH_SECTOR_SIZE];
595 uint32_t cur_addr, next_sec_addr, end_addr, cnt, sect_num;
600 end_addr = addr + len;
602 if (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK) {
604 next_sec_addr = (cur_addr + MG_MFLASH_SECTOR_SIZE) & ~MG_MFLASH_SECTOR_SIZE_MASK;
605 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
606 ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
610 if (end_addr < next_sec_addr) {
612 sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK),
613 end_addr - cur_addr);
615 "mflash: copies %" PRIu32 " byte from sector offset 0x%8.8" PRIx32 "",
621 sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK),
622 next_sec_addr - cur_addr);
624 "mflash: copies %" PRIu32 " byte from sector offset 0x%8.8" PRIx32 "",
625 next_sec_addr - cur_addr,
627 buff_ptr += (next_sec_addr - cur_addr);
628 cur_addr = next_sec_addr;
632 if (cur_addr < end_addr) {
634 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
635 next_sec_addr = cur_addr + MG_MFLASH_SECTOR_SIZE;
637 while (next_sec_addr <= end_addr) {
639 next_sec_addr += MG_MFLASH_SECTOR_SIZE;
643 ret = mg_mflash_read_sects(buff_ptr, sect_num, cnt);
648 buff_ptr += cnt * MG_MFLASH_SECTOR_SIZE;
649 cur_addr += cnt * MG_MFLASH_SECTOR_SIZE;
651 if (cur_addr < end_addr) {
653 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
654 ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
658 memcpy(buff_ptr, sect_buff, end_addr - cur_addr);
659 LOG_DEBUG("mflash: copies %u byte", (unsigned)(end_addr - cur_addr));
666 static int mg_mflash_write(uint32_t addr, uint8_t *buff, uint32_t len)
668 uint8_t *buff_ptr = buff;
669 uint8_t sect_buff[MG_MFLASH_SECTOR_SIZE];
670 uint32_t cur_addr, next_sec_addr, end_addr, cnt, sect_num;
675 end_addr = addr + len;
677 if (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK) {
679 next_sec_addr = (cur_addr + MG_MFLASH_SECTOR_SIZE) & ~MG_MFLASH_SECTOR_SIZE_MASK;
680 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
681 ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
685 if (end_addr < next_sec_addr) {
686 memcpy(sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK),
688 end_addr - cur_addr);
690 "mflash: copies %" PRIu32 " byte to sector offset 0x%8.8" PRIx32 "",
695 memcpy(sect_buff + (cur_addr & MG_MFLASH_SECTOR_SIZE_MASK),
697 next_sec_addr - cur_addr);
699 "mflash: copies %" PRIu32 " byte to sector offset 0x%8.8" PRIx32 "",
700 next_sec_addr - cur_addr,
702 buff_ptr += (next_sec_addr - cur_addr);
703 cur_addr = next_sec_addr;
706 ret = mg_mflash_write_sects(sect_buff, sect_num, 1);
711 if (cur_addr < end_addr) {
713 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
714 next_sec_addr = cur_addr + MG_MFLASH_SECTOR_SIZE;
716 while (next_sec_addr <= end_addr) {
718 next_sec_addr += MG_MFLASH_SECTOR_SIZE;
722 ret = mg_mflash_write_sects(buff_ptr, sect_num, cnt);
727 buff_ptr += cnt * MG_MFLASH_SECTOR_SIZE;
728 cur_addr += cnt * MG_MFLASH_SECTOR_SIZE;
730 if (cur_addr < end_addr) {
732 sect_num = cur_addr >> MG_MFLASH_SECTOR_SIZE_SHIFT;
733 ret = mg_mflash_read_sects(sect_buff, sect_num, 1);
737 memcpy(sect_buff, buff_ptr, end_addr - cur_addr);
738 LOG_DEBUG("mflash: copies %" PRIu32 " byte", end_addr - cur_addr);
739 ret = mg_mflash_write_sects(sect_buff, sect_num, 1);
746 COMMAND_HANDLER(mg_write_cmd)
748 uint32_t address, cnt, res, i;
750 struct fileio *fileio;
754 return ERROR_COMMAND_SYNTAX_ERROR;
756 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
758 ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_READ, FILEIO_BINARY);
763 buffer = malloc(MG_FILEIO_CHUNK);
765 fileio_close(fileio);
768 int retval = fileio_size(fileio, &filesize);
769 if (retval != ERROR_OK) {
770 fileio_close(fileio);
775 cnt = filesize / MG_FILEIO_CHUNK;
776 res = filesize % MG_FILEIO_CHUNK;
778 struct duration bench;
779 duration_start(&bench);
782 for (i = 0; i < cnt; i++) {
783 ret = fileio_read(fileio, MG_FILEIO_CHUNK, buffer, &buf_cnt);
785 goto mg_write_cmd_err;
786 ret = mg_mflash_write(address, buffer, MG_FILEIO_CHUNK);
788 goto mg_write_cmd_err;
789 address += MG_FILEIO_CHUNK;
793 ret = fileio_read(fileio, res, buffer, &buf_cnt);
795 goto mg_write_cmd_err;
796 ret = mg_mflash_write(address, buffer, res);
798 goto mg_write_cmd_err;
801 if (duration_measure(&bench) == ERROR_OK) {
802 command_print(CMD_CTX, "wrote %zu bytes from file %s "
803 "in %fs (%0.3f kB/s)", filesize, CMD_ARGV[1],
804 duration_elapsed(&bench), duration_kbps(&bench, filesize));
808 fileio_close(fileio);
814 fileio_close(fileio);
819 COMMAND_HANDLER(mg_dump_cmd)
821 uint32_t address, size, cnt, res, i;
823 struct fileio *fileio;
827 return ERROR_COMMAND_SYNTAX_ERROR;
829 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], address);
830 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[3], size);
832 ret = fileio_open(&fileio, CMD_ARGV[1], FILEIO_WRITE, FILEIO_BINARY);
836 buffer = malloc(MG_FILEIO_CHUNK);
838 fileio_close(fileio);
842 cnt = size / MG_FILEIO_CHUNK;
843 res = size % MG_FILEIO_CHUNK;
845 struct duration bench;
846 duration_start(&bench);
849 for (i = 0; i < cnt; i++) {
850 ret = mg_mflash_read(address, buffer, MG_FILEIO_CHUNK);
852 goto mg_dump_cmd_err;
853 ret = fileio_write(fileio, MG_FILEIO_CHUNK, buffer, &size_written);
855 goto mg_dump_cmd_err;
856 address += MG_FILEIO_CHUNK;
860 ret = mg_mflash_read(address, buffer, res);
862 goto mg_dump_cmd_err;
863 ret = fileio_write(fileio, res, buffer, &size_written);
865 goto mg_dump_cmd_err;
868 if (duration_measure(&bench) == ERROR_OK) {
869 command_print(CMD_CTX, "dump image (address 0x%8.8" PRIx32 " "
870 "size %" PRIu32 ") to file %s in %fs (%0.3f kB/s)",
871 address, size, CMD_ARGV[1],
872 duration_elapsed(&bench), duration_kbps(&bench, size));
876 fileio_close(fileio);
882 fileio_close(fileio);
887 static int mg_set_feature(mg_feature_id feature, mg_feature_val config)
889 struct target *target = mflash_bank->target;
890 uint32_t mg_task_reg = mflash_bank->base + MG_REG_OFFSET;
893 ret = mg_dsk_wait(mg_io_wait_rdy_noerr, MG_OEM_DISK_WAIT_TIME_NORMAL);
897 ret = target_write_u8(target, mg_task_reg + MG_REG_FEATURE, feature);
898 ret |= target_write_u8(target, mg_task_reg + MG_REG_SECT_CNT, config);
899 ret |= target_write_u8(target, mg_task_reg + MG_REG_COMMAND,
900 mg_io_cmd_set_feature);
905 static int mg_is_valid_pll(double XIN, int N, double CLK_OUT, int NO)
908 double v2 = CLK_OUT * NO;
910 if (v1 < 1000000 || v1 > 15000000 || v2 < 100000000 || v2 > 500000000)
911 return ERROR_MG_INVALID_PLL;
916 static int mg_pll_get_M(unsigned short feedback_div)
920 for (i = 1, M = 0; i < 512; i <<= 1, feedback_div >>= 1)
921 M += (feedback_div & 1) * i;
926 static int mg_pll_get_N(unsigned char input_div)
930 for (i = 1, N = 0; i < 32; i <<= 1, input_div >>= 1)
931 N += (input_div & 1) * i;
936 static int mg_pll_get_NO(unsigned char output_div)
940 for (i = 0, NO = 1; i < 2; ++i, output_div >>= 1)
947 static double mg_do_calc_pll(double XIN, mg_pll_t *p_pll_val, int is_approximate)
956 if (is_approximate) {
961 for (i = 0; i < MG_PLL_MAX_FEEDBACKDIV_VAL; ++i) {
964 for (j = 0; j < MG_PLL_MAX_INPUTDIV_VAL; ++j) {
967 for (k = 0; k < MG_PLL_MAX_OUTPUTDIV_VAL; ++k) {
968 NO = mg_pll_get_NO(k);
970 CLK_OUT = XIN * ((double)M / N) / NO;
972 if ((int)((CLK_OUT + ROUND) / DIV)
973 == (int)(MG_PLL_CLK_OUT / DIV)) {
974 if (mg_is_valid_pll(XIN, N, CLK_OUT, NO) == ERROR_OK) {
975 p_pll_val->lock_cyc =
976 (int)(XIN * MG_PLL_STD_LOCKCYCLE /
977 MG_PLL_STD_INPUTCLK);
978 p_pll_val->feedback_div = i;
979 p_pll_val->input_div = j;
980 p_pll_val->output_div = k;
992 static double mg_calc_pll(double XIN, mg_pll_t *p_pll_val)
996 CLK_OUT = mg_do_calc_pll(XIN, p_pll_val, 0);
999 return mg_do_calc_pll(XIN, p_pll_val, 1);
1004 static int mg_verify_interface(void)
1006 uint16_t buff[MG_MFLASH_SECTOR_SIZE >> 1];
1008 uint32_t address = mflash_bank->base + MG_BUFFER_OFFSET;
1009 struct target *target = mflash_bank->target;
1012 for (j = 0; j < 10; j++) {
1013 for (i = 0; i < MG_MFLASH_SECTOR_SIZE >> 1; i++)
1016 ret = target_write_memory(target, address, 2,
1017 MG_MFLASH_SECTOR_SIZE / 2, (uint8_t *)buff);
1018 if (ret != ERROR_OK)
1021 memset(buff, 0xff, MG_MFLASH_SECTOR_SIZE);
1023 ret = target_read_memory(target, address, 2,
1024 MG_MFLASH_SECTOR_SIZE / 2, (uint8_t *)buff);
1025 if (ret != ERROR_OK)
1028 for (i = 0; i < MG_MFLASH_SECTOR_SIZE >> 1; i++) {
1030 LOG_ERROR("mflash: verify interface fail");
1031 return ERROR_MG_INTERFACE;
1036 LOG_INFO("mflash: verify interface ok");
1040 static const char g_strSEG_SerialNum[20] = {
1041 'G', 'm', 'n', 'i', '-', 'e', 'e', 'S', 'g', 'a', 'e', 'l',
1042 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
1045 static const char g_strSEG_FWRev[8] = {
1046 'F', 'X', 'L', 'T', '2', 'v', '0', '.'
1049 static const char g_strSEG_ModelNum[40] = {
1050 'F', 'X', 'A', 'L', 'H', 'S', '2', 0x20, '0', '0', 's', '7',
1051 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1052 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
1053 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20
1056 static void mg_gen_ataid(mg_io_type_drv_info *pSegIdDrvInfo)
1058 /* b15 is ATA device(0) , b7 is Removable Media Device */
1059 pSegIdDrvInfo->general_configuration = 0x045A;
1060 /* 128MB : Cylinder=> 977 , Heads=> 8 , Sectors=> 32
1061 * 256MB : Cylinder=> 980 , Heads=> 16 , Sectors=> 32
1062 * 384MB : Cylinder=> 745 , Heads=> 16 , Sectors=> 63
1064 pSegIdDrvInfo->number_of_cylinders = 0x02E9;
1065 pSegIdDrvInfo->reserved1 = 0x0;
1066 pSegIdDrvInfo->number_of_heads = 0x10;
1067 pSegIdDrvInfo->unformatted_bytes_per_track = 0x0;
1068 pSegIdDrvInfo->unformatted_bytes_per_sector = 0x0;
1069 pSegIdDrvInfo->sectors_per_track = 0x3F;
1070 pSegIdDrvInfo->vendor_unique1[0] = 0x000B;
1071 pSegIdDrvInfo->vendor_unique1[1] = 0x7570;
1072 pSegIdDrvInfo->vendor_unique1[2] = 0x8888;
1074 memcpy(pSegIdDrvInfo->serial_number, g_strSEG_SerialNum, 20);
1075 /* 0x2 : dual buffer */
1076 pSegIdDrvInfo->buffer_type = 0x2;
1077 /* buffer size : 2KB */
1078 pSegIdDrvInfo->buffer_sector_size = 0x800;
1079 pSegIdDrvInfo->number_of_ecc_bytes = 0;
1081 memcpy(pSegIdDrvInfo->firmware_revision, g_strSEG_FWRev, 8);
1083 memcpy(pSegIdDrvInfo->model_number, g_strSEG_ModelNum, 40);
1085 pSegIdDrvInfo->maximum_block_transfer = 0x4;
1086 pSegIdDrvInfo->vendor_unique2 = 0x0;
1087 pSegIdDrvInfo->dword_io = 0x00;
1088 /* b11 : IORDY support(PIO Mode 4), b10 : Disable/Enbale IORDY
1089 * b9 : LBA support, b8 : DMA mode support
1091 pSegIdDrvInfo->capabilities = 0x1 << 9;
1093 pSegIdDrvInfo->reserved2 = 0x4000;
1094 pSegIdDrvInfo->vendor_unique3 = 0x00;
1095 /* PIOMode-2 support */
1096 pSegIdDrvInfo->pio_cycle_timing_mode = 0x02;
1097 pSegIdDrvInfo->vendor_unique4 = 0x00;
1098 /* MultiWord-2 support */
1099 pSegIdDrvInfo->dma_cycle_timing_mode = 0x00;
1100 /* b1 : word64~70 is valid
1101 * b0 : word54~58 are valid and reflect the current numofcyls,heads,sectors
1102 * b2 : If device supports Ultra DMA , set to one to vaildate word88
1104 pSegIdDrvInfo->translation_fields_valid = (0x1 << 1) | (0x1 << 0);
1105 pSegIdDrvInfo->number_of_current_cylinders = 0x02E9;
1106 pSegIdDrvInfo->number_of_current_heads = 0x10;
1107 pSegIdDrvInfo->current_sectors_per_track = 0x3F;
1108 pSegIdDrvInfo->current_sector_capacity_lo = 0x7570;
1109 pSegIdDrvInfo->current_sector_capacity_hi = 0x000B;
1111 pSegIdDrvInfo->multi_sector_count = 0x04;
1112 /* b8 : Multiple secotr setting valid , b[7:0] num of secotrs per block */
1113 pSegIdDrvInfo->multi_sector_setting_valid = 0x01;
1114 pSegIdDrvInfo->total_user_addressable_sectors_lo = 0x7570;
1115 pSegIdDrvInfo->total_user_addressable_sectors_hi = 0x000B;
1116 pSegIdDrvInfo->single_dma_modes_supported = 0x00;
1117 pSegIdDrvInfo->single_dma_transfer_active = 0x00;
1118 /* b2 :Multi-word DMA mode 2, b1 : Multi-word DMA mode 1 */
1119 pSegIdDrvInfo->multi_dma_modes_supported = (0x1 << 0);
1120 /* b2 :Multi-word DMA mode 2, b1 : Multi-word DMA mode 1 */
1121 pSegIdDrvInfo->multi_dma_transfer_active = (0x1 << 0);
1122 /* b0 : PIO Mode-3 support, b1 : PIO Mode-4 support */
1123 pSegIdDrvInfo->adv_pio_mode = 0x00;
1124 /* 480(0x1E0)nsec for Multi-word DMA mode0
1125 * 150(0x96) nsec for Multi-word DMA mode1
1126 * 120(0x78) nsec for Multi-word DMA mode2
1128 pSegIdDrvInfo->min_dma_cyc = 0x1E0;
1129 pSegIdDrvInfo->recommend_dma_cyc = 0x1E0;
1130 pSegIdDrvInfo->min_pio_cyc_no_iordy = 0x1E0;
1131 pSegIdDrvInfo->min_pio_cyc_with_iordy = 0x1E0;
1132 memset(pSegIdDrvInfo->reserved3, 0x00, 22);
1133 /* b7 : ATA/ATAPI-7 ,b6 : ATA/ATAPI-6 ,b5 : ATA/ATAPI-5,b4 : ATA/ATAPI-4 */
1134 pSegIdDrvInfo->major_ver_num = 0x7E;
1135 /* 0x1C : ATA/ATAPI-6 T13 1532D revision1 */
1136 pSegIdDrvInfo->minor_ver_num = 0x19;
1137 /* NOP/READ BUFFER/WRITE BUFFER/Power management feature set support */
1138 pSegIdDrvInfo->feature_cmd_set_suprt0 = 0x7068;
1139 /* Features/command set is valid/Advanced Pwr management/CFA feature set
1142 pSegIdDrvInfo->feature_cmd_set_suprt1 = 0x400C;
1143 pSegIdDrvInfo->feature_cmd_set_suprt2 = 0x4000;
1144 /* READ/WRITE BUFFER/PWR Management enable */
1145 pSegIdDrvInfo->feature_cmd_set_en0 = 0x7000;
1146 /* CFA feature is disabled / Advancde power management disable */
1147 pSegIdDrvInfo->feature_cmd_set_en1 = 0x0;
1148 pSegIdDrvInfo->feature_cmd_set_en2 = 0x4000;
1149 pSegIdDrvInfo->reserved4 = 0x0;
1150 /* 0x1 * 2minutes */
1151 pSegIdDrvInfo->req_time_for_security_er_done = 0x19;
1152 pSegIdDrvInfo->req_time_for_enhan_security_er_done = 0x19;
1153 /* Advanced power management level 1 */
1154 pSegIdDrvInfo->adv_pwr_mgm_lvl_val = 0x0;
1155 pSegIdDrvInfo->reserved5 = 0x0;
1156 memset(pSegIdDrvInfo->reserved6, 0x00, 68);
1157 /* Security mode feature is disabled */
1158 pSegIdDrvInfo->security_stas = 0x0;
1159 memset(pSegIdDrvInfo->vendor_uniq_bytes, 0x00, 62);
1160 /* CFA power mode 1 support in maximum 200mA */
1161 pSegIdDrvInfo->cfa_pwr_mode = 0x0100;
1162 memset(pSegIdDrvInfo->reserved7, 0x00, 190);
1165 static int mg_storage_config(void)
1170 ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd);
1171 if (ret != ERROR_OK)
1174 mg_gen_ataid((mg_io_type_drv_info *)(void *)buff);
1176 ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_update_stgdrvinfo);
1177 if (ret != ERROR_OK)
1180 ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default);
1181 if (ret != ERROR_OK)
1184 LOG_INFO("mflash: storage config ok");
1188 static int mg_boot_config(void)
1193 ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd);
1194 if (ret != ERROR_OK)
1197 memset(buff, 0xff, 512);
1199 buff[0] = mg_op_mode_snd; /* operation mode */
1200 buff[1] = MG_UNLOCK_OTP_AREA;
1201 buff[2] = 4; /* boot size */
1202 *((uint32_t *)(void *)(buff + 4)) = 0; /* XIP size */
1204 ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_update_xipinfo);
1205 if (ret != ERROR_OK)
1208 ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default);
1209 if (ret != ERROR_OK)
1212 LOG_INFO("mflash: boot config ok");
1216 static int mg_set_pll(mg_pll_t *pll)
1221 memset(buff, 0xff, 512);
1222 /* PLL Lock cycle and Feedback 9bit Divider */
1223 memcpy(buff, &pll->lock_cyc, sizeof(uint32_t));
1224 memcpy(buff + 4, &pll->feedback_div, sizeof(uint16_t));
1225 buff[6] = pll->input_div; /* PLL Input 5bit Divider */
1226 buff[7] = pll->output_div; /* PLL Output Divider */
1228 ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd);
1229 if (ret != ERROR_OK)
1232 ret = mg_mflash_do_write_sects(buff, 0, 1, mg_vcmd_wr_pll);
1233 if (ret != ERROR_OK)
1236 ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default);
1237 if (ret != ERROR_OK)
1240 LOG_INFO("mflash: set pll ok");
1244 static int mg_erase_nand(void)
1248 ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_vcmd);
1249 if (ret != ERROR_OK)
1252 ret = mg_mflash_do_write_sects(NULL, 0, 0, mg_vcmd_purge_nand);
1253 if (ret != ERROR_OK)
1256 ret = mg_set_feature(mg_feature_id_transmode, mg_feature_val_trans_default);
1257 if (ret != ERROR_OK)
1260 LOG_INFO("mflash: erase nand ok");
1264 COMMAND_HANDLER(mg_config_cmd)
1270 ret = mg_verify_interface();
1271 if (ret != ERROR_OK)
1274 ret = mg_mflash_rst();
1275 if (ret != ERROR_OK)
1280 if (!strcmp(CMD_ARGV[1], "boot"))
1281 return mg_boot_config();
1282 else if (!strcmp(CMD_ARGV[1], "storage"))
1283 return mg_storage_config();
1285 return ERROR_COMMAND_NOTFOUND;
1288 if (!strcmp(CMD_ARGV[1], "pll")) {
1290 COMMAND_PARSE_NUMBER(ulong, CMD_ARGV[2], freq);
1293 if (fin > MG_PLL_CLK_OUT) {
1294 LOG_ERROR("mflash: input freq. is too large");
1295 return ERROR_MG_INVALID_OSC;
1298 fout = mg_calc_pll(fin, &pll);
1301 LOG_ERROR("mflash: cannot generate valid pll");
1302 return ERROR_MG_INVALID_PLL;
1305 LOG_INFO("mflash: Fout=%" PRIu32 " Hz, feedback=%u,"
1306 "indiv=%u, outdiv=%u, lock=%u",
1307 (uint32_t)fout, pll.feedback_div,
1308 pll.input_div, pll.output_div,
1311 ret = mg_erase_nand();
1312 if (ret != ERROR_OK)
1315 return mg_set_pll(&pll);
1317 return ERROR_COMMAND_NOTFOUND;
1320 return ERROR_COMMAND_SYNTAX_ERROR;
1324 static const struct command_registration mflash_exec_command_handlers[] = {
1327 .handler = mg_probe_cmd,
1328 .mode = COMMAND_EXEC,
1329 .help = "Detect bank configuration information",
1333 .handler = mg_write_cmd,
1334 .mode = COMMAND_EXEC,
1335 /* FIXME bank_num is unused */
1336 .usage = "bank_num filename address",
1337 .help = "Write binary file at the specified address.",
1341 .handler = mg_dump_cmd,
1342 .mode = COMMAND_EXEC,
1343 /* FIXME bank_num is unused */
1344 .usage = "bank_num filename address size",
1345 .help = "Write specified number of bytes from a binary file "
1346 "to the specified, address.",
1350 .handler = mg_config_cmd,
1351 .mode = COMMAND_EXEC,
1352 .help = "Configure MFLASH options.",
1353 .usage = "('boot'|'storage'|'pll' frequency)",
1355 COMMAND_REGISTRATION_DONE
1358 static int mflash_init_drivers(struct command_context *cmd_ctx)
1362 return register_commands(cmd_ctx, NULL, mflash_exec_command_handlers);
1365 COMMAND_HANDLER(handle_mflash_init_command)
1368 return ERROR_COMMAND_SYNTAX_ERROR;
1370 static bool mflash_initialized;
1371 if (mflash_initialized) {
1372 LOG_INFO("'mflash init' has already been called");
1375 mflash_initialized = true;
1377 LOG_DEBUG("Initializing mflash devices...");
1378 return mflash_init_drivers(CMD_CTX);
1381 COMMAND_HANDLER(mg_bank_cmd)
1383 struct target *target;
1387 return ERROR_COMMAND_SYNTAX_ERROR;
1389 target = get_target(CMD_ARGV[3]);
1390 if (target == NULL) {
1391 LOG_ERROR("target '%s' not defined", CMD_ARGV[3]);
1395 mflash_bank = calloc(sizeof(struct mflash_bank), 1);
1396 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], mflash_bank->base);
1397 /** @todo Verify how this parsing should work, then document it. */
1399 mflash_bank->rst_pin.num = strtoul(CMD_ARGV[2], &str, 0);
1401 mflash_bank->rst_pin.port[0] = (uint16_t)
1402 tolower((unsigned)str[0]);
1404 mflash_bank->target = target;
1406 for (i = 0; mflash_gpio[i]; i++) {
1407 if (!strcmp(mflash_gpio[i]->name, CMD_ARGV[0]))
1408 mflash_bank->gpio_drv = mflash_gpio[i];
1411 if (!mflash_bank->gpio_drv) {
1412 LOG_ERROR("%s is unsupported soc", CMD_ARGV[0]);
1413 return ERROR_MG_UNSUPPORTED_SOC;
1419 static const struct command_registration mflash_config_command_handlers[] = {
1422 .handler = mg_bank_cmd,
1423 .mode = COMMAND_CONFIG,
1424 .help = "configure a mflash device bank",
1425 .usage = "soc_type base_addr pin_id target",
1429 .mode = COMMAND_CONFIG,
1430 .handler = handle_mflash_init_command,
1431 .help = "initialize mflash devices",
1434 COMMAND_REGISTRATION_DONE
1436 static const struct command_registration mflash_command_handler[] = {
1439 .mode = COMMAND_ANY,
1440 .help = "mflash command group",
1442 .chain = mflash_config_command_handlers,
1444 COMMAND_REGISTRATION_DONE
1446 int mflash_register_commands(struct command_context *cmd_ctx)
1448 return register_commands(cmd_ctx, NULL, mflash_command_handler);