From mboxrd@z Thu Jan 1 00:00:00 1970 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 46554D62603 for ; Thu, 22 Jan 2026 08:36:40 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id EB41C10E926; Thu, 22 Jan 2026 08:36:34 +0000 (UTC) Authentication-Results: gabe.freedesktop.org; dkim=pass (1024-bit key; unprotected) header.d=collabora.com header.i=nicolas.frattaroli@collabora.com header.b="Vlm7SXMW"; dkim-atps=neutral Received: from sender4-pp-f112.zoho.com (sender4-pp-f112.zoho.com [136.143.188.112]) by gabe.freedesktop.org (Postfix) with ESMTPS id 3A66710E7AA; Wed, 21 Jan 2026 13:48:02 +0000 (UTC) ARC-Seal: i=1; a=rsa-sha256; t=1769003275; cv=none; d=zohomail.com; s=zohoarc; b=lheahf/rqBGLL9wRKdlRo/hKbMuZ66G+Lhp0HOh3O0V6h8c9asYS0QY3Rf9Pds8ViMiMzfESGLh0Qzhmo6AGTtj/KIzvkKgYWQClSRCmx67nr8ctcMBDnwbVOaGZGJCHo5XkRKEyiYQvFWOpQLG8GRyAnCzAhcrAPog96zceKJY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1769003275; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=qFgsuYFcKp2aiHu+Dr9JQBFDziu8Ye39CXeQpE5eav4=; b=hnxeg2xn4vGqabC2FDRluYhwptcK7pU4Uw5AUiys7yB207p49EQCDWkexA9PVkQA79i0w7zkdOAkxaJsq+fJPUIiK8QDpQrWFF2lre8FGqYNIRMzSjTDWFlL67mdAn7hNnoInEOonnc3ULrS/XkHvbYfJKhIjzemhvAtCuv5pb8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1769003275; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=qFgsuYFcKp2aiHu+Dr9JQBFDziu8Ye39CXeQpE5eav4=; b=Vlm7SXMW63gsARKK18CZt2K/X/hHkLzfOAUdTPYaHE3hImUan7op/N+n+Umq9NpK cbhGJh9Q6SMpaYqgKqG4rxbeYAiSsGuD8AEuwbIcwSjuRIJgvnQoIN23CRY1JgXSegX c9aNR+JafHO/bZ+lPT7jWsf+ZcZpP53N2TWqAb8Q= Received: by mx.zohomail.com with SMTPS id 1769003273659128.66489880127222; Wed, 21 Jan 2026 05:47:53 -0800 (PST) From: Nicolas Frattaroli Date: Wed, 21 Jan 2026 14:45:41 +0100 Subject: [PATCH v6 15/21] drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260121-color-format-v6-15-7b81a771cd0b@collabora.com> References: <20260121-color-format-v6-0-7b81a771cd0b@collabora.com> In-Reply-To: <20260121-color-format-v6-0-7b81a771cd0b@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 X-Mailman-Approved-At: Thu, 22 Jan 2026 08:36:26 +0000 X-BeenThere: amd-gfx@lists.freedesktop.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Discussion list for AMD gfx List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: amd-gfx-bounces@lists.freedesktop.org Sender: "amd-gfx" Switch between requested color formats by setting the right bus formats, configuring the VO GRF registers, and setting the right output mode. To do this, the encoder's atomic_check queries the bus format of the first bridge, which was determined by the bridge chain recursive format selection. Pick the input format if it's !FIXED, otherwise, pick the output format. The previously unused GRF register color format defines are redone as well. Both RK3588 and RK3576 use the same defines; it didn't look like this as there was a typo in the previously (unused) definition. Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 107 ++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c index 1a09bcc96c3e..d39a4284b92c 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -43,10 +44,6 @@ #define RK3576_8BPC 0x0 #define RK3576_10BPC 0x6 #define RK3576_COLOR_FORMAT_MASK GENMASK(7, 4) -#define RK3576_RGB 0x9 -#define RK3576_YUV422 0x1 -#define RK3576_YUV444 0x2 -#define RK3576_YUV420 0x3 #define RK3576_CECIN_MASK BIT(3) #define RK3576_VO0_GRF_SOC_CON14 0x0038 @@ -74,8 +71,6 @@ #define RK3588_8BPC 0x0 #define RK3588_10BPC 0x6 #define RK3588_COLOR_FORMAT_MASK GENMASK(3, 0) -#define RK3588_RGB 0x0 -#define RK3588_YUV420 0x3 #define RK3588_SCLIN_MASK BIT(9) #define RK3588_SDAIN_MASK BIT(10) #define RK3588_MODE_MASK BIT(11) @@ -87,6 +82,11 @@ #define HOTPLUG_DEBOUNCE_MS 150 #define MAX_HDMI_PORT_NUM 2 +#define RK_COLOR_FMT_RGB 0x0 +#define RK_COLOR_FMT_YUV422 0x1 +#define RK_COLOR_FMT_YUV444 0x2 +#define RK_COLOR_FMT_YUV420 0x3 + struct rockchip_hdmi_qp { struct device *dev; struct regmap *regmap; @@ -115,6 +115,33 @@ static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder) return container_of(rkencoder, struct rockchip_hdmi_qp, encoder); } +/** + * dw_hdmi_qp_rockchip_bus_fmt_to_reg - converts a bus format to a GRF reg value + * @bus_fmt: One of the MEDIA_BUS_FMT_s allowed by this driver's atomic_check + * + * Returns: an unshifted value to be written to the COLOR_FORMAT GRF register + * on success, or %-EINVAL if the bus format is not supported. + */ +static int __pure dw_hdmi_qp_rockchip_bus_fmt_to_reg(u32 bus_fmt) +{ + switch (bus_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB101010_1X30: + return RK_COLOR_FMT_RGB; + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY10_1X20: + return RK_COLOR_FMT_YUV422; + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + return RK_COLOR_FMT_YUV444; + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + return RK_COLOR_FMT_YUV420; + } + + return -EINVAL; +} + static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) { struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); @@ -130,29 +157,83 @@ static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) hdmi->ctrl_ops->enc_init(hdmi, to_rockchip_crtc_state(crtc->state)); } +/** + * dw_hdmi_qp_rockchip_get_vop_format - get the bus format VOP should output + * @encoder: pointer to a &struct drm_encoder + * @conn_state: pointer to the current atomic &struct drm_connector_state + * + * Determines which bus format the Rockchip video processor should output as + * to feed into the bridge chain. + * + * Returns a MEDIA_BUS_FMT_* on success, or %0 on error. + */ +static u32 dw_hdmi_qp_rockchip_get_vop_format(struct drm_encoder *encoder, + struct drm_connector_state *conn_state) +{ + struct drm_bridge *bridge __free(drm_bridge_put) = NULL; + struct drm_bridge_state *bstate; + + bridge = drm_bridge_chain_get_first_bridge(encoder); + if (!bridge) + return 0; + + bstate = drm_atomic_get_bridge_state(conn_state->state, bridge); + if (!bstate) + return 0; + + if (bstate->input_bus_cfg.format != MEDIA_BUS_FMT_FIXED) + return bstate->input_bus_cfg.format; + + return bstate->output_bus_cfg.format; +} + static int dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); union phy_configure_opts phy_cfg = {}; + u32 ingest_fmt; int ret; + ingest_fmt = dw_hdmi_qp_rockchip_get_vop_format(encoder, conn_state); + if (!ingest_fmt) + return -EINVAL; + if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate && - s->output_bpc == conn_state->hdmi.output_bpc) + s->output_bpc == conn_state->hdmi.output_bpc && + s->bus_format == ingest_fmt) return 0; + switch (ingest_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + break; + case MEDIA_BUS_FMT_UYVY8_1X16: + s->output_mode = ROCKCHIP_OUT_MODE_YUV422; + break; + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + s->output_mode = ROCKCHIP_OUT_MODE_YUV420; + break; + default: + return -EINVAL; + } + phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate; phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc; ret = phy_configure(hdmi->phy, &phy_cfg); if (!ret) { hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate; - s->output_mode = ROCKCHIP_OUT_MODE_AAAA; s->output_type = DRM_MODE_CONNECTOR_HDMIA; s->output_bpc = conn_state->hdmi.output_bpc; + s->bus_format = ingest_fmt; } else { dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret); } @@ -382,6 +463,7 @@ static void dw_hdmi_qp_rk3588_io_init(struct rockchip_hdmi_qp *hdmi) static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi, struct rockchip_crtc_state *state) { + int color = dw_hdmi_qp_rockchip_bus_fmt_to_reg(state->bus_format); u32 val; if (state->output_bpc == 10) @@ -389,12 +471,16 @@ static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi, else val = FIELD_PREP_WM16(RK3576_COLOR_DEPTH_MASK, RK3576_8BPC); + if (likely(color > 0)) + val |= FIELD_PREP_WM16(RK3576_COLOR_FORMAT_MASK, color); + regmap_write(hdmi->vo_regmap, RK3576_VO0_GRF_SOC_CON8, val); } static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi, struct rockchip_crtc_state *state) { + int color = dw_hdmi_qp_rockchip_bus_fmt_to_reg(state->bus_format); u32 val; if (state->output_bpc == 10) @@ -402,6 +488,9 @@ static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi, else val = FIELD_PREP_WM16(RK3588_COLOR_DEPTH_MASK, RK3588_8BPC); + if (likely(color > 0)) + val |= FIELD_PREP_WM16(RK3588_COLOR_FORMAT_MASK, color); + regmap_write(hdmi->vo_regmap, hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3, val); -- 2.52.0 From mboxrd@z Thu Jan 1 00:00:00 1970 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 bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (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 79275C4453D for ; Wed, 21 Jan 2026 13:48:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:Cc:To:In-Reply-To:References:Message-Id :MIME-Version:Subject:Date:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=l9lBCbVbavu733CZ4USaigSjiAA9ZIKPcHrJPY0VAwI=; b=0E3kxD81erWna5 BMVWhYwtn1E1lPYS5spH2ruUF2YeyBDuvAwLT4NpagyVBdQuvz2OKnMqcesK4J+t56/m4LG1P0jgZ K74MAN06GxN3dpbXIU7HVbO/e6VdQyiiKpl3/uacD/KlEV+en1PXlQk/06eiia03deU6WoaIquox2 2iXptsoW1hefzVBx08M/nKek9rzixA4QiW+5hqVW2P4Ixj7nuUjCMfgASNIfaN/akdt87YrgPvLLX ZirPaCEEWVFt3AC+T94oQCbFoKvOCeKTArdULB13gLZKK7D8vaYTzj8ATeahz1xrfnfmbWixHhmW/ sSfM0unYjM9reIVWvU7Q==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.98.2 #2 (Red Hat Linux)) id 1viYZV-00000005Wom-1POD; Wed, 21 Jan 2026 13:48:33 +0000 Received: from sender4-pp-f112.zoho.com ([136.143.188.112]) by bombadil.infradead.org with esmtps (Exim 4.98.2 #2 (Red Hat Linux)) id 1viYZO-00000005Wht-1xBz; Wed, 21 Jan 2026 13:48:29 +0000 ARC-Seal: i=1; a=rsa-sha256; t=1769003275; cv=none; d=zohomail.com; s=zohoarc; b=lheahf/rqBGLL9wRKdlRo/hKbMuZ66G+Lhp0HOh3O0V6h8c9asYS0QY3Rf9Pds8ViMiMzfESGLh0Qzhmo6AGTtj/KIzvkKgYWQClSRCmx67nr8ctcMBDnwbVOaGZGJCHo5XkRKEyiYQvFWOpQLG8GRyAnCzAhcrAPog96zceKJY= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1769003275; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:MIME-Version:Message-ID:References:Subject:Subject:To:To:Message-Id:Reply-To; bh=qFgsuYFcKp2aiHu+Dr9JQBFDziu8Ye39CXeQpE5eav4=; b=hnxeg2xn4vGqabC2FDRluYhwptcK7pU4Uw5AUiys7yB207p49EQCDWkexA9PVkQA79i0w7zkdOAkxaJsq+fJPUIiK8QDpQrWFF2lre8FGqYNIRMzSjTDWFlL67mdAn7hNnoInEOonnc3ULrS/XkHvbYfJKhIjzemhvAtCuv5pb8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass header.i=collabora.com; spf=pass smtp.mailfrom=nicolas.frattaroli@collabora.com; dmarc=pass header.from= DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1769003275; s=zohomail; d=collabora.com; i=nicolas.frattaroli@collabora.com; h=From:From:Date:Date:Subject:Subject:MIME-Version:Content-Type:Content-Transfer-Encoding:Message-Id:Message-Id:References:In-Reply-To:To:To:Cc:Cc:Reply-To; bh=qFgsuYFcKp2aiHu+Dr9JQBFDziu8Ye39CXeQpE5eav4=; b=Vlm7SXMW63gsARKK18CZt2K/X/hHkLzfOAUdTPYaHE3hImUan7op/N+n+Umq9NpK cbhGJh9Q6SMpaYqgKqG4rxbeYAiSsGuD8AEuwbIcwSjuRIJgvnQoIN23CRY1JgXSegX c9aNR+JafHO/bZ+lPT7jWsf+ZcZpP53N2TWqAb8Q= Received: by mx.zohomail.com with SMTPS id 1769003273659128.66489880127222; Wed, 21 Jan 2026 05:47:53 -0800 (PST) From: Nicolas Frattaroli Date: Wed, 21 Jan 2026 14:45:41 +0100 Subject: [PATCH v6 15/21] drm/rockchip: dw_hdmi_qp: Implement "color format" DRM property MIME-Version: 1.0 Message-Id: <20260121-color-format-v6-15-7b81a771cd0b@collabora.com> References: <20260121-color-format-v6-0-7b81a771cd0b@collabora.com> In-Reply-To: <20260121-color-format-v6-0-7b81a771cd0b@collabora.com> To: Harry Wentland , Leo Li , Rodrigo Siqueira , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , David Airlie , Simona Vetter , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Sandy Huang , =?utf-8?q?Heiko_St=C3=BCbner?= , Andy Yan , Jani Nikula , Rodrigo Vivi , Joonas Lahtinen , Tvrtko Ursulin , Dmitry Baryshkov , Sascha Hauer , Rob Herring , Jonathan Corbet Cc: kernel@collabora.com, amd-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-rockchip@lists.infradead.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, linux-doc@vger.kernel.org, Nicolas Frattaroli X-Mailer: b4 0.14.3 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20260121_054826_645400_90F3D932 X-CRM114-Status: GOOD ( 20.93 ) X-BeenThere: linux-rockchip@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Upstream kernel work for Rockchip platforms List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-rockchip" Errors-To: linux-rockchip-bounces+linux-rockchip=archiver.kernel.org@lists.infradead.org Switch between requested color formats by setting the right bus formats, configuring the VO GRF registers, and setting the right output mode. To do this, the encoder's atomic_check queries the bus format of the first bridge, which was determined by the bridge chain recursive format selection. Pick the input format if it's !FIXED, otherwise, pick the output format. The previously unused GRF register color format defines are redone as well. Both RK3588 and RK3576 use the same defines; it didn't look like this as there was a typo in the previously (unused) definition. Signed-off-by: Nicolas Frattaroli --- drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c | 107 ++++++++++++++++++++++--- 1 file changed, 98 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c index 1a09bcc96c3e..d39a4284b92c 100644 --- a/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c +++ b/drivers/gpu/drm/rockchip/dw_hdmi_qp-rockchip.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -43,10 +44,6 @@ #define RK3576_8BPC 0x0 #define RK3576_10BPC 0x6 #define RK3576_COLOR_FORMAT_MASK GENMASK(7, 4) -#define RK3576_RGB 0x9 -#define RK3576_YUV422 0x1 -#define RK3576_YUV444 0x2 -#define RK3576_YUV420 0x3 #define RK3576_CECIN_MASK BIT(3) #define RK3576_VO0_GRF_SOC_CON14 0x0038 @@ -74,8 +71,6 @@ #define RK3588_8BPC 0x0 #define RK3588_10BPC 0x6 #define RK3588_COLOR_FORMAT_MASK GENMASK(3, 0) -#define RK3588_RGB 0x0 -#define RK3588_YUV420 0x3 #define RK3588_SCLIN_MASK BIT(9) #define RK3588_SDAIN_MASK BIT(10) #define RK3588_MODE_MASK BIT(11) @@ -87,6 +82,11 @@ #define HOTPLUG_DEBOUNCE_MS 150 #define MAX_HDMI_PORT_NUM 2 +#define RK_COLOR_FMT_RGB 0x0 +#define RK_COLOR_FMT_YUV422 0x1 +#define RK_COLOR_FMT_YUV444 0x2 +#define RK_COLOR_FMT_YUV420 0x3 + struct rockchip_hdmi_qp { struct device *dev; struct regmap *regmap; @@ -115,6 +115,33 @@ static struct rockchip_hdmi_qp *to_rockchip_hdmi_qp(struct drm_encoder *encoder) return container_of(rkencoder, struct rockchip_hdmi_qp, encoder); } +/** + * dw_hdmi_qp_rockchip_bus_fmt_to_reg - converts a bus format to a GRF reg value + * @bus_fmt: One of the MEDIA_BUS_FMT_s allowed by this driver's atomic_check + * + * Returns: an unshifted value to be written to the COLOR_FORMAT GRF register + * on success, or %-EINVAL if the bus format is not supported. + */ +static int __pure dw_hdmi_qp_rockchip_bus_fmt_to_reg(u32 bus_fmt) +{ + switch (bus_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB101010_1X30: + return RK_COLOR_FMT_RGB; + case MEDIA_BUS_FMT_UYVY8_1X16: + case MEDIA_BUS_FMT_UYVY10_1X20: + return RK_COLOR_FMT_YUV422; + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + return RK_COLOR_FMT_YUV444; + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + return RK_COLOR_FMT_YUV420; + } + + return -EINVAL; +} + static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) { struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); @@ -130,29 +157,83 @@ static void dw_hdmi_qp_rockchip_encoder_enable(struct drm_encoder *encoder) hdmi->ctrl_ops->enc_init(hdmi, to_rockchip_crtc_state(crtc->state)); } +/** + * dw_hdmi_qp_rockchip_get_vop_format - get the bus format VOP should output + * @encoder: pointer to a &struct drm_encoder + * @conn_state: pointer to the current atomic &struct drm_connector_state + * + * Determines which bus format the Rockchip video processor should output as + * to feed into the bridge chain. + * + * Returns a MEDIA_BUS_FMT_* on success, or %0 on error. + */ +static u32 dw_hdmi_qp_rockchip_get_vop_format(struct drm_encoder *encoder, + struct drm_connector_state *conn_state) +{ + struct drm_bridge *bridge __free(drm_bridge_put) = NULL; + struct drm_bridge_state *bstate; + + bridge = drm_bridge_chain_get_first_bridge(encoder); + if (!bridge) + return 0; + + bstate = drm_atomic_get_bridge_state(conn_state->state, bridge); + if (!bstate) + return 0; + + if (bstate->input_bus_cfg.format != MEDIA_BUS_FMT_FIXED) + return bstate->input_bus_cfg.format; + + return bstate->output_bus_cfg.format; +} + static int dw_hdmi_qp_rockchip_encoder_atomic_check(struct drm_encoder *encoder, struct drm_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state); + struct rockchip_hdmi_qp *hdmi = to_rockchip_hdmi_qp(encoder); union phy_configure_opts phy_cfg = {}; + u32 ingest_fmt; int ret; + ingest_fmt = dw_hdmi_qp_rockchip_get_vop_format(encoder, conn_state); + if (!ingest_fmt) + return -EINVAL; + if (hdmi->tmds_char_rate == conn_state->hdmi.tmds_char_rate && - s->output_bpc == conn_state->hdmi.output_bpc) + s->output_bpc == conn_state->hdmi.output_bpc && + s->bus_format == ingest_fmt) return 0; + switch (ingest_fmt) { + case MEDIA_BUS_FMT_RGB888_1X24: + case MEDIA_BUS_FMT_RGB101010_1X30: + case MEDIA_BUS_FMT_YUV8_1X24: + case MEDIA_BUS_FMT_YUV10_1X30: + s->output_mode = ROCKCHIP_OUT_MODE_AAAA; + break; + case MEDIA_BUS_FMT_UYVY8_1X16: + s->output_mode = ROCKCHIP_OUT_MODE_YUV422; + break; + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: + s->output_mode = ROCKCHIP_OUT_MODE_YUV420; + break; + default: + return -EINVAL; + } + phy_cfg.hdmi.tmds_char_rate = conn_state->hdmi.tmds_char_rate; phy_cfg.hdmi.bpc = conn_state->hdmi.output_bpc; ret = phy_configure(hdmi->phy, &phy_cfg); if (!ret) { hdmi->tmds_char_rate = conn_state->hdmi.tmds_char_rate; - s->output_mode = ROCKCHIP_OUT_MODE_AAAA; s->output_type = DRM_MODE_CONNECTOR_HDMIA; s->output_bpc = conn_state->hdmi.output_bpc; + s->bus_format = ingest_fmt; } else { dev_err(hdmi->dev, "Failed to configure phy: %d\n", ret); } @@ -382,6 +463,7 @@ static void dw_hdmi_qp_rk3588_io_init(struct rockchip_hdmi_qp *hdmi) static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi, struct rockchip_crtc_state *state) { + int color = dw_hdmi_qp_rockchip_bus_fmt_to_reg(state->bus_format); u32 val; if (state->output_bpc == 10) @@ -389,12 +471,16 @@ static void dw_hdmi_qp_rk3576_enc_init(struct rockchip_hdmi_qp *hdmi, else val = FIELD_PREP_WM16(RK3576_COLOR_DEPTH_MASK, RK3576_8BPC); + if (likely(color > 0)) + val |= FIELD_PREP_WM16(RK3576_COLOR_FORMAT_MASK, color); + regmap_write(hdmi->vo_regmap, RK3576_VO0_GRF_SOC_CON8, val); } static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi, struct rockchip_crtc_state *state) { + int color = dw_hdmi_qp_rockchip_bus_fmt_to_reg(state->bus_format); u32 val; if (state->output_bpc == 10) @@ -402,6 +488,9 @@ static void dw_hdmi_qp_rk3588_enc_init(struct rockchip_hdmi_qp *hdmi, else val = FIELD_PREP_WM16(RK3588_COLOR_DEPTH_MASK, RK3588_8BPC); + if (likely(color > 0)) + val |= FIELD_PREP_WM16(RK3588_COLOR_FORMAT_MASK, color); + regmap_write(hdmi->vo_regmap, hdmi->port_id ? RK3588_GRF_VO1_CON6 : RK3588_GRF_VO1_CON3, val); -- 2.52.0 _______________________________________________ Linux-rockchip mailing list Linux-rockchip@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-rockchip