video: rockchip: mpp: reset relative code refactoring

tips:
1. it should not use reset->rw_sem when reset is not shared.
2. if hardware is combo, and work is time sharing, which
   reset_group in the same taskqueue, the reset->rw_sem
   is also should turn off.

Change-Id: I9d89e3118997cc8d1871ac77799faf85043743d3
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2020-05-28 17:03:50 +08:00
committed by Tao Huang
parent 8ec4aa8c3b
commit ae6f03a436
10 changed files with 146 additions and 182 deletions

View File

@@ -317,7 +317,7 @@ static void mpp_task_timeout_work(struct work_struct *work_s)
mpp = session->mpp;
/* hardware maybe dead, reset it */
up_read(&mpp->reset_group->rw_sem);
mpp_reset_up_read(mpp->reset_group);
mpp_dev_reset(mpp);
mpp_power_off(mpp);
@@ -395,83 +395,54 @@ static int mpp_refresh_pm_runtime(struct mpp_iommu_info *info,
}
struct reset_control *
mpp_reset_control_get(struct mpp_dev *mpp, const char *name)
mpp_reset_control_get(struct mpp_dev *mpp, enum MPP_RESET_TYPE type, const char *name)
{
struct mpp_reset_clk *rst_clk = NULL, *n;
struct reset_control *clk = NULL;
struct device *dev = mpp->dev;
char shared_name[30] = "shared_";
int index = 0;
int clk_cnt = 0, i = 0;
static const char * const clk_list[] = {
"video_a", "video_h",
"niu_a", "niu_h",
"video_cabac", "video_core",
"video_hevc_cabac",
};
int index;
struct reset_control *rst = NULL;
char shared_name[32] = "shared_";
struct mpp_reset_group *group;
if (!name) {
mpp_err("error: reset clk name is null\n");
return NULL;
}
clk_cnt = ARRAY_SIZE(clk_list);
for (i = 0; i < clk_cnt; i++) {
if (!strcmp(clk_list[i], name))
break;
}
if (i == clk_cnt) {
mpp_err("error: reset clk name is error\n");
return NULL;
}
if (!dev) {
mpp_err("error: dev is null\n");
return NULL;
}
/* not shared reset clk */
index = of_property_match_string(dev->of_node, "reset-names", name);
/* check reset whether belone to device alone */
index = of_property_match_string(mpp->dev->of_node, "reset-names", name);
if (index >= 0) {
clk = devm_reset_control_get(dev, name);
return clk;
rst = devm_reset_control_get(mpp->dev, name);
mpp_safe_unreset(rst);
return rst;
}
/* shared reset clk */
/* check reset whether is shared */
strncat(shared_name, name,
sizeof(shared_name) - strlen(shared_name) - 1);
index = of_property_match_string(dev->of_node, "reset-names",
shared_name);
if (index >= 0) {
down_write(&mpp->reset_group->rw_sem);
list_for_each_entry_safe(rst_clk, n,
&mpp->reset_group->clk, link) {
if (!strcmp(rst_clk->name, name)) {
clk = rst_clk->clk;
break;
}
}
if (!clk) {
rst_clk = devm_kzalloc(dev, sizeof(*rst_clk),
GFP_KERNEL);
strncpy(rst_clk->name, name, sizeof(rst_clk->name));
rst_clk->clk = devm_reset_control_get(dev,
shared_name);
if (IS_ERR_OR_NULL(rst_clk->clk))
goto fail;
INIT_LIST_HEAD(&rst_clk->link);
list_add_tail(&rst_clk->link, &mpp->reset_group->clk);
clk = rst_clk->clk;
}
up_write(&mpp->reset_group->rw_sem);
index = of_property_match_string(mpp->dev->of_node,
"reset-names", shared_name);
if (index < 0) {
dev_err(mpp->dev, "%s is not found!\n", shared_name);
return NULL;
}
return clk;
fail:
devm_kfree(dev, rst_clk);
up_write(&mpp->reset_group->rw_sem);
return NULL;
if (!mpp->reset_group) {
dev_err(mpp->dev, "reset group is empty!\n");
return NULL;
}
group = mpp->reset_group;
down_write(&group->rw_sem);
rst = group->resets[type];
if (!rst) {
rst = devm_reset_control_get(mpp->dev, shared_name);
mpp_safe_unreset(rst);
group->resets[type] = rst;
group->queue = mpp->queue;
}
/* if reset not in the same queue, it means different device
* may reset in the same time, then rw_sem_on should set true.
*/
group->rw_sem_on |= (group->queue != mpp->queue) ? true : false;
dev_info(mpp->dev, "reset_group->rw_sem_on=%d\n", group->rw_sem_on);
up_write(&group->rw_sem);
return rst;
}
int mpp_dev_reset(struct mpp_dev *mpp)
@@ -491,7 +462,7 @@ int mpp_dev_reset(struct mpp_dev *mpp)
mpp->hw_ops->reduce_freq(mpp);
/* FIXME lock resource lock of the other devices in combo */
down_write(&mpp->iommu_info->rw_sem);
down_write(&mpp->reset_group->rw_sem);
mpp_reset_down_write(mpp->reset_group);
atomic_set(&mpp->reset_request, 0);
mpp_iommu_detach(mpp->iommu_info);
@@ -507,7 +478,7 @@ int mpp_dev_reset(struct mpp_dev *mpp)
mpp_refresh_pm_runtime(mpp->iommu_info, mpp->dev);
mpp_iommu_attach(mpp->iommu_info);
up_write(&mpp->reset_group->rw_sem);
mpp_reset_up_write(mpp->reset_group);
up_write(&mpp->iommu_info->rw_sem);
dev_info(mpp->dev, "reset done\n");
@@ -556,7 +527,7 @@ static int mpp_task_run(struct mpp_dev *mpp,
* TODO: Lock the reader locker of the device resource lock here,
* release at the finish operation
*/
down_read(&mpp->reset_group->rw_sem);
mpp_reset_down_read(mpp->reset_group);
set_bit(TASK_STATE_START, &task->state);
schedule_delayed_work(&task->timeout_work,
@@ -801,15 +772,6 @@ int mpp_taskqueue_init(struct mpp_taskqueue *queue,
return 0;
}
int mpp_reset_group_init(struct mpp_reset_group *group,
struct mpp_service *srv)
{
init_rwsem(&group->rw_sem);
INIT_LIST_HEAD(&group->clk);
return 0;
}
static int mpp_check_cmd_v1(__u32 cmd)
{
int ret;
@@ -1423,7 +1385,7 @@ int mpp_task_finish(struct mpp_session *session,
if (mpp->dev_ops->finish)
mpp->dev_ops->finish(mpp, task);
up_read(&mpp->reset_group->rw_sem);
mpp_reset_up_read(mpp->reset_group);
if (atomic_read(&mpp->reset_request) > 0)
mpp_dev_reset(mpp);
mpp_power_off(mpp);

View File

@@ -111,6 +111,18 @@ enum MPP_CLOCK_MODE {
CLK_MODE_BUTT,
};
enum MPP_RESET_TYPE {
RST_TYPE_BASE = 0,
RST_TYPE_A = RST_TYPE_BASE,
RST_TYPE_H,
RST_TYPE_NIU_A,
RST_TYPE_NIU_H,
RST_TYPE_CORE,
RST_TYPE_CABAC,
RST_TYPE_HEVC_CABAC,
RST_TYPE_BUTT,
};
/* data common struct for parse out */
struct mpp_request {
__u32 cmd;
@@ -324,15 +336,13 @@ struct mpp_taskqueue {
struct list_head mmu_list;
};
struct mpp_reset_clk {
struct list_head link;
struct reset_control *clk;
char name[20];
};
struct mpp_reset_group {
/* the flag for whether use rw_sem */
u32 rw_sem_on;
struct rw_semaphore rw_sem;
struct list_head clk;
struct reset_control *resets[RST_TYPE_BUTT];
/* for set rw_sem */
struct mpp_taskqueue *queue;
};
struct mpp_service {
@@ -416,8 +426,6 @@ struct mpp_dev_ops {
int mpp_taskqueue_init(struct mpp_taskqueue *queue,
struct mpp_service *srv);
int mpp_reset_group_init(struct mpp_reset_group *group,
struct mpp_service *srv);
struct mpp_mem_region *
mpp_task_attach_fd(struct mpp_task *task, int fd);
@@ -454,8 +462,9 @@ int mpp_dev_reset(struct mpp_dev *mpp);
irqreturn_t mpp_dev_irq(int irq, void *param);
irqreturn_t mpp_dev_isr_sched(int irq, void *param);
struct reset_control *
mpp_reset_control_get(struct mpp_dev *mpp, const char *name);
struct reset_control *mpp_reset_control_get(struct mpp_dev *mpp,
enum MPP_RESET_TYPE type,
const char *name);
u32 mpp_get_grf(struct mpp_grf_info *grf_info);
int mpp_set_grf(struct mpp_grf_info *grf_info);
@@ -557,6 +566,38 @@ static inline int mpp_clk_safe_disable(struct clk *clk)
return 0;
}
static inline int mpp_reset_down_read(struct mpp_reset_group *group)
{
if (group && group->rw_sem_on)
down_read(&group->rw_sem);
return 0;
}
static inline int mpp_reset_up_read(struct mpp_reset_group *group)
{
if (group && group->rw_sem_on)
up_read(&group->rw_sem);
return 0;
}
static inline int mpp_reset_down_write(struct mpp_reset_group *group)
{
if (group && group->rw_sem_on)
down_write(&group->rw_sem);
return 0;
}
static inline int mpp_reset_up_write(struct mpp_reset_group *group)
{
if (group && group->rw_sem_on)
up_write(&group->rw_sem);
return 0;
}
/* workaround according hardware */
int px30_workaround_combo_init(struct mpp_dev *mpp);
int px30_workaround_combo_switch_grf(struct mpp_dev *mpp);

View File

@@ -822,21 +822,15 @@ static int iep2_init(struct mpp_dev *mpp)
/* Set default rates */
mpp_set_clk_info_rate_hz(&iep->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
iep->rst_a = devm_reset_control_get(mpp->dev, "rst_a");
if (IS_ERR_OR_NULL(iep->rst_a)) {
iep->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "rst_a");
if (!iep->rst_a)
mpp_err("No aclk reset resource define\n");
iep->rst_a = NULL;
}
iep->rst_h = devm_reset_control_get(mpp->dev, "rst_h");
if (IS_ERR_OR_NULL(iep->rst_h)) {
iep->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "rst_h");
if (!iep->rst_h)
mpp_err("No hclk reset resource define\n");
iep->rst_h = NULL;
}
iep->rst_s = devm_reset_control_get(mpp->dev, "rst_s");
if (IS_ERR_OR_NULL(iep->rst_h)) {
iep->rst_s = mpp_reset_control_get(mpp, RST_TYPE_CORE, "rst_s");
if (!iep->rst_s)
mpp_err("No sclk reset resource define\n");
iep->rst_s = NULL;
}
iep->roi.size = IEP2_TILE_W_MAX * IEP2_TILE_H_MAX;
iep->roi.vaddr = dma_alloc_coherent(mpp->dev, iep->roi.size,

View File

@@ -1182,41 +1182,28 @@ static int rkvdec_init(struct mpp_dev *mpp)
mpp_set_clk_info_rate_hz(&dec->cabac_clk_info, CLK_MODE_DEFAULT, 200 * MHZ);
mpp_set_clk_info_rate_hz(&dec->hevc_cabac_clk_info, CLK_MODE_DEFAULT, 300 * MHZ);
dec->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(dec->rst_a)) {
/* Get reset control from dtsi */
dec->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
if (!dec->rst_a)
mpp_err("No aclk reset resource define\n");
dec->rst_a = NULL;
}
dec->rst_h = mpp_reset_control_get(mpp, "video_h");
if (IS_ERR_OR_NULL(dec->rst_h)) {
dec->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "video_h");
if (!dec->rst_h)
mpp_err("No hclk reset resource define\n");
dec->rst_h = NULL;
}
dec->rst_niu_a = mpp_reset_control_get(mpp, "niu_a");
if (IS_ERR_OR_NULL(dec->rst_niu_a)) {
dec->rst_niu_a = mpp_reset_control_get(mpp, RST_TYPE_NIU_A, "niu_a");
if (!dec->rst_niu_a)
mpp_err("No niu aclk reset resource define\n");
dec->rst_niu_a = NULL;
}
dec->rst_niu_h = mpp_reset_control_get(mpp, "niu_h");
if (IS_ERR_OR_NULL(dec->rst_niu_h)) {
dec->rst_niu_h = mpp_reset_control_get(mpp, RST_TYPE_NIU_H, "niu_h");
if (!dec->rst_niu_h)
mpp_err("No niu hclk reset resource define\n");
dec->rst_niu_h = NULL;
}
dec->rst_cabac = mpp_reset_control_get(mpp, "video_cabac");
if (IS_ERR_OR_NULL(dec->rst_cabac)) {
mpp_err("No cabac reset resource define\n");
dec->rst_cabac = NULL;
}
dec->rst_core = mpp_reset_control_get(mpp, "video_core");
if (IS_ERR_OR_NULL(dec->rst_core)) {
dec->rst_core = mpp_reset_control_get(mpp, RST_TYPE_CORE, "video_core");
if (!dec->rst_core)
mpp_err("No core reset resource define\n");
dec->rst_core = NULL;
}
dec->rst_hevc_cabac = mpp_reset_control_get(mpp, "video_hevc_cabac");
if (IS_ERR_OR_NULL(dec->rst_hevc_cabac)) {
dec->rst_cabac = mpp_reset_control_get(mpp, RST_TYPE_CABAC, "video_cabac");
if (!dec->rst_cabac)
mpp_err("No cabac reset resource define\n");
dec->rst_hevc_cabac = mpp_reset_control_get(mpp, RST_TYPE_HEVC_CABAC, "video_hevc_cabac");
if (!dec->rst_hevc_cabac)
mpp_err("No hevc cabac reset resource define\n");
dec->rst_hevc_cabac = NULL;
}
return 0;
}

View File

@@ -869,24 +869,16 @@ static int rkvenc_init(struct mpp_dev *mpp)
mpp_set_clk_info_rate_hz(&enc->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
mpp_set_clk_info_rate_hz(&enc->core_clk_info, CLK_MODE_DEFAULT, 600 * MHZ);
enc->rst_a = devm_reset_control_get_shared(mpp->dev, "video_a");
if (IS_ERR_OR_NULL(enc->rst_a)) {
/* Get reset control from dtsi */
enc->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
if (!enc->rst_a)
mpp_err("No aclk reset resource define\n");
enc->rst_a = NULL;
}
enc->rst_h = devm_reset_control_get_shared(mpp->dev, "video_h");
if (IS_ERR_OR_NULL(enc->rst_h)) {
enc->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "video_h");
if (!enc->rst_h)
mpp_err("No hclk reset resource define\n");
enc->rst_h = NULL;
}
enc->rst_core = devm_reset_control_get_shared(mpp->dev, "video_core");
if (IS_ERR_OR_NULL(enc->rst_core)) {
enc->rst_core = mpp_reset_control_get(mpp, RST_TYPE_CORE, "video_core");
if (!enc->rst_core)
mpp_err("No core reset resource define\n");
enc->rst_core = NULL;
}
mpp_safe_unreset(enc->rst_a);
mpp_safe_unreset(enc->rst_h);
mpp_safe_unreset(enc->rst_core);
#ifdef CONFIG_PM_DEVFREQ
ret = rkvenc_devfreq_init(mpp);

View File

@@ -229,7 +229,7 @@ static int mpp_service_probe(struct platform_device *pdev)
if (!group)
continue;
mpp_reset_group_init(group, srv);
init_rwsem(&group->rw_sem);
srv->reset_groups[i] = group;
}
}

View File

@@ -545,16 +545,13 @@ static int vdpu_init(struct mpp_dev *mpp)
/* Set default rates */
mpp_set_clk_info_rate_hz(&dec->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
dec->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(dec->rst_a)) {
/* Get reset control from dtsi */
dec->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
if (!dec->rst_a)
mpp_err("No aclk reset resource define\n");
dec->rst_a = NULL;
}
dec->rst_h = mpp_reset_control_get(mpp, "video_h");
if (IS_ERR_OR_NULL(dec->rst_h)) {
dec->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "video_h");
if (!dec->rst_h)
mpp_err("No hclk reset resource define\n");
dec->rst_h = NULL;
}
return 0;
}

View File

@@ -498,16 +498,13 @@ static int vdpu_init(struct mpp_dev *mpp)
/* Set default rates */
mpp_set_clk_info_rate_hz(&dec->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
dec->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(dec->rst_a)) {
/* Get reset control from dtsi */
dec->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
if (!dec->rst_a)
mpp_err("No aclk reset resource define\n");
dec->rst_a = NULL;
}
dec->rst_h = mpp_reset_control_get(mpp, "video_h");
if (IS_ERR_OR_NULL(dec->rst_h)) {
dec->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "video_h");
if (!dec->rst_h)
mpp_err("No hclk reset resource define\n");
dec->rst_h = NULL;
}
return 0;
}

View File

@@ -452,16 +452,13 @@ static int vepu_init(struct mpp_dev *mpp)
/* Set default rates */
mpp_set_clk_info_rate_hz(&enc->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
enc->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(enc->rst_a)) {
/* Get reset control from dtsi */
enc->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
if (!enc->rst_a)
mpp_err("No aclk reset resource define\n");
enc->rst_a = NULL;
}
enc->rst_h = mpp_reset_control_get(mpp, "video_h");
if (IS_ERR_OR_NULL(enc->rst_h)) {
enc->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "video_h");
if (!enc->rst_h)
mpp_err("No hclk reset resource define\n");
enc->rst_h = NULL;
}
return 0;
}

View File

@@ -464,16 +464,13 @@ static int vepu_init(struct mpp_dev *mpp)
/* Set default rates */
mpp_set_clk_info_rate_hz(&enc->aclk_info, CLK_MODE_DEFAULT, 300 * MHZ);
enc->rst_a = mpp_reset_control_get(mpp, "video_a");
if (IS_ERR_OR_NULL(enc->rst_a)) {
/* Get reset control from dtsi */
enc->rst_a = mpp_reset_control_get(mpp, RST_TYPE_A, "video_a");
if (!enc->rst_a)
mpp_err("No aclk reset resource define\n");
enc->rst_a = NULL;
}
enc->rst_h = mpp_reset_control_get(mpp, "video_h");
if (IS_ERR_OR_NULL(enc->rst_h)) {
enc->rst_h = mpp_reset_control_get(mpp, RST_TYPE_H, "video_h");
if (!enc->rst_h)
mpp_err("No hclk reset resource define\n");
enc->rst_h = NULL;
}
return 0;
}