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>
This commit is contained in:
Tony Truong 2015-01-28 16:04:53 -08:00
parent 7e50aaf5f3
commit 863174982d
1 changed files with 86 additions and 36 deletions

View File

@ -1309,6 +1309,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 */
@ -1383,22 +1406,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",
@ -1407,22 +1430,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",
@ -1431,22 +1454,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",
@ -1455,22 +1478,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",
@ -1504,7 +1527,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] =
@ -1516,9 +1539,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 +
@ -1531,7 +1554,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",
@ -1574,7 +1597,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] =
@ -1586,9 +1609,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 +
@ -1601,7 +1624,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",
@ -2716,50 +2739,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) {
@ -2795,7 +2845,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] =
@ -2807,9 +2857,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));
@ -2820,7 +2870,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));
}
}