# HG changeset patch # User Mychaela Falconia # Date 1701584190 0 # Node ID ad3041e1988451fc2d51acf362d365aaaf1ea043 # Parent 84c9869a3659f0a7d7c9a4d49caf1fed9e5f3a29 fc-loadtool flash: implement PPB ops for Spansion PL-N diff -r 84c9869a3659 -r ad3041e19884 loadtools/flamdsec.c --- a/loadtools/flamdsec.c Sun Dec 03 04:58:50 2023 +0000 +++ b/loadtools/flamdsec.c Sun Dec 03 06:16:30 2023 +0000 @@ -10,6 +10,7 @@ #include #include #include +#include #include #include "flash.h" @@ -436,6 +437,68 @@ } /* + * Spansion PL-N PPB write functions, referenced from lock_info structures + * in fldevs.c device descriptions. + */ + +static +pln_ppb_write_op(oper_addr, write1, write2, expect_stat) + uint32_t oper_addr; + uint16_t write1, write2, expect_stat; +{ + int rc; + uint16_t read_stat, prev_stat; + time_t start_time, curtime; + + rc = pln_special_mode_entry(oper_addr, 0xC0); + if (rc < 0) + return(rc); + if (do_w16(oper_addr, write1)) { +bad_w16: fprintf(stderr, + "unexpected response to w16 in PPB command sequence - aborting\n"); + return(-1); + } + if (do_w16(oper_addr, write2)) + goto bad_w16; + printf("Polling for completion status\n"); + usleep(10000); /* make sure we don't get state before op starts */ + start_time = time(0); + rc = do_r16(oper_addr, &read_stat); + if (rc < 0) + return(rc); + for (;;) { + prev_stat = read_stat; + rc = do_r16(oper_addr, &read_stat); + if (rc < 0) + return(rc); + if (read_stat == expect_stat && prev_stat == expect_stat) + break; + curtime = time(0); + if (curtime >= start_time + 10) { + fprintf(stderr, "operation timeout, aborting\n"); + return(-1); + } + } + printf("Operation completed successfully\n"); + return pln_special_mode_exit(oper_addr); +} + +pln_ppb_program_one(bi, sector_addr) + struct flash_bank_info *bi; + uint32_t sector_addr; +{ + printf("Issuing PPB Program command\n"); + return pln_ppb_write_op(bi->base_addr + sector_addr, 0xA0, 0, 0); +} + +pln_ppb_erase_all(bi, raw_mode) + struct flash_bank_info *bi; +{ + printf("Issuing All PPB Erase command\n"); + return pln_ppb_write_op(bi->base_addr, 0x80, 0x30, 1); +} + +/* * Front end functions for PPB operation commands. */ diff -r 84c9869a3659 -r ad3041e19884 loadtools/fldevs.c --- a/loadtools/fldevs.c Sun Dec 03 04:58:50 2023 +0000 +++ b/loadtools/fldevs.c Sun Dec 03 06:16:30 2023 +0000 @@ -14,6 +14,9 @@ extern int plj_ppb_erase_all_single(); extern int plj_ppb_erase_all_dualbank(); +extern int pln_ppb_program_one(); +extern int pln_ppb_erase_all(); + /* flash bank geometries */ static struct flash_geom geom_2M_topboot = { @@ -556,6 +559,8 @@ {0x40000, 24, 0, 1, 1}}, .have_status_word_3 = 1, .have_pln_lock_reg = 1, + .ppb_program_one = pln_ppb_program_one, + .ppb_erase_all = pln_ppb_erase_all, }; static struct amd_lock_info PL129N_lock_info_1 = { @@ -565,6 +570,7 @@ {0x40000, 7, 0, 1, 0}, {0x10000, 4, 0, 0, 1}}, .have_status_word_3 = 1, + .ppb_program_one = pln_ppb_program_one, }; struct flash_device flashdev_PL129N = {