From patchwork Sun Jun 4 16:01:41 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Icenowy Zheng X-Patchwork-Id: 9764969 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id D92D160392 for ; Sun, 4 Jun 2017 16:04:02 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id CFCD027F88 for ; Sun, 4 Jun 2017 16:04:02 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id C481728111; Sun, 4 Jun 2017 16:04:02 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-1.9 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID autolearn=ham version=3.3.1 Received: from bombadil.infradead.org (bombadil.infradead.org [65.50.211.133]) (using TLSv1.2 with cipher AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 3EA0428236 for ; Sun, 4 Jun 2017 16:04:01 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20170209; h=Sender: Content-Transfer-Encoding:Content-Type:MIME-Version:Cc:List-Subscribe: List-Help:List-Post:List-Archive:List-Unsubscribe:List-Id:References: In-Reply-To:Message-Id:Date:Subject:To:From:Reply-To:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Owner; bh=mICTRmvPHaRVBqeVU4fb2SmKy/lpIHrtTcGBtlST870=; b=CUI+CTIget6+BbatcI8aCRUyNv 6P/7D76oeL/YtHsD4COKmhUL0EITGPghTmoZXGVzSkTihs42yJkn5ZOfcPRLvZfHFwNyLjxvg5P8y MTVKVAYnerjUzpz3QXEj6I0qoPT1CrV9TDZqZ858khw/u41H6i4Ovx0MLcu0eE9/LURbOTTw1ulwV GIjtgWxR/xKEG3YeiW/iU6uwOGIuOHo/wcryrRxts0YG98ZD1BPsHYAZsOK1OqRo1qgJKIgsDgVRg O1aPh5pSXRyCCClwG4VTbZI4zEDyw1cTyUqHXL1ZygavA7l/ouSIwJ/SPVJftwb2l4MJT95Bmb0uY SzeJBoFQ==; Received: from localhost ([127.0.0.1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.87 #1 (Red Hat Linux)) id 1dHY0W-0001zE-Db; Sun, 04 Jun 2017 16:04:00 +0000 Received: from chameleon.ash.relay.mailchannels.net ([23.83.222.33]) by bombadil.infradead.org with esmtps (Exim 4.87 #1 (Red Hat Linux)) id 1dHXzb-00014L-7t for linux-arm-kernel@lists.infradead.org; Sun, 04 Jun 2017 16:03:09 +0000 X-Sender-Id: lmn-tzduiowcrqmw|x-authsender|icenowy@aosc.io Received: from relay.mailchannels.net (localhost [127.0.0.1]) by relay.mailchannels.net (Postfix) with ESMTP id 7283B7C4DF3; Sun, 4 Jun 2017 16:02:37 +0000 (UTC) Received: from hermes.aosc.io (unknown [100.96.136.220]) (Authenticated sender: lmn-TZDUIOWCRQMW) by relay.mailchannels.net (Postfix) with ESMTPA id 618897C5540; Sun, 4 Jun 2017 16:02:34 +0000 (UTC) X-Sender-Id: lmn-tzduiowcrqmw|x-authsender|icenowy@aosc.io Received: from hermes.aosc.io (hermes.aosc.io [172.20.107.195]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384) by 0.0.0.0:2500 (trex/5.9.4); Sun, 04 Jun 2017 16:02:37 +0000 X-MC-Relay: Neutral X-MailChannels-SenderId: lmn-tzduiowcrqmw|x-authsender|icenowy@aosc.io X-MailChannels-Auth-Id: lmn-TZDUIOWCRQMW X-Absorbed-Bitter: 2b31c73706dc9597_1496592155592_900814421 X-MC-Loop-Signature: 1496592155592:3984220137 X-MC-Ingress-Time: 1496592155591 Received: from localhost (localhost [127.0.0.1]) (Authenticated sender: icenowy@aosc.io) by hermes.aosc.io (Postfix) with ESMTPSA id 05E3F50AD3; Sun, 4 Jun 2017 16:02:22 +0000 (UTC) From: Icenowy Zheng To: Maxime Ripard , Rob Herring , Chen-Yu Tsai , =?UTF-8?q?Jernej=20=C5=A0krabec?= Subject: [PATCH v2 03/11] drm: sun4i: ignore swapped mixer<->tcon connection for DE2 Date: Mon, 5 Jun 2017 00:01:41 +0800 Message-Id: <20170604160149.30230-4-icenowy@aosc.io> In-Reply-To: <20170604160149.30230-1-icenowy@aosc.io> References: <20170604160149.30230-1-icenowy@aosc.io> X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20170604_090304_259170_DBA671C2 X-CRM114-Status: GOOD ( 16.15 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, linux-sunxi@googlegroups.com, linux-clk@vger.kernel.org, linux-arm-kernel@lists.infradead.org, Icenowy Zheng MIME-Version: 1.0 Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org X-Virus-Scanned: ClamAV using ClamSMTP Some SoC's DE2 has two mixers. Defaultly the mixer0 is connected to tcon0 and mixer1 is connected to tcon1; however by setting a bit the connection can be swapped. As we now hardcode the default connection, ignore the bonus endpoint for the mixer's output and the TCON's input, as they stands for the swapped connection. Signed-off-by: Icenowy Zheng --- Changes in v2: - Change to use new endpoint reg definition. drivers/gpu/drm/sun4i/sun4i_drv.c | 45 ++++++++++++++++++++++++++++ drivers/gpu/drm/sun4i/sun4i_tcon.c | 61 ++++++++++++++++++++++++++++++++------ drivers/gpu/drm/sun4i/sun4i_tcon.h | 2 ++ 3 files changed, 99 insertions(+), 9 deletions(-) diff --git a/drivers/gpu/drm/sun4i/sun4i_drv.c b/drivers/gpu/drm/sun4i/sun4i_drv.c index f19100c91c2b..775eee82d8a9 100644 --- a/drivers/gpu/drm/sun4i/sun4i_drv.c +++ b/drivers/gpu/drm/sun4i/sun4i_drv.c @@ -178,6 +178,13 @@ static bool sun4i_drv_node_is_frontend(struct device_node *node) of_device_is_compatible(node, "allwinner,sun8i-a33-display-frontend"); } +static bool sun4i_drv_node_is_swappable_de2_mixer(struct device_node *node) +{ + /* The V3s has only one mixer-tcon pair, so it's not listed here. */ + return of_device_is_compatible(node, "allwinner,sun8i-h3-de2-mixer0") || + of_device_is_compatible(node, "allwinner,sun8i-h3-de2-mixer1"); +} + static bool sun4i_drv_node_is_tcon(struct device_node *node) { return of_device_is_compatible(node, "allwinner,sun5i-a13-tcon") || @@ -261,6 +268,44 @@ static int sun4i_drv_add_endpoints(struct device *dev, } } + /* + * The second endpoint of the output of a swappable DE2 mixer + * is the TCON after connection swapping. + * Ignore it now, as we now hardcode mixer0->tcon0, + * mixer1->tcon1 connection. + */ + if (sun4i_drv_node_is_swappable_de2_mixer(node)) { + struct device_node *remote_ep_node; + struct of_endpoint local_endpoint, remote_endpoint; + + remote_ep_node = of_graph_get_remote_endpoint(ep); + if (!remote_ep_node) { + DRM_DEBUG_DRIVER("Couldn't get remote endpoint\n"); + continue; + } + + if (of_graph_parse_endpoint(ep, &local_endpoint)) { + DRM_DEBUG_DRIVER("Couldn't parse local endpoint\n"); + of_node_put(remote_ep_node); + continue; + } + + if (of_graph_parse_endpoint(remote_ep_node, + &remote_endpoint)) { + DRM_DEBUG_DRIVER("Couldn't parse remote endpoint\n"); + of_node_put(remote_ep_node); + continue; + } + + if (local_endpoint.id != remote_endpoint.id) { + DRM_DEBUG_DRIVER("Endpoint is an unused connection for DE2 mixer... skipping\n"); + of_node_put(remote_ep_node); + continue; + } + + of_node_put(remote_ep_node); + } + /* Walk down our tree */ count += sun4i_drv_add_endpoints(dev, match, remote); diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.c b/drivers/gpu/drm/sun4i/sun4i_tcon.c index d9791292553e..568cea0e5f8f 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.c +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.c @@ -464,7 +464,8 @@ static int sun4i_tcon_init_regmap(struct device *dev, * requested via the get_id function of the engine. */ static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv, - struct device_node *node) + struct device_node *node, + bool skip_bonus_ep) { struct device_node *port, *ep, *remote; struct sunxi_engine *engine; @@ -478,6 +479,42 @@ static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv, if (!remote) continue; + if (skip_bonus_ep) { + struct device_node *remote_ep_node; + struct of_endpoint local_endpoint, remote_endpoint; + + remote_ep_node = of_graph_get_remote_endpoint(ep); + if (!remote_ep_node) { + DRM_DEBUG_DRIVER("Couldn't get remote endpoint\n"); + of_node_put(remote); + continue; + } + + if (of_graph_parse_endpoint(ep, &local_endpoint)) { + DRM_DEBUG_DRIVER("Couldn't parse local endpoint\n"); + of_node_put(remote); + of_node_put(remote_ep_node); + continue; + } + + if (of_graph_parse_endpoint(remote_ep_node, + &remote_endpoint)) { + DRM_DEBUG_DRIVER("Couldn't parse remote endpoint\n"); + of_node_put(remote); + of_node_put(remote_ep_node); + continue; + } + + if (local_endpoint.id != remote_endpoint.id) { + DRM_DEBUG_DRIVER("Skipping bonus mixer->TCON connection when searching engine\n"); + of_node_put(remote); + of_node_put(remote_ep_node); + continue; + } + + of_node_put(remote_ep_node); + } + /* does this node match any registered engines? */ list_for_each_entry(engine, &drv->engine_list, list) { if (remote == engine->node) { @@ -488,7 +525,7 @@ static struct sunxi_engine *sun4i_tcon_find_engine(struct sun4i_drv *drv, } /* keep looking through upstream ports */ - engine = sun4i_tcon_find_engine(drv, remote); + engine = sun4i_tcon_find_engine(drv, remote, skip_bonus_ep); if (!IS_ERR(engine)) { of_node_put(remote); of_node_put(port); @@ -508,21 +545,27 @@ static int sun4i_tcon_bind(struct device *dev, struct device *master, struct sun4i_tcon *tcon; int ret; - engine = sun4i_tcon_find_engine(drv, dev->of_node); - if (IS_ERR(engine)) { - dev_err(dev, "Couldn't find matching engine\n"); - return -EPROBE_DEFER; - } - tcon = devm_kzalloc(dev, sizeof(*tcon), GFP_KERNEL); if (!tcon) return -ENOMEM; dev_set_drvdata(dev, tcon); tcon->drm = drm; tcon->dev = dev; - tcon->id = engine->id; tcon->quirks = of_device_get_match_data(dev); + /* + * As we keep the connection between DE2 mixer and TCON not swapped, + * skip the bonus endpoints (which stand for swapped connection) + * when finding the correspoing engine. + */ + engine = sun4i_tcon_find_engine(drv, dev->of_node, + tcon->quirks->swappable_input); + if (IS_ERR(engine)) { + dev_err(dev, "Couldn't find matching engine\n"); + return -EPROBE_DEFER; + } + tcon->id = engine->id; + tcon->lcd_rst = devm_reset_control_get(dev, "lcd"); if (IS_ERR(tcon->lcd_rst)) { dev_err(dev, "Couldn't get our reset line\n"); diff --git a/drivers/gpu/drm/sun4i/sun4i_tcon.h b/drivers/gpu/drm/sun4i/sun4i_tcon.h index e3c50ecdcd04..c3e01c06e9a0 100644 --- a/drivers/gpu/drm/sun4i/sun4i_tcon.h +++ b/drivers/gpu/drm/sun4i/sun4i_tcon.h @@ -146,6 +146,8 @@ struct sun4i_tcon_quirks { bool has_unknown_mux; /* sun5i has undocumented mux */ bool has_channel_1; /* a33 does not have channel 1 */ + /* Some DE2 can swap the mixer<->TCON connection */ + bool swappable_input; }; struct sun4i_tcon {