From patchwork Fri Jan 4 10:47:52 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 1020677 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-tegra-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="dkTDiFXT"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43WM2803Ntz9s7T for ; Fri, 4 Jan 2019 21:48:00 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726332AbfADKr6 (ORCPT ); Fri, 4 Jan 2019 05:47:58 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:52522 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725958AbfADKr6 (ORCPT ); Fri, 4 Jan 2019 05:47:58 -0500 Received: by mail-wm1-f66.google.com with SMTP id m1so756344wml.2; Fri, 04 Jan 2019 02:47:55 -0800 (PST) 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=8xpDAL9/YCh1qqkCTeD/Mgy8bX1iUucEHanYuvewn0w=; b=dkTDiFXTkneJgNyoG/Vj1rfPAjMDhfXwAe3cokQdhvJaSvCIp5z2hCW0v3qgylK7Tg 65ZzGmh9LCuxa/usRDslBQxeiVd0e8joe3FfmFjpYiAgpc33s9Rir9twlK0EJkFuheUp AnJXLhiF4qNlTYL6Njn58v89MQ+eY76ycvsieMVKhd5YfnvynUQbK7qoi4XuY8QVoXo/ kFiz7cjNEqpeBkefY/fYDtqa2Ykpjx3j6lw6OMh30d5giMyTX0enh7YkgeunLQ1SCZs9 /MNzphwsRSeKTRyfAHnI4qZZD34K3hBTVYTTUe5E35yV3aOI+ClkmFES7UZa4cRIdYXV Dedg== 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=8xpDAL9/YCh1qqkCTeD/Mgy8bX1iUucEHanYuvewn0w=; b=IBTEP6kDYMSt8jcSw8UXk58yL14X7H6EiLqeW34MLVtjC0WS/qlrbjieyHykr5K0bZ korRslWIDtSCODkAfTlz983IDyGOyVIX7GV7JnOiazSXfjl2b8BRtR555XWDz34m+ENa TrGbMvyMhOo959CcMYA1MFJjyCwdX5mz3FqYD8EAF1E+d8pi9Mgup22iUdmVoz0G5lRg f4GBdJ0BCGX5UQhp1Y6MX0/XFnff9s4uvJy9UikBbby22F4gpQr/SoJ31GCxn1PYnyyF d+QbnGKwLlop4nrJhbg0EWYlCe7LxXlb15nHZcLtUXS0tqNezWOV14OB353pCI9pma+q 3rrA== X-Gm-Message-State: AJcUukddkT+CyH7+pyjLYFoEAky7g2WFu4ws/kjd0+4ltQbYq/wwfw6E uzs5A+K/szFQfc7lt+KJG7g= X-Google-Smtp-Source: ALg8bN7kHOy0rtk4BhtbMkAar92/PRIlPuLEamvR1DVfKquT4XcprgBIDQ6TZFbJD42W6DsSOKXIkw== X-Received: by 2002:a1c:7706:: with SMTP id t6mr903236wmi.57.1546598875060; Fri, 04 Jan 2019 02:47:55 -0800 (PST) Received: from localhost (pD9E51040.dip0.t-ipconnect.de. [217.229.16.64]) by smtp.gmail.com with ESMTPSA id o5sm703510wmg.25.2019.01.04.02.47.54 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 04 Jan 2019 02:47:54 -0800 (PST) From: Thierry Reding To: Adrian Hunter , Ulf Hansson Cc: Jonathan Hunter , Sowjanya Komatineni , Krishna Reddy , linux-mmc@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/2] mmc: sdhci: Properly set DMA mask Date: Fri, 4 Jan 2019 11:47:52 +0100 Message-Id: <20190104104753.3383-1-thierry.reding@gmail.com> X-Mailer: git-send-email 2.19.1 MIME-Version: 1.0 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org From: Thierry Reding The implementation of sdhci_set_dma_mask() is conflating two things: on one hand it uses the SDHCI_USE_64_BIT_DMA flag to determine whether or not to use the 64-bit addressing capability of the controller and on the other hand it also uses that flag to set a DMA mask for the controller's parent device. However, a controller supporting 64-bit addressing doesn't mean that it needs to support addressing 64 bits of address range. It's perfectly acceptable to use 64-bit addressing for a 32-bit address range or even smaller, even if that makes little sense, considering the extra overhead of the 64-bit addressing descriptors. But it is fairly common for hardware to support somewhere between 32 and 64 bits of address range. Tegra124 and Tegra210, for example, support 34 bits and the newer Tegra186 and Tegra194 support 40 bits. The latter can also use an IOMMU for address translation, which has an input address range of 48 bits. This causes problems with the current algorithm in the SDHCI core for choosing the DMA mask. If the DMA mask is set to 64 bits, the DMA memory allocations can (and usually do because the allocator starts from the top) end up beyond the 40 bit boundary addressable by the SDHCI controller, causing IOMMU faults. For Tegra specifically this problem is currently worked around by setting the SDHCI_QUIRK2_BROKEN_64_BIT_DMA quirk. This causes the DMA mask to always be set to 32 bits and therefore all allocations will fit within the range addressable by the controller. This commit reworks the code in sdhci_set_dma_mask() to fix the above issue. The rationale behind this change is that the SDHCI controller driver should be the authoritative source of the DMA mask setting. The SDHCI core has no way of knowing what the individual SDHCI controllers are capable of. So instead of overriding the DMA mask depending on whether or not 64-bit addressing mode is used, the DMA mask is only modified if absolutely necessary. On one hand, if the controller can only address 32 bits of memory or less, we disable use of 64-bit addressing mode because it is not needed. On the other hand, we also want to make sure that if we don't support 64-bit addressing mode, such as in the case where the BROKEN_64_BIT_DMA quirk is set, we do restrict the DMA mask to fit the capabilities. The latter is an inconsistency by the driver, so we warn about it to make sure it will be addressed in the driver. Signed-off-by: Thierry Reding --- drivers/mmc/host/sdhci.c | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c index 7c6c93e85b7e..01f81e96be23 100644 --- a/drivers/mmc/host/sdhci.c +++ b/drivers/mmc/host/sdhci.c @@ -3499,27 +3499,35 @@ static int sdhci_set_dma_mask(struct sdhci_host *host) { struct mmc_host *mmc = host->mmc; struct device *dev = mmc_dev(mmc); - int ret = -EINVAL; + u64 dma_mask = dma_get_mask(dev); + u64 dma32 = DMA_BIT_MASK(32); + int ret = 0; if (host->quirks2 & SDHCI_QUIRK2_BROKEN_64_BIT_DMA) host->flags &= ~SDHCI_USE_64_BIT_DMA; - /* Try 64-bit mask if hardware is capable of it */ - if (host->flags & SDHCI_USE_64_BIT_DMA) { - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)); - if (ret) { - pr_warn("%s: Failed to set 64-bit DMA mask.\n", - mmc_hostname(mmc)); - host->flags &= ~SDHCI_USE_64_BIT_DMA; - } + /* + * Hardware that can't address more than the 32-bit address range does + * not need to use 64-bit addressing mode, even if it supports it. + */ + if ((host->flags & SDHCI_USE_64_BIT_DMA) && (dma_mask <= dma32)) { + pr_debug("%s: controller needs addresses <= 32-bits\n", + mmc_hostname(mmc)); + host->flags &= ~SDHCI_USE_64_BIT_DMA; } - /* 32-bit mask as default & fallback */ - if (ret) { - ret = dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32)); + /* + * If the hardware doesn't support 64-bit addressing, make sure to + * restrict the DMA mask so we don't get buffers allocated beyond the + * 32-bit boundary. + */ + if (!(host->flags & SDHCI_USE_64_BIT_DMA) && (dma_mask > dma32)) { + WARN(1, "64-bit DMA not supported, DMA mask %llx\n", dma_mask); + + ret = dma_set_mask_and_coherent(dev, dma32); if (ret) - pr_warn("%s: Failed to set 32-bit DMA mask.\n", - mmc_hostname(mmc)); + pr_warn("%s: failed to set 32-bit DMA mask: %d\n", + mmc_hostname(mmc), ret); } return ret; From patchwork Fri Jan 4 10:47:53 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Thierry Reding X-Patchwork-Id: 1020678 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-tegra-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="I3gDNu0J"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43WM2H5k9wz9s9G for ; Fri, 4 Jan 2019 21:48:07 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727005AbfADKsA (ORCPT ); Fri, 4 Jan 2019 05:48:00 -0500 Received: from mail-wm1-f66.google.com ([209.85.128.66]:56219 "EHLO mail-wm1-f66.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726028AbfADKr7 (ORCPT ); Fri, 4 Jan 2019 05:47:59 -0500 Received: by mail-wm1-f66.google.com with SMTP id y139so743904wmc.5; Fri, 04 Jan 2019 02:47:57 -0800 (PST) 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=gmIKRkHjPNoHY17G01o1jvoarrqTR1poeaUem5PMPwA=; b=I3gDNu0J9giu2WdEDLJMwTUUZgvxOh8sHkZ4Sm2u5nB43vJFz80+z9MVSs2mxf2OM7 rUZzyhif+FhOZMXuqDs453H5hnCw7IBDiQIhTq6213MxrGCzvZl19mtwI0p9B3we8UKJ CpVg9rFE6rOQRF2h/M5NmrdoYwVEI4ppzdZFqaoINRdOwCpiS8kWXXWiExv0E+7nMa2O biUap0T1GRLJ3+NyI3fQwQZNKuKRUXAG77KLO9FvNZy9zoaFiHcNR2NLBpNa2KMhi/Oe LDwB8VycpGuzhTn3NzKjP4eKrTirnWF4Nf1VO4Nqdy3O++lvbz36B+ALwn8qNqqEQewd lHgA== 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=gmIKRkHjPNoHY17G01o1jvoarrqTR1poeaUem5PMPwA=; b=CJoVNJ/28/1nM3O6KQK0Nc19jkwSKzcncY3o6TZ3wk0P9EqQ4Wd9TsRv1vV57TrL9/ 3y/n8RFlefvTTWrj332WK4EHmLrZ36kbGcKQeAlOvNyB8ctasjbIX1M6irXMqrIB8jhc uV7Oy7wc1z1kdVGZ3+Zjd/ohry0YcBy3MvvNs9iFysN7fbm3v6RmKTcfpxaZbs8S690R 39JOV38u1gSQ3FCjc0xTbNW3CuqUvh3Z7v+afuWthzppOkbftkLGJ8g5FRaNNzvtTJLV BaJv8Ca5/CixNT/Y6Xw+e5HsugLjxyqecvBYBgbYtKb8j05nu3dTu10uCV9PrsPv8cbp 8LxQ== X-Gm-Message-State: AJcUukcFSvj9vwcqh5FD8FxIoe/4eBiKsUjxpu5dOq1p6DfJ6hWaT+E4 hRyZ2ea3bIgpzp050YFF+Xg= X-Google-Smtp-Source: ALg8bN6msobFyqiI06na9J1Rj8PxG5Wq5+FFcA7jE0KazXeewLKWHuj+sSSMBEFlb4fgllqK+TlkwQ== X-Received: by 2002:a1c:2856:: with SMTP id o83mr1026268wmo.45.1546598876563; Fri, 04 Jan 2019 02:47:56 -0800 (PST) Received: from localhost (pD9E51040.dip0.t-ipconnect.de. [217.229.16.64]) by smtp.gmail.com with ESMTPSA id c15sm648660wml.27.2019.01.04.02.47.55 (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Fri, 04 Jan 2019 02:47:55 -0800 (PST) From: Thierry Reding To: Adrian Hunter , Ulf Hansson Cc: Jonathan Hunter , Sowjanya Komatineni , Krishna Reddy , linux-mmc@vger.kernel.org, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 2/2] mmc: sdhci: tegra: Set DMA mask depending on generation Date: Fri, 4 Jan 2019 11:47:53 +0100 Message-Id: <20190104104753.3383-2-thierry.reding@gmail.com> X-Mailer: git-send-email 2.19.1 In-Reply-To: <20190104104753.3383-1-thierry.reding@gmail.com> References: <20190104104753.3383-1-thierry.reding@gmail.com> MIME-Version: 1.0 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org From: Thierry Reding The SDHCI controller found in early Tegra SoCs (from Tegra20 through Tegra114) used an AHB interface to the memory controller, which allowed only 32 bits of memory to be addressed. Starting with Tegra124, this limitation was removed by making the SDHCI controllers native MCCIF clients, which means that they got increased bandwidth and better arbitration to the memory controller as well as an address range extended to 40 bits, out of which only 34 were actually used (bits 34-39 are tied to 0 in the controller). Starting with Tegra186, all of the 40 bits can be used. Signed-off-by: Thierry Reding --- drivers/mmc/host/sdhci-tegra.c | 35 +++++++++++++++------------------- 1 file changed, 15 insertions(+), 20 deletions(-) diff --git a/drivers/mmc/host/sdhci-tegra.c b/drivers/mmc/host/sdhci-tegra.c index e6ace31e2a41..c861e0ee7ef2 100644 --- a/drivers/mmc/host/sdhci-tegra.c +++ b/drivers/mmc/host/sdhci-tegra.c @@ -13,6 +13,7 @@ */ #include +#include #include #include #include @@ -92,6 +93,7 @@ struct sdhci_tegra_soc_data { const struct sdhci_pltfm_data *pdata; u32 nvquirks; + u64 dma_mask; }; /* Magic pull up and pull down pad calibration offsets */ @@ -862,6 +864,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra20 = { .pdata = &sdhci_tegra20_pdata, .nvquirks = NVQUIRK_FORCE_SDHCI_SPEC_200 | NVQUIRK_ENABLE_BLOCK_GAP_DET, + .dma_mask = DMA_BIT_MASK(32), }; static const struct sdhci_pltfm_data sdhci_tegra30_pdata = { @@ -890,6 +893,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra30 = { NVQUIRK_ENABLE_SDR50 | NVQUIRK_ENABLE_SDR104 | NVQUIRK_HAS_PADCALIB, + .dma_mask = DMA_BIT_MASK(32), }; static const struct sdhci_ops tegra114_sdhci_ops = { @@ -919,6 +923,7 @@ static const struct sdhci_pltfm_data sdhci_tegra114_pdata = { static const struct sdhci_tegra_soc_data soc_data_tegra114 = { .pdata = &sdhci_tegra114_pdata, + .dma_mask = DMA_BIT_MASK(32), }; static const struct sdhci_pltfm_data sdhci_tegra124_pdata = { @@ -928,22 +933,13 @@ static const struct sdhci_pltfm_data sdhci_tegra124_pdata = { SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | - /* - * The TRM states that the SD/MMC controller found on - * Tegra124 can address 34 bits (the maximum supported by - * the Tegra memory controller), but tests show that DMA - * to or from above 4 GiB doesn't work. This is possibly - * caused by missing programming, though it's not obvious - * what sequence is required. Mark 64-bit DMA broken for - * now to fix this for existing users (e.g. Nyan boards). - */ - SDHCI_QUIRK2_BROKEN_64_BIT_DMA, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, .ops = &tegra114_sdhci_ops, }; static const struct sdhci_tegra_soc_data soc_data_tegra124 = { .pdata = &sdhci_tegra124_pdata, + .dma_mask = DMA_BIT_MASK(34), }; static const struct sdhci_ops tegra210_sdhci_ops = { @@ -977,6 +973,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra210 = { NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | NVQUIRK_ENABLE_SDR50 | NVQUIRK_ENABLE_SDR104, + .dma_mask = DMA_BIT_MASK(34), }; static const struct sdhci_ops tegra186_sdhci_ops = { @@ -998,15 +995,7 @@ static const struct sdhci_pltfm_data sdhci_tegra186_pdata = { SDHCI_QUIRK_NO_HISPD_BIT | SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC | SDHCI_QUIRK_CAP_CLOCK_BASE_BROKEN, - .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN | - /* SDHCI controllers on Tegra186 support 40-bit addressing. - * IOVA addresses are 48-bit wide on Tegra186. - * With 64-bit dma mask used for SDHCI, accesses can - * be broken. Disable 64-bit dma, which would fall back - * to 32-bit dma mask. Ideally 40-bit dma mask would work, - * But it is not supported as of now. - */ - SDHCI_QUIRK2_BROKEN_64_BIT_DMA, + .quirks2 = SDHCI_QUIRK2_PRESET_VALUE_BROKEN, .ops = &tegra186_sdhci_ops, }; @@ -1017,6 +1006,7 @@ static const struct sdhci_tegra_soc_data soc_data_tegra186 = { NVQUIRK_DIS_CARD_CLK_CONFIG_TAP | NVQUIRK_ENABLE_SDR50 | NVQUIRK_ENABLE_SDR104, + .dma_mask = DMA_BIT_MASK(40), }; static const struct of_device_id sdhci_tegra_dt_match[] = { @@ -1045,6 +1035,11 @@ static int sdhci_tegra_probe(struct platform_device *pdev) return -EINVAL; soc_data = match->data; + rc = dma_set_mask_and_coherent(&pdev->dev, soc_data->dma_mask); + if (rc) + dev_warn(&pdev->dev, "failed to set DMA mask %llx: %d\n", + soc_data->dma_mask, rc); + host = sdhci_pltfm_init(pdev, soc_data->pdata, sizeof(*tegra_host)); if (IS_ERR(host)) return PTR_ERR(host);