From nobody Sat May 18 08:46:57 2024 Received: from ironport.ite.com.tw (60-251-196-230.hinet-ip.hinet.net [60.251.196.230]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8785948788 for ; Tue, 23 Apr 2024 08:16:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=60.251.196.230 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713860207; cv=none; b=J0sKSrxxaWxORjvzIJPKkLATeFPtZtq2env/+uolKwrGTkLne4H+3MB2Z0dIoR1auxhYQvsARWn4RCo88c6tzRDFWpN+3EyH2qz5aO11N6PYPNxMMxYZrE8TwaGippuY1F0lPuaVvMWFhuIs+rVrzgw5mfq4jBCOg6T88yjpcuA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1713860207; c=relaxed/simple; bh=qMRvRfCHt4RfsM1ayabBFvguO+HsdBVmxHCbs/4Emq0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=lkJ77Zq2t9yoQ3X38QUMmBv5UdDv6cbSXJ+xpKFzUAq3pre2jfnU8Rz1wX3+jhBeMbsxph7SvjGXUN1bAXwRNVwK09g0UI9BxzpTjGNdegWRrlPzajYpATekSA3j7iWnUui6U0HSDM4lJqd5x9SgRW3dk04H9NsjdmcGsjD4ETw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ite.com.tw; spf=pass smtp.mailfrom=ite.com.tw; dkim=fail (0-bit key) header.d=ite.com.tw header.i=@ite.com.tw header.b=H+GOWL9s reason="key not found in DNS"; arc=none smtp.client-ip=60.251.196.230 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=ite.com.tw Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=ite.com.tw Authentication-Results: smtp.subspace.kernel.org; dkim=fail reason="key not found in DNS" (0-bit key) header.d=ite.com.tw header.i=@ite.com.tw header.b="H+GOWL9s" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ite.com.tw; s=dkim; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version:content-transfer-encoding; bh=ZtLQhVDsiAYpK4O5MlGv6l3VXtS61DUL+pH4DJcyy/Q=; b=H+GOWL9s+34ow1f+trqu4m+usnpck+ckQ8KEfPicE1lUx5ih0lPLidEN O8m2VQ68tP73tpU1OlvahFDhwaY1mTcD2aIvvcYRrxJhLKdrSymDYY68M wEXAd6URnU5sqvIbPDyeBVFXN+NqLpa2idIq45tc4hHeVJ4AWSzv31pio YBe0V/BMrfh/8Xa+s4iIUGoRPBd29igm0uAG7Uq6IEvIMgO2AdUjH+aly GKpgrwTMBTV8SY3mRom+ure+OXJKLNwOMUQJdIhJYNjM5nLCUQtWS2057 XzAI/yurP0AWbyjcY54KV+LePIoq1bw9hWez2grVpXMRHG18LYZG2J7Q5 g==; Received: from unknown (HELO mse.ite.com.tw) ([192.168.35.30]) by ironport.ite.com.tw with ESMTP; 23 Apr 2024 16:16:34 +0800 Received: from CSBMAIL1.internal.ite.com.tw (CSBMAIL1.internal.ite.com.tw [192.168.65.58]) by mse.ite.com.tw with ESMTP id 43N8GRwc058283; Tue, 23 Apr 2024 16:16:27 +0800 (GMT-8) (envelope-from kuro.chung@ite.com.tw) Received: from ite-XPS-13-9360.internal.ite.com.tw (192.168.72.42) by CSBMAIL1.internal.ite.com.tw (192.168.65.58) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.35; Tue, 23 Apr 2024 16:16:27 +0800 From: kuro To: CC: Allen Chen , Pin-yen Lin , Kuro Chung , Kenneth Haung , Kuro Chung , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Daniel Vetter , "open list:DRM DRIVERS" , open list Subject: [PATCH v6 1/1] drm/bridge: it6505: fix hibernate to resume no display issue Date: Tue, 23 Apr 2024 16:27:22 +0800 Message-ID: <20240423082722.843587-2-kuro.chung@ite.com.tw> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240423082722.843587-1-kuro.chung@ite.com.tw> References: <20240423082722.843587-1-kuro.chung@ite.com.tw> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: CSBMAIL1.internal.ite.com.tw (192.168.65.58) To CSBMAIL1.internal.ite.com.tw (192.168.65.58) X-TM-SNTS-SMTP: 3B09192209B203025BD741B7ACA8E0C697888362F73B39FE3A32B9968F8B69552002:8 X-MAIL: mse.ite.com.tw 43N8GRwc058283 Content-Type: text/plain; charset="utf-8" From: Kuro ITE added a FIFO reset bit for input video. When system power resume, the TTL input of it6505 may get some noise before video signal stable and the hardware function reset is required. But the input FIFO reset will also trigger error interrupts of output modul= e rising. Thus, it6505 have to wait a period can clear those expected error interrupts caused by manual hardware reset in one interrupt handler calling to avoid i= nterrupt looping. Signed-off-by: Kuro Chung --- drivers/gpu/drm/bridge/ite-it6505.c | 73 +++++++++++++++++++---------- 1 file changed, 49 insertions(+), 24 deletions(-) diff --git a/drivers/gpu/drm/bridge/ite-it6505.c b/drivers/gpu/drm/bridge/i= te-it6505.c index b53da9bb65a16..ae7f4c7ec6dd0 100644 --- a/drivers/gpu/drm/bridge/ite-it6505.c +++ b/drivers/gpu/drm/bridge/ite-it6505.c @@ -1317,9 +1317,15 @@ static void it6505_video_reset(struct it6505 *it6505) it6505_link_reset_step_train(it6505); it6505_set_bits(it6505, REG_DATA_MUTE_CTRL, EN_VID_MUTE, EN_VID_MUTE); it6505_set_bits(it6505, REG_INFOFRAME_CTRL, EN_VID_CTRL_PKT, 0x00); - it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET); + + it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 0x02); + it6505_set_bits(it6505, REG_VID_BUS_CTRL1, TX_FIFO_RESET, 0x00); + it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, RST_501_FIFO); it6505_set_bits(it6505, REG_501_FIFO_CTRL, RST_501_FIFO, 0x00); + + it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, VIDEO_RESET); + usleep_range(1000, 2000); it6505_set_bits(it6505, REG_RESET_CTRL, VIDEO_RESET, 0x00); } =20 @@ -2249,12 +2255,11 @@ static void it6505_link_training_work(struct work_s= truct *work) if (ret) { it6505->auto_train_retry =3D AUTO_TRAIN_RETRY; it6505_link_train_ok(it6505); - return; } else { it6505->auto_train_retry--; + it6505_dump(it6505); } =20 - it6505_dump(it6505); } =20 static void it6505_plugged_status_to_codec(struct it6505 *it6505) @@ -2475,31 +2480,53 @@ static void it6505_irq_link_train_fail(struct it650= 5 *it6505) schedule_work(&it6505->link_works); } =20 -static void it6505_irq_video_fifo_error(struct it6505 *it6505) +static bool it6505_test_bit(unsigned int bit, const unsigned int *addr) { - struct device *dev =3D &it6505->client->dev; - - DRM_DEV_DEBUG_DRIVER(dev, "video fifo overflow interrupt"); - it6505->auto_train_retry =3D AUTO_TRAIN_RETRY; - flush_work(&it6505->link_works); - it6505_stop_hdcp(it6505); - it6505_video_reset(it6505); + return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE)); } =20 -static void it6505_irq_io_latch_fifo_overflow(struct it6505 *it6505) +static void it6505_irq_video_handler(struct it6505 *it6505, const int *int= _status) { struct device *dev =3D &it6505->client->dev; + int reg_0d, reg_int03; =20 - DRM_DEV_DEBUG_DRIVER(dev, "IO latch fifo overflow interrupt"); - it6505->auto_train_retry =3D AUTO_TRAIN_RETRY; - flush_work(&it6505->link_works); - it6505_stop_hdcp(it6505); - it6505_video_reset(it6505); -} + /* + * When video SCDT change with video not stable, + * Or video FIFO error, need video reset + */ =20 -static bool it6505_test_bit(unsigned int bit, const unsigned int *addr) -{ - return 1 & (addr[bit / BITS_PER_BYTE] >> (bit % BITS_PER_BYTE)); + if ((!it6505_get_video_status(it6505) && + (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *) int_status))) || + (it6505_test_bit(BIT_INT_IO_FIFO_OVERFLOW, (unsigned int *) int_status))= || + (it6505_test_bit(BIT_INT_VID_FIFO_ERROR, (unsigned int *) int_status))) { + + it6505->auto_train_retry =3D AUTO_TRAIN_RETRY; + flush_work(&it6505->link_works); + it6505_stop_hdcp(it6505); + it6505_video_reset(it6505); + + usleep_range(10000, 11000); + + /* + * Clear FIFO error IRQ to prevent fifo error -> reset loop + * HW will trigger SCDT change IRQ again when video stable + */ + + reg_int03 =3D it6505_read(it6505, INT_STATUS_03); + reg_0d =3D it6505_read(it6505, REG_SYSTEM_STS); + + reg_int03 &=3D (BIT(INT_VID_FIFO_ERROR) | BIT(INT_IO_LATCH_FIFO_OVERFLOW= )); + it6505_write(it6505, INT_STATUS_03, reg_int03); + + DRM_DEV_DEBUG_DRIVER(dev, "reg08 =3D 0x%02x", reg_int03); + DRM_DEV_DEBUG_DRIVER(dev, "reg0D =3D 0x%02x", reg_0d); + + return; + } + + + if (it6505_test_bit(INT_SCDT_CHANGE, (unsigned int *) int_status)) + it6505_irq_scdt(it6505); } =20 static irqreturn_t it6505_int_threaded_handler(int unused, void *data) @@ -2512,15 +2539,12 @@ static irqreturn_t it6505_int_threaded_handler(int = unused, void *data) } irq_vec[] =3D { { BIT_INT_HPD, it6505_irq_hpd }, { BIT_INT_HPD_IRQ, it6505_irq_hpd_irq }, - { BIT_INT_SCDT, it6505_irq_scdt }, { BIT_INT_HDCP_FAIL, it6505_irq_hdcp_fail }, { BIT_INT_HDCP_DONE, it6505_irq_hdcp_done }, { BIT_INT_AUX_CMD_FAIL, it6505_irq_aux_cmd_fail }, { BIT_INT_HDCP_KSV_CHECK, it6505_irq_hdcp_ksv_check }, { BIT_INT_AUDIO_FIFO_ERROR, it6505_irq_audio_fifo_error }, { BIT_INT_LINK_TRAIN_FAIL, it6505_irq_link_train_fail }, - { BIT_INT_VID_FIFO_ERROR, it6505_irq_video_fifo_error }, - { BIT_INT_IO_FIFO_OVERFLOW, it6505_irq_io_latch_fifo_overflow }, }; int int_status[3], i; =20 @@ -2550,6 +2574,7 @@ static irqreturn_t it6505_int_threaded_handler(int un= used, void *data) if (it6505_test_bit(irq_vec[i].bit, (unsigned int *)int_status)) irq_vec[i].handler(it6505); } + it6505_irq_video_handler(it6505, (unsigned int *) int_status); } =20 pm_runtime_put_sync(dev); --=20 2.25.1