1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * PCIe host controller driver for Rockchip SoCs. 4 * 5 * Copyright (C) 2021 Rockchip Electronics Co., Ltd. 6 * http://www.rock-chips.com 7 * 8 * Author: Simon Xue <xxm@rock-chips.com> 9 */ 10 11 #include <linux/clk.h> 12 #include <linux/gpio/consumer.h> 13 #include <linux/mfd/syscon.h> 14 #include <linux/module.h> 15 #include <linux/of_device.h> 16 #include <linux/phy/phy.h> 17 #include <linux/platform_device.h> 18 #include <linux/regmap.h> 19 #include <linux/reset.h> 20 21 #include "pcie-designware.h" 22 23 /* 24 * The upper 16 bits of PCIE_CLIENT_CONFIG are a write 25 * mask for the lower 16 bits. 26 */ 27 #define HIWORD_UPDATE(mask, val) (((mask) << 16) | (val)) 28 #define HIWORD_UPDATE_BIT(val) HIWORD_UPDATE(val, val) 29 30 #define to_rockchip_pcie(x) dev_get_drvdata((x)->dev) 31 32 #define PCIE_CLIENT_RC_MODE HIWORD_UPDATE_BIT(0x40) 33 #define PCIE_CLIENT_ENABLE_LTSSM HIWORD_UPDATE_BIT(0xc) 34 #define PCIE_SMLH_LINKUP BIT(16) 35 #define PCIE_RDLH_LINKUP BIT(17) 36 #define PCIE_LINKUP (PCIE_SMLH_LINKUP | PCIE_RDLH_LINKUP) 37 #define PCIE_L0S_ENTRY 0x11 38 #define PCIE_CLIENT_GENERAL_CONTROL 0x0 39 #define PCIE_CLIENT_GENERAL_DEBUG 0x104 40 #define PCIE_CLIENT_HOT_RESET_CTRL 0x180 41 #define PCIE_CLIENT_LTSSM_STATUS 0x300 42 #define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) 43 #define PCIE_LTSSM_STATUS_MASK GENMASK(5, 0) 44 45 struct rockchip_pcie { 46 struct dw_pcie pci; 47 void __iomem *apb_base; 48 struct phy *phy; 49 struct clk_bulk_data *clks; 50 unsigned int clk_cnt; 51 struct reset_control *rst; 52 struct gpio_desc *rst_gpio; 53 struct regulator *vpcie3v3; 54 }; 55 56 static int rockchip_pcie_readl_apb(struct rockchip_pcie *rockchip, 57 u32 reg) 58 { 59 return readl_relaxed(rockchip->apb_base + reg); 60 } 61 62 static void rockchip_pcie_writel_apb(struct rockchip_pcie *rockchip, 63 u32 val, u32 reg) 64 { 65 writel_relaxed(val, rockchip->apb_base + reg); 66 } 67 68 static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip) 69 { 70 rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_ENABLE_LTSSM, 71 PCIE_CLIENT_GENERAL_CONTROL); 72 } 73 74 static int rockchip_pcie_link_up(struct dw_pcie *pci) 75 { 76 struct rockchip_pcie *rockchip = to_rockchip_pcie(pci); 77 u32 val = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_LTSSM_STATUS); 78 79 if ((val & PCIE_LINKUP) == PCIE_LINKUP && 80 (val & PCIE_LTSSM_STATUS_MASK) == PCIE_L0S_ENTRY) 81 return 1; 82 83 return 0; 84 } 85 86 static int rockchip_pcie_start_link(struct dw_pcie *pci) 87 { 88 struct rockchip_pcie *rockchip = to_rockchip_pcie(pci); 89 90 /* Reset device */ 91 gpiod_set_value_cansleep(rockchip->rst_gpio, 0); 92 93 rockchip_pcie_enable_ltssm(rockchip); 94 95 /* 96 * PCIe requires the refclk to be stable for 100µs prior to releasing 97 * PERST. See table 2-4 in section 2.6.2 AC Specifications of the PCI 98 * Express Card Electromechanical Specification, 1.1. However, we don't 99 * know if the refclk is coming from RC's PHY or external OSC. If it's 100 * from RC, so enabling LTSSM is the just right place to release #PERST. 101 * We need more extra time as before, rather than setting just 102 * 100us as we don't know how long should the device need to reset. 103 */ 104 msleep(100); 105 gpiod_set_value_cansleep(rockchip->rst_gpio, 1); 106 107 return 0; 108 } 109 110 static int rockchip_pcie_host_init(struct pcie_port *pp) 111 { 112 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 113 struct rockchip_pcie *rockchip = to_rockchip_pcie(pci); 114 u32 val = HIWORD_UPDATE_BIT(PCIE_LTSSM_ENABLE_ENHANCE); 115 116 /* LTSSM enable control mode */ 117 rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL); 118 119 rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_RC_MODE, 120 PCIE_CLIENT_GENERAL_CONTROL); 121 122 return 0; 123 } 124 125 static const struct dw_pcie_host_ops rockchip_pcie_host_ops = { 126 .host_init = rockchip_pcie_host_init, 127 }; 128 129 static int rockchip_pcie_clk_init(struct rockchip_pcie *rockchip) 130 { 131 struct device *dev = rockchip->pci.dev; 132 int ret; 133 134 ret = devm_clk_bulk_get_all(dev, &rockchip->clks); 135 if (ret < 0) 136 return ret; 137 138 rockchip->clk_cnt = ret; 139 140 return clk_bulk_prepare_enable(rockchip->clk_cnt, rockchip->clks); 141 } 142 143 static int rockchip_pcie_resource_get(struct platform_device *pdev, 144 struct rockchip_pcie *rockchip) 145 { 146 rockchip->apb_base = devm_platform_ioremap_resource_byname(pdev, "apb"); 147 if (IS_ERR(rockchip->apb_base)) 148 return PTR_ERR(rockchip->apb_base); 149 150 rockchip->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", 151 GPIOD_OUT_HIGH); 152 if (IS_ERR(rockchip->rst_gpio)) 153 return PTR_ERR(rockchip->rst_gpio); 154 155 return 0; 156 } 157 158 static int rockchip_pcie_phy_init(struct rockchip_pcie *rockchip) 159 { 160 struct device *dev = rockchip->pci.dev; 161 int ret; 162 163 rockchip->phy = devm_phy_get(dev, "pcie-phy"); 164 if (IS_ERR(rockchip->phy)) 165 return dev_err_probe(dev, PTR_ERR(rockchip->phy), 166 "missing PHY\n"); 167 168 ret = phy_init(rockchip->phy); 169 if (ret < 0) 170 return ret; 171 172 ret = phy_power_on(rockchip->phy); 173 if (ret) 174 phy_exit(rockchip->phy); 175 176 return ret; 177 } 178 179 static void rockchip_pcie_phy_deinit(struct rockchip_pcie *rockchip) 180 { 181 phy_exit(rockchip->phy); 182 phy_power_off(rockchip->phy); 183 } 184 185 static int rockchip_pcie_reset_control_release(struct rockchip_pcie *rockchip) 186 { 187 struct device *dev = rockchip->pci.dev; 188 189 rockchip->rst = devm_reset_control_array_get_exclusive(dev); 190 if (IS_ERR(rockchip->rst)) 191 return dev_err_probe(dev, PTR_ERR(rockchip->rst), 192 "failed to get reset lines\n"); 193 194 return reset_control_deassert(rockchip->rst); 195 } 196 197 static const struct dw_pcie_ops dw_pcie_ops = { 198 .link_up = rockchip_pcie_link_up, 199 .start_link = rockchip_pcie_start_link, 200 }; 201 202 static int rockchip_pcie_probe(struct platform_device *pdev) 203 { 204 struct device *dev = &pdev->dev; 205 struct rockchip_pcie *rockchip; 206 struct pcie_port *pp; 207 int ret; 208 209 rockchip = devm_kzalloc(dev, sizeof(*rockchip), GFP_KERNEL); 210 if (!rockchip) 211 return -ENOMEM; 212 213 platform_set_drvdata(pdev, rockchip); 214 215 rockchip->pci.dev = dev; 216 rockchip->pci.ops = &dw_pcie_ops; 217 218 pp = &rockchip->pci.pp; 219 pp->ops = &rockchip_pcie_host_ops; 220 221 ret = rockchip_pcie_resource_get(pdev, rockchip); 222 if (ret) 223 return ret; 224 225 /* DON'T MOVE ME: must be enable before PHY init */ 226 rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); 227 if (IS_ERR(rockchip->vpcie3v3)) { 228 if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV) 229 return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3), 230 "failed to get vpcie3v3 regulator\n"); 231 rockchip->vpcie3v3 = NULL; 232 } else { 233 ret = regulator_enable(rockchip->vpcie3v3); 234 if (ret) { 235 dev_err(dev, "failed to enable vpcie3v3 regulator\n"); 236 return ret; 237 } 238 } 239 240 ret = rockchip_pcie_phy_init(rockchip); 241 if (ret) 242 goto disable_regulator; 243 244 ret = rockchip_pcie_reset_control_release(rockchip); 245 if (ret) 246 goto deinit_phy; 247 248 ret = rockchip_pcie_clk_init(rockchip); 249 if (ret) 250 goto deinit_phy; 251 252 ret = dw_pcie_host_init(pp); 253 if (!ret) 254 return 0; 255 256 clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks); 257 deinit_phy: 258 rockchip_pcie_phy_deinit(rockchip); 259 disable_regulator: 260 if (rockchip->vpcie3v3) 261 regulator_disable(rockchip->vpcie3v3); 262 263 return ret; 264 } 265 266 static const struct of_device_id rockchip_pcie_of_match[] = { 267 { .compatible = "rockchip,rk3568-pcie", }, 268 {}, 269 }; 270 271 static struct platform_driver rockchip_pcie_driver = { 272 .driver = { 273 .name = "rockchip-dw-pcie", 274 .of_match_table = rockchip_pcie_of_match, 275 .suppress_bind_attrs = true, 276 }, 277 .probe = rockchip_pcie_probe, 278 }; 279 builtin_platform_driver(rockchip_pcie_driver); 280