From patchwork Mon Jan 25 22:58:43 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Shanker Donthineni X-Patchwork-Id: 8116741 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork1.web.kernel.org (Postfix) with ESMTP id AFB299F38B for ; Mon, 25 Jan 2016 23:01:07 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id B454B2038D for ; Mon, 25 Jan 2016 23:01:06 +0000 (UTC) Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.9]) (using TLSv1.2 with cipher AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id B3F5120389 for ; Mon, 25 Jan 2016 23:01:05 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1aNq6Q-0000G2-Vc; Mon, 25 Jan 2016 22:59:18 +0000 Received: from smtp.codeaurora.org ([198.145.29.96]) by bombadil.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1aNq6N-0000Dx-D6 for linux-arm-kernel@lists.infradead.org; Mon, 25 Jan 2016 22:59:16 +0000 Received: from smtp.codeaurora.org (localhost [127.0.0.1]) by smtp.codeaurora.org (Postfix) with ESMTP id A10FA604A2; Mon, 25 Jan 2016 22:58:54 +0000 (UTC) Received: by smtp.codeaurora.org (Postfix, from userid 1000) id 8CAB960499; Mon, 25 Jan 2016 22:58:54 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Spam-Level: X-Spam-Status: No, score=-4.2 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_MED, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable version=3.3.1 Received: from shankerd-ubuntu.qualcomm.com (rrcs-67-52-129-61.west.biz.rr.com [67.52.129.61]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-SHA256 (128/128 bits)) (No client certificate requested) (Authenticated sender: shankerd@smtp.codeaurora.org) by smtp.codeaurora.org (Postfix) with ESMTPSA id DE88C60318; Mon, 25 Jan 2016 22:58:52 +0000 (UTC) From: Shanker Donthineni To: Marc Zyngier , linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org Subject: [PATCH 1/1] [V2] irqchip: gicv3-its: Introduce indirect device-ITT table support Date: Mon, 25 Jan 2016 16:58:43 -0600 Message-Id: <1453762723-19477-1-git-send-email-shankerd@codeaurora.org> X-Mailer: git-send-email 1.9.1 X-Virus-Scanned: ClamAV using ClamSMTP X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160125_145915_503143_FA0B752E X-CRM114-Status: GOOD ( 20.48 ) X-Spam-Score: -1.9 (-) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Christopher Covington , Jason Cooper , Vikram Sethi , Tomasz Nowicki , Timur Tabi , Thomas Gleixner , Shanker Donthineni MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Current ITS driver implementation limits the device ID to a few number of bits depending on memory that has been allocated to a flat DEV-ITT table. Some of the devices are not usable when device ID is spread out across a large range of 32 bit values. This patch covers more DEVID bits by implementing the GIC-ITS indirect device table. This feature is enabled automatically during driver probe if the flat table is not adequate to hold all DEVID bits. Signed-off-by: Shanker Donthineni --- [v1]->[v2]: -Removed the line "Change-Id: I9c6d005dexxx" from commit message. -Fixed the its->max_devid field initialization. drivers/irqchip/irq-gic-v3-its.c | 79 +++++++++++++++++++++++++++++++++++--- include/linux/irqchip/arm-gic-v3.h | 1 + 2 files changed, 75 insertions(+), 5 deletions(-) diff --git a/drivers/irqchip/irq-gic-v3-its.c b/drivers/irqchip/irq-gic-v3-its.c index e23d1d1..408a358 100644 --- a/drivers/irqchip/irq-gic-v3-its.c +++ b/drivers/irqchip/irq-gic-v3-its.c @@ -41,6 +41,8 @@ #define ITS_FLAGS_CMDQ_NEEDS_FLUSHING (1ULL << 0) #define ITS_FLAGS_WORKAROUND_CAVIUM_22375 (1ULL << 1) +#define ITS_FLAGS_DEVICE_NEEDS_FLUSHING (1ULL << 2) +#define ITS_FLAGS_INDIRECT_DEVICE_TABLE (1ULL << 3) #define RDIST_FLAGS_PROPBASE_NEEDS_FLUSHING (1 << 0) @@ -71,6 +73,10 @@ struct its_node { struct list_head its_device_list; u64 flags; u32 ite_size; + u32 dev_table_idx; + u32 dev_table_shift; + u32 max_devid; + u32 order; }; #define ITS_ITT_ALIGN SZ_256 @@ -824,6 +830,8 @@ static int its_alloc_tables(const char *node_name, struct its_node *its) u64 typer; u32 ids; +#define ITS_DEVICE_MAX_ORDER min(MAX_ORDER, get_order(SZ_8M)) + if (its->flags & ITS_FLAGS_WORKAROUND_CAVIUM_22375) { /* * erratum 22375: only alloc 8MB table size @@ -867,11 +875,12 @@ static int its_alloc_tables(const char *node_name, struct its_node *its) */ order = max(get_order((1UL << ids) * entry_size), order); - if (order >= MAX_ORDER) { - order = MAX_ORDER - 1; - pr_warn("%s: Device Table too large, reduce its page order to %u\n", - node_name, order); - } + if (order >= ITS_DEVICE_MAX_ORDER) { + /* Update flags for two-level setup */ + its->flags |= ITS_FLAGS_INDIRECT_DEVICE_TABLE; + order = ITS_DEVICE_MAX_ORDER - 1; + } else + its->max_devid = (1 << ids) - 1; } alloc_size = (1 << order) * PAGE_SIZE; @@ -911,6 +920,26 @@ retry_baser: break; } + /* Enable two-level (indirect) device table if it is required */ + if ((type == GITS_BASER_TYPE_DEVICE) && + (its->flags & ITS_FLAGS_INDIRECT_DEVICE_TABLE)) { + u32 shift = ilog2(psz / entry_size); + u32 max_ids = ilog2(alloc_size >> 3) + shift; + + if (ids > max_ids) { + pr_warn( + "ITS: @%pa DEVID too large reduce %u->%u\n", + &its->phys_base, ids, max_ids); + } + its->max_devid = (1UL << max_ids) - 1; + its->order = get_order(psz); + its->dev_table_idx = i; + its->dev_table_shift = shift; + if (!(val & GITS_BASER_SHAREABILITY_MASK)) + its->flags |= ITS_FLAGS_DEVICE_NEEDS_FLUSHING; + val |= GITS_BASER_INDIRECT; + } + val |= alloc_pages - 1; writeq_relaxed(val, its->base + GITS_BASER + i * 8); @@ -1134,6 +1163,32 @@ static struct its_device *its_find_device(struct its_node *its, u32 dev_id) return its_dev; } +static int its_alloc_device_table(struct its_node *its, u32 dev_id) +{ + u64 *devtbl = its->tables[its->dev_table_idx]; + u32 alloc_size = (1 << its->order) * PAGE_SIZE; + u32 idx = dev_id >> its->dev_table_shift; + struct page *page; + + /* Do nothing if the level-2 DEV-ITT entry was mapped earlier */ + if (devtbl[idx]) + return 0; + + /* Allocate memory for level-2 device table & map to level-1 table */ + page = alloc_pages(GFP_KERNEL | __GFP_ZERO, its->order); + if (!page) + return -ENOMEM; + + devtbl[idx] = page_to_phys(page) | GITS_BASER_VALID; + + if (its->flags & ITS_FLAGS_DEVICE_NEEDS_FLUSHING) { + __flush_dcache_area(page_address(page), alloc_size); + __flush_dcache_area(devtbl + idx, sizeof(*devtbl)); + } + + return 0; +} + static struct its_device *its_create_device(struct its_node *its, u32 dev_id, int nvecs) { @@ -1147,6 +1202,20 @@ static struct its_device *its_create_device(struct its_node *its, u32 dev_id, int nr_ites; int sz; + if (dev_id > its->max_devid) { + pr_err("ITS: dev_id too large %d\n", dev_id); + return NULL; + } + + /* Ensure memory for level-2 table is allocated for dev_id */ + if (its->flags & ITS_FLAGS_INDIRECT_DEVICE_TABLE) { + int ret; + + ret = its_alloc_device_table(its, dev_id); + if (ret) + return NULL; + } + dev = kzalloc(sizeof(*dev), GFP_KERNEL); /* * At least one bit of EventID is being used, hence a minimum diff --git a/include/linux/irqchip/arm-gic-v3.h b/include/linux/irqchip/arm-gic-v3.h index d5d798b..04dfe09 100644 --- a/include/linux/irqchip/arm-gic-v3.h +++ b/include/linux/irqchip/arm-gic-v3.h @@ -206,6 +206,7 @@ #define GITS_BASER_NR_REGS 8 #define GITS_BASER_VALID (1UL << 63) +#define GITS_BASER_INDIRECT (1UL << 62) #define GITS_BASER_nCnB (0UL << 59) #define GITS_BASER_nC (1UL << 59) #define GITS_BASER_RaWt (2UL << 59)