Re: [PATCH v2 04/11] PCI: dwc: pcie-kirin: add support for Kirin 970 PCIe controller

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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



[Index of Archives]     [DMA Engine]     [Linux Coverity]     [Linux USB]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Greybus]

  Powered by Linux