162306a36Sopenharmony_ci/* SPDX-License-Identifier: ISC */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (c) 2005-2011 Atheros Communications Inc.
462306a36Sopenharmony_ci * Copyright (c) 2011-2017 Qualcomm Atheros, Inc.
562306a36Sopenharmony_ci */
662306a36Sopenharmony_ci
762306a36Sopenharmony_ci#ifndef _PCI_H_
862306a36Sopenharmony_ci#define _PCI_H_
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <linux/interrupt.h>
1162306a36Sopenharmony_ci#include <linux/mutex.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include "hw.h"
1462306a36Sopenharmony_ci#include "ce.h"
1562306a36Sopenharmony_ci#include "ahb.h"
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci/*
1862306a36Sopenharmony_ci * maximum number of bytes that can be
1962306a36Sopenharmony_ci * handled atomically by DiagRead/DiagWrite
2062306a36Sopenharmony_ci */
2162306a36Sopenharmony_ci#define DIAG_TRANSFER_LIMIT 2048
2262306a36Sopenharmony_ci
2362306a36Sopenharmony_cistruct bmi_xfer {
2462306a36Sopenharmony_ci	bool tx_done;
2562306a36Sopenharmony_ci	bool rx_done;
2662306a36Sopenharmony_ci	bool wait_for_resp;
2762306a36Sopenharmony_ci	u32 resp_len;
2862306a36Sopenharmony_ci};
2962306a36Sopenharmony_ci
3062306a36Sopenharmony_ci/*
3162306a36Sopenharmony_ci * PCI-specific Target state
3262306a36Sopenharmony_ci *
3362306a36Sopenharmony_ci * NOTE: Structure is shared between Host software and Target firmware!
3462306a36Sopenharmony_ci *
3562306a36Sopenharmony_ci * Much of this may be of interest to the Host so
3662306a36Sopenharmony_ci * HOST_INTEREST->hi_interconnect_state points here
3762306a36Sopenharmony_ci * (and all members are 32-bit quantities in order to
3862306a36Sopenharmony_ci * facilitate Host access). In particular, Host software is
3962306a36Sopenharmony_ci * required to initialize pipe_cfg_addr and svc_to_pipe_map.
4062306a36Sopenharmony_ci */
4162306a36Sopenharmony_cistruct pcie_state {
4262306a36Sopenharmony_ci	/* Pipe configuration Target address */
4362306a36Sopenharmony_ci	/* NB: ce_pipe_config[CE_COUNT] */
4462306a36Sopenharmony_ci	u32 pipe_cfg_addr;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	/* Service to pipe map Target address */
4762306a36Sopenharmony_ci	/* NB: service_to_pipe[PIPE_TO_CE_MAP_CN] */
4862306a36Sopenharmony_ci	u32 svc_to_pipe_map;
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci	/* number of MSI interrupts requested */
5162306a36Sopenharmony_ci	u32 msi_requested;
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	/* number of MSI interrupts granted */
5462306a36Sopenharmony_ci	u32 msi_granted;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	/* Message Signalled Interrupt address */
5762306a36Sopenharmony_ci	u32 msi_addr;
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	/* Base data */
6062306a36Sopenharmony_ci	u32 msi_data;
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci	/*
6362306a36Sopenharmony_ci	 * Data for firmware interrupt;
6462306a36Sopenharmony_ci	 * MSI data for other interrupts are
6562306a36Sopenharmony_ci	 * in various SoC registers
6662306a36Sopenharmony_ci	 */
6762306a36Sopenharmony_ci	u32 msi_fw_intr_data;
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_ci	/* PCIE_PWR_METHOD_* */
7062306a36Sopenharmony_ci	u32 power_mgmt_method;
7162306a36Sopenharmony_ci
7262306a36Sopenharmony_ci	/* PCIE_CONFIG_FLAG_* */
7362306a36Sopenharmony_ci	u32 config_flags;
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ci/* PCIE_CONFIG_FLAG definitions */
7762306a36Sopenharmony_ci#define PCIE_CONFIG_FLAG_ENABLE_L1  0x0000001
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci/* Per-pipe state. */
8062306a36Sopenharmony_cistruct ath10k_pci_pipe {
8162306a36Sopenharmony_ci	/* Handle of underlying Copy Engine */
8262306a36Sopenharmony_ci	struct ath10k_ce_pipe *ce_hdl;
8362306a36Sopenharmony_ci
8462306a36Sopenharmony_ci	/* Our pipe number; facilitates use of pipe_info ptrs. */
8562306a36Sopenharmony_ci	u8 pipe_num;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	/* Convenience back pointer to hif_ce_state. */
8862306a36Sopenharmony_ci	struct ath10k *hif_ce_state;
8962306a36Sopenharmony_ci
9062306a36Sopenharmony_ci	size_t buf_sz;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	/* protects compl_free and num_send_allowed */
9362306a36Sopenharmony_ci	spinlock_t pipe_lock;
9462306a36Sopenharmony_ci};
9562306a36Sopenharmony_ci
9662306a36Sopenharmony_cistruct ath10k_pci_supp_chip {
9762306a36Sopenharmony_ci	u32 dev_id;
9862306a36Sopenharmony_ci	u32 rev_id;
9962306a36Sopenharmony_ci};
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_cienum ath10k_pci_irq_mode {
10262306a36Sopenharmony_ci	ATH10K_PCI_IRQ_AUTO = 0,
10362306a36Sopenharmony_ci	ATH10K_PCI_IRQ_LEGACY = 1,
10462306a36Sopenharmony_ci	ATH10K_PCI_IRQ_MSI = 2,
10562306a36Sopenharmony_ci};
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_cistruct ath10k_pci {
10862306a36Sopenharmony_ci	struct pci_dev *pdev;
10962306a36Sopenharmony_ci	struct device *dev;
11062306a36Sopenharmony_ci	struct ath10k *ar;
11162306a36Sopenharmony_ci	void __iomem *mem;
11262306a36Sopenharmony_ci	size_t mem_len;
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_ci	/* Operating interrupt mode */
11562306a36Sopenharmony_ci	enum ath10k_pci_irq_mode oper_irq_mode;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	struct ath10k_pci_pipe pipe_info[CE_COUNT_MAX];
11862306a36Sopenharmony_ci
11962306a36Sopenharmony_ci	/* Copy Engine used for Diagnostic Accesses */
12062306a36Sopenharmony_ci	struct ath10k_ce_pipe *ce_diag;
12162306a36Sopenharmony_ci	/* For protecting ce_diag */
12262306a36Sopenharmony_ci	struct mutex ce_diag_mutex;
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_ci	struct work_struct dump_work;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	struct ath10k_ce ce;
12762306a36Sopenharmony_ci	struct timer_list rx_post_retry;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	/* Due to HW quirks it is recommended to disable ASPM during device
13062306a36Sopenharmony_ci	 * bootup. To do that the original PCI-E Link Control is stored before
13162306a36Sopenharmony_ci	 * device bootup is executed and re-programmed later.
13262306a36Sopenharmony_ci	 */
13362306a36Sopenharmony_ci	u16 link_ctl;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci	/* Protects ps_awake and ps_wake_refcount */
13662306a36Sopenharmony_ci	spinlock_t ps_lock;
13762306a36Sopenharmony_ci
13862306a36Sopenharmony_ci	/* The device has a special powersave-oriented register. When device is
13962306a36Sopenharmony_ci	 * considered asleep it drains less power and driver is forbidden from
14062306a36Sopenharmony_ci	 * accessing most MMIO registers. If host were to access them without
14162306a36Sopenharmony_ci	 * waking up the device might scribble over host memory or return
14262306a36Sopenharmony_ci	 * 0xdeadbeef readouts.
14362306a36Sopenharmony_ci	 */
14462306a36Sopenharmony_ci	unsigned long ps_wake_refcount;
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	/* Waking up takes some time (up to 2ms in some cases) so it can be bad
14762306a36Sopenharmony_ci	 * for latency. To mitigate this the device isn't immediately allowed
14862306a36Sopenharmony_ci	 * to sleep after all references are undone - instead there's a grace
14962306a36Sopenharmony_ci	 * period after which the powersave register is updated unless some
15062306a36Sopenharmony_ci	 * activity to/from device happened in the meantime.
15162306a36Sopenharmony_ci	 *
15262306a36Sopenharmony_ci	 * Also see comments on ATH10K_PCI_SLEEP_GRACE_PERIOD_MSEC.
15362306a36Sopenharmony_ci	 */
15462306a36Sopenharmony_ci	struct timer_list ps_timer;
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_ci	/* MMIO registers are used to communicate with the device. With
15762306a36Sopenharmony_ci	 * intensive traffic accessing powersave register would be a bit
15862306a36Sopenharmony_ci	 * wasteful overhead and would needlessly stall CPU. It is far more
15962306a36Sopenharmony_ci	 * efficient to rely on a variable in RAM and update it only upon
16062306a36Sopenharmony_ci	 * powersave register state changes.
16162306a36Sopenharmony_ci	 */
16262306a36Sopenharmony_ci	bool ps_awake;
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci	/* pci power save, disable for QCA988X and QCA99X0.
16562306a36Sopenharmony_ci	 * Writing 'false' to this variable avoids frequent locking
16662306a36Sopenharmony_ci	 * on MMIO read/write.
16762306a36Sopenharmony_ci	 */
16862306a36Sopenharmony_ci	bool pci_ps;
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	/* Chip specific pci reset routine used to do a safe reset */
17162306a36Sopenharmony_ci	int (*pci_soft_reset)(struct ath10k *ar);
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci	/* Chip specific pci full reset function */
17462306a36Sopenharmony_ci	int (*pci_hard_reset)(struct ath10k *ar);
17562306a36Sopenharmony_ci
17662306a36Sopenharmony_ci	/* chip specific methods for converting target CPU virtual address
17762306a36Sopenharmony_ci	 * space to CE address space
17862306a36Sopenharmony_ci	 */
17962306a36Sopenharmony_ci	u32 (*targ_cpu_to_ce_addr)(struct ath10k *ar, u32 addr);
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	struct ce_attr *attr;
18262306a36Sopenharmony_ci	struct ce_pipe_config *pipe_config;
18362306a36Sopenharmony_ci	struct ce_service_to_pipe *serv_to_pipe;
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci	/* Keep this entry in the last, memory for struct ath10k_ahb is
18662306a36Sopenharmony_ci	 * allocated (ahb support enabled case) in the continuation of
18762306a36Sopenharmony_ci	 * this struct.
18862306a36Sopenharmony_ci	 */
18962306a36Sopenharmony_ci	struct ath10k_ahb ahb[];
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_cistatic inline struct ath10k_pci *ath10k_pci_priv(struct ath10k *ar)
19462306a36Sopenharmony_ci{
19562306a36Sopenharmony_ci	return (struct ath10k_pci *)ar->drv_priv;
19662306a36Sopenharmony_ci}
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci#define ATH10K_PCI_RX_POST_RETRY_MS 50
19962306a36Sopenharmony_ci#define ATH_PCI_RESET_WAIT_MAX 10 /* ms */
20062306a36Sopenharmony_ci#define PCIE_WAKE_TIMEOUT 30000	/* 30ms */
20162306a36Sopenharmony_ci#define PCIE_WAKE_LATE_US 10000	/* 10ms */
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci#define BAR_NUM 0
20462306a36Sopenharmony_ci
20562306a36Sopenharmony_ci#define CDC_WAR_MAGIC_STR   0xceef0000
20662306a36Sopenharmony_ci#define CDC_WAR_DATA_CE     4
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci/* Wait up to this many Ms for a Diagnostic Access CE operation to complete */
20962306a36Sopenharmony_ci#define DIAG_ACCESS_CE_TIMEOUT_US 10000 /* 10 ms */
21062306a36Sopenharmony_ci#define DIAG_ACCESS_CE_WAIT_US	50
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_civoid ath10k_pci_write32(struct ath10k *ar, u32 offset, u32 value);
21362306a36Sopenharmony_civoid ath10k_pci_soc_write32(struct ath10k *ar, u32 addr, u32 val);
21462306a36Sopenharmony_civoid ath10k_pci_reg_write32(struct ath10k *ar, u32 addr, u32 val);
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_ciu32 ath10k_pci_read32(struct ath10k *ar, u32 offset);
21762306a36Sopenharmony_ciu32 ath10k_pci_soc_read32(struct ath10k *ar, u32 addr);
21862306a36Sopenharmony_ciu32 ath10k_pci_reg_read32(struct ath10k *ar, u32 addr);
21962306a36Sopenharmony_ci
22062306a36Sopenharmony_ciint ath10k_pci_hif_tx_sg(struct ath10k *ar, u8 pipe_id,
22162306a36Sopenharmony_ci			 struct ath10k_hif_sg_item *items, int n_items);
22262306a36Sopenharmony_ciint ath10k_pci_hif_diag_read(struct ath10k *ar, u32 address, void *buf,
22362306a36Sopenharmony_ci			     size_t buf_len);
22462306a36Sopenharmony_ciint ath10k_pci_diag_write_mem(struct ath10k *ar, u32 address,
22562306a36Sopenharmony_ci			      const void *data, int nbytes);
22662306a36Sopenharmony_ciint ath10k_pci_hif_exchange_bmi_msg(struct ath10k *ar, void *req, u32 req_len,
22762306a36Sopenharmony_ci				    void *resp, u32 *resp_len);
22862306a36Sopenharmony_ciint ath10k_pci_hif_map_service_to_pipe(struct ath10k *ar, u16 service_id,
22962306a36Sopenharmony_ci				       u8 *ul_pipe, u8 *dl_pipe);
23062306a36Sopenharmony_civoid ath10k_pci_hif_get_default_pipe(struct ath10k *ar, u8 *ul_pipe,
23162306a36Sopenharmony_ci				     u8 *dl_pipe);
23262306a36Sopenharmony_civoid ath10k_pci_hif_send_complete_check(struct ath10k *ar, u8 pipe,
23362306a36Sopenharmony_ci					int force);
23462306a36Sopenharmony_ciu16 ath10k_pci_hif_get_free_queue_number(struct ath10k *ar, u8 pipe);
23562306a36Sopenharmony_civoid ath10k_pci_hif_power_down(struct ath10k *ar);
23662306a36Sopenharmony_ciint ath10k_pci_alloc_pipes(struct ath10k *ar);
23762306a36Sopenharmony_civoid ath10k_pci_free_pipes(struct ath10k *ar);
23862306a36Sopenharmony_civoid ath10k_pci_rx_replenish_retry(struct timer_list *t);
23962306a36Sopenharmony_civoid ath10k_pci_ce_deinit(struct ath10k *ar);
24062306a36Sopenharmony_civoid ath10k_pci_init_napi(struct ath10k *ar);
24162306a36Sopenharmony_ciint ath10k_pci_init_pipes(struct ath10k *ar);
24262306a36Sopenharmony_ciint ath10k_pci_init_config(struct ath10k *ar);
24362306a36Sopenharmony_civoid ath10k_pci_rx_post(struct ath10k *ar);
24462306a36Sopenharmony_civoid ath10k_pci_flush(struct ath10k *ar);
24562306a36Sopenharmony_civoid ath10k_pci_enable_legacy_irq(struct ath10k *ar);
24662306a36Sopenharmony_cibool ath10k_pci_irq_pending(struct ath10k *ar);
24762306a36Sopenharmony_civoid ath10k_pci_disable_and_clear_legacy_irq(struct ath10k *ar);
24862306a36Sopenharmony_civoid ath10k_pci_irq_msi_fw_mask(struct ath10k *ar);
24962306a36Sopenharmony_ciint ath10k_pci_wait_for_target_init(struct ath10k *ar);
25062306a36Sopenharmony_ciint ath10k_pci_setup_resource(struct ath10k *ar);
25162306a36Sopenharmony_civoid ath10k_pci_release_resource(struct ath10k *ar);
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci/* QCA6174 is known to have Tx/Rx issues when SOC_WAKE register is poked too
25462306a36Sopenharmony_ci * frequently. To avoid this put SoC to sleep after a very conservative grace
25562306a36Sopenharmony_ci * period. Adjust with great care.
25662306a36Sopenharmony_ci */
25762306a36Sopenharmony_ci#define ATH10K_PCI_SLEEP_GRACE_PERIOD_MSEC 60
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci#endif /* _PCI_H_ */
260