mhi: core: Read the EXEC_ENV from device
Read the EXEC_ENV register from device to determine the MHI base state. Change-Id: Id70a360cfa3775a7186e5059306385a37960df2d Signed-off-by: Andrei Danaila <adanaila@codeaurora.org> Signed-off-by: Tony Truong <truong@codeaurora.org>
This commit is contained in:
parent
747f687329
commit
4b71631d65
3 changed files with 35 additions and 31 deletions
|
@ -170,17 +170,12 @@ int bhi_probe(struct mhi_pcie_dev_info *mhi_pcie_device)
|
||||||
{
|
{
|
||||||
struct bhi_ctxt_t *bhi_ctxt = &mhi_pcie_device->bhi_ctxt;
|
struct bhi_ctxt_t *bhi_ctxt = &mhi_pcie_device->bhi_ctxt;
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
u32 pcie_word_val = 0;
|
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
if (NULL == mhi_pcie_device || 0 == mhi_pcie_device->core.bar0_base
|
if (NULL == mhi_pcie_device || 0 == mhi_pcie_device->core.bar0_base
|
||||||
|| 0 == mhi_pcie_device->core.bar0_end)
|
|| 0 == mhi_pcie_device->core.bar0_end)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
|
||||||
bhi_ctxt->bhi_base = mhi_pcie_device->core.bar0_base;
|
|
||||||
pcie_word_val = mhi_reg_read(bhi_ctxt->bhi_base, BHIOFF);
|
|
||||||
bhi_ctxt->bhi_base += pcie_word_val;
|
|
||||||
|
|
||||||
mhi_log(MHI_MSG_INFO,
|
mhi_log(MHI_MSG_INFO,
|
||||||
"Successfully registered char dev. bhi base is: 0x%p.\n",
|
"Successfully registered char dev. bhi base is: 0x%p.\n",
|
||||||
bhi_ctxt->bhi_base);
|
bhi_ctxt->bhi_base);
|
||||||
|
|
|
@ -167,17 +167,10 @@ int mhi_ctxt_init(struct mhi_pcie_dev_info *mhi_pcie_dev)
|
||||||
pcie_device->dev.platform_data = &mhi_pcie_dev->mhi_ctxt;
|
pcie_device->dev.platform_data = &mhi_pcie_dev->mhi_ctxt;
|
||||||
mhi_pcie_dev->mhi_ctxt.dev_info->plat_dev->dev.platform_data =
|
mhi_pcie_dev->mhi_ctxt.dev_info->plat_dev->dev.platform_data =
|
||||||
&mhi_pcie_dev->mhi_ctxt;
|
&mhi_pcie_dev->mhi_ctxt;
|
||||||
if (mhi_pcie_dev->mhi_ctxt.base_state == STATE_TRANSITION_BHI) {
|
|
||||||
ret_val = bhi_probe(mhi_pcie_dev);
|
|
||||||
if (ret_val) {
|
|
||||||
mhi_log(MHI_MSG_ERROR, "Failed to initialize BHI.\n");
|
|
||||||
goto mhi_state_transition_error;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ret_val = mhi_reg_notifiers(&mhi_pcie_dev->mhi_ctxt);
|
ret_val = mhi_reg_notifiers(&mhi_pcie_dev->mhi_ctxt);
|
||||||
if (ret_val) {
|
if (ret_val) {
|
||||||
mhi_log(MHI_MSG_ERROR, "Failed to register for notifiers\n");
|
mhi_log(MHI_MSG_ERROR, "Failed to register for notifiers\n");
|
||||||
return ret_val;
|
goto mhi_state_transition_error;
|
||||||
}
|
}
|
||||||
mhi_log(MHI_MSG_INFO,
|
mhi_log(MHI_MSG_INFO,
|
||||||
"Finished all driver probing returning ret_val %d.\n",
|
"Finished all driver probing returning ret_val %d.\n",
|
||||||
|
|
|
@ -12,6 +12,8 @@
|
||||||
|
|
||||||
#include <mhi_sys.h>
|
#include <mhi_sys.h>
|
||||||
#include <mhi.h>
|
#include <mhi.h>
|
||||||
|
#include <mhi_bhi.h>
|
||||||
|
#include <mhi_hwio.h>
|
||||||
|
|
||||||
#include <soc/qcom/subsystem_restart.h>
|
#include <soc/qcom/subsystem_restart.h>
|
||||||
#include <soc/qcom/subsystem_notif.h>
|
#include <soc/qcom/subsystem_notif.h>
|
||||||
|
@ -79,19 +81,6 @@ static struct notifier_block mhi_ssr_nb = {
|
||||||
.notifier_call = mhi_ssr_notify_cb,
|
.notifier_call = mhi_ssr_notify_cb,
|
||||||
};
|
};
|
||||||
|
|
||||||
static void esoc_parse_link_type(struct mhi_device_ctxt *mhi_dev_ctxt)
|
|
||||||
{
|
|
||||||
int ret_val;
|
|
||||||
|
|
||||||
ret_val = strcmp(mhi_dev_ctxt->esoc_handle->link, "HSIC+PCIe");
|
|
||||||
mhi_log(MHI_MSG_VERBOSE, "Link type is %s as indicated by ESOC\n",
|
|
||||||
mhi_dev_ctxt->esoc_handle->link);
|
|
||||||
if (ret_val)
|
|
||||||
mhi_dev_ctxt->base_state = STATE_TRANSITION_BHI;
|
|
||||||
else
|
|
||||||
mhi_dev_ctxt->base_state = STATE_TRANSITION_RESET;
|
|
||||||
}
|
|
||||||
|
|
||||||
int mhi_esoc_register(struct mhi_device_ctxt *mhi_dev_ctxt)
|
int mhi_esoc_register(struct mhi_device_ctxt *mhi_dev_ctxt)
|
||||||
{
|
{
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
|
@ -99,7 +88,6 @@ int mhi_esoc_register(struct mhi_device_ctxt *mhi_dev_ctxt)
|
||||||
struct pci_driver *mhi_driver;
|
struct pci_driver *mhi_driver;
|
||||||
struct device *dev = &mhi_dev_ctxt->dev_info->pcie_device->dev;
|
struct device *dev = &mhi_dev_ctxt->dev_info->pcie_device->dev;
|
||||||
|
|
||||||
mhi_dev_ctxt->base_state = STATE_TRANSITION_BHI;
|
|
||||||
mhi_driver = mhi_dev_ctxt->dev_info->mhi_pcie_driver;
|
mhi_driver = mhi_dev_ctxt->dev_info->mhi_pcie_driver;
|
||||||
np = dev->of_node;
|
np = dev->of_node;
|
||||||
mhi_dev_ctxt->esoc_handle = devm_register_esoc_client(dev, "mdm");
|
mhi_dev_ctxt->esoc_handle = devm_register_esoc_client(dev, "mdm");
|
||||||
|
@ -113,8 +101,6 @@ int mhi_esoc_register(struct mhi_device_ctxt *mhi_dev_ctxt)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
}
|
}
|
||||||
|
|
||||||
esoc_parse_link_type(mhi_dev_ctxt);
|
|
||||||
|
|
||||||
mhi_dev_ctxt->esoc_ssr_handle = subsys_notif_register_notifier(
|
mhi_dev_ctxt->esoc_ssr_handle = subsys_notif_register_notifier(
|
||||||
mhi_dev_ctxt->esoc_handle->name,
|
mhi_dev_ctxt->esoc_handle->name,
|
||||||
&mhi_ssr_nb);
|
&mhi_ssr_nb);
|
||||||
|
@ -162,6 +148,34 @@ void mhi_notify_clients(struct mhi_device_ctxt *mhi_dev_ctxt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int set_mhi_base_state(struct mhi_pcie_dev_info *mhi_pcie_dev)
|
||||||
|
{
|
||||||
|
u32 pcie_word_val = 0;
|
||||||
|
int r = 0;
|
||||||
|
struct mhi_device_ctxt *mhi_dev_ctxt = &mhi_pcie_dev->mhi_ctxt;
|
||||||
|
|
||||||
|
mhi_pcie_dev->bhi_ctxt.bhi_base = mhi_pcie_dev->core.bar0_base;
|
||||||
|
pcie_word_val = mhi_reg_read(mhi_pcie_dev->bhi_ctxt.bhi_base, BHIOFF);
|
||||||
|
mhi_pcie_dev->bhi_ctxt.bhi_base += pcie_word_val;
|
||||||
|
pcie_word_val = mhi_reg_read(mhi_pcie_dev->bhi_ctxt.bhi_base,
|
||||||
|
BHI_EXECENV);
|
||||||
|
if (pcie_word_val == MHI_EXEC_ENV_AMSS) {
|
||||||
|
mhi_dev_ctxt->base_state = STATE_TRANSITION_RESET;
|
||||||
|
} else if (pcie_word_val == MHI_EXEC_ENV_PBL) {
|
||||||
|
mhi_dev_ctxt->base_state = STATE_TRANSITION_BHI;
|
||||||
|
r = bhi_probe(mhi_pcie_dev);
|
||||||
|
if (r)
|
||||||
|
mhi_log(MHI_MSG_ERROR, "Failed to initialize BHI.\n");
|
||||||
|
} else {
|
||||||
|
mhi_log(MHI_MSG_ERROR, "Invalid EXEC_ENV: 0x%x\n",
|
||||||
|
pcie_word_val);
|
||||||
|
r = -EIO;
|
||||||
|
}
|
||||||
|
mhi_log(MHI_MSG_INFO, "EXEC_ENV: %d Base state %d\n",
|
||||||
|
pcie_word_val, mhi_dev_ctxt->base_state);
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
void mhi_link_state_cb(struct msm_pcie_notify *notify)
|
void mhi_link_state_cb(struct msm_pcie_notify *notify)
|
||||||
{
|
{
|
||||||
int ret_val = 0;
|
int ret_val = 0;
|
||||||
|
@ -200,6 +214,9 @@ void mhi_link_state_cb(struct msm_pcie_notify *notify)
|
||||||
mhi_dev_ctxt = &mhi_pcie_dev->mhi_ctxt;
|
mhi_dev_ctxt = &mhi_pcie_dev->mhi_ctxt;
|
||||||
mhi_pcie_dev->mhi_ctxt.flags.link_up = 1;
|
mhi_pcie_dev->mhi_ctxt.flags.link_up = 1;
|
||||||
pci_set_master(mhi_pcie_dev->pcie_device);
|
pci_set_master(mhi_pcie_dev->pcie_device);
|
||||||
|
r = set_mhi_base_state(mhi_pcie_dev);
|
||||||
|
if (r)
|
||||||
|
return;
|
||||||
init_mhi_base_state(mhi_dev_ctxt);
|
init_mhi_base_state(mhi_dev_ctxt);
|
||||||
} else {
|
} else {
|
||||||
mhi_log(MHI_MSG_INFO,
|
mhi_log(MHI_MSG_INFO,
|
||||||
|
@ -242,8 +259,7 @@ int init_mhi_base_state(struct mhi_device_ctxt *mhi_dev_ctxt)
|
||||||
if (r)
|
if (r)
|
||||||
mhi_log(MHI_MSG_INFO,
|
mhi_log(MHI_MSG_INFO,
|
||||||
"Failed to scale bus request to active set.\n");
|
"Failed to scale bus request to active set.\n");
|
||||||
r = mhi_init_state_transition(mhi_dev_ctxt,
|
r = mhi_init_state_transition(mhi_dev_ctxt, mhi_dev_ctxt->base_state);
|
||||||
mhi_dev_ctxt->base_state);
|
|
||||||
if (r) {
|
if (r) {
|
||||||
mhi_log(MHI_MSG_CRITICAL,
|
mhi_log(MHI_MSG_CRITICAL,
|
||||||
"Failed to start state change event, to %d\n",
|
"Failed to start state change event, to %d\n",
|
||||||
|
|
Loading…
Add table
Reference in a new issue