From patchwork Sat May 27 16:44:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Artur Rojek X-Patchwork-Id: 99851 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp460608vqr; Sat, 27 May 2023 09:54:43 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ77XWeR6gjIW7zJzU3+1CxJGwrQMdj0g9EVpZLGU8/T3udHo2w50nFjr1nLRTknv1uRtn7L X-Received: by 2002:a17:902:d48a:b0:1af:e4d5:703c with SMTP id c10-20020a170902d48a00b001afe4d5703cmr7189684plg.61.1685206483609; Sat, 27 May 2023 09:54:43 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685206483; cv=none; d=google.com; s=arc-20160816; b=SkpHszt2kIeW5HnGt19wD8Ike4tFz0+oq20yR8cWMuPZZlO53AcOzrKVfT/sGHH3XQ /2oEdl4tH9gjBsx5IsVCNMVcxAXXrltm7TreaUfXPv1ZFpHVlw79y6MlNZDgTlHhMIs6 3SBq3F4Wm11B8OGIlwPy1yht5GQHW+tcRZReQtFQV115cd+d5VDvITUacUc17b/PD4eQ IVk2LGez5RN3KwdwWLegmJKRCVU7nmKk33Q3VT9Tj5lbwEnMJfxwC3jfH4PQjP/ed3vV Tg6SS+iKCBrh2wZhJldnulU5V2xlKiqhBGfKKo/l2qSLC26hlRkNcwema4+XWYLFcU25 sBEQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from; bh=GJtZar2ICR0h4cjoNX37ZyCxM7L3qobK7USMnMF+q7c=; b=RZp7srBjbVIF/6RYh4a5Zd9EuZT8IJoZPhThs1pm/K8B2qWbHLASNySfchUMSIpAd+ CVnEZ65oCECN35WmEXW89Zi291cEyuJyVU6Yp4Afv9yv0Bs6m3DinPV4KAFIa3Aa7Xv8 xvTFkRQgXiVjNMhF1OdKx8qXc0qmdYHNY0pdg6zv064j78NCdpDRssFjt73wl2EEioOq YwZqoY5zIvMJ+k99v24hd23J+CL1KkERCuciIQDKpHekJxWA6C58/VTfJfVh83HR3vpv vK9QillnngD6YNoTbn1PPAmTkf5LvFqfixMZIY0ty2gc5A+bUL1SjtijEMN/i+F0k2LP FGZw== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bj2-20020a170902850200b001ae52127485si1128943plb.433.2023.05.27.09.54.26; Sat, 27 May 2023 09:54:43 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230050AbjE0Qpa (ORCPT + 99 others); Sat, 27 May 2023 12:45:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:55318 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229494AbjE0Qp0 (ORCPT ); Sat, 27 May 2023 12:45:26 -0400 Received: from relay7-d.mail.gandi.net (relay7-d.mail.gandi.net [217.70.183.200]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 47443D3; Sat, 27 May 2023 09:45:15 -0700 (PDT) X-GND-Sasl: contact@artur-rojek.eu X-GND-Sasl: contact@artur-rojek.eu X-GND-Sasl: contact@artur-rojek.eu X-GND-Sasl: contact@artur-rojek.eu X-GND-Sasl: contact@artur-rojek.eu X-GND-Sasl: contact@artur-rojek.eu X-GND-Sasl: contact@artur-rojek.eu X-GND-Sasl: contact@artur-rojek.eu Received: by mail.gandi.net (Postfix) with ESMTPSA id 9D16920004; Sat, 27 May 2023 16:45:12 +0000 (UTC) From: Artur Rojek To: Yoshinori Sato , Rich Felker , John Paul Adrian Glaubitz , Geert Uytterhoeven Cc: Rafael Ignacio Zurita , linux-sh@vger.kernel.org, linux-kernel@vger.kernel.org, Artur Rojek Subject: [PATCH v2 1/3] sh: dma: Fix dma channel offset calculation Date: Sat, 27 May 2023 18:44:50 +0200 Message-Id: <20230527164452.64797-2-contact@artur-rojek.eu> X-Mailer: git-send-email 2.40.1 In-Reply-To: <20230527164452.64797-1-contact@artur-rojek.eu> References: <20230527164452.64797-1-contact@artur-rojek.eu> MIME-Version: 1.0 X-Spam-Status: No, score=-2.6 required=5.0 tests=BAYES_00,NO_DNS_FOR_FROM, RCVD_IN_DNSWL_LOW,SPF_HELO_NONE,T_SCC_BODY_TEXT_LINE,T_SPF_TEMPERROR autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767067074072350394?= X-GMAIL-MSGID: =?utf-8?q?1767067074072350394?= Various SoCs of the SH3, SH4 and SH4A family, which use this driver, feature a differing number of DMA channels, which can be distributed between up to two DMAC modules. Existing implementation fails to correctly accommodate for all those variations, resulting in wrong channel offset calculations and leading to kernel panics. Rewrite dma_base_addr() in order to properly calculate channel offsets in a DMAC module. Fix dmaor_read_reg() and dmaor_write_reg(), so that the correct DMAC module base is selected for the DMAOR register. Fixes: 7f47c7189b3e8f19 ("sh: dma: More legacy cpu dma chainsawing.") Signed-off-by: Artur Rojek Reviewed-by: Geert Uytterhoeven Reviewed-by: John Paul Adrian Glaubitz --- v2: also handle differing numbers of DMAC modules and channels arch/sh/drivers/dma/dma-sh.c | 37 +++++++++++++++++++++++------------- 1 file changed, 24 insertions(+), 13 deletions(-) diff --git a/arch/sh/drivers/dma/dma-sh.c b/arch/sh/drivers/dma/dma-sh.c index 96c626c2cd0a..306fba1564e5 100644 --- a/arch/sh/drivers/dma/dma-sh.c +++ b/arch/sh/drivers/dma/dma-sh.c @@ -18,6 +18,18 @@ #include #include +/* + * Some of the SoCs feature two DMAC modules. In such a case, the channels are + * distributed equally among them. + */ +#ifdef SH_DMAC_BASE1 +#define SH_DMAC_NR_MD_CH (CONFIG_NR_ONCHIP_DMA_CHANNELS / 2) +#else +#define SH_DMAC_NR_MD_CH CONFIG_NR_ONCHIP_DMA_CHANNELS +#endif + +#define SH_DMAC_CH_SZ 0x10 + /* * Define the default configuration for dual address memory-memory transfer. * The 0x400 value represents auto-request, external->external. @@ -29,7 +41,7 @@ static unsigned long dma_find_base(unsigned int chan) unsigned long base = SH_DMAC_BASE0; #ifdef SH_DMAC_BASE1 - if (chan >= 6) + if (chan >= SH_DMAC_NR_MD_CH) base = SH_DMAC_BASE1; #endif @@ -40,13 +52,13 @@ static unsigned long dma_base_addr(unsigned int chan) { unsigned long base = dma_find_base(chan); - /* Normalize offset calculation */ - if (chan >= 9) - chan -= 6; - if (chan >= 4) - base += 0x10; + chan = (chan % SH_DMAC_NR_MD_CH) * SH_DMAC_CH_SZ; + + /* DMAOR is placed inside the channel register space. Step over it. */ + if (chan >= DMAOR) + base += SH_DMAC_CH_SZ; - return base + (chan * 0x10); + return base + chan; } #ifdef CONFIG_SH_DMA_IRQ_MULTI @@ -250,12 +262,11 @@ static int sh_dmac_get_dma_residue(struct dma_channel *chan) #define NR_DMAOR 1 #endif -/* - * DMAOR bases are broken out amongst channel groups. DMAOR0 manages - * channels 0 - 5, DMAOR1 6 - 11 (optional). - */ -#define dmaor_read_reg(n) __raw_readw(dma_find_base((n)*6)) -#define dmaor_write_reg(n, data) __raw_writew(data, dma_find_base(n)*6) +#define dmaor_read_reg(n) __raw_readw(dma_find_base((n) * \ + SH_DMAC_NR_MD_CH) + DMAOR) +#define dmaor_write_reg(n, data) __raw_writew(data, \ + dma_find_base((n) * \ + SH_DMAC_NR_MD_CH) + DMAOR) static inline int dmaor_reset(int no) {