diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index fa34bef077..a434473139 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #define pr_fmt(fmt) "[drm:%s:%d] " fmt, __func__, __LINE__ @@ -4387,7 +4387,7 @@ static int _sde_hardware_pre_caps(struct sde_mdss_cfg *sde_cfg, uint32_t hw_rev) sde_cfg->has_3d_merge_reset = true; sde_cfg->has_hdr = true; sde_cfg->has_hdr_plus = true; - set_bit(SDE_MDP_DHDR_MEMPOOL, &sde_cfg->mdp[0].features); + set_bit(SDE_MDP_DHDR_MEMPOOL_4K, &sde_cfg->mdp[0].features); sde_cfg->has_vig_p010 = true; sde_cfg->true_inline_rot_rev = SDE_INLINE_ROT_VERSION_2_0_0; sde_cfg->uidle_cfg.uidle_rev = SDE_UIDLE_VERSION_1_0_0; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index ffbe166d49..e33276e550 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _SDE_HW_CATALOG_H @@ -176,6 +176,7 @@ struct sde_intr_irq_offsets { * @SDE_MDP_UBWC_1_5, Universal Bandwidth compression version 1.5 * @SDE_MDP_VSYNC_SEL Vsync selection for command mode panels * @SDE_MDP_DHDR_MEMPOOL Dynamic HDR Metadata mempool present + * @SDE_MDP_DHDR_MEMPOOL_4K Dynamic HDR mempool is 4k aligned * @SDE_MDP_MAX Maximum value */ @@ -187,6 +188,7 @@ enum { SDE_MDP_UBWC_1_5, SDE_MDP_VSYNC_SEL, SDE_MDP_DHDR_MEMPOOL, + SDE_MDP_DHDR_MEMPOOL_4K, SDE_MDP_MAX }; diff --git a/msm/sde/sde_hw_top.c b/msm/sde/sde_hw_top.c index 7c2de6c3d0..9b58ff5dbb 100644 --- a/msm/sde/sde_hw_top.c +++ b/msm/sde/sde_hw_top.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #include "sde_hwio.h" @@ -485,32 +485,45 @@ static void sde_hw_program_cwb_ppb_ctrl(struct sde_hw_mdp *mdp, static void sde_hw_set_hdr_plus_metadata(struct sde_hw_mdp *mdp, u8 *payload, u32 len, u32 stream_id) { - u32 i; - size_t length = len - 1; - u32 offset = 0, data = 0, byte_idx = 0; + u32 i, b; + u32 length = len - 1; + u32 d_offset, nb_offset, data = 0; const u32 dword_size = sizeof(u32); + bool is_4k_aligned = mdp->caps->features & + BIT(SDE_MDP_DHDR_MEMPOOL_4K); if (!payload || !len) { SDE_ERROR("invalid payload with length: %d\n", len); return; } - if (stream_id) - offset = DP_DHDR_MEM_POOL_1_DATA - DP_DHDR_MEM_POOL_0_DATA; - - /* payload[0] is set in VSCEXT header byte 1, skip programming here */ - SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_NUM_BYTES + offset, length); - for (i = 1; i < len; i++) { - if (byte_idx && !(byte_idx % dword_size)) { - SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_DATA + - offset, data); - data = 0; + if (stream_id) { + if (is_4k_aligned) { + d_offset = DP_DHDR_MEM_POOL_1_DATA_4K; + nb_offset = DP_DHDR_MEM_POOL_1_NUM_BYTES_4K; + } else { + d_offset = DP_DHDR_MEM_POOL_1_DATA; + nb_offset = DP_DHDR_MEM_POOL_1_NUM_BYTES; + } + } else { + if (is_4k_aligned) { + d_offset = DP_DHDR_MEM_POOL_0_DATA_4K; + nb_offset = DP_DHDR_MEM_POOL_0_NUM_BYTES_4K; + } else { + d_offset = DP_DHDR_MEM_POOL_0_DATA; + nb_offset = DP_DHDR_MEM_POOL_0_NUM_BYTES; } - - data |= payload[i] << (8 * (byte_idx++ % dword_size)); } - SDE_REG_WRITE(&mdp->hw, DP_DHDR_MEM_POOL_0_DATA + offset, data); + /* payload[0] is set in VSCEXT header byte 1, skip programming here */ + SDE_REG_WRITE(&mdp->hw, nb_offset, length); + for (i = 1; i < len; i += dword_size) { + for (b = 0; (i + b) < len && b < dword_size; b++) + data |= payload[i + b] << (8 * b); + + SDE_REG_WRITE(&mdp->hw, d_offset, data); + data = 0; + } } static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops, @@ -533,7 +546,9 @@ static void _setup_mdp_ops(struct sde_hw_mdp_ops *ops, ops->setup_vsync_source = sde_hw_setup_vsync_source; else ops->setup_vsync_source = sde_hw_setup_vsync_source_v1; - if (cap & BIT(SDE_MDP_DHDR_MEMPOOL)) + + if (cap & BIT(SDE_MDP_DHDR_MEMPOOL_4K) || + cap & BIT(SDE_MDP_DHDR_MEMPOOL)) ops->set_hdr_plus_metadata = sde_hw_set_hdr_plus_metadata; } diff --git a/msm/sde/sde_hwio.h b/msm/sde/sde_hwio.h index c3dbde0f2a..170f36c354 100644 --- a/msm/sde/sde_hwio.h +++ b/msm/sde/sde_hwio.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2015-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2015-2020, The Linux Foundation. All rights reserved. */ #ifndef _SDE_HWIO_H @@ -57,6 +57,11 @@ #define DP_DHDR_MEM_POOL_0_NUM_BYTES 0x47c #define DP_DHDR_MEM_POOL_1_NUM_BYTES 0x480 +#define DP_DHDR_MEM_POOL_0_DATA_4K 0x1004 +#define DP_DHDR_MEM_POOL_1_DATA_4K 0x2004 +#define DP_DHDR_MEM_POOL_0_NUM_BYTES_4K 0x100c +#define DP_DHDR_MEM_POOL_1_NUM_BYTES_4K 0x200c + /* SDE_SCALER_QSEED3 */ #define QSEED3_COEF_LUT_OFF 0x100 #define QSEED3_FILTERS 5