pcie-histb.c (11235B)
1// SPDX-License-Identifier: GPL-2.0 2/* 3 * PCIe host controller driver for HiSilicon STB SoCs 4 * 5 * Copyright (C) 2016-2017 HiSilicon Co., Ltd. http://www.hisilicon.com 6 * 7 * Authors: Ruqiang Ju <juruqiang@hisilicon.com> 8 * Jianguo Sun <sunjianguo1@huawei.com> 9 */ 10 11#include <linux/clk.h> 12#include <linux/delay.h> 13#include <linux/interrupt.h> 14#include <linux/kernel.h> 15#include <linux/module.h> 16#include <linux/of.h> 17#include <linux/of_gpio.h> 18#include <linux/pci.h> 19#include <linux/phy/phy.h> 20#include <linux/platform_device.h> 21#include <linux/resource.h> 22#include <linux/reset.h> 23 24#include "pcie-designware.h" 25 26#define to_histb_pcie(x) dev_get_drvdata((x)->dev) 27 28#define PCIE_SYS_CTRL0 0x0000 29#define PCIE_SYS_CTRL1 0x0004 30#define PCIE_SYS_CTRL7 0x001C 31#define PCIE_SYS_CTRL13 0x0034 32#define PCIE_SYS_CTRL15 0x003C 33#define PCIE_SYS_CTRL16 0x0040 34#define PCIE_SYS_CTRL17 0x0044 35 36#define PCIE_SYS_STAT0 0x0100 37#define PCIE_SYS_STAT4 0x0110 38 39#define PCIE_RDLH_LINK_UP BIT(5) 40#define PCIE_XMLH_LINK_UP BIT(15) 41#define PCIE_ELBI_SLV_DBI_ENABLE BIT(21) 42#define PCIE_APP_LTSSM_ENABLE BIT(11) 43 44#define PCIE_DEVICE_TYPE_MASK GENMASK(31, 28) 45#define PCIE_WM_EP 0 46#define PCIE_WM_LEGACY BIT(1) 47#define PCIE_WM_RC BIT(30) 48 49#define PCIE_LTSSM_STATE_MASK GENMASK(5, 0) 50#define PCIE_LTSSM_STATE_ACTIVE 0x11 51 52struct histb_pcie { 53 struct dw_pcie *pci; 54 struct clk *aux_clk; 55 struct clk *pipe_clk; 56 struct clk *sys_clk; 57 struct clk *bus_clk; 58 struct phy *phy; 59 struct reset_control *soft_reset; 60 struct reset_control *sys_reset; 61 struct reset_control *bus_reset; 62 void __iomem *ctrl; 63 int reset_gpio; 64 struct regulator *vpcie; 65}; 66 67static u32 histb_pcie_readl(struct histb_pcie *histb_pcie, u32 reg) 68{ 69 return readl(histb_pcie->ctrl + reg); 70} 71 72static void histb_pcie_writel(struct histb_pcie *histb_pcie, u32 reg, u32 val) 73{ 74 writel(val, histb_pcie->ctrl + reg); 75} 76 77static void histb_pcie_dbi_w_mode(struct pcie_port *pp, bool enable) 78{ 79 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 80 struct histb_pcie *hipcie = to_histb_pcie(pci); 81 u32 val; 82 83 val = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0); 84 if (enable) 85 val |= PCIE_ELBI_SLV_DBI_ENABLE; 86 else 87 val &= ~PCIE_ELBI_SLV_DBI_ENABLE; 88 histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, val); 89} 90 91static void histb_pcie_dbi_r_mode(struct pcie_port *pp, bool enable) 92{ 93 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 94 struct histb_pcie *hipcie = to_histb_pcie(pci); 95 u32 val; 96 97 val = histb_pcie_readl(hipcie, PCIE_SYS_CTRL1); 98 if (enable) 99 val |= PCIE_ELBI_SLV_DBI_ENABLE; 100 else 101 val &= ~PCIE_ELBI_SLV_DBI_ENABLE; 102 histb_pcie_writel(hipcie, PCIE_SYS_CTRL1, val); 103} 104 105static u32 histb_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, 106 u32 reg, size_t size) 107{ 108 u32 val; 109 110 histb_pcie_dbi_r_mode(&pci->pp, true); 111 dw_pcie_read(base + reg, size, &val); 112 histb_pcie_dbi_r_mode(&pci->pp, false); 113 114 return val; 115} 116 117static void histb_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, 118 u32 reg, size_t size, u32 val) 119{ 120 histb_pcie_dbi_w_mode(&pci->pp, true); 121 dw_pcie_write(base + reg, size, val); 122 histb_pcie_dbi_w_mode(&pci->pp, false); 123} 124 125static int histb_pcie_rd_own_conf(struct pci_bus *bus, unsigned int devfn, 126 int where, int size, u32 *val) 127{ 128 struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); 129 130 if (PCI_SLOT(devfn)) 131 return PCIBIOS_DEVICE_NOT_FOUND; 132 133 *val = dw_pcie_read_dbi(pci, where, size); 134 return PCIBIOS_SUCCESSFUL; 135} 136 137static int histb_pcie_wr_own_conf(struct pci_bus *bus, unsigned int devfn, 138 int where, int size, u32 val) 139{ 140 struct dw_pcie *pci = to_dw_pcie_from_pp(bus->sysdata); 141 142 if (PCI_SLOT(devfn)) 143 return PCIBIOS_DEVICE_NOT_FOUND; 144 145 dw_pcie_write_dbi(pci, where, size, val); 146 return PCIBIOS_SUCCESSFUL; 147} 148 149static struct pci_ops histb_pci_ops = { 150 .read = histb_pcie_rd_own_conf, 151 .write = histb_pcie_wr_own_conf, 152}; 153 154static int histb_pcie_link_up(struct dw_pcie *pci) 155{ 156 struct histb_pcie *hipcie = to_histb_pcie(pci); 157 u32 regval; 158 u32 status; 159 160 regval = histb_pcie_readl(hipcie, PCIE_SYS_STAT0); 161 status = histb_pcie_readl(hipcie, PCIE_SYS_STAT4); 162 status &= PCIE_LTSSM_STATE_MASK; 163 if ((regval & PCIE_XMLH_LINK_UP) && (regval & PCIE_RDLH_LINK_UP) && 164 (status == PCIE_LTSSM_STATE_ACTIVE)) 165 return 1; 166 167 return 0; 168} 169 170static int histb_pcie_start_link(struct dw_pcie *pci) 171{ 172 struct histb_pcie *hipcie = to_histb_pcie(pci); 173 u32 regval; 174 175 /* assert LTSSM enable */ 176 regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL7); 177 regval |= PCIE_APP_LTSSM_ENABLE; 178 histb_pcie_writel(hipcie, PCIE_SYS_CTRL7, regval); 179 180 return 0; 181} 182 183static int histb_pcie_host_init(struct pcie_port *pp) 184{ 185 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 186 struct histb_pcie *hipcie = to_histb_pcie(pci); 187 u32 regval; 188 189 pp->bridge->ops = &histb_pci_ops; 190 191 /* PCIe RC work mode */ 192 regval = histb_pcie_readl(hipcie, PCIE_SYS_CTRL0); 193 regval &= ~PCIE_DEVICE_TYPE_MASK; 194 regval |= PCIE_WM_RC; 195 histb_pcie_writel(hipcie, PCIE_SYS_CTRL0, regval); 196 197 return 0; 198} 199 200static const struct dw_pcie_host_ops histb_pcie_host_ops = { 201 .host_init = histb_pcie_host_init, 202}; 203 204static void histb_pcie_host_disable(struct histb_pcie *hipcie) 205{ 206 reset_control_assert(hipcie->soft_reset); 207 reset_control_assert(hipcie->sys_reset); 208 reset_control_assert(hipcie->bus_reset); 209 210 clk_disable_unprepare(hipcie->aux_clk); 211 clk_disable_unprepare(hipcie->pipe_clk); 212 clk_disable_unprepare(hipcie->sys_clk); 213 clk_disable_unprepare(hipcie->bus_clk); 214 215 if (gpio_is_valid(hipcie->reset_gpio)) 216 gpio_set_value_cansleep(hipcie->reset_gpio, 0); 217 218 if (hipcie->vpcie) 219 regulator_disable(hipcie->vpcie); 220} 221 222static int histb_pcie_host_enable(struct pcie_port *pp) 223{ 224 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 225 struct histb_pcie *hipcie = to_histb_pcie(pci); 226 struct device *dev = pci->dev; 227 int ret; 228 229 /* power on PCIe device if have */ 230 if (hipcie->vpcie) { 231 ret = regulator_enable(hipcie->vpcie); 232 if (ret) { 233 dev_err(dev, "failed to enable regulator: %d\n", ret); 234 return ret; 235 } 236 } 237 238 if (gpio_is_valid(hipcie->reset_gpio)) 239 gpio_set_value_cansleep(hipcie->reset_gpio, 1); 240 241 ret = clk_prepare_enable(hipcie->bus_clk); 242 if (ret) { 243 dev_err(dev, "cannot prepare/enable bus clk\n"); 244 goto err_bus_clk; 245 } 246 247 ret = clk_prepare_enable(hipcie->sys_clk); 248 if (ret) { 249 dev_err(dev, "cannot prepare/enable sys clk\n"); 250 goto err_sys_clk; 251 } 252 253 ret = clk_prepare_enable(hipcie->pipe_clk); 254 if (ret) { 255 dev_err(dev, "cannot prepare/enable pipe clk\n"); 256 goto err_pipe_clk; 257 } 258 259 ret = clk_prepare_enable(hipcie->aux_clk); 260 if (ret) { 261 dev_err(dev, "cannot prepare/enable aux clk\n"); 262 goto err_aux_clk; 263 } 264 265 reset_control_assert(hipcie->soft_reset); 266 reset_control_deassert(hipcie->soft_reset); 267 268 reset_control_assert(hipcie->sys_reset); 269 reset_control_deassert(hipcie->sys_reset); 270 271 reset_control_assert(hipcie->bus_reset); 272 reset_control_deassert(hipcie->bus_reset); 273 274 return 0; 275 276err_aux_clk: 277 clk_disable_unprepare(hipcie->pipe_clk); 278err_pipe_clk: 279 clk_disable_unprepare(hipcie->sys_clk); 280err_sys_clk: 281 clk_disable_unprepare(hipcie->bus_clk); 282err_bus_clk: 283 if (hipcie->vpcie) 284 regulator_disable(hipcie->vpcie); 285 286 return ret; 287} 288 289static const struct dw_pcie_ops dw_pcie_ops = { 290 .read_dbi = histb_pcie_read_dbi, 291 .write_dbi = histb_pcie_write_dbi, 292 .link_up = histb_pcie_link_up, 293 .start_link = histb_pcie_start_link, 294}; 295 296static int histb_pcie_probe(struct platform_device *pdev) 297{ 298 struct histb_pcie *hipcie; 299 struct dw_pcie *pci; 300 struct pcie_port *pp; 301 struct device_node *np = pdev->dev.of_node; 302 struct device *dev = &pdev->dev; 303 enum of_gpio_flags of_flags; 304 unsigned long flag = GPIOF_DIR_OUT; 305 int ret; 306 307 hipcie = devm_kzalloc(dev, sizeof(*hipcie), GFP_KERNEL); 308 if (!hipcie) 309 return -ENOMEM; 310 311 pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL); 312 if (!pci) 313 return -ENOMEM; 314 315 hipcie->pci = pci; 316 pp = &pci->pp; 317 pci->dev = dev; 318 pci->ops = &dw_pcie_ops; 319 320 hipcie->ctrl = devm_platform_ioremap_resource_byname(pdev, "control"); 321 if (IS_ERR(hipcie->ctrl)) { 322 dev_err(dev, "cannot get control reg base\n"); 323 return PTR_ERR(hipcie->ctrl); 324 } 325 326 pci->dbi_base = devm_platform_ioremap_resource_byname(pdev, "rc-dbi"); 327 if (IS_ERR(pci->dbi_base)) { 328 dev_err(dev, "cannot get rc-dbi base\n"); 329 return PTR_ERR(pci->dbi_base); 330 } 331 332 hipcie->vpcie = devm_regulator_get_optional(dev, "vpcie"); 333 if (IS_ERR(hipcie->vpcie)) { 334 if (PTR_ERR(hipcie->vpcie) != -ENODEV) 335 return PTR_ERR(hipcie->vpcie); 336 hipcie->vpcie = NULL; 337 } 338 339 hipcie->reset_gpio = of_get_named_gpio_flags(np, 340 "reset-gpios", 0, &of_flags); 341 if (of_flags & OF_GPIO_ACTIVE_LOW) 342 flag |= GPIOF_ACTIVE_LOW; 343 if (gpio_is_valid(hipcie->reset_gpio)) { 344 ret = devm_gpio_request_one(dev, hipcie->reset_gpio, 345 flag, "PCIe device power control"); 346 if (ret) { 347 dev_err(dev, "unable to request gpio\n"); 348 return ret; 349 } 350 } 351 352 hipcie->aux_clk = devm_clk_get(dev, "aux"); 353 if (IS_ERR(hipcie->aux_clk)) { 354 dev_err(dev, "Failed to get PCIe aux clk\n"); 355 return PTR_ERR(hipcie->aux_clk); 356 } 357 358 hipcie->pipe_clk = devm_clk_get(dev, "pipe"); 359 if (IS_ERR(hipcie->pipe_clk)) { 360 dev_err(dev, "Failed to get PCIe pipe clk\n"); 361 return PTR_ERR(hipcie->pipe_clk); 362 } 363 364 hipcie->sys_clk = devm_clk_get(dev, "sys"); 365 if (IS_ERR(hipcie->sys_clk)) { 366 dev_err(dev, "Failed to get PCIEe sys clk\n"); 367 return PTR_ERR(hipcie->sys_clk); 368 } 369 370 hipcie->bus_clk = devm_clk_get(dev, "bus"); 371 if (IS_ERR(hipcie->bus_clk)) { 372 dev_err(dev, "Failed to get PCIe bus clk\n"); 373 return PTR_ERR(hipcie->bus_clk); 374 } 375 376 hipcie->soft_reset = devm_reset_control_get(dev, "soft"); 377 if (IS_ERR(hipcie->soft_reset)) { 378 dev_err(dev, "couldn't get soft reset\n"); 379 return PTR_ERR(hipcie->soft_reset); 380 } 381 382 hipcie->sys_reset = devm_reset_control_get(dev, "sys"); 383 if (IS_ERR(hipcie->sys_reset)) { 384 dev_err(dev, "couldn't get sys reset\n"); 385 return PTR_ERR(hipcie->sys_reset); 386 } 387 388 hipcie->bus_reset = devm_reset_control_get(dev, "bus"); 389 if (IS_ERR(hipcie->bus_reset)) { 390 dev_err(dev, "couldn't get bus reset\n"); 391 return PTR_ERR(hipcie->bus_reset); 392 } 393 394 hipcie->phy = devm_phy_get(dev, "phy"); 395 if (IS_ERR(hipcie->phy)) { 396 dev_info(dev, "no pcie-phy found\n"); 397 hipcie->phy = NULL; 398 /* fall through here! 399 * if no pcie-phy found, phy init 400 * should be done under boot! 401 */ 402 } else { 403 phy_init(hipcie->phy); 404 } 405 406 pp->ops = &histb_pcie_host_ops; 407 408 platform_set_drvdata(pdev, hipcie); 409 410 ret = histb_pcie_host_enable(pp); 411 if (ret) { 412 dev_err(dev, "failed to enable host\n"); 413 return ret; 414 } 415 416 ret = dw_pcie_host_init(pp); 417 if (ret) { 418 dev_err(dev, "failed to initialize host\n"); 419 return ret; 420 } 421 422 return 0; 423} 424 425static int histb_pcie_remove(struct platform_device *pdev) 426{ 427 struct histb_pcie *hipcie = platform_get_drvdata(pdev); 428 429 histb_pcie_host_disable(hipcie); 430 431 if (hipcie->phy) 432 phy_exit(hipcie->phy); 433 434 return 0; 435} 436 437static const struct of_device_id histb_pcie_of_match[] = { 438 { .compatible = "hisilicon,hi3798cv200-pcie", }, 439 {}, 440}; 441MODULE_DEVICE_TABLE(of, histb_pcie_of_match); 442 443static struct platform_driver histb_pcie_platform_driver = { 444 .probe = histb_pcie_probe, 445 .remove = histb_pcie_remove, 446 .driver = { 447 .name = "histb-pcie", 448 .of_match_table = histb_pcie_of_match, 449 }, 450}; 451module_platform_driver(histb_pcie_platform_driver); 452 453MODULE_DESCRIPTION("HiSilicon STB PCIe host controller driver"); 454MODULE_LICENSE("GPL v2");