summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/drm_modes.c43
-rw-r--r--drivers/gpu/drm/msm/sde/sde_hw_sspp.c28
-rw-r--r--drivers/soc/qcom/qdsp6v2/voice_svc.c40
3 files changed, 94 insertions, 17 deletions
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c
index 71a10f08522e..c2f23a344b62 100644
--- a/drivers/gpu/drm/drm_modes.c
+++ b/drivers/gpu/drm/drm_modes.c
@@ -949,6 +949,7 @@ bool drm_mode_equal_no_clocks_no_stereo(const struct drm_display_mode *mode1,
mode1->vsync_end == mode2->vsync_end &&
mode1->vtotal == mode2->vtotal &&
mode1->vscan == mode2->vscan &&
+ mode1->picture_aspect_ratio == mode2->picture_aspect_ratio &&
(mode1->flags & ~DRM_MODE_FLAG_3D_MASK) ==
(mode2->flags & ~DRM_MODE_FLAG_3D_MASK))
return true;
@@ -1445,6 +1446,27 @@ void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
out->vrefresh = in->vrefresh;
out->flags = in->flags;
out->type = in->type;
+ out->flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
+
+ switch (in->picture_aspect_ratio) {
+ case HDMI_PICTURE_ASPECT_4_3:
+ out->flags |= DRM_MODE_FLAG_PIC_AR_4_3;
+ break;
+ case HDMI_PICTURE_ASPECT_16_9:
+ out->flags |= DRM_MODE_FLAG_PIC_AR_16_9;
+ break;
+ case HDMI_PICTURE_ASPECT_64_27:
+ out->flags |= DRM_MODE_FLAG_PIC_AR_64_27;
+ break;
+ case DRM_MODE_PICTURE_ASPECT_256_135:
+ out->flags |= DRM_MODE_FLAG_PIC_AR_256_135;
+ break;
+ case HDMI_PICTURE_ASPECT_RESERVED:
+ default:
+ out->flags |= DRM_MODE_FLAG_PIC_AR_NONE;
+ break;
+ }
+
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
}
@@ -1490,6 +1512,27 @@ int drm_mode_convert_umode(struct drm_display_mode *out,
strncpy(out->name, in->name, DRM_DISPLAY_MODE_LEN);
out->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+ /* Clearing picture aspect ratio bits from out flags */
+ out->flags &= ~DRM_MODE_FLAG_PIC_AR_MASK;
+
+ switch (in->flags & DRM_MODE_FLAG_PIC_AR_MASK) {
+ case DRM_MODE_FLAG_PIC_AR_4_3:
+ out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_4_3;
+ break;
+ case DRM_MODE_FLAG_PIC_AR_16_9:
+ out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_16_9;
+ break;
+ case DRM_MODE_FLAG_PIC_AR_64_27:
+ out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_64_27;
+ break;
+ case DRM_MODE_FLAG_PIC_AR_256_135:
+ out->picture_aspect_ratio |= HDMI_PICTURE_ASPECT_256_135;
+ break;
+ default:
+ out->picture_aspect_ratio = HDMI_PICTURE_ASPECT_NONE;
+ break;
+ }
+
out->status = drm_mode_validate_basic(out);
if (out->status != MODE_OK)
goto out;
diff --git a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
index be620aebf850..f5b433c61776 100644
--- a/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
+++ b/drivers/gpu/drm/msm/sde/sde_hw_sspp.c
@@ -595,10 +595,8 @@ static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx,
|| !scaler3_cfg || !ctx || !ctx->cap || !ctx->cap->sblk)
return;
- if (!scaler3_cfg->enable) {
- SDE_REG_WRITE(&ctx->hw, QSEED3_OP_MODE + idx, 0x0);
- return;
- }
+ if (!scaler3_cfg->enable)
+ goto end;
op_mode |= BIT(0);
op_mode |= (scaler3_cfg->y_rgb_filter_cfg & 0x3) << 16;
@@ -608,9 +606,6 @@ static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx,
op_mode |= (scaler3_cfg->uv_filter_cfg & 0x3) << 24;
}
- if (!SDE_FORMAT_IS_DX(sspp->layout.format))
- op_mode |= BIT(14);
-
op_mode |= (scaler3_cfg->blend_cfg & 1) << 31;
op_mode |= (scaler3_cfg->dir_en) ? BIT(4) : 0;
@@ -638,10 +633,6 @@ static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx,
_sde_hw_sspp_setup_scaler3_lut(ctx, scaler3_cfg);
if (ctx->cap->sblk->scaler_blk.version == 0x1002) {
- if (sspp->layout.format->alpha_enable) {
- op_mode |= BIT(10);
- op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x1) << 30;
- }
phase_init =
((scaler3_cfg->init_phase_x[0] & 0x3F) << 0) |
((scaler3_cfg->init_phase_y[0] & 0x3F) << 8) |
@@ -649,10 +640,6 @@ static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx,
((scaler3_cfg->init_phase_y[1] & 0x3F) << 24);
SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT + idx, phase_init);
} else {
- if (sspp->layout.format->alpha_enable) {
- op_mode |= BIT(10);
- op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x3) << 29;
- }
SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_Y_H + idx,
scaler3_cfg->init_phase_x[0] & 0x1FFFFF);
SDE_REG_WRITE(&ctx->hw, QSEED3_PHASE_INIT_Y_V + idx,
@@ -683,6 +670,17 @@ static void _sde_hw_sspp_setup_scaler3(struct sde_hw_pipe *ctx,
SDE_REG_WRITE(&ctx->hw, QSEED3_DST_SIZE + idx, dst);
+end:
+ if (!SDE_FORMAT_IS_DX(sspp->layout.format))
+ op_mode |= BIT(14);
+
+ if (sspp->layout.format->alpha_enable) {
+ op_mode |= BIT(10);
+ if (ctx->cap->sblk->scaler_blk.version == 0x1002)
+ op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x1) << 30;
+ else
+ op_mode |= (scaler3_cfg->alpha_filter_cfg & 0x3) << 29;
+ }
SDE_REG_WRITE(&ctx->hw, QSEED3_OP_MODE + idx, op_mode);
}
diff --git a/drivers/soc/qcom/qdsp6v2/voice_svc.c b/drivers/soc/qcom/qdsp6v2/voice_svc.c
index fe5458974406..c560ec7d7401 100644
--- a/drivers/soc/qcom/qdsp6v2/voice_svc.c
+++ b/drivers/soc/qcom/qdsp6v2/voice_svc.c
@@ -14,6 +14,7 @@
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/errno.h>
+#include <linux/spinlock.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/slab.h>
@@ -67,7 +68,11 @@ static void *dummy_q6_mvm;
static void *dummy_q6_cvs;
dev_t device_num;
+static spinlock_t voicesvc_lock;
+static bool is_released;
static int voice_svc_dummy_reg(void);
+static int voice_svc_dummy_dereg(void);
+
static int32_t qdsp_dummy_apr_callback(struct apr_client_data *data,
void *priv);
@@ -82,10 +87,16 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv)
return -EINVAL;
}
+ spin_lock(&voicesvc_lock);
+ if (is_released) {
+ spin_unlock(&voicesvc_lock);
+ return 0;
+ }
prtd = (struct voice_svc_prvt *)priv;
if (prtd == NULL) {
pr_err("%s: private data is NULL\n", __func__);
+ spin_unlock(&voicesvc_lock);
return -EINVAL;
}
@@ -128,6 +139,7 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv)
spin_unlock_irqrestore(&prtd->response_lock,
spin_flags);
+ spin_unlock(&voicesvc_lock);
return -ENOMEM;
}
@@ -156,6 +168,7 @@ static int32_t qdsp_apr_callback(struct apr_client_data *data, void *priv)
__func__);
}
+ spin_unlock(&voicesvc_lock);
return 0;
}
@@ -614,6 +627,21 @@ err:
return -EINVAL;
}
+static int voice_svc_dummy_dereg(void)
+{
+ pr_debug("%s\n", __func__);
+ if (dummy_q6_mvm != NULL) {
+ apr_deregister(dummy_q6_mvm);
+ dummy_q6_mvm = NULL;
+ }
+
+ if (dummy_q6_cvs != NULL) {
+ apr_deregister(dummy_q6_cvs);
+ dummy_q6_cvs = NULL;
+ }
+ return 0;
+}
+
static int voice_svc_open(struct inode *inode, struct file *file)
{
struct voice_svc_prvt *prtd = NULL;
@@ -637,6 +665,7 @@ static int voice_svc_open(struct inode *inode, struct file *file)
mutex_init(&prtd->response_mutex_lock);
file->private_data = (void *)prtd;
+ is_released = 0;
/* Current APR implementation doesn't support session based
* multiple service registrations. The apr_deregister()
* function sets the destination and client IDs to zero, if
@@ -669,6 +698,11 @@ static int voice_svc_release(struct inode *inode, struct file *file)
goto done;
}
+ mutex_lock(&prtd->response_mutex_lock);
+ if (reg_dummy_sess) {
+ voice_svc_dummy_dereg();
+ reg_dummy_sess = 0;
+ }
if (prtd->apr_q6_cvs != NULL) {
svc_name = VOICE_SVC_MVM_STR;
handle = &prtd->apr_q6_cvs;
@@ -685,7 +719,6 @@ static int voice_svc_release(struct inode *inode, struct file *file)
pr_err("%s: Failed to dereg MVM %d\n", __func__, ret);
}
- mutex_lock(&prtd->response_mutex_lock);
spin_lock_irqsave(&prtd->response_lock, spin_flags);
while (!list_empty(&prtd->response_queue)) {
@@ -703,9 +736,11 @@ static int voice_svc_release(struct inode *inode, struct file *file)
mutex_destroy(&prtd->response_mutex_lock);
+ spin_lock(&voicesvc_lock);
kfree(file->private_data);
file->private_data = NULL;
-
+ is_released = 1;
+ spin_unlock(&voicesvc_lock);
done:
return ret;
}
@@ -774,6 +809,7 @@ static int voice_svc_probe(struct platform_device *pdev)
goto add_err;
}
pr_debug("%s: Device created\n", __func__);
+ spin_lock_init(&voicesvc_lock);
goto done;
add_err: