[PATCH 02/15] habanalabs: allow setting HBM BAR to other regions

From: Oded Gabbay
Date: Thu Oct 27 2022 - 05:10:49 EST


From: Ohad Sharabi <osharabi@xxxxxxxxx>

Up until now the use-case in the driver was that the HBM is accessed
using the HBM BAR, yet the BAR sometimes cannot cover the whole HBM and
so we needed to set the BAR to other HBM offset.
Now we are facing the need to access other PCI memory regions that can
be covered by the HBM BAR.
To answer that we are allowing the caller to determine if the HBM BAR
need to be set or not regardless of the PCI memory region.

Signed-off-by: Ohad Sharabi <osharabi@xxxxxxxxx>
Reviewed-by: Oded Gabbay <ogabbay@xxxxxxxxxx>
Signed-off-by: Oded Gabbay <ogabbay@xxxxxxxxxx>
---
drivers/misc/habanalabs/common/device.c | 29 ++++++++++++---------
drivers/misc/habanalabs/common/habanalabs.h | 2 ++
2 files changed, 18 insertions(+), 13 deletions(-)

diff --git a/drivers/misc/habanalabs/common/device.c b/drivers/misc/habanalabs/common/device.c
index dd01be5c4ba3..0026fe42b3d2 100644
--- a/drivers/misc/habanalabs/common/device.c
+++ b/drivers/misc/habanalabs/common/device.c
@@ -32,6 +32,7 @@ enum dma_alloc_type {
* @hdev: pointer to habanalabs device structure.
* @addr: the address the caller wants to access.
* @region: the PCI region.
+ * @new_bar_region_base: the new BAR region base address.
*
* @return: the old BAR base address on success, U64_MAX for failure.
* The caller should set it back to the old address after use.
@@ -41,7 +42,8 @@ enum dma_alloc_type {
* This function can be called also if the bar doesn't need to be set,
* in that case it just won't change the base.
*/
-static u64 hl_set_dram_bar(struct hl_device *hdev, u64 addr, struct pci_mem_region *region)
+static u64 hl_set_dram_bar(struct hl_device *hdev, u64 addr, struct pci_mem_region *region,
+ u64 *new_bar_region_base)
{
struct asic_fixed_properties *prop = &hdev->asic_prop;
u64 bar_base_addr, old_base;
@@ -55,27 +57,28 @@ static u64 hl_set_dram_bar(struct hl_device *hdev, u64 addr, struct pci_mem_regi
old_base = hdev->asic_funcs->set_dram_bar_base(hdev, bar_base_addr);

/* in case of success we need to update the new BAR base */
- if (old_base != U64_MAX)
- region->region_base = bar_base_addr;
+ if ((old_base != U64_MAX) && new_bar_region_base)
+ *new_bar_region_base = bar_base_addr;

return old_base;
}

-static int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val,
- enum debugfs_access_type acc_type, enum pci_region region_type)
+int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val,
+ enum debugfs_access_type acc_type, enum pci_region region_type, bool set_dram_bar)
{
struct pci_mem_region *region = &hdev->pci_mem_region[region_type];
+ u64 old_base = 0, rc, new_bar_region_base = 0;
void __iomem *acc_addr;
- u64 old_base = 0, rc;

- if (region_type == PCI_REGION_DRAM) {
- old_base = hl_set_dram_bar(hdev, addr, region);
+ if (set_dram_bar) {
+ old_base = hl_set_dram_bar(hdev, addr, region, &new_bar_region_base);
if (old_base == U64_MAX)
return -EIO;
}

- acc_addr = hdev->pcie_bar[region->bar_id] + addr - region->region_base +
- region->offset_in_bar;
+ acc_addr = hdev->pcie_bar[region->bar_id] + region->offset_in_bar +
+ (addr - new_bar_region_base);
+
switch (acc_type) {
case DEBUGFS_READ8:
*val = readb(acc_addr);
@@ -97,8 +100,8 @@ static int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val
break;
}

- if (region_type == PCI_REGION_DRAM) {
- rc = hl_set_dram_bar(hdev, old_base, region);
+ if (set_dram_bar) {
+ rc = hl_set_dram_bar(hdev, old_base, region, NULL);
if (rc == U64_MAX)
return -EIO;
}
@@ -283,7 +286,7 @@ int hl_access_dev_mem(struct hl_device *hdev, enum pci_region region_type,
case PCI_REGION_SRAM:
case PCI_REGION_DRAM:
return hl_access_sram_dram_region(hdev, addr, val, acc_type,
- region_type);
+ region_type, (region_type == PCI_REGION_DRAM));
default:
return -EFAULT;
}
diff --git a/drivers/misc/habanalabs/common/habanalabs.h b/drivers/misc/habanalabs/common/habanalabs.h
index 4913197c433e..c8347eac09ed 100644
--- a/drivers/misc/habanalabs/common/habanalabs.h
+++ b/drivers/misc/habanalabs/common/habanalabs.h
@@ -3486,6 +3486,8 @@ void hl_asic_dma_pool_free_caller(struct hl_device *hdev, void *vaddr, dma_addr_
int hl_dma_map_sgtable(struct hl_device *hdev, struct sg_table *sgt, enum dma_data_direction dir);
void hl_dma_unmap_sgtable(struct hl_device *hdev, struct sg_table *sgt,
enum dma_data_direction dir);
+int hl_access_sram_dram_region(struct hl_device *hdev, u64 addr, u64 *val,
+ enum debugfs_access_type acc_type, enum pci_region region_type, bool set_dram_bar);
int hl_access_cfg_region(struct hl_device *hdev, u64 addr, u64 *val,
enum debugfs_access_type acc_type);
int hl_access_dev_mem(struct hl_device *hdev, enum pci_region region_type,
--
2.25.1