Quellcode durchsuchen

msm-mmrm: Add support to number of hw blocks

Add number of hw blocks support for peak current calculation.
With this support multiple blocks of same clock can be accounted
for peak current.

Change-Id: I277636cedc4cda731fc845dcba3e742e840446d4
Signed-off-by: mbao <[email protected]>
mbao vor 4 Jahren
Ursprung
Commit
aa373d648a
2 geänderte Dateien mit 30 neuen und 6 gelöschten Zeilen
  1. 1 0
      driver/src/mmrm_clk_rsrc_mgr.h
  2. 29 6
      driver/src/mmrm_clk_rsrc_mgr_sw.c

+ 1 - 0
driver/src/mmrm_clk_rsrc_mgr.h

@@ -64,6 +64,7 @@ struct mmrm_sw_clk_client_tbl_entry {
 	u32 vdd_level;
 	bool reserve;
 	u32 ref_count;
+	u32 num_hw_blocks;
 };
 
 struct mmrm_sw_throttled_clients_data {

+ 29 - 6
driver/src/mmrm_clk_rsrc_mgr_sw.c

@@ -16,7 +16,6 @@
 #define CLK_RATE_STEP 1000000
 #define CLIENT_CB_TIMEOUT msecs_to_jiffies(100)
 
-
 static int mmrm_sw_update_freq(
 	struct mmrm_sw_clk_mgr_info *sinfo, struct mmrm_sw_clk_client_tbl_entry *tbl_entry)
 {
@@ -662,7 +661,7 @@ static int mmrm_reinstate_throttled_client(struct mmrm_sw_clk_mgr_info *sinfo) {
 
 static int mmrm_sw_check_peak_current(struct mmrm_sw_clk_mgr_info *sinfo,
 	struct mmrm_sw_clk_client_tbl_entry *tbl_entry,
-	u32 req_level, u32 clk_val)
+	u32 req_level, u32 clk_val, u32 num_hw_blocks)
 {
 	int rc = 0;
 	struct mmrm_sw_peak_current_data *peak_data = &sinfo->peak_cur_data;
@@ -692,7 +691,7 @@ static int mmrm_sw_check_peak_current(struct mmrm_sw_clk_mgr_info *sinfo,
 	}
 
 	if (clk_val) {
-		new_cur = tbl_entry->current_ma[req_level][adj_level];
+		new_cur = tbl_entry->current_ma[req_level][adj_level] * num_hw_blocks;
 	}
 
 	delta_cur = (signed)new_cur - old_cur;
@@ -742,6 +741,21 @@ err_peak_overshoot:
 	return rc;
 }
 
+static bool mmrm_sw_is_valid_num_hw_block(struct mmrm_sw_clk_client_tbl_entry *tbl_entry,
+	struct mmrm_client_data *client_data)
+{
+	bool rc = false;
+	u32 num_hw_blocks = client_data->num_hw_blocks;
+
+	if (num_hw_blocks == 1) {
+		rc = true;
+	} else if  (tbl_entry->clk_src_id == 0x10025) { // CAM_CC_IFE_CSID_CLK_SRC
+		if (num_hw_blocks >= 1 && num_hw_blocks <= 3)
+			rc = true;
+	}
+	return rc;
+}
+
 static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
 	struct mmrm_client *client,
 	struct mmrm_client_data *client_data,
@@ -793,7 +807,8 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
 	 * d.  reserve  && !req_reserve:  set clk rate
 	 */
 	req_reserve = client_data->flags & MMRM_CLIENT_DATA_FLAG_RESERVE_ONLY;
-	if (tbl_entry->clk_rate == clk_val) {
+	if (tbl_entry->clk_rate == clk_val &&
+				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);
 
@@ -825,11 +840,18 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
 	} else {
 		req_level = 0;
 	}
+	if (!mmrm_sw_is_valid_num_hw_block(tbl_entry, client_data)) {
+		d_mpr_e("%s: csid(0x%x) num_hw_block:%d\n",
+			__func__, tbl_entry->clk_src_id, client_data->num_hw_blocks);
+		rc = -EINVAL;
+		goto err_invalid_client_data;
+	}
 
 	mutex_lock(&sw_clk_mgr->lock);
 
 	/* check and update for peak current */
-	rc = mmrm_sw_check_peak_current(sinfo, tbl_entry, req_level, clk_val);
+	rc = mmrm_sw_check_peak_current(sinfo, tbl_entry,
+		req_level, clk_val, client_data->num_hw_blocks);
 	if (rc) {
 		d_mpr_e("%s: csid (0x%x) peak overshoot peak_cur(%lu)\n",
 			__func__, tbl_entry->clk_src_id,
@@ -842,6 +864,7 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
 	tbl_entry->clk_rate = clk_val;
 	tbl_entry->vdd_level = req_level;
 	tbl_entry->reserve = req_reserve;
+	tbl_entry->num_hw_blocks = client_data->num_hw_blocks;
 
 	mutex_unlock(&sw_clk_mgr->lock);
 
@@ -866,7 +889,7 @@ set_clk_rate:
 	}
 
 exit_no_err:
-	d_mpr_h("%s: clk rate %llu set successfully for %s\n",
+	d_mpr_h("%s: clk rate %lu set successfully for %s\n",
 			__func__, clk_val, tbl_entry->name);
 	return rc;