Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents
Introduction

This documents provides the details about the Pl35x smc and pl35x nand drivers located in drivers/memory/pl353-smc.c and drivers/mtd/nand/raw/pl353_nand.c
Link for the source files: pl353-smc.c and pl353_nand.c
The SMC (PL353) supports two memory interfaces:
  • Interface 0 type SRAM/NOR.
  • Interface 1 type NAND.
For NOR, it is generic Linux CFI driver.

HW/IP Features

Controller Features

  • ONFI 1.0 compatible
  • supports up to 1GB device
  • 8/16-bit IO width with a single chip select
  • 16-word read/write FIFOs
  • 8-word command FIFO
  • Programmable IO Cycle timing
  • 1-bit ECC hardware with sw assist
  • Asynchronous memory operating mode

Driver Features

Supports only the mandatory ONFI 1.0 commands.

Table of Contents
Introduction

This documents provides the details about the Pl35x smc and pl35x nand drivers located in drivers/memory/pl353-smc.c and drivers/mtd/nand/raw/pl35x-nand-controller.c

Link for the source files: pl353-smc.c and pl35x-nand-controller.c

The SMC (PL353) supports two memory interfaces:
  • Interface 0 type SRAM/NOR.
  • Interface 1 type NAND.

For NOR, it is generic Linux CFI driver.

HW/IP Features

Controller Features

  • ONFI 1.0 compatible
  • supports up to 1GB device
  • 8/16-bit IO width with a single chip select
  • 16-word read/write FIFOs
  • 8-word command FIFO
  • Programmable IO Cycle timing
  • 1-bit ECC hardware with sw assist
  • Asynchronous memory operating mode

Driver Features

  • Supports only the mandatory ONFI 1.0 commands. i.e Reset, Read status, Read ID, Read Parameter Page, Read Page, Program Page, Erase Block, Set/Get Features
  • Supports BBT management
  • Supports ondie ecc devices
  • Support for hw ecc and sw ecc
  • support for 8 and 16 bit flash devices
  • Support for configuring the nand and nor timing parameters

Missing Features, Known issues, limitations

  • HW ecc support for devices with 2K page size up and oobsize up to 64 bytes. Beyond that the driver will choose sw ecc mechanism.
  • Driver has auto detection mechanism for ondie ecc devices and this support is available only for micron devices with oob size 64 bytes
  • NOR driver has been tested for single chip select configuration

Bad Block managementBad Block management

As part of the bbt management, driver reserves the last 4 blocks of the flash device for storing the bbt information. bbt management is similar to the standard Linux algorithm except the offset of storing the BBT signature and version; and also the locations reserved for storing the ecc information.

Kernel Configuration options

SMC Driver

The following kernel configuration options should be enabled for compiling the pl353 smc driver

Device Drivers -> Memory Control Drivers -> ARM PL353 Static Memory Controller(SMC) driver

CONFIG_ARM = y
CONFIG_PL353_SMC = y
Image RemovedImage Added

NAND Driver

The following kernel configuration options should be enabled for compiling the pl353 smc nand driver

Device Drivers -> Memory Technology Device (MTD) support -> NAND - > Raw/Parallel NAND Device Support ->ARM PL353 NAND flash driver

CONFIG_MTD_NAND = y
CONFIG_ARM = y
CONFIG_PL353_SMC = y
CONFIG_MTD_NAND_PL35X = y
Image RemovedImage Added

NOR Driver

Select the Device Drivers option and then, select Memory Technology Devices (MTD).
Finally, choose the RAM/ROM/Flash chip drivers option.
Detect flash chips by common flash interface (CFI) by selecting one of the following:
  • For the static build, choose the option <*> Detect flash chips by Common Flash Interface (CFI).
  • For build as a module, choose the option <M> Detect flash chips by Common Flash Interface (CFI).
To build support for the AMD select one of the following:
  • For static build, choose the option <*> Support for AMD/Fujitsu flash chips.
  • For build as a module, choose the option <M> Support for AMD/Fujitsu flash chips.
To build support for Intel select one of the following:
  • For static build, choose the option <*> Support for Intel/Sharp flash chips.
  • For build as a module, choose the option <M> Support for Intel/Sharp flash chips.
To build support for Mapping drivers for chip access
  • For static build, <*> Flash device in physical memory map based on OF description
  • For build as a module, <M> Flash device in physical memory map based on OF description



Device Tree

For more details on nand devicetree details, please refer Documentation/devicetree/bindings/mtd/nand.txt
Link: Device Tree Binding info
refer pl353-smc.yaml

The timing parameters t0, t1, t2, t3, t4, t5, t6 denotes
nand-cycle-t0 : Read cycle time(t_rc).
nand-cycle-t1 : Write cycle time(t_wc).
nand-cycle-t2 : re_n assertion delay(t_rea).
nand-cycle-t3 : we_n de-assertion delay(t_wp).
nand-cycle-t4 : Status read time(t_clr)
nand-cycle-t5 : ID read time(t_ar)
nand-cycle-t6 : busy to re_n(t_rr)

Code Block
themeMidnight
NAND Node:
--------------
		smcc: memorymemory-controller@e000e000 {
			#address-cells = <1>; 			#size-cells = <1>; 			status = "disabled";
			clock-names	compatible = "memclkarm,pl353-smc-r2p1", "apb_pclkarm,primecell";
			clocks = <&clkc 11>, <&clkc 44>; 			compatible = "arm,pl353-smc-r2p1", "arm,primecell";
			interrupt-parent = <&intc>;
			interrupts = <0 18 4>;
			ranges ;
			reg = <0xe000e000 0x1000>;
			nand0: flash@e1000000 {
				       reg = <0xe000e000 0x1000>;
             status = "disabledokay";
				compatible = "arm,pl353-nand-r2p1";
				reg = <0xe1000000 0x1000000>;
				#address-cells = <1>;
				#size-cells = <1>;
				/* Depending upon the ecc support, change nand-ecc-mode to "hw" */
 				nand-ecc-mode = "on-die";
				/* Depending upon the bus width configuration change it to 8 or 16 */
				nand-bus-width = <8>;
                partition@nand-fsbl-uboot {              clock-names = "memclk", "apb_pclk";
              clocks = <0x1 0xb 0x1 0x2c>;
              ranges = <0x0 0x0 0xe1000000 0x1000000 0x1 0x0 0xe2000000 0x2000000 0x2 0x0 0xe4000000 0x2000000>;
              #address-cells = <0x2>;
     label = "nand-fsbl-uboot";       #size-cells = <0x1>;
           reg = <0x0 0x100000>;interrupt-parent = <0x4>;
              };interrupts = <0x0 0x12 0x4>;
            partition@nand-linux { phandle = <0x26>;

                labelnand-controller@0,0 {
					compatible = "arm,pl353-nand-linuxr2p1";
                    reg = <0x100000<0x0 0x0 0x500000>0x1000000>;
                 }   status = "okay";
                partition@nand-device-tree {    #address-cells = <0x1>;
                    label#size-cells = "nand-device-tree"<0x0>;
                    regphandle = <0x600000 0x20000><0x27>;

               };     nand@0 {
							reg = <0x0>;
       partition@nand-rootfs {                    #address-cells label = "nand-rootfs";
 <0x1>;
                  reg = <0x620000 0x5E0000>;       #size-cells = <0x1>;
       };                 partition@nand-bitstream {   nand-ecc-mode = "hw";
               label = "nand-bitstream";           nand-on-flash-bbt;

        reg = <0xC00000 0x400000>;                 partition@0 {
};               } ;         } ;  	label NOR node:
---------
		smcc: memory-controller@e000e000 {
			#address-cells = <1>;
			#size-cells = <1>;
			status = "disabled";
			clock-names = "memclk", "apb_pclk";
			clocks = <&clkc 11>, <&clkc 44>;
			compatible = "arm,pl353-smc-r2p1", "arm,primecell";
			interrupt-parent = <&intc>;
			interrupts = <0 18 4>;
			ranges ;
			reg = <0xe000e000 0x1000>;
			nor0: flash@e2000000 {
				status = "disabled";
				compatible = "cfi-flash";
				reg = <0xe2000000 0x2000000>;
	= "nand-fsbl-uboot";
                                reg = <0x0 0x10000000>;
                            };
 	bank-width = <1>;                 		xlnx,sram-cycle-t0 = <0xb>};
           		xlnx,sram-cycle-t1 = <0xb>   };
	 }; 

NOR node:
---------
		smcc: memory-controller@e000e000 {
 			xlnx,sram-cycle-t2#address-cells = <0x4><1>;
           		xlnx,sram-cycle-t3 = <0x4>;
           		xlnx,sram-cycle-t4 = <0x3>;
          		xlnx,sram-cycle-t5 = <0x3>;
           		xlnx,sram-cycle-t6 = <0x2>;
			#size-cells = <1>;
			status = "disabled";
			clock-names = "memclk", "apb_pclk";
			clocks = <&clkc 11>, <&clkc 44>;
			compatible = "arm,pl353-smc-r2p1", "arm,primecell";
			interrupt-parent = <&intc>;
			interrupts = <0 18 4>;
			ranges ;
			reg = <0xe000e000 0x1000>;
			nor0: flash@e2000000 {
				status = "disabled";
				compatible = "cfi-flash";
				reg = <0xe2000000 0x2000000>;
	           		#addressbank-cellswidth = <1>;
           		#size-cellsxlnx,sram-cycle-t0 = <1><0xb>;
           		partition@norxlnx,sram-fsblcycle-uboott1 {= <0xb>;
           		xlnx,sram-cycle-t2 = <0x4>;
   label = "nor-fsbl-uboot";      		xlnx,sram-cycle-t3 = <0x4>;
          reg 		xlnx,sram-cycle-t4 = <0x0 0x100000><0x3>;

          		}xlnx,sram-cycle-t5 = <0x3>;
           		partition@nor-linux {
xlnx,sram-cycle-t6 = <0x2>;
           		#address-cells = <1>;
    label = "nor-linux";                    reg = <0x100000 0x500000>;
           		}		#size-cells = <1>;
           		partition@nor-devicefsbl-treeuboot {

                  label = "nor-devicefsbl-treeuboot";
                   reg = <0x600000<0x0 0x20000>0x100000>;
           		};
            		partition@nor-rootfslinux {
                   label = "nor-rootfslinux";
                   reg = <0x620000<0x100000 0x5E0000>0x500000>;
            		};
           		partition@nor-bitstreamdevice-tree {
                   label = "nor-bitstreamdevice-tree";
                   reg = <0xC00000<0x600000 0x400000>0x20000>;
            		} ;
			};;
            		partition@nor-rootfs {
                   label }= ;

Performance

ModeWrite SpeedRead Speed8 bit8MB/sec9.5MB/sec16bit  7MB/sec 11.1MB/sec

Test Procedure

JFFS2 filesystem

How to Run
Code Block
themeMidnight
Erase the flash partition:
 
flash_eraseall <device>
 
Mount the partition:
 
mount -t jffs2 <block device> <directory>
 
Perform file read/write and compare operation:
 
unmount the partition:
umount <directory>
 

UBIFS file system

View file
nameUBIFS.docx
Images:
View file
nameubifs.zip

Flashcp

Code Block
themeMidnight
flashcp -v <device name>

mtd_speedtest

Select the mtd_speedtest from the kernel configuration menu:
Image Removed
Build it as module and use the generated .ko from the location drivers/mtd/tests/

How to run

Speed Test

Code Block
themeMidnight
insmod mtd_speedtest.ko -device=<mtd device number>
 
rmmod mtd_speedtest
 

Expected Output

Code Block
themeMidnight
root@xilinx-zc702-2020_1:~# insmod /lib/modules/`uname -r`/kernel/drivers/mtd/tests/mtd_speedtest.ko dev=1
 
=================================================
mtd_speedtest: MTD device: 1
mtd_speedtest: MTD device size 5242880, eraseblock size 131072, page size 2048, count of eraseblocks 40, pages per eraseblock 64, OOB size 64
mtd_test: scanning for bad eraseblocks
mtd_test: scanned 40 eraseblocks, 0 are bad
mtd_speedtest: testing eraseblock write speed
mtd_speedtest: eraseblock write speed is 8025 KiB/s
mtd_speedtest: testing eraseblock read speed
mtd_speedtest: eraseblock read speed is 9534 KiB/s
mtd_speedtest: testing page write speed
mtd_speedtest: page write speed is 7925 KiB/s
mtd_speedtest: testing page read speed
mtd_speedtest: page read speed is 9499 KiB/s
mtd_speedtest: testing 2 page write speed
mtd_speedtest: 2 page write speed is 7962 KiB/s
mtd_speedtest: testing 2 page read speed
mtd_speedtest: 2 page read speed is 9516 KiB/s
mtd_speedtest: Testing erase speed
mtd_speedtest: erase speed is 170666 KiB/s
mtd_speedtest: Testing 2x multi-block erase speed
mtd_speedtest: 2x multi-block erase speed is 341333 KiB/s
mtd_speedtest: Testing 4x multi-block erase speed
mtd_speedtest: 4x multi-block erase speed is 341333 KiB/s
mtd_speedtest: Testing 8x multi-block erase speed
mtd_speedtest: 8x multi-block erase speed is 341333 KiB/s
mtd_speedtest: Testing 16x multi-block erase speed
mtd_speedtest: 16x multi-block erase speed is 341333"nor-rootfs";
                   reg = <0x620000 0x5E0000>;
            		};
           		partition@nor-bitstream {
                   label = "nor-bitstream";
                   reg = <0xC00000 0x400000>;
            	} ;
			};
        } ;

Performance


ModeWrite SpeedRead Speed
8 bit3.8MB/sec5.6MB/sec
16bit  5.6MB/sec 8MB/sec

Test Procedure


JFFS2 filesystem


How to Run
Code Block
themeMidnight
Erase the flash partition:
 
flash_eraseall <device>
 
Mount the partition:
 
mount -t jffs2 <block device> <directory>
 
Perform file read/write and compare operation:
 
unmount the partition:
umount <directory>
 

UBIFS file system



View file
nameUBIFS.docx




Images:
View file
nameubifs.zip


Flashcp

Code Block
themeMidnight
flashcp -v <device name>

mtd_speedtest


Select the mtd_speedtest from the kernel configuration menu:

Image Added

Build it as module and use the generated .ko from the location drivers/mtd/tests/

How to run

Speed Test

Code Block
themeMidnight
insmod mtd_speedtest.ko -device=<mtd device number>
 
rmmod mtd_speedtest
 

Expected Output

Code Block
themeMidnight
root@xilinx-zc702-2020_1:~# insmod /lib/modules/`uname -r`/kernel/drivers/mtd/tests/mtd_speedtest.ko dev=1
 
=================================================
mtd_speedtest: MTD device: 1
mtd_speedtest: MTD device size 5242880, eraseblock size 131072, page size 2048, count of eraseblocks 40, pages per eraseblock 64, OOB size 64
mtd_test: scanning for bad eraseblocks
mtd_test: scanned 40 eraseblocks, 0 are bad
mtd_speedtest: testing eraseblock write speed
mtd_speedtest: eraseblock write speed is 8025 KiB/s
mtd_speedtest: Testingtesting 32xeraseblock multi-blockread erase speed
mtd_speedtest: 32xeraseblock multi-blockread erase speed is 3413339534 KiB/s
mtd_speedtest: Testingtesting 64xpage multi-block erasewrite speed
mtd_speedtest: page write speed is 7925 KiB/s
mtd_speedtest: 64x multi-block erasetesting page read speed
mtd_speedtest: page read speed is 3413339499 KiB/s
mtd_speedtest: finished
=================================================
root@xilinx-zc702-2020_1:~#
 

oob test

Code Block
themeMidnight
insmod mtd_oob.ko -device=<mtd device number>
 
rmmod mtd_speedtest
 

Expected Output

Code Block
themeMidnight
root@xilinx-zc702-2020_1:~# insmod /lib/modules/`uname -r`/kernel/drivers/mtd/tests/mtd_oobtest.ko dev=1
 
=================================================
mtd_oobtest: MTD device: 1
mtd_oobtest: MTD device size 5242880, eraseblock size 131072, page size 2048, count of eraseblocks 40, pages per eraseblock 64, OOB size 64
mtd_test: scanning for bad eraseblocks
mtd_test: scanned 40 eraseblocks, 0 are bad
mtd_oobtest: test 1 of 5
mtd_oobtest: writing OOBs of whole device
mtd_oobtest: written up to eraseblock 0
mtd_oobtest: written 40 eraseblocks
mtd_oobtest: verifying all eraseblocks
mtd_oobtest: verified up to eraseblock 0
mtd_oobtest: verified 40 eraseblocks
mtd_oobtest: test 2 of 5
mtd_oobtest: writing OOBs of whole device
mtd_oobtest: written up to eraseblock 0
mtd_oobtest: written 40 eraseblocks
mtd_oobtest: verifying all eraseblocks
mtd_oobtest: verified up to eraseblock 0
mtd_oobtest: verified 40 eraseblocks
mtd_oobtest: test 3 of 5
mtd_oobtest: writing OOBs of whole device
mtd_oobtest: written up to eraseblock 0
mtd_oobtest: written 40 eraseblocks
mtd_oobtest: verifying all eraseblocks
mtd_oobtest: verified up to eraseblock 0
mtd_oobtest: verified 40 eraseblocks
mtd_oobtest: test 4 testing 2 page write speed
mtd_speedtest: 2 page write speed is 7962 KiB/s
mtd_speedtest: testing 2 page read speed
mtd_speedtest: 2 page read speed is 9516 KiB/s
mtd_speedtest: Testing erase speed
mtd_speedtest: erase speed is 170666 KiB/s
mtd_speedtest: Testing 2x multi-block erase speed
mtd_speedtest: 2x multi-block erase speed is 341333 KiB/s
mtd_speedtest: Testing 4x multi-block erase speed
mtd_speedtest: 4x multi-block erase speed is 341333 KiB/s
mtd_speedtest: Testing 8x multi-block erase speed
mtd_speedtest: 8x multi-block erase speed is 341333 KiB/s
mtd_speedtest: Testing 16x multi-block erase speed
mtd_speedtest: 16x multi-block erase speed is 341333 KiB/s
mtd_speedtest: Testing 32x multi-block erase speed
mtd_speedtest: 32x multi-block erase speed is 341333 KiB/s
mtd_speedtest: Testing 64x multi-block erase speed
mtd_speedtest: 64x multi-block erase speed is 341333 KiB/s
mtd_speedtest: finished
=================================================
root@xilinx-zc702-2020_1:~#
 


oob test


Code Block
themeMidnight
insmod mtd_oob.ko -device=<mtd device number>
 
rmmod mtd_speedtest
 

Expected Output

Code Block
themeMidnight
root@xilinx-zc702-2020_1:~# insmod /lib/modules/`uname -r`/kernel/drivers/mtd/tests/mtd_oobtest.ko dev=1
 
=================================================
mtd_oobtest: MTD device: 1
mtd_oobtest: MTD device size 5242880, eraseblock size 131072, page size 2048, count of eraseblocks 40, pages per eraseblock 64, OOB size 64
mtd_test: scanning for bad eraseblocks
mtd_test: scanned 40 eraseblocks, 0 are bad
mtd_oobtest: test 1 of 5
mtd_oobtest: attemptingwriting toOOBs startof writewhole past end of OOB
device
mtd_oobtest: anwritten errorup to is expected...eraseblock 0
mtd_oobtest: errorwritten occurred40 aseraseblocks
expected
mtd_oobtest: attemptingverifying to start read past end of OOBall eraseblocks
mtd_oobtest: verified anup errorto is expected...eraseblock 0
mtd_oobtest: errorverified occurred40 aseraseblocks
expected
mtd_oobtest: attemptingtest to write past end 2 of device5
mtd_oobtest: anwriting errorOOBs of is expected...whole device
mtd_oobtest: errorwritten up occurredto aseraseblock expected0
mtd_oobtest: attemptingwritten to40 read past end of deviceeraseblocks
mtd_oobtest: verifying all eraseblocks
mtd_oobtest: anverified up errorto is expected...eraseblock 0
mtd_oobtest: errorverified occurred40 aseraseblocks
expected
mtd_oobtest: attemptingtest to3 writeof past end of device
5
mtd_oobtest: anwriting OOBs errorof is expected...whole device
mtd_oobtest: written errorup occurredto aseraseblock expected0
mtd_oobtest: attemptingwritten to40 read past end of deviceeraseblocks
mtd_oobtest: verifying all eraseblocks
mtd_oobtest: verified anup errorto is expected...eraseblock 0
mtd_oobtest: errorverified occurred40 aseraseblocks
expected
mtd_oobtest: test 54 of 5
mtd_oobtest: writingattempting OOBs to start write past end of wholeOOB
device
mtd_oobtest: writtenan uperror to eraseblock 0
is expected...
mtd_oobtest: writtenerror upoccurred toas eraseblock 0expected
mtd_oobtest: attempting writtento 39start eraseblocks
mtd_oobtest: verifying all eraseblocksread past end of OOB
mtd_oobtest: verifiedan uperror to eraseblock 0is expected...
mtd_oobtest: verifiederror 39occurred as eraseblocksexpected
mtd_oobtest: attempting to finishedwrite withpast 0end errors
=================================================
root@xilinx-zc702-2020_1:~#
 

Change Log

  • 2016.3

    • Summary
      • None
    • Commits
      • None
  • 2016.4

    • Summary
      • None
    • Commits
      • None
  • 2017.1

    • Summary
      • Update smc nand driver as per latest kernel changes
    • Commits
  • 2017.2

    • Summary
      • None
    • Commits
      • None
  • 2017.3

    • Summary
      • None
    • Commits
      • None
  • 2017.4

    • None
  • 2018.1

    • Summary
      • Do bit operations on offset not on virtual address
    • Commits
  • 2018.2

    • Summary
      • Fix for incorrect ooblayout offset update
    • Commits
  • 2018.3

    • Summary
      • Implement De-select in chip select
      • Add ECC checking for on-die nand flash
    • Commits
  • 2019.1

    • Summary
      • Implemented →exec_op
    • Commits
  • 2019
    of device
    mtd_oobtest: an error is expected...
    mtd_oobtest: error occurred as expected
    mtd_oobtest: attempting to read past end of device
    mtd_oobtest: an error is expected...
    mtd_oobtest: error occurred as expected
    mtd_oobtest: attempting to write past end of device
    mtd_oobtest: an error is expected...
    mtd_oobtest: error occurred as expected
    mtd_oobtest: attempting to read past end of device
    mtd_oobtest: an error is expected...
    mtd_oobtest: error occurred as expected
    mtd_oobtest: test 5 of 5
    mtd_oobtest: writing OOBs of whole device
    mtd_oobtest: written up to eraseblock 0
    mtd_oobtest: written up to eraseblock 0
    mtd_oobtest: written 39 eraseblocks
    mtd_oobtest: verifying all eraseblocks
    mtd_oobtest: verified up to eraseblock 0
    mtd_oobtest: verified 39 eraseblocks
    mtd_oobtest: finished with 0 errors
    =================================================
    root@xilinx-zc702-2020_1:~#
     

    Change Log

    • 2023.2

      • Summary
        • None
      • Commits
        • None
    • 2023.1

      • Summary
        • None
      • Commits
        • None
    • 2022.2

      • Summary
        • None
      • Commits
        • None
      2020
    • 2022.1

      • Summary
        • Updated the driver as per new kernel NAND framework
        Commits
          75721e47 updated the driver under new NAND framework
        • Add support for the ARM PL353 SMC NAND controller
        • Set the nand chip node as the flash node
      • Commits

    Mainline Status

    PL353 SMC Driver - Done

    ...