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.
 -----BEGIN PGP SIGNATURE-----
 
 iQFHBAABCgAxFiEE7TEboABC71LctBLFZR1NuKta54AFAmCWTaoTHG9nYWJiYXlA
 a2VybmVsLm9yZwAKCRBlHU24q1rngMgUB/4gep0fP5vP71R4vsjdlKFkuf/1+b9/
 oUJbI5ujWLuJGJpxpv1pZfy/miT4hOIYgxR5jRXa7NJMabW4+PBO7lufif9nsFb9
 D4BG/2hAWJLoSdmSlNaRhswScDVjfQBpQPtKBUZPs7YOebNjVCdXBoFwKSFHeWV/
 L3zs2/zelCqz8l+F3UFi7Pix+SZCOruah9iAPQaluhQvYEiz6BH5mnz+rm2v7X/X
 0/ySpKmtpBcRiL736s9tAZpGjgkfT6Ujdv4qWywX6YPVndoaWLbZlkwm/FGH9SwL
 KLE9bx0xi9u1b8bVN4OltV37g4cH7dqfktXYS0AP4S2lnjTkMCoUmzu0
 =7Lkr
 -----END PGP SIGNATURE-----

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
This commit is contained in:
Greg Kroah-Hartman 2021-05-10 16:30:03 +02:00
commit ba2b062ffa
10 changed files with 160 additions and 128 deletions

View File

@ -2017,7 +2017,7 @@ wait_again:
if (completion_value >= target_value) {
*status = CS_WAIT_STATUS_COMPLETED;
} else {
timeout -= jiffies_to_usecs(completion_rc);
timeout = completion_rc;
goto wait_again;
}
} else {

View File

@ -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) {
dev_warn(hdev->dev,
dev_err(hdev->dev,
"Device boot warning - security not ready\n");
/* This is a warning so we don't want it to disable the
* device
*/
err_val &= ~CPU_BOOT_ERR0_SECURITY_NOT_RDY;
err_exists = true;
}
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,
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 0;
@ -661,18 +659,13 @@ int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, u64 *total_energy)
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)
{
struct asic_fixed_properties *prop = &hdev->asic_prop;
u8 pll_byte, pll_bit_off;
bool dynamic_pll;
if (input_pll_index >= PLL_MAX) {
dev_err(hdev->dev, "PLL index %d is out of range\n",
input_pll_index);
return -EINVAL;
}
int fw_pll_idx;
dynamic_pll = prop->fw_security_status_valid &&
(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,
if (!dynamic_pll) {
/*
* 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;
}
/* PLL map is a u8 array */
pll_byte = prop->cpucp_info.pll_map[input_pll_index >> 3];
pll_bit_off = input_pll_index & 0x7;
if (!(pll_byte & BIT(pll_bit_off))) {
dev_err(hdev->dev, "PLL index %d is not supported\n",
input_pll_index);
/* 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_index = input_pll_index;
/* PLL map is a u8 array */
pll_byte = prop->cpucp_info.pll_map[fw_pll_idx >> 3];
pll_bit_off = fw_pll_idx & 0x7;
if (!(pll_byte & BIT(pll_bit_off))) {
dev_err(hdev->dev, "PLL index %d is not supported\n",
fw_pll_idx);
return -EINVAL;
}
*pll_index = fw_pll_idx;
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)
{
struct cpucp_packet pkt;
@ -844,8 +848,13 @@ int hl_fw_read_preboot_status(struct hl_device *hdev, u32 cpu_boot_status_reg,
if (rc) {
dev_err(hdev->dev, "Failed to read preboot version\n");
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;
}

View File

@ -930,6 +930,9 @@ enum div_select_defs {
* driver is ready to receive asynchronous events. This
* function should be called during the first init and
* 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 {
int (*early_init)(struct hl_device *hdev);
@ -1054,6 +1057,7 @@ struct hl_asic_funcs {
u32 block_id, u32 block_size);
void (*enable_events_from_fw)(struct hl_device *hdev);
void (*get_msi_info)(u32 *table);
int (*map_pll_idx_to_fw_idx)(u32 pll_idx);
};
@ -1950,8 +1954,6 @@ struct hl_mmu_funcs {
* @aggregated_cs_counters: aggregated cs counters among all contexts
* @mmu_priv: device-specific MMU data.
* @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.
* @timeout_jiffies: device CS timeout value.
* @max_power: the max power of the device, as configured by the sysadmin. This
@ -1960,6 +1962,12 @@ struct hl_mmu_funcs {
* @clock_gating_mask: is clock gating enabled. bitmask that represents the
* different engines. See debugfs-driver-habanalabs for
* 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.
* @curr_pll_profile: current PLL profile.
* @card_type: Various ASICs have several card types. This indicates the card
@ -2071,12 +2079,11 @@ struct hl_device {
struct hl_mmu_priv mmu_priv;
struct hl_mmu_funcs mmu_func[MMU_NUM_PGT_LOCATIONS];
enum pll_index *legacy_pll_map;
atomic64_t dram_used_mem;
u64 timeout_jiffies;
u64 max_power;
u64 clock_gating_mask;
u64 boot_error_status_mask;
atomic_t in_reset;
enum hl_pll_frequency curr_pll_profile;
enum cpucp_card_types card_type;
@ -2387,9 +2394,9 @@ int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev,
struct hl_info_pci_counters *counters);
int hl_fw_cpucp_total_energy_get(struct hl_device *hdev,
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);
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);
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,
@ -2411,9 +2418,9 @@ int hl_pci_set_outbound_region(struct hl_device *hdev,
int hl_pci_init(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);
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);
int hl_get_temperature(struct hl_device *hdev,
int sensor_index, u32 attr, long *value);

View File

@ -30,6 +30,7 @@ static DEFINE_MUTEX(hl_devs_idr_lock);
static int timeout_locked = 30;
static int reset_on_lockup = 1;
static int memory_scrub = 1;
static ulong boot_error_status_mask = ULONG_MAX;
module_param(timeout_locked, int, 0444);
MODULE_PARM_DESC(timeout_locked,
@ -43,6 +44,10 @@ module_param(memory_scrub, int, 0444);
MODULE_PARM_DESC(memory_scrub,
"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_IDS_GOYA 0x0001
@ -319,6 +324,8 @@ int create_hdev(struct hl_device **dev, struct pci_dev *pdev,
hdev->major = hl_major;
hdev->reset_on_lockup = reset_on_lockup;
hdev->memory_scrub = memory_scrub;
hdev->boot_error_status_mask = boot_error_status_mask;
hdev->pldm = 0;
set_driver_behavior_per_device(hdev);

View File

@ -9,7 +9,7 @@
#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)
{
struct cpucp_packet pkt;
@ -44,7 +44,7 @@ long hl_get_frequency(struct hl_device *hdev, enum pll_index pll_index,
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)
{
struct cpucp_packet pkt;

View File

@ -105,36 +105,6 @@
#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] = {
"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",
@ -810,7 +780,7 @@ static int gaudi_fetch_psoc_frequency(struct hl_device *hdev)
freq = 0;
}
} 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)
return rc;
@ -1652,9 +1622,6 @@ static int gaudi_sw_init(struct hl_device *hdev)
hdev->asic_specific = gaudi;
/* store legacy PLL map */
hdev->legacy_pll_map = gaudi_pll_map;
/* Create DMA pool for small allocations */
hdev->dma_pool = dma_pool_create(dev_name(hdev->dev),
&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,
struct hl_cs_job *job;
u32 cb_size, ctl, err_cause;
struct hl_cb *cb;
u64 id;
int rc;
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,
}
release_cb:
id = cb->id;
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;
}
@ -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);
}
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 = {
.early_init = gaudi_early_init,
.early_fini = gaudi_early_fini,
@ -8866,7 +8852,8 @@ static const struct hl_asic_funcs gaudi_funcs = {
.ack_protection_bits_errors = gaudi_ack_protection_bits_errors,
.get_hw_block_id = gaudi_get_hw_block_id,
.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
};
/**

View File

@ -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;
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)
@ -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))
return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, false);
value = hl_get_frequency(hdev, HL_GAUDI_MME_PLL, false);
if (value < 0) {
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)
*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) {
dev_err(hdev->dev,
@ -57,7 +57,7 @@ static ssize_t clk_max_freq_mhz_show(struct device *dev,
if (!hl_device_operational(hdev, NULL))
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;
@ -85,7 +85,7 @@ static ssize_t clk_max_freq_mhz_store(struct device *dev,
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:
return count;
@ -100,7 +100,7 @@ static ssize_t clk_cur_freq_mhz_show(struct device *dev,
if (!hl_device_operational(hdev, NULL))
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));
}

View File

@ -118,30 +118,6 @@
#define IS_MME_IDLE(mme_arch_sts) \
(((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] = {
"goya cq 0", "goya cq 1", "goya cq 2", "goya cq 3",
"goya cq 4", "goya cpu eq"
@ -775,7 +751,8 @@ static void goya_fetch_psoc_frequency(struct hl_device *hdev)
freq = 0;
}
} 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)
return;
@ -897,9 +874,6 @@ static int goya_sw_init(struct hl_device *hdev)
hdev->asic_specific = goya;
/* store legacy PLL map */
hdev->legacy_pll_map = goya_pll_map;
/* Create DMA pool for small allocations */
hdev->dma_pool = dma_pool_create(dev_name(hdev->dev),
&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)
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 = {
.early_init = goya_early_init,
.early_fini = goya_early_fini,
@ -5595,7 +5583,8 @@ static const struct hl_asic_funcs goya_funcs = {
.ack_protection_bits_errors = goya_ack_protection_bits_errors,
.get_hw_block_id = goya_get_hw_block_id,
.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
};
/*

View File

@ -13,19 +13,19 @@ void goya_set_pll_profile(struct hl_device *hdev, enum hl_pll_frequency freq)
switch (freq) {
case PLL_HIGH:
hl_set_frequency(hdev, MME_PLL, hdev->high_pll);
hl_set_frequency(hdev, TPC_PLL, hdev->high_pll);
hl_set_frequency(hdev, IC_PLL, hdev->high_pll);
hl_set_frequency(hdev, HL_GOYA_MME_PLL, hdev->high_pll);
hl_set_frequency(hdev, HL_GOYA_TPC_PLL, hdev->high_pll);
hl_set_frequency(hdev, HL_GOYA_IC_PLL, hdev->high_pll);
break;
case PLL_LOW:
hl_set_frequency(hdev, MME_PLL, GOYA_PLL_FREQ_LOW);
hl_set_frequency(hdev, TPC_PLL, GOYA_PLL_FREQ_LOW);
hl_set_frequency(hdev, IC_PLL, GOYA_PLL_FREQ_LOW);
hl_set_frequency(hdev, HL_GOYA_MME_PLL, GOYA_PLL_FREQ_LOW);
hl_set_frequency(hdev, HL_GOYA_TPC_PLL, GOYA_PLL_FREQ_LOW);
hl_set_frequency(hdev, HL_GOYA_IC_PLL, GOYA_PLL_FREQ_LOW);
break;
case PLL_LAST:
hl_set_frequency(hdev, MME_PLL, goya->mme_clk);
hl_set_frequency(hdev, TPC_PLL, goya->tpc_clk);
hl_set_frequency(hdev, IC_PLL, goya->ic_clk);
hl_set_frequency(hdev, HL_GOYA_MME_PLL, goya->mme_clk);
hl_set_frequency(hdev, HL_GOYA_TPC_PLL, goya->tpc_clk);
hl_set_frequency(hdev, HL_GOYA_IC_PLL, goya->ic_clk);
break;
default:
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)
if (!hl_device_operational(hdev, NULL))
return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, false);
value = hl_get_frequency(hdev, HL_GOYA_MME_PLL, false);
if (value < 0) {
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)
*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) {
dev_err(hdev->dev,
@ -72,7 +72,7 @@ static ssize_t mme_clk_show(struct device *dev, struct device_attribute *attr,
if (!hl_device_operational(hdev, NULL))
return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, false);
value = hl_get_frequency(hdev, HL_GOYA_MME_PLL, false);
if (value < 0)
return value;
@ -105,7 +105,7 @@ static ssize_t mme_clk_store(struct device *dev, struct device_attribute *attr,
goto fail;
}
hl_set_frequency(hdev, MME_PLL, value);
hl_set_frequency(hdev, HL_GOYA_MME_PLL, value);
goya->mme_clk = value;
fail:
@ -121,7 +121,7 @@ static ssize_t tpc_clk_show(struct device *dev, struct device_attribute *attr,
if (!hl_device_operational(hdev, NULL))
return -ENODEV;
value = hl_get_frequency(hdev, TPC_PLL, false);
value = hl_get_frequency(hdev, HL_GOYA_TPC_PLL, false);
if (value < 0)
return value;
@ -154,7 +154,7 @@ static ssize_t tpc_clk_store(struct device *dev, struct device_attribute *attr,
goto fail;
}
hl_set_frequency(hdev, TPC_PLL, value);
hl_set_frequency(hdev, HL_GOYA_TPC_PLL, value);
goya->tpc_clk = value;
fail:
@ -170,7 +170,7 @@ static ssize_t ic_clk_show(struct device *dev, struct device_attribute *attr,
if (!hl_device_operational(hdev, NULL))
return -ENODEV;
value = hl_get_frequency(hdev, IC_PLL, false);
value = hl_get_frequency(hdev, HL_GOYA_IC_PLL, false);
if (value < 0)
return value;
@ -203,7 +203,7 @@ static ssize_t ic_clk_store(struct device *dev, struct device_attribute *attr,
goto fail;
}
hl_set_frequency(hdev, IC_PLL, value);
hl_set_frequency(hdev, HL_GOYA_IC_PLL, value);
goya->ic_clk = value;
fail:
@ -219,7 +219,7 @@ static ssize_t mme_clk_curr_show(struct device *dev,
if (!hl_device_operational(hdev, NULL))
return -ENODEV;
value = hl_get_frequency(hdev, MME_PLL, true);
value = hl_get_frequency(hdev, HL_GOYA_MME_PLL, true);
if (value < 0)
return value;
@ -236,7 +236,7 @@ static ssize_t tpc_clk_curr_show(struct device *dev,
if (!hl_device_operational(hdev, NULL))
return -ENODEV;
value = hl_get_frequency(hdev, TPC_PLL, true);
value = hl_get_frequency(hdev, HL_GOYA_TPC_PLL, true);
if (value < 0)
return value;
@ -253,7 +253,7 @@ static ssize_t ic_clk_curr_show(struct device *dev,
if (!hl_device_operational(hdev, NULL))
return -ENODEV;
value = hl_get_frequency(hdev, IC_PLL, true);
value = hl_get_frequency(hdev, HL_GOYA_IC_PLL, true);
if (value < 0)
return value;

View File

@ -239,6 +239,39 @@ enum gaudi_engine_id {
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 {
HL_DEVICE_STATUS_OPERATIONAL,
HL_DEVICE_STATUS_IN_RESET,