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