Loading Documentation/devicetree/bindings/arm/coresight.txt +127 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ its hardware characteristcs. - "arm,coresight-funnel", "arm,primecell"; - "arm,coresight-etm3x", "arm,primecell"; - "qcom,coresight-replicator1x", "arm,primecell"; - "arm,coresight-stm", "arm,primecell"; * reg: physical base address and length of the register set(s) of the component. Loading @@ -35,12 +36,20 @@ its hardware characteristcs. * Required properties for devices that don't show up on the AMBA bus, such as non-configurable replicators: * compatible: Currently supported value is (note the absence of the * compatible: Currently supported values are (note the absence of the AMBA markee): - "arm,coresight-replicator" - "qcom,coresight-csr" - "arm,coresight-cti" - "qcom,coresight-tpda" - "qcom,coresight-tpdm" * port or ports: same as above. * Optional properties for all components: * coresight-name: unique descriptive name of the component. * reg-names: names corresponding to each reg property value. * Optional properties for ETM/PTMs: * arm,cp14: must be present if the system accesses ETM/PTM management Loading @@ -54,6 +63,35 @@ its hardware characteristcs. * arm,buffer-size: size of contiguous buffer space for TMC ETR (embedded trace router) * Required property for TPDAs: * qcom,tpda-atid: must be present. Specifies the ATID for TPDA. * Optional properties for TPDAs: * qcom,bc-elem-size: specifies the BC element size supported by each monitor connected to the aggregator on each port. Should be specified in pairs (port, bc element size). * qcom,tc-elem-size: specifies the TC element size supported by each monitor connected to the aggregator on each port. Should be specified in pairs (port, tc element size). * qcom,dsb-elem-size: specifies the DSB element size supported by each monitor connected to the aggregator on each port. Should be specified in pairs (port, dsb element size). * qcom,cmb-elem-size: specifies the CMB element size supported by each monitor connected to the aggregator on each port. Should be specified in pairs (port, cmb element size). * Optional properties for TPDM: * qcom,clk-enable: specifies whether additional clock bit needs to be set for M4M TPDM. * qcom,msr-fix-req: boolean, indicating if MSRs need to be programmed after enabling the subunit. Example: Loading Loading @@ -170,6 +208,42 @@ Example: }; }; tpda_mss: tpda@7043000 { compatible = "qcom,coresight-tpda"; reg = <0x7043000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-mss"; qcom,tpda-atid = <67>; qcom,dsb-elem-size = <0 32>; qcom,cmb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_mss_out_funnel_in1: endpoint { remote-endpoint = <&funnel_in1_in_tpda_mss>; }; }; port@1 { reg = <0>; tpda_mss_in_tpdm_mss: endpoint { slave-mode; remote-endpoint = <&tpdm_mss_out_tpda_mss>; }; }; }; }; 3. Sources ptm@2201c000 { compatible = "arm,coresight-etm3x", "arm,primecell"; Loading Loading @@ -198,3 +272,55 @@ Example: }; }; }; stm: stm@6002000 { compatible = "arm,coresight-stm", "arm,primecell"; arm,primecell-periphid = <0x0003b962>; reg = <0x6002000 0x1000>, <0x16280000 0x180000>; reg-names = "stm-base", "stm-data-base"; coresight-name = "coresight-stm"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "apb_pclk", "core_a_clk"; port{ stm_out_funnel_in0: endpoint { remote-endpoint = <&funnel_in0_in_stm>; }; }; }; tpdm_mss: tpdm@7042000 { compatible = "qcom,coresight-tpdm"; reg = <0x7042000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-mss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_mss_out_tpda_mss: endpoint { remote-endpoint = <&tpda_mss_in_tpdm_mss>; }; }; }; 4. CTIs cti0: cti@6010000 { compatible = "arm,coresight-cti"; reg = <0x6010000 0x1000>; reg-names = "cti-base"; coresight-name = "coresight-cti0"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; }; arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi +553 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,22 @@ }; }; port@1 { reg = <3>; funnel_in0_in_funnel_spss: endpoint { slave-mode; remote-endpoint = <&funnel_spss_out_funnel_in0>; }; }; port@2 { reg = <6>; funnel_in0_in_funnel_qatb: endpoint { slave-mode; remote-endpoint = <&funnel_qatb_out_funnel_in0>; }; }; port@3 { reg = <7>; funnel_in0_in_stm: endpoint { slave-mode; Loading Loading @@ -199,6 +215,22 @@ }; }; port@1 { reg = <2>; funnel_in1_in_tpda_nav: endpoint { slave-mode; remote-endpoint = <&tpda_nav_out_funnel_in1>; }; }; port@2 { reg = <3>; funnel_in1_in_tpda_mss: endpoint { slave-mode; remote-endpoint = <&tpda_mss_out_funnel_in1>; }; }; port@3 { reg = <6>; funnel_in1_in_funnel_apss_merg: endpoint { slave-mode; Loading Loading @@ -241,6 +273,22 @@ <&funnel_apss_out_funnel_apss_merg>; }; }; port@2 { reg = <1>; funnel_apss_merg_in_tpda_olc: endpoint { slave-mode; remote-endpoint = <&tpda_olc_out_funnel_apss_merg>; }; }; port@3 { reg = <3>; funnel_apss_merg_in_tpda_apss: endpoint { slave-mode; remote-endpoint = <&tpda_apss_out_funnel_apss_merg>; }; }; }; }; Loading Loading @@ -811,4 +859,509 @@ <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; }; funnel_qatb: funnel@6005000 { compatible = "arm,primecell"; arm,primecell-periphid = <0x0003b908>; reg = <0x6005000 0x1000>; reg-names = "funnel-base"; coresight-name = "coresight-funnel-qatb"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "apb_pclk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; funnel_qatb_out_funnel_in0: endpoint { remote-endpoint = <&funnel_in0_in_funnel_qatb>; }; }; port@1 { reg = <0>; funnel_qatb_in_tpda: endpoint { slave-mode; remote-endpoint = <&tpda_out_funnel_qatb>; }; }; }; }; tpda: tpda@6004000 { compatible = "qcom,coresight-tpda"; reg = <0x6004000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda"; qcom,tpda-atid = <65>; qcom,bc-elem-size = <7 32>, <9 32>; qcom,tc-elem-size = <3 32>, <6 32>, <9 32>; qcom,dsb-elem-size = <7 32>, <9 32>; qcom,cmb-elem-size = <3 32>, <4 32>, <5 32>, <9 64>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_out_funnel_qatb: endpoint { remote-endpoint = <&funnel_qatb_in_tpda>; }; }; port@1 { reg = <3>; tpda_in_tpdm_vsense: endpoint { slave-mode; remote-endpoint = <&tpdm_vsense_out_tpda>; }; }; port@2 { reg = <4>; tpda_in_tpdm_dcc: endpoint { slave-mode; remote-endpoint = <&tpdm_dcc_out_tpda>; }; }; port@3 { reg = <5>; tpda_in_tpdm_prng: endpoint { slave-mode; remote-endpoint = <&tpdm_prng_out_tpda>; }; }; port@4 { reg = <7>; tpda_in_tpdm_qm: endpoint { slave-mode; remote-endpoint = <&tpdm_qm_out_tpda>; }; }; port@5 { reg = <9>; tpda_in_tpdm_pimem: endpoint { slave-mode; remote-endpoint = <&tpdm_pimem_out_tpda>; }; }; }; }; tpdm_vsense: tpdm@7038000 { compatible = "qcom,coresight-tpdm"; reg = <0x7038000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-vsense"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_vsense_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_vsense>; }; }; }; tpdm_dcc: tpdm@7054000 { compatible = "qcom,coresight-tpdm"; reg = <0x7054000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-dcc"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_dcc_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_dcc>; }; }; }; tpdm_prng: tpdm@704c000 { compatible = "qcom,coresight-tpdm"; reg = <0x704c000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-prng"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_prng_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_prng>; }; }; }; tpdm_qm: tpdm@71d0000 { compatible = "qcom,coresight-tpdm"; reg = <0x71d0000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-qm"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_qm_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_qm>; }; }; }; tpdm_pimem: tpdm@7050000 { compatible = "qcom,coresight-tpdm"; reg = <0x7050000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-pimem"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_pimem_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_pimem>; }; }; }; tpda_apss: tpda@7bc2000 { compatible = "qcom,coresight-tpda"; reg = <0x7bc2000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-apss"; qcom,tpda-atid = <66>; qcom,dsb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_apss_out_funnel_apss_merg: endpoint { remote-endpoint = <&funnel_apss_merg_in_tpda_apss>; }; }; port@1 { reg = <0>; tpda_apss_in_tpdm_apss: endpoint { slave-mode; remote-endpoint = <&tpdm_apss_out_tpda_apss>; }; }; }; }; tpdm_apss: tpdm@7bc0000 { compatible = "qcom,coresight-tpdm"; reg = <0x7bc0000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-apss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_apss_out_tpda_apss: endpoint { remote-endpoint = <&tpda_apss_in_tpdm_apss>; }; }; }; tpda_mss: tpda@7043000 { compatible = "qcom,coresight-tpda"; reg = <0x7043000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-mss"; qcom,tpda-atid = <67>; qcom,dsb-elem-size = <0 32>; qcom,cmb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_mss_out_funnel_in1: endpoint { remote-endpoint = <&funnel_in1_in_tpda_mss>; }; }; port@1 { reg = <0>; tpda_mss_in_tpdm_mss: endpoint { slave-mode; remote-endpoint = <&tpdm_mss_out_tpda_mss>; }; }; }; }; tpdm_mss: tpdm@7042000 { compatible = "qcom,coresight-tpdm"; reg = <0x7042000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-mss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_mss_out_tpda_mss: endpoint { remote-endpoint = <&tpda_mss_in_tpdm_mss>; }; }; }; tpda_nav: tpda@7191000 { compatible = "qcom,coresight-tpda"; reg = <0x7191000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-nav"; qcom,tpda-atid = <68>; qcom,cmb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_nav_out_funnel_in1: endpoint { remote-endpoint = <&funnel_in1_in_tpda_nav>; }; }; port@1 { reg = <0>; tpda_nav_in_tpdm_nav: endpoint { slave-mode; remote-endpoint = <&tpdm_nav_out_tpda_nav>; }; }; }; }; tpdm_nav: tpdm@7190000 { compatible = "qcom,coresight-tpdm"; reg = <0x7190000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-nav"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_nav_out_tpda_nav: endpoint { remote-endpoint = <&tpda_nav_in_tpdm_nav>; }; }; }; tpda_olc: tpda@7b92000 { compatible = "qcom,coresight-tpda"; reg = <0x7b92000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-olc"; qcom,tpda-atid = <69>; qcom,cmb-elem-size = <0 64>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_olc_out_funnel_apss_merg: endpoint { remote-endpoint = <&funnel_apss_merg_in_tpda_olc>; }; }; port@1 { reg = <0>; tpda_olc_in_tpdm_olc: endpoint { slave-mode; remote-endpoint = <&tpdm_olc_out_tpda_olc>; }; }; }; }; tpdm_olc: tpdm@7b90000 { compatible = "qcom,coresight-tpdm"; reg = <0x7b90000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-olc"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_olc_out_tpda_olc: endpoint { remote-endpoint = <&tpda_olc_in_tpdm_olc>; }; }; }; funnel_spss: funnel@7083000 { compatible = "arm,primecell"; arm,primecell-periphid = <0x0003b908>; reg = <0x7083000 0x1000>; reg-names = "funnel-base"; coresight-name = "coresight-funnel-spss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "apb_pclk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; funnel_spss_out_funnel_in0: endpoint { remote-endpoint = <&funnel_in0_in_funnel_spss>; }; }; port@1 { reg = <0>; funnel_spss_in_tpda_spss: endpoint { slave-mode; remote-endpoint = <&tpda_spss_out_funnel_spss>; }; }; }; }; tpda_spss: tpda@7082000 { compatible = "qcom,coresight-tpda"; reg = <0x7082000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-spss"; qcom,tpda-atid = <70>; qcom,dsb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_spss_out_funnel_spss: endpoint { remote-endpoint = <&funnel_spss_in_tpda_spss>; }; }; port@1 { reg = <0>; tpda_spss_in_tpdm_spss: endpoint { slave-mode; remote-endpoint = <&tpdm_spss_out_tpda_spss>; }; }; }; }; tpdm_spss: tpdm@7080000 { compatible = "qcom,coresight-tpdm"; reg = <0x7080000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-spss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_spss_out_tpda_spss: endpoint { remote-endpoint = <&tpda_spss_in_tpdm_spss>; }; }; }; }; drivers/hwtracing/coresight/Kconfig +27 −0 Original line number Diff line number Diff line Loading @@ -103,4 +103,31 @@ config CORESIGHT_CTI hardware component to another. It can also be used to pass software generated events. config CORESIGHT_TPDA bool "CoreSight Trace, Profiling & Diagnostics Aggregator driver" help This driver provides support for configuring aggregator. This is primarily useful for pulling the data sets from one or more attached monitors and pushing the resultant data out. Multiple monitors are connected on different input ports of TPDA. config CORESIGHT_TPDM bool "CoreSight Trace, Profiling & Diagnostics Monitor driver" help This driver provides support for configuring monitor. Monitors are primarily responsible for data set collection and support the ability to collect any permutation of data set types. Monitors are also responsible for interaction with system cross triggering. config CORESIGHT_TPDM_DEFAULT_ENABLE bool "Turn on TPDM tracing by default" depends on CORESIGHT_TPDM help Turns on CoreSight TPDM tracing for different data set types by default. Otherwise, tracing is disabled by default but can be enabled via sysfs. If unsure, say 'N' here to avoid potential power and performance penalty. endif drivers/hwtracing/coresight/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -14,3 +14,5 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o obj-$(CONFIG_CORESIGHT_TPDA) += coresight-tpda.o obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o drivers/hwtracing/coresight/coresight-etm4x.c +130 −44 Original line number Diff line number Diff line /* Copyright (c) 2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -24,7 +24,6 @@ #include <linux/smp.h> #include <linux/sysfs.h> #include <linux/stat.h> #include <linux/clk.h> #include <linux/cpu.h> #include <linux/coresight.h> #include <linux/pm_wakeup.h> Loading @@ -42,14 +41,17 @@ module_param_named(boot_enable, boot_enable, int, S_IRUGO); /* The number of ETMv4 currently registered */ static int etm4_count; static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; static struct notifier_block etm4_cpu_notifier; static void etm4_os_unlock(void *info) { struct etmv4_drvdata *drvdata = (struct etmv4_drvdata *)info; CS_UNLOCK(drvdata->base); /* Writing any value to ETMOSLAR unlocks the trace registers */ writel_relaxed(0x0, drvdata->base + TRCOSLAR); isb(); CS_LOCK(drvdata->base); } static bool etm4_arch_supported(u8 arch) Loading Loading @@ -93,8 +95,6 @@ static void etm4_enable_hw(void *info) CS_UNLOCK(drvdata->base); etm4_os_unlock(drvdata); /* Disable the trace unit before programming trace registers */ writel_relaxed(0, drvdata->base + TRCPRGCTLR); Loading Loading @@ -2543,27 +2543,84 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata) drvdata->vmid_mask1 = 0x0; /* * A trace ID value of 0 is invalid, so let's start at some * random value that fits in 7 bits. ETMv3.x has 0x10 so let's * start at 0x20. * Start trace id from 0x1. */ drvdata->trcid = 0x20 + drvdata->cpu; drvdata->trcid = 0x1 + drvdata->cpu; } static int etm4_late_init(struct etmv4_drvdata *drvdata) { int ret; struct coresight_desc *desc; struct device *dev = drvdata->dev; if (etm4_arch_supported(drvdata->arch) == false) return -EINVAL; etm4_init_default_data(drvdata); desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); if (!desc) return -ENOMEM; desc->type = CORESIGHT_DEV_TYPE_SOURCE; desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc->ops = &etm4_cs_ops; desc->pdata = dev->platform_data; desc->dev = dev; desc->groups = coresight_etmv4_groups; drvdata->csdev = coresight_register(desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); goto err_coresight_register; } dev_info(dev, "ETM 4.0 initialized\n"); if (boot_enable) { coresight_enable(drvdata->csdev); drvdata->boot_enable = true; } drvdata->init = true; return 0; err_coresight_register: devm_kfree(dev, desc); return ret; } static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; static bool clk_disable[NR_CPUS]; int ret; if (!etmdrvdata[cpu]) goto out; switch (action & (~CPU_TASKS_FROZEN)) { case CPU_UP_PREPARE: if (!etmdrvdata[cpu]->os_unlock) { ret = pm_runtime_get_sync(etmdrvdata[cpu]->dev); if (ret) { dev_err(etmdrvdata[cpu]->dev, "ETM clk enable during hotplug failed for cpu: %d, ret: %d\n", cpu, ret); goto err_clk_init; } clk_disable[cpu] = true; } break; case CPU_STARTING: spin_lock(&etmdrvdata[cpu]->spinlock); if (!etmdrvdata[cpu]->os_unlock) { etm4_os_unlock(etmdrvdata[cpu]); etmdrvdata[cpu]->os_unlock = true; etm4_init_arch_data(etmdrvdata[cpu]); } if (etmdrvdata[cpu]->enable) Loading @@ -2572,11 +2629,36 @@ static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action, break; case CPU_ONLINE: mutex_lock(&etmdrvdata[cpu]->mutex); if (!etmdrvdata[cpu]->init) { ret = etm4_late_init(etmdrvdata[cpu]); if (ret) { dev_err(etmdrvdata[cpu]->dev, "ETM init failed. Cpu: %d, ret: %d\n", cpu, ret); mutex_unlock(&etmdrvdata[cpu]->mutex); goto err_init; } } mutex_unlock(&etmdrvdata[cpu]->mutex); if (clk_disable[cpu]) { pm_runtime_put(etmdrvdata[cpu]->dev); clk_disable[cpu] = false; } if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable) coresight_enable(etmdrvdata[cpu]->csdev); break; case CPU_UP_CANCELED: if (clk_disable[cpu]) { pm_runtime_put(etmdrvdata[cpu]->dev); clk_disable[cpu] = false; } break; case CPU_DYING: spin_lock(&etmdrvdata[cpu]->spinlock); if (etmdrvdata[cpu]->enable) Loading @@ -2586,6 +2668,23 @@ static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action, } out: return NOTIFY_OK; err_init: if (--etm4_count == 0) unregister_hotcpu_notifier(&etm4_cpu_notifier); if (clk_disable[cpu]) { pm_runtime_put(etmdrvdata[cpu]->dev); clk_disable[cpu] = false; } devm_iounmap(etmdrvdata[cpu]->dev, etmdrvdata[cpu]->base); dev_set_drvdata(etmdrvdata[cpu]->dev, NULL); devm_kfree(etmdrvdata[cpu]->dev, etmdrvdata[cpu]); etmdrvdata[cpu] = NULL; err_clk_init: return notifier_from_errno(ret); } static struct notifier_block etm4_cpu_notifier = { Loading @@ -2600,13 +2699,8 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) struct coresight_platform_data *pdata = NULL; struct etmv4_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc *desc; struct device_node *np = adev->dev.of_node; desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); if (!desc) return -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; Loading @@ -2629,56 +2723,48 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) drvdata->base = base; spin_lock_init(&drvdata->spinlock); mutex_init(&drvdata->mutex); drvdata->cpu = pdata ? pdata->cpu : 0; get_online_cpus(); etmdrvdata[drvdata->cpu] = drvdata; if (!smp_call_function_single(drvdata->cpu, etm4_os_unlock, drvdata, 1)) if (!smp_call_function_single(drvdata->cpu, etm4_os_unlock, drvdata, 1)) { drvdata->os_unlock = true; if (smp_call_function_single(drvdata->cpu, etm4_init_arch_data, drvdata, 1)) ret = smp_call_function_single(drvdata->cpu, etm4_init_arch_data, drvdata, 1); if (ret) { dev_err(dev, "ETM arch init failed\n"); put_online_cpus(); pm_runtime_put(&adev->dev); return ret; } } etmdrvdata[drvdata->cpu] = drvdata; if (!etm4_count++) register_hotcpu_notifier(&etm4_cpu_notifier); put_online_cpus(); if (etm4_arch_supported(drvdata->arch) == false) { ret = -EINVAL; goto err_arch_supported; } etm4_init_default_data(drvdata); pm_runtime_put(&adev->dev); desc->type = CORESIGHT_DEV_TYPE_SOURCE; desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc->ops = &etm4_cs_ops; desc->pdata = pdata; desc->dev = dev; desc->groups = coresight_etmv4_groups; drvdata->csdev = coresight_register(desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); goto err_coresight_register; mutex_lock(&drvdata->mutex); if (drvdata->os_unlock && !drvdata->init) { ret = etm4_late_init(drvdata); if (ret) { mutex_unlock(&drvdata->mutex); goto err_late_init; } dev_info(dev, "%s initialized\n", (char *)id->data); if (boot_enable) { coresight_enable(drvdata->csdev); drvdata->boot_enable = true; } mutex_unlock(&drvdata->mutex); return 0; err_arch_supported: pm_runtime_put(&adev->dev); err_coresight_register: err_late_init: if (--etm4_count == 0) unregister_hotcpu_notifier(&etm4_cpu_notifier); return ret; Loading Loading
Documentation/devicetree/bindings/arm/coresight.txt +127 −1 Original line number Diff line number Diff line Loading @@ -18,6 +18,7 @@ its hardware characteristcs. - "arm,coresight-funnel", "arm,primecell"; - "arm,coresight-etm3x", "arm,primecell"; - "qcom,coresight-replicator1x", "arm,primecell"; - "arm,coresight-stm", "arm,primecell"; * reg: physical base address and length of the register set(s) of the component. Loading @@ -35,12 +36,20 @@ its hardware characteristcs. * Required properties for devices that don't show up on the AMBA bus, such as non-configurable replicators: * compatible: Currently supported value is (note the absence of the * compatible: Currently supported values are (note the absence of the AMBA markee): - "arm,coresight-replicator" - "qcom,coresight-csr" - "arm,coresight-cti" - "qcom,coresight-tpda" - "qcom,coresight-tpdm" * port or ports: same as above. * Optional properties for all components: * coresight-name: unique descriptive name of the component. * reg-names: names corresponding to each reg property value. * Optional properties for ETM/PTMs: * arm,cp14: must be present if the system accesses ETM/PTM management Loading @@ -54,6 +63,35 @@ its hardware characteristcs. * arm,buffer-size: size of contiguous buffer space for TMC ETR (embedded trace router) * Required property for TPDAs: * qcom,tpda-atid: must be present. Specifies the ATID for TPDA. * Optional properties for TPDAs: * qcom,bc-elem-size: specifies the BC element size supported by each monitor connected to the aggregator on each port. Should be specified in pairs (port, bc element size). * qcom,tc-elem-size: specifies the TC element size supported by each monitor connected to the aggregator on each port. Should be specified in pairs (port, tc element size). * qcom,dsb-elem-size: specifies the DSB element size supported by each monitor connected to the aggregator on each port. Should be specified in pairs (port, dsb element size). * qcom,cmb-elem-size: specifies the CMB element size supported by each monitor connected to the aggregator on each port. Should be specified in pairs (port, cmb element size). * Optional properties for TPDM: * qcom,clk-enable: specifies whether additional clock bit needs to be set for M4M TPDM. * qcom,msr-fix-req: boolean, indicating if MSRs need to be programmed after enabling the subunit. Example: Loading Loading @@ -170,6 +208,42 @@ Example: }; }; tpda_mss: tpda@7043000 { compatible = "qcom,coresight-tpda"; reg = <0x7043000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-mss"; qcom,tpda-atid = <67>; qcom,dsb-elem-size = <0 32>; qcom,cmb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_mss_out_funnel_in1: endpoint { remote-endpoint = <&funnel_in1_in_tpda_mss>; }; }; port@1 { reg = <0>; tpda_mss_in_tpdm_mss: endpoint { slave-mode; remote-endpoint = <&tpdm_mss_out_tpda_mss>; }; }; }; }; 3. Sources ptm@2201c000 { compatible = "arm,coresight-etm3x", "arm,primecell"; Loading Loading @@ -198,3 +272,55 @@ Example: }; }; }; stm: stm@6002000 { compatible = "arm,coresight-stm", "arm,primecell"; arm,primecell-periphid = <0x0003b962>; reg = <0x6002000 0x1000>, <0x16280000 0x180000>; reg-names = "stm-base", "stm-data-base"; coresight-name = "coresight-stm"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "apb_pclk", "core_a_clk"; port{ stm_out_funnel_in0: endpoint { remote-endpoint = <&funnel_in0_in_stm>; }; }; }; tpdm_mss: tpdm@7042000 { compatible = "qcom,coresight-tpdm"; reg = <0x7042000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-mss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_mss_out_tpda_mss: endpoint { remote-endpoint = <&tpda_mss_in_tpdm_mss>; }; }; }; 4. CTIs cti0: cti@6010000 { compatible = "arm,coresight-cti"; reg = <0x6010000 0x1000>; reg-names = "cti-base"; coresight-name = "coresight-cti0"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; };
arch/arm/boot/dts/qcom/msmcobalt-coresight.dtsi +553 −0 Original line number Diff line number Diff line Loading @@ -165,6 +165,22 @@ }; }; port@1 { reg = <3>; funnel_in0_in_funnel_spss: endpoint { slave-mode; remote-endpoint = <&funnel_spss_out_funnel_in0>; }; }; port@2 { reg = <6>; funnel_in0_in_funnel_qatb: endpoint { slave-mode; remote-endpoint = <&funnel_qatb_out_funnel_in0>; }; }; port@3 { reg = <7>; funnel_in0_in_stm: endpoint { slave-mode; Loading Loading @@ -199,6 +215,22 @@ }; }; port@1 { reg = <2>; funnel_in1_in_tpda_nav: endpoint { slave-mode; remote-endpoint = <&tpda_nav_out_funnel_in1>; }; }; port@2 { reg = <3>; funnel_in1_in_tpda_mss: endpoint { slave-mode; remote-endpoint = <&tpda_mss_out_funnel_in1>; }; }; port@3 { reg = <6>; funnel_in1_in_funnel_apss_merg: endpoint { slave-mode; Loading Loading @@ -241,6 +273,22 @@ <&funnel_apss_out_funnel_apss_merg>; }; }; port@2 { reg = <1>; funnel_apss_merg_in_tpda_olc: endpoint { slave-mode; remote-endpoint = <&tpda_olc_out_funnel_apss_merg>; }; }; port@3 { reg = <3>; funnel_apss_merg_in_tpda_apss: endpoint { slave-mode; remote-endpoint = <&tpda_apss_out_funnel_apss_merg>; }; }; }; }; Loading Loading @@ -811,4 +859,509 @@ <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; }; funnel_qatb: funnel@6005000 { compatible = "arm,primecell"; arm,primecell-periphid = <0x0003b908>; reg = <0x6005000 0x1000>; reg-names = "funnel-base"; coresight-name = "coresight-funnel-qatb"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "apb_pclk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; funnel_qatb_out_funnel_in0: endpoint { remote-endpoint = <&funnel_in0_in_funnel_qatb>; }; }; port@1 { reg = <0>; funnel_qatb_in_tpda: endpoint { slave-mode; remote-endpoint = <&tpda_out_funnel_qatb>; }; }; }; }; tpda: tpda@6004000 { compatible = "qcom,coresight-tpda"; reg = <0x6004000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda"; qcom,tpda-atid = <65>; qcom,bc-elem-size = <7 32>, <9 32>; qcom,tc-elem-size = <3 32>, <6 32>, <9 32>; qcom,dsb-elem-size = <7 32>, <9 32>; qcom,cmb-elem-size = <3 32>, <4 32>, <5 32>, <9 64>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_out_funnel_qatb: endpoint { remote-endpoint = <&funnel_qatb_in_tpda>; }; }; port@1 { reg = <3>; tpda_in_tpdm_vsense: endpoint { slave-mode; remote-endpoint = <&tpdm_vsense_out_tpda>; }; }; port@2 { reg = <4>; tpda_in_tpdm_dcc: endpoint { slave-mode; remote-endpoint = <&tpdm_dcc_out_tpda>; }; }; port@3 { reg = <5>; tpda_in_tpdm_prng: endpoint { slave-mode; remote-endpoint = <&tpdm_prng_out_tpda>; }; }; port@4 { reg = <7>; tpda_in_tpdm_qm: endpoint { slave-mode; remote-endpoint = <&tpdm_qm_out_tpda>; }; }; port@5 { reg = <9>; tpda_in_tpdm_pimem: endpoint { slave-mode; remote-endpoint = <&tpdm_pimem_out_tpda>; }; }; }; }; tpdm_vsense: tpdm@7038000 { compatible = "qcom,coresight-tpdm"; reg = <0x7038000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-vsense"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_vsense_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_vsense>; }; }; }; tpdm_dcc: tpdm@7054000 { compatible = "qcom,coresight-tpdm"; reg = <0x7054000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-dcc"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_dcc_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_dcc>; }; }; }; tpdm_prng: tpdm@704c000 { compatible = "qcom,coresight-tpdm"; reg = <0x704c000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-prng"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_prng_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_prng>; }; }; }; tpdm_qm: tpdm@71d0000 { compatible = "qcom,coresight-tpdm"; reg = <0x71d0000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-qm"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_qm_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_qm>; }; }; }; tpdm_pimem: tpdm@7050000 { compatible = "qcom,coresight-tpdm"; reg = <0x7050000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-pimem"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_pimem_out_tpda: endpoint { remote-endpoint = <&tpda_in_tpdm_pimem>; }; }; }; tpda_apss: tpda@7bc2000 { compatible = "qcom,coresight-tpda"; reg = <0x7bc2000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-apss"; qcom,tpda-atid = <66>; qcom,dsb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_apss_out_funnel_apss_merg: endpoint { remote-endpoint = <&funnel_apss_merg_in_tpda_apss>; }; }; port@1 { reg = <0>; tpda_apss_in_tpdm_apss: endpoint { slave-mode; remote-endpoint = <&tpdm_apss_out_tpda_apss>; }; }; }; }; tpdm_apss: tpdm@7bc0000 { compatible = "qcom,coresight-tpdm"; reg = <0x7bc0000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-apss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_apss_out_tpda_apss: endpoint { remote-endpoint = <&tpda_apss_in_tpdm_apss>; }; }; }; tpda_mss: tpda@7043000 { compatible = "qcom,coresight-tpda"; reg = <0x7043000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-mss"; qcom,tpda-atid = <67>; qcom,dsb-elem-size = <0 32>; qcom,cmb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_mss_out_funnel_in1: endpoint { remote-endpoint = <&funnel_in1_in_tpda_mss>; }; }; port@1 { reg = <0>; tpda_mss_in_tpdm_mss: endpoint { slave-mode; remote-endpoint = <&tpdm_mss_out_tpda_mss>; }; }; }; }; tpdm_mss: tpdm@7042000 { compatible = "qcom,coresight-tpdm"; reg = <0x7042000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-mss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_mss_out_tpda_mss: endpoint { remote-endpoint = <&tpda_mss_in_tpdm_mss>; }; }; }; tpda_nav: tpda@7191000 { compatible = "qcom,coresight-tpda"; reg = <0x7191000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-nav"; qcom,tpda-atid = <68>; qcom,cmb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_nav_out_funnel_in1: endpoint { remote-endpoint = <&funnel_in1_in_tpda_nav>; }; }; port@1 { reg = <0>; tpda_nav_in_tpdm_nav: endpoint { slave-mode; remote-endpoint = <&tpdm_nav_out_tpda_nav>; }; }; }; }; tpdm_nav: tpdm@7190000 { compatible = "qcom,coresight-tpdm"; reg = <0x7190000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-nav"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_nav_out_tpda_nav: endpoint { remote-endpoint = <&tpda_nav_in_tpdm_nav>; }; }; }; tpda_olc: tpda@7b92000 { compatible = "qcom,coresight-tpda"; reg = <0x7b92000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-olc"; qcom,tpda-atid = <69>; qcom,cmb-elem-size = <0 64>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_olc_out_funnel_apss_merg: endpoint { remote-endpoint = <&funnel_apss_merg_in_tpda_olc>; }; }; port@1 { reg = <0>; tpda_olc_in_tpdm_olc: endpoint { slave-mode; remote-endpoint = <&tpdm_olc_out_tpda_olc>; }; }; }; }; tpdm_olc: tpdm@7b90000 { compatible = "qcom,coresight-tpdm"; reg = <0x7b90000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-olc"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_olc_out_tpda_olc: endpoint { remote-endpoint = <&tpda_olc_in_tpdm_olc>; }; }; }; funnel_spss: funnel@7083000 { compatible = "arm,primecell"; arm,primecell-periphid = <0x0003b908>; reg = <0x7083000 0x1000>; reg-names = "funnel-base"; coresight-name = "coresight-funnel-spss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "apb_pclk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; funnel_spss_out_funnel_in0: endpoint { remote-endpoint = <&funnel_in0_in_funnel_spss>; }; }; port@1 { reg = <0>; funnel_spss_in_tpda_spss: endpoint { slave-mode; remote-endpoint = <&tpda_spss_out_funnel_spss>; }; }; }; }; tpda_spss: tpda@7082000 { compatible = "qcom,coresight-tpda"; reg = <0x7082000 0x1000>; reg-names = "tpda-base"; coresight-name = "coresight-tpda-spss"; qcom,tpda-atid = <70>; qcom,dsb-elem-size = <0 32>; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; ports { #address-cells = <1>; #size-cells = <0>; port@0 { reg = <0>; tpda_spss_out_funnel_spss: endpoint { remote-endpoint = <&funnel_spss_in_tpda_spss>; }; }; port@1 { reg = <0>; tpda_spss_in_tpdm_spss: endpoint { slave-mode; remote-endpoint = <&tpdm_spss_out_tpda_spss>; }; }; }; }; tpdm_spss: tpdm@7080000 { compatible = "qcom,coresight-tpdm"; reg = <0x7080000 0x1000>; reg-names = "tpdm-base"; coresight-name = "coresight-tpdm-spss"; clocks = <&clock_gcc clk_qdss_clk>, <&clock_gcc clk_qdss_a_clk>; clock-names = "core_clk", "core_a_clk"; port{ tpdm_spss_out_tpda_spss: endpoint { remote-endpoint = <&tpda_spss_in_tpdm_spss>; }; }; }; };
drivers/hwtracing/coresight/Kconfig +27 −0 Original line number Diff line number Diff line Loading @@ -103,4 +103,31 @@ config CORESIGHT_CTI hardware component to another. It can also be used to pass software generated events. config CORESIGHT_TPDA bool "CoreSight Trace, Profiling & Diagnostics Aggregator driver" help This driver provides support for configuring aggregator. This is primarily useful for pulling the data sets from one or more attached monitors and pushing the resultant data out. Multiple monitors are connected on different input ports of TPDA. config CORESIGHT_TPDM bool "CoreSight Trace, Profiling & Diagnostics Monitor driver" help This driver provides support for configuring monitor. Monitors are primarily responsible for data set collection and support the ability to collect any permutation of data set types. Monitors are also responsible for interaction with system cross triggering. config CORESIGHT_TPDM_DEFAULT_ENABLE bool "Turn on TPDM tracing by default" depends on CORESIGHT_TPDM help Turns on CoreSight TPDM tracing for different data set types by default. Otherwise, tracing is disabled by default but can be enabled via sysfs. If unsure, say 'N' here to avoid potential power and performance penalty. endif
drivers/hwtracing/coresight/Makefile +2 −0 Original line number Diff line number Diff line Loading @@ -14,3 +14,5 @@ obj-$(CONFIG_CORESIGHT_SOURCE_ETM4X) += coresight-etm4x.o obj-$(CONFIG_CORESIGHT_QCOM_REPLICATOR) += coresight-replicator-qcom.o obj-$(CONFIG_CORESIGHT_STM) += coresight-stm.o obj-$(CONFIG_CORESIGHT_CTI) += coresight-cti.o obj-$(CONFIG_CORESIGHT_TPDA) += coresight-tpda.o obj-$(CONFIG_CORESIGHT_TPDM) += coresight-tpdm.o
drivers/hwtracing/coresight/coresight-etm4x.c +130 −44 Original line number Diff line number Diff line /* Copyright (c) 2014, The Linux Foundation. All rights reserved. /* Copyright (c) 2014, 2016 The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading @@ -24,7 +24,6 @@ #include <linux/smp.h> #include <linux/sysfs.h> #include <linux/stat.h> #include <linux/clk.h> #include <linux/cpu.h> #include <linux/coresight.h> #include <linux/pm_wakeup.h> Loading @@ -42,14 +41,17 @@ module_param_named(boot_enable, boot_enable, int, S_IRUGO); /* The number of ETMv4 currently registered */ static int etm4_count; static struct etmv4_drvdata *etmdrvdata[NR_CPUS]; static struct notifier_block etm4_cpu_notifier; static void etm4_os_unlock(void *info) { struct etmv4_drvdata *drvdata = (struct etmv4_drvdata *)info; CS_UNLOCK(drvdata->base); /* Writing any value to ETMOSLAR unlocks the trace registers */ writel_relaxed(0x0, drvdata->base + TRCOSLAR); isb(); CS_LOCK(drvdata->base); } static bool etm4_arch_supported(u8 arch) Loading Loading @@ -93,8 +95,6 @@ static void etm4_enable_hw(void *info) CS_UNLOCK(drvdata->base); etm4_os_unlock(drvdata); /* Disable the trace unit before programming trace registers */ writel_relaxed(0, drvdata->base + TRCPRGCTLR); Loading Loading @@ -2543,27 +2543,84 @@ static void etm4_init_default_data(struct etmv4_drvdata *drvdata) drvdata->vmid_mask1 = 0x0; /* * A trace ID value of 0 is invalid, so let's start at some * random value that fits in 7 bits. ETMv3.x has 0x10 so let's * start at 0x20. * Start trace id from 0x1. */ drvdata->trcid = 0x20 + drvdata->cpu; drvdata->trcid = 0x1 + drvdata->cpu; } static int etm4_late_init(struct etmv4_drvdata *drvdata) { int ret; struct coresight_desc *desc; struct device *dev = drvdata->dev; if (etm4_arch_supported(drvdata->arch) == false) return -EINVAL; etm4_init_default_data(drvdata); desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); if (!desc) return -ENOMEM; desc->type = CORESIGHT_DEV_TYPE_SOURCE; desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc->ops = &etm4_cs_ops; desc->pdata = dev->platform_data; desc->dev = dev; desc->groups = coresight_etmv4_groups; drvdata->csdev = coresight_register(desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); goto err_coresight_register; } dev_info(dev, "ETM 4.0 initialized\n"); if (boot_enable) { coresight_enable(drvdata->csdev); drvdata->boot_enable = true; } drvdata->init = true; return 0; err_coresight_register: devm_kfree(dev, desc); return ret; } static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action, void *hcpu) { unsigned int cpu = (unsigned long)hcpu; static bool clk_disable[NR_CPUS]; int ret; if (!etmdrvdata[cpu]) goto out; switch (action & (~CPU_TASKS_FROZEN)) { case CPU_UP_PREPARE: if (!etmdrvdata[cpu]->os_unlock) { ret = pm_runtime_get_sync(etmdrvdata[cpu]->dev); if (ret) { dev_err(etmdrvdata[cpu]->dev, "ETM clk enable during hotplug failed for cpu: %d, ret: %d\n", cpu, ret); goto err_clk_init; } clk_disable[cpu] = true; } break; case CPU_STARTING: spin_lock(&etmdrvdata[cpu]->spinlock); if (!etmdrvdata[cpu]->os_unlock) { etm4_os_unlock(etmdrvdata[cpu]); etmdrvdata[cpu]->os_unlock = true; etm4_init_arch_data(etmdrvdata[cpu]); } if (etmdrvdata[cpu]->enable) Loading @@ -2572,11 +2629,36 @@ static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action, break; case CPU_ONLINE: mutex_lock(&etmdrvdata[cpu]->mutex); if (!etmdrvdata[cpu]->init) { ret = etm4_late_init(etmdrvdata[cpu]); if (ret) { dev_err(etmdrvdata[cpu]->dev, "ETM init failed. Cpu: %d, ret: %d\n", cpu, ret); mutex_unlock(&etmdrvdata[cpu]->mutex); goto err_init; } } mutex_unlock(&etmdrvdata[cpu]->mutex); if (clk_disable[cpu]) { pm_runtime_put(etmdrvdata[cpu]->dev); clk_disable[cpu] = false; } if (etmdrvdata[cpu]->boot_enable && !etmdrvdata[cpu]->sticky_enable) coresight_enable(etmdrvdata[cpu]->csdev); break; case CPU_UP_CANCELED: if (clk_disable[cpu]) { pm_runtime_put(etmdrvdata[cpu]->dev); clk_disable[cpu] = false; } break; case CPU_DYING: spin_lock(&etmdrvdata[cpu]->spinlock); if (etmdrvdata[cpu]->enable) Loading @@ -2586,6 +2668,23 @@ static int etm4_cpu_callback(struct notifier_block *nfb, unsigned long action, } out: return NOTIFY_OK; err_init: if (--etm4_count == 0) unregister_hotcpu_notifier(&etm4_cpu_notifier); if (clk_disable[cpu]) { pm_runtime_put(etmdrvdata[cpu]->dev); clk_disable[cpu] = false; } devm_iounmap(etmdrvdata[cpu]->dev, etmdrvdata[cpu]->base); dev_set_drvdata(etmdrvdata[cpu]->dev, NULL); devm_kfree(etmdrvdata[cpu]->dev, etmdrvdata[cpu]); etmdrvdata[cpu] = NULL; err_clk_init: return notifier_from_errno(ret); } static struct notifier_block etm4_cpu_notifier = { Loading @@ -2600,13 +2699,8 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) struct coresight_platform_data *pdata = NULL; struct etmv4_drvdata *drvdata; struct resource *res = &adev->res; struct coresight_desc *desc; struct device_node *np = adev->dev.of_node; desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); if (!desc) return -ENOMEM; drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); if (!drvdata) return -ENOMEM; Loading @@ -2629,56 +2723,48 @@ static int etm4_probe(struct amba_device *adev, const struct amba_id *id) drvdata->base = base; spin_lock_init(&drvdata->spinlock); mutex_init(&drvdata->mutex); drvdata->cpu = pdata ? pdata->cpu : 0; get_online_cpus(); etmdrvdata[drvdata->cpu] = drvdata; if (!smp_call_function_single(drvdata->cpu, etm4_os_unlock, drvdata, 1)) if (!smp_call_function_single(drvdata->cpu, etm4_os_unlock, drvdata, 1)) { drvdata->os_unlock = true; if (smp_call_function_single(drvdata->cpu, etm4_init_arch_data, drvdata, 1)) ret = smp_call_function_single(drvdata->cpu, etm4_init_arch_data, drvdata, 1); if (ret) { dev_err(dev, "ETM arch init failed\n"); put_online_cpus(); pm_runtime_put(&adev->dev); return ret; } } etmdrvdata[drvdata->cpu] = drvdata; if (!etm4_count++) register_hotcpu_notifier(&etm4_cpu_notifier); put_online_cpus(); if (etm4_arch_supported(drvdata->arch) == false) { ret = -EINVAL; goto err_arch_supported; } etm4_init_default_data(drvdata); pm_runtime_put(&adev->dev); desc->type = CORESIGHT_DEV_TYPE_SOURCE; desc->subtype.source_subtype = CORESIGHT_DEV_SUBTYPE_SOURCE_PROC; desc->ops = &etm4_cs_ops; desc->pdata = pdata; desc->dev = dev; desc->groups = coresight_etmv4_groups; drvdata->csdev = coresight_register(desc); if (IS_ERR(drvdata->csdev)) { ret = PTR_ERR(drvdata->csdev); goto err_coresight_register; mutex_lock(&drvdata->mutex); if (drvdata->os_unlock && !drvdata->init) { ret = etm4_late_init(drvdata); if (ret) { mutex_unlock(&drvdata->mutex); goto err_late_init; } dev_info(dev, "%s initialized\n", (char *)id->data); if (boot_enable) { coresight_enable(drvdata->csdev); drvdata->boot_enable = true; } mutex_unlock(&drvdata->mutex); return 0; err_arch_supported: pm_runtime_put(&adev->dev); err_coresight_register: err_late_init: if (--etm4_count == 0) unregister_hotcpu_notifier(&etm4_cpu_notifier); return ret; Loading