From patchwork Mon May 3 21:16:46 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12237029 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 99AABC433ED for ; Mon, 3 May 2021 21:16:56 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7484161186 for ; Mon, 3 May 2021 21:16:56 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229596AbhECVRt (ORCPT ); Mon, 3 May 2021 17:17:49 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56816 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229499AbhECVRt (ORCPT ); Mon, 3 May 2021 17:17:49 -0400 Received: from mail-lf1-x135.google.com (mail-lf1-x135.google.com [IPv6:2a00:1450:4864:20::135]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 52FEFC061573 for ; Mon, 3 May 2021 14:16:55 -0700 (PDT) Received: by mail-lf1-x135.google.com with SMTP id z9so5671294lfu.8 for ; Mon, 03 May 2021 14:16:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=UeUdJecAQ1EFBmsBBl7X0ql/Ifw+M/goFR+FKShjaLo=; b=zhGp2kGTw3vlEVfjhYFCtNJOAqf1HfplFQw791ZqhNotLlasQ1zML9yHB3OX6lSHdA SFgQijLpnwaQgujXjjSDEy0yjHlVoyhUKU9RGfzr50X11f2ayWp+x6yXsoj8USsxOa+1 B6LDXSzlCjMk6nl7iOp4FYUyoEIrvIvwh/w7dOub31UVGdUMPwK+3M2pF63buDdODSd+ mc8BABYe5vQ+5IN12Yy01x4QKbvska26GtBpaLqnR/574p/UHUxlBaBXcBTqJvSoaj7N 0ma1E8mneMqu1K0Bw3o+12Xo3QOv7Wh39/vvR3p98trfdXCaGLeLFtunf6ndBlVz1Hzc OvAA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=UeUdJecAQ1EFBmsBBl7X0ql/Ifw+M/goFR+FKShjaLo=; b=cN2Cb2iNYZB/3wwLETGU9BS5dbAZ8svvJYYirGpqhQRS9v+1Pyl+mdK72ZpN7J3lJX pZ37qvUM1iablLxw03sM7otMJ82iY7mu4iEwgcizsGfkeBioIs844XjzwsV0BLeXh9BQ hQ0Bf4it4TTEki1RmlvfukUad6p1A/1Jai8G6lWRwEJTzmAACzBBglBFSGytl87Zd3B8 GnQEnI6L36KKWkwsvbrM/Wn9NLGMn74YsqqZ9WIXJA7qdgmJ3rKAuUvQZS8UXulMSvvN ddM8rjpdf/ewPDMiGLusNVIMhLgBR/5UDdpj3pS+Nk1+xb0fZu1JbH9S4ejsMuP+a4d7 oCgQ== X-Gm-Message-State: AOAM533tN655YSxTWHtyduzXU9KReXBgEbgy8wuD+reF6xqm9Y+eWdQQ Xc7tO7Ei6d8u71t7gD7JhvghjA== X-Google-Smtp-Source: ABdhPJwu/vgRKVdWmCHN0xj3FO/a4qJYzBvfsyIggIl3UqTaU1H9WftAAF6bZgsrueP2qcnMOKQcnA== X-Received: by 2002:a19:f506:: with SMTP id j6mr8705696lfb.454.1620076613759; Mon, 03 May 2021 14:16:53 -0700 (PDT) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id m12sm67676lfb.72.2021.05.03.14.16.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 May 2021 14:16:53 -0700 (PDT) From: Linus Walleij To: Bjorn Helgaas Cc: linux-pci@vger.kernel.org, Arnd Bergmann , Imre Kaloz , Krzysztof Halasa , Zoltan HERPAI , Raylynn Knight , Linus Walleij Subject: [PATCH 1/4] ARM/ixp4xx: Move the UART and exp bus virtbases Date: Mon, 3 May 2021 23:16:46 +0200 Message-Id: <20210503211649.4109334-2-linus.walleij@linaro.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210503211649.4109334-1-linus.walleij@linaro.org> References: <20210503211649.4109334-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org 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 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 Cc: Imre Kaloz Cc: Krzysztof Halasa Cc: Zoltan HERPAI Cc: Raylynn Knight Signed-off-by: Linus Walleij --- 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 #include -#include -#include +/* + * 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 = { /* From patchwork Mon May 3 21:16:47 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12237031 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3C80DC433B4 for ; Mon, 3 May 2021 21:16:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 19433611EE for ; Mon, 3 May 2021 21:16:58 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229619AbhECVRv (ORCPT ); Mon, 3 May 2021 17:17:51 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56824 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229499AbhECVRu (ORCPT ); Mon, 3 May 2021 17:17:50 -0400 Received: from mail-lf1-x12e.google.com (mail-lf1-x12e.google.com [IPv6:2a00:1450:4864:20::12e]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D1017C061573 for ; Mon, 3 May 2021 14:16:56 -0700 (PDT) Received: by mail-lf1-x12e.google.com with SMTP id x2so10127887lff.10 for ; Mon, 03 May 2021 14:16:56 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=sflI/S+pVRCUAC9nbwy+3rUc9QtjU7IHjAfIdZROvPY=; b=MSJ4/8R9B1uTtOA7+8OUAvMxUOpCWfdyn1yvs6fbHQTe4qJPejnIM2yDHPKkaDzB9P V6fR+cCdUKZMTSRS0wIStJQQgR78WrjOKAHltToUuNEXaT/t5mBmNlCdlIFskp/zelN9 88lucXsJ2juSkfWAyGSb+J9qg8bqjNJZUlHkKmN9xZmvSp41YdQFKq6n6rNfv1/KZKna Bgd2v6zqd/8wKHguHLKvDCr8ErRR4+pzsTgUxbvV/HUqQpQrIQ9QdG1mA7KUzXoH5EK9 iGbUhDU0unoYX63///lxbj5p1krUGzzAA91OzDkGUbLw+XuMT5fgG5amZHKVWHrV7iyj Lpfw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=sflI/S+pVRCUAC9nbwy+3rUc9QtjU7IHjAfIdZROvPY=; b=UmsPPbZEBTokBJpVtvIeAjsv/H4zJE5/u0XyeNsOMYvXTOvfkr2hPqu7CLNPMdXpmE /CJ/mfE+/bNXN9kQlu5X3S+9UOwipx+RMMg+q6dBME/Me7U/Nnc1wQ6ThtV6bek7xqk9 kFb0+8+k+KBnK/1AjC1vHPh1/didzK/zRDQGUUFztOv/NqwA5mnSi3xLwkge2+m8jt/y Zj5mIVsR7Rj9Oe4uSgGZWaBcNs5H9b7ltzAusp1a9gXphzdYXRXj9q3myjguSg0S5krg pz+qAJsrVxiKxhZV11wYzqKVkaVRGIg1P8M6IZS7qmSH/qHsntaKEpagSsRwU+6DQyVS /XXg== X-Gm-Message-State: AOAM532VMqeoIi6//s1NrC8MAYM+kAZ2iZ6ZCw98s1hAyFoCRKtGj19W OSnYyPoN6BLBPMxd7uoPKxNopA== X-Google-Smtp-Source: ABdhPJywSqUk8mu6m96auLHGlXXozMnoDK+81sYxmfaldSjcRDChskyvpqOC+M1WGi9V/Yo9JvNFyQ== X-Received: by 2002:a05:6512:2343:: with SMTP id p3mr14461954lfu.463.1620076615268; Mon, 03 May 2021 14:16:55 -0700 (PDT) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id m12sm67676lfb.72.2021.05.03.14.16.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 May 2021 14:16:54 -0700 (PDT) From: Linus Walleij To: Bjorn Helgaas Cc: linux-pci@vger.kernel.org, Arnd Bergmann , Imre Kaloz , Krzysztof Halasa , Zoltan HERPAI , Raylynn Knight , Linus Walleij Subject: [PATCH 2/4] ARM/ixp4xx: Make NEED_MACH_IO_H optional Date: Mon, 3 May 2021 23:16:47 +0200 Message-Id: <20210503211649.4109334-3-linus.walleij@linaro.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210503211649.4109334-1-linus.walleij@linaro.org> References: <20210503211649.4109334-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org In order to create a proper PCI driver for the IXP4xx we need to make the old PCI driver and its reliance on 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 and headers that they previously obtained implicitly using that would include 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 Cc: Imre Kaloz Cc: Krzysztof Halasa Cc: Zoltan HERPAI Cc: Raylynn Knight Signed-off-by: Linus Walleij --- 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 #include #include -#include #include #include #include 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 #include #include +#include #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 #include #include +#include #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 #include #include +#include #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 #include #include +#include #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 #include #include +#include #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 #include #include +#include +#include #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 #include #include +#include +#include static struct qmgr_regs __iomem *qmgr_regs; static int qmgr_irq_1; From patchwork Mon May 3 21:16:48 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12237033 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A93CDC43461 for ; Mon, 3 May 2021 21:16:59 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 8A3E26115B for ; Mon, 3 May 2021 21:16:59 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229637AbhECVRw (ORCPT ); Mon, 3 May 2021 17:17:52 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56834 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229499AbhECVRw (ORCPT ); Mon, 3 May 2021 17:17:52 -0400 Received: from mail-lj1-x230.google.com (mail-lj1-x230.google.com [IPv6:2a00:1450:4864:20::230]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4EAF8C06174A for ; Mon, 3 May 2021 14:16:58 -0700 (PDT) Received: by mail-lj1-x230.google.com with SMTP id p12so8614215ljg.1 for ; Mon, 03 May 2021 14:16:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=Wxi/xMMGJqV7UoX2rYd8j1MY3pfk8Gq2PEylFD9T6K8=; b=y7OupY+e/6RARMk8sDxPGtRVk6ynzzdFqYm2m1/mY4BxU3ro2OoGuUSR5v/w/OVBn+ Mf2gvXkPu73yfswkN88T/C/BgM2exaZZdCnSNQGkYQwfW0GccjkA8reli01dhVYaF69Q DZWWAhOupzAxw3Qe6vCHZ4MWvCtvWkduTB+R764WB7mwnQLzkzk0axwaoPQK6WQZwrKo /l1tBbz1Rpm9Gu3WVJBFEkJluT5rG++JypiqwEfJqx+cRUqQt/kE2JPEGxnag9vHNge+ cVZvHUw75XOm3mc+lACHPldlH5lIyak0wd+t2uoebVRacFr62ZNfQFLYUyPI7WraDMLt W+bA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Wxi/xMMGJqV7UoX2rYd8j1MY3pfk8Gq2PEylFD9T6K8=; b=sMcxosaQfmQDhymmkGygFcpGgtgq8l/JuQyEhi3UG+44a59p7B0uTI7ds8r3oaIGhs P63rSk/i7MfdyfXuEoN++wGtDCslZ0oYBQGvAUoIX+ex0XMuM15pqUA2Dvtw3/kFWG3q /Ga8bHE2DpgwDLXXVdbzXWpdSlsQa+OEB+l8UBRaMAkWIfuDYAeBfPJSPiyzPuKlQaTT Hy3oXmerw39XGnLJQgPwkXhoyBHeZSAaL1YscFVI4vYFLnCOSGUWwJFqAiox3ZfLQGGq 2ltyn5mKEC9SyQm4QrMpo0hRPyE1YrW9dKFqoMOWmgtfHEpny1q3FoFjHyZhxm6Fn4L7 iUvw== X-Gm-Message-State: AOAM533+9MWgCOAUfMQKUunj3bLea5pNixQP041z4G0feuOOt6DjxxIX /5k7gB/YHf46L1NYoZtBi3UIZA== X-Google-Smtp-Source: ABdhPJwjJ5v6IlL9XgEILDChrs9KXqs6ohxsuU/GUL291m3kpFUU7tdOIHuPKVxPNwEjZqp7MscLrg== X-Received: by 2002:a2e:bc22:: with SMTP id b34mr14776708ljf.392.1620076616829; Mon, 03 May 2021 14:16:56 -0700 (PDT) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id m12sm67676lfb.72.2021.05.03.14.16.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 May 2021 14:16:56 -0700 (PDT) From: Linus Walleij To: Bjorn Helgaas Cc: linux-pci@vger.kernel.org, Arnd Bergmann , Imre Kaloz , Krzysztof Halasa , Zoltan HERPAI , Raylynn Knight , Linus Walleij , devicetree@vger.kernel.org Subject: [PATCH 3/4] PCI: ixp4xx: Add device tree bindings for IXP4xx Date: Mon, 3 May 2021 23:16:48 +0200 Message-Id: <20210503211649.4109334-4-linus.walleij@linaro.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210503211649.4109334-1-linus.walleij@linaro.org> References: <20210503211649.4109334-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org 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 Cc: Imre Kaloz Cc: Krzysztof Halasa Cc: Zoltan HERPAI Cc: Raylynn Knight Signed-off-by: Linus Walleij --- 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 + +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 */ + }; From patchwork Mon May 3 21:16:49 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 12237035 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-18.7 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id D66A5C433ED for ; Mon, 3 May 2021 21:17:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id BDD0861185 for ; Mon, 3 May 2021 21:17:01 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229680AbhECVRy (ORCPT ); Mon, 3 May 2021 17:17:54 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56854 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229628AbhECVRy (ORCPT ); Mon, 3 May 2021 17:17:54 -0400 Received: from mail-lj1-x229.google.com (mail-lj1-x229.google.com [IPv6:2a00:1450:4864:20::229]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 2B053C06174A for ; Mon, 3 May 2021 14:17:00 -0700 (PDT) Received: by mail-lj1-x229.google.com with SMTP id p12so8614281ljg.1 for ; Mon, 03 May 2021 14:17:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=QB2eo9mOZyIP1GSRr7eRTM83gniSfCN+6Qj6PzMwfco=; b=aCYhJfHufwZ+VSjm/SQDR8Oa3vljj5MHXPfPGLbtySrL9EhCk5AK5OW/n8TRySDPNa ZC7zIMOALyJcXMrQXgRkEk/c/lmSxZBJs5FiEfWa5Mq54M1T451RydPysGk1yex0Bo6j aLum1Y/aK/xgYlO4PYcD0HCM4A53MY+sl+NPPHHePwe8s6QwwwcjayG1IXXH1zu8U8Zr SArKA5mdXzTLBgtWj5LHInqkD10ks/V0hoG0NnRyFjVPCHHuPBDfSgE55UwnL0HyTcna lEAdu2mY/N4CfVe0O/zmA6u3AIWEzsTAEu/vl6UQC5D+SJB5xZPFteQA841Fn4juuCsA RFZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=QB2eo9mOZyIP1GSRr7eRTM83gniSfCN+6Qj6PzMwfco=; b=rUC8QoYw1CjMxtNSh62moE1kpiKrQsbjRbx4pMW48Mp7dcvzEOFMfGW1PGPPHo8UeE qV52dIk4wDz+pmTxoIaWdA5uWr9Ig/JP5+noHPnwc+c4X0UeXzOZji4FrXbSQQHzvbNW kVty9JVbKoirwGk/tE83f0uKeV3u1H15Xxzusca/ITS0hFlOcgia6r0CLsu3uaxjabpb ShVHBzpatHKciXgvCwWVfgHaJqL44r3qXxbOH/IFcRd8fa3uHqPZUZql4vmjvD+dMlWu 0o2H6qopMNDrKd1UpKODnLw5pD85ucWA5xP61pKjwmW6FcHSj4/Z6C9EYTx5+eF1rWAK tcTA== X-Gm-Message-State: AOAM530OpNcxxrUeR8L7ovqRjAYWoH0eiLTHBOn8b1sDkftLI4TLAA8o WW4MgOW4d0ojkQpu5drMmufloA== X-Google-Smtp-Source: ABdhPJzvrTmjYFUidR7z6SX2xhven0jTGno2hhx7hvJkueL4F4JRIWr3v/jJ9xO3RbA0jRa7NeBw6A== X-Received: by 2002:a2e:a585:: with SMTP id m5mr13309810ljp.223.1620076618500; Mon, 03 May 2021 14:16:58 -0700 (PDT) Received: from localhost.localdomain (c-fdcc225c.014-348-6c756e10.bbcust.telenor.se. [92.34.204.253]) by smtp.gmail.com with ESMTPSA id m12sm67676lfb.72.2021.05.03.14.16.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 May 2021 14:16:58 -0700 (PDT) From: Linus Walleij To: Bjorn Helgaas Cc: linux-pci@vger.kernel.org, Arnd Bergmann , Imre Kaloz , Krzysztof Halasa , Zoltan HERPAI , Raylynn Knight , Linus Walleij Subject: [PATCH 4/4] PCI: ixp4xx: Add a new driver for IXP4xx Date: Mon, 3 May 2021 23:16:49 +0200 Message-Id: <20210503211649.4109334-5-linus.walleij@linaro.org> X-Mailer: git-send-email 2.29.2 In-Reply-To: <20210503211649.4109334-1-linus.walleij@linaro.org> References: <20210503211649.4109334-1-linus.walleij@linaro.org> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org 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 Cc: Imre Kaloz Cc: Krzysztof Halasa Cc: Zoltan HERPAI Cc: Raylynn Knight Signed-off-by: Linus Walleij Reported-by: kernel test robot --- 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 +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 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 + * + * Based on the IXP4xx arch/arm/mach-ixp4xx/common-pci.c driver + * Copyright (C) 2002 Intel Corporation + * Copyright (C) 2003 Greg Ungerer + * Copyright (C) 2003-2004 MontaVista Software, Inc. + * Copyright (C) 2005 Deepak Saxena + * Copyright (C) 2005 Alessandro Zummo + * + * TODO: + * - Test IO-space access + * - DMA support + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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);