mirror of
https://github.com/torvalds/linux.git
synced 2024-11-10 14:11:52 +00:00
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:
commit
ba2b062ffa
@ -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 {
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -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));
|
||||
}
|
||||
|
@ -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
|
||||
};
|
||||
|
||||
/*
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user