diff options
Diffstat (limited to 'drivers/hwtracing/coresight/coresight-tmc.c')
-rw-r--r-- | drivers/hwtracing/coresight/coresight-tmc.c | 67 |
1 files changed, 63 insertions, 4 deletions
diff --git a/drivers/hwtracing/coresight/coresight-tmc.c b/drivers/hwtracing/coresight/coresight-tmc.c index 1cf82fa58289..408306736fb8 100644 --- a/drivers/hwtracing/coresight/coresight-tmc.c +++ b/drivers/hwtracing/coresight/coresight-tmc.c @@ -46,8 +46,12 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata) u32 ffcr; ffcr = readl_relaxed(drvdata->base + TMC_FFCR); - ffcr |= TMC_FFCR_STOP_ON_FLUSH; - writel_relaxed(ffcr, drvdata->base + TMC_FFCR); + + if (!(drvdata->etr_options & CSETR_QUIRK_NO_STOP_FLUSH)) { + /* Its assumed that ETM is stopped as an alternative */ + ffcr |= TMC_FFCR_STOP_ON_FLUSH; + writel_relaxed(ffcr, drvdata->base + TMC_FFCR); + } ffcr |= BIT(TMC_FFCR_FLUSHMAN_BIT); writel_relaxed(ffcr, drvdata->base + TMC_FFCR); /* Ensure flush completes */ @@ -57,7 +61,8 @@ void tmc_flush_and_stop(struct tmc_drvdata *drvdata) "timeout while waiting for completion of Manual Flush\n"); } - tmc_wait_for_tmcready(drvdata); + if (!(drvdata->etr_options & CSETR_QUIRK_NO_STOP_FLUSH)) + tmc_wait_for_tmcready(drvdata); } void tmc_enable_hw(struct tmc_drvdata *drvdata) @@ -148,6 +153,11 @@ static int tmc_open(struct inode *inode, struct file *file) struct tmc_drvdata *drvdata = container_of(file->private_data, struct tmc_drvdata, miscdev); + if (drvdata->buf == NULL) { + drvdata->mode = CS_MODE_READ_PREVBOOT; + dev_info(&drvdata->csdev->dev, "TMC read mode for previous boot\n"); + } + ret = tmc_read_prepare(drvdata); if (ret) return ret; @@ -183,6 +193,10 @@ static ssize_t tmc_read(struct file *file, char __user *data, size_t len, if (actual <= 0) return 0; + if ((drvdata->etr_options & CSETR_QUIRK_SECURE_BUFF) && + tmc_copy_secure_buffer(drvdata, bufp, len)) + return -EFAULT; + if (copy_to_user(data, bufp, actual)) { dev_dbg(&drvdata->csdev->dev, "%s: copy_to_user failed\n", __func__); @@ -346,9 +360,27 @@ static ssize_t buffer_size_store(struct device *dev, static DEVICE_ATTR_RW(buffer_size); +static ssize_t tracebuffer_size_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + return -EINVAL; +} + +static ssize_t tracebuffer_size_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct tmc_drvdata *drvdata = dev_get_drvdata(dev->parent); + unsigned long val = drvdata->size; + + return sprintf(buf, "%#lx\n", val); +} +static DEVICE_ATTR_RW(tracebuffer_size); + static struct attribute *coresight_tmc_attrs[] = { &dev_attr_trigger_cntr.attr, &dev_attr_buffer_size.attr, + &dev_attr_tracebuffer_size.attr, NULL, }; @@ -425,8 +457,15 @@ static int tmc_etr_setup_caps(struct device *parent, u32 devid, void *dev_caps) static u32 tmc_etr_get_default_buffer_size(struct device *dev) { u32 size; + struct tmc_drvdata *drvdata; - if (fwnode_property_read_u32(dev->fwnode, "arm,buffer-size", &size)) + drvdata = dev_get_drvdata(dev); + if (drvdata->etr_options & CSETR_QUIRK_SECURE_BUFF) { + if (tmc_get_cpu_tracebufsize(drvdata, + &size) || !size) { + return 0; + } + } else size = SZ_1M; return size; } @@ -461,17 +500,35 @@ static int tmc_probe(struct amba_device *adev, const struct amba_id *id) spin_lock_init(&drvdata->spinlock); + drvdata->cpu = coresight_get_cpu(dev); + + /* Enable fixes for Silicon issues */ + drvdata->etr_options = coresight_get_etr_quirks(OCTEONTX_CN9XXX_ETR); + + /* Update the smp target cpu */ + drvdata->rc_cpu = is_etm_sync_mode_sw_global() ? SYNC_GLOBAL_CORE : + drvdata->cpu; + if (!is_etm_sync_mode_hw()) { + tmc_etr_add_cpumap(drvdata); /* Used for global sync mode */ + tmc_etr_timer_init(drvdata); + } + devid = readl_relaxed(drvdata->base + CORESIGHT_DEVID); drvdata->config_type = BMVAL(devid, 6, 7); drvdata->memwidth = tmc_get_memwidth(devid); /* This device is not associated with a session */ drvdata->pid = -1; + drvdata->formatter_en = !(readl_relaxed(drvdata->base + TMC_FFSR) & + TMC_FFSR_FT_NOT_PRESENT); if (drvdata->config_type == TMC_CONFIG_TYPE_ETR) drvdata->size = tmc_etr_get_default_buffer_size(dev); else drvdata->size = readl_relaxed(drvdata->base + TMC_RSZ) * 4; + /* Keep cache lock disabled by default */ + drvdata->cache_lock_en = false; + desc.dev = dev; desc.groups = coresight_tmc_groups; @@ -546,6 +603,8 @@ static const struct amba_id tmc_ids[] = { CS_AMBA_ID(0x000bb9e9), /* Coresight SoC 600 TMC-ETF */ CS_AMBA_ID(0x000bb9ea), + /* Marvell OcteonTx CN9xxx */ + CS_AMBA_ID_DATA(OCTEONTX_CN9XXX_ETR, (unsigned long)OCTEONTX_CN9XXX_ETR_CAPS), { 0, 0}, }; |