* [PATCH 0/4] IXP4xx PCI rework @ 2021-05-03 21:16 Linus Walleij 2021-05-03 21:16 ` [PATCH 1/4] ARM/ixp4xx: Move the UART and exp bus virtbases Linus Walleij ` (3 more replies) 0 siblings, 4 replies; 11+ messages in thread From: Linus Walleij @ 2021-05-03 21:16 UTC (permalink / raw) To: Bjorn Helgaas Cc: linux-pci, Arnd Bergmann, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, Linus Walleij This series reworks the IXP4xx PCI driver. The plan is the following: - Implement a new proper host controller that is just used when booting IXP4xx from device tree. (This patch series.) - Delete all boardfiles. - Delete the old PCI driver in arch/arm/mach-ixp4xx. - Only device tree and proper PCI driver remains. Linus Walleij (4): ARM/ixp4xx: Move the UART and exp bus virtbases ARM/ixp4xx: Make NEED_MACH_IO_H optional PCI: ixp4xx: Add device tree bindings for IXP4xx PCI: ixp4xx: Add a new driver for IXP4xx .../bindings/pci/intel,ixp4xx-pci.yaml | 96 +++ MAINTAINERS | 6 + arch/arm/Kconfig | 3 +- arch/arm/Kconfig.debug | 4 +- arch/arm/mach-ixp4xx/Kconfig | 33 +- arch/arm/mach-ixp4xx/common.c | 1 - arch/arm/mach-ixp4xx/fsg-setup.c | 1 + .../mach-ixp4xx/include/mach/ixp4xx-regs.h | 7 +- arch/arm/mach-ixp4xx/ixp4xx-of.c | 8 +- arch/arm/mach-ixp4xx/nas100d-setup.c | 1 + arch/arm/mach-ixp4xx/nslu2-setup.c | 1 + drivers/ata/pata_ixp4xx_cf.c | 1 + drivers/net/ethernet/xscale/ixp4xx_eth.c | 1 + drivers/pci/controller/Kconfig | 5 + drivers/pci/controller/Makefile | 1 + drivers/pci/controller/pci-ixp4xx.c | 684 ++++++++++++++++++ drivers/soc/ixp4xx/ixp4xx-npe.c | 2 + drivers/soc/ixp4xx/ixp4xx-qmgr.c | 2 + 18 files changed, 836 insertions(+), 21 deletions(-) create mode 100644 Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml create mode 100644 drivers/pci/controller/pci-ixp4xx.c -- 2.29.2 ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 1/4] ARM/ixp4xx: Move the UART and exp bus virtbases 2021-05-03 21:16 [PATCH 0/4] IXP4xx PCI rework Linus Walleij @ 2021-05-03 21:16 ` Linus Walleij 2021-05-04 7:38 ` Arnd Bergmann 2021-05-03 21:16 ` [PATCH 2/4] ARM/ixp4xx: Make NEED_MACH_IO_H optional Linus Walleij ` (2 subsequent siblings) 3 siblings, 1 reply; 11+ messages in thread From: Linus Walleij @ 2021-05-03 21:16 UTC (permalink / raw) To: Bjorn Helgaas Cc: linux-pci, Arnd Bergmann, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, Linus Walleij UART1, UART2 and the expansion bus config registers are the only registers mapped in a fixed location when using device tree. For device tree we also want to get rid of the custom <mach/io.h> for IXP4xx. So we need to undefine CONFIG_NEED_MACH_IO_H. Doing that activates the fixed mapping of the PCI IO space to PCI_IO_VIRT_BASE which is hardcoded to 0xFEE00000 and this would collide with the old fixed mappings. Move the UART1 and UART2 to the beginning of the fixmap region at 0xFFC80000-0xFFC81FFF and move the expansion bus base to 0xFFC82000-0xFFC81FFF in order to be able to accommodate for the fixed PCI virtual IO space. Cc: Arnd Bergmann <arnd@arndb.de> Cc: Imre Kaloz <kaloz@openwrt.org> Cc: Krzysztof Halasa <khalasa@piap.pl> Cc: Zoltan HERPAI <wigyori@uid0.hu> Cc: Raylynn Knight <rayknight@me.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- PCI maintainers: this patch is mostly FYI, will be merged through ARM SoC --- arch/arm/Kconfig.debug | 4 ++-- arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h | 7 ++++--- arch/arm/mach-ixp4xx/ixp4xx-of.c | 8 ++++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug index 9e0b5e7f12af..bbe799f6bc03 100644 --- a/arch/arm/Kconfig.debug +++ b/arch/arm/Kconfig.debug @@ -1803,8 +1803,8 @@ config DEBUG_UART_VIRT default 0xfedc0000 if DEBUG_EP93XX default 0xfee003f8 if DEBUG_FOOTBRIDGE_COM1 default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART - default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN - default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN + default 0xffc80000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN + default 0xffc80003 if ARCH_IXP4XX && CPU_BIG_ENDIAN default 0xfef36000 if DEBUG_HIGHBANK_UART default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1 default 0xfefb0800 if DEBUG_OMAP1UART2 || DEBUG_OMAP7XXUART2 diff --git a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h index 708d085ce39f..45b0f2c3a1d6 100644 --- a/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h +++ b/arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h @@ -59,7 +59,7 @@ * Expansion BUS Configuration registers */ #define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000 -#define IXP4XX_EXP_CFG_BASE_VIRT 0xFEF14000 +#define IXP4XX_EXP_CFG_BASE_VIRT 0xFFC82000 #define IXP4XX_EXP_CFG_REGION_SIZE 0x00001000 #define IXP4XX_EXP_CS0_OFFSET 0x00 @@ -120,8 +120,9 @@ #define IXP4XX_SSP_BASE_PHYS (IXP4XX_PERIPHERAL_BASE_PHYS + 0x12000) -#define IXP4XX_UART1_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x0000) -#define IXP4XX_UART2_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x1000) +/* The UART is explicitly put in the beginning of fixmap */ +#define IXP4XX_UART1_BASE_VIRT (0xFFC80000) +#define IXP4XX_UART2_BASE_VIRT (0xFFC81000) #define IXP4XX_PMU_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x2000) #define IXP4XX_INTC_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x3000) #define IXP4XX_GPIO_BASE_VIRT (IXP4XX_PERIPHERAL_BASE_VIRT + 0x4000) diff --git a/arch/arm/mach-ixp4xx/ixp4xx-of.c b/arch/arm/mach-ixp4xx/ixp4xx-of.c index 7449b8319c8a..e3d823c077e8 100644 --- a/arch/arm/mach-ixp4xx/ixp4xx-of.c +++ b/arch/arm/mach-ixp4xx/ixp4xx-of.c @@ -9,8 +9,12 @@ #include <asm/mach/arch.h> #include <asm/mach/map.h> -#include <mach/hardware.h> -#include <mach/ixp4xx-regs.h> +/* + * These are the only fixed phys to virt mappings we ever need + * we put it right after the UART mapping at 0xffc80000-0xffc81fff + */ +#define IXP4XX_EXP_CFG_BASE_PHYS 0xC4000000 +#define IXP4XX_EXP_CFG_BASE_VIRT 0xFFC82000 static struct map_desc ixp4xx_of_io_desc[] __initdata = { /* -- 2.29.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 1/4] ARM/ixp4xx: Move the UART and exp bus virtbases 2021-05-03 21:16 ` [PATCH 1/4] ARM/ixp4xx: Move the UART and exp bus virtbases Linus Walleij @ 2021-05-04 7:38 ` Arnd Bergmann 0 siblings, 0 replies; 11+ messages in thread From: Arnd Bergmann @ 2021-05-04 7:38 UTC (permalink / raw) To: Linus Walleij Cc: Bjorn Helgaas, linux-pci, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight On Mon, May 3, 2021 at 11:16 PM Linus Walleij <linus.walleij@linaro.org> wrote: > > UART1, UART2 and the expansion bus config registers > are the only registers mapped in a fixed location > when using device tree. > > For device tree we also want to get rid of the custom > <mach/io.h> for IXP4xx. So we need to undefine > CONFIG_NEED_MACH_IO_H. Doing that activates the fixed > mapping of the PCI IO space to PCI_IO_VIRT_BASE which > is hardcoded to 0xFEE00000 and this would collide with > the old fixed mappings. > > Move the UART1 and UART2 to the beginning of the fixmap > region at 0xFFC80000-0xFFC81FFF and move the expansion > bus base to 0xFFC82000-0xFFC81FFF in order to be able to > accommodate for the fixed PCI virtual IO space. This doesn't feel right to me, for multiple reasons: - I don't think putting something into fixmap is valid unless you assign a fixmap constant in arch/arm/include/asm/fixmap.h for it and use that constant. We do have FIX_EARLYCON_MEM_BASE already, and we could in theory use the same constant for both debug_ll and earlycon (I think), or we could have adjacent pages for the two. - IIRC, DEBUG_LL always uses a section map, so if you just need a single page, it doesn't work right. Would it be sufficient if you just move IXP4XX_*_BASE_VIRT from 0xFEF????? to 0xFEC????? ? Idea I've had in the past was to treat DEBUG_UART_VIRT==0 as a special case that automatically picks a reasonable fixed address, such as (0xfec00000 | (DEBUG_UART_PHYS & 0x1fffff) and document that area in Documentation/arm/memory.txt as the default place for debug_ll. Arnd > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: Imre Kaloz <kaloz@openwrt.org> > Cc: Krzysztof Halasa <khalasa@piap.pl> > Cc: Zoltan HERPAI <wigyori@uid0.hu> > Cc: Raylynn Knight <rayknight@me.com> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > --- > PCI maintainers: this patch is mostly FYI, will be > merged through ARM SoC > --- > arch/arm/Kconfig.debug | 4 ++-- > arch/arm/mach-ixp4xx/include/mach/ixp4xx-regs.h | 7 ++++--- > arch/arm/mach-ixp4xx/ixp4xx-of.c | 8 ++++++-- > 3 files changed, 12 insertions(+), 7 deletions(-) > > diff --git a/arch/arm/Kconfig.debug b/arch/arm/Kconfig.debug > index 9e0b5e7f12af..bbe799f6bc03 100644 > --- a/arch/arm/Kconfig.debug > +++ b/arch/arm/Kconfig.debug > @@ -1803,8 +1803,8 @@ config DEBUG_UART_VIRT > default 0xfedc0000 if DEBUG_EP93XX > default 0xfee003f8 if DEBUG_FOOTBRIDGE_COM1 > default 0xfee20000 if DEBUG_NSPIRE_CLASSIC_UART || DEBUG_NSPIRE_CX_UART > - default 0xfef00000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN > - default 0xfef00003 if ARCH_IXP4XX && CPU_BIG_ENDIAN > + default 0xffc80000 if ARCH_IXP4XX && !CPU_BIG_ENDIAN > + default 0xffc80003 if ARCH_IXP4XX && CPU_BIG_ENDIAN > default 0xfef36000 if DEBUG_HIGHBANK_UART > default 0xfefb0000 if DEBUG_OMAP1UART1 || DEBUG_OMAP7XXUART1 Please keep these sorted numerically Arnd ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 2/4] ARM/ixp4xx: Make NEED_MACH_IO_H optional 2021-05-03 21:16 [PATCH 0/4] IXP4xx PCI rework Linus Walleij 2021-05-03 21:16 ` [PATCH 1/4] ARM/ixp4xx: Move the UART and exp bus virtbases Linus Walleij @ 2021-05-03 21:16 ` Linus Walleij 2021-05-03 21:16 ` [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx Linus Walleij 2021-05-03 21:16 ` [PATCH 4/4] PCI: ixp4xx: Add a new driver " Linus Walleij 3 siblings, 0 replies; 11+ messages in thread From: Linus Walleij @ 2021-05-03 21:16 UTC (permalink / raw) To: Bjorn Helgaas Cc: linux-pci, Arnd Bergmann, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, Linus Walleij In order to create a proper PCI driver for the IXP4xx we need to make the old PCI driver and its reliance on <mach/io.h> optional. Create a new Kconfig symbol for the legacy PCI driver IXP4XX_PCI_LEGACY and only activate NEED_MACH_IO_H for this driver. A few files need to be adjusted to explicitly include the <mach/hardware.h> and <mach/cpu.h> headers that they previously obtained implicitly using <linux/io.h> that would include <mach/io.h> and in turn include these two headers. This breaks our reliance on the old PCI and indirect PCI support so we can reimplement a proper purely DT-based driver in the PCI subsystem. Cc: Arnd Bergmann <arnd@arndb.de> Cc: Imre Kaloz <kaloz@openwrt.org> Cc: Krzysztof Halasa <khalasa@piap.pl> Cc: Zoltan HERPAI <wigyori@uid0.hu> Cc: Raylynn Knight <rayknight@me.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- PCI maintainers: this patch is mostly FYI, will be merged through ARM SoC --- arch/arm/Kconfig | 3 ++- arch/arm/mach-ixp4xx/Kconfig | 33 +++++++++++++++--------- arch/arm/mach-ixp4xx/common.c | 1 - arch/arm/mach-ixp4xx/fsg-setup.c | 1 + arch/arm/mach-ixp4xx/nas100d-setup.c | 1 + arch/arm/mach-ixp4xx/nslu2-setup.c | 1 + drivers/ata/pata_ixp4xx_cf.c | 1 + drivers/net/ethernet/xscale/ixp4xx_eth.c | 1 + drivers/soc/ixp4xx/ixp4xx-npe.c | 2 ++ drivers/soc/ixp4xx/ixp4xx-qmgr.c | 2 ++ 10 files changed, 32 insertions(+), 14 deletions(-) diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 853aab5ab327..4ca2ab19d265 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -394,7 +394,8 @@ config ARCH_IXP4XX select HAVE_PCI select IXP4XX_IRQ select IXP4XX_TIMER - select NEED_MACH_IO_H + # With the new PCI driver this is not needed + select NEED_MACH_IO_H if PCI_IXP4XX_LEGACY select USB_EHCI_BIG_ENDIAN_DESC select USB_EHCI_BIG_ENDIAN_MMIO help diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig index 165c184801e1..cabb37232704 100644 --- a/arch/arm/mach-ixp4xx/Kconfig +++ b/arch/arm/mach-ixp4xx/Kconfig @@ -20,7 +20,7 @@ config MACH_IXP4XX_OF config MACH_NSLU2 bool prompt "Linksys NSLU2" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support Linksys's NSLU2 NAS device. For more information on this platform, @@ -28,7 +28,7 @@ config MACH_NSLU2 config MACH_AVILA bool "Avila" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support the Gateworks Avila Network Platform. For more information on this platform, @@ -44,7 +44,7 @@ config MACH_LOFT config ARCH_ADI_COYOTE bool "Coyote" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support the ADI Engineering Coyote Gateway Reference Platform. For more @@ -52,7 +52,7 @@ config ARCH_ADI_COYOTE config MACH_GATEWAY7001 bool "Gateway 7001" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support Gateway's 7001 Access Point. For more information on this platform, @@ -60,7 +60,7 @@ config MACH_GATEWAY7001 config MACH_WG302V2 bool "Netgear WG302 v2 / WAG302 v2" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support Netgear's WG302 v2 or WAG302 v2 Access Points. For more information @@ -68,6 +68,7 @@ config MACH_WG302V2 config ARCH_IXDP425 bool "IXDP425" + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support Intel's IXDP425 Development Platform (Also known as Richfield). @@ -75,6 +76,7 @@ config ARCH_IXDP425 config MACH_IXDPG425 bool "IXDPG425" + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support Intel's IXDPG425 Development Platform (Also known as Montajade). @@ -120,7 +122,7 @@ config ARCH_PRPMC1100 config MACH_NAS100D bool prompt "NAS100D" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support Iomega's NAS 100d device. For more information on this platform, @@ -129,7 +131,7 @@ config MACH_NAS100D config MACH_DSMG600 bool prompt "D-Link DSM-G600 RevA" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support D-Link's DSM-G600 RevA device. For more information on this platform, @@ -143,7 +145,7 @@ config ARCH_IXDP4XX config MACH_FSG bool prompt "Freecom FSG-3" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support Freecom's FSG-3 device. For more information on this platform, @@ -152,7 +154,7 @@ config MACH_FSG config MACH_ARCOM_VULCAN bool prompt "Arcom/Eurotech Vulcan" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support Arcom's Vulcan board. @@ -173,7 +175,7 @@ config CPU_IXP43X config MACH_GTWX5715 bool "Gemtek WX5715 (Linksys WRV54G)" depends on ARCH_IXP4XX - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help This board is currently inside the Linksys WRV54G Gateways. @@ -196,7 +198,7 @@ config MACH_DEVIXP config MACH_MICCPT bool "Omicron MICCPT" - select FORCE_PCI + depends on IXP4XX_PCI_LEGACY help Say 'Y' here if you want your kernel to support the MICCPT board from OMICRON electronics GmbH. @@ -209,9 +211,16 @@ config MACH_MIC256 comment "IXP4xx Options" +config IXP4XX_PCI_LEGACY + bool "IXP4xx legacy PCI driver support" + depends on PCI + help + Selects legacy PCI driver. + Not recommended for new development. + config IXP4XX_INDIRECT_PCI bool "Use indirect PCI memory access" - depends on PCI + depends on IXP4XX_PCI_LEGACY help IXP4xx provides two methods of accessing PCI memory space: diff --git a/arch/arm/mach-ixp4xx/common.c b/arch/arm/mach-ixp4xx/common.c index 000f672a94c9..431da1b4f6bd 100644 --- a/arch/arm/mach-ixp4xx/common.c +++ b/arch/arm/mach-ixp4xx/common.c @@ -32,7 +32,6 @@ #include <linux/dma-map-ops.h> #include <mach/udc.h> #include <mach/hardware.h> -#include <mach/io.h> #include <linux/uaccess.h> #include <asm/page.h> #include <asm/exception.h> diff --git a/arch/arm/mach-ixp4xx/fsg-setup.c b/arch/arm/mach-ixp4xx/fsg-setup.c index 507ee3878769..844329c5610d 100644 --- a/arch/arm/mach-ixp4xx/fsg-setup.c +++ b/arch/arm/mach-ixp4xx/fsg-setup.c @@ -28,6 +28,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> +#include <mach/hardware.h> #include "irqs.h" diff --git a/arch/arm/mach-ixp4xx/nas100d-setup.c b/arch/arm/mach-ixp4xx/nas100d-setup.c index 6959ad2e3aec..6133cf01cbe4 100644 --- a/arch/arm/mach-ixp4xx/nas100d-setup.c +++ b/arch/arm/mach-ixp4xx/nas100d-setup.c @@ -33,6 +33,7 @@ #include <asm/mach-types.h> #include <asm/mach/arch.h> #include <asm/mach/flash.h> +#include <mach/hardware.h> #include "irqs.h" diff --git a/arch/arm/mach-ixp4xx/nslu2-setup.c b/arch/arm/mach-ixp4xx/nslu2-setup.c index a428bb918703..8526a70e401b 100644 --- a/arch/arm/mach-ixp4xx/nslu2-setup.c +++ b/arch/arm/mach-ixp4xx/nslu2-setup.c @@ -31,6 +31,7 @@ #include <asm/mach/arch.h> #include <asm/mach/flash.h> #include <asm/mach/time.h> +#include <mach/hardware.h> #include "irqs.h" diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c index d1644a8ef9fa..9929d0150141 100644 --- a/drivers/ata/pata_ixp4xx_cf.c +++ b/drivers/ata/pata_ixp4xx_cf.c @@ -18,6 +18,7 @@ #include <linux/irq.h> #include <linux/platform_device.h> #include <scsi/scsi_host.h> +#include <mach/hardware.h> #define DRV_NAME "pata_ixp4xx_cf" #define DRV_VERSION "0.2" diff --git a/drivers/net/ethernet/xscale/ixp4xx_eth.c b/drivers/net/ethernet/xscale/ixp4xx_eth.c index 0152f1e70783..88ad1639a7da 100644 --- a/drivers/net/ethernet/xscale/ixp4xx_eth.c +++ b/drivers/net/ethernet/xscale/ixp4xx_eth.c @@ -36,6 +36,7 @@ #include <linux/module.h> #include <linux/soc/ixp4xx/npe.h> #include <linux/soc/ixp4xx/qmgr.h> +#include <mach/hardware.h> #include "ixp46x_ts.h" diff --git a/drivers/soc/ixp4xx/ixp4xx-npe.c b/drivers/soc/ixp4xx/ixp4xx-npe.c index ec90b44fa0cd..0a16ac46ab59 100644 --- a/drivers/soc/ixp4xx/ixp4xx-npe.c +++ b/drivers/soc/ixp4xx/ixp4xx-npe.c @@ -20,6 +20,8 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/soc/ixp4xx/npe.h> +#include <mach/hardware.h> +#include <mach/cpu.h> #define DEBUG_MSG 0 #define DEBUG_FW 0 diff --git a/drivers/soc/ixp4xx/ixp4xx-qmgr.c b/drivers/soc/ixp4xx/ixp4xx-qmgr.c index 8c968382cea7..1b1631ac0438 100644 --- a/drivers/soc/ixp4xx/ixp4xx-qmgr.c +++ b/drivers/soc/ixp4xx/ixp4xx-qmgr.c @@ -12,6 +12,8 @@ #include <linux/of.h> #include <linux/platform_device.h> #include <linux/soc/ixp4xx/qmgr.h> +#include <mach/hardware.h> +#include <mach/cpu.h> static struct qmgr_regs __iomem *qmgr_regs; static int qmgr_irq_1; -- 2.29.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx 2021-05-03 21:16 [PATCH 0/4] IXP4xx PCI rework Linus Walleij 2021-05-03 21:16 ` [PATCH 1/4] ARM/ixp4xx: Move the UART and exp bus virtbases Linus Walleij 2021-05-03 21:16 ` [PATCH 2/4] ARM/ixp4xx: Make NEED_MACH_IO_H optional Linus Walleij @ 2021-05-03 21:16 ` Linus Walleij 2021-05-04 12:54 ` Arnd Bergmann 2021-05-06 20:24 ` Rob Herring 2021-05-03 21:16 ` [PATCH 4/4] PCI: ixp4xx: Add a new driver " Linus Walleij 3 siblings, 2 replies; 11+ messages in thread From: Linus Walleij @ 2021-05-03 21:16 UTC (permalink / raw) To: Bjorn Helgaas Cc: linux-pci, Arnd Bergmann, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, Linus Walleij, devicetree This adds device tree bindings for the Intel IXP4xx PCI controller which can be used as both host and option. Cc: devicetree@vger.kernel.org Cc: Arnd Bergmann <arnd@arndb.de> Cc: Imre Kaloz <kaloz@openwrt.org> Cc: Krzysztof Halasa <khalasa@piap.pl> Cc: Zoltan HERPAI <wigyori@uid0.hu> Cc: Raylynn Knight <rayknight@me.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- PCI maintainers: mainly looking for a review and ACK (if you care about DT bindings) the patch will be merged through ARM SoC. --- .../bindings/pci/intel,ixp4xx-pci.yaml | 96 +++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml diff --git a/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml b/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml new file mode 100644 index 000000000000..5b6af2f5c2a5 --- /dev/null +++ b/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pci/intel,ixp4xx-pci.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Intel IXP4xx PCI controller + +maintainers: + - Linus Walleij <linus.walleij@linaro.org> + +description: PCI host controller found in the Intel IXP4xx SoC series. + +allOf: + - $ref: /schemas/pci/pci-bus.yaml# + +properties: + compatible: + items: + - enum: + - intel,ixp42x-pci + - intel,ixp43x-pci + description: The two supported variants are ixp42x and ixp43x, + though more variants may exist. + + reg: + items: + - description: IXP4xx-specific registers + + ranges: + maxItems: 2 + description: Typically one memory range of 64MB and one IO + space range of 64KB. + + dma-ranges: + maxItems: 1 + description: The DMA range tells the PCI host which addresses + the RAM is at. It can map only 64MB so if the RAM is bigger + than 64MB the DMA access has to be restricted to these + addresses. + + "#interrupt-cells": true + + interrupt-map: true + + interrupt-map-mask: + items: + - const: 0xf800 + - const: 0 + - const: 0 + - const: 7 + +required: + - compatible + - reg + - ranges + - dma-ranges + - "#interrupt-cells" + - interrupt-map + - interrupt-map-mask + +unevaluatedProperties: false + +examples: + - | + pci@c0000000 { + compatible = "intel,ixp43x-pci"; + reg = <0xc0000000 0x1000>; + #address-cells = <3>; + #size-cells = <2>; + device_type = "pci"; + bus-range = <0x00 0xff>; + status = "disabled"; + + ranges = + <0x02000000 0 0x48000000 0x48000000 0 0x04000000>, + <0x01000000 0 0x00000000 0x4c000000 0 0x00010000>; + dma-ranges = + <0x02000000 0 0x00000000 0x00000000 0 0x04000000>; + + #interrupt-cells = <1>; + interrupt-map-mask = <0xf800 0 0 7>; + interrupt-map = + <0x0800 0 0 1 &gpio0 11 3>, /* INT A on slot 1 is irq 11 */ + <0x0800 0 0 2 &gpio0 10 3>, /* INT B on slot 1 is irq 10 */ + <0x0800 0 0 3 &gpio0 9 3>, /* INT C on slot 1 is irq 9 */ + <0x0800 0 0 4 &gpio0 8 3>, /* INT D on slot 1 is irq 8 */ + <0x1000 0 0 1 &gpio0 10 3>, /* INT A on slot 2 is irq 10 */ + <0x1000 0 0 2 &gpio0 9 3>, /* INT B on slot 2 is irq 9 */ + <0x1000 0 0 3 &gpio0 8 3>, /* INT C on slot 2 is irq 8 */ + <0x1000 0 0 4 &gpio0 11 3>, /* INT D on slot 2 is irq 11 */ + <0x1800 0 0 1 &gpio0 9 3>, /* INT A on slot 3 is irq 9 */ + <0x1800 0 0 2 &gpio0 8 3>, /* INT B on slot 3 is irq 8 */ + <0x1800 0 0 3 &gpio0 11 3>, /* INT C on slot 3 is irq 11 */ + <0x1800 0 0 4 &gpio0 10 3>; /* INT D on slot 3 is irq 10 */ + }; -- 2.29.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx 2021-05-03 21:16 ` [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx Linus Walleij @ 2021-05-04 12:54 ` Arnd Bergmann 2021-05-09 21:31 ` Linus Walleij 2021-05-06 20:24 ` Rob Herring 1 sibling, 1 reply; 11+ messages in thread From: Arnd Bergmann @ 2021-05-04 12:54 UTC (permalink / raw) To: Linus Walleij Cc: Bjorn Helgaas, linux-pci, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, DTML On Mon, May 3, 2021 at 11:16 PM Linus Walleij <linus.walleij@linaro.org> wrote: > + compatible: > + items: > + - enum: > + - intel,ixp42x-pci > + - intel,ixp43x-pci > + description: The two supported variants are ixp42x and ixp43x, > + though more variants may exist. These are still wildcard names, better pick a real soc identifier such as "ixp425" instead of "ixp42x" in case there are differences after all. > + <0x0800 0 0 1 &gpio0 11 3>, /* INT A on slot 1 is irq 11 */ > + <0x0800 0 0 2 &gpio0 10 3>, /* INT B on slot 1 is irq 10 */ > + <0x0800 0 0 3 &gpio0 9 3>, /* INT C on slot 1 is irq 9 */ > + <0x0800 0 0 4 &gpio0 8 3>, /* INT D on slot 1 is irq 8 */ > + <0x1000 0 0 1 &gpio0 10 3>, /* INT A on slot 2 is irq 10 */ > + <0x1000 0 0 2 &gpio0 9 3>, /* INT B on slot 2 is irq 9 */ > + <0x1000 0 0 3 &gpio0 8 3>, /* INT C on slot 2 is irq 8 */ > + <0x1000 0 0 4 &gpio0 11 3>, /* INT D on slot 2 is irq 11 */ > + <0x1800 0 0 1 &gpio0 9 3>, /* INT A on slot 3 is irq 9 */ > + <0x1800 0 0 2 &gpio0 8 3>, /* INT B on slot 3 is irq 8 */ > + <0x1800 0 0 3 &gpio0 11 3>, /* INT C on slot 3 is irq 11 */ > + <0x1800 0 0 4 &gpio0 10 3>; /* INT D on slot 3 is irq 10 */ Is this different from the default swizzling rules? You normally only have to provide the irqs for the bus once. Arnd ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx 2021-05-04 12:54 ` Arnd Bergmann @ 2021-05-09 21:31 ` Linus Walleij 0 siblings, 0 replies; 11+ messages in thread From: Linus Walleij @ 2021-05-09 21:31 UTC (permalink / raw) To: Arnd Bergmann Cc: Bjorn Helgaas, linux-pci, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, DTML On Tue, May 4, 2021 at 2:55 PM Arnd Bergmann <arnd@arndb.de> wrote: > On Mon, May 3, 2021 at 11:16 PM Linus Walleij <linus.walleij@linaro.org> wrote: > > > + compatible: > > + items: > > + - enum: > > + - intel,ixp42x-pci > > + - intel,ixp43x-pci > > + description: The two supported variants are ixp42x and ixp43x, > > + though more variants may exist. > > These are still wildcard names, better pick a real soc identifier > such as "ixp425" instead of "ixp42x" in case there are differences > after all. In general I agree. But when not even the vendor think they should be held apart that is another thing. Even the official Intel documentation uses these names: https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/ixp42x-product-line-network-processors-datasheet.pdf https://www.intel.com/content/dam/www/public/us/en/documents/datasheets/ixp43x-product-line-network-processors-datasheet.pdf The differences seem to be very small and related to the NPE and page 23 in the 42x documentation makes no difference between them. I guess I will change it if you insist, but none of the other drivers have this fine-grained compatible strings. > > + <0x0800 0 0 1 &gpio0 11 3>, /* INT A on slot 1 is irq 11 */ > > + <0x0800 0 0 2 &gpio0 10 3>, /* INT B on slot 1 is irq 10 */ > > + <0x0800 0 0 3 &gpio0 9 3>, /* INT C on slot 1 is irq 9 */ > > + <0x0800 0 0 4 &gpio0 8 3>, /* INT D on slot 1 is irq 8 */ > > + <0x1000 0 0 1 &gpio0 10 3>, /* INT A on slot 2 is irq 10 */ > > + <0x1000 0 0 2 &gpio0 9 3>, /* INT B on slot 2 is irq 9 */ > > + <0x1000 0 0 3 &gpio0 8 3>, /* INT C on slot 2 is irq 8 */ > > + <0x1000 0 0 4 &gpio0 11 3>, /* INT D on slot 2 is irq 11 */ > > + <0x1800 0 0 1 &gpio0 9 3>, /* INT A on slot 3 is irq 9 */ > > + <0x1800 0 0 2 &gpio0 8 3>, /* INT B on slot 3 is irq 8 */ > > + <0x1800 0 0 3 &gpio0 11 3>, /* INT C on slot 3 is irq 11 */ > > + <0x1800 0 0 4 &gpio0 10 3>; /* INT D on slot 3 is irq 10 */ > > Is this different from the default swizzling rules? You normally > only have to provide the irqs for the bus once. The different board files for ixp4xx does the swizzling in different ways. The NSLU2 rotates only the top 3 IRQs and looks like this: + /* + * Taken from NSLU2 PCI boardfile, INT A, B, C swizzled D constant + * We have slots (IDSEL) 1, 2 and 3. + */ + interrupt-map = + /* IDSEL 1 */ + <0x0800 0 0 1 &gpio0 11 3>, /* INT A on slot 1 is irq 11 */ + <0x0800 0 0 2 &gpio0 10 3>, /* INT B on slot 1 is irq 10 */ + <0x0800 0 0 3 &gpio0 9 3>, /* INT C on slot 1 is irq 9 */ + <0x0800 0 0 4 &gpio0 8 3>, /* INT D on slot 1 is irq 8 */ + /* IDSEL 2 */ + <0x1000 0 0 1 &gpio0 10 3>, /* INT A on slot 2 is irq 10 */ + <0x1000 0 0 2 &gpio0 9 3>, /* INT B on slot 2 is irq 9 */ + <0x1000 0 0 3 &gpio0 11 3>, /* INT C on slot 2 is irq 11 */ + <0x1000 0 0 4 &gpio0 8 3>, /* INT D on slot 2 is irq 8 */ + /* IDSEL 3 */ + <0x1800 0 0 1 &gpio0 9 3>, /* INT A on slot 3 is irq 9 */ + <0x1800 0 0 2 &gpio0 11 3>, /* INT B on slot 3 is irq 11 */ + <0x1800 0 0 3 &gpio0 10 3>, /* INT C on slot 3 is irq 10 */ + <0x1800 0 0 4 &gpio0 8 3>; /* INT D on slot 3 is irq 8 */ Yours, Linus Walleij ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx 2021-05-03 21:16 ` [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx Linus Walleij 2021-05-04 12:54 ` Arnd Bergmann @ 2021-05-06 20:24 ` Rob Herring 1 sibling, 0 replies; 11+ messages in thread From: Rob Herring @ 2021-05-06 20:24 UTC (permalink / raw) To: Linus Walleij Cc: Bjorn Helgaas, linux-pci, Arnd Bergmann, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, devicetree On Mon, May 03, 2021 at 11:16:48PM +0200, Linus Walleij wrote: > This adds device tree bindings for the Intel IXP4xx > PCI controller which can be used as both host and > option. > > Cc: devicetree@vger.kernel.org > Cc: Arnd Bergmann <arnd@arndb.de> > Cc: Imre Kaloz <kaloz@openwrt.org> > Cc: Krzysztof Halasa <khalasa@piap.pl> > Cc: Zoltan HERPAI <wigyori@uid0.hu> > Cc: Raylynn Knight <rayknight@me.com> > Signed-off-by: Linus Walleij <linus.walleij@linaro.org> > --- > PCI maintainers: mainly looking for a review and ACK (if > you care about DT bindings) the patch will be merged > through ARM SoC. > --- > .../bindings/pci/intel,ixp4xx-pci.yaml | 96 +++++++++++++++++++ > 1 file changed, 96 insertions(+) > create mode 100644 Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml > > diff --git a/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml b/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml > new file mode 100644 > index 000000000000..5b6af2f5c2a5 > --- /dev/null > +++ b/Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml > @@ -0,0 +1,96 @@ > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) > +%YAML 1.2 > +--- > +$id: http://devicetree.org/schemas/pci/intel,ixp4xx-pci.yaml# > +$schema: http://devicetree.org/meta-schemas/core.yaml# > + > +title: Intel IXP4xx PCI controller > + > +maintainers: > + - Linus Walleij <linus.walleij@linaro.org> > + > +description: PCI host controller found in the Intel IXP4xx SoC series. > + > +allOf: > + - $ref: /schemas/pci/pci-bus.yaml# > + > +properties: > + compatible: > + items: > + - enum: > + - intel,ixp42x-pci > + - intel,ixp43x-pci > + description: The two supported variants are ixp42x and ixp43x, > + though more variants may exist. > + > + reg: > + items: > + - description: IXP4xx-specific registers > + > + ranges: > + maxItems: 2 > + description: Typically one memory range of 64MB and one IO > + space range of 64KB. > + > + dma-ranges: > + maxItems: 1 > + description: The DMA range tells the PCI host which addresses > + the RAM is at. It can map only 64MB so if the RAM is bigger > + than 64MB the DMA access has to be restricted to these > + addresses. > + > + "#interrupt-cells": true > + > + interrupt-map: true > + > + interrupt-map-mask: > + items: > + - const: 0xf800 > + - const: 0 > + - const: 0 > + - const: 7 > + > +required: > + - compatible > + - reg > + - ranges Already required by pci-bus.yaml I think. > + - dma-ranges > + - "#interrupt-cells" > + - interrupt-map > + - interrupt-map-mask > + > +unevaluatedProperties: false > + > +examples: > + - | > + pci@c0000000 { > + compatible = "intel,ixp43x-pci"; > + reg = <0xc0000000 0x1000>; > + #address-cells = <3>; > + #size-cells = <2>; > + device_type = "pci"; > + bus-range = <0x00 0xff>; > + status = "disabled"; Don't show status in examples. I've really got to come up with an examples only schema to check this. Rob ^ permalink raw reply [flat|nested] 11+ messages in thread
* [PATCH 4/4] PCI: ixp4xx: Add a new driver for IXP4xx 2021-05-03 21:16 [PATCH 0/4] IXP4xx PCI rework Linus Walleij ` (2 preceding siblings ...) 2021-05-03 21:16 ` [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx Linus Walleij @ 2021-05-03 21:16 ` Linus Walleij 2021-05-04 0:40 ` kernel test robot 2021-05-04 7:12 ` Arnd Bergmann 3 siblings, 2 replies; 11+ messages in thread From: Linus Walleij @ 2021-05-03 21:16 UTC (permalink / raw) To: Bjorn Helgaas Cc: linux-pci, Arnd Bergmann, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, Linus Walleij This adds a new PCI controller driver for the Intel IXP4xx (IX425, IXP435 etc), based on the XScale microarchitecture. This replaces the old driver in arch/arm/mach-ixp4xx/common-pci.c which utilized the ARM-specific BIOS32 PCI framework, and all parameterization for such things as memory and IO space as well as interrupt swizzling is done from the device tree. The __raw_writel() and __raw_readl() are used for accessing the PCI controller for the same reason that these accessors are used in the timer, IRQ and GPIO drivers: the platform will alter its address bus pattern based on whether the system is booted in big- or little-endian mode. For this reason all register on IXP4xx must always be accessed in native (CPU) endianness. This driver supports 64MB of PCI memory space, but not the indirect access of 1GB that is available in the old driver. We can address that later if and only if there are users that need all 1GB of PCI address space. Tested by booting the NSLU2, attaching a USB stick, mounting and browsing the drive. Cc: Arnd Bergmann <arnd@arndb.de> Cc: Imre Kaloz <kaloz@openwrt.org> Cc: Krzysztof Halasa <khalasa@piap.pl> Cc: Zoltan HERPAI <wigyori@uid0.hu> Cc: Raylynn Knight <rayknight@me.com> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> --- PCI maintainers: looking for review or ACK to take this driver throght ARM SoC since it is dependent on the first patches in the series in order not to cause build problems. --- MAINTAINERS | 6 + drivers/pci/controller/Kconfig | 5 + drivers/pci/controller/Makefile | 1 + drivers/pci/controller/pci-ixp4xx.c | 684 ++++++++++++++++++++++++++++ 4 files changed, 696 insertions(+) create mode 100644 drivers/pci/controller/pci-ixp4xx.c diff --git a/MAINTAINERS b/MAINTAINERS index d92f85ca831d..ae220d52a6d7 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -13692,6 +13692,12 @@ S: Maintained F: Documentation/devicetree/bindings/pci/fsl,imx6q-pcie.txt F: drivers/pci/controller/dwc/*imx6* +PCI DRIVER FOR INTEL IXP4XX +M: Linus Walleij <linus.walleij@linaro.org> +S: Maintained +F: Documentation/devicetree/bindings/pci/intel,ixp4xx-pci.yaml +F: drivers/pci/controller/pci-ixp4xx.c + PCI DRIVER FOR INTEL VOLUME MANAGEMENT DEVICE (VMD) M: Jonathan Derrick <jonathan.derrick@intel.com> L: linux-pci@vger.kernel.org diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig index 5aa8977d7b0f..fc6249cdd909 100644 --- a/drivers/pci/controller/Kconfig +++ b/drivers/pci/controller/Kconfig @@ -37,6 +37,11 @@ config PCI_FTPCI100 depends on OF default ARCH_GEMINI +config PCI_IXP4XX + bool "Intel IXP4xx PCI controller" + depends on OF + default ARCH_IXP4XX + config PCI_TEGRA bool "NVIDIA Tegra PCIe controller" depends on ARCH_TEGRA || COMPILE_TEST diff --git a/drivers/pci/controller/Makefile b/drivers/pci/controller/Makefile index e4559f2182f2..f81f3fd7a9e0 100644 --- a/drivers/pci/controller/Makefile +++ b/drivers/pci/controller/Makefile @@ -1,6 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_PCIE_CADENCE) += cadence/ obj-$(CONFIG_PCI_FTPCI100) += pci-ftpci100.o +obj-$(CONFIG_PCI_IXP4XX) += pci-ixp4xx.o obj-$(CONFIG_PCI_HYPERV) += pci-hyperv.o obj-$(CONFIG_PCI_HYPERV_INTERFACE) += pci-hyperv-intf.o obj-$(CONFIG_PCI_MVEBU) += pci-mvebu.o diff --git a/drivers/pci/controller/pci-ixp4xx.c b/drivers/pci/controller/pci-ixp4xx.c new file mode 100644 index 000000000000..313fbe7cf177 --- /dev/null +++ b/drivers/pci/controller/pci-ixp4xx.c @@ -0,0 +1,684 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Support for Intel IXP4xx PCI host controller + * + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> + * + * Based on the IXP4xx arch/arm/mach-ixp4xx/common-pci.c driver + * Copyright (C) 2002 Intel Corporation + * Copyright (C) 2003 Greg Ungerer <gerg@linux-m68k.org> + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * Copyright (C) 2005 Deepak Saxena <dsaxena@plexity.net> + * Copyright (C) 2005 Alessandro Zummo <a.zummo@towertech.it> + * + * TODO: + * - Test IO-space access + * - DMA support + */ + +#include <linux/init.h> +#include <linux/io.h> +#include <linux/kernel.h> +#include <linux/of_address.h> +#include <linux/of_device.h> +#include <linux/of_pci.h> +#include <linux/pci.h> +#include <linux/platform_device.h> +#include <linux/slab.h> +#include <linux/bits.h> + +#include "../pci.h" + +/* Register offsets */ +#define IXP4XX_PCI_NP_AD 0x00 +#define IXP4XX_PCI_NP_CBE 0x04 +#define IXP4XX_PCI_NP_WDATA 0x08 +#define IXP4XX_PCI_NP_RDATA 0x0c +#define IXP4XX_PCI_CRP_AD_CBE 0x10 +#define IXP4XX_PCI_CRP_WDATA 0x14 +#define IXP4XX_PCI_CRP_RDATA 0x18 +#define IXP4XX_PCI_CSR 0x1c +#define IXP4XX_PCI_ISR 0x20 +#define IXP4XX_PCI_INTEN 0x24 +#define IXP4XX_PCI_DMACTRL 0x28 +#define IXP4XX_PCI_AHBMEMBASE 0x2c +#define IXP4XX_PCI_AHBIOBASE 0x30 +#define IXP4XX_PCI_PCIMEMBASE 0x34 +#define IXP4XX_PCI_AHBDOORBELL 0x38 +#define IXP4XX_PCI_PCIDOORBELL 0x3C +#define IXP4XX_PCI_ATPDMA0_AHBADDR 0x40 +#define IXP4XX_PCI_ATPDMA0_PCIADDR 0x44 +#define IXP4XX_PCI_ATPDMA0_LENADDR 0x48 +#define IXP4XX_PCI_ATPDMA1_AHBADDR 0x4C +#define IXP4XX_PCI_ATPDMA1_PCIADDR 0x50 +#define IXP4XX_PCI_ATPDMA1_LENADDR 0x54 + +/* CSR bit definitions */ +#define IXP4XX_PCI_CSR_HOST BIT(0) +#define IXP4XX_PCI_CSR_ARBEN BIT(1) +#define IXP4XX_PCI_CSR_ADS BIT(2) +#define IXP4XX_PCI_CSR_PDS BIT(3) +#define IXP4XX_PCI_CSR_ABE BIT(4) +#define IXP4XX_PCI_CSR_DBT BIT(5) +#define IXP4XX_PCI_CSR_ASE BIT(8) +#define IXP4XX_PCI_CSR_IC BIT(15) +#define IXP4XX_PCI_CSR_PRST BIT(16) + +/* ISR (Interrupt status) Register bit definitions */ +#define IXP4XX_PCI_ISR_PSE BIT(0) +#define IXP4XX_PCI_ISR_PFE BIT(1) +#define IXP4XX_PCI_ISR_PPE BIT(2) +#define IXP4XX_PCI_ISR_AHBE BIT(3) +#define IXP4XX_PCI_ISR_APDC BIT(4) +#define IXP4XX_PCI_ISR_PADC BIT(5) +#define IXP4XX_PCI_ISR_ADB BIT(6) +#define IXP4XX_PCI_ISR_PDB BIT(7) + +/* INTEN (Interrupt Enable) Register bit definitions */ +#define IXP4XX_PCI_INTEN_PSE BIT(0) +#define IXP4XX_PCI_INTEN_PFE BIT(1) +#define IXP4XX_PCI_INTEN_PPE BIT(2) +#define IXP4XX_PCI_INTEN_AHBE BIT(3) +#define IXP4XX_PCI_INTEN_APDC BIT(4) +#define IXP4XX_PCI_INTEN_PADC BIT(5) +#define IXP4XX_PCI_INTEN_ADB BIT(6) +#define IXP4XX_PCI_INTEN_PDB BIT(7) + +/* Shift value for byte enable on NP cmd/byte enable register */ +#define IXP4XX_PCI_NP_CBE_BESL 4 + +/* PCI commands supported by NP access unit */ +#define NP_CMD_IOREAD 0x2 +#define NP_CMD_IOWRITE 0x3 +#define NP_CMD_CONFIGREAD 0xa +#define NP_CMD_CONFIGWRITE 0xb +#define NP_CMD_MEMREAD 0x6 +#define NP_CMD_MEMWRITE 0x7 + +/* Constants for CRP access into local config space */ +#define CRP_AD_CBE_BESL 20 +#define CRP_AD_CBE_WRITE 0x00010000 + +/* Special PCI configuration space registers for this controller */ +#define IXP4XX_PCI_RTOTTO 0x40 + +struct ixp4xx_pci { + struct device *dev; + void __iomem *base; + struct pci_bus *bus; + raw_spinlock_t lock; /* Protects bus writes */ + bool errata_hammer; + bool host_mode; +}; + +static int ixp4xx_pci_check_master_abort(struct ixp4xx_pci *p) +{ + u32 isr = __raw_readl(p->base + IXP4XX_PCI_ISR); + + if (isr & IXP4XX_PCI_ISR_PFE) { + /* Make sure the master abort bit is reset */ + __raw_writel(IXP4XX_PCI_ISR_PFE, p->base + IXP4XX_PCI_ISR); + dev_dbg(p->dev, "master abort detected\n"); + return -EINVAL; + } + + return 0; +} + +static int ixp4xx_pci_read(struct ixp4xx_pci *p, u32 addr, u32 cmd, u32 *data) +{ + unsigned long flags; + int ret; + + raw_spin_lock_irqsave(&p->lock, flags); + + __raw_writel(addr, p->base + IXP4XX_PCI_NP_AD); + + if (p->errata_hammer) { + int i; + + /* + * PCI workaround - only works if NP PCI space reads have + * no side effects. Hammer the register and read twice 8 + * times. last one will be good. + */ + for (i = 0; i < 8; i++) { + __raw_writel(cmd, p->base + IXP4XX_PCI_NP_CBE); + *data = __raw_readl(p->base + IXP4XX_PCI_NP_RDATA); + *data = __raw_readl(p->base + IXP4XX_PCI_NP_RDATA); + } + } else { + __raw_writel(cmd, p->base + IXP4XX_PCI_NP_CBE); + *data = __raw_readl(p->base + IXP4XX_PCI_NP_RDATA); + } + + /* Check for master abort */ + ret = ixp4xx_pci_check_master_abort(p); + + raw_spin_unlock_irqrestore(&p->lock, flags); + return ret; +} + +static int ixp4xx_pci_write(struct ixp4xx_pci *p, u32 addr, u32 cmd, u32 data) +{ + unsigned long flags; + int ret; + + raw_spin_lock_irqsave(&p->lock, flags); + + __raw_writel(addr, p->base + IXP4XX_PCI_NP_AD); + + /* Set up the write */ + __raw_writel(cmd, p->base + IXP4XX_PCI_NP_CBE); + + /* Execute the write by writing to NP_WDATA */ + __raw_writel(data, p->base + IXP4XX_PCI_NP_WDATA); + + /* Check for master abort */ + ret = ixp4xx_pci_check_master_abort(p); + + raw_spin_unlock_irqrestore(&p->lock, flags); + return ret; +} + +static u32 ixp4xx_config_addr(u8 bus_num, u16 devfn, int where) +{ + u32 addr; + + if (!bus_num) { + /* type 0 */ + addr = BIT(32-PCI_SLOT(devfn)) | ((PCI_FUNC(devfn)) << 8) | + (where & ~3); + } else { + /* type 1 */ + addr = (bus_num << 16) | ((PCI_SLOT(devfn)) << 11) | + ((PCI_FUNC(devfn)) << 8) | (where & ~3) | 1; + } + return addr; +} + +/* + * CRP functions are "Controller Configuration Port" accesses + * initiated from within this driver itself to read/write PCI + * control information in the config space. + */ +static u32 ixp4xx_crp_byte_lane_enable_bits(u32 n, int size) +{ + if (size == 1) + return (0xf & ~BIT(n)) << CRP_AD_CBE_BESL; + if (size == 2) + return (0xf & ~(BIT(n) | BIT(n+1))) << CRP_AD_CBE_BESL; + if (size == 4) + return 0; + return 0xffffffff; +} + +static int ixp4xx_crp_read_config(struct ixp4xx_pci *p, int where, int size, + u32 *value) +{ + unsigned long flags; + u32 n, cmd, val; + + n = where % 4; + cmd = where & ~3; + + dev_dbg(p->dev, "%s from %d size %d cmd %08x\n", + __func__, where, size, cmd); + + raw_spin_lock_irqsave(&p->lock, flags); + __raw_writel(cmd, p->base + IXP4XX_PCI_CRP_AD_CBE); + val = __raw_readl(p->base + IXP4XX_PCI_CRP_RDATA); + raw_spin_unlock_irqrestore(&p->lock, flags); + + val >>= (8*n); + switch (size) { + case 1: + val &= U8_MAX; + dev_dbg(p->dev, "%s read byte %02x\n", __func__, val); + break; + case 2: + val &= U16_MAX; + dev_dbg(p->dev, "%s read word %04x\n", __func__, val); + break; + case 4: + val &= U32_MAX; + dev_dbg(p->dev, "%s read long %08x\n", __func__, val); + break; + default: + /* Should not happen */ + dev_err(p->dev, "%s illegal size\n", __func__); + return PCIBIOS_DEVICE_NOT_FOUND; + } + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int ixp4xx_crp_write_config(struct ixp4xx_pci *p, int where, int size, + u32 value) +{ + unsigned long flags; + u32 n, cmd, val; + + n = where % 4; + cmd = ixp4xx_crp_byte_lane_enable_bits(n, size); + if (cmd == 0xffffffff) + return PCIBIOS_BAD_REGISTER_NUMBER; + cmd |= where & ~3; + cmd |= CRP_AD_CBE_WRITE; + + val = value << (8*n); + + dev_dbg(p->dev, "%s to %d size %d cmd %08x val %08x\n", + __func__, where, size, cmd, val); + + raw_spin_lock_irqsave(&p->lock, flags); + __raw_writel(cmd, p->base + IXP4XX_PCI_CRP_AD_CBE); + __raw_writel(val, p->base + IXP4XX_PCI_CRP_WDATA); + raw_spin_unlock_irqrestore(&p->lock, flags); + + return PCIBIOS_SUCCESSFUL; +} + +/* + * Then follows the functions that read and write from the common + * PCI configuration space. + */ + +static u32 ixp4xx_byte_lane_enable_bits(u32 n, int size) +{ + if (size == 1) + return (0xf & ~BIT(n)) << 4; + if (size == 2) + return (0xf & ~(BIT(n) | BIT(n+1))) << 4; + if (size == 4) + return 0; + return 0xffffffff; +} + +static int ixp4xx_pci_read_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 *value) +{ + struct ixp4xx_pci *p = bus->sysdata; + u32 n, addr, val, cmd; + u8 bus_num = bus->number; + int ret; + + *value = 0xffffffff; + n = where % 4; + cmd = ixp4xx_byte_lane_enable_bits(n, size); + if (cmd == 0xffffffff) + return PCIBIOS_BAD_REGISTER_NUMBER; + + addr = ixp4xx_config_addr(bus_num, devfn, where); + cmd |= NP_CMD_CONFIGREAD; + dev_dbg(p->dev, "read_config from %d size %d dev %d:%d:%d address: %08x cmd: %08x\n", + where, size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn), addr, cmd); + + ret = ixp4xx_pci_read(p, addr, cmd, &val); + if (ret) + return PCIBIOS_DEVICE_NOT_FOUND; + + val >>= (8*n); + switch (size) { + case 1: + val &= U8_MAX; + dev_dbg(p->dev, "%s read byte %02x\n", __func__, val); + break; + case 2: + val &= U16_MAX; + dev_dbg(p->dev, "%s read word %04x\n", __func__, val); + break; + case 4: + val &= U32_MAX; + dev_dbg(p->dev, "%s read long %08x\n", __func__, val); + break; + default: + /* Should not happen */ + dev_err(p->dev, "%s illegal size\n", __func__); + return PCIBIOS_DEVICE_NOT_FOUND; + } + *value = val; + + return PCIBIOS_SUCCESSFUL; +} + +static int ixp4xx_pci_write_config(struct pci_bus *bus, unsigned int devfn, + int where, int size, u32 value) +{ + struct ixp4xx_pci *p = bus->sysdata; + u32 n, addr, val, cmd; + u8 bus_num = bus->number; + int ret; + + n = where % 4; + cmd = ixp4xx_byte_lane_enable_bits(n, size); + if (cmd == 0xffffffff) + return PCIBIOS_BAD_REGISTER_NUMBER; + + addr = ixp4xx_config_addr(bus_num, devfn, where); + cmd |= NP_CMD_CONFIGWRITE; + val = value << (8*n); + + dev_dbg(p->dev, "write_config_byte %#x to %d size %d dev %d:%d:%d addr: %08x cmd %08x\n", + value, where, size, bus_num, PCI_SLOT(devfn), PCI_FUNC(devfn), addr, cmd); + + ret = ixp4xx_pci_write(p, addr, cmd, val); + if (ret) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + +static struct pci_ops ixp4xx_pci_ops = { + .read = ixp4xx_pci_read_config, + .write = ixp4xx_pci_write_config, +}; + +static u32 ixp4xx_pci_addr_to_64mconf(phys_addr_t addr) +{ + u8 base; + + base = ((addr & 0xff000000) >> 24); + return (base << 24) | ((base + 1) << 16) + | ((base + 2) << 8) | (base + 3); +} + +static int ixp4xx_pci_parse_map_ranges(struct ixp4xx_pci *p) +{ + struct device *dev = p->dev; + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(p); + struct resource_entry *win; + struct resource *res; + phys_addr_t addr; + + win = resource_list_first_type(&bridge->windows, IORESOURCE_MEM); + if (win) { + u32 pcimembase; + + res = win->res; + addr = res->start - win->offset; + + if (res->flags & IORESOURCE_PREFETCH) + res->name = "IXP4xx PCI PRE-MEM"; + else + res->name = "IXP4xx PCI NON-PRE-MEM"; + + dev_dbg(dev, "%s window %pR, bus addr %pa\n", + res->name, res, &addr); + if (resource_size(res) != SZ_64M) { + dev_err(dev, "memory range is not 64MB\n"); + return -EINVAL; + } + + pcimembase = ixp4xx_pci_addr_to_64mconf(addr); + /* Commit configuration */ + __raw_writel(pcimembase, p->base + IXP4XX_PCI_PCIMEMBASE); + } else { + dev_err(dev, "no AHB memory mapping defined\n"); + } + + win = resource_list_first_type(&bridge->windows, IORESOURCE_IO); + if (win) { + res = win->res; + + addr = pci_pio_to_address(res->start); + if (addr & 0xff) { + dev_err(dev, "IO mem at uneven address: %pa\n", &addr); + return -EINVAL; + } + + res->name = "IXP4xx PCI IO MEM"; + /* + * Setup I/O space location for PCI->AHB access, the + * upper 24 bits of the address goes into the lower + * 24 bits of this register. + */ + __raw_writel((addr >> 8), p->base + IXP4XX_PCI_AHBIOBASE); + } else { + dev_info(dev, "no IO space AHB memory mapping defined\n"); + } + + return 0; +} + +static int ixp4xx_pci_parse_map_dma_ranges(struct ixp4xx_pci *p) +{ + struct device *dev = p->dev; + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(p); + struct resource_entry *win; + struct resource *res; + phys_addr_t addr; + u32 ahbmembase; + + win = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM); + if (win) { + res = win->res; + addr = res->start - win->offset; + + if (resource_size(res) != SZ_64M) { + dev_err(dev, "DMA memory range is not 64MB\n"); + return -EINVAL; + } + + dev_dbg(dev, "DMA MEM BASE: %pa\n", &addr); + /* + * 4 PCI-to-AHB windows of 16 MB each, write the 8 high bits + * into each byte of the PCI_AHBMEMBASE register. + */ + ahbmembase = ixp4xx_pci_addr_to_64mconf(addr); + /* Commit AHB membase */ + __raw_writel(ahbmembase, p->base + IXP4XX_PCI_AHBMEMBASE); + } else { + dev_err(dev, "no DMA memory range defined\n"); + } + + return 0; +} + +/* Only used to get context for abort handling */ +static struct ixp4xx_pci *ixp4xx_pci_abort_singleton; + +static int ixp4xx_pci_abort_handler(unsigned long addr, unsigned int fsr, + struct pt_regs *regs) +{ + struct ixp4xx_pci *p = ixp4xx_pci_abort_singleton; + u32 isr, status; + int ret; + + isr = __raw_readl(p->base + IXP4XX_PCI_ISR); + ret = ixp4xx_crp_read_config(p, PCI_STATUS, 2, &status); + if (ret) { + dev_err(p->dev, "unable to read abort status\n"); + return -EINVAL; + } + + dev_err(p->dev, + "PCI: abort_handler addr = %#lx, isr = %#x, status = %#x\n", + addr, isr, status); + + /* Make sure the Master Abort bit is reset */ + __raw_writel(IXP4XX_PCI_ISR_PFE, p->base + IXP4XX_PCI_ISR); + status |= PCI_STATUS_REC_MASTER_ABORT; + ret = ixp4xx_crp_write_config(p, PCI_STATUS, 2, status); + if (ret) + dev_err(p->dev, "unable to clear abort status bit\n"); + + /* + * If it was an imprecise abort, then we need to correct the + * return address to be _after_ the instruction. + */ + if (fsr & (1 << 10)) { + dev_err(p->dev, "imprecise abort\n"); + regs->ARM_pc += 4; + } + + return 0; +} + +static int ixp4xx_pci_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct device_node *np = dev->of_node; + struct ixp4xx_pci *p; + struct pci_host_bridge *host; + int ret; + u32 val; + phys_addr_t addr; + u32 basereg[4] = { + PCI_BASE_ADDRESS_0, + PCI_BASE_ADDRESS_1, + PCI_BASE_ADDRESS_2, + PCI_BASE_ADDRESS_3, + }; + int i; + + host = devm_pci_alloc_host_bridge(dev, sizeof(*p)); + if (!host) + return -ENOMEM; + + host->ops = &ixp4xx_pci_ops; + p = pci_host_bridge_priv(host); + host->sysdata = p; + p->dev = dev; + raw_spin_lock_init(&p->lock); + + /* + * Set up quirk for erratic behaviour in the 42x variant + * when accessing config space. + */ + if (of_device_is_compatible(np, "intel,ixp42x-pci")) { + p->errata_hammer = true; + dev_info(dev, "activate hammering errata\n"); + } + + p->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(p->base)) + return PTR_ERR(p->base); + + val = __raw_readl(p->base + IXP4XX_PCI_CSR); + p->host_mode = !!(val & IXP4XX_PCI_CSR_HOST); + dev_info(dev, "controller is in %s mode\n", + p->host_mode ? "host" : "option"); + + /* Hook in our fault handler for PCI errors */ + ixp4xx_pci_abort_singleton = p; + hook_fault_code(16+6, ixp4xx_pci_abort_handler, SIGBUS, 0, + "imprecise external abort"); + + ret = ixp4xx_pci_parse_map_ranges(p); + if (ret) + return ret; + + ret = ixp4xx_pci_parse_map_dma_ranges(p); + if (ret) + return ret; + + /* This is only configured in host mode */ + if (p->host_mode) { + addr = __pa(PAGE_OFFSET); + /* This is a noop (0x00) but explains what is going on */ + addr |= PCI_BASE_ADDRESS_SPACE_MEMORY; + + for (i = 0; i < 4; i++) { + /* Write this directly into the config space */ + ret = ixp4xx_crp_write_config(p, basereg[i], 4, addr); + if (ret) + dev_err(dev, "failed to set up PCI_BASE_ADDRESS_%d\n", i); + else + dev_info(dev, "set PCI_BASE_ADDR_%d to %pa\n", i, &addr); + addr += SZ_16M; + } + + /* + * Enable CSR window at 64 MiB to allow PCI masters to continue + * prefetching past the 64 MiB boundary, if all AHB to PCI windows + * are consecutive. + */ + ret = ixp4xx_crp_write_config(p, PCI_BASE_ADDRESS_4, 4, addr); + if (ret) + dev_err(dev, "failed to set up PCI_BASE_ADDRESS_4\n"); + else + dev_info(dev, "set PCI_BASE_ADDR_4 to %pa\n", &addr); + + /* + * Put the IO memory at the very end of physical memory at + * 0xfffffc00. This is when the PCI is trying to access IO + * memory over AHB. + */ + addr = 0xfffffc00; + addr |= PCI_BASE_ADDRESS_SPACE_IO; + ret = ixp4xx_crp_write_config(p, PCI_BASE_ADDRESS_5, 4, addr); + if (ret) + dev_err(dev, "failed to set up PCI_BASE_ADDRESS_5\n"); + else + dev_info(dev, "set PCI_BASE_ADDR_5 to %pa\n", &addr); + + /* + * Retry timeout to 0x80 + * Transfer ready timeout to 0xff + */ + ret = ixp4xx_crp_write_config(p, IXP4XX_PCI_RTOTTO, 4, + 0x000080ff); + if (ret) + dev_err(dev, "failed to set up TRDY limit\n"); + else + dev_info(dev, "set TRDY limit to 0x80ff\n"); + } + + /* Clear interrupts */ + val = IXP4XX_PCI_ISR_PSE | IXP4XX_PCI_ISR_PFE | IXP4XX_PCI_ISR_PPE | IXP4XX_PCI_ISR_AHBE; + __raw_writel(val, p->base + IXP4XX_PCI_ISR); + + /* + * Set Initialize Complete in PCI Control Register: allow IXP4XX to + * respond to PCI configuration cycles. Specify that the AHB bus is + * operating in big endian mode. Set up byte lane swapping between + * little-endian PCI and the big-endian AHB bus. + */ + val = IXP4XX_PCI_CSR_IC | IXP4XX_PCI_CSR_ABE; +#ifdef __ARMEB__ + val |= (IXP4XX_PCI_CSR_PDS | IXP4XX_PCI_CSR_ADS); +#endif + __raw_writel(val, p->base + IXP4XX_PCI_CSR); + + + ret = ixp4xx_crp_write_config(p, PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); + if (ret) + dev_err(dev, "unable to initialize master and command memory\n"); + else + dev_info(dev, "initialized as master\n"); + + ret = pci_scan_root_bus_bridge(host); + if (ret) { + dev_err(dev, "failed to scan host: %d\n", ret); + return ret; + } + + p->bus = host->bus; + + pci_bus_assign_resources(p->bus); + pci_bus_add_devices(p->bus); + + return 0; +} + +static const struct of_device_id ixp4xx_pci_of_match[] = { + { + .compatible = "intel,ixp42x-pci", + }, + { + .compatible = "intel,ixp43x-pci", + }, + {}, +}; + +static struct platform_driver ixp4xx_pci_driver = { + .driver = { + .name = "ixp4xx-pci", + .of_match_table = of_match_ptr(ixp4xx_pci_of_match), + .suppress_bind_attrs = true, + }, + .probe = ixp4xx_pci_probe, +}; +builtin_platform_driver(ixp4xx_pci_driver); -- 2.29.2 ^ permalink raw reply related [flat|nested] 11+ messages in thread
* Re: [PATCH 4/4] PCI: ixp4xx: Add a new driver for IXP4xx 2021-05-03 21:16 ` [PATCH 4/4] PCI: ixp4xx: Add a new driver " Linus Walleij @ 2021-05-04 0:40 ` kernel test robot 2021-05-04 7:12 ` Arnd Bergmann 1 sibling, 0 replies; 11+ messages in thread From: kernel test robot @ 2021-05-04 0:40 UTC (permalink / raw) To: Linus Walleij, Bjorn Helgaas Cc: kbuild-all, linux-pci, Arnd Bergmann, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight, Linus Walleij [-- Attachment #1: Type: text/plain, Size: 8774 bytes --] Hi Linus, I love your patch! Yet something to improve: [auto build test ERROR on soc/for-next] [also build test ERROR on pci/next block/for-next linus/master v5.12 next-20210503] [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/Linus-Walleij/IXP4xx-PCI-rework/20210504-051847 base: https://git.kernel.org/pub/scm/linux/kernel/git/soc/soc.git for-next config: ia64-allmodconfig (attached as .config) compiler: ia64-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/f3c7dd73e6c1b358e1f61a4b3a186ce5b336deaf git remote add linux-review https://github.com/0day-ci/linux git fetch --no-tags linux-review Linus-Walleij/IXP4xx-PCI-rework/20210504-051847 git checkout f3c7dd73e6c1b358e1f61a4b3a186ce5b336deaf # save the attached .config to linux build tree COMPILER_INSTALL_PATH=$HOME/0day COMPILER=gcc-9.3.0 make.cross W=1 ARCH=ia64 If you fix the issue, kindly add following tag as appropriate Reported-by: kernel test robot <lkp@intel.com> All errors (new ones prefixed by >>): drivers/pci/controller/pci-ixp4xx.c: In function 'ixp4xx_pci_abort_handler': >> drivers/pci/controller/pci-ixp4xx.c:513:7: error: 'struct pt_regs' has no member named 'ARM_pc' 513 | regs->ARM_pc += 4; | ^~ drivers/pci/controller/pci-ixp4xx.c: In function 'ixp4xx_pci_probe': >> drivers/pci/controller/pci-ixp4xx.c:566:2: error: implicit declaration of function 'hook_fault_code' [-Werror=implicit-function-declaration] 566 | hook_fault_code(16+6, ixp4xx_pci_abort_handler, SIGBUS, 0, | ^~~~~~~~~~~~~~~ cc1: some warnings being treated as errors Kconfig warnings: (for reference only) WARNING: unmet direct dependencies detected for FRAME_POINTER Depends on DEBUG_KERNEL && (M68K || UML || SUPERH) || ARCH_WANT_FRAME_POINTERS Selected by - FAULT_INJECTION_STACKTRACE_FILTER && FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT && !X86_64 && !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM && !ARC && !X86 vim +513 drivers/pci/controller/pci-ixp4xx.c 481 482 static int ixp4xx_pci_abort_handler(unsigned long addr, unsigned int fsr, 483 struct pt_regs *regs) 484 { 485 struct ixp4xx_pci *p = ixp4xx_pci_abort_singleton; 486 u32 isr, status; 487 int ret; 488 489 isr = __raw_readl(p->base + IXP4XX_PCI_ISR); 490 ret = ixp4xx_crp_read_config(p, PCI_STATUS, 2, &status); 491 if (ret) { 492 dev_err(p->dev, "unable to read abort status\n"); 493 return -EINVAL; 494 } 495 496 dev_err(p->dev, 497 "PCI: abort_handler addr = %#lx, isr = %#x, status = %#x\n", 498 addr, isr, status); 499 500 /* Make sure the Master Abort bit is reset */ 501 __raw_writel(IXP4XX_PCI_ISR_PFE, p->base + IXP4XX_PCI_ISR); 502 status |= PCI_STATUS_REC_MASTER_ABORT; 503 ret = ixp4xx_crp_write_config(p, PCI_STATUS, 2, status); 504 if (ret) 505 dev_err(p->dev, "unable to clear abort status bit\n"); 506 507 /* 508 * If it was an imprecise abort, then we need to correct the 509 * return address to be _after_ the instruction. 510 */ 511 if (fsr & (1 << 10)) { 512 dev_err(p->dev, "imprecise abort\n"); > 513 regs->ARM_pc += 4; 514 } 515 516 return 0; 517 } 518 519 static int ixp4xx_pci_probe(struct platform_device *pdev) 520 { 521 struct device *dev = &pdev->dev; 522 struct device_node *np = dev->of_node; 523 struct ixp4xx_pci *p; 524 struct pci_host_bridge *host; 525 int ret; 526 u32 val; 527 phys_addr_t addr; 528 u32 basereg[4] = { 529 PCI_BASE_ADDRESS_0, 530 PCI_BASE_ADDRESS_1, 531 PCI_BASE_ADDRESS_2, 532 PCI_BASE_ADDRESS_3, 533 }; 534 int i; 535 536 host = devm_pci_alloc_host_bridge(dev, sizeof(*p)); 537 if (!host) 538 return -ENOMEM; 539 540 host->ops = &ixp4xx_pci_ops; 541 p = pci_host_bridge_priv(host); 542 host->sysdata = p; 543 p->dev = dev; 544 raw_spin_lock_init(&p->lock); 545 546 /* 547 * Set up quirk for erratic behaviour in the 42x variant 548 * when accessing config space. 549 */ 550 if (of_device_is_compatible(np, "intel,ixp42x-pci")) { 551 p->errata_hammer = true; 552 dev_info(dev, "activate hammering errata\n"); 553 } 554 555 p->base = devm_platform_ioremap_resource(pdev, 0); 556 if (IS_ERR(p->base)) 557 return PTR_ERR(p->base); 558 559 val = __raw_readl(p->base + IXP4XX_PCI_CSR); 560 p->host_mode = !!(val & IXP4XX_PCI_CSR_HOST); 561 dev_info(dev, "controller is in %s mode\n", 562 p->host_mode ? "host" : "option"); 563 564 /* Hook in our fault handler for PCI errors */ 565 ixp4xx_pci_abort_singleton = p; > 566 hook_fault_code(16+6, ixp4xx_pci_abort_handler, SIGBUS, 0, 567 "imprecise external abort"); 568 569 ret = ixp4xx_pci_parse_map_ranges(p); 570 if (ret) 571 return ret; 572 573 ret = ixp4xx_pci_parse_map_dma_ranges(p); 574 if (ret) 575 return ret; 576 577 /* This is only configured in host mode */ 578 if (p->host_mode) { 579 addr = __pa(PAGE_OFFSET); 580 /* This is a noop (0x00) but explains what is going on */ 581 addr |= PCI_BASE_ADDRESS_SPACE_MEMORY; 582 583 for (i = 0; i < 4; i++) { 584 /* Write this directly into the config space */ 585 ret = ixp4xx_crp_write_config(p, basereg[i], 4, addr); 586 if (ret) 587 dev_err(dev, "failed to set up PCI_BASE_ADDRESS_%d\n", i); 588 else 589 dev_info(dev, "set PCI_BASE_ADDR_%d to %pa\n", i, &addr); 590 addr += SZ_16M; 591 } 592 593 /* 594 * Enable CSR window at 64 MiB to allow PCI masters to continue 595 * prefetching past the 64 MiB boundary, if all AHB to PCI windows 596 * are consecutive. 597 */ 598 ret = ixp4xx_crp_write_config(p, PCI_BASE_ADDRESS_4, 4, addr); 599 if (ret) 600 dev_err(dev, "failed to set up PCI_BASE_ADDRESS_4\n"); 601 else 602 dev_info(dev, "set PCI_BASE_ADDR_4 to %pa\n", &addr); 603 604 /* 605 * Put the IO memory at the very end of physical memory at 606 * 0xfffffc00. This is when the PCI is trying to access IO 607 * memory over AHB. 608 */ 609 addr = 0xfffffc00; 610 addr |= PCI_BASE_ADDRESS_SPACE_IO; 611 ret = ixp4xx_crp_write_config(p, PCI_BASE_ADDRESS_5, 4, addr); 612 if (ret) 613 dev_err(dev, "failed to set up PCI_BASE_ADDRESS_5\n"); 614 else 615 dev_info(dev, "set PCI_BASE_ADDR_5 to %pa\n", &addr); 616 617 /* 618 * Retry timeout to 0x80 619 * Transfer ready timeout to 0xff 620 */ 621 ret = ixp4xx_crp_write_config(p, IXP4XX_PCI_RTOTTO, 4, 622 0x000080ff); 623 if (ret) 624 dev_err(dev, "failed to set up TRDY limit\n"); 625 else 626 dev_info(dev, "set TRDY limit to 0x80ff\n"); 627 } 628 629 /* Clear interrupts */ 630 val = IXP4XX_PCI_ISR_PSE | IXP4XX_PCI_ISR_PFE | IXP4XX_PCI_ISR_PPE | IXP4XX_PCI_ISR_AHBE; 631 __raw_writel(val, p->base + IXP4XX_PCI_ISR); 632 633 /* 634 * Set Initialize Complete in PCI Control Register: allow IXP4XX to 635 * respond to PCI configuration cycles. Specify that the AHB bus is 636 * operating in big endian mode. Set up byte lane swapping between 637 * little-endian PCI and the big-endian AHB bus. 638 */ 639 val = IXP4XX_PCI_CSR_IC | IXP4XX_PCI_CSR_ABE; 640 #ifdef __ARMEB__ 641 val |= (IXP4XX_PCI_CSR_PDS | IXP4XX_PCI_CSR_ADS); 642 #endif 643 __raw_writel(val, p->base + IXP4XX_PCI_CSR); 644 645 646 ret = ixp4xx_crp_write_config(p, PCI_COMMAND, 2, PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY); 647 if (ret) 648 dev_err(dev, "unable to initialize master and command memory\n"); 649 else 650 dev_info(dev, "initialized as master\n"); 651 652 ret = pci_scan_root_bus_bridge(host); 653 if (ret) { 654 dev_err(dev, "failed to scan host: %d\n", ret); 655 return ret; 656 } 657 658 p->bus = host->bus; 659 660 pci_bus_assign_resources(p->bus); 661 pci_bus_add_devices(p->bus); 662 663 return 0; 664 } 665 --- 0-DAY CI Kernel Test Service, Intel Corporation https://lists.01.org/hyperkitty/list/kbuild-all@lists.01.org [-- Attachment #2: .config.gz --] [-- Type: application/gzip, Size: 63879 bytes --] ^ permalink raw reply [flat|nested] 11+ messages in thread
* Re: [PATCH 4/4] PCI: ixp4xx: Add a new driver for IXP4xx 2021-05-03 21:16 ` [PATCH 4/4] PCI: ixp4xx: Add a new driver " Linus Walleij 2021-05-04 0:40 ` kernel test robot @ 2021-05-04 7:12 ` Arnd Bergmann 1 sibling, 0 replies; 11+ messages in thread From: Arnd Bergmann @ 2021-05-04 7:12 UTC (permalink / raw) To: Linus Walleij Cc: Bjorn Helgaas, linux-pci, Imre Kaloz, Krzysztof Halasa, Zoltan HERPAI, Raylynn Knight On Mon, May 3, 2021 at 11:16 PM Linus Walleij <linus.walleij@linaro.org> wrote: > > This adds a new PCI controller driver for the Intel IXP4xx > (IX425, IXP435 etc), based on the XScale microarchitecture. > > This replaces the old driver in arch/arm/mach-ixp4xx/common-pci.c > which utilized the ARM-specific BIOS32 PCI framework, > and all parameterization for such things as memory and > IO space as well as interrupt swizzling is done from the > device tree. Nice work! > The __raw_writel() and __raw_readl() are used for accessing > the PCI controller for the same reason that these accessors > are used in the timer, IRQ and GPIO drivers: the platform > will alter its address bus pattern based on whether the > system is booted in big- or little-endian mode. For this > reason all register on IXP4xx must always be accessed in > native (CPU) endianness. Can you add a pair of inline function that wraps these into a driver specific helper with a comment? > This driver supports 64MB of PCI memory space, but not the > indirect access of 1GB that is available in the old driver. > We can address that later if and only if there are users > that need all 1GB of PCI address space. > + > + ret = pci_scan_root_bus_bridge(host); > + if (ret) { > + dev_err(dev, "failed to scan host: %d\n", ret); > + return ret; > + } > + > + p->bus = host->bus; I don't think you need to store the bus separately, just use host->bus everywhere. > + pci_bus_assign_resources(p->bus); > + pci_bus_add_devices(p->bus); Can you call pci_host_probe() instead of open-coding it here? > + > +static struct platform_driver ixp4xx_pci_driver = { > + .driver = { > + .name = "ixp4xx-pci", > + .of_match_table = of_match_ptr(ixp4xx_pci_of_match), > + .suppress_bind_attrs = true, > + }, > + .probe = ixp4xx_pci_probe, > +}; > +builtin_platform_driver(ixp4xx_pci_driver); It should be possible to make it a loadable module, after Rob Herring fixed some of the bugs around that. Arnd ^ permalink raw reply [flat|nested] 11+ messages in thread
end of thread, other threads:[~2021-05-09 21:31 UTC | newest] Thread overview: 11+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2021-05-03 21:16 [PATCH 0/4] IXP4xx PCI rework Linus Walleij 2021-05-03 21:16 ` [PATCH 1/4] ARM/ixp4xx: Move the UART and exp bus virtbases Linus Walleij 2021-05-04 7:38 ` Arnd Bergmann 2021-05-03 21:16 ` [PATCH 2/4] ARM/ixp4xx: Make NEED_MACH_IO_H optional Linus Walleij 2021-05-03 21:16 ` [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx Linus Walleij 2021-05-04 12:54 ` Arnd Bergmann 2021-05-09 21:31 ` Linus Walleij 2021-05-06 20:24 ` Rob Herring 2021-05-03 21:16 ` [PATCH 4/4] PCI: ixp4xx: Add a new driver " Linus Walleij 2021-05-04 0:40 ` kernel test robot 2021-05-04 7:12 ` Arnd Bergmann
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).