diff options
-rw-r--r-- | drivers/misc/habanalabs/goya/goya.c | 19 | ||||
-rw-r--r-- | drivers/misc/habanalabs/habanalabs.h | 9 | ||||
-rw-r--r-- | drivers/misc/habanalabs/include/hl_boot_if.h | 1 | ||||
-rw-r--r-- | drivers/misc/habanalabs/pci.c | 63 |
4 files changed, 53 insertions, 39 deletions
diff --git a/drivers/misc/habanalabs/goya/goya.c b/drivers/misc/habanalabs/goya/goya.c index a0a96ca31757..85f29cb7d67b 100644 --- a/drivers/misc/habanalabs/goya/goya.c +++ b/drivers/misc/habanalabs/goya/goya.c @@ -531,7 +531,7 @@ 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); + rc = hl_pci_init(hdev); if (rc) return rc; @@ -5185,6 +5185,20 @@ u32 goya_get_queue_id_for_cq(struct hl_device *hdev, u32 cq_idx) return cq_idx; } +static void goya_set_dma_mask_from_fw(struct hl_device *hdev) +{ + if (RREG32(mmPSOC_GLOBAL_CONF_NON_RST_FLOPS_0) == + HL_POWER9_HOST_MAGIC) { + dev_dbg(hdev->dev, "Working in 64-bit DMA mode\n"); + hdev->power9_64bit_dma_enable = 1; + hdev->dma_mask = 64; + } else { + dev_dbg(hdev->dev, "Working in 48-bit DMA mode\n"); + hdev->power9_64bit_dma_enable = 0; + hdev->dma_mask = 48; + } +} + static const struct hl_asic_funcs goya_funcs = { .early_init = goya_early_init, .early_fini = goya_early_fini, @@ -5247,7 +5261,8 @@ static const struct hl_asic_funcs goya_funcs = { .get_clk_rate = goya_get_clk_rate, .get_queue_id_for_cq = goya_get_queue_id_for_cq, .read_device_fw_version = goya_read_device_fw_version, - .load_firmware_to_device = goya_load_firmware_to_device + .load_firmware_to_device = goya_load_firmware_to_device, + .set_dma_mask_from_fw = goya_set_dma_mask_from_fw }; /* diff --git a/drivers/misc/habanalabs/habanalabs.h b/drivers/misc/habanalabs/habanalabs.h index 6c54d0ba0a1d..29b9767387af 100644 --- a/drivers/misc/habanalabs/habanalabs.h +++ b/drivers/misc/habanalabs/habanalabs.h @@ -552,6 +552,8 @@ enum hl_pll_frequency { * @read_device_fw_version: read the device's firmware versions that are * contained in registers * @load_firmware_to_device: load the firmware to the device's memory + * @set_dma_mask_from_fw: set the DMA mask in the driver according to the + * firmware configuration */ struct hl_asic_funcs { int (*early_init)(struct hl_device *hdev); @@ -642,6 +644,7 @@ struct hl_asic_funcs { void (*read_device_fw_version)(struct hl_device *hdev, enum hl_fw_component fwc); int (*load_firmware_to_device)(struct hl_device *hdev); + void (*set_dma_mask_from_fw)(struct hl_device *hdev); }; @@ -1321,6 +1324,8 @@ struct hl_device_idle_busy_ts { * @dma_mask: the dma mask that was set for this device * @in_debug: is device under debug. This, together with fpriv_list, 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. * @cdev_sysfs_created: were char devices and sysfs nodes created. * @stop_on_err: true if engines should stop on error. */ @@ -1402,6 +1407,7 @@ struct hl_device { u8 device_cpu_disabled; u8 dma_mask; u8 in_debug; + u8 power9_64bit_dma_enable; u8 cdev_sysfs_created; u8 stop_on_err; @@ -1632,9 +1638,8 @@ int hl_pci_set_dram_bar_base(struct hl_device *hdev, u8 inbound_region, u8 bar, int hl_pci_init_iatu(struct hl_device *hdev, u64 sram_base_address, u64 dram_base_address, u64 host_phys_base_address, u64 host_phys_size); -int hl_pci_init(struct hl_device *hdev, u8 dma_mask); +int hl_pci_init(struct hl_device *hdev); void hl_pci_fini(struct hl_device *hdev); -int hl_pci_set_dma_mask(struct hl_device *hdev, u8 dma_mask); long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr); void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq); diff --git a/drivers/misc/habanalabs/include/hl_boot_if.h b/drivers/misc/habanalabs/include/hl_boot_if.h index 660550604362..7106315fc92e 100644 --- a/drivers/misc/habanalabs/include/hl_boot_if.h +++ b/drivers/misc/habanalabs/include/hl_boot_if.h @@ -9,6 +9,7 @@ #define HL_BOOT_IF_H #define LKD_HARD_RESET_MAGIC 0xED7BD694 +#define HL_POWER9_HOST_MAGIC 0x1DA30009 /* * CPU error bits in BOOT_ERROR registers diff --git a/drivers/misc/habanalabs/pci.c b/drivers/misc/habanalabs/pci.c index c98d88c7a5c6..0aef4af9f5ec 100644 --- a/drivers/misc/habanalabs/pci.c +++ b/drivers/misc/habanalabs/pci.c @@ -267,6 +267,12 @@ int hl_pci_init_iatu(struct hl_device *hdev, u64 sram_base_address, /* Enable + Bar match + match enable */ rc |= hl_pci_iatu_write(hdev, 0x104, 0xC0080000); + /* Return the DBI window to the default location */ + rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr, 0); + rc |= hl_pci_elbi_write(hdev, prop->pcie_aux_dbi_reg_addr + 4, 0); + + hdev->asic_funcs->set_dma_mask_from_fw(hdev); + /* Point to DRAM */ if (!hdev->asic_funcs->set_dram_bar_base) return -EINVAL; @@ -274,7 +280,6 @@ int hl_pci_init_iatu(struct hl_device *hdev, u64 sram_base_address, U64_MAX) return -EIO; - /* Outbound Region 0 - Point to Host */ host_phys_end_addr = host_phys_base_address + host_phys_size - 1; rc |= hl_pci_iatu_write(hdev, 0x008, @@ -283,7 +288,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); @@ -310,41 +320,25 @@ int hl_pci_init_iatu(struct hl_device *hdev, u64 sram_base_address, * * Return: 0 on success, non-zero for failure. */ -int hl_pci_set_dma_mask(struct hl_device *hdev, u8 dma_mask) +int hl_pci_set_dma_mask(struct hl_device *hdev) { struct pci_dev *pdev = hdev->pdev; int rc; /* set DMA mask */ - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_mask)); + rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(hdev->dma_mask)); if (rc) { - dev_warn(hdev->dev, + dev_err(hdev->dev, "Failed to set pci dma mask to %d bits, error %d\n", - dma_mask, rc); - - dma_mask = hdev->dma_mask; - - rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(dma_mask)); - if (rc) { - dev_err(hdev->dev, - "Failed to set pci dma mask to %d bits, error %d\n", - dma_mask, rc); - return rc; - } + hdev->dma_mask, rc); + return rc; } - /* - * We managed to set the dma mask, so update the dma mask field. If - * the set to the coherent mask will fail with that mask, we will - * fail the entire function - */ - hdev->dma_mask = dma_mask; - - rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(dma_mask)); + rc = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(hdev->dma_mask)); if (rc) { dev_err(hdev->dev, "Failed to set pci consistent dma mask to %d bits, error %d\n", - dma_mask, rc); + hdev->dma_mask, rc); return rc; } @@ -354,21 +348,16 @@ int hl_pci_set_dma_mask(struct hl_device *hdev, u8 dma_mask) /** * hl_pci_init() - PCI initialization code. * @hdev: Pointer to hl_device structure. - * @dma_mask: number of bits for the requested dma mask. * * Set DMA masks, initialize the PCI controller and map the PCI BARs. * * Return: 0 on success, non-zero for failure. */ -int hl_pci_init(struct hl_device *hdev, u8 dma_mask) +int hl_pci_init(struct hl_device *hdev) { struct pci_dev *pdev = hdev->pdev; int rc; - rc = hl_pci_set_dma_mask(hdev, dma_mask); - if (rc) - return rc; - if (hdev->reset_pcilink) hl_pci_reset_link_through_bridge(hdev); @@ -380,18 +369,22 @@ int hl_pci_init(struct hl_device *hdev, u8 dma_mask) pci_set_master(pdev); - rc = hdev->asic_funcs->init_iatu(hdev); + rc = hdev->asic_funcs->pci_bars_map(hdev); if (rc) { - dev_err(hdev->dev, "Failed to initialize iATU\n"); + dev_err(hdev->dev, "Failed to initialize PCI BARs\n"); goto disable_device; } - rc = hdev->asic_funcs->pci_bars_map(hdev); + rc = hdev->asic_funcs->init_iatu(hdev); if (rc) { - dev_err(hdev->dev, "Failed to initialize PCI BARs\n"); + dev_err(hdev->dev, "Failed to initialize iATU\n"); goto disable_device; } + rc = hl_pci_set_dma_mask(hdev); + if (rc) + goto disable_device; + return 0; disable_device: |