msm_mmrm: Add support of new low voltage corners in mmrm driver
Add support of low priority voltage corners lowsvs and svs in mmrm driver. This logic maintains a list of clients which are to be proritize to be throtlled to low power in order to satisfy high priority client's power requiretment. Change-Id: Ia7f912e41bbcff057c0732cc7c2b16e327c59fd8 Signed-off-by: Mahesh Kumar Sharma <smahesh@codeaurora.org>
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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"
|
#include "mmrm_clk_rsrc_mgr.h"
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
#include <linux/soc/qcom/msm_mmrm.h>
|
#include <linux/soc/qcom/msm_mmrm.h>
|
||||||
|
|
||||||
#include "mmrm_internal.h"
|
#include "mmrm_internal.h"
|
||||||
|
#define MMRM_MAX_THROTTLE_CLIENTS 5
|
||||||
|
|
||||||
enum mmrm_clk_mgr_scheme {
|
enum mmrm_clk_mgr_scheme {
|
||||||
CLK_MGR_SCHEME_SW,
|
CLK_MGR_SCHEME_SW,
|
||||||
@@ -17,6 +18,8 @@ enum mmrm_clk_mgr_scheme {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum mmrm_sw_vdd_levels {
|
enum mmrm_sw_vdd_levels {
|
||||||
|
MMRM_VDD_LEVEL_LOW_SVS,
|
||||||
|
MMRM_VDD_LEVEL_SVS,
|
||||||
MMRM_VDD_LEVEL_SVS_L1,
|
MMRM_VDD_LEVEL_SVS_L1,
|
||||||
MMRM_VDD_LEVEL_NOM,
|
MMRM_VDD_LEVEL_NOM,
|
||||||
MMRM_VDD_LEVEL_TURBO,
|
MMRM_VDD_LEVEL_TURBO,
|
||||||
@@ -24,6 +27,8 @@ enum mmrm_sw_vdd_levels {
|
|||||||
};
|
};
|
||||||
|
|
||||||
static int mmrm_sw_vdd_corner[] = {
|
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_SVS_L1] = RPMH_REGULATOR_LEVEL_SVS_L1,
|
||||||
[MMRM_VDD_LEVEL_NOM] = RPMH_REGULATOR_LEVEL_NOM,
|
[MMRM_VDD_LEVEL_NOM] = RPMH_REGULATOR_LEVEL_NOM,
|
||||||
[MMRM_VDD_LEVEL_TURBO] = RPMH_REGULATOR_LEVEL_TURBO
|
[MMRM_VDD_LEVEL_TURBO] = RPMH_REGULATOR_LEVEL_TURBO
|
||||||
@@ -70,6 +75,11 @@ struct mmrm_sw_peak_current_data {
|
|||||||
u32 aggreg_level;
|
u32 aggreg_level;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mmrm_throttle_info {
|
||||||
|
u32 csid_throttle_client;
|
||||||
|
u16 tbl_entry_id;
|
||||||
|
};
|
||||||
|
|
||||||
struct mmrm_sw_clk_mgr_info {
|
struct mmrm_sw_clk_mgr_info {
|
||||||
void *driver_data;
|
void *driver_data;
|
||||||
|
|
||||||
@@ -77,6 +87,8 @@ struct mmrm_sw_clk_mgr_info {
|
|||||||
struct mmrm_sw_clk_client_tbl_entry *clk_client_tbl;
|
struct mmrm_sw_clk_client_tbl_entry *clk_client_tbl;
|
||||||
u32 tot_clk_clients;
|
u32 tot_clk_clients;
|
||||||
u32 enabled_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 */
|
/* peak current data */
|
||||||
struct mmrm_sw_peak_current_data peak_cur_data;
|
struct mmrm_sw_peak_current_data peak_cur_data;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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(
|
struct mmrm_client *mmrm_cxipeak_clk_client_register(
|
||||||
|
@@ -55,9 +55,8 @@ static int mmrm_sw_update_freq(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* voltage corner is below svsl1 */
|
/* voltage corner is below svsl1 */
|
||||||
if (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_SVS_L1];
|
voltage_corner = mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_LOW_SVS];
|
||||||
}
|
|
||||||
|
|
||||||
/* match vdd level */
|
/* match vdd level */
|
||||||
for (i = 0; i < MMRM_VDD_LEVEL_MAX; i++) {
|
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) {
|
if (tbl_entry->ref_count == 0) {
|
||||||
|
|
||||||
kfree(tbl_entry->client);
|
kfree(tbl_entry->client);
|
||||||
|
tbl_entry->vdd_level = 0;
|
||||||
|
tbl_entry->clk_rate = 0;
|
||||||
tbl_entry->client = NULL;
|
tbl_entry->client = NULL;
|
||||||
tbl_entry->clk = NULL;
|
tbl_entry->clk = NULL;
|
||||||
tbl_entry->pri = 0x0;
|
tbl_entry->pri = 0x0;
|
||||||
@@ -378,13 +378,13 @@ static int mmrm_sw_get_req_level(
|
|||||||
goto err_invalid_corner;
|
goto err_invalid_corner;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* voltage corner is below svsl1 */
|
/* voltage corner is below low svs */
|
||||||
if (voltage_corner < mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_SVS_L1]) {
|
if (voltage_corner < mmrm_sw_vdd_corner[MMRM_VDD_LEVEL_LOW_SVS]) {
|
||||||
d_mpr_h("%s: csid(0x%x): lower voltage corner(%d)\n",
|
d_mpr_h("%s: csid(0x%x): lower voltage corner(%d)\n",
|
||||||
__func__,
|
__func__,
|
||||||
tbl_entry->clk_src_id,
|
tbl_entry->clk_src_id,
|
||||||
voltage_corner);
|
voltage_corner);
|
||||||
*req_level = MMRM_VDD_LEVEL_SVS_L1;
|
*req_level = MMRM_VDD_LEVEL_LOW_SVS;
|
||||||
goto exit_no_err;
|
goto exit_no_err;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,41 +489,44 @@ err_invalid_level:
|
|||||||
static int mmrm_sw_throttle_low_priority_client(
|
static int mmrm_sw_throttle_low_priority_client(
|
||||||
struct mmrm_sw_clk_mgr_info *sinfo, u32 *delta_cur)
|
struct mmrm_sw_clk_mgr_info *sinfo, u32 *delta_cur)
|
||||||
{
|
{
|
||||||
int rc = 0, c = 0;
|
int rc = 0, i;
|
||||||
bool found_client_throttle = false;
|
bool found_client_throttle = false;
|
||||||
struct mmrm_sw_clk_client_tbl_entry *tbl_entry_throttle_client;
|
struct mmrm_sw_clk_client_tbl_entry *tbl_entry_throttle_client;
|
||||||
struct mmrm_client_notifier_data notifier_data;
|
struct mmrm_client_notifier_data notifier_data;
|
||||||
struct completion timeout;
|
struct completion timeout;
|
||||||
struct mmrm_sw_peak_current_data *peak_data = &sinfo->peak_cur_data;
|
struct mmrm_sw_peak_current_data *peak_data = &sinfo->peak_cur_data;
|
||||||
u32 now_cur_ma, min_cur_ma;
|
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__);
|
d_mpr_h("%s: entering\n", __func__);
|
||||||
init_completion(&timeout);
|
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,
|
__func__, tbl_entry_throttle_client->clk_src_id,
|
||||||
tbl_entry_throttle_client->name, now_cur_ma, min_cur_ma,
|
tbl_entry_throttle_client->name);
|
||||||
*delta_cur);
|
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
|
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) && (now_cur_ma - min_cur_ma > *delta_cur)) {
|
&& (now_cur_ma - min_cur_ma > *delta_cur)) {
|
||||||
found_client_throttle = true;
|
found_client_throttle = true;
|
||||||
d_mpr_h("%s: Throttle client csid(0x%x) name(%s)\n", __func__,
|
d_mpr_h("%s: Throttle client csid(0x%x) name(%s)\n",
|
||||||
tbl_entry_throttle_client->clk_src_id,
|
__func__, tbl_entry_throttle_client->clk_src_id,
|
||||||
tbl_entry_throttle_client->name);
|
tbl_entry_throttle_client->name);
|
||||||
d_mpr_h("%s: now_cur_ma(%llu) - min_cur_ma(%llu) > delta_cur(%d)\n",
|
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);
|
__func__, now_cur_ma, min_cur_ma, *delta_cur);
|
||||||
|
/* found client to throttle, break from here. */
|
||||||
/* found client to throttle, break from here. */
|
break;
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -536,14 +539,11 @@ static int mmrm_sw_throttle_low_priority_client(
|
|||||||
tbl_entry_throttle_client->freq[tbl_entry_throttle_client->vdd_level];
|
tbl_entry_throttle_client->freq[tbl_entry_throttle_client->vdd_level];
|
||||||
notifier_data.cb_data.val_chng.new_val =
|
notifier_data.cb_data.val_chng.new_val =
|
||||||
tbl_entry_throttle_client->freq[clk_min_level];
|
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)
|
if (tbl_entry_throttle_client->notifier_cb_fn)
|
||||||
rc = tbl_entry_throttle_client->notifier_cb_fn(¬ifier_data);
|
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) {
|
if (rc) {
|
||||||
d_mpr_e("%s: Client failed to send SUCCESS in callback(%d)\n",
|
d_mpr_e("%s: Client failed to send SUCCESS in callback(%d)\n",
|
||||||
__func__, tbl_entry_throttle_client->clk_src_id);
|
__func__, tbl_entry_throttle_client->clk_src_id);
|
||||||
@@ -559,6 +559,9 @@ static int mmrm_sw_throttle_low_priority_client(
|
|||||||
rc = -EINVAL;
|
rc = -EINVAL;
|
||||||
goto err_clk_set_fail;
|
goto err_clk_set_fail;
|
||||||
} else {
|
} 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;
|
*delta_cur = now_cur_ma - min_cur_ma;
|
||||||
}
|
}
|
||||||
/* Store the throttled clock rate of client */
|
/* Store the throttled clock rate of client */
|
||||||
@@ -570,6 +573,7 @@ static int mmrm_sw_throttle_low_priority_client(
|
|||||||
|
|
||||||
/* Clearing the reserve flag */
|
/* Clearing the reserve flag */
|
||||||
tbl_entry_throttle_client->reserve = tbl_entry_throttle_client->reserve & 0;
|
tbl_entry_throttle_client->reserve = tbl_entry_throttle_client->reserve & 0;
|
||||||
|
d_mpr_h("%s: exiting\n", __func__);
|
||||||
}
|
}
|
||||||
err_clk_set_fail:
|
err_clk_set_fail:
|
||||||
return rc;
|
return rc;
|
||||||
@@ -664,8 +668,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;
|
||||||
|
|
||||||
d_mpr_h("%s: entering\n", __func__);
|
|
||||||
|
|
||||||
/* validate input params */
|
/* validate input params */
|
||||||
if (!client) {
|
if (!client) {
|
||||||
d_mpr_e("%s: invalid client\n");
|
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;
|
rc = -EINVAL;
|
||||||
goto err_invalid_client;
|
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.
|
/* 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.
|
* When clk rates are the same, compare this with the current state.
|
||||||
@@ -777,7 +781,8 @@ set_clk_rate:
|
|||||||
}
|
}
|
||||||
|
|
||||||
exit_no_err:
|
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;
|
return rc;
|
||||||
|
|
||||||
err_invalid_client:
|
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 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 *drv_data =
|
||||||
(struct mmrm_driver_data *)driver_data;
|
(struct mmrm_driver_data *)driver_data;
|
||||||
struct mmrm_clk_platform_resources *cres = &drv_data->clk_res;
|
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 */
|
/* update the peak current threshold */
|
||||||
sinfo->peak_cur_data.threshold = cres->threshold;
|
sinfo->peak_cur_data.threshold = cres->threshold;
|
||||||
sinfo->peak_cur_data.aggreg_val = 0;
|
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 */
|
/* initialize mutex for sw clk mgr */
|
||||||
mutex_init(&sw_clk_mgr->lock);
|
mutex_init(&sw_clk_mgr->lock);
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* 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__
|
#ifndef __MMRM_DEBUG__
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* 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
|
#ifdef _FIXP_ARITH_H
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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 <linux/types.h>
|
#include <linux/types.h>
|
||||||
@@ -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 = {
|
static struct mmrm_platform_data waipio_data = {
|
||||||
.common_data = waipio_common_data,
|
.common_data = waipio_common_data,
|
||||||
.common_data_length = ARRAY_SIZE(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[] = {
|
static const struct of_device_id mmrm_dt_match[] = {
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* 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_
|
#ifndef _MMRM_INTERNAL_H_
|
||||||
@@ -17,9 +17,16 @@ struct mmrm_common_data {
|
|||||||
int value;
|
int value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct mmrm_throttle_clients_data {
|
||||||
|
u32 domain;
|
||||||
|
u32 id;
|
||||||
|
};
|
||||||
|
|
||||||
struct mmrm_platform_data {
|
struct mmrm_platform_data {
|
||||||
struct mmrm_common_data *common_data;
|
struct mmrm_common_data *common_data;
|
||||||
|
struct mmrm_throttle_clients_data *throttle_clk_clients_data;
|
||||||
u32 common_data_length;
|
u32 common_data_length;
|
||||||
|
u16 throttle_clk_clients_data_length;
|
||||||
u32 scheme;
|
u32 scheme;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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 <linux/types.h>
|
#include <linux/types.h>
|
||||||
@@ -30,7 +30,7 @@ static int mmrm_read_clk_pltfrm_rsrc_frm_drv_data(
|
|||||||
{
|
{
|
||||||
struct mmrm_platform_data *pdata;
|
struct mmrm_platform_data *pdata;
|
||||||
struct mmrm_clk_platform_resources *cres;
|
struct mmrm_clk_platform_resources *cres;
|
||||||
int rc = 0;
|
int i = 0;
|
||||||
|
|
||||||
pdata = ddata->platform_data;
|
pdata = ddata->platform_data;
|
||||||
cres = &ddata->clk_res;
|
cres = &ddata->clk_res;
|
||||||
@@ -44,8 +44,15 @@ static int mmrm_read_clk_pltfrm_rsrc_frm_drv_data(
|
|||||||
"qcom,mmrm_clk_mgr_scheme");
|
"qcom,mmrm_clk_mgr_scheme");
|
||||||
d_mpr_h("%s: configured mmrm scheme %d\n",
|
d_mpr_h("%s: configured mmrm scheme %d\n",
|
||||||
__func__, cres->scheme);
|
__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(
|
static void mmrm_free_rail_corner_table(
|
||||||
|
@@ -1,12 +1,13 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* 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_
|
#ifndef _MMRM_RESOURCES_H_
|
||||||
#define _MMRM_RESOURCES_H_
|
#define _MMRM_RESOURCES_H_
|
||||||
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#define MMRM_MAX_THROTTLE_CLIENTS 5
|
||||||
|
|
||||||
struct corner_info {
|
struct corner_info {
|
||||||
const char *name;
|
const char *name;
|
||||||
@@ -36,6 +37,8 @@ struct mmrm_clk_platform_resources {
|
|||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
u32 threshold;
|
u32 threshold;
|
||||||
u32 scheme;
|
u32 scheme;
|
||||||
|
u32 clsid_threshold_clients[MMRM_MAX_THROTTLE_CLIENTS];
|
||||||
|
u16 throttle_clients_data_length;
|
||||||
struct voltage_corner_set corner_set;
|
struct voltage_corner_set corner_set;
|
||||||
struct nom_clk_src_set nom_clk_set;
|
struct nom_clk_src_set nom_clk_set;
|
||||||
};
|
};
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0-only
|
// 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 <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
Reference in New Issue
Block a user