disp: msm: sde: add multirect error status for ubwc and meta

This change adds support for error checking ubwc and meta error status
based off whether REC0 or RECT1 is used.

Change-Id: I7c39755da99a9d6c0d02b4ef16fa93b8ec7458a9
Signed-off-by: Samantha Tran <samtran@codeaurora.org>
This commit is contained in:
Samantha Tran
2021-02-08 21:33:40 -08:00
父節點 23734fc295
當前提交 73373271a7
共有 7 個文件被更改,包括 163 次插入18 次删除

查看文件

@@ -2279,7 +2279,7 @@ static void sde_crtc_frame_event_cb(void *data, u32 event)
struct sde_crtc_frame_event *fevent; struct sde_crtc_frame_event *fevent;
struct sde_kms_frame_event_cb_data *cb_data; struct sde_kms_frame_event_cb_data *cb_data;
struct drm_plane *plane; struct drm_plane *plane;
u32 ubwc_error; u32 ubwc_error, meta_error;
unsigned long flags; unsigned long flags;
u32 crtc_id; u32 crtc_id;
@@ -2322,13 +2322,14 @@ static void sde_crtc_frame_event_cb(void *data, u32 event)
drm_for_each_plane_mask(plane, crtc->dev, drm_for_each_plane_mask(plane, crtc->dev,
sde_crtc->plane_mask_old) { sde_crtc->plane_mask_old) {
ubwc_error = sde_plane_get_ubwc_error(plane); ubwc_error = sde_plane_get_ubwc_error(plane);
if (ubwc_error) { meta_error = sde_plane_get_meta_error(plane);
SDE_EVT32(DRMID(crtc), DRMID(plane), if (ubwc_error | meta_error) {
ubwc_error, SDE_EVTLOG_ERROR); SDE_EVT32(DRMID(crtc), DRMID(plane), ubwc_error,
SDE_DEBUG("crtc%d plane %d ubwc_error %d\n", meta_error, SDE_EVTLOG_ERROR);
DRMID(crtc), DRMID(plane), SDE_DEBUG("crtc%d plane %d ubwc_error %d meta_error %d\n",
ubwc_error); DRMID(crtc), DRMID(plane), ubwc_error, meta_error);
sde_plane_clear_ubwc_error(plane); sde_plane_clear_ubwc_error(plane);
sde_plane_clear_meta_error(plane);
} }
} }
} }

查看文件

@@ -1744,6 +1744,9 @@ static void sde_sspp_set_features(struct sde_mdss_cfg *sde_cfg,
if (sde_cfg->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache) if (sde_cfg->sc_cfg[SDE_SYS_CACHE_DISP].has_sys_cache)
set_bit(SDE_PERF_SSPP_SYS_CACHE, &sspp->perf_features); set_bit(SDE_PERF_SSPP_SYS_CACHE, &sspp->perf_features);
if (sde_cfg->sspp_multirect_error)
set_bit(SDE_SSPP_MULTIRECT_ERROR, &sspp->features);
if (sde_cfg->has_decimation) { if (sde_cfg->has_decimation) {
sblk->maxhdeciexp = MAX_HORZ_DECIMATION; sblk->maxhdeciexp = MAX_HORZ_DECIMATION;
sblk->maxvdeciexp = MAX_VERT_DECIMATION; sblk->maxvdeciexp = MAX_VERT_DECIMATION;
@@ -4827,6 +4830,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev)
sde_cfg->dither_luma_mode_support = true; sde_cfg->dither_luma_mode_support = true;
sde_cfg->mdss_hw_block_size = 0x158; sde_cfg->mdss_hw_block_size = 0x158;
sde_cfg->syscache_supported = true; sde_cfg->syscache_supported = true;
sde_cfg->sspp_multirect_error = true;
} else { } else {
SDE_ERROR("unsupported chipset id:%X\n", hw_rev); SDE_ERROR("unsupported chipset id:%X\n", hw_rev);
sde_cfg->perf.min_prefill_lines = 0xffff; sde_cfg->perf.min_prefill_lines = 0xffff;

查看文件

@@ -252,6 +252,7 @@ enum {
* @SDE_SSPP_BLOCK_SEC_UI Blocks secure-ui layers * @SDE_SSPP_BLOCK_SEC_UI Blocks secure-ui layers
* @SDE_SSPP_SCALER_QSEED3LITE Qseed3lite algorithm support * @SDE_SSPP_SCALER_QSEED3LITE Qseed3lite algorithm support
* @SDE_SSPP_TRUE_INLINE_ROT Support of SSPP true inline rotation v1 * @SDE_SSPP_TRUE_INLINE_ROT Support of SSPP true inline rotation v1
* @SDE_SSPP_MULTIRECT_ERROR SSPP has error based on RECT0 or RECT1
* @SDE_SSPP_PREDOWNSCALE Support pre-downscale X-direction by 2 for inline * @SDE_SSPP_PREDOWNSCALE Support pre-downscale X-direction by 2 for inline
* @SDE_SSPP_PREDOWNSCALE_Y Support pre-downscale Y-direction for inline * @SDE_SSPP_PREDOWNSCALE_Y Support pre-downscale Y-direction for inline
* @SDE_SSPP_INLINE_CONST_CLR Inline rotation requires const clr disabled * @SDE_SSPP_INLINE_CONST_CLR Inline rotation requires const clr disabled
@@ -283,6 +284,7 @@ enum {
SDE_SSPP_BLOCK_SEC_UI, SDE_SSPP_BLOCK_SEC_UI,
SDE_SSPP_SCALER_QSEED3LITE, SDE_SSPP_SCALER_QSEED3LITE,
SDE_SSPP_TRUE_INLINE_ROT, SDE_SSPP_TRUE_INLINE_ROT,
SDE_SSPP_MULTIRECT_ERROR,
SDE_SSPP_PREDOWNSCALE, SDE_SSPP_PREDOWNSCALE,
SDE_SSPP_PREDOWNSCALE_Y, SDE_SSPP_PREDOWNSCALE_Y,
SDE_SSPP_INLINE_CONST_CLR, SDE_SSPP_INLINE_CONST_CLR,
@@ -1416,6 +1418,7 @@ struct sde_perf_cfg {
* @true_inline_rot_rev inline rotator feature revision * @true_inline_rot_rev inline rotator feature revision
* @macrotile_mode UBWC parameter for macro tile channel distribution * @macrotile_mode UBWC parameter for macro tile channel distribution
* @pipe_order_type indicate if it is required to specify pipe order * @pipe_order_type indicate if it is required to specify pipe order
* @sspp_multirect_error flag to indicate whether ubwc and meta error by rect is supported
* @delay_prg_fetch_start indicates if throttling the fetch start is required * @delay_prg_fetch_start indicates if throttling the fetch start is required
* @has_qsync Supports qsync feature * @has_qsync Supports qsync feature
* @has_3d_merge_reset Supports 3D merge reset * @has_3d_merge_reset Supports 3D merge reset
@@ -1489,6 +1492,7 @@ struct sde_mdss_cfg {
u32 true_inline_rot_rev; u32 true_inline_rot_rev;
u32 macrotile_mode; u32 macrotile_mode;
u32 pipe_order_type; u32 pipe_order_type;
bool sspp_multirect_error;
bool delay_prg_fetch_start; bool delay_prg_fetch_start;
bool has_qsync; bool has_qsync;
bool has_3d_merge_reset; bool has_3d_merge_reset;

查看文件

@@ -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 "sde_hwio.h" #include "sde_hwio.h"
@@ -86,6 +86,7 @@
#define SSPP_SW_PIX_EXT_C3_LR 0x120 #define SSPP_SW_PIX_EXT_C3_LR 0x120
#define SSPP_SW_PIX_EXT_C3_TB 0x124 #define SSPP_SW_PIX_EXT_C3_TB 0x124
#define SSPP_SW_PIX_EXT_C3_REQ_PIXELS 0x128 #define SSPP_SW_PIX_EXT_C3_REQ_PIXELS 0x128
#define SSPP_META_ERROR_STATUS 0X12C
#define SSPP_TRAFFIC_SHAPER 0x130 #define SSPP_TRAFFIC_SHAPER 0x130
#define SSPP_CDP_CNTL 0x134 #define SSPP_CDP_CNTL 0x134
#define SSPP_UBWC_ERROR_STATUS 0x138 #define SSPP_UBWC_ERROR_STATUS 0x138
@@ -95,6 +96,8 @@
#define SSPP_TRAFFIC_SHAPER_REC1 0x158 #define SSPP_TRAFFIC_SHAPER_REC1 0x158
#define SSPP_EXCL_REC_SIZE 0x1B4 #define SSPP_EXCL_REC_SIZE 0x1B4
#define SSPP_EXCL_REC_XY 0x1B8 #define SSPP_EXCL_REC_XY 0x1B8
#define SSPP_META_ERROR_STATUS_REC1 0x1C4
#define SSPP_UBWC_ERROR_STATUS_REC1 0x1C8
#define SSPP_VIG_OP_MODE 0x0 #define SSPP_VIG_OP_MODE 0x0
#define SSPP_VIG_CSC_10_OP_MODE 0x0 #define SSPP_VIG_CSC_10_OP_MODE 0x0
#define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF #define SSPP_TRAFFIC_SHAPER_BPC_MAX 0xFF
@@ -417,25 +420,81 @@ static void sde_hw_sspp_setup_format(struct sde_hw_pipe *ctx,
SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31)); SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS + idx, BIT(31));
} }
static void sde_hw_sspp_clear_ubwc_error(struct sde_hw_pipe *ctx) static void sde_hw_sspp_clear_ubwc_error(struct sde_hw_pipe *ctx, uint32_t multirect_index)
{ {
struct sde_hw_blk_reg_map *c; struct sde_hw_blk_reg_map *c;
c = &ctx->hw; c = &ctx->hw;
SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS, BIT(31)); SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS, BIT(31));
} }
static u32 sde_hw_sspp_get_ubwc_error(struct sde_hw_pipe *ctx) static u32 sde_hw_sspp_get_ubwc_error(struct sde_hw_pipe *ctx, uint32_t multirect_index)
{ {
struct sde_hw_blk_reg_map *c; struct sde_hw_blk_reg_map *c;
u32 reg_code; u32 reg_code;
c = &ctx->hw; c = &ctx->hw;
reg_code = SDE_REG_READ(c, SSPP_UBWC_ERROR_STATUS); reg_code = SDE_REG_READ(c, SSPP_UBWC_ERROR_STATUS);
return reg_code; return reg_code;
} }
static void sde_hw_sspp_clear_ubwc_error_v1(struct sde_hw_pipe *ctx, uint32_t multirect_index)
{
struct sde_hw_blk_reg_map *c;
c = &ctx->hw;
if (multirect_index == SDE_SSPP_RECT_1)
SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS_REC1, BIT(31));
else
SDE_REG_WRITE(c, SSPP_UBWC_ERROR_STATUS, BIT(31));
}
static u32 sde_hw_sspp_get_ubwc_error_v1(struct sde_hw_pipe *ctx, uint32_t multirect_index)
{
struct sde_hw_blk_reg_map *c;
u32 reg_code;
c = &ctx->hw;
if (multirect_index == SDE_SSPP_RECT_1)
reg_code = SDE_REG_READ(c, SSPP_UBWC_ERROR_STATUS_REC1);
else
reg_code = SDE_REG_READ(c, SSPP_UBWC_ERROR_STATUS);
return reg_code;
}
static void sde_hw_sspp_clear_meta_error(struct sde_hw_pipe *ctx, uint32_t multirect_index)
{
struct sde_hw_blk_reg_map *c;
c = &ctx->hw;
if (multirect_index == SDE_SSPP_RECT_1)
SDE_REG_WRITE(c, SSPP_META_ERROR_STATUS_REC1, BIT(31));
else
SDE_REG_WRITE(c, SSPP_META_ERROR_STATUS, BIT(31));
}
static u32 sde_hw_sspp_get_meta_error(struct sde_hw_pipe *ctx, uint32_t multirect_index)
{
struct sde_hw_blk_reg_map *c;
u32 reg_code;
c = &ctx->hw;
if (multirect_index == SDE_SSPP_RECT_1)
reg_code = SDE_REG_READ(c, SSPP_META_ERROR_STATUS_REC1);
else
reg_code = SDE_REG_READ(c, SSPP_META_ERROR_STATUS);
return reg_code;
}
static void sde_hw_sspp_setup_secure(struct sde_hw_pipe *ctx, static void sde_hw_sspp_setup_secure(struct sde_hw_pipe *ctx,
enum sde_sspp_multirect_index rect_mode, enum sde_sspp_multirect_index rect_mode,
bool enable) bool enable)
@@ -1253,6 +1312,17 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
c->ops.setup_scaler = reg_dmav1_setup_vig_qseed3; c->ops.setup_scaler = reg_dmav1_setup_vig_qseed3;
} }
if (test_bit(SDE_SSPP_MULTIRECT_ERROR, &features)) {
c->ops.get_meta_error = sde_hw_sspp_get_meta_error;
c->ops.clear_meta_error = sde_hw_sspp_clear_meta_error;
c->ops.get_ubwc_error = sde_hw_sspp_get_ubwc_error_v1;
c->ops.clear_ubwc_error = sde_hw_sspp_clear_ubwc_error_v1;
} else {
c->ops.get_ubwc_error = sde_hw_sspp_get_ubwc_error;
c->ops.clear_ubwc_error = sde_hw_sspp_clear_ubwc_error;
}
if (test_bit(SDE_SSPP_PREDOWNSCALE, &features)) if (test_bit(SDE_SSPP_PREDOWNSCALE, &features))
c->ops.setup_pre_downscale = sde_hw_sspp_setup_pre_downscale; c->ops.setup_pre_downscale = sde_hw_sspp_setup_pre_downscale;
@@ -1271,9 +1341,6 @@ static void _setup_layer_ops(struct sde_hw_pipe *c,
c->ops.setup_inverse_pma = sde_hw_sspp_setup_dgm_inverse_pma; c->ops.setup_inverse_pma = sde_hw_sspp_setup_dgm_inverse_pma;
else if (test_bit(SDE_SSPP_INVERSE_PMA, &features)) else if (test_bit(SDE_SSPP_INVERSE_PMA, &features))
c->ops.setup_inverse_pma = sde_hw_sspp_setup_inverse_pma; c->ops.setup_inverse_pma = sde_hw_sspp_setup_inverse_pma;
c->ops.get_ubwc_error = sde_hw_sspp_get_ubwc_error;
c->ops.clear_ubwc_error = sde_hw_sspp_clear_ubwc_error;
} }
static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp, static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp,

查看文件

@@ -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_SSPP_H #ifndef _SDE_HW_SSPP_H
@@ -591,17 +591,33 @@ struct sde_hw_sspp_ops {
void (*setup_dgm_csc)(struct sde_hw_pipe *ctx, void (*setup_dgm_csc)(struct sde_hw_pipe *ctx,
enum sde_sspp_multirect_index index, struct sde_csc_cfg *data); enum sde_sspp_multirect_index index, struct sde_csc_cfg *data);
/**
* clear_meta_error - clear the meta error-code registers
* @ctx: Pointer to pipe context
* @multirect_index: rec in use
*/
void (*clear_meta_error)(struct sde_hw_pipe *ctx, uint32_t multirect_index);
/**
* get_meta_error - get the meta error-code
* @ctx: Pointer to pipe context
* @multirect_index: rec in use
*/
u32 (*get_meta_error)(struct sde_hw_pipe *ctx, uint32_t multirect_index);
/** /**
* clear_ubwc_error - clear the ubwc error-code registers * clear_ubwc_error - clear the ubwc error-code registers
* @ctx: Pointer to pipe context * @ctx: Pointer to pipe context
* @multirect_index: rec in use
*/ */
void (*clear_ubwc_error)(struct sde_hw_pipe *ctx); void (*clear_ubwc_error)(struct sde_hw_pipe *ctx, uint32_t multirect_index);
/** /**
* get_ubwc_error - get the ubwc error-code * get_ubwc_error - get the ubwc error-code
* @ctx: Pointer to pipe context * @ctx: Pointer to pipe context
* @multirect_index: rec in use
*/ */
u32 (*get_ubwc_error)(struct sde_hw_pipe *ctx); u32 (*get_ubwc_error)(struct sde_hw_pipe *ctx, uint32_t multirect_index);
}; };
/** /**

查看文件

@@ -4276,15 +4276,18 @@ u32 sde_plane_get_ubwc_error(struct drm_plane *plane)
{ {
u32 ubwc_error = 0; u32 ubwc_error = 0;
struct sde_plane *psde; struct sde_plane *psde;
struct sde_plane_state *pstate;
if (!plane) { if (!plane) {
SDE_ERROR("invalid plane\n"); SDE_ERROR("invalid plane\n");
return 0; return 0;
} }
psde = to_sde_plane(plane); psde = to_sde_plane(plane);
pstate = to_sde_plane_state(plane->state);
if (!psde->is_virtual && psde->pipe_hw->ops.get_ubwc_error) if (!psde->is_virtual && psde->pipe_hw->ops.get_ubwc_error)
ubwc_error = psde->pipe_hw->ops.get_ubwc_error(psde->pipe_hw); ubwc_error = psde->pipe_hw->ops.get_ubwc_error(psde->pipe_hw,
pstate->multirect_index);
return ubwc_error; return ubwc_error;
} }
@@ -4292,15 +4295,53 @@ u32 sde_plane_get_ubwc_error(struct drm_plane *plane)
void sde_plane_clear_ubwc_error(struct drm_plane *plane) void sde_plane_clear_ubwc_error(struct drm_plane *plane)
{ {
struct sde_plane *psde; struct sde_plane *psde;
struct sde_plane_state *pstate;
if (!plane) { if (!plane) {
SDE_ERROR("invalid plane\n"); SDE_ERROR("invalid plane\n");
return; return;
} }
psde = to_sde_plane(plane); psde = to_sde_plane(plane);
pstate = to_sde_plane_state(plane->state);
if (psde->pipe_hw->ops.clear_ubwc_error) if (psde->pipe_hw->ops.clear_ubwc_error)
psde->pipe_hw->ops.clear_ubwc_error(psde->pipe_hw); psde->pipe_hw->ops.clear_ubwc_error(psde->pipe_hw, pstate->multirect_index);
}
u32 sde_plane_get_meta_error(struct drm_plane *plane)
{
u32 meta_error = 0;
struct sde_plane *psde;
struct sde_plane_state *pstate;
if (!plane) {
SDE_ERROR("invalid plane\n");
return 0;
}
psde = to_sde_plane(plane);
pstate = to_sde_plane_state(plane->state);
if (psde->pipe_hw->ops.get_meta_error)
meta_error = psde->pipe_hw->ops.get_meta_error(psde->pipe_hw,
pstate->multirect_index);
return meta_error;
}
void sde_plane_clear_meta_error(struct drm_plane *plane)
{
struct sde_plane *psde;
struct sde_plane_state *pstate;
if (!plane) {
SDE_ERROR("invalid plane\n");
return;
}
psde = to_sde_plane(plane);
pstate = to_sde_plane_state(plane->state);
if (psde->pipe_hw->ops.clear_meta_error)
psde->pipe_hw->ops.clear_meta_error(psde->pipe_hw, pstate->multirect_index);
} }
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS

查看文件

@@ -317,6 +317,18 @@ u32 sde_plane_get_ubwc_error(struct drm_plane *plane);
*/ */
void sde_plane_clear_ubwc_error(struct drm_plane *plane); void sde_plane_clear_ubwc_error(struct drm_plane *plane);
/*
* sde_plane_get_meta_error - gets the meta error code
* @plane: Pointer to DRM plane object
*/
u32 sde_plane_get_meta_error(struct drm_plane *plane);
/*
* sde_plane_clear_meta_error - clears the meta error code
* @plane: Pointer to DRM plane object
*/
void sde_plane_clear_meta_error(struct drm_plane *plane);
/* /*
* sde_plane_setup_src_split_order - enable/disable pipe's src_split_order * sde_plane_setup_src_split_order - enable/disable pipe's src_split_order
* @plane: Pointer to DRM plane object * @plane: Pointer to DRM plane object