Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 0/9] drm/nouveau: Various fixes for GP10B
From: Thierry Reding <treding at nvidia.com> Hi Ben, here's a revised subset of the patches I had sent out a couple of weeks ago. I've reworked the BAR2 accesses in the way that you had suggested, which at least for GP10B turned out to be fairly trivial to do. I have not looked in detail at this for GV11B yet, but a cursory look showed that BAR2 is accessed in more places, so the equivalent for GV11B might be a bit more involved. Other than that, not a lot has changed since then. I've added a couple of precursory patches to add IOMMU helper dummies for the case where IOMMU is disabled (as suggested by Ben Dooks). Joerg, it'd be great if you could give an Acked-by on those two patches so that Ben can pick them both up into the Nouveau tree. Alternatively I can put them both into a stable branch and send a pull request to both of you. Or yet another alternative would be for Joerg to apply them now and Ben to wait for v5.5-rc1 until he picks up the rest. All of those work for me. Thierry Thierry Reding (9): iommu: Document iommu_fwspec::flags field iommu: Add dummy dev_iommu_fwspec_get() helper drm/nouveau: fault: Add support for GP10B drm/nouveau: tegra: Do not try to disable PCI device drm/nouveau: tegra: Avoid pulsing reset twice drm/nouveau: tegra: Set clock rate if not set drm/nouveau: secboot: Read WPR configuration from GPU registers drm/nouveau: gp10b: Add custom L2 cache implementation drm/nouveau: gp10b: Use correct copy engine .../drm/nouveau/include/nvkm/subdev/fault.h | 1 + .../gpu/drm/nouveau/include/nvkm/subdev/ltc.h | 1 + drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +- .../gpu/drm/nouveau/nvkm/engine/device/base.c | 6 +- .../drm/nouveau/nvkm/engine/device/tegra.c | 24 ++++-- .../gpu/drm/nouveau/nvkm/subdev/fault/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fault/base.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/fault/gp100.c | 17 ++-- .../gpu/drm/nouveau/nvkm/subdev/fault/gp10b.c | 53 ++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/fault/gv100.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/fault/priv.h | 10 +++ .../gpu/drm/nouveau/nvkm/subdev/ltc/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c | 65 +++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/ltc/priv.h | 2 + .../drm/nouveau/nvkm/subdev/secboot/gm200.h | 2 +- .../drm/nouveau/nvkm/subdev/secboot/gm20b.c | 81 ++++++++++++------- .../drm/nouveau/nvkm/subdev/secboot/gp10b.c | 4 +- include/linux/iommu.h | 46 ++++++----- 18 files changed, 249 insertions(+), 71 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp10b.c create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 1/9] iommu: Document iommu_fwspec::flags field
From: Thierry Reding <treding at nvidia.com> When this field was added in commit 5702ee24182f ("ACPI/IORT: Check ATS capability in root complex nodes"), the kerneldoc comment wasn't updated at the same time. Signed-off-by: Thierry Reding <treding at nvidia.com> --- include/linux/iommu.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index e28e80dea141..7bf038b371b8 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -570,6 +570,7 @@ struct iommu_group *fsl_mc_device_group(struct device *dev); * @ops: ops for this device's IOMMU * @iommu_fwnode: firmware handle for this device's IOMMU * @iommu_priv: IOMMU driver private data for this device + * @flags: IOMMU flags associated with this device * @num_ids: number of associated device IDs * @ids: IDs which this device may present to the IOMMU */ -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 2/9] iommu: Add dummy dev_iommu_fwspec_get() helper
From: Thierry Reding <treding at nvidia.com> This dummy implementation is useful to avoid a dependency on the IOMMU_API Kconfig symbol in drivers that can optionally use the IOMMU API. In order to fully use this, also move the struct iommu_fwspec definition out of the IOMMU_API protected region. Suggested-by: Ben Dooks <ben.dooks at codethink.co.uk> Signed-off-by: Thierry Reding <treding at nvidia.com> --- include/linux/iommu.h | 47 ++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 21 deletions(-) diff --git a/include/linux/iommu.h b/include/linux/iommu.h index 7bf038b371b8..b092e73b2c86 100644 --- a/include/linux/iommu.h +++ b/include/linux/iommu.h @@ -190,6 +190,27 @@ struct iommu_sva_ops { iommu_mm_exit_handler_t mm_exit; }; +/** + * struct iommu_fwspec - per-device IOMMU instance data + * @ops: ops for this device's IOMMU + * @iommu_fwnode: firmware handle for this device's IOMMU + * @iommu_priv: IOMMU driver private data for this device + * @flags: IOMMU flags associated with this device + * @num_ids: number of associated device IDs + * @ids: IDs which this device may present to the IOMMU + */ +struct iommu_fwspec { + const struct iommu_ops *ops; + struct fwnode_handle *iommu_fwnode; + void *iommu_priv; + u32 flags; + unsigned int num_ids; + u32 ids[1]; +}; + +/* ATS is supported */ +#define IOMMU_FWSPEC_PCI_RC_ATS (1 << 0) + #ifdef CONFIG_IOMMU_API /** @@ -565,27 +586,6 @@ extern struct iommu_group *generic_device_group(struct device *dev); /* FSL-MC device grouping function */ struct iommu_group *fsl_mc_device_group(struct device *dev); -/** - * struct iommu_fwspec - per-device IOMMU instance data - * @ops: ops for this device's IOMMU - * @iommu_fwnode: firmware handle for this device's IOMMU - * @iommu_priv: IOMMU driver private data for this device - * @flags: IOMMU flags associated with this device - * @num_ids: number of associated device IDs - * @ids: IDs which this device may present to the IOMMU - */ -struct iommu_fwspec { - const struct iommu_ops *ops; - struct fwnode_handle *iommu_fwnode; - void *iommu_priv; - u32 flags; - unsigned int num_ids; - u32 ids[1]; -}; - -/* ATS is supported */ -#define IOMMU_FWSPEC_PCI_RC_ATS (1 << 0) - /** * struct iommu_sva - handle to a device-mm bond */ @@ -980,6 +980,11 @@ const struct iommu_ops *iommu_ops_from_fwnode(struct fwnode_handle *fwnode) return NULL; } +static inline struct iommu_fwspec *dev_iommu_fwspec_get(struct device *dev) +{ + return NULL; +} + static inline bool iommu_dev_has_feature(struct device *dev, enum iommu_dev_features feat) { -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 3/9] drm/nouveau: fault: Add support for GP10B
From: Thierry Reding <treding at nvidia.com> There is no BAR2 on GP10B and there is no need to map through BAR2 because all memory is shared between the GPU and the CPU. Add a custom implementation of the fault sub-device that uses nvkm_memory_addr() instead of nvkm_memory_bar2() to return the address of a pinned fault buffer. Signed-off-by: Thierry Reding <treding at nvidia.com> --- .../drm/nouveau/include/nvkm/subdev/fault.h | 1 + .../gpu/drm/nouveau/nvkm/engine/device/base.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/fault/Kbuild | 1 + .../gpu/drm/nouveau/nvkm/subdev/fault/base.c | 2 +- .../gpu/drm/nouveau/nvkm/subdev/fault/gp100.c | 17 ++++-- .../gpu/drm/nouveau/nvkm/subdev/fault/gp10b.c | 53 +++++++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/fault/gv100.c | 1 + .../gpu/drm/nouveau/nvkm/subdev/fault/priv.h | 10 ++++ 8 files changed, 80 insertions(+), 7 deletions(-) create mode 100644 drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp10b.c diff --git a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h index 97322f95b3ee..a513c16ab105 100644 --- a/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h +++ b/drivers/gpu/drm/nouveau/include/nvkm/subdev/fault.h @@ -31,6 +31,7 @@ struct nvkm_fault_data { }; int gp100_fault_new(struct nvkm_device *, int, struct nvkm_fault **); +int gp10b_fault_new(struct nvkm_device *, int, struct nvkm_fault **); int gv100_fault_new(struct nvkm_device *, int, struct nvkm_fault **); int tu102_fault_new(struct nvkm_device *, int, struct nvkm_fault **); #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..b061df138142 100644 --- a/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/engine/device/base.c @@ -2375,7 +2375,7 @@ nv13b_chipset = { .name = "GP10B", .bar = gm20b_bar_new, .bus = gf100_bus_new, - .fault = gp100_fault_new, + .fault = gp10b_fault_new, .fb = gp10b_fb_new, .fuse = gm107_fuse_new, .ibus = gp10b_ibus_new, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild index 53b9d638f2c8..d65ec719f153 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/Kbuild @@ -2,5 +2,6 @@ nvkm-y += nvkm/subdev/fault/base.o nvkm-y += nvkm/subdev/fault/user.o nvkm-y += nvkm/subdev/fault/gp100.o +nvkm-y += nvkm/subdev/fault/gp10b.o nvkm-y += nvkm/subdev/fault/gv100.o nvkm-y += nvkm/subdev/fault/tu102.o diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c index ca251560d3e0..1c4b852b26c3 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/base.c @@ -108,7 +108,7 @@ nvkm_fault_oneinit_buffer(struct nvkm_fault *fault, int id) return ret; /* Pin fault buffer in BAR2. */ - buffer->addr = nvkm_memory_bar2(buffer->mem); + buffer->addr = fault->func->buffer.pin(buffer); if (buffer->addr == ~0ULL) return -EFAULT; diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c index 4f3c4e091117..f6b189cc4330 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp100.c @@ -21,25 +21,26 @@ */ #include "priv.h" +#include <core/memory.h> #include <subdev/mc.h> #include <nvif/class.h> -static void +void gp100_fault_buffer_intr(struct nvkm_fault_buffer *buffer, bool enable) { struct nvkm_device *device = buffer->fault->subdev.device; nvkm_mc_intr_mask(device, NVKM_SUBDEV_FAULT, enable); } -static void +void gp100_fault_buffer_fini(struct nvkm_fault_buffer *buffer) { struct nvkm_device *device = buffer->fault->subdev.device; nvkm_mask(device, 0x002a70, 0x00000001, 0x00000000); } -static void +void gp100_fault_buffer_init(struct nvkm_fault_buffer *buffer) { struct nvkm_device *device = buffer->fault->subdev.device; @@ -48,7 +49,12 @@ gp100_fault_buffer_init(struct nvkm_fault_buffer *buffer) nvkm_mask(device, 0x002a70, 0x00000001, 0x00000001); } -static void +u64 gp100_fault_buffer_pin(struct nvkm_fault_buffer *buffer) +{ + return nvkm_memory_bar2(buffer->mem); +} + +void gp100_fault_buffer_info(struct nvkm_fault_buffer *buffer) { buffer->entries = nvkm_rd32(buffer->fault->subdev.device, 0x002a78); @@ -56,7 +62,7 @@ gp100_fault_buffer_info(struct nvkm_fault_buffer *buffer) buffer->put = 0x002a80; } -static void +void gp100_fault_intr(struct nvkm_fault *fault) { nvkm_event_send(&fault->event, 1, 0, NULL, 0); @@ -68,6 +74,7 @@ gp100_fault = { .buffer.nr = 1, .buffer.entry_size = 32, .buffer.info = gp100_fault_buffer_info, + .buffer.pin = gp100_fault_buffer_pin, .buffer.init = gp100_fault_buffer_init, .buffer.fini = gp100_fault_buffer_fini, .buffer.intr = gp100_fault_buffer_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp10b.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp10b.c new file mode 100644 index 000000000000..9e66d1f7654d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gp10b.c @@ -0,0 +1,53 @@ +/* + * 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. + */ + +#include "priv.h" + +#include <core/memory.h> + +#include <nvif/class.h> + +u64 +gp10b_fault_buffer_pin(struct nvkm_fault_buffer *buffer) +{ + return nvkm_memory_addr(buffer->mem); +} + +static const struct nvkm_fault_func +gp10b_fault = { + .intr = gp100_fault_intr, + .buffer.nr = 1, + .buffer.entry_size = 32, + .buffer.info = gp100_fault_buffer_info, + .buffer.pin = gp10b_fault_buffer_pin, + .buffer.init = gp100_fault_buffer_init, + .buffer.fini = gp100_fault_buffer_fini, + .buffer.intr = gp100_fault_buffer_intr, + .user = { { 0, 0, MAXWELL_FAULT_BUFFER_A }, 0 }, +}; + +int +gp10b_fault_new(struct nvkm_device *device, int index, + struct nvkm_fault **pfault) +{ + return nvkm_fault_new_(&gp10b_fault, device, index, pfault); +} diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c index 6747f09c2dc3..2707be4ffabc 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/gv100.c @@ -214,6 +214,7 @@ gv100_fault = { .buffer.nr = 2, .buffer.entry_size = 32, .buffer.info = gv100_fault_buffer_info, + .buffer.pin = gp100_fault_buffer_pin, .buffer.init = gv100_fault_buffer_init, .buffer.fini = gv100_fault_buffer_fini, .buffer.intr = gv100_fault_buffer_intr, diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h index 975e66ac6344..f6f1dd7eee1f 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fault/priv.h @@ -30,6 +30,7 @@ struct nvkm_fault_func { int nr; u32 entry_size; void (*info)(struct nvkm_fault_buffer *); + u64 (*pin)(struct nvkm_fault_buffer *); void (*init)(struct nvkm_fault_buffer *); void (*fini)(struct nvkm_fault_buffer *); void (*intr)(struct nvkm_fault_buffer *, bool enable); @@ -40,6 +41,15 @@ struct nvkm_fault_func { } user; }; +void gp100_fault_buffer_intr(struct nvkm_fault_buffer *, bool enable); +void gp100_fault_buffer_fini(struct nvkm_fault_buffer *); +void gp100_fault_buffer_init(struct nvkm_fault_buffer *); +u64 gp100_fault_buffer_pin(struct nvkm_fault_buffer *); +void gp100_fault_buffer_info(struct nvkm_fault_buffer *); +void gp100_fault_intr(struct nvkm_fault *); + +u64 gp10b_fault_buffer_pin(struct nvkm_fault_buffer *); + int gv100_fault_oneinit(struct nvkm_fault *); int nvkm_ufault_new(struct nvkm_device *, const struct nvkm_oclass *, -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 4/9] drm/nouveau: tegra: Do not try to disable PCI device
From: Thierry Reding <treding at nvidia.com> When Nouveau is instantiated on top of a platform device, the dev->pdev field will be NULL and calling pci_disable_device() will crash. Move the PCI disabling code to the PCI specific driver removal code. Reviewed-by: Lyude Paul <lyude at redhat.com> Signed-off-by: Thierry Reding <treding at nvidia.com> --- drivers/gpu/drm/nouveau/nouveau_drm.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 2cd83849600f..b65ae817eabf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -715,7 +715,6 @@ static int nouveau_drm_probe(struct pci_dev *pdev, void nouveau_drm_device_remove(struct drm_device *dev) { - struct pci_dev *pdev = dev->pdev; struct nouveau_drm *drm = nouveau_drm(dev); struct nvkm_client *client; struct nvkm_device *device; @@ -727,7 +726,6 @@ nouveau_drm_device_remove(struct drm_device *dev) device = nvkm_device_find(client->device); nouveau_drm_device_fini(dev); - pci_disable_device(pdev); drm_dev_put(dev); nvkm_device_del(&device); } @@ -738,6 +736,7 @@ nouveau_drm_remove(struct pci_dev *pdev) struct drm_device *dev = pci_get_drvdata(pdev); nouveau_drm_device_remove(dev); + pci_disable_device(pdev); } static int -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 5/9] drm/nouveau: tegra: Avoid pulsing reset twice
From: Thierry Reding <treding at nvidia.com> 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 <treding at nvidia.com> --- 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; -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 6/9] drm/nouveau: tegra: Set clock rate if not set
From: Thierry Reding <treding at nvidia.com> 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 <treding at nvidia.com> --- 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)) { -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 7/9] drm/nouveau: secboot: Read WPR configuration from GPU registers
From: Thierry Reding <treding at nvidia.com> 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 <treding at nvidia.com> --- .../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; -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 8/9] drm/nouveau: gp10b: Add custom L2 cache implementation
From: Thierry Reding <treding at nvidia.com> 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 <treding at nvidia.com> --- Changes in v2: - remove IOMMU_API protection to increase compile coverage - relies on dummy dev_iommu_fwspec_get() helper .../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 | 65 +++++++++++++++++++ .../gpu/drm/nouveau/nvkm/subdev/ltc/priv.h | 2 + 5 files changed, 70 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 b061df138142..231ec0073af3 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..c0063c7caa50 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/ltc/gp10b.c @@ -0,0 +1,65 @@ +/* + * 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; + struct iommu_fwspec *spec; + + nvkm_wr32(device, 0x17e27c, ltc->ltc_nr); + nvkm_wr32(device, 0x17e000, ltc->ltc_nr); + nvkm_wr32(device, 0x100800, ltc->ltc_nr); + + spec = dev_iommu_fwspec_get(device->dev); + if (spec) { + u32 sid = spec->ids[0] & 0xffff; + + /* stream ID */ + nvkm_wr32(device, 0x160000, sid << 2); + } +} + +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 -- 2.23.0
Thierry Reding
2019-Nov-02 17:56 UTC
[Nouveau] [PATCH v2 9/9] drm/nouveau: gp10b: Use correct copy engine
From: Thierry Reding <treding at nvidia.com> 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 <treding at nvidia.com> --- 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 231ec0073af3..eba450e689b2 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, -- 2.23.0
kbuild test robot
2019-Nov-03 05:17 UTC
[Nouveau] [PATCH v2 2/9] iommu: Add dummy dev_iommu_fwspec_get() helper
Hi Thierry, I love your patch! Yet something to improve: [auto build test ERROR on linus/master] [also build test ERROR on v5.4-rc5 next-20191031] [if your patch is applied to the wrong git tree, please drop us a note to help improve the system. BTW, we also suggest to use '--base' option to specify the base tree in git format-patch, please see https://stackoverflow.com/a/37406982] url: https://github.com/0day-ci/linux/commits/Thierry-Reding/drm-nouveau-Various-fixes-for-GP10B/20191103-125101 base: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git 56cfd2507d3e720f4b1dbf9513e00680516a0826 config: i386-tinyconfig (attached as .config) compiler: gcc-7 (Debian 7.4.0-14) 7.4.0 reproduce: # save the attached .config to linux build tree make ARCH=i386 If you fix the issue, kindly add following tag Reported-by: kbuild test robot <lkp at intel.com> All errors (new ones prefixed by >>): In file included from arch/x86/kernel/pci-dma.c:4:0:>> include/linux/iommu.h:615:8: error: redefinition of 'struct iommu_fwspec'struct iommu_fwspec {}; ^~~~~~~~~~~~ In file included from include/linux/dma-mapping.h:7:0, from include/linux/dma-direct.h:5, from arch/x86/kernel/pci-dma.c:2: include/linux/device.h:43:8: note: originally defined here struct iommu_fwspec; ^~~~~~~~~~~~ vim +615 include/linux/iommu.h 4a77a6cf6d9bf9 Joerg Roedel 2008-11-26 612 39d4ebb9592504 Joerg Roedel 2011-09-06 613 struct iommu_ops {}; d72e31c9374627 Alex Williamson 2012-05-30 614 struct iommu_group {}; 57f98d2f61e191 Robin Murphy 2016-09-13 @615 struct iommu_fwspec {}; b0119e870837dc Joerg Roedel 2017-02-01 616 struct iommu_device {}; 4e32348ba5269a Jacob Pan 2019-06-03 617 struct iommu_fault_param {}; a7d20dc19d9ea7 Will Deacon 2019-07-02 618 struct iommu_iotlb_gather {}; 4a77a6cf6d9bf9 Joerg Roedel 2008-11-26 619 :::::: The code at line 615 was first introduced by commit :::::: 57f98d2f61e191ef9d06863c9ce3f8621f3671ef iommu: Introduce iommu_fwspec :::::: TO: Robin Murphy <robin.murphy at arm.com> :::::: CC: Will Deacon <will.deacon at arm.com> --- 0-DAY kernel test infrastructure Open Source Technology Center https://lists.01.org/pipermail/kbuild-all Intel Corporation -------------- next part -------------- A non-text attachment was scrubbed... Name: .config.gz Type: application/gzip Size: 7207 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/nouveau/attachments/20191103/03cd3df5/attachment.gz>
Thierry Reding
2019-Nov-18 13:44 UTC
[Nouveau] [PATCH v2 0/9] drm/nouveau: Various fixes for GP10B
On Sat, Nov 02, 2019 at 06:56:28PM +0100, Thierry Reding wrote:> From: Thierry Reding <treding at nvidia.com> > > Hi Ben, > > here's a revised subset of the patches I had sent out a couple of weeks > ago. I've reworked the BAR2 accesses in the way that you had suggested, > which at least for GP10B turned out to be fairly trivial to do. I have > not looked in detail at this for GV11B yet, but a cursory look showed > that BAR2 is accessed in more places, so the equivalent for GV11B might > be a bit more involved. > > Other than that, not a lot has changed since then. I've added a couple > of precursory patches to add IOMMU helper dummies for the case where > IOMMU is disabled (as suggested by Ben Dooks). > > Joerg, it'd be great if you could give an Acked-by on those two patches > so that Ben can pick them both up into the Nouveau tree. Alternatively I > can put them both into a stable branch and send a pull request to both > of you. Or yet another alternative would be for Joerg to apply them now > and Ben to wait for v5.5-rc1 until he picks up the rest. All of those > work for me.Hi Joerg, Ben, do you guys have any further comments on this series? I've got an updated patch to silence the warning that the kbuild robot flagged, so if there are no other comments I can send a final v3 of the series. Thierry -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 833 bytes Desc: not available URL: <https://lists.freedesktop.org/archives/nouveau/attachments/20191118/28a1cf83/attachment-0001.sig>
Ben Skeggs
2019-Nov-20 06:11 UTC
[Nouveau] [PATCH v2 0/9] drm/nouveau: Various fixes for GP10B
On Mon, Nov 18, 2019 at 11:45 PM Thierry Reding <thierry.reding at gmail.com> wrote:> > On Sat, Nov 02, 2019 at 06:56:28PM +0100, Thierry Reding wrote: > > From: Thierry Reding <treding at nvidia.com> > > > > Hi Ben, > > > > here's a revised subset of the patches I had sent out a couple of weeks > > ago. I've reworked the BAR2 accesses in the way that you had suggested, > > which at least for GP10B turned out to be fairly trivial to do. I have > > not looked in detail at this for GV11B yet, but a cursory look showed > > that BAR2 is accessed in more places, so the equivalent for GV11B might > > be a bit more involved. > > > > Other than that, not a lot has changed since then. I've added a couple > > of precursory patches to add IOMMU helper dummies for the case where > > IOMMU is disabled (as suggested by Ben Dooks). > > > > Joerg, it'd be great if you could give an Acked-by on those two patches > > so that Ben can pick them both up into the Nouveau tree. Alternatively I > > can put them both into a stable branch and send a pull request to both > > of you. Or yet another alternative would be for Joerg to apply them now > > and Ben to wait for v5.5-rc1 until he picks up the rest. All of those > > work for me. > > Hi Joerg, Ben, > > do you guys have any further comments on this series? I've got an > updated patch to silence the warning that the kbuild robot flagged, so > if there are no other comments I can send a final v3 of the series.I'm on leave at the moment. But the nouveau fixes look fine to me and I'm happy to pick them up once you send a v3, and allow Jeorg to apply the rest through his tree. Thanks, Ben.> > Thierry
Joerg Roedel
2019-Nov-29 11:20 UTC
[Nouveau] [PATCH v2 0/9] drm/nouveau: Various fixes for GP10B
On Sat, Nov 02, 2019 at 06:56:28PM +0100, Thierry Reding wrote:> Thierry Reding (9): > iommu: Document iommu_fwspec::flags field > iommu: Add dummy dev_iommu_fwspec_get() helperAcked-by: Joerg Roedel <jroedel at suse.de>
Possibly Parallel Threads
- [PATCH 00/14] iommu: Move iommu_fwspec out of 'struct device'
- [PATCH 00/15 v2] iommu: Move iommu_fwspec out of 'struct device'
- [PATCH v2 0/9] drm/nouveau: Various fixes for GP10B
- [PATCH v8 5/7] iommu: Add virtio-iommu driver
- [PATCH v2 17/33] iommu/arm-smmu: Convert to probe/release_device() call-backs