Lines Matching +full:pci +full:- +full:x

1 // SPDX-License-Identifier: BSD-3-Clause-Clear
3 * Copyright (c) 2019-2020 The Linux Foundation. All rights reserved.
4 * Copyright (c) 2021-2025 Qualcomm Innovation Center, Inc. All rights reserved.
9 #include <linux/pci.h>
20 #include "pci.h"
49 MODULE_DEVICE_TABLE(pci, ath11k_pci_id_table);
55 return mhi_device_get_sync(ab_pci->mhi_ctrl->mhi_dev); in ath11k_pci_bus_wake_up()
62 mhi_device_put(ab_pci->mhi_ctrl->mhi_dev); in ath11k_pci_bus_release()
67 if (!ab->hw_params.static_window_map) in ath11k_pci_get_window_start()
83 struct ath11k_base *ab = ab_pci->ab; in ath11k_pci_select_window()
87 lockdep_assert_held(&ab_pci->window_lock); in ath11k_pci_select_window()
89 if (window != ab_pci->register_window) { in ath11k_pci_select_window()
92 ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); in ath11k_pci_select_window()
93 ioread32(ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); in ath11k_pci_select_window()
96 (char *)ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); in ath11k_pci_select_window()
97 ioread32((char *)ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); in ath11k_pci_select_window()
99 ab_pci->register_window = window; in ath11k_pci_select_window()
112 spin_lock_bh(&ab_pci->window_lock); in ath11k_pci_window_write32()
115 iowrite32(value, ab->mem + window_start + in ath11k_pci_window_write32()
117 iowrite32(value, (char *)ab->mem + window_start + in ath11k_pci_window_write32()
120 spin_unlock_bh(&ab_pci->window_lock); in ath11k_pci_window_write32()
123 iowrite32(value, ab->mem + window_start + in ath11k_pci_window_write32()
125 iowrite32(value, (char *)ab->mem + window_start + in ath11k_pci_window_write32()
139 spin_lock_bh(&ab_pci->window_lock); in ath11k_pci_window_read32()
142 val = ioread32(ab->mem + window_start + in ath11k_pci_window_read32()
144 val = ioread32((char *)ab->mem + window_start + in ath11k_pci_window_read32()
147 spin_unlock_bh(&ab_pci->window_lock); in ath11k_pci_window_read32()
150 val = ioread32(ab->mem + window_start + in ath11k_pci_window_read32()
152 val = ioread32((char *)ab->mem + window_start + in ath11k_pci_window_read32()
162 struct pci_dev *pci_dev = to_pci_dev(ab->dev); in ath11k_pci_get_msi_irq()
206 ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); in ath11k_pci_select_static_window()
208 (char *)ab_pci->ab->mem + ATH11K_PCI_WINDOW_REG_ADDRESS); in ath11k_pci_select_static_window()
244 ath11k_dbg(ab, ATH11K_DBG_PCI, "pcie_q6_cookie_addr 0x%x\n", val); in ath11k_pci_clear_dbg_registers()
247 ath11k_dbg(ab, ATH11K_DBG_PCI, "wlaon_warm_sw_entry 0x%x\n", val); in ath11k_pci_clear_dbg_registers()
259 ath11k_dbg(ab, ATH11K_DBG_PCI, "wlaon_warm_sw_entry 0x%x\n", val); in ath11k_pci_clear_dbg_registers()
288 ath11k_warn(ab, "failed to set pcie link register 0x%08x: 0x%08x != 0x%08x\n", in ath11k_pci_set_link_reg()
291 return -ETIMEDOUT; in ath11k_pci_set_link_reg()
353 ath11k_dbg(ab, ATH11K_DBG_PCI, "ltssm 0x%x\n", val); in ath11k_pci_enable_ltssm()
360 ath11k_dbg(ab, ATH11K_DBG_PCI, "pcie_hot_rst 0x%x\n", val); in ath11k_pci_enable_ltssm()
398 if (ab->hw_params.fix_l1ss) in ath11k_pci_sw_reset()
410 struct ath11k_qmi_ce_cfg *cfg = &ab->qmi.ce_cfg; in ath11k_pci_init_qmi_ce_config()
412 cfg->tgt_ce = ab->hw_params.target_ce_config; in ath11k_pci_init_qmi_ce_config()
413 cfg->tgt_ce_len = ab->hw_params.target_ce_count; in ath11k_pci_init_qmi_ce_config()
415 cfg->svc_to_ce_map = ab->hw_params.svc_to_ce_map; in ath11k_pci_init_qmi_ce_config()
416 cfg->svc_to_ce_map_len = ab->hw_params.svc_to_ce_map_len; in ath11k_pci_init_qmi_ce_config()
417 ab->qmi.service_ins_id = ab->hw_params.qmi_service_ins_id; in ath11k_pci_init_qmi_ce_config()
419 ath11k_ce_get_shadow_config(ab, &cfg->shadow_reg_v2, in ath11k_pci_init_qmi_ce_config()
420 &cfg->shadow_reg_v2_len); in ath11k_pci_init_qmi_ce_config()
425 struct pci_dev *dev = ab_pci->pdev; in ath11k_pci_msi_config()
428 pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control); in ath11k_pci_msi_config()
435 pci_write_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, control); in ath11k_pci_msi_config()
450 struct ath11k_base *ab = ab_pci->ab; in ath11k_pci_alloc_msi()
451 const struct ath11k_msi_config *msi_config = ab->pci.msi.config; in ath11k_pci_alloc_msi()
452 struct pci_dev *pci_dev = ab_pci->pdev; in ath11k_pci_alloc_msi()
458 msi_config->total_vectors, in ath11k_pci_alloc_msi()
459 msi_config->total_vectors, in ath11k_pci_alloc_msi()
461 if (num_vectors == msi_config->total_vectors) { in ath11k_pci_alloc_msi()
462 set_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); in ath11k_pci_alloc_msi()
464 num_vectors = pci_alloc_irq_vectors(ab_pci->pdev, in ath11k_pci_alloc_msi()
469 ret = -EINVAL; in ath11k_pci_alloc_msi()
472 clear_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags); in ath11k_pci_alloc_msi()
473 ab->pci.msi.config = &msi_config_one_msi; in ath11k_pci_alloc_msi()
480 msi_desc = irq_get_msi_desc(ab_pci->pdev->irq); in ath11k_pci_alloc_msi()
483 ret = -EINVAL; in ath11k_pci_alloc_msi()
487 ab->pci.msi.ep_base_data = msi_desc->msg.data; in ath11k_pci_alloc_msi()
489 pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_LO, in ath11k_pci_alloc_msi()
490 &ab->pci.msi.addr_lo); in ath11k_pci_alloc_msi()
492 if (msi_desc->pci.msi_attrib.is_64) { in ath11k_pci_alloc_msi()
493 pci_read_config_dword(pci_dev, pci_dev->msi_cap + PCI_MSI_ADDRESS_HI, in ath11k_pci_alloc_msi()
494 &ab->pci.msi.addr_hi); in ath11k_pci_alloc_msi()
496 ab->pci.msi.addr_hi = 0; in ath11k_pci_alloc_msi()
499 ath11k_dbg(ab, ATH11K_DBG_PCI, "msi base data is %d\n", ab->pci.msi.ep_base_data); in ath11k_pci_alloc_msi()
504 pci_free_irq_vectors(ab_pci->pdev); in ath11k_pci_alloc_msi()
512 pci_free_irq_vectors(ab_pci->pdev); in ath11k_pci_free_msi()
519 msi_desc = irq_get_msi_desc(ab_pci->pdev->irq); in ath11k_pci_config_msi_data()
521 ath11k_err(ab_pci->ab, "msi_desc is NULL!\n"); in ath11k_pci_config_msi_data()
522 pci_free_irq_vectors(ab_pci->pdev); in ath11k_pci_config_msi_data()
523 return -EINVAL; in ath11k_pci_config_msi_data()
526 ab_pci->ab->pci.msi.ep_base_data = msi_desc->msg.data; in ath11k_pci_config_msi_data()
528 ath11k_dbg(ab_pci->ab, ATH11K_DBG_PCI, "after request_irq msi_ep_base_data %d\n", in ath11k_pci_config_msi_data()
529 ab_pci->ab->pci.msi.ep_base_data); in ath11k_pci_config_msi_data()
536 struct ath11k_base *ab = ab_pci->ab; in ath11k_pci_claim()
541 if (device_id != ab_pci->dev_id) { in ath11k_pci_claim()
542 ath11k_err(ab, "pci device id mismatch: 0x%x 0x%x\n", in ath11k_pci_claim()
543 device_id, ab_pci->dev_id); in ath11k_pci_claim()
544 ret = -EIO; in ath11k_pci_claim()
550 ath11k_err(ab, "failed to assign pci resource: %d\n", ret); in ath11k_pci_claim()
556 ath11k_err(ab, "failed to enable pci device: %d\n", ret); in ath11k_pci_claim()
562 ath11k_err(ab, "failed to request pci region: %d\n", ret); in ath11k_pci_claim()
566 ret = dma_set_mask(&pdev->dev, in ath11k_pci_claim()
569 ath11k_err(ab, "failed to set pci dma mask to %d: %d\n", in ath11k_pci_claim()
574 ab_pci->dma_mask = DMA_BIT_MASK(ATH11K_PCI_DMA_MASK); in ath11k_pci_claim()
576 ret = dma_set_coherent_mask(&pdev->dev, in ath11k_pci_claim()
579 ath11k_err(ab, "failed to set pci coherent dma mask to %d: %d\n", in ath11k_pci_claim()
586 ab->mem_len = pci_resource_len(pdev, ATH11K_PCI_BAR_NUM); in ath11k_pci_claim()
587 ab->mem = pci_iomap(pdev, ATH11K_PCI_BAR_NUM, 0); in ath11k_pci_claim()
588 if (!ab->mem) { in ath11k_pci_claim()
589 ath11k_err(ab, "failed to map pci bar %d\n", ATH11K_PCI_BAR_NUM); in ath11k_pci_claim()
590 ret = -EIO; in ath11k_pci_claim()
594 ab->mem_ce = ab->mem; in ath11k_pci_claim()
596 ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci_mem 0x%p\n", ab->mem); in ath11k_pci_claim()
609 struct ath11k_base *ab = ab_pci->ab; in ath11k_pci_free_region()
610 struct pci_dev *pci_dev = ab_pci->pdev; in ath11k_pci_free_region()
612 pci_iounmap(pci_dev, ab->mem); in ath11k_pci_free_region()
613 ab->mem = NULL; in ath11k_pci_free_region()
621 struct ath11k_base *ab = ab_pci->ab; in ath11k_pci_aspm_disable()
623 pcie_capability_read_word(ab_pci->pdev, PCI_EXP_LNKCTL, in ath11k_pci_aspm_disable()
624 &ab_pci->link_ctl); in ath11k_pci_aspm_disable()
626 ath11k_dbg(ab, ATH11K_DBG_PCI, "link_ctl 0x%04x L0s %d L1 %d\n", in ath11k_pci_aspm_disable()
627 ab_pci->link_ctl, in ath11k_pci_aspm_disable()
628 u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L0S), in ath11k_pci_aspm_disable()
629 u16_get_bits(ab_pci->link_ctl, PCI_EXP_LNKCTL_ASPM_L1)); in ath11k_pci_aspm_disable()
632 pcie_capability_clear_word(ab_pci->pdev, PCI_EXP_LNKCTL, in ath11k_pci_aspm_disable()
635 set_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags); in ath11k_pci_aspm_disable()
640 if (test_and_clear_bit(ATH11K_PCI_ASPM_RESTORE, &ab_pci->flags)) in ath11k_pci_aspm_restore()
641 pcie_capability_clear_and_set_word(ab_pci->pdev, PCI_EXP_LNKCTL, in ath11k_pci_aspm_restore()
643 ab_pci->link_ctl & in ath11k_pci_aspm_restore()
651 struct mhi_controller *mhi_ctrl = ab_pci->mhi_ctrl; in ath11k_pci_coredump_calculate_size()
659 rddm_img = mhi_ctrl->rddm_image; in ath11k_pci_coredump_calculate_size()
665 fw_img = mhi_ctrl->fbc_image; in ath11k_pci_coredump_calculate_size()
667 for (i = 0; i < fw_img->entries ; i++) { in ath11k_pci_coredump_calculate_size()
668 if (!fw_img->mhi_buf[i].buf) in ath11k_pci_coredump_calculate_size()
671 paging_tlv_sz += fw_img->mhi_buf[i].len; in ath11k_pci_coredump_calculate_size()
675 for (i = 0; i < rddm_img->entries; i++) { in ath11k_pci_coredump_calculate_size()
676 if (!rddm_img->mhi_buf[i].buf) in ath11k_pci_coredump_calculate_size()
679 rddm_tlv_sz += rddm_img->mhi_buf[i].len; in ath11k_pci_coredump_calculate_size()
683 for (i = 0; i < ab->qmi.mem_seg_count; i++) { in ath11k_pci_coredump_calculate_size()
684 mem_type = ath11k_coredump_get_dump_type(ab->qmi.target_mem[i].type); in ath11k_pci_coredump_calculate_size()
692 ab->qmi.target_mem[i].type); in ath11k_pci_coredump_calculate_size()
696 if (!ab->qmi.target_mem[i].anyaddr) in ath11k_pci_coredump_calculate_size()
699 dump_seg_sz[mem_type] += ab->qmi.target_mem[i].size; in ath11k_pci_coredump_calculate_size()
718 struct mhi_controller *mhi_ctrl = ab_pci->mhi_ctrl; in ath11k_pci_coredump_download()
737 rddm_img = mhi_ctrl->rddm_image; in ath11k_pci_coredump_download()
738 fw_img = mhi_ctrl->fbc_image; in ath11k_pci_coredump_download()
745 ab->dump_data = buf; in ath11k_pci_coredump_download()
746 ab->ath11k_coredump_len = len; in ath11k_pci_coredump_download()
747 file_data = ab->dump_data; in ath11k_pci_coredump_download()
748 strscpy(file_data->df_magic, "ATH11K-FW-DUMP", sizeof(file_data->df_magic)); in ath11k_pci_coredump_download()
749 file_data->len = cpu_to_le32(len); in ath11k_pci_coredump_download()
750 file_data->version = cpu_to_le32(ATH11K_FW_CRASH_DUMP_V2); in ath11k_pci_coredump_download()
751 file_data->chip_id = cpu_to_le32(ab_pci->dev_id); in ath11k_pci_coredump_download()
752 file_data->qrtr_id = cpu_to_le32(ab_pci->ab->qmi.service_ins_id); in ath11k_pci_coredump_download()
753 file_data->bus_id = cpu_to_le32(pci_domain_nr(ab_pci->pdev->bus)); in ath11k_pci_coredump_download()
754 guid_gen(&file_data->guid); in ath11k_pci_coredump_download()
756 file_data->tv_sec = cpu_to_le64(timestamp.tv_sec); in ath11k_pci_coredump_download()
757 file_data->tv_nsec = cpu_to_le64(timestamp.tv_nsec); in ath11k_pci_coredump_download()
760 dump_tlv->type = cpu_to_le32(FW_CRASH_DUMP_PAGING_DATA); in ath11k_pci_coredump_download()
761 dump_tlv->tlv_len = cpu_to_le32(dump_seg_sz[FW_CRASH_DUMP_PAGING_DATA]); in ath11k_pci_coredump_download()
767 for (i = 0; i < fw_img->entries ; i++) { in ath11k_pci_coredump_download()
768 if (!fw_img->mhi_buf[i].buf) in ath11k_pci_coredump_download()
771 memcpy_fromio(buf, (void const __iomem *)fw_img->mhi_buf[i].buf, in ath11k_pci_coredump_download()
772 fw_img->mhi_buf[i].len); in ath11k_pci_coredump_download()
773 buf += fw_img->mhi_buf[i].len; in ath11k_pci_coredump_download()
777 dump_tlv->type = cpu_to_le32(FW_CRASH_DUMP_RDDM_DATA); in ath11k_pci_coredump_download()
778 dump_tlv->tlv_len = cpu_to_le32(dump_seg_sz[FW_CRASH_DUMP_RDDM_DATA]); in ath11k_pci_coredump_download()
784 for (i = 0; i < rddm_img->entries; i++) { in ath11k_pci_coredump_download()
785 if (!rddm_img->mhi_buf[i].buf) in ath11k_pci_coredump_download()
788 memcpy_fromio(buf, (void const __iomem *)rddm_img->mhi_buf[i].buf, in ath11k_pci_coredump_download()
789 rddm_img->mhi_buf[i].len); in ath11k_pci_coredump_download()
790 buf += rddm_img->mhi_buf[i].len; in ath11k_pci_coredump_download()
798 for (i = 0; i < ab->qmi.mem_seg_count; i++) { in ath11k_pci_coredump_download()
800 (ab->qmi.target_mem[i].type); in ath11k_pci_coredump_download()
805 if (!ab->qmi.target_mem[i].anyaddr) { in ath11k_pci_coredump_download()
808 ab->qmi.target_mem[i].type); in ath11k_pci_coredump_download()
813 dump_tlv->type = cpu_to_le32(mem_idx); in ath11k_pci_coredump_download()
814 dump_tlv->tlv_len = cpu_to_le32(dump_seg_sz[mem_idx]); in ath11k_pci_coredump_download()
817 memcpy_fromio(buf, ab->qmi.target_mem[i].iaddr, in ath11k_pci_coredump_download()
818 ab->qmi.target_mem[i].size); in ath11k_pci_coredump_download()
820 buf += ab->qmi.target_mem[i].size; in ath11k_pci_coredump_download()
824 queue_work(ab->workqueue, &ab->dump_work); in ath11k_pci_coredump_download()
833 ab_pci->register_window = 0; in ath11k_pci_power_up()
834 clear_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags); in ath11k_pci_power_up()
835 ath11k_pci_sw_reset(ab_pci->ab, true); in ath11k_pci_power_up()
850 if (ab->hw_params.static_window_map) in ath11k_pci_power_up()
863 ath11k_pci_force_wake(ab_pci->ab); in ath11k_pci_power_down()
868 clear_bit(ATH11K_FLAG_DEVICE_INIT_DONE, &ab->dev_flags); in ath11k_pci_power_down()
869 ath11k_pci_sw_reset(ab_pci->ab, false); in ath11k_pci_power_down()
903 if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab->dev_flags)) in ath11k_pci_start()
906 ath11k_info(ab, "leaving PCI ASPM disabled to avoid MHI M2 problems\n"); in ath11k_pci_start()
957 if (test_bit(ATH11K_FLAG_MULTI_MSI_VECTORS, &ab_pci->ab->dev_flags)) in ath11k_pci_set_irq_affinity_hint()
960 return irq_set_affinity_and_hint(ab_pci->pdev->irq, m); in ath11k_pci_set_irq_affinity_hint()
973 ab = ath11k_core_alloc(&pdev->dev, sizeof(*ab_pci), ATH11K_BUS_PCI); in ath11k_pci_probe()
976 dev_err(&pdev->dev, "failed to allocate ath11k base\n"); in ath11k_pci_probe()
977 return -ENOMEM; in ath11k_pci_probe()
980 ab->dev = &pdev->dev; in ath11k_pci_probe()
983 ab_pci->dev_id = pci_dev->device; in ath11k_pci_probe()
984 ab_pci->ab = ab; in ath11k_pci_probe()
985 ab_pci->pdev = pdev; in ath11k_pci_probe()
986 ab->hif.ops = &ath11k_pci_hif_ops; in ath11k_pci_probe()
987 ab->fw_mode = ATH11K_FIRMWARE_MODE_NORMAL; in ath11k_pci_probe()
989 spin_lock_init(&ab_pci->window_lock); in ath11k_pci_probe()
996 if (of_property_present(ab->dev->of_node, "memory-region")) in ath11k_pci_probe()
997 set_bit(ATH11K_FLAG_FIXED_MEM_RGN, &ab->dev_flags); in ath11k_pci_probe()
1006 ath11k_dbg(ab, ATH11K_DBG_BOOT, "pci probe %04x:%04x %04x:%04x\n", in ath11k_pci_probe()
1007 pdev->vendor, pdev->device, in ath11k_pci_probe()
1008 pdev->subsystem_vendor, pdev->subsystem_device); in ath11k_pci_probe()
1010 ab->id.vendor = pdev->vendor; in ath11k_pci_probe()
1011 ab->id.device = pdev->device; in ath11k_pci_probe()
1012 ab->id.subsystem_vendor = pdev->subsystem_vendor; in ath11k_pci_probe()
1013 ab->id.subsystem_device = pdev->subsystem_device; in ath11k_pci_probe()
1015 switch (pci_dev->device) { in ath11k_pci_probe()
1019 ath11k_err(ab, "failed to register PCI ops: %d\n", ret); in ath11k_pci_probe()
1027 ab->hw_rev = ATH11K_HW_QCA6390_HW20; in ath11k_pci_probe()
1030 dev_err(&pdev->dev, "Unsupported QCA6390 SOC hardware version: %d %d\n", in ath11k_pci_probe()
1032 ret = -EOPNOTSUPP; in ath11k_pci_probe()
1040 ath11k_err(ab, "failed to register PCI ops: %d\n", ret); in ath11k_pci_probe()
1043 ab->hw_rev = ATH11K_HW_QCN9074_HW10; in ath11k_pci_probe()
1048 ath11k_err(ab, "failed to register PCI ops: %d\n", ret); in ath11k_pci_probe()
1051 ab->id.bdf_search = ATH11K_BDF_SEARCH_BUS_AND_BOARD; in ath11k_pci_probe()
1059 ab->hw_rev = ATH11K_HW_WCN6855_HW20; in ath11k_pci_probe()
1064 ath11k_dbg(ab, ATH11K_DBG_PCI, "sub_version 0x%x\n", in ath11k_pci_probe()
1071 ab->hw_rev = ATH11K_HW_QCA2066_HW21; in ath11k_pci_probe()
1074 ab->hw_rev = ATH11K_HW_QCA6698AQ_HW21; in ath11k_pci_probe()
1077 ab->hw_rev = ATH11K_HW_WCN6855_HW21; in ath11k_pci_probe()
1086 dev_err(&pdev->dev, "Unsupported WCN6855 SOC hardware version: %d %d\n", in ath11k_pci_probe()
1088 ret = -EOPNOTSUPP; in ath11k_pci_probe()
1094 dev_err(&pdev->dev, "Unknown PCI device found: 0x%x\n", in ath11k_pci_probe()
1095 pci_dev->device); in ath11k_pci_probe()
1096 ret = -EOPNOTSUPP; in ath11k_pci_probe()
1201 if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) { in ath11k_pci_remove()
1209 set_bit(ATH11K_FLAG_UNREGISTERING, &ab->dev_flags); in ath11k_pci_remove()
1211 cancel_work_sync(&ab->reset_work); in ath11k_pci_remove()
1212 cancel_work_sync(&ab->dump_work); in ath11k_pci_remove()
1243 if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) { in ath11k_pci_pm_suspend()
1244 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot skipping pci suspend as qmi is not initialised\n"); in ath11k_pci_pm_suspend()
1260 if (test_bit(ATH11K_FLAG_QMI_FAIL, &ab->dev_flags)) { in ath11k_pci_pm_resume()
1261 ath11k_dbg(ab, ATH11K_DBG_BOOT, "boot skipping pci resume as qmi is not initialised\n"); in ath11k_pci_pm_resume()
1294 pr_err("failed to register ath11k pci driver: %d\n", in ath11k_pci_init()