|
@@ -46,7 +46,6 @@
|
|
|
* @event_sel: Event selected for configured counter
|
|
|
* @filter_en: Filter activation flag for configured counter
|
|
|
* @filter_sel: Filter applied for configured counter
|
|
|
- * @ports_supported: Ports reserved for configured counter
|
|
|
* @counter_dump: Cumulative counter dump
|
|
|
*/
|
|
|
struct llcc_perfmon_counter_map {
|
|
@@ -54,7 +53,6 @@ struct llcc_perfmon_counter_map {
|
|
|
unsigned int event_sel;
|
|
|
bool filter_en;
|
|
|
u8 filter_sel;
|
|
|
- u16 ports_supported;
|
|
|
unsigned long long counter_dump[NUM_CHANNELS];
|
|
|
};
|
|
|
|
|
@@ -89,8 +87,8 @@ enum fltr_config {
|
|
|
* @port_ops: struct event_port_ops
|
|
|
* @configured: Mapping of configured event counters
|
|
|
* @configured_cntrs: Count of configured counters.
|
|
|
+ * @removed_cntrs: Count of removed counter configurations.
|
|
|
* @enables_port: Port enabled for perfmon configuration
|
|
|
- * @filtered_ports: Port filter enabled
|
|
|
* @port_filter_sel: Port filter enabled for Filter0 and Filter1
|
|
|
* @filters_applied: List of all filters applied on ports
|
|
|
* @fltr_logic: Filter selection logic to support existing Filter 0 approach
|
|
@@ -113,8 +111,8 @@ struct llcc_perfmon_private {
|
|
|
struct event_port_ops *port_ops[MAX_NUMBER_OF_PORTS];
|
|
|
struct llcc_perfmon_counter_map configured[MAX_CNTR];
|
|
|
unsigned int configured_cntrs;
|
|
|
+ unsigned int removed_cntrs;
|
|
|
unsigned int enables_port;
|
|
|
- unsigned int filtered_ports;
|
|
|
unsigned int port_filter_sel[MAX_FILTERS_TYPE];
|
|
|
u8 filters_applied[MAX_NUMBER_OF_PORTS][MAX_FILTERS][MAX_FILTERS_TYPE];
|
|
|
enum fltr_config fltr_logic;
|
|
@@ -299,6 +297,10 @@ static void remove_counters(struct llcc_perfmon_private *llcc_priv)
|
|
|
/* Remove the counters configured for ports */
|
|
|
for (i = 0; i < llcc_priv->configured_cntrs - 1; i++) {
|
|
|
counter_map = &llcc_priv->configured[i];
|
|
|
+ /* In case the port configuration is already removed, skip */
|
|
|
+ if (counter_map->port_sel == MAX_NUMBER_OF_PORTS)
|
|
|
+ continue;
|
|
|
+
|
|
|
port_ops = llcc_priv->port_ops[counter_map->port_sel];
|
|
|
port_ops->event_config(llcc_priv, 0, &i, false);
|
|
|
pr_info("removed counter %2d for event %2ld from port %2ld\n", i,
|
|
@@ -325,6 +327,19 @@ static void remove_counters(struct llcc_perfmon_private *llcc_priv)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+static bool find_filter_index(const char *token, u8 *filter_idx)
|
|
|
+{
|
|
|
+ if (sysfs_streq(token, "FILTER0")) {
|
|
|
+ *filter_idx = FILTER_0;
|
|
|
+ return true;
|
|
|
+ } else if (sysfs_streq(token, "FILTER1")) {
|
|
|
+ *filter_idx = FILTER_1;
|
|
|
+ return true;
|
|
|
+ } else {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
static ssize_t perfmon_configure_store(struct device *dev,
|
|
|
struct device_attribute *attr, const char *buf, size_t count)
|
|
|
{
|
|
@@ -335,15 +350,38 @@ static ssize_t perfmon_configure_store(struct device *dev,
|
|
|
unsigned long port_sel, event_sel;
|
|
|
uint32_t val, offset;
|
|
|
char *token, *delim = DELIM_CHAR;
|
|
|
+ u8 filter_idx = FILTER_0;
|
|
|
+ bool multi_fltr_flag = false;
|
|
|
|
|
|
mutex_lock(&llcc_priv->mutex);
|
|
|
- if (llcc_priv->configured_cntrs) {
|
|
|
+ if (llcc_priv->configured_cntrs == MAX_CNTR - 1) {
|
|
|
pr_err("Counters configured already, remove & try again\n");
|
|
|
mutex_unlock(&llcc_priv->mutex);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ /* Cheking whether an existing counter configuration is present, if present initializing
|
|
|
+ * the count to number of configured counters - 1 to overwrite the last configured cyclic
|
|
|
+ * counter. Cyclic count will be configured to the last counter available.
|
|
|
+ */
|
|
|
+ if (llcc_priv->configured_cntrs)
|
|
|
+ j = llcc_priv->configured_cntrs - 1;
|
|
|
+
|
|
|
token = strsep((char **)&buf, delim);
|
|
|
+ /* Getting filter information if provided */
|
|
|
+ if (strlen(token) == strlen("FILTERX")) {
|
|
|
+ if (llcc_priv->fltr_logic != multiple_filtr) {
|
|
|
+ pr_err("Error Multifilter configuration not present\n");
|
|
|
+ goto out_configure;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!find_filter_index(token, &filter_idx)) {
|
|
|
+ pr_err("Invalid Filter Index, supported are FILTER0/1\n");
|
|
|
+ goto out_configure;
|
|
|
+ }
|
|
|
+ multi_fltr_flag = true;
|
|
|
+ token = strsep((char **)&buf, delim);
|
|
|
+ }
|
|
|
|
|
|
while (token != NULL) {
|
|
|
if (kstrtoul(token, 0, &port_sel))
|
|
@@ -352,6 +390,14 @@ static ssize_t perfmon_configure_store(struct device *dev,
|
|
|
if (port_sel >= llcc_priv->port_configd)
|
|
|
break;
|
|
|
|
|
|
+ /* Checking whether given filter is enabled for the port */
|
|
|
+ if (multi_fltr_flag &&
|
|
|
+ !(llcc_priv->port_filter_sel[filter_idx] & (1 << port_sel))) {
|
|
|
+ pr_err("Filter not configured for given port, removing configurations\n");
|
|
|
+ remove_counters(llcc_priv);
|
|
|
+ goto out_configure;
|
|
|
+ }
|
|
|
+
|
|
|
token = strsep((char **)&buf, delim);
|
|
|
if (token == NULL)
|
|
|
break;
|
|
@@ -376,30 +422,16 @@ static ssize_t perfmon_configure_store(struct device *dev,
|
|
|
counter_map = &llcc_priv->configured[j];
|
|
|
counter_map->port_sel = port_sel;
|
|
|
counter_map->event_sel = event_sel;
|
|
|
-
|
|
|
- /* Conflict in Filter selection logic */
|
|
|
- if (counter_map->filter_en && !(counter_map->ports_supported & (1 << port_sel))) {
|
|
|
- pr_err("Counter %hhu is not reserved for port %hhu. %s\n", j, port_sel,
|
|
|
- "Reversing the configured counters");
|
|
|
-
|
|
|
- for (k = 0; k < j; k++) {
|
|
|
- counter_map = &llcc_priv->configured[k];
|
|
|
- port_ops = llcc_priv->port_ops[counter_map->port_sel];
|
|
|
- port_ops->event_config(llcc_priv, counter_map->event_sel,
|
|
|
- &k, false);
|
|
|
- pr_info("Removed counter %2d for event %2ld from port %ld\n",
|
|
|
- k, counter_map->event_sel, counter_map->port_sel);
|
|
|
- }
|
|
|
-
|
|
|
- /* Removing configured filters as well */
|
|
|
- remove_filters(llcc_priv);
|
|
|
- goto out_configure;
|
|
|
+ if (multi_fltr_flag) {
|
|
|
+ counter_map->filter_en = true;
|
|
|
+ counter_map->filter_sel = filter_idx;
|
|
|
}
|
|
|
|
|
|
for (k = 0; k < llcc_priv->num_banks; k++)
|
|
|
counter_map->counter_dump[k] = 0;
|
|
|
|
|
|
port_ops = llcc_priv->port_ops[port_sel];
|
|
|
+ /* if any perfmon configuration fails, remove the existing configurations */
|
|
|
if (!port_ops->event_config(llcc_priv, event_sel, &j, true)) {
|
|
|
llcc_priv->configured_cntrs = ++j;
|
|
|
remove_counters(llcc_priv);
|
|
@@ -441,6 +473,8 @@ static ssize_t perfmon_remove_store(struct device *dev,
|
|
|
unsigned long port_sel, event_sel;
|
|
|
char *token, *delim = DELIM_CHAR;
|
|
|
uint32_t offset;
|
|
|
+ u8 filter_idx = FILTER_0;
|
|
|
+ bool multi_fltr_flag = false, filter_en = false;
|
|
|
|
|
|
mutex_lock(&llcc_priv->mutex);
|
|
|
if (!llcc_priv->configured_cntrs) {
|
|
@@ -449,14 +483,35 @@ static ssize_t perfmon_remove_store(struct device *dev,
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
|
|
|
+ /* Checking if counters were removed earlier, setting the count value to next counter */
|
|
|
+ if (llcc_priv->removed_cntrs &&
|
|
|
+ llcc_priv->removed_cntrs < (llcc_priv->configured_cntrs - MAX_CLOCK_CNTR))
|
|
|
+ j = llcc_priv->removed_cntrs;
|
|
|
+
|
|
|
token = strsep((char **)&buf, delim);
|
|
|
|
|
|
/* Case for removing all the counters at once */
|
|
|
if (token && sysfs_streq(token, "REMOVE")) {
|
|
|
+ pr_info("Removing all configured counters and Filters\n");
|
|
|
remove_counters(llcc_priv);
|
|
|
goto out_remove_store;
|
|
|
}
|
|
|
|
|
|
+ /* Getting filter information if provided */
|
|
|
+ if (strlen(token) == strlen("FILTERX")) {
|
|
|
+ if (llcc_priv->fltr_logic != multiple_filtr) {
|
|
|
+ pr_err("Error! Multifilter configuration not present\n");
|
|
|
+ goto out_remove_store_err;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (!find_filter_index(token, &filter_idx)) {
|
|
|
+ pr_err("Error! Invalid Filter Index, supported are FILTER0/1\n");
|
|
|
+ goto out_remove_store_err;
|
|
|
+ }
|
|
|
+ multi_fltr_flag = true;
|
|
|
+ token = strsep((char **)&buf, delim);
|
|
|
+ }
|
|
|
+
|
|
|
while (token != NULL) {
|
|
|
if (kstrtoul(token, 0, &port_sel))
|
|
|
break;
|
|
@@ -464,6 +519,34 @@ static ssize_t perfmon_remove_store(struct device *dev,
|
|
|
if (port_sel >= llcc_priv->port_configd)
|
|
|
break;
|
|
|
|
|
|
+ /* Counter mapping for last removed counter */
|
|
|
+ counter_map = &llcc_priv->configured[j];
|
|
|
+
|
|
|
+ /* Getting filter activation status for given port and filter type 0/1 */
|
|
|
+ if (counter_map->filter_en)
|
|
|
+ filter_en = llcc_priv->port_filter_sel[counter_map->filter_sel] &
|
|
|
+ (1 << port_sel);
|
|
|
+
|
|
|
+ /* If multifilters format is used to remove perfmon configuration checking if given
|
|
|
+ * port is same as configured port on current counter checking if filter is enabled
|
|
|
+ * on current counter for given port with same filter type FILTER0/FILTER1
|
|
|
+ */
|
|
|
+ if (counter_map->port_sel == port_sel) {
|
|
|
+ if (multi_fltr_flag && !filter_en) {
|
|
|
+ pr_err("Error! filter not present counter:%u for port:%u\n", j,
|
|
|
+ port_sel);
|
|
|
+ goto out_remove_store_err;
|
|
|
+ } else if (!multi_fltr_flag && filter_en) {
|
|
|
+ pr_err("Error! Filter is present on counter:%u for port:%u\n", j,
|
|
|
+ port_sel);
|
|
|
+ goto out_remove_store_err;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ pr_err("Error! Given port %u is not configured on counter %u\n", port_sel,
|
|
|
+ j);
|
|
|
+ goto out_remove_store_err;
|
|
|
+ }
|
|
|
+
|
|
|
token = strsep((char **)&buf, delim);
|
|
|
if (token == NULL)
|
|
|
break;
|
|
@@ -486,11 +569,11 @@ static ssize_t perfmon_remove_store(struct device *dev,
|
|
|
break;
|
|
|
|
|
|
/* put dummy values */
|
|
|
- counter_map = &llcc_priv->configured[j];
|
|
|
counter_map->port_sel = MAX_NUMBER_OF_PORTS;
|
|
|
counter_map->event_sel = 0;
|
|
|
port_ops = llcc_priv->port_ops[port_sel];
|
|
|
port_ops->event_config(llcc_priv, event_sel, &j, false);
|
|
|
+ llcc_priv->removed_cntrs++;
|
|
|
pr_info("removed counter %2d for event %2ld from port %2ld\n", j++, event_sel,
|
|
|
port_sel);
|
|
|
if ((llcc_priv->enables_port & (1 << port_sel)) && port_ops->event_enable)
|
|
@@ -499,66 +582,24 @@ static ssize_t perfmon_remove_store(struct device *dev,
|
|
|
llcc_priv->enables_port &= ~(1 << port_sel);
|
|
|
}
|
|
|
|
|
|
- /* remove clock event */
|
|
|
- offset = PERFMON_COUNTER_n_CONFIG(llcc_priv->drv_ver, j);
|
|
|
- llcc_bcast_write(llcc_priv, offset, 0);
|
|
|
- llcc_priv->configured_cntrs = 0;
|
|
|
+ /* If count reached to configured counters then removing clock event, else updating the
|
|
|
+ * removed counters list to support next removal configuraiton
|
|
|
+ */
|
|
|
+ if (j == llcc_priv->configured_cntrs - 1) {
|
|
|
+ pr_info("All couters removed, removing last cyclic counter\n");
|
|
|
+ offset = PERFMON_COUNTER_n_CONFIG(llcc_priv->drv_ver, j);
|
|
|
+ llcc_bcast_write(llcc_priv, offset, 0);
|
|
|
+ llcc_priv->configured_cntrs = 0;
|
|
|
+ llcc_priv->removed_cntrs = 0;
|
|
|
+ }
|
|
|
|
|
|
out_remove_store:
|
|
|
mutex_unlock(&llcc_priv->mutex);
|
|
|
return count;
|
|
|
-}
|
|
|
-
|
|
|
-static int cntr_fltr_select(const char *buf, struct llcc_perfmon_private *llcc_priv,
|
|
|
- u8 filter_idx, unsigned long ports, u16 *cntrs_res_temp, bool enable)
|
|
|
-{
|
|
|
- char *token, *delim = DELIM_CHAR;
|
|
|
- int ret = -EINVAL;
|
|
|
- unsigned long long cntr;
|
|
|
-
|
|
|
- token = strsep((char **)&buf, delim);
|
|
|
-
|
|
|
- /*
|
|
|
- * For special cases where counter reservation is not needed and multiple filters are
|
|
|
- * required on a given port
|
|
|
- */
|
|
|
- if (token == NULL) {
|
|
|
- pr_info("Selected filter configuration without counters reservation\n");
|
|
|
- ret = 0;
|
|
|
- }
|
|
|
-
|
|
|
- while (token != NULL) {
|
|
|
- if (kstrtoull(token, 0, &cntr)) {
|
|
|
- pr_err("filter configuration failed, Wrong format\n");
|
|
|
- return ret;
|
|
|
- }
|
|
|
-
|
|
|
- if (enable) {
|
|
|
- if (!llcc_priv->configured[cntr].filter_en) {
|
|
|
- llcc_priv->configured[cntr].filter_en = true;
|
|
|
- llcc_priv->configured[cntr].filter_sel = filter_idx;
|
|
|
- llcc_priv->configured[cntr].ports_supported = ports;
|
|
|
- *cntrs_res_temp |= (1 << cntr);
|
|
|
- ret = 0;
|
|
|
- } else {
|
|
|
- pr_err("Conflict, counter already configured for filter\n");
|
|
|
- ret = -EINVAL;
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (llcc_priv->configured[cntr].filter_en &&
|
|
|
- llcc_priv->configured[cntr].filter_sel == filter_idx) {
|
|
|
- llcc_priv->configured[cntr].filter_en = false;
|
|
|
- ret = 0;
|
|
|
- } else {
|
|
|
- pr_err("Conflict, Filter counter mismatch, removal failed\n");
|
|
|
- ret = -EINVAL;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- token = strsep((char **)&buf, delim);
|
|
|
- }
|
|
|
-
|
|
|
- return ret;
|
|
|
+out_remove_store_err:
|
|
|
+ remove_counters(llcc_priv);
|
|
|
+ mutex_unlock(&llcc_priv->mutex);
|
|
|
+ return -EINVAL;
|
|
|
}
|
|
|
|
|
|
static enum filter_type find_filter_type(char *filter)
|
|
@@ -589,18 +630,6 @@ static enum filter_type find_filter_type(char *filter)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
-static bool find_filter_index(const char *token, u8 *filter_idx)
|
|
|
-{
|
|
|
- if (sysfs_streq(token, "FILTER0"))
|
|
|
- return true;
|
|
|
- else if (sysfs_streq(token, "FILTER1"))
|
|
|
- *filter_idx = FILTER_1;
|
|
|
- else
|
|
|
- return false;
|
|
|
-
|
|
|
- return true;
|
|
|
-}
|
|
|
-
|
|
|
static ssize_t perfmon_filter_config_store(struct device *dev,
|
|
|
struct device_attribute *attr, const char *buf,
|
|
|
size_t count)
|
|
@@ -612,7 +641,6 @@ static ssize_t perfmon_filter_config_store(struct device *dev,
|
|
|
char *token, *delim = DELIM_CHAR;
|
|
|
enum filter_type fil_applied = UNKNOWN_FILTER;
|
|
|
u8 filter_idx = 0, i;
|
|
|
- u16 cntrs_res_temp = 0;
|
|
|
bool filter_status;
|
|
|
|
|
|
if (llcc_priv->configured_cntrs) {
|
|
@@ -677,12 +705,6 @@ static ssize_t perfmon_filter_config_store(struct device *dev,
|
|
|
goto filter_config_free;
|
|
|
}
|
|
|
|
|
|
- if (cntr_fltr_select(buf, llcc_priv, filter_idx, port_filter_en,
|
|
|
- &cntrs_res_temp, true)) {
|
|
|
- pr_err("Counter values not provided, try again\n");
|
|
|
- goto filter_config_free;
|
|
|
- }
|
|
|
-
|
|
|
llcc_priv->fltr_logic = multiple_filtr;
|
|
|
pr_info("Selective filter configuration selected\n");
|
|
|
break;
|
|
@@ -836,9 +858,6 @@ static ssize_t perfmon_filter_remove_store(struct device *dev,
|
|
|
goto filter_remove_free;
|
|
|
}
|
|
|
|
|
|
- if (cntr_fltr_select(buf, llcc_priv, filter_idx, port_filter_en, NULL,
|
|
|
- false))
|
|
|
- goto filter_remove_free;
|
|
|
break;
|
|
|
}
|
|
|
|
|
@@ -1121,10 +1140,9 @@ static bool feac_event_config(struct llcc_perfmon_private *llcc_priv,
|
|
|
bool enable)
|
|
|
{
|
|
|
uint32_t val = 0, mask_val, offset;
|
|
|
- int filter_en, filter_sel;
|
|
|
+ u8 filter_en, filter_sel = FILTER_0;
|
|
|
|
|
|
- filter_en = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_FEAC);
|
|
|
- filter_sel = FILTER_0;
|
|
|
+ filter_en = llcc_priv->port_filter_sel[filter_sel] & (1 << EVENT_PORT_FEAC);
|
|
|
if (llcc_priv->fltr_logic == multiple_filtr) {
|
|
|
filter_en = llcc_priv->configured[*counter_num].filter_en;
|
|
|
filter_sel = llcc_priv->configured[*counter_num].filter_sel;
|
|
@@ -1173,16 +1191,16 @@ static void feac_event_enable(struct llcc_perfmon_private *llcc_priv,
|
|
|
bool enable)
|
|
|
{
|
|
|
uint32_t val = 0, val_cfg1 = 0, mask_val = 0, offset;
|
|
|
- bool filter_0 = false, filter_1 = false;
|
|
|
+ bool prof_cfg_filter = false, prof_cfg1_filter1 = false;
|
|
|
|
|
|
- filter_0 = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_FEAC);
|
|
|
- filter_1 = llcc_priv->port_filter_sel[1] & (1 << EVENT_PORT_FEAC);
|
|
|
+ prof_cfg_filter = llcc_priv->port_filter_sel[FILTER_0] & (1 << EVENT_PORT_FEAC);
|
|
|
+ prof_cfg1_filter1 = llcc_priv->port_filter_sel[FILTER_1] & (1 << EVENT_PORT_FEAC);
|
|
|
|
|
|
val = (BYTE_SCALING << BYTE_SCALING_SHIFT) | (BEAT_SCALING << BEAT_SCALING_SHIFT);
|
|
|
val_cfg1 = (BYTE_SCALING << BYTE_SCALING_SHIFT) | (BEAT_SCALING << BEAT_SCALING_SHIFT);
|
|
|
mask_val = PROF_CFG_BEAT_SCALING_MASK | PROF_CFG_BYTE_SCALING_MASK | PROF_CFG_EN_MASK;
|
|
|
|
|
|
- if (filter_0 || filter_1) {
|
|
|
+ if (prof_cfg_filter || prof_cfg1_filter1) {
|
|
|
if (llcc_priv->version == REV_0) {
|
|
|
mask_val |= FEAC_SCALING_FILTER_SEL_MASK | FEAC_SCALING_FILTER_EN_MASK;
|
|
|
val |= (FILTER_0 << FEAC_SCALING_FILTER_SEL_SHIFT) |
|
|
@@ -1195,7 +1213,7 @@ static void feac_event_enable(struct llcc_perfmon_private *llcc_priv,
|
|
|
val |= FEAC_WR_BEAT_FILTER_EN | FEAC_WR_BYTE_FILTER_EN |
|
|
|
FEAC_RD_BEAT_FILTER_EN | FEAC_RD_BYTE_FILTER_EN;
|
|
|
|
|
|
- if (filter_0 && filter_1) {
|
|
|
+ if (prof_cfg_filter && prof_cfg1_filter1) {
|
|
|
val_cfg1 = val;
|
|
|
val |= (FILTER_0 << FEAC_WR_BEAT_FILTER_SEL_SHIFT) |
|
|
|
(FILTER_0 << FEAC_WR_BYTE_FILTER_SEL_SHIFT) |
|
|
@@ -1205,12 +1223,12 @@ static void feac_event_enable(struct llcc_perfmon_private *llcc_priv,
|
|
|
(FILTER_1 << FEAC_WR_BYTE_FILTER_SEL_SHIFT) |
|
|
|
(FILTER_1 << FEAC_RD_BEAT_FILTER_SEL_SHIFT) |
|
|
|
(FILTER_1 << FEAC_RD_BYTE_FILTER_SEL_SHIFT);
|
|
|
- } else if (filter_1) {
|
|
|
+ } else if (prof_cfg1_filter1) {
|
|
|
val |= (FILTER_1 << FEAC_WR_BEAT_FILTER_SEL_SHIFT) |
|
|
|
(FILTER_1 << FEAC_WR_BYTE_FILTER_SEL_SHIFT) |
|
|
|
(FILTER_1 << FEAC_RD_BEAT_FILTER_SEL_SHIFT) |
|
|
|
(FILTER_1 << FEAC_RD_BYTE_FILTER_SEL_SHIFT);
|
|
|
- } else if (filter_0) {
|
|
|
+ } else if (prof_cfg_filter) {
|
|
|
val |= (FILTER_0 << FEAC_WR_BEAT_FILTER_SEL_SHIFT) |
|
|
|
(FILTER_0 << FEAC_WR_BYTE_FILTER_SEL_SHIFT) |
|
|
|
(FILTER_0 << FEAC_RD_BEAT_FILTER_SEL_SHIFT) |
|
|
@@ -1230,7 +1248,7 @@ static void feac_event_enable(struct llcc_perfmon_private *llcc_priv,
|
|
|
* filter0 & 1 can be applied on PROF_CFG and PROG_CFG1 respectively. Otherwise for a
|
|
|
* single applied filter only PROF_CFG will be used for either filter 0 or 1
|
|
|
*/
|
|
|
- if ((llcc_priv->version >= REV_2) && (filter_0 && filter_1)) {
|
|
|
+ if (llcc_priv->version >= REV_2 && (prof_cfg_filter && prof_cfg1_filter1)) {
|
|
|
offset = FEAC_PROF_CFG(llcc_priv->drv_ver);
|
|
|
llcc_bcast_modify(llcc_priv, offset, val, mask_val);
|
|
|
mask_val &= ~PROF_CFG_EN_MASK;
|
|
@@ -1395,10 +1413,9 @@ static bool ferc_event_config(struct llcc_perfmon_private *llcc_priv,
|
|
|
bool enable)
|
|
|
{
|
|
|
uint32_t val = 0, mask_val, offset;
|
|
|
- int filter_en, filter_sel;
|
|
|
+ u8 filter_en, filter_sel = FILTER_0;
|
|
|
|
|
|
- filter_en = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_FERC);
|
|
|
- filter_sel = FILTER_0;
|
|
|
+ filter_en = llcc_priv->port_filter_sel[filter_sel] & (1 << EVENT_PORT_FERC);
|
|
|
if (llcc_priv->fltr_logic == multiple_filtr) {
|
|
|
filter_en = llcc_priv->configured[*counter_num].filter_en;
|
|
|
filter_sel = llcc_priv->configured[*counter_num].filter_sel;
|
|
@@ -1468,10 +1485,9 @@ static bool fewc_event_config(struct llcc_perfmon_private *llcc_priv,
|
|
|
bool enable)
|
|
|
{
|
|
|
uint32_t val = 0, mask_val, offset;
|
|
|
- int filter_en, filter_sel;
|
|
|
+ u8 filter_en, filter_sel = FILTER_0;
|
|
|
|
|
|
- filter_en = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_FEWC);
|
|
|
- filter_sel = FILTER_0;
|
|
|
+ filter_en = llcc_priv->port_filter_sel[filter_sel] & (1 << EVENT_PORT_FEWC);
|
|
|
if (llcc_priv->fltr_logic == multiple_filtr) {
|
|
|
filter_en = llcc_priv->configured[*counter_num].filter_en;
|
|
|
filter_sel = llcc_priv->configured[*counter_num].filter_sel;
|
|
@@ -1530,11 +1546,10 @@ static bool beac_event_config(struct llcc_perfmon_private *llcc_priv,
|
|
|
uint32_t valcfg = 0, mask_valcfg = 0;
|
|
|
unsigned int mc_cnt, offset;
|
|
|
struct llcc_perfmon_counter_map *counter_map;
|
|
|
- int filter_en, filter_sel;
|
|
|
+ u8 filter_en, filter_sel = FILTER_0;
|
|
|
uint32_t mask_val_cfg, val_cfg0 = 0, val_cfg1 = 0;
|
|
|
|
|
|
- filter_en = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_BEAC);
|
|
|
- filter_sel = FILTER_0;
|
|
|
+ filter_en = llcc_priv->port_filter_sel[filter_sel] & (1 << EVENT_PORT_BEAC);
|
|
|
if (llcc_priv->fltr_logic == multiple_filtr) {
|
|
|
filter_en = llcc_priv->configured[*counter_num].filter_en;
|
|
|
filter_sel = llcc_priv->configured[*counter_num].filter_sel;
|
|
@@ -1776,10 +1791,9 @@ static bool berc_event_config(struct llcc_perfmon_private *llcc_priv,
|
|
|
bool enable)
|
|
|
{
|
|
|
uint32_t val = 0, mask_val, offset;
|
|
|
- int filter_en, filter_sel;
|
|
|
+ u8 filter_en, filter_sel = FILTER_0;
|
|
|
|
|
|
- filter_en = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_BERC);
|
|
|
- filter_sel = FILTER_0;
|
|
|
+ filter_en = llcc_priv->port_filter_sel[filter_sel] & (1 << EVENT_PORT_BERC);
|
|
|
if (llcc_priv->fltr_logic == multiple_filtr) {
|
|
|
filter_en = llcc_priv->configured[*counter_num].filter_en;
|
|
|
filter_sel = llcc_priv->configured[*counter_num].filter_sel;
|
|
@@ -1849,10 +1863,9 @@ static bool trp_event_config(struct llcc_perfmon_private *llcc_priv,
|
|
|
bool enable)
|
|
|
{
|
|
|
uint32_t val = 0, mask_val;
|
|
|
- int filter_en, filter_sel;
|
|
|
+ u8 filter_en, filter_sel = FILTER_0;
|
|
|
|
|
|
- filter_en = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_TRP);
|
|
|
- filter_sel = FILTER_0;
|
|
|
+ filter_en = llcc_priv->port_filter_sel[filter_sel] & (1 << EVENT_PORT_TRP);
|
|
|
if (llcc_priv->fltr_logic == multiple_filtr) {
|
|
|
filter_en = llcc_priv->configured[*counter_num].filter_en;
|
|
|
filter_sel = llcc_priv->configured[*counter_num].filter_sel;
|
|
@@ -1952,10 +1965,9 @@ static bool drp_event_config(struct llcc_perfmon_private *llcc_priv,
|
|
|
bool enable)
|
|
|
{
|
|
|
uint32_t val = 0, mask_val, offset;
|
|
|
- int filter_en, filter_sel;
|
|
|
+ u8 filter_en, filter_sel = FILTER_0;
|
|
|
|
|
|
- filter_en = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_DRP);
|
|
|
- filter_sel = FILTER_0;
|
|
|
+ filter_en = llcc_priv->port_filter_sel[filter_sel] & (1 << EVENT_PORT_DRP);
|
|
|
if (llcc_priv->fltr_logic == multiple_filtr) {
|
|
|
filter_en = llcc_priv->configured[*counter_num].filter_en;
|
|
|
filter_sel = llcc_priv->configured[*counter_num].filter_sel;
|
|
@@ -2007,10 +2019,9 @@ static bool pmgr_event_config(struct llcc_perfmon_private *llcc_priv,
|
|
|
bool enable)
|
|
|
{
|
|
|
uint32_t val = 0, mask_val, offset;
|
|
|
- int filter_en, filter_sel;
|
|
|
+ u8 filter_en, filter_sel = FILTER_0;
|
|
|
|
|
|
- filter_en = llcc_priv->port_filter_sel[0] & (1 << EVENT_PORT_PMGR);
|
|
|
- filter_sel = FILTER_0;
|
|
|
+ filter_en = llcc_priv->port_filter_sel[filter_sel] & (1 << EVENT_PORT_PMGR);
|
|
|
if (llcc_priv->fltr_logic == multiple_filtr) {
|
|
|
filter_en = llcc_priv->configured[*counter_num].filter_en;
|
|
|
filter_sel = llcc_priv->configured[*counter_num].filter_sel;
|