From patchwork Wed Oct 5 18:16:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Marijn Suijten X-Patchwork-Id: 12999571 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 26E94C433F5 for ; Wed, 5 Oct 2022 18:17:48 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id B753610E741; Wed, 5 Oct 2022 18:17:28 +0000 (UTC) Received: from relay08.th.seeweb.it (relay08.th.seeweb.it [IPv6:2001:4b7a:2000:18::169]) by gabe.freedesktop.org (Postfix) with ESMTPS id B320F10E735; Wed, 5 Oct 2022 18:17:20 +0000 (UTC) Received: from localhost.localdomain (94-209-172-39.cable.dynamic.v4.ziggo.nl [94.209.172.39]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by m-r2.th.seeweb.it (Postfix) with ESMTPSA id A7ABD3F5CF; Wed, 5 Oct 2022 20:17:18 +0200 (CEST) From: Marijn Suijten To: phone-devel@vger.kernel.org, Rob Clark , Dmitry Baryshkov , Vinod Koul Subject: [PATCH v2 5/7] drm/msm/dsi: Account for DSC's bits_per_pixel having 4 fractional bits Date: Wed, 5 Oct 2022 20:16:55 +0200 Message-Id: <20221005181657.784375-6-marijn.suijten@somainline.org> X-Mailer: git-send-email 2.38.0 In-Reply-To: <20221005181657.784375-1-marijn.suijten@somainline.org> References: <20221005181657.784375-1-marijn.suijten@somainline.org> MIME-Version: 1.0 X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: freedreno@lists.freedesktop.org, Douglas Anderson , Thomas Zimmermann , Jami Kettunen , Vladimir Lypak , linux-arm-msm@vger.kernel.org, Konrad Dybcio , Abhinav Kumar , dri-devel@lists.freedesktop.org, Javier Martinez Canillas , David Airlie , Martin Botka , ~postmarketos/upstreaming@lists.sr.ht, AngeloGioacchino Del Regno , Alex Deucher , Marijn Suijten , Sean Paul , linux-kernel@vger.kernel.org Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" drm_dsc_config's bits_per_pixel field holds a fractional value with 4 bits, which all panel drivers should adhere to for drm_dsc_pps_payload_pack() to generate a valid payload. All code in the DSI driver here seems to assume that this field doesn't contain any fractional bits, hence resulting in the wrong values being computed. Since none of the calculations leave any room for fractional bits or seem to indicate any possible area of support, disallow such values altogether. Fixes: b9080324d6ca ("drm/msm/dsi: add support for dsc data") Signed-off-by: Marijn Suijten --- drivers/gpu/drm/msm/dsi/dsi_host.c | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index f42794cdd4c1..4717d49d76be 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -33,7 +33,7 @@ #define DSI_RESET_TOGGLE_DELAY_MS 20 -static int dsi_populate_dsc_params(struct drm_dsc_config *dsc); +static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc); static int dsi_get_version(const void __iomem *base, u32 *major, u32 *minor) { @@ -908,6 +908,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) u32 va_end = va_start + mode->vdisplay; u32 hdisplay = mode->hdisplay; u32 wc; + int ret; DBG(""); @@ -943,7 +944,9 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) /* we do the calculations for dsc parameters here so that * panel can use these parameters */ - dsi_populate_dsc_params(dsc); + ret = dsi_populate_dsc_params(msm_host, dsc); + if (ret) + return; /* Divide the display by 3 but keep back/font porch and * pulse width same @@ -1769,7 +1772,7 @@ static char bpg_offset[DSC_NUM_BUF_RANGES] = { 2, 0, 0, -2, -4, -6, -8, -8, -8, -10, -10, -12, -12, -12, -12 }; -static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) +static int dsi_populate_dsc_params(struct msm_dsi_host *msm_host, struct drm_dsc_config *dsc) { int mux_words_size; int groups_per_line, groups_total; @@ -1780,6 +1783,12 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) int data; int final_value, final_scale; int i; + u16 bpp = dsc->bits_per_pixel >> 4; + + if (dsc->bits_per_pixel & 0xf) { + DRM_DEV_ERROR(&msm_host->pdev->dev, "DSI does not support fractional bits_per_pixel\n"); + return -EINVAL; + } dsc->rc_model_size = 8192; dsc->first_line_bpg_offset = 12; @@ -1801,7 +1810,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) } dsc->initial_offset = 6144; /* Not bpp 12 */ - if (dsc->bits_per_pixel != 8) + if (bpp != 8) dsc->initial_offset = 2048; /* bpp = 12 */ mux_words_size = 48; /* bpc == 8/10 */ @@ -1824,14 +1833,14 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) * params are calculated */ groups_per_line = DIV_ROUND_UP(dsc->slice_width, 3); - dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * dsc->bits_per_pixel, 8); + dsc->slice_chunk_size = DIV_ROUND_UP(dsc->slice_width * bpp, 8); /* rbs-min */ min_rate_buffer_size = dsc->rc_model_size - dsc->initial_offset + - dsc->initial_xmit_delay * dsc->bits_per_pixel + + dsc->initial_xmit_delay * bpp + groups_per_line * dsc->first_line_bpg_offset; - hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, dsc->bits_per_pixel); + hrd_delay = DIV_ROUND_UP(min_rate_buffer_size, bpp); dsc->initial_dec_delay = hrd_delay - dsc->initial_xmit_delay; @@ -1854,7 +1863,7 @@ static int dsi_populate_dsc_params(struct drm_dsc_config *dsc) data = 2048 * (dsc->rc_model_size - dsc->initial_offset + num_extra_mux_bits); dsc->slice_bpg_offset = DIV_ROUND_UP(data, groups_total); - data = dsc->initial_xmit_delay * dsc->bits_per_pixel; + data = dsc->initial_xmit_delay * bpp; final_value = dsc->rc_model_size - data + num_extra_mux_bits; dsc->final_offset = final_value;