Em Wed, 3 Feb 2021 08:34:21 -0600 Rob Herring <robh@xxxxxxxxxx> escreveu: > On Wed, Feb 3, 2021 at 1:02 AM Mauro Carvalho Chehab > <mchehab+huawei@xxxxxxxxxx> wrote: > > > > From: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> > > > > Add support for HiSilicon Kirin 970 (hi3670) SoC PCIe controller, based > > on Synopsys DesignWare PCIe controller IP. > > > > [mchehab+huawei@xxxxxxxxxx: fix merge conflicts] > > Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@xxxxxxxxxx> > > Signed-off-by: Mauro Carvalho Chehab <mchehab+huawei@xxxxxxxxxx> > > --- > > drivers/pci/controller/dwc/pcie-kirin.c | 723 +++++++++++++++++++++++- > > 1 file changed, 707 insertions(+), 16 deletions(-) > > > > diff --git a/drivers/pci/controller/dwc/pcie-kirin.c b/drivers/pci/controller/dwc/pcie-kirin.c > > index 026fd1e42a55..5925d2b345a8 100644 > > --- a/drivers/pci/controller/dwc/pcie-kirin.c > > +++ b/drivers/pci/controller/dwc/pcie-kirin.c > > @@ -29,6 +29,7 @@ > > #define to_kirin_pcie(x) dev_get_drvdata((x)->dev) > > > > #define REF_CLK_FREQ 100000000 > > +#define AXI_CLK_FREQ 207500000 > > > > /* PCIe ELBI registers */ > > #define SOC_PCIECTRL_CTRL0_ADDR 0x000 > > @@ -60,6 +61,65 @@ > > #define PCIE_DEBOUNCE_PARAM 0xF0F400 > > #define PCIE_OE_BYPASS (0x3 << 28) > > > > +/* PCIe CTRL registers */ > > +#define SOC_PCIECTRL_CTRL0_ADDR 0x000 > > +#define SOC_PCIECTRL_CTRL1_ADDR 0x004 > > +#define SOC_PCIECTRL_CTRL7_ADDR 0x01c > > +#define SOC_PCIECTRL_CTRL12_ADDR 0x030 > > +#define SOC_PCIECTRL_CTRL20_ADDR 0x050 > > +#define SOC_PCIECTRL_CTRL21_ADDR 0x054 > > +#define SOC_PCIECTRL_STATE0_ADDR 0x400 > > + > > +/* PCIe PHY registers */ > > +#define SOC_PCIEPHY_CTRL0_ADDR 0x000 > > +#define SOC_PCIEPHY_CTRL1_ADDR 0x004 > > +#define SOC_PCIEPHY_CTRL2_ADDR 0x008 > > +#define SOC_PCIEPHY_CTRL3_ADDR 0x00c > > +#define SOC_PCIEPHY_CTRL38_ADDR 0x0098 > > +#define SOC_PCIEPHY_STATE0_ADDR 0x400 > > + > > +#define PCIE_LINKUP_ENABLE (0x8020) > > +#define PCIE_ELBI_SLV_DBI_ENABLE (0x1 << 21) > > +#define PCIE_LTSSM_ENABLE_BIT (0x1 << 11) > > +#define PCIEPHY_RESET_BIT (0x1 << 17) > > +#define PCIEPHY_PIPE_LINE0_RESET_BIT (0x1 << 19) > > + > > +#define PORT_MSI_CTRL_ADDR 0x820 > > +#define PORT_MSI_CTRL_UPPER_ADDR 0x824 > > +#define PORT_MSI_CTRL_INT0_ENABLE 0x828 > > These are common DWC 'port logic' registers. I think the core DWC > should handle them if not already. I'll double-check if are there something that can be dropped. > > > + > > +#define EYEPARAM_NOCFG 0xFFFFFFFF > > +#define RAWLANEN_DIG_PCS_XF_TX_OVRD_IN_1 0x3001 > > +#define SUP_DIG_LVL_OVRD_IN 0xf > > +#define LANEN_DIG_ASIC_TX_OVRD_IN_1 0x1002 > > +#define LANEN_DIG_ASIC_TX_OVRD_IN_2 0x1003 > > + > > +/* kirin970 pciephy register */ > > +#define SOC_PCIEPHY_MMC1PLL_CTRL1 0xc04 > > +#define SOC_PCIEPHY_MMC1PLL_CTRL16 0xC40 > > +#define SOC_PCIEPHY_MMC1PLL_CTRL17 0xC44 > > +#define SOC_PCIEPHY_MMC1PLL_CTRL20 0xC50 > > +#define SOC_PCIEPHY_MMC1PLL_CTRL21 0xC54 > > +#define SOC_PCIEPHY_MMC1PLL_STAT0 0xE00 > > This looks like it is almost all phy related. I think it should all be > moved to a separate phy driver. Yes, we have some other PCI drivers > controlling their phys directly where the phy registers are > intermingled with the PCI host registers, but I think those either > predate the phy subsystem or are really simple. I also have a dream to > move all the phy control to the DWC core code. Yeah, it sounds so. I'll check how hard would be to split this code into a phy driver on a separate patch. > > +struct kirin_pcie_ops { > > + long (*get_resource)(struct kirin_pcie *kirin_pcie, > > + struct platform_device *pdev); > > + int (*power_on)(struct kirin_pcie *kirin_pcie); > > Never need to power off? This driver uses devm_*() to allocate its resources, and doesn't even uses builtin_platform_driver(kirin_pcie_driver) to register. So, at the current state, it doesn't need a poweroff. This "power_on" method is actually the device-specific part of the probe: depending on the compatible, it either runs the Kirin 960 or the new Kirin 970 variant. I'll try to double-check this when trying to split the PHY logic from the driver. > > +static long kirin970_pcie_get_resource(struct kirin_pcie *kirin_pcie, > > + struct platform_device *pdev) > > +{ > > + struct device *dev = &pdev->dev; > > + struct resource *apb; > > + struct resource *phy; > > + struct resource *dbi; > > + int ret; > > + > > + apb = platform_get_resource_byname(pdev, IORESOURCE_MEM, "apb"); > > + kirin_pcie->apb_base = devm_ioremap_resource(dev, apb); > > + if (IS_ERR(kirin_pcie->apb_base)) > > + return PTR_ERR(kirin_pcie->apb_base); > > + > > + phy = platform_get_resource_byname(pdev, IORESOURCE_MEM, "phy"); > > + kirin_pcie->phy_base = devm_ioremap_resource(dev, phy); > > + if (IS_ERR(kirin_pcie->phy_base)) > > + return PTR_ERR(kirin_pcie->phy_base); > > + > > + dbi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi"); > > + kirin_pcie->pci->dbi_base = devm_ioremap_resource(dev, dbi); > > The DWC core handles this now. Yes. This is addressed on this patch: [PATCH v2 07/11] PCI: dwc: pcie-kirin: place common init code altogether > > + if (IS_ERR(kirin_pcie->pci->dbi_base)) > > + return PTR_ERR(kirin_pcie->pci->dbi_base); > > + > > + kirin970_pcie_get_eyeparam(kirin_pcie); > > + > > + kirin_pcie->gpio_id_reset[0] = of_get_named_gpio(dev->of_node, > > + "switch,reset-gpios", 0); > > + if (kirin_pcie->gpio_id_reset[0] < 0) > > + return -ENODEV; > > + > > + kirin_pcie->gpio_id_reset[1] = of_get_named_gpio(dev->of_node, > > + "eth,reset-gpios", 0); > > + if (kirin_pcie->gpio_id_reset[1] < 0) > > + return -ENODEV; > > + > > + kirin_pcie->gpio_id_reset[2] = of_get_named_gpio(dev->of_node, > > + "m_2,reset-gpios", 0); > > + if (kirin_pcie->gpio_id_reset[2] < 0) > > + return -ENODEV; > > + > > + kirin_pcie->gpio_id_reset[3] = of_get_named_gpio(dev->of_node, > > + "mini1,reset-gpios", 0); > > + if (kirin_pcie->gpio_id_reset[3] < 0) > > I've already explained how all this is wrong. This patch: [PATCH v2 09/11] PCI: dwc: pcie-kirin: allow using multiple reset GPIOs Changes the above to, instead, get all the PERST# reset from "reset-gpios": kirin_pcie->n_gpio_resets = of_gpio_named_count(np, "reset-gpios"); if (kirin_pcie->n_gpio_resets > MAX_GPIO_RESETS) { dev_err(dev, "Too many GPIO resets!\n"); return -EINVAL; } for (i = 0; i < kirin_pcie->n_gpio_resets; i++) { kirin_pcie->gpio_id_reset[i] = of_get_named_gpio(dev->of_node, "reset-gpios", i); if (kirin_pcie->gpio_id_reset[i] < 0) return kirin_pcie->gpio_id_reset[i]; sprintf(name, "pcie_perst_%d", i); kirin_pcie->reset_names[i] = devm_kstrdup_const(dev, name, GFP_KERNEL); if (!kirin_pcie->reset_names[i]) return -ENOMEM; } They're all handled altogether inside the driver. > > @@ -431,6 +1124,9 @@ static int kirin_pcie_probe(struct platform_device *pdev) > > return -EINVAL; > > } > > > > + of_id = of_match_node(kirin_pcie_match, dev->of_node); > > + ops = (struct kirin_pcie_ops *)of_id->data; > > of_device_get_match_data() Ok. Thanks, Mauro