Loading Documentation/devicetree/bindings/display/msm/sde.txt +49 −6 Original line number Diff line number Diff line Loading @@ -148,10 +148,6 @@ Optional properties: control register. Number of offsets defined should match the number of offsets defined in property: qcom,sde-sspp-off. - qcom,sde-sspp-danger-lut: A 3 cell property, with a format of <linear, tile, nrt>, indicating the danger luts on sspp. - qcom,sde-sspp-safe-lut: A 3 cell property, with a format of <linear, tile, nrt>, indicating the safe luts on sspp. - qcom,sde-sspp-excl-rect: Array of u32 values indicating exclusion rectangle support on each sspp. - qcom,sde-sspp-smart-dma-priority: Array of u32 values indicating hw pipe Loading Loading @@ -301,6 +297,28 @@ Optional properties: priority for realtime clients. - qcom,sde-vbif-qos-nrt-remap: This array is used to program vbif qos remapper register priority for non-realtime clients. - qcom,sde-danger-lut: A 4 cell property, with a format of <linear, tile, nrt, cwb>, indicating the danger luts on sspp. - qcom,sde-safe-lut: A 4 cell property, with a format of <linear, tile, nrt, cwb>, indicating the safe luts on sspp. - qcom,sde-qos-lut-linear: Array of 3 cell property, with a format of <fill level, lut hi, lut lo> in ascending fill level indicating the qos luts for linear format on sspp. Zero fill level on the last entry identifies the default lut. - qcom,sde-qos-lut-macrotile: Array of 3 cell property, with a format of <fill level, lut hi, lut lo> in ascending fill level indicating the qos luts for macrotile format on sspp. Zero fill level on the last entry identifies the default lut. - qcom,sde-qos-lut-nrt: Array of 3 cell property, with a format of <fill level, lut hi, lut lo> in ascending fill level indicating the qos luts for nrt (e.g wfd) on sspp. Zero fill level on the last entry identifies the default lut. - qcom,sde-qos-lut-cwb: Array of 3 cell property, with a format of <fill level, lut hi, lut lo> in ascending fill level indicating the qos luts for cwb on sspp. Zero fill level on the last entry identifies the default lut. Bus Scaling Subnodes: - qcom,sde-reg-bus: Property to provide Bus scaling for register access for Loading Loading @@ -471,8 +489,33 @@ Example: qcom,sde-wb-id = <2>; qcom,sde-wb-clk-ctrl = <0x2bc 16>; qcom,sde-sspp-danger-lut = <0x000f 0xffff 0x0000>; qcom,sde-sspp-safe-lut = <0xfffc 0xff00 0xffff>; qcom,sde-danger-lut = <0x0000000f 0x0000ffff 0x00000000 0x00000000>; qcom,sde-safe-lut = <0xfffc 0xff00 0xffff 0xffff>; qcom,sde-qos-lut-linear = <4 0x00000000 0x00000357>, <5 0x00000000 0x00003357>, <6 0x00000000 0x00023357>, <7 0x00000000 0x00223357>, <8 0x00000000 0x02223357>, <9 0x00000000 0x22223357>, <10 0x00000002 0x22223357>, <11 0x00000022 0x22223357>, <12 0x00000222 0x22223357>, <13 0x00002222 0x22223357>, <14 0x00012222 0x22223357>, <0 0x00112222 0x22223357>; qcom,sde-qos-lut-macrotile = <10 0x00000003 0x44556677>, <11 0x00000033 0x44556677>, <12 0x00000233 0x44556677>, <13 0x00002233 0x44556677>, <14 0x00012233 0x44556677>, <0 0x00112233 0x44556677>; qcom,sde-qos-lut-nrt = <0 0x00000000 0x00000000>; qcom,sde-qos-lut-cwb = <0 0x75300000 0x00000000>; qcom,sde-vbif-off = <0 0>; qcom,sde-vbif-id = <0 1>; Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.c +127 −37 Original line number Diff line number Diff line Loading @@ -79,7 +79,6 @@ /* maximum XIN halt timeout in usec */ #define VBIF_XIN_HALT_TIMEOUT 0x4000 #define DEFAULT_CREQ_LUT_NRT 0x0 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024) /* access property value based on prop_type and hardware index */ Loading Loading @@ -160,6 +159,12 @@ enum { PERF_DOWNSCALING_PREFILL_LINES, PERF_XTRA_PREFILL_LINES, PERF_AMORTIZABLE_THRESHOLD, PERF_DANGER_LUT, PERF_SAFE_LUT, PERF_QOS_LUT_LINEAR, PERF_QOS_LUT_MACROTILE, PERF_QOS_LUT_NRT, PERF_QOS_LUT_CWB, PERF_PROP_MAX, }; Loading @@ -170,8 +175,6 @@ enum { SSPP_XIN, SSPP_CLK_CTRL, SSPP_CLK_STATUS, SSPP_DANGER, SSPP_SAFE, SSPP_SCALE_SIZE, SSPP_VIG_BLOCKS, SSPP_RGB_BLOCKS, Loading Loading @@ -378,6 +381,16 @@ static struct sde_prop_type sde_perf_prop[] = { false, PROP_TYPE_U32}, {PERF_AMORTIZABLE_THRESHOLD, "qcom,sde-amortizable-threshold", false, PROP_TYPE_U32}, {PERF_DANGER_LUT, "qcom,sde-danger-lut", false, PROP_TYPE_U32_ARRAY}, {PERF_SAFE_LUT, "qcom,sde-safe-lut", false, PROP_TYPE_U32_ARRAY}, {PERF_QOS_LUT_LINEAR, "qcom,sde-qos-lut-linear", false, PROP_TYPE_U32_ARRAY}, {PERF_QOS_LUT_MACROTILE, "qcom,sde-qos-lut-macrotile", false, PROP_TYPE_U32_ARRAY}, {PERF_QOS_LUT_NRT, "qcom,sde-qos-lut-nrt", false, PROP_TYPE_U32_ARRAY}, {PERF_QOS_LUT_CWB, "qcom,sde-qos-lut-cwb", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type sspp_prop[] = { Loading @@ -389,8 +402,6 @@ static struct sde_prop_type sspp_prop[] = { PROP_TYPE_BIT_OFFSET_ARRAY}, {SSPP_CLK_STATUS, "qcom,sde-sspp-clk-status", false, PROP_TYPE_BIT_OFFSET_ARRAY}, {SSPP_DANGER, "qcom,sde-sspp-danger-lut", false, PROP_TYPE_U32_ARRAY}, {SSPP_SAFE, "qcom,sde-sspp-safe-lut", false, PROP_TYPE_U32_ARRAY}, {SSPP_SCALE_SIZE, "qcom,sde-sspp-scale-size", false, PROP_TYPE_U32}, {SSPP_VIG_BLOCKS, "qcom,sde-sspp-vig-blocks", false, PROP_TYPE_NODE}, {SSPP_RGB_BLOCKS, "qcom,sde-sspp-rgb-blocks", false, PROP_TYPE_NODE}, Loading Loading @@ -792,6 +803,8 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg, sspp->clk_ctrl = SDE_CLK_CTRL_VIG0 + *vig_count; sspp->type = SSPP_TYPE_VIG; set_bit(SDE_SSPP_QOS, &sspp->features); if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_SSPP_QOS_8LVL, &sspp->features); (*vig_count)++; if (!prop_value) Loading Loading @@ -884,6 +897,8 @@ static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg, sspp->clk_ctrl = SDE_CLK_CTRL_RGB0 + *rgb_count; sspp->type = SSPP_TYPE_RGB; set_bit(SDE_SSPP_QOS, &sspp->features); if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_SSPP_QOS_8LVL, &sspp->features); (*rgb_count)++; if (!prop_value) Loading Loading @@ -954,6 +969,8 @@ static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg, sspp->id - SSPP_VIG0); sspp->type = SSPP_TYPE_DMA; set_bit(SDE_SSPP_QOS, &sspp->features); if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_SSPP_QOS_8LVL, &sspp->features); (*dma_count)++; } Loading @@ -970,7 +987,6 @@ static int sde_sspp_parse_dt(struct device_node *np, struct sde_sspp_cfg *sspp; struct sde_sspp_sub_blks *sblk; u32 vig_count = 0, dma_count = 0, rgb_count = 0, cursor_count = 0; u32 danger_count = 0, safe_count = 0; struct device_node *snp = NULL; prop_value = kzalloc(SSPP_PROP_MAX * Loading @@ -985,16 +1001,6 @@ static int sde_sspp_parse_dt(struct device_node *np, if (rc) goto end; rc = _validate_dt_entry(np, &sspp_prop[SSPP_DANGER], 1, &prop_count[SSPP_DANGER], &danger_count); if (rc) goto end; rc = _validate_dt_entry(np, &sspp_prop[SSPP_SAFE], 1, &prop_count[SSPP_SAFE], &safe_count); if (rc) goto end; rc = _read_dt_entry(np, sspp_prop, ARRAY_SIZE(sspp_prop), prop_count, prop_exists, prop_value); if (rc) Loading Loading @@ -1099,19 +1105,6 @@ static int sde_sspp_parse_dt(struct device_node *np, sblk->maxvdeciexp = MAX_VERT_DECIMATION; sspp->xin_id = PROP_VALUE_ACCESS(prop_value, SSPP_XIN, i); sblk->danger_lut_linear = PROP_VALUE_ACCESS(prop_value, SSPP_DANGER, 0); sblk->danger_lut_tile = PROP_VALUE_ACCESS(prop_value, SSPP_DANGER, 1); sblk->danger_lut_nrt = PROP_VALUE_ACCESS(prop_value, SSPP_DANGER, 2); sblk->safe_lut_linear = PROP_VALUE_ACCESS(prop_value, SSPP_SAFE, 0); sblk->safe_lut_tile = PROP_VALUE_ACCESS(prop_value, SSPP_SAFE, 1); sblk->safe_lut_nrt = PROP_VALUE_ACCESS(prop_value, SSPP_SAFE, 2); sblk->creq_lut_nrt = DEFAULT_CREQ_LUT_NRT; sblk->pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE; sblk->src_blk.len = PROP_VALUE_ACCESS(prop_value, SSPP_SIZE, 0); Loading @@ -1134,15 +1127,8 @@ static int sde_sspp_parse_dt(struct device_node *np, } SDE_DEBUG( "xin:%d danger:%x/%x/%x safe:%x/%x/%x creq:%x ram:%d clk%d:%x/%d\n", "xin:%d ram:%d clk%d:%x/%d\n", sspp->xin_id, sblk->danger_lut_linear, sblk->danger_lut_tile, sblk->danger_lut_nrt, sblk->safe_lut_linear, sblk->safe_lut_tile, sblk->safe_lut_nrt, sblk->creq_lut_nrt, sblk->pixel_ram_size, sspp->clk_ctrl, sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].reg_off, Loading Loading @@ -1514,6 +1500,10 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) set_bit(SDE_WB_TRAFFIC_SHAPER, &wb->features); set_bit(SDE_WB_YUV_CONFIG, &wb->features); set_bit(SDE_WB_QOS, &wb->features); if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_WB_QOS_8LVL, &wb->features); if (sde_cfg->has_wb_ubwc) set_bit(SDE_WB_UBWC, &wb->features); Loading Loading @@ -2380,6 +2370,7 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) struct sde_prop_value *prop_value = NULL; bool prop_exists[PERF_PROP_MAX]; const char *str = NULL; int j, k; if (!cfg) { SDE_ERROR("invalid argument\n"); Loading @@ -2399,6 +2390,36 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_DANGER_LUT], 1, &prop_count[PERF_DANGER_LUT], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT], 1, &prop_count[PERF_SAFE_LUT], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_LINEAR], 1, &prop_count[PERF_QOS_LUT_LINEAR], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_MACROTILE], 1, &prop_count[PERF_QOS_LUT_MACROTILE], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_NRT], 1, &prop_count[PERF_QOS_LUT_NRT], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_CWB], 1, &prop_count[PERF_QOS_LUT_CWB], NULL); if (rc) goto freeprop; rc = _read_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop), prop_count, prop_exists, prop_value); if (rc) Loading Loading @@ -2472,6 +2493,72 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) PERF_AMORTIZABLE_THRESHOLD, 0) : DEFAULT_AMORTIZABLE_THRESHOLD; if (prop_exists[PERF_DANGER_LUT] && prop_count[PERF_DANGER_LUT] <= SDE_QOS_LUT_USAGE_MAX) { for (j = 0; j < prop_count[PERF_DANGER_LUT]; j++) { cfg->perf.danger_lut_tbl[j] = PROP_VALUE_ACCESS(prop_value, PERF_DANGER_LUT, j); SDE_DEBUG("danger usage:%d lut:0x%x\n", j, cfg->perf.danger_lut_tbl[j]); } } if (prop_exists[PERF_SAFE_LUT] && prop_count[PERF_SAFE_LUT] <= SDE_QOS_LUT_USAGE_MAX) { for (j = 0; j < prop_count[PERF_SAFE_LUT]; j++) { cfg->perf.safe_lut_tbl[j] = PROP_VALUE_ACCESS(prop_value, PERF_SAFE_LUT, j); SDE_DEBUG("safe usage:%d lut:0x%x\n", j, cfg->perf.safe_lut_tbl[j]); } } for (j = 0; j < SDE_QOS_LUT_USAGE_MAX; j++) { static const u32 prop_key[SDE_QOS_LUT_USAGE_MAX] = { [SDE_QOS_LUT_USAGE_LINEAR] = PERF_QOS_LUT_LINEAR, [SDE_QOS_LUT_USAGE_MACROTILE] = PERF_QOS_LUT_MACROTILE, [SDE_QOS_LUT_USAGE_NRT] = PERF_QOS_LUT_NRT, [SDE_QOS_LUT_USAGE_CWB] = PERF_QOS_LUT_CWB, }; const u32 entry_size = 3; int m, count; int key = prop_key[j]; if (!prop_exists[key]) continue; count = prop_count[key] / entry_size; cfg->perf.qos_lut_tbl[j].entries = kcalloc(count, sizeof(struct sde_qos_lut_entry), GFP_KERNEL); if (!cfg->perf.qos_lut_tbl[j].entries) { rc = -ENOMEM; goto end; } for (k = 0, m = 0; k < count; k++, m += entry_size) { u64 lut_hi, lut_lo; cfg->perf.qos_lut_tbl[j].entries[k].fl = PROP_VALUE_ACCESS(prop_value, key, m); lut_hi = PROP_VALUE_ACCESS(prop_value, key, m + 1); lut_lo = PROP_VALUE_ACCESS(prop_value, key, m + 2); cfg->perf.qos_lut_tbl[j].entries[k].lut = (lut_hi << 32) | lut_lo; SDE_DEBUG("usage:%d.%d fl:%d lut:0x%llx\n", j, k, cfg->perf.qos_lut_tbl[j].entries[k].fl, cfg->perf.qos_lut_tbl[j].entries[k].lut); } cfg->perf.qos_lut_tbl[j].nentry = count; } freeprop: kfree(prop_value); end: Loading Loading @@ -2639,6 +2726,9 @@ void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg) kfree(sde_cfg->vbif[i].qos_nrt_tbl.priority_lvl); } for (i = 0; i < SDE_QOS_LUT_USAGE_MAX; i++) kfree(sde_cfg->perf.qos_lut_tbl[i].entries); kfree(sde_cfg->dma_formats); kfree(sde_cfg->cursor_formats); kfree(sde_cfg->vig_formats); Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.h +43 −14 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ enum { * @SDE_SSPP_PCC, Color correction support * @SDE_SSPP_CURSOR, SSPP can be used as a cursor layer * @SDE_SSPP_QOS, SSPP support QoS control, danger/safe/creq * @SDE_SSPP_QOS_8LVL, SSPP support 8-level QoS control * @SDE_SSPP_EXCL_RECT, SSPP supports exclusion rect * @SDE_SSPP_SMART_DMA_V1, SmartDMA 1.0 support * @SDE_SSPP_SMART_DMA_V2, SmartDMA 2.0 support Loading @@ -128,6 +129,7 @@ enum { SDE_SSPP_PCC, SDE_SSPP_CURSOR, SDE_SSPP_QOS, SDE_SSPP_QOS_8LVL, SDE_SSPP_EXCL_RECT, SDE_SSPP_SMART_DMA_V1, SDE_SSPP_SMART_DMA_V2, Loading Loading @@ -241,6 +243,8 @@ enum { * @SDE_WB_PIPE_ALPHA Writeback supports pipe alpha * @SDE_WB_XY_ROI_OFFSET Writeback supports x/y-offset of out ROI in * the destination image * @SDE_WB_QOS, Writeback supports QoS control, danger/safe/creq * @SDE_WB_QOS_8LVL, Writeback supports 8-level QoS control * @SDE_WB_MAX maximum value */ enum { Loading @@ -256,6 +260,8 @@ enum { SDE_WB_YUV_CONFIG, SDE_WB_PIPE_ALPHA, SDE_WB_XY_ROI_OFFSET, SDE_WB_QOS, SDE_WB_QOS_8LVL, SDE_WB_MAX }; Loading Loading @@ -343,18 +349,42 @@ struct sde_format_extended { uint64_t modifier; }; /** * enum sde_qos_lut_usage - define QoS LUT use cases */ enum sde_qos_lut_usage { SDE_QOS_LUT_USAGE_LINEAR, SDE_QOS_LUT_USAGE_MACROTILE, SDE_QOS_LUT_USAGE_NRT, SDE_QOS_LUT_USAGE_CWB, SDE_QOS_LUT_USAGE_MAX, }; /** * struct sde_qos_lut_entry - define QoS LUT table entry * @fl: fill level, or zero on last entry to indicate default lut * @lut: lut to use if equal to or less than fill level */ struct sde_qos_lut_entry { u32 fl; u64 lut; }; /** * struct sde_qos_lut_tbl - define QoS LUT table * @nentry: number of entry in this table * @entries: Pointer to table entries */ struct sde_qos_lut_tbl { u32 nentry; struct sde_qos_lut_entry *entries; }; /** * struct sde_sspp_sub_blks : SSPP sub-blocks * @maxdwnscale: max downscale ratio supported(without DECIMATION) * @maxupscale: maxupscale ratio supported * @maxwidth: max pixelwidth supported by this pipe * @danger_lut_linear: LUT to generate danger signals for linear format * @safe_lut_linear: LUT to generate safe signals for linear format * @danger_lut_tile: LUT to generate danger signals for tile format * @safe_lut_tile: LUT to generate safe signals for tile format * @danger_lut_nrt: LUT to generate danger signals for non-realtime use case * @safe_lut_nrt: LUT to generate safe signals for non-realtime use case * @creq_lut_nrt: LUT to generate creq signals for non-realtime use case * @creq_vblank: creq priority during vertical blanking * @danger_vblank: danger priority during vertical blanking * @pixel_ram_size: size of latency hiding and de-tiling buffer in bytes Loading @@ -371,13 +401,6 @@ struct sde_format_extended { */ struct sde_sspp_sub_blks { u32 maxlinewidth; u32 danger_lut_linear; u32 safe_lut_linear; u32 danger_lut_tile; u32 safe_lut_tile; u32 danger_lut_nrt; u32 safe_lut_nrt; u32 creq_lut_nrt; u32 creq_vblank; u32 danger_vblank; u32 pixel_ram_size; Loading Loading @@ -722,6 +745,9 @@ struct sde_reg_dma_cfg { * @downscaling_prefill_lines downscaling latency in lines * @amortizable_theshold minimum y position for traffic shaping prefill * @min_prefill_lines minimum pipeline latency in lines * @safe_lut_tbl: LUT tables for safe signals * @danger_lut_tbl: LUT tables for danger signals * @qos_lut_tbl: LUT tables for QoS signals */ struct sde_perf_cfg { u32 max_bw_low; Loading @@ -739,6 +765,9 @@ struct sde_perf_cfg { u32 downscaling_prefill_lines; u32 amortizable_threshold; u32 min_prefill_lines; u32 safe_lut_tbl[SDE_QOS_LUT_USAGE_MAX]; u32 danger_lut_tbl[SDE_QOS_LUT_USAGE_MAX]; struct sde_qos_lut_tbl qos_lut_tbl[SDE_QOS_LUT_USAGE_MAX]; }; /** Loading drivers/gpu/drm/msm/sde/sde_hw_sspp.c +9 −1 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ #define SSPP_QOS_CTRL 0x6C #define SSPP_DECIMATION_CONFIG 0xB4 #define SSPP_SRC_ADDR_SW_STATUS 0x70 #define SSPP_CREQ_LUT_0 0x74 #define SSPP_CREQ_LUT_1 0x78 #define SSPP_SW_PIX_EXT_C0_LR 0x100 #define SSPP_SW_PIX_EXT_C0_TB 0x104 #define SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108 Loading Loading @@ -982,8 +984,14 @@ static void sde_hw_sspp_setup_creq_lut(struct sde_hw_pipe *ctx, if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx)) return; if (ctx->cap && test_bit(SDE_SSPP_QOS_8LVL, &ctx->cap->features)) { SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, cfg->creq_lut); SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_1 + idx, cfg->creq_lut >> 32); } else { SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut); } } static void sde_hw_sspp_setup_qos_ctrl(struct sde_hw_pipe *ctx, struct sde_hw_pipe_qos_cfg *cfg) Loading drivers/gpu/drm/msm/sde/sde_hw_sspp.h +1 −1 Original line number Diff line number Diff line Loading @@ -300,7 +300,7 @@ struct sde_hw_pipe_cfg { struct sde_hw_pipe_qos_cfg { u32 danger_lut; u32 safe_lut; u32 creq_lut; u64 creq_lut; u32 creq_vblank; u32 danger_vblank; bool vblank_en; Loading Loading
Documentation/devicetree/bindings/display/msm/sde.txt +49 −6 Original line number Diff line number Diff line Loading @@ -148,10 +148,6 @@ Optional properties: control register. Number of offsets defined should match the number of offsets defined in property: qcom,sde-sspp-off. - qcom,sde-sspp-danger-lut: A 3 cell property, with a format of <linear, tile, nrt>, indicating the danger luts on sspp. - qcom,sde-sspp-safe-lut: A 3 cell property, with a format of <linear, tile, nrt>, indicating the safe luts on sspp. - qcom,sde-sspp-excl-rect: Array of u32 values indicating exclusion rectangle support on each sspp. - qcom,sde-sspp-smart-dma-priority: Array of u32 values indicating hw pipe Loading Loading @@ -301,6 +297,28 @@ Optional properties: priority for realtime clients. - qcom,sde-vbif-qos-nrt-remap: This array is used to program vbif qos remapper register priority for non-realtime clients. - qcom,sde-danger-lut: A 4 cell property, with a format of <linear, tile, nrt, cwb>, indicating the danger luts on sspp. - qcom,sde-safe-lut: A 4 cell property, with a format of <linear, tile, nrt, cwb>, indicating the safe luts on sspp. - qcom,sde-qos-lut-linear: Array of 3 cell property, with a format of <fill level, lut hi, lut lo> in ascending fill level indicating the qos luts for linear format on sspp. Zero fill level on the last entry identifies the default lut. - qcom,sde-qos-lut-macrotile: Array of 3 cell property, with a format of <fill level, lut hi, lut lo> in ascending fill level indicating the qos luts for macrotile format on sspp. Zero fill level on the last entry identifies the default lut. - qcom,sde-qos-lut-nrt: Array of 3 cell property, with a format of <fill level, lut hi, lut lo> in ascending fill level indicating the qos luts for nrt (e.g wfd) on sspp. Zero fill level on the last entry identifies the default lut. - qcom,sde-qos-lut-cwb: Array of 3 cell property, with a format of <fill level, lut hi, lut lo> in ascending fill level indicating the qos luts for cwb on sspp. Zero fill level on the last entry identifies the default lut. Bus Scaling Subnodes: - qcom,sde-reg-bus: Property to provide Bus scaling for register access for Loading Loading @@ -471,8 +489,33 @@ Example: qcom,sde-wb-id = <2>; qcom,sde-wb-clk-ctrl = <0x2bc 16>; qcom,sde-sspp-danger-lut = <0x000f 0xffff 0x0000>; qcom,sde-sspp-safe-lut = <0xfffc 0xff00 0xffff>; qcom,sde-danger-lut = <0x0000000f 0x0000ffff 0x00000000 0x00000000>; qcom,sde-safe-lut = <0xfffc 0xff00 0xffff 0xffff>; qcom,sde-qos-lut-linear = <4 0x00000000 0x00000357>, <5 0x00000000 0x00003357>, <6 0x00000000 0x00023357>, <7 0x00000000 0x00223357>, <8 0x00000000 0x02223357>, <9 0x00000000 0x22223357>, <10 0x00000002 0x22223357>, <11 0x00000022 0x22223357>, <12 0x00000222 0x22223357>, <13 0x00002222 0x22223357>, <14 0x00012222 0x22223357>, <0 0x00112222 0x22223357>; qcom,sde-qos-lut-macrotile = <10 0x00000003 0x44556677>, <11 0x00000033 0x44556677>, <12 0x00000233 0x44556677>, <13 0x00002233 0x44556677>, <14 0x00012233 0x44556677>, <0 0x00112233 0x44556677>; qcom,sde-qos-lut-nrt = <0 0x00000000 0x00000000>; qcom,sde-qos-lut-cwb = <0 0x75300000 0x00000000>; qcom,sde-vbif-off = <0 0>; qcom,sde-vbif-id = <0 1>; Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.c +127 −37 Original line number Diff line number Diff line Loading @@ -79,7 +79,6 @@ /* maximum XIN halt timeout in usec */ #define VBIF_XIN_HALT_TIMEOUT 0x4000 #define DEFAULT_CREQ_LUT_NRT 0x0 #define DEFAULT_PIXEL_RAM_SIZE (50 * 1024) /* access property value based on prop_type and hardware index */ Loading Loading @@ -160,6 +159,12 @@ enum { PERF_DOWNSCALING_PREFILL_LINES, PERF_XTRA_PREFILL_LINES, PERF_AMORTIZABLE_THRESHOLD, PERF_DANGER_LUT, PERF_SAFE_LUT, PERF_QOS_LUT_LINEAR, PERF_QOS_LUT_MACROTILE, PERF_QOS_LUT_NRT, PERF_QOS_LUT_CWB, PERF_PROP_MAX, }; Loading @@ -170,8 +175,6 @@ enum { SSPP_XIN, SSPP_CLK_CTRL, SSPP_CLK_STATUS, SSPP_DANGER, SSPP_SAFE, SSPP_SCALE_SIZE, SSPP_VIG_BLOCKS, SSPP_RGB_BLOCKS, Loading Loading @@ -378,6 +381,16 @@ static struct sde_prop_type sde_perf_prop[] = { false, PROP_TYPE_U32}, {PERF_AMORTIZABLE_THRESHOLD, "qcom,sde-amortizable-threshold", false, PROP_TYPE_U32}, {PERF_DANGER_LUT, "qcom,sde-danger-lut", false, PROP_TYPE_U32_ARRAY}, {PERF_SAFE_LUT, "qcom,sde-safe-lut", false, PROP_TYPE_U32_ARRAY}, {PERF_QOS_LUT_LINEAR, "qcom,sde-qos-lut-linear", false, PROP_TYPE_U32_ARRAY}, {PERF_QOS_LUT_MACROTILE, "qcom,sde-qos-lut-macrotile", false, PROP_TYPE_U32_ARRAY}, {PERF_QOS_LUT_NRT, "qcom,sde-qos-lut-nrt", false, PROP_TYPE_U32_ARRAY}, {PERF_QOS_LUT_CWB, "qcom,sde-qos-lut-cwb", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type sspp_prop[] = { Loading @@ -389,8 +402,6 @@ static struct sde_prop_type sspp_prop[] = { PROP_TYPE_BIT_OFFSET_ARRAY}, {SSPP_CLK_STATUS, "qcom,sde-sspp-clk-status", false, PROP_TYPE_BIT_OFFSET_ARRAY}, {SSPP_DANGER, "qcom,sde-sspp-danger-lut", false, PROP_TYPE_U32_ARRAY}, {SSPP_SAFE, "qcom,sde-sspp-safe-lut", false, PROP_TYPE_U32_ARRAY}, {SSPP_SCALE_SIZE, "qcom,sde-sspp-scale-size", false, PROP_TYPE_U32}, {SSPP_VIG_BLOCKS, "qcom,sde-sspp-vig-blocks", false, PROP_TYPE_NODE}, {SSPP_RGB_BLOCKS, "qcom,sde-sspp-rgb-blocks", false, PROP_TYPE_NODE}, Loading Loading @@ -792,6 +803,8 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg, sspp->clk_ctrl = SDE_CLK_CTRL_VIG0 + *vig_count; sspp->type = SSPP_TYPE_VIG; set_bit(SDE_SSPP_QOS, &sspp->features); if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_SSPP_QOS_8LVL, &sspp->features); (*vig_count)++; if (!prop_value) Loading Loading @@ -884,6 +897,8 @@ static void _sde_sspp_setup_rgb(struct sde_mdss_cfg *sde_cfg, sspp->clk_ctrl = SDE_CLK_CTRL_RGB0 + *rgb_count; sspp->type = SSPP_TYPE_RGB; set_bit(SDE_SSPP_QOS, &sspp->features); if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_SSPP_QOS_8LVL, &sspp->features); (*rgb_count)++; if (!prop_value) Loading Loading @@ -954,6 +969,8 @@ static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg, sspp->id - SSPP_VIG0); sspp->type = SSPP_TYPE_DMA; set_bit(SDE_SSPP_QOS, &sspp->features); if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_SSPP_QOS_8LVL, &sspp->features); (*dma_count)++; } Loading @@ -970,7 +987,6 @@ static int sde_sspp_parse_dt(struct device_node *np, struct sde_sspp_cfg *sspp; struct sde_sspp_sub_blks *sblk; u32 vig_count = 0, dma_count = 0, rgb_count = 0, cursor_count = 0; u32 danger_count = 0, safe_count = 0; struct device_node *snp = NULL; prop_value = kzalloc(SSPP_PROP_MAX * Loading @@ -985,16 +1001,6 @@ static int sde_sspp_parse_dt(struct device_node *np, if (rc) goto end; rc = _validate_dt_entry(np, &sspp_prop[SSPP_DANGER], 1, &prop_count[SSPP_DANGER], &danger_count); if (rc) goto end; rc = _validate_dt_entry(np, &sspp_prop[SSPP_SAFE], 1, &prop_count[SSPP_SAFE], &safe_count); if (rc) goto end; rc = _read_dt_entry(np, sspp_prop, ARRAY_SIZE(sspp_prop), prop_count, prop_exists, prop_value); if (rc) Loading Loading @@ -1099,19 +1105,6 @@ static int sde_sspp_parse_dt(struct device_node *np, sblk->maxvdeciexp = MAX_VERT_DECIMATION; sspp->xin_id = PROP_VALUE_ACCESS(prop_value, SSPP_XIN, i); sblk->danger_lut_linear = PROP_VALUE_ACCESS(prop_value, SSPP_DANGER, 0); sblk->danger_lut_tile = PROP_VALUE_ACCESS(prop_value, SSPP_DANGER, 1); sblk->danger_lut_nrt = PROP_VALUE_ACCESS(prop_value, SSPP_DANGER, 2); sblk->safe_lut_linear = PROP_VALUE_ACCESS(prop_value, SSPP_SAFE, 0); sblk->safe_lut_tile = PROP_VALUE_ACCESS(prop_value, SSPP_SAFE, 1); sblk->safe_lut_nrt = PROP_VALUE_ACCESS(prop_value, SSPP_SAFE, 2); sblk->creq_lut_nrt = DEFAULT_CREQ_LUT_NRT; sblk->pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE; sblk->src_blk.len = PROP_VALUE_ACCESS(prop_value, SSPP_SIZE, 0); Loading @@ -1134,15 +1127,8 @@ static int sde_sspp_parse_dt(struct device_node *np, } SDE_DEBUG( "xin:%d danger:%x/%x/%x safe:%x/%x/%x creq:%x ram:%d clk%d:%x/%d\n", "xin:%d ram:%d clk%d:%x/%d\n", sspp->xin_id, sblk->danger_lut_linear, sblk->danger_lut_tile, sblk->danger_lut_nrt, sblk->safe_lut_linear, sblk->safe_lut_tile, sblk->safe_lut_nrt, sblk->creq_lut_nrt, sblk->pixel_ram_size, sspp->clk_ctrl, sde_cfg->mdp[0].clk_ctrls[sspp->clk_ctrl].reg_off, Loading Loading @@ -1514,6 +1500,10 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) set_bit(SDE_WB_TRAFFIC_SHAPER, &wb->features); set_bit(SDE_WB_YUV_CONFIG, &wb->features); set_bit(SDE_WB_QOS, &wb->features); if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_WB_QOS_8LVL, &wb->features); if (sde_cfg->has_wb_ubwc) set_bit(SDE_WB_UBWC, &wb->features); Loading Loading @@ -2380,6 +2370,7 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) struct sde_prop_value *prop_value = NULL; bool prop_exists[PERF_PROP_MAX]; const char *str = NULL; int j, k; if (!cfg) { SDE_ERROR("invalid argument\n"); Loading @@ -2399,6 +2390,36 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_DANGER_LUT], 1, &prop_count[PERF_DANGER_LUT], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_SAFE_LUT], 1, &prop_count[PERF_SAFE_LUT], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_LINEAR], 1, &prop_count[PERF_QOS_LUT_LINEAR], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_MACROTILE], 1, &prop_count[PERF_QOS_LUT_MACROTILE], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_NRT], 1, &prop_count[PERF_QOS_LUT_NRT], NULL); if (rc) goto freeprop; rc = _validate_dt_entry(np, &sde_perf_prop[PERF_QOS_LUT_CWB], 1, &prop_count[PERF_QOS_LUT_CWB], NULL); if (rc) goto freeprop; rc = _read_dt_entry(np, sde_perf_prop, ARRAY_SIZE(sde_perf_prop), prop_count, prop_exists, prop_value); if (rc) Loading Loading @@ -2472,6 +2493,72 @@ static int sde_perf_parse_dt(struct device_node *np, struct sde_mdss_cfg *cfg) PERF_AMORTIZABLE_THRESHOLD, 0) : DEFAULT_AMORTIZABLE_THRESHOLD; if (prop_exists[PERF_DANGER_LUT] && prop_count[PERF_DANGER_LUT] <= SDE_QOS_LUT_USAGE_MAX) { for (j = 0; j < prop_count[PERF_DANGER_LUT]; j++) { cfg->perf.danger_lut_tbl[j] = PROP_VALUE_ACCESS(prop_value, PERF_DANGER_LUT, j); SDE_DEBUG("danger usage:%d lut:0x%x\n", j, cfg->perf.danger_lut_tbl[j]); } } if (prop_exists[PERF_SAFE_LUT] && prop_count[PERF_SAFE_LUT] <= SDE_QOS_LUT_USAGE_MAX) { for (j = 0; j < prop_count[PERF_SAFE_LUT]; j++) { cfg->perf.safe_lut_tbl[j] = PROP_VALUE_ACCESS(prop_value, PERF_SAFE_LUT, j); SDE_DEBUG("safe usage:%d lut:0x%x\n", j, cfg->perf.safe_lut_tbl[j]); } } for (j = 0; j < SDE_QOS_LUT_USAGE_MAX; j++) { static const u32 prop_key[SDE_QOS_LUT_USAGE_MAX] = { [SDE_QOS_LUT_USAGE_LINEAR] = PERF_QOS_LUT_LINEAR, [SDE_QOS_LUT_USAGE_MACROTILE] = PERF_QOS_LUT_MACROTILE, [SDE_QOS_LUT_USAGE_NRT] = PERF_QOS_LUT_NRT, [SDE_QOS_LUT_USAGE_CWB] = PERF_QOS_LUT_CWB, }; const u32 entry_size = 3; int m, count; int key = prop_key[j]; if (!prop_exists[key]) continue; count = prop_count[key] / entry_size; cfg->perf.qos_lut_tbl[j].entries = kcalloc(count, sizeof(struct sde_qos_lut_entry), GFP_KERNEL); if (!cfg->perf.qos_lut_tbl[j].entries) { rc = -ENOMEM; goto end; } for (k = 0, m = 0; k < count; k++, m += entry_size) { u64 lut_hi, lut_lo; cfg->perf.qos_lut_tbl[j].entries[k].fl = PROP_VALUE_ACCESS(prop_value, key, m); lut_hi = PROP_VALUE_ACCESS(prop_value, key, m + 1); lut_lo = PROP_VALUE_ACCESS(prop_value, key, m + 2); cfg->perf.qos_lut_tbl[j].entries[k].lut = (lut_hi << 32) | lut_lo; SDE_DEBUG("usage:%d.%d fl:%d lut:0x%llx\n", j, k, cfg->perf.qos_lut_tbl[j].entries[k].fl, cfg->perf.qos_lut_tbl[j].entries[k].lut); } cfg->perf.qos_lut_tbl[j].nentry = count; } freeprop: kfree(prop_value); end: Loading Loading @@ -2639,6 +2726,9 @@ void sde_hw_catalog_deinit(struct sde_mdss_cfg *sde_cfg) kfree(sde_cfg->vbif[i].qos_nrt_tbl.priority_lvl); } for (i = 0; i < SDE_QOS_LUT_USAGE_MAX; i++) kfree(sde_cfg->perf.qos_lut_tbl[i].entries); kfree(sde_cfg->dma_formats); kfree(sde_cfg->cursor_formats); kfree(sde_cfg->vig_formats); Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.h +43 −14 Original line number Diff line number Diff line Loading @@ -107,6 +107,7 @@ enum { * @SDE_SSPP_PCC, Color correction support * @SDE_SSPP_CURSOR, SSPP can be used as a cursor layer * @SDE_SSPP_QOS, SSPP support QoS control, danger/safe/creq * @SDE_SSPP_QOS_8LVL, SSPP support 8-level QoS control * @SDE_SSPP_EXCL_RECT, SSPP supports exclusion rect * @SDE_SSPP_SMART_DMA_V1, SmartDMA 1.0 support * @SDE_SSPP_SMART_DMA_V2, SmartDMA 2.0 support Loading @@ -128,6 +129,7 @@ enum { SDE_SSPP_PCC, SDE_SSPP_CURSOR, SDE_SSPP_QOS, SDE_SSPP_QOS_8LVL, SDE_SSPP_EXCL_RECT, SDE_SSPP_SMART_DMA_V1, SDE_SSPP_SMART_DMA_V2, Loading Loading @@ -241,6 +243,8 @@ enum { * @SDE_WB_PIPE_ALPHA Writeback supports pipe alpha * @SDE_WB_XY_ROI_OFFSET Writeback supports x/y-offset of out ROI in * the destination image * @SDE_WB_QOS, Writeback supports QoS control, danger/safe/creq * @SDE_WB_QOS_8LVL, Writeback supports 8-level QoS control * @SDE_WB_MAX maximum value */ enum { Loading @@ -256,6 +260,8 @@ enum { SDE_WB_YUV_CONFIG, SDE_WB_PIPE_ALPHA, SDE_WB_XY_ROI_OFFSET, SDE_WB_QOS, SDE_WB_QOS_8LVL, SDE_WB_MAX }; Loading Loading @@ -343,18 +349,42 @@ struct sde_format_extended { uint64_t modifier; }; /** * enum sde_qos_lut_usage - define QoS LUT use cases */ enum sde_qos_lut_usage { SDE_QOS_LUT_USAGE_LINEAR, SDE_QOS_LUT_USAGE_MACROTILE, SDE_QOS_LUT_USAGE_NRT, SDE_QOS_LUT_USAGE_CWB, SDE_QOS_LUT_USAGE_MAX, }; /** * struct sde_qos_lut_entry - define QoS LUT table entry * @fl: fill level, or zero on last entry to indicate default lut * @lut: lut to use if equal to or less than fill level */ struct sde_qos_lut_entry { u32 fl; u64 lut; }; /** * struct sde_qos_lut_tbl - define QoS LUT table * @nentry: number of entry in this table * @entries: Pointer to table entries */ struct sde_qos_lut_tbl { u32 nentry; struct sde_qos_lut_entry *entries; }; /** * struct sde_sspp_sub_blks : SSPP sub-blocks * @maxdwnscale: max downscale ratio supported(without DECIMATION) * @maxupscale: maxupscale ratio supported * @maxwidth: max pixelwidth supported by this pipe * @danger_lut_linear: LUT to generate danger signals for linear format * @safe_lut_linear: LUT to generate safe signals for linear format * @danger_lut_tile: LUT to generate danger signals for tile format * @safe_lut_tile: LUT to generate safe signals for tile format * @danger_lut_nrt: LUT to generate danger signals for non-realtime use case * @safe_lut_nrt: LUT to generate safe signals for non-realtime use case * @creq_lut_nrt: LUT to generate creq signals for non-realtime use case * @creq_vblank: creq priority during vertical blanking * @danger_vblank: danger priority during vertical blanking * @pixel_ram_size: size of latency hiding and de-tiling buffer in bytes Loading @@ -371,13 +401,6 @@ struct sde_format_extended { */ struct sde_sspp_sub_blks { u32 maxlinewidth; u32 danger_lut_linear; u32 safe_lut_linear; u32 danger_lut_tile; u32 safe_lut_tile; u32 danger_lut_nrt; u32 safe_lut_nrt; u32 creq_lut_nrt; u32 creq_vblank; u32 danger_vblank; u32 pixel_ram_size; Loading Loading @@ -722,6 +745,9 @@ struct sde_reg_dma_cfg { * @downscaling_prefill_lines downscaling latency in lines * @amortizable_theshold minimum y position for traffic shaping prefill * @min_prefill_lines minimum pipeline latency in lines * @safe_lut_tbl: LUT tables for safe signals * @danger_lut_tbl: LUT tables for danger signals * @qos_lut_tbl: LUT tables for QoS signals */ struct sde_perf_cfg { u32 max_bw_low; Loading @@ -739,6 +765,9 @@ struct sde_perf_cfg { u32 downscaling_prefill_lines; u32 amortizable_threshold; u32 min_prefill_lines; u32 safe_lut_tbl[SDE_QOS_LUT_USAGE_MAX]; u32 danger_lut_tbl[SDE_QOS_LUT_USAGE_MAX]; struct sde_qos_lut_tbl qos_lut_tbl[SDE_QOS_LUT_USAGE_MAX]; }; /** Loading
drivers/gpu/drm/msm/sde/sde_hw_sspp.c +9 −1 Original line number Diff line number Diff line Loading @@ -70,6 +70,8 @@ #define SSPP_QOS_CTRL 0x6C #define SSPP_DECIMATION_CONFIG 0xB4 #define SSPP_SRC_ADDR_SW_STATUS 0x70 #define SSPP_CREQ_LUT_0 0x74 #define SSPP_CREQ_LUT_1 0x78 #define SSPP_SW_PIX_EXT_C0_LR 0x100 #define SSPP_SW_PIX_EXT_C0_TB 0x104 #define SSPP_SW_PIX_EXT_C0_REQ_PIXELS 0x108 Loading Loading @@ -982,8 +984,14 @@ static void sde_hw_sspp_setup_creq_lut(struct sde_hw_pipe *ctx, if (_sspp_subblk_offset(ctx, SDE_SSPP_SRC, &idx)) return; if (ctx->cap && test_bit(SDE_SSPP_QOS_8LVL, &ctx->cap->features)) { SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_0 + idx, cfg->creq_lut); SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT_1 + idx, cfg->creq_lut >> 32); } else { SDE_REG_WRITE(&ctx->hw, SSPP_CREQ_LUT + idx, cfg->creq_lut); } } static void sde_hw_sspp_setup_qos_ctrl(struct sde_hw_pipe *ctx, struct sde_hw_pipe_qos_cfg *cfg) Loading
drivers/gpu/drm/msm/sde/sde_hw_sspp.h +1 −1 Original line number Diff line number Diff line Loading @@ -300,7 +300,7 @@ struct sde_hw_pipe_cfg { struct sde_hw_pipe_qos_cfg { u32 danger_lut; u32 safe_lut; u32 creq_lut; u64 creq_lut; u32 creq_vblank; u32 danger_vblank; bool vblank_en; Loading