diff --git a/msm/sde/sde_encoder_phys_wb.c b/msm/sde/sde_encoder_phys_wb.c index 99ea7153ed56..8a27e4dd255c 100644 --- a/msm/sde/sde_encoder_phys_wb.c +++ b/msm/sde/sde_encoder_phys_wb.c @@ -24,6 +24,10 @@ #define TO_S15D16(_x_) ((_x_) << 7) +#define SDE_WB_MAX_LINEWIDTH(fmt, wb_cfg) \ + (SDE_FORMAT_IS_UBWC(fmt) ? wb_cfg->sblk->maxlinewidth : \ + wb_cfg->sblk->maxlinewidth_linear) + static const u32 cwb_irq_tbl[PINGPONG_MAX] = {SDE_NONE, INTR_IDX_PP1_OVFL, INTR_IDX_PP2_OVFL, INTR_IDX_PP3_OVFL, INTR_IDX_PP4_OVFL, INTR_IDX_PP5_OVFL, SDE_NONE, SDE_NONE}; @@ -766,9 +770,10 @@ static int sde_encoder_phys_wb_atomic_check( SDE_ERROR("invalid roi y=%d, h=%d, fb h=%d\n", wb_roi.y, wb_roi.h, fb->height); return -EINVAL; - } else if (wb_roi.w > wb_cfg->sblk->maxlinewidth) { - SDE_ERROR("invalid roi w=%d, maxlinewidth=%u\n", - wb_roi.w, wb_cfg->sblk->maxlinewidth); + } else if (wb_roi.w > SDE_WB_MAX_LINEWIDTH(fmt, wb_cfg)) { + SDE_ERROR("invalid roi ubwc=%d w=%d, maxlinewidth=%u\n", + SDE_FORMAT_IS_UBWC(fmt), wb_roi.w, + SDE_WB_MAX_LINEWIDTH(fmt, wb_cfg)); return -EINVAL; } } else { @@ -784,9 +789,10 @@ static int sde_encoder_phys_wb_atomic_check( SDE_ERROR("invalid fb h=%d, mode h=%d\n", fb->height, mode->vdisplay); return -EINVAL; - } else if (fb->width > wb_cfg->sblk->maxlinewidth) { - SDE_ERROR("invalid fb w=%d, maxlinewidth=%u\n", - fb->width, wb_cfg->sblk->maxlinewidth); + } else if (fb->width > SDE_WB_MAX_LINEWIDTH(fmt, wb_cfg)) { + SDE_ERROR("invalid fb ubwc=%d w=%d, maxlinewidth=%u\n", + SDE_FORMAT_IS_UBWC(fmt), fb->width, + SDE_WB_MAX_LINEWIDTH(fmt, wb_cfg)); return -EINVAL; } } diff --git a/msm/sde/sde_hw_catalog.c b/msm/sde/sde_hw_catalog.c index c40f74eeb2b5..b489af70c921 100644 --- a/msm/sde/sde_hw_catalog.c +++ b/msm/sde/sde_hw_catalog.c @@ -182,6 +182,7 @@ enum sde_prop { MIXER_LINEWIDTH, MIXER_BLEND, WB_LINEWIDTH, + WB_LINEWIDTH_LINEAR, BANK_BIT, UBWC_VERSION, UBWC_STATIC, @@ -542,6 +543,8 @@ static struct sde_prop_type sde_prop[] = { {MIXER_LINEWIDTH, "qcom,sde-mixer-linewidth", false, PROP_TYPE_U32}, {MIXER_BLEND, "qcom,sde-mixer-blendstages", false, PROP_TYPE_U32}, {WB_LINEWIDTH, "qcom,sde-wb-linewidth", false, PROP_TYPE_U32}, + {WB_LINEWIDTH_LINEAR, "qcom,sde-wb-linewidth-linear", + false, PROP_TYPE_U32}, {BANK_BIT, "qcom,sde-highest-bank-bit", false, PROP_TYPE_U32}, {UBWC_VERSION, "qcom,sde-ubwc-version", false, PROP_TYPE_U32}, {UBWC_STATIC, "qcom,sde-ubwc-static", false, PROP_TYPE_U32}, @@ -2298,6 +2301,7 @@ static int sde_wb_parse_dt(struct device_node *np, struct sde_mdss_cfg *sde_cfg) if (!prop_exists[WB_LEN]) wb->len = DEFAULT_SDE_HW_BLOCK_LEN; sblk->maxlinewidth = sde_cfg->max_wb_linewidth; + sblk->maxlinewidth_linear = sde_cfg->max_wb_linewidth_linear; if (wb->id >= LINE_MODE_WB_OFFSET) set_bit(SDE_WB_LINE_MODE, &wb->features); @@ -3654,6 +3658,11 @@ static void _sde_top_parse_dt_helper(struct sde_mdss_cfg *cfg, PROP_VALUE_ACCESS(props->values, WB_LINEWIDTH, 0) : DEFAULT_SDE_LINE_WIDTH; + /* if wb linear width is not defined use the line width as default */ + cfg->max_wb_linewidth_linear = props->exists[WB_LINEWIDTH_LINEAR] ? + PROP_VALUE_ACCESS(props->values, WB_LINEWIDTH_LINEAR, 0) + : cfg->max_wb_linewidth; + cfg->max_mixer_width = props->exists[MIXER_LINEWIDTH] ? PROP_VALUE_ACCESS(props->values, MIXER_LINEWIDTH, 0) : DEFAULT_SDE_LINE_WIDTH; diff --git a/msm/sde/sde_hw_catalog.h b/msm/sde/sde_hw_catalog.h index 4e0021a5b4e7..33f2e49d90d4 100644 --- a/msm/sde/sde_hw_catalog.h +++ b/msm/sde/sde_hw_catalog.h @@ -817,6 +817,7 @@ struct sde_vdc_sub_blks { struct sde_wb_sub_blocks { u32 maxlinewidth; + u32 maxlinewidth_linear; }; struct sde_mdss_base_cfg { @@ -1364,6 +1365,7 @@ struct sde_perf_cfg { * @max_mixer_blendstages max layer mixer blend stages or * supported z order * @max_wb_linewidth max writeback line width support. + * @max_wb_linewidth_linear max writeback line width for linear formats. * @max_display_width maximum display width support. * @max_display_height maximum display height support. * @max_lm_per_display maximum layer mixer per display @@ -1433,6 +1435,7 @@ struct sde_mdss_cfg { u32 max_mixer_width; u32 max_mixer_blendstages; u32 max_wb_linewidth; + u32 max_wb_linewidth_linear; u32 max_display_width; u32 max_display_height; diff --git a/msm/sde/sde_wb.c b/msm/sde/sde_wb.c index dd6d3fa9125a..3b51db3492fc 100644 --- a/msm/sde/sde_wb.c +++ b/msm/sde/sde_wb.c @@ -97,9 +97,11 @@ int sde_wb_connector_get_modes(struct drm_connector *connector, void *display, num_modes++; } } else { - u32 max_width = (wb_dev->wb_cfg && wb_dev->wb_cfg->sblk) ? - wb_dev->wb_cfg->sblk->maxlinewidth : - SDE_WB_MODE_MAX_WIDTH; + u32 max_width = SDE_WB_MODE_MAX_WIDTH; + + if (wb_dev->wb_cfg && wb_dev->wb_cfg->sblk) + max_width = max(wb_dev->wb_cfg->sblk->maxlinewidth, + wb_dev->wb_cfg->sblk->maxlinewidth_linear); num_modes = drm_add_modes_noedid(connector, max_width, SDE_WB_MODE_MAX_HEIGHT); @@ -298,21 +300,24 @@ int sde_wb_get_info(struct drm_connector *connector, struct msm_display_info *info, void *display) { struct sde_wb_device *wb_dev = display; + u32 max_width = SDE_WB_MODE_MAX_WIDTH; if (!info || !wb_dev) { pr_err("invalid params\n"); return -EINVAL; } + if (wb_dev->wb_cfg && wb_dev->wb_cfg->sblk) + max_width = max(wb_dev->wb_cfg->sblk->maxlinewidth, + wb_dev->wb_cfg->sblk->maxlinewidth_linear); + memset(info, 0, sizeof(struct msm_display_info)); info->intf_type = DRM_MODE_CONNECTOR_VIRTUAL; info->num_of_h_tiles = 1; info->h_tile_instance[0] = sde_wb_get_index(display); info->is_connected = true; info->capabilities = MSM_DISPLAY_CAP_HOT_PLUG | MSM_DISPLAY_CAP_EDID; - info->max_width = (wb_dev->wb_cfg && wb_dev->wb_cfg->sblk) ? - wb_dev->wb_cfg->sblk->maxlinewidth : - SDE_WB_MODE_MAX_WIDTH; + info->max_width = max_width; info->max_height = SDE_WB_MODE_MAX_HEIGHT; return 0; } @@ -391,6 +396,10 @@ int sde_wb_connector_set_info_blob(struct drm_connector *connector, "maxlinewidth", wb_dev->wb_cfg->sblk->maxlinewidth); + sde_kms_info_add_keyint(info, + "maxlinewidth_linear", + wb_dev->wb_cfg->sblk->maxlinewidth_linear); + sde_kms_info_start(info, "features"); if (wb_dev->wb_cfg && (wb_dev->wb_cfg->features & BIT(SDE_WB_UBWC))) sde_kms_info_append(info, "wb_ubwc");