/
UFS Linux driver

UFS Linux driver

Introduction

The UFS Host Controller core is a standard based Serial Interface Engine for implementing a UFS interface in compliance with the UFS Architecture Specification [UFS] and the UFS Host Controller Specification [UFSHCI]. The UFS Host Controller application layer connects to a UniPro protocol stack and M-PHY. Both, UniPro protocol stack and M-PHY can be considered part of the UFS Host Controller.
The UFS Host Controller IP is a high-performance interface that is primarily used in mobile devices where data is stored on non-volatile mass storage memory device.

The primary blocks of the ufshc core architecture are

  • UFS Transport Protocol Layer

  • UFS InterConnect Layer, which consists of the following:

    • UniPro protocol stack

    • M-PHY

Features Supported in HW

  • Pre-configured for up to 32 task requests

  • Pre-configured for up to 8 task management requests

  • Support to pre-fetch more than one PRD entry (up to 16 PRD entries)

  • Supports the following UFS2.0 features

    • Higher speed up to HS-G3 (High-Speed Gear 3)

    • Symmetric 2RX-2TX lanes

    • Pre-configured for up to 2 TX/RX lanesSupport for the full range of UPIU packets, from 32 byte up to 64 kB

  • Supports the following UFS 3.0 features

    • Higher speed up to HS-G4 (High Speed Gear 4)

  • Supports UFS Card Detection

  • Supports 40-bit RMMI data interface

  • Auto-hibernate entry and exit sequence

  • With the UniPro stack and M-PHY, provides a high performance and reliable connection to the UFS Flash Memory Device.

  • Scatter/Gather DMA to transfer large data blocks

Features supported in driver

  • Supported UPIUs

    • Command/Response

    • Query Request/Query Response

    • Task Management (Not tested)

  • Interrupt mode of operation

  • PHY Configuration setup

  • UIC commands

  • Vendor specific interrupts (CIS, CRS, CTES) handling

  • Manual Hibernate entry and exit

Driver Missing features, Known Issues and Limitations

  • Disabled AH(Auto-Hibernate) feature

  • Supported only PWM-G1

Device Configuration

By default (any new UFS device) all the Logical Units were in disabled state, which means we cannot access UFS memory from the user space unless device is configured with the required number of Logical Units.

As part of the device configuration, Logical Units must be enabled with required amount of memory assigned to it.

This device configuration can be done in two ways

  1. UFS BareMetal application (ufspsxc_setluncfg_example.c)

  2. open source utility (ufs-utils) from Linux (refer the readme for some top level details ufs-utils/README.md at dev · SanDisk-Open-Source/ufs-utils)

Commands to perform the basic configurations(LU enable and assign memory) to the Logical Units using ufs-utils

  1. Use the below command dump the configuration descriptor into “ufsconfig” file in binary format and also displays the descriptor content on the terminal

versal2-common:/home/basecamp# ufs-utils desc -t 1 -D ufsconfig -p /dev/bsg/ufs-bsg0 Config Device Descriptor: [Byte offset 0x0]: bLength = 0xe6 Config Device Descriptor: [Byte offset 0x1]: bDescriptorType = 0x1 Config Device Descriptor: [Byte offset 0x2]: bConfDescContinue = 0x0 Config Device Descriptor: [Byte offset 0x3]: bBootEnable = 0x1 Config Device Descriptor: [Byte offset 0x4]: bDescrAccessEn = 0x0 Config Device Descriptor: [Byte offset 0x5]: bInitPowerMode = 0x1 Config Device Descriptor: [Byte offset 0x6]: bHighPriorityLUN = 0x7f Config Device Descriptor: [Byte offset 0x7]: bSecureRemovalType = 0x0 Config Device Descriptor: [Byte offset 0x8]: bInitActiveICCLevel = 0x0 Config Device Descriptor: [Byte offset 0x9]: wPeriodicRTCUpdate = 0x0 Config Device Descriptor: [Byte offset 0xb]: bHPBControl = 0x1 Config Device Descriptor: [Byte offset 0xc]: bRPMBRegionEnable = 0x0 Config Device Descriptor: [Byte offset 0xd]: bRPMBRegion1Size = 0x0 Config Device Descriptor: [Byte offset 0xe]: bRPMBRegion2Size = 0x0 Config Device Descriptor: [Byte offset 0xf]: bRPMBRegion3Size = 0x0 Config Device Descriptor: [Byte offset 0x10]: bWriteBoosterBufferPreserveUserSpaceEn = 0x0 Config Device Descriptor: [Byte offset 0x11]: bWriteBoosterBufferType = 0x0 Config Device Descriptor: [Byte offset 0x12]: dNumSharedWriteBoosterBufferAllocUnits = 0x0 Config 0 Unit Descriptor: Config Descriptor: [Byte offset 0x0]: bLUEnable = 0x1 Config Descriptor: [Byte offset 0x1]: bBootLunID = 0x1 Config Descriptor: [Byte offset 0x2]: bLUWriteProtect = 0x0 Config Descriptor: [Byte offset 0x3]: bMemoryType = 0x0 Config Descriptor: [Byte offset 0x4]: dNumAllocUnits = 0x1400 Config Descriptor: [Byte offset 0x8]: bDataReliability = 0x0 Config Descriptor: [Byte offset 0x9]: bLogicalBlockSize = 0xc Config Descriptor: [Byte offset 0xa]: bProvisioningType = 0x0 Config Descriptor: [Byte offset 0xb]: wContextCapabilities = 0x0 Config Descriptor: [Byte offset 0x10]: wLUMaxActiveHPBRegions = 0x0 Config Descriptor: [Byte offset 0x12]: wHPBPinnedRegionStartIdx = 0x0 Config Descriptor: [Byte offset 0x14]: wNumHPBPinnedRegions = 0x0 Config Descriptor: [Byte offset 0x16]: dLUNumWriteBoosterBufferAllocUnits = 0x0 Config 1 Unit Descriptor: Config Descriptor: [Byte offset 0x0]: bLUEnable = 0x1 Config Descriptor: [Byte offset 0x1]: bBootLunID = 0x0 Config Descriptor: [Byte offset 0x2]: bLUWriteProtect = 0x0 Config Descriptor: [Byte offset 0x3]: bMemoryType = 0x0 Config Descriptor: [Byte offset 0x4]: dNumAllocUnits = 0x100 Config Descriptor: [Byte offset 0x8]: bDataReliability = 0x0 Config Descriptor: [Byte offset 0x9]: bLogicalBlockSize = 0xc Config Descriptor: [Byte offset 0xa]: bProvisioningType = 0x0 Config Descriptor: [Byte offset 0xb]: wContextCapabilities = 0x0 Config Descriptor: [Byte offset 0x10]: wLUMaxActiveHPBRegions = 0x0 Config Descriptor: [Byte offset 0x12]: wHPBPinnedRegionStartIdx = 0x0 Config Descriptor: [Byte offset 0x14]: wNumHPBPinnedRegions = 0x0 Config Descriptor: [Byte offset 0x16]: dLUNumWriteBoosterBufferAllocUnits = 0x0 Config 2 Unit Descriptor: Config Descriptor: [Byte offset 0x0]: bLUEnable = 0x1 Config Descriptor: [Byte offset 0x1]: bBootLunID = 0x0 Config Descriptor: [Byte offset 0x2]: bLUWriteProtect = 0x0 Config Descriptor: [Byte offset 0x3]: bMemoryType = 0x0 Config Descriptor: [Byte offset 0x4]: dNumAllocUnits = 0x400 Config Descriptor: [Byte offset 0x8]: bDataReliability = 0x0 Config Descriptor: [Byte offset 0x9]: bLogicalBlockSize = 0xc Config Descriptor: [Byte offset 0xa]: bProvisioningType = 0x0 Config Descriptor: [Byte offset 0xb]: wContextCapabilities = 0x0 Config Descriptor: [Byte offset 0x10]: wLUMaxActiveHPBRegions = 0x0 Config Descriptor: [Byte offset 0x12]: wHPBPinnedRegionStartIdx = 0x0 Config Descriptor: [Byte offset 0x14]: wNumHPBPinnedRegions = 0x0 Config Descriptor: [Byte offset 0x16]: dLUNumWriteBoosterBufferAllocUnits = 0x0 Config 3 Unit Descriptor: Config Descriptor: [Byte offset 0x0]: bLUEnable = 0x0 Config Descriptor: [Byte offset 0x1]: bBootLunID = 0x0 Config Descriptor: [Byte offset 0x2]: bLUWriteProtect = 0x0 Config Descriptor: [Byte offset 0x3]: bMemoryType = 0x0 Config Descriptor: [Byte offset 0x4]: dNumAllocUnits = 0x0 Config Descriptor: [Byte offset 0x8]: bDataReliability = 0x0 Config Descriptor: [Byte offset 0x9]: bLogicalBlockSize = 0xc Config Descriptor: [Byte offset 0xa]: bProvisioningType = 0x0 Config Descriptor: [Byte offset 0xb]: wContextCapabilities = 0x0 Config Descriptor: [Byte offset 0x10]: wLUMaxActiveHPBRegions = 0x0 Config Descriptor: [Byte offset 0x12]: wHPBPinnedRegionStartIdx = 0x0 Config Descriptor: [Byte offset 0x14]: wNumHPBPinnedRegions = 0x0 Config Descriptor: [Byte offset 0x16]: dLUNumWriteBoosterBufferAllocUnits = 0x0 Config 4 Unit Descriptor: Config Descriptor: [Byte offset 0x0]: bLUEnable = 0x0 Config Descriptor: [Byte offset 0x1]: bBootLunID = 0x0 Config Descriptor: [Byte offset 0x2]: bLUWriteProtect = 0x0 Config Descriptor: [Byte offset 0x3]: bMemoryType = 0x0 Config Descriptor: [Byte offset 0x4]: dNumAllocUnits = 0x0 Config Descriptor: [Byte offset 0x8]: bDataReliability = 0x0 Config Descriptor: [Byte offset 0x9]: bLogicalBlockSize = 0xc Config Descriptor: [Byte offset 0xa]: bProvisioningType = 0x0 Config Descriptor: [Byte offset 0xb]: wContextCapabilities = 0x0 Config Descriptor: [Byte offset 0x10]: wLUMaxActiveHPBRegions = 0x0 Config Descriptor: [Byte offset 0x12]: wHPBPinnedRegionStartIdx = 0x0 Config Descriptor: [Byte offset 0x14]: wNumHPBPinnedRegions = 0x0 Config Descriptor: [Byte offset 0x16]: dLUNumWriteBoosterBufferAllocUnits = 0x0 Config 5 Unit Descriptor: Config Descriptor: [Byte offset 0x0]: bLUEnable = 0x0 Config Descriptor: [Byte offset 0x1]: bBootLunID = 0x0 Config Descriptor: [Byte offset 0x2]: bLUWriteProtect = 0x0 Config Descriptor: [Byte offset 0x3]: bMemoryType = 0x0 Config Descriptor: [Byte offset 0x4]: dNumAllocUnits = 0x0 Config Descriptor: [Byte offset 0x8]: bDataReliability = 0x0 Config Descriptor: [Byte offset 0x9]: bLogicalBlockSize = 0xc Config Descriptor: [Byte offset 0xa]: bProvisioningType = 0x0 Config Descriptor: [Byte offset 0xb]: wContextCapabilities = 0x0 Config Descriptor: [Byte offset 0x10]: wLUMaxActiveHPBRegions = 0x0 Config Descriptor: [Byte offset 0x12]: wHPBPinnedRegionStartIdx = 0x0 Config Descriptor: [Byte offset 0x14]: wNumHPBPinnedRegions = 0x0 Config Descriptor: [Byte offset 0x16]: dLUNumWriteBoosterBufferAllocUnits = 0x0 Config 6 Unit Descriptor: Config Descriptor: [Byte offset 0x0]: bLUEnable = 0x0 Config Descriptor: [Byte offset 0x1]: bBootLunID = 0x0 Config Descriptor: [Byte offset 0x2]: bLUWriteProtect = 0x0 Config Descriptor: [Byte offset 0x3]: bMemoryType = 0x0 Config Descriptor: [Byte offset 0x4]: dNumAllocUnits = 0x0 Config Descriptor: [Byte offset 0x8]: bDataReliability = 0x0 Config Descriptor: [Byte offset 0x9]: bLogicalBlockSize = 0xc Config Descriptor: [Byte offset 0xa]: bProvisioningType = 0x0 Config Descriptor: [Byte offset 0xb]: wContextCapabilities = 0x0 Config Descriptor: [Byte offset 0x10]: wLUMaxActiveHPBRegions = 0x0 Config Descriptor: [Byte offset 0x12]: wHPBPinnedRegionStartIdx = 0x0 Config Descriptor: [Byte offset 0x14]: wNumHPBPinnedRegions = 0x0 Config Descriptor: [Byte offset 0x16]: dLUNumWriteBoosterBufferAllocUnits = 0x0 Config 7 Unit Descriptor: Config Descriptor: [Byte offset 0x0]: bLUEnable = 0x0 Config Descriptor: [Byte offset 0x1]: bBootLunID = 0x0 Config Descriptor: [Byte offset 0x2]: bLUWriteProtect = 0x0 Config Descriptor: [Byte offset 0x3]: bMemoryType = 0x0 Config Descriptor: [Byte offset 0x4]: dNumAllocUnits = 0x0 Config Descriptor: [Byte offset 0x8]: bDataReliability = 0x0 Config Descriptor: [Byte offset 0x9]: bLogicalBlockSize = 0xc Config Descriptor: [Byte offset 0xa]: bProvisioningType = 0x0 Config Descriptor: [Byte offset 0xb]: wContextCapabilities = 0x0 Config Descriptor: [Byte offset 0x10]: wLUMaxActiveHPBRegions = 0x0 Config Descriptor: [Byte offset 0x12]: wHPBPinnedRegionStartIdx = 0x0 Config Descriptor: [Byte offset 0x14]: wNumHPBPinnedRegions = 0x0 Config Descriptor: [Byte offset 0x16]: dLUNumWriteBoosterBufferAllocUnits = 0x0 Config Descriptor was written into ufsconfig file versal2-common:/home/basecamp#
  1. Enabling the Logical Unit

    1. bLUEnable field should be set to 1 for the corresponding Unit descriptor/Logical Unit

      1. For example to enable LU0, update the bLUEnable field to 1 in Config 0 Unit Descriptor

      2. Offset for bLUEnable for LU0 in ufsconfig file

        1. 0x16 - UFS device version >=3.1 device

        2. 0x10 - UFS device version < 3.1 device

  2. Assigning the memory to the Logical Unit

    1. dNumAllocUnits field should be set as mentioned in the below formulae for the corresponding Unit descriptor/Logical Unit

    2. Offset for dNumAllocUnits for LU0 in ufsconfig file

      1. 0x1A-0x1D(4-bytes in big endian format) - UFS device version >=3.1 device

      2. 0x14-0x17(4-bytes in big endian format) - UFS device version < 3.1 device

image-20250213-100844.png

Note:

CapacityAdjFactor value for Normal memory(bMemoryType = 0x0) type is 1

dSegmentSize(offset: 0xd) and bAllocationUnitSize(offset: 0x11) values are available in geometry descriptor as shown below

versal2-common:/home/basecamp# ufs-utils desc -t 7 -p /dev/bsg/ufs-bsg0 Geometry Descriptor [Byte offset 0x0]: bLength = 0x57 Geometry Descriptor [Byte offset 0x1]: bDescriptorType = 0x7 Geometry Descriptor [Byte offset 0x2]: bMediaTechnology = 0x0 Geometry Descriptor [Byte offset 0x4]: qTotalRawDeviceCapacity = 0x7734000 Geometry Descriptor [Byte offset 0xc]: bMaxNumberLU = 0x1 Geometry Descriptor [Byte offset 0xd]: dSegmentSize = 0x2000 Geometry Descriptor [Byte offset 0x11]: bAllocationUnitSize = 0x1 Geometry Descriptor [Byte offset 0x12]: bMinAddrBlockSize = 0x8 Geometry Descriptor [Byte offset 0x13]: bOptimalReadBlockSize = 0x80 Geometry Descriptor [Byte offset 0x14]: bOptimalWriteBlockSize = 0x80 Geometry Descriptor [Byte offset 0x15]: bMaxInBufferSize = 0x40 Geometry Descriptor [Byte offset 0x16]: bMaxOutBufferSize = 0x40 Geometry Descriptor [Byte offset 0x17]: bRPMB_ReadWriteSize = 0x20 Geometry Descriptor [Byte offset 0x18]: bDynamicCapacityResourcePolicy = 0x1 Geometry Descriptor [Byte offset 0x19]: bDataOrdering = 0x0 Geometry Descriptor [Byte offset 0x1a]: bMaxContexIDNumber = 0x20 Geometry Descriptor [Byte offset 0x1b]: bSysDataTagUnitSize = 0x0 Geometry Descriptor [Byte offset 0x1c]: bSysDataTagResSize = 0x6 Geometry Descriptor [Byte offset 0x1d]: bSupportedSecRTypes = 0x9 Geometry Descriptor [Byte offset 0x1e]: wSupportedMemoryTypes = 0x8009 Geometry Descriptor [Byte offset 0x20]: dSystemCodeMaxNAllocU = 0x0 Geometry Descriptor [Byte offset 0x24]: wSystemCodeCapAdjFac = 0x0 Geometry Descriptor [Byte offset 0x26]: dNonPersistMaxNAllocU = 0x0 Geometry Descriptor [Byte offset 0x2a]: wNonPersistCapAdjFac = 0x0 Geometry Descriptor [Byte offset 0x2c]: dEnhanced1MaxNAllocU = 0x3b9a Geometry Descriptor [Byte offset 0x30]: wEnhanced1CapAdjFac = 0x300 Geometry Descriptor [Byte offset 0x32]: dEnhanced2MaxNAllocU = 0x0 Geometry Descriptor [Byte offset 0x36]: wEnhanced2CapAdjFac = 0x0 Geometry Descriptor [Byte offset 0x38]: dEnhanced3MaxNAllocU = 0x0 Geometry Descriptor [Byte offset 0x3c]: wEnhanced3CapAdjFac = 0x0 Geometry Descriptor [Byte offset 0x3e]: dEnhanced4MaxNAllocU = 0x0 Geometry Descriptor [Byte offset 0x42]: wEnhanced4CapAdjFac = 0x0 Geometry Descriptor [Byte offset 0x44]: dOptimalLogicalBlockSize = 0x0 Geometry Descriptor [Byte offset 0x48]: bHPBRegionSize = 0x13 Geometry Descriptor [Byte offset 0x49]: bHPBNumberLU = 0x20 Geometry Descriptor [Byte offset 0x4a]: bHPBSubRegionSize = 0x13 Geometry Descriptor [Byte offset 0x4b]: wDeviceMaxActiveHPBRegions = 0xef Geometry Descriptor [Byte offset 0x4d]: Reserved = 0x0 Geometry Descriptor [Byte offset 0x4f]: dWriteBoosterBufferMaxNAllocUnits = 0xee6 Geometry Descriptor [Byte offset 0x53]: bDeviceMaxWriteBoosterLUs = 0x1 Geometry Descriptor [Byte offset 0x54]: bWriteBoosterBufferCapAdjFac = 0x3 Geometry Descriptor [Byte offset 0x55]: bSupportedWriteBoosterBufferUserSpaceReductionTypes = 0x2 Geometry Descriptor [Byte offset 0x56]: bSupportedWriteBoosterBufferTypes = 0x2 versal2-common:/home/basecamp#

Example to calculate the dNumAllocUnits for 12GB LU size

dSegmentSize = 1024

bAllocationUnitSize = 8

CapacityAdjFactor = 1 (meaning bMemoryType = 0 (Normal Memory))

image-20250213-102202.png
  1. Edit the “ufsconfig“ binary file using hexedit utility (update the contents as per the requirement)

    1. For example, below file updated to enable 3 LUs with LU0 - 20GB, LU1 - 1GB and LU2 - 4GB.

versal2-common:/home/basecamp# hexedit ufsconfig /* This will open the editor to edit the file */ 00000000 E6 01 00 01 00 01 7F 00 00 00 00 01 00 00 00 00 00 00 00 00 00 00 01 00 ........................ 00000018 00 00 00 00 14 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........................ 00000030 01 00 00 00 00 00 01 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ........................ 00000048 00 00 01 00 00 00 00 00 04 00 00 0C 00 00 00 00 00 00 00 00 00 00 00 00 ........................ 00000060 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 00 00 00 ........................ 00000078 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 00 00 ........................ 00000090 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 00 00 00 ........................ 000000A8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 00 00 ........................ 000000C0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 0C 00 00 ........................ 000000D8 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .............. 000000F0 00000108 00000120 00000138
  1. Write back the “ufsconfig“ file using the below command

versal2-common:/home/basecamp# ufs-utils desc -t 1 -w ufsconfig -p /dev/bsg/ufs-bsg0 Config Descriptor was written to device

Note: Reboot the Linux to see newly configured Logical Units or partitions

UFS boot Prerequisites(Device configurations required for UFS boot)

  1. For a UFS bootable device, the boot feature is enabled if bBootEnable field in the Device Descriptor is set to 01h, user must set this bit.

bBootEnable = 0x1

  1. User must create at least one Boot Logical Unit (Max 2 Boot Logical Units can be created) and enable it with the required memory configured to place the Boot Image in it. 

bBootLunID = 0x1 (or) 0x2

bLUEnable = 0x1

dNumAllocUnits = <Num of Alloc Units based on user choice>

  1. One of the B-LU should be active during the boot process (configured by writing the bBootLunEn attribute).

bBootLunEn = 0x1 (Boot LU A enabled) (OR) bBootLunEn = 0x2 (Boot LU B enabled)

  1. bRefClkFreq Attribute need to be configured to 26MHz.

bRefClkFreq = 0x1 (26MHz)

Testing

  • Tested basic read/write on QEMU and SPP platforms

QEMU log

/***** Boot Log *****/ [ 3.846772] ufshcd-versal2 f10b0000.ufs: ufshcd_populate_vreg: Unable to find vdd-hba-supply regulator, assuming enabled [ 3.847622] ufshcd-versal2 f10b0000.ufs: ufshcd_populate_vreg: Unable to find vcc-supply regulator, assuming enabled [ 3.848248] ufshcd-versal2 f10b0000.ufs: ufshcd_populate_vreg: Unable to find vccq-supply regulator, assuming enabled [ 3.848879] ufshcd-versal2 f10b0000.ufs: ufshcd_populate_vreg: Unable to find vccq2-supply regulator, assuming enabled NOTICE: SCMI: CLK: id: 16, get_rate: 26000000 NOTICE: SCMI: CLK: id: 14, get_rate: 100000000 [ 3.859747] scsi host0: ufshcd NOTICE: SCMI reset 4/ufs0 set NOTICE: SCMI reset 35/ufsphy0 set NOTICE: SCMI reset 4/ufs0 release NOTICE: SCMI reset 35/ufsphy0 release [ 3.890596] of_cfs_init [ 3.891851] of_cfs_init: OK [ 3.893704] clk: Disabling unused clocks [ 3.894691] ALSA device list: [ 3.895493] No soundcards found. [ 3.900197] ufshcd-versal2 f10b0000.ufs: Undefined ref clk gating wait time, use default 255us [ 3.904870] Before configuring the PWR mode [ 3.908103] uart-pl011 f1920000.serial: no DMA platform data [ 3.910505] [ 3.910505] After configuring the PWR mode [ 3.931345] scsi 0:0:0:49488: Well-known LUN QEMU QEMU UFS PQ: 0 ANSI: 6 [ 3.948062] scsi 0:0:0:49476: Well-known LUN QEMU QEMU UFS PQ: 0 ANSI: 6 [ 3.954786] scsi 0:0:0:49456: scsi_add_lun: correcting incorrect peripheral device type 0x1f for W-LUN 0x c130hN [ 3.955619] scsi 0:0:0:49456: Well-known LUN QEMU QEMU TARGET 2.5 PQ: 1 ANSI: 5 [ 4.095731] scsi 0:0:0:1: Direct-Access QEMU QEMU HARDDISK 2.5+ PQ: 0 ANSI: 5 [ 4.103338] sd 0:0:0:1: [sda] 1048576 4096-byte logical blocks: (4.29 GB/4.00 GiB) [ 4.104745] sd 0:0:0:1: [sda] Write Protect is off [ 4.106060] sd 0:0:0:1: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA [ 4.122833] sd 0:0:0:1: [sda] Attached SCSI disk /* FAT file system creation */ minRootfs:/home/petalinux# mkfs.vfat -F 32 -S 4096 /dev/sda mkfs.fat 4.2 (2021-01-31) minRootfs:/home/petalinux# [ 99.490635] sda: sda1 /******** Read/Write test log *******/ minRootfs:/home/petalinux# dd if=/dev/urandom of=data.bin bs=1024 count=1024 1024+0 records in 1024+0 records out minRootfs:/home/petalinux# dd of=/dev/sda if=data.bin bs=1024 count=1024 sda sda1 minRootfs:/home/petalinux# dd of=/dev/sda1 if=data.bin bs=1024 count=1024 1024+0 records in 1024+0 records out minRootfs:/home/petalinux# dd if=/dev/sda1 of=data1.bin bs=1024 count=1024 1024+0 records in 1024+0 records out minRootfs:/home/petalinux# md5sum data.bin data1.bin 35668509971b00b7cce23b749d9ef1e4 data.bin 35668509971b00b7cce23b749d9ef1e4 data1.bin /* ext4 file system creation */ minRootfs:/home/petalinux# mkfs.ext4 -b 4096 /dev/sda mke2fs 1.46.5 (30-Dec-2021) Creating filesystem with 5242880 4k blocks and 1310720 inodes Filesystem UUID: f1365c22-01b3-4830-98cd-fe840a17ef3c Superblock backups stored on blocks: 32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208, 4096000 Allocating group tables: done Writing inode tables: done Creating journal (32768 blocks): done Writing superblocks and filesystem accounting information: done minRootfs:/home/petalinux#

Kernel Configuration

CONFIG_SCSI_UFSHCD=y CONFIG_SCSI_UFS_BSG=y CONFIG_SCSI_UFSHCD_PLATFORM=y CONFIG_SCSI_UFS_AMD_VERSAL2=y

Device-tree

Sample Device-tree node for UFS

ufs@f10b0000 { compatible = "amd,versal2-ufs"; status = "okay"; interrupts = <0x00 0xea 0x04>; reg = <0x00 0xf10b0000 0x00 0x100>; freq-table-hz = <0x00 0x00>; clock-names = "core_clk"; reset-names = "ufshc-rst\0ufsphy-rst"; clocks = <0x0a 0x0e>; assigned-clocks = <0x0a 0x0e>; resets = <0x0b 0x04 0x0b 0x23>; assigned-clock-rates = <0x5f5e100>; };

Performance Details

Configurations

  • UFS Controller reference clock: 300MHz

  • PHY Ref and Config clock (external clocks): 26MHz

  • Number of lanes: 2 Tx and 2 Rx lanes

HS-G4 (Rate B) - Default Speed Gear after enabling the High Speed

versal2-vek385-sdt-seg:/home/basecamp# hdparm -tT /dev/sda

/dev/sda:
Timing cached reads: 10704 MB in 2.00 seconds = 5359.80 MB/sec
Timing buffered disk reads: 1024 MB in 0.63 seconds = 1617.36 MB/sec

HS-G1 (Rate B)

versal2-vek385-sdt-seg:/home/basecamp# hdparm -tT /dev/sda

/dev/sda:
Timing cached reads: 10050 MB in 2.00 seconds = 5031.82 MB/sec
Timing buffered disk reads: 722 MB in 3.00 seconds = 240.62 MB/sec

HS-G4 (Rate A)

versal2-vek385-sdt-seg:/home/basecamp# hdparm -tT /dev/sda

/dev/sda:
Timing cached reads: 11450 MB in 2.00 seconds = 5734.63 MB/sec
Timing buffered disk reads: 4328 MB in 3.00 seconds = 1442.06 MB/sec

HS-G1 (Rate A)

versal2-vek385-sdt-seg:/home/basecamp# hdparm -tT /dev/sda

/dev/sda:
Timing cached reads: 11360 MB in 2.00 seconds = 5689.53 MB/sec
Timing buffered disk reads: 618 MB in 3.00 seconds = 205.98 MB/sec

PWM-G4

/dev/sda:
Timing cached reads: 10156 MB in 2.00 seconds = 5084.37 MB/sec
Timing buffered disk reads: 28 MB in 3.20 seconds = 8.74 MB/sec

PWM-G1

versal2-vek385-sdt-seg:/home/basecamp# hdparm -tT /dev/sda

/dev/sda:
Timing cached reads: 634 MB in 2.00 seconds = 317.00 MB/sec
Timing buffered disk reads: 4 MB in 3.78 seconds = 1.06 MB/sec

Mainline Status

Not in Mainline

Change Log

2024.2

  • Summary

    • Add vendor specific ops to handle interrupts

    • Add AMD Versal Gen 2 UFS support

    • Disable AUTO_HIBERN8 and HS modes

  • Commits

Related content

© Copyright 2019 - 2022 Xilinx Inc. Privacy Policy