18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: ISC */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2005-2011 Atheros Communications Inc. 48c2ecf20Sopenharmony_ci * Copyright (c) 2011-2017 Qualcomm Atheros, Inc. 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#ifndef _PCI_H_ 88c2ecf20Sopenharmony_ci#define _PCI_H_ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 118c2ecf20Sopenharmony_ci#include <linux/mutex.h> 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include "hw.h" 148c2ecf20Sopenharmony_ci#include "ce.h" 158c2ecf20Sopenharmony_ci#include "ahb.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci/* 188c2ecf20Sopenharmony_ci * maximum number of bytes that can be 198c2ecf20Sopenharmony_ci * handled atomically by DiagRead/DiagWrite 208c2ecf20Sopenharmony_ci */ 218c2ecf20Sopenharmony_ci#define DIAG_TRANSFER_LIMIT 2048 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_cistruct bmi_xfer { 248c2ecf20Sopenharmony_ci bool tx_done; 258c2ecf20Sopenharmony_ci bool rx_done; 268c2ecf20Sopenharmony_ci bool wait_for_resp; 278c2ecf20Sopenharmony_ci u32 resp_len; 288c2ecf20Sopenharmony_ci}; 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci/* 318c2ecf20Sopenharmony_ci * PCI-specific Target state 328c2ecf20Sopenharmony_ci * 338c2ecf20Sopenharmony_ci * NOTE: Structure is shared between Host software and Target firmware! 348c2ecf20Sopenharmony_ci * 358c2ecf20Sopenharmony_ci * Much of this may be of interest to the Host so 368c2ecf20Sopenharmony_ci * HOST_INTEREST->hi_interconnect_state points here 378c2ecf20Sopenharmony_ci * (and all members are 32-bit quantities in order to 388c2ecf20Sopenharmony_ci * facilitate Host access). In particular, Host software is 398c2ecf20Sopenharmony_ci * required to initialize pipe_cfg_addr and svc_to_pipe_map. 408c2ecf20Sopenharmony_ci */ 418c2ecf20Sopenharmony_cistruct pcie_state { 428c2ecf20Sopenharmony_ci /* Pipe configuration Target address */ 438c2ecf20Sopenharmony_ci /* NB: ce_pipe_config[CE_COUNT] */ 448c2ecf20Sopenharmony_ci u32 pipe_cfg_addr; 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci /* Service to pipe map Target address */ 478c2ecf20Sopenharmony_ci /* NB: service_to_pipe[PIPE_TO_CE_MAP_CN] */ 488c2ecf20Sopenharmony_ci u32 svc_to_pipe_map; 498c2ecf20Sopenharmony_ci 508c2ecf20Sopenharmony_ci /* number of MSI interrupts requested */ 518c2ecf20Sopenharmony_ci u32 msi_requested; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci /* number of MSI interrupts granted */ 548c2ecf20Sopenharmony_ci u32 msi_granted; 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci /* Message Signalled Interrupt address */ 578c2ecf20Sopenharmony_ci u32 msi_addr; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci /* Base data */ 608c2ecf20Sopenharmony_ci u32 msi_data; 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci /* 638c2ecf20Sopenharmony_ci * Data for firmware interrupt; 648c2ecf20Sopenharmony_ci * MSI data for other interrupts are 658c2ecf20Sopenharmony_ci * in various SoC registers 668c2ecf20Sopenharmony_ci */ 678c2ecf20Sopenharmony_ci u32 msi_fw_intr_data; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci /* PCIE_PWR_METHOD_* */ 708c2ecf20Sopenharmony_ci u32 power_mgmt_method; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci /* PCIE_CONFIG_FLAG_* */ 738c2ecf20Sopenharmony_ci u32 config_flags; 748c2ecf20Sopenharmony_ci}; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci/* PCIE_CONFIG_FLAG definitions */ 778c2ecf20Sopenharmony_ci#define PCIE_CONFIG_FLAG_ENABLE_L1 0x0000001 788c2ecf20Sopenharmony_ci 798c2ecf20Sopenharmony_ci/* Per-pipe state. */ 808c2ecf20Sopenharmony_cistruct ath10k_pci_pipe { 818c2ecf20Sopenharmony_ci /* Handle of underlying Copy Engine */ 828c2ecf20Sopenharmony_ci struct ath10k_ce_pipe *ce_hdl; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci /* Our pipe number; facilitiates use of pipe_info ptrs. */ 858c2ecf20Sopenharmony_ci u8 pipe_num; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci /* Convenience back pointer to hif_ce_state. */ 888c2ecf20Sopenharmony_ci struct ath10k *hif_ce_state; 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci size_t buf_sz; 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci /* protects compl_free and num_send_allowed */ 938c2ecf20Sopenharmony_ci spinlock_t pipe_lock; 948c2ecf20Sopenharmony_ci}; 958c2ecf20Sopenharmony_ci 968c2ecf20Sopenharmony_cistruct ath10k_pci_supp_chip { 978c2ecf20Sopenharmony_ci u32 dev_id; 988c2ecf20Sopenharmony_ci u32 rev_id; 998c2ecf20Sopenharmony_ci}; 1008c2ecf20Sopenharmony_ci 1018c2ecf20Sopenharmony_cienum ath10k_pci_irq_mode { 1028c2ecf20Sopenharmony_ci ATH10K_PCI_IRQ_AUTO = 0, 1038c2ecf20Sopenharmony_ci ATH10K_PCI_IRQ_LEGACY = 1, 1048c2ecf20Sopenharmony_ci ATH10K_PCI_IRQ_MSI = 2, 1058c2ecf20Sopenharmony_ci}; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_cistruct ath10k_pci { 1088c2ecf20Sopenharmony_ci struct pci_dev *pdev; 1098c2ecf20Sopenharmony_ci struct device *dev; 1108c2ecf20Sopenharmony_ci struct ath10k *ar; 1118c2ecf20Sopenharmony_ci void __iomem *mem; 1128c2ecf20Sopenharmony_ci size_t mem_len; 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci /* Operating interrupt mode */ 1158c2ecf20Sopenharmony_ci enum ath10k_pci_irq_mode oper_irq_mode; 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX]; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci /* Copy Engine used for Diagnostic Accesses */ 1208c2ecf20Sopenharmony_ci struct ath10k_ce_pipe *ce_diag; 1218c2ecf20Sopenharmony_ci /* For protecting ce_diag */ 1228c2ecf20Sopenharmony_ci struct mutex ce_diag_mutex; 1238c2ecf20Sopenharmony_ci 1248c2ecf20Sopenharmony_ci struct work_struct dump_work; 1258c2ecf20Sopenharmony_ci 1268c2ecf20Sopenharmony_ci struct ath10k_ce ce; 1278c2ecf20Sopenharmony_ci struct timer_list rx_post_retry; 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci /* Due to HW quirks it is recommended to disable ASPM during device 1308c2ecf20Sopenharmony_ci * bootup. To do that the original PCI-E Link Control is stored before 1318c2ecf20Sopenharmony_ci * device bootup is executed and re-programmed later. 1328c2ecf20Sopenharmony_ci */ 1338c2ecf20Sopenharmony_ci u16 link_ctl; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci /* Protects ps_awake and ps_wake_refcount */ 1368c2ecf20Sopenharmony_ci spinlock_t ps_lock; 1378c2ecf20Sopenharmony_ci 1388c2ecf20Sopenharmony_ci /* The device has a special powersave-oriented register. When device is 1398c2ecf20Sopenharmony_ci * considered asleep it drains less power and driver is forbidden from 1408c2ecf20Sopenharmony_ci * accessing most MMIO registers. If host were to access them without 1418c2ecf20Sopenharmony_ci * waking up the device might scribble over host memory or return 1428c2ecf20Sopenharmony_ci * 0xdeadbeef readouts. 1438c2ecf20Sopenharmony_ci */ 1448c2ecf20Sopenharmony_ci unsigned long ps_wake_refcount; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci /* Waking up takes some time (up to 2ms in some cases) so it can be bad 1478c2ecf20Sopenharmony_ci * for latency. To mitigate this the device isn't immediately allowed 1488c2ecf20Sopenharmony_ci * to sleep after all references are undone - instead there's a grace 1498c2ecf20Sopenharmony_ci * period after which the powersave register is updated unless some 1508c2ecf20Sopenharmony_ci * activity to/from device happened in the meantime. 1518c2ecf20Sopenharmony_ci * 1528c2ecf20Sopenharmony_ci * Also see comments on ATH10K_PCI_SLEEP_GRACE_PERIOD_MSEC. 1538c2ecf20Sopenharmony_ci */ 1548c2ecf20Sopenharmony_ci struct timer_list ps_timer; 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci /* MMIO registers are used to communicate with the device. With 1578c2ecf20Sopenharmony_ci * intensive traffic accessing powersave register would be a bit 1588c2ecf20Sopenharmony_ci * wasteful overhead and would needlessly stall CPU. It is far more 1598c2ecf20Sopenharmony_ci * efficient to rely on a variable in RAM and update it only upon 1608c2ecf20Sopenharmony_ci * powersave register state changes. 1618c2ecf20Sopenharmony_ci */ 1628c2ecf20Sopenharmony_ci bool ps_awake; 1638c2ecf20Sopenharmony_ci 1648c2ecf20Sopenharmony_ci /* pci power save, disable for QCA988X and QCA99X0. 1658c2ecf20Sopenharmony_ci * Writing 'false' to this variable avoids frequent locking 1668c2ecf20Sopenharmony_ci * on MMIO read/write. 1678c2ecf20Sopenharmony_ci */ 1688c2ecf20Sopenharmony_ci bool pci_ps; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci /* Chip specific pci reset routine used to do a safe reset */ 1718c2ecf20Sopenharmony_ci int (*pci_soft_reset)(struct ath10k *ar); 1728c2ecf20Sopenharmony_ci 1738c2ecf20Sopenharmony_ci /* Chip specific pci full reset function */ 1748c2ecf20Sopenharmony_ci int (*pci_hard_reset)(struct ath10k *ar); 1758c2ecf20Sopenharmony_ci 1768c2ecf20Sopenharmony_ci /* chip specific methods for converting target CPU virtual address 1778c2ecf20Sopenharmony_ci * space to CE address space 1788c2ecf20Sopenharmony_ci */ 1798c2ecf20Sopenharmony_ci u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr); 1808c2ecf20Sopenharmony_ci 1818c2ecf20Sopenharmony_ci struct ce_attr *attr; 1828c2ecf20Sopenharmony_ci struct ce_pipe_config *pipe_config; 1838c2ecf20Sopenharmony_ci struct ce_service_to_pipe *serv_to_pipe; 1848c2ecf20Sopenharmony_ci 1858c2ecf20Sopenharmony_ci /* Keep this entry in the last, memory for struct ath10k_ahb is 1868c2ecf20Sopenharmony_ci * allocated (ahb support enabled case) in the continuation of 1878c2ecf20Sopenharmony_ci * this struct. 1888c2ecf20Sopenharmony_ci */ 1898c2ecf20Sopenharmony_ci struct ath10k_ahb ahb[]; 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci}; 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_cistatic inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar) 1948c2ecf20Sopenharmony_ci{ 1958c2ecf20Sopenharmony_ci return (struct ath10k_pci *)ar->drv_priv; 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci#define ATH10K_PCI_RX_POST_RETRY_MS 50 1998c2ecf20Sopenharmony_ci#define ATH_PCI_RESET_WAIT_MAX 10 /* ms */ 2008c2ecf20Sopenharmony_ci#define PCIE_WAKE_TIMEOUT 30000 /* 30ms */ 2018c2ecf20Sopenharmony_ci#define PCIE_WAKE_LATE_US 10000 /* 10ms */ 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_ci#define BAR_NUM 0 2048c2ecf20Sopenharmony_ci 2058c2ecf20Sopenharmony_ci#define CDC_WAR_MAGIC_STR 0xceef0000 2068c2ecf20Sopenharmony_ci#define CDC_WAR_DATA_CE 4 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */ 2098c2ecf20Sopenharmony_ci#define DIAG_ACCESS_CE_TIMEOUT_US 10000 /* 10 ms */ 2108c2ecf20Sopenharmony_ci#define DIAG_ACCESS_CE_WAIT_US 50 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_civoid ath10k_pci_write32(struct ath10k *ar, u32 offset, u32 value); 2138c2ecf20Sopenharmony_civoid ath10k_pci_soc_write32(struct ath10k *ar, u32 addr, u32 val); 2148c2ecf20Sopenharmony_civoid ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val); 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ciu32 ath10k_pci_read32(struct ath10k *ar, u32 offset); 2178c2ecf20Sopenharmony_ciu32 ath10k_pci_soc_read32(struct ath10k *ar, u32 addr); 2188c2ecf20Sopenharmony_ciu32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ciint ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id, 2218c2ecf20Sopenharmony_ci struct ath10k_hif_sg_item *items, int n_items); 2228c2ecf20Sopenharmony_ciint ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf, 2238c2ecf20Sopenharmony_ci size_t buf_len); 2248c2ecf20Sopenharmony_ciint ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address, 2258c2ecf20Sopenharmony_ci const void *data, int nbytes); 2268c2ecf20Sopenharmony_ciint ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, void *req, u32 req_len, 2278c2ecf20Sopenharmony_ci void *resp, u32 *resp_len); 2288c2ecf20Sopenharmony_ciint ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id, 2298c2ecf20Sopenharmony_ci u8 *ul_pipe, u8 *dl_pipe); 2308c2ecf20Sopenharmony_civoid ath10k_pci_hif_get_default_pipe(struct ath10k *ar, u8 *ul_pipe, 2318c2ecf20Sopenharmony_ci u8 *dl_pipe); 2328c2ecf20Sopenharmony_civoid ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe, 2338c2ecf20Sopenharmony_ci int force); 2348c2ecf20Sopenharmony_ciu16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe); 2358c2ecf20Sopenharmony_civoid ath10k_pci_hif_power_down(struct ath10k *ar); 2368c2ecf20Sopenharmony_ciint ath10k_pci_alloc_pipes(struct ath10k *ar); 2378c2ecf20Sopenharmony_civoid ath10k_pci_free_pipes(struct ath10k *ar); 2388c2ecf20Sopenharmony_civoid ath10k_pci_free_pipes(struct ath10k *ar); 2398c2ecf20Sopenharmony_civoid ath10k_pci_rx_replenish_retry(struct timer_list *t); 2408c2ecf20Sopenharmony_civoid ath10k_pci_ce_deinit(struct ath10k *ar); 2418c2ecf20Sopenharmony_civoid ath10k_pci_init_napi(struct ath10k *ar); 2428c2ecf20Sopenharmony_ciint ath10k_pci_init_pipes(struct ath10k *ar); 2438c2ecf20Sopenharmony_ciint ath10k_pci_init_config(struct ath10k *ar); 2448c2ecf20Sopenharmony_civoid ath10k_pci_rx_post(struct ath10k *ar); 2458c2ecf20Sopenharmony_civoid ath10k_pci_flush(struct ath10k *ar); 2468c2ecf20Sopenharmony_civoid ath10k_pci_enable_legacy_irq(struct ath10k *ar); 2478c2ecf20Sopenharmony_cibool ath10k_pci_irq_pending(struct ath10k *ar); 2488c2ecf20Sopenharmony_civoid ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar); 2498c2ecf20Sopenharmony_civoid ath10k_pci_irq_msi_fw_mask(struct ath10k *ar); 2508c2ecf20Sopenharmony_ciint ath10k_pci_wait_for_target_init(struct ath10k *ar); 2518c2ecf20Sopenharmony_ciint ath10k_pci_setup_resource(struct ath10k *ar); 2528c2ecf20Sopenharmony_civoid ath10k_pci_release_resource(struct ath10k *ar); 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci/* QCA6174 is known to have Tx/Rx issues when SOC_WAKE register is poked too 2558c2ecf20Sopenharmony_ci * frequently. To avoid this put SoC to sleep after a very conservative grace 2568c2ecf20Sopenharmony_ci * period. Adjust with great care. 2578c2ecf20Sopenharmony_ci */ 2588c2ecf20Sopenharmony_ci#define ATH10K_PCI_SLEEP_GRACE_PERIOD_MSEC 60 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci#endif /* _PCI_H_ */ 261