Loading Documentation/devicetree/bindings/pci/msm_pcie.txt +20 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,11 @@ Optional Properties: - qcom,n-fts: The number of fast training sequences sent when the link state is changed from L0s to L0. - qcom,pcie-phy-ver: version of PCIe PHY. - qcom,phy-sequence: The initialization sequence to bring up the PCIe PHY. Should be specified in groups (offset, value, delay). - qcom,port-phy-sequence: The initialization sequence to bring up the PCIe port PHY. Should be specified in groups (offset, value, delay). - qcom,use-19p2mhz-aux-clk: The frequency of PCIe AUX clock is 19.2MHz. - qcom,ep-wakeirq: The endpoint will issue wake signal when it is up, and the root complex has the capability to enumerate the endpoint for this case. Loading Loading @@ -189,6 +194,21 @@ Example: "msi_20", "msi_21", "msi_22", "msi_23", "msi_24", "msi_25", "msi_26", "msi_27", "msi_28", "msi_29", "msi_30", "msi_31"; qcom,phy-sequence = <0x804 0x01 0x00 0x034 0x14 0x00 0x138 0x30 0x00 0x048 0x0f 0x00 0x15c 0x06 0x00 0x090 0x01 0x00 0x808 0x03 0x00>; qcom,port-phy-sequence = <0x804 0x01 0x00 0x034 0x14 0x00 0x138 0x30 0x00 0x048 0x0f 0x00 0x15c 0x06 0x00 0x090 0x01 0x00 0x808 0x03 0x00>; perst-gpio = <&msmgpio 70 0>; wake-gpio = <&msmgpio 69 0>; clkreq-gpio = <&msmgpio 68 0>; Loading drivers/pci/host/pci-msm.c +105 −1 Original line number Diff line number Diff line Loading @@ -502,6 +502,13 @@ struct msm_pcie_irq_info_t { uint32_t num; }; /* phy info structure */ struct msm_pcie_phy_info_t { u32 offset; u32 val; u32 delay; }; /* PCIe device info structure */ struct msm_pcie_device_info { u32 bdf; Loading Loading @@ -615,6 +622,10 @@ struct msm_pcie_dev_t { u32 num_active_ep; u32 num_ep; bool pending_ep_reg; u32 phy_len; u32 port_phy_len; struct msm_pcie_phy_info_t *phy_sequence; struct msm_pcie_phy_info_t *port_phy_sequence; u32 ep_shadow[MAX_DEVICE_NUM][PCIE_CONF_SPACE_DW]; u32 rc_shadow[PCIE_CONF_SPACE_DW]; bool shadow_en; Loading Loading @@ -1411,10 +1422,28 @@ static bool pcie_phy_is_ready(struct msm_pcie_dev_t *dev) #else static void pcie_phy_init(struct msm_pcie_dev_t *dev) { int i; struct msm_pcie_phy_info_t *phy_seq; PCIE_DBG(dev, "RC%d: Initializing 14nm QMP phy - 19.2MHz with Common Mode Clock (SSC ON)\n", dev->rc_idx); if (dev->phy_sequence) { i = dev->phy_len; phy_seq = dev->phy_sequence; while (i--) { msm_pcie_write_reg(dev->phy, phy_seq->offset, phy_seq->val); if (phy_seq->delay) usleep_range(phy_seq->delay, phy_seq->delay + 1); phy_seq++; } return; } if (dev->common_phy) msm_pcie_write_reg(dev->phy, PCIE_COM_POWER_DOWN_CONTROL, 0x01); Loading Loading @@ -1475,6 +1504,8 @@ static void pcie_phy_init(struct msm_pcie_dev_t *dev) static void pcie_pcs_port_phy_init(struct msm_pcie_dev_t *dev) { int i; struct msm_pcie_phy_info_t *phy_seq; u8 common_phy; PCIE_DBG(dev, "RC%d: Initializing PCIe PHY Port\n", dev->rc_idx); Loading @@ -1484,6 +1515,21 @@ static void pcie_pcs_port_phy_init(struct msm_pcie_dev_t *dev) else common_phy = 0; if (dev->port_phy_sequence) { i = dev->port_phy_len; phy_seq = dev->port_phy_sequence; while (i--) { msm_pcie_write_reg(dev->phy, phy_seq->offset, phy_seq->val); if (phy_seq->delay) usleep_range(phy_seq->delay, phy_seq->delay + 1); phy_seq++; } return; } msm_pcie_write_reg(dev->phy, QSERDES_TX_N_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN(dev->rc_idx, common_phy), 0x45); Loading Loading @@ -1772,6 +1818,10 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev) dev->num_active_ep); PCIE_DBG_FS(dev, "pending_ep_reg: %s\n", dev->pending_ep_reg ? "true" : "false"); PCIE_DBG_FS(dev, "phy_len is %d", dev->phy_len); PCIE_DBG_FS(dev, "port_phy_len is %d", dev->port_phy_len); PCIE_DBG_FS(dev, "disable_pc is %d", dev->disable_pc); PCIE_DBG_FS(dev, "l0s_supported is %s supported\n", Loading Loading @@ -3821,7 +3871,7 @@ void msm_pcie_config_msi_controller(struct msm_pcie_dev_t *dev) static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, struct platform_device *pdev) { int i, len, cnt, ret = 0; int i, len, cnt, ret = 0, size = 0; struct msm_pcie_vreg_info_t *vreg_info; struct msm_pcie_gpio_info_t *gpio_info; struct msm_pcie_clk_info_t *clk_info; Loading Loading @@ -3944,6 +3994,56 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, ret = 0; } of_get_property(pdev->dev.of_node, "qcom,phy-sequence", &size); if (size) { dev->phy_sequence = (struct msm_pcie_phy_info_t *) devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (dev->phy_sequence) { dev->phy_len = size / sizeof(*dev->phy_sequence); of_property_read_u32_array(pdev->dev.of_node, "qcom,phy-sequence", (unsigned int *)dev->phy_sequence, size / sizeof(dev->phy_sequence->offset)); } else { PCIE_ERR(dev, "RC%d: Could not allocate memory for phy init sequence.\n", dev->rc_idx); ret = -ENOMEM; goto out; } } else { PCIE_DBG(dev, "RC%d: phy sequence is not present in DT\n", dev->rc_idx); } of_get_property(pdev->dev.of_node, "qcom,port-phy-sequence", &size); if (size) { dev->port_phy_sequence = (struct msm_pcie_phy_info_t *) devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (dev->port_phy_sequence) { dev->port_phy_len = size / sizeof(*dev->port_phy_sequence); of_property_read_u32_array(pdev->dev.of_node, "qcom,port-phy-sequence", (unsigned int *)dev->port_phy_sequence, size / sizeof(dev->port_phy_sequence->offset)); } else { PCIE_ERR(dev, "RC%d: Could not allocate memory for port phy init sequence.\n", dev->rc_idx); ret = -ENOMEM; goto out; } } else { PCIE_DBG(dev, "RC%d: port phy sequence is not present in DT\n", dev->rc_idx); } for (i = 0; i < MSM_PCIE_MAX_CLK; i++) { clk_info = &dev->clk[i]; Loading Loading @@ -5878,6 +5978,10 @@ static int msm_pcie_probe(struct platform_device *pdev) msm_pcie_dev[rc_idx].num_active_ep = 0; msm_pcie_dev[rc_idx].num_ep = 0; msm_pcie_dev[rc_idx].pending_ep_reg = false; msm_pcie_dev[rc_idx].phy_len = 0; msm_pcie_dev[rc_idx].port_phy_len = 0; msm_pcie_dev[rc_idx].phy_sequence = NULL; msm_pcie_dev[rc_idx].port_phy_sequence = NULL; msm_pcie_dev[rc_idx].event_reg = NULL; msm_pcie_dev[rc_idx].linkdown_counter = 0; msm_pcie_dev[rc_idx].link_turned_on_counter = 0; Loading Loading
Documentation/devicetree/bindings/pci/msm_pcie.txt +20 −0 Original line number Diff line number Diff line Loading @@ -73,6 +73,11 @@ Optional Properties: - qcom,n-fts: The number of fast training sequences sent when the link state is changed from L0s to L0. - qcom,pcie-phy-ver: version of PCIe PHY. - qcom,phy-sequence: The initialization sequence to bring up the PCIe PHY. Should be specified in groups (offset, value, delay). - qcom,port-phy-sequence: The initialization sequence to bring up the PCIe port PHY. Should be specified in groups (offset, value, delay). - qcom,use-19p2mhz-aux-clk: The frequency of PCIe AUX clock is 19.2MHz. - qcom,ep-wakeirq: The endpoint will issue wake signal when it is up, and the root complex has the capability to enumerate the endpoint for this case. Loading Loading @@ -189,6 +194,21 @@ Example: "msi_20", "msi_21", "msi_22", "msi_23", "msi_24", "msi_25", "msi_26", "msi_27", "msi_28", "msi_29", "msi_30", "msi_31"; qcom,phy-sequence = <0x804 0x01 0x00 0x034 0x14 0x00 0x138 0x30 0x00 0x048 0x0f 0x00 0x15c 0x06 0x00 0x090 0x01 0x00 0x808 0x03 0x00>; qcom,port-phy-sequence = <0x804 0x01 0x00 0x034 0x14 0x00 0x138 0x30 0x00 0x048 0x0f 0x00 0x15c 0x06 0x00 0x090 0x01 0x00 0x808 0x03 0x00>; perst-gpio = <&msmgpio 70 0>; wake-gpio = <&msmgpio 69 0>; clkreq-gpio = <&msmgpio 68 0>; Loading
drivers/pci/host/pci-msm.c +105 −1 Original line number Diff line number Diff line Loading @@ -502,6 +502,13 @@ struct msm_pcie_irq_info_t { uint32_t num; }; /* phy info structure */ struct msm_pcie_phy_info_t { u32 offset; u32 val; u32 delay; }; /* PCIe device info structure */ struct msm_pcie_device_info { u32 bdf; Loading Loading @@ -615,6 +622,10 @@ struct msm_pcie_dev_t { u32 num_active_ep; u32 num_ep; bool pending_ep_reg; u32 phy_len; u32 port_phy_len; struct msm_pcie_phy_info_t *phy_sequence; struct msm_pcie_phy_info_t *port_phy_sequence; u32 ep_shadow[MAX_DEVICE_NUM][PCIE_CONF_SPACE_DW]; u32 rc_shadow[PCIE_CONF_SPACE_DW]; bool shadow_en; Loading Loading @@ -1411,10 +1422,28 @@ static bool pcie_phy_is_ready(struct msm_pcie_dev_t *dev) #else static void pcie_phy_init(struct msm_pcie_dev_t *dev) { int i; struct msm_pcie_phy_info_t *phy_seq; PCIE_DBG(dev, "RC%d: Initializing 14nm QMP phy - 19.2MHz with Common Mode Clock (SSC ON)\n", dev->rc_idx); if (dev->phy_sequence) { i = dev->phy_len; phy_seq = dev->phy_sequence; while (i--) { msm_pcie_write_reg(dev->phy, phy_seq->offset, phy_seq->val); if (phy_seq->delay) usleep_range(phy_seq->delay, phy_seq->delay + 1); phy_seq++; } return; } if (dev->common_phy) msm_pcie_write_reg(dev->phy, PCIE_COM_POWER_DOWN_CONTROL, 0x01); Loading Loading @@ -1475,6 +1504,8 @@ static void pcie_phy_init(struct msm_pcie_dev_t *dev) static void pcie_pcs_port_phy_init(struct msm_pcie_dev_t *dev) { int i; struct msm_pcie_phy_info_t *phy_seq; u8 common_phy; PCIE_DBG(dev, "RC%d: Initializing PCIe PHY Port\n", dev->rc_idx); Loading @@ -1484,6 +1515,21 @@ static void pcie_pcs_port_phy_init(struct msm_pcie_dev_t *dev) else common_phy = 0; if (dev->port_phy_sequence) { i = dev->port_phy_len; phy_seq = dev->port_phy_sequence; while (i--) { msm_pcie_write_reg(dev->phy, phy_seq->offset, phy_seq->val); if (phy_seq->delay) usleep_range(phy_seq->delay, phy_seq->delay + 1); phy_seq++; } return; } msm_pcie_write_reg(dev->phy, QSERDES_TX_N_HIGHZ_TRANSCEIVEREN_BIAS_DRVR_EN(dev->rc_idx, common_phy), 0x45); Loading Loading @@ -1772,6 +1818,10 @@ static void msm_pcie_show_status(struct msm_pcie_dev_t *dev) dev->num_active_ep); PCIE_DBG_FS(dev, "pending_ep_reg: %s\n", dev->pending_ep_reg ? "true" : "false"); PCIE_DBG_FS(dev, "phy_len is %d", dev->phy_len); PCIE_DBG_FS(dev, "port_phy_len is %d", dev->port_phy_len); PCIE_DBG_FS(dev, "disable_pc is %d", dev->disable_pc); PCIE_DBG_FS(dev, "l0s_supported is %s supported\n", Loading Loading @@ -3821,7 +3871,7 @@ void msm_pcie_config_msi_controller(struct msm_pcie_dev_t *dev) static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, struct platform_device *pdev) { int i, len, cnt, ret = 0; int i, len, cnt, ret = 0, size = 0; struct msm_pcie_vreg_info_t *vreg_info; struct msm_pcie_gpio_info_t *gpio_info; struct msm_pcie_clk_info_t *clk_info; Loading Loading @@ -3944,6 +3994,56 @@ static int msm_pcie_get_resources(struct msm_pcie_dev_t *dev, ret = 0; } of_get_property(pdev->dev.of_node, "qcom,phy-sequence", &size); if (size) { dev->phy_sequence = (struct msm_pcie_phy_info_t *) devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (dev->phy_sequence) { dev->phy_len = size / sizeof(*dev->phy_sequence); of_property_read_u32_array(pdev->dev.of_node, "qcom,phy-sequence", (unsigned int *)dev->phy_sequence, size / sizeof(dev->phy_sequence->offset)); } else { PCIE_ERR(dev, "RC%d: Could not allocate memory for phy init sequence.\n", dev->rc_idx); ret = -ENOMEM; goto out; } } else { PCIE_DBG(dev, "RC%d: phy sequence is not present in DT\n", dev->rc_idx); } of_get_property(pdev->dev.of_node, "qcom,port-phy-sequence", &size); if (size) { dev->port_phy_sequence = (struct msm_pcie_phy_info_t *) devm_kzalloc(&pdev->dev, size, GFP_KERNEL); if (dev->port_phy_sequence) { dev->port_phy_len = size / sizeof(*dev->port_phy_sequence); of_property_read_u32_array(pdev->dev.of_node, "qcom,port-phy-sequence", (unsigned int *)dev->port_phy_sequence, size / sizeof(dev->port_phy_sequence->offset)); } else { PCIE_ERR(dev, "RC%d: Could not allocate memory for port phy init sequence.\n", dev->rc_idx); ret = -ENOMEM; goto out; } } else { PCIE_DBG(dev, "RC%d: port phy sequence is not present in DT\n", dev->rc_idx); } for (i = 0; i < MSM_PCIE_MAX_CLK; i++) { clk_info = &dev->clk[i]; Loading Loading @@ -5878,6 +5978,10 @@ static int msm_pcie_probe(struct platform_device *pdev) msm_pcie_dev[rc_idx].num_active_ep = 0; msm_pcie_dev[rc_idx].num_ep = 0; msm_pcie_dev[rc_idx].pending_ep_reg = false; msm_pcie_dev[rc_idx].phy_len = 0; msm_pcie_dev[rc_idx].port_phy_len = 0; msm_pcie_dev[rc_idx].phy_sequence = NULL; msm_pcie_dev[rc_idx].port_phy_sequence = NULL; msm_pcie_dev[rc_idx].event_reg = NULL; msm_pcie_dev[rc_idx].linkdown_counter = 0; msm_pcie_dev[rc_idx].link_turned_on_counter = 0; Loading