From patchwork Mon Dec 12 12:33:10 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Manivannan Sadhasivam X-Patchwork-Id: 32368 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:adf:f944:0:0:0:0:0 with SMTP id q4csp2221043wrr; Mon, 12 Dec 2022 04:47:47 -0800 (PST) X-Google-Smtp-Source: AA0mqf7MGXzRaoZwJV09pPFj0d/lqCwpgcYouq3vKxihZsqzSAqVdLaS7kYZLmRFkhN9liWP9mGf X-Received: by 2002:a17:903:189:b0:18c:1bc5:bd58 with SMTP id z9-20020a170903018900b0018c1bc5bd58mr25271714plg.9.1670849266861; Mon, 12 Dec 2022 04:47:46 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1670849266; cv=none; d=google.com; s=arc-20160816; b=CUNAMm78NIxKLdR6KlLEtIjdx7m9drDi8vHEB6JzRPo/SeHbMy3fvgAFusx+WnpD+9 Z1JyziVKUnu9dRv+P3LMdwhaWo/FWnxo23UPwMUM8eJb48UpdZ/rqm3YIPuaGDwoY9ww g1GUM5NlebLaTzX0/QuoPAUA4mfc5KUJXLccO7+1+bCAYCo0Dfu7On8YkPrZuqKswfte qWZwh5irLIRpQMafQo8z7UVExhh0Sbk2ASENsgDuYrqZ52hX9z7Z+Zua1dE0T06taM/m J2fnVMZFT7HWrmaumlp/hSIBIXZ/YRto9PzHVNloNR6NyC7mVBobb0xBvrV5k687s9mz B2gA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=wh6m1JcK6STNBXORkx35NkjOywagUzfiNFikKvcldrw=; b=GJnRTUtTgEgxlNeYzryY05TeVRHGdGiDVd7msTzM5RYu8YHtoZYOaeA7WwIi8xOzwf XjOz5Ql6zydQ4+wMaZ6dDhCUl5x2LOG/CaGviCAzjgz8rjwM8A/cpwahvsHJJ8y+WCh5 AcByGjqxwhfJnhnln9qdIkL/LP/Yc8yD7Vgs1mXteCYs5SyifCS//OxRku8QcQ5Sz9qR 65a5tKAHNxfx5+yoQM702LCk3G7+jeZ+Y8XSmMnmYGZbcZSO72U4wha79LyJTsBmS5Vg UZR1QhCFq1O33lHCrcbtHAaaiNH6+d4KBsbpS4JeQ5wpyg/FKtLjZ3ys0DcvvddSI0RJ ojkQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tZ4QCiCi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id v9-20020a1709029a0900b00189bdfb4710si8777673plp.280.2022.12.12.04.47.33; Mon, 12 Dec 2022 04:47:46 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tZ4QCiCi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232452AbiLLMgN (ORCPT + 99 others); Mon, 12 Dec 2022 07:36:13 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:44278 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232355AbiLLMfY (ORCPT ); Mon, 12 Dec 2022 07:35:24 -0500 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 26A9362CB for ; Mon, 12 Dec 2022 04:34:43 -0800 (PST) Received: by mail-pl1-x62d.google.com with SMTP id t2so8933343ply.2 for ; Mon, 12 Dec 2022 04:34:43 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; 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=wh6m1JcK6STNBXORkx35NkjOywagUzfiNFikKvcldrw=; b=tZ4QCiCi57c8AXrLrbQadVtl/gJetV5jfdp19zgCctxTIPtWX+IZUFLwMcQMtsf0QU yHsylcO5d6cpIAJO2tUg46uZ/SHRnlBIv9vaOSi1+V8nom1DY0+tlVE3FXvyMmtrpKPU lW7rUro7Q6LJxSMxP3XcYaCH0udFRMSMMRhHgIHQYQFU+9ILBDeSOXHtvKrmBnJjvr0r pQ95hoXf5efGxKJhnis5gINcO7es8xuDQqWTXrCZahMKCzNAS3+zBqSvb957dKlcNqNN VA57RPLouYDk1ntUhmunc9aRDxNuvNb+zL0KNqW6qaHRvKWqgTTvj99IeG1AaZcWjlRN ikRQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; 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=wh6m1JcK6STNBXORkx35NkjOywagUzfiNFikKvcldrw=; b=QUlz/PGmqHxczLqpHLg8xCIj891/bR4A4CkJsAX2Bs7cf3IfMAdz6vXMjAe+bAn+7M MiWNky9C5LF6lh5uCWpZwCG0VnsxqZzjBFGvyr+0Vnoh4JSu5PwQ+0Xh9kAZqsn2Np98 DPBWt9nVVlDayrhjkyLXax6wkH7hzFGsbiCQXoGmkZjuOYRcaEHpg78FXXV/5ujWIAAT xvFHBLbDTgIjtchJ14DY+4OgizNc0BTpb7E67byz4hEnAY/oZKiLe9GaTsppBGuYz2zp YrvTt3Xl1bZQHp2GyHTgiDNHyf0k/+eHHHuMLUtbKQOfOqvp3UPaaI/M7i8KetFYHOcv rv7A== X-Gm-Message-State: ANoB5pkyZATBCtdA+ZhhUWNh0KfzZ2aK5tm+Yn4Oeqif17hjxTyTOBN+ 9199E4keXAO7heT8QmpTRFfL X-Received: by 2002:a17:902:f2ca:b0:189:ac49:fe9d with SMTP id h10-20020a170902f2ca00b00189ac49fe9dmr15186029plc.19.1670848475217; Mon, 12 Dec 2022 04:34:35 -0800 (PST) Received: from localhost.localdomain ([220.158.159.33]) by smtp.gmail.com with ESMTPSA id j14-20020a170902da8e00b00189c93ce5easm6252557plx.166.2022.12.12.04.34.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 12 Dec 2022 04:34:34 -0800 (PST) From: Manivannan Sadhasivam To: andersson@kernel.org, robh+dt@kernel.org, krzysztof.kozlowski+dt@linaro.org, bp@alien8.de, tony.luck@intel.com Cc: quic_saipraka@quicinc.com, konrad.dybcio@linaro.org, linux-arm-msm@vger.kernel.org, linux-kernel@vger.kernel.org, james.morse@arm.com, mchehab@kernel.org, rric@kernel.org, linux-edac@vger.kernel.org, quic_ppareek@quicinc.com, luca.weiss@fairphone.com, Manivannan Sadhasivam , stable@vger.kernel.org Subject: [PATCH v2 12/13] qcom: llcc/edac: Fix the base address used for accessing LLCC banks Date: Mon, 12 Dec 2022 18:03:10 +0530 Message-Id: <20221212123311.146261-13-manivannan.sadhasivam@linaro.org> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20221212123311.146261-1-manivannan.sadhasivam@linaro.org> References: <20221212123311.146261-1-manivannan.sadhasivam@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1752012441081096043?= X-GMAIL-MSGID: =?utf-8?q?1752012441081096043?= The Qualcomm LLCC/EDAC drivers were using a fixed register stride for accessing the (Control and Status Registers) CSRs of each LLCC bank. This stride only works for some SoCs like SDM845 for which driver support was initially added. But the later SoCs use different register stride that vary between the banks with holes in-between. So it is not possible to use a single register stride for accessing the CSRs of each bank. By doing so could result in a crash. For fixing this issue, let's obtain the base address of each LLCC bank from devicetree and get rid of the fixed stride. This also means, we no longer need to rely on reg-names property and get the base addresses using index. First index is LLCC bank 0 and last index is LLCC broadcast. If the SoC supports more than one bank, then those needs to be defined in devicetree for index from 1..N-1. Cc: # 4.20 Fixes: a3134fb09e0b ("drivers: soc: Add LLCC driver") Fixes: 27450653f1db ("drivers: edac: Add EDAC driver support for QCOM SoCs") Reported-by: Parikshit Pareek Signed-off-by: Manivannan Sadhasivam --- drivers/edac/qcom_edac.c | 14 +++--- drivers/soc/qcom/llcc-qcom.c | 72 +++++++++++++++++------------- include/linux/soc/qcom/llcc-qcom.h | 6 +-- 3 files changed, 48 insertions(+), 44 deletions(-) diff --git a/drivers/edac/qcom_edac.c b/drivers/edac/qcom_edac.c index 97a27e42dd61..5be93577fc03 100644 --- a/drivers/edac/qcom_edac.c +++ b/drivers/edac/qcom_edac.c @@ -213,7 +213,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) for (i = 0; i < reg_data.reg_cnt; i++) { synd_reg = reg_data.synd_reg + (i * 4); - ret = regmap_read(drv->regmap, drv->offsets[bank] + synd_reg, + ret = regmap_read(drv->regmaps[bank], synd_reg, &synd_val); if (ret) goto clear; @@ -222,8 +222,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) reg_data.name, i, synd_val); } - ret = regmap_read(drv->regmap, - drv->offsets[bank] + reg_data.count_status_reg, + ret = regmap_read(drv->regmaps[bank], reg_data.count_status_reg, &err_cnt); if (ret) goto clear; @@ -233,8 +232,7 @@ dump_syn_reg_values(struct llcc_drv_data *drv, u32 bank, int err_type) edac_printk(KERN_CRIT, EDAC_LLCC, "%s: Error count: 0x%4x\n", reg_data.name, err_cnt); - ret = regmap_read(drv->regmap, - drv->offsets[bank] + reg_data.ways_status_reg, + ret = regmap_read(drv->regmaps[bank], reg_data.ways_status_reg, &err_ways); if (ret) goto clear; @@ -296,8 +294,7 @@ llcc_ecc_irq_handler(int irq, void *edev_ctl) /* Iterate over the banks and look for Tag RAM or Data RAM errors */ for (i = 0; i < drv->num_banks; i++) { - ret = regmap_read(drv->regmap, - drv->offsets[i] + DRP_INTERRUPT_STATUS, + ret = regmap_read(drv->regmaps[i], DRP_INTERRUPT_STATUS, &drp_error); if (!ret && (drp_error & SB_ECC_ERROR)) { @@ -312,8 +309,7 @@ llcc_ecc_irq_handler(int irq, void *edev_ctl) if (!ret) irq_rc = IRQ_HANDLED; - ret = regmap_read(drv->regmap, - drv->offsets[i] + TRP_INTERRUPT_0_STATUS, + ret = regmap_read(drv->regmaps[i], TRP_INTERRUPT_0_STATUS, &trp_error); if (!ret && (trp_error & SB_ECC_ERROR)) { diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 23ce2f78c4ed..a29f22dad7fa 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -62,8 +62,6 @@ #define LLCC_TRP_WRSC_CACHEABLE_EN 0x21f2c #define LLCC_TRP_ALGO_CFG8 0x21f30 -#define BANK_OFFSET_STRIDE 0x80000 - #define LLCC_VERSION_2_0_0_0 0x02000000 #define LLCC_VERSION_2_1_0_0 0x02010000 #define LLCC_VERSION_4_1_0_0 0x04010000 @@ -898,8 +896,8 @@ static int qcom_llcc_remove(struct platform_device *pdev) return 0; } -static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, - const char *name) +static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, u8 index, + const char *name) { void __iomem *base; struct regmap_config llcc_regmap_config = { @@ -909,7 +907,7 @@ static struct regmap *qcom_llcc_init_mmio(struct platform_device *pdev, .fast_io = true, }; - base = devm_platform_ioremap_resource_byname(pdev, name); + base = devm_platform_ioremap_resource(pdev, index); if (IS_ERR(base)) return ERR_CAST(base); @@ -927,6 +925,7 @@ static int qcom_llcc_probe(struct platform_device *pdev) const struct llcc_slice_config *llcc_cfg; u32 sz; u32 version; + struct regmap *regmap; drv_data = devm_kzalloc(dev, sizeof(*drv_data), GFP_KERNEL); if (!drv_data) { @@ -934,21 +933,51 @@ static int qcom_llcc_probe(struct platform_device *pdev) goto err; } - drv_data->regmap = qcom_llcc_init_mmio(pdev, "llcc_base"); - if (IS_ERR(drv_data->regmap)) { - ret = PTR_ERR(drv_data->regmap); + /* Initialize the first LLCC bank regmap */ + regmap = qcom_llcc_init_mmio(pdev, i, "llcc0_base"); + if (IS_ERR(regmap)) { + ret = PTR_ERR(regmap); goto err; } - drv_data->bcast_regmap = - qcom_llcc_init_mmio(pdev, "llcc_broadcast_base"); + cfg = of_device_get_match_data(&pdev->dev); + + ret = regmap_read(regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], &num_banks); + if (ret) + goto err; + + num_banks &= LLCC_LB_CNT_MASK; + num_banks >>= LLCC_LB_CNT_SHIFT; + drv_data->num_banks = num_banks; + + drv_data->regmaps = devm_kcalloc(dev, num_banks, sizeof(*drv_data->regmaps), GFP_KERNEL); + if (!drv_data->regmaps) { + ret = -ENOMEM; + goto err; + } + + drv_data->regmaps[0] = regmap; + + /* Initialize rest of LLCC bank regmaps */ + for (i = 1; i < num_banks; i++) { + char *base = kasprintf(GFP_KERNEL, "llcc%d_base", i); + + drv_data->regmaps[i] = qcom_llcc_init_mmio(pdev, i, base); + if (IS_ERR(drv_data->regmaps[i])) { + ret = PTR_ERR(drv_data->regmaps[i]); + kfree(base); + goto err; + } + + kfree(base); + } + + drv_data->bcast_regmap = qcom_llcc_init_mmio(pdev, i, "llcc_broadcast_base"); if (IS_ERR(drv_data->bcast_regmap)) { ret = PTR_ERR(drv_data->bcast_regmap); goto err; } - cfg = of_device_get_match_data(&pdev->dev); - /* Extract version of the IP */ ret = regmap_read(drv_data->bcast_regmap, cfg->reg_offset[LLCC_COMMON_HW_INFO], &version); @@ -957,15 +986,6 @@ static int qcom_llcc_probe(struct platform_device *pdev) drv_data->version = version; - ret = regmap_read(drv_data->regmap, cfg->reg_offset[LLCC_COMMON_STATUS0], - &num_banks); - if (ret) - goto err; - - num_banks &= LLCC_LB_CNT_MASK; - num_banks >>= LLCC_LB_CNT_SHIFT; - drv_data->num_banks = num_banks; - llcc_cfg = cfg->sct_data; sz = cfg->size; @@ -973,16 +993,6 @@ static int qcom_llcc_probe(struct platform_device *pdev) if (llcc_cfg[i].slice_id > drv_data->max_slices) drv_data->max_slices = llcc_cfg[i].slice_id; - drv_data->offsets = devm_kcalloc(dev, num_banks, sizeof(u32), - GFP_KERNEL); - if (!drv_data->offsets) { - ret = -ENOMEM; - goto err; - } - - for (i = 0; i < num_banks; i++) - drv_data->offsets[i] = i * BANK_OFFSET_STRIDE; - drv_data->bitmap = devm_bitmap_zalloc(dev, drv_data->max_slices, GFP_KERNEL); if (!drv_data->bitmap) { diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index ad1fd718169d..423220e66026 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -120,7 +120,7 @@ struct llcc_edac_reg_offset { /** * struct llcc_drv_data - Data associated with the llcc driver - * @regmap: regmap associated with the llcc device + * @regmaps: regmaps associated with the llcc device * @bcast_regmap: regmap associated with llcc broadcast offset * @cfg: pointer to the data structure for slice configuration * @edac_reg_offset: Offset of the LLCC EDAC registers @@ -129,12 +129,11 @@ struct llcc_edac_reg_offset { * @max_slices: max slices as read from device tree * @num_banks: Number of llcc banks * @bitmap: Bit map to track the active slice ids - * @offsets: Pointer to the bank offsets array * @ecc_irq: interrupt for llcc cache error detection and reporting * @version: Indicates the LLCC version */ struct llcc_drv_data { - struct regmap *regmap; + struct regmap **regmaps; struct regmap *bcast_regmap; const struct llcc_slice_config *cfg; const struct llcc_edac_reg_offset *edac_reg_offset; @@ -143,7 +142,6 @@ struct llcc_drv_data { u32 max_slices; u32 num_banks; unsigned long *bitmap; - u32 *offsets; int ecc_irq; u32 version; };