^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Rockchip AXI PCIe host controller driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) 2016 Rockchip, Inc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Author: Shawn Lin <shawn.lin@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Wenrui Li <wenrui.li@rock-chips.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Bits taken from Synopsys DesignWare Host controller driver and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * ARM PCI Host generic driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/of_pci.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/reset.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) #include "../pci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #include "pcie-rockchip.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) struct device *dev = rockchip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) struct platform_device *pdev = to_platform_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) struct device_node *node = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) struct resource *regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) if (rockchip->is_rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) regs = platform_get_resource_byname(pdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) "axi-base");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) rockchip->reg_base = devm_pci_remap_cfg_resource(dev, regs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) if (IS_ERR(rockchip->reg_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) return PTR_ERR(rockchip->reg_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) rockchip->mem_res =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) platform_get_resource_byname(pdev, IORESOURCE_MEM,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) "mem-base");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) if (!rockchip->mem_res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) rockchip->apb_base =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) devm_platform_ioremap_resource_byname(pdev, "apb-base");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (IS_ERR(rockchip->apb_base))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return PTR_ERR(rockchip->apb_base);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) err = rockchip_pcie_get_phys(rockchip);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) rockchip->lanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) err = of_property_read_u32(node, "num-lanes", &rockchip->lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) if (!err && (rockchip->lanes == 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) rockchip->lanes == 3 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) rockchip->lanes > 4)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) dev_warn(dev, "invalid num-lanes, default to use one lane\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) rockchip->lanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) rockchip->link_gen = of_pci_get_max_link_speed(node);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) if (rockchip->link_gen < 0 || rockchip->link_gen > 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) rockchip->link_gen = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) rockchip->core_rst = devm_reset_control_get_exclusive(dev, "core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) if (IS_ERR(rockchip->core_rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if (PTR_ERR(rockchip->core_rst) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) dev_err(dev, "missing core reset property in node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) return PTR_ERR(rockchip->core_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) rockchip->mgmt_rst = devm_reset_control_get_exclusive(dev, "mgmt");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if (IS_ERR(rockchip->mgmt_rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) if (PTR_ERR(rockchip->mgmt_rst) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) dev_err(dev, "missing mgmt reset property in node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return PTR_ERR(rockchip->mgmt_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) rockchip->mgmt_sticky_rst = devm_reset_control_get_exclusive(dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) "mgmt-sticky");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) if (IS_ERR(rockchip->mgmt_sticky_rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) if (PTR_ERR(rockchip->mgmt_sticky_rst) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) dev_err(dev, "missing mgmt-sticky reset property in node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return PTR_ERR(rockchip->mgmt_sticky_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) rockchip->pipe_rst = devm_reset_control_get_exclusive(dev, "pipe");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (IS_ERR(rockchip->pipe_rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) if (PTR_ERR(rockchip->pipe_rst) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) dev_err(dev, "missing pipe reset property in node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return PTR_ERR(rockchip->pipe_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) rockchip->pm_rst = devm_reset_control_get_exclusive(dev, "pm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (IS_ERR(rockchip->pm_rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (PTR_ERR(rockchip->pm_rst) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) dev_err(dev, "missing pm reset property in node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) return PTR_ERR(rockchip->pm_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) rockchip->pclk_rst = devm_reset_control_get_exclusive(dev, "pclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) if (IS_ERR(rockchip->pclk_rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (PTR_ERR(rockchip->pclk_rst) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) dev_err(dev, "missing pclk reset property in node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) return PTR_ERR(rockchip->pclk_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) rockchip->aclk_rst = devm_reset_control_get_exclusive(dev, "aclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (IS_ERR(rockchip->aclk_rst)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) if (PTR_ERR(rockchip->aclk_rst) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) dev_err(dev, "missing aclk reset property in node\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) return PTR_ERR(rockchip->aclk_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) if (rockchip->is_rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) rockchip->ep_gpio = devm_gpiod_get_optional(dev, "ep",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) GPIOD_OUT_HIGH);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) if (IS_ERR(rockchip->ep_gpio))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) return dev_err_probe(dev, PTR_ERR(rockchip->ep_gpio),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) "failed to get ep GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) rockchip->aclk_pcie = devm_clk_get(dev, "aclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (IS_ERR(rockchip->aclk_pcie)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) dev_err(dev, "aclk clock not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return PTR_ERR(rockchip->aclk_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) rockchip->aclk_perf_pcie = devm_clk_get(dev, "aclk-perf");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) if (IS_ERR(rockchip->aclk_perf_pcie)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) dev_err(dev, "aclk_perf clock not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) return PTR_ERR(rockchip->aclk_perf_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) rockchip->hclk_pcie = devm_clk_get(dev, "hclk");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) if (IS_ERR(rockchip->hclk_pcie)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) dev_err(dev, "hclk clock not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) return PTR_ERR(rockchip->hclk_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) rockchip->clk_pcie_pm = devm_clk_get(dev, "pm");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) if (IS_ERR(rockchip->clk_pcie_pm)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) dev_err(dev, "pm clock not found\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) return PTR_ERR(rockchip->clk_pcie_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) EXPORT_SYMBOL_GPL(rockchip_pcie_parse_dt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) int rockchip_pcie_init_port(struct rockchip_pcie *rockchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) struct device *dev = rockchip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) int err, i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) u32 regs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) err = reset_control_assert(rockchip->aclk_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) dev_err(dev, "assert aclk_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) err = reset_control_assert(rockchip->pclk_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) dev_err(dev, "assert pclk_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) err = reset_control_assert(rockchip->pm_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) dev_err(dev, "assert pm_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) for (i = 0; i < MAX_LANE_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) err = phy_init(rockchip->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) dev_err(dev, "init phy%d err %d\n", i, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) err = reset_control_assert(rockchip->core_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) dev_err(dev, "assert core_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) err = reset_control_assert(rockchip->mgmt_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) dev_err(dev, "assert mgmt_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) err = reset_control_assert(rockchip->mgmt_sticky_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) dev_err(dev, "assert mgmt_sticky_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) err = reset_control_assert(rockchip->pipe_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) dev_err(dev, "assert pipe_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) udelay(10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) err = reset_control_deassert(rockchip->pm_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) dev_err(dev, "deassert pm_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) err = reset_control_deassert(rockchip->aclk_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) dev_err(dev, "deassert aclk_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) err = reset_control_deassert(rockchip->pclk_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) dev_err(dev, "deassert pclk_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) goto err_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) if (rockchip->link_gen == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) PCIE_CLIENT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) rockchip_pcie_write(rockchip, PCIE_CLIENT_GEN_SEL_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) PCIE_CLIENT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) regs = PCIE_CLIENT_LINK_TRAIN_ENABLE | PCIE_CLIENT_ARI_ENABLE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) PCIE_CLIENT_CONF_LANE_NUM(rockchip->lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) if (rockchip->is_rc)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) regs |= PCIE_CLIENT_CONF_ENABLE | PCIE_CLIENT_MODE_RC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) regs |= PCIE_CLIENT_CONF_DISABLE | PCIE_CLIENT_MODE_EP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) rockchip_pcie_write(rockchip, regs, PCIE_CLIENT_CONFIG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) for (i = 0; i < MAX_LANE_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) err = phy_power_on(rockchip->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) dev_err(dev, "power on phy%d err %d\n", i, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * Please don't reorder the deassert sequence of the following
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * four reset pins.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) err = reset_control_deassert(rockchip->mgmt_sticky_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) dev_err(dev, "deassert mgmt_sticky_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) err = reset_control_deassert(rockchip->core_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) dev_err(dev, "deassert core_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) err = reset_control_deassert(rockchip->mgmt_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) dev_err(dev, "deassert mgmt_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) err = reset_control_deassert(rockchip->pipe_rst);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) dev_err(dev, "deassert pipe_rst err %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) goto err_power_off_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) err_power_off_phy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) while (i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) phy_power_off(rockchip->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) i = MAX_LANE_NUM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) err_exit_phy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) while (i--)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) phy_exit(rockchip->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) EXPORT_SYMBOL_GPL(rockchip_pcie_init_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) int rockchip_pcie_get_phys(struct rockchip_pcie *rockchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) struct device *dev = rockchip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) struct phy *phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) char *name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) phy = devm_phy_get(dev, "pcie-phy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) if (!IS_ERR(phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) rockchip->legacy_phy = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) rockchip->phys[0] = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) dev_warn(dev, "legacy phy model is deprecated!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) if (PTR_ERR(phy) == -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) return PTR_ERR(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) dev_dbg(dev, "missing legacy phy; search for per-lane PHY\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) for (i = 0; i < MAX_LANE_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) name = kasprintf(GFP_KERNEL, "pcie-phy-%u", i);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) phy = devm_of_phy_get(dev, dev->of_node, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) kfree(name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) if (IS_ERR(phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) if (PTR_ERR(phy) != -EPROBE_DEFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) dev_err(dev, "missing phy for lane %d: %ld\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) i, PTR_ERR(phy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) return PTR_ERR(phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) rockchip->phys[i] = phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) EXPORT_SYMBOL_GPL(rockchip_pcie_get_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) void rockchip_pcie_deinit_phys(struct rockchip_pcie *rockchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) for (i = 0; i < MAX_LANE_NUM; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) /* inactive lanes are already powered off */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) if (rockchip->lanes_map & BIT(i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) phy_power_off(rockchip->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) phy_exit(rockchip->phys[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) EXPORT_SYMBOL_GPL(rockchip_pcie_deinit_phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) int rockchip_pcie_enable_clocks(struct rockchip_pcie *rockchip)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) struct device *dev = rockchip->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) err = clk_prepare_enable(rockchip->aclk_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) dev_err(dev, "unable to enable aclk_pcie clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) err = clk_prepare_enable(rockchip->aclk_perf_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) dev_err(dev, "unable to enable aclk_perf_pcie clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) goto err_aclk_perf_pcie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) err = clk_prepare_enable(rockchip->hclk_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) dev_err(dev, "unable to enable hclk_pcie clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) goto err_hclk_pcie;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) err = clk_prepare_enable(rockchip->clk_pcie_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) if (err) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) dev_err(dev, "unable to enable clk_pcie_pm clock\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) goto err_clk_pcie_pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) err_clk_pcie_pm:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) clk_disable_unprepare(rockchip->hclk_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) err_hclk_pcie:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) clk_disable_unprepare(rockchip->aclk_perf_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) err_aclk_perf_pcie:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) clk_disable_unprepare(rockchip->aclk_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) EXPORT_SYMBOL_GPL(rockchip_pcie_enable_clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) void rockchip_pcie_disable_clocks(void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) struct rockchip_pcie *rockchip = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) clk_disable_unprepare(rockchip->clk_pcie_pm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) clk_disable_unprepare(rockchip->hclk_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) clk_disable_unprepare(rockchip->aclk_perf_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) clk_disable_unprepare(rockchip->aclk_pcie);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) EXPORT_SYMBOL_GPL(rockchip_pcie_disable_clocks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) void rockchip_pcie_cfg_configuration_accesses(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) struct rockchip_pcie *rockchip, u32 type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) u32 ob_desc_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) /* Configuration Accesses for region 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) rockchip_pcie_write(rockchip, 0x0, PCIE_RC_BAR_CONF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) rockchip_pcie_write(rockchip,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) (RC_REGION_0_ADDR_TRANS_L + RC_REGION_0_PASS_BITS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) PCIE_CORE_OB_REGION_ADDR0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) rockchip_pcie_write(rockchip, RC_REGION_0_ADDR_TRANS_H,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) PCIE_CORE_OB_REGION_ADDR1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ob_desc_0 = rockchip_pcie_read(rockchip, PCIE_CORE_OB_REGION_DESC0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) ob_desc_0 &= ~(RC_REGION_0_TYPE_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) ob_desc_0 |= (type | (0x1 << 23));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) rockchip_pcie_write(rockchip, ob_desc_0, PCIE_CORE_OB_REGION_DESC0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) rockchip_pcie_write(rockchip, 0x0, PCIE_CORE_OB_REGION_DESC1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) EXPORT_SYMBOL_GPL(rockchip_pcie_cfg_configuration_accesses);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) MODULE_AUTHOR("Rockchip Inc");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) MODULE_DESCRIPTION("Rockchip AXI PCIe driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) MODULE_LICENSE("GPL v2");