From patchwork Wed Apr 15 15:57:26 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Kerello X-Patchwork-Id: 201989 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10A40C2BB55 for ; Wed, 15 Apr 2020 15:59:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id D746C20857 for ; Wed, 15 Apr 2020 15:58:59 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=st.com header.i=@st.com header.b="GL/vZDAJ" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2404612AbgDOP64 (ORCPT ); Wed, 15 Apr 2020 11:58:56 -0400 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:27786 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1414848AbgDOP6x (ORCPT ); Wed, 15 Apr 2020 11:58:53 -0400 Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03FFbUoi021298; Wed, 15 Apr 2020 17:58:27 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=bdRXf3zdEShw9un2WH8w6BeS8Uh/zpwDR4mugvsjHJg=; b=GL/vZDAJPwYhCuPeqj8jqKJBH+DJSyDBb2EoIXVx4xrh49vVwB5TWRSS1Hovdg5lGjKP Py3D6RPcsOfNxS2l7RTmauW7JVSPyplA2kUemihZA0L6FwKAHHhzhuSMU/rTy7VGCIrh FDhptDV09hi6owpERAPx+DINNdlrw9fD8pCFvhkVl8N8tZKovX4CyROvHh0psww7z1mu uwRLPfYjlgUoxJ/BgenKSEi0+LVKiqd7OluQPoM8XpdGC1sdmz7TZhBKXoblzD39OwKz 8WwjF6FwjAwAevoH4ry7zJu+UCU7P+Vaxk78khPMqGk97beg6eisHHwoirlIyExM2wlK IA== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 30dn8rvww4-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 Apr 2020 17:58:27 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id AB415100038; Wed, 15 Apr 2020 17:58:26 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag6node2.st.com [10.75.127.17]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 96E942B213D; Wed, 15 Apr 2020 17:58:26 +0200 (CEST) Received: from localhost (10.75.127.49) by SFHDAG6NODE2.st.com (10.75.127.17) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Wed, 15 Apr 2020 17:58:24 +0200 From: Christophe Kerello To: , , , , , , CC: , , , , , Christophe Kerello Subject: [PATCH v2 02/12] mfd: stm32-fmc2: add STM32 FMC2 controller driver Date: Wed, 15 Apr 2020 17:57:26 +0200 Message-ID: <1586966256-29548-3-git-send-email-christophe.kerello@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> References: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.49] X-ClientProxiedBy: SFHDAG6NODE1.st.com (10.75.127.16) To SFHDAG6NODE2.st.com (10.75.127.17) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-04-15_05:2020-04-14,2020-04-15 signatures=0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The driver adds the support for the STMicroelectronics FMC2 controller found on STM32MP SOCs. The FMC2 functional block makes the interface with: synchronous and asynchronous static memories (such as PSNOR, PSRAM or other memory-mapped peripherals) and NAND flash memories. Signed-off-by: Christophe Kerello --- Changes in v2: - remove ops from stm32_fmc2 structure - add 2 APIs to manage FMC2 enable/disable - add 2 APIs to manage FMC2 NWAIT shared signal drivers/mfd/Kconfig | 12 +++ drivers/mfd/Makefile | 1 + drivers/mfd/stm32-fmc2.c | 136 +++++++++++++++++++++++++ include/linux/mfd/stm32-fmc2.h | 225 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 374 insertions(+) create mode 100644 drivers/mfd/stm32-fmc2.c create mode 100644 include/linux/mfd/stm32-fmc2.h diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 2b20329..5260582 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1922,6 +1922,18 @@ config MFD_ROHM_BD71828 Also included is a Coulomb counter, a real-time clock (RTC), and a 32.768 kHz clock gate. +config MFD_STM32_FMC2 + tristate "Support for FMC2 controllers on STM32MP SoCs" + depends on MACH_STM32MP157 || COMPILE_TEST + select MFD_CORE + select REGMAP + select REGMAP_MMIO + help + Select this option to enable STM32 FMC2 driver used for FMC2 External + Bus Interface controller and FMC2 NAND flash controller. This driver + provides core support for the STM32 FMC2 controllers, in order to use + the actual functionality of the device other drivers must be enabled. + config MFD_STM32_LPTIMER tristate "Support for STM32 Low-Power Timer" depends on (ARCH_STM32 && OF) || COMPILE_TEST diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index b83f172..880de3c 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -256,5 +256,6 @@ obj-$(CONFIG_MFD_ROHM_BD70528) += rohm-bd70528.o obj-$(CONFIG_MFD_ROHM_BD71828) += rohm-bd71828.o obj-$(CONFIG_MFD_ROHM_BD718XX) += rohm-bd718x7.o obj-$(CONFIG_MFD_STMFX) += stmfx.o +obj-$(CONFIG_MFD_STM32_FMC2) += stm32-fmc2.o obj-$(CONFIG_SGI_MFD_IOC3) += ioc3.o diff --git a/drivers/mfd/stm32-fmc2.c b/drivers/mfd/stm32-fmc2.c new file mode 100644 index 0000000..764c077 --- /dev/null +++ b/drivers/mfd/stm32-fmc2.c @@ -0,0 +1,136 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) STMicroelectronics 2020 + */ + +#include +#include +#include +#include +#include + +/* Regmap registers configuration */ +#define FMC2_MAX_REGISTER 0x3fc + +static const struct regmap_config stm32_fmc2_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = sizeof(u32), + .max_register = FMC2_MAX_REGISTER, +}; + +void stm32_fmc2_enable(struct stm32_fmc2 *fmc2) +{ + if (atomic_inc_return(&fmc2->nb_ctrl_used) == 1) + regmap_update_bits(fmc2->regmap, FMC2_BCR1, + FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN); +} +EXPORT_SYMBOL_GPL(stm32_fmc2_enable); + +void stm32_fmc2_disable(struct stm32_fmc2 *fmc2) +{ + if (atomic_dec_and_test(&fmc2->nb_ctrl_used)) + regmap_update_bits(fmc2->regmap, FMC2_BCR1, + FMC2_BCR1_FMC2EN, 0); +} +EXPORT_SYMBOL_GPL(stm32_fmc2_disable); + +bool stm32_fmc2_get_nwait(struct stm32_fmc2 *fmc2) +{ + if (atomic_inc_return(&fmc2->nwait_is_used) > 1) { + atomic_dec(&fmc2->nwait_is_used); + return false; + } + + return true; +} +EXPORT_SYMBOL_GPL(stm32_fmc2_get_nwait); + +void stm32_fmc2_put_nwait(struct stm32_fmc2 *fmc2) +{ + atomic_dec(&fmc2->nwait_is_used); +} +EXPORT_SYMBOL_GPL(stm32_fmc2_put_nwait); + +static int stm32_fmc2_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct reset_control *rstc; + struct stm32_fmc2 *fmc2; + struct resource *res; + void __iomem *mmio; + int ret; + + fmc2 = devm_kzalloc(dev, sizeof(*fmc2), GFP_KERNEL); + if (!fmc2) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + mmio = devm_ioremap_resource(dev, res); + if (IS_ERR(mmio)) + return PTR_ERR(mmio); + + fmc2->regmap = devm_regmap_init_mmio(dev, mmio, + &stm32_fmc2_regmap_cfg); + if (IS_ERR(fmc2->regmap)) + return PTR_ERR(fmc2->regmap); + + fmc2->reg_phys_addr = res->start; + + fmc2->clk = devm_clk_get(dev, NULL); + if (IS_ERR(fmc2->clk)) + return PTR_ERR(fmc2->clk); + + rstc = devm_reset_control_get(dev, NULL); + if (PTR_ERR(rstc) == -EPROBE_DEFER) + return -EPROBE_DEFER; + + ret = clk_prepare_enable(fmc2->clk); + if (ret) + return ret; + + if (!IS_ERR(rstc)) { + reset_control_assert(rstc); + reset_control_deassert(rstc); + } + + platform_set_drvdata(pdev, fmc2); + + clk_disable_unprepare(fmc2->clk); + + return devm_of_platform_populate(dev); +} + +static int __maybe_unused stm32_fmc2_suspend(struct device *dev) +{ + return pinctrl_pm_select_sleep_state(dev); +} + +static int __maybe_unused stm32_fmc2_resume(struct device *dev) +{ + return pinctrl_pm_select_default_state(dev); +} + +static SIMPLE_DEV_PM_OPS(stm32_fmc2_pm_ops, stm32_fmc2_suspend, + stm32_fmc2_resume); + +static const struct of_device_id stm32_fmc2_match[] = { + {.compatible = "st,stm32mp1-fmc2"}, + {} +}; +MODULE_DEVICE_TABLE(of, stm32_fmc2_match); + +static struct platform_driver stm32_fmc2_driver = { + .probe = stm32_fmc2_probe, + .driver = { + .name = "stm32_fmc2", + .of_match_table = stm32_fmc2_match, + .pm = &stm32_fmc2_pm_ops, + }, +}; +module_platform_driver(stm32_fmc2_driver); + +MODULE_ALIAS("platform:stm32_fmc2"); +MODULE_AUTHOR("Christophe Kerello "); +MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 driver"); +MODULE_LICENSE("GPL v2"); diff --git a/include/linux/mfd/stm32-fmc2.h b/include/linux/mfd/stm32-fmc2.h new file mode 100644 index 0000000..0e549f8 --- /dev/null +++ b/include/linux/mfd/stm32-fmc2.h @@ -0,0 +1,225 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * Copyright (C) STMicroelectronics 2020 + */ + +#ifndef _LINUX_STM32_FMC2_H_ +#define _LINUX_STM32_FMC2_H_ + +#include +#include +#include +#include + +/* FMC2 Controller Registers */ +#define FMC2_BCR1 0x0 +#define FMC2_BTR1 0x4 +#define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1) +#define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1) +#define FMC2_PCSCNTR 0x20 +#define FMC2_PCR 0x80 +#define FMC2_SR 0x84 +#define FMC2_PMEM 0x88 +#define FMC2_PATT 0x8c +#define FMC2_HECCR 0x94 +#define FMC2_BWTR1 0x104 +#define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1) +#define FMC2_ISR 0x184 +#define FMC2_ICR 0x188 +#define FMC2_CSQCR 0x200 +#define FMC2_CSQCFGR1 0x204 +#define FMC2_CSQCFGR2 0x208 +#define FMC2_CSQCFGR3 0x20c +#define FMC2_CSQAR1 0x210 +#define FMC2_CSQAR2 0x214 +#define FMC2_CSQIER 0x220 +#define FMC2_CSQISR 0x224 +#define FMC2_CSQICR 0x228 +#define FMC2_CSQEMSR 0x230 +#define FMC2_BCHIER 0x250 +#define FMC2_BCHISR 0x254 +#define FMC2_BCHICR 0x258 +#define FMC2_BCHPBR1 0x260 +#define FMC2_BCHPBR2 0x264 +#define FMC2_BCHPBR3 0x268 +#define FMC2_BCHPBR4 0x26c +#define FMC2_BCHDSR0 0x27c +#define FMC2_BCHDSR1 0x280 +#define FMC2_BCHDSR2 0x284 +#define FMC2_BCHDSR3 0x288 +#define FMC2_BCHDSR4 0x28c + +/* Register: FMC2_BCR1 */ +#define FMC2_BCR1_CCLKEN BIT(20) +#define FMC2_BCR1_FMC2EN BIT(31) + +/* Register: FMC2_BCRx */ +#define FMC2_BCR_MBKEN BIT(0) +#define FMC2_BCR_MUXEN BIT(1) +#define FMC2_BCR_MTYP GENMASK(3, 2) +#define FMC2_BCR_MWID GENMASK(5, 4) +#define FMC2_BCR_FACCEN BIT(6) +#define FMC2_BCR_BURSTEN BIT(8) +#define FMC2_BCR_WAITPOL BIT(9) +#define FMC2_BCR_WAITCFG BIT(11) +#define FMC2_BCR_WREN BIT(12) +#define FMC2_BCR_WAITEN BIT(13) +#define FMC2_BCR_EXTMOD BIT(14) +#define FMC2_BCR_ASYNCWAIT BIT(15) +#define FMC2_BCR_CPSIZE GENMASK(18, 16) +#define FMC2_BCR_CBURSTRW BIT(19) +#define FMC2_BCR_NBLSET GENMASK(23, 22) + +/* Register: FMC2_BTRx/FMC2_BWTRx */ +#define FMC2_BXTR_ADDSET GENMASK(3, 0) +#define FMC2_BXTR_ADDHLD GENMASK(7, 4) +#define FMC2_BXTR_DATAST GENMASK(15, 8) +#define FMC2_BXTR_BUSTURN GENMASK(19, 16) +#define FMC2_BTR_CLKDIV GENMASK(23, 20) +#define FMC2_BTR_DATLAT GENMASK(27, 24) +#define FMC2_BXTR_ACCMOD GENMASK(29, 28) +#define FMC2_BXTR_DATAHLD GENMASK(31, 30) + +/* Register: FMC2_PCSCNTR */ +#define FMC2_PCSCNTR_CSCOUNT GENMASK(15, 0) +#define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16) + +/* Register: FMC2_PCR */ +#define FMC2_PCR_PWAITEN BIT(1) +#define FMC2_PCR_PBKEN BIT(2) +#define FMC2_PCR_PWID GENMASK(5, 4) +#define FMC2_PCR_PWID_BUSWIDTH_8 0 +#define FMC2_PCR_PWID_BUSWIDTH_16 1 +#define FMC2_PCR_ECCEN BIT(6) +#define FMC2_PCR_ECCALG BIT(8) +#define FMC2_PCR_TCLR GENMASK(12, 9) +#define FMC2_PCR_TAR GENMASK(16, 13) +#define FMC2_PCR_ECCSS GENMASK(19, 17) +#define FMC2_PCR_ECCSS_512 1 +#define FMC2_PCR_ECCSS_2048 3 +#define FMC2_PCR_BCHECC BIT(24) +#define FMC2_PCR_WEN BIT(25) + +/* Register: FMC2_SR */ +#define FMC2_SR_NWRF BIT(6) + +/* Register: FMC2_PMEM */ +#define FMC2_PMEM_MEMSET GENMASK(7, 0) +#define FMC2_PMEM_MEMWAIT GENMASK(15, 8) +#define FMC2_PMEM_MEMHOLD GENMASK(23, 16) +#define FMC2_PMEM_MEMHIZ GENMASK(31, 24) + +/* Register: FMC2_PATT */ +#define FMC2_PATT_ATTSET GENMASK(7, 0) +#define FMC2_PATT_ATTWAIT GENMASK(15, 8) +#define FMC2_PATT_ATTHOLD GENMASK(23, 16) +#define FMC2_PATT_ATTHIZ GENMASK(31, 24) + +/* Register: FMC2_ISR */ +#define FMC2_ISR_IHLF BIT(1) + +/* Register: FMC2_ICR */ +#define FMC2_ICR_CIHLF BIT(1) + +/* Register: FMC2_CSQCR */ +#define FMC2_CSQCR_CSQSTART BIT(0) + +/* Register: FMC2_CSQCFGR1 */ +#define FMC2_CSQCFGR1_CMD2EN BIT(1) +#define FMC2_CSQCFGR1_DMADEN BIT(2) +#define FMC2_CSQCFGR1_ACYNBR GENMASK(6, 4) +#define FMC2_CSQCFGR1_CMD1 GENMASK(15, 8) +#define FMC2_CSQCFGR1_CMD2 GENMASK(23, 16) +#define FMC2_CSQCFGR1_CMD1T BIT(24) +#define FMC2_CSQCFGR1_CMD2T BIT(25) + +/* Register: FMC2_CSQCFGR2 */ +#define FMC2_CSQCFGR2_SQSDTEN BIT(0) +#define FMC2_CSQCFGR2_RCMD2EN BIT(1) +#define FMC2_CSQCFGR2_DMASEN BIT(2) +#define FMC2_CSQCFGR2_RCMD1 GENMASK(15, 8) +#define FMC2_CSQCFGR2_RCMD2 GENMASK(23, 16) +#define FMC2_CSQCFGR2_RCMD1T BIT(24) +#define FMC2_CSQCFGR2_RCMD2T BIT(25) + +/* Register: FMC2_CSQCFGR3 */ +#define FMC2_CSQCFGR3_SNBR GENMASK(13, 8) +#define FMC2_CSQCFGR3_AC1T BIT(16) +#define FMC2_CSQCFGR3_AC2T BIT(17) +#define FMC2_CSQCFGR3_AC3T BIT(18) +#define FMC2_CSQCFGR3_AC4T BIT(19) +#define FMC2_CSQCFGR3_AC5T BIT(20) +#define FMC2_CSQCFGR3_SDT BIT(21) +#define FMC2_CSQCFGR3_RAC1T BIT(22) +#define FMC2_CSQCFGR3_RAC2T BIT(23) + +/* Register: FMC2_CSQCAR1 */ +#define FMC2_CSQCAR1_ADDC1 GENMASK(7, 0) +#define FMC2_CSQCAR1_ADDC2 GENMASK(15, 8) +#define FMC2_CSQCAR1_ADDC3 GENMASK(23, 16) +#define FMC2_CSQCAR1_ADDC4 GENMASK(31, 24) + +/* Register: FMC2_CSQCAR2 */ +#define FMC2_CSQCAR2_ADDC5 GENMASK(7, 0) +#define FMC2_CSQCAR2_NANDCEN GENMASK(11, 10) +#define FMC2_CSQCAR2_SAO GENMASK(31, 16) + +/* Register: FMC2_CSQIER */ +#define FMC2_CSQIER_TCIE BIT(0) + +/* Register: FMC2_CSQICR */ +#define FMC2_CSQICR_CLEAR_IRQ GENMASK(4, 0) + +/* Register: FMC2_CSQEMSR */ +#define FMC2_CSQEMSR_SEM GENMASK(15, 0) + +/* Register: FMC2_BCHIER */ +#define FMC2_BCHIER_DERIE BIT(1) +#define FMC2_BCHIER_EPBRIE BIT(4) + +/* Register: FMC2_BCHICR */ +#define FMC2_BCHICR_CLEAR_IRQ GENMASK(4, 0) + +/* Register: FMC2_BCHDSR0 */ +#define FMC2_BCHDSR0_DUE BIT(0) +#define FMC2_BCHDSR0_DEF BIT(1) +#define FMC2_BCHDSR0_DEN GENMASK(7, 4) + +/* Register: FMC2_BCHDSR1 */ +#define FMC2_BCHDSR1_EBP1 GENMASK(12, 0) +#define FMC2_BCHDSR1_EBP2 GENMASK(28, 16) + +/* Register: FMC2_BCHDSR2 */ +#define FMC2_BCHDSR2_EBP3 GENMASK(12, 0) +#define FMC2_BCHDSR2_EBP4 GENMASK(28, 16) + +/* Register: FMC2_BCHDSR3 */ +#define FMC2_BCHDSR3_EBP5 GENMASK(12, 0) +#define FMC2_BCHDSR3_EBP6 GENMASK(28, 16) + +/* Register: FMC2_BCHDSR4 */ +#define FMC2_BCHDSR4_EBP7 GENMASK(12, 0) +#define FMC2_BCHDSR4_EBP8 GENMASK(28, 16) + +/* + * struct stm32_fmc2 - STM32 FMC2 data assigned by parent device + * @clk: clock reference for this instance + * @regmap: register map reference for this instance + * @reg_phys_addr: physical address of the register map + * @nb_ctrl_used: number of used controller + * @nwait_is_used: NWAIT signal in used by a controller + */ +struct stm32_fmc2 { + struct clk *clk; + struct regmap *regmap; + phys_addr_t reg_phys_addr; + atomic_t nb_ctrl_used; + atomic_t nwait_is_used; +}; + +void stm32_fmc2_enable(struct stm32_fmc2 *fmc2); +void stm32_fmc2_disable(struct stm32_fmc2 *fmc2); +bool stm32_fmc2_get_nwait(struct stm32_fmc2 *fmc2); +void stm32_fmc2_put_nwait(struct stm32_fmc2 *fmc2); + +#endif From patchwork Wed Apr 15 15:57:27 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Kerello X-Patchwork-Id: 201984 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, USER_AGENT_GIT autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id A925EC2BA19 for ; Wed, 15 Apr 2020 16:00:21 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 709BF206F9 for ; Wed, 15 Apr 2020 16:00:21 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=st.com header.i=@st.com header.b="ebKO/pfU" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1415036AbgDOP7X (ORCPT ); Wed, 15 Apr 2020 11:59:23 -0400 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:17538 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2410043AbgDOP7F (ORCPT ); Wed, 15 Apr 2020 11:59:05 -0400 Received: from pps.filterd (m0046668.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03FFX7Dh020617; Wed, 15 Apr 2020 17:58:36 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=EwHTI1j3wU7XXWavG0RvpMfKA+ZP+AaGxMqpL9GvqDw=; b=ebKO/pfUSWpBIdQTvds7VYrDqF044zQ37eQRso6xH44moqrWgKAPnMHl+sf1qbL7Mfyb uW1S35NWV2RAB5IEQ7XchtoJ9KkrSoccxsKVQTNFvgzmB9MOjXGhU0t4xMPF+lSSLkOA YV7CpZzyQLC4FtYo8k68L/sb362/th2z4IOaS2WSCe6DWN7MGfHclT8peVJRREj+l5mW VfSzENlPEjzk0Z15Y6AAGjZuQMDlkrYTS3RrNVYV+wBHdVAALyW0tLvW6jitJeQJv3fI nzdnlSO4ChHinlztJKsjGtDrMQV6wjOAZJl3ZlszrUTgKg85Qpc0e88WM8Sz3AFD3gNR vQ== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 30dn6svygd-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 Apr 2020 17:58:36 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 611C0100038; Wed, 15 Apr 2020 17:58:36 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag6node2.st.com [10.75.127.17]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 4F1202AF583; Wed, 15 Apr 2020 17:58:36 +0200 (CEST) Received: from localhost (10.75.127.50) by SFHDAG6NODE2.st.com (10.75.127.17) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Wed, 15 Apr 2020 17:58:29 +0200 From: Christophe Kerello To: , , , , , , CC: , , , , , Christophe Kerello Subject: [PATCH v2 03/12] bus: stm32-fmc2-ebi: add STM32 FMC2 EBI controller driver Date: Wed, 15 Apr 2020 17:57:27 +0200 Message-ID: <1586966256-29548-4-git-send-email-christophe.kerello@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> References: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.50] X-ClientProxiedBy: SFHDAG2NODE1.st.com (10.75.127.4) To SFHDAG6NODE2.st.com (10.75.127.17) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-04-15_05:2020-04-14,2020-04-15 signatures=0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org The driver adds the support for the STMicroelectronics FMC2 EBI controller found on STM32MP SOCs. Signed-off-by: Christophe Kerello Tested-by: Marek Vasut --- Changes in v2: - call 2 APIs to manage FMC2 enable/disable instead of ops - call 2 APIs to manage FMC2 NWAIT shared signal instead of ops drivers/bus/Kconfig | 11 + drivers/bus/Makefile | 1 + drivers/bus/stm32-fmc2-ebi.c | 1091 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 1103 insertions(+) create mode 100644 drivers/bus/stm32-fmc2-ebi.c diff --git a/drivers/bus/Kconfig b/drivers/bus/Kconfig index 6095b6d..367f015 100644 --- a/drivers/bus/Kconfig +++ b/drivers/bus/Kconfig @@ -200,6 +200,17 @@ config DA8XX_MSTPRI configuration. Allows to adjust the priorities of all master peripherals. +config STM32_FMC2_EBI + tristate "Support for FMC2 External Bus Interface on STM32MP SoCs" + depends on MACH_STM32MP157 || COMPILE_TEST + select REGMAP + select MFD_STM32_FMC2 + help + Select this option to enable the STM32 FMC2 External Bus Interface + controller. This driver configures the transactions with external + devices (like SRAM, ethernet adapters, FPGAs, LCD displays, ...) on + SOCs containing the FMC2 External Bus Interface. + source "drivers/bus/fsl-mc/Kconfig" endmenu diff --git a/drivers/bus/Makefile b/drivers/bus/Makefile index 1320bcf..e2d7992 100644 --- a/drivers/bus/Makefile +++ b/drivers/bus/Makefile @@ -25,6 +25,7 @@ obj-$(CONFIG_QCOM_EBI2) += qcom-ebi2.o obj-$(CONFIG_SUN50I_DE2_BUS) += sun50i-de2.o obj-$(CONFIG_SUNXI_RSB) += sunxi-rsb.o obj-$(CONFIG_SIMPLE_PM_BUS) += simple-pm-bus.o +obj-$(CONFIG_STM32_FMC2_EBI) += stm32-fmc2-ebi.o obj-$(CONFIG_TEGRA_ACONNECT) += tegra-aconnect.o obj-$(CONFIG_TEGRA_GMI) += tegra-gmi.o obj-$(CONFIG_TI_PWMSS) += ti-pwmss.o diff --git a/drivers/bus/stm32-fmc2-ebi.c b/drivers/bus/stm32-fmc2-ebi.c new file mode 100644 index 0000000..0ec327c --- /dev/null +++ b/drivers/bus/stm32-fmc2-ebi.c @@ -0,0 +1,1091 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) STMicroelectronics 2020 + */ + +#include +#include +#include + +#define FMC2_MAX_EBI_CE 4 + +#define FMC2_BCR_CPSIZE_0 0x0 +#define FMC2_BCR_CPSIZE_128 0x1 +#define FMC2_BCR_CPSIZE_256 0x2 +#define FMC2_BCR_CPSIZE_512 0x3 +#define FMC2_BCR_CPSIZE_1024 0x4 + +#define FMC2_BCR_MWID_8 0x0 +#define FMC2_BCR_MWID_16 0x1 + +#define FMC2_BCR_MTYP_SRAM 0x0 +#define FMC2_BCR_MTYP_PSRAM 0x1 +#define FMC2_BCR_MTYP_NOR 0x2 + +#define FMC2_BXTR_EXTMOD_A 0x0 +#define FMC2_BXTR_EXTMOD_B 0x1 +#define FMC2_BXTR_EXTMOD_C 0x2 +#define FMC2_BXTR_EXTMOD_D 0x3 + +#define FMC2_BCR_NBLSET_MAX 0x3 +#define FMC2_BXTR_ADDSET_MAX 0xf +#define FMC2_BXTR_ADDHLD_MAX 0xf +#define FMC2_BXTR_DATAST_MAX 0xff +#define FMC2_BXTR_BUSTURN_MAX 0xf +#define FMC2_BXTR_DATAHLD_MAX 0x3 +#define FMC2_BTR_CLKDIV_MAX 0xf +#define FMC2_BTR_DATLAT_MAX 0xf +#define FMC2_PCSCNTR_CSCOUNT_MAX 0xff + +enum stm32_fmc2_ebi_register_type { + FMC2_REG_BCR = 1, + FMC2_REG_BTR, + FMC2_REG_BWTR, + FMC2_REG_PCSCNTR +}; + +enum stm32_fmc2_ebi_transaction_type { + FMC2_ASYNC_MODE_1_SRAM = 0, + FMC2_ASYNC_MODE_1_PSRAM, + FMC2_ASYNC_MODE_A_SRAM, + FMC2_ASYNC_MODE_A_PSRAM, + FMC2_ASYNC_MODE_2_NOR, + FMC2_ASYNC_MODE_B_NOR, + FMC2_ASYNC_MODE_C_NOR, + FMC2_ASYNC_MODE_D_NOR, + FMC2_SYNC_READ_SYNC_WRITE_PSRAM, + FMC2_SYNC_READ_ASYNC_WRITE_PSRAM, + FMC2_SYNC_READ_SYNC_WRITE_NOR, + FMC2_SYNC_READ_ASYNC_WRITE_NOR +}; + +enum stm32_fmc2_ebi_buswidth { + FMC2_BUSWIDTH_8 = 8, + FMC2_BUSWIDTH_16 = 16 +}; + +enum stm32_fmc2_ebi_cpsize { + FMC2_CPSIZE_0 = 0, + FMC2_CPSIZE_128 = 128, + FMC2_CPSIZE_256 = 256, + FMC2_CPSIZE_512 = 512, + FMC2_CPSIZE_1024 = 1024 +}; + +struct stm32_fmc2_ebi { + u32 bcr[FMC2_MAX_EBI_CE]; + u32 btr[FMC2_MAX_EBI_CE]; + u32 bwtr[FMC2_MAX_EBI_CE]; + u32 pcscntr; + u8 cs_assigned; +}; + +/* + * struct stm32_fmc2_prop - STM32 FMC2 EBI property + * @name: the device tree binding name of the property + * @bprop: indicate that it is a boolean property + * @mprop: indicate that it is a mandatory property + * @reg_type: the register that have to be modified + * @reg_mask: the bit that have to be modified in the selected register + * in case of it is a boolean property + * @reset_val: the default value that have to be set in case the property + * has not been defined in the device tree + * @check: this callback ckecks that the property is compliant with the + * transaction type selected + * @calculate: this callback is called to calculate for exemple a timing + * set in ns in the device tree in clock cycles + * @set: this callback applies the values in the registers + */ +struct stm32_fmc2_prop { + const char *name; + bool bprop; + bool mprop; + int reg_type; + u32 reg_mask; + u32 reset_val; + int (*check)(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, int cs); + u32 (*calculate)(struct stm32_fmc2 *fmc2, u32 setup); + int (*set)(struct stm32_fmc2 *fmc2, const struct stm32_fmc2_prop *prop, + int cs, u32 setup); +}; + +static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr; + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + + if (bcr & FMC2_BCR_MTYP) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_waitcfg(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + + if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_sync_trans(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr; + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + + if (bcr & FMC2_BCR_BURSTEN) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr; + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + + if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_cpsize(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr, val = FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + + if ((bcr & FMC2_BCR_MTYP) == val && bcr & FMC2_BCR_BURSTEN) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_address_hold(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr, bxtr, val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + if (prop->reg_type == FMC2_REG_BWTR) + regmap_read(fmc2->regmap, FMC2_BWTR(cs), &bxtr); + else + regmap_read(fmc2->regmap, FMC2_BTR(cs), &bxtr); + + if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) && + ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN)) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_clk_period(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 bcr, bcr1; + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + if (cs) + regmap_read(fmc2->regmap, FMC2_BCR(0), &bcr1); + else + bcr1 = bcr; + + if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN))) + return 0; + + return -EINVAL; +} + +static int stm32_fmc2_ebi_check_cclk(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs) +{ + if (cs) + return -EINVAL; + + return stm32_fmc2_ebi_check_sync_trans(fmc2, prop, cs); +} + +static u32 stm32_fmc2_ebi_timing_ns_to_clock_cycles(struct stm32_fmc2 *fmc2, + u32 setup) +{ + unsigned long hclk = clk_get_rate(fmc2->clk); + unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000); + + return DIV_ROUND_UP(setup * 1000, hclkp); +} + +static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg) +{ + switch (reg_type) { + case FMC2_REG_BCR: + *reg = FMC2_BCR(cs); + break; + case FMC2_REG_BTR: + *reg = FMC2_BTR(cs); + break; + case FMC2_REG_BWTR: + *reg = FMC2_BWTR(cs); + break; + case FMC2_REG_PCSCNTR: + *reg = FMC2_PCSCNTR; + break; + default: + return -EINVAL; + } + + return 0; +} + +static int stm32_fmc2_ebi_set_bit_field(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + regmap_update_bits(fmc2->regmap, reg, prop->reg_mask, + setup ? prop->reg_mask : 0); + + return 0; +} + +static int stm32_fmc2_ebi_set_trans_type(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 bcr_mask, bcr = FMC2_BCR_WREN; + u32 btr_mask, btr = 0; + u32 bwtr_mask, bwtr = 0; + + bwtr_mask = FMC2_BXTR_ACCMOD; + btr_mask = FMC2_BXTR_ACCMOD; + bcr_mask = FMC2_BCR_MUXEN | FMC2_BCR_MTYP | FMC2_BCR_FACCEN | + FMC2_BCR_WREN | FMC2_BCR_WAITEN | FMC2_BCR_BURSTEN | + FMC2_BCR_EXTMOD | FMC2_BCR_CBURSTRW; + + switch (setup) { + case FMC2_ASYNC_MODE_1_SRAM: + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM); + /* + * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + break; + case FMC2_ASYNC_MODE_1_PSRAM: + /* + * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + break; + case FMC2_ASYNC_MODE_A_SRAM: + /* + * MUXEN = 0, MTYP = 0, FACCEN = 0, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_SRAM); + bcr |= FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A); + break; + case FMC2_ASYNC_MODE_A_PSRAM: + /* + * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + bcr |= FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_A); + break; + case FMC2_ASYNC_MODE_2_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN; + break; + case FMC2_ASYNC_MODE_B_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 1 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_B); + break; + case FMC2_ASYNC_MODE_C_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 2 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_C); + break; + case FMC2_ASYNC_MODE_D_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 0, WAITEN = 0, + * WREN = 1, EXTMOD = 1, CBURSTRW = 0, ACCMOD = 3 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_EXTMOD; + btr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + bwtr |= FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + break; + case FMC2_SYNC_READ_SYNC_WRITE_PSRAM: + /* + * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + bcr |= FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW; + break; + case FMC2_SYNC_READ_ASYNC_WRITE_PSRAM: + /* + * MUXEN = 0, MTYP = 1, FACCEN = 0, BURSTEN = 1, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + bcr |= FMC2_BCR_BURSTEN; + break; + case FMC2_SYNC_READ_SYNC_WRITE_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 1, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN | FMC2_BCR_CBURSTRW; + break; + case FMC2_SYNC_READ_ASYNC_WRITE_NOR: + /* + * MUXEN = 0, MTYP = 2, FACCEN = 1, BURSTEN = 1, WAITEN = 0, + * WREN = 1, EXTMOD = 0, CBURSTRW = 0, ACCMOD = 0 + */ + bcr |= FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + bcr |= FMC2_BCR_FACCEN | FMC2_BCR_BURSTEN; + break; + default: + /* Type of transaction not supported */ + return -EINVAL; + } + + if (bcr & FMC2_BCR_EXTMOD) + regmap_update_bits(fmc2->regmap, FMC2_BWTR(cs), + bwtr_mask, bwtr); + regmap_update_bits(fmc2->regmap, FMC2_BTR(cs), btr_mask, btr); + regmap_update_bits(fmc2->regmap, FMC2_BCR(cs), bcr_mask, bcr); + + return 0; +} + +static int stm32_fmc2_ebi_set_buswidth(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + switch (setup) { + case FMC2_BUSWIDTH_8: + val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_8); + break; + case FMC2_BUSWIDTH_16: + val = FIELD_PREP(FMC2_BCR_MWID, FMC2_BCR_MWID_16); + break; + default: + /* Buswidth not supported */ + return -EINVAL; + } + + regmap_update_bits(fmc2->regmap, FMC2_BCR(cs), FMC2_BCR_MWID, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_cpsize(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + switch (setup) { + case FMC2_CPSIZE_0: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_0); + break; + case FMC2_CPSIZE_128: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_128); + break; + case FMC2_CPSIZE_256: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_256); + break; + case FMC2_CPSIZE_512: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_512); + break; + case FMC2_CPSIZE_1024: + val = FIELD_PREP(FMC2_BCR_CPSIZE, FMC2_BCR_CPSIZE_1024); + break; + default: + /* Cpsize not supported */ + return -EINVAL; + } + + regmap_update_bits(fmc2->regmap, FMC2_BCR(cs), FMC2_BCR_CPSIZE, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_bl_setup(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + val = min_t(u32, setup, FMC2_BCR_NBLSET_MAX); + val = FIELD_PREP(FMC2_BCR_NBLSET, val); + regmap_update_bits(fmc2->regmap, FMC2_BCR(cs), FMC2_BCR_NBLSET, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_address_setup(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 bcr, bxtr, reg; + u32 val = FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + if (prop->reg_type == FMC2_REG_BWTR) + regmap_read(fmc2->regmap, FMC2_BWTR(cs), &bxtr); + else + regmap_read(fmc2->regmap, FMC2_BTR(cs), &bxtr); + + if ((bxtr & FMC2_BXTR_ACCMOD) == val || bcr & FMC2_BCR_MUXEN) + val = clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX); + else + val = min_t(u32, setup, FMC2_BXTR_ADDSET_MAX); + val = FIELD_PREP(FMC2_BXTR_ADDSET, val); + regmap_update_bits(fmc2->regmap, reg, FMC2_BXTR_ADDSET, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_address_hold(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + val = clamp_val(setup, 1, FMC2_BXTR_ADDHLD_MAX); + val = FIELD_PREP(FMC2_BXTR_ADDHLD, val); + regmap_update_bits(fmc2->regmap, reg, FMC2_BXTR_ADDHLD, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_data_setup(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + val = clamp_val(setup, 1, FMC2_BXTR_DATAST_MAX); + val = FIELD_PREP(FMC2_BXTR_DATAST, val); + regmap_update_bits(fmc2->regmap, reg, FMC2_BXTR_DATAST, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_bus_turnaround(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + val = setup ? min_t(u32, setup - 1, FMC2_BXTR_BUSTURN_MAX) : 0; + val = FIELD_PREP(FMC2_BXTR_BUSTURN, val); + regmap_update_bits(fmc2->regmap, reg, FMC2_BXTR_BUSTURN, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_data_hold(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, reg; + int ret; + + ret = stm32_fmc2_ebi_get_reg(prop->reg_type, cs, ®); + if (ret) + return ret; + + if (prop->reg_type == FMC2_REG_BWTR) + val = setup ? min_t(u32, setup - 1, FMC2_BXTR_DATAHLD_MAX) : 0; + else + val = min_t(u32, setup, FMC2_BXTR_DATAHLD_MAX); + val = FIELD_PREP(FMC2_BXTR_DATAHLD, val); + regmap_update_bits(fmc2->regmap, reg, FMC2_BXTR_DATAHLD, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_clk_period(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + val = setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1; + val = FIELD_PREP(FMC2_BTR_CLKDIV, val); + regmap_update_bits(fmc2->regmap, FMC2_BTR(cs), FMC2_BTR_CLKDIV, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + val = min_t(u32, setup, FMC2_BTR_DATLAT_MAX); + val = FIELD_PREP(FMC2_BTR_DATLAT, val); + regmap_update_bits(fmc2->regmap, FMC2_BTR(cs), FMC2_BTR_DATLAT, val); + + return 0; +} + +static int stm32_fmc2_ebi_set_max_low_pulse(struct stm32_fmc2 *fmc2, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 old_val, new_val, pcscntr; + + if (setup < 1) + return 0; + + regmap_read(fmc2->regmap, FMC2_PCSCNTR, &pcscntr); + + /* Enable counter for the bank */ + regmap_update_bits(fmc2->regmap, FMC2_PCSCNTR, + FMC2_PCSCNTR_CNTBEN(cs), + FMC2_PCSCNTR_CNTBEN(cs)); + + new_val = min_t(u32, setup - 1, FMC2_PCSCNTR_CSCOUNT_MAX); + old_val = FIELD_GET(FMC2_PCSCNTR_CSCOUNT, pcscntr); + if (old_val && new_val > old_val) + /* Keep current counter value */ + return 0; + + new_val = FIELD_PREP(FMC2_PCSCNTR_CSCOUNT, new_val); + regmap_update_bits(fmc2->regmap, FMC2_PCSCNTR, + FMC2_PCSCNTR_CSCOUNT, new_val); + + return 0; +} + +static const struct stm32_fmc2_prop stm32_fmc2_child_props[] = { + /* st,fmc2_ebi_cs_trans_type must be the first property */ + { + .name = "st,fmc2_ebi_cs_transaction_type", + .mprop = true, + .set = stm32_fmc2_ebi_set_trans_type, + }, + { + .name = "st,fmc2_ebi_cs_cclk_enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR1_CCLKEN, + .check = stm32_fmc2_ebi_check_cclk, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2_ebi_cs_mux_enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_MUXEN, + .check = stm32_fmc2_ebi_check_mux, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2_ebi_cs_buswidth", + .reset_val = FMC2_BUSWIDTH_16, + .set = stm32_fmc2_ebi_set_buswidth, + }, + { + .name = "st,fmc2_ebi_cs_waitpol_high", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_WAITPOL, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2_ebi_cs_waitcfg_enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_WAITCFG, + .check = stm32_fmc2_ebi_check_waitcfg, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2_ebi_cs_wait_enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_WAITEN, + .check = stm32_fmc2_ebi_check_sync_trans, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2_ebi_cs_asyncwait_enable", + .bprop = true, + .reg_type = FMC2_REG_BCR, + .reg_mask = FMC2_BCR_ASYNCWAIT, + .check = stm32_fmc2_ebi_check_async_trans, + .set = stm32_fmc2_ebi_set_bit_field, + }, + { + .name = "st,fmc2_ebi_cs_cpsize", + .check = stm32_fmc2_ebi_check_cpsize, + .set = stm32_fmc2_ebi_set_cpsize, + }, + { + .name = "st,fmc2_ebi_cs_byte_lane_setup", + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_bl_setup, + }, + { + .name = "st,fmc2_ebi_cs_address_setup", + .reg_type = FMC2_REG_BTR, + .reset_val = FMC2_BXTR_ADDSET_MAX, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_address_setup, + }, + { + .name = "st,fmc2_ebi_cs_address_hold", + .reg_type = FMC2_REG_BTR, + .reset_val = FMC2_BXTR_ADDHLD_MAX, + .check = stm32_fmc2_ebi_check_address_hold, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_address_hold, + }, + { + .name = "st,fmc2_ebi_cs_data_setup", + .reg_type = FMC2_REG_BTR, + .reset_val = FMC2_BXTR_DATAST_MAX, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_data_setup, + }, + { + .name = "st,fmc2_ebi_cs_bus_turnaround", + .reg_type = FMC2_REG_BTR, + .reset_val = FMC2_BXTR_BUSTURN_MAX + 1, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_bus_turnaround, + }, + { + .name = "st,fmc2_ebi_cs_data_hold", + .reg_type = FMC2_REG_BTR, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_data_hold, + }, + { + .name = "st,fmc2_ebi_cs_clk_period", + .reset_val = FMC2_BTR_CLKDIV_MAX + 1, + .check = stm32_fmc2_ebi_check_clk_period, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_clk_period, + }, + { + .name = "st,fmc2_ebi_cs_data_latency", + .check = stm32_fmc2_ebi_check_sync_trans, + .set = stm32_fmc2_ebi_set_data_latency, + }, + { + .name = "st,fmc2_ebi_cs_write_address_setup", + .reg_type = FMC2_REG_BWTR, + .reset_val = FMC2_BXTR_ADDSET_MAX, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_address_setup, + }, + { + .name = "st,fmc2_ebi_cs_write_address_hold", + .reg_type = FMC2_REG_BWTR, + .reset_val = FMC2_BXTR_ADDHLD_MAX, + .check = stm32_fmc2_ebi_check_address_hold, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_address_hold, + }, + { + .name = "st,fmc2_ebi_cs_write_data_setup", + .reg_type = FMC2_REG_BWTR, + .reset_val = FMC2_BXTR_DATAST_MAX, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_data_setup, + }, + { + .name = "st,fmc2_ebi_cs_write_bus_turnaround", + .reg_type = FMC2_REG_BWTR, + .reset_val = FMC2_BXTR_BUSTURN_MAX + 1, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_bus_turnaround, + }, + { + .name = "st,fmc2_ebi_cs_write_data_hold", + .reg_type = FMC2_REG_BWTR, + .check = stm32_fmc2_ebi_check_async_trans, + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_data_hold, + }, + { + .name = "st,fmc2_ebi_cs_max_low_pulse", + .calculate = stm32_fmc2_ebi_timing_ns_to_clock_cycles, + .set = stm32_fmc2_ebi_set_max_low_pulse, + }, +}; + +static void stm32_fmc2_ebi_set_bank(struct stm32_fmc2 *fmc2, + int cs, bool enable) +{ + regmap_update_bits(fmc2->regmap, FMC2_BCR(cs), FMC2_BCR_MBKEN, + enable ? FMC2_BCR_MBKEN : 0); +} + +static int stm32_fmc2_ebi_parse_prop(struct device *dev, + struct device_node *dev_node, + const struct stm32_fmc2_prop *prop, + int cs) +{ + struct stm32_fmc2 *fmc2 = dev_get_drvdata(dev->parent); + u32 setup = 0; + + if (!prop->set) { + dev_err(dev, "property %s is not well defined\n", prop->name); + return -EINVAL; + } + + if (prop->check && prop->check(fmc2, prop, cs)) + /* Skeep this property */ + return 0; + + if (prop->bprop) { + const __be32 *bprop = of_get_property(dev_node, + prop->name, NULL); + + if (prop->mprop && !bprop) { + dev_err(dev, "mandatory property %s not defined in the device tree\n", + prop->name); + return -EINVAL; + } + + if (bprop) + setup = 1; + } else { + u32 val; + int ret; + + ret = of_property_read_u32(dev_node, prop->name, &val); + if (prop->mprop && ret) { + dev_err(dev, "mandatory property %s not defined in the device tree\n", + prop->name); + return ret; + } + + if (ret) + setup = prop->reset_val; + else if (prop->calculate) + setup = prop->calculate(fmc2, val); + else + setup = val; + } + + return prop->set(fmc2, prop, cs, setup); +} + +static int stm32_fmc2_ebi_setup_cs(struct device *dev, + struct device_node *dev_node, + u32 cs) +{ + struct stm32_fmc2 *fmc2 = dev_get_drvdata(dev->parent); + unsigned int i; + int ret; + + /* Disable the bank */ + stm32_fmc2_ebi_set_bank(fmc2, cs, false); + + for (i = 0; i < ARRAY_SIZE(stm32_fmc2_child_props); i++) { + const struct stm32_fmc2_prop *p = &stm32_fmc2_child_props[i]; + + ret = stm32_fmc2_ebi_parse_prop(dev, dev_node, p, cs); + if (ret) { + dev_err(dev, "property %s could not be set: %d\n", + p->name, ret); + return ret; + } + } + + /* Enable the bank */ + stm32_fmc2_ebi_set_bank(fmc2, cs, true); + + return 0; +} + +static int stm32_fmc2_ebi_parse_dt(struct device *dev, + struct stm32_fmc2_ebi *ebi) +{ + struct device_node *child; + bool child_found = false; + u32 cs; + int ret; + + for_each_available_child_of_node(dev->of_node, child) { + ret = of_property_read_u32(child, "reg", &cs); + if (ret) { + dev_err(dev, "could not retrieve reg property: %d\n", + ret); + return ret; + } + + if (cs > FMC2_MAX_EBI_CE) { + dev_err(dev, "invalid reg value: %d\n", cs); + return -EINVAL; + } + + if (ebi->cs_assigned & BIT(cs)) { + dev_err(dev, "cs already assigned: %d\n", cs); + return -EINVAL; + } + + ret = stm32_fmc2_ebi_setup_cs(dev, child, cs); + if (ret) { + dev_err(dev, "setup chip select %d failed: %d\n", + cs, ret); + return ret; + } + + ebi->cs_assigned |= BIT(cs); + child_found = true; + } + + if (!child_found) { + dev_warn(dev, "no subnodes found, disable the driver.\n"); + return -ENODEV; + } + + return of_platform_default_populate(dev->of_node, NULL, dev); +} + +static void stm32_fmc2_ebi_save_setup(struct stm32_fmc2 *fmc2, + struct stm32_fmc2_ebi *ebi) +{ + unsigned int cs; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + regmap_read(fmc2->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); + regmap_read(fmc2->regmap, FMC2_BTR(cs), &ebi->btr[cs]); + regmap_read(fmc2->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); + } + + regmap_read(fmc2->regmap, FMC2_PCSCNTR, &ebi->pcscntr); +} + +static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2 *fmc2, + struct stm32_fmc2_ebi *ebi) +{ + unsigned int cs; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + regmap_write(fmc2->regmap, FMC2_BCR(cs), ebi->bcr[cs]); + regmap_write(fmc2->regmap, FMC2_BTR(cs), ebi->btr[cs]); + regmap_write(fmc2->regmap, FMC2_BWTR(cs), ebi->bwtr[cs]); + } + + regmap_write(fmc2->regmap, FMC2_PCSCNTR, ebi->pcscntr); +} + +static bool stm32_fmc2_ebi_check_nwait_is_used(struct stm32_fmc2 *fmc2, + struct stm32_fmc2_ebi *ebi) +{ + unsigned int cs; + u32 bcr; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + if (!(ebi->cs_assigned & BIT(cs))) + continue; + + regmap_read(fmc2->regmap, FMC2_BCR(cs), &bcr); + if (bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) + return true; + } + + return false; +} + +static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2 *fmc2, + struct stm32_fmc2_ebi *ebi) +{ + unsigned int cs; + + for (cs = 0; cs < FMC2_MAX_EBI_CE; cs++) { + if (!(ebi->cs_assigned & BIT(cs))) + continue; + + stm32_fmc2_ebi_set_bank(fmc2, cs, false); + } +} + +static int stm32_fmc2_ebi_probe(struct platform_device *pdev) +{ + struct stm32_fmc2 *fmc2 = dev_get_drvdata(pdev->dev.parent); + struct stm32_fmc2_ebi *ebi; + int ret; + + ebi = devm_kzalloc(&pdev->dev, sizeof(*ebi), GFP_KERNEL); + if (!ebi) + return -ENOMEM; + + ret = clk_prepare_enable(fmc2->clk); + if (ret) + return ret; + + ret = stm32_fmc2_ebi_parse_dt(&pdev->dev, ebi); + if (ret) + goto out; + + if (stm32_fmc2_ebi_check_nwait_is_used(fmc2, ebi) && + !stm32_fmc2_get_nwait(fmc2)) { + ret = -EINVAL; + goto out; + } + + stm32_fmc2_ebi_save_setup(fmc2, ebi); + stm32_fmc2_enable(fmc2); + platform_set_drvdata(pdev, ebi); + + return 0; + +out: + stm32_fmc2_ebi_disable_banks(fmc2, ebi); + clk_disable_unprepare(fmc2->clk); + + return ret; +} + +static int stm32_fmc2_ebi_remove(struct platform_device *pdev) +{ + struct stm32_fmc2 *fmc2 = dev_get_drvdata(pdev->dev.parent); + struct stm32_fmc2_ebi *ebi = platform_get_drvdata(pdev); + + if (stm32_fmc2_ebi_check_nwait_is_used(fmc2, ebi)) + stm32_fmc2_put_nwait(fmc2); + stm32_fmc2_ebi_disable_banks(fmc2, ebi); + stm32_fmc2_disable(fmc2); + clk_disable_unprepare(fmc2->clk); + + return 0; +} + +static int __maybe_unused stm32_fmc2_ebi_suspend(struct device *dev) +{ + struct stm32_fmc2 *fmc2 = dev_get_drvdata(dev->parent); + + stm32_fmc2_disable(fmc2); + clk_disable_unprepare(fmc2->clk); + + return 0; +} + +static int __maybe_unused stm32_fmc2_ebi_resume(struct device *dev) +{ + struct stm32_fmc2 *fmc2 = dev_get_drvdata(dev->parent); + struct stm32_fmc2_ebi *ebi = dev_get_drvdata(dev); + int ret; + + ret = clk_prepare_enable(fmc2->clk); + if (ret) + return ret; + + stm32_fmc2_ebi_set_setup(fmc2, ebi); + stm32_fmc2_enable(fmc2); + + return 0; +} + +static SIMPLE_DEV_PM_OPS(stm32_fmc2_ebi_pm_ops, stm32_fmc2_ebi_suspend, + stm32_fmc2_ebi_resume); + +static const struct of_device_id stm32_fmc2_ebi_match[] = { + {.compatible = "st,stm32mp1-fmc2-ebi"}, + {} +}; +MODULE_DEVICE_TABLE(of, stm32_fmc2_ebi_match); + +static struct platform_driver stm32_fmc2_ebi_driver = { + .probe = stm32_fmc2_ebi_probe, + .remove = stm32_fmc2_ebi_remove, + .driver = { + .name = "stm32_fmc2_ebi", + .of_match_table = stm32_fmc2_ebi_match, + .pm = &stm32_fmc2_ebi_pm_ops, + }, +}; +module_platform_driver(stm32_fmc2_ebi_driver); + +MODULE_ALIAS("platform:stm32_fmc2_ebi"); +MODULE_AUTHOR("Christophe Kerello "); +MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 ebi driver"); +MODULE_LICENSE("GPL v2"); From patchwork Wed Apr 15 15:57:30 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Kerello X-Patchwork-Id: 201988 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4E98EC38A29 for ; Wed, 15 Apr 2020 15:59:13 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2EA442076A for ; Wed, 15 Apr 2020 15:59:13 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=st.com header.i=@st.com header.b="AtCus4if" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1415016AbgDOP7L (ORCPT ); Wed, 15 Apr 2020 11:59:11 -0400 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:39887 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2410054AbgDOP7F (ORCPT ); Wed, 15 Apr 2020 11:59:05 -0400 Received: from pps.filterd (m0046037.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03FFW6Hc032223; Wed, 15 Apr 2020 17:58:49 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=kyVB+tiE+rN9XPO8kyR9LpGoCVCUanK+RTCgZf2jO/w=; b=AtCus4ifxTr/M17C7ri7ozELEn/Q2Ec2NMTSkCz/IvF+XFvZo6YuHd32YlYf2oYS/GsH APJoL/Uzi2K52Si3f0QQZ/baw6p8Rgwj88/O828W5iZdUMHeCYr1qO74/hpuQKQfG2qH CVhR0zlBHEpDOiagc5QDIi5OYdz+Qk8xaeHxxFrdqRHLshviwWOoGf5mv1TDw8fPe1Yt o9eaA/WnMGrcnCgEXeeS85X9zD/9IJW9nSgy1NkwvHGC8n+ffXKEBiwfa6Tyy80K6cZS 0TnSTk268qtpIYIPvww/IqnBI8NB0T43DXg29NnpFwWL+I/LhKnGiAGxcd3ax2RIwlIO fg== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 30dn94cy00-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 Apr 2020 17:58:49 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 28E4B100038; Wed, 15 Apr 2020 17:58:49 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag6node2.st.com [10.75.127.17]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 178FA2AF597; Wed, 15 Apr 2020 17:58:49 +0200 (CEST) Received: from localhost (10.75.127.51) by SFHDAG6NODE2.st.com (10.75.127.17) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Wed, 15 Apr 2020 17:58:48 +0200 From: Christophe Kerello To: , , , , , , CC: , , , , , Christophe Kerello Subject: [PATCH v2 06/12] mtd: rawnand: stm32_fmc2: use FMC2_TIMEOUT_MS for timeouts Date: Wed, 15 Apr 2020 17:57:30 +0200 Message-ID: <1586966256-29548-7-git-send-email-christophe.kerello@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> References: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.51] X-ClientProxiedBy: SFHDAG5NODE2.st.com (10.75.127.14) To SFHDAG6NODE2.st.com (10.75.127.17) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-04-15_05:2020-04-14,2020-04-15 signatures=0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch removes the constant FMC2_TIMEOUT_US. FMC2_TIMEOUT_MS is set to 5 seconds and this constant is used each time that we need to wait (except when the timeout value is set by the framework) Signed-off-by: Christophe Kerello --- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index ab53314..f159c39 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -37,8 +37,7 @@ /* Max ECC buffer length */ #define FMC2_MAX_ECC_BUF_LEN (FMC2_BCHDSRS_LEN * FMC2_MAX_SG) -#define FMC2_TIMEOUT_US 1000 -#define FMC2_TIMEOUT_MS 1000 +#define FMC2_TIMEOUT_MS 5000 /* Timings */ #define FMC2_THIZ 1 @@ -525,9 +524,9 @@ static int stm32_fmc2_ham_calculate(struct nand_chip *chip, const u8 *data, u32 sr, heccr; int ret; - ret = readl_relaxed_poll_timeout(fmc2->io_base + FMC2_SR, - sr, sr & FMC2_SR_NWRF, 10, - FMC2_TIMEOUT_MS); + ret = readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, + sr, sr & FMC2_SR_NWRF, 1, + 1000 * FMC2_TIMEOUT_MS); if (ret) { dev_err(fmc2->dev, "ham timeout\n"); return ret; @@ -1315,7 +1314,7 @@ static int stm32_fmc2_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) /* Check if there is no pending requests to the NAND flash */ if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr, sr & FMC2_SR_NWRF, 1, - FMC2_TIMEOUT_US)) + 1000 * FMC2_TIMEOUT_MS)) dev_warn(fmc2->dev, "Waitrdy timeout\n"); /* Wait tWB before R/B# signal is low */ From patchwork Wed Apr 15 15:57:31 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Kerello X-Patchwork-Id: 201985 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.0 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY, SPF_HELO_NONE, SPF_PASS, UNWANTED_LANGUAGE_BODY, USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 647B0C2BA19 for ; Wed, 15 Apr 2020 15:59:51 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 281A42076A for ; Wed, 15 Apr 2020 15:59:51 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=st.com header.i=@st.com header.b="zjDVAcf/" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1415058AbgDOP7l (ORCPT ); Wed, 15 Apr 2020 11:59:41 -0400 Received: from mx07-00178001.pphosted.com ([62.209.51.94]:39807 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1415031AbgDOP7h (ORCPT ); Wed, 15 Apr 2020 11:59:37 -0400 Received: from pps.filterd (m0046037.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03FFW6Hg032223; Wed, 15 Apr 2020 17:58:58 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=m21xKrJLs/OSGHibHlcNLM0+73h19wveY71mhiLNwAs=; b=zjDVAcf/G/sdf02wr3Fs8APNCPZ3RkfZh/a9HuGXnhw5ZjpbseD4RPPkBsI1s1LzbLXn 3OEiSoASNvGfBsaDgmMgHr1EFU8e6AmAnk824bSf+quyrWlmVnSomUbOgb+wh0btrV+o f8mf/gSnwgfXx+YLVOmDFWc3/+d95ZXbCRmfUovCtxvA+oaRHBtVXTe2EhskcwAOxPZA XfyYc3LWrdTm5T/uPBCNjGM1p8bO3k1tIDXkwvJMQiY9cvSdvUTYoVwDbdxKF6aHsurx o0CXajVwdEln9uS7EhX7R8NKZlElvhje334TqLxcwcx3hTCs4zhSo0WgyjWz+ERqUsRp ow== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 30dn94cy0y-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 Apr 2020 17:58:58 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id 184A9100034; Wed, 15 Apr 2020 17:58:58 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag6node2.st.com [10.75.127.17]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 0417E2AF597; Wed, 15 Apr 2020 17:58:58 +0200 (CEST) Received: from localhost (10.75.127.48) by SFHDAG6NODE2.st.com (10.75.127.17) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Wed, 15 Apr 2020 17:58:51 +0200 From: Christophe Kerello To: , , , , , , CC: , , , , , Christophe Kerello Subject: [PATCH v2 07/12] mtd: rawnand: stm32_fmc2: cleanup Date: Wed, 15 Apr 2020 17:57:31 +0200 Message-ID: <1586966256-29548-8-git-send-email-christophe.kerello@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> References: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.48] X-ClientProxiedBy: SFHDAG6NODE3.st.com (10.75.127.18) To SFHDAG6NODE2.st.com (10.75.127.17) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-04-15_05:2020-04-14,2020-04-15 signatures=0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch renames functions and local variables to be ready to use stm32_fmc2 structure. Signed-off-by: Christophe Kerello --- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 812 ++++++++++++++++----------------- 1 file changed, 404 insertions(+), 408 deletions(-) diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index f159c39..9ce405d 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -280,12 +280,12 @@ static inline struct stm32_fmc2_nfc *to_stm32_nfc(struct nand_controller *base) return container_of(base, struct stm32_fmc2_nfc, base); } -static void stm32_fmc2_timings_init(struct nand_chip *chip) +static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); struct stm32_fmc2_timings *timings = &nand->timings; - u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR); + u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); u32 pmem, patt; /* Set tclr/tar timings */ @@ -306,15 +306,15 @@ static void stm32_fmc2_timings_init(struct nand_chip *chip) patt |= FMC2_PATT_ATTHOLD(timings->thold_att); patt |= FMC2_PATT_ATTHIZ(timings->thiz); - writel_relaxed(pcr, fmc2->io_base + FMC2_PCR); - writel_relaxed(pmem, fmc2->io_base + FMC2_PMEM); - writel_relaxed(patt, fmc2->io_base + FMC2_PATT); + writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + writel_relaxed(pmem, nfc->io_base + FMC2_PMEM); + writel_relaxed(patt, nfc->io_base + FMC2_PATT); } -static void stm32_fmc2_setup(struct nand_chip *chip) +static void stm32_fmc2_nfc_setup(struct nand_chip *chip) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); - u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); + u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); /* Configure ECC algorithm (default configuration is Hamming) */ pcr &= ~FMC2_PCR_ECCALG; @@ -335,174 +335,174 @@ static void stm32_fmc2_setup(struct nand_chip *chip) pcr &= ~FMC2_PCR_ECCSS_MASK; pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512); - writel_relaxed(pcr, fmc2->io_base + FMC2_PCR); + writel_relaxed(pcr, nfc->io_base + FMC2_PCR); } -static int stm32_fmc2_select_chip(struct nand_chip *chip, int chipnr) +static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); struct dma_slave_config dma_cfg; int ret; - if (nand->cs_used[chipnr] == fmc2->cs_sel) + if (nand->cs_used[chipnr] == nfc->cs_sel) return 0; - fmc2->cs_sel = nand->cs_used[chipnr]; - stm32_fmc2_setup(chip); - stm32_fmc2_timings_init(chip); + nfc->cs_sel = nand->cs_used[chipnr]; + stm32_fmc2_nfc_setup(chip); + stm32_fmc2_nfc_timings_init(chip); - if (fmc2->dma_tx_ch && fmc2->dma_rx_ch) { + if (nfc->dma_tx_ch && nfc->dma_rx_ch) { memset(&dma_cfg, 0, sizeof(dma_cfg)); - dma_cfg.src_addr = fmc2->data_phys_addr[fmc2->cs_sel]; - dma_cfg.dst_addr = fmc2->data_phys_addr[fmc2->cs_sel]; + dma_cfg.src_addr = nfc->data_phys_addr[nfc->cs_sel]; + dma_cfg.dst_addr = nfc->data_phys_addr[nfc->cs_sel]; dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; dma_cfg.src_maxburst = 32; dma_cfg.dst_maxburst = 32; - ret = dmaengine_slave_config(fmc2->dma_tx_ch, &dma_cfg); + ret = dmaengine_slave_config(nfc->dma_tx_ch, &dma_cfg); if (ret) { - dev_err(fmc2->dev, "tx DMA engine slave config failed\n"); + dev_err(nfc->dev, "tx DMA engine slave config failed\n"); return ret; } - ret = dmaengine_slave_config(fmc2->dma_rx_ch, &dma_cfg); + ret = dmaengine_slave_config(nfc->dma_rx_ch, &dma_cfg); if (ret) { - dev_err(fmc2->dev, "rx DMA engine slave config failed\n"); + dev_err(nfc->dev, "rx DMA engine slave config failed\n"); return ret; } } - if (fmc2->dma_ecc_ch) { + if (nfc->dma_ecc_ch) { /* * Hamming: we read HECCR register * BCH4/BCH8: we read BCHDSRSx registers */ memset(&dma_cfg, 0, sizeof(dma_cfg)); - dma_cfg.src_addr = fmc2->io_phys_addr; + dma_cfg.src_addr = nfc->io_phys_addr; dma_cfg.src_addr += chip->ecc.strength == FMC2_ECC_HAM ? FMC2_HECCR : FMC2_BCHDSR0; dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - ret = dmaengine_slave_config(fmc2->dma_ecc_ch, &dma_cfg); + ret = dmaengine_slave_config(nfc->dma_ecc_ch, &dma_cfg); if (ret) { - dev_err(fmc2->dev, "ECC DMA engine slave config failed\n"); + dev_err(nfc->dev, "ECC DMA engine slave config failed\n"); return ret; } /* Calculate ECC length needed for one sector */ - fmc2->dma_ecc_len = chip->ecc.strength == FMC2_ECC_HAM ? - FMC2_HECCR_LEN : FMC2_BCHDSRS_LEN; + nfc->dma_ecc_len = chip->ecc.strength == FMC2_ECC_HAM ? + FMC2_HECCR_LEN : FMC2_BCHDSRS_LEN; } return 0; } -static void stm32_fmc2_set_buswidth_16(struct stm32_fmc2_nfc *fmc2, bool set) +static void stm32_fmc2_nfc_set_buswidth_16(struct stm32_fmc2_nfc *nfc, bool set) { - u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR); + u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); pcr &= ~FMC2_PCR_PWID_MASK; if (set) pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16); - writel_relaxed(pcr, fmc2->io_base + FMC2_PCR); + writel_relaxed(pcr, nfc->io_base + FMC2_PCR); } -static void stm32_fmc2_set_ecc(struct stm32_fmc2_nfc *fmc2, bool enable) +static void stm32_fmc2_nfc_set_ecc(struct stm32_fmc2_nfc *nfc, bool enable) { - u32 pcr = readl(fmc2->io_base + FMC2_PCR); + u32 pcr = readl(nfc->io_base + FMC2_PCR); pcr &= ~FMC2_PCR_ECCEN; if (enable) pcr |= FMC2_PCR_ECCEN; - writel(pcr, fmc2->io_base + FMC2_PCR); + writel(pcr, nfc->io_base + FMC2_PCR); } -static inline void stm32_fmc2_enable_seq_irq(struct stm32_fmc2_nfc *fmc2) +static inline void stm32_fmc2_nfc_enable_seq_irq(struct stm32_fmc2_nfc *nfc) { - u32 csqier = readl_relaxed(fmc2->io_base + FMC2_CSQIER); + u32 csqier = readl_relaxed(nfc->io_base + FMC2_CSQIER); csqier |= FMC2_CSQIER_TCIE; - fmc2->irq_state = FMC2_IRQ_SEQ; + nfc->irq_state = FMC2_IRQ_SEQ; - writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER); + writel_relaxed(csqier, nfc->io_base + FMC2_CSQIER); } -static inline void stm32_fmc2_disable_seq_irq(struct stm32_fmc2_nfc *fmc2) +static inline void stm32_fmc2_nfc_disable_seq_irq(struct stm32_fmc2_nfc *nfc) { - u32 csqier = readl_relaxed(fmc2->io_base + FMC2_CSQIER); + u32 csqier = readl_relaxed(nfc->io_base + FMC2_CSQIER); csqier &= ~FMC2_CSQIER_TCIE; - writel_relaxed(csqier, fmc2->io_base + FMC2_CSQIER); + writel_relaxed(csqier, nfc->io_base + FMC2_CSQIER); - fmc2->irq_state = FMC2_IRQ_UNKNOWN; + nfc->irq_state = FMC2_IRQ_UNKNOWN; } -static inline void stm32_fmc2_clear_seq_irq(struct stm32_fmc2_nfc *fmc2) +static inline void stm32_fmc2_nfc_clear_seq_irq(struct stm32_fmc2_nfc *nfc) { - writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, fmc2->io_base + FMC2_CSQICR); + writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, nfc->io_base + FMC2_CSQICR); } -static inline void stm32_fmc2_enable_bch_irq(struct stm32_fmc2_nfc *fmc2, - int mode) +static inline void stm32_fmc2_nfc_enable_bch_irq(struct stm32_fmc2_nfc *nfc, + int mode) { - u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER); + u32 bchier = readl_relaxed(nfc->io_base + FMC2_BCHIER); if (mode == NAND_ECC_WRITE) bchier |= FMC2_BCHIER_EPBRIE; else bchier |= FMC2_BCHIER_DERIE; - fmc2->irq_state = FMC2_IRQ_BCH; + nfc->irq_state = FMC2_IRQ_BCH; - writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER); + writel_relaxed(bchier, nfc->io_base + FMC2_BCHIER); } -static inline void stm32_fmc2_disable_bch_irq(struct stm32_fmc2_nfc *fmc2) +static inline void stm32_fmc2_nfc_disable_bch_irq(struct stm32_fmc2_nfc *nfc) { - u32 bchier = readl_relaxed(fmc2->io_base + FMC2_BCHIER); + u32 bchier = readl_relaxed(nfc->io_base + FMC2_BCHIER); bchier &= ~FMC2_BCHIER_DERIE; bchier &= ~FMC2_BCHIER_EPBRIE; - writel_relaxed(bchier, fmc2->io_base + FMC2_BCHIER); + writel_relaxed(bchier, nfc->io_base + FMC2_BCHIER); - fmc2->irq_state = FMC2_IRQ_UNKNOWN; + nfc->irq_state = FMC2_IRQ_UNKNOWN; } -static inline void stm32_fmc2_clear_bch_irq(struct stm32_fmc2_nfc *fmc2) +static inline void stm32_fmc2_nfc_clear_bch_irq(struct stm32_fmc2_nfc *nfc) { - writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, fmc2->io_base + FMC2_BCHICR); + writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, nfc->io_base + FMC2_BCHICR); } /* * Enable ECC logic and reset syndrome/parity bits previously calculated * Syndrome/parity bits is cleared by setting the ECCEN bit to 0 */ -static void stm32_fmc2_hwctl(struct nand_chip *chip, int mode) +static void stm32_fmc2_nfc_hwctl(struct nand_chip *chip, int mode) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); - stm32_fmc2_set_ecc(fmc2, false); + stm32_fmc2_nfc_set_ecc(nfc, false); if (chip->ecc.strength != FMC2_ECC_HAM) { - u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR); + u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); if (mode == NAND_ECC_WRITE) pcr |= FMC2_PCR_WEN; else pcr &= ~FMC2_PCR_WEN; - writel_relaxed(pcr, fmc2->io_base + FMC2_PCR); + writel_relaxed(pcr, nfc->io_base + FMC2_PCR); - reinit_completion(&fmc2->complete); - stm32_fmc2_clear_bch_irq(fmc2); - stm32_fmc2_enable_bch_irq(fmc2, mode); + reinit_completion(&nfc->complete); + stm32_fmc2_nfc_clear_bch_irq(nfc); + stm32_fmc2_nfc_enable_bch_irq(nfc, mode); } - stm32_fmc2_set_ecc(fmc2, true); + stm32_fmc2_nfc_set_ecc(nfc, true); } /* @@ -510,37 +510,37 @@ static void stm32_fmc2_hwctl(struct nand_chip *chip, int mode) * ECC is 3 bytes for 512 bytes of data (supports error correction up to * max of 1-bit) */ -static inline void stm32_fmc2_ham_set_ecc(const u32 ecc_sta, u8 *ecc) +static inline void stm32_fmc2_nfc_ham_set_ecc(const u32 ecc_sta, u8 *ecc) { ecc[0] = ecc_sta; ecc[1] = ecc_sta >> 8; ecc[2] = ecc_sta >> 16; } -static int stm32_fmc2_ham_calculate(struct nand_chip *chip, const u8 *data, - u8 *ecc) +static int stm32_fmc2_nfc_ham_calculate(struct nand_chip *chip, const u8 *data, + u8 *ecc) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); u32 sr, heccr; int ret; - ret = readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, + ret = readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_SR, sr, sr & FMC2_SR_NWRF, 1, 1000 * FMC2_TIMEOUT_MS); if (ret) { - dev_err(fmc2->dev, "ham timeout\n"); + dev_err(nfc->dev, "ham timeout\n"); return ret; } - heccr = readl_relaxed(fmc2->io_base + FMC2_HECCR); - stm32_fmc2_ham_set_ecc(heccr, ecc); - stm32_fmc2_set_ecc(fmc2, false); + heccr = readl_relaxed(nfc->io_base + FMC2_HECCR); + stm32_fmc2_nfc_ham_set_ecc(heccr, ecc); + stm32_fmc2_nfc_set_ecc(nfc, false); return 0; } -static int stm32_fmc2_ham_correct(struct nand_chip *chip, u8 *dat, - u8 *read_ecc, u8 *calc_ecc) +static int stm32_fmc2_nfc_ham_correct(struct nand_chip *chip, u8 *dat, + u8 *read_ecc, u8 *calc_ecc) { u8 bit_position = 0, b0, b1, b2; u32 byte_addr = 0, b; @@ -596,28 +596,28 @@ static int stm32_fmc2_ham_correct(struct nand_chip *chip, u8 *dat, * ECC is 7/13 bytes for 512 bytes of data (supports error correction up to * max of 4-bit/8-bit) */ -static int stm32_fmc2_bch_calculate(struct nand_chip *chip, const u8 *data, - u8 *ecc) +static int stm32_fmc2_nfc_bch_calculate(struct nand_chip *chip, const u8 *data, + u8 *ecc) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); u32 bchpbr; /* Wait until the BCH code is ready */ - if (!wait_for_completion_timeout(&fmc2->complete, + if (!wait_for_completion_timeout(&nfc->complete, msecs_to_jiffies(FMC2_TIMEOUT_MS))) { - dev_err(fmc2->dev, "bch timeout\n"); - stm32_fmc2_disable_bch_irq(fmc2); + dev_err(nfc->dev, "bch timeout\n"); + stm32_fmc2_nfc_disable_bch_irq(nfc); return -ETIMEDOUT; } /* Read parity bits */ - bchpbr = readl_relaxed(fmc2->io_base + FMC2_BCHPBR1); + bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR1); ecc[0] = bchpbr; ecc[1] = bchpbr >> 8; ecc[2] = bchpbr >> 16; ecc[3] = bchpbr >> 24; - bchpbr = readl_relaxed(fmc2->io_base + FMC2_BCHPBR2); + bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR2); ecc[4] = bchpbr; ecc[5] = bchpbr >> 8; ecc[6] = bchpbr >> 16; @@ -625,22 +625,22 @@ static int stm32_fmc2_bch_calculate(struct nand_chip *chip, const u8 *data, if (chip->ecc.strength == FMC2_ECC_BCH8) { ecc[7] = bchpbr >> 24; - bchpbr = readl_relaxed(fmc2->io_base + FMC2_BCHPBR3); + bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR3); ecc[8] = bchpbr; ecc[9] = bchpbr >> 8; ecc[10] = bchpbr >> 16; ecc[11] = bchpbr >> 24; - bchpbr = readl_relaxed(fmc2->io_base + FMC2_BCHPBR4); + bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR4); ecc[12] = bchpbr; } - stm32_fmc2_set_ecc(fmc2, false); + stm32_fmc2_nfc_set_ecc(nfc, false); return 0; } -static int stm32_fmc2_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta) +static int stm32_fmc2_nfc_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta) { u32 bchdsr0 = ecc_sta[0]; u32 bchdsr1 = ecc_sta[1]; @@ -679,33 +679,33 @@ static int stm32_fmc2_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta) return nb_errs; } -static int stm32_fmc2_bch_correct(struct nand_chip *chip, u8 *dat, - u8 *read_ecc, u8 *calc_ecc) +static int stm32_fmc2_nfc_bch_correct(struct nand_chip *chip, u8 *dat, + u8 *read_ecc, u8 *calc_ecc) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); u32 ecc_sta[5]; /* Wait until the decoding error is ready */ - if (!wait_for_completion_timeout(&fmc2->complete, + if (!wait_for_completion_timeout(&nfc->complete, msecs_to_jiffies(FMC2_TIMEOUT_MS))) { - dev_err(fmc2->dev, "bch timeout\n"); - stm32_fmc2_disable_bch_irq(fmc2); + dev_err(nfc->dev, "bch timeout\n"); + stm32_fmc2_nfc_disable_bch_irq(nfc); return -ETIMEDOUT; } - ecc_sta[0] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR0); - ecc_sta[1] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR1); - ecc_sta[2] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR2); - ecc_sta[3] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR3); - ecc_sta[4] = readl_relaxed(fmc2->io_base + FMC2_BCHDSR4); + ecc_sta[0] = readl_relaxed(nfc->io_base + FMC2_BCHDSR0); + ecc_sta[1] = readl_relaxed(nfc->io_base + FMC2_BCHDSR1); + ecc_sta[2] = readl_relaxed(nfc->io_base + FMC2_BCHDSR2); + ecc_sta[3] = readl_relaxed(nfc->io_base + FMC2_BCHDSR3); + ecc_sta[4] = readl_relaxed(nfc->io_base + FMC2_BCHDSR4); - stm32_fmc2_set_ecc(fmc2, false); + stm32_fmc2_nfc_set_ecc(nfc, false); - return stm32_fmc2_bch_decode(chip->ecc.size, dat, ecc_sta); + return stm32_fmc2_nfc_bch_decode(chip->ecc.size, dat, ecc_sta); } -static int stm32_fmc2_read_page(struct nand_chip *chip, u8 *buf, - int oob_required, int page) +static int stm32_fmc2_nfc_read_page(struct nand_chip *chip, u8 *buf, + int oob_required, int page) { struct mtd_info *mtd = nand_to_mtd(chip); int ret, i, s, stat, eccsize = chip->ecc.size; @@ -767,21 +767,21 @@ static int stm32_fmc2_read_page(struct nand_chip *chip, u8 *buf, } /* Sequencer read/write configuration */ -static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page, - int raw, bool write_data) +static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, + int raw, bool write_data) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct mtd_info *mtd = nand_to_mtd(chip); u32 csqcfgr1, csqcfgr2, csqcfgr3; u32 csqar1, csqar2; u32 ecc_offset = mtd->writesize + FMC2_BBM_LEN; - u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR); + u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); if (write_data) pcr |= FMC2_PCR_WEN; else pcr &= ~FMC2_PCR_WEN; - writel_relaxed(pcr, fmc2->io_base + FMC2_PCR); + writel_relaxed(pcr, nfc->io_base + FMC2_PCR); /* * - Set Program Page/Page Read command @@ -843,7 +843,7 @@ static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page, * - Calculate the number of address cycles to be issued * - Set byte 5 of address cycle if needed */ - csqar2 = FMC2_CSQCAR2_NANDCEN(fmc2->cs_sel); + csqar2 = FMC2_CSQCAR2_NANDCEN(nfc->cs_sel); if (chip->options & NAND_BUSWIDTH_16) csqar2 |= FMC2_CSQCAR2_SAO(ecc_offset >> 1); else @@ -855,31 +855,32 @@ static void stm32_fmc2_rw_page_init(struct nand_chip *chip, int page, csqcfgr1 |= FMC2_CSQCFGR1_ACYNBR(4); } - writel_relaxed(csqcfgr1, fmc2->io_base + FMC2_CSQCFGR1); - writel_relaxed(csqcfgr2, fmc2->io_base + FMC2_CSQCFGR2); - writel_relaxed(csqcfgr3, fmc2->io_base + FMC2_CSQCFGR3); - writel_relaxed(csqar1, fmc2->io_base + FMC2_CSQAR1); - writel_relaxed(csqar2, fmc2->io_base + FMC2_CSQAR2); + writel_relaxed(csqcfgr1, nfc->io_base + FMC2_CSQCFGR1); + writel_relaxed(csqcfgr2, nfc->io_base + FMC2_CSQCFGR2); + writel_relaxed(csqcfgr3, nfc->io_base + FMC2_CSQCFGR3); + writel_relaxed(csqar1, nfc->io_base + FMC2_CSQAR1); + writel_relaxed(csqar2, nfc->io_base + FMC2_CSQAR2); } -static void stm32_fmc2_dma_callback(void *arg) +static void stm32_fmc2_nfc_dma_callback(void *arg) { complete((struct completion *)arg); } /* Read/write data from/to a page */ -static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf, - int raw, bool write_data) +static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf, + int raw, bool write_data) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct dma_async_tx_descriptor *desc_data, *desc_ecc; struct scatterlist *sg; - struct dma_chan *dma_ch = fmc2->dma_rx_ch; + struct dma_chan *dma_ch = nfc->dma_rx_ch; enum dma_data_direction dma_data_dir = DMA_FROM_DEVICE; enum dma_transfer_direction dma_transfer_dir = DMA_DEV_TO_MEM; - u32 csqcr = readl_relaxed(fmc2->io_base + FMC2_CSQCR); + u32 csqcr = readl_relaxed(nfc->io_base + FMC2_CSQCR); int eccsteps = chip->ecc.steps; int eccsize = chip->ecc.size; + unsigned long timeout = msecs_to_jiffies(FMC2_TIMEOUT_MS); const u8 *p = buf; int s, ret; @@ -887,20 +888,20 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf, if (write_data) { dma_data_dir = DMA_TO_DEVICE; dma_transfer_dir = DMA_MEM_TO_DEV; - dma_ch = fmc2->dma_tx_ch; + dma_ch = nfc->dma_tx_ch; } - for_each_sg(fmc2->dma_data_sg.sgl, sg, eccsteps, s) { + for_each_sg(nfc->dma_data_sg.sgl, sg, eccsteps, s) { sg_set_buf(sg, p, eccsize); p += eccsize; } - ret = dma_map_sg(fmc2->dev, fmc2->dma_data_sg.sgl, + ret = dma_map_sg(nfc->dev, nfc->dma_data_sg.sgl, eccsteps, dma_data_dir); if (ret < 0) return ret; - desc_data = dmaengine_prep_slave_sg(dma_ch, fmc2->dma_data_sg.sgl, + desc_data = dmaengine_prep_slave_sg(dma_ch, nfc->dma_data_sg.sgl, eccsteps, dma_transfer_dir, DMA_PREP_INTERRUPT); if (!desc_data) { @@ -908,10 +909,10 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf, goto err_unmap_data; } - reinit_completion(&fmc2->dma_data_complete); - reinit_completion(&fmc2->complete); - desc_data->callback = stm32_fmc2_dma_callback; - desc_data->callback_param = &fmc2->dma_data_complete; + reinit_completion(&nfc->dma_data_complete); + reinit_completion(&nfc->complete); + desc_data->callback = stm32_fmc2_nfc_dma_callback; + desc_data->callback_param = &nfc->dma_data_complete; ret = dma_submit_error(dmaengine_submit(desc_data)); if (ret) goto err_unmap_data; @@ -920,19 +921,19 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf, if (!write_data && !raw) { /* Configure DMA ECC status */ - p = fmc2->ecc_buf; - for_each_sg(fmc2->dma_ecc_sg.sgl, sg, eccsteps, s) { - sg_set_buf(sg, p, fmc2->dma_ecc_len); - p += fmc2->dma_ecc_len; + p = nfc->ecc_buf; + for_each_sg(nfc->dma_ecc_sg.sgl, sg, eccsteps, s) { + sg_set_buf(sg, p, nfc->dma_ecc_len); + p += nfc->dma_ecc_len; } - ret = dma_map_sg(fmc2->dev, fmc2->dma_ecc_sg.sgl, + ret = dma_map_sg(nfc->dev, nfc->dma_ecc_sg.sgl, eccsteps, dma_data_dir); if (ret < 0) goto err_unmap_data; - desc_ecc = dmaengine_prep_slave_sg(fmc2->dma_ecc_ch, - fmc2->dma_ecc_sg.sgl, + desc_ecc = dmaengine_prep_slave_sg(nfc->dma_ecc_ch, + nfc->dma_ecc_sg.sgl, eccsteps, dma_transfer_dir, DMA_PREP_INTERRUPT); if (!desc_ecc) { @@ -940,76 +941,73 @@ static int stm32_fmc2_xfer(struct nand_chip *chip, const u8 *buf, goto err_unmap_ecc; } - reinit_completion(&fmc2->dma_ecc_complete); - desc_ecc->callback = stm32_fmc2_dma_callback; - desc_ecc->callback_param = &fmc2->dma_ecc_complete; + reinit_completion(&nfc->dma_ecc_complete); + desc_ecc->callback = stm32_fmc2_nfc_dma_callback; + desc_ecc->callback_param = &nfc->dma_ecc_complete; ret = dma_submit_error(dmaengine_submit(desc_ecc)); if (ret) goto err_unmap_ecc; - dma_async_issue_pending(fmc2->dma_ecc_ch); + dma_async_issue_pending(nfc->dma_ecc_ch); } - stm32_fmc2_clear_seq_irq(fmc2); - stm32_fmc2_enable_seq_irq(fmc2); + stm32_fmc2_nfc_clear_seq_irq(nfc); + stm32_fmc2_nfc_enable_seq_irq(nfc); /* Start the transfer */ csqcr |= FMC2_CSQCR_CSQSTART; - writel_relaxed(csqcr, fmc2->io_base + FMC2_CSQCR); + writel_relaxed(csqcr, nfc->io_base + FMC2_CSQCR); /* Wait end of sequencer transfer */ - if (!wait_for_completion_timeout(&fmc2->complete, - msecs_to_jiffies(FMC2_TIMEOUT_MS))) { - dev_err(fmc2->dev, "seq timeout\n"); - stm32_fmc2_disable_seq_irq(fmc2); + if (!wait_for_completion_timeout(&nfc->complete, timeout)) { + dev_err(nfc->dev, "seq timeout\n"); + stm32_fmc2_nfc_disable_seq_irq(nfc); dmaengine_terminate_all(dma_ch); if (!write_data && !raw) - dmaengine_terminate_all(fmc2->dma_ecc_ch); + dmaengine_terminate_all(nfc->dma_ecc_ch); ret = -ETIMEDOUT; goto err_unmap_ecc; } /* Wait DMA data transfer completion */ - if (!wait_for_completion_timeout(&fmc2->dma_data_complete, - msecs_to_jiffies(FMC2_TIMEOUT_MS))) { - dev_err(fmc2->dev, "data DMA timeout\n"); + if (!wait_for_completion_timeout(&nfc->dma_data_complete, timeout)) { + dev_err(nfc->dev, "data DMA timeout\n"); dmaengine_terminate_all(dma_ch); ret = -ETIMEDOUT; } /* Wait DMA ECC transfer completion */ if (!write_data && !raw) { - if (!wait_for_completion_timeout(&fmc2->dma_ecc_complete, - msecs_to_jiffies(FMC2_TIMEOUT_MS))) { - dev_err(fmc2->dev, "ECC DMA timeout\n"); - dmaengine_terminate_all(fmc2->dma_ecc_ch); + if (!wait_for_completion_timeout(&nfc->dma_ecc_complete, + timeout)) { + dev_err(nfc->dev, "ECC DMA timeout\n"); + dmaengine_terminate_all(nfc->dma_ecc_ch); ret = -ETIMEDOUT; } } err_unmap_ecc: if (!write_data && !raw) - dma_unmap_sg(fmc2->dev, fmc2->dma_ecc_sg.sgl, + dma_unmap_sg(nfc->dev, nfc->dma_ecc_sg.sgl, eccsteps, dma_data_dir); err_unmap_data: - dma_unmap_sg(fmc2->dev, fmc2->dma_data_sg.sgl, eccsteps, dma_data_dir); + dma_unmap_sg(nfc->dev, nfc->dma_data_sg.sgl, eccsteps, dma_data_dir); return ret; } -static int stm32_fmc2_sequencer_write(struct nand_chip *chip, - const u8 *buf, int oob_required, - int page, int raw) +static int stm32_fmc2_nfc_seq_write(struct nand_chip *chip, const u8 *buf, + int oob_required, int page, int raw) { struct mtd_info *mtd = nand_to_mtd(chip); int ret; /* Configure the sequencer */ - stm32_fmc2_rw_page_init(chip, page, raw, true); + stm32_fmc2_nfc_rw_page_init(chip, page, raw, true); /* Write the page */ - ret = stm32_fmc2_xfer(chip, buf, raw, true); + ret = stm32_fmc2_nfc_xfer(chip, buf, raw, true); if (ret) return ret; @@ -1025,53 +1023,50 @@ static int stm32_fmc2_sequencer_write(struct nand_chip *chip, return nand_prog_page_end_op(chip); } -static int stm32_fmc2_sequencer_write_page(struct nand_chip *chip, - const u8 *buf, - int oob_required, - int page) +static int stm32_fmc2_nfc_seq_write_page(struct nand_chip *chip, const u8 *buf, + int oob_required, int page) { int ret; - ret = stm32_fmc2_select_chip(chip, chip->cur_cs); + ret = stm32_fmc2_nfc_select_chip(chip, chip->cur_cs); if (ret) return ret; - return stm32_fmc2_sequencer_write(chip, buf, oob_required, page, false); + return stm32_fmc2_nfc_seq_write(chip, buf, oob_required, page, false); } -static int stm32_fmc2_sequencer_write_page_raw(struct nand_chip *chip, - const u8 *buf, - int oob_required, - int page) +static int stm32_fmc2_nfc_seq_write_page_raw(struct nand_chip *chip, + const u8 *buf, int oob_required, + int page) { int ret; - ret = stm32_fmc2_select_chip(chip, chip->cur_cs); + ret = stm32_fmc2_nfc_select_chip(chip, chip->cur_cs); if (ret) return ret; - return stm32_fmc2_sequencer_write(chip, buf, oob_required, page, true); + return stm32_fmc2_nfc_seq_write(chip, buf, oob_required, page, true); } /* Get a status indicating which sectors have errors */ -static inline u16 stm32_fmc2_get_mapping_status(struct stm32_fmc2_nfc *fmc2) +static inline u16 stm32_fmc2_nfc_get_mapping_status(struct stm32_fmc2_nfc *nfc) { - u32 csqemsr = readl_relaxed(fmc2->io_base + FMC2_CSQEMSR); + u32 csqemsr = readl_relaxed(nfc->io_base + FMC2_CSQEMSR); return csqemsr & FMC2_CSQEMSR_SEM; } -static int stm32_fmc2_sequencer_correct(struct nand_chip *chip, u8 *dat, - u8 *read_ecc, u8 *calc_ecc) +static int stm32_fmc2_nfc_seq_correct(struct nand_chip *chip, u8 *dat, + u8 *read_ecc, u8 *calc_ecc) { struct mtd_info *mtd = nand_to_mtd(chip); - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); int eccbytes = chip->ecc.bytes; int eccsteps = chip->ecc.steps; int eccstrength = chip->ecc.strength; int i, s, eccsize = chip->ecc.size; - u32 *ecc_sta = (u32 *)fmc2->ecc_buf; - u16 sta_map = stm32_fmc2_get_mapping_status(fmc2); + u32 *ecc_sta = (u32 *)nfc->ecc_buf; + u16 sta_map = stm32_fmc2_nfc_get_mapping_status(nfc); unsigned int max_bitflips = 0; for (i = 0, s = 0; s < eccsteps; s++, i += eccbytes, dat += eccsize) { @@ -1080,10 +1075,11 @@ static int stm32_fmc2_sequencer_correct(struct nand_chip *chip, u8 *dat, if (eccstrength == FMC2_ECC_HAM) { /* Ecc_sta = FMC2_HECCR */ if (sta_map & BIT(s)) { - stm32_fmc2_ham_set_ecc(*ecc_sta, &calc_ecc[i]); - stat = stm32_fmc2_ham_correct(chip, dat, - &read_ecc[i], - &calc_ecc[i]); + stm32_fmc2_nfc_ham_set_ecc(*ecc_sta, + &calc_ecc[i]); + stat = stm32_fmc2_nfc_ham_correct(chip, dat, + &read_ecc[i], + &calc_ecc[i]); } ecc_sta++; } else { @@ -1095,8 +1091,8 @@ static int stm32_fmc2_sequencer_correct(struct nand_chip *chip, u8 *dat, * Ecc_sta[4] = FMC2_BCHDSR4 */ if (sta_map & BIT(s)) - stat = stm32_fmc2_bch_decode(eccsize, dat, - ecc_sta); + stat = stm32_fmc2_nfc_bch_decode(eccsize, dat, + ecc_sta); ecc_sta += 5; } @@ -1119,29 +1115,29 @@ static int stm32_fmc2_sequencer_correct(struct nand_chip *chip, u8 *dat, return max_bitflips; } -static int stm32_fmc2_sequencer_read_page(struct nand_chip *chip, u8 *buf, - int oob_required, int page) +static int stm32_fmc2_nfc_seq_read_page(struct nand_chip *chip, u8 *buf, + int oob_required, int page) { struct mtd_info *mtd = nand_to_mtd(chip); - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); u8 *ecc_calc = chip->ecc.calc_buf; u8 *ecc_code = chip->ecc.code_buf; u16 sta_map; int ret; - ret = stm32_fmc2_select_chip(chip, chip->cur_cs); + ret = stm32_fmc2_nfc_select_chip(chip, chip->cur_cs); if (ret) return ret; /* Configure the sequencer */ - stm32_fmc2_rw_page_init(chip, page, 0, false); + stm32_fmc2_nfc_rw_page_init(chip, page, 0, false); /* Read the page */ - ret = stm32_fmc2_xfer(chip, buf, 0, false); + ret = stm32_fmc2_nfc_xfer(chip, buf, 0, false); if (ret) return ret; - sta_map = stm32_fmc2_get_mapping_status(fmc2); + sta_map = stm32_fmc2_nfc_get_mapping_status(nfc); /* Check if errors happen */ if (likely(!sta_map)) { @@ -1168,21 +1164,21 @@ static int stm32_fmc2_sequencer_read_page(struct nand_chip *chip, u8 *buf, return chip->ecc.correct(chip, buf, ecc_code, ecc_calc); } -static int stm32_fmc2_sequencer_read_page_raw(struct nand_chip *chip, u8 *buf, - int oob_required, int page) +static int stm32_fmc2_nfc_seq_read_page_raw(struct nand_chip *chip, u8 *buf, + int oob_required, int page) { struct mtd_info *mtd = nand_to_mtd(chip); int ret; - ret = stm32_fmc2_select_chip(chip, chip->cur_cs); + ret = stm32_fmc2_nfc_select_chip(chip, chip->cur_cs); if (ret) return ret; /* Configure the sequencer */ - stm32_fmc2_rw_page_init(chip, page, 1, false); + stm32_fmc2_nfc_rw_page_init(chip, page, 1, false); /* Read the page */ - ret = stm32_fmc2_xfer(chip, buf, 1, false); + ret = stm32_fmc2_nfc_xfer(chip, buf, 1, false); if (ret) return ret; @@ -1195,31 +1191,31 @@ static int stm32_fmc2_sequencer_read_page_raw(struct nand_chip *chip, u8 *buf, return 0; } -static irqreturn_t stm32_fmc2_irq(int irq, void *dev_id) +static irqreturn_t stm32_fmc2_nfc_irq(int irq, void *dev_id) { - struct stm32_fmc2_nfc *fmc2 = (struct stm32_fmc2_nfc *)dev_id; + struct stm32_fmc2_nfc *nfc = (struct stm32_fmc2_nfc *)dev_id; - if (fmc2->irq_state == FMC2_IRQ_SEQ) + if (nfc->irq_state == FMC2_IRQ_SEQ) /* Sequencer is used */ - stm32_fmc2_disable_seq_irq(fmc2); - else if (fmc2->irq_state == FMC2_IRQ_BCH) + stm32_fmc2_nfc_disable_seq_irq(nfc); + else if (nfc->irq_state == FMC2_IRQ_BCH) /* BCH is used */ - stm32_fmc2_disable_bch_irq(fmc2); + stm32_fmc2_nfc_disable_bch_irq(nfc); - complete(&fmc2->complete); + complete(&nfc->complete); return IRQ_HANDLED; } -static void stm32_fmc2_read_data(struct nand_chip *chip, void *buf, - unsigned int len, bool force_8bit) +static void stm32_fmc2_nfc_read_data(struct nand_chip *chip, void *buf, + unsigned int len, bool force_8bit) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); - void __iomem *io_addr_r = fmc2->data_base[fmc2->cs_sel]; + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); + void __iomem *io_addr_r = nfc->data_base[nfc->cs_sel]; if (force_8bit && chip->options & NAND_BUSWIDTH_16) /* Reconfigure bus width to 8-bit */ - stm32_fmc2_set_buswidth_16(fmc2, false); + stm32_fmc2_nfc_set_buswidth_16(nfc, false); if (!IS_ALIGNED((uintptr_t)buf, sizeof(u32))) { if (!IS_ALIGNED((uintptr_t)buf, sizeof(u16)) && len) { @@ -1255,18 +1251,18 @@ static void stm32_fmc2_read_data(struct nand_chip *chip, void *buf, if (force_8bit && chip->options & NAND_BUSWIDTH_16) /* Reconfigure bus width to 16-bit */ - stm32_fmc2_set_buswidth_16(fmc2, true); + stm32_fmc2_nfc_set_buswidth_16(nfc, true); } -static void stm32_fmc2_write_data(struct nand_chip *chip, const void *buf, - unsigned int len, bool force_8bit) +static void stm32_fmc2_nfc_write_data(struct nand_chip *chip, const void *buf, + unsigned int len, bool force_8bit) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); - void __iomem *io_addr_w = fmc2->data_base[fmc2->cs_sel]; + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); + void __iomem *io_addr_w = nfc->data_base[nfc->cs_sel]; if (force_8bit && chip->options & NAND_BUSWIDTH_16) /* Reconfigure bus width to 8-bit */ - stm32_fmc2_set_buswidth_16(fmc2, false); + stm32_fmc2_nfc_set_buswidth_16(nfc, false); if (!IS_ALIGNED((uintptr_t)buf, sizeof(u32))) { if (!IS_ALIGNED((uintptr_t)buf, sizeof(u16)) && len) { @@ -1302,44 +1298,45 @@ static void stm32_fmc2_write_data(struct nand_chip *chip, const void *buf, if (force_8bit && chip->options & NAND_BUSWIDTH_16) /* Reconfigure bus width to 16-bit */ - stm32_fmc2_set_buswidth_16(fmc2, true); + stm32_fmc2_nfc_set_buswidth_16(nfc, true); } -static int stm32_fmc2_waitrdy(struct nand_chip *chip, unsigned long timeout_ms) +static int stm32_fmc2_nfc_waitrdy(struct nand_chip *chip, + unsigned long timeout_ms) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); const struct nand_sdr_timings *timings; u32 isr, sr; /* Check if there is no pending requests to the NAND flash */ - if (readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_SR, sr, + if (readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_SR, sr, sr & FMC2_SR_NWRF, 1, 1000 * FMC2_TIMEOUT_MS)) - dev_warn(fmc2->dev, "Waitrdy timeout\n"); + dev_warn(nfc->dev, "Waitrdy timeout\n"); /* Wait tWB before R/B# signal is low */ timings = nand_get_sdr_timings(&chip->data_interface); ndelay(PSEC_TO_NSEC(timings->tWB_max)); /* R/B# signal is low, clear high level flag */ - writel_relaxed(FMC2_ICR_CIHLF, fmc2->io_base + FMC2_ICR); + writel_relaxed(FMC2_ICR_CIHLF, nfc->io_base + FMC2_ICR); /* Wait R/B# signal is high */ - return readl_relaxed_poll_timeout_atomic(fmc2->io_base + FMC2_ISR, + return readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_ISR, isr, isr & FMC2_ISR_IHLF, 5, 1000 * timeout_ms); } -static int stm32_fmc2_exec_op(struct nand_chip *chip, - const struct nand_operation *op, - bool check_only) +static int stm32_fmc2_nfc_exec_op(struct nand_chip *chip, + const struct nand_operation *op, + bool check_only) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); const struct nand_op_instr *instr = NULL; - unsigned int op_id, i; + unsigned int op_id, i, timeout; int ret; - ret = stm32_fmc2_select_chip(chip, op->cs); + ret = stm32_fmc2_nfc_select_chip(chip, op->cs); if (ret) return ret; @@ -1352,30 +1349,30 @@ static int stm32_fmc2_exec_op(struct nand_chip *chip, switch (instr->type) { case NAND_OP_CMD_INSTR: writeb_relaxed(instr->ctx.cmd.opcode, - fmc2->cmd_base[fmc2->cs_sel]); + nfc->cmd_base[nfc->cs_sel]); break; case NAND_OP_ADDR_INSTR: for (i = 0; i < instr->ctx.addr.naddrs; i++) writeb_relaxed(instr->ctx.addr.addrs[i], - fmc2->addr_base[fmc2->cs_sel]); + nfc->addr_base[nfc->cs_sel]); break; case NAND_OP_DATA_IN_INSTR: - stm32_fmc2_read_data(chip, instr->ctx.data.buf.in, - instr->ctx.data.len, - instr->ctx.data.force_8bit); + stm32_fmc2_nfc_read_data(chip, instr->ctx.data.buf.in, + instr->ctx.data.len, + instr->ctx.data.force_8bit); break; case NAND_OP_DATA_OUT_INSTR: - stm32_fmc2_write_data(chip, instr->ctx.data.buf.out, - instr->ctx.data.len, - instr->ctx.data.force_8bit); + stm32_fmc2_nfc_write_data(chip, instr->ctx.data.buf.out, + instr->ctx.data.len, + instr->ctx.data.force_8bit); break; case NAND_OP_WAITRDY_INSTR: - ret = stm32_fmc2_waitrdy(chip, - instr->ctx.waitrdy.timeout_ms); + timeout = instr->ctx.waitrdy.timeout_ms; + ret = stm32_fmc2_nfc_waitrdy(chip, timeout); break; } } @@ -1383,13 +1380,13 @@ static int stm32_fmc2_exec_op(struct nand_chip *chip, return ret; } -static void stm32_fmc2_init(struct stm32_fmc2_nfc *fmc2) +static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc) { - u32 pcr = readl_relaxed(fmc2->io_base + FMC2_PCR); - u32 bcr1 = readl_relaxed(fmc2->io_base + FMC2_BCR1); + u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); + u32 bcr1 = readl_relaxed(nfc->io_base + FMC2_BCR1); /* Set CS used to undefined */ - fmc2->cs_sel = -1; + nfc->cs_sel = -1; /* Enable wait feature and nand flash memory bank */ pcr |= FMC2_PCR_PWAITEN; @@ -1419,19 +1416,19 @@ static void stm32_fmc2_init(struct stm32_fmc2_nfc *fmc2) /* Enable FMC2 controller */ bcr1 |= FMC2_BCR1_FMC2EN; - writel_relaxed(bcr1, fmc2->io_base + FMC2_BCR1); - writel_relaxed(pcr, fmc2->io_base + FMC2_PCR); - writel_relaxed(FMC2_PMEM_DEFAULT, fmc2->io_base + FMC2_PMEM); - writel_relaxed(FMC2_PATT_DEFAULT, fmc2->io_base + FMC2_PATT); + writel_relaxed(bcr1, nfc->io_base + FMC2_BCR1); + writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + writel_relaxed(FMC2_PMEM_DEFAULT, nfc->io_base + FMC2_PMEM); + writel_relaxed(FMC2_PATT_DEFAULT, nfc->io_base + FMC2_PATT); } -static void stm32_fmc2_calc_timings(struct nand_chip *chip, - const struct nand_sdr_timings *sdrt) +static void stm32_fmc2_nfc_calc_timings(struct nand_chip *chip, + const struct nand_sdr_timings *sdrt) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); struct stm32_fmc2_timings *tims = &nand->timings; - unsigned long hclk = clk_get_rate(fmc2->clk); + unsigned long hclk = clk_get_rate(nfc->clk); unsigned long hclkp = NSEC_PER_SEC / (hclk / 1000); unsigned long timing, tar, tclr, thiz, twait; unsigned long tset_mem, tset_att, thold_mem, thold_att; @@ -1555,80 +1552,79 @@ static void stm32_fmc2_calc_timings(struct nand_chip *chip, tims->thold_att = clamp_val(timing, 1, FMC2_PMEM_PATT_TIMING_MASK); } -static int stm32_fmc2_setup_interface(struct nand_chip *chip, int chipnr, - const struct nand_data_interface *conf) +static int stm32_fmc2_nfc_setup_interface(struct nand_chip *chip, int chipnr, + const struct nand_data_interface *cf) { const struct nand_sdr_timings *sdrt; - sdrt = nand_get_sdr_timings(conf); + sdrt = nand_get_sdr_timings(cf); if (IS_ERR(sdrt)) return PTR_ERR(sdrt); if (chipnr == NAND_DATA_IFACE_CHECK_ONLY) return 0; - stm32_fmc2_calc_timings(chip, sdrt); - stm32_fmc2_timings_init(chip); + stm32_fmc2_nfc_calc_timings(chip, sdrt); + stm32_fmc2_nfc_timings_init(chip); return 0; } -static int stm32_fmc2_dma_setup(struct stm32_fmc2_nfc *fmc2) +static int stm32_fmc2_nfc_dma_setup(struct stm32_fmc2_nfc *nfc) { int ret = 0; - fmc2->dma_tx_ch = dma_request_chan(fmc2->dev, "tx"); - if (IS_ERR(fmc2->dma_tx_ch)) { - ret = PTR_ERR(fmc2->dma_tx_ch); + nfc->dma_tx_ch = dma_request_chan(nfc->dev, "tx"); + if (IS_ERR(nfc->dma_tx_ch)) { + ret = PTR_ERR(nfc->dma_tx_ch); if (ret != -ENODEV) - dev_err(fmc2->dev, + dev_err(nfc->dev, "failed to request tx DMA channel: %d\n", ret); - fmc2->dma_tx_ch = NULL; + nfc->dma_tx_ch = NULL; goto err_dma; } - fmc2->dma_rx_ch = dma_request_chan(fmc2->dev, "rx"); - if (IS_ERR(fmc2->dma_rx_ch)) { - ret = PTR_ERR(fmc2->dma_rx_ch); + nfc->dma_rx_ch = dma_request_chan(nfc->dev, "rx"); + if (IS_ERR(nfc->dma_rx_ch)) { + ret = PTR_ERR(nfc->dma_rx_ch); if (ret != -ENODEV) - dev_err(fmc2->dev, + dev_err(nfc->dev, "failed to request rx DMA channel: %d\n", ret); - fmc2->dma_rx_ch = NULL; + nfc->dma_rx_ch = NULL; goto err_dma; } - fmc2->dma_ecc_ch = dma_request_chan(fmc2->dev, "ecc"); - if (IS_ERR(fmc2->dma_ecc_ch)) { - ret = PTR_ERR(fmc2->dma_ecc_ch); + nfc->dma_ecc_ch = dma_request_chan(nfc->dev, "ecc"); + if (IS_ERR(nfc->dma_ecc_ch)) { + ret = PTR_ERR(nfc->dma_ecc_ch); if (ret != -ENODEV) - dev_err(fmc2->dev, + dev_err(nfc->dev, "failed to request ecc DMA channel: %d\n", ret); - fmc2->dma_ecc_ch = NULL; + nfc->dma_ecc_ch = NULL; goto err_dma; } - ret = sg_alloc_table(&fmc2->dma_ecc_sg, FMC2_MAX_SG, GFP_KERNEL); + ret = sg_alloc_table(&nfc->dma_ecc_sg, FMC2_MAX_SG, GFP_KERNEL); if (ret) return ret; /* Allocate a buffer to store ECC status registers */ - fmc2->ecc_buf = devm_kzalloc(fmc2->dev, FMC2_MAX_ECC_BUF_LEN, - GFP_KERNEL); - if (!fmc2->ecc_buf) + nfc->ecc_buf = devm_kzalloc(nfc->dev, FMC2_MAX_ECC_BUF_LEN, GFP_KERNEL); + if (!nfc->ecc_buf) return -ENOMEM; - ret = sg_alloc_table(&fmc2->dma_data_sg, FMC2_MAX_SG, GFP_KERNEL); + ret = sg_alloc_table(&nfc->dma_data_sg, FMC2_MAX_SG, GFP_KERNEL); if (ret) return ret; - init_completion(&fmc2->dma_data_complete); - init_completion(&fmc2->dma_ecc_complete); + init_completion(&nfc->dma_data_complete); + init_completion(&nfc->dma_ecc_complete); return 0; err_dma: if (ret == -ENODEV) { - dev_warn(fmc2->dev, + dev_warn(nfc->dev, "DMAs not defined in the DT, polling mode is used\n"); ret = 0; } @@ -1636,34 +1632,34 @@ static int stm32_fmc2_dma_setup(struct stm32_fmc2_nfc *fmc2) return ret; } -static void stm32_fmc2_nand_callbacks_setup(struct nand_chip *chip) +static void stm32_fmc2_nfc_nand_callbacks_setup(struct nand_chip *chip) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); /* * Specific callbacks to read/write a page depending on * the mode (polling/sequencer) and the algo used (Hamming, BCH). */ - if (fmc2->dma_tx_ch && fmc2->dma_rx_ch && fmc2->dma_ecc_ch) { + if (nfc->dma_tx_ch && nfc->dma_rx_ch && nfc->dma_ecc_ch) { /* DMA => use sequencer mode callbacks */ - chip->ecc.correct = stm32_fmc2_sequencer_correct; - chip->ecc.write_page = stm32_fmc2_sequencer_write_page; - chip->ecc.read_page = stm32_fmc2_sequencer_read_page; - chip->ecc.write_page_raw = stm32_fmc2_sequencer_write_page_raw; - chip->ecc.read_page_raw = stm32_fmc2_sequencer_read_page_raw; + chip->ecc.correct = stm32_fmc2_nfc_seq_correct; + chip->ecc.write_page = stm32_fmc2_nfc_seq_write_page; + chip->ecc.read_page = stm32_fmc2_nfc_seq_read_page; + chip->ecc.write_page_raw = stm32_fmc2_nfc_seq_write_page_raw; + chip->ecc.read_page_raw = stm32_fmc2_nfc_seq_read_page_raw; } else { /* No DMA => use polling mode callbacks */ - chip->ecc.hwctl = stm32_fmc2_hwctl; + chip->ecc.hwctl = stm32_fmc2_nfc_hwctl; if (chip->ecc.strength == FMC2_ECC_HAM) { /* Hamming is used */ - chip->ecc.calculate = stm32_fmc2_ham_calculate; - chip->ecc.correct = stm32_fmc2_ham_correct; + chip->ecc.calculate = stm32_fmc2_nfc_ham_calculate; + chip->ecc.correct = stm32_fmc2_nfc_ham_correct; chip->ecc.options |= NAND_ECC_GENERIC_ERASED_CHECK; } else { /* BCH is used */ - chip->ecc.calculate = stm32_fmc2_bch_calculate; - chip->ecc.correct = stm32_fmc2_bch_correct; - chip->ecc.read_page = stm32_fmc2_read_page; + chip->ecc.calculate = stm32_fmc2_nfc_bch_calculate; + chip->ecc.correct = stm32_fmc2_nfc_bch_correct; + chip->ecc.read_page = stm32_fmc2_nfc_read_page; } } @@ -1676,8 +1672,8 @@ static void stm32_fmc2_nand_callbacks_setup(struct nand_chip *chip) chip->ecc.bytes = chip->options & NAND_BUSWIDTH_16 ? 8 : 7; } -static int stm32_fmc2_nand_ooblayout_ecc(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) +static int stm32_fmc2_nfc_ooblayout_ecc(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobregion) { struct nand_chip *chip = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &chip->ecc; @@ -1691,8 +1687,8 @@ static int stm32_fmc2_nand_ooblayout_ecc(struct mtd_info *mtd, int section, return 0; } -static int stm32_fmc2_nand_ooblayout_free(struct mtd_info *mtd, int section, - struct mtd_oob_region *oobregion) +static int stm32_fmc2_nfc_ooblayout_free(struct mtd_info *mtd, int section, + struct mtd_oob_region *oobregion) { struct nand_chip *chip = mtd_to_nand(mtd); struct nand_ecc_ctrl *ecc = &chip->ecc; @@ -1706,12 +1702,12 @@ static int stm32_fmc2_nand_ooblayout_free(struct mtd_info *mtd, int section, return 0; } -static const struct mtd_ooblayout_ops stm32_fmc2_nand_ooblayout_ops = { - .ecc = stm32_fmc2_nand_ooblayout_ecc, - .free = stm32_fmc2_nand_ooblayout_free, +static const struct mtd_ooblayout_ops stm32_fmc2_nfc_ooblayout_ops = { + .ecc = stm32_fmc2_nfc_ooblayout_ecc, + .free = stm32_fmc2_nfc_ooblayout_free, }; -static int stm32_fmc2_calc_ecc_bytes(int step_size, int strength) +static int stm32_fmc2_nfc_calc_ecc_bytes(int step_size, int strength) { /* Hamming */ if (strength == FMC2_ECC_HAM) @@ -1725,13 +1721,13 @@ static int stm32_fmc2_calc_ecc_bytes(int step_size, int strength) return 8; } -NAND_ECC_CAPS_SINGLE(stm32_fmc2_ecc_caps, stm32_fmc2_calc_ecc_bytes, +NAND_ECC_CAPS_SINGLE(stm32_fmc2_nfc_ecc_caps, stm32_fmc2_nfc_calc_ecc_bytes, FMC2_ECC_STEP_SIZE, FMC2_ECC_HAM, FMC2_ECC_BCH4, FMC2_ECC_BCH8); -static int stm32_fmc2_attach_chip(struct nand_chip *chip) +static int stm32_fmc2_nfc_attach_chip(struct nand_chip *chip) { - struct stm32_fmc2_nfc *fmc2 = to_stm32_nfc(chip->controller); + struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct mtd_info *mtd = nand_to_mtd(chip); int ret; @@ -1743,45 +1739,45 @@ static int stm32_fmc2_attach_chip(struct nand_chip *chip) * ECC sector size = 512 */ if (chip->ecc.mode != NAND_ECC_HW) { - dev_err(fmc2->dev, "nand_ecc_mode is not well defined in the DT\n"); + dev_err(nfc->dev, "nand_ecc_mode is not well defined in the DT\n"); return -EINVAL; } - ret = nand_ecc_choose_conf(chip, &stm32_fmc2_ecc_caps, + ret = nand_ecc_choose_conf(chip, &stm32_fmc2_nfc_ecc_caps, mtd->oobsize - FMC2_BBM_LEN); if (ret) { - dev_err(fmc2->dev, "no valid ECC settings set\n"); + dev_err(nfc->dev, "no valid ECC settings set\n"); return ret; } if (mtd->writesize / chip->ecc.size > FMC2_MAX_SG) { - dev_err(fmc2->dev, "nand page size is not supported\n"); + dev_err(nfc->dev, "nand page size is not supported\n"); return -EINVAL; } if (chip->bbt_options & NAND_BBT_USE_FLASH) chip->bbt_options |= NAND_BBT_NO_OOB; - stm32_fmc2_nand_callbacks_setup(chip); + stm32_fmc2_nfc_nand_callbacks_setup(chip); - mtd_set_ooblayout(mtd, &stm32_fmc2_nand_ooblayout_ops); + mtd_set_ooblayout(mtd, &stm32_fmc2_nfc_ooblayout_ops); if (chip->options & NAND_BUSWIDTH_16) - stm32_fmc2_set_buswidth_16(fmc2, true); + stm32_fmc2_nfc_set_buswidth_16(nfc, true); return 0; } -static const struct nand_controller_ops stm32_fmc2_nand_controller_ops = { - .attach_chip = stm32_fmc2_attach_chip, - .exec_op = stm32_fmc2_exec_op, - .setup_data_interface = stm32_fmc2_setup_interface, +static const struct nand_controller_ops stm32_fmc2_nfc_controller_ops = { + .attach_chip = stm32_fmc2_nfc_attach_chip, + .exec_op = stm32_fmc2_nfc_exec_op, + .setup_data_interface = stm32_fmc2_nfc_setup_interface, }; -static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2, - struct device_node *dn) +static int stm32_fmc2_nfc_parse_child(struct stm32_fmc2_nfc *nfc, + struct device_node *dn) { - struct stm32_fmc2_nand *nand = &fmc2->nand; + struct stm32_fmc2_nand *nand = &nfc->nand; u32 cs; int ret, i; @@ -1790,29 +1786,29 @@ static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2, nand->ncs /= sizeof(u32); if (!nand->ncs) { - dev_err(fmc2->dev, "invalid reg property size\n"); + dev_err(nfc->dev, "invalid reg property size\n"); return -EINVAL; } for (i = 0; i < nand->ncs; i++) { ret = of_property_read_u32_index(dn, "reg", i, &cs); if (ret) { - dev_err(fmc2->dev, "could not retrieve reg property: %d\n", + dev_err(nfc->dev, "could not retrieve reg property: %d\n", ret); return ret; } if (cs > FMC2_MAX_CE) { - dev_err(fmc2->dev, "invalid reg value: %d\n", cs); + dev_err(nfc->dev, "invalid reg value: %d\n", cs); return -EINVAL; } - if (fmc2->cs_assigned & BIT(cs)) { - dev_err(fmc2->dev, "cs already assigned: %d\n", cs); + if (nfc->cs_assigned & BIT(cs)) { + dev_err(nfc->dev, "cs already assigned: %d\n", cs); return -EINVAL; } - fmc2->cs_assigned |= BIT(cs); + nfc->cs_assigned |= BIT(cs); nand->cs_used[i] = cs; } @@ -1821,25 +1817,25 @@ static int stm32_fmc2_parse_child(struct stm32_fmc2_nfc *fmc2, return 0; } -static int stm32_fmc2_parse_dt(struct stm32_fmc2_nfc *fmc2) +static int stm32_fmc2_nfc_parse_dt(struct stm32_fmc2_nfc *nfc) { - struct device_node *dn = fmc2->dev->of_node; + struct device_node *dn = nfc->dev->of_node; struct device_node *child; int nchips = of_get_child_count(dn); int ret = 0; if (!nchips) { - dev_err(fmc2->dev, "NAND chip not defined\n"); + dev_err(nfc->dev, "NAND chip not defined\n"); return -EINVAL; } if (nchips > 1) { - dev_err(fmc2->dev, "too many NAND chips defined\n"); + dev_err(nfc->dev, "too many NAND chips defined\n"); return -EINVAL; } for_each_child_of_node(dn, child) { - ret = stm32_fmc2_parse_child(fmc2, child); + ret = stm32_fmc2_nfc_parse_child(nfc, child); if (ret < 0) { of_node_put(child); return ret; @@ -1849,79 +1845,79 @@ static int stm32_fmc2_parse_dt(struct stm32_fmc2_nfc *fmc2) return ret; } -static int stm32_fmc2_probe(struct platform_device *pdev) +static int stm32_fmc2_nfc_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct reset_control *rstc; - struct stm32_fmc2_nfc *fmc2; + struct stm32_fmc2_nfc *nfc; struct stm32_fmc2_nand *nand; struct resource *res; struct mtd_info *mtd; struct nand_chip *chip; int chip_cs, mem_region, ret, irq; - fmc2 = devm_kzalloc(dev, sizeof(*fmc2), GFP_KERNEL); - if (!fmc2) + nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); + if (!nfc) return -ENOMEM; - fmc2->dev = dev; - nand_controller_init(&fmc2->base); - fmc2->base.ops = &stm32_fmc2_nand_controller_ops; + nfc->dev = dev; + nand_controller_init(&nfc->base); + nfc->base.ops = &stm32_fmc2_nfc_controller_ops; - ret = stm32_fmc2_parse_dt(fmc2); + ret = stm32_fmc2_nfc_parse_dt(nfc); if (ret) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - fmc2->io_base = devm_ioremap_resource(dev, res); - if (IS_ERR(fmc2->io_base)) - return PTR_ERR(fmc2->io_base); + nfc->io_base = devm_ioremap_resource(dev, res); + if (IS_ERR(nfc->io_base)) + return PTR_ERR(nfc->io_base); - fmc2->io_phys_addr = res->start; + nfc->io_phys_addr = res->start; for (chip_cs = 0, mem_region = 1; chip_cs < FMC2_MAX_CE; chip_cs++, mem_region += 3) { - if (!(fmc2->cs_assigned & BIT(chip_cs))) + if (!(nfc->cs_assigned & BIT(chip_cs))) continue; res = platform_get_resource(pdev, IORESOURCE_MEM, mem_region); - fmc2->data_base[chip_cs] = devm_ioremap_resource(dev, res); - if (IS_ERR(fmc2->data_base[chip_cs])) - return PTR_ERR(fmc2->data_base[chip_cs]); + nfc->data_base[chip_cs] = devm_ioremap_resource(dev, res); + if (IS_ERR(nfc->data_base[chip_cs])) + return PTR_ERR(nfc->data_base[chip_cs]); - fmc2->data_phys_addr[chip_cs] = res->start; + nfc->data_phys_addr[chip_cs] = res->start; res = platform_get_resource(pdev, IORESOURCE_MEM, mem_region + 1); - fmc2->cmd_base[chip_cs] = devm_ioremap_resource(dev, res); - if (IS_ERR(fmc2->cmd_base[chip_cs])) - return PTR_ERR(fmc2->cmd_base[chip_cs]); + nfc->cmd_base[chip_cs] = devm_ioremap_resource(dev, res); + if (IS_ERR(nfc->cmd_base[chip_cs])) + return PTR_ERR(nfc->cmd_base[chip_cs]); res = platform_get_resource(pdev, IORESOURCE_MEM, mem_region + 2); - fmc2->addr_base[chip_cs] = devm_ioremap_resource(dev, res); - if (IS_ERR(fmc2->addr_base[chip_cs])) - return PTR_ERR(fmc2->addr_base[chip_cs]); + nfc->addr_base[chip_cs] = devm_ioremap_resource(dev, res); + if (IS_ERR(nfc->addr_base[chip_cs])) + return PTR_ERR(nfc->addr_base[chip_cs]); } irq = platform_get_irq(pdev, 0); if (irq < 0) return irq; - ret = devm_request_irq(dev, irq, stm32_fmc2_irq, 0, - dev_name(dev), fmc2); + ret = devm_request_irq(dev, irq, stm32_fmc2_nfc_irq, 0, + dev_name(dev), nfc); if (ret) { dev_err(dev, "failed to request irq\n"); return ret; } - init_completion(&fmc2->complete); + init_completion(&nfc->complete); - fmc2->clk = devm_clk_get(dev, NULL); - if (IS_ERR(fmc2->clk)) - return PTR_ERR(fmc2->clk); + nfc->clk = devm_clk_get(dev, NULL); + if (IS_ERR(nfc->clk)) + return PTR_ERR(nfc->clk); - ret = clk_prepare_enable(fmc2->clk); + ret = clk_prepare_enable(nfc->clk); if (ret) { dev_err(dev, "can not enable the clock\n"); return ret; @@ -1937,18 +1933,18 @@ static int stm32_fmc2_probe(struct platform_device *pdev) reset_control_deassert(rstc); } - ret = stm32_fmc2_dma_setup(fmc2); + ret = stm32_fmc2_nfc_dma_setup(nfc); if (ret) goto err_dma_setup; - stm32_fmc2_init(fmc2); + stm32_fmc2_nfc_init(nfc); - nand = &fmc2->nand; + nand = &nfc->nand; chip = &nand->chip; mtd = nand_to_mtd(chip); mtd->dev.parent = dev; - chip->controller = &fmc2->base; + chip->controller = &nfc->base; chip->options |= NAND_BUSWIDTH_AUTO | NAND_NO_SUBPAGE_WRITE | NAND_USE_BOUNCE_BUFFER; @@ -1966,7 +1962,7 @@ static int stm32_fmc2_probe(struct platform_device *pdev) if (ret) goto err_device_register; - platform_set_drvdata(pdev, fmc2); + platform_set_drvdata(pdev, nfc); return 0; @@ -1974,73 +1970,73 @@ static int stm32_fmc2_probe(struct platform_device *pdev) nand_cleanup(chip); err_dma_setup: - if (fmc2->dma_ecc_ch) - dma_release_channel(fmc2->dma_ecc_ch); - if (fmc2->dma_tx_ch) - dma_release_channel(fmc2->dma_tx_ch); - if (fmc2->dma_rx_ch) - dma_release_channel(fmc2->dma_rx_ch); + if (nfc->dma_ecc_ch) + dma_release_channel(nfc->dma_ecc_ch); + if (nfc->dma_tx_ch) + dma_release_channel(nfc->dma_tx_ch); + if (nfc->dma_rx_ch) + dma_release_channel(nfc->dma_rx_ch); - sg_free_table(&fmc2->dma_data_sg); - sg_free_table(&fmc2->dma_ecc_sg); + sg_free_table(&nfc->dma_data_sg); + sg_free_table(&nfc->dma_ecc_sg); err_clk_disable: - clk_disable_unprepare(fmc2->clk); + clk_disable_unprepare(nfc->clk); return ret; } -static int stm32_fmc2_remove(struct platform_device *pdev) +static int stm32_fmc2_nfc_remove(struct platform_device *pdev) { - struct stm32_fmc2_nfc *fmc2 = platform_get_drvdata(pdev); - struct stm32_fmc2_nand *nand = &fmc2->nand; + struct stm32_fmc2_nfc *nfc = platform_get_drvdata(pdev); + struct stm32_fmc2_nand *nand = &nfc->nand; nand_release(&nand->chip); - if (fmc2->dma_ecc_ch) - dma_release_channel(fmc2->dma_ecc_ch); - if (fmc2->dma_tx_ch) - dma_release_channel(fmc2->dma_tx_ch); - if (fmc2->dma_rx_ch) - dma_release_channel(fmc2->dma_rx_ch); + if (nfc->dma_ecc_ch) + dma_release_channel(nfc->dma_ecc_ch); + if (nfc->dma_tx_ch) + dma_release_channel(nfc->dma_tx_ch); + if (nfc->dma_rx_ch) + dma_release_channel(nfc->dma_rx_ch); - sg_free_table(&fmc2->dma_data_sg); - sg_free_table(&fmc2->dma_ecc_sg); + sg_free_table(&nfc->dma_data_sg); + sg_free_table(&nfc->dma_ecc_sg); - clk_disable_unprepare(fmc2->clk); + clk_disable_unprepare(nfc->clk); return 0; } -static int __maybe_unused stm32_fmc2_suspend(struct device *dev) +static int __maybe_unused stm32_fmc2_nfc_suspend(struct device *dev) { - struct stm32_fmc2_nfc *fmc2 = dev_get_drvdata(dev); + struct stm32_fmc2_nfc *nfc = dev_get_drvdata(dev); - clk_disable_unprepare(fmc2->clk); + clk_disable_unprepare(nfc->clk); pinctrl_pm_select_sleep_state(dev); return 0; } -static int __maybe_unused stm32_fmc2_resume(struct device *dev) +static int __maybe_unused stm32_fmc2_nfc_resume(struct device *dev) { - struct stm32_fmc2_nfc *fmc2 = dev_get_drvdata(dev); - struct stm32_fmc2_nand *nand = &fmc2->nand; + struct stm32_fmc2_nfc *nfc = dev_get_drvdata(dev); + struct stm32_fmc2_nand *nand = &nfc->nand; int chip_cs, ret; pinctrl_pm_select_default_state(dev); - ret = clk_prepare_enable(fmc2->clk); + ret = clk_prepare_enable(nfc->clk); if (ret) { dev_err(dev, "can not enable the clock\n"); return ret; } - stm32_fmc2_init(fmc2); + stm32_fmc2_nfc_init(nfc); for (chip_cs = 0; chip_cs < FMC2_MAX_CE; chip_cs++) { - if (!(fmc2->cs_assigned & BIT(chip_cs))) + if (!(nfc->cs_assigned & BIT(chip_cs))) continue; nand_reset(&nand->chip, chip_cs); @@ -2049,27 +2045,27 @@ static int __maybe_unused stm32_fmc2_resume(struct device *dev) return 0; } -static SIMPLE_DEV_PM_OPS(stm32_fmc2_pm_ops, stm32_fmc2_suspend, - stm32_fmc2_resume); +static SIMPLE_DEV_PM_OPS(stm32_fmc2_nfc_pm_ops, stm32_fmc2_nfc_suspend, + stm32_fmc2_nfc_resume); -static const struct of_device_id stm32_fmc2_match[] = { +static const struct of_device_id stm32_fmc2_nfc_match[] = { {.compatible = "st,stm32mp15-fmc2"}, {} }; -MODULE_DEVICE_TABLE(of, stm32_fmc2_match); +MODULE_DEVICE_TABLE(of, stm32_fmc2_nfc_match); -static struct platform_driver stm32_fmc2_driver = { - .probe = stm32_fmc2_probe, - .remove = stm32_fmc2_remove, +static struct platform_driver stm32_fmc2_nfc_driver = { + .probe = stm32_fmc2_nfc_probe, + .remove = stm32_fmc2_nfc_remove, .driver = { - .name = "stm32_fmc2_nand", - .of_match_table = stm32_fmc2_match, - .pm = &stm32_fmc2_pm_ops, + .name = "stm32_fmc2_nfc", + .of_match_table = stm32_fmc2_nfc_match, + .pm = &stm32_fmc2_nfc_pm_ops, }, }; -module_platform_driver(stm32_fmc2_driver); +module_platform_driver(stm32_fmc2_nfc_driver); -MODULE_ALIAS("platform:stm32_fmc2_nand"); +MODULE_ALIAS("platform:stm32_fmc2_nfc"); MODULE_AUTHOR("Christophe Kerello "); -MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 nand driver"); +MODULE_DESCRIPTION("STMicroelectronics STM32 FMC2 nfc driver"); MODULE_LICENSE("GPL v2"); From patchwork Wed Apr 15 15:57:32 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Kerello X-Patchwork-Id: 201987 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id DB656C2BB55 for ; Wed, 15 Apr 2020 15:59:31 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id AC9BD20857 for ; Wed, 15 Apr 2020 15:59:31 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=st.com header.i=@st.com header.b="rfReXrFG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1415046AbgDOP72 (ORCPT ); Wed, 15 Apr 2020 11:59:28 -0400 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:44340 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1415027AbgDOP7Z (ORCPT ); Wed, 15 Apr 2020 11:59:25 -0400 Received: from pps.filterd (m0046661.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03FFXqhu002772; Wed, 15 Apr 2020 17:59:03 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=CqyYyg1hqEyPGJdOAAKlTdHo595F6ovJE5aSd4s3ldE=; b=rfReXrFGXDvaVesoS+JEsXG4A9dF8c9oVtrDxL4ZcK1EedXhekqgWPx+KRZUltsy9e6a 999X3qwQ/fTSWmEUIPoc3R0zctAa0Ez5WJZuQh3341L6jxYW1mJ9+K3Ty51YrrCxgQU0 XW/+MiDm9vqHLML69vpfqRGsHgbQqZLBLDxfn891RfhpxzLP0Dc9EEETxcK0d6WnyplK Qn7gbneT0z7igwhckna9nETcvWB7wk6QYwyeBypJACTZr44UgPaxzApwLpvGQRnLMpzB Lj0MhdGUdE/q6BAsO7wZ8QbqBc7P93dF0qKzt99yJmUXISScoiB4A3lAWHSNK3azmMks kA== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 30dn75mxhf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 Apr 2020 17:59:03 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id E77E6100034; Wed, 15 Apr 2020 17:59:02 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag6node2.st.com [10.75.127.17]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id D5BB62B213D; Wed, 15 Apr 2020 17:59:02 +0200 (CEST) Received: from localhost (10.75.127.50) by SFHDAG6NODE2.st.com (10.75.127.17) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Wed, 15 Apr 2020 17:59:01 +0200 From: Christophe Kerello To: , , , , , , CC: , , , , , Christophe Kerello Subject: [PATCH v2 08/12] mtd: rawnand: stm32_fmc2: use FIELD_PREP/FIELD_GET macros Date: Wed, 15 Apr 2020 17:57:32 +0200 Message-ID: <1586966256-29548-9-git-send-email-christophe.kerello@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> References: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.50] X-ClientProxiedBy: SFHDAG8NODE1.st.com (10.75.127.22) To SFHDAG6NODE2.st.com (10.75.127.17) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-04-15_05:2020-04-14,2020-04-15 signatures=0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch removes custom macros and uses FIELD_PREP and FIELD_GET macros. Signed-off-by: Christophe Kerello --- drivers/mtd/nand/raw/stm32_fmc2_nand.c | 177 ++++++++++++++++----------------- 1 file changed, 85 insertions(+), 92 deletions(-) diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index 9ce405d..e0a7c08 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -4,6 +4,7 @@ * Author: Christophe Kerello */ +#include #include #include #include @@ -84,20 +85,16 @@ /* Register: FMC2_PCR */ #define FMC2_PCR_PWAITEN BIT(1) #define FMC2_PCR_PBKEN BIT(2) -#define FMC2_PCR_PWID_MASK GENMASK(5, 4) -#define FMC2_PCR_PWID(x) (((x) & 0x3) << 4) +#define FMC2_PCR_PWID GENMASK(5, 4) #define FMC2_PCR_PWID_BUSWIDTH_8 0 #define FMC2_PCR_PWID_BUSWIDTH_16 1 #define FMC2_PCR_ECCEN BIT(6) #define FMC2_PCR_ECCALG BIT(8) -#define FMC2_PCR_TCLR_MASK GENMASK(12, 9) -#define FMC2_PCR_TCLR(x) (((x) & 0xf) << 9) +#define FMC2_PCR_TCLR GENMASK(12, 9) #define FMC2_PCR_TCLR_DEFAULT 0xf -#define FMC2_PCR_TAR_MASK GENMASK(16, 13) -#define FMC2_PCR_TAR(x) (((x) & 0xf) << 13) +#define FMC2_PCR_TAR GENMASK(16, 13) #define FMC2_PCR_TAR_DEFAULT 0xf -#define FMC2_PCR_ECCSS_MASK GENMASK(19, 17) -#define FMC2_PCR_ECCSS(x) (((x) & 0x7) << 17) +#define FMC2_PCR_ECCSS GENMASK(19, 17) #define FMC2_PCR_ECCSS_512 1 #define FMC2_PCR_ECCSS_2048 3 #define FMC2_PCR_BCHECC BIT(24) @@ -107,17 +104,17 @@ #define FMC2_SR_NWRF BIT(6) /* Register: FMC2_PMEM */ -#define FMC2_PMEM_MEMSET(x) (((x) & 0xff) << 0) -#define FMC2_PMEM_MEMWAIT(x) (((x) & 0xff) << 8) -#define FMC2_PMEM_MEMHOLD(x) (((x) & 0xff) << 16) -#define FMC2_PMEM_MEMHIZ(x) (((x) & 0xff) << 24) +#define FMC2_PMEM_MEMSET GENMASK(7, 0) +#define FMC2_PMEM_MEMWAIT GENMASK(15, 8) +#define FMC2_PMEM_MEMHOLD GENMASK(23, 16) +#define FMC2_PMEM_MEMHIZ GENMASK(31, 24) #define FMC2_PMEM_DEFAULT 0x0a0a0a0a /* Register: FMC2_PATT */ -#define FMC2_PATT_ATTSET(x) (((x) & 0xff) << 0) -#define FMC2_PATT_ATTWAIT(x) (((x) & 0xff) << 8) -#define FMC2_PATT_ATTHOLD(x) (((x) & 0xff) << 16) -#define FMC2_PATT_ATTHIZ(x) (((x) & 0xff) << 24) +#define FMC2_PATT_ATTSET GENMASK(7, 0) +#define FMC2_PATT_ATTWAIT GENMASK(15, 8) +#define FMC2_PATT_ATTHOLD GENMASK(23, 16) +#define FMC2_PATT_ATTHIZ GENMASK(31, 24) #define FMC2_PATT_DEFAULT 0x0a0a0a0a /* Register: FMC2_ISR */ @@ -132,9 +129,9 @@ /* Register: FMC2_CSQCFGR1 */ #define FMC2_CSQCFGR1_CMD2EN BIT(1) #define FMC2_CSQCFGR1_DMADEN BIT(2) -#define FMC2_CSQCFGR1_ACYNBR(x) (((x) & 0x7) << 4) -#define FMC2_CSQCFGR1_CMD1(x) (((x) & 0xff) << 8) -#define FMC2_CSQCFGR1_CMD2(x) (((x) & 0xff) << 16) +#define FMC2_CSQCFGR1_ACYNBR GENMASK(6, 4) +#define FMC2_CSQCFGR1_CMD1 GENMASK(15, 8) +#define FMC2_CSQCFGR1_CMD2 GENMASK(23, 16) #define FMC2_CSQCFGR1_CMD1T BIT(24) #define FMC2_CSQCFGR1_CMD2T BIT(25) @@ -142,13 +139,13 @@ #define FMC2_CSQCFGR2_SQSDTEN BIT(0) #define FMC2_CSQCFGR2_RCMD2EN BIT(1) #define FMC2_CSQCFGR2_DMASEN BIT(2) -#define FMC2_CSQCFGR2_RCMD1(x) (((x) & 0xff) << 8) -#define FMC2_CSQCFGR2_RCMD2(x) (((x) & 0xff) << 16) +#define FMC2_CSQCFGR2_RCMD1 GENMASK(15, 8) +#define FMC2_CSQCFGR2_RCMD2 GENMASK(23, 16) #define FMC2_CSQCFGR2_RCMD1T BIT(24) #define FMC2_CSQCFGR2_RCMD2T BIT(25) /* Register: FMC2_CSQCFGR3 */ -#define FMC2_CSQCFGR3_SNBR(x) (((x) & 0x1f) << 8) +#define FMC2_CSQCFGR3_SNBR GENMASK(13, 8) #define FMC2_CSQCFGR3_AC1T BIT(16) #define FMC2_CSQCFGR3_AC2T BIT(17) #define FMC2_CSQCFGR3_AC3T BIT(18) @@ -159,15 +156,15 @@ #define FMC2_CSQCFGR3_RAC2T BIT(23) /* Register: FMC2_CSQCAR1 */ -#define FMC2_CSQCAR1_ADDC1(x) (((x) & 0xff) << 0) -#define FMC2_CSQCAR1_ADDC2(x) (((x) & 0xff) << 8) -#define FMC2_CSQCAR1_ADDC3(x) (((x) & 0xff) << 16) -#define FMC2_CSQCAR1_ADDC4(x) (((x) & 0xff) << 24) +#define FMC2_CSQCAR1_ADDC1 GENMASK(7, 0) +#define FMC2_CSQCAR1_ADDC2 GENMASK(15, 8) +#define FMC2_CSQCAR1_ADDC3 GENMASK(23, 16) +#define FMC2_CSQCAR1_ADDC4 GENMASK(31, 24) /* Register: FMC2_CSQCAR2 */ -#define FMC2_CSQCAR2_ADDC5(x) (((x) & 0xff) << 0) -#define FMC2_CSQCAR2_NANDCEN(x) (((x) & 0x3) << 10) -#define FMC2_CSQCAR2_SAO(x) (((x) & 0xffff) << 16) +#define FMC2_CSQCAR2_ADDC5 GENMASK(7, 0) +#define FMC2_CSQCAR2_NANDCEN GENMASK(11, 10) +#define FMC2_CSQCAR2_SAO GENMASK(31, 16) /* Register: FMC2_CSQIER */ #define FMC2_CSQIER_TCIE BIT(0) @@ -188,28 +185,23 @@ /* Register: FMC2_BCHDSR0 */ #define FMC2_BCHDSR0_DUE BIT(0) #define FMC2_BCHDSR0_DEF BIT(1) -#define FMC2_BCHDSR0_DEN_MASK GENMASK(7, 4) -#define FMC2_BCHDSR0_DEN_SHIFT 4 +#define FMC2_BCHDSR0_DEN GENMASK(7, 4) /* Register: FMC2_BCHDSR1 */ -#define FMC2_BCHDSR1_EBP1_MASK GENMASK(12, 0) -#define FMC2_BCHDSR1_EBP2_MASK GENMASK(28, 16) -#define FMC2_BCHDSR1_EBP2_SHIFT 16 +#define FMC2_BCHDSR1_EBP1 GENMASK(12, 0) +#define FMC2_BCHDSR1_EBP2 GENMASK(28, 16) /* Register: FMC2_BCHDSR2 */ -#define FMC2_BCHDSR2_EBP3_MASK GENMASK(12, 0) -#define FMC2_BCHDSR2_EBP4_MASK GENMASK(28, 16) -#define FMC2_BCHDSR2_EBP4_SHIFT 16 +#define FMC2_BCHDSR2_EBP3 GENMASK(12, 0) +#define FMC2_BCHDSR2_EBP4 GENMASK(28, 16) /* Register: FMC2_BCHDSR3 */ -#define FMC2_BCHDSR3_EBP5_MASK GENMASK(12, 0) -#define FMC2_BCHDSR3_EBP6_MASK GENMASK(28, 16) -#define FMC2_BCHDSR3_EBP6_SHIFT 16 +#define FMC2_BCHDSR3_EBP5 GENMASK(12, 0) +#define FMC2_BCHDSR3_EBP6 GENMASK(28, 16) /* Register: FMC2_BCHDSR4 */ -#define FMC2_BCHDSR4_EBP7_MASK GENMASK(12, 0) -#define FMC2_BCHDSR4_EBP8_MASK GENMASK(28, 16) -#define FMC2_BCHDSR4_EBP8_SHIFT 16 +#define FMC2_BCHDSR4_EBP7 GENMASK(12, 0) +#define FMC2_BCHDSR4_EBP8 GENMASK(28, 16) enum stm32_fmc2_ecc { FMC2_ECC_HAM = 1, @@ -289,22 +281,22 @@ static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip) u32 pmem, patt; /* Set tclr/tar timings */ - pcr &= ~FMC2_PCR_TCLR_MASK; - pcr |= FMC2_PCR_TCLR(timings->tclr); - pcr &= ~FMC2_PCR_TAR_MASK; - pcr |= FMC2_PCR_TAR(timings->tar); + pcr &= ~FMC2_PCR_TCLR; + pcr |= FIELD_PREP(FMC2_PCR_TCLR, timings->tclr); + pcr &= ~FMC2_PCR_TAR; + pcr |= FIELD_PREP(FMC2_PCR_TAR, timings->tar); /* Set tset/twait/thold/thiz timings in common bank */ - pmem = FMC2_PMEM_MEMSET(timings->tset_mem); - pmem |= FMC2_PMEM_MEMWAIT(timings->twait); - pmem |= FMC2_PMEM_MEMHOLD(timings->thold_mem); - pmem |= FMC2_PMEM_MEMHIZ(timings->thiz); + pmem = FIELD_PREP(FMC2_PMEM_MEMSET, timings->tset_mem); + pmem |= FIELD_PREP(FMC2_PMEM_MEMWAIT, timings->twait); + pmem |= FIELD_PREP(FMC2_PMEM_MEMHOLD, timings->thold_mem); + pmem |= FIELD_PREP(FMC2_PMEM_MEMHIZ, timings->thiz); /* Set tset/twait/thold/thiz timings in attribut bank */ - patt = FMC2_PATT_ATTSET(timings->tset_att); - patt |= FMC2_PATT_ATTWAIT(timings->twait); - patt |= FMC2_PATT_ATTHOLD(timings->thold_att); - patt |= FMC2_PATT_ATTHIZ(timings->thiz); + patt = FIELD_PREP(FMC2_PATT_ATTSET, timings->tset_att); + patt |= FIELD_PREP(FMC2_PATT_ATTWAIT, timings->twait); + patt |= FIELD_PREP(FMC2_PATT_ATTHOLD, timings->thold_att); + patt |= FIELD_PREP(FMC2_PATT_ATTHIZ, timings->thiz); writel_relaxed(pcr, nfc->io_base + FMC2_PCR); writel_relaxed(pmem, nfc->io_base + FMC2_PMEM); @@ -327,13 +319,13 @@ static void stm32_fmc2_nfc_setup(struct nand_chip *chip) } /* Set buswidth */ - pcr &= ~FMC2_PCR_PWID_MASK; + pcr &= ~FMC2_PCR_PWID; if (chip->options & NAND_BUSWIDTH_16) - pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16); + pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16); /* Set ECC sector size */ - pcr &= ~FMC2_PCR_ECCSS_MASK; - pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_512); + pcr &= ~FMC2_PCR_ECCSS; + pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_512); writel_relaxed(pcr, nfc->io_base + FMC2_PCR); } @@ -403,9 +395,9 @@ static void stm32_fmc2_nfc_set_buswidth_16(struct stm32_fmc2_nfc *nfc, bool set) { u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); - pcr &= ~FMC2_PCR_PWID_MASK; + pcr &= ~FMC2_PCR_PWID; if (set) - pcr |= FMC2_PCR_PWID(FMC2_PCR_PWID_BUSWIDTH_16); + pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16); writel_relaxed(pcr, nfc->io_base + FMC2_PCR); } @@ -659,16 +651,16 @@ static int stm32_fmc2_nfc_bch_decode(int eccsize, u8 *dat, u32 *ecc_sta) if (unlikely(bchdsr0 & FMC2_BCHDSR0_DUE)) return -EBADMSG; - pos[0] = bchdsr1 & FMC2_BCHDSR1_EBP1_MASK; - pos[1] = (bchdsr1 & FMC2_BCHDSR1_EBP2_MASK) >> FMC2_BCHDSR1_EBP2_SHIFT; - pos[2] = bchdsr2 & FMC2_BCHDSR2_EBP3_MASK; - pos[3] = (bchdsr2 & FMC2_BCHDSR2_EBP4_MASK) >> FMC2_BCHDSR2_EBP4_SHIFT; - pos[4] = bchdsr3 & FMC2_BCHDSR3_EBP5_MASK; - pos[5] = (bchdsr3 & FMC2_BCHDSR3_EBP6_MASK) >> FMC2_BCHDSR3_EBP6_SHIFT; - pos[6] = bchdsr4 & FMC2_BCHDSR4_EBP7_MASK; - pos[7] = (bchdsr4 & FMC2_BCHDSR4_EBP8_MASK) >> FMC2_BCHDSR4_EBP8_SHIFT; + pos[0] = FIELD_GET(FMC2_BCHDSR1_EBP1, bchdsr1); + pos[1] = FIELD_GET(FMC2_BCHDSR1_EBP2, bchdsr1); + pos[2] = FIELD_GET(FMC2_BCHDSR2_EBP3, bchdsr2); + pos[3] = FIELD_GET(FMC2_BCHDSR2_EBP4, bchdsr2); + pos[4] = FIELD_GET(FMC2_BCHDSR3_EBP5, bchdsr3); + pos[5] = FIELD_GET(FMC2_BCHDSR3_EBP6, bchdsr3); + pos[6] = FIELD_GET(FMC2_BCHDSR4_EBP7, bchdsr4); + pos[7] = FIELD_GET(FMC2_BCHDSR4_EBP8, bchdsr4); - den = (bchdsr0 & FMC2_BCHDSR0_DEN_MASK) >> FMC2_BCHDSR0_DEN_SHIFT; + den = FIELD_GET(FMC2_BCHDSR0_DEN, bchdsr0); for (i = 0; i < den; i++) { if (pos[i] < eccsize * 8) { change_bit(pos[i], (unsigned long *)dat); @@ -790,11 +782,11 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, */ csqcfgr1 = FMC2_CSQCFGR1_DMADEN | FMC2_CSQCFGR1_CMD1T; if (write_data) - csqcfgr1 |= FMC2_CSQCFGR1_CMD1(NAND_CMD_SEQIN); + csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_SEQIN); else - csqcfgr1 |= FMC2_CSQCFGR1_CMD1(NAND_CMD_READ0) | + csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_READ0) | FMC2_CSQCFGR1_CMD2EN | - FMC2_CSQCFGR1_CMD2(NAND_CMD_READSTART) | + FIELD_PREP(FMC2_CSQCFGR1_CMD2, NAND_CMD_READSTART) | FMC2_CSQCFGR1_CMD2T; /* @@ -804,11 +796,12 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * - Set timings */ if (write_data) - csqcfgr2 = FMC2_CSQCFGR2_RCMD1(NAND_CMD_RNDIN); + csqcfgr2 = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDIN); else - csqcfgr2 = FMC2_CSQCFGR2_RCMD1(NAND_CMD_RNDOUT) | + csqcfgr2 = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDOUT) | FMC2_CSQCFGR2_RCMD2EN | - FMC2_CSQCFGR2_RCMD2(NAND_CMD_RNDOUTSTART) | + FIELD_PREP(FMC2_CSQCFGR2_RCMD2, + NAND_CMD_RNDOUTSTART) | FMC2_CSQCFGR2_RCMD1T | FMC2_CSQCFGR2_RCMD2T; if (!raw) { @@ -820,7 +813,7 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * - Set the number of sectors to be written * - Set timings */ - csqcfgr3 = FMC2_CSQCFGR3_SNBR(chip->ecc.steps - 1); + csqcfgr3 = FIELD_PREP(FMC2_CSQCFGR3_SNBR, chip->ecc.steps - 1); if (write_data) { csqcfgr3 |= FMC2_CSQCFGR3_RAC2T; if (chip->options & NAND_ROW_ADDR_3) @@ -834,8 +827,8 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * Byte 1 and byte 2 => column, we start at 0x0 * Byte 3 and byte 4 => page */ - csqar1 = FMC2_CSQCAR1_ADDC3(page); - csqar1 |= FMC2_CSQCAR1_ADDC4(page >> 8); + csqar1 = FIELD_PREP(FMC2_CSQCAR1_ADDC3, page); + csqar1 |= FIELD_PREP(FMC2_CSQCAR1_ADDC4, page >> 8); /* * - Set chip enable number @@ -843,16 +836,16 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * - Calculate the number of address cycles to be issued * - Set byte 5 of address cycle if needed */ - csqar2 = FMC2_CSQCAR2_NANDCEN(nfc->cs_sel); + csqar2 = FIELD_PREP(FMC2_CSQCAR2_NANDCEN, nfc->cs_sel); if (chip->options & NAND_BUSWIDTH_16) - csqar2 |= FMC2_CSQCAR2_SAO(ecc_offset >> 1); + csqar2 |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset >> 1); else - csqar2 |= FMC2_CSQCAR2_SAO(ecc_offset); + csqar2 |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset); if (chip->options & NAND_ROW_ADDR_3) { - csqcfgr1 |= FMC2_CSQCFGR1_ACYNBR(5); - csqar2 |= FMC2_CSQCAR2_ADDC5(page >> 16); + csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 5); + csqar2 |= FIELD_PREP(FMC2_CSQCAR2_ADDC5, page >> 16); } else { - csqcfgr1 |= FMC2_CSQCFGR1_ACYNBR(4); + csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 4); } writel_relaxed(csqcfgr1, nfc->io_base + FMC2_CSQCFGR1); @@ -1393,7 +1386,7 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc) pcr |= FMC2_PCR_PBKEN; /* Set buswidth to 8 bits mode for identification */ - pcr &= ~FMC2_PCR_PWID_MASK; + pcr &= ~FMC2_PCR_PWID; /* ECC logic is disabled */ pcr &= ~FMC2_PCR_ECCEN; @@ -1404,14 +1397,14 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc) pcr &= ~FMC2_PCR_WEN; /* Set default ECC sector size */ - pcr &= ~FMC2_PCR_ECCSS_MASK; - pcr |= FMC2_PCR_ECCSS(FMC2_PCR_ECCSS_2048); + pcr &= ~FMC2_PCR_ECCSS; + pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_2048); /* Set default tclr/tar timings */ - pcr &= ~FMC2_PCR_TCLR_MASK; - pcr |= FMC2_PCR_TCLR(FMC2_PCR_TCLR_DEFAULT); - pcr &= ~FMC2_PCR_TAR_MASK; - pcr |= FMC2_PCR_TAR(FMC2_PCR_TAR_DEFAULT); + pcr &= ~FMC2_PCR_TCLR; + pcr |= FIELD_PREP(FMC2_PCR_TCLR, FMC2_PCR_TCLR_DEFAULT); + pcr &= ~FMC2_PCR_TAR; + pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT); /* Enable FMC2 controller */ bcr1 |= FMC2_BCR1_FMC2EN; From patchwork Wed Apr 15 15:57:34 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christophe Kerello X-Patchwork-Id: 201986 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.8 required=3.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU, HEADER_FROM_DIFFERENT_DOMAINS, INCLUDES_PATCH, MAILING_LIST_MULTI, SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 84E91C2BA19 for ; Wed, 15 Apr 2020 15:59:44 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3E5F220771 for ; Wed, 15 Apr 2020 15:59:44 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=st.com header.i=@st.com header.b="aAQmrtxR" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1415061AbgDOP7m (ORCPT ); Wed, 15 Apr 2020 11:59:42 -0400 Received: from mx08-00178001.pphosted.com ([91.207.212.93]:28068 "EHLO mx07-00178001.pphosted.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1415052AbgDOP7h (ORCPT ); Wed, 15 Apr 2020 11:59:37 -0400 Received: from pps.filterd (m0046660.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.16.0.42/8.16.0.42) with SMTP id 03FFbV2V021305; Wed, 15 Apr 2020 17:59:16 +0200 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=st.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=STMicroelectronics; bh=MAAvXOpPFKkjpOaCEBbUbgZpac918EwI2tYNZN7FjEw=; b=aAQmrtxRGR6ABz6w95fGuTDIUrhsug9Bl9O7W+rwnJN8o+wvJDptPbu66/bFkMYTV2C/ MbHG1ubDnVpC56fpf3fJs5tp6SBep1Vyhm9NAmVRTWQ8PSqbKqwGllhLWKTiZjkL7UOr zVdBrOT6UOf1cBBnhHDYyOQ8vpQtHDXehnlCx8kfNEE7ZX6REaeptfovjRTFoiCygkq1 tJeVY3Y/FxLu9jpVpgdBAHK+QZoCip/jgyrJmg2QsmepyUQ1NbOwKuE2+mWfmQ0xumBS 4S2/B/2Yc+vTEgDW3sgbX5ePzNmbXVlLdJIWOAhcVkiXAA2jkNu6MEzmPgKBNFbv8RwS wA== Received: from beta.dmz-eu.st.com (beta.dmz-eu.st.com [164.129.1.35]) by mx07-00178001.pphosted.com with ESMTP id 30dn8rvx2d-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Wed, 15 Apr 2020 17:59:16 +0200 Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-eu.st.com (STMicroelectronics) with ESMTP id E0D86100034; Wed, 15 Apr 2020 17:59:15 +0200 (CEST) Received: from Webmail-eu.st.com (sfhdag6node2.st.com [10.75.127.17]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id D06F92AF597; Wed, 15 Apr 2020 17:59:15 +0200 (CEST) Received: from localhost (10.75.127.49) by SFHDAG6NODE2.st.com (10.75.127.17) with Microsoft SMTP Server (TLS) id 15.0.1347.2; Wed, 15 Apr 2020 17:59:13 +0200 From: Christophe Kerello To: , , , , , , CC: , , , , , Christophe Kerello Subject: [PATCH v2 10/12] mtd: rawnand: stm32_fmc2: use regmap APIs Date: Wed, 15 Apr 2020 17:57:34 +0200 Message-ID: <1586966256-29548-11-git-send-email-christophe.kerello@st.com> X-Mailer: git-send-email 1.9.1 In-Reply-To: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> References: <1586966256-29548-1-git-send-email-christophe.kerello@st.com> MIME-Version: 1.0 X-Originating-IP: [10.75.127.49] X-ClientProxiedBy: SFHDAG5NODE2.st.com (10.75.127.14) To SFHDAG6NODE2.st.com (10.75.127.17) X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:6.0.138, 18.0.676 definitions=2020-04-15_05:2020-04-14,2020-04-15 signatures=0 Sender: devicetree-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: devicetree@vger.kernel.org This patch uses regmap APIs to access all FMC2 registers. Signed-off-by: Christophe Kerello --- Changes in v2: - use of regmap_bulk_write/regmap_bulk_read APIs drivers/mtd/nand/raw/Kconfig | 2 + drivers/mtd/nand/raw/stm32_fmc2_nand.c | 267 +++++++++++++++------------------ 2 files changed, 126 insertions(+), 143 deletions(-) diff --git a/drivers/mtd/nand/raw/Kconfig b/drivers/mtd/nand/raw/Kconfig index a80a46b..12b715a 100644 --- a/drivers/mtd/nand/raw/Kconfig +++ b/drivers/mtd/nand/raw/Kconfig @@ -419,6 +419,8 @@ config MTD_NAND_TEGRA config MTD_NAND_STM32_FMC2 tristate "Support for NAND controller on STM32MP SoCs" depends on MACH_STM32MP157 || COMPILE_TEST + select REGMAP + select REGMAP_MMIO help Enables support for NAND Flash chips on SoCs containing the FMC2 NAND controller. This controller is found on STM32MP SoCs. diff --git a/drivers/mtd/nand/raw/stm32_fmc2_nand.c b/drivers/mtd/nand/raw/stm32_fmc2_nand.c index 9f12a59..a3c2a11 100644 --- a/drivers/mtd/nand/raw/stm32_fmc2_nand.c +++ b/drivers/mtd/nand/raw/stm32_fmc2_nand.c @@ -51,6 +51,16 @@ #define FMC2_PMEM_DEFAULT 0x0a0a0a0a #define FMC2_PATT_DEFAULT 0x0a0a0a0a +/* Regmap registers configuration */ +#define FMC2_MAX_REGISTER 0x3fc + +static const struct regmap_config stm32_fmc2_regmap_cfg = { + .reg_bits = 32, + .val_bits = 32, + .reg_stride = sizeof(u32), + .max_register = FMC2_MAX_REGISTER, +}; + enum stm32_fmc2_ecc { FMC2_ECC_HAM = 1, FMC2_ECC_BCH4 = 4, @@ -90,7 +100,7 @@ struct stm32_fmc2_nfc { struct nand_controller base; struct stm32_fmc2_nand nand; struct device *dev; - void __iomem *io_base; + struct regmap *regmap; void __iomem *data_base[FMC2_MAX_CE]; void __iomem *cmd_base[FMC2_MAX_CE]; void __iomem *addr_base[FMC2_MAX_CE]; @@ -125,40 +135,37 @@ static void stm32_fmc2_nfc_timings_init(struct nand_chip *chip) struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct stm32_fmc2_nand *nand = to_fmc2_nand(chip); struct stm32_fmc2_timings *timings = &nand->timings; - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); u32 pmem, patt; /* Set tclr/tar timings */ - pcr &= ~FMC2_PCR_TCLR; - pcr |= FIELD_PREP(FMC2_PCR_TCLR, timings->tclr); - pcr &= ~FMC2_PCR_TAR; - pcr |= FIELD_PREP(FMC2_PCR_TAR, timings->tar); + regmap_update_bits(nfc->regmap, FMC2_PCR, + FMC2_PCR_TCLR | FMC2_PCR_TAR, + FIELD_PREP(FMC2_PCR_TCLR, timings->tclr) | + FIELD_PREP(FMC2_PCR_TAR, timings->tar)); /* Set tset/twait/thold/thiz timings in common bank */ pmem = FIELD_PREP(FMC2_PMEM_MEMSET, timings->tset_mem); pmem |= FIELD_PREP(FMC2_PMEM_MEMWAIT, timings->twait); pmem |= FIELD_PREP(FMC2_PMEM_MEMHOLD, timings->thold_mem); pmem |= FIELD_PREP(FMC2_PMEM_MEMHIZ, timings->thiz); + regmap_write(nfc->regmap, FMC2_PMEM, pmem); /* Set tset/twait/thold/thiz timings in attribut bank */ patt = FIELD_PREP(FMC2_PATT_ATTSET, timings->tset_att); patt |= FIELD_PREP(FMC2_PATT_ATTWAIT, timings->twait); patt |= FIELD_PREP(FMC2_PATT_ATTHOLD, timings->thold_att); patt |= FIELD_PREP(FMC2_PATT_ATTHIZ, timings->thiz); - - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); - writel_relaxed(pmem, nfc->io_base + FMC2_PMEM); - writel_relaxed(patt, nfc->io_base + FMC2_PATT); + regmap_write(nfc->regmap, FMC2_PATT, patt); } static void stm32_fmc2_nfc_setup(struct nand_chip *chip) { struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); + u32 pcr = 0, pcr_mask; /* Configure ECC algorithm (default configuration is Hamming) */ - pcr &= ~FMC2_PCR_ECCALG; - pcr &= ~FMC2_PCR_BCHECC; + pcr_mask = FMC2_PCR_ECCALG; + pcr_mask |= FMC2_PCR_BCHECC; if (chip->ecc.strength == FMC2_ECC_BCH8) { pcr |= FMC2_PCR_ECCALG; pcr |= FMC2_PCR_BCHECC; @@ -167,15 +174,15 @@ static void stm32_fmc2_nfc_setup(struct nand_chip *chip) } /* Set buswidth */ - pcr &= ~FMC2_PCR_PWID; + pcr_mask |= FMC2_PCR_PWID; if (chip->options & NAND_BUSWIDTH_16) pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16); /* Set ECC sector size */ - pcr &= ~FMC2_PCR_ECCSS; + pcr_mask |= FMC2_PCR_ECCSS; pcr |= FIELD_PREP(FMC2_PCR_ECCSS, FMC2_PCR_ECCSS_512); - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + regmap_update_bits(nfc->regmap, FMC2_PCR, pcr_mask, pcr); } static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr) @@ -241,81 +248,63 @@ static int stm32_fmc2_nfc_select_chip(struct nand_chip *chip, int chipnr) static void stm32_fmc2_nfc_set_buswidth_16(struct stm32_fmc2_nfc *nfc, bool set) { - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); + u32 pcr; - pcr &= ~FMC2_PCR_PWID; - if (set) - pcr |= FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16); - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + pcr = set ? FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_16) : + FIELD_PREP(FMC2_PCR_PWID, FMC2_PCR_PWID_BUSWIDTH_8); + + regmap_update_bits(nfc->regmap, FMC2_PCR, FMC2_PCR_PWID, pcr); } static void stm32_fmc2_nfc_set_ecc(struct stm32_fmc2_nfc *nfc, bool enable) { - u32 pcr = readl(nfc->io_base + FMC2_PCR); - - pcr &= ~FMC2_PCR_ECCEN; - if (enable) - pcr |= FMC2_PCR_ECCEN; - writel(pcr, nfc->io_base + FMC2_PCR); + regmap_update_bits(nfc->regmap, FMC2_PCR, FMC2_PCR_ECCEN, + enable ? FMC2_PCR_ECCEN : 0); } -static inline void stm32_fmc2_nfc_enable_seq_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_enable_seq_irq(struct stm32_fmc2_nfc *nfc) { - u32 csqier = readl_relaxed(nfc->io_base + FMC2_CSQIER); - - csqier |= FMC2_CSQIER_TCIE; - nfc->irq_state = FMC2_IRQ_SEQ; - writel_relaxed(csqier, nfc->io_base + FMC2_CSQIER); + regmap_update_bits(nfc->regmap, FMC2_CSQIER, + FMC2_CSQIER_TCIE, FMC2_CSQIER_TCIE); } -static inline void stm32_fmc2_nfc_disable_seq_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_disable_seq_irq(struct stm32_fmc2_nfc *nfc) { - u32 csqier = readl_relaxed(nfc->io_base + FMC2_CSQIER); - - csqier &= ~FMC2_CSQIER_TCIE; - - writel_relaxed(csqier, nfc->io_base + FMC2_CSQIER); + regmap_update_bits(nfc->regmap, FMC2_CSQIER, FMC2_CSQIER_TCIE, 0); nfc->irq_state = FMC2_IRQ_UNKNOWN; } -static inline void stm32_fmc2_nfc_clear_seq_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_clear_seq_irq(struct stm32_fmc2_nfc *nfc) { - writel_relaxed(FMC2_CSQICR_CLEAR_IRQ, nfc->io_base + FMC2_CSQICR); + regmap_write(nfc->regmap, FMC2_CSQICR, FMC2_CSQICR_CLEAR_IRQ); } -static inline void stm32_fmc2_nfc_enable_bch_irq(struct stm32_fmc2_nfc *nfc, - int mode) +static void stm32_fmc2_nfc_enable_bch_irq(struct stm32_fmc2_nfc *nfc, int mode) { - u32 bchier = readl_relaxed(nfc->io_base + FMC2_BCHIER); + nfc->irq_state = FMC2_IRQ_BCH; if (mode == NAND_ECC_WRITE) - bchier |= FMC2_BCHIER_EPBRIE; + regmap_update_bits(nfc->regmap, FMC2_BCHIER, + FMC2_BCHIER_EPBRIE, FMC2_BCHIER_EPBRIE); else - bchier |= FMC2_BCHIER_DERIE; - - nfc->irq_state = FMC2_IRQ_BCH; - - writel_relaxed(bchier, nfc->io_base + FMC2_BCHIER); + regmap_update_bits(nfc->regmap, FMC2_BCHIER, + FMC2_BCHIER_DERIE, FMC2_BCHIER_DERIE); } -static inline void stm32_fmc2_nfc_disable_bch_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_disable_bch_irq(struct stm32_fmc2_nfc *nfc) { - u32 bchier = readl_relaxed(nfc->io_base + FMC2_BCHIER); - - bchier &= ~FMC2_BCHIER_DERIE; - bchier &= ~FMC2_BCHIER_EPBRIE; - - writel_relaxed(bchier, nfc->io_base + FMC2_BCHIER); + regmap_update_bits(nfc->regmap, FMC2_BCHIER, + FMC2_BCHIER_DERIE | FMC2_BCHIER_EPBRIE, 0); nfc->irq_state = FMC2_IRQ_UNKNOWN; } -static inline void stm32_fmc2_nfc_clear_bch_irq(struct stm32_fmc2_nfc *nfc) +static void stm32_fmc2_nfc_clear_bch_irq(struct stm32_fmc2_nfc *nfc) { - writel_relaxed(FMC2_BCHICR_CLEAR_IRQ, nfc->io_base + FMC2_BCHICR); + regmap_write(nfc->regmap, FMC2_BCHICR, FMC2_BCHICR_CLEAR_IRQ); } /* @@ -329,13 +318,8 @@ static void stm32_fmc2_nfc_hwctl(struct nand_chip *chip, int mode) stm32_fmc2_nfc_set_ecc(nfc, false); if (chip->ecc.strength != FMC2_ECC_HAM) { - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); - - if (mode == NAND_ECC_WRITE) - pcr |= FMC2_PCR_WEN; - else - pcr &= ~FMC2_PCR_WEN; - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + regmap_update_bits(nfc->regmap, FMC2_PCR, FMC2_PCR_WEN, + mode == NAND_ECC_WRITE ? FMC2_PCR_WEN : 0); reinit_completion(&nfc->complete); stm32_fmc2_nfc_clear_bch_irq(nfc); @@ -350,7 +334,7 @@ static void stm32_fmc2_nfc_hwctl(struct nand_chip *chip, int mode) * ECC is 3 bytes for 512 bytes of data (supports error correction up to * max of 1-bit) */ -static inline void stm32_fmc2_nfc_ham_set_ecc(const u32 ecc_sta, u8 *ecc) +static void stm32_fmc2_nfc_ham_set_ecc(const u32 ecc_sta, u8 *ecc) { ecc[0] = ecc_sta; ecc[1] = ecc_sta >> 8; @@ -364,15 +348,15 @@ static int stm32_fmc2_nfc_ham_calculate(struct nand_chip *chip, const u8 *data, u32 sr, heccr; int ret; - ret = readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_SR, - sr, sr & FMC2_SR_NWRF, 1, - 1000 * FMC2_TIMEOUT_MS); + ret = regmap_read_poll_timeout(nfc->regmap, FMC2_SR, sr, + sr & FMC2_SR_NWRF, 1, + 1000 * FMC2_TIMEOUT_MS); if (ret) { dev_err(nfc->dev, "ham timeout\n"); return ret; } - heccr = readl_relaxed(nfc->io_base + FMC2_HECCR); + regmap_read(nfc->regmap, FMC2_HECCR, &heccr); stm32_fmc2_nfc_ham_set_ecc(heccr, ecc); stm32_fmc2_nfc_set_ecc(nfc, false); @@ -451,13 +435,13 @@ static int stm32_fmc2_nfc_bch_calculate(struct nand_chip *chip, const u8 *data, } /* Read parity bits */ - bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR1); + regmap_read(nfc->regmap, FMC2_BCHPBR1, &bchpbr); ecc[0] = bchpbr; ecc[1] = bchpbr >> 8; ecc[2] = bchpbr >> 16; ecc[3] = bchpbr >> 24; - bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR2); + regmap_read(nfc->regmap, FMC2_BCHPBR2, &bchpbr); ecc[4] = bchpbr; ecc[5] = bchpbr >> 8; ecc[6] = bchpbr >> 16; @@ -465,13 +449,13 @@ static int stm32_fmc2_nfc_bch_calculate(struct nand_chip *chip, const u8 *data, if (chip->ecc.strength == FMC2_ECC_BCH8) { ecc[7] = bchpbr >> 24; - bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR3); + regmap_read(nfc->regmap, FMC2_BCHPBR3, &bchpbr); ecc[8] = bchpbr; ecc[9] = bchpbr >> 8; ecc[10] = bchpbr >> 16; ecc[11] = bchpbr >> 24; - bchpbr = readl_relaxed(nfc->io_base + FMC2_BCHPBR4); + regmap_read(nfc->regmap, FMC2_BCHPBR4, &bchpbr); ecc[12] = bchpbr; } @@ -533,11 +517,7 @@ static int stm32_fmc2_nfc_bch_correct(struct nand_chip *chip, u8 *dat, return -ETIMEDOUT; } - ecc_sta[0] = readl_relaxed(nfc->io_base + FMC2_BCHDSR0); - ecc_sta[1] = readl_relaxed(nfc->io_base + FMC2_BCHDSR1); - ecc_sta[2] = readl_relaxed(nfc->io_base + FMC2_BCHDSR2); - ecc_sta[3] = readl_relaxed(nfc->io_base + FMC2_BCHDSR3); - ecc_sta[4] = readl_relaxed(nfc->io_base + FMC2_BCHDSR4); + regmap_bulk_read(nfc->regmap, FMC2_BCHDSR0, ecc_sta, 5); stm32_fmc2_nfc_set_ecc(nfc, false); @@ -612,30 +592,29 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, { struct stm32_fmc2_nfc *nfc = to_stm32_nfc(chip->controller); struct mtd_info *mtd = nand_to_mtd(chip); - u32 csqcfgr1, csqcfgr2, csqcfgr3; - u32 csqar1, csqar2; u32 ecc_offset = mtd->writesize + FMC2_BBM_LEN; - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); + /* + * cfg[0] => csqcfgr1, cfg[1] => csqcfgr2, cfg[2] => csqcfgr3 + * cfg[3] => csqar1, cfg[4] => csqar2 + */ + u32 cfg[5]; - if (write_data) - pcr |= FMC2_PCR_WEN; - else - pcr &= ~FMC2_PCR_WEN; - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); + regmap_update_bits(nfc->regmap, FMC2_PCR, FMC2_PCR_WEN, + write_data ? FMC2_PCR_WEN : 0); /* * - Set Program Page/Page Read command * - Enable DMA request data * - Set timings */ - csqcfgr1 = FMC2_CSQCFGR1_DMADEN | FMC2_CSQCFGR1_CMD1T; + cfg[0] = FMC2_CSQCFGR1_DMADEN | FMC2_CSQCFGR1_CMD1T; if (write_data) - csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_SEQIN); + cfg[0] |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_SEQIN); else - csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_READ0) | - FMC2_CSQCFGR1_CMD2EN | - FIELD_PREP(FMC2_CSQCFGR1_CMD2, NAND_CMD_READSTART) | - FMC2_CSQCFGR1_CMD2T; + cfg[0] |= FIELD_PREP(FMC2_CSQCFGR1_CMD1, NAND_CMD_READ0) | + FMC2_CSQCFGR1_CMD2EN | + FIELD_PREP(FMC2_CSQCFGR1_CMD2, NAND_CMD_READSTART) | + FMC2_CSQCFGR1_CMD2T; /* * - Set Random Data Input/Random Data Read command @@ -644,30 +623,29 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * - Set timings */ if (write_data) - csqcfgr2 = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDIN); + cfg[1] = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDIN); else - csqcfgr2 = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDOUT) | - FMC2_CSQCFGR2_RCMD2EN | - FIELD_PREP(FMC2_CSQCFGR2_RCMD2, - NAND_CMD_RNDOUTSTART) | - FMC2_CSQCFGR2_RCMD1T | - FMC2_CSQCFGR2_RCMD2T; + cfg[1] = FIELD_PREP(FMC2_CSQCFGR2_RCMD1, NAND_CMD_RNDOUT) | + FMC2_CSQCFGR2_RCMD2EN | + FIELD_PREP(FMC2_CSQCFGR2_RCMD2, NAND_CMD_RNDOUTSTART) | + FMC2_CSQCFGR2_RCMD1T | + FMC2_CSQCFGR2_RCMD2T; if (!raw) { - csqcfgr2 |= write_data ? 0 : FMC2_CSQCFGR2_DMASEN; - csqcfgr2 |= FMC2_CSQCFGR2_SQSDTEN; + cfg[1] |= write_data ? 0 : FMC2_CSQCFGR2_DMASEN; + cfg[1] |= FMC2_CSQCFGR2_SQSDTEN; } /* * - Set the number of sectors to be written * - Set timings */ - csqcfgr3 = FIELD_PREP(FMC2_CSQCFGR3_SNBR, chip->ecc.steps - 1); + cfg[2] = FIELD_PREP(FMC2_CSQCFGR3_SNBR, chip->ecc.steps - 1); if (write_data) { - csqcfgr3 |= FMC2_CSQCFGR3_RAC2T; + cfg[2] |= FMC2_CSQCFGR3_RAC2T; if (chip->options & NAND_ROW_ADDR_3) - csqcfgr3 |= FMC2_CSQCFGR3_AC5T; + cfg[2] |= FMC2_CSQCFGR3_AC5T; else - csqcfgr3 |= FMC2_CSQCFGR3_AC4T; + cfg[2] |= FMC2_CSQCFGR3_AC4T; } /* @@ -675,8 +653,8 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * Byte 1 and byte 2 => column, we start at 0x0 * Byte 3 and byte 4 => page */ - csqar1 = FIELD_PREP(FMC2_CSQCAR1_ADDC3, page); - csqar1 |= FIELD_PREP(FMC2_CSQCAR1_ADDC4, page >> 8); + cfg[3] = FIELD_PREP(FMC2_CSQCAR1_ADDC3, page); + cfg[3] |= FIELD_PREP(FMC2_CSQCAR1_ADDC4, page >> 8); /* * - Set chip enable number @@ -684,23 +662,19 @@ static void stm32_fmc2_nfc_rw_page_init(struct nand_chip *chip, int page, * - Calculate the number of address cycles to be issued * - Set byte 5 of address cycle if needed */ - csqar2 = FIELD_PREP(FMC2_CSQCAR2_NANDCEN, nfc->cs_sel); + cfg[4] = FIELD_PREP(FMC2_CSQCAR2_NANDCEN, nfc->cs_sel); if (chip->options & NAND_BUSWIDTH_16) - csqar2 |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset >> 1); + cfg[4] |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset >> 1); else - csqar2 |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset); + cfg[4] |= FIELD_PREP(FMC2_CSQCAR2_SAO, ecc_offset); if (chip->options & NAND_ROW_ADDR_3) { - csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 5); - csqar2 |= FIELD_PREP(FMC2_CSQCAR2_ADDC5, page >> 16); + cfg[0] |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 5); + cfg[4] |= FIELD_PREP(FMC2_CSQCAR2_ADDC5, page >> 16); } else { - csqcfgr1 |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 4); + cfg[0] |= FIELD_PREP(FMC2_CSQCFGR1_ACYNBR, 4); } - writel_relaxed(csqcfgr1, nfc->io_base + FMC2_CSQCFGR1); - writel_relaxed(csqcfgr2, nfc->io_base + FMC2_CSQCFGR2); - writel_relaxed(csqcfgr3, nfc->io_base + FMC2_CSQCFGR3); - writel_relaxed(csqar1, nfc->io_base + FMC2_CSQAR1); - writel_relaxed(csqar2, nfc->io_base + FMC2_CSQAR2); + regmap_bulk_write(nfc->regmap, FMC2_CSQCFGR1, cfg, 5); } static void stm32_fmc2_nfc_dma_callback(void *arg) @@ -718,7 +692,6 @@ static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf, struct dma_chan *dma_ch = nfc->dma_rx_ch; enum dma_data_direction dma_data_dir = DMA_FROM_DEVICE; enum dma_transfer_direction dma_transfer_dir = DMA_DEV_TO_MEM; - u32 csqcr = readl_relaxed(nfc->io_base + FMC2_CSQCR); int eccsteps = chip->ecc.steps; int eccsize = chip->ecc.size; unsigned long timeout = msecs_to_jiffies(FMC2_TIMEOUT_MS); @@ -796,8 +769,8 @@ static int stm32_fmc2_nfc_xfer(struct nand_chip *chip, const u8 *buf, stm32_fmc2_nfc_enable_seq_irq(nfc); /* Start the transfer */ - csqcr |= FMC2_CSQCR_CSQSTART; - writel_relaxed(csqcr, nfc->io_base + FMC2_CSQCR); + regmap_update_bits(nfc->regmap, FMC2_CSQCR, + FMC2_CSQCR_CSQSTART, FMC2_CSQCR_CSQSTART); /* Wait end of sequencer transfer */ if (!wait_for_completion_timeout(&nfc->complete, timeout)) { @@ -890,11 +863,13 @@ static int stm32_fmc2_nfc_seq_write_page_raw(struct nand_chip *chip, } /* Get a status indicating which sectors have errors */ -static inline u16 stm32_fmc2_nfc_get_mapping_status(struct stm32_fmc2_nfc *nfc) +static u16 stm32_fmc2_nfc_get_mapping_status(struct stm32_fmc2_nfc *nfc) { - u32 csqemsr = readl_relaxed(nfc->io_base + FMC2_CSQEMSR); + u32 csqemsr; + + regmap_read(nfc->regmap, FMC2_CSQEMSR, &csqemsr); - return csqemsr & FMC2_CSQEMSR_SEM; + return FIELD_GET(FMC2_CSQEMSR_SEM, csqemsr); } static int stm32_fmc2_nfc_seq_correct(struct nand_chip *chip, u8 *dat, @@ -1150,9 +1125,9 @@ static int stm32_fmc2_nfc_waitrdy(struct nand_chip *chip, u32 isr, sr; /* Check if there is no pending requests to the NAND flash */ - if (readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_SR, sr, - sr & FMC2_SR_NWRF, 1, - 1000 * FMC2_TIMEOUT_MS)) + if (regmap_read_poll_timeout(nfc->regmap, FMC2_SR, sr, + sr & FMC2_SR_NWRF, 1, + 1000 * FMC2_TIMEOUT_MS)) dev_warn(nfc->dev, "Waitrdy timeout\n"); /* Wait tWB before R/B# signal is low */ @@ -1160,12 +1135,12 @@ static int stm32_fmc2_nfc_waitrdy(struct nand_chip *chip, ndelay(PSEC_TO_NSEC(timings->tWB_max)); /* R/B# signal is low, clear high level flag */ - writel_relaxed(FMC2_ICR_CIHLF, nfc->io_base + FMC2_ICR); + regmap_write(nfc->regmap, FMC2_ICR, FMC2_ICR_CIHLF); /* Wait R/B# signal is high */ - return readl_relaxed_poll_timeout_atomic(nfc->io_base + FMC2_ISR, - isr, isr & FMC2_ISR_IHLF, - 5, 1000 * timeout_ms); + return regmap_read_poll_timeout(nfc->regmap, FMC2_ISR, isr, + isr & FMC2_ISR_IHLF, 5, + 1000 * FMC2_TIMEOUT_MS); } static int stm32_fmc2_nfc_exec_op(struct nand_chip *chip, @@ -1223,8 +1198,9 @@ static int stm32_fmc2_nfc_exec_op(struct nand_chip *chip, static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc) { - u32 pcr = readl_relaxed(nfc->io_base + FMC2_PCR); - u32 bcr1 = readl_relaxed(nfc->io_base + FMC2_BCR1); + u32 pcr; + + regmap_read(nfc->regmap, FMC2_PCR, &pcr); /* Set CS used to undefined */ nfc->cs_sel = -1; @@ -1255,12 +1231,12 @@ static void stm32_fmc2_nfc_init(struct stm32_fmc2_nfc *nfc) pcr |= FIELD_PREP(FMC2_PCR_TAR, FMC2_PCR_TAR_DEFAULT); /* Enable FMC2 controller */ - bcr1 |= FMC2_BCR1_FMC2EN; + regmap_update_bits(nfc->regmap, FMC2_BCR1, + FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN); - writel_relaxed(bcr1, nfc->io_base + FMC2_BCR1); - writel_relaxed(pcr, nfc->io_base + FMC2_PCR); - writel_relaxed(FMC2_PMEM_DEFAULT, nfc->io_base + FMC2_PMEM); - writel_relaxed(FMC2_PATT_DEFAULT, nfc->io_base + FMC2_PATT); + regmap_write(nfc->regmap, FMC2_PCR, pcr); + regmap_write(nfc->regmap, FMC2_PMEM, FMC2_PMEM_DEFAULT); + regmap_write(nfc->regmap, FMC2_PATT, FMC2_PATT_DEFAULT); } static void stm32_fmc2_nfc_calc_timings(struct nand_chip *chip, @@ -1695,6 +1671,7 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) struct resource *res; struct mtd_info *mtd; struct nand_chip *chip; + void __iomem *mmio; int chip_cs, mem_region, ret, irq; nfc = devm_kzalloc(dev, sizeof(*nfc), GFP_KERNEL); @@ -1710,9 +1687,13 @@ static int stm32_fmc2_nfc_probe(struct platform_device *pdev) return ret; res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - nfc->io_base = devm_ioremap_resource(dev, res); - if (IS_ERR(nfc->io_base)) - return PTR_ERR(nfc->io_base); + mmio = devm_ioremap_resource(dev, res); + if (IS_ERR(mmio)) + return PTR_ERR(mmio); + + nfc->regmap = devm_regmap_init_mmio(dev, mmio, &stm32_fmc2_regmap_cfg); + if (IS_ERR(nfc->regmap)) + return PTR_ERR(nfc->regmap); nfc->io_phys_addr = res->start;