summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTony Truong <truong@codeaurora.org>2015-04-29 19:22:00 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 11:09:16 -0700
commit66be1625587cb321acbfa5062218c1aa40459028 (patch)
treedce4d2f73eb4c345f8499f752c7aac85a48b650d
parente20be88c34e2d45c2eab6af4d05b55ecaf3ad1b5 (diff)
msm: pcie: add support to enable additional GPIO for endpoint
Some EP requires additional GPIO to be enabled for link training. Add the support in PCIe Bus Driver to manage this GPIO. Change-Id: I837edae478779fdaf3e94c70a0a031f9d0580a77 Signed-off-by: Tony Truong <truong@codeaurora.org>
-rw-r--r--Documentation/devicetree/bindings/pci/msm_pcie.txt2
-rw-r--r--drivers/pci/host/pci-msm.c31
2 files changed, 29 insertions, 4 deletions
diff --git a/Documentation/devicetree/bindings/pci/msm_pcie.txt b/Documentation/devicetree/bindings/pci/msm_pcie.txt
index 9033c4bb90d7..04a5585ceff4 100644
--- a/Documentation/devicetree/bindings/pci/msm_pcie.txt
+++ b/Documentation/devicetree/bindings/pci/msm_pcie.txt
@@ -47,6 +47,7 @@ Optional Properties:
- qcom,<supply-name>-voltage-level: specifies voltage levels for supply.
Should be specified in pairs (max, min, optimal), units uV.
- clkreq-gpio: CLKREQ GPIO specified by PCIe spec.
+ - qcom,ep-gpio: GPIO which enables a certain type of endpoint for link training.
- pinctrl-names: The state name of the pin configuration.
supports: "default", "sleep"
- pinctrl-0: For details of pinctrl properties, please refer to:
@@ -179,6 +180,7 @@ Example:
perst-gpio = <&msmgpio 70 0>;
wake-gpio = <&msmgpio 69 0>;
clkreq-gpio = <&msmgpio 68 0>;
+ qcom,ep-gpio = <&tlmm 94 0>;
gdsc-vdd-supply = <&gdsc_pcie_0>;
vreg-1.8-supply = <&pma8084_l12>;
diff --git a/drivers/pci/host/pci-msm.c b/drivers/pci/host/pci-msm.c
index 99535f6be2e0..810159df8707 100644
--- a/drivers/pci/host/pci-msm.c
+++ b/drivers/pci/host/pci-msm.c
@@ -360,6 +360,7 @@ enum msm_pcie_irq {
enum msm_pcie_gpio {
MSM_PCIE_GPIO_PERST,
MSM_PCIE_GPIO_WAKE,
+ MSM_PCIE_GPIO_EP,
MSM_PCIE_MAX_GPIO
};
@@ -376,6 +377,7 @@ struct msm_pcie_gpio_info_t {
bool out;
uint32_t on;
uint32_t init;
+ bool required;
};
/* voltage regulator info structrue */
@@ -567,8 +569,9 @@ static struct msm_pcie_vreg_info_t msm_pcie_vreg_info[MSM_PCIE_MAX_VREG] = {
/* GPIOs */
static struct msm_pcie_gpio_info_t msm_pcie_gpio_info[MSM_PCIE_MAX_GPIO] = {
- {"perst-gpio", 0, 1, 0, 0},
- {"wake-gpio", 0, 0, 0, 0}
+ {"perst-gpio", 0, 1, 0, 0, 1},
+ {"wake-gpio", 0, 0, 0, 0, 1},
+ {"qcom,ep-gpio", 0, 1, 1, 0, 0}
};
/* clocks */
@@ -3283,13 +3286,22 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev,
gpio_info->name, 0);
if (ret >= 0) {
gpio_info->num = ret;
- ret = 0;
dev->gpio_n++;
PCIE_DBG(dev, "GPIO num for %s is %d\n",
gpio_info->name, gpio_info->num);
} else {
- goto out;
+ if (gpio_info->required) {
+ PCIE_ERR(dev,
+ "Could not get required GPIO %s\n",
+ gpio_info->name);
+ goto out;
+ } else {
+ PCIE_DBG(dev,
+ "Could not get optional GPIO %s\n",
+ gpio_info->name);
+ }
}
+ ret = 0;
}
for (i = 0; i < MSM_PCIE_MAX_CLK; i++) {
@@ -3583,6 +3595,10 @@ int msm_pcie_enable(struct msm_pcie_dev_t *dev, u32 options)
if (dev->ep_latency)
usleep_range(dev->ep_latency * 1000, dev->ep_latency * 1000);
+ if (dev->gpio[MSM_PCIE_GPIO_EP].num)
+ gpio_set_value(dev->gpio[MSM_PCIE_GPIO_EP].num,
+ dev->gpio[MSM_PCIE_GPIO_EP].on);
+
/* de-assert PCIe reset link to bring EP out of reset */
PCIE_INFO(dev, "PCIe: Release the reset of endpoint of RC%d.\n",
@@ -3641,6 +3657,9 @@ int msm_pcie_enable(struct msm_pcie_dev_t *dev, u32 options)
goto out;
link_fail:
+ if (dev->gpio[MSM_PCIE_GPIO_EP].num)
+ gpio_set_value(dev->gpio[MSM_PCIE_GPIO_EP].num,
+ 1 - dev->gpio[MSM_PCIE_GPIO_EP].on);
msm_pcie_write_reg(dev->phy,
PCIE_N_SW_RESET(dev->rc_idx, dev->common_phy), 0x1);
msm_pcie_write_reg(dev->phy,
@@ -3712,6 +3731,10 @@ void msm_pcie_disable(struct msm_pcie_dev_t *dev, u32 options)
if (options & PM_PIPE_CLK)
msm_pcie_pipe_clk_deinit(dev);
+ if (dev->gpio[MSM_PCIE_GPIO_EP].num)
+ gpio_set_value(dev->gpio[MSM_PCIE_GPIO_EP].num,
+ 1 - dev->gpio[MSM_PCIE_GPIO_EP].on);
+
mutex_unlock(&dev->setup_lock);
PCIE_DBG(dev, "RC%d: exit\n", dev->rc_idx);