Pārlūkot izejas kodu

mm-drivers: hw_fence: Add per client ipc interrupt property

Not all clients need ipc interrupt for an already signaled fence. Set the
per client property based on whether a client needs the interrupt or not.
Also, set update_rxq property for GPU client to false, as GPU doesn't need
already signaled fences to be sent to GPU Rx Queue.

Change-Id: I08a6bbd598695b112124ce6ec409db75d5e11e0f
Signed-off-by: Harshdeep Dhatt <[email protected]>
Harshdeep Dhatt 2 gadi atpakaļ
vecāks
revīzija
9ff114eee8

+ 10 - 0
hw_fence/include/hw_fence_drv_ipc.h

@@ -87,4 +87,14 @@ int hw_fence_ipcc_get_signal_id(struct hw_fence_driver_data *drv_data, u32 clien
  */
 bool hw_fence_ipcc_needs_rxq_update(struct hw_fence_driver_data *drv_data, int client_id);
 
+/**
+ * hw_fence_ipcc_needs_ipc_irq() - Returns bool to indicate if client needs ipc interrupt for
+ *		already signaled fences
+ * @drv_data: driver data.
+ * @client_id: hw fence driver client id.
+ *
+ * Return: true if client needs ipc interrupt for signaled fences, false otherwise
+ */
+bool hw_fence_ipcc_needs_ipc_irq(struct hw_fence_driver_data *drv_data, int client_id);
+
 #endif /* __HW_FENCE_DRV_IPC_H */

+ 2 - 0
hw_fence/include/hw_fence_drv_priv.h

@@ -150,6 +150,7 @@ enum payload_type {
  * @ipc_signal_id: id of the signal to be triggered for this client
  * @ipc_client_id: id of the ipc client for this hw fence driver client
  * @update_rxq: bool to indicate if client uses rx-queue
+ * @send_ipc: bool to indicate if client requires ipc interrupt for already signaled fences
  * @wait_queue: wait queue for the validation clients
  * @val_signal: doorbell flag to signal the validation clients in the wait queue
  */
@@ -160,6 +161,7 @@ struct msm_hw_fence_client {
 	int ipc_signal_id;
 	int ipc_client_id;
 	bool update_rxq;
+	bool send_ipc;
 #if IS_ENABLED(CONFIG_DEBUG_FS)
 	wait_queue_head_t wait_queue;
 	atomic_t val_signal;

+ 40 - 30
hw_fence/src/hw_fence_drv_ipc.c

@@ -13,11 +13,13 @@
  * @ipc_client_id: ipc client id for the hw-fence client.
  * @ipc_signal_id: ipc signal id for the hw-fence client.
  * @update_rxq: bool to indicate if clinet uses rx-queue.
+ * @send_ipc: bool to indicate if client requires ipc interrupt for signaled fences
  */
 struct hw_fence_client_ipc_map {
 	int ipc_client_id;
 	int ipc_signal_id;
 	bool update_rxq;
+	bool send_ipc;
 };
 
 /**
@@ -32,22 +34,22 @@ struct hw_fence_client_ipc_map {
  *   {HW_FENCE_IPC_CLIENT_ID_APPS, 20}.
  */
 struct hw_fence_client_ipc_map hw_fence_clients_ipc_map_no_dpu[HW_FENCE_CLIENT_MAX] = {
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 1, true}, /* ctrl queue loopback */
-	{HW_FENCE_IPC_CLIENT_ID_GPU,  0, true}, /* ctx0 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 14, false}, /* ctl0 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 15, false}, /* ctl1 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 16, false}, /* ctl2 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 17, false}, /* ctl3 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 18, false}, /* ctl4 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 19, false}, /* ctl5 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 1, true, true}, /* ctrl queue loopback */
+	{HW_FENCE_IPC_CLIENT_ID_GPU,  0, false, false}, /* ctx0 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 14, false, true}, /* ctl0 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 15, false, true}, /* ctl1 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 16, false, true}, /* ctl2 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 17, false, true}, /* ctl3 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 18, false, true}, /* ctl4 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 19, false, true}, /* ctl5 */
 #if IS_ENABLED(CONFIG_DEBUG_FS)
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 21, true}, /* val0 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 22, true}, /* val1 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 23, true}, /* val2 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 24, true}, /* val3 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 25, true}, /* val4 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 26, true}, /* val5 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 27, true}, /* val6 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 21, true, true}, /* val0 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 22, true, true}, /* val1 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 23, true, true}, /* val2 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 24, true, true}, /* val3 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 25, true, true}, /* val4 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 26, true, true}, /* val5 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 27, true, true}, /* val6 */
 #endif /* CONFIG_DEBUG_FS */
 };
 
@@ -60,22 +62,22 @@ struct hw_fence_client_ipc_map hw_fence_clients_ipc_map_no_dpu[HW_FENCE_CLIENT_M
  * Note that the index of this struct must match the enum hw_fence_client_id
  */
 struct hw_fence_client_ipc_map hw_fence_clients_ipc_map[HW_FENCE_CLIENT_MAX] = {
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 1, true}, /* ctrl queue loopback */
-	{HW_FENCE_IPC_CLIENT_ID_GPU,  0, true}, /* ctx0 */
-	{HW_FENCE_IPC_CLIENT_ID_DPU,  0, false}, /* ctl0 */
-	{HW_FENCE_IPC_CLIENT_ID_DPU,  1, false}, /* ctl1 */
-	{HW_FENCE_IPC_CLIENT_ID_DPU,  2, false}, /* ctl2 */
-	{HW_FENCE_IPC_CLIENT_ID_DPU,  3, false}, /* ctl3 */
-	{HW_FENCE_IPC_CLIENT_ID_DPU,  4, false}, /* ctl4 */
-	{HW_FENCE_IPC_CLIENT_ID_DPU,  5, false}, /* ctl5 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 1, true, true}, /* ctrl queue loopback */
+	{HW_FENCE_IPC_CLIENT_ID_GPU,  0, false, false}, /* ctx0 */
+	{HW_FENCE_IPC_CLIENT_ID_DPU,  0, false, true}, /* ctl0 */
+	{HW_FENCE_IPC_CLIENT_ID_DPU,  1, false, true}, /* ctl1 */
+	{HW_FENCE_IPC_CLIENT_ID_DPU,  2, false, true}, /* ctl2 */
+	{HW_FENCE_IPC_CLIENT_ID_DPU,  3, false, true}, /* ctl3 */
+	{HW_FENCE_IPC_CLIENT_ID_DPU,  4, false, true}, /* ctl4 */
+	{HW_FENCE_IPC_CLIENT_ID_DPU,  5, false, true}, /* ctl5 */
 #if IS_ENABLED(CONFIG_DEBUG_FS)
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 21, true}, /* val0 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 22, true}, /* val1 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 23, true}, /* val2 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 24, true}, /* val3 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 25, true}, /* val4 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 26, true}, /* val5 */
-	{HW_FENCE_IPC_CLIENT_ID_APPS, 27, true}, /* val6 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 21, true, true}, /* val0 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 22, true, true}, /* val1 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 23, true, true}, /* val2 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 24, true, true}, /* val3 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 25, true, true}, /* val4 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 26, true, true}, /* val5 */
+	{HW_FENCE_IPC_CLIENT_ID_APPS, 27, true, true}, /* val6 */
 #endif /* CONFIG_DEBUG_FS */
 };
 
@@ -103,6 +105,14 @@ bool hw_fence_ipcc_needs_rxq_update(struct hw_fence_driver_data *drv_data, int c
 	return drv_data->ipc_clients_table[client_id].update_rxq;
 }
 
+bool hw_fence_ipcc_needs_ipc_irq(struct hw_fence_driver_data *drv_data, int client_id)
+{
+	if (!drv_data || client_id >= HW_FENCE_CLIENT_MAX)
+		return -EINVAL;
+
+	return drv_data->ipc_clients_table[client_id].send_ipc;
+}
+
 /**
  * _get_ipc_client_name() - Returns ipc client name, used for debugging.
  */

+ 3 - 2
hw_fence/src/hw_fence_drv_priv.c

@@ -1058,8 +1058,9 @@ static void _fence_ctl_signal(struct hw_fence_driver_data *drv_data,
 			hw_fence->seq_id, hash, flags, error, HW_FENCE_RX_QUEUE - 1);
 
 	/* Signal the hw fence now */
-	hw_fence_ipcc_trigger_signal(drv_data, tx_client_id, rx_client_id,
-		hw_fence_client->ipc_signal_id);
+	if (hw_fence_client->send_ipc)
+		hw_fence_ipcc_trigger_signal(drv_data, tx_client_id, rx_client_id,
+			hw_fence_client->ipc_signal_id);
 }
 
 static void _cleanup_join_and_child_fences(struct hw_fence_driver_data *drv_data,

+ 1 - 0
hw_fence/src/msm_hw_fence.c

@@ -70,6 +70,7 @@ void *msm_hw_fence_register(enum hw_fence_client_id client_id,
 	}
 
 	hw_fence_client->update_rxq = hw_fence_ipcc_needs_rxq_update(hw_fence_drv_data, client_id);
+	hw_fence_client->send_ipc = hw_fence_ipcc_needs_ipc_irq(hw_fence_drv_data, client_id);
 
 	/* Alloc Client HFI Headers and Queues */
 	ret = hw_fence_alloc_client_resources(hw_fence_drv_data,