Skip to content
Snippets Groups Projects
Commit ed27de95 authored by Tony Truong's avatar Tony Truong
Browse files

msm: pcie: restore security config during PCIe link up


The security config for PCIe controller is not retained when PCIe
link is turned off. Thus, restore security config when PCIe link
is turned on.

Change-Id: Ie3a5238e40dd712e8d5e597b48b024c326d83c71
Signed-off-by: default avatarTony Truong <truong@codeaurora.org>
parent e5e4b4c9
Branches
Tags
No related merge requests found
...@@ -71,6 +71,10 @@ Optional Properties: ...@@ -71,6 +71,10 @@ Optional Properties:
- qcom,msm-bus,num-cases - qcom,msm-bus,num-cases
- qcom,msm-bus,num-paths - qcom,msm-bus,num-paths
- qcom,msm-bus,vectors-KBps - qcom,msm-bus,vectors-KBps
- qcom,scm-dev-id: If present then device id value is passed to secure channel
manager(scm) driver. scm driver uses this device id to restore PCIe
controller related security configuration after coming out of the controller
power collapse.
Example: Example:
...@@ -155,4 +159,6 @@ Example: ...@@ -155,4 +159,6 @@ Example:
qcom,msm-bus,vectors-KBps = qcom,msm-bus,vectors-KBps =
<45 512 0 0>, <45 512 0 0>,
<45 512 500 800>; <45 512 500 800>;
qcom,scm-dev-id = <11>;
}; };
...@@ -38,6 +38,7 @@ ...@@ -38,6 +38,7 @@
#include <linux/irqdomain.h> #include <linux/irqdomain.h>
#include <linux/pm_wakeup.h> #include <linux/pm_wakeup.h>
#include <linux/compiler.h> #include <linux/compiler.h>
#include <soc/qcom/scm.h>
#include <linux/ipc_logging.h> #include <linux/ipc_logging.h>
#include <linux/msm_pcie.h> #include <linux/msm_pcie.h>
...@@ -224,6 +225,7 @@ ...@@ -224,6 +225,7 @@
#define MAX_BUS_NUM 3 #define MAX_BUS_NUM 3
#define MAX_PROP_SIZE 32 #define MAX_PROP_SIZE 32
#define MAX_RC_NAME_LEN 15 #define MAX_RC_NAME_LEN 15
#define PCIE_MSM_RESTORE_SCM_CFG_CMD 0x2
#define MSM_PCIE_MAX_VREG 3 #define MSM_PCIE_MAX_VREG 3
#define MSM_PCIE_MAX_CLK 7 #define MSM_PCIE_MAX_CLK 7
#define MSM_PCIE_MAX_PIPE_CLK 1 #define MSM_PCIE_MAX_PIPE_CLK 1
...@@ -455,6 +457,7 @@ struct msm_pcie_dev_t { ...@@ -455,6 +457,7 @@ struct msm_pcie_dev_t {
u32 rc_shadow[PCIE_CONF_SPACE_DW]; u32 rc_shadow[PCIE_CONF_SPACE_DW];
bool shadow_en; bool shadow_en;
struct msm_pcie_register_event *event_reg; struct msm_pcie_register_event *event_reg;
unsigned int scm_dev_id;
bool power_on; bool power_on;
void *ipc_log; void *ipc_log;
struct msm_pcie_device_info pcidev_table[MAX_DEVICE_NUM]; struct msm_pcie_device_info pcidev_table[MAX_DEVICE_NUM];
...@@ -763,6 +766,36 @@ static bool pcie_phy_is_ready(struct msm_pcie_dev_t *dev) ...@@ -763,6 +766,36 @@ static bool pcie_phy_is_ready(struct msm_pcie_dev_t *dev)
return true; return true;
} }
static int msm_pcie_restore_sec_config(struct msm_pcie_dev_t *dev)
{
/* scm command buffer structrue */
struct msm_pcie_scm_cmd_buf {
unsigned int device_id;
unsigned int spare;
} cbuf;
int ret, scm_ret = 0;
if (!dev) {
pr_err("PCIe: the input pcie dev is NULL.\n");
return -ENODEV;
}
cbuf.device_id = dev->scm_dev_id;
ret = scm_call(SCM_SVC_MP, PCIE_MSM_RESTORE_SCM_CFG_CMD, &cbuf,
sizeof(cbuf), &scm_ret, sizeof(scm_ret));
if (ret || scm_ret) {
PCIE_ERR(dev,
"PCIe: RC%d failed(%d) to restore sec config, scm_ret=%d\n",
dev->rc_idx, ret, scm_ret);
return ret ? ret : -EINVAL;
}
return 0;
}
static bool msm_pcie_confirm_linkup(struct msm_pcie_dev_t *dev, static bool msm_pcie_confirm_linkup(struct msm_pcie_dev_t *dev,
bool check_sw_stts, bool check_sw_stts,
bool check_ep) bool check_ep)
...@@ -1903,6 +1936,11 @@ int msm_pcie_enable(struct msm_pcie_dev_t *dev, u32 options) ...@@ -1903,6 +1936,11 @@ int msm_pcie_enable(struct msm_pcie_dev_t *dev, u32 options)
goto clk_fail; goto clk_fail;
} }
if (dev->scm_dev_id) {
PCIE_DBG(dev, "RC%d: restoring sec config\n", dev->rc_idx);
msm_pcie_restore_sec_config(dev);
}
/* enable PCIe clocks and resets */ /* enable PCIe clocks and resets */
msm_pcie_write_mask(dev->parf + PCIE20_PARF_PHY_CTRL, BIT(0), 0); msm_pcie_write_mask(dev->parf + PCIE20_PARF_PHY_CTRL, BIT(0), 0);
...@@ -2984,6 +3022,11 @@ static int msm_pcie_probe(struct platform_device *pdev) ...@@ -2984,6 +3022,11 @@ static int msm_pcie_probe(struct platform_device *pdev)
} }
} }
msm_pcie_dev[rc_idx].scm_dev_id = 0;
ret = of_property_read_u32((&pdev->dev)->of_node,
"qcom,scm-dev-id",
&msm_pcie_dev[rc_idx].scm_dev_id);
msm_pcie_dev[rc_idx].rc_idx = rc_idx; msm_pcie_dev[rc_idx].rc_idx = rc_idx;
msm_pcie_dev[rc_idx].pdev = pdev; msm_pcie_dev[rc_idx].pdev = pdev;
msm_pcie_dev[rc_idx].vreg_n = 0; msm_pcie_dev[rc_idx].vreg_n = 0;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment