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 <cohens@codeaurora.org>
This commit is contained in:
@@ -21,12 +21,7 @@
|
|||||||
#include "sde_trace.h"
|
#include "sde_trace.h"
|
||||||
#include "sde_dbg.h"
|
#include "sde_dbg.h"
|
||||||
|
|
||||||
static const struct sde_power_bus_scaling_data sde_reg_bus_table[] = {
|
#define KBPS2BPS(x) ((x) * 1000ULL)
|
||||||
{0, 0},
|
|
||||||
{0, 76800},
|
|
||||||
{0, 150000},
|
|
||||||
{0, 300000},
|
|
||||||
};
|
|
||||||
|
|
||||||
static const char *data_bus_name[SDE_POWER_HANDLE_DBUS_ID_MAX] = {
|
static const char *data_bus_name[SDE_POWER_HANDLE_DBUS_ID_MAX] = {
|
||||||
[SDE_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,sde-data-bus",
|
[SDE_POWER_HANDLE_DBUS_ID_MNOC] = "qcom,sde-data-bus",
|
||||||
@@ -395,6 +390,46 @@ end:
|
|||||||
return 0;
|
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 : "<unknown>");
|
||||||
|
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,
|
static int sde_power_mnoc_bus_parse(struct platform_device *pdev,
|
||||||
struct sde_power_data_bus_handle *pdbus, const char *name)
|
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;
|
int i, j, rc = 0;
|
||||||
bool active_only = false;
|
bool active_only = false;
|
||||||
const char *bus_name = "qcom,sde-reg-bus";
|
|
||||||
struct sde_power_data_bus_handle *pdbus = phandle->data_bus_handle;
|
struct sde_power_data_bus_handle *pdbus = phandle->data_bus_handle;
|
||||||
|
|
||||||
/* reg bus */
|
/* 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)
|
if (rc)
|
||||||
return 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)
|
static void sde_power_bus_unregister(struct sde_power_handle *phandle)
|
||||||
{
|
{
|
||||||
int i, j;
|
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;
|
struct sde_power_data_bus_handle *pdbus = phandle->data_bus_handle;
|
||||||
|
|
||||||
icc_put(phandle->reg_bus_hdl);
|
icc_put(reg_bus->reg_bus_hdl);
|
||||||
phandle->reg_bus_hdl = NULL;
|
reg_bus->reg_bus_hdl = NULL;
|
||||||
|
|
||||||
for (i = SDE_POWER_HANDLE_DBUS_ID_MAX - 1;
|
for (i = SDE_POWER_HANDLE_DBUS_ID_MAX - 1;
|
||||||
i >= SDE_POWER_HANDLE_DBUS_ID_MNOC; i--) {
|
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)
|
u32 usecase_ndx)
|
||||||
{
|
{
|
||||||
int rc = 0;
|
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");
|
SDE_ATRACE_BEGIN("msm_bus_scale_req");
|
||||||
rc = icc_set_bw(reg_bus_hdl,
|
rc = icc_set_bw(reg_bus->reg_bus_hdl, Bps_to_icc(ab_quota),
|
||||||
sde_reg_bus_table[usecase_ndx].ab,
|
Bps_to_icc(ib_quota));
|
||||||
sde_reg_bus_table[usecase_ndx].ib);
|
|
||||||
SDE_ATRACE_END("msm_bus_scale_req");
|
SDE_ATRACE_END("msm_bus_scale_req");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (rc)
|
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;
|
return rc;
|
||||||
}
|
}
|
||||||
@@ -629,23 +673,17 @@ int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
|
|||||||
{
|
{
|
||||||
int rc = 0;
|
int rc = 0;
|
||||||
|
|
||||||
|
if (!phandle->reg_bus_handle.reg_bus_hdl)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!skip_lock)
|
if (!skip_lock)
|
||||||
mutex_lock(&phandle->phandle_lock);
|
mutex_lock(&phandle->phandle_lock);
|
||||||
|
|
||||||
pr_debug("%pS: requested:%d\n",
|
pr_debug("%pS: requested:%d\n",
|
||||||
__builtin_return_address(0), usecase_ndx);
|
__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);
|
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)
|
if (!skip_lock)
|
||||||
mutex_unlock(&phandle->phandle_lock);
|
mutex_unlock(&phandle->phandle_lock);
|
||||||
@@ -653,21 +691,6 @@ int sde_power_scale_reg_bus(struct sde_power_handle *phandle,
|
|||||||
return rc;
|
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 sde_power_resource_enable(struct sde_power_handle *phandle, bool enable)
|
||||||
{
|
{
|
||||||
int rc = 0, i = 0;
|
int rc = 0, i = 0;
|
||||||
|
@@ -92,8 +92,8 @@ enum SDE_POWER_HANDLE_DBUS_ID {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* struct sde_power_bus_scaling_data: struct for bus setting
|
* struct sde_power_bus_scaling_data: struct for bus setting
|
||||||
* @ab: average bandwidth in kilobytes per second
|
* @ab: average bandwidth in bytes per second
|
||||||
* @ib: peak bandwidth in kilobytes per second
|
* @ib: peak bandwidth in bytes per second
|
||||||
*/
|
*/
|
||||||
struct sde_power_bus_scaling_data {
|
struct sde_power_bus_scaling_data {
|
||||||
uint64_t ab; /* Arbitrated bandwidth */
|
uint64_t ab; /* Arbitrated bandwidth */
|
||||||
@@ -113,6 +113,18 @@ struct sde_power_data_bus_handle {
|
|||||||
bool bus_active_only;
|
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
|
* struct sde_power_event - local event registration structure
|
||||||
* @client_name: name of the client registering
|
* @client_name: name of the client registering
|
||||||
@@ -136,9 +148,7 @@ struct sde_power_event {
|
|||||||
* @mp: module power for clock and regulator
|
* @mp: module power for clock and regulator
|
||||||
* @phandle_lock: lock to synchronize the enable/disable
|
* @phandle_lock: lock to synchronize the enable/disable
|
||||||
* @dev: pointer to device structure
|
* @dev: pointer to device structure
|
||||||
* @usecase_ndx: current usecase index
|
* @reg_bus_handle: context structure for reg bus control
|
||||||
* @reg_bus_hdl: current register bus handle
|
|
||||||
* @reg_bus_curr_val: save currecnt reg bus value
|
|
||||||
* @data_bus_handle: context structure for data bus control
|
* @data_bus_handle: context structure for data bus control
|
||||||
* @event_list: current power handle event list
|
* @event_list: current power handle event list
|
||||||
* @rsc_client: sde rsc client pointer
|
* @rsc_client: sde rsc client pointer
|
||||||
@@ -148,9 +158,7 @@ struct sde_power_handle {
|
|||||||
struct dss_module_power mp;
|
struct dss_module_power mp;
|
||||||
struct mutex phandle_lock;
|
struct mutex phandle_lock;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
u32 current_usecase_ndx;
|
struct sde_power_reg_bus_handle reg_bus_handle;
|
||||||
struct icc_path *reg_bus_hdl;
|
|
||||||
struct sde_power_bus_scaling_data reg_bus_curr_val;
|
|
||||||
struct sde_power_data_bus_handle data_bus_handle
|
struct sde_power_data_bus_handle data_bus_handle
|
||||||
[SDE_POWER_HANDLE_DBUS_ID_MAX];
|
[SDE_POWER_HANDLE_DBUS_ID_MAX];
|
||||||
struct list_head event_list;
|
struct list_head event_list;
|
||||||
|
@@ -433,9 +433,7 @@ static int sde_rsc_resource_disable(struct sde_rsc_priv *rsc)
|
|||||||
phandle = &rsc->phandle;
|
phandle = &rsc->phandle;
|
||||||
mp = &phandle->mp;
|
mp = &phandle->mp;
|
||||||
msm_dss_enable_clk(mp->clk_config, mp->num_clk, false);
|
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);
|
msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, false);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@@ -463,12 +461,10 @@ static int sde_rsc_resource_enable(struct sde_rsc_priv *rsc)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (phandle->reg_bus_hdl) {
|
rc = sde_power_scale_reg_bus(phandle, VOTE_INDEX_LOW, false);
|
||||||
rc = sde_power_scale_reg_bus(phandle, VOTE_INDEX_LOW, false);
|
if (rc) {
|
||||||
if (rc) {
|
pr_err("failed to set reg bus vote rc=%d\n", rc);
|
||||||
pr_err("failed to set reg bus vote rc=%d\n", rc);
|
goto reg_bus_hdl_err;
|
||||||
goto reg_bus_hdl_err;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = msm_dss_enable_clk(mp->clk_config, mp->num_clk, true);
|
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;
|
return rc;
|
||||||
|
|
||||||
clk_err:
|
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:
|
reg_bus_hdl_err:
|
||||||
msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, false);
|
msm_dss_enable_vreg(mp->vreg_config, mp->num_vreg, false);
|
||||||
|
Reference in New Issue
Block a user