habanalabs: retrieve DMA mask indication from firmware

Retrieve from the firmware the DMA mask value we need to set according to
the device's PCI controller configuration. This is needed when working on
POWER9 machines, as the device's PCI controller is configured in a
different way in those machines.

Reviewed-by: Tomer Tayar <ttayar@habana.ai>
Signed-off-by: Oded Gabbay <oded.gabbay@gmail.com>
This commit is contained in:
Oded Gabbay 2020-03-29 13:18:30 +03:00
parent c8aee597bb
commit cb056b9fd5
4 changed files with 53 additions and 39 deletions

View File

@ -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
};
/*

View File

@ -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);

View File

@ -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

View File

@ -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,17 +369,21 @@ int hl_pci_init(struct hl_device *hdev, u8 dma_mask)
pci_set_master(pdev);
rc = hdev->asic_funcs->pci_bars_map(hdev);
if (rc) {
dev_err(hdev->dev, "Failed to initialize PCI BARs\n");
goto disable_device;
}
rc = hdev->asic_funcs->init_iatu(hdev);
if (rc) {
dev_err(hdev->dev, "Failed to initialize iATU\n");
goto disable_device;
}
rc = hdev->asic_funcs->pci_bars_map(hdev);
if (rc) {
dev_err(hdev->dev, "Failed to initialize PCI BARs\n");
rc = hl_pci_set_dma_mask(hdev);
if (rc)
goto disable_device;
}
return 0;