xref: /linux/drivers/net/ethernet/microchip/fdma/fdma_pci.h (revision 3318a794bb15e329d09dba3aaddd5ef8e22eace4)
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 
3 #ifndef _FDMA_PCI_H_
4 #define _FDMA_PCI_H_
5 
6 #include <linux/align.h>
7 #include <linux/bits.h>
8 #include <linux/mutex.h>
9 #include <linux/types.h>
10 
11 #define FDMA_PCI_ATU_REGION_MAX 6
12 
13 /* Outbound regions are 64KB granular (datasheet section 3.24.7.4.1), so both
14  * the region base and the mapped size must be aligned to this.
15  */
16 #define FDMA_PCI_ATU_REGION_ALIGN BIT(16)
17 
18 #define FDMA_PCI_DB_ALIGN 128
19 #define FDMA_PCI_DB_SIZE(mtu) ALIGN(mtu, FDMA_PCI_DB_ALIGN)
20 
21 struct fdma_pci_atu;
22 
23 struct fdma_pci_atu_region {
24 	struct fdma_pci_atu *atu;
25 	u64 base_addr; /* Base addr of the OB window */
26 	u64 limit_addr; /* End addr of the active mapping (base_addr + size - 1) */
27 	u64 target_addr; /* Host DMA address this region maps to */
28 	int idx;
29 	bool in_use;
30 };
31 
32 struct fdma_pci_atu {
33 	void __iomem *addr;
34 	struct mutex lock; /* Protects region alloc/free and ATU register access */
35 	struct fdma_pci_atu_region regions[FDMA_PCI_ATU_REGION_MAX];
36 };
37 
38 /* Initialize ATU, dividing OB space into regions. */
39 void fdma_pci_atu_init(struct fdma_pci_atu *atu, void __iomem *addr);
40 
41 /* Unmap an ATU region, clearing its translation and disabling it. */
42 void fdma_pci_atu_region_unmap(struct fdma_pci_atu_region *region);
43 
44 /* Map a host DMA address into a free ATU region. target_addr and size must be
45  * FDMA_PCI_ATU_REGION_ALIGN aligned; a misaligned target_addr returns -EINVAL.
46  */
47 struct fdma_pci_atu_region *fdma_pci_atu_region_map(struct fdma_pci_atu *atu,
48 						    u64 target_addr,
49 						    int size);
50 
51 /* Translate a host DMA address to the OB address space. Reads the region
52  * unlocked, so the caller must quiesce DMA and the descriptor paths before
53  * unmapping the region.
54  */
55 u64 fdma_pci_atu_translate_addr(struct fdma_pci_atu_region *region, u64 addr);
56 
57 #endif
58