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-2021 Linaro Ltd.
13 #include <linux/firmware.h>
52 * currently supported. Despite that, some resources--including routing
53 * tables and filter tables--are defined in this driver because they must
54 * be initialized even when the advanced hardware features are not used.
59 * well-defined communication layer between the AP subsystem and the IPA
71 /* The name of the GSI firmware file relative to /lib/firmware */
84 * ipa_setup() - Set up IPA hardware
88 * the command TX endpoint. If the modem is doing GSI firmware load
91 * called from ipa_probe() after GSI firmware has been successfully
98 struct device *dev = &ipa->pdev->dev; in ipa_setup()
101 ret = gsi_setup(&ipa->gsi); in ipa_setup()
114 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_setup()
130 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_setup()
135 ipa_endpoint_default_route_set(ipa, exception_endpoint->endpoint_id); in ipa_setup()
142 ipa->setup_complete = true; in ipa_setup()
157 gsi_teardown(&ipa->gsi); in ipa_setup()
163 * ipa_teardown() - Inverse of ipa_setup()
172 ipa->setup_complete = false; in ipa_teardown()
176 exception_endpoint = ipa->name_map[IPA_ENDPOINT_AP_LAN_RX]; in ipa_teardown()
178 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_teardown()
182 gsi_teardown(&ipa->gsi); in ipa_teardown()
191 if (ipa->version < IPA_VERSION_4_0) in ipa_hardware_config_comp()
194 val = ioread32(ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET); in ipa_hardware_config_comp()
196 if (ipa->version == IPA_VERSION_4_0) { in ipa_hardware_config_comp()
200 } else if (ipa->version < IPA_VERSION_4_5) { in ipa_hardware_config_comp()
209 iowrite32(val, ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET); in ipa_hardware_config_comp()
221 data0 = &data->qsb_data[IPA_QSB_MASTER_DDR]; in ipa_hardware_config_qsb()
222 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
223 data1 = &data->qsb_data[IPA_QSB_MASTER_PCIE]; in ipa_hardware_config_qsb()
226 val = u32_encode_bits(data0->max_writes, GEN_QMB_0_MAX_WRITES_FMASK); in ipa_hardware_config_qsb()
227 if (data->qsb_count > 1) in ipa_hardware_config_qsb()
228 val |= u32_encode_bits(data1->max_writes, in ipa_hardware_config_qsb()
230 iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_WRITES_OFFSET); in ipa_hardware_config_qsb()
233 val = u32_encode_bits(data0->max_reads, GEN_QMB_0_MAX_READS_FMASK); in ipa_hardware_config_qsb()
234 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
235 val |= u32_encode_bits(data0->max_reads_beats, in ipa_hardware_config_qsb()
237 if (data->qsb_count > 1) { in ipa_hardware_config_qsb()
238 val |= u32_encode_bits(data1->max_reads, in ipa_hardware_config_qsb()
240 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
241 val |= u32_encode_bits(data1->max_reads_beats, in ipa_hardware_config_qsb()
244 iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_READS_OFFSET); in ipa_hardware_config_qsb()
258 return DIV_ROUND_CLOSEST(usec * TIMER_FREQUENCY, USEC_PER_SEC) - 1; in ipa_aggr_granularity_val()
263 * Qtimer is based on a 56-bit timestamp incremented at each tick of
268 * some number of bits to produce the low-order bits of the coarser
275 * those used for aggregation or head-of-line block handling) now
283 iowrite32(0, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET); in ipa_qtime_config()
291 iowrite32(val, ipa->reg_virt + IPA_REG_QTIME_TIMESTAMP_CFG_OFFSET); in ipa_qtime_config()
297 iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_PULSE_GRAN_CFG_OFFSET); in ipa_qtime_config()
300 val = u32_encode_bits(IPA_XO_CLOCK_DIVIDER - 1, DIV_VALUE_FMASK); in ipa_qtime_config()
301 iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET); in ipa_qtime_config()
303 /* Divider value is set; re-enable the common timer clock divider */ in ipa_qtime_config()
305 iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET); in ipa_qtime_config()
320 offset = ipa_reg_idle_indication_cfg_offset(ipa->version); in ipa_idle_indication_cfg()
321 iowrite32(val, ipa->reg_virt + offset); in ipa_idle_indication_cfg()
325 * ipa_hardware_dcd_config() - Enable dynamic clock division on IPA
340 /* Power-on reset values */ in ipa_hardware_dcd_deconfig()
345 * ipa_hardware_config() - Primitive hardware initialization
351 enum ipa_version version = ipa->version; in ipa_hardware_config()
357 val = data->backward_compat; in ipa_hardware_config()
358 iowrite32(val, ipa->reg_virt + IPA_REG_BCR_OFFSET); in ipa_hardware_config()
364 val = ioread32(ipa->reg_virt + IPA_REG_TX_CFG_OFFSET); in ipa_hardware_config()
366 iowrite32(val, ipa->reg_virt + IPA_REG_TX_CFG_OFFSET); in ipa_hardware_config()
376 iowrite32(val, ipa->reg_virt + IPA_REG_CLKON_CFG_OFFSET); in ipa_hardware_config()
387 iowrite32(val, ipa->reg_virt + IPA_REG_COUNTER_CFG_OFFSET); in ipa_hardware_config()
396 iowrite32(0, ipa->reg_virt + offset); in ipa_hardware_config()
404 * ipa_hardware_deconfig() - Inverse of ipa_hardware_config()
407 * This restores the power-on reset values (even if they aren't different)
416 * ipa_config() - Configure IPA hardware
432 ipa->interrupt = ipa_interrupt_config(ipa); in ipa_config()
433 if (IS_ERR(ipa->interrupt)) { in ipa_config()
434 ret = PTR_ERR(ipa->interrupt); in ipa_config()
435 ipa->interrupt = NULL; in ipa_config()
448 ret = ipa_resource_config(ipa, data->resource_data); in ipa_config()
462 ipa_interrupt_deconfig(ipa->interrupt); in ipa_config()
463 ipa->interrupt = NULL; in ipa_config()
473 * ipa_deconfig() - Inverse of ipa_config()
481 ipa_interrupt_deconfig(ipa->interrupt); in ipa_deconfig()
482 ipa->interrupt = NULL; in ipa_deconfig()
489 const struct firmware *fw; in ipa_firmware_load()
498 node = of_parse_phandle(dev->of_node, "memory-region", 0); in ipa_firmware_load()
500 dev_err(dev, "DT error getting \"memory-region\" property\n"); in ipa_firmware_load()
501 return -EINVAL; in ipa_firmware_load()
507 dev_err(dev, "error %d getting \"memory-region\" resource\n", in ipa_firmware_load()
513 ret = of_property_read_string(dev->of_node, "firmware-name", &path); in ipa_firmware_load()
515 dev_dbg(dev, "error %d getting \"firmware-name\" resource\n", in ipa_firmware_load()
530 dev_err(dev, "unable to remap firmware memory\n"); in ipa_firmware_load()
531 ret = -ENOMEM; in ipa_firmware_load()
550 .compatible = "qcom,msm8998-ipa",
554 .compatible = "qcom,sdm845-ipa",
558 .compatible = "qcom,sc7180-ipa",
562 .compatible = "qcom,sdx55-ipa",
566 .compatible = "qcom,sm8350-ipa",
570 .compatible = "qcom,sc7280-ipa",
583 /* At one time we assumed a 64-bit build, allowing some do_div() in ipa_validate_build()
587 * of being a 64-bit value. (It should be guaranteed 32 bits wide in ipa_validate_build()
588 * on a 32-bit build, but there is no harm in verifying that.) in ipa_validate_build()
604 * TLV FIFO size. A transaction structure uses 8-bit fields in ipa_validate_build()
640 * ipa_probe() - IPA platform driver probe function
648 * - The "init" stage involves activities that can be initialized without
650 * - The "config" stage requires IPA power to be active so IPA registers
652 * - The "setup" stage uses IPA immediate commands, and so requires the GSI
653 * layer to be initialized.
655 * A Boolean Device Tree "modem-init" property determines whether GSI
664 struct device *dev = &pdev->dev; in ipa_probe()
677 return -ENODEV; in ipa_probe()
680 if (!ipa_version_valid(data->version)) { in ipa_probe()
682 return -EINVAL; in ipa_probe()
686 modem_init = of_property_read_bool(dev->of_node, "modem-init"); in ipa_probe()
689 return -EPROBE_DEFER; in ipa_probe()
692 * probed, so might return -EPROBE_DEFER. in ipa_probe()
694 power = ipa_power_init(dev, data->power_data); in ipa_probe()
701 ret = -ENOMEM; in ipa_probe()
705 ipa->pdev = pdev; in ipa_probe()
707 ipa->power = power; in ipa_probe()
708 ipa->version = data->version; in ipa_probe()
709 init_completion(&ipa->completion); in ipa_probe()
715 ret = ipa_mem_init(ipa, data->mem_data); in ipa_probe()
719 ret = gsi_init(&ipa->gsi, pdev, ipa->version, data->endpoint_count, in ipa_probe()
720 data->endpoint_data); in ipa_probe()
724 /* Result is a non-zero mask of endpoints that support filtering */ in ipa_probe()
725 ipa->filter_map = ipa_endpoint_init(ipa, data->endpoint_count, in ipa_probe()
726 data->endpoint_data); in ipa_probe()
727 if (!ipa->filter_map) { in ipa_probe()
728 ret = -EINVAL; in ipa_probe()
749 dev_info(dev, "IPA driver initialized"); in ipa_probe()
758 /* Otherwise we need to load the firmware and have Trust Zone validate in ipa_probe()
784 gsi_exit(&ipa->gsi); in ipa_probe()
799 struct ipa *ipa = dev_get_drvdata(&pdev->dev); in ipa_remove()
800 struct ipa_power *power = ipa->power; in ipa_remove()
801 struct device *dev = &pdev->dev; in ipa_remove()
808 if (ipa->setup_complete) { in ipa_remove()
811 if (ret == -EBUSY) { in ipa_remove()
827 gsi_exit(&ipa->gsi); in ipa_remove()
842 dev_err(&pdev->dev, "shutdown: remove returned %d\n", ret); in ipa_shutdown()