mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
Qualcomm driver updates for v7.4 (second attempt)
Add UBWC 7.0 configuration for Hawi and Maili, and reuse Glymur's UBWC configuration for Nord. Parse Glymur's DDR information from SMEM, including its frequency plan and highest bank bit. Correct DDR frequency overflow and byte order, and handle unrecognized DDR layouts correctly. Configure dedicated LLCC slices for the IPQ5424 PPE and Wi-Fi datapaths, adjust the CPU slice, and propagate errors from optional IRQ lookup. Allow the GENI serial-engine driver to be selected on 32-bit Qualcomm SoCs such as Kuno. Fix firmware loading bounds, endianness, and writes to read-only firmware. Allow QSEECOM on the Glymur-based HP EliteBook X G2q 14 AI, Lenovo Yoga Slim 7x Gen11, and Asus Zenbook A14 (UX3407NA), enabling EFI variable access on the HP and Asus laptops. Release SCM reserved memory on probe failure or unbind, and limit Qualcomm firmware Kconfig options to Qualcomm platforms. Defer PMIC GLINK altmode work until devices resume to avoid accessing suspended I2C controllers. Fix cleanup of failed APR service registrations to prevent stale lookups, and remove unused APR device-ID matching. Add the SM7250 SoC ID, correct SMSM and SMP2P I/O annotations, and clean up RPMh kernel-doc and redundant IRQ error messages. Document the Kuno SCM interface, Shikra CTCU fallback, and Milos CPU bandwidth monitor. Add Abel Vesa as a Qualcomm SoC reviewer. -----BEGIN PGP SIGNATURE----- iQJJBAABCgAzFiEEBd4DzF816k8JZtUlCx85Pw2ZrcUFAmrJ6ckVHGFuZGVyc3Nv bkBrZXJuZWwub3JnAAoJEAsfOT8Nma3Fh6MQAKZr+FrRPfUfY7xK9DX2HX/Qkr2w JJJJ8ghiffkBvfBWexoZSIpXfCcPjoKIyqltOVtGnaC/+MzupOYG3PYMgePxVA1s XomAViwUUsRyMK5wTIsoI/hskYTuDcxalHvzMGmJ2InpDl/qz9oZkHL/PgVSLOO4 IHYV1qTWEbaa/7H+otTzOY+n7n7YgCApmuzuHZi4wd15NLj6YntBLKYmxMLVlebi nh2Y4RNPI9XALofSK8SAE8udxUK5zpa/+hDpZ6Aa/tgM8Pgf6rCnrQarFtNm3qHW R8w5yxpOc9/6oVSXIgdVSs6yqjIS0yri3uySlthQFht+ZeqG9sifz2H1lx2hltKF 4YoanwZbudrAgTg8tpvVx4PfXNSLqrYrNGHUNo5wwlVu/dlllZuu2pVSu6sc3Jhx 3mi8QquhMdDl1jORxdT9sV65AK2aIyoXMJrvg40LEk3CDHtnnhc5EFghMe3JVPwO LVqQzGsaqSNJcs29ythN3RgjhdwQkih84VbqVfqbyL5l3halDsc0yVS4OJmr8hhh K6nJqr+bBVT/FF8vWL4Kluk3v/w7O80NhOLQjAbpSriScww+FBn9kaKGEwi4Ywi2 pWG1/tLjrOt2eVMuDAsUvLkDjj6Qwp+TFjkrr4DQbZYPlbxkcTliZP5R86ZCiSgb cF19q4GGok+sRWNp =ejUm -----END PGP SIGNATURE----- gpgsig -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEo6/YBQwIrVS28WGKmmx57+YAGNkFAmrOPlQACgkQmmx57+YA GNndKg//bdKS/0hex1kiKzm0Ezzw578ifGkIm2AquhyfjKuPpA+bQkNvdPbhhgaY IGaadnpi8vqT6T1Rl5SHixiKmmZqB3c2OyEBQPSdXZXtEh/oCrwLOQgyDkBegwab K84whGgNNvna5pdxKyFFsrPgQityx9rlMnbUgqYzBRgZ9c7oA5J78JTHhVruBJoR 0N04Y40qTQ9C2NB6FuoepGrVbX/lcog+QzRsNKdm/EJyt0XSI1czaxHr1HNIgKJt EW4u0fPjkrvwG84WtgoRJO0KaGqX9OIpzTbDXRhW8jB3vHQiRSmGk7hfVYwv33FZ PpyFG4Fg/MOntbSO0SNsWwvvugvE1XhpruJrZSfkh9tiDPQpS9JyoPqoQY/TsgEP DydiIMeVinzUUqrXBhV9M8hVLVgcQHTKd5pzkoROS8vMyAZ6qRwto4MxOrMuIkoU fy9vJRyTp4Nipg95cZ7luJnuaNz2Pch7CpUhP710bU5okEydTIQc094sHb4uqVH7 8MdrNt7jF1aji4OaFTjIGG9bqTHhP3EJ0wkhni87y0jzQH5a+IWEVedYLyitHGb5 P9PmVtwnCMwWApm+EriNEfMcZT6bJei0kuWWjlfaU3ST3GT+tU5lSy0WbHTfSMH2 qsUJ48VXdUEmnKNkubtGB/XBYBF5kDBJrmXLbRMmCE8MbISnmQA= =hOZ6 -----END PGP SIGNATURE----- Merge tag 'qcom-drivers-for-7.4-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux into soc/drivers Qualcomm driver updates for v7.4 (second attempt) Add UBWC 7.0 configuration for Hawi and Maili, and reuse Glymur's UBWC configuration for Nord. Parse Glymur's DDR information from SMEM, including its frequency plan and highest bank bit. Correct DDR frequency overflow and byte order, and handle unrecognized DDR layouts correctly. Configure dedicated LLCC slices for the IPQ5424 PPE and Wi-Fi datapaths, adjust the CPU slice, and propagate errors from optional IRQ lookup. Allow the GENI serial-engine driver to be selected on 32-bit Qualcomm SoCs such as Kuno. Fix firmware loading bounds, endianness, and writes to read-only firmware. Allow QSEECOM on the Glymur-based HP EliteBook X G2q 14 AI, Lenovo Yoga Slim 7x Gen11, and Asus Zenbook A14 (UX3407NA), enabling EFI variable access on the HP and Asus laptops. Release SCM reserved memory on probe failure or unbind, and limit Qualcomm firmware Kconfig options to Qualcomm platforms. Defer PMIC GLINK altmode work until devices resume to avoid accessing suspended I2C controllers. Fix cleanup of failed APR service registrations to prevent stale lookups, and remove unused APR device-ID matching. Add the SM7250 SoC ID, correct SMSM and SMP2P I/O annotations, and clean up RPMh kernel-doc and redundant IRQ error messages. Document the Kuno SCM interface, Shikra CTCU fallback, and Milos CPU bandwidth monitor. Add Abel Vesa as a Qualcomm SoC reviewer. * tag 'qcom-drivers-for-7.4-2' of https://git.kernel.org/pub/scm/linux/kernel/git/qcom/linux: (34 commits) firmware: qcom: scm: Allow QSEECOM on Asus Zenbook A14 (UX3407NA) firmware: qcom: scm: Allow QSEECOM on Yoga Slim 7x Gen11 MAINTAINERS: add Abel as reviewer for linux-arm-msm soc: qcom: ubwcg: Add Nord UBWC config firmware: QCOM interfaces should depend on ARCH_QCOM firmware: qcom: scm: Use devm_of_reserved_mem_device_init() soc: qcom: smp2p: fix __iomem annotation on entry->value pointer soc: qcom: apr: clean up failed service registrations soc: qcom: smem: Fix signedness bug in smem_dram_parse() soc: qcom: ubwc: Add configuration for Maili soc: qcom: ubwc: Add configuration for Hawi soc: qcom: rpmh-rsc: fix kernel-doc issues in rpmh-rsc.c soc: qcom: rpmh: fix kernel-doc issues in rpmh.c soc: qcom: rpmh-internal: fix kernel-doc issues in rpmh-internal.h soc: qcom: pmic_glink: Fix device access from worker during suspend soc: qcom: llcc-qcom: Handle errors from optional IRQ lookup soc: qcom: geni-se: Fix write to read-only firmware buffer soc: qcom: geni-se: Fix fw_end computed before round-up; propagate size to caller soc: qcom: geni-se: Widen fw_size to u32 to prevent wrap-around soc: qcom: geni-se: Fix endian conversion for serial_protocol comparison ... Signed-off-by: Arnd Bergmann <arnd@arndb.de>
This commit is contained in:
commit
3780804272
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -3432,6 +3432,7 @@ F: include/linux/soc/qcom/
|
|||
ARM/QUALCOMM SUPPORT
|
||||
M: Bjorn Andersson <andersson@kernel.org>
|
||||
M: Konrad Dybcio <konradybcio@kernel.org>
|
||||
R: Abel Vesa <abelvesa@kernel.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
S: Maintained
|
||||
C: irc://irc.oftc.net/linux-msm
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) },
|
||||
|
|
|
|||
|
|
@ -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, },
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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 <linux/types.h>
|
||||
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 */
|
||||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/device-id/apr.h>
|
||||
#include <dt-bindings/soc/qcom,apr.h>
|
||||
#include <dt-bindings/soc/qcom,gpr.h>
|
||||
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user