From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (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 6222D2FBAB8; Mon, 5 May 2025 22:25:51 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746483951; cv=none; b=mLlOKhthHQWEu4rZUfLb7oMDdAU3Qd1ilzXjbMyZnNGVPpnHCe3BN+5oRCjY1HOttJCQo3iB0NywfJs7wbiGkk3Heb6ahMzPvRjBds6OvUdA9m1JAfPqzqaCvVuIayw/Yd08PCuUbdp7cwFDx5eUOhhrQ4tQHrI+MSek0Bkio5I= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746483951; c=relaxed/simple; bh=hcwdfhhGaHajzSEOCx6SVqIs1/onTusH1hNuhmcLL/8=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=gLhNvVzoVRJ60SsI/Q3h1c5r9thd3xmh4mReJZQNPColR3H8XKufUFOLl5/PylaVqhgkzUCCUbIkcT+yJc+Jvq1tw7W9GHRmdjkBnDaWxssN8ixEpf/nonNZMMeiaK5MaNdBKOQ1f8PFH447JnxQnf5Pe6aJavOyOZzRkONeH1Y= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MhtKieVY; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MhtKieVY" Received: by smtp.kernel.org (Postfix) with ESMTPSA id F311EC4CEED; Mon, 5 May 2025 22:25:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746483951; bh=hcwdfhhGaHajzSEOCx6SVqIs1/onTusH1hNuhmcLL/8=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=MhtKieVYM6HVaVWeVklfntalNoWO64H2nl+Ke7a+ZBgWOCpTyMD526Xr8E5UsjHNz apAlGSQ+EzsRoiCznsrn9KS72Nv66gkK2ULgjEk6kGZbOERMzsVjB8LLLFFdZRDvvV 3B6jSogcnbBYEzcYG+yYBUJMa8BrHLhve1fzuD4C6dPFczmHVrWGD8OJ+2PKpPwlTW HlF4mgw1SqSDUwBYlKhpJbes5lOQkNAccgfdteQLEofXrj3hecfCHhKshDAFLkml8t E0hwM6z+aSbpiqu5VnAC/x85P9c0imW3KHUoHlFITzBRK/zfmLrThdHa8LSZWDK8tG +zAOiyV/ycMZg== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Li Bin , Nicolas Ferre , Ryan Wanner , Durai Manickam KR , Andrei Simion , Claudiu Beznea , Sasha Levin , linux@armlinux.org.uk, alexandre.belloni@bootlin.com, linux-arm-kernel@lists.infradead.org Subject: [PATCH AUTOSEL 6.14 286/642] ARM: at91: pm: fix at91_suspend_finish for ZQ calibration Date: Mon, 5 May 2025 18:08:22 -0400 Message-Id: <20250505221419.2672473-286-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250505221419.2672473-1-sashal@kernel.org> References: <20250505221419.2672473-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore X-stable-base: Linux 6.14.5 Content-Transfer-Encoding: 8bit From: Li Bin [ Upstream commit bc4722c3598d0e2c2dbf9609a3d3198993093e2b ] For sama7g5 and sama7d65 backup mode, we encountered a "ZQ calibrate error" during recalibrating the impedance in BootStrap. We found that the impedance value saved in at91_suspend_finish() before the DDR entered self-refresh mode did not match the resistor values. The ZDATA field in the DDR3PHY_ZQ0CR0 register uses a modified gray code to select the different impedance setting. But these gray code are incorrect, a workaournd from design team fixed the bug in the calibration logic. The ZDATA contains four independent impedance elements, but the algorithm combined the four elements into one. The elements were fixed using properly shifted offsets. Signed-off-by: Li Bin [nicolas.ferre@microchip.com: fix indentation and combine 2 patches] Signed-off-by: Nicolas Ferre Tested-by: Ryan Wanner Tested-by: Durai Manickam KR Tested-by: Andrei Simion Signed-off-by: Ryan Wanner Link: https://lore.kernel.org/r/28b33f9bcd0ca60ceba032969fe054d38f2b9577.1740671156.git.Ryan.Wanner@microchip.com Signed-off-by: Claudiu Beznea Signed-off-by: Sasha Levin --- arch/arm/mach-at91/pm.c | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/arch/arm/mach-at91/pm.c b/arch/arm/mach-at91/pm.c index 05a1547642b60..6c3e6aa22606f 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -545,11 +545,12 @@ extern u32 at91_pm_suspend_in_sram_sz; static int at91_suspend_finish(unsigned long val) { - unsigned char modified_gray_code[] = { - 0x00, 0x01, 0x02, 0x03, 0x06, 0x07, 0x04, 0x05, 0x0c, 0x0d, - 0x0e, 0x0f, 0x0a, 0x0b, 0x08, 0x09, 0x18, 0x19, 0x1a, 0x1b, - 0x1e, 0x1f, 0x1c, 0x1d, 0x14, 0x15, 0x16, 0x17, 0x12, 0x13, - 0x10, 0x11, + /* SYNOPSYS workaround to fix a bug in the calibration logic */ + unsigned char modified_fix_code[] = { + 0x00, 0x01, 0x01, 0x06, 0x07, 0x0c, 0x06, 0x07, 0x0b, 0x18, + 0x0a, 0x0b, 0x0c, 0x0d, 0x0d, 0x0a, 0x13, 0x13, 0x12, 0x13, + 0x14, 0x15, 0x15, 0x12, 0x18, 0x19, 0x19, 0x1e, 0x1f, 0x14, + 0x1e, 0x1f, }; unsigned int tmp, index; int i; @@ -560,25 +561,25 @@ static int at91_suspend_finish(unsigned long val) * restore the ZQ0SR0 with the value saved here. But the * calibration is buggy and restoring some values from ZQ0SR0 * is forbidden and risky thus we need to provide processed - * values for these (modified gray code values). + * values for these. */ tmp = readl(soc_pm.data.ramc_phy + DDR3PHY_ZQ0SR0); /* Store pull-down output impedance select. */ index = (tmp >> DDR3PHY_ZQ0SR0_PDO_OFF) & 0x1f; - soc_pm.bu->ddr_phy_calibration[0] = modified_gray_code[index]; + soc_pm.bu->ddr_phy_calibration[0] = modified_fix_code[index] << DDR3PHY_ZQ0SR0_PDO_OFF; /* Store pull-up output impedance select. */ index = (tmp >> DDR3PHY_ZQ0SR0_PUO_OFF) & 0x1f; - soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; + soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SR0_PUO_OFF; /* Store pull-down on-die termination impedance select. */ index = (tmp >> DDR3PHY_ZQ0SR0_PDODT_OFF) & 0x1f; - soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; + soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SR0_PDODT_OFF; /* Store pull-up on-die termination impedance select. */ index = (tmp >> DDR3PHY_ZQ0SRO_PUODT_OFF) & 0x1f; - soc_pm.bu->ddr_phy_calibration[0] |= modified_gray_code[index]; + soc_pm.bu->ddr_phy_calibration[0] |= modified_fix_code[index] << DDR3PHY_ZQ0SRO_PUODT_OFF; /* * The 1st 8 words of memory might get corrupted in the process -- 2.39.5