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