summaryrefslogtreecommitdiff
path: root/drivers/pci
diff options
context:
space:
mode:
authorTony Truong <truong@codeaurora.org>2015-01-28 16:04:53 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:09:02 -0700
commitb80470b0c1be9c496af542a98eec0ae31d2cc5c3 (patch)
tree8f7280b8b951e3ab92d689b96f95f32042fa9e82 /drivers/pci
parentb77df9a2633f352375ebe1ba9407352983d2c859 (diff)
msm: pcie: calculate EP's capability register offsets
The start address of the capability register varies depending on the endpoint. This change calculates the endpoint's capability register offset instead of using a fixed one. Change-Id: I28a97d316aee8c34afe313838b91fcc06af0847f Signed-off-by: Tony Truong <truong@codeaurora.org>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/host/pci-msm.c122
1 files changed, 86 insertions, 36 deletions
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 01ff8b8fca1f..0ca874fbc763 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -1190,6 +1190,29 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
u32 current_offset = 0;
u32 ep_l1sub_ctrl1_offset = 0;
u32 ep_l1sub_cap_reg1_offset = 0;
+ u32 ep_link_ctrlstts_offset = 0;
+ u32 ep_dev_ctrl2stts2_offset = 0;
+
+ current_offset = readl_relaxed(dev->conf + PCIE_CAP_PTR_OFFSET) & 0xff;
+
+ while (current_offset) {
+ val = readl_relaxed(dev->conf + current_offset);
+ if ((val & 0xff) == PCIE20_CAP_ID) {
+ ep_link_ctrlstts_offset = current_offset + 0x10;
+ ep_dev_ctrl2stts2_offset = current_offset + 0x28;
+ break;
+ }
+ current_offset = (val >> 8) & 0xff;
+ }
+
+ if (!ep_link_ctrlstts_offset)
+ PCIE_DBG(dev,
+ "RC%d endpoint does not support PCIe capability registers\n",
+ dev->rc_idx);
+ else
+ PCIE_DBG(dev,
+ "RC%d: ep_link_ctrlstts_offset: 0x%x\n",
+ dev->rc_idx, ep_link_ctrlstts_offset);
switch (testcase) {
case 0: /* output status */
@@ -1264,22 +1287,22 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
PCIE20_CAP_LINKCTRLSTATUS,
BIT(0), 0);
msm_pcie_write_mask(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS,
+ ep_link_ctrlstts_offset,
BIT(0), 0);
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_CAP_LINKCTRLSTATUS / 4] =
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS);
- dev->ep_shadow[0][PCIE20_CAP_LINKCTRLSTATUS / 4] =
+ dev->ep_shadow[0][ep_link_ctrlstts_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS);
+ ep_link_ctrlstts_offset);
}
pr_alert("PCIe: RC's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS));
pr_alert("PCIe: EP's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS));
+ ep_link_ctrlstts_offset));
break;
case 6: /* enable L0s */
pr_alert("\n\nPCIe: RC%d: enable L0s\n\n",
@@ -1288,22 +1311,22 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
PCIE20_CAP_LINKCTRLSTATUS,
0, BIT(0));
msm_pcie_write_mask(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS,
+ ep_link_ctrlstts_offset,
0, BIT(0));
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_CAP_LINKCTRLSTATUS / 4] =
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS);
- dev->ep_shadow[0][PCIE20_CAP_LINKCTRLSTATUS / 4] =
+ dev->ep_shadow[0][ep_link_ctrlstts_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS);
+ ep_link_ctrlstts_offset);
}
pr_alert("PCIe: RC's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS));
pr_alert("PCIe: EP's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS));
+ ep_link_ctrlstts_offset));
break;
case 7: /* disable L1 */
pr_alert("\n\nPCIe: RC%d: disable L1\n\n",
@@ -1312,22 +1335,22 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
PCIE20_CAP_LINKCTRLSTATUS,
BIT(1), 0);
msm_pcie_write_mask(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS,
+ ep_link_ctrlstts_offset,
BIT(1), 0);
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_CAP_LINKCTRLSTATUS / 4] =
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS);
- dev->ep_shadow[0][PCIE20_CAP_LINKCTRLSTATUS / 4] =
+ dev->ep_shadow[0][ep_link_ctrlstts_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS);
+ ep_link_ctrlstts_offset);
}
pr_alert("PCIe: RC's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS));
pr_alert("PCIe: EP's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS));
+ ep_link_ctrlstts_offset));
break;
case 8: /* enable L1 */
pr_alert("\n\nPCIe: RC%d: enable L1\n\n",
@@ -1336,22 +1359,22 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
PCIE20_CAP_LINKCTRLSTATUS,
0, BIT(1));
msm_pcie_write_mask(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS,
+ ep_link_ctrlstts_offset,
0, BIT(1));
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_CAP_LINKCTRLSTATUS / 4] =
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS);
- dev->ep_shadow[0][PCIE20_CAP_LINKCTRLSTATUS / 4] =
+ dev->ep_shadow[0][ep_link_ctrlstts_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS);
+ ep_link_ctrlstts_offset);
}
pr_alert("PCIe: RC's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS));
pr_alert("PCIe: EP's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS));
+ ep_link_ctrlstts_offset));
break;
case 9: /* disable L1ss */
pr_alert("\n\nPCIe: RC%d: disable L1ss\n\n",
@@ -1385,7 +1408,7 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
ep_l1sub_ctrl1_offset,
0xf, 0);
msm_pcie_write_mask(dev->conf +
- PCIE20_DEVICE_CONTROL2_STATUS2,
+ ep_dev_ctrl2stts2_offset,
BIT(10), 0);
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_L1SUB_CONTROL1 / 4] =
@@ -1397,9 +1420,9 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
dev->ep_shadow[0][ep_l1sub_ctrl1_offset / 4] =
readl_relaxed(dev->conf +
ep_l1sub_ctrl1_offset);
- dev->ep_shadow[0][PCIE20_DEVICE_CONTROL2_STATUS2 / 4] =
+ dev->ep_shadow[0][ep_dev_ctrl2stts2_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_DEVICE_CONTROL2_STATUS2);
+ ep_dev_ctrl2stts2_offset);
}
pr_alert("PCIe: RC's L1SUB_CONTROL1:0x%x\n",
readl_relaxed(dev->dm_core +
@@ -1412,7 +1435,7 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
ep_l1sub_ctrl1_offset));
pr_alert("PCIe: EP's DEVICE_CONTROL2_STATUS2:0x%x\n",
readl_relaxed(dev->conf +
- PCIE20_DEVICE_CONTROL2_STATUS2));
+ ep_dev_ctrl2stts2_offset));
break;
case 10: /* enable L1ss */
pr_alert("\n\nPCIe: RC%d: enable L1ss\n\n",
@@ -1455,7 +1478,7 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
ep_l1sub_ctrl1_offset,
0xf, val);
msm_pcie_write_mask(dev->conf +
- PCIE20_DEVICE_CONTROL2_STATUS2,
+ ep_dev_ctrl2stts2_offset,
0, BIT(10));
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_L1SUB_CONTROL1 / 4] =
@@ -1467,9 +1490,9 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
dev->ep_shadow[0][ep_l1sub_ctrl1_offset / 4] =
readl_relaxed(dev->conf +
ep_l1sub_ctrl1_offset);
- dev->ep_shadow[0][PCIE20_DEVICE_CONTROL2_STATUS2 / 4] =
+ dev->ep_shadow[0][ep_dev_ctrl2stts2_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_DEVICE_CONTROL2_STATUS2);
+ ep_dev_ctrl2stts2_offset);
}
pr_alert("PCIe: RC's L1SUB_CONTROL1:0x%x\n",
readl_relaxed(dev->dm_core +
@@ -1482,7 +1505,7 @@ static void msm_pcie_sel_debug_testcase(struct msm_pcie_dev_t *dev,
ep_l1sub_ctrl1_offset));
pr_alert("PCIe: EP's DEVICE_CONTROL2_STATUS2:0x%x\n",
readl_relaxed(dev->conf +
- PCIE20_DEVICE_CONTROL2_STATUS2));
+ ep_dev_ctrl2stts2_offset));
break;
case 11: /* enumerate PCIe */
pr_alert("\n\nPCIe: attempting to enumerate RC%d\n\n",
@@ -2597,50 +2620,77 @@ static void msm_pcie_config_link_state(struct msm_pcie_dev_t *dev)
u32 current_offset;
u32 ep_l1sub_ctrl1_offset = 0;
u32 ep_l1sub_cap_reg1_offset = 0;
+ u32 ep_link_cap_offset = 0;
+ u32 ep_link_ctrlstts_offset = 0;
+ u32 ep_dev_ctrl2stts2_offset = 0;
/* Enable the AUX Clock and the Core Clk to be synchronous for L1SS*/
if (!dev->aux_clk_sync && dev->l1ss_supported)
msm_pcie_write_mask(dev->parf +
PCIE20_PARF_SYS_CTRL, BIT(3), 0);
+ current_offset = readl_relaxed(dev->conf + PCIE_CAP_PTR_OFFSET) & 0xff;
+
+ while (current_offset) {
+ val = readl_relaxed(dev->conf + current_offset);
+ if ((val & 0xff) == PCIE20_CAP_ID) {
+ ep_link_cap_offset = current_offset + 0x0c;
+ ep_link_ctrlstts_offset = current_offset + 0x10;
+ ep_dev_ctrl2stts2_offset = current_offset + 0x28;
+ break;
+ }
+ current_offset = (val >> 8) & 0xff;
+ }
+
+ if (!ep_link_cap_offset) {
+ PCIE_DBG(dev,
+ "RC%d endpoint does not support PCIe capability registers\n",
+ dev->rc_idx);
+ return;
+ } else {
+ PCIE_DBG(dev,
+ "RC%d: ep_link_cap_offset: 0x%x\n",
+ dev->rc_idx, ep_link_cap_offset);
+ }
+
if (dev->l0s_supported) {
msm_pcie_write_mask(dev->dm_core + PCIE20_CAP_LINKCTRLSTATUS,
0, BIT(0));
- msm_pcie_write_mask(dev->conf + PCIE20_CAP_LINKCTRLSTATUS,
+ msm_pcie_write_mask(dev->conf + ep_link_ctrlstts_offset,
0, BIT(0));
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_CAP_LINKCTRLSTATUS / 4] =
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS);
- dev->ep_shadow[0][PCIE20_CAP_LINKCTRLSTATUS / 4] =
+ dev->ep_shadow[0][ep_link_ctrlstts_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS);
+ ep_link_ctrlstts_offset);
}
PCIE_DBG2(dev, "RC's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS));
PCIE_DBG2(dev, "EP's CAP_LINKCTRLSTATUS:0x%x\n",
- readl_relaxed(dev->conf + PCIE20_CAP_LINKCTRLSTATUS));
+ readl_relaxed(dev->conf + ep_link_ctrlstts_offset));
}
if (dev->l1_supported) {
msm_pcie_write_mask(dev->dm_core + PCIE20_CAP_LINKCTRLSTATUS,
0, BIT(1));
- msm_pcie_write_mask(dev->conf + PCIE20_CAP_LINKCTRLSTATUS,
+ msm_pcie_write_mask(dev->conf + ep_link_ctrlstts_offset,
0, BIT(1));
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_CAP_LINKCTRLSTATUS / 4] =
readl_relaxed(dev->conf +
PCIE20_CAP_LINKCTRLSTATUS);
- dev->ep_shadow[0][PCIE20_CAP_LINKCTRLSTATUS / 4] =
+ dev->ep_shadow[0][ep_link_ctrlstts_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_CAP_LINKCTRLSTATUS);
+ ep_link_ctrlstts_offset);
}
PCIE_DBG2(dev, "RC's CAP_LINKCTRLSTATUS:0x%x\n",
readl_relaxed(dev->dm_core +
PCIE20_CAP_LINKCTRLSTATUS));
PCIE_DBG2(dev, "EP's CAP_LINKCTRLSTATUS:0x%x\n",
- readl_relaxed(dev->conf + PCIE20_CAP_LINKCTRLSTATUS));
+ readl_relaxed(dev->conf + ep_link_ctrlstts_offset));
}
if (dev->l1ss_supported) {
@@ -2676,7 +2726,7 @@ static void msm_pcie_config_link_state(struct msm_pcie_dev_t *dev)
0, BIT(10));
msm_pcie_write_reg_field(dev->conf, ep_l1sub_ctrl1_offset,
0xf, val);
- msm_pcie_write_mask(dev->conf + PCIE20_DEVICE_CONTROL2_STATUS2,
+ msm_pcie_write_mask(dev->conf + ep_dev_ctrl2stts2_offset,
0, BIT(10));
if (dev->shadow_en) {
dev->rc_shadow[PCIE20_L1SUB_CONTROL1 / 4] =
@@ -2688,9 +2738,9 @@ static void msm_pcie_config_link_state(struct msm_pcie_dev_t *dev)
dev->ep_shadow[0][ep_l1sub_ctrl1_offset / 4] =
readl_relaxed(dev->conf +
ep_l1sub_ctrl1_offset);
- dev->ep_shadow[0][PCIE20_DEVICE_CONTROL2_STATUS2 / 4] =
+ dev->ep_shadow[0][ep_dev_ctrl2stts2_offset / 4] =
readl_relaxed(dev->conf +
- PCIE20_DEVICE_CONTROL2_STATUS2);
+ ep_dev_ctrl2stts2_offset);
}
PCIE_DBG2(dev, "RC's L1SUB_CONTROL1:0x%x\n",
readl_relaxed(dev->dm_core + PCIE20_L1SUB_CONTROL1));
@@ -2701,7 +2751,7 @@ static void msm_pcie_config_link_state(struct msm_pcie_dev_t *dev)
readl_relaxed(dev->conf + ep_l1sub_ctrl1_offset));
PCIE_DBG2(dev, "EP's DEVICE_CONTROL2_STATUS2:0x%x\n",
readl_relaxed(dev->conf +
- PCIE20_DEVICE_CONTROL2_STATUS2));
+ ep_dev_ctrl2stts2_offset));
}
}