/* * Copyright (C) 2016-2018 Spreadtrum Communications Inc. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and * may be copied, distributed, and modified under those terms. * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. */ #ifndef __PCIE_DRV_H__ #define __PCIE_DRV_H__ #include #define DRVER_NAME "wcn_pcie" /* Synopsis PCIE configuration registers */ /* For Region control 2 */ #define REGION_EN BIT(31) /* * 0: Address Match Mode. The iATU operates using addresses as in the outbound * direction. The Region Base and Limit Registers must be setup. * * 1:BAR Match Mode. BAR matching is used. The "BAR Number" field is relevant. * Not used for RC. */ #define MATCH_MODE BIT(30) #define ADDR_MATCH_MODE ~BIT(30) #define BAR_MATCH_MODE BIT(30) #define BAR_NUM (BIT(10) | BIT(9) | BIT(8)) #define BAR_0 BIT(8) #define BAR_1 BIT(9) #define BAR_2 (BIT(9) | BIT(8)) #define IATU_OFFSET_ADDR 0x10000 #define OBREG0_OFFSET_ADDR (0x10000 + (0 * 0x200)) #define IBREG0_OFFSET_ADDR (0x10000 + (0 * 0x200) + 0x100) #define OBREG1_OFFSET_ADDR (0x10000 + (1 * 0x200)) #define IBREG1_OFFSET_ADDR (0x10000 + (1 * 0x200) + 0x100) struct bar_info { resource_size_t mmio_start; resource_size_t mmio_end; resource_size_t mmio_len; unsigned long mmio_flags; unsigned char *mem; unsigned char *vmem; }; struct dma_buf { unsigned long vir; unsigned long phy; int size; }; struct wcn_pcie_info { struct pci_dev *dev; struct pci_saved_state *saved_state; int legacy_en; int msi_en; int msix_en; int in_use; int irq; int irq_num; int irq_en; int bar_num; struct bar_info bar[8]; struct msix_entry msix[100]; /* board info */ unsigned char revision; unsigned char irq_pin; unsigned char irq_line; unsigned short sub_vendor_id; unsigned short sub_system_id; unsigned short vendor_id; unsigned short device_id; struct char_drv_info *p_char; }; struct inbound_reg { unsigned int type;/* region contril 1 ;0:mem, 2:i/o 4:cfg */ unsigned int en;/* region contril 2 [10:8]:BAR_NUM, */ unsigned int lower_base_addr; unsigned int upper_base_addr; unsigned int limit; unsigned int lower_target_addr; unsigned int upper_target_addr; } __packed; struct outbound_reg { unsigned int type; unsigned int en; unsigned int lower_base_addr; unsigned int upper_base_addr; unsigned int limit; unsigned int lower_target_addr; unsigned int upper_target_addr; } __packed; int pcie_bar_write(struct wcn_pcie_info *priv, int bar, int offset, char *buf, int len); int pcie_bar_read(struct wcn_pcie_info *priv, int bar, int offset, char *buf, int len); char *pcie_bar_vmem(struct wcn_pcie_info *priv, int bar); int dmalloc(struct wcn_pcie_info *priv, struct dma_buf *dm, int size); int dmfree(struct wcn_pcie_info *priv, struct dma_buf *dm); unsigned char *ibreg_base(struct wcn_pcie_info *priv, char region); unsigned char *obreg_base(struct wcn_pcie_info *priv, char region); int pcie_config_read(struct wcn_pcie_info *priv, int offset, char *buf, int len); int sprd_pcie_bar_map(struct wcn_pcie_info *priv, int bar, unsigned int addr); struct wcn_pcie_info *get_wcn_device_info(void); #endif