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 8EDBE3839AD; Mon, 5 May 2025 23:09:50 +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=1746486591; cv=none; b=o52l7Z4V9z/S3s3YwG/ysLJ8x8/SFSuUtU6nVl70ywJVgiee5tYmjmSznnEBWR8tOqATtvuSu91t/enGhQMy6pOY5X4VrccRsJeo//HVrnkibSl0EF56iivOOLo0vAPjedQ7zyHO3RvKZj1r0dGhxxx7Be3kMxEidvZNST7aW3g= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1746486591; c=relaxed/simple; bh=kdgouvIuSf+MepR2cgLgP4/YpNyYF3lj0hkGQS+dlvA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=pBd+Xqsz3EBSjoPcHJ76gIcY/ZB6RjaHozSfrEkc2qlKIWEEqVYhXxm3E85oqE81bWX+UBkAx+c4OaJaNMVpu8L4lnX5ZDHkPVVRl8FQrHU1fTV6924fgQD77YXfiqbU4qyEDUnk2Fm2EO3eSwO35K03yv5lPnrCPhrdRSp3rNo= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=B4cIbzG0; 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="B4cIbzG0" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 2A8AEC4CEED; Mon, 5 May 2025 23:09:49 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1746486590; bh=kdgouvIuSf+MepR2cgLgP4/YpNyYF3lj0hkGQS+dlvA=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=B4cIbzG0tSTtq3iLJjIBYa2bBqtPdR/p88UEUjP1fbm3JSCNUgy3IAsPH9Vm2BBwd L/YRhuBm2Z5MXcNdd1np7f4XaPlCvQfbxrE9F1saHQk7BykjJ9y8Ftng+hAK/wU+tI EhpFyUNpSG2EVTck7g5wEUqAYXaE539nXrvjsFYTNwsmnALJVySThJTwvgIXZ2XHz+ hXJUPQ1+cclodkq87Cue8TXzYqZyYOSALpzfpKM4bcQufxN8TIyaTvVBq2ucL3r42P CLiCORvfgzfc6HvWLRgBiI0uQTZ0ocTQOuCVXwWGMhLcYs0CshWk9VQoAT1ek1awT6 iHaubibCcIYpQ== 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.1 105/212] ARM: at91: pm: fix at91_suspend_finish for ZQ calibration Date: Mon, 5 May 2025 19:04:37 -0400 Message-Id: <20250505230624.2692522-105-sashal@kernel.org> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250505230624.2692522-1-sashal@kernel.org> References: <20250505230624.2692522-1-sashal@kernel.org> Precedence: bulk X-Mailing-List: stable@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.1.136 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 4d0d0d49a7442..77aec670f635c 100644 --- a/arch/arm/mach-at91/pm.c +++ b/arch/arm/mach-at91/pm.c @@ -537,11 +537,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; @@ -552,25 +553,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