1 /* 2 * Copyright(C) 2016 Linaro Limited. All rights reserved. 3 * Author: Mathieu Poirier <mathieu.poirier@linaro.org> 4 * 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. 8 * 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 12 * more details. 13 * 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/>. 16 */ 17 18 #include <linux/coresight.h> 19 #include <linux/dma-mapping.h> 20 #include "coresight-priv.h" 21 #include "coresight-tmc.h" 22 23 void tmc_etr_enable_hw(struct tmc_drvdata *drvdata) 24 { 25 u32 axictl; 26 27 /* Zero out the memory to help with debug */ 28 memset(drvdata->vaddr, 0, drvdata->size); 29 30 CS_UNLOCK(drvdata->base); 31 32 /* Wait for TMCSReady bit to be set */ 33 tmc_wait_for_tmcready(drvdata); 34 35 writel_relaxed(drvdata->size / 4, drvdata->base + TMC_RSZ); 36 writel_relaxed(TMC_MODE_CIRCULAR_BUFFER, drvdata->base + TMC_MODE); 37 38 axictl = readl_relaxed(drvdata->base + TMC_AXICTL); 39 axictl |= TMC_AXICTL_WR_BURST_16; 40 writel_relaxed(axictl, drvdata->base + TMC_AXICTL); 41 axictl &= ~TMC_AXICTL_SCT_GAT_MODE; 42 writel_relaxed(axictl, drvdata->base + TMC_AXICTL); 43 axictl = (axictl & 44 ~(TMC_AXICTL_PROT_CTL_B0 | TMC_AXICTL_PROT_CTL_B1)) | 45 TMC_AXICTL_PROT_CTL_B1; 46 writel_relaxed(axictl, drvdata->base + TMC_AXICTL); 47 48 writel_relaxed(drvdata->paddr, drvdata->base + TMC_DBALO); 49 writel_relaxed(0x0, drvdata->base + TMC_DBAHI); 50 writel_relaxed(TMC_FFCR_EN_FMT | TMC_FFCR_EN_TI | 51 TMC_FFCR_FON_FLIN | TMC_FFCR_FON_TRIG_EVT | 52 TMC_FFCR_TRIGON_TRIGIN, 53 drvdata->base + TMC_FFCR); 54 writel_relaxed(drvdata->trigger_cntr, drvdata->base + TMC_TRG); 55 tmc_enable_hw(drvdata); 56 57 CS_LOCK(drvdata->base); 58 } 59 60 static void tmc_etr_dump_hw(struct tmc_drvdata *drvdata) 61 { 62 u32 rwp, val; 63 64 rwp = readl_relaxed(drvdata->base + TMC_RWP); 65 val = readl_relaxed(drvdata->base + TMC_STS); 66 67 /* How much memory do we still have */ 68 if (val & BIT(0)) 69 drvdata->buf = drvdata->vaddr + rwp - drvdata->paddr; 70 else 71 drvdata->buf = drvdata->vaddr; 72 } 73 74 static void tmc_etr_disable_hw(struct tmc_drvdata *drvdata) 75 { 76 CS_UNLOCK(drvdata->base); 77 78 tmc_flush_and_stop(drvdata); 79 /* 80 * When operating in sysFS mode the content of the buffer needs to be 81 * read before the TMC is disabled. 82 */ 83 if (local_read(&drvdata->mode) == CS_MODE_SYSFS) 84 tmc_etr_dump_hw(drvdata); 85 tmc_disable_hw(drvdata); 86 87 CS_LOCK(drvdata->base); 88 } 89 90 static int tmc_enable_etr_sink_sysfs(struct coresight_device *csdev, u32 mode) 91 { 92 int ret = 0; 93 bool used = false; 94 long val; 95 unsigned long flags; 96 void __iomem *vaddr = NULL; 97 dma_addr_t paddr; 98 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 99 100 /* This shouldn't be happening */ 101 if (WARN_ON(mode != CS_MODE_SYSFS)) 102 return -EINVAL; 103 104 /* 105 * If we don't have a buffer release the lock and allocate memory. 106 * Otherwise keep the lock and move along. 107 */ 108 spin_lock_irqsave(&drvdata->spinlock, flags); 109 if (!drvdata->vaddr) { 110 spin_unlock_irqrestore(&drvdata->spinlock, flags); 111 112 /* 113 * Contiguous memory can't be allocated while a spinlock is 114 * held. As such allocate memory here and free it if a buffer 115 * has already been allocated (from a previous session). 116 */ 117 vaddr = dma_alloc_coherent(drvdata->dev, drvdata->size, 118 &paddr, GFP_KERNEL); 119 if (!vaddr) 120 return -ENOMEM; 121 122 /* Let's try again */ 123 spin_lock_irqsave(&drvdata->spinlock, flags); 124 } 125 126 if (drvdata->reading) { 127 ret = -EBUSY; 128 goto out; 129 } 130 131 val = local_xchg(&drvdata->mode, mode); 132 /* 133 * In sysFS mode we can have multiple writers per sink. Since this 134 * sink is already enabled no memory is needed and the HW need not be 135 * touched. 136 */ 137 if (val == CS_MODE_SYSFS) 138 goto out; 139 140 /* 141 * If drvdata::buf == NULL, use the memory allocated above. 142 * Otherwise a buffer still exists from a previous session, so 143 * simply use that. 144 */ 145 if (drvdata->buf == NULL) { 146 used = true; 147 drvdata->vaddr = vaddr; 148 drvdata->paddr = paddr; 149 drvdata->buf = drvdata->vaddr; 150 } 151 152 memset(drvdata->vaddr, 0, drvdata->size); 153 154 tmc_etr_enable_hw(drvdata); 155 out: 156 spin_unlock_irqrestore(&drvdata->spinlock, flags); 157 158 /* Free memory outside the spinlock if need be */ 159 if (!used && vaddr) 160 dma_free_coherent(drvdata->dev, drvdata->size, vaddr, paddr); 161 162 if (!ret) 163 dev_info(drvdata->dev, "TMC-ETR enabled\n"); 164 165 return ret; 166 } 167 168 static int tmc_enable_etr_sink_perf(struct coresight_device *csdev, u32 mode) 169 { 170 int ret = 0; 171 long val; 172 unsigned long flags; 173 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 174 175 /* This shouldn't be happening */ 176 if (WARN_ON(mode != CS_MODE_PERF)) 177 return -EINVAL; 178 179 spin_lock_irqsave(&drvdata->spinlock, flags); 180 if (drvdata->reading) { 181 ret = -EINVAL; 182 goto out; 183 } 184 185 val = local_xchg(&drvdata->mode, mode); 186 /* 187 * In Perf mode there can be only one writer per sink. There 188 * is also no need to continue if the ETR is already operated 189 * from sysFS. 190 */ 191 if (val != CS_MODE_DISABLED) { 192 ret = -EINVAL; 193 goto out; 194 } 195 196 tmc_etr_enable_hw(drvdata); 197 out: 198 spin_unlock_irqrestore(&drvdata->spinlock, flags); 199 200 return ret; 201 } 202 203 static int tmc_enable_etr_sink(struct coresight_device *csdev, u32 mode) 204 { 205 switch (mode) { 206 case CS_MODE_SYSFS: 207 return tmc_enable_etr_sink_sysfs(csdev, mode); 208 case CS_MODE_PERF: 209 return tmc_enable_etr_sink_perf(csdev, mode); 210 } 211 212 /* We shouldn't be here */ 213 return -EINVAL; 214 } 215 216 static void tmc_disable_etr_sink(struct coresight_device *csdev) 217 { 218 long val; 219 unsigned long flags; 220 struct tmc_drvdata *drvdata = dev_get_drvdata(csdev->dev.parent); 221 222 spin_lock_irqsave(&drvdata->spinlock, flags); 223 if (drvdata->reading) { 224 spin_unlock_irqrestore(&drvdata->spinlock, flags); 225 return; 226 } 227 228 val = local_xchg(&drvdata->mode, CS_MODE_DISABLED); 229 /* Disable the TMC only if it needs to */ 230 if (val != CS_MODE_DISABLED) 231 tmc_etr_disable_hw(drvdata); 232 233 spin_unlock_irqrestore(&drvdata->spinlock, flags); 234 235 dev_info(drvdata->dev, "TMC-ETR disabled\n"); 236 } 237 238 static const struct coresight_ops_sink tmc_etr_sink_ops = { 239 .enable = tmc_enable_etr_sink, 240 .disable = tmc_disable_etr_sink, 241 }; 242 243 const struct coresight_ops tmc_etr_cs_ops = { 244 .sink_ops = &tmc_etr_sink_ops, 245 }; 246 247 int tmc_read_prepare_etr(struct tmc_drvdata *drvdata) 248 { 249 int ret = 0; 250 long val; 251 unsigned long flags; 252 253 /* config types are set a boot time and never change */ 254 if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) 255 return -EINVAL; 256 257 spin_lock_irqsave(&drvdata->spinlock, flags); 258 if (drvdata->reading) { 259 ret = -EBUSY; 260 goto out; 261 } 262 263 val = local_read(&drvdata->mode); 264 /* Don't interfere if operated from Perf */ 265 if (val == CS_MODE_PERF) { 266 ret = -EINVAL; 267 goto out; 268 } 269 270 /* If drvdata::buf is NULL the trace data has been read already */ 271 if (drvdata->buf == NULL) { 272 ret = -EINVAL; 273 goto out; 274 } 275 276 /* Disable the TMC if need be */ 277 if (val == CS_MODE_SYSFS) 278 tmc_etr_disable_hw(drvdata); 279 280 drvdata->reading = true; 281 out: 282 spin_unlock_irqrestore(&drvdata->spinlock, flags); 283 284 return ret; 285 } 286 287 int tmc_read_unprepare_etr(struct tmc_drvdata *drvdata) 288 { 289 unsigned long flags; 290 dma_addr_t paddr; 291 void __iomem *vaddr = NULL; 292 293 /* config types are set a boot time and never change */ 294 if (WARN_ON_ONCE(drvdata->config_type != TMC_CONFIG_TYPE_ETR)) 295 return -EINVAL; 296 297 spin_lock_irqsave(&drvdata->spinlock, flags); 298 299 /* RE-enable the TMC if need be */ 300 if (local_read(&drvdata->mode) == CS_MODE_SYSFS) { 301 /* 302 * The trace run will continue with the same allocated trace 303 * buffer. The trace buffer is cleared in tmc_etr_enable_hw(), 304 * so we don't have to explicitly clear it. Also, since the 305 * tracer is still enabled drvdata::buf can't be NULL. 306 */ 307 tmc_etr_enable_hw(drvdata); 308 } else { 309 /* 310 * The ETR is not tracing and the buffer was just read. 311 * As such prepare to free the trace buffer. 312 */ 313 vaddr = drvdata->vaddr; 314 paddr = drvdata->paddr; 315 drvdata->buf = drvdata->vaddr = NULL; 316 } 317 318 drvdata->reading = false; 319 spin_unlock_irqrestore(&drvdata->spinlock, flags); 320 321 /* Free allocated memory out side of the spinlock */ 322 if (vaddr) 323 dma_free_coherent(drvdata->dev, drvdata->size, vaddr, paddr); 324 325 return 0; 326 } 327