Received: by 10.192.165.156 with SMTP id m28csp540595imm; Fri, 13 Apr 2018 03:44:17 -0700 (PDT) X-Google-Smtp-Source: AIpwx4/kscwwElKzFhoHqol0OROm2j3LqkuRSY1hdQ6aDyP8X2EMzx6CUwgHLCr2T0eVn2fw6suc X-Received: by 10.99.157.66 with SMTP id i63mr3429400pgd.83.1523616257798; Fri, 13 Apr 2018 03:44:17 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1523616257; cv=none; d=google.com; s=arc-20160816; b=qmReH3kHjFXphgLmqcH49ZiSGonBCusDlct/S89buYC3fJhnzjQWOdz7zuJUGyGcF5 jSpd3eFTIv1Y6Eyq3WVVGli87d5s9ca3dIkI4n4BAwwjVvE+CHS+Zca6lxG/8x8qblBi x+hZTU0C+8IcCfq1HWs1W0n8HUGuzbJ5YZo0SbXfM3z51X+uIPY6F/+IsD88kAndPNkX sJe4SVSq6LmVAjY9HzXYzVqFV7+Ocdp7wVbhIwvq7Pu3cFlXQ640NU3iF527sD6XJqsQ LyW2E3nrSDOKJOt00p5154x1DMyS1krD0aYZCjfCZEW2XUKYspdUKnivP0hH9drzuzQs TROw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:references:in-reply-to:message-id:date :subject:cc:to:from:arc-authentication-results; bh=5ftmizYg+ysUuSEeHWv2+XZ/K23zINM7FBpmUPEuBXw=; b=bAIMXdWvhn0MCEvVnbqtl7ejXwYENdvCIMi83S6p1BOyHDvTYNycjoblMZm9FdGs7D 9fbTSxjwPzHbL6L1ZkVSpU4ceWLOEjcPYebaSkdTnCEl5eEuWZ1zFgRhzY03qFwAHHfV BMpseUemgMgRFVXj4uNY8MToRBoqTfmjmo+vy7oa562X4CVldJx5DS2IEnND2PYfxv9Y eodocxM8YDjS2gXhNMSbNCJfpnHwJzU0gqU2+1mJi5bApte83LnhmBZaSI7Wh29w/L2k rQhFHZBjt3B2c25xGiaNX7ObxUGuliJdhwn48nHLaRqphWPl+mfcz/uwepb5gGAOkWBK /N1Q== 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=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id l84si4378547pfj.344.2018.04.13.03.44.03; Fri, 13 Apr 2018 03:44:17 -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=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754109AbeDMJlE (ORCPT + 99 others); Fri, 13 Apr 2018 05:41:04 -0400 Received: from mx3-rdu2.redhat.com ([66.187.233.73]:38746 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1753927AbeDMJlB (ORCPT ); Fri, 13 Apr 2018 05:41:01 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CC47881A88BC; Fri, 13 Apr 2018 09:41:00 +0000 (UTC) Received: from thh440s.redhat.com (ovpn-116-23.ams2.redhat.com [10.36.116.23]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1E4FB2026DFD; Fri, 13 Apr 2018 09:40:59 +0000 (UTC) From: Thomas Huth To: Gustavo Padovan , Maarten Lankhorst , Sean Paul , David Airlie , dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org, Gerd Hoffmann , Farhan Ali , borntraeger@de.ibm.com Subject: [PATCH 1/2] drm: Move CONFIG_HDMI-dependent code to a separate file Date: Fri, 13 Apr 2018 11:40:55 +0200 Message-Id: <1523612456-14827-2-git-send-email-thuth@redhat.com> In-Reply-To: <1523612456-14827-1-git-send-email-thuth@redhat.com> References: <1523612456-14827-1-git-send-email-thuth@redhat.com> X-Scanned-By: MIMEDefang 2.78 on 10.11.54.4 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 13 Apr 2018 09:41:00 +0000 (UTC) X-Greylist: inspected by milter-greylist-4.5.16 (mx1.redhat.com [10.11.55.8]); Fri, 13 Apr 2018 09:41:00 +0000 (UTC) for IP:'10.11.54.4' DOMAIN:'int-mx04.intmail.prod.int.rdu2.redhat.com' HELO:'smtp.corp.redhat.com' FROM:'thuth@redhat.com' RCPT:'' Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Selecting CONFIG_HDMI for S390 is inappropriate - there is no real graphic hardware on this architecture. The drm subsystem is only enabled here for using the virtual graphics card "virtio-gpu". So it should be possible to compile the drm subsystem also without CONFIG_DRM. Let's move the related code to a separate file for this. Signed-off-by: Thomas Huth --- drivers/gpu/drm/Kconfig | 2 +- drivers/gpu/drm/Makefile | 1 + drivers/gpu/drm/drm_crtc_internal.h | 2 + drivers/gpu/drm/drm_edid.c | 163 +------------------------------- drivers/gpu/drm/drm_hdmi.c | 182 ++++++++++++++++++++++++++++++++++++ 5 files changed, 188 insertions(+), 162 deletions(-) create mode 100644 drivers/gpu/drm/drm_hdmi.c diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index deeefa7..298a518 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -8,7 +8,7 @@ menuconfig DRM tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" depends on (AGP || AGP=n) && !EMULATED_CMPXCHG && HAS_DMA select DRM_PANEL_ORIENTATION_QUIRKS - select HDMI + select HDMI if !S390 select FB_CMDLINE select I2C select I2C_ALGOBIT diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 50093ff..16fd8e3 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -20,6 +20,7 @@ drm-y := drm_auth.o drm_bufs.o drm_cache.o \ drm_dumb_buffers.o drm_mode_config.o drm_vblank.o \ drm_syncobj.o drm_lease.o +drm-$(CONFIG_HDMI) += drm_hdmi.o drm-$(CONFIG_DRM_LIB_RANDOM) += lib/drm_random.o drm-$(CONFIG_DRM_VM) += drm_vm.o drm-$(CONFIG_COMPAT) += drm_ioc32.o diff --git a/drivers/gpu/drm/drm_crtc_internal.h b/drivers/gpu/drm/drm_crtc_internal.h index 3c2b828..0804348 100644 --- a/drivers/gpu/drm/drm_crtc_internal.h +++ b/drivers/gpu/drm/drm_crtc_internal.h @@ -220,3 +220,5 @@ int drm_mode_page_flip_ioctl(struct drm_device *dev, /* drm_edid.c */ void drm_mode_fixup_1366x768(struct drm_display_mode *mode); +u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match); +bool drm_valid_hdmi_vic(u8 vic); diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index 134069f..3820763 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c @@ -29,7 +29,6 @@ */ #include #include -#include #include #include #include @@ -3062,7 +3061,7 @@ static u8 drm_match_hdmi_mode_clock_tolerance(const struct drm_display_mode *to_ * * Returns the HDMI Video ID (VIC) of the mode or 0 if it isn't one. */ -static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) +u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) { u8 vic; @@ -3085,7 +3084,7 @@ static u8 drm_match_hdmi_mode(const struct drm_display_mode *to_match) return 0; } -static bool drm_valid_hdmi_vic(u8 vic) +bool drm_valid_hdmi_vic(u8 vic) { return vic > 0 && vic < ARRAY_SIZE(edid_4k_modes); } @@ -4817,76 +4816,6 @@ void drm_set_preferred_mode(struct drm_connector *connector, EXPORT_SYMBOL(drm_set_preferred_mode); /** - * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with - * data from a DRM display mode - * @frame: HDMI AVI infoframe - * @mode: DRM display mode - * @is_hdmi2_sink: Sink is HDMI 2.0 compliant - * - * Return: 0 on success or a negative error code on failure. - */ -int -drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, - const struct drm_display_mode *mode, - bool is_hdmi2_sink) -{ - int err; - - if (!frame || !mode) - return -EINVAL; - - err = hdmi_avi_infoframe_init(frame); - if (err < 0) - return err; - - if (mode->flags & DRM_MODE_FLAG_DBLCLK) - frame->pixel_repeat = 1; - - frame->video_code = drm_match_cea_mode(mode); - - /* - * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but - * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we - * have to make sure we dont break HDMI 1.4 sinks. - */ - if (!is_hdmi2_sink && frame->video_code > 64) - frame->video_code = 0; - - /* - * HDMI spec says if a mode is found in HDMI 1.4b 4K modes - * we should send its VIC in vendor infoframes, else send the - * VIC in AVI infoframes. Lets check if this mode is present in - * HDMI 1.4b 4K modes - */ - if (frame->video_code) { - u8 vendor_if_vic = drm_match_hdmi_mode(mode); - bool is_s3d = mode->flags & DRM_MODE_FLAG_3D_MASK; - - if (drm_valid_hdmi_vic(vendor_if_vic) && !is_s3d) - frame->video_code = 0; - } - - frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE; - - /* - * Populate picture aspect ratio from either - * user input (if specified) or from the CEA mode list. - */ - if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 || - mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9) - frame->picture_aspect = mode->picture_aspect_ratio; - else if (frame->video_code > 0) - frame->picture_aspect = drm_get_cea_aspect_ratio( - frame->video_code); - - frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; - frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN; - - return 0; -} -EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode); - -/** * drm_hdmi_avi_infoframe_quant_range() - fill the HDMI AVI infoframe * quantization range information * @frame: HDMI AVI infoframe @@ -4945,94 +4874,6 @@ void drm_set_preferred_mode(struct drm_connector *connector, } EXPORT_SYMBOL(drm_hdmi_avi_infoframe_quant_range); -static enum hdmi_3d_structure -s3d_structure_from_display_mode(const struct drm_display_mode *mode) -{ - u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK; - - switch (layout) { - case DRM_MODE_FLAG_3D_FRAME_PACKING: - return HDMI_3D_STRUCTURE_FRAME_PACKING; - case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: - return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE; - case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: - return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE; - case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: - return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL; - case DRM_MODE_FLAG_3D_L_DEPTH: - return HDMI_3D_STRUCTURE_L_DEPTH; - case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: - return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH; - case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: - return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM; - case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: - return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF; - default: - return HDMI_3D_STRUCTURE_INVALID; - } -} - -/** - * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with - * data from a DRM display mode - * @frame: HDMI vendor infoframe - * @connector: the connector - * @mode: DRM display mode - * - * Note that there's is a need to send HDMI vendor infoframes only when using a - * 4k or stereoscopic 3D mode. So when giving any other mode as input this - * function will return -EINVAL, error that can be safely ignored. - * - * Return: 0 on success or a negative error code on failure. - */ -int -drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, - struct drm_connector *connector, - const struct drm_display_mode *mode) -{ - /* - * FIXME: sil-sii8620 doesn't have a connector around when - * we need one, so we have to be prepared for a NULL connector. - */ - bool has_hdmi_infoframe = connector ? - connector->display_info.has_hdmi_infoframe : false; - int err; - u32 s3d_flags; - u8 vic; - - if (!frame || !mode) - return -EINVAL; - - if (!has_hdmi_infoframe) - return -EINVAL; - - vic = drm_match_hdmi_mode(mode); - s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK; - - /* - * Even if it's not absolutely necessary to send the infoframe - * (ie.vic==0 and s3d_struct==0) we will still send it if we - * know that the sink can handle it. This is based on a - * suggestion in HDMI 2.0 Appendix F. Apparently some sinks - * have trouble realizing that they shuld switch from 3D to 2D - * mode if the source simply stops sending the infoframe when - * it wants to switch from 3D to 2D. - */ - - if (vic && s3d_flags) - return -EINVAL; - - err = hdmi_vendor_infoframe_init(frame); - if (err < 0) - return err; - - frame->vic = vic; - frame->s3d_struct = s3d_structure_from_display_mode(mode); - - return 0; -} -EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode); - static int drm_parse_tiled_block(struct drm_connector *connector, struct displayid_block *block) { diff --git a/drivers/gpu/drm/drm_hdmi.c b/drivers/gpu/drm/drm_hdmi.c new file mode 100644 index 0000000..9ddf538 --- /dev/null +++ b/drivers/gpu/drm/drm_hdmi.c @@ -0,0 +1,182 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright (c) 2006 Luc Verhaegen (quirks list) + * Copyright (c) 2007-2008 Intel Corporation + * Jesse Barnes + * Copyright 2010 Red Hat, Inc. + * + * DDC probing routines (drm_ddc_read & drm_do_probe_ddc_edid) originally from + * FB layer. + * Copyright (C) 2006 Dennis Munsie + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "drm_crtc_internal.h" + +/** + * drm_hdmi_avi_infoframe_from_display_mode() - fill an HDMI AVI infoframe with + * data from a DRM display mode + * @frame: HDMI AVI infoframe + * @mode: DRM display mode + * @is_hdmi2_sink: Sink is HDMI 2.0 compliant + * + * Return: 0 on success or a negative error code on failure. + */ +int +drm_hdmi_avi_infoframe_from_display_mode(struct hdmi_avi_infoframe *frame, + const struct drm_display_mode *mode, + bool is_hdmi2_sink) +{ + int err; + + if (!frame || !mode) + return -EINVAL; + + err = hdmi_avi_infoframe_init(frame); + if (err < 0) + return err; + + if (mode->flags & DRM_MODE_FLAG_DBLCLK) + frame->pixel_repeat = 1; + + frame->video_code = drm_match_cea_mode(mode); + + /* + * HDMI 1.4 VIC range: 1 <= VIC <= 64 (CEA-861-D) but + * HDMI 2.0 VIC range: 1 <= VIC <= 107 (CEA-861-F). So we + * have to make sure we dont break HDMI 1.4 sinks. + */ + if (!is_hdmi2_sink && frame->video_code > 64) + frame->video_code = 0; + + /* + * HDMI spec says if a mode is found in HDMI 1.4b 4K modes + * we should send its VIC in vendor infoframes, else send the + * VIC in AVI infoframes. Lets check if this mode is present in + * HDMI 1.4b 4K modes + */ + if (frame->video_code) { + u8 vendor_if_vic = drm_match_hdmi_mode(mode); + bool is_s3d = mode->flags & DRM_MODE_FLAG_3D_MASK; + + if (drm_valid_hdmi_vic(vendor_if_vic) && !is_s3d) + frame->video_code = 0; + } + + frame->picture_aspect = HDMI_PICTURE_ASPECT_NONE; + + /* + * Populate picture aspect ratio from either + * user input (if specified) or from the CEA mode list. + */ + if (mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_4_3 || + mode->picture_aspect_ratio == HDMI_PICTURE_ASPECT_16_9) + frame->picture_aspect = mode->picture_aspect_ratio; + else if (frame->video_code > 0) + frame->picture_aspect = drm_get_cea_aspect_ratio( + frame->video_code); + + frame->active_aspect = HDMI_ACTIVE_ASPECT_PICTURE; + frame->scan_mode = HDMI_SCAN_MODE_UNDERSCAN; + + return 0; +} +EXPORT_SYMBOL(drm_hdmi_avi_infoframe_from_display_mode); + +static enum hdmi_3d_structure +s3d_structure_from_display_mode(const struct drm_display_mode *mode) +{ + u32 layout = mode->flags & DRM_MODE_FLAG_3D_MASK; + + switch (layout) { + case DRM_MODE_FLAG_3D_FRAME_PACKING: + return HDMI_3D_STRUCTURE_FRAME_PACKING; + case DRM_MODE_FLAG_3D_FIELD_ALTERNATIVE: + return HDMI_3D_STRUCTURE_FIELD_ALTERNATIVE; + case DRM_MODE_FLAG_3D_LINE_ALTERNATIVE: + return HDMI_3D_STRUCTURE_LINE_ALTERNATIVE; + case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_FULL: + return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_FULL; + case DRM_MODE_FLAG_3D_L_DEPTH: + return HDMI_3D_STRUCTURE_L_DEPTH; + case DRM_MODE_FLAG_3D_L_DEPTH_GFX_GFX_DEPTH: + return HDMI_3D_STRUCTURE_L_DEPTH_GFX_GFX_DEPTH; + case DRM_MODE_FLAG_3D_TOP_AND_BOTTOM: + return HDMI_3D_STRUCTURE_TOP_AND_BOTTOM; + case DRM_MODE_FLAG_3D_SIDE_BY_SIDE_HALF: + return HDMI_3D_STRUCTURE_SIDE_BY_SIDE_HALF; + default: + return HDMI_3D_STRUCTURE_INVALID; + } +} + +/** + * drm_hdmi_vendor_infoframe_from_display_mode() - fill an HDMI infoframe with + * data from a DRM display mode + * @frame: HDMI vendor infoframe + * @connector: the connector + * @mode: DRM display mode + * + * Note that there's is a need to send HDMI vendor infoframes only when using a + * 4k or stereoscopic 3D mode. So when giving any other mode as input this + * function will return -EINVAL, error that can be safely ignored. + * + * Return: 0 on success or a negative error code on failure. + */ +int +drm_hdmi_vendor_infoframe_from_display_mode(struct hdmi_vendor_infoframe *frame, + struct drm_connector *connector, + const struct drm_display_mode *mode) +{ + /* + * FIXME: sil-sii8620 doesn't have a connector around when + * we need one, so we have to be prepared for a NULL connector. + */ + bool has_hdmi_infoframe = connector ? + connector->display_info.has_hdmi_infoframe : false; + int err; + u32 s3d_flags; + u8 vic; + + if (!frame || !mode) + return -EINVAL; + + if (!has_hdmi_infoframe) + return -EINVAL; + + vic = drm_match_hdmi_mode(mode); + s3d_flags = mode->flags & DRM_MODE_FLAG_3D_MASK; + + /* + * Even if it's not absolutely necessary to send the infoframe + * (ie.vic==0 and s3d_struct==0) we will still send it if we + * know that the sink can handle it. This is based on a + * suggestion in HDMI 2.0 Appendix F. Apparently some sinks + * have trouble realizing that they shuld switch from 3D to 2D + * mode if the source simply stops sending the infoframe when + * it wants to switch from 3D to 2D. + */ + + if (vic && s3d_flags) + return -EINVAL; + + err = hdmi_vendor_infoframe_init(frame); + if (err < 0) + return err; + + frame->vic = vic; + frame->s3d_struct = s3d_structure_from_display_mode(mode); + + return 0; +} +EXPORT_SYMBOL(drm_hdmi_vendor_infoframe_from_display_mode); -- 1.8.3.1