From patchwork Fri Mar 10 04:32:39 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Paul X-Patchwork-Id: 9614787 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 054A960415 for ; Fri, 10 Mar 2017 04:51:14 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EB133286C0 for ; Fri, 10 Mar 2017 04:51:13 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DFE58286EF; Fri, 10 Mar 2017 04:51:13 +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=-3.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, FUZZY_AMBIEN, RCVD_IN_DNSWL_MED, T_DKIM_INVALID autolearn=ham version=3.3.1 Received: from gabe.freedesktop.org (gabe.freedesktop.org [131.252.210.177]) (using TLSv1.2 with cipher DHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.wl.linuxfoundation.org (Postfix) with ESMTPS id 367C5286C0 for ; Fri, 10 Mar 2017 04:51:13 +0000 (UTC) Received: from gabe.freedesktop.org (localhost [127.0.0.1]) by gabe.freedesktop.org (Postfix) with ESMTP id 12A716EDB1; Fri, 10 Mar 2017 04:50:42 +0000 (UTC) X-Original-To: dri-devel@lists.freedesktop.org Delivered-To: dri-devel@lists.freedesktop.org Received: from mail-qk0-x234.google.com (mail-qk0-x234.google.com [IPv6:2607:f8b0:400d:c09::234]) by gabe.freedesktop.org (Postfix) with ESMTPS id 788E16ED93 for ; Fri, 10 Mar 2017 04:48:53 +0000 (UTC) Received: by mail-qk0-x234.google.com with SMTP id p64so152497601qke.1 for ; Thu, 09 Mar 2017 20:48:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=chromium.org; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=C5luKXokBWnzaQ+96D4ogW0czgAJ6Uf8ZTI5Iens0dI=; b=OQMfRezJiMaw6yR0YC9CCgwRe2eL/W4idtzyQ0ZGDfcqhl/XZNq/u8nModJ2fN+aWv btF1zademKfhFHBhBxpTT1L65mdNhD8H5BvNqfunCOF/ehBoAYgp4pPaAnGunmqy2rf9 yHIDSQkkqG3nUbnGby7vccz+wrWbwyWxHjSC4= 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:in-reply-to :references; bh=C5luKXokBWnzaQ+96D4ogW0czgAJ6Uf8ZTI5Iens0dI=; b=NZV5wa8Q0MMes5MT8H5H56eNqihmYHFbWIIVznMmOJ0uXYz0iCtA7IqV/1BITYDfXy NN8vZ7MTJtplyXw8dcoSt6A5HPFJJTpdWROHm/m0CCjDWBY3AQ4+mTL1jHOo0ysq9w2b 6ergH3kmJqkjA5vdaL44jOIqWhFuuKiUIon8CEaz0QDPXYFbAvPOlLCRZlLo+MAzQfnX jrKdTC/AKpgOvf0hyBWum40ynblQaf9zGL52GcCEyyFbIpPS4WEORfnK0IiQbeNJbqD1 i0/tmcB5rb+G15xeCV9MVgjFXtk0J6JMHvtl+LgduqguYzqXR3sq7tLndyKerfpGoKTs ZrGA== X-Gm-Message-State: AMke39lBrbaqTQB0+kf1jqSTURt6uiWq2pRfWi6QgGP7lGfvhgw+klrEwYljSkykpQDaww/w X-Received: by 10.237.34.250 with SMTP id q55mr18452043qtc.144.1489120759653; Thu, 09 Mar 2017 20:39:19 -0800 (PST) Received: from boxwood.roam.corp.google.com (cpe-75-189-128-87.nc.res.rr.com. [75.189.128.87]) by smtp.gmail.com with ESMTPSA id n19sm5697731qtn.35.2017.03.09.20.39.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 09 Mar 2017 20:39:18 -0800 (PST) From: Sean Paul To: linux-rockchip@lists.infradead.org, dri-devel@lists.freedesktop.org Subject: [PATCH 24/41] drm/bridge: analogix_dp: Check dpcd write/read status Date: Thu, 9 Mar 2017 23:32:39 -0500 Message-Id: <20170310043305.17216-25-seanpaul@chromium.org> X-Mailer: git-send-email 2.12.0.246.ga2ecc84866-goog In-Reply-To: <20170310043305.17216-1-seanpaul@chromium.org> References: <20170310043305.17216-1-seanpaul@chromium.org> Cc: zain wang , Lin Huang , Tomeu Vizoso , Douglas Anderson , Yakir Yang , "Kristian H . Kristensen" X-BeenThere: dri-devel@lists.freedesktop.org X-Mailman-Version: 2.1.18 Precedence: list List-Id: Direct Rendering Infrastructure - Development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" X-Virus-Scanned: ClamAV using ClamSMTP From: Lin Huang We need to check the dpcd write/read return value to see whether the write/read was successful Cc: Kristian H. Kristensen Signed-off-by: Lin Huang Signed-off-by: zain wang Signed-off-by: Douglas Anderson Signed-off-by: Sean Paul Reviewed-by: Andrzej Hajda --- drivers/gpu/drm/bridge/analogix/analogix_dp_core.c | 173 +++++++++++++++------ 1 file changed, 125 insertions(+), 48 deletions(-) diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index 8d69d4327871..dcf39ea0d14b 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -163,80 +163,132 @@ int analogix_dp_disable_psr(struct device *dev) } EXPORT_SYMBOL_GPL(analogix_dp_disable_psr); -static bool analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) +static int analogix_dp_detect_sink_psr(struct analogix_dp_device *dp) { unsigned char psr_version; + int ret; + + ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version); + if (ret != 1) { + dev_err(dp->dev, "failed to get PSR version, disable it\n"); + return ret; + } - drm_dp_dpcd_readb(&dp->aux, DP_PSR_SUPPORT, &psr_version); dev_dbg(dp->dev, "Panel PSR version : %x\n", psr_version); - return (psr_version & DP_PSR_IS_SUPPORTED) ? true : false; + dp->psr_enable = (psr_version & DP_PSR_IS_SUPPORTED) ? true : false; + return 0; } -static void analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) +static int analogix_dp_enable_sink_psr(struct analogix_dp_device *dp) { unsigned char psr_en; + int ret; /* Disable psr function */ - drm_dp_dpcd_readb(&dp->aux, DP_PSR_EN_CFG, &psr_en); + ret = drm_dp_dpcd_readb(&dp->aux, DP_PSR_EN_CFG, &psr_en); + if (ret != 1) { + dev_err(dp->dev, "failed to get psr config\n"); + goto end; + } + psr_en &= ~DP_PSR_ENABLE; - drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); + ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); + if (ret != 1) { + dev_err(dp->dev, "failed to disable panel psr\n"); + goto end; + } /* Main-Link transmitter remains active during PSR active states */ psr_en = DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; - drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); + ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); + if (ret != 1) { + dev_err(dp->dev, "failed to set panel psr\n"); + goto end; + } /* Enable psr function */ psr_en = DP_PSR_ENABLE | DP_PSR_MAIN_LINK_ACTIVE | DP_PSR_CRC_VERIFICATION; - drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); + ret = drm_dp_dpcd_writeb(&dp->aux, DP_PSR_EN_CFG, psr_en); + if (ret != 1) { + dev_err(dp->dev, "failed to set panel psr\n"); + goto end; + } analogix_dp_enable_psr_crc(dp); + return 0; +end: + dev_err(dp->dev, "enable psr fail, force to disable psr\n"); + dp->psr_enable = false; + return ret; } -static void +static int analogix_dp_enable_rx_to_enhanced_mode(struct analogix_dp_device *dp, bool enable) { u8 data; + int ret; - drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data); + ret = drm_dp_dpcd_readb(&dp->aux, DP_LANE_COUNT_SET, &data); + if (ret < 0) + return ret; if (enable) - drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, - DP_LANE_COUNT_ENHANCED_FRAME_EN | - DPCD_LANE_COUNT_SET(data)); + ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, + DP_LANE_COUNT_ENHANCED_FRAME_EN | + DPCD_LANE_COUNT_SET(data)); else - drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, - DPCD_LANE_COUNT_SET(data)); + ret = drm_dp_dpcd_writeb(&dp->aux, DP_LANE_COUNT_SET, + DPCD_LANE_COUNT_SET(data)); + + return ret < 0 ? ret : 0; } -static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp) +static int analogix_dp_is_enhanced_mode_available(struct analogix_dp_device *dp, + u8 *enhanced_mode_support) { u8 data; - int retval; + int ret; - drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data); - retval = DPCD_ENHANCED_FRAME_CAP(data); + ret = drm_dp_dpcd_readb(&dp->aux, DP_MAX_LANE_COUNT, &data); + if (ret < 0) + return ret; - return retval; + *enhanced_mode_support = DPCD_ENHANCED_FRAME_CAP(data); + + return 0; } -static void analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp) +static int analogix_dp_set_enhanced_mode(struct analogix_dp_device *dp) { u8 data; + int ret; + + ret = analogix_dp_is_enhanced_mode_available(dp, &data); + if (ret < 0) + return ret; + + ret = analogix_dp_enable_rx_to_enhanced_mode(dp, data); + if (ret < 0) + return ret; - data = analogix_dp_is_enhanced_mode_available(dp); - analogix_dp_enable_rx_to_enhanced_mode(dp, data); analogix_dp_enable_enhanced_mode(dp, data); + + return 0; } -static void analogix_dp_training_pattern_dis(struct analogix_dp_device *dp) +static int analogix_dp_training_pattern_dis(struct analogix_dp_device *dp) { + int retval; + analogix_dp_set_training_pattern(dp, DP_NONE); - drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, - DP_TRAINING_PATTERN_DISABLE); + retval = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, + DP_TRAINING_PATTERN_DISABLE); + + return retval < 0 ? retval : 0; } static void @@ -285,7 +337,11 @@ static int analogix_dp_link_start(struct analogix_dp_device *dp) if (retval < 0) return retval; /* set enhanced mode if available */ - analogix_dp_set_enhanced_mode(dp); + retval = analogix_dp_set_enhanced_mode(dp); + if (retval < 0) { + dev_err(dp->dev, "failed to set enhance mode\n"); + return retval; + } /* Set TX pre-emphasis to minimum */ for (lane = 0; lane < lane_count; lane++) @@ -570,10 +626,11 @@ static int analogix_dp_process_equalizer_training(struct analogix_dp_device *dp) if (!analogix_dp_channel_eq_ok(link_status, link_align, lane_count)) { /* traing pattern Set to Normal */ - analogix_dp_training_pattern_dis(dp); + retval = analogix_dp_training_pattern_dis(dp); + if (retval < 0) + return retval; dev_info(dp->dev, "Link Training success!\n"); - analogix_dp_get_link_bandwidth(dp, ®); dp->link_train.link_rate = reg; dev_dbg(dp->dev, "final bandwidth = %.2x\n", @@ -810,7 +867,6 @@ static int analogix_dp_train_link(struct analogix_dp_device *dp) static int analogix_dp_config_video(struct analogix_dp_device *dp) { - int retval = 0; int timeout_loop = 0; int done_count = 0; @@ -828,8 +884,9 @@ static int analogix_dp_config_video(struct analogix_dp_device *dp) if (analogix_dp_is_slave_video_stream_clock_on(dp) == 0) break; if (timeout_loop > DP_TIMEOUT_LOOP_COUNT) { - dev_err(dp->dev, "Timeout of slave video streamclk ok\n"); - return -ETIMEDOUT; + dev_warn(dp->dev, + "Ignoring timeout of slave video streamclk ok\n"); + break; } usleep_range(1000, 1001); } @@ -868,30 +925,35 @@ static int analogix_dp_config_video(struct analogix_dp_device *dp) usleep_range(1000, 1001); } - if (retval != 0) - dev_err(dp->dev, "Video stream is not detected!\n"); - - return retval; + return 0; } -static void analogix_dp_enable_scramble(struct analogix_dp_device *dp, +static int analogix_dp_enable_scramble(struct analogix_dp_device *dp, bool enable) { u8 data; + int ret; if (enable) { analogix_dp_enable_scrambling(dp); - drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET, &data); - drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, + ret = drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET, + &data); + if (ret != 1) + return ret; + ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, (u8)(data & ~DP_LINK_SCRAMBLING_DISABLE)); } else { analogix_dp_disable_scrambling(dp); - drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET, &data); - drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, + ret = drm_dp_dpcd_readb(&dp->aux, DP_TRAINING_PATTERN_SET, + &data); + if (ret != 1) + return ret; + ret = drm_dp_dpcd_writeb(&dp->aux, DP_TRAINING_PATTERN_SET, (u8)(data | DP_LINK_SCRAMBLING_DISABLE)); } + return ret < 0 ? ret : 0; } static irqreturn_t analogix_dp_hardirq(int irq, void *arg) @@ -946,23 +1008,36 @@ static int analogix_dp_commit(struct analogix_dp_device *dp) return ret; } - analogix_dp_enable_scramble(dp, 1); + ret = analogix_dp_enable_scramble(dp, 1); + if (ret < 0) { + dev_err(dp->dev, "can not enable scramble\n"); + return ret; + } analogix_dp_init_video(dp); ret = analogix_dp_config_video(dp); - if (ret) + if (ret) { dev_err(dp->dev, "unable to config video\n"); + return ret; + } /* Safe to enable the panel now */ if (dp->plat_data->panel) { - if (drm_panel_enable(dp->plat_data->panel)) + ret = drm_panel_enable(dp->plat_data->panel); + if (ret) { DRM_ERROR("failed to enable the panel\n"); + return ret; + } } - dp->psr_enable = analogix_dp_detect_sink_psr(dp); + ret = analogix_dp_detect_sink_psr(dp); + if (ret) + return ret; + if (dp->psr_enable) - analogix_dp_enable_sink_psr(dp); - return 0; + ret = analogix_dp_enable_sink_psr(dp); + + return ret; } /* @@ -1186,8 +1261,10 @@ static int analogix_dp_set_bridge(struct analogix_dp_device *dp) } ret = analogix_dp_commit(dp); - if (ret) + if (ret) { + DRM_ERROR("dp commit error, ret = %d\n", ret); goto out_dp_init; + } enable_irq(dp->irq); return 0;