msm: mdss: Fix scalar LUT handling
Add lock to serialize access between userspace and kernel. Fix error handling for LUT allocation. Change-Id: Ie86a8eb3e2a11852ae16d87ebc851afb6566732f Signed-off-by: Animesh Kishore <animeshk@codeaurora.org>
This commit is contained in:
parent
867bd83b1f
commit
4c2dad03b7
4 changed files with 45 additions and 17 deletions
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -255,6 +255,13 @@ struct mdss_scaler_block {
|
||||||
u32 *dest_scaler_off;
|
u32 *dest_scaler_off;
|
||||||
u32 *dest_scaler_lut_off;
|
u32 *dest_scaler_lut_off;
|
||||||
struct mdss_mdp_qseed3_lut_tbl lut_tbl;
|
struct mdss_mdp_qseed3_lut_tbl lut_tbl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Lock is mainly to serialize access to LUT.
|
||||||
|
* LUT values come asynchronously from userspace
|
||||||
|
* via ioctl.
|
||||||
|
*/
|
||||||
|
struct mutex scaler_lock;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mdss_data_type;
|
struct mdss_data_type;
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* MDSS MDP Interface (used by framebuffer core)
|
* MDSS MDP Interface (used by framebuffer core)
|
||||||
*
|
*
|
||||||
* Copyright (c) 2007-2017, The Linux Foundation. All rights reserved.
|
* Copyright (c) 2007-2018, The Linux Foundation. All rights reserved.
|
||||||
* Copyright (C) 2007 Google Incorporated
|
* Copyright (C) 2007 Google Incorporated
|
||||||
*
|
*
|
||||||
* This software is licensed under the terms of the GNU General Public
|
* This software is licensed under the terms of the GNU General Public
|
||||||
|
@ -2436,6 +2436,8 @@ static u32 mdss_mdp_scaler_init(struct mdss_data_type *mdata,
|
||||||
ret = mdss_mdp_ds_addr_setup(mdata);
|
ret = mdss_mdp_ds_addr_setup(mdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_init(&mdata->scaler_off->scaler_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -6631,14 +6631,18 @@ static int mdss_mdp_scaler_lut_init(struct mdss_data_type *mdata,
|
||||||
if (!mdata->scaler_off)
|
if (!mdata->scaler_off)
|
||||||
return -EFAULT;
|
return -EFAULT;
|
||||||
|
|
||||||
|
mutex_lock(&mdata->scaler_off->scaler_lock);
|
||||||
|
|
||||||
qseed3_lut_tbl = &mdata->scaler_off->lut_tbl;
|
qseed3_lut_tbl = &mdata->scaler_off->lut_tbl;
|
||||||
if ((lut_tbl->dir_lut_size !=
|
if ((lut_tbl->dir_lut_size !=
|
||||||
DIR_LUT_IDX * DIR_LUT_COEFFS * sizeof(uint32_t)) ||
|
DIR_LUT_IDX * DIR_LUT_COEFFS * sizeof(uint32_t)) ||
|
||||||
(lut_tbl->cir_lut_size !=
|
(lut_tbl->cir_lut_size !=
|
||||||
CIR_LUT_IDX * CIR_LUT_COEFFS * sizeof(uint32_t)) ||
|
CIR_LUT_IDX * CIR_LUT_COEFFS * sizeof(uint32_t)) ||
|
||||||
(lut_tbl->sep_lut_size !=
|
(lut_tbl->sep_lut_size !=
|
||||||
SEP_LUT_IDX * SEP_LUT_COEFFS * sizeof(uint32_t)))
|
SEP_LUT_IDX * SEP_LUT_COEFFS * sizeof(uint32_t))) {
|
||||||
return -EINVAL;
|
mutex_unlock(&mdata->scaler_off->scaler_lock);
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
if (!qseed3_lut_tbl->dir_lut) {
|
if (!qseed3_lut_tbl->dir_lut) {
|
||||||
qseed3_lut_tbl->dir_lut = devm_kzalloc(&mdata->pdev->dev,
|
qseed3_lut_tbl->dir_lut = devm_kzalloc(&mdata->pdev->dev,
|
||||||
|
@ -6646,7 +6650,7 @@ static int mdss_mdp_scaler_lut_init(struct mdss_data_type *mdata,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!qseed3_lut_tbl->dir_lut) {
|
if (!qseed3_lut_tbl->dir_lut) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto fail;
|
goto err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6656,7 +6660,7 @@ static int mdss_mdp_scaler_lut_init(struct mdss_data_type *mdata,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!qseed3_lut_tbl->cir_lut) {
|
if (!qseed3_lut_tbl->cir_lut) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto fail;
|
goto fail_free_dir_lut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6666,44 +6670,52 @@ static int mdss_mdp_scaler_lut_init(struct mdss_data_type *mdata,
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
if (!qseed3_lut_tbl->sep_lut) {
|
if (!qseed3_lut_tbl->sep_lut) {
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
goto fail;
|
goto fail_free_cir_lut;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Invalidate before updating */
|
/* Invalidate before updating */
|
||||||
qseed3_lut_tbl->valid = false;
|
qseed3_lut_tbl->valid = false;
|
||||||
|
|
||||||
|
|
||||||
if (copy_from_user(qseed3_lut_tbl->dir_lut,
|
if (copy_from_user(qseed3_lut_tbl->dir_lut,
|
||||||
(void *)(unsigned long)lut_tbl->dir_lut,
|
(void *)(unsigned long)lut_tbl->dir_lut,
|
||||||
lut_tbl->dir_lut_size)) {
|
lut_tbl->dir_lut_size)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err;
|
goto fail_free_sep_lut;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy_from_user(qseed3_lut_tbl->cir_lut,
|
if (copy_from_user(qseed3_lut_tbl->cir_lut,
|
||||||
(void *)(unsigned long)lut_tbl->cir_lut,
|
(void *)(unsigned long)lut_tbl->cir_lut,
|
||||||
lut_tbl->cir_lut_size)) {
|
lut_tbl->cir_lut_size)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err;
|
goto fail_free_sep_lut;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (copy_from_user(qseed3_lut_tbl->sep_lut,
|
if (copy_from_user(qseed3_lut_tbl->sep_lut,
|
||||||
(void *)(unsigned long)lut_tbl->sep_lut,
|
(void *)(unsigned long)lut_tbl->sep_lut,
|
||||||
lut_tbl->sep_lut_size)) {
|
lut_tbl->sep_lut_size)) {
|
||||||
ret = -EINVAL;
|
ret = -EINVAL;
|
||||||
goto err;
|
goto fail_free_sep_lut;
|
||||||
}
|
}
|
||||||
|
|
||||||
qseed3_lut_tbl->valid = true;
|
qseed3_lut_tbl->valid = true;
|
||||||
|
mutex_unlock(&mdata->scaler_off->scaler_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
fail:
|
fail_free_sep_lut:
|
||||||
kfree(qseed3_lut_tbl->dir_lut);
|
devm_kfree(&mdata->pdev->dev, qseed3_lut_tbl->sep_lut);
|
||||||
kfree(qseed3_lut_tbl->cir_lut);
|
fail_free_cir_lut:
|
||||||
kfree(qseed3_lut_tbl->sep_lut);
|
devm_kfree(&mdata->pdev->dev, qseed3_lut_tbl->cir_lut);
|
||||||
|
fail_free_dir_lut:
|
||||||
|
devm_kfree(&mdata->pdev->dev, qseed3_lut_tbl->dir_lut);
|
||||||
err:
|
err:
|
||||||
|
qseed3_lut_tbl->dir_lut = NULL;
|
||||||
|
qseed3_lut_tbl->cir_lut = NULL;
|
||||||
|
qseed3_lut_tbl->sep_lut = NULL;
|
||||||
qseed3_lut_tbl->valid = false;
|
qseed3_lut_tbl->valid = false;
|
||||||
|
mutex_unlock(&mdata->scaler_off->scaler_lock);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
|
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License version 2 and
|
* it under the terms of the GNU General Public License version 2 and
|
||||||
|
@ -1604,11 +1604,16 @@ int mdss_mdp_scaler_lut_cfg(struct mdp_scale_data_v2 *scaler,
|
||||||
};
|
};
|
||||||
|
|
||||||
mdata = mdss_mdp_get_mdata();
|
mdata = mdss_mdp_get_mdata();
|
||||||
|
|
||||||
|
mutex_lock(&mdata->scaler_off->scaler_lock);
|
||||||
|
|
||||||
lut_tbl = &mdata->scaler_off->lut_tbl;
|
lut_tbl = &mdata->scaler_off->lut_tbl;
|
||||||
if ((!lut_tbl) || (!lut_tbl->valid)) {
|
if ((!lut_tbl) || (!lut_tbl->valid)) {
|
||||||
|
mutex_unlock(&mdata->scaler_off->scaler_lock);
|
||||||
pr_err("%s:Invalid QSEED3 LUT TABLE\n", __func__);
|
pr_err("%s:Invalid QSEED3 LUT TABLE\n", __func__);
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((scaler->lut_flag & SCALER_LUT_DIR_WR) ||
|
if ((scaler->lut_flag & SCALER_LUT_DIR_WR) ||
|
||||||
(scaler->lut_flag & SCALER_LUT_Y_CIR_WR) ||
|
(scaler->lut_flag & SCALER_LUT_Y_CIR_WR) ||
|
||||||
(scaler->lut_flag & SCALER_LUT_UV_CIR_WR) ||
|
(scaler->lut_flag & SCALER_LUT_UV_CIR_WR) ||
|
||||||
|
@ -1656,6 +1661,8 @@ int mdss_mdp_scaler_lut_cfg(struct mdp_scale_data_v2 *scaler,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mutex_unlock(&mdata->scaler_off->scaler_lock);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue