disp: msm: sde: read demura plane status registers on cont-splash boot

Extrapolate the Demura plane configuration from the Demura DSPP block
on cont-splash boot, and pass this information to DRM clients via a
CRTC property. This will allow user-space to be aware of all plane
reservations, and avoid plane mangling in multi display use-cases.

Change-Id: I6d216f555fcddbd19c18b6209dc830c21f6be5a4
Signed-off-by: Christopher Braga <cbraga@codeaurora.org>
This commit is contained in:
Christopher Braga
2020-06-05 16:49:47 -04:00
committed by Gopikrishnaiah Anandan
parent c8f9e73f0e
commit dc1af2c9d5
8 changed files with 176 additions and 12 deletions

View File

@@ -1291,6 +1291,47 @@ static void _sde_cp_crtc_install_immutable_property(struct drm_crtc *crtc,
feature, val); feature, val);
_sde_cp_crtc_attach_property(&prop_attach); _sde_cp_crtc_attach_property(&prop_attach);
} }
static void _sde_cp_crtc_install_bitmask_property(struct drm_crtc *crtc,
char *name, u32 feature, bool immutable,
const struct drm_prop_enum_list *list, u32 enum_sz,
u64 supported_bits)
{
struct drm_property *prop;
struct sde_cp_node *prop_node = NULL;
struct msm_drm_private *priv;
struct sde_cp_prop_attach prop_attach;
int flags = immutable ? DRM_MODE_PROP_IMMUTABLE : 0;
uint64_t val = 0;
if (feature >= SDE_CP_CRTC_MAX_FEATURES) {
DRM_ERROR("invalid feature %d max %d\n", feature,
SDE_CP_CRTC_MAX_FEATURES);
return;
}
prop_node = kzalloc(sizeof(*prop_node), GFP_KERNEL);
if (!prop_node)
return;
priv = crtc->dev->dev_private;
prop = priv->cp_property[feature];
if (!prop) {
prop = drm_property_create_bitmask(crtc->dev, flags, name, list,
enum_sz, supported_bits);
if (!prop) {
DRM_ERROR("property create failed: %s\n", name);
kfree(prop_node);
return;
}
priv->cp_property[feature] = prop;
}
INIT_PROP_ATTACH(&prop_attach, crtc, prop, prop_node, feature, val);
_sde_cp_crtc_attach_property(&prop_attach);
}
static void _sde_cp_crtc_install_range_property(struct drm_crtc *crtc, static void _sde_cp_crtc_install_range_property(struct drm_crtc *crtc,
char *name, char *name,
u32 feature, u32 feature,
@@ -2184,6 +2225,44 @@ static int _sde_cp_crtc_set_range_prop(
return ret; return ret;
} }
void sde_cp_crtc_refresh_status_properties(struct drm_crtc *crtc)
{
struct sde_crtc *sde_crtc = NULL;
int i = 0;
struct sde_hw_dspp *hw_dspp = NULL;
struct msm_drm_private *priv;
struct drm_property *prop;
u64 val = 0;
if (!crtc) {
DRM_ERROR("invalid crtc %pKn", crtc);
return;
}
sde_crtc = to_sde_crtc(crtc);
if (!sde_crtc) {
DRM_ERROR("invalid sde_crtc %pK\n", sde_crtc);
return;
}
priv = crtc->dev->dev_private;
prop = priv->cp_property[SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE];
if (!prop)
return;
for (i = 0; i < sde_crtc->num_mixers; i++) {
u32 status = 0;
hw_dspp = sde_crtc->mixers[i].hw_dspp;
if (hw_dspp && hw_dspp->ops.demura_read_plane_status) {
hw_dspp->ops.demura_read_plane_status(hw_dspp, &status);
if (status != DEM_FETCH_DMA_INVALID)
val |= 1 << status;
}
}
drm_object_property_set_value(&crtc->base, prop, val);
}
int sde_cp_crtc_set_property(struct drm_crtc *crtc, int sde_cp_crtc_set_property(struct drm_crtc *crtc,
struct drm_crtc_state *state, struct drm_crtc_state *state,
struct drm_property *property, struct drm_property *property,
@@ -3029,6 +3108,10 @@ static void _dspp_demura_install_property(struct drm_crtc *crtc)
_sde_cp_crtc_install_range_property(crtc, "SDE_DEMURA_BACKLIGHT_V1", _sde_cp_crtc_install_range_property(crtc, "SDE_DEMURA_BACKLIGHT_V1",
SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT, SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT,
0, 1024, 0); 0, 1024, 0);
_sde_cp_crtc_install_bitmask_property(crtc, "SDE_DEMURA_BOOT_PLANE_V1",
SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE, true,
sde_demura_fetch_planes,
ARRAY_SIZE(sde_demura_fetch_planes), 0xf);
break; break;
default: default:
DRM_ERROR("version %d not supported\n", version); DRM_ERROR("version %d not supported\n", version);

View File

@@ -104,6 +104,7 @@ enum sde_cp_crtc_features {
SDE_CP_CRTC_DSPP_SPR_INIT, SDE_CP_CRTC_DSPP_SPR_INIT,
SDE_CP_CRTC_DSPP_DEMURA_INIT, SDE_CP_CRTC_DSPP_DEMURA_INIT,
SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT, SDE_CP_CRTC_DSPP_DEMURA_BACKLIGHT,
SDE_CP_CRTC_DSPP_DEMURA_BOOT_PLANE,
SDE_CP_CRTC_DSPP_MAX, SDE_CP_CRTC_DSPP_MAX,
/* DSPP features end */ /* DSPP features end */
@@ -161,6 +162,14 @@ void sde_cp_crtc_install_properties(struct drm_crtc *crtc);
*/ */
void sde_cp_crtc_destroy_properties(struct drm_crtc *crtc); void sde_cp_crtc_destroy_properties(struct drm_crtc *crtc);
/**
* sde_cp_crtc_refresh_status_properties(): Updates color processing
* properties reflecting the status
* of the crtc.
* @crtc: Pointer to crtc.
*/
void sde_cp_crtc_refresh_status_properties(struct drm_crtc *crtc);
/** /**
* sde_cp_crtc_set_property: Set a color processing property * sde_cp_crtc_set_property: Set a color processing property
* for a crtc. * for a crtc.

View File

@@ -7228,6 +7228,7 @@ void sde_crtc_update_cont_splash_settings(struct drm_crtc *crtc)
} }
_sde_crtc_setup_mixers(crtc); _sde_crtc_setup_mixers(crtc);
sde_cp_crtc_refresh_status_properties(crtc);
crtc->enabled = true; crtc->enabled = true;
/* update core clk value for initial state with cont-splash */ /* update core clk value for initial state with cont-splash */

View File

@@ -1,12 +1,39 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* 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_ #ifndef _SDE_HW_COLOR_PROC_COMMON_V4_H_
#define _SDE_HW_COLOR_PROC_COMMON_V4_H_ #define _SDE_HW_COLOR_PROC_COMMON_V4_H_
#include "sde_hw_mdss.h" #include "sde_hw_mdss.h"
/*
* DEMURA fetch planes
* @DEM_FETCH_DMA1_RECT0 Demura data fetched from DMA plane 1 rectangle 0
* @DEM_FETCH_DMA1_RECT1 Demura data fetched from DMA plane 1 rectangle 1
* @DEM_FETCH_DMA3_RECT0 Demura data fetched from DMA plane 3 rectangle 0
* @DEM_FETCH_DMA3_RECT1 Demura data fetched from DMA plane 3 rectangle 1
* @DEM_FETCH_DMA_INVALID Invalid DMA plane for fetching Demmura data
*/
enum demura_fetch_planes {
DEM_FETCH_DMA1_RECT0 = 0,
DEM_FETCH_DMA1_RECT1,
DEM_FETCH_DMA3_RECT0,
DEM_FETCH_DMA3_RECT1,
DEM_FETCH_DMA_INVALID,
};
/**
* struct sde_demura_fetch_planes - drm prop enun struct containing bit
* mask enum properties and values
*/
static const struct drm_prop_enum_list sde_demura_fetch_planes[] = {
{DEM_FETCH_DMA1_RECT0, "demura_dma1_rect0"},
{DEM_FETCH_DMA1_RECT1, "demura_dma1_rect1"},
{DEM_FETCH_DMA3_RECT0, "demura_dma3_rect0"},
{DEM_FETCH_DMA3_RECT1, "demura_dma3_rect1"},
};
#define GAMUT_TABLE_SEL_OFF 0x4 #define GAMUT_TABLE_SEL_OFF 0x4
#define GAMUT_UPPER_COLOR_OFF 0x8 #define GAMUT_UPPER_COLOR_OFF 0x8
#define GAMUT_LOWER_COLOR_OFF 0xc #define GAMUT_LOWER_COLOR_OFF 0xc

View File

@@ -398,19 +398,20 @@ 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); SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->ltm.base + 0x58, clear);
} }
void sde_demura_backlight_cfg(struct sde_hw_dspp *dspp, u64 val) void sde_demura_backlight_cfg(struct sde_hw_dspp *ctx, u64 val)
{ {
u32 demura_base; u32 demura_base;
u32 backlight; u32 backlight;
if (!dspp) { if (!ctx) {
DRM_ERROR("invalid parameter ctx %pK", dspp); DRM_ERROR("invalid parameter ctx %pK", ctx);
return; return;
} }
demura_base = dspp->cap->sblk->demura.base;
demura_base = ctx->cap->sblk->demura.base;
backlight = (val & REG_MASK(11)); backlight = (val & REG_MASK(11));
backlight |= ((val & REG_MASK_SHIFT(11, 32)) >> 16); backlight |= ((val & REG_MASK_SHIFT(11, 32)) >> 16);
SDE_REG_WRITE(&dspp->hw, dspp->cap->sblk->demura.base + 0x8, SDE_REG_WRITE(&ctx->hw, ctx->cap->sblk->demura.base + 0x8,
backlight); backlight);
} }
@@ -608,3 +609,30 @@ void sde_setup_fp16_unmultv1(struct sde_hw_pipe *ctx,
SDE_REG_WRITE(&ctx->hw, unmult_base, unmult); SDE_REG_WRITE(&ctx->hw, unmult_base, unmult);
} }
void sde_demura_read_plane_status(struct sde_hw_dspp *ctx, u32 *status)
{
u32 demura_base;
u32 value;
if (!ctx) {
DRM_ERROR("invalid parameter ctx %pK", ctx);
return;
}
demura_base = ctx->cap->sblk->demura.base;
value = SDE_REG_READ(&ctx->hw, demura_base + 0x4);
if (!(value & 0x4)) {
*status = DEM_FETCH_DMA_INVALID;
} else if (ctx->idx == DSPP_0) {
if (value & 0x80000000)
*status = DEM_FETCH_DMA1_RECT0;
else
*status = DEM_FETCH_DMA3_RECT0;
} else {
if (value & 0x80000000)
*status = DEM_FETCH_DMA1_RECT1;
else
*status = DEM_FETCH_DMA3_RECT1;
}
}

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* SPDX-License-Identifier: GPL-2.0-only */
/* /*
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2017-2019, 2021 The Linux Foundation. All rights reserved.
*/ */
#ifndef _SDE_HW_COLOR_PROC_V4_H_ #ifndef _SDE_HW_COLOR_PROC_V4_H_
#define _SDE_HW_COLOR_PROC_V4_H_ #define _SDE_HW_COLOR_PROC_V4_H_
@@ -74,10 +74,17 @@ void sde_ltm_read_intr_status(struct sde_hw_dspp *dspp, u32 *status);
/** /**
* sde_demura_backlight_cfg - api to set backlight for demura * sde_demura_backlight_cfg - api to set backlight for demura
* @dspp: pointer to dspp object * @ctx: pointer to dspp object
* @val: value of backlight * @val: value of backlight
*/ */
void sde_demura_backlight_cfg(struct sde_hw_dspp *dspp, u64 val); void sde_demura_backlight_cfg(struct sde_hw_dspp *ctx, u64 val);
/**
* sde_demura_read_plane_status - api to read demura plane fetch setup.
* @ctx: pointer to dspp object.
* @status: Currently present plane. Reported as a demura_fetch_planes value.
*/
void sde_demura_read_plane_status(struct sde_hw_dspp *ctx, u32 *status);
/** /**
* sde_setup_fp16_cscv1 - api to set FP16 CSC cp block * sde_setup_fp16_cscv1 - api to set FP16 CSC cp block

View File

@@ -1,6 +1,6 @@
// SPDX-License-Identifier: GPL-2.0-only // 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> #include <drm/msm_drm_pp.h>
@@ -328,7 +328,9 @@ static void dspp_demura(struct sde_hw_dspp *c)
if (!ret) { if (!ret) {
c->ops.setup_demura_cfg = reg_dmav1_setup_demurav1; c->ops.setup_demura_cfg = reg_dmav1_setup_demurav1;
c->ops.setup_demura_backlight_cfg = c->ops.setup_demura_backlight_cfg =
sde_demura_backlight_cfg; sde_demura_backlight_cfg;
c->ops.demura_read_plane_status =
sde_demura_read_plane_status;
} }
} }
} }

View File

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */ /* 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 #ifndef _SDE_HW_DSPP_H
@@ -276,6 +276,13 @@ struct sde_hw_dspp_ops {
* @status: Pointer to configuration. * @status: Pointer to configuration.
*/ */
void (*setup_demura_backlight_cfg)(struct sde_hw_dspp *ctx, u64 val); void (*setup_demura_backlight_cfg)(struct sde_hw_dspp *ctx, u64 val);
/**
* demura_read_plane_status - Query demura plane status
* @ctx: Pointer to dspp context
* @status: Demura plane used by DSPP. demura_fetch_planes enum value.
*/
void (*demura_read_plane_status)(struct sde_hw_dspp *ctx, u32 *status);
}; };
/** /**