SAMA5 NAND: Changes made durint testing (still does not work)
This commit is contained in:
parent
4483117a60
commit
0c3a0bfd3f
@ -788,8 +788,11 @@ endchoice # Base layer color format
|
||||
endif # SAMA5_LCDC_HCR
|
||||
|
||||
config SAMA5_LCDC_REGDEBUG
|
||||
bool "Low level register debug"
|
||||
bool "Register-Level Debug"
|
||||
default n
|
||||
depends on DEBUG
|
||||
---help---
|
||||
Enable very low-level register access debug. Depends on DEBUG.
|
||||
|
||||
endmenu # LCDC configuration
|
||||
endif # SAMA5_LCDC
|
||||
@ -3420,6 +3423,14 @@ config SAMA5_PMECC_GALOIS_CUSTOM
|
||||
by any NuttX logic.
|
||||
|
||||
endif # SAMA5_HAVE_PMECC
|
||||
|
||||
config SAMA5_NAND_REGDEBUG
|
||||
bool "Register-Level NAND Debug"
|
||||
default n
|
||||
depends on DEBUG
|
||||
---help---
|
||||
Enable very low-level register access debug. Depends on DEBUG.
|
||||
|
||||
endif # SAMA5_HAVE_NAND
|
||||
endmenu # External Memory Configuration
|
||||
|
||||
|
@ -339,15 +339,12 @@
|
||||
/* HSMC NFC Interrupt Mask Register */
|
||||
|
||||
#define HSMC_SR_SMCSTS (1 << 0) /* Bit 0: NAND Flash Controller Status (SR only) */
|
||||
|
||||
#define HSMC_NFCINT_RB_RISE (1 << 4) /* Bit 4: Ready Busy Rising Edge Detection Interrupt */
|
||||
#define HSMC_NFCINT_RB_FALL (1 << 5) /* Bit 5: Ready Busy Falling Edge Detection Interrupt */
|
||||
|
||||
#define HSMC_SR_NFCBUSY (1 << 8) /* Bit 8: NFC Busy (SR only) */
|
||||
#define HSMC_SR_NFCWR (1 << 11) /* Bit 11: NFC Write/Read Operation (SR only) */
|
||||
#define HSMC_SR_NFCSID_SHIFT (12) /* Bits 12-14: NFC Chip Select ID (SR only) */
|
||||
#define HSMC_SR_NFCSID_MASK (7 << HSMC_SR_NFCSID_SHIFT)
|
||||
|
||||
#define HSMC_NFCINT_XFRDONE (1 << 16) /* Bit 16: Transfer Done Interrupt */
|
||||
#define HSMC_NFCINT_CMDDONE (1 << 17) /* Bit 17: Command Done Interrupt */
|
||||
#define HSMC_NFCINT_DTOE (1 << 20) /* Bit 20: Data Timeout Error Interrupt Enable */
|
||||
@ -356,7 +353,7 @@
|
||||
#define HSMC_NFCINT_NFCASE (1 << 23) /* Bit 23: NFC Access Size Error Interrupt */
|
||||
#define HSMC_NFCINT_RBEDGE0 (1 << 24) /* Bit 24: Ready/Busy Line 0 Interrupt */
|
||||
|
||||
#define HSMC_NFCINT_ALL (0x01f300030)
|
||||
#define HSMC_NFCINT_ALL (0x01f30030)
|
||||
|
||||
/* HSMC NFC Address Cycle Zero Register */
|
||||
|
||||
@ -597,22 +594,24 @@
|
||||
#define NFCADDR_CMD_VCMD2 (1 << 18) /* Bit 18:Valid Cycle 2 Command */
|
||||
#define NFCADDR_CMD_ACYCLE_SHIFT (19) /* Bits 19-21: Number of Address required for command */
|
||||
#define NFCADDR_CMD_ACYCLE_MASK (7 << NFCADDR_CMD_ACYCLE_SHIFT)
|
||||
# define NFCADDR_CMD_ACYCLE_NONE (0 << NFCADDR_CMD_ACYCLE_SHIFT) /* No address cycle */
|
||||
# define NFCADDR_CMD_ACYCLE_ONE (1 << NFCADDR_CMD_ACYCLE_SHIFT) /* One address cycle */
|
||||
# define NFCADDR_CMD_ACYCLE_TWO (2 << NFCADDR_CMD_ACYCLE_SHIFT) /* Two address cycles */
|
||||
# define NFCADDR_CMD_ACYCLE_THREE (3 << NFCADDR_CMD_ACYCLE_SHIFT) /* Three address cycles */
|
||||
# define NFCADDR_CMD_ACYCLE_FOUR (4 << NFCADDR_CMD_ACYCLE_SHIFT) /* Four address cycles */
|
||||
# define NFCADDR_CMD_ACYCLE_FIVE (5 << NFCADDR_CMD_ACYCLE_SHIFT) /* Five address cycles */
|
||||
# define NFCADDR_CMD_ACYCLE(n) ((uint32_t)(n) << NFCADDR_CMD_ACYCLE_SHIFT) /* n address cycles, n=0-5 */
|
||||
# define NFCADDR_CMD_ACYCLE_NONE (0 << NFCADDR_CMD_ACYCLE_SHIFT) /* No address cycle */
|
||||
# define NFCADDR_CMD_ACYCLE_ONE (1 << NFCADDR_CMD_ACYCLE_SHIFT) /* One address cycle */
|
||||
# define NFCADDR_CMD_ACYCLE_TWO (2 << NFCADDR_CMD_ACYCLE_SHIFT) /* Two address cycles */
|
||||
# define NFCADDR_CMD_ACYCLE_THREE (3 << NFCADDR_CMD_ACYCLE_SHIFT) /* Three address cycles */
|
||||
# define NFCADDR_CMD_ACYCLE_FOUR (4 << NFCADDR_CMD_ACYCLE_SHIFT) /* Four address cycles */
|
||||
# define NFCADDR_CMD_ACYCLE_FIVE (5 << NFCADDR_CMD_ACYCLE_SHIFT) /* Five address cycles */
|
||||
#define NFCADDR_CMD_CSID_SHIFT (22) /* Bits 22-24: Chip Select Identifier */
|
||||
#define NFCADDR_CMD_CSID_MASK (7 << NFCADDR_CMD_CSID_SHIFT) /* Bits 22-24: Chip Select Identifier */
|
||||
# define NFCADDR_CMD_CSID_0 (0 << NFCADDR_CMD_CSID_SHIFT) /* CS0 */
|
||||
# define NFCADDR_CMD_CSID_1 (1 << NFCADDR_CMD_CSID_SHIFT) /* CS1 */
|
||||
# define NFCADDR_CMD_CSID_2 (2 << NFCADDR_CMD_CSID_SHIFT) /* CS2 */
|
||||
# define NFCADDR_CMD_CSID_3 (3 << NFCADDR_CMD_CSID_SHIFT) /* CS3 */
|
||||
# define NFCADDR_CMD_CSID_4 (4 << NFCADDR_CMD_CSID_SHIFT) /* CS4 */
|
||||
# define NFCADDR_CMD_CSID_5 (5 << NFCADDR_CMD_CSID_SHIFT) /* CS5 */
|
||||
# define NFCADDR_CMD_CSID_6 (6 << NFCADDR_CMD_CSID_SHIFT) /* CS6 */
|
||||
# define NFCADDR_CMD_CSID_7 (7 << NFCADDR_CMD_CSID_SHIFT) /* CS7 */
|
||||
#define NFCADDR_CMD_CSID_MASK (7 << NFCADDR_CMD_CSID_SHIFT)
|
||||
# define NFCADDR_CMD_CSID(n) ((uint32_t)(n) << NFCADDR_CMD_CSID_SHIFT) /* CSn, n=0-7 */
|
||||
# define NFCADDR_CMD_CSID_0 (0 << NFCADDR_CMD_CSID_SHIFT) /* CS0 */
|
||||
# define NFCADDR_CMD_CSID_1 (1 << NFCADDR_CMD_CSID_SHIFT) /* CS1 */
|
||||
# define NFCADDR_CMD_CSID_2 (2 << NFCADDR_CMD_CSID_SHIFT) /* CS2 */
|
||||
# define NFCADDR_CMD_CSID_3 (3 << NFCADDR_CMD_CSID_SHIFT) /* CS3 */
|
||||
# define NFCADDR_CMD_CSID_4 (4 << NFCADDR_CMD_CSID_SHIFT) /* CS4 */
|
||||
# define NFCADDR_CMD_CSID_5 (5 << NFCADDR_CMD_CSID_SHIFT) /* CS5 */
|
||||
# define NFCADDR_CMD_CSID_6 (6 << NFCADDR_CMD_CSID_SHIFT) /* CS6 */
|
||||
# define NFCADDR_CMD_CSID_7 (7 << NFCADDR_CMD_CSID_SHIFT) /* CS7 */
|
||||
#define NFCADDR_CMD_DATAEN (1 << 25) /* Bit 25: 1=NFC Data Enable */
|
||||
#define NFCADDR_CMD_DATADIS (0 << 25) /* Bit 25: 0=NFC Data disable */
|
||||
#define NFCADDR_CMD_NFCRD (0 << 26) /* Bit 26: 0=NFC Read Enable */
|
||||
|
@ -254,7 +254,6 @@
|
||||
|
||||
#define SAM_BOOTMEM_MMUFLAGS MMU_ROMFLAGS
|
||||
#define SAM_ROM_MMUFLAGS MMU_ROMFLAGS
|
||||
#define SAM_NFCSRAM_MMUFLAGS MMU_IOFLAGS
|
||||
#define SAM_ISRAM_MMUFLAGS MMU_MEMFLAGS
|
||||
#define SAM_SMD_MMUFLAGS MMU_MEMFLAGS
|
||||
#define SAM_UDPHSRAM_MMUFLAGS MMU_IOFLAGS
|
||||
@ -263,6 +262,17 @@
|
||||
#define SAM_AXIMX_MMUFLAGS MMU_IOFLAGS
|
||||
#define SAM_DAP_MMUFLAGS MMU_IOFLAGS
|
||||
|
||||
/* If the NFC is not being used, the NFC SRAM can be used as general purpose
|
||||
* SRAM (cached). If the NFC is used, then the NFC SRAM should be treated
|
||||
* as an I/O devices (uncached).
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_SAMA5_HAVE_NAND
|
||||
# define SAM_NFCSRAM_MMUFLAGS MMU_IOFLAGS
|
||||
#else
|
||||
# define SAM_NFCSRAM_MMUFLAGS MMU_MEMFLAGS
|
||||
#endif
|
||||
|
||||
/* SDRAM is a special case because it requires non-cached access of its
|
||||
* initial configuration, then caached access thereafter.
|
||||
*/
|
||||
|
@ -615,7 +615,7 @@ static void nand_nfc_configure(struct sam_nandcs_s *priv, uint8_t mode,
|
||||
acycle = NFCADDR_CMD_ACYCLE_NONE;
|
||||
}
|
||||
|
||||
cmd = (rw | regval | NFCADDR_CMD_CSID_3 | acycle |
|
||||
cmd = (rw | regval | NFCADDR_CMD_CSID(priv->cs) | acycle |
|
||||
(((mode & HSMC_CLE_VCMD2_EN) == HSMC_CLE_VCMD2_EN) ? NFCADDR_CMD_VCMD2 : 0) |
|
||||
(cmd1 << NFCADDR_CMD_CMD1_SHIFT) | (cmd2 << NFCADDR_CMD_CMD2_SHIFT));
|
||||
|
||||
@ -860,13 +860,17 @@ static void nand_setup_rbedge(struct sam_nandcs_s *priv)
|
||||
|
||||
static int hsmc_interrupt(int irq, void *context)
|
||||
{
|
||||
uint32_t status = nand_getreg(SAM_HSMC_SR);
|
||||
uint32_t sr = nand_getreg(SAM_HSMC_SR);
|
||||
uint32_t imr = nand_getreg(SAM_HSMC_IMR);
|
||||
uint32_t pending = sr & imr;
|
||||
|
||||
fllvdbg("sr=%08x imr=%08x pending=%08x\n", sr, imr, pending);
|
||||
|
||||
/* When set to one, this XFRDONE indicates that the NFC has terminated
|
||||
* the data transfer. This flag is reset after the status read.
|
||||
*/
|
||||
|
||||
if ((status & HSMC_NFCINT_XFRDONE) != 0)
|
||||
if ((pending & HSMC_NFCINT_XFRDONE) != 0)
|
||||
{
|
||||
g_nand.xfrdone = true;
|
||||
sem_post(&g_nand.waitsem);
|
||||
@ -876,7 +880,7 @@ static int hsmc_interrupt(int irq, void *context)
|
||||
* the Command. This flag is reset after the status read.
|
||||
*/
|
||||
|
||||
if ((status & HSMC_NFCINT_CMDDONE) != 0)
|
||||
if ((pending & HSMC_NFCINT_CMDDONE) != 0)
|
||||
{
|
||||
g_nand.cmddone = true;
|
||||
sem_post(&g_nand.waitsem);
|
||||
@ -888,7 +892,7 @@ static int hsmc_interrupt(int irq, void *context)
|
||||
* reset after the status read.
|
||||
*/
|
||||
|
||||
if ((status & HSMC_NFCINT_RBEDGE0) != 0)
|
||||
if ((pending & HSMC_NFCINT_RBEDGE0) != 0)
|
||||
{
|
||||
g_nand.rbedge = true;
|
||||
sem_post(&g_nand.waitsem);
|
||||
@ -1179,7 +1183,7 @@ static int nand_smc_read16(uintptr_t src, uint8_t *dest, size_t buflen)
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Name: nand_write
|
||||
* Name: nand_read
|
||||
*
|
||||
* Description:
|
||||
* Read data from NAND using the appropriate method
|
||||
@ -1271,8 +1275,9 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block,
|
||||
uint32_t regval;
|
||||
uint16_t pagesize;
|
||||
uint16_t sparesize;
|
||||
int ret;
|
||||
|
||||
fvdbg("Block %d Page %d\n", block, page);
|
||||
fvdbg("block=%d page=%d data=%p\n", (int)block, page, data);
|
||||
DEBUGASSERT(priv && data);
|
||||
|
||||
/* Get page and spare sizes */
|
||||
@ -1349,7 +1354,12 @@ static int nand_read_pmecc(struct sam_nandcs_s *priv, off_t block,
|
||||
nand_putreg(SAM_HSMC_PMECCFG, regval);
|
||||
|
||||
regval = nand_getreg(SAM_HSMC_PMECCEADDR);
|
||||
nand_read(priv, true, (uint8_t *)data, pagesize + (regval + 1));
|
||||
ret = nand_read(priv, true, (uint8_t *)data, pagesize + (regval + 1));
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: nand_read for data region failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Wait until the kernel of the PMECC is not busy */
|
||||
|
||||
@ -1544,8 +1554,9 @@ static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block,
|
||||
uint16_t sparesize;
|
||||
off_t rowaddr;
|
||||
off_t coladdr;
|
||||
int ret;
|
||||
|
||||
fvdbg("Block %d Page %d\n", (int)block, page);
|
||||
fvdbg("block=%d page=%d data=%p spare=%p\n", (int)block, page, data, spare);
|
||||
DEBUGASSERT(priv && (data || spare));
|
||||
|
||||
/* Get page and spare sizes */
|
||||
@ -1605,14 +1616,24 @@ static int nand_readpage_noecc(struct sam_nandcs_s *priv, off_t block,
|
||||
|
||||
if (data)
|
||||
{
|
||||
nand_read(priv, true, (uint8_t *)data, pagesize);
|
||||
ret = nand_read(priv, true, (uint8_t *)data, pagesize);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: nand_read for data region failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/* Read the spare are is so requested */
|
||||
|
||||
if (spare)
|
||||
{
|
||||
nand_read(priv, true, (uint8_t *)spare, sparesize);
|
||||
ret = nand_read(priv, true, (uint8_t *)spare, sparesize);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: nand_read for spare region failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -1647,18 +1668,22 @@ static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
||||
|
||||
DEBUGASSERT(priv && data);
|
||||
|
||||
/* Get exclusive access to the PMECC */
|
||||
/* Make sure that we have exclusive access to the PMECC and that the PMECC
|
||||
* is properly configured for this CS.
|
||||
*/
|
||||
|
||||
nand_lock();
|
||||
sparesize = nandmodel_getsparesize(&priv->raw.model);
|
||||
pmecc_lock();
|
||||
pmecc_configure(priv, 0, false);
|
||||
|
||||
/* Start by reading the spare data */
|
||||
|
||||
sparesize = nandmodel_getsparesize(&priv->raw.model);
|
||||
|
||||
ret = nand_read_pmecc(priv, block, page, data);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Failed to read page\n");
|
||||
return ret;
|
||||
goto errout;
|
||||
}
|
||||
|
||||
regval = nand_getreg(SAM_HSMC_PMECCISR);
|
||||
@ -1688,17 +1713,18 @@ static int nand_readpage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
||||
ret = pmecc_correction(regval, (uintptr_t)data);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Block %d page %d Unrecoverable data\n", block, page);
|
||||
fdbg("ERROR: block=%d page=%d Unrecoverable data\n", block, page);
|
||||
}
|
||||
|
||||
/* Disable the HSMC */
|
||||
/* Disable auto mode */
|
||||
|
||||
errout:
|
||||
regval = nand_getreg(SAM_HSMC_PMECCFG);
|
||||
regval &= ~HSMC_PMECCFG_AUTO_MASK;
|
||||
nand_putreg(SAM_HSMC_PMECCFG, regval);
|
||||
|
||||
nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DISABLE);
|
||||
nand_unlock();
|
||||
pmecc_unlock();
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_SAMA5_HAVE_PMECC */
|
||||
@ -1731,7 +1757,7 @@ static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block,
|
||||
off_t rowaddr;
|
||||
int ret = OK;
|
||||
|
||||
fvdbg("Block %d Page %d\n", block, page);
|
||||
fvdbg("block=%d page=%d data=%p spare=%p\n", (int)block, page, data, spare);
|
||||
|
||||
/* Get page and spare sizes */
|
||||
|
||||
@ -1789,11 +1815,21 @@ static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block,
|
||||
|
||||
if (data)
|
||||
{
|
||||
nand_write(priv, true, (uint8_t *)data, pagesize, 0);
|
||||
ret = nand_write(priv, true, (uint8_t *)data, pagesize, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: nand_write for data region failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (spare)
|
||||
{
|
||||
nand_write(priv, true, (uint8_t *)spare, sparesize, pagesize);
|
||||
ret = nand_write(priv, true, (uint8_t *)spare, sparesize, pagesize);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: nand_write for data region failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1832,7 +1868,7 @@ static int nand_writepage_noecc(struct sam_nandcs_s *priv, off_t block,
|
||||
ret = nand_write(priv, false, (uint8_t *)spare, sparesize, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: Failed writing data area\n");
|
||||
fdbg("ERROR: nand_write for spare region failed: %d\n", ret);
|
||||
ret = -EPERM;
|
||||
}
|
||||
|
||||
@ -1879,11 +1915,14 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
||||
int i;
|
||||
int ret = 0;
|
||||
|
||||
fvdbg("Block %d Page %d\n", block, page);
|
||||
fvdbg("block=%d page=%d data=%p\n", (int)block, page, data);
|
||||
|
||||
/* Get exclusive access to the PMECC */
|
||||
/* Make sure that we have exclusive access to the PMECC and that the PMECC
|
||||
* is properly configured for this CS.
|
||||
*/
|
||||
|
||||
nand_lock();
|
||||
pmecc_lock();
|
||||
pmecc_configure(priv, 0, false);
|
||||
|
||||
/* Calculate the start page address */
|
||||
|
||||
@ -1899,7 +1938,12 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
||||
|
||||
if (data)
|
||||
{
|
||||
nand_write(priv, true, (uint8_t *)data, pagesize, 0);
|
||||
ret = nand_write(priv, true, (uint8_t *)data, pagesize, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: nand_write for data region failed: %d\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the number of sectors per page */
|
||||
@ -2000,7 +2044,14 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
||||
}
|
||||
}
|
||||
|
||||
nand_write(priv, false, (uint8_t *)(uint8_t *)g_nand.ecctab, sectornumber * eccpersector, 0);
|
||||
ret = nand_write(priv, false, (uint8_t *)(uint8_t *)g_nand.ecctab,
|
||||
sectornumber * eccpersector, 0);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdbg("ERROR: nand_write for spare region failed: %d\n", ret);
|
||||
goto errout;
|
||||
}
|
||||
|
||||
nand_nfc_configure(priv, HSMC_CLE_WRITE_EN, COMMAND_WRITE_2, 0, 0, 0);
|
||||
nand_wait_ready(priv);
|
||||
|
||||
@ -2014,8 +2065,9 @@ static int nand_writepage_pmecc(struct sam_nandcs_s *priv, off_t block,
|
||||
|
||||
/* Disable the PMECC */
|
||||
|
||||
errout:
|
||||
nand_putreg(SAM_HSMC_PMECCTRL, HSMC_PMECCTRL_DISABLE);
|
||||
nand_unlock();
|
||||
pmecc_unlock();
|
||||
return ret;
|
||||
}
|
||||
#endif /* CONFIG_SAMA5_HAVE_PMECC */
|
||||
@ -2069,7 +2121,7 @@ static int nand_eraseblock(struct nand_raw_s *raw, off_t block)
|
||||
|
||||
DEBUGASSERT(priv);
|
||||
|
||||
fvdbg("Block %d\n", (int)block);
|
||||
fvdbg("block=%d\n", (int)block);
|
||||
|
||||
/* Get exclusvie access to the HSMC hardware.
|
||||
* REVISIT: The scope of this exclusivity is just NAND.
|
||||
|
Loading…
Reference in New Issue
Block a user