static bool gaudi_is_device_idle()

in habanalabs/gaudi/gaudi.c [8451:8593]


static bool gaudi_is_device_idle(struct hl_device *hdev, u64 *mask_arr,
					u8 mask_len, struct seq_file *s)
{
	struct gaudi_device *gaudi = hdev->asic_specific;
	const char *fmt = "%-5d%-9s%#-14x%#-12x%#x\n";
	const char *mme_slave_fmt = "%-5d%-9s%-14s%-12s%#x\n";
	const char *nic_fmt = "%-5d%-9s%#-14x%#x\n";
	unsigned long *mask = (unsigned long *)mask_arr;
	u32 qm_glbl_sts0, qm_cgm_sts, dma_core_sts0, tpc_cfg_sts, mme_arch_sts;
	bool is_idle = true, is_eng_idle, is_slave;
	u64 offset;
	int i, dma_id, port;

	mutex_lock(&gaudi->clk_gate_mutex);

	hdev->asic_funcs->disable_clock_gating(hdev);

	if (s)
		seq_puts(s,
			"\nDMA  is_idle  QM_GLBL_STS0  QM_CGM_STS  DMA_CORE_STS0\n"
			"---  -------  ------------  ----------  -------------\n");

	for (i = 0 ; i < DMA_NUMBER_OF_CHNLS ; i++) {
		dma_id = gaudi_dma_assignment[i];
		offset = dma_id * DMA_QMAN_OFFSET;

		qm_glbl_sts0 = RREG32(mmDMA0_QM_GLBL_STS0 + offset);
		qm_cgm_sts = RREG32(mmDMA0_QM_CGM_STS + offset);
		dma_core_sts0 = RREG32(mmDMA0_CORE_STS0 + offset);
		is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts) &&
				IS_DMA_IDLE(dma_core_sts0);
		is_idle &= is_eng_idle;

		if (mask && !is_eng_idle)
			set_bit(GAUDI_ENGINE_ID_DMA_0 + dma_id, mask);
		if (s)
			seq_printf(s, fmt, dma_id,
				is_eng_idle ? "Y" : "N", qm_glbl_sts0,
				qm_cgm_sts, dma_core_sts0);
	}

	if (s)
		seq_puts(s,
			"\nTPC  is_idle  QM_GLBL_STS0  QM_CGM_STS  CFG_STATUS\n"
			"---  -------  ------------  ----------  ----------\n");

	for (i = 0 ; i < TPC_NUMBER_OF_ENGINES ; i++) {
		offset = i * TPC_QMAN_OFFSET;
		qm_glbl_sts0 = RREG32(mmTPC0_QM_GLBL_STS0 + offset);
		qm_cgm_sts = RREG32(mmTPC0_QM_CGM_STS + offset);
		tpc_cfg_sts = RREG32(mmTPC0_CFG_STATUS + offset);
		is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts) &&
				IS_TPC_IDLE(tpc_cfg_sts);
		is_idle &= is_eng_idle;

		if (mask && !is_eng_idle)
			set_bit(GAUDI_ENGINE_ID_TPC_0 + i, mask);
		if (s)
			seq_printf(s, fmt, i,
				is_eng_idle ? "Y" : "N",
				qm_glbl_sts0, qm_cgm_sts, tpc_cfg_sts);
	}

	if (s)
		seq_puts(s,
			"\nMME  is_idle  QM_GLBL_STS0  QM_CGM_STS  ARCH_STATUS\n"
			"---  -------  ------------  ----------  -----------\n");

	for (i = 0 ; i < MME_NUMBER_OF_ENGINES ; i++) {
		offset = i * MME_QMAN_OFFSET;
		mme_arch_sts = RREG32(mmMME0_CTRL_ARCH_STATUS + offset);
		is_eng_idle = IS_MME_IDLE(mme_arch_sts);

		/* MME 1 & 3 are slaves, no need to check their QMANs */
		is_slave = i % 2;
		if (!is_slave) {
			qm_glbl_sts0 = RREG32(mmMME0_QM_GLBL_STS0 + offset);
			qm_cgm_sts = RREG32(mmMME0_QM_CGM_STS + offset);
			is_eng_idle &= IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts);
		}

		is_idle &= is_eng_idle;

		if (mask && !is_eng_idle)
			set_bit(GAUDI_ENGINE_ID_MME_0 + i, mask);
		if (s) {
			if (!is_slave)
				seq_printf(s, fmt, i,
					is_eng_idle ? "Y" : "N",
					qm_glbl_sts0, qm_cgm_sts, mme_arch_sts);
			else
				seq_printf(s, mme_slave_fmt, i,
					is_eng_idle ? "Y" : "N", "-",
					"-", mme_arch_sts);
		}
	}

	if (s)
		seq_puts(s, "\nNIC  is_idle  QM_GLBL_STS0  QM_CGM_STS\n"
				"---  -------  ------------  ----------\n");

	for (i = 0 ; i < (NIC_NUMBER_OF_ENGINES / 2) ; i++) {
		offset = i * NIC_MACRO_QMAN_OFFSET;
		port = 2 * i;
		if (gaudi->hw_cap_initialized & BIT(HW_CAP_NIC_SHIFT + port)) {
			qm_glbl_sts0 = RREG32(mmNIC0_QM0_GLBL_STS0 + offset);
			qm_cgm_sts = RREG32(mmNIC0_QM0_CGM_STS + offset);
			is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts);
			is_idle &= is_eng_idle;

			if (mask && !is_eng_idle)
				set_bit(GAUDI_ENGINE_ID_NIC_0 + port, mask);
			if (s)
				seq_printf(s, nic_fmt, port,
						is_eng_idle ? "Y" : "N",
						qm_glbl_sts0, qm_cgm_sts);
		}

		port = 2 * i + 1;
		if (gaudi->hw_cap_initialized & BIT(HW_CAP_NIC_SHIFT + port)) {
			qm_glbl_sts0 = RREG32(mmNIC0_QM1_GLBL_STS0 + offset);
			qm_cgm_sts = RREG32(mmNIC0_QM1_CGM_STS + offset);
			is_eng_idle = IS_QM_IDLE(qm_glbl_sts0, qm_cgm_sts);
			is_idle &= is_eng_idle;

			if (mask && !is_eng_idle)
				set_bit(GAUDI_ENGINE_ID_NIC_0 + port, mask);
			if (s)
				seq_printf(s, nic_fmt, port,
						is_eng_idle ? "Y" : "N",
						qm_glbl_sts0, qm_cgm_sts);
		}
	}

	if (s)
		seq_puts(s, "\n");

	hdev->asic_funcs->set_clock_gating(hdev);

	mutex_unlock(&gaudi->clk_gate_mutex);

	return is_idle;
}