[PATCH 8/8] habanalabs: enable 64-bit DMA mask in POWER9

From: Oded Gabbay
Date: Tue Jun 11 2019 - 01:55:29 EST


This patch enables support in the driver for 64-bit DMA mask when running
in a POWER9 machine.

POWER9 supports either 32-bit or 64-bit DMA mask. However, our ASICs
support 48-bit DMA mask. To support 64-bit, the driver needs to add a
special configuration to the ASIC's PCIe controller.

The activation of this special configuration is done via kernel module
parameter because:

1. It should affect all the habanalabs ASICs in the machine.

2. The pci_set_dma_mask() is a generic Linux kernel call, so the driver
can't tell why it got an error when it tried to set the DMA mask to 48
bits. And upon such failure, the driver must fall-back to set the mask
to 32 bits.

3. There is no standard way to differentiate in runtime between POWER9 and
other architectures.

Signed-off-by: Oded Gabbay <oded.gabbay@xxxxxxxxx>
---
drivers/misc/habanalabs/goya/goya.c | 6 +++++-
drivers/misc/habanalabs/habanalabs.h | 3 +++
drivers/misc/habanalabs/habanalabs_drv.c | 7 +++++++
drivers/misc/habanalabs/pci.c | 7 ++++++-
4 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c
index e8b3a31d211f..eb6cd1ee06f2 100644
--- a/drivers/misc/habanalabs/goya/goya.c
+++ b/drivers/misc/habanalabs/goya/goya.c
@@ -472,7 +472,11 @@ static int goya_early_init(struct hl_device *hdev)

prop->dram_pci_bar_size = pci_resource_len(pdev, DDR_BAR_ID);

- rc = hl_pci_init(hdev, 48);
+ if (hdev->power9_64bit_dma_enable)
+ rc = hl_pci_init(hdev, 64);
+ else
+ rc = hl_pci_init(hdev, 48);
+
if (rc)
return rc;

diff --git a/drivers/misc/habanalabs/habanalabs.h b/drivers/misc/habanalabs/habanalabs.h
index 5e4a631b3d88..b6fa2df0b2d6 100644
--- a/drivers/misc/habanalabs/habanalabs.h
+++ b/drivers/misc/habanalabs/habanalabs.h
@@ -1208,6 +1208,8 @@ struct hl_device_reset_work {
* @dma_mask: the dma mask that was set for this device
* @in_debug: is device under debug. This, together with fd_open_cnt, enforces
* that only a single user is configuring the debug infrastructure.
+ * @power9_64bit_dma_enable: true to enable 64-bit DMA mask support. Relevant
+ * only to POWER9 machines.
*/
struct hl_device {
struct pci_dev *pdev;
@@ -1281,6 +1283,7 @@ struct hl_device {
u8 device_cpu_disabled;
u8 dma_mask;
u8 in_debug;
+ u8 power9_64bit_dma_enable;

/* Parameters for bring-up */
u8 mmu_enable;
diff --git a/drivers/misc/habanalabs/habanalabs_drv.c b/drivers/misc/habanalabs/habanalabs_drv.c
index 6f6dbe93f1df..9ca2d9d4f3fe 100644
--- a/drivers/misc/habanalabs/habanalabs_drv.c
+++ b/drivers/misc/habanalabs/habanalabs_drv.c
@@ -28,6 +28,7 @@ static DEFINE_MUTEX(hl_devs_idr_lock);

static int timeout_locked = 5;
static int reset_on_lockup = 1;
+static int power9_64bit_dma_enable;

module_param(timeout_locked, int, 0444);
MODULE_PARM_DESC(timeout_locked,
@@ -37,6 +38,10 @@ module_param(reset_on_lockup, int, 0444);
MODULE_PARM_DESC(reset_on_lockup,
"Do device reset on lockup (0 = no, 1 = yes, default yes)");

+module_param(power9_64bit_dma_enable, int, 0444);
+MODULE_PARM_DESC(power9_64bit_dma_enable,
+ "Enable 64-bit DMA mask. Should be set only in POWER9 machine (0 = no, 1 = yes, default no)");
+
#define PCI_VENDOR_ID_HABANALABS 0x1da3

#define PCI_IDS_GOYA 0x0001
@@ -223,6 +228,8 @@ int create_hdev(struct hl_device **dev, struct pci_dev *pdev,

hdev->major = hl_major;
hdev->reset_on_lockup = reset_on_lockup;
+ hdev->power9_64bit_dma_enable = power9_64bit_dma_enable;
+
hdev->pldm = 0;

set_driver_behavior_per_device(hdev);
diff --git a/drivers/misc/habanalabs/pci.c b/drivers/misc/habanalabs/pci.c
index c98d88c7a5c6..15954bf419fa 100644
--- a/drivers/misc/habanalabs/pci.c
+++ b/drivers/misc/habanalabs/pci.c
@@ -283,7 +283,12 @@ int hl_pci_init_iatu(struct hl_device *hdev, u64 sram_base_address,
upper_32_bits(host_phys_base_address));
rc |= hl_pci_iatu_write(hdev, 0x010, lower_32_bits(host_phys_end_addr));
rc |= hl_pci_iatu_write(hdev, 0x014, 0);
- rc |= hl_pci_iatu_write(hdev, 0x018, 0);
+
+ if ((hdev->power9_64bit_dma_enable) && (hdev->dma_mask == 64))
+ rc |= hl_pci_iatu_write(hdev, 0x018, 0x08000000);
+ else
+ rc |= hl_pci_iatu_write(hdev, 0x018, 0);
+
rc |= hl_pci_iatu_write(hdev, 0x020, upper_32_bits(host_phys_end_addr));
/* Increase region size */
rc |= hl_pci_iatu_write(hdev, 0x000, 0x00002000);
--
2.17.1