disp: msm: rotator: migrated the new BUS driver for rotator on lahaina
Migrate to icb framework API in drm and rotator driver. The change also removes msm_bus custom API usage from both drivers. Change-Id: I15de82986204a12e4cc124f51793328c3d403256 Signed-off-by: Yuan Zhao <yzhao@codeaurora.org>
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

parent
cc564849ae
commit
f3553ab628
@@ -14,8 +14,6 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/iopoll.h>
|
#include <linux/iopoll.h>
|
||||||
#include <linux/msm-bus.h>
|
|
||||||
#include <linux/msm-bus-board.h>
|
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
|
|
||||||
#define CREATE_TRACE_POINTS
|
#define CREATE_TRACE_POINTS
|
||||||
@@ -26,6 +24,13 @@
|
|||||||
#include "sde_rotator_dev.h"
|
#include "sde_rotator_dev.h"
|
||||||
#include "sde_rotator_vbif.h"
|
#include "sde_rotator_vbif.h"
|
||||||
|
|
||||||
|
static const struct sde_rot_bus_data sde_rot_reg_bus_table[] = {
|
||||||
|
{0, 0},
|
||||||
|
{0, 76800},
|
||||||
|
{0, 150000},
|
||||||
|
{0, 300000},
|
||||||
|
};
|
||||||
|
|
||||||
static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
|
static inline u64 fudge_factor(u64 val, u32 numer, u32 denom)
|
||||||
{
|
{
|
||||||
u64 result = (val * (u64)numer);
|
u64 result = (val * (u64)numer);
|
||||||
@@ -51,6 +56,11 @@ static inline bool validate_comp_ratio(struct sde_mult_factor *factor)
|
|||||||
return factor->numer && factor->denom;
|
return factor->numer && factor->denom;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const struct sde_rot_bus_data *sde_get_rot_reg_bus_value(u32 usecase_ndx)
|
||||||
|
{
|
||||||
|
return &sde_rot_reg_bus_table[usecase_ndx];
|
||||||
|
}
|
||||||
|
|
||||||
u32 sde_apply_comp_ratio_factor(u32 quota,
|
u32 sde_apply_comp_ratio_factor(u32 quota,
|
||||||
struct sde_mdp_format_params *fmt,
|
struct sde_mdp_format_params *fmt,
|
||||||
struct sde_mult_factor *factor)
|
struct sde_mult_factor *factor)
|
||||||
@@ -471,6 +481,7 @@ int sde_update_reg_bus_vote(struct reg_bus_client *bus_client, u32 usecase_ndx)
|
|||||||
int ret = 0;
|
int ret = 0;
|
||||||
bool changed = false;
|
bool changed = false;
|
||||||
u32 max_usecase_ndx = VOTE_INDEX_DISABLE;
|
u32 max_usecase_ndx = VOTE_INDEX_DISABLE;
|
||||||
|
const struct sde_rot_bus_data *reg_bus_value = NULL;
|
||||||
struct reg_bus_client *client, *temp_client;
|
struct reg_bus_client *client, *temp_client;
|
||||||
struct sde_rot_data_type *sde_res = sde_rot_get_mdata();
|
struct sde_rot_data_type *sde_res = sde_rot_get_mdata();
|
||||||
|
|
||||||
@@ -487,19 +498,27 @@ int sde_update_reg_bus_vote(struct reg_bus_client *bus_client, u32 usecase_ndx)
|
|||||||
max_usecase_ndx = client->usecase_ndx;
|
max_usecase_ndx = client->usecase_ndx;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sde_res->reg_bus_usecase_ndx != max_usecase_ndx) {
|
if (sde_res->reg_bus_usecase_ndx != max_usecase_ndx)
|
||||||
changed = true;
|
changed = true;
|
||||||
sde_res->reg_bus_usecase_ndx = max_usecase_ndx;
|
|
||||||
}
|
|
||||||
|
|
||||||
SDEROT_DBG(
|
SDEROT_DBG(
|
||||||
"%pS: changed=%d current idx=%d request client %s id:%u idx:%d\n",
|
"%pS: changed=%d current idx=%d request client %s id:%u idx:%d\n",
|
||||||
__builtin_return_address(0), changed, max_usecase_ndx,
|
__builtin_return_address(0), changed, max_usecase_ndx,
|
||||||
bus_client->name, bus_client->id, usecase_ndx);
|
bus_client->name, bus_client->id, usecase_ndx);
|
||||||
if (changed)
|
if (changed) {
|
||||||
ret = msm_bus_scale_client_update_request(sde_res->reg_bus_hdl,
|
reg_bus_value = sde_get_rot_reg_bus_value(max_usecase_ndx);
|
||||||
max_usecase_ndx);
|
ret = icc_set_bw(sde_res->reg_bus_hdl, reg_bus_value->ab,
|
||||||
|
reg_bus_value->ib);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ret) {
|
||||||
|
pr_err("rotator: reg_bus_hdl set failed ab=%llu, ib=%llu\n",
|
||||||
|
reg_bus_value->ab, reg_bus_value->ib);
|
||||||
|
if (sde_res->reg_bus_usecase_ndx == VOTE_INDEX_DISABLE)
|
||||||
|
pr_err("rotator: reg_bus_hdl was disabled\n");
|
||||||
|
} else {
|
||||||
|
sde_res->reg_bus_usecase_ndx = max_usecase_ndx;
|
||||||
|
}
|
||||||
mutex_unlock(&sde_res->reg_bus_lock);
|
mutex_unlock(&sde_res->reg_bus_lock);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -820,74 +839,33 @@ static void sde_mdp_destroy_dt_misc(struct platform_device *pdev,
|
|||||||
mdata->vbif_nrt_qos = NULL;
|
mdata->vbif_nrt_qos = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MDP_REG_BUS_VECTOR_ENTRY(ab_val, ib_val) \
|
|
||||||
{ \
|
|
||||||
.src = MSM_BUS_MASTER_AMPSS_M0, \
|
|
||||||
.dst = MSM_BUS_SLAVE_DISPLAY_CFG, \
|
|
||||||
.ab = (ab_val), \
|
|
||||||
.ib = (ib_val), \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BUS_VOTE_19_MHZ 153600000
|
|
||||||
#define BUS_VOTE_40_MHZ 320000000
|
|
||||||
#define BUS_VOTE_80_MHZ 640000000
|
|
||||||
|
|
||||||
#ifdef CONFIG_QCOM_BUS_SCALING
|
|
||||||
|
|
||||||
static struct msm_bus_vectors mdp_reg_bus_vectors[] = {
|
|
||||||
MDP_REG_BUS_VECTOR_ENTRY(0, 0),
|
|
||||||
MDP_REG_BUS_VECTOR_ENTRY(0, BUS_VOTE_19_MHZ),
|
|
||||||
MDP_REG_BUS_VECTOR_ENTRY(0, BUS_VOTE_40_MHZ),
|
|
||||||
MDP_REG_BUS_VECTOR_ENTRY(0, BUS_VOTE_80_MHZ),
|
|
||||||
};
|
|
||||||
static struct msm_bus_paths mdp_reg_bus_usecases[ARRAY_SIZE(
|
|
||||||
mdp_reg_bus_vectors)];
|
|
||||||
static struct msm_bus_scale_pdata mdp_reg_bus_scale_table = {
|
|
||||||
.usecase = mdp_reg_bus_usecases,
|
|
||||||
.num_usecases = ARRAY_SIZE(mdp_reg_bus_usecases),
|
|
||||||
.name = "sde_reg",
|
|
||||||
.active_only = true,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int sde_mdp_bus_scale_register(struct sde_rot_data_type *mdata)
|
static int sde_mdp_bus_scale_register(struct sde_rot_data_type *mdata)
|
||||||
{
|
{
|
||||||
struct msm_bus_scale_pdata *reg_bus_pdata;
|
int rc = 0;
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!mdata->reg_bus_hdl) {
|
mdata->reg_bus_hdl = of_icc_get(&mdata->pdev->dev, "qcom,sde-reg-bus");
|
||||||
reg_bus_pdata = &mdp_reg_bus_scale_table;
|
|
||||||
for (i = 0; i < reg_bus_pdata->num_usecases; i++) {
|
if (mdata->reg_bus_hdl == NULL) {
|
||||||
mdp_reg_bus_usecases[i].num_paths = 1;
|
pr_err("rotator: reg bus dt node missing\n");
|
||||||
mdp_reg_bus_usecases[i].vectors =
|
return 0;
|
||||||
&mdp_reg_bus_vectors[i];
|
} else if (IS_ERR(mdata->reg_bus_hdl)) {
|
||||||
|
SDEROT_ERR("reg bus handle parsing failed\n");
|
||||||
|
mdata->reg_bus_hdl = NULL;
|
||||||
|
rc = -EINVAL;
|
||||||
|
} else {
|
||||||
|
SDEROT_DBG("rotator reg_bus_hdl parsing success\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
mdata->reg_bus_hdl =
|
return rc;
|
||||||
msm_bus_scale_register_client(reg_bus_pdata);
|
|
||||||
if (!mdata->reg_bus_hdl) {
|
|
||||||
/* Continue without reg_bus scaling */
|
|
||||||
SDEROT_WARN("reg_bus_client register failed\n");
|
|
||||||
} else
|
|
||||||
SDEROT_DBG("register reg_bus_hdl=%x\n",
|
|
||||||
mdata->reg_bus_hdl);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static inline int sde_mdp_bus_scale_register(struct sde_rot_data_type *mdata)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static void sde_mdp_bus_scale_unregister(struct sde_rot_data_type *mdata)
|
static void sde_mdp_bus_scale_unregister(struct sde_rot_data_type *mdata)
|
||||||
{
|
{
|
||||||
SDEROT_DBG("unregister reg_bus_hdl=%x\n", mdata->reg_bus_hdl);
|
SDEROT_DBG("unregister reg_bus_hdl\n");
|
||||||
|
|
||||||
if (mdata->reg_bus_hdl) {
|
if (mdata->reg_bus_hdl) {
|
||||||
msm_bus_scale_unregister_client(mdata->reg_bus_hdl);
|
icc_put(mdata->reg_bus_hdl);
|
||||||
mdata->reg_bus_hdl = 0;
|
mdata->reg_bus_hdl = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/of_platform.h>
|
#include <linux/of_platform.h>
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
|
#include <linux/interconnect.h>
|
||||||
|
|
||||||
#include "sde_rotator_hwio.h"
|
#include "sde_rotator_hwio.h"
|
||||||
#include "sde_rotator_io_util.h"
|
#include "sde_rotator_io_util.h"
|
||||||
@@ -90,9 +91,9 @@ struct sde_mdp_vbif_halt_params {
|
|||||||
|
|
||||||
enum sde_bus_vote_type {
|
enum sde_bus_vote_type {
|
||||||
VOTE_INDEX_DISABLE,
|
VOTE_INDEX_DISABLE,
|
||||||
VOTE_INDEX_19_MHZ,
|
VOTE_INDEX_76_MHZ,
|
||||||
VOTE_INDEX_40_MHZ,
|
VOTE_INDEX_150_MHZ,
|
||||||
VOTE_INDEX_80_MHZ,
|
VOTE_INDEX_300_MHZ,
|
||||||
VOTE_INDEX_MAX,
|
VOTE_INDEX_MAX,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -192,6 +193,16 @@ struct sde_smmu_client {
|
|||||||
u32 sid;
|
u32 sid;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* struct sde_rot_bus_data: struct for bus setting
|
||||||
|
* @ab: average bandwidth in kilobytes per second
|
||||||
|
* @ib: peak bandwidth in kilobytes per second
|
||||||
|
*/
|
||||||
|
struct sde_rot_bus_data {
|
||||||
|
uint64_t ab; /* Arbitrated bandwidth */
|
||||||
|
uint64_t ib; /* Instantaneous bandwidth */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* struct sde_rot_debug_bus: rotator debugbus header structure
|
* struct sde_rot_debug_bus: rotator debugbus header structure
|
||||||
* @wr_addr: write address for debugbus controller
|
* @wr_addr: write address for debugbus controller
|
||||||
@@ -251,7 +262,7 @@ struct sde_rot_data_type {
|
|||||||
u32 rot_block_size;
|
u32 rot_block_size;
|
||||||
|
|
||||||
/* register bus (AHB) */
|
/* register bus (AHB) */
|
||||||
u32 reg_bus_hdl;
|
struct icc_path *reg_bus_hdl;
|
||||||
u32 reg_bus_usecase_ndx;
|
u32 reg_bus_usecase_ndx;
|
||||||
struct list_head reg_bus_clist;
|
struct list_head reg_bus_clist;
|
||||||
struct mutex reg_bus_lock;
|
struct mutex reg_bus_lock;
|
||||||
@@ -320,6 +331,7 @@ void vbif_unlock(struct platform_device *parent_pdev);
|
|||||||
void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params);
|
void sde_mdp_halt_vbif_xin(struct sde_mdp_vbif_halt_params *params);
|
||||||
|
|
||||||
int sde_mdp_init_vbif(void);
|
int sde_mdp_init_vbif(void);
|
||||||
|
const struct sde_rot_bus_data *sde_get_rot_reg_bus_value(u32 usecase_ndx);
|
||||||
|
|
||||||
#define SDE_VBIF_WRITE(mdata, offset, value) \
|
#define SDE_VBIF_WRITE(mdata, offset, value) \
|
||||||
(sde_reg_w(&mdata->vbif_nrt_io, offset, value, 0))
|
(sde_reg_w(&mdata->vbif_nrt_io, offset, value, 0))
|
||||||
|
@@ -13,8 +13,6 @@
|
|||||||
#include <linux/of.h>
|
#include <linux/of.h>
|
||||||
#include <linux/clk.h>
|
#include <linux/clk.h>
|
||||||
#include <linux/debugfs.h>
|
#include <linux/debugfs.h>
|
||||||
#include <linux/msm-bus.h>
|
|
||||||
#include <linux/msm-bus-board.h>
|
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <linux/dma-direction.h>
|
#include <linux/dma-direction.h>
|
||||||
#include <soc/qcom/scm.h>
|
#include <soc/qcom/scm.h>
|
||||||
@@ -69,50 +67,20 @@
|
|||||||
*/
|
*/
|
||||||
#define ROT_MAX_HW_BLOCKS 2
|
#define ROT_MAX_HW_BLOCKS 2
|
||||||
|
|
||||||
#define SDE_REG_BUS_VECTOR_ENTRY(ab_val, ib_val) \
|
|
||||||
{ \
|
|
||||||
.src = MSM_BUS_MASTER_AMPSS_M0, \
|
|
||||||
.dst = MSM_BUS_SLAVE_DISPLAY_CFG, \
|
|
||||||
.ab = (ab_val), \
|
|
||||||
.ib = (ib_val), \
|
|
||||||
}
|
|
||||||
|
|
||||||
#define BUS_VOTE_19_MHZ 153600000
|
#define BUS_VOTE_19_MHZ 153600000
|
||||||
|
|
||||||
/* forward prototype */
|
/* forward prototype */
|
||||||
static int sde_rotator_update_perf(struct sde_rot_mgr *mgr);
|
static int sde_rotator_update_perf(struct sde_rot_mgr *mgr);
|
||||||
|
|
||||||
#ifdef CONFIG_QCOM_BUS_SCALING
|
|
||||||
static struct msm_bus_vectors rot_reg_bus_vectors[] = {
|
|
||||||
SDE_REG_BUS_VECTOR_ENTRY(0, 0),
|
|
||||||
SDE_REG_BUS_VECTOR_ENTRY(0, BUS_VOTE_19_MHZ),
|
|
||||||
};
|
|
||||||
static struct msm_bus_paths rot_reg_bus_usecases[ARRAY_SIZE(
|
|
||||||
rot_reg_bus_vectors)];
|
|
||||||
static struct msm_bus_scale_pdata rot_reg_bus_scale_table = {
|
|
||||||
.usecase = rot_reg_bus_usecases,
|
|
||||||
.num_usecases = ARRAY_SIZE(rot_reg_bus_usecases),
|
|
||||||
.name = "mdss_rot_reg",
|
|
||||||
.active_only = 1,
|
|
||||||
};
|
|
||||||
|
|
||||||
static int sde_rotator_bus_scale_set_quota(struct sde_rot_bus_data_type *bus,
|
static int sde_rotator_bus_scale_set_quota(struct sde_rot_bus_data_type *bus,
|
||||||
u64 quota)
|
u64 quota)
|
||||||
{
|
{
|
||||||
int new_uc_idx;
|
int ret = 0, i = 0, j = 0;
|
||||||
int ret;
|
u64 ab = 0;
|
||||||
|
|
||||||
if (!bus) {
|
if (!bus || !bus->data_paths_cnt) {
|
||||||
SDEROT_ERR("null parameter\n");
|
SDEROT_DBG("bus scaling not register\n");
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!bus->bus_hdl) {
|
|
||||||
SDEROT_DBG("bus scaling not enabled\n");
|
|
||||||
return 0;
|
return 0;
|
||||||
} else if (bus->bus_hdl < 0) {
|
|
||||||
SDEROT_ERR("invalid bus handle %d\n", bus->bus_hdl);
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bus->curr_quota_val == quota) {
|
if (bus->curr_quota_val == quota) {
|
||||||
@@ -120,46 +88,31 @@ static int sde_rotator_bus_scale_set_quota(struct sde_rot_bus_data_type *bus,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!bus->bus_scale_pdata || !bus->bus_scale_pdata->num_usecases) {
|
SDEROT_EVTLOG(quota);
|
||||||
SDEROT_ERR("invalid bus scale data\n");
|
SDEROT_DBG("quota=%llu\n", quota);
|
||||||
return -EINVAL;
|
ATRACE_BEGIN("msm_bus_scale_req_rot");
|
||||||
}
|
ab = div_u64(quota, bus->data_paths_cnt);
|
||||||
|
|
||||||
if (!quota) {
|
for (i = 0; i < bus->data_paths_cnt; i++) {
|
||||||
new_uc_idx = 0;
|
if (bus->data_bus_hdl[i]) {
|
||||||
} else {
|
ret = icc_set_bw(bus->data_bus_hdl[i], ab, ab);
|
||||||
struct msm_bus_vectors *vect = NULL;
|
if (ret)
|
||||||
struct msm_bus_scale_pdata *bw_table =
|
goto err;
|
||||||
bus->bus_scale_pdata;
|
|
||||||
u64 port_quota = quota;
|
|
||||||
u32 total_axi_port_cnt;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
new_uc_idx = (bus->curr_bw_uc_idx %
|
|
||||||
(bw_table->num_usecases - 1)) + 1;
|
|
||||||
|
|
||||||
total_axi_port_cnt = bw_table->usecase[new_uc_idx].num_paths;
|
|
||||||
if (total_axi_port_cnt == 0) {
|
|
||||||
SDEROT_ERR("Number of bw paths is 0\n");
|
|
||||||
return -ENODEV;
|
|
||||||
}
|
|
||||||
do_div(port_quota, total_axi_port_cnt);
|
|
||||||
|
|
||||||
for (i = 0; i < total_axi_port_cnt; i++) {
|
|
||||||
vect = &bw_table->usecase[new_uc_idx].vectors[i];
|
|
||||||
vect->ab = port_quota;
|
|
||||||
vect->ib = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
bus->curr_bw_uc_idx = new_uc_idx;
|
|
||||||
|
ATRACE_END("msm_bus_scale_req_rot");
|
||||||
bus->curr_quota_val = quota;
|
bus->curr_quota_val = quota;
|
||||||
|
|
||||||
SDEROT_EVTLOG(new_uc_idx, quota);
|
return 0;
|
||||||
SDEROT_DBG("uc_idx=%d quota=%llu\n", new_uc_idx, quota);
|
err:
|
||||||
ATRACE_BEGIN("msm_bus_scale_req_rot");
|
ab = div_u64(bus->curr_quota_val, bus->data_paths_cnt);
|
||||||
ret = msm_bus_scale_client_update_request(bus->bus_hdl,
|
for (j = 0; j < i; j++)
|
||||||
new_uc_idx);
|
icc_set_bw(bus->data_bus_hdl[j], ab, ab);
|
||||||
ATRACE_END("msm_bus_scale_req_rot");
|
ATRACE_END("msm_bus_scale_req_rot");
|
||||||
|
pr_err("failed to set data bus quota %llu\n", quota);
|
||||||
|
if (!bus->curr_quota_val) {
|
||||||
|
pr_err("rotator: data bus was set to 0\n");
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -168,43 +121,40 @@ static int sde_rotator_enable_reg_bus(struct sde_rot_mgr *mgr, u64 quota)
|
|||||||
{
|
{
|
||||||
int ret = 0, changed = 0;
|
int ret = 0, changed = 0;
|
||||||
u32 usecase_ndx = 0;
|
u32 usecase_ndx = 0;
|
||||||
|
const struct sde_rot_bus_data *reg_bus_value = NULL;
|
||||||
|
|
||||||
if (!mgr || !mgr->reg_bus.bus_hdl)
|
if (!mgr || !mgr->reg_bus.data_paths_cnt)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
if (quota)
|
if (quota)
|
||||||
usecase_ndx = 1;
|
usecase_ndx = VOTE_INDEX_76_MHZ;
|
||||||
|
|
||||||
if (usecase_ndx != mgr->reg_bus.curr_bw_uc_idx) {
|
if (usecase_ndx != mgr->reg_bus.curr_bw_uc_idx)
|
||||||
mgr->reg_bus.curr_bw_uc_idx = usecase_ndx;
|
|
||||||
changed++;
|
changed++;
|
||||||
}
|
|
||||||
|
|
||||||
SDEROT_DBG("%s, changed=%d register bus %s\n", __func__, changed,
|
SDEROT_DBG("%s, changed=%d register bus %s\n", __func__, changed,
|
||||||
quota ? "Enable":"Disable");
|
quota ? "Enable":"Disable");
|
||||||
|
|
||||||
if (changed) {
|
if (changed) {
|
||||||
ATRACE_BEGIN("msm_bus_scale_req_rot_reg");
|
ATRACE_BEGIN("msm_bus_scale_req_rot_reg");
|
||||||
ret = msm_bus_scale_client_update_request(mgr->reg_bus.bus_hdl,
|
|
||||||
usecase_ndx);
|
reg_bus_value = sde_get_rot_reg_bus_value(usecase_ndx);
|
||||||
|
ret = icc_set_bw(mgr->reg_bus.data_bus_hdl[0],
|
||||||
|
reg_bus_value->ab, reg_bus_value->ib);
|
||||||
ATRACE_END("msm_bus_scale_req_rot_reg");
|
ATRACE_END("msm_bus_scale_req_rot_reg");
|
||||||
|
|
||||||
|
}
|
||||||
|
if (ret) {
|
||||||
|
pr_err("rotator: set reg bus failed ab=%llu, lb=%llu\n",
|
||||||
|
reg_bus_value->ab, reg_bus_value->ib);
|
||||||
|
if (mgr->reg_bus.curr_bw_uc_idx == VOTE_INDEX_DISABLE)
|
||||||
|
pr_err("rotator: reg bus was disabled\n");
|
||||||
|
} else {
|
||||||
|
mgr->reg_bus.curr_bw_uc_idx = usecase_ndx;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static inline int sde_rotator_enable_reg_bus(struct sde_rot_mgr *mgr, u64 quota)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline int sde_rotator_bus_scale_set_quota(
|
|
||||||
struct sde_rot_bus_data_type *bus, u64 quota)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Clock rate of all open sessions working a particular hw block
|
* Clock rate of all open sessions working a particular hw block
|
||||||
* are added together to get the required rate for that hw block.
|
* are added together to get the required rate for that hw block.
|
||||||
@@ -375,6 +325,7 @@ int sde_rotator_clk_ctrl(struct sde_rot_mgr *mgr, int enable)
|
|||||||
{
|
{
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int changed = 0;
|
int changed = 0;
|
||||||
|
int i = 0, bus_cnt = 0;
|
||||||
|
|
||||||
if (enable) {
|
if (enable) {
|
||||||
if (mgr->rot_enable_clk_cnt == 0)
|
if (mgr->rot_enable_clk_cnt == 0)
|
||||||
@@ -425,9 +376,15 @@ int sde_rotator_clk_ctrl(struct sde_rot_mgr *mgr, int enable)
|
|||||||
goto error_rot_sub;
|
goto error_rot_sub;
|
||||||
|
|
||||||
/* Active+Sleep */
|
/* Active+Sleep */
|
||||||
msm_bus_scale_client_update_context(
|
if (mgr->data_bus.bus_active_only) {
|
||||||
mgr->data_bus.bus_hdl, false,
|
bus_cnt = mgr->data_bus.data_paths_cnt;
|
||||||
mgr->data_bus.curr_bw_uc_idx);
|
for (i = 0; i < bus_cnt; i++) {
|
||||||
|
icc_set_tag(
|
||||||
|
mgr->data_bus.data_bus_hdl[i],
|
||||||
|
(QCOM_ICC_TAG_ACTIVE_ONLY |
|
||||||
|
QCOM_ICC_TAG_SLEEP));
|
||||||
|
}
|
||||||
|
}
|
||||||
trace_rot_bw_ao_as_context(0);
|
trace_rot_bw_ao_as_context(0);
|
||||||
} else {
|
} else {
|
||||||
sde_rotator_disable_clk(mgr,
|
sde_rotator_disable_clk(mgr,
|
||||||
@@ -440,9 +397,15 @@ int sde_rotator_clk_ctrl(struct sde_rot_mgr *mgr, int enable)
|
|||||||
sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_MNOC_AHB);
|
sde_rotator_disable_clk(mgr, SDE_ROTATOR_CLK_MNOC_AHB);
|
||||||
|
|
||||||
/* Active Only */
|
/* Active Only */
|
||||||
msm_bus_scale_client_update_context(
|
if (mgr->data_bus.bus_active_only) {
|
||||||
mgr->data_bus.bus_hdl, true,
|
bus_cnt = mgr->data_bus.data_paths_cnt;
|
||||||
mgr->data_bus.curr_bw_uc_idx);
|
for (i = 0; i < bus_cnt; i++) {
|
||||||
|
icc_set_tag(
|
||||||
|
mgr->data_bus.data_bus_hdl[i],
|
||||||
|
QCOM_ICC_TAG_ACTIVE_ONLY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trace_rot_bw_ao_as_context(1);
|
trace_rot_bw_ao_as_context(1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2766,56 +2729,67 @@ static struct attribute_group sde_rotator_fs_attr_group = {
|
|||||||
.attrs = sde_rotator_fs_attrs
|
.attrs = sde_rotator_fs_attrs
|
||||||
};
|
};
|
||||||
|
|
||||||
#ifdef CONFIG_QCOM_BUS_SCALING
|
|
||||||
static int sde_rotator_parse_dt_bus(struct sde_rot_mgr *mgr,
|
static int sde_rotator_parse_dt_bus(struct sde_rot_mgr *mgr,
|
||||||
struct platform_device *dev)
|
struct platform_device *dev)
|
||||||
{
|
{
|
||||||
int ret = 0, i;
|
char bus_name[32];
|
||||||
int usecases;
|
int ret = 0, i = 0;
|
||||||
struct device_node *node;
|
|
||||||
|
|
||||||
mgr->data_bus.bus_scale_pdata = msm_bus_cl_get_pdata(dev);
|
mgr->reg_bus.data_bus_hdl[0] = of_icc_get(&dev->dev,
|
||||||
if (IS_ERR_OR_NULL(mgr->data_bus.bus_scale_pdata)) {
|
"qcom,sde-reg-bus");
|
||||||
ret = PTR_ERR(mgr->data_bus.bus_scale_pdata);
|
|
||||||
if (ret) {
|
if (mgr->reg_bus.data_bus_hdl[0] == NULL) {
|
||||||
SDEROT_ERR("msm_bus_cl_get_pdata failed. ret=%d\n",
|
mgr->reg_bus.data_paths_cnt = 0;
|
||||||
|
pr_debug("rotator: reg bus dt node missing\n");
|
||||||
|
goto data_bus;
|
||||||
|
} else if (IS_ERR(mgr->reg_bus.data_bus_hdl[0])) {
|
||||||
|
SDEROT_ERR("sde rotator parse reg bus failed. ret=%d\n",
|
||||||
ret);
|
ret);
|
||||||
mgr->data_bus.bus_scale_pdata = NULL;
|
mgr->reg_bus.data_bus_hdl[0] = NULL;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
node = of_get_child_by_name(dev->dev.of_node, "qcom,rot-reg-bus");
|
|
||||||
if (node) {
|
|
||||||
mgr->reg_bus.bus_scale_pdata
|
|
||||||
= msm_bus_pdata_from_node(dev, node);
|
|
||||||
if (IS_ERR_OR_NULL(mgr->reg_bus.bus_scale_pdata)) {
|
|
||||||
SDEROT_ERR("reg bus pdata parsing failed\n");
|
|
||||||
ret = PTR_ERR(mgr->reg_bus.bus_scale_pdata);
|
|
||||||
if (!mgr->reg_bus.bus_scale_pdata)
|
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
mgr->reg_bus.bus_scale_pdata = NULL;
|
return ret;
|
||||||
}
|
}
|
||||||
} else {
|
mgr->reg_bus.data_paths_cnt = 1;
|
||||||
SDEROT_DBG(
|
|
||||||
"no DT entries, configuring default reg bus table\n");
|
data_bus:
|
||||||
mgr->reg_bus.bus_scale_pdata = &rot_reg_bus_scale_table;
|
for (i = 0; i < SDE_ROTATION_BUS_PATH_MAX; i++) {
|
||||||
usecases = mgr->reg_bus.bus_scale_pdata->num_usecases;
|
snprintf(bus_name, 32, "%s%d", "qcom,rot-data-bus", i);
|
||||||
for (i = 0; i < usecases; i++) {
|
ret = of_property_match_string(pdev->dev.of_node,
|
||||||
rot_reg_bus_usecases[i].num_paths = 1;
|
"interconnect-names", bus_name);
|
||||||
rot_reg_bus_usecases[i].vectors =
|
if (ret < 0) {
|
||||||
&rot_reg_bus_vectors[i];
|
if (!mgr->data_bus.data_paths_cnt) {
|
||||||
|
pr_debug("rotator: bus %s dt node missing\n", bus_name);
|
||||||
|
return 0;
|
||||||
|
} else
|
||||||
|
goto end;
|
||||||
|
} else
|
||||||
|
mgr->data_bus.data_bus_hdl[i] = of_icc_get(&pdev->dev, bus_name);
|
||||||
|
|
||||||
|
if (IS_ERR_OR_NULL(mgr->data_bus.data_bus_hdl[i])) {
|
||||||
|
SDEROT_ERR("rotator: get data bus %s failed\n",
|
||||||
|
bus_name);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
mgr->data_bus.data_paths_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!mgr->data_bus.data_paths_cnt) {
|
||||||
|
pr_err("rotator: get none data bus path\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
end:
|
||||||
|
if (of_find_property(dev->dev.of_node,
|
||||||
|
"qcom,msm-bus,active-only", NULL)) {
|
||||||
|
mgr->data_bus.bus_active_only = true;
|
||||||
|
for (i = 0; i < mgr->data_bus.data_paths_cnt; i++) {
|
||||||
|
icc_set_tag(mgr->data_bus.data_bus_hdl[i],
|
||||||
|
QCOM_ICC_TAG_ACTIVE_ONLY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
static inline int sde_rotator_parse_dt_bus(struct sde_rot_mgr *mgr,
|
|
||||||
struct platform_device *dev)
|
|
||||||
{
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
static int sde_rotator_parse_dt(struct sde_rot_mgr *mgr,
|
static int sde_rotator_parse_dt(struct sde_rot_mgr *mgr,
|
||||||
struct platform_device *dev)
|
struct platform_device *dev)
|
||||||
@@ -2920,59 +2894,19 @@ error:
|
|||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_QCOM_BUS_SCALING
|
|
||||||
static void sde_rotator_bus_scale_unregister(struct sde_rot_mgr *mgr)
|
static void sde_rotator_bus_scale_unregister(struct sde_rot_mgr *mgr)
|
||||||
{
|
{
|
||||||
SDEROT_DBG("unregister bus_hdl=%x, reg_bus_hdl=%x\n",
|
int i = 0;
|
||||||
mgr->data_bus.bus_hdl, mgr->reg_bus.bus_hdl);
|
|
||||||
|
|
||||||
if (mgr->data_bus.bus_hdl)
|
SDEROT_DBG("unregister sde rotator bus\n");
|
||||||
msm_bus_scale_unregister_client(mgr->data_bus.bus_hdl);
|
for (i = 0; i < mgr->data_bus.data_paths_cnt; i++) {
|
||||||
|
if (mgr->data_bus.data_bus_hdl[i])
|
||||||
if (mgr->reg_bus.bus_hdl)
|
icc_put(mgr->data_bus.data_bus_hdl[i]);
|
||||||
msm_bus_scale_unregister_client(mgr->reg_bus.bus_hdl);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int sde_rotator_bus_scale_register(struct sde_rot_mgr *mgr)
|
|
||||||
{
|
|
||||||
if (!mgr->data_bus.bus_scale_pdata) {
|
|
||||||
SDEROT_DBG("Bus scaling is not enabled\n");
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
mgr->data_bus.bus_hdl =
|
if (mgr->reg_bus.data_bus_hdl[0])
|
||||||
msm_bus_scale_register_client(
|
icc_put(mgr->reg_bus.data_bus_hdl[0]);
|
||||||
mgr->data_bus.bus_scale_pdata);
|
|
||||||
if (!mgr->data_bus.bus_hdl) {
|
|
||||||
SDEROT_ERR("bus_client register failed\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
SDEROT_DBG("registered bus_hdl=%x\n", mgr->data_bus.bus_hdl);
|
|
||||||
|
|
||||||
if (mgr->reg_bus.bus_scale_pdata) {
|
|
||||||
mgr->reg_bus.bus_hdl =
|
|
||||||
msm_bus_scale_register_client(
|
|
||||||
mgr->reg_bus.bus_scale_pdata);
|
|
||||||
if (!mgr->reg_bus.bus_hdl) {
|
|
||||||
SDEROT_ERR("register bus_client register failed\n");
|
|
||||||
sde_rotator_bus_scale_unregister(mgr);
|
|
||||||
} else {
|
|
||||||
SDEROT_DBG("registered register bus_hdl=%x\n",
|
|
||||||
mgr->reg_bus.bus_hdl);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#else
|
|
||||||
static inline void sde_rotator_bus_scale_unregister(struct sde_rot_mgr *mgr)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
static inline int sde_rotator_bus_scale_register(struct sde_rot_mgr *mgr)
|
|
||||||
{
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static inline int sde_rotator_search_dt_clk(struct platform_device *pdev,
|
static inline int sde_rotator_search_dt_clk(struct platform_device *pdev,
|
||||||
struct sde_rot_mgr *mgr, char *clk_name, int clk_idx,
|
struct sde_rot_mgr *mgr, char *clk_name, int clk_idx,
|
||||||
@@ -3092,10 +3026,6 @@ static int sde_rotator_res_init(struct platform_device *pdev,
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
ret = sde_rotator_bus_scale_register(mgr);
|
|
||||||
if (ret)
|
|
||||||
goto error;
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
error:
|
error:
|
||||||
sde_rotator_put_dt_vreg_data(&pdev->dev, &mgr->module_power);
|
sde_rotator_put_dt_vreg_data(&pdev->dev, &mgr->module_power);
|
||||||
|
@@ -60,6 +60,23 @@
|
|||||||
|
|
||||||
/* use client provided clock/bandwidth parameters */
|
/* use client provided clock/bandwidth parameters */
|
||||||
#define SDE_ROTATION_EXT_PERF 0x100000
|
#define SDE_ROTATION_EXT_PERF 0x100000
|
||||||
|
#define SDE_ROTATION_BUS_PATH_MAX 0x2
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The AMC bucket denotes constraints that are applied to hardware when
|
||||||
|
* icc_set_bw() completes, whereas the WAKE and SLEEP constraints are applied
|
||||||
|
* when the execution environment transitions between active and low power mode.
|
||||||
|
*/
|
||||||
|
#define QCOM_ICC_BUCKET_AMC 0
|
||||||
|
#define QCOM_ICC_BUCKET_WAKE 1
|
||||||
|
#define QCOM_ICC_BUCKET_SLEEP 2
|
||||||
|
#define QCOM_ICC_NUM_BUCKETS 3
|
||||||
|
#define QCOM_ICC_TAG_AMC BIT(QCOM_ICC_BUCKET_AMC)
|
||||||
|
#define QCOM_ICC_TAG_WAKE BIT(QCOM_ICC_BUCKET_WAKE)
|
||||||
|
#define QCOM_ICC_TAG_SLEEP BIT(QCOM_ICC_BUCKET_SLEEP)
|
||||||
|
#define QCOM_ICC_TAG_ACTIVE_ONLY (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE)
|
||||||
|
#define QCOM_ICC_TAG_ALWAYS (QCOM_ICC_TAG_AMC | QCOM_ICC_TAG_WAKE |\
|
||||||
|
QCOM_ICC_TAG_SLEEP)
|
||||||
|
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* configuration structures
|
* configuration structures
|
||||||
@@ -374,18 +391,19 @@ struct sde_rot_file_private {
|
|||||||
struct sde_rot_queue_v1 *fenceq;
|
struct sde_rot_queue_v1 *fenceq;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* struct sde_rot_bus_data_type - rotator bus scaling configuration
|
* struct sde_rot_bus_data_type: power handle struct for data bus
|
||||||
* @bus_cale_pdata: pointer to bus scaling configuration table
|
* @data_paths_cnt: number of rt data path ports
|
||||||
* @bus_hdl: msm bus scaling handle
|
* @curr_quota_val: save the current bus value
|
||||||
* @curr_bw_uc_idx; current usecase index into configuration table
|
* @curr_bw_uc_idx: current reg bus value index
|
||||||
* @curr_quota_val: current bandwidth request in byte per second
|
* @bus_active_only: AMC support, can set the bus path WAKE/SLEEP
|
||||||
*/
|
*/
|
||||||
struct sde_rot_bus_data_type {
|
struct sde_rot_bus_data_type {
|
||||||
struct msm_bus_scale_pdata *bus_scale_pdata;
|
struct icc_path *data_bus_hdl[SDE_ROTATION_BUS_PATH_MAX];
|
||||||
u32 bus_hdl;
|
u32 data_paths_cnt;
|
||||||
u32 curr_bw_uc_idx;
|
|
||||||
u64 curr_quota_val;
|
u64 curr_quota_val;
|
||||||
|
u32 curr_bw_uc_idx;
|
||||||
|
bool bus_active_only;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -12,7 +12,6 @@
|
|||||||
#include <linux/ktime.h>
|
#include <linux/ktime.h>
|
||||||
#include <linux/iommu.h>
|
#include <linux/iommu.h>
|
||||||
#include <linux/dma-buf.h>
|
#include <linux/dma-buf.h>
|
||||||
#include <linux/msm-bus.h>
|
|
||||||
#include <linux/platform_device.h>
|
#include <linux/platform_device.h>
|
||||||
#include <linux/soc/qcom/llcc-qcom.h>
|
#include <linux/soc/qcom/llcc-qcom.h>
|
||||||
#include <linux/kthread.h>
|
#include <linux/kthread.h>
|
||||||
|
@@ -164,7 +164,7 @@ static int sde_smmu_enable_power(struct sde_smmu_client *sde_smmu,
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
sde_update_reg_bus_vote(sde_smmu->reg_bus_clt,
|
sde_update_reg_bus_vote(sde_smmu->reg_bus_clt,
|
||||||
VOTE_INDEX_19_MHZ);
|
VOTE_INDEX_76_MHZ);
|
||||||
rc = sde_rot_enable_clk(mp->clk_config, mp->num_clk, true);
|
rc = sde_rot_enable_clk(mp->clk_config, mp->num_clk, true);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
SDEROT_ERR("clock enable failed - rc:%d\n", rc);
|
SDEROT_ERR("clock enable failed - rc:%d\n", rc);
|
||||||
|
@@ -18,8 +18,6 @@
|
|||||||
#include <linux/slab.h>
|
#include <linux/slab.h>
|
||||||
#include <linux/io.h>
|
#include <linux/io.h>
|
||||||
#include <linux/iopoll.h>
|
#include <linux/iopoll.h>
|
||||||
#include <linux/msm-bus.h>
|
|
||||||
#include <linux/msm-bus-board.h>
|
|
||||||
#include <linux/regulator/consumer.h>
|
#include <linux/regulator/consumer.h>
|
||||||
#include <media/msm_media_info.h>
|
#include <media/msm_media_info.h>
|
||||||
#include <linux/videodev2.h>
|
#include <linux/videodev2.h>
|
||||||
|
Reference in New Issue
Block a user