Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0+
0002 /*
0003  * Rockchip AXI PCIe host controller driver
0004  *
0005  * Copyright (c) 2016 Rockchip, Inc.
0006  *
0007  * Author: Shawn Lin <shawn.lin@rock-chips.com>
0008  *         Wenrui Li <wenrui.li@rock-chips.com>
0009  *
0010  * Bits taken from Synopsys DesignWare Host controller driver and
0011  * ARM PCI Host generic driver.
0012  */
0013 
0014 #include <linux/clk.h>
0015 #include <linux/delay.h>
0016 #include <linux/gpio/consumer.h>
0017 #include <linux/of_pci.h>
0018 #include <linux/phy/phy.h>
0019 #include <linux/platform_device.h>
0020 #include <linux/reset.h>
0021 
0022 #include "../pci.h"
0023 #include "pcie-rockchip.h"
0024 
0025 int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
0026 {
0027     struct device *dev = rockchip->dev;
0028     struct platform_device *pdev = to_platform_device(dev);
0029     struct device_node *node = dev->of_node;
0030     struct resource *regs;
0031     int err;
0032 
0033     if (rockchip->is_rc) {
0034         regs = platform_get_resource_byname(pdev,
0035                             IORESOURCE_MEM,
0036                             "axi-base");
0037         rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
0038         if (IS_ERR(rockchip->reg_base))
0039             return PTR_ERR(rockchip->reg_base);
0040     } else {
0041         rockchip->mem_res =
0042             platform_get_resource_byname(pdev, IORESOURCE_MEM,
0043                              "mem-base");
0044         if (!rockchip->mem_res)
0045             return -EINVAL;
0046     }
0047 
0048     rockchip->apb_base =
0049         devm_platform_ioremap_resource_byname(pdev, "apb-base");
0050     if (IS_ERR(rockchip->apb_base))
0051         return PTR_ERR(rockchip->apb_base);
0052 
0053     err = rockchip_pcie_get_phys(rockchip);
0054     if (err)
0055         return err;
0056 
0057     rockchip->lanes = 1;
0058     err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
0059     if (!err && (rockchip->lanes == 0 ||
0060              rockchip->lanes == 3 ||
0061              rockchip->lanes > 4)) {
0062         dev_warn(dev, "invalid num-lanes, default to use one lane\n");
0063         rockchip->lanes = 1;
0064     }
0065 
0066     rockchip->link_gen = of_pci_get_max_link_speed(node);
0067     if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
0068         rockchip->link_gen = 2;
0069 
0070     rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
0071     if (IS_ERR(rockchip->core_rst)) {
0072         if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
0073             dev_err(dev, "missing core reset property in node\n");
0074         return PTR_ERR(rockchip->core_rst);
0075     }
0076 
0077     rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
0078     if (IS_ERR(rockchip->mgmt_rst)) {
0079         if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
0080             dev_err(dev, "missing mgmt reset property in node\n");
0081         return PTR_ERR(rockchip->mgmt_rst);
0082     }
0083 
0084     rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
0085                                 "mgmt-sticky");
0086     if (IS_ERR(rockchip->mgmt_sticky_rst)) {
0087         if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
0088             dev_err(dev, "missing mgmt-sticky reset property in node\n");
0089         return PTR_ERR(rockchip->mgmt_sticky_rst);
0090     }
0091 
0092     rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
0093     if (IS_ERR(rockchip->pipe_rst)) {
0094         if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
0095             dev_err(dev, "missing pipe reset property in node\n");
0096         return PTR_ERR(rockchip->pipe_rst);
0097     }
0098 
0099     rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
0100     if (IS_ERR(rockchip->pm_rst)) {
0101         if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
0102             dev_err(dev, "missing pm reset property in node\n");
0103         return PTR_ERR(rockchip->pm_rst);
0104     }
0105 
0106     rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
0107     if (IS_ERR(rockchip->pclk_rst)) {
0108         if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
0109             dev_err(dev, "missing pclk reset property in node\n");
0110         return PTR_ERR(rockchip->pclk_rst);
0111     }
0112 
0113     rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
0114     if (IS_ERR(rockchip->aclk_rst)) {
0115         if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
0116             dev_err(dev, "missing aclk reset property in node\n");
0117         return PTR_ERR(rockchip->aclk_rst);
0118     }
0119 
0120     if (rockchip->is_rc) {
0121         rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep",
0122                                 GPIOD_OUT_HIGH);
0123         if (IS_ERR(rockchip->ep_gpio))
0124             return dev_err_probe(dev, PTR_ERR(rockchip->ep_gpio),
0125                          "failed to get ep GPIO\n");
0126     }
0127 
0128     rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
0129     if (IS_ERR(rockchip->aclk_pcie)) {
0130         dev_err(dev, "aclk clock not found\n");
0131         return PTR_ERR(rockchip->aclk_pcie);
0132     }
0133 
0134     rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
0135     if (IS_ERR(rockchip->aclk_perf_pcie)) {
0136         dev_err(dev, "aclk_perf clock not found\n");
0137         return PTR_ERR(rockchip->aclk_perf_pcie);
0138     }
0139 
0140     rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
0141     if (IS_ERR(rockchip->hclk_pcie)) {
0142         dev_err(dev, "hclk clock not found\n");
0143         return PTR_ERR(rockchip->hclk_pcie);
0144     }
0145 
0146     rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
0147     if (IS_ERR(rockchip->clk_pcie_pm)) {
0148         dev_err(dev, "pm clock not found\n");
0149         return PTR_ERR(rockchip->clk_pcie_pm);
0150     }
0151 
0152     return 0;
0153 }
0154 EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
0155 
0156 int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
0157 {
0158     struct device *dev = rockchip->dev;
0159     int err, i;
0160     u32 regs;
0161 
0162     err = reset_control_assert(rockchip->aclk_rst);
0163     if (err) {
0164         dev_err(dev, "assert aclk_rst err %d\n", err);
0165         return err;
0166     }
0167 
0168     err = reset_control_assert(rockchip->pclk_rst);
0169     if (err) {
0170         dev_err(dev, "assert pclk_rst err %d\n", err);
0171         return err;
0172     }
0173 
0174     err = reset_control_assert(rockchip->pm_rst);
0175     if (err) {
0176         dev_err(dev, "assert pm_rst err %d\n", err);
0177         return err;
0178     }
0179 
0180     for (i = 0; i < MAX_LANE_NUM; i++) {
0181         err = phy_init(rockchip->phys[i]);
0182         if (err) {
0183             dev_err(dev, "init phy%d err %d\n", i, err);
0184             goto err_exit_phy;
0185         }
0186     }
0187 
0188     err = reset_control_assert(rockchip->core_rst);
0189     if (err) {
0190         dev_err(dev, "assert core_rst err %d\n", err);
0191         goto err_exit_phy;
0192     }
0193 
0194     err = reset_control_assert(rockchip->mgmt_rst);
0195     if (err) {
0196         dev_err(dev, "assert mgmt_rst err %d\n", err);
0197         goto err_exit_phy;
0198     }
0199 
0200     err = reset_control_assert(rockchip->mgmt_sticky_rst);
0201     if (err) {
0202         dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
0203         goto err_exit_phy;
0204     }
0205 
0206     err = reset_control_assert(rockchip->pipe_rst);
0207     if (err) {
0208         dev_err(dev, "assert pipe_rst err %d\n", err);
0209         goto err_exit_phy;
0210     }
0211 
0212     udelay(10);
0213 
0214     err = reset_control_deassert(rockchip->pm_rst);
0215     if (err) {
0216         dev_err(dev, "deassert pm_rst err %d\n", err);
0217         goto err_exit_phy;
0218     }
0219 
0220     err = reset_control_deassert(rockchip->aclk_rst);
0221     if (err) {
0222         dev_err(dev, "deassert aclk_rst err %d\n", err);
0223         goto err_exit_phy;
0224     }
0225 
0226     err = reset_control_deassert(rockchip->pclk_rst);
0227     if (err) {
0228         dev_err(dev, "deassert pclk_rst err %d\n", err);
0229         goto err_exit_phy;
0230     }
0231 
0232     if (rockchip->link_gen == 2)
0233         rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2,
0234                     PCIE_CLIENT_CONFIG);
0235     else
0236         rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1,
0237                     PCIE_CLIENT_CONFIG);
0238 
0239     regs = PCIE_CLIENT_LINK_TRAIN_ENABLE | PCIE_CLIENT_ARI_ENABLE |
0240            PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes);
0241 
0242     if (rockchip->is_rc)
0243         regs |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC;
0244     else
0245         regs |= PCIE_CLIENT_CONF_DISABLE | PCIE_CLIENT_MODE_EP;
0246 
0247     rockchip_pcie_write(rockchip, regs, PCIE_CLIENT_CONFIG);
0248 
0249     for (i = 0; i < MAX_LANE_NUM; i++) {
0250         err = phy_power_on(rockchip->phys[i]);
0251         if (err) {
0252             dev_err(dev, "power on phy%d err %d\n", i, err);
0253             goto err_power_off_phy;
0254         }
0255     }
0256 
0257     /*
0258      * Please don't reorder the deassert sequence of the following
0259      * four reset pins.
0260      */
0261     err = reset_control_deassert(rockchip->mgmt_sticky_rst);
0262     if (err) {
0263         dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
0264         goto err_power_off_phy;
0265     }
0266 
0267     err = reset_control_deassert(rockchip->core_rst);
0268     if (err) {
0269         dev_err(dev, "deassert core_rst err %d\n", err);
0270         goto err_power_off_phy;
0271     }
0272 
0273     err = reset_control_deassert(rockchip->mgmt_rst);
0274     if (err) {
0275         dev_err(dev, "deassert mgmt_rst err %d\n", err);
0276         goto err_power_off_phy;
0277     }
0278 
0279     err = reset_control_deassert(rockchip->pipe_rst);
0280     if (err) {
0281         dev_err(dev, "deassert pipe_rst err %d\n", err);
0282         goto err_power_off_phy;
0283     }
0284 
0285     return 0;
0286 err_power_off_phy:
0287     while (i--)
0288         phy_power_off(rockchip->phys[i]);
0289     i = MAX_LANE_NUM;
0290 err_exit_phy:
0291     while (i--)
0292         phy_exit(rockchip->phys[i]);
0293     return err;
0294 }
0295 EXPORT_SYMBOL_GPL(rockchip_pcie_init_port);
0296 
0297 int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip)
0298 {
0299     struct device *dev = rockchip->dev;
0300     struct phy *phy;
0301     char *name;
0302     u32 i;
0303 
0304     phy = devm_phy_get(dev, "pcie-phy");
0305     if (!IS_ERR(phy)) {
0306         rockchip->legacy_phy = true;
0307         rockchip->phys[0] = phy;
0308         dev_warn(dev, "legacy phy model is deprecated!\n");
0309         return 0;
0310     }
0311 
0312     if (PTR_ERR(phy) == -EPROBE_DEFER)
0313         return PTR_ERR(phy);
0314 
0315     dev_dbg(dev, "missing legacy phy; search for per-lane PHY\n");
0316 
0317     for (i = 0; i < MAX_LANE_NUM; i++) {
0318         name = kasprintf(GFP_KERNEL, "pcie-phy-%u", i);
0319         if (!name)
0320             return -ENOMEM;
0321 
0322         phy = devm_of_phy_get(dev, dev->of_node, name);
0323         kfree(name);
0324 
0325         if (IS_ERR(phy)) {
0326             if (PTR_ERR(phy) != -EPROBE_DEFER)
0327                 dev_err(dev, "missing phy for lane %d: %ld\n",
0328                     i, PTR_ERR(phy));
0329             return PTR_ERR(phy);
0330         }
0331 
0332         rockchip->phys[i] = phy;
0333     }
0334 
0335     return 0;
0336 }
0337 EXPORT_SYMBOL_GPL(rockchip_pcie_get_phys);
0338 
0339 void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip)
0340 {
0341     int i;
0342 
0343     for (i = 0; i < MAX_LANE_NUM; i++) {
0344         /* inactive lanes are already powered off */
0345         if (rockchip->lanes_map & BIT(i))
0346             phy_power_off(rockchip->phys[i]);
0347         phy_exit(rockchip->phys[i]);
0348     }
0349 }
0350 EXPORT_SYMBOL_GPL(rockchip_pcie_deinit_phys);
0351 
0352 int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip)
0353 {
0354     struct device *dev = rockchip->dev;
0355     int err;
0356 
0357     err = clk_prepare_enable(rockchip->aclk_pcie);
0358     if (err) {
0359         dev_err(dev, "unable to enable aclk_pcie clock\n");
0360         return err;
0361     }
0362 
0363     err = clk_prepare_enable(rockchip->aclk_perf_pcie);
0364     if (err) {
0365         dev_err(dev, "unable to enable aclk_perf_pcie clock\n");
0366         goto err_aclk_perf_pcie;
0367     }
0368 
0369     err = clk_prepare_enable(rockchip->hclk_pcie);
0370     if (err) {
0371         dev_err(dev, "unable to enable hclk_pcie clock\n");
0372         goto err_hclk_pcie;
0373     }
0374 
0375     err = clk_prepare_enable(rockchip->clk_pcie_pm);
0376     if (err) {
0377         dev_err(dev, "unable to enable clk_pcie_pm clock\n");
0378         goto err_clk_pcie_pm;
0379     }
0380 
0381     return 0;
0382 
0383 err_clk_pcie_pm:
0384     clk_disable_unprepare(rockchip->hclk_pcie);
0385 err_hclk_pcie:
0386     clk_disable_unprepare(rockchip->aclk_perf_pcie);
0387 err_aclk_perf_pcie:
0388     clk_disable_unprepare(rockchip->aclk_pcie);
0389     return err;
0390 }
0391 EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks);
0392 
0393 void rockchip_pcie_disable_clocks(void *data)
0394 {
0395     struct rockchip_pcie *rockchip = data;
0396 
0397     clk_disable_unprepare(rockchip->clk_pcie_pm);
0398     clk_disable_unprepare(rockchip->hclk_pcie);
0399     clk_disable_unprepare(rockchip->aclk_perf_pcie);
0400     clk_disable_unprepare(rockchip->aclk_pcie);
0401 }
0402 EXPORT_SYMBOL_GPL(rockchip_pcie_disable_clocks);
0403 
0404 void rockchip_pcie_cfg_configuration_accesses(
0405         struct rockchip_pcie *rockchip, u32 type)
0406 {
0407     u32 ob_desc_0;
0408 
0409     /* Configuration Accesses for region 0 */
0410     rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF);
0411 
0412     rockchip_pcie_write(rockchip,
0413                 (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS),
0414                 PCIE_CORE_OB_REGION_ADDR0);
0415     rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H,
0416                 PCIE_CORE_OB_REGION_ADDR1);
0417     ob_desc_0 = rockchip_pcie_read(rockchip, PCIE_CORE_OB_REGION_DESC0);
0418     ob_desc_0 &= ~(RC_REGION_0_TYPE_MASK);
0419     ob_desc_0 |= (type | (0x1 << 23));
0420     rockchip_pcie_write(rockchip, ob_desc_0, PCIE_CORE_OB_REGION_DESC0);
0421     rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1);
0422 }
0423 EXPORT_SYMBOL_GPL(rockchip_pcie_cfg_configuration_accesses);