From patchwork Fri Apr 28 04:08:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Peng Fan (OSS)" X-Patchwork-Id: 1774739 X-Patchwork-Delegate: sbabic@denx.de Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: legolas.ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.a=rsa-sha256 header.s=selector2-NXP1-onmicrosoft-com header.b=ff86gcc7; dkim-atps=neutral Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (P-384)) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4Q6yfq6X7nz23v9 for ; Fri, 28 Apr 2023 13:25:39 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id EE8C48641E; Fri, 28 Apr 2023 05:20:39 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=oss.nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=NXP1.onmicrosoft.com header.i=@NXP1.onmicrosoft.com header.b="ff86gcc7"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id CD16B863DE; Fri, 28 Apr 2023 05:19:38 +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=-0.9 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,FORGED_SPF_HELO,SPF_HELO_PASS,T_SCC_BODY_TEXT_LINE, T_SPF_PERMERROR autolearn=no autolearn_force=no version=3.4.2 Received: from EUR05-AM6-obe.outbound.protection.outlook.com (mail-am6eur05on20603.outbound.protection.outlook.com [IPv6:2a01:111:f400:7e1b::603]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 4A6F4863EB for ; Fri, 28 Apr 2023 05:19:34 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=oss.nxp.com Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=peng.fan@oss.nxp.com ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=JxB/3WVn83qSNlfYMEdl7m7w9wMSJ6gVShPt3z/2mxV4L3l04H/DBqOvuKB9wZx2IuG7nGnroQ1A72AoPFtd0gYnUWR1SqYNx5baOh2m8bILHs7qMM8N1v4LLLAyO2gKcfcsKZs2zQc9D0poDy3pU9RqZ4X27CP7rgjwZUp59nVOyEqV2uejCpEWPiGLtHAW/XRYsQiVNrsbDAHYVSgJs07dylmp0+Z9ZcT8HYiZcgknNuvVmMyaATBysUlGY0dkdwmWhVeZqgRVkF6tzoVhB4jaL9Rh3B7kjepX/iTSy+QwZXdf0lxpe7v3Njf9lSyTup6bJ0l/7C5zWmLTDoggVA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=kdgFxnAfcax0CDt/9lDYRDD70Hy+d7gbDu5QNJN/Ars=; b=DfiUD5ut5hwMldfROISIud9ZCb3F8GliebZu4UArtaPUqxNJnupfI+HXIZN3DIlYjDPKnVmEojRgj3na7Zs6Nz9SbiUSYFYyHPWbqwW+g2PegWoHpp7ExrvyNjbDLyUQ2ljnc7sh2+kgi0RdFS5GkmaJHk/xiIaKeT8XPepsdQDnzByvsec/Ja5kRElN5ayRb75tCZhVid7U3Zi5F8ZXsZZdqvVnbXJFR4TPkV2HgTo82T15iRhtXnQK2QbNMav8VksGbD+bb4HMC2el9DGb+XMcQ5hAFaXNkyouZITT8ERE2j0gk5ttwxL+fVOY7kmA5yyXwelK6CDgzZu4yscBLQ== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=oss.nxp.com; dmarc=pass action=none header.from=oss.nxp.com; dkim=pass header.d=oss.nxp.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com; s=selector2-NXP1-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=kdgFxnAfcax0CDt/9lDYRDD70Hy+d7gbDu5QNJN/Ars=; b=ff86gcc7Y8vXC2eh6rLzWWeGfNqsAQal5GDixYVm+lBwdpFVaJHhxNT8v4su4Oil7+GH8//N3WPgxlG6Q+FGD+xqIygiII+jDkrWbmO+we8Gf5IpDrSTI1MSwNJYzCQHFbEQA2k18N09NdT/1DPJlN0OC25gnN8+5YiE6GhnhpY= Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=oss.nxp.com; Received: from DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) by DB9PR04MB8233.eurprd04.prod.outlook.com (2603:10a6:10:24b::17) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.6340.21; Fri, 28 Apr 2023 03:19:32 +0000 Received: from DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::b999:f2c6:a8cc:7b4]) by DU0PR04MB9417.eurprd04.prod.outlook.com ([fe80::b999:f2c6:a8cc:7b4%5]) with mapi id 15.20.6340.022; Fri, 28 Apr 2023 03:19:32 +0000 From: "Peng Fan (OSS)" To: sbabic@denx.de, festevam@gmail.com, "NXP i.MX U-Boot Team" Cc: u-boot@lists.denx.de, Jacky Bai , Ye Li Subject: [PATCH 38/42] ddr: imx93: update the ddr init to support mult setpoints Date: Fri, 28 Apr 2023 12:08:43 +0800 Message-Id: <20230428040847.10841-39-peng.fan@oss.nxp.com> X-Mailer: git-send-email 2.40.0 In-Reply-To: <20230428040847.10841-1-peng.fan@oss.nxp.com> References: <20230428040847.10841-1-peng.fan@oss.nxp.com> X-ClientProxiedBy: SI1PR02CA0033.apcprd02.prod.outlook.com (2603:1096:4:1f6::14) To DU0PR04MB9417.eurprd04.prod.outlook.com (2603:10a6:10:358::11) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: DU0PR04MB9417:EE_|DB9PR04MB8233:EE_ X-MS-Office365-Filtering-Correlation-Id: d52e82b9-9921-463d-d2d9-08db4797627e X-MS-Exchange-SharedMailbox-RoutingAgent-Processed: True X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: 6i8Mq5kWBnMolhZ8rcXiLsmHiKKmCv9aX40pQOnizJoSe5+u1cQ28Ek6/OZi2oGAYi33nV9iFzEEIBXg5jpm874ysWzC31ydVq5Sc5Vy7E+S6Yivsn1aKg2vRQNjqVNXwAm8yw2NnUFqzp9Ik3QJXppOSI2vYNVnDFv9wkgItsvlIU3fBThAdWrsI0IU21WATk7etdHmJ4ShvgKNRZJJ/2MyEGbW3+OVEUuXK/US2yuj+nyWJUmPDTcFmU9tp8FRskBiHECR2DSklrZHrrILDejDE5AoeOEiZaqFokUxEv+xpIxwmy9e3qGmqY//mlc6c/hAeBfJYlU4SgwfV8ejSbrOwVTTD56Ip2bXeJI7jVJvJEbHe0yEixXz21VHqdtT/62w/V7gEkVUP8nYHP5SwIeG9XPkT37QB9pNZeuXacvdMenmAgzedyeIL9r5ML6VY7zkwrt4+olX7u45XabYY8tOdTF4y+yKEMB5MuM6sxnQ2EtYsDVBQpBvQS9GCfdG0gCEWvU8ttBNUWIS+4n7faP7c2bVXH4ECs+1AG1dwMXO/h25cHBJu4siJ87fc5n/8nipt0/LMOcZaAZGxXph25j8zoSLuvVjW/0VSQyoGL5c99h/fNMSqlj2SWambBlv X-Forefront-Antispam-Report: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DU0PR04MB9417.eurprd04.prod.outlook.com; PTR:; CAT:NONE; SFS:(13230028)(4636009)(346002)(136003)(396003)(366004)(39860400002)(376002)(451199021)(2906002)(52116002)(2616005)(6666004)(6486002)(54906003)(83380400001)(478600001)(26005)(6506007)(6512007)(186003)(1076003)(15650500001)(316002)(66476007)(4326008)(66556008)(66946007)(6862004)(8676002)(5660300002)(8936002)(38350700002)(38100700002)(86362001)(41300700001); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: o+u02es7+CbHRXZqx2/hGSCz3nfe9alKLaq6DpXAAHPh615Mv2EZw9XA7FkN54Tf/FLOWGnUaamaB2V4hxSlTny/m0lCj0HVjIDmkvc+uXy67qW6FnKMRk/VPuOPKsPIICY4mJtYmzJeJf+S3dNN714reBL/nREt5L+YLcsue3K36B9dliZ3Z+gG+hzL7qg8G0AALBE9IGBq45kGGAQyoCsQJbLH+cSCvU1RHo1zc5wCTk8GXJjsLlcuYLR3grX6iymgMjjurWpPz3Kg0xSo4sTAEzX1nVJ8V8ENbTY1DNv3OLJuHR9KyLS9n6dxIGkYAYjQkiMCol9gtXraXbcUafrlSXng2DcPsAxZeyAYNl+p+6lllzGgQekFwnPEZQuZDCBVytYpvj/J/PpQG/iAa6K0FXH5LFVCuDQQlSi4ghJPlfngDPLPVPYETGfH3OWN14Z0yM9MgpcKGnJ+F6YcrFEtMmsT+unMnExA2svaZB24EfFW7NypTca1XOvYOJL1Oxnb26m+6dDq/TSfIe/qNn0NT3lO/a8DHQ6Ajglt+TKtrJd39yn/IN0H3sJpd5FElorQgPvn390SnUGTHNReoK7ez6kiGMAbLUGVn5sk29/85p96jVreMz1r2NXKrO+Qo8EI3Wpkvuo3GJYvBlOf8z6OXZzWU0y/q5PjqoUDUoTRKbjnm7QLgv72xE1q7xO/QjcLm6XWzSxwKEXe+YHsvl57t4Yt5GaNMp5wHaYlbc0GDmbQI/pJFf6oJDtmQkkFYudE5gbbT4xforSsv62MB9u2hUk9/F5DwiQgbCHEEjLh0H8KX2epJOy5gv1tGYmfVQbSEKnw3EsFYgI4MjP+vwR6V2PwixP64KSZybNyDC0dfaFIHCkWZQgB0qQATujZQASH5G0nq1CFkfz1okaFDxmSk9AyJusxtEPFmz1DSGIMZoYZ5FxytgBHNAl6flqaEriWOs1B1BQ3odwRFlGEmtkuRtV9dNaNRB4UnaQry9d7/FmnvPyrv6svtdjdHzlC3sablh2orAgJjv98butKoXHJ3v0UaVM6+K4qYyrnQMymR4VwAe2E/ut4wfoNClgQ0KR+h33CsF7dcuVnLyWTF8B2XSKrmcqAQeDaJp+/Y6awYnBJDXXEhlZCSK2BAZoUB4qo+q7hLQrNkqp4InvsVTpq1rfZ5qJVKUy4l1XjHinm6WUicNwjwV3Rssm+gK6ny4nwNBv9pChLYbpvwUIX4VG9DMurCKvboQBdb9D8jDj4awSBY9FIaFgx9QkEaenggqc9/u1xRM4Rn49FwleE84SeGXZguPTUSF49ZrhrWfvyJ3ow6IFcBvsCX3qWWIAoS7U11OMXCTQT4t3d6kWhS/KYj215xCpMXXWkXlkC+f4GqNVSymN97Q5OIsAa6wft2bHP9qe9Ds12E6hPXkX6wyUdOAsYQROnj8MxkApjnlsx9dUl8/Baenn7e03qWNLx7yplbke45ESimsuhlBNflHk5ijHB8JeU9iF23wuSJHru1qQxr7uawcr8DLrN4qiN+t/u9Zdsb2ANUbpNxstKcxpteuUh9osrd5PBNd6JJd5TEoF2JXcat1vNOOWqUGx7 X-OriginatorOrg: oss.nxp.com X-MS-Exchange-CrossTenant-Network-Message-Id: d52e82b9-9921-463d-d2d9-08db4797627e X-MS-Exchange-CrossTenant-AuthSource: DU0PR04MB9417.eurprd04.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 28 Apr 2023 03:19:32.4248 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635 X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: 9DxUA1WmeSWlCsaaOC5d+8IPk55FlsZTfF1TGxGYErlUUE+M87NdZLsuWhbbGoRv4AkOONQfTWNWfJ37b7HaIQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: DB9PR04MB8233 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.39 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.8 at phobos.denx.de X-Virus-Status: Clean From: Jacky Bai Update the DDR init flow for multi-setpoint support on i.MX93. A new fsp_cfg struct need to be added in the timing file to store the diff part of the DDRC and DRAM MR register for each setpoint. Signed-off-by: Jacky Bai Reviewed-by: Ye Li Signed-off-by: Peng Fan --- arch/arm/include/asm/arch-imx8m/ddr.h | 2 +- arch/arm/include/asm/arch-imx9/ddr.h | 21 ++++- drivers/ddr/imx/imx9/ddr_init.c | 113 +++++++++++++++++++++++++- drivers/ddr/imx/phy/helper.c | 5 +- 4 files changed, 134 insertions(+), 7 deletions(-) diff --git a/arch/arm/include/asm/arch-imx8m/ddr.h b/arch/arm/include/asm/arch-imx8m/ddr.h index 2f76e7d69b9..c14855d177e 100644 --- a/arch/arm/include/asm/arch-imx8m/ddr.h +++ b/arch/arm/include/asm/arch-imx8m/ddr.h @@ -709,7 +709,7 @@ int ddr_init(struct dram_timing_info *timing_info); int ddr_cfg_phy(struct dram_timing_info *timing_info); void load_lpddr4_phy_pie(void); void ddrphy_trained_csr_save(struct dram_cfg_param *param, unsigned int num); -void dram_config_save(struct dram_timing_info *info, unsigned long base); +void *dram_config_save(struct dram_timing_info *info, unsigned long base); void board_dram_ecc_scrub(void); void ddrc_inline_ecc_scrub(unsigned int start_address, unsigned int range_address); diff --git a/arch/arm/include/asm/arch-imx9/ddr.h b/arch/arm/include/asm/arch-imx9/ddr.h index 8e4f946e5b0..2b22f3a5bea 100644 --- a/arch/arm/include/asm/arch-imx9/ddr.h +++ b/arch/arm/include/asm/arch-imx9/ddr.h @@ -13,11 +13,21 @@ #define DDR_PHY_BASE 0x4E100000 #define DDRMIX_BLK_CTRL_BASE 0x4E010000 +#define REG_DDR_SDRAM_MD_CNTL (DDR_CTL_BASE + 0x120) +#define REG_DDR_CS0_BNDS (DDR_CTL_BASE + 0x0) +#define REG_DDR_CS1_BNDS (DDR_CTL_BASE + 0x8) #define REG_DDRDSR_2 (DDR_CTL_BASE + 0xB24) #define REG_DDR_TIMING_CFG_0 (DDR_CTL_BASE + 0x104) #define REG_DDR_SDRAM_CFG (DDR_CTL_BASE + 0x110) #define REG_DDR_TIMING_CFG_4 (DDR_CTL_BASE + 0x160) #define REG_DDR_DEBUG_19 (DDR_CTL_BASE + 0xF48) +#define REG_DDR_SDRAM_CFG_3 (DDR_CTL_BASE + 0x260) +#define REG_DDR_SDRAM_CFG_4 (DDR_CTL_BASE + 0x264) +#define REG_DDR_SDRAM_MD_CNTL_2 (DDR_CTL_BASE + 0x270) +#define REG_DDR_SDRAM_MPR4 (DDR_CTL_BASE + 0x28C) +#define REG_DDR_SDRAM_MPR5 (DDR_CTL_BASE + 0x290) + +#define REG_DDR_ERR_EN (DDR_CTL_BASE + 0x1000) #define SRC_BASE_ADDR (0x44460000) #define SRC_DPHY_BASE_ADDR (SRC_BASE_ADDR + 0x1400) @@ -52,6 +62,12 @@ struct dram_cfg_param { unsigned int val; }; +struct dram_fsp_cfg { + struct dram_cfg_param ddrc_cfg[20]; + struct dram_cfg_param mr_cfg[10]; + unsigned int bypass; +}; + struct dram_fsp_msg { unsigned int drate; enum fw_type fw_type; @@ -63,6 +79,9 @@ struct dram_timing_info { /* umctl2 config */ struct dram_cfg_param *ddrc_cfg; unsigned int ddrc_cfg_num; + /* fsp config */ + struct dram_fsp_cfg *fsp_cfg; + unsigned int fsp_cfg_num; /* ddrphy config */ struct dram_cfg_param *ddrphy_cfg; unsigned int ddrphy_cfg_num; @@ -86,7 +105,7 @@ int ddr_init(struct dram_timing_info *timing_info); int ddr_cfg_phy(struct dram_timing_info *timing_info); void load_lpddr4_phy_pie(void); void ddrphy_trained_csr_save(struct dram_cfg_param *param, unsigned int num); -void dram_config_save(struct dram_timing_info *info, unsigned long base); +void *dram_config_save(struct dram_timing_info *info, unsigned long base); void board_dram_ecc_scrub(void); void ddrc_inline_ecc_scrub(unsigned int start_address, unsigned int range_address); diff --git a/drivers/ddr/imx/imx9/ddr_init.c b/drivers/ddr/imx/imx9/ddr_init.c index a1d953026f3..a2158094b28 100644 --- a/drivers/ddr/imx/imx9/ddr_init.c +++ b/drivers/ddr/imx/imx9/ddr_init.c @@ -71,14 +71,25 @@ void check_dfi_init_complete(void) setbits_le32(REG_DDRDSR_2, BIT(2)); } -void ddrc_config(struct dram_cfg_param *ddrc_config, int num) +void ddrc_config(struct dram_timing_info *dram_timing) { + u32 num = dram_timing->ddrc_cfg_num; + struct dram_cfg_param *ddrc_config; int i = 0; + ddrc_config = dram_timing->ddrc_cfg; for (i = 0; i < num; i++) { writel(ddrc_config->val, (ulong)ddrc_config->reg); ddrc_config++; } + + if (dram_timing->fsp_cfg) { + ddrc_config = dram_timing->fsp_cfg[0].ddrc_cfg; + while (ddrc_config->reg != 0) { + writel(ddrc_config->val, (ulong)ddrc_config->reg); + ddrc_config++; + } + } } static unsigned int look_for_max(unsigned int data[], unsigned int addr_start, @@ -198,10 +209,85 @@ void update_umctl2_rank_space_setting(unsigned int pstat_num) writel(tmp_t, REG_DDR_TIMING_CFG_4); } +u32 ddrc_mrr(u32 chip_select, u32 mode_reg_num, u32 *mode_reg_val) +{ + u32 temp; + + writel(0x80000000, REG_DDR_SDRAM_MD_CNTL_2); + temp = 0x80000000 | (chip_select << 28) | (mode_reg_num << 0); + writel(temp, REG_DDR_SDRAM_MD_CNTL); + while ((readl(REG_DDR_SDRAM_MD_CNTL) & 0x80000000) == 0x80000000) + ; + while (!(readl(REG_DDR_SDRAM_MPR5))) + ; + *mode_reg_val = (readl(REG_DDR_SDRAM_MPR4) & 0xFF0000) >> 16; + writel(0x0, REG_DDR_SDRAM_MPR5); + while ((readl(REG_DDR_SDRAM_MPR5))) + ; + writel(0x0, REG_DDR_SDRAM_MPR4); + writel(0x0, REG_DDR_SDRAM_MD_CNTL_2); + + return 0; +} + +void ddrc_mrs(u32 cs_sel, u32 opcode, u32 mr) +{ + u32 regval; + + regval = (cs_sel << 28) | (opcode << 6) | (mr); + writel(regval, REG_DDR_SDRAM_MD_CNTL); + setbits_le32(REG_DDR_SDRAM_MD_CNTL, BIT(31)); + check_ddrc_idle(); +} + +u32 lpddr4_mr_read(u32 mr_rank, u32 mr_addr) +{ + u32 chip_select, regval; + + if (mr_rank == 1) + chip_select = 0; /* CS0 */ + else if (mr_rank == 2) + chip_select = 1; /* CS1 */ + else + chip_select = 4; /* CS0 & CS1 */ + + ddrc_mrr(chip_select, mr_addr, ®val); + + return regval; +} + +void update_mr_fsp_op0(struct dram_cfg_param *cfg, unsigned int num) +{ + int i; + + ddrc_mrs(0x4, 0x88, 13); /* FSP-OP->1, FSP-WR->0, VRCG=1, DMD=0 */ + for (i = 0; i < num; i++) { + if (cfg[i].reg) + ddrc_mrs(0x4, cfg[i].val, cfg[i].reg); + } + ddrc_mrs(0x4, 0xc0, 13); /* FSP-OP->1, FSP-WR->1, VRCG=0, DMD=0 */ +} + +void save_trained_mr12_14(struct dram_cfg_param *cfg, u32 cfg_num, u32 mr12, u32 mr14) +{ + int i; + + for (i = 0; i < cfg_num; i++) { + if (cfg->reg == 12) + cfg->val = mr12; + else if (cfg->reg == 14) + cfg->val = mr14; + cfg++; + } +} + int ddr_init(struct dram_timing_info *dram_timing) { unsigned int initial_drate; + struct dram_timing_info *saved_timing; + void *fsp; int ret; + u32 mr12, mr14; u32 regval; debug("DDRINFO: start DRAM init\n"); @@ -229,7 +315,7 @@ int ddr_init(struct dram_timing_info *dram_timing) /* rogram the ddrc registers */ debug("DDRINFO: ddrc config start\n"); - ddrc_config(dram_timing->ddrc_cfg, dram_timing->ddrc_cfg_num); + ddrc_config(dram_timing); debug("DDRINFO: ddrc config done\n"); update_umctl2_rank_space_setting(dram_timing->fsp_msg_num - 1); @@ -245,8 +331,29 @@ int ddr_init(struct dram_timing_info *dram_timing) check_ddrc_idle(); + mr12 = lpddr4_mr_read(1, 12); + mr14 = lpddr4_mr_read(1, 14); + /* save the dram timing config into memory */ - dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE); + fsp = dram_config_save(dram_timing, CONFIG_SAVED_DRAM_TIMING_BASE); + + saved_timing = (struct dram_timing_info *)CONFIG_SAVED_DRAM_TIMING_BASE; + saved_timing->fsp_cfg = fsp; + saved_timing->fsp_cfg_num = dram_timing->fsp_cfg_num; + if (saved_timing->fsp_cfg_num) { + memcpy(saved_timing->fsp_cfg, dram_timing->fsp_cfg, + dram_timing->fsp_cfg_num * sizeof(struct dram_fsp_cfg)); + + save_trained_mr12_14(saved_timing->fsp_cfg[0].mr_cfg, + ARRAY_SIZE(saved_timing->fsp_cfg[0].mr_cfg), mr12, mr14); + /* + * Configure mode registers in fsp1 to mode register 0 because DDRC + * doesn't automatically set. + */ + if (saved_timing->fsp_cfg_num > 1) + update_mr_fsp_op0(saved_timing->fsp_cfg[1].mr_cfg, + ARRAY_SIZE(saved_timing->fsp_cfg[1].mr_cfg)); + } return 0; } diff --git a/drivers/ddr/imx/phy/helper.c b/drivers/ddr/imx/phy/helper.c index e9e0294f87d..8cd438791e5 100644 --- a/drivers/ddr/imx/phy/helper.c +++ b/drivers/ddr/imx/phy/helper.c @@ -167,8 +167,7 @@ void ddrphy_trained_csr_save(struct dram_cfg_param *ddrphy_csr, dwc_ddrphy_apb_wr(0xd0000, 0x1); } -void dram_config_save(struct dram_timing_info *timing_info, - unsigned long saved_timing_base) +void *dram_config_save(struct dram_timing_info *timing_info, unsigned long saved_timing_base) { int i = 0; struct dram_timing_info *saved_timing = (struct dram_timing_info *)saved_timing_base; @@ -217,4 +216,6 @@ void dram_config_save(struct dram_timing_info *timing_info, cfg->val = timing_info->ddrphy_pie[i].val; cfg++; } + + return (void *)cfg; }