msm: ep_pcie: allow wake assertion during D3hot

PCIe client may need to wake up the host when PCIe link is still
on. Add the support to assert wake to host side when PCIe is in
D3hot.

Change-Id: I15ffd5f03183054c7ef5d143757b923f32de0adc
Signed-off-by: Yan He <yanhe@codeaurora.org>
This commit is contained in:
Yan He 2015-03-25 23:04:16 -07:00 committed by David Keitel
parent 5dbc08812b
commit 4b39cc2da0
2 changed files with 11 additions and 4 deletions

View file

@ -283,6 +283,7 @@ struct ep_pcie_dev_t {
bool perst_deast; bool perst_deast;
bool power_on; bool power_on;
bool suspending; bool suspending;
bool l23_ready;
bool l1ss_enabled; bool l1ss_enabled;
struct ep_pcie_msi_config msi_cfg; struct ep_pcie_msi_config msi_cfg;

View file

@ -1075,6 +1075,7 @@ int ep_pcie_core_enable_endpoint(enum ep_pcie_options opt)
goto link_fail; goto link_fail;
} else { } else {
dev->link_status = EP_PCIE_LINK_UP; dev->link_status = EP_PCIE_LINK_UP;
dev->l23_ready = false;
EP_PCIE_DBG(dev, EP_PCIE_DBG(dev,
"PCIe V%d: link is up after %d checkings (%d ms)\n", "PCIe V%d: link is up after %d checkings (%d ms)\n",
dev->rev, retries, dev->rev, retries,
@ -1250,6 +1251,7 @@ static irqreturn_t ep_pcie_handle_dstate_change_irq(int irq, void *data)
ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_DM_CORE), false); ep_pcie_reg_dump(dev, BIT(EP_PCIE_RES_DM_CORE), false);
if (dstate == 3) { if (dstate == 3) {
dev->l23_ready = true;
dev->d3_counter++; dev->d3_counter++;
EP_PCIE_DBG(dev, EP_PCIE_DBG(dev,
"PCIe V%d: No. %ld change to D3 state.\n", "PCIe V%d: No. %ld change to D3 state.\n",
@ -1257,6 +1259,7 @@ static irqreturn_t ep_pcie_handle_dstate_change_irq(int irq, void *data)
ep_pcie_write_mask(dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(1)); ep_pcie_write_mask(dev->parf + PCIE20_PARF_PM_CTRL, 0, BIT(1));
ep_pcie_notify_event(dev, EP_PCIE_EVENT_PM_D3_HOT); ep_pcie_notify_event(dev, EP_PCIE_EVENT_PM_D3_HOT);
} else if (dstate == 0) { } else if (dstate == 0) {
dev->l23_ready = false;
dev->d0_counter++; dev->d0_counter++;
EP_PCIE_DBG(dev, EP_PCIE_DBG(dev,
"PCIe V%d: No. %ld change to D0 state.\n", "PCIe V%d: No. %ld change to D0 state.\n",
@ -1647,14 +1650,17 @@ int ep_pcie_core_wakeup_host(void)
{ {
struct ep_pcie_dev_t *dev = &ep_pcie_dev; struct ep_pcie_dev_t *dev = &ep_pcie_dev;
if (dev->perst_deast) { if (dev->perst_deast && !dev->l23_ready) {
EP_PCIE_ERR(dev, EP_PCIE_ERR(dev,
"PCIe V%d: request to assert WAKE# when PERST is de-asserted.\n", "PCIe V%d: request to assert WAKE# when PERST is de-asserted and D3hot is not received.\n",
dev->rev); dev->rev);
return EP_PCIE_ERROR; return EP_PCIE_ERROR;
} else { } else {
EP_PCIE_DBG(dev, "PCIe V%d: No. %ld to assert PCIe WAKE#.\n", EP_PCIE_DBG(dev,
dev->rev, ++dev->wake_counter); "PCIe V%d: No. %ld to assert PCIe WAKE#; perst is %s de-asserted; D3hot is %s received.\n",
dev->rev, ++dev->wake_counter,
dev->perst_deast ? "" : "not",
dev->l23_ready ? "" : "not");
gpio_set_value(dev->gpio[EP_PCIE_GPIO_WAKE].num, gpio_set_value(dev->gpio[EP_PCIE_GPIO_WAKE].num,
1 - dev->gpio[EP_PCIE_GPIO_WAKE].on); 1 - dev->gpio[EP_PCIE_GPIO_WAKE].on);
gpio_set_value(dev->gpio[EP_PCIE_GPIO_WAKE].num, gpio_set_value(dev->gpio[EP_PCIE_GPIO_WAKE].num,