Message ID | 20220430084846.3127041-7-chenhuacai@loongson.cn |
---|---|
State | New |
Headers | show |
Series | PCI: Loongson pci improvements and quirks | expand |
On Sat, Apr 30, 2022 at 04:48:46PM +0800, Huacai Chen wrote: > From: Jianmin Lv <lvjianmin@loongson.cn> > > In LS7A, multifunction device use same PCI PIN (because the PIN register > report the same INTx value to each function) but we need different IRQ > for different functions, so add a quirk to fix it for standard PCI PIN > usage. Is this because your _PRT is missing or broken? of_irq_parse_pci() reads and relies on PCI_INTERRUPT_PIN, too, so it seems like the _PRT could contain the same routing information you're getting from DT. > This patch only affect ACPI based systems (and only needed by ACPI based > systems, too). For DT based systems, the irq mappings is defined in .dts > files and be handled by of_irq_parse_pci(). > > Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn> > Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> > --- > drivers/pci/controller/pci-loongson.c | 32 +++++++++++++++++++++++++++ > 1 file changed, 32 insertions(+) > > diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c > index 49d8b8c24ffb..024542a31a8c 100644 > --- a/drivers/pci/controller/pci-loongson.c > +++ b/drivers/pci/controller/pci-loongson.c > @@ -22,6 +22,13 @@ > #define DEV_LS2K_APB 0x7a02 > #define DEV_LS7A_CONF 0x7a10 > #define DEV_LS7A_LPC 0x7a0c > +#define DEV_LS7A_GMAC 0x7a03 > +#define DEV_LS7A_DC1 0x7a06 > +#define DEV_LS7A_DC2 0x7a36 > +#define DEV_LS7A_GPU 0x7a15 > +#define DEV_LS7A_AHCI 0x7a08 > +#define DEV_LS7A_EHCI 0x7a14 > +#define DEV_LS7A_OHCI 0x7a24 > > #define FLAG_CFG0 BIT(0) > #define FLAG_CFG1 BIT(1) > @@ -102,6 +109,31 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, > DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, > DEV_PCIE_PORT_2, loongson_bmaster_quirk); > > +static void loongson_pci_pin_quirk(struct pci_dev *pdev) > +{ > + pdev->pin = 1 + (PCI_FUNC(pdev->devfn) & 3); > +} > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_LS7A_DC1, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_LS7A_DC2, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_LS7A_GPU, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_LS7A_GMAC, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_LS7A_AHCI, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_LS7A_EHCI, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_LS7A_OHCI, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_PCIE_PORT_0, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_PCIE_PORT_1, loongson_pci_pin_quirk); > +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, > + DEV_PCIE_PORT_2, loongson_pci_pin_quirk); > + > static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) > { > struct pci_config_window *cfg; > -- > 2.27.0 >
On 2022/6/1 上午10:07, Bjorn Helgaas wrote: > On Sat, Apr 30, 2022 at 04:48:46PM +0800, Huacai Chen wrote: >> From: Jianmin Lv <lvjianmin@loongson.cn> >> >> In LS7A, multifunction device use same PCI PIN (because the PIN register >> report the same INTx value to each function) but we need different IRQ >> for different functions, so add a quirk to fix it for standard PCI PIN >> usage. > Is this because your _PRT is missing or broken? of_irq_parse_pci() > reads and relies on PCI_INTERRUPT_PIN, too, so it seems like the _PRT > could contain the same routing information you're getting from DT. > Thanks for your reply first. In _PRT, we have following packages for pci device 6(a multi-fun device), Package (0x04) { 0x0006FFFF, Zero, Zero, 0x5D }, Package (0x04) { 0x0006FFFF, One, Zero, 0x5C }, the 'Pin' in two packages must be diffirent(0-INTA, 1-INTB, 2-INTC, 3-INTD) because that the 'Pin' of the _PRT entry will be compared with the pin in the PIN register of pci config space for a pci device in following code path: pci_device_probe ->pcibios_alloc_irq ->acpi_pci_irq_enable ->acpi_pci_irq_lookup ->acpi_pci_irq_find_prt_entry ->acpi_pci_irq_check_entry and in acpi_pci_irq_check_entry(), there is following code: if (((prt->address >> 16) & 0xffff) != device || prt->pin + 1 != pin) return -ENODEV; In LS7A, the PIN register returns same value(0) for all the different function, so, we have to fix it first. I don't know if there is any other way to address it. >> This patch only affect ACPI based systems (and only needed by ACPI based >> systems, too). For DT based systems, the irq mappings is defined in .dts >> files and be handled by of_irq_parse_pci(). >> >> Signed-off-by: Jianmin Lv <lvjianmin@loongson.cn> >> Signed-off-by: Huacai Chen <chenhuacai@loongson.cn> >> --- >> drivers/pci/controller/pci-loongson.c | 32 +++++++++++++++++++++++++++ >> 1 file changed, 32 insertions(+) >> >> diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c >> index 49d8b8c24ffb..024542a31a8c 100644 >> --- a/drivers/pci/controller/pci-loongson.c >> +++ b/drivers/pci/controller/pci-loongson.c >> @@ -22,6 +22,13 @@ >> #define DEV_LS2K_APB 0x7a02 >> #define DEV_LS7A_CONF 0x7a10 >> #define DEV_LS7A_LPC 0x7a0c >> +#define DEV_LS7A_GMAC 0x7a03 >> +#define DEV_LS7A_DC1 0x7a06 >> +#define DEV_LS7A_DC2 0x7a36 >> +#define DEV_LS7A_GPU 0x7a15 >> +#define DEV_LS7A_AHCI 0x7a08 >> +#define DEV_LS7A_EHCI 0x7a14 >> +#define DEV_LS7A_OHCI 0x7a24 >> >> #define FLAG_CFG0 BIT(0) >> #define FLAG_CFG1 BIT(1) >> @@ -102,6 +109,31 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, >> DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, >> DEV_PCIE_PORT_2, loongson_bmaster_quirk); >> >> +static void loongson_pci_pin_quirk(struct pci_dev *pdev) >> +{ >> + pdev->pin = 1 + (PCI_FUNC(pdev->devfn) & 3); >> +} >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_LS7A_DC1, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_LS7A_DC2, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_LS7A_GPU, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_LS7A_GMAC, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_LS7A_AHCI, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_LS7A_EHCI, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_LS7A_OHCI, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_PCIE_PORT_0, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_PCIE_PORT_1, loongson_pci_pin_quirk); >> +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, >> + DEV_PCIE_PORT_2, loongson_pci_pin_quirk); >> + >> static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) >> { >> struct pci_config_window *cfg; >> -- >> 2.27.0 >>
diff --git a/drivers/pci/controller/pci-loongson.c b/drivers/pci/controller/pci-loongson.c index 49d8b8c24ffb..024542a31a8c 100644 --- a/drivers/pci/controller/pci-loongson.c +++ b/drivers/pci/controller/pci-loongson.c @@ -22,6 +22,13 @@ #define DEV_LS2K_APB 0x7a02 #define DEV_LS7A_CONF 0x7a10 #define DEV_LS7A_LPC 0x7a0c +#define DEV_LS7A_GMAC 0x7a03 +#define DEV_LS7A_DC1 0x7a06 +#define DEV_LS7A_DC2 0x7a36 +#define DEV_LS7A_GPU 0x7a15 +#define DEV_LS7A_AHCI 0x7a08 +#define DEV_LS7A_EHCI 0x7a14 +#define DEV_LS7A_OHCI 0x7a24 #define FLAG_CFG0 BIT(0) #define FLAG_CFG1 BIT(1) @@ -102,6 +109,31 @@ DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_LOONGSON, DEV_PCIE_PORT_2, loongson_bmaster_quirk); +static void loongson_pci_pin_quirk(struct pci_dev *pdev) +{ + pdev->pin = 1 + (PCI_FUNC(pdev->devfn) & 3); +} +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_DC1, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_DC2, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_GPU, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_GMAC, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_AHCI, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_EHCI, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_LS7A_OHCI, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_0, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_1, loongson_pci_pin_quirk); +DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LOONGSON, + DEV_PCIE_PORT_2, loongson_pci_pin_quirk); + static struct loongson_pci *pci_bus_to_loongson_pci(struct pci_bus *bus) { struct pci_config_window *cfg;