mirror of
https://github.com/apache/nuttx.git
synced 2026-06-07 17:33:08 +08:00
SAMA5 NAND: bugfixes
This commit is contained in:
@@ -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) */
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user