nandps_v2_2: Deprecated exiting version of nandps driver, Added new version.
Deprecated existing version v2_1, Added new version V2_2. Signed-off-by: Shakti Bhatnagar <shaktib@xilinx.com>
This commit is contained in:
parent
a84c7db3c2
commit
31c7177fc4
16 changed files with 6506 additions and 0 deletions
42
XilinxProcessorIPLib/drivers/nandps/data/nandps.mdd
Executable file
42
XilinxProcessorIPLib/drivers/nandps/data/nandps.mdd
Executable file
|
@ -0,0 +1,42 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# Use of the Software is limited solely to applications:
|
||||
# (a) running on a Xilinx device, or
|
||||
# (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
# in advertising or otherwise to promote the sale, use or other dealings in
|
||||
# this Software without prior written authorization from Xilinx.
|
||||
#
|
||||
###############################################################################
|
||||
OPTION psf_version = 2.1;
|
||||
|
||||
BEGIN driver nandps
|
||||
|
||||
OPTION supported_peripherals = (ps7_nand);
|
||||
OPTION driver_state = ACTIVE;
|
||||
OPTION copyfiles = all;
|
||||
OPTION VERSION = 2.2;
|
||||
OPTION NAME = nandps;
|
||||
|
||||
END driver
|
194
XilinxProcessorIPLib/drivers/nandps/data/nandps.tcl
Executable file
194
XilinxProcessorIPLib/drivers/nandps/data/nandps.tcl
Executable file
|
@ -0,0 +1,194 @@
|
|||
###############################################################################
|
||||
#
|
||||
# Copyright (C) 2012 - 2014 Xilinx, Inc. All rights reserved.
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
# of this software and associated documentation files (the "Software"), to deal
|
||||
# in the Software without restriction, including without limitation the rights
|
||||
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
# copies of the Software, and to permit persons to whom the Software is
|
||||
# furnished to do so, subject to the following conditions:
|
||||
#
|
||||
# The above copyright notice and this permission notice shall be included in
|
||||
# all copies or substantial portions of the Software.
|
||||
#
|
||||
# Use of the Software is limited solely to applications:
|
||||
# (a) running on a Xilinx device, or
|
||||
# (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
# XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
# OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
# SOFTWARE.
|
||||
#
|
||||
# Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
# in advertising or otherwise to promote the sale, use or other dealings in
|
||||
# this Software without prior written authorization from Xilinx.
|
||||
#
|
||||
###############################################################################
|
||||
##############################################################################
|
||||
#
|
||||
# Modification History
|
||||
#
|
||||
# Ver Who Date Changes
|
||||
# ----- ---- -------- -----------------------------------------------
|
||||
# 1.00a sdm 11/22/11 Created
|
||||
# 2.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
#
|
||||
##############################################################################
|
||||
|
||||
#uses "xillib.tcl"
|
||||
|
||||
proc generate {drv_handle} {
|
||||
xdefine_zynq_include_file $drv_handle "xparameters.h" "XNandPs" "NUM_INSTANCES" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_NAND_CLK_FREQ_HZ" "C_SMC_BASEADDR" "C_NAND_WIDTH"
|
||||
|
||||
xdefine_zynq_config_file $drv_handle "xnandps_g.c" "XNandPs" "DEVICE_ID" "C_SMC_BASEADDR" "C_S_AXI_BASEADDR" "C_NAND_WIDTH"
|
||||
|
||||
xdefine_zynq_canonical_xpars $drv_handle "xparameters.h" "XNandPs" "DEVICE_ID" "C_S_AXI_BASEADDR" "C_S_AXI_HIGHADDR" "C_NAND_CLK_FREQ_HZ" "C_SMC_BASEADDR" "C_NAND_WIDTH"
|
||||
|
||||
}
|
||||
|
||||
|
||||
#
|
||||
# Given a list of arguments, define them all in an include file.
|
||||
# Similar to proc xdefine_include_file, except that uses regsub
|
||||
# to replace "S_AXI_" with "".
|
||||
#
|
||||
proc xdefine_zynq_include_file {drv_handle file_name drv_string args} {
|
||||
# Open include file
|
||||
set file_handle [::hsi::utils::open_include_file $file_name]
|
||||
|
||||
# Get all peripherals connected to this driver
|
||||
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
|
||||
|
||||
# Handle special cases
|
||||
set arg "NUM_INSTANCES"
|
||||
set posn [lsearch -exact $args $arg]
|
||||
if {$posn > -1} {
|
||||
puts $file_handle "/* Definitions for driver [string toupper [common::get_property NAME $drv_handle]] */"
|
||||
# Define NUM_INSTANCES
|
||||
puts $file_handle "#define [::hsi::utils::get_driver_param_name $drv_string $arg] [llength $periphs]"
|
||||
set args [lreplace $args $posn $posn]
|
||||
}
|
||||
# Check if it is a driver parameter
|
||||
|
||||
lappend newargs
|
||||
foreach arg $args {
|
||||
set value [common::get_property CONFIG.$arg $drv_handle]
|
||||
if {[llength $value] == 0} {
|
||||
lappend newargs $arg
|
||||
} else {
|
||||
puts $file_handle "#define [::hsi::utils::get_driver_param_name $drv_string $arg] [common::get_property CONFIG.$arg $drv_handle]"
|
||||
}
|
||||
}
|
||||
set args $newargs
|
||||
|
||||
# Print all parameters for all peripherals
|
||||
set device_id 0
|
||||
foreach periph $periphs {
|
||||
puts $file_handle ""
|
||||
puts $file_handle "/* Definitions for peripheral [string toupper [common::get_property NAME $periph]] */"
|
||||
foreach arg $args {
|
||||
if {[string compare -nocase "DEVICE_ID" $arg] == 0} {
|
||||
set value $device_id
|
||||
incr device_id
|
||||
} elseif {[string compare -nocase "C_SMC_BASEADDR" $arg] == 0} {
|
||||
set value 0xE000E000
|
||||
} else {
|
||||
set value [::hsi::utils::get_param_value $periph $arg]
|
||||
}
|
||||
if {[llength $value] == 0} {
|
||||
set value 0
|
||||
}
|
||||
set value [::hsi::utils::format_addr_string $value $arg]
|
||||
set arg_name [::hsi::utils::get_ip_param_name $periph $arg]
|
||||
regsub "S_AXI_" $arg_name "" arg_name
|
||||
if {[string compare -nocase "HW_VER" $arg] == 0} {
|
||||
puts $file_handle "#define $arg_name \"$value\""
|
||||
} else {
|
||||
puts $file_handle "#define $arg_name $value"
|
||||
}
|
||||
}
|
||||
puts $file_handle ""
|
||||
}
|
||||
puts $file_handle "\n/******************************************************************/\n"
|
||||
close $file_handle
|
||||
}
|
||||
|
||||
#-----------------------------------------------------------------------------
|
||||
# xdefine_zynq_canonical_xpars - Used to print out canonical defines for a driver.
|
||||
# Similar to proc xdefine_config_file, except that uses regsub to replace "S_AXI_"
|
||||
# with "".
|
||||
#-----------------------------------------------------------------------------
|
||||
proc xdefine_zynq_canonical_xpars {drv_handle file_name drv_string args} {
|
||||
# Open include file
|
||||
set file_handle [::hsi::utils::open_include_file $file_name]
|
||||
|
||||
# Get all the peripherals connected to this driver
|
||||
set periphs [::hsi::utils::get_common_driver_ips $drv_handle]
|
||||
|
||||
# Get the names of all the peripherals connected to this driver
|
||||
foreach periph $periphs {
|
||||
set peripheral_name [string toupper [common::get_property NAME $periph]]
|
||||
lappend peripherals $peripheral_name
|
||||
}
|
||||
|
||||
# Get possible canonical names for all the peripherals connected to this
|
||||
# driver
|
||||
set device_id 0
|
||||
foreach periph $periphs {
|
||||
set canonical_name [string toupper [format "%s_%s" $drv_string $device_id]]
|
||||
lappend canonicals $canonical_name
|
||||
|
||||
# Create a list of IDs of the peripherals whose hardware instance name
|
||||
# doesn't match the canonical name. These IDs can be used later to
|
||||
# generate canonical definitions
|
||||
if { [lsearch $peripherals $canonical_name] < 0 } {
|
||||
lappend indices $device_id
|
||||
}
|
||||
incr device_id
|
||||
}
|
||||
|
||||
set i 0
|
||||
foreach periph $periphs {
|
||||
set periph_name [string toupper [common::get_property NAME $periph]]
|
||||
|
||||
# Generate canonical definitions only for the peripherals whose
|
||||
# canonical name is not the same as hardware instance name
|
||||
if { [lsearch $canonicals $periph_name] < 0 } {
|
||||
puts $file_handle "/* Canonical definitions for peripheral $periph_name */"
|
||||
set canonical_name [format "%s_%s" $drv_string [lindex $indices $i]]
|
||||
|
||||
foreach arg $args {
|
||||
set lvalue [::hsi::utils::get_driver_param_name $canonical_name $arg]
|
||||
# replace S_SXI_ with CPU_. This is a temporary fix. Revist when the
|
||||
# S_AXI_DIST_BASEADDR is generated by the tools
|
||||
regsub "S_AXI_" $lvalue "CPU_" lvalue
|
||||
|
||||
# The commented out rvalue is the name of the instance-specific constant
|
||||
# set rvalue [::hsi::utils::get_ip_param_name $periph $arg]
|
||||
# The rvalue set below is the actual value of the parameter
|
||||
if {[string compare -nocase "C_SMC_BASEADDR" $arg] == 0} {
|
||||
set rvalue 0xE000E000
|
||||
} else {
|
||||
set rvalue [::hsi::utils::get_param_value $periph $arg]
|
||||
}
|
||||
if {[llength $rvalue] == 0} {
|
||||
set rvalue 0
|
||||
}
|
||||
set rvalue [::hsi::utils::format_addr_string $rvalue $arg]
|
||||
|
||||
puts $file_handle "#define $lvalue $rvalue"
|
||||
|
||||
}
|
||||
puts $file_handle ""
|
||||
incr i
|
||||
}
|
||||
}
|
||||
|
||||
puts $file_handle "\n/******************************************************************/\n"
|
||||
close $file_handle
|
||||
}
|
19
XilinxProcessorIPLib/drivers/nandps/examples/index.html
Executable file
19
XilinxProcessorIPLib/drivers/nandps/examples/index.html
Executable file
|
@ -0,0 +1,19 @@
|
|||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
|
||||
<html>
|
||||
<head>
|
||||
<meta http-equiv="Content-Language" content="en-us">
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
|
||||
<title>Driver example applications</title>
|
||||
<link rel="stylesheet" type="text/css" href="../help.css">
|
||||
</head>
|
||||
<body bgcolor="#FFFFFF">
|
||||
<h1> Example Applications for the driver nandps_v2_1</h1>
|
||||
<HR>
|
||||
<ul>
|
||||
<li>xnandps_example.c <a href="xnandps_example.c">(source)</a> </li>
|
||||
<li>xnandps_skip_example.c <a href="xnandps_skip_example.c">(source)</a> </li>
|
||||
<li>xnandps_cache_example.c <a href="xnandps_cache_example.c">(source)</a> </li>
|
||||
</ul>
|
||||
<p><font face="Times New Roman" color="#800000">Copyright <20> 2009-2014 Xilinx, Inc. All rights reserved.</font></p>
|
||||
</body>
|
||||
</html>
|
258
XilinxProcessorIPLib/drivers/nandps/examples/xnandps_cache_example.c
Executable file
258
XilinxProcessorIPLib/drivers/nandps/examples/xnandps_cache_example.c
Executable file
|
@ -0,0 +1,258 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2013 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* @file xnandps_cache_example.c
|
||||
**
|
||||
* This file contains a design example using the NAND driver (XNandPs).
|
||||
* This example tests NAND page cache read and write commands. The page cache
|
||||
* commands are not supported by OnDie ECC flash since ECC is enabled by
|
||||
* default. Tested Spansion S34ML04G100TFI00 flash with this example.
|
||||
*
|
||||
* This example tests the block erase, block read and block write features.
|
||||
* The flash blocks are erased and written. The data is read back and compared
|
||||
* with the data written for correctness. The bad blocks are not erased/programmed.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00 nm 04/25/2013 First release.
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <xil_types.h>
|
||||
#include <xil_printf.h>
|
||||
#include <xparameters.h>
|
||||
#include <xnandps.h>
|
||||
#include <xnandps_bbm.h>
|
||||
/************************** Constant Definitions *****************************/
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define NAND_DEVICE_ID XPAR_XNANDPS_0_DEVICE_ID
|
||||
/* Test parameters */
|
||||
#define NAND_TEST_START_BLOCK 64 /**< Starting block to test */
|
||||
#define NAND_TEST_NUM_BLOCKS 16 /**< Number of blocks to test */
|
||||
#define NAND_TEST_BLOCK_SIZE 0x20000 /**< Test Block Size, must be same as
|
||||
the flash block size */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int NandReadWriteCacheExample(u32 NandDeviceId);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
XNandPs NandInstance; /* XNand Instance. */
|
||||
XNandPs *NandInstPtr = &NandInstance;
|
||||
/*
|
||||
* Buffers used during read and write transactions.
|
||||
*/
|
||||
u8 ReadBuffer[NAND_TEST_BLOCK_SIZE]; /**< Block sized Read buffer */
|
||||
u8 WriteBuffer[NAND_TEST_BLOCK_SIZE]; /**< Block sized write buffer */
|
||||
/************************** Function Definitions ******************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to execute the Nand Flash read write example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if the example has completed successfully.
|
||||
* - XST_FAILURE if the example has failed.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("Nand Flash Read Write Example Test\r\n");
|
||||
/*
|
||||
* Run the NAND read write example, specify the Base Address that
|
||||
* is generated in xparameters.h .
|
||||
*/
|
||||
Status = NandReadWriteCacheExample(NAND_DEVICE_ID);
|
||||
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("Nand Flash Read Write Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran Nand Flash Read Write Example Test\r\n");
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function runs a test on the NAND flash device using the basic driver
|
||||
* functions.
|
||||
* The function does the following tasks:
|
||||
* - Initialize the driver.
|
||||
* - Erase the blocks.
|
||||
* - Write in to all the blocks.
|
||||
* - Read back the data from the blocks.
|
||||
* - Compare the data read against the data Written.
|
||||
*
|
||||
* @param NandDeviceId is is the XPAR_<NAND_instance>_DEVICE_ID value
|
||||
* from xparameters.h.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if failed.
|
||||
*
|
||||
* @note When bad blocks are encountered, they are not erased and
|
||||
* programmed.
|
||||
*
|
||||
****************************************************************************/
|
||||
int NandReadWriteCacheExample(u32 NandDeviceId)
|
||||
{
|
||||
int Status;
|
||||
u32 Index;
|
||||
u32 BlockIndex;
|
||||
XNandPs_Config *ConfigPtr;
|
||||
u64 Offset;
|
||||
u32 Length;
|
||||
u32 StartBlock;
|
||||
u32 EndBlock;
|
||||
|
||||
/*
|
||||
* Initialize the flash driver.
|
||||
*/
|
||||
ConfigPtr = XNandPs_LookupConfig(NandDeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XNandPs_CfgInitialize(NandInstPtr, ConfigPtr,
|
||||
ConfigPtr->SmcBase,ConfigPtr->FlashBase);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
StartBlock = NAND_TEST_START_BLOCK;
|
||||
EndBlock = NAND_TEST_START_BLOCK + NAND_TEST_NUM_BLOCKS;
|
||||
Length = NAND_TEST_BLOCK_SIZE;
|
||||
/*
|
||||
* Prepare the write buffer. Fill in the data need to be written into
|
||||
* Flash Device.
|
||||
*/
|
||||
for (Index = 0; Index < Length; Index++) {
|
||||
WriteBuffer[Index] = Index % 256;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase the blocks in the flash
|
||||
*/
|
||||
for (BlockIndex = StartBlock; BlockIndex < EndBlock; BlockIndex++) {
|
||||
/*
|
||||
* Don't erase bad blocks.
|
||||
*/
|
||||
if (XNandPs_IsBlockBad(NandInstPtr, BlockIndex) == XST_SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Perform erase operation.
|
||||
*/
|
||||
Status = XNandPs_EraseBlock(NandInstPtr, BlockIndex);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the read/write operation
|
||||
*/
|
||||
for (BlockIndex = StartBlock; BlockIndex < EndBlock; BlockIndex++) {
|
||||
/*
|
||||
* Don't program bad blocks.
|
||||
*/
|
||||
if (XNandPs_IsBlockBad(NandInstPtr, BlockIndex) == XST_SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Offset = BlockIndex * NandInstPtr->Geometry.BlockSize;
|
||||
|
||||
/*
|
||||
* Perform the write operation.
|
||||
*/
|
||||
Status = XNandPs_WriteCache(NandInstPtr, Offset, Length, WriteBuffer, NULL);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the read operation.
|
||||
*/
|
||||
Status = XNandPs_ReadCache(NandInstPtr, Offset, Length, ReadBuffer, NULL);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare the data read against the data Written.
|
||||
*/
|
||||
for (Index = 0; Index < Length; Index++) {
|
||||
if (ReadBuffer[Index] != WriteBuffer[Index]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the Receive buffer for next iteration
|
||||
*/
|
||||
memset(ReadBuffer, 0, Length);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
255
XilinxProcessorIPLib/drivers/nandps/examples/xnandps_example.c
Executable file
255
XilinxProcessorIPLib/drivers/nandps/examples/xnandps_example.c
Executable file
|
@ -0,0 +1,255 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* @file xnandps_example.c
|
||||
**
|
||||
* This file contains a design example using the NAND driver (XNandPs).
|
||||
* This example tests the block erase, block read and block write features.
|
||||
* The flash blocks are erased and written. The data is read back and compared
|
||||
* with the data written for correctness. The bad blocks are not erased/programmed.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00 nm 12/10/2010 First release.
|
||||
* 1.01a nm 28/02/2012 Modified the test offsets.
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <xil_types.h>
|
||||
#include <xil_printf.h>
|
||||
#include <xparameters.h>
|
||||
#include <xnandps.h>
|
||||
#include <xnandps_bbm.h>
|
||||
/************************** Constant Definitions *****************************/
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define NAND_DEVICE_ID XPAR_XNANDPS_0_DEVICE_ID
|
||||
/* Test parameters */
|
||||
#define NAND_TEST_START_BLOCK 64 /**< Starting block to test */
|
||||
#define NAND_TEST_NUM_BLOCKS 16 /**< Number of blocks to test */
|
||||
#define NAND_TEST_BLOCK_SIZE 0x20000 /**< Test Block Size, must be same as
|
||||
the flash block size */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int NandReadWriteExample(u32 NandDeviceId);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
XNandPs NandInstance; /* XNand Instance. */
|
||||
XNandPs *NandInstPtr = &NandInstance;
|
||||
/*
|
||||
* Buffers used during read and write transactions.
|
||||
*/
|
||||
u8 ReadBuffer[NAND_TEST_BLOCK_SIZE]; /**< Block sized Read buffer */
|
||||
u8 WriteBuffer[NAND_TEST_BLOCK_SIZE]; /**< Block sized write buffer */
|
||||
/************************** Function Definitions ******************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to execute the Nand Flash read write example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if the example has completed successfully.
|
||||
* - XST_FAILURE if the example has failed.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("Nand Flash Read Write Example Test\r\n");
|
||||
/*
|
||||
* Run the NAND read write example, specify the Base Address that
|
||||
* is generated in xparameters.h .
|
||||
*/
|
||||
Status = NandReadWriteExample(NAND_DEVICE_ID);
|
||||
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("Nand Flash Read Write Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
xil_printf("Successfully ran Nand Flash Read Write Example Test\r\n");
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function runs a test on the NAND flash device using the basic driver
|
||||
* functions.
|
||||
* The function does the following tasks:
|
||||
* - Initialize the driver.
|
||||
* - Erase the blocks.
|
||||
* - Write in to all the blocks.
|
||||
* - Read back the data from the blocks.
|
||||
* - Compare the data read against the data Written.
|
||||
*
|
||||
* @param NandDeviceId is is the XPAR_<NAND_instance>_DEVICE_ID value
|
||||
* from xparameters.h.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if failed.
|
||||
*
|
||||
* @note When bad blocks are encountered, they are not erased and
|
||||
* programmed.
|
||||
*
|
||||
****************************************************************************/
|
||||
int NandReadWriteExample(u32 NandDeviceId)
|
||||
{
|
||||
int Status;
|
||||
u32 Index;
|
||||
u32 BlockIndex;
|
||||
XNandPs_Config *ConfigPtr;
|
||||
u64 Offset;
|
||||
u32 Length;
|
||||
u32 StartBlock;
|
||||
u32 EndBlock;
|
||||
|
||||
/*
|
||||
* Initialize the flash driver.
|
||||
*/
|
||||
ConfigPtr = XNandPs_LookupConfig(NandDeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XNandPs_CfgInitialize(NandInstPtr, ConfigPtr,
|
||||
ConfigPtr->SmcBase,ConfigPtr->FlashBase);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
StartBlock = NAND_TEST_START_BLOCK;
|
||||
EndBlock = NAND_TEST_START_BLOCK + NAND_TEST_NUM_BLOCKS;
|
||||
Length = NAND_TEST_BLOCK_SIZE;
|
||||
/*
|
||||
* Prepare the write buffer. Fill in the data need to be written into
|
||||
* Flash Device.
|
||||
*/
|
||||
for (Index = 0; Index < Length; Index++) {
|
||||
WriteBuffer[Index] = Index % 256;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase the blocks in the flash
|
||||
*/
|
||||
for (BlockIndex = StartBlock; BlockIndex < EndBlock; BlockIndex++) {
|
||||
/*
|
||||
* Don't erase bad blocks.
|
||||
*/
|
||||
if (XNandPs_IsBlockBad(NandInstPtr, BlockIndex) == XST_SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
/*
|
||||
* Perform erase operation.
|
||||
*/
|
||||
Status = XNandPs_EraseBlock(NandInstPtr, BlockIndex);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the read/write operation
|
||||
*/
|
||||
for (BlockIndex = StartBlock; BlockIndex < EndBlock; BlockIndex++) {
|
||||
/*
|
||||
* Don't program bad blocks.
|
||||
*/
|
||||
if (XNandPs_IsBlockBad(NandInstPtr, BlockIndex) == XST_SUCCESS)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
Offset = BlockIndex * NandInstPtr->Geometry.BlockSize;
|
||||
|
||||
/*
|
||||
* Perform the write operation.
|
||||
*/
|
||||
Status = XNandPs_Write(NandInstPtr, Offset, Length, WriteBuffer, NULL);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform the read operation.
|
||||
*/
|
||||
Status = XNandPs_Read(NandInstPtr, Offset, Length, ReadBuffer, NULL);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare the data read against the data Written.
|
||||
*/
|
||||
for (Index = 0; Index < Length; Index++) {
|
||||
if (ReadBuffer[Index] != WriteBuffer[Index]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Clear the Receive buffer for next iteration
|
||||
*/
|
||||
memset(ReadBuffer, 0, Length);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
514
XilinxProcessorIPLib/drivers/nandps/examples/xnandps_skip_example.c
Executable file
514
XilinxProcessorIPLib/drivers/nandps/examples/xnandps_skip_example.c
Executable file
|
@ -0,0 +1,514 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/******************************************************************************
|
||||
*
|
||||
* @file xnandps_skip_example.c
|
||||
**
|
||||
* This file contains a design example using the NAND driver (XNandPs).
|
||||
* This example tests the skip block method of erase/read/write operations.
|
||||
* The skip block method is useful while reading/writing images on to the flash.
|
||||
* The flash is erased and programming by considering the bad blocks. The data is
|
||||
* read back and compared with the data written for correctness.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* None.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00 nm 12/10/2010 First release
|
||||
* 1.01a nm 28/02/2012 Modified the test offsets.
|
||||
*
|
||||
*</pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <xil_types.h>
|
||||
#include <xil_printf.h>
|
||||
#include <xparameters.h>
|
||||
#include <xnandps.h>
|
||||
#include <xnandps_bbm.h>
|
||||
/************************** Constant Definitions *****************************/
|
||||
/*
|
||||
* The following constants map to the XPAR parameters created in the
|
||||
* xparameters.h file. They are defined here such that a user can easily
|
||||
* change all the needed parameters in one place.
|
||||
*/
|
||||
#define NAND_DEVICE_ID XPAR_XNANDPS_0_DEVICE_ID
|
||||
/* Test parameters */
|
||||
#define NAND_TEST_OFFSET 0x01000000 /**< Flash Test Offset */
|
||||
#define NAND_TEST_LENGTH 0x00080000 /**< Test Length */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int NandSkipBlockExample(u32 NandDeviceId);
|
||||
|
||||
int XNandPs_SkipRead(XNandPs *InstancePtr, u64 Offset, u32 Length, void
|
||||
*DestPtr);
|
||||
|
||||
int XNandPs_SkipWrite(XNandPs *InstancePtr, u64 Offset, u32 Length, void
|
||||
*SrcPtr);
|
||||
|
||||
int XNandPs_SkipErase(XNandPs *InstancePtr, u64 Offset, u32 Length);
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
XNandPs NandInstance; /* XNand Instance. */
|
||||
XNandPs *NandInstPtr = &NandInstance;
|
||||
/*
|
||||
* Buffers used during read and write transactions.
|
||||
*/
|
||||
u8 ReadBuffer[NAND_TEST_LENGTH];
|
||||
u8 WriteBuffer[NAND_TEST_LENGTH];
|
||||
/************************** Function Definitions ******************************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* Main function to execute the Skip Block based Nand read/write example.
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if the example has completed successfully.
|
||||
* - XST_FAILURE if the example has failed.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
int main(void)
|
||||
{
|
||||
int Status;
|
||||
|
||||
xil_printf("Nand Flash Skip Block Method Example Test\r\n");
|
||||
|
||||
/*
|
||||
* Run the NAND read write example, specify the Base Address that
|
||||
* is generated in xparameters.h .
|
||||
*/
|
||||
Status = NandSkipBlockExample(NAND_DEVICE_ID);
|
||||
|
||||
if (Status != XST_SUCCESS) {
|
||||
xil_printf("Nand Flash Skip Block Method Example Test Failed\r\n");
|
||||
return XST_FAILURE;
|
||||
}
|
||||
xil_printf("Successfully ran Nand Flash Skip Block Method Example Test\r\n");
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function runs a test on the NAND flash device using the basic driver
|
||||
* functions.
|
||||
* The function does the following tasks:
|
||||
* - Initialize the driver.
|
||||
* - Erase the required length of bytes by taking bad blocks into account.
|
||||
* - Write the number of bytes from given offset by taking bad blocks
|
||||
* into account.
|
||||
* - Read the number of bytes from given offset by taking bad blocks
|
||||
* into account.
|
||||
* - Compare the data read against the data Written.
|
||||
*
|
||||
* @param NandDeviceId is the XPAR_<NAND_instance>_DEVICE_ID value
|
||||
* from xparameters.h.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if failed.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
****************************************************************************/
|
||||
int NandSkipBlockExample(u32 NandDeviceId)
|
||||
{
|
||||
int Status;
|
||||
u32 Index;
|
||||
XNandPs_Config *ConfigPtr;
|
||||
u64 Offset;
|
||||
u32 Length;
|
||||
|
||||
/*
|
||||
* Initialize the flash driver.
|
||||
*/
|
||||
ConfigPtr = XNandPs_LookupConfig(NandDeviceId);
|
||||
if (ConfigPtr == NULL) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Status = XNandPs_CfgInitialize(NandInstPtr, ConfigPtr,
|
||||
ConfigPtr->SmcBase,ConfigPtr->FlashBase);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
Offset = NAND_TEST_OFFSET;
|
||||
Length = NAND_TEST_LENGTH;
|
||||
|
||||
/*
|
||||
* Prepare the write buffer. Fill in the data need to be written into
|
||||
* Flash Device.
|
||||
*/
|
||||
for (Index = 0; Index < Length; Index++) {
|
||||
WriteBuffer[Index] = Index % 256;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase the blocks using skip block method
|
||||
*/
|
||||
Status = XNandPs_SkipErase(NandInstPtr, Offset, Length);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write into the flash offset.
|
||||
*/
|
||||
Status = XNandPs_SkipWrite(NandInstPtr, Offset, Length, WriteBuffer);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read back from the flash.
|
||||
*/
|
||||
Status = XNandPs_SkipRead(NandInstPtr, Offset, Length, ReadBuffer);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Compare the data read against the data Written.
|
||||
*/
|
||||
for (Index = 0; Index < Length; Index++) {
|
||||
if (ReadBuffer[Index] != WriteBuffer[Index]) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function returns the length including bad blocks from a given offset and
|
||||
* length.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @param Offset is the flash data address to read from.
|
||||
* @param Length is number of bytes to read.
|
||||
*
|
||||
* @return
|
||||
* - Return actual length including bad blocks.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
u32 XNandPs_CalculateLength(XNandPs *InstancePtr, u64 Offset, u32 Length)
|
||||
{
|
||||
u32 BlockSize = InstancePtr->Geometry.BlockSize;
|
||||
u32 CurBlockLen;
|
||||
u32 CurBlock;
|
||||
u32 Status;
|
||||
u32 TempLen = 0;
|
||||
u32 ActLen = 0;
|
||||
|
||||
while (TempLen < Length) {
|
||||
CurBlockLen = BlockSize - (Offset & (BlockSize - 1));
|
||||
CurBlock = (Offset & ~(BlockSize - 1))/BlockSize;
|
||||
|
||||
/*
|
||||
* Check if the block is bad
|
||||
*/
|
||||
Status = XNandPs_IsBlockBad(InstancePtr, CurBlock);
|
||||
if (Status != XST_SUCCESS) {
|
||||
/* Good Block */
|
||||
TempLen += CurBlockLen;
|
||||
}
|
||||
ActLen += CurBlockLen;
|
||||
Offset += CurBlockLen;
|
||||
if (Offset >= InstancePtr->Geometry.DeviceSize) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ActLen;
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function reads the data from the Flash device and copies it into the
|
||||
* specified user buffer. This function considers bad blocks and skips them
|
||||
* to read next blocks.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @param Offset is the flash data address to read from.
|
||||
* @param Length is number of bytes to read.
|
||||
* @param DestPtr is the destination address to copy data to.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XNandPs_SkipRead(XNandPs *InstancePtr, u64 Offset, u32 Length, void
|
||||
*DestPtr)
|
||||
{
|
||||
u32 ActLen;
|
||||
u32 BlockOffset;
|
||||
u32 Block;
|
||||
u32 Status;
|
||||
u32 BytesLeft = Length;
|
||||
u32 BlockSize = InstancePtr->Geometry.BlockSize;
|
||||
u8 *BufPtr = (u8 *)DestPtr;
|
||||
u32 ReadLen;
|
||||
u32 BlockReadLen;
|
||||
|
||||
/*
|
||||
* Calculate the actual length including bad blocks
|
||||
*/
|
||||
ActLen = XNandPs_CalculateLength(InstancePtr, Offset, Length);
|
||||
|
||||
/*
|
||||
* Check if the actual length cross flash size
|
||||
*/
|
||||
if (Offset + ActLen > InstancePtr->Geometry.DeviceSize) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
while (BytesLeft > 0) {
|
||||
BlockOffset = Offset & (BlockSize - 1);
|
||||
Block = (Offset & ~(BlockSize - 1))/BlockSize;
|
||||
BlockReadLen = BlockSize - BlockOffset;
|
||||
|
||||
Status = XNandPs_IsBlockBad(InstancePtr, Block);
|
||||
if (Status == XST_SUCCESS) {
|
||||
/* Move to next block */
|
||||
Offset += BlockReadLen;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we cross block boundary
|
||||
*/
|
||||
if (BytesLeft < BlockReadLen) {
|
||||
ReadLen = BytesLeft;
|
||||
} else {
|
||||
ReadLen = BlockReadLen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the NAND flash
|
||||
*/
|
||||
Status = XNandPs_Read(InstancePtr, Offset, ReadLen, BufPtr, NULL);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
BytesLeft -= ReadLen;
|
||||
Offset += ReadLen;
|
||||
BufPtr += ReadLen;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function programs the flash device(s) with data specified in the user
|
||||
* buffer. This function considers bad blocks and skips them.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @param Offset is the flash data address to write to.
|
||||
* @param Length is number of bytes to write.
|
||||
* @param SrcPtr is the source address to write the data from.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XNandPs_SkipWrite(XNandPs *InstancePtr, u64 Offset, u32 Length, void
|
||||
*SrcPtr)
|
||||
{
|
||||
u32 ActLen;
|
||||
u32 BlockOffset;
|
||||
u32 Block;
|
||||
u32 Status;
|
||||
u32 BytesLeft = Length;
|
||||
u32 BlockSize = InstancePtr->Geometry.BlockSize;
|
||||
u8 *BufPtr = (u8 *)SrcPtr;
|
||||
u32 WriteLen;
|
||||
u32 BlockWriteLen;
|
||||
|
||||
/*
|
||||
* Calculate the actual length including bad blocks
|
||||
*/
|
||||
ActLen = XNandPs_CalculateLength(InstancePtr, Offset, Length);
|
||||
|
||||
/*
|
||||
* Check if the actual length cross flash size
|
||||
*/
|
||||
if (Offset + ActLen > InstancePtr->Geometry.DeviceSize) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
while (BytesLeft > 0) {
|
||||
BlockOffset = Offset & (BlockSize - 1);
|
||||
Block = (Offset & ~(BlockSize - 1))/BlockSize;
|
||||
BlockWriteLen = BlockSize - BlockOffset;
|
||||
|
||||
/*
|
||||
* Check if the block is bad
|
||||
*/
|
||||
Status = XNandPs_IsBlockBad(InstancePtr, Block);
|
||||
if (Status == XST_SUCCESS) {
|
||||
/* Move to next block */
|
||||
Offset += BlockWriteLen;
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we cross block boundary
|
||||
*/
|
||||
if (BytesLeft < BlockWriteLen) {
|
||||
WriteLen = BytesLeft;
|
||||
} else {
|
||||
WriteLen = BlockWriteLen;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from the NAND flash
|
||||
*/
|
||||
Status = XNandPs_Write(InstancePtr, Offset, WriteLen, BufPtr, NULL);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
BytesLeft -= WriteLen;
|
||||
Offset += WriteLen;
|
||||
BufPtr += WriteLen;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function erases length bytes in the flash device from a given offset.
|
||||
* The Offset and Length must be block aligned. This functions skips bad blocks.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNand instance.
|
||||
* @param Offset is the flash address to start erasing from.
|
||||
* @param Length is number of bytes to erase.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if error in erase.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XNandPs_SkipErase(XNandPs *InstancePtr, u64 Offset, u32 Length)
|
||||
{
|
||||
u32 StartBlock;
|
||||
u32 NumOfBlocks;
|
||||
u32 BlockSize;
|
||||
u32 Block;
|
||||
int Status;
|
||||
|
||||
BlockSize = InstancePtr->Geometry.BlockSize;
|
||||
/*
|
||||
* Start address must align on block boundary
|
||||
*/
|
||||
if (Offset & (BlockSize - 1)) {
|
||||
/* Unalinged offset */
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Length must align on block boundary
|
||||
*/
|
||||
if (Length & (BlockSize - 1)) {
|
||||
/* Length is not block aligned */
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
StartBlock = (Offset & ~(BlockSize - 1))/BlockSize;
|
||||
NumOfBlocks = (Length & ~(BlockSize - 1))/BlockSize;
|
||||
|
||||
for (Block = StartBlock; Block < (StartBlock + NumOfBlocks)
|
||||
; Block++) {
|
||||
/*
|
||||
* Check if the block is bad
|
||||
*/
|
||||
Status = XNandPs_IsBlockBad(InstancePtr, Block);
|
||||
if (Status == XST_SUCCESS) {
|
||||
NumOfBlocks++;
|
||||
if ((StartBlock + NumOfBlocks) >=
|
||||
InstancePtr->Geometry.NumBlocks) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
/* Increase the block count for skip block method */
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Erase the Nand flash block
|
||||
*/
|
||||
Status = XNandPs_EraseBlock(InstancePtr, Block);
|
||||
if (Status == XST_NAND_WRITE_PROTECTED) {
|
||||
/* Flash is write protected */
|
||||
return XST_FAILURE;
|
||||
}
|
||||
if (Status != XST_SUCCESS) {
|
||||
/* Erase operation error */
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
40
XilinxProcessorIPLib/drivers/nandps/src/Makefile
Executable file
40
XilinxProcessorIPLib/drivers/nandps/src/Makefile
Executable file
|
@ -0,0 +1,40 @@
|
|||
COMPILER=
|
||||
ARCHIVER=
|
||||
CP=cp
|
||||
COMPILER_FLAGS=
|
||||
EXTRA_COMPILER_FLAGS=
|
||||
LIB=libxil.a
|
||||
|
||||
CC_FLAGS = $(COMPILER_FLAGS)
|
||||
ECC_FLAGS = $(EXTRA_COMPILER_FLAGS)
|
||||
|
||||
RELEASEDIR=../../../lib
|
||||
INCLUDEDIR=../../../include
|
||||
INCLUDES=-I./. -I${INCLUDEDIR}
|
||||
|
||||
OUTS = *.o
|
||||
|
||||
LIBSOURCES:=*.c
|
||||
INCLUDEFILES:=*.h
|
||||
|
||||
OBJECTS = $(addsuffix .o, $(basename $(wildcard *.c)))
|
||||
|
||||
libs: banner xnandps_libs clean
|
||||
|
||||
%.o: %.c
|
||||
${COMPILER} $(CC_FLAGS) $(ECC_FLAGS) $(INCLUDES) -o $@ $<
|
||||
|
||||
banner:
|
||||
echo "Compiling nandps"
|
||||
|
||||
xnandps_libs: ${OBJECTS}
|
||||
$(ARCHIVER) -r ${RELEASEDIR}/${LIB} ${OBJECTS}
|
||||
|
||||
.PHONY: include
|
||||
include: xnandps_includes
|
||||
|
||||
xnandps_includes:
|
||||
${CP} ${INCLUDEFILES} ${INCLUDEDIR}
|
||||
|
||||
clean:
|
||||
rm -rf ${OBJECTS}
|
1963
XilinxProcessorIPLib/drivers/nandps/src/xnandps.c
Executable file
1963
XilinxProcessorIPLib/drivers/nandps/src/xnandps.c
Executable file
File diff suppressed because it is too large
Load diff
447
XilinxProcessorIPLib/drivers/nandps/src/xnandps.h
Executable file
447
XilinxProcessorIPLib/drivers/nandps/src/xnandps.h
Executable file
|
@ -0,0 +1,447 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xnandps.h
|
||||
*
|
||||
* This file implements a driver for the NAND flash controller.
|
||||
*
|
||||
* <b>Driver Initialization</b>
|
||||
*
|
||||
* The function call XNandPs_CfgInitialize() should be called by the application
|
||||
* before any other function in the driver. The initialization function takes
|
||||
* device specific data (like device id, instance id, and base address) and
|
||||
* initializes the XNandPs instance with the device specific data.
|
||||
*
|
||||
* <b>Device Geometry</b>
|
||||
*
|
||||
* NAND flash device is memory device and it is segmented into areas called
|
||||
* Logical Unit(s) (LUN) and further in to blocks and pages. A NAND flash device
|
||||
* can have multiple LUN. LUN is sequential raw of multiple blocks of the same
|
||||
* size. A block is the smallest erasable unit of data within the Flash array of
|
||||
* a LUN. The size of each block is based on a power of 2. There is no
|
||||
* restriction on the number of blocks within the LUN. A block contains a number
|
||||
* of pages. A page is the smallest addressable unit for read and program
|
||||
* operations. The arrangement of LUN, blocks, and pages is referred to by this
|
||||
* module as the part's geometry.
|
||||
*
|
||||
* The cells within the part can be programmed from a logic 1 to a logic 0
|
||||
* and not the other way around. To change a cell back to a logic 1, the
|
||||
* entire block containing that cell must be erased. When a block is erased
|
||||
* all bytes contain the value 0xFF. The number of times a block can be
|
||||
* erased is finite. Eventually the block will wear out and will no longer
|
||||
* be capable of erasure. As of this writing, the typical flash block can
|
||||
* be erased 100,000 or more times.
|
||||
*
|
||||
* The jobs done by this driver typically are:
|
||||
* - 8/16 bit operational mode
|
||||
* - Read, Write, and Erase operation
|
||||
* - Read, Write cache operation
|
||||
* - Read, Write Spare area operation
|
||||
* - HW Error Check and Correction (ECC)
|
||||
*
|
||||
* <b>Write Operation</b>
|
||||
*
|
||||
* The write call can be used to write a minimum of one byte and a maximum
|
||||
* entire flash. If the address offset specified to write is out of flash or if
|
||||
* the number of bytes specified from the offset exceed flash boundaries
|
||||
* an error is reported back to the user. The write is blocking in nature in that
|
||||
* the control is returned back to user only after the write operation is
|
||||
* completed successfully or an error is reported.
|
||||
*
|
||||
* <b>Read Operation</b>
|
||||
*
|
||||
* The read call can be used to read a minimum of one byte and maximum of
|
||||
* entire flash. If the address offset specified to read is out of flash or if
|
||||
* the number of bytes specified from the offset exceed flash boundaries
|
||||
* an error is reported back to the user. The read is blocking in nature in that
|
||||
* the control is returned back to user only after the read operation is
|
||||
* completed successfully or an error is reported.
|
||||
*
|
||||
* <b>Erase Operation</b>
|
||||
*
|
||||
* The erase operations are provided to erase a Block in the Flash memory. The
|
||||
* erase call is blocking in nature in that the control is returned back to user
|
||||
* only after the erase operation is completed successfully or an error is
|
||||
* reported.
|
||||
*
|
||||
* <b>Page Cache Write Operation</b>
|
||||
*
|
||||
* The page cache write call is same as write call except that it uses cache
|
||||
* commands to write. This enhances the performance. This operation can't be
|
||||
* performed on OnDie ECC with internal ECC enabled. There is no way to disable
|
||||
* internal ECC for OnDie ECC flash parts in current driver. This operation
|
||||
* is tested with Spansion S34ML04G100TFI00 flash. We have to use this operation
|
||||
* only on the flash parts which supports program page cache command.
|
||||
*
|
||||
* <b>Page Cache Read Operation</b>
|
||||
*
|
||||
* The page cache read call is same as read call except that it uses cache
|
||||
* commands to read. This enhances the performance.
|
||||
* The read cache random command is used since the HW ECC block doesn't
|
||||
* support commands without address for starting ECC.
|
||||
* This operation can't be performed on OnDie ECC with internal ECC enabled.
|
||||
* There is no way to disable internal ECC for OnDie ECC flash parts in current
|
||||
* driver. This operation is tested with Spansion S34ML04G100TFI00 flash.
|
||||
* We have to use this operation only on the flash parts which supports
|
||||
* read page cache command (random).
|
||||
*
|
||||
* <b>Write Spare Bytes Operation</b>
|
||||
*
|
||||
* This call writes to user specified buffer into spare bytes of a page.
|
||||
*
|
||||
* <b>Read Spare Bytes Operation</b>
|
||||
*
|
||||
* This call reads spare bytes of a page into user specified buffer.
|
||||
*
|
||||
* @note
|
||||
*
|
||||
* This driver is intended to be RTOS and processor independent. It works with
|
||||
* physical addresses only. Any needs for dynamic memory management, threads,
|
||||
* mutual exclusion, virtual memory, cache control, or HW write protection
|
||||
* management must be satisfied by the layer above this driver.
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00a nm 12/10/2010 First release
|
||||
* nm 29/09/2011 Added support for On-Die ECC NAND and Clean NAND
|
||||
* flash parts.
|
||||
* Added user spare buffer pointer to read/write
|
||||
* API's. Added new API's for reading and writing
|
||||
* spare buffer area.
|
||||
* Changes nand_cycles with ONFI timing mode 0.
|
||||
* Modified ONFI parameter page reading to read 3
|
||||
* mandatory pages.
|
||||
* 1.01a nm 28/02/2012 Added tcl file to generate xparameters.h.
|
||||
* Added support for 8Gb On-Die ECC NAND flash
|
||||
* parts (CR 648463).
|
||||
* Fixed 16-bit issue with ONFI commands like
|
||||
* read, write and read status command.
|
||||
* 1.02a nm 20/09/2012 Removed setting of set_cycles and set_opmode
|
||||
* register values as it is now done in FSBL using
|
||||
* the PCW generated files. CR#678949.
|
||||
* 1.03a nm 10/22/2012 Fixed CR# 683787,673348.
|
||||
* 1.04a nm 04/15/2013 Fixed CR# 704401. Removed warnings when compiled
|
||||
* with -Wall and -Wextra option in bsp.
|
||||
* 04/25/2013 Implemented PR# 699544. Added page cache read
|
||||
* and program support. Added API's XNandPs_ReadCache
|
||||
* and XNandPs_WriteCache for page cache support.
|
||||
* Added XNandPs_Features structure to XNandPs instance
|
||||
* which contains features handled by driver.
|
||||
* Added function prototypes for Page cache read/write
|
||||
* and spare byte read/write API's.
|
||||
* 2.0 adk 12/10/13 Updated as per the New Tcl API's
|
||||
* 2.1 kpc 07/24/13 Fixed CR#808770. Update command register twice only
|
||||
* if flash device requires >= four address cycles.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XNANDPS_H /* prevent circular inclusions */
|
||||
#define XNANDPS_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include <string.h> /* For memcpy, memset */
|
||||
#include "xil_types.h"
|
||||
#include "xil_assert.h"
|
||||
#include "xil_io.h"
|
||||
#include "xstatus.h"
|
||||
#include "xnandps_hw.h"
|
||||
/************************** Constant Definitions *****************************/
|
||||
#define XNANDPS_MAX_TARGETS 1 /**< Max number of targets
|
||||
supported */
|
||||
#define XNANDPS_MAX_BLOCKS 32768 /**< Max number of Blocks */
|
||||
#define XNANDPS_MAX_PAGE_SIZE 16384 /**< Max page size of NAND
|
||||
flash */
|
||||
#define XNANDPS_MAX_SPARE_SIZE 512 /**< Max spare bytes of a NAND
|
||||
flash page */
|
||||
#define XNANDPS_ECC_BLOCK_SIZE 512 /**< ECC block size */
|
||||
#define XNANDPS_ECC_BYTES 3 /**< ECC bytes per ECC block */
|
||||
|
||||
#define XNANDPS_PAGE_SIZE_512 512 /**< Page size 512 */
|
||||
#define XNANDPS_PAGE_SIZE_1024 1024 /**< Page size 1024 */
|
||||
#define XNANDPS_PAGE_SIZE_2048 2048 /**< Page size 2048 */
|
||||
#define XNANDPS_PAGE_SIZE_4096 4096 /**< Page size 4096 */
|
||||
#define XNANDPS_PAGE_SIZE_8192 8192 /**< Page size 8192 */
|
||||
|
||||
#define XNANDPS_SPARE_SIZE_8 8 /**< Spare bytes size 8 */
|
||||
#define XNANDPS_SPARE_SIZE_16 16 /**< Spare bytes size 16 */
|
||||
#define XNANDPS_SPARE_SIZE_32 32 /**< Spare bytes size 32 */
|
||||
#define XNANDPS_SPARE_SIZE_64 64 /**< Spare bytes size 64 */
|
||||
#define XNANDPS_SPARE_SIZE_128 128 /**< Spare bytes size 128 */
|
||||
#define XNANDPS_SPARE_SIZE_256 256 /**< Spare bytes size 256 */
|
||||
|
||||
#define XNANDPS_FLASH_WIDTH_8 8 /**< NAND Flash width 8-bit */
|
||||
#define XNANDPS_FLASH_WIDTH_16 16 /**< NAND Flash width 16-bit */
|
||||
|
||||
/* Macros used for framing SMC AXI command phase and Data phase address */
|
||||
#define XNANDPS_END_CMD_NONE 0 /**< No End command */
|
||||
#define XNANDPS_END_CMD_INVALID 0 /**< End command invalid */
|
||||
#define XNANDPS_CMD_PHASE 1 /**< End command in command
|
||||
phase */
|
||||
#define XNANDPS_DATA_PHASE 2 /**< End command in data
|
||||
phase */
|
||||
|
||||
#define XNANDPS_PAGE_NOT_VALID -1 /**< Page is not valid in
|
||||
command phase */
|
||||
#define XNANDPS_COLUMN_NOT_VALID -1 /**< Column is not valid in
|
||||
command phase */
|
||||
|
||||
#define XNANDPS_AXI_DATA_WIDTH 4 /**< AXI Data width for last
|
||||
transaction while reading
|
||||
and writing */
|
||||
|
||||
/* Bit shift for AXI Command/Data phase address calculation */
|
||||
#define XNANDPS_START_CMD_SHIFT 3 /**< Start command shift */
|
||||
#define XNANDPS_END_CMD_SHIFT 11 /**< End command shift */
|
||||
#define XNANDPS_END_CMD_VALID_SHIFT 20 /**< End command valid shift */
|
||||
#define XNANDPS_ADDR_CYCLES_SHIFT 21 /**< Address cycles shift */
|
||||
#define XNANDPS_CHIP_ADDR_SHIFT 24 /**< Chip address shift */
|
||||
#define XNANDPS_ECC_LAST_SHIFT 10 /**< Ecc last shift */
|
||||
#define XNANDPS_CLEAR_CS_SHIFT 21 /**< clear chip select shift */
|
||||
#define XNANDPS_COMMAND_PHASE_MASK 0x00000000 /**< Command
|
||||
phase mask */
|
||||
#define XNANDPS_DATA_PHASE_MASK 0x00080000 /**< Data phase mask */
|
||||
|
||||
/* Macros used for correcting ECC errors */
|
||||
#define XNANDPS_ECC_CORRECT_BYTE_MASK 0x1FF /**< ECC error correction byte
|
||||
position mask, bits[11:3] of
|
||||
error code */
|
||||
#define XNANDPS_ECC_CORRECT_BIT_MASK 0x7 /**< ECC error correction bit
|
||||
position mask, bits[0:2] of
|
||||
error code */
|
||||
|
||||
/* Flash memory controller operating parameters */
|
||||
#define XNANDPS_CLR_CONFIG \
|
||||
((XNANDPS_MEMC_CLR_CONFIG_INT_DISABLE1_MASK) | \
|
||||
(XNANDPS_MEMC_CLR_CONFIG_INT_CLR1_MASK) | \
|
||||
(XNANDPS_MEMC_CLR_CONFIG_ECC_INT_DISABLE1_MASK))
|
||||
/**< Interrupt settings */
|
||||
|
||||
#define XNANDPS_ECC_MEMCFG \
|
||||
((0x1 << XNANDPS_ECC_MEMCFG_ECC_MODE_SHIFT) | \
|
||||
(0x1 << XNANDPS_ECC_MEMCFG_ECC_READ_END_SHIFT) | \
|
||||
(0x0 << XNANDPS_ECC_MEMCFG_ECC_JUMP_SHIFT))
|
||||
/**< ECC memory configuration settings */
|
||||
|
||||
#define XNANDPS_ECC_CMD1 \
|
||||
((0x80 << XNANDPS_ECC_MEMCOMMAND1_WR_CMD_SHIFT) | \
|
||||
(0x00 << XNANDPS_ECC_MEMCOMMAND1_RD_CMD_SHIFT) | \
|
||||
(0x30 << XNANDPS_ECC_MEMCOMMAND1_RD_CMD_END_SHIFT) | \
|
||||
(0x1 << XNANDPS_ECC_MEMCOMMAND1_RD_CMD_END_VALID_SHIFT))
|
||||
/**< ECC command 1 settings */
|
||||
|
||||
#define XNANDPS_ECC_CMD2 \
|
||||
((0x85 << XNANDPS_ECC_MEMCOMMAND2_WR_COL_CHANGE_SHIFT) | \
|
||||
(0x05 << XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_SHIFT) | \
|
||||
(0xE0 << XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_END_SHIFT) | \
|
||||
(0x1 << XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_END_VALID_SHIFT))
|
||||
/**< ECC command 2 settings */
|
||||
|
||||
#define XNANDPS_CLR_CS (0x1 << XNANDPS_CLEAR_CS_SHIFT)
|
||||
/**< set Clear chip select */
|
||||
#define XNANDPS_ECC_LAST (0x1 << XNANDPS_ECC_LAST_SHIFT)
|
||||
/**< set Ecc last */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
/*
|
||||
* This enum contains ECC Mode
|
||||
*/
|
||||
typedef enum {
|
||||
XNANDPS_ECC_NONE = 0, /**< No ECC */
|
||||
XNANDPS_ECC_SW, /**< Software ECC */
|
||||
XNANDPS_ECC_HW, /**< Hardware controller ECC */
|
||||
XNANDPS_ECC_ONDIE /**< On-Die ECC */
|
||||
} XNandPs_EccMode;
|
||||
|
||||
/**
|
||||
* This typedef contains configuration information for the flash device.
|
||||
*/
|
||||
typedef struct {
|
||||
u16 DeviceId; /**< Instance ID of device */
|
||||
u32 SmcBase; /**< SMC Base address */
|
||||
u32 FlashBase; /**< NAND base address */
|
||||
u32 FlashWidth; /**< Flash width */
|
||||
} XNandPs_Config;
|
||||
/**
|
||||
* Flash geometry
|
||||
*/
|
||||
typedef struct {
|
||||
u32 BytesPerPage; /**< Bytes per page */
|
||||
u16 SpareBytesPerPage; /**< Size of spare area in bytes */
|
||||
u32 PagesPerBlock; /**< Pages per block */
|
||||
u32 BlocksPerLun; /**< Bocks per LUN */
|
||||
u8 NumLun; /**< Total number of LUN */
|
||||
u8 FlashWidth; /**< Data width of flash device */
|
||||
u64 NumPages; /**< Total number of pages in device */
|
||||
u64 NumBlocks; /**< Total number of blocks in device */
|
||||
u64 BlockSize; /**< Size of a block in bytes */
|
||||
u64 DeviceSize; /**< Total device size in bytes */
|
||||
u8 RowAddrCycles; /**< Row address cycles */
|
||||
u8 ColAddrCycles; /**< Column address cycles */
|
||||
} XNandPs_Geometry;
|
||||
|
||||
/**
|
||||
* ONFI Features and Optional commands supported
|
||||
* See parameter page byte 6-7 and 8-9
|
||||
*/
|
||||
typedef struct {
|
||||
int ProgramCache;
|
||||
int ReadCache;
|
||||
} XNandPs_Features;
|
||||
|
||||
/**
|
||||
* Bad block table descriptor
|
||||
*/
|
||||
typedef struct {
|
||||
u32 PageOffset; /**< Page offset where BBT resides */
|
||||
u32 SigOffset; /**< Signature offset in Spare area */
|
||||
u32 VerOffset; /**< Offset of BBT version */
|
||||
u32 SigLength; /**< Length of the signature */
|
||||
u32 MaxBlocks; /**< Max blocks to search for BBT */
|
||||
char Signature[4]; /**< BBT signature */
|
||||
u8 Version; /**< BBT version */
|
||||
u32 Valid; /**< BBT descriptor is valid or not */
|
||||
} XNandPs_BbtDesc;
|
||||
|
||||
/**
|
||||
* Bad block pattern
|
||||
*/
|
||||
typedef struct {
|
||||
u32 Options; /**< Options to search the bad block pattern */
|
||||
u32 Offset; /**< Offset to search for specified pattern */
|
||||
u32 Length; /**< Number of bytes to check the pattern */
|
||||
u8 Pattern[2]; /**< Pattern format to search for */
|
||||
} XNandPs_BadBlockPattern;
|
||||
|
||||
/**
|
||||
* ECC configuration structure.
|
||||
* Contains information related to ECC.
|
||||
*/
|
||||
typedef struct {
|
||||
u32 NumSteps; /**< Number of ECC steps for the flash page */
|
||||
u32 BlockSize; /**< ECC block size */
|
||||
u32 BytesPerBlock; /**< Number of ECC bytes for a block */
|
||||
u32 TotalBytes; /**< Total number of ECC bytes for Page */
|
||||
u32 EccPos[XNANDPS_MAX_SPARE_SIZE];
|
||||
/**< ECC position in the spare area */
|
||||
} XNandPs_EccConfig;
|
||||
|
||||
/**
|
||||
* The XNandPs driver instance data. The user is required to allocate a
|
||||
* variable of this type for every flash device in the system. A pointer to a
|
||||
* variable of this type is then passed to the driver API functions.
|
||||
*/
|
||||
typedef struct XNandPsTag {
|
||||
u32 IsReady; /**< Device is initialized and ready */
|
||||
XNandPs_Config Config; /**< XNandPs_Config of current
|
||||
device */
|
||||
XNandPs_Geometry Geometry; /**< Part geometry */
|
||||
XNandPs_Features Features; /**< Features and Optional commands */
|
||||
u32 CommandPhaseAddr; /**< NAND command phase address */
|
||||
u32 DataPhaseAddr; /**< NAND Data phase address */
|
||||
XNandPs_EccConfig EccConfig; /**< ECC configuration parameters */
|
||||
/* Bad block table definitions */
|
||||
XNandPs_BbtDesc BbtDesc; /**< Bad block table descriptor */
|
||||
XNandPs_BbtDesc BbtMirrorDesc; /**< Mirror BBT descriptor */
|
||||
XNandPs_BadBlockPattern BbPattern; /**< Bad block pattern to
|
||||
search */
|
||||
u8 Bbt[XNANDPS_MAX_BLOCKS >> 2]; /**< Bad block table array */
|
||||
u8 DataBuf[XNANDPS_MAX_PAGE_SIZE + XNANDPS_MAX_SPARE_SIZE];
|
||||
/**< Data buffer for partial read/writes */
|
||||
u8 *SpareBufPtr; /**< Pointer to store spare buffer */
|
||||
u8 EccCalc[XNANDPS_MAX_SPARE_SIZE]; /**< Buffer for calculated
|
||||
ECC */
|
||||
u8 EccCode[XNANDPS_MAX_SPARE_SIZE]; /**< Buffer for stored ECC */
|
||||
XNandPs_EccMode EccMode; /**< ECC Mode */
|
||||
int (*ReadPage) (struct XNandPsTag *InstancePtr, u8 *DstPtr);
|
||||
/**< Read Page routine */
|
||||
int (*WritePage) (struct XNandPsTag *InstancePtr, u8 *SrcPtr);
|
||||
/**< Write Page routine */
|
||||
} XNandPs;
|
||||
|
||||
/**
|
||||
* NAND Command format structures
|
||||
*/
|
||||
typedef struct {
|
||||
int StartCmd; /**< Start command */
|
||||
int EndCmd; /**< End command */
|
||||
u8 AddrCycles; /**< Number of address cycles */
|
||||
u8 EndCmdValid; /**< End command valid */
|
||||
} XNandPs_CommandFormat;
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/**
|
||||
* OneHot is used to check if one and only one bit is set.
|
||||
* This Macro returns 1 if the value passed is OneHot.
|
||||
*/
|
||||
#define OneHot(Value) (!((Value) & (Value - 1)))
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/*
|
||||
* Functions in xnandps_sinit.c
|
||||
*/
|
||||
XNandPs_Config *XNandPs_LookupConfig(u16 DeviceId);
|
||||
|
||||
/*
|
||||
* Functions in xnandps.c
|
||||
*/
|
||||
/*
|
||||
* Initialization, read, write and erase functions.
|
||||
*/
|
||||
int XNandPs_CfgInitialize(XNandPs *InstancePtr, XNandPs_Config *ConfigPtr,
|
||||
u32 SmcBaseAddr, u32 FlashBaseAddr);
|
||||
int XNandPs_Read(XNandPs *InstancePtr, u64 Offset, u32 Bytes, void *DestPtr,
|
||||
u8 *UserSparePtr);
|
||||
int XNandPs_ReadCache(XNandPs *InstancePtr, u64 Offset, u32 Bytes,
|
||||
void *SrcPtr, u8 *UserSparePtr);
|
||||
int XNandPs_Write(XNandPs *InstancePtr, u64 Offset, u32 Bytes, void *SrcPtr,
|
||||
u8 *UserSparePtr);
|
||||
int XNandPs_WriteCache(XNandPs *InstancePtr, u64 Offset, u32 Length,
|
||||
void *SrcPtr, u8 *UserSparePtr);
|
||||
int XNandPs_ReadSpareBytes(XNandPs *InstancePtr, u32 Page, u8 *Buf);
|
||||
int XNandPs_WriteSpareBytes(XNandPs *InstancePtr, u32 Page, u8 *Buf);
|
||||
int XNandPs_EraseBlock(XNandPs *InstancePtr, u32 BlockNum);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
869
XilinxProcessorIPLib/drivers/nandps/src/xnandps_bbm.c
Executable file
869
XilinxProcessorIPLib/drivers/nandps/src/xnandps_bbm.c
Executable file
|
@ -0,0 +1,869 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xnandps_bbm.c
|
||||
* This file implements the Bad Block Management (BBM) functionality.
|
||||
* See xnandps_bbm.h for more details.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00a nm 12/10/2010 First release
|
||||
* 1.03a nm 10/22/2012 Fixed CR# 683787.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include <string.h> /**< For memcpy and memset */
|
||||
#include "xil_types.h"
|
||||
#include "xnandps_bbm.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
static int XNandPs_ReadBbt(XNandPs *InstancePtr);
|
||||
|
||||
static int XNandPs_SearchBbt(XNandPs *InstancePtr, XNandPs_BbtDesc *Desc);
|
||||
|
||||
static void XNandPs_CreateBbt(XNandPs *InstancePtr);
|
||||
|
||||
static void XNandPs_ConvertBbt(XNandPs *InstancePtr, u8 *Buf);
|
||||
|
||||
static int XNandPs_WriteBbt(XNandPs *InstancePtr, XNandPs_BbtDesc *Desc,
|
||||
XNandPs_BbtDesc *MirrorDesc);
|
||||
|
||||
static int XNandPs_MarkBbt(XNandPs* InstancePtr, XNandPs_BbtDesc *Desc);
|
||||
|
||||
static int XNandPs_UpdateBbt(XNandPs *InstancePtr);
|
||||
|
||||
extern int XNandPs_ReadSpareBytes(XNandPs *InstancePtr, u32 Page, u8 *Buf);
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function initializes the Bad Block Table(BBT) descriptors with a
|
||||
* predefined pattern for searching Bad Block Table(BBT) in flash.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
*
|
||||
* @return
|
||||
* - NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
void XNandPs_InitBbtDesc(XNandPs *InstancePtr)
|
||||
{
|
||||
int Index;
|
||||
|
||||
Xil_AssertVoid(InstancePtr != NULL);
|
||||
Xil_AssertVoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
/*
|
||||
* Initialize primary Bad Block Table(BBT)
|
||||
*/
|
||||
InstancePtr->BbtDesc.PageOffset = XNANDPS_BBT_DESC_PAGE_OFFSET;
|
||||
if (InstancePtr->EccMode == XNANDPS_ECC_ONDIE) {
|
||||
InstancePtr->BbtDesc.SigOffset = 0x4;
|
||||
InstancePtr->BbtDesc.VerOffset = 0x14;
|
||||
} else {
|
||||
InstancePtr->BbtDesc.SigOffset = XNANDPS_BBT_DESC_SIG_OFFSET;
|
||||
InstancePtr->BbtDesc.VerOffset = XNANDPS_BBT_DESC_VER_OFFSET;
|
||||
}
|
||||
InstancePtr->BbtDesc.SigLength = XNANDPS_BBT_DESC_SIG_LEN;
|
||||
InstancePtr->BbtDesc.MaxBlocks = XNANDPS_BBT_DESC_MAX_BLOCKS;
|
||||
strcpy(&InstancePtr->BbtDesc.Signature[0], "Bbt0");
|
||||
InstancePtr->BbtDesc.Version = 0;
|
||||
InstancePtr->BbtDesc.Valid = 0;
|
||||
|
||||
/*
|
||||
* Initialize mirror Bad Block Table(BBT)
|
||||
*/
|
||||
InstancePtr->BbtMirrorDesc.PageOffset = XNANDPS_BBT_DESC_PAGE_OFFSET;
|
||||
if (InstancePtr->EccMode == XNANDPS_ECC_ONDIE) {
|
||||
InstancePtr->BbtMirrorDesc.SigOffset = 0x4;
|
||||
InstancePtr->BbtMirrorDesc.VerOffset = 0x14;
|
||||
} else {
|
||||
InstancePtr->BbtMirrorDesc.SigOffset = XNANDPS_BBT_DESC_SIG_OFFSET;
|
||||
InstancePtr->BbtMirrorDesc.VerOffset = XNANDPS_BBT_DESC_VER_OFFSET;
|
||||
}
|
||||
InstancePtr->BbtMirrorDesc.SigLength = XNANDPS_BBT_DESC_SIG_LEN;
|
||||
InstancePtr->BbtMirrorDesc.MaxBlocks = XNANDPS_BBT_DESC_MAX_BLOCKS;
|
||||
strcpy(&InstancePtr->BbtMirrorDesc.Signature[0], "1tbB");
|
||||
InstancePtr->BbtMirrorDesc.Version = 0;
|
||||
InstancePtr->BbtMirrorDesc.Valid = 0;
|
||||
|
||||
/*
|
||||
* Initialize Bad block search pattern structure
|
||||
*/
|
||||
if (InstancePtr->Geometry.BytesPerPage > 512) {
|
||||
/* For flash page size > 512 bytes */
|
||||
InstancePtr->BbPattern.Options = XNANDPS_BBT_SCAN_2ND_PAGE;
|
||||
InstancePtr->BbPattern.Offset =
|
||||
XNANDPS_BB_PATTERN_OFFSET_LARGE_PAGE;
|
||||
InstancePtr->BbPattern.Length =
|
||||
XNANDPS_BB_PATTERN_LENGTH_LARGE_PAGE;
|
||||
} else {
|
||||
InstancePtr->BbPattern.Options = XNANDPS_BBT_SCAN_2ND_PAGE;
|
||||
InstancePtr->BbPattern.Offset =
|
||||
XNANDPS_BB_PATTERN_OFFSET_SMALL_PAGE;
|
||||
InstancePtr->BbPattern.Length =
|
||||
XNANDPS_BB_PATTERN_LENGTH_SMALL_PAGE;
|
||||
}
|
||||
for(Index=0; Index < XNANDPS_BB_PATTERN_LENGTH_LARGE_PAGE; Index++) {
|
||||
InstancePtr->BbPattern.Pattern[Index] = XNANDPS_BB_PATTERN;
|
||||
}
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function scans the NAND flash for factory marked bad blocks and creates
|
||||
* a RAM based Bad Block Table(BBT).
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
*
|
||||
* @return
|
||||
* - NONE
|
||||
*
|
||||
******************************************************************************/
|
||||
static void XNandPs_CreateBbt(XNandPs *InstancePtr)
|
||||
{
|
||||
u32 BlockIndex;
|
||||
u32 PageIndex;
|
||||
u32 Length;
|
||||
u32 BlockOffset;
|
||||
u32 BlockShift;
|
||||
u32 NumPages;
|
||||
u32 Page;
|
||||
u8 Buf[XNANDPS_MAX_SPARE_SIZE];
|
||||
u32 BbtLen = InstancePtr->Geometry.NumBlocks >>
|
||||
XNANDPS_BBT_BLOCK_SHIFT;
|
||||
int Status;
|
||||
|
||||
/*
|
||||
* Number of pages to search for bad block pattern
|
||||
*/
|
||||
if (InstancePtr->BbPattern.Options & XNANDPS_BBT_SCAN_2ND_PAGE) {
|
||||
NumPages = 2;
|
||||
} else {
|
||||
NumPages = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zero the RAM based Bad Block Table(BBT) entries
|
||||
*/
|
||||
memset(&InstancePtr->Bbt[0], 0, BbtLen);
|
||||
|
||||
/*
|
||||
* Scan all the blocks for factory marked bad blocks
|
||||
*/
|
||||
for(BlockIndex = 0; BlockIndex <
|
||||
InstancePtr->Geometry.NumBlocks; BlockIndex++) {
|
||||
/*
|
||||
* Block offset in Bad Block Table(BBT) entry
|
||||
*/
|
||||
BlockOffset = BlockIndex >> XNANDPS_BBT_BLOCK_SHIFT;
|
||||
/*
|
||||
* Block shift value in the byte
|
||||
*/
|
||||
BlockShift = XNandPs_BbtBlockShift(BlockIndex);
|
||||
Page = BlockIndex * InstancePtr->Geometry.PagesPerBlock;
|
||||
|
||||
/*
|
||||
* Search for the bad block pattern
|
||||
*/
|
||||
for(PageIndex = 0; PageIndex < NumPages; PageIndex++) {
|
||||
Status = XNandPs_ReadSpareBytes(InstancePtr,
|
||||
(Page + PageIndex), &Buf[0]);
|
||||
|
||||
if (Status != XST_SUCCESS) {
|
||||
/* Marking as bad block */
|
||||
InstancePtr->Bbt[BlockOffset] |=
|
||||
(XNANDPS_BLOCK_FACTORY_BAD <<
|
||||
BlockShift);
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read the spare bytes to check for bad block
|
||||
* pattern
|
||||
*/
|
||||
for(Length = 0; Length <
|
||||
InstancePtr->BbPattern.Length; Length++) {
|
||||
if (Buf[InstancePtr->BbPattern.Offset + Length]
|
||||
!=
|
||||
InstancePtr->BbPattern.Pattern[Length])
|
||||
{
|
||||
/* Bad block found */
|
||||
InstancePtr->Bbt[BlockOffset] |=
|
||||
(XNANDPS_BLOCK_FACTORY_BAD <<
|
||||
BlockShift);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function reads the Bad Block Table(BBT) if present in flash. If not it
|
||||
* scans the flash for detecting factory marked bad blocks and creates a bad
|
||||
* block table and write the Bad Block Table(BBT) into the flash.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XNandPs_ScanBbt(XNandPs *InstancePtr)
|
||||
{
|
||||
int Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
|
||||
if (XNandPs_ReadBbt(InstancePtr) != XST_SUCCESS) {
|
||||
/*
|
||||
* Create memory based Bad Block Table(BBT)
|
||||
*/
|
||||
XNandPs_CreateBbt(InstancePtr);
|
||||
|
||||
/*
|
||||
* Write the Bad Block Table(BBT) to the flash
|
||||
*/
|
||||
Status = XNandPs_WriteBbt(InstancePtr,
|
||||
&InstancePtr->BbtDesc,
|
||||
&InstancePtr->BbtMirrorDesc);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the Mirror Bad Block Table(BBT) to the flash
|
||||
*/
|
||||
Status = XNandPs_WriteBbt(InstancePtr,
|
||||
&InstancePtr->BbtMirrorDesc,
|
||||
&InstancePtr->BbtDesc);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark the blocks containing Bad Block Table(BBT) as Reserved
|
||||
*/
|
||||
XNandPs_MarkBbt(InstancePtr, &InstancePtr->BbtDesc);
|
||||
XNandPs_MarkBbt(InstancePtr, &InstancePtr->BbtMirrorDesc);
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function converts the Bad Block Table(BBT) read from the flash to the RAM
|
||||
* based Bad Block Table(BBT).
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
* @param Buf is the buffer which contains BBT read from flash.
|
||||
*
|
||||
* @return
|
||||
* - NONE.
|
||||
*
|
||||
******************************************************************************/
|
||||
static void XNandPs_ConvertBbt(XNandPs *InstancePtr, u8 *Buf)
|
||||
{
|
||||
u32 BlockOffset;
|
||||
u32 BlockShift;
|
||||
u32 Data;
|
||||
u8 BlockType;
|
||||
u32 BlockIndex;
|
||||
u32 BbtLen = InstancePtr->Geometry.NumBlocks >>
|
||||
XNANDPS_BBT_BLOCK_SHIFT;
|
||||
|
||||
for(BlockOffset = 0; BlockOffset < BbtLen; BlockOffset++) {
|
||||
Data = Buf[BlockOffset];
|
||||
|
||||
/*
|
||||
* Clear the RAM based Bad Block Table(BBT) contents
|
||||
*/
|
||||
InstancePtr->Bbt[BlockOffset] = 0x0;
|
||||
|
||||
/*
|
||||
* Loop through the every 4 blocks in the bitmap
|
||||
*/
|
||||
for(BlockIndex = 0; BlockIndex < XNANDPS_BBT_ENTRY_NUM_BLOCKS;
|
||||
BlockIndex++) {
|
||||
BlockShift = XNandPs_BbtBlockShift(BlockIndex);
|
||||
BlockType = (Data >> BlockShift) &
|
||||
XNANDPS_BLOCK_TYPE_MASK;
|
||||
switch(BlockType) {
|
||||
case XNANDPS_FLASH_BLOCK_FACTORY_BAD:
|
||||
/* Factory bad block */
|
||||
InstancePtr->Bbt[BlockOffset] |=
|
||||
XNANDPS_BLOCK_FACTORY_BAD <<
|
||||
BlockShift;
|
||||
break;
|
||||
case XNANDPS_FLASH_BLOCK_RESERVED:
|
||||
/* Reserved block */
|
||||
InstancePtr->Bbt[BlockOffset] |=
|
||||
XNANDPS_BLOCK_RESERVED <<
|
||||
BlockShift;
|
||||
break;
|
||||
case XNANDPS_FLASH_BLOCK_BAD:
|
||||
/* Bad block due to wear */
|
||||
InstancePtr->Bbt[BlockOffset] |=
|
||||
XNANDPS_BLOCK_BAD <<
|
||||
BlockShift;
|
||||
break;
|
||||
default:
|
||||
/* Good block */
|
||||
/* The BBT entry already defaults to
|
||||
* zero */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function searches the Bad Bloock Table(BBT) in flash and loads into the
|
||||
* memory based Bad Block Table(BBT).
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int XNandPs_ReadBbt(XNandPs *InstancePtr)
|
||||
{
|
||||
u64 Offset;
|
||||
u8 Buf[XNANDPS_MAX_BLOCKS >> XNANDPS_BBT_BLOCK_SHIFT];
|
||||
u32 Status1;
|
||||
u32 Status2;
|
||||
u32 Status;
|
||||
u32 BbtLen;
|
||||
|
||||
XNandPs_BbtDesc *Desc = &InstancePtr->BbtDesc;
|
||||
XNandPs_BbtDesc *MirrorDesc = &InstancePtr->BbtMirrorDesc;
|
||||
BbtLen = InstancePtr->Geometry.NumBlocks >> XNANDPS_BBT_BLOCK_SHIFT;
|
||||
|
||||
/*
|
||||
* Search the Bad Block Table(BBT) in flash
|
||||
*/
|
||||
Status1 = XNandPs_SearchBbt(InstancePtr, Desc);
|
||||
Status2 = XNandPs_SearchBbt(InstancePtr, MirrorDesc);
|
||||
if ((Status1 != XST_SUCCESS) && (Status2 != XST_SUCCESS)) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bad Block Table found
|
||||
*/
|
||||
if (Desc->Valid && MirrorDesc->Valid) {
|
||||
/*
|
||||
* Valid BBT & Mirror BBT found
|
||||
*/
|
||||
if (Desc->Version > MirrorDesc->Version) {
|
||||
Offset = Desc->PageOffset *
|
||||
InstancePtr->Geometry.BytesPerPage;
|
||||
XNandPs_Read(InstancePtr, Offset, BbtLen, &Buf, NULL);
|
||||
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
*/
|
||||
XNandPs_ConvertBbt(InstancePtr, &Buf[0]);
|
||||
MirrorDesc->Version = Desc->Version;
|
||||
|
||||
/*
|
||||
* Write the BBT to Mirror BBT location in flash
|
||||
*/
|
||||
Status = XNandPs_WriteBbt(InstancePtr, MirrorDesc,
|
||||
Desc);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
} else if (Desc->Version < MirrorDesc->Version) {
|
||||
Offset = MirrorDesc->PageOffset *
|
||||
InstancePtr->Geometry.BytesPerPage;
|
||||
XNandPs_Read(InstancePtr, Offset, BbtLen, &Buf, NULL);
|
||||
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
*/
|
||||
XNandPs_ConvertBbt(InstancePtr, &Buf[0]);
|
||||
Desc->Version = MirrorDesc->Version;
|
||||
|
||||
/*
|
||||
* Write the Mirror BBT to BBT location in flash
|
||||
*/
|
||||
Status = XNandPs_WriteBbt(InstancePtr, Desc,
|
||||
MirrorDesc);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
/* Both are up-to-date */
|
||||
Offset = Desc->PageOffset *
|
||||
InstancePtr->Geometry.BytesPerPage;
|
||||
XNandPs_Read(InstancePtr, Offset, BbtLen, &Buf, NULL);
|
||||
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
*/
|
||||
XNandPs_ConvertBbt(InstancePtr, &Buf[0]);
|
||||
}
|
||||
} else if (Desc->Valid) {
|
||||
/*
|
||||
* Valid Primary BBT found
|
||||
*/
|
||||
Offset = Desc->PageOffset * InstancePtr->Geometry.BytesPerPage;
|
||||
XNandPs_Read(InstancePtr, Offset, BbtLen, &Buf, NULL);
|
||||
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
*/
|
||||
XNandPs_ConvertBbt(InstancePtr, &Buf[0]);
|
||||
MirrorDesc->Version = Desc->Version;
|
||||
|
||||
/*
|
||||
* Write the BBT to Mirror BBT location in flash
|
||||
*/
|
||||
Status = XNandPs_WriteBbt(InstancePtr, MirrorDesc, Desc);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Valid Mirror BBT found
|
||||
*/
|
||||
Offset = MirrorDesc->PageOffset *
|
||||
InstancePtr->Geometry.BytesPerPage;
|
||||
XNandPs_Read(InstancePtr, Offset, BbtLen, &Buf, NULL);
|
||||
|
||||
/*
|
||||
* Convert flash BBT to memory based BBT
|
||||
*/
|
||||
XNandPs_ConvertBbt(InstancePtr, &Buf[0]);
|
||||
Desc->Version = MirrorDesc->Version;
|
||||
|
||||
/*
|
||||
* Write the Mirror BBT to BBT location in flash
|
||||
*/
|
||||
Status = XNandPs_WriteBbt(InstancePtr, Desc, MirrorDesc);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function searches the BBT in flash.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @param Desc is the BBT descriptor pattern to search.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int XNandPs_SearchBbt(XNandPs *InstancePtr, XNandPs_BbtDesc *Desc)
|
||||
{
|
||||
u32 StartBlock;
|
||||
u32 SigOffset;
|
||||
u32 VerOffset;
|
||||
u32 MaxBlocks;
|
||||
u32 PageOff;
|
||||
u32 SigLength;
|
||||
u8 Buf[XNANDPS_MAX_SPARE_SIZE];
|
||||
u32 Block;
|
||||
u32 Offset;
|
||||
int Status;
|
||||
|
||||
StartBlock = InstancePtr->Geometry.NumBlocks - 1;
|
||||
SigOffset = Desc->SigOffset;
|
||||
VerOffset = Desc->VerOffset;
|
||||
MaxBlocks = Desc->MaxBlocks;
|
||||
SigLength = Desc->SigLength;
|
||||
|
||||
/*
|
||||
* Read the last 4 blocks for Bad Block Table(BBT) signature
|
||||
*/
|
||||
for(Block = 0; Block < MaxBlocks; Block++) {
|
||||
PageOff = (StartBlock - Block) *
|
||||
InstancePtr->Geometry.PagesPerBlock;
|
||||
|
||||
Status = XNandPs_ReadSpareBytes(InstancePtr, PageOff, &Buf[0]);
|
||||
if (Status != XST_SUCCESS) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check the Bad Block Table(BBT) signature
|
||||
*/
|
||||
for(Offset = 0; Offset < SigLength; Offset++) {
|
||||
if (Buf[Offset + SigOffset] != Desc->Signature[Offset])
|
||||
{
|
||||
break; /* Check the next blocks */
|
||||
}
|
||||
}
|
||||
if (Offset >= SigLength) {
|
||||
/*
|
||||
* Bad Block Table(BBT) found
|
||||
*/
|
||||
Desc->PageOffset = PageOff;
|
||||
Desc->Version = Buf[VerOffset];
|
||||
Desc->Valid = 1;
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Bad Block Table(BBT) not found
|
||||
*/
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function writes Bad Block Table(BBT) from RAM to flash.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @param Desc is the BBT descriptor to be written to flash.
|
||||
* @param MirrorDesc is the mirror BBT descriptor.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int XNandPs_WriteBbt(XNandPs *InstancePtr, XNandPs_BbtDesc *Desc,
|
||||
XNandPs_BbtDesc *MirrorDesc)
|
||||
{
|
||||
u64 Offset;
|
||||
u32 Block = InstancePtr->Geometry.NumBlocks - 1;
|
||||
u8 Buf[XNANDPS_MAX_BLOCKS >> XNANDPS_BBT_BLOCK_SHIFT];
|
||||
u8 SpareBuf[XNANDPS_MAX_SPARE_SIZE];
|
||||
u8 Mask[4] = {0x00, 0x01, 0x02, 0x03};
|
||||
u8 Data;
|
||||
u32 BlockOffset;
|
||||
u32 BlockShift;
|
||||
u32 Status;
|
||||
u32 BlockIndex;
|
||||
u32 Index;
|
||||
u8 BlockType;
|
||||
u32 BbtLen = InstancePtr->Geometry.NumBlocks >>
|
||||
XNANDPS_BBT_BLOCK_SHIFT;
|
||||
|
||||
/*
|
||||
* Find a valid block to write the Bad Block Table(BBT)
|
||||
*/
|
||||
if (!Desc->Valid) {
|
||||
for(Index = 0; Index < Desc->MaxBlocks; Index++) {
|
||||
Block = (Block - Index);
|
||||
BlockOffset = Block >> XNANDPS_BBT_BLOCK_SHIFT;
|
||||
BlockShift = XNandPs_BbtBlockShift(Block);
|
||||
BlockType = (InstancePtr->Bbt[BlockOffset] >>
|
||||
BlockShift) & XNANDPS_BLOCK_TYPE_MASK;
|
||||
switch(BlockType)
|
||||
{
|
||||
case XNANDPS_BLOCK_BAD:
|
||||
case XNANDPS_BLOCK_FACTORY_BAD:
|
||||
continue;
|
||||
default:
|
||||
/* Good Block */
|
||||
break;
|
||||
}
|
||||
Desc->PageOffset = Block *
|
||||
InstancePtr->Geometry.PagesPerBlock;
|
||||
if (Desc->PageOffset != MirrorDesc->PageOffset) {
|
||||
/* Free block found */
|
||||
Desc->Valid = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Block not found for writing Bad Block Table(BBT)
|
||||
*/
|
||||
if (Index >= Desc->MaxBlocks) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
} else {
|
||||
Block = Desc->PageOffset/InstancePtr->Geometry.PagesPerBlock;
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert the memory based BBT to flash based table
|
||||
*/
|
||||
memset(Buf, 0xff, BbtLen);
|
||||
|
||||
/*
|
||||
* Loop through the number of blocks
|
||||
*/
|
||||
for(BlockOffset = 0; BlockOffset < BbtLen; BlockOffset++) {
|
||||
Data = InstancePtr->Bbt[BlockOffset];
|
||||
/*
|
||||
* Calculate the bit mask for 4 blocks at a time in loop
|
||||
*/
|
||||
for(BlockIndex = 0; BlockIndex < XNANDPS_BBT_ENTRY_NUM_BLOCKS;
|
||||
BlockIndex++) {
|
||||
BlockShift = XNandPs_BbtBlockShift(BlockIndex);
|
||||
Buf[BlockOffset] &= ~(Mask[Data &
|
||||
XNANDPS_BLOCK_TYPE_MASK] <<
|
||||
BlockShift);
|
||||
Data >>= XNANDPS_BBT_BLOCK_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the Bad Block Table(BBT) to flash
|
||||
*/
|
||||
Status = XNandPs_EraseBlock(InstancePtr, Block);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write the signature and version in the spare data area
|
||||
*/
|
||||
memset(SpareBuf, 0xff, InstancePtr->Geometry.SpareBytesPerPage);
|
||||
memcpy(SpareBuf + Desc->SigOffset, &Desc->Signature[0],
|
||||
Desc->SigLength);
|
||||
memcpy(SpareBuf + Desc->VerOffset, &Desc->Version, 1);
|
||||
|
||||
/*
|
||||
* Write the BBT to page offset
|
||||
*/
|
||||
Offset = Desc->PageOffset * InstancePtr->Geometry.BytesPerPage;
|
||||
Status = XNandPs_Write(InstancePtr, Offset, BbtLen, &Buf[0], SpareBuf);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function updates the primary and mirror Bad Block Table(BBT) in the
|
||||
* flash.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int XNandPs_UpdateBbt(XNandPs *InstancePtr)
|
||||
{
|
||||
int Status;
|
||||
u8 Version;
|
||||
|
||||
/*
|
||||
* Update the version number
|
||||
*/
|
||||
Version = InstancePtr->BbtDesc.Version;
|
||||
InstancePtr->BbtDesc.Version = (Version + 1) % 256;
|
||||
Version = InstancePtr->BbtMirrorDesc.Version;
|
||||
InstancePtr->BbtMirrorDesc.Version = (Version + 1) % 256;
|
||||
|
||||
/*
|
||||
* Update the primary Bad Block Table(BBT) in flash
|
||||
*/
|
||||
Status = XNandPs_WriteBbt(InstancePtr, &InstancePtr->BbtDesc,
|
||||
&InstancePtr->BbtMirrorDesc);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the mirrored Bad Block Table(BBT) in flash
|
||||
*/
|
||||
Status = XNandPs_WriteBbt(InstancePtr, &InstancePtr->BbtMirrorDesc,
|
||||
&InstancePtr->BbtDesc);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function marks the block containing Bad Block Table as reserved
|
||||
* and updates the BBT.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @param Desc is the BBT descriptor pointer.
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int XNandPs_MarkBbt(XNandPs* InstancePtr, XNandPs_BbtDesc *Desc)
|
||||
{
|
||||
u32 BlockIndex;
|
||||
u32 BlockOffset;
|
||||
u8 BlockShift;
|
||||
u8 OldVal;
|
||||
u8 NewVal;
|
||||
int Status;
|
||||
u32 UpdateBbt = 0;
|
||||
u32 Index;
|
||||
|
||||
/*
|
||||
* Mark the last four blocks as Reserved
|
||||
*/
|
||||
BlockIndex = InstancePtr->Geometry.NumBlocks - Desc->MaxBlocks - 1;
|
||||
|
||||
for(Index = 0; Index < Desc->MaxBlocks; Index++,BlockIndex++) {
|
||||
|
||||
BlockOffset = BlockIndex >> XNANDPS_BBT_BLOCK_SHIFT;
|
||||
BlockShift = XNandPs_BbtBlockShift(BlockIndex);
|
||||
OldVal = InstancePtr->Bbt[BlockOffset];
|
||||
NewVal = OldVal | (XNANDPS_BLOCK_RESERVED << BlockShift);
|
||||
InstancePtr->Bbt[BlockOffset] = NewVal;
|
||||
|
||||
if (OldVal != NewVal) {
|
||||
UpdateBbt = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Update the BBT to flash
|
||||
*/
|
||||
if (UpdateBbt) {
|
||||
Status = XNandPs_UpdateBbt(InstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function checks whether a block is bad or not.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
*
|
||||
* @param Block is the block number.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XNandPs_IsBlockBad(XNandPs *InstancePtr, u32 Block)
|
||||
{
|
||||
u8 Data;
|
||||
u8 BlockShift;
|
||||
u8 BlockType;
|
||||
u32 BlockOffset;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks);
|
||||
|
||||
BlockOffset = Block >> XNANDPS_BBT_BLOCK_SHIFT;
|
||||
BlockShift = XNandPs_BbtBlockShift(Block);
|
||||
Data = InstancePtr->Bbt[BlockOffset]; /* Block information in BBT */
|
||||
BlockType = (Data >> BlockShift) & XNANDPS_BLOCK_TYPE_MASK;
|
||||
|
||||
if (BlockType != XNANDPS_BLOCK_GOOD)
|
||||
return XST_SUCCESS;
|
||||
else
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
* This function marks a block as bad in the RAM based Bad Block Table(BBT). It
|
||||
* also updates the Bad Block Table(BBT) in the flash.
|
||||
*
|
||||
* @param InstancePtr is the pointer to the XNandPs instance.
|
||||
* @param Block is the block number.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if fail.
|
||||
*
|
||||
******************************************************************************/
|
||||
int XNandPs_MarkBlockBad(XNandPs *InstancePtr, u32 Block)
|
||||
{
|
||||
u8 Data;
|
||||
u8 BlockShift;
|
||||
u32 BlockOffset;
|
||||
u8 OldVal;
|
||||
u8 NewVal;
|
||||
u32 Status;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
Xil_AssertNonvoid(InstancePtr->IsReady == XIL_COMPONENT_IS_READY);
|
||||
Xil_AssertNonvoid(Block < InstancePtr->Geometry.NumBlocks);
|
||||
|
||||
BlockOffset = Block >> XNANDPS_BBT_BLOCK_SHIFT;
|
||||
BlockShift = XNandPs_BbtBlockShift(Block);
|
||||
Data = InstancePtr->Bbt[BlockOffset]; /* Block information in BBT */
|
||||
|
||||
/*
|
||||
* Mark the block as bad in the RAM based Bad Block Table
|
||||
*/
|
||||
OldVal = Data;
|
||||
Data &= ~(XNANDPS_BLOCK_TYPE_MASK << BlockShift);
|
||||
Data |= (XNANDPS_BLOCK_BAD << BlockShift);
|
||||
NewVal = Data;
|
||||
InstancePtr->Bbt[BlockOffset] = Data;
|
||||
|
||||
/*
|
||||
* Update the Bad Block Table(BBT) in flash
|
||||
*/
|
||||
if (OldVal != NewVal) {
|
||||
Status = XNandPs_UpdateBbt(InstancePtr);
|
||||
if (Status != XST_SUCCESS) {
|
||||
return Status;
|
||||
}
|
||||
}
|
||||
return XST_SUCCESS;
|
||||
}
|
185
XilinxProcessorIPLib/drivers/nandps/src/xnandps_bbm.h
Executable file
185
XilinxProcessorIPLib/drivers/nandps/src/xnandps_bbm.h
Executable file
|
@ -0,0 +1,185 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xnandps_bbm.h
|
||||
*
|
||||
* This file implements the Bad Block Management(BBM) functionality. This is
|
||||
* similar to the Bad Block Management which is a part of the MTD subsystem in
|
||||
* Linux. The factory marked bad blocks are scanned initially and a Bad Block
|
||||
* Table(BBT) is created in the memory. This table is also written to the flash
|
||||
* so that upon reboot, the BBT is read back from the flash and loaded into the
|
||||
* memory instead of scanning every time. The Bad Block Table(BBT) is written
|
||||
* into one of the the last four blocks in the flash memory. The last four
|
||||
* blocks are marked as Reserved so that user can't erase/program those blocks.
|
||||
*
|
||||
* There are two bad block tables, a primary table and a mirror table. The
|
||||
* tables are versioned and incrementing version number is used to detect and
|
||||
* recover from interrupted updates. Each table is stored in a separate block,
|
||||
* beginning in the first page of that block. Only two blocks would be necessary
|
||||
* in the absence of bad blocks within the last four; the range of four provides
|
||||
* a little slack in case one or two of those blocks is bad. These blocks are
|
||||
* marked as reserved and cannot be programmed by the user. A NAND Flash device
|
||||
* with 3 or more factory bad blocks in the last 4 cannot be used. The bad block
|
||||
* table signature is written into the spare data area of the pages containing
|
||||
* bad block table so that upon rebooting the bad block table signature is
|
||||
* searched and the bad block table is loaded into RAM. The signature is "Bbt0"
|
||||
* for primary Bad Block Table and "1tbB" for Mirror Bad Block Table. The
|
||||
* version offset follows the signature offset in the spare data area. The
|
||||
* version number increments on every update to the bad block table and the
|
||||
* version wraps at 0xff.
|
||||
*
|
||||
* Each block in the Bad Block Table(BBT) is represented by 2 bits.
|
||||
* The two bits are encoded as follows in RAM BBT.
|
||||
* 0'b00 -> Good Block
|
||||
* 0'b01 -> Block is bad due to wear
|
||||
* 0'b10 -> Reserved block
|
||||
* 0'b11 -> Factory marked bad block
|
||||
*
|
||||
* While writing to the flash the two bits are encoded as follows.
|
||||
* 0'b00 -> Factory marked bad block
|
||||
* 0'b01 -> Reserved block
|
||||
* 0'b10 -> Block is bad due to wear
|
||||
* 0'b11 -> Good Block
|
||||
*
|
||||
* The user can check for the validity of the block using the API
|
||||
* XNandPs_IsBlockBad and take the action based on the return value. Also user
|
||||
* can update the bad block table using XNandPs_MarkBlockBad API.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00a nm 12/10/2010 First release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef BBM_H /* prevent circular inclusions */
|
||||
#define BBM_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xnandps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
/*
|
||||
* Block definitions for RAM based Bad Block Table (BBT)
|
||||
*/
|
||||
#define XNANDPS_BLOCK_GOOD 0x0 /**< Block is good */
|
||||
#define XNANDPS_BLOCK_BAD 0x1 /**< Block is bad */
|
||||
#define XNANDPS_BLOCK_RESERVED 0x2 /**< Reserved block */
|
||||
#define XNANDPS_BLOCK_FACTORY_BAD 0x3 /**< Factory marked bad
|
||||
block */
|
||||
/*
|
||||
* Block definitions for FLASH based Bad Block Table (BBT)
|
||||
*/
|
||||
#define XNANDPS_FLASH_BLOCK_GOOD 0x3 /**< Block is good */
|
||||
#define XNANDPS_FLASH_BLOCK_BAD 0x2 /**< Block is bad */
|
||||
#define XNANDPS_FLASH_BLOCK_RESERVED 0x1 /**< Reserved block */
|
||||
#define XNANDPS_FLASH_BLOCK_FACTORY_BAD 0x0 /**< Factory marked bad
|
||||
block */
|
||||
|
||||
#define XNANDPS_BBT_SCAN_2ND_PAGE 0x00000001 /**< Scan the
|
||||
second page
|
||||
for bad block
|
||||
information
|
||||
*/
|
||||
#define XNANDPS_BBT_DESC_PAGE_OFFSET 0 /**< Page offset of Bad
|
||||
Block Table Desc */
|
||||
#define XNANDPS_BBT_DESC_SIG_OFFSET 8 /**< Bad Block Table
|
||||
signature offset */
|
||||
#define XNANDPS_BBT_DESC_VER_OFFSET 12 /**< Bad block Table
|
||||
version offset */
|
||||
#define XNANDPS_BBT_DESC_SIG_LEN 4 /**< Bad block Table
|
||||
signature length */
|
||||
#define XNANDPS_BBT_DESC_MAX_BLOCKS 4 /**< Bad block Table
|
||||
max blocks */
|
||||
|
||||
#define XNANDPS_BBT_BLOCK_SHIFT 2 /**< Block shift value
|
||||
for a block in BBT */
|
||||
#define XNANDPS_BBT_ENTRY_NUM_BLOCKS 4 /**< Num of blocks in
|
||||
one BBT entry */
|
||||
#define XNANDPS_BB_PATTERN_OFFSET_SMALL_PAGE 5 /**< Bad block pattern
|
||||
offset in a page */
|
||||
#define XNANDPS_BB_PATTERN_LENGTH_SMALL_PAGE 1 /**< Bad block pattern
|
||||
length */
|
||||
#define XNANDPS_BB_PATTERN_OFFSET_LARGE_PAGE 0 /**< Bad block pattern
|
||||
offset in a large
|
||||
page */
|
||||
#define XNANDPS_BB_PATTERN_LENGTH_LARGE_PAGE 2 /**< Bad block pattern
|
||||
length */
|
||||
#define XNANDPS_BB_PATTERN 0xFF /**< Bad block pattern
|
||||
to search in a page
|
||||
*/
|
||||
#define XNANDPS_BLOCK_TYPE_MASK 0x03 /**< Block type mask */
|
||||
#define XNANDPS_BLOCK_SHIFT_MASK 0x06 /**< Block shift mask
|
||||
for a Bad Block Table
|
||||
entry byte */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This macro returns the Block shift value corresponding to a Block.
|
||||
*
|
||||
* @param Block is the block number.
|
||||
*
|
||||
* @return Block shift value
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
*****************************************************************************/
|
||||
#define XNandPs_BbtBlockShift(Block) \
|
||||
((Block * 2) & XNANDPS_BLOCK_SHIFT_MASK)
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
int XNandPs_IsBlockBad(XNandPs *InstancePtr, u32 Block);
|
||||
int XNandPs_MarkBlockBad(XNandPs *InstancePtr, u32 Block);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
84
XilinxProcessorIPLib/drivers/nandps/src/xnandps_g.c
Executable file
84
XilinxProcessorIPLib/drivers/nandps/src/xnandps_g.c
Executable file
|
@ -0,0 +1,84 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xnandps_g.c
|
||||
*
|
||||
* This file contains a configuration table that specifies the configuration
|
||||
* of NAND flash devices in the system.
|
||||
*
|
||||
* See xnandps.h for more information about this driver.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00a nm 12/10/2010 First release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xnandps.h"
|
||||
#include "xparameters.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Prototypes ******************************/
|
||||
|
||||
/**
|
||||
* This table contains configuration information for each System Monitor/ADC
|
||||
* device in the system.
|
||||
*/
|
||||
XNandPs_Config XNandPs_ConfigTable[XPAR_XNANDPS_NUM_INSTANCES] =
|
||||
{
|
||||
{
|
||||
XPAR_XNANDPS_0_DEVICE_ID, /**< Device ID of device */
|
||||
XPAR_XPARPORTPS_CTRL_BASEADDR, /**< SMC Base address
|
||||
0xE000E000 */
|
||||
XPAR_XNANDPS_0_BASEADDR, /**< NAND flash Base address
|
||||
0xE1000000 */
|
||||
XPAR_XNANDPS_0_FLASH_WIDTH /**< Flash data width */
|
||||
}
|
||||
};
|
570
XilinxProcessorIPLib/drivers/nandps/src/xnandps_hw.h
Executable file
570
XilinxProcessorIPLib/drivers/nandps/src/xnandps_hw.h
Executable file
|
@ -0,0 +1,570 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xnandps_hw.h
|
||||
*
|
||||
* This file contains identifiers and low-level macros/functions for the NAND
|
||||
* Flash controller driver.
|
||||
* See xnandps.h for more information.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00a nm 12/10/2010 First release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
#ifndef XNANDPS_HW_H /* prevent circular inclusions */
|
||||
#define XNANDPS_HW_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/*
|
||||
* Memory controller configuration register offset
|
||||
*/
|
||||
#define XNANDPS_MEMC_STATUS_OFFSET 0x000 /**< Controller status
|
||||
reg, RO */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_OFFSET 0x004 /**< Interface config
|
||||
reg, RO */
|
||||
#define XNANDPS_MEMC_SET_CONFIG_OFFSET 0x008 /**< Set configuration
|
||||
reg, WO */
|
||||
#define XNANDPS_MEMC_CLR_CONFIG_OFFSET 0x00C /**< Clear config reg,
|
||||
WO */
|
||||
#define XNANDPS_DIRECT_CMD_OFFSET 0x010 /**< Direct command
|
||||
reg, WO */
|
||||
#define XNANDPS_SET_CYCLES_OFFSET 0x014 /**< Set cycles
|
||||
register, WO */
|
||||
#define XNANDPS_SET_OPMODE_OFFSET 0x018 /**< Set opmode
|
||||
register, WO */
|
||||
#define XNANDPS_REFRESH_PERIOD_0_OFFSET 0x020 /**< Refresh period_0
|
||||
reg, RW */
|
||||
#define XNANDPS_REFRESH_PERIOD_1_OFFSET 0x024 /**< Refresh period_1
|
||||
reg, RW */
|
||||
|
||||
/*
|
||||
* Chip configuration register offset
|
||||
*/
|
||||
#define XNANDPS_IF0_CHIP_0_CONFIG_OFFSET 0x100 /**< Interface 0 chip 0
|
||||
config */
|
||||
#define XNANDPS_IF0_CHIP_1_CONFIG_OFFSET 0x120 /**< Interface 0 chip 1
|
||||
config */
|
||||
#define XNANDPS_IF0_CHIP_2_CONFIG_OFFSET 0x140 /**< Interface 0 chip 2
|
||||
config */
|
||||
#define XNANDPS_IF0_CHIP_3_CONFIG_OFFSET 0x160 /**< Interface 0 chip 3
|
||||
config */
|
||||
#define XNANDPS_IF1_CHIP_0_CONFIG_OFFSET 0x180 /**< Interface 1 chip 0
|
||||
config */
|
||||
#define XNANDPS_IF1_CHIP_1_CONFIG_OFFSET 0x1A0 /**< Interface 1 chip 1
|
||||
config */
|
||||
#define XNANDPS_IF1_CHIP_2_CONFIG_OFFSET 0x1C0 /**< Interface 1 chip 2
|
||||
config */
|
||||
#define XNANDPS_IF1_CHIP_3_CONFIG_OFFSET 0x1E0 /**< Interface 1 chip 3
|
||||
config */
|
||||
|
||||
/*
|
||||
* nand_cycles (RO), sram_cycles (RO) and opmode_x_n (RO) registers offsets
|
||||
*/
|
||||
#define XNANDPS_FLASH_CYCLES(addr) (0x000 + addr) /**< NAND & SRAM
|
||||
cycle,RO*/
|
||||
#define XNANDPS_OPMODE(addr) (0x004 + addr) /**< Chip opmode
|
||||
reg, RO */
|
||||
|
||||
/*
|
||||
* User configuration register offset
|
||||
*/
|
||||
#define XNANDPS_USER_STATUS_OFFSET 0x200 /**< User status reg,
|
||||
RO */
|
||||
#define XNANDPS_USER_CONFIG_OFFSET 0x204 /**< User config reg,
|
||||
WO */
|
||||
|
||||
/*
|
||||
* ECC register offset
|
||||
*/
|
||||
#define XNANDPS_IF0_ECC_OFFSET 0x300 /**< Interface 0 ECC
|
||||
register */
|
||||
#define XNANDPS_IF1_ECC_OFFSET 0x400 /**< Interface 1 ECC
|
||||
register */
|
||||
#define XNANDPS_ECC_STATUS_OFFSET(addr) (0x000 + addr) /**< ECC status
|
||||
register */
|
||||
#define XNANDPS_ECC_MEMCFG_OFFSET(addr) (0x004 + addr) /**< ECC mem
|
||||
config reg */
|
||||
#define XNANDPS_ECC_MEMCMD1_OFFSET(addr) (0x008 + addr) /**< ECC mem
|
||||
com1 reg*/
|
||||
#define XNANDPS_ECC_MEMCMD2_OFFSET(addr) (0x00C + addr) /**< ECC mem
|
||||
com2 reg*/
|
||||
#define XNANDPS_ECC_ADDR0_OFFSET(addr) (0x010 + addr) /**< ECC
|
||||
address0 reg
|
||||
*/
|
||||
#define XNANDPS_ECC_ADDR1_OFFSET(addr) (0x014 + addr) /**< ECC
|
||||
address1 reg
|
||||
*/
|
||||
#define XNANDPS_ECC_VALUE0_OFFSET(addr) (0x018 + addr) /**< ECC value 0
|
||||
reg */
|
||||
#define XNANDPS_ECC_VALUE1_OFFSET(addr) (0x01C + addr) /**< ECC value 1
|
||||
reg */
|
||||
#define XNANDPS_ECC_VALUE2_OFFSET(addr) (0x020 + addr) /**< ECC value 2
|
||||
reg */
|
||||
#define XNANDPS_ECC_VALUE3_OFFSET(addr) (0x024 + addr) /**< ECC value 3
|
||||
reg */
|
||||
#define XNANDPS_ECC_VALUE4_OFFSET(addr) (0x028 + addr) /**< ECC value 4
|
||||
reg */
|
||||
|
||||
/*
|
||||
* Integration test register offset
|
||||
*/
|
||||
#define XNANDPS_INTGTEST_OFFSET 0xE00 /**< Integration test
|
||||
offset */
|
||||
|
||||
/*
|
||||
* ID configuration register offset
|
||||
*/
|
||||
#define XNANDPS_PERIPH_ID0_OFFSET 0xFE0 /**< Peripheral id0
|
||||
register */
|
||||
#define XNANDPS_PERIPH_ID1_OFFSET 0xFE4 /**< Peripheral id1
|
||||
register */
|
||||
#define XNANDPS_PERIPH_ID2_OFFSET 0xFE8 /**< Peripheral id2
|
||||
register */
|
||||
#define XNANDPS_PERIPH_ID3_OFFSET 0xFEC /**< Peripheral id3
|
||||
register */
|
||||
#define XNANDPS_PCELL_ID0_OFFSET 0xFF0 /**< Primecell id0
|
||||
register */
|
||||
#define XNANDPS_PCELL_ID1_OFFSET 0xFF4 /**< Primecell id1
|
||||
register */
|
||||
#define XNANDPS_PCELL_ID2_OFFSET 0xFF8 /**< Primecell id2
|
||||
register */
|
||||
#define XNANDPS_PCELL_ID3_OFFSET 0xFFC /**< Primecell id3
|
||||
register */
|
||||
|
||||
/** @name Memory controller status register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_MEMC_STATUS_STATE_MASK 0x00000001 /**< Memory
|
||||
controller operating state mask */
|
||||
#define XNANDPS_MEMC_STATUS_INT_EN0_MASK 0x00000002 /**< Memory
|
||||
controller interface 0 interrupt enable mask */
|
||||
#define XNANDPS_MEMC_STATUS_INT_EN1_MASK 0x00000004 /**< Memory
|
||||
controller interface 1 interrupt enable mask */
|
||||
#define XNANDPS_MEMC_STATUS_INT_STATUS0_MASK 0x00000008 /**< Memory
|
||||
controller interface 0 interrupt status mask */
|
||||
#define XNANDPS_MEMC_STATUS_INT_STATUS1_MASK 0x00000010 /**< Memory
|
||||
controller interface 1 interrupt status mask */
|
||||
#define XNANDPS_MEMC_STATUS_RAW_INT_STATUS0_MASK 0x00000020 /**< Memory
|
||||
controller interface 0 raw interrupt status mask */
|
||||
#define XNANDPS_MEMC_STATUS_RAW_INT_STATUS1_MASK 0x00000040 /**< Memory
|
||||
controller interface 1 raw interrupt status mask */
|
||||
#define XNANDPS_MEMC_STATUS_ECC_INT_EN0_MASK 0x00000080 /**< Memory
|
||||
controller interface 0 ECC interrupt enable mask */
|
||||
#define XNANDPS_MEMC_STATUS_ECC_INT_EN1_MASK 0x00000100 /**< Memory
|
||||
controller interface 1 ECC interrupt enable mask */
|
||||
#define XNANDPS_MEMC_STATUS_ECC_INT0_MASK 0x00000200 /**< Memory
|
||||
controller interface 0 ECC interrupt status mask */
|
||||
#define XNANDPS_MEMC_STATUS_ECC_INT1_MASK 0x00000400 /**< Memory
|
||||
controller interface 1 ECC interrupt status mask */
|
||||
#define XNANDPS_MEMC_STATUS_RAW_ECC_INT0_MASK 0x00000800 /**< Memory
|
||||
controller interface 0 raw ECC interrupt status mask */
|
||||
#define XNANDPS_MEMC_STATUS_RAW_ECC_INT1_MASK 0x00001000 /**< Memory
|
||||
controller interface 1 raw ECC interrupt status mask */
|
||||
/* @} */
|
||||
|
||||
/** @name Memory interface configurartion register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_MEMC_IF_CONFIG_MEMORY_TYPE0_MASK 0x00000003 /**< Memory
|
||||
controller interface 0 type mask */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_MEMORY_CHIPS0_MASK 0x0000000C /**< Memory
|
||||
controller interface 0 chip select mask */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_MEMORY_WIDTH0_MASK 0x00000030 /**< Memory
|
||||
controller interface 0 data width mask */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_REMAP0_MASK 0x00000040 /**< Memory
|
||||
controller interface 0 remap0 mask */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_MEMORY_TYPE1_MASK 0x00000300 /**< Memory
|
||||
controller interface 1 type mask */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_MEMORY_CHIPS1_MASK 0x00000C00 /**< Memory
|
||||
controller interface 1 chip select mask */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_MEMORY_WIDTH1_MASK 0x00003000 /**< Memory
|
||||
controller interface 1 data width mask */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_REMAP1_MASK 0x00004000 /**< Memory
|
||||
controller interface 1 remap0 mask */
|
||||
#define XNANDPS_MEMC_IF_CONFIG_EX_MONITORS_MASK 0x00030000 /**< Memory
|
||||
controller interface exclusive masks mask */
|
||||
/* @} */
|
||||
|
||||
/** @name Set configuration register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_MEMC_SET_CONFIG_INT_ENABLE0_MASK 0x00000001 /**< Memory
|
||||
controller interfce0 interrupt enable mask */
|
||||
#define XNANDPS_MEMC_SET_CONFIG_INT_ENABLE1_MASK 0x00000002 /**< Memory
|
||||
controller interfce1 interrupt enable mask */
|
||||
#define XNANDPS_MEMC_SET_CONFIG_LOW_POWER_REQ_MASK 0x00000004 /**< Memory
|
||||
controller low power state mask */
|
||||
#define XNANDPS_MEMC_SET_CONFIG_ECC_INT_ENABLE0_MASK 0x00000020 /**< Memory
|
||||
controller interfce0 ECC interrupt enable mask */
|
||||
#define XNANDPS_MEMC_SET_CONFIG_ECC_INT_ENABLE1_MASK 0x00000040 /**< Memory
|
||||
controller interfce1 ECC interrupt enable mask */
|
||||
/* @} */
|
||||
|
||||
/** @name Clear configuration register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_MEMC_CLR_CONFIG_INT_DISABLE0_MASK 0x00000001 /**< Memory
|
||||
controller interface 0 interrupt disable mask */
|
||||
#define XNANDPS_MEMC_CLR_CONFIG_INT_DISABLE1_MASK 0x00000002 /**< Memory
|
||||
controller interface 1 interrupt disable mask */
|
||||
#define XNANDPS_MEMC_CLR_CONFIG_LOW_POWER_EXIT_MASK 0x00000004 /**< Memory
|
||||
controller low power exit mask */
|
||||
#define XNANDPS_MEMC_CLR_CONFIG_INT_CLR0_MASK 0x00000008 /**< Memory
|
||||
controller interface0 interrupt clear mask */
|
||||
#define XNANDPS_MEMC_CLR_CONFIG_INT_CLR1_MASK 0x00000010 /**< Memory
|
||||
controller interface1 interrupt clear mask */
|
||||
#define XNANDPS_MEMC_CLR_CONFIG_ECC_INT_DISABLE0_MASK 0x00000020 /**< Memory
|
||||
controller interface0 ECC interrupt disable mask */
|
||||
#define XNANDPS_MEMC_CLR_CONFIG_ECC_INT_DISABLE1_MASK 0x00000040 /**< Memory
|
||||
controller interface1 ECC interrupt disable mask */
|
||||
/* @} */
|
||||
|
||||
/** @name Clear configuration register bit definitions and masks and shift
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_DIRECT_CMD_ADDR_MASK 0x000FFFFF /**< Direct
|
||||
command address mask */
|
||||
#define XNANDPS_DIRECT_CMD_SET_CRE_MASK 0x00100000 /**< Direct
|
||||
command set cre mask */
|
||||
#define XNANDPS_DIRECT_CMD_TYPE_MASK 0x00600000 /**< Direct
|
||||
command type mask */
|
||||
#define XNANDPS_DIRECT_CMD_CHIP_SELECT_MASK 0x03800000 /**< Direct
|
||||
command chip select mask */
|
||||
|
||||
#define XNANDPS_DIRECT_CMD_SET_CRE_SHIFT 20 /**< Direct command
|
||||
set_cre shift */
|
||||
#define XNANDPS_DIRECT_CMD_CMD_TYPE_SHIFT 21 /**< Direct command
|
||||
cmd_type shift */
|
||||
#define XNANDPS_DIRECT_CMD_CHIP_SELECT_SHIFT 23 /**< Direct command
|
||||
chip select shift */
|
||||
/* @} */
|
||||
|
||||
/** @name Set cycles register bit definitions and masks and shift
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_SET_CYCLES_SET_T0_MASK 0x0000000F /**< Set
|
||||
cycles set_t0 mask */
|
||||
#define XNANDPS_SET_CYCLES_SET_T1_MASK 0x000000F0 /**< Set
|
||||
cycles set_t1 mask */
|
||||
#define XNANDPS_SET_CYCLES_SET_T2_MASK 0x00000700 /**< Set
|
||||
cycles set_t2 mask */
|
||||
#define XNANDPS_SET_CYCLES_SET_T3_MASK 0x00003800 /**< Set
|
||||
cycles set_t3 mask */
|
||||
#define XNANDPS_SET_CYCLES_SET_T4_MASK 0x0001C000 /**< Set
|
||||
cycles set_t4 mask */
|
||||
#define XNANDPS_SET_CYCLES_SET_T5_MASK 0x000E0000 /**< Set
|
||||
cycles set_t5 mask */
|
||||
#define XNANDPS_SET_CYCLES_SET_T6_MASK 0x00F00000 /**< Set
|
||||
cycles set_t6 mask */
|
||||
|
||||
#define XNANDPS_SET_CYCLES_SET_T0_SHIFT 0 /**< Set cycles set_t0
|
||||
shift */
|
||||
#define XNANDPS_SET_CYCLES_SET_T1_SHIFT 4 /**< Set cycles set_t1
|
||||
shift */
|
||||
#define XNANDPS_SET_CYCLES_SET_T2_SHIFT 8 /**< Set cycles set_t2
|
||||
shift */
|
||||
#define XNANDPS_SET_CYCLES_SET_T3_SHIFT 11 /**< Set cycles set_t3
|
||||
shift */
|
||||
#define XNANDPS_SET_CYCLES_SET_T4_SHIFT 14 /**< Set cycles set_t4
|
||||
shift */
|
||||
#define XNANDPS_SET_CYCLES_SET_T5_SHIFT 17 /**< Set cycles set_t5
|
||||
shift */
|
||||
#define XNANDPS_SET_CYCLES_SET_T6_SHIFT 20 /**< Set cycles set_t6
|
||||
shift */
|
||||
|
||||
/* @} */
|
||||
|
||||
/** @name Set opmode register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_SET_OPMODE_SET_MW_MASK 0x00000003 /**< Set
|
||||
opmode set memory width mask */
|
||||
#define XNANDPS_SET_OPMODE_SET_RD_SYNC_MASK 0x00000004 /**< Set
|
||||
opmode set rd_sync mask */
|
||||
#define XNANDPS_SET_OPMODE_SET_RD_BL_MASK 0x00000038 /**< Set
|
||||
opmode set rd_bl mask */
|
||||
#define XNANDPS_SET_OPMODE_SET_WR_SYNC_MASK 0x00000040 /**< Set
|
||||
opmode set wr_sync mask */
|
||||
#define XNANDPS_SET_OPMODE_SET_WR_BL_MASK 0x00000380 /**< Set
|
||||
opmode set wr_bl mask */
|
||||
#define XNANDPS_SET_OPMODE_SET_BAA_MASK 0x00000400 /**< Set
|
||||
opmode set baa mask */
|
||||
#define XNANDPS_SET_OPMODE_SET_ADV_MASK 0x00000800 /**< Set
|
||||
opmode set adv mask */
|
||||
#define XNANDPS_SET_OPMODE_SET_BLS_MASK 0x00001000 /**< Set
|
||||
opmode set bls mask */
|
||||
#define XNANDPS_SET_OPMODE_SET_BURST_ALIGN_MASK 0x0000E000 /**< Set
|
||||
opmode set burst align mask */
|
||||
|
||||
#define XNANDPS_SET_OPMODE_MW_8_BITS 0x0 /**< Set opmode
|
||||
memory width value for 8-bit flash */
|
||||
#define XNANDPS_SET_OPMODE_MW_16_BITS 0x1 /**< Set opmode
|
||||
memory width value for 16-bit flash */
|
||||
#define XNANDPS_SET_OPMODE_MW_32_BITS 0x2 /**< Set opmode
|
||||
memory width value for 32-bit flash */
|
||||
/* @} */
|
||||
|
||||
/** @name Refresh period register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_REFRESH_PERIOD_0_MASK 0x0000000F
|
||||
/**< Interface 0 refresh period mask */
|
||||
#define XNANDPS_REFRESH_PERIOD_1_MASK 0x0000000F
|
||||
/**< Interface 1 refresh period mask */
|
||||
/* @} */
|
||||
|
||||
/** @name Opmode register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_OPMODE_MW_MASK 0x00000003
|
||||
/**< Opmode Memory width mask */
|
||||
#define XNANDPS_OPMODE_RD_SYNC_MASK 0x00000004
|
||||
/**< Opmode rd_sync mask */
|
||||
#define XNANDPS_OPMODE_RD_BL_MASK 0x00000038
|
||||
/**< Opmode rd_bl mask */
|
||||
#define XNANDPS_OPMODE_WR_SYNC_MASK 0x00000040
|
||||
/**< Opmode wr_sync mask */
|
||||
#define XNANDPS_OPMODE_WR_BL_MASK 0x00000380
|
||||
/**< Opmode BAA mask */
|
||||
#define XNANDPS_OPMODE_BAA_MASK 0x00000400
|
||||
/**< Opmode ADV mask */
|
||||
#define XNANDPS_OPMODE_ADV_MASK 0x00000800
|
||||
/**< Opmode BLS mask */
|
||||
#define XNANDPS_OPMODE_BLS_MASK 0x00001000
|
||||
/**< Opmode Burst align mask */
|
||||
#define XNANDPS_OPMODE_BURST_ALIGN_MASK 0x0000E000
|
||||
/**< Opmode Address mask */
|
||||
#define XNANDPS_OPMODE_ADDRESS_MASK 0x00FF0000
|
||||
/**< Opmode Address match mask */
|
||||
#define XNANDPS_OPMODE_ADDRESS_MATCH_MASK 0xFF000000
|
||||
/* @} */
|
||||
|
||||
/** @name User status register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_USER_STATUS_MASK 0x000000FF /**< User
|
||||
status mask */
|
||||
/* @} */
|
||||
|
||||
/** @name User config register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_USER_CONFIG_MASK 0x000000FF /**< User
|
||||
config mask */
|
||||
/* @} */
|
||||
|
||||
/** @name ECC status register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_ECC_STATUS_RAW_INT_STATUS_MASK 0x0000003F /**< Ecc
|
||||
status raw_int_status mask */
|
||||
#define XNANDPS_ECC_STATUS_MASK 0x00000040 /**< Ecc
|
||||
status ecc_status mask */
|
||||
#define XNANDPS_ECC_LAST_MASK 0x00000180 /**< Ecc
|
||||
status ecc_last mask */
|
||||
#define XNANDPS_ECC_READ_NOT_WRITE_MASK 0x00000200 /**< Ecc
|
||||
status ecc_read_not_write mask */
|
||||
#define XNANDPS_ECC_VALID_MASK 0x00007C00 /**< Ecc
|
||||
status ecc_valid mask */
|
||||
#define XNANDPS_ECC_FAIL_MASK 0x000F8000 /**< Ecc
|
||||
status ecc_fail mask */
|
||||
#define XNANDPS_ECC_CAN_CORRECT_MASK 0x01F00000 /**< Ecc
|
||||
status ecc_can_correct mask */
|
||||
#define XNANDPS_ECC_READ_MASK 0x37000000 /**< Ecc
|
||||
status ecc_read mask */
|
||||
/* @} */
|
||||
|
||||
/** @name ECC mem config register bit definitions and masks and shifts
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_ECC_MEMCFG_PAGE_SIZE_MASK 0x00000003
|
||||
/**< Ecc cfg page_size mask */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_MODE_MASK 0x0000000C
|
||||
/**< Ecc cfg ecc_mode mask */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_READ_END_MASK 0x00000010
|
||||
/**< Ecc cfg ecc_read_end mask */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_JUMP_MASK 0x00000060
|
||||
/**< Ecc cfg ecc_jump mask */
|
||||
#define XNANDPS_ECC_MEMCFG_IGNORE_ADD8_MASK 0x00000080
|
||||
/**< Ecc cfg ecc_ignore_add_eight mask */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_INT_PASS_MASK 0x00000100
|
||||
/**< Ecc cfg ecc_int_pass mask */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_INT_ABORT_MASK 0x00000200
|
||||
/**< Ecc cfg ecc_int_abort mask */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_EXTRA_BLOCK_MASK 0x00000400
|
||||
/**< Ecc cfg ecc_extra_block mask */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_EXTRA_BLOCK_SIZE_MASK 0x00001800
|
||||
/**< Ecc cfg ecc_extra_block_size mask */
|
||||
|
||||
#define XNANDPS_ECC_MEMCFG_PAGE_SIZE_SHIFT 0
|
||||
/**< Ecc cfg page_size shift */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_MODE_SHIFT 2
|
||||
/**< Ecc cfg ecc_mode shift */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_READ_END_SHIFT 4
|
||||
/**< Ecc cfg ecc_read_end shift */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_JUMP_SHIFT 5
|
||||
/**< Ecc cfg ecc_jump shift */
|
||||
#define XNANDPS_ECC_MEMCFG_IGNORE_ADD8_SHIFT 7
|
||||
/**< Ecc cfg ecc_ignore_add_eight shift */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_INT_PASS_SHIFT 8
|
||||
/**< Ecc cfg ecc_int_pass shift */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_INT_ABORT_SHIFT 9
|
||||
/**< Ecc cfg ecc_int_abort shift */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_EXTRA_BLOCK_SHIFT 10
|
||||
/**< Ecc cfg ecc_extra_block shift */
|
||||
#define XNANDPS_ECC_MEMCFG_ECC_EXTRA_BLOCK_SIZE_SHIFT 11
|
||||
/**< Ecc cfg ecc_extra_block_size shift */
|
||||
|
||||
#define XNANDPS_ECC_MEMCFG_PAGE_SIZE_512 0x1 /**< ECC cfg
|
||||
page size value for 512 byte page */
|
||||
#define XNANDPS_ECC_MEMCFG_PAGE_SIZE_1024 0x2 /**< ECC cfg
|
||||
page size value for 1024 byte page */
|
||||
#define XNANDPS_ECC_MEMCFG_PAGE_SIZE_2048 0x3 /**< ECC cfg
|
||||
page size value for 2048 byte page */
|
||||
/* @} */
|
||||
/* @} */
|
||||
|
||||
/** @name ECC mem command1 register bit definitions and masks and shifts
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_ECC_MEMCOMMAND1_WR_CMD_MASK 0x000000FF
|
||||
/**< Ecc command 1 nand_wr_cmd mask */
|
||||
#define XNANDPS_ECC_MEMCOMMAND1_RD_CMD_MASK 0x0000FF00
|
||||
/**< Ecc command 1 nand_rd_cmd mask */
|
||||
#define XNANDPS_ECC_MEMCOMMAND1_RD_CMD_END_MASK 0x00FF0000
|
||||
/**< Ecc command 1 nand_rd_cmd_end mask */
|
||||
#define XNANDPS_ECC_MEMCOMMAND1_RD_CMD_END_VALID_MASK 0x01000000
|
||||
/**< Ecc command 1 nand_rd_cmd_end_valid mask */
|
||||
|
||||
#define XNANDPS_ECC_MEMCOMMAND1_WR_CMD_SHIFT 0
|
||||
/**< Ecc command 1 nand_wr_cmd shift */
|
||||
#define XNANDPS_ECC_MEMCOMMAND1_RD_CMD_SHIFT 8
|
||||
/**< Ecc command 1 nand_rd_cmd shift */
|
||||
#define XNANDPS_ECC_MEMCOMMAND1_RD_CMD_END_SHIFT 16
|
||||
/**< Ecc command 1 nand_rd_cmd_end shift */
|
||||
#define XNANDPS_ECC_MEMCOMMAND1_RD_CMD_END_VALID_SHIFT 24
|
||||
/**< Ecc command 1 nand_rd_cmd_end_valid shift */
|
||||
/* @} */
|
||||
|
||||
/** @name ECC mem command2 register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_ECC_MEMCOMMAND2_WR_COL_CHANGE_MASK 0x000000FF
|
||||
/**< Ecc command2 nand_wr_col_change mask */
|
||||
#define XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_MASK 0x0000FF00
|
||||
/**< Ecc command2 nand_rd_col_change mask */
|
||||
#define XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_END_MASK 0x00FF0000
|
||||
/**< Ecc command2 nand_rd_col_change_end mask */
|
||||
#define XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_END_VALID_MASK 0x00FF0000
|
||||
/**< Ecc command2 nand_rd_col_change_end_valid mask */
|
||||
|
||||
|
||||
#define XNANDPS_ECC_MEMCOMMAND2_WR_COL_CHANGE_SHIFT 0
|
||||
/**< Ecc command2 nand_wr_col_change shift */
|
||||
#define XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_SHIFT 8
|
||||
/**< Ecc command2 nand_rd_col_change shift */
|
||||
#define XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_END_SHIFT 16
|
||||
/**< Ecc command2 nand_rd_col_change_end shift */
|
||||
#define XNANDPS_ECC_MEMCOMMAND2_RD_COL_CHANGE_END_VALID_SHIFT 24
|
||||
/**< Ecc command2 nand_rd_col_change_end_valid shift */
|
||||
/* @} */
|
||||
|
||||
/** @name ECC value register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_ECC_VALUE_MASK 0x00FFFFFF
|
||||
/**< Ecc value ecc_value mask */
|
||||
#define XNANDPS_ECC_VALUE_CORRECT_MASK 0x08000000
|
||||
/**< Ecc value ecc_correct mask */
|
||||
#define XNANDPS_ECC_VALUE_FAIL_MASK 0x10000000
|
||||
/**< Ecc value ecc_fail mask */
|
||||
#define XNANDPS_ECC_VALUE_READ_MASK 0x20000000
|
||||
/**< Ecc value ecc_read mask */
|
||||
#define XNANDPS_ECC_VALUE_VALID_MASK 0x40000000
|
||||
/**< Ecc value ecc_valid mask */
|
||||
#define XNANDPS_ECC_VALUE_INT_MASK 0x80000000
|
||||
/**< Ecc value ecc_int mask */
|
||||
/* @} */
|
||||
|
||||
/** @name Peripheral ID register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_PERIPH_ID_PART_NUM_MASK 0x00000FFF
|
||||
/**< Peripheral ID part_num mask */
|
||||
#define XNANDPS_PERIPH_ID_DESIGNER_ID_MASK 0x000FF000
|
||||
/**< Peripheral ID designed id mask */
|
||||
#define XNANDPS_PERIPH_ID_REVISION_MASK 0x00F00000
|
||||
/**< Peripheral ID revision mask */
|
||||
#define XNANDPS_PERIPH_ID_INTG_CFG_MASK 0x01000000
|
||||
/**< Peripheral ID integration_cfg mask */
|
||||
/* @} */
|
||||
|
||||
/** @name Peripheral ID register bit definitions and masks
|
||||
* @{
|
||||
*/
|
||||
#define XNANDPS_PCELL_ID_MASK 0x000000FF
|
||||
/**< Primecell identification register mask */
|
||||
/* @} */
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
#define XNandPs_ReadReg Xil_In32 /**< XNandPs Register register */
|
||||
#define XNandPs_WriteReg Xil_Out32 /**< XNandPs register write */
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
654
XilinxProcessorIPLib/drivers/nandps/src/xnandps_onfi.c
Executable file
654
XilinxProcessorIPLib/drivers/nandps/src/xnandps_onfi.c
Executable file
|
@ -0,0 +1,654 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xnandps_onfi.c
|
||||
*
|
||||
* This module implements the ONFI specific commands.
|
||||
* See xnandps_onfi.h for more information.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00a nm 12/10/2010 First release
|
||||
* 1.01a nm 28/02/2012 Added support for 8Gb On-Die ECC NAND flash
|
||||
* parts (CR 648463).
|
||||
* Fixed 16-bit issue with ONFI commands like
|
||||
* read, write and read status command.
|
||||
* 1.03a nm 10/22/2012 Fixed CR# 673348.
|
||||
* 1.04a nm 04/25/2013 Implemented PR# 699544. Added page cache read
|
||||
* and program commands to ONFI command list.
|
||||
* Reading the cache features during read param page.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xnandps_onfi.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
static void Onfi_ReadData(XNandPs *InstancePtr, u8 *Buf, u32 Length);
|
||||
|
||||
static void Onfi_CmdReset(XNandPs *InstancePtr);
|
||||
|
||||
static void Onfi_CmdReadId(XNandPs *InstancePtr, u8 Address);
|
||||
|
||||
static void Onfi_CmdReadParamPage(XNandPs *InstancePtr);
|
||||
|
||||
static unsigned long Onfi_Crc16(u8 *Buf);
|
||||
|
||||
static int Onfi_ReadParamPage(XNandPs *InstancePtr, u8 *Buf);
|
||||
|
||||
extern void XNandPs_SendCommand(XNandPs *InstancePtr, XNandPs_CommandFormat
|
||||
*Command, int Page, int Column);
|
||||
/************************** Variable Definitions *****************************/
|
||||
|
||||
/**
|
||||
* This structure defines the onfi command format sent to the flash.
|
||||
*/
|
||||
XNandPs_CommandFormat OnfiCommands[] = {
|
||||
{ONFI_CMD_READ1, ONFI_CMD_READ2, 5, XNANDPS_CMD_PHASE},
|
||||
/*<< Read command format */
|
||||
{ONFI_CMD_CHANGE_READ_COLUMN1, ONFI_CMD_CHANGE_READ_COLUMN2,
|
||||
2, XNANDPS_CMD_PHASE}, /*<< Change Read column format */
|
||||
{ONFI_CMD_BLOCK_ERASE1, ONFI_CMD_BLOCK_ERASE2, 3, XNANDPS_CMD_PHASE},
|
||||
/*<<Block Erase command format */
|
||||
{ONFI_CMD_READ_STATUS, XNANDPS_END_CMD_NONE, 0,
|
||||
XNANDPS_END_CMD_INVALID},
|
||||
/*<< Read Status command format */
|
||||
{ONFI_CMD_PAGE_PROG1, ONFI_CMD_PAGE_PROG2, 5, XNANDPS_DATA_PHASE},
|
||||
/*<< Page program command format */
|
||||
{ONFI_CMD_CHANGE_WRITE_COLUMN, XNANDPS_END_CMD_NONE, 2,
|
||||
XNANDPS_END_CMD_INVALID}, /*<< Change Write Column
|
||||
command format */
|
||||
{ONFI_CMD_READ_ID, XNANDPS_END_CMD_NONE, 1, XNANDPS_END_CMD_INVALID},
|
||||
/*<< Read ID command format */
|
||||
{ONFI_CMD_READ_PARAM_PAGE, XNANDPS_END_CMD_NONE, 1,
|
||||
XNANDPS_END_CMD_INVALID},
|
||||
/*<< Read Param Page command format */
|
||||
{ONFI_CMD_RESET, XNANDPS_END_CMD_NONE, 0, XNANDPS_END_CMD_INVALID},
|
||||
/*<< Reset command format */
|
||||
{ONFI_CMD_GET_FEATURES, XNANDPS_END_CMD_NONE, 1,
|
||||
XNANDPS_END_CMD_INVALID},
|
||||
/*<< Get Features */
|
||||
{ONFI_CMD_SET_FEATURES, XNANDPS_END_CMD_NONE, 1,
|
||||
XNANDPS_END_CMD_INVALID},
|
||||
/*<< Set Features */
|
||||
{ONFI_CMD_READ_CACHE_ENHANCED1, ONFI_CMD_READ_CACHE_ENHANCED2, 5,
|
||||
XNANDPS_CMD_PHASE},
|
||||
/*<< Read page cache random */
|
||||
{ONFI_CMD_READ_CACHE_END, XNANDPS_END_CMD_NONE, 0,
|
||||
XNANDPS_END_CMD_INVALID},
|
||||
/*<< Read page cache end */
|
||||
{ONFI_CMD_PAGE_CACHE_PROGRAM1, ONFI_CMD_PAGE_CACHE_PROGRAM2, 5,
|
||||
XNANDPS_DATA_PHASE},
|
||||
/*<< Program page cache */
|
||||
};
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function reads the data from flash. It is used for reading the control
|
||||
* information from flash like ID and Parameter page.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
* @param Buf is the buffer pointer to read the data.
|
||||
* @param Length is the length of data to read.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static void Onfi_ReadData(XNandPs *InstancePtr, u8 *Buf, u32 Length)
|
||||
{
|
||||
u32 Index;
|
||||
|
||||
/*
|
||||
* 8-bit/16-bit access for basic read operations
|
||||
*/
|
||||
for(Index = 0; Index < Length; Index++) {
|
||||
|
||||
if (InstancePtr->Config.FlashWidth == XNANDPS_FLASH_WIDTH_16)
|
||||
Buf[Index] = (u8)Xil_In16(InstancePtr->DataPhaseAddr);
|
||||
else
|
||||
Buf[Index] = Xil_In8(InstancePtr->DataPhaseAddr);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function writes command data to flash. It is used for writing the
|
||||
* control information like set features.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
* @param Buf is the buffer pointer to write the data.
|
||||
* @param Length is the length of data to write.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static void Onfi_WriteData(XNandPs *InstancePtr, u8 *Buf, u32 Length)
|
||||
{
|
||||
u32 Index;
|
||||
|
||||
/*
|
||||
* 8-bit/16-bit access for basic write operations
|
||||
*/
|
||||
for(Index = 0; Index < Length; Index++) {
|
||||
if (InstancePtr->Config.FlashWidth == XNANDPS_FLASH_WIDTH_16)
|
||||
Xil_Out16(InstancePtr->DataPhaseAddr, Buf[Index]);
|
||||
else
|
||||
Xil_Out8(InstancePtr->DataPhaseAddr, Buf[Index]);
|
||||
}
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends read status command to the flash device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
*
|
||||
* @return flash status value read
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
u8 Onfi_CmdReadStatus(XNandPs *InstancePtr)
|
||||
{
|
||||
u8 Status;
|
||||
|
||||
XNandPs_SendCommand(InstancePtr, &OnfiCommands[READ_STATUS],
|
||||
XNANDPS_PAGE_NOT_VALID, XNANDPS_COLUMN_NOT_VALID);
|
||||
|
||||
if(InstancePtr->Config.FlashWidth == XNANDPS_FLASH_WIDTH_16)
|
||||
Status = (u8) Xil_In16(InstancePtr->DataPhaseAddr);
|
||||
else
|
||||
Status = Xil_In8(InstancePtr->DataPhaseAddr);
|
||||
|
||||
return Status;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends reset command to the flash device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static void Onfi_CmdReset(XNandPs *InstancePtr)
|
||||
{
|
||||
u8 Status;
|
||||
|
||||
XNandPs_SendCommand(InstancePtr, &OnfiCommands[RESET],
|
||||
XNANDPS_PAGE_NOT_VALID, XNANDPS_COLUMN_NOT_VALID);
|
||||
|
||||
/*
|
||||
* Check the Status Register SR[6]
|
||||
*/
|
||||
do {
|
||||
Status = Onfi_CmdReadStatus(InstancePtr);
|
||||
}while ((Status & ONFI_STATUS_RDY) != ONFI_STATUS_RDY);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends read ID command to the flash device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static void Onfi_CmdReadId(XNandPs *InstancePtr, u8 Address)
|
||||
{
|
||||
XNandPs_SendCommand(InstancePtr, &OnfiCommands[READ_ID],
|
||||
XNANDPS_PAGE_NOT_VALID, Address);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends read parameter page command to the flash device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static void Onfi_CmdReadParamPage(XNandPs *InstancePtr)
|
||||
{
|
||||
u8 Status;
|
||||
u32 ZeroCommand;
|
||||
|
||||
XNandPs_SendCommand(InstancePtr, &OnfiCommands[READ_PARAM_PAGE],
|
||||
XNANDPS_PAGE_NOT_VALID, 0x00);
|
||||
/*
|
||||
* Check the Status Register SR[6]
|
||||
*/
|
||||
do {
|
||||
Status = Onfi_CmdReadStatus(InstancePtr);
|
||||
}while ((Status & ONFI_STATUS_RDY) != ONFI_STATUS_RDY);
|
||||
|
||||
/*
|
||||
* ONFI : Reissue the 0x00 on the command line to start reading data
|
||||
*/
|
||||
ZeroCommand = InstancePtr->Config.FlashBase |
|
||||
(0 << XNANDPS_ADDR_CYCLES_SHIFT)|
|
||||
(0 << XNANDPS_END_CMD_VALID_SHIFT)|
|
||||
(XNANDPS_COMMAND_PHASE_MASK)|
|
||||
(0 << XNANDPS_END_CMD_SHIFT)|
|
||||
(0 << XNANDPS_START_CMD_SHIFT);
|
||||
|
||||
/*
|
||||
* Dummy AXI transaction for sending command 0x00 to the flash
|
||||
*/
|
||||
Xil_Out32(ZeroCommand, 0x0);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends Get Feature command to the flash device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
* @param Feature is the feature value to read.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static void Onfi_GetFeature(XNandPs *InstancePtr, u8 Feature, u8 *Val)
|
||||
{
|
||||
u8 Status;
|
||||
u32 ZeroCommand;
|
||||
|
||||
XNandPs_SendCommand(InstancePtr, &OnfiCommands[GET_FEATURES],
|
||||
XNANDPS_PAGE_NOT_VALID, Feature);
|
||||
/*
|
||||
* Check the Status Register SR[6]
|
||||
*/
|
||||
do {
|
||||
Status = Onfi_CmdReadStatus(InstancePtr);
|
||||
}while ((Status & ONFI_STATUS_RDY) != ONFI_STATUS_RDY);
|
||||
|
||||
/*
|
||||
* ONFI 2.3: Reissue the 0x00 on the command line to start reading
|
||||
* data.
|
||||
*/
|
||||
ZeroCommand = InstancePtr->Config.FlashBase |
|
||||
(0 << XNANDPS_ADDR_CYCLES_SHIFT)|
|
||||
(0 << XNANDPS_END_CMD_VALID_SHIFT)|
|
||||
(XNANDPS_COMMAND_PHASE_MASK)|
|
||||
(0 << XNANDPS_END_CMD_SHIFT)|
|
||||
(0 << XNANDPS_START_CMD_SHIFT);
|
||||
|
||||
/*
|
||||
* Dummy AXI transaction for sending command 0x00 to the flash
|
||||
*/
|
||||
Xil_Out32(ZeroCommand, 0x00);
|
||||
|
||||
/*
|
||||
* Read the feature value
|
||||
*/
|
||||
Onfi_ReadData(InstancePtr, Val, 4);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function sends Set Feature command to the flash device.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
* @param Feature is the feature value to Set.
|
||||
*
|
||||
* @return None
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static void Onfi_SetFeature(XNandPs *InstancePtr, u8 Feature, u8 *Val)
|
||||
{
|
||||
u8 Status;
|
||||
|
||||
XNandPs_SendCommand(InstancePtr, &OnfiCommands[SET_FEATURES],
|
||||
XNANDPS_PAGE_NOT_VALID, Feature);
|
||||
|
||||
Onfi_WriteData(InstancePtr, Val, 4);
|
||||
|
||||
/*
|
||||
* Check the Status Register SR[6]
|
||||
*/
|
||||
do {
|
||||
Status = Onfi_CmdReadStatus(InstancePtr);
|
||||
}while ((Status & ONFI_STATUS_RDY) != ONFI_STATUS_RDY);
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function calculates the CRC on the parameter page buffer. This is taken
|
||||
* from the ONFI 1.0 specification.
|
||||
*
|
||||
* @param Buf is the parameter page buffer.
|
||||
*
|
||||
* @return CRC value calculated.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static unsigned long Onfi_Crc16(u8 *Buf)
|
||||
{
|
||||
const int Order = ONFI_CRC_ORDER;
|
||||
const unsigned long Polynom = ONFI_CRC_POLYNOM;
|
||||
u32 Crc = ONFI_CRC_INIT;
|
||||
u32 Index;
|
||||
u32 j;
|
||||
u32 c;
|
||||
u32 Bit;
|
||||
u32 DataIn;
|
||||
int DataByteCount = 0;
|
||||
u32 CrcMask = ((((u32)1 << (Order - 1)) -1) << 1) | 1;
|
||||
u32 CrcHighBit = (u32)1 << (Order - 1);
|
||||
|
||||
/*
|
||||
* CRC covers the data bytes between byte 0 and byte 253 (ONFI 1.0, sec
|
||||
* 5.4.1.36)
|
||||
*/
|
||||
for(Index = 0; Index < ONFI_CRC_LEN; Index++)
|
||||
{
|
||||
DataIn = Buf[Index];
|
||||
c = (u32)DataIn;
|
||||
DataByteCount++;
|
||||
for(j = 0x80; j; j >>= 1) {
|
||||
Bit = Crc & CrcHighBit;
|
||||
Crc <<= 1;
|
||||
if (c & j) Bit ^= CrcHighBit;
|
||||
if (Bit) Crc ^= Polynom;
|
||||
}
|
||||
Crc &= CrcMask;
|
||||
}
|
||||
return Crc;
|
||||
}
|
||||
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function reads the NAND flash parameter page defined by ONFI 1.0
|
||||
* specfication.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
* @param Buf is a buffer pointer to fill the data.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if parameter page read successfully.
|
||||
* - XST_FAILURE if parameter page is not read successfully.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
static int Onfi_ReadParamPage(XNandPs *InstancePtr, u8 *Buf)
|
||||
{
|
||||
u32 Index;
|
||||
u32 CrcCalc;
|
||||
OnfiNand_Geometry *Geometry;
|
||||
|
||||
/*
|
||||
* Read the first 256 bytes of parameter page
|
||||
*/
|
||||
Onfi_CmdReadParamPage(InstancePtr);
|
||||
/* Read the 3 mandatory parameter pages */
|
||||
for(Index = 0; Index < 3; Index++) {
|
||||
Onfi_ReadData(InstancePtr, Buf, ONFI_PARAM_PAGE_LEN);
|
||||
Geometry = (OnfiNand_Geometry *)Buf;
|
||||
/* Check the CRC */
|
||||
CrcCalc = Onfi_Crc16(Buf);
|
||||
if(CrcCalc == Geometry->Crc) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (Index == 3) {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
||||
/**************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function initializes the NAND flash and gets the geometry information.
|
||||
*
|
||||
* @param InstancePtr is a pointer to the XNandPs instance.
|
||||
*
|
||||
* @return
|
||||
* - XST_SUCCESS if successful.
|
||||
* - XST_FAILURE if failed.
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
***************************************************************************/
|
||||
int Onfi_NandInit(XNandPs *InstancePtr)
|
||||
{
|
||||
u32 Target;
|
||||
int Status;
|
||||
u8 Id[ONFI_ID_LEN];
|
||||
u8 JedecId[2];
|
||||
u8 EccSetFeature[4] = {0x08, 0x00, 0x00, 0x00};
|
||||
u8 EccGetFeature[4];
|
||||
OnfiNand_Geometry Nand_Geometry;
|
||||
|
||||
Xil_AssertNonvoid(InstancePtr != NULL);
|
||||
|
||||
for(Target=0; Target < XNANDPS_MAX_TARGETS; Target++) {
|
||||
/*
|
||||
* Reset the target
|
||||
*/
|
||||
Onfi_CmdReset(InstancePtr);
|
||||
|
||||
/*
|
||||
* Read the ONFI ID
|
||||
*/
|
||||
Onfi_CmdReadId(InstancePtr, 0x20);
|
||||
Onfi_ReadData(InstancePtr, &Id[0], ONFI_ID_LEN);
|
||||
|
||||
/*
|
||||
* Check the ONFI signature to know that the target supports
|
||||
* ONFI
|
||||
*/
|
||||
if (Id[0]=='O' && Id[1]=='N' && Id[2]=='F' && Id[3]=='I') {
|
||||
/* Read the parameter page structure */
|
||||
Status = Onfi_ReadParamPage(InstancePtr,
|
||||
(u8 *)&Nand_Geometry);
|
||||
if (Status != XST_FAILURE) {
|
||||
InstancePtr->Geometry.NumLun =
|
||||
Nand_Geometry.NumLuns;
|
||||
InstancePtr->Geometry.PagesPerBlock =
|
||||
Nand_Geometry.PagesPerBlock;
|
||||
InstancePtr->Geometry.SpareBytesPerPage =
|
||||
Nand_Geometry.SpareBytesPerPage;
|
||||
InstancePtr->Geometry.BytesPerPage =
|
||||
Nand_Geometry.BytesPerPage;
|
||||
InstancePtr->Geometry.BlocksPerLun =
|
||||
Nand_Geometry.BlocksPerLun;
|
||||
InstancePtr->Geometry.NumBlocks =
|
||||
(Nand_Geometry.NumLuns *
|
||||
InstancePtr->Geometry.BlocksPerLun);
|
||||
InstancePtr->Geometry.NumPages =
|
||||
(Nand_Geometry.NumLuns *
|
||||
Nand_Geometry.BlocksPerLun *
|
||||
Nand_Geometry.PagesPerBlock);
|
||||
InstancePtr->Geometry.BlockSize =
|
||||
(Nand_Geometry.PagesPerBlock *
|
||||
Nand_Geometry.BytesPerPage);
|
||||
InstancePtr->Geometry.DeviceSize =
|
||||
(InstancePtr->Geometry.NumBlocks *
|
||||
InstancePtr->Geometry.PagesPerBlock *
|
||||
InstancePtr->Geometry.BytesPerPage);
|
||||
/*
|
||||
* Calculate the address cycles
|
||||
*/
|
||||
InstancePtr->Geometry.RowAddrCycles =
|
||||
(Nand_Geometry.AddrCycles & 0xf);
|
||||
InstancePtr->Geometry.ColAddrCycles =
|
||||
((Nand_Geometry.AddrCycles >> 4) & 0xf);
|
||||
|
||||
OnfiCommands[READ].AddrCycles =
|
||||
(InstancePtr->Geometry.RowAddrCycles +
|
||||
InstancePtr->Geometry.ColAddrCycles);
|
||||
|
||||
OnfiCommands[PAGE_PROGRAM].AddrCycles =
|
||||
(InstancePtr->Geometry.RowAddrCycles +
|
||||
InstancePtr->Geometry.ColAddrCycles);
|
||||
|
||||
OnfiCommands[BLOCK_ERASE].AddrCycles =
|
||||
InstancePtr->Geometry.RowAddrCycles;
|
||||
|
||||
OnfiCommands[CHANGE_READ_COLUMN].AddrCycles =
|
||||
InstancePtr->Geometry.ColAddrCycles;
|
||||
|
||||
OnfiCommands[CHANGE_WRITE_COLUMN].AddrCycles =
|
||||
InstancePtr->Geometry.ColAddrCycles;
|
||||
/*
|
||||
* Read JEDEC ID
|
||||
*/
|
||||
Onfi_CmdReadId(InstancePtr, 0x00);
|
||||
Onfi_ReadData(InstancePtr, &JedecId[0], 2);
|
||||
|
||||
if ((JedecId[0] == 0x2C) &&
|
||||
/* 1 Gb flash devices */
|
||||
((JedecId[1] == 0xF1) ||
|
||||
(JedecId[1] == 0xA1) ||
|
||||
(JedecId[1] == 0xB1) ||
|
||||
/* 2 Gb flash devices */
|
||||
(JedecId[1] == 0xAA) ||
|
||||
(JedecId[1] == 0xBA) ||
|
||||
(JedecId[1] == 0xDA) ||
|
||||
(JedecId[1] == 0xCA) ||
|
||||
/* 4 Gb flash devices */
|
||||
(JedecId[1] == 0xAC) ||
|
||||
(JedecId[1] == 0xBC) ||
|
||||
(JedecId[1] == 0xDC) ||
|
||||
(JedecId[1] == 0xCC) ||
|
||||
/* 8 Gb flash devices */
|
||||
(JedecId[1] == 0xA3) ||
|
||||
(JedecId[1] == 0xB3) ||
|
||||
(JedecId[1] == 0xD3) ||
|
||||
(JedecId[1] == 0xC3))) {
|
||||
/*
|
||||
* Check if this flash supports On-Die ECC.
|
||||
* Micron Flash: MT29F1G08ABADA, MT29F1G08ABBDA
|
||||
* MT29F1G16ABBDA,
|
||||
* MT29F2G08ABBEA, MT29F2G16ABBEA,
|
||||
* MT29F2G08ABAEA, MT29F2G16ABAEA,
|
||||
* MT29F4G08ABBDA, MT29F4G16ABBDA,
|
||||
* MT29F4G08ABADA, MT29F4G16ABADA,
|
||||
* MT29F8G08ADBDA, MT29F8G16ADBDA,
|
||||
* MT29F8G08ADADA, MT29F8G16ADADA
|
||||
*/
|
||||
|
||||
Onfi_SetFeature(InstancePtr, 0x90,
|
||||
&EccSetFeature[0]);
|
||||
/* Check to see if ECC feature is set */
|
||||
Onfi_GetFeature(InstancePtr, 0x90,
|
||||
&EccGetFeature[0]);
|
||||
if (EccGetFeature[0] & 0x08) {
|
||||
InstancePtr->EccMode = XNANDPS_ECC_ONDIE;
|
||||
} else {
|
||||
InstancePtr->EccMode = XNANDPS_ECC_HW;
|
||||
}
|
||||
} else if (Nand_Geometry.BytesPerPage < 512 ||
|
||||
Nand_Geometry.BytesPerPage > 2048) {
|
||||
/*
|
||||
* This controller doesn't support ECC for
|
||||
* page size < 512 & > 2048 bytes.
|
||||
*/
|
||||
InstancePtr->EccMode = XNANDPS_ECC_NONE;
|
||||
} else {
|
||||
/* SMC controller ECC (1-bit correction) */
|
||||
InstancePtr->EccMode = XNANDPS_ECC_HW;
|
||||
}
|
||||
/*
|
||||
* Updating the instance flash width after checking
|
||||
* for on-die ECC
|
||||
*/
|
||||
InstancePtr->Geometry.FlashWidth =
|
||||
(Nand_Geometry.Features & 0x1) ?
|
||||
XNANDPS_FLASH_WIDTH_16 :
|
||||
XNANDPS_FLASH_WIDTH_8;
|
||||
/*
|
||||
* Features and Optional commands supported.
|
||||
* On-Die ECC flash doesn't support these
|
||||
* commands when ECC is enabled.
|
||||
*/
|
||||
if (InstancePtr->EccMode != XNANDPS_ECC_ONDIE) {
|
||||
InstancePtr->Features.ProgramCache =
|
||||
(Nand_Geometry.OptionalCmds & 0x1) ? 1:0;
|
||||
InstancePtr->Features.ReadCache =
|
||||
(Nand_Geometry.OptionalCmds & 0x2) ? 1:0;
|
||||
}
|
||||
} else {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
} else {
|
||||
return XST_FAILURE;
|
||||
}
|
||||
}
|
||||
|
||||
return XST_SUCCESS;
|
||||
}
|
314
XilinxProcessorIPLib/drivers/nandps/src/xnandps_onfi.h
Executable file
314
XilinxProcessorIPLib/drivers/nandps/src/xnandps_onfi.h
Executable file
|
@ -0,0 +1,314 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xnandps_onfi.h
|
||||
*
|
||||
* This file implements ONFI specific commands which are used to get the
|
||||
* parameter page information.
|
||||
*
|
||||
* The following commands are supported currently.
|
||||
* - Reset
|
||||
* - Read ID
|
||||
* - READ Parameter Page
|
||||
* - Read Status
|
||||
* - Change Read Column
|
||||
* - Get Features
|
||||
* - Set Features
|
||||
*
|
||||
* @note None
|
||||
*
|
||||
* <pre>
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00a nm 12/10/2010 First release
|
||||
* 1.04a nm 04/25/2013 Implemented PR# 699544. Added page cache read
|
||||
* and program commands to ONFI command list.
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
#ifndef ONFI_H /* prevent circular inclusions */
|
||||
#define ONFI_H /* by using protection macros */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
#include "xnandps.h"
|
||||
/************************** Constant Definitions *****************************/
|
||||
/*
|
||||
* Standard ONFI NAND flash commands
|
||||
*/
|
||||
|
||||
/*
|
||||
* Mandatory commands
|
||||
*/
|
||||
#define ONFI_CMD_READ1 0x00 /**< ONFI Read command
|
||||
(1st cycle) */
|
||||
#define ONFI_CMD_READ2 0x30 /**< ONFI Read command
|
||||
(2nd cycle) */
|
||||
#define ONFI_CMD_CHANGE_READ_COLUMN1 0x05 /**< ONFI Change Read
|
||||
Column command (1st
|
||||
cycle) */
|
||||
#define ONFI_CMD_CHANGE_READ_COLUMN2 0xE0 /**< ONFI Change Read
|
||||
Column command (2nd
|
||||
cycle) */
|
||||
#define ONFI_CMD_BLOCK_ERASE1 0x60 /**< ONFI Block Erase
|
||||
(1st cycle) */
|
||||
#define ONFI_CMD_BLOCK_ERASE2 0xD0 /**< ONFI Block Erase
|
||||
(2nd cycle) */
|
||||
#define ONFI_CMD_READ_STATUS 0x70 /**< ONFI Read status
|
||||
command */
|
||||
#define ONFI_CMD_PAGE_PROG1 0x80 /**< ONFI Page Program
|
||||
command (1st cycle)
|
||||
*/
|
||||
#define ONFI_CMD_PAGE_PROG2 0x10 /**< ONFI Page Program
|
||||
command (2nd cycle)
|
||||
*/
|
||||
#define ONFI_CMD_CHANGE_WRITE_COLUMN 0x85 /**< ONFI Change Write
|
||||
Column command */
|
||||
#define ONFI_CMD_READ_ID 0x90 /**< ONFI Read ID
|
||||
command */
|
||||
#define ONFI_CMD_READ_PARAM_PAGE 0xEC /**< ONFI Read
|
||||
Parameter Page
|
||||
command */
|
||||
#define ONFI_CMD_RESET 0xFF /**< ONFI Reset
|
||||
command */
|
||||
/*
|
||||
* Optional commands
|
||||
*/
|
||||
#define ONFI_CMD_COPYBACK_READ1 0x00 /**< ONFI Copyback Read
|
||||
command (1st cycle)
|
||||
*/
|
||||
#define ONFI_CMD_COPYBACK_READ2 0x35 /**< ONFI Copyback Read
|
||||
command (2nd cycle)
|
||||
*/
|
||||
#define ONFI_CMD_READ_CACHE_ENHANCED1 0x00 /**< ONFI Read cache
|
||||
enhanced command (1st
|
||||
cycle) */
|
||||
#define ONFI_CMD_READ_CACHE_ENHANCED2 0x31 /**< ONFI Read cache
|
||||
enhanced command (2nd
|
||||
cycle) */
|
||||
#define ONFI_CMD_READ_CACHE 0x31 /**< ONFI Read cache
|
||||
command */
|
||||
#define ONFI_CMD_READ_CACHE_END 0x3F /**< ONFI Read cache
|
||||
end command */
|
||||
#define ONFI_CMD_BLOCK_ERASE_INTERLEAVED2 0xD1 /**< ONFI Block Erase
|
||||
interleaved command
|
||||
(2nd cycle) */
|
||||
#define ONFI_CMD_READ_STATUS_ENHANCED 0x78 /**< ONFI Read Status
|
||||
enhanced command */
|
||||
#define ONFI_CMD_PAGE_PROGRAM_INTERLEAVED2 0x11 /**< ONFI Page Program
|
||||
interleaved command
|
||||
(2nd cycle) */
|
||||
#define ONFI_CMD_PAGE_CACHE_PROGRAM1 0x80 /**< ONFI Page cache
|
||||
program (1st cycle)
|
||||
*/
|
||||
#define ONFI_CMD_PAGE_CACHE_PROGRAM2 0x15 /**< ONFI Page cache
|
||||
program (2nd cycle)
|
||||
*/
|
||||
#define ONFI_CMD_COPYBACK_PROGRAM1 0x85 /**< ONFI Copyback
|
||||
program command (1st
|
||||
cycle) */
|
||||
#define ONFI_CMD_COPYBACK_PROGRAM2 0x10 /**< ONFI Copyback
|
||||
program command (2nd
|
||||
cycle) */
|
||||
#define ONFI_CMD_COPYBACK_PROGRAM_INTERLEAVED2 0x11 /**< ONFI Copyback
|
||||
program interleaved
|
||||
command (2nd cycle)
|
||||
*/
|
||||
#define ONFI_CMD_READ_UNIQUEID 0xED /**< ONFI Read Unique
|
||||
ID command */
|
||||
#define ONFI_CMD_GET_FEATURES 0xEE /**< ONFI Get features
|
||||
command */
|
||||
#define ONFI_CMD_SET_FEATURES 0xEF /**< ONFI Set features
|
||||
command */
|
||||
|
||||
/*
|
||||
* ONFI Status Register bit offsets
|
||||
*/
|
||||
#define ONFI_STATUS_FAIL 0x01 /**< ONFI Status
|
||||
Register : FAIL */
|
||||
#define ONFI_STATUS_FAILC 0x02 /**< ONFI Status
|
||||
Register : FAILC */
|
||||
#define ONFI_STATUS_ARDY 0x20 /**< ONFI Status
|
||||
Register : ARDY */
|
||||
#define ONFI_STATUS_RDY 0x40 /**< ONFI Status
|
||||
Register : RDY */
|
||||
#define ONFI_STATUS_WP 0x80 /**< ONFI Status
|
||||
Register : WR */
|
||||
/*
|
||||
* ONFI constants
|
||||
*/
|
||||
#define ONFI_ID_LEN 4 /**< ONFI ID Length */
|
||||
#define ONFI_CRC_INIT 0x4F4E /**< ONFI CRC16
|
||||
Inititialization constant */
|
||||
#define ONFI_CRC_POLYNOM 0x8005 /**< ONFI CRC16 polynomial */
|
||||
#define ONFI_CRC_ORDER 16 /**< ONFI CRC16 order */
|
||||
#define ONFI_PARAM_PAGE_LEN 256 /**< ONFI Parameter page length
|
||||
*/
|
||||
#define ONFI_CRC_LEN 254 /**< ONFI CRC16 length */
|
||||
#define ONFI_SIGNATURE_LEN 4 /**< ONFI Signature Length */
|
||||
|
||||
|
||||
/**
|
||||
* This enum defines the onfi commands.
|
||||
*/
|
||||
enum OnfiCommandsEnum {
|
||||
READ=0, /**< ONFI Read */
|
||||
CHANGE_READ_COLUMN, /**< ONFI Change Read Column */
|
||||
BLOCK_ERASE, /**< ONFI Block Erase */
|
||||
READ_STATUS, /**< ONFI Read Status */
|
||||
PAGE_PROGRAM, /**< ONFI Page Program */
|
||||
CHANGE_WRITE_COLUMN, /**< ONFI Change Write Column */
|
||||
READ_ID, /**< ONFI Read ID */
|
||||
READ_PARAM_PAGE, /**< ONFI Read Parameter Page */
|
||||
RESET, /**< ONFI Reset */
|
||||
GET_FEATURES, /**< ONFI Get Features */
|
||||
SET_FEATURES, /**< ONFI Set Features */
|
||||
READ_CACHE_RANDOM, /**< ONFI Read page cache random */
|
||||
READ_CACHE_END_SEQ, /**< ONFI Read page cache end */
|
||||
PAGE_CACHE_PROGRAM /**< ONFI Program page cache */
|
||||
};
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
/**
|
||||
* ONFI 1.0 support
|
||||
*/
|
||||
/*
|
||||
* Parameter page structure of ONFI 1.0 specification.
|
||||
* Enhanced this sturcture to include ONFI 2.3 information for EZ NAND support.
|
||||
*/
|
||||
typedef struct {
|
||||
/*
|
||||
* Revision information and features block
|
||||
*/
|
||||
u8 Signature[4]; /**< Parameter page signature */
|
||||
u16 Revision; /**< Revision Number */
|
||||
u16 Features; /**< Features supported */
|
||||
u16 OptionalCmds; /**< Optional commands supported */
|
||||
u8 Reserved0[2]; /**< ONFI 2.3: Reserved */
|
||||
u16 ExtParamPageLen; /**< ONFI 2.3: extended parameter page
|
||||
length */
|
||||
u8 NumOfParamPages; /**< ONFI 2.3: No of parameter pages */
|
||||
u8 Reserved1[17]; /**< Reserved */
|
||||
/*
|
||||
* Manufacturer information block
|
||||
*/
|
||||
u8 DeviceManufacturer[12]; /**< Device manufacturer */
|
||||
u8 DeviceModel[20]; /**< Device model */
|
||||
u8 JedecManufacturerId; /**< JEDEC Manufacturer ID */
|
||||
u8 DateCode[2]; /**< Date code */
|
||||
u8 Reserved2[13]; /**< Reserved */
|
||||
/*
|
||||
* Memory organization block
|
||||
*/
|
||||
u32 BytesPerPage; /**< Number of data bytes per page */
|
||||
u16 SpareBytesPerPage; /**< Number of spare bytes per page */
|
||||
u32 BytesPerPartialPage; /**< Number of data bytes per partial
|
||||
page */
|
||||
u16 SpareBytesPerPartialPage; /**< Number of spare bytes per partial
|
||||
page */
|
||||
u32 PagesPerBlock; /**< Number of pages per block */
|
||||
u32 BlocksPerLun; /**< Number of blocks per logical unit
|
||||
(LUN) */
|
||||
u8 NumLuns; /**< Number of LUN's */
|
||||
u8 AddrCycles; /**< Number of address cycles */
|
||||
u8 BitsPerCell; /**< Number of bits per cell */
|
||||
u16 MaxBadBlocksPerLun; /**< Bad blocks maximum per LUN */
|
||||
u16 BlockEndurance; /**< Block endurance */
|
||||
u8 GuaranteedValidBlock; /**< Guaranteed valid blocks at
|
||||
beginning of target */
|
||||
u16 BlockEnduranceGvb; /**< Block endurance for guaranteed
|
||||
valid block */
|
||||
u8 ProgramsPerPage; /**< Number of programs per page */
|
||||
u8 PartialProgAttr; /**< Partial programming attributes */
|
||||
u8 EccBits; /**< Number of bits ECC
|
||||
correctability */
|
||||
u8 InterleavedAddrBits; /**< Number of interleaved address
|
||||
bits */
|
||||
u8 InterleavedOperation; /**< Interleaved operation
|
||||
attributes */
|
||||
u8 EzNandSupport; /**< ONFI 2.3: EZ NAND support
|
||||
parameters */
|
||||
u8 Reserved3[12]; /**< Reserved */
|
||||
/*
|
||||
* Electrical parameters block
|
||||
*/
|
||||
u8 IOPinCapacitance; /**< I/O pin capacitance */
|
||||
u16 TimingMode; /**< Timing mode support */
|
||||
u16 PagecacheTimingMode; /**< Program cache timing mode */
|
||||
u16 TProg; /**< Maximum page program time */
|
||||
u16 TBers; /**< Maximum block erase time */
|
||||
u16 TR; /**< Maximum page read time */
|
||||
u16 TCcs; /**< Maximum change column setup
|
||||
time */
|
||||
u16 SynTimingMode; /**< ONFI 2.3: Source synchronous
|
||||
timing mode support */
|
||||
u8 SynFeatures; /**< ONFI 2.3: Source synchronous
|
||||
features */
|
||||
u16 ClkInputPinCap; /**< ONFI 2.3: CLK input pin
|
||||
capacitance */
|
||||
u16 IOPinCap; /**< ONFI 2.3: I/O pin capacitance */
|
||||
u16 InputPinCap; /**< ONFI 2.3: Input pin capacitance
|
||||
typical */
|
||||
u8 InputPinCapMax; /**< ONFI 2.3: Input pin capacitance
|
||||
maximum */
|
||||
u8 DrvStrength; /**< ONFI 2.3: Driver strength
|
||||
support */
|
||||
u16 TMr; /**< ONFI 2.3: Maximum multi-plane
|
||||
read time */
|
||||
u16 TAdl; /**< ONFI 2.3: Program page register
|
||||
clear enhancement value */
|
||||
u16 TEr; /**< ONFI 2.3: Typical page read time
|
||||
for EZ NAND */
|
||||
u8 Reserved4[6]; /**< Reserved */
|
||||
/*
|
||||
* Vendor block
|
||||
*/
|
||||
u16 VendorRevisionNum; /**< Vendor specific revision
|
||||
number */
|
||||
u8 VendorSpecific[88]; /**< Vendor specific */
|
||||
u16 Crc; /**< Integrity CRC */
|
||||
}__attribute__((packed))OnfiNand_Geometry;
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* end of protection macro */
|
98
XilinxProcessorIPLib/drivers/nandps/src/xnandps_sinit.c
Executable file
98
XilinxProcessorIPLib/drivers/nandps/src/xnandps_sinit.c
Executable file
|
@ -0,0 +1,98 @@
|
|||
/******************************************************************************
|
||||
*
|
||||
* Copyright (C) 2009 - 2014 Xilinx, Inc. All rights reserved.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* Use of the Software is limited solely to applications:
|
||||
* (a) running on a Xilinx device, or
|
||||
* (b) that interact with a Xilinx device through a bus or interconnect.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* XILINX CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF
|
||||
* OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
* SOFTWARE.
|
||||
*
|
||||
* Except as contained in this notice, the name of the Xilinx shall not be used
|
||||
* in advertising or otherwise to promote the sale, use or other dealings in
|
||||
* this Software without prior written authorization from Xilinx.
|
||||
*
|
||||
******************************************************************************/
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* @file xnandps_sinit.c
|
||||
*
|
||||
* This file contains the implementation of the XNand driver's static
|
||||
* initialization functionality.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
* <pre>
|
||||
*
|
||||
* MODIFICATION HISTORY:
|
||||
*
|
||||
* Ver Who Date Changes
|
||||
* ----- ---- ---------- -----------------------------------------------
|
||||
* 1.00a nm 12/10/2010 First release
|
||||
* </pre>
|
||||
*
|
||||
******************************************************************************/
|
||||
|
||||
/***************************** Include Files *********************************/
|
||||
|
||||
#include "xparameters.h"
|
||||
#include "xnandps.h"
|
||||
|
||||
/************************** Constant Definitions *****************************/
|
||||
|
||||
/**************************** Type Definitions *******************************/
|
||||
|
||||
/***************** Macros (Inline Functions) Definitions *********************/
|
||||
|
||||
/************************** Function Prototypes ******************************/
|
||||
|
||||
/************************** Variable Definitions *****************************/
|
||||
extern XNandPs_Config XNandPs_ConfigTable[];
|
||||
|
||||
/*****************************************************************************/
|
||||
/**
|
||||
*
|
||||
* This function looks up the device configuration based on the unique device ID.
|
||||
* The table XNandPs_ConfigTable contains the configuration info for each device
|
||||
* in the system.
|
||||
*
|
||||
* @param DeviceId contains the ID of the device for which the
|
||||
* device configuration pointer is to be returned.
|
||||
*
|
||||
* @return
|
||||
* - A pointer to the configuration found.
|
||||
* - NULL if the specified device ID was not found.
|
||||
*
|
||||
* @note None.
|
||||
*
|
||||
******************************************************************************/
|
||||
XNandPs_Config *XNandPs_LookupConfig(u16 DeviceId)
|
||||
{
|
||||
XNandPs_Config *CfgPtr = NULL;
|
||||
u32 Index;
|
||||
|
||||
for (Index=0; Index < XPAR_XNANDPS_NUM_INSTANCES; Index++) {
|
||||
if (XNandPs_ConfigTable[Index].DeviceId == DeviceId) {
|
||||
CfgPtr = &XNandPs_ConfigTable[Index];
|
||||
break;
|
||||
}
|
||||
}
|
||||
return CfgPtr;
|
||||
}
|
Loading…
Add table
Reference in a new issue