Received: by 2002:a25:ab43:0:0:0:0:0 with SMTP id u61csp3956548ybi; Mon, 27 May 2019 08:32:59 -0700 (PDT) X-Google-Smtp-Source: APXvYqx+DyBZPhC/ow6r6iPz99IcQbze8UkPyB42LDMRElYtVSyWsshceLN5sdOAoZeAnEGGHBTz X-Received: by 2002:a17:90a:ac18:: with SMTP id o24mr32960468pjq.116.1558971179682; Mon, 27 May 2019 08:32:59 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1558971179; cv=none; d=google.com; s=arc-20160816; b=jxFvrdTCGTKTyDSGuCYA3TILAjImrXkIJO65Udzy1oFCVsJJZ3dGvUbqndWtq0rb3y NoH0PJvoOQcBxAScc+/SkSRWS675GjNyF2k/MKhKeKEclJnC/Y/hvei2Da5cs7fu8Q2t cGGdCnLufpxNLgDc16ESuyr8Px3qVd5gOQ5C5k3n4Ohg6QM9eqVgb3UnsXIfSlsKGRW4 zjDA84CmOxBE4PJx6Ir/T0zVoTL4wMEakKQe1GCsEObhp+Oom/9WVIo64S0S7l4DnlN/ QK1DQboarOLKMVdap24Bo82djYbOyZZiNXgNy5ZHsmVbrWvsYdzECLeryVt5vUUkpBsD WIzw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=3fJ/HEQjswtwhFQSFYmErJntB702nw6TffMIb1Mi4O0=; b=tb2UFRztB6ubDfi7G5E7Wz+gNWDdL0fD4PcsTCAyEDytniiONQmFii7VFc0BKNR5LF gdgPOt0hLw6U1fpGkpN52OIE37Dgx+rj2rDFIziP0YeEMDjq8/uG/h2+D/k/84TryCFO GPgEAz9Y6xrvH/GvS6Z4eExWm3mvqAn+X99r7sba//d71Yc1aJn6WNNf6R6srv49IMuK RI8qFzdYPJFaXPFR/w/XodcOOk759bPYEp3rUxbWVyw1ongYpzxulW5tKXWHcP+pXLkh V1RuMS8vdvw2VWJOS4WKjCrhqzj1cl4pwQEnCPAsGVKJbeJUL8mY9xsULC1vhaEixJv+ Dpew== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=siol.net Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id m1si19133728pgt.93.2019.05.27.08.32.42; Mon, 27 May 2019 08:32:59 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=siol.net Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726670AbfE0PaQ (ORCPT + 99 others); Mon, 27 May 2019 11:30:16 -0400 Received: from mailoutvs55.siol.net ([185.57.226.246]:47807 "EHLO mail.siol.net" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726115AbfE0PaP (ORCPT ); Mon, 27 May 2019 11:30:15 -0400 Received: from localhost (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTP id 65F0A522B8D; Mon, 27 May 2019 17:30:10 +0200 (CEST) X-Virus-Scanned: amavisd-new at psrvmta10.zcs-production.pri Received: from mail.siol.net ([127.0.0.1]) by localhost (psrvmta10.zcs-production.pri [127.0.0.1]) (amavisd-new, port 10032) with ESMTP id AsIJkzKwdpyq; Mon, 27 May 2019 17:30:09 +0200 (CEST) Received: from mail.siol.net (localhost [127.0.0.1]) by mail.siol.net (Postfix) with ESMTPS id BDA28522C5D; Mon, 27 May 2019 17:30:09 +0200 (CEST) Received: from jernej-laptop.localnet (cpe-86-58-52-202.static.triera.net [86.58.52.202]) (Authenticated sender: jernej.skrabec@siol.net) by mail.siol.net (Postfix) with ESMTPA id 32F84522B8D; Mon, 27 May 2019 17:30:09 +0200 (CEST) From: Jernej =?utf-8?B?xaBrcmFiZWM=?= To: Neil Armstrong Cc: a.hajda@samsung.com, Laurent.pinchart@ideasonboard.com, jonas@kwiboo.se, hverkuil@xs4all.nl, dri-devel@lists.freedesktop.org, heiko@sntech.de, maxime.ripard@bootlin.com, hjc@rock-chips.com, linux-amlogic@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [PATCH 3/5] drm/bridge: dw-hdmi: Add support for dynamic output format setup Date: Mon, 27 May 2019 17:30:08 +0200 Message-ID: <6496480.LkDOl06ZB3@jernej-laptop> In-Reply-To: <20190520133753.23871-4-narmstrong@baylibre.com> References: <20190520133753.23871-1-narmstrong@baylibre.com> <20190520133753.23871-4-narmstrong@baylibre.com> MIME-Version: 1.0 Content-Transfer-Encoding: 7Bit Content-Type: text/plain; charset="us-ascii" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi! Dne ponedeljek, 20. maj 2019 ob 15:37:51 CEST je Neil Armstrong napisal(a): > In order to support the HDMI2.0 YUV420, YUV422 and the 10bit, 12bit and > 16bits outpu use cases, add support for the recently introduced bridge > callback format_set(). > > This callback will setup the new input format and encoding from encoder, > then these information will be used instead of the default ones > in the dw_hdmi_setup() function. > > To determine the output bus format, has been added : > - support for the connector display_info bus_formats, where a fixed > output bus format can be enforced by the encoder > - support for synami output bus format depending on the input format, > especially the YUV420 input bus format, enforcing YUV420 as output > with the correct bit depth > > Signed-off-by: Neil Armstrong > --- > drivers/gpu/drm/bridge/synopsys/dw-hdmi.c | 121 ++++++++++++++++++++-- > 1 file changed, 112 insertions(+), 9 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c index > b50c49caf7ae..284ce59be8f8 100644 > --- a/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > +++ b/drivers/gpu/drm/bridge/synopsys/dw-hdmi.c > @@ -103,6 +103,8 @@ struct hdmi_vmode { > }; > > struct hdmi_data_info { > + unsigned int bridge_in_bus_format; > + unsigned int bridge_in_encoding; > unsigned int enc_in_bus_format; > unsigned int enc_out_bus_format; > unsigned int enc_in_encoding; > @@ -1838,8 +1840,51 @@ static void hdmi_disable_overflow_interrupts(struct > dw_hdmi *hdmi) HDMI_IH_MUTE_FC_STAT2); > } > > +/* > + * The DW-HDMI CSC can only interpolate and decimate from 4:2:2 to > 4:4:4/RGB + * and from 4:4:4/RGB to 4:2:2. > + * Default to RGB output except if 4:2:0 as input, which CSC cannot > convert. + */ > +static unsigned long dw_hdmi_determine_output_bus_format(struct dw_hdmi > *hdmi) +{ > + unsigned int depth = hdmi_bus_fmt_color_depth( > + hdmi- >hdmi_data.enc_in_bus_format); > + bool is_420 = hdmi_bus_fmt_is_yuv420(hdmi- >hdmi_data.enc_in_bus_format); > + unsigned long fmt = MEDIA_BUS_FMT_RGB888_1X24; > + > + switch (depth) { > + case 8: > + if (is_420) > + fmt = MEDIA_BUS_FMT_UYYVYY8_0_5X24; > + else > + fmt = MEDIA_BUS_FMT_RGB888_1X24; > + break; > + case 10: > + if (is_420) > + fmt = MEDIA_BUS_FMT_UYYVYY10_0_5X30; > + else > + fmt = MEDIA_BUS_FMT_RGB101010_1X30; > + break; > + case 12: > + if (is_420) > + fmt = MEDIA_BUS_FMT_UYYVYY12_0_5X36; > + else > + fmt = MEDIA_BUS_FMT_RGB121212_1X36; > + break; > + case 16: > + if (is_420) > + fmt = MEDIA_BUS_FMT_UYYVYY16_0_5X48; > + else > + fmt = MEDIA_BUS_FMT_RGB161616_1X48; > + break; > + } > + > + return fmt; > +} > + > static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct drm_display_mode > *mode) { > + struct drm_display_info *display = &hdmi->connector.display_info; > int ret; > > hdmi_disable_overflow_interrupts(hdmi); > @@ -1853,9 +1898,9 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, struct > drm_display_mode *mode) } > > if ((hdmi->vic == 6) || (hdmi->vic == 7) || > - (hdmi->vic == 21) || (hdmi->vic == 22) || > - (hdmi->vic == 2) || (hdmi->vic == 3) || > - (hdmi->vic == 17) || (hdmi->vic == 18)) > + (hdmi->vic == 21) || (hdmi->vic == 22) || > + (hdmi->vic == 2) || (hdmi->vic == 3) || > + (hdmi->vic == 17) || (hdmi->vic == 18)) > hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_601; > else > hdmi->hdmi_data.enc_out_encoding = V4L2_YCBCR_ENC_709; > @@ -1863,22 +1908,29 @@ static int dw_hdmi_setup(struct dw_hdmi *hdmi, > struct drm_display_mode *mode) > hdmi->hdmi_data.video_mode.mpixelrepetitionoutput = 0; > hdmi->hdmi_data.video_mode.mpixelrepetitioninput = 0; > > - /* TOFIX: Get input format from plat data or fallback to RGB888 */ > - if (hdmi->plat_data->input_bus_format) > + if (hdmi->hdmi_data.bridge_in_bus_format) > + hdmi->hdmi_data.enc_in_bus_format = > + hdmi->hdmi_data.bridge_in_bus_format; > + else if (hdmi->plat_data->input_bus_format) > hdmi->hdmi_data.enc_in_bus_format = > hdmi->plat_data->input_bus_format; > else > hdmi->hdmi_data.enc_in_bus_format = MEDIA_BUS_FMT_RGB888_1X24; > > - /* TOFIX: Get input encoding from plat data or fallback to none */ > - if (hdmi->plat_data->input_bus_encoding) > + if (hdmi->hdmi_data.bridge_in_encoding) > + hdmi->hdmi_data.enc_in_encoding = > + hdmi->hdmi_data.bridge_in_encoding; > + else if (hdmi->plat_data->input_bus_encoding) > hdmi->hdmi_data.enc_in_encoding = > hdmi->plat_data->input_bus_encoding; > else > hdmi->hdmi_data.enc_in_encoding = V4L2_YCBCR_ENC_DEFAULT; > > - /* TOFIX: Default to RGB888 output format */ > - hdmi->hdmi_data.enc_out_bus_format = MEDIA_BUS_FMT_RGB888_1X24; > + if (display->num_bus_formats) > + hdmi->hdmi_data.enc_out_bus_format = display- >bus_formats[0]; > + else > + hdmi->hdmi_data.enc_out_bus_format = > + dw_hdmi_determine_output_bus_format(hdmi); > > hdmi->hdmi_data.pix_repet_factor = 0; > hdmi->hdmi_data.hdcp_enable = 0; > @@ -2150,6 +2202,56 @@ dw_hdmi_bridge_mode_valid(struct drm_bridge *bridge, > return mode_status; > } > > +static bool dw_hdmi_drm_bridge_format_set(struct drm_bridge *bridge, > + const u32 input_bus_format, > + const u32 input_encoding) > +{ > + struct dw_hdmi *hdmi = bridge->driver_private; > + > + /* Filter supported input bus formats */ > + switch (input_bus_format) { > + case MEDIA_BUS_FMT_RGB888_1X24: > + case MEDIA_BUS_FMT_RGB101010_1X30: > + case MEDIA_BUS_FMT_RGB121212_1X36: > + case MEDIA_BUS_FMT_RGB161616_1X48: > + case MEDIA_BUS_FMT_YUV8_1X24: > + case MEDIA_BUS_FMT_YUV10_1X30: > + case MEDIA_BUS_FMT_YUV12_1X36: > + case MEDIA_BUS_FMT_YUV16_1X48: > + case MEDIA_BUS_FMT_UYVY8_1X16: > + case MEDIA_BUS_FMT_UYVY10_1X20: > + case MEDIA_BUS_FMT_UYVY12_1X24: > + case MEDIA_BUS_FMT_UYYVYY8_0_5X24: > + case MEDIA_BUS_FMT_UYYVYY10_0_5X30: > + case MEDIA_BUS_FMT_UYYVYY12_0_5X36: > + case MEDIA_BUS_FMT_UYYVYY16_0_5X48: > + break; > + default: > + dev_dbg(hdmi->dev, "Unsupported Input bus format %x\n", > + input_bus_format); > + return false; > + } > + > + /* Filter supported input bus encoding */ > + switch (input_encoding) { > + case V4L2_YCBCR_ENC_DEFAULT: > + case V4L2_YCBCR_ENC_601: > + case V4L2_YCBCR_ENC_709: > + case V4L2_YCBCR_ENC_XV601: > + case V4L2_YCBCR_ENC_XV709: > + break; > + default: > + dev_dbg(hdmi->dev, "Unsupported Input encoding %x\n", > + input_bus_format); > + return false; > + } > + > + hdmi->hdmi_data.bridge_in_bus_format = input_bus_format; > + hdmi->hdmi_data.bridge_in_encoding = input_encoding; > + > + return true; > +} > + > static void dw_hdmi_bridge_mode_set(struct drm_bridge *bridge, > const struct drm_display_mode *orig_mode, > const struct drm_display_mode *mode) > @@ -2192,6 +2294,7 @@ static const struct drm_bridge_funcs > dw_hdmi_bridge_funcs = { .disable = dw_hdmi_bridge_disable, > .mode_set = dw_hdmi_bridge_mode_set, > .mode_valid = dw_hdmi_bridge_mode_valid, > + .format_set = dw_hdmi_drm_bridge_format_set, > }; > > static irqreturn_t dw_hdmi_i2c_irq(struct dw_hdmi *hdmi) Reviewed-by: Jernej Skrabec Best regards, Jernej