Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

PCI: exynos: Remove deprecated PHY initialization code

Exynos platforms have a PCI PHY driver in the PHY framework that can be
used by the PCI host bridge drivers to initialize and manage the PHY.

Remove the deprecated PHY initialization code in the Exynos PCI host
bridge driver by updating the driver to use the PHY framework API;
modify the DT binding documentation accordingly.

Signed-off-by: Jaehoon Chung <jh80.chung@samsung.com>
[lorenzo.pieralisi@arm.com: updated commit log]
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Acked-by: Jingoo Han <jingoohan1@gmail.com>
Reviewed-by: Rob Herring <robh@kernel.org>

authored by

Jaehoon Chung and committed by
Lorenzo Pieralisi
83f4f3f6 dc734ee0

+21 -254
+11 -47
Documentation/devicetree/bindings/pci/samsung,exynos5440-pcie.txt
··· 6 6 Required properties: 7 7 - compatible: "samsung,exynos5440-pcie" 8 8 - reg: base addresses and lengths of the PCIe controller, 9 - the PHY controller, additional register for the PHY controller. 10 - (Registers for the PHY controller are DEPRECATED. 11 - Use the PHY framework.) 12 9 - reg-names : First name should be set to "elbi". 13 10 And use the "config" instead of getting the configuration address space 14 11 from "ranges". ··· 20 23 21 24 Example: 22 25 23 - SoC-specific DT Entry: 26 + SoC-specific DT Entry (with using PHY framework): 24 27 25 - pcie@290000 { 26 - compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; 27 - reg = <0x290000 0x1000 28 - 0x270000 0x1000 29 - 0x271000 0x40>; 30 - interrupts = <0 20 0>, <0 21 0>, <0 22 0>; 31 - clocks = <&clock 28>, <&clock 27>; 32 - clock-names = "pcie", "pcie_bus"; 33 - #address-cells = <3>; 34 - #size-cells = <2>; 35 - device_type = "pci"; 36 - ranges = <0x00000800 0 0x40000000 0x40000000 0 0x00001000 /* configuration space */ 37 - 0x81000000 0 0 0x40001000 0 0x00010000 /* downstream I/O */ 38 - 0x82000000 0 0x40011000 0x40011000 0 0x1ffef000>; /* non-prefetchable memory */ 39 - #interrupt-cells = <1>; 40 - interrupt-map-mask = <0 0 0 0>; 41 - interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; 42 - num-lanes = <4>; 43 - }; 44 - 45 - pcie@2a0000 { 46 - compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; 47 - reg = <0x2a0000 0x1000 48 - 0x272000 0x1000 49 - 0x271040 0x40>; 50 - interrupts = <0 23 0>, <0 24 0>, <0 25 0>; 51 - clocks = <&clock 29>, <&clock 27>; 52 - clock-names = "pcie", "pcie_bus"; 53 - #address-cells = <3>; 54 - #size-cells = <2>; 55 - device_type = "pci"; 56 - ranges = <0x00000800 0 0x60000000 0x60000000 0 0x00001000 /* configuration space */ 57 - 0x81000000 0 0 0x60001000 0 0x00010000 /* downstream I/O */ 58 - 0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; /* non-prefetchable memory */ 59 - #interrupt-cells = <1>; 60 - interrupt-map-mask = <0 0 0 0>; 61 - interrupt-map = <0 0 0 0 &gic GIC_SPI 24 IRQ_TYPE_LEVEL_HIGH>; 62 - num-lanes = <4>; 63 - }; 64 - 65 - With using PHY framework: 66 28 pcie_phy0: pcie-phy@270000 { 67 29 ... 68 30 reg = <0x270000 0x1000>, <0x271000 0x40>; ··· 30 74 }; 31 75 32 76 pcie@290000 { 33 - ... 77 + compatible = "samsung,exynos5440-pcie", "snps,dw-pcie"; 34 78 reg = <0x290000 0x1000>, <0x40000000 0x1000>; 35 79 reg-names = "elbi", "config"; 80 + clocks = <&clock 28>, <&clock 27>; 81 + clock-names = "pcie", "pcie_bus"; 82 + #address-cells = <3>; 83 + #size-cells = <2>; 84 + device_type = "pci"; 36 85 phys = <&pcie_phy0>; 37 86 ranges = <0x81000000 0 0 0x60001000 0 0x00010000 38 87 0x82000000 0 0x60011000 0x60011000 0 0x1ffef000>; 39 - ... 88 + #interrupt-cells = <1>; 89 + interrupt-map-mask = <0 0 0 0>; 90 + interrupt-map = <0 0 0 0 &gic GIC_SPI 21 IRQ_TYPE_LEVEL_HIGH>; 91 + num-lanes = <4>; 40 92 }; 41 93 42 94 Board-specific DT Entry:
+10 -207
drivers/pci/dwc/pci-exynos.c
··· 55 55 #define PCIE_ELBI_SLV_ARMISC 0x120 56 56 #define PCIE_ELBI_SLV_DBI_ENABLE BIT(21) 57 57 58 - /* PCIe Purple registers */ 59 - #define PCIE_PHY_GLOBAL_RESET 0x000 60 - #define PCIE_PHY_COMMON_RESET 0x004 61 - #define PCIE_PHY_CMN_REG 0x008 62 - #define PCIE_PHY_MAC_RESET 0x00c 63 - #define PCIE_PHY_PLL_LOCKED 0x010 64 - #define PCIE_PHY_TRSVREG_RESET 0x020 65 - #define PCIE_PHY_TRSV_RESET 0x024 66 - 67 - /* PCIe PHY registers */ 68 - #define PCIE_PHY_IMPEDANCE 0x004 69 - #define PCIE_PHY_PLL_DIV_0 0x008 70 - #define PCIE_PHY_PLL_BIAS 0x00c 71 - #define PCIE_PHY_DCC_FEEDBACK 0x014 72 - #define PCIE_PHY_PLL_DIV_1 0x05c 73 - #define PCIE_PHY_COMMON_POWER 0x064 74 - #define PCIE_PHY_COMMON_PD_CMN BIT(3) 75 - #define PCIE_PHY_TRSV0_EMP_LVL 0x084 76 - #define PCIE_PHY_TRSV0_DRV_LVL 0x088 77 - #define PCIE_PHY_TRSV0_RXCDR 0x0ac 78 - #define PCIE_PHY_TRSV0_POWER 0x0c4 79 - #define PCIE_PHY_TRSV0_PD_TSV BIT(7) 80 - #define PCIE_PHY_TRSV0_LVCC 0x0dc 81 - #define PCIE_PHY_TRSV1_EMP_LVL 0x144 82 - #define PCIE_PHY_TRSV1_RXCDR 0x16c 83 - #define PCIE_PHY_TRSV1_POWER 0x184 84 - #define PCIE_PHY_TRSV1_PD_TSV BIT(7) 85 - #define PCIE_PHY_TRSV1_LVCC 0x19c 86 - #define PCIE_PHY_TRSV2_EMP_LVL 0x204 87 - #define PCIE_PHY_TRSV2_RXCDR 0x22c 88 - #define PCIE_PHY_TRSV2_POWER 0x244 89 - #define PCIE_PHY_TRSV2_PD_TSV BIT(7) 90 - #define PCIE_PHY_TRSV2_LVCC 0x25c 91 - #define PCIE_PHY_TRSV3_EMP_LVL 0x2c4 92 - #define PCIE_PHY_TRSV3_RXCDR 0x2ec 93 - #define PCIE_PHY_TRSV3_POWER 0x304 94 - #define PCIE_PHY_TRSV3_PD_TSV BIT(7) 95 - #define PCIE_PHY_TRSV3_LVCC 0x31c 96 - 97 58 struct exynos_pcie_mem_res { 98 59 void __iomem *elbi_base; /* DT 0th resource: PCIe CTRL */ 99 - void __iomem *phy_base; /* DT 1st resource: PHY CTRL */ 100 - void __iomem *block_base; /* DT 2nd resource: PHY ADDITIONAL CTRL */ 101 60 }; 102 61 103 62 struct exynos_pcie_clk_res { ··· 71 112 const struct exynos_pcie_ops *ops; 72 113 int reset_gpio; 73 114 74 - /* For Generic PHY Framework */ 75 - bool using_phy; 76 115 struct phy *phy; 77 116 }; 78 117 ··· 97 140 ep->mem_res->elbi_base = devm_ioremap_resource(dev, res); 98 141 if (IS_ERR(ep->mem_res->elbi_base)) 99 142 return PTR_ERR(ep->mem_res->elbi_base); 100 - 101 - /* If using the PHY framework, doesn't need to get other resource */ 102 - if (ep->using_phy) 103 - return 0; 104 - 105 - res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 106 - ep->mem_res->phy_base = devm_ioremap_resource(dev, res); 107 - if (IS_ERR(ep->mem_res->phy_base)) 108 - return PTR_ERR(ep->mem_res->phy_base); 109 - 110 - res = platform_get_resource(pdev, IORESOURCE_MEM, 2); 111 - ep->mem_res->block_base = devm_ioremap_resource(dev, res); 112 - if (IS_ERR(ep->mem_res->block_base)) 113 - return PTR_ERR(ep->mem_res->block_base); 114 143 115 144 return 0; 116 145 } ··· 222 279 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_NONSTICKY_RESET); 223 280 exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_APP_INIT_RESET); 224 281 exynos_pcie_writel(ep->mem_res->elbi_base, 0, PCIE_APP_INIT_RESET); 225 - exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_MAC_RESET); 226 - } 227 - 228 - static void exynos_pcie_assert_phy_reset(struct exynos_pcie *ep) 229 - { 230 - exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_MAC_RESET); 231 - exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_GLOBAL_RESET); 232 - } 233 - 234 - static void exynos_pcie_deassert_phy_reset(struct exynos_pcie *ep) 235 - { 236 - exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_GLOBAL_RESET); 237 - exynos_pcie_writel(ep->mem_res->elbi_base, 1, PCIE_PWR_RESET); 238 - exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_COMMON_RESET); 239 - exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_CMN_REG); 240 - exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_TRSVREG_RESET); 241 - exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_TRSV_RESET); 242 - } 243 - 244 - static void exynos_pcie_power_on_phy(struct exynos_pcie *ep) 245 - { 246 - u32 val; 247 - 248 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_COMMON_POWER); 249 - val &= ~PCIE_PHY_COMMON_PD_CMN; 250 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_COMMON_POWER); 251 - 252 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV0_POWER); 253 - val &= ~PCIE_PHY_TRSV0_PD_TSV; 254 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV0_POWER); 255 - 256 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV1_POWER); 257 - val &= ~PCIE_PHY_TRSV1_PD_TSV; 258 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV1_POWER); 259 - 260 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV2_POWER); 261 - val &= ~PCIE_PHY_TRSV2_PD_TSV; 262 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV2_POWER); 263 - 264 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV3_POWER); 265 - val &= ~PCIE_PHY_TRSV3_PD_TSV; 266 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV3_POWER); 267 - } 268 - 269 - static void exynos_pcie_power_off_phy(struct exynos_pcie *ep) 270 - { 271 - u32 val; 272 - 273 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_COMMON_POWER); 274 - val |= PCIE_PHY_COMMON_PD_CMN; 275 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_COMMON_POWER); 276 - 277 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV0_POWER); 278 - val |= PCIE_PHY_TRSV0_PD_TSV; 279 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV0_POWER); 280 - 281 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV1_POWER); 282 - val |= PCIE_PHY_TRSV1_PD_TSV; 283 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV1_POWER); 284 - 285 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV2_POWER); 286 - val |= PCIE_PHY_TRSV2_PD_TSV; 287 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV2_POWER); 288 - 289 - val = exynos_pcie_readl(ep->mem_res->phy_base, PCIE_PHY_TRSV3_POWER); 290 - val |= PCIE_PHY_TRSV3_PD_TSV; 291 - exynos_pcie_writel(ep->mem_res->phy_base, val, PCIE_PHY_TRSV3_POWER); 292 - } 293 - 294 - static void exynos_pcie_init_phy(struct exynos_pcie *ep) 295 - { 296 - /* DCC feedback control off */ 297 - exynos_pcie_writel(ep->mem_res->phy_base, 0x29, PCIE_PHY_DCC_FEEDBACK); 298 - 299 - /* set TX/RX impedance */ 300 - exynos_pcie_writel(ep->mem_res->phy_base, 0xd5, PCIE_PHY_IMPEDANCE); 301 - 302 - /* set 50Mhz PHY clock */ 303 - exynos_pcie_writel(ep->mem_res->phy_base, 0x14, PCIE_PHY_PLL_DIV_0); 304 - exynos_pcie_writel(ep->mem_res->phy_base, 0x12, PCIE_PHY_PLL_DIV_1); 305 - 306 - /* set TX Differential output for lane 0 */ 307 - exynos_pcie_writel(ep->mem_res->phy_base, 0x7f, PCIE_PHY_TRSV0_DRV_LVL); 308 - 309 - /* set TX Pre-emphasis Level Control for lane 0 to minimum */ 310 - exynos_pcie_writel(ep->mem_res->phy_base, 0x0, PCIE_PHY_TRSV0_EMP_LVL); 311 - 312 - /* set RX clock and data recovery bandwidth */ 313 - exynos_pcie_writel(ep->mem_res->phy_base, 0xe7, PCIE_PHY_PLL_BIAS); 314 - exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV0_RXCDR); 315 - exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV1_RXCDR); 316 - exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV2_RXCDR); 317 - exynos_pcie_writel(ep->mem_res->phy_base, 0x82, PCIE_PHY_TRSV3_RXCDR); 318 - 319 - /* change TX Pre-emphasis Level Control for lanes */ 320 - exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV0_EMP_LVL); 321 - exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV1_EMP_LVL); 322 - exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV2_EMP_LVL); 323 - exynos_pcie_writel(ep->mem_res->phy_base, 0x39, PCIE_PHY_TRSV3_EMP_LVL); 324 - 325 - /* set LVCC */ 326 - exynos_pcie_writel(ep->mem_res->phy_base, 0x20, PCIE_PHY_TRSV0_LVCC); 327 - exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV1_LVCC); 328 - exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV2_LVCC); 329 - exynos_pcie_writel(ep->mem_res->phy_base, 0xa0, PCIE_PHY_TRSV3_LVCC); 330 282 } 331 283 332 284 static void exynos_pcie_assert_reset(struct exynos_pcie *ep) ··· 239 401 struct dw_pcie *pci = ep->pci; 240 402 struct pcie_port *pp = &pci->pp; 241 403 struct device *dev = pci->dev; 242 - u32 val; 243 404 244 405 if (dw_pcie_link_up(pci)) { 245 406 dev_err(dev, "Link already up\n"); ··· 247 410 248 411 exynos_pcie_assert_core_reset(ep); 249 412 250 - if (ep->using_phy) { 251 - phy_reset(ep->phy); 413 + phy_reset(ep->phy); 252 414 253 - exynos_pcie_writel(ep->mem_res->elbi_base, 1, 254 - PCIE_PWR_RESET); 415 + exynos_pcie_writel(ep->mem_res->elbi_base, 1, 416 + PCIE_PWR_RESET); 255 417 256 - phy_power_on(ep->phy); 257 - phy_init(ep->phy); 258 - } else { 259 - exynos_pcie_assert_phy_reset(ep); 260 - exynos_pcie_deassert_phy_reset(ep); 261 - exynos_pcie_power_on_phy(ep); 262 - exynos_pcie_init_phy(ep); 263 - 264 - /* pulse for common reset */ 265 - exynos_pcie_writel(ep->mem_res->block_base, 1, 266 - PCIE_PHY_COMMON_RESET); 267 - udelay(500); 268 - exynos_pcie_writel(ep->mem_res->block_base, 0, 269 - PCIE_PHY_COMMON_RESET); 270 - } 271 - 272 - /* pulse for common reset */ 273 - exynos_pcie_writel(ep->mem_res->block_base, 1, PCIE_PHY_COMMON_RESET); 274 - udelay(500); 275 - exynos_pcie_writel(ep->mem_res->block_base, 0, PCIE_PHY_COMMON_RESET); 418 + phy_power_on(ep->phy); 419 + phy_init(ep->phy); 276 420 277 421 exynos_pcie_deassert_core_reset(ep); 278 422 dw_pcie_setup_rc(pp); ··· 267 449 if (!dw_pcie_wait_for_link(pci)) 268 450 return 0; 269 451 270 - if (ep->using_phy) { 271 - phy_power_off(ep->phy); 272 - return -ETIMEDOUT; 273 - } 274 - 275 - while (exynos_pcie_readl(ep->mem_res->phy_base, 276 - PCIE_PHY_PLL_LOCKED) == 0) { 277 - val = exynos_pcie_readl(ep->mem_res->block_base, 278 - PCIE_PHY_PLL_LOCKED); 279 - dev_info(dev, "PLL Locked: 0x%x\n", val); 280 - } 281 - exynos_pcie_power_off_phy(ep); 452 + phy_power_off(ep->phy); 282 453 return -ETIMEDOUT; 283 454 } 284 455 ··· 485 678 486 679 ep->reset_gpio = of_get_named_gpio(np, "reset-gpio", 0); 487 680 488 - /* Assume that controller doesn't use the PHY framework */ 489 - ep->using_phy = false; 490 - 491 681 ep->phy = devm_of_phy_get(dev, np, NULL); 492 682 if (IS_ERR(ep->phy)) { 493 683 if (PTR_ERR(ep->phy) == -EPROBE_DEFER) 494 684 return PTR_ERR(ep->phy); 495 - dev_warn(dev, "Use the 'phy' property. Current DT of pci-exynos was deprecated!!\n"); 496 - } else 497 - ep->using_phy = true; 685 + 686 + ep->phy = NULL; 687 + } 498 688 499 689 if (ep->ops && ep->ops->get_mem_resources) { 500 690 ret = ep->ops->get_mem_resources(pdev, ep); ··· 517 713 return 0; 518 714 519 715 fail_probe: 520 - if (ep->using_phy) 521 - phy_exit(ep->phy); 716 + phy_exit(ep->phy); 522 717 523 718 if (ep->ops && ep->ops->deinit_clk_resources) 524 719 ep->ops->deinit_clk_resources(ep);