Lines Matching full:ipa

22 #include "ipa.h"
40 * This driver supports the Qualcomm IP Accelerator (IPA), which is a
41 * networking component found in many Qualcomm SoCs. The IPA is connected
45 * The IPA is the conduit between the AP and the modem that carries network
49 * The IPA provides protocol checksum calculation, offloading this work
50 * from the AP. The IPA offers additional functionality, including routing,
56 * There are two distinct layers that implement the IPA hardware, and this
58 * interface (GSI) is an integral component of the IPA, providing a
59 * well-defined communication layer between the AP subsystem and the IPA
61 * between the AP and the IPA.
63 * The IPA layer uses GSI channels to implement its "endpoints". And while
64 * a GSI channel carries data between the AP and the IPA, a pair of IPA
84 * ipa_setup() - Set up IPA hardware
85 * @ipa: IPA pointer
94 int ipa_setup(struct ipa *ipa) in ipa_setup() argument
98 struct device *dev = &ipa->pdev->dev; in ipa_setup()
101 ret = gsi_setup(&ipa->gsi); in ipa_setup()
105 ret = ipa_power_setup(ipa); in ipa_setup()
109 ipa_endpoint_setup(ipa); in ipa_setup()
114 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_setup()
119 ret = ipa_mem_setup(ipa); /* No matching teardown required */ in ipa_setup()
123 ret = ipa_table_setup(ipa); /* No matching teardown required */ 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()
138 ret = ipa_qmi_setup(ipa); in ipa_setup()
142 ipa->setup_complete = true; in ipa_setup()
144 dev_info(dev, "IPA driver setup completed successfully\n"); in ipa_setup()
149 ipa_endpoint_default_route_clear(ipa); in ipa_setup()
154 ipa_endpoint_teardown(ipa); in ipa_setup()
155 ipa_power_teardown(ipa); in ipa_setup()
157 gsi_teardown(&ipa->gsi); in ipa_setup()
164 * @ipa: IPA pointer
166 static void ipa_teardown(struct ipa *ipa) in ipa_teardown() argument
172 ipa->setup_complete = false; in ipa_teardown()
174 ipa_qmi_teardown(ipa); in ipa_teardown()
175 ipa_endpoint_default_route_clear(ipa); 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()
180 ipa_endpoint_teardown(ipa); in ipa_teardown()
181 ipa_power_teardown(ipa); in ipa_teardown()
182 gsi_teardown(&ipa->gsi); in ipa_teardown()
185 /* Configure bus access behavior for IPA components */
186 static void ipa_hardware_config_comp(struct ipa *ipa) in ipa_hardware_config_comp() argument
190 /* Nothing to configure prior to IPA v4.0 */ in ipa_hardware_config_comp()
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()
203 /* For IPA v4.5 IPA_FULL_FLUSH_WAIT_RSC_CLOSE_EN is 0 */ in ipa_hardware_config_comp()
209 iowrite32(val, ipa->reg_virt + IPA_REG_COMP_CFG_OFFSET); in ipa_hardware_config_comp()
214 ipa_hardware_config_qsb(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config_qsb() argument
230 iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_WRITES_OFFSET); in ipa_hardware_config_qsb()
234 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
240 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
244 iowrite32(val, ipa->reg_virt + IPA_REG_QSB_MAX_READS_OFFSET); in ipa_hardware_config_qsb()
261 /* IPA uses unified Qtime starting at IPA v4.5, implementing various
262 * timestamps and timers independent of the IPA core clock rate. The
266 * For IPA timestamps (tag, NAT, data path logging) a lower resolution
274 * timer ticks at a configurable frequency. IPA timers (such as
278 static void ipa_qtime_config(struct ipa *ipa) in ipa_qtime_config() argument
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()
301 iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET); in ipa_qtime_config()
305 iowrite32(val, ipa->reg_virt + IPA_REG_TIMERS_XO_CLK_DIV_CFG_OFFSET); in ipa_qtime_config()
308 static void ipa_idle_indication_cfg(struct ipa *ipa, in ipa_idle_indication_cfg() argument
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
326 * @ipa: IPA pointer
328 * Configures when the IPA signals it is idle to the global clock
332 static void ipa_hardware_dcd_config(struct ipa *ipa) in ipa_hardware_dcd_config() argument
334 /* Recommended values for IPA 3.5 and later according to IPA HPG */ in ipa_hardware_dcd_config()
335 ipa_idle_indication_cfg(ipa, 256, false); in ipa_hardware_dcd_config()
338 static void ipa_hardware_dcd_deconfig(struct ipa *ipa) in ipa_hardware_dcd_deconfig() argument
341 ipa_idle_indication_cfg(ipa, 0, true); in ipa_hardware_dcd_deconfig()
346 * @ipa: IPA pointer
347 * @data: IPA configuration data
349 static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config() argument
351 enum ipa_version version = ipa->version; in ipa_hardware_config()
355 /* IPA v4.5+ has no backward compatibility register */ 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()
378 ipa_hardware_config_comp(ipa); in ipa_hardware_config()
381 ipa_hardware_config_qsb(ipa, data); in ipa_hardware_config()
387 iowrite32(val, ipa->reg_virt + IPA_REG_COUNTER_CFG_OFFSET); in ipa_hardware_config()
389 ipa_qtime_config(ipa); in ipa_hardware_config()
392 /* IPA v4.2 does not support hashed tables, so disable them */ in ipa_hardware_config()
396 iowrite32(0, ipa->reg_virt + offset); in ipa_hardware_config()
400 ipa_hardware_dcd_config(ipa); in ipa_hardware_config()
405 * @ipa: IPA pointer
409 static void ipa_hardware_deconfig(struct ipa *ipa) in ipa_hardware_deconfig() argument
412 ipa_hardware_dcd_deconfig(ipa); in ipa_hardware_deconfig()
416 * ipa_config() - Configure IPA hardware
417 * @ipa: IPA pointer
418 * @data: IPA configuration data
420 * Perform initialization requiring IPA power to be enabled.
422 static int ipa_config(struct ipa *ipa, const struct ipa_data *data) in ipa_config() argument
426 ipa_hardware_config(ipa, data); in ipa_config()
428 ret = ipa_mem_config(ipa); in ipa_config()
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()
439 ipa_uc_config(ipa); in ipa_config()
441 ret = ipa_endpoint_config(ipa); in ipa_config()
445 ipa_table_config(ipa); /* No deconfig required */ in ipa_config()
448 ret = ipa_resource_config(ipa, data->resource_data); in ipa_config()
452 ret = ipa_modem_config(ipa); in ipa_config()
459 ipa_endpoint_deconfig(ipa); in ipa_config()
461 ipa_uc_deconfig(ipa); in ipa_config()
462 ipa_interrupt_deconfig(ipa->interrupt); in ipa_config()
463 ipa->interrupt = NULL; in ipa_config()
465 ipa_mem_deconfig(ipa); in ipa_config()
467 ipa_hardware_deconfig(ipa); in ipa_config()
474 * @ipa: IPA pointer
476 static void ipa_deconfig(struct ipa *ipa) in ipa_deconfig() argument
478 ipa_modem_deconfig(ipa); in ipa_deconfig()
479 ipa_endpoint_deconfig(ipa); in ipa_deconfig()
480 ipa_uc_deconfig(ipa); in ipa_deconfig()
481 ipa_interrupt_deconfig(ipa->interrupt); in ipa_deconfig()
482 ipa->interrupt = NULL; in ipa_deconfig()
483 ipa_mem_deconfig(ipa); in ipa_deconfig()
484 ipa_hardware_deconfig(ipa); in ipa_deconfig()
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",
640 * ipa_probe() - IPA platform driver probe function
646 * This is the main entry point for the IPA driver. Initialization proceeds
649 * access to the IPA hardware.
650 * - The "config" stage requires IPA power to be active so IPA registers
651 * can be accessed, but does not require the use of IPA immediate commands.
652 * - The "setup" stage uses IPA immediate commands, and so requires the GSI
660 * to the AP; this triggers the start if IPA setup.
668 struct ipa *ipa; in ipa_probe() local
681 dev_err(dev, "invalid IPA version\n"); in ipa_probe()
698 /* No more EPROBE_DEFER. Allocate and initialize the IPA structure */ in ipa_probe()
699 ipa = kzalloc(sizeof(*ipa), GFP_KERNEL); in ipa_probe()
700 if (!ipa) { in ipa_probe()
705 ipa->pdev = pdev; in ipa_probe()
706 dev_set_drvdata(dev, ipa); 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()
711 ret = ipa_reg_init(ipa); 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()
725 ipa->filter_map = ipa_endpoint_init(ipa, data->endpoint_count, in ipa_probe()
727 if (!ipa->filter_map) { in ipa_probe()
732 ret = ipa_table_init(ipa); in ipa_probe()
736 ret = ipa_modem_init(ipa, modem_init); in ipa_probe()
745 ret = ipa_config(ipa, data); in ipa_probe()
749 dev_info(dev, "IPA driver initialized"); in ipa_probe()
765 ret = ipa_setup(ipa); in ipa_probe()
775 ipa_deconfig(ipa); in ipa_probe()
778 ipa_modem_exit(ipa); in ipa_probe()
780 ipa_table_exit(ipa); in ipa_probe()
782 ipa_endpoint_exit(ipa); in ipa_probe()
784 gsi_exit(&ipa->gsi); in ipa_probe()
786 ipa_mem_exit(ipa); in ipa_probe()
788 ipa_reg_exit(ipa); in ipa_probe()
790 kfree(ipa); in ipa_probe()
799 struct ipa *ipa = dev_get_drvdata(&pdev->dev); in ipa_remove() local
800 struct ipa_power *power = ipa->power; in ipa_remove()
808 if (ipa->setup_complete) { in ipa_remove()
809 ret = ipa_modem_stop(ipa); in ipa_remove()
813 ret = ipa_modem_stop(ipa); in ipa_remove()
818 ipa_teardown(ipa); in ipa_remove()
821 ipa_deconfig(ipa); in ipa_remove()
824 ipa_modem_exit(ipa); in ipa_remove()
825 ipa_table_exit(ipa); in ipa_remove()
826 ipa_endpoint_exit(ipa); in ipa_remove()
827 gsi_exit(&ipa->gsi); in ipa_remove()
828 ipa_mem_exit(ipa); in ipa_remove()
829 ipa_reg_exit(ipa); in ipa_remove()
830 kfree(ipa); in ipa_remove()
857 .name = "ipa",