From nobody Sun Feb 8 09:17:04 2026 Received: from mx08-00178001.pphosted.com (mx08-00178001.pphosted.com [91.207.212.93]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9416E381BE; Mon, 26 Feb 2024 10:16:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=91.207.212.93 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942568; cv=none; b=px69FDSlQYGnbmfJ02ln+b3YpJiwGC/xen1p/DP7+wyzz7KdDpd5n/7NRFiygsnYhQdXMKk/oypBUjEZ3TOJip+BdcQtucualrC5yK07kNW8c8KrTzEz8hjXvmIGTJMw3fcPn+Sfq0607CtS/uLtxgAWKY20HPOaNXiOcUqrQIg= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942568; c=relaxed/simple; bh=UDNvKSYg+/SA5i8qLf0z8IBqL6wuxzfyh+tb5eFpRXg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IzZifWJGVyLW5D+hedIrpnrb/VwmFZ+a36rs1hP1WLOXORQs5E/mQuOuoEMJ9VHUqdy+VNYDSmUe8H/MFKdl4imHM1mb3BxNuS8dX5Ns0r9HYPodpAqzgrlcmEyjSqxoweRQD3oX7RhkLcoqJrTQbSF/goeNouyQTGvdbSobnok= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=JT+WIcT9; arc=none smtp.client-ip=91.207.212.93 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="JT+WIcT9" Received: from pps.filterd (m0369457.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41QAFijw010324; Mon, 26 Feb 2024 11:15:45 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=OW57AZTUsQlp0CNOE8yjZNo7VI7deZ88cKgdLkWe72c=; b=JT +WIcT9QolRpLOc/FyUTQPE1SdjiI4HED5CBLcRFE8fA4aabvoojqeE+bAqkMtgJH jUtpSKKthrEgEKA8D1UCeg5SYT+P9pH3puhNYAfF0XdOAJHgDGXhEJaV7W3F/ciA pqWedqQJqOdSIdTyQKSPb9lWt9I2VbqUriYixBl6ma8lQUhafrAWsxVjnqDHhtFI vTkSDyZZU4BzI+6y/h6vclkY4fN1PkUUN40NcN2iCxTocD2uC2Tl8BVc9QjHBdKk wLRYE5q21KfGjFqzKEHggTaZb/Y6G9Y/DmzUqn4RNzbVZN9SZap2RXLa3z8JWXas cGotRzlTzFmVbO+1wzNQ== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3wfv9tv67b-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 26 Feb 2024 11:15:45 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 2D3234002D; Mon, 26 Feb 2024 11:15:30 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 8170F25ED94; Mon, 26 Feb 2024 11:15:00 +0100 (CET) Received: from localhost (10.201.21.177) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 26 Feb 2024 11:15:00 +0100 From: Christophe Kerello To: , , , CC: , , , Christophe Kerello Subject: [PATCH v3 1/5] dt-bindings: memory-controller: st,stm32: add MP25 support Date: Mon, 26 Feb 2024 11:14:24 +0100 Message-ID: <20240226101428.37791-2-christophe.kerello@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226101428.37791-1-christophe.kerello@foss.st.com> References: <20240226101428.37791-1-christophe.kerello@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-26_07,2024-02-23_01,2023-05-22_02 Content-Type: text/plain; charset="utf-8" Add a new compatible string to support MP25 SoC. On MP1 SoC, RNB signal (NAND controller signal) and NWAIT signal (PSRAM controller signal) have been integrated together in the SoC. That means that the NAND controller and the PSRAM controller (if the signal is used) can not be used at the same time. On MP25 SoC, the 2 signals can be used outside the SoC, so there is no more restrictions. MP1 SoC also embeds revision 1.1 of the FMC2 IP when MP25 SoC embeds revision 2.0 of the FMC2 IP. MP25 SoC is also using PSCI OS-initiated mode, so allow a single 'power-domains' entry for STM32 FMC2. As MP1 will move on PSCI OS-initiated mode, add this property as optional for all FMC2 variants. Signed-off-by: Christophe Kerello --- Changes in v2: - V1 patch 1 and 2 have been squashed and commit message has been updated. .../bindings/memory-controllers/st,stm32-fmc2-ebi.yaml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/Documentation/devicetree/bindings/memory-controllers/st,stm32-= fmc2-ebi.yaml b/Documentation/devicetree/bindings/memory-controllers/st,stm= 32-fmc2-ebi.yaml index 14f1833d37c9..84ac6f50a6fc 100644 --- a/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-eb= i.yaml +++ b/Documentation/devicetree/bindings/memory-controllers/st,stm32-fmc2-eb= i.yaml @@ -23,7 +23,9 @@ maintainers: =20 properties: compatible: - const: st,stm32mp1-fmc2-ebi + enum: + - st,stm32mp1-fmc2-ebi + - st,stm32mp25-fmc2-ebi =20 reg: maxItems: 1 @@ -34,6 +36,9 @@ properties: resets: maxItems: 1 =20 + power-domains: + maxItems: 1 + "#address-cells": const: 2 =20 --=20 2.25.1 From nobody Sun Feb 8 09:17:04 2026 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BDC4418E3F; Mon, 26 Feb 2024 10:15:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942561; cv=none; b=m3hDLRANXa72SvOVmDI2348aqyBaBmEOOuUcD/HcADbFWgpBG95rD+ISastqgNR8HA4RfwYMuhrgHNc7mYlwIBHAdX62qVambPC0jxBkjlokWIQurrvOOYMtbs5ro4sx2WtRqnvG6OpRShaCj58vRDMDEH8F3PTkXBZjvr2cyD4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942561; c=relaxed/simple; bh=9Uopn/B9kw/+Y8vsNhqRf98SnGm9Bmt3yeH5cL3+ENg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=DwUMvl/y5UtfhoamW3Jdp0oiYGQWJ8NdgRMcoo4wF34WNzkTgN4/ap4afrFgVpQtgYf2rOB+LFug6FNg3A+NNfJgR8+KdZcf0QzeCaArjUMd6smjV3SfiFa8s+XpA8+7OcO6uUWbObvPGt0V5w9KBaJOq92pq6e5JdMMdYXn7n4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=Q0RlmTeV; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="Q0RlmTeV" Received: from pps.filterd (m0288072.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41QAFjHj024554; Mon, 26 Feb 2024 11:15:52 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=WPnMq16B7ucTbP+rKNcejvrnq5iyzNgD0l0s6l+thas=; b=Q0 RlmTeVpSElqWHOQyCRSR42y3mXH1z3FO1iidfCbAX5NHtLYSGE6lk77jxyKh/l4A KDlIUFILPkHTEvh84OpkF1wchE0nkzB8ye0W8jBR4x9QQmy5PO1+82DY6IZA4cT4 OsGLY64O6QSRu6Dm5TX24DtkC/YrhjouLy+HGh8qJ/TpI9xYVOeVUsZC6wD9U3ZK VTcAHspcBStMfKlPFNLxCkMPv1a9hyWXUcgmTG+Ua5ILrNiefD0TYX5GqQURBPbS bF+/qZYZ4SIEDG64Jgkr8sXgmHkXWBkX1lLktNIMF+tixzmXfs/T+r7mXfSwMZSn WyZQHjifFDnqUWJ9WjNw== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3wf6rkesuf-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 26 Feb 2024 11:15:51 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 943A340045; Mon, 26 Feb 2024 11:15:48 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 4CB9B259B8F; Mon, 26 Feb 2024 11:15:17 +0100 (CET) Received: from localhost (10.201.21.177) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 26 Feb 2024 11:15:16 +0100 From: Christophe Kerello To: , , , CC: , , , Christophe Kerello Subject: [PATCH v3 2/5] memory: stm32-fmc2-ebi: check regmap_read return value Date: Mon, 26 Feb 2024 11:14:25 +0100 Message-ID: <20240226101428.37791-3-christophe.kerello@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226101428.37791-1-christophe.kerello@foss.st.com> References: <20240226101428.37791-1-christophe.kerello@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-26_07,2024-02-23_01,2023-05-22_02 Content-Type: text/plain; charset="utf-8" Check regmap_read return value to avoid to use uninitialized local variables. Signed-off-by: Christophe Kerello --- Changes in v3: - Simplify stm32_fmc2_ebi_save_setup function Changes in v2: - New patch added drivers/memory/stm32-fmc2-ebi.c | 122 +++++++++++++++++++++++--------- 1 file changed, 88 insertions(+), 34 deletions(-) diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-eb= i.c index 47d0ea5f1616..81c1cd88fb97 100644 --- a/drivers/memory/stm32-fmc2-ebi.c +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -181,8 +181,11 @@ static int stm32_fmc2_ebi_check_mux(struct stm32_fmc2_= ebi *ebi, int cs) { u32 bcr; + int ret; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; =20 if (bcr & FMC2_BCR_MTYP) return 0; @@ -195,8 +198,11 @@ static int stm32_fmc2_ebi_check_waitcfg(struct stm32_f= mc2_ebi *ebi, int cs) { u32 bcr, val =3D FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_NOR); + int ret; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; =20 if ((bcr & FMC2_BCR_MTYP) =3D=3D val && bcr & FMC2_BCR_BURSTEN) return 0; @@ -209,8 +215,11 @@ static int stm32_fmc2_ebi_check_sync_trans(struct stm3= 2_fmc2_ebi *ebi, int cs) { u32 bcr; + int ret; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; =20 if (bcr & FMC2_BCR_BURSTEN) return 0; @@ -223,8 +232,11 @@ static int stm32_fmc2_ebi_check_async_trans(struct stm= 32_fmc2_ebi *ebi, int cs) { u32 bcr; + int ret; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; =20 if (!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) return 0; @@ -237,8 +249,11 @@ static int stm32_fmc2_ebi_check_cpsize(struct stm32_fm= c2_ebi *ebi, int cs) { u32 bcr, val =3D FIELD_PREP(FMC2_BCR_MTYP, FMC2_BCR_MTYP_PSRAM); + int ret; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; =20 if ((bcr & FMC2_BCR_MTYP) =3D=3D val && bcr & FMC2_BCR_BURSTEN) return 0; @@ -251,12 +266,18 @@ static int stm32_fmc2_ebi_check_address_hold(struct s= tm32_fmc2_ebi *ebi, int cs) { u32 bcr, bxtr, val =3D FIELD_PREP(FMC2_BXTR_ACCMOD, FMC2_BXTR_EXTMOD_D); + int ret; + + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); if (prop->reg_type =3D=3D FMC2_REG_BWTR) - regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); + ret =3D regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); else - regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); + ret =3D regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); + if (ret) + return ret; =20 if ((!(bcr & FMC2_BCR_BURSTEN) || !(bcr & FMC2_BCR_CBURSTRW)) && ((bxtr & FMC2_BXTR_ACCMOD) =3D=3D val || bcr & FMC2_BCR_MUXEN)) @@ -270,12 +291,19 @@ static int stm32_fmc2_ebi_check_clk_period(struct stm= 32_fmc2_ebi *ebi, int cs) { u32 bcr, bcr1; + int ret; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); - if (cs) - regmap_read(ebi->regmap, FMC2_BCR1, &bcr1); - else + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; + + if (cs) { + ret =3D regmap_read(ebi->regmap, FMC2_BCR1, &bcr1); + if (ret) + return ret; + } else { bcr1 =3D bcr; + } =20 if (bcr & FMC2_BCR_BURSTEN && (!cs || !(bcr1 & FMC2_BCR1_CCLKEN))) return 0; @@ -307,12 +335,18 @@ static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm= 32_fmc2_ebi *ebi, { u32 nb_clk_cycles =3D stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup); u32 bcr, btr, clk_period; + int ret; + + ret =3D regmap_read(ebi->regmap, FMC2_BCR1, &bcr); + if (ret) + return ret; =20 - regmap_read(ebi->regmap, FMC2_BCR1, &bcr); if (bcr & FMC2_BCR1_CCLKEN || !cs) - regmap_read(ebi->regmap, FMC2_BTR1, &btr); + ret =3D regmap_read(ebi->regmap, FMC2_BTR1, &btr); else - regmap_read(ebi->regmap, FMC2_BTR(cs), &btr); + ret =3D regmap_read(ebi->regmap, FMC2_BTR(cs), &btr); + if (ret) + return ret; =20 clk_period =3D FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1; =20 @@ -571,11 +605,16 @@ static int stm32_fmc2_ebi_set_address_setup(struct st= m32_fmc2_ebi *ebi, if (ret) return ret; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; + if (prop->reg_type =3D=3D FMC2_REG_BWTR) - regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); + ret =3D regmap_read(ebi->regmap, FMC2_BWTR(cs), &bxtr); else - regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); + ret =3D regmap_read(ebi->regmap, FMC2_BTR(cs), &bxtr); + if (ret) + return ret; =20 if ((bxtr & FMC2_BXTR_ACCMOD) =3D=3D val || bcr & FMC2_BCR_MUXEN) val =3D clamp_val(setup, 1, FMC2_BXTR_ADDSET_MAX); @@ -693,11 +732,14 @@ static int stm32_fmc2_ebi_set_max_low_pulse(struct st= m32_fmc2_ebi *ebi, int cs, u32 setup) { u32 old_val, new_val, pcscntr; + int ret; =20 if (setup < 1) return 0; =20 - regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr); + ret =3D regmap_read(ebi->regmap, FMC2_PCSCNTR, &pcscntr); + if (ret) + return ret; =20 /* Enable counter for the bank */ regmap_update_bits(ebi->regmap, FMC2_PCSCNTR, @@ -944,17 +986,20 @@ static void stm32_fmc2_ebi_disable_bank(struct stm32_= fmc2_ebi *ebi, int cs) regmap_update_bits(ebi->regmap, FMC2_BCR(cs), FMC2_BCR_MBKEN, 0); } =20 -static void stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi) +static int stm32_fmc2_ebi_save_setup(struct stm32_fmc2_ebi *ebi) { unsigned int cs; + int ret; =20 for (cs =3D 0; cs < FMC2_MAX_EBI_CE; cs++) { - regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); - regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]); - regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); + ret |=3D regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]); + ret |=3D regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); + if (ret) + return ret; } =20 - regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr); + return regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr); } =20 static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi) @@ -983,22 +1028,29 @@ static void stm32_fmc2_ebi_disable_banks(struct stm3= 2_fmc2_ebi *ebi) } =20 /* NWAIT signal can not be connected to EBI controller and NAND controller= */ -static bool stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi) +static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct stm32_fmc2_ebi *ebi) { + struct device *dev =3D ebi->dev; unsigned int cs; u32 bcr; + int ret; =20 for (cs =3D 0; cs < FMC2_MAX_EBI_CE; cs++) { if (!(ebi->bank_assigned & BIT(cs))) continue; =20 - regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &bcr); + if (ret) + return ret; + if ((bcr & FMC2_BCR_WAITEN || bcr & FMC2_BCR_ASYNCWAIT) && - ebi->bank_assigned & BIT(FMC2_NAND)) - return true; + ebi->bank_assigned & BIT(FMC2_NAND)) { + dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n"); + return -EINVAL; + } } =20 - return false; + return 0; } =20 static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi) @@ -1085,10 +1137,9 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2= _ebi *ebi) return -ENODEV; } =20 - if (stm32_fmc2_ebi_nwait_used_by_ctrls(ebi)) { - dev_err(dev, "NWAIT signal connected to EBI and NAND controllers\n"); - return -EINVAL; - } + ret =3D stm32_fmc2_ebi_nwait_used_by_ctrls(ebi); + if (ret) + return ret; =20 stm32_fmc2_ebi_enable(ebi); =20 @@ -1133,7 +1184,10 @@ static int stm32_fmc2_ebi_probe(struct platform_devi= ce *pdev) if (ret) goto err_release; =20 - stm32_fmc2_ebi_save_setup(ebi); + ret =3D stm32_fmc2_ebi_save_setup(ebi); + if (ret) + goto err_release; + platform_set_drvdata(pdev, ebi); =20 return 0; --=20 2.25.1 From nobody Sun Feb 8 09:17:04 2026 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 23D7E60257; Mon, 26 Feb 2024 10:16:11 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942574; cv=none; b=c9tys5gpIuEE+2TG1/+9O89/SFHiLVuTounmy1SwncAGHFUof1vdHNWUTpnZCAf4HIVZ9INH8OJZAMU+TFkGazinNUEci0JBrTDofgRqyIwszWmj5J6IzGdNkOQ5/vAteq8Elm52GHJkmVyrvLZ62UfIV0onltS/Gdk5H9oub6k= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942574; c=relaxed/simple; bh=xG4B6Ql4VMiCTmHWRlPGftBv8A84ypxzrWlw0E/dyiA=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=B8Vn4mSZrRd56meNoHlmfn1/+9OcfvijnS29yuhspe+cDyQiU8OP6u57CHNFRoa9r9RbIQfInykmG4irCKvMrpE7a0qzshTC+JvtPfU/SWyuOkjuFCczjx4RwLqSapNdbKDK1ZNZaeufi7/sjRP4jVmfhuXqUUWdhWI599kc+ig= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=wT0uuraL; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="wT0uuraL" Received: from pps.filterd (m0288072.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41QAFiq6024424; Mon, 26 Feb 2024 11:16:05 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=bYN8QcYPZerw3PiBE9CtbjcJvZo5s+faU3m6zXrrDqE=; b=wT 0uuraLr7RuU4lD+l2S95rF08pLWGzxMOEGiXpbgP2pqID20zT2UaFlckEhPgp8ml qPc8Svp2lBG/5VqJoc/JgAtU6Z1ojzBwAoZ80lQVDWD8T0eTxYIEhbQxJ4MFmmwH EYIxayKvA0RO4u4D+KQHCsvwZkzju75KVcD2sUph51An26OZ1bv5DWOlSRLDTSk7 NwZlxpyQ+c3oDGX4cCzP7mrv6E4wQAHr4oaYT0h6P9ABUkCbQf23xLqVEHg3MFjR vKtqG3JJgR7o/MiFXgrWEdTTM623BnKoxxWN+iRXtuZtgk5a6ZnEggqTYpNL3lwp 6MIaxZ3KnyqTqZ8BvtIQ== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3wf6rkesvj-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 26 Feb 2024 11:16:05 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id E20C740045; Mon, 26 Feb 2024 11:16:01 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 9342D259106; Mon, 26 Feb 2024 11:15:32 +0100 (CET) Received: from localhost (10.201.21.177) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 26 Feb 2024 11:15:32 +0100 From: Christophe Kerello To: , , , CC: , , , Christophe Kerello Subject: [PATCH v3 3/5] memory: stm32-fmc2-ebi: add MP25 support Date: Mon, 26 Feb 2024 11:14:26 +0100 Message-ID: <20240226101428.37791-4-christophe.kerello@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226101428.37791-1-christophe.kerello@foss.st.com> References: <20240226101428.37791-1-christophe.kerello@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-26_07,2024-02-23_01,2023-05-22_02 Content-Type: text/plain; charset="utf-8" Add the support of the revision 2 of FMC2 IP. - PCSCNTR register has been removed, - CFGR register has been added, - the bit used to enable the IP has moved from BCR1 to CFGR, - the timeout for CEx deassertion has moved from PCSCNTR to BCRx, - the continuous clock enable has moved from BCR1 to CFGR, - the clk divide ratio has moved from BCR1 to CFGR. The MP1 SoCs have only one signal to manage all the controllers (NWAIT). The MP25 SOC has one RNB signal for the NAND controller and one NWAIT signal for the memory controller. Let's use a platform data structure for parameters that will differ between MP1 and MP25. Signed-off-by: Christophe Kerello --- Changes in v3: - Do not check non null ops. Changes in v2: - V1 patch 3, 4 and 5 have been squashed and reworked. - a platform data structure is handling the difference between MP1 and MP2= 5. drivers/memory/stm32-fmc2-ebi.c | 362 ++++++++++++++++++++++++++++++-- 1 file changed, 350 insertions(+), 12 deletions(-) diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-eb= i.c index 81c1cd88fb97..e81ba43b14db 100644 --- a/drivers/memory/stm32-fmc2-ebi.c +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -20,6 +20,7 @@ #define FMC2_BCR(x) ((x) * 0x8 + FMC2_BCR1) #define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1) #define FMC2_PCSCNTR 0x20 +#define FMC2_CFGR 0x20 #define FMC2_BWTR1 0x104 #define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1) =20 @@ -42,6 +43,7 @@ #define FMC2_BCR_ASYNCWAIT BIT(15) #define FMC2_BCR_CPSIZE GENMASK(18, 16) #define FMC2_BCR_CBURSTRW BIT(19) +#define FMC2_BCR_CSCOUNT GENMASK(21, 20) #define FMC2_BCR_NBLSET GENMASK(23, 22) =20 /* Register: FMC2_BTRx/FMC2_BWTRx */ @@ -58,6 +60,11 @@ #define FMC2_PCSCNTR_CSCOUNT GENMASK(15, 0) #define FMC2_PCSCNTR_CNTBEN(x) BIT((x) + 16) =20 +/* Register: FMC2_CFGR */ +#define FMC2_CFGR_CLKDIV GENMASK(19, 16) +#define FMC2_CFGR_CCLKEN BIT(20) +#define FMC2_CFGR_FMC2EN BIT(31) + #define FMC2_MAX_EBI_CE 4 #define FMC2_MAX_BANKS 5 =20 @@ -74,6 +81,11 @@ #define FMC2_BCR_MTYP_PSRAM 0x1 #define FMC2_BCR_MTYP_NOR 0x2 =20 +#define FMC2_BCR_CSCOUNT_0 0x0 +#define FMC2_BCR_CSCOUNT_1 0x1 +#define FMC2_BCR_CSCOUNT_64 0x2 +#define FMC2_BCR_CSCOUNT_256 0x3 + #define FMC2_BXTR_EXTMOD_A 0x0 #define FMC2_BXTR_EXTMOD_B 0x1 #define FMC2_BXTR_EXTMOD_C 0x2 @@ -88,6 +100,7 @@ #define FMC2_BTR_CLKDIV_MAX 0xf #define FMC2_BTR_DATLAT_MAX 0xf #define FMC2_PCSCNTR_CSCOUNT_MAX 0xff +#define FMC2_CFGR_CLKDIV_MAX 0xf =20 enum stm32_fmc2_ebi_bank { FMC2_EBI1 =3D 0, @@ -101,7 +114,8 @@ enum stm32_fmc2_ebi_register_type { FMC2_REG_BCR =3D 1, FMC2_REG_BTR, FMC2_REG_BWTR, - FMC2_REG_PCSCNTR + FMC2_REG_PCSCNTR, + FMC2_REG_CFGR }; =20 enum stm32_fmc2_ebi_transaction_type { @@ -132,16 +146,37 @@ enum stm32_fmc2_ebi_cpsize { FMC2_CPSIZE_1024 =3D 1024 }; =20 +enum stm32_fmc2_ebi_cscount { + FMC2_CSCOUNT_0 =3D 0, + FMC2_CSCOUNT_1 =3D 1, + FMC2_CSCOUNT_64 =3D 64, + FMC2_CSCOUNT_256 =3D 256 +}; + +struct stm32_fmc2_ebi; + +struct stm32_fmc2_ebi_data { + const struct stm32_fmc2_prop *child_props; + unsigned int nb_child_props; + u32 fmc2_enable_reg; + u32 fmc2_enable_bit; + int (*nwait_used_by_ctrls)(struct stm32_fmc2_ebi *ebi); + void (*set_setup)(struct stm32_fmc2_ebi *ebi); + int (*save_setup)(struct stm32_fmc2_ebi *ebi); +}; + struct stm32_fmc2_ebi { struct device *dev; struct clk *clk; struct regmap *regmap; + const struct stm32_fmc2_ebi_data *data; u8 bank_assigned; =20 u32 bcr[FMC2_MAX_EBI_CE]; u32 btr[FMC2_MAX_EBI_CE]; u32 bwtr[FMC2_MAX_EBI_CE]; u32 pcscntr; + u32 cfgr; }; =20 /* @@ -353,6 +388,30 @@ static u32 stm32_fmc2_ebi_ns_to_clk_period(struct stm3= 2_fmc2_ebi *ebi, return DIV_ROUND_UP(nb_clk_cycles, clk_period); } =20 +static u32 stm32_fmc2_ebi_mp25_ns_to_clk_period(struct stm32_fmc2_ebi *ebi, + int cs, u32 setup) +{ + u32 nb_clk_cycles =3D stm32_fmc2_ebi_ns_to_clock_cycles(ebi, cs, setup); + u32 cfgr, btr, clk_period; + int ret; + + ret =3D regmap_read(ebi->regmap, FMC2_CFGR, &cfgr); + if (ret) + return ret; + + if (cfgr & FMC2_CFGR_CCLKEN) { + clk_period =3D FIELD_GET(FMC2_CFGR_CLKDIV, cfgr) + 1; + } else { + ret =3D regmap_read(ebi->regmap, FMC2_BTR(cs), &btr); + if (ret) + return ret; + + clk_period =3D FIELD_GET(FMC2_BTR_CLKDIV, btr) + 1; + } + + return DIV_ROUND_UP(nb_clk_cycles, clk_period); +} + static int stm32_fmc2_ebi_get_reg(int reg_type, int cs, u32 *reg) { switch (reg_type) { @@ -368,6 +427,9 @@ static int stm32_fmc2_ebi_get_reg(int reg_type, int cs,= u32 *reg) case FMC2_REG_PCSCNTR: *reg =3D FMC2_PCSCNTR; break; + case FMC2_REG_CFGR: + *reg =3D FMC2_CFGR; + break; default: return -EINVAL; } @@ -714,6 +776,30 @@ static int stm32_fmc2_ebi_set_clk_period(struct stm32_= fmc2_ebi *ebi, return 0; } =20 +static int stm32_fmc2_ebi_mp25_set_clk_period(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val, cfgr; + int ret; + + ret =3D regmap_read(ebi->regmap, FMC2_CFGR, &cfgr); + if (ret) + return ret; + + if (cfgr & FMC2_CFGR_CCLKEN) { + val =3D setup ? clamp_val(setup - 1, 1, FMC2_CFGR_CLKDIV_MAX) : 1; + val =3D FIELD_PREP(FMC2_CFGR_CLKDIV, val); + regmap_update_bits(ebi->regmap, FMC2_CFGR, FMC2_CFGR_CLKDIV, val); + } else { + val =3D setup ? clamp_val(setup - 1, 1, FMC2_BTR_CLKDIV_MAX) : 1; + val =3D FIELD_PREP(FMC2_BTR_CLKDIV, val); + regmap_update_bits(ebi->regmap, FMC2_BTR(cs), FMC2_BTR_CLKDIV, val); + } + + return 0; +} + static int stm32_fmc2_ebi_set_data_latency(struct stm32_fmc2_ebi *ebi, const struct stm32_fmc2_prop *prop, int cs, u32 setup) @@ -759,6 +845,27 @@ static int stm32_fmc2_ebi_set_max_low_pulse(struct stm= 32_fmc2_ebi *ebi, return 0; } =20 +static int stm32_fmc2_ebi_mp25_set_max_low_pulse(struct stm32_fmc2_ebi *eb= i, + const struct stm32_fmc2_prop *prop, + int cs, u32 setup) +{ + u32 val; + + if (setup =3D=3D FMC2_CSCOUNT_0) + val =3D FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_0); + else if (setup =3D=3D FMC2_CSCOUNT_1) + val =3D FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_1); + else if (setup <=3D FMC2_CSCOUNT_64) + val =3D FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_64); + else + val =3D FIELD_PREP(FMC2_BCR_CSCOUNT, FMC2_BCR_CSCOUNT_256); + + regmap_update_bits(ebi->regmap, FMC2_BCR(cs), + FMC2_BCR_CSCOUNT, val); + + return 0; +} + static const struct stm32_fmc2_prop stm32_fmc2_child_props[] =3D { /* st,fmc2-ebi-cs-trans-type must be the first property */ { @@ -924,6 +1031,171 @@ static const struct stm32_fmc2_prop stm32_fmc2_child= _props[] =3D { }, }; =20 +static const struct stm32_fmc2_prop stm32_fmc2_mp25_child_props[] =3D { + /* st,fmc2-ebi-cs-trans-type must be the first property */ + { + .name =3D "st,fmc2-ebi-cs-transaction-type", + .mprop =3D true, + .set =3D stm32_fmc2_ebi_set_trans_type, + }, + { + .name =3D "st,fmc2-ebi-cs-cclk-enable", + .bprop =3D true, + .reg_type =3D FMC2_REG_CFGR, + .reg_mask =3D FMC2_CFGR_CCLKEN, + .check =3D stm32_fmc2_ebi_check_sync_trans, + .set =3D stm32_fmc2_ebi_set_bit_field, + }, + { + .name =3D "st,fmc2-ebi-cs-mux-enable", + .bprop =3D true, + .reg_type =3D FMC2_REG_BCR, + .reg_mask =3D FMC2_BCR_MUXEN, + .check =3D stm32_fmc2_ebi_check_mux, + .set =3D stm32_fmc2_ebi_set_bit_field, + }, + { + .name =3D "st,fmc2-ebi-cs-buswidth", + .reset_val =3D FMC2_BUSWIDTH_16, + .set =3D stm32_fmc2_ebi_set_buswidth, + }, + { + .name =3D "st,fmc2-ebi-cs-waitpol-high", + .bprop =3D true, + .reg_type =3D FMC2_REG_BCR, + .reg_mask =3D FMC2_BCR_WAITPOL, + .set =3D stm32_fmc2_ebi_set_bit_field, + }, + { + .name =3D "st,fmc2-ebi-cs-waitcfg-enable", + .bprop =3D true, + .reg_type =3D FMC2_REG_BCR, + .reg_mask =3D FMC2_BCR_WAITCFG, + .check =3D stm32_fmc2_ebi_check_waitcfg, + .set =3D stm32_fmc2_ebi_set_bit_field, + }, + { + .name =3D "st,fmc2-ebi-cs-wait-enable", + .bprop =3D true, + .reg_type =3D FMC2_REG_BCR, + .reg_mask =3D FMC2_BCR_WAITEN, + .check =3D stm32_fmc2_ebi_check_sync_trans, + .set =3D stm32_fmc2_ebi_set_bit_field, + }, + { + .name =3D "st,fmc2-ebi-cs-asyncwait-enable", + .bprop =3D true, + .reg_type =3D FMC2_REG_BCR, + .reg_mask =3D FMC2_BCR_ASYNCWAIT, + .check =3D stm32_fmc2_ebi_check_async_trans, + .set =3D stm32_fmc2_ebi_set_bit_field, + }, + { + .name =3D "st,fmc2-ebi-cs-cpsize", + .check =3D stm32_fmc2_ebi_check_cpsize, + .set =3D stm32_fmc2_ebi_set_cpsize, + }, + { + .name =3D "st,fmc2-ebi-cs-byte-lane-setup-ns", + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_bl_setup, + }, + { + .name =3D "st,fmc2-ebi-cs-address-setup-ns", + .reg_type =3D FMC2_REG_BTR, + .reset_val =3D FMC2_BXTR_ADDSET_MAX, + .check =3D stm32_fmc2_ebi_check_async_trans, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_address_setup, + }, + { + .name =3D "st,fmc2-ebi-cs-address-hold-ns", + .reg_type =3D FMC2_REG_BTR, + .reset_val =3D FMC2_BXTR_ADDHLD_MAX, + .check =3D stm32_fmc2_ebi_check_address_hold, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_address_hold, + }, + { + .name =3D "st,fmc2-ebi-cs-data-setup-ns", + .reg_type =3D FMC2_REG_BTR, + .reset_val =3D FMC2_BXTR_DATAST_MAX, + .check =3D stm32_fmc2_ebi_check_async_trans, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_data_setup, + }, + { + .name =3D "st,fmc2-ebi-cs-bus-turnaround-ns", + .reg_type =3D FMC2_REG_BTR, + .reset_val =3D FMC2_BXTR_BUSTURN_MAX + 1, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_bus_turnaround, + }, + { + .name =3D "st,fmc2-ebi-cs-data-hold-ns", + .reg_type =3D FMC2_REG_BTR, + .check =3D stm32_fmc2_ebi_check_async_trans, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_data_hold, + }, + { + .name =3D "st,fmc2-ebi-cs-clk-period-ns", + .reset_val =3D FMC2_CFGR_CLKDIV_MAX + 1, + .check =3D stm32_fmc2_ebi_check_sync_trans, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_mp25_set_clk_period, + }, + { + .name =3D "st,fmc2-ebi-cs-data-latency-ns", + .check =3D stm32_fmc2_ebi_check_sync_trans, + .calculate =3D stm32_fmc2_ebi_mp25_ns_to_clk_period, + .set =3D stm32_fmc2_ebi_set_data_latency, + }, + { + .name =3D "st,fmc2-ebi-cs-write-address-setup-ns", + .reg_type =3D FMC2_REG_BWTR, + .reset_val =3D FMC2_BXTR_ADDSET_MAX, + .check =3D stm32_fmc2_ebi_check_async_trans, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_address_setup, + }, + { + .name =3D "st,fmc2-ebi-cs-write-address-hold-ns", + .reg_type =3D FMC2_REG_BWTR, + .reset_val =3D FMC2_BXTR_ADDHLD_MAX, + .check =3D stm32_fmc2_ebi_check_address_hold, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_address_hold, + }, + { + .name =3D "st,fmc2-ebi-cs-write-data-setup-ns", + .reg_type =3D FMC2_REG_BWTR, + .reset_val =3D FMC2_BXTR_DATAST_MAX, + .check =3D stm32_fmc2_ebi_check_async_trans, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_data_setup, + }, + { + .name =3D "st,fmc2-ebi-cs-write-bus-turnaround-ns", + .reg_type =3D FMC2_REG_BWTR, + .reset_val =3D FMC2_BXTR_BUSTURN_MAX + 1, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_bus_turnaround, + }, + { + .name =3D "st,fmc2-ebi-cs-write-data-hold-ns", + .reg_type =3D FMC2_REG_BWTR, + .check =3D stm32_fmc2_ebi_check_async_trans, + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_set_data_hold, + }, + { + .name =3D "st,fmc2-ebi-cs-max-low-pulse-ns", + .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, + .set =3D stm32_fmc2_ebi_mp25_set_max_low_pulse, + }, +}; + static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi, struct device_node *dev_node, const struct stm32_fmc2_prop *prop, @@ -999,9 +1271,31 @@ static int stm32_fmc2_ebi_save_setup(struct stm32_fmc= 2_ebi *ebi) return ret; } =20 + return 0; +} + +static int stm32_fmc2_ebi_mp1_save_setup(struct stm32_fmc2_ebi *ebi) +{ + int ret; + + ret =3D stm32_fmc2_ebi_save_setup(ebi); + if (ret) + return ret; + return regmap_read(ebi->regmap, FMC2_PCSCNTR, &ebi->pcscntr); } =20 +static int stm32_fmc2_ebi_mp25_save_setup(struct stm32_fmc2_ebi *ebi) +{ + int ret; + + ret =3D stm32_fmc2_ebi_save_setup(ebi); + if (ret) + return ret; + + return regmap_read(ebi->regmap, FMC2_CFGR, &ebi->cfgr); +} + static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi) { unsigned int cs; @@ -1011,10 +1305,20 @@ static void stm32_fmc2_ebi_set_setup(struct stm32_f= mc2_ebi *ebi) regmap_write(ebi->regmap, FMC2_BTR(cs), ebi->btr[cs]); regmap_write(ebi->regmap, FMC2_BWTR(cs), ebi->bwtr[cs]); } +} =20 +static void stm32_fmc2_ebi_mp1_set_setup(struct stm32_fmc2_ebi *ebi) +{ + stm32_fmc2_ebi_set_setup(ebi); regmap_write(ebi->regmap, FMC2_PCSCNTR, ebi->pcscntr); } =20 +static void stm32_fmc2_ebi_mp25_set_setup(struct stm32_fmc2_ebi *ebi) +{ + stm32_fmc2_ebi_set_setup(ebi); + regmap_write(ebi->regmap, FMC2_CFGR, ebi->cfgr); +} + static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2_ebi *ebi) { unsigned int cs; @@ -1055,13 +1359,15 @@ static int stm32_fmc2_ebi_nwait_used_by_ctrls(struc= t stm32_fmc2_ebi *ebi) =20 static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi) { - regmap_update_bits(ebi->regmap, FMC2_BCR1, - FMC2_BCR1_FMC2EN, FMC2_BCR1_FMC2EN); + regmap_update_bits(ebi->regmap, ebi->data->fmc2_enable_reg, + ebi->data->fmc2_enable_bit, + ebi->data->fmc2_enable_bit); } =20 static void stm32_fmc2_ebi_disable(struct stm32_fmc2_ebi *ebi) { - regmap_update_bits(ebi->regmap, FMC2_BCR1, FMC2_BCR1_FMC2EN, 0); + regmap_update_bits(ebi->regmap, ebi->data->fmc2_enable_reg, + ebi->data->fmc2_enable_bit, 0); } =20 static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_ebi *ebi, @@ -1073,8 +1379,8 @@ static int stm32_fmc2_ebi_setup_cs(struct stm32_fmc2_= ebi *ebi, =20 stm32_fmc2_ebi_disable_bank(ebi, cs); =20 - for (i =3D 0; i < ARRAY_SIZE(stm32_fmc2_child_props); i++) { - const struct stm32_fmc2_prop *p =3D &stm32_fmc2_child_props[i]; + for (i =3D 0; i < ebi->data->nb_child_props; i++) { + const struct stm32_fmc2_prop *p =3D &ebi->data->child_props[i]; =20 ret =3D stm32_fmc2_ebi_parse_prop(ebi, dev_node, p, cs); if (ret) { @@ -1137,9 +1443,11 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2= _ebi *ebi) return -ENODEV; } =20 - ret =3D stm32_fmc2_ebi_nwait_used_by_ctrls(ebi); - if (ret) - return ret; + if (ebi->data->nwait_used_by_ctrls) { + ret =3D ebi->data->nwait_used_by_ctrls(ebi); + if (ret) + return ret; + } =20 stm32_fmc2_ebi_enable(ebi); =20 @@ -1159,6 +1467,10 @@ static int stm32_fmc2_ebi_probe(struct platform_devi= ce *pdev) =20 ebi->dev =3D dev; =20 + ebi->data =3D of_device_get_match_data(dev); + if (!ebi->data) + return -EINVAL; + ebi->regmap =3D device_node_to_regmap(dev->of_node); if (IS_ERR(ebi->regmap)) return PTR_ERR(ebi->regmap); @@ -1184,7 +1496,7 @@ static int stm32_fmc2_ebi_probe(struct platform_devic= e *pdev) if (ret) goto err_release; =20 - ret =3D stm32_fmc2_ebi_save_setup(ebi); + ret =3D ebi->data->save_setup(ebi); if (ret) goto err_release; =20 @@ -1232,7 +1544,7 @@ static int __maybe_unused stm32_fmc2_ebi_resume(struc= t device *dev) if (ret) return ret; =20 - stm32_fmc2_ebi_set_setup(ebi); + ebi->data->set_setup(ebi); stm32_fmc2_ebi_enable(ebi); =20 return 0; @@ -1241,8 +1553,34 @@ static int __maybe_unused stm32_fmc2_ebi_resume(stru= ct device *dev) static SIMPLE_DEV_PM_OPS(stm32_fmc2_ebi_pm_ops, stm32_fmc2_ebi_suspend, stm32_fmc2_ebi_resume); =20 +static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp1_data =3D { + .child_props =3D stm32_fmc2_child_props, + .nb_child_props =3D ARRAY_SIZE(stm32_fmc2_child_props), + .fmc2_enable_reg =3D FMC2_BCR1, + .fmc2_enable_bit =3D FMC2_BCR1_FMC2EN, + .nwait_used_by_ctrls =3D stm32_fmc2_ebi_nwait_used_by_ctrls, + .set_setup =3D stm32_fmc2_ebi_mp1_set_setup, + .save_setup =3D stm32_fmc2_ebi_mp1_save_setup, +}; + +static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp25_data =3D { + .child_props =3D stm32_fmc2_mp25_child_props, + .nb_child_props =3D ARRAY_SIZE(stm32_fmc2_mp25_child_props), + .fmc2_enable_reg =3D FMC2_CFGR, + .fmc2_enable_bit =3D FMC2_CFGR_FMC2EN, + .set_setup =3D stm32_fmc2_ebi_mp25_set_setup, + .save_setup =3D stm32_fmc2_ebi_mp25_save_setup, +}; + static const struct of_device_id stm32_fmc2_ebi_match[] =3D { - {.compatible =3D "st,stm32mp1-fmc2-ebi"}, + { + .compatible =3D "st,stm32mp1-fmc2-ebi", + .data =3D &stm32_fmc2_ebi_mp1_data, + }, + { + .compatible =3D "st,stm32mp25-fmc2-ebi", + .data =3D &stm32_fmc2_ebi_mp25_data, + }, {} }; MODULE_DEVICE_TABLE(of, stm32_fmc2_ebi_match); --=20 2.25.1 From nobody Sun Feb 8 09:17:04 2026 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5D2763D541; Mon, 26 Feb 2024 10:16:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942588; cv=none; b=NRy1j3Fd9F1LNKDW5zjCbASzkHTp/b0Ft53S5h8VZT3p0s08D/Ip8ksrrLY4RDh6upvHt6SQgdRGyYSkJx8cGzmv+yDv+xVntggiANA5148WUHIHCz+ckAw7VNtur9/kIxtN/Rq8sehVEnXaT1YDwhvAxyLUS/cI+qQwgEPVFik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942588; c=relaxed/simple; bh=y0X+YOYArTTWsi8ZCqnPFS2QszArarFEQ+FvnMqW6fw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Qa3Z+lnmi+TyA6rELCZIJZbA1sY7nV4s9t9owGCJHiZKaVoO5Mn1be7v41V+0jCl8LgXYKW/dDIsyVFNcSDec7l+JOMk+fBDeY7cJQu9vFTduHrqG0iTwPR3HxoaZoGe0R5l8MOHAcur3WBkRuS0Y0AyiBdrptgcbx9+wm4KBTI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=ZbP2mdfD; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="ZbP2mdfD" Received: from pps.filterd (m0369458.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41QAFmkq008208; Mon, 26 Feb 2024 11:16:19 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=5g3/9ZWMdTP9BTYUvNGlAmFKIpX9qM06tseiEL+EjSQ=; b=Zb P2mdfDBGSEnh25TPr+v/Fp0pEluKFAH+XO9s3fK/0mDjKRVcCiOa9+jGRks3cYoh O3ks/gKbnCPAAQ6sGPCJ5n7XpWBL4zrwIZTo6hllR8Tl9UJ78xBX4WlIsrpAzeRE DnulZFXH8f1vXwUJsV69M0lrWrlK8txTHCsOqW+gMBjzEst1Z6Ab6tXnqn3G0F1C l9o722XTVspWfYhdOG1LmclgU2PneQ2y3AWta+GrioHEUDUx9e4rMMHMnICY7RmA vPA6ar20suvh0G1gKUdShyvL1rli0icAKrqvB8ONod71Xsg/7JojsCWrP8qeqynf balphlkq1uwGilGKD0Kg== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3wftw4mh1e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 26 Feb 2024 11:16:19 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 289FC40045; Mon, 26 Feb 2024 11:16:16 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 880AE25ED80; Mon, 26 Feb 2024 11:15:47 +0100 (CET) Received: from localhost (10.201.21.177) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 26 Feb 2024 11:15:47 +0100 From: Christophe Kerello To: , , , CC: , , , Christophe Kerello Subject: [PATCH v3 4/5] memory: stm32-fmc2-ebi: add MP25 RIF support Date: Mon, 26 Feb 2024 11:14:27 +0100 Message-ID: <20240226101428.37791-5-christophe.kerello@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226101428.37791-1-christophe.kerello@foss.st.com> References: <20240226101428.37791-1-christophe.kerello@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-26_07,2024-02-23_01,2023-05-22_02 Content-Type: text/plain; charset="utf-8" The FMC2 revision 2 supports security and isolation compliant with the Resource Isolation Framework (RIF). From RIF point of view, the FMC2 is composed of several independent resources, listed below, which can be assigned to different security and compartment domains: - 0: Common FMC_CFGR register. - 1: EBI controller for Chip Select 1. - 2: EBI controller for Chip Select 2. - 3: EBI controller for Chip Select 3. - 4: EBI controller for Chip Select 4. - 5: NAND controller. Signed-off-by: Christophe Kerello --- Changes in v2: - security check done throw ops. drivers/memory/stm32-fmc2-ebi.c | 224 +++++++++++++++++++++++++++++++- 1 file changed, 220 insertions(+), 4 deletions(-) diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-eb= i.c index e81ba43b14db..45c658af613d 100644 --- a/drivers/memory/stm32-fmc2-ebi.c +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -21,8 +21,14 @@ #define FMC2_BTR(x) ((x) * 0x8 + FMC2_BTR1) #define FMC2_PCSCNTR 0x20 #define FMC2_CFGR 0x20 +#define FMC2_SR 0x84 #define FMC2_BWTR1 0x104 #define FMC2_BWTR(x) ((x) * 0x8 + FMC2_BWTR1) +#define FMC2_SECCFGR 0x300 +#define FMC2_CIDCFGR0 0x30c +#define FMC2_CIDCFGR(x) ((x) * 0x8 + FMC2_CIDCFGR0) +#define FMC2_SEMCR0 0x310 +#define FMC2_SEMCR(x) ((x) * 0x8 + FMC2_SEMCR0) =20 /* Register: FMC2_BCR1 */ #define FMC2_BCR1_CCLKEN BIT(20) @@ -65,8 +71,23 @@ #define FMC2_CFGR_CCLKEN BIT(20) #define FMC2_CFGR_FMC2EN BIT(31) =20 +/* Register: FMC2_SR */ +#define FMC2_SR_ISOST GENMASK(1, 0) + +/* Register: FMC2_CIDCFGR */ +#define FMC2_CIDCFGR_CFEN BIT(0) +#define FMC2_CIDCFGR_SEMEN BIT(1) +#define FMC2_CIDCFGR_SCID GENMASK(6, 4) +#define FMC2_CIDCFGR_SEMWLC1 BIT(17) + +/* Register: FMC2_SEMCR */ +#define FMC2_SEMCR_SEM_MUTEX BIT(0) +#define FMC2_SEMCR_SEMCID GENMASK(6, 4) + #define FMC2_MAX_EBI_CE 4 #define FMC2_MAX_BANKS 5 +#define FMC2_MAX_RESOURCES 6 +#define FMC2_CID1 1 =20 #define FMC2_BCR_CPSIZE_0 0x0 #define FMC2_BCR_CPSIZE_128 0x1 @@ -163,6 +184,9 @@ struct stm32_fmc2_ebi_data { int (*nwait_used_by_ctrls)(struct stm32_fmc2_ebi *ebi); void (*set_setup)(struct stm32_fmc2_ebi *ebi); int (*save_setup)(struct stm32_fmc2_ebi *ebi); + int (*check_rif)(struct stm32_fmc2_ebi *ebi, u32 resource); + void (*put_sems)(struct stm32_fmc2_ebi *ebi); + void (*get_sems)(struct stm32_fmc2_ebi *ebi); }; =20 struct stm32_fmc2_ebi { @@ -171,6 +195,8 @@ struct stm32_fmc2_ebi { struct regmap *regmap; const struct stm32_fmc2_ebi_data *data; u8 bank_assigned; + u8 sem_taken; + bool access_granted; =20 u32 bcr[FMC2_MAX_EBI_CE]; u32 btr[FMC2_MAX_EBI_CE]; @@ -262,6 +288,33 @@ static int stm32_fmc2_ebi_check_sync_trans(struct stm3= 2_fmc2_ebi *ebi, return -EINVAL; } =20 +static int stm32_fmc2_ebi_mp25_check_cclk(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + if (!ebi->access_granted) + return -EACCES; + + return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs); +} + +static int stm32_fmc2_ebi_mp25_check_clk_period(struct stm32_fmc2_ebi *ebi, + const struct stm32_fmc2_prop *prop, + int cs) +{ + u32 cfgr; + int ret; + + ret =3D regmap_read(ebi->regmap, FMC2_CFGR, &cfgr); + if (ret) + return ret; + + if (cfgr & FMC2_CFGR_CCLKEN && !ebi->access_granted) + return -EACCES; + + return stm32_fmc2_ebi_check_sync_trans(ebi, prop, cs); +} + static int stm32_fmc2_ebi_check_async_trans(struct stm32_fmc2_ebi *ebi, const struct stm32_fmc2_prop *prop, int cs) @@ -1043,7 +1096,7 @@ static const struct stm32_fmc2_prop stm32_fmc2_mp25_c= hild_props[] =3D { .bprop =3D true, .reg_type =3D FMC2_REG_CFGR, .reg_mask =3D FMC2_CFGR_CCLKEN, - .check =3D stm32_fmc2_ebi_check_sync_trans, + .check =3D stm32_fmc2_ebi_mp25_check_cclk, .set =3D stm32_fmc2_ebi_set_bit_field, }, { @@ -1141,7 +1194,7 @@ static const struct stm32_fmc2_prop stm32_fmc2_mp25_c= hild_props[] =3D { { .name =3D "st,fmc2-ebi-cs-clk-period-ns", .reset_val =3D FMC2_CFGR_CLKDIV_MAX + 1, - .check =3D stm32_fmc2_ebi_check_sync_trans, + .check =3D stm32_fmc2_ebi_mp25_check_clk_period, .calculate =3D stm32_fmc2_ebi_ns_to_clock_cycles, .set =3D stm32_fmc2_ebi_mp25_set_clk_period, }, @@ -1196,6 +1249,110 @@ static const struct stm32_fmc2_prop stm32_fmc2_mp25= _child_props[] =3D { }, }; =20 +static int stm32_fmc2_ebi_mp25_check_rif(struct stm32_fmc2_ebi *ebi, u32 r= esource) +{ + u32 seccfgr, cidcfgr, semcr; + int cid, ret; + + if (resource >=3D FMC2_MAX_RESOURCES) + return -EINVAL; + + ret =3D regmap_read(ebi->regmap, FMC2_SECCFGR, &seccfgr); + if (ret) + return ret; + + if (seccfgr & BIT(resource)) { + if (resource) + dev_err(ebi->dev, "resource %d is configured as secure\n", + resource); + + return -EACCES; + } + + ret =3D regmap_read(ebi->regmap, FMC2_CIDCFGR(resource), &cidcfgr); + if (ret) + return ret; + + if (!(cidcfgr & FMC2_CIDCFGR_CFEN)) + /* CID filtering is turned off: access granted */ + return 0; + + if (!(cidcfgr & FMC2_CIDCFGR_SEMEN)) { + /* Static CID mode */ + cid =3D FIELD_GET(FMC2_CIDCFGR_SCID, cidcfgr); + if (cid !=3D FMC2_CID1) { + if (resource) + dev_err(ebi->dev, "static CID%d set for resource %d\n", + cid, resource); + + return -EACCES; + } + + return 0; + } + + /* Pass-list with semaphore mode */ + if (!(cidcfgr & FMC2_CIDCFGR_SEMWLC1)) { + if (resource) + dev_err(ebi->dev, "CID1 is block-listed for resource %d\n", + resource); + + return -EACCES; + } + + ret =3D regmap_read(ebi->regmap, FMC2_SEMCR(resource), &semcr); + if (ret) + return ret; + + if (!(semcr & FMC2_SEMCR_SEM_MUTEX)) { + regmap_update_bits(ebi->regmap, FMC2_SEMCR(resource), + FMC2_SEMCR_SEM_MUTEX, FMC2_SEMCR_SEM_MUTEX); + + ret =3D regmap_read(ebi->regmap, FMC2_SEMCR(resource), &semcr); + if (ret) + return ret; + } + + cid =3D FIELD_GET(FMC2_SEMCR_SEMCID, semcr); + if (cid !=3D FMC2_CID1) { + if (resource) + dev_err(ebi->dev, "resource %d is already used by CID%d\n", + resource, cid); + + return -EACCES; + } + + ebi->sem_taken |=3D BIT(resource); + + return 0; +} + +static void stm32_fmc2_ebi_mp25_put_sems(struct stm32_fmc2_ebi *ebi) +{ + unsigned int resource; + + for (resource =3D 0; resource < FMC2_MAX_RESOURCES; resource++) { + if (!(ebi->sem_taken & BIT(resource))) + continue; + + regmap_update_bits(ebi->regmap, FMC2_SEMCR(resource), + FMC2_SEMCR_SEM_MUTEX, 0); + } +} + +static void stm32_fmc2_ebi_mp25_get_sems(struct stm32_fmc2_ebi *ebi) +{ + unsigned int resource; + + for (resource =3D 0; resource < FMC2_MAX_RESOURCES; resource++) { + if (!(ebi->sem_taken & BIT(resource))) + continue; + + regmap_update_bits(ebi->regmap, FMC2_SEMCR(resource), + FMC2_SEMCR_SEM_MUTEX, FMC2_SEMCR_SEM_MUTEX); + } +} + static int stm32_fmc2_ebi_parse_prop(struct stm32_fmc2_ebi *ebi, struct device_node *dev_node, const struct stm32_fmc2_prop *prop, @@ -1264,6 +1421,9 @@ static int stm32_fmc2_ebi_save_setup(struct stm32_fmc= 2_ebi *ebi) int ret; =20 for (cs =3D 0; cs < FMC2_MAX_EBI_CE; cs++) { + if (!(ebi->bank_assigned & BIT(cs))) + continue; + ret =3D regmap_read(ebi->regmap, FMC2_BCR(cs), &ebi->bcr[cs]); ret |=3D regmap_read(ebi->regmap, FMC2_BTR(cs), &ebi->btr[cs]); ret |=3D regmap_read(ebi->regmap, FMC2_BWTR(cs), &ebi->bwtr[cs]); @@ -1293,7 +1453,10 @@ static int stm32_fmc2_ebi_mp25_save_setup(struct stm= 32_fmc2_ebi *ebi) if (ret) return ret; =20 - return regmap_read(ebi->regmap, FMC2_CFGR, &ebi->cfgr); + if (ebi->access_granted) + ret =3D regmap_read(ebi->regmap, FMC2_CFGR, &ebi->cfgr); + + return ret; } =20 static void stm32_fmc2_ebi_set_setup(struct stm32_fmc2_ebi *ebi) @@ -1301,6 +1464,9 @@ static void stm32_fmc2_ebi_set_setup(struct stm32_fmc= 2_ebi *ebi) unsigned int cs; =20 for (cs =3D 0; cs < FMC2_MAX_EBI_CE; cs++) { + if (!(ebi->bank_assigned & BIT(cs))) + continue; + regmap_write(ebi->regmap, FMC2_BCR(cs), ebi->bcr[cs]); regmap_write(ebi->regmap, FMC2_BTR(cs), ebi->btr[cs]); regmap_write(ebi->regmap, FMC2_BWTR(cs), ebi->bwtr[cs]); @@ -1316,7 +1482,9 @@ static void stm32_fmc2_ebi_mp1_set_setup(struct stm32= _fmc2_ebi *ebi) static void stm32_fmc2_ebi_mp25_set_setup(struct stm32_fmc2_ebi *ebi) { stm32_fmc2_ebi_set_setup(ebi); - regmap_write(ebi->regmap, FMC2_CFGR, ebi->cfgr); + + if (ebi->access_granted) + regmap_write(ebi->regmap, FMC2_CFGR, ebi->cfgr); } =20 static void stm32_fmc2_ebi_disable_banks(struct stm32_fmc2_ebi *ebi) @@ -1359,6 +1527,9 @@ static int stm32_fmc2_ebi_nwait_used_by_ctrls(struct = stm32_fmc2_ebi *ebi) =20 static void stm32_fmc2_ebi_enable(struct stm32_fmc2_ebi *ebi) { + if (!ebi->access_granted) + return; + regmap_update_bits(ebi->regmap, ebi->data->fmc2_enable_reg, ebi->data->fmc2_enable_bit, ebi->data->fmc2_enable_bit); @@ -1366,6 +1537,9 @@ static void stm32_fmc2_ebi_enable(struct stm32_fmc2_e= bi *ebi) =20 static void stm32_fmc2_ebi_disable(struct stm32_fmc2_ebi *ebi) { + if (!ebi->access_granted) + return; + regmap_update_bits(ebi->regmap, ebi->data->fmc2_enable_reg, ebi->data->fmc2_enable_bit, 0); } @@ -1424,6 +1598,15 @@ static int stm32_fmc2_ebi_parse_dt(struct stm32_fmc2= _ebi *ebi) return -EINVAL; } =20 + if (ebi->data->check_rif) { + ret =3D ebi->data->check_rif(ebi, bank + 1); + if (ret) { + dev_err(dev, "bank access failed: %d\n", bank); + of_node_put(child); + return ret; + } + } + if (bank < FMC2_MAX_EBI_CE) { ret =3D stm32_fmc2_ebi_setup_cs(ebi, child, bank); if (ret) { @@ -1492,6 +1675,28 @@ static int stm32_fmc2_ebi_probe(struct platform_devi= ce *pdev) reset_control_deassert(rstc); } =20 + /* Check if CFGR register can be modified */ + ebi->access_granted =3D true; + if (ebi->data->check_rif) { + ret =3D ebi->data->check_rif(ebi, 0); + if (ret) { + u32 sr; + + ebi->access_granted =3D false; + + ret =3D regmap_read(ebi->regmap, FMC2_SR, &sr); + if (ret) + goto err_release; + + /* In case of CFGR is secure, just check that the FMC2 is enabled */ + if (sr & FMC2_SR_ISOST) { + dev_err(dev, "FMC2 is not ready to be used.\n"); + ret =3D -EACCES; + goto err_release; + } + } + } + ret =3D stm32_fmc2_ebi_parse_dt(ebi); if (ret) goto err_release; @@ -1507,6 +1712,8 @@ static int stm32_fmc2_ebi_probe(struct platform_devic= e *pdev) err_release: stm32_fmc2_ebi_disable_banks(ebi); stm32_fmc2_ebi_disable(ebi); + if (ebi->data->put_sems) + ebi->data->put_sems(ebi); clk_disable_unprepare(ebi->clk); =20 return ret; @@ -1519,6 +1726,8 @@ static void stm32_fmc2_ebi_remove(struct platform_dev= ice *pdev) of_platform_depopulate(&pdev->dev); stm32_fmc2_ebi_disable_banks(ebi); stm32_fmc2_ebi_disable(ebi); + if (ebi->data->put_sems) + ebi->data->put_sems(ebi); clk_disable_unprepare(ebi->clk); } =20 @@ -1527,6 +1736,8 @@ static int __maybe_unused stm32_fmc2_ebi_suspend(stru= ct device *dev) struct stm32_fmc2_ebi *ebi =3D dev_get_drvdata(dev); =20 stm32_fmc2_ebi_disable(ebi); + if (ebi->data->put_sems) + ebi->data->put_sems(ebi); clk_disable_unprepare(ebi->clk); pinctrl_pm_select_sleep_state(dev); =20 @@ -1544,6 +1755,8 @@ static int __maybe_unused stm32_fmc2_ebi_resume(struc= t device *dev) if (ret) return ret; =20 + if (ebi->data->get_sems) + ebi->data->get_sems(ebi); ebi->data->set_setup(ebi); stm32_fmc2_ebi_enable(ebi); =20 @@ -1570,6 +1783,9 @@ static const struct stm32_fmc2_ebi_data stm32_fmc2_eb= i_mp25_data =3D { .fmc2_enable_bit =3D FMC2_CFGR_FMC2EN, .set_setup =3D stm32_fmc2_ebi_mp25_set_setup, .save_setup =3D stm32_fmc2_ebi_mp25_save_setup, + .check_rif =3D stm32_fmc2_ebi_mp25_check_rif, + .put_sems =3D stm32_fmc2_ebi_mp25_put_sems, + .get_sems =3D stm32_fmc2_ebi_mp25_get_sems, }; =20 static const struct of_device_id stm32_fmc2_ebi_match[] =3D { --=20 2.25.1 From nobody Sun Feb 8 09:17:04 2026 Received: from mx07-00178001.pphosted.com (mx07-00178001.pphosted.com [185.132.182.106]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id AE281605A6; Mon, 26 Feb 2024 10:16:39 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=185.132.182.106 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942601; cv=none; b=N8Ch3Aia/fslCvfC+VDZpXVqDllANeK427SQLSP4Fi3ZfP07JX7JjOvz3St3SUbBJD/XofrE55Xo4iLpYVtuAgzHwWDERBSJXtfJ4RgE32Bl5Xg62OlH8iwhu+mG7g4bzgM4o9+riwqowHL2OEXm1qyiVIrL1g4iVaeJQlgwc1M= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1708942601; c=relaxed/simple; bh=BBLXVljoZZOO7u++4ebU0cnPhwZGz3QMObnaaqrDBB0=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=np4cNm4f3uNom01IpYyMMBA+rglwGknB0cHTMGmFqHb8D+zhbtnH7gv3TLtlYmdZG+lKDoPzoE75Lr89T8VMT5pvDQCH8YLN6TpPF54a2VAwKbQSWatVTG5fPkDayc7fX3fKJxbkw6Qqg2+Vg8zENVkweWtt0opTR5zJE9xod8c= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com; spf=pass smtp.mailfrom=foss.st.com; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b=4Jq7FCFk; arc=none smtp.client-ip=185.132.182.106 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=foss.st.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=foss.st.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=foss.st.com header.i=@foss.st.com header.b="4Jq7FCFk" Received: from pps.filterd (m0369458.ppops.net [127.0.0.1]) by mx07-00178001.pphosted.com (8.17.1.24/8.17.1.24) with ESMTP id 41QAFlbT008172; Mon, 26 Feb 2024 11:16:32 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=foss.st.com; h= from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding:content-type; s= selector1; bh=PT3rYq5wlLifa1OetliYI6KgIIUCxnn4TmN7Bb6JlgM=; b=4J q7FCFkxxDiPjkA38ACbqL8dIcdiM7qa9nM4FFO55DvREPOjTty845/9D4tnatVOA TS6/JqIlOBdfel12QFGvCFk4om/yOPceAgnMZ2+Xc+0bRVnWfTwVVq9Ur+h4SQvM G99cXqzYZDkg6KRX/kTxAcqF+WipLhFXqO2yiO0KbE70l7U9Lh0xFzZgCLMo6jqi OQTVFZH1/Q4RGY2lsNKvZ6YfcnlhJkVuI23/xr62A1EwSN3j5VBq7DX043HXwMRK w7/80lXYO4nfLfqggLaZxpurUxuPFwu3evdKHpnlFenqdpM57YBB4tL+G4H+CBfz Yejvl5bbyTbaKCjqX2XQ== Received: from beta.dmz-ap.st.com (beta.dmz-ap.st.com [138.198.100.35]) by mx07-00178001.pphosted.com (PPS) with ESMTPS id 3wftw4mh2e-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=NOT); Mon, 26 Feb 2024 11:16:32 +0100 (CET) Received: from euls16034.sgp.st.com (euls16034.sgp.st.com [10.75.44.20]) by beta.dmz-ap.st.com (STMicroelectronics) with ESMTP id 2BA4F40045; Mon, 26 Feb 2024 11:16:29 +0100 (CET) Received: from Webmail-eu.st.com (shfdag1node3.st.com [10.75.129.71]) by euls16034.sgp.st.com (STMicroelectronics) with ESMTP id 74A71259106; Mon, 26 Feb 2024 11:16:02 +0100 (CET) Received: from localhost (10.201.21.177) by SHFDAG1NODE3.st.com (10.75.129.71) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) id 15.1.2507.27; Mon, 26 Feb 2024 11:16:02 +0100 From: Christophe Kerello To: , , , CC: , , , Christophe Kerello Subject: [PATCH v3 5/5] memory: stm32-fmc2-ebi: keep power domain on Date: Mon, 26 Feb 2024 11:14:28 +0100 Message-ID: <20240226101428.37791-6-christophe.kerello@foss.st.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20240226101428.37791-1-christophe.kerello@foss.st.com> References: <20240226101428.37791-1-christophe.kerello@foss.st.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: EQNCAS1NODE3.st.com (10.75.129.80) To SHFDAG1NODE3.st.com (10.75.129.71) X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.272,Aquarius:18.0.1011,Hydra:6.0.619,FMLib:17.11.176.26 definitions=2024-02-26_07,2024-02-23_01,2023-05-22_02 Content-Type: text/plain; charset="utf-8" MP25 FMC2 domain has to be kept on. To handle it throw PSCI OS-initiated, basic PM for keeping domain on is introduced. Signed-off-by: Christophe Kerello --- Changes in v2: - Patch has been renamed and associated commit message has been updated. drivers/memory/stm32-fmc2-ebi.c | 41 +++++++++++++++++++++++++-------- 1 file changed, 32 insertions(+), 9 deletions(-) diff --git a/drivers/memory/stm32-fmc2-ebi.c b/drivers/memory/stm32-fmc2-eb= i.c index 45c658af613d..1c63eeacd071 100644 --- a/drivers/memory/stm32-fmc2-ebi.c +++ b/drivers/memory/stm32-fmc2-ebi.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include =20 @@ -1649,6 +1650,7 @@ static int stm32_fmc2_ebi_probe(struct platform_devic= e *pdev) return -ENOMEM; =20 ebi->dev =3D dev; + platform_set_drvdata(pdev, ebi); =20 ebi->data =3D of_device_get_match_data(dev); if (!ebi->data) @@ -1666,10 +1668,14 @@ static int stm32_fmc2_ebi_probe(struct platform_dev= ice *pdev) if (PTR_ERR(rstc) =3D=3D -EPROBE_DEFER) return -EPROBE_DEFER; =20 - ret =3D clk_prepare_enable(ebi->clk); + ret =3D devm_pm_runtime_enable(dev); if (ret) return ret; =20 + ret =3D pm_runtime_resume_and_get(dev); + if (ret < 0) + return ret; + if (!IS_ERR(rstc)) { reset_control_assert(rstc); reset_control_deassert(rstc); @@ -1705,8 +1711,6 @@ static int stm32_fmc2_ebi_probe(struct platform_devic= e *pdev) if (ret) goto err_release; =20 - platform_set_drvdata(pdev, ebi); - return 0; =20 err_release: @@ -1714,7 +1718,7 @@ static int stm32_fmc2_ebi_probe(struct platform_devic= e *pdev) stm32_fmc2_ebi_disable(ebi); if (ebi->data->put_sems) ebi->data->put_sems(ebi); - clk_disable_unprepare(ebi->clk); + pm_runtime_put_sync_suspend(dev); =20 return ret; } @@ -1728,7 +1732,23 @@ static void stm32_fmc2_ebi_remove(struct platform_de= vice *pdev) stm32_fmc2_ebi_disable(ebi); if (ebi->data->put_sems) ebi->data->put_sems(ebi); + pm_runtime_put_sync_suspend(&pdev->dev); +} + +static int __maybe_unused stm32_fmc2_ebi_runtime_suspend(struct device *de= v) +{ + struct stm32_fmc2_ebi *ebi =3D dev_get_drvdata(dev); + clk_disable_unprepare(ebi->clk); + + return 0; +} + +static int __maybe_unused stm32_fmc2_ebi_runtime_resume(struct device *dev) +{ + struct stm32_fmc2_ebi *ebi =3D dev_get_drvdata(dev); + + return clk_prepare_enable(ebi->clk); } =20 static int __maybe_unused stm32_fmc2_ebi_suspend(struct device *dev) @@ -1738,7 +1758,7 @@ static int __maybe_unused stm32_fmc2_ebi_suspend(stru= ct device *dev) stm32_fmc2_ebi_disable(ebi); if (ebi->data->put_sems) ebi->data->put_sems(ebi); - clk_disable_unprepare(ebi->clk); + pm_runtime_put_sync_suspend(dev); pinctrl_pm_select_sleep_state(dev); =20 return 0; @@ -1751,8 +1771,8 @@ static int __maybe_unused stm32_fmc2_ebi_resume(struc= t device *dev) =20 pinctrl_pm_select_default_state(dev); =20 - ret =3D clk_prepare_enable(ebi->clk); - if (ret) + ret =3D pm_runtime_resume_and_get(dev); + if (ret < 0) return ret; =20 if (ebi->data->get_sems) @@ -1763,8 +1783,11 @@ static int __maybe_unused stm32_fmc2_ebi_resume(stru= ct device *dev) return 0; } =20 -static SIMPLE_DEV_PM_OPS(stm32_fmc2_ebi_pm_ops, stm32_fmc2_ebi_suspend, - stm32_fmc2_ebi_resume); +static const struct dev_pm_ops stm32_fmc2_ebi_pm_ops =3D { + SET_RUNTIME_PM_OPS(stm32_fmc2_ebi_runtime_suspend, + stm32_fmc2_ebi_runtime_resume, NULL) + SET_SYSTEM_SLEEP_PM_OPS(stm32_fmc2_ebi_suspend, stm32_fmc2_ebi_resume) +}; =20 static const struct stm32_fmc2_ebi_data stm32_fmc2_ebi_mp1_data =3D { .child_props =3D stm32_fmc2_child_props, --=20 2.25.1