Received: by 2002:a05:6358:3188:b0:123:57c1:9b43 with SMTP id q8csp1054954rwd; Sat, 27 May 2023 10:22:51 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5IipzztwCClNiY+pklY8H/xApxicGmQNHxH4De/yA5yIA5KU87DIFQvSx/iBJLSZyn2FiK X-Received: by 2002:a05:6a00:b8d:b0:64d:5cc5:fa67 with SMTP id g13-20020a056a000b8d00b0064d5cc5fa67mr9546093pfj.17.1685208171203; Sat, 27 May 2023 10:22:51 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685208171; cv=none; d=google.com; s=arc-20160816; b=W5XQyz/yUJUzQUyxSlXwVa1VScsVA+v8iPckUeIiwFMUigSiRX7m8eFBGasFCT+FlE FrgG/DxrJI4iDkCtVb63TDB7HlZMZfEiVDIDOlaBHrVB1VTpHASWfEecK1CRvYDT6y4K 21OUb/WF9EegOrdz5KiJl17XGx+tvTWDltuWiKlyFHRRHLou40M5w4Ee7NgTpDzr9mxS jFci9aNMtPKF2VrQtdCFwkwx0Php3qCQ3OQa89mqUPotwLF4eEcqALNJd8o6oaafWkVb chEBrTQZ17AEfBzg2RhKKj9c9TbYPQGz6pfPcTXwFr6ThvU3ScFmSguzRPEN84f6SuRe vwPw== 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 Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id e28-20020aa7981c000000b0063d24857c5bsi6710193pfl.43.2023.05.27.10.22.39; Sat, 27 May 2023 10:22:51 -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 S230044AbjE0Qp3 (ORCPT + 99 others); Sat, 27 May 2023 12:45:29 -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 Content-Transfer-Encoding: 8bit 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 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 --- 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) { -- 2.40.1