Merge "mhi: core: Check for RDDM cookie set by device to indicate readiness"

This commit is contained in:
qctecmdr 2020-08-28 17:56:36 -07:00 • committed by Gerrit - the friendly Code Review server
commit 54dded298e
3 changed files with 67 additions and 21 deletions

View file

@ -139,6 +139,31 @@ void mhi_dump_sfr(struct mhi_controller *mhi_cntrl)
}
EXPORT_SYMBOL(mhi_dump_sfr);
bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie)
{
int ret;
u32 val;
if (!mhi_cntrl->rddm_supported || !cookie)
return false;
MHI_CNTRL_LOG("Checking BHI debug register for 0x%x\n", cookie);
if (!MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
return false;
ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_ERRDBG2, &val);
if (ret)
return false;
MHI_CNTRL_LOG("BHI_ERRDBG2 value:0x%x\n", val);
if (val == cookie)
return true;
return false;
}
EXPORT_SYMBOL(mhi_scan_rddm_cookie);
/* setup rddm vector table for rddm transfer and program rxvec */
void mhi_rddm_prepare(struct mhi_controller *mhi_cntrl,
struct image_info *img_info)
@ -444,6 +469,9 @@ void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl,
int i;
struct mhi_buf *mhi_buf = image_info->mhi_buf;
if (!image_info)
return;
for (i = 0; i < image_info->entries; i++, mhi_buf++)
mhi_free_contig_coherent(mhi_cntrl, mhi_buf->len, mhi_buf->buf,
mhi_buf->dma_addr);
@ -571,14 +599,14 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
!mhi_cntrl->seg_len))) {
MHI_CNTRL_ERR(
"No firmware image defined or !sbl_size || !seg_len\n");
return;
goto fw_load_error;
}
ret = request_firmware(&firmware, fw_name, mhi_cntrl->dev);
if (ret) {
if (!mhi_cntrl->fw_image_fallback) {
MHI_CNTRL_ERR("Error loading fw, ret:%d\n", ret);
return;
goto fw_load_error;
}
/* re-try with fall back fw image */
@ -586,7 +614,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
mhi_cntrl->dev);
if (ret) {
MHI_CNTRL_ERR("Error loading fw_fb, ret:%d\n", ret);
return;
goto fw_load_error;
}
mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data,
@ -602,8 +630,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
buf = mhi_alloc_coherent(mhi_cntrl, size, &dma_addr, GFP_KERNEL);
if (!buf) {
MHI_CNTRL_ERR("Could not allocate memory for image\n");
release_firmware(firmware);
return;
goto fw_load_error_release;
}
/* load sbl or edl image via BHI */
@ -611,17 +638,16 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
ret = mhi_fw_load_bhi(mhi_cntrl, dma_addr, size);
mhi_free_coherent(mhi_cntrl, size, buf, dma_addr);
if (!mhi_cntrl->fbc_download || ret || mhi_cntrl->ee == MHI_EE_EDL)
release_firmware(firmware);
if (ret) {
MHI_CNTRL_ERR("MHI did not load SBL/EDL image, ret:%d\n", ret);
return;
goto fw_load_error_release;
}
/* we are done with FW load is EE is EDL */
if (mhi_cntrl->ee == MHI_EE_EDL)
if (mhi_cntrl->ee == MHI_EE_EDL) {
release_firmware(firmware);
return;
}
write_lock_irq(&mhi_cntrl->pm_lock);
mhi_cntrl->dev_state = MHI_STATE_RESET;
@ -636,7 +662,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
firmware->size);
if (ret) {
MHI_CNTRL_ERR("Error alloc size:%zu\n", firmware->size);
goto error_alloc_fw_table;
goto fw_load_error_ready;
}
MHI_CNTRL_LOG("Copying firmware image into vector table\n");
@ -645,6 +671,9 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
mhi_firmware_copy(mhi_cntrl, firmware, mhi_cntrl->fbc_image);
}
release_firmware(firmware);
firmware = NULL;
fw_load_ee_pthru:
/* transitioning into MHI RESET->READY state */
ret = mhi_ready_state_transition(mhi_cntrl);
@ -653,15 +682,14 @@ fw_load_ee_pthru:
to_mhi_pm_state_str(mhi_cntrl->pm_state),
TO_MHI_STATE_STR(mhi_cntrl->dev_state),
TO_MHI_EXEC_STR(mhi_cntrl->ee), ret);
if (!mhi_cntrl->fbc_download)
return;
if (ret) {
MHI_CNTRL_ERR("Did not transition to READY state\n");
goto error_read;
goto fw_load_error_ready;
}
if (!mhi_cntrl->fbc_download || mhi_cntrl->ee == MHI_EE_PTHRU)
return;
/* wait for SBL event */
ret = wait_event_timeout(mhi_cntrl->state_event,
mhi_cntrl->ee == MHI_EE_SBL ||
@ -670,7 +698,7 @@ fw_load_ee_pthru:
if (!ret || MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
MHI_CNTRL_ERR("MHI did not enter BHIE\n");
goto error_read;
goto fw_load_error_ready;
}
/* start full firmware image download */
@ -681,16 +709,23 @@ fw_load_ee_pthru:
MHI_CNTRL_LOG("amss fw_load ret:%d\n", ret);
release_firmware(firmware);
if (ret)
goto fw_load_error;
return;
error_read:
fw_load_error_ready:
mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
mhi_cntrl->fbc_image = NULL;
error_alloc_fw_table:
fw_load_error_release:
release_firmware(firmware);
fw_load_error:
write_lock_irq(&mhi_cntrl->pm_lock);
mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
wake_up_all(&mhi_cntrl->state_event);
write_unlock_irq(&mhi_cntrl->pm_lock);
}
void mhi_perform_soc_reset(struct mhi_controller *mhi_cntrl)

View file

@ -481,12 +481,15 @@ static int mhi_pm_mission_mode_transition(struct mhi_controller *mhi_cntrl)
write_lock_irq(&mhi_cntrl->pm_lock);
if (MHI_REG_ACCESS_VALID(mhi_cntrl->pm_state))
ee = mhi_get_exec_env(mhi_cntrl);
write_unlock_irq(&mhi_cntrl->pm_lock);
if (!MHI_IN_MISSION_MODE(ee)) {
MHI_CNTRL_ERR("Invalid EE:%s\n", TO_MHI_EXEC_STR(ee));
mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
wake_up_all(&mhi_cntrl->state_event);
write_unlock_irq(&mhi_cntrl->pm_lock);
return -EIO;
}
write_unlock_irq(&mhi_cntrl->pm_lock);
mhi_cntrl->status_cb(mhi_cntrl, mhi_cntrl->priv_data,
MHI_CB_EE_MISSION_MODE);

View file

@ -797,6 +797,14 @@ int mhi_pm_fast_resume(struct mhi_controller *mhi_cntrl, bool notify_client);
*/
int mhi_download_rddm_img(struct mhi_controller *mhi_cntrl, bool in_panic);
/**
* mhi_scan_rddm_cookie - Look for supplied cookie value in the BHI debug
* registers set by device to indicate rddm readiness for debugging purposes.
* @mhi_cntrl: MHI controller
* @cookie: cookie/pattern value to match
*/
bool mhi_scan_rddm_cookie(struct mhi_controller *mhi_cntrl, u32 cookie);
/**
* mhi_force_rddm_mode - Force external device into rddm mode
* to collect device ramdump. This is useful if host driver assert