From patchwork Wed Sep 28 18:17:14 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: fu.wei@linaro.org X-Patchwork-Id: 9354485 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 954386086A for ; Wed, 28 Sep 2016 18:21:40 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 86B7D297A3 for ; Wed, 28 Sep 2016 18:21:40 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7A75729688; Wed, 28 Sep 2016 18:21:40 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-4.1 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=unavailable version=3.3.1 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.wl.linuxfoundation.org (Postfix) with ESMTPS id 22118297A3 for ; Wed, 28 Sep 2016 18:21:40 +0000 (UTC) Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.85_2 #1 (Red Hat Linux)) id 1bpJSo-0006LQ-QG; Wed, 28 Sep 2016 18:20:14 +0000 Received: from mail-pa0-x22f.google.com ([2607:f8b0:400e:c03::22f]) by bombadil.infradead.org with esmtps (Exim 4.85_2 #1 (Red Hat Linux)) id 1bpJRd-0005Ud-Uf for linux-arm-kernel@lists.infradead.org; Wed, 28 Sep 2016 18:19:04 +0000 Received: by mail-pa0-x22f.google.com with SMTP id qn7so19057180pac.3 for ; Wed, 28 Sep 2016 11:18:41 -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; bh=L0bmYUsPgZ/Stc1pDNHuM2WkgoTeOQ8U8yD22oaN+9w=; b=e6NYUh6KLnkoxQ0FlZT3V2dPaKP2UkgrZcqKWxM+BBCVAH6H9ci7RafmK0dLuqAPVQ NiOkTEDldH0uj4H6rJjqOM0NEMkp9rh1mwQoft1XViZmUSSQuiLkjn/Kyj8pqN4uhCxT UqVuBFC9A0DkmBfDurGCC6ur2JOCSJl0tipp4= 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:in-reply-to :references; bh=L0bmYUsPgZ/Stc1pDNHuM2WkgoTeOQ8U8yD22oaN+9w=; b=htiOtZCRV7blAp0jAkjdCW1Y2Tv+n4aazqQKrIg/Ktwkt7OMrGEvG2zFckOo1H+4MO oUtvnwl8S4s9ImJL9Xa8637ckcnVPcwrAF3wPHIM8qgsqsgpRRrArijBKMcxp2v7/sJM KYdkTpTQcQgDC4HAfUDH3lqsGTAZwXXP7jQ0mqzOLvqdjziltuVKgc1//agrQn9ztJGb GY1o9yk3pjp9Mxl+KJgmub1wWV12cBGYiYswDUERILvN6/g6Qhap5jbv1SaIouirseim lBhZd17ZuavXHz6F9nvtSUYihz9ww/DvxvAripVNvGci5cY39oacYz80iW2yH09SnqMG dSnw== X-Gm-Message-State: AE9vXwPnxve2r3SXulZV9Sa6q+WutMStHBOhm5gj48cUvJRfGrzmK8W69xHFKP7dL+yg1IKE X-Received: by 10.66.145.73 with SMTP id ss9mr60136730pab.82.1475086720945; Wed, 28 Sep 2016 11:18:40 -0700 (PDT) Received: from Rei-Ayanami.localdomain.localdomain ([67.238.99.186]) by smtp.googlemail.com with ESMTPSA id ak3sm14226365pad.19.2016.09.28.11.18.38 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 28 Sep 2016 11:18:40 -0700 (PDT) From: fu.wei@linaro.org To: rjw@rjwysocki.net, lenb@kernel.org, daniel.lezcano@linaro.org, tglx@linutronix.de, marc.zyngier@arm.com, mark.rutland@arm.com, lorenzo.pieralisi@arm.com, sudeep.holla@arm.com, hanjun.guo@linaro.org Subject: [PATCH v14 6/9] acpi/arm64: Add memory-mapped timer support in GTDT driver Date: Thu, 29 Sep 2016 02:17:14 +0800 Message-Id: <1475086637-1914-7-git-send-email-fu.wei@linaro.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1475086637-1914-1-git-send-email-fu.wei@linaro.org> References: <1475086637-1914-1-git-send-email-fu.wei@linaro.org> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20160928_111902_105835_825140C4 X-CRM114-Status: GOOD ( 16.48 ) 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: linaro-acpi@lists.linaro.org, catalin.marinas@arm.com, will.deacon@arm.com, linux-kernel@vger.kernel.org, wim@iguana.be, Fu Wei , wei@redhat.com, al.stone@linaro.org, tn@semihalf.com, timur@codeaurora.org, linux-acpi@vger.kernel.org, linux@roeck-us.net, harba@codeaurora.org, julien.grall@arm.com, linux-watchdog@vger.kernel.org, arnd@arndb.de, jcm@redhat.com, cov@codeaurora.org, linux-arm-kernel@lists.infradead.org, graeme.gregory@linaro.org, rruigrok@codeaurora.org, leo.duran@amd.com, Suravee.Suthikulpanit@amd.com, christoffer.dall@linaro.org 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 From: Fu Wei On platforms booting with ACPI, architected memory-mapped timers' configuration data is provided by firmware through the ACPI GTDT static table. The clocksource architected timer kernel driver requires a firmware interface to collect timer configuration and configure its driver. this infrastructure is present for device tree systems, but it is missing on systems booting with ACPI. Implement the kernel infrastructure required to parse the static ACPI GTDT table so that the architected timer clocksource driver can make use of it on systems booting with ACPI, therefore enabling the corresponding timers configuration. Signed-off-by: Fu Wei Signed-off-by: Hanjun Guo --- drivers/acpi/arm64/gtdt.c | 70 ++++++++++++++++++++++++++++++++++++ include/clocksource/arm_arch_timer.h | 15 ++++++++ include/linux/acpi.h | 1 + 3 files changed, 86 insertions(+) diff --git a/drivers/acpi/arm64/gtdt.c b/drivers/acpi/arm64/gtdt.c index b24844d..b6021db 100644 --- a/drivers/acpi/arm64/gtdt.c +++ b/drivers/acpi/arm64/gtdt.c @@ -150,3 +150,73 @@ int __init acpi_gtdt_init(struct acpi_table_header *table) return gtdt->platform_timer_count; } + +static int __init gtdt_parse_gt_block(struct acpi_gtdt_timer_block *block, + struct gt_block_data *data) +{ + struct acpi_gtdt_timer_entry *frame; + int i; + + if (!block || !data) + return -EINVAL; + + if (!block->block_address || !block->timer_count) + return -EINVAL; + + data->cntctlbase_phy = (phys_addr_t)block->block_address; + data->timer_count = block->timer_count; + + frame = (void *)block + block->timer_offset; + if (frame + block->timer_count != (void *)block + block->header.length) + return -EINVAL; + + /* + * Get the GT timer Frame data for every GT Block Timer + */ + for (i = 0; i < block->timer_count; i++, frame++) { + if (!frame->base_address || !frame->timer_interrupt) + return -EINVAL; + + data->timer[i].irq = map_gt_gsi(frame->timer_interrupt, + frame->timer_flags); + if (data->timer[i].irq <= 0) + return -EINVAL; + + if (frame->virtual_timer_interrupt) { + data->timer[i].virtual_irq = + map_gt_gsi(frame->virtual_timer_interrupt, + frame->virtual_timer_flags); + if (data->timer[i].virtual_irq <= 0) + return -EINVAL; + } + + data->timer[i].frame_nr = frame->frame_number; + data->timer[i].cntbase_phy = frame->base_address; + } + + return 0; +} + +/* + * Get the GT block info for memory-mapped timer from GTDT table. + */ +int __init gtdt_arch_timer_mem_init(struct gt_block_data *data) +{ + void *platform_timer; + int index = 0; + int ret; + + for_each_platform_timer(platform_timer) { + if (!is_timer_block(platform_timer)) + continue; + ret = gtdt_parse_gt_block(platform_timer, data + index); + if (ret) + return ret; + index++; + } + + if (index) + pr_info("found %d memory-mapped timer block(s).\n", index); + + return index; +} diff --git a/include/clocksource/arm_arch_timer.h b/include/clocksource/arm_arch_timer.h index 16dcd10..94a5d14 100644 --- a/include/clocksource/arm_arch_timer.h +++ b/include/clocksource/arm_arch_timer.h @@ -56,6 +56,8 @@ enum spi_nr { #define ARCH_TIMER_MEM_PHYS_ACCESS 2 #define ARCH_TIMER_MEM_VIRT_ACCESS 3 +#define ARCH_TIMER_MEM_MAX_FRAME 8 + #define ARCH_TIMER_USR_PCT_ACCESS_EN (1 << 0) /* physical counter */ #define ARCH_TIMER_USR_VCT_ACCESS_EN (1 << 1) /* virtual counter */ #define ARCH_TIMER_VIRT_EVT_EN (1 << 2) @@ -71,6 +73,19 @@ struct arch_timer_kvm_info { int virtual_irq; }; +struct gt_timer_data { + int frame_nr; + phys_addr_t cntbase_phy; + int irq; + int virtual_irq; +}; + +struct gt_block_data { + phys_addr_t cntctlbase_phy; + int timer_count; + struct gt_timer_data timer[ARCH_TIMER_MEM_MAX_FRAME]; +}; + #ifdef CONFIG_ARM_ARCH_TIMER extern u32 arch_timer_get_rate(void); diff --git a/include/linux/acpi.h b/include/linux/acpi.h index e2f9841..5dc0b85 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -571,6 +571,7 @@ int acpi_reconfig_notifier_unregister(struct notifier_block *nb); int acpi_gtdt_init(struct acpi_table_header *table); int acpi_gtdt_map_ppi(int type); bool acpi_gtdt_c3stop(void); +int gtdt_arch_timer_mem_init(struct gt_block_data *data); #endif #else /* !CONFIG_ACPI */