Loading Documentation/devicetree/bindings/display/msm/sde.txt +24 −1 Original line number Diff line number Diff line Loading @@ -212,11 +212,23 @@ Optional properties: -- qcom,sde-vig-pcc: offset and version of PCC hardware -- qcom,sde-vig-hsic: offset and version of global PA adjustment -- qcom,sde-vig-memcolor: offset and version of PA memcolor hardware -- qcom,sde-vig-gamut: offset and version of 3D LUT Gamut hardware -- qcom,sde-vig-igc: offset and version of 1D LUT IGC hardware - qcom,sde-sspp-dma-blocks: A node that lists the blocks inside the DMA hardware. There can be more than one instance of this binding, in which case the entry would be appended with dgm entry index. Each entry will contain the offset and version (if needed) of each feature block. The presence of a block entry indicates that the SSPP DMA contains that feature hardware. e.g. qcom,sde-sspp-dma-blocks -- dgm@0 -- qcom,sde-dma-igc: offset and version of DMA IGC -- qcom,sde-dma-gc: offset and version of DMA GC - qcom,sde-sspp-rgb-blocks: A node that lists the blocks inside the RGB hardware. The block entries will contain the offset and version (if needed) of each feature block. The presence of a block entry indicates that the SSPP RGB contains that feature hardware. e.g. qcom,sde-sspp-vig-blocks e.g. qcom,sde-sspp-rgb-blocks -- qcom,sde-rgb-scaler-off: offset of RGB scaler hardware -- qcom,sde-rgb-scaler-size: A u32 address range for scaler. -- qcom,sde-rgb-pcc: offset and version of PCC hardware Loading Loading @@ -670,6 +682,17 @@ Example: qcom,sde-vig-pcc = <0x1780 0x00010000>; }; qcom,sde-sspp-dma-blocks { dgm@0 { qcom,sde-dma-igc = <0x400 0x00050000>; qcom,sde-dma-gc = <0x600 0x00050000>; } dgm@1 { qcom,sde-dma-igc = <0x1400 0x00050000>; qcom,sde-dma-gc = <0x600 0x00050000>; } }; qcom,sde-sspp-rgb-blocks { qcom,sde-rgb-scaler-off = <0x200>; qcom,sde-rgb-scaler-size = <0x74>; Loading drivers/gpu/drm/msm/msm_drv.h +4 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,10 @@ enum msm_mdp_plane_property { PLANE_PROP_SKIN_COLOR, PLANE_PROP_SKY_COLOR, PLANE_PROP_FOLIAGE_COLOR, PLANE_PROP_VIG_GAMUT, PLANE_PROP_VIG_IGC, PLANE_PROP_DMA_IGC, PLANE_PROP_DMA_GC, PLANE_PROP_ROT_CAPS_V1, /* # of blob properties */ Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.c +124 −4 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -195,6 +195,7 @@ enum { SSPP_SCALE_SIZE, SSPP_VIG_BLOCKS, SSPP_RGB_BLOCKS, SSPP_DMA_BLOCKS, SSPP_EXCL_RECT, SSPP_SMART_DMA, SSPP_MAX_PER_PIPE_BW, Loading @@ -208,6 +209,8 @@ enum { VIG_HSIC_PROP, VIG_MEMCOLOR_PROP, VIG_PCC_PROP, VIG_GAMUT_PROP, VIG_IGC_PROP, VIG_PROP_MAX, }; Loading @@ -218,6 +221,12 @@ enum { RGB_PROP_MAX, }; enum { DMA_IGC_PROP, DMA_GC_PROP, DMA_PROP_MAX, }; enum { INTF_OFF, INTF_LEN, Loading Loading @@ -473,6 +482,7 @@ static struct sde_prop_type sspp_prop[] = { {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}, {SSPP_DMA_BLOCKS, "qcom,sde-sspp-dma-blocks", false, PROP_TYPE_NODE}, {SSPP_EXCL_RECT, "qcom,sde-sspp-excl-rect", false, PROP_TYPE_U32_ARRAY}, {SSPP_SMART_DMA, "qcom,sde-sspp-smart-dma-priority", false, PROP_TYPE_U32_ARRAY}, Loading @@ -488,6 +498,8 @@ static struct sde_prop_type vig_prop[] = { {VIG_MEMCOLOR_PROP, "qcom,sde-vig-memcolor", false, PROP_TYPE_U32_ARRAY}, {VIG_PCC_PROP, "qcom,sde-vig-pcc", false, PROP_TYPE_U32_ARRAY}, {VIG_GAMUT_PROP, "qcom,sde-vig-gamut", false, PROP_TYPE_U32_ARRAY}, {VIG_IGC_PROP, "qcom,sde-vig-igc", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type rgb_prop[] = { Loading @@ -496,6 +508,11 @@ static struct sde_prop_type rgb_prop[] = { {RGB_PCC_PROP, "qcom,sde-rgb-pcc", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type dma_prop[] = { {DMA_IGC_PROP, "qcom,sde-dma-igc", false, PROP_TYPE_U32_ARRAY}, {DMA_GC_PROP, "qcom,sde-dma-gc", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type ctl_prop[] = { {HW_OFF, "qcom,sde-ctl-off", true, PROP_TYPE_U32_ARRAY}, {HW_LEN, "qcom,sde-ctl-size", false, PROP_TYPE_U32}, Loading Loading @@ -1010,6 +1027,30 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg, set_bit(SDE_SSPP_PCC, &sspp->features); } if (prop_exists[VIG_GAMUT_PROP]) { sblk->gamut_blk.id = SDE_SSPP_VIG_GAMUT; snprintf(sblk->gamut_blk.name, SDE_HW_BLK_NAME_LEN, "sspp_vig_gamut%u", sspp->id - SSPP_VIG0); sblk->gamut_blk.base = PROP_VALUE_ACCESS(prop_value, VIG_GAMUT_PROP, 0); sblk->gamut_blk.version = PROP_VALUE_ACCESS(prop_value, VIG_GAMUT_PROP, 1); sblk->gamut_blk.len = 0; set_bit(SDE_SSPP_VIG_GAMUT, &sspp->features); } if (prop_exists[VIG_IGC_PROP]) { sblk->igc_blk[0].id = SDE_SSPP_VIG_IGC; snprintf(sblk->igc_blk[0].name, SDE_HW_BLK_NAME_LEN, "sspp_vig_igc%u", sspp->id - SSPP_VIG0); sblk->igc_blk[0].base = PROP_VALUE_ACCESS(prop_value, VIG_IGC_PROP, 0); sblk->igc_blk[0].version = PROP_VALUE_ACCESS(prop_value, VIG_IGC_PROP, 1); sblk->igc_blk[0].len = 0; set_bit(SDE_SSPP_VIG_IGC, &sspp->features); } sblk->format_list = sde_cfg->vig_formats; sblk->virt_format_list = sde_cfg->dma_formats; } Loading Loading @@ -1089,8 +1130,11 @@ static void _sde_sspp_setup_cursor(struct sde_mdss_cfg *sde_cfg, static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg, struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk, struct sde_prop_value *prop_value, u32 *dma_count) bool prop_exists[][DMA_PROP_MAX], struct sde_prop_value *prop_value, u32 *dma_count, u32 dgm_count) { u32 i = 0; sblk->maxupscale = SSPP_UNITY_SCALE; sblk->maxdwnscale = SSPP_UNITY_SCALE; sblk->format_list = sde_cfg->dma_formats; Loading @@ -1104,6 +1148,60 @@ static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg, if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_SSPP_QOS_8LVL, &sspp->features); (*dma_count)++; if (!prop_value) return; sblk->num_igc_blk = dgm_count; sblk->num_gc_blk = dgm_count; for (i = 0; i < dgm_count; i++) { if (prop_exists[i][DMA_IGC_PROP]) { sblk->igc_blk[i].id = SDE_SSPP_DMA_IGC; snprintf(sblk->igc_blk[i].name, SDE_HW_BLK_NAME_LEN, "sspp_dma_igc%u", sspp->id - SSPP_DMA0); sblk->igc_blk[i].base = PROP_VALUE_ACCESS( &prop_value[i * DMA_PROP_MAX], DMA_IGC_PROP, 0); sblk->igc_blk[i].version = PROP_VALUE_ACCESS( &prop_value[i * DMA_PROP_MAX], DMA_IGC_PROP, 1); sblk->igc_blk[i].len = 0; set_bit(SDE_SSPP_DMA_IGC, &sspp->features); } if (prop_exists[i][DMA_GC_PROP]) { sblk->gc_blk[i].id = SDE_SSPP_DMA_GC; snprintf(sblk->gc_blk[0].name, SDE_HW_BLK_NAME_LEN, "sspp_dma_gc%u", sspp->id - SSPP_DMA0); sblk->gc_blk[i].base = PROP_VALUE_ACCESS( &prop_value[i * DMA_PROP_MAX], DMA_GC_PROP, 0); sblk->gc_blk[i].version = PROP_VALUE_ACCESS( &prop_value[i * DMA_PROP_MAX], DMA_GC_PROP, 1); sblk->gc_blk[i].len = 0; set_bit(SDE_SSPP_DMA_GC, &sspp->features); } } } static int sde_dgm_parse_dt(struct device_node *np, u32 index, struct sde_prop_value *prop_value, bool *prop_exists) { int rc = 0; u32 child_idx = 0; int prop_count[DMA_PROP_MAX] = {0}; struct device_node *dgm_snp = NULL; for_each_child_of_node(np, dgm_snp) { if (index != child_idx++) continue; rc = _validate_dt_entry(dgm_snp, dma_prop, ARRAY_SIZE(dma_prop), prop_count, NULL); if (rc) return rc; rc = _read_dt_entry(dgm_snp, dma_prop, ARRAY_SIZE(dma_prop), prop_count, prop_exists, prop_value); } return rc; } static int sde_sspp_parse_dt(struct device_node *np, Loading @@ -1113,12 +1211,15 @@ static int sde_sspp_parse_dt(struct device_node *np, int vig_prop_count[VIG_PROP_MAX], rgb_prop_count[RGB_PROP_MAX]; bool prop_exists[SSPP_PROP_MAX], vig_prop_exists[VIG_PROP_MAX]; bool rgb_prop_exists[RGB_PROP_MAX]; bool dgm_prop_exists[SSPP_SUBBLK_COUNT_MAX][DMA_PROP_MAX]; struct sde_prop_value *prop_value = NULL; struct sde_prop_value *vig_prop_value = NULL, *rgb_prop_value = NULL; struct sde_prop_value *dgm_prop_value = NULL; const char *type; 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 dgm_count = 0; struct device_node *snp = NULL; prop_value = kcalloc(SSPP_PROP_MAX, Loading Loading @@ -1177,6 +1278,23 @@ static int sde_sspp_parse_dt(struct device_node *np, rgb_prop_value); } /* get dma feature dt properties if they exist */ snp = of_get_child_by_name(np, sspp_prop[SSPP_DMA_BLOCKS].prop_name); if (snp) { dgm_count = of_get_child_count(snp); if (dgm_count > 0 && dgm_count <= SSPP_SUBBLK_COUNT_MAX) { dgm_prop_value = kzalloc(dgm_count * DMA_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!dgm_prop_value) return -ENOMEM; for (i = 0; i < dgm_count; i++) sde_dgm_parse_dt(snp, i, &dgm_prop_value[i * DMA_PROP_MAX], &dgm_prop_exists[i][0]); } } for (i = 0; i < off_count; i++) { sspp = sde_cfg->sspp + i; sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); Loading Loading @@ -1225,8 +1343,9 @@ static int sde_sspp_parse_dt(struct device_node *np, &cursor_count); } else if (!strcmp(type, "dma")) { /* No prop values for DMA pipes */ _sde_sspp_setup_dma(sde_cfg, sspp, sblk, NULL, &dma_count); _sde_sspp_setup_dma(sde_cfg, sspp, sblk, dgm_prop_exists, dgm_prop_value, &dma_count, dgm_count); } else { SDE_ERROR("invalid sspp type:%s\n", type); rc = -EINVAL; Loading Loading @@ -1281,6 +1400,7 @@ static int sde_sspp_parse_dt(struct device_node *np, kfree(prop_value); kfree(vig_prop_value); kfree(rgb_prop_value); kfree(dgm_prop_value); return rc; } Loading drivers/gpu/drm/msm/sde/sde_hw_catalog.h +12 −2 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ #define SDE_COLOR_PROCESS_MINOR(version) ((version) & 0xFFFF) #define MAX_XIN_COUNT 16 #define SSPP_SUBBLK_COUNT_MAX 2 /** * Supported UBWC feature versions Loading Loading @@ -417,7 +418,12 @@ struct sde_qos_lut_tbl { * @hsic: * @memcolor: * @pcc_blk: * @igc_blk: * @gamut_blk: 3D LUT gamut block * @num_igc_blk: number of IGC block * @igc_blk: 1D LUT IGC block * @num_gc_blk: number of GC block * @gc_blk: 1D LUT GC block * @format_list: Pointer to list of supported formats * @virt_format_list: Pointer to list of supported formats for virtual planes */ Loading @@ -438,7 +444,11 @@ struct sde_sspp_sub_blks { struct sde_pp_blk hsic_blk; struct sde_pp_blk memcolor_blk; struct sde_pp_blk pcc_blk; struct sde_pp_blk igc_blk; struct sde_pp_blk gamut_blk; u32 num_igc_blk; struct sde_pp_blk igc_blk[SSPP_SUBBLK_COUNT_MAX]; u32 num_gc_blk; struct sde_pp_blk gc_blk[SSPP_SUBBLK_COUNT_MAX]; const struct sde_format_extended *format_list; const struct sde_format_extended *virt_format_list; Loading drivers/gpu/drm/msm/sde/sde_hw_sspp.c +78 −19 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -908,6 +908,81 @@ static void sde_hw_sspp_setup_cdp(struct sde_hw_pipe *ctx, SDE_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl); } static void _setup_layer_ops_colorproc(struct sde_hw_pipe *c, unsigned long features) { int ret = 0; if (test_bit(SDE_SSPP_HSIC, &features)) { if (c->cap->sblk->hsic_blk.version == (SDE_COLOR_PROCESS_VER(0x1, 0x7))) { c->ops.setup_pa_hue = sde_setup_pipe_pa_hue_v1_7; c->ops.setup_pa_sat = sde_setup_pipe_pa_sat_v1_7; c->ops.setup_pa_val = sde_setup_pipe_pa_val_v1_7; c->ops.setup_pa_cont = sde_setup_pipe_pa_cont_v1_7; } } if (test_bit(SDE_SSPP_MEMCOLOR, &features)) { if (c->cap->sblk->memcolor_blk.version == (SDE_COLOR_PROCESS_VER(0x1, 0x7))) c->ops.setup_pa_memcolor = sde_setup_pipe_pa_memcol_v1_7; } if (test_bit(SDE_SSPP_VIG_GAMUT, &features)) { if (c->cap->sblk->gamut_blk.version == (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { ret = reg_dmav1_init_sspp_op_v4(SDE_SSPP_VIG_GAMUT, c->idx); if (!ret) c->ops.setup_vig_gamut = reg_dmav1_setup_vig_gamutv5; else c->ops.setup_vig_gamut = NULL; } } if (test_bit(SDE_SSPP_VIG_IGC, &features)) { if (c->cap->sblk->igc_blk[0].version == (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { ret = reg_dmav1_init_sspp_op_v4(SDE_SSPP_VIG_IGC, c->idx); if (!ret) c->ops.setup_vig_igc = reg_dmav1_setup_vig_igcv5; else c->ops.setup_vig_igc = NULL; } } if (test_bit(SDE_SSPP_DMA_IGC, &features)) { if (c->cap->sblk->igc_blk[0].version == (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { ret = reg_dmav1_init_sspp_op_v4(SDE_SSPP_DMA_IGC, c->idx); if (!ret) c->ops.setup_dma_igc = reg_dmav1_setup_dma_igcv5; else c->ops.setup_dma_igc = NULL; } } if (test_bit(SDE_SSPP_DMA_GC, &features)) { if (c->cap->sblk->gc_blk[0].version == (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { ret = reg_dmav1_init_sspp_op_v4(SDE_SSPP_DMA_GC, c->idx); if (!ret) c->ops.setup_dma_gc = reg_dmav1_setup_dma_gcv5; else c->ops.setup_dma_gc = NULL; } } } static void _setup_layer_ops(struct sde_hw_pipe *c, unsigned long features) { Loading Loading @@ -950,24 +1025,6 @@ static void _setup_layer_ops(struct sde_hw_pipe *c, c->ops.get_scaler_ver = _sde_hw_sspp_get_scaler3_ver; } if (test_bit(SDE_SSPP_HSIC, &features)) { /* TODO: add version based assignment here as inline or macro */ if (c->cap->sblk->hsic_blk.version == (SDE_COLOR_PROCESS_VER(0x1, 0x7))) { c->ops.setup_pa_hue = sde_setup_pipe_pa_hue_v1_7; c->ops.setup_pa_sat = sde_setup_pipe_pa_sat_v1_7; c->ops.setup_pa_val = sde_setup_pipe_pa_val_v1_7; c->ops.setup_pa_cont = sde_setup_pipe_pa_cont_v1_7; } } if (test_bit(SDE_SSPP_MEMCOLOR, &features)) { if (c->cap->sblk->memcolor_blk.version == (SDE_COLOR_PROCESS_VER(0x1, 0x7))) c->ops.setup_pa_memcolor = sde_setup_pipe_pa_memcol_v1_7; } if (test_bit(SDE_SSPP_SBUF, &features)) { c->ops.setup_sys_cache = sde_hw_sspp_setup_sys_cache; c->ops.get_sbuf_status = sde_hw_sspp_get_sbuf_status; Loading @@ -975,6 +1032,8 @@ static void _setup_layer_ops(struct sde_hw_pipe *c, if (test_bit(SDE_SSPP_CDP, &features)) c->ops.setup_cdp = sde_hw_sspp_setup_cdp; _setup_layer_ops_colorproc(c, features); } static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp, Loading Loading
Documentation/devicetree/bindings/display/msm/sde.txt +24 −1 Original line number Diff line number Diff line Loading @@ -212,11 +212,23 @@ Optional properties: -- qcom,sde-vig-pcc: offset and version of PCC hardware -- qcom,sde-vig-hsic: offset and version of global PA adjustment -- qcom,sde-vig-memcolor: offset and version of PA memcolor hardware -- qcom,sde-vig-gamut: offset and version of 3D LUT Gamut hardware -- qcom,sde-vig-igc: offset and version of 1D LUT IGC hardware - qcom,sde-sspp-dma-blocks: A node that lists the blocks inside the DMA hardware. There can be more than one instance of this binding, in which case the entry would be appended with dgm entry index. Each entry will contain the offset and version (if needed) of each feature block. The presence of a block entry indicates that the SSPP DMA contains that feature hardware. e.g. qcom,sde-sspp-dma-blocks -- dgm@0 -- qcom,sde-dma-igc: offset and version of DMA IGC -- qcom,sde-dma-gc: offset and version of DMA GC - qcom,sde-sspp-rgb-blocks: A node that lists the blocks inside the RGB hardware. The block entries will contain the offset and version (if needed) of each feature block. The presence of a block entry indicates that the SSPP RGB contains that feature hardware. e.g. qcom,sde-sspp-vig-blocks e.g. qcom,sde-sspp-rgb-blocks -- qcom,sde-rgb-scaler-off: offset of RGB scaler hardware -- qcom,sde-rgb-scaler-size: A u32 address range for scaler. -- qcom,sde-rgb-pcc: offset and version of PCC hardware Loading Loading @@ -670,6 +682,17 @@ Example: qcom,sde-vig-pcc = <0x1780 0x00010000>; }; qcom,sde-sspp-dma-blocks { dgm@0 { qcom,sde-dma-igc = <0x400 0x00050000>; qcom,sde-dma-gc = <0x600 0x00050000>; } dgm@1 { qcom,sde-dma-igc = <0x1400 0x00050000>; qcom,sde-dma-gc = <0x600 0x00050000>; } }; qcom,sde-sspp-rgb-blocks { qcom,sde-rgb-scaler-off = <0x200>; qcom,sde-rgb-scaler-size = <0x74>; Loading
drivers/gpu/drm/msm/msm_drv.h +4 −0 Original line number Diff line number Diff line Loading @@ -91,6 +91,10 @@ enum msm_mdp_plane_property { PLANE_PROP_SKIN_COLOR, PLANE_PROP_SKY_COLOR, PLANE_PROP_FOLIAGE_COLOR, PLANE_PROP_VIG_GAMUT, PLANE_PROP_VIG_IGC, PLANE_PROP_DMA_IGC, PLANE_PROP_DMA_GC, PLANE_PROP_ROT_CAPS_V1, /* # of blob properties */ Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.c +124 −4 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -195,6 +195,7 @@ enum { SSPP_SCALE_SIZE, SSPP_VIG_BLOCKS, SSPP_RGB_BLOCKS, SSPP_DMA_BLOCKS, SSPP_EXCL_RECT, SSPP_SMART_DMA, SSPP_MAX_PER_PIPE_BW, Loading @@ -208,6 +209,8 @@ enum { VIG_HSIC_PROP, VIG_MEMCOLOR_PROP, VIG_PCC_PROP, VIG_GAMUT_PROP, VIG_IGC_PROP, VIG_PROP_MAX, }; Loading @@ -218,6 +221,12 @@ enum { RGB_PROP_MAX, }; enum { DMA_IGC_PROP, DMA_GC_PROP, DMA_PROP_MAX, }; enum { INTF_OFF, INTF_LEN, Loading Loading @@ -473,6 +482,7 @@ static struct sde_prop_type sspp_prop[] = { {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}, {SSPP_DMA_BLOCKS, "qcom,sde-sspp-dma-blocks", false, PROP_TYPE_NODE}, {SSPP_EXCL_RECT, "qcom,sde-sspp-excl-rect", false, PROP_TYPE_U32_ARRAY}, {SSPP_SMART_DMA, "qcom,sde-sspp-smart-dma-priority", false, PROP_TYPE_U32_ARRAY}, Loading @@ -488,6 +498,8 @@ static struct sde_prop_type vig_prop[] = { {VIG_MEMCOLOR_PROP, "qcom,sde-vig-memcolor", false, PROP_TYPE_U32_ARRAY}, {VIG_PCC_PROP, "qcom,sde-vig-pcc", false, PROP_TYPE_U32_ARRAY}, {VIG_GAMUT_PROP, "qcom,sde-vig-gamut", false, PROP_TYPE_U32_ARRAY}, {VIG_IGC_PROP, "qcom,sde-vig-igc", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type rgb_prop[] = { Loading @@ -496,6 +508,11 @@ static struct sde_prop_type rgb_prop[] = { {RGB_PCC_PROP, "qcom,sde-rgb-pcc", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type dma_prop[] = { {DMA_IGC_PROP, "qcom,sde-dma-igc", false, PROP_TYPE_U32_ARRAY}, {DMA_GC_PROP, "qcom,sde-dma-gc", false, PROP_TYPE_U32_ARRAY}, }; static struct sde_prop_type ctl_prop[] = { {HW_OFF, "qcom,sde-ctl-off", true, PROP_TYPE_U32_ARRAY}, {HW_LEN, "qcom,sde-ctl-size", false, PROP_TYPE_U32}, Loading Loading @@ -1010,6 +1027,30 @@ static void _sde_sspp_setup_vig(struct sde_mdss_cfg *sde_cfg, set_bit(SDE_SSPP_PCC, &sspp->features); } if (prop_exists[VIG_GAMUT_PROP]) { sblk->gamut_blk.id = SDE_SSPP_VIG_GAMUT; snprintf(sblk->gamut_blk.name, SDE_HW_BLK_NAME_LEN, "sspp_vig_gamut%u", sspp->id - SSPP_VIG0); sblk->gamut_blk.base = PROP_VALUE_ACCESS(prop_value, VIG_GAMUT_PROP, 0); sblk->gamut_blk.version = PROP_VALUE_ACCESS(prop_value, VIG_GAMUT_PROP, 1); sblk->gamut_blk.len = 0; set_bit(SDE_SSPP_VIG_GAMUT, &sspp->features); } if (prop_exists[VIG_IGC_PROP]) { sblk->igc_blk[0].id = SDE_SSPP_VIG_IGC; snprintf(sblk->igc_blk[0].name, SDE_HW_BLK_NAME_LEN, "sspp_vig_igc%u", sspp->id - SSPP_VIG0); sblk->igc_blk[0].base = PROP_VALUE_ACCESS(prop_value, VIG_IGC_PROP, 0); sblk->igc_blk[0].version = PROP_VALUE_ACCESS(prop_value, VIG_IGC_PROP, 1); sblk->igc_blk[0].len = 0; set_bit(SDE_SSPP_VIG_IGC, &sspp->features); } sblk->format_list = sde_cfg->vig_formats; sblk->virt_format_list = sde_cfg->dma_formats; } Loading Loading @@ -1089,8 +1130,11 @@ static void _sde_sspp_setup_cursor(struct sde_mdss_cfg *sde_cfg, static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg, struct sde_sspp_cfg *sspp, struct sde_sspp_sub_blks *sblk, struct sde_prop_value *prop_value, u32 *dma_count) bool prop_exists[][DMA_PROP_MAX], struct sde_prop_value *prop_value, u32 *dma_count, u32 dgm_count) { u32 i = 0; sblk->maxupscale = SSPP_UNITY_SCALE; sblk->maxdwnscale = SSPP_UNITY_SCALE; sblk->format_list = sde_cfg->dma_formats; Loading @@ -1104,6 +1148,60 @@ static void _sde_sspp_setup_dma(struct sde_mdss_cfg *sde_cfg, if (sde_cfg->vbif_qos_nlvl == 8) set_bit(SDE_SSPP_QOS_8LVL, &sspp->features); (*dma_count)++; if (!prop_value) return; sblk->num_igc_blk = dgm_count; sblk->num_gc_blk = dgm_count; for (i = 0; i < dgm_count; i++) { if (prop_exists[i][DMA_IGC_PROP]) { sblk->igc_blk[i].id = SDE_SSPP_DMA_IGC; snprintf(sblk->igc_blk[i].name, SDE_HW_BLK_NAME_LEN, "sspp_dma_igc%u", sspp->id - SSPP_DMA0); sblk->igc_blk[i].base = PROP_VALUE_ACCESS( &prop_value[i * DMA_PROP_MAX], DMA_IGC_PROP, 0); sblk->igc_blk[i].version = PROP_VALUE_ACCESS( &prop_value[i * DMA_PROP_MAX], DMA_IGC_PROP, 1); sblk->igc_blk[i].len = 0; set_bit(SDE_SSPP_DMA_IGC, &sspp->features); } if (prop_exists[i][DMA_GC_PROP]) { sblk->gc_blk[i].id = SDE_SSPP_DMA_GC; snprintf(sblk->gc_blk[0].name, SDE_HW_BLK_NAME_LEN, "sspp_dma_gc%u", sspp->id - SSPP_DMA0); sblk->gc_blk[i].base = PROP_VALUE_ACCESS( &prop_value[i * DMA_PROP_MAX], DMA_GC_PROP, 0); sblk->gc_blk[i].version = PROP_VALUE_ACCESS( &prop_value[i * DMA_PROP_MAX], DMA_GC_PROP, 1); sblk->gc_blk[i].len = 0; set_bit(SDE_SSPP_DMA_GC, &sspp->features); } } } static int sde_dgm_parse_dt(struct device_node *np, u32 index, struct sde_prop_value *prop_value, bool *prop_exists) { int rc = 0; u32 child_idx = 0; int prop_count[DMA_PROP_MAX] = {0}; struct device_node *dgm_snp = NULL; for_each_child_of_node(np, dgm_snp) { if (index != child_idx++) continue; rc = _validate_dt_entry(dgm_snp, dma_prop, ARRAY_SIZE(dma_prop), prop_count, NULL); if (rc) return rc; rc = _read_dt_entry(dgm_snp, dma_prop, ARRAY_SIZE(dma_prop), prop_count, prop_exists, prop_value); } return rc; } static int sde_sspp_parse_dt(struct device_node *np, Loading @@ -1113,12 +1211,15 @@ static int sde_sspp_parse_dt(struct device_node *np, int vig_prop_count[VIG_PROP_MAX], rgb_prop_count[RGB_PROP_MAX]; bool prop_exists[SSPP_PROP_MAX], vig_prop_exists[VIG_PROP_MAX]; bool rgb_prop_exists[RGB_PROP_MAX]; bool dgm_prop_exists[SSPP_SUBBLK_COUNT_MAX][DMA_PROP_MAX]; struct sde_prop_value *prop_value = NULL; struct sde_prop_value *vig_prop_value = NULL, *rgb_prop_value = NULL; struct sde_prop_value *dgm_prop_value = NULL; const char *type; 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 dgm_count = 0; struct device_node *snp = NULL; prop_value = kcalloc(SSPP_PROP_MAX, Loading Loading @@ -1177,6 +1278,23 @@ static int sde_sspp_parse_dt(struct device_node *np, rgb_prop_value); } /* get dma feature dt properties if they exist */ snp = of_get_child_by_name(np, sspp_prop[SSPP_DMA_BLOCKS].prop_name); if (snp) { dgm_count = of_get_child_count(snp); if (dgm_count > 0 && dgm_count <= SSPP_SUBBLK_COUNT_MAX) { dgm_prop_value = kzalloc(dgm_count * DMA_PROP_MAX * sizeof(struct sde_prop_value), GFP_KERNEL); if (!dgm_prop_value) return -ENOMEM; for (i = 0; i < dgm_count; i++) sde_dgm_parse_dt(snp, i, &dgm_prop_value[i * DMA_PROP_MAX], &dgm_prop_exists[i][0]); } } for (i = 0; i < off_count; i++) { sspp = sde_cfg->sspp + i; sblk = kzalloc(sizeof(*sblk), GFP_KERNEL); Loading Loading @@ -1225,8 +1343,9 @@ static int sde_sspp_parse_dt(struct device_node *np, &cursor_count); } else if (!strcmp(type, "dma")) { /* No prop values for DMA pipes */ _sde_sspp_setup_dma(sde_cfg, sspp, sblk, NULL, &dma_count); _sde_sspp_setup_dma(sde_cfg, sspp, sblk, dgm_prop_exists, dgm_prop_value, &dma_count, dgm_count); } else { SDE_ERROR("invalid sspp type:%s\n", type); rc = -EINVAL; Loading Loading @@ -1281,6 +1400,7 @@ static int sde_sspp_parse_dt(struct device_node *np, kfree(prop_value); kfree(vig_prop_value); kfree(rgb_prop_value); kfree(dgm_prop_value); return rc; } Loading
drivers/gpu/drm/msm/sde/sde_hw_catalog.h +12 −2 Original line number Diff line number Diff line Loading @@ -66,6 +66,7 @@ #define SDE_COLOR_PROCESS_MINOR(version) ((version) & 0xFFFF) #define MAX_XIN_COUNT 16 #define SSPP_SUBBLK_COUNT_MAX 2 /** * Supported UBWC feature versions Loading Loading @@ -417,7 +418,12 @@ struct sde_qos_lut_tbl { * @hsic: * @memcolor: * @pcc_blk: * @igc_blk: * @gamut_blk: 3D LUT gamut block * @num_igc_blk: number of IGC block * @igc_blk: 1D LUT IGC block * @num_gc_blk: number of GC block * @gc_blk: 1D LUT GC block * @format_list: Pointer to list of supported formats * @virt_format_list: Pointer to list of supported formats for virtual planes */ Loading @@ -438,7 +444,11 @@ struct sde_sspp_sub_blks { struct sde_pp_blk hsic_blk; struct sde_pp_blk memcolor_blk; struct sde_pp_blk pcc_blk; struct sde_pp_blk igc_blk; struct sde_pp_blk gamut_blk; u32 num_igc_blk; struct sde_pp_blk igc_blk[SSPP_SUBBLK_COUNT_MAX]; u32 num_gc_blk; struct sde_pp_blk gc_blk[SSPP_SUBBLK_COUNT_MAX]; const struct sde_format_extended *format_list; const struct sde_format_extended *virt_format_list; Loading
drivers/gpu/drm/msm/sde/sde_hw_sspp.c +78 −19 Original line number Diff line number Diff line /* Copyright (c) 2015-2017, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -908,6 +908,81 @@ static void sde_hw_sspp_setup_cdp(struct sde_hw_pipe *ctx, SDE_REG_WRITE(&ctx->hw, cdp_cntl_offset, cdp_cntl); } static void _setup_layer_ops_colorproc(struct sde_hw_pipe *c, unsigned long features) { int ret = 0; if (test_bit(SDE_SSPP_HSIC, &features)) { if (c->cap->sblk->hsic_blk.version == (SDE_COLOR_PROCESS_VER(0x1, 0x7))) { c->ops.setup_pa_hue = sde_setup_pipe_pa_hue_v1_7; c->ops.setup_pa_sat = sde_setup_pipe_pa_sat_v1_7; c->ops.setup_pa_val = sde_setup_pipe_pa_val_v1_7; c->ops.setup_pa_cont = sde_setup_pipe_pa_cont_v1_7; } } if (test_bit(SDE_SSPP_MEMCOLOR, &features)) { if (c->cap->sblk->memcolor_blk.version == (SDE_COLOR_PROCESS_VER(0x1, 0x7))) c->ops.setup_pa_memcolor = sde_setup_pipe_pa_memcol_v1_7; } if (test_bit(SDE_SSPP_VIG_GAMUT, &features)) { if (c->cap->sblk->gamut_blk.version == (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { ret = reg_dmav1_init_sspp_op_v4(SDE_SSPP_VIG_GAMUT, c->idx); if (!ret) c->ops.setup_vig_gamut = reg_dmav1_setup_vig_gamutv5; else c->ops.setup_vig_gamut = NULL; } } if (test_bit(SDE_SSPP_VIG_IGC, &features)) { if (c->cap->sblk->igc_blk[0].version == (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { ret = reg_dmav1_init_sspp_op_v4(SDE_SSPP_VIG_IGC, c->idx); if (!ret) c->ops.setup_vig_igc = reg_dmav1_setup_vig_igcv5; else c->ops.setup_vig_igc = NULL; } } if (test_bit(SDE_SSPP_DMA_IGC, &features)) { if (c->cap->sblk->igc_blk[0].version == (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { ret = reg_dmav1_init_sspp_op_v4(SDE_SSPP_DMA_IGC, c->idx); if (!ret) c->ops.setup_dma_igc = reg_dmav1_setup_dma_igcv5; else c->ops.setup_dma_igc = NULL; } } if (test_bit(SDE_SSPP_DMA_GC, &features)) { if (c->cap->sblk->gc_blk[0].version == (SDE_COLOR_PROCESS_VER(0x5, 0x0))) { ret = reg_dmav1_init_sspp_op_v4(SDE_SSPP_DMA_GC, c->idx); if (!ret) c->ops.setup_dma_gc = reg_dmav1_setup_dma_gcv5; else c->ops.setup_dma_gc = NULL; } } } static void _setup_layer_ops(struct sde_hw_pipe *c, unsigned long features) { Loading Loading @@ -950,24 +1025,6 @@ static void _setup_layer_ops(struct sde_hw_pipe *c, c->ops.get_scaler_ver = _sde_hw_sspp_get_scaler3_ver; } if (test_bit(SDE_SSPP_HSIC, &features)) { /* TODO: add version based assignment here as inline or macro */ if (c->cap->sblk->hsic_blk.version == (SDE_COLOR_PROCESS_VER(0x1, 0x7))) { c->ops.setup_pa_hue = sde_setup_pipe_pa_hue_v1_7; c->ops.setup_pa_sat = sde_setup_pipe_pa_sat_v1_7; c->ops.setup_pa_val = sde_setup_pipe_pa_val_v1_7; c->ops.setup_pa_cont = sde_setup_pipe_pa_cont_v1_7; } } if (test_bit(SDE_SSPP_MEMCOLOR, &features)) { if (c->cap->sblk->memcolor_blk.version == (SDE_COLOR_PROCESS_VER(0x1, 0x7))) c->ops.setup_pa_memcolor = sde_setup_pipe_pa_memcol_v1_7; } if (test_bit(SDE_SSPP_SBUF, &features)) { c->ops.setup_sys_cache = sde_hw_sspp_setup_sys_cache; c->ops.get_sbuf_status = sde_hw_sspp_get_sbuf_status; Loading @@ -975,6 +1032,8 @@ static void _setup_layer_ops(struct sde_hw_pipe *c, if (test_bit(SDE_SSPP_CDP, &features)) c->ops.setup_cdp = sde_hw_sspp_setup_cdp; _setup_layer_ops_colorproc(c, features); } static struct sde_sspp_cfg *_sspp_offset(enum sde_sspp sspp, Loading