Merge "disp: msm: sde: Validate transaction counts for LUTDMA abs writes"
This commit is contained in:

committed by
Gerrit - the friendly Code Review server

commit
b8a102735a
@@ -1353,6 +1353,7 @@ struct sde_reg_dma_blk_info {
|
|||||||
* @broadcast_disabled flag indicating if broadcast usage should be avoided
|
* @broadcast_disabled flag indicating if broadcast usage should be avoided
|
||||||
* @xin_id VBIF xin client-id for LUTDMA
|
* @xin_id VBIF xin client-id for LUTDMA
|
||||||
* @vbif_idx VBIF id (RT/NRT)
|
* @vbif_idx VBIF id (RT/NRT)
|
||||||
|
* @base_off Base offset of LUTDMA from the MDSS root
|
||||||
* @clk_ctrl VBIF xin client clk-ctrl
|
* @clk_ctrl VBIF xin client clk-ctrl
|
||||||
*/
|
*/
|
||||||
struct sde_reg_dma_cfg {
|
struct sde_reg_dma_cfg {
|
||||||
@@ -1362,6 +1363,7 @@ struct sde_reg_dma_cfg {
|
|||||||
u32 broadcast_disabled;
|
u32 broadcast_disabled;
|
||||||
u32 xin_id;
|
u32 xin_id;
|
||||||
u32 vbif_idx;
|
u32 vbif_idx;
|
||||||
|
u32 base_off;
|
||||||
enum sde_clk_ctrl_type clk_ctrl;
|
enum sde_clk_ctrl_type clk_ctrl;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
#define GUARD_BYTES (BIT(8) - 1)
|
#define GUARD_BYTES (BIT(8) - 1)
|
||||||
#define ALIGNED_OFFSET (U32_MAX & ~(GUARD_BYTES))
|
#define ALIGNED_OFFSET (U32_MAX & ~(GUARD_BYTES))
|
||||||
#define ADDR_ALIGN BIT(8)
|
#define ADDR_ALIGN BIT(8)
|
||||||
#define MAX_RELATIVE_OFF (BIT(20) - 1)
|
#define MAX_RELATIVE_OFF (BIT(21) - 1)
|
||||||
#define ABSOLUTE_RANGE BIT(27)
|
#define ABSOLUTE_RANGE BIT(27)
|
||||||
|
|
||||||
#define DECODE_SEL_OP (BIT(HW_BLK_SELECT))
|
#define DECODE_SEL_OP (BIT(HW_BLK_SELECT))
|
||||||
@@ -254,6 +254,9 @@ static int write_multi_reg(struct sde_reg_dma_setup_ops_cfg *cfg)
|
|||||||
cfg->dma_buf->next_op_allowed = REG_WRITE_OP | DECODE_SEL_OP;
|
cfg->dma_buf->next_op_allowed = REG_WRITE_OP | DECODE_SEL_OP;
|
||||||
cfg->dma_buf->ops_completed |= REG_WRITE_OP;
|
cfg->dma_buf->ops_completed |= REG_WRITE_OP;
|
||||||
|
|
||||||
|
if (cfg->blk == MDSS)
|
||||||
|
cfg->dma_buf->abs_write_cnt += SIZE_DWORD(cfg->data_size);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,8 +322,10 @@ static int write_single_reg(struct sde_reg_dma_setup_ops_cfg *cfg)
|
|||||||
cfg->dma_buf->index);
|
cfg->dma_buf->index);
|
||||||
loc[0] = SINGLE_REG_WRITE_OPCODE;
|
loc[0] = SINGLE_REG_WRITE_OPCODE;
|
||||||
loc[0] |= (cfg->blk_offset & MAX_RELATIVE_OFF);
|
loc[0] |= (cfg->blk_offset & MAX_RELATIVE_OFF);
|
||||||
if (cfg->blk == MDSS)
|
if (cfg->blk == MDSS) {
|
||||||
loc[0] |= ABSOLUTE_RANGE;
|
loc[0] |= ABSOLUTE_RANGE;
|
||||||
|
cfg->dma_buf->abs_write_cnt++;
|
||||||
|
}
|
||||||
|
|
||||||
loc[1] = *cfg->data;
|
loc[1] = *cfg->data;
|
||||||
cfg->dma_buf->index += ops_mem_size[cfg->ops];
|
cfg->dma_buf->index += ops_mem_size[cfg->ops];
|
||||||
@@ -624,6 +629,32 @@ static int validate_kick_off_v1(struct sde_reg_dma_kickoff_cfg *cfg)
|
|||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((cfg->dma_buf->abs_write_cnt % 2) != 0) {
|
||||||
|
/* Touch up buffer to avoid HW issues with odd number of abs writes */
|
||||||
|
u32 reg = 0;
|
||||||
|
struct sde_reg_dma_setup_ops_cfg dma_write_cfg;
|
||||||
|
|
||||||
|
dma_write_cfg.dma_buf = cfg->dma_buf;
|
||||||
|
dma_write_cfg.blk = MDSS;
|
||||||
|
dma_write_cfg.feature = REG_DMA_FEATURES_MAX;
|
||||||
|
dma_write_cfg.ops = HW_BLK_SELECT;
|
||||||
|
if (validate_write_decode_sel(&dma_write_cfg) || write_decode_sel(&dma_write_cfg)) {
|
||||||
|
DRM_ERROR("Failed setting MDSS decode select for LUTDMA touch up\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Perform dummy write on LUTDMA RO version reg */
|
||||||
|
dma_write_cfg.ops = REG_SINGLE_WRITE;
|
||||||
|
dma_write_cfg.blk_offset = reg_dma->caps->base_off +
|
||||||
|
reg_dma->caps->reg_dma_blks[cfg->dma_type].base;
|
||||||
|
dma_write_cfg.data = ®
|
||||||
|
dma_write_cfg.data_size = sizeof(uint32_t);
|
||||||
|
if (validate_write_reg(&dma_write_cfg) || write_single_reg(&dma_write_cfg)) {
|
||||||
|
DRM_ERROR("Failed to add touch up write to LUTDMA buffer\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1110,6 +1141,7 @@ static int reset_reg_dma_buffer_v1(struct sde_reg_dma_buffer *lut_buf)
|
|||||||
lut_buf->index = 0;
|
lut_buf->index = 0;
|
||||||
lut_buf->ops_completed = 0;
|
lut_buf->ops_completed = 0;
|
||||||
lut_buf->next_op_allowed = DECODE_SEL_OP;
|
lut_buf->next_op_allowed = DECODE_SEL_OP;
|
||||||
|
lut_buf->abs_write_cnt = 0;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -4557,7 +4557,9 @@ static int _sde_kms_hw_init_ioremap(struct sde_kms *sde_kms,
|
|||||||
sde_kms->reg_dma = NULL;
|
sde_kms->reg_dma = NULL;
|
||||||
SDE_DEBUG("REG_DMA is not defined");
|
SDE_DEBUG("REG_DMA is not defined");
|
||||||
} else {
|
} else {
|
||||||
|
unsigned long mdp_addr = msm_get_phys_addr(platformdev, "mdp_phys");
|
||||||
sde_kms->reg_dma_len = msm_iomap_size(platformdev, "regdma_phys");
|
sde_kms->reg_dma_len = msm_iomap_size(platformdev, "regdma_phys");
|
||||||
|
sde_kms->reg_dma_off = msm_get_phys_addr(platformdev, "regdma_phys") - mdp_addr;
|
||||||
rc = sde_dbg_reg_register_base("reg_dma", sde_kms->reg_dma,
|
rc = sde_dbg_reg_register_base("reg_dma", sde_kms->reg_dma,
|
||||||
sde_kms->reg_dma_len,
|
sde_kms->reg_dma_len,
|
||||||
msm_get_phys_addr(platformdev, "regdma_phys"),
|
msm_get_phys_addr(platformdev, "regdma_phys"),
|
||||||
@@ -4651,6 +4653,7 @@ static int _sde_kms_hw_init_blocks(struct sde_kms *sde_kms,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize reg dma block which is a singleton */
|
/* Initialize reg dma block which is a singleton */
|
||||||
|
sde_kms->catalog->dma_cfg.base_off = sde_kms->reg_dma_off;
|
||||||
rc = sde_reg_dma_init(sde_kms->reg_dma, sde_kms->catalog,
|
rc = sde_reg_dma_init(sde_kms->reg_dma, sde_kms->catalog,
|
||||||
sde_kms->dev);
|
sde_kms->dev);
|
||||||
if (rc) {
|
if (rc) {
|
||||||
|
@@ -262,6 +262,7 @@ struct sde_kms {
|
|||||||
/* io/register spaces: */
|
/* io/register spaces: */
|
||||||
void __iomem *mmio, *vbif[VBIF_MAX], *reg_dma, *sid;
|
void __iomem *mmio, *vbif[VBIF_MAX], *reg_dma, *sid;
|
||||||
unsigned long mmio_len, vbif_len[VBIF_MAX], reg_dma_len, sid_len;
|
unsigned long mmio_len, vbif_len[VBIF_MAX], reg_dma_len, sid_len;
|
||||||
|
unsigned long reg_dma_off;
|
||||||
|
|
||||||
struct regulator *vdd;
|
struct regulator *vdd;
|
||||||
struct regulator *mmagic;
|
struct regulator *mmagic;
|
||||||
|
@@ -1,6 +1,6 @@
|
|||||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
/* 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_REG_DMA_H
|
#ifndef _SDE_REG_DMA_H
|
||||||
@@ -232,6 +232,7 @@ enum sde_reg_dma_last_cmd_mode {
|
|||||||
* @vaddr: cpu address
|
* @vaddr: cpu address
|
||||||
* @next_op_allowed: operation allowed on the buffer
|
* @next_op_allowed: operation allowed on the buffer
|
||||||
* @ops_completed: operations completed on buffer
|
* @ops_completed: operations completed on buffer
|
||||||
|
* @abs_write_cnt: count of mdss absolute addr writes in the current buffer
|
||||||
*/
|
*/
|
||||||
struct sde_reg_dma_buffer {
|
struct sde_reg_dma_buffer {
|
||||||
struct drm_gem_object *buf;
|
struct drm_gem_object *buf;
|
||||||
@@ -242,6 +243,7 @@ struct sde_reg_dma_buffer {
|
|||||||
void *vaddr;
|
void *vaddr;
|
||||||
u32 next_op_allowed;
|
u32 next_op_allowed;
|
||||||
u32 ops_completed;
|
u32 ops_completed;
|
||||||
|
u32 abs_write_cnt;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Reference in New Issue
Block a user