From patchwork Thu Mar 28 16:11:37 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rickard Andersson X-Patchwork-Id: 2357721 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 17CB13FD40 for ; Thu, 28 Mar 2013 16:18:50 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1ULFU4-0006qZ-Du; Thu, 28 Mar 2013 16:15:25 +0000 Received: from eu1sys200aog110.obsmtp.com ([207.126.144.129]) by merlin.infradead.org with smtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1ULFQw-0005nz-Br for linux-arm-kernel@lists.infradead.org; Thu, 28 Mar 2013 16:12:19 +0000 Received: from beta.dmz-us.st.com ([167.4.1.35]) (using TLSv1) by eu1sys200aob110.postini.com ([207.126.147.11]) with SMTP ID DSNKUVRr0mM07/JVKvyA3Ulxt8uqlNEwk7NC@postini.com; Thu, 28 Mar 2013 16:12:09 UTC Received: from zeta.dmz-us.st.com (ns4.st.com [167.4.16.71]) by beta.dmz-us.st.com (STMicroelectronics) with ESMTP id 40FBF50; Thu, 28 Mar 2013 16:11:06 +0000 (GMT) Received: from relay2.stm.gmessaging.net (unknown [10.230.100.18]) by zeta.dmz-us.st.com (STMicroelectronics) with ESMTP id 6230864; Thu, 28 Mar 2013 09:39:39 +0000 (GMT) Received: from exdcvycastm022.EQ1STM.local (alteon-source-exch [10.230.100.61]) (using TLSv1 with cipher RC4-MD5 (128/128 bits)) (Client CN "exdcvycastm022", Issuer "exdcvycastm022" (not verified)) by relay2.stm.gmessaging.net (Postfix) with ESMTPS id E9A5AA8074; Thu, 28 Mar 2013 17:11:50 +0100 (CET) Received: from steludxu2826.lud.stericsson.com (10.230.100.153) by smtp.stericsson.com (10.230.100.30) with Microsoft SMTP Server (TLS) id 8.3.279.5; Thu, 28 Mar 2013 17:11:56 +0100 From: Rickard Andersson To: , , Subject: [PATCH V2 11/12] misc: ux500: Add TPIU driver Date: Thu, 28 Mar 2013 17:11:37 +0100 Message-ID: <1364487098-10319-12-git-send-email-rickard.andersson@stericsson.com> X-Mailer: git-send-email 1.8.2 In-Reply-To: <1364487098-10319-1-git-send-email-rickard.andersson@stericsson.com> References: <1364487098-10319-1-git-send-email-rickard.andersson@stericsson.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20130328_121210_763641_7C2543EC X-CRM114-Status: GOOD ( 18.44 ) X-Spam-Score: -4.2 (----) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-4.2 points) pts rule name description ---- ---------------------- -------------------------------------------------- -2.3 RCVD_IN_DNSWL_MED RBL: Sender listed at http://www.dnswl.org/, medium trust [207.126.144.129 listed in list.dnswl.org] -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: hongbo.zhang@linaro.org, ulf.hansson@linaro.org, khilman@linaro.org, linus.walleij@stericsson.com, daniel.lezcano@linaro.org, rickard.andersson@stericsson.com X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org TPIU is Trace Port Interface Unit. Ux500 needs a TPIU driver because in Ux500 the TPIU hardware block loses its settings when the APE power domain is turned off. Settings needs to be saved before the sleep state ApSleep or ApDeepSleep is reached and the block needs to be unlocked and restored when leaving those sleep states. If this is not done PTM tracing with debugger stops working after the first sleep where the power domain is off. Signed-off-by: Rickard Andersson --- drivers/misc/Makefile | 1 + drivers/misc/dbx500-tpiu.c | 182 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 183 insertions(+) create mode 100644 drivers/misc/dbx500-tpiu.c diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile index 2129377..9a774ab 100644 --- a/drivers/misc/Makefile +++ b/drivers/misc/Makefile @@ -49,3 +49,4 @@ obj-y += carma/ obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/ obj-$(CONFIG_INTEL_MEI) += mei/ +obj-$(CONFIG_UX500_SOC_DB8500) += dbx500-tpiu.o \ No newline at end of file diff --git a/drivers/misc/dbx500-tpiu.c b/drivers/misc/dbx500-tpiu.c new file mode 100644 index 0000000..fd07c6f --- /dev/null +++ b/drivers/misc/dbx500-tpiu.c @@ -0,0 +1,182 @@ +/* + * Copyright (C) ST-Ericsson SA 2010-2013 + * Author: Rickard Andersson + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#include +#include +#include +#include +#include + +#define TPIU_PORT_SIZE 0x4 +#define TPIU_TRIGGER_COUNTER 0x104 +#define TPIU_TRIGGER_MULTIPLIER 0x108 +#define TPIU_CURRENT_TEST_PATTERN 0x204 +#define TPIU_TEST_PATTERN_REPEAT 0x208 +#define TPIU_FORMATTER 0x304 +#define TPIU_FORMATTER_SYNC 0x308 +#define TPIU_LOCK_ACCESS_REGISTER 0xFB0 + +#define TPIU_UNLOCK_CODE 0xc5acce55 + +/* The context of the Trace Port Interface Unit (TPIU) */ +static struct { + void __iomem *base; + u32 port_size; + u32 trigger_counter; + u32 trigger_multiplier; + u32 current_test_pattern; + u32 test_pattern_repeat; + u32 formatter; + u32 formatter_sync; +} context_tpiu; + +/* + * Save the context of the DB8500 Trace Port Interface Unit (TPIU). + * Saving/restoring is needed for the PTM tracing to work together + * with sleep states where the APE power domain is turned off. + */ +static void tpiu_save_context(void) +{ + context_tpiu.port_size = readl(context_tpiu.base + + TPIU_PORT_SIZE); + context_tpiu.trigger_counter = readl(context_tpiu.base + + TPIU_TRIGGER_COUNTER); + context_tpiu.trigger_multiplier = readl(context_tpiu.base + + TPIU_TRIGGER_MULTIPLIER); + context_tpiu.current_test_pattern = readl(context_tpiu.base + + TPIU_CURRENT_TEST_PATTERN); + context_tpiu.test_pattern_repeat = readl(context_tpiu.base + + TPIU_TEST_PATTERN_REPEAT); + context_tpiu.formatter = readl(context_tpiu.base + + TPIU_FORMATTER); + context_tpiu.formatter_sync = readl(context_tpiu.base + + TPIU_FORMATTER_SYNC); +} + +/* + * Restore the context of the DB8500 Trace Port Interface Unit (TPIU). + * Saving/restoring is needed for the PTM tracing to work together + * with the sleep states where the APE power domain is turned off. + */ +static void tpiu_restore_context(void) +{ + writel(TPIU_UNLOCK_CODE, + context_tpiu.base + TPIU_LOCK_ACCESS_REGISTER); + + writel(context_tpiu.port_size, + context_tpiu.base + TPIU_PORT_SIZE); + writel(context_tpiu.trigger_counter, + context_tpiu.base + TPIU_TRIGGER_COUNTER); + writel(context_tpiu.trigger_multiplier, + context_tpiu.base + TPIU_TRIGGER_MULTIPLIER); + writel(context_tpiu.current_test_pattern, + context_tpiu.base + TPIU_CURRENT_TEST_PATTERN); + writel(context_tpiu.test_pattern_repeat, + context_tpiu.base + TPIU_TEST_PATTERN_REPEAT); + writel(context_tpiu.formatter, + context_tpiu.base + TPIU_FORMATTER); + writel(context_tpiu.formatter_sync, + context_tpiu.base + TPIU_FORMATTER_SYNC); +} + +static int tpiu_context_call(struct notifier_block *this, + unsigned long event, void *data) +{ + bool power_on = (bool)event; + + if (power_on) + tpiu_restore_context(); + else + tpiu_save_context(); + + return 0; +} + +static struct notifier_block tpiu_context_notifier = { + .notifier_call = tpiu_context_call, +}; + +static const struct of_device_id dbx500_tpiu_match[] = { + { .compatible = "stericsson,dbx500-tpiu", }, + {}, +}; + +static struct platform_driver dbx500_tpiu_plat_driver = { + .driver = { + .name = "dbx500-tpiu", + .of_match_table = dbx500_tpiu_match, + }, + .remove = __exit_p(dbx500_tpiu_remove), +}; + +static int __init dbx500_tpiu_probe(struct platform_device *pdev) +{ + int ret = 0; + struct resource *res; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + dev_err(&pdev->dev, "missing platform resources\n"); + return -EINVAL; + } + + if (!request_mem_region(res->start, resource_size(res), pdev->name)) { + dev_err(&pdev->dev, "failed to request I/O memory\n"); + return -EBUSY; + } + + context_tpiu.base = ioremap(res->start, resource_size(res)); + if (!context_tpiu.base) { + ret = -ENOMEM; + goto err_free_mem_region; + } + + ret = pm_genpd_register_on_off_notifier(&pdev->dev, + &tpiu_context_notifier); + if (ret) + goto err_iounmap; + + return ret; + + err_iounmap: + iounmap(context_tpiu.base); + err_free_mem_region: + release_mem_region(res->start, resource_size(res)); + return ret; +} + +static int __exit dbx500_tpiu_remove(struct platform_device *pdev) +{ + int ret; + + struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + + ret = pm_genpd_unregister_on_off_notifier(&pdev->dev, + &tpiu_context_notifier); + iounmap(context_tpiu.base); + release_mem_region(res->start, resource_size(res)); + + return ret; +} + +static int __init dbx500_tpiu_init(void) +{ + return platform_driver_probe(&dbx500_tpiu_plat_driver, + dbx500_tpiu_probe); +} + +static void __exit dbx500_tpiu_exit(void) +{ + return platform_driver_unregister(&dbx500_tpiu_plat_driver); +} + +arch_initcall(dbx500_tpiu_init); +module_exit(dbx500_tpiu_exit); + +MODULE_DESCRIPTION("TPIU driver for dbx500"); +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Rickard Andersson ");