Message ID | 20210430012741.24811-1-xxm@rock-chips.com (mailing list archive) |
---|---|
State | Superseded |
Headers | show |
Series | [v8,1/2] dt-bindings: rockchip: Add DesignWare based PCIe controller | expand |
Hi Simon, Thank you for the patch! Yet something to improve: [auto build test ERROR on pci/next] [also build test ERROR on v5.12 next-20210430] [If your patch is applied to the wrong git tree, kindly drop us a note. And when submitting patch, we suggest to use '--base' as documented in https://git-scm.com/docs/git-format-patch] url: https://github.com/0day-ci/linux/commits/Simon-Xue/dt-bindings-rockchip-Add-DesignWare-based-PCIe-controller/20210430-092937 base: https://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git next config: microblaze-randconfig-r032-20210430 (attached as .config) compiler: microblaze-linux-gcc (GCC) 9.3.0 reproduce (this is a W=1 build): wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross chmod +x ~/bin/make.cross # https://github.com/0day-ci/linux/commit/d7f0227a3e8ea1c9594e9cec8fbd84715a987f2a git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Simon-Xue/dt-bindings-rockchip-Add-DesignWare-based-PCIe-controller/20210430-092937 git checkout d7f0227a3e8ea1c9594e9cec8fbd84715a987f2a # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=microblaze If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All error/warnings (new ones prefixed by >>): >> drivers/pci/controller/dwc/pcie-designware-host.c:49:15: error: variable 'dw_pcie_msi_domain_info' has initializer but incomplete type 49 | static struct msi_domain_info dw_pcie_msi_domain_info = { | ^~~~~~~~~~~~~~~ >> drivers/pci/controller/dwc/pcie-designware-host.c:50:3: error: 'struct msi_domain_info' has no member named 'flags' 50 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ^~~~~ >> drivers/pci/controller/dwc/pcie-designware-host.c:50:12: error: 'MSI_FLAG_USE_DEF_DOM_OPS' undeclared here (not in a function) 50 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ^~~~~~~~~~~~~~~~~~~~~~~~ >> drivers/pci/controller/dwc/pcie-designware-host.c:50:39: error: 'MSI_FLAG_USE_DEF_CHIP_OPS' undeclared here (not in a function) 50 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ^~~~~~~~~~~~~~~~~~~~~~~~~ >> drivers/pci/controller/dwc/pcie-designware-host.c:51:6: error: 'MSI_FLAG_PCI_MSIX' undeclared here (not in a function) 51 | MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), | ^~~~~~~~~~~~~~~~~ >> drivers/pci/controller/dwc/pcie-designware-host.c:51:26: error: 'MSI_FLAG_MULTI_PCI_MSI' undeclared here (not in a function) 51 | MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), | ^~~~~~~~~~~~~~~~~~~~~~ >> drivers/pci/controller/dwc/pcie-designware-host.c:50:11: warning: excess elements in struct initializer 50 | .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | | ^ drivers/pci/controller/dwc/pcie-designware-host.c:50:11: note: (near initialization for 'dw_pcie_msi_domain_info') >> drivers/pci/controller/dwc/pcie-designware-host.c:52:3: error: 'struct msi_domain_info' has no member named 'chip' 52 | .chip = &dw_pcie_msi_irq_chip, | ^~~~ drivers/pci/controller/dwc/pcie-designware-host.c:52:10: warning: excess elements in struct initializer 52 | .chip = &dw_pcie_msi_irq_chip, | ^ drivers/pci/controller/dwc/pcie-designware-host.c:52:10: note: (near initialization for 'dw_pcie_msi_domain_info') drivers/pci/controller/dwc/pcie-designware-host.c: In function 'dw_pcie_allocate_domains': >> drivers/pci/controller/dwc/pcie-designware-host.c:247:19: error: implicit declaration of function 'pci_msi_create_irq_domain'; did you mean 'pci_msi_get_device_domain'? [-Werror=implicit-function-declaration] 247 | pp->msi_domain = pci_msi_create_irq_domain(fwnode, | ^~~~~~~~~~~~~~~~~~~~~~~~~ | pci_msi_get_device_domain >> drivers/pci/controller/dwc/pcie-designware-host.c:247:17: warning: assignment to 'struct irq_domain *' from 'int' makes pointer from integer without a cast [-Wint-conversion] 247 | pp->msi_domain = pci_msi_create_irq_domain(fwnode, | ^ drivers/pci/controller/dwc/pcie-designware-host.c: At top level: >> drivers/pci/controller/dwc/pcie-designware-host.c:49:31: error: storage size of 'dw_pcie_msi_domain_info' isn't known 49 | static struct msi_domain_info dw_pcie_msi_domain_info = { | ^~~~~~~~~~~~~~~~~~~~~~~ cc1: some warnings being treated as errors Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for PCIE_DW_HOST Depends on PCI && PCI_MSI_IRQ_DOMAIN Selected by - PCIE_ROCKCHIP_DW_HOST && PCI && (ARCH_ROCKCHIP || COMPILE_TEST && OF vim +/dw_pcie_msi_domain_info +49 drivers/pci/controller/dwc/pcie-designware-host.c 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 48 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 @49 static struct msi_domain_info dw_pcie_msi_domain_info = { 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 @50 .flags = (MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS | 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 @51 MSI_FLAG_PCI_MSIX | MSI_FLAG_MULTI_PCI_MSI), 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 @52 .chip = &dw_pcie_msi_irq_chip, feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 53 }; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 54 feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 55 /* MSI int handler */ feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 56 irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 57 { feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 58 int i, pos, irq; 1137e61dcb99f7 drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2019-09-04 59 unsigned long val; 1137e61dcb99f7 drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2019-09-04 60 u32 status, num_ctrls; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 61 irqreturn_t ret = IRQ_NONE; f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 62 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 63 1f319cb0538a10 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 64 num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL; 1f319cb0538a10 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 65 1f319cb0538a10 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 66 for (i = 0; i < num_ctrls; i++) { f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 67 status = dw_pcie_readl_dbi(pci, PCIE_MSI_INTR0_STATUS + f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 68 (i * MSI_REG_CTRL_BLOCK_SIZE)); 1137e61dcb99f7 drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2019-09-04 69 if (!status) dbe4a09e8bbcf8 drivers/pci/dwc/pcie-designware-host.c Bjorn Helgaas 2017-03-16 70 continue; dbe4a09e8bbcf8 drivers/pci/dwc/pcie-designware-host.c Bjorn Helgaas 2017-03-16 71 feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 72 ret = IRQ_HANDLED; 1137e61dcb99f7 drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2019-09-04 73 val = status; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 74 pos = 0; 1137e61dcb99f7 drivers/pci/controller/dwc/pcie-designware-host.c Niklas Cassel 2019-09-04 75 while ((pos = find_next_bit(&val, MAX_MSI_IRQS_PER_CTRL, 76cbf066b1ab75 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 76 pos)) != MAX_MSI_IRQS_PER_CTRL) { 76cbf066b1ab75 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 77 irq = irq_find_mapping(pp->irq_domain, 76cbf066b1ab75 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 78 (i * MAX_MSI_IRQS_PER_CTRL) + 76cbf066b1ab75 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 79 pos); 8c934095fa2f33 drivers/pci/dwc/pcie-designware-host.c Faiz Abbas 2017-08-10 80 generic_handle_irq(irq); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 81 pos++; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 82 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 83 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 84 feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 85 return ret; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 86 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 87 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 88 /* Chained MSI interrupt service routine */ 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 89 static void dw_chained_msi_isr(struct irq_desc *desc) feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 90 { 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 91 struct irq_chip *chip = irq_desc_get_chip(desc); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 92 struct pcie_port *pp; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 93 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 94 chained_irq_enter(chip, desc); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 95 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 96 pp = irq_desc_get_handler_data(desc); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 97 dw_handle_msi_irq(pp); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 98 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 99 chained_irq_exit(chip, desc); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 100 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 101 59ea68b3f17294 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 102 static void dw_pci_setup_msi_msg(struct irq_data *d, struct msi_msg *msg) feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 103 { 59ea68b3f17294 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 104 struct pcie_port *pp = irq_data_get_irq_chip_data(d); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 105 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 106 u64 msi_target; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 107 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 108 msi_target = (u64)pp->msi_data; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 109 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 110 msg->address_lo = lower_32_bits(msi_target); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 111 msg->address_hi = upper_32_bits(msi_target); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 112 59ea68b3f17294 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 113 msg->data = d->hwirq; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 114 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 115 dev_dbg(pci->dev, "msi#%d address_hi %#x address_lo %#x\n", 59ea68b3f17294 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 116 (int)d->hwirq, msg->address_hi, msg->address_lo); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 117 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 118 fd5288a362ab55 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 119 static int dw_pci_msi_set_affinity(struct irq_data *d, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 120 const struct cpumask *mask, bool force) feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 121 { 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 122 return -EINVAL; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 123 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 124 40e9892ef94ce8 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 125 static void dw_pci_bottom_mask(struct irq_data *d) feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 126 { 40e9892ef94ce8 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 127 struct pcie_port *pp = irq_data_get_irq_chip_data(d); f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 128 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 129 unsigned int res, bit, ctrl; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 130 unsigned long flags; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 131 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 132 raw_spin_lock_irqsave(&pp->lock, flags); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 133 40e9892ef94ce8 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 134 ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; 76cbf066b1ab75 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 135 res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; 40e9892ef94ce8 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 136 bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 137 657722570a555c drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 138 pp->irq_mask[ctrl] |= BIT(bit); f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 139 dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, pp->irq_mask[ctrl]); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 140 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 141 raw_spin_unlock_irqrestore(&pp->lock, flags); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 142 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 143 40e9892ef94ce8 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 144 static void dw_pci_bottom_unmask(struct irq_data *d) 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 145 { 40e9892ef94ce8 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 146 struct pcie_port *pp = irq_data_get_irq_chip_data(d); f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 147 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 148 unsigned int res, bit, ctrl; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 149 unsigned long flags; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 150 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 151 raw_spin_lock_irqsave(&pp->lock, flags); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 152 40e9892ef94ce8 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 153 ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; 76cbf066b1ab75 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 154 res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; 40e9892ef94ce8 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 155 bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 156 657722570a555c drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 157 pp->irq_mask[ctrl] &= ~BIT(bit); f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 158 dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_MASK + res, pp->irq_mask[ctrl]); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 159 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 160 raw_spin_unlock_irqrestore(&pp->lock, flags); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 161 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 162 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 163 static void dw_pci_bottom_ack(struct irq_data *d) 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 164 { 3f7bb2ec20ce07 drivers/pci/controller/dwc/pcie-designware-host.c Marc Zyngier 2018-11-13 165 struct pcie_port *pp = irq_data_get_irq_chip_data(d); f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 166 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 3f7bb2ec20ce07 drivers/pci/controller/dwc/pcie-designware-host.c Marc Zyngier 2018-11-13 167 unsigned int res, bit, ctrl; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 168 3f7bb2ec20ce07 drivers/pci/controller/dwc/pcie-designware-host.c Marc Zyngier 2018-11-13 169 ctrl = d->hwirq / MAX_MSI_IRQS_PER_CTRL; 3f7bb2ec20ce07 drivers/pci/controller/dwc/pcie-designware-host.c Marc Zyngier 2018-11-13 170 res = ctrl * MSI_REG_CTRL_BLOCK_SIZE; 3f7bb2ec20ce07 drivers/pci/controller/dwc/pcie-designware-host.c Marc Zyngier 2018-11-13 171 bit = d->hwirq % MAX_MSI_IRQS_PER_CTRL; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 172 f81c770df72e72 drivers/pci/controller/dwc/pcie-designware-host.c Rob Herring 2020-08-20 173 dw_pcie_writel_dbi(pci, PCIE_MSI_INTR0_STATUS + res, BIT(bit)); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 174 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 175 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 176 static struct irq_chip dw_pci_msi_bottom_irq_chip = { 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 177 .name = "DWPCI-MSI", 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 178 .irq_ack = dw_pci_bottom_ack, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 179 .irq_compose_msi_msg = dw_pci_setup_msi_msg, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 180 .irq_set_affinity = dw_pci_msi_set_affinity, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 181 .irq_mask = dw_pci_bottom_mask, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 182 .irq_unmask = dw_pci_bottom_unmask, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 183 }; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 184 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 185 static int dw_pcie_irq_domain_alloc(struct irq_domain *domain, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 186 unsigned int virq, unsigned int nr_irqs, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 187 void *args) feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 188 { 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 189 struct pcie_port *pp = domain->host_data; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 190 unsigned long flags; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 191 u32 i; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 192 int bit; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 193 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 194 raw_spin_lock_irqsave(&pp->lock, flags); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 195 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 196 bit = bitmap_find_free_region(pp->msi_irq_in_use, pp->num_vectors, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 197 order_base_2(nr_irqs)); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 198 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 199 raw_spin_unlock_irqrestore(&pp->lock, flags); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 200 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 201 if (bit < 0) 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 202 return -ENOSPC; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 203 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 204 for (i = 0; i < nr_irqs; i++) 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 205 irq_domain_set_info(domain, virq + i, bit + i, 9f67437b3a0858 drivers/pci/controller/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2019-03-21 206 pp->msi_irq_chip, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 207 pp, handle_edge_irq, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 208 NULL, NULL); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 209 feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 210 return 0; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 211 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 212 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 213 static void dw_pcie_irq_domain_free(struct irq_domain *domain, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 214 unsigned int virq, unsigned int nr_irqs) feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 215 { 4cfae0f1f8ce16 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 216 struct irq_data *d = irq_domain_get_irq_data(domain, virq); 03f8c1b350d001 drivers/pci/controller/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2019-12-20 217 struct pcie_port *pp = domain->host_data; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 218 unsigned long flags; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 219 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 220 raw_spin_lock_irqsave(&pp->lock, flags); b4a8a51caf7de4 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 221 4cfae0f1f8ce16 drivers/pci/controller/dwc/pcie-designware-host.c Gustavo Pimentel 2019-01-31 222 bitmap_release_region(pp->msi_irq_in_use, d->hwirq, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 223 order_base_2(nr_irqs)); b4a8a51caf7de4 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 224 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 225 raw_spin_unlock_irqrestore(&pp->lock, flags); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 226 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 227 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 228 static const struct irq_domain_ops dw_pcie_msi_domain_ops = { 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 229 .alloc = dw_pcie_irq_domain_alloc, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 230 .free = dw_pcie_irq_domain_free, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 231 }; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 232 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 233 int dw_pcie_allocate_domains(struct pcie_port *pp) 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 234 { 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 235 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 236 struct fwnode_handle *fwnode = of_node_to_fwnode(pci->dev->of_node); feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 237 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 238 pp->irq_domain = irq_domain_create_linear(fwnode, pp->num_vectors, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 239 &dw_pcie_msi_domain_ops, pp); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 240 if (!pp->irq_domain) { b4a8a51caf7de4 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 241 dev_err(pci->dev, "Failed to create IRQ domain\n"); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 242 return -ENOMEM; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 243 } 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 244 0414b93e78d87e drivers/pci/controller/dwc/pcie-designware-host.c Marc Zyngier 2020-05-01 245 irq_domain_update_bus_token(pp->irq_domain, DOMAIN_BUS_NEXUS); 0414b93e78d87e drivers/pci/controller/dwc/pcie-designware-host.c Marc Zyngier 2020-05-01 246 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 @247 pp->msi_domain = pci_msi_create_irq_domain(fwnode, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 248 &dw_pcie_msi_domain_info, 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 249 pp->irq_domain); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 250 if (!pp->msi_domain) { b4a8a51caf7de4 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-05-14 251 dev_err(pci->dev, "Failed to create MSI domain\n"); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 252 irq_domain_remove(pp->irq_domain); 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 253 return -ENOMEM; 7c5925afbc58c6 drivers/pci/dwc/pcie-designware-host.c Gustavo Pimentel 2018-03-06 254 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 255 feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 256 return 0; feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 257 } feb85d9b1c47ea drivers/pci/dwc/pcie-designware-host.c Kishon Vijay Abraham I 2017-02-15 258 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org
diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig index b9aaa84452c4..a4d0e0c2f503 100644 --- a/drivers/pci/controller/dwc/Kconfig +++ b/drivers/pci/controller/dwc/Kconfig @@ -214,6 +214,16 @@ config PCIE_ARTPEC6_EP Enables support for the PCIe controller in the ARTPEC-6 SoC to work in endpoint mode. This uses the DesignWare core. +config PCIE_ROCKCHIP_DW_HOST + bool "Rockchip DesignWare PCIe controller" + select PCIE_DW + select PCIE_DW_HOST + depends on ARCH_ROCKCHIP || COMPILE_TEST + depends on OF + help + Enables support for the DesignWare PCIe controller in the + Rockchip SoC except RK3399. + config PCIE_INTEL_GW bool "Intel Gateway PCIe host controller support" depends on OF && (X86 || COMPILE_TEST) diff --git a/drivers/pci/controller/dwc/Makefile b/drivers/pci/controller/dwc/Makefile index 912b8ad5fc85..eeb7f2d57b2d 100644 --- a/drivers/pci/controller/dwc/Makefile +++ b/drivers/pci/controller/dwc/Makefile @@ -13,6 +13,7 @@ obj-$(CONFIG_PCI_LAYERSCAPE_EP) += pci-layerscape-ep.o obj-$(CONFIG_PCIE_QCOM) += pcie-qcom.o obj-$(CONFIG_PCIE_ARMADA_8K) += pcie-armada8k.o obj-$(CONFIG_PCIE_ARTPEC6) += pcie-artpec6.o +obj-$(CONFIG_PCIE_ROCKCHIP_DW_HOST) += pcie-dw-rockchip.o obj-$(CONFIG_PCIE_INTEL_GW) += pcie-intel-gw.o obj-$(CONFIG_PCIE_KIRIN) += pcie-kirin.o obj-$(CONFIG_PCIE_HISI_STB) += pcie-histb.o diff --git a/drivers/pci/controller/dwc/pcie-dw-rockchip.c b/drivers/pci/controller/dwc/pcie-dw-rockchip.c new file mode 100644 index 000000000000..3f060144eeab --- /dev/null +++ b/drivers/pci/controller/dwc/pcie-dw-rockchip.c @@ -0,0 +1,277 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * PCIe host controller driver for Rockchip SoCs. + * + * Copyright (C) 2021 Rockchip Electronics Co., Ltd. + * http://www.rock-chips.com + * + * Author: Simon Xue <xxm@rock-chips.com> + */ + +#include <linux/clk.h> +#include <linux/gpio/consumer.h> +#include <linux/mfd/syscon.h> +#include <linux/module.h> +#include <linux/of_device.h> +#include <linux/phy/phy.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/reset.h> + +#include "pcie-designware.h" + +/* + * The upper 16 bits of PCIE_CLIENT_CONFIG are a write + * mask for the lower 16 bits. + */ +#define HIWORD_UPDATE(mask, val) (((mask) << 16) | (val)) +#define HIWORD_UPDATE_BIT(val) HIWORD_UPDATE(val, val) + +#define to_rockchip_pcie(x) dev_get_drvdata((x)->dev) + +#define PCIE_CLIENT_RC_MODE HIWORD_UPDATE_BIT(0x40) +#define PCIE_CLIENT_ENABLE_LTSSM HIWORD_UPDATE_BIT(0xc) +#define PCIE_SMLH_LINKUP BIT(16) +#define PCIE_RDLH_LINKUP BIT(17) +#define PCIE_LINKUP (PCIE_SMLH_LINKUP | PCIE_RDLH_LINKUP) +#define PCIE_L0S_ENTRY 0x11 +#define PCIE_CLIENT_GENERAL_CONTROL 0x0 +#define PCIE_CLIENT_GENERAL_DEBUG 0x104 +#define PCIE_CLIENT_HOT_RESET_CTRL 0x180 +#define PCIE_CLIENT_LTSSM_STATUS 0x300 +#define PCIE_LTSSM_ENABLE_ENHANCE BIT(4) + +struct rockchip_pcie { + struct dw_pcie pci; + void __iomem *apb_base; + struct phy *phy; + struct clk_bulk_data *clks; + unsigned int clk_cnt; + struct reset_control *rst; + struct gpio_desc *rst_gpio; + struct regulator *vpcie3v3; +}; + +static int rockchip_pcie_readl_apb(struct rockchip_pcie *rockchip, + u32 reg) +{ + return readl(rockchip->apb_base + reg); +} + +static void rockchip_pcie_writel_apb(struct rockchip_pcie *rockchip, + u32 val, u32 reg) +{ + writel(val, rockchip->apb_base + reg); +} + +static void rockchip_pcie_enable_ltssm(struct rockchip_pcie *rockchip) +{ + rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_ENABLE_LTSSM, + PCIE_CLIENT_GENERAL_CONTROL); +} + +static int rockchip_pcie_link_up(struct dw_pcie *pci) +{ + struct rockchip_pcie *rockchip = to_rockchip_pcie(pci); + u32 val = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_LTSSM_STATUS); + + if ((val & (PCIE_RDLH_LINKUP | PCIE_SMLH_LINKUP)) == PCIE_LINKUP && + (val & GENMASK(5, 0)) == PCIE_L0S_ENTRY) + return 1; + + return 0; +} + +static int rockchip_pcie_start_link(struct dw_pcie *pci) +{ + struct rockchip_pcie *rockchip = to_rockchip_pcie(pci); + + /* Reset device */ + gpiod_set_value_cansleep(rockchip->rst_gpio, 0); + + rockchip_pcie_enable_ltssm(rockchip); + + /* + * PCIe requires the refclk to be stable for 100µs prior to releasing + * PERST. See table 2-4 in section 2.6.2 AC Specifications of the PCI + * Express Card Electromechanical Specification, 1.1. However, we don't + * know if the refclk is coming from RC's PHY or external OSC. If it's + * from RC, so enabling LTSSM is the just right place to release #PERST. + * We need more extra time as before, rather than setting just + * 100us as we don't know how long should the device need to reset. + */ + msleep(100); + gpiod_set_value_cansleep(rockchip->rst_gpio, 1); + + return 0; +} + +static int rockchip_pcie_host_init(struct pcie_port *pp) +{ + struct dw_pcie *pci = to_dw_pcie_from_pp(pp); + struct rockchip_pcie *rockchip = to_rockchip_pcie(pci); + u32 val; + + /* LTSSM enable control mode */ + val = rockchip_pcie_readl_apb(rockchip, PCIE_CLIENT_HOT_RESET_CTRL); + val |= PCIE_LTSSM_ENABLE_ENHANCE | (PCIE_LTSSM_ENABLE_ENHANCE << 16); + rockchip_pcie_writel_apb(rockchip, val, PCIE_CLIENT_HOT_RESET_CTRL); + + rockchip_pcie_writel_apb(rockchip, PCIE_CLIENT_RC_MODE, + PCIE_CLIENT_GENERAL_CONTROL); + + return 0; +} + +static const struct dw_pcie_host_ops rockchip_pcie_host_ops = { + .host_init = rockchip_pcie_host_init, +}; + +static int rockchip_pcie_clk_init(struct rockchip_pcie *rockchip) +{ + struct device *dev = rockchip->pci.dev; + int ret; + + ret = devm_clk_bulk_get_all(dev, &rockchip->clks); + if (ret < 0) + return ret; + + rockchip->clk_cnt = ret; + + return clk_bulk_prepare_enable(rockchip->clk_cnt, rockchip->clks); +} + +static int rockchip_pcie_resource_get(struct platform_device *pdev, + struct rockchip_pcie *rockchip) +{ + rockchip->apb_base = devm_platform_ioremap_resource_byname(pdev, "apb"); + if (IS_ERR(rockchip->apb_base)) + return PTR_ERR(rockchip->apb_base); + + rockchip->rst_gpio = devm_gpiod_get_optional(&pdev->dev, "reset", + GPIOD_OUT_HIGH); + if (IS_ERR(rockchip->rst_gpio)) + return PTR_ERR(rockchip->rst_gpio); + + return 0; +} + +static int rockchip_pcie_phy_init(struct rockchip_pcie *rockchip) +{ + struct device *dev = rockchip->pci.dev; + int ret; + + rockchip->phy = devm_phy_get(dev, "pcie-phy"); + if (IS_ERR(rockchip->phy)) + return dev_err_probe(dev, PTR_ERR(rockchip->phy), + "missing PHY\n"); + + ret = phy_init(rockchip->phy); + if (ret < 0) + return ret; + + ret = phy_power_on(rockchip->phy); + if (ret) + phy_exit(rockchip->phy); + + return ret; +} + +static void rockchip_pcie_phy_deinit(struct rockchip_pcie *rockchip) +{ + phy_exit(rockchip->phy); + phy_power_off(rockchip->phy); +} + +static int rockchip_pcie_reset_control_release(struct rockchip_pcie *rockchip) +{ + struct device *dev = rockchip->pci.dev; + + rockchip->rst = devm_reset_control_array_get_exclusive(dev); + if (IS_ERR(rockchip->rst)) + return dev_err_probe(dev, PTR_ERR(rockchip->rst), + "failed to get reset lines\n"); + + return reset_control_deassert(rockchip->rst); +} + +static const struct dw_pcie_ops dw_pcie_ops = { + .link_up = rockchip_pcie_link_up, + .start_link = rockchip_pcie_start_link, +}; + +static int rockchip_pcie_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct rockchip_pcie *rockchip; + struct pcie_port *pp; + int ret; + + rockchip = devm_kzalloc(dev, sizeof(*rockchip), GFP_KERNEL); + if (!rockchip) + return -ENOMEM; + + platform_set_drvdata(pdev, rockchip); + + rockchip->pci.dev = dev; + rockchip->pci.ops = &dw_pcie_ops; + + pp = &rockchip->pci.pp; + pp->ops = &rockchip_pcie_host_ops; + + ret = rockchip_pcie_resource_get(pdev, rockchip); + if (ret) + return ret; + + /* DON'T MOVE ME: must be enable before PHY init */ + rockchip->vpcie3v3 = devm_regulator_get_optional(dev, "vpcie3v3"); + if (IS_ERR(rockchip->vpcie3v3)) + if (PTR_ERR(rockchip->vpcie3v3) != -ENODEV) + return dev_err_probe(dev, PTR_ERR(rockchip->vpcie3v3), + "failed to get vpcie3v3 regulator\n"); + + ret = regulator_enable(rockchip->vpcie3v3); + if (ret) { + dev_err(dev, "failed to enable vpcie3v3 regulator\n"); + return ret; + } + + ret = rockchip_pcie_phy_init(rockchip); + if (ret) + goto disable_regulator; + + ret = rockchip_pcie_reset_control_release(rockchip); + if (ret) + goto deinit_phy; + + ret = rockchip_pcie_clk_init(rockchip); + if (ret) + goto deinit_phy; + + ret = dw_pcie_host_init(pp); + if (!ret) + return 0; + + clk_bulk_disable_unprepare(rockchip->clk_cnt, rockchip->clks); +deinit_phy: + rockchip_pcie_phy_deinit(rockchip); +disable_regulator: + regulator_disable(rockchip->vpcie3v3); + + return ret; +} + +static const struct of_device_id rockchip_pcie_of_match[] = { + { .compatible = "rockchip,rk3568-pcie", }, + {}, +}; + +static struct platform_driver rockchip_pcie_driver = { + .driver = { + .name = "rockchip-dw-pcie", + .of_match_table = rockchip_pcie_of_match, + .suppress_bind_attrs = true, + }, + .probe = rockchip_pcie_probe, +}; +builtin_platform_driver(rockchip_pcie_driver);