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

mmrm: Fixing delta current for number of hw instances

While adjusting the voltage corner for all clients, number of
hw instances in not included. Also when calculating the old
current of a client number of hw blocks is not included.
Fixed the calculations to project the correct current calculation
when either overall voltage corner is adjested or corner is adjusted
for a client.

Change-Id: I4ee9bb02275fda61c72dce99f41dbf73b4cf8fc5
Signed-off-by: Shivendra Kakrania <[email protected]>
Shivendra Kakrania 3 жил өмнө
parent
commit
d5c40be33b

+ 38 - 19
driver/src/mmrm_clk_rsrc_mgr_sw.c

@@ -460,7 +460,7 @@ err_invalid_level:
 
 static int mmrm_sw_calculate_total_current(
 	struct mmrm_sw_clk_mgr_info *sinfo,
-	u32 req_level, u32 *total_cur)
+	u32 req_level, u32 *total_cur, struct mmrm_sw_clk_client_tbl_entry *tbl_entry_new)
 {
 	int rc = 0;
 	struct mmrm_sw_clk_client_tbl_entry *tbl_entry;
@@ -475,14 +475,16 @@ static int mmrm_sw_calculate_total_current(
 	/* calculate sum of values (scaled by volt) */
 	for (c = 0; c < sinfo->tot_clk_clients; c++) {
 		tbl_entry = &sinfo->clk_client_tbl[c];
-		if (IS_ERR_OR_NULL(tbl_entry->clk) || !tbl_entry->clk_rate) {
+		if (IS_ERR_OR_NULL(tbl_entry->clk) || !tbl_entry->clk_rate
+			|| (tbl_entry == tbl_entry_new)) {
 			continue;
 		}
-		sum_cur += tbl_entry->current_ma[tbl_entry->vdd_level][req_level];
+		sum_cur += (tbl_entry->current_ma[tbl_entry->vdd_level][req_level]
+			* tbl_entry->num_hw_blocks);
 	}
 
 	*total_cur = sum_cur;
-	d_mpr_h("%s: total_cur(%d)\n", __func__, sum_cur);
+	d_mpr_h("%s: total_cur(%lu)\n", __func__, *total_cur);
 	return rc;
 
 err_invalid_level:
@@ -617,13 +619,14 @@ static void mmrm_sw_dump_enabled_client_info(struct mmrm_sw_clk_mgr_info *sinfo)
 	for (c = 0; c < sinfo->tot_clk_clients; c++) {
 		tbl_entry = &sinfo->clk_client_tbl[c];
 		if (tbl_entry->clk_rate) {
-			d_mpr_e("%s: csid(0x%x) clk_rate(%zu) vdd_level(%zu) cur_ma(%zu)\n",
+			d_mpr_e("%s: csid(0x%x) clk_rate(%zu) vdd_level(%zu) cur_ma(%zu) num_hw_blocks(%zu)\n",
 				__func__,
 				tbl_entry->clk_src_id,
 				tbl_entry->clk_rate,
 				tbl_entry->vdd_level,
 				tbl_entry->current_ma[tbl_entry->vdd_level]
-									[peak_data->aggreg_level]);
+					[peak_data->aggreg_level] * tbl_entry->num_hw_blocks,
+				tbl_entry->num_hw_blocks);
 		}
 	}
 	if (peak_data) {
@@ -698,7 +701,7 @@ static int mmrm_sw_check_peak_current(struct mmrm_sw_clk_mgr_info *sinfo,
 	u32 peak_cur = peak_data->aggreg_val;
 	u32 old_cur = 0, new_cur = 0;
 
-	int delta_cur;
+	int delta_cur = 0;
 
 	/* check the req level and adjust according to tbl entries */
 	rc = mmrm_sw_check_req_level(sinfo, tbl_entry->clk_src_id, req_level, &adj_level);
@@ -706,24 +709,38 @@ static int mmrm_sw_check_peak_current(struct mmrm_sw_clk_mgr_info *sinfo,
 		goto err_invalid_level;
 	}
 
+	/* calculate new cur val as per adj_val */
+	if (clk_val)
+		new_cur = tbl_entry->current_ma[req_level][adj_level] * num_hw_blocks;
+
+
+	/* calculate old cur */
+	if (tbl_entry->clk_rate) {
+		//old_cur = tbl_entry->current_ma[tbl_entry->vdd_level][adj_level];
+		old_cur = tbl_entry->current_ma[tbl_entry->vdd_level]
+			[peak_data->aggreg_level] * tbl_entry->num_hw_blocks;
+	}
+
+	/* 1. adj_level increase: recalculated peak_cur other clients + new_cur
+	 * 2. adj_level decrease: recalculated peak_cur other clients + new_cur
+	 * 3. clk_val increase: aggreg_val + (new_cur - old_cur)
+	 * 4. clk_val decrease: aggreg_val + (new_cur - old_cur)
+	 * 5. clk_val 0: aggreg_val - old_cur
+	 */
+
 	/* recalculate aggregated current with adj level */
 	if (adj_level != peak_data->aggreg_level) {
-		rc = mmrm_sw_calculate_total_current(sinfo, adj_level, &peak_cur);
+		rc = mmrm_sw_calculate_total_current(sinfo, adj_level, &peak_cur, tbl_entry);
 		if (rc) {
 			goto err_invalid_level;
 		}
+		peak_cur += new_cur;
+	} else {
+		delta_cur = (signed int)new_cur - old_cur;
 	}
 
-	/* calculate delta cur */
-	if (tbl_entry->clk_rate) {
-		old_cur = tbl_entry->current_ma[tbl_entry->vdd_level][adj_level];
-	}
-
-	if (clk_val) {
-		new_cur = tbl_entry->current_ma[req_level][adj_level] * num_hw_blocks;
-	}
-
-	delta_cur = (signed)new_cur - old_cur;
+	d_mpr_h("%s: csid (0x%x) peak_cur(%zu) new_cur(%zu) old_cur(%zu) delta_cur(%d)\n",
+		__func__, tbl_entry->clk_src_id, peak_cur, new_cur, old_cur, delta_cur);
 
 	/* negative value, update peak data */
 	if ((signed)peak_cur + delta_cur <= 0) {
@@ -753,6 +770,7 @@ static int mmrm_sw_check_peak_current(struct mmrm_sw_clk_mgr_info *sinfo,
 			goto err_peak_overshoot;
 		}
 	}
+
 	/* update peak data */
 	peak_data->aggreg_val = peak_cur + delta_cur;
 	peak_data->aggreg_level = adj_level;
@@ -848,7 +866,8 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
 	 */
 	req_reserve = client_data->flags & MMRM_CLIENT_DATA_FLAG_RESERVE_ONLY;
 	if (tbl_entry->clk_rate == clk_val &&
-				tbl_entry->num_hw_blocks == client_data->num_hw_blocks) {
+		tbl_entry->num_hw_blocks == client_data->num_hw_blocks) {
+
 		d_mpr_h("%s: csid(0x%x) same as previous clk rate %llu\n",
 			__func__, tbl_entry->clk_src_id, clk_val);