habanalabs: send dynamic msi-x indexes to f/w

In order to minimize hard coded values between F/W and the driver, we
send msi-x indexes dynamically to the F/W.

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:
Ohad Sharabi 2021-03-22 14:30:52 +02:00 committed by Oded Gabbay
parent 1b4971573f
commit e9c2003be4
5 changed files with 131 additions and 19 deletions

View File

@ -422,6 +422,73 @@ out:
return rc;
}
static int hl_fw_send_msi_info_msg(struct hl_device *hdev)
{
struct cpucp_array_data_packet *pkt;
size_t total_pkt_size, data_size;
u64 result;
int rc;
/* skip sending this info for unsupported ASICs */
if (!hdev->asic_funcs->get_msi_info)
return 0;
data_size = CPUCP_NUM_OF_MSI_TYPES * sizeof(u32);
total_pkt_size = sizeof(struct cpucp_array_data_packet) + data_size;
/* data should be aligned to 8 bytes in order to CPU-CP to copy it */
total_pkt_size = (total_pkt_size + 0x7) & ~0x7;
/* total_pkt_size is casted to u16 later on */
if (total_pkt_size > USHRT_MAX) {
dev_err(hdev->dev, "CPUCP array data is too big\n");
return -EINVAL;
}
pkt = kzalloc(total_pkt_size, GFP_KERNEL);
if (!pkt)
return -ENOMEM;
pkt->length = cpu_to_le32(CPUCP_NUM_OF_MSI_TYPES);
hdev->asic_funcs->get_msi_info((u32 *)&pkt->data);
pkt->cpucp_pkt.ctl = cpu_to_le32(CPUCP_PACKET_MSI_INFO_SET <<
CPUCP_PKT_CTL_OPCODE_SHIFT);
rc = hdev->asic_funcs->send_cpu_message(hdev, (u32 *)pkt,
total_pkt_size, 0, &result);
/*
* in case packet result is invalid it means that FW does not support
* this feature and will use default/hard coded MSI values. no reason
* to stop the boot
*/
if (rc && result == cpucp_packet_invalid)
rc = 0;
if (rc)
dev_err(hdev->dev, "failed to send CPUCP array data\n");
kfree(pkt);
return rc;
}
int hl_fw_cpucp_handshake(struct hl_device *hdev,
u32 cpu_security_boot_status_reg,
u32 boot_err0_reg)
{
int rc;
rc = hl_fw_cpucp_info_get(hdev, cpu_security_boot_status_reg,
boot_err0_reg);
if (rc)
return rc;
return hl_fw_send_msi_info_msg(hdev);
}
int hl_fw_get_eeprom_data(struct hl_device *hdev, void *data, size_t max_size)
{
struct cpucp_packet pkt = {};

View File

@ -1049,6 +1049,7 @@ struct hl_asic_funcs {
int (*hw_block_mmap)(struct hl_device *hdev, struct vm_area_struct *vma,
u32 block_id, u32 block_size);
void (*enable_events_from_fw)(struct hl_device *hdev);
void (*get_msi_info)(u32 *table);
};
@ -2374,6 +2375,9 @@ int hl_fw_send_heartbeat(struct hl_device *hdev);
int hl_fw_cpucp_info_get(struct hl_device *hdev,
u32 cpu_security_boot_status_reg,
u32 boot_err0_reg);
int hl_fw_cpucp_handshake(struct hl_device *hdev,
u32 cpu_security_boot_status_reg,
u32 boot_err0_reg);
int hl_fw_get_eeprom_data(struct hl_device *hdev, void *data, size_t max_size);
int hl_fw_cpucp_pci_counters_get(struct hl_device *hdev,
struct hl_info_pci_counters *counters);

View File

@ -7966,7 +7966,7 @@ static int gaudi_cpucp_info_get(struct hl_device *hdev)
if (!(gaudi->hw_cap_initialized & HW_CAP_CPU_Q))
return 0;
rc = hl_fw_cpucp_info_get(hdev, mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0);
rc = hl_fw_cpucp_handshake(hdev, mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0);
if (rc)
return rc;

View File

@ -5245,7 +5245,7 @@ int goya_cpucp_info_get(struct hl_device *hdev)
if (!(goya->hw_cap_initialized & HW_CAP_CPU_Q))
return 0;
rc = hl_fw_cpucp_info_get(hdev, mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0);
rc = hl_fw_cpucp_handshake(hdev, mmCPU_BOOT_DEV_STS0, mmCPU_BOOT_ERR0);
if (rc)
return rc;

View File

@ -302,6 +302,27 @@ enum pq_init_status {
* CPUCP_PACKET_POWER_GET
* Fetch the present power consumption of the device (Current * Voltage).
*
* CPUCP_PACKET_NIC_PFC_SET -
* Enable/Disable the NIC PFC feature. The packet's arguments specify the
* NIC port, relevant lanes to configure and one bit indication for
* enable/disable.
*
* CPUCP_PACKET_NIC_FAULT_GET -
* Fetch the current indication for local/remote faults from the NIC MAC.
* The result is 32-bit value of the relevant register.
*
* CPUCP_PACKET_NIC_LPBK_SET -
* Enable/Disable the MAC loopback feature. The packet's arguments specify
* the NIC port, relevant lanes to configure and one bit indication for
* enable/disable.
*
* CPUCP_PACKET_NIC_MAC_INIT -
* Configure the NIC MAC channels. The packet's arguments specify the
* NIC port and the speed.
*
* CPUCP_PACKET_MSI_INFO_SET -
* set the index number for each supported msi type going from
* host to device
*/
enum cpucp_packet_id {
@ -337,6 +358,11 @@ enum cpucp_packet_id {
CPUCP_PACKET_PLL_INFO_GET, /* internal */
CPUCP_PACKET_NIC_STATUS, /* internal */
CPUCP_PACKET_POWER_GET, /* internal */
CPUCP_PACKET_NIC_PFC_SET, /* internal */
CPUCP_PACKET_NIC_FAULT_GET, /* internal */
CPUCP_PACKET_NIC_LPBK_SET, /* internal */
CPUCP_PACKET_NIC_MAC_CFG, /* internal */
CPUCP_PACKET_MSI_INFO_SET, /* internal */
};
#define CPUCP_PACKET_FENCE_VAL 0xFE8CE7A5
@ -408,6 +434,12 @@ struct cpucp_unmask_irq_arr_packet {
__le32 irqs[0];
};
struct cpucp_array_data_packet {
struct cpucp_packet cpucp_pkt;
__le32 length;
__le32 data[0];
};
enum cpucp_packet_rc {
cpucp_packet_success,
cpucp_packet_invalid,
@ -476,6 +508,22 @@ enum cpucp_pll_type_attributes {
cpucp_pll_pci,
};
/*
* MSI type enumeration table for all ASICs and future SW versions.
* For future ASIC-LKD compatibility, we can only add new enumerations.
* at the end of the table (before CPUCP_NUM_OF_MSI_TYPES).
* Changing the order of entries or removing entries is not allowed.
*/
enum cpucp_msi_type {
CPUCP_EVENT_QUEUE_MSI_TYPE,
CPUCP_NIC_PORT1_MSI_TYPE,
CPUCP_NIC_PORT3_MSI_TYPE,
CPUCP_NIC_PORT5_MSI_TYPE,
CPUCP_NIC_PORT7_MSI_TYPE,
CPUCP_NIC_PORT9_MSI_TYPE,
CPUCP_NUM_OF_MSI_TYPES
};
/*
* PLL enumeration table used for all ASICs and future SW versions.
* For future ASIC-LKD compatibility, we can only add new enumerations.
@ -492,23 +540,16 @@ enum pll_index {
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,
NS_PLL = 9,
HBM_PLL = 10,
MSS_PLL = 11,
DDR_PLL = 12,
VID_PLL = 13,
BANK_PLL = 14,
MMU_PLL = 15,
IC_PLL = 16,
MC_PLL = 17,
EMMC_PLL = 18,
PLL_MAX
};