mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "cnss2: Remove unnecessary logs for Bus BW voting"
This commit is contained in:
commit
c1d17bef32
3 changed files with 184 additions and 91 deletions
|
|
@ -2230,75 +2230,130 @@ int cnss_minidump_remove_region(struct cnss_plat_data *plat_priv,
|
|||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* cnss_register_bus_scale() - Setup interconnect voting data
|
||||
* @plat_priv: Platform data structure
|
||||
*
|
||||
* For different interconnect path configured in device tree setup voting data
|
||||
* for list of bandwidth requirements.
|
||||
*
|
||||
* Result: 0 for success. -EINVAL if not configured
|
||||
*/
|
||||
static int cnss_register_bus_scale(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
int ret = 0, len = 0, i, j;
|
||||
struct cnss_bus_bw_info *bus_bw_info;
|
||||
const u32 *cfg_arr;
|
||||
int ret = -EINVAL;
|
||||
u32 idx, i, j, cfg_arr_size, *cfg_arr;
|
||||
struct cnss_bus_bw_info *bus_bw_info, *tmp;
|
||||
struct device *dev = &plat_priv->plat_dev->dev;
|
||||
|
||||
bus_bw_info = &plat_priv->bus_bw_info;
|
||||
|
||||
bus_bw_info->cnss_path =
|
||||
of_icc_get(&plat_priv->plat_dev->dev, NULL);
|
||||
|
||||
if (!bus_bw_info->cnss_path) {
|
||||
cnss_pr_err("Skip Bus BW setup. Interconnect not configured\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (IS_ERR(bus_bw_info->cnss_path)) {
|
||||
ret = PTR_ERR(bus_bw_info->cnss_path);
|
||||
if (ret != -EPROBE_DEFER) {
|
||||
cnss_pr_err("Failed to get Interconnect path: %d!\n",
|
||||
ret);
|
||||
goto out;
|
||||
}
|
||||
INIT_LIST_HEAD(&plat_priv->icc.list_head);
|
||||
ret = of_property_read_u32(dev->of_node,
|
||||
"qcom,icc-path-count",
|
||||
&plat_priv->icc.path_count);
|
||||
if (ret) {
|
||||
cnss_pr_err("Platform Bus Interconnect path not configured\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
ret = of_property_read_u32(plat_priv->plat_dev->dev.of_node,
|
||||
"qcom,bus-bw-cfg-num",
|
||||
&bus_bw_info->num_cfg);
|
||||
"qcom,bus-bw-cfg-count",
|
||||
&plat_priv->icc.bus_bw_cfg_count);
|
||||
if (ret) {
|
||||
cnss_pr_err("Failed to get Bus BW Config table size\n");
|
||||
goto out;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
cfg_arr = of_get_property(plat_priv->plat_dev->dev.of_node,
|
||||
"qcom,bus-bw-cfg", &len);
|
||||
cfg_arr_size = plat_priv->icc.path_count *
|
||||
plat_priv->icc.bus_bw_cfg_count * CNSS_ICC_VOTE_MAX;
|
||||
cfg_arr = kzalloc(cfg_arr_size, GFP_KERNEL);
|
||||
if (!cfg_arr) {
|
||||
cnss_pr_err("Bus BW Config Table not setup!\n");
|
||||
ret = -EINVAL;
|
||||
goto out;
|
||||
cnss_pr_err("Failed to alloc cfg table mem\n");
|
||||
ret = -ENOMEM;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
bus_bw_info->cfg_table = kcalloc(bus_bw_info->num_cfg,
|
||||
sizeof(*bus_bw_info->cfg_table),
|
||||
GFP_KERNEL);
|
||||
if (!bus_bw_info->cfg_table) {
|
||||
cnss_pr_err("No mem for Bus BW config table\n");
|
||||
return -ENOMEM;
|
||||
ret = of_property_read_u32_array(plat_priv->plat_dev->dev.of_node,
|
||||
"qcom,bus-bw-cfg", cfg_arr,
|
||||
cfg_arr_size);
|
||||
if (ret) {
|
||||
cnss_pr_err("Invalid Bus BW Config Table\n");
|
||||
goto cleanup;
|
||||
}
|
||||
for (i = 0, j = 0; i < bus_bw_info->num_cfg; i++, j += 2) {
|
||||
bus_bw_info->cfg_table[i].ab = be32_to_cpu(cfg_arr[j]);
|
||||
bus_bw_info->cfg_table[i].ib = be32_to_cpu(cfg_arr[j + 1]);
|
||||
cnss_pr_dbg("Bandwidth Type: %d bw_cfg.ab: %d bw_cfg.ib: %d\n",
|
||||
i, bus_bw_info->cfg_table[i].ab,
|
||||
bus_bw_info->cfg_table[i].ib);
|
||||
|
||||
cnss_pr_dbg("ICC Path_Count: %d BW_CFG_Count: %d\n",
|
||||
plat_priv->icc.path_count, plat_priv->icc.bus_bw_cfg_count);
|
||||
|
||||
for (idx = 0; idx < plat_priv->icc.path_count; idx++) {
|
||||
bus_bw_info = devm_kzalloc(dev, sizeof(*bus_bw_info),
|
||||
GFP_KERNEL);
|
||||
if (!bus_bw_info) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
ret = of_property_read_string_index(dev->of_node,
|
||||
"interconnect-names", idx,
|
||||
&bus_bw_info->icc_name);
|
||||
if (ret)
|
||||
goto out;
|
||||
|
||||
bus_bw_info->icc_path =
|
||||
of_icc_get(&plat_priv->plat_dev->dev,
|
||||
bus_bw_info->icc_name);
|
||||
|
||||
if (IS_ERR(bus_bw_info->icc_path)) {
|
||||
ret = PTR_ERR(bus_bw_info->icc_path);
|
||||
if (ret != -EPROBE_DEFER) {
|
||||
cnss_pr_err("Failed to get Interconnect path for %s. Err: %d\n",
|
||||
bus_bw_info->icc_name, ret);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
bus_bw_info->cfg_table =
|
||||
devm_kcalloc(dev, plat_priv->icc.bus_bw_cfg_count,
|
||||
sizeof(*bus_bw_info->cfg_table),
|
||||
GFP_KERNEL);
|
||||
if (!bus_bw_info->cfg_table) {
|
||||
ret = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
cnss_pr_dbg("ICC Vote CFG for path: %s\n",
|
||||
bus_bw_info->icc_name);
|
||||
for (i = 0, j = (idx * plat_priv->icc.bus_bw_cfg_count *
|
||||
CNSS_ICC_VOTE_MAX);
|
||||
i < plat_priv->icc.bus_bw_cfg_count;
|
||||
i++, j += 2) {
|
||||
bus_bw_info->cfg_table[i].avg_bw = cfg_arr[j];
|
||||
bus_bw_info->cfg_table[i].peak_bw = cfg_arr[j + 1];
|
||||
cnss_pr_dbg("ICC Vote BW: %d avg: %d peak: %d\n",
|
||||
i, bus_bw_info->cfg_table[i].avg_bw,
|
||||
bus_bw_info->cfg_table[i].peak_bw);
|
||||
}
|
||||
list_add_tail(&bus_bw_info->list,
|
||||
&plat_priv->icc.list_head);
|
||||
}
|
||||
kfree(cfg_arr);
|
||||
return 0;
|
||||
out:
|
||||
list_for_each_entry_safe(bus_bw_info, tmp,
|
||||
&plat_priv->icc.list_head, list) {
|
||||
list_del(&bus_bw_info->list);
|
||||
}
|
||||
cleanup:
|
||||
kfree(cfg_arr);
|
||||
memset(&plat_priv->icc, 0, sizeof(plat_priv->icc));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cnss_unregister_bus_scale(struct cnss_plat_data *plat_priv)
|
||||
{
|
||||
struct cnss_bus_bw_info *bus_bw_info;
|
||||
struct cnss_bus_bw_info *bus_bw_info, *tmp;
|
||||
|
||||
bus_bw_info = &plat_priv->bus_bw_info;
|
||||
|
||||
if (bus_bw_info->cnss_path)
|
||||
icc_put(bus_bw_info->cnss_path);
|
||||
|
||||
kfree(bus_bw_info->cfg_table);
|
||||
list_for_each_entry_safe(bus_bw_info, tmp,
|
||||
&plat_priv->icc.list_head, list) {
|
||||
list_del(&bus_bw_info->list);
|
||||
if (bus_bw_info->icc_path)
|
||||
icc_put(bus_bw_info->icc_path);
|
||||
}
|
||||
memset(&plat_priv->icc, 0, sizeof(plat_priv->icc));
|
||||
}
|
||||
|
||||
static ssize_t recovery_store(struct device *dev,
|
||||
|
|
|
|||
|
|
@ -140,18 +140,48 @@ struct cnss_esoc_info {
|
|||
};
|
||||
#endif
|
||||
|
||||
/**
|
||||
* struct cnss_bus_bw_cfg - Interconnect vote data
|
||||
* @avg_bw: Vote for average bandwidth
|
||||
* @peak_bw: Vote for peak bandwidth
|
||||
*/
|
||||
struct cnss_bus_bw_cfg {
|
||||
u32 ab;
|
||||
u32 ib;
|
||||
u32 avg_bw;
|
||||
u32 peak_bw;
|
||||
};
|
||||
|
||||
/* Number of bw votes (avg, peak) entries that ICC requires */
|
||||
#define CNSS_ICC_VOTE_MAX 2
|
||||
|
||||
/**
|
||||
* struct cnss_bus_bw_info - Bus bandwidth config for interconnect path
|
||||
* @list: Kernel linked list
|
||||
* @icc_name: Name of interconnect path as defined in Device tree
|
||||
* @icc_path: Interconnect path data structure
|
||||
* @cfg_table: Interconnect vote data for average and peak bandwidth
|
||||
*/
|
||||
struct cnss_bus_bw_info {
|
||||
struct icc_path *cnss_path;
|
||||
int current_bw_vote;
|
||||
u32 num_cfg;
|
||||
struct list_head list;
|
||||
const char *icc_name;
|
||||
struct icc_path *icc_path;
|
||||
struct cnss_bus_bw_cfg *cfg_table;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct cnss_interconnect_cfg - CNSS platform interconnect config
|
||||
* @list_head: List of interconnect path bandwidth configs
|
||||
* @path_count: Count of interconnect path configured in device tree
|
||||
* @current_bw_vote: WLAN driver provided bandwidth vote
|
||||
* @bus_bw_cfg_count: Number of bandwidth configs for voting. It is the array
|
||||
* size of struct cnss_bus_bw_info.cfg_table
|
||||
*/
|
||||
struct cnss_interconnect_cfg {
|
||||
struct list_head list_head;
|
||||
u32 path_count;
|
||||
int current_bw_vote;
|
||||
u32 bus_bw_cfg_count;
|
||||
};
|
||||
|
||||
struct cnss_fw_mem {
|
||||
size_t size;
|
||||
void *va;
|
||||
|
|
@ -360,7 +390,7 @@ struct cnss_plat_data {
|
|||
#if IS_ENABLED(CONFIG_ESOC)
|
||||
struct cnss_esoc_info esoc_info;
|
||||
#endif
|
||||
struct cnss_bus_bw_info bus_bw_info;
|
||||
struct cnss_interconnect_cfg icc;
|
||||
struct notifier_block modem_nb;
|
||||
struct notifier_block reboot_nb;
|
||||
struct notifier_block panic_nb;
|
||||
|
|
|
|||
|
|
@ -509,42 +509,58 @@ static int cnss_pci_force_wake_put(struct cnss_pci_data *pci_priv)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int cnss_request_bus_bandwidth(struct device *dev, int bandwidth)
|
||||
/**
|
||||
* cnss_setup_bus_bandwidth() - Setup interconnect vote for given bandwidth
|
||||
* @plat_priv: Platform private data struct
|
||||
* @bw: bandwidth
|
||||
* @save: toggle flag to save bandwidth to current_bw_vote
|
||||
*
|
||||
* Setup bandwidth votes for configured interconnect paths
|
||||
*
|
||||
* Return: 0 for success
|
||||
*/
|
||||
static int cnss_setup_bus_bandwidth(struct cnss_plat_data *plat_priv,
|
||||
u32 bw, bool save)
|
||||
{
|
||||
int ret = 0;
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
struct cnss_bus_bw_info *bus_bw_info;
|
||||
|
||||
if (!plat_priv->icc.path_count)
|
||||
return -ENOTSUPP;
|
||||
|
||||
if (bw >= plat_priv->icc.bus_bw_cfg_count) {
|
||||
cnss_pr_err("Invalid bus bandwidth Type: %d", bw);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
list_for_each_entry(bus_bw_info, &plat_priv->icc.list_head, list) {
|
||||
ret = icc_set_bw(bus_bw_info->icc_path,
|
||||
bus_bw_info->cfg_table[bw].avg_bw,
|
||||
bus_bw_info->cfg_table[bw].peak_bw);
|
||||
if (ret) {
|
||||
cnss_pr_err("Could not set BW Cfg: %d, err = %d ICC Path: %s Val: %d %d\n",
|
||||
bw, ret, bus_bw_info->icc_name,
|
||||
bus_bw_info->cfg_table[bw].avg_bw,
|
||||
bus_bw_info->cfg_table[bw].peak_bw);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (ret == 0 && save)
|
||||
plat_priv->icc.current_bw_vote = bw;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cnss_request_bus_bandwidth(struct device *dev, int bandwidth)
|
||||
{
|
||||
struct cnss_plat_data *plat_priv = cnss_bus_dev_to_plat_priv(dev);
|
||||
|
||||
if (!plat_priv)
|
||||
return -ENODEV;
|
||||
|
||||
bus_bw_info = &plat_priv->bus_bw_info;
|
||||
if (!bus_bw_info->cnss_path || bandwidth > bus_bw_info->num_cfg)
|
||||
if (bandwidth < 0)
|
||||
return -EINVAL;
|
||||
|
||||
switch (bandwidth) {
|
||||
case CNSS_BUS_WIDTH_NONE:
|
||||
case CNSS_BUS_WIDTH_IDLE:
|
||||
case CNSS_BUS_WIDTH_LOW:
|
||||
case CNSS_BUS_WIDTH_MEDIUM:
|
||||
case CNSS_BUS_WIDTH_HIGH:
|
||||
case CNSS_BUS_WIDTH_VERY_HIGH:
|
||||
case CNSS_BUS_WIDTH_LOW_LATENCY:
|
||||
ret = icc_set_bw(bus_bw_info->cnss_path,
|
||||
bus_bw_info->cfg_table[bandwidth].ab,
|
||||
bus_bw_info->cfg_table[bandwidth].ib);
|
||||
if (!ret)
|
||||
bus_bw_info->current_bw_vote = bandwidth;
|
||||
else
|
||||
cnss_pr_err("Could not set bus bandwidth: %d, err = %d\n",
|
||||
bandwidth, ret);
|
||||
break;
|
||||
default:
|
||||
cnss_pr_err("Invalid bus bandwidth: %d", bandwidth);
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
return cnss_setup_bus_bandwidth(plat_priv, (u32)bandwidth, true);
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_request_bus_bandwidth);
|
||||
|
||||
|
|
@ -2987,7 +3003,6 @@ int cnss_auto_suspend(struct device *dev)
|
|||
struct pci_dev *pci_dev = to_pci_dev(dev);
|
||||
struct cnss_pci_data *pci_priv = cnss_get_pci_priv(pci_dev);
|
||||
struct cnss_plat_data *plat_priv;
|
||||
struct cnss_bus_bw_info *bus_bw_info;
|
||||
|
||||
if (!pci_priv)
|
||||
return -ENODEV;
|
||||
|
|
@ -3008,18 +3023,11 @@ int cnss_auto_suspend(struct device *dev)
|
|||
|
||||
cnss_pci_set_monitor_wake_intr(pci_priv, true);
|
||||
|
||||
bus_bw_info = &plat_priv->bus_bw_info;
|
||||
if (!bus_bw_info->cnss_path)
|
||||
goto out;
|
||||
|
||||
/* For suspend temporarily set bandwidth vote to NONE and dont save in
|
||||
* current_bw_vote as in resume path we should vote for last used
|
||||
* bandwidth vote. Also ignore error if bw voting is not setup.
|
||||
*/
|
||||
icc_set_bw(bus_bw_info->cnss_path,
|
||||
bus_bw_info->cfg_table[CNSS_BUS_WIDTH_NONE].ab,
|
||||
bus_bw_info->cfg_table[CNSS_BUS_WIDTH_NONE].ib);
|
||||
out:
|
||||
cnss_setup_bus_bandwidth(plat_priv, CNSS_BUS_WIDTH_NONE, false);
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL(cnss_auto_suspend);
|
||||
|
|
@ -3048,7 +3056,7 @@ int cnss_auto_resume(struct device *dev)
|
|||
cnss_pci_set_auto_suspended(pci_priv, 0);
|
||||
mutex_unlock(&pci_priv->bus_lock);
|
||||
|
||||
cnss_request_bus_bandwidth(dev, plat_priv->bus_bw_info.current_bw_vote);
|
||||
cnss_request_bus_bandwidth(dev, plat_priv->icc.current_bw_vote);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue