From 1b445022d1d0ec7431b6f8fe0054ae8ccf33d60a Mon Sep 17 00:00:00 2001 From: Konrad Dybcio Date: Mon, 27 Jul 2026 11:59:29 +0200 Subject: [PATCH] soc: qcom: ubwc: Get HBB from SMEM 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 Link: https://lore.kernel.org/r/20260727-topic-smem_dramc-v5-3-66188b3e338d@oss.qualcomm.com Signed-off-by: Bjorn Andersson --- drivers/soc/qcom/ubwc_config.c | 40 +++++++++++++++++++++++++++++++++- 1 file changed, 39 insertions(+), 1 deletion(-) diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 0209a02c390f..23901a4c51f7 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c @@ -11,6 +11,7 @@ #include #include +#include static const struct qcom_ubwc_cfg_data no_ubwc_data = { /* no UBWC, no HBB */ @@ -168,9 +169,25 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { } }; +static struct qcom_ubwc_cfg_data *cfg; +static DEFINE_MUTEX(cfg_mutex); +/** + * qcom_ubwc_config_get_data() - Retrieve UBWC data for the platform. + * + * Return: Pointer to valid struct qcom_ubwc_cfg_data on success, negative + * errno on failure. Note that this may return EPROBE_DEFER. + */ const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void) { const struct qcom_ubwc_cfg_data *data; + int hbb; + + guard(mutex)(&cfg_mutex); + if (cfg) + return cfg; + + if (!qcom_smem_is_available()) + return ERR_PTR(-EPROBE_DEFER); data = of_machine_get_match_data(qcom_ubwc_configs); if (!data) { @@ -178,9 +195,30 @@ const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void) return ERR_PTR(-EINVAL); } - return data; + hbb = qcom_smem_dram_get_hbb(); + if (hbb == -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); + } + + cfg = kmemdup(data, sizeof(*data), GFP_KERNEL); + if (!cfg) + return ERR_PTR(-ENOMEM); + + cfg->highest_bank_bit = hbb; + + return cfg; } EXPORT_SYMBOL_GPL(qcom_ubwc_config_get_data); +static void __exit ubwc_config_exit(void) +{ + kfree(cfg); +} +module_exit(ubwc_config_exit); + MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("UBWC config database for QTI SoCs");