Message ID | 20231114174218.19765-4-jonathan@marek.ca |
---|---|
State | New |
Headers |
Return-Path: <linux-kernel-owner@vger.kernel.org> Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:6358:a59:b0:164:83eb:24d7 with SMTP id 25csp2091117rwb; Tue, 14 Nov 2023 09:44:59 -0800 (PST) X-Google-Smtp-Source: AGHT+IEgoLkMLN/mUOyTYkIWtvQf7y8ifsUz1VfYuf6grU0XGYb1R/dUPwOS6UsTUWE8hX8uFOsl X-Received: by 2002:a05:6a20:7fa6:b0:159:e4ab:15ce with SMTP id d38-20020a056a207fa600b00159e4ab15cemr5018579pzj.15.1699983899391; Tue, 14 Nov 2023 09:44:59 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1699983899; cv=none; d=google.com; s=arc-20160816; b=VaGcro09NqcEZcc6PMM2WrKBputAK5iZ7yN8H81Ym6qHMsDUZKRX/nq4QOpuTO7jU/ +0Zkdhe9hZuY02rsdyAEAbXY845UlKvbfZ5f5EDVMB85HzmzK/CPsUnoDrE6KMZkTJak gbqYiYlQKxerif+ORf2y43d4R9GpYHHgTcBykLidDUl4gfl/uQJ8NoC4ZCoqi9S/7E4h JZpqz37g4o6m7GpndtviarqJKqzXm8mXOMCaRtbFFl1ns/TLNFMZ2PQVrZtA5RKAKDh6 +LqQvjondW/9yv3qbQbBmw8B6PgphPXVDyLY1Dp8HdHsgcUWRkuF++DvnvIgMuEl8N0j qSfg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=LxJSud2bUpEWb5+zdKhsCdpc+jFCEiyn/rkkbqMyRnU=; fh=fJLioXbYvMLR8h+77QRpLrDtdTQfyALOiDgPhzA9oJM=; b=MieB3hO6IFrGcbg+kblMbCMXSFCQ8FaqfcLK83GUU6IS00NRFeHAnfdbAA+NIbfG9f lLlV+F5FVryK8Uu5J5SW+YVlb5ESQ3GiKqb0J2G4m67RG4BQY7UCMwltpxpBumP1G56c RAg2Dh011ys4Y0k6HOopd1qt3qqBc4bX7clPXqF58ycGjz7IZrF9/EICBwX8dSMVXhno c3SbnsKRXOFtsd6DDP1ij0t4JS99fBMOU3vHsC2332+ujyZCyL+C+mqCDeA4fnrlHZ+P x8/LMD3dXSQqRzSd37W3XLRGzi8/oZ8U6N8Po8lE9Ys1c3GIeqSPyEK2iETQYS+ZlENk 257g== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@marek.ca header.s=google header.b=H46kxdtM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from lipwig.vger.email (lipwig.vger.email. [23.128.96.33]) by mx.google.com with ESMTPS id s8-20020a637708000000b005bdfdf1c44dsi8202447pgc.126.2023.11.14.09.44.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 09:44:59 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) client-ip=23.128.96.33; Authentication-Results: mx.google.com; dkim=pass header.i=@marek.ca header.s=google header.b=H46kxdtM; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.33 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (depot.vger.email [IPv6:2620:137:e000::3:0]) by lipwig.vger.email (Postfix) with ESMTP id 2D394802F721; Tue, 14 Nov 2023 09:44:54 -0800 (PST) X-Virus-Status: Clean X-Virus-Scanned: clamav-milter 0.103.11 at lipwig.vger.email Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233871AbjKNRoZ (ORCPT <rfc822;lhua1029@gmail.com> + 29 others); Tue, 14 Nov 2023 12:44:25 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44530 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233903AbjKNRoW (ORCPT <rfc822;linux-kernel@vger.kernel.org>); Tue, 14 Nov 2023 12:44:22 -0500 Received: from mail-qk1-x736.google.com (mail-qk1-x736.google.com [IPv6:2607:f8b0:4864:20::736]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AF7E1193 for <linux-kernel@vger.kernel.org>; Tue, 14 Nov 2023 09:44:14 -0800 (PST) Received: by mail-qk1-x736.google.com with SMTP id af79cd13be357-77bac408851so564714985a.1 for <linux-kernel@vger.kernel.org>; Tue, 14 Nov 2023 09:44:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=marek.ca; s=google; t=1699983853; x=1700588653; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LxJSud2bUpEWb5+zdKhsCdpc+jFCEiyn/rkkbqMyRnU=; b=H46kxdtM39JzFf+LiuZsCA4xkC9uXqQPJJmPtN8byJufdLblbxs8j9x84ekLl5Vd6e aMsG4JU+0vI8Pv/bFXzOx5UoA5+ZTlCkWfQltXAe70Spdhb3h1OetvPcn7QRjcMuhWaX HEQz5WszLmr6TEw6wJosYC3CUwUr8TYJ9EpZ2+WsUXzPrjkyZ2KI1RJCSuNzvs08MkQb CifyUDKl6k5fMz2iP9MRTIHx5Y0G7qXmNLzAW3GUozrRUCCIWCZbt7PCSSHiyUHCq9+u tM6F8UN11YjPbSdBEeZv1tvKToSishGG5eHPImFn7u8vMJz0RowHq4bjEOTKqLxKR7bj 6EaQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1699983853; x=1700588653; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LxJSud2bUpEWb5+zdKhsCdpc+jFCEiyn/rkkbqMyRnU=; b=BmJhukXjbyqMqNaMP0ZOaGv8XvaqsodyMqlQyer8+WBGLFegDvAjhSu7YF0A2gjV0J 67oASEfwUhdiOHGMNRdHaYvB0RmBzNWpHoMMkSLambt8mI09EaM2fR2yqs7McW/1WXQz RJRnnI3HARVyCpHprJ5kge8SNrlZCWiOhGTjBVu3taGtaP7y2KCN/TTgmJmtf4ZhiHQ0 yK+T6lwlIlqe4QtQdPKfnytDv5ipNrsrvQXV7U7828oNgq+QwKEyTRcSQ87WR10erFXd I2M5X9kVs8fBqp+sMGQPITl+e++bbSE8Iuzw0Ohh11FqnwwBEOjM0ocQ+pPTHaYg8lcG 0CqA== X-Gm-Message-State: AOJu0Yxd5gaVo8fYuTw5UG/3eeaHhd1qjY33jVPghdVBdT9FvWFbzpVV CjWPLwbjzjDh/Oee6kuyrmX/uw== X-Received: by 2002:a05:620a:1993:b0:76c:b7f0:2bc9 with SMTP id bm19-20020a05620a199300b0076cb7f02bc9mr5333777qkb.16.1699983853651; Tue, 14 Nov 2023 09:44:13 -0800 (PST) Received: from localhost.localdomain (modemcable125.110-19-135.mc.videotron.ca. [135.19.110.125]) by smtp.gmail.com with ESMTPSA id bi8-20020a05620a318800b007671cfe8a18sm2833350qkb.13.2023.11.14.09.44.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 14 Nov 2023 09:44:13 -0800 (PST) From: Jonathan Marek <jonathan@marek.ca> To: freedreno@lists.freedesktop.org Cc: Rob Clark <robdclark@gmail.com>, Abhinav Kumar <quic_abhinavk@quicinc.com>, Dmitry Baryshkov <dmitry.baryshkov@linaro.org>, Sean Paul <sean@poorly.run>, Marijn Suijten <marijn.suijten@somainline.org>, David Airlie <airlied@gmail.com>, Daniel Vetter <daniel@ffwll.ch>, Jessica Zhang <quic_jesszhan@quicinc.com>, Konrad Dybcio <konrad.dybcio@linaro.org>, Jiasheng Jiang <jiasheng@iscas.ac.cn>, Doug Anderson <dianders@chromium.org>, linux-arm-msm@vger.kernel.org (open list:DRM DRIVER FOR MSM ADRENO GPU), dri-devel@lists.freedesktop.org (open list:DRM DRIVER FOR MSM ADRENO GPU), linux-kernel@vger.kernel.org (open list) Subject: [PATCH 4/4] drm/msm/dsi: fix DSC for the bonded DSI case Date: Tue, 14 Nov 2023 12:42:16 -0500 Message-Id: <20231114174218.19765-4-jonathan@marek.ca> X-Mailer: git-send-email 2.26.1 In-Reply-To: <20231114174218.19765-1-jonathan@marek.ca> References: <20231114174218.19765-1-jonathan@marek.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-0.9 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lipwig.vger.email Precedence: bulk List-ID: <linux-kernel.vger.kernel.org> X-Mailing-List: linux-kernel@vger.kernel.org X-Greylist: Sender passed SPF test, not delayed by milter-greylist-4.6.4 (lipwig.vger.email [0.0.0.0]); Tue, 14 Nov 2023 09:44:54 -0800 (PST) X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1782562317102048866 X-GMAIL-MSGID: 1782562317102048866 |
Series |
[1/4] drm/msm/dsi: set VIDEO_COMPRESSION_MODE_CTRL_WC (fix video mode DSC)
|
|
Commit Message
Jonathan Marek
Nov. 14, 2023, 5:42 p.m. UTC
For the bonded DSI case, DSC pic_width and timing calculations should use
the width of a single panel instead of the total combined width.
Signed-off-by: Jonathan Marek <jonathan@marek.ca>
---
drivers/gpu/drm/msm/dsi/dsi.h | 3 ++-
drivers/gpu/drm/msm/dsi/dsi_host.c | 20 +++++++++++---------
drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +-
3 files changed, 14 insertions(+), 11 deletions(-)
Comments
On what hardware have you been testing this? Dmitry and I have a stack of patches to resolve support for Active CTL programming on newer hardware (DPU 5.0+ IIRC), where a single CTL is responsible for programming multiple INTF and DSC blocks as used in bonded DSI. On 2023-11-14 12:42:16, Jonathan Marek wrote: > For the bonded DSI case, DSC pic_width and timing calculations should use > the width of a single panel instead of the total combined width. > > Signed-off-by: Jonathan Marek <jonathan@marek.ca> > --- > drivers/gpu/drm/msm/dsi/dsi.h | 3 ++- > drivers/gpu/drm/msm/dsi/dsi_host.c | 20 +++++++++++--------- > drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +- > 3 files changed, 14 insertions(+), 11 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h > index 28379b1af63f..3a641e69447c 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi.h > +++ b/drivers/gpu/drm/msm/dsi/dsi.h > @@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host); > int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, > const struct drm_display_mode *mode); > enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > - const struct drm_display_mode *mode); > + const struct drm_display_mode *mode, > + bool is_bonded_dsi); > unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); > int msm_dsi_host_register(struct mipi_dsi_host *host); > void msm_dsi_host_unregister(struct mipi_dsi_host *host); > diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c > index 7284346ab787..a6286eb9d006 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > @@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > mode->hdisplay, mode->vdisplay); > return; > } > - > - dsc->pic_width = mode->hdisplay; > + dsc->pic_width = hdisplay; In my testing and debugging on CMDmode panels downstream this value/register was always programmed to the _full_ width of the bonded panel. Is that maybe different for video mode? > dsc->pic_height = mode->vdisplay; > DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height); > > @@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > if (ret) > return; > > + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) > + dsi_update_dsc_timing(msm_host, false, hdisplay); > + else > + dsi_update_dsc_timing(msm_host, true, hdisplay); > + Such cleanups (which appear unrelated) should probably be posted as separate patches. - Marijn > /* Divide the display by 3 but keep back/font porch and > * pulse width same > */ > @@ -966,9 +970,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > } > > if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { > - if (msm_host->dsc) > - dsi_update_dsc_timing(msm_host, false, mode->hdisplay); > - > dsi_write(msm_host, REG_DSI_ACTIVE_H, > DSI_ACTIVE_H_START(ha_start) | > DSI_ACTIVE_H_END(ha_end)); > @@ -987,9 +988,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > DSI_ACTIVE_VSYNC_VPOS_START(vs_start) | > DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); > } else { /* command mode */ > - if (msm_host->dsc) > - dsi_update_dsc_timing(msm_host, true, mode->hdisplay); > - > /* image data and 1 byte write_memory_start cmd */ > if (!msm_host->dsc) > wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; > @@ -2487,7 +2485,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, > } > > enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > - const struct drm_display_mode *mode) > + const struct drm_display_mode *mode, > + bool is_bonded_dsi) > { > struct msm_dsi_host *msm_host = to_msm_dsi_host(host); > struct drm_dsc_config *dsc = msm_host->dsc; > @@ -2497,6 +2496,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > if (!msm_host->dsc) > return MODE_OK; > > + if (is_bonded_dsi) > + pic_width = mode->hdisplay / 2; > + > if (pic_width % dsc->slice_width) { > pr_err("DSI: pic_width %d has to be multiple of slice %d\n", > pic_width, dsc->slice_width); > diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c > index 896f369fdd53..2ca1a7ca3659 100644 > --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c > +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c > @@ -455,7 +455,7 @@ static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge, > return MODE_ERROR; > } > > - return msm_dsi_host_check_dsc(host, mode); > + return msm_dsi_host_check_dsc(host, mode, IS_BONDED_DSI()); > } > > static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = { > -- > 2.26.1 >
On 11/14/23 1:28 PM, Marijn Suijten wrote: > On what hardware have you been testing this? Dmitry and I have a stack of > patches to resolve support for Active CTL programming on newer hardware (DPU > 5.0+ IIRC), where a single CTL is responsible for programming multiple INTF and > DSC blocks as used in bonded DSI. > I am also using DPU 6+ but I won't be posting patches for DPU to support this as I am not using the upstream DPU codebase. > On 2023-11-14 12:42:16, Jonathan Marek wrote: >> For the bonded DSI case, DSC pic_width and timing calculations should use >> the width of a single panel instead of the total combined width. >> >> Signed-off-by: Jonathan Marek <jonathan@marek.ca> >> --- >> drivers/gpu/drm/msm/dsi/dsi.h | 3 ++- >> drivers/gpu/drm/msm/dsi/dsi_host.c | 20 +++++++++++--------- >> drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +- >> 3 files changed, 14 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h >> index 28379b1af63f..3a641e69447c 100644 >> --- a/drivers/gpu/drm/msm/dsi/dsi.h >> +++ b/drivers/gpu/drm/msm/dsi/dsi.h >> @@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host); >> int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, >> const struct drm_display_mode *mode); >> enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, >> - const struct drm_display_mode *mode); >> + const struct drm_display_mode *mode, >> + bool is_bonded_dsi); >> unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); >> int msm_dsi_host_register(struct mipi_dsi_host *host); >> void msm_dsi_host_unregister(struct mipi_dsi_host *host); >> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c >> index 7284346ab787..a6286eb9d006 100644 >> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c >> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c >> @@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) >> mode->hdisplay, mode->vdisplay); >> return; >> } >> - >> - dsc->pic_width = mode->hdisplay; >> + dsc->pic_width = hdisplay; > > In my testing and debugging on CMDmode panels downstream this value/register > was always programmed to the _full_ width of the bonded panel. Is that maybe > different for video mode? > downstream dual DSI panel timings are specified for a single panel ("qcom,mdss-dsi-panel-width" is for a single panel, not both panels) >> dsc->pic_height = mode->vdisplay; >> DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height); >> >> @@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) >> if (ret) >> return; >> >> + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) >> + dsi_update_dsc_timing(msm_host, false, hdisplay); >> + else >> + dsi_update_dsc_timing(msm_host, true, hdisplay); >> + > > Such cleanups (which appear unrelated) should probably be posted as separate > patches. > > - Marijn > Its not unrelated, dsi_update_dsc_timing call is moved up so it can use the single-panel "hdisplay" value before it gets adjusted for DSC. >> /* Divide the display by 3 but keep back/font porch and >> * pulse width same >> */ >> @@ -966,9 +970,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) >> } >> >> if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { >> - if (msm_host->dsc) >> - dsi_update_dsc_timing(msm_host, false, mode->hdisplay); >> - >> dsi_write(msm_host, REG_DSI_ACTIVE_H, >> DSI_ACTIVE_H_START(ha_start) | >> DSI_ACTIVE_H_END(ha_end)); >> @@ -987,9 +988,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) >> DSI_ACTIVE_VSYNC_VPOS_START(vs_start) | >> DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); >> } else { /* command mode */ >> - if (msm_host->dsc) >> - dsi_update_dsc_timing(msm_host, true, mode->hdisplay); >> - >> /* image data and 1 byte write_memory_start cmd */ >> if (!msm_host->dsc) >> wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; >> @@ -2487,7 +2485,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, >> } >> >> enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, >> - const struct drm_display_mode *mode) >> + const struct drm_display_mode *mode, >> + bool is_bonded_dsi) >> { >> struct msm_dsi_host *msm_host = to_msm_dsi_host(host); >> struct drm_dsc_config *dsc = msm_host->dsc; >> @@ -2497,6 +2496,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, >> if (!msm_host->dsc) >> return MODE_OK; >> >> + if (is_bonded_dsi) >> + pic_width = mode->hdisplay / 2; >> + >> if (pic_width % dsc->slice_width) { >> pr_err("DSI: pic_width %d has to be multiple of slice %d\n", >> pic_width, dsc->slice_width); >> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c >> index 896f369fdd53..2ca1a7ca3659 100644 >> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c >> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c >> @@ -455,7 +455,7 @@ static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge, >> return MODE_ERROR; >> } >> >> - return msm_dsi_host_check_dsc(host, mode); >> + return msm_dsi_host_check_dsc(host, mode, IS_BONDED_DSI()); >> } >> >> static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = { >> -- >> 2.26.1 >>
On 2023-11-14 14:00:19, Jonathan Marek wrote: > On 11/14/23 1:28 PM, Marijn Suijten wrote: > > On what hardware have you been testing this? Dmitry and I have a stack of > > patches to resolve support for Active CTL programming on newer hardware (DPU > > 5.0+ IIRC), where a single CTL is responsible for programming multiple INTF and > > DSC blocks as used in bonded DSI. > > > > I am also using DPU 6+ but I won't be posting patches for DPU to support > this as I am not using the upstream DPU codebase. Oh that is an odd situation! At least glad to hear we aren't completely duplicating our efforts :) > > On 2023-11-14 12:42:16, Jonathan Marek wrote: > >> For the bonded DSI case, DSC pic_width and timing calculations should use > >> the width of a single panel instead of the total combined width. > >> > >> Signed-off-by: Jonathan Marek <jonathan@marek.ca> > >> --- > >> drivers/gpu/drm/msm/dsi/dsi.h | 3 ++- > >> drivers/gpu/drm/msm/dsi/dsi_host.c | 20 +++++++++++--------- > >> drivers/gpu/drm/msm/dsi/dsi_manager.c | 2 +- > >> 3 files changed, 14 insertions(+), 11 deletions(-) > >> > >> diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h > >> index 28379b1af63f..3a641e69447c 100644 > >> --- a/drivers/gpu/drm/msm/dsi/dsi.h > >> +++ b/drivers/gpu/drm/msm/dsi/dsi.h > >> @@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host); > >> int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, > >> const struct drm_display_mode *mode); > >> enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > >> - const struct drm_display_mode *mode); > >> + const struct drm_display_mode *mode, > >> + bool is_bonded_dsi); > >> unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); > >> int msm_dsi_host_register(struct mipi_dsi_host *host); > >> void msm_dsi_host_unregister(struct mipi_dsi_host *host); > >> diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c > >> index 7284346ab787..a6286eb9d006 100644 > >> --- a/drivers/gpu/drm/msm/dsi/dsi_host.c > >> +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c > >> @@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > >> mode->hdisplay, mode->vdisplay); > >> return; > >> } > >> - > >> - dsc->pic_width = mode->hdisplay; > >> + dsc->pic_width = hdisplay; > > > > In my testing and debugging on CMDmode panels downstream this value/register > > was always programmed to the _full_ width of the bonded panel. Is that maybe > > different for video mode? > > > > downstream dual DSI panel timings are specified for a single panel > ("qcom,mdss-dsi-panel-width" is for a single panel, not both panels) _dual panels_? In my case I have a "single panel" that is driven by two "bonded" DSI hosts, just to achieve enough bandwidth. Indeed my downstream DTS has qcom,mdss-dsi-panel-width set to half the total panel width, but I recall seeing the full width in the register dump. I'll scan through my logs and see if I can back this up. > >> dsc->pic_height = mode->vdisplay; > >> DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height); > >> > >> @@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > >> if (ret) > >> return; > >> > >> + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) > >> + dsi_update_dsc_timing(msm_host, false, hdisplay); > >> + else > >> + dsi_update_dsc_timing(msm_host, true, hdisplay); Another thought: it's probably clearer to write: bool is_cmd_mode = msm_host->mode_flags & MIPI_DSI_MODE_VIDEO; dsi_update_dsc_timing(msm_host, is_cmd_mode, hdisplay); > >> + > > > > Such cleanups (which appear unrelated) should probably be posted as separate > > patches. > > > > - Marijn > > > > Its not unrelated, dsi_update_dsc_timing call is moved up so it can use > the single-panel "hdisplay" value before it gets adjusted for DSC. This reply was mostly expected after not looking at the original code folded in the diff, and pretty much solidifies my point: it's a hidden semantical change that's not immediately obvious from reading the patch, and why I'd like to see this split up in a few smaller patches. > >> /* Divide the display by 3 but keep back/font porch and > >> * pulse width same > >> */ > >> @@ -966,9 +970,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > >> } > >> > >> if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { > >> - if (msm_host->dsc) > >> - dsi_update_dsc_timing(msm_host, false, mode->hdisplay); > >> - > >> dsi_write(msm_host, REG_DSI_ACTIVE_H, > >> DSI_ACTIVE_H_START(ha_start) | > >> DSI_ACTIVE_H_END(ha_end)); > >> @@ -987,9 +988,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) > >> DSI_ACTIVE_VSYNC_VPOS_START(vs_start) | > >> DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); > >> } else { /* command mode */ > >> - if (msm_host->dsc) > >> - dsi_update_dsc_timing(msm_host, true, mode->hdisplay); > >> - > >> /* image data and 1 byte write_memory_start cmd */ > >> if (!msm_host->dsc) > >> wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; Regarding another patch: cmdmode calculates and uses word count here, but video mode does it as part of timing calculations? - Marijn > >> @@ -2487,7 +2485,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, > >> } > >> > >> enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > >> - const struct drm_display_mode *mode) > >> + const struct drm_display_mode *mode, > >> + bool is_bonded_dsi) > >> { > >> struct msm_dsi_host *msm_host = to_msm_dsi_host(host); > >> struct drm_dsc_config *dsc = msm_host->dsc; > >> @@ -2497,6 +2496,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, > >> if (!msm_host->dsc) > >> return MODE_OK; > >> > >> + if (is_bonded_dsi) > >> + pic_width = mode->hdisplay / 2; > >> + > >> if (pic_width % dsc->slice_width) { > >> pr_err("DSI: pic_width %d has to be multiple of slice %d\n", > >> pic_width, dsc->slice_width); > >> diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c > >> index 896f369fdd53..2ca1a7ca3659 100644 > >> --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c > >> +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c > >> @@ -455,7 +455,7 @@ static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge, > >> return MODE_ERROR; > >> } > >> > >> - return msm_dsi_host_check_dsc(host, mode); > >> + return msm_dsi_host_check_dsc(host, mode, IS_BONDED_DSI()); > >> } > >> > >> static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = { > >> -- > >> 2.26.1 > >>
diff --git a/drivers/gpu/drm/msm/dsi/dsi.h b/drivers/gpu/drm/msm/dsi/dsi.h index 28379b1af63f..3a641e69447c 100644 --- a/drivers/gpu/drm/msm/dsi/dsi.h +++ b/drivers/gpu/drm/msm/dsi/dsi.h @@ -93,7 +93,8 @@ int msm_dsi_host_power_off(struct mipi_dsi_host *host); int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, const struct drm_display_mode *mode); enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, - const struct drm_display_mode *mode); + const struct drm_display_mode *mode, + bool is_bonded_dsi); unsigned long msm_dsi_host_get_mode_flags(struct mipi_dsi_host *host); int msm_dsi_host_register(struct mipi_dsi_host *host); void msm_dsi_host_unregister(struct mipi_dsi_host *host); diff --git a/drivers/gpu/drm/msm/dsi/dsi_host.c b/drivers/gpu/drm/msm/dsi/dsi_host.c index 7284346ab787..a6286eb9d006 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_host.c +++ b/drivers/gpu/drm/msm/dsi/dsi_host.c @@ -938,8 +938,7 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) mode->hdisplay, mode->vdisplay); return; } - - dsc->pic_width = mode->hdisplay; + dsc->pic_width = hdisplay; dsc->pic_height = mode->vdisplay; DBG("Mode %dx%d\n", dsc->pic_width, dsc->pic_height); @@ -950,6 +949,11 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) if (ret) return; + if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) + dsi_update_dsc_timing(msm_host, false, hdisplay); + else + dsi_update_dsc_timing(msm_host, true, hdisplay); + /* Divide the display by 3 but keep back/font porch and * pulse width same */ @@ -966,9 +970,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) } if (msm_host->mode_flags & MIPI_DSI_MODE_VIDEO) { - if (msm_host->dsc) - dsi_update_dsc_timing(msm_host, false, mode->hdisplay); - dsi_write(msm_host, REG_DSI_ACTIVE_H, DSI_ACTIVE_H_START(ha_start) | DSI_ACTIVE_H_END(ha_end)); @@ -987,9 +988,6 @@ static void dsi_timing_setup(struct msm_dsi_host *msm_host, bool is_bonded_dsi) DSI_ACTIVE_VSYNC_VPOS_START(vs_start) | DSI_ACTIVE_VSYNC_VPOS_END(vs_end)); } else { /* command mode */ - if (msm_host->dsc) - dsi_update_dsc_timing(msm_host, true, mode->hdisplay); - /* image data and 1 byte write_memory_start cmd */ if (!msm_host->dsc) wc = hdisplay * dsi_get_bpp(msm_host->format) / 8 + 1; @@ -2487,7 +2485,8 @@ int msm_dsi_host_set_display_mode(struct mipi_dsi_host *host, } enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, - const struct drm_display_mode *mode) + const struct drm_display_mode *mode, + bool is_bonded_dsi) { struct msm_dsi_host *msm_host = to_msm_dsi_host(host); struct drm_dsc_config *dsc = msm_host->dsc; @@ -2497,6 +2496,9 @@ enum drm_mode_status msm_dsi_host_check_dsc(struct mipi_dsi_host *host, if (!msm_host->dsc) return MODE_OK; + if (is_bonded_dsi) + pic_width = mode->hdisplay / 2; + if (pic_width % dsc->slice_width) { pr_err("DSI: pic_width %d has to be multiple of slice %d\n", pic_width, dsc->slice_width); diff --git a/drivers/gpu/drm/msm/dsi/dsi_manager.c b/drivers/gpu/drm/msm/dsi/dsi_manager.c index 896f369fdd53..2ca1a7ca3659 100644 --- a/drivers/gpu/drm/msm/dsi/dsi_manager.c +++ b/drivers/gpu/drm/msm/dsi/dsi_manager.c @@ -455,7 +455,7 @@ static enum drm_mode_status dsi_mgr_bridge_mode_valid(struct drm_bridge *bridge, return MODE_ERROR; } - return msm_dsi_host_check_dsc(host, mode); + return msm_dsi_host_check_dsc(host, mode, IS_BONDED_DSI()); } static const struct drm_bridge_funcs dsi_mgr_bridge_funcs = {