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 */
86 * enum ipa_firmware_loader: How GSI firmware gets loaded
89 * @IPA_LOADER_SELF: AP loads GSI firmware
90 * @IPA_LOADER_MODEM: Modem loads GSI firmware, signals when done
91 * @IPA_LOADER_SKIP: Neither AP nor modem need to load GSI firmware
92 * @IPA_LOADER_INVALID: GSI firmware loader specification is invalid
103 * ipa_setup() - Set up IPA hardware
107 * the command TX endpoint. If the modem is doing GSI firmware load
110 * called from ipa_probe() after GSI firmware has been successfully
117 struct device *dev = &ipa->pdev->dev; in ipa_setup()
120 ret = gsi_setup(&ipa->gsi); in ipa_setup()
133 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_setup()
149 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_setup()
154 ipa_endpoint_default_route_set(ipa, exception_endpoint->endpoint_id); in ipa_setup()
161 ipa->setup_complete = true; in ipa_setup()
176 gsi_teardown(&ipa->gsi); in ipa_setup()
182 * ipa_teardown() - Inverse of ipa_setup()
191 ipa->setup_complete = false; in ipa_teardown()
195 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_teardown()
197 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_teardown()
201 gsi_teardown(&ipa->gsi); in ipa_teardown()
211 if (ipa->version >= IPA_VERSION_4_5) in ipa_hardware_config_bcr()
215 val = data->backward_compat; in ipa_hardware_config_bcr()
216 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_bcr()
221 enum ipa_version version = ipa->version; in ipa_hardware_config_tx()
233 val = ioread32(ipa->reg_virt + offset); in ipa_hardware_config_tx()
237 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_tx()
242 enum ipa_version version = ipa->version; in ipa_hardware_config_clkon()
263 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_clkon()
274 if (ipa->version < IPA_VERSION_4_0) in ipa_hardware_config_comp()
280 val = ioread32(ipa->reg_virt + offset); in ipa_hardware_config_comp()
282 if (ipa->version == IPA_VERSION_4_0) { in ipa_hardware_config_comp()
286 } else if (ipa->version < IPA_VERSION_4_5) { in ipa_hardware_config_comp()
295 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_comp()
308 data0 = &data->qsb_data[IPA_QSB_MASTER_DDR]; in ipa_hardware_config_qsb()
309 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
310 data1 = &data->qsb_data[IPA_QSB_MASTER_PCIE]; in ipa_hardware_config_qsb()
315 val = reg_encode(reg, GEN_QMB_0_MAX_WRITES, data0->max_writes); in ipa_hardware_config_qsb()
316 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
317 val |= reg_encode(reg, GEN_QMB_1_MAX_WRITES, data1->max_writes); in ipa_hardware_config_qsb()
319 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
324 val = reg_encode(reg, GEN_QMB_0_MAX_READS, data0->max_reads); in ipa_hardware_config_qsb()
325 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
327 data0->max_reads_beats); in ipa_hardware_config_qsb()
328 if (data->qsb_count > 1) { in ipa_hardware_config_qsb()
329 val = reg_encode(reg, GEN_QMB_1_MAX_READS, data1->max_reads); in ipa_hardware_config_qsb()
330 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
332 data1->max_reads_beats); in ipa_hardware_config_qsb()
335 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
349 return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1; in ipa_aggr_granularity_val()
354 * Qtimer is based on a 56-bit timestamp incremented at each tick of
359 * some number of bits to produce the low-order bits of the coarser
366 * those used for aggregation or head-of-line block handling) now
377 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
380 if (ipa->version < IPA_VERSION_5_5) { in ipa_qtime_config()
389 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
395 if (ipa->version >= IPA_VERSION_5_0) { in ipa_qtime_config()
402 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
408 val = reg_encode(reg, DIV_VALUE, IPA_XO_CLOCK_DIVIDER - 1); in ipa_qtime_config()
410 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
412 /* Divider value is set; re-enable the common timer clock divider */ in ipa_qtime_config()
415 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
428 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_counter()
433 if (ipa->version < IPA_VERSION_4_5) in ipa_hardware_config_timing()
448 if (ipa->version != IPA_VERSION_4_2) in ipa_hardware_config_hashing()
457 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_hashing()
467 if (ipa->version < IPA_VERSION_3_5_1) in ipa_idle_indication_cfg()
476 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_idle_indication_cfg()
480 * ipa_hardware_dcd_config() - Enable dynamic clock division on IPA
495 /* Power-on reset values */ in ipa_hardware_dcd_deconfig()
500 * ipa_hardware_config() - Primitive hardware initialization
517 * ipa_hardware_deconfig() - Inverse of ipa_hardware_config()
520 * This restores the power-on reset values (even if they aren't different)
529 * ipa_config() - Configure IPA hardware
545 ipa->interrupt = ipa_interrupt_config(ipa); in ipa_config()
546 if (IS_ERR(ipa->interrupt)) { in ipa_config()
547 ret = PTR_ERR(ipa->interrupt); in ipa_config()
548 ipa->interrupt = NULL; in ipa_config()
561 ret = ipa_resource_config(ipa, data->resource_data); in ipa_config()
575 ipa_interrupt_deconfig(ipa->interrupt); in ipa_config()
576 ipa->interrupt = NULL; in ipa_config()
586 * ipa_deconfig() - Inverse of ipa_config()
594 ipa_interrupt_deconfig(ipa->interrupt); in ipa_deconfig()
595 ipa->interrupt = NULL; in ipa_deconfig()
602 const struct firmware *fw; in ipa_firmware_load()
611 node = of_parse_phandle(dev->of_node, "memory-region", 0); in ipa_firmware_load()
613 dev_err(dev, "DT error getting \"memory-region\" property\n"); in ipa_firmware_load()
614 return -EINVAL; in ipa_firmware_load()
620 dev_err(dev, "error %d getting \"memory-region\" resource\n", in ipa_firmware_load()
626 ret = of_property_read_string(dev->of_node, "firmware-name", &path); in ipa_firmware_load()
628 dev_dbg(dev, "error %d getting \"firmware-name\" resource\n", in ipa_firmware_load()
643 dev_err(dev, "unable to remap firmware memory\n"); in ipa_firmware_load()
644 ret = -ENOMEM; in ipa_firmware_load()
663 .compatible = "qcom,msm8998-ipa",
667 .compatible = "qcom,sdm845-ipa",
671 .compatible = "qcom,sc7180-ipa",
675 .compatible = "qcom,sdx55-ipa",
679 .compatible = "qcom,sm6350-ipa",
683 .compatible = "qcom,sm8350-ipa",
687 .compatible = "qcom,sc7280-ipa",
691 .compatible = "qcom,sdx65-ipa",
695 .compatible = "qcom,sm8550-ipa",
708 /* At one time we assumed a 64-bit build, allowing some do_div() in ipa_validate_build()
712 * of being a 64-bit value. (It should be guaranteed 32 bits wide in ipa_validate_build()
713 * on a 32-bit build, but there is no harm in verifying that.) in ipa_validate_build()
729 * TLV FIFO size. A transaction structure uses 8-bit fields in ipa_validate_build()
748 modem_init = of_property_read_bool(dev->of_node, "modem-init"); in ipa_firmware_loader()
749 ret = of_property_read_string(dev->of_node, "qcom,gsi-loader", &str); in ipa_firmware_loader()
752 if (ret == -EINVAL) { in ipa_firmware_loader()
766 /* Modem loads GSI firmware for "modem" */ in ipa_firmware_loader()
770 /* No GSI firmware load is needed for "skip" */ in ipa_firmware_loader()
778 /* We need Trust Zone to load firmware; make sure it's available */ in ipa_firmware_loader()
786 * ipa_probe() - IPA platform driver probe function
794 * - The "init" stage involves activities that can be initialized without
796 * - The "config" stage requires IPA power to be active so IPA registers
798 * - The "setup" stage uses IPA immediate commands, and so requires the GSI
799 * layer to be initialized.
801 * A Boolean Device Tree "modem-init" property determines whether GSI
810 struct device *dev = &pdev->dev; in ipa_probe()
823 return -ENODEV; in ipa_probe()
826 if (!ipa_version_supported(data->version)) { in ipa_probe()
827 dev_err(dev, "unsupported IPA version %u\n", data->version); in ipa_probe()
828 return -EINVAL; in ipa_probe()
831 if (!data->modem_route_count) { in ipa_probe()
833 return -EINVAL; in ipa_probe()
838 return -EINVAL; in ipa_probe()
840 return -EPROBE_DEFER; in ipa_probe()
843 * probed, so might return -EPROBE_DEFER. in ipa_probe()
845 power = ipa_power_init(dev, data->power_data); in ipa_probe()
852 ret = -ENOMEM; in ipa_probe()
856 ipa->pdev = pdev; in ipa_probe()
858 ipa->power = power; in ipa_probe()
859 ipa->version = data->version; in ipa_probe()
860 ipa->modem_route_count = data->modem_route_count; in ipa_probe()
861 init_completion(&ipa->completion); in ipa_probe()
867 ret = ipa_mem_init(ipa, data->mem_data); in ipa_probe()
871 ret = gsi_init(&ipa->gsi, pdev, ipa->version, data->endpoint_count, in ipa_probe()
872 data->endpoint_data); in ipa_probe()
876 /* Result is a non-zero mask of endpoints that support filtering */ in ipa_probe()
877 ret = ipa_endpoint_init(ipa, data->endpoint_count, data->endpoint_data); in ipa_probe()
898 dev_info(dev, "IPA driver initialized"); in ipa_probe()
900 /* If the modem is loading GSI firmware, it will trigger a call to in ipa_probe()
907 /* The AP is loading GSI firmware; do so now */ in ipa_probe()
913 /* GSI firmware is loaded; proceed to setup */ in ipa_probe()
933 gsi_exit(&ipa->gsi); in ipa_probe()
948 struct ipa *ipa = dev_get_drvdata(&pdev->dev); in ipa_remove()
949 struct ipa_power *power = ipa->power; in ipa_remove()
950 struct device *dev = &pdev->dev; in ipa_remove()
954 * also ensures a modem-initiated setup that's underway completes. in ipa_remove()
962 if (ipa->setup_complete) { in ipa_remove()
965 if (ret == -EBUSY) { in ipa_remove()
989 gsi_exit(&ipa->gsi); in ipa_remove()