mirror of
https://github.com/S3NEO/android_kernel_samsung_msm8226.git
synced 2024-11-07 03:47:13 +00:00
mtd: msm_qpic_nand: Initial driver for QPIC based NAND controller
This is an initial driver for the new QPIC based NAND controller(NANDc) that is introduced in MDM9x25. This driver has been leveraged from the current driver msm_nand.c and is modified for the new hardware changes in QPIC NANDc. Addition of SPS/BAM support is one of the major hardware changes in new controller. It also supports only BCH ECC and based on the device capabilities either 4 bit or 8 bit BCH ECC will be used. This driver is based on the device tree architecture. Change-Id: Ie9f782a796bd7c1506997e8eaa1e797310dc26a0 Signed-off-by: Sahitya Tummala <stummala@codeaurora.org>
This commit is contained in:
parent
f330512d2f
commit
f57ae88a7b
4 changed files with 2810 additions and 0 deletions
296
Documentation/mtd/devices/msm_qpic_nand.txt
Normal file
296
Documentation/mtd/devices/msm_qpic_nand.txt
Normal file
|
@ -0,0 +1,296 @@
|
|||
Introduction
|
||||
============
|
||||
|
||||
In MDM9x25, new NAND controller(NANDc) has been added and it has the
|
||||
following major changes as compared to its previous version -
|
||||
|
||||
1. It includes Secured BAM-Lite and the support for ADM(Application Data Mover)
|
||||
has been removed.
|
||||
|
||||
2. It includes 4 bit BCH ECC and the support for 4 bit Reed Solomon ECC has
|
||||
been removed.
|
||||
|
||||
3. The support for Dual NAND controllers has been removed and thus the
|
||||
software features like ping-pong mode and interleave mode are deprecated.
|
||||
|
||||
4. It includes support for dual buffers in case of read and one dedicated
|
||||
write buffer to each processor (Modem and Apps).
|
||||
|
||||
This new NAND driver takes care of all the above new hardware changes. In
|
||||
addition to the above hardware changes, it also takes care of software device
|
||||
tree changes.
|
||||
|
||||
Hardware description
|
||||
====================
|
||||
|
||||
The NANDc Core:
|
||||
---------------
|
||||
Qualcomm Parallel Interface Controller (QPIC), formerly named EBI2, is a
|
||||
wrapper module which integrates a NAND controller core and a LCD controller
|
||||
core and multiplexes their access to shared parallel interfaces pins. Both
|
||||
controller cores are accessible to processors (Modem and Apps), and share
|
||||
master access to the Peripheral NoC (Network on Chip) via a BAM module.
|
||||
|
||||
In MDM9x25, QPIC is located on the peripheral NoC, connected via a 32-bit AHB
|
||||
Master port and a 32-bit AHB Slave Port. The NANDc register interface goes
|
||||
through AHB Slave Port and data transfers using BAM goes through AHB Master
|
||||
Port. The NAND Controller (NANDc) is a hardware core which manages the access
|
||||
to an off-chip NAND device.
|
||||
|
||||
BAM-Lite:
|
||||
---------
|
||||
BAM(Bus Access Manager) can transfer data between a peripheral and memory,
|
||||
or between two peripherals in a BAM to BAM mode. Each BAM contains multiple
|
||||
DMA channels, called pipes. A pipe provides a unidirectional data transfer
|
||||
engine, capable of either receiving data in consumer mode, or transmitting
|
||||
data in producer mode. The consumer fetches the data from the source system
|
||||
memory, and the producer writes data to the destination system memory.
|
||||
|
||||
BAM-Lite's interface is similar to the BAM interface with slight changes to
|
||||
the sideband interface. BAM-Lite is an area-optimized version of BAM. BAM-Lite
|
||||
supports new features such as Notify-When-Done(NWD), pipe lock/unlock and
|
||||
command descriptors.
|
||||
|
||||
NANDc has a secured BAM-Lite which provides DMA support for the NANDc and
|
||||
command support for accessing the NANDc registers. It is called secured
|
||||
because it has an integrated APU (Address Protection Unit) that validates
|
||||
every access to BAM and its peripheral registers.
|
||||
|
||||
The NANDc has in total 6 BAM pipes - 3 pipes are dedicated for each processor
|
||||
(Modem and Apps) at the hardware level.
|
||||
|
||||
Software description
|
||||
====================
|
||||
|
||||
The NAND device is shared between two independent file systems, each running
|
||||
on a different processor - the application processor (Apps) and the Modem.
|
||||
The NAND driver uses BAM driver to transfer NAND operation requests and
|
||||
data to/from the NAND Controller (NANDc) core through the BAM pipes. Every
|
||||
NANDc register read/write access must go through BAM as it facilitates security
|
||||
mechanisms to enable simultaneous access to NAND device from both processors
|
||||
(Modem and Apps).
|
||||
|
||||
The Apps NAND driver registers NANDc BAM peripheral with BAM driver, allocates
|
||||
endpoints and descriptor FIFO memory and registers for complete event
|
||||
notification for the following pipes:
|
||||
|
||||
- system consumer pipe for data (pipe#0) : This BAM pipe will be used
|
||||
for transferring data from system memory to NANDc i.e., during write.
|
||||
|
||||
- system producer pipe for data (pipe#1) : This BAM pipe will be used
|
||||
for transferring data from NANDc to system memory i.e., during read.
|
||||
|
||||
- system consumer pipe for commands (pipe#2) : This BAM pipe will be
|
||||
used for both reading and writing to NANDc registers. It can be
|
||||
configured either as consumer pipe or producer pipe but as per HW
|
||||
team's recommendation it is configured as consumer pipe.
|
||||
|
||||
Control path:
|
||||
-------------
|
||||
Each NAND operation can be described as a set of BAM command or/and data
|
||||
descriptors.
|
||||
|
||||
A command descriptor(CD) points to the starting address of a command
|
||||
block. Each command block may contain a set of command elements where
|
||||
each command element is a single NANDc register read/write. The NAND
|
||||
driver submits all command descriptors to its system consumer pipe#2.
|
||||
|
||||
Data path:
|
||||
----------
|
||||
A Data Descriptor(DD) points to the start of a data block which is a sequential
|
||||
chunk of data.
|
||||
|
||||
For page write operations, the NAND driver submits data descriptors to system
|
||||
consumer pipe#0 and as per the descriptors submitted, the BAM reads data from
|
||||
the data block into the NANDc buffer.
|
||||
|
||||
For page read operations, the NAND driver submits data descriptors to system
|
||||
producer pipe#1 and as per the descriptors submitted, the BAM reads data from
|
||||
the NANDc buffer into the data block.
|
||||
|
||||
The driver submits a CD/DD using BAM driver APIs sps_transfer_one()/
|
||||
sps_transfer(). To this API, flags is passed as one of the arguments and if
|
||||
SPS_IOVEC_FLAG_CMD is passed, then it is identified as a CD. Otherwise, it is
|
||||
identified as a DD. The other valid SPS flags for a CD/DD are -
|
||||
|
||||
- SPS_IOVEC_FLAG_INT : This flag indicates BAM driver to raise BAM
|
||||
interrupt after the current descriptor with this flag has been
|
||||
processed by BAM HW. This flag is applicable for both CD and DD.
|
||||
|
||||
- SPS_IOVEC_FLAG_NWD : This flag indicates BAM HW to not process
|
||||
next descriptors until it receives an acknowledgement by NANDc
|
||||
that the current descriptor with this flag is completely
|
||||
executed. This flag is applicable only for a CD.
|
||||
|
||||
- SPS_IOVEC_FLAG_LOCK: This flag marks the beginning of a series of
|
||||
commands and it indicates that all the CDs submitted on this pipe
|
||||
must be executed atomically without any interruption by commands
|
||||
from other pipes. This is applicable only for a CD.
|
||||
|
||||
- SPS_IOVEC_FLAG_UNLOCK: This flag marks the end of a series of
|
||||
commands and it indicates that the other pipe that was locked due to
|
||||
SPS_IOVEC_FLAG_LOCK flag can be unblocked after the current CD
|
||||
with this flag is executed. This is applicable only for a CD.
|
||||
|
||||
- SPS_IOVEC_FLAG_EOT - This flag indicates to BAM driver that the
|
||||
current descriptor with this flag is the last descriptor submitted
|
||||
during write operation. This is applicable only for a DD.
|
||||
|
||||
Error handling:
|
||||
---------------
|
||||
After a page read/write complete notification from BAM, NAND driver validates
|
||||
the values read from NANDc registers to confirm the success/failure of page
|
||||
read/write operation. For example, after a page read/write is complete, the
|
||||
drivers reads the NANDc status registers to check for any operational errors,
|
||||
protection violation errors and device status errors, number of correctable/
|
||||
uncorrectable errors reported by the controller. Based on the error conditions
|
||||
that are met, the driver reports appropriate error codes to upper layers. The
|
||||
upper layers respond to these errors and take appropriate action.
|
||||
|
||||
Design
|
||||
======
|
||||
|
||||
The existing NAND driver (ADM based) can not be reused due to many major HW
|
||||
changes (see Introduction section) in the new NANDc core. Some of the complex
|
||||
features (Dual NAND controllers support) too are deprecated in the new NANDc.
|
||||
Hence, a new NAND driver is written to take care of both SPS/BAM changes and
|
||||
other controller specific changes. The rest of the interaction with MTD and
|
||||
YAFFS2 remains same as its previous version of NAND driver msm_nand.c.
|
||||
|
||||
Power Management
|
||||
================
|
||||
|
||||
Two clocks are supplied by the system's clock controller to NANDc - AHB clock
|
||||
and interface clock. The interface clock is the clock that drives some of the
|
||||
HW blocks within NANDc. As of now, both these clocks are always on. But NANDc
|
||||
provides clock gating if some of the QPIC clock control registers are
|
||||
configured. The clock gating is yet to be enabled by driver.
|
||||
|
||||
SMP/Multi-Core
|
||||
==============
|
||||
|
||||
The locking mechanism for page read/write operations is taken care of by the
|
||||
higher layers such as MTD/YAFFS2 and only one single page operation can happen
|
||||
at any time on a given partition. For a single page operation, there is always
|
||||
only one context associated within the driver and thus no additional handling
|
||||
is required within the driver. But it is possible for file system to issue
|
||||
one request on partition and at the same time to issue another request on
|
||||
another partition as each partition corresponds to different MTD block device.
|
||||
This situation is handled within the driver by properly acquiring a mutex lock
|
||||
before submitting any command/data descriptors to any of the BAM pipes.
|
||||
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
The same NAND device is accessible from both processors (Modem and Apps) and
|
||||
thus to avoid any configuration overwrite issues during a page operation,
|
||||
driver on each processor (Modem and Apps) must explicitly use BAM pipe
|
||||
lock/unlock mechanism. This is taken care of by the NAND driver. The partition
|
||||
violation issues are prevented by an MPU (Memory Protection Unit) that is
|
||||
attached to NANDc.
|
||||
|
||||
Performance
|
||||
===========
|
||||
|
||||
None.
|
||||
|
||||
Interface
|
||||
=========
|
||||
|
||||
The NAND driver registers each partition on NAND device as a MTD block device
|
||||
using mtd_device_register(). As part of this registration, the following ops
|
||||
(struct mtd_info *mtd) are registered with MTD layer for each partition:
|
||||
|
||||
mtd->_block_isbad = msm_nand_block_isbad;
|
||||
mtd->_block_markbad = msm_nand_block_markbad;
|
||||
mtd->_read = msm_nand_read;
|
||||
mtd->_write = msm_nand_write;
|
||||
mtd->_read_oob = msm_nand_read_oob;
|
||||
mtd->_write_oob = msm_nand_write_oob;
|
||||
mtd->_erase = msm_nand_erase;
|
||||
|
||||
msm_nand_block_isbad() - This checks if a block is bad or not by reading bad
|
||||
block byte in the first page of a block. A block is considered as bad if bad
|
||||
block byte location contains any value other than 0xFF.
|
||||
|
||||
msm_nand_block_markbad() - This marks a block as bad by writing 0 to the
|
||||
entire first page of the block and thus writing 0 to bad block byte location.
|
||||
|
||||
msm_nand_read/write() - This is used to read/write only main data from/to
|
||||
single/multiple pages within NAND device. The YAFFS2 file system can send
|
||||
read/write request for two types of data -
|
||||
|
||||
- Main data : This is the actual data to be read/written from/to a
|
||||
page during a read/write operation on this device. The size of this
|
||||
data request is typically based on the page size of the device
|
||||
(2K/4K).
|
||||
|
||||
- OOB(Out Of Band) data : This is the spare data that will be used by
|
||||
file system to keep track of its meta data/tags associated with the
|
||||
actual data. As of now, the file system needs only 16 bytes to
|
||||
accommodate this data. The NAND driver always writes this data
|
||||
towards the end of main data.
|
||||
|
||||
It is up to the file system whether or not to send a read/write request for OOB
|
||||
data along with main data.
|
||||
|
||||
msm_nand_read_oob()/write_oob() - This is used to read/write both main data
|
||||
and spare data from/to single/multiple pages within NAND device.
|
||||
|
||||
msm_nand_erase() - This erases the complete block by sending erase command to
|
||||
the device.
|
||||
|
||||
The YAFFS2 file system registers as the user of MTD device and uses the ops
|
||||
exposed by the NAND driver to perform read/write/erase operations on NAND
|
||||
device. As of now, the driver can work with only YAFFS2 file system. An
|
||||
attempt to use it with any other file system might demand additional changes
|
||||
in the driver.
|
||||
|
||||
Driver parameters
|
||||
=================
|
||||
|
||||
None.
|
||||
|
||||
Config options
|
||||
==============
|
||||
|
||||
The config option MTD_MSM_QPIC_NAND enables this driver.
|
||||
|
||||
Dependencies
|
||||
============
|
||||
|
||||
It depends on the following kernel components:
|
||||
|
||||
- SPS/BAM driver
|
||||
- MTD core layer
|
||||
- To add necessary NANDc and BAM resources to .dts file
|
||||
|
||||
It depends on the following non-kernel components:
|
||||
|
||||
The partition information of the NAND device must be passed by Modem subsystem
|
||||
to Apps boot loader and Apps boot loader must update the .dts file
|
||||
with the partition information as per the defined MTD bindings.
|
||||
|
||||
The detailed information on MTD bindings can be found at -
|
||||
Documentation/devicetree/bindings/mtd/msm_qpic_nand.txt
|
||||
|
||||
User space utilities
|
||||
====================
|
||||
|
||||
None.
|
||||
|
||||
Other
|
||||
=====
|
||||
|
||||
No changes other than device tree changes are anticipated.
|
||||
|
||||
Known issues
|
||||
============
|
||||
|
||||
None.
|
||||
|
||||
To do
|
||||
=====
|
||||
|
||||
The NANDc core supports clock gating and is not yet supported by the driver.
|
|
@ -60,6 +60,19 @@ config MTD_MSM_NAND
|
|||
help
|
||||
Support for some NAND chips connected to the MSM NAND controller.
|
||||
|
||||
config MTD_MSM_QPIC_NAND
|
||||
tristate "MSM QPIC NAND Device Support"
|
||||
depends on MTD && ARCH_MSM && !MTD_MSM_NAND
|
||||
select CRC16
|
||||
select BITREVERSE
|
||||
select MTD_NAND_IDS
|
||||
default n
|
||||
help
|
||||
Support for NAND controller in Qualcomm Parallel Interface
|
||||
controller (QPIC). This new controller supports BAM mode
|
||||
and BCH error correction mechanism. Based on the device
|
||||
capabilities either 4 bit or 8 bit BCH ECC will be used.
|
||||
|
||||
config MTD_DATAFLASH
|
||||
tristate "Support for AT45xxx DataFlash"
|
||||
depends on SPI_MASTER && EXPERIMENTAL
|
||||
|
|
|
@ -13,6 +13,7 @@ obj-$(CONFIG_MTD_PHRAM) += phram.o
|
|||
obj-$(CONFIG_MTD_PMC551) += pmc551.o
|
||||
obj-$(CONFIG_MTD_MS02NV) += ms02-nv.o
|
||||
obj-$(CONFIG_MTD_MSM_NAND) += msm_nand.o
|
||||
obj-$(CONFIG_MTD_MSM_QPIC_NAND) += msm_qpic_nand.o
|
||||
obj-$(CONFIG_MTD_MTDRAM) += mtdram.o
|
||||
obj-$(CONFIG_MTD_LART) += lart.o
|
||||
obj-$(CONFIG_MTD_BLOCK2MTD) += block2mtd.o
|
||||
|
|
2500
drivers/mtd/devices/msm_qpic_nand.c
Normal file
2500
drivers/mtd/devices/msm_qpic_nand.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue