ret = mhi_write_reg_field(mhi_cntrl, base, BHIE_RXVECDB_OFFS,
BHIE_RXVECDB_SEQNUM_BMSK, sequence_id); if (ret) {
dev_err(dev, "Failed to write sequence ID for BHIE_RXVECDB\n"); return ret;
}
dev_dbg(dev, "Entered with pm_state:%s dev_state:%s ee:%s\n",
to_mhi_pm_state_str(mhi_cntrl->pm_state),
mhi_state_str(mhi_cntrl->dev_state),
TO_MHI_EXEC_STR(mhi_cntrl->ee));
/* * This should only be executing during a kernel panic, we expect all * other cores to shutdown while we're collecting RDDM buffer. After * returning from this function, we expect the device to reset. * * Normally, we read/write pm_state only after grabbing the * pm_lock, since we're in a panic, skipping it. Also there is no * guarantee that this state change would take effect since * we're setting it w/o grabbing pm_lock
*/
mhi_cntrl->pm_state = MHI_PM_LD_ERR_FATAL_DETECT; /* update should take the effect immediately */
smp_wmb();
/* * Make sure device is not already in RDDM. In case the device asserts * and a kernel panic follows, device will already be in RDDM. * Do not trigger SYS ERR again and proceed with waiting for * image download completion.
*/
ee = mhi_get_exec_env(mhi_cntrl); if (ee == MHI_EE_MAX) goto error_exit_rddm;
if (ee != MHI_EE_RDDM) {
dev_dbg(dev, "Trigger device into RDDM mode using SYS ERR\n");
mhi_set_mhi_state(mhi_cntrl, MHI_STATE_SYS_ERR);
dev_dbg(dev, "Waiting for device to enter RDDM\n"); while (rddm_retry--) {
ee = mhi_get_exec_env(mhi_cntrl); if (ee == MHI_EE_RDDM) break;
udelay(delayus);
}
if (rddm_retry <= 0) { /* Hardware reset so force device to enter RDDM */
dev_dbg(dev, "Did not enter RDDM, do a host req reset\n");
mhi_soc_reset(mhi_cntrl);
udelay(delayus);
}
ee = mhi_get_exec_env(mhi_cntrl);
}
dev_dbg(dev, "Waiting for RDDM image download via BHIe, current EE:%s\n",
TO_MHI_EXEC_STR(ee));
while (retry--) {
ret = mhi_read_reg_field(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS,
BHIE_RXVECSTATUS_STATUS_BMSK, &rx_status); if (ret) return -EIO;
if (rx_status == BHIE_RXVECSTATUS_STATUS_XFER_COMPL) return 0;
udelay(delayus);
}
ee = mhi_get_exec_env(mhi_cntrl);
ret = mhi_read_reg(mhi_cntrl, base, BHIE_RXVECSTATUS_OFFS, &rx_status);
dev_err(dev, "RXVEC_STATUS: 0x%x\n", rx_status);
error_exit_rddm:
dev_err(dev, "RDDM transfer failed. Current EE: %s\n",
TO_MHI_EXEC_STR(ee));
if (MHI_PM_IN_ERROR_STATE(mhi_cntrl->pm_state)) {
dev_err(dev, "Device MHI is not in valid state\n"); return;
}
/* save hardware info from BHI */
ret = mhi_read_reg(mhi_cntrl, mhi_cntrl->bhi, BHI_SERIALNU,
&mhi_cntrl->serial_number); if (ret)
dev_err(dev, "Could not capture serial number via BHI\n");
/* wait for ready on pass through or any other execution environment */ if (!MHI_FW_LOAD_CAPABLE(mhi_cntrl->ee)) goto fw_load_ready_state;
/* check if the driver has already provided the firmware data */ if (!fw_name && mhi_cntrl->fbc_download &&
mhi_cntrl->fw_data && mhi_cntrl->fw_sz) { if (!mhi_cntrl->sbl_size) {
dev_err(dev, "fw_data provided but no sbl_size\n"); goto error_fw_load;
}
/* * If we're doing fbc, populate vector tables while * device transitioning into MHI READY state
*/ if (fw_load_type == MHI_FW_LOAD_FBC) {
ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz); if (ret) {
release_firmware(firmware); goto error_fw_load;
}
/* Load the firmware into BHIE vec table */
mhi_firmware_copy_bhie(mhi_cntrl, fw_data, fw_sz, mhi_cntrl->fbc_image);
}
release_firmware(firmware);
fw_load_ready_state: /* Transitioning into MHI RESET->READY state */
ret = mhi_ready_state_transition(mhi_cntrl); if (ret) {
dev_err(dev, "MHI did not enter READY state\n"); goto error_ready_state;
}
dev_info(dev, "Wait for device to enter SBL or Mission mode\n"); return;
error_ready_state: if (mhi_cntrl->fbc_image) {
mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
mhi_cntrl->fbc_image = NULL;
}
int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
{ struct image_info *image_info = mhi_cntrl->fbc_image; struct device *dev = &mhi_cntrl->mhi_dev->dev; enum mhi_pm_state new_state; int ret;
if (!image_info) return -EIO;
ret = mhi_fw_load_bhie(mhi_cntrl, /* Vector table is the last entry */
&image_info->mhi_buf[image_info->entries - 1]); if (ret) {
dev_err(dev, "MHI did not load AMSS, ret:%d\n", ret);
write_lock_irq(&mhi_cntrl->pm_lock);
new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
write_unlock_irq(&mhi_cntrl->pm_lock); if (new_state == MHI_PM_FW_DL_ERR)
wake_up_all(&mhi_cntrl->state_event);
}
return ret;
}
Messung V0.5
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.6Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.