From patchwork Fri Mar 7 04:34:43 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Dmitry Baryshkov X-Patchwork-Id: 871697 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 6E1B6C2E0; Fri, 7 Mar 2025 04:35:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741322101; cv=none; b=KAVRJjZP0W33jvxhiHO/hlkn+bPJtvqOPdbgnadulf+4AVGi8D5htlslgdnMJP3gHVhlB9amSZE9sNq3+lX5MNFC2jcW5jx6XFgiP+IDnb78fA7uaUzmm4Vrh+8cBhHNu8G1dXcwbV181hjn7nQ64Vca8fhauxLyRbkLG8LrRd8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1741322101; c=relaxed/simple; bh=eOTV044WYhocRx1vXkpraElTyG3Fqa9oEKLRf65avo8=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PCB0uc2vYWm8TEBwi45CwOji0dLeCw+bkR7LQkIuIDtwzyqliRDQf7MurRgNH6JtgGpjSUMEW41D7uU12k3MeqLRJp5tGfsGOWR6raKE6+yBhqhaokSYgxXvCLlMF6X67ekA7VUfp3N839RdvEbXuUadgOo3ymMc+Dh9dGXQWlI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=kbBv0Wez; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="kbBv0Wez" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 4CA82C4CEE7; Fri, 7 Mar 2025 04:34:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1741322100; bh=eOTV044WYhocRx1vXkpraElTyG3Fqa9oEKLRf65avo8=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=kbBv0Wez8COiRkm4MKqKGM+B9CMdvf6w2xB6CCt79bTj2qE4PdtCoyOtslleQvw9J Tf8bkIsng/MGnib3O741wH+yTt+1cEhUgH56C5VRvlABiMkBK+6yrkJAIiQDhFpmLY tBluPkg4/TYUg83NYvvFfmyXAjnsRicuS7Rt/TpM7TtSVQrQr9XJmHBAjwpeDSdqiE qEhqe3u4xPnzk8wmElvd9/kg8q1jIoRsIHM/tIxBYZjPuIdqoVPwaFOWi2n+ub4UbW h84gvqs85+4Jj+YWbZ1PQ3tmHFmxo8WdFb4LCwk7wfOOTH6mvvFBd9rkyrnnyMthmC xqCGfJJijZ3NQ== From: Dmitry Baryshkov Date: Fri, 07 Mar 2025 06:34:43 +0200 Subject: [PATCH RFC v3 1/7] drm/display: dp: implement new access helpers Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20250307-drm-rework-dpcd-access-v3-1-9044a3a868ee@linaro.org> References: <20250307-drm-rework-dpcd-access-v3-0-9044a3a868ee@linaro.org> In-Reply-To: <20250307-drm-rework-dpcd-access-v3-0-9044a3a868ee@linaro.org> To: Lyude Paul , Maarten Lankhorst , Maxime Ripard , Thomas Zimmermann , David Airlie , Simona Vetter , Rob Clark , Abhinav Kumar , Sean Paul , Marijn Suijten , Jani Nikula , Alex Deucher , =?utf-8?q?Christian_K=C3=B6nig?= , Andrzej Hajda , Neil Armstrong , Robert Foss , Laurent Pinchart , Jonas Karlman , Jernej Skrabec , Xinliang Liu , Tian Tao , Xinwei Kong , Sumit Semwal , Yongqin Liu , John Stultz Cc: dri-devel@lists.freedesktop.org, linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, freedreno@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, intel-xe@lists.freedesktop.org, amd-gfx@lists.freedesktop.org, Jani Nikula X-Mailer: b4 0.14.2 X-Developer-Signature: v=1; a=openpgp-sha256; l=6662; i=dmitry.baryshkov@linaro.org; h=from:subject:message-id; bh=SmZu1bk63rEb0BXZXya3Ueg7NpPOC5KqOlIN1CXFX+4=; b=owEBbQGS/pANAwAKAYs8ij4CKSjVAcsmYgBnyndlpmM7SwYZ9oezAZbVfAnEvPMSol8yIr3yL cjm9tXBuZSJATMEAAEKAB0WIQRMcISVXLJjVvC4lX+LPIo+Aiko1QUCZ8p3ZQAKCRCLPIo+Aiko 1XwuB/94oyKTlhatl5m82hLLyvzpc7YCxkMcpwIBqCye2l9AEF2N7CcaS13LLQqV72VPqizPqkV Y76HuqAJ90v42eB3x/As32QFw2dcPobj+smP+OArSoN1pzgty2qvUK6wPaiRoY0px6MrzGUzLR8 X2pVePwcouuQpYsLN3cTjtnw6xAe2ChT4S5TiaoK+50m4z0Hf6EX8lVbGByY/l2F2zQFUOTr0Gs ZI7JejT0cBOpQPeZegZqy+O7ic7mXXoLAtb0hjRHhUpVUdp4JEBruO1g4TzwaCuqX89uXmELSHV 2+ptEU1JzbibIyR9bSUj04CvQ1H1SVVOef0tcYQYHNCuAx0j X-Developer-Key: i=dmitry.baryshkov@linaro.org; a=openpgp; fpr=8F88381DD5C873E4AE487DA5199BF1243632046A From: Dmitry Baryshkov Existing DPCD access functions return an error code or the number of bytes being read / write in case of partial access. However a lot of drivers either (incorrectly) ignore partial access or mishandle error codes. In other cases this results in a boilerplate code which compares returned value with the size. Implement new set of DPCD access helpers, which ignore partial access, always return 0 or an error code. Suggested-by: Jani Nikula Acked-by: Jani Nikula Signed-off-by: Dmitry Baryshkov Reviewed-by: Lyude Paul --- drivers/gpu/drm/display/drm_dp_helper.c | 4 ++ include/drm/display/drm_dp_helper.h | 92 ++++++++++++++++++++++++++++++++- 2 files changed, 94 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/display/drm_dp_helper.c b/drivers/gpu/drm/display/drm_dp_helper.c index dbce1c3f49691fc687fee2404b723c73d533f23d..e43a8f4a252dae22eeaae1f4ca94da064303033d 100644 --- a/drivers/gpu/drm/display/drm_dp_helper.c +++ b/drivers/gpu/drm/display/drm_dp_helper.c @@ -704,6 +704,8 @@ EXPORT_SYMBOL(drm_dp_dpcd_set_powered); * function returns -EPROTO. Errors from the underlying AUX channel transfer * function, with the exception of -EBUSY (which causes the transaction to * be retried), are propagated to the caller. + * + * In most of the cases you want to use drm_dp_dpcd_read_data() instead. */ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size) @@ -752,6 +754,8 @@ EXPORT_SYMBOL(drm_dp_dpcd_read); * function returns -EPROTO. Errors from the underlying AUX channel transfer * function, with the exception of -EBUSY (which causes the transaction to * be retried), are propagated to the caller. + * + * In most of the cases you want to use drm_dp_dpcd_write_data() instead. */ ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size) diff --git a/include/drm/display/drm_dp_helper.h b/include/drm/display/drm_dp_helper.h index 5ae4241959f24e2c1fb581d7c7d770485d603099..c5be44d72c9a04474f6c795e03bf02bf08f5eaef 100644 --- a/include/drm/display/drm_dp_helper.h +++ b/include/drm/display/drm_dp_helper.h @@ -527,6 +527,64 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_aux *aux, unsigned int offset, ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset, void *buffer, size_t size); +/** + * drm_dp_dpcd_read_data() - read a series of bytes from the DPCD + * @aux: DisplayPort AUX channel (SST or MST) + * @offset: address of the (first) register to read + * @buffer: buffer to store the register values + * @size: number of bytes in @buffer + * + * Returns zero (0) on success, or a negative error + * code on failure. -EIO is returned if the request was NAKed by the sink or + * if the retry count was exceeded. If not all bytes were transferred, this + * function returns -EPROTO. Errors from the underlying AUX channel transfer + * function, with the exception of -EBUSY (which causes the transaction to + * be retried), are propagated to the caller. + */ +static inline int drm_dp_dpcd_read_data(struct drm_dp_aux *aux, + unsigned int offset, + void *buffer, size_t size) +{ + int ret; + + ret = drm_dp_dpcd_read(aux, offset, buffer, size); + if (ret < 0) + return ret; + if (ret < size) + return -EPROTO; + + return 0; +} + +/** + * drm_dp_dpcd_write_data() - write a series of bytes to the DPCD + * @aux: DisplayPort AUX channel (SST or MST) + * @offset: address of the (first) register to write + * @buffer: buffer containing the values to write + * @size: number of bytes in @buffer + * + * Returns zero (0) on success, or a negative error + * code on failure. -EIO is returned if the request was NAKed by the sink or + * if the retry count was exceeded. If not all bytes were transferred, this + * function returns -EPROTO. Errors from the underlying AUX channel transfer + * function, with the exception of -EBUSY (which causes the transaction to + * be retried), are propagated to the caller. + */ +static inline int drm_dp_dpcd_write_data(struct drm_dp_aux *aux, + unsigned int offset, + void *buffer, size_t size) +{ + int ret; + + ret = drm_dp_dpcd_write(aux, offset, buffer, size); + if (ret < 0) + return ret; + if (ret < size) + return -EPROTO; + + return 0; +} + /** * drm_dp_dpcd_readb() - read a single byte from the DPCD * @aux: DisplayPort AUX channel @@ -534,7 +592,8 @@ ssize_t drm_dp_dpcd_write(struct drm_dp_aux *aux, unsigned int offset, * @valuep: location where the value of the register will be stored * * Returns the number of bytes transferred (1) on success, or a negative - * error code on failure. + * error code on failure. In most of the cases you should be using + * drm_dp_dpcd_read_byte() instead */ static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux, unsigned int offset, u8 *valuep) @@ -549,7 +608,8 @@ static inline ssize_t drm_dp_dpcd_readb(struct drm_dp_aux *aux, * @value: value to write to the register * * Returns the number of bytes transferred (1) on success, or a negative - * error code on failure. + * error code on failure. In most of the cases you should be using + * drm_dp_dpcd_write_byte() instead */ static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux, unsigned int offset, u8 value) @@ -557,6 +617,34 @@ static inline ssize_t drm_dp_dpcd_writeb(struct drm_dp_aux *aux, return drm_dp_dpcd_write(aux, offset, &value, 1); } +/** + * drm_dp_dpcd_read_byte() - read a single byte from the DPCD + * @aux: DisplayPort AUX channel + * @offset: address of the register to read + * @valuep: location where the value of the register will be stored + * + * Returns zero (0) on success, or a negative error code on failure. + */ +static inline int drm_dp_dpcd_read_byte(struct drm_dp_aux *aux, + unsigned int offset, u8 *valuep) +{ + return drm_dp_dpcd_read_data(aux, offset, valuep, 1); +} + +/** + * drm_dp_dpcd_write_byte() - write a single byte to the DPCD + * @aux: DisplayPort AUX channel + * @offset: address of the register to write + * @value: value to write to the register + * + * Returns zero (0) on success, or a negative error code on failure. + */ +static inline int drm_dp_dpcd_write_byte(struct drm_dp_aux *aux, + unsigned int offset, u8 value) +{ + return drm_dp_dpcd_write_data(aux, offset, &value, 1); +} + int drm_dp_read_dpcd_caps(struct drm_dp_aux *aux, u8 dpcd[DP_RECEIVER_CAP_SIZE]);