|
@@ -475,16 +475,23 @@ static int mmrm_sw_get_req_level(
|
|
{
|
|
{
|
|
int rc = 0;
|
|
int rc = 0;
|
|
int voltage_corner;
|
|
int voltage_corner;
|
|
|
|
+ unsigned long clk_round_val = 0;
|
|
u32 level;
|
|
u32 level;
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * Clients may set rates that are higher than max supported rate for a clock.
|
|
|
|
+ * Round the rate to get the max supported corner.
|
|
|
|
+ */
|
|
|
|
+ clk_round_val = clk_round_rate(tbl_entry->clk, clk_val);
|
|
|
|
+
|
|
/* get voltage corner */
|
|
/* get voltage corner */
|
|
- voltage_corner = qcom_clk_get_voltage(tbl_entry->clk, clk_val);
|
|
|
|
|
|
+ voltage_corner = qcom_clk_get_voltage(tbl_entry->clk, clk_round_val);
|
|
if (voltage_corner < 0 || voltage_corner > mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_TURBO]) {
|
|
if (voltage_corner < 0 || voltage_corner > mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_TURBO]) {
|
|
- d_mpr_e("%s: csid(0x%x): invalid voltage corner(%d) for clk rate(%llu)\n",
|
|
|
|
|
|
+ d_mpr_e("%s: csid(0x%x): invalid voltage corner(%d) for rounded clk rate(%llu)\n",
|
|
__func__,
|
|
__func__,
|
|
tbl_entry->clk_src_id,
|
|
tbl_entry->clk_src_id,
|
|
voltage_corner,
|
|
voltage_corner,
|
|
- clk_val);
|
|
|
|
|
|
+ clk_round_val);
|
|
rc = voltage_corner;
|
|
rc = voltage_corner;
|
|
goto err_invalid_corner;
|
|
goto err_invalid_corner;
|
|
}
|
|
}
|
|
@@ -506,11 +513,11 @@ static int mmrm_sw_get_req_level(
|
|
}
|
|
}
|
|
|
|
|
|
if (level == MMRM_VDD_LEVEL_MAX) {
|
|
if (level == MMRM_VDD_LEVEL_MAX) {
|
|
- d_mpr_e("%s: csid(0x%x): invalid voltage corner(%d) for clk rate(%llu)\n",
|
|
|
|
|
|
+ d_mpr_e("%s: csid(0x%x): invalid voltage corner(%d) for rounded clk rate(%llu)\n",
|
|
__func__,
|
|
__func__,
|
|
tbl_entry->clk_src_id,
|
|
tbl_entry->clk_src_id,
|
|
voltage_corner,
|
|
voltage_corner,
|
|
- clk_val);
|
|
|
|
|
|
+ clk_round_val);
|
|
rc = -EINVAL;
|
|
rc = -EINVAL;
|
|
goto err_invalid_corner;
|
|
goto err_invalid_corner;
|
|
}
|
|
}
|
|
@@ -918,7 +925,6 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
|
|
bool req_reserve;
|
|
bool req_reserve;
|
|
u32 req_level;
|
|
u32 req_level;
|
|
unsigned long crm_max_rate = 0;
|
|
unsigned long crm_max_rate = 0;
|
|
- unsigned long clk_round_val = 0;
|
|
|
|
int max_rate_idx = 0;
|
|
int max_rate_idx = 0;
|
|
|
|
|
|
/* validate input params */
|
|
/* validate input params */
|
|
@@ -949,17 +955,8 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
|
|
goto err_invalid_client;
|
|
goto err_invalid_client;
|
|
}
|
|
}
|
|
|
|
|
|
- /*
|
|
|
|
- * Clients may set rates that are higher than max supported rate for a clock.
|
|
|
|
- * Round the rate to max supported rate and use this rate for tracking/calculations.
|
|
|
|
- * Use the client-set value to set the rate to clock driver - clock driver internally
|
|
|
|
- * rounds the rate to max supported value.
|
|
|
|
- */
|
|
|
|
- if (clk_val != 0)
|
|
|
|
- clk_round_val = clk_round_rate(tbl_entry->clk, clk_val);
|
|
|
|
-
|
|
|
|
- d_mpr_h("%s: csid(0x%x) clk rate %llu, clk round rate %llu\n",
|
|
|
|
- __func__, tbl_entry->clk_src_id, clk_val, clk_round_val);
|
|
|
|
|
|
+ d_mpr_h("%s: csid(0x%x) clk rate %llu\n",
|
|
|
|
+ __func__, tbl_entry->clk_src_id, clk_val);
|
|
|
|
|
|
if (tbl_entry->is_crm_client) {
|
|
if (tbl_entry->is_crm_client) {
|
|
if (client_data->crm_drv_idx >= tbl_entry->hw_drv_instances ||
|
|
if (client_data->crm_drv_idx >= tbl_entry->hw_drv_instances ||
|
|
@@ -970,7 +967,7 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
|
|
}
|
|
}
|
|
|
|
|
|
crm_max_rate = mmrm_sw_get_max_crm_rate(tbl_entry, client_data,
|
|
crm_max_rate = mmrm_sw_get_max_crm_rate(tbl_entry, client_data,
|
|
- clk_round_val, &max_rate_idx);
|
|
|
|
|
|
+ clk_val, &max_rate_idx);
|
|
}
|
|
}
|
|
|
|
|
|
/*
|
|
/*
|
|
@@ -985,12 +982,12 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
|
|
* d. reserve && !req_reserve: set clk rate
|
|
* d. reserve && !req_reserve: set clk rate
|
|
*/
|
|
*/
|
|
req_reserve = client_data->flags & MMRM_CLIENT_DATA_FLAG_RESERVE_ONLY;
|
|
req_reserve = client_data->flags & MMRM_CLIENT_DATA_FLAG_RESERVE_ONLY;
|
|
- if (tbl_entry->clk_rate == clk_round_val &&
|
|
|
|
|
|
+ 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 &&
|
|
tbl_entry->is_crm_client == false) {
|
|
tbl_entry->is_crm_client == false) {
|
|
|
|
|
|
- d_mpr_h("%s: csid(0x%x) same as previous (rounded) clk rate %llu\n",
|
|
|
|
- __func__, tbl_entry->clk_src_id, clk_round_val);
|
|
|
|
|
|
+ d_mpr_h("%s: csid(0x%x) same as previous clk rate %llu\n",
|
|
|
|
+ __func__, tbl_entry->clk_src_id, clk_val);
|
|
|
|
|
|
/* a & b */
|
|
/* a & b */
|
|
if (tbl_entry->reserve == req_reserve)
|
|
if (tbl_entry->reserve == req_reserve)
|
|
@@ -1009,14 +1006,14 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
|
|
}
|
|
}
|
|
|
|
|
|
/* get corresponding level */
|
|
/* get corresponding level */
|
|
- if (clk_round_val) {
|
|
|
|
|
|
+ if (clk_val) {
|
|
if (!tbl_entry->is_crm_client)
|
|
if (!tbl_entry->is_crm_client)
|
|
- rc = mmrm_sw_get_req_level(tbl_entry, clk_round_val, &req_level);
|
|
|
|
|
|
+ rc = mmrm_sw_get_req_level(tbl_entry, clk_val, &req_level);
|
|
else
|
|
else
|
|
rc = mmrm_sw_get_req_level(tbl_entry, crm_max_rate, &req_level);
|
|
rc = mmrm_sw_get_req_level(tbl_entry, crm_max_rate, &req_level);
|
|
if (rc || req_level >= MMRM_VDD_LEVEL_MAX) {
|
|
if (rc || req_level >= MMRM_VDD_LEVEL_MAX) {
|
|
d_mpr_e("%s: csid(0x%x) unable to get level for clk rate %llu crm_max_rate %llu\n",
|
|
d_mpr_e("%s: csid(0x%x) unable to get level for clk rate %llu crm_max_rate %llu\n",
|
|
- __func__, tbl_entry->clk_src_id, clk_round_val, crm_max_rate);
|
|
|
|
|
|
+ __func__, tbl_entry->clk_src_id, clk_val, crm_max_rate);
|
|
rc = -EINVAL;
|
|
rc = -EINVAL;
|
|
goto err_invalid_clk_val;
|
|
goto err_invalid_clk_val;
|
|
}
|
|
}
|
|
@@ -1036,7 +1033,7 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
|
|
/* check and update for peak current */
|
|
/* check and update for peak current */
|
|
if (!tbl_entry->is_crm_client) {
|
|
if (!tbl_entry->is_crm_client) {
|
|
rc = mmrm_sw_check_peak_current(sinfo, tbl_entry,
|
|
rc = mmrm_sw_check_peak_current(sinfo, tbl_entry,
|
|
- req_level, clk_round_val, client_data->num_hw_blocks);
|
|
|
|
|
|
+ req_level, clk_val, client_data->num_hw_blocks);
|
|
} else {
|
|
} else {
|
|
rc = mmrm_sw_check_peak_current(sinfo, tbl_entry,
|
|
rc = mmrm_sw_check_peak_current(sinfo, tbl_entry,
|
|
req_level, crm_max_rate, client_data->num_hw_blocks);
|
|
req_level, crm_max_rate, client_data->num_hw_blocks);
|
|
@@ -1052,16 +1049,16 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
|
|
|
|
|
|
/* update table entry */
|
|
/* update table entry */
|
|
if (!tbl_entry->is_crm_client) {
|
|
if (!tbl_entry->is_crm_client) {
|
|
- tbl_entry->clk_rate = clk_round_val;
|
|
|
|
|
|
+ tbl_entry->clk_rate = clk_val;
|
|
} else {
|
|
} else {
|
|
tbl_entry->max_rate_idx = max_rate_idx;
|
|
tbl_entry->max_rate_idx = max_rate_idx;
|
|
tbl_entry->clk_rate = crm_max_rate;
|
|
tbl_entry->clk_rate = crm_max_rate;
|
|
if (client_data->drv_type == MMRM_CRM_SW_DRV)
|
|
if (client_data->drv_type == MMRM_CRM_SW_DRV)
|
|
- tbl_entry->crm_client_tbl[tbl_entry->crm_client_tbl_size - 1] = clk_round_val;
|
|
|
|
|
|
+ tbl_entry->crm_client_tbl[tbl_entry->crm_client_tbl_size - 1] = clk_val;
|
|
else
|
|
else
|
|
tbl_entry->crm_client_tbl[tbl_entry->num_pwr_states *
|
|
tbl_entry->crm_client_tbl[tbl_entry->num_pwr_states *
|
|
client_data->crm_drv_idx +
|
|
client_data->crm_drv_idx +
|
|
- client_data->pwr_st] = clk_round_val;
|
|
|
|
|
|
+ client_data->pwr_st] = clk_val;
|
|
|
|
|
|
mmrm_sw_print_crm_table(tbl_entry);
|
|
mmrm_sw_print_crm_table(tbl_entry);
|
|
}
|
|
}
|
|
@@ -1081,29 +1078,30 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr,
|
|
|
|
|
|
set_clk_rate:
|
|
set_clk_rate:
|
|
if (!tbl_entry->is_crm_client || client_data->drv_type == MMRM_CRM_SW_DRV) {
|
|
if (!tbl_entry->is_crm_client || client_data->drv_type == MMRM_CRM_SW_DRV) {
|
|
- d_mpr_h("%s: csid(0x%x) setting rounded clk rate %llu\n",
|
|
|
|
- __func__, tbl_entry->clk_src_id, clk_round_val);
|
|
|
|
|
|
+ d_mpr_h("%s: csid(0x%x) setting clk rate %llu\n",
|
|
|
|
+ __func__, tbl_entry->clk_src_id, clk_val);
|
|
|
|
|
|
- rc = clk_set_rate(tbl_entry->clk, clk_round_val);
|
|
|
|
|
|
+ rc = clk_set_rate(tbl_entry->clk, clk_val);
|
|
if (rc) {
|
|
if (rc) {
|
|
- d_mpr_e("%s: csid(0x%x) failed to set rounded clk rate %llu\n",
|
|
|
|
- __func__, tbl_entry->clk_src_id, clk_round_val);
|
|
|
|
|
|
+ d_mpr_e("%s: csid(0x%x) failed to set clk rate %llu\n",
|
|
|
|
+ __func__, tbl_entry->clk_src_id, clk_val);
|
|
rc = -EINVAL;
|
|
rc = -EINVAL;
|
|
/* TBD: incase of failure clk_rate is invalid */
|
|
/* TBD: incase of failure clk_rate is invalid */
|
|
goto err_clk_set_fail;
|
|
goto err_clk_set_fail;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
- d_mpr_h("%s: csid(0x%x) setting rounded clk rate %llu drv_type %u, crm_drv_idx %u, pwr_st %u\n",
|
|
|
|
- __func__, tbl_entry->clk_src_id, clk_round_val,
|
|
|
|
- CRM_HW_DRV, client_data->crm_drv_idx,
|
|
|
|
- client_data->pwr_st);
|
|
|
|
|
|
+ d_mpr_h(
|
|
|
|
+ "%s: csid(0x%x) setting clk rate %llu drv_type %u, crm_drv_idx %u, pwr_st %u\n",
|
|
|
|
+ __func__, tbl_entry->clk_src_id, clk_val,
|
|
|
|
+ CRM_HW_DRV, client_data->crm_drv_idx,
|
|
|
|
+ client_data->pwr_st);
|
|
|
|
|
|
rc = qcom_clk_crm_set_rate(tbl_entry->clk, CRM_HW_DRV,
|
|
rc = qcom_clk_crm_set_rate(tbl_entry->clk, CRM_HW_DRV,
|
|
client_data->crm_drv_idx,
|
|
client_data->crm_drv_idx,
|
|
- client_data->pwr_st, clk_round_val);
|
|
|
|
|
|
+ client_data->pwr_st, clk_val);
|
|
if (rc) {
|
|
if (rc) {
|
|
- d_mpr_e("%s: csid(0x%x) failed to set rounded clk rate %llu\n",
|
|
|
|
- __func__, tbl_entry->clk_src_id, clk_round_val);
|
|
|
|
|
|
+ d_mpr_e("%s: csid(0x%x) failed to set clk rate %llu\n",
|
|
|
|
+ __func__, tbl_entry->clk_src_id, clk_val);
|
|
rc = -EINVAL;
|
|
rc = -EINVAL;
|
|
/* TBD: incase of failure clk_rate is invalid */
|
|
/* TBD: incase of failure clk_rate is invalid */
|
|
goto err_clk_set_fail;
|
|
goto err_clk_set_fail;
|
|
@@ -1111,8 +1109,8 @@ set_clk_rate:
|
|
}
|
|
}
|
|
|
|
|
|
exit_no_err:
|
|
exit_no_err:
|
|
- d_mpr_h("%s: clk rate (round) %lu set successfully for %s\n",
|
|
|
|
- __func__, clk_round_val, tbl_entry->name);
|
|
|
|
|
|
+ d_mpr_h("%s: clk rate %lu set successfully for %s\n",
|
|
|
|
+ __func__, clk_val, tbl_entry->name);
|
|
return rc;
|
|
return rc;
|
|
|
|
|
|
err_invalid_client:
|
|
err_invalid_client:
|