Commit ba2b062f authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

Merge tag 'misc-habanalabs-fixes-2021-05-08' of...

Merge tag 'misc-habanalabs-fixes-2021-05-08' of https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/linux into char-misc-linus

Oded writes:

This tag contains the following fixes for 5.13-rc2:

- Expose PLL information per ASIC. This also fixes some casting warnings.
- Skip reading further firmware errors in case PCI link is down.
- Security firmware error should be handled as error and not warning.
- Allow user to ignore firmware errors.
- Fix bug in timeout calculation when waiting for interrupt of CS.
- Fix bug of potential use-after-free.

* tag 'misc-habanalabs-fixes-2021-05-08' of https://git.kernel.org/pub/scm/linux/kernel/git/ogabbay/linux:
  habanalabs/gaudi: Fix a potential use after free in gaudi_memset_device_memory
  habanalabs: wait for interrupt wrong timeout calculation
  habanalabs: ignore f/w status error
  habanalabs: change error level of security not ready
  habanalabs: skip reading f/w errors on bad status
  habanalabs: expose ASIC specific PLL index
parents 6efb943b 115726c5
...@@ -2017,7 +2017,7 @@ static int _hl_interrupt_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx, ...@@ -2017,7 +2017,7 @@ static int _hl_interrupt_wait_ioctl(struct hl_device *hdev, struct hl_ctx *ctx,
if (completion_value >= target_value) { if (completion_value >= target_value) {
*status = CS_WAIT_STATUS_COMPLETED; *status = CS_WAIT_STATUS_COMPLETED;
} else { } else {
timeout -= jiffies_to_usecs(completion_rc); timeout = completion_rc;
goto wait_again; goto wait_again;
} }
} else { } else {
......
...@@ -362,12 +362,9 @@ static int fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg, ...@@ -362,12 +362,9 @@ static int fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg,
} }
if (err_val & CPU_BOOT_ERR0_SECURITY_NOT_RDY) { if (err_val & CPU_BOOT_ERR0_SECURITY_NOT_RDY) {
dev_warn(hdev->dev, dev_err(hdev->dev,
"Device boot warning - security not ready\n"); "Device boot warning - security not ready\n");
/* This is a warning so we don't want it to disable the err_exists = true;
* device
*/
err_val &= ~CPU_BOOT_ERR0_SECURITY_NOT_RDY;
} }
if (err_val & CPU_BOOT_ERR0_SECURITY_FAIL) { if (err_val & CPU_BOOT_ERR0_SECURITY_FAIL) {
...@@ -403,7 +400,8 @@ static int fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg, ...@@ -403,7 +400,8 @@ static int fw_read_errors(struct hl_device *hdev, u32 boot_err0_reg,
err_exists = true; err_exists = true;
} }
if (err_exists) if (err_exists && ((err_val & ~CPU_BOOT_ERR0_ENABLED) &
lower_32_bits(hdev->boot_error_status_mask)))
return -EIO; return -EIO;
return 0; return 0;
...@@ -661,18 +659,13 @@ int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, u64 *total_energy) ...@@ -661,18 +659,13 @@ int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, u64 *total_energy)
return rc; return rc;
} }
int get_used_pll_index(struct hl_device *hdev, enum pll_index input_pll_index, int get_used_pll_index(struct hl_device *hdev, u32 input_pll_index,
enum pll_index *pll_index) enum pll_index *pll_index)
{ {
struct asic_fixed_properties *prop = &hdev->asic_prop; struct asic_fixed_properties *prop = &hdev->asic_prop;
u8 pll_byte, pll_bit_off; u8 pll_byte, pll_bit_off;
bool dynamic_pll; bool dynamic_pll;
int fw_pll_idx;
if (input_pll_index >= PLL_MAX) {
dev_err(hdev->dev, "PLL index %d is out of range\n",
input_pll_index);
return -EINVAL;
}
dynamic_pll = prop->fw_security_status_valid && dynamic_pll = prop->fw_security_status_valid &&
(prop->fw_app_security_map & CPU_BOOT_DEV_STS0_DYN_PLL_EN); (prop->fw_app_security_map & CPU_BOOT_DEV_STS0_DYN_PLL_EN);
...@@ -680,28 +673,39 @@ int get_used_pll_index(struct hl_device *hdev, enum pll_index input_pll_index, ...@@ -680,28 +673,39 @@ int get_used_pll_index(struct hl_device *hdev, enum pll_index input_pll_index,
if (!dynamic_pll) { if (!dynamic_pll) {
/* /*
* in case we are working with legacy FW (each asic has unique * in case we are working with legacy FW (each asic has unique
* PLL numbering) extract the legacy numbering * PLL numbering) use the driver based index as they are
* aligned with fw legacy numbering
*/ */
*pll_index = hdev->legacy_pll_map[input_pll_index]; *pll_index = input_pll_index;
return 0; return 0;
} }
/* retrieve a FW compatible PLL index based on
* ASIC specific user request
*/
fw_pll_idx = hdev->asic_funcs->map_pll_idx_to_fw_idx(input_pll_index);
if (fw_pll_idx < 0) {
dev_err(hdev->dev, "Invalid PLL index (%u) error %d\n",
input_pll_index, fw_pll_idx);
return -EINVAL;
}
/* PLL map is a u8 array */ /* PLL map is a u8 array */
pll_byte = prop->cpucp_info.pll_map[input_pll_index >> 3]; pll_byte = prop->cpucp_info.pll_map[fw_pll_idx >> 3];
pll_bit_off = input_pll_index & 0x7; pll_bit_off = fw_pll_idx & 0x7;
if (!(pll_byte & BIT(pll_bit_off))) { if (!(pll_byte & BIT(pll_bit_off))) {
dev_err(hdev->dev, "PLL index %d is not supported\n", dev_err(hdev->dev, "PLL index %d is not supported\n",
input_pll_index); fw_pll_idx);
return -EINVAL; return -EINVAL;
} }
*pll_index = input_pll_index; *pll_index = fw_pll_idx;
return 0; return 0;
} }
int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, enum pll_index pll_index, int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, u32 pll_index,
u16 *pll_freq_arr) u16 *pll_freq_arr)
{ {
struct cpucp_packet pkt; struct cpucp_packet pkt;
...@@ -844,8 +848,13 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg, ...@@ -844,8 +848,13 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg,
if (rc) { if (rc) {
dev_err(hdev->dev, "Failed to read preboot version\n"); dev_err(hdev->dev, "Failed to read preboot version\n");
detect_cpu_boot_status(hdev, status); detect_cpu_boot_status(hdev, status);
fw_read_errors(hdev, boot_err0_reg,
cpu_security_boot_status_reg); /* If we read all FF, then something is totally wrong, no point
* of reading specific errors
*/
if (status != -1)
fw_read_errors(hdev, boot_err0_reg,
cpu_security_boot_status_reg);
return -EIO; return -EIO;
} }
......
...@@ -930,6 +930,9 @@ enum div_select_defs { ...@@ -930,6 +930,9 @@ enum div_select_defs {
* driver is ready to receive asynchronous events. This * driver is ready to receive asynchronous events. This
* function should be called during the first init and * function should be called during the first init and
* after every hard-reset of the device * after every hard-reset of the device
* @get_msi_info: Retrieve asic-specific MSI ID of the f/w async event
* @map_pll_idx_to_fw_idx: convert driver specific per asic PLL index to
* generic f/w compatible PLL Indexes
*/ */
struct hl_asic_funcs { struct hl_asic_funcs {
int (*early_init)(struct hl_device *hdev); int (*early_init)(struct hl_device *hdev);
...@@ -1054,6 +1057,7 @@ struct hl_asic_funcs { ...@@ -1054,6 +1057,7 @@ struct hl_asic_funcs {
u32 block_id, u32 block_size); u32 block_id, u32 block_size);
void (*enable_events_from_fw)(struct hl_device *hdev); void (*enable_events_from_fw)(struct hl_device *hdev);
void (*get_msi_info)(u32 *table); void (*get_msi_info)(u32 *table);
int (*map_pll_idx_to_fw_idx)(u32 pll_idx);
}; };
...@@ -1950,8 +1954,6 @@ struct hl_mmu_funcs { ...@@ -1950,8 +1954,6 @@ struct hl_mmu_funcs {
* @aggregated_cs_counters: aggregated cs counters among all contexts * @aggregated_cs_counters: aggregated cs counters among all contexts
* @mmu_priv: device-specific MMU data. * @mmu_priv: device-specific MMU data.
* @mmu_func: device-related MMU functions. * @mmu_func: device-related MMU functions.
* @legacy_pll_map: map holding map between dynamic (common) PLL indexes and
* static (asic specific) PLL indexes.
* @dram_used_mem: current DRAM memory consumption. * @dram_used_mem: current DRAM memory consumption.
* @timeout_jiffies: device CS timeout value. * @timeout_jiffies: device CS timeout value.
* @max_power: the max power of the device, as configured by the sysadmin. This * @max_power: the max power of the device, as configured by the sysadmin. This
...@@ -1960,6 +1962,12 @@ struct hl_mmu_funcs { ...@@ -1960,6 +1962,12 @@ struct hl_mmu_funcs {
* @clock_gating_mask: is clock gating enabled. bitmask that represents the * @clock_gating_mask: is clock gating enabled. bitmask that represents the
* different engines. See debugfs-driver-habanalabs for * different engines. See debugfs-driver-habanalabs for
* details. * details.
* @boot_error_status_mask: contains a mask of the device boot error status.
* Each bit represents a different error, according to
* the defines in hl_boot_if.h. If the bit is cleared,
* the error will be ignored by the driver during
* device initialization. Mainly used to debug and
* workaround firmware bugs
* @in_reset: is device in reset flow. * @in_reset: is device in reset flow.
* @curr_pll_profile: current PLL profile. * @curr_pll_profile: current PLL profile.
* @card_type: Various ASICs have several card types. This indicates the card * @card_type: Various ASICs have several card types. This indicates the card
...@@ -2071,12 +2079,11 @@ struct hl_device { ...@@ -2071,12 +2079,11 @@ struct hl_device {
struct hl_mmu_priv mmu_priv; struct hl_mmu_priv mmu_priv;
struct hl_mmu_funcs mmu_func[MMU_NUM_PGT_LOCATIONS]; struct hl_mmu_funcs mmu_func[MMU_NUM_PGT_LOCATIONS];
enum pll_index *legacy_pll_map;
atomic64_t dram_used_mem; atomic64_t dram_used_mem;
u64 timeout_jiffies; u64 timeout_jiffies;
u64 max_power; u64 max_power;
u64 clock_gating_mask; u64 clock_gating_mask;
u64 boot_error_status_mask;
atomic_t in_reset; atomic_t in_reset;
enum hl_pll_frequency curr_pll_profile; enum hl_pll_frequency curr_pll_profile;
enum cpucp_card_types card_type; enum cpucp_card_types card_type;
...@@ -2387,9 +2394,9 @@ int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev, ...@@ -2387,9 +2394,9 @@ int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev,
struct hl_info_pci_counters *counters); struct hl_info_pci_counters *counters);
int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, int hl_fw_cpucp_total_energy_get(struct hl_device *hdev,
u64 *total_energy); u64 *total_energy);
int get_used_pll_index(struct hl_device *hdev, enum pll_index input_pll_index, int get_used_pll_index(struct hl_device *hdev, u32 input_pll_index,
enum pll_index *pll_index); enum pll_index *pll_index);
int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, enum pll_index pll_index, int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, u32 pll_index,
u16 *pll_freq_arr); u16 *pll_freq_arr);
int hl_fw_cpucp_power_get(struct hl_device *hdev, u64 *power); int hl_fw_cpucp_power_get(struct hl_device *hdev, u64 *power);
int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg, int hl_fw_init_cpu(struct hl_device *hdev, u32 cpu_boot_status_reg,
...@@ -2411,9 +2418,9 @@ int hl_pci_set_outbound_region(struct hl_device *hdev, ...@@ -2411,9 +2418,9 @@ int hl_pci_set_outbound_region(struct hl_device *hdev,
int hl_pci_init(struct hl_device *hdev); int hl_pci_init(struct hl_device *hdev);
void hl_pci_fini(struct hl_device *hdev); void hl_pci_fini(struct hl_device *hdev);
long hl_get_frequency(struct hl_device *hdev, enum pll_index pll_index, long hl_get_frequency(struct hl_device *hdev, u32 pll_index,
bool curr); bool curr);
void hl_set_frequency(struct hl_device *hdev, enum pll_index pll_index, void hl_set_frequency(struct hl_device *hdev, u32 pll_index,
u64 freq); u64 freq);
int hl_get_temperature(struct hl_device *hdev, int hl_get_temperature(struct hl_device *hdev,
int sensor_index, u32 attr, long *value); int sensor_index, u32 attr, long *value);
......
...@@ -30,6 +30,7 @@ static DEFINE_MUTEX(hl_devs_idr_lock); ...@@ -30,6 +30,7 @@ static DEFINE_MUTEX(hl_devs_idr_lock);
static int timeout_locked = 30; static int timeout_locked = 30;
static int reset_on_lockup = 1; static int reset_on_lockup = 1;
static int memory_scrub = 1; static int memory_scrub = 1;
static ulong boot_error_status_mask = ULONG_MAX;
module_param(timeout_locked, int, 0444); module_param(timeout_locked, int, 0444);
MODULE_PARM_DESC(timeout_locked, MODULE_PARM_DESC(timeout_locked,
...@@ -43,6 +44,10 @@ module_param(memory_scrub, int, 0444); ...@@ -43,6 +44,10 @@ module_param(memory_scrub, int, 0444);
MODULE_PARM_DESC(memory_scrub, MODULE_PARM_DESC(memory_scrub,
"Scrub device memory in various states (0 = no, 1 = yes, default yes)"); "Scrub device memory in various states (0 = no, 1 = yes, default yes)");
module_param(boot_error_status_mask, ulong, 0444);
MODULE_PARM_DESC(boot_error_status_mask,
"Mask of the error status during device CPU boot (If bitX is cleared then error X is masked. Default all 1's)");
#define PCI_VENDOR_ID_HABANALABS 0x1da3 #define PCI_VENDOR_ID_HABANALABS 0x1da3
#define PCI_IDS_GOYA 0x0001 #define PCI_IDS_GOYA 0x0001
...@@ -319,6 +324,8 @@ int create_hdev(struct hl_device **dev, struct pci_dev *pdev, ...@@ -319,6 +324,8 @@ int create_hdev(struct hl_device **dev, struct pci_dev *pdev,
hdev->major = hl_major; hdev->major = hl_major;
hdev->reset_on_lockup = reset_on_lockup; hdev->reset_on_lockup = reset_on_lockup;
hdev->memory_scrub = memory_scrub; hdev->memory_scrub = memory_scrub;
hdev->boot_error_status_mask = boot_error_status_mask;
hdev->pldm = 0; hdev->pldm = 0;
set_driver_behavior_per_device(hdev); set_driver_behavior_per_device(hdev);
......
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
#include <linux/pci.h> #include <linux/pci.h>
long hl_get_frequency(struct hl_device *hdev, enum pll_index pll_index, long hl_get_frequency(struct hl_device *hdev, u32 pll_index,
bool curr) bool curr)
{ {
struct cpucp_packet pkt; struct cpucp_packet pkt;
...@@ -44,7 +44,7 @@ long hl_get_frequency(struct hl_device *hdev, enum pll_index pll_index, ...@@ -44,7 +44,7 @@ long hl_get_frequency(struct hl_device *hdev, enum pll_index pll_index,
return (long) result; return (long) result;
} }
void hl_set_frequency(struct hl_device *hdev, enum pll_index pll_index, void hl_set_frequency(struct hl_device *hdev, u32 pll_index,
u64 freq) u64 freq)
{ {
struct cpucp_packet pkt; struct cpucp_packet pkt;
......
...@@ -105,36 +105,6 @@ ...@@ -105,36 +105,6 @@
#define GAUDI_PLL_MAX 10 #define GAUDI_PLL_MAX 10
/*
* this enum kept here for compatibility with old FW (in which each asic has
* unique PLL numbering
*/
enum gaudi_pll_index {
GAUDI_CPU_PLL = 0,
GAUDI_PCI_PLL,
GAUDI_SRAM_PLL,
GAUDI_HBM_PLL,
GAUDI_NIC_PLL,
GAUDI_DMA_PLL,
GAUDI_MESH_PLL,
GAUDI_MME_PLL,
GAUDI_TPC_PLL,
GAUDI_IF_PLL,
};
static enum pll_index gaudi_pll_map[PLL_MAX] = {
[CPU_PLL] = GAUDI_CPU_PLL,
[PCI_PLL] = GAUDI_PCI_PLL,
[SRAM_PLL] = GAUDI_SRAM_PLL,
[HBM_PLL] = GAUDI_HBM_PLL,
[NIC_PLL] = GAUDI_NIC_PLL,
[DMA_PLL] = GAUDI_DMA_PLL,
[MESH_PLL] = GAUDI_MESH_PLL,
[MME_PLL] = GAUDI_MME_PLL,
[TPC_PLL] = GAUDI_TPC_PLL,
[IF_PLL] = GAUDI_IF_PLL,
};
static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = { static const char gaudi_irq_name[GAUDI_MSI_ENTRIES][GAUDI_MAX_STRING_LEN] = {
"gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3", "gaudi cq 0_0", "gaudi cq 0_1", "gaudi cq 0_2", "gaudi cq 0_3",
"gaudi cq 1_0", "gaudi cq 1_1", "gaudi cq 1_2", "gaudi cq 1_3", "gaudi cq 1_0", "gaudi cq 1_1", "gaudi cq 1_2", "gaudi cq 1_3",
...@@ -810,7 +780,7 @@ static int gaudi_fetch_psoc_frequency(struct hl_device *hdev) ...@@ -810,7 +780,7 @@ static int gaudi_fetch_psoc_frequency(struct hl_device *hdev)
freq = 0; freq = 0;
} }
} else { } else {
rc = hl_fw_cpucp_pll_info_get(hdev, CPU_PLL, pll_freq_arr); rc = hl_fw_cpucp_pll_info_get(hdev, HL_GAUDI_CPU_PLL, pll_freq_arr);
if (rc) if (rc)
return rc; return rc;
...@@ -1652,9 +1622,6 @@ static int gaudi_sw_init(struct hl_device *hdev) ...@@ -1652,9 +1622,6 @@ static int gaudi_sw_init(struct hl_device *hdev)
hdev->asic_specific = gaudi; hdev->asic_specific = gaudi;
/* store legacy PLL map */
hdev->legacy_pll_map = gaudi_pll_map;
/* Create DMA pool for small allocations */ /* Create DMA pool for small allocations */
hdev->dma_pool = dma_pool_create(dev_name(hdev->dev), hdev->dma_pool = dma_pool_create(dev_name(hdev->dev),
&hdev->pdev->dev, GAUDI_DMA_POOL_BLK_SIZE, 8, 0); &hdev->pdev->dev, GAUDI_DMA_POOL_BLK_SIZE, 8, 0);
...@@ -5612,6 +5579,7 @@ static int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr, ...@@ -5612,6 +5579,7 @@ static int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr,
struct hl_cs_job *job; struct hl_cs_job *job;
u32 cb_size, ctl, err_cause; u32 cb_size, ctl, err_cause;
struct hl_cb *cb; struct hl_cb *cb;
u64 id;
int rc; int rc;
cb = hl_cb_kernel_create(hdev, PAGE_SIZE, false); cb = hl_cb_kernel_create(hdev, PAGE_SIZE, false);
...@@ -5678,8 +5646,9 @@ static int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr, ...@@ -5678,8 +5646,9 @@ static int gaudi_memset_device_memory(struct hl_device *hdev, u64 addr,
} }
release_cb: release_cb:
id = cb->id;
hl_cb_put(cb); hl_cb_put(cb);
hl_cb_destroy(hdev, &hdev->kernel_cb_mgr, cb->id << PAGE_SHIFT); hl_cb_destroy(hdev, &hdev->kernel_cb_mgr, id << PAGE_SHIFT);
return rc; return rc;
} }
...@@ -8783,6 +8752,23 @@ static void gaudi_enable_events_from_fw(struct hl_device *hdev) ...@@ -8783,6 +8752,23 @@ static void gaudi_enable_events_from_fw(struct hl_device *hdev)
WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_INTS_REGISTER); WREG32(mmGIC_DISTRIBUTOR__5_GICD_SETSPI_NSR, GAUDI_EVENT_INTS_REGISTER);
} }
static int gaudi_map_pll_idx_to_fw_idx(u32 pll_idx)
{
switch (pll_idx) {
case HL_GAUDI_CPU_PLL: return CPU_PLL;
case HL_GAUDI_PCI_PLL: return PCI_PLL;
case HL_GAUDI_NIC_PLL: return NIC_PLL;
case HL_GAUDI_DMA_PLL: return DMA_PLL;
case HL_GAUDI_MESH_PLL: return MESH_PLL;
case HL_GAUDI_MME_PLL: return MME_PLL;
case HL_GAUDI_TPC_PLL: return TPC_PLL;
case HL_GAUDI_IF_PLL: return IF_PLL;
case HL_GAUDI_SRAM_PLL: return SRAM_PLL;
case HL_GAUDI_HBM_PLL: return HBM_PLL;
default: return -EINVAL;
}
}
static const struct hl_asic_funcs gaudi_funcs = { static const struct hl_asic_funcs gaudi_funcs = {
.early_init = gaudi_early_init, .early_init = gaudi_early_init,
.early_fini = gaudi_early_fini, .early_fini = gaudi_early_fini,
...@@ -8866,7 +8852,8 @@ static const struct hl_asic_funcs gaudi_funcs = { ...@@ -8866,7 +8852,8 @@ static const struct hl_asic_funcs gaudi_funcs = {
.ack_protection_bits_errors = gaudi_ack_protection_bits_errors, .ack_protection_bits_errors = gaudi_ack_protection_bits_errors,
.get_hw_block_id = gaudi_get_hw_block_id, .get_hw_block_id = gaudi_get_hw_block_id,
.hw_block_mmap = gaudi_block_mmap, .hw_block_mmap = gaudi_block_mmap,
.enable_events_from_fw = gaudi_enable_events_from_fw .enable_events_from_fw = gaudi_enable_events_from_fw,
.map_pll_idx_to_fw_idx = gaudi_map_pll_idx_to_fw_idx
}; };
/** /**
......
...@@ -13,7 +13,7 @@ void gaudi_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq) ...@@ -13,7 +13,7 @@ void gaudi_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq)
struct gaudi_device *gaudi = hdev->asic_specific; struct gaudi_device *gaudi = hdev->asic_specific;
if (freq == PLL_LAST) if (freq == PLL_LAST)
hl_set_frequency(hdev, MME_PLL, gaudi->max_freq_value); hl_set_frequency(hdev, HL_GAUDI_MME_PLL, gaudi->max_freq_value);
} }
int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk)
...@@ -23,7 +23,7 @@ int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) ...@@ -23,7 +23,7 @@ int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk)
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, false); value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, false);
if (value < 0) { if (value < 0) {
dev_err(hdev->dev, "Failed to retrieve device max clock %ld\n", dev_err(hdev->dev, "Failed to retrieve device max clock %ld\n",
...@@ -33,7 +33,7 @@ int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) ...@@ -33,7 +33,7 @@ int gaudi_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk)
*max_clk = (value / 1000 / 1000); *max_clk = (value / 1000 / 1000);
value = hl_get_frequency(hdev, MME_PLL, true); value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, true);
if (value < 0) { if (value < 0) {
dev_err(hdev->dev, dev_err(hdev->dev,
...@@ -57,7 +57,7 @@ static ssize_t clk_max_freq_mhz_show(struct device *dev, ...@@ -57,7 +57,7 @@ static ssize_t clk_max_freq_mhz_show(struct device *dev,
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, false); value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, false);
gaudi->max_freq_value = value; gaudi->max_freq_value = value;
...@@ -85,7 +85,7 @@ static ssize_t clk_max_freq_mhz_store(struct device *dev, ...@@ -85,7 +85,7 @@ static ssize_t clk_max_freq_mhz_store(struct device *dev,
gaudi->max_freq_value = value * 1000 * 1000; gaudi->max_freq_value = value * 1000 * 1000;
hl_set_frequency(hdev, MME_PLL, gaudi->max_freq_value); hl_set_frequency(hdev, HL_GAUDI_MME_PLL, gaudi->max_freq_value);
fail: fail:
return count; return count;
...@@ -100,7 +100,7 @@ static ssize_t clk_cur_freq_mhz_show(struct device *dev, ...@@ -100,7 +100,7 @@ static ssize_t clk_cur_freq_mhz_show(struct device *dev,
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, true); value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, true);
return sprintf(buf, "%lu\n", (value / 1000 / 1000)); return sprintf(buf, "%lu\n", (value / 1000 / 1000));
} }
......
...@@ -118,30 +118,6 @@ ...@@ -118,30 +118,6 @@
#define IS_MME_IDLE(mme_arch_sts) \ #define IS_MME_IDLE(mme_arch_sts) \
(((mme_arch_sts) & MME_ARCH_IDLE_MASK) == MME_ARCH_IDLE_MASK) (((mme_arch_sts) & MME_ARCH_IDLE_MASK) == MME_ARCH_IDLE_MASK)
/*
* this enum kept here for compatibility with old FW (in which each asic has
* unique PLL numbering
*/
enum goya_pll_index {
GOYA_CPU_PLL = 0,
GOYA_IC_PLL,
GOYA_MC_PLL,
GOYA_MME_PLL,
GOYA_PCI_PLL,
GOYA_EMMC_PLL,
GOYA_TPC_PLL,
};
static enum pll_index goya_pll_map[PLL_MAX] = {
[CPU_PLL] = GOYA_CPU_PLL,
[IC_PLL] = GOYA_IC_PLL,
[MC_PLL] = GOYA_MC_PLL,
[MME_PLL] = GOYA_MME_PLL,
[PCI_PLL] = GOYA_PCI_PLL,
[EMMC_PLL] = GOYA_EMMC_PLL,
[TPC_PLL] = GOYA_TPC_PLL,
};
static const char goya_irq_name[GOYA_MSIX_ENTRIES][GOYA_MAX_STRING_LEN] = { static const char goya_irq_name[GOYA_MSIX_ENTRIES][GOYA_MAX_STRING_LEN] = {
"goya cq 0", "goya cq 1", "goya cq 2", "goya cq 3", "goya cq 0", "goya cq 1", "goya cq 2", "goya cq 3",
"goya cq 4", "goya cpu eq" "goya cq 4", "goya cpu eq"
...@@ -775,7 +751,8 @@ static void goya_fetch_psoc_frequency(struct hl_device *hdev) ...@@ -775,7 +751,8 @@ static void goya_fetch_psoc_frequency(struct hl_device *hdev)
freq = 0; freq = 0;
} }
} else { } else {
rc = hl_fw_cpucp_pll_info_get(hdev, PCI_PLL, pll_freq_arr); rc = hl_fw_cpucp_pll_info_get(hdev, HL_GOYA_PCI_PLL,
pll_freq_arr);
if (rc) if (rc)
return; return;
...@@ -897,9 +874,6 @@ static int goya_sw_init(struct hl_device *hdev) ...@@ -897,9 +874,6 @@ static int goya_sw_init(struct hl_device *hdev)
hdev->asic_specific = goya; hdev->asic_specific = goya;
/* store legacy PLL map */
hdev->legacy_pll_map = goya_pll_map;
/* Create DMA pool for small allocations */ /* Create DMA pool for small allocations */
hdev->dma_pool = dma_pool_create(dev_name(hdev->dev), hdev->dma_pool = dma_pool_create(dev_name(hdev->dev),
&hdev->pdev->dev, GOYA_DMA_POOL_BLK_SIZE, 8, 0); &hdev->pdev->dev, GOYA_DMA_POOL_BLK_SIZE, 8, 0);
...@@ -5512,6 +5486,20 @@ static void goya_enable_events_from_fw(struct hl_device *hdev) ...@@ -5512,6 +5486,20 @@ static void goya_enable_events_from_fw(struct hl_device *hdev)
GOYA_ASYNC_EVENT_ID_INTS_REGISTER); GOYA_ASYNC_EVENT_ID_INTS_REGISTER);
} }
static int goya_map_pll_idx_to_fw_idx(u32 pll_idx)
{
switch (pll_idx) {
case HL_GOYA_CPU_PLL: return CPU_PLL;
case HL_GOYA_PCI_PLL: return PCI_PLL;
case HL_GOYA_MME_PLL: return MME_PLL;
case HL_GOYA_TPC_PLL: return TPC_PLL;
case HL_GOYA_IC_PLL: return IC_PLL;
case HL_GOYA_MC_PLL: return MC_PLL;
case HL_GOYA_EMMC_PLL: return EMMC_PLL;
default: return -EINVAL;
}
}
static const struct hl_asic_funcs goya_funcs = { static const struct hl_asic_funcs goya_funcs = {
.early_init = goya_early_init, .early_init = goya_early_init,
.early_fini = goya_early_fini, .early_fini = goya_early_fini,
...@@ -5595,7 +5583,8 @@ static const struct hl_asic_funcs goya_funcs = { ...@@ -5595,7 +5583,8 @@ static const struct hl_asic_funcs goya_funcs = {
.ack_protection_bits_errors = goya_ack_protection_bits_errors, .ack_protection_bits_errors = goya_ack_protection_bits_errors,
.get_hw_block_id = goya_get_hw_block_id, .get_hw_block_id = goya_get_hw_block_id,
.hw_block_mmap = goya_block_mmap, .hw_block_mmap = goya_block_mmap,
.enable_events_from_fw = goya_enable_events_from_fw .enable_events_from_fw = goya_enable_events_from_fw,
.map_pll_idx_to_fw_idx = goya_map_pll_idx_to_fw_idx
}; };
/* /*
......
...@@ -13,19 +13,19 @@ void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq) ...@@ -13,19 +13,19 @@ void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq)
switch (freq) { switch (freq) {
case PLL_HIGH: case PLL_HIGH:
hl_set_frequency(hdev, MME_PLL, hdev->high_pll); hl_set_frequency(hdev, HL_GOYA_MME_PLL, hdev->high_pll);
hl_set_frequency(hdev, TPC_PLL, hdev->high_pll); hl_set_frequency(hdev, HL_GOYA_TPC_PLL, hdev->high_pll);
hl_set_frequency(hdev, IC_PLL, hdev->high_pll); hl_set_frequency(hdev, HL_GOYA_IC_PLL, hdev->high_pll);
break; break;
case PLL_LOW: case PLL_LOW:
hl_set_frequency(hdev, MME_PLL, GOYA_PLL_FREQ_LOW); hl_set_frequency(hdev, HL_GOYA_MME_PLL, GOYA_PLL_FREQ_LOW);
hl_set_frequency(hdev, TPC_PLL, GOYA_PLL_FREQ_LOW); hl_set_frequency(hdev, HL_GOYA_TPC_PLL, GOYA_PLL_FREQ_LOW);
hl_set_frequency(hdev, IC_PLL, GOYA_PLL_FREQ_LOW); hl_set_frequency(hdev, HL_GOYA_IC_PLL, GOYA_PLL_FREQ_LOW);
break; break;
case PLL_LAST: case PLL_LAST:
hl_set_frequency(hdev, MME_PLL, goya->mme_clk); hl_set_frequency(hdev, HL_GOYA_MME_PLL, goya->mme_clk);
hl_set_frequency(hdev, TPC_PLL, goya->tpc_clk); hl_set_frequency(hdev, HL_GOYA_TPC_PLL, goya->tpc_clk);
hl_set_frequency(hdev, IC_PLL, goya->ic_clk); hl_set_frequency(hdev, HL_GOYA_IC_PLL, goya->ic_clk);
break; break;
default: default:
dev_err(hdev->dev, "unknown frequency setting\n"); dev_err(hdev->dev, "unknown frequency setting\n");
...@@ -39,7 +39,7 @@ int goya_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) ...@@ -39,7 +39,7 @@ int goya_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk)
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, false); value = hl_get_frequency(hdev, HL_GOYA_MME_PLL, false);
if (value < 0) { if (value < 0) {
dev_err(hdev->dev, "Failed to retrieve device max clock %ld\n", dev_err(hdev->dev, "Failed to retrieve device max clock %ld\n",
...@@ -49,7 +49,7 @@ int goya_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk) ...@@ -49,7 +49,7 @@ int goya_get_clk_rate(struct hl_device *hdev, u32 *cur_clk, u32 *max_clk)
*max_clk = (value / 1000 / 1000); *max_clk = (value / 1000 / 1000);
value = hl_get_frequency(hdev, MME_PLL, true); value = hl_get_frequency(hdev, HL_GOYA_MME_PLL, true);
if (value < 0) { if (value < 0) {
dev_err(hdev->dev, dev_err(hdev->dev,
...@@ -72,7 +72,7 @@ static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr, ...@@ -72,7 +72,7 @@ static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr,
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, false); value = hl_get_frequency(hdev, HL_GOYA_MME_PLL, false);
if (value < 0) if (value < 0)
return value; return value;
...@@ -105,7 +105,7 @@ static ssize_t mme_clk_store(struct device *dev, struct device_attribute *attr, ...@@ -105,7 +105,7 @@ static ssize_t mme_clk_store(struct device *dev, struct device_attribute *attr,
goto fail; goto fail;
} }
hl_set_frequency(hdev, MME_PLL, value); hl_set_frequency(hdev, HL_GOYA_MME_PLL, value);
goya->mme_clk = value; goya->mme_clk = value;
fail: fail:
...@@ -121,7 +121,7 @@ static ssize_t tpc_clk_show(struct device *dev, struct device_attribute *attr, ...@@ -121,7 +121,7 @@ static ssize_t tpc_clk_show(struct device *dev, struct device_attribute *attr,
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, TPC_PLL, false); value = hl_get_frequency(hdev, HL_GOYA_TPC_PLL, false);
if (value < 0) if (value < 0)
return value; return value;
...@@ -154,7 +154,7 @@ static ssize_t tpc_clk_store(struct device *dev, struct device_attribute *attr, ...@@ -154,7 +154,7 @@ static ssize_t tpc_clk_store(struct device *dev, struct device_attribute *attr,
goto fail; goto fail;
} }
hl_set_frequency(hdev, TPC_PLL, value); hl_set_frequency(hdev, HL_GOYA_TPC_PLL, value);
goya->tpc_clk = value; goya->tpc_clk = value;
fail: fail:
...@@ -170,7 +170,7 @@ static ssize_t ic_clk_show(struct device *dev, struct device_attribute *attr, ...@@ -170,7 +170,7 @@ static ssize_t ic_clk_show(struct device *dev, struct device_attribute *attr,
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, IC_PLL, false); value = hl_get_frequency(hdev, HL_GOYA_IC_PLL, false);
if (value < 0) if (value < 0)
return value; return value;
...@@ -203,7 +203,7 @@ static ssize_t ic_clk_store(struct device *dev, struct device_attribute *attr, ...@@ -203,7 +203,7 @@ static ssize_t ic_clk_store(struct device *dev, struct device_attribute *attr,
goto fail; goto fail;
} }
hl_set_frequency(hdev, IC_PLL, value); hl_set_frequency(hdev, HL_GOYA_IC_PLL, value);
goya->ic_clk = value; goya->ic_clk = value;
fail: fail:
...@@ -219,7 +219,7 @@ static ssize_t mme_clk_curr_show(struct device *dev, ...@@ -219,7 +219,7 @@ static ssize_t mme_clk_curr_show(struct device *dev,
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, true); value = hl_get_frequency(hdev, HL_GOYA_MME_PLL, true);
if (value < 0) if (value < 0)
return value; return value;
...@@ -236,7 +236,7 @@ static ssize_t tpc_clk_curr_show(struct device *dev, ...@@ -236,7 +236,7 @@ static ssize_t tpc_clk_curr_show(struct device *dev,
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, TPC_PLL, true); value = hl_get_frequency(hdev, HL_GOYA_TPC_PLL, true);
if (value < 0) if (value < 0)
return value; return value;
...@@ -253,7 +253,7 @@ static ssize_t ic_clk_curr_show(struct device *dev, ...@@ -253,7 +253,7 @@ static ssize_t ic_clk_curr_show(struct device *dev,
if (!hl_device_operational(hdev, NULL)) if (!hl_device_operational(hdev, NULL))
return -ENODEV; return -ENODEV;
value = hl_get_frequency(hdev, IC_PLL, true); value = hl_get_frequency(hdev, HL_GOYA_IC_PLL, true);
if (value < 0) if (value < 0)
return value; return value;
......
...@@ -239,6 +239,39 @@ enum gaudi_engine_id { ...@@ -239,6 +239,39 @@ enum gaudi_engine_id {
GAUDI_ENGINE_ID_SIZE GAUDI_ENGINE_ID_SIZE
}; };
/*
* ASIC specific PLL index
*
* Used to retrieve in frequency info of different IPs via
* HL_INFO_PLL_FREQUENCY under HL_IOCTL_INFO IOCTL. The enums need to be
* used as an index in struct hl_pll_frequency_info
*/
enum hl_goya_pll_index {
HL_GOYA_CPU_PLL = 0,
HL_GOYA_IC_PLL,
HL_GOYA_MC_PLL,
HL_GOYA_MME_PLL,
HL_GOYA_PCI_PLL,
HL_GOYA_EMMC_PLL,
HL_GOYA_TPC_PLL,
HL_GOYA_PLL_MAX
};
enum hl_gaudi_pll_index {
HL_GAUDI_CPU_PLL = 0,
HL_GAUDI_PCI_PLL,
HL_GAUDI_SRAM_PLL,
HL_GAUDI_HBM_PLL,
HL_GAUDI_NIC_PLL,
HL_GAUDI_DMA_PLL,
HL_GAUDI_MESH_PLL,
HL_GAUDI_MME_PLL,
HL_GAUDI_TPC_PLL,
HL_GAUDI_IF_PLL,
HL_GAUDI_PLL_MAX
};
enum hl_device_status { enum hl_device_status {
HL_DEVICE_STATUS_OPERATIONAL, HL_DEVICE_STATUS_OPERATIONAL,
HL_DEVICE_STATUS_IN_RESET, HL_DEVICE_STATUS_IN_RESET,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment