Received: by 2002:a25:8b12:0:0:0:0:0 with SMTP id i18csp4548796ybl; Mon, 26 Aug 2019 12:04:47 -0700 (PDT) X-Google-Smtp-Source: APXvYqzCMOC4O+Yj9Zm8HY0l92X27hAlaQEEwuvilUFmHfhBI5vgb/d6kOno1rVIzaRLTUB6wrU/ X-Received: by 2002:a17:902:b695:: with SMTP id c21mr6774659pls.126.1566846287218; Mon, 26 Aug 2019 12:04:47 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1566846287; cv=none; d=google.com; s=arc-20160816; b=GVQjtIrHYRX+eKIW+JRJTl/MSa9EL6lcnyhDLCw8/S9n0CsMvPqmlXlVGTP4/92eK3 VnWdPi1ZiLbpgbNoSAh44AaTB5SgqODB9nAODJCjWYuxN6RX5jR85feQoFu49RX2tB7o 0vPnCRbMRBWM2r/9Lq/+c1G77wcgkXXM0FJxtrWqbcN4TYAv/6L2OJ+avk1+XQYvmVbK 3WWgv9MVWpH1Ri9uMguISWK1FhquKrrEW/d7NRPERNrPUjw0JSrv2APvuwCgKnAbU8S9 oH+k/Tp2+qnyxZFOt30pkZ3j1LaD8eeYN2fTG9uxIyg7pxuqrDS1V7JGiu2igZLW2PSq 1oLA== 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 :message-id:date:subject:cc:to:from:dkim-signature; bh=+gA8jssMO1pksTsqR/pMqsa2lOfnXR7skUMtSC/xqHY=; b=dYQU4p/vQlRYXhTg6dzMsIiBmU/kIWUsChvry2iyS+Y8vxcFri47nrAX/IYJGVD/Ll ahgoja6F+mO7e9PfiXo9jd9D1CZCgfa8/fPiqxNoae8zEeV1GoYpPPFDs2+UiIN/7Wi5 kcV1xLJXYajHSQuXp90MAQ3iy89WnZjwEWZAhGJcwwwYhiiuj5STdoMCClOTkoLNEPhG vZ6AFBoyp1dxnSVxPO2kaQH7ykQzHsDhz9+7M1pDyZE0GA7BzrOcJ7sNHj7DFY1iJwJz 7StrOBo2ZArUS4VgDW1sQgnqLLNw6jYkl2JM1QNG78Fo6plVhLtfpeSps1NnrufECW24 xfuw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@gmail.com header.s=20161025 header.b=S3ywNs7k; 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=QUARANTINE dis=NONE) header.from=gmail.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id t18si319189pjr.102.2019.08.26.12.04.32; Mon, 26 Aug 2019 12:04:47 -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=@gmail.com header.s=20161025 header.b=S3ywNs7k; 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=QUARANTINE dis=NONE) header.from=gmail.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1733281AbfHZSZk (ORCPT + 99 others); Mon, 26 Aug 2019 14:25:40 -0400 Received: from mail-pf1-f194.google.com ([209.85.210.194]:38817 "EHLO mail-pf1-f194.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1730228AbfHZSZk (ORCPT ); Mon, 26 Aug 2019 14:25:40 -0400 Received: by mail-pf1-f194.google.com with SMTP id o70so12324149pfg.5 for ; Mon, 26 Aug 2019 11:25:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=+gA8jssMO1pksTsqR/pMqsa2lOfnXR7skUMtSC/xqHY=; b=S3ywNs7kjy4cM0PRe2kTVACTyIBBM7ncMRlhawPkpH5iVGq0E5C+eagwIbWUxldvhP 3oYZy7l8F6w0AcpcJ9PpQ8iRFC5UG2PCSyPP37G/AM81YmwK0AJ9w3kjTKoK4n+W87Oj onqZy8zAMpRqk4ZPQIMdrMfYEIrvw0pIb5SkNgBsijLtxOU7O6IWsRo+UFrqxura02kL ++CbEvonYdsCofdPjVps/uvNv3vb7IIMstr0OxlSKAg99n/KhgPByoXGpE0ZoyZIavgS koqNmfUEaK1rY7XxmexHT5ZJV4oEsLm3Zvii3UeFz0ZKXebsxEr+wEyaHnjiRV7VGnXe RuUA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:mime-version :content-transfer-encoding; bh=+gA8jssMO1pksTsqR/pMqsa2lOfnXR7skUMtSC/xqHY=; b=XePogdlwctxB+nP+WAej8Iifj4mAHuMfMrjQvi1UPGd26B+2E2Vso2XOkETMMljEYG C4Mg46JjCJ6XUJ/q5i0UZDPGVSLuHAbatzyYfm1lPBePqVxxV9dCdACYV8e/OoDTHIq8 bZim27E9g5TmYa5wkr1gdU6STvfK8duSQnw83WVLIX4+dqb1HmGtI7oZScuYOAdyboOk T+YUiRPWznSAYmkaS0jWLiYqqreF3X6ONx2AUtb9IS/RqqdAbeXmaGAdUmLuXbwFf86r 8iIchtVvzOiEtlVmYXYN+04XKcZxhK5fj2OrfGCbjrMJ0cwN1E1OmUv2bacR7mbL3RqV K9Dw== X-Gm-Message-State: APjAAAVvnvowg/5W/NW3pwHdtXo5KCLKtimDRnRrL8JWC7W0vzUddPEb LG3CjPzmN7YQfhUliJrC9u4= X-Received: by 2002:a62:2603:: with SMTP id m3mr22334428pfm.163.1566843939143; Mon, 26 Aug 2019 11:25:39 -0700 (PDT) Received: from localhost.lan (c-67-185-54-80.hsd1.wa.comcast.net. [67.185.54.80]) by smtp.gmail.com with ESMTPSA id 15sm4710778pfh.188.2019.08.26.11.25.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 26 Aug 2019 11:25:38 -0700 (PDT) From: Andrey Smirnov To: dri-devel@lists.freedesktop.org Cc: Andrey Smirnov , Andrzej Hajda , Laurent Pinchart , Tomi Valkeinen , Cory Tusar , Chris Healy , Lucas Stach , linux-kernel@vger.kernel.org Subject: [PATCH] drm/bridge: tc358767: Expose test mode functionality via debugfs Date: Mon, 26 Aug 2019 11:25:24 -0700 Message-Id: <20190826182524.5064-1-andrew.smirnov@gmail.com> X-Mailer: git-send-email 2.21.0 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Presently, the driver code artificially limits test pattern mode to a single pattern with fixed color selection. It being a kernel module parameter makes switching "test patter" <-> "proper output" modes on-the-fly clunky and outright impossible if the driver is built into the kernel. To improve the situation a bit, convert current test pattern code to use debugfs instead by exposing "TestCtl" register. This way old "tc_test_pattern=1" functionality can be emulated via: echo -n 0x78146312 > tstctl and switch back to regular mode can be done with: echo -n 0x78146310 > tstctl Note that switching to any of the test patterns, will NOT trigger link re-establishment whereas switching to normal operation WILL. This is done so: a) we can isolate and verify (e)DP link functionality by switching to one of the test patters b) trigger a link re-establishment by switching back to normal mode Signed-off-by: Andrey Smirnov Cc: Andrzej Hajda Cc: Laurent Pinchart Cc: Tomi Valkeinen Cc: Cory Tusar Cc: Chris Healy Cc: Lucas Stach Cc: dri-devel@lists.freedesktop.org Cc: linux-kernel@vger.kernel.org --- drivers/gpu/drm/bridge/tc358767.c | 137 ++++++++++++++++++++++-------- 1 file changed, 101 insertions(+), 36 deletions(-) diff --git a/drivers/gpu/drm/bridge/tc358767.c b/drivers/gpu/drm/bridge/tc358767.c index 6308d93ad91d..7a795b613ed0 100644 --- a/drivers/gpu/drm/bridge/tc358767.c +++ b/drivers/gpu/drm/bridge/tc358767.c @@ -17,6 +17,7 @@ #include #include +#include #include #include #include @@ -222,11 +223,10 @@ #define COLOR_B GENMASK(15, 8) #define ENI2CFILTER BIT(4) #define COLOR_BAR_MODE GENMASK(1, 0) +#define COLOR_BAR_MODE_NORMAL 0 #define COLOR_BAR_MODE_BARS 2 -#define PLL_DBG 0x0a04 -static bool tc_test_pattern; -module_param_named(test, tc_test_pattern, bool, 0644); +#define PLL_DBG 0x0a04 struct tc_edp_link { struct drm_dp_link base; @@ -789,16 +789,6 @@ static int tc_set_video_mode(struct tc_data *tc, if (ret) return ret; - /* Test pattern settings */ - ret = regmap_write(tc->regmap, TSTCTL, - FIELD_PREP(COLOR_R, 120) | - FIELD_PREP(COLOR_G, 20) | - FIELD_PREP(COLOR_B, 99) | - ENI2CFILTER | - FIELD_PREP(COLOR_BAR_MODE, COLOR_BAR_MODE_BARS)); - if (ret) - return ret; - /* DP Main Stream Attributes */ vid_sync_dly = hsync_len + left_margin + mode->hdisplay; ret = regmap_write(tc->regmap, DP0_VIDSYNCDELAY, @@ -1150,14 +1140,6 @@ static int tc_stream_enable(struct tc_data *tc) dev_dbg(tc->dev, "enable video stream\n"); - /* PXL PLL setup */ - if (tc_test_pattern) { - ret = tc_pxl_pll_en(tc, clk_get_rate(tc->refclk), - 1000 * tc->mode.clock); - if (ret) - return ret; - } - ret = tc_set_video_mode(tc, &tc->mode); if (ret) return ret; @@ -1186,12 +1168,8 @@ static int tc_stream_enable(struct tc_data *tc) if (ret) return ret; /* Set input interface */ - value = DP0_AUDSRC_NO_INPUT; - if (tc_test_pattern) - value |= DP0_VIDSRC_COLOR_BAR; - else - value |= DP0_VIDSRC_DPI_RX; - ret = regmap_write(tc->regmap, SYSCTRL, value); + ret = regmap_write(tc->regmap, SYSCTRL, + DP0_AUDSRC_NO_INPUT | DP0_VIDSRC_DPI_RX); if (ret) return ret; @@ -1220,39 +1198,44 @@ static void tc_bridge_pre_enable(struct drm_bridge *bridge) drm_panel_prepare(tc->panel); } -static void tc_bridge_enable(struct drm_bridge *bridge) +static int __tc_bridge_enable(struct tc_data *tc) { - struct tc_data *tc = bridge_to_tc(bridge); int ret; ret = tc_get_display_props(tc); if (ret < 0) { dev_err(tc->dev, "failed to read display props: %d\n", ret); - return; + return ret; } ret = tc_main_link_enable(tc); if (ret < 0) { dev_err(tc->dev, "main link enable error: %d\n", ret); - return; + return ret; } ret = tc_stream_enable(tc); if (ret < 0) { dev_err(tc->dev, "main link stream start error: %d\n", ret); tc_main_link_disable(tc); - return; } - drm_panel_enable(tc->panel); + return ret; } -static void tc_bridge_disable(struct drm_bridge *bridge) +static void tc_bridge_enable(struct drm_bridge *bridge) { struct tc_data *tc = bridge_to_tc(bridge); - int ret; - drm_panel_disable(tc->panel); + if (__tc_bridge_enable(tc) < 0) + return; + + drm_panel_enable(tc->panel); +} + +static int __tc_bridge_disable(struct tc_data *tc) +{ + int ret; ret = tc_stream_disable(tc); if (ret < 0) @@ -1261,6 +1244,16 @@ static void tc_bridge_disable(struct drm_bridge *bridge) ret = tc_main_link_disable(tc); if (ret < 0) dev_err(tc->dev, "main link disable error: %d\n", ret); + + return ret; +} + +static void tc_bridge_disable(struct drm_bridge *bridge) +{ + struct tc_data *tc = bridge_to_tc(bridge); + + drm_panel_disable(tc->panel); + __tc_bridge_disable(tc); } static void tc_bridge_post_disable(struct drm_bridge *bridge) @@ -1372,6 +1365,77 @@ static enum drm_connector_status tc_connector_detect(struct drm_connector *conne return connector_status_disconnected; } +static int tc_tstctl_set(void *data, u64 val) +{ + struct tc_data *tc = data; + int ret; + + if (FIELD_GET(COLOR_BAR_MODE, val) == COLOR_BAR_MODE_NORMAL) { + ret = regmap_write(tc->regmap, SYSCTRL, DP0_VIDSRC_DPI_RX); + if (ret) { + dev_err(tc->dev, + "failed to select dpi video stream\n"); + return ret; + } + + ret = regmap_write(tc->regmap, TSTCTL, val | ENI2CFILTER); + if (ret) { + dev_err(tc->dev, "failed to set TSTCTL\n"); + return ret; + } + + ret = tc_pxl_pll_dis(tc); + if (ret) { + dev_err(tc->dev, "failed to disable PLL\n"); + return ret; + } + + /* + * Re-establish DP link + */ + ret = __tc_bridge_disable(tc); + if (ret) + return ret; + + ret = __tc_bridge_enable(tc); + if (ret) + return ret; + } else { + ret = tc_pxl_pll_en(tc, clk_get_rate(tc->refclk), + 1000 * tc->mode.clock); + if (ret) { + dev_err(tc->dev, "failed to enable PLL\n"); + return ret; + } + + ret = regmap_write(tc->regmap, TSTCTL, val | ENI2CFILTER); + if (ret) { + dev_err(tc->dev, "failed to set TSTCTL\n"); + return ret; + } + + ret = regmap_write(tc->regmap, SYSCTRL, DP0_VIDSRC_COLOR_BAR); + if (ret) { + dev_err(tc->dev, "failed to color bar video stream\n"); + return ret; + } + } + + return 0; +} + +DEFINE_SIMPLE_ATTRIBUTE(tc_tstctl_fops, NULL, tc_tstctl_set, "%llu\n"); + +static int tc_late_register(struct drm_connector *connector) +{ + if (connector->debugfs_entry) + debugfs_create_file_unsafe("tstctl", 0644, + connector->debugfs_entry, + connector_to_tc(connector), + &tc_tstctl_fops); + return 0; +} + static const struct drm_connector_funcs tc_connector_funcs = { .detect = tc_connector_detect, .fill_modes = drm_helper_probe_single_connector_modes, @@ -1379,6 +1443,7 @@ static const struct drm_connector_funcs tc_connector_funcs = { .reset = drm_atomic_helper_connector_reset, .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, + .late_register = tc_late_register, }; static int tc_bridge_attach(struct drm_bridge *bridge) -- 2.21.0