mirror of
https://github.com/edk2-porting/linux-next.git
synced 2025-01-15 09:03:59 +08:00
habanalabs: support legacy and new pll indexes
In order to use minimum of hard coded values common to LKD and F/W a dynamic method to work with PLLs is introduced in this patch. Formerly asic specific PLL numbering is now common for all asics. To be backward compatible a bit in dev status is defined, if the bit is not set LKD will keep working with old PLL numbering. Signed-off-by: Ohad Sharabi <osharabi@habana.ai> Reviewed-by: Oded Gabbay <ogabbay@kernel.org> Signed-off-by: Oded Gabbay <ogabbay@kernel.org>
This commit is contained in:
parent
8445dde1b9
commit
e8f9392a5c
@ -539,18 +539,63 @@ int hl_fw_cpucp_total_energy_get(struct hl_device *hdev, u64 *total_energy)
|
||||
return rc;
|
||||
}
|
||||
|
||||
int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, u16 pll_index,
|
||||
int get_used_pll_index(struct hl_device *hdev, enum pll_index 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;
|
||||
}
|
||||
|
||||
dynamic_pll = prop->fw_security_status_valid &&
|
||||
(prop->fw_app_security_map & CPU_BOOT_DEV_STS0_DYN_PLL_EN);
|
||||
|
||||
if (!dynamic_pll) {
|
||||
/*
|
||||
* in case we are working with legacy FW (each asic has unique
|
||||
* PLL numbering) extract the legacy numbering
|
||||
*/
|
||||
*pll_index = hdev->legacy_pll_map[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);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
*pll_index = input_pll_index;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, enum pll_index pll_index,
|
||||
u16 *pll_freq_arr)
|
||||
{
|
||||
struct cpucp_packet pkt;
|
||||
enum pll_index used_pll_idx;
|
||||
u64 result;
|
||||
int rc;
|
||||
|
||||
rc = get_used_pll_index(hdev, pll_index, &used_pll_idx);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
|
||||
pkt.ctl = cpu_to_le32(CPUCP_PACKET_PLL_INFO_GET <<
|
||||
CPUCP_PKT_CTL_OPCODE_SHIFT);
|
||||
pkt.pll_type = __cpu_to_le16(pll_index);
|
||||
pkt.pll_type = __cpu_to_le16((u16)used_pll_idx);
|
||||
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
|
||||
HL_CPUCP_INFO_TIMEOUT_USEC, &result);
|
||||
|
@ -1946,6 +1946,8 @@ 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
|
||||
@ -2070,6 +2072,8 @@ 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;
|
||||
@ -2383,7 +2387,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 hl_fw_cpucp_pll_info_get(struct hl_device *hdev, u16 pll_index,
|
||||
int get_used_pll_index(struct hl_device *hdev, enum pll_index input_pll_index,
|
||||
enum pll_index *pll_index);
|
||||
int hl_fw_cpucp_pll_info_get(struct hl_device *hdev, enum pll_index 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,
|
||||
@ -2404,8 +2410,10 @@ 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, u32 pll_index, bool curr);
|
||||
void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq);
|
||||
long hl_get_frequency(struct hl_device *hdev, enum pll_index pll_index,
|
||||
bool curr);
|
||||
void hl_set_frequency(struct hl_device *hdev, enum pll_index pll_index,
|
||||
u64 freq);
|
||||
int hl_get_temperature(struct hl_device *hdev,
|
||||
int sensor_index, u32 attr, long *value);
|
||||
int hl_set_temperature(struct hl_device *hdev,
|
||||
|
@ -9,12 +9,18 @@
|
||||
|
||||
#include <linux/pci.h>
|
||||
|
||||
long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr)
|
||||
long hl_get_frequency(struct hl_device *hdev, enum pll_index pll_index,
|
||||
bool curr)
|
||||
{
|
||||
struct cpucp_packet pkt;
|
||||
u32 used_pll_idx;
|
||||
u64 result;
|
||||
int rc;
|
||||
|
||||
rc = get_used_pll_index(hdev, pll_index, &used_pll_idx);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
|
||||
if (curr)
|
||||
@ -23,7 +29,7 @@ long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr)
|
||||
else
|
||||
pkt.ctl = cpu_to_le32(CPUCP_PACKET_FREQUENCY_GET <<
|
||||
CPUCP_PKT_CTL_OPCODE_SHIFT);
|
||||
pkt.pll_index = cpu_to_le32(pll_index);
|
||||
pkt.pll_index = cpu_to_le32((u32)used_pll_idx);
|
||||
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
|
||||
0, &result);
|
||||
@ -31,23 +37,29 @@ long hl_get_frequency(struct hl_device *hdev, u32 pll_index, bool curr)
|
||||
if (rc) {
|
||||
dev_err(hdev->dev,
|
||||
"Failed to get frequency of PLL %d, error %d\n",
|
||||
pll_index, rc);
|
||||
used_pll_idx, rc);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return (long) result;
|
||||
}
|
||||
|
||||
void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq)
|
||||
void hl_set_frequency(struct hl_device *hdev, enum pll_index pll_index,
|
||||
u64 freq)
|
||||
{
|
||||
struct cpucp_packet pkt;
|
||||
u32 used_pll_idx;
|
||||
int rc;
|
||||
|
||||
rc = get_used_pll_index(hdev, pll_index, &used_pll_idx);
|
||||
if (rc)
|
||||
return;
|
||||
|
||||
memset(&pkt, 0, sizeof(pkt));
|
||||
|
||||
pkt.ctl = cpu_to_le32(CPUCP_PACKET_FREQUENCY_SET <<
|
||||
CPUCP_PKT_CTL_OPCODE_SHIFT);
|
||||
pkt.pll_index = cpu_to_le32(pll_index);
|
||||
pkt.pll_index = cpu_to_le32((u32)used_pll_idx);
|
||||
pkt.value = cpu_to_le64(freq);
|
||||
|
||||
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *) &pkt, sizeof(pkt),
|
||||
@ -56,7 +68,7 @@ void hl_set_frequency(struct hl_device *hdev, u32 pll_index, u64 freq)
|
||||
if (rc)
|
||||
dev_err(hdev->dev,
|
||||
"Failed to set frequency to PLL %d, error %d\n",
|
||||
pll_index, rc);
|
||||
used_pll_idx, rc);
|
||||
}
|
||||
|
||||
u64 hl_get_max_power(struct hl_device *hdev)
|
||||
|
@ -105,6 +105,36 @@
|
||||
|
||||
#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",
|
||||
@ -1588,6 +1618,9 @@ 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);
|
||||
|
@ -118,6 +118,29 @@
|
||||
#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",
|
||||
@ -853,6 +876,9 @@ 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);
|
||||
|
@ -28,6 +28,9 @@
|
||||
#define CPUCP_PKT_HBM_ECC_INFO_HBM_CH_SHIFT 6
|
||||
#define CPUCP_PKT_HBM_ECC_INFO_HBM_CH_MASK 0x000007C0
|
||||
|
||||
#define PLL_MAP_MAX_BITS 128
|
||||
#define PLL_MAP_LEN (PLL_MAP_MAX_BITS / 8)
|
||||
|
||||
/*
|
||||
* info of the pkt queue pointers in the first async occurrence
|
||||
*/
|
||||
@ -473,6 +476,42 @@ enum cpucp_pll_type_attributes {
|
||||
cpucp_pll_pci,
|
||||
};
|
||||
|
||||
/*
|
||||
* PLL enumeration table used for all ASICs and future SW versions.
|
||||
* For future ASIC-LKD compatibility, we can only add new enumerations.
|
||||
* at the end of the table.
|
||||
* Changing the order of entries or removing entries is not allowed.
|
||||
*/
|
||||
enum pll_index {
|
||||
CPU_PLL = 0,
|
||||
PCI_PLL = 1,
|
||||
NIC_PLL = 2,
|
||||
DMA_PLL = 3,
|
||||
MESH_PLL = 4,
|
||||
MME_PLL = 5,
|
||||
TPC_PLL = 6,
|
||||
IF_PLL = 7,
|
||||
SRAM_PLL = 8,
|
||||
NS_DCORE_PLL = 9,
|
||||
MESH_DCORE_PLL = 10,
|
||||
HBM_PLL = 11,
|
||||
TPC_DCORE_PLL = 12,
|
||||
VIDEO_DCORE_PLL = 13,
|
||||
SRAM_DCORE_PLL = 14,
|
||||
NIC_PHY_DCORE_PLL = 15,
|
||||
MSS_DCORE_PLL = 16,
|
||||
DMA_DCORE_PLL = 17,
|
||||
SIF_PLL = 18,
|
||||
DDR_PLL = 19,
|
||||
VID_PLL = 20,
|
||||
BANK_PLL = 21,
|
||||
MMU_PLL = 22,
|
||||
IC_PLL = 23,
|
||||
MC_PLL = 24,
|
||||
EMMC_PLL = 25,
|
||||
PLL_MAX
|
||||
};
|
||||
|
||||
/* Event Queue Packets */
|
||||
|
||||
struct eq_generic_event {
|
||||
@ -547,6 +586,7 @@ struct cpucp_security_info {
|
||||
* @dram_size: available DRAM size.
|
||||
* @card_name: card name that will be displayed in HWMON subsystem on the host
|
||||
* @sec_info: security information
|
||||
* @pll_map: Bit map of supported PLLs for current ASIC version.
|
||||
*/
|
||||
struct cpucp_info {
|
||||
struct cpucp_sensor sensors[CPUCP_MAX_SENSORS];
|
||||
@ -568,6 +608,7 @@ struct cpucp_info {
|
||||
__u8 pad[7];
|
||||
struct cpucp_security_info sec_info;
|
||||
__le32 reserved6;
|
||||
__u8 pll_map[PLL_MAP_LEN];
|
||||
};
|
||||
|
||||
struct cpucp_mac_addr {
|
||||
|
@ -179,6 +179,11 @@
|
||||
* configured and is ready for use.
|
||||
* Initialized in: ppboot
|
||||
*
|
||||
* CPU_BOOT_DEV_STS0_DYN_PLL_EN Dynamic PLL configuration is enabled.
|
||||
* FW sends to host a bitmap of supported
|
||||
* PLLs.
|
||||
* Initialized in: linux
|
||||
*
|
||||
* CPU_BOOT_DEV_STS0_ENABLED Device status register enabled.
|
||||
* This is a main indication that the
|
||||
* running FW populates the device status
|
||||
@ -206,6 +211,7 @@
|
||||
#define CPU_BOOT_DEV_STS0_PKT_PI_ACK_EN (1 << 15)
|
||||
#define CPU_BOOT_DEV_STS0_FW_LD_COM_EN (1 << 16)
|
||||
#define CPU_BOOT_DEV_STS0_FW_IATU_CONF_EN (1 << 17)
|
||||
#define CPU_BOOT_DEV_STS0_DYN_PLL_EN (1 << 19)
|
||||
#define CPU_BOOT_DEV_STS0_ENABLED (1 << 31)
|
||||
|
||||
enum cpu_boot_status {
|
||||
|
@ -20,20 +20,6 @@
|
||||
#define UBOOT_FW_OFFSET 0x100000 /* 1MB in SRAM */
|
||||
#define LINUX_FW_OFFSET 0x800000 /* 8MB in HBM */
|
||||
|
||||
enum gaudi_pll_index {
|
||||
CPU_PLL = 0,
|
||||
PCI_PLL,
|
||||
SRAM_PLL,
|
||||
HBM_PLL,
|
||||
NIC_PLL,
|
||||
DMA_PLL,
|
||||
MESH_PLL,
|
||||
MME_PLL,
|
||||
TPC_PLL,
|
||||
IF_PLL,
|
||||
PLL_MAX
|
||||
};
|
||||
|
||||
enum gaudi_nic_axi_error {
|
||||
RXB,
|
||||
RXE,
|
||||
|
@ -15,17 +15,6 @@
|
||||
#define UBOOT_FW_OFFSET 0x100000 /* 1MB in SRAM */
|
||||
#define LINUX_FW_OFFSET 0x800000 /* 8MB in DDR */
|
||||
|
||||
enum goya_pll_index {
|
||||
CPU_PLL = 0,
|
||||
IC_PLL,
|
||||
MC_PLL,
|
||||
MME_PLL,
|
||||
PCI_PLL,
|
||||
EMMC_PLL,
|
||||
TPC_PLL,
|
||||
PLL_MAX
|
||||
};
|
||||
|
||||
#define GOYA_PLL_FREQ_LOW 50000000 /* 50 MHz */
|
||||
|
||||
#endif /* GOYA_FW_IF_H */
|
||||
|
Loading…
Reference in New Issue
Block a user