Received: by 2002:a25:ad19:0:0:0:0:0 with SMTP id y25csp2327564ybi; Mon, 1 Jul 2019 10:02:34 -0700 (PDT) X-Google-Smtp-Source: APXvYqxaD21Gy2MiQhVwG90n1Y21rKh8I46eyaSRvVPbSQCNCI3bQ25o0fwLA2Ou8K7DAR15NNLD X-Received: by 2002:a17:902:788f:: with SMTP id q15mr30680232pll.236.1562000554100; Mon, 01 Jul 2019 10:02:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1562000554; cv=none; d=google.com; s=arc-20160816; b=VYZO+1Sg/Kq1JKSSqIP3gmKuYSExzFxqv/cF++sxXBhmYywWftBviC2qVF5aTzI/UX 0vLsu5tajAvESQrm/xnQYP6u9/gZ56IaEi6MBxHtFNFhX98BvcCqikY/ndp3mxd1dQnt w/gRlpaRhGv9m+mRytIwG+aBMJnp2RJik5Nj5h/7Ta4cjyJ59+4rL6IxsteDedLtMHCh B2I0tgc4QUXrnR0v/fUQqY0pSnLLOqgvNSpd9GYTvjrP3KbkdmEirR5XOc5QqM5Cy7RB doAMi9fdyNvoEMs8A6EHf56DWmmslUTfc2MWGUkKpPxhCXn8B6cNbuFyxIf789wBHGuh a6NQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:dkim-signature; bh=p18mI6/20bFKypRld06SAfi0/go3QKljAqtkFENCpmc=; b=VflcVa2oxIXOSoPvD6K86DMvA0loNHyt9IsV8F2pijNT3Yd1/El+bBd6dY6kYPq+Pv bumLLMn5AezGwYonGcSpnz0oqOJ6DkqoqqvRJD5OaHw378robNMZ6/3W3rJua1vhCOy1 HXWnQng0U2hTZXeHqVnwC/tIjQlU6xgtN63TekElEUIkmm/AnGjLnWPSsC5nzl1Zmc4F veTCjj+iO+BYiS3UwYhDivED7qMoZm/e4ISrlvKkCG1zACJ5iHvZLD+19ZpcDba5irn5 R7ENp16dbLiXW578SGaWPrVUsmpXuLNlbnAomkcr+yYPd9Enew8u0SJ8v2d6tOpexTm4 2Zlw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@chromium.org header.s=google header.b=BLEh6NVQ; 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=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t129si536764pfb.16.2019.07.01.10.02.13; Mon, 01 Jul 2019 10:02:34 -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; dkim=pass header.i=@chromium.org header.s=google header.b=BLEh6NVQ; 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=pass (p=NONE sp=NONE dis=NONE) header.from=chromium.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1729449AbfGAQjk (ORCPT + 99 others); Mon, 1 Jul 2019 12:39:40 -0400 Received: from mail-io1-f65.google.com ([209.85.166.65]:33090 "EHLO mail-io1-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728187AbfGAQjk (ORCPT ); Mon, 1 Jul 2019 12:39:40 -0400 Received: by mail-io1-f65.google.com with SMTP id u13so30334397iop.0 for ; Mon, 01 Jul 2019 09:39:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=mime-version:references:in-reply-to:from:date:message-id:subject:to :cc; bh=p18mI6/20bFKypRld06SAfi0/go3QKljAqtkFENCpmc=; b=BLEh6NVQjzd/lDI/fhA9TxE0gONI1OE1ADRQfc/gHNWpXo0HGOhu11uzc9cS4nskJy U57jmZFkZcXb1fIUlf4tYzexTdASwXIKatQvOJc6tPxJz4k+kmXspvtvNIYo2Vm4puH4 on/9bZA0CjrU7ISIb0+QA7DfGck8w2sNeSdeQ= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:references:in-reply-to:from:date :message-id:subject:to:cc; bh=p18mI6/20bFKypRld06SAfi0/go3QKljAqtkFENCpmc=; b=qjnHz+BcZcVt7KYkDko3FWcACh+0hYlO8F6xdKaIHwQr00siXJvOZ8gZa6MDWaHu3e KISec7i2soDmJ8rcWLbQC1R5nmiGhrQLJix7abqoLtmZpqqwZHwlk2kNV+3qRH1XG9zA V0oar8M0jEgavGNhqR36W6VIsOuK7sWo6fM4GFWPeAGeOi0nmkCpIn3niOH70zA7Nq19 wC0BXlpEko0RO+CnlxhYcB5MfitDK5u+072BONvO4oUmzkHBVg4wWc6wg3lslxzChWId GB/zsYMinC3P7P/SW9Z9DgVCYDrytC/ocPzfiXYFTE5k9hErQXMJ5uHiqJ11nUl65cjk BSfg== X-Gm-Message-State: APjAAAVDvsS6dp6+W2SAIm2PUJ4Z3m7Vj5hDIL+oiMdu9eMC4/gXu/5S jx2B5QA899lm73DOxOX0hPZ4OE56ERI= X-Received: by 2002:a5d:8347:: with SMTP id q7mr25978424ior.277.1561999179053; Mon, 01 Jul 2019 09:39:39 -0700 (PDT) Received: from mail-io1-f54.google.com (mail-io1-f54.google.com. [209.85.166.54]) by smtp.gmail.com with ESMTPSA id b20sm9261950ios.44.2019.07.01.09.39.37 for (version=TLS1_3 cipher=AEAD-AES128-GCM-SHA256 bits=128/128); Mon, 01 Jul 2019 09:39:37 -0700 (PDT) Received: by mail-io1-f54.google.com with SMTP id h6so30333603ioh.3 for ; Mon, 01 Jul 2019 09:39:37 -0700 (PDT) X-Received: by 2002:a5e:c241:: with SMTP id w1mr5709959iop.58.1561999176456; Mon, 01 Jul 2019 09:39:36 -0700 (PDT) MIME-Version: 1.0 References: <20190401171724.215780-1-dianders@chromium.org> <20190401171724.215780-3-dianders@chromium.org> <20190630202246.GB15102@ravnborg.org> In-Reply-To: <20190630202246.GB15102@ravnborg.org> From: Doug Anderson Date: Mon, 1 Jul 2019 09:39:24 -0700 X-Gmail-Original-Message-ID: Message-ID: Subject: Re: [PATCH v5 2/7] drm/panel: simple: Add ability to override typical timing To: Sam Ravnborg Cc: Thierry Reding , Heiko Stuebner , Sean Paul , devicetree@vger.kernel.org, Rob Herring , David Airlie , Jeffy Chen , dri-devel , LKML , "open list:ARM/Rockchip SoC..." , Boris Brezillon , Laurent Pinchart , =?UTF-8?Q?Enric_Balletb=C3=B2?= , =?UTF-8?Q?St=C3=A9phane_Marchesin?= , Ezequiel Garcia , Matthias Kaehlcke Content-Type: text/plain; charset="UTF-8" Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi, On Sun, Jun 30, 2019 at 1:22 PM Sam Ravnborg wrote: > > > @@ -91,6 +92,8 @@ struct panel_simple { > > struct i2c_adapter *ddc; > > > > struct gpio_desc *enable_gpio; > > + > > + struct drm_display_mode override_mode; > I fail to see where this poiter is assigned. In panel_simple_parse_override_mode(). Specifically: drm_display_mode_from_videomode(&vm, &panel->override_mode); > @@ -152,6 +162,44 @@ static int panel_simple_get_fixed_modes(struct panel_simple *panel) > > num++; > > } > > > > + return num; > > +} > > + > > +static int panel_simple_get_non_edid_modes(struct panel_simple *panel) > > +{ > > + struct drm_connector *connector = panel->base.connector; > > + struct drm_device *drm = panel->base.drm; > > + struct drm_display_mode *mode; > > + bool has_override = panel->override_mode.type; > This looks suspicious. > panel->override_mode.type is an unsigned int that may have a number of > bits set. > So the above code implicitly convert a .type != 0 to a true. > This can be expressed in a much more reader friendly way. You would suggest that I add a boolean field to a structure to indicate whether an override mode is present? I will certainly do that if you're sure that's what you want, but my understanding of the convention for much of the kernel is that you generally rely on structures being zero-initialized and then (assuming that zero isn't a valid value) it's safe to confirm they've been initialized by seeing that they're non-zero. In this case panel_simple_parse_override_mode() will _definitely_ set a non-zero value for this field in the case that it ran to completion. ...and, even further, the end of that function has a WARN_ON() if it doesn't. Any chance you missed reading panel_simple_parse_override_mode() in the original patch? > And on top of this, I cannot see that panel->override_mode points to a > valid instance of display_mode, at least not always. override_mode isn't a pointer, right? It's a structure straight in the panel. So all its fields will be initted to 0 by the kzalloc in panel_simple_probe(). If the type is non-zero then we know panel_simple_parse_override_mode() finished to completion. > > @@ -268,7 +316,7 @@ static int panel_simple_get_modes(struct drm_panel *panel) > > } > > > > /* add hard-coded panel modes */ > > - num += panel_simple_get_fixed_modes(p); > > + num += panel_simple_get_non_edid_modes(p); > > > > return num; > > } > > @@ -299,10 +347,58 @@ static const struct drm_panel_funcs panel_simple_funcs = { > > .get_timings = panel_simple_get_timings, > > }; > > > > +#define PANEL_SIMPLE_BOUNDS_CHECK(to_check, bounds, field) \ > > + (to_check->field.typ >= bounds->field.min && \ > > + to_check->field.typ <= bounds->field.max) > > +static void panel_simple_parse_override_mode(struct device *dev, > > + struct panel_simple *panel, > > + const struct display_timing *ot) > > +{ > > + const struct panel_desc *desc = panel->desc; > > + struct videomode vm; > > + unsigned int i; > > + > > + if (WARN_ON(desc->num_modes)) { > > + dev_err(dev, "Reject override mode: panel has a fixed mode\n"); > > + return; > > + } > > + if (WARN_ON(!desc->num_timings)) { > > + dev_err(dev, "Reject override mode: no timings specified\n"); > > + return; > > + } > > + > > + for (i = 0; i < panel->desc->num_timings; i++) { > > + const struct display_timing *dt = &panel->desc->timings[i]; > > + > > + if (!PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, hactive) || > > + !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, hfront_porch) || > > + !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, hback_porch) || > > + !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, hsync_len) || > > + !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, vactive) || > > + !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, vfront_porch) || > > + !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, vback_porch) || > > + !PANEL_SIMPLE_BOUNDS_CHECK(ot, dt, vsync_len)) > > + continue; > > + > > + if (ot->flags != dt->flags) > > + continue; > The binding do not say anything about flags. Is this check really > needed? Flags here is an implementation detail of the Linux driver and the bindings are supposed to be Linux-agnostic. The bindings started out talking about lots of stuff that happened in the driver and I was told to take all those out. ;-) Specifically note that flags here holds whether we have specified a positive or negative for hsync or vsync. These are the "hsync-active" and "vsync-active" properties of the panel bindings. Take a look at of_parse_display_timing(). ...so to summarize the flags here is just a different set of properties to check like the checks above. > > + > > + videomode_from_timing(ot, &vm); > > + drm_display_mode_from_videomode(&vm, &panel->override_mode); > > > + panel->override_mode.type |= DRM_MODE_TYPE_DRIVER | > > + DRM_MODE_TYPE_PREFERRED; > > + break; > > + } > > + > > + if (WARN_ON(!panel->override_mode.type)) > > + dev_err(dev, "Reject override mode: No display_timing found\n"); > > +} > > + > > static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) > > { > > struct device_node *backlight, *ddc; > > struct panel_simple *panel; > > + struct display_timing dt; > > int err; > > > > panel = devm_kzalloc(dev, sizeof(*panel), GFP_KERNEL); > > @@ -348,6 +444,9 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc) > > } > > } > > > > + if (!of_get_display_timing(dev->of_node, "panel-timing", &dt)) > > + panel_simple_parse_override_mode(dev, panel, &dt); > > + > Naming bike-shedding. > With the new node name, the function name > panel_simple_parse_override_mode() could use an update. > Maybe: panel_simple_parse_panel_timing_node() Happy to change the name to panel_simple_parse_panel_timing_node(). --- Summary of the above: * Unless you say otherwise, I will leave the check of "type != 0" and not introduce a new boolean. * Only action request is rename of panel_simple_parse_override_mode() to panel_simple_parse_panel_timing_node() NOTE: Since this feedback is minor and this patch has been outstanding for a while (and is blocking other work), I am assuming that the best path forward is for Heiko to land this patch with Thierry's Ack and I'll send a follow-up. Please yell if you disagree. I'll respond to each of your emails separately and then wait for your response before sending the follow-up series. -Doug