Loading drivers/media/platform/msm/broadcast/tspp2.c +119 −72 Original line number Diff line number Diff line Loading @@ -200,7 +200,7 @@ enum tspp2_operation_opcode { /* Bits for TSPP2_FILTER_ENTRY1 register */ #define FILTER_ENTRY1_CONTEXT_OFFS 0 /* Filter counter register definitions: n = 0..127 */ /* Filter context-based counter register definitions: n = 0..127 */ #define TSPP2_FILTER_TSP_SYNC_ERROR(n) (0x4000 + ((n) << 2)) #define TSPP2_FILTER_ERRED_TSP(n) (0x4200 + ((n) << 2)) #define TSPP2_FILTER_DISCONTINUITIES(n) (0x4400 + ((n) << 2)) Loading Loading @@ -733,12 +733,12 @@ struct tspp2_pipe_irq_stats { }; /** * struct tspp2_filter_irq_stats - Filter interrupt statistics counters * struct tspp2_filter_context_irq_stats - Filter interrupt statistics counters * * @sc_go_high: Scrambling bits change from clear to encrypted. * @sc_go_low: Scrambling bits change from encrypted to clear. */ struct tspp2_filter_irq_stats { struct tspp2_filter_context_irq_stats { u32 sc_go_high; u32 sc_go_low; }; Loading @@ -750,14 +750,14 @@ struct tspp2_filter_irq_stats { * @src: Memory source interrupt statistics counters * @kt: Key table interrupt statistics counters * @pipe: Pipe interrupt statistics counters * @filter: Filter interrupt statistics counters * @ctx: Filter context interrupt statistics counters */ struct tspp2_irq_stats { struct tspp2_global_irq_stats global; struct tspp2_src_irq_stats src[TSPP2_NUM_MEM_INPUTS]; struct tspp2_keytable_irq_stats kt[TSPP2_NUM_KEYTABLES]; struct tspp2_pipe_irq_stats pipe[TSPP2_NUM_PIPES]; struct tspp2_filter_irq_stats filter[TSPP2_NUM_HW_FILTERS]; struct tspp2_filter_context_irq_stats ctx[TSPP2_NUM_CONTEXTS]; }; /** Loading Loading @@ -1226,6 +1226,45 @@ static int filter_debugfs_print(struct seq_file *s, void *p) seq_printf(s, "raw_op_set: %d\n", filter->raw_op_set); seq_printf(s, "pes_tx_op_set: %d\n", filter->pes_tx_op_set); seq_printf(s, "Status: %s\n", filter->enabled ? "enabled" : "disabled"); if (filter->enabled) { seq_printf(s, "Filter context-based counters, context %d\n", filter->context); seq_printf(s, "filter_tsp_sync_err = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_TSP_SYNC_ERROR(filter->context))); seq_printf(s, "filter_erred_tsp = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_ERRED_TSP(filter->context))); seq_printf(s, "filter_discontinuities = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_DISCONTINUITIES(filter->context))); seq_printf(s, "filter_sc_bits_discard = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(filter->context))); seq_printf(s, "filter_tsp_total_num = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_TSP_TOTAL_NUM(filter->context))); seq_printf(s, "filter_discont_indicator = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_DISCONT_INDICATOR(filter->context))); seq_printf(s, "filter_tsp_no_payload = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_TSP_NO_PAYLOAD(filter->context))); seq_printf(s, "filter_tsp_duplicate = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_TSP_DUPLICATE(filter->context))); seq_printf(s, "filter_key_fetch_fail = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_KEY_FETCH_FAILURE(filter->context))); seq_printf(s, "filter_dropped_pcr = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_DROPPED_PCR(filter->context))); seq_printf(s, "filter_pes_errors = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_PES_ERRORS(filter->context))); } return 0; } Loading Loading @@ -1369,35 +1408,11 @@ static void tspp2_debugfs_init(struct tspp2_device *device) &device->irq_stats.global.encrypt_level_err); } dir = debugfs_create_dir("filters", device->debugfs_entry); for (i = 0; i < TSPP2_NUM_HW_FILTERS; i++) { snprintf(name, 80, "filter%03i", i); dir = debugfs_create_dir("counters", device->debugfs_entry); for (i = 0; i < TSPP2_NUM_CONTEXTS; i++) { snprintf(name, 80, "context%03i", i); dentry = debugfs_create_dir(name, dir); if (dentry) { debugfs_create_u32( "stat_sc_go_high", S_IRUGO | S_IWUSR | S_IWGRP, dentry, &device->irq_stats.filter[i].sc_go_high); debugfs_create_u32( "stat_sc_go_low", S_IRUGO | S_IWUSR | S_IWGRP, dentry, &device->irq_stats.filter[i].sc_go_low); debugfs_create_file("filter_entry0", TSPP2_S_RW, dentry, base + TSPP2_FILTER_ENTRY0(i), &fops_iomem_x32); debugfs_create_file("filter_entry1", TSPP2_S_RW, dentry, base + TSPP2_FILTER_ENTRY1(i), &fops_iomem_x32); debugfs_create_file("filter_tsp_sync_err", TSPP2_S_RW, dentry, Loading Loading @@ -1464,6 +1479,37 @@ static void tspp2_debugfs_init(struct tspp2_device *device) base + TSPP2_FILTER_PES_ERRORS(i), &fops_iomem_x32); debugfs_create_u32( "stat_sc_go_high", S_IRUGO | S_IWUSR | S_IWGRP, dentry, &device->irq_stats.ctx[i].sc_go_high); debugfs_create_u32( "stat_sc_go_low", S_IRUGO | S_IWUSR | S_IWGRP, dentry, &device->irq_stats.ctx[i].sc_go_low); } } dir = debugfs_create_dir("filters", device->debugfs_entry); for (i = 0; i < TSPP2_NUM_HW_FILTERS; i++) { snprintf(name, 80, "filter%03i", i); dentry = debugfs_create_dir(name, dir); if (dentry) { debugfs_create_file("filter_entry0", TSPP2_S_RW, dentry, base + TSPP2_FILTER_ENTRY0(i), &fops_iomem_x32); debugfs_create_file("filter_entry1", TSPP2_S_RW, dentry, base + TSPP2_FILTER_ENTRY1(i), &fops_iomem_x32); for (j = 0; j < TSPP2_MAX_OPS_PER_FILTER; j++) { snprintf(name, 80, "opcode%02i", j); debugfs_create_file(name, Loading Loading @@ -1948,27 +1994,24 @@ static void tspp2_clock_stop(struct tspp2_device *device) * tspp2_filter_counters_reset() - Reset a filter's HW counters. * * @device: TSPP2 device. * @hw_index: Filter HW index. * @index: Filter context index. Note counters are based on the context * index and not on the filter HW index. */ static void tspp2_filter_counters_reset(struct tspp2_device *device, u32 hw_index) static void tspp2_filter_counters_reset(struct tspp2_device *device, u32 index) { /* Reset filter counters */ writel_relaxed(0, device->base + TSPP2_FILTER_TSP_SYNC_ERROR(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_ERRED_TSP(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_DISCONTINUITIES(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_SYNC_ERROR(index)); writel_relaxed(0, device->base + TSPP2_FILTER_ERRED_TSP(index)); writel_relaxed(0, device->base + TSPP2_FILTER_DISCONTINUITIES(index)); writel_relaxed(0, device->base + TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_TOTAL_NUM(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_DISCONT_INDICATOR(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_NO_PAYLOAD(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_DUPLICATE(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_KEY_FETCH_FAILURE(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_DROPPED_PCR(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_PES_ERRORS(hw_index)); device->base + TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_TOTAL_NUM(index)); writel_relaxed(0, device->base + TSPP2_FILTER_DISCONT_INDICATOR(index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_NO_PAYLOAD(index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_DUPLICATE(index)); writel_relaxed(0, device->base + TSPP2_FILTER_KEY_FETCH_FAILURE(index)); writel_relaxed(0, device->base + TSPP2_FILTER_DROPPED_PCR(index)); writel_relaxed(0, device->base + TSPP2_FILTER_PES_ERRORS(index)); } /** Loading Loading @@ -2075,7 +2118,10 @@ static int tspp2_global_hw_reset(struct tspp2_device *device, /* Disable all HW filters */ writel_relaxed(0, device->base + TSPP2_FILTER_ENTRY0(i)); writel_relaxed(0, device->base + TSPP2_FILTER_ENTRY1(i)); /* Reset filter counters */ } for (i = 0; i < TSPP2_NUM_CONTEXTS; i++) { /* Reset filter context-based counters */ tspp2_filter_counters_reset(device, i); } Loading Loading @@ -5062,8 +5108,8 @@ int tspp2_src_filters_clear(u32 src_handle) TSPP2_FILTER_ENTRY0(filter->hw_index)); /* Clear filter operations in HW as well as related SW fields */ tspp2_filter_ops_clear(filter); /* Reset filter counters */ tspp2_filter_counters_reset(filter->device, filter->hw_index); /* Reset filter context-based counters */ tspp2_filter_counters_reset(filter->device, filter->context); /* Reset filter context and release it back to the device */ tspp2_filter_context_reset(filter); /* Reset filter SW fields */ Loading Loading @@ -5229,6 +5275,7 @@ int tspp2_filter_open(u32 src_handle, u16 pid, u16 mask, u32 *filter_handle) if (i == TSPP2_NUM_BATCHES) { pr_err("%s: No available filters\n", __func__); src->device->contexts[filter->context] = 0; filter->context = 0; mutex_unlock(&src->device->mutex); pm_runtime_mark_last_busy(src->device->dev); pm_runtime_put_autosuspend(src->device->dev); Loading Loading @@ -5265,8 +5312,8 @@ int tspp2_filter_open(u32 src_handle, u16 pid, u16 mask, u32 *filter_handle) list_add_tail(&filter->link, &src->filters_list); src->num_associated_filters++; /* Reset filter counters */ tspp2_filter_counters_reset(filter->device, filter->hw_index); /* Reset filter context-based counters */ tspp2_filter_counters_reset(filter->device, filter->context); /* Reset this filter's context */ writel_relaxed((0x1 << TSPP2_MODULUS_OP(filter->context, 32)), Loading Loading @@ -5378,8 +5425,8 @@ int tspp2_filter_close(u32 filter_handle) /* Clear filter operations in HW as well as related SW fields */ tspp2_filter_ops_clear(filter); /* Reset filter counters */ tspp2_filter_counters_reset(device, filter->hw_index); /* Reset filter context-based counters */ tspp2_filter_counters_reset(device, filter->context); /* Reset filter context and release it back to the device */ tspp2_filter_context_reset(filter); Loading Loading @@ -6315,9 +6362,6 @@ static int tspp2_filter_ops_update(struct tspp2_filter *filter, return -EINVAL; } /* Reset new filter HW counters */ tspp2_filter_counters_reset(filter->device, tmp_filter->hw_index); /* Set the same context of the old filter to the new HW filter */ writel_relaxed((filter->context << FILTER_ENTRY1_CONTEXT_OFFS), filter->device->base + Loading @@ -6329,6 +6373,10 @@ static int tspp2_filter_ops_update(struct tspp2_filter *filter, * that uses a context where before there was no operation that used it, * we reset that context. We need to do this before we start using the * new operation, so before we enable the new filter. * Note: there is no need to reset most of the filter's context-based * counters, because the filter keeps using the same context. The * exception is the PES error counters that we may want to reset when * resetting the entire PES context. */ if (!filter->pes_tx_op_set && tmp_filter->pes_tx_op_set) { /* PES Tx operation added */ Loading @@ -6336,6 +6384,8 @@ static int tspp2_filter_ops_update(struct tspp2_filter *filter, (0x1 << TSPP2_MODULUS_OP(filter->context, 32)), filter->device->base + TSPP2_PES_CONTEXT_RESET(filter->context >> 5)); writel_relaxed(0, filter->device->base + TSPP2_FILTER_PES_ERRORS(filter->context)); } if (!filter->indexing_op_set && tmp_filter->indexing_op_set) { Loading Loading @@ -6379,9 +6429,6 @@ static int tspp2_filter_ops_update(struct tspp2_filter *filter, /* The new HW filter may be in a new batch, so we need to update */ filter->batch = batch; /* Reset old filter HW counters */ tspp2_filter_counters_reset(filter->device, filter->hw_index); /* * Update source's reserved filter HW index, and also update the * new HW index in the filter object. Loading Loading @@ -7318,14 +7365,14 @@ int tspp2_filter_event_notification_register(u32 filter_handle, spin_unlock_irqrestore(&filter->device->spinlock, flags); /* Enable/disable SC high/low interrupts per filter as requested */ idx = (filter->hw_index >> 5); idx = (filter->context >> 5); reg = readl_relaxed(filter->device->base + TSPP2_SC_GO_HIGH_ENABLE(idx)); if (callback && (filter_event_bitmask & TSPP2_FILTER_EVENT_SCRAMBLING_HIGH)) { reg |= (0x1 << TSPP2_MODULUS_OP(filter->hw_index, 32)); reg |= (0x1 << TSPP2_MODULUS_OP(filter->context, 32)); } else { reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->hw_index, 32)); reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->context, 32)); } writel_relaxed(reg, filter->device->base + TSPP2_SC_GO_HIGH_ENABLE(idx)); Loading @@ -7334,9 +7381,9 @@ int tspp2_filter_event_notification_register(u32 filter_handle, TSPP2_SC_GO_LOW_ENABLE(idx)); if (callback && (filter_event_bitmask & TSPP2_FILTER_EVENT_SCRAMBLING_LOW)) { reg |= (0x1 << TSPP2_MODULUS_OP(filter->hw_index, 32)); reg |= (0x1 << TSPP2_MODULUS_OP(filter->context, 32)); } else { reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->hw_index, 32)); reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->context, 32)); } writel_relaxed(reg, filter->device->base + TSPP2_SC_GO_LOW_ENABLE(idx)); Loading Loading @@ -7926,7 +7973,7 @@ static irqreturn_t tspp2_isr(int irq, void *dev) u32 i = 0, j = 0; u32 global_bitmask = 0; u32 src_bitmask[TSPP2_NUM_MEM_INPUTS] = {0}; u32 filter_bitmask[TSPP2_NUM_HW_FILTERS] = {0}; u32 filter_bitmask[TSPP2_NUM_CONTEXTS] = {0}; u32 reg = 0; reg = readl_relaxed(device->base + TSPP2_GLOBAL_IRQ_STATUS); Loading Loading @@ -7993,7 +8040,7 @@ static irqreturn_t tspp2_isr(int irq, void *dev) for_each_set_bit(i, &ext_reg, 32) { filter_bitmask[j*32 + i] |= TSPP2_FILTER_EVENT_SCRAMBLING_HIGH; device->irq_stats.filter[j*32 + i].sc_go_high++; device->irq_stats.ctx[j*32 + i].sc_go_high++; } writel_relaxed(ext_reg, device->base + TSPP2_SC_GO_HIGH_CLEAR(j)); Loading @@ -8007,7 +8054,7 @@ static irqreturn_t tspp2_isr(int irq, void *dev) for_each_set_bit(i, &ext_reg, 32) { filter_bitmask[j*32 + i] |= TSPP2_FILTER_EVENT_SCRAMBLING_LOW; device->irq_stats.filter[j*32 + i].sc_go_low++; device->irq_stats.ctx[j*32 + i].sc_go_low++; } writel_relaxed(ext_reg, device->base + TSPP2_SC_GO_LOW_CLEAR(j)); Loading Loading @@ -8056,12 +8103,12 @@ static irqreturn_t tspp2_isr(int irq, void *dev) for (i = 0; i < TSPP2_NUM_HW_FILTERS; i++) { f = &device->filters[i]; if (f->event_callback && (f->event_bitmask & filter_bitmask[f->hw_index])) (f->event_bitmask & filter_bitmask[f->context])) tspp2_event_work_prepare(device, f->event_callback, f->event_cookie, (f->event_bitmask & filter_bitmask[f->hw_index])); filter_bitmask[f->context])); } spin_unlock_irqrestore(&device->spinlock, flags); Loading Loading
drivers/media/platform/msm/broadcast/tspp2.c +119 −72 Original line number Diff line number Diff line Loading @@ -200,7 +200,7 @@ enum tspp2_operation_opcode { /* Bits for TSPP2_FILTER_ENTRY1 register */ #define FILTER_ENTRY1_CONTEXT_OFFS 0 /* Filter counter register definitions: n = 0..127 */ /* Filter context-based counter register definitions: n = 0..127 */ #define TSPP2_FILTER_TSP_SYNC_ERROR(n) (0x4000 + ((n) << 2)) #define TSPP2_FILTER_ERRED_TSP(n) (0x4200 + ((n) << 2)) #define TSPP2_FILTER_DISCONTINUITIES(n) (0x4400 + ((n) << 2)) Loading Loading @@ -733,12 +733,12 @@ struct tspp2_pipe_irq_stats { }; /** * struct tspp2_filter_irq_stats - Filter interrupt statistics counters * struct tspp2_filter_context_irq_stats - Filter interrupt statistics counters * * @sc_go_high: Scrambling bits change from clear to encrypted. * @sc_go_low: Scrambling bits change from encrypted to clear. */ struct tspp2_filter_irq_stats { struct tspp2_filter_context_irq_stats { u32 sc_go_high; u32 sc_go_low; }; Loading @@ -750,14 +750,14 @@ struct tspp2_filter_irq_stats { * @src: Memory source interrupt statistics counters * @kt: Key table interrupt statistics counters * @pipe: Pipe interrupt statistics counters * @filter: Filter interrupt statistics counters * @ctx: Filter context interrupt statistics counters */ struct tspp2_irq_stats { struct tspp2_global_irq_stats global; struct tspp2_src_irq_stats src[TSPP2_NUM_MEM_INPUTS]; struct tspp2_keytable_irq_stats kt[TSPP2_NUM_KEYTABLES]; struct tspp2_pipe_irq_stats pipe[TSPP2_NUM_PIPES]; struct tspp2_filter_irq_stats filter[TSPP2_NUM_HW_FILTERS]; struct tspp2_filter_context_irq_stats ctx[TSPP2_NUM_CONTEXTS]; }; /** Loading Loading @@ -1226,6 +1226,45 @@ static int filter_debugfs_print(struct seq_file *s, void *p) seq_printf(s, "raw_op_set: %d\n", filter->raw_op_set); seq_printf(s, "pes_tx_op_set: %d\n", filter->pes_tx_op_set); seq_printf(s, "Status: %s\n", filter->enabled ? "enabled" : "disabled"); if (filter->enabled) { seq_printf(s, "Filter context-based counters, context %d\n", filter->context); seq_printf(s, "filter_tsp_sync_err = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_TSP_SYNC_ERROR(filter->context))); seq_printf(s, "filter_erred_tsp = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_ERRED_TSP(filter->context))); seq_printf(s, "filter_discontinuities = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_DISCONTINUITIES(filter->context))); seq_printf(s, "filter_sc_bits_discard = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(filter->context))); seq_printf(s, "filter_tsp_total_num = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_TSP_TOTAL_NUM(filter->context))); seq_printf(s, "filter_discont_indicator = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_DISCONT_INDICATOR(filter->context))); seq_printf(s, "filter_tsp_no_payload = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_TSP_NO_PAYLOAD(filter->context))); seq_printf(s, "filter_tsp_duplicate = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_TSP_DUPLICATE(filter->context))); seq_printf(s, "filter_key_fetch_fail = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_KEY_FETCH_FAILURE(filter->context))); seq_printf(s, "filter_dropped_pcr = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_DROPPED_PCR(filter->context))); seq_printf(s, "filter_pes_errors = 0x%08X\n", readl_relaxed(filter->device->base + TSPP2_FILTER_PES_ERRORS(filter->context))); } return 0; } Loading Loading @@ -1369,35 +1408,11 @@ static void tspp2_debugfs_init(struct tspp2_device *device) &device->irq_stats.global.encrypt_level_err); } dir = debugfs_create_dir("filters", device->debugfs_entry); for (i = 0; i < TSPP2_NUM_HW_FILTERS; i++) { snprintf(name, 80, "filter%03i", i); dir = debugfs_create_dir("counters", device->debugfs_entry); for (i = 0; i < TSPP2_NUM_CONTEXTS; i++) { snprintf(name, 80, "context%03i", i); dentry = debugfs_create_dir(name, dir); if (dentry) { debugfs_create_u32( "stat_sc_go_high", S_IRUGO | S_IWUSR | S_IWGRP, dentry, &device->irq_stats.filter[i].sc_go_high); debugfs_create_u32( "stat_sc_go_low", S_IRUGO | S_IWUSR | S_IWGRP, dentry, &device->irq_stats.filter[i].sc_go_low); debugfs_create_file("filter_entry0", TSPP2_S_RW, dentry, base + TSPP2_FILTER_ENTRY0(i), &fops_iomem_x32); debugfs_create_file("filter_entry1", TSPP2_S_RW, dentry, base + TSPP2_FILTER_ENTRY1(i), &fops_iomem_x32); debugfs_create_file("filter_tsp_sync_err", TSPP2_S_RW, dentry, Loading Loading @@ -1464,6 +1479,37 @@ static void tspp2_debugfs_init(struct tspp2_device *device) base + TSPP2_FILTER_PES_ERRORS(i), &fops_iomem_x32); debugfs_create_u32( "stat_sc_go_high", S_IRUGO | S_IWUSR | S_IWGRP, dentry, &device->irq_stats.ctx[i].sc_go_high); debugfs_create_u32( "stat_sc_go_low", S_IRUGO | S_IWUSR | S_IWGRP, dentry, &device->irq_stats.ctx[i].sc_go_low); } } dir = debugfs_create_dir("filters", device->debugfs_entry); for (i = 0; i < TSPP2_NUM_HW_FILTERS; i++) { snprintf(name, 80, "filter%03i", i); dentry = debugfs_create_dir(name, dir); if (dentry) { debugfs_create_file("filter_entry0", TSPP2_S_RW, dentry, base + TSPP2_FILTER_ENTRY0(i), &fops_iomem_x32); debugfs_create_file("filter_entry1", TSPP2_S_RW, dentry, base + TSPP2_FILTER_ENTRY1(i), &fops_iomem_x32); for (j = 0; j < TSPP2_MAX_OPS_PER_FILTER; j++) { snprintf(name, 80, "opcode%02i", j); debugfs_create_file(name, Loading Loading @@ -1948,27 +1994,24 @@ static void tspp2_clock_stop(struct tspp2_device *device) * tspp2_filter_counters_reset() - Reset a filter's HW counters. * * @device: TSPP2 device. * @hw_index: Filter HW index. * @index: Filter context index. Note counters are based on the context * index and not on the filter HW index. */ static void tspp2_filter_counters_reset(struct tspp2_device *device, u32 hw_index) static void tspp2_filter_counters_reset(struct tspp2_device *device, u32 index) { /* Reset filter counters */ writel_relaxed(0, device->base + TSPP2_FILTER_TSP_SYNC_ERROR(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_ERRED_TSP(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_DISCONTINUITIES(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_SYNC_ERROR(index)); writel_relaxed(0, device->base + TSPP2_FILTER_ERRED_TSP(index)); writel_relaxed(0, device->base + TSPP2_FILTER_DISCONTINUITIES(index)); writel_relaxed(0, device->base + TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_TOTAL_NUM(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_DISCONT_INDICATOR(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_NO_PAYLOAD(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_DUPLICATE(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_KEY_FETCH_FAILURE(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_DROPPED_PCR(hw_index)); writel_relaxed(0, device->base + TSPP2_FILTER_PES_ERRORS(hw_index)); device->base + TSPP2_FILTER_SCRAMBLING_BITS_DISCARD(index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_TOTAL_NUM(index)); writel_relaxed(0, device->base + TSPP2_FILTER_DISCONT_INDICATOR(index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_NO_PAYLOAD(index)); writel_relaxed(0, device->base + TSPP2_FILTER_TSP_DUPLICATE(index)); writel_relaxed(0, device->base + TSPP2_FILTER_KEY_FETCH_FAILURE(index)); writel_relaxed(0, device->base + TSPP2_FILTER_DROPPED_PCR(index)); writel_relaxed(0, device->base + TSPP2_FILTER_PES_ERRORS(index)); } /** Loading Loading @@ -2075,7 +2118,10 @@ static int tspp2_global_hw_reset(struct tspp2_device *device, /* Disable all HW filters */ writel_relaxed(0, device->base + TSPP2_FILTER_ENTRY0(i)); writel_relaxed(0, device->base + TSPP2_FILTER_ENTRY1(i)); /* Reset filter counters */ } for (i = 0; i < TSPP2_NUM_CONTEXTS; i++) { /* Reset filter context-based counters */ tspp2_filter_counters_reset(device, i); } Loading Loading @@ -5062,8 +5108,8 @@ int tspp2_src_filters_clear(u32 src_handle) TSPP2_FILTER_ENTRY0(filter->hw_index)); /* Clear filter operations in HW as well as related SW fields */ tspp2_filter_ops_clear(filter); /* Reset filter counters */ tspp2_filter_counters_reset(filter->device, filter->hw_index); /* Reset filter context-based counters */ tspp2_filter_counters_reset(filter->device, filter->context); /* Reset filter context and release it back to the device */ tspp2_filter_context_reset(filter); /* Reset filter SW fields */ Loading Loading @@ -5229,6 +5275,7 @@ int tspp2_filter_open(u32 src_handle, u16 pid, u16 mask, u32 *filter_handle) if (i == TSPP2_NUM_BATCHES) { pr_err("%s: No available filters\n", __func__); src->device->contexts[filter->context] = 0; filter->context = 0; mutex_unlock(&src->device->mutex); pm_runtime_mark_last_busy(src->device->dev); pm_runtime_put_autosuspend(src->device->dev); Loading Loading @@ -5265,8 +5312,8 @@ int tspp2_filter_open(u32 src_handle, u16 pid, u16 mask, u32 *filter_handle) list_add_tail(&filter->link, &src->filters_list); src->num_associated_filters++; /* Reset filter counters */ tspp2_filter_counters_reset(filter->device, filter->hw_index); /* Reset filter context-based counters */ tspp2_filter_counters_reset(filter->device, filter->context); /* Reset this filter's context */ writel_relaxed((0x1 << TSPP2_MODULUS_OP(filter->context, 32)), Loading Loading @@ -5378,8 +5425,8 @@ int tspp2_filter_close(u32 filter_handle) /* Clear filter operations in HW as well as related SW fields */ tspp2_filter_ops_clear(filter); /* Reset filter counters */ tspp2_filter_counters_reset(device, filter->hw_index); /* Reset filter context-based counters */ tspp2_filter_counters_reset(device, filter->context); /* Reset filter context and release it back to the device */ tspp2_filter_context_reset(filter); Loading Loading @@ -6315,9 +6362,6 @@ static int tspp2_filter_ops_update(struct tspp2_filter *filter, return -EINVAL; } /* Reset new filter HW counters */ tspp2_filter_counters_reset(filter->device, tmp_filter->hw_index); /* Set the same context of the old filter to the new HW filter */ writel_relaxed((filter->context << FILTER_ENTRY1_CONTEXT_OFFS), filter->device->base + Loading @@ -6329,6 +6373,10 @@ static int tspp2_filter_ops_update(struct tspp2_filter *filter, * that uses a context where before there was no operation that used it, * we reset that context. We need to do this before we start using the * new operation, so before we enable the new filter. * Note: there is no need to reset most of the filter's context-based * counters, because the filter keeps using the same context. The * exception is the PES error counters that we may want to reset when * resetting the entire PES context. */ if (!filter->pes_tx_op_set && tmp_filter->pes_tx_op_set) { /* PES Tx operation added */ Loading @@ -6336,6 +6384,8 @@ static int tspp2_filter_ops_update(struct tspp2_filter *filter, (0x1 << TSPP2_MODULUS_OP(filter->context, 32)), filter->device->base + TSPP2_PES_CONTEXT_RESET(filter->context >> 5)); writel_relaxed(0, filter->device->base + TSPP2_FILTER_PES_ERRORS(filter->context)); } if (!filter->indexing_op_set && tmp_filter->indexing_op_set) { Loading Loading @@ -6379,9 +6429,6 @@ static int tspp2_filter_ops_update(struct tspp2_filter *filter, /* The new HW filter may be in a new batch, so we need to update */ filter->batch = batch; /* Reset old filter HW counters */ tspp2_filter_counters_reset(filter->device, filter->hw_index); /* * Update source's reserved filter HW index, and also update the * new HW index in the filter object. Loading Loading @@ -7318,14 +7365,14 @@ int tspp2_filter_event_notification_register(u32 filter_handle, spin_unlock_irqrestore(&filter->device->spinlock, flags); /* Enable/disable SC high/low interrupts per filter as requested */ idx = (filter->hw_index >> 5); idx = (filter->context >> 5); reg = readl_relaxed(filter->device->base + TSPP2_SC_GO_HIGH_ENABLE(idx)); if (callback && (filter_event_bitmask & TSPP2_FILTER_EVENT_SCRAMBLING_HIGH)) { reg |= (0x1 << TSPP2_MODULUS_OP(filter->hw_index, 32)); reg |= (0x1 << TSPP2_MODULUS_OP(filter->context, 32)); } else { reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->hw_index, 32)); reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->context, 32)); } writel_relaxed(reg, filter->device->base + TSPP2_SC_GO_HIGH_ENABLE(idx)); Loading @@ -7334,9 +7381,9 @@ int tspp2_filter_event_notification_register(u32 filter_handle, TSPP2_SC_GO_LOW_ENABLE(idx)); if (callback && (filter_event_bitmask & TSPP2_FILTER_EVENT_SCRAMBLING_LOW)) { reg |= (0x1 << TSPP2_MODULUS_OP(filter->hw_index, 32)); reg |= (0x1 << TSPP2_MODULUS_OP(filter->context, 32)); } else { reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->hw_index, 32)); reg &= ~(0x1 << TSPP2_MODULUS_OP(filter->context, 32)); } writel_relaxed(reg, filter->device->base + TSPP2_SC_GO_LOW_ENABLE(idx)); Loading Loading @@ -7926,7 +7973,7 @@ static irqreturn_t tspp2_isr(int irq, void *dev) u32 i = 0, j = 0; u32 global_bitmask = 0; u32 src_bitmask[TSPP2_NUM_MEM_INPUTS] = {0}; u32 filter_bitmask[TSPP2_NUM_HW_FILTERS] = {0}; u32 filter_bitmask[TSPP2_NUM_CONTEXTS] = {0}; u32 reg = 0; reg = readl_relaxed(device->base + TSPP2_GLOBAL_IRQ_STATUS); Loading Loading @@ -7993,7 +8040,7 @@ static irqreturn_t tspp2_isr(int irq, void *dev) for_each_set_bit(i, &ext_reg, 32) { filter_bitmask[j*32 + i] |= TSPP2_FILTER_EVENT_SCRAMBLING_HIGH; device->irq_stats.filter[j*32 + i].sc_go_high++; device->irq_stats.ctx[j*32 + i].sc_go_high++; } writel_relaxed(ext_reg, device->base + TSPP2_SC_GO_HIGH_CLEAR(j)); Loading @@ -8007,7 +8054,7 @@ static irqreturn_t tspp2_isr(int irq, void *dev) for_each_set_bit(i, &ext_reg, 32) { filter_bitmask[j*32 + i] |= TSPP2_FILTER_EVENT_SCRAMBLING_LOW; device->irq_stats.filter[j*32 + i].sc_go_low++; device->irq_stats.ctx[j*32 + i].sc_go_low++; } writel_relaxed(ext_reg, device->base + TSPP2_SC_GO_LOW_CLEAR(j)); Loading Loading @@ -8056,12 +8103,12 @@ static irqreturn_t tspp2_isr(int irq, void *dev) for (i = 0; i < TSPP2_NUM_HW_FILTERS; i++) { f = &device->filters[i]; if (f->event_callback && (f->event_bitmask & filter_bitmask[f->hw_index])) (f->event_bitmask & filter_bitmask[f->context])) tspp2_event_work_prepare(device, f->event_callback, f->event_cookie, (f->event_bitmask & filter_bitmask[f->hw_index])); filter_bitmask[f->context])); } spin_unlock_irqrestore(&device->spinlock, flags); Loading