diff --git a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml index f3f3feac4ce2..335a8e1a5a9e 100644 --- a/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml +++ b/Documentation/devicetree/bindings/arm/qcom,coresight-ctcu.yaml @@ -32,6 +32,7 @@ properties: - qcom,glymur-ctcu - qcom,kaanapali-ctcu - qcom,qcs8300-ctcu + - qcom,shikra-ctcu - qcom,sm8750-ctcu - qcom,x1e80100-ctcu - const: qcom,sa8775p-ctcu diff --git a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml index 037d4ad8f718..ecee5aef65a7 100644 --- a/Documentation/devicetree/bindings/firmware/qcom,scm.yaml +++ b/Documentation/devicetree/bindings/firmware/qcom,scm.yaml @@ -37,6 +37,7 @@ properties: - qcom,scm-ipq9574 - qcom,scm-ipq9650 - qcom,scm-kaanapali + - qcom,scm-kuno - qcom,scm-maili - qcom,scm-mdm9607 - qcom,scm-milos diff --git a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml index 21b4e04727de..f6969910bded 100644 --- a/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml +++ b/Documentation/devicetree/bindings/interconnect/qcom,msm8998-bwmon.yaml @@ -50,6 +50,7 @@ properties: - enum: - qcom,eliza-llcc-bwmon - qcom,hawi-llcc-bwmon + - qcom,milos-cpu-bwmon - qcom,qcs615-llcc-bwmon - qcom,qcs8300-llcc-bwmon - qcom,sa8775p-llcc-bwmon diff --git a/MAINTAINERS b/MAINTAINERS index 5b722dba5395..7b6166c1b8fa 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -3432,6 +3432,7 @@ F: include/linux/soc/qcom/ ARM/QUALCOMM SUPPORT M: Bjorn Andersson M: Konrad Dybcio +R: Abel Vesa L: linux-arm-msm@vger.kernel.org S: Maintained C: irc://irc.oftc.net/linux-msm diff --git a/drivers/firmware/qcom/Kconfig b/drivers/firmware/qcom/Kconfig index c7f8413ab996..691db0ded8e8 100644 --- a/drivers/firmware/qcom/Kconfig +++ b/drivers/firmware/qcom/Kconfig @@ -7,7 +7,7 @@ menu "Qualcomm firmware drivers" config QCOM_PAS - tristate "Qualcomm generic PAS interface driver" + tristate "Qualcomm generic PAS interface driver" if COMPILE_TEST help Enable the generic Peripheral Authentication Service (PAS) provided by the firmware. It acts as the common layer with different TZ @@ -16,6 +16,7 @@ config QCOM_PAS config QCOM_PAS_TEE tristate "Qualcomm PAS TEE interface driver" + depends on ARCH_QCOM || COMPILE_TEST select QCOM_PAS depends on TEE depends on !CPU_BIG_ENDIAN @@ -26,6 +27,7 @@ config QCOM_PAS_TEE config QCOM_SCM tristate "Qualcomm PAS SCM interface driver" + depends on ARCH_QCOM || COMPILE_TEST select QCOM_PAS select QCOM_TZMEM default y if ARCH_QCOM diff --git a/drivers/firmware/qcom/qcom_scm.c b/drivers/firmware/qcom/qcom_scm.c index 363362a59b5a..df20773dd754 100644 --- a/drivers/firmware/qcom/qcom_scm.c +++ b/drivers/firmware/qcom/qcom_scm.c @@ -2217,6 +2217,7 @@ EXPORT_SYMBOL_GPL(qcom_scm_qseecom_app_send); static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "asus,vivobook-s15" }, { .compatible = "asus,vivobook-s15-x1p4" }, + { .compatible = "asus,zenbook-a14-ux3407na" }, { .compatible = "asus,zenbook-a14-ux3407qa" }, { .compatible = "asus,zenbook-a14-ux3407ra" }, { .compatible = "asus,zenbook-a16-ux3607oa" }, @@ -2226,6 +2227,7 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "ecs,liva-qc710" }, { .compatible = "honor,magicbook-art-14-snapdragon" }, { .compatible = "hp,elitebook-ultra-g1q" }, + { .compatible = "hp,elitebook-x-g2q" }, { .compatible = "hp,omnibook-x14" }, { .compatible = "huawei,gaokun3" }, { .compatible = "lenovo,flex-5g" }, @@ -2234,6 +2236,7 @@ static const struct of_device_id qcom_scm_qseecom_allowlist[] __maybe_unused = { { .compatible = "lenovo,thinkpad-t14s" }, { .compatible = "lenovo,thinkpad-x13s", }, { .compatible = "lenovo,yoga-slim7x" }, + { .compatible = "lenovo,yoga-slim7x-gen11" }, { .compatible = "medion,sprchrgd14s1" }, { .compatible = "microsoft,arcata", }, { .compatible = "microsoft,surface-pro-12in", }, @@ -2759,17 +2762,15 @@ static int qcom_scm_probe(struct platform_device *pdev) if (ret) return ret; - ret = of_reserved_mem_device_init(scm->dev); + ret = devm_of_reserved_mem_device_init(scm->dev); if (ret && ret != -ENODEV) return dev_err_probe(scm->dev, ret, "Failed to setup the reserved memory region for TZ mem\n"); ret = qcom_tzmem_enable(scm->dev); - if (ret) { - ret = dev_err_probe(scm->dev, ret, - "Failed to enable the TrustZone memory allocator\n"); - goto err_rmem; - } + if (ret) + return dev_err_probe(scm->dev, ret, + "Failed to enable the TrustZone memory allocator\n"); memset(&pool_config, 0, sizeof(pool_config)); pool_config.initial_size = 0; @@ -2777,11 +2778,9 @@ static int qcom_scm_probe(struct platform_device *pdev) pool_config.max_size = SZ_256K; scm->mempool = devm_qcom_tzmem_pool_new(scm->dev, &pool_config); - if (IS_ERR(scm->mempool)) { - ret = dev_err_probe(scm->dev, PTR_ERR(scm->mempool), - "Failed to create the SCM memory pool\n"); - goto err_rmem; - } + if (IS_ERR(scm->mempool)) + return dev_err_probe(scm->dev, PTR_ERR(scm->mempool), + "Failed to create the SCM memory pool\n"); ret = qcom_scm_query_waitq_count(scm); scm->wq_cnt = ret < 0 ? QCOM_SCM_DEFAULT_WAITQ_COUNT : ret; @@ -2857,10 +2856,6 @@ static int qcom_scm_probe(struct platform_device *pdev) qcom_scm_gunyah_wdt_init(scm); return 0; - -err_rmem: - of_reserved_mem_device_release(scm->dev); - return ret; } static void qcom_scm_shutdown(struct platform_device *pdev) diff --git a/drivers/soc/qcom/Kconfig b/drivers/soc/qcom/Kconfig index 2b524154d9fb..9f703261d7ac 100644 --- a/drivers/soc/qcom/Kconfig +++ b/drivers/soc/qcom/Kconfig @@ -39,7 +39,6 @@ config QCOM_COMMAND_DB config QCOM_GENI_SE tristate "Qualcomm GENI Serial Engine Driver" - depends on ARM64 || COMPILE_TEST default ARCH_QCOM help This driver is used to manage Generic Interface (GENI) firmware based diff --git a/drivers/soc/qcom/apr.c b/drivers/soc/qcom/apr.c index ea7f83916d8d..2d5645ff9919 100644 --- a/drivers/soc/qcom/apr.c +++ b/drivers/soc/qcom/apr.c @@ -338,29 +338,6 @@ static void apr_rxwq(struct work_struct *work) } } -static int apr_device_match(struct device *dev, const struct device_driver *drv) -{ - struct apr_device *adev = to_apr_device(dev); - const struct apr_driver *adrv = to_apr_driver(drv); - const struct apr_device_id *id = adrv->id_table; - - /* Attempt an OF style match first */ - if (of_driver_match_device(dev, drv)) - return 1; - - if (!id) - return 0; - - while (id->domain_id != 0 || id->svc_id != 0) { - if (id->domain_id == adev->domain_id && - id->svc_id == adev->svc.id) - return 1; - id++; - } - - return 0; -} - static int apr_device_probe(struct device *dev) { struct apr_device *adev = to_apr_device(dev); @@ -401,7 +378,7 @@ static int apr_uevent(const struct device *dev, struct kobj_uevent_env *env) const struct bus_type aprbus = { .name = "aprbus", - .match = apr_device_match, + .match = of_driver_match_device, .probe = apr_device_probe, .uevent = apr_uevent, .remove = apr_device_remove, @@ -434,31 +411,35 @@ static int apr_add_device(struct device *dev, struct device_node *np, if (np) snprintf(adev->name, APR_NAME_SIZE, "%pOFn", np); - switch (apr->type) { - case PR_TYPE_APR: - dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name, - domain_id, svc_id); - break; - case PR_TYPE_GPR: - dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name, - domain_id, svc_id); - break; - default: - break; - } - adev->dev.bus = &aprbus; adev->dev.parent = dev; adev->dev.of_node = np; adev->dev.release = apr_dev_release; adev->dev.driver = NULL; + device_initialize(&adev->dev); + + switch (apr->type) { + case PR_TYPE_APR: + ret = dev_set_name(&adev->dev, "aprsvc:%s:%x:%x", adev->name, + domain_id, svc_id); + break; + case PR_TYPE_GPR: + ret = dev_set_name(&adev->dev, "gprsvc:%s:%x:%x", adev->name, + domain_id, svc_id); + break; + default: + ret = -EINVAL; + break; + } + if (ret) + goto out_put_device; spin_lock(&apr->svcs_lock); ret = idr_alloc(&apr->svcs_idr, svc, svc_id, svc_id + 1, GFP_ATOMIC); spin_unlock(&apr->svcs_lock); if (ret < 0) { dev_err(dev, "idr_alloc failed: %d\n", ret); - goto out; + goto out_put_device; } /* Protection domain is optional, it does not exist on older platforms */ @@ -466,18 +447,26 @@ static int apr_add_device(struct device *dev, struct device_node *np, 1, &adev->service_path); if (ret < 0 && ret != -EINVAL) { dev_err(dev, "Failed to read second value of qcom,protection-domain\n"); - goto out; + goto out_remove_idr; } dev_info(dev, "Adding APR/GPR dev: %s\n", dev_name(&adev->dev)); - ret = device_register(&adev->dev); + ret = device_add(&adev->dev); if (ret) { - dev_err(dev, "device_register failed: %d\n", ret); - put_device(&adev->dev); + dev_err(dev, "device_add failed: %d\n", ret); + goto out_remove_idr; } -out: + return 0; + +out_remove_idr: + spin_lock(&apr->svcs_lock); + idr_remove(&apr->svcs_idr, svc_id); + spin_unlock(&apr->svcs_lock); + flush_workqueue(apr->rxwq); +out_put_device: + put_device(&adev->dev); return ret; } diff --git a/drivers/soc/qcom/llcc-qcom.c b/drivers/soc/qcom/llcc-qcom.c index 733999867bbf..5e45a10663c4 100644 --- a/drivers/soc/qcom/llcc-qcom.c +++ b/drivers/soc/qcom/llcc-qcom.c @@ -626,11 +626,11 @@ static const struct llcc_slice_config glymur_data[] = { static const struct llcc_slice_config ipq5424_data[] = { { - .usecase_id = LLCC_CPUSS, + .usecase_id = LLCC_PPE_RXDESC, .slice_id = 1, - .max_cap = 768, - .priority = 1, - .bonus_ways = 0xFFFF, + .max_cap = 128, + .priority = 3, + .bonus_ways = 0x0FFF, .retain_on_pc = true, .activate_on_init = true, .write_scid_cacheable_en = true, @@ -642,12 +642,52 @@ static const struct llcc_slice_config ipq5424_data[] = { .vict_prio = true, }, { - .usecase_id = LLCC_VIDSC0, + .usecase_id = LLCC_CPUSS, .slice_id = 2, - .max_cap = 256, - .priority = 2, + .max_cap = 768, + .priority = 1, .fixed_size = true, - .bonus_ways = 0xF000, + .bonus_ways = 0x0FFF, + .retain_on_pc = true, + .activate_on_init = true, + .write_scid_cacheable_en = true, + .stale_en = true, + .stale_cap_en = true, + }, + { + .usecase_id = LLCC_PPE_RXFILL, + .slice_id = 5, + .max_cap = 128, + .priority = 3, + .bonus_ways = 0x0FFF, + .retain_on_pc = true, + .activate_on_init = true, + .write_scid_cacheable_en = true, + .stale_en = true, + .stale_cap_en = true, + .alloc_oneway_en = true, + .ovcap_en = true, + .ovcap_prio = true, + .vict_prio = true, + }, + { + .usecase_id = LLCC_WLAN_5G, + .slice_id = 6, + .max_cap = 128, + .priority = 3, + .bonus_ways = 0xC000, + .retain_on_pc = true, + .activate_on_init = true, + .write_scid_cacheable_en = true, + .stale_en = true, + .stale_cap_en = true, + }, + { + .usecase_id = LLCC_WLAN_6G, + .slice_id = 7, + .max_cap = 128, + .priority = 3, + .bonus_ways = 0x3000, .retain_on_pc = true, .activate_on_init = true, .write_scid_cacheable_en = true, @@ -5617,6 +5657,10 @@ static int qcom_llcc_probe(struct platform_device *pdev) } drv_data->ecc_irq = platform_get_irq_optional(pdev, 0); + if (drv_data->ecc_irq < 0 && drv_data->ecc_irq != -ENXIO) + return dev_err_probe(&pdev->dev, drv_data->ecc_irq, + "failed to get IRQ resource\n"); + drv_data->edac_reg_offset = cfg->edac_reg_offset; drv_data->ecc_irq_configured = cfg->irq_configured; drv_data->dev = dev; diff --git a/drivers/soc/qcom/pmic_glink_altmode.c b/drivers/soc/qcom/pmic_glink_altmode.c index 13c434f8d03a..465e5d2316a0 100644 --- a/drivers/soc/qcom/pmic_glink_altmode.c +++ b/drivers/soc/qcom/pmic_glink_altmode.c @@ -451,7 +451,7 @@ static void pmic_glink_altmode_sc8180xp_notify(struct pmic_glink_altmode *altmod alt_port->mode = mode; alt_port->hpd_state = hpd_state; alt_port->hpd_irq = hpd_irq; - schedule_work(&alt_port->work); + queue_work(system_freezable_wq, &alt_port->work); } #define SC8280XP_DPAM_MASK 0x3f @@ -502,7 +502,7 @@ static void pmic_glink_altmode_sc8280xp_notify(struct pmic_glink_altmode *altmod alt_port->tbt_data = *tbt; } - schedule_work(&alt_port->work); + queue_work(system_freezable_wq, &alt_port->work); } static void pmic_glink_altmode_callback(const void *data, size_t len, void *priv) diff --git a/drivers/soc/qcom/qcom-geni-se.c b/drivers/soc/qcom/qcom-geni-se.c index 873bfbd6b2b7..6ac2bdc16984 100644 --- a/drivers/soc/qcom/qcom-geni-se.c +++ b/drivers/soc/qcom/qcom-geni-se.c @@ -1230,25 +1230,28 @@ EXPORT_SYMBOL_GPL(geni_se_resources_init); * @se: Pointer to the serial engine structure. * @fw: Pointer to the firmware image. * @protocol: Expected serial engine protocol type. + * @fw_size_out: Non-NULL output parameter; receives the rounded, validated + * firmware word count on success. * * Identifies the appropriate firmware image or configuration required for a * specific communication protocol instance running on a Qualcomm GENI * controller. Validates the firmware size against the hardware PROG_RAM_DEPTH * read from SE_HW_PARAM_2. * - * Return: pointer to a valid 'struct se_fw_hdr' if found, or NULL otherwise. + * Return: pointer to a valid 'const struct se_fw_hdr' if found, or NULL otherwise. */ -static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct firmware *fw, - enum geni_se_protocol_type protocol) +static const struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct firmware *fw, + enum geni_se_protocol_type protocol, + u32 *fw_size_out) { struct device *dev = se->dev; const struct elf32_hdr *ehdr; const struct elf32_phdr *phdrs; const struct elf32_phdr *phdr; - struct se_fw_hdr *sefw; + const struct se_fw_hdr *sefw; u32 fw_end, cfg_idx_end, cfg_val_end; u32 prog_ram_depth; - u16 fw_size; + u32 fw_size; int i; if (!fw || fw->size < sizeof(struct elf32_hdr)) @@ -1287,25 +1290,24 @@ static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct if (phdr->p_filesz < sizeof(struct se_fw_hdr)) continue; - sefw = (struct se_fw_hdr *)(fw->data + phdr->p_offset); + sefw = (const struct se_fw_hdr *)(fw->data + phdr->p_offset); fw_size = le16_to_cpu(sefw->fw_size_in_items); + + if (le32_to_cpu(sefw->magic) != SE_MAGIC_NUM || le32_to_cpu(sefw->version) != 1) + continue; + + if (le16_to_cpu(sefw->serial_protocol) != protocol) + continue; + + if (fw_size % 2 != 0) + fw_size++; + fw_end = le16_to_cpu(sefw->fw_offset) + fw_size * sizeof(u32); cfg_idx_end = le16_to_cpu(sefw->cfg_idx_offset) + le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u8); cfg_val_end = le16_to_cpu(sefw->cfg_val_offset) + le16_to_cpu(sefw->cfg_size_in_items) * sizeof(u32); - if (le32_to_cpu(sefw->magic) != SE_MAGIC_NUM || le32_to_cpu(sefw->version) != 1) - continue; - - if (le32_to_cpu(sefw->serial_protocol) != protocol) - continue; - - if (fw_size % 2 != 0) { - fw_size++; - sefw->fw_size_in_items = cpu_to_le16(fw_size); - } - prog_ram_depth = FIELD_GET(PROG_RAM_DEPTH_MSK, readl_relaxed(se->base + SE_HW_PARAM_2)); if (fw_size >= prog_ram_depth) { @@ -1320,6 +1322,7 @@ static struct se_fw_hdr *geni_find_protocol_fw(struct geni_se *se, const struct continue; } + *fw_size_out = fw_size; return sefw; } @@ -1430,17 +1433,17 @@ static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw, { const u32 *fw_data, *cfg_val_arr; const u8 *cfg_idx_arr; - u32 i, reg_value; + u32 i, reg_value, fw_size_in_items; int ret; - struct se_fw_hdr *hdr; + const struct se_fw_hdr *hdr; - hdr = geni_find_protocol_fw(se, fw, protocol); + hdr = geni_find_protocol_fw(se, fw, protocol, &fw_size_in_items); if (!hdr) return -EINVAL; - fw_data = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->fw_offset)); + fw_data = (const u32 *)((const u8 *)hdr + le16_to_cpu(hdr->fw_offset)); cfg_idx_arr = (const u8 *)hdr + le16_to_cpu(hdr->cfg_idx_offset); - cfg_val_arr = (const u32 *)((u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset)); + cfg_val_arr = (const u32 *)((const u8 *)hdr + le16_to_cpu(hdr->cfg_val_offset)); ret = geni_icc_set_bw(se); if (ret) @@ -1511,7 +1514,7 @@ static int geni_load_se_fw(struct geni_se *se, const struct firmware *fw, /* Program RAM address space. */ memcpy_toio(se->base + SE_GENI_CFG_RAMN, fw_data, - le16_to_cpu(hdr->fw_size_in_items) * sizeof(u32)); + fw_size_in_items * sizeof(u32)); /* Put default values on GENI's output pads. */ writel_relaxed(0x1, se->base + GENI_FORCE_DEFAULT_REG); diff --git a/drivers/soc/qcom/qcom_aoss.c b/drivers/soc/qcom/qcom_aoss.c index 259c41f0c34e..a6b673cd7678 100644 --- a/drivers/soc/qcom/qcom_aoss.c +++ b/drivers/soc/qcom/qcom_aoss.c @@ -602,10 +602,8 @@ static int qmp_probe(struct platform_device *pdev) irq = platform_get_irq(pdev, 0); ret = devm_request_irq(&pdev->dev, irq, qmp_intr, 0, "aoss-qmp", qmp); - if (ret < 0) { - dev_err(&pdev->dev, "failed to request interrupt\n"); + if (ret < 0) goto err_free_mbox; - } ret = qmp_open(qmp); if (ret < 0) diff --git a/drivers/soc/qcom/rpmh-internal.h b/drivers/soc/qcom/rpmh-internal.h index e3cf1beff803..39441a25af9b 100644 --- a/drivers/soc/qcom/rpmh-internal.h +++ b/drivers/soc/qcom/rpmh-internal.h @@ -20,7 +20,7 @@ struct rsc_drv; /** - * struct tcs_group: group of Trigger Command Sets (TCS) to send state requests + * struct tcs_group - group of Trigger Command Sets (TCS) to send state requests * to the controller * * @drv: The controller. @@ -53,7 +53,7 @@ struct tcs_group { }; /** - * struct rpmh_request: the message to be sent to rpmh-rsc + * struct rpmh_request - the message to be sent to rpmh-rsc * * @msg: the request * @cmd: the payload that will be part of the @msg @@ -70,7 +70,7 @@ struct rpmh_request { }; /** - * struct rpmh_ctrlr: our representation of the controller + * struct rpmh_ctrlr - our representation of the controller * * @cache: the list of cached requests * @cache_lock: synchronize access to the cache data @@ -84,13 +84,19 @@ struct rpmh_ctrlr { struct list_head batch_cache; }; +/** + * struct rsc_ver - Hardware version of the RSC controller. + * + * @major: Major version number. + * @minor: Minor version number. + */ struct rsc_ver { u32 major; u32 minor; }; /** - * struct rsc_drv: the Direct Resource Voter (DRV) of the + * struct rsc_drv - the Direct Resource Voter (DRV) of the * Resource State Coordinator controller (RSC) * * @name: Controller identifier. @@ -116,6 +122,8 @@ struct rsc_ver { * slot * @client: Handle to the DRV's client. * @dev: RSC device. + * @ver: HW version of the RSC controller. + * @regs: Pointer to the register offset table for this version. */ struct rsc_drv { const char *name; diff --git a/drivers/soc/qcom/rpmh-rsc.c b/drivers/soc/qcom/rpmh-rsc.c index f881af35ecfc..c4542318eac4 100644 --- a/drivers/soc/qcom/rpmh-rsc.c +++ b/drivers/soc/qcom/rpmh-rsc.c @@ -842,7 +842,7 @@ void rpmh_rsc_write_next_wakeup(struct rsc_drv *drv) } /** - * rpmh_rsc_cpu_pm_callback() - Check if any of the AMCs are busy. + * rpmh_rsc_cpu_pm_callback() - CPU PM notifier to flush sleep/wake TCS data. * @nfb: Pointer to the notifier block in struct rsc_drv. * @action: CPU_PM_ENTER, CPU_PM_ENTER_FAILED, or CPU_PM_EXIT. * @v: Unused @@ -923,7 +923,7 @@ static int rpmh_rsc_cpu_pm_callback(struct notifier_block *nfb, } /** - * rpmh_rsc_pd_callback() - Check if any of the AMCs are busy. + * rpmh_rsc_pd_callback() - PM domain callback to flush sleep/wake TCS data. * @nfb: Pointer to the genpd notifier block in struct rsc_drv. * @action: GENPD_NOTIFY_PRE_OFF, GENPD_NOTIFY_OFF, GENPD_NOTIFY_PRE_ON or GENPD_NOTIFY_ON. * @v: Unused diff --git a/drivers/soc/qcom/rpmh.c b/drivers/soc/qcom/rpmh.c index f881c4c757ec..360242a315e3 100644 --- a/drivers/soc/qcom/rpmh.c +++ b/drivers/soc/qcom/rpmh.c @@ -41,7 +41,7 @@ #define ctrlr_to_drv(ctrlr) container_of(ctrlr, struct rsc_drv, client) /** - * struct cache_req: the request object for caching + * struct cache_req - the request object for caching * * @addr: the address of the resource * @sleep_val: the sleep vote @@ -56,7 +56,7 @@ struct cache_req { }; /** - * struct batch_cache_req - An entry in our batch catch + * struct batch_cache_req - An entry in our batch cache * * @list: linked list obj * @count: number of messages @@ -76,6 +76,14 @@ static struct rpmh_ctrlr *get_rpmh_ctrlr(const struct device *dev) return &drv->client; } +/** + * rpmh_tx_done() - Signal the completion of a RPMH transfer. + * @msg: The request that was previously sent. + * + * Called by the RSC driver when an active-only transfer is complete. + * Signals any blocking waiter and frees the message if it was dynamically + * allocated. + */ void rpmh_tx_done(const struct tcs_request *msg) { struct rpmh_request *rpm_msg = container_of(msg, struct rpmh_request, @@ -157,7 +165,7 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, } /** - * __rpmh_write: Cache and send the RPMH request + * __rpmh_write() - Cache and send the RPMH request. * * @dev: The device making the request * @state: Active/Sleep request type @@ -166,6 +174,8 @@ static struct cache_req *cache_rpm_request(struct rpmh_ctrlr *ctrlr, * Cache the RPMH request and send if the state is ACTIVE_ONLY. * SLEEP/WAKE_ONLY requests are not sent to the controller at * this time. Use rpmh_flush() to send them to the controller. + * + * Return: 0 on success, negative error code on failure. */ static int __rpmh_write(const struct device *dev, enum rpmh_state state, struct rpmh_request *rpm_msg) @@ -248,7 +258,7 @@ int rpmh_read(const struct device *dev, struct tcs_cmd *cmd) EXPORT_SYMBOL_GPL(rpmh_read); /** - * rpmh_write_async: Write a set of RPMH commands + * rpmh_write_async() - Write a set of RPMH commands. * * @dev: The device making the request * @state: Active/sleep set @@ -257,6 +267,8 @@ EXPORT_SYMBOL_GPL(rpmh_read); * * Write a set of RPMH commands, the order of commands is maintained * and will be sent as a single shot. + * + * Return: 0 on success, negative error code on failure. */ int rpmh_write_async(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) @@ -280,7 +292,7 @@ int rpmh_write_async(const struct device *dev, enum rpmh_state state, EXPORT_SYMBOL_GPL(rpmh_write_async); /** - * rpmh_write: Write a set of RPMH commands and block until response + * rpmh_write() - Write a set of RPMH commands and block until response * * @dev: The device making the request * @state: Active/sleep set @@ -288,6 +300,8 @@ EXPORT_SYMBOL_GPL(rpmh_write_async); * @n: The number of elements in @cmd * * May sleep. Do not call from atomic contexts. + * + * Return: 0 on success, negative error code on failure. */ int rpmh_write(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 n) @@ -342,7 +356,7 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr) } /** - * rpmh_write_batch: Write multiple sets of RPMH commands and wait for the + * rpmh_write_batch() - Write multiple sets of RPMH commands and wait for the * batch to finish. * * @dev: the device making the request @@ -350,13 +364,15 @@ static int flush_batch(struct rpmh_ctrlr *ctrlr) * @cmd: The payload data * @n: The array of count of elements in each batch, 0 terminated. * - * Write a request to the RSC controller without caching. If the request - * state is ACTIVE, then the requests are treated as completion request - * and sent to the controller immediately. The function waits until all the - * commands are complete. If the request was to SLEEP or WAKE_ONLY, then the - * request is sent as fire-n-forget and no ack is expected. + * If the request state is ACTIVE_ONLY, the requests are sent to the + * controller immediately and the function waits until all commands are + * complete. If the state is SLEEP or WAKE_ONLY, the requests are cached + * and the function returns immediately; they are sent to the controller + * later by rpmh_flush(). * * May sleep. Do not call from atomic contexts for ACTIVE_ONLY requests. + * + * Return: 0 on success, negative error code on failure. */ int rpmh_write_batch(const struct device *dev, enum rpmh_state state, const struct tcs_cmd *cmd, u32 *n) @@ -519,7 +535,7 @@ int rpmh_flush(struct rpmh_ctrlr *ctrlr) } /** - * rpmh_invalidate: Invalidate sleep and wake sets in batch_cache + * rpmh_invalidate() - Invalidate sleep and wake sets in batch_cache * * @dev: The device making the request * diff --git a/drivers/soc/qcom/smem_dramc.c b/drivers/soc/qcom/smem_dramc.c index 63ebe7f6db59..497513c95308 100644 --- a/drivers/soc/qcom/smem_dramc.c +++ b/drivers/soc/qcom/smem_dramc.c @@ -20,12 +20,22 @@ #define MAX_DDR_FREQ_NUM_V5 14 #define MAX_CHAN_NUM 8 +#define MAX_CHAN_NUM_V7_GLYMUR 16 #define MAX_RANK_NUM 2 #define DDR_HBB_MIN 13 #define DDR_HBB_MAX 19 #define MAX_SHUB_ENTRIES 8 +#define MAX_SHUB_ENTRIES_V7_GLYMUR 10 +#define MAX_DDR_REGIONS_V7_GLYMUR 4 + +/* + * Glymur's DRAM information entry has 256 bytes of trailing zeroes + * after its DDR details, four region slots, 10-entry SHUB frequency + * plan, and v6 misc information. + */ +#define DDR_V7_GLYMUR_RESERVED_SIZE 256 static struct smem_dram *__dram; @@ -39,6 +49,7 @@ enum ddr_info_version { INFO_V6, /* INFO_V6 seems to only have shipped with 6 DDR regions, unlike V7 */ INFO_V7, INFO_V7_WITH_6_REGIONS, + INFO_V7_GLYMUR, }; struct smem_dram { @@ -188,6 +199,37 @@ struct ddr_details_v7 { struct ddr_regions_v5 ddr_regions; }; +struct ddr_regions_v7_glymur { + __le32 ddr_region_num; + __le64 ddr_rank0_size; + __le64 ddr_rank1_size; + __le64 ddr_cs0_start_addr; + __le64 ddr_cs1_start_addr; + __le32 highest_bank_addr_bit; + struct ddr_region_v5 ddr_region[MAX_DDR_REGIONS_V7_GLYMUR]; +}; + +struct ddr_details_v7_glymur { + u8 manufacturer_id; + u8 device_type; + struct ddr_part_details ddr_params[MAX_CHAN_NUM_V7_GLYMUR]; + struct ddr_freq_plan_v5 ddr_freq_tbl; + u8 num_channels; + u8 sct_config; + struct ddr_regions_v7_glymur ddr_regions; +}; + +struct shub_freq_plan_entry_v7_glymur { + u8 num_shub_freqs; + struct shub_freq_table shub_freq[MAX_SHUB_ENTRIES_V7_GLYMUR]; +}; + +struct ddr_v7_glymur_tail { + struct shub_freq_plan_entry_v7_glymur shub_freq_plan; + struct ddr_misc_info_v6 misc_info; + u8 reserved[DDR_V7_GLYMUR_RESERVED_SIZE]; +}; + /** * qcom_smem_dram_get_hbb(): Get the Highest bank address bit * @@ -219,7 +261,7 @@ static void smem_dram_parse_v3_data(struct smem_dram *dram, void *data) if (freq_entry->freq_khz && freq_entry->enabled) { u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); - dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz; + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; } } } @@ -231,8 +273,11 @@ static void smem_dram_parse_v3_14freqs_data(struct smem_dram *dram, void *data) for (int i = 0; i < MAX_DDR_FREQ_NUM_V3 + 1; i++) { struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i]; - if (freq_entry->freq_khz && freq_entry->enabled) - dram->frequencies[dram->num_frequencies++] = 1000 * freq_entry->freq_khz; + if (freq_entry->freq_khz && freq_entry->enabled) { + u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); + + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; + } } } @@ -248,7 +293,7 @@ static void smem_dram_parse_v4_data(struct smem_dram *dram, void *data) if (freq_entry->freq_khz && freq_entry->enabled) { u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); - dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz; + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; } } } @@ -265,7 +310,7 @@ static void smem_dram_parse_v5_data(struct smem_dram *dram, void *data) if (freq_entry->freq_khz && freq_entry->enabled) { u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); - dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz; + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; } } } @@ -282,6 +327,23 @@ static void smem_dram_parse_v7_data(struct smem_dram *dram, void *data) if (freq_entry->freq_khz && freq_entry->enabled) { u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); + dram->frequencies[dram->num_frequencies++] = 1000UL * freq_khz; + } + } +} + +static void smem_dram_parse_v7_glymur_data(struct smem_dram *dram, void *data) +{ + struct ddr_details_v7_glymur *details = data; + + dram->hbb = le32_to_cpu(details->ddr_regions.highest_bank_addr_bit); + + for (int i = 0; i < MAX_DDR_FREQ_NUM_V5; i++) { + struct ddr_freq_table *freq_entry = &details->ddr_freq_tbl.ddr_freq[i]; + + if (freq_entry->freq_khz && freq_entry->enabled) { + u32 freq_khz = le32_to_cpu(freq_entry->freq_khz); + dram->frequencies[dram->num_frequencies++] = 1000 * freq_khz; } } @@ -341,6 +403,10 @@ static int smem_dram_infer_struct_version(size_t size) sizeof(struct shub_freq_plan_entry)) return INFO_V7_WITH_6_REGIONS; + if (size == sizeof(struct ddr_details_v7_glymur) + + sizeof(struct ddr_v7_glymur_tail)) + return INFO_V7_GLYMUR; + return INFO_UNKNOWN; } @@ -382,7 +448,7 @@ struct dentry *smem_dram_parse(struct qcom_smem *smem, struct device *dev) return ERR_PTR(-ENODATA); ver = smem_dram_infer_struct_version(actual_size); - if (ver < 0) { + if ((int)ver < 0) { /* Some SoCs don't provide data that's useful for us */ return ERR_PTR(-ENODATA); } else if (ver == INFO_UNKNOWN) { @@ -415,6 +481,9 @@ struct dentry *smem_dram_parse(struct qcom_smem *smem, struct device *dev) case INFO_V7_WITH_6_REGIONS: smem_dram_parse_v7_data(dram, data); break; + case INFO_V7_GLYMUR: + smem_dram_parse_v7_glymur_data(dram, data); + break; default: return ERR_PTR(-EINVAL); } diff --git a/drivers/soc/qcom/smp2p.c b/drivers/soc/qcom/smp2p.c index af0ceeaf6e07..3104e31f91c9 100644 --- a/drivers/soc/qcom/smp2p.c +++ b/drivers/soc/qcom/smp2p.c @@ -102,7 +102,7 @@ struct smp2p_entry { struct qcom_smp2p *smp2p; const char *name; - u32 *value; + u32 __iomem *value; u32 last_value; struct irq_domain *domain; @@ -276,7 +276,7 @@ static void qcom_smp2p_start_in(struct qcom_smp2p *smp2p) list_for_each_entry(entry, &smp2p->inbound, node) { memcpy(buf, in->entries[i].name, sizeof(buf)); if (!strcmp(buf, entry->name)) { - entry->value = &in->entries[i].value; + entry->value = (u32 __iomem *)&in->entries[i].value; entry->last_value = readl(entry->value); break; } @@ -302,7 +302,7 @@ static void qcom_smp2p_notify_in(struct qcom_smp2p *smp2p) list_for_each_entry(entry, &smp2p->inbound, node) { memcpy(buf, in->entries[i].name, sizeof(buf)); if (!strcmp(buf, entry->name)) { - entry->value = &in->entries[i].value; + entry->value = (u32 __iomem *)&in->entries[i].value; break; } } @@ -528,7 +528,7 @@ static int qcom_smp2p_outbound_entry(struct qcom_smp2p *smp2p, memcpy(out->entries[out->valid_entries].name, buf, SMP2P_MAX_ENTRY_NAME); /* Make the logical entry reference the physical value */ - entry->value = &out->entries[out->valid_entries].value; + entry->value = (u32 __iomem *)&out->entries[out->valid_entries].value; out->valid_entries++; @@ -720,10 +720,8 @@ static int qcom_smp2p_probe(struct platform_device *pdev) NULL, qcom_smp2p_intr, IRQF_ONESHOT, NULL, (void *)smp2p); - if (ret) { - dev_err(&pdev->dev, "failed to request interrupt\n"); + if (ret) goto unwind_interfaces; - } /* * Treat smp2p interrupt as wakeup source, but keep it disabled diff --git a/drivers/soc/qcom/smsm.c b/drivers/soc/qcom/smsm.c index 021e9d1f61dc..ac3c85a2597a 100644 --- a/drivers/soc/qcom/smsm.c +++ b/drivers/soc/qcom/smsm.c @@ -82,8 +82,8 @@ struct qcom_smsm { u32 num_hosts; u32 num_entries; - u32 *local_state; - u32 *subscription; + u32 __iomem *local_state; + u32 __iomem *subscription; struct qcom_smem_state *state; spinlock_t lock; @@ -115,8 +115,8 @@ struct smsm_entry { DECLARE_BITMAP(irq_falling, 32); unsigned long last_value; - u32 *remote_state; - u32 *subscription; + u32 __iomem *remote_state; + u32 __iomem *subscription; }; /** @@ -451,10 +451,8 @@ static int smsm_inbound_entry(struct qcom_smsm *smsm, NULL, smsm_intr, IRQF_ONESHOT, "smsm", (void *)entry); - if (ret) { - dev_err(smsm->dev, "failed to request interrupt\n"); + if (ret) return ret; - } entry->domain = irq_domain_create_linear(of_fwnode_handle(node), 32, &smsm_irq_ops, entry); if (!entry->domain) { @@ -513,9 +511,9 @@ static int qcom_smsm_probe(struct platform_device *pdev) struct device_node *node; struct smsm_entry *entry; struct qcom_smsm *smsm; - u32 *intr_mask; + u32 __iomem *intr_mask; size_t size; - u32 *states; + u32 __iomem *states; u32 id; int ret; @@ -579,7 +577,7 @@ static int qcom_smsm_probe(struct platform_device *pdev) goto out_put; } - states = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); + states = (u32 __iomem *)qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_SHARED_STATE, NULL); if (IS_ERR(states)) { dev_err(&pdev->dev, "Unable to acquire shared state entry\n"); ret = PTR_ERR(states); @@ -594,7 +592,7 @@ static int qcom_smsm_probe(struct platform_device *pdev) goto out_put; } - intr_mask = qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); + intr_mask = (u32 __iomem *)qcom_smem_get(QCOM_SMEM_HOST_ANY, SMEM_SMSM_CPU_INTR_MASK, NULL); if (IS_ERR(intr_mask)) { dev_err(&pdev->dev, "unable to acquire shared memory interrupt mask\n"); ret = PTR_ERR(intr_mask); diff --git a/drivers/soc/qcom/socinfo.c b/drivers/soc/qcom/socinfo.c index 1836e226a294..63ee5cd561a2 100644 --- a/drivers/soc/qcom/socinfo.c +++ b/drivers/soc/qcom/socinfo.c @@ -450,6 +450,7 @@ static const struct soc_id soc_id[] = { { qcom_board_id(IPQ8172) }, { qcom_board_id(IPQ8173) }, { qcom_board_id(IPQ8174) }, + { qcom_board_id(SM7250) }, { qcom_board_id(IPQ6018) }, { qcom_board_id(IPQ6028) }, { qcom_board_id(SDM429W) }, diff --git a/drivers/soc/qcom/ubwc_config.c b/drivers/soc/qcom/ubwc_config.c index 23901a4c51f7..36c90f72943f 100644 --- a/drivers/soc/qcom/ubwc_config.c +++ b/drivers/soc/qcom/ubwc_config.c @@ -105,6 +105,13 @@ static const struct qcom_ubwc_cfg_data milos_data = { .highest_bank_bit = 15, }; +static const struct qcom_ubwc_cfg_data ubwc_7_0_hbb16 = { + .ubwc_enc_version = UBWC_7_0, + .flags = UBWC_SWIZZLE_ENABLE_LVL2 | + UBWC_SWIZZLE_ENABLE_LVL3, + .highest_bank_bit = 16, +}; + static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,apq8016", .data = &no_ubwc_data }, { .compatible = "qcom,apq8026", .data = &no_ubwc_data }, @@ -112,8 +119,10 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,apq8096", .data = &ubwc_1_0_hbb15 }, { .compatible = "qcom,eliza", .data = &ubwc_5_0_hbb15 }, { .compatible = "qcom,glymur", .data = &glymur_data}, + { .compatible = "qcom,hawi", .data = &ubwc_7_0_hbb16 }, { .compatible = "qcom,kaanapali", .data = &ubwc_6_0_hbb16 }, { .compatible = "qcom,mahua", .data = &glymur_data }, + { .compatible = "qcom,maili", .data = &ubwc_7_0_hbb16, }, { .compatible = "qcom,milos", .data = &milos_data }, { .compatible = "qcom,msm8226", .data = &no_ubwc_data }, { .compatible = "qcom,msm8916", .data = &no_ubwc_data }, @@ -127,6 +136,7 @@ static const struct of_device_id qcom_ubwc_configs[] __maybe_unused = { { .compatible = "qcom,msm8976", .data = &no_ubwc_data }, { .compatible = "qcom,msm8996", .data = &ubwc_1_0_hbb15 }, { .compatible = "qcom,msm8998", .data = &ubwc_1_0_hbb15 }, + { .compatible = "qcom,nord", .data = &glymur_data }, { .compatible = "qcom,qcm2290", .data = &ubwc_0_0_hbb15, }, { .compatible = "qcom,qcm6490", .data = &ubwc_3_1_hbb14, }, { .compatible = "qcom,qcs8300", .data = &ubwc_4_0_hbb16, }, diff --git a/include/dt-bindings/arm/qcom,ids.h b/include/dt-bindings/arm/qcom,ids.h index 2cf433f61d5e..b63e4a0b8e54 100644 --- a/include/dt-bindings/arm/qcom,ids.h +++ b/include/dt-bindings/arm/qcom,ids.h @@ -209,6 +209,7 @@ #define QCOM_ID_IPQ8172 397 #define QCOM_ID_IPQ8173 398 #define QCOM_ID_IPQ8174 399 +#define QCOM_ID_SM7250 400 #define QCOM_ID_IPQ6018 402 #define QCOM_ID_IPQ6028 403 #define QCOM_ID_SDM429W 416 diff --git a/include/linux/device-id/apr.h b/include/linux/device-id/apr.h deleted file mode 100644 index f282608ea018..000000000000 --- a/include/linux/device-id/apr.h +++ /dev/null @@ -1,21 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0 */ -#ifndef LINUX_DEVICE_ID_APR_H -#define LINUX_DEVICE_ID_APR_H - -#ifdef __KERNEL__ -#include -typedef unsigned long kernel_ulong_t; -#endif - -#define APR_NAME_SIZE 32 -#define APR_MODULE_PREFIX "apr:" - -struct apr_device_id { - char name[APR_NAME_SIZE]; - __u32 domain_id; - __u32 svc_id; - __u32 svc_version; - kernel_ulong_t driver_data; /* Data private to the driver */ -}; - -#endif /* ifndef LINUX_DEVICE_ID_APR_H */ diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h index a397213bedac..4fe1cd64292f 100644 --- a/include/linux/mod_devicetable.h +++ b/include/linux/mod_devicetable.h @@ -15,7 +15,6 @@ #include "device-id/acpi.h" #include "device-id/amba.h" #include "device-id/ap.h" -#include "device-id/apr.h" #include "device-id/auxiliary.h" #include "device-id/bcma.h" #include "device-id/ccw.h" diff --git a/include/linux/soc/qcom/apr.h b/include/linux/soc/qcom/apr.h index 909e84f84e0c..2e4231092088 100644 --- a/include/linux/soc/qcom/apr.h +++ b/include/linux/soc/qcom/apr.h @@ -5,7 +5,6 @@ #include #include -#include #include #include @@ -135,6 +134,8 @@ struct pkt_router_svc { typedef struct pkt_router_svc gpr_port_t; +#define APR_NAME_SIZE 32 + struct apr_device { struct device dev; uint16_t svc_id; @@ -158,7 +159,6 @@ struct apr_driver { const struct apr_resp_pkt *d); gpr_port_cb gpr_callback; struct device_driver driver; - const struct apr_device_id *id_table; }; typedef struct apr_driver gpr_driver_t; diff --git a/include/linux/soc/qcom/llcc-qcom.h b/include/linux/soc/qcom/llcc-qcom.h index f3ed63e475ab..1ccc429401e8 100644 --- a/include/linux/soc/qcom/llcc-qcom.h +++ b/include/linux/soc/qcom/llcc-qcom.h @@ -86,6 +86,10 @@ #define LLCC_CPUSS_HEU 94 #define LLCC_PCIE_TCU 97 #define LLCC_MDM_PNG_FIXED 100 +#define LLCC_PPE_RXDESC 101 +#define LLCC_PPE_RXFILL 102 +#define LLCC_WLAN_5G 103 +#define LLCC_WLAN_6G 104 /** * struct llcc_slice_desc - Cache slice descriptor diff --git a/include/linux/soc/qcom/ubwc.h b/include/linux/soc/qcom/ubwc.h index f3a70360b177..b09ae05cbeae 100644 --- a/include/linux/soc/qcom/ubwc.h +++ b/include/linux/soc/qcom/ubwc.h @@ -36,6 +36,7 @@ struct qcom_ubwc_cfg_data { #define UBWC_4_3 0x40030000 #define UBWC_5_0 0x50000000 #define UBWC_6_0 0x60000000 +#define UBWC_7_0 0x70000000 #if IS_ENABLED(CONFIG_QCOM_UBWC_CONFIG) const struct qcom_ubwc_cfg_data *qcom_ubwc_config_get_data(void); @@ -108,6 +109,8 @@ static inline u32 qcom_ubwc_swizzle(const struct qcom_ubwc_cfg_data *cfg) static inline u32 qcom_ubwc_version_tag(const struct qcom_ubwc_cfg_data *cfg) { + if (cfg->ubwc_enc_version >= UBWC_7_0) + return 6; if (cfg->ubwc_enc_version >= UBWC_6_0) return 5; if (cfg->ubwc_enc_version >= UBWC_5_0)