diff options
author | Bjorn Helgaas <bhelgaas@google.com> | 2016-12-12 12:25:11 -0500 |
---|---|---|
committer | Bjorn Helgaas <bhelgaas@google.com> | 2016-12-12 12:25:11 -0500 |
commit | 44b83b32e7c8d6fcd6a7e877ce3db65f6afdf87c (patch) | |
tree | 234c09cccd1e7a475598e79316cc61e3fd78c646 | |
parent | a1d9190d9682fd5cb8af811228f492b2ddd41366 (diff) | |
parent | 0722bdd2962a4a0f6d5e8973b0d274d147adacfb (diff) |
Merge branch 'pci/host-rockchip' into next
* pci/host-rockchip:
PCI: rockchip: Move the deassert of pm/aclk/pclk after phy_init()
PCI: rockchip: Split out rockchip_cfg_atu()
PCI: rockchip: Clean up bit definitions for PCIE_RC_CONFIG_LCS
PCI: rockchip: Correct the use of FTS mask
PCI: rockchip: Remove the pointer to L1 substate cap
PCI: rockchip: Specify the link capability
PCI: rockchip: Fix negotiated lanes calculation
PCI: rockchip: Add Kconfig COMPILE_TEST
PCI: rockchip: Mark RC as common clock architecture
PCI: rockchip: Provide captured slot power limit and scale
PCI: rockchip: Add three new resets as required properties
PCI: Don't attempt to claim shadow copies of ROM
PCI: designware: Check for iATU unroll support after initializing host
PCI: qcom: Fix pp->dev usage before assignment
PCI: designware-plat: Update author email address
PCI: layerscape: Fix drvdata usage before assignment
PCI: designware-plat: Change maintainer to Jose Abreu
-rw-r--r-- | Documentation/devicetree/bindings/pci/rockchip-pcie.txt | 11 | ||||
-rw-r--r-- | MAINTAINERS | 2 | ||||
-rw-r--r-- | drivers/pci/host/Kconfig | 2 | ||||
-rw-r--r-- | drivers/pci/host/pci-layerscape.c | 2 | ||||
-rw-r--r-- | drivers/pci/host/pcie-designware-plat.c | 2 | ||||
-rw-r--r-- | drivers/pci/host/pcie-designware.c | 7 | ||||
-rw-r--r-- | drivers/pci/host/pcie-qcom.c | 2 | ||||
-rw-r--r-- | drivers/pci/host/pcie-rockchip.c | 303 | ||||
-rw-r--r-- | drivers/pci/setup-res.c | 8 |
9 files changed, 238 insertions, 101 deletions
diff --git a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt index ba67b39939c1..71aeda1ca055 100644 --- a/Documentation/devicetree/bindings/pci/rockchip-pcie.txt +++ b/Documentation/devicetree/bindings/pci/rockchip-pcie.txt | |||
@@ -26,13 +26,16 @@ Required properties: | |||
26 | - "sys" | 26 | - "sys" |
27 | - "legacy" | 27 | - "legacy" |
28 | - "client" | 28 | - "client" |
29 | - resets: Must contain five entries for each entry in reset-names. | 29 | - resets: Must contain seven entries for each entry in reset-names. |
30 | See ../reset/reset.txt for details. | 30 | See ../reset/reset.txt for details. |
31 | - reset-names: Must include the following names | 31 | - reset-names: Must include the following names |
32 | - "core" | 32 | - "core" |
33 | - "mgmt" | 33 | - "mgmt" |
34 | - "mgmt-sticky" | 34 | - "mgmt-sticky" |
35 | - "pipe" | 35 | - "pipe" |
36 | - "pm" | ||
37 | - "aclk" | ||
38 | - "pclk" | ||
36 | - pinctrl-names : The pin control state names | 39 | - pinctrl-names : The pin control state names |
37 | - pinctrl-0: The "default" pinctrl state | 40 | - pinctrl-0: The "default" pinctrl state |
38 | - #interrupt-cells: specifies the number of cells needed to encode an | 41 | - #interrupt-cells: specifies the number of cells needed to encode an |
@@ -86,8 +89,10 @@ pcie0: pcie@f8000000 { | |||
86 | reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; | 89 | reg = <0x0 0xf8000000 0x0 0x2000000>, <0x0 0xfd000000 0x0 0x1000000>; |
87 | reg-names = "axi-base", "apb-base"; | 90 | reg-names = "axi-base", "apb-base"; |
88 | resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, | 91 | resets = <&cru SRST_PCIE_CORE>, <&cru SRST_PCIE_MGMT>, |
89 | <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE>; | 92 | <&cru SRST_PCIE_MGMT_STICKY>, <&cru SRST_PCIE_PIPE> , |
90 | reset-names = "core", "mgmt", "mgmt-sticky", "pipe"; | 93 | <&cru SRST_PCIE_PM>, <&cru SRST_P_PCIE>, <&cru SRST_A_PCIE>; |
94 | reset-names = "core", "mgmt", "mgmt-sticky", "pipe", | ||
95 | "pm", "pclk", "aclk"; | ||
91 | phys = <&pcie_phy>; | 96 | phys = <&pcie_phy>; |
92 | phy-names = "pcie-phy"; | 97 | phy-names = "pcie-phy"; |
93 | pinctrl-names = "default"; | 98 | pinctrl-names = "default"; |
diff --git a/MAINTAINERS b/MAINTAINERS index 5b608ac85641..2a7ea17c449a 100644 --- a/MAINTAINERS +++ b/MAINTAINERS | |||
@@ -9300,7 +9300,7 @@ S: Maintained | |||
9300 | F: drivers/pci/host/*designware* | 9300 | F: drivers/pci/host/*designware* |
9301 | 9301 | ||
9302 | PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE | 9302 | PCI DRIVER FOR SYNOPSYS PROTOTYPING DEVICE |
9303 | M: Joao Pinto <jpinto@synopsys.com> | 9303 | M: Jose Abreu <Jose.Abreu@synopsys.com> |
9304 | L: linux-pci@vger.kernel.org | 9304 | L: linux-pci@vger.kernel.org |
9305 | S: Maintained | 9305 | S: Maintained |
9306 | F: Documentation/devicetree/bindings/pci/designware-pcie.txt | 9306 | F: Documentation/devicetree/bindings/pci/designware-pcie.txt |
diff --git a/drivers/pci/host/Kconfig b/drivers/pci/host/Kconfig index 1fb55182ccaf..fa8f1f1a93e7 100644 --- a/drivers/pci/host/Kconfig +++ b/drivers/pci/host/Kconfig | |||
@@ -278,7 +278,7 @@ config PCIE_ARTPEC6 | |||
278 | 278 | ||
279 | config PCIE_ROCKCHIP | 279 | config PCIE_ROCKCHIP |
280 | bool "Rockchip PCIe controller" | 280 | bool "Rockchip PCIe controller" |
281 | depends on ARCH_ROCKCHIP | 281 | depends on ARCH_ROCKCHIP || COMPILE_TEST |
282 | depends on OF | 282 | depends on OF |
283 | depends on PCI_MSI_IRQ_DOMAIN | 283 | depends on PCI_MSI_IRQ_DOMAIN |
284 | select MFD_SYSCON | 284 | select MFD_SYSCON |
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c index ca48ceb6ebaf..ea789138531b 100644 --- a/drivers/pci/host/pci-layerscape.c +++ b/drivers/pci/host/pci-layerscape.c | |||
@@ -255,6 +255,7 @@ static int __init ls_pcie_probe(struct platform_device *pdev) | |||
255 | 255 | ||
256 | pp = &pcie->pp; | 256 | pp = &pcie->pp; |
257 | pp->dev = dev; | 257 | pp->dev = dev; |
258 | pcie->drvdata = match->data; | ||
258 | pp->ops = pcie->drvdata->ops; | 259 | pp->ops = pcie->drvdata->ops; |
259 | 260 | ||
260 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); | 261 | dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs"); |
@@ -262,7 +263,6 @@ static int __init ls_pcie_probe(struct platform_device *pdev) | |||
262 | if (IS_ERR(pcie->pp.dbi_base)) | 263 | if (IS_ERR(pcie->pp.dbi_base)) |
263 | return PTR_ERR(pcie->pp.dbi_base); | 264 | return PTR_ERR(pcie->pp.dbi_base); |
264 | 265 | ||
265 | pcie->drvdata = match->data; | ||
266 | pcie->lut = pcie->pp.dbi_base + pcie->drvdata->lut_offset; | 266 | pcie->lut = pcie->pp.dbi_base + pcie->drvdata->lut_offset; |
267 | 267 | ||
268 | if (!ls_pcie_is_bridge(pcie)) | 268 | if (!ls_pcie_is_bridge(pcie)) |
diff --git a/drivers/pci/host/pcie-designware-plat.c b/drivers/pci/host/pcie-designware-plat.c index 537f58a664fa..8df6312ed300 100644 --- a/drivers/pci/host/pcie-designware-plat.c +++ b/drivers/pci/host/pcie-designware-plat.c | |||
@@ -3,7 +3,7 @@ | |||
3 | * | 3 | * |
4 | * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) | 4 | * Copyright (C) 2015-2016 Synopsys, Inc. (www.synopsys.com) |
5 | * | 5 | * |
6 | * Authors: Joao Pinto <jpinto@synopsys.com> | 6 | * Authors: Joao Pinto <jpmpinto@gmail.com> |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or modify | 8 | * This program is free software; you can redistribute it and/or modify |
9 | * it under the terms of the GNU General Public License version 2 as | 9 | * it under the terms of the GNU General Public License version 2 as |
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c index 035f50c03281..bed19994c1e9 100644 --- a/drivers/pci/host/pcie-designware.c +++ b/drivers/pci/host/pcie-designware.c | |||
@@ -637,8 +637,6 @@ int dw_pcie_host_init(struct pcie_port *pp) | |||
637 | } | 637 | } |
638 | } | 638 | } |
639 | 639 | ||
640 | pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp); | ||
641 | |||
642 | if (pp->ops->host_init) | 640 | if (pp->ops->host_init) |
643 | pp->ops->host_init(pp); | 641 | pp->ops->host_init(pp); |
644 | 642 | ||
@@ -809,6 +807,11 @@ void dw_pcie_setup_rc(struct pcie_port *pp) | |||
809 | { | 807 | { |
810 | u32 val; | 808 | u32 val; |
811 | 809 | ||
810 | /* get iATU unroll support */ | ||
811 | pp->iatu_unroll_enabled = dw_pcie_iatu_unroll_enabled(pp); | ||
812 | dev_dbg(pp->dev, "iATU unroll: %s\n", | ||
813 | pp->iatu_unroll_enabled ? "enabled" : "disabled"); | ||
814 | |||
812 | /* set the number of lanes */ | 815 | /* set the number of lanes */ |
813 | val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL); | 816 | val = dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL); |
814 | val &= ~PORT_LINK_MODE_MASK; | 817 | val &= ~PORT_LINK_MODE_MASK; |
diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c index 8b02db2da6cc..734ba0d4a5c8 100644 --- a/drivers/pci/host/pcie-qcom.c +++ b/drivers/pci/host/pcie-qcom.c | |||
@@ -699,11 +699,11 @@ static int qcom_pcie_probe(struct platform_device *pdev) | |||
699 | if (IS_ERR(pcie->phy)) | 699 | if (IS_ERR(pcie->phy)) |
700 | return PTR_ERR(pcie->phy); | 700 | return PTR_ERR(pcie->phy); |
701 | 701 | ||
702 | pp->dev = dev; | ||
702 | ret = pcie->ops->get_resources(pcie); | 703 | ret = pcie->ops->get_resources(pcie); |
703 | if (ret) | 704 | if (ret) |
704 | return ret; | 705 | return ret; |
705 | 706 | ||
706 | pp->dev = dev; | ||
707 | pp->root_bus_nr = -1; | 707 | pp->root_bus_nr = -1; |
708 | pp->ops = &qcom_pcie_dw_ops; | 708 | pp->ops = &qcom_pcie_dw_ops; |
709 | 709 | ||
diff --git a/drivers/pci/host/pcie-rockchip.c b/drivers/pci/host/pcie-rockchip.c index 6419d8ca4a84..f2dca7bb0b39 100644 --- a/drivers/pci/host/pcie-rockchip.c +++ b/drivers/pci/host/pcie-rockchip.c | |||
@@ -53,6 +53,7 @@ | |||
53 | #define PCIE_CLIENT_ARI_ENABLE HIWORD_UPDATE_BIT(0x0008) | 53 | #define PCIE_CLIENT_ARI_ENABLE HIWORD_UPDATE_BIT(0x0008) |
54 | #define PCIE_CLIENT_CONF_LANE_NUM(x) HIWORD_UPDATE(0x0030, ENCODE_LANES(x)) | 54 | #define PCIE_CLIENT_CONF_LANE_NUM(x) HIWORD_UPDATE(0x0030, ENCODE_LANES(x)) |
55 | #define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040) | 55 | #define PCIE_CLIENT_MODE_RC HIWORD_UPDATE_BIT(0x0040) |
56 | #define PCIE_CLIENT_GEN_SEL_1 HIWORD_UPDATE(0x0080, 0) | ||
56 | #define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) | 57 | #define PCIE_CLIENT_GEN_SEL_2 HIWORD_UPDATE_BIT(0x0080) |
57 | #define PCIE_CLIENT_BASIC_STATUS1 (PCIE_CLIENT_BASE + 0x48) | 58 | #define PCIE_CLIENT_BASIC_STATUS1 (PCIE_CLIENT_BASE + 0x48) |
58 | #define PCIE_CLIENT_LINK_STATUS_UP 0x00300000 | 59 | #define PCIE_CLIENT_LINK_STATUS_UP 0x00300000 |
@@ -135,13 +136,14 @@ | |||
135 | #define PCIE_RC_CONFIG_VENDOR (PCIE_RC_CONFIG_BASE + 0x00) | 136 | #define PCIE_RC_CONFIG_VENDOR (PCIE_RC_CONFIG_BASE + 0x00) |
136 | #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) | 137 | #define PCIE_RC_CONFIG_RID_CCR (PCIE_RC_CONFIG_BASE + 0x08) |
137 | #define PCIE_RC_CONFIG_SCC_SHIFT 16 | 138 | #define PCIE_RC_CONFIG_SCC_SHIFT 16 |
139 | #define PCIE_RC_CONFIG_DCR (PCIE_RC_CONFIG_BASE + 0xc4) | ||
140 | #define PCIE_RC_CONFIG_DCR_CSPL_SHIFT 18 | ||
141 | #define PCIE_RC_CONFIG_DCR_CSPL_LIMIT 0xff | ||
142 | #define PCIE_RC_CONFIG_DCR_CPLS_SHIFT 26 | ||
138 | #define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) | 143 | #define PCIE_RC_CONFIG_LCS (PCIE_RC_CONFIG_BASE + 0xd0) |
139 | #define PCIE_RC_CONFIG_LCS_RETRAIN_LINK BIT(5) | ||
140 | #define PCIE_RC_CONFIG_LCS_LBMIE BIT(10) | ||
141 | #define PCIE_RC_CONFIG_LCS_LABIE BIT(11) | ||
142 | #define PCIE_RC_CONFIG_LCS_LBMS BIT(30) | ||
143 | #define PCIE_RC_CONFIG_LCS_LAMS BIT(31) | ||
144 | #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c) | 144 | #define PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 (PCIE_RC_CONFIG_BASE + 0x90c) |
145 | #define PCIE_RC_CONFIG_THP_CAP (PCIE_RC_CONFIG_BASE + 0x274) | ||
146 | #define PCIE_RC_CONFIG_THP_CAP_NEXT_MASK GENMASK(31, 20) | ||
145 | 147 | ||
146 | #define PCIE_CORE_AXI_CONF_BASE 0xc00000 | 148 | #define PCIE_CORE_AXI_CONF_BASE 0xc00000 |
147 | #define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0) | 149 | #define PCIE_CORE_OB_REGION_ADDR0 (PCIE_CORE_AXI_CONF_BASE + 0x0) |
@@ -190,6 +192,9 @@ struct rockchip_pcie { | |||
190 | struct reset_control *mgmt_rst; | 192 | struct reset_control *mgmt_rst; |
191 | struct reset_control *mgmt_sticky_rst; | 193 | struct reset_control *mgmt_sticky_rst; |
192 | struct reset_control *pipe_rst; | 194 | struct reset_control *pipe_rst; |
195 | struct reset_control *pm_rst; | ||
196 | struct reset_control *aclk_rst; | ||
197 | struct reset_control *pclk_rst; | ||
193 | struct clk *aclk_pcie; | 198 | struct clk *aclk_pcie; |
194 | struct clk *aclk_perf_pcie; | 199 | struct clk *aclk_perf_pcie; |
195 | struct clk *hclk_pcie; | 200 | struct clk *hclk_pcie; |
@@ -200,8 +205,14 @@ struct rockchip_pcie { | |||
200 | struct gpio_desc *ep_gpio; | 205 | struct gpio_desc *ep_gpio; |
201 | u32 lanes; | 206 | u32 lanes; |
202 | u8 root_bus_nr; | 207 | u8 root_bus_nr; |
208 | int link_gen; | ||
203 | struct device *dev; | 209 | struct device *dev; |
204 | struct irq_domain *irq_domain; | 210 | struct irq_domain *irq_domain; |
211 | u32 io_size; | ||
212 | int offset; | ||
213 | phys_addr_t io_bus_addr; | ||
214 | u32 mem_size; | ||
215 | phys_addr_t mem_bus_addr; | ||
205 | }; | 216 | }; |
206 | 217 | ||
207 | static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) | 218 | static u32 rockchip_pcie_read(struct rockchip_pcie *rockchip, u32 reg) |
@@ -220,7 +231,7 @@ static void rockchip_pcie_enable_bw_int(struct rockchip_pcie *rockchip) | |||
220 | u32 status; | 231 | u32 status; |
221 | 232 | ||
222 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); | 233 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); |
223 | status |= (PCIE_RC_CONFIG_LCS_LBMIE | PCIE_RC_CONFIG_LCS_LABIE); | 234 | status |= (PCI_EXP_LNKCTL_LBMIE | PCI_EXP_LNKCTL_LABIE); |
224 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | 235 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); |
225 | } | 236 | } |
226 | 237 | ||
@@ -229,7 +240,7 @@ static void rockchip_pcie_clr_bw_int(struct rockchip_pcie *rockchip) | |||
229 | u32 status; | 240 | u32 status; |
230 | 241 | ||
231 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); | 242 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); |
232 | status |= (PCIE_RC_CONFIG_LCS_LBMS | PCIE_RC_CONFIG_LCS_LAMS); | 243 | status |= (PCI_EXP_LNKSTA_LBMS | PCI_EXP_LNKSTA_LABS) << 16; |
233 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | 244 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); |
234 | } | 245 | } |
235 | 246 | ||
@@ -395,6 +406,40 @@ static struct pci_ops rockchip_pcie_ops = { | |||
395 | .write = rockchip_pcie_wr_conf, | 406 | .write = rockchip_pcie_wr_conf, |
396 | }; | 407 | }; |
397 | 408 | ||
409 | static void rockchip_pcie_set_power_limit(struct rockchip_pcie *rockchip) | ||
410 | { | ||
411 | u32 status, curr, scale, power; | ||
412 | |||
413 | if (IS_ERR(rockchip->vpcie3v3)) | ||
414 | return; | ||
415 | |||
416 | /* | ||
417 | * Set RC's captured slot power limit and scale if | ||
418 | * vpcie3v3 available. The default values are both zero | ||
419 | * which means the software should set these two according | ||
420 | * to the actual power supply. | ||
421 | */ | ||
422 | curr = regulator_get_current_limit(rockchip->vpcie3v3); | ||
423 | if (curr > 0) { | ||
424 | scale = 3; /* 0.001x */ | ||
425 | curr = curr / 1000; /* convert to mA */ | ||
426 | power = (curr * 3300) / 1000; /* milliwatt */ | ||
427 | while (power > PCIE_RC_CONFIG_DCR_CSPL_LIMIT) { | ||
428 | if (!scale) { | ||
429 | dev_warn(rockchip->dev, "invalid power supply\n"); | ||
430 | return; | ||
431 | } | ||
432 | scale--; | ||
433 | power = power / 10; | ||
434 | } | ||
435 | |||
436 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_DCR); | ||
437 | status |= (power << PCIE_RC_CONFIG_DCR_CSPL_SHIFT) | | ||
438 | (scale << PCIE_RC_CONFIG_DCR_CPLS_SHIFT); | ||
439 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_DCR); | ||
440 | } | ||
441 | } | ||
442 | |||
398 | /** | 443 | /** |
399 | * rockchip_pcie_init_port - Initialize hardware | 444 | * rockchip_pcie_init_port - Initialize hardware |
400 | * @rockchip: PCIe port information | 445 | * @rockchip: PCIe port information |
@@ -408,6 +453,24 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
408 | 453 | ||
409 | gpiod_set_value(rockchip->ep_gpio, 0); | 454 | gpiod_set_value(rockchip->ep_gpio, 0); |
410 | 455 | ||
456 | err = reset_control_assert(rockchip->aclk_rst); | ||
457 | if (err) { | ||
458 | dev_err(dev, "assert aclk_rst err %d\n", err); | ||
459 | return err; | ||
460 | } | ||
461 | |||
462 | err = reset_control_assert(rockchip->pclk_rst); | ||
463 | if (err) { | ||
464 | dev_err(dev, "assert pclk_rst err %d\n", err); | ||
465 | return err; | ||
466 | } | ||
467 | |||
468 | err = reset_control_assert(rockchip->pm_rst); | ||
469 | if (err) { | ||
470 | dev_err(dev, "assert pm_rst err %d\n", err); | ||
471 | return err; | ||
472 | } | ||
473 | |||
411 | err = phy_init(rockchip->phy); | 474 | err = phy_init(rockchip->phy); |
412 | if (err < 0) { | 475 | if (err < 0) { |
413 | dev_err(dev, "fail to init phy, err %d\n", err); | 476 | dev_err(dev, "fail to init phy, err %d\n", err); |
@@ -438,14 +501,40 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
438 | return err; | 501 | return err; |
439 | } | 502 | } |
440 | 503 | ||
504 | udelay(10); | ||
505 | |||
506 | err = reset_control_deassert(rockchip->pm_rst); | ||
507 | if (err) { | ||
508 | dev_err(dev, "deassert pm_rst err %d\n", err); | ||
509 | return err; | ||
510 | } | ||
511 | |||
512 | err = reset_control_deassert(rockchip->aclk_rst); | ||
513 | if (err) { | ||
514 | dev_err(dev, "deassert aclk_rst err %d\n", err); | ||
515 | return err; | ||
516 | } | ||
517 | |||
518 | err = reset_control_deassert(rockchip->pclk_rst); | ||
519 | if (err) { | ||
520 | dev_err(dev, "deassert pclk_rst err %d\n", err); | ||
521 | return err; | ||
522 | } | ||
523 | |||
524 | if (rockchip->link_gen == 2) | ||
525 | rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2, | ||
526 | PCIE_CLIENT_CONFIG); | ||
527 | else | ||
528 | rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1, | ||
529 | PCIE_CLIENT_CONFIG); | ||
530 | |||
441 | rockchip_pcie_write(rockchip, | 531 | rockchip_pcie_write(rockchip, |
442 | PCIE_CLIENT_CONF_ENABLE | | 532 | PCIE_CLIENT_CONF_ENABLE | |
443 | PCIE_CLIENT_LINK_TRAIN_ENABLE | | 533 | PCIE_CLIENT_LINK_TRAIN_ENABLE | |
444 | PCIE_CLIENT_ARI_ENABLE | | 534 | PCIE_CLIENT_ARI_ENABLE | |
445 | PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes) | | 535 | PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes) | |
446 | PCIE_CLIENT_MODE_RC | | 536 | PCIE_CLIENT_MODE_RC, |
447 | PCIE_CLIENT_GEN_SEL_2, | 537 | PCIE_CLIENT_CONFIG); |
448 | PCIE_CLIENT_CONFIG); | ||
449 | 538 | ||
450 | err = phy_power_on(rockchip->phy); | 539 | err = phy_power_on(rockchip->phy); |
451 | if (err) { | 540 | if (err) { |
@@ -481,21 +570,19 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
481 | return err; | 570 | return err; |
482 | } | 571 | } |
483 | 572 | ||
484 | /* | ||
485 | * We need to read/write PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2 before | ||
486 | * enabling ASPM. Otherwise L1PwrOnSc and L1PwrOnVal isn't | ||
487 | * reliable and enabling ASPM doesn't work. This is a controller | ||
488 | * bug we need to work around. | ||
489 | */ | ||
490 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2); | ||
491 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_L1_SUBSTATE_CTRL2); | ||
492 | |||
493 | /* Fix the transmitted FTS count desired to exit from L0s. */ | 573 | /* Fix the transmitted FTS count desired to exit from L0s. */ |
494 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL_PLC1); | 574 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL_PLC1); |
495 | status = (status & PCIE_CORE_CTRL_PLC1_FTS_MASK) | | 575 | status = (status & ~PCIE_CORE_CTRL_PLC1_FTS_MASK) | |
496 | (PCIE_CORE_CTRL_PLC1_FTS_CNT << PCIE_CORE_CTRL_PLC1_FTS_SHIFT); | 576 | (PCIE_CORE_CTRL_PLC1_FTS_CNT << PCIE_CORE_CTRL_PLC1_FTS_SHIFT); |
497 | rockchip_pcie_write(rockchip, status, PCIE_CORE_CTRL_PLC1); | 577 | rockchip_pcie_write(rockchip, status, PCIE_CORE_CTRL_PLC1); |
498 | 578 | ||
579 | rockchip_pcie_set_power_limit(rockchip); | ||
580 | |||
581 | /* Set RC's clock architecture as common clock */ | ||
582 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); | ||
583 | status |= PCI_EXP_LNKCTL_CCC; | ||
584 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | ||
585 | |||
499 | /* Enable Gen1 training */ | 586 | /* Enable Gen1 training */ |
500 | rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, | 587 | rockchip_pcie_write(rockchip, PCIE_CLIENT_LINK_TRAIN_ENABLE, |
501 | PCIE_CLIENT_CONFIG); | 588 | PCIE_CLIENT_CONFIG); |
@@ -522,35 +609,37 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
522 | msleep(20); | 609 | msleep(20); |
523 | } | 610 | } |
524 | 611 | ||
525 | /* | 612 | if (rockchip->link_gen == 2) { |
526 | * Enable retrain for gen2. This should be configured only after | 613 | /* |
527 | * gen1 finished. | 614 | * Enable retrain for gen2. This should be configured only after |
528 | */ | 615 | * gen1 finished. |
529 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); | 616 | */ |
530 | status |= PCIE_RC_CONFIG_LCS_RETRAIN_LINK; | 617 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_LCS); |
531 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | 618 | status |= PCI_EXP_LNKCTL_RL; |
619 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_LCS); | ||
620 | |||
621 | timeout = jiffies + msecs_to_jiffies(500); | ||
622 | for (;;) { | ||
623 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); | ||
624 | if ((status & PCIE_CORE_PL_CONF_SPEED_MASK) == | ||
625 | PCIE_CORE_PL_CONF_SPEED_5G) { | ||
626 | dev_dbg(dev, "PCIe link training gen2 pass!\n"); | ||
627 | break; | ||
628 | } | ||
532 | 629 | ||
533 | timeout = jiffies + msecs_to_jiffies(500); | 630 | if (time_after(jiffies, timeout)) { |
534 | for (;;) { | 631 | dev_dbg(dev, "PCIe link training gen2 timeout, fall back to gen1!\n"); |
535 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); | 632 | break; |
536 | if ((status & PCIE_CORE_PL_CONF_SPEED_MASK) == | 633 | } |
537 | PCIE_CORE_PL_CONF_SPEED_5G) { | ||
538 | dev_dbg(dev, "PCIe link training gen2 pass!\n"); | ||
539 | break; | ||
540 | } | ||
541 | 634 | ||
542 | if (time_after(jiffies, timeout)) { | 635 | msleep(20); |
543 | dev_dbg(dev, "PCIe link training gen2 timeout, fall back to gen1!\n"); | ||
544 | break; | ||
545 | } | 636 | } |
546 | |||
547 | msleep(20); | ||
548 | } | 637 | } |
549 | 638 | ||
550 | /* Check the final link width from negotiated lane counter from MGMT */ | 639 | /* Check the final link width from negotiated lane counter from MGMT */ |
551 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); | 640 | status = rockchip_pcie_read(rockchip, PCIE_CORE_CTRL); |
552 | status = 0x1 << ((status & PCIE_CORE_PL_CONF_LANE_MASK) >> | 641 | status = 0x1 << ((status & PCIE_CORE_PL_CONF_LANE_MASK) >> |
553 | PCIE_CORE_PL_CONF_LANE_MASK); | 642 | PCIE_CORE_PL_CONF_LANE_SHIFT); |
554 | dev_dbg(dev, "current link width is x%d\n", status); | 643 | dev_dbg(dev, "current link width is x%d\n", status); |
555 | 644 | ||
556 | rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID, | 645 | rockchip_pcie_write(rockchip, ROCKCHIP_VENDOR_ID, |
@@ -558,6 +647,12 @@ static int rockchip_pcie_init_port(struct rockchip_pcie *rockchip) | |||
558 | rockchip_pcie_write(rockchip, | 647 | rockchip_pcie_write(rockchip, |
559 | PCI_CLASS_BRIDGE_PCI << PCIE_RC_CONFIG_SCC_SHIFT, | 648 | PCI_CLASS_BRIDGE_PCI << PCIE_RC_CONFIG_SCC_SHIFT, |
560 | PCIE_RC_CONFIG_RID_CCR); | 649 | PCIE_RC_CONFIG_RID_CCR); |
650 | |||
651 | /* Clear THP cap's next cap pointer to remove L1 substate cap */ | ||
652 | status = rockchip_pcie_read(rockchip, PCIE_RC_CONFIG_THP_CAP); | ||
653 | status &= ~PCIE_RC_CONFIG_THP_CAP_NEXT_MASK; | ||
654 | rockchip_pcie_write(rockchip, status, PCIE_RC_CONFIG_THP_CAP); | ||
655 | |||
561 | rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); | 656 | rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF); |
562 | 657 | ||
563 | rockchip_pcie_write(rockchip, | 658 | rockchip_pcie_write(rockchip, |
@@ -753,6 +848,10 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) | |||
753 | rockchip->lanes = 1; | 848 | rockchip->lanes = 1; |
754 | } | 849 | } |
755 | 850 | ||
851 | rockchip->link_gen = of_pci_get_max_link_speed(node); | ||
852 | if (rockchip->link_gen < 0 || rockchip->link_gen > 2) | ||
853 | rockchip->link_gen = 2; | ||
854 | |||
756 | rockchip->core_rst = devm_reset_control_get(dev, "core"); | 855 | rockchip->core_rst = devm_reset_control_get(dev, "core"); |
757 | if (IS_ERR(rockchip->core_rst)) { | 856 | if (IS_ERR(rockchip->core_rst)) { |
758 | if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER) | 857 | if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER) |
@@ -781,6 +880,27 @@ static int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip) | |||
781 | return PTR_ERR(rockchip->pipe_rst); | 880 | return PTR_ERR(rockchip->pipe_rst); |
782 | } | 881 | } |
783 | 882 | ||
883 | rockchip->pm_rst = devm_reset_control_get(dev, "pm"); | ||
884 | if (IS_ERR(rockchip->pm_rst)) { | ||
885 | if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER) | ||
886 | dev_err(dev, "missing pm reset property in node\n"); | ||
887 | return PTR_ERR(rockchip->pm_rst); | ||
888 | } | ||
889 | |||
890 | rockchip->pclk_rst = devm_reset_control_get(dev, "pclk"); | ||
891 | if (IS_ERR(rockchip->pclk_rst)) { | ||
892 | if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER) | ||
893 | dev_err(dev, "missing pclk reset property in node\n"); | ||
894 | return PTR_ERR(rockchip->pclk_rst); | ||
895 | } | ||
896 | |||
897 | rockchip->aclk_rst = devm_reset_control_get(dev, "aclk"); | ||
898 | if (IS_ERR(rockchip->aclk_rst)) { | ||
899 | if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER) | ||
900 | dev_err(dev, "missing aclk reset property in node\n"); | ||
901 | return PTR_ERR(rockchip->aclk_rst); | ||
902 | } | ||
903 | |||
784 | rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH); | 904 | rockchip->ep_gpio = devm_gpiod_get(dev, "ep", GPIOD_OUT_HIGH); |
785 | if (IS_ERR(rockchip->ep_gpio)) { | 905 | if (IS_ERR(rockchip->ep_gpio)) { |
786 | dev_err(dev, "missing ep-gpios property in node\n"); | 906 | dev_err(dev, "missing ep-gpios property in node\n"); |
@@ -1025,6 +1145,50 @@ static int rockchip_pcie_prog_ib_atu(struct rockchip_pcie *rockchip, | |||
1025 | return 0; | 1145 | return 0; |
1026 | } | 1146 | } |
1027 | 1147 | ||
1148 | static int rockchip_cfg_atu(struct rockchip_pcie *rockchip) | ||
1149 | { | ||
1150 | struct device *dev = rockchip->dev; | ||
1151 | int offset; | ||
1152 | int err; | ||
1153 | int reg_no; | ||
1154 | |||
1155 | for (reg_no = 0; reg_no < (rockchip->mem_size >> 20); reg_no++) { | ||
1156 | err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1, | ||
1157 | AXI_WRAPPER_MEM_WRITE, | ||
1158 | 20 - 1, | ||
1159 | rockchip->mem_bus_addr + | ||
1160 | (reg_no << 20), | ||
1161 | 0); | ||
1162 | if (err) { | ||
1163 | dev_err(dev, "program RC mem outbound ATU failed\n"); | ||
1164 | return err; | ||
1165 | } | ||
1166 | } | ||
1167 | |||
1168 | err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0); | ||
1169 | if (err) { | ||
1170 | dev_err(dev, "program RC mem inbound ATU failed\n"); | ||
1171 | return err; | ||
1172 | } | ||
1173 | |||
1174 | offset = rockchip->mem_size >> 20; | ||
1175 | for (reg_no = 0; reg_no < (rockchip->io_size >> 20); reg_no++) { | ||
1176 | err = rockchip_pcie_prog_ob_atu(rockchip, | ||
1177 | reg_no + 1 + offset, | ||
1178 | AXI_WRAPPER_IO_WRITE, | ||
1179 | 20 - 1, | ||
1180 | rockchip->io_bus_addr + | ||
1181 | (reg_no << 20), | ||
1182 | 0); | ||
1183 | if (err) { | ||
1184 | dev_err(dev, "program RC io outbound ATU failed\n"); | ||
1185 | return err; | ||
1186 | } | ||
1187 | } | ||
1188 | |||
1189 | return 0; | ||
1190 | } | ||
1191 | |||
1028 | static int rockchip_pcie_probe(struct platform_device *pdev) | 1192 | static int rockchip_pcie_probe(struct platform_device *pdev) |
1029 | { | 1193 | { |
1030 | struct rockchip_pcie *rockchip; | 1194 | struct rockchip_pcie *rockchip; |
@@ -1034,13 +1198,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1034 | resource_size_t io_base; | 1198 | resource_size_t io_base; |
1035 | struct resource *mem; | 1199 | struct resource *mem; |
1036 | struct resource *io; | 1200 | struct resource *io; |
1037 | phys_addr_t io_bus_addr = 0; | ||
1038 | u32 io_size; | ||
1039 | phys_addr_t mem_bus_addr = 0; | ||
1040 | u32 mem_size = 0; | ||
1041 | int reg_no; | ||
1042 | int err; | 1201 | int err; |
1043 | int offset; | ||
1044 | 1202 | ||
1045 | LIST_HEAD(res); | 1203 | LIST_HEAD(res); |
1046 | 1204 | ||
@@ -1107,14 +1265,13 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1107 | goto err_vpcie; | 1265 | goto err_vpcie; |
1108 | 1266 | ||
1109 | /* Get the I/O and memory ranges from DT */ | 1267 | /* Get the I/O and memory ranges from DT */ |
1110 | io_size = 0; | ||
1111 | resource_list_for_each_entry(win, &res) { | 1268 | resource_list_for_each_entry(win, &res) { |
1112 | switch (resource_type(win->res)) { | 1269 | switch (resource_type(win->res)) { |
1113 | case IORESOURCE_IO: | 1270 | case IORESOURCE_IO: |
1114 | io = win->res; | 1271 | io = win->res; |
1115 | io->name = "I/O"; | 1272 | io->name = "I/O"; |
1116 | io_size = resource_size(io); | 1273 | rockchip->io_size = resource_size(io); |
1117 | io_bus_addr = io->start - win->offset; | 1274 | rockchip->io_bus_addr = io->start - win->offset; |
1118 | err = pci_remap_iospace(io, io_base); | 1275 | err = pci_remap_iospace(io, io_base); |
1119 | if (err) { | 1276 | if (err) { |
1120 | dev_warn(dev, "error %d: failed to map resource %pR\n", | 1277 | dev_warn(dev, "error %d: failed to map resource %pR\n", |
@@ -1125,8 +1282,8 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1125 | case IORESOURCE_MEM: | 1282 | case IORESOURCE_MEM: |
1126 | mem = win->res; | 1283 | mem = win->res; |
1127 | mem->name = "MEM"; | 1284 | mem->name = "MEM"; |
1128 | mem_size = resource_size(mem); | 1285 | rockchip->mem_size = resource_size(mem); |
1129 | mem_bus_addr = mem->start - win->offset; | 1286 | rockchip->mem_bus_addr = mem->start - win->offset; |
1130 | break; | 1287 | break; |
1131 | case IORESOURCE_BUS: | 1288 | case IORESOURCE_BUS: |
1132 | rockchip->root_bus_nr = win->res->start; | 1289 | rockchip->root_bus_nr = win->res->start; |
@@ -1136,45 +1293,9 @@ static int rockchip_pcie_probe(struct platform_device *pdev) | |||
1136 | } | 1293 | } |
1137 | } | 1294 | } |
1138 | 1295 | ||
1139 | if (mem_size) { | 1296 | err = rockchip_cfg_atu(rockchip); |
1140 | for (reg_no = 0; reg_no < (mem_size >> 20); reg_no++) { | 1297 | if (err) |
1141 | err = rockchip_pcie_prog_ob_atu(rockchip, reg_no + 1, | ||
1142 | AXI_WRAPPER_MEM_WRITE, | ||
1143 | 20 - 1, | ||
1144 | mem_bus_addr + | ||
1145 | (reg_no << 20), | ||
1146 | 0); | ||
1147 | if (err) { | ||
1148 | dev_err(dev, "program RC mem outbound ATU failed\n"); | ||
1149 | goto err_vpcie; | ||
1150 | } | ||
1151 | } | ||
1152 | } | ||
1153 | |||
1154 | err = rockchip_pcie_prog_ib_atu(rockchip, 2, 32 - 1, 0x0, 0); | ||
1155 | if (err) { | ||
1156 | dev_err(dev, "program RC mem inbound ATU failed\n"); | ||
1157 | goto err_vpcie; | 1298 | goto err_vpcie; |
1158 | } | ||
1159 | |||
1160 | offset = mem_size >> 20; | ||
1161 | |||
1162 | if (io_size) { | ||
1163 | for (reg_no = 0; reg_no < (io_size >> 20); reg_no++) { | ||
1164 | err = rockchip_pcie_prog_ob_atu(rockchip, | ||
1165 | reg_no + 1 + offset, | ||
1166 | AXI_WRAPPER_IO_WRITE, | ||
1167 | 20 - 1, | ||
1168 | io_bus_addr + | ||
1169 | (reg_no << 20), | ||
1170 | 0); | ||
1171 | if (err) { | ||
1172 | dev_err(dev, "program RC io outbound ATU failed\n"); | ||
1173 | goto err_vpcie; | ||
1174 | } | ||
1175 | } | ||
1176 | } | ||
1177 | |||
1178 | bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res); | 1299 | bus = pci_scan_root_bus(&pdev->dev, 0, &rockchip_pcie_ops, rockchip, &res); |
1179 | if (!bus) { | 1300 | if (!bus) { |
1180 | err = -ENOMEM; | 1301 | err = -ENOMEM; |
diff --git a/drivers/pci/setup-res.c b/drivers/pci/setup-res.c index 045427336e11..4bc589ee78d0 100644 --- a/drivers/pci/setup-res.c +++ b/drivers/pci/setup-res.c | |||
@@ -141,6 +141,14 @@ int pci_claim_resource(struct pci_dev *dev, int resource) | |||
141 | return -EINVAL; | 141 | return -EINVAL; |
142 | } | 142 | } |
143 | 143 | ||
144 | /* | ||
145 | * If we have a shadow copy in RAM, the PCI device doesn't respond | ||
146 | * to the shadow range, so we don't need to claim it, and upstream | ||
147 | * bridges don't need to route the range to the device. | ||
148 | */ | ||
149 | if (res->flags & IORESOURCE_ROM_SHADOW) | ||
150 | return 0; | ||
151 | |||
144 | root = pci_find_parent_resource(dev, res); | 152 | root = pci_find_parent_resource(dev, res); |
145 | if (!root) { | 153 | if (!root) { |
146 | dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", | 154 | dev_info(&dev->dev, "can't claim BAR %d %pR: no compatible bridge window\n", |