From nobody Sat Feb 7 09:34:53 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 25E5446AED8; Thu, 8 Jan 2026 14:22:13 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767882134; cv=none; b=lqeRh3N7Xof3juSiNsEVa5rCyXnNoNkCsYgcjNYewACmIZZ05P+WHtwcag5ngIS0vfV6GKY1rOY0Aw6sk2AvXcD6UCx2e8cMiRl3eYKqJp179n52BJ+3QqltOUan+KujniMKV98u8u25S4WvSDj/NzChLnXn2jauK8JDPxXydoE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767882134; c=relaxed/simple; bh=Ve7yFMC0d18w0wz9TE+6/Y0/0LqqctViUweAKq7ukTU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=QQsw0aV/e7AmULsVC1RR6GMun6dZ+0cWsv3vXEfJbmJgMos67oqWjeHhjQBN1egKBHw1I0CD+DIflxve4fWEOLCodXZ/z6yI/sYjOd+XtPpNJZhJEpcqUsxMqvJWdoBDRCGQiW1zRQGzEJma6CFtMqbr19fCIRnWDezcC/BtO/4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=MVePyoiL; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="MVePyoiL" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 19DE1C16AAE; Thu, 8 Jan 2026 14:22:08 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1767882133; bh=Ve7yFMC0d18w0wz9TE+6/Y0/0LqqctViUweAKq7ukTU=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=MVePyoiL4jzwfdxFngQkEYScGMBR5S6SuagMEvLsrYC/zWvsGNH3aeAoDwoE57QO9 gLZkJ0tSc5fCm4Gyej4FsgyyxwCpl2Hx3Ld4SszAesddubF033ddpLjn4Aox1Aa+RF Dblg6aZyU95wWZKT2pNqDNeJy4SlwGGlbpi64yJGDqnUq50P0efGEpDBWXzGG0r//s a4YgpGeNdIfqrdcKfkMzR24VGP2nBw2Ni+fK4A0wNEvP+831MErPOUvG6RSAhi07bm rXytkQNUCjb59PFiBbknQSCJ1leuK8bhqNMjxlrSXQ7OXYDaoujb2LnSbM84itJI8U zvvujtlF74Fog== From: Konrad Dybcio Date: Thu, 08 Jan 2026 15:21:50 +0100 Subject: [PATCH v3 1/3] soc: qcom: smem: Expose DDR data from SMEM Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260108-topic-smem_dramc-v3-1-6b64df58a017@oss.qualcomm.com> References: <20260108-topic-smem_dramc-v3-0-6b64df58a017@oss.qualcomm.com> In-Reply-To: <20260108-topic-smem_dramc-v3-0-6b64df58a017@oss.qualcomm.com> To: Bjorn Andersson , Konrad Dybcio , Kees Cook , "Gustavo A. R. Silva" , Rob Clark , Sean Paul , Akhil P Oommen , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Marijn Suijten , David Airlie , Simona Vetter Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-hardening@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, Konrad Dybcio X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1767882123; l=15947; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=j4mua/XHOw3V/7YDtS3vdbIot0Y9cW+Px2gdnBswi4c=; b=XG4DKiLC+0G24UmxaPMenBeoKeVCxbr2MzMp6t9FDEqtCCMxDUDvKKKoDd2aYUt8h7dp0rpCm hcU9xW9GVYTBX3DX9YnAuhxSQBKF6aZ6Nq0c2GkPRFM8Jenaouvbn9b X-Developer-Key: i=konrad.dybcio@oss.qualcomm.com; a=ed25519; pk=iclgkYvtl2w05SSXO5EjjSYlhFKsJ+5OSZBjOkQuEms= From: Konrad Dybcio Most modern Qualcomm platforms (>=3D SM8150) expose information about the DDR memory present on the system via SMEM. Details from this information is used in various scenarios, such as multimedia drivers configuring the hardware based on the "Highest Bank address Bit" (hbb), or the list of valid frequencies in validation scenarios... Add support for parsing v3-v7 version of the structs. Unforunately, they are not versioned, so some elbow grease is necessary to determine which one is present. See for reference: ver 3: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/1d1189= 7d2cfcc7b85f28ff74c445018dbbecac7a ver 4: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/f6e9aa= 549260bbc0bdcb156c2b05f48dc5963203 ver 5: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/617d32= 97abe8b1b8dd3de3d1dd69c3961e6f343f ver 5 with 6regions: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-= /commit/d770e009f9bae58d56d926f7490bbfb45af8341f ver 6: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/62659b= 557fdb1551b20fae8073d1d701dfa8a62e ver 7: https://git.codelinaro.org/clo/la/abl/tianocore/edk2/-/commit/734d95= 599c5ebb1ca0d4e1639142e65c590532b7 Reviewed-by: Bjorn Andersson Signed-off-by: Konrad Dybcio Tested-by: Neil Armstrong # on SM8650-HDK --- drivers/soc/qcom/Makefile | 3 +- drivers/soc/qcom/smem.c | 14 +- drivers/soc/qcom/smem.h | 9 + drivers/soc/qcom/smem_dramc.c | 408 ++++++++++++++++++++++++++++++++++++++= ++++ include/linux/soc/qcom/smem.h | 4 + 5 files changed, 436 insertions(+), 2 deletions(-) diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index b7f1d2a57367..798643be3590 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -23,7 +23,8 @@ obj-$(CONFIG_QCOM_RPMH) +=3D qcom_rpmh.o qcom_rpmh-y +=3D rpmh-rsc.o qcom_rpmh-y +=3D rpmh.o obj-$(CONFIG_QCOM_SMD_RPM) +=3D rpm-proc.o smd-rpm.o -obj-$(CONFIG_QCOM_SMEM) +=3D smem.o +qcom_smem-y +=3D smem.o smem_dramc.o +obj-$(CONFIG_QCOM_SMEM) +=3D qcom_smem.o obj-$(CONFIG_QCOM_SMEM_STATE) +=3D smem_state.o CFLAGS_smp2p.o :=3D -I$(src) obj-$(CONFIG_QCOM_SMP2P) +=3D smp2p.o diff --git a/drivers/soc/qcom/smem.c b/drivers/soc/qcom/smem.c index 088b2bbee9e6..a53bf9ed8e92 100644 --- a/drivers/soc/qcom/smem.c +++ b/drivers/soc/qcom/smem.c @@ -4,6 +4,7 @@ * Copyright (c) 2012-2013, The Linux Foundation. All rights reserved. */ =20 +#include #include #include #include @@ -16,6 +17,8 @@ #include #include =20 +#include "smem.h" + /* * The Qualcomm shared memory system is a allocate only heap structure that * consists of one of more memory areas that can be accessed by the proces= sors @@ -284,6 +287,8 @@ struct qcom_smem { struct smem_partition global_partition; struct smem_partition partitions[SMEM_HOST_COUNT]; =20 + struct dentry *debugfs_dir; + unsigned num_regions; struct smem_region regions[] __counted_by(num_regions); }; @@ -1236,17 +1241,24 @@ static int qcom_smem_probe(struct platform_device *= pdev) =20 __smem =3D smem; =20 + smem->debugfs_dir =3D smem_dram_parse(smem->dev); + smem->socinfo =3D platform_device_register_data(&pdev->dev, "qcom-socinfo= ", PLATFORM_DEVID_NONE, NULL, 0); - if (IS_ERR(smem->socinfo)) + if (IS_ERR(smem->socinfo)) { + debugfs_remove_recursive(smem->debugfs_dir); + dev_dbg(&pdev->dev, "failed to register socinfo device\n"); + } =20 return 0; } =20 static void qcom_smem_remove(struct platform_device *pdev) { + debugfs_remove_recursive(__smem->debugfs_dir); + platform_device_unregister(__smem->socinfo); =20 __smem =3D NULL; diff --git a/drivers/soc/qcom/smem.h b/drivers/soc/qcom/smem.h new file mode 100644 index 000000000000..8bf3f606e1ae --- /dev/null +++ b/drivers/soc/qcom/smem.h @@ -0,0 +1,9 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef __QCOM_SMEM_INTERNAL__ +#define __QCOM_SMEM_INTERNAL__ + +#include + +struct dentry *smem_dram_parse(struct device *dev); + +#endif diff --git a/drivers/soc/qcom/smem_dramc.c b/drivers/soc/qcom/smem_dramc.c new file mode 100644 index 000000000000..017bb894a91b --- /dev/null +++ b/drivers/soc/qcom/smem_dramc.c @@ -0,0 +1,408 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (c) 2025 Qualcomm Innovation Center, Inc. All rights reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "smem.h" + +#define SMEM_DDR_INFO_ID 603 + +#define MAX_DDR_FREQ_NUM_V3 13 +#define MAX_DDR_FREQ_NUM_V5 14 + +#define MAX_CHAN_NUM 8 +#define MAX_RANK_NUM 2 + +#define DDR_HBB_MIN 13 +#define DDR_HBB_MAX 19 + +#define MAX_SHUB_ENTRIES 8 + +static struct smem_dram *__dram; + +enum ddr_info_version { + INFO_UNKNOWN, + INFO_V3, + INFO_V3_WITH_14_FREQS, + INFO_V4, + INFO_V5, + INFO_V5_WITH_6_REGIONS, + INFO_V6, /* INFO_V6 seems to only have shipped with 6 DDR regions, unlike= V7 */ + INFO_V7, + INFO_V7_WITH_6_REGIONS, +}; + +struct smem_dram { + unsigned long frequencies[MAX_DDR_FREQ_NUM_V5]; + u32 num_frequencies; + u8 hbb; +}; + +enum ddr_type { + DDR_TYPE_NODDR =3D 0, + DDR_TYPE_LPDDR1 =3D 1, + DDR_TYPE_LPDDR2 =3D 2, + DDR_TYPE_PCDDR2 =3D 3, + DDR_TYPE_PCDDR3 =3D 4, + DDR_TYPE_LPDDR3 =3D 5, + DDR_TYPE_LPDDR4 =3D 6, + DDR_TYPE_LPDDR4X =3D 7, + DDR_TYPE_LPDDR5 =3D 8, + DDR_TYPE_LPDDR5X =3D 9, +}; + +/* The data structures below are NOT __packed on purpose! */ + +/* Structs used across multiple versions */ +struct ddr_part_details { + __le16 revision_id1; + __le16 revision_id2; + __le16 width; + __le16 density; +}; + +struct ddr_freq_table { + u32 freq_khz; + u8 enabled; +}; + +/* V3 */ +struct ddr_freq_plan_v3 { + struct ddr_freq_table ddr_freq[MAX_DDR_FREQ_NUM_V3]; /* NOTE: some have 1= 4 like v5 */ + u8 num_ddr_freqs; + phys_addr_t clk_period_address; +}; + +struct ddr_details_v3 { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM]; + struct ddr_freq_plan_v3 ddr_freq_tbl; + u8 num_channels; +}; + +/* V4 */ +struct ddr_details_v4 { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM]; + struct ddr_freq_plan_v3 ddr_freq_tbl; + u8 num_channels; + u8 num_ranks[MAX_CHAN_NUM]; + u8 highest_bank_addr_bit[MAX_CHAN_NUM][MAX_RANK_NUM]; +}; + +/* V5 */ +struct shub_freq_table { + u8 enable; + u32 freq_khz; +}; + +struct shub_freq_plan_entry { + u8 num_shub_freqs; + struct shub_freq_table shub_freq[MAX_SHUB_ENTRIES]; +}; + +struct ddr_xbl2quantum_smem_data { + phys_addr_t ssr_cookie_addr; + u32 reserved[10]; +}; + +struct ddr_freq_plan_v5 { + struct ddr_freq_table ddr_freq[MAX_DDR_FREQ_NUM_V5]; + u8 num_ddr_freqs; + phys_addr_t clk_period_address; + u32 max_nom_ddr_freq; +}; + +struct ddr_region_v5 { + u64 start_address; + u64 size; + u64 mem_controller_address; + u32 granule_size; /* MiB */ + u8 ddr_rank; +#define DDR_RANK_0 BIT(0) +#define DDR_RANK_1 BIT(1) + u8 segments_start_index; + u64 segments_start_offset; +}; + +struct ddr_regions_v5 { + u32 ddr_region_num; /* We expect this to always be 4 or 6 */ + u64 ddr_rank0_size; + u64 ddr_rank1_size; + u64 ddr_cs0_start_addr; + u64 ddr_cs1_start_addr; + u32 highest_bank_addr_bit; + struct ddr_region_v5 ddr_region[] __counted_by(ddr_region_num); +}; + +struct ddr_details_v5 { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM]; + struct ddr_freq_plan_v5 ddr_freq_tbl; + u8 num_channels; + u8 _padding; + struct ddr_regions_v5 ddr_regions; +}; + +/* V6 */ +struct ddr_misc_info_v6 { + u32 dsf_version; + u32 reserved[10]; +}; + +/* V7 */ +struct ddr_details_v7 { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM]; + struct ddr_freq_plan_v5 ddr_freq_tbl; + u8 num_channels; + u8 sct_config; + struct ddr_regions_v5 ddr_regions; +}; + +/** + * qcom_smem_dram_get_hbb(): Get the Highest bank address bit + * + * Context: Check qcom_smem_is_available() before calling this function. + * Because __dram * is initialized by smem_dram_parse(), which is in turn + * called from * qcom_smem_probe(), __dram will only be NULL if the data + * couldn't have been found/interpreted correctly. + * + * Return: 0 on success, -ENODATA on failure. + */ +int qcom_smem_dram_get_hbb(void) +{ + int hbb; + + if (!__dram) + return -ENODATA; + + hbb =3D __dram->hbb; + if (hbb =3D=3D 0) + return -ENODATA; + else if (hbb < DDR_HBB_MIN || hbb > DDR_HBB_MAX) + return -EINVAL; + + return hbb; +} +EXPORT_SYMBOL_GPL(qcom_smem_dram_get_hbb); + +static void smem_dram_parse_v3_data(struct smem_dram *dram, void *data, bo= ol additional_freq_entry) +{ + /* This may be 13 or 14 */ + int num_freq_entries =3D MAX_DDR_FREQ_NUM_V3; + struct ddr_details_v3 *details =3D data; + + if (additional_freq_entry) + num_freq_entries++; + + for (int i =3D 0; i < num_freq_entries; i++) { + struct ddr_freq_table *freq_entry =3D &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) + dram->frequencies[dram->num_frequencies++] =3D 1000 * freq_entry->freq_= khz; + } +} + +static void smem_dram_parse_v4_data(struct smem_dram *dram, void *data) +{ + struct ddr_details_v4 *details =3D data; + + /* Rank 0 channel 0 entry holds the correct value */ + dram->hbb =3D details->highest_bank_addr_bit[0][0]; + + for (int i =3D 0; i < MAX_DDR_FREQ_NUM_V3; i++) { + struct ddr_freq_table *freq_entry =3D &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) + dram->frequencies[dram->num_frequencies++] =3D 1000 * freq_entry->freq_= khz; + } +} + +static void smem_dram_parse_v5_data(struct smem_dram *dram, void *data) +{ + struct ddr_details_v5 *details =3D data; + struct ddr_regions_v5 *region =3D &details->ddr_regions; + + dram->hbb =3D region[0].highest_bank_addr_bit; + + for (int i =3D 0; i < MAX_DDR_FREQ_NUM_V5; i++) { + struct ddr_freq_table *freq_entry =3D &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) + dram->frequencies[dram->num_frequencies++] =3D 1000 * freq_entry->freq_= khz; + } +} + +static void smem_dram_parse_v7_data(struct smem_dram *dram, void *data) +{ + struct ddr_details_v7 *details =3D data; + struct ddr_regions_v5 *region =3D &details->ddr_regions; + + dram->hbb =3D region[0].highest_bank_addr_bit; + + for (int i =3D 0; i < MAX_DDR_FREQ_NUM_V5; i++) { + struct ddr_freq_table *freq_entry =3D &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) + dram->frequencies[dram->num_frequencies++] =3D 1000 * freq_entry->freq_= khz; + } +} + +/* The structure contains no version field, so we have to perform some gue= sswork.. */ +static int smem_dram_infer_struct_version(size_t size) +{ + /* Some early versions provided less bytes of less useful data */ + if (size < sizeof(struct ddr_details_v3)) + return -EINVAL; + + if (size =3D=3D sizeof(struct ddr_details_v3)) + return INFO_V3; + + if (size =3D=3D sizeof(struct ddr_details_v3) + + sizeof(struct ddr_freq_table)) + return INFO_V3_WITH_14_FREQS; + + if (size =3D=3D sizeof(struct ddr_details_v4)) + return INFO_V4; + + if (size =3D=3D sizeof(struct ddr_details_v5) + + 4 * sizeof(struct ddr_region_v5)) + return INFO_V5; + + if (size =3D=3D sizeof(struct ddr_details_v5) + + 4 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_xbl2quantum_smem_data) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V5; + + if (size =3D=3D sizeof(struct ddr_details_v5) + + 6 * sizeof(struct ddr_region_v5)) + return INFO_V5_WITH_6_REGIONS; + + if (size =3D=3D sizeof(struct ddr_details_v5) + + 6 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_xbl2quantum_smem_data) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V5_WITH_6_REGIONS; + + if (size =3D=3D sizeof(struct ddr_details_v5) + + 6 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_misc_info_v6) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V6; + + if (size =3D=3D sizeof(struct ddr_details_v7) + + 4 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_misc_info_v6) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V7; + + if (size =3D=3D sizeof(struct ddr_details_v7) + + 6 * sizeof(struct ddr_region_v5) + + sizeof(struct ddr_misc_info_v6) + + sizeof(struct shub_freq_plan_entry)) + return INFO_V7_WITH_6_REGIONS; + + return INFO_UNKNOWN; +} + +static int smem_dram_frequencies_show(struct seq_file *s, void *unused) +{ + struct smem_dram *dram =3D s->private; + + for (int i =3D 0; i < dram->num_frequencies; i++) + seq_printf(s, "%lu\n", dram->frequencies[i]); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(smem_dram_frequencies); + +static int smem_hbb_show(struct seq_file *s, void *unused) +{ + struct smem_dram *dram =3D s->private; + + if (!dram->hbb) + return -EINVAL; + + seq_printf(s, "%d\n", dram->hbb); + + return 0; +} +DEFINE_SHOW_ATTRIBUTE(smem_hbb); + +struct dentry *smem_dram_parse(struct device *dev) +{ + struct dentry *debugfs_dir; + enum ddr_info_version ver; + struct smem_dram *dram; + size_t actual_size; + void *data =3D NULL; + + /* No need to check qcom_smem_is_available(), this func is called by the = SMEM driver */ + data =3D qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_DDR_INFO_ID, &actual_size= ); + if (IS_ERR_OR_NULL(data)) + return ERR_PTR(-ENODATA); + + ver =3D smem_dram_infer_struct_version(actual_size); + if (ver < 0) { + /* Some SoCs don't provide data that's useful for us */ + return ERR_PTR(-ENODATA); + } else if (ver =3D=3D INFO_UNKNOWN) { + /* In other cases, we may not have added support for a newer struct revi= sion */ + pr_err("Found an unknown type of DRAM info struct (size =3D %zu)\n", act= ual_size); + return ERR_PTR(-EINVAL); + } + + dram =3D devm_kzalloc(dev, sizeof(*dram), GFP_KERNEL); + if (!dram) + return ERR_PTR(-ENOMEM); + + switch (ver) { + case INFO_V3: + smem_dram_parse_v3_data(dram, data, false); + break; + case INFO_V3_WITH_14_FREQS: + smem_dram_parse_v3_data(dram, data, true); + break; + case INFO_V4: + smem_dram_parse_v4_data(dram, data); + break; + case INFO_V5: + case INFO_V5_WITH_6_REGIONS: + case INFO_V6: + smem_dram_parse_v5_data(dram, data); + break; + case INFO_V7: + case INFO_V7_WITH_6_REGIONS: + smem_dram_parse_v7_data(dram, data); + break; + default: + return ERR_PTR(-EINVAL); + } + + /* Both the entry and its parent dir will be cleaned up by debugfs_remove= _recursive */ + debugfs_dir =3D debugfs_create_dir("qcom_smem", NULL); + debugfs_create_file("dram_frequencies", 0444, debugfs_dir, dram, + &smem_dram_frequencies_fops); + debugfs_create_file("hbb", 0444, debugfs_dir, dram, &smem_hbb_fops); + + /* If there was no failure so far, assign the global variable */ + __dram =3D dram; + + return debugfs_dir; +} diff --git a/include/linux/soc/qcom/smem.h b/include/linux/soc/qcom/smem.h index f946e3beca21..223cd5090a2a 100644 --- a/include/linux/soc/qcom/smem.h +++ b/include/linux/soc/qcom/smem.h @@ -2,6 +2,8 @@ #ifndef __QCOM_SMEM_H__ #define __QCOM_SMEM_H__ =20 +#include + #define QCOM_SMEM_HOST_ANY -1 =20 bool qcom_smem_is_available(void); @@ -17,4 +19,6 @@ int qcom_smem_get_feature_code(u32 *code); =20 int qcom_smem_bust_hwspin_lock_by_host(unsigned int host); =20 +int qcom_smem_dram_get_hbb(void); + #endif --=20 2.52.0 From nobody Sat Feb 7 09:34:53 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id F29E046AECE; Thu, 8 Jan 2026 14:22:18 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767882139; cv=none; b=UTJsJjgonBcZOLsu+Mj7/Wp5VRLNu3JzzMzNttblp6cVO3tTwADdVofwZbRQ942GbwEBUwz25JM37sEpeJlQLzz6WY+O9OKPmMFN/rVG3dbCobWfyubxS5oAJo23eW81lV8EMTWl1OVjgeyJzjA50IG2FI/W7MESPbJEPAP0OVY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767882139; c=relaxed/simple; bh=uDuRuz6holk0p1W5KjXd7ziv9LHNLbMpJvwufQS0xJI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=fvbmLskT0p3fDdiMqaDMy6FpMoNQ10SYIOFs3iozaLMfcD+s1Lg8MPBR1yUoA4LhBS06mpuhLEfQePjEcPVuwq/6zp5fFM/RMnd4UWhGftWKPaad1bYuLtdeW/X7PARzfhI0vpKLuGEAMiT47dr5JA5WA2rRqSj9DSBbVZrr1kA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=RcrLmkq9; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="RcrLmkq9" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0EE79C19422; Thu, 8 Jan 2026 14:22:13 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1767882138; bh=uDuRuz6holk0p1W5KjXd7ziv9LHNLbMpJvwufQS0xJI=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=RcrLmkq93kQ22yZ9KL0tLoCY85RZ5mb861YZWHp9bN/RkkydVX3ta9OkLr98YILsv 3elplbb62imu+1070aJRrAZxJhTiQp/2HFLzo8Fq32P4haBvIE8sNakstXPoBrQVvE wvsqWdfUcYnOtl9+bjPN7zgyQ/Z3rIgZcnUNu/97/dKSR1x3+vKKo7zDe/MG352YLM eh5mPiQzXY91FJv+ZIaHb7x5K//xv5me5mfxBHkLFnVFxfwILllRGiThqOS3Lc8Pgy M6Lv3olL+rYlZ+EMX+lWOKWZcQVJdkg6FuRMhammC/Dw4GLqafKJrwWMpltXbAR+qk IRE6ajaoclBiw== From: Konrad Dybcio Date: Thu, 08 Jan 2026 15:21:51 +0100 Subject: [PATCH v3 2/3] soc: qcom: ubwc: Get HBB from SMEM Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260108-topic-smem_dramc-v3-2-6b64df58a017@oss.qualcomm.com> References: <20260108-topic-smem_dramc-v3-0-6b64df58a017@oss.qualcomm.com> In-Reply-To: <20260108-topic-smem_dramc-v3-0-6b64df58a017@oss.qualcomm.com> To: Bjorn Andersson , Konrad Dybcio , Kees Cook , "Gustavo A. R. Silva" , Rob Clark , Sean Paul , Akhil P Oommen , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Marijn Suijten , David Airlie , Simona Vetter Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-hardening@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, Konrad Dybcio X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1767882123; l=9485; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=PNGfZ45coN1C/o+QL9ZexnumgXEWcaMR9QTIU53QLLI=; b=HIkBEggRFxaEVDk+SXDG8YmOReIY+FoLieMqX0aAIL8ImBlyKUPBmw/dPNneUFtXWfUt/K7zG 8MsZqEIwSnYC/kv+n417iT/cgfrOMgDr2dua/tB9KaQu43py9AxKaF4 X-Developer-Key: i=konrad.dybcio@oss.qualcomm.com; a=ed25519; pk=iclgkYvtl2w05SSXO5EjjSYlhFKsJ+5OSZBjOkQuEms= From: Konrad Dybcio To make sure the correct settings for a given DRAM configuration get applied, attempt to retrieve that data from SMEM (which happens to be what the BSP kernel does, albeit with through convoluted means of the bootloader altering the DT with this data). Signed-off-by: Konrad Dybcio Tested-by: Neil Armstrong # on SM8650-HDK --- I'm not sure about this approach - perhaps a global variable storing the selected config, which would then be non-const would be better? --- drivers/soc/qcom/ubwc_config.c | 69 ++++++++++++++++++++++++++------------= ---- 1 file changed, 43 insertions(+), 26 deletions(-) diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 1c25aaf55e52..21bb444dc27c 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c @@ -11,12 +11,13 @@ #include =20 #include +#include =20 -static const struct qcom_ubwc_cfg_data no_ubwc_data =3D { +static struct qcom_ubwc_cfg_data no_ubwc_data =3D { /* no UBWC, no HBB */ }; =20 -static const struct qcom_ubwc_cfg_data kaanapali_data =3D { +static struct qcom_ubwc_cfg_data kaanapali_data =3D { .ubwc_enc_version =3D UBWC_6_0, .ubwc_dec_version =3D UBWC_6_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -26,7 +27,7 @@ static const struct qcom_ubwc_cfg_data kaanapali_data =3D= { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data msm8937_data =3D { +static struct qcom_ubwc_cfg_data msm8937_data =3D { .ubwc_enc_version =3D UBWC_1_0, .ubwc_dec_version =3D UBWC_1_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL1 | @@ -35,7 +36,7 @@ static const struct qcom_ubwc_cfg_data msm8937_data =3D { .highest_bank_bit =3D 14, }; =20 -static const struct qcom_ubwc_cfg_data msm8998_data =3D { +static struct qcom_ubwc_cfg_data msm8998_data =3D { .ubwc_enc_version =3D UBWC_1_0, .ubwc_dec_version =3D UBWC_1_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL1 | @@ -44,12 +45,12 @@ static const struct qcom_ubwc_cfg_data msm8998_data =3D= { .highest_bank_bit =3D 15, }; =20 -static const struct qcom_ubwc_cfg_data qcm2290_data =3D { +static struct qcom_ubwc_cfg_data qcm2290_data =3D { /* no UBWC */ .highest_bank_bit =3D 15, }; =20 -static const struct qcom_ubwc_cfg_data sa8775p_data =3D { +static struct qcom_ubwc_cfg_data sa8775p_data =3D { .ubwc_enc_version =3D UBWC_4_0, .ubwc_dec_version =3D UBWC_4_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL3, @@ -58,7 +59,7 @@ static const struct qcom_ubwc_cfg_data sa8775p_data =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data sar2130p_data =3D { +static struct qcom_ubwc_cfg_data sar2130p_data =3D { .ubwc_enc_version =3D UBWC_3_0, /* 4.0.2 in hw */ .ubwc_dec_version =3D UBWC_4_3, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -68,7 +69,7 @@ static const struct qcom_ubwc_cfg_data sar2130p_data =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data sc7180_data =3D { +static struct qcom_ubwc_cfg_data sc7180_data =3D { .ubwc_enc_version =3D UBWC_2_0, .ubwc_dec_version =3D UBWC_2_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -77,7 +78,7 @@ static const struct qcom_ubwc_cfg_data sc7180_data =3D { .highest_bank_bit =3D 14, }; =20 -static const struct qcom_ubwc_cfg_data sc7280_data =3D { +static struct qcom_ubwc_cfg_data sc7280_data =3D { .ubwc_enc_version =3D UBWC_3_0, .ubwc_dec_version =3D UBWC_4_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -87,7 +88,7 @@ static const struct qcom_ubwc_cfg_data sc7280_data =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data sc8180x_data =3D { +static struct qcom_ubwc_cfg_data sc8180x_data =3D { .ubwc_enc_version =3D UBWC_3_0, .ubwc_dec_version =3D UBWC_3_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -96,7 +97,7 @@ static const struct qcom_ubwc_cfg_data sc8180x_data =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data sc8280xp_data =3D { +static struct qcom_ubwc_cfg_data sc8280xp_data =3D { .ubwc_enc_version =3D UBWC_4_0, .ubwc_dec_version =3D UBWC_4_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -106,7 +107,7 @@ static const struct qcom_ubwc_cfg_data sc8280xp_data = =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data sdm670_data =3D { +static struct qcom_ubwc_cfg_data sdm670_data =3D { .ubwc_enc_version =3D UBWC_2_0, .ubwc_dec_version =3D UBWC_2_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -114,7 +115,7 @@ static const struct qcom_ubwc_cfg_data sdm670_data =3D { .highest_bank_bit =3D 14, }; =20 -static const struct qcom_ubwc_cfg_data sdm845_data =3D { +static struct qcom_ubwc_cfg_data sdm845_data =3D { .ubwc_enc_version =3D UBWC_2_0, .ubwc_dec_version =3D UBWC_2_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -122,7 +123,7 @@ static const struct qcom_ubwc_cfg_data sdm845_data =3D { .highest_bank_bit =3D 15, }; =20 -static const struct qcom_ubwc_cfg_data sm6115_data =3D { +static struct qcom_ubwc_cfg_data sm6115_data =3D { .ubwc_enc_version =3D UBWC_1_0, .ubwc_dec_version =3D UBWC_2_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL1 | @@ -132,7 +133,7 @@ static const struct qcom_ubwc_cfg_data sm6115_data =3D { .highest_bank_bit =3D 14, }; =20 -static const struct qcom_ubwc_cfg_data sm6125_data =3D { +static struct qcom_ubwc_cfg_data sm6125_data =3D { .ubwc_enc_version =3D UBWC_1_0, .ubwc_dec_version =3D UBWC_3_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL1 | @@ -141,7 +142,7 @@ static const struct qcom_ubwc_cfg_data sm6125_data =3D { .highest_bank_bit =3D 14, }; =20 -static const struct qcom_ubwc_cfg_data sm6150_data =3D { +static struct qcom_ubwc_cfg_data sm6150_data =3D { .ubwc_enc_version =3D UBWC_2_0, .ubwc_dec_version =3D UBWC_2_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -149,7 +150,7 @@ static const struct qcom_ubwc_cfg_data sm6150_data =3D { .highest_bank_bit =3D 14, }; =20 -static const struct qcom_ubwc_cfg_data sm6350_data =3D { +static struct qcom_ubwc_cfg_data sm6350_data =3D { .ubwc_enc_version =3D UBWC_2_0, .ubwc_dec_version =3D UBWC_2_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -158,7 +159,7 @@ static const struct qcom_ubwc_cfg_data sm6350_data =3D { .highest_bank_bit =3D 14, }; =20 -static const struct qcom_ubwc_cfg_data sm7150_data =3D { +static struct qcom_ubwc_cfg_data sm7150_data =3D { .ubwc_enc_version =3D UBWC_2_0, .ubwc_dec_version =3D UBWC_2_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -166,7 +167,7 @@ static const struct qcom_ubwc_cfg_data sm7150_data =3D { .highest_bank_bit =3D 14, }; =20 -static const struct qcom_ubwc_cfg_data sm8150_data =3D { +static struct qcom_ubwc_cfg_data sm8150_data =3D { .ubwc_enc_version =3D UBWC_3_0, .ubwc_dec_version =3D UBWC_3_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -174,7 +175,7 @@ static const struct qcom_ubwc_cfg_data sm8150_data =3D { .highest_bank_bit =3D 15, }; =20 -static const struct qcom_ubwc_cfg_data sm8250_data =3D { +static struct qcom_ubwc_cfg_data sm8250_data =3D { .ubwc_enc_version =3D UBWC_4_0, .ubwc_dec_version =3D UBWC_4_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -185,7 +186,7 @@ static const struct qcom_ubwc_cfg_data sm8250_data =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data sm8350_data =3D { +static struct qcom_ubwc_cfg_data sm8350_data =3D { .ubwc_enc_version =3D UBWC_4_0, .ubwc_dec_version =3D UBWC_4_0, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -196,7 +197,7 @@ static const struct qcom_ubwc_cfg_data sm8350_data =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data sm8550_data =3D { +static struct qcom_ubwc_cfg_data sm8550_data =3D { .ubwc_enc_version =3D UBWC_4_0, .ubwc_dec_version =3D UBWC_4_3, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -207,7 +208,7 @@ static const struct qcom_ubwc_cfg_data sm8550_data =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data sm8750_data =3D { +static struct qcom_ubwc_cfg_data sm8750_data =3D { .ubwc_enc_version =3D UBWC_5_0, .ubwc_dec_version =3D UBWC_5_0, .ubwc_swizzle =3D 6, @@ -217,7 +218,7 @@ static const struct qcom_ubwc_cfg_data sm8750_data =3D { .macrotile_mode =3D true, }; =20 -static const struct qcom_ubwc_cfg_data x1e80100_data =3D { +static struct qcom_ubwc_cfg_data x1e80100_data =3D { .ubwc_enc_version =3D UBWC_4_0, .ubwc_dec_version =3D UBWC_4_3, .ubwc_swizzle =3D UBWC_SWIZZLE_ENABLE_LVL2 | @@ -301,14 +302,30 @@ static const struct of_device_id qcom_ubwc_configs[] = __maybe_unused =3D { =20 const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void) { - const struct qcom_ubwc_cfg_data *data; + struct qcom_ubwc_cfg_data *data; + int hbb; =20 - data =3D of_machine_get_match_data(qcom_ubwc_configs); + if (!qcom_smem_is_available()) + return ERR_PTR(-EPROBE_DEFER); + + /* Discard the const qualifier, but still return a const pointer to consu= mers */ + data =3D (struct qcom_ubwc_cfg_data *)of_machine_get_match_data(qcom_ubwc= _configs); if (!data) { pr_err("Couldn't find UBWC config data for this platform!\n"); return ERR_PTR(-EINVAL); } =20 + hbb =3D qcom_smem_dram_get_hbb(); + if (hbb =3D=3D -ENODATA) { + /* Lack of HBB data is OK - it was only introduced later */ + return data; + } else if (hbb < 0) { + pr_err("Couldn't get HBB data from SMEM: %d\n", hbb); + return ERR_PTR(hbb); + } + + data->highest_bank_bit =3D hbb; + return data; } EXPORT_SYMBOL_GPL(qcom_ubwc_config_get_data); --=20 2.52.0 From nobody Sat Feb 7 09:34:53 2026 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 281E14779A9; Thu, 8 Jan 2026 14:22:23 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767882143; cv=none; b=U5e4hmwJ/UqlPmjjT/bDHXTnSXNaa4DoNcRaz3VFJ5SDi0w5VPHfkoyFyyIav0409VwQhFWOk7FcEw70JMKglPJl0MrPpHcCS/YgvBtGD+L6uJ90VPwYlL8HsMrZx6Pwwn6prt48QDCBQWIHJBRQ0Bm9cH+3NspND1xwROgLvss= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1767882143; c=relaxed/simple; bh=0hY9JelA00ZEkrC7+2oNgWXngE5MpTczcLOf3S0rzvw=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HR9OBLo0F5XaGDdd4XhYZyNb/tQP4RT4L+6slno0RO/jXeviwc/+3SHrYxnukHDW5nM7g3swq2Ze8TsYRn8WV1FyPvlfd/i84BnZe5ljOaSL6condqNzL7/SGee9DICxAJ3Sl/vJuqO5ts8fZWH+tkz+p7oUn0Au3jr3qIX/YHU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=Xa9p18R/; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="Xa9p18R/" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 03F8FC116C6; Thu, 8 Jan 2026 14:22:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1767882143; bh=0hY9JelA00ZEkrC7+2oNgWXngE5MpTczcLOf3S0rzvw=; h=From:Date:Subject:References:In-Reply-To:To:Cc:From; b=Xa9p18R/CYw8HZX364CEj6bdpfUoIngst996QFzwnZloIOVlrs4JYPOlV5Lf13+f5 u3arwHIrXUjSlndMHQKztRmek++C5yUfk+Uh/j3CJ4+WbFm860ithOP6OkNWMZMwww Kq63DW5zMPtffqiXbQlZJECGHgjpI1qwStauFUezVUIeeVS+x2aC2EnRtFs7GoPaOU AduV82cD28JT+NSTSXFkXZIHrU5HgMZV8dCqsqYUgJ0iNbxUhYBLeObfAYt5Wz+6hR YZz1A98/1h7+Wj+7WjsS0H8Deqc6oc/4zPTOljkM7ZXqxWya76k9Pq+4R/Zlv5FNvS 4KXK+b03at1rw== From: Konrad Dybcio Date: Thu, 08 Jan 2026 15:21:52 +0100 Subject: [PATCH v3 3/3] drm/msm/adreno: Trust the SSoT UBWC config Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260108-topic-smem_dramc-v3-3-6b64df58a017@oss.qualcomm.com> References: <20260108-topic-smem_dramc-v3-0-6b64df58a017@oss.qualcomm.com> In-Reply-To: <20260108-topic-smem_dramc-v3-0-6b64df58a017@oss.qualcomm.com> To: Bjorn Andersson , Konrad Dybcio , Kees Cook , "Gustavo A. R. Silva" , Rob Clark , Sean Paul , Akhil P Oommen , Dmitry Baryshkov , Abhinav Kumar , Jessica Zhang , Marijn Suijten , David Airlie , Simona Vetter Cc: linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org, linux-hardening@vger.kernel.org, dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org, Konrad Dybcio X-Mailer: b4 0.14.3 X-Developer-Signature: v=1; a=ed25519-sha256; t=1767882123; l=5689; i=konrad.dybcio@oss.qualcomm.com; s=20230215; h=from:subject:message-id; bh=aTiejsPtfF2C+UvMvN1X8HZ/alQLAnwLRugfA9Gd7pc=; b=UjmQRKA9IH21fUaxqBYt5irSAUkUhy+Es7pOm2Z5NFVDKfc2ml4W4kBdGRaHyAs8d7AV7G92I e/hv5XcKzAFCpChVUBWNSPKYA5MDbmS55KybMHemL3qJ/ZlFy/m3Dwl X-Developer-Key: i=konrad.dybcio@oss.qualcomm.com; a=ed25519; pk=iclgkYvtl2w05SSXO5EjjSYlhFKsJ+5OSZBjOkQuEms= From: Konrad Dybcio Now that the highest_bank_bit value is retrieved from the running system and the global config has been part of the tree for a couple of releases, there is no reason to keep any hardcoded values inside the GPU driver. Get rid of them. Signed-off-by: Konrad Dybcio Reviewed-by: Dmitry Baryshkov Reviewed-by: Rob Clark Tested-by: Neil Armstrong # on SM8650-HDK --- drivers/gpu/drm/msm/adreno/a5xx_gpu.c | 11 ++--- drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 82 ++---------------------------= ---- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 5 -- 3 files changed, 6 insertions(+), 92 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c b/drivers/gpu/drm/msm/ad= reno/a5xx_gpu.c index 56eaff2ee4e4..eba6e74d0084 100644 --- a/drivers/gpu/drm/msm/adreno/a5xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a5xx_gpu.c @@ -1728,7 +1728,6 @@ static struct msm_gpu *a5xx_gpu_init(struct drm_devic= e *dev) struct msm_drm_private *priv =3D dev->dev_private; struct platform_device *pdev =3D priv->gpu_pdev; struct adreno_platform_config *config =3D pdev->dev.platform_data; - const struct qcom_ubwc_cfg_data *common_cfg; struct a5xx_gpu *a5xx_gpu =3D NULL; struct adreno_gpu *adreno_gpu; struct msm_gpu *gpu; @@ -1766,13 +1765,9 @@ static struct msm_gpu *a5xx_gpu_init(struct drm_devi= ce *dev) a5xx_preempt_init(gpu); =20 /* Inherit the common config and make some necessary fixups */ - common_cfg =3D qcom_ubwc_config_get_data(); - if (IS_ERR(common_cfg)) - return ERR_CAST(common_cfg); - - /* Copy the data into the internal struct to drop the const qualifier (te= mporarily) */ - adreno_gpu->_ubwc_config =3D *common_cfg; - adreno_gpu->ubwc_config =3D &adreno_gpu->_ubwc_config; + adreno_gpu->ubwc_config =3D qcom_ubwc_config_get_data(); + if (IS_ERR(adreno_gpu->ubwc_config)) + return ERR_CAST(adreno_gpu->ubwc_config); =20 adreno_gpu->uche_trap_base =3D 0x0001ffffffff0000ull; =20 diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c b/drivers/gpu/drm/msm/ad= reno/a6xx_gpu.c index 2129d230a92b..3a2429632225 100644 --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c @@ -729,82 +729,6 @@ static void a6xx_set_cp_protect(struct msm_gpu *gpu) gpu_write(gpu, REG_A6XX_CP_PROTECT(protect->count_max - 1), protect->regs= [i]); } =20 -static int a6xx_calc_ubwc_config(struct adreno_gpu *gpu) -{ - const struct qcom_ubwc_cfg_data *common_cfg; - struct qcom_ubwc_cfg_data *cfg =3D &gpu->_ubwc_config; - - /* Inherit the common config and make some necessary fixups */ - common_cfg =3D qcom_ubwc_config_get_data(); - if (IS_ERR(common_cfg)) - return PTR_ERR(common_cfg); - - /* Copy the data into the internal struct to drop the const qualifier (te= mporarily) */ - *cfg =3D *common_cfg; - - /* Use common config as is for A8x */ - if (!adreno_is_a8xx(gpu)) { - cfg->ubwc_swizzle =3D 0x6; - cfg->highest_bank_bit =3D 15; - } - - if (adreno_is_a610(gpu)) { - cfg->highest_bank_bit =3D 13; - cfg->ubwc_swizzle =3D 0x7; - } - - if (adreno_is_a612(gpu)) - cfg->highest_bank_bit =3D 14; - - if (adreno_is_a618(gpu)) - cfg->highest_bank_bit =3D 14; - - if (adreno_is_a619(gpu)) - /* TODO: Should be 14 but causes corruption at e.g. 1920x1200 on DP */ - cfg->highest_bank_bit =3D 13; - - if (adreno_is_a619_holi(gpu)) - cfg->highest_bank_bit =3D 13; - - if (adreno_is_a621(gpu)) - cfg->highest_bank_bit =3D 13; - - if (adreno_is_a623(gpu)) - cfg->highest_bank_bit =3D 16; - - if (adreno_is_a650(gpu) || - adreno_is_a660(gpu) || - adreno_is_a690(gpu) || - adreno_is_a730(gpu) || - adreno_is_a740_family(gpu)) { - /* TODO: get ddr type from bootloader and use 15 for LPDDR4 */ - cfg->highest_bank_bit =3D 16; - } - - if (adreno_is_a663(gpu)) { - cfg->highest_bank_bit =3D 13; - cfg->ubwc_swizzle =3D 0x4; - } - - if (adreno_is_7c3(gpu)) - cfg->highest_bank_bit =3D 14; - - if (adreno_is_a702(gpu)) - cfg->highest_bank_bit =3D 14; - - if (cfg->highest_bank_bit !=3D common_cfg->highest_bank_bit) - DRM_WARN_ONCE("Inconclusive highest_bank_bit value: %u (GPU) vs %u (UBWC= _CFG)\n", - cfg->highest_bank_bit, common_cfg->highest_bank_bit); - - if (cfg->ubwc_swizzle !=3D common_cfg->ubwc_swizzle) - DRM_WARN_ONCE("Inconclusive ubwc_swizzle value: %u (GPU) vs %u (UBWC_CFG= )\n", - cfg->ubwc_swizzle, common_cfg->ubwc_swizzle); - - gpu->ubwc_config =3D &gpu->_ubwc_config; - - return 0; -} - static void a6xx_set_ubwc_config(struct msm_gpu *gpu) { struct adreno_gpu *adreno_gpu =3D to_adreno_gpu(gpu); @@ -2721,10 +2645,10 @@ static struct msm_gpu *a6xx_gpu_init(struct drm_dev= ice *dev) msm_mmu_set_fault_handler(to_msm_vm(gpu->vm)->mmu, gpu, adreno_gpu->funcs->mmu_fault_handler); =20 - ret =3D a6xx_calc_ubwc_config(adreno_gpu); - if (ret) { + adreno_gpu->ubwc_config =3D qcom_ubwc_config_get_data(); + if (IS_ERR(adreno_gpu->ubwc_config)) { a6xx_destroy(&(a6xx_gpu->base.base)); - return ERR_PTR(ret); + return ERR_CAST(adreno_gpu->ubwc_config); } =20 /* Set up the preemption specific bits and pieces for each ringbuffer */ diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/= adreno/adreno_gpu.h index 1d0145f8b3ec..da9a6da7c108 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -237,12 +237,7 @@ struct adreno_gpu { /* firmware: */ const struct firmware *fw[ADRENO_FW_MAX]; =20 - /* - * The migration to the central UBWC config db is still in flight - keep - * a copy containing some local fixups until that's done. - */ const struct qcom_ubwc_cfg_data *ubwc_config; - struct qcom_ubwc_cfg_data _ubwc_config; =20 /* * Register offsets are different between some GPUs. --=20 2.52.0