Przeglądaj źródła

video: driver: enable interframe power collapse

Hand off regulators to hw to enable interframe power collapse.

Change-Id: I11d3d96f0a6cce23ef374e2065532a13af38d2f4
Signed-off-by: Chinmay Sawarkar <[email protected]>
Chinmay Sawarkar 4 lat temu
rodzic
commit
6070bc2523

+ 2 - 0
driver/vidc/inc/hfi_packet.h

@@ -42,4 +42,6 @@ int hfi_packet_sys_debug_config(struct msm_vidc_core *core,
 int hfi_packet_session_command(struct msm_vidc_inst *inst,
 	u32 pkt_type, u32 flags, u32 port, u32 session_id,
 	u32 payload_type, void *payload, u32 payload_size);
+int hfi_packet_sys_intraframe_powercollapse(struct msm_vidc_core* core,
+	u8* pkt, u32 pkt_size, u32 enable);
 #endif // _HFI_PACKET_H_

+ 1 - 0
driver/vidc/inc/msm_vidc_core.h

@@ -109,6 +109,7 @@ struct msm_vidc_core {
 	u32                                    header_id;
 	u32                                    packet_id;
 	struct completion                      init_done;
+	u32                                    handoff_done;
 };
 
 #endif // _MSM_VIDC_CORE_H_

+ 39 - 14
driver/vidc/src/hfi_packet.c

@@ -354,20 +354,6 @@ int hfi_packet_sys_init(struct msm_vidc_core *core,
 	if (rc)
 		goto err_sys_init;
 
-	/* HFI_PROP_INTRA_FRAME_POWER_COLLAPSE */
-	payload = 0;
-	d_vpr_h("%s: intra frame power collapse %d\n", __func__, payload);
-	rc = hfi_create_packet(pkt, pkt_size,
-				   HFI_PROP_INTRA_FRAME_POWER_COLLAPSE,
-				   HFI_HOST_FLAGS_NONE,
-				   HFI_PAYLOAD_U32,
-				   HFI_PORT_NONE,
-				   core->packet_id++,
-				   &payload,
-				   sizeof(u32));
-	if (rc)
-		goto err_sys_init;
-
 	/* HFI_PROP_UBWC_MAX_CHANNELS */
 	payload = core->platform->data.ubwc_config->max_channels;
 	d_vpr_h("%s: ubwc max channels %d\n", __func__, payload);
@@ -635,3 +621,42 @@ err_cmd:
 	d_vpr_e("%s: create packet failed\n", __func__);
 	return rc;
 }
+
+int hfi_packet_sys_intraframe_powercollapse(struct msm_vidc_core* core,
+	u8* pkt, u32 pkt_size, u32 enable)
+{
+	int rc = 0;
+	u32 payload = 0;
+
+	if (!core || !pkt) {
+		d_vpr_e("%s: Invalid params\n", __func__);
+		return -EINVAL;
+	}
+
+	rc = hfi_create_header(pkt, pkt_size,
+		0 /*session_id*/,
+		core->header_id++);
+	if (rc)
+		goto err;
+
+	/* HFI_PROP_INTRA_FRAME_POWER_COLLAPSE */
+	payload = enable;
+	d_vpr_h("%s: intra frame power collapse %d\n", __func__, payload);
+	rc = hfi_create_packet(pkt, pkt_size,
+		HFI_PROP_INTRA_FRAME_POWER_COLLAPSE,
+		HFI_HOST_FLAGS_NONE,
+		HFI_PAYLOAD_U32,
+		HFI_PORT_NONE,
+		core->packet_id++,
+		&payload,
+		sizeof(u32));
+	if (rc)
+		goto err;
+
+	d_vpr_h("IFPC packet created\n");
+	return rc;
+
+err:
+	d_vpr_e("%s: create packet failed\n", __func__);
+	return rc;
+}

+ 1 - 1
driver/vidc/src/msm_vidc.c

@@ -713,7 +713,7 @@ void *msm_vidc_open(void *vidc_core, u32 session_type)
 	kref_init(&inst->kref);
 	mutex_init(&inst->lock);
 
-	i_vpr_e(inst, "Opening video instance: %d\n", session_type);
+	i_vpr_h(inst, "Opening video instance: %d\n", session_type);
 
 	inst->response_workq = create_singlethread_workqueue("response_workq");
 	if (!inst->response_workq) {

+ 23 - 21
driver/vidc/src/venus_hfi.c

@@ -386,10 +386,12 @@ static int __hand_off_regulator(struct msm_vidc_core *core,
 		rc = regulator_set_mode(rinfo->regulator,
 				REGULATOR_MODE_FAST);
 		if (rc) {
+			core->handoff_done = 0;
 			d_vpr_e("Failed to hand off regulator control: %s\n",
 				rinfo->name);
 			return rc;
 		} else {
+			core->handoff_done = 1;
 			d_vpr_h("Hand off regulator control to HW: %s\n",
 					rinfo->name);
 		}
@@ -1049,28 +1051,24 @@ static int __sys_set_coverage(struct msm_vidc_core *core,
 
 	return 0;
 }
-
+*/
 static int __sys_set_power_control(struct msm_vidc_core *core, bool enable)
 {
-	struct regulator_info *rinfo;
-	bool supported = false;
+	int rc = 0;
 
-	venus_hfi_for_each_regulator(core, rinfo) {
-		if (rinfo->has_hw_power_collapse) {
-			supported = true;
-			break;
-		}
-	}
+	if (!core->handoff_done)
+		return rc;
 
-	if (!supported)
-		return 0;
+	rc = hfi_packet_sys_intraframe_powercollapse(core, core->packet, core->packet_size, enable);
+	if (rc)
+		return rc;
 
-	//call_hfi_pkt_op(core, sys_power_control, pkt, enable);
-	//if (__iface_cmdq_write(core, pkt, sid))
-	//	return -ENOTEMPTY;
-	return 0;
+	rc = __iface_cmdq_write(core, core->packet);
+	if (rc)
+		return rc;
+
+	return rc;
 }
-*/
 
 int __prepare_pc(struct msm_vidc_core *core)
 {
@@ -1698,14 +1696,11 @@ static int __enable_hw_power_collapse(struct msm_vidc_core *core)
 {
 	int rc = 0;
 
-	// TODO: skip if hardwar power control feature is not present
-	d_vpr_e("%s: skip hand off regulators\n", __func__);
-	return 0;
-
 	rc = __hand_off_regulators(core);
 	if (rc)
 		d_vpr_e("%s: Failed to enable HW power collapse %d\n",
-				__func__, rc);
+			__func__, rc);
+
 	return rc;
 }
 
@@ -2122,6 +2117,7 @@ static int __resume(struct msm_vidc_core *core)
 	}
 
 	__sys_set_debug(core, (msm_vidc_debug & FW_LOGMASK) >> FW_LOGSHIFT);
+
 	rc = __enable_subcaches(core);
 	if (rc) {
 		d_vpr_e("Failed to activate subcache\n");
@@ -2129,6 +2125,9 @@ static int __resume(struct msm_vidc_core *core)
 	}
 	__set_subcaches(core);
 
+	if (core->handoff_done)
+		__sys_set_power_control(core, true);
+
 	d_vpr_h("Resumed from power collapse\n");
 exit:
 	/* Don't reset skip_pc_count for SYS_PC_PREP cmd */
@@ -2679,6 +2678,9 @@ int venus_hfi_core_init(struct msm_vidc_core *core)
 	if (rc)
 		goto error;
 
+	if (core->handoff_done)
+		__sys_set_power_control(core, true);
+
 	d_vpr_h("%s(): successful\n", __func__);
 	return 0;