Lines Matching +full:firmware +full:- +full:initialized
1 // SPDX-License-Identifier: GPL-2.0
3 /* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
4 * Copyright (C) 2018-2023 Linaro Ltd.
13 #include <linux/firmware.h>
19 #include <linux/firmware/qcom/qcom_scm.h>
53 * currently supported. Despite that, some resources--including routing
54 * tables and filter tables--are defined in this driver because they must
55 * be initialized even when the advanced hardware features are not used.
60 * well-defined communication layer between the AP subsystem and the IPA
72 /* The name of the GSI firmware file relative to /lib/firmware */
85 * enum ipa_firmware_loader: How GSI firmware gets loaded
88 * @IPA_LOADER_SELF: AP loads GSI firmware
89 * @IPA_LOADER_MODEM: Modem loads GSI firmware, signals when done
90 * @IPA_LOADER_SKIP: Neither AP nor modem need to load GSI firmware
91 * @IPA_LOADER_INVALID: GSI firmware loader specification is invalid
102 * ipa_setup() - Set up IPA hardware
106 * the command TX endpoint. If the modem is doing GSI firmware load
109 * called from ipa_probe() after GSI firmware has been successfully
116 struct device *dev = &ipa->pdev->dev; in ipa_setup()
119 ret = gsi_setup(&ipa->gsi); in ipa_setup()
132 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_setup()
148 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_setup()
153 ipa_endpoint_default_route_set(ipa, exception_endpoint->endpoint_id); in ipa_setup()
160 ipa->setup_complete = true; in ipa_setup()
175 gsi_teardown(&ipa->gsi); in ipa_setup()
181 * ipa_teardown() - Inverse of ipa_setup()
190 ipa->setup_complete = false; in ipa_teardown()
194 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_teardown()
196 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_teardown()
200 gsi_teardown(&ipa->gsi); in ipa_teardown()
210 if (ipa->version >= IPA_VERSION_4_5) in ipa_hardware_config_bcr()
214 val = data->backward_compat; in ipa_hardware_config_bcr()
215 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_bcr()
220 enum ipa_version version = ipa->version; in ipa_hardware_config_tx()
232 val = ioread32(ipa->reg_virt + offset); in ipa_hardware_config_tx()
236 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_tx()
241 enum ipa_version version = ipa->version; in ipa_hardware_config_clkon()
262 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_clkon()
273 if (ipa->version < IPA_VERSION_4_0) in ipa_hardware_config_comp()
279 val = ioread32(ipa->reg_virt + offset); in ipa_hardware_config_comp()
281 if (ipa->version == IPA_VERSION_4_0) { in ipa_hardware_config_comp()
285 } else if (ipa->version < IPA_VERSION_4_5) { in ipa_hardware_config_comp()
294 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_comp()
307 data0 = &data->qsb_data[IPA_QSB_MASTER_DDR]; in ipa_hardware_config_qsb()
308 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
309 data1 = &data->qsb_data[IPA_QSB_MASTER_PCIE]; in ipa_hardware_config_qsb()
314 val = reg_encode(reg, GEN_QMB_0_MAX_WRITES, data0->max_writes); in ipa_hardware_config_qsb()
315 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
316 val |= reg_encode(reg, GEN_QMB_1_MAX_WRITES, data1->max_writes); in ipa_hardware_config_qsb()
318 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
323 val = reg_encode(reg, GEN_QMB_0_MAX_READS, data0->max_reads); in ipa_hardware_config_qsb()
324 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
326 data0->max_reads_beats); in ipa_hardware_config_qsb()
327 if (data->qsb_count > 1) { in ipa_hardware_config_qsb()
328 val = reg_encode(reg, GEN_QMB_1_MAX_READS, data1->max_reads); in ipa_hardware_config_qsb()
329 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
331 data1->max_reads_beats); in ipa_hardware_config_qsb()
334 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
348 return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1; in ipa_aggr_granularity_val()
353 * Qtimer is based on a 56-bit timestamp incremented at each tick of
358 * some number of bits to produce the low-order bits of the coarser
365 * those used for aggregation or head-of-line block handling) now
376 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
386 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
392 if (ipa->version >= IPA_VERSION_5_0) { in ipa_qtime_config()
399 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
405 val = reg_encode(reg, DIV_VALUE, IPA_XO_CLOCK_DIVIDER - 1); in ipa_qtime_config()
407 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
409 /* Divider value is set; re-enable the common timer clock divider */ in ipa_qtime_config()
412 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
425 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_counter()
430 if (ipa->version < IPA_VERSION_4_5) in ipa_hardware_config_timing()
445 if (ipa->version != IPA_VERSION_4_2) in ipa_hardware_config_hashing()
454 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_hashing()
464 if (ipa->version < IPA_VERSION_3_5_1) in ipa_idle_indication_cfg()
473 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_idle_indication_cfg()
477 * ipa_hardware_dcd_config() - Enable dynamic clock division on IPA
492 /* Power-on reset values */ in ipa_hardware_dcd_deconfig()
497 * ipa_hardware_config() - Primitive hardware initialization
514 * ipa_hardware_deconfig() - Inverse of ipa_hardware_config()
517 * This restores the power-on reset values (even if they aren't different)
526 * ipa_config() - Configure IPA hardware
542 ipa->interrupt = ipa_interrupt_config(ipa); in ipa_config()
543 if (IS_ERR(ipa->interrupt)) { in ipa_config()
544 ret = PTR_ERR(ipa->interrupt); in ipa_config()
545 ipa->interrupt = NULL; in ipa_config()
558 ret = ipa_resource_config(ipa, data->resource_data); in ipa_config()
572 ipa_interrupt_deconfig(ipa->interrupt); in ipa_config()
573 ipa->interrupt = NULL; in ipa_config()
583 * ipa_deconfig() - Inverse of ipa_config()
591 ipa_interrupt_deconfig(ipa->interrupt); in ipa_deconfig()
592 ipa->interrupt = NULL; in ipa_deconfig()
599 const struct firmware *fw; in ipa_firmware_load()
608 node = of_parse_phandle(dev->of_node, "memory-region", 0); in ipa_firmware_load()
610 dev_err(dev, "DT error getting \"memory-region\" property\n"); in ipa_firmware_load()
611 return -EINVAL; in ipa_firmware_load()
617 dev_err(dev, "error %d getting \"memory-region\" resource\n", in ipa_firmware_load()
623 ret = of_property_read_string(dev->of_node, "firmware-name", &path); in ipa_firmware_load()
625 dev_dbg(dev, "error %d getting \"firmware-name\" resource\n", in ipa_firmware_load()
640 dev_err(dev, "unable to remap firmware memory\n"); in ipa_firmware_load()
641 ret = -ENOMEM; in ipa_firmware_load()
660 .compatible = "qcom,msm8998-ipa",
664 .compatible = "qcom,sdm845-ipa",
668 .compatible = "qcom,sc7180-ipa",
672 .compatible = "qcom,sdx55-ipa",
676 .compatible = "qcom,sm6350-ipa",
680 .compatible = "qcom,sm8350-ipa",
684 .compatible = "qcom,sc7280-ipa",
688 .compatible = "qcom,sdx65-ipa",
701 /* At one time we assumed a 64-bit build, allowing some do_div() in ipa_validate_build()
705 * of being a 64-bit value. (It should be guaranteed 32 bits wide in ipa_validate_build()
706 * on a 32-bit build, but there is no harm in verifying that.) in ipa_validate_build()
722 * TLV FIFO size. A transaction structure uses 8-bit fields in ipa_validate_build()
741 modem_init = of_property_read_bool(dev->of_node, "modem-init"); in ipa_firmware_loader()
742 ret = of_property_read_string(dev->of_node, "qcom,gsi-loader", &str); in ipa_firmware_loader()
745 if (ret == -EINVAL) { in ipa_firmware_loader()
759 /* Modem loads GSI firmware for "modem" */ in ipa_firmware_loader()
763 /* No GSI firmware load is needed for "skip" */ in ipa_firmware_loader()
771 /* We need Trust Zone to load firmware; make sure it's available */ in ipa_firmware_loader()
779 * ipa_probe() - IPA platform driver probe function
787 * - The "init" stage involves activities that can be initialized without
789 * - The "config" stage requires IPA power to be active so IPA registers
791 * - The "setup" stage uses IPA immediate commands, and so requires the GSI
792 * layer to be initialized.
794 * A Boolean Device Tree "modem-init" property determines whether GSI
803 struct device *dev = &pdev->dev; in ipa_probe()
816 return -ENODEV; in ipa_probe()
819 if (!ipa_version_supported(data->version)) { in ipa_probe()
820 dev_err(dev, "unsupported IPA version %u\n", data->version); in ipa_probe()
821 return -EINVAL; in ipa_probe()
824 if (!data->modem_route_count) { in ipa_probe()
826 return -EINVAL; in ipa_probe()
831 return -EINVAL; in ipa_probe()
833 return -EPROBE_DEFER; in ipa_probe()
836 * probed, so might return -EPROBE_DEFER. in ipa_probe()
838 power = ipa_power_init(dev, data->power_data); in ipa_probe()
845 ret = -ENOMEM; in ipa_probe()
849 ipa->pdev = pdev; in ipa_probe()
851 ipa->power = power; in ipa_probe()
852 ipa->version = data->version; in ipa_probe()
853 ipa->modem_route_count = data->modem_route_count; in ipa_probe()
854 init_completion(&ipa->completion); in ipa_probe()
860 ret = ipa_mem_init(ipa, data->mem_data); in ipa_probe()
864 ret = gsi_init(&ipa->gsi, pdev, ipa->version, data->endpoint_count, in ipa_probe()
865 data->endpoint_data); in ipa_probe()
869 /* Result is a non-zero mask of endpoints that support filtering */ in ipa_probe()
870 ret = ipa_endpoint_init(ipa, data->endpoint_count, data->endpoint_data); in ipa_probe()
891 dev_info(dev, "IPA driver initialized"); in ipa_probe()
893 /* If the modem is loading GSI firmware, it will trigger a call to in ipa_probe()
900 /* The AP is loading GSI firmware; do so now */ in ipa_probe()
906 /* GSI firmware is loaded; proceed to setup */ in ipa_probe()
926 gsi_exit(&ipa->gsi); in ipa_probe()
941 struct ipa *ipa = dev_get_drvdata(&pdev->dev); in ipa_remove()
942 struct ipa_power *power = ipa->power; in ipa_remove()
943 struct device *dev = &pdev->dev; in ipa_remove()
947 * also ensures a modem-initiated setup that's underway completes. in ipa_remove()
955 if (ipa->setup_complete) { in ipa_remove()
958 if (ret == -EBUSY) { in ipa_remove()
974 gsi_exit(&ipa->gsi); in ipa_remove()
991 dev_err(&pdev->dev, "shutdown: remove returned %d\n", ret); in ipa_shutdown()