2 * Copyright(C) 2016 Linaro Limited. All rights reserved.
3 * Author: Mathieu Poirier <mathieu.poirier@linaro.org>
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 as published by
7 * the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program. If not, see <http://www.gnu.org/licenses/>.
18 #include <linux/coresight.h>
19 #include "coresight-priv.h"
20 #include "coresight-tmc.h"
22 void tmc_etr_enable_hw(struct tmc_drvdata *drvdata)
26 /* Zero out the memory to help with debug */
27 memset(drvdata->vaddr, 0, drvdata->size);
29 CS_UNLOCK(drvdata->base);
31 /* Wait for TMCSReady bit to be set */
32 tmc_wait_for_tmcready(drvdata);
34 writel_relaxed(drvdata->size / 4, drvdata->base + TMC_RSZ);
35 writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE);
37 axictl = readl_relaxed(drvdata->base + TMC_AXICTL);
38 axictl |= TMC_AXICTL_WR_BURST_16;
39 writel_relaxed(axictl, drvdata->base + TMC_AXICTL);
40 axictl &= ~TMC_AXICTL_SCT_GAT_MODE;
41 writel_relaxed(axictl, drvdata->base + TMC_AXICTL);
43 ~(TMC_AXICTL_PROT_CTL_B0 | TMC_AXICTL_PROT_CTL_B1)) |
44 TMC_AXICTL_PROT_CTL_B1;
45 writel_relaxed(axictl, drvdata->base + TMC_AXICTL);
47 writel_relaxed(drvdata->paddr, drvdata->base + TMC_DBALO);
48 writel_relaxed(0x0, drvdata->base + TMC_DBAHI);
49 writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI |
50 TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT |
51 TMC_FFCR_TRIGON_TRIGIN,
52 drvdata->base + TMC_FFCR);
53 writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG);
54 tmc_enable_hw(drvdata);
56 CS_LOCK(drvdata->base);
59 static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata)
63 rwp = readl_relaxed(drvdata->base + TMC_RWP);
64 val = readl_relaxed(drvdata->base + TMC_STS);
66 /* How much memory do we still have */
68 drvdata->buf = drvdata->vaddr + rwp - drvdata->paddr;
70 drvdata->buf = drvdata->vaddr;
73 static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata)
75 CS_UNLOCK(drvdata->base);
77 tmc_flush_and_stop(drvdata);
78 tmc_etr_dump_hw(drvdata);
79 tmc_disable_hw(drvdata);
81 CS_LOCK(drvdata->base);
84 static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode)
87 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
89 spin_lock_irqsave(&drvdata->spinlock, flags);
90 if (drvdata->reading) {
91 spin_unlock_irqrestore(&drvdata->spinlock, flags);
95 tmc_etr_enable_hw(drvdata);
96 drvdata->enable = true;
97 spin_unlock_irqrestore(&drvdata->spinlock, flags);
99 dev_info(drvdata->dev, "TMC-ETR enabled\n");
103 static void tmc_disable_etr_sink(struct coresight_device *csdev)
106 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent);
108 spin_lock_irqsave(&drvdata->spinlock, flags);
109 if (drvdata->reading) {
110 spin_unlock_irqrestore(&drvdata->spinlock, flags);
114 tmc_etr_disable_hw(drvdata);
115 drvdata->enable = false;
116 spin_unlock_irqrestore(&drvdata->spinlock, flags);
118 dev_info(drvdata->dev, "TMC-ETR disabled\n");
121 static const struct coresight_ops_sink tmc_etr_sink_ops = {
122 .enable = tmc_enable_etr_sink,
123 .disable = tmc_disable_etr_sink,
126 const struct coresight_ops tmc_etr_cs_ops = {
127 .sink_ops = &tmc_etr_sink_ops,
130 int tmc_read_prepare_etr(struct tmc_drvdata *drvdata)
134 /* config types are set a boot time and never change */
135 if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
138 spin_lock_irqsave(&drvdata->spinlock, flags);
140 /* Disable the TMC if need be */
142 tmc_etr_disable_hw(drvdata);
144 drvdata->reading = true;
145 spin_unlock_irqrestore(&drvdata->spinlock, flags);
150 int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata)
154 /* config types are set a boot time and never change */
155 if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR))
158 spin_lock_irqsave(&drvdata->spinlock, flags);
160 /* RE-enable the TMC if need be */
162 tmc_etr_enable_hw(drvdata);
164 drvdata->reading = false;
165 spin_unlock_irqrestore(&drvdata->spinlock, flags);