F-RAM Support under Linux – KBA223028

Version: **

 

Question:

How can I add support for serial F-RAM devices to Linux?

 

Answer:

Cypress F-RAM parts are drop-in compatible with standard SPI flash. Both devices use identical packages, pinouts, command codes, and register layouts. So, the standard Linux MTD driver stack for SPI flash can also be used for serial F-RAM. In this case, the device ignores the erase commands and the status register never goes busy, so that polling loops immediately complete.

 

In current Linux kernels, the flash chip driver is split up into drivers/mtd/spi-nor/spi-nor.c and drivers/mtd/devices/m25p80.c. Underneath this chip driver, a hardware-specific SPI controller driver is needed. That controller driver usually also comes with the board support package as part of the Linux kernel source tree. With these drivers enabled in the kernel configuration menu, a F-RAM-specific device ID must be added to the list of supported devices in spi-nor.c. For example, for the CY15B104Q 4-Mbit device, the following entry can be added to spi_nor_ids[] in drivers/mtd/spi-nor/spi-nor.c.

 

               { "cy15b104q",  INFO(0x7f7f7f, 0,        512, 1024, 0) },

 

Then, the part is probed correctly:

 

     Feb  5 11:10:40 muc-cse-01 kernel: Found Cypress(TM) PISMO(TM) PCI card rev 3

     Feb  5 11:10:40 muc-cse-01 kernel: Active memory bank at CS0: 128 MB, 8-bit

     Feb  5 11:10:42 muc-cse-01 kernel: m25p80 spi0.0: found cy15b104q, expected m25p80

     Feb  5 11:10:42 muc-cse-01 kernel: m25p80 spi0.0: cy15b104q (512 Kbytes)

 

     # cat /proc/mtd

     dev:    size erasesize  name

     mtd0: 00080000 00000200 "spi0.0"

 

The raw read and write operations to the F-RAM are working:

 

     # dd if=/dev/mtd0 bs=32 count=1 | od -v -Ax -tx1

     1+0 records in

     1+0 records out

     32 bytes copied, 0.000133754 s, 239 kB/s

     000000 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

     000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

     000020

 

     # echo "Hello world!" > /dev/mtd0

     # dd if=/dev/mtd0 bs=32 count=1 | od -v -Ax -tx1

     1+0 records in

     1+0 records out

     32 bytes copied, 0.000129754 s, 247 kB/s

     000000 48 65 6c 6c 6f 20 77 6f 72 6c 64 21 0a 00 00 00

     000010 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

     000020

 

Normal MTD partitioning also works. Note that newer 1.8 V devices have the 9 device ID bytes coming out in the other order which requires a minor change in the ID entry, but the idea is the same. For the 2-Mbit part the device size changes from 512 * 1024 to 256 * 1024 (256 kB) in the ID entry field.

 

If a file system is required on top of the MTD, you can easily create a small FAT file system if you define a sector scheme with 512 byte sectors. The above ID entry specifies 1024 sectors of 512 bytes each. Basically, you can define any sector layout you want (if the total sum equals the device size). This is possible since the device ignores the sector erase commands and because there is no restriction regarding write size. For classic hard disks, 512 bytes is used. You can create a FAT on the MTD block device, as shown in the following log: