Lines Matching +full:layers +full:- +full:configurable

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.
53 * currently supported. Despite that, some resources--including routing
54 * tables and filter tables--are defined in this driver because they must
57 * There are two distinct layers that implement the IPA hardware, and this
60 * well-defined communication layer between the AP subsystem and the IPA
103 * ipa_setup() - Set up IPA hardware
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
365 * timer ticks at a configurable frequency. IPA timers (such as
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()
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()
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()
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
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()
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()