1 /******************************************************************************
2 *
3 * Copyright(c) 2019 - Realtek Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 *****************************************************************************/
15 #include "drv_types.h"
16
17 #ifdef CONFIG_PLATFORM_AML_S905
18 extern struct device * g_pcie_reserved_mem_dev;
19 #endif
20
21
pci_cache_wback(struct pci_dev * hwdev,dma_addr_t * bus_addr,size_t size,int direction)22 void pci_cache_wback(struct pci_dev *hwdev,
23 dma_addr_t *bus_addr, size_t size, int direction)
24 {
25 if (NULL != hwdev && NULL != bus_addr) {
26 #ifdef CONFIG_PLATFORM_AML_S905
27 if (g_pcie_reserved_mem_dev)
28 hwdev->dev.dma_mask = NULL;
29 #endif
30 pci_dma_sync_single_for_device(hwdev, *bus_addr, size,
31 direction);
32 } else
33 RTW_ERR("pcie hwdev handle or bus addr is NULL!\n");
34 }
pci_cache_inv(struct pci_dev * hwdev,dma_addr_t * bus_addr,size_t size,int direction)35 void pci_cache_inv(struct pci_dev *hwdev,
36 dma_addr_t *bus_addr, size_t size, int direction)
37 {
38 if (NULL != hwdev && NULL != bus_addr) {
39 #ifdef CONFIG_PLATFORM_AML_S905
40 if (g_pcie_reserved_mem_dev)
41 hwdev->dev.dma_mask = NULL;
42 #endif
43 pci_dma_sync_single_for_cpu(hwdev, *bus_addr, size, direction);
44 } else
45 RTW_ERR("pcie hwdev handle or bus addr is NULL!\n");
46 }
pci_get_bus_addr(struct pci_dev * hwdev,void * vir_addr,dma_addr_t * bus_addr,size_t size,int direction)47 void pci_get_bus_addr(struct pci_dev *hwdev,
48 void *vir_addr, dma_addr_t *bus_addr,
49 size_t size, int direction)
50 {
51 if (NULL != hwdev) {
52 #ifdef CONFIG_PLATFORM_AML_S905
53 if (g_pcie_reserved_mem_dev)
54 hwdev->dev.dma_mask = NULL;
55 #endif
56 *bus_addr = pci_map_single(hwdev, vir_addr, size, direction);
57 } else {
58 RTW_ERR("pcie hwdev handle is NULL!\n");
59 *bus_addr = (dma_addr_t)virt_to_phys(vir_addr);
60 /*RTW_ERR("Get bus_addr: %x by virt_to_phys()\n", bus_addr);*/
61 }
62 }
pci_unmap_bus_addr(struct pci_dev * hwdev,dma_addr_t * bus_addr,size_t size,int direction)63 void pci_unmap_bus_addr(struct pci_dev *hwdev,
64 dma_addr_t *bus_addr, size_t size, int direction)
65 {
66 if (NULL != hwdev && NULL != bus_addr) {
67 #ifdef CONFIG_PLATFORM_AML_S905
68 if (g_pcie_reserved_mem_dev)
69 hwdev->dev.dma_mask = NULL;
70 #endif
71 pci_unmap_single(hwdev, *bus_addr, size, direction);
72 } else
73 RTW_ERR("pcie hwdev handle or bus addr is NULL!\n");
74 }
pci_alloc_cache_mem(struct pci_dev * pdev,dma_addr_t * bus_addr,size_t size,int direction)75 void *pci_alloc_cache_mem(struct pci_dev *pdev,
76 dma_addr_t *bus_addr, size_t size, int direction)
77 {
78 void *vir_addr = NULL;
79
80 vir_addr = rtw_zmalloc(size);
81
82 if (!vir_addr)
83 bus_addr = NULL;
84 else
85 pci_get_bus_addr(pdev, vir_addr, bus_addr, size, direction);
86
87 return vir_addr;
88 }
89
pci_alloc_noncache_mem(struct pci_dev * pdev,dma_addr_t * bus_addr,size_t size)90 void *pci_alloc_noncache_mem(struct pci_dev *pdev,
91 dma_addr_t *bus_addr, size_t size)
92 {
93 void *vir_addr = NULL;
94 struct device *dev = NULL;
95
96 if (NULL != pdev) {
97 dev = &pdev->dev;
98 #ifdef CONFIG_PLATFORM_AML_S905
99 if (g_pcie_reserved_mem_dev)\
100 dev = g_pcie_reserved_mem_dev;
101
102 #endif
103 vir_addr = dma_alloc_coherent(dev,
104 size, bus_addr,
105 (in_atomic() ? GFP_ATOMIC : GFP_KERNEL));
106 }
107 if (!vir_addr)
108 bus_addr = NULL;
109 else
110 bus_addr = (dma_addr_t *)((((SIZE_PTR)bus_addr + 3) / 4) * 4);
111
112 return vir_addr;
113 }
114
pci_create_dma_pool(struct pci_dev * pdev,char * name,size_t size)115 struct dma_pool *pci_create_dma_pool(struct pci_dev *pdev, char *name, size_t size)
116 {
117 return dma_pool_create(name, &pdev->dev, size, 2, 0);
118 }
119
pci_zalloc_pool_mem(struct pci_dev * pdev,struct dma_pool * pool,dma_addr_t * bus_addr)120 void *pci_zalloc_pool_mem(struct pci_dev *pdev, struct dma_pool *pool, dma_addr_t *bus_addr)
121 {
122 return dma_pool_zalloc(pool, (in_atomic() ? GFP_ATOMIC : GFP_KERNEL), bus_addr);
123 }
124
pci_free_pool_mem(struct pci_dev * pdev,struct dma_pool * pool,void * vir_addr,dma_addr_t * bus_addr)125 void pci_free_pool_mem(struct pci_dev *pdev, struct dma_pool *pool, void *vir_addr, dma_addr_t *bus_addr)
126 {
127 return dma_pool_free(pool, vir_addr, *bus_addr);
128 }
129
pci_destory_dma_pool(struct pci_dev * pdev,struct dma_pool * pool)130 void pci_destory_dma_pool(struct pci_dev *pdev, struct dma_pool *pool)
131 {
132 dma_pool_destroy(pool);
133 }
134
pci_free_cache_mem(struct pci_dev * pdev,void * vir_addr,dma_addr_t * bus_addr,size_t size,int direction)135 void pci_free_cache_mem(struct pci_dev *pdev,
136 void *vir_addr, dma_addr_t *bus_addr,
137 size_t size, int direction)
138 {
139 pci_unmap_bus_addr(pdev, bus_addr, size, direction);
140 rtw_mfree(vir_addr, size);
141
142 vir_addr = NULL;
143 }
144
pci_free_noncache_mem(struct pci_dev * pdev,void * vir_addr,dma_addr_t * bus_addr,size_t size)145 void pci_free_noncache_mem(struct pci_dev *pdev,
146 void *vir_addr, dma_addr_t *bus_addr, size_t size)
147 {
148 struct device *dev = NULL;
149
150 if (NULL != pdev) {
151 dev = &pdev->dev;
152 #ifdef CONFIG_PLATFORM_AML_S905
153 if (g_pcie_reserved_mem_dev)
154 dev = g_pcie_reserved_mem_dev;
155 #endif
156 dma_free_coherent(dev, size, vir_addr, *bus_addr);
157 }
158 vir_addr = NULL;
159 }
160