From e3184000c5e7360434340c3344e5025a506851db Mon Sep 17 00:00:00 2001 From: Steve Cohen Date: Sat, 4 Apr 2020 01:54:10 -0400 Subject: [PATCH] disp: msm: get reg-bus vote values from device node property Get the register bus AB/IB vote values for each supported mode from the device node to allow flexibility in adjusting these settings for various different targets. Change-Id: I258320d4847accfa8043f5f9fc4ccc791c16dddd Signed-off-by: Steve Cohen --- msm/sde_power_handle.c | 105 +++++++++++++++++++++++++---------------- msm/sde_power_handle.h | 24 ++++++---- msm/sde_rsc.c | 17 +++---- 3 files changed, 86 insertions(+), 60 deletions(-) diff --git a/msm/sde_power_handle.c b/msm/sde_power_handle.c index 2d67fe4fb3..50124f9f7d 100644 --- a/msm/sde_power_handle.c +++ b/msm/sde_power_handle.c @@ -21,12 +21,7 @@ #include "sde_trace.h" #include "sde_dbg.h" -static const struct sde_power_bus_scaling_data sde_reg_bus_table[] = { - {0, 0}, - {0, 76800}, - {0, 150000}, - {0, 300000}, -}; +#define KBPS2BPS(x) ((x) * 1000ULL) static const char *data_bus_name[SDE_POWER_HANDLE_DBUS_ID_MAX] = { [SDE_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,sde-data-bus", @@ -395,6 +390,46 @@ end: return 0; } +static int sde_power_reg_bus_parse(struct platform_device *pdev, + struct sde_power_reg_bus_handle *reg_bus) +{ + const char *bus_name = "qcom,sde-reg-bus"; + const u32 *vec_arr = NULL; + int rc, len, i, vec_idx = 0; + u32 paths = 0; + + rc = sde_power_icc_get(pdev, bus_name, ®_bus->reg_bus_hdl, &paths); + if (rc) + return rc; + + if (!paths) { + pr_debug("%s not defined for pdev %s\n", bus_name, pdev->name ? + pdev->name : ""); + return 0; + } + + vec_arr = of_get_property(pdev->dev.of_node, + "qcom,sde-reg-bus,vectors-KBps", &len); + if (!vec_arr) { + pr_err("%s scale table property not found\n", bus_name); + return -EINVAL; + } + + if (len / sizeof(*vec_arr) != VOTE_INDEX_MAX * 2) { + pr_err("wrong size for %s vector table\n", bus_name); + return -EINVAL; + } + + for (i = 0; i < VOTE_INDEX_MAX; ++i) { + reg_bus->scale_table[i].ab = (u64)KBPS2BPS(be32_to_cpu( + vec_arr[vec_idx++])); + reg_bus->scale_table[i].ib = (u64)KBPS2BPS(be32_to_cpu( + vec_arr[vec_idx++])); + } + + return rc; +} + static int sde_power_mnoc_bus_parse(struct platform_device *pdev, struct sde_power_data_bus_handle *pdbus, const char *name) { @@ -426,11 +461,10 @@ static int sde_power_bus_parse(struct platform_device *pdev, { int i, j, rc = 0; bool active_only = false; - const char *bus_name = "qcom,sde-reg-bus"; struct sde_power_data_bus_handle *pdbus = phandle->data_bus_handle; /* reg bus */ - rc = sde_power_icc_get(pdev, bus_name, &phandle->reg_bus_hdl, NULL); + rc = sde_power_reg_bus_parse(pdev, &phandle->reg_bus_handle); if (rc) return rc; @@ -469,10 +503,11 @@ static int sde_power_bus_parse(struct platform_device *pdev, static void sde_power_bus_unregister(struct sde_power_handle *phandle) { int i, j; + struct sde_power_reg_bus_handle *reg_bus = &phandle->reg_bus_handle; struct sde_power_data_bus_handle *pdbus = phandle->data_bus_handle; - icc_put(phandle->reg_bus_hdl); - phandle->reg_bus_hdl = NULL; + icc_put(reg_bus->reg_bus_hdl); + reg_bus->reg_bus_hdl = NULL; for (i = SDE_POWER_HANDLE_DBUS_ID_MAX - 1; i >= SDE_POWER_HANDLE_DBUS_ID_MNOC; i--) { @@ -485,21 +520,30 @@ static void sde_power_bus_unregister(struct sde_power_handle *phandle) } } -static int sde_power_reg_bus_update(struct icc_path *reg_bus_hdl, +static int sde_power_reg_bus_update(struct sde_power_reg_bus_handle *reg_bus, u32 usecase_ndx) { int rc = 0; + u64 ab_quota, ib_quota; - if (reg_bus_hdl) { + ab_quota = reg_bus->scale_table[usecase_ndx].ab; + ib_quota = reg_bus->scale_table[usecase_ndx].ib; + + if (reg_bus->reg_bus_hdl) { SDE_ATRACE_BEGIN("msm_bus_scale_req"); - rc = icc_set_bw(reg_bus_hdl, - sde_reg_bus_table[usecase_ndx].ab, - sde_reg_bus_table[usecase_ndx].ib); + rc = icc_set_bw(reg_bus->reg_bus_hdl, Bps_to_icc(ab_quota), + Bps_to_icc(ib_quota)); SDE_ATRACE_END("msm_bus_scale_req"); } if (rc) - pr_err("failed to set reg bus vote rc=%d\n", rc); + pr_err("failed to set reg bus vote to index %d, rc=%d\n", + usecase_ndx, rc); + else { + reg_bus->curr_idx = usecase_ndx; + pr_debug("reg-bus vote set to index=%d, ab=%llu, ib=%llu\n", + usecase_ndx, ab_quota, ib_quota); + } return rc; } @@ -629,23 +673,17 @@ int sde_power_scale_reg_bus(struct sde_power_handle *phandle, { int rc = 0; + if (!phandle->reg_bus_handle.reg_bus_hdl) + return 0; + if (!skip_lock) mutex_lock(&phandle->phandle_lock); pr_debug("%pS: requested:%d\n", __builtin_return_address(0), usecase_ndx); - rc = sde_power_reg_bus_update(phandle->reg_bus_hdl, + rc = sde_power_reg_bus_update(&phandle->reg_bus_handle, usecase_ndx); - if (rc) - pr_err("failed to set reg bus vote rc=%d\n", rc); - else { - phandle->reg_bus_curr_val.ab = - sde_reg_bus_table[usecase_ndx].ab; - phandle->reg_bus_curr_val.ib = - sde_reg_bus_table[usecase_ndx].ib; - phandle->current_usecase_ndx = usecase_ndx; - } if (!skip_lock) mutex_unlock(&phandle->phandle_lock); @@ -653,21 +691,6 @@ int sde_power_scale_reg_bus(struct sde_power_handle *phandle, return rc; } -static inline bool _resource_changed(u32 current_usecase_ndx, - u32 max_usecase_ndx) -{ - WARN_ON((current_usecase_ndx >= VOTE_INDEX_MAX) - || (max_usecase_ndx >= VOTE_INDEX_MAX)); - - if (((current_usecase_ndx >= VOTE_INDEX_LOW) && /* enabled */ - (max_usecase_ndx == VOTE_INDEX_DISABLE)) || /* max disabled */ - ((current_usecase_ndx == VOTE_INDEX_DISABLE) && /* disabled */ - (max_usecase_ndx >= VOTE_INDEX_LOW))) /* max enabled */ - return true; - - return false; -} - int sde_power_resource_enable(struct sde_power_handle *phandle, bool enable) { int rc = 0, i = 0; diff --git a/msm/sde_power_handle.h b/msm/sde_power_handle.h index 5b7c2197b3..4273308c92 100644 --- a/msm/sde_power_handle.h +++ b/msm/sde_power_handle.h @@ -92,8 +92,8 @@ enum SDE_POWER_HANDLE_DBUS_ID { /** * struct sde_power_bus_scaling_data: struct for bus setting - * @ab: average bandwidth in kilobytes per second - * @ib: peak bandwidth in kilobytes per second + * @ab: average bandwidth in bytes per second + * @ib: peak bandwidth in bytes per second */ struct sde_power_bus_scaling_data { uint64_t ab; /* Arbitrated bandwidth */ @@ -113,6 +113,18 @@ struct sde_power_data_bus_handle { bool bus_active_only; }; +/** + * struct sde_power_reg_bus_handle: power handle struct for reg bus + * @reg_bus_hdl: reg bus interconnect path handle + * @curr_idx : use-case index in to scale_table for the current vote + * @scale_table: bus scaling bandwidth vote table + */ +struct sde_power_reg_bus_handle { + struct icc_path *reg_bus_hdl; + enum mdss_bus_vote_type curr_idx; + struct sde_power_bus_scaling_data scale_table[VOTE_INDEX_MAX]; +}; + /* * struct sde_power_event - local event registration structure * @client_name: name of the client registering @@ -136,9 +148,7 @@ struct sde_power_event { * @mp: module power for clock and regulator * @phandle_lock: lock to synchronize the enable/disable * @dev: pointer to device structure - * @usecase_ndx: current usecase index - * @reg_bus_hdl: current register bus handle - * @reg_bus_curr_val: save currecnt reg bus value + * @reg_bus_handle: context structure for reg bus control * @data_bus_handle: context structure for data bus control * @event_list: current power handle event list * @rsc_client: sde rsc client pointer @@ -148,9 +158,7 @@ struct sde_power_handle { struct dss_module_power mp; struct mutex phandle_lock; struct device *dev; - u32 current_usecase_ndx; - struct icc_path *reg_bus_hdl; - struct sde_power_bus_scaling_data reg_bus_curr_val; + struct sde_power_reg_bus_handle reg_bus_handle; struct sde_power_data_bus_handle data_bus_handle [SDE_POWER_HANDLE_DBUS_ID_MAX]; struct list_head event_list; diff --git a/msm/sde_rsc.c b/msm/sde_rsc.c index ef6a9d15ee..27cac4dbf6 100644 --- a/msm/sde_rsc.c +++ b/msm/sde_rsc.c @@ -433,9 +433,7 @@ static int sde_rsc_resource_disable(struct sde_rsc_priv *rsc) phandle = &rsc->phandle; mp = &phandle->mp; msm_dss_enable_clk(mp->clk_config, mp->num_clk, false); - if (phandle->reg_bus_hdl) - sde_power_scale_reg_bus(phandle, VOTE_INDEX_DISABLE, false); - + sde_power_scale_reg_bus(phandle, VOTE_INDEX_DISABLE, false); msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, false); return 0; @@ -463,12 +461,10 @@ static int sde_rsc_resource_enable(struct sde_rsc_priv *rsc) goto end; } - if (phandle->reg_bus_hdl) { - rc = sde_power_scale_reg_bus(phandle, VOTE_INDEX_LOW, false); - if (rc) { - pr_err("failed to set reg bus vote rc=%d\n", rc); - goto reg_bus_hdl_err; - } + rc = sde_power_scale_reg_bus(phandle, VOTE_INDEX_LOW, false); + if (rc) { + pr_err("failed to set reg bus vote rc=%d\n", rc); + goto reg_bus_hdl_err; } rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true); @@ -480,8 +476,7 @@ static int sde_rsc_resource_enable(struct sde_rsc_priv *rsc) return rc; clk_err: - if (phandle->reg_bus_hdl) - sde_power_scale_reg_bus(phandle, VOTE_INDEX_DISABLE, false); + sde_power_scale_reg_bus(phandle, VOTE_INDEX_DISABLE, false); reg_bus_hdl_err: msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, false);