Merge "disp: msm: sde: handle LTM switch in and out of dual pipe merge mode"

This commit is contained in:
qctecmdr 2021-03-18 02:20:38 -07:00 • committed by Gerrit - the friendly Code Review server
commit 6187bc9792
8 changed files with 82 additions and 8 deletions

View file

@ -1959,6 +1959,41 @@ static int sde_cp_crtc_set_pu_features(struct drm_crtc *crtc, bool *need_flush)
return 0;
}
static void _sde_clear_ltm_merge_mode(struct sde_crtc *sde_crtc)
{
u32 num_mixers = 0, i = 0;
struct sde_hw_ctl *ctl = NULL;
struct sde_hw_dspp *hw_dspp = NULL;
unsigned long irq_flags;
num_mixers = sde_crtc->num_mixers;
if (!num_mixers) {
DRM_ERROR("no mixers for this crtc\n");
return;
}
spin_lock_irqsave(&sde_crtc->ltm_lock, irq_flags);
if (!sde_crtc->ltm_merge_clear_pending) {
spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags);
return;
}
sde_cp_dspp_flush_helper(sde_crtc, SDE_CP_CRTC_DSPP_LTM_HIST_CTL);
for (i = 0; i < num_mixers; i++) {
hw_dspp = sde_crtc->mixers[i].hw_dspp;
ctl = sde_crtc->mixers[i].hw_ctl;
if (!hw_dspp || !ctl || i >= DSPP_MAX)
continue;
if (hw_dspp->ops.clear_ltm_merge_mode)
hw_dspp->ops.clear_ltm_merge_mode(hw_dspp);
if (ctl->ops.update_bitmask_dspp)
ctl->ops.update_bitmask_dspp(ctl, hw_dspp->idx, 1);
}
sde_crtc->ltm_merge_clear_pending = false;
spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags);
}
void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
{
struct sde_crtc *sde_crtc = NULL;
@ -1988,6 +2023,7 @@ void sde_cp_crtc_apply_properties(struct drm_crtc *crtc)
}
mutex_lock(&sde_crtc->crtc_cp_lock);
_sde_clear_ltm_merge_mode(sde_crtc);
if (list_empty(&sde_crtc->dirty_list) &&
list_empty(&sde_crtc->ad_dirty) &&
@ -2307,6 +2343,7 @@ void sde_cp_crtc_destroy_properties(struct drm_crtc *crtc)
}
sde_crtc->ltm_buffer_cnt = 0;
sde_crtc->ltm_hist_en = false;
sde_crtc->ltm_merge_clear_pending = false;
sde_crtc->hist_irq_idx = -1;
mutex_destroy(&sde_crtc->crtc_cp_lock);
@ -2352,6 +2389,7 @@ void sde_cp_crtc_suspend(struct drm_crtc *crtc)
spin_lock_irqsave(&sde_crtc->ltm_lock, irq_flags);
sde_crtc->ltm_hist_en = false;
sde_crtc->ltm_merge_clear_pending = false;
spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags);
if (ad_suspend)
@ -2402,6 +2440,7 @@ void sde_cp_crtc_clear(struct drm_crtc *crtc)
}
sde_crtc->ltm_buffer_cnt = 0;
sde_crtc->ltm_hist_en = false;
sde_crtc->ltm_merge_clear_pending = false;
sde_crtc->hist_irq_idx = -1;
INIT_LIST_HEAD(&sde_crtc->ltm_buf_free);
INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy);
@ -3791,6 +3830,7 @@ static void _sde_cp_crtc_disable_ltm_hist(struct sde_crtc *sde_crtc,
spin_lock_irqsave(&sde_crtc->ltm_lock, irq_flags);
sde_crtc->ltm_hist_en = false;
sde_crtc->ltm_merge_clear_pending = true;
INIT_LIST_HEAD(&sde_crtc->ltm_buf_free);
INIT_LIST_HEAD(&sde_crtc->ltm_buf_busy);
for (i = 0; i < sde_crtc->ltm_buffer_cnt; i++)
@ -3862,7 +3902,7 @@ static void sde_cp_ltm_hist_interrupt_cb(void *arg, int irq_idx)
hw_dspp->ops.setup_ltm_hist_ctrl(hw_dspp, NULL, false,
0);
}
sde_crtc->ltm_merge_clear_pending = true;
spin_unlock_irqrestore(&sde_crtc->ltm_lock, irq_flags);
DRM_DEBUG_DRIVER("LTM histogram is disabled\n");
return;

View file

@ -286,6 +286,7 @@ struct sde_crtc_misr_info {
* @ltm_buf_free : list of LTM buffers that are available
* @ltm_buf_busy : list of LTM buffers that are been used by HW
* @ltm_hist_en : flag to indicate whether LTM hist is enabled or not
* @ltm_merge_clear_pending : flag indicates merge mode bit needs to be cleared
* @ltm_buffer_lock : muttx to protect ltm_buffers allcation and free
* @ltm_lock : Spinlock to protect ltm buffer_cnt, hist_en and ltm lists
* @needs_hw_reset : Initiate a hw ctl reset
@ -376,6 +377,7 @@ struct sde_crtc {
struct list_head ltm_buf_free;
struct list_head ltm_buf_busy;
bool ltm_hist_en;
bool ltm_merge_clear_pending;
struct drm_msm_ltm_cfg_param ltm_cfg;
struct mutex ltm_buffer_lock;
spinlock_t ltm_lock;

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2019,2021, The Linux Foundation. All rights reserved.
*/
#ifndef _SDE_HW_COLOR_PROC_COMMON_V4_H_
#define _SDE_HW_COLOR_PROC_COMMON_V4_H_
@ -121,6 +121,8 @@ enum {
#define SSPP 0
#define DSPP 1
#define LTM_CONFIG_MERGE_MODE_ONLY (BIT(16) | BIT(17))
struct sde_ltm_phase_info {
u32 init_h[LTM_MAX];
u32 init_v;

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#include <drm/msm_drm_pp.h>
#include "sde_hw_color_proc_common_v4.h"
@ -339,7 +339,7 @@ void sde_setup_dspp_ltm_hist_ctrlv1(struct sde_hw_dspp *ctx, void *cfg,
if (op_mode & BIT(1))
op_mode &= ~BIT(0);
else
op_mode = 0;
op_mode &= LTM_CONFIG_MERGE_MODE_ONLY;
SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->ltm.base + 0x4,
(op_mode & 0x1FFFFFF));
@ -398,6 +398,21 @@ void sde_ltm_read_intr_status(struct sde_hw_dspp *ctx, u32 *status)
SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->ltm.base + 0x58, clear);
}
void sde_ltm_clear_merge_mode(struct sde_hw_dspp *ctx)
{
u32 clear;
if (!ctx) {
DRM_ERROR("invalid parameters ctx %pK\n", ctx);
return;
}
/* clear the merge_mode bit */
clear = SDE_REG_READ(&ctx->hw, ctx->cap->sblk->ltm.base + 0x04);
clear &= ~LTM_CONFIG_MERGE_MODE_ONLY;
SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->ltm.base + 0x04, clear);
}
void sde_demura_backlight_cfg(struct sde_hw_dspp *dspp, u64 val)
{
u32 demura_base;

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _SDE_HW_COLOR_PROC_V4_H_
#define _SDE_HW_COLOR_PROC_V4_H_
@ -70,6 +70,13 @@ void sde_setup_dspp_ltm_hist_bufferv1(struct sde_hw_dspp *ctx, u64 addr);
*/
void sde_ltm_read_intr_status(struct sde_hw_dspp *dspp, u32 *status);
/**
* sde_ltm_clear_merge_mode - api to clear ltm merge_mode
* @dspp: pointer to dspp object
*/
void sde_ltm_clear_merge_mode(struct sde_hw_dspp *dspp);
/**
* sde_demura_backlight_cfg - api to set backlight for demura
* @dspp: pointer to dspp object

View file

@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
*/
#include <drm/msm_drm_pp.h>
@ -245,6 +245,7 @@ static void dspp_ltm(struct sde_hw_dspp *c)
c->ops.setup_ltm_hist_buffer =
sde_setup_dspp_ltm_hist_bufferv1;
c->ops.ltm_read_intr_status = sde_ltm_read_intr_status;
c->ops.clear_ltm_merge_mode = sde_ltm_clear_merge_mode;
} else {
c->ops.setup_ltm_init = NULL;
c->ops.setup_ltm_roi = NULL;
@ -253,6 +254,7 @@ static void dspp_ltm(struct sde_hw_dspp *c)
c->ops.setup_ltm_hist_ctrl = NULL;
c->ops.setup_ltm_hist_buffer = NULL;
c->ops.ltm_read_intr_status = NULL;
c->ops.clear_ltm_merge_mode = NULL;
}
if (!ret && c->cap->sblk->ltm.version ==
SDE_COLOR_PROCESS_VER(0x1, 0x1))

View file

@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2015-2020, The Linux Foundation. All rights reserved.
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _SDE_HW_DSPP_H
@ -210,6 +210,12 @@ struct sde_hw_dspp_ops {
*/
void (*ltm_read_intr_status)(struct sde_hw_dspp *ctx, u32 *status);
/**
* clear_ltm_merge_mode - clear LTM merge_mode bit
* @ctx: Pointer to dspp context
*/
void (*clear_ltm_merge_mode)(struct sde_hw_dspp *ctx);
/**
* validate_rc_mask - Validate RC mask configuration
* @ctx: Pointer to dspp context.

View file

@ -3805,7 +3805,7 @@ static void ltm_vlutv1_disable(struct sde_hw_dspp *ctx)
/* disable VLUT/INIT/ROI */
opmode &= REG_DMA_LTM_VLUT_DISABLE_OP_MASK;
else
opmode = 0;
opmode &= LTM_CONFIG_MERGE_MODE_ONLY;
SDE_REG_WRITE(&ctx->hw, offset, opmode);
}