UFS Device Provisioning
The DEBUGFS kernel interface is used to provision refclk frequency and Logical units of UFS device.
To provision UFS device using debugfs entries
1. CONFIG_DEBUG_FS should be enabled in kernel and debugfs should be mounted.
Use the following command to mount debugfs if it is not automatically mounted:
mount -t debugfs none /sys/kernel/debug
2. The following DT flag should be present in UFS DT node to expose provisioning debugfs entries:
nvidia,enable-ufs-provisioning
Example:
ufshci@2450000 {
status = "okay";
nvidia,enable-ufs-provisioning;
};
3. If refclk frequency provisioning is not done on device/board, the following DT flag should be present in the UFS DT node to enumerate UFS in non-HS (pwm) mode:
/delete-property/ nvidia,enable-hs-mode;
Example:
ufshci@2450000 {
status = "okay";
/delete-property/ nvidia,enable-hs-mode;
nvidia,enable-ufs-provisioning;
};
4. It is recommended to increase the log level to monitor any failure message. Use the following command to increase log level:
dmesg -n 7
As part of UFS provisioning, the following types of programming are allowed:
1. Program Refclk frequency of UFS device
2. Program Logical Units for UFS device
To provision a UFS device through the flashing tools
Enter the following command:
cd <top>/drive-t186ref-foundation/tools/host/flashtools/bootburn_t19x
./bootburn.sh -b e3550b01-t194a -U <top>/drive-t186ref-foundation/tools/host/flashtools/bootburn_t19x/ufs-provision-e3550.cfg -l
This boots the device in RCM mode, then programs the frequency and lun_nodes based on the values provided in the file ufs-provision-<e3550 | p2888>.cfg.
Program bRefClkFreq
Note: | Refclk frequency field for a device is a write once attribute in device lifetime. |
To program refclkfreq following steps needs to be done after UFS device is enumerated.
1. Change directory to UFS refclk programming debugfs node:
cd /sys/kernel/debug/<UFS_debugfs_node>/ufs_reflck
Note: | Typically <UFS_debugfs_node> represents the value “2450000.ufshci” |
2. Provide input value to be programmed in refclkfreq_value:
echo val > refclkfreq_value
where val can be provided as follows (according to UFS spec):
Reference Clock Frequency value:
0h:19.2MHz
1h: 26MHz
2h: 38.4MHz
3h: 52MHz
Others: Reserved
3. Trigger programing of refclk value by writing “1” to program_refclkfreq debugfs node
echo 1 > program_refclkfreq
Note: | Reflclk frequency programming will only be triggered when input value to program_refclkfreq debugfs node is 1. For any other input value, the programming command will not be issued. |
Program LUNs
LUNs can only be programmed once in a boot cycle.
Target should be rebooted if LUNs are programmed in current boot cycle and need to be re-programmed again.
Steps to program LUNs on a UFS device
1. Change current directory to UFS LUN programming debugfs directory.
cd /sys/kernel/debug/<UFS_debugfs_node>/ufs_luns
Note: | Typically <UFS_debugfs_node> represents the value “2450000.ufshci” |
The debugfs directory contains the following:
• lun0 to lun7 debugfs directories: Each LUN directory contains user configurable parameters of unit descriptor for each LUN.
• program_lun debugfs node: Used to trigger LUN programming.
2. Program unit descriptor parameters for each LUN.
• Each LUN contains following parameters:
“bLUenable"
"bBootLUNID"
"bLUWriteProtect"
"bMemoryType"
"dNumAllocUnits"
"bDataReliability"
"bLogicalBlocksize"
"bProvisionType"
"wContextCapabilities"
Details for the above parameters are provided in table below:
Offset in hex | Size in Bytes | Name | Description |
00 | 1 | bLUEnable | Logical Unit Enable 00h: Logical Unit disabled 01h: Logical Unit enabled Others: Reserved |
01 | 1 | bBootLunID | Boot LUN ID 00h: Not bootable 01h: Boot LU A 02h: Boot LU B Others: Reserved. |
02 | 1 | bLUWriteProtect | Logical Unit Write Protect 00h: LU not write protected 01h: LU write protected when fPowerOnWPEn =1 02h: LU permanently write protected when fPermanentWPEn =1 03h: Reserved (for UFS Security Extension specification) Others: Reserved |
03 | 1 | bMemoryType | Memory Type bMemoryType defines logical unit memory type. 00h: Normal Memory 01h: System code memory type 02h: Non-Persistent memory type 03h: Enhanced memory type 1 04h: Enhanced memory type 2 05h: Enhanced memory type 3 06h: Enhanced memory type 4 Others: Reserved |
04 | 4 | dNumAllocUnits | Number of Allocation Units Number of allocation units assigned to the logical unit. The value shall be calculated considering the capacity adjustment factor of the selected memory type |
08 | 1 | bDataReliability | Data Reliability bDataReliability defines the device behavior when a power failure occurs during a write operation to the logical unit 00h: the logical unit is not protected. All of the data contained in the logical unit might be lost as a result of a power failure during a write operation 01h: logical unit is protected. Logical unit's data is protected against power failure. Others: Reserved |
09 | 1 | bLogicalBlockSize | Logical Block Size The size of addressable logical blocks is equal the result of exponentiation with as base the number two and as exponent the bLogicalBlockSize value: 2bLogicalBlockSize (i.e., bLogicalBlockSize = 0Ch corresponds to 4 KByte Logical Block Size). Its minimum value is 0Ch, which corresponds to 4 KByte |
0A | 1 | bProvisioningType | Provisioning Type 00h: Thin Provisioning is disabled (default) 02h: Thin Provisioning is enabled and TPRZ = 0 03h: Thin Provisioning is enabled and TPRZ = 1 Others: Reserved |
0B | 2 | wContextCapabilities | Context Capabilities |
0D:0F | 3 | Reserved | |
• For programming “n” LUNs unit descriptor parameters of lun0 to lun(n-) should be programmed.
For example: To program 4 LUNs, parameters for lun0 to lun3 should be programmed.
Note: | Programming LUN parameters out of order is not supported. |
• The following example programs 2 LUNs of 4GB data.
echo 1 > ./lun0/bLUenable
echo 1 > ./lun1/bLUenable
echo 0x00040000 > ./lun0/dNumAllocUnits
echo 0x00040000 > ./lun1/dNumAllocUnits
echo 0x01 > ./lun0/bDataReliability
echo 0x01 > ./lun1/bDataReliability
echo 0x0C > ./lun0/bLogicalBlocksize
echo 0x0C > ./lun1/bLogicalBlocksize
Note: | Other parameters are set to zero when not explicitly programmed. Specify values in reverse-byte order for dNumAllocUnits and wContextCapabilities. For example, if dNumAllocUnits for lun0 must be configured to 0x0400, specify that as the following:
echo 0x00040000 > ./lun0/dNumAllocUnits |
3. Trigger UFS programming.
After data for unit descriptor parameter is given LUN programming can be triggered as follows:
echo 1 > program_lun
Note: | Only writing “1” to this node triggers UFS LUN programming. Device should be reset after programming LUNs as per spec. |
Troubleshooting
If failure logs similar to the following pattern are noticed:
[ 136.960244] ufs_tegra 2450000.ufshci: program_refclk_debugfs_write: Write bRefClkFreq failed
or
[ 145.564544] ufs_tegra 2450000.ufshci: program_lun_debugfs_write: Failed to program LUNs
Perform the following steps:
1. Please recheck if all the pre-requisite steps are followed.
2. Try provisioning the device in non-HS mode.