Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp3903666ybz; Mon, 4 May 2020 11:51:00 -0700 (PDT) X-Google-Smtp-Source: APiQypIoc83XQQ69RIgATAVxjkyG78BeJn82krnCSWAqcjJRf3w0t3R0aQp3etwESQCvWlaOySvg X-Received: by 2002:aa7:ce17:: with SMTP id d23mr7096156edv.89.1588618260263; Mon, 04 May 2020 11:51:00 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1588618260; cv=none; d=google.com; s=arc-20160816; b=diKwL2wap+Sctq9zHrMwOVL9kMWwSu5xcqJiKgL3WnZqBTqpLAj9ZnxQvyt8y0SbBA qrpLXnpvLz+maprkwz94tZYc01ntgwpLL0M23Xhr8SYKcvhUsPFfEd2ci69OuRxGt2GR elrfc9pOk7mhILbJ8nYaKMprbdXNPLejK0EMbvZ1OtL39ksbYNtgL8iBeayY7kE+y3YE v3TNB3q3WLqDXXCj3Pjs2CYE6tagqlP/3N9KrrHJnQX9/LA9IDiUsGI4TB0GWR/5IcCC iihVTB8w/VOpg0JMUdd4XegRNtXxvx1LnPyPXMKHHyhyVGT0tX7i8jCUsS09blSmVnSK hq/A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=+uxv+I2/FTJBYBAjECwblv3RDhMku6JWKomQ4Y91nmM=; b=HWdwWcwlArids6qwbMOPYAq7iI64iEtFO7VaoHbOvNt/RYoRSIZmAG2wh2ljmXP9iw 3SYTWFeXFBCaJCvYE/qZ938wKWzIBVg9Xn7Fjej+H7KpgtUaasX6/u60wp7KkhWvk7U+ j3a/eLc0sM5rSZY8q2P2Tb/mq0UoLMXZ1mzRlSrFYr4UpeXpWHpA7em5ov2iD4wAUj9E LAZzIOOpMsg5ow6HZZ3+TkVhTHfmGXq9ZLfiF62Tnno+Mr2pJDrsx+rCpkpRgWVKOL37 9VZFsS0uOuts4eA2bOGgAzIxUs3IlVmaYHgbvzbmS4BgdrArPFbcdGrdyGbvApMcC3GL pWog== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YZxhexqn; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id o20si7367431edr.279.2020.05.04.11.50.36; Mon, 04 May 2020 11:51:00 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=YZxhexqn; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731428AbgEDSPg (ORCPT + 99 others); Mon, 4 May 2020 14:15:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56806 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1730710AbgEDR7Q (ORCPT ); Mon, 4 May 2020 13:59:16 -0400 Received: from mail-qv1-xf44.google.com (mail-qv1-xf44.google.com [IPv6:2607:f8b0:4864:20::f44]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 95158C03C1A8 for ; Mon, 4 May 2020 10:59:14 -0700 (PDT) Received: by mail-qv1-xf44.google.com with SMTP id h6so88447qvz.8 for ; Mon, 04 May 2020 10:59:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=+uxv+I2/FTJBYBAjECwblv3RDhMku6JWKomQ4Y91nmM=; b=YZxhexqnPFjsUEno3wMFzz4uVv+T4dxyAFeY8zRX7vCaz6sBXdDQUCmQ4q4+Zdr8Fs nJ+u+TO9wxbFzHeqT5YpvrhrM6gTVYVpq2+ew0kco14IskiOwmTxKMELMjjJrhMKaRCZ oTbnfu5g+N5cyKttHJ7A6OnutV1gpDOofKj+eS3sespsP96LK32wdd3O/24AHvsfQLHb S8/V4CCeqEY3hKAUn43D+ZozDTjNEXTbBeTa5e4Bo1e4PkS6rrc+1uRx+foinVGa8neg 19EW+9gD3O/wQ3ODKFRpodOzmDSOsYILowzUJ9XvRIoygeMH66g9JNnCKk7ZDAIgXvbg 1Y3g== 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=+uxv+I2/FTJBYBAjECwblv3RDhMku6JWKomQ4Y91nmM=; b=sxrxpbVbOFe+6w7L/O2+7YVCxZ+h9647D/4fN9djV2hPkf0osf5HNey3GXCIyQ/NkM DPDrFzdzE5NuFEp/Au0xfwaJaZoyvPuDI61O6GIbaAxPlRdw4FdApKBU1Ll5fGHs/9HM 3MfwMIEeof3MCT95aCfIxnS6KLMxXHTOla2DlVE6u9z2tHPd105hYaIZ3PAYmltF4zL/ EYWTCcwFb678PK+zhp3ZTHVr1hL7TCuF8NCW160mpEmzVXPKrXM47v4pXIW11nxg8OqY eEBFnpKWcbzyOtJVtO3DcsuoKJH/mKcAGMaUv8nJ7q5i1Q+fotQ9awuPhVb2lFEDRcvU +jXA== X-Gm-Message-State: AGi0Pua+9XOXEy3r7NIatIFvksF8LEg6oHwILkd4MhOzEaoSrvioy5wD LQLVrPhDDkSoToqQgaLo41YMAw== X-Received: by 2002:a0c:ba17:: with SMTP id w23mr319531qvf.176.1588615153711; Mon, 04 May 2020 10:59:13 -0700 (PDT) Received: from beast.localdomain (c-73-185-129-58.hsd1.mn.comcast.net. [73.185.129.58]) by smtp.gmail.com with ESMTPSA id h19sm11271088qtk.78.2020.05.04.10.59.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 May 2020 10:59:13 -0700 (PDT) From: Alex Elder To: davem@davemloft.net Cc: evgreen@chromium.org, subashab@codeaurora.org, cpratapa@codeaurora.org, bjorn.andersson@linaro.org, agross@kernel.org, robh+dt@kernel.org, netdev@vger.kernel.org, devicetree@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v2 4/4] net: ipa: define SMEM memory region for IPA Date: Mon, 4 May 2020 12:58:59 -0500 Message-Id: <20200504175859.22606-5-elder@linaro.org> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20200504175859.22606-1-elder@linaro.org> References: <20200504175859.22606-1-elder@linaro.org> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Arrange to use an item from SMEM memory for IPA. SMEM item number 497 is designated to be used by the IPA. Specify the item ID and size of the region in platform configuration data. Allocate and get a pointer to this region from ipa_mem_init(). The memory must be mapped for access through an SMMU. Signed-off-by: Alex Elder --- drivers/net/ipa/ipa.h | 5 ++ drivers/net/ipa/ipa_data-sc7180.c | 2 + drivers/net/ipa/ipa_data-sdm845.c | 2 + drivers/net/ipa/ipa_data.h | 4 ++ drivers/net/ipa/ipa_mem.c | 116 ++++++++++++++++++++++++++++++ 5 files changed, 129 insertions(+) diff --git a/drivers/net/ipa/ipa.h b/drivers/net/ipa/ipa.h index 32f6dfafdb05..b10a85392952 100644 --- a/drivers/net/ipa/ipa.h +++ b/drivers/net/ipa/ipa.h @@ -49,6 +49,8 @@ struct ipa_interrupt; * @mem: Array of IPA-local memory region descriptors * @imem_iova: I/O virtual address of IPA region in IMEM * @imem_size; Size of IMEM region + * @smem_iova: I/O virtual address of IPA region in SMEM + * @smem_size; Size of SMEM region * @zero_addr: DMA address of preallocated zero-filled memory * @zero_virt: Virtual address of preallocated zero-filled memory * @zero_size: Size (bytes) of preallocated zero-filled memory @@ -93,6 +95,9 @@ struct ipa { unsigned long imem_iova; size_t imem_size; + unsigned long smem_iova; + size_t smem_size; + dma_addr_t zero_addr; void *zero_virt; size_t zero_size; diff --git a/drivers/net/ipa/ipa_data-sc7180.c b/drivers/net/ipa/ipa_data-sc7180.c index e9007d151c68..43faa35ae726 100644 --- a/drivers/net/ipa/ipa_data-sc7180.c +++ b/drivers/net/ipa/ipa_data-sc7180.c @@ -301,6 +301,8 @@ static struct ipa_mem_data ipa_mem_data = { .local = ipa_mem_local_data, .imem_addr = 0x146a8000, .imem_size = 0x00002000, + .smem_id = 497, + .smem_size = 0x00002000, }; /* Configuration data for the SC7180 SoC. */ diff --git a/drivers/net/ipa/ipa_data-sdm845.c b/drivers/net/ipa/ipa_data-sdm845.c index c0e207085550..f7ba85717edf 100644 --- a/drivers/net/ipa/ipa_data-sdm845.c +++ b/drivers/net/ipa/ipa_data-sdm845.c @@ -323,6 +323,8 @@ static struct ipa_mem_data ipa_mem_data = { .local = ipa_mem_local_data, .imem_addr = 0x146bd000, .imem_size = 0x00002000, + .smem_id = 497, + .smem_size = 0x00002000, }; /* Configuration data for the SDM845 SoC. */ diff --git a/drivers/net/ipa/ipa_data.h b/drivers/net/ipa/ipa_data.h index 69957af56ccd..16dfd74717b1 100644 --- a/drivers/net/ipa/ipa_data.h +++ b/drivers/net/ipa/ipa_data.h @@ -250,12 +250,16 @@ struct ipa_resource_data { * @local: array of IPA-local memory region descriptors * @imem_addr: physical address of IPA region within IMEM * @imem_size: size in bytes of IPA IMEM region + * @smem_id: item identifier for IPA region within SMEM memory + * @imem_size: size in bytes of the IPA SMEM region */ struct ipa_mem_data { u32 local_count; const struct ipa_mem *local; u32 imem_addr; u32 imem_size; + u32 smem_id; + u32 smem_size; }; /** diff --git a/drivers/net/ipa/ipa_mem.c b/drivers/net/ipa/ipa_mem.c index 3c0916597fe1..aa8f6b0f3d50 100644 --- a/drivers/net/ipa/ipa_mem.c +++ b/drivers/net/ipa/ipa_mem.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "ipa.h" #include "ipa_reg.h" @@ -23,6 +24,9 @@ /* "Canary" value placed between memory regions to detect overflow */ #define IPA_MEM_CANARY_VAL cpu_to_le32(0xdeadbeef) +/* SMEM host id representing the modem. */ +#define QCOM_SMEM_HOST_MODEM 1 + /* Add an immediate command to a transaction that zeroes a memory region */ static void ipa_mem_zero_region_add(struct gsi_trans *trans, const struct ipa_mem *mem) @@ -340,6 +344,111 @@ static void ipa_imem_exit(struct ipa *ipa) ipa->imem_iova = 0; } +/** + * ipa_smem_init() - Initialize SMEM memory used by the IPA + * @ipa: IPA pointer + * @item: Item ID of SMEM memory + * @size: Size (bytes) of SMEM memory region + * + * SMEM is a managed block of shared DRAM, from which numbered "items" + * can be allocated. One item is designated for use by the IPA. + * + * The modem accesses SMEM memory directly, but the IPA accesses it + * via the IOMMU, using the AP's credentials. + * + * If size provided is non-zero, we allocate it and map it for + * access through the IOMMU. + * + * Note: @size and the item address are is not guaranteed to be page-aligned. + */ +static int ipa_smem_init(struct ipa *ipa, u32 item, size_t size) +{ + struct device *dev = &ipa->pdev->dev; + struct iommu_domain *domain; + unsigned long iova; + phys_addr_t phys; + phys_addr_t addr; + size_t actual; + void *virt; + int ret; + + if (!size) + return 0; /* SMEM memory not used */ + + /* SMEM is memory shared between the AP and another system entity + * (in this case, the modem). An allocation from SMEM is persistent + * until the AP reboots; there is no way to free an allocated SMEM + * region. Allocation only reserves the space; to use it you need + * to "get" a pointer it (this implies no reference counting). + * The item might have already been allocated, in which case we + * use it unless the size isn't what we expect. + */ + ret = qcom_smem_alloc(QCOM_SMEM_HOST_MODEM, item, size); + if (ret && ret != -EEXIST) { + dev_err(dev, "error %d allocating size %zu SMEM item %u\n", + ret, size, item); + return ret; + } + + /* Now get the address of the SMEM memory region */ + virt = qcom_smem_get(QCOM_SMEM_HOST_MODEM, item, &actual); + if (IS_ERR(virt)) { + ret = PTR_ERR(virt); + dev_err(dev, "error %d getting SMEM item %u\n", ret, item); + return ret; + } + + /* In case the region was already allocated, verify the size */ + if (ret && actual != size) { + dev_err(dev, "SMEM item %u has size %zu, expected %zu\n", + item, actual, size); + return -EINVAL; + } + + domain = iommu_get_domain_for_dev(dev); + if (!domain) { + dev_err(dev, "no IOMMU domain found for SMEM\n"); + return -EINVAL; + } + + /* Align the address down and the size up to a page boundary */ + addr = qcom_smem_virt_to_phys(virt) & PAGE_MASK; + phys = addr & PAGE_MASK; + size = PAGE_ALIGN(size + addr - phys); + iova = phys; /* We just want a direct mapping */ + + ret = iommu_map(domain, iova, phys, size, IOMMU_READ | IOMMU_WRITE); + if (ret) + return ret; + + ipa->smem_iova = iova; + ipa->smem_size = size; + + return 0; +} + +static void ipa_smem_exit(struct ipa *ipa) +{ + struct device *dev = &ipa->pdev->dev; + struct iommu_domain *domain; + + domain = iommu_get_domain_for_dev(dev); + if (domain) { + size_t size; + + size = iommu_unmap(domain, ipa->smem_iova, ipa->smem_size); + if (size != ipa->smem_size) + dev_warn(dev, "unmapped %zu SMEM bytes, expected %lu\n", + size, ipa->smem_size); + + } else { + dev_err(dev, "couldn't get IPA IOMMU domain for SMEM\n"); + } + + ipa->smem_size = 0; + ipa->smem_iova = 0; +} + /* Perform memory region-related initialization */ int ipa_mem_init(struct ipa *ipa, const struct ipa_mem_data *mem_data) { @@ -383,8 +492,14 @@ int ipa_mem_init(struct ipa *ipa, const struct ipa_mem_data *mem_data) if (ret) goto err_unmap; + ret = ipa_smem_init(ipa, mem_data->smem_id, mem_data->smem_size); + if (ret) + goto err_imem_exit; + return 0; +err_imem_exit: + ipa_imem_exit(ipa); err_unmap: memunmap(ipa->mem_virt); @@ -394,6 +509,7 @@ int ipa_mem_init(struct ipa *ipa, const struct ipa_mem_data *mem_data) /* Inverse of ipa_mem_init() */ void ipa_mem_exit(struct ipa *ipa) { + ipa_smem_exit(ipa); ipa_imem_exit(ipa); memunmap(ipa->mem_virt); } -- 2.20.1