From patchwork Wed Sep 20 19:26:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393330 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B143BC04FF1 for ; Wed, 20 Sep 2023 19:28:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=cBm4+9M8qt6CkeWPXmNRtDV1EY6wgpwcD2zaKadny0U=; b=FaXOnlPCFS8rrO 0rJrwTdyU7XMPsTd8uW6VlQzFUTYIEmgBc5OiemaoZgDiP0Tmodv/WNIeVvBGzxdC7fkqm6ofqmsa 5hQRV04YZ65ruDrhslz5Ycor5XU7TkIwwwnRQg7BmzUf9bKlFwS5PX5WDObdvFpdONKMaV5KKQAUY 87EZMYkUjTXayNfeeDm98ptb+OlvpRAAibKqjT9Iu2745gbJFKk+X+i0GxZWJugpz964wqfakoZt7 LvZOh7Fl9g1ZDBn9nGmaBPZDrycrJ2cQHMbY1N8aTfdrm69cdqXhqd+jop5A0wcL5LCLzaT50EUSI xTsbqdC6UZswlekn4lzQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sC-00407X-2z; Wed, 20 Sep 2023 19:28:32 +0000 Received: from mail-lf1-x134.google.com ([2a00:1450:4864:20::134]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2s3-00401e-2J for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:25 +0000 Received: by mail-lf1-x134.google.com with SMTP id 2adb3069b0e04-501eec0a373so407166e87.3 for ; Wed, 20 Sep 2023 12:28:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238101; x=1695842901; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=slA2GCsU+M93cytZBZ/cPNG/4Z+l1JlZLJUZAsah/2M=; b=U0TOUA0HqkEDaISX+qsz1fg+SwzG6qJ9ek1LMjKBSVwxnUg1l9LC+EKcozqYbHW7mc GCGQQSpyat59+KrDu5VHp0f3yIIGEnZVD06z0eJUvD28oEJpz3hJPERLS/OFf6lXWj7N oUtSw9IpWGsBxb0HHamQVfzbBJOwTZf54YRozePKbA0ROup5FGKquvjfHxb8pbA4ewly agbdGVwoJRas5iCwyngtE2qPuCTNszy+UdKfBjvtQWrQPs3droIHmBUgXkuAzNqX6rqp RXu+t5DZ08/etvrI8UJLFYL6WyCyHiQzIFJmZ8mWyzXKK+yGqcooZL4Us8aj4VFfmb+z /sdA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238101; x=1695842901; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=slA2GCsU+M93cytZBZ/cPNG/4Z+l1JlZLJUZAsah/2M=; b=MPtYX+3Cdy5uuPkjmpAtXvwqgJQw6+oWvFpATPz8cEqDgPx10EEaSTHPfMKdXwNBXF BV0zugnP7Pij3tC4MCbLfTHVat8xO/Eqglh23iSR6WLeT8pfT8rgl6A/O4kbmZCT4ViM G1ONKK/HlTvelLwWGF/fX4LBTLfsb8oxKImGyA76XO/E5PRMP3LLjkPEODf8Q/ZOGoBU QOYCHDWLMwlQ0PELcqNAUjqAFsfbJ8hMkU1UHtvAKpc1hHv9SgExmJmeHVL5+RNT3m+H H+Hhs1Z/0Zgl8Ow2htx+xfd2bJtZPjjLl8pL+IR9ZMydynPvWbwHIEUuf/AsSVTnvkaS +Oow== X-Gm-Message-State: AOJu0Ywzhzb2QLkHm/vpaGyjcWEgMyoQsF49SnHNnDznmIUZpHdxgYPI euRXbTuQXatDgjvIvrqIoWM= X-Google-Smtp-Source: AGHT+IF+ObWvzYHZ8zlMxC7DoVW4y5G1q84HHE1PKwiFaw5asqnXFJ+fr0nnN/Rho8M8vEajlLTXNg== X-Received: by 2002:a19:6905:0:b0:502:adbb:f9db with SMTP id e5-20020a196905000000b00502adbbf9dbmr2142896lfc.65.1695238100510; Wed, 20 Sep 2023 12:28:20 -0700 (PDT) Received: from localhost ([85.26.234.143]) by smtp.gmail.com with ESMTPSA id v22-20020ac25596000000b005041a71237asm339716lfg.111.2023.09.20.12.28.19 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:19 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 01/18] EDAC/synopsys: Convert sysfs nodes to debugfs ones Date: Wed, 20 Sep 2023 22:26:46 +0300 Message-ID: <20230920192806.29960-2-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122823_758206_C36B67B2 X-CRM114-Status: GOOD ( 22.87 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The DW uMCTL2 DDRC EDAC driver supports creating two sysfs nodes: "inject_data_error" and "inject_data_poison". First of them is responsible for setting the error-injecting physical address up. The second one is supposed to be used to enable the hardware capability of the correctable and uncorrectable errors injection. The semantics of these nodes is pure debug. They are even created only if the EDAC_DEBUG kernel config is enabled. Thus there is no point in having these nodes exported in the sysfs especially seeing they aren't listed in the sysfs ABI. Just move them to the device private directory in DebugFS. While at it move the address map initialization procedure call to the DebugFS nodes creating function (it's useless with no DebugFS nodes being available anyway) and create an empty snps_create_debugfs_nodes() method in case if the EDAC_DEBUG config is disabled. Thus the DW uMCTL2 DDRC EDAC probe procedure will get to be a bit simpler and redundant work won't be performed. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 221 +++++++++++++++++++---------------- 1 file changed, 122 insertions(+), 99 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 327023e35d42..10716f365c6f 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -641,6 +642,16 @@ static int snps_setup_irq(struct mem_ctl_info *mci, struct platform_device *pdev #ifdef CONFIG_EDAC_DEBUG +#define SNPS_DEBUGFS_FOPS(__name, __read, __write) \ + static const struct file_operations __name = { \ + .owner = THIS_MODULE, \ + .open = simple_open, \ + .read = __read, \ + .write = __write, \ + } + +#define SNPS_DBGFS_BUF_LEN 128 + /** * snps_data_poison_setup - Update poison registers. * @priv: DDR memory controller private instance data. @@ -701,90 +712,6 @@ static void snps_data_poison_setup(struct snps_edac_priv *priv) writel(regval, priv->baseaddr + ECC_POISON1_OFST); } -static ssize_t inject_data_error_show(struct device *dev, - struct device_attribute *mattr, - char *data) -{ - struct mem_ctl_info *mci = to_mci(dev); - struct snps_edac_priv *priv = mci->pvt_info; - - return sprintf(data, "Poison0 Addr: 0x%08x\n\rPoison1 Addr: 0x%08x\n\r" - "Error injection Address: 0x%lx\n\r", - readl(priv->baseaddr + ECC_POISON0_OFST), - readl(priv->baseaddr + ECC_POISON1_OFST), - priv->poison_addr); -} - -static ssize_t inject_data_error_store(struct device *dev, - struct device_attribute *mattr, - const char *data, size_t count) -{ - struct mem_ctl_info *mci = to_mci(dev); - struct snps_edac_priv *priv = mci->pvt_info; - - if (kstrtoul(data, 0, &priv->poison_addr)) - return -EINVAL; - - snps_data_poison_setup(priv); - - return count; -} - -static ssize_t inject_data_poison_show(struct device *dev, - struct device_attribute *mattr, - char *data) -{ - struct mem_ctl_info *mci = to_mci(dev); - struct snps_edac_priv *priv = mci->pvt_info; - const char *errstr; - u32 regval; - - regval = readl(priv->baseaddr + ECC_CFG1_OFST); - errstr = FIELD_GET(ECC_CEPOISON_MASK, regval) == ECC_CEPOISON_MASK ? - "Correctable Error" : "UnCorrectable Error"; - - return sprintf(data, "Data Poisoning: %s\n\r", errstr); -} - -static ssize_t inject_data_poison_store(struct device *dev, - struct device_attribute *mattr, - const char *data, size_t count) -{ - struct mem_ctl_info *mci = to_mci(dev); - struct snps_edac_priv *priv = mci->pvt_info; - - writel(0, priv->baseaddr + DDR_SWCTL); - if (strncmp(data, "CE", 2) == 0) - writel(ECC_CEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST); - else - writel(ECC_UEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST); - writel(1, priv->baseaddr + DDR_SWCTL); - - return count; -} - -static DEVICE_ATTR_RW(inject_data_error); -static DEVICE_ATTR_RW(inject_data_poison); - -static int snps_create_sysfs_attributes(struct mem_ctl_info *mci) -{ - int rc; - - rc = device_create_file(&mci->dev, &dev_attr_inject_data_error); - if (rc < 0) - return rc; - rc = device_create_file(&mci->dev, &dev_attr_inject_data_poison); - if (rc < 0) - return rc; - return 0; -} - -static void snps_remove_sysfs_attributes(struct mem_ctl_info *mci) -{ - device_remove_file(&mci->dev, &dev_attr_inject_data_error); - device_remove_file(&mci->dev, &dev_attr_inject_data_poison); -} - static void snps_setup_row_address_map(struct snps_edac_priv *priv, u32 *addrmap) { u32 addrmap_row_b2_10; @@ -1005,7 +932,115 @@ static void snps_setup_address_map(struct snps_edac_priv *priv) snps_setup_rank_address_map(priv, addrmap); } -#endif /* CONFIG_EDAC_DEBUG */ + +static ssize_t snps_inject_data_error_read(struct file *filep, char __user *ubuf, + size_t size, loff_t *offp) +{ + struct mem_ctl_info *mci = filep->private_data; + struct snps_edac_priv *priv = mci->pvt_info; + char buf[SNPS_DBGFS_BUF_LEN]; + int pos; + + pos = scnprintf(buf, sizeof(buf), "Poison0 Addr: 0x%08x\n\r", + readl(priv->baseaddr + ECC_POISON0_OFST)); + pos += scnprintf(buf + pos, sizeof(buf) - pos, "Poison1 Addr: 0x%08x\n\r", + readl(priv->baseaddr + ECC_POISON1_OFST)); + pos += scnprintf(buf + pos, sizeof(buf) - pos, "Error injection Address: 0x%lx\n\r", + priv->poison_addr); + + return simple_read_from_buffer(ubuf, size, offp, buf, pos); +} + +static ssize_t snps_inject_data_error_write(struct file *filep, const char __user *ubuf, + size_t size, loff_t *offp) +{ + struct mem_ctl_info *mci = filep->private_data; + struct snps_edac_priv *priv = mci->pvt_info; + int rc; + + rc = kstrtoul_from_user(ubuf, size, 0, &priv->poison_addr); + if (rc) + return rc; + + snps_data_poison_setup(priv); + + return size; +} + +SNPS_DEBUGFS_FOPS(snps_inject_data_error, snps_inject_data_error_read, + snps_inject_data_error_write); + +static ssize_t snps_inject_data_poison_read(struct file *filep, char __user *ubuf, + size_t size, loff_t *offp) +{ + struct mem_ctl_info *mci = filep->private_data; + struct snps_edac_priv *priv = mci->pvt_info; + char buf[SNPS_DBGFS_BUF_LEN]; + const char *errstr; + u32 regval; + int pos; + + regval = readl(priv->baseaddr + ECC_CFG1_OFST); + errstr = FIELD_GET(ECC_CEPOISON_MASK, regval) == ECC_CEPOISON_MASK ? + "Correctable Error" : "UnCorrectable Error"; + + pos = scnprintf(buf, sizeof(buf), "Data Poisoning: %s\n\r", errstr); + + return simple_read_from_buffer(ubuf, size, offp, buf, pos); +} + +static ssize_t snps_inject_data_poison_write(struct file *filep, const char __user *ubuf, + size_t size, loff_t *offp) +{ + struct mem_ctl_info *mci = filep->private_data; + struct snps_edac_priv *priv = mci->pvt_info; + char buf[SNPS_DBGFS_BUF_LEN]; + int rc; + + rc = simple_write_to_buffer(buf, sizeof(buf), offp, ubuf, size); + if (rc < 0) + return rc; + + writel(0, priv->baseaddr + DDR_SWCTL); + if (strncmp(buf, "CE", 2) == 0) + writel(ECC_CEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST); + else + writel(ECC_UEPOISON_MASK, priv->baseaddr + ECC_CFG1_OFST); + writel(1, priv->baseaddr + DDR_SWCTL); + + return size; +} + +SNPS_DEBUGFS_FOPS(snps_inject_data_poison, snps_inject_data_poison_read, + snps_inject_data_poison_write); + +/** + * snps_create_debugfs_nodes - Create DebugFS nodes. + * @mci: EDAC memory controller instance. + * + * Create DW uMCTL2 EDAC driver DebugFS nodes in the device private + * DebugFS directory. + * + * Return: none. + */ +static void snps_create_debugfs_nodes(struct mem_ctl_info *mci) +{ + struct snps_edac_priv *priv = mci->pvt_info; + + snps_setup_address_map(priv); + + edac_debugfs_create_file("inject_data_error", 0600, mci->debugfs, mci, + &snps_inject_data_error); + + edac_debugfs_create_file("inject_data_poison", 0600, mci->debugfs, mci, + &snps_inject_data_poison); +} + +#else /* !CONFIG_EDAC_DEBUG */ + +static inline void snps_create_debugfs_nodes(struct mem_ctl_info *mci) {} + +#endif /* !CONFIG_EDAC_DEBUG */ /** * snps_mc_probe - Check controller and bind driver. @@ -1071,17 +1106,9 @@ static int snps_mc_probe(struct platform_device *pdev) goto free_edac_mc; } -#ifdef CONFIG_EDAC_DEBUG - rc = snps_create_sysfs_attributes(mci); - if (rc) { - edac_printk(KERN_ERR, EDAC_MC, "Failed to create sysfs entries\n"); - goto free_edac_mc; - } + snps_create_debugfs_nodes(mci); - snps_setup_address_map(priv); -#endif - - return rc; + return 0; free_edac_mc: edac_mc_free(mci); @@ -1102,10 +1129,6 @@ static int snps_mc_remove(struct platform_device *pdev) snps_disable_irq(priv); -#ifdef CONFIG_EDAC_DEBUG - snps_remove_sysfs_attributes(mci); -#endif - edac_mc_del_mc(&pdev->dev); edac_mc_free(mci); From patchwork Wed Sep 20 19:26:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393329 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4B8E5C04FEE for ; Wed, 20 Sep 2023 19:28:58 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=kV6+V+81x7C5/+x8LmOYi9jyl3VVTrjtV/yGaTiBByg=; b=vyKb97d8/c30EW QZ1hKxuHFtt/TlvyKiaku2QttZ3nmDAFmNYrjzGchadPGkCoh9RS+1qCnLOjKYXTeLB8iHU8uuf9M hunonmAmXkytY3qeGHF8WtWhIfviqpvhYxVpH2rmnq+JHa3lFtHNe1JB9bsnWkD25t6mdsWfQq/7y WbekNsygIdW9RWbuN2cQ+XiNcZH7ytDmOPWjulAQizjjy6PZntlY3yXC67fRQlehKK2QmCXkaDq8V wK57wy9xjKrDDUB7CuRHdcNQzxPtD9CUfYYluY01NC5sWk8N+/kvdHu26gvycIEjRkWsMMylAWpkt 2iXbW2hS93/qC1aupcNw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sD-004082-20; Wed, 20 Sep 2023 19:28:33 +0000 Received: from mail-lf1-x129.google.com ([2a00:1450:4864:20::129]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2s4-00402W-2O for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:26 +0000 Received: by mail-lf1-x129.google.com with SMTP id 2adb3069b0e04-5041d6d8b10so388986e87.2 for ; Wed, 20 Sep 2023 12:28:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238103; x=1695842903; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lSZwUqk2LhSLToURZdxj4BC7qr/BbA6pyW8daToL0QU=; b=MESpe8HO88R47NKJ4DoLmYwC+HWPlEvci6CQk90ORCuI4jDdnX06YLSsIpNI3bdMhs skFCuViiiIhTehY2z0Ikn6qKY2vULlom47aROxpjEgNIXDO6kE/Lxix6ApBIrlZyAL5i g59egeEJjNYizWONEZCwICEGNWTk1ofRzS9Ucs+jzNlH305FyAqxNlKhL1PY03UBdIAN 2eItjoSW+Yww/PWL4ZDBS7UCkN5SjUfDOWpjMmGxpQGphEj+1TAIwCItF1dQwzHYHAkQ ickaLSK12JUP+V4RSSTC+PNUlZLwF8wIU4PqAwmNEm8tKO7OWwctJ6m9UT+3xMdqnnz0 PjnQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238103; x=1695842903; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lSZwUqk2LhSLToURZdxj4BC7qr/BbA6pyW8daToL0QU=; b=IBESwlD0ReJYCm5ENgGxClMwS9XpPdWfMz2d/IhRqMil0fxaa4zJVxKv+3iSkmuowR gUXcv5hBRQeFrcLOTbMXDNOtzwIyt4Zoz3W+hWP8ut7kQnwcdqBrl2EUoD+oIi42+OVs xxZ8trRF5h9V11tRER1kigKUe11MszOJ/XKbBvM04s5aguDSocqlSnMaryEPIBHWgv8h pruFYePNoCjIwSTOJewG2DmzxrD8kaxrbu62KFG/N1pJRejsCjfHorvLQaa9uer7nrA6 Zh/YyWwKYnC42vU90Jx7muqMwh60DRNws0WjLc6TbN3fTBmTUGAzQdfVqhGs2ftLa4xP 2fNw== X-Gm-Message-State: AOJu0Yzrtzgfz7sRoYSti7/j5x69xGnablD72fsAahFcs5LvLqR0broW B+Ii8UtxHATDutoAunzMpa8= X-Google-Smtp-Source: AGHT+IHu9ipPueyvMIh6eHJbINo45HFjPnT1i9SCVvpQktfQ6hYhHXC08wGvzUA0gWFFZYqbkjqqLQ== X-Received: by 2002:a19:ca03:0:b0:500:b42f:1830 with SMTP id a3-20020a19ca03000000b00500b42f1830mr2620543lfg.63.1695238103285; Wed, 20 Sep 2023 12:28:23 -0700 (PDT) Received: from localhost ([178.176.81.142]) by smtp.gmail.com with ESMTPSA id i25-20020a056512007900b0050332394bcasm802769lfo.150.2023.09.20.12.28.22 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:22 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 02/18] EDAC/mc: Extend memtypes with LPDDR(mDDR) and LPDDR2 Date: Wed, 20 Sep 2023 22:26:47 +0300 Message-ID: <20230920192806.29960-3-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122824_803047_9A9ED5AA X-CRM114-Status: GOOD ( 14.30 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org These are normal memory types [1] which can be met on the real hardware. DW uMCTL2 DDRC IP-core can be configured to have them supported [2,3]. Extend the EDAC memory types enumeration with the corresponding IDs then. [1] https://en.wikipedia.org/wiki/LPDDR [2] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.501 [3] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.1717 Signed-off-by: Serge Semin --- drivers/edac/edac_mc.c | 2 ++ include/linux/edac.h | 6 ++++++ 2 files changed, 8 insertions(+) diff --git a/drivers/edac/edac_mc.c b/drivers/edac/edac_mc.c index 634c41ea7804..e353e98e01e2 100644 --- a/drivers/edac/edac_mc.c +++ b/drivers/edac/edac_mc.c @@ -151,10 +151,12 @@ const char * const edac_mem_types[] = { [MEM_RDR] = "Registered-SDR", [MEM_DDR] = "Unbuffered-DDR", [MEM_RDDR] = "Registered-DDR", + [MEM_LPDDR] = "Low-Power-(m)DDR-RAM", [MEM_RMBS] = "RMBS", [MEM_DDR2] = "Unbuffered-DDR2", [MEM_FB_DDR2] = "FullyBuffered-DDR2", [MEM_RDDR2] = "Registered-DDR2", + [MEM_LPDDR2] = "Low-Power-DDR2-RAM", [MEM_XDR] = "XDR", [MEM_DDR3] = "Unbuffered-DDR3", [MEM_RDDR3] = "Registered-DDR3", diff --git a/include/linux/edac.h b/include/linux/edac.h index fa4bda2a70f6..89167a4459d5 100644 --- a/include/linux/edac.h +++ b/include/linux/edac.h @@ -157,6 +157,7 @@ static inline char *mc_event_error_type(const unsigned int err_type) * This is a variant of the DDR memories. * A registered memory has a buffer inside it, hiding * part of the memory details to the memory controller. + * @MEM_LPDDR: Low-Power DDR memory (mDDR). * @MEM_RMBS: Rambus DRAM, used on a few Pentium III/IV controllers. * @MEM_DDR2: DDR2 RAM, as described at JEDEC JESD79-2F. * Those memories are labeled as "PC2-" instead of "PC" to @@ -167,6 +168,7 @@ static inline char *mc_event_error_type(const unsigned int err_type) * a chip select signal. * @MEM_RDDR2: Registered DDR2 RAM * This is a variant of the DDR2 memories. + * @MEM_LPDDR2: Low-Power DDR2 memory. * @MEM_XDR: Rambus XDR * It is an evolution of the original RAMBUS memories, * created to compete with DDR2. Weren't used on any @@ -199,10 +201,12 @@ enum mem_type { MEM_RDR, MEM_DDR, MEM_RDDR, + MEM_LPDDR, MEM_RMBS, MEM_DDR2, MEM_FB_DDR2, MEM_RDDR2, + MEM_LPDDR2, MEM_XDR, MEM_DDR3, MEM_RDDR3, @@ -230,10 +234,12 @@ enum mem_type { #define MEM_FLAG_RDR BIT(MEM_RDR) #define MEM_FLAG_DDR BIT(MEM_DDR) #define MEM_FLAG_RDDR BIT(MEM_RDDR) +#define MEM_FLAG_LPDDR BIT(MEM_LPDDR) #define MEM_FLAG_RMBS BIT(MEM_RMBS) #define MEM_FLAG_DDR2 BIT(MEM_DDR2) #define MEM_FLAG_FB_DDR2 BIT(MEM_FB_DDR2) #define MEM_FLAG_RDDR2 BIT(MEM_RDDR2) +#define MEM_FLAG_LPDDR2 BIT(MEM_LPDDR2) #define MEM_FLAG_XDR BIT(MEM_XDR) #define MEM_FLAG_DDR3 BIT(MEM_DDR3) #define MEM_FLAG_RDDR3 BIT(MEM_RDDR3) From patchwork Wed Sep 20 19:26:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393331 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6D9C9C04FF1 for ; Wed, 20 Sep 2023 19:29:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=iKliP5UXeODru/syRKjsOCuv1zoKSnrY/Ea3nIU2FdM=; b=2V01h0hORcce0r 36Dw8+uRFqxOa22euunJt6h64dzDP1s6B77xBJ5z0YkwAEK2VK1CojOtOnkYNJ8D8wptOA10cH8t2 d4Vil2KqHkSXGyXHhMIyzzAkz/4qfvVLTSf4UwytB00FpHnJNhius6bhOgU/OCHUdOZDSjchrTsh8 xSNuCGNjsqA7glvojtH3M140xkMbudW6eGndH9exzJq8JRLv8QCQOYq4XIWYNtiHmVTtXPXy63UyW RjZpyTM4tPbnfWHCfMkqzY1ATjt7P4sVwP/+0PfSfX4kOlaw+hmQJSHssZTBI0386WBY2BfnUi5Hd hUcneROAr2/6MeVQlSrQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sE-00408g-13; Wed, 20 Sep 2023 19:28:34 +0000 Received: from mail-lj1-x233.google.com ([2a00:1450:4864:20::233]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2s7-00404E-35 for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:29 +0000 Received: by mail-lj1-x233.google.com with SMTP id 38308e7fff4ca-2c01d22f332so15656801fa.0 for ; Wed, 20 Sep 2023 12:28:27 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238106; x=1695842906; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=yRpb2GxtnVP5nWSE0kBTW6FlNIFe1bv1+IIvLCRkryM=; b=YGMAxqc1D7BrW++4UbIrwbGRxzRBiv+dpzRKscgw1cIJYmH8BYGsy3PC+Z53wKUSF+ Z2Ha7eByAO4cU3D+ypRqAwK6ES/mAFp2iLUCpLQrLiCBVachhFttoOYwJQa5T3NjYk+8 Avz2PEDz7INg23Vxdx59WRJilXe7Ty8b3c7dLr6Jz8zEwUpKm6Tfo+ynDYThQ6OUxyqY 1gwatBXe3Ypr3vJjr5JCy1oj5PNd11CoCZcny/byMAnfl7mszscVgmgWml/mWRUnrxY+ OERtE62cx/dhugVCRz4Cgf1SyWVRyV3ESvewaHtdlHj2bI7z9qg59Is/eDXEU0o9zmdZ nUtw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238106; x=1695842906; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=yRpb2GxtnVP5nWSE0kBTW6FlNIFe1bv1+IIvLCRkryM=; b=ezjknsRHkn1yyMQOItM5404ccqfRH50Tvr9vugV0q1xb7llrDkVJsI9ttKrUM0KT0o gBymlbfFMJzcVZd8Gs8vGegtYfggzxrDN/ByLZSMgPNN7o8KZ+bsRcDX7/vmK0mwgreO It5MCQ6p/AI7szOVde9SXxWRlbpAbwBimXJAlBVdaXtm4JCaRvsSsf8AzlTwyUv5Rc+f FcgILi9hT5klF3TnRHjc9Tpc8BR62+KYRoa/gwhGMNY5UdIJNj5cMtHnm5aLnITk5IlG P7TQeQvFVM2UupC4XNow/48gXEpYTAMIAiWiv13adW8mct9wxUL6i/mmCpMacZPpKppJ jC6Q== X-Gm-Message-State: AOJu0Yzk4yUdmTDiNbnh+C+LuiewgM/g4fg4AP61uwHbmmGzvj/wC29I XZH/anjOiyyZVTqZrrLugWg= X-Google-Smtp-Source: AGHT+IGyHrILRPaV9pJ2zQgJeEVuZslG3NO98MRbEvq/YyXB/RrkwS0N6dvP/s2RWOZgLB2ubbRn0Q== X-Received: by 2002:a2e:a60b:0:b0:2bf:f90e:2794 with SMTP id v11-20020a2ea60b000000b002bff90e2794mr2545427ljp.23.1695238106225; Wed, 20 Sep 2023 12:28:26 -0700 (PDT) Received: from localhost ([178.176.85.138]) by smtp.gmail.com with ESMTPSA id d19-20020a2eb053000000b002b9ec22d9fasm1105300ljl.29.2023.09.20.12.28.24 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:25 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 03/18] EDAC/synopsys: Extend memtypes supported by controller Date: Wed, 20 Sep 2023 22:26:48 +0300 Message-ID: <20230920192806.29960-4-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122828_139401_3BA482C2 X-CRM114-Status: GOOD ( 18.62 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org In accordance with [1] the DW uMCTL2 DDR controllers can support the next DDR protocols: LPDDR, (LP)DDR(2|3|4). Even if the controller is configured to support several of these memory chip types only one of these modes could be enabled at runtime [2]. Taking all of that into account update the snps_get_mtype() procedure so the DW uMCTL2 DDRC driver would be able to detect all the claimed to be supported memory types in accordance with the table defined in [2]. Note alas it's not possible do determine which MEMC DDR configs were enabled at the IP-core synthesize. Therefore there is no other choice but to initialize the EDAC MC mem-types capability field with all the types claimed to be supported by the IP-core. [1] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.501 [2] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.501 Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 41 ++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 14 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 10716f365c6f..e08e9f3c81cb 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -102,11 +102,14 @@ #define DDR_MSTR_BUSWIDTH_16 2 #define DDR_MSTR_BUSWIDTH_32 1 #define DDR_MSTR_BUSWIDTH_64 0 +#define DDR_MSTR_MEM_MASK GENMASK(5, 0) #define DDR_MSTR_MEM_LPDDR4 BIT(5) #define DDR_MSTR_MEM_DDR4 BIT(4) #define DDR_MSTR_MEM_LPDDR3 BIT(3) -#define DDR_MSTR_MEM_DDR2 BIT(2) +#define DDR_MSTR_MEM_LPDDR2 BIT(2) +#define DDR_MSTR_MEM_LPDDR BIT(1) #define DDR_MSTR_MEM_DDR3 BIT(0) +#define DDR_MSTR_MEM_DDR2 0 /* ECC CFG0 register definitions */ #define ECC_CFG0_MODE_MASK GENMASK(2, 0) @@ -535,21 +538,29 @@ static u32 snps_get_memsize(void) */ static enum mem_type snps_get_mtype(const void __iomem *base) { - enum mem_type mt; - u32 memtype; + u32 regval; - memtype = readl(base + DDR_MSTR_OFST); + regval = readl(base + DDR_MSTR_OFST); + regval = FIELD_GET(DDR_MSTR_MEM_MASK, regval); - if ((memtype & DDR_MSTR_MEM_DDR3) || (memtype & DDR_MSTR_MEM_LPDDR3)) - mt = MEM_DDR3; - else if (memtype & DDR_MSTR_MEM_DDR2) - mt = MEM_RDDR2; - else if ((memtype & DDR_MSTR_MEM_LPDDR4) || (memtype & DDR_MSTR_MEM_DDR4)) - mt = MEM_DDR4; - else - mt = MEM_EMPTY; + switch (regval) { + case DDR_MSTR_MEM_DDR2: + return MEM_DDR2; + case DDR_MSTR_MEM_DDR3: + return MEM_DDR3; + case DDR_MSTR_MEM_LPDDR: + return MEM_LPDDR; + case DDR_MSTR_MEM_LPDDR2: + return MEM_LPDDR2; + case DDR_MSTR_MEM_LPDDR3: + return MEM_LPDDR3; + case DDR_MSTR_MEM_DDR4: + return MEM_DDR4; + case DDR_MSTR_MEM_LPDDR4: + return MEM_LPDDR4; + } - return mt; + return MEM_RESERVED; } /** @@ -597,7 +608,9 @@ static void snps_mc_init(struct mem_ctl_info *mci, struct platform_device *pdev) platform_set_drvdata(pdev, mci); /* Initialize controller capabilities and configuration */ - mci->mtype_cap = MEM_FLAG_DDR3 | MEM_FLAG_DDR2; + mci->mtype_cap = MEM_FLAG_LPDDR | MEM_FLAG_DDR2 | MEM_FLAG_LPDDR2 | + MEM_FLAG_DDR3 | MEM_FLAG_LPDDR3 | + MEM_FLAG_DDR4 | MEM_FLAG_LPDDR4; mci->edac_ctl_cap = EDAC_FLAG_NONE | EDAC_FLAG_SECDED; mci->scrub_cap = SCRUB_FLAG_HW_SRC; mci->scrub_mode = SCRUB_NONE; From patchwork Wed Sep 20 19:26:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393334 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 1B59DC04FF5 for ; Wed, 20 Sep 2023 19:29:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=/DKKA57vsIIZiB6/M3ddgWRQVM7Xxkx3463CgdJsEK8=; b=lHmYybpfaYBz9F zPAavPce2u+lsZWzGGuWGXcENoQRoRFNIGSTVHckSKxLTVpWRKR4Vwnz7QPqJvFb9Qgw1OCDvJwou Z7ZUNZcxvIhXXzsdgv8vX6w0z8AKXDqd/Q3e+oFM43IiM/Eq8e0+W59byoZUAWCZ4gSXRRhqcRset eW2awTDK7C4TQRU045jTXbkE+kwu5HGcoYs0u14A7NsG/MucWQ5PFdFwsX08hxthEd/eopErXbHD3 Ie6N85+AUqVXk8SSkvXhu/jPjixgh1CXYYxAUi1ShcxnQjVpAvzLhUd35n/pmuTORo41TeyM9x2jo KfgOBN92lgqgG4gxspuA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sS-0040H2-29; Wed, 20 Sep 2023 19:28:48 +0000 Received: from mail-lf1-x12d.google.com ([2a00:1450:4864:20::12d]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sD-004064-1K for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:35 +0000 Received: by mail-lf1-x12d.google.com with SMTP id 2adb3069b0e04-5031426b626so347626e87.3 for ; Wed, 20 Sep 2023 12:28:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238109; x=1695842909; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=0p8U90biBaY98m+/7YTgOwqeSiRSThvzebPVxAHZ0NU=; b=eXw9/Ps5qTFl0crp/k1F594Oe7mxjkGGkRHMDa3AxrY2zmGAg6frIOklpQdRjokp2g 9Gy7kRfIxlwRUOFzqJLPPWj/BUtdiZIm2o2NKnztGNjwLUwUvyMYyxD9SfO+3i/5GghI ecdqNhI1SrKeh7MQn2si3eK6+PQsNxENjV4djbmoc/TfMAijtzU3E4jxTituzZS09qi9 DC7USc5WzzLEODlOXtsqaMIJrj1HaY9UyxBMOnGDyCPQFRaZBCFQGKklzLwtViJEwjJb RuyGki8Dy2CB4wriwsl4lrVGwmCzm2Iki6HjgaKFHcJ31iPIAQUS84cmbdTbvbbpQGB0 EcFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238109; x=1695842909; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=0p8U90biBaY98m+/7YTgOwqeSiRSThvzebPVxAHZ0NU=; b=rWcbJeJ7oeTSfUEZn0v8IbGAAkQUiTzqjkJ+hva2cjjUkOI41lh49AtdlWltWrUAS5 MxFF2/xlMaPvzDUnvwHAGeDXBWrlS4VynyDnIQojapDMIOwhP31N2keh/OdWlvDyZNbT Dl07p8ciZ04JX4OCc/+jW0wyicwfp24rl+6GhjSwQtt6lsJu75cX+gF2n5VeflGPftJU DFscmYCH0ni6KPSAYS/vJIbjCmXUF33Hf1fXk/eVj7OALmBddOIJwNaDPAJG+MQ6QMkc gj+ZSTXkXEedyIQZUW6TUGvH8Gd8kdZqnU/fcQjM7AyxLSujLt9VMdLBfilyPf5AE+Vd 9vyA== X-Gm-Message-State: AOJu0YxZ+xTCUyc0WRmjdW+dAxQch3PtfKvnB5SZqI2yCSUZsJx1bCuS MGUeTmKZGk06M5hLI8DgIw0= X-Google-Smtp-Source: AGHT+IGIdInnubjIeWh18A6utltiooTc5XhoZwMANbo8N+mo1k1GV2zYTk6K/MsLe6Nk9T2xrOWP9w== X-Received: by 2002:a05:6512:3da7:b0:503:38ef:eb54 with SMTP id k39-20020a0565123da700b0050338efeb54mr4177670lfv.37.1695238109286; Wed, 20 Sep 2023 12:28:29 -0700 (PDT) Received: from localhost ([83.149.21.189]) by smtp.gmail.com with ESMTPSA id q26-20020a05651232ba00b0050307bf2bcdsm1933853lfe.247.2023.09.20.12.28.28 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:28 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 04/18] EDAC/synopsys: Detach private data from mci instance Date: Wed, 20 Sep 2023 22:26:49 +0300 Message-ID: <20230920192806.29960-5-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122833_521090_799B569E X-CRM114-Status: GOOD ( 25.79 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org A comprehensive DW uMCTL2 DDRC parameters detection procedure and some resources requests (clocks and resets) are about to be added to the driver. Since these parameters will be utilized in the various parts of the driver and in particular used for the Memory Controller data instance pre-initialization, they need to be: first retrieved before the MCI is allocated; second preserved in the driver private data. Therefore the best approach would be to add the parameters structure right into the driver private data and just allocate the data separately from the mem_ctl_info instance. For that: add a new static method snps_data_create(), which aside with the snps_edac_priv structure allocation will also perform the private data basic initialization like CSRs region mapping, device data getting, platform data pointer copying and spin-lock initialization; convert the snps_mc_init() method to snps_mc_create(), which from now will be used to allocate and initialize the mem_ctl_info structure instance. Note in order to have an access to the snps_edac_priv structure instance as before this change, the mem_ctl_info.pvt_info field will be initialized with the pointer to that structure instance. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 137 +++++++++++++++++++++++------------ 1 file changed, 90 insertions(+), 47 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index e08e9f3c81cb..e177a36646c0 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -242,6 +242,7 @@ struct snps_ecc_status { /** * struct snps_edac_priv - DDR memory controller private data. + * @pdev: Platform device. * @baseaddr: Base address of the DDR controller. * @reglock: Concurrent CSRs access lock. * @message: Buffer for framing the event specific info. @@ -255,6 +256,7 @@ struct snps_ecc_status { * @rank_shift: Bit shifts for rank bit. */ struct snps_edac_priv { + struct platform_device *pdev; void __iomem *baseaddr; spinlock_t reglock; char message[SNPS_EDAC_MSG_SIZE]; @@ -463,6 +465,34 @@ static irqreturn_t snps_irq_handler(int irq, void *dev_id) return IRQ_HANDLED; } +/** + * snps_create_data - Create private data. + * @pdev: platform device. + * + * Return: Private data instance or negative errno. + */ +static struct snps_edac_priv *snps_create_data(struct platform_device *pdev) +{ + struct snps_edac_priv *priv; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return ERR_PTR(-ENOMEM); + + priv->baseaddr = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(priv->baseaddr)) + return ERR_CAST(priv->baseaddr); + + priv->p_data = of_device_get_match_data(&pdev->dev); + if (!priv->p_data) + return ERR_PTR(-ENODEV); + + priv->pdev = pdev; + spin_lock_init(&priv->reglock); + + return priv; +} + /** * snps_get_dtype - Return the controller memory width. * @base: DDR memory controller base address. @@ -594,18 +624,36 @@ static void snps_init_csrows(struct mem_ctl_info *mci) } /** - * snps_mc_init - Initialize one driver instance. - * @mci: EDAC memory controller instance. - * @pdev: platform device. + * snps_mc_create - Create and initialize MC instance. + * @priv: DDR memory controller private data. + * + * Allocate the EDAC memory controller descriptor and initialize it + * using the private data info. * - * Perform initialization of the EDAC memory controller instance and - * related driver-private data associated with the memory controller the - * instance is bound to. + * Return: MC data instance or negative errno. */ -static void snps_mc_init(struct mem_ctl_info *mci, struct platform_device *pdev) +static struct mem_ctl_info *snps_mc_create(struct snps_edac_priv *priv) { - mci->pdev = &pdev->dev; - platform_set_drvdata(pdev, mci); + struct edac_mc_layer layers[2]; + struct mem_ctl_info *mci; + + layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; + layers[0].size = SNPS_EDAC_NR_CSROWS; + layers[0].is_virt_csrow = true; + layers[1].type = EDAC_MC_LAYER_CHANNEL; + layers[1].size = SNPS_EDAC_NR_CHANS; + layers[1].is_virt_csrow = false; + + mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, 0); + if (!mci) { + edac_printk(KERN_ERR, EDAC_MC, + "Failed memory allocation for mc instance\n"); + return ERR_PTR(-ENOMEM); + } + + mci->pvt_info = priv; + mci->pdev = &priv->pdev->dev; + platform_set_drvdata(priv->pdev, mci); /* Initialize controller capabilities and configuration */ mci->mtype_cap = MEM_FLAG_LPDDR | MEM_FLAG_DDR2 | MEM_FLAG_LPDDR2 | @@ -625,24 +673,43 @@ static void snps_mc_init(struct mem_ctl_info *mci, struct platform_device *pdev) mci->ctl_page_to_phys = NULL; snps_init_csrows(mci); + + return mci; } +/** + * snps_mc_free - Free MC instance. + * @mci: EDAC memory controller instance. + * + * Just revert what was done in the framework of the snps_mc_create(). + * + * Return: MC data instance or negative errno. + */ +static void snps_mc_free(struct mem_ctl_info *mci) +{ + struct snps_edac_priv *priv = mci->pvt_info; + + platform_set_drvdata(priv->pdev, NULL); + edac_mc_free(mci); +} -static int snps_setup_irq(struct mem_ctl_info *mci, struct platform_device *pdev) + + +static int snps_setup_irq(struct mem_ctl_info *mci) { struct snps_edac_priv *priv = mci->pvt_info; int ret, irq; - irq = platform_get_irq(pdev, 0); + irq = platform_get_irq(priv->pdev, 0); if (irq < 0) { edac_printk(KERN_ERR, EDAC_MC, "No IRQ %d in DT\n", irq); return irq; } - ret = devm_request_irq(&pdev->dev, irq, snps_irq_handler, - 0, dev_name(&pdev->dev), mci); + ret = devm_request_irq(&priv->pdev->dev, irq, snps_irq_handler, + 0, dev_name(&priv->pdev->dev), mci); if (ret < 0) { edac_printk(KERN_ERR, EDAC_MC, "Failed to request IRQ\n"); return ret; @@ -1066,49 +1133,24 @@ static inline void snps_create_debugfs_nodes(struct mem_ctl_info *mci) {} */ static int snps_mc_probe(struct platform_device *pdev) { - const struct snps_platform_data *p_data; - struct edac_mc_layer layers[2]; struct snps_edac_priv *priv; struct mem_ctl_info *mci; - void __iomem *baseaddr; int rc; - baseaddr = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(baseaddr)) - return PTR_ERR(baseaddr); - - p_data = of_device_get_match_data(&pdev->dev); - if (!p_data) - return -ENODEV; + priv = snps_create_data(pdev); + if (IS_ERR(priv)) + return PTR_ERR(priv); if (!snps_get_ecc_state(baseaddr)) { edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n"); return -ENXIO; } - layers[0].type = EDAC_MC_LAYER_CHIP_SELECT; - layers[0].size = SNPS_EDAC_NR_CSROWS; - layers[0].is_virt_csrow = true; - layers[1].type = EDAC_MC_LAYER_CHANNEL; - layers[1].size = SNPS_EDAC_NR_CHANS; - layers[1].is_virt_csrow = false; - - mci = edac_mc_alloc(EDAC_AUTO_MC_NUM, ARRAY_SIZE(layers), layers, - sizeof(struct snps_edac_priv)); - if (!mci) { - edac_printk(KERN_ERR, EDAC_MC, - "Failed memory allocation for mc instance\n"); - return -ENOMEM; - } - - priv = mci->pvt_info; - priv->baseaddr = baseaddr; - priv->p_data = p_data; - spin_lock_init(&priv->reglock); + mci = snps_mc_create(priv); + if (IS_ERR(mci)) + return PTR_ERR(mci); - snps_mc_init(mci, pdev); - - rc = snps_setup_irq(mci, pdev); + rc = snps_setup_irq(mci); if (rc) goto free_edac_mc; @@ -1124,7 +1166,7 @@ static int snps_mc_probe(struct platform_device *pdev) return 0; free_edac_mc: - edac_mc_free(mci); + snps_mc_free(mci); return rc; } @@ -1143,7 +1185,8 @@ static int snps_mc_remove(struct platform_device *pdev) snps_disable_irq(priv); edac_mc_del_mc(&pdev->dev); - edac_mc_free(mci); + + snps_mc_free(mci); return 0; } From patchwork Wed Sep 20 19:26:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393332 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 9FA62C04FEE for ; Wed, 20 Sep 2023 19:29:14 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=jgcbL+wAuA1v5Iw0mUYXx0ueJQsOk8yD1FVedMRPKVo=; b=Jo8JV6bCVrl6Zh msVw5/+Jv1KU81PbA3i+64g/6F2rTT+NdWn2ZfCMNE4xlPjkt3ZdqdKSdXNbguSHit1Ut5K/EMqKG CdrzrQPe8YNFvXO0Vyl6T5N4kRhJySX5h6s/a5Y9DmD6FpDVIhY38nnBn/0SxdJZI8mCfxHXJ1ZGo 4gf8BdEvqkZfMwpGnD2aUXAI7IP6oXnLBBHaSZ4hIZqT5ay2GvUJUGq649ppFhq9jh8iqlpDBbTz8 uC1v9oZD+qfQE0endW9vPTC6nMX+YEzogaMfJ2wUcX3LgdXx0uPEKdDI5tCPzmRhypbLdwKGr2k64 sdOigB3AtAu2UkbDYEmw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sT-0040I4-2d; Wed, 20 Sep 2023 19:28:49 +0000 Received: from mail-lj1-x233.google.com ([2a00:1450:4864:20::233]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sE-00408a-2h for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:37 +0000 Received: by mail-lj1-x233.google.com with SMTP id 38308e7fff4ca-2bcb50e194dso2348041fa.3 for ; Wed, 20 Sep 2023 12:28:34 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238113; x=1695842913; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=FcE22L1gZlo+3hTGWgJEFMaEq2Hv0fi5fdl2Fwo2OJ8=; b=YOPVuj0UgyXMItOjXCMu9Ia3Glv+6GYRZWJuAYkZpoL/YjpiloazYKseARk3r6b6l5 oog5CtT6MHn+UzsTvc4PERkvMcBDIs3AcqKpaREq12VLF8BBmvRKJQA8JjamWWb4Hu8n 7LWkCaHePcILf6EfSqW3nJmD63KW/OeUtXh2H+gYAvdiIU1e+7qaC5GRf9mtQ8HxMQvt 40Uiaz8nmk03endVxUCbuS2Di6fZ4KfA2uiMPfnzwe+HdNvR6c7JG8ChA8GmBRPrXZvG 1NSJ5vzGuMDWwQl1gdS982zDS2T+lY6Harkm4tPxAXKnMDepDULx/6NspuFr8LfsXgHV gKKg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238113; x=1695842913; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=FcE22L1gZlo+3hTGWgJEFMaEq2Hv0fi5fdl2Fwo2OJ8=; b=bebKg+pOg2+T9JSD6V3sXxrVA5WegQJFTdhJDhZC+S4Frmr1ABmvgEw5cv/OtT/Ir5 o49YlxtU9PfUSggUfRbUl1Fb0w2teiYs13PiytGEdcjMo9K5gUFDbvh3xgAQ+fgihEf3 v3eica2f5YXJqqofr23SUB/5kia/Gx7i+iRuuCMU2SYK22svZF6jNLCjcnwynYxkucq9 TC4TZAmOsZe8z/i/Q8NMwmoMuU36dTUMb5c/UGme5EJADaWodzlLUu6AG4iDP0fwWtFb 0Mcqa+JJtJ1z+Vvg7b+eNFF+zSwiyBN3IAmQmoZVL2Yde3jq0v7++CE9u7kkxUfRrykt LKbw== X-Gm-Message-State: AOJu0Yy76ZOGRwntlYFoUc+sI2ZORcgWLIJZBAZh3EtpgS7c6gn83QFV cm7z7i/JlTxaZufA6JXmLHM= X-Google-Smtp-Source: AGHT+IGiKZmJrEyWUj9IUt/0uAtjUF2FJ30VYmmzKUPIOz+867IhCz6JlP56yZK2hIC7esXYv4AdjQ== X-Received: by 2002:a2e:90d5:0:b0:2bf:ff17:811b with SMTP id o21-20020a2e90d5000000b002bfff17811bmr2917213ljg.3.1695238113260; Wed, 20 Sep 2023 12:28:33 -0700 (PDT) Received: from localhost ([178.176.83.40]) by smtp.gmail.com with ESMTPSA id x18-20020a2e9c92000000b002b6cb25e3f1sm3065569lji.108.2023.09.20.12.28.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:32 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 05/18] EDAC/synopsys: Add DDRC basic parameters infrastructure Date: Wed, 20 Sep 2023 22:26:50 +0300 Message-ID: <20230920192806.29960-6-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122835_048975_F37352D0 X-CRM114-Status: GOOD ( 30.36 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Currently the driver supports a single DW uMCTL2 DDRC IP-core: 64-bit DQ bus, ECC SEC/DED with always on Scrub (HW-src scrub). This makes the driver application being very limited. In addition to that lacking of any controller capabilities/parameters infrastructure makes it harder to add optional features support. Let's overcome all of that by adding a simple DW uMCTL2 DDRC IP-core parameters infrastructure. It's made of the snps_ddrc_info structure and a new method snps_get_ddrc_info() introduced to fill the structure fields in. The structure contains the IP-core parameters needed to create a more comprehensive driver and will be used in the driver to activate/de-activate various features: - ECC Mode: SEC/DED or Advanced X4/X8 ECC features. (Currently SEC/DED is only supported.) - SDRAM mode: (LP)DDR[2-4] memory interfaces. (Required for the HIF/SDRAM address translation.) - Memory Device config: Memory chips detected on the platform. (Applicable for DDR4 setups only.) - DQ-bus width: Maximal DQ-bus width utilized by the device. (Required for the Application/HIF address translation.) - DQ-bus mode: Actual DQ-bus width used to access the memory devices. (Required for the HIF/SDRAM address translation and ECC grain calc.) - HIF/SDRAM burst length. (Required for the Scrubber bandwidth calculation.) - HIF/SDRAM frequency ratio. (Required for the SDRAM bandwidth calculation.) - SDRAM ranks number. (Required for the Application/HIF address translation.) The list can be easily updated should any additional features support is required to be added in future, but at this stage the driver is fixed in a few places to have the new infrastructure utilized: SDRAM column address mapper, MCI csrows initialization. Note getting all of these parameters in a single method is very suitable from two perspectives. First it localizes the IP-core parameters detection thus improving the code readability and maintainability. Second it's very suitable for the platform-specific quirks implementation. Since some of the IP-core parameters can't be auto-detected at run-time, they will be able to be fixed right in the parameters getter by means of the platform quirks. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 268 +++++++++++++++++++++++++++-------- 1 file changed, 211 insertions(+), 57 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index e177a36646c0..b830e4b4292d 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -87,6 +88,11 @@ /* DDR Software Control Register */ #define DDR_SWCTL 0x320 +/* ECC Poison Pattern Registers */ +#define ECC_POISONPAT0_OFST 0x37C +#define ECC_POISONPAT1_OFST 0x380 +#define ECC_POISONPAT2_OFST 0x384 + /* ZynqMP DDR QOS Registers */ #define ZYNQMP_DDR_QOS_IRQ_STAT_OFST 0x20200 #define ZYNQMP_DDR_QOS_IRQ_EN_OFST 0x20208 @@ -98,10 +104,10 @@ #define DDR_MSTR_DEV_X8 1 #define DDR_MSTR_DEV_X16 2 #define DDR_MSTR_DEV_X32 3 +#define DDR_MSTR_ACT_RANKS_MASK GENMASK(27, 24) +#define DDR_MSTR_FREQ_RATIO11 BIT(22) +#define DDR_MSTR_BURST_RDWR GENMASK(19, 16) #define DDR_MSTR_BUSWIDTH_MASK GENMASK(13, 12) -#define DDR_MSTR_BUSWIDTH_16 2 -#define DDR_MSTR_BUSWIDTH_32 1 -#define DDR_MSTR_BUSWIDTH_64 0 #define DDR_MSTR_MEM_MASK GENMASK(5, 0) #define DDR_MSTR_MEM_LPDDR4 BIT(5) #define DDR_MSTR_MEM_DDR4 BIT(4) @@ -113,7 +119,6 @@ /* ECC CFG0 register definitions */ #define ECC_CFG0_MODE_MASK GENMASK(2, 0) -#define ECC_CFG0_MODE_SECDED 0x4 /* ECC status register definitions */ #define ECC_STAT_UE_MASK GENMASK(23, 16) @@ -208,6 +213,91 @@ #define ZYNQMP_DDR_QOS_CE_MASK BIT(1) #define ZYNQMP_DDR_QOS_IRQ_MASK (ZYNQMP_DDR_QOS_UE_MASK | ZYNQMP_DDR_QOS_CE_MASK) +/** + * enum snps_dq_width - SDRAM DQ bus width (ECC capable). + * SNPS_DQ_32: 32-bit memory data width. + * SNPS_DQ_64: 64-bit memory data width. + */ +enum snps_dq_width { + SNPS_DQ_32 = 2, + SNPS_DQ_64 = 3, +}; + +/** + * enum snps_dq_mode - SDRAM DQ bus mode. + * @SNPS_DQ_FULL: Full DQ bus width. + * @SNPS_DQ_HALF: Half DQ bus width. + * @SNPS_DQ_QRTR: Quarter DQ bus width. + */ +enum snps_dq_mode { + SNPS_DQ_FULL = 0, + SNPS_DQ_HALF = 1, + SNPS_DQ_QRTR = 2, +}; + +/** + * enum snps_burst_length - HIF/SDRAM burst transactions length. + * @SNPS_DDR_BL2: Burst length 2xSDRAM-words. + * @SNPS_DDR_BL4: Burst length 4xSDRAM-words. + * @SNPS_DDR_BL8: Burst length 8xSDRAM-words. + * @SNPS_DDR_BL16: Burst length 16xSDRAM-words. + */ +enum snps_burst_length { + SNPS_DDR_BL2 = 2, + SNPS_DDR_BL4 = 4, + SNPS_DDR_BL8 = 8, + SNPS_DDR_BL16 = 16, +}; + +/** + * enum snps_freq_ratio - HIF:SDRAM frequency ratio mode. + * @SNPS_FREQ_RATIO11: 1:1 frequency mode. + * @SNPS_FREQ_RATIO12: 1:2 frequency mode. + */ +enum snps_freq_ratio { + SNPS_FREQ_RATIO11 = 1, + SNPS_FREQ_RATIO12 = 2, +}; + +/** + * enum snps_ecc_mode - ECC mode. + * @SNPS_ECC_DISABLED: ECC is disabled/unavailable. + * @SNPS_ECC_SECDED: SEC/DED over 1 beat ECC (SideBand/Inline). + * @SNPS_ECC_ADVX4X8: Advanced ECC X4/X8 (SideBand). + */ +enum snps_ecc_mode { + SNPS_ECC_DISABLED = 0, + SNPS_ECC_SECDED = 4, + SNPS_ECC_ADVX4X8 = 5, +}; + +/** + * struct snps_ddrc_info - DDR controller platform parameters. + * @caps: DDR controller capabilities. + * @sdram_mode: Current SDRAM mode selected. + * @dev_cfg: Current memory device config (if applicable). + * @dq_width: Memory data bus width (width of the DQ signals + * connected to SDRAM chips). + * @dq_mode: Proportion of the DQ bus utilized to access SDRAM. + * @sdram_burst_len: SDRAM burst transaction length. + * @hif_burst_len: HIF burst transaction length (Host Interface). + * @freq_ratio: HIF/SDRAM frequency ratio mode. + * @ecc_mode: ECC mode enabled for the DDR controller (SEC/DED, etc). + * @ranks: Number of ranks enabled to access DIMM (1, 2 or 4). + */ +struct snps_ddrc_info { + unsigned int caps; + enum mem_type sdram_mode; + enum dev_type dev_cfg; + enum snps_dq_width dq_width; + enum snps_dq_mode dq_mode; + enum snps_burst_length sdram_burst_len; + enum snps_burst_length hif_burst_len; + enum snps_freq_ratio freq_ratio; + enum snps_ecc_mode ecc_mode; + unsigned int ranks; +}; + /** * struct snps_ecc_error_info - ECC error log information. * @row: Row number. @@ -242,6 +332,7 @@ struct snps_ecc_status { /** * struct snps_edac_priv - DDR memory controller private data. + * @info: DDR controller config info. * @pdev: Platform device. * @baseaddr: Base address of the DDR controller. * @reglock: Concurrent CSRs access lock. @@ -256,6 +347,7 @@ struct snps_ecc_status { * @rank_shift: Bit shifts for rank bit. */ struct snps_edac_priv { + struct snps_ddrc_info info; struct platform_device *pdev; void __iomem *baseaddr; spinlock_t reglock; @@ -495,23 +587,19 @@ static struct snps_edac_priv *snps_create_data(struct platform_device *pdev) /** * snps_get_dtype - Return the controller memory width. - * @base: DDR memory controller base address. + * @mstr: Master CSR value. * * Get the EDAC device type width appropriate for the current controller * configuration. * * Return: a device type width enumeration. */ -static enum dev_type snps_get_dtype(const void __iomem *base) +static inline enum dev_type snps_get_dtype(u32 mstr) { - u32 regval; - - regval = readl(base + DDR_MSTR_OFST); - if (!(regval & DDR_MSTR_MEM_DDR4)) + if (!(mstr & DDR_MSTR_MEM_DDR4)) return DEV_UNKNOWN; - regval = FIELD_GET(DDR_MSTR_DEV_CFG_MASK, regval); - switch (regval) { + switch (FIELD_GET(DDR_MSTR_DEV_CFG_MASK, mstr)) { case DDR_MSTR_DEV_X4: return DEV_X4; case DDR_MSTR_DEV_X8: @@ -525,24 +613,6 @@ static enum dev_type snps_get_dtype(const void __iomem *base) return DEV_UNKNOWN; } -/** - * snps_get_ecc_state - Return the controller ECC enable/disable status. - * @base: DDR memory controller base address. - * - * Get the ECC enable/disable status for the controller. - * - * Return: a ECC status boolean i.e true/false - enabled/disabled. - */ -static bool snps_get_ecc_state(void __iomem *base) -{ - u32 regval; - - regval = readl(base + ECC_CFG0_OFST); - regval = FIELD_GET(ECC_CFG0_MODE_MASK, regval); - - return (regval == ECC_CFG0_MODE_SECDED); -} - /** * snps_get_memsize - Read the size of the attached memory device. * @@ -559,21 +629,16 @@ static u32 snps_get_memsize(void) /** * snps_get_mtype - Returns controller memory type. - * @base: Synopsys ECC status structure. + * @mstr: Master CSR value. * * Get the EDAC memory type appropriate for the current controller * configuration. * * Return: a memory type enumeration. */ -static enum mem_type snps_get_mtype(const void __iomem *base) +static inline enum mem_type snps_get_mtype(u32 mstr) { - u32 regval; - - regval = readl(base + DDR_MSTR_OFST); - regval = FIELD_GET(DDR_MSTR_MEM_MASK, regval); - - switch (regval) { + switch (FIELD_GET(DDR_MSTR_MEM_MASK, mstr)) { case DDR_MSTR_MEM_DDR2: return MEM_DDR2; case DDR_MSTR_MEM_DDR3: @@ -593,6 +658,69 @@ static enum mem_type snps_get_mtype(const void __iomem *base) return MEM_RESERVED; } +/** + * snps_get_ddrc_info - Get the DDR controller config data. + * @priv: DDR memory controller private data. + * + * Return: negative errno if no ECC detected, otherwise - zero. + */ +static int snps_get_ddrc_info(struct snps_edac_priv *priv) +{ + int (*init_plat)(struct snps_edac_priv *priv); + u32 regval; + + /* Before getting the DDRC parameters make sure ECC is enabled */ + regval = readl(priv->baseaddr + ECC_CFG0_OFST); + + priv->info.ecc_mode = FIELD_GET(ECC_CFG0_MODE_MASK, regval); + if (priv->info.ecc_mode != SNPS_ECC_SECDED) { + edac_printk(KERN_INFO, EDAC_MC, "SEC/DED ECC not enabled\n"); + return -ENXIO; + } + + /* Auto-detect the basic HIF/SDRAM bus parameters */ + regval = readl(priv->baseaddr + DDR_MSTR_OFST); + + priv->info.sdram_mode = snps_get_mtype(regval); + priv->info.dev_cfg = snps_get_dtype(regval); + + priv->info.dq_mode = FIELD_GET(DDR_MSTR_BUSWIDTH_MASK, regval); + + /* + * Assume HIF burst length matches the SDRAM burst length since it's + * not auto-detectable + */ + priv->info.sdram_burst_len = FIELD_GET(DDR_MSTR_BURST_RDWR, regval) << 1; + priv->info.hif_burst_len = priv->info.sdram_burst_len; + + /* Retrieve the current HIF/SDRAM frequency ratio: 1:1 vs 1:2 */ + priv->info.freq_ratio = !(regval & DDR_MSTR_FREQ_RATIO11) + 1; + + /* Activated ranks field: set bit corresponds to populated rank */ + priv->info.ranks = FIELD_GET(DDR_MSTR_ACT_RANKS_MASK, regval); + priv->info.ranks = hweight_long(priv->info.ranks); + + /* Auto-detect the DQ bus width by using the ECC-poison pattern CSR */ + writel(0, priv->baseaddr + DDR_SWCTL); + + /* + * If poison pattern [32:64] is changeable then DQ is 64-bit wide. + * Note the feature has been available since IP-core v2.51a. + */ + regval = readl(priv->baseaddr + ECC_POISONPAT1_OFST); + writel(~regval, priv->baseaddr + ECC_POISONPAT1_OFST); + if (regval != readl(priv->baseaddr + ECC_POISONPAT1_OFST)) { + priv->info.dq_width = SNPS_DQ_64; + writel(regval, priv->baseaddr + ECC_POISONPAT1_OFST); + } else { + priv->info.dq_width = SNPS_DQ_32; + } + + writel(1, priv->baseaddr + DDR_SWCTL); + + return 0; +} + /** * snps_init_csrows - Initialize the csrow data. * @mci: EDAC memory controller instance. @@ -615,10 +743,10 @@ static void snps_init_csrows(struct mem_ctl_info *mci) for (j = 0; j < csi->nr_channels; j++) { dimm = csi->channels[j]->dimm; dimm->edac_mode = EDAC_SECDED; - dimm->mtype = snps_get_mtype(priv->baseaddr); + dimm->mtype = priv->info.sdram_mode; dimm->nr_pages = (size >> PAGE_SHIFT) / csi->nr_channels; dimm->grain = SNPS_EDAC_ERR_GRAIN; - dimm->dtype = snps_get_dtype(priv->baseaddr); + dimm->dtype = priv->info.dev_cfg; } } } @@ -732,6 +860,33 @@ static int snps_setup_irq(struct mem_ctl_info *mci) #define SNPS_DBGFS_BUF_LEN 128 +static int snps_ddrc_info_show(struct seq_file *s, void *data) +{ + struct mem_ctl_info *mci = s->private; + struct snps_edac_priv *priv = mci->pvt_info; + + seq_printf(s, "SDRAM: %s\n", edac_mem_types[priv->info.sdram_mode]); + + seq_printf(s, "DQ bus: %u/%s\n", (BITS_PER_BYTE << priv->info.dq_width), + priv->info.dq_mode == SNPS_DQ_FULL ? "Full" : + priv->info.dq_mode == SNPS_DQ_HALF ? "Half" : + priv->info.dq_mode == SNPS_DQ_QRTR ? "Quarter" : + "Unknown"); + seq_printf(s, "Burst: SDRAM %u HIF %u\n", priv->info.sdram_burst_len, + priv->info.hif_burst_len); + + seq_printf(s, "Ranks: %u\n", priv->info.ranks); + + seq_printf(s, "ECC: %s\n", + priv->info.ecc_mode == SNPS_ECC_SECDED ? "SEC/DED" : + priv->info.ecc_mode == SNPS_ECC_ADVX4X8 ? "Advanced X4/X8" : + "Unknown"); + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(snps_ddrc_info); + /** * snps_data_poison_setup - Update poison registers. * @priv: DDR memory controller private instance data. @@ -853,12 +1008,8 @@ static void snps_setup_row_address_map(struct snps_edac_priv *priv, u32 *addrmap static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addrmap) { - u32 width, memtype; int index; - memtype = readl(priv->baseaddr + DDR_MSTR_OFST); - width = FIELD_GET(DDR_MSTR_BUSWIDTH_MASK, memtype); - priv->col_shift[0] = 0; priv->col_shift[1] = 1; priv->col_shift[2] = (addrmap[2] & COL_MAX_VAL_MASK) + COL_B2_BASE; @@ -882,8 +1033,8 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr priv->col_shift[9] = (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) + COL_B9_BASE); - if (width == DDR_MSTR_BUSWIDTH_64) { - if (memtype & DDR_MSTR_MEM_LPDDR3) { + if (priv->info.dq_mode == SNPS_DQ_FULL) { + if (priv->info.sdram_mode == MEM_LPDDR3) { priv->col_shift[10] = ((addrmap[4] & COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : ((addrmap[4] & COL_MAX_VAL_MASK) + @@ -902,8 +1053,8 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr (((addrmap[4] >> 8) & COL_MAX_VAL_MASK) + COL_B11_BASE); } - } else if (width == DDR_MSTR_BUSWIDTH_32) { - if (memtype & DDR_MSTR_MEM_LPDDR3) { + } else if (priv->info.dq_mode == SNPS_DQ_HALF) { + if (priv->info.sdram_mode == MEM_LPDDR3) { priv->col_shift[10] = (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) + @@ -923,7 +1074,7 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr COL_B10_BASE); } } else { - if (memtype & DDR_MSTR_MEM_LPDDR3) { + if (priv->info.sdram_mode == MEM_LPDDR3) { priv->col_shift[10] = (((addrmap[3] >> 16) & COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : (((addrmap[3] >> 16) & COL_MAX_VAL_MASK) + @@ -944,10 +1095,11 @@ static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addr } } - if (width) { - for (index = 9; index > width; index--) { - priv->col_shift[index] = priv->col_shift[index - width]; - priv->col_shift[index - width] = 0; + if (priv->info.dq_mode) { + for (index = 9; index > priv->info.dq_mode; index--) { + priv->col_shift[index] = + priv->col_shift[index - priv->info.dq_mode]; + priv->col_shift[index - priv->info.dq_mode] = 0; } } @@ -1109,6 +1261,9 @@ static void snps_create_debugfs_nodes(struct mem_ctl_info *mci) snps_setup_address_map(priv); + edac_debugfs_create_file("ddrc_info", 0400, mci->debugfs, mci, + &snps_ddrc_info_fops); + edac_debugfs_create_file("inject_data_error", 0600, mci->debugfs, mci, &snps_inject_data_error); @@ -1141,10 +1296,9 @@ static int snps_mc_probe(struct platform_device *pdev) if (IS_ERR(priv)) return PTR_ERR(priv); - if (!snps_get_ecc_state(baseaddr)) { - edac_printk(KERN_INFO, EDAC_MC, "ECC not enabled\n"); - return -ENXIO; - } + rc = snps_get_ddrc_info(priv); + if (rc) + return rc; mci = snps_mc_create(priv); if (IS_ERR(mci)) From patchwork Wed Sep 20 19:26:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393335 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 603EDC04FF1 for ; Wed, 20 Sep 2023 19:29:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=1ko5Sghni0tmQBwN8VbUy8M/zX6q5iPoJ5lppDJfPFc=; b=yIyIK/qF062Kb8 J9O8AxbgJTrd29zWXFAgYen76gGrnQgVngByB3zwy8C3/0pi384sT8KW57D0HVAzkF8yXPflY0Hwy Lldkn0iqF6m+sPq6NDketcMH4/pxlYOlcbJ0NXMn4E2KdrXAnK6tZvKticsk96InfH9qXzECX5Pu9 b6aR161nlAJmzXbeGxuXKHDAEUzO1vbEKTKd0K4nY8LZaqFBmlGK3bIA1HGMr7n8xvvudXRxRq00J xRdsk31O03GTjCg9VEoiYjqEsg6QiBAcymoJG5Dx92eQR1IcoxssiOZnX4ZfGHERM5CoMu07vxfVV pBbKg73r3Bpd1/XVKKYA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sV-0040It-0G; Wed, 20 Sep 2023 19:28:51 +0000 Received: from mail-lf1-x12b.google.com ([2a00:1450:4864:20::12b]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sH-0040AI-2k for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:39 +0000 Received: by mail-lf1-x12b.google.com with SMTP id 2adb3069b0e04-5029ace4a28so1547318e87.1 for ; Wed, 20 Sep 2023 12:28:37 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238116; x=1695842916; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=AdGvtIhnrYM49qOF0XUq1B70UdgD51RskmRPZFchMpY=; b=N2MzDJ0W3MRRM5qDjXwcWiO0u6zoIrBAVqTMwlag1u9mCobmxfbJYA8pYo3usvQmX/ RptkFSrLPlLlepzTwrAxF1csA75lz05e8NiVcWSdCGRWkyWaQhGt6qbTHVzEHX3yj/Nz lrDx/ZJVovsvf2RriulKOPoruzjc0ye8A1ruRF/ZV+t2rOGYi1jjWnCkthSZWDKAwkLh IHskoL3O6JJf8bsXRREq9pOA+nXZhFVP8jGgx2eYg2ZE4qo8GwFw1OR5Wh68dH7z/Dkk EZC0oOuRe+Npf2g+aHvfhUA6ti2tnN7E6/D6hRotQB/k/0R4Sb93Dqg6ktIU7ovKjQnc ItEg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238116; x=1695842916; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=AdGvtIhnrYM49qOF0XUq1B70UdgD51RskmRPZFchMpY=; b=HgPNtYZC+6+SUsv/MFvGkQ+Ymlb1pkAeoJo3dHjPYLVPTV2xO19NPRGGOc+U/sNOaS FH8KjJB+S6LH72JerCgDQDn3u9qXi4P/ohI5F3rRyqElRvtx98LnT3oSVYh3e/uaZceJ uIzUy01g9SCinp9zm4neDGdTV4ORghURFpLersSEVuKGDYHf4bdYm2dpbIySMb5mXqJ+ LGcrrL0FFOZm00dlU59GyHGZuk4+eWswNQHikpQ/uqsLm9GaVwpB2cpq85MuUeQ4YLjx rdreM05sqSVLivVglFtvOwAqXuZ5Ad71E/7NzJdPNEr/laNvbHUUA6gHAeRgkZiKKanF tOZg== X-Gm-Message-State: AOJu0Yw40NDv+cLX1hEseOlB6aBzHVl23F24JnVxyRYS2RMvKba9hvfT ZZS2Leghz4m8X0VYnfMAeFs= X-Google-Smtp-Source: AGHT+IGvY2WjckLrqKF2TZ5J4zmwaRfWiTj3OXCSDcx1z66FZOZ2M7wBbipUU8euAtyWN4c2zI6iZQ== X-Received: by 2002:a05:6512:3d29:b0:502:d973:3206 with SMTP id d41-20020a0565123d2900b00502d9733206mr3053467lfv.6.1695238116092; Wed, 20 Sep 2023 12:28:36 -0700 (PDT) Received: from localhost ([85.140.0.70]) by smtp.gmail.com with ESMTPSA id p21-20020a19f015000000b00500a14a6659sm2769277lfc.51.2023.09.20.12.28.34 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:35 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 06/18] EDAC/synopsys: Convert plat-data to plat-init function Date: Wed, 20 Sep 2023 22:26:51 +0300 Message-ID: <20230920192806.29960-7-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122837_903789_57894979 X-CRM114-Status: GOOD ( 24.63 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Since DW uMCTL2 device info and capabilities infrastructure is now available there is no point in supporting an additional abstraction like platform quirks. Instead convert the already defined ZynqMP quirk to the ZynqMP-specific capability and add the platform-specific initialization function support. This function will be called after the device parameters are detected and thus fixing some of them if required. Note the new approach will provide a very flexible interface of the platform-specific setups. The platform-specific init() callback can be used not only for the capabilities flags modification, but for example for the resources requests or custom CSRs alterations. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 68 +++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 33 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index b830e4b4292d..b77bc84c0bb0 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -34,8 +34,8 @@ #define SNPS_EDAC_MOD_STRING "snps_edac" #define SNPS_EDAC_MOD_VER "1" -/* DDR ECC Quirks */ -#define SNPS_ZYNQMP_IRQ_REGS BIT(0) +/* DDR capabilities */ +#define SNPS_CAP_ZYNQMP BIT(31) /* Synopsys uMCTL2 DDR controller registers that are relevant to ECC */ @@ -338,7 +338,6 @@ struct snps_ecc_status { * @reglock: Concurrent CSRs access lock. * @message: Buffer for framing the event specific info. * @stat: ECC status information. - * @p_data: Platform data. * @poison_addr: Data poison address. * @row_shift: Bit shifts for row bit. * @col_shift: Bit shifts for column bit. @@ -353,7 +352,6 @@ struct snps_edac_priv { spinlock_t reglock; char message[SNPS_EDAC_MSG_SIZE]; struct snps_ecc_status stat; - const struct snps_platform_data *p_data; #ifdef CONFIG_EDAC_DEBUG ulong poison_addr; u32 row_shift[18]; @@ -364,14 +362,6 @@ struct snps_edac_priv { #endif }; -/** - * struct snps_platform_data - Synopsys uMCTL2 DDRC platform data. - * @quirks: IP-core specific quirks. - */ -struct snps_platform_data { - u32 quirks; -}; - /** * snps_get_error_info - Get the current ECC error info. * @priv: DDR memory controller private instance data. @@ -485,7 +475,7 @@ static void snps_enable_irq(struct snps_edac_priv *priv) unsigned long flags; /* Enable UE/CE Interrupts */ - if (priv->p_data->quirks & SNPS_ZYNQMP_IRQ_REGS) { + if (priv->info.caps & SNPS_CAP_ZYNQMP) { writel(ZYNQMP_DDR_QOS_UE_MASK | ZYNQMP_DDR_QOS_CE_MASK, priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_EN_OFST); @@ -509,7 +499,7 @@ static void snps_disable_irq(struct snps_edac_priv *priv) unsigned long flags; /* Disable UE/CE Interrupts */ - if (priv->p_data->quirks & SNPS_ZYNQMP_IRQ_REGS) { + if (priv->info.caps & SNPS_CAP_ZYNQMP) { writel(ZYNQMP_DDR_QOS_UE_MASK | ZYNQMP_DDR_QOS_CE_MASK, priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_DB_OFST); @@ -538,7 +528,7 @@ static irqreturn_t snps_irq_handler(int irq, void *dev_id) priv = mci->pvt_info; - if (priv->p_data->quirks & SNPS_ZYNQMP_IRQ_REGS) { + if (priv->info.caps & SNPS_CAP_ZYNQMP) { regval = readl(priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_STAT_OFST); regval &= (ZYNQMP_DDR_QOS_CE_MASK | ZYNQMP_DDR_QOS_UE_MASK); if (!(regval & ZYNQMP_DDR_QOS_IRQ_MASK)) @@ -551,7 +541,7 @@ static irqreturn_t snps_irq_handler(int irq, void *dev_id) snps_handle_error(mci, &priv->stat); - if (priv->p_data->quirks & SNPS_ZYNQMP_IRQ_REGS) + if (priv->info.caps & SNPS_CAP_ZYNQMP) writel(regval, priv->baseaddr + ZYNQMP_DDR_QOS_IRQ_STAT_OFST); return IRQ_HANDLED; @@ -575,16 +565,26 @@ static struct snps_edac_priv *snps_create_data(struct platform_device *pdev) if (IS_ERR(priv->baseaddr)) return ERR_CAST(priv->baseaddr); - priv->p_data = of_device_get_match_data(&pdev->dev); - if (!priv->p_data) - return ERR_PTR(-ENODEV); - priv->pdev = pdev; spin_lock_init(&priv->reglock); return priv; } +/* + * zynqmp_init_plat - ZynqMP-specific platform initialization. + * @priv: DDR memory controller private data. + * + * Return: always zero. + */ +static int zynqmp_init_plat(struct snps_edac_priv *priv) +{ + priv->info.caps |= SNPS_CAP_ZYNQMP; + priv->info.dq_width = SNPS_DQ_64; + + return 0; +} + /** * snps_get_dtype - Return the controller memory width. * @mstr: Master CSR value. @@ -718,7 +718,10 @@ static int snps_get_ddrc_info(struct snps_edac_priv *priv) writel(1, priv->baseaddr + DDR_SWCTL); - return 0; + /* Apply platform setups after all the configs auto-detection */ + init_plat = device_get_match_data(&priv->pdev->dev); + + return init_plat ? init_plat(priv) : 0; } /** @@ -822,8 +825,6 @@ static void snps_mc_free(struct mem_ctl_info *mci) edac_mc_free(mci); } - - static int snps_setup_irq(struct mem_ctl_info *mci) { struct snps_edac_priv *priv = mci->pvt_info; @@ -882,6 +883,15 @@ static int snps_ddrc_info_show(struct seq_file *s, void *data) priv->info.ecc_mode == SNPS_ECC_ADVX4X8 ? "Advanced X4/X8" : "Unknown"); + seq_puts(s, "Caps:"); + if (priv->info.caps) { + if (priv->info.caps & SNPS_CAP_ZYNQMP) + seq_puts(s, " +ZynqMP"); + } else { + seq_puts(s, " -"); + } + seq_putc(s, '\n'); + return 0; } @@ -1345,17 +1355,9 @@ static int snps_mc_remove(struct platform_device *pdev) return 0; } -static const struct snps_platform_data zynqmp_edac_def = { - .quirks = SNPS_ZYNQMP_IRQ_REGS, -}; - -static const struct snps_platform_data snps_edac_def = { - .quirks = 0, -}; - static const struct of_device_id snps_edac_match[] = { - { .compatible = "xlnx,zynqmp-ddrc-2.40a", .data = &zynqmp_edac_def }, - { .compatible = "snps,ddrc-3.80a", .data = &snps_edac_def }, + { .compatible = "xlnx,zynqmp-ddrc-2.40a", .data = zynqmp_init_plat }, + { .compatible = "snps,ddrc-3.80a" }, { } }; MODULE_DEVICE_TABLE(of, snps_edac_match); From patchwork Wed Sep 20 19:26:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393333 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A05A3C04FF1 for ; Wed, 20 Sep 2023 19:29:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=oQIqr9TzKMsEUHLw3XpUDGFsD0WnmR95H5+tB4OSdnI=; b=I3189xUOQfA1fa 2YueCjNkJgCXLulWgtMkkGQQZ/6cW2IFLktF3+veapAHroxSMPEu8uL8YlAfLHZBt2cvuuUG9Eeyd 6qLFbmdgm0l5kZjYjtr4DReju0gbEaTTPJek3sEZ7qw8ZC/40zrbA19QkELO64geka3/XlxgSYmIa w75iLm4dJcIvfs1PRSpr1YA8DlPyBWwmid29pTYA0kEJPEAjcYyUBxNs4swJxh1w57eF2Jxjgm2Ef d3HAih0FvA5lptnQGwfc51jUEy+CwA37tx6VqzUiMJMGuCAx4MayGEIrmphzk9/hYhUedBU6oT3ML PMdij2N/QQNqNa4W9d1A==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sW-0040Jl-0C; Wed, 20 Sep 2023 19:28:52 +0000 Received: from mail-lf1-x131.google.com ([2a00:1450:4864:20::131]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sP-0040Eq-0q for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:46 +0000 Received: by mail-lf1-x131.google.com with SMTP id 2adb3069b0e04-50300cb4776so366241e87.3 for ; Wed, 20 Sep 2023 12:28:44 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238123; x=1695842923; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=9BUlFc32U67LJr2U7BzHv473MxaTEfZQ+YLInYVLVj8=; b=YTXAIz7WdzwOWyux6yTXU93iRVMv69aWmApxC6DmIziW6ehzOGEugjI7dTxaZ7Xozz 5WIfW5Ef08/vQXlqHk1La3QSgzNR4YcncqG/wmF1DJ3fTEmt2ptBUhYlvabuG2rwXJng xNwULMIznesRPtyjHk+NIxgO8IRHJNrQDLHkEg7RKI/b7MnuwuBuvuGVixR+XRaylnYA 9H/8aiSfzJxySES9eL8EzmimiT4cIS9xb2VrDXxDXIBEPuEmoSbrGfrA0EOl0gjnHVu9 ELF+V/O5Dl6JZuETcQtn+xUKp9d0omMTu8K73qytTPTiExCbJSOULh9DYvAFKTHCDaxt ws9A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238123; x=1695842923; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=9BUlFc32U67LJr2U7BzHv473MxaTEfZQ+YLInYVLVj8=; b=X1JbPdsXlUUT07nRmVbw56zzwECgKGqOyI4Wy6KNXaPWW8z6LpvRrpjj7SURY9v1iB JfFCthtIhF9GLFRY5HyaAjaJSCsEqiCv9g2Uc/lh63ZxMYDqbRHtwABxVchgHVTp4MwI fhay2vwZfkBdsIRpOeKwO3GU1rb3DeUwS2k303Xud5cbo67BKPK/uGkNKE01EMcAZUFF DE3R9ungcpfe4TeoET7JS4yOMABSZpmQ7779G/a+/FirlJz6ULZsSPcM+eMgFNYzcQW+ TIyIriX8tJ6cV3fUQ+TvbM1D3NGYhyUaPnapa/iR9Dg8tjohyDI0i2aEyytgAHVLS5lX xBaw== X-Gm-Message-State: AOJu0YxxhRe/rSrlv+bKGarBECB+ET+f2xVK8OxWoGPkEDRskiZ7Hsbk HGf2/pynX7cNFR0bloZiE3k= X-Google-Smtp-Source: AGHT+IFYNvADX+pg8J040J7aG80SLXnN5ERc9qA5f7ctLC5xfL2gP5i7P26Ct9T5OB35Yi6y+G1VvQ== X-Received: by 2002:a19:384b:0:b0:4fd:c715:5667 with SMTP id d11-20020a19384b000000b004fdc7155667mr2480908lfj.20.1695238123500; Wed, 20 Sep 2023 12:28:43 -0700 (PDT) Received: from localhost ([178.176.82.53]) by smtp.gmail.com with ESMTPSA id d5-20020ac241c5000000b004fe28e3841bsm2793757lfi.267.2023.09.20.12.28.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:42 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 07/18] EDAC/synopsys: Parse ADDRMAP[7-8] CSRs for (LP)DDR4 only Date: Wed, 20 Sep 2023 22:26:52 +0300 Message-ID: <20230920192806.29960-8-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122845_329731_F3826A5D X-CRM114-Status: GOOD ( 14.25 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org These CSRs contain the SDRAM Bank Groups and row[16]/row[17] bits mapping, which are applicable for the DDR4 and LPDDR4 memory chips only. For the rest of the memories the ADDRMAP[7-8] registers are unused by the controller and are zeros by default. The zero values will be perceived by the HIF/SDRAM mapping detection procedure as normal bit positions, which is wrong. So in order to prevent that parse these registers only if they are applicable for the detected DDR protocol. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index b77bc84c0bb0..5a06038aedcb 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -1008,12 +1008,15 @@ static void snps_setup_row_address_map(struct snps_edac_priv *priv, u32 *addrmap priv->row_shift[15] = (((addrmap[6] >> 24) & ROW_MAX_VAL_MASK) == ROW_MAX_VAL_MASK) ? 0 : (((addrmap[6] >> 24) & ROW_MAX_VAL_MASK) + ROW_B15_BASE); - priv->row_shift[16] = ((addrmap[7] & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : ((addrmap[7] & - ROW_MAX_VAL_MASK) + ROW_B16_BASE); - priv->row_shift[17] = (((addrmap[7] >> 8) & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : (((addrmap[7] >> 8) & - ROW_MAX_VAL_MASK) + ROW_B17_BASE); + + if (priv->info.sdram_mode == MEM_DDR4 || priv->info.sdram_mode == MEM_LPDDR4) { + priv->row_shift[16] = ((addrmap[7] & ROW_MAX_VAL_MASK) == + ROW_MAX_VAL_MASK) ? 0 : ((addrmap[7] & + ROW_MAX_VAL_MASK) + ROW_B16_BASE); + priv->row_shift[17] = (((addrmap[7] >> 8) & ROW_MAX_VAL_MASK) == + ROW_MAX_VAL_MASK) ? 0 : (((addrmap[7] >> 8) & + ROW_MAX_VAL_MASK) + ROW_B17_BASE); + } } static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addrmap) @@ -1129,6 +1132,10 @@ static void snps_setup_bank_address_map(struct snps_edac_priv *priv, u32 *addrma static void snps_setup_bg_address_map(struct snps_edac_priv *priv, u32 *addrmap) { + /* Bank group signals are available on the DDR4 memory only */ + if (priv->info.sdram_mode != MEM_DDR4) + return; + priv->bankgrp_shift[0] = (addrmap[8] & BANKGRP_MAX_VAL_MASK) + BANKGRP_B0_BASE; priv->bankgrp_shift[1] = (((addrmap[8] >> 8) & BANKGRP_MAX_VAL_MASK) == From patchwork Wed Sep 20 19:26:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393343 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 67A6CC04FF1 for ; Wed, 20 Sep 2023 19:29:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=2asz8jl2tLEw+HcMjcXWJ+NEQqrpkPlwhA/rfBICZMY=; b=3Rj0fBcSwxR4gu b4bGHWDVACaLz2mqqbxnAJBxQPAnb01E1b2fNizHeHz/hbe1jiDtMnvQpKIUA123SjwiqtHDExL19 QeDVqIkTf+6dDzZ8ziZFLpiy9ZJ+JRMJUAzbMd2eKv4ZomsQ/lB1lPIBVAtr+fPpsbfXrpHM5PYEh 7MV5QXz9Fe8M0Egp9sZGPXqdcmF6QVYDXVlfwk5pUHXkcF/gDxhQ6AjsyMV/Px5VgDqIPikv4FeWc Rys1mqNvkvwMc066XSQXO0NlqcKD0814PxbP0pu1GrLUTxg9k4zKuQAJuUJ/EvtYat+92IMpD4qH/ 6tnSgNzoBpVXdmIM4mMg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sn-0040WX-1k; Wed, 20 Sep 2023 19:29:09 +0000 Received: from mail-lj1-x236.google.com ([2a00:1450:4864:20::236]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sS-0040Gd-38 for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:50 +0000 Received: by mail-lj1-x236.google.com with SMTP id 38308e7fff4ca-2b962c226ceso2464941fa.3 for ; Wed, 20 Sep 2023 12:28:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238127; x=1695842927; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=TA5e5G5EPvnnL49j/b8nNcZDnZYJMuuDQgONa21D59s=; b=I2Vocha2UfTFy/4Qmx5x0ezy0nTCRixdaax10UxKt1jgit6IYVRod2ePTujkGAMShL 9dlySXnAsCEOh/44SbZgjFoTUkNAha/ohjZHubEn+rCib0AWrwjkziQxdYyf2Ex9yF3v YHeNrTxQ8Z1qs3t3pInbBgblnZA9ubmvkAcVeXlqDoL0doCstIBuR4EQIAp3kezW2sRg 6ZpBsM+HtVe4Ar5eSBTFhA5Q6LVhfW9QCqm5CEy5tBhqnKVEy1RbxkfpPClZQ5pfx89/ UldIEgPkKoKbRD3OY07U8E6pYkrPLusGpHDi1WVW7HuZyxnv61pTuS1fucFoQvdbPo3J 3ihQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238127; x=1695842927; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=TA5e5G5EPvnnL49j/b8nNcZDnZYJMuuDQgONa21D59s=; b=r+3kmyxVDJOxPak1G9T5OrWbGnuagSwnRMjgnixgFIQ2wPTfMv+OEHqpLbEYRKxBDB M+bGfl91vkf7dSpA33uO0//ZCat/CZE4tibj3y/2VgcSOQupT3qwYgaLJpdf9hDGHkIW cwgPTg7/tFrdq054RbcNLdk0u+PaHLNmvpSKHjjANJkeAjrDOmOJtBq9DZyepI0DnvQ8 yRXgdjmjpp7UFozEIOzoaUfAjJSxEVjJWOfSV0aGJ71bZsGNJ64GxDz08a9YbWNpEhvj /B5I9bviQyh1qlxPtJlnqbkz1EHvp5EoLgfZzNkdvNmRm5YFv3eHmUUaZkaCeGeTuYd9 VG3Q== X-Gm-Message-State: AOJu0YyMvLqwTlzH0LUX1ibigW37nv1qtOXTpsu+S0tflUmlO2q/Ui5n yNT/QnnoIuEU1fTA71fs8O4= X-Google-Smtp-Source: AGHT+IFZDSF5zoq/W8jvFfDRKCF1KokOy7dJYucnqgvUrulEP8IaDlgpjwEqAHOhtU+vPGMtXh3DmA== X-Received: by 2002:a05:6512:104f:b0:503:364e:96ce with SMTP id c15-20020a056512104f00b00503364e96cemr3532656lfb.29.1695238126987; Wed, 20 Sep 2023 12:28:46 -0700 (PDT) Received: from localhost ([178.176.85.138]) by smtp.gmail.com with ESMTPSA id j26-20020a19f51a000000b004ff973cb14esm739436lfb.108.2023.09.20.12.28.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:45 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 08/18] EDAC/synopsys: Parse ADDRMAP[0] CSR for multi-ranks case only Date: Wed, 20 Sep 2023 22:26:53 +0300 Message-ID: <20230920192806.29960-9-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122849_096362_E20112B0 X-CRM114-Status: GOOD ( 15.85 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org The ADDRMAP[0] CSR contains the SDRAM Rank bits mapping (and memory channel mapping but it's irrelevant in this case). Obviously they are applicable for the multi-ranked memory only. If either the attached memory isn't multi-ranked or the controller simply doesn't support the multi-rank memory, parsing the ADDRMAP[0] CSR will be not just pointless, but in the later case erroneous since the CSR fields will contain zeros which will be perceived by the mapping detection procedure as a valid value. So the mapping will get to be invalid. Thus make sure the ADDRMAP[0] register is parsed only if a multi-ranked memory setup has been detected. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 5a06038aedcb..e6288e135480 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -1146,9 +1146,12 @@ static void snps_setup_bg_address_map(struct snps_edac_priv *priv, u32 *addrmap) static void snps_setup_rank_address_map(struct snps_edac_priv *priv, u32 *addrmap) { - priv->rank_shift[0] = ((addrmap[0] & RANK_MAX_VAL_MASK) == - RANK_MAX_VAL_MASK) ? 0 : ((addrmap[0] & - RANK_MAX_VAL_MASK) + RANK_B0_BASE); + /* Ranks mapping is unavailable for the single-ranked memory */ + if (priv->info.ranks > 1) { + priv->rank_shift[0] = ((addrmap[0] & RANK_MAX_VAL_MASK) == + RANK_MAX_VAL_MASK) ? 0 : ((addrmap[0] & + RANK_MAX_VAL_MASK) + RANK_B0_BASE); + } } /** From patchwork Wed Sep 20 19:26:54 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393342 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 684EAC04FF3 for ; Wed, 20 Sep 2023 19:29:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Q1OyjdOJj+uPLAS56/22XguJBtNn2s9l3fnlcFOjQxE=; b=VDknBKSnaBW6sP Q8GPmUO/v+dJUKYq6fBQmYUTf3SOGI5eEPEHXE2p8ria2Hf63PcIOybo7wT2XSteXQon/1GmKsXyu xAE5Fc3NJW2XYJHhMlJOwMlojnTVwHMUocb+ZB7HLT59Ljvj6C/O38nyaPvBvJO03uo1WZISNy7fD o+GTwhZsfISzzuT1B84a7YOZfJiHINeFIl4zm/qo8cHZPbr5u7isFHDGTYdY5ikCaraJtef3U7H6H zRdA6es7mu7js7Gelq4pET3Y77XVq12CGgP6ebBQ8Q2q9UBUWt5+U+uU/1FgWAlIHbE6iQDZ6nOBN YiD50CVV2+QYojx5ezJw==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2so-0040XA-1X; Wed, 20 Sep 2023 19:29:10 +0000 Received: from mail-lf1-x12e.google.com ([2a00:1450:4864:20::12e]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sX-0040Ig-17 for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:54 +0000 Received: by mail-lf1-x12e.google.com with SMTP id 2adb3069b0e04-50300cb4776so366412e87.3 for ; Wed, 20 Sep 2023 12:28:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238130; x=1695842930; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=QqkMxqOHncqsMYhQRlBDL7MG22B9ye3F7LSOor6Fxdc=; b=aFvA4QyAGEfD9nw6TrOa2Fwrg05ixI6DlUUx91futu2KEHdsaRub4vwPagfNqrmQuL +WZMLTjBglSfhXbUTMRmICFUJR8WYEuff/UZO6pPUPio0tMSBhmnMoQ2bOLL8Vu048pV Di7CW0Wisj5aYxHfXhDqurQiY0tEnegzQmklRPQZ2+4b9YVblcrXlcREhf/9jPGUON2f 2Nt1RGjYdaf8UG2Z5RmUyFwhhSPs8QRhwpwLGepkR0vDpvKHd+MccK41cpHbnlgggZL6 X3zTUR4yNYxcOMev3+Yo1ZeFygOslyaTL0edx0FkOk0IcOCJ8s05+oOHAESZuS6E2+8y KJmw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238130; x=1695842930; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=QqkMxqOHncqsMYhQRlBDL7MG22B9ye3F7LSOor6Fxdc=; b=EzHJBH6S20qACG5aYYEj6kofRIa19tf02SN4Hh3WPCDKNK7OiYEV+O+0UbVdZvkAXk ooTggaLjr52KDhBbfTp11FWrykukW/LGt08d2gEGjYVHuv6JMnb3ibDBsB2gTg8IjWMq J5xYxcRxTW2Jde3bNs8io41JjlcZICHHx3eD7Y6BJ02yJBCMYYAS1tTM+izBCrHlAsvm HyjKz6IeoT3e1gaYlPUqudZ8yf5IeBC+LFh9KLKqu5zA+69wiU1JYhcqrz3RdWEfWB9k iRJL+OG5yiv7XsY9zNZ5GMs1zsetpip/xPhSi4hZNc+5eOgtzXS+2ulv78BvKKnsWbSb rwFQ== X-Gm-Message-State: AOJu0YxjGl1q8HowEoJ6iZ1E0HYOJaBpq2MBhTmbjfO/2vEQyelyZsXI cZlsdVHMs2W1/knPJJCbvq4= X-Google-Smtp-Source: AGHT+IHwKIWEU16ms/otWDq2b8ELHaN+mH3xTI3PC2c/Z46prfo2moy4ZDTclGHfvjbZhTpn7gKqlQ== X-Received: by 2002:a05:6512:2813:b0:503:3803:9e99 with SMTP id cf19-20020a056512281300b0050338039e99mr4239358lfb.15.1695238129974; Wed, 20 Sep 2023 12:28:49 -0700 (PDT) Received: from localhost ([178.176.86.191]) by smtp.gmail.com with ESMTPSA id r6-20020a19ac46000000b00502e01d1383sm2805899lfc.27.2023.09.20.12.28.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:49 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 09/18] EDAC/synopsys: Set actual DIMM ECC errors grain Date: Wed, 20 Sep 2023 22:26:54 +0300 Message-ID: <20230920192806.29960-10-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122853_397891_C931D3C1 X-CRM114-Status: GOOD ( 17.17 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org It was wrong to set the DIMM errors grain parameter to just 1 byte because DW uMCTL2 DDRC calculates ECC for each SDRAM word and passes it as an additional byte of data to the memory chips. SDRAM word is the actual DQ-bus width determined by the DQ-width set during the IP-core synthesize and the DQ-bus mode (part of the DQ-bus actually used to get data from the memory chips) selected during the DDR controller initial setup procedure. Thus set the MCI DIMMs grain based on these parameters determined during the DW uMCTL2 DDRC config getting procedure. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index e6288e135480..e10778cead63 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -26,9 +26,6 @@ /* Number of channels per memory controller */ #define SNPS_EDAC_NR_CHANS 1 -/* Granularity of reported error in bytes */ -#define SNPS_EDAC_ERR_GRAIN 1 - #define SNPS_EDAC_MSG_SIZE 256 #define SNPS_EDAC_MOD_STRING "snps_edac" @@ -736,9 +733,12 @@ static void snps_init_csrows(struct mem_ctl_info *mci) struct snps_edac_priv *priv = mci->pvt_info; struct csrow_info *csi; struct dimm_info *dimm; - u32 size, row; + u32 size, row, width; int j; + /* Actual SDRAM-word width for which ECC is calculated */ + width = 1U << (priv->info.dq_width - priv->info.dq_mode); + for (row = 0; row < mci->nr_csrows; row++) { csi = mci->csrows[row]; size = snps_get_memsize(); @@ -748,7 +748,7 @@ static void snps_init_csrows(struct mem_ctl_info *mci) dimm->edac_mode = EDAC_SECDED; dimm->mtype = priv->info.sdram_mode; dimm->nr_pages = (size >> PAGE_SHIFT) / csi->nr_channels; - dimm->grain = SNPS_EDAC_ERR_GRAIN; + dimm->grain = width; dimm->dtype = priv->info.dev_cfg; } } From patchwork Wed Sep 20 19:26:55 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393344 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 4DB76C04FF3 for ; Wed, 20 Sep 2023 19:29:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=rQs8bodn1ARJeH3xALgVRBfeM87EhWVHlqL/HC/V3oY=; b=l8jfhWGVF3jdxP qbVvjdiPt7OM/JKf3gxjUMZPoZA9YvmSb/JWwAYE/sE2y67TmG8ORcFCf42PhTYGAcDDN4MJ3Aw2o K62hKHqkarTtrQemjP5zXR6bwT5oEml6GJM3RobNStiadWhw4hlefN83A0okEHWGFb3vlgdGOLoiz YR4jNFlQ2l+/mLyXFffstppRyF4779ki7ZjQ4gjGmLIfsdYbcwUIvQeEsuWTD40oZ4bJFXpwv6I6u oeXsvk+jd+kojI71Hlf98w7h5oPEvcz5fufG2IloXkhagXt6h6ELUf2pdsk1WryMY6ZbOAduOKsuk heczPBK8+xG+XovGKiBA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sp-0040Xv-1B; Wed, 20 Sep 2023 19:29:11 +0000 Received: from mail-lf1-x12c.google.com ([2a00:1450:4864:20::12c]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sZ-0040Lm-1s for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:28:57 +0000 Received: by mail-lf1-x12c.google.com with SMTP id 2adb3069b0e04-50300141a64so448721e87.0 for ; Wed, 20 Sep 2023 12:28:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238134; x=1695842934; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=dSPG6G1jeOItVuaHV8to9W/3RsF6DlFlBIE3fQ0A7VI=; b=NldMO42pz+BnhASnDAF7fWjmZGWonOpmYbcXgoynRJ+QPIoo/vGfgOCCVWgZdAzgMl Oxh/MK/oxnyHahsOTO+6PLLtiZCwxhLLIvAFDezc8H7DhIKu/RXALmG0oDGcpXO4Vk/p MqQX2+sAeAVhMj3zgsOjNDWwcZGmYGbpwkuTJtms1bmPMLxKJv+yQgdYprCWrm4tyB8X IwSryLapNFJRb5ReO8skph3e0d9oWjH4cOoSEfjFMw5NqrRJwkvjUjb1dJ8rM8wXXCa7 qE9XFsuqTy+VfBa3K7DHCZulgdOLPGXoQXGkZnj19htDvTgFJXPrGMoHsMnnAs2VnHhQ 9Tgg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238134; x=1695842934; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=dSPG6G1jeOItVuaHV8to9W/3RsF6DlFlBIE3fQ0A7VI=; b=vjV+cLsIGrEa20dpSQElLvE0PlPej4DMnhzkjzZbXraZyQ5YewRlaMBby6JZ2uBZzp 3U/3GwHbcQn8LAjV8cHgEVN1mdpPECodwhJ4gYi1cADp/rncZhlYSCq1kf/TMZ9GhveA d864ZiMEEvfTOBe5e3ORCEg5xw/cm0hv4klg7i3qIbErBZfIyQekkfGTMXY4uNIPxKc3 74W2I7KIESayOVedlTIU5ztIA5hf4hFV5DuI17vG6URLoqLOAz3Bjd6b+QOfIBQYRQw9 jr0YSOVySUczppbe4CUu6S0gBln29M2k029x/KwU+9bEfADscp3zrGFUv5MnUISgs/VX CAVw== X-Gm-Message-State: AOJu0YwWNyoO4I9VIadOWVaAVqa6oy+II09WI4fPq/mhbC49Fy34Jsfw Yox4ZaqGvag2dgOjBkAuTaQ= X-Google-Smtp-Source: AGHT+IE4CKi5qzbdonKtH3syFc1QDsHYzWBoZm/gWrZLX2VxjB4N/bBbjITdQQHzwGC8uuJ42MoYbQ== X-Received: by 2002:a19:e04c:0:b0:4fd:fabf:b6ee with SMTP id g12-20020a19e04c000000b004fdfabfb6eemr2561415lfj.9.1695238133794; Wed, 20 Sep 2023 12:28:53 -0700 (PDT) Received: from localhost ([85.140.6.11]) by smtp.gmail.com with ESMTPSA id eo25-20020a056512481900b00500b3157ec8sm2790111lfb.163.2023.09.20.12.28.52 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:53 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 10/18] EDAC/synopsys: Get corrected bit position Date: Wed, 20 Sep 2023 22:26:55 +0300 Message-ID: <20230920192806.29960-11-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122855_683985_D7AD1594 X-CRM114-Status: GOOD ( 19.72 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Since the DQ-bus width is now available in the driver it can be utilized to calculate the exact bit-position corrected by the ECC engine for any Synopsys memory controller setup. A corrected error syndrome is exposed by the ECCSTAT.corrected_bit_num field. A particular erroneous bit position is described in the lookup table [1] which also contains a dependency between the field value and the DQ-bus widths. The syndrome values table basically represents a standard lookup table for the Hamming (64,8)/(32,7)/(16,6) codes (the error-correcting bits placed at the power-of-two positions) except that the zero value means error in the ecc[0] bit. So using the offsets from that table introduce a new inline method snps_get_bitpos() which would provide the actual CE bit-position. The method will be called if a corrected error is detected. [1] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.426-427 Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 28 +++++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index e10778cead63..e08cb30b7a7d 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -301,6 +302,7 @@ struct snps_ddrc_info { * @col: Column number. * @bank: Bank number. * @bankgrp: Bank group number. + * @syndrome: Error syndrome. * @bitpos: Bit position. * @data: Data causing the error. */ @@ -309,6 +311,7 @@ struct snps_ecc_error_info { u32 col; u32 bank; u32 bankgrp; + u32 syndrome; u32 bitpos; u32 data; }; @@ -359,6 +362,27 @@ struct snps_edac_priv { #endif }; +/** + * snps_get_bitpos - Get DQ-bus corrected bit position. + * @syndrome: Error syndrome. + * @dq_width: Controller DQ-bus width. + * + * Return: actual corrected DQ-bus bit position starting from 0. + */ +static inline u32 snps_get_bitpos(u32 syndrome, enum snps_dq_width dq_width) +{ + /* ecc[0] bit */ + if (syndrome == 0) + return BITS_PER_BYTE << dq_width; + + /* ecc[1:x] bit */ + if (is_power_of_2(syndrome)) + return (BITS_PER_BYTE << dq_width) + ilog2(syndrome) + 1; + + /* data[0:y] bit */ + return syndrome - ilog2(syndrome) - 2; +} + /** * snps_get_error_info - Get the current ECC error info. * @priv: DDR memory controller private instance data. @@ -379,7 +403,7 @@ static int snps_get_error_info(struct snps_edac_priv *priv) if (!regval) return 1; - p->ceinfo.bitpos = FIELD_GET(ECC_STAT_BITNUM_MASK, regval); + p->ceinfo.syndrome = FIELD_GET(ECC_STAT_BITNUM_MASK, regval); regval = readl(base + ECC_ERRCNT_OFST); p->ce_cnt = FIELD_GET(ECC_ERRCNT_CECNT_MASK, regval); @@ -387,6 +411,8 @@ static int snps_get_error_info(struct snps_edac_priv *priv) if (!p->ce_cnt) goto ue_err; + p->ceinfo.bitpos = snps_get_bitpos(p->ceinfo.syndrome, priv->info.dq_width); + regval = readl(base + ECC_CEADDR0_OFST); p->ceinfo.row = FIELD_GET(ECC_CEADDR0_ROW_MASK, regval); From patchwork Wed Sep 20 19:26:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393346 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id E274EC04FF5 for ; Wed, 20 Sep 2023 19:29:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=s6aMgfLe570JnmSyXNg7adl8B60Vi21f7wHgwDLz//8=; b=1IkgD3ccAusN+G 8dngQkvhTEyPhs7xG8a3NGSKroIx1uJfVviO3cBnAn1vrAMuatOCd+hRPxNMpuxjSkYx6H+cPpue+ s62tLXyLOmP9lSGMMQLNaJAqC28HT7dnpNeSwo3Jxc6y3zAWVRTC54rYjAxr9XqpimK7olrL/BrRZ 7x1xYMT3s2zDQcoPgJiT9m34oqFym1rPzE6lwwSSzbL/zQV+TtO3B3gwDeGZw33dDHthnqtjV6F/t 7kw8h+jswlU4wVOz31hD0WuLq89/CbqyK/RgJWaryml6JQc7XRvXL5/aiHD8GwaK9tOFZx+9MlmEa 9Y5pfp/k+f/amzlPOTZQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sr-0040Zd-0M; Wed, 20 Sep 2023 19:29:13 +0000 Received: from mail-lj1-x22a.google.com ([2a00:1450:4864:20::22a]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2se-0040Nc-2j for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:29:02 +0000 Received: by mail-lj1-x22a.google.com with SMTP id 38308e7fff4ca-2b9338e4695so2422711fa.2 for ; Wed, 20 Sep 2023 12:28:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238136; x=1695842936; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=1JamuYRg/bmHGo8DyK8kNadLYs1ZIGP2QJGW5LQhCWc=; b=HsEJPUzyFzSUZ6lL1NUF4VdYuxT3MWVUTHDA6gZzzBC4Sv8rey5Q2vU5ev8+JXg4+5 DFMx5K2GE/wHv9c0+EtMqZBjQKjFI9LsMHgCNoRPslIiEiTxVHBgvz1hVuI6rm8gXz8N gByjOagf5QjpONOPDTEch8MIz/jqJ3CZuSOkRHVF11jbCxBfMcbKTUZXWNhMezvlHZr7 lc0XBnX9qtPyXayA77n3mcAvhBqYXBICzRBvyxoJJNWnPAvKLZOeJk/5QbttWXSnwBmj EFOIJLMFEz8tP3S+lz3NKl0dpQgTYCMRdO/O2pG/IJjpAek2D9UMEsidi2wLoERmHY5Z o05w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238136; x=1695842936; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=1JamuYRg/bmHGo8DyK8kNadLYs1ZIGP2QJGW5LQhCWc=; b=XLKfx6+LojCgJmUxWD/UQcMGstBHbGRezOtxu7xDR9kmDr+8teufzqNuJMSsxYlScC /VJkq45hCo+JeOGRqXzRZtYwb6npNL9q8lUvtORSWOB0Ze5JF/jAmiDJQgIu5wwoSpo5 D1GKHtT4tGiUdxhDtveCWATPgDdma2CP+UwLXB9HOCPG4erZK5GEPcTb1CkbOGTXdZPE Rqp6pW7gPr182UICynt7TMMiPnTAwu4T+IMWarE72Icol9+pS7Bu8J08cPL5rQI1Hgcz VU86aXtkvSQCv0nGQ7L6pF/P/VRDnFRGZ9iNhq7TUcsatrrHXIVQ6Hifr0iiqZ3yM28N MsgA== X-Gm-Message-State: AOJu0YxyDZTSpL2GsAbebwiMuFWyRriFhpVQFm65ZCLVwptm0574lD8h E5vig5HUljmiWtndk5JHrTI= X-Google-Smtp-Source: AGHT+IHed65zcIiGfMl4641Tw0aSRdFZiaSvi+nuE8E8l6I8lUHfaSfYYBmvSyduJ4FWc0Z/ibqVGA== X-Received: by 2002:a05:6512:32b8:b0:502:adbc:9b75 with SMTP id q24-20020a05651232b800b00502adbc9b75mr2680835lfe.51.1695238136237; Wed, 20 Sep 2023 12:28:56 -0700 (PDT) Received: from localhost ([85.140.6.205]) by smtp.gmail.com with ESMTPSA id y20-20020ac255b4000000b005009d5aaaedsm2822225lfg.172.2023.09.20.12.28.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:55 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 11/18] EDAC/synopsys: Pass syndrome to EDAC error handler Date: Wed, 20 Sep 2023 22:26:56 +0300 Message-ID: <20230920192806.29960-12-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122901_022262_30D04EF4 X-CRM114-Status: GOOD ( 14.34 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org EDAC MC error handler permits specifying a corrected error syndrome which then will be printed as a part of the generic error message. Since it's available in the error info structure pass it to the edac_mc_handle_error() function. Signed-off-by: Serge Semin --- Changelog v4: - Get syndrome from the ECCSTAT.ecc_corrected_bit_num field rather than from ECCCSYN2. The later CSR in fact contains ECC. --- drivers/edac/synopsys_edac.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index e08cb30b7a7d..fbf1f8af9788 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -474,7 +474,7 @@ static void snps_handle_error(struct mem_ctl_info *mci, struct snps_ecc_status * pinf->bitpos, pinf->data); edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, - p->ce_cnt, 0, 0, 0, 0, 0, -1, + p->ce_cnt, 0, 0, pinf->syndrome, 0, 0, -1, priv->message, ""); } From patchwork Wed Sep 20 19:26:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393345 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 0D588C04FEE for ; Wed, 20 Sep 2023 19:29:39 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Pux/G5mHFb176batV4As2sRHwrF85jBjGvtdVvAoo84=; b=bYMNZ61FIgP5Y0 qVUKwpnAz7v5FL12RHrM0z2QkyS266X51Qc4Rl4YKdQq0lVTMVRbC3HvjBZR7oWJDI4aZjdK/6aaV M3NmA1TmAi5QcqUtPGhy5CbWZ4z2QjgKs2s8B6b4koZssloi0PICDLjsy275rCXaUzZF9b4auNimB vwEb7ooAsNgzQ3bYCCQKSPxfsY1nYSO9eFjM+xJ2ntE+UQk43SLnFSYfWbSZy0yNNmzefaoNHmHqZ g1FAnIAzCyGn2m7STlaLOChM0JaLtVkTIv0W7o4XE7WMpMXTtV/jh9W5aHnZDmrY/MEVd6unBrZgN C7d/7mBQ6EWELM1H41Dg==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sq-0040Yb-0q; Wed, 20 Sep 2023 19:29:12 +0000 Received: from mail-lf1-x12b.google.com ([2a00:1450:4864:20::12b]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2se-0040PO-0k for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:29:02 +0000 Received: by mail-lf1-x12b.google.com with SMTP id 2adb3069b0e04-502e6d632b6so383059e87.0 for ; Wed, 20 Sep 2023 12:29:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238139; x=1695842939; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=uqBb3j7kZv1svEf6sHTFvZChySF0UAHxjiT2Ls2Akek=; b=BqvhFd7UTN96x8bU2+BTijdyd9E9HmdbAiR8II/PTxgBhs457+0CZa1oPD+PmcDoTi 8OnVZPGXiL3fzvYB08+EmAh9bzEKZzNv7CbAywqRSBtsBbzpqxthuKg4lJkYj9lmXu5H 9FY0K6E0oriQ6OQED5Xabotp5FRgI8M/vCtSnXDtUGiS0wgAge1CsFnS1ZKuQHpoOSC9 SG1fRaJNUMqY7H9Kta8AZkuXiN5oH6DW62YKQTF+urALI7+08DnWaQi2L4XxgEXbnH0p zY7E5X6tWrBOY8CdWfV59AfitjBYD828kFG+tsKa40ItnV+hYtKQhPIRRVPW341vLzfS w+Eg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238139; x=1695842939; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=uqBb3j7kZv1svEf6sHTFvZChySF0UAHxjiT2Ls2Akek=; b=KUOI3OWjJiMd1anrv6gQvwBExrx+JWvMllrgB3vYCJJXBBTqjU+7jKHh2jR1FMcNAI J+j8PRCN5gmgQ0Aej+gv4rIj/owiTSnRSNZ2Je5Q6xZ9sx97DkisMEDRzZo+PWSUHenD MQGjEea2QnfX0I3oL4tg0CTqX4A8A3NaASQbVzJYBl7OI9HpAdKK1dGNv1FDJ2YrE2gP draZiVhniEt+AFFjSapEONZSzXxvRtV7bjCXHYor9cKaB6fgcbHa809ob+mi+htvilYq u17xwxDaG+zkil0dC5j6uzxtg1XFExuET72d7qry3hKYF27JHi0xDybu17SHBSENIQ2G A0SQ== X-Gm-Message-State: AOJu0Yy0bRUYN0igmPPD+4ADuHmoK6IdGOnby1Lh/g8I5vETZWyx3oPh m/06YLSyZpQD7FyWTVu+M5E= X-Google-Smtp-Source: AGHT+IGR+wqT1IZCsN8BwpelDunWHlppDt+ckZw/f6gkalBZjyHHw9oeTt8SYJvf8EPjwOvyp2pgkQ== X-Received: by 2002:ac2:4bd1:0:b0:503:3805:e902 with SMTP id o17-20020ac24bd1000000b005033805e902mr3479722lfq.30.1695238138594; Wed, 20 Sep 2023 12:28:58 -0700 (PDT) Received: from localhost ([85.26.234.143]) by smtp.gmail.com with ESMTPSA id d9-20020ac244c9000000b005007da9f823sm524439lfm.168.2023.09.20.12.28.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:28:58 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 12/18] EDAC/synopsys: Read full data+ecc pattern on errors Date: Wed, 20 Sep 2023 22:26:57 +0300 Message-ID: <20230920192806.29960-13-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122900_285688_A5EC4436 X-CRM114-Status: GOOD ( 18.29 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DW uMCTL2 DDRC calculates ECC for the Full DQ-bus word. If non-Full bus width mode is activated the leftover DQ-bits will be padded with zeros, but the ECC code is calculated for the whole width anyway [1]. For some reason the DW uMCTL2 DDRC driver currently doesn't read the whole SDRAM word in if ECC errors happens even though the 64-bits DQ-bus has been supported for a long time. Moreover a Full ECC value is also available in the ECC(C|U)SYN2 register. In a less than 64-bits DQ-bus setups the higher ECC bits are just unused. So update the errors handler to reading the entire data+ecc pattern: extend the data field of the ECC error info structure since it may contain 64-bit data; add a new ECC field there since it's a part of the erroneous data pattern; read the upper 32-bits part of the data pattern only if an ECC error happens and the DDR controller has been configured with the 64-bits DQ bus; read the full ECC value from the ECC(C|U)SYN2 register. The data+ecc couple will be printed as a part of the custom error message passed then to the edac_mc_handle_error() method. Note since the full data+ecc info is now always logged into the EDAC core there is no longer need in the debug print of the Syndrome Registers content. Drop it then. [1] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.424-425 Signed-off-by: Serge Semin --- Changelog v4: - Retrieve ECC too. --- drivers/edac/synopsys_edac.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index fbf1f8af9788..7376a0fc6394 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -305,6 +305,7 @@ struct snps_ddrc_info { * @syndrome: Error syndrome. * @bitpos: Bit position. * @data: Data causing the error. + * @ecc: Data ECC. */ struct snps_ecc_error_info { u32 row; @@ -313,7 +314,8 @@ struct snps_ecc_error_info { u32 bankgrp; u32 syndrome; u32 bitpos; - u32 data; + u64 data; + u32 ecc; }; /** @@ -422,10 +424,10 @@ static int snps_get_error_info(struct snps_edac_priv *priv) p->ceinfo.col = FIELD_GET(ECC_CEADDR1_COL_MASK, regval); p->ceinfo.data = readl(base + ECC_CSYND0_OFST); + if (priv->info.dq_width == SNPS_DQ_64) + p->ceinfo.data |= (u64)readl(base + ECC_CSYND1_OFST) << 32; - edac_dbg(2, "ECCCSYN0: 0x%08X ECCCSYN1: 0x%08X ECCCSYN2: 0x%08X\n", - readl(base + ECC_CSYND0_OFST), readl(base + ECC_CSYND1_OFST), - readl(base + ECC_CSYND2_OFST)); + p->ceinfo.ecc = readl(base + ECC_CSYND2_OFST); ue_err: if (!p->ue_cnt) @@ -440,6 +442,11 @@ static int snps_get_error_info(struct snps_edac_priv *priv) p->ueinfo.col = FIELD_GET(ECC_CEADDR1_COL_MASK, regval); p->ueinfo.data = readl(base + ECC_UESYND0_OFST); + if (priv->info.dq_width == SNPS_DQ_64) + p->ueinfo.data |= (u64)readl(base + ECC_UESYND1_OFST) << 32; + + p->ueinfo.ecc = readl(base + ECC_UESYND2_OFST); + out: spin_lock_irqsave(&priv->reglock, flags); @@ -469,9 +476,9 @@ static void snps_handle_error(struct mem_ctl_info *mci, struct snps_ecc_status * pinf = &p->ceinfo; snprintf(priv->message, SNPS_EDAC_MSG_SIZE, - "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08x", + "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08llx:0x%02x", pinf->row, pinf->col, pinf->bank, pinf->bankgrp, - pinf->bitpos, pinf->data); + pinf->bitpos, pinf->data, pinf->ecc); edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, p->ce_cnt, 0, 0, pinf->syndrome, 0, 0, -1, @@ -482,8 +489,9 @@ static void snps_handle_error(struct mem_ctl_info *mci, struct snps_ecc_status * pinf = &p->ueinfo; snprintf(priv->message, SNPS_EDAC_MSG_SIZE, - "Row %d Col %d Bank %d Bank Group %d", - pinf->row, pinf->col, pinf->bank, pinf->bankgrp); + "Row %d Col %d Bank %d Bank Group %d Data 0x%08llx:0x%02x", + pinf->row, pinf->col, pinf->bank, pinf->bankgrp, + pinf->data, pinf->ecc); edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, p->ue_cnt, 0, 0, 0, 0, 0, -1, From patchwork Wed Sep 20 19:26:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393348 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 74BA9C04FF7 for ; Wed, 20 Sep 2023 19:29:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=HbZBgUIRqxeNOPqwoMBUGK9tPb0jvqlNgeX5QdO4hZw=; b=p2BxZp9QfPdGHH hHCsp7xOHBDi192ZXIgIDwN8I7CTLm/Vp/+XKCG75/D1mdpOoDyhGpGJNYoQe4zBnlIo1R2ki1p0R TOJcbTwF+edpQOr9rjgwd3k4kG0Ni9+LQYX11md2xRxygXBFo5oFYIXhX3mRa47rBR2ALxrugPjTm ibhjb6S8WwN5u4g8tRV+FdZ3Ltuix6RiURLN+g38siDFFNgK0Te4I9kLwhpLX/gM4Ppco4awiCfuy zJ+LHdcuepSSUiXJTcVkTrPmxvbOmEHv2oQZE+kl0c1BnxHlMB2mP6t4mPdFZV0hJ4RylTd+RnHTI DW4PagghhdtOq/dKg/OQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2st-0040bD-01; Wed, 20 Sep 2023 19:29:15 +0000 Received: from mail-lj1-x229.google.com ([2a00:1450:4864:20::229]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2si-0040RO-19 for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:29:08 +0000 Received: by mail-lj1-x229.google.com with SMTP id 38308e7fff4ca-2bffc55af02so2432241fa.2 for ; Wed, 20 Sep 2023 12:29:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238141; x=1695842941; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=PyWc+rqkVGRwEwvNukmSeBhnWN0IDxv9BejmAkmAVHI=; b=OHN7rnrgZ9ShlWbXAZ8F3OoQW0Pz8dbGOkYOWwVIcogBImjDPtK0WOFSEAWc5UC5IL 9viG3+kdqj+bQwWaGzaEqH3mLa33txUXXQQluXrP8HLeMYVRvm+L0oWVnj53ogR3X1uY /VfjmHW6PpTIYQp4NsTU9EtF0dKyDPzlH4wJR/rpFaKuchz7STrB/7nXetH2LchkAPLH mzbMflCjCI0bRbHJiBGfEUiWEUoRx1rNyXwD0rbfDpt7JYRLtFJQ8/YTSifL5PKgHlvu r/gxUEFa5EHLUWvq+yNGNaalHW4cIGCMHjp7U1esDoeABkL/FJWflM5/Xm5N8Gq8ik/h ZhNg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238141; x=1695842941; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=PyWc+rqkVGRwEwvNukmSeBhnWN0IDxv9BejmAkmAVHI=; b=jz80vQC+x0IuLqMR/pFxB1FZnDml42Q4h7pX9maUUpxLzNW4sDgPcXSj5Yah17ea4D IZ0GYaIh7n3LAeTFp3pKVH1Ghf7vTjCVhv0+QT4U6T2Kx0yOlEdwwINwCHhiBH+dwIvP v2ntjW3dYffA6EFNkGnuAdoBFLQA6H3obaMlXuW/4veYWSFOJCoTVceJaT7HkaoeqMe7 z/uYXtSXWs/YeJQMhUYtkFk89HyGYT7n5EPG0cv/iMFYADzajw7JTPGNJ0WdxD39O54t VtZ7zXt7EqIuDwfW39MyQ4rdJwCx8s4hcUG4EdgVcCWziGrr7LtNn4+0ciS3dLwSRs5E CFog== X-Gm-Message-State: AOJu0YwbjmuE8FdosTFmqeYxLcyrFGhCYr6STLtX9I/U3ifMdLO5q/oS xBkr8qgvXa/JDsq6zy3PIkA= X-Google-Smtp-Source: AGHT+IEpTykgcLIH+idrJB48K2nb7IZC4Rc3s6pqC54gb+zNS9FJz8ftJFzd+shjXK6WP/7b6om5tg== X-Received: by 2002:a2e:7410:0:b0:2bf:b133:dd65 with SMTP id p16-20020a2e7410000000b002bfb133dd65mr3011859ljc.38.1695238141089; Wed, 20 Sep 2023 12:29:01 -0700 (PDT) Received: from localhost ([85.140.0.70]) by smtp.gmail.com with ESMTPSA id c3-20020a2e9483000000b002bcdbfe36a1sm3211616ljh.84.2023.09.20.12.29.00 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:29:00 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 13/18] EDAC/synopsys: Introduce System/SDRAM address translation interface Date: Wed, 20 Sep 2023 22:26:58 +0300 Message-ID: <20230920192806.29960-14-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122904_422039_AA74AC62 X-CRM114-Status: GOOD ( 32.34 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Currently the address translation is performed only in the framework of the ECC poison procedures. The available infrastructure is utilized for the device and driver debugging. Meanwhile it would be very useful to know not only the SDRAM address of the runtime ECC errors, but the originating system address accepted on the AXI/AHB ports of the DW uMCTL2 DDR controller. In order to be able to do so the currently available infrastructure needs to be properly updated. First of all move it away from under the EDAC_DEBUG config, since it will be always utilized by the driver. Secondly for the sake of the code simplification split up the translation procedure into the next three stages: 1. System<->Application address translation (just type cast for now). 2. Application<->HIF address translation (DQ-bus width based address shift). 3. HIF<->SDRAM address translation (ADDRMAPx-based mapping). The suggested implementation supports the 1->3 translation only in the same way as it was before this modification (the backward address translation will be added later). Semantically it's the same except the next four aspects: ff-value is used as a marker of the unmapped HIF/SDRAM bits instead of zero-value which in some cases is a valid mapping bit id; DQ-width is used to perform the Application<->HIF address translation instead of the fixed 64-bit DQ-bus width assumption; the HIF/SDRAM address translation procedure searches through the whole dimensions width instead of stopping at the first unmapped bit since in general some of the row/column/bank/etc bits (especially the column bits, like b10) can be left unmapped; the number of supported ranks is extended to four - maximum possible value. Note while at it the code is simplified a bit: encapsulate the mapping table into a dedicated structure (snps_hif_sdram_map); use the FIELD_GET() helper to get ADDRMAP CSR fields; define more descriptive max-value macros. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 750 +++++++++++++++++++++-------------- 1 file changed, 453 insertions(+), 297 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 7376a0fc6394..204d7f1fc7e2 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -153,17 +153,28 @@ #define ECC_CEPOISON_MASK GENMASK(1, 0) #define ECC_UEPOISON_MASK BIT(0) -/* DDRC Device config shifts/masks */ -#define DDR_MAX_ROW_SHIFT 18 -#define DDR_MAX_COL_SHIFT 14 -#define DDR_MAX_BANK_SHIFT 3 -#define DDR_MAX_BANKGRP_SHIFT 2 - -#define ROW_MAX_VAL_MASK 0xF -#define COL_MAX_VAL_MASK 0xF -#define BANK_MAX_VAL_MASK 0x1F -#define BANKGRP_MAX_VAL_MASK 0x1F -#define RANK_MAX_VAL_MASK 0x1F +/* DDRC address mapping parameters */ +#define DDR_ADDRMAP_NREGS 12 + +#define DDR_MAX_ROW_WIDTH 18 +#define DDR_MAX_COL_WIDTH 14 +#define DDR_MAX_BANK_WIDTH 3 +#define DDR_MAX_BANKGRP_WIDTH 2 +#define DDR_MAX_RANK_WIDTH 2 + +#define DDR_ADDRMAP_B0_M15 GENMASK(3, 0) +#define DDR_ADDRMAP_B8_M15 GENMASK(11, 8) +#define DDR_ADDRMAP_B16_M15 GENMASK(19, 16) +#define DDR_ADDRMAP_B24_M15 GENMASK(27, 24) + +#define DDR_ADDRMAP_B0_M31 GENMASK(4, 0) +#define DDR_ADDRMAP_B8_M31 GENMASK(12, 8) +#define DDR_ADDRMAP_B16_M31 GENMASK(20, 16) +#define DDR_ADDRMAP_B24_M31 GENMASK(28, 24) + +#define DDR_ADDRMAP_UNUSED ((u8)-1) +#define DDR_ADDRMAP_MAX_15 DDR_ADDRMAP_B0_M15 +#define DDR_ADDRMAP_MAX_31 DDR_ADDRMAP_B0_M31 #define ROW_B0_BASE 6 #define ROW_B1_BASE 7 @@ -205,6 +216,7 @@ #define BANKGRP_B1_BASE 3 #define RANK_B0_BASE 6 +#define RANK_B1_BASE 7 /* ZynqMP DDR QOS Interrupt register definitions */ #define ZYNQMP_DDR_QOS_UE_MASK BIT(2) @@ -296,6 +308,41 @@ struct snps_ddrc_info { unsigned int ranks; }; +/** + * struct snps_hif_sdram_map - HIF/SDRAM mapping table. + * @row: HIF bit offsets used as row address bits. + * @col: HIF bit offsets used as column address bits. + * @bank: HIF bit offsets used as bank address bits. + * @bankgrp: HIF bit offsets used as bank group address bits. + * @rank: HIF bit offsets used as rank address bits. + * + * For example, row[0] = 6 means row bit #0 is encoded by the HIF + * address bit #6 and vice-versa. + */ +struct snps_hif_sdram_map { + u8 row[DDR_MAX_ROW_WIDTH]; + u8 col[DDR_MAX_COL_WIDTH]; + u8 bank[DDR_MAX_BANK_WIDTH]; + u8 bankgrp[DDR_MAX_BANKGRP_WIDTH]; + u8 rank[DDR_MAX_RANK_WIDTH]; +}; + +/** + * struct snps_sdram_addr - SDRAM address. + * @row: Row number. + * @col: Column number. + * @bank: Bank number. + * @bankgrp: Bank group number. + * @rank: Rank number. + */ +struct snps_sdram_addr { + u16 row; + u16 col; + u8 bank; + u8 bankgrp; + u8 rank; +}; + /** * struct snps_ecc_error_info - ECC error log information. * @row: Row number. @@ -335,20 +382,17 @@ struct snps_ecc_status { /** * struct snps_edac_priv - DDR memory controller private data. * @info: DDR controller config info. + * @hif_sdram_map: HIF/SDRAM mapping table. * @pdev: Platform device. * @baseaddr: Base address of the DDR controller. * @reglock: Concurrent CSRs access lock. * @message: Buffer for framing the event specific info. * @stat: ECC status information. * @poison_addr: Data poison address. - * @row_shift: Bit shifts for row bit. - * @col_shift: Bit shifts for column bit. - * @bank_shift: Bit shifts for bank bit. - * @bankgrp_shift: Bit shifts for bank group bit. - * @rank_shift: Bit shifts for rank bit. */ struct snps_edac_priv { struct snps_ddrc_info info; + struct snps_hif_sdram_map hif_sdram_map; struct platform_device *pdev; void __iomem *baseaddr; spinlock_t reglock; @@ -356,14 +400,97 @@ struct snps_edac_priv { struct snps_ecc_status stat; #ifdef CONFIG_EDAC_DEBUG ulong poison_addr; - u32 row_shift[18]; - u32 col_shift[14]; - u32 bank_shift[3]; - u32 bankgrp_shift[2]; - u32 rank_shift[1]; #endif }; +/** + * snps_map_app_to_hif - Map Application address to HIF address. + * @priv: DDR memory controller private instance data. + * @app: Application address (source). + * @hif: HIF address (destination). + * + * HIF address is used to perform the DQ bus width aligned burst transactions. + * So in order to perform the Application-to-HIF address translation we just + * need to discard the SDRAM-word bits of the Application address. + */ +static void snps_map_app_to_hif(struct snps_edac_priv *priv, + u64 app, u64 *hif) +{ + *hif = app >> priv->info.dq_width; +} + +/** + * snps_map_hif_to_sdram - Map HIF address to SDRAM address. + * @priv: DDR memory controller private instance data. + * @hif: HIF address (source). + * @sdram: SDRAM address (destination). + * + * HIF-SDRAM address mapping is configured with the ADDRMAPx registers, Based + * on the CSRs value the HIF address bits are mapped to the corresponding bits + * in the SDRAM rank/bank/column/row. If an SDRAM address bit is unused (there + * is no any HIF address bit corresponding to it) it will be set to zero. Using + * this fact we can freely set the output SDRAM address with zeros and walk + * over the set HIF address bits only. Similarly the unmapped HIF address bits + * are just ignored. + */ +static void snps_map_hif_to_sdram(struct snps_edac_priv *priv, + u64 hif, struct snps_sdram_addr *sdram) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + int i; + + sdram->row = 0; + for (i = 0; i < DDR_MAX_ROW_WIDTH; i++) { + if (map->row[i] != DDR_ADDRMAP_UNUSED && hif & BIT(map->row[i])) + sdram->row |= BIT(i); + } + + sdram->col = 0; + for (i = 0; i < DDR_MAX_COL_WIDTH; i++) { + if (map->col[i] != DDR_ADDRMAP_UNUSED && hif & BIT(map->col[i])) + sdram->col |= BIT(i); + } + + sdram->bank = 0; + for (i = 0; i < DDR_MAX_BANK_WIDTH; i++) { + if (map->bank[i] != DDR_ADDRMAP_UNUSED && hif & BIT(map->bank[i])) + sdram->bank |= BIT(i); + } + + sdram->bankgrp = 0; + for (i = 0; i < DDR_MAX_BANKGRP_WIDTH; i++) { + if (map->bankgrp[i] != DDR_ADDRMAP_UNUSED && hif & BIT(map->bankgrp[i])) + sdram->bankgrp |= BIT(i); + } + + sdram->rank = 0; + for (i = 0; i < DDR_MAX_RANK_WIDTH; i++) { + if (map->rank[i] != DDR_ADDRMAP_UNUSED && hif & BIT(map->rank[i])) + sdram->rank |= BIT(i); + } +} + +/** + * snps_map_sys_to_sdram - Map System address to SDRAM address. + * @priv: DDR memory controller private instance data. + * @sys: System address (source). + * @sdram: SDRAM address (destination). + * + * Perform a full mapping of the system address (detected on the controller + * ports) to the SDRAM address tuple row/column/bank/etc. + */ +static void snps_map_sys_to_sdram(struct snps_edac_priv *priv, + dma_addr_t sys, struct snps_sdram_addr *sdram) +{ + u64 app, hif; + + app = sys; + + snps_map_app_to_hif(priv, app, &hif); + + snps_map_hif_to_sdram(priv, hif, sdram); +} + /** * snps_get_bitpos - Get DQ-bus corrected bit position. * @syndrome: Error syndrome. @@ -755,6 +882,301 @@ static int snps_get_ddrc_info(struct snps_edac_priv *priv) return init_plat ? init_plat(priv) : 0; } +/** + * snps_get_hif_row_map - Get HIF/SDRAM-row address map. + * @priv: DDR memory controller private instance data. + * @addrmap: Array with ADDRMAP registers value. + * + * SDRAM-row address is defined by the fields in the ADDRMAP[5-7,9-11] + * registers. Those fields value indicate the HIF address bits used to encode + * the DDR row address. + */ +static void snps_get_hif_row_map(struct snps_edac_priv *priv, u32 *addrmap) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + u8 map_row_b2_10; + int i; + + for (i = 0; i < DDR_MAX_ROW_WIDTH; i++) + map->row[i] = DDR_ADDRMAP_UNUSED; + + map->row[0] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[5]) + ROW_B0_BASE; + map->row[1] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[5]) + ROW_B1_BASE; + + map_row_b2_10 = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[5]); + if (map_row_b2_10 != DDR_ADDRMAP_MAX_15) { + for (i = 2; i < 11; i++) + map->row[i] = map_row_b2_10 + i + ROW_B0_BASE; + } else { + map->row[2] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[9]) + ROW_B2_BASE; + map->row[3] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[9]) + ROW_B3_BASE; + map->row[4] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[9]) + ROW_B4_BASE; + map->row[5] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[9]) + ROW_B5_BASE; + map->row[6] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[10]) + ROW_B6_BASE; + map->row[7] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[10]) + ROW_B7_BASE; + map->row[8] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[10]) + ROW_B8_BASE; + map->row[9] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[10]) + ROW_B9_BASE; + map->row[10] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[11]) + ROW_B10_BASE; + } + + map->row[11] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[5]); + map->row[11] = map->row[11] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->row[11] + ROW_B11_BASE; + + map->row[12] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[6]); + map->row[12] = map->row[12] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->row[12] + ROW_B12_BASE; + + map->row[13] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[6]); + map->row[13] = map->row[13] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->row[13] + ROW_B13_BASE; + + map->row[14] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[6]); + map->row[14] = map->row[14] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->row[14] + ROW_B14_BASE; + + map->row[15] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[6]); + map->row[15] = map->row[15] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->row[15] + ROW_B15_BASE; + + if (priv->info.sdram_mode == MEM_DDR4 || priv->info.sdram_mode == MEM_LPDDR4) { + map->row[16] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[7]); + map->row[16] = map->row[16] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->row[16] + ROW_B16_BASE; + + map->row[17] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[7]); + map->row[17] = map->row[17] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->row[17] + ROW_B17_BASE; + } +} + +/** + * snps_get_hif_col_map - Get HIF/SDRAM-column address map. + * @priv: DDR memory controller private instance data. + * @addrmap: Array with ADDRMAP registers value. + * + * SDRAM-column address is defined by the fields in the ADDRMAP[2-4] + * registers. Those fields value indicate the HIF address bits used to encode + * the DDR row address. + */ +static void snps_get_hif_col_map(struct snps_edac_priv *priv, u32 *addrmap) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + int i; + + for (i = 0; i < DDR_MAX_COL_WIDTH; i++) + map->col[i] = DDR_ADDRMAP_UNUSED; + + map->col[0] = 0; + map->col[1] = 1; + map->col[2] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[2]) + COL_B2_BASE; + map->col[3] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[2]) + COL_B3_BASE; + + map->col[4] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[2]); + map->col[4] = map->col[4] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[4] + COL_B4_BASE; + + map->col[5] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[2]); + map->col[5] = map->col[5] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[5] + COL_B5_BASE; + + map->col[6] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[3]); + map->col[6] = map->col[6] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[6] + COL_B6_BASE; + + map->col[7] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[3]); + map->col[7] = map->col[7] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[7] + COL_B7_BASE; + + map->col[8] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[3]); + map->col[8] = map->col[8] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[8] + COL_B8_BASE; + + map->col[9] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); + map->col[9] = map->col[9] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[9] + COL_B9_BASE; + + if (priv->info.dq_mode) { + for (i = 9; i > priv->info.dq_mode; i--) { + map->col[i] = map->col[i - priv->info.dq_mode]; + map->col[i - priv->info.dq_mode] = DDR_ADDRMAP_UNUSED; + } + } + + /* + * Per JEDEC DDR2/3/4/mDDR specification, column address bit 10 is + * reserved for indicating auto-precharge, and hence no source + * address bit can be mapped to col[10]. + * Per JEDEC specification, column address bit 12 is reserved + * for the Burst-chop status, so no source address bit mapping + * for col[12] either. + */ + if (priv->info.dq_mode == SNPS_DQ_FULL) { + if (priv->info.sdram_mode == MEM_LPDDR3) { + map->col[10] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); + map->col[10] = map->col[10] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[10] + COL_B10_BASE; + + map->col[11] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[4]); + map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[11] + COL_B11_BASE; + } else { + map->col[11] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); + map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[11] + COL_B10_BASE; + + map->col[13] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[4]); + map->col[13] = map->col[13] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[13] + COL_B11_BASE; + } + } else if (priv->info.dq_mode == SNPS_DQ_HALF) { + if (priv->info.sdram_mode == MEM_LPDDR3) { + map->col[10] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); + map->col[10] = map->col[10] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[10] + COL_B9_BASE; + + map->col[11] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); + map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[11] + COL_B10_BASE; + } else { + map->col[11] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); + map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[11] + COL_B9_BASE; + + map->col[13] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); + map->col[13] = map->col[13] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[13] + COL_B10_BASE; + } + } else { + if (priv->info.sdram_mode == MEM_LPDDR3) { + map->col[10] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[3]); + map->col[10] = map->col[10] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[10] + COL_B8_BASE; + + map->col[11] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); + map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[11] + COL_B9_BASE; + } else { + map->col[11] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[3]); + map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[11] + COL_B8_BASE; + + map->col[11] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); + map->col[13] = map->col[13] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[13] + COL_B9_BASE; + } + } +} + +/** + * snps_get_hif_bank_map - Get HIF/SDRAM-bank address map. + * @priv: DDR memory controller private instance data. + * @addrmap: Array with ADDRMAP registers value. + * + * SDRAM-bank address is defined by the fields in the ADDRMAP[1] + * register. Those fields value indicate the HIF address bits used to encode + * the DDR bank address. + */ +static void snps_get_hif_bank_map(struct snps_edac_priv *priv, u32 *addrmap) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + int i; + + for (i = 0; i < DDR_MAX_BANK_WIDTH; i++) + map->bank[i] = DDR_ADDRMAP_UNUSED; + + map->bank[0] = FIELD_GET(DDR_ADDRMAP_B0_M31, addrmap[1]) + BANK_B0_BASE; + map->bank[1] = FIELD_GET(DDR_ADDRMAP_B8_M31, addrmap[1]) + BANK_B1_BASE; + + map->bank[2] = FIELD_GET(DDR_ADDRMAP_B16_M31, addrmap[1]); + map->bank[2] = map->bank[2] == DDR_ADDRMAP_MAX_31 ? + DDR_ADDRMAP_UNUSED : map->bank[2] + BANK_B2_BASE; +} + +/** + * snps_get_hif_bankgrp_map - Get HIF/SDRAM-bank group address map. + * @priv: DDR memory controller private instance data. + * @addrmap: Array with ADDRMAP registers value. + * + * SDRAM-bank group address is defined by the fields in the ADDRMAP[8] + * register. Those fields value indicate the HIF address bits used to encode + * the DDR bank group address. + */ +static void snps_get_hif_bankgrp_map(struct snps_edac_priv *priv, u32 *addrmap) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + int i; + + for (i = 0; i < DDR_MAX_BANKGRP_WIDTH; i++) + map->bankgrp[i] = DDR_ADDRMAP_UNUSED; + + /* Bank group signals are available on the DDR4 memory only */ + if (priv->info.sdram_mode != MEM_DDR4) + return; + + map->bankgrp[0] = FIELD_GET(DDR_ADDRMAP_B0_M31, addrmap[8]) + BANKGRP_B0_BASE; + + map->bankgrp[1] = FIELD_GET(DDR_ADDRMAP_B8_M31, addrmap[8]); + map->bankgrp[1] = map->bankgrp[1] == DDR_ADDRMAP_MAX_31 ? + DDR_ADDRMAP_UNUSED : map->bankgrp[1] + BANKGRP_B1_BASE; +} + +/** + * snps_get_hif_rank_map - Get HIF/SDRAM-rank address map. + * @priv: DDR memory controller private instance data. + * @addrmap: Array with ADDRMAP registers value. + * + * SDRAM-rank address is defined by the fields in the ADDRMAP[0] + * register. Those fields value indicate the HIF address bits used to encode + * the DDR rank address. + */ +static void snps_get_hif_rank_map(struct snps_edac_priv *priv, u32 *addrmap) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + int i; + + for (i = 0; i < DDR_MAX_RANK_WIDTH; i++) + map->rank[i] = DDR_ADDRMAP_UNUSED; + + if (priv->info.ranks > 1) { + map->rank[0] = FIELD_GET(DDR_ADDRMAP_B0_M31, addrmap[0]); + map->rank[0] = map->rank[0] == DDR_ADDRMAP_MAX_31 ? + DDR_ADDRMAP_UNUSED : map->rank[0] + RANK_B0_BASE; + } + + if (priv->info.ranks > 2) { + map->rank[1] = FIELD_GET(DDR_ADDRMAP_B8_M31, addrmap[0]); + map->rank[1] = map->rank[1] == DDR_ADDRMAP_MAX_31 ? + DDR_ADDRMAP_UNUSED : map->rank[1] + RANK_B1_BASE; + } +} + +/** + * snps_get_addr_map - Get HIF/SDRAM/etc address map from CSRs. + * @priv: DDR memory controller private instance data. + * + * Parse the controller registers content creating the addresses mapping tables. + * They will be used for the erroneous and poison addresses encode/decode. + */ +static void snps_get_addr_map(struct snps_edac_priv *priv) +{ + u32 regval[DDR_ADDRMAP_NREGS]; + int i; + + for (i = 0; i < DDR_ADDRMAP_NREGS; i++) + regval[i] = readl(priv->baseaddr + DDR_ADDRMAP0_OFST + i * 4); + + snps_get_hif_row_map(priv, regval); + + snps_get_hif_col_map(priv, regval); + + snps_get_hif_bank_map(priv, regval); + + snps_get_hif_bankgrp_map(priv, regval); + + snps_get_hif_rank_map(priv, regval); +} + /** * snps_init_csrows - Initialize the csrow data. * @mci: EDAC memory controller instance. @@ -940,285 +1362,21 @@ DEFINE_SHOW_ATTRIBUTE(snps_ddrc_info); */ static void snps_data_poison_setup(struct snps_edac_priv *priv) { - int col = 0, row = 0, bank = 0, bankgrp = 0, rank = 0, regval; - int index; - ulong hif_addr = 0; - - hif_addr = priv->poison_addr >> 3; - - for (index = 0; index < DDR_MAX_ROW_SHIFT; index++) { - if (priv->row_shift[index]) - row |= (((hif_addr >> priv->row_shift[index]) & - BIT(0)) << index); - else - break; - } - - for (index = 0; index < DDR_MAX_COL_SHIFT; index++) { - if (priv->col_shift[index] || index < 3) - col |= (((hif_addr >> priv->col_shift[index]) & - BIT(0)) << index); - else - break; - } - - for (index = 0; index < DDR_MAX_BANK_SHIFT; index++) { - if (priv->bank_shift[index]) - bank |= (((hif_addr >> priv->bank_shift[index]) & - BIT(0)) << index); - else - break; - } - - for (index = 0; index < DDR_MAX_BANKGRP_SHIFT; index++) { - if (priv->bankgrp_shift[index]) - bankgrp |= (((hif_addr >> priv->bankgrp_shift[index]) - & BIT(0)) << index); - else - break; - } + struct snps_sdram_addr sdram; + u32 regval; - if (priv->rank_shift[0]) - rank = (hif_addr >> priv->rank_shift[0]) & BIT(0); + snps_map_sys_to_sdram(priv, priv->poison_addr, &sdram); - regval = FIELD_PREP(ECC_POISON0_RANK_MASK, rank) | - FIELD_PREP(ECC_POISON0_COL_MASK, col); + regval = FIELD_PREP(ECC_POISON0_RANK_MASK, sdram.rank) | + FIELD_PREP(ECC_POISON0_COL_MASK, sdram.col); writel(regval, priv->baseaddr + ECC_POISON0_OFST); - regval = FIELD_PREP(ECC_POISON1_BANKGRP_MASK, bankgrp) | - FIELD_PREP(ECC_POISON1_BANK_MASK, bank) | - FIELD_PREP(ECC_POISON1_ROW_MASK, row); + regval = FIELD_PREP(ECC_POISON1_BANKGRP_MASK, sdram.bankgrp) | + FIELD_PREP(ECC_POISON1_BANK_MASK, sdram.bank) | + FIELD_PREP(ECC_POISON1_ROW_MASK, sdram.row); writel(regval, priv->baseaddr + ECC_POISON1_OFST); } -static void snps_setup_row_address_map(struct snps_edac_priv *priv, u32 *addrmap) -{ - u32 addrmap_row_b2_10; - int index; - - priv->row_shift[0] = (addrmap[5] & ROW_MAX_VAL_MASK) + ROW_B0_BASE; - priv->row_shift[1] = ((addrmap[5] >> 8) & - ROW_MAX_VAL_MASK) + ROW_B1_BASE; - - addrmap_row_b2_10 = (addrmap[5] >> 16) & ROW_MAX_VAL_MASK; - if (addrmap_row_b2_10 != ROW_MAX_VAL_MASK) { - for (index = 2; index < 11; index++) - priv->row_shift[index] = addrmap_row_b2_10 + - index + ROW_B0_BASE; - - } else { - priv->row_shift[2] = (addrmap[9] & - ROW_MAX_VAL_MASK) + ROW_B2_BASE; - priv->row_shift[3] = ((addrmap[9] >> 8) & - ROW_MAX_VAL_MASK) + ROW_B3_BASE; - priv->row_shift[4] = ((addrmap[9] >> 16) & - ROW_MAX_VAL_MASK) + ROW_B4_BASE; - priv->row_shift[5] = ((addrmap[9] >> 24) & - ROW_MAX_VAL_MASK) + ROW_B5_BASE; - priv->row_shift[6] = (addrmap[10] & - ROW_MAX_VAL_MASK) + ROW_B6_BASE; - priv->row_shift[7] = ((addrmap[10] >> 8) & - ROW_MAX_VAL_MASK) + ROW_B7_BASE; - priv->row_shift[8] = ((addrmap[10] >> 16) & - ROW_MAX_VAL_MASK) + ROW_B8_BASE; - priv->row_shift[9] = ((addrmap[10] >> 24) & - ROW_MAX_VAL_MASK) + ROW_B9_BASE; - priv->row_shift[10] = (addrmap[11] & - ROW_MAX_VAL_MASK) + ROW_B10_BASE; - } - - priv->row_shift[11] = (((addrmap[5] >> 24) & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : (((addrmap[5] >> 24) & - ROW_MAX_VAL_MASK) + ROW_B11_BASE); - priv->row_shift[12] = ((addrmap[6] & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : ((addrmap[6] & - ROW_MAX_VAL_MASK) + ROW_B12_BASE); - priv->row_shift[13] = (((addrmap[6] >> 8) & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : (((addrmap[6] >> 8) & - ROW_MAX_VAL_MASK) + ROW_B13_BASE); - priv->row_shift[14] = (((addrmap[6] >> 16) & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : (((addrmap[6] >> 16) & - ROW_MAX_VAL_MASK) + ROW_B14_BASE); - priv->row_shift[15] = (((addrmap[6] >> 24) & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : (((addrmap[6] >> 24) & - ROW_MAX_VAL_MASK) + ROW_B15_BASE); - - if (priv->info.sdram_mode == MEM_DDR4 || priv->info.sdram_mode == MEM_LPDDR4) { - priv->row_shift[16] = ((addrmap[7] & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : ((addrmap[7] & - ROW_MAX_VAL_MASK) + ROW_B16_BASE); - priv->row_shift[17] = (((addrmap[7] >> 8) & ROW_MAX_VAL_MASK) == - ROW_MAX_VAL_MASK) ? 0 : (((addrmap[7] >> 8) & - ROW_MAX_VAL_MASK) + ROW_B17_BASE); - } -} - -static void snps_setup_column_address_map(struct snps_edac_priv *priv, u32 *addrmap) -{ - int index; - - priv->col_shift[0] = 0; - priv->col_shift[1] = 1; - priv->col_shift[2] = (addrmap[2] & COL_MAX_VAL_MASK) + COL_B2_BASE; - priv->col_shift[3] = ((addrmap[2] >> 8) & - COL_MAX_VAL_MASK) + COL_B3_BASE; - priv->col_shift[4] = (((addrmap[2] >> 16) & COL_MAX_VAL_MASK) == - COL_MAX_VAL_MASK) ? 0 : (((addrmap[2] >> 16) & - COL_MAX_VAL_MASK) + COL_B4_BASE); - priv->col_shift[5] = (((addrmap[2] >> 24) & COL_MAX_VAL_MASK) == - COL_MAX_VAL_MASK) ? 0 : (((addrmap[2] >> 24) & - COL_MAX_VAL_MASK) + COL_B5_BASE); - priv->col_shift[6] = ((addrmap[3] & COL_MAX_VAL_MASK) == - COL_MAX_VAL_MASK) ? 0 : ((addrmap[3] & - COL_MAX_VAL_MASK) + COL_B6_BASE); - priv->col_shift[7] = (((addrmap[3] >> 8) & COL_MAX_VAL_MASK) == - COL_MAX_VAL_MASK) ? 0 : (((addrmap[3] >> 8) & - COL_MAX_VAL_MASK) + COL_B7_BASE); - priv->col_shift[8] = (((addrmap[3] >> 16) & COL_MAX_VAL_MASK) == - COL_MAX_VAL_MASK) ? 0 : (((addrmap[3] >> 16) & - COL_MAX_VAL_MASK) + COL_B8_BASE); - priv->col_shift[9] = (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) == - COL_MAX_VAL_MASK) ? 0 : (((addrmap[3] >> 24) & - COL_MAX_VAL_MASK) + COL_B9_BASE); - if (priv->info.dq_mode == SNPS_DQ_FULL) { - if (priv->info.sdram_mode == MEM_LPDDR3) { - priv->col_shift[10] = ((addrmap[4] & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - ((addrmap[4] & COL_MAX_VAL_MASK) + - COL_B10_BASE); - priv->col_shift[11] = (((addrmap[4] >> 8) & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - (((addrmap[4] >> 8) & COL_MAX_VAL_MASK) + - COL_B11_BASE); - } else { - priv->col_shift[11] = ((addrmap[4] & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - ((addrmap[4] & COL_MAX_VAL_MASK) + - COL_B10_BASE); - priv->col_shift[13] = (((addrmap[4] >> 8) & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - (((addrmap[4] >> 8) & COL_MAX_VAL_MASK) + - COL_B11_BASE); - } - } else if (priv->info.dq_mode == SNPS_DQ_HALF) { - if (priv->info.sdram_mode == MEM_LPDDR3) { - priv->col_shift[10] = (((addrmap[3] >> 24) & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) + - COL_B9_BASE); - priv->col_shift[11] = ((addrmap[4] & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - ((addrmap[4] & COL_MAX_VAL_MASK) + - COL_B10_BASE); - } else { - priv->col_shift[11] = (((addrmap[3] >> 24) & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) + - COL_B9_BASE); - priv->col_shift[13] = ((addrmap[4] & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - ((addrmap[4] & COL_MAX_VAL_MASK) + - COL_B10_BASE); - } - } else { - if (priv->info.sdram_mode == MEM_LPDDR3) { - priv->col_shift[10] = (((addrmap[3] >> 16) & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - (((addrmap[3] >> 16) & COL_MAX_VAL_MASK) + - COL_B8_BASE); - priv->col_shift[11] = (((addrmap[3] >> 24) & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) + - COL_B9_BASE); - } else { - priv->col_shift[11] = (((addrmap[3] >> 16) & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - (((addrmap[3] >> 16) & COL_MAX_VAL_MASK) + - COL_B8_BASE); - priv->col_shift[13] = (((addrmap[3] >> 24) & - COL_MAX_VAL_MASK) == COL_MAX_VAL_MASK) ? 0 : - (((addrmap[3] >> 24) & COL_MAX_VAL_MASK) + - COL_B9_BASE); - } - } - - if (priv->info.dq_mode) { - for (index = 9; index > priv->info.dq_mode; index--) { - priv->col_shift[index] = - priv->col_shift[index - priv->info.dq_mode]; - priv->col_shift[index - priv->info.dq_mode] = 0; - } - } - -} - -static void snps_setup_bank_address_map(struct snps_edac_priv *priv, u32 *addrmap) -{ - priv->bank_shift[0] = (addrmap[1] & BANK_MAX_VAL_MASK) + BANK_B0_BASE; - priv->bank_shift[1] = ((addrmap[1] >> 8) & - BANK_MAX_VAL_MASK) + BANK_B1_BASE; - priv->bank_shift[2] = (((addrmap[1] >> 16) & - BANK_MAX_VAL_MASK) == BANK_MAX_VAL_MASK) ? 0 : - (((addrmap[1] >> 16) & BANK_MAX_VAL_MASK) + - BANK_B2_BASE); - -} - -static void snps_setup_bg_address_map(struct snps_edac_priv *priv, u32 *addrmap) -{ - /* Bank group signals are available on the DDR4 memory only */ - if (priv->info.sdram_mode != MEM_DDR4) - return; - - priv->bankgrp_shift[0] = (addrmap[8] & - BANKGRP_MAX_VAL_MASK) + BANKGRP_B0_BASE; - priv->bankgrp_shift[1] = (((addrmap[8] >> 8) & BANKGRP_MAX_VAL_MASK) == - BANKGRP_MAX_VAL_MASK) ? 0 : (((addrmap[8] >> 8) - & BANKGRP_MAX_VAL_MASK) + BANKGRP_B1_BASE); - -} - -static void snps_setup_rank_address_map(struct snps_edac_priv *priv, u32 *addrmap) -{ - /* Ranks mapping is unavailable for the single-ranked memory */ - if (priv->info.ranks > 1) { - priv->rank_shift[0] = ((addrmap[0] & RANK_MAX_VAL_MASK) == - RANK_MAX_VAL_MASK) ? 0 : ((addrmap[0] & - RANK_MAX_VAL_MASK) + RANK_B0_BASE); - } -} - -/** - * snps_setup_address_map - Set Address Map by querying ADDRMAP registers. - * @priv: DDR memory controller private instance data. - * - * Set Address Map by querying ADDRMAP registers. - * - * Return: none. - */ -static void snps_setup_address_map(struct snps_edac_priv *priv) -{ - u32 addrmap[12]; - int index; - - for (index = 0; index < 12; index++) { - u32 addrmap_offset; - - addrmap_offset = DDR_ADDRMAP0_OFST + (index * 4); - addrmap[index] = readl(priv->baseaddr + addrmap_offset); - } - - snps_setup_row_address_map(priv, addrmap); - - snps_setup_column_address_map(priv, addrmap); - - snps_setup_bank_address_map(priv, addrmap); - - snps_setup_bg_address_map(priv, addrmap); - - snps_setup_rank_address_map(priv, addrmap); -} - static ssize_t snps_inject_data_error_read(struct file *filep, char __user *ubuf, size_t size, loff_t *offp) { @@ -1311,10 +1469,6 @@ SNPS_DEBUGFS_FOPS(snps_inject_data_poison, snps_inject_data_poison_read, */ static void snps_create_debugfs_nodes(struct mem_ctl_info *mci) { - struct snps_edac_priv *priv = mci->pvt_info; - - snps_setup_address_map(priv); - edac_debugfs_create_file("ddrc_info", 0400, mci->debugfs, mci, &snps_ddrc_info_fops); @@ -1354,6 +1508,8 @@ static int snps_mc_probe(struct platform_device *pdev) if (rc) return rc; + snps_get_addr_map(priv); + mci = snps_mc_create(priv); if (IS_ERR(mci)) return PTR_ERR(mci); From patchwork Wed Sep 20 19:26:59 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393347 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id A6389C04FF3 for ; Wed, 20 Sep 2023 19:29:40 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=0de/O+4zI+3/CSmEkxlfNQFCcYskVIRPApPrTdfbiU0=; b=AN/aMbPRw/4muY o5hUtGu5SwYsQQ7PS3ksXYyw1SAxJ2cTvGLSq5NmibXyT4uNq5AzTffsJIsvzkHvfQrPs6LfFe6ey iWp2vnRu9tH/pfXMKy9+ybpz2zE5aYfo25hIQbP1Dy/V+V6sy+WqP0ynIYKvseAaA5j/maCjmzXcK a3gEmC/pzBp4ZoGzZd+spDvd/SssprQ9gEVUuMsmdr2YXz7yh4d3gF+4q6YxZCTQx4yA45prMeMfn AgxB1B2aS90WKDn3XDXOwB7Y1jkTednru3RUZCUuJJSU0a0laSkksCrELewKXzpm0ZmZBTDq9Dtns /uh43y1aQgp8BiUR2f8g==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2ss-0040aQ-0E; Wed, 20 Sep 2023 19:29:14 +0000 Received: from mail-lf1-x12a.google.com ([2a00:1450:4864:20::12a]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sj-0040T7-2b for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:29:07 +0000 Received: by mail-lf1-x12a.google.com with SMTP id 2adb3069b0e04-500cfb168c6so372439e87.2 for ; Wed, 20 Sep 2023 12:29:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238144; x=1695842944; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=c4SLo29ZsWRxmXYEq5pouZGHA4AJYrYqVFNN0wYQp34=; b=b+4nw1W6M92aF/efjAj0M8hSzDQo7xEXQJWf/92UO1RLChABVCw/Utg2hls/lULbbP kvvGtDTzX/RQ/sy4+Rm2VRgZF74yDbxteFvJ+bwpHS1tqlHpGz2eTc9JoLKkEXuqFaJB 2pBk8Jm/oU4+pi4HA7wnSprbg7J/Hc2lFnfwxbGV8TvI5cGsrVMUq5ATnYWCPaPSqUd8 yVh1xmGg57BbOMNGobu2i89rDAVwd1NdpsuCtMYyvEewiDd+djiZKIYWqDMV+MwU4kZh NFuN0RmkaT3VcDOdjpCUQK/AFlk4sqrztwg+nGs97OftN7/bm1MrPBp+cXPneJ2gjL+2 FLPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238144; x=1695842944; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=c4SLo29ZsWRxmXYEq5pouZGHA4AJYrYqVFNN0wYQp34=; b=YFMSeh3LYVwKBuaZAOTuCzn7TD8R5J0tYbxyKUfB6QLGRI6yWCNte+yJL7rAqUpvAG 65SubG8s4/giv3JqwO3MYQumw9STRaLdeAidjZ772cRiwfo+QGSJjiVillJFDq3ObCaH uiXbacXNKy90b2LnS+Yl8ltGjzHjcJA/P2A972QM1jbLWzXWH2BE1trXt/O+GX1YJfnO djNxcjj3BWGtv4a9FEmDvkMfi9IUSXyMvHduUpFZolEWGGCW3FX13/HP4EakTBKukQ3o 3sQerXts9YEroKZdKsTTnWRZbj3XJfsm7WJB7Mczyv+yRqrkoegO2USa/AocqUFq7MQQ 7Awg== X-Gm-Message-State: AOJu0YyT1HSXg55STgb+FDaL2oq5zWl+7LJ+31j0S5WJhPqOGo0JRQ97 wB0htPhT/hbLz+3lFCkta4o= X-Google-Smtp-Source: AGHT+IE61sBSRYaEasfvKoNub8Bh9Qbify371yZ1L9/rJ06IVapYKu9pHIJzUaCgHNrlId97sqmRMA== X-Received: by 2002:ac2:5b1d:0:b0:500:9214:b308 with SMTP id v29-20020ac25b1d000000b005009214b308mr3264451lfn.65.1695238143992; Wed, 20 Sep 2023 12:29:03 -0700 (PDT) Received: from localhost ([85.26.234.143]) by smtp.gmail.com with ESMTPSA id v10-20020ac2560a000000b00501ce5c2e4asm542921lfd.262.2023.09.20.12.29.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:29:03 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 14/18] EDAC/synopsys: Simplify HIF/SDRAM column mapping get procedure Date: Wed, 20 Sep 2023 22:26:59 +0300 Message-ID: <20230920192806.29960-15-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122905_914401_6A18F69B X-CRM114-Status: GOOD ( 20.84 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org What is currently implemented in the driver by means of the multiple if-else-if-else statements in fact is described in the hardware reference manual [1]. It says: 1. All of the column bits shift up 1 bit when only half of the data bus is in use. (In this case, for instance, you need to look at ADDRMAP3.addrmap_col_b6 instead to determine the value of column address bit 7.) 2. All of the column bits shift up 2 bits when only a quarter of the data bus is in use. (In this case, for instance, you need to look at ADDRMAP2.addrmap_col_b5 instead to determine the value of column address bit 7.) 3. In addition to the above, the column bit 10 is reserved for the auto-precharge command in DDR2/3/4/mDDR. So the column bits must be further shifted up 1 bit when one of these DDR protocols is enabled. So taking into account all of the notes above and what the column bit 12 is always reserved, the SDRAM column bits mapping procedure can be significantly simplified: initially read the mapping as if for the LPDDR2/3/4 memory with Full DQ-bus utilized; then shift the column bits up in accordance with the detected DQ-bus width mode. That's it. Simple, canonical and scalable. [1] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.154 Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 83 ++++++++++++------------------------ 1 file changed, 27 insertions(+), 56 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 204d7f1fc7e2..a359018c261c 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -996,8 +996,22 @@ static void snps_get_hif_col_map(struct snps_edac_priv *priv, u32 *addrmap) map->col[9] = map->col[9] == DDR_ADDRMAP_MAX_15 ? DDR_ADDRMAP_UNUSED : map->col[9] + COL_B9_BASE; + map->col[10] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); + map->col[10] = map->col[10] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[10] + COL_B10_BASE; + + map->col[11] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[4]); + map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? + DDR_ADDRMAP_UNUSED : map->col[11] + COL_B11_BASE; + + /* + * In case of the non-Full DQ bus mode the lowest columns are + * unmapped and used by the controller to read the full DQ word + * in multiple cycles (col[0] for the Half bus mode, col[0:1] for + * the Quarter bus mode). + */ if (priv->info.dq_mode) { - for (i = 9; i > priv->info.dq_mode; i--) { + for (i = 11 + priv->info.dq_mode; i >= priv->info.dq_mode; i--) { map->col[i] = map->col[i - priv->info.dq_mode]; map->col[i - priv->info.dq_mode] = DDR_ADDRMAP_UNUSED; } @@ -1007,65 +1021,22 @@ static void snps_get_hif_col_map(struct snps_edac_priv *priv, u32 *addrmap) * Per JEDEC DDR2/3/4/mDDR specification, column address bit 10 is * reserved for indicating auto-precharge, and hence no source * address bit can be mapped to col[10]. + */ + if (priv->info.sdram_mode == MEM_LPDDR || priv->info.sdram_mode == MEM_DDR2 || + priv->info.sdram_mode == MEM_DDR3 || priv->info.sdram_mode == MEM_DDR4) { + for (i = 12 + priv->info.dq_mode; i > 10; i--) { + map->col[i] = map->col[i - 1]; + map->col[i - 1] = DDR_ADDRMAP_UNUSED; + } + } + + /* * Per JEDEC specification, column address bit 12 is reserved * for the Burst-chop status, so no source address bit mapping * for col[12] either. */ - if (priv->info.dq_mode == SNPS_DQ_FULL) { - if (priv->info.sdram_mode == MEM_LPDDR3) { - map->col[10] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); - map->col[10] = map->col[10] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[10] + COL_B10_BASE; - - map->col[11] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[4]); - map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[11] + COL_B11_BASE; - } else { - map->col[11] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); - map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[11] + COL_B10_BASE; - - map->col[13] = FIELD_GET(DDR_ADDRMAP_B8_M15, addrmap[4]); - map->col[13] = map->col[13] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[13] + COL_B11_BASE; - } - } else if (priv->info.dq_mode == SNPS_DQ_HALF) { - if (priv->info.sdram_mode == MEM_LPDDR3) { - map->col[10] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); - map->col[10] = map->col[10] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[10] + COL_B9_BASE; - - map->col[11] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); - map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[11] + COL_B10_BASE; - } else { - map->col[11] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); - map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[11] + COL_B9_BASE; - - map->col[13] = FIELD_GET(DDR_ADDRMAP_B0_M15, addrmap[4]); - map->col[13] = map->col[13] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[13] + COL_B10_BASE; - } - } else { - if (priv->info.sdram_mode == MEM_LPDDR3) { - map->col[10] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[3]); - map->col[10] = map->col[10] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[10] + COL_B8_BASE; - - map->col[11] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); - map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[11] + COL_B9_BASE; - } else { - map->col[11] = FIELD_GET(DDR_ADDRMAP_B16_M15, addrmap[3]); - map->col[11] = map->col[11] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[11] + COL_B8_BASE; - - map->col[11] = FIELD_GET(DDR_ADDRMAP_B24_M15, addrmap[3]); - map->col[13] = map->col[13] == DDR_ADDRMAP_MAX_15 ? - DDR_ADDRMAP_UNUSED : map->col[13] + COL_B9_BASE; - } - } + map->col[13] = map->col[12]; + map->col[12] = DDR_ADDRMAP_UNUSED; } /** From patchwork Wed Sep 20 19:27:00 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393349 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6B353C04FEE for ; Wed, 20 Sep 2023 19:30:16 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=u0qMTJOS7uCMCqBPHJvPAH+Av3bhn6VJFFNV+4xjr2Y=; b=CE8YgjTWop2d+D u7laVHoiVQR3VdkhJMB6ZE+7Vks8mSsdgpVL6ExhOEZWazl1v3fMpMkj6do87Bs/F0XONpze1ahtd vldG7DxIsQW66nsbnQlSDw9TwuruOhpVrw75zUDMbLimZLwWUW5RIOCgbGRWHD86ENCAAi4PZV/p8 /NNiKPEolU3W28XXGRNASSOWVpCrp4rO9iWQx0ek+8DJ/yifFrYW+9xBV7rrA6kCjEbUU2MruhyEl CbAA8w3SVLw9cEqXitsfjdxfiX+iVGCNEIwEBFCsnYLcv3qIvXduKrUo6x9tJRh2McMR577FBvwal CPSD7g7DVh1eE7zVLa2w==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj2tU-00413A-0M; Wed, 20 Sep 2023 19:29:52 +0000 Received: from mail-lf1-x12e.google.com ([2a00:1450:4864:20::12e]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj2sq-0040YJ-2c for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:29:14 +0000 Received: by mail-lf1-x12e.google.com with SMTP id 2adb3069b0e04-50300141a64so449201e87.0 for ; Wed, 20 Sep 2023 12:29:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695238151; x=1695842951; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=ruI/DsrXUPHPt+yo4IDD0wOJzQ+cTuT8XaOYtD4sKFA=; b=EbH75EGrU85IyE4XQqvxvzkblrIUwJDJeWkE3nZM2yIiqca8CBS5LwFnR8QwindVeb h09Vy7HMzKpnOX5UHCUMaN8kzHDx00l5RnAyynHMxlPe+lm+MKxT5s7gFZxnQdJe+uBO rJcITyyOhf/wT+RpgPobquSX3t0aeAW99GuYShW9dyLugJPOm6XlqftfVotrBUjxFJkz Kp8q4o/Z4uzTmX9UQRYQYEWBF4RmqBYRYiJc+CSbqIJNFnVxpoBzYWhtr/siqFUWCm9m KUqcYpOA2Y/VtxNnIs4uvn//ipLm0X+MMAF93d+TOR+GrGiW1V8Hv7CihrPtOsyTC094 pS2w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695238151; x=1695842951; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=ruI/DsrXUPHPt+yo4IDD0wOJzQ+cTuT8XaOYtD4sKFA=; b=uVFViPhJUMdF3fyZWHwb/PcUCeyna2FD1R3qNlWg1BjeW2JvUEcuZzmSPsjgofUWOq QryHka9xcAEMREsSJ9P5EzOLXeaZ4agL1tpiq7C3MC2WETcXoyj5N+P7rHAgXkc8oiZy 6hziUjyYdz+gG78/C5HKvthAt9tWYEYdNhMOM+tYrzGB2rMYZ66menJp2Sqzscv62mXN PezvvHunL2YPDFJ9SRqlizND3IIDBPlKzgqBRmwuJ7b5WlAV3lI0yudbX3Aqz0myDrb7 6BKcyNOffF0E/cHd4mITEuGh2dGGlKl8xx4Vn66B45O2mOWHk6GFpPLnW5C2x5hfrm+G XUXA== X-Gm-Message-State: AOJu0Yx1oolPY+wpaMxrxoKkLhJubhOTzvvxpjuoyPnq5UvRRSoSLo3i yTWw/w88f1AGuYrQ2czf8u8= X-Google-Smtp-Source: AGHT+IGNZjm+wfCwzWQAszOVACunejknYU5hlY3VaoId/Y1DBikEzHrl+fcXMYzw4TlI07AA56CvxQ== X-Received: by 2002:a05:6512:3f1:b0:500:91ac:c0b5 with SMTP id n17-20020a05651203f100b0050091acc0b5mr2883240lfq.30.1695238151186; Wed, 20 Sep 2023 12:29:11 -0700 (PDT) Received: from localhost ([178.176.86.251]) by smtp.gmail.com with ESMTPSA id z23-20020ac25df7000000b004fdde1db756sm2808772lfq.26.2023.09.20.12.29.10 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:29:10 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 15/18] EDAC/synopsys: Add HIF/SDRAM mapping debugfs node Date: Wed, 20 Sep 2023 22:27:00 +0300 Message-ID: <20230920192806.29960-16-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_122912_864951_9527AD81 X-CRM114-Status: GOOD ( 20.04 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Since the available address mapping is about to be utilized for the erroneous SDRAM address decode, before adding such functionality it will be useful to have a way to get an info regarding the most complicated part of the address translation - HIF/SDRAM mapping table just in case something gets wrong in the implemented translation procedures. So add the DebugFS node which on read returns the HIF/SDRAM mapping table in the hexdump-like manner: first line contains the HIF address bit position units, first column contains the HIF address bit position tens, the line and column intersections have the SDRAM dimension (row/column/bank/etc) and a bit position used to encode the corresponding HIF address bit. Note DW uMCTL2 DDRC IP-core doesn't have a parameter to set the HIF address width. So the maximum value (60 bits) of the UMCTL2_A_ADDRW synthesize parameter [1] is utilized as the maximum HIF address width. That parameter defines the controller ports address bus width and in case if the DQ bus width equals to eight bytes defines the HIF address width too. So its upper constraints is fully applicable in this case. [1] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.515 Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 82 ++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index a359018c261c..6b8949c66eef 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -156,6 +156,7 @@ /* DDRC address mapping parameters */ #define DDR_ADDRMAP_NREGS 12 +#define DDR_MAX_HIF_WIDTH 60 #define DDR_MAX_ROW_WIDTH 18 #define DDR_MAX_COL_WIDTH 14 #define DDR_MAX_BANK_WIDTH 3 @@ -1324,6 +1325,84 @@ static int snps_ddrc_info_show(struct seq_file *s, void *data) DEFINE_SHOW_ATTRIBUTE(snps_ddrc_info); +static u8 snps_find_sdram_dim(struct snps_edac_priv *priv, u8 hif, char *dim) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + int i; + + for (i = 0; i < DDR_MAX_ROW_WIDTH; i++) { + if (map->row[i] == hif) { + *dim = 'r'; + return i; + } + } + + for (i = 0; i < DDR_MAX_COL_WIDTH; i++) { + if (map->col[i] == hif) { + *dim = 'c'; + return i; + } + } + + for (i = 0; i < DDR_MAX_BANK_WIDTH; i++) { + if (map->bank[i] == hif) { + *dim = 'b'; + return i; + } + } + + for (i = 0; i < DDR_MAX_BANKGRP_WIDTH; i++) { + if (map->bankgrp[i] == hif) { + *dim = 'g'; + return i; + } + } + + for (i = 0; i < DDR_MAX_RANK_WIDTH; i++) { + if (map->rank[i] == hif) { + *dim = 'a'; + return i; + } + } + + return DDR_ADDRMAP_UNUSED; +} + +static int snps_hif_sdram_map_show(struct seq_file *s, void *data) +{ + struct mem_ctl_info *mci = s->private; + struct snps_edac_priv *priv = mci->pvt_info; + char dim, buf[SNPS_DBGFS_BUF_LEN]; + const int line_len = 10; + u8 bit; + int i; + + seq_printf(s, "%3s", ""); + for (i = 0; i < line_len; i++) + seq_printf(s, " %02d ", i); + + for (i = 0; i < DDR_MAX_HIF_WIDTH; i++) { + if (i % line_len == 0) + seq_printf(s, "\n%02d ", i); + + bit = snps_find_sdram_dim(priv, i, &dim); + + if (bit != DDR_ADDRMAP_UNUSED) + scnprintf(buf, SNPS_DBGFS_BUF_LEN, "%c%hhu", dim, bit); + else + scnprintf(buf, SNPS_DBGFS_BUF_LEN, "--"); + + seq_printf(s, "%3s ", buf); + } + seq_putc(s, '\n'); + + seq_puts(s, "r - row, c - column, b - bank, g - bank group, a - rank\n"); + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(snps_hif_sdram_map); + /** * snps_data_poison_setup - Update poison registers. * @priv: DDR memory controller private instance data. @@ -1443,6 +1522,9 @@ static void snps_create_debugfs_nodes(struct mem_ctl_info *mci) edac_debugfs_create_file("ddrc_info", 0400, mci->debugfs, mci, &snps_ddrc_info_fops); + edac_debugfs_create_file("hif_sdram_map", 0400, mci->debugfs, mci, + &snps_hif_sdram_map_fops); + edac_debugfs_create_file("inject_data_error", 0600, mci->debugfs, mci, &snps_inject_data_error); From patchwork Wed Sep 20 19:46:53 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393353 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 6FA3DC04FF1 for ; Wed, 20 Sep 2023 19:47:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=j70xB6O3wqx3mlW2u84/gpfmPBn+gHAAwnkvMSuOwAw=; b=M+az1LBjSxJZsT gBochDrXBdKrQDdf9/Q7XNQdsKZjGV1sujJ+SD8SnnbZq9x2wfELa0VS8L5KWieTouW4YldRmdBeq uSXtAMVwaJxekHHcG+/9MR2GAy82EZ8CHIk4e8DWmx7m64jWG/u6d6RkDzWs4TAND04Tg+u22vBl+ ksKCGpteJAfKonRxJF4MZwf8ESAAdJxFsXgzmawlM24XH5xz/GyWORilAEW5xQUCdtUVwu5gpsYHc bM3IIZ9hMciMBDiCPO5BOr1j0lwSFVzXftNrWETTh8sJifExEgw23JRcxoYVzRMBoYetMlDn9uumB 96v8vl0h0fdJehE2R+SQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj3AO-00436y-2R; Wed, 20 Sep 2023 19:47:20 +0000 Received: from mail-lf1-x133.google.com ([2a00:1450:4864:20::133]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj3AL-00435k-2B for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:47:19 +0000 Received: by mail-lf1-x133.google.com with SMTP id 2adb3069b0e04-5041bb9ce51so403011e87.1 for ; Wed, 20 Sep 2023 12:47:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695239233; x=1695844033; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=LsdrfYeqptfMWbElOCcxrDUsL4RROO8o0AF8EPJzHss=; b=nSrIwP467lro2PABYandWw2N1DZ8g6NwHiu76filpXtSLGUdv/rzIiYYySH9Xv2ZqB 7XHau9BMqBnH0EaOZOL7GI57s5uxcP3SJsMRx4CY68lgFERMZq0RGI3hXrEncuzaHhKf F/iuBGrki13o1CXkm7EVfh0vBboCK60H7bFPZy4RjS4l5xkTcUjcgz+5N1pHtE6dEjFC hD9V2choVmYyqXctOs/Oe9BqA1z5SNntLmzQNzISlmPVEvlTHbRjCrQ3BvH1ZlKt2r4K tRMgc0vo0ofSpX9hpzvv0xrn9s1cjxzopyHHoodhYGNSV6VTwVjUEyzBPsAS6s4O5TVm sF0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695239233; x=1695844033; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=LsdrfYeqptfMWbElOCcxrDUsL4RROO8o0AF8EPJzHss=; b=BHDZOaTAKjQzKERbP4tDab72T6cWaXEy8BWYpYJpgfzzLk+3FIl6z1+d6jv7+QF+hr bgsdT9Jf4RpioCzlCuIkr6/WwtaAHhxOFLrR7Jjg2iLmUE2azwemyUL0T6kTaWveJ5Lk R8ust+tO3XBEQvaRJcW4HTmuC9bJRiYFSmIBUIfuD/Klp6bmdL/z68sceV3h/ycw7Fra dLPZeXM54raoQ6i4tlTNFDvScULlPktdpV5aiwa5i03Ge4eS4bvSXny5w9QhRz+aNjcD 7fpmpFHHx5DDm8iTUmgdNkcbIAhwpAkiunGdk0eyHpqMQ/bGV5wlnZuJoOtz52cL6E14 smzw== X-Gm-Message-State: AOJu0YzZvPHz/PQloL16GS/cYnYhY1joktqNouPlERad4M2KqehXEVnN d1XPrUogdTSM5Ossqfx1Oko= X-Google-Smtp-Source: AGHT+IF2EECUChEDs96AZIqyG2t+5+DnqORvDjSbDx+3X391xaVVAM70vp3LMepGVoihIJSTPWJe+g== X-Received: by 2002:a2e:96c4:0:b0:2bd:1804:29fa with SMTP id d4-20020a2e96c4000000b002bd180429famr3383605ljj.39.1695239233454; Wed, 20 Sep 2023 12:47:13 -0700 (PDT) Received: from localhost ([178.176.81.142]) by smtp.gmail.com with ESMTPSA id v5-20020a2e7a05000000b002bcda31af28sm3240999ljc.42.2023.09.20.12.47.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:47:12 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 16/18] EDAC/synopsys: Add erroneous page-frame/offset reporting Date: Wed, 20 Sep 2023 22:46:53 +0300 Message-ID: <20230920194656.30879-1-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_124717_890316_9F1938D4 X-CRM114-Status: GOOD ( 21.84 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org A full System/SDRAM address translation interface is now available. Use it to determine the system address causing the ECC faults: add the System-> Application->HIF->SDRAM address translation procedures based on the DW uMCTL2 DDRC DQ-bus config and HIF/SDRAM mapping table retrieved on the device probe stage; for the sake of simplification convert the snps_ecc_error_info structure to containing the snps_sdram_addr structure instance, since the erroneous SDRAM address will now participate in the address translation chain; issue the SDRAM->System address translation before passing the later to the edac_mc_handle_error() method. Note the ECC address rank needs to be retrieved now too in order to determine a correct system address. But the rank won't be passed to the MCI core for now since the MCI device is registered with a single ranked layer 0. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 143 +++++++++++++++++++++++++++++------ 1 file changed, 118 insertions(+), 25 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 6b8949c66eef..5384e93ec58c 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -346,20 +347,14 @@ struct snps_sdram_addr { /** * struct snps_ecc_error_info - ECC error log information. - * @row: Row number. - * @col: Column number. - * @bank: Bank number. - * @bankgrp: Bank group number. + * @sdram: SDRAM address. * @syndrome: Error syndrome. * @bitpos: Bit position. * @data: Data causing the error. * @ecc: Data ECC. */ struct snps_ecc_error_info { - u32 row; - u32 col; - u32 bank; - u32 bankgrp; + struct snps_sdram_addr sdram; u32 syndrome; u32 bitpos; u64 data; @@ -420,6 +415,21 @@ static void snps_map_app_to_hif(struct snps_edac_priv *priv, *hif = app >> priv->info.dq_width; } +/** + * snps_map_hif_to_app - Map HIF address to Application address. + * @priv: DDR memory controller private instance data. + * @hif: HIF address (source). + * @app: Application address (destination). + * + * Backward HIF-to-App translation is just the opposite DQ-width-based + * shift operation. + */ +static void snps_map_hif_to_app(struct snps_edac_priv *priv, + u64 hif, u64 *app) +{ + *app = hif << priv->info.dq_width; +} + /** * snps_map_hif_to_sdram - Map HIF address to SDRAM address. * @priv: DDR memory controller private instance data. @@ -471,6 +481,58 @@ static void snps_map_hif_to_sdram(struct snps_edac_priv *priv, } } +/** + * snps_map_sdram_to_hif - Map SDRAM address to HIF address. + * @priv: DDR memory controller private instance data. + * @sdram: SDRAM address (source). + * @hif: HIF address (destination). + * + * SDRAM-HIF address mapping is similar to the HIF-SDRAM mapping procedure, but + * we'll traverse each SDRAM rank/bank/column/row bit. + * + * Note the unmapped bits of the SDRAM address components will be just + * ignored. So make sure the source address is valid. + */ +static void snps_map_sdram_to_hif(struct snps_edac_priv *priv, + struct snps_sdram_addr *sdram, u64 *hif) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + unsigned long addr; + int i; + + *hif = 0; + + addr = sdram->row; + for_each_set_bit(i, &addr, DDR_MAX_ROW_WIDTH) { + if (map->row[i] != DDR_ADDRMAP_UNUSED) + *hif |= BIT_ULL(map->row[i]); + } + + addr = sdram->col; + for_each_set_bit(i, &addr, DDR_MAX_COL_WIDTH) { + if (map->col[i] != DDR_ADDRMAP_UNUSED) + *hif |= BIT_ULL(map->col[i]); + } + + addr = sdram->bank; + for_each_set_bit(i, &addr, DDR_MAX_BANK_WIDTH) { + if (map->bank[i] != DDR_ADDRMAP_UNUSED) + *hif |= BIT_ULL(map->bank[i]); + } + + addr = sdram->bankgrp; + for_each_set_bit(i, &addr, DDR_MAX_BANKGRP_WIDTH) { + if (map->bankgrp[i] != DDR_ADDRMAP_UNUSED) + *hif |= BIT_ULL(map->bankgrp[i]); + } + + addr = sdram->rank; + for_each_set_bit(i, &addr, DDR_MAX_RANK_WIDTH) { + if (map->rank[i] != DDR_ADDRMAP_UNUSED) + *hif |= BIT_ULL(map->rank[i]); + } +} + /** * snps_map_sys_to_sdram - Map System address to SDRAM address. * @priv: DDR memory controller private instance data. @@ -492,6 +554,27 @@ static void snps_map_sys_to_sdram(struct snps_edac_priv *priv, snps_map_hif_to_sdram(priv, hif, sdram); } +/** + * snps_map_sdram_to_sys - Map SDRAM address to SDRAM address. + * @priv: DDR memory controller private instance data. + * @sys: System address (source). + * @sdram: SDRAM address (destination). + * + * Perform a full mapping of the SDRAM address (row/column/bank/etc) to + * the system address specific to the controller system bus ports. + */ +static void snps_map_sdram_to_sys(struct snps_edac_priv *priv, + struct snps_sdram_addr *sdram, dma_addr_t *sys) +{ + u64 app, hif; + + snps_map_sdram_to_hif(priv, sdram, &hif); + + snps_map_hif_to_app(priv, hif, &app); + + *sys = app; +} + /** * snps_get_bitpos - Get DQ-bus corrected bit position. * @syndrome: Error syndrome. @@ -544,12 +627,13 @@ static int snps_get_error_info(struct snps_edac_priv *priv) p->ceinfo.bitpos = snps_get_bitpos(p->ceinfo.syndrome, priv->info.dq_width); regval = readl(base + ECC_CEADDR0_OFST); - p->ceinfo.row = FIELD_GET(ECC_CEADDR0_ROW_MASK, regval); + p->ceinfo.sdram.rank = FIELD_GET(ECC_CEADDR0_RANK_MASK, regval); + p->ceinfo.sdram.row = FIELD_GET(ECC_CEADDR0_ROW_MASK, regval); regval = readl(base + ECC_CEADDR1_OFST); - p->ceinfo.bank = FIELD_GET(ECC_CEADDR1_BANK_MASK, regval); - p->ceinfo.bankgrp = FIELD_GET(ECC_CEADDR1_BANKGRP_MASK, regval); - p->ceinfo.col = FIELD_GET(ECC_CEADDR1_COL_MASK, regval); + p->ceinfo.sdram.bankgrp = FIELD_GET(ECC_CEADDR1_BANKGRP_MASK, regval); + p->ceinfo.sdram.bank = FIELD_GET(ECC_CEADDR1_BANK_MASK, regval); + p->ceinfo.sdram.col = FIELD_GET(ECC_CEADDR1_COL_MASK, regval); p->ceinfo.data = readl(base + ECC_CSYND0_OFST); if (priv->info.dq_width == SNPS_DQ_64) @@ -562,12 +646,13 @@ static int snps_get_error_info(struct snps_edac_priv *priv) goto out; regval = readl(base + ECC_UEADDR0_OFST); - p->ueinfo.row = FIELD_GET(ECC_CEADDR0_ROW_MASK, regval); + p->ueinfo.sdram.rank = FIELD_GET(ECC_CEADDR0_RANK_MASK, regval); + p->ueinfo.sdram.row = FIELD_GET(ECC_CEADDR0_ROW_MASK, regval); regval = readl(base + ECC_UEADDR1_OFST); - p->ueinfo.bankgrp = FIELD_GET(ECC_CEADDR1_BANKGRP_MASK, regval); - p->ueinfo.bank = FIELD_GET(ECC_CEADDR1_BANK_MASK, regval); - p->ueinfo.col = FIELD_GET(ECC_CEADDR1_COL_MASK, regval); + p->ueinfo.sdram.bankgrp = FIELD_GET(ECC_CEADDR1_BANKGRP_MASK, regval); + p->ueinfo.sdram.bank = FIELD_GET(ECC_CEADDR1_BANK_MASK, regval); + p->ueinfo.sdram.col = FIELD_GET(ECC_CEADDR1_COL_MASK, regval); p->ueinfo.data = readl(base + ECC_UESYND0_OFST); if (priv->info.dq_width == SNPS_DQ_64) @@ -599,31 +684,39 @@ static void snps_handle_error(struct mem_ctl_info *mci, struct snps_ecc_status * { struct snps_edac_priv *priv = mci->pvt_info; struct snps_ecc_error_info *pinf; + dma_addr_t sys; if (p->ce_cnt) { pinf = &p->ceinfo; + snps_map_sdram_to_sys(priv, &pinf->sdram, &sys); + snprintf(priv->message, SNPS_EDAC_MSG_SIZE, - "Row %d Col %d Bank %d Bank Group %d Bit %d Data 0x%08llx:0x%02x", - pinf->row, pinf->col, pinf->bank, pinf->bankgrp, + "Row %hu Col %hu Bank %hhu Bank Group %hhu Rank %hhu Bit %d Data 0x%08llx:0x%02x", + pinf->sdram.row, pinf->sdram.col, pinf->sdram.bank, + pinf->sdram.bankgrp, pinf->sdram.rank, pinf->bitpos, pinf->data, pinf->ecc); - edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, - p->ce_cnt, 0, 0, pinf->syndrome, 0, 0, -1, + edac_mc_handle_error(HW_EVENT_ERR_CORRECTED, mci, p->ce_cnt, + PHYS_PFN(sys), offset_in_page(sys), + pinf->syndrome, 0, 0, -1, priv->message, ""); } if (p->ue_cnt) { pinf = &p->ueinfo; + snps_map_sdram_to_sys(priv, &pinf->sdram, &sys); + snprintf(priv->message, SNPS_EDAC_MSG_SIZE, - "Row %d Col %d Bank %d Bank Group %d Data 0x%08llx:0x%02x", - pinf->row, pinf->col, pinf->bank, pinf->bankgrp, + "Row %hu Col %hu Bank %hhu Bank Group %hhu Rank %hhu Data 0x%08llx:0x%02x", + pinf->sdram.row, pinf->sdram.col, pinf->sdram.bank, + pinf->sdram.bankgrp, pinf->sdram.rank, pinf->data, pinf->ecc); - edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, - p->ue_cnt, 0, 0, 0, 0, 0, -1, - priv->message, ""); + edac_mc_handle_error(HW_EVENT_ERR_UNCORRECTED, mci, p->ue_cnt, + PHYS_PFN(sys), offset_in_page(sys), + 0, 0, 0, -1, priv->message, ""); } memset(p, 0, sizeof(*p)); From patchwork Wed Sep 20 19:50:27 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393365 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 8532EC04FEE for ; Wed, 20 Sep 2023 19:51:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=JKCaZ/AzyWXYp8y4obOrANhJcyQZs9aK6Eg7B0Sj5Vs=; b=qF0iBmmCiFvkmI lizE0hE17X6dBJrs4AAUSJcudWOfVh8BLWwbx8hAKavA7X0xIzglSmWss1KL6ayNzd5Kqltfs9Wnx FDIdVeVaDGkJXKydt3OOipqkFQPHr9GZPcKjbPKLSt4vRCg3APhMBJ3DNMkwGL1YVtTcHBXXK/xdE gs6nSX0gjfC0aCkl7hdu/7FwYrtdbo+MQ4CVztutN/qMyH3+LanDdcj0JAqV0TydIYKy+oC0EHjID aZbIukSbPH4wGfARigqjmmuuS3FAxVBLK84IYeC5Ee5xsiw0qAedP2sji8zqk2ekz2lzk4T/5EiHc uoz7bVIRRm9Pmx0uWOcA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj3Dc-0043Vo-2G; Wed, 20 Sep 2023 19:50:40 +0000 Received: from mail-lf1-x135.google.com ([2a00:1450:4864:20::135]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj3DZ-0043UX-2J for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:50:39 +0000 Received: by mail-lf1-x135.google.com with SMTP id 2adb3069b0e04-5041335fb9cso425028e87.0 for ; Wed, 20 Sep 2023 12:50:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695239434; x=1695844234; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YWC//1VDwpZ/BXBcYZgbJZ5FW8tYbZIyE13JuB9Qg8Y=; b=TiFKLTrg9SuSBfOn5GsWqENNUvelo+zl0FKNhtg6hmYwodlnZR+0z6YDEwcQbKEJNy ap5jZtGP8P95ZNjOVyoB0FtXYlHxO5xY0k39iXbQ690q7E3g2zUCgPUNUOKr9fQljXAZ yYwjyZsSHxtr1R49DqMsQ4/n5IyGB43L4gofc5D639Lu0OIG+2dI+meEA/OpOT0D581T Okkdjt8qgGX92zdl3ikLlIkrA1k8JTFe3AM9SW27ee6BPs6+T/TndsRvJya9gPIpVMPR 3JNnQbuT02aZ8C3rjSAVPa4CyZkhe9FKKoKa/eD4JuCtAptTj/sKEBP0KH+bpqxZGfLz +2+Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695239434; x=1695844234; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YWC//1VDwpZ/BXBcYZgbJZ5FW8tYbZIyE13JuB9Qg8Y=; b=gTVNXNzV/qBFkNtbN+zldsNqf56g9SsoY0Vzypx0+jixE0n1gtp1RHP2BEys1P4LY0 rt0Q2CC5g0BRdCTaYPnkayn1xrFuktpfkFKSamMXz0tJsR3KDaEX/M/J2y1orUJjkkSw Cxo47yIohDQ4lFYDIZ6dzQDPw+1YsVmfz+DU6WUwTEZPzyP1ThY6YbxAjztMXhYDv/e2 9gqrIPy3ukRxuWfT4t02iWN1AX7vFa/GtgjQis/wpTCPkdKH1mIkT+ujWrPyUAfa6WyU 0+oAbyxC4pZohBGK1x8VS+hVk+leyeONic2IAn4RjkcuhvIQGA01A6RSVNPuIV61x1WD az4w== X-Gm-Message-State: AOJu0Yw6gp2izJv44ZVx4kBUC1gE559nM06aBoRHdFoiFb+MjXkB/KVO RV/nBtCgoW5nzws32ICtcNM= X-Google-Smtp-Source: AGHT+IHl9bQqdS2KJb5XtEqsELvseVSuXh9tdWPDur97OTi1SeKgJauyCJnpn1BUq+4/XVCrCREzNw== X-Received: by 2002:a19:5057:0:b0:503:2561:c8b with SMTP id z23-20020a195057000000b0050325610c8bmr2989096lfj.33.1695239433506; Wed, 20 Sep 2023 12:50:33 -0700 (PDT) Received: from localhost ([178.176.81.142]) by smtp.gmail.com with ESMTPSA id w26-20020ac2443a000000b004fe47879d93sm2798613lfl.106.2023.09.20.12.50.32 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:50:33 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 17/18] EDAC/synopsys: Add system address regions support Date: Wed, 20 Sep 2023 22:50:27 +0300 Message-ID: <20230920195030.31437-1-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_125037_757510_99556CC6 X-CRM114-Status: GOOD ( 36.00 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Aside with the Application, HIF and SDRAM address spaces DW uMCTL2 DDR controller supports one more level of the address abstraction. It's the System Address Regions (SARs). By default SARs are disabled by means of the IP-core synthesize parameter UMCTL2_A_NSAR being set to zero. In that case the System and Application address spaces match. But if that parameter is set to a non-zero value (but less than or equal to 4), then it's possible to define up to 4 disjoint memory regions mapping to the SDRAM as consecutive addresses. So if the SARs are available on the particular DW uMCTL2 DDR controller, they need to be taken into account in order to get a correct Physical/DMA address by the SDRAM address and vice-versa. The SAR/Application address mapping support is implemented in the similar way as it has been done for the HIF/SDRAM address translation: read the mapping from the SARBASEn and SARSIZEn CSRs and save it in the System/Application address mapping table as the regions base address, size and offset; use the SARs mapping table to translate the system addresses to the application addresses and vice-versa in the framework of the sys-to-SDRAM and SDRAM-to-sys address translation chain. The described functionality is utilized in the code requiring the address translation: ECC errors detection and ECC data poisoning. Note aside with the number of SARs there is the aUMCTL2_SARMINSIZE IP-core parameter which indicates the SARs minimal block size. Alas it isn't auto-detectable, but it's critical to have a correct mapping table. So the suggested functionality expects it being specified for each particular controller otherwise the system address regions support will be forcibly disabled in the driver. Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 191 ++++++++++++++++++++++++++++++++++- 1 file changed, 188 insertions(+), 3 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index 5384e93ec58c..d67a19fedb3c 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include #include @@ -92,6 +93,10 @@ #define ECC_POISONPAT1_OFST 0x380 #define ECC_POISONPAT2_OFST 0x384 +/* DDR SAR Registers */ +#define DDR_SARBASE0_OFST 0xF04 +#define DDR_SARSIZE0_OFST 0xF08 + /* ZynqMP DDR QOS Registers */ #define ZYNQMP_DDR_QOS_IRQ_STAT_OFST 0x20200 #define ZYNQMP_DDR_QOS_IRQ_EN_OFST 0x20208 @@ -220,6 +225,10 @@ #define RANK_B0_BASE 6 #define RANK_B1_BASE 7 +/* DDRC System Address parameters */ +#define DDR_MAX_NSAR 4 +#define DDR_MIN_SARSIZE SZ_256M + /* ZynqMP DDR QOS Interrupt register definitions */ #define ZYNQMP_DDR_QOS_UE_MASK BIT(2) #define ZYNQMP_DDR_QOS_CE_MASK BIT(1) @@ -310,6 +319,24 @@ struct snps_ddrc_info { unsigned int ranks; }; +/** + * struct snps_sys_app_map - System/Application mapping table. + * @nsar: Number of SARs enabled on the controller (max 4). + * @minsize: Minimal block size (from 256MB to 32GB). + * @sar.base: SAR base address aligned to minsize. + * @sar.size: SAR size aligned to minsize. + * @sar.ofst: SAR address offset. + */ +struct snps_sys_app_map { + u8 nsar; + u64 minsize; + struct { + u64 base; + u64 size; + u64 ofst; + } sar[DDR_MAX_NSAR]; +}; + /** * struct snps_hif_sdram_map - HIF/SDRAM mapping table. * @row: HIF bit offsets used as row address bits. @@ -378,6 +405,7 @@ struct snps_ecc_status { /** * struct snps_edac_priv - DDR memory controller private data. * @info: DDR controller config info. + * @sys_app_map: Sys/App mapping table. * @hif_sdram_map: HIF/SDRAM mapping table. * @pdev: Platform device. * @baseaddr: Base address of the DDR controller. @@ -388,6 +416,7 @@ struct snps_ecc_status { */ struct snps_edac_priv { struct snps_ddrc_info info; + struct snps_sys_app_map sys_app_map; struct snps_hif_sdram_map hif_sdram_map; struct platform_device *pdev; void __iomem *baseaddr; @@ -399,6 +428,77 @@ struct snps_edac_priv { #endif }; +/** + * snps_map_sys_to_app - Map System address to Application address. + * @priv: DDR memory controller private instance data. + * @sys: System address (source). + * @app: Application address (destination). + * + * System address space is used to define disjoint memory regions + * mapped then to the contiguous application memory space: + * + * System Address Space (SAR) <-> Application Address Space + * +------+ +------+ + * | SAR0 |----------------------->| Reg0 | + * +------+ -offset +------+ + * | ... | +----------->| Reg1 | + * +------+ | +------+ + * | SAR1 |-----------+ | ... | + * +------+ + * | ... | + * + * The translation is done by applying the corresponding SAR offset + * to the inbound system address. Note according to the hardware reference + * manual the same mapping is applied to the addresses up to the next + * SAR base address irrespective to the region size. + */ +static void snps_map_sys_to_app(struct snps_edac_priv *priv, + dma_addr_t sys, u64 *app) +{ + struct snps_sys_app_map *map = &priv->sys_app_map; + u64 ofst; + int i; + + ofst = 0; + for (i = 0; i < map->nsar; i++) { + if (sys < map->sar[i].base) + break; + + ofst = map->sar[i].ofst; + } + + *app = sys - ofst; +} + +/** + * snps_map_sys_to_app - Map Application address to System address. + * @priv: DDR memory controller private instance data. + * @app: Application address (source). + * @sys: System address (destination). + * + * Backward App-to-sys translation is easier because the application address + * space is contiguous. So we just need to add the offset corresponding + * to the region the passed address belongs to. Note the later offset is applied + * to all the addresses above the last available region. + */ +static void snps_map_app_to_sys(struct snps_edac_priv *priv, + u64 app, dma_addr_t *sys) +{ + struct snps_sys_app_map *map = &priv->sys_app_map; + u64 ofst, size; + int i; + + ofst = 0; + for (i = 0, size = 0; i < map->nsar; i++) { + ofst = map->sar[i].ofst; + size += map->sar[i].size; + if (app < size) + break; + } + + *sys = app + ofst; +} + /** * snps_map_app_to_hif - Map Application address to HIF address. * @priv: DDR memory controller private instance data. @@ -547,7 +647,7 @@ static void snps_map_sys_to_sdram(struct snps_edac_priv *priv, { u64 app, hif; - app = sys; + snps_map_sys_to_app(priv, sys, &app); snps_map_app_to_hif(priv, app, &hif); @@ -572,7 +672,7 @@ static void snps_map_sdram_to_sys(struct snps_edac_priv *priv, snps_map_hif_to_app(priv, hif, &app); - *sys = app; + snps_map_app_to_sys(priv, app, sys); } /** @@ -976,6 +1076,52 @@ static int snps_get_ddrc_info(struct snps_edac_priv *priv) return init_plat ? init_plat(priv) : 0; } +/** + * snps_get_sys_app_map - Get System/Application address map. + * @priv: DDR memory controller private instance data. + * @sarregs: Array with SAR registers value. + * + * System address regions are defined by the SARBASEn and SARSIZEn registers. + * Controller reference manual requires the base addresses and sizes creating + * a set of ascending non-overlapped regions in order to have a linear + * application address space. Doing otherwise causes unpredictable results. + */ +static void snps_get_sys_app_map(struct snps_edac_priv *priv, u32 *sarregs) +{ + struct snps_sys_app_map *map = &priv->sys_app_map; + int i, ofst; + + /* + * SARs are supposed to be initialized in the ascending non-overlapped + * order: base[i - 1] < base[i] < etc. If that rule is broken for a SAR + * it's considered as no more SARs have been enabled, so the detection + * procedure will halt. Having the very first SAR with zero base + * address only makes sense if there is a consequent SAR. + */ + for (i = 0, ofst = 0; i < DDR_MAX_NSAR; i++) { + map->sar[i].base = sarregs[2 * i] * map->minsize; + if (map->sar[i].base) + map->nsar = i + 1; + else if (i && map->sar[i].base <= map->sar[i - 1].base) + break; + + map->sar[i].size = (sarregs[2 * i + 1] + 1) * map->minsize; + map->sar[i].ofst = map->sar[i].base - ofst; + ofst += map->sar[i].size; + } + + /* + * SAR block size isn't auto-detectable. If one isn't specified for the + * platform there is a good chance to have invalid mapping of the + * detected SARs. So proceed with 1:1 mapping then. + */ + if (!map->minsize && map->nsar) { + edac_printk(KERN_WARNING, EDAC_MC, + "No block size specified. Discard SARs mapping\n"); + map->nsar = 0; + } +} + /** * snps_get_hif_row_map - Get HIF/SDRAM-row address map. * @priv: DDR memory controller private instance data. @@ -1225,9 +1371,14 @@ static void snps_get_hif_rank_map(struct snps_edac_priv *priv, u32 *addrmap) */ static void snps_get_addr_map(struct snps_edac_priv *priv) { - u32 regval[DDR_ADDRMAP_NREGS]; + u32 regval[max(DDR_ADDRMAP_NREGS, 2 * DDR_MAX_NSAR)]; int i; + for (i = 0; i < 2 * DDR_MAX_NSAR; i++) + regval[i] = readl(priv->baseaddr + DDR_SARBASE0_OFST + i * 4); + + snps_get_sys_app_map(priv, regval); + for (i = 0; i < DDR_ADDRMAP_NREGS; i++) regval[i] = readl(priv->baseaddr + DDR_ADDRMAP0_OFST + i * 4); @@ -1418,6 +1569,37 @@ static int snps_ddrc_info_show(struct seq_file *s, void *data) DEFINE_SHOW_ATTRIBUTE(snps_ddrc_info); +static int snps_sys_app_map_show(struct seq_file *s, void *data) +{ + struct mem_ctl_info *mci = s->private; + struct snps_edac_priv *priv = mci->pvt_info; + struct snps_sys_app_map *map = &priv->sys_app_map; + u64 size; + int i; + + if (!map->nsar) { + seq_puts(s, "No SARs detected\n"); + return 0; + } + + seq_printf(s, "%9s %-37s %-18s %-37s\n", + "", "System address", "Offset", "App address"); + + for (i = 0, size = 0; i < map->nsar; i++) { + seq_printf(s, "Region %d: ", i); + seq_printf(s, "0x%016llx-0x%016llx ", map->sar[i].base, + map->sar[i].base + map->sar[i].size - 1); + seq_printf(s, "0x%016llx ", map->sar[i].ofst); + seq_printf(s, "0x%016llx-0x%016llx\n", size, + size + map->sar[i].size - 1); + size += map->sar[i].size; + } + + return 0; +} + +DEFINE_SHOW_ATTRIBUTE(snps_sys_app_map); + static u8 snps_find_sdram_dim(struct snps_edac_priv *priv, u8 hif, char *dim) { struct snps_hif_sdram_map *map = &priv->hif_sdram_map; @@ -1615,6 +1797,9 @@ static void snps_create_debugfs_nodes(struct mem_ctl_info *mci) edac_debugfs_create_file("ddrc_info", 0400, mci->debugfs, mci, &snps_ddrc_info_fops); + edac_debugfs_create_file("sys_app_map", 0400, mci->debugfs, mci, + &snps_sys_app_map_fops); + edac_debugfs_create_file("hif_sdram_map", 0400, mci->debugfs, mci, &snps_hif_sdram_map_fops); From patchwork Wed Sep 20 19:50:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Serge Semin X-Patchwork-Id: 13393366 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id B0FB8C04FEE for ; Wed, 20 Sep 2023 19:51:20 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=rXx/dPW5H/FIJIitycKE6LnnDOM0hPF/97ZFxJkCNmY=; b=aaXZdq86zF+Zbk pc/L7ohFssHp3fpdHZwxeMA22yRD3RBoPxAqHp3YxKExsbti8EBuvyTRpqQ8h0z2o5OMcI9xMlQ8A Ham4W6ITqJRC5QrBMD1s9E2kZ1ROqMxhJVYBZRm4Ie+ol5esYK1SHcdv2/KSX654lSrhdToqRPbtd I/oRuB64bdjhBRvqzQSP6B0SzSmo//ew22dWK35xDG8dVLAri3biQJZ8W28CUWDRoiRK9E/raxq1I Uy0jOxUnbXitkx1t4m2HEGywUI1bOQmvf+iCMEfxN2BeknuUqzg4FTHXkQ7+tx0jSSNja+Zw/wN6E hT8IPT7TRIa4GH6mSaHA==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.96 #2 (Red Hat Linux)) id 1qj3Dv-0043Zt-2j; Wed, 20 Sep 2023 19:50:59 +0000 Received: from mail-lf1-x12d.google.com ([2a00:1450:4864:20::12d]) by bombadil.infradead.org with esmtps (Exim 4.96 #2 (Red Hat Linux)) id 1qj3Dm-0043XA-1Z for linux-arm-kernel@lists.infradead.org; Wed, 20 Sep 2023 19:50:52 +0000 Received: by mail-lf1-x12d.google.com with SMTP id 2adb3069b0e04-50307759b65so444773e87.0 for ; Wed, 20 Sep 2023 12:50:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1695239449; x=1695844249; darn=lists.infradead.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=lLdARslqZ1UHIFAXq/hck+mV3lZPnBFJ5rf0uyQGrzY=; b=GuZviqJg39zm4vwFCmsgDNSYyRHn2Ppmt+XO0T7bo1w9ipt/E57u8R3AcIxfyWQq6u SvZF9KrdKBdUbO68n5Onq0k2pc2Y9K6xvI3bKVhrdanUmKZxNor2diuQkTdU1tvLmfBK T4/TQ55K14dt8ujMHRO9X12ovZgpbvrHXKh3sDLwAKO738eB1iKAR15Qx09DuhSKQQXL O9EqPahHO4MU6ek4YrJocj/P4aLmwF3J7zowzRtZPr0UZT8niow3lf30r+zt8GmO4oVz RPauFt5mChieFuq0hbQOouBokw4daXH6r1sXnHTC21UQ050IwjLtV3DsbuE2gZ4UlovC AUwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1695239449; x=1695844249; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=lLdARslqZ1UHIFAXq/hck+mV3lZPnBFJ5rf0uyQGrzY=; b=eNfgjLTJWrK6+fuu0Z+du4OYAU2WNVfyeRdTyj8/czeJslTLjeY1p8oCAAzT4Ei+dc PJxw2p1ZsedFTQXXoqj54PshFPywbKcMsS5XotmMk4mKmv97SwsGl0MKzo/u/In+xzGb cGATO1nzTzuNTvWuAHrSdAbwYuVB2x9TxpIP0q2ULh7Ghpb1xlxjrI95gqDlzmI28hUi nE8KAfgcymQqnChIZRKWNiPlCA2Ij9HiHmBvyvC2JDphN4s1GcJE1wsCj89olGEaBc3r 2ZPU1V2smAhWYJI480DOZgR0YcSq/49Kas1o4OMUOcIovNEH5jXVL1c46aq1F1CPeX7o YaiQ== X-Gm-Message-State: AOJu0YxYCnL7o8FGdvo7xa+o4F+HOEqr3DrTZau9BhuDvg32/in7x7Kg kg7PA8q3IRZEWabsE8TMc1g= X-Google-Smtp-Source: AGHT+IGD+1vuPJHvvxlM6XsMPzpeFlN+p62CF5i4Vq+sUzIz0nwdXcTwcBohCcB4cG1BpSAoCNN2PQ== X-Received: by 2002:a05:6512:b10:b0:500:9a29:bcb8 with SMTP id w16-20020a0565120b1000b005009a29bcb8mr4023028lfu.4.1695239448598; Wed, 20 Sep 2023 12:50:48 -0700 (PDT) Received: from localhost ([85.140.0.132]) by smtp.gmail.com with ESMTPSA id t26-20020ac2549a000000b004fe09e6d1e7sm2791953lfk.110.2023.09.20.12.50.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 20 Sep 2023 12:50:48 -0700 (PDT) From: Serge Semin To: Michal Simek , Alexander Stein , Borislav Petkov , Tony Luck , James Morse , Mauro Carvalho Chehab , Robert Richter Cc: Serge Semin , Punnaiah Choudary Kalluri , Dinh Nguyen , Arnd Bergmann , Greg Kroah-Hartman , linux-arm-kernel@lists.infradead.org, linux-edac@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH v4 18/18] EDAC/synopsys: Add mapping-based memory size calculation Date: Wed, 20 Sep 2023 22:50:42 +0300 Message-ID: <20230920195045.31466-1-fancer.lancer@gmail.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20230920192806.29960-1-fancer.lancer@gmail.com> References: <20230920192806.29960-1-fancer.lancer@gmail.com> MIME-Version: 1.0 X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20230920_125050_534986_3474F1DE X-CRM114-Status: GOOD ( 22.16 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org Currently the size of the memory attached to the controller is retrieved by means of the si_meminfo() method. It isn't quite correct because the system may have more than one memory controller. There is a better and more portable approach available to find out the attached memory size. Since the full HIF/SDRAM mapping table is available already in the device probe procedure and the DQ-bus width is detected at that stage too, that info can be used to calculate the total memory size accessible over the corresponding DW uMCTL2 DDR controller. It can be done since the controller databook demands that none two SDRAM bits are mapped to the same HIF bit [1] and that the unused SDRAM address bits mapping must be disabled [2]. Note the size calculation procedure takes the ranks mapping into account. That part will be removed after the multi-ranked MC registration is added. [1] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.108 [2] DesignWare® Cores Enhanced Universal DDR Memory Controller (uMCTL2) Databook, Version 3.91a, October 2020, p.109 Signed-off-by: Serge Semin --- drivers/edac/synopsys_edac.c | 66 ++++++++++++++++++++++++++---------- 1 file changed, 49 insertions(+), 17 deletions(-) diff --git a/drivers/edac/synopsys_edac.c b/drivers/edac/synopsys_edac.c index d67a19fedb3c..9a621b7a256d 100644 --- a/drivers/edac/synopsys_edac.c +++ b/drivers/edac/synopsys_edac.c @@ -965,20 +965,6 @@ static inline enum dev_type snps_get_dtype(u32 mstr) return DEV_UNKNOWN; } -/** - * snps_get_memsize - Read the size of the attached memory device. - * - * Return: the memory size in bytes. - */ -static u32 snps_get_memsize(void) -{ - struct sysinfo inf; - - si_meminfo(&inf); - - return inf.totalram * inf.mem_unit; -} - /** * snps_get_mtype - Returns controller memory type. * @mstr: Master CSR value. @@ -1393,6 +1379,51 @@ static void snps_get_addr_map(struct snps_edac_priv *priv) snps_get_hif_rank_map(priv, regval); } +/** + * snps_get_sdram_size - Calculate SDRAM size. + * @priv: DDR memory controller private data. + * + * The total size of the attached memory is calculated based on the HIF/SDRAM + * mapping table. It can be done since the hardware reference manual demands + * that none two SDRAM bits should be mapped to the same HIF bit and that the + * unused SDRAM address bits mapping must be disabled. + * + * Return: the memory size in bytes. + */ +static u64 snps_get_sdram_size(struct snps_edac_priv *priv) +{ + struct snps_hif_sdram_map *map = &priv->hif_sdram_map; + u64 size = 0; + int i; + + for (i = 0; i < DDR_MAX_ROW_WIDTH; i++) { + if (map->row[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + for (i = 0; i < DDR_MAX_COL_WIDTH; i++) { + if (map->col[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + for (i = 0; i < DDR_MAX_BANK_WIDTH; i++) { + if (map->bank[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + for (i = 0; i < DDR_MAX_BANKGRP_WIDTH; i++) { + if (map->bankgrp[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + for (i = 0; i < DDR_MAX_RANK_WIDTH; i++) { + if (map->rank[i] != DDR_ADDRMAP_UNUSED) + size++; + } + + return 1ULL << (size + priv->info.dq_width); +} + /** * snps_init_csrows - Initialize the csrow data. * @mci: EDAC memory controller instance. @@ -1405,7 +1436,8 @@ static void snps_init_csrows(struct mem_ctl_info *mci) struct snps_edac_priv *priv = mci->pvt_info; struct csrow_info *csi; struct dimm_info *dimm; - u32 size, row, width; + u32 row, width; + u64 size; int j; /* Actual SDRAM-word width for which ECC is calculated */ @@ -1413,13 +1445,13 @@ static void snps_init_csrows(struct mem_ctl_info *mci) for (row = 0; row < mci->nr_csrows; row++) { csi = mci->csrows[row]; - size = snps_get_memsize(); + size = snps_get_sdram_size(priv); for (j = 0; j < csi->nr_channels; j++) { dimm = csi->channels[j]->dimm; dimm->edac_mode = EDAC_SECDED; dimm->mtype = priv->info.sdram_mode; - dimm->nr_pages = (size >> PAGE_SHIFT) / csi->nr_channels; + dimm->nr_pages = PHYS_PFN(size) / csi->nr_channels; dimm->grain = width; dimm->dtype = priv->info.dev_cfg; }