ATF bl1 ufshc_dme_get/set處理流程分析
- UFS術語縮略詞
- 1 ATF的下載鏈接
- 2 ATF BL1 ufshc_dme_get/set流程
- 3 ufs總體架構圖
- 3.1 UFS Top Level Architecture
- 3.2 UFS System Model
- 4 ufshc_dme_get/set函數接口詳細分析
- 4.1 ufshc_dme_get
- 4.2 ufshc_dme_set
- 4.3 ufshc_send_uic_cmd
- 4.4 ufs_wait_for_int_status
以海思hikey960為例來介紹,簡單介紹在ATF BL1階段的初始化處理。
UFS術語縮略詞
UTP:UFS Transport Protocol
DME:Device Management Entity
UCS:UFS Command Set
UIC:UFS Interconnect
UTRD:UTP Transfer Request Descriptor
UPIU:UFS Protocol Information Unit
1 ATF的下載鏈接
https://github.com/ARM-software/arm-trusted-firmware
可以通過下面的命令來下載ATF的代碼,或者通過打包下載的方式也可以。
git clone git@github.com:ARM-software/arm-trusted-firmware.git
2 ATF BL1 ufshc_dme_get/set流程
- 設置
ufs dme get/set
的cmd參數 - 在
ufshc_send_uic_cmd
函數中首先等到UIC READY
,然后配置UFS CMD ARG
寄存器以及UIC CMD
寄存器。
3 ufs總體架構圖
3.1 UFS Top Level Architecture
3.2 UFS System Model
4 ufshc_dme_get/set函數接口詳細分析
4.1 ufshc_dme_get
cmd.op = DME_GET;
ufshc_send_uic_cmd(base, &cmd);
int ufshc_dme_get(unsigned int attr, unsigned int idx, unsigned int *val)
{uintptr_t base;int result, retries;uic_cmd_t cmd;assert(ufs_params.reg_base != 0);if (val == NULL)return -EINVAL;base = ufs_params.reg_base;cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx);cmd.arg2 = 0;cmd.arg3 = 0;cmd.op = DME_GET;for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) {result = ufshc_send_uic_cmd(base, &cmd);if (result == 0)break;/* -EIO requires UFS re-init */if (result == -EIO) {return result;}}if (retries >= UFS_UIC_COMMAND_RETRIES)return -EIO;*val = mmio_read_32(base + UCMDARG3);return 0;
}
4.2 ufshc_dme_set
cmd.op = DME_SET;
ufshc_send_uic_cmd(base, &cmd);
int ufshc_dme_set(unsigned int attr, unsigned int idx, unsigned int val)
{uintptr_t base;int result, retries;uic_cmd_t cmd;assert((ufs_params.reg_base != 0));base = ufs_params.reg_base;cmd.arg1 = (attr << 16) | GEN_SELECTOR_IDX(idx);cmd.arg2 = 0;cmd.arg3 = val;cmd.op = DME_SET;for (retries = 0; retries < UFS_UIC_COMMAND_RETRIES; ++retries) {result = ufshc_send_uic_cmd(base, &cmd);if (result == 0)break;/* -EIO requires UFS re-init */if (result == -EIO) {return result;} }if (retries >= UFS_UIC_COMMAND_RETRIES)return -EIO;return 0;
}
4.3 ufshc_send_uic_cmd
data = mmio_read_32(base + HCS);
讀取Host Controller Status寄存器的值,僅當UCRDY置位時才繼續執行對應的ufs cmd。該位被置位表示當前ufs 主控制器已經準備好處理UIC命令。
mmio_write_32(base + IS, ~0);
使能IAGES,CQES,SQES,CEFES,SBFES,HCFES,UTPES,DFES,UCCS,UTMRCS,ULSS,ULLS,UHES,UHXS,UPMS,UTMS,UE,UDEPRI,UTRCSmmio_write_32(base + UCMDARG1, cmd->arg1);
將arg1參數值寫入UCMDARG1寄存器中。
MIBattribute: Indicates the ID of the attribute of the requested. See MIPI UniPro Specification for the details of the MIBattribute parameter.
MIBattribute: 表示請求的屬性 ID。有關 MIBattribute 參數的詳細信息,請參見 MIPI UniPro Specification。
GenSelectorIndex: Indicates the targeted M-PHY data lane or CPort or Test Feature when relevant. See MIPI UniPro Specification for the details of the GenSelectorIndex parameter.
GenSelectorIndex: 表示目標 M-PHY 數據通道、CPort 或測試功能(如相關)。有關 GenSelectorIndex 參數的詳細信息,請參閱 MIPI UniPro 規范。
ResetMode: Indicates the link startup mode. See MIPI UniPro Specification for the details of the ResetMode parameter.
重置模式: 表示鏈路啟動模式。有關 ResetMode 參數的詳細信息,請參閱 MIPI UniPro 規范。
ResetLevel: Indicates the reset type. See MIPI UniPro Specification for the details of the ResetLevel parameter.
重置級別: 表示復位類型。有關 ResetLevel 參數的詳細信息,請參見 MIPI UniPro Specification。
-
mmio_write_32(base + UCMDARG2, cmd->arg2);
將arg2參數值寫入UCMDARG2寄存器中。
AttrSetType: Indicates whether the attribute value (AttrSet = NORMAL) or the attribute non-volatile reset value (STATIC) setting is requested. See MIPI UniPro Specification for the details of the AttrSetType parameter.
AttrSetType: 表示請求設置屬性值(AttrSet = NORMAL)還是屬性非易失性重置值(STATIC)。有關 AttrSetType 參數的詳細信息,請參閱 MIPI UniPro 規范。
ConfigResultCode: Indicates the result of the UIC configuration command request. It is valid after host controller has set the IS.UCCS bit to ’1’. See MIPI UniPro Specification for the details of the ConfigResultCode parameter.
ConfigResultCode: 表示 UIC 配置命令請求的結果。它在主機控制器將 IS.UCCS 位設置為 "1 "后有效。有關 ConfigResultCode 參數的詳細信息,請參見 MIPI UniPro Specification。
GenericErrorCode: Indicates the result of the UIC control command request. It is valid after host controller has set the IS.UCCS bit to ’1’. See MIPI UniPro Specification for the details of the GenericErrorCode parameter.
通用錯誤代碼: 表示 UIC 控制命令請求的結果。它在主機控制器將 IS.UCCS 位設置為 "1 "后有效。有關 GenericErrorCode 參數的詳細信息,請參見 MIPI UniPro Specification。
-
mmio_write_32(base + UCMDARG3, cmd->arg3);
將arg3參數值寫入UCMDARG3寄存器中。
MIBvalue_R: Indicates the value of the attribute as returned by the UIC command returned. It is valid after host controller has set the IS.UCCS bit to ’1’. See MIPI UniPro Specification for the details of the MIBvalue parameter.
MIBvalue_R: 表示 UIC 命令返回的屬性值。它在主機控制器將 IS.UCCS 位設置為 "1 "后有效。有關 MIBvalue 參數的詳細信息,請參閱 MIPI UniPro 規范。
MIBvalue_W: Indicates the value of the attribute to be set. See MIPI UniPro Specification for details of the MIBvalue parameter.
MIBvalue_W: 表示要設置的屬性值。有關 MIBvalue 參數的詳細信息,請參見 MIPI UniPro Specification。 -
mmio_write_32(base + UICCMD, cmd->op);
將cmd-ops寫入UICCMD寄存器中,使cmd開始處理。
-
ufs_wait_for_int_status(UFS_INT_UCCS, UIC_CMD_TIMEOUT_MS, cmd->op == DME_SET);
等待期待的中斷狀態
int ufshc_send_uic_cmd(uintptr_t base, uic_cmd_t *cmd)
{unsigned int data;int result, retries;if (base == 0 || cmd == NULL)return -EINVAL;for (retries = 0; retries < 100; retries++) {data = mmio_read_32(base + HCS);if ((data & HCS_UCRDY) != 0) {break;}mdelay(1);}if (retries >= 100) { return -EBUSY;}mmio_write_32(base + IS, ~0);mmio_write_32(base + UCMDARG1, cmd->arg1);mmio_write_32(base + UCMDARG2, cmd->arg2);mmio_write_32(base + UCMDARG3, cmd->arg3);mmio_write_32(base + UICCMD, cmd->op);result = ufs_wait_for_int_status(UFS_INT_UCCS, UIC_CMD_TIMEOUT_MS,cmd->op == DME_SET);if (result != 0) {return result;}return mmio_read_32(base + UCMDARG2) & CONFIG_RESULT_CODE_MASK;
}
4.4 ufs_wait_for_int_status
interrupts_enabled = mmio_read_32(ufs_params.reg_base + IE);
讀取中斷使能寄存器的值,該寄存器可啟用或禁用向主機軟件報告相應的中斷。當某位被設置(‘1’)且相應的中斷條件處于活動狀態時,就會產生中斷。被禁用(‘0’)的中斷源仍會在 IS 寄存器中顯示。該寄存器與 IS 寄存器對稱。interrupt_status = mmio_read_32(ufs_params.reg_base + IS) & interrupts_enabled;
讀取中斷狀態寄存器的值與中斷使能寄存器的值與獲取當前中斷的狀態值。
/* * ufs_wait_for_int_status - wait for expected interrupt status* @expected: expected interrupt status bit* @timeout_ms: timeout in milliseconds to poll for* @ignore_linereset: set to ignore PA_LAYER_GEN_ERR (UIC error)** Returns* 0 - received expected interrupt and cleared it* -EIO - fatal error, needs re-init* -EAGAIN - non-fatal error, caller can retry* -ETIMEDOUT - timed out waiting for interrupt status*/
static int ufs_wait_for_int_status(const uint32_t expected_status,unsigned int timeout_ms,bool ignore_linereset)
{ uint32_t interrupt_status, interrupts_enabled;int result = 0;interrupts_enabled = mmio_read_32(ufs_params.reg_base + IE);do {interrupt_status = mmio_read_32(ufs_params.reg_base + IS) & interrupts_enabled; if (interrupt_status & UFS_INT_ERR) {mmio_write_32(ufs_params.reg_base + IS, interrupt_status & UFS_INT_ERR);result = ufs_error_handler(interrupt_status, ignore_linereset);if (result != 0) {return result;}}if (interrupt_status & expected_status) {break;}mdelay(1);} while (timeout_ms-- > 0);if (!(interrupt_status & expected_status)) {return -ETIMEDOUT;}mmio_write_32(ufs_params.reg_base + IS, expected_status);return result;
}