Lines Matching full:ipa
22 #include "ipa.h"
41 * This driver supports the Qualcomm IP Accelerator (IPA), which is a
42 * networking component found in many Qualcomm SoCs. The IPA is connected
46 * The IPA is the conduit between the AP and the modem that carries network
50 * The IPA provides protocol checksum calculation, offloading this work
51 * from the AP. The IPA offers additional functionality, including routing,
57 * There are two distinct layers that implement the IPA hardware, and this
59 * interface (GSI) is an integral component of the IPA, providing a
60 * well-defined communication layer between the AP subsystem and the IPA
62 * between the AP and the IPA.
64 * The IPA layer uses GSI channels to implement its "endpoints". And while
65 * a GSI channel carries data between the AP and the IPA, a pair of IPA
102 * ipa_setup() - Set up IPA hardware
103 * @ipa: IPA pointer
112 int ipa_setup(struct ipa *ipa) in ipa_setup() argument
116 struct device *dev = &ipa->pdev->dev; in ipa_setup()
119 ret = gsi_setup(&ipa->gsi); in ipa_setup()
123 ret = ipa_power_setup(ipa); in ipa_setup()
127 ipa_endpoint_setup(ipa); in ipa_setup()
132 command_endpoint = ipa->name_map[IPA_ENDPOINT_AP_COMMAND_TX]; in ipa_setup()
137 ret = ipa_mem_setup(ipa); /* No matching teardown required */ in ipa_setup()
141 ret = ipa_table_setup(ipa); /* No matching teardown required */ 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()
156 ret = ipa_qmi_setup(ipa); in ipa_setup()
160 ipa->setup_complete = true; in ipa_setup()
162 dev_info(dev, "IPA driver setup completed successfully\n"); in ipa_setup()
167 ipa_endpoint_default_route_clear(ipa); in ipa_setup()
172 ipa_endpoint_teardown(ipa); in ipa_setup()
173 ipa_power_teardown(ipa); in ipa_setup()
175 gsi_teardown(&ipa->gsi); in ipa_setup()
182 * @ipa: IPA pointer
184 static void ipa_teardown(struct ipa *ipa) in ipa_teardown() argument
190 ipa->setup_complete = false; in ipa_teardown()
192 ipa_qmi_teardown(ipa); in ipa_teardown()
193 ipa_endpoint_default_route_clear(ipa); 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()
198 ipa_endpoint_teardown(ipa); in ipa_teardown()
199 ipa_power_teardown(ipa); in ipa_teardown()
200 gsi_teardown(&ipa->gsi); in ipa_teardown()
204 ipa_hardware_config_bcr(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config_bcr() argument
209 /* IPA v4.5+ has no backward compatibility register */ in ipa_hardware_config_bcr()
210 if (ipa->version >= IPA_VERSION_4_5) in ipa_hardware_config_bcr()
213 reg = ipa_reg(ipa, IPA_BCR); in ipa_hardware_config_bcr()
215 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_bcr()
218 static void ipa_hardware_config_tx(struct ipa *ipa) in ipa_hardware_config_tx() argument
220 enum ipa_version version = ipa->version; in ipa_hardware_config_tx()
229 reg = ipa_reg(ipa, IPA_TX_CFG); 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()
239 static void ipa_hardware_config_clkon(struct ipa *ipa) in ipa_hardware_config_clkon() argument
241 enum ipa_version version = ipa->version; in ipa_hardware_config_clkon()
252 reg = ipa_reg(ipa, CLKON_CFG); in ipa_hardware_config_clkon()
256 } else { /* IPA v4.0+ */ in ipa_hardware_config_clkon()
262 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_clkon()
265 /* Configure bus access behavior for IPA components */
266 static void ipa_hardware_config_comp(struct ipa *ipa) in ipa_hardware_config_comp() argument
272 /* Nothing to configure prior to IPA v4.0 */ in ipa_hardware_config_comp()
273 if (ipa->version < IPA_VERSION_4_0) in ipa_hardware_config_comp()
276 reg = ipa_reg(ipa, COMP_CFG); 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()
288 /* For IPA v4.5+ FULL_FLUSH_WAIT_RS_CLOSURE_EN is 0 */ in ipa_hardware_config_comp()
294 iowrite32(val, ipa->reg_virt + offset); in ipa_hardware_config_comp()
299 ipa_hardware_config_qsb(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config_qsb() argument
312 reg = ipa_reg(ipa, QSB_MAX_WRITES); in ipa_hardware_config_qsb()
318 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
321 reg = ipa_reg(ipa, QSB_MAX_READS); in ipa_hardware_config_qsb()
324 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
329 if (ipa->version >= IPA_VERSION_4_0) in ipa_hardware_config_qsb()
334 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_qsb()
351 /* IPA uses unified Qtime starting at IPA v4.5, implementing various
352 * timestamps and timers independent of the IPA core clock rate. The
356 * For IPA timestamps (tag, NAT, data path logging) a lower resolution
364 * timer ticks at a configurable frequency. IPA timers (such as
368 static void ipa_qtime_config(struct ipa *ipa) in ipa_qtime_config() argument
375 reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG); in ipa_qtime_config()
376 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
378 reg = ipa_reg(ipa, QTIME_TIMESTAMP_CFG); in ipa_qtime_config()
386 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_qtime_config()
389 reg = ipa_reg(ipa, TIMERS_PULSE_GRAN_CFG); 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()
402 reg = ipa_reg(ipa, TIMERS_XO_CLK_DIV_CFG); in ipa_qtime_config()
407 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
412 iowrite32(val, ipa->reg_virt + offset); in ipa_qtime_config()
415 /* Before IPA v4.5 timing is controlled by a counter register */
416 static void ipa_hardware_config_counter(struct ipa *ipa) in ipa_hardware_config_counter() argument
422 reg = ipa_reg(ipa, COUNTER_CFG); in ipa_hardware_config_counter()
425 iowrite32(val, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_counter()
428 static void ipa_hardware_config_timing(struct ipa *ipa) in ipa_hardware_config_timing() argument
430 if (ipa->version < IPA_VERSION_4_5) in ipa_hardware_config_timing()
431 ipa_hardware_config_counter(ipa); in ipa_hardware_config_timing()
433 ipa_qtime_config(ipa); in ipa_hardware_config_timing()
436 static void ipa_hardware_config_hashing(struct ipa *ipa) in ipa_hardware_config_hashing() argument
440 /* Other than IPA v4.2, all versions enable "hashing". Starting in ipa_hardware_config_hashing()
441 * with IPA v5.0, the filter and router tables are implemented in ipa_hardware_config_hashing()
445 if (ipa->version != IPA_VERSION_4_2) in ipa_hardware_config_hashing()
448 /* IPA v4.2 does not support hashed tables, so disable them */ in ipa_hardware_config_hashing()
449 reg = ipa_reg(ipa, FILT_ROUT_HASH_EN); in ipa_hardware_config_hashing()
454 iowrite32(0, ipa->reg_virt + reg_offset(reg)); in ipa_hardware_config_hashing()
457 static void ipa_idle_indication_cfg(struct ipa *ipa, in ipa_idle_indication_cfg() argument
464 if (ipa->version < IPA_VERSION_3_5_1) in ipa_idle_indication_cfg()
467 reg = ipa_reg(ipa, IDLE_INDICATION_CFG); 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
478 * @ipa: IPA pointer
480 * Configures when the IPA signals it is idle to the global clock
484 static void ipa_hardware_dcd_config(struct ipa *ipa) in ipa_hardware_dcd_config() argument
486 /* Recommended values for IPA 3.5 and later according to IPA HPG */ in ipa_hardware_dcd_config()
487 ipa_idle_indication_cfg(ipa, 256, false); in ipa_hardware_dcd_config()
490 static void ipa_hardware_dcd_deconfig(struct ipa *ipa) in ipa_hardware_dcd_deconfig() argument
493 ipa_idle_indication_cfg(ipa, 0, true); in ipa_hardware_dcd_deconfig()
498 * @ipa: IPA pointer
499 * @data: IPA configuration data
501 static void ipa_hardware_config(struct ipa *ipa, const struct ipa_data *data) in ipa_hardware_config() argument
503 ipa_hardware_config_bcr(ipa, data); in ipa_hardware_config()
504 ipa_hardware_config_tx(ipa); in ipa_hardware_config()
505 ipa_hardware_config_clkon(ipa); in ipa_hardware_config()
506 ipa_hardware_config_comp(ipa); in ipa_hardware_config()
507 ipa_hardware_config_qsb(ipa, data); in ipa_hardware_config()
508 ipa_hardware_config_timing(ipa); in ipa_hardware_config()
509 ipa_hardware_config_hashing(ipa); in ipa_hardware_config()
510 ipa_hardware_dcd_config(ipa); in ipa_hardware_config()
515 * @ipa: IPA pointer
519 static void ipa_hardware_deconfig(struct ipa *ipa) in ipa_hardware_deconfig() argument
522 ipa_hardware_dcd_deconfig(ipa); in ipa_hardware_deconfig()
526 * ipa_config() - Configure IPA hardware
527 * @ipa: IPA pointer
528 * @data: IPA configuration data
530 * Perform initialization requiring IPA power to be enabled.
532 static int ipa_config(struct ipa *ipa, const struct ipa_data *data) in ipa_config() argument
536 ipa_hardware_config(ipa, data); in ipa_config()
538 ret = ipa_mem_config(ipa); in ipa_config()
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()
549 ipa_uc_config(ipa); in ipa_config()
551 ret = ipa_endpoint_config(ipa); in ipa_config()
555 ipa_table_config(ipa); /* No deconfig required */ in ipa_config()
558 ret = ipa_resource_config(ipa, data->resource_data); in ipa_config()
562 ret = ipa_modem_config(ipa); in ipa_config()
569 ipa_endpoint_deconfig(ipa); in ipa_config()
571 ipa_uc_deconfig(ipa); in ipa_config()
572 ipa_interrupt_deconfig(ipa->interrupt); in ipa_config()
573 ipa->interrupt = NULL; in ipa_config()
575 ipa_mem_deconfig(ipa); in ipa_config()
577 ipa_hardware_deconfig(ipa); in ipa_config()
584 * @ipa: IPA pointer
586 static void ipa_deconfig(struct ipa *ipa) in ipa_deconfig() argument
588 ipa_modem_deconfig(ipa); in ipa_deconfig()
589 ipa_endpoint_deconfig(ipa); in ipa_deconfig()
590 ipa_uc_deconfig(ipa); in ipa_deconfig()
591 ipa_interrupt_deconfig(ipa->interrupt); in ipa_deconfig()
592 ipa->interrupt = NULL; in ipa_deconfig()
593 ipa_mem_deconfig(ipa); in ipa_deconfig()
594 ipa_hardware_deconfig(ipa); in ipa_deconfig()
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",
779 * ipa_probe() - IPA platform driver probe function
785 * This is the main entry point for the IPA driver. Initialization proceeds
788 * access to the IPA hardware.
789 * - The "config" stage requires IPA power to be active so IPA registers
790 * can be accessed, but does not require the use of IPA immediate commands.
791 * - The "setup" stage uses IPA immediate commands, and so requires the GSI
799 * to the AP; this triggers the start if IPA setup.
807 struct ipa *ipa; in ipa_probe() local
820 dev_err(dev, "unsupported IPA version %u\n", data->version); in ipa_probe()
842 /* No more EPROBE_DEFER. Allocate and initialize the IPA structure */ in ipa_probe()
843 ipa = kzalloc(sizeof(*ipa), GFP_KERNEL); in ipa_probe()
844 if (!ipa) { in ipa_probe()
849 ipa->pdev = pdev; in ipa_probe()
850 dev_set_drvdata(dev, ipa); 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()
856 ret = ipa_reg_init(ipa); 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()
870 ret = ipa_endpoint_init(ipa, data->endpoint_count, data->endpoint_data); in ipa_probe()
874 ret = ipa_table_init(ipa); in ipa_probe()
878 ret = ipa_smp2p_init(ipa, loader == IPA_LOADER_MODEM); in ipa_probe()
887 ret = ipa_config(ipa, data); in ipa_probe()
891 dev_info(dev, "IPA driver initialized"); in ipa_probe()
907 ret = ipa_setup(ipa); in ipa_probe()
917 ipa_deconfig(ipa); in ipa_probe()
920 ipa_smp2p_exit(ipa); in ipa_probe()
922 ipa_table_exit(ipa); in ipa_probe()
924 ipa_endpoint_exit(ipa); in ipa_probe()
926 gsi_exit(&ipa->gsi); in ipa_probe()
928 ipa_mem_exit(ipa); in ipa_probe()
930 ipa_reg_exit(ipa); in ipa_probe()
932 kfree(ipa); in ipa_probe()
941 struct ipa *ipa = dev_get_drvdata(&pdev->dev); in ipa_remove() local
942 struct ipa_power *power = ipa->power; in ipa_remove()
949 ipa_smp2p_irq_disable_setup(ipa); in ipa_remove()
955 if (ipa->setup_complete) { in ipa_remove()
956 ret = ipa_modem_stop(ipa); in ipa_remove()
960 ret = ipa_modem_stop(ipa); in ipa_remove()
965 ipa_teardown(ipa); in ipa_remove()
968 ipa_deconfig(ipa); in ipa_remove()
971 ipa_smp2p_exit(ipa); in ipa_remove()
972 ipa_table_exit(ipa); in ipa_remove()
973 ipa_endpoint_exit(ipa); in ipa_remove()
974 gsi_exit(&ipa->gsi); in ipa_remove()
975 ipa_mem_exit(ipa); in ipa_remove()
976 ipa_reg_exit(ipa); in ipa_remove()
977 kfree(ipa); in ipa_remove()
980 dev_info(dev, "IPA driver removed"); in ipa_remove()
1007 .name = "ipa",