|
@@ -378,12 +378,14 @@ static inline bool hal_is_reg_write_tput_level_high(struct hal_soc *hal)
|
|
|
* @hal: hal_soc pointer
|
|
|
* @q_elem: pointer to hal regiter write queue element
|
|
|
*
|
|
|
- * Return: None
|
|
|
+ * Return: The value which was written to the address
|
|
|
*/
|
|
|
-static void hal_process_reg_write_q_elem(struct hal_soc *hal,
|
|
|
- struct hal_reg_write_q_elem *q_elem)
|
|
|
+static uint32_t
|
|
|
+hal_process_reg_write_q_elem(struct hal_soc *hal,
|
|
|
+ struct hal_reg_write_q_elem *q_elem)
|
|
|
{
|
|
|
struct hal_srng *srng = q_elem->srng;
|
|
|
+ uint32_t write_val;
|
|
|
|
|
|
SRNG_LOCK(&srng->lock);
|
|
|
|
|
@@ -395,14 +397,19 @@ static void hal_process_reg_write_q_elem(struct hal_soc *hal,
|
|
|
hal_write_address_32_mb(hal,
|
|
|
srng->u.src_ring.hp_addr,
|
|
|
srng->u.src_ring.hp, false);
|
|
|
+ write_val = srng->u.src_ring.hp;
|
|
|
} else {
|
|
|
q_elem->dequeue_val = srng->u.dst_ring.tp;
|
|
|
hal_write_address_32_mb(hal,
|
|
|
srng->u.dst_ring.tp_addr,
|
|
|
srng->u.dst_ring.tp, false);
|
|
|
+ write_val = srng->u.dst_ring.tp;
|
|
|
}
|
|
|
|
|
|
+ q_elem->valid = 0;
|
|
|
SRNG_UNLOCK(&srng->lock);
|
|
|
+
|
|
|
+ return write_val;
|
|
|
}
|
|
|
|
|
|
/**
|
|
@@ -437,10 +444,12 @@ static inline void hal_reg_write_fill_sched_delay_hist(struct hal_soc *hal,
|
|
|
*/
|
|
|
static void hal_reg_write_work(void *arg)
|
|
|
{
|
|
|
- int32_t q_depth;
|
|
|
+ int32_t q_depth, write_val;
|
|
|
struct hal_soc *hal = arg;
|
|
|
struct hal_reg_write_q_elem *q_elem;
|
|
|
uint64_t delta_us;
|
|
|
+ uint8_t ring_id;
|
|
|
+ uint32_t *addr;
|
|
|
|
|
|
q_elem = &hal->reg_write_queue[(hal->read_idx)];
|
|
|
|
|
@@ -458,6 +467,8 @@ static void hal_reg_write_work(void *arg)
|
|
|
|
|
|
while (q_elem->valid) {
|
|
|
q_elem->dequeue_time = qdf_get_log_timestamp();
|
|
|
+ ring_id = q_elem->srng->ring_id;
|
|
|
+ addr = q_elem->addr;
|
|
|
delta_us = qdf_log_timestamp_to_usecs(q_elem->dequeue_time -
|
|
|
q_elem->enqueue_time);
|
|
|
hal_reg_write_fill_sched_delay_hist(hal, delta_us);
|
|
@@ -465,15 +476,10 @@ static void hal_reg_write_work(void *arg)
|
|
|
hal->stats.wstats.dequeues++;
|
|
|
qdf_atomic_dec(&hal->stats.wstats.q_depth);
|
|
|
|
|
|
- hal_process_reg_write_q_elem(hal, q_elem);
|
|
|
+ write_val = hal_process_reg_write_q_elem(hal, q_elem);
|
|
|
hal_verbose_debug("read_idx %u srng 0x%x, addr 0x%pK dequeue_val %u sched delay %llu us",
|
|
|
- hal->read_idx,
|
|
|
- q_elem->srng->ring_id,
|
|
|
- q_elem->addr,
|
|
|
- q_elem->dequeue_val,
|
|
|
- delta_us);
|
|
|
+ hal->read_idx, ring_id, addr, write_val, delta_us);
|
|
|
|
|
|
- q_elem->valid = 0;
|
|
|
hal->read_idx = (hal->read_idx + 1) &
|
|
|
(HAL_REG_WRITE_QUEUE_LEN - 1);
|
|
|
q_elem = &hal->reg_write_queue[(hal->read_idx)];
|
|
@@ -544,6 +550,13 @@ static void hal_reg_write_enqueue(struct hal_soc *hal_soc,
|
|
|
q_elem->enqueue_val = value;
|
|
|
q_elem->enqueue_time = qdf_get_log_timestamp();
|
|
|
|
|
|
+ /*
|
|
|
+ * Before the valid flag is set to true, all the other
|
|
|
+ * fields in the q_elem needs to be updated in memory.
|
|
|
+ * Else there is a chance that the dequeuing worker thread
|
|
|
+ * might read stale entries and process incorrect srng.
|
|
|
+ */
|
|
|
+ qdf_wmb();
|
|
|
q_elem->valid = true;
|
|
|
|
|
|
srng->reg_write_in_progress = true;
|