diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index 6836e35eb9..1800054a3a 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -222,6 +222,7 @@ enum sde_prop { TRUSTED_VM_ENV, MAX_TRUSTED_VM_DISPLAYS, TVM_INCLUDE_REG, + IPCC_PROTOCOL_ID, 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, PROP_TYPE_U32}, {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[] = { @@ -3992,6 +3994,8 @@ static void _sde_top_parse_dt_helper(struct sde_mdss_cfg *cfg, cfg->mdp[0].smart_panel_align_mode = 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]) { cfg->sec_sid_mask_count = props->counts[SEC_SID_MASK]; for (i = 0; i < cfg->sec_sid_mask_count; i++) diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index a9afabeb38..4eab98d8c0 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -1847,6 +1847,7 @@ struct sde_perf_cfg { * @inline_rot_restricted_formats restricted formats for inline rotation * @dnsc_blur_filters supported filters 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 { /* Block Revisions */ @@ -1964,6 +1965,8 @@ struct sde_mdss_cfg { struct sde_format_extended *inline_rot_restricted_formats; struct sde_dnsc_blur_filter_info *dnsc_blur_filters; u32 dnsc_blur_filter_count; + + u32 ipcc_protocol_id; }; struct sde_mdss_hw_cfg_handler { diff --git a/msm/sde/sde_hw_top.c b/msm/sde/sde_hw_top.c index b32fef0ac8..78645ca815 100644 --- a/msm/sde/sde_hw_top.c +++ b/msm/sde/sde_hw_top.c @@ -101,11 +101,9 @@ #define MDP_CTL_HW_FENCE_IDm_DATA 0x14058 #define MDP_CTL_HW_FENCE_IDm_MASK 0x1405c #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_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_m(base, m) (base + (0x14*m)) #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; } -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; 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.blk_off = 0x0; - /* select ipcc protocol id for dpu */ - SDE_REG_WRITE(&c, MDP_CTL_HW_FENCE_CTRL, HW_FENCE_IPCC_PROTOCOL_ID_COMPUTE_L1); + /*select ipcc protocol id for dpu */ + 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 */ 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 */ 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, - HW_FENCE_IPCC_PROTOCOL_ID_COMPUTE_L1, 25); + val = HW_FENCE_IPCC_PROTOCOLp_CLIENTc_RECV_ID(ipcc_base_addr, + protocol_id, HW_FENCE_IPCC_CLIENT_DPU); SDE_REG_WRITE(&c, offset, val); 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 */ 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, - HW_FENCE_IPCC_PROTOCOL_ID_COMPUTE_L1, 25); + val = HW_FENCE_IPCC_PROTOCOLp_CLIENTc_SEND(ipcc_base_addr, + protocol_id, HW_FENCE_IPCC_CLIENT_DPU); SDE_REG_WRITE(&c, offset, val); offset = MDP_CTL_HW_FENCE_ID_OFFSET_m(MDP_CTL_HW_FENCE_IDm_ATTR, 4); diff --git a/msm/sde/sde_hw_top.h b/msm/sde/sde_hw_top.h index c7464eec3c..45fa9f808c 100644 --- a/msm/sde/sde_hw_top.h +++ b/msm/sde/sde_hw_top.h @@ -11,6 +11,9 @@ #include "sde_hw_mdss.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_sid; @@ -206,8 +209,11 @@ struct sde_hw_mdp_ops { /** * setup_hw_fences - configure hw fences top registers * @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); }; diff --git a/msm/sde/sde_kms.c b/msm/sde/sde_kms.c index 8134a0421c..ec239bd08d 100644 --- a/msm/sde/sde_kms.c +++ b/msm/sde/sde_kms.c @@ -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, 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) { struct msm_mmu *mmu; + struct resource *res; + struct platform_device *pdev; int i, ret; #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 * 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; 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) diff --git a/msm/sde/sde_kms.h b/msm/sde/sde_kms.h index b5d8e1d8d4..d3408ee9ec 100644 --- a/msm/sde/sde_kms.h +++ b/msm/sde/sde_kms.h @@ -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) 2013 Red Hat * Author: Rob Clark @@ -315,6 +316,8 @@ struct sde_kms { struct irq_affinity_notify affinity_notify; struct sde_vm *vm; + + unsigned long ipcc_base_addr; }; struct vsync_info {