Skip to content

Commit 0edb1dc

Browse files
committed
Progress with IFC Flash testing
1 parent 610af12 commit 0edb1dc

File tree

3 files changed

+55
-15
lines changed

3 files changed

+55
-15
lines changed

config/examples/nxp-t2080.config

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
11
# NXP T2080 wolfBoot Configuration Template
2-
#
3-
# Stock (default): Compact layout, NOR base 0xEFFE0000
4-
# NAII 68PPC2 (alternate): Larger app partition, NOR base 0xE8000000
5-
# Uncomment the "# NAII 68PPC2:" lines and comment the stock lines to use.
62

73
ARCH=PPC
84
TARGET=nxp_t2080
@@ -59,3 +55,6 @@ WOLFBOOT_DTS_BOOT_ADDRESS?=0xE8040000
5955
WOLFBOOT_DTS_UPDATE_ADDRESS?=0xE8050000
6056
# DTS Load to RAM Address
6157
WOLFBOOT_LOAD_DTS_ADDRESS?=0x200000
58+
59+
# Optional QSPI flash test (erase/write/read on update partition)
60+
#CFLAGS_EXTRA+=-DTEST_FLASH

hal/nxp_t2080.c

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -217,9 +217,10 @@ static void hal_flash_init(void)
217217
wolfBoot_printf("IFC CSPR0: 0x%x%s\n", cspr,
218218
(cspr & IFC_CSPR_WP) ? " (WP set)" : "");
219219
#endif
220-
if (cspr & IFC_CSPR_WP) {
221-
set32(IFC_CSPR(0), cspr & ~IFC_CSPR_WP);
222-
}
220+
/* WP clearing is done in hal_flash_clear_wp() from RAMFUNCTION code.
221+
* T2080RM requires V=0 before modifying IFC_CSPR, which is not safe
222+
* during XIP. The RAMFUNCTION code runs from DDR with flash TLB
223+
* guarded, so it can safely toggle V=0 -> modify -> V=1. */
223224

224225
/* Note: hal_flash_getid() is disabled because AMD Autoselect mode
225226
* affects the entire flash bank. Since wolfBoot runs XIP from the same
@@ -715,6 +716,25 @@ static void RAMFUNCTION hal_flash_cache_enable(void)
715716
invalidate_icache();
716717
}
717718

719+
/* Clear IFC write-protect. T2080RM says IFC_CSPR should only be written
720+
* when V=0. Must be called from RAMFUNCTION (DDR) with flash TLB set to
721+
* guarded (MAS2_G) so no speculative access occurs while V is briefly 0. */
722+
static void RAMFUNCTION hal_flash_clear_wp(void)
723+
{
724+
uint32_t cspr = get32(IFC_CSPR(0));
725+
if (cspr & IFC_CSPR_WP) {
726+
/* Clear V first, then modify WP, then re-enable V */
727+
set32(IFC_CSPR(0), cspr & ~(IFC_CSPR_WP | IFC_CSPR_V));
728+
__asm__ __volatile__("sync; isync");
729+
set32(IFC_CSPR(0), (cspr & ~IFC_CSPR_WP) | IFC_CSPR_V);
730+
__asm__ __volatile__("sync; isync");
731+
/* Verify WP cleared */
732+
cspr = get32(IFC_CSPR(0));
733+
wolfBoot_printf("WP clear: CSPR0=0x%x%s\n", cspr,
734+
(cspr & IFC_CSPR_WP) ? " (FAILED)" : " (OK)");
735+
}
736+
}
737+
718738
static void RAMFUNCTION hal_flash_unlock_sector(uint32_t sector)
719739
{
720740
/* AMD unlock sequence */
@@ -773,6 +793,12 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
773793

774794
/* Disable flash caching — AMD commands must reach the chip directly */
775795
hal_flash_cache_disable();
796+
hal_flash_clear_wp();
797+
798+
/* Reset flash to read-array mode in case previous operation left it
799+
* in command mode (e.g. after a timeout or incomplete operation) */
800+
FLASH_IO8_WRITE(0, 0, AMD_CMD_RESET);
801+
ram_udelay(50);
776802

777803
pos = 0;
778804
while (len > 0) {
@@ -792,18 +818,15 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
792818

793819
hal_flash_unlock_sector(sector);
794820
FLASH_IO8_WRITE(sector, offset, AMD_CMD_WRITE_TO_BUFFER);
795-
#if FLASH_CFI_WIDTH == 16
796-
FLASH_IO16_WRITE(sector, offset, (nwords-1));
797-
#else
821+
/* Word count (N-1) must be replicated to both chips */
798822
FLASH_IO8_WRITE(sector, offset, (nwords-1));
799-
#endif
800823

801824
for (i=0; i<nwords; i++) {
802825
const uint8_t* ptr = &data[pos];
803826
#if FLASH_CFI_WIDTH == 16
804-
FLASH_IO16_WRITE(sector, i, *((const uint16_t*)ptr));
827+
FLASH_IO16_WRITE(sector, offset + i, *((const uint16_t*)ptr));
805828
#else
806-
FLASH_IO8_WRITE(sector, i, *ptr);
829+
FLASH_IO8_WRITE(sector, offset + i, *ptr);
807830
#endif
808831
pos += (FLASH_CFI_WIDTH/8);
809832
}
@@ -814,6 +837,7 @@ int RAMFUNCTION hal_flash_write(uint32_t address, const uint8_t *data, int len)
814837
ret = hal_flash_status_wait(sector, 0x44, 200*1000);
815838
if (ret != 0) {
816839
wolfBoot_printf("Flash Write: Timeout at sector %d\n", sector);
840+
FLASH_IO8_WRITE(sector, 0, AMD_CMD_RESET);
817841
break;
818842
}
819843

@@ -837,6 +861,12 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
837861

838862
/* Disable flash caching — AMD commands must reach the chip directly */
839863
hal_flash_cache_disable();
864+
hal_flash_clear_wp();
865+
866+
/* Reset flash to read-array mode in case previous operation left it
867+
* in command mode (e.g. after a timeout or incomplete operation) */
868+
FLASH_IO8_WRITE(0, 0, AMD_CMD_RESET);
869+
ram_udelay(50);
840870

841871
while (len > 0) {
842872
/* determine sector address */
@@ -854,10 +884,21 @@ int RAMFUNCTION hal_flash_erase(uint32_t address, int len)
854884
/* block erase timeout = 50us - for additional sectors */
855885
/* Typical is 200ms (max 1100ms) */
856886

887+
/* Debug: check if flash entered erase mode (DQ6 should toggle) */
888+
{
889+
uint16_t r1 = FLASH_IO8_READ(sector, 0);
890+
uint16_t r2 = FLASH_IO8_READ(sector, 0);
891+
wolfBoot_printf("Erase cmd sent: read 0x%x, 0x%x %s\n",
892+
r1, r2, (r1 != r2) ? "(toggling)" : "(NOT toggling)");
893+
}
894+
857895
/* poll for erase completion - max 1.1 sec */
858896
ret = hal_flash_status_wait(sector, 0x4C, 1100*1000);
859897
if (ret != 0) {
860-
wolfBoot_printf("Flash Erase: Timeout at sector %d\n", sector);
898+
uint16_t r1 = FLASH_IO8_READ(sector, 0);
899+
wolfBoot_printf("Flash Erase: Timeout at sector %d (status 0x%x)\n",
900+
sector, r1);
901+
FLASH_IO8_WRITE(sector, 0, AMD_CMD_RESET);
861902
break;
862903
}
863904

hal/nxp_t2080.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ enum ifc_amask_sizes {
131131

132132
/* ---- NOR Flash ---- */
133133
#define FLASH_BANK_SIZE (128*1024*1024)
134-
#define FLASH_PAGE_SIZE (1024) /* program buffer */
134+
#define FLASH_PAGE_SIZE (512) /* program buffer (256 bytes per chip x 2 chips) */
135135
#define FLASH_SECTOR_SIZE (128*1024)
136136
#define FLASH_SECTORS (FLASH_BANK_SIZE / FLASH_SECTOR_SIZE)
137137
#define FLASH_CFI_WIDTH 16 /* 8 or 16 */

0 commit comments

Comments
 (0)