From patchwork Tue May 12 14:48:00 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Yousaf Kaukab X-Patchwork-Id: 1288493 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=vger.kernel.org (client-ip=23.128.96.18; helo=vger.kernel.org; envelope-from=linux-tegra-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=suse.de Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by ozlabs.org (Postfix) with ESMTP id 49M0zv3WQDz9sRY for ; Wed, 13 May 2020 00:48:43 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730214AbgELOsm (ORCPT ); Tue, 12 May 2020 10:48:42 -0400 Received: from mx2.suse.de ([195.135.220.15]:35628 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725929AbgELOsm (ORCPT ); Tue, 12 May 2020 10:48:42 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 24BEEAC58; Tue, 12 May 2020 14:48:43 +0000 (UTC) From: Mian Yousaf Kaukab To: swarren@wwwdotorg.org, robh+dt@kernel.org, robin.murphy@arm.com Cc: devicetree@vger.kernel.org, talho@nvidia.com, thierry.reding@gmail.com, jonathanh@nvidia.com, linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, afaerber@suse.de, arnd@arndb.de, gregkh@linuxfoundation.org, Mian Yousaf Kaukab Subject: [PATCH 1/4] misc: sram: add support for remapping reserved regions only Date: Tue, 12 May 2020 16:48:00 +0200 Message-Id: <20200512144803.24344-1-ykaukab@suse.de> X-Mailer: git-send-email 2.25.0 MIME-Version: 1.0 Sender: linux-tegra-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-tegra@vger.kernel.org Some SRAM kernel users may be interested in SRAM’s reserved regions only, though a bigger SRAM is available on the platform. Add an optional flag 'reserved-only' which allows to ioremap reserved regions only. Rest of SRAM is not remapped. ioremap type is selected depending upon no-memory-wc as usual. Signed-off-by: Mian Yousaf Kaukab --- *Tested only on Jetson TX2. Jetson AGX Xavier is untested.* drivers/misc/sram.c | 73 ++++++++++++++++++++++++++++++++++----------- drivers/misc/sram.h | 3 ++ 2 files changed, 58 insertions(+), 18 deletions(-) diff --git a/drivers/misc/sram.c b/drivers/misc/sram.c index 6c1a23cb3e8c..44e459f39e22 100644 --- a/drivers/misc/sram.c +++ b/drivers/misc/sram.c @@ -97,7 +97,7 @@ static int sram_add_partition(struct sram_dev *sram, struct sram_reserve *block, struct sram_partition *part = &sram->partition[sram->partitions]; mutex_init(&part->lock); - part->base = sram->virt_base + block->start; + part->base = block->virt_start; if (block->pool) { ret = sram_add_pool(sram, block, start, part); @@ -153,6 +153,25 @@ static int sram_reserve_cmp(void *priv, struct list_head *a, return ra->start - rb->start; } +static int sram_remap_resource(struct sram_dev *sram, + struct resource *res, void __iomem **virt) +{ + void __iomem *addr; + + if (sram->no_memory_wc) + addr = devm_ioremap_resource(sram->dev, res); + else + addr = devm_ioremap_resource_wc(sram->dev, res); + + if (IS_ERR(addr)) { + dev_err(sram->dev, "could not map SRAM region\n"); + return PTR_ERR(addr); + } + + *virt = addr; + return 0; +} + static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) { struct device_node *np = sram->dev->of_node, *child; @@ -239,6 +258,16 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) block->start, block->start + block->size); } + /* ioremap reserved block as whole sram is not remapped */ + if (sram->reserved_only) { + ret = sram_remap_resource(sram, &child_res, + &block->virt_start); + if (ret) + goto err_chunks; + } else { + block->virt_start = sram->virt_base + block->start; + } + block++; } child = NULL; @@ -282,8 +311,11 @@ static int sram_reserve_regions(struct sram_dev *sram, struct resource *res) } } - /* current start is in a reserved block, so continue after it */ - if (block->start == cur_start) { + /* + * Current start is in a reserved block, so continue after it. + * Or if only using reserved blocks + */ + if (block->start == cur_start || sram->reserved_only) { cur_start = block->start + block->size; continue; } @@ -342,6 +374,7 @@ static int sram_probe(struct platform_device *pdev) struct sram_dev *sram; int ret; int (*init_func)(void); + struct resource *res; sram = devm_kzalloc(&pdev->dev, sizeof(*sram), GFP_KERNEL); if (!sram) @@ -349,19 +382,22 @@ static int sram_probe(struct platform_device *pdev) sram->dev = &pdev->dev; - if (of_property_read_bool(pdev->dev.of_node, "no-memory-wc")) - sram->virt_base = devm_platform_ioremap_resource(pdev, 0); - else - sram->virt_base = devm_platform_ioremap_resource_wc(pdev, 0); - if (IS_ERR(sram->virt_base)) { - dev_err(&pdev->dev, "could not map SRAM registers\n"); - return PTR_ERR(sram->virt_base); - } + sram->no_memory_wc = + of_property_read_bool(pdev->dev.of_node, "no-memory-wc"); + sram->reserved_only = + of_property_read_bool(pdev->dev.of_node, "reserved-only"); - sram->pool = devm_gen_pool_create(sram->dev, ilog2(SRAM_GRANULARITY), - NUMA_NO_NODE, NULL); - if (IS_ERR(sram->pool)) - return PTR_ERR(sram->pool); + if (!sram->reserved_only) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + ret = sram_remap_resource(sram, res, &sram->virt_base); + if (ret) + return ret; + + sram->pool = devm_gen_pool_create(sram->dev, + ilog2(SRAM_GRANULARITY), NUMA_NO_NODE, NULL); + if (IS_ERR(sram->pool)) + return PTR_ERR(sram->pool); + } sram->clk = devm_clk_get(sram->dev, NULL); if (IS_ERR(sram->clk)) @@ -383,8 +419,9 @@ static int sram_probe(struct platform_device *pdev) goto err_free_partitions; } - dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n", - gen_pool_size(sram->pool) / 1024, sram->virt_base); + if (sram->pool) + dev_dbg(sram->dev, "SRAM pool: %zu KiB @ 0x%p\n", + gen_pool_size(sram->pool) / 1024, sram->virt_base); return 0; @@ -403,7 +440,7 @@ static int sram_remove(struct platform_device *pdev) sram_free_partitions(sram); - if (gen_pool_avail(sram->pool) < gen_pool_size(sram->pool)) + if (sram->pool && gen_pool_avail(sram->pool) < gen_pool_size(sram->pool)) dev_err(sram->dev, "removed while SRAM allocated\n"); if (sram->clk) diff --git a/drivers/misc/sram.h b/drivers/misc/sram.h index 9c1d21ff7347..a485fa29458b 100644 --- a/drivers/misc/sram.h +++ b/drivers/misc/sram.h @@ -23,6 +23,8 @@ struct sram_dev { struct sram_partition *partition; u32 partitions; + bool no_memory_wc; + bool reserved_only; }; struct sram_reserve { @@ -33,6 +35,7 @@ struct sram_reserve { bool pool; bool protect_exec; const char *label; + void __iomem *virt_start; }; #ifdef CONFIG_SRAM_EXEC