diff --git a/arm64-tegra186-enable-USB-on-Jetson-TX2.patch b/arm64-tegra186-enable-USB-on-Jetson-TX2.patch new file mode 100644 index 000000000..ea0287c2b --- /dev/null +++ b/arm64-tegra186-enable-USB-on-Jetson-TX2.patch @@ -0,0 +1,51 @@ +From e5ccb943712d261b8ebb3e8ac92a82be4b244ce4 Mon Sep 17 00:00:00 2001 +From: Peter Robinson +Date: Sun, 6 Oct 2019 14:44:25 +0100 +Subject: [PATCH] arm64: tegra186: enable USB on Jetson-TX2 + +Based on the following patch series: +https://www.spinics.net/lists/linux-tegra/msg44216.html + +Signed-off-by: Peter Robinson +--- + arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts | 4 ++-- + arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 + + 2 files changed, 3 insertions(+), 2 deletions(-) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +index bdace01561ba..2e6195764268 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts ++++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +@@ -115,7 +115,7 @@ + }; + + padctl@3520000 { +- status = "disabled"; ++ status = "okay"; + + avdd-pll-erefeut-supply = <&vdd_1v8_pll>; + avdd-usb-supply = <&vdd_3v3_sys>; +@@ -193,7 +193,7 @@ + }; + + usb@3530000 { +- status = "disabled"; ++ status = "okay"; + + phys = <&{/padctl@3520000/pads/usb2/lanes/usb2-0}>, + <&{/padctl@3520000/pads/usb2/lanes/usb2-1}>, +diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi +index 47cd831fcf44..abdc81f555b9 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi +@@ -525,6 +525,7 @@ + <0x0 0x03538000 0x0 0x1000>; + reg-names = "hcd", "fpci"; + ++ iommus = <&smmu TEGRA186_SID_XUSB_HOST>; + interrupts = , + , + ; +-- +2.21.0 + diff --git a/drm-nouveau-Enable-GP10B-by-default.patch b/drm-nouveau-Enable-GP10B-by-default.patch new file mode 100644 index 000000000..e44a5b339 --- /dev/null +++ b/drm-nouveau-Enable-GP10B-by-default.patch @@ -0,0 +1,1275 @@ +From patchwork Mon Sep 16 15:04:02 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [01/11] drm/nouveau: tegra: Avoid pulsing reset twice +From: Thierry Reding +X-Patchwork-Id: 331044 +Message-Id: <20190916150412.10025-2-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:02 +0200 + +From: Thierry Reding + +When the GPU powergate is controlled by a generic power domain provider, +the reset will automatically be asserted and deasserted as part of the +power-ungating procedure. + +On some Jetson TX2 boards, doing an additional assert and deassert of +the GPU outside of the power-ungate procedure can cause the GPU to go +into a bad state where the memory interface can no longer access system +memory. + +Signed-off-by: Thierry Reding +--- + drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +index 0e372a190d3f..747a775121cf 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +@@ -52,18 +52,18 @@ nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) + clk_set_rate(tdev->clk_pwr, 204000000); + udelay(10); + +- reset_control_assert(tdev->rst); +- udelay(10); +- + if (!tdev->pdev->dev.pm_domain) { ++ reset_control_assert(tdev->rst); ++ udelay(10); ++ + ret = tegra_powergate_remove_clamping(TEGRA_POWERGATE_3D); + if (ret) + goto err_clamp; + udelay(10); +- } + +- reset_control_deassert(tdev->rst); +- udelay(10); ++ reset_control_deassert(tdev->rst); ++ udelay(10); ++ } + + return 0; + + +From patchwork Mon Sep 16 15:04:03 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [02/11] drm/nouveau: tegra: Set clock rate if not set +From: Thierry Reding +X-Patchwork-Id: 331046 +Message-Id: <20190916150412.10025-3-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:03 +0200 + +From: Thierry Reding + +If the GPU clock has not had a rate set, initialize it to the maximum +clock rate to make sure it does run. + +Signed-off-by: Thierry Reding +--- + drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +index 747a775121cf..d0d52c1d4aee 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +@@ -279,6 +279,7 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, + struct nvkm_device **pdevice) + { + struct nvkm_device_tegra *tdev; ++ unsigned long rate; + int ret; + + if (!(tdev = kzalloc(sizeof(*tdev), GFP_KERNEL))) +@@ -307,6 +308,17 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, + goto free; + } + ++ rate = clk_get_rate(tdev->clk); ++ if (rate == 0) { ++ ret = clk_set_rate(tdev->clk, ULONG_MAX); ++ if (ret < 0) ++ goto free; ++ ++ rate = clk_get_rate(tdev->clk); ++ ++ dev_dbg(&pdev->dev, "GPU clock set to %lu\n", rate); ++ } ++ + if (func->require_ref_clk) + tdev->clk_ref = devm_clk_get(&pdev->dev, "ref"); + if (IS_ERR(tdev->clk_ref)) { + +From patchwork Mon Sep 16 15:04:04 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [03/11] drm/nouveau: secboot: Read WPR configuration from GPU + registers +From: Thierry Reding +X-Patchwork-Id: 331048 +Message-Id: <20190916150412.10025-4-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:04 +0200 + +From: Thierry Reding + +The GPUs found on Tegra SoCs have registers that can be used to read the +WPR configuration. Use these registers instead of reaching into the +memory controller's register space to read the same information. + +Signed-off-by: Thierry Reding +--- + .../drm/nouveau/nvkm/subdev/secboot/gm200.h | 2 +- + .../drm/nouveau/nvkm/subdev/secboot/gm20b.c | 81 ++++++++++++------- + .../drm/nouveau/nvkm/subdev/secboot/gp10b.c | 4 +- + 3 files changed, 53 insertions(+), 34 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h +index 62c5e162099a..280b1448df88 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm200.h +@@ -41,6 +41,6 @@ int gm200_secboot_run_blob(struct nvkm_secboot *, struct nvkm_gpuobj *, + struct nvkm_falcon *); + + /* Tegra-only */ +-int gm20b_secboot_tegra_read_wpr(struct gm200_secboot *, u32); ++int gm20b_secboot_tegra_read_wpr(struct gm200_secboot *); + + #endif +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c +index df8b919dcf09..f8a543122219 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gm20b.c +@@ -23,39 +23,65 @@ + #include "acr.h" + #include "gm200.h" + +-#define TEGRA210_MC_BASE 0x70019000 +- + #ifdef CONFIG_ARCH_TEGRA +-#define MC_SECURITY_CARVEOUT2_CFG0 0xc58 +-#define MC_SECURITY_CARVEOUT2_BOM_0 0xc5c +-#define MC_SECURITY_CARVEOUT2_BOM_HI_0 0xc60 +-#define MC_SECURITY_CARVEOUT2_SIZE_128K 0xc64 +-#define TEGRA_MC_SECURITY_CARVEOUT_CFG_LOCKED (1 << 1) + /** + * gm20b_secboot_tegra_read_wpr() - read the WPR registers on Tegra + * +- * On dGPU, we can manage the WPR region ourselves, but on Tegra the WPR region +- * is reserved from system memory by the bootloader and irreversibly locked. +- * This function reads the address and size of the pre-configured WPR region. ++ * On dGPU, we can manage the WPR region ourselves, but on Tegra this region ++ * is allocated from system memory by the secure firmware. The region is then ++ * marked as a "secure carveout" and irreversibly locked. Furthermore, the WPR ++ * secure carveout is also configured to be sent to the GPU via a dedicated ++ * serial bus between the memory controller and the GPU. The GPU requests this ++ * information upon leaving reset and exposes it through a FIFO register at ++ * offset 0x100cd4. ++ * ++ * The FIFO register's lower 4 bits can be used to set the read index into the ++ * FIFO. After each read of the FIFO register, the read index is incremented. ++ * ++ * Indices 2 and 3 contain the lower and upper addresses of the WPR. These are ++ * stored in units of 256 B. The WPR is inclusive of both addresses. ++ * ++ * Unfortunately, for some reason the WPR info register doesn't contain the ++ * correct values for the secure carveout. It seems like the upper address is ++ * always too small by 128 KiB - 1. Given that the secure carvout size in the ++ * memory controller configuration is specified in units of 128 KiB, it's ++ * possible that the computation of the upper address of the WPR is wrong and ++ * causes this difference. + */ + int +-gm20b_secboot_tegra_read_wpr(struct gm200_secboot *gsb, u32 mc_base) ++gm20b_secboot_tegra_read_wpr(struct gm200_secboot *gsb) + { ++ struct nvkm_device *device = gsb->base.subdev.device; + struct nvkm_secboot *sb = &gsb->base; +- void __iomem *mc; +- u32 cfg; ++ u64 base, limit; ++ u32 value; + +- mc = ioremap(mc_base, 0xd00); +- if (!mc) { +- nvkm_error(&sb->subdev, "Cannot map Tegra MC registers\n"); +- return -ENOMEM; +- } +- sb->wpr_addr = ioread32_native(mc + MC_SECURITY_CARVEOUT2_BOM_0) | +- ((u64)ioread32_native(mc + MC_SECURITY_CARVEOUT2_BOM_HI_0) << 32); +- sb->wpr_size = ioread32_native(mc + MC_SECURITY_CARVEOUT2_SIZE_128K) +- << 17; +- cfg = ioread32_native(mc + MC_SECURITY_CARVEOUT2_CFG0); +- iounmap(mc); ++ /* set WPR info register to point at WPR base address register */ ++ value = nvkm_rd32(device, 0x100cd4); ++ value &= ~0xf; ++ value |= 0x2; ++ nvkm_wr32(device, 0x100cd4, value); ++ ++ /* read base address */ ++ value = nvkm_rd32(device, 0x100cd4); ++ base = (u64)(value >> 4) << 12; ++ ++ /* read limit */ ++ value = nvkm_rd32(device, 0x100cd4); ++ limit = (u64)(value >> 4) << 12; ++ ++ /* ++ * The upper address of the WPR seems to be computed wrongly and is ++ * actually SZ_128K - 1 bytes lower than it should be. Adjust the ++ * value accordingly. ++ */ ++ limit += SZ_128K - 1; ++ ++ sb->wpr_size = limit - base + 1; ++ sb->wpr_addr = base; ++ ++ nvkm_info(&sb->subdev, "WPR: %016llx-%016llx\n", sb->wpr_addr, ++ sb->wpr_addr + sb->wpr_size - 1); + + /* Check that WPR settings are valid */ + if (sb->wpr_size == 0) { +@@ -63,11 +89,6 @@ gm20b_secboot_tegra_read_wpr(struct gm200_secboot *gsb, u32 mc_base) + return -EINVAL; + } + +- if (!(cfg & TEGRA_MC_SECURITY_CARVEOUT_CFG_LOCKED)) { +- nvkm_error(&sb->subdev, "WPR region not locked\n"); +- return -EINVAL; +- } +- + return 0; + } + #else +@@ -85,7 +106,7 @@ gm20b_secboot_oneinit(struct nvkm_secboot *sb) + struct gm200_secboot *gsb = gm200_secboot(sb); + int ret; + +- ret = gm20b_secboot_tegra_read_wpr(gsb, TEGRA210_MC_BASE); ++ ret = gm20b_secboot_tegra_read_wpr(gsb); + if (ret) + return ret; + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c +index 28ca29d0eeee..d84e85825995 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/secboot/gp10b.c +@@ -23,15 +23,13 @@ + #include "acr.h" + #include "gm200.h" + +-#define TEGRA186_MC_BASE 0x02c10000 +- + static int + gp10b_secboot_oneinit(struct nvkm_secboot *sb) + { + struct gm200_secboot *gsb = gm200_secboot(sb); + int ret; + +- ret = gm20b_secboot_tegra_read_wpr(gsb, TEGRA186_MC_BASE); ++ ret = gm20b_secboot_tegra_read_wpr(gsb); + if (ret) + return ret; + + +From patchwork Mon Sep 16 15:04:05 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [04/11] drm/nouveau: gp10b: Add custom L2 cache implementation +From: Thierry Reding +X-Patchwork-Id: 331049 +Message-Id: <20190916150412.10025-5-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:05 +0200 + +From: Thierry Reding + +There are extra registers that need to be programmed to make the level 2 +cache work on GP10B, such as the stream ID register that is used when an +SMMU is used to translate memory addresses. + +Signed-off-by: Thierry Reding +--- + .../gpu/drm/nouveau/include/nvkm/subdev/ltc.h | 1 + + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- + .../gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild | 1 + + .../gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c | 69 +++++++++++++++++++ + .../gpu/drm/nouveau/nvkm/subdev/ltc/priv.h | 2 + + 5 files changed, 74 insertions(+), 1 deletion(-) + create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c + +diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h +index 644d527c3b96..d76f60d7d29a 100644 +--- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h ++++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/ltc.h +@@ -40,4 +40,5 @@ int gm107_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); + int gm200_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); + int gp100_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); + int gp102_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); ++int gp10b_ltc_new(struct nvkm_device *, int, struct nvkm_ltc **); + #endif +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +index c3c7159f3411..d2d6d5f4028a 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +@@ -2380,7 +2380,7 @@ nv13b_chipset = { + .fuse = gm107_fuse_new, + .ibus = gp10b_ibus_new, + .imem = gk20a_instmem_new, +- .ltc = gp102_ltc_new, ++ .ltc = gp10b_ltc_new, + .mc = gp10b_mc_new, + .mmu = gp10b_mmu_new, + .secboot = gp10b_secboot_new, +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild +index 2b6d36ea7067..728d75010847 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild +@@ -6,3 +6,4 @@ nvkm-y += nvkm/subdev/ltc/gm107.o + nvkm-y += nvkm/subdev/ltc/gm200.o + nvkm-y += nvkm/subdev/ltc/gp100.o + nvkm-y += nvkm/subdev/ltc/gp102.o ++nvkm-y += nvkm/subdev/ltc/gp10b.o +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c +new file mode 100644 +index 000000000000..4d27c6ea1552 +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c +@@ -0,0 +1,69 @@ ++/* ++ * Copyright (c) 2019 NVIDIA Corporation. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ * ++ * Authors: Thierry Reding ++ */ ++ ++#include "priv.h" ++ ++static void ++gp10b_ltc_init(struct nvkm_ltc *ltc) ++{ ++ struct nvkm_device *device = ltc->subdev.device; ++#ifdef CONFIG_IOMMU_API ++ struct iommu_fwspec *spec; ++#endif ++ ++ nvkm_wr32(device, 0x17e27c, ltc->ltc_nr); ++ nvkm_wr32(device, 0x17e000, ltc->ltc_nr); ++ nvkm_wr32(device, 0x100800, ltc->ltc_nr); ++ ++#ifdef CONFIG_IOMMU_API ++ spec = dev_iommu_fwspec_get(device->dev); ++ if (spec) { ++ u32 sid = spec->ids[0] & 0xffff; ++ ++ /* stream ID */ ++ nvkm_wr32(device, 0x160000, sid << 2); ++ } ++#endif ++} ++ ++static const struct nvkm_ltc_func ++gp10b_ltc = { ++ .oneinit = gp100_ltc_oneinit, ++ .init = gp10b_ltc_init, ++ .intr = gp100_ltc_intr, ++ .cbc_clear = gm107_ltc_cbc_clear, ++ .cbc_wait = gm107_ltc_cbc_wait, ++ .zbc = 16, ++ .zbc_clear_color = gm107_ltc_zbc_clear_color, ++ .zbc_clear_depth = gm107_ltc_zbc_clear_depth, ++ .zbc_clear_stencil = gp102_ltc_zbc_clear_stencil, ++ .invalidate = gf100_ltc_invalidate, ++ .flush = gf100_ltc_flush, ++}; ++ ++int ++gp10b_ltc_new(struct nvkm_device *device, int index, struct nvkm_ltc **pltc) ++{ ++ return nvkm_ltc_new_(&gp10b_ltc, device, index, pltc); ++} +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h +index 2fcf18e46ce3..eca5a711b1b8 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/priv.h +@@ -46,4 +46,6 @@ void gm107_ltc_zbc_clear_depth(struct nvkm_ltc *, int, const u32); + int gp100_ltc_oneinit(struct nvkm_ltc *); + void gp100_ltc_init(struct nvkm_ltc *); + void gp100_ltc_intr(struct nvkm_ltc *); ++ ++void gp102_ltc_zbc_clear_stencil(struct nvkm_ltc *, int, const u32); + #endif + +From patchwork Mon Sep 16 15:04:06 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [05/11] drm/nouveau: gp10b: Use correct copy engine +From: Thierry Reding +X-Patchwork-Id: 331052 +Message-Id: <20190916150412.10025-6-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:06 +0200 + +From: Thierry Reding + +gp10b uses the new engine enumeration mechanism introduced in the Pascal +architecture. As a result, the copy engine, which used to be at index 2 +for prior Tegra GPU instantiations, has now moved to index 0. Fix up the +index and also use the gp100 variant of the copy engine class because on +gp10b the PASCAL_DMA_COPY_B class is not supported. + +Signed-off-by: Thierry Reding +--- + drivers/gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +index d2d6d5f4028a..99d3fa3fad89 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +@@ -2387,7 +2387,7 @@ nv13b_chipset = { + .pmu = gm20b_pmu_new, + .timer = gk20a_timer_new, + .top = gk104_top_new, +- .ce[2] = gp102_ce_new, ++ .ce[0] = gp100_ce_new, + .dma = gf119_dma_new, + .fifo = gp10b_fifo_new, + .gr = gp10b_gr_new, + +From patchwork Mon Sep 16 15:04:07 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [06/11] drm/nouveau: gk20a: Set IOMMU bit for DMA API if appropriate +From: Thierry Reding +X-Patchwork-Id: 331053 +Message-Id: <20190916150412.10025-7-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:07 +0200 + +From: Thierry Reding + +Detect if the DMA API is backed by an IOMMU and set the IOMMU bit if so. +This is needed to make sure IOMMU addresses are properly translated even +the explicit IOMMU API is not used. + +Signed-off-by: Thierry Reding +--- + .../drm/nouveau/nvkm/subdev/instmem/gk20a.c | 35 +++++++++++++------ + 1 file changed, 25 insertions(+), 10 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +index b0493f8df1fe..1120a2a7d5f1 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/instmem/gk20a.c +@@ -100,12 +100,14 @@ struct gk20a_instmem { + unsigned int vaddr_max; + struct list_head vaddr_lru; + ++ /* IOMMU mapping */ ++ unsigned int page_shift; ++ u64 iommu_mask; ++ + /* Only used if IOMMU if present */ + struct mutex *mm_mutex; + struct nvkm_mm *mm; + struct iommu_domain *domain; +- unsigned long iommu_pgshift; +- u16 iommu_bit; + + /* Only used by DMA API */ + unsigned long attrs; +@@ -357,12 +359,12 @@ gk20a_instobj_dtor_iommu(struct nvkm_memory *memory) + mutex_unlock(&imem->lock); + + /* clear IOMMU bit to unmap pages */ +- r->offset &= ~BIT(imem->iommu_bit - imem->iommu_pgshift); ++ r->offset &= ~imem->iommu_mask; + + /* Unmap pages from GPU address space and free them */ + for (i = 0; i < node->base.mn->length; i++) { + iommu_unmap(imem->domain, +- (r->offset + i) << imem->iommu_pgshift, PAGE_SIZE); ++ (r->offset + i) << imem->page_shift, PAGE_SIZE); + dma_unmap_page(dev, node->dma_addrs[i], PAGE_SIZE, + DMA_BIDIRECTIONAL); + __free_page(node->pages[i]); +@@ -440,7 +442,7 @@ gk20a_instobj_ctor_dma(struct gk20a_instmem *imem, u32 npages, u32 align, + + /* present memory for being mapped using small pages */ + node->r.type = 12; +- node->r.offset = node->handle >> 12; ++ node->r.offset = imem->iommu_mask | node->handle >> 12; + node->r.length = (npages << PAGE_SHIFT) >> 12; + + node->base.mn = &node->r; +@@ -493,7 +495,7 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align, + mutex_lock(imem->mm_mutex); + /* Reserve area from GPU address space */ + ret = nvkm_mm_head(imem->mm, 0, 1, npages, npages, +- align >> imem->iommu_pgshift, &r); ++ align >> imem->page_shift, &r); + mutex_unlock(imem->mm_mutex); + if (ret) { + nvkm_error(subdev, "IOMMU space is full!\n"); +@@ -502,7 +504,7 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align, + + /* Map into GPU address space */ + for (i = 0; i < npages; i++) { +- u32 offset = (r->offset + i) << imem->iommu_pgshift; ++ u32 offset = (r->offset + i) << imem->page_shift; + + ret = iommu_map(imem->domain, offset, node->dma_addrs[i], + PAGE_SIZE, IOMMU_READ | IOMMU_WRITE); +@@ -518,7 +520,7 @@ gk20a_instobj_ctor_iommu(struct gk20a_instmem *imem, u32 npages, u32 align, + } + + /* IOMMU bit tells that an address is to be resolved through the IOMMU */ +- r->offset |= BIT(imem->iommu_bit - imem->iommu_pgshift); ++ r->offset |= imem->iommu_mask; + + node->base.mn = r; + return 0; +@@ -619,11 +621,12 @@ gk20a_instmem_new(struct nvkm_device *device, int index, + imem->mm_mutex = &tdev->iommu.mutex; + imem->mm = &tdev->iommu.mm; + imem->domain = tdev->iommu.domain; +- imem->iommu_pgshift = tdev->iommu.pgshift; +- imem->iommu_bit = tdev->func->iommu_bit; ++ imem->page_shift = tdev->iommu.pgshift; + + nvkm_info(&imem->base.subdev, "using IOMMU\n"); + } else { ++ imem->page_shift = PAGE_SHIFT; ++ + imem->attrs = DMA_ATTR_NON_CONSISTENT | + DMA_ATTR_WEAK_ORDERING | + DMA_ATTR_WRITE_COMBINE; +@@ -631,5 +634,17 @@ gk20a_instmem_new(struct nvkm_device *device, int index, + nvkm_info(&imem->base.subdev, "using DMA API\n"); + } + ++ /* ++ * The IOMMU mask needs to be set if an IOMMU is used explicitly (via ++ * direct IOMMU API usage) or implicitly (via the DMA API). In both ++ * cases the device will have been attached to an IOMMU domain. ++ */ ++ if (iommu_get_domain_for_dev(device->dev)) { ++ imem->iommu_mask = BIT_ULL(tdev->func->iommu_bit - ++ imem->page_shift); ++ nvkm_debug(&imem->base.subdev, "IOMMU mask: %016llx\n", ++ imem->iommu_mask); ++ } ++ + return 0; + } + +From patchwork Mon Sep 16 15:04:08 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [07/11] drm/nouveau: gk20a: Implement custom MMU class +From: Thierry Reding +X-Patchwork-Id: 331057 +Message-Id: <20190916150412.10025-8-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:08 +0200 + +From: Thierry Reding + +The GPU integrated in NVIDIA Tegra SoCs is connected to system memory +via two paths: one direct path to the memory controller and another path +that goes through a system MMU first. It's not typically necessary to go +through the system MMU because the GPU's MMU can already map buffers so +that they appear contiguous to the GPU. + +However, in order to support big pages, the system MMU has to be used to +combine multiple small pages into one virtually contiguous chunk so that +the GPU can then treat that as a single big page. + +In order to prepare for big page support, implement a custom MMU class +that takes care of setting the IOMMU bit when writing page tables and +when appropriate. + +This is also necessary to make sure that Nouveau works correctly on +Tegra devices where the GPU is connected to a system MMU and that IOMMU +is used to back the DMA API. Currently Nouveau assumes that the DMA API +is never backed by an IOMMU, so access to DMA-mapped buffers fault when +suddenly this assumption is no longer true. + +One situation where this can happen is on 32-bit Tegra SoCs where the +ARM architecture code automatically attaches the GPU with a DMA/IOMMU +domain. This is currently worked around by detaching the GPU from the +IOMMU domain at probe time. However, with Tegra186 and later this can +now also happen, but unfortunately no mechanism exists to detach from +the domain in the 64-bit ARM architecture code. + +Using this Tegra-specific MMU class ensures that DMA-mapped buffers are +properly mapped (with the IOMMU bit set) if the DMA API is backed by an +IOMMU domain. + +Signed-off-by: Thierry Reding +--- + .../gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c | 50 ++++++++++++++++++- + .../gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.h | 44 ++++++++++++++++ + .../gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c | 6 ++- + .../gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c | 4 +- + drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h | 1 + + .../drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c | 22 +++++++- + .../drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c | 4 +- + .../drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c | 20 +++++++- + 8 files changed, 142 insertions(+), 9 deletions(-) + create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.h + +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +index ac74965a60d4..d9a5e05b7dc7 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.c +@@ -19,11 +19,59 @@ + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ ++ ++#include "gk20a.h" + #include "mem.h" + #include "vmm.h" + ++#include + #include + ++static void ++gk20a_mmu_ctor(const struct nvkm_mmu_func *func, struct nvkm_device *device, ++ int index, struct gk20a_mmu *mmu) ++{ ++ struct iommu_domain *domain = iommu_get_domain_for_dev(device->dev); ++ struct nvkm_device_tegra *tegra = device->func->tegra(device); ++ ++ nvkm_mmu_ctor(func, device, index, &mmu->base); ++ ++ /* ++ * If the DMA API is backed by an IOMMU, make sure the IOMMU bit is ++ * set for all buffer accesses. If the IOMMU is explicitly used, it ++ * is only used for instance blocks and the MMU doesn't care, since ++ * buffer objects are only mapped through the MMU, not through the ++ * IOMMU. ++ * ++ * Big page support could be implemented using explicit IOMMU usage, ++ * but the DMA API already provides that for free, so we don't worry ++ * about it for now. ++ */ ++ if (domain && !tegra->iommu.domain) { ++ mmu->iommu_mask = BIT_ULL(tegra->func->iommu_bit); ++ nvkm_debug(&mmu->base.subdev, "IOMMU mask: %llx\n", ++ mmu->iommu_mask); ++ } ++} ++ ++int ++gk20a_mmu_new_(const struct nvkm_mmu_func *func, struct nvkm_device *device, ++ int index, struct nvkm_mmu **pmmu) ++{ ++ struct gk20a_mmu *mmu; ++ ++ mmu = kzalloc(sizeof(*mmu), GFP_KERNEL); ++ if (!mmu) ++ return -ENOMEM; ++ ++ gk20a_mmu_ctor(func, device, index, mmu); ++ ++ if (pmmu) ++ *pmmu = &mmu->base; ++ ++ return 0; ++} ++ + static const struct nvkm_mmu_func + gk20a_mmu = { + .dma_bits = 40, +@@ -37,5 +85,5 @@ gk20a_mmu = { + int + gk20a_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) + { +- return nvkm_mmu_new_(&gk20a_mmu, device, index, pmmu); ++ return gk20a_mmu_new_(&gk20a_mmu, device, index, pmmu); + } +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.h +new file mode 100644 +index 000000000000..bb81fc62509c +--- /dev/null ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gk20a.h +@@ -0,0 +1,44 @@ ++/* ++ * Copyright (c) 2019 NVIDIA Corporation. ++ * ++ * Permission is hereby granted, free of charge, to any person obtaining a ++ * copy of this software and associated documentation files (the "Software"), ++ * to deal in the Software without restriction, including without limitation ++ * the rights to use, copy, modify, merge, publish, distribute, sublicense, ++ * and/or sell copies of the Software, and to permit persons to whom the ++ * Software is furnished to do so, subject to the following conditions: ++ * ++ * The above copyright notice and this permission notice shall be included in ++ * all copies or substantial portions of the Software. ++ * ++ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR ++ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, ++ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL ++ * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR ++ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ++ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR ++ * OTHER DEALINGS IN THE SOFTWARE. ++ */ ++ ++#ifndef __NVKM_MMU_GK20A_H__ ++#define __NVKM_MMU_GK20A_H__ ++ ++#include "priv.h" ++ ++struct gk20a_mmu { ++ struct nvkm_mmu base; ++ ++ /* ++ * If an IOMMU is used, indicates which address bit will trigger an ++ * IOMMU translation when set (when this bit is not set, the IOMMU is ++ * bypassed). A value of 0 means an IOMMU is never used. ++ */ ++ u64 iommu_mask; ++}; ++ ++#define gk20a_mmu(mmu) container_of(mmu, struct gk20a_mmu, base) ++ ++int gk20a_mmu_new_(const struct nvkm_mmu_func *, struct nvkm_device *, ++ int index, struct nvkm_mmu **); ++ ++#endif +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +index 7353a94b4091..7fccd4df52a8 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gm20b.c +@@ -19,6 +19,8 @@ + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ ++ ++#include "gk20a.h" + #include "mem.h" + #include "vmm.h" + +@@ -50,6 +52,6 @@ int + gm20b_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) + { + if (device->fb->page) +- return nvkm_mmu_new_(&gm20b_mmu_fixed, device, index, pmmu); +- return nvkm_mmu_new_(&gm20b_mmu, device, index, pmmu); ++ return gk20a_mmu_new_(&gm20b_mmu_fixed, device, index, pmmu); ++ return gk20a_mmu_new_(&gm20b_mmu, device, index, pmmu); + } +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c +index 0a50be9a785a..ae3cb47be3d8 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/gp10b.c +@@ -19,6 +19,8 @@ + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ ++ ++#include "gk20a.h" + #include "mem.h" + #include "vmm.h" + +@@ -41,5 +43,5 @@ gp10b_mmu_new(struct nvkm_device *device, int index, struct nvkm_mmu **pmmu) + { + if (!nvkm_boolopt(device->cfgopt, "GP100MmuLayout", true)) + return gm20b_mmu_new(device, index, pmmu); +- return nvkm_mmu_new_(&gp10b_mmu, device, index, pmmu); ++ return gk20a_mmu_new_(&gp10b_mmu, device, index, pmmu); + } +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +index 5e55ecbd8005..fb3a9e8bb9cd 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmm.h +@@ -213,6 +213,7 @@ void gf100_vmm_invalidate(struct nvkm_vmm *, u32 type); + void gf100_vmm_invalidate_pdb(struct nvkm_vmm *, u64 addr); + + int gk20a_vmm_aper(enum nvkm_memory_target); ++int gk20a_vmm_valid(struct nvkm_vmm *, void *, u32, struct nvkm_vmm_map *); + + int gm200_vmm_new_(const struct nvkm_vmm_func *, const struct nvkm_vmm_func *, + struct nvkm_mmu *, bool, u64, u64, void *, u32, +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c +index 5a9582dce970..16d7bf727292 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgk20a.c +@@ -19,6 +19,8 @@ + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ ++ ++#include "gk20a.h" + #include "vmm.h" + + #include +@@ -33,12 +35,28 @@ gk20a_vmm_aper(enum nvkm_memory_target target) + } + } + ++int ++gk20a_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc, ++ struct nvkm_vmm_map *map) ++{ ++ struct gk20a_mmu *mmu = gk20a_mmu(vmm->mmu); ++ int ret; ++ ++ ret = gf100_vmm_valid(vmm, argv, argc, map); ++ if (ret < 0) ++ return ret; ++ ++ map->type |= mmu->iommu_mask >> 8; ++ ++ return 0; ++} ++ + static const struct nvkm_vmm_func + gk20a_vmm_17 = { + .join = gf100_vmm_join, + .part = gf100_vmm_part, + .aper = gf100_vmm_aper, +- .valid = gf100_vmm_valid, ++ .valid = gk20a_vmm_valid, + .flush = gf100_vmm_flush, + .invalidate_pdb = gf100_vmm_invalidate_pdb, + .page = { +@@ -53,7 +71,7 @@ gk20a_vmm_16 = { + .join = gf100_vmm_join, + .part = gf100_vmm_part, + .aper = gf100_vmm_aper, +- .valid = gf100_vmm_valid, ++ .valid = gk20a_vmm_valid, + .flush = gf100_vmm_flush, + .invalidate_pdb = gf100_vmm_invalidate_pdb, + .page = { +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c +index 96b759695dd8..7a6066d886cd 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgm20b.c +@@ -26,7 +26,7 @@ gm20b_vmm_17 = { + .join = gm200_vmm_join, + .part = gf100_vmm_part, + .aper = gk20a_vmm_aper, +- .valid = gf100_vmm_valid, ++ .valid = gk20a_vmm_valid, + .flush = gf100_vmm_flush, + .invalidate_pdb = gf100_vmm_invalidate_pdb, + .page = { +@@ -42,7 +42,7 @@ gm20b_vmm_16 = { + .join = gm200_vmm_join, + .part = gf100_vmm_part, + .aper = gk20a_vmm_aper, +- .valid = gf100_vmm_valid, ++ .valid = gk20a_vmm_valid, + .flush = gf100_vmm_flush, + .invalidate_pdb = gf100_vmm_invalidate_pdb, + .page = { +diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c +index e081239afe58..180c8f006e32 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c ++++ b/drivers/gpu/drm/nouveau/nvkm/subdev/mmu/vmmgp10b.c +@@ -19,14 +19,32 @@ + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ ++ ++#include "gk20a.h" + #include "vmm.h" + ++static int ++gp10b_vmm_valid(struct nvkm_vmm *vmm, void *argv, u32 argc, ++ struct nvkm_vmm_map *map) ++{ ++ struct gk20a_mmu *mmu = gk20a_mmu(vmm->mmu); ++ int ret; ++ ++ ret = gp100_vmm_valid(vmm, argv, argc, map); ++ if (ret < 0) ++ return ret; ++ ++ map->type |= mmu->iommu_mask >> 4; ++ ++ return 0; ++} ++ + static const struct nvkm_vmm_func + gp10b_vmm = { + .join = gp100_vmm_join, + .part = gf100_vmm_part, + .aper = gk20a_vmm_aper, +- .valid = gp100_vmm_valid, ++ .valid = gp10b_vmm_valid, + .flush = gp100_vmm_flush, + .mthd = gp100_vmm_mthd, + .invalidate_pdb = gp100_vmm_invalidate_pdb, + +From patchwork Mon Sep 16 15:04:09 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [08/11] drm/nouveau: tegra: Skip IOMMU initialization if already + attached +From: Thierry Reding +X-Patchwork-Id: 331060 +Message-Id: <20190916150412.10025-9-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:09 +0200 + +From: Thierry Reding + +If the GPU is already attached to an IOMMU, don't detach it and setup an +explicit IOMMU domain. Since Nouveau can now properly handle the case of +the DMA API being backed by an IOMMU, just continue using the DMA API. + +Signed-off-by: Thierry Reding +--- + .../drm/nouveau/nvkm/engine/device/tegra.c | 19 +++++++------------ + 1 file changed, 7 insertions(+), 12 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +index d0d52c1d4aee..fc652aaa41c7 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +@@ -23,10 +23,6 @@ + #ifdef CONFIG_NOUVEAU_PLATFORM_DRIVER + #include "priv.h" + +-#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) +-#include +-#endif +- + static int + nvkm_device_tegra_power_up(struct nvkm_device_tegra *tdev) + { +@@ -109,14 +105,13 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) + unsigned long pgsize_bitmap; + int ret; + +-#if IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU) +- if (dev->archdata.mapping) { +- struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); +- +- arm_iommu_detach_device(dev); +- arm_iommu_release_mapping(mapping); +- } +-#endif ++ /* ++ * Skip explicit IOMMU initialization if the GPU is already attached ++ * to an IOMMU domain. This can happen if the DMA API is backed by an ++ * IOMMU. ++ */ ++ if (iommu_get_domain_for_dev(dev)) ++ return; + + if (!tdev->func->iommu_bit) + return; + +From patchwork Mon Sep 16 15:04:10 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [09/11] drm/nouveau: tegra: Fall back to 32-bit DMA mask without IOMMU +From: Thierry Reding +X-Patchwork-Id: 331061 +Message-Id: <20190916150412.10025-10-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:10 +0200 + +From: Thierry Reding + +The GPU can usually address more than 32-bit, even without being +attached to an IOMMU. However, if the GPU is not attached to an IOMMU, +it's likely that there is no IOMMU in the system, in which case any +buffers allocated by Nouveau will likely end up in a region of memory +that cannot be accessed by host1x. + +Signed-off-by: Thierry Reding +--- + .../drm/nouveau/nvkm/engine/device/tegra.c | 111 +++++++++++------- + 1 file changed, 70 insertions(+), 41 deletions(-) + +diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +index fc652aaa41c7..221238a2cf53 100644 +--- a/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c ++++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/tegra.c +@@ -97,7 +97,7 @@ nvkm_device_tegra_power_down(struct nvkm_device_tegra *tdev) + return 0; + } + +-static void ++static int + nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) + { + #if IS_ENABLED(CONFIG_IOMMU_API) +@@ -111,47 +111,65 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) + * IOMMU. + */ + if (iommu_get_domain_for_dev(dev)) +- return; ++ return -ENODEV; + + if (!tdev->func->iommu_bit) +- return; ++ return -ENODEV; ++ ++ if (!iommu_present(&platform_bus_type)) ++ return -ENODEV; + + mutex_init(&tdev->iommu.mutex); + +- if (iommu_present(&platform_bus_type)) { +- tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type); +- if (!tdev->iommu.domain) +- goto error; ++ tdev->iommu.domain = iommu_domain_alloc(&platform_bus_type); ++ if (!tdev->iommu.domain) ++ return -ENOMEM; + +- /* +- * A IOMMU is only usable if it supports page sizes smaller +- * or equal to the system's PAGE_SIZE, with a preference if +- * both are equal. +- */ +- pgsize_bitmap = tdev->iommu.domain->ops->pgsize_bitmap; +- if (pgsize_bitmap & PAGE_SIZE) { +- tdev->iommu.pgshift = PAGE_SHIFT; +- } else { +- tdev->iommu.pgshift = fls(pgsize_bitmap & ~PAGE_MASK); +- if (tdev->iommu.pgshift == 0) { +- dev_warn(dev, "unsupported IOMMU page size\n"); +- goto free_domain; +- } +- tdev->iommu.pgshift -= 1; ++ /* ++ * An IOMMU is only usable if it supports page sizes smaller or equal ++ * to the system's PAGE_SIZE, with a preference if both are equal. ++ */ ++ pgsize_bitmap = tdev->iommu.domain->ops->pgsize_bitmap; ++ if (pgsize_bitmap & PAGE_SIZE) { ++ tdev->iommu.pgshift = PAGE_SHIFT; ++ } else { ++ tdev->iommu.pgshift = fls(pgsize_bitmap & ~PAGE_MASK); ++ if (tdev->iommu.pgshift == 0) { ++ dev_warn(dev, "unsupported IOMMU page size\n"); ++ ret = -ENOTSUPP; ++ goto free_domain; + } + +- ret = iommu_attach_device(tdev->iommu.domain, dev); +- if (ret) +- goto free_domain; ++ tdev->iommu.pgshift -= 1; ++ } + +- ret = nvkm_mm_init(&tdev->iommu.mm, 0, 0, +- (1ULL << tdev->func->iommu_bit) >> +- tdev->iommu.pgshift, 1); +- if (ret) +- goto detach_device; ++ ret = iommu_attach_device(tdev->iommu.domain, dev); ++ if (ret) { ++ dev_warn(dev, "failed to attach to IOMMU: %d\n", ret); ++ goto free_domain; ++ } ++ ++ ret = nvkm_mm_init(&tdev->iommu.mm, 0, 0, ++ (1ULL << tdev->func->iommu_bit) >> ++ tdev->iommu.pgshift, 1); ++ if (ret) { ++ dev_warn(dev, "failed to initialize IOVA space: %d\n", ret); ++ goto detach_device; ++ } ++ ++ /* ++ * The IOMMU bit defines the upper limit of the GPU-addressable space. ++ */ ++ ret = dma_set_mask(dev, DMA_BIT_MASK(tdev->func->iommu_bit)); ++ if (ret) { ++ dev_warn(dev, "failed to set DMA mask: %d\n", ret); ++ goto fini_mm; + } + +- return; ++ return 0; ++ ++fini_mm: ++ nvkm_mm_fini(&tdev->iommu.mm); + + detach_device: + iommu_detach_device(tdev->iommu.domain, dev); +@@ -159,10 +177,15 @@ nvkm_device_tegra_probe_iommu(struct nvkm_device_tegra *tdev) + free_domain: + iommu_domain_free(tdev->iommu.domain); + +-error: ++ /* reset these so that the DMA API code paths are executed */ + tdev->iommu.domain = NULL; + tdev->iommu.pgshift = 0; +- dev_err(dev, "cannot initialize IOMMU MM\n"); ++ ++ dev_warn(dev, "cannot initialize IOMMU MM\n"); ++ ++ return ret; ++#else ++ return -ENOTSUPP; + #endif + } + +@@ -327,14 +350,20 @@ nvkm_device_tegra_new(const struct nvkm_device_tegra_func *func, + goto free; + } + +- /** +- * The IOMMU bit defines the upper limit of the GPU-addressable space. +- */ +- ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(tdev->func->iommu_bit)); +- if (ret) +- goto free; +- +- nvkm_device_tegra_probe_iommu(tdev); ++ ret = nvkm_device_tegra_probe_iommu(tdev); ++ if (ret) { ++ /* ++ * If we fail to set up an IOMMU, fall back to a 32-bit DMA ++ * mask. This is not necessary for the GPU to work because it ++ * can usually address all of system memory. However, if the ++ * buffers allocated by Nouveau are meant to be shared with ++ * the display controller, we need to restrict where they can ++ * come from. ++ */ ++ ret = dma_set_mask(&pdev->dev, DMA_BIT_MASK(32)); ++ if (ret) ++ goto free; ++ } + + ret = nvkm_device_tegra_power_up(tdev); + if (ret) + +From patchwork Mon Sep 16 15:04:11 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [10/11] arm64: tegra: Enable GPU on Jetson TX2 +From: Thierry Reding +X-Patchwork-Id: 331063 +Message-Id: <20190916150412.10025-11-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:11 +0200 + +From: Alexandre Courbot + +Enable the GPU node for the Jetson TX2 board. + +Signed-off-by: Alexandre Courbot +Signed-off-by: Thierry Reding +--- + arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +index bdace01561ba..6f7c7c4c5c29 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts ++++ b/arch/arm64/boot/dts/nvidia/tegra186-p2771-0000.dts +@@ -276,6 +276,10 @@ + }; + }; + ++ gpu@17000000 { ++ status = "okay"; ++ }; ++ + gpio-keys { + compatible = "gpio-keys"; + + +From patchwork Mon Sep 16 15:04:12 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +Subject: [11/11] arm64: tegra: Enable SMMU for GPU on Tegra186 +From: Thierry Reding +X-Patchwork-Id: 331062 +Message-Id: <20190916150412.10025-12-thierry.reding@gmail.com> +To: Ben Skeggs , Thierry Reding +Cc: linux-tegra@vger.kernel.org, nouveau@lists.freedesktop.org, + dri-devel@lists.freedesktop.org +Date: Mon, 16 Sep 2019 17:04:12 +0200 + +From: Thierry Reding + +The GPU has a connection to the ARM SMMU found on Tegra186, which can be +used to support large pages. Make sure the GPU is attached to the SMMU +to take advantage of its capabilities. + +Signed-off-by: Thierry Reding +--- + arch/arm64/boot/dts/nvidia/tegra186.dtsi | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/arch/arm64/boot/dts/nvidia/tegra186.dtsi b/arch/arm64/boot/dts/nvidia/tegra186.dtsi +index 47cd831fcf44..171fd4dfa58d 100644 +--- a/arch/arm64/boot/dts/nvidia/tegra186.dtsi ++++ b/arch/arm64/boot/dts/nvidia/tegra186.dtsi +@@ -1172,6 +1172,7 @@ + status = "disabled"; + + power-domains = <&bpmp TEGRA186_POWER_DOMAIN_GPU>; ++ iommus = <&smmu TEGRA186_SID_GPU>; + }; + + sysram@30000000 { diff --git a/gpio-max77620-Use-correct-unit-for-debounce-times.patch b/gpio-max77620-Use-correct-unit-for-debounce-times.patch new file mode 100644 index 000000000..bcf575fb8 --- /dev/null +++ b/gpio-max77620-Use-correct-unit-for-debounce-times.patch @@ -0,0 +1,586 @@ +From patchwork Wed Oct 2 12:28:23 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Thierry Reding +X-Patchwork-Id: 1170631 +Return-Path: +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (mailfrom) smtp.mailfrom=vger.kernel.org + (client-ip=209.132.180.67; helo=vger.kernel.org; + envelope-from=linux-gpio-owner@vger.kernel.org; + receiver=) +Authentication-Results: ozlabs.org; + dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; + unprotected) header.d=gmail.com header.i=@gmail.com + header.b="Xe4ozWCs"; dkim-atps=neutral +Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) + by ozlabs.org (Postfix) with ESMTP id 46jwR31mYjz9sPl + for ; + Wed, 2 Oct 2019 22:28:31 +1000 (AEST) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S1725875AbfJBM2a (ORCPT ); + Wed, 2 Oct 2019 08:28:30 -0400 +Received: from mail-wr1-f67.google.com ([209.85.221.67]:42402 "EHLO + mail-wr1-f67.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S1725848AbfJBM23 (ORCPT + ); Wed, 2 Oct 2019 08:28:29 -0400 +Received: by mail-wr1-f67.google.com with SMTP id n14so19415351wrw.9; + Wed, 02 Oct 2019 05:28:28 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; + h=from:to:cc:subject:date:message-id:mime-version + :content-transfer-encoding; + bh=qP9mbplmTy0EguziRYmdZKFvmKZpgiY1goXlhQxV0/8=; + b=Xe4ozWCsxpb6DK1agUyM9eUxlP6G03BBFhI5g4JErak3F1hsMTKXmoyANoMKXxS+UF + OWRiAkrVC3cQOJczX/+7HhZQ8bMC3apl96os1jO6/JWJEP2BHZpDAF0bRyJQdbd0lmMA + afH1TDc/aCLYhrc6UF4IMSf4Noe9cSvoyQYpo0qgpxktdn7I/jv5ztIFWEVBOuEfDveP + hKAmMRuOGlokBd9/+TirOM307HbJYDWAZ8Wko3G+bYcw41RSULf9eN0mQPLmeF/+J9tC + XwaypBneeu3VeCmfU/DxP1duZ3pCcnwOu5nrzdHsS6ow28T2CVk8VvAAZGEU1cUIX4Z+ + +hkw== +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:mime-version + :content-transfer-encoding; + bh=qP9mbplmTy0EguziRYmdZKFvmKZpgiY1goXlhQxV0/8=; + b=akVGfKDGN9KlaS7GfDnHx98C2QeedcAeu8RIoCS8uh0twWVOZMZKbUY6M/2HaZKsPI + 38mOkZ2CRPyO1EzbpI9UU6hHXfohMTHuWX0pTdvkFXn+TfZPAxJa1fVRhHgOcknkhb/U + JBzse/qoFFdlsRK3kY6I+0R1YyyAD2SDlzfax4U6ew8DL0icpWegiNEXnIno/7b6sIt2 + 9u9PEHk+1AdQkgS/tVRAFdVg6rrYMbUFkh1JAYsEED71D2IR38JmdUfjsW0Bi1aohXuz + F8LOoB0G33BszHljgknOYlHF4tPGDitMVI+giV3UgwXEWHKFgimUJKOb1nyg+4fcVOLO + 2g1g== +X-Gm-Message-State: APjAAAX5YpK/Xf8BgNQ7EyD7TzARRLtN4fRfLcEXIT3fZkDHf5xGyxPi + jnbTBpi+UDekDgGOQiVnsoo= +X-Google-Smtp-Source: APXvYqw9HA6mSwE4O/MajE0OyTuT/xQaPqMRcrU+p/RXgMiP+Q297cH5ORneUFjHbOQpwrdgestsJw== +X-Received: by 2002:adf:fe05:: with SMTP id n5mr2716992wrr.355.1570019307315; + Wed, 02 Oct 2019 05:28:27 -0700 (PDT) +Received: from localhost (p2E5BE2CE.dip0.t-ipconnect.de. [46.91.226.206]) + by smtp.gmail.com with ESMTPSA id + e17sm5719759wma.15.2019.10.02.05.28.25 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Wed, 02 Oct 2019 05:28:26 -0700 (PDT) +From: Thierry Reding +To: Linus Walleij , + Bartosz Golaszewski +Cc: Timo Alho , linux-gpio@vger.kernel.org, + linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH 1/3] gpio: max77620: Use correct unit for debounce times +Date: Wed, 2 Oct 2019 14:28:23 +0200 +Message-Id: <20191002122825.3948322-1-thierry.reding@gmail.com> +X-Mailer: git-send-email 2.23.0 +MIME-Version: 1.0 +Sender: linux-gpio-owner@vger.kernel.org +Precedence: bulk +List-ID: +X-Mailing-List: linux-gpio@vger.kernel.org + +From: Thierry Reding + +The gpiod_set_debounce() function takes the debounce time in +microseconds. Adjust the switch/case values in the MAX77620 GPIO to use +the correct unit. + +Signed-off-by: Thierry Reding +--- + drivers/gpio/gpio-max77620.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/gpio/gpio-max77620.c b/drivers/gpio/gpio-max77620.c +index 47d05e357e61..faf86ea9c51a 100644 +--- a/drivers/gpio/gpio-max77620.c ++++ b/drivers/gpio/gpio-max77620.c +@@ -192,13 +192,13 @@ static int max77620_gpio_set_debounce(struct max77620_gpio *mgpio, + case 0: + val = MAX77620_CNFG_GPIO_DBNC_None; + break; +- case 1 ... 8: ++ case 1000 ... 8000: + val = MAX77620_CNFG_GPIO_DBNC_8ms; + break; +- case 9 ... 16: ++ case 9000 ... 16000: + val = MAX77620_CNFG_GPIO_DBNC_16ms; + break; +- case 17 ... 32: ++ case 17000 ... 32000: + val = MAX77620_CNFG_GPIO_DBNC_32ms; + break; + default: + +From patchwork Wed Oct 2 12:28:24 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Thierry Reding +X-Patchwork-Id: 1170635 +Return-Path: +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (mailfrom) smtp.mailfrom=vger.kernel.org + (client-ip=209.132.180.67; helo=vger.kernel.org; + envelope-from=linux-gpio-owner@vger.kernel.org; + receiver=) +Authentication-Results: ozlabs.org; + dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; + unprotected) header.d=gmail.com header.i=@gmail.com + header.b="ZNLKx8UP"; dkim-atps=neutral +Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) + by ozlabs.org (Postfix) with ESMTP id 46jwRG4D1Dz9sPj + for ; + Wed, 2 Oct 2019 22:28:42 +1000 (AEST) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S1726684AbfJBM2d (ORCPT ); + Wed, 2 Oct 2019 08:28:33 -0400 +Received: from mail-wr1-f66.google.com ([209.85.221.66]:43919 "EHLO + mail-wr1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S1725848AbfJBM2c (ORCPT + ); Wed, 2 Oct 2019 08:28:32 -0400 +Received: by mail-wr1-f66.google.com with SMTP id q17so19436519wrx.10; + Wed, 02 Oct 2019 05:28:30 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; + h=from:to:cc:subject:date:message-id:in-reply-to:references + :mime-version:content-transfer-encoding; + bh=iB2sFoZ4x2KF5IYNHgeqY98wXl2bB2JULeTFtyoqdVY=; + b=ZNLKx8UP+ukUsboEbPQ9oqLgg5M+37mex1mpr0SgaI7zjToRbmdCJL/chPAEK2r7t8 + C+RcBU7oQnbO3L1hTZQh1VyMX84xXmn0x8g7AskW0bydPo29O2lwBgM9BeNJiMt7gaS7 + LtCbNGe/ttaTfoTsJSOmpLgAJLVJ7mpN5r3h18HtAYcsB5NqjcgFF1yFZ9FvmXOIhxAm + 1MxDJ7tO9pJbc4JQ8iR/yPEsCNibvlX1qtkuBUWdy6aJHG4CkqIbqb+V+84d3R5bsmoe + sDx7f/mMbJ6cF7dCarqOe47Quscz7UkGw/gZywhaYNS/7p6JBvKDCe0bbruzj3MEXMRy + 2tlw== +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=iB2sFoZ4x2KF5IYNHgeqY98wXl2bB2JULeTFtyoqdVY=; + b=E8tcBQ6lyFYE0z3JyOT1cT/Bgc194gfYXxSrFLZnHENJjrNz2Ijr9mgmTvanMcmLgs + qvPIH6L5rKKzPpmhxkGCVNMunQuR3U4+g4lCHaJuDE3QikN/dAMpfidmgej7UBcnxYXq + c8yhdhWsg36bVdUYmTdrPVNYayH3WqNj6h3724+nRQnwGs5Y+emoWuhckIBZQR2fJd3Z + jEEmej1F2QBBv4/Cf7RoOd9BVX1DFI3LgOoGADQcGnuCW/+2clFWp860wnWLGdTGqPKI + KCaPoNOzFDkbQCyhebPt8recsiTexB8AmRdTCOszf/TYQwmlvVUUSVqdwY4/P2N0uAGO + 8kOA== +X-Gm-Message-State: APjAAAVWUbix6mCYosiAjDRWTB69Pz3baQGdU6UKJJJba2d6nCyRFzs3 + w1iyx5KVIbR84BwLezjxgUk= +X-Google-Smtp-Source: APXvYqylRlhdhO5L5gTZTUh+KEGBPZYsf15BqzctBqRpCy2v75DzIQkOOs8h+NZd8ePk6530OH8SlA== +X-Received: by 2002:adf:f112:: with SMTP id r18mr2493221wro.88.1570019309276; + Wed, 02 Oct 2019 05:28:29 -0700 (PDT) +Received: from localhost (p2E5BE2CE.dip0.t-ipconnect.de. [46.91.226.206]) + by smtp.gmail.com with ESMTPSA id + h17sm10777194wme.6.2019.10.02.05.28.28 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Wed, 02 Oct 2019 05:28:28 -0700 (PDT) +From: Thierry Reding +To: Linus Walleij , + Bartosz Golaszewski +Cc: Timo Alho , linux-gpio@vger.kernel.org, + linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH 2/3] gpio: max77620: Do not allocate IRQs upfront +Date: Wed, 2 Oct 2019 14:28:24 +0200 +Message-Id: <20191002122825.3948322-2-thierry.reding@gmail.com> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191002122825.3948322-1-thierry.reding@gmail.com> +References: <20191002122825.3948322-1-thierry.reding@gmail.com> +MIME-Version: 1.0 +Sender: linux-gpio-owner@vger.kernel.org +Precedence: bulk +List-ID: +X-Mailing-List: linux-gpio@vger.kernel.org + +From: Thierry Reding + +regmap_add_irq_chip() will try to allocate all of the IRQ descriptors +upfront if passed a non-zero irq_base parameter. However, the intention +is to allocate IRQ descriptors on an as-needed basis if possible. Pass 0 +instead of -1 to fix that use-case. + +Signed-off-by: Thierry Reding +--- + drivers/gpio/gpio-max77620.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpio/gpio-max77620.c b/drivers/gpio/gpio-max77620.c +index faf86ea9c51a..c58b56e5291e 100644 +--- a/drivers/gpio/gpio-max77620.c ++++ b/drivers/gpio/gpio-max77620.c +@@ -304,7 +304,7 @@ static int max77620_gpio_probe(struct platform_device *pdev) + } + + ret = devm_regmap_add_irq_chip(&pdev->dev, chip->rmap, gpio_irq, +- IRQF_ONESHOT, -1, ++ IRQF_ONESHOT, 0, + &max77620_gpio_irq_chip, + &chip->gpio_irq_data); + if (ret < 0) { + +From patchwork Wed Oct 2 12:28:25 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Thierry Reding +X-Patchwork-Id: 1170633 +Return-Path: +X-Original-To: incoming@patchwork.ozlabs.org +Delivered-To: patchwork-incoming@bilbo.ozlabs.org +Authentication-Results: ozlabs.org; + spf=none (mailfrom) smtp.mailfrom=vger.kernel.org + (client-ip=209.132.180.67; helo=vger.kernel.org; + envelope-from=linux-gpio-owner@vger.kernel.org; + receiver=) +Authentication-Results: ozlabs.org; + dmarc=pass (p=none dis=none) header.from=gmail.com +Authentication-Results: ozlabs.org; dkim=pass (2048-bit key; + unprotected) header.d=gmail.com header.i=@gmail.com + header.b="TsA9TpB7"; dkim-atps=neutral +Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) + by ozlabs.org (Postfix) with ESMTP id 46jwRD5mmDz9sPq + for ; + Wed, 2 Oct 2019 22:28:40 +1000 (AEST) +Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand + id S1727456AbfJBM2f (ORCPT ); + Wed, 2 Oct 2019 08:28:35 -0400 +Received: from mail-wm1-f66.google.com ([209.85.128.66]:34525 "EHLO + mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org + with ESMTP id S1726682AbfJBM2e (ORCPT + ); Wed, 2 Oct 2019 08:28:34 -0400 +Received: by mail-wm1-f66.google.com with SMTP id y135so4823030wmc.1; + Wed, 02 Oct 2019 05:28:32 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; + h=from:to:cc:subject:date:message-id:in-reply-to:references + :mime-version:content-transfer-encoding; + bh=CBafHZOcPLRsPg6HMh6RW3fmvKDiW2MODjit57xEepE=; + b=TsA9TpB72Q02EPmaBqcc4zzucsjsdc5mtjgAgTak5YrKh+mRT2HMioWeCxrLu5Cl+6 + 66PhcUzrRtOnct3yEqC1hueFX+K8TsDr1bJq2f3L5LqA9rYz5Hdk93jVmwyEKtrPUOa5 + DNgu/r4ppuWX/d9nuLpVLcFGOzWYjz/GSfyRm/B0MNSsiIFx/VfjsK6OQk48uN2gyMPf + LsirANA0HYZPyXaUFBkchtTE71HqGFSIzJGUSVGm12Z26puMZ9GiUid1l1XJjdDuFfhU + 3k9TQnvLEpZDHArb2G8JrwRI8fRZ/OBDLPyKvH/EEdDYa/FfJOzliZBqMgVFpXpXGTZ6 + 7YAw== +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=CBafHZOcPLRsPg6HMh6RW3fmvKDiW2MODjit57xEepE=; + b=MVU3M5NDj2W8TitA2MM98hE9Vgb07UODtrRolwf9TaeTgf2XRMgYAWr9v5zaHvBU2q + 4q/HPqbn0WAW3OBfSQLW6CFcdiHOkjfR+r8tKHpNMNBbeDrj1DeeKE/A25plLXxg+Ypz + 1bKJe6DPvjIqLvrpVmPADaRtsAkgDFTt/h41ti2uTwS5xq4qEf1mwz6lFyJkGyf+Qjb5 + pnViJ3Lv89RLBvJwWj0j2t/EzzznPZn9xP663YkNrUNRYrAM7ZBauvK7kMyf8LnKo96E + +niJu7OV4PnRspOC8AS3PPM4DHGctXZl6QMcJ1LyPwBkd8EHJioV1iDJKqHQIbxew46f + AzCA== +X-Gm-Message-State: APjAAAWbRYKoHNSgs+vkRdoNeam2jbbuVKAFxN3ysahEdBul5DIjNFsz + JRjkPkilW+LPTwy2EmDLNUE= +X-Google-Smtp-Source: APXvYqyfSTFvcH9+iLVzVGJ5KDEauN0ssdr9eBfIIdRWe8prWnP7KBGuKItc0GAk8lMLMDzdLKlWtw== +X-Received: by 2002:a1c:7306:: with SMTP id d6mr2864027wmb.62.1570019311374; + Wed, 02 Oct 2019 05:28:31 -0700 (PDT) +Received: from localhost (p2E5BE2CE.dip0.t-ipconnect.de. [46.91.226.206]) + by smtp.gmail.com with ESMTPSA id + 90sm3179450wrr.1.2019.10.02.05.28.30 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Wed, 02 Oct 2019 05:28:30 -0700 (PDT) +From: Thierry Reding +To: Linus Walleij , + Bartosz Golaszewski +Cc: Timo Alho , linux-gpio@vger.kernel.org, + linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org +Subject: [PATCH 3/3] gpio: max77620: Fix interrupt handling +Date: Wed, 2 Oct 2019 14:28:25 +0200 +Message-Id: <20191002122825.3948322-3-thierry.reding@gmail.com> +X-Mailer: git-send-email 2.23.0 +In-Reply-To: <20191002122825.3948322-1-thierry.reding@gmail.com> +References: <20191002122825.3948322-1-thierry.reding@gmail.com> +MIME-Version: 1.0 +Sender: linux-gpio-owner@vger.kernel.org +Precedence: bulk +List-ID: +X-Mailing-List: linux-gpio@vger.kernel.org + +From: Timo Alho + +The interrupt-related register fields on the MAX77620 GPIO controller +share registers with GPIO related fields. If the IRQ chip is implemented +with regmap-irq, this causes the IRQ controller code to overwrite fields +previously configured by the GPIO controller code. + +Two examples where this causes problems are the NVIDIA Jetson TX1 and +Jetson TX2 boards, where some of the GPIOs are used to enable vital +power regulators. The MAX77620 GPIO controller also provides the USB OTG +ID pin. If configured as an interrupt, this causes some of the +regulators to be powered off. + +Signed-off-by: Timo Alho +Signed-off-by: Thierry Reding +--- + drivers/gpio/gpio-max77620.c | 231 ++++++++++++++++++----------------- + 1 file changed, 117 insertions(+), 114 deletions(-) + +diff --git a/drivers/gpio/gpio-max77620.c b/drivers/gpio/gpio-max77620.c +index c58b56e5291e..c5b64a4ac172 100644 +--- a/drivers/gpio/gpio-max77620.c ++++ b/drivers/gpio/gpio-max77620.c +@@ -18,109 +18,115 @@ struct max77620_gpio { + struct gpio_chip gpio_chip; + struct regmap *rmap; + struct device *dev; ++ struct mutex buslock; /* irq_bus_lock */ ++ unsigned int irq_type[8]; ++ bool irq_enabled[8]; + }; + +-static const struct regmap_irq max77620_gpio_irqs[] = { +- [0] = { +- .reg_offset = 0, +- .mask = MAX77620_IRQ_LVL2_GPIO_EDGE0, +- .type = { +- .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, +- .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, +- .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, +- .type_reg_offset = 0, +- .types_supported = IRQ_TYPE_EDGE_BOTH, +- }, +- }, +- [1] = { +- .reg_offset = 0, +- .mask = MAX77620_IRQ_LVL2_GPIO_EDGE1, +- .type = { +- .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, +- .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, +- .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, +- .type_reg_offset = 1, +- .types_supported = IRQ_TYPE_EDGE_BOTH, +- }, +- }, +- [2] = { +- .reg_offset = 0, +- .mask = MAX77620_IRQ_LVL2_GPIO_EDGE2, +- .type = { +- .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, +- .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, +- .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, +- .type_reg_offset = 2, +- .types_supported = IRQ_TYPE_EDGE_BOTH, +- }, +- }, +- [3] = { +- .reg_offset = 0, +- .mask = MAX77620_IRQ_LVL2_GPIO_EDGE3, +- .type = { +- .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, +- .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, +- .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, +- .type_reg_offset = 3, +- .types_supported = IRQ_TYPE_EDGE_BOTH, +- }, +- }, +- [4] = { +- .reg_offset = 0, +- .mask = MAX77620_IRQ_LVL2_GPIO_EDGE4, +- .type = { +- .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, +- .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, +- .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, +- .type_reg_offset = 4, +- .types_supported = IRQ_TYPE_EDGE_BOTH, +- }, +- }, +- [5] = { +- .reg_offset = 0, +- .mask = MAX77620_IRQ_LVL2_GPIO_EDGE5, +- .type = { +- .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, +- .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, +- .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, +- .type_reg_offset = 5, +- .types_supported = IRQ_TYPE_EDGE_BOTH, +- }, +- }, +- [6] = { +- .reg_offset = 0, +- .mask = MAX77620_IRQ_LVL2_GPIO_EDGE6, +- .type = { +- .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, +- .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, +- .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, +- .type_reg_offset = 6, +- .types_supported = IRQ_TYPE_EDGE_BOTH, +- }, +- }, +- [7] = { +- .reg_offset = 0, +- .mask = MAX77620_IRQ_LVL2_GPIO_EDGE7, +- .type = { +- .type_rising_val = MAX77620_CNFG_GPIO_INT_RISING, +- .type_falling_val = MAX77620_CNFG_GPIO_INT_FALLING, +- .type_reg_mask = MAX77620_CNFG_GPIO_INT_MASK, +- .type_reg_offset = 7, +- .types_supported = IRQ_TYPE_EDGE_BOTH, +- }, +- }, +-}; ++static irqreturn_t max77620_gpio_irqhandler(int irq, void *data) ++{ ++ struct max77620_gpio *gpio = data; ++ unsigned int value, offset; ++ unsigned long pending; ++ int err; ++ ++ err = regmap_read(gpio->rmap, MAX77620_REG_IRQ_LVL2_GPIO, &value); ++ if (err < 0) { ++ dev_err(gpio->dev, "REG_IRQ_LVL2_GPIO read failed: %d\n", err); ++ return IRQ_NONE; ++ } ++ ++ pending = value; ++ ++ for_each_set_bit(offset, &pending, 8) { ++ unsigned int virq; ++ ++ virq = irq_find_mapping(gpio->gpio_chip.irq.domain, offset); ++ handle_nested_irq(virq); ++ } ++ ++ return IRQ_HANDLED; ++} ++ ++static void max77620_gpio_irq_mask(struct irq_data *data) ++{ ++ struct gpio_chip *chip = irq_data_get_irq_chip_data(data); ++ struct max77620_gpio *gpio = gpiochip_get_data(chip); ++ ++ gpio->irq_enabled[data->hwirq] = false; ++} + +-static const struct regmap_irq_chip max77620_gpio_irq_chip = { +- .name = "max77620-gpio", +- .irqs = max77620_gpio_irqs, +- .num_irqs = ARRAY_SIZE(max77620_gpio_irqs), +- .num_regs = 1, +- .num_type_reg = 8, +- .irq_reg_stride = 1, +- .type_reg_stride = 1, +- .status_base = MAX77620_REG_IRQ_LVL2_GPIO, +- .type_base = MAX77620_REG_GPIO0, ++static void max77620_gpio_irq_unmask(struct irq_data *data) ++{ ++ struct gpio_chip *chip = irq_data_get_irq_chip_data(data); ++ struct max77620_gpio *gpio = gpiochip_get_data(chip); ++ ++ gpio->irq_enabled[data->hwirq] = true; ++} ++ ++static int max77620_gpio_set_irq_type(struct irq_data *data, unsigned int type) ++{ ++ struct gpio_chip *chip = irq_data_get_irq_chip_data(data); ++ struct max77620_gpio *gpio = gpiochip_get_data(chip); ++ unsigned int irq_type; ++ ++ switch (type) { ++ case IRQ_TYPE_EDGE_RISING: ++ irq_type = MAX77620_CNFG_GPIO_INT_RISING; ++ break; ++ ++ case IRQ_TYPE_EDGE_FALLING: ++ irq_type = MAX77620_CNFG_GPIO_INT_FALLING; ++ break; ++ ++ case IRQ_TYPE_EDGE_BOTH: ++ irq_type = MAX77620_CNFG_GPIO_INT_RISING | ++ MAX77620_CNFG_GPIO_INT_FALLING; ++ break; ++ ++ default: ++ return -EINVAL; ++ } ++ ++ gpio->irq_type[data->hwirq] = irq_type; ++ ++ return 0; ++} ++ ++static void max77620_gpio_bus_lock(struct irq_data *data) ++{ ++ struct gpio_chip *chip = irq_data_get_irq_chip_data(data); ++ struct max77620_gpio *gpio = gpiochip_get_data(chip); ++ ++ mutex_lock(&gpio->buslock); ++} ++ ++static void max77620_gpio_bus_sync_unlock(struct irq_data *data) ++{ ++ struct gpio_chip *chip = irq_data_get_irq_chip_data(data); ++ struct max77620_gpio *gpio = gpiochip_get_data(chip); ++ unsigned int value, offset = data->hwirq; ++ int err; ++ ++ value = gpio->irq_enabled[offset] ? gpio->irq_type[offset] : 0; ++ ++ err = regmap_update_bits(gpio->rmap, GPIO_REG_ADDR(offset), ++ MAX77620_CNFG_GPIO_INT_MASK, value); ++ if (err < 0) ++ dev_err(chip->parent, "failed to update interrupt mask: %d\n", ++ err); ++ ++ mutex_unlock(&gpio->buslock); ++} ++ ++static struct irq_chip max77620_gpio_irqchip = { ++ .name = "max77620-gpio", ++ .irq_mask = max77620_gpio_irq_mask, ++ .irq_unmask = max77620_gpio_irq_unmask, ++ .irq_set_type = max77620_gpio_set_irq_type, ++ .irq_bus_lock = max77620_gpio_bus_lock, ++ .irq_bus_sync_unlock = max77620_gpio_bus_sync_unlock, ++ .flags = IRQCHIP_MASK_ON_SUSPEND, + }; + + static int max77620_gpio_dir_input(struct gpio_chip *gc, unsigned int offset) +@@ -254,14 +260,6 @@ static int max77620_gpio_set_config(struct gpio_chip *gc, unsigned int offset, + return -ENOTSUPP; + } + +-static int max77620_gpio_to_irq(struct gpio_chip *gc, unsigned int offset) +-{ +- struct max77620_gpio *mgpio = gpiochip_get_data(gc); +- struct max77620_chip *chip = dev_get_drvdata(mgpio->dev->parent); +- +- return regmap_irq_get_virq(chip->gpio_irq_data, offset); +-} +- + static int max77620_gpio_probe(struct platform_device *pdev) + { + struct max77620_chip *chip = dev_get_drvdata(pdev->dev.parent); +@@ -287,7 +285,6 @@ static int max77620_gpio_probe(struct platform_device *pdev) + mgpio->gpio_chip.direction_output = max77620_gpio_dir_output; + mgpio->gpio_chip.set = max77620_gpio_set; + mgpio->gpio_chip.set_config = max77620_gpio_set_config; +- mgpio->gpio_chip.to_irq = max77620_gpio_to_irq; + mgpio->gpio_chip.ngpio = MAX77620_GPIO_NR; + mgpio->gpio_chip.can_sleep = 1; + mgpio->gpio_chip.base = -1; +@@ -303,15 +300,21 @@ static int max77620_gpio_probe(struct platform_device *pdev) + return ret; + } + +- ret = devm_regmap_add_irq_chip(&pdev->dev, chip->rmap, gpio_irq, +- IRQF_ONESHOT, 0, +- &max77620_gpio_irq_chip, +- &chip->gpio_irq_data); ++ mutex_init(&mgpio->buslock); ++ ++ gpiochip_irqchip_add_nested(&mgpio->gpio_chip, &max77620_gpio_irqchip, ++ 0, handle_edge_irq, IRQ_TYPE_NONE); ++ ++ ret = request_threaded_irq(gpio_irq, NULL, max77620_gpio_irqhandler, ++ IRQF_ONESHOT, "max77620-gpio", mgpio); + if (ret < 0) { +- dev_err(&pdev->dev, "Failed to add gpio irq_chip %d\n", ret); ++ dev_err(&pdev->dev, "failed to request IRQ: %d\n", ret); + return ret; + } + ++ gpiochip_set_nested_irqchip(&mgpio->gpio_chip, &max77620_gpio_irqchip, ++ gpio_irq); ++ + return 0; + } + diff --git a/kernel.spec b/kernel.spec index 0e08534ff..b66e7fb7e 100644 --- a/kernel.spec +++ b/kernel.spec @@ -563,6 +563,14 @@ Patch308: arm64-dts-rockchip-fix-Rockpro64-RK808-interrupt-line.patch Patch320: arm64-tegra-jetson-tx1-fixes.patch # https://www.spinics.net/lists/linux-tegra/msg43110.html Patch321: arm64-tegra-Jetson-TX2-Allow-bootloader-to-configure.patch +# https://patchwork.kernel.org/patch/11171225/ +Patch322: mfd-max77620-Do-not-allocate-IRQs-upfront.patch +# https://patchwork.ozlabs.org/patch/1170631/ +Patch323: gpio-max77620-Use-correct-unit-for-debounce-times.patch +# https://patchwork.freedesktop.org/series/66762/ +Patch324: drm-nouveau-Enable-GP10B-by-default.patch +# https://www.spinics.net/lists/linux-tegra/msg44216.html +Patch325: arm64-tegra186-enable-USB-on-Jetson-TX2.patch # QCom laptop bits # https://patchwork.kernel.org/patch/11133827/ @@ -1803,6 +1811,7 @@ fi %changelog * Sun Oct 6 2019 Peter Robinson - Fixes for RockPro64 +- Fixes for Jetson-TX series devices * Wed Oct 03 2019 Justin M. Forbes - Fix CVE-2019-17052 CVE-2019-17053 CVE-2019-17054 CVE-2019-17055 CVE-2019-17056 diff --git a/mfd-max77620-Do-not-allocate-IRQs-upfront.patch b/mfd-max77620-Do-not-allocate-IRQs-upfront.patch new file mode 100644 index 000000000..0b4820ad7 --- /dev/null +++ b/mfd-max77620-Do-not-allocate-IRQs-upfront.patch @@ -0,0 +1,183 @@ +From patchwork Wed Oct 2 14:43:18 2019 +Content-Type: text/plain; charset="utf-8" +MIME-Version: 1.0 +Content-Transfer-Encoding: 7bit +X-Patchwork-Submitter: Thierry Reding +X-Patchwork-Id: 11171225 +Return-Path: + +Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org + [172.30.200.123]) + by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C771E1747 + for ; + Wed, 2 Oct 2019 14:45:14 +0000 (UTC) +Received: from bombadil.infradead.org (bombadil.infradead.org + [198.137.202.133]) + (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) + (No client certificate requested) + by mail.kernel.org (Postfix) with ESMTPS id 9703B21D81 + for ; + Wed, 2 Oct 2019 14:45:14 +0000 (UTC) +Authentication-Results: mail.kernel.org; + dkim=pass (2048-bit key) header.d=lists.infradead.org + header.i=@lists.infradead.org header.b="LCP5OdWP"; + dkim=fail reason="signature verification failed" (2048-bit key) + header.d=gmail.com header.i=@gmail.com header.b="ahoJ80fO" +DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 9703B21D81 +Authentication-Results: mail.kernel.org; + dmarc=fail (p=none dis=none) header.from=gmail.com +Authentication-Results: mail.kernel.org; + spf=none + smtp.mailfrom=linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org +DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; + d=lists.infradead.org; s=bombadil.20170209; h=Sender: + Content-Transfer-Encoding:Content-Type:Cc:List-Subscribe:List-Help:List-Post: + List-Archive:List-Unsubscribe:List-Id:MIME-Version:Message-Id:Date:Subject:To + :From:Reply-To:Content-ID:Content-Description:Resent-Date:Resent-From: + Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:In-Reply-To:References: + List-Owner; bh=csIWPoJz7RR9msf1imaCNOLXiDPcaRmxRKjOL8gMaXM=; b=LCP5OdWPpIBxJz + tSNffGBZI2pwLSarAvmqKIowLW5LghNe3CVQh7HM3sIR+IqrUtTSXi/0EEQAQORrYHSnR4zrDlubl + 8IIqIetbgOrEmYRpHQxWZV/Z0p5JTdvNVeOiR63CuFbjz/h9UXPWOiLZijU1eZfSN2UuEJWxzoWMF + CsXxW+3rZ3os8AAa9x0lt6gGLwAPEPrxP44q4AJTVp3q+cD7GTXHu0F2ZT2flxES+cFF2/cPg2GiM + yR5j7GNMDhdxFKjGp8qcDhfCKx/0jF0DofnC4JsVlN0R25HdwYHzdHhysk8ca7JxLIMJlgXsgM5aY + 4XUIEB/0CjoPtdbP+8yw==; +Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) + by bombadil.infradead.org with esmtp (Exim 4.92.2 #3 (Red Hat Linux)) + id 1iFfsO-0006Nf-SR; Wed, 02 Oct 2019 14:45:12 +0000 +Received: from mail-wr1-x443.google.com ([2a00:1450:4864:20::443]) + by bombadil.infradead.org with esmtps (Exim 4.92.2 #3 (Red Hat Linux)) + id 1iFfqd-0003rK-EL + for linux-arm-kernel@lists.infradead.org; Wed, 02 Oct 2019 14:43:47 +0000 +Received: by mail-wr1-x443.google.com with SMTP id w12so19991081wro.5 + for ; + Wed, 02 Oct 2019 07:43:21 -0700 (PDT) +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; + h=from:to:cc:subject:date:message-id:mime-version + :content-transfer-encoding; + bh=y9l/1MkRoZLCyZNPXaR5fzwvTbuyIzYA20JLtWuhYR4=; + b=ahoJ80fONPxwQPqvbuQRAba40syj0YJFK3SbqTxd0FOzhs1n3WTvNd/gHQ+2WK5WwB + 8joqipXveUGBgePR1RwHR0oQyDAumewRmSMStvhyCHPeo154CNqZfGQNlbNlRng2QJqd + 1/Sq8GNJ1DjcLifpHWbCC9LoK5U3UkvdIWHPFx0cqJ+ENvPHkYPr2FdpaZ8jxuJta3TT + dplkNk0AsL/tc33KBJbKUSlnYppX878WQXUvnhdB+TRmr5R3dtc5Ewc0TH4h7V1SXTly + GiNnbbCc+BKzzqk9PTo/Pqf5dzWcpNDBA1GUkzQZDTXOXXUzBjnlrTaQctjSdE6meWfJ + JbDw== +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:mime-version + :content-transfer-encoding; + bh=y9l/1MkRoZLCyZNPXaR5fzwvTbuyIzYA20JLtWuhYR4=; + b=m4CouDn44ioMScPU+9h/V5vlxCAt0m4CSZKRu3pcsThkHE6u1TeKieaoBr1mh1qnIv + YS+V9Cd7osJa8R8USg+SJkEaSSarOn4kUq2MPTgMMmvKb63SSCCs0QD44nwEBAjIgMd/ + /akFUOMTGQBnN7P8Iq3KWI00bVJLeoVWmqtQPkLFI1cIRrkCKTF4jh6b+i6xsiT8t2rd + l6WPsWnKkqUmPAqzpmLJ9bmSsiGBBFUexUJDcQnskkx6tTBzFhyNtpsbq6VdcY2mS3LR + rgGbisZRFdLvdZfGhmPX1hRgDoiHQLuWNAv49LtJtR7/CjNFmsKr4MBg1ydz0uO01Axr + zoIQ== +X-Gm-Message-State: APjAAAXPZ9a+CEGZKeL6T+FXZoBRFrxryg3xujpPFnNpjznB8ehsaTI0 + P6wL6cWqK9IRnS17Y/YRAb4= +X-Google-Smtp-Source: + APXvYqyETp8FIXhzzDrv+mhfzHhU0D9h3bcpLQ9oRbkEYPG7JvxLk5RVWx/ooYmku2+exI6oXsHTnA== +X-Received: by 2002:a5d:4dd0:: with SMTP id f16mr2905889wru.85.1570027400467; + Wed, 02 Oct 2019 07:43:20 -0700 (PDT) +Received: from localhost (p2E5BE2CE.dip0.t-ipconnect.de. [46.91.226.206]) + by smtp.gmail.com with ESMTPSA id z125sm10251381wme.37.2019.10.02.07.43.19 + (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); + Wed, 02 Oct 2019 07:43:19 -0700 (PDT) +From: Thierry Reding +To: Lee Jones +Subject: [PATCH] mfd: max77620: Do not allocate IRQs upfront +Date: Wed, 2 Oct 2019 16:43:18 +0200 +Message-Id: <20191002144318.140365-1-thierry.reding@gmail.com> +X-Mailer: git-send-email 2.23.0 +MIME-Version: 1.0 +X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 +X-CRM114-CacheID: sfid-20191002_074330_018855_CC323A91 +X-CRM114-Status: GOOD ( 11.81 ) +X-Spam-Score: -0.2 (/) +X-Spam-Report: SpamAssassin version 3.4.2 on bombadil.infradead.org summary: + Content analysis details: (-0.2 points) + pts rule name description + ---- ---------------------- + -------------------------------------------------- + -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at https://www.dnswl.org/, + no trust [2a00:1450:4864:20:0:0:0:443 listed in] + [list.dnswl.org] + -0.0 SPF_PASS SPF: sender matches SPF record + 0.0 SPF_HELO_NONE SPF: HELO does not publish an SPF Record + 0.0 FREEMAIL_FROM Sender email is commonly abused enduser mail + provider (thierry.reding[at]gmail.com) + -0.1 DKIM_VALID_EF Message has a valid DKIM or DK signature from + envelope-from domain + 0.1 DKIM_SIGNED Message has a DKIM or DK signature, + not necessarily + valid + -0.1 DKIM_VALID_AU Message has a valid DKIM or DK signature from + author's domain + -0.1 DKIM_VALID Message has at least one valid DKIM or DK signature +X-BeenThere: linux-arm-kernel@lists.infradead.org +X-Mailman-Version: 2.1.29 +Precedence: list +List-Id: +List-Unsubscribe: + , + +List-Archive: +List-Post: +List-Help: +List-Subscribe: + , + +Cc: linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, + linux-arm-kernel@lists.infradead.org +Content-Type: text/plain; charset="us-ascii" +Sender: "linux-arm-kernel" +Errors-To: + linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org + +From: Thierry Reding + +regmap_add_irq_chip() will try to allocate all of the IRQ descriptors +upfront if passed a non-zero irq_base parameter. However, the intention +is to allocate IRQ descriptors on an as-needed basis if possible. Pass 0 +instead of -1 to fix that use-case. + +Signed-off-by: Thierry Reding +--- + drivers/mfd/max77620.c | 5 ++--- + include/linux/mfd/max77620.h | 1 - + 2 files changed, 2 insertions(+), 4 deletions(-) + +diff --git a/drivers/mfd/max77620.c b/drivers/mfd/max77620.c +index a851ff473a44..c7ed5c353553 100644 +--- a/drivers/mfd/max77620.c ++++ b/drivers/mfd/max77620.c +@@ -507,7 +507,6 @@ static int max77620_probe(struct i2c_client *client, + + i2c_set_clientdata(client, chip); + chip->dev = &client->dev; +- chip->irq_base = -1; + chip->chip_irq = client->irq; + chip->chip_id = (enum max77620_chip_id)id->driver_data; + +@@ -545,8 +544,8 @@ static int max77620_probe(struct i2c_client *client, + + max77620_top_irq_chip.irq_drv_data = chip; + ret = devm_regmap_add_irq_chip(chip->dev, chip->rmap, client->irq, +- IRQF_ONESHOT | IRQF_SHARED, +- chip->irq_base, &max77620_top_irq_chip, ++ IRQF_ONESHOT | IRQF_SHARED, 0, ++ &max77620_top_irq_chip, + &chip->top_irq_data); + if (ret < 0) { + dev_err(chip->dev, "Failed to add regmap irq: %d\n", ret); +diff --git a/include/linux/mfd/max77620.h b/include/linux/mfd/max77620.h +index 12ba157cb83f..f552ef5b1100 100644 +--- a/include/linux/mfd/max77620.h ++++ b/include/linux/mfd/max77620.h +@@ -329,7 +329,6 @@ struct max77620_chip { + struct regmap *rmap; + + int chip_irq; +- int irq_base; + + /* chip id */ + enum max77620_chip_id chip_id;