disp: msm: sde: adds mem mapping for hwfence ipcc reg

This change adds one-to-one memory mapping for the hwfence
ipcc register memory needed for hw fence feature.

Change-Id: I0e264183e02d0ed5f2254b409cc5e776d670f0dc
Signed-off-by: Christina Oliveira <quic_coliveir@quicinc.com>
This commit is contained in:
Christina Oliveira
2022-05-06 08:49:43 -07:00
parent 640c8111d3
commit 0e20e27cc1
6 changed files with 80 additions and 12 deletions

View File

@@ -222,6 +222,7 @@ enum sde_prop {
TRUSTED_VM_ENV, TRUSTED_VM_ENV,
MAX_TRUSTED_VM_DISPLAYS, MAX_TRUSTED_VM_DISPLAYS,
TVM_INCLUDE_REG, TVM_INCLUDE_REG,
IPCC_PROTOCOL_ID,
SDE_PROP_MAX, SDE_PROP_MAX,
}; };
@@ -620,6 +621,7 @@ static struct sde_prop_type sde_prop[] = {
{MAX_TRUSTED_VM_DISPLAYS, "qcom,sde-max-trusted-vm-displays", false, {MAX_TRUSTED_VM_DISPLAYS, "qcom,sde-max-trusted-vm-displays", false,
PROP_TYPE_U32}, PROP_TYPE_U32},
{TVM_INCLUDE_REG, "qcom,tvm-include-reg", false, PROP_TYPE_U32_ARRAY}, {TVM_INCLUDE_REG, "qcom,tvm-include-reg", false, PROP_TYPE_U32_ARRAY},
{IPCC_PROTOCOL_ID, "qcom,sde-ipcc-protocol-id", false, PROP_TYPE_U32},
}; };
static struct sde_prop_type sde_perf_prop[] = { static struct sde_prop_type sde_perf_prop[] = {
@@ -3992,6 +3994,8 @@ static void _sde_top_parse_dt_helper(struct sde_mdss_cfg *cfg,
cfg->mdp[0].smart_panel_align_mode = cfg->mdp[0].smart_panel_align_mode =
PROP_VALUE_ACCESS(props->values, SMART_PANEL_ALIGN_MODE, 0); PROP_VALUE_ACCESS(props->values, SMART_PANEL_ALIGN_MODE, 0);
cfg->ipcc_protocol_id = PROP_VALUE_ACCESS(props->values, IPCC_PROTOCOL_ID, 0);
if (props->exists[SEC_SID_MASK]) { if (props->exists[SEC_SID_MASK]) {
cfg->sec_sid_mask_count = props->counts[SEC_SID_MASK]; cfg->sec_sid_mask_count = props->counts[SEC_SID_MASK];
for (i = 0; i < cfg->sec_sid_mask_count; i++) for (i = 0; i < cfg->sec_sid_mask_count; i++)

View File

@@ -1847,6 +1847,7 @@ struct sde_perf_cfg {
* @inline_rot_restricted_formats restricted formats for inline rotation * @inline_rot_restricted_formats restricted formats for inline rotation
* @dnsc_blur_filters supported filters for downscale blur * @dnsc_blur_filters supported filters for downscale blur
* @dnsc_blur_filter_count supported filter count for downscale blur * @dnsc_blur_filter_count supported filter count for downscale blur
* @ipcc_protocol_id ipcc protocol id for the hw
*/ */
struct sde_mdss_cfg { struct sde_mdss_cfg {
/* Block Revisions */ /* Block Revisions */
@@ -1964,6 +1965,8 @@ struct sde_mdss_cfg {
struct sde_format_extended *inline_rot_restricted_formats; struct sde_format_extended *inline_rot_restricted_formats;
struct sde_dnsc_blur_filter_info *dnsc_blur_filters; struct sde_dnsc_blur_filter_info *dnsc_blur_filters;
u32 dnsc_blur_filter_count; u32 dnsc_blur_filter_count;
u32 ipcc_protocol_id;
}; };
struct sde_mdss_hw_cfg_handler { struct sde_mdss_hw_cfg_handler {

View File

@@ -101,11 +101,9 @@
#define MDP_CTL_HW_FENCE_IDm_DATA 0x14058 #define MDP_CTL_HW_FENCE_IDm_DATA 0x14058
#define MDP_CTL_HW_FENCE_IDm_MASK 0x1405c #define MDP_CTL_HW_FENCE_IDm_MASK 0x1405c
#define MDP_CTL_HW_FENCE_IDm_ATTR 0x14060 #define MDP_CTL_HW_FENCE_IDm_ATTR 0x14060
#define HW_FENCE_IPCC_PROTOCOL_ID_COMPUTE_L1 0x2
#define HW_FENCE_IPCC_PROTOCOLp_CLIENTc_SEND(ba, p, c) ((ba+0xc) + (0x40000*p) + (0x1000*c)) #define HW_FENCE_IPCC_PROTOCOLp_CLIENTc_SEND(ba, p, c) ((ba+0xc) + (0x40000*p) + (0x1000*c))
#define HW_FENCE_IPCC_PROTOCOLp_CLIENTc_RECV_ID(ba, p, c) ((ba+0x10) + (0x40000*p) + (0x1000*c)) #define HW_FENCE_IPCC_PROTOCOLp_CLIENTc_RECV_ID(ba, p, c) ((ba+0x10) + (0x40000*p) + (0x1000*c))
#define HW_FENCE_IPCC_SEND_BA 0x40000c
#define HW_FENCE_IPCC_RECV_ID_BA 0x400010
#define MDP_CTL_HW_FENCE_ID_OFFSET_n(base, n) (base + (0x14*n)) #define MDP_CTL_HW_FENCE_ID_OFFSET_n(base, n) (base + (0x14*n))
#define MDP_CTL_HW_FENCE_ID_OFFSET_m(base, m) (base + (0x14*m)) #define MDP_CTL_HW_FENCE_ID_OFFSET_m(base, m) (base + (0x14*m))
#define MDP_CTL_FENCE_ATTRS(devicetype, size, resp_req) \ #define MDP_CTL_FENCE_ATTRS(devicetype, size, resp_req) \
@@ -595,7 +593,8 @@ static u32 sde_hw_get_autorefresh_status(struct sde_hw_mdp *mdp, u32 intf_idx)
return autorefresh_status; return autorefresh_status;
} }
static void sde_hw_setup_hw_fences_config(struct sde_hw_mdp *mdp) static void sde_hw_setup_hw_fences_config(struct sde_hw_mdp *mdp, u32 protocol_id,
unsigned long ipcc_base_addr)
{ {
u32 val, offset; u32 val, offset;
struct sde_hw_blk_reg_map c; struct sde_hw_blk_reg_map c;
@@ -609,8 +608,8 @@ static void sde_hw_setup_hw_fences_config(struct sde_hw_mdp *mdp)
c = mdp->hw; c = mdp->hw;
c.blk_off = 0x0; c.blk_off = 0x0;
/* select ipcc protocol id for dpu */ /*select ipcc protocol id for dpu */
SDE_REG_WRITE(&c, MDP_CTL_HW_FENCE_CTRL, HW_FENCE_IPCC_PROTOCOL_ID_COMPUTE_L1); SDE_REG_WRITE(&c, MDP_CTL_HW_FENCE_CTRL, protocol_id);
/* configure the start of the FENCE_IDn_ISR ops for input and output fence isr's */ /* configure the start of the FENCE_IDn_ISR ops for input and output fence isr's */
val = (HW_FENCE_DPU_OUTPUT_FENCE_START_N << 16) | (HW_FENCE_DPU_INPUT_FENCE_START_N & 0xFF); val = (HW_FENCE_DPU_OUTPUT_FENCE_START_N << 16) | (HW_FENCE_DPU_INPUT_FENCE_START_N & 0xFF);
@@ -620,8 +619,8 @@ static void sde_hw_setup_hw_fences_config(struct sde_hw_mdp *mdp)
/* configure the attribs for the isr read_reg op */ /* configure the attribs for the isr read_reg op */
offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ADDR, 0); offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ADDR, 0);
val = HW_FENCE_IPCC_PROTOCOLp_CLIENTc_RECV_ID(HW_FENCE_IPCC_RECV_ID_BA, val = HW_FENCE_IPCC_PROTOCOLp_CLIENTc_RECV_ID(ipcc_base_addr,
HW_FENCE_IPCC_PROTOCOL_ID_COMPUTE_L1, 25); protocol_id, HW_FENCE_IPCC_CLIENT_DPU);
SDE_REG_WRITE(&c, offset, val); SDE_REG_WRITE(&c, offset, val);
offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ATTR, 0); offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ATTR, 0);
@@ -659,8 +658,8 @@ static void sde_hw_setup_hw_fences_config(struct sde_hw_mdp *mdp)
/* configure the attribs for the isr load_data op */ /* configure the attribs for the isr load_data op */
offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ADDR, 4); offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ADDR, 4);
val = HW_FENCE_IPCC_PROTOCOLp_CLIENTc_SEND(HW_FENCE_IPCC_SEND_BA, val = HW_FENCE_IPCC_PROTOCOLp_CLIENTc_SEND(ipcc_base_addr,
HW_FENCE_IPCC_PROTOCOL_ID_COMPUTE_L1, 25); protocol_id, HW_FENCE_IPCC_CLIENT_DPU);
SDE_REG_WRITE(&c, offset, val); SDE_REG_WRITE(&c, offset, val);
offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ATTR, 4); offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ATTR, 4);

View File

@@ -11,6 +11,9 @@
#include "sde_hw_mdss.h" #include "sde_hw_mdss.h"
#include "sde_hw_util.h" #include "sde_hw_util.h"
#define HW_FENCE_IPCC_CLIENT_DPU 25
#define HW_FENCE_IPCC_PROTOCOLp_CLIENTc(ba, p, c) (ba + (0x40000*p) + (0x1000*c))
struct sde_hw_mdp; struct sde_hw_mdp;
struct sde_hw_sid; struct sde_hw_sid;
@@ -206,8 +209,11 @@ struct sde_hw_mdp_ops {
/** /**
* setup_hw_fences - configure hw fences top registers * setup_hw_fences - configure hw fences top registers
* @mdp: mdp top context driver * @mdp: mdp top context driver
* @protocol_id: ipcc protocol id
* @ipcc_base_addr: base address for ipcc reg block
*/ */
void (*setup_hw_fences)(struct sde_hw_mdp *mdp); void (*setup_hw_fences)(struct sde_hw_mdp *mdp, u32 protocol_id,
unsigned long ipcc_base_addr);
}; };

View File

@@ -783,6 +783,37 @@ static int _sde_kms_release_shared_buffer(unsigned int mem_addr,
} }
static int _sde_kms_one2one_mem_map_ipcc_reg(struct sde_kms *sde_kms, u32 buf_size,
unsigned long buf_base)
{
struct msm_mmu *mmu = NULL;
int ret = 0;
if (!sde_kms->aspace[MSM_SMMU_DOMAIN_UNSECURE]
|| !sde_kms->aspace[MSM_SMMU_DOMAIN_UNSECURE]->mmu) {
SDE_ERROR("aspace not found for sde kms node\n");
return -EINVAL;
}
mmu = sde_kms->aspace[MSM_SMMU_DOMAIN_UNSECURE]->mmu;
if (!mmu) {
SDE_ERROR("mmu not found for aspace\n");
return -EINVAL;
}
if (!mmu->funcs || !mmu->funcs->one_to_one_map) {
SDE_ERROR("invalid input params for map\n");
return -EINVAL;
}
ret = mmu->funcs->one_to_one_map(mmu, buf_base, buf_base, buf_size,
IOMMU_READ | IOMMU_WRITE);
if (ret)
SDE_ERROR("one2one memory smmu map failed:%d\n", ret);
return ret;
}
static int _sde_kms_splash_mem_get(struct sde_kms *sde_kms, static int _sde_kms_splash_mem_get(struct sde_kms *sde_kms,
struct sde_splash_mem *splash) struct sde_splash_mem *splash)
{ {
@@ -4169,6 +4200,8 @@ static int _sde_kms_mmu_destroy(struct sde_kms *sde_kms)
static int _sde_kms_mmu_init(struct sde_kms *sde_kms) static int _sde_kms_mmu_init(struct sde_kms *sde_kms)
{ {
struct msm_mmu *mmu; struct msm_mmu *mmu;
struct resource *res;
struct platform_device *pdev;
int i, ret; int i, ret;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0)) #if (LINUX_VERSION_CODE < KERNEL_VERSION(5, 15, 0))
@@ -4210,6 +4243,25 @@ static int _sde_kms_mmu_init(struct sde_kms *sde_kms)
} }
} }
if (i == MSM_SMMU_DOMAIN_UNSECURE && sde_kms->catalog->hw_fence_rev) {
pdev = to_platform_device(sde_kms->dev->dev);
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ipcc_reg");
if (!res) {
SDE_DEBUG("failed to get resource ipcc_reg, cannot map ipcc\n");
sde_kms->catalog->hw_fence_rev = 0;
} else {
sde_kms->ipcc_base_addr = res->start;
ret = _sde_kms_one2one_mem_map_ipcc_reg(sde_kms, resource_size(res),
HW_FENCE_IPCC_PROTOCOLp_CLIENTc(res->start,
sde_kms->catalog->ipcc_protocol_id,
HW_FENCE_IPCC_CLIENT_DPU));
/* if mapping fails disable hw-fences */
if (ret)
sde_kms->catalog->hw_fence_rev = 0;
}
}
/* /*
* disable early-map which would have been enabled during * disable early-map which would have been enabled during
* bootup by smmu through the device-tree hint for cont-spash * bootup by smmu through the device-tree hint for cont-spash
@@ -4258,7 +4310,8 @@ static void sde_kms_init_hw_fences(struct sde_kms *sde_kms)
return; return;
if (sde_kms->hw_mdp->ops.setup_hw_fences) if (sde_kms->hw_mdp->ops.setup_hw_fences)
sde_kms->hw_mdp->ops.setup_hw_fences(sde_kms->hw_mdp); sde_kms->hw_mdp->ops.setup_hw_fences(sde_kms->hw_mdp,
sde_kms->catalog->ipcc_protocol_id, sde_kms->ipcc_base_addr);
} }
static void sde_kms_init_shared_hw(struct sde_kms *sde_kms) static void sde_kms_init_shared_hw(struct sde_kms *sde_kms)

View File

@@ -1,4 +1,5 @@
/* /*
* Copyright (c) 2022 Qualcomm Innovation Center, Inc. All rights reserved.
* Copyright (c) 2015-2021, The Linux Foundation. All rights reserved. * Copyright (c) 2015-2021, The Linux Foundation. All rights reserved.
* Copyright (C) 2013 Red Hat * Copyright (C) 2013 Red Hat
* Author: Rob Clark <robdclark@gmail.com> * Author: Rob Clark <robdclark@gmail.com>
@@ -315,6 +316,8 @@ struct sde_kms {
struct irq_affinity_notify affinity_notify; struct irq_affinity_notify affinity_notify;
struct sde_vm *vm; struct sde_vm *vm;
unsigned long ipcc_base_addr;
}; };
struct vsync_info { struct vsync_info {