Commit e9c2003b authored by Ohad Sharabi's avatar Ohad Sharabi Committed by Oded Gabbay
Browse files

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: default avatarOhad Sharabi <osharabi@habana.ai>
Reviewed-by: default avatarOded Gabbay <ogabbay@kernel.org>
Signed-off-by: default avatarOded Gabbay <ogabbay@kernel.org>
parent 1b497157
Loading
Loading
Loading
Loading
+67 −0
Original line number Diff line number Diff line
@@ -422,6 +422,73 @@ int hl_fw_cpucp_info_get(struct hl_device *hdev,
	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 = {};
+4 −0
Original line number Diff line number Diff line
@@ -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);
+1 −1
Original line number Diff line number Diff line
@@ -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;

+1 −1
Original line number Diff line number Diff line
@@ -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;

+58 −17
Original line number Diff line number Diff line
@@ -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
};