diff --git a/driver/src/mmrm_clk_rsrc_mgr.c b/driver/src/mmrm_clk_rsrc_mgr.c index 027c17b107..4fd26846ad 100644 --- a/driver/src/mmrm_clk_rsrc_mgr.c +++ b/driver/src/mmrm_clk_rsrc_mgr.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include "mmrm_clk_rsrc_mgr.h" diff --git a/driver/src/mmrm_clk_rsrc_mgr.h b/driver/src/mmrm_clk_rsrc_mgr.h index 57acc3ca30..21a313bbc1 100644 --- a/driver/src/mmrm_clk_rsrc_mgr.h +++ b/driver/src/mmrm_clk_rsrc_mgr.h @@ -10,6 +10,7 @@ #include #include "mmrm_internal.h" +#define MMRM_MAX_THROTTLE_CLIENTS 5 enum mmrm_clk_mgr_scheme { CLK_MGR_SCHEME_SW, @@ -17,6 +18,8 @@ enum mmrm_clk_mgr_scheme { }; enum mmrm_sw_vdd_levels { + MMRM_VDD_LEVEL_LOW_SVS, + MMRM_VDD_LEVEL_SVS, MMRM_VDD_LEVEL_SVS_L1, MMRM_VDD_LEVEL_NOM, MMRM_VDD_LEVEL_TURBO, @@ -24,6 +27,8 @@ enum mmrm_sw_vdd_levels { }; static int mmrm_sw_vdd_corner[] = { + [MMRM_VDD_LEVEL_LOW_SVS] = RPMH_REGULATOR_LEVEL_LOW_SVS, + [MMRM_VDD_LEVEL_SVS] = RPMH_REGULATOR_LEVEL_SVS, [MMRM_VDD_LEVEL_SVS_L1] = RPMH_REGULATOR_LEVEL_SVS_L1, [MMRM_VDD_LEVEL_NOM] = RPMH_REGULATOR_LEVEL_NOM, [MMRM_VDD_LEVEL_TURBO] = RPMH_REGULATOR_LEVEL_TURBO @@ -70,6 +75,11 @@ struct mmrm_sw_peak_current_data { u32 aggreg_level; }; +struct mmrm_throttle_info { + u32 csid_throttle_client; + u16 tbl_entry_id; +}; + struct mmrm_sw_clk_mgr_info { void *driver_data; @@ -77,6 +87,8 @@ struct mmrm_sw_clk_mgr_info { struct mmrm_sw_clk_client_tbl_entry *clk_client_tbl; u32 tot_clk_clients; u32 enabled_clk_clients; + struct mmrm_throttle_info throttle_clients_info[MMRM_MAX_THROTTLE_CLIENTS]; + u16 throttle_clients_data_length; /* peak current data */ struct mmrm_sw_peak_current_data peak_cur_data; diff --git a/driver/src/mmrm_clk_rsrc_mgr_cxipeak.c b/driver/src/mmrm_clk_rsrc_mgr_cxipeak.c index 2ca74a791f..0661c4f6cf 100644 --- a/driver/src/mmrm_clk_rsrc_mgr_cxipeak.c +++ b/driver/src/mmrm_clk_rsrc_mgr_cxipeak.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ struct mmrm_client *mmrm_cxipeak_clk_client_register( diff --git a/driver/src/mmrm_clk_rsrc_mgr_sw.c b/driver/src/mmrm_clk_rsrc_mgr_sw.c index 7c1c5c81c1..08e97a5591 100644 --- a/driver/src/mmrm_clk_rsrc_mgr_sw.c +++ b/driver/src/mmrm_clk_rsrc_mgr_sw.c @@ -55,9 +55,8 @@ static int mmrm_sw_update_freq( } /* voltage corner is below svsl1 */ - if (voltage_corner < mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_SVS_L1]) { - voltage_corner = mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_SVS_L1]; - } + if (voltage_corner < mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_LOW_SVS]) + voltage_corner = mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_LOW_SVS]; /* match vdd level */ for (i = 0; i < MMRM_VDD_LEVEL_MAX; i++) { @@ -340,7 +339,8 @@ static int mmrm_sw_clk_client_deregister(struct mmrm_clk_mgr *sw_clk_mgr, if (tbl_entry->ref_count == 0) { kfree(tbl_entry->client); - + tbl_entry->vdd_level = 0; + tbl_entry->clk_rate = 0; tbl_entry->client = NULL; tbl_entry->clk = NULL; tbl_entry->pri = 0x0; @@ -378,13 +378,13 @@ static int mmrm_sw_get_req_level( goto err_invalid_corner; } - /* voltage corner is below svsl1 */ - if (voltage_corner < mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_SVS_L1]) { + /* voltage corner is below low svs */ + if (voltage_corner < mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_LOW_SVS]) { d_mpr_h("%s: csid(0x%x): lower voltage corner(%d)\n", __func__, tbl_entry->clk_src_id, voltage_corner); - *req_level = MMRM_VDD_LEVEL_SVS_L1; + *req_level = MMRM_VDD_LEVEL_LOW_SVS; goto exit_no_err; } @@ -489,41 +489,44 @@ err_invalid_level: static int mmrm_sw_throttle_low_priority_client( struct mmrm_sw_clk_mgr_info *sinfo, u32 *delta_cur) { - int rc = 0, c = 0; + int rc = 0, i; bool found_client_throttle = false; struct mmrm_sw_clk_client_tbl_entry *tbl_entry_throttle_client; struct mmrm_client_notifier_data notifier_data; struct completion timeout; struct mmrm_sw_peak_current_data *peak_data = &sinfo->peak_cur_data; u32 now_cur_ma, min_cur_ma; - long clk_min_level = MMRM_VDD_LEVEL_SVS_L1; + long clk_min_level = MMRM_VDD_LEVEL_LOW_SVS; d_mpr_h("%s: entering\n", __func__); init_completion(&timeout); - for (c = 0; c < sinfo->tot_clk_clients; c++) { - tbl_entry_throttle_client = &sinfo->clk_client_tbl[c]; - now_cur_ma = tbl_entry_throttle_client->current_ma - [tbl_entry_throttle_client->vdd_level][peak_data->aggreg_level]; - min_cur_ma = tbl_entry_throttle_client->current_ma[clk_min_level] - [peak_data->aggreg_level]; - d_mpr_h("%s:csid(0x%x) name(%s) now_cur_ma(%llu) min_cur_ma(%llu) delta_cur(%d)\n", + for (i = 0; i < sinfo->throttle_clients_data_length ; i++) { + tbl_entry_throttle_client = + &sinfo->clk_client_tbl[sinfo->throttle_clients_info[i].tbl_entry_id]; + now_cur_ma = tbl_entry_throttle_client->current_ma + [tbl_entry_throttle_client->vdd_level] + [peak_data->aggreg_level]; + min_cur_ma = tbl_entry_throttle_client->current_ma[clk_min_level] + [peak_data->aggreg_level]; + + d_mpr_h("%s:csid(0x%x) name(%s)\n", __func__, tbl_entry_throttle_client->clk_src_id, - tbl_entry_throttle_client->name, now_cur_ma, min_cur_ma, - *delta_cur); + tbl_entry_throttle_client->name); + d_mpr_h("%s:now_cur_ma(%llu) min_cur_ma(%llu) delta_cur(%d)\n", + __func__, now_cur_ma, min_cur_ma, *delta_cur); - if (tbl_entry_throttle_client - && (tbl_entry_throttle_client->pri == MMRM_CLIENT_PRIOR_LOW) - && (now_cur_ma > min_cur_ma) && (now_cur_ma - min_cur_ma > *delta_cur)) { - found_client_throttle = true; - d_mpr_h("%s: Throttle client csid(0x%x) name(%s)\n", __func__, - tbl_entry_throttle_client->clk_src_id, - tbl_entry_throttle_client->name); - d_mpr_h("%s: now_cur_ma(%llu) - min_cur_ma(%llu) > delta_cur(%d)\n", - __func__, now_cur_ma, min_cur_ma, *delta_cur); - - /* found client to throttle, break from here. */ - break; + if (tbl_entry_throttle_client + && (now_cur_ma > min_cur_ma) + && (now_cur_ma - min_cur_ma > *delta_cur)) { + found_client_throttle = true; + d_mpr_h("%s: Throttle client csid(0x%x) name(%s)\n", + __func__, tbl_entry_throttle_client->clk_src_id, + tbl_entry_throttle_client->name); + d_mpr_h("%s:now_cur_ma %llu-min_cur_ma %llu>delta_cur %d\n", + __func__, now_cur_ma, min_cur_ma, *delta_cur); + /* found client to throttle, break from here. */ + break; } } @@ -536,14 +539,11 @@ static int mmrm_sw_throttle_low_priority_client( tbl_entry_throttle_client->freq[tbl_entry_throttle_client->vdd_level]; notifier_data.cb_data.val_chng.new_val = tbl_entry_throttle_client->freq[clk_min_level]; - notifier_data.pvt_data = NULL; + notifier_data.pvt_data = tbl_entry_throttle_client->pvt_data; if (tbl_entry_throttle_client->notifier_cb_fn) rc = tbl_entry_throttle_client->notifier_cb_fn(¬ifier_data); - if (!wait_for_completion_timeout(&timeout, CLIENT_CB_TIMEOUT)) - d_mpr_h("Intentionally added to wait for 100ms\n", __func__); - if (rc) { d_mpr_e("%s: Client failed to send SUCCESS in callback(%d)\n", __func__, tbl_entry_throttle_client->clk_src_id); @@ -559,6 +559,9 @@ static int mmrm_sw_throttle_low_priority_client( rc = -EINVAL; goto err_clk_set_fail; } else { + d_mpr_h("%s: %s throttled to %llu\n", + __func__, tbl_entry_throttle_client->name, + tbl_entry_throttle_client->freq[clk_min_level]); *delta_cur = now_cur_ma - min_cur_ma; } /* Store the throttled clock rate of client */ @@ -570,6 +573,7 @@ static int mmrm_sw_throttle_low_priority_client( /* Clearing the reserve flag */ tbl_entry_throttle_client->reserve = tbl_entry_throttle_client->reserve & 0; + d_mpr_h("%s: exiting\n", __func__); } err_clk_set_fail: return rc; @@ -664,8 +668,6 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr, bool req_reserve; u32 req_level; - d_mpr_h("%s: entering\n", __func__); - /* validate input params */ if (!client) { d_mpr_e("%s: invalid client\n"); @@ -693,6 +695,8 @@ static int mmrm_sw_clk_client_setval(struct mmrm_clk_mgr *sw_clk_mgr, rc = -EINVAL; goto err_invalid_client; } + d_mpr_h("%s: csid(0x%x) clk rate %llu\n", + __func__, tbl_entry->clk_src_id, clk_val); /* Check if the requested clk rate is the same as the current clk rate. * When clk rates are the same, compare this with the current state. @@ -777,7 +781,8 @@ set_clk_rate: } exit_no_err: - d_mpr_h("%s: exiting with success\n", __func__); + d_mpr_h("%s: clk rate %llu set successfully for %s\n", + __func__, clk_val, tbl_entry->name); return rc; err_invalid_client: @@ -889,7 +894,7 @@ static int mmrm_sw_prepare_table(struct mmrm_clk_platform_resources *cres, int mmrm_init_sw_clk_mgr(void *driver_data) { - int rc = 0; + int rc = 0, i, j; struct mmrm_driver_data *drv_data = (struct mmrm_driver_data *)driver_data; struct mmrm_clk_platform_resources *cres = &drv_data->clk_res; @@ -936,7 +941,19 @@ int mmrm_init_sw_clk_mgr(void *driver_data) /* update the peak current threshold */ sinfo->peak_cur_data.threshold = cres->threshold; sinfo->peak_cur_data.aggreg_val = 0; - sinfo->peak_cur_data.aggreg_level = MMRM_VDD_LEVEL_SVS_L1; + sinfo->peak_cur_data.aggreg_level = 0; + sinfo->throttle_clients_data_length = cres->throttle_clients_data_length; + for (i = 0; i < sinfo->throttle_clients_data_length; i++) { + for (j = 0; j < sinfo->tot_clk_clients; j++) { + if (sinfo->clk_client_tbl[j].clk_src_id + == cres->clsid_threshold_clients[i]) { + sinfo->throttle_clients_info[i].csid_throttle_client + = cres->clsid_threshold_clients[i]; + sinfo->throttle_clients_info[i].tbl_entry_id = j; + break; + } + } + } /* initialize mutex for sw clk mgr */ mutex_init(&sw_clk_mgr->lock); diff --git a/driver/src/mmrm_debug.h b/driver/src/mmrm_debug.h index 64852252b4..f216c531e8 100644 --- a/driver/src/mmrm_debug.h +++ b/driver/src/mmrm_debug.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #ifndef __MMRM_DEBUG__ diff --git a/driver/src/mmrm_fixedpoint.h b/driver/src/mmrm_fixedpoint.h index f05f017963..6921d9dd85 100644 --- a/driver/src/mmrm_fixedpoint.h +++ b/driver/src/mmrm_fixedpoint.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #ifdef _FIXP_ARITH_H diff --git a/driver/src/mmrm_internal.c b/driver/src/mmrm_internal.c index acd3be5163..8c1adae0df 100644 --- a/driver/src/mmrm_internal.c +++ b/driver/src/mmrm_internal.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include @@ -20,9 +20,36 @@ static struct mmrm_common_data waipio_common_data[] = { }, }; +/*throttle client list is as per fdd & resource availability*/ + +static struct mmrm_throttle_clients_data waipio_throttle_clients_data[] = { + { + .domain = MMRM_CLIENT_DOMAIN_DISPLAY, + .id = 0x3d, + }, + { + .domain = MMRM_CLIENT_DOMAIN_VIDEO, + .id = 0x03, + }, + { + .domain = MMRM_CLIENT_DOMAIN_CAMERA, + .id = 0x46, + }, + { + .domain = MMRM_CLIENT_DOMAIN_CVP, + .id = 0x08, + }, + { + .domain = MMRM_CLIENT_DOMAIN_CAMERA, + .id = 0x02, + }, +}; + static struct mmrm_platform_data waipio_data = { .common_data = waipio_common_data, .common_data_length = ARRAY_SIZE(waipio_common_data), + .throttle_clk_clients_data = waipio_throttle_clients_data, + .throttle_clk_clients_data_length = ARRAY_SIZE(waipio_throttle_clients_data), }; static const struct of_device_id mmrm_dt_match[] = { diff --git a/driver/src/mmrm_internal.h b/driver/src/mmrm_internal.h index 2bc20b2c97..32656dc051 100644 --- a/driver/src/mmrm_internal.h +++ b/driver/src/mmrm_internal.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #ifndef _MMRM_INTERNAL_H_ @@ -17,9 +17,16 @@ struct mmrm_common_data { int value; }; +struct mmrm_throttle_clients_data { + u32 domain; + u32 id; +}; + struct mmrm_platform_data { struct mmrm_common_data *common_data; + struct mmrm_throttle_clients_data *throttle_clk_clients_data; u32 common_data_length; + u16 throttle_clk_clients_data_length; u32 scheme; }; diff --git a/driver/src/mmrm_res_parse.c b/driver/src/mmrm_res_parse.c index 99657e7f39..259bb1b5f4 100644 --- a/driver/src/mmrm_res_parse.c +++ b/driver/src/mmrm_res_parse.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include @@ -30,7 +30,7 @@ static int mmrm_read_clk_pltfrm_rsrc_frm_drv_data( { struct mmrm_platform_data *pdata; struct mmrm_clk_platform_resources *cres; - int rc = 0; + int i = 0; pdata = ddata->platform_data; cres = &ddata->clk_res; @@ -44,8 +44,15 @@ static int mmrm_read_clk_pltfrm_rsrc_frm_drv_data( "qcom,mmrm_clk_mgr_scheme"); d_mpr_h("%s: configured mmrm scheme %d\n", __func__, cres->scheme); + cres->throttle_clients_data_length = pdata->throttle_clk_clients_data_length; - return rc; + for (i = 0; i < pdata->throttle_clk_clients_data_length; i++) { + cres->clsid_threshold_clients[i] = + (pdata->throttle_clk_clients_data[i].domain << 16 + | pdata->throttle_clk_clients_data[i].id); + } + + return 0; } static void mmrm_free_rail_corner_table( diff --git a/driver/src/mmrm_resources.h b/driver/src/mmrm_resources.h index 002d7eca59..7656b624f0 100644 --- a/driver/src/mmrm_resources.h +++ b/driver/src/mmrm_resources.h @@ -1,12 +1,13 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #ifndef _MMRM_RESOURCES_H_ #define _MMRM_RESOURCES_H_ #include +#define MMRM_MAX_THROTTLE_CLIENTS 5 struct corner_info { const char *name; @@ -36,6 +37,8 @@ struct mmrm_clk_platform_resources { struct platform_device *pdev; u32 threshold; u32 scheme; + u32 clsid_threshold_clients[MMRM_MAX_THROTTLE_CLIENTS]; + u16 throttle_clients_data_length; struct voltage_corner_set corner_set; struct nom_clk_src_set nom_clk_set; }; diff --git a/driver/src/msm_mmrm.c b/driver/src/msm_mmrm.c index 5ce639f05e..7506b41c70 100644 --- a/driver/src/msm_mmrm.c +++ b/driver/src/msm_mmrm.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. */ #include