blob: 0e78a04d63f45286ad957e9094cee43df575883d [file] [log] [blame]
Tomer Tayarb6f897d2019-03-05 16:48:42 +02001// SPDX-License-Identifier: GPL-2.0
2
3/*
4 * Copyright 2016-2019 HabanaLabs, Ltd.
5 * All Rights Reserved.
6 */
7
8#include "habanalabs.h"
9#include "include/hw_ip/pci/pci_general.h"
10
11#include <linux/pci.h>
12
13/**
14 * hl_pci_bars_map() - Map PCI BARs.
15 * @hdev: Pointer to hl_device structure.
16 * @bar_name: Array of BAR names.
17 * @is_wc: Array with flag per BAR whether a write-combined mapping is needed.
18 *
19 * Request PCI regions and map them to kernel virtual addresses.
20 *
21 * Return: 0 on success, non-zero for failure.
22 */
23int hl_pci_bars_map(struct hl_device *hdev, const char * const name[3],
24 bool is_wc[3])
25{
26 struct pci_dev *pdev = hdev->pdev;
27 int rc, i, bar;
28
29 rc = pci_request_regions(pdev, HL_NAME);
30 if (rc) {
31 dev_err(hdev->dev, "Cannot obtain PCI resources\n");
32 return rc;
33 }
34
35 for (i = 0 ; i < 3 ; i++) {
36 bar = i * 2; /* 64-bit BARs */
37 hdev->pcie_bar[bar] = is_wc[i] ?
38 pci_ioremap_wc_bar(pdev, bar) :
39 pci_ioremap_bar(pdev, bar);
40 if (!hdev->pcie_bar[bar]) {
41 dev_err(hdev->dev, "pci_ioremap%s_bar failed for %s\n",
42 is_wc[i] ? "_wc" : "", name[i]);
43 rc = -ENODEV;
44 goto err;
45 }
46 }
47
48 return 0;
49
50err:
51 for (i = 2 ; i >= 0 ; i--) {
52 bar = i * 2; /* 64-bit BARs */
53 if (hdev->pcie_bar[bar])
54 iounmap(hdev->pcie_bar[bar]);
55 }
56
57 pci_release_regions(pdev);
58
59 return rc;
60}
61
62/*
63 * hl_pci_bars_unmap() - Unmap PCI BARS.
64 * @hdev: Pointer to hl_device structure.
65 *
66 * Release all PCI BARs and unmap their virtual addresses.
67 */
68static void hl_pci_bars_unmap(struct hl_device *hdev)
69{
70 struct pci_dev *pdev = hdev->pdev;
71 int i, bar;
72
73 for (i = 2 ; i >= 0 ; i--) {
74 bar = i * 2; /* 64-bit BARs */
75 iounmap(hdev->pcie_bar[bar]);
76 }
77
78 pci_release_regions(pdev);
79}
80
81/*
82 * hl_pci_elbi_write() - Write through the ELBI interface.
83 * @hdev: Pointer to hl_device structure.
84 *
85 * Return: 0 on success, negative value for failure.
86 */
87static int hl_pci_elbi_write(struct hl_device *hdev, u64 addr, u32 data)
88{
89 struct pci_dev *pdev = hdev->pdev;
90 ktime_t timeout;
91 u32 val;
92
93 /* Clear previous status */
94 pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_STS, 0);
95
96 pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_ADDR, (u32) addr);
97 pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_DATA, data);
98 pci_write_config_dword(pdev, mmPCI_CONFIG_ELBI_CTRL,
99 PCI_CONFIG_ELBI_CTRL_WRITE);
100
101 timeout = ktime_add_ms(ktime_get(), 10);
102 for (;;) {
103 pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_STS, &val);
104 if (val & PCI_CONFIG_ELBI_STS_MASK)
105 break;
106 if (ktime_compare(ktime_get(), timeout) > 0) {
107 pci_read_config_dword(pdev, mmPCI_CONFIG_ELBI_STS,
108 &val);
109 break;
110 }
111
112 usleep_range(300, 500);
113 }
114
115 if ((val & PCI_CONFIG_ELBI_STS_MASK) == PCI_CONFIG_ELBI_STS_DONE)
116 return 0;
117
118 if (val & PCI_CONFIG_ELBI_STS_ERR) {
119 dev_err(hdev->dev, "Error writing to ELBI\n");
120 return -EIO;
121 }
122
123 if (!(val & PCI_CONFIG_ELBI_STS_MASK)) {
124 dev_err(hdev->dev, "ELBI write didn't finish in time\n");
125 return -EIO;
126 }
127
128 dev_err(hdev->dev, "ELBI write has undefined bits in status\n");
129 return -EIO;
130}
131
132/**
133 * hl_pci_iatu_write() - iatu write routine.
134 * @hdev: Pointer to hl_device structure.
135 *
136 * Return: 0 on success, negative value for failure.
137 */
138int hl_pci_iatu_write(struct hl_device *hdev, u32 addr, u32 data)
139{
140 struct asic_fixed_properties *prop = &hdev->asic_prop;
141 u32 dbi_offset;
142 int rc;
143
144 dbi_offset = addr & 0xFFF;
145
146 rc = hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0x00300000);
147 rc |= hl_pci_elbi_write(hdev, prop->pcie_dbi_base_address + dbi_offset,
148 data);
149
150 if (rc)
151 return -EIO;
152
153 return 0;
154}
155
156/*
157 * hl_pci_reset_link_through_bridge() - Reset PCI link.
158 * @hdev: Pointer to hl_device structure.
159 */
160static void hl_pci_reset_link_through_bridge(struct hl_device *hdev)
161{
162 struct pci_dev *pdev = hdev->pdev;
163 struct pci_dev *parent_port;
164 u16 val;
165
166 parent_port = pdev->bus->self;
167 pci_read_config_word(parent_port, PCI_BRIDGE_CONTROL, &val);
168 val |= PCI_BRIDGE_CTL_BUS_RESET;
169 pci_write_config_word(parent_port, PCI_BRIDGE_CONTROL, val);
170 ssleep(1);
171
172 val &= ~(PCI_BRIDGE_CTL_BUS_RESET);
173 pci_write_config_word(parent_port, PCI_BRIDGE_CONTROL, val);
174 ssleep(3);
175}
176
177/**
178 * hl_pci_set_dram_bar_base() - Set DDR BAR to map specific device address.
179 * @hdev: Pointer to hl_device structure.
180 * @inbound_region: Inbound region number.
181 * @bar: PCI BAR number.
182 * @addr: Address in DRAM. Must be aligned to DRAM bar size.
183 *
184 * Configure the iATU so that the DRAM bar will start at the specified address.
185 *
186 * Return: 0 on success, negative value for failure.
187 */
188int hl_pci_set_dram_bar_base(struct hl_device *hdev, u8 inbound_region, u8 bar,
189 u64 addr)
190{
191 struct asic_fixed_properties *prop = &hdev->asic_prop;
192 u32 offset;
193 int rc;
194
195 switch (inbound_region) {
196 case 0:
197 offset = 0x100;
198 break;
199 case 1:
200 offset = 0x300;
201 break;
202 case 2:
203 offset = 0x500;
204 break;
205 default:
206 dev_err(hdev->dev, "Invalid inbound region %d\n",
207 inbound_region);
208 return -EINVAL;
209 }
210
211 if (bar != 0 && bar != 2 && bar != 4) {
212 dev_err(hdev->dev, "Invalid PCI BAR %d\n", bar);
213 return -EINVAL;
214 }
215
216 /* Point to the specified address */
217 rc = hl_pci_iatu_write(hdev, offset + 0x14, lower_32_bits(addr));
218 rc |= hl_pci_iatu_write(hdev, offset + 0x18, upper_32_bits(addr));
219 rc |= hl_pci_iatu_write(hdev, offset + 0x0, 0);
220 /* Enable + BAR match + match enable + BAR number */
221 rc |= hl_pci_iatu_write(hdev, offset + 0x4, 0xC0080000 | (bar << 8));
222
223 /* Return the DBI window to the default location */
224 rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0);
225 rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr + 4, 0);
226
227 if (rc)
228 dev_err(hdev->dev, "failed to map DRAM bar to 0x%08llx\n",
229 addr);
230
231 return rc;
232}
233
234/**
235 * hl_pci_init_iatu() - Initialize the iATU unit inside the PCI controller.
236 * @hdev: Pointer to hl_device structure.
237 * @sram_base_address: SRAM base address.
238 * @dram_base_address: DRAM base address.
Tomer Tayar94cb6692019-05-01 11:28:15 +0300239 * @host_phys_base_address: Base physical address of host memory for device
240 * transactions.
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200241 * @host_phys_size: Size of host memory for device transactions.
242 *
243 * This is needed in case the firmware doesn't initialize the iATU.
244 *
245 * Return: 0 on success, negative value for failure.
246 */
247int hl_pci_init_iatu(struct hl_device *hdev, u64 sram_base_address,
Tomer Tayar94cb6692019-05-01 11:28:15 +0300248 u64 dram_base_address, u64 host_phys_base_address,
249 u64 host_phys_size)
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200250{
251 struct asic_fixed_properties *prop = &hdev->asic_prop;
252 u64 host_phys_end_addr;
253 int rc = 0;
254
255 /* Inbound Region 0 - Bar 0 - Point to SRAM base address */
256 rc = hl_pci_iatu_write(hdev, 0x114, lower_32_bits(sram_base_address));
257 rc |= hl_pci_iatu_write(hdev, 0x118, upper_32_bits(sram_base_address));
258 rc |= hl_pci_iatu_write(hdev, 0x100, 0);
259 /* Enable + Bar match + match enable */
260 rc |= hl_pci_iatu_write(hdev, 0x104, 0xC0080000);
261
262 /* Point to DRAM */
263 if (!hdev->asic_funcs->set_dram_bar_base)
264 return -EINVAL;
Oded Gabbaya38693d2019-04-28 10:18:35 +0300265 if (hdev->asic_funcs->set_dram_bar_base(hdev, dram_base_address) ==
266 U64_MAX)
267 return -EIO;
268
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200269
270 /* Outbound Region 0 - Point to Host */
Tomer Tayar94cb6692019-05-01 11:28:15 +0300271 host_phys_end_addr = host_phys_base_address + host_phys_size - 1;
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200272 rc |= hl_pci_iatu_write(hdev, 0x008,
Tomer Tayar94cb6692019-05-01 11:28:15 +0300273 lower_32_bits(host_phys_base_address));
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200274 rc |= hl_pci_iatu_write(hdev, 0x00C,
Tomer Tayar94cb6692019-05-01 11:28:15 +0300275 upper_32_bits(host_phys_base_address));
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200276 rc |= hl_pci_iatu_write(hdev, 0x010, lower_32_bits(host_phys_end_addr));
277 rc |= hl_pci_iatu_write(hdev, 0x014, 0);
278 rc |= hl_pci_iatu_write(hdev, 0x018, 0);
279 rc |= hl_pci_iatu_write(hdev, 0x020, upper_32_bits(host_phys_end_addr));
280 /* Increase region size */
281 rc |= hl_pci_iatu_write(hdev, 0x000, 0x00002000);
282 /* Enable */
283 rc |= hl_pci_iatu_write(hdev, 0x004, 0x80000000);
284
285 /* Return the DBI window to the default location */
286 rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0);
287 rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr + 4, 0);
288
289 if (rc)
290 return -EIO;
291
292 return 0;
293}
294
295/**
Oded Gabbayd9973872019-03-07 18:03:23 +0200296 * hl_pci_set_dma_mask() - Set DMA masks for the device.
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200297 * @hdev: Pointer to hl_device structure.
Oded Gabbayd9973872019-03-07 18:03:23 +0200298 * @dma_mask: number of bits for the requested dma mask.
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200299 *
Oded Gabbayd9973872019-03-07 18:03:23 +0200300 * This function sets the DMA masks (regular and consistent) for a specified
301 * value. If it doesn't succeed, it tries to set it to a fall-back value
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200302 *
303 * Return: 0 on success, non-zero for failure.
304 */
Oded Gabbayd9973872019-03-07 18:03:23 +0200305int hl_pci_set_dma_mask(struct hl_device *hdev, u8 dma_mask)
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200306{
307 struct pci_dev *pdev = hdev->pdev;
308 int rc;
309
310 /* set DMA mask */
Oded Gabbayd9973872019-03-07 18:03:23 +0200311 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_mask));
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200312 if (rc) {
Oded Gabbayd9973872019-03-07 18:03:23 +0200313 dev_warn(hdev->dev,
314 "Failed to set pci dma mask to %d bits, error %d\n",
315 dma_mask, rc);
316
317 dma_mask = hdev->dma_mask;
318
319 rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_mask));
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200320 if (rc) {
321 dev_err(hdev->dev,
Oded Gabbayd9973872019-03-07 18:03:23 +0200322 "Failed to set pci dma mask to %d bits, error %d\n",
323 dma_mask, rc);
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200324 return rc;
325 }
326 }
327
Oded Gabbayd9973872019-03-07 18:03:23 +0200328 /*
329 * We managed to set the dma mask, so update the dma mask field. If
330 * the set to the coherent mask will fail with that mask, we will
331 * fail the entire function
332 */
333 hdev->dma_mask = dma_mask;
334
335 rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(dma_mask));
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200336 if (rc) {
Oded Gabbayd9973872019-03-07 18:03:23 +0200337 dev_err(hdev->dev,
338 "Failed to set pci consistent dma mask to %d bits, error %d\n",
339 dma_mask, rc);
340 return rc;
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200341 }
342
Oded Gabbayd9973872019-03-07 18:03:23 +0200343 return 0;
344}
345
346/**
347 * hl_pci_init() - PCI initialization code.
348 * @hdev: Pointer to hl_device structure.
349 * @dma_mask: number of bits for the requested dma mask.
350 *
351 * Set DMA masks, initialize the PCI controller and map the PCI BARs.
352 *
353 * Return: 0 on success, non-zero for failure.
354 */
355int hl_pci_init(struct hl_device *hdev, u8 dma_mask)
356{
357 struct pci_dev *pdev = hdev->pdev;
358 int rc;
359
360 rc = hl_pci_set_dma_mask(hdev, dma_mask);
361 if (rc)
362 return rc;
363
Tomer Tayarb6f897d2019-03-05 16:48:42 +0200364 if (hdev->reset_pcilink)
365 hl_pci_reset_link_through_bridge(hdev);
366
367 rc = pci_enable_device_mem(pdev);
368 if (rc) {
369 dev_err(hdev->dev, "can't enable PCI device\n");
370 return rc;
371 }
372
373 pci_set_master(pdev);
374
375 rc = hdev->asic_funcs->init_iatu(hdev);
376 if (rc) {
377 dev_err(hdev->dev, "Failed to initialize iATU\n");
378 goto disable_device;
379 }
380
381 rc = hdev->asic_funcs->pci_bars_map(hdev);
382 if (rc) {
383 dev_err(hdev->dev, "Failed to initialize PCI BARs\n");
384 goto disable_device;
385 }
386
387 return 0;
388
389disable_device:
390 pci_clear_master(pdev);
391 pci_disable_device(pdev);
392
393 return rc;
394}
395
396/**
397 * hl_fw_fini() - PCI finalization code.
398 * @hdev: Pointer to hl_device structure
399 *
400 * Unmap PCI bars and disable PCI device.
401 */
402void hl_pci_fini(struct hl_device *hdev)
403{
404 hl_pci_bars_unmap(hdev);
405
406 pci_clear_master(hdev->pdev);
407 pci_disable_device(hdev->pdev);
408}