From nobody Wed Jan 7 03:31:41 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4ECEBE7849A for ; Mon, 2 Oct 2023 13:18:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237440AbjJBNSQ (ORCPT ); Mon, 2 Oct 2023 09:18:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:59364 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237381AbjJBNSB (ORCPT ); Mon, 2 Oct 2023 09:18:01 -0400 Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E3EF3C6; Mon, 2 Oct 2023 06:17:57 -0700 (PDT) Received: by mail.gandi.net (Postfix) with ESMTPSA id 81AED1BF205; Mon, 2 Oct 2023 13:17:55 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1696252676; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=F+CSUvAMd1jybDq39rbPIkUIvZut6yZ4pfXMFOmMcHw=; b=Bu7573VhSa5erKsSfwK0iaEuh1VE0npy5odZq3iNi+YU0L+E6Tg69KeevCCXPqC0VXyT0a RZp//Qp3exSV75CU9MjD1plVw64IoBSBKPfq8+lVCOj7LfG3TPAAPh/aQiZ+tHCIbmce3x IFdbf3LBwq1ba/VIlrmUAIDMgJ8WJOPLvf9+v6ZZX/oOr9BKlYLaTpNUHktd7Dyq+lgWTj xzwh835qXlf65Ccnr+nmscYy5V4gVZb0cBcj90RF+c0KbU/r9K1dWAxSbA20feyzGcDzIs rj9+RKK49RBbwx2WPqWSgYgzkCgEV8EFgOoH1Gu7HABc0jo6qrkHAD+ofj8U2Q== From: =?UTF-8?q?K=C3=B6ry=20Maincent?= To: Cai Huoqing , Manivannan Sadhasivam , Serge Semin , Vinod Koul , Gustavo Pimentel , dmaengine@vger.kernel.org, linux-kernel@vger.kernel.org Cc: Thomas Petazzoni , Gustavo Pimentel , Herve Codina , Kory Maincent Subject: [PATCH v2 4/5] dmaengine: dw-edma: HDMA: Add sync read before starting the DMA transfer in remote setup Date: Mon, 2 Oct 2023 15:17:48 +0200 Message-Id: <20231002131749.2977952-5-kory.maincent@bootlin.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20231002131749.2977952-1-kory.maincent@bootlin.com> References: <20231002131749.2977952-1-kory.maincent@bootlin.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-GND-Sasl: kory.maincent@bootlin.com Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Type: text/plain; charset="utf-8" From: Kory Maincent The Linked list element and pointer are not stored in the same memory as the HDMA controller register. If the doorbell register is toggled before the full write of the linked list a race condition error can appears. In remote setup we can only use a readl to the memory to assured the full write has occurred. Fixes: e74c39573d35 ("dmaengine: dw-edma: Add support for native HDMA") Signed-off-by: Kory Maincent --- Changes in v2: - Move the sync read in a function. - Add commments --- drivers/dma/dw-edma/dw-hdma-v0-core.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/drivers/dma/dw-edma/dw-hdma-v0-core.c b/drivers/dma/dw-edma/dw= -hdma-v0-core.c index 0cce1880cfdc..26b5020dcc2a 100644 --- a/drivers/dma/dw-edma/dw-hdma-v0-core.c +++ b/drivers/dma/dw-edma/dw-hdma-v0-core.c @@ -221,6 +221,25 @@ static void dw_hdma_v0_core_write_chunk(struct dw_edma= _chunk *chunk) dw_hdma_v0_write_ll_link(chunk, i, control, chunk->ll_region.paddr); } =20 +/** + * dw_hdma_v0_sync_ll_data() - sync the ll data write + * @chunk: dma chunk + * + * In case of remote HDMA engine setup, the DW PCIe RP/EP internals + * configuration registers and Application memory are normally accesse + * over different buses. We need to insure ll data has been written before + * toggling the doorbell register. + */ +static void dw_hdma_v0_sync_ll_data(struct dw_edma_chunk *chunk) +{ + if (!(chunk->chan->dw->chip->flags & DW_EDMA_CHIP_LOCAL)) + /* Linux memory barriers don't cater for what's required here. + * What's required is what's here - a read of the linked + * list region. + */ + readl(chunk->ll_region.vaddr.io); +} + static void dw_hdma_v0_core_start(struct dw_edma_chunk *chunk, bool first) { struct dw_edma_chan *chan =3D chunk->chan; @@ -251,6 +270,9 @@ static void dw_hdma_v0_core_start(struct dw_edma_chunk = *chunk, bool first) /* Set consumer cycle */ SET_CH_32(dw, chan->dir, chan->id, cycle_sync, HDMA_V0_CONSUMER_CYCLE_STAT | HDMA_V0_CONSUMER_CYCLE_BIT); + + dw_hdma_v0_sync_ll_data(chunk); + /* Doorbell */ SET_CH_32(dw, chan->dir, chan->id, doorbell, HDMA_V0_DOORBELL_START); } --=20 2.25.1