diff --git a/drivers/hwtracing/coresight/coresight-cti-core.c b/drivers/hwtracing/coresight/coresight-cti-core.c index 8988b2ed2ea6..f1df253019cb 100644 --- a/drivers/hwtracing/coresight/coresight-cti-core.c +++ b/drivers/hwtracing/coresight/coresight-cti-core.c @@ -69,16 +69,29 @@ void cti_write_all_hw_regs(struct cti_drvdata *drvdata) writel_relaxed(0, drvdata->base + CTICONTROL); /* write the CTI trigger registers */ - for (i = 0; i < config->nr_trig_max; i++) { - writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN(i)); - writel_relaxed(config->ctiouten[i], - drvdata->base + CTIOUTEN(i)); - } + if (drvdata->extended_cti) { + for (i = 0; i < config->nr_trig_max; i++) { + writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN_EXTENDED(i)); + writel_relaxed(config->ctiouten[i], + drvdata->base + CTIOUTEN_EXTENDED(i)); + } - /* other regs */ - writel_relaxed(config->ctigate, drvdata->base + CTIGATE); - writel_relaxed(config->asicctl, drvdata->base + ASICCTL); - writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET); + /* other regs */ + writel_relaxed(config->ctigate, drvdata->base + CTIGATE_EXTENDED); + writel_relaxed(config->asicctl, drvdata->base + ASICCTL_EXTENDED); + writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET_EXTENDED); + } else { + for (i = 0; i < config->nr_trig_max; i++) { + writel_relaxed(config->ctiinen[i], drvdata->base + CTIINEN(i)); + writel_relaxed(config->ctiouten[i], + drvdata->base + CTIOUTEN(i)); + } + + /* other regs */ + writel_relaxed(config->ctigate, drvdata->base + CTIGATE); + writel_relaxed(config->asicctl, drvdata->base + ASICCTL); + writel_relaxed(config->ctiappset, drvdata->base + CTIAPPSET); + } /* re-enable CTI */ writel_relaxed(1, drvdata->base + CTICONTROL); @@ -101,10 +114,12 @@ static int cti_enable_hw(struct cti_drvdata *drvdata) if (config->hw_enabled || !config->hw_powered) goto cti_state_unchanged; - /* claim the device */ - rc = coresight_claim_device(drvdata->csdev); - if (rc) - goto cti_err_not_enabled; + if (!drvdata->extended_cti) { + /* claim the device */ + rc = coresight_claim_device(drvdata->csdev); + if (rc) + goto cti_err_not_enabled; + } cti_write_all_hw_regs(drvdata); @@ -172,7 +187,8 @@ static int cti_disable_hw(struct cti_drvdata *drvdata) writel_relaxed(0, drvdata->base + CTICONTROL); config->hw_enabled = false; - coresight_disclaim_device_unlocked(csdev); + if (!drvdata->extended_cti) + coresight_disclaim_device_unlocked(csdev); CS_LOCK(drvdata->base); spin_unlock(&drvdata->spinlock); pm_runtime_put(dev->parent); @@ -268,8 +284,10 @@ int cti_add_connection_entry(struct device *dev, struct cti_drvdata *drvdata, cti_dev->nr_trig_con++; /* add connection usage bit info to overall info */ - drvdata->config.trig_in_use |= tc->con_in->used_mask; - drvdata->config.trig_out_use |= tc->con_out->used_mask; + bitmap_or(drvdata->config.trig_in_use, drvdata->config.trig_in_use, + tc->con_in->used_mask, drvdata->config.nr_trig_max); + bitmap_or(drvdata->config.trig_out_use, drvdata->config.trig_out_use, + tc->con_out->used_mask, drvdata->config.nr_trig_max); return 0; } @@ -312,7 +330,6 @@ int cti_add_default_connection(struct device *dev, struct cti_drvdata *drvdata) { int ret = 0; int n_trigs = drvdata->config.nr_trig_max; - u32 n_trig_mask = GENMASK(n_trigs - 1, 0); struct cti_trig_con *tc = NULL; /* @@ -323,8 +340,8 @@ int cti_add_default_connection(struct device *dev, struct cti_drvdata *drvdata) if (!tc) return -ENOMEM; - tc->con_in->used_mask = n_trig_mask; - tc->con_out->used_mask = n_trig_mask; + bitmap_fill(tc->con_in->used_mask, n_trigs); + bitmap_fill(tc->con_out->used_mask, n_trigs); ret = cti_add_connection_entry(dev, drvdata, tc, NULL, "default"); return ret; } @@ -337,7 +354,6 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, { struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *config = &drvdata->config; - u32 trig_bitmask; u32 chan_bitmask; u32 reg_value; int reg_offset; @@ -347,25 +363,27 @@ int cti_channel_trig_op(struct device *dev, enum cti_chan_op op, (trigger_idx >= config->nr_trig_max)) return -EINVAL; - trig_bitmask = BIT(trigger_idx); - /* ensure registered triggers and not out filtered */ if (direction == CTI_TRIG_IN) { - if (!(trig_bitmask & config->trig_in_use)) + if (!(test_bit(trigger_idx, config->trig_in_use))) return -EINVAL; } else { - if (!(trig_bitmask & config->trig_out_use)) + if (!(test_bit(trigger_idx, config->trig_out_use))) return -EINVAL; if ((config->trig_filter_enable) && - (config->trig_out_filter & trig_bitmask)) + test_bit(trigger_idx, config->trig_out_filter)) return -EINVAL; } /* update the local register values */ chan_bitmask = BIT(channel_idx); - reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) : - CTIOUTEN(trigger_idx)); + if (drvdata->extended_cti) + reg_offset = (direction == CTI_TRIG_IN ? CTIINEN_EXTENDED(trigger_idx) : + CTIOUTEN_EXTENDED(trigger_idx)); + else + reg_offset = (direction == CTI_TRIG_IN ? CTIINEN(trigger_idx) : + CTIOUTEN(trigger_idx)); spin_lock(&drvdata->spinlock); @@ -421,8 +439,12 @@ int cti_channel_gate_op(struct device *dev, enum cti_chan_gate_op op, } if (err == 0) { config->ctigate = reg_value; - if (cti_active(config)) - cti_write_single_reg(drvdata, CTIGATE, reg_value); + if (cti_active(config)) { + if (drvdata->extended_cti) + cti_write_single_reg(drvdata, CTIGATE_EXTENDED, reg_value); + else + cti_write_single_reg(drvdata, CTIGATE, reg_value); + } } spin_unlock(&drvdata->spinlock); return err; @@ -449,19 +471,28 @@ int cti_channel_setop(struct device *dev, enum cti_chan_set_op op, case CTI_CHAN_SET: config->ctiappset |= chan_bitmask; reg_value = config->ctiappset; - reg_offset = CTIAPPSET; + if (drvdata->extended_cti) + reg_offset = CTIAPPSET_EXTENDED; + else + reg_offset = CTIAPPSET; break; case CTI_CHAN_CLR: config->ctiappset &= ~chan_bitmask; reg_value = chan_bitmask; - reg_offset = CTIAPPCLEAR; + if (drvdata->extended_cti) + reg_offset = CTIAPPCLEAR_EXTENDED; + else + reg_offset = CTIAPPCLEAR; break; case CTI_CHAN_PULSE: config->ctiappset &= ~chan_bitmask; reg_value = chan_bitmask; - reg_offset = CTIAPPPULSE; + if (drvdata->extended_cti) + reg_offset = CTIAPPPULSE_EXTENDED; + else + reg_offset = CTIAPPPULSE; break; default: @@ -850,6 +881,11 @@ static void cti_remove(struct amba_device *adev) coresight_unregister(drvdata->csdev); } +static bool is_extended_cti(struct device *dev) +{ + return fwnode_property_present(dev->fwnode, "qcom,extended_cti"); +} + static int cti_probe(struct amba_device *adev, const struct amba_id *id) { int ret = 0; @@ -941,6 +977,7 @@ static int cti_probe(struct amba_device *adev, const struct amba_id *id) drvdata->csdev_release = drvdata->csdev->dev.release; drvdata->csdev->dev.release = cti_device_release; + drvdata->extended_cti = is_extended_cti(dev); /* all done - dec pm refcount */ pm_runtime_put(&adev->dev); dev_info(&drvdata->csdev->dev, "CTI initialized\n"); diff --git a/drivers/hwtracing/coresight/coresight-cti-platform.c b/drivers/hwtracing/coresight/coresight-cti-platform.c index ccef04f27f12..c95130e34aa3 100644 --- a/drivers/hwtracing/coresight/coresight-cti-platform.c +++ b/drivers/hwtracing/coresight/coresight-cti-platform.c @@ -136,8 +136,8 @@ static int cti_plat_create_v8_etm_connection(struct device *dev, goto create_v8_etm_out; /* build connection data */ - tc->con_in->used_mask = 0xF0; /* sigs <4,5,6,7> */ - tc->con_out->used_mask = 0xF0; /* sigs <4,5,6,7> */ + bitmap_set(tc->con_in->used_mask, 4, 4); /* sigs <4,5,6,7> */ + bitmap_set(tc->con_out->used_mask, 4, 4); /* sigs <4,5,6,7> */ /* * The EXTOUT type signals from the ETM are connected to a set of input @@ -194,10 +194,10 @@ static int cti_plat_create_v8_connections(struct device *dev, goto of_create_v8_out; /* Set the v8 PE CTI connection data */ - tc->con_in->used_mask = 0x3; /* sigs <0 1> */ + bitmap_set(tc->con_in->used_mask, 0, 2); /* sigs <0 1> */ tc->con_in->sig_types[0] = PE_DBGTRIGGER; tc->con_in->sig_types[1] = PE_PMUIRQ; - tc->con_out->used_mask = 0x7; /* sigs <0 1 2 > */ + bitmap_set(tc->con_out->used_mask, 0, 3); /* sigs <0 1 2 > */ tc->con_out->sig_types[0] = PE_EDBGREQ; tc->con_out->sig_types[1] = PE_DBGRESTART; tc->con_out->sig_types[2] = PE_CTIIRQ; @@ -213,7 +213,7 @@ static int cti_plat_create_v8_connections(struct device *dev, goto of_create_v8_out; /* filter pe_edbgreq - PE trigout sig <0> */ - drvdata->config.trig_out_filter |= 0x1; + set_bit(0, drvdata->config.trig_out_filter); of_create_v8_out: return ret; @@ -257,7 +257,7 @@ static int cti_plat_read_trig_group(struct cti_trig_grp *tgrp, if (!err) { /* set the signal usage mask */ for (idx = 0; idx < tgrp->nr_sigs; idx++) - tgrp->used_mask |= BIT(values[idx]); + set_bit(values[idx], tgrp->used_mask); } kfree(values); @@ -331,7 +331,9 @@ static int cti_plat_process_filter_sigs(struct cti_drvdata *drvdata, err = cti_plat_read_trig_group(tg, fwnode, CTI_DT_FILTER_OUT_SIGS); if (!err) - drvdata->config.trig_out_filter |= tg->used_mask; + bitmap_or(drvdata->config.trig_out_filter, + drvdata->config.trig_out_filter, + tg->used_mask, drvdata->config.nr_trig_max); kfree(tg); return err; diff --git a/drivers/hwtracing/coresight/coresight-cti-sysfs.c b/drivers/hwtracing/coresight/coresight-cti-sysfs.c index 7ff7e7780bbf..fac67c9edba9 100644 --- a/drivers/hwtracing/coresight/coresight-cti-sysfs.c +++ b/drivers/hwtracing/coresight/coresight-cti-sysfs.c @@ -208,60 +208,6 @@ static struct attribute *coresight_cti_mgmt_attrs[] = { NULL, }; -/* CTI low level programming registers */ - -/* - * Show a simple 32 bit value if enabled and powered. - * If inaccessible & pcached_val not NULL then show cached value. - */ -static ssize_t cti_reg32_show(struct device *dev, char *buf, - u32 *pcached_val, int reg_offset) -{ - u32 val = 0; - struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); - struct cti_config *config = &drvdata->config; - - spin_lock(&drvdata->spinlock); - if ((reg_offset >= 0) && cti_active(config)) { - CS_UNLOCK(drvdata->base); - val = readl_relaxed(drvdata->base + reg_offset); - if (pcached_val) - *pcached_val = val; - CS_LOCK(drvdata->base); - } else if (pcached_val) { - val = *pcached_val; - } - spin_unlock(&drvdata->spinlock); - return sprintf(buf, "%#x\n", val); -} - -/* - * Store a simple 32 bit value. - * If pcached_val not NULL, then copy to here too, - * if reg_offset >= 0 then write through if enabled. - */ -static ssize_t cti_reg32_store(struct device *dev, const char *buf, - size_t size, u32 *pcached_val, int reg_offset) -{ - unsigned long val; - struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); - struct cti_config *config = &drvdata->config; - - if (kstrtoul(buf, 0, &val)) - return -EINVAL; - - spin_lock(&drvdata->spinlock); - /* local store */ - if (pcached_val) - *pcached_val = (u32)val; - - /* write through if offset and enabled */ - if ((reg_offset >= 0) && cti_active(config)) - cti_write_single_reg(drvdata, reg_offset, val); - spin_unlock(&drvdata->spinlock); - return size; -} - /* Standard macro for simple rw cti config registers */ #define cti_config_reg32_rw(name, cfgname, offset) \ static ssize_t name##_show(struct device *dev, \ @@ -345,8 +291,13 @@ static ssize_t inen_store(struct device *dev, config->ctiinen[index] = val; /* write through if enabled */ - if (cti_active(config)) - cti_write_single_reg(drvdata, CTIINEN(index), val); + if (cti_active(config)) { + if (drvdata->extended_cti) + cti_write_single_reg(drvdata, CTIINEN_EXTENDED(index), val); + else + cti_write_single_reg(drvdata, CTIINEN(index), val); + } + spin_unlock(&drvdata->spinlock); return size; } @@ -384,8 +335,13 @@ static ssize_t outen_store(struct device *dev, config->ctiouten[index] = val; /* write through if enabled */ - if (cti_active(config)) - cti_write_single_reg(drvdata, CTIOUTEN(index), val); + if (cti_active(config)) { + if (drvdata->extended_cti) + cti_write_single_reg(drvdata, CTIOUTEN_EXTENDED(index), val); + else + cti_write_single_reg(drvdata, CTIOUTEN(index), val); + } + spin_unlock(&drvdata->spinlock); return size; } @@ -405,9 +361,143 @@ static ssize_t intack_store(struct device *dev, } static DEVICE_ATTR_WO(intack); -cti_config_reg32_rw(gate, ctigate, CTIGATE); -cti_config_reg32_rw(asicctl, asicctl, ASICCTL); -cti_config_reg32_rw(appset, ctiappset, CTIAPPSET); +static ssize_t gate_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u32 val = 0; + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cti_config *config = &drvdata->config; + + spin_lock(&drvdata->spinlock); + if (cti_active(config)) { + CS_UNLOCK(drvdata->base); + if (drvdata->extended_cti) + val = readl_relaxed(drvdata->base + CTIGATE_EXTENDED); + else + val = readl_relaxed(drvdata->base + CTIGATE); + CS_LOCK(drvdata->base); + } + spin_unlock(&drvdata->spinlock); + return scnprintf(buf, PAGE_SIZE, "%#x\n", val); + +} + +static ssize_t gate_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cti_config *config = &drvdata->config; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + /* write through if offset and enabled */ + if (cti_active(config)) { + if (drvdata->extended_cti) + cti_write_single_reg(drvdata, CTIGATE_EXTENDED, val); + else + cti_write_single_reg(drvdata, CTIGATE, val); + } + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(gate); + +static ssize_t asicctl_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u32 val = 0; + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cti_config *config = &drvdata->config; + + spin_lock(&drvdata->spinlock); + if (cti_active(config)) { + CS_UNLOCK(drvdata->base); + if (drvdata->extended_cti) + val = readl_relaxed(drvdata->base + ASICCTL_EXTENDED); + else + val = readl_relaxed(drvdata->base + ASICCTL); + CS_LOCK(drvdata->base); + } + spin_unlock(&drvdata->spinlock); + return scnprintf(buf, PAGE_SIZE, "%#x\n", val); + +} + +static ssize_t asicctl_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cti_config *config = &drvdata->config; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + /* write through if offset and enabled */ + if (cti_active(config)) { + if (drvdata->extended_cti) + cti_write_single_reg(drvdata, ASICCTL_EXTENDED, val); + else + cti_write_single_reg(drvdata, ASICCTL, val); + } + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(asicctl); + +static ssize_t appset_show(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + u32 val = 0; + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cti_config *config = &drvdata->config; + + spin_lock(&drvdata->spinlock); + if (cti_active(config)) { + CS_UNLOCK(drvdata->base); + if (drvdata->extended_cti) + val = readl_relaxed(drvdata->base + CTIAPPSET_EXTENDED); + else + val = readl_relaxed(drvdata->base + CTIAPPSET); + CS_LOCK(drvdata->base); + } + spin_unlock(&drvdata->spinlock); + return scnprintf(buf, PAGE_SIZE, "%#x\n", val); + +} + +static ssize_t appset_store(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t size) +{ + unsigned long val; + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cti_config *config = &drvdata->config; + + if (kstrtoul(buf, 0, &val)) + return -EINVAL; + + spin_lock(&drvdata->spinlock); + /* write through if offset and enabled */ + if (cti_active(config)) { + if (drvdata->extended_cti) + cti_write_single_reg(drvdata, CTIAPPSET_EXTENDED, val); + else + cti_write_single_reg(drvdata, CTIAPPSET, val); + } + spin_unlock(&drvdata->spinlock); + return size; +} +static DEVICE_ATTR_RW(appset); static ssize_t appclear_store(struct device *dev, struct device_attribute *attr, @@ -426,8 +516,12 @@ static ssize_t appclear_store(struct device *dev, config->ctiappset &= ~val; /* write through if enabled */ - if (cti_active(config)) - cti_write_single_reg(drvdata, CTIAPPCLEAR, val); + if (cti_active(config)) { + if (drvdata->extended_cti) + cti_write_single_reg(drvdata, CTIAPPCLEAR, val); + else + cti_write_single_reg(drvdata, CTIAPPCLEAR_EXTENDED, val); + } spin_unlock(&drvdata->spinlock); return size; } @@ -447,17 +541,146 @@ static ssize_t apppulse_store(struct device *dev, spin_lock(&drvdata->spinlock); /* write through if enabled */ - if (cti_active(config)) - cti_write_single_reg(drvdata, CTIAPPPULSE, val); + if (cti_active(config)) { + if (drvdata->extended_cti) + cti_write_single_reg(drvdata, CTIAPPPULSE_EXTENDED, val); + else + cti_write_single_reg(drvdata, CTIAPPPULSE, val); + } spin_unlock(&drvdata->spinlock); return size; } static DEVICE_ATTR_WO(apppulse); -coresight_cti_reg(triginstatus, CTITRIGINSTATUS); -coresight_cti_reg(trigoutstatus, CTITRIGOUTSTATUS); -coresight_cti_reg(chinstatus, CTICHINSTATUS); -coresight_cti_reg(choutstatus, CTICHOUTSTATUS); +static ssize_t triginstatus_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cti_config *config = &drvdata->config; + u32 val = 0; + u32 n, i = 0; + ssize_t len = 0; + int ret; + + ret = pm_runtime_get_sync(dev->parent); + if (ret < 0) { + pm_runtime_put_noidle(dev->parent); + return ret; + } + + spin_lock(&drvdata->spinlock); + if (drvdata->config.hw_powered) { + if (drvdata->extended_cti) { + i = (config->nr_trig_max - 1) / 32; + for (n = 0; n <= i; n++) { + val = readl_relaxed(drvdata->base + CTITRIGINSTATUS_EXTENDED(n)); + len += scnprintf(buf + len, PAGE_SIZE - len, "%u - %u : 0x%x\n", n, + ((n+1) * 32) - 1, val); + } + } else + val = readl_relaxed(drvdata->base + CTITRIGINSTATUS); + } + spin_unlock(&drvdata->spinlock); + pm_runtime_put_sync(dev->parent); + + if (drvdata->extended_cti) + return len; + else + return scnprintf(buf, PAGE_SIZE, "0x%x\n", val); +} +static DEVICE_ATTR_RO(triginstatus); + +static ssize_t trigoutstatus_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + struct cti_config *config = &drvdata->config; + u32 val = 0; + u32 n, i = 0; + ssize_t len = 0; + int ret; + + ret = pm_runtime_get_sync(dev->parent); + if (ret < 0) { + pm_runtime_put_noidle(dev->parent); + return ret; + } + + spin_lock(&drvdata->spinlock); + if (drvdata->config.hw_powered) { + if (drvdata->extended_cti) { + i = (config->nr_trig_max - 1) / 32; + for (n = 0; n <= i; n++) { + val = readl_relaxed(drvdata->base + CTITRIGOUTSTATUS_EXTENDED(n)); + len += scnprintf(buf + len, PAGE_SIZE - len, "%u - %u : 0x%x\n", n, + ((n+1) * 32) - 1, val); + } + } else + val = readl_relaxed(drvdata->base + CTITRIGOUTSTATUS); + } + spin_unlock(&drvdata->spinlock); + pm_runtime_put_sync(dev->parent); + + if (drvdata->extended_cti) + return len; + else + return scnprintf(buf, PAGE_SIZE, "0x%x\n", val); +} +static DEVICE_ATTR_RO(trigoutstatus); + +static ssize_t chinstatus_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + u32 val = 0; + int ret; + + ret = pm_runtime_get_sync(dev->parent); + if (ret < 0) { + pm_runtime_put_noidle(dev->parent); + return ret; + } + + spin_lock(&drvdata->spinlock); + if (drvdata->config.hw_powered) { + if (drvdata->extended_cti) + val = readl_relaxed(drvdata->base + CTICHINSTATUS_EXTENDED); + else + val = readl_relaxed(drvdata->base + CTICHINSTATUS); + } + spin_unlock(&drvdata->spinlock); + pm_runtime_put_sync(dev->parent); + + return scnprintf(buf, PAGE_SIZE, "0x%x\n", val); +} +static DEVICE_ATTR_RO(chinstatus); + +static ssize_t choutstatus_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); + u32 val = 0; + int ret; + + ret = pm_runtime_get_sync(dev->parent); + if (ret < 0) { + pm_runtime_put_noidle(dev->parent); + return ret; + } + + spin_lock(&drvdata->spinlock); + if (drvdata->config.hw_powered) { + if (drvdata->extended_cti) + val = readl_relaxed(drvdata->base + CTICHOUTSTATUS_EXTENDED); + else + val = readl_relaxed(drvdata->base + CTICHOUTSTATUS); + } + spin_unlock(&drvdata->spinlock); + pm_runtime_put_sync(dev->parent); + + return scnprintf(buf, PAGE_SIZE, "0x%x\n", val); +} +static DEVICE_ATTR_RO(choutstatus); /* * Define CONFIG_CORESIGHT_CTI_INTEGRATION_REGS to enable the access to the @@ -743,10 +966,8 @@ static ssize_t trigout_filtered_show(struct device *dev, struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *cfg = &drvdata->config; int size = 0, nr_trig_max = cfg->nr_trig_max; - unsigned long mask = cfg->trig_out_filter; - if (mask) - size = bitmap_print_to_pagebuf(true, buf, &mask, nr_trig_max); + size = bitmap_print_to_pagebuf(true, buf, cfg->trig_out_filter, nr_trig_max); return size; } static DEVICE_ATTR_RO(trigout_filtered); @@ -958,9 +1179,8 @@ static ssize_t trigin_sig_show(struct device *dev, struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *cfg = &drvdata->config; - unsigned long mask = con->con_in->used_mask; - return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max); + return bitmap_print_to_pagebuf(true, buf, con->con_in->used_mask, cfg->nr_trig_max); } static ssize_t trigout_sig_show(struct device *dev, @@ -972,9 +1192,8 @@ static ssize_t trigout_sig_show(struct device *dev, struct cti_trig_con *con = (struct cti_trig_con *)ext_attr->var; struct cti_drvdata *drvdata = dev_get_drvdata(dev->parent); struct cti_config *cfg = &drvdata->config; - unsigned long mask = con->con_out->used_mask; - return bitmap_print_to_pagebuf(true, buf, &mask, cfg->nr_trig_max); + return bitmap_print_to_pagebuf(true, buf, con->con_out->used_mask, cfg->nr_trig_max); } /* convert a sig type id to a name */ diff --git a/drivers/hwtracing/coresight/coresight-cti.h b/drivers/hwtracing/coresight/coresight-cti.h index acf7b545e6b9..f2913da3934b 100644 --- a/drivers/hwtracing/coresight/coresight-cti.h +++ b/drivers/hwtracing/coresight/coresight-cti.h @@ -37,6 +37,20 @@ #define CTICHOUTSTATUS 0x13C #define CTIGATE 0x140 #define ASICCTL 0x144 + +#define CTIINTACK_EXTENDED(n) (0x020 + (4 * n)) +#define CTIAPPSET_EXTENDED 0x004 +#define CTIAPPCLEAR_EXTENDED 0x008 +#define CTIAPPPULSE_EXTENDED 0x00C +#define CTIINEN_EXTENDED(n) (0x400 + (4 * n)) +#define CTIOUTEN_EXTENDED(n) (0x800 + (4 * n)) +#define CTITRIGINSTATUS_EXTENDED(n) (0x040 + (4 * n)) +#define CTITRIGOUTSTATUS_EXTENDED(n) (0x060 + (4 * n)) +#define CTICHINSTATUS_EXTENDED 0x080 +#define CTICHOUTSTATUS_EXTENDED 0x084 +#define CTIGATE_EXTENDED 0x088 +#define ASICCTL_EXTENDED 0x08c + /* Integration test registers */ #define ITCHINACK 0xEDC /* WO CTI CSSoc 400 only*/ #define ITTRIGINACK 0xEE0 /* WO CTI CSSoc 400 only*/ @@ -46,6 +60,16 @@ #define ITTRIGOUTACK 0xEF0 /* RO CTI CSSoc 400 only*/ #define ITCHIN 0xEF4 /* RO */ #define ITTRIGIN 0xEF8 /* RO */ + +#define ITCHINACK_EXTENDED 0xE70 /* WO CTI CSSoc 400 only*/ +#define ITTRIGINACK_EXTENDED(n) (0xE80 + (4 * n)) /* WO CTI CSSoc 400 only*/ +#define ITCHOUT_EXTENDED 0xE74 /* WO RW-600 */ +#define ITTRIGOUT_EXTENDED(n) (0xEA + (4 * n)) /* WO RW-600 */ +#define ITCHOUTACK_EXTENDED 0xE78 /* RO CTI CSSoc 400 only*/ +#define ITTRIGOUTACK_EXTENDED(n) (0xEC0 + (4 * n)) /* RO CTI CSSoc 400 only*/ +#define ITCHIN_EXTENDED 0xE7C /* RO */ +#define ITTRIGIN_EXTENDED(n) (0xEE0 + (4 * n)) /* RO */ + /* management registers */ #define CTIDEVAFF0 0xFA8 #define CTIDEVAFF1 0xFAC @@ -56,7 +80,7 @@ * Max of in and out defined in the DEVID register. * - pick up actual number used from .dts parameters if present. */ -#define CTIINOUTEN_MAX 32 +#define CTIINOUTEN_MAX 128 /** * Group of related trigger signals @@ -67,7 +91,7 @@ */ struct cti_trig_grp { int nr_sigs; - u32 used_mask; + DECLARE_BITMAP(used_mask, CTIINOUTEN_MAX); int sig_types[]; }; @@ -146,9 +170,9 @@ struct cti_config { bool hw_powered; /* registered triggers and filtering */ - u32 trig_in_use; - u32 trig_out_use; - u32 trig_out_filter; + DECLARE_BITMAP(trig_in_use, CTIINOUTEN_MAX); + DECLARE_BITMAP(trig_out_use, CTIINOUTEN_MAX); + DECLARE_BITMAP(trig_out_filter, CTIINOUTEN_MAX); bool trig_filter_enable; u8 xtrig_rchan_sel; @@ -179,6 +203,7 @@ struct cti_drvdata { struct cti_config config; struct list_head node; void (*csdev_release)(struct device *dev); + bool extended_cti; }; /*