brintos

brintos / linux-shallow public Read only

0
0
Text · 34.6 KiB · 60b33fc Raw
1178 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright (C) 2020-2024 Intel Corporation4 */5 6#include "ivpu_drv.h"7#include "ivpu_fw.h"8#include "ivpu_hw.h"9#include "ivpu_hw_37xx_reg.h"10#include "ivpu_hw_40xx_reg.h"11#include "ivpu_hw_ip.h"12#include "ivpu_hw_reg_io.h"13#include "ivpu_mmu.h"14#include "ivpu_pm.h"15 16#define PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT 017#define PWR_ISLAND_EN_POST_DLY_FREQ_HIGH    1818#define PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT  319#define PWR_ISLAND_STATUS_DLY_FREQ_HIGH	    4620#define PWR_ISLAND_STATUS_TIMEOUT_US        (5 * USEC_PER_MSEC)21 22#define TIM_SAFE_ENABLE		            0xf1d0dead23#define TIM_WATCHDOG_RESET_VALUE            0xffffffff24 25#define ICB_0_IRQ_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \26			     (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \27			     (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \28			     (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \29			     (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \30			     (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \31			     (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))32 33#define ICB_1_IRQ_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \34			     (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \35			     (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))36 37#define ICB_0_1_IRQ_MASK_37XX ((((u64)ICB_1_IRQ_MASK_37XX) << 32) | ICB_0_IRQ_MASK_37XX)38 39#define ICB_0_IRQ_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \40			     (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \41			     (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \42			     (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \43			     (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \44			     (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \45			     (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))46 47#define ICB_1_IRQ_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \48			     (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \49			     (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))50 51#define ICB_0_1_IRQ_MASK_40XX ((((u64)ICB_1_IRQ_MASK_40XX) << 32) | ICB_0_IRQ_MASK_40XX)52 53#define ITF_FIREWALL_VIOLATION_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \54					  (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \55					  (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \56					  (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \57					  (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \58					  (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \59					  (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))60 61#define ITF_FIREWALL_VIOLATION_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \62					  (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \63					  (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \64					  (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \65					  (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \66					  (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \67					  (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))68 69static int wait_for_ip_bar(struct ivpu_device *vdev)70{71	return REGV_POLL_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, AON, 0, 100);72}73 74static void host_ss_rst_clr(struct ivpu_device *vdev)75{76	u32 val = 0;77 78	val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, TOP_NOC, val);79	val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, DSS_MAS, val);80	val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, MSS_MAS, val);81 82	REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_CLR, val);83}84 85static int host_ss_noc_qreqn_check_37xx(struct ivpu_device *vdev, u32 exp_val)86{87	u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);88 89	if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))90		return -EIO;91 92	return 0;93}94 95static int host_ss_noc_qreqn_check_40xx(struct ivpu_device *vdev, u32 exp_val)96{97	u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);98 99	if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))100		return -EIO;101 102	return 0;103}104 105static int host_ss_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)106{107	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)108		return host_ss_noc_qreqn_check_37xx(vdev, exp_val);109	else110		return host_ss_noc_qreqn_check_40xx(vdev, exp_val);111}112 113static int host_ss_noc_qacceptn_check_37xx(struct ivpu_device *vdev, u32 exp_val)114{115	u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QACCEPTN);116 117	if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))118		return -EIO;119 120	return 0;121}122 123static int host_ss_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)124{125	u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QACCEPTN);126 127	if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))128		return -EIO;129 130	return 0;131}132 133static int host_ss_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)134{135	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)136		return host_ss_noc_qacceptn_check_37xx(vdev, exp_val);137	else138		return host_ss_noc_qacceptn_check_40xx(vdev, exp_val);139}140 141static int host_ss_noc_qdeny_check_37xx(struct ivpu_device *vdev, u32 exp_val)142{143	u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QDENY);144 145	if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))146		return -EIO;147 148	return 0;149}150 151static int host_ss_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)152{153	u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QDENY);154 155	if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))156		return -EIO;157 158	return 0;159}160 161static int host_ss_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)162{163	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)164		return host_ss_noc_qdeny_check_37xx(vdev, exp_val);165	else166		return host_ss_noc_qdeny_check_40xx(vdev, exp_val);167}168 169static int top_noc_qrenqn_check_37xx(struct ivpu_device *vdev, u32 exp_val)170{171	u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);172 173	if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||174	    !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))175		return -EIO;176 177	return 0;178}179 180static int top_noc_qrenqn_check_40xx(struct ivpu_device *vdev, u32 exp_val)181{182	u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);183 184	if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||185	    !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))186		return -EIO;187 188	return 0;189}190 191static int top_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)192{193	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)194		return top_noc_qrenqn_check_37xx(vdev, exp_val);195	else196		return top_noc_qrenqn_check_40xx(vdev, exp_val);197}198 199int ivpu_hw_ip_host_ss_configure(struct ivpu_device *vdev)200{201	int ret;202 203	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {204		ret = wait_for_ip_bar(vdev);205		if (ret) {206			ivpu_err(vdev, "Timed out waiting for NPU IP bar\n");207			return ret;208		}209		host_ss_rst_clr(vdev);210	}211 212	ret = host_ss_noc_qreqn_check(vdev, 0x0);213	if (ret) {214		ivpu_err(vdev, "Failed qreqn check: %d\n", ret);215		return ret;216	}217 218	ret = host_ss_noc_qacceptn_check(vdev, 0x0);219	if (ret) {220		ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);221		return ret;222	}223 224	ret = host_ss_noc_qdeny_check(vdev, 0x0);225	if (ret)226		ivpu_err(vdev, "Failed qdeny check %d\n", ret);227 228	return ret;229}230 231static void idle_gen_drive_37xx(struct ivpu_device *vdev, bool enable)232{233	u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN);234 235	if (enable)236		val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, EN, val);237	else238		val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, EN, val);239 240	REGV_WR32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, val);241}242 243static void idle_gen_drive_40xx(struct ivpu_device *vdev, bool enable)244{245	u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_IDLE_GEN);246 247	if (enable)248		val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);249	else250		val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);251 252	REGV_WR32(VPU_40XX_HOST_SS_AON_IDLE_GEN, val);253}254 255void ivpu_hw_ip_idle_gen_enable(struct ivpu_device *vdev)256{257	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)258		idle_gen_drive_37xx(vdev, true);259	else260		idle_gen_drive_40xx(vdev, true);261}262 263void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev)264{265	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)266		idle_gen_drive_37xx(vdev, false);267	else268		idle_gen_drive_40xx(vdev, false);269}270 271static void pwr_island_delay_set_50xx(struct ivpu_device *vdev)272{273	u32 val, post, status;274 275	if (vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_DEFAULT) {276		post = PWR_ISLAND_EN_POST_DLY_FREQ_DEFAULT;277		status = PWR_ISLAND_STATUS_DLY_FREQ_DEFAULT;278	} else {279		post = PWR_ISLAND_EN_POST_DLY_FREQ_HIGH;280		status = PWR_ISLAND_STATUS_DLY_FREQ_HIGH;281	}282 283	val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY);284	val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST_DLY, post, val);285	REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, val);286 287	val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY);288	val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY, STATUS_DLY, status, val);289	REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY, val);290}291 292static void pwr_island_trickle_drive_37xx(struct ivpu_device *vdev, bool enable)293{294	u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);295 296	if (enable)297		val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);298	else299		val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);300 301	REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);302}303 304static void pwr_island_trickle_drive_40xx(struct ivpu_device *vdev, bool enable)305{306	u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);307 308	if (enable)309		val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);310	else311		val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);312 313	REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);314 315	if (enable)316		ndelay(500);317}318 319static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable)320{321	u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0);322 323	if (enable)324		val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);325	else326		val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);327 328	REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, val);329 330	if (!enable)331		ndelay(500);332}333 334static void pwr_island_drive_40xx(struct ivpu_device *vdev, bool enable)335{336	u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0);337 338	if (enable)339		val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);340	else341		val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);342 343	REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, val);344}345 346static void pwr_island_enable(struct ivpu_device *vdev)347{348	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {349		pwr_island_trickle_drive_37xx(vdev, true);350		pwr_island_drive_37xx(vdev, true);351	} else {352		pwr_island_trickle_drive_40xx(vdev, true);353		pwr_island_drive_40xx(vdev, true);354	}355}356 357static int wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val)358{359	if (IVPU_WA(punit_disabled))360		return 0;361 362	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)363		return REGV_POLL_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_STATUS0, MSS_CPU, exp_val,364				     PWR_ISLAND_STATUS_TIMEOUT_US);365	else366		return REGV_POLL_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_STATUS0, CSS_CPU, exp_val,367				     PWR_ISLAND_STATUS_TIMEOUT_US);368}369 370static void pwr_island_isolation_drive_37xx(struct ivpu_device *vdev, bool enable)371{372	u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0);373 374	if (enable)375		val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);376	else377		val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);378 379	REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, val);380}381 382static void pwr_island_isolation_drive_40xx(struct ivpu_device *vdev, bool enable)383{384	u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0);385 386	if (enable)387		val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);388	else389		val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);390 391	REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, val);392}393 394static void pwr_island_isolation_drive(struct ivpu_device *vdev, bool enable)395{396	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)397		pwr_island_isolation_drive_37xx(vdev, enable);398	else399		pwr_island_isolation_drive_40xx(vdev, enable);400}401 402static void pwr_island_isolation_disable(struct ivpu_device *vdev)403{404	pwr_island_isolation_drive(vdev, false);405}406 407static void host_ss_clk_drive_37xx(struct ivpu_device *vdev, bool enable)408{409	u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_CLK_SET);410 411	if (enable) {412		val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);413		val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);414		val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);415	} else {416		val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);417		val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);418		val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);419	}420 421	REGV_WR32(VPU_37XX_HOST_SS_CPR_CLK_SET, val);422}423 424static void host_ss_clk_drive_40xx(struct ivpu_device *vdev, bool enable)425{426	u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_CLK_EN);427 428	if (enable) {429		val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);430		val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);431		val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);432	} else {433		val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);434		val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);435		val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);436	}437 438	REGV_WR32(VPU_40XX_HOST_SS_CPR_CLK_EN, val);439}440 441static void host_ss_clk_drive(struct ivpu_device *vdev, bool enable)442{443	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)444		host_ss_clk_drive_37xx(vdev, enable);445	else446		host_ss_clk_drive_40xx(vdev, enable);447}448 449static void host_ss_clk_enable(struct ivpu_device *vdev)450{451	host_ss_clk_drive(vdev, true);452}453 454static void host_ss_rst_drive_37xx(struct ivpu_device *vdev, bool enable)455{456	u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_RST_SET);457 458	if (enable) {459		val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);460		val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);461		val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);462	} else {463		val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);464		val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);465		val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);466	}467 468	REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_SET, val);469}470 471static void host_ss_rst_drive_40xx(struct ivpu_device *vdev, bool enable)472{473	u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_RST_EN);474 475	if (enable) {476		val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);477		val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);478		val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);479	} else {480		val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);481		val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);482		val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);483	}484 485	REGV_WR32(VPU_40XX_HOST_SS_CPR_RST_EN, val);486}487 488static void host_ss_rst_drive(struct ivpu_device *vdev, bool enable)489{490	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)491		host_ss_rst_drive_37xx(vdev, enable);492	else493		host_ss_rst_drive_40xx(vdev, enable);494}495 496static void host_ss_rst_enable(struct ivpu_device *vdev)497{498	host_ss_rst_drive(vdev, true);499}500 501static void host_ss_noc_qreqn_top_socmmio_drive_37xx(struct ivpu_device *vdev, bool enable)502{503	u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);504 505	if (enable)506		val = REG_SET_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);507	else508		val = REG_CLR_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);509	REGV_WR32(VPU_37XX_HOST_SS_NOC_QREQN, val);510}511 512static void host_ss_noc_qreqn_top_socmmio_drive_40xx(struct ivpu_device *vdev, bool enable)513{514	u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);515 516	if (enable)517		val = REG_SET_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);518	else519		val = REG_CLR_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);520	REGV_WR32(VPU_40XX_HOST_SS_NOC_QREQN, val);521}522 523static void host_ss_noc_qreqn_top_socmmio_drive(struct ivpu_device *vdev, bool enable)524{525	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)526		host_ss_noc_qreqn_top_socmmio_drive_37xx(vdev, enable);527	else528		host_ss_noc_qreqn_top_socmmio_drive_40xx(vdev, enable);529}530 531static int host_ss_axi_drive(struct ivpu_device *vdev, bool enable)532{533	int ret;534 535	host_ss_noc_qreqn_top_socmmio_drive(vdev, enable);536 537	ret = host_ss_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);538	if (ret) {539		ivpu_err(vdev, "Failed HOST SS NOC QACCEPTN check: %d\n", ret);540		return ret;541	}542 543	ret = host_ss_noc_qdeny_check(vdev, 0x0);544	if (ret)545		ivpu_err(vdev, "Failed HOST SS NOC QDENY check: %d\n", ret);546 547	return ret;548}549 550static void top_noc_qreqn_drive_40xx(struct ivpu_device *vdev, bool enable)551{552	u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);553 554	if (enable) {555		val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);556		val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);557	} else {558		val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);559		val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);560	}561 562	REGV_WR32(VPU_40XX_TOP_NOC_QREQN, val);563}564 565static void top_noc_qreqn_drive_37xx(struct ivpu_device *vdev, bool enable)566{567	u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);568 569	if (enable) {570		val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);571		val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);572	} else {573		val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);574		val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);575	}576 577	REGV_WR32(VPU_37XX_TOP_NOC_QREQN, val);578}579 580static void top_noc_qreqn_drive(struct ivpu_device *vdev, bool enable)581{582	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)583		top_noc_qreqn_drive_37xx(vdev, enable);584	else585		top_noc_qreqn_drive_40xx(vdev, enable);586}587 588int ivpu_hw_ip_host_ss_axi_enable(struct ivpu_device *vdev)589{590	return host_ss_axi_drive(vdev, true);591}592 593static int top_noc_qacceptn_check_37xx(struct ivpu_device *vdev, u32 exp_val)594{595	u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QACCEPTN);596 597	if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||598	    !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))599		return -EIO;600 601	return 0;602}603 604static int top_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)605{606	u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QACCEPTN);607 608	if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||609	    !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))610		return -EIO;611 612	return 0;613}614 615static int top_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)616{617	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)618		return top_noc_qacceptn_check_37xx(vdev, exp_val);619	else620		return top_noc_qacceptn_check_40xx(vdev, exp_val);621}622 623static int top_noc_qdeny_check_37xx(struct ivpu_device *vdev, u32 exp_val)624{625	u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QDENY);626 627	if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||628	    !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))629		return -EIO;630 631	return 0;632}633 634static int top_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)635{636	u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QDENY);637 638	if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||639	    !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))640		return -EIO;641 642	return 0;643}644 645static int top_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)646{647	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)648		return top_noc_qdeny_check_37xx(vdev, exp_val);649	else650		return top_noc_qdeny_check_40xx(vdev, exp_val);651}652 653static int top_noc_drive(struct ivpu_device *vdev, bool enable)654{655	int ret;656 657	top_noc_qreqn_drive(vdev, enable);658 659	ret = top_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);660	if (ret) {661		ivpu_err(vdev, "Failed TOP NOC QACCEPTN check: %d\n", ret);662		return ret;663	}664 665	ret = top_noc_qdeny_check(vdev, 0x0);666	if (ret)667		ivpu_err(vdev, "Failed TOP NOC QDENY check: %d\n", ret);668 669	return ret;670}671 672int ivpu_hw_ip_top_noc_enable(struct ivpu_device *vdev)673{674	return top_noc_drive(vdev, true);675}676 677static void dpu_active_drive_37xx(struct ivpu_device *vdev, bool enable)678{679	u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE);680 681	if (enable)682		val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);683	else684		val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);685 686	REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val);687}688 689int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev)690{691	int ret;692 693	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_50XX)694		pwr_island_delay_set_50xx(vdev);695 696	pwr_island_enable(vdev);697 698	ret = wait_for_pwr_island_status(vdev, 0x1);699	if (ret) {700		ivpu_err(vdev, "Timed out waiting for power island status\n");701		return ret;702	}703 704	ret = top_noc_qreqn_check(vdev, 0x0);705	if (ret) {706		ivpu_err(vdev, "Failed TOP NOC QREQN check %d\n", ret);707		return ret;708	}709 710	host_ss_clk_enable(vdev);711	pwr_island_isolation_disable(vdev);712	host_ss_rst_enable(vdev);713 714	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)715		dpu_active_drive_37xx(vdev, true);716 717	return ret;718}719 720u64 ivpu_hw_ip_read_perf_timer_counter(struct ivpu_device *vdev)721{722	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)723		return REGV_RD64(VPU_37XX_CPU_SS_TIM_PERF_FREE_CNT);724	else725		return REGV_RD64(VPU_40XX_CPU_SS_TIM_PERF_EXT_FREE_CNT);726}727 728static void ivpu_hw_ip_snoop_disable_37xx(struct ivpu_device *vdev)729{730	u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);731 732	val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val);733	val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val);734 735	if (ivpu_is_force_snoop_enabled(vdev))736		val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);737	else738		val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);739 740	REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val);741}742 743static void ivpu_hw_ip_snoop_disable_40xx(struct ivpu_device *vdev)744{745	u32 val = REGV_RD32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES);746 747	val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, SNOOP_OVERRIDE_EN, val);748	val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, val);749 750	if (ivpu_is_force_snoop_enabled(vdev))751		val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);752	else753		val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);754 755	REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val);756}757 758void ivpu_hw_ip_snoop_disable(struct ivpu_device *vdev)759{760	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)761		return ivpu_hw_ip_snoop_disable_37xx(vdev);762	else763		return ivpu_hw_ip_snoop_disable_40xx(vdev);764}765 766static void ivpu_hw_ip_tbu_mmu_enable_37xx(struct ivpu_device *vdev)767{768	u32 val = REGV_RD32(VPU_37XX_HOST_IF_TBU_MMUSSIDV);769 770	val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);771	val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);772	val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);773	val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);774 775	REGV_WR32(VPU_37XX_HOST_IF_TBU_MMUSSIDV, val);776}777 778static void ivpu_hw_ip_tbu_mmu_enable_40xx(struct ivpu_device *vdev)779{780	u32 val = REGV_RD32(VPU_40XX_HOST_IF_TBU_MMUSSIDV);781 782	val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);783	val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);784	val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_AWMMUSSIDV, val);785	val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_ARMMUSSIDV, val);786	val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);787	val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);788 789	REGV_WR32(VPU_40XX_HOST_IF_TBU_MMUSSIDV, val);790}791 792void ivpu_hw_ip_tbu_mmu_enable(struct ivpu_device *vdev)793{794	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)795		return ivpu_hw_ip_tbu_mmu_enable_37xx(vdev);796	else797		return ivpu_hw_ip_tbu_mmu_enable_40xx(vdev);798}799 800static int soc_cpu_boot_37xx(struct ivpu_device *vdev)801{802	u32 val;803 804	val = REGV_RD32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC);805	val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTRUN0, val);806 807	val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTVEC, val);808	REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);809 810	val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);811	REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);812 813	val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);814	REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);815 816	val = vdev->fw->entry_point >> 9;817	REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);818 819	val = REG_SET_FLD(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, DONE, val);820	REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);821 822	ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n",823		 vdev->fw->entry_point == vdev->fw->cold_boot_entry_point ? "cold boot" : "resume");824 825	return 0;826}827 828static int cpu_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)829{830	u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN);831 832	if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN, TOP_MMIO, exp_val, val))833		return -EIO;834 835	return 0;836}837 838static int cpu_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)839{840	u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QDENY);841 842	if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QDENY, TOP_MMIO, exp_val, val))843		return -EIO;844 845	return 0;846}847 848static void cpu_noc_top_mmio_drive_40xx(struct ivpu_device *vdev, bool enable)849{850	u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QREQN);851 852	if (enable)853		val = REG_SET_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);854	else855		val = REG_CLR_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);856	REGV_WR32(VPU_40XX_CPU_SS_CPR_NOC_QREQN, val);857}858 859static int soc_cpu_drive_40xx(struct ivpu_device *vdev, bool enable)860{861	int ret;862 863	cpu_noc_top_mmio_drive_40xx(vdev, enable);864 865	ret = cpu_noc_qacceptn_check_40xx(vdev, enable ? 0x1 : 0x0);866	if (ret) {867		ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);868		return ret;869	}870 871	ret = cpu_noc_qdeny_check_40xx(vdev, 0x0);872	if (ret)873		ivpu_err(vdev, "Failed qdeny check: %d\n", ret);874 875	return ret;876}877 878static int soc_cpu_enable(struct ivpu_device *vdev)879{880	return soc_cpu_drive_40xx(vdev, true);881}882 883static int soc_cpu_boot_40xx(struct ivpu_device *vdev)884{885	int ret;886	u32 val;887	u64 val64;888 889	ret = soc_cpu_enable(vdev);890	if (ret) {891		ivpu_err(vdev, "Failed to enable SOC CPU: %d\n", ret);892		return ret;893	}894 895	val64 = vdev->fw->entry_point;896	val64 <<= ffs(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO_IMAGE_LOCATION_MASK) - 1;897	REGV_WR64(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val64);898 899	val = REGV_RD32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO);900	val = REG_SET_FLD(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, DONE, val);901	REGV_WR32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val);902 903	ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n",904		 ivpu_fw_is_cold_boot(vdev) ? "cold boot" : "resume");905 906	return 0;907}908 909int ivpu_hw_ip_soc_cpu_boot(struct ivpu_device *vdev)910{911	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)912		return soc_cpu_boot_37xx(vdev);913	else914		return soc_cpu_boot_40xx(vdev);915}916 917static void wdt_disable_37xx(struct ivpu_device *vdev)918{919	u32 val;920 921	/* Enable writing and set non-zero WDT value */922	REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);923	REGV_WR32(VPU_37XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);924 925	/* Enable writing and disable watchdog timer */926	REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);927	REGV_WR32(VPU_37XX_CPU_SS_TIM_WDOG_EN, 0);928 929	/* Now clear the timeout interrupt */930	val = REGV_RD32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG);931	val = REG_CLR_FLD(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);932	REGV_WR32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, val);933}934 935static void wdt_disable_40xx(struct ivpu_device *vdev)936{937	u32 val;938 939	REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);940	REGV_WR32(VPU_40XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);941 942	REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);943	REGV_WR32(VPU_40XX_CPU_SS_TIM_WDOG_EN, 0);944 945	val = REGV_RD32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG);946	val = REG_CLR_FLD(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);947	REGV_WR32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, val);948}949 950void ivpu_hw_ip_wdt_disable(struct ivpu_device *vdev)951{952	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)953		return wdt_disable_37xx(vdev);954	else955		return wdt_disable_40xx(vdev);956}957 958static u32 ipc_rx_count_get_37xx(struct ivpu_device *vdev)959{960	u32 count = REGV_RD32_SILENT(VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT);961 962	return REG_GET_FLD(VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);963}964 965static u32 ipc_rx_count_get_40xx(struct ivpu_device *vdev)966{967	u32 count = REGV_RD32_SILENT(VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT);968 969	return REG_GET_FLD(VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);970}971 972u32 ivpu_hw_ip_ipc_rx_count_get(struct ivpu_device *vdev)973{974	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)975		return ipc_rx_count_get_37xx(vdev);976	else977		return ipc_rx_count_get_40xx(vdev);978}979 980void ivpu_hw_ip_irq_enable(struct ivpu_device *vdev)981{982	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {983		REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK_37XX);984		REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK_37XX);985	} else {986		REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK_40XX);987		REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK_40XX);988	}989}990 991void ivpu_hw_ip_irq_disable(struct ivpu_device *vdev)992{993	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {994		REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, 0x0ull);995		REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, 0x0);996	} else {997		REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, 0x0ull);998		REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, 0x0ul);999	}1000}1001 1002static void diagnose_failure_37xx(struct ivpu_device *vdev)1003{1004	u32 reg = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_37XX;1005 1006	if (ipc_rx_count_get_37xx(vdev))1007		ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");1008 1009	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, reg))1010		ivpu_err(vdev, "WDT MSS timeout detected\n");1011 1012	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, reg))1013		ivpu_err(vdev, "WDT NCE timeout detected\n");1014 1015	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, reg))1016		ivpu_err(vdev, "NOC Firewall irq detected\n");1017}1018 1019static void diagnose_failure_40xx(struct ivpu_device *vdev)1020{1021	u32 reg = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_40XX;1022 1023	if (ipc_rx_count_get_40xx(vdev))1024		ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");1025 1026	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, reg))1027		ivpu_err(vdev, "WDT MSS timeout detected\n");1028 1029	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, reg))1030		ivpu_err(vdev, "WDT NCE timeout detected\n");1031 1032	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, reg))1033		ivpu_err(vdev, "NOC Firewall irq detected\n");1034}1035 1036void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev)1037{1038	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)1039		diagnose_failure_37xx(vdev);1040	else1041		diagnose_failure_40xx(vdev);1042}1043 1044void ivpu_hw_ip_irq_clear(struct ivpu_device *vdev)1045{1046	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)1047		REGV_WR64(VPU_37XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK_37XX);1048	else1049		REGV_WR64(VPU_40XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK_40XX);1050}1051 1052static void irq_wdt_nce_handler(struct ivpu_device *vdev)1053{1054	ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ");1055}1056 1057static void irq_wdt_mss_handler(struct ivpu_device *vdev)1058{1059	ivpu_hw_ip_wdt_disable(vdev);1060	ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ");1061}1062 1063static void irq_noc_firewall_handler(struct ivpu_device *vdev)1064{1065	atomic_inc(&vdev->hw->firewall_irq_counter);1066 1067	ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n",1068		 atomic_read(&vdev->hw->firewall_irq_counter));1069}1070 1071/* Handler for IRQs from NPU core */1072bool ivpu_hw_ip_irq_handler_37xx(struct ivpu_device *vdev, int irq)1073{1074	u32 status = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_37XX;1075 1076	if (!status)1077		return false;1078 1079	REGV_WR32(VPU_37XX_HOST_SS_ICB_CLEAR_0, status);1080 1081	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))1082		ivpu_mmu_irq_evtq_handler(vdev);1083 1084	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))1085		ivpu_ipc_irq_handler(vdev);1086 1087	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))1088		ivpu_dbg(vdev, IRQ, "MMU sync complete\n");1089 1090	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))1091		ivpu_mmu_irq_gerr_handler(vdev);1092 1093	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))1094		irq_wdt_mss_handler(vdev);1095 1096	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))1097		irq_wdt_nce_handler(vdev);1098 1099	if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))1100		irq_noc_firewall_handler(vdev);1101 1102	return true;1103}1104 1105/* Handler for IRQs from NPU core */1106bool ivpu_hw_ip_irq_handler_40xx(struct ivpu_device *vdev, int irq)1107{1108	u32 status = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_40XX;1109 1110	if (!status)1111		return false;1112 1113	REGV_WR32(VPU_40XX_HOST_SS_ICB_CLEAR_0, status);1114 1115	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))1116		ivpu_mmu_irq_evtq_handler(vdev);1117 1118	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))1119		ivpu_ipc_irq_handler(vdev);1120 1121	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))1122		ivpu_dbg(vdev, IRQ, "MMU sync complete\n");1123 1124	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))1125		ivpu_mmu_irq_gerr_handler(vdev);1126 1127	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))1128		irq_wdt_mss_handler(vdev);1129 1130	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))1131		irq_wdt_nce_handler(vdev);1132 1133	if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))1134		irq_noc_firewall_handler(vdev);1135 1136	return true;1137}1138 1139static void db_set_37xx(struct ivpu_device *vdev, u32 db_id)1140{1141	u32 reg_stride = VPU_37XX_CPU_SS_DOORBELL_1 - VPU_37XX_CPU_SS_DOORBELL_0;1142	u32 val = REG_FLD(VPU_37XX_CPU_SS_DOORBELL_0, SET);1143 1144	REGV_WR32I(VPU_37XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);1145}1146 1147static void db_set_40xx(struct ivpu_device *vdev, u32 db_id)1148{1149	u32 reg_stride = VPU_40XX_CPU_SS_DOORBELL_1 - VPU_40XX_CPU_SS_DOORBELL_0;1150	u32 val = REG_FLD(VPU_40XX_CPU_SS_DOORBELL_0, SET);1151 1152	REGV_WR32I(VPU_40XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);1153}1154 1155void ivpu_hw_ip_db_set(struct ivpu_device *vdev, u32 db_id)1156{1157	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)1158		db_set_37xx(vdev, db_id);1159	else1160		db_set_40xx(vdev, db_id);1161}1162 1163u32 ivpu_hw_ip_ipc_rx_addr_get(struct ivpu_device *vdev)1164{1165	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)1166		return REGV_RD32(VPU_37XX_HOST_SS_TIM_IPC_FIFO_ATM);1167	else1168		return REGV_RD32(VPU_40XX_HOST_SS_TIM_IPC_FIFO_ATM);1169}1170 1171void ivpu_hw_ip_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)1172{1173	if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)1174		REGV_WR32(VPU_37XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);1175	else1176		REGV_WR32(VPU_40XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);1177}1178