Эх сурвалжийг харах

video: driver: disable and unprepare clock source to update MMRM count

[1] Currently enable/disable clock(video_cc_mvs0_clk_src) not called. So
updating clock reset value to MMRM is getting skipped. So MMRM has high
projection
[2] __scale_clocks() api is not considering scaling factor, while
setting clock rate.

Added change to address above 2 issues.

Change-Id: I4e96556f9b9d659c436e77d03f8d0dd471a50226
Signed-off-by: Govindaraj Rajagopal <[email protected]>
Govindaraj Rajagopal 3 жил өмнө
parent
commit
caeaca6ccd

+ 24 - 2
driver/variant/iris2/src/msm_vidc_iris2.c

@@ -213,6 +213,7 @@ static int __prepare_enable_clock_iris2(struct msm_vidc_core *core,
 	int rc = 0;
 	struct clock_info *cl;
 	bool found;
+	u64 rate = 0;
 
 	if (!core || !clk_name) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -233,8 +234,16 @@ static int __prepare_enable_clock_iris2(struct msm_vidc_core *core,
 		 * them.  Since we don't really have a load at this point, scale
 		 * it to the lowest frequency possible
 		 */
-		if (cl->has_scaling)
-			__set_clk_rate(core, cl, clk_round_rate(cl->clk, 0));
+		if (cl->has_scaling) {
+			rate = clk_round_rate(cl->clk, 0);
+			/**
+			 * source clock is already multipled with scaling ratio and __set_clk_rate
+			 * attempts to multiply again. So divide scaling ratio before calling
+			 * __set_clk_rate.
+			 */
+			rate = rate / MSM_VIDC_CLOCK_SOURCE_SCALING_RATIO;
+			__set_clk_rate(core, cl, rate);
+		}
 
 		rc = clk_prepare_enable(cl->clk);
 		if (rc) {
@@ -586,6 +595,13 @@ static int __power_off_iris2_controller(struct msm_vidc_core *core)
 		rc = 0;
 	}
 
+	/* Turn off MVP MVS0 SRC clock */
+	rc = __disable_unprepare_clock_iris2(core, "video_cc_mvs0_clk_src");
+	if (rc) {
+		d_vpr_e("%s: disable unprepare video_cc_mvs0_clk_src failed\n", __func__);
+		rc = 0;
+	}
+
 	return rc;
 }
 
@@ -639,8 +655,14 @@ static int __power_on_iris2_controller(struct msm_vidc_core *core)
 	if (rc)
 		goto fail_clk_controller;
 
+	rc = __prepare_enable_clock_iris2(core, "video_cc_mvs0_clk_src");
+	if (rc)
+		goto fail_clk_src;
+
 	return 0;
 
+fail_clk_src:
+	__disable_unprepare_clock_iris2(core, "core_clk");
 fail_clk_controller:
 	__disable_unprepare_clock_iris2(core, "gcc_video_axi0");
 fail_clk_axi:

+ 3 - 0
driver/vidc/inc/msm_vidc_power.h

@@ -13,6 +13,9 @@
 
 #define COMPRESSION_RATIO_MAX 5
 
+/* TODO: Move to dtsi OR use source clock instead of branch clock.*/
+#define MSM_VIDC_CLOCK_SOURCE_SCALING_RATIO 3
+
 enum vidc_bus_type {
 	PERF,
 	DDR,

+ 0 - 12
driver/vidc/src/msm_vidc_power.c

@@ -21,9 +21,6 @@
 #define MSM_VIDC_MIN_UBWC_COMPRESSION_RATIO (1 << 16)
 #define MSM_VIDC_MAX_UBWC_COMPRESSION_RATIO (5 << 16)
 
-/* TODO: Move to dtsi OR use source clock instead of branch clock.*/
-#define MSM_VIDC_CLOCK_SOURCE_SCALING_RATIO 3
-
 u64 msm_vidc_max_freq(struct msm_vidc_inst *inst)
 {
 	struct msm_vidc_core* core;
@@ -365,15 +362,6 @@ int msm_vidc_set_clocks(struct msm_vidc_inst* inst)
 		__func__, rate, freq, increment, decrement);
 	mutex_unlock(&core->lock);
 
-	/*
-	 * This conversion is necessary since we are scaling clock values based on
-	 * the branch clock. However, mmrm driver expects source clock to be registered
-	 * and used for scaling.
-	 * TODO: Remove this scaling if using source clock instead of branch clock.
-	 */
-	rate = rate * MSM_VIDC_CLOCK_SOURCE_SCALING_RATIO;
-	i_vpr_l(inst, "%s: scaled clock rate %lu\n", __func__, rate);
-
 	rc = venus_hfi_scale_clocks(inst, rate);
 	if (rc)
 		return rc;

+ 19 - 3
driver/vidc/src/venus_hfi.c

@@ -668,6 +668,14 @@ int __set_clk_rate(struct msm_vidc_core *core,
 	}
 	client = cl->mmrm_client;
 
+	/*
+	 * This conversion is necessary since we are scaling clock values based on
+	 * the branch clock. However, mmrm driver expects source clock to be registered
+	 * and used for scaling.
+	 * TODO: Remove this scaling if using source clock instead of branch clock.
+	 */
+	rate = rate * MSM_VIDC_CLOCK_SOURCE_SCALING_RATIO;
+
 	/* bail early if requested clk rate is not changed */
 	if (rate == cl->prev)
 		return 0;
@@ -1609,6 +1617,7 @@ int __prepare_enable_clks(struct msm_vidc_core *core)
 {
 	struct clock_info *cl = NULL;
 	int rc = 0, c = 0;
+	u64 rate = 0;
 
 	if (!core) {
 		d_vpr_e("%s: invalid params\n", __func__);
@@ -1626,9 +1635,16 @@ int __prepare_enable_clks(struct msm_vidc_core *core)
 		 * them.  Since we don't really have a load at this point, scale
 		 * it to the lowest frequency possible
 		 */
-		if (cl->has_scaling)
-			__set_clk_rate(core, cl,
-					clk_round_rate(cl->clk, 0));
+		if (cl->has_scaling) {
+			rate = clk_round_rate(cl->clk, 0);
+			/**
+			 * source clock is already multipled with scaling ratio and __set_clk_rate
+			 * attempts to multiply again. So divide scaling ratio before calling
+			 * __set_clk_rate.
+			 */
+			rate = rate / MSM_VIDC_CLOCK_SOURCE_SCALING_RATIO;
+			__set_clk_rate(core, cl, rate);
+		}
 
 		rc = clk_prepare_enable(cl->clk);
 		if (rc) {