Patch Detail
get:
Show a patch.
patch:
Update a patch.
put:
Update a patch.
GET /api/1.2/patches/2230934/?format=api
{ "id": 2230934, "url": "http://patchwork.ozlabs.org/api/1.2/patches/2230934/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/patch/20260430084414.1354490-8-richard.genoud@bootlin.com/", "project": { "id": 18, "url": "http://patchwork.ozlabs.org/api/1.2/projects/18/?format=api", "name": "U-Boot", "link_name": "uboot", "list_id": "u-boot.lists.denx.de", "list_email": "u-boot@lists.denx.de", "web_url": null, "scm_url": null, "webscm_url": null, "list_archive_url": "", "list_archive_url_format": "", "commit_url_format": "" }, "msgid": "<20260430084414.1354490-8-richard.genoud@bootlin.com>", "list_archive_url": null, "date": "2026-04-30T08:44:00", "name": "[07/20] ram: k3-ddrss: Add exit retention support", "commit_ref": null, "pull_url": null, "state": "new", "archived": false, "hash": "b686622b733e537f5106eee8ff98206c1592ae58", "submitter": { "id": 88519, "url": "http://patchwork.ozlabs.org/api/1.2/people/88519/?format=api", "name": "Richard Genoud (TI)", "email": "richard.genoud@bootlin.com" }, "delegate": { "id": 3651, "url": "http://patchwork.ozlabs.org/api/1.2/users/3651/?format=api", "username": "trini", "first_name": "Tom", "last_name": "Rini", "email": "trini@ti.com" }, "mbox": "http://patchwork.ozlabs.org/project/uboot/patch/20260430084414.1354490-8-richard.genoud@bootlin.com/mbox/", "series": [ { "id": 502237, "url": "http://patchwork.ozlabs.org/api/1.2/series/502237/?format=api", "web_url": "http://patchwork.ozlabs.org/project/uboot/list/?series=502237", "date": "2026-04-30T08:43:53", "name": "Introduce resume for J7xx SoCs", "version": 1, "mbox": "http://patchwork.ozlabs.org/series/502237/mbox/" } ], "comments": "http://patchwork.ozlabs.org/api/patches/2230934/comments/", "check": "pending", "checks": "http://patchwork.ozlabs.org/api/patches/2230934/checks/", "tags": {}, "related": [], "headers": { "Return-Path": "<u-boot-bounces@lists.denx.de>", "X-Original-To": "incoming@patchwork.ozlabs.org", "Delivered-To": "patchwork-incoming@legolas.ozlabs.org", "Authentication-Results": [ "legolas.ozlabs.org;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=bootlin.com header.i=@bootlin.com header.a=rsa-sha256\n header.s=dkim header.b=OU0njhar;\n\tdkim-atps=neutral", "legolas.ozlabs.org;\n spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de\n (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de;\n envelope-from=u-boot-bounces@lists.denx.de; receiver=patchwork.ozlabs.org)", "phobos.denx.de;\n dmarc=pass (p=reject dis=none) header.from=bootlin.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de", "phobos.denx.de;\n\tdkim=pass (2048-bit key;\n unprotected) header.d=bootlin.com header.i=@bootlin.com header.b=\"OU0njhar\";\n\tdkim-atps=neutral", "phobos.denx.de;\n dmarc=pass (p=reject dis=none) header.from=bootlin.com", "phobos.denx.de;\n spf=pass smtp.mailfrom=richard.genoud@bootlin.com" ], "Received": [ "from phobos.denx.de (phobos.denx.de\n [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01])\n\t(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)\n\t key-exchange x25519)\n\t(No client certificate requested)\n\tby legolas.ozlabs.org (Postfix) with ESMTPS id 4g5nnC4YMBz1yHZ\n\tfor <incoming@patchwork.ozlabs.org>; Thu, 30 Apr 2026 18:45:35 +1000 (AEST)", "from h2850616.stratoserver.net (localhost [IPv6:::1])\n\tby phobos.denx.de (Postfix) with ESMTP id 4A15F8469A;\n\tThu, 30 Apr 2026 10:44:50 +0200 (CEST)", "by phobos.denx.de (Postfix, from userid 109)\n id 40EDE846A5; Thu, 30 Apr 2026 10:44:49 +0200 (CEST)", "from smtpout-03.galae.net (smtpout-03.galae.net [185.246.85.4])\n (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits))\n (No client certificate requested)\n by phobos.denx.de (Postfix) with ESMTPS id 8627F8469A\n for <u-boot@lists.denx.de>; Thu, 30 Apr 2026 10:44:46 +0200 (CEST)", "from smtpout-01.galae.net (smtpout-01.galae.net [212.83.139.233])\n by smtpout-03.galae.net (Postfix) with ESMTPS id 29A9A4E42B79;\n Thu, 30 Apr 2026 08:44:46 +0000 (UTC)", "from mail.galae.net (mail.galae.net [212.83.136.155])\n by smtpout-01.galae.net (Postfix) with ESMTPS id EBA6260495;\n Thu, 30 Apr 2026 08:44:45 +0000 (UTC)", "from [127.0.0.1] (localhost [127.0.0.1]) by localhost (Mailerdaemon)\n with ESMTPSA id 204951072B7A1;\n Thu, 30 Apr 2026 10:44:41 +0200 (CEST)" ], "X-Spam-Checker-Version": "SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de", "X-Spam-Level": "", "X-Spam-Status": "No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED,\n DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_BLOCKED,\n SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2", "DKIM-Signature": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=dkim;\n t=1777538684; h=from:subject:date:message-id:to:cc:mime-version:\n content-transfer-encoding:in-reply-to:references;\n bh=SEd01lWSl5hnm7GsdrhF1DAr8rHm56G76Fw7jBZjHxs=;\n b=OU0njhartUTdOiPNF3a/lyTSJwRzYyitC7z+9MsNPI03Hfm7kI/SmhgXjy2tAU9sYqAiNp\n P7eTyggTYe9Q0AjnnbECFHFnIZ30XRdv2Ng5E6T78B3kOkLyEn770hB/yDNg6dA71O7clu\n k+xzJQMLiBkx37B0cM3xb7JbGL/qV63KenlntW6aGFAmgB0b1XeO6PTT+eEy7J7cd9XpUD\n qFv4xn5OHgVtjZB7ahihmECT2YmO+5eCHFoUcn4sao7Q6X+Do3Kk4K5J8KkHyP8Lv7nvDK\n ojzrf3f2ZmCYZ9uoJDuxDufz42gawhO5hH+0VAYLXQnm+3wJQbCuzsyoO5X8UA==", "From": "\"Richard Genoud (TI)\" <richard.genoud@bootlin.com>", "To": "Tom Rini <trini@konsulko.com>, Manorit Chawdhry <m-chawdhry@ti.com>,\n Apurva Nandan <a-nandan@ti.com>, \"Andrew F . Davis\" <afd@ti.com>,\n Vignesh Raghavendra <vigneshr@ti.com>, Bryan Brattlof <bb@ti.com>,\n Vaishnav Achath <vaishnav.a@ti.com>, Jayesh Choudhary <j-choudhary@ti.com>,\n Simon Glass <sjg@chromium.org>, Alper Nebi Yasak <alpernebiyasak@gmail.com>", "Cc": "Markus Schneider-Pargmann <msp@baylibre.com>,\n Udit Kumar <u-kumar1@ti.com>,\n Abhash Kumar <a-kumar2@ti.com>,\n Thomas Richard <thomas.richard@bootlin.com>,\n Gregory CLEMENT <gregory.clement@bootlin.com>,\n Thomas Petazzoni <thomas.petazzoni@bootlin.com>,\n Richard Genoud <richard.genoud@bootlin.com>, u-boot@lists.denx.de", "Subject": "[PATCH 07/20] ram: k3-ddrss: Add exit retention support", "Date": "Thu, 30 Apr 2026 10:44:00 +0200", "Message-ID": "<20260430084414.1354490-8-richard.genoud@bootlin.com>", "X-Mailer": "git-send-email 2.47.3", "In-Reply-To": "<20260430084414.1354490-1-richard.genoud@bootlin.com>", "References": "<20260430084414.1354490-1-richard.genoud@bootlin.com>", "MIME-Version": "1.0", "Content-Transfer-Encoding": "8bit", "X-Last-TLS-Session-Version": "TLSv1.3", "X-BeenThere": "u-boot@lists.denx.de", "X-Mailman-Version": "2.1.39", "Precedence": "list", "List-Id": "U-Boot discussion <u-boot.lists.denx.de>", "List-Unsubscribe": "<https://lists.denx.de/options/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=unsubscribe>", "List-Archive": "<https://lists.denx.de/pipermail/u-boot/>", "List-Post": "<mailto:u-boot@lists.denx.de>", "List-Help": "<mailto:u-boot-request@lists.denx.de?subject=help>", "List-Subscribe": "<https://lists.denx.de/listinfo/u-boot>,\n <mailto:u-boot-request@lists.denx.de?subject=subscribe>", "Errors-To": "u-boot-bounces@lists.denx.de", "Sender": "\"U-Boot\" <u-boot-bounces@lists.denx.de>", "X-Virus-Scanned": "clamav-milter 0.103.8 at phobos.denx.de", "X-Virus-Status": "Clean" }, "content": "From: \"Thomas Richard (TI)\" <thomas.richard@bootlin.com>\n\nAdd functions that implements retention exit sequence of DDR.\n\nTypical DDR resume sequence is:\n- exit DDR from retention\n- de-assert the DDR_RET pin\n- restore DDR max frequency\n- exit DDR from low power\n\nWe have to separate each action in order to de-assert the DDR_RET pins\nat the right time, because the DDR_RET pins are all tied together\nin hardware.\nAdditional interleaving to be taken care and configuring of PMIC differs\ndevice to device depending on number of PMIC.\n\nSigned-off-by: Thomas Richard (TI) <thomas.richard@bootlin.com>\nCo-developed-by: Richard Genoud (TI) <richard.genoud@bootlin.com>\nSigned-off-by: Richard Genoud (TI) <richard.genoud@bootlin.com>\n---\n arch/arm/mach-k3/include/mach/k3-ddr.h | 16 ++\n drivers/ram/k3-ddrss/k3-ddrss.c | 253 +++++++++++++++++++++++++\n drivers/ram/k3-ddrss/lpddr4_k3_reg.h | 94 +++++++++\n 3 files changed, 363 insertions(+)\n create mode 100644 drivers/ram/k3-ddrss/lpddr4_k3_reg.h", "diff": "diff --git a/arch/arm/mach-k3/include/mach/k3-ddr.h b/arch/arm/mach-k3/include/mach/k3-ddr.h\nindex 6ac7f682fb80..5dd4025bdbb7 100644\n--- a/arch/arm/mach-k3/include/mach/k3-ddr.h\n+++ b/arch/arm/mach-k3/include/mach/k3-ddr.h\n@@ -7,6 +7,7 @@\n #define _K3_DDR_H_\n \n #include <spl.h>\n+#include <compiler.h>\n \n /* We need 4 extra entries for:\n * 1. SoC peripherals\n@@ -17,10 +18,25 @@\n #define K3_MEM_MAP_LEN\t\t\t((CONFIG_NR_DRAM_BANKS) + 4)\n #define K3_MEM_MAP_FIRST_BANK_IDX\t3\n \n+struct k3_ddrss_regs {\n+\tu32 ctl_141;\n+\tu32 phy_1305;\n+\tu32 ctl_88;\n+\tu32 pi_134;\n+\tu32 pi_7;\n+\tu32 ctl_20;\n+\tu32 wdqlvl_f1;\n+\tu32 wdqlvl_f2;\n+};\n+\n int dram_init(void);\n int dram_init_banksize(void);\n \n void fixup_ddr_driver_for_ecc(struct spl_image_info *spl_image);\n void fixup_memory_node(struct spl_image_info *spl_image);\n \n+/* LPDDR4 power management functions */\n+void k3_ddrss_lpddr4_exit_retention(struct udevice *dev, struct k3_ddrss_regs *regs);\n+void k3_ddrss_lpddr4_change_freq(struct udevice *dev);\n+void k3_ddrss_lpddr4_exit_low_power(struct udevice *dev, struct k3_ddrss_regs *regs);\n #endif /* _K3_DDR_H_ */\ndiff --git a/drivers/ram/k3-ddrss/k3-ddrss.c b/drivers/ram/k3-ddrss/k3-ddrss.c\nindex 27823e91d5ef..7b2d2e0814b8 100644\n--- a/drivers/ram/k3-ddrss/k3-ddrss.c\n+++ b/drivers/ram/k3-ddrss/k3-ddrss.c\n@@ -19,12 +19,14 @@\n #include <power-domain.h>\n #include <wait_bit.h>\n #include <power/regulator.h>\n+#include <mach/k3-ddr.h>\n \n #include \"k3-ddrss-lpm.h\"\n #include \"lpddr4_obj_if.h\"\n #include \"lpddr4_if.h\"\n #include \"lpddr4_structs_if.h\"\n #include \"lpddr4_ctl_regs.h\"\n+#include \"lpddr4_k3_reg.h\"\n \n #define SRAM_MAX 512\n \n@@ -441,6 +443,257 @@ static int k3_ddrss_ofdata_to_priv(struct udevice *dev)\n \treturn ret;\n }\n \n+#if defined(CONFIG_K3_J721E_DDRSS)\n+\n+void k3_ddrss_lpddr4_exit_retention(struct udevice *dev,\n+\t\t\t\t struct k3_ddrss_regs *regs)\n+{\n+\tstruct k3_ddrss_desc *ddrss = dev_get_priv(dev);\n+\tu32 regval;\n+\tunsigned int pll_ctrl;\n+\tunsigned int val;\n+\n+\t/*\n+\t * Saving registers\n+\t */\n+\tlpddr4_k3_readreg_ctl(ddrss, DENALI_CTL_141, ®s->ctl_141);\n+\tlpddr4_k3_readreg_phy(ddrss, DENALI_PHY_1305, ®s->phy_1305);\n+\tlpddr4_k3_readreg_ctl(ddrss, DENALI_CTL_88, ®s->ctl_88);\n+\tlpddr4_k3_readreg_pi(ddrss, DENALI_PI_134, ®s->pi_134);\n+\t// PI_139 cannot be restored\n+\tlpddr4_k3_readreg_pi(ddrss, DENALI_PI_7, ®s->pi_7);\n+\tlpddr4_k3_readreg_ctl(ddrss, DENALI_CTL_20, ®s->ctl_20);\n+\n+\t/* disable auto entry / exit */\n+\tlpddr4_k3_clr_ctl(ddrss, DENALI_CTL_141, (0xF << 24) | (0xF << 16));\n+\n+\t/* Configure DFI Interface, DDR retention exit occurs through PHY */\n+\tlpddr4_k3_readreg_phy(ddrss, LPDDR4__PHY_SET_DFI_INPUT_0__REG, ®val);\n+\tregval &= ~0xF0F; // Set DFI_Input_1 = 0\n+\tregval |= 0x01; // Set DFI Input_0 = 1\n+\tlpddr4_k3_writereg_phy(ddrss, LPDDR4__PHY_SET_DFI_INPUT_0__REG, regval);\n+\n+\t/* PWRUP_SREFRESH_EXIT = 1 */\n+\tlpddr4_k3_set_ctl(ddrss, LPDDR4__PWRUP_SREFRESH_EXIT__REG, 0x1);\n+\n+\t/* PI_PWRUP_SREFRESH_EXIT = 0 */\n+\tlpddr4_k3_clr_pi(ddrss, LPDDR4__PI_PWRUP_SREFRESH_EXIT__REG, 0x1 << 16);\n+\n+\t/* PI_DRAM_INIT_EN = 0 */\n+\tlpddr4_k3_clr_pi(ddrss, LPDDR4__PI_DRAM_INIT_EN__REG, 0x1 << 8);\n+\n+\t/* PI_DFI_PHYMSTR_STATE_SEL_R = 1 (force memory into self-refresh) */\n+\tlpddr4_k3_set_pi(ddrss, LPDDR4__PI_DFI_PHYMSTR_STATE_SEL_R__REG, (1 << 24));\n+\n+\t/* PHY_INDEP_INIT_MODE = 0 */\n+\tlpddr4_k3_clr_ctl(ddrss, LPDDR4__PHY_INDEP_INIT_MODE__REG, (0x1 << 16));\n+\n+\t/* PHY_INDEP_TRAIN_MODE = 1 */\n+\tlpddr4_k3_set_ctl(ddrss, LPDDR4__PHY_INDEP_TRAIN_MODE__REG, 0x1);\n+\n+\tlpddr4_k3_readreg_pi(ddrss, LPDDR4__PI_WDQLVL_EN_F1__REG, ®s->wdqlvl_f1);\n+\tregs->wdqlvl_f1 &= LPDDR4__DENALI_PI_214__PI_WDQLVL_EN_F1_MASK;\n+\n+\tlpddr4_k3_readreg_pi(ddrss, LPDDR4__PI_WDQLVL_EN_F2__REG, ®s->wdqlvl_f2);\n+\tregs->wdqlvl_f2 &= LPDDR4__DENALI_PI_217__PI_WDQLVL_EN_F2_MASK;\n+\n+\t/* clear periodic WDQLVL for F0 */\n+\tlpddr4_k3_clr_pi(ddrss, LPDDR4__PI_WDQLVL_EN_F0__REG,\n+\t\t\t 0x2 << LPDDR4__DENALI_PI_212__PI_WDQLVL_EN_F0_SHIFT);\n+\n+\t/* clear periodic WDQLVL for F1 */\n+\tlpddr4_k3_clr_pi(ddrss, LPDDR4__PI_WDQLVL_EN_F1__REG,\n+\t\t\t 0x2 << LPDDR4__DENALI_PI_214__PI_WDQLVL_EN_F1_SHIFT);\n+\n+\t/* clear periodic WDQLVL for F2 */\n+\tlpddr4_k3_clr_pi(ddrss, LPDDR4__PI_WDQLVL_EN_F2__REG,\n+\t\t\t 0x2 << LPDDR4__DENALI_PI_217__PI_WDQLVL_EN_F2_SHIFT);\n+\n+#define PLL_CTRL_OFF 0x20\n+#define PLL_CFG 0x00680000\n+\tswitch (ddrss->instance) {\n+\tcase 0:\n+\t\tpll_ctrl = PLL_CFG + 12 * 0x1000 + PLL_CTRL_OFF;\n+\t\tbreak;\n+\tcase 1:\n+\t\tpll_ctrl = PLL_CFG + 26 * 0x1000 + PLL_CTRL_OFF;\n+\t\tbreak;\n+\tcase 2:\n+\t\tpll_ctrl = PLL_CFG + 27 * 0x1000 + PLL_CTRL_OFF;\n+\t\tbreak;\n+\tcase 3:\n+\t\tpll_ctrl = PLL_CFG + 28 * 0x1000 + PLL_CTRL_OFF;\n+\t\tbreak;\n+\t}\n+\n+\t*(unsigned int *)pll_ctrl |= 0x80000000;\n+\tval = *(unsigned int *)pll_ctrl;\n+\tif ((val & 0x80000000) != 0x80000000)\n+\t\tval = *(unsigned int *)pll_ctrl;\n+}\n+\n+void k3_ddrss_lpddr4_change_freq(struct udevice *dev)\n+{\n+\tstruct k3_ddrss_desc *ddrss = dev_get_priv(dev);\n+\tu32 regval;\n+\tunsigned long tmo;\n+\n+\t/* PI_START=1 */\n+\tlpddr4_k3_set_pi(ddrss, LPDDR4__PI_START__REG, 0x01);\n+\t/* START=1 */\n+\tlpddr4_k3_set_ctl(ddrss, LPDDR4__START__REG, 0x01);\n+\n+\tk3_lpddr4_freq_update(ddrss);\n+\n+\ttmo = timer_get_us() + 100000;\n+\tdo {\n+\t\tlpddr4_k3_readreg_pi(ddrss, LPDDR4__PI_INT_STATUS__REG, ®val);\n+\t\tif (timer_get_us() > tmo) {\n+\t\t\tprintf(\"%s:%d timeout error\\n\", __func__, __LINE__);\n+\t\t\thang();\n+\t\t}\n+\t} while ((regval & (1 << 0)) == 0x00);\n+\n+\ttmo = timer_get_us() + 4000;\n+\tdo {\n+\t\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__INT_STATUS_0__REG, ®val);\n+\t\tif (timer_get_us() > tmo) {\n+\t\t\tprintf(\"%s:%d timeout error\\n\", __func__, __LINE__);\n+\t\t\thang();\n+\t\t}\n+\t} while ((regval & (1 << 9)) == 0x00);\n+\n+\tlpddr4_k3_readreg_pi(ddrss, LPDDR4__PI_INT_STATUS__REG, ®val);\n+\tdebug(\"%s: PI interrupt status: 0x%08x\\n\", __func__, regval);\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__INT_STATUS_0__REG, ®val);\n+\tdebug(\"%s: Controller interrupt status: 0x%08x\\n\", __func__, regval);\n+\n+\tdebug(\"%s: Successfully exited Retention\\n\", __func__);\n+}\n+\n+void k3_ddrss_lpddr4_exit_low_power(struct udevice *dev,\n+\t\t\t\t struct k3_ddrss_regs *regs)\n+{\n+\tstruct k3_ddrss_desc *ddrss = dev_get_priv(dev);\n+\tu32 regval, fspop, fspwr;\n+\tunsigned long tmo;\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__LP_STATE_CS0__REG, ®val);\n+\tdebug(\"%s: LP State: 0x%08x\\n\", __func__, regval);\n+\n+\t/* make sure that LP flag is clear before going through this process */\n+\tlpddr4_k3_writereg_ctl(ddrss, LPDDR4__INT_ACK_0__REG, (0x1 << 10));\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__CKSRX_F1__REG, ®val);\n+\tregval &= ~(0x7F << 24);\n+\tregval |= (0x2 << 24); // set low power mode exit\n+\tlpddr4_k3_writereg_ctl(ddrss, LPDDR4__CKSRX_F1__REG, regval);\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__LP_STATE_CS0__REG, ®val);\n+\tdebug(\"%s: LP State: 0x%08x\\n\", __func__, regval);\n+\n+\t/* wait until low power operation has been completed */\n+\ttmo = timer_get_us() + 4000;\n+\tdo {\n+\t\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__INT_STATUS_0__REG, ®val);\n+\t\tif (timer_get_us() > tmo) {\n+\t\t\tprintf(\"%s:%d timeout error\\n\", __func__, __LINE__);\n+\t\t\thang();\n+\t\t}\n+\t} while ((regval & (0x1 << 10)) == 0);\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__LP_STATE_CS0__REG, ®val);\n+\tdebug(\"%s: LP State: 0x%08x\\n\", __func__, regval);\n+\n+\tlpddr4_k3_writereg_ctl(ddrss, LPDDR4__INT_ACK_0__REG, (0x1 << 10));\n+\n+\t/*\n+\t * bit 6 / 14 -- lp_state valid\n+\t * bits 13:8 / 5:0 0x0F SRPD Long with Mem and Controller Clk Gating\n+\t */\n+\ttmo = timer_get_us() + 4000;\n+\tdo {\n+\t\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__LP_STATE_CS0__REG, ®val);\n+\t\tif (timer_get_us() > tmo) {\n+\t\t\tprintf(\"%s:%d timeout error\\n\", __func__, __LINE__);\n+\t\t\thang();\n+\t\t}\n+\t} while ((regval & 0x4F4F) != 0x4040);\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, LPDDR4__LP_STATE_CS0__REG, ®val);\n+\tdebug(\"%s: LP State: 0x%08x\\n\", __func__, regval);\n+\n+\t/*\n+\t * MR13 data within the PI is based upon CS but NOT based upon\n+\t * frequency set point.\n+\t * MR13 is the current MR13 value\n+\t */\n+\tlpddr4_k3_readreg_pi(ddrss, LPDDR4__PI_MR13_DATA_0__REG, ®val);\n+\tfspop = (regval & ((u32)1 << 31)) >> 31;\n+\tfspwr = (regval & ((u32)1 << 30)) >> 30;\n+\n+\tlpddr4_k3_set_ctl(ddrss, LPDDR4__FSP_OP_CURRENT__REG,\n+\t\t\t fspop << LPDDR4__DENALI_CTL_192__FSP_OP_CURRENT_SHIFT);\n+\n+\tlpddr4_k3_set_ctl(ddrss, LPDDR4__FSP_WR_CURRENT__REG,\n+\t\t\t fspwr << LPDDR4__DENALI_CTL_192__FSP_WR_CURRENT_SHIFT);\n+\n+\t// do not allow CTL to update MR\n+\tlpddr4_k3_set_ctl(ddrss, LPDDR4__FSP_PHY_UPDATE_MRW__REG,\n+\t\t\t 1 << LPDDR4__DENALI_CTL_191__FSP_PHY_UPDATE_MRW_SHIFT);\n+\n+\t// do not allow PI to update MR\n+\tlpddr4_k3_clr_pi(ddrss, DENALI_PI_64, 1 << 0);\n+\n+\t// PI_FREQ_MAP defines supported working frequencies\n+\tlpddr4_k3_readreg_pi(ddrss, LPDDR4__PI_FREQ_MAP__REG, ®val);\n+\tif (regval & (0x1 << 1)) {\n+\t\t// define FSP0 and FSP1 as trained\n+\t\tlpddr4_k3_set_ctl(ddrss, LPDDR4__MR_FSP_DATA_VALID_F0__REG,\n+\t\t\t\t LPDDR4__DENALI_CTL_190__MR_FSP_DATA_VALID_F0_MASK);\n+\t\tlpddr4_k3_set_ctl(ddrss, LPDDR4__MR_FSP_DATA_VALID_F1__REG,\n+\t\t\t\t LPDDR4__DENALI_CTL_190__MR_FSP_DATA_VALID_F1_MASK);\n+\t}\n+\tif (regval & (0x1 << 2)) {\n+\t\t// define FSP0 and FSP2 as trained\n+\t\tlpddr4_k3_set_ctl(ddrss, LPDDR4__MR_FSP_DATA_VALID_F0__REG,\n+\t\t\t\t LPDDR4__DENALI_CTL_190__MR_FSP_DATA_VALID_F0_MASK);\n+\t\tlpddr4_k3_set_ctl(ddrss, LPDDR4__MR_FSP_DATA_VALID_F2__REG,\n+\t\t\t\t LPDDR4__DENALI_CTL_190__MR_FSP_DATA_VALID_F2_MASK);\n+\t}\n+\n+\t/*\n+\t * Restore registers\n+\t */\n+\tlpddr4_k3_writereg_ctl(ddrss, DENALI_CTL_141, regs->ctl_141);\n+\tlpddr4_k3_writereg_phy(ddrss, DENALI_PHY_1305, regs->phy_1305);\n+\tlpddr4_k3_writereg_ctl(ddrss, DENALI_CTL_88, regs->ctl_88);\n+\tlpddr4_k3_writereg_pi(ddrss, DENALI_PI_134, regs->pi_134);\n+\t// PI_139 cannot be restored\n+\tlpddr4_k3_writereg_pi(ddrss, DENALI_PI_7, regs->pi_7);\n+\tlpddr4_k3_writereg_ctl(ddrss, DENALI_CTL_20, regs->ctl_20);\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, DENALI_CTL_141, ®s->ctl_141);\n+\tlpddr4_k3_readreg_phy(ddrss, DENALI_PHY_1305, ®s->phy_1305);\n+\tlpddr4_k3_readreg_ctl(ddrss, DENALI_CTL_88, ®s->ctl_88);\n+\t// PI_139 cannot be restored\n+\tlpddr4_k3_readreg_pi(ddrss, DENALI_PI_7, ®s->pi_7);\n+\n+\tlpddr4_k3_readreg_pi(ddrss, DENALI_PI_79, ®val);\n+\tlpddr4_k3_writereg_pi(ddrss, DENALI_PI_80, regval);\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, DENALI_CTL_293, ®val);\n+\tlpddr4_k3_writereg_ctl(ddrss, DENALI_CTL_295, regval);\n+\n+\tlpddr4_k3_readreg_ctl(ddrss, DENALI_CTL_294, ®val);\n+\tlpddr4_k3_writereg_ctl(ddrss, DENALI_CTL_296, regval);\n+\n+\tlpddr4_k3_set_pi(ddrss, DENALI_PI_214, regs->wdqlvl_f1);\n+\tlpddr4_k3_set_pi(ddrss, DENALI_PI_217, regs->wdqlvl_f2);\n+}\n+#endif /* CONFIG_K3_J721E_DDRSS */\n+\n void k3_lpddr4_probe(struct k3_ddrss_desc *ddrss)\n {\n \tu32 status = 0U;\ndiff --git a/drivers/ram/k3-ddrss/lpddr4_k3_reg.h b/drivers/ram/k3-ddrss/lpddr4_k3_reg.h\nnew file mode 100644\nindex 000000000000..aca56200a96b\n--- /dev/null\n+++ b/drivers/ram/k3-ddrss/lpddr4_k3_reg.h\n@@ -0,0 +1,94 @@\n+/* SPDX-License-Identifier: BSD-3-Clause */\n+/*\n+ * Copyright (C) 2026 Texas Instruments Incorporated - https://www.ti.com/\n+ */\n+\n+#ifndef LPDDR4_K3_REG\n+#define LPDDR4_K3_REG\n+\n+#define _lpddr4_k3_readreg(_shift, _fnct, _ddrss, _reg, _p) do {\t\\\n+\tu16 offset = 0U;\t\t\t\t\t\t\\\n+\tu32 result = 0U;\t\t\t\t\t\t\\\n+\tTH_OFFSET_FROM_REG(_reg, _shift, offset);\t\t\t\\\n+\tresult = (_fnct)(&(_ddrss)->pd, _p, (u16 *)(&offset), 1);\t\\\n+\tif (result > 0U) {\t\t\t\t\t\t\\\n+\t\tprintf(\"%s: Failed to read %s\\n\", __func__, xstr(_reg));\\\n+\t\thang();\t\t\t\t\t\t\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+} while (0)\n+\n+#define _lpddr4_k3_writereg(_shift, _fnct, _ddrss, _reg, _val) do {\t\\\n+\tu16 offset = 0U;\t\t\t\t\t\t\\\n+\tu32 result = 0U;\t\t\t\t\t\t\\\n+\tu32 writeval = _val;\t\t\t\t\t\t\\\n+\tTH_OFFSET_FROM_REG(_reg, _shift, offset);\t\t\t\\\n+\tresult = (_fnct)(&(_ddrss)->pd,\t&writeval, (u16 *)(&offset), 1);\\\n+\tif (result > 0U) {\t\t\t\t\t\t\\\n+\t\tprintf(\"%s: Failed to write %s\\n\", __func__, xstr(_reg));\\\n+\t\thang();\t\t\t\t\t\t\t\\\n+\t}\t\t\t\t\t\t\t\t\\\n+} while (0)\n+\n+#define lpddr4_k3_readreg_ctl(_ddrss, _reg, _pt)\t\t\\\n+\t_lpddr4_k3_readreg(CTL_SHIFT,\t\t\t\t\\\n+\t\t\t (_ddrss)->driverdt->readctlconfig,\t\\\n+\t\t\t _ddrss, _reg, _pt)\n+\n+#define lpddr4_k3_readreg_pi(_ddrss, _reg, _pt)\t\t\t\t\\\n+\t_lpddr4_k3_readreg(PI_SHIFT,\t\t\t\t\t\\\n+\t\t\t (_ddrss)->driverdt->readphyindepconfig,\t\\\n+\t\t\t _ddrss, _reg, _pt)\n+\n+#define lpddr4_k3_readreg_phy(_ddrss, _reg, _pt)\t\t\\\n+\t_lpddr4_k3_readreg(PHY_SHIFT,\t\t\t\t\\\n+\t\t\t (_ddrss)->driverdt->readphyconfig,\t\\\n+\t\t\t _ddrss, _reg, _pt)\n+\n+#define lpddr4_k3_writereg_ctl(_ddrss, _reg, _val)\t\t\\\n+\t_lpddr4_k3_writereg(CTL_SHIFT,\t\t\t\t\\\n+\t\t\t (_ddrss)->driverdt->writectlconfig,\t\\\n+\t\t\t _ddrss, _reg, _val)\n+\n+#define lpddr4_k3_writereg_pi(_ddrss, _reg, _val)\t\t\t\\\n+\t_lpddr4_k3_writereg(PI_SHIFT,\t\t\t\t\t\\\n+\t\t\t (_ddrss)->driverdt->writephyindepconfig,\t\\\n+\t\t\t _ddrss, _reg, _val)\n+\n+#define lpddr4_k3_writereg_phy(_ddrss, _reg, _val)\t\t\\\n+\t_lpddr4_k3_writereg(PHY_SHIFT,\t\t\t\t\\\n+\t\t\t (_ddrss)->driverdt->writephyconfig,\t\\\n+\t\t\t _ddrss, _reg, _val)\n+\n+#define _lpddr4_k3_set(_type, _ddrss, _reg, _mask) do {\t\\\n+\tu32 _val;\t\t\t\t\t\\\n+\tlpddr4_k3_readreg_##_type(_ddrss, _reg, &_val);\t\\\n+\t_val |= _mask;\t\t\t\t\t\\\n+\tlpddr4_k3_writereg_##_type(_ddrss, _reg, _val);\t\\\n+} while (0)\n+\n+#define _lpddr4_k3_clr(_type, _ddrss, _reg, _mask) do {\t\\\n+\tu32 _val;\t\t\t\t\t\\\n+\tlpddr4_k3_readreg_##_type(_ddrss, _reg, &_val);\t\\\n+\t_val &= ~(_mask);\t\t\t\t\\\n+\tlpddr4_k3_writereg_##_type(_ddrss, _reg, _val);\t\\\n+} while (0)\n+\n+#define lpddr4_k3_set_ctl(_ddrss, _reg, _mask)\t\\\n+\t_lpddr4_k3_set(ctl, _ddrss, _reg, _mask)\n+\n+#define lpddr4_k3_clr_ctl(_ddrss, _reg, _mask) \\\n+\t_lpddr4_k3_clr(ctl, _ddrss, _reg, _mask)\n+\n+#define lpddr4_k3_set_pi(_ddrss, _reg, _mask) \\\n+\t_lpddr4_k3_set(pi, _ddrss, _reg, _mask)\n+\n+#define lpddr4_k3_clr_pi(_ddrss, _reg, _mask) \\\n+\t_lpddr4_k3_clr(pi, _ddrss, _reg, _mask)\n+\n+#define lpddr4_k3_set_phy(_ddrss, _reg, _mask) \\\n+\t_lpddr4_k3_set(phy, _ddrss, _reg, _mask)\n+\n+#define lpddr4_k3_clr_phy(_ddrss, _reg, _mask) \\\n+\t_lpddr4_k3_clr(phy, _ddrss, _reg, _mask)\n+\n+#endif /* LPDDR4_K3_REG */\n", "prefixes": [ "07/20" ] }