diff options
Diffstat (limited to 'drivers/soc')
-rw-r--r-- | drivers/soc/qcom/Kconfig | 9 | ||||
-rw-r--r-- | drivers/soc/qcom/Makefile | 1 | ||||
-rw-r--r-- | drivers/soc/qcom/apr.c | 3 | ||||
-rw-r--r-- | drivers/soc/qcom/cpr.c | 6 | ||||
-rw-r--r-- | drivers/soc/qcom/ramp_controller.c | 343 | ||||
-rw-r--r-- | drivers/soc/qcom/rmtfs_mem.c | 29 | ||||
-rw-r--r-- | drivers/soc/qcom/rpmhpd.c | 34 | ||||
-rw-r--r-- | drivers/soc/qcom/rpmpd.c | 18 | ||||
-rw-r--r-- | drivers/soc/qcom/socinfo.c | 96 |
9 files changed, 509 insertions, 30 deletions
diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index df6ff7bf90cb..348fde2a8aae 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -111,6 +111,15 @@ config QCOM_QMI_HELPERS tristate depends on NET +config QCOM_RAMP_CTRL + tristate "Qualcomm Ramp Controller driver" + depends on ARCH_QCOM || COMPILE_TEST + help + The Ramp Controller is used to program the sequence ID for pulse + swallowing, enable sequence and link sequence IDs for the CPU + cores on some Qualcomm SoCs. + Say y here to enable support for the ramp controller. + config QCOM_RMTFS_MEM tristate "Qualcomm Remote Filesystem memory driver" depends on ARCH_QCOM diff --git a/drivers/soc/qcom/Makefile b/drivers/soc/qcom/Makefile index 8d62a17863c1..6e88da899f60 100644 --- a/drivers/soc/qcom/Makefile +++ b/drivers/soc/qcom/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink.o obj-$(CONFIG_QCOM_PMIC_GLINK) += pmic_glink_altmode.o obj-$(CONFIG_QCOM_QMI_HELPERS) += qmi_helpers.o qmi_helpers-y += qmi_encdec.o qmi_interface.o +obj-$(CONFIG_QCOM_RAMP_CTRL) += ramp_controller.o obj-$(CONFIG_QCOM_RMTFS_MEM) += rmtfs_mem.o obj-$(CONFIG_QCOM_RPMH) += qcom_rpmh.o qcom_rpmh-y += rpmh-rsc.o diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index cd44f17dad3d..d51abb462ae5 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -461,9 +461,10 @@ static int apr_add_device(struct device *dev, struct device_node *np, goto out; } + /* Protection domain is optional, it does not exist on older platforms */ ret = of_property_read_string_index(np, "qcom,protection-domain", 1, &adev->service_path); - if (ret < 0) { + if (ret < 0 && ret != -EINVAL) { dev_err(dev, "Failed to read second value of qcom,protection-domain\n"); goto out; } diff --git a/drivers/soc/qcom/cpr.c b/drivers/soc/qcom/cpr.c index e9b854ed1bdf..144ea68e0920 100644 --- a/drivers/soc/qcom/cpr.c +++ b/drivers/soc/qcom/cpr.c @@ -1708,12 +1708,16 @@ static int cpr_probe(struct platform_device *pdev) ret = of_genpd_add_provider_simple(dev->of_node, &drv->pd); if (ret) - return ret; + goto err_remove_genpd; platform_set_drvdata(pdev, drv); cpr_debugfs_init(drv); return 0; + +err_remove_genpd: + pm_genpd_remove(&drv->pd); + return ret; } static int cpr_remove(struct platform_device *pdev) diff --git a/drivers/soc/qcom/ramp_controller.c b/drivers/soc/qcom/ramp_controller.c new file mode 100644 index 000000000000..dc74d2a19de2 --- /dev/null +++ b/drivers/soc/qcom/ramp_controller.c @@ -0,0 +1,343 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Qualcomm Ramp Controller driver + * Copyright (c) 2022, AngeloGioacchino Del Regno + * <angelogioacchino.delregno@collabora.com> + */ + +#include <linux/bitfield.h> +#include <linux/kernel.h> +#include <linux/module.h> +#include <linux/of.h> +#include <linux/of_platform.h> +#include <linux/platform_device.h> +#include <linux/regmap.h> +#include <linux/types.h> + +#define RC_UPDATE_EN BIT(0) +#define RC_ROOT_EN BIT(1) + +#define RC_REG_CFG_UPDATE 0x60 +#define RC_CFG_UPDATE_EN BIT(8) +#define RC_CFG_ACK GENMASK(31, 16) + +#define RC_DCVS_CFG_SID 2 +#define RC_LINK_SID 3 +#define RC_LMH_SID 6 +#define RC_DFS_SID 14 + +#define RC_UPDATE_TIMEOUT_US 500 + +/** + * struct qcom_ramp_controller_desc - SoC specific parameters + * @cfg_dfs_sid: Dynamic Frequency Scaling SID configuration + * @cfg_link_sid: Link SID configuration + * @cfg_lmh_sid: Limits Management hardware SID configuration + * @cfg_ramp_en: Ramp Controller enable sequence + * @cfg_ramp_dis: Ramp Controller disable sequence + * @cmd_reg: Command register offset + * @num_dfs_sids: Number of DFS SIDs (max 8) + * @num_link_sids: Number of Link SIDs (max 3) + * @num_lmh_sids: Number of LMh SIDs (max 8) + * @num_ramp_en: Number of entries in enable sequence + * @num_ramp_dis: Number of entries in disable sequence + */ +struct qcom_ramp_controller_desc { + const struct reg_sequence *cfg_dfs_sid; + const struct reg_sequence *cfg_link_sid; + const struct reg_sequence *cfg_lmh_sid; + const struct reg_sequence *cfg_ramp_en; + const struct reg_sequence *cfg_ramp_dis; + u8 cmd_reg; + u8 num_dfs_sids; + u8 num_link_sids; + u8 num_lmh_sids; + u8 num_ramp_en; + u8 num_ramp_dis; +}; + +/** + * struct qcom_ramp_controller - Main driver structure + * @regmap: Regmap handle + * @desc: SoC specific parameters + */ +struct qcom_ramp_controller { + struct regmap *regmap; + const struct qcom_ramp_controller_desc *desc; +}; + +/** + * rc_wait_for_update() - Wait for Ramp Controller root update + * @qrc: Main driver structure + * + * Return: Zero for success or negative number for failure + */ +static int rc_wait_for_update(struct qcom_ramp_controller *qrc) +{ + const struct qcom_ramp_controller_desc *d = qrc->desc; + struct regmap *r = qrc->regmap; + u32 val; + int ret; + + ret = regmap_set_bits(r, d->cmd_reg, RC_ROOT_EN); + if (ret) + return ret; + + return regmap_read_poll_timeout(r, d->cmd_reg, val, !(val & RC_UPDATE_EN), + 1, RC_UPDATE_TIMEOUT_US); +} + +/** + * rc_set_cfg_update() - Ramp Controller configuration update + * @qrc: Main driver structure + * @ce: Configuration entry to update + * + * Return: Zero for success or negative number for failure + */ +static int rc_set_cfg_update(struct qcom_ramp_controller *qrc, u8 ce) +{ + const struct qcom_ramp_controller_desc *d = qrc->desc; + struct regmap *r = qrc->regmap; + u32 ack, val; + int ret; + + /* The ack bit is between bits 16-31 of RC_REG_CFG_UPDATE */ + ack = FIELD_PREP(RC_CFG_ACK, BIT(ce)); + + /* Write the configuration type first... */ + ret = regmap_set_bits(r, d->cmd_reg + RC_REG_CFG_UPDATE, ce); + if (ret) + return ret; + + /* ...and after that, enable the update bit to sync the changes */ + ret = regmap_set_bits(r, d->cmd_reg + RC_REG_CFG_UPDATE, RC_CFG_UPDATE_EN); + if (ret) + return ret; + + /* Wait for the changes to go through */ + ret = regmap_read_poll_timeout(r, d->cmd_reg + RC_REG_CFG_UPDATE, val, + val & ack, 1, RC_UPDATE_TIMEOUT_US); + if (ret) + return ret; + + /* + * Configuration update success! The CFG_UPDATE register will not be + * cleared automatically upon applying the configuration, so we have + * to do that manually in order to leave the ramp controller in a + * predictable and clean state. + */ + ret = regmap_write(r, d->cmd_reg + RC_REG_CFG_UPDATE, 0); + if (ret) + return ret; + + /* Wait for the update bit cleared ack */ + return regmap_read_poll_timeout(r, d->cmd_reg + RC_REG_CFG_UPDATE, + val, !(val & RC_CFG_ACK), 1, + RC_UPDATE_TIMEOUT_US); +} + +/** + * rc_write_cfg - Send configuration sequence + * @qrc: Main driver structure + * @seq: Register sequence to send before asking for update + * @ce: Configuration SID + * @nsids: Total number of SIDs + * + * Returns: Zero for success or negative number for error + */ +static int rc_write_cfg(struct qcom_ramp_controller *qrc, + const struct reg_sequence *seq, + u16 ce, u8 nsids) +{ + int ret; + u8 i; + + /* Check if, and wait until the ramp controller is ready */ + ret = rc_wait_for_update(qrc); + if (ret) + return ret; + + /* Write the sequence */ + ret = regmap_multi_reg_write(qrc->regmap, seq, nsids); + if (ret) + return ret; + + /* Pull the trigger: do config update starting from the last sid */ + for (i = 0; i < nsids; i++) { + ret = rc_set_cfg_update(qrc, (u8)ce - i); + if (ret) + return ret; + } + + return 0; +} + +/** + * rc_ramp_ctrl_enable() - Enable Ramp up/down Control + * @qrc: Main driver structure + * + * Return: Zero for success or negative number for error + */ +static int rc_ramp_ctrl_enable(struct qcom_ramp_controller *qrc) +{ + const struct qcom_ramp_controller_desc *d = qrc->desc; + int i, ret; + + for (i = 0; i < d->num_ramp_en; i++) { + ret = rc_write_cfg(qrc, &d->cfg_ramp_en[i], RC_DCVS_CFG_SID, 1); + if (ret) + return ret; + } + + return 0; +} + +/** + * qcom_ramp_controller_start() - Initialize and start the ramp controller + * @qrc: Main driver structure + * + * The Ramp Controller needs to be initialized by programming the relevant + * registers with SoC-specific configuration: once programming is done, + * the hardware will take care of the rest (no further handling required). + * + * Return: Zero for success or negative number for error + */ +static int qcom_ramp_controller_start(struct qcom_ramp_controller *qrc) +{ + const struct qcom_ramp_controller_desc *d = qrc->desc; + int ret; + + /* Program LMH, DFS, Link SIDs */ + ret = rc_write_cfg(qrc, d->cfg_lmh_sid, RC_LMH_SID, d->num_lmh_sids); + if (ret) + return ret; + + ret = rc_write_cfg(qrc, d->cfg_dfs_sid, RC_DFS_SID, d->num_dfs_sids); + if (ret) + return ret; + + ret = rc_write_cfg(qrc, d->cfg_link_sid, RC_LINK_SID, d->num_link_sids); + if (ret) + return ret; + + /* Everything is ready! Enable the ramp up/down control */ + return rc_ramp_ctrl_enable(qrc); +} + +static const struct regmap_config qrc_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .max_register = 0x68, + .fast_io = true, +}; + +static const struct reg_sequence msm8976_cfg_dfs_sid[] = { + { 0x10, 0xfefebff7 }, + { 0x14, 0xfdff7fef }, + { 0x18, 0xfbffdefb }, + { 0x1c, 0xb69b5555 }, + { 0x20, 0x24929249 }, + { 0x24, 0x49241112 }, + { 0x28, 0x11112111 }, + { 0x2c, 0x8102 } +}; + +static const struct reg_sequence msm8976_cfg_link_sid[] = { + { 0x40, 0xfc987 } +}; + +static const struct reg_sequence msm8976_cfg_lmh_sid[] = { + { 0x30, 0x77706db }, + { 0x34, 0x5550249 }, + { 0x38, 0x111 } +}; + +static const struct reg_sequence msm8976_cfg_ramp_en[] = { + { 0x50, 0x800 }, /* pre_en */ + { 0x50, 0xc00 }, /* en */ + { 0x50, 0x400 } /* post_en */ +}; + +static const struct reg_sequence msm8976_cfg_ramp_dis[] = { + { 0x50, 0x0 } +}; + +static const struct qcom_ramp_controller_desc msm8976_rc_cfg = { + .cfg_dfs_sid = msm8976_cfg_dfs_sid, + .num_dfs_sids = ARRAY_SIZE(msm8976_cfg_dfs_sid), + + .cfg_link_sid = msm8976_cfg_link_sid, + .num_link_sids = ARRAY_SIZE(msm8976_cfg_link_sid), + + .cfg_lmh_sid = msm8976_cfg_lmh_sid, + .num_lmh_sids = ARRAY_SIZE(msm8976_cfg_lmh_sid), + + .cfg_ramp_en = msm8976_cfg_ramp_en, + .num_ramp_en = ARRAY_SIZE(msm8976_cfg_ramp_en), + + .cfg_ramp_dis = msm8976_cfg_ramp_dis, + .num_ramp_dis = ARRAY_SIZE(msm8976_cfg_ramp_dis), + + .cmd_reg = 0x0, +}; + +static int qcom_ramp_controller_probe(struct platform_device *pdev) +{ + struct qcom_ramp_controller *qrc; + void __iomem *base; + + base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(base)) + return PTR_ERR(base); + + qrc = devm_kmalloc(&pdev->dev, sizeof(*qrc), GFP_KERNEL); + if (!qrc) + return -ENOMEM; + + qrc->desc = device_get_match_data(&pdev->dev); + if (!qrc) + return -EINVAL; + + qrc->regmap = devm_regmap_init_mmio(&pdev->dev, base, &qrc_regmap_config); + if (IS_ERR(qrc->regmap)) + return PTR_ERR(qrc->regmap); + + platform_set_drvdata(pdev, qrc); + + return qcom_ramp_controller_start(qrc); +} + +static int qcom_ramp_controller_remove(struct platform_device *pdev) +{ + struct qcom_ramp_controller *qrc = platform_get_drvdata(pdev); + + return rc_write_cfg(qrc, qrc->desc->cfg_ramp_dis, + RC_DCVS_CFG_SID, qrc->desc->num_ramp_dis); +} + +static const struct of_device_id qcom_ramp_controller_match_table[] = { + { .compatible = "qcom,msm8976-ramp-controller", .data = &msm8976_rc_cfg }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, qcom_ramp_controller_match_table); + +static struct platform_driver qcom_ramp_controller_driver = { + .driver = { + .name = "qcom-ramp-controller", + .of_match_table = qcom_ramp_controller_match_table, + .suppress_bind_attrs = true, + }, + .probe = qcom_ramp_controller_probe, + .remove = qcom_ramp_controller_remove, +}; + +static int __init qcom_ramp_controller_init(void) +{ + return platform_driver_register(&qcom_ramp_controller_driver); +} +arch_initcall(qcom_ramp_controller_init); + +MODULE_AUTHOR("AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>"); +MODULE_DESCRIPTION("Qualcomm Ramp Controller driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/soc/qcom/rmtfs_mem.c b/drivers/soc/qcom/rmtfs_mem.c index 0feaae357821..9d59ad509a5c 100644 --- a/drivers/soc/qcom/rmtfs_mem.c +++ b/drivers/soc/qcom/rmtfs_mem.c @@ -17,6 +17,7 @@ #include <linux/qcom_scm.h> #define QCOM_RMTFS_MEM_DEV_MAX (MINORMASK + 1) +#define NUM_MAX_VMIDS 2 static dev_t qcom_rmtfs_mem_major; @@ -171,12 +172,12 @@ static void qcom_rmtfs_mem_release_device(struct device *dev) static int qcom_rmtfs_mem_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; - struct qcom_scm_vmperm perms[2]; + struct qcom_scm_vmperm perms[NUM_MAX_VMIDS + 1]; struct reserved_mem *rmem; struct qcom_rmtfs_mem *rmtfs_mem; u32 client_id; - u32 vmid; - int ret; + u32 num_vmids, vmid[NUM_MAX_VMIDS]; + int ret, i; rmem = of_reserved_mem_lookup(node); if (!rmem) { @@ -226,7 +227,18 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev) goto put_device; } - ret = of_property_read_u32(node, "qcom,vmid", &vmid); + num_vmids = of_property_count_u32_elems(node, "qcom,vmid"); + if (num_vmids < 0) { + dev_err(&pdev->dev, "failed to count qcom,vmid elements: %d\n", ret); + goto remove_cdev; + } else if (num_vmids > NUM_MAX_VMIDS) { + dev_warn(&pdev->dev, + "too many VMIDs (%d) specified! Only mapping first %d entries\n", + num_vmids, NUM_MAX_VMIDS); + num_vmids = NUM_MAX_VMIDS; + } + + ret = of_property_read_u32_array(node, "qcom,vmid", vmid, num_vmids); if (ret < 0 && ret != -EINVAL) { dev_err(&pdev->dev, "failed to parse qcom,vmid\n"); goto remove_cdev; @@ -238,12 +250,15 @@ static int qcom_rmtfs_mem_probe(struct platform_device *pdev) perms[0].vmid = QCOM_SCM_VMID_HLOS; perms[0].perm = QCOM_SCM_PERM_RW; - perms[1].vmid = vmid; - perms[1].perm = QCOM_SCM_PERM_RW; + + for (i = 0; i < num_vmids; i++) { + perms[i + 1].vmid = vmid[i]; + perms[i + 1].perm = QCOM_SCM_PERM_RW; + } rmtfs_mem->perms = BIT(QCOM_SCM_VMID_HLOS); ret = qcom_scm_assign_mem(rmtfs_mem->addr, rmtfs_mem->size, - &rmtfs_mem->perms, perms, 2); + &rmtfs_mem->perms, perms, num_vmids + 1); if (ret < 0) { dev_err(&pdev->dev, "assign memory failed\n"); goto remove_cdev; diff --git a/drivers/soc/qcom/rpmhpd.c b/drivers/soc/qcom/rpmhpd.c index 4c2d2c296790..f20e2a49a669 100644 --- a/drivers/soc/qcom/rpmhpd.c +++ b/drivers/soc/qcom/rpmhpd.c @@ -187,6 +187,16 @@ static struct rpmhpd nsp = { .res_name = "nsp.lvl", }; +static struct rpmhpd nsp0 = { + .pd = { .name = "nsp0", }, + .res_name = "nsp0.lvl", +}; + +static struct rpmhpd nsp1 = { + .pd = { .name = "nsp1", }, + .res_name = "nsp1.lvl", +}; + static struct rpmhpd qphy = { .pd = { .name = "qphy", }, .res_name = "qphy.lvl", @@ -212,6 +222,29 @@ static const struct rpmhpd_desc sa8540p_desc = { .num_pds = ARRAY_SIZE(sa8540p_rpmhpds), }; +/* SA8775P RPMH power domains */ +static struct rpmhpd *sa8775p_rpmhpds[] = { + [SA8775P_CX] = &cx, + [SA8775P_CX_AO] = &cx_ao, + [SA8775P_EBI] = &ebi, + [SA8775P_GFX] = &gfx, + [SA8775P_LCX] = &lcx, + [SA8775P_LMX] = &lmx, + [SA8775P_MMCX] = &mmcx, + [SA8775P_MMCX_AO] = &mmcx_ao, + [SA8775P_MXC] = &mxc, + [SA8775P_MXC_AO] = &mxc_ao, + [SA8775P_MX] = &mx, + [SA8775P_MX_AO] = &mx_ao, + [SA8775P_NSP0] = &nsp0, + [SA8775P_NSP1] = &nsp1, +}; + +static const struct rpmhpd_desc sa8775p_desc = { + .rpmhpds = sa8775p_rpmhpds, + .num_pds = ARRAY_SIZE(sa8775p_rpmhpds), +}; + /* SDM670 RPMH powerdomains */ static struct rpmhpd *sdm670_rpmhpds[] = { [SDM670_CX] = &cx_w_mx_parent, @@ -487,6 +520,7 @@ static const struct rpmhpd_desc sc8280xp_desc = { static const struct of_device_id rpmhpd_match_table[] = { { .compatible = "qcom,qdu1000-rpmhpd", .data = &qdu1000_desc }, { .compatible = "qcom,sa8540p-rpmhpd", .data = &sa8540p_desc }, + { .compatible = "qcom,sa8775p-rpmhpd", .data = &sa8775p_desc }, { .compatible = "qcom,sc7180-rpmhpd", .data = &sc7180_desc }, { .compatible = "qcom,sc7280-rpmhpd", .data = &sc7280_desc }, { .compatible = "qcom,sc8180x-rpmhpd", .data = &sc8180x_desc }, diff --git a/drivers/soc/qcom/rpmpd.c b/drivers/soc/qcom/rpmpd.c index f0db6a10cf4e..337b1ad1cd3b 100644 --- a/drivers/soc/qcom/rpmpd.c +++ b/drivers/soc/qcom/rpmpd.c @@ -471,23 +471,6 @@ static const struct rpmpd_desc qcm2290_desc = { .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, }; -static struct rpmpd *sm4250_rpmpds[] = { - [SM4250_VDDCX] = &sm6115_vddcx, - [SM4250_VDDCX_AO] = &sm6115_vddcx_ao, - [SM4250_VDDCX_VFL] = &sm6115_vddcx_vfl, - [SM4250_VDDMX] = &sm6115_vddmx, - [SM4250_VDDMX_AO] = &sm6115_vddmx_ao, - [SM4250_VDDMX_VFL] = &sm6115_vddmx_vfl, - [SM4250_VDD_LPI_CX] = &sm6115_vdd_lpi_cx, - [SM4250_VDD_LPI_MX] = &sm6115_vdd_lpi_mx, -}; - -static const struct rpmpd_desc sm4250_desc = { - .rpmpds = sm4250_rpmpds, - .num_pds = ARRAY_SIZE(sm4250_rpmpds), - .max_state = RPM_SMD_LEVEL_TURBO_NO_CPR, -}; - static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,mdm9607-rpmpd", .data = &mdm9607_desc }, { .compatible = "qcom,msm8226-rpmpd", .data = &msm8226_desc }, @@ -502,7 +485,6 @@ static const struct of_device_id rpmpd_match_table[] = { { .compatible = "qcom,qcm2290-rpmpd", .data = &qcm2290_desc }, { .compatible = "qcom,qcs404-rpmpd", .data = &qcs404_desc }, { .compatible = "qcom,sdm660-rpmpd", .data = &sdm660_desc }, - { .compatible = "qcom,sm4250-rpmpd", .data = &sm4250_desc }, { .compatible = "qcom,sm6115-rpmpd", .data = &sm6115_desc }, { .compatible = "qcom,sm6125-rpmpd", .data = &sm6125_desc }, { .compatible = "qcom,sm6375-rpmpd", .data = &sm6375_desc }, diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index ebcbf9b9c18b..3b970a80f3aa 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -169,6 +169,11 @@ struct socinfo { __le32 ndefective_parts_array_offset; /* Version 15 */ __le32 nmodem_supported; + /* Version 16 */ + __le32 feature_code; + __le32 pcode; + __le32 npartnamemap_offset; + __le32 nnum_partname_mapping; }; #ifdef CONFIG_DEBUG_FS @@ -189,6 +194,8 @@ struct socinfo_params { u32 num_defective_parts; u32 ndefective_parts_array_offset; u32 nmodem_supported; + u32 feature_code; + u32 pcode; }; struct smem_image_version { @@ -214,44 +221,68 @@ struct soc_id { }; static const struct soc_id soc_id[] = { + { qcom_board_id(MSM8260) }, + { qcom_board_id(MSM8660) }, + { qcom_board_id(APQ8060) }, { qcom_board_id(MSM8960) }, { qcom_board_id(APQ8064) }, + { qcom_board_id(MSM8930) }, + { qcom_board_id(MSM8630) }, + { qcom_board_id(MSM8230) }, + { qcom_board_id(APQ8030) }, + { qcom_board_id(MSM8627) }, + { qcom_board_id(MSM8227) }, { qcom_board_id(MSM8660A) }, { qcom_board_id(MSM8260A) }, { qcom_board_id(APQ8060A) }, { qcom_board_id(MSM8974) }, + { qcom_board_id(MSM8225) }, + { qcom_board_id(MSM8625) }, { qcom_board_id(MPQ8064) }, { qcom_board_id(MSM8960AB) }, { qcom_board_id(APQ8060AB) }, { qcom_board_id(MSM8260AB) }, { qcom_board_id(MSM8660AB) }, + { qcom_board_id(MSM8930AA) }, + { qcom_board_id(MSM8630AA) }, + { qcom_board_id(MSM8230AA) }, { qcom_board_id(MSM8626) }, { qcom_board_id(MSM8610) }, { qcom_board_id(APQ8064AB) }, + { qcom_board_id(MSM8930AB) }, + { qcom_board_id(MSM8630AB) }, + { qcom_board_id(MSM8230AB) }, + { qcom_board_id(APQ8030AB) }, { qcom_board_id(MSM8226) }, { qcom_board_id(MSM8526) }, + { qcom_board_id(APQ8030AA) }, { qcom_board_id(MSM8110) }, { qcom_board_id(MSM8210) }, { qcom_board_id(MSM8810) }, { qcom_board_id(MSM8212) }, { qcom_board_id(MSM8612) }, { qcom_board_id(MSM8112) }, + { qcom_board_id(MSM8125) }, { qcom_board_id(MSM8225Q) }, { qcom_board_id(MSM8625Q) }, { qcom_board_id(MSM8125Q) }, { qcom_board_id(APQ8064AA) }, { qcom_board_id(APQ8084) }, + { qcom_board_id(MSM8130) }, + { qcom_board_id(MSM8130AA) }, + { qcom_board_id(MSM8130AB) }, + { qcom_board_id(MSM8627AA) }, + { qcom_board_id(MSM8227AA) }, { qcom_board_id(APQ8074) }, { qcom_board_id(MSM8274) }, { qcom_board_id(MSM8674) }, + { qcom_board_id(MDM9635) }, { qcom_board_id_named(MSM8974PRO_AC, "MSM8974PRO-AC") }, { qcom_board_id(MSM8126) }, { qcom_board_id(APQ8026) }, { qcom_board_id(MSM8926) }, { qcom_board_id(MSM8326) }, { qcom_board_id(MSM8916) }, - { qcom_board_id(MSM8956) }, - { qcom_board_id(MSM8976) }, { qcom_board_id(MSM8994) }, { qcom_board_id_named(APQ8074PRO_AA, "APQ8074PRO-AA") }, { qcom_board_id_named(APQ8074PRO_AB, "APQ8074PRO-AB") }, @@ -273,32 +304,72 @@ static const struct soc_id soc_id[] = { { qcom_board_id(MSM8510) }, { qcom_board_id(MSM8512) }, { qcom_board_id(MSM8936) }, + { qcom_board_id(MDM9640) }, { qcom_board_id(MSM8939) }, { qcom_board_id(APQ8036) }, { qcom_board_id(APQ8039) }, + { qcom_board_id(MSM8236) }, + { qcom_board_id(MSM8636) }, + { qcom_board_id(MSM8909) }, { qcom_board_id(MSM8996) }, { qcom_board_id(APQ8016) }, { qcom_board_id(MSM8216) }, { qcom_board_id(MSM8116) }, { qcom_board_id(MSM8616) }, { qcom_board_id(MSM8992) }, + { qcom_board_id(APQ8092) }, { qcom_board_id(APQ8094) }, + { qcom_board_id(MSM8209) }, + { qcom_board_id(MSM8208) }, + { qcom_board_id(MDM9209) }, + { qcom_board_id(MDM9309) }, + { qcom_board_id(MDM9609) }, + { qcom_board_id(MSM8239) }, + { qcom_board_id(MSM8952) }, + { qcom_board_id(APQ8009) }, + { qcom_board_id(MSM8956) }, + { qcom_board_id(MSM8929) }, + { qcom_board_id(MSM8629) }, + { qcom_board_id(MSM8229) }, + { qcom_board_id(APQ8029) }, + { qcom_board_id(APQ8056) }, + { qcom_board_id(MSM8609) }, + { qcom_board_id(APQ8076) }, + { qcom_board_id(MSM8976) }, + { qcom_board_id(MDM9650) }, + { qcom_board_id(MDM9655) }, + { qcom_board_id(MDM9250) }, + { qcom_board_id(MDM9255) }, + { qcom_board_id(MDM9350) }, + { qcom_board_id(APQ8052) }, { qcom_board_id(MDM9607) }, { qcom_board_id(APQ8096) }, { qcom_board_id(MSM8998) }, { qcom_board_id(MSM8953) }, + { qcom_board_id(MSM8937) }, + { qcom_board_id(APQ8037) }, { qcom_board_id(MDM8207) }, { qcom_board_id(MDM9207) }, { qcom_board_id(MDM9307) }, { qcom_board_id(MDM9628) }, + { qcom_board_id(MSM8909W) }, + { qcom_board_id(APQ8009W) }, + { qcom_board_id(MSM8996L) }, + { qcom_board_id(MSM8917) }, { qcom_board_id(APQ8053) }, { qcom_board_id(MSM8996SG) }, + { qcom_board_id(APQ8017) }, + { qcom_board_id(MSM8217) }, + { qcom_board_id(MSM8617) }, { qcom_board_id(MSM8996AU) }, { qcom_board_id(APQ8096AU) }, { qcom_board_id(APQ8096SG) }, + { qcom_board_id(MSM8940) }, + { qcom_board_id(SDX201) }, { qcom_board_id(SDM660) }, { qcom_board_id(SDM630) }, { qcom_board_id(APQ8098) }, + { qcom_board_id(MSM8920) }, { qcom_board_id(SDM845) }, { qcom_board_id(MDM9206) }, { qcom_board_id(IPQ8074) }, @@ -306,6 +377,8 @@ static const struct soc_id soc_id[] = { { qcom_board_id(SDM658) }, { qcom_board_id(SDA658) }, { qcom_board_id(SDA630) }, + { qcom_board_id(MSM8905) }, + { qcom_board_id(SDX202) }, { qcom_board_id(SDM450) }, { qcom_board_id(SM8150) }, { qcom_board_id(SDA845) }, @@ -317,10 +390,15 @@ static const struct soc_id soc_id[] = { { qcom_board_id(SDM632) }, { qcom_board_id(SDA632) }, { qcom_board_id(SDA450) }, + { qcom_board_id(SDM439) }, + { qcom_board_id(SDM429) }, { qcom_board_id(SM8250) }, { qcom_board_id(SA8155) }, + { qcom_board_id(SDA439) }, + { qcom_board_id(SDA429) }, { qcom_board_id(IPQ8070) }, { qcom_board_id(IPQ8071) }, + { qcom_board_id(QM215) }, { qcom_board_id(IPQ8072A) }, { qcom_board_id(IPQ8074A) }, { qcom_board_id(IPQ8076A) }, @@ -330,18 +408,20 @@ static const struct soc_id soc_id[] = { { qcom_board_id(IPQ8071A) }, { qcom_board_id(IPQ6018) }, { qcom_board_id(IPQ6028) }, + { qcom_board_id(SDM429W) }, { qcom_board_id(SM4250) }, { qcom_board_id(IPQ6000) }, { qcom_board_id(IPQ6010) }, { qcom_board_id(SC7180) }, { qcom_board_id(SM6350) }, + { qcom_board_id(QCM2150) }, + { qcom_board_id(SDA429W) }, { qcom_board_id(SM8350) }, { qcom_board_id(SM6115) }, { qcom_board_id(SC8280XP) }, { qcom_board_id(IPQ6005) }, { qcom_board_id(QRB5165) }, { qcom_board_id(SM8450) }, - { qcom_board_id(SM8550) }, { qcom_board_id(SM7225) }, { qcom_board_id(SA8295P) }, { qcom_board_id(SA8540P) }, @@ -352,6 +432,7 @@ static const struct soc_id soc_id[] = { { qcom_board_id(SC7280) }, { qcom_board_id(SC7180P) }, { qcom_board_id(SM6375) }, + { qcom_board_id(SM8550) }, { qcom_board_id(QRU1000) }, { qcom_board_id(QDU1000) }, { qcom_board_id(QDU1010) }, @@ -512,6 +593,15 @@ static void socinfo_debugfs_init(struct qcom_socinfo *qcom_socinfo, &qcom_socinfo->info.fmt); switch (qcom_socinfo->info.fmt) { + case SOCINFO_VERSION(0, 16): + qcom_socinfo->info.feature_code = __le32_to_cpu(info->feature_code); + qcom_socinfo->info.pcode = __le32_to_cpu(info->pcode); + + debugfs_create_u32("feature_code", 0444, qcom_socinfo->dbg_root, + &qcom_socinfo->info.feature_code); + debugfs_create_u32("pcode", 0444, qcom_socinfo->dbg_root, + &qcom_socinfo->info.pcode); + fallthrough; case SOCINFO_VERSION(0, 15): qcom_socinfo->info.nmodem_supported = __le32_to_cpu(info->nmodem_supported); |