diff --git a/arch/arm/src/sama5/chip/sam_hsmc.h b/arch/arm/src/sama5/chip/sam_hsmc.h index d7ea2837bb2..cec7027ffdd 100644 --- a/arch/arm/src/sama5/chip/sam_hsmc.h +++ b/arch/arm/src/sama5/chip/sam_hsmc.h @@ -79,31 +79,31 @@ #define SAM_HSMC_PMECCIMR_OFFSET 0x0094 /* PMECC Interrupt Mask Register */ #define SAM_HSMC_PMECCISR_OFFSET 0x0098 /* PMECC Interrupt Status Register */ /* 0x009c-0x00ac Reserved */ -#define SAM_HSMC_PMECC_OFFSET(sec) (0x00b0+((sec) << 6)) /* PMECC sector offset */ -#define SAM_HSMC_PMECC0_OFFSET(sec) (0x00b0+((sec) << 6)) /* PMECC Redundancy 0 Register */ -#define SAM_HSMC_PMECC1_OFFSET(sec) (0x00b4+((sec) << 6)) /* PMECC Redundancy 1 Register */ -#define SAM_HSMC_PMECC2_OFFSET(sec) (0x00b8+((sec) << 6)) /* PMECC Redundancy 2 Register */ -#define SAM_HSMC_PMECC3_OFFSET(sec) (0x00bc+((sec) << 6)) /* PMECC Redundancy 3 Register */ -#define SAM_HSMC_PMECC4_OFFSET(sec) (0x00c0+((sec) << 6)) /* PMECC Redundancy 4 Register */ -#define SAM_HSMC_PMECC5_OFFSET(sec) (0x00c4+((sec) << 6)) /* PMECC Redundancy 5 Register */ -#define SAM_HSMC_PMECC6_OFFSET(sec) (0x00c8+((sec) << 6)) /* PMECC Redundancy 6 Register */ -#define SAM_HSMC_PMECC7_OFFSET(sec) (0x00cc+((sec) << 6)) /* PMECC Redundancy 7 Register */ -#define SAM_HSMC_PMECC8_OFFSET(sec) (0x00d0+((sec) << 6)) /* PMECC Redundancy 8 Register */ -#define SAM_HSMC_PMECC9_OFFSET(sec) (0x00d4+((sec) << 6)) /* PMECC Redundancy 9 Register */ -#define SAM_HSMC_PMECC10_OFFSET(sec) (0x00d8+((sec) << 6)) /* PMECC Redundancy 10 Register */ -#define SAM_HSMC_PEM_OFFSET(sec) (0x02b0+((sec) << 6)) /* PMECC Remainder offset */ -#define SAM_HSMC_REM0_OFFSET(sec) (0x02b0+((sec) << 6)) /* PMECC Remainder 0 Register */ -#define SAM_HSMC_REM1_OFFSET(sec) (0x02b4+((sec) << 6)) /* PMECC Remainder 1 Register */ -#define SAM_HSMC_REM2_OFFSET(sec) (0x02b8+((sec) << 6)) /* PMECC Remainder 2 Register */ -#define SAM_HSMC_REM3_OFFSET(sec) (0x02bc+((sec) << 6)) /* PMECC Remainder 3 Register */ -#define SAM_HSMC_REM4_OFFSET(sec) (0x02b0+((sec) << 6)) /* PMECC Remainder 4 Register */ -#define SAM_HSMC_REM5_OFFSET(sec) (0x02b4+((sec) << 6)) /* PMECC Remainder 5 Register */ -#define SAM_HSMC_REM6_OFFSET(sec) (0x02b8+((sec) << 6)) /* PMECC Remainder 6 Register */ -#define SAM_HSMC_REM7_OFFSET(sec) (0x02bc+((sec) << 6)) /* PMECC Remainder 7 Register */ -#define SAM_HSMC_REM8_OFFSET(sec) (0x02b0+((sec) << 6)) /* PMECC Remainder 8 Register */ -#define SAM_HSMC_REM9_OFFSET(sec) (0x02b4+((sec) << 6)) /* PMECC Remainder 9 Register */ -#define SAM_HSMC_REM10_OFFSET(sec) (0x02b8+((sec) << 6)) /* PMECC Remainder 10 Register */ -#define SAM_HSMC_REM11_OFFSET(sec) (0x02bc+((sec) << 6)) /* PMECC Remainder 11 Register */ +#define SAM_HSMC_PMECC_OFFSET(n) (0x00b0 + ((n) << 6)) /* PMECC sector offset */ +# define SAM_HSMC_PMECC0_OFFSET(n) (0x00b0 + ((n) << 6)) /* PMECC Redundancy 0 Register */ +# define SAM_HSMC_PMECC1_OFFSET(n) (0x00b4 + ((n) << 6)) /* PMECC Redundancy 1 Register */ +# define SAM_HSMC_PMECC2_OFFSET(n) (0x00b8 + ((n) << 6)) /* PMECC Redundancy 2 Register */ +# define SAM_HSMC_PMECC3_OFFSET(n) (0x00bc + ((n) << 6)) /* PMECC Redundancy 3 Register */ +# define SAM_HSMC_PMECC4_OFFSET(n) (0x00c0 + ((n) << 6)) /* PMECC Redundancy 4 Register */ +# define SAM_HSMC_PMECC5_OFFSET(n) (0x00c4 + ((n) << 6)) /* PMECC Redundancy 5 Register */ +# define SAM_HSMC_PMECC6_OFFSET(n) (0x00c8 + ((n) << 6)) /* PMECC Redundancy 6 Register */ +# define SAM_HSMC_PMECC7_OFFSET(n) (0x00cc + ((n) << 6)) /* PMECC Redundancy 7 Register */ +# define SAM_HSMC_PMECC8_OFFSET(n) (0x00d0 + ((n) << 6)) /* PMECC Redundancy 8 Register */ +# define SAM_HSMC_PMECC9_OFFSET(n) (0x00d4 + ((n) << 6)) /* PMECC Redundancy 9 Register */ +# define SAM_HSMC_PMECC10_OFFSET(n) (0x00d8 + ((n) << 6)) /* PMECC Redundancy 10 Register */ +#define SAM_HSMC_REM_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder offset */ +# define SAM_HSMC_REM0_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 0 Register */ +# define SAM_HSMC_REM1_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 1 Register */ +# define SAM_HSMC_REM2_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 2 Register */ +# define SAM_HSMC_REM3_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 3 Register */ +# define SAM_HSMC_REM4_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 4 Register */ +# define SAM_HSMC_REM5_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 5 Register */ +# define SAM_HSMC_REM6_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 6 Register */ +# define SAM_HSMC_REM7_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 7 Register */ +# define SAM_HSMC_REM8_OFFSET(n) (0x02b0 + ((n) << 6)) /* PMECC Remainder 8 Register */ +# define SAM_HSMC_REM9_OFFSET(n) (0x02b4 + ((n) << 6)) /* PMECC Remainder 9 Register */ +# define SAM_HSMC_REM10_OFFSET(n) (0x02b8 + ((n) << 6)) /* PMECC Remainder 10 Register */ +# define SAM_HSMC_REM11_OFFSET(n) (0x02bc + ((n) << 6)) /* PMECC Remainder 11 Register */ /* 0x04a0-0x04fc Reserved */ #define SAM_HSMC_ELCFG_OFFSET 0x0500 /* PMECC Error Location Configuration Register */ #define SAM_HSMC_ELPRIM_OFFSET 0x0504 /* PMECC Error Location Primitive Register */ @@ -115,7 +115,7 @@ #define SAM_HSMC_ELIMR_OFFSET 0x051c /* PMECC Error Location Interrupt Mask Register */ #define SAM_HSMC_ELISR_OFFSET 0x0520 /* PMECC Error Location Interrupt Status Register */ /* 0x0524-0x052c Reserved */ -#define SAM_HSMC_SIGMA_OFFSET(n) (0x0528+((n)<<2)) /* PMECC Error Location SIGMA n Register */ +#define SAM_HSMC_SIGMA_OFFSET(n) (0x0528 + ((n) << 2)) /* PMECC Error Location SIGMA n Register */ # define SAM_HSMC_SIGMA0_OFFSET 0x0528 /* PMECC Error Location SIGMA 0 Register */ # define SAM_HSMC_SIGMA1_OFFSET 0x052c /* PMECC Error Location SIGMA 1 Register */ # define SAM_HSMC_SIGMA2_OFFSET 0x0530 /* PMECC Error Location SIGMA 2 Register */ @@ -141,7 +141,7 @@ # define SAM_HSMC_SIGMA22_OFFSET 0x0580 /* PMECC Error Location SIGMA 22 Register */ # define SAM_HSMC_SIGMA23_OFFSET 0x0584 /* PMECC Error Location SIGMA 23 Register */ # define SAM_HSMC_SIGMA24_OFFSET 0x0588 /* PMECC Error Location SIGMA 24 Register */ -#define SAM_HSMC_ERRLOC_OFFSET(n) (0x058c+((n)<<2)) /* PMECC Error Location n Register */ +#define SAM_HSMC_ERRLOC_OFFSET(n) (0x058c + ((n) << 2)) /* PMECC Error Location n Register */ # define SAM_HSMC_ERRLOC0_OFFSET 0x058c /* PMECC Error Location 0 Register */ # define SAM_HSMC_ERRLOC1_OFFSET 0x0590 /* PMECC Error Location 1 Register */ # define SAM_HSMC_ERRLOC2_OFFSET 0x0594 /* PMECC Error Location 2 Register */ @@ -167,11 +167,11 @@ # define SAM_HSMC_ERRLOC22_OFFSET 0x05e4 /* PMECC Error Location 22 Register */ # define SAM_HSMC_ERRLOC23_OFFSET 0x05e8 /* PMECC Error Location 23 Register */ /* 0x05ec-0x05fc Reserved */ -#define SAM_HSMC_SETUP_OFFSET(cs) (0x0600+0x14*(cs)) /* HSMC Setup Register */ -#define SAM_HSMC_PULSE_OFFSET(cs) (0x0604+0x14*(cs)) /* HSMC Pulse Register */ -#define SAM_HSMC_CYCLE_OFFSET(cs) (0x0608+0x14*(cs)) /* HSMC Cycle Register */ -#define SAM_HSMC_TIMINGS_OFFSET(cs) (0x060c+0x14*(cs)) /* HSMC Timings Register */ -#define SAM_HSMC_MODE_OFFSET(cs) (0x0610+0x14*(cs)) /* HSMC Mode Register */ +#define SAM_HSMC_SETUP_OFFSET(n) (0x0600 + 0x14 * (n)) /* HSMC Setup Register */ +#define SAM_HSMC_PULSE_OFFSET(n) (0x0604 + 0x14 * (n)) /* HSMC Pulse Register */ +#define SAM_HSMC_CYCLE_OFFSET(n) (0x0608 + 0x14 * (n)) /* HSMC Cycle Register */ +#define SAM_HSMC_TIMINGS_OFFSET(n) (0x060c + 0x14 * (n)) /* HSMC Timings Register */ +#define SAM_HSMC_MODE_OFFSET(n) (0x0610 + 0x14 * (n)) /* HSMC Mode Register */ #define SAM_HSMC_OCMS_OFFSET 0x06a0 /* HSMC OCMS Register */ #define SAM_HSMC_KEY1_OFFSET 0x06a4 /* HSMC OCMS KEY1 Register */ #define SAM_HSMC_KEY2_OFFSET 0x06a8 /* HSMC OCMS KEY2 Register */ @@ -200,31 +200,31 @@ #define SAM_HSMC_PMECCIDR (SAM_HSMC_VBASE+SAM_HSMC_PMECCIDR_OFFSET) #define SAM_HSMC_PMECCIMR (SAM_HSMC_VBASE+SAM_HSMC_PMECCIMR_OFFSET) #define SAM_HSMC_PMECCISR (SAM_HSMC_VBASE+SAM_HSMC_PMECCISR_OFFSET) -#define SAM_HSMC_PMECC_BASE(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC_OFFSET(sec)) -# define SAM_HSMC_PMECC0(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC0_OFFSET(sec)) -# define SAM_HSMC_PMECC1(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC1_OFFSET(sec)) -# define SAM_HSMC_PMECC2(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC2_OFFSET(sec)) -# define SAM_HSMC_PMECC3(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC3_OFFSET(sec)) -# define SAM_HSMC_PMECC4(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC4_OFFSET(sec)) -# define SAM_HSMC_PMECC5(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC5_OFFSET(sec)) -# define SAM_HSMC_PMECC6(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC6_OFFSET(sec)) -# define SAM_HSMC_PMECC7(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC7_OFFSET(sec)) -# define SAM_HSMC_PMECC8(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC8_OFFSET(sec)) -# define SAM_HSMC_PMECC9(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC9_OFFSET(sec)) -# define SAM_HSMC_PMECC10(sec) (SAM_HSMC_VBASE+SAM_HSMC_PMECC10_OFFSET(sec)) -#define SAM_HSMC_REM_BASE(sec) (SAM_HSMC_VBASE+SAM_HSMC_PEM_OFFSET(sec)) -# define SAM_HSMC_REM0(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM0_OFFSET(sec)) -# define SAM_HSMC_REM1(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM1_OFFSET(sec)) -# define SAM_HSMC_REM2(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM2_OFFSET(sec)) -# define SAM_HSMC_REM3(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM3_OFFSET(sec)) -# define SAM_HSMC_REM4(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM4_OFFSET(sec)) -# define SAM_HSMC_REM5(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM5_OFFSET(sec)) -# define SAM_HSMC_REM6(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM6_OFFSET(sec)) -# define SAM_HSMC_REM7(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM7_OFFSET(sec)) -# define SAM_HSMC_REM8(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM8_OFFSET(sec)) -# define SAM_HSMC_REM9(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM9_OFFSET(sec)) -# define SAM_HSMC_REM10(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM10_OFFSET(sec)) -# define SAM_HSMC_REM11(sec) (SAM_HSMC_VBASE+SAM_HSMC_REM11_OFFSET(sec)) +#define SAM_HSMC_PMECC_BASE(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC_OFFSET(n)) +# define SAM_HSMC_PMECC0(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC0_OFFSET(n)) +# define SAM_HSMC_PMECC1(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC1_OFFSET(n)) +# define SAM_HSMC_PMECC2(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC2_OFFSET(n)) +# define SAM_HSMC_PMECC3(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC3_OFFSET(n)) +# define SAM_HSMC_PMECC4(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC4_OFFSET(n)) +# define SAM_HSMC_PMECC5(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC5_OFFSET(n)) +# define SAM_HSMC_PMECC6(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC6_OFFSET(n)) +# define SAM_HSMC_PMECC7(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC7_OFFSET(n)) +# define SAM_HSMC_PMECC8(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC8_OFFSET(n)) +# define SAM_HSMC_PMECC9(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC9_OFFSET(n)) +# define SAM_HSMC_PMECC10(n) (SAM_HSMC_VBASE+SAM_HSMC_PMECC10_OFFSET(n)) +#define SAM_HSMC_REM_BASE(n) (SAM_HSMC_VBASE+SAM_HSMC_REM_OFFSET(n)) +# define SAM_HSMC_REM0(n) (SAM_HSMC_VBASE+SAM_HSMC_REM0_OFFSET(n)) +# define SAM_HSMC_REM1(n) (SAM_HSMC_VBASE+SAM_HSMC_REM1_OFFSET(n)) +# define SAM_HSMC_REM2(n) (SAM_HSMC_VBASE+SAM_HSMC_REM2_OFFSET(n)) +# define SAM_HSMC_REM3(n) (SAM_HSMC_VBASE+SAM_HSMC_REM3_OFFSET(n)) +# define SAM_HSMC_REM4(n) (SAM_HSMC_VBASE+SAM_HSMC_REM4_OFFSET(n)) +# define SAM_HSMC_REM5(n) (SAM_HSMC_VBASE+SAM_HSMC_REM5_OFFSET(n)) +# define SAM_HSMC_REM6(n) (SAM_HSMC_VBASE+SAM_HSMC_REM6_OFFSET(n)) +# define SAM_HSMC_REM7(n) (SAM_HSMC_VBASE+SAM_HSMC_REM7_OFFSET(n)) +# define SAM_HSMC_REM8(n) (SAM_HSMC_VBASE+SAM_HSMC_REM8_OFFSET(n)) +# define SAM_HSMC_REM9(n) (SAM_HSMC_VBASE+SAM_HSMC_REM9_OFFSET(n)) +# define SAM_HSMC_REM10(n) (SAM_HSMC_VBASE+SAM_HSMC_REM10_OFFSET(n)) +# define SAM_HSMC_REM11(n) (SAM_HSMC_VBASE+SAM_HSMC_REM11_OFFSET(n)) #define SAM_HSMC_ELCFG (SAM_HSMC_VBASE+SAM_HSMC_ELCFG_OFFSET) #define SAM_HSMC_ELPRIM (SAM_HSMC_VBASE+SAM_HSMC_ELPRIM_OFFSET) #define SAM_HSMC_ELEN (SAM_HSMC_VBASE+SAM_HSMC_ELEN_OFFSET) @@ -285,11 +285,11 @@ # define SAM_HSMC_ERRLOC21 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC21_OFFSET) # define SAM_HSMC_ERRLOC22 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC22_OFFSET) # define SAM_HSMC_ERRLOC23 (SAM_HSMC_VBASE+SAM_HSMC_ERRLOC23_OFFSET) -#define SAM_HSMC_SETUP(cs) (SAM_HSMC_VBASE+SAM_HSMC_SETUP_OFFSET(cs)) -#define SAM_HSMC_PULSE(cs) (SAM_HSMC_VBASE+SAM_HSMC_PULSE_OFFSET(cs)) -#define SAM_HSMC_CYCLE(cs) (SAM_HSMC_VBASE+SAM_HSMC_CYCLE_OFFSET(cs)) -#define SAM_HSMC_TIMINGS(cs) (SAM_HSMC_VBASE+SAM_HSMC_TIMINGS_OFFSET(cs)) -#define SAM_HSMC_MODE(cs) (SAM_HSMC_VBASE+SAM_HSMC_MODE_OFFSET(cs)) +#define SAM_HSMC_SETUP(n) (SAM_HSMC_VBASE+SAM_HSMC_SETUP_OFFSET(n)) +#define SAM_HSMC_PULSE(n) (SAM_HSMC_VBASE+SAM_HSMC_PULSE_OFFSET(n)) +#define SAM_HSMC_CYCLE(n) (SAM_HSMC_VBASE+SAM_HSMC_CYCLE_OFFSET(n)) +#define SAM_HSMC_TIMINGS(n) (SAM_HSMC_VBASE+SAM_HSMC_TIMINGS_OFFSET(n)) +#define SAM_HSMC_MODE(n) (SAM_HSMC_VBASE+SAM_HSMC_MODE_OFFSET(n)) #define SAM_HSMC_OCMS (SAM_HSMC_VBASE+SAM_HSMC_OCMS_OFFSET) #define SAM_HSMC_KEY1 (SAM_HSMC_VBASE+SAM_HSMC_KEY1_OFFSET) #define SAM_HSMC_KEY2 (SAM_HSMC_VBASE+SAM_HSMC_KEY2_OFFSET) @@ -428,7 +428,7 @@ /* PMECC Interrupt Status Register */ -#define HSMC_PMECCISR_ERRIS(sec) (1 << (sec)) /* Bits 0-7: Error Interrupt Status */ +#define HSMC_PMECCISR_ERRIS(n) (1 << (n)) /* Bits 0-7: Error Interrupt Status */ /* PMECC Redundancy x Register (32-bit ECC value) */ diff --git a/arch/arm/src/sama5/sam_dmac.c b/arch/arm/src/sama5/sam_dmac.c index d6831210e48..da58c2971ce 100644 --- a/arch/arm/src/sama5/sam_dmac.c +++ b/arch/arm/src/sama5/sam_dmac.c @@ -58,6 +58,7 @@ #include "chip.h" #include "sam_dmac.h" #include "sam_periphclks.h" +#include "sam_memories.h" #include "chip/sam_pmc.h" #include "chip/sam_dmac.h" diff --git a/arch/arm/src/sama5/sam_nand.c b/arch/arm/src/sama5/sam_nand.c index 8227ba4d257..29c8fc38d30 100644 --- a/arch/arm/src/sama5/sam_nand.c +++ b/arch/arm/src/sama5/sam_nand.c @@ -220,7 +220,7 @@ static int nand_dma_write(struct sam_nandcs_s *priv, /* Raw Data Transfer Helpers */ static int nand_nfcsram_read(struct sam_nandcs_s *priv, - uint8_t *buffer, uint16_t buflen); + uint8_t *buffer, uint16_t buflen, uint16_t offset); #ifdef CONFIG_SAMA5_HAVE_PMECC static int nand_read(struct sam_nandcs_s *priv, uint8_t *buffer, uint16_t buflen); @@ -1466,13 +1466,18 @@ static int nand_dma_write(struct sam_nandcs_s *priv, ****************************************************************************/ static int nand_nfcsram_read(struct sam_nandcs_s *priv, uint8_t *buffer, - uint16_t buflen) + uint16_t buflen, uint16_t offset) { + uintptr_t src; int remaining; int ret; fvdbg("buffer=%p buflen=%d\n", buffer, buflen); + /* Get the offset data source address */ + + src = NFCSRAM_BASE + (uintptr_t)offset; + #ifdef CONFIG_SAMA5_NAND_DMA /* Then perform the transfer via memory-to-memory DMA or not, depending * on if we have a DMA channel assigned and if the transfer is @@ -1493,8 +1498,7 @@ static int nand_nfcsram_read(struct sam_nandcs_s *priv, uint8_t *buffer, /* Transfer using DMA */ - ret = nand_dma_read(priv, NFCSRAM_BASE, (uintptr_t)buffer, buflen, - dmaflags); + ret = nand_dma_read(priv, src, (uintptr_t)buffer, buflen, dmaflags); } else #endif @@ -1502,7 +1506,7 @@ static int nand_nfcsram_read(struct sam_nandcs_s *priv, uint8_t *buffer, /* Transfer without DMA */ { - uint8_t *src8 = (uint8_t *)NFCSRAM_BASE; + uint8_t *src8 = (uint8_t *)src; uint8_t *dest8 = buffer; for (remaining = buflen; remaining > 0; remaining--) @@ -1699,11 +1703,17 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block, nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DATA); +#if 0 /* Don't use NFC SRAM */ + nand_nfc_cleale(priv, + HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN | HSMC_CLE_VCMD2_EN | HSMC_CLE_DATA_EN, + COMMAND_READ_1, COMMAND_READ_2, 0, rowaddr); +#else nand_setup_rbedge(priv); nand_nfc_cleale(priv, HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN | HSMC_CLE_VCMD2_EN, COMMAND_READ_1, COMMAND_READ_2, 0, rowaddr); nand_wait_rbedge(priv); +#endif /* Reset the PMECC module */ @@ -1718,7 +1728,11 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block, * busy below would hang. */ +#if 0 /* Don't use NFC SRAM */ + ret = nand_nfcsram_read(priv, (uint8_t *)data, pagesize, 0); +#else ret = nand_read(priv, (uint8_t *)data, pagesize); +#endif if (ret < 0) { fdbg("ERROR: nand_read for data region failed: %d\n", ret); @@ -1727,7 +1741,11 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block, /* Now read the spare area into priv->raw.spare (sparesize bytes). */ +#if 0 /* Don't use NFC SRAM */ + ret = nand_nfcsram_read(priv, priv->raw.spare, sparesize, pagesize); +#else ret = nand_read(priv, priv->raw.spare, sparesize); +#endif if (ret < 0) { fdbg("ERROR: nand_read for spare region failed: %d\n", ret); @@ -1989,7 +2007,7 @@ static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block, if (data) { - ret = nand_nfcsram_read(priv, (uint8_t *)data, pagesize); + ret = nand_nfcsram_read(priv, (uint8_t *)data, pagesize, 0); if (ret < 0) { fdbg("ERROR: nand_nfcsram_read for data region failed: %d\n", ret); @@ -2004,7 +2022,7 @@ static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block, if (spare) { - ret = nand_nfcsram_read(priv, (uint8_t *)spare, sparesize); + ret = nand_nfcsram_read(priv, (uint8_t *)spare, sparesize, 0); if (ret < 0) { fdbg("ERROR: nand_nfcsram_read for spare region failed: %d\n", ret); @@ -2309,7 +2327,7 @@ static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block, #ifdef CONFIG_SAMA5_HAVE_PMECC static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, - unsigned int page, const void *data) + unsigned int page, const void *data) { uint32_t regval; volatile uint8_t *pmecc; @@ -2348,23 +2366,21 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, /* Calculate physical address of the page */ rowaddr = block * nandmodel_pagesperblock(&priv->raw.model) + page; - fvdbg("pagesize=%d eccsaddr=%d rowaddr=%d\n", pagesize, eccsaddr, rowaddr); - /* Write data area if needed */ +#if 1 /* Use NFC SRAM */ + /* Write the data area to NFC SRAM */ - if (data) + ret = nand_nfcsram_write(priv, (uint8_t *)data, pagesize, 0); + if (ret < 0) { - ret = nand_nfcsram_write(priv, (uint8_t *)data, pagesize, 0); - if (ret < 0) - { - fdbg("ERROR: Block %d page %d nand_nfcsram_write for data region failed: %d\n", - block, page, ret); - goto errout; - } + fdbg("ERROR: Block %d page %d nand_nfcsram_write for data region failed: %d\n", + block, page, ret); + goto errout; } +#endif - /* Get the number of sectors per page */ + /* Get the encoded number of sectors per page */ switch (pmecc_get_pagesize()) { @@ -2402,7 +2418,8 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, regval |= HSMC_PMECCFG_NANDWR_WRITE; nand_putreg(SAM_HSMC_PMECCFG, regval); - /* Configure the NFC */ +#if 1 /* Use NFC SRAM */ + /* Setup the NFC and wait for the transfer to complete */ nand_setup_xfrdone(priv); nand_nfc_cleale(priv, @@ -2410,16 +2427,34 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, HSMC_ALE_ROW_EN | HSMC_CLE_DATA_EN, COMMAND_WRITE_1, 0, 0, rowaddr); nand_wait_xfrdone(priv); +#else + /* Setup the for the data transfer */ nand_nfc_cleale(priv, - HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN, + HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN | HSMC_ALE_ROW_EN, + COMMAND_WRITE_1, 0, 0, rowaddr); + + /* Transfer the data via the NAND */ + + ret = nand_write(priv, (uint8_t *)data, pagesize, 0); + if (ret < 0) + { + fdbg("ERROR: Block %d page %d nand_write for data region failed: %d\n", + block, page, ret); + goto errout; + } +#endif + + /* Set up for the ECC transfer */ + + nand_nfc_cleale(priv, HSMC_CLE_WRITE_EN | HSMC_ALE_COL_EN, COMMAND_RANDOM_IN, 0, eccsaddr, 0); /* Wait until the kernel of the PMECC is not busy */ while ((nand_getreg(SAM_HSMC_PMECCSR) & HSMC_PMECCSR_BUSY) != 0); - /* Write the ECC */ + /* Get the ECC values from the PMECC */ eccpersector = (pmecc_get_eccsize()) / sectersperpage; eccsize = sectersperpage * eccpersector; @@ -2430,8 +2465,9 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, #ifdef CONFIG_SAMA5_PMECC_TRIMPAGE if (nand_trrimffs(priv) && page >= nand_get_trimpage(priv)) { - /* This behaviour was found to fix both UBI and JFFS2 images written to - * cleanly erased NAND partitions + /* Comments in the Atmel sample say that this behavior was found to + * fix both UBI and JFFS2 images written to cleanly erased NAND + * partitions */ memset(g_nand.ecctab, 0xff, eccsize); @@ -2455,6 +2491,8 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block, } } + /* Write the ECC to NAND */ + ret = nand_write(priv, (uint8_t *)g_nand.ecctab, eccsize, 0); if (ret < 0) { @@ -3017,20 +3055,14 @@ struct mtd_dev_s *sam_nand_initialize(int cs) return NULL; } +#ifdef CONFIG_SAMA5_NAND_DMA /* Allocate a DMA channel for NAND transfers. The channels will be - * configured as needed on-the-fly + * configured as needed on-the-fly. NOTE that no failure is declared + * if we fail to allocate DMA channel; in that case, only non-DMA + * transfers will be performed. */ -#ifdef CONFIG_SAMA5_NAND_DMA - if (nandmodel_getbuswidth(&priv->raw.model) == 16) - { - priv->dma = sam_dmachannel(NAND_DMAC, 0); - } - else - { - priv->dma = sam_dmachannel(NAND_DMAC, 0); - } - + priv->dma = sam_dmachannel(NAND_DMAC, 0); if (!priv->dma) { fdbg("ERROR: Failed to allocate the DMA channel for CS%d\n", cs);