From patchwork Thu Jul 7 16:59:28 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ard Biesheuvel X-Patchwork-Id: 71604 Delivered-To: patch@linaro.org Received: by 10.140.28.4 with SMTP id 4csp1918qgy; Thu, 7 Jul 2016 09:59:54 -0700 (PDT) X-Received: by 10.66.20.166 with SMTP id o6mr2004625pae.96.1467910793966; Thu, 07 Jul 2016 09:59:53 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id vq1si5654880pab.242.2016.07.07.09.59.53; Thu, 07 Jul 2016 09:59:53 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752284AbcGGQ7w (ORCPT + 30 others); Thu, 7 Jul 2016 12:59:52 -0400 Received: from mail-wm0-f44.google.com ([74.125.82.44]:37418 "EHLO mail-wm0-f44.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751150AbcGGQ7n (ORCPT ); Thu, 7 Jul 2016 12:59:43 -0400 Received: by mail-wm0-f44.google.com with SMTP id a66so39605178wme.0 for ; Thu, 07 Jul 2016 09:59:43 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id; bh=Lr3xUWOw/hbfeQcRvDH4X5d+8d4O8oURUccWRdLCC/k=; b=XJ3TZqQ+iMynwtUSAWinFI1KOLdtjCtulCZU0TKDK5wo/r3YlepT8/lafhJUVzm1ep xdX98VikzVGbplCTNeJOtzSyQkFsj69rKswd5GqYzowax2YuJ+546T/RsmRIIH4lvZnm IiRzlDxrl5rQRqWD771+lyOe9fIM6JY+haZDc= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=Lr3xUWOw/hbfeQcRvDH4X5d+8d4O8oURUccWRdLCC/k=; b=Aguk2wZ4p9ZX2Jf7sXvOSuiijohN8Ejhhct/Lsv4vwzI84FZ6CjliHS5sOet/hajOp Xb7Cr+NTM0FrkMXnMixwXTFl6I0onl3u0O7BM714xBNbypRrDlF3BPr40CH0aUNP0jeW sBUdSyKfkGtZKN3Z2fc9qXIyTY0bzDqke7ttnTFrzADTg5wdB6bk1NLCif615t/vGG93 Lavc17Yc+mULFLo0tG0zoJdiJTo8mjlOPsdJdYDiGDxb/ubI+lN9INXNi2qljYuecGc8 oNby+Qi94drB1Of7dZ0JoyGRUOYyURs2Mlat42iBGd87HYxv7xio/olwo/K/eQr82UxM a/gA== X-Gm-Message-State: ALyK8tLfEeuh1zdfipirUBZYskTIJ3vf7KbZai/6x2cEnqfTsbUH8KmhWJg+TdR+g0Cz63Gp X-Received: by 10.28.131.200 with SMTP id f191mr4008986wmd.80.1467910782180; Thu, 07 Jul 2016 09:59:42 -0700 (PDT) Received: from localhost.localdomain ([188.203.148.129]) by smtp.gmail.com with ESMTPSA id el4sm952050wjd.23.2016.07.07.09.59.37 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 07 Jul 2016 09:59:41 -0700 (PDT) From: Ard Biesheuvel To: nouveau@lists.freedesktop.org, dri-devel@lists.freedesktop.org, bskeggs@redhat.com Cc: airlied@linux.ie, linux-kernel@vger.kernel.org, Ard Biesheuvel Subject: [PATCH v3] drm/nouveau/fb/nv50: set DMA mask before mapping scratch page Date: Thu, 7 Jul 2016 18:59:28 +0200 Message-Id: <1467910768-2643-1-git-send-email-ard.biesheuvel@linaro.org> X-Mailer: git-send-email 2.7.4 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org The 100c08 scratch page is mapped using dma_map_page() before the TTM layer has had a chance to set the DMA mask. This means we are still running with the default of 32 when this code executes, and this causes problems for platforms with no memory below 4 GB (such as AMD Seattle) So move the dma_map_page() to the .init hook, and set the streaming DMA mask based on the MMU subdev parameters before performing the call. Signed-off-by: Ard Biesheuvel --- I am sure there is a much better way to address this, but this fixes the problem I get on AMD Seattle with a GeForce 210 PCIe card: nouveau 0000:02:00.0: enabling device (0000 -> 0003) nouveau 0000:02:00.0: NVIDIA GT218 (0a8280b1) nouveau 0000:02:00.0: bios: version 70.18.a6.00.00 nouveau 0000:02:00.0: fb ctor failed, -14 nouveau: probe of 0000:02:00.0 failed with error -14 v2: replace incorrect comparison of dma_addr_t type var against NULL v3: rework code to get rid of DMA_ERROR_CODE references, which is not defined on all architectures drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c | 40 ++++++++++++++------ 1 file changed, 29 insertions(+), 11 deletions(-) -- 2.7.4 diff --git a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c index 1b5fb02eab2a..f713cb3fe56c 100644 --- a/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/nvkm/subdev/fb/nv50.c @@ -216,11 +216,33 @@ nv50_fb_init(struct nvkm_fb *base) struct nv50_fb *fb = nv50_fb(base); struct nvkm_device *device = fb->base.subdev.device; + if (!fb->r100c08) { + /* We are calling the DMA api way before the TTM layer sets the + * DMA mask based on the MMU subdev parameters. This means we + * are using the default DMA mask of 32, which may cause + * problems on systems with no RAM below the 4 GB mark. So set + * the streaming DMA mask here as well. + */ + dma_addr_t addr; + + dma_set_mask(device->dev, DMA_BIT_MASK(device->mmu->dma_bits)); + + addr = dma_map_page(device->dev, fb->r100c08_page, 0, PAGE_SIZE, + DMA_BIDIRECTIONAL); + if (!dma_mapping_error(device->dev, addr)) { + fb->r100c08 = addr; + } else { + nvkm_warn(&fb->base.subdev, + "dma_map_page() failed on 100c08 page\n"); + } + } + /* Not a clue what this is exactly. Without pointing it at a * scratch page, VRAM->GART blits with M2MF (as in DDX DFS) * cause IOMMU "read from address 0" errors (rh#561267) */ - nvkm_wr32(device, 0x100c08, fb->r100c08 >> 8); + if (fb->r100c08) + nvkm_wr32(device, 0x100c08, fb->r100c08 >> 8); /* This is needed to get meaningful information from 100c90 * on traps. No idea what these values mean exactly. */ @@ -233,11 +255,11 @@ nv50_fb_dtor(struct nvkm_fb *base) struct nv50_fb *fb = nv50_fb(base); struct nvkm_device *device = fb->base.subdev.device; - if (fb->r100c08_page) { + if (fb->r100c08) dma_unmap_page(device->dev, fb->r100c08, PAGE_SIZE, DMA_BIDIRECTIONAL); - __free_page(fb->r100c08_page); - } + + __free_page(fb->r100c08_page); return fb; } @@ -264,13 +286,9 @@ nv50_fb_new_(const struct nv50_fb_func *func, struct nvkm_device *device, *pfb = &fb->base; fb->r100c08_page = alloc_page(GFP_KERNEL | __GFP_ZERO); - if (fb->r100c08_page) { - fb->r100c08 = dma_map_page(device->dev, fb->r100c08_page, 0, - PAGE_SIZE, DMA_BIDIRECTIONAL); - if (dma_mapping_error(device->dev, fb->r100c08)) - return -EFAULT; - } else { - nvkm_warn(&fb->base.subdev, "failed 100c08 page alloc\n"); + if (!fb->r100c08_page) { + nvkm_error(&fb->base.subdev, "failed 100c08 page alloc\n"); + return -ENOMEM; } return 0;