mirror of
https://github.com/torvalds/linux.git
synced 2026-07-30 03:01:41 +02:00
Merge "coresight-cti: Add extended CTI support"
This commit is contained in:
commit
c675ecc323
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user