| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226 |
- // SPDX-License-Identifier: GPL-2.0-only
- /*
- * Copyright (C) 2020-2024 Intel Corporation
- */
- #include "ivpu_drv.h"
- #include "ivpu_fw.h"
- #include "ivpu_gem.h"
- #include "ivpu_hw.h"
- #include "ivpu_hw_37xx_reg.h"
- #include "ivpu_hw_40xx_reg.h"
- #include "ivpu_hw_btrs.h"
- #include "ivpu_hw_ip.h"
- #include "ivpu_hw_reg_io.h"
- #include "ivpu_mmu.h"
- #include "ivpu_pm.h"
- #define PWR_ISLAND_STATUS_TIMEOUT_US (5 * USEC_PER_MSEC)
- #define TIM_SAFE_ENABLE 0xf1d0dead
- #define TIM_WATCHDOG_RESET_VALUE 0xffffffff
- #define ICB_0_IRQ_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
- #define ICB_1_IRQ_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
- (REG_FLD(VPU_37XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
- #define ICB_0_1_IRQ_MASK_37XX ((((u64)ICB_1_IRQ_MASK_37XX) << 32) | ICB_0_IRQ_MASK_37XX)
- #define ICB_0_IRQ_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT)))
- #define ICB_1_IRQ_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_2_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_3_INT)) | \
- (REG_FLD(VPU_40XX_HOST_SS_ICB_STATUS_1, CPU_INT_REDIRECT_4_INT)))
- #define ICB_0_1_IRQ_MASK_40XX ((((u64)ICB_1_IRQ_MASK_40XX) << 32) | ICB_0_IRQ_MASK_40XX)
- #define ITF_FIREWALL_VIOLATION_MASK_37XX ((REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
- (REG_FLD(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
- #define ITF_FIREWALL_VIOLATION_MASK_40XX ((REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_ROM_CMX)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_DBG)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, CSS_CTRL)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, DEC400)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_NCE)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI)) | \
- (REG_FLD(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, MSS_MBI_CMX)))
- static int wait_for_ip_bar(struct ivpu_device *vdev)
- {
- return REGV_POLL_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, AON, 0, 100);
- }
- static void host_ss_rst_clr(struct ivpu_device *vdev)
- {
- u32 val = 0;
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, TOP_NOC, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, DSS_MAS, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_CLR, MSS_MAS, val);
- REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_CLR, val);
- }
- static int host_ss_noc_qreqn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);
- if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
- return -EIO;
- return 0;
- }
- static int host_ss_noc_qreqn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);
- if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, exp_val, val))
- return -EIO;
- return 0;
- }
- static int host_ss_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return host_ss_noc_qreqn_check_37xx(vdev, exp_val);
- else
- return host_ss_noc_qreqn_check_40xx(vdev, exp_val);
- }
- static int host_ss_noc_qacceptn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QACCEPTN);
- if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
- return -EIO;
- return 0;
- }
- static int host_ss_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QACCEPTN);
- if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QACCEPTN, TOP_SOCMMIO, exp_val, val))
- return -EIO;
- return 0;
- }
- static int host_ss_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return host_ss_noc_qacceptn_check_37xx(vdev, exp_val);
- else
- return host_ss_noc_qacceptn_check_40xx(vdev, exp_val);
- }
- static int host_ss_noc_qdeny_check_37xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QDENY);
- if (!REG_TEST_FLD_NUM(VPU_37XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
- return -EIO;
- return 0;
- }
- static int host_ss_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QDENY);
- if (!REG_TEST_FLD_NUM(VPU_40XX_HOST_SS_NOC_QDENY, TOP_SOCMMIO, exp_val, val))
- return -EIO;
- return 0;
- }
- static int host_ss_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return host_ss_noc_qdeny_check_37xx(vdev, exp_val);
- else
- return host_ss_noc_qdeny_check_40xx(vdev, exp_val);
- }
- static int top_noc_qrenqn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);
- if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
- return 0;
- }
- static int top_noc_qrenqn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);
- if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
- return 0;
- }
- static int top_noc_qreqn_check(struct ivpu_device *vdev, u32 exp_val)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return top_noc_qrenqn_check_37xx(vdev, exp_val);
- else
- return top_noc_qrenqn_check_40xx(vdev, exp_val);
- }
- int ivpu_hw_ip_host_ss_configure(struct ivpu_device *vdev)
- {
- int ret;
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
- ret = wait_for_ip_bar(vdev);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for NPU IP bar\n");
- return ret;
- }
- host_ss_rst_clr(vdev);
- }
- ret = host_ss_noc_qreqn_check(vdev, 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qreqn check: %d\n", ret);
- return ret;
- }
- ret = host_ss_noc_qacceptn_check(vdev, 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
- return ret;
- }
- ret = host_ss_noc_qdeny_check(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed qdeny check %d\n", ret);
- return ret;
- }
- static void idle_gen_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN);
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, EN, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, EN, val);
- REGV_WR32(VPU_37XX_HOST_SS_AON_VPU_IDLE_GEN, val);
- }
- static void idle_gen_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_IDLE_GEN);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_IDLE_GEN, EN, val);
- REGV_WR32(VPU_40XX_HOST_SS_AON_IDLE_GEN, val);
- }
- void ivpu_hw_ip_idle_gen_enable(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- idle_gen_drive_37xx(vdev, true);
- else
- idle_gen_drive_40xx(vdev, true);
- }
- void ivpu_hw_ip_idle_gen_disable(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- idle_gen_drive_37xx(vdev, false);
- else
- idle_gen_drive_40xx(vdev, false);
- }
- static void
- pwr_island_delay_set_50xx(struct ivpu_device *vdev, u32 post, u32 post1, u32 post2, u32 status)
- {
- u32 val;
- val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY);
- val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST_DLY, post, val);
- val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST1_DLY, post1, val);
- val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, POST2_DLY, post2, val);
- REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_EN_POST_DLY, val);
- val = REGV_RD32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY);
- val = REG_SET_FLD_NUM(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY, STATUS_DLY, status, val);
- REGV_WR32(VPU_50XX_HOST_SS_AON_PWR_ISLAND_STATUS_DLY, val);
- }
- static void pwr_island_trickle_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, MSS_CPU, val);
- REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
- }
- static void pwr_island_trickle_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, CSS_CPU, val);
- REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_TRICKLE_EN0, val);
- }
- static void pwr_island_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, CSS_CPU, val);
- REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISLAND_EN0, val);
- }
- static void pwr_island_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0);
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, MSS_CPU, val);
- REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISLAND_EN0, val);
- }
- static void pwr_island_enable(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
- pwr_island_trickle_drive_37xx(vdev, true);
- ndelay(500);
- pwr_island_drive_37xx(vdev, true);
- } else {
- pwr_island_trickle_drive_40xx(vdev, true);
- ndelay(500);
- pwr_island_drive_40xx(vdev, true);
- }
- }
- static int wait_for_pwr_island_status(struct ivpu_device *vdev, u32 exp_val)
- {
- if (IVPU_WA(punit_disabled))
- return 0;
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return REGV_POLL_FLD(VPU_37XX_HOST_SS_AON_PWR_ISLAND_STATUS0, MSS_CPU, exp_val,
- PWR_ISLAND_STATUS_TIMEOUT_US);
- else
- return REGV_POLL_FLD(VPU_40XX_HOST_SS_AON_PWR_ISLAND_STATUS0, CSS_CPU, exp_val,
- PWR_ISLAND_STATUS_TIMEOUT_US);
- }
- static void pwr_island_isolation_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0);
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, MSS_CPU, val);
- REGV_WR32(VPU_37XX_HOST_SS_AON_PWR_ISO_EN0, val);
- }
- static void pwr_island_isolation_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, CSS_CPU, val);
- REGV_WR32(VPU_40XX_HOST_SS_AON_PWR_ISO_EN0, val);
- }
- static void pwr_island_isolation_drive(struct ivpu_device *vdev, bool enable)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- pwr_island_isolation_drive_37xx(vdev, enable);
- else
- pwr_island_isolation_drive_40xx(vdev, enable);
- }
- static void pwr_island_isolation_disable(struct ivpu_device *vdev)
- {
- pwr_island_isolation_drive(vdev, false);
- }
- static void host_ss_clk_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_CLK_SET);
- if (enable) {
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
- } else {
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, TOP_NOC, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, DSS_MAS, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_CLK_SET, MSS_MAS, val);
- }
- REGV_WR32(VPU_37XX_HOST_SS_CPR_CLK_SET, val);
- }
- static void host_ss_clk_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_CLK_EN);
- if (enable) {
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);
- } else {
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, TOP_NOC, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, DSS_MAS, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_CLK_EN, CSS_MAS, val);
- }
- REGV_WR32(VPU_40XX_HOST_SS_CPR_CLK_EN, val);
- }
- static void host_ss_clk_drive(struct ivpu_device *vdev, bool enable)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- host_ss_clk_drive_37xx(vdev, enable);
- else
- host_ss_clk_drive_40xx(vdev, enable);
- }
- static void host_ss_clk_enable(struct ivpu_device *vdev)
- {
- host_ss_clk_drive(vdev, true);
- }
- static void host_ss_rst_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_CPR_RST_SET);
- if (enable) {
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);
- } else {
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, TOP_NOC, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, DSS_MAS, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_CPR_RST_SET, MSS_MAS, val);
- }
- REGV_WR32(VPU_37XX_HOST_SS_CPR_RST_SET, val);
- }
- static void host_ss_rst_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_CPR_RST_EN);
- if (enable) {
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);
- } else {
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, TOP_NOC, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, DSS_MAS, val);
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_CPR_RST_EN, CSS_MAS, val);
- }
- REGV_WR32(VPU_40XX_HOST_SS_CPR_RST_EN, val);
- }
- static void host_ss_rst_drive(struct ivpu_device *vdev, bool enable)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- host_ss_rst_drive_37xx(vdev, enable);
- else
- host_ss_rst_drive_40xx(vdev, enable);
- }
- static void host_ss_rst_enable(struct ivpu_device *vdev)
- {
- host_ss_rst_drive(vdev, true);
- }
- static void host_ss_noc_qreqn_top_socmmio_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_NOC_QREQN);
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
- REGV_WR32(VPU_37XX_HOST_SS_NOC_QREQN, val);
- }
- static void host_ss_noc_qreqn_top_socmmio_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_SS_NOC_QREQN);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_SS_NOC_QREQN, TOP_SOCMMIO, val);
- REGV_WR32(VPU_40XX_HOST_SS_NOC_QREQN, val);
- }
- static void host_ss_noc_qreqn_top_socmmio_drive(struct ivpu_device *vdev, bool enable)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- host_ss_noc_qreqn_top_socmmio_drive_37xx(vdev, enable);
- else
- host_ss_noc_qreqn_top_socmmio_drive_40xx(vdev, enable);
- }
- static int host_ss_axi_drive(struct ivpu_device *vdev, bool enable)
- {
- int ret;
- host_ss_noc_qreqn_top_socmmio_drive(vdev, enable);
- ret = host_ss_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed HOST SS NOC QACCEPTN check: %d\n", ret);
- return ret;
- }
- ret = host_ss_noc_qdeny_check(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed HOST SS NOC QDENY check: %d\n", ret);
- return ret;
- }
- static void top_noc_qreqn_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QREQN);
- if (enable) {
- val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);
- val = REG_SET_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
- } else {
- val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, CPU_CTRL, val);
- val = REG_CLR_FLD(VPU_40XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
- }
- REGV_WR32(VPU_40XX_TOP_NOC_QREQN, val);
- }
- static void top_noc_qreqn_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QREQN);
- if (enable) {
- val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);
- val = REG_SET_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
- } else {
- val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, CPU_CTRL, val);
- val = REG_CLR_FLD(VPU_37XX_TOP_NOC_QREQN, HOSTIF_L2CACHE, val);
- }
- REGV_WR32(VPU_37XX_TOP_NOC_QREQN, val);
- }
- static void top_noc_qreqn_drive(struct ivpu_device *vdev, bool enable)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- top_noc_qreqn_drive_37xx(vdev, enable);
- else
- top_noc_qreqn_drive_40xx(vdev, enable);
- }
- int ivpu_hw_ip_host_ss_axi_enable(struct ivpu_device *vdev)
- {
- return host_ss_axi_drive(vdev, true);
- }
- static int top_noc_qacceptn_check_37xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QACCEPTN);
- if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
- return 0;
- }
- static int top_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QACCEPTN);
- if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QACCEPTN, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
- return 0;
- }
- static int top_noc_qacceptn_check(struct ivpu_device *vdev, u32 exp_val)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return top_noc_qacceptn_check_37xx(vdev, exp_val);
- else
- return top_noc_qacceptn_check_40xx(vdev, exp_val);
- }
- static int top_noc_qdeny_check_37xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_37XX_TOP_NOC_QDENY);
- if (!REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_37XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
- return 0;
- }
- static int top_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_40XX_TOP_NOC_QDENY);
- if (!REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, CPU_CTRL, exp_val, val) ||
- !REG_TEST_FLD_NUM(VPU_40XX_TOP_NOC_QDENY, HOSTIF_L2CACHE, exp_val, val))
- return -EIO;
- return 0;
- }
- static int top_noc_qdeny_check(struct ivpu_device *vdev, u32 exp_val)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return top_noc_qdeny_check_37xx(vdev, exp_val);
- else
- return top_noc_qdeny_check_40xx(vdev, exp_val);
- }
- static int top_noc_drive(struct ivpu_device *vdev, bool enable)
- {
- int ret;
- top_noc_qreqn_drive(vdev, enable);
- ret = top_noc_qacceptn_check(vdev, enable ? 0x1 : 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed TOP NOC QACCEPTN check: %d\n", ret);
- return ret;
- }
- ret = top_noc_qdeny_check(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed TOP NOC QDENY check: %d\n", ret);
- return ret;
- }
- int ivpu_hw_ip_top_noc_enable(struct ivpu_device *vdev)
- {
- return top_noc_drive(vdev, true);
- }
- static void dpu_active_drive_37xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE);
- if (enable)
- val = REG_SET_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
- else
- val = REG_CLR_FLD(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, DPU_ACTIVE, val);
- REGV_WR32(VPU_37XX_HOST_SS_AON_DPU_ACTIVE, val);
- }
- static void pwr_island_delay_set(struct ivpu_device *vdev)
- {
- bool high = vdev->hw->pll.profiling_freq == PLL_PROFILING_FREQ_HIGH;
- u32 post, post1, post2, status;
- if (ivpu_hw_ip_gen(vdev) < IVPU_HW_IP_50XX)
- return;
- switch (ivpu_device_id(vdev)) {
- case PCI_DEVICE_ID_WCL:
- case PCI_DEVICE_ID_PTL_P:
- post = high ? 18 : 0;
- post1 = 0;
- post2 = 0;
- status = high ? 46 : 3;
- break;
- case PCI_DEVICE_ID_NVL:
- post = high ? 198 : 17;
- post1 = 0;
- post2 = high ? 198 : 17;
- status = 0;
- break;
- default:
- dump_stack();
- ivpu_err(vdev, "Unknown device ID\n");
- return;
- }
- pwr_island_delay_set_50xx(vdev, post, post1, post2, status);
- }
- int ivpu_hw_ip_pwr_domain_enable(struct ivpu_device *vdev)
- {
- int ret;
- pwr_island_delay_set(vdev);
- pwr_island_enable(vdev);
- ret = wait_for_pwr_island_status(vdev, 0x1);
- if (ret) {
- ivpu_err(vdev, "Timed out waiting for power island status\n");
- return ret;
- }
- ret = top_noc_qreqn_check(vdev, 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed TOP NOC QREQN check %d\n", ret);
- return ret;
- }
- host_ss_clk_enable(vdev);
- pwr_island_isolation_disable(vdev);
- host_ss_rst_enable(vdev);
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- dpu_active_drive_37xx(vdev, true);
- return ret;
- }
- u64 ivpu_hw_ip_read_perf_timer_counter(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return REGV_RD64(VPU_37XX_CPU_SS_TIM_PERF_FREE_CNT);
- else
- return REGV_RD64(VPU_40XX_CPU_SS_TIM_PERF_EXT_FREE_CNT);
- }
- static void ivpu_hw_ip_snoop_disable_37xx(struct ivpu_device *vdev)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, NOSNOOP_OVERRIDE_EN, val);
- val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AW_NOSNOOP_OVERRIDE, val);
- if (ivpu_is_force_snoop_enabled(vdev))
- val = REG_CLR_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
- else
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, AR_NOSNOOP_OVERRIDE, val);
- REGV_WR32(VPU_37XX_HOST_IF_TCU_PTW_OVERRIDES, val);
- }
- static void ivpu_hw_ip_snoop_disable_40xx(struct ivpu_device *vdev)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, SNOOP_OVERRIDE_EN, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AW_SNOOP_OVERRIDE, val);
- if (ivpu_is_force_snoop_enabled(vdev))
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
- else
- val = REG_CLR_FLD(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, AR_SNOOP_OVERRIDE, val);
- REGV_WR32(VPU_40XX_HOST_IF_TCU_PTW_OVERRIDES, val);
- }
- void ivpu_hw_ip_snoop_disable(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return ivpu_hw_ip_snoop_disable_37xx(vdev);
- else
- return ivpu_hw_ip_snoop_disable_40xx(vdev);
- }
- static void ivpu_hw_ip_tbu_mmu_enable_37xx(struct ivpu_device *vdev)
- {
- u32 val = REGV_RD32(VPU_37XX_HOST_IF_TBU_MMUSSIDV);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_37XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
- REGV_WR32(VPU_37XX_HOST_IF_TBU_MMUSSIDV, val);
- }
- static void ivpu_hw_ip_tbu_mmu_enable_40xx(struct ivpu_device *vdev)
- {
- u32 val = REGV_RD32(VPU_40XX_HOST_IF_TBU_MMUSSIDV);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU0_ARMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU1_ARMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_AWMMUSSIDV, val);
- val = REG_SET_FLD(VPU_40XX_HOST_IF_TBU_MMUSSIDV, TBU2_ARMMUSSIDV, val);
- REGV_WR32(VPU_40XX_HOST_IF_TBU_MMUSSIDV, val);
- }
- void ivpu_hw_ip_tbu_mmu_enable(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return ivpu_hw_ip_tbu_mmu_enable_37xx(vdev);
- else
- return ivpu_hw_ip_tbu_mmu_enable_40xx(vdev);
- }
- static inline u64 get_entry_point_addr(struct ivpu_device *vdev)
- {
- if (ivpu_fw_is_warm_boot(vdev))
- return vdev->fw->warm_boot_entry_point;
- else
- return vdev->fw->cold_boot_entry_point;
- }
- static int soc_cpu_boot_37xx(struct ivpu_device *vdev)
- {
- u32 val;
- val = REGV_RD32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC);
- val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTRUN0, val);
- val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RSTVEC, val);
- REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
- val = REG_SET_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
- REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
- val = REG_CLR_FLD(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, IRQI_RESUME0, val);
- REGV_WR32(VPU_37XX_CPU_SS_MSSCPU_CPR_LEON_RT_VEC, val);
- val = get_entry_point_addr(vdev) >> 9;
- REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);
- val = REG_SET_FLD(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, DONE, val);
- REGV_WR32(VPU_37XX_HOST_SS_LOADING_ADDRESS_LO, val);
- return 0;
- }
- static int cpu_noc_qacceptn_check_40xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN);
- if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QACCEPTN, TOP_MMIO, exp_val, val))
- return -EIO;
- return 0;
- }
- static int cpu_noc_qdeny_check_40xx(struct ivpu_device *vdev, u32 exp_val)
- {
- u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QDENY);
- if (!REG_TEST_FLD_NUM(VPU_40XX_CPU_SS_CPR_NOC_QDENY, TOP_MMIO, exp_val, val))
- return -EIO;
- return 0;
- }
- static void cpu_noc_top_mmio_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- u32 val = REGV_RD32(VPU_40XX_CPU_SS_CPR_NOC_QREQN);
- if (enable)
- val = REG_SET_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);
- else
- val = REG_CLR_FLD(VPU_40XX_CPU_SS_CPR_NOC_QREQN, TOP_MMIO, val);
- REGV_WR32(VPU_40XX_CPU_SS_CPR_NOC_QREQN, val);
- }
- static int soc_cpu_drive_40xx(struct ivpu_device *vdev, bool enable)
- {
- int ret;
- cpu_noc_top_mmio_drive_40xx(vdev, enable);
- ret = cpu_noc_qacceptn_check_40xx(vdev, enable ? 0x1 : 0x0);
- if (ret) {
- ivpu_err(vdev, "Failed qacceptn check: %d\n", ret);
- return ret;
- }
- ret = cpu_noc_qdeny_check_40xx(vdev, 0x0);
- if (ret)
- ivpu_err(vdev, "Failed qdeny check: %d\n", ret);
- return ret;
- }
- static void soc_cpu_set_entry_point_40xx(struct ivpu_device *vdev, u64 entry_point)
- {
- u64 val64;
- u32 val;
- val64 = entry_point;
- val64 <<= ffs(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO_IMAGE_LOCATION_MASK) - 1;
- REGV_WR64(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val64);
- val = REGV_RD32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO);
- val = REG_SET_FLD(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, DONE, val);
- REGV_WR32(VPU_40XX_HOST_SS_VERIFICATION_ADDRESS_LO, val);
- }
- static int soc_cpu_boot_40xx(struct ivpu_device *vdev)
- {
- int ret;
- ret = soc_cpu_drive_40xx(vdev, true);
- if (ret) {
- ivpu_err(vdev, "Failed to enable SOC CPU: %d\n", ret);
- return ret;
- }
- soc_cpu_set_entry_point_40xx(vdev, get_entry_point_addr(vdev));
- return 0;
- }
- static int soc_cpu_boot_60xx(struct ivpu_device *vdev)
- {
- soc_cpu_set_entry_point_40xx(vdev, vdev->fw->cold_boot_entry_point);
- return 0;
- }
- int ivpu_hw_ip_soc_cpu_boot(struct ivpu_device *vdev)
- {
- int ret;
- switch (ivpu_hw_ip_gen(vdev)) {
- case IVPU_HW_IP_37XX:
- ret = soc_cpu_boot_37xx(vdev);
- break;
- case IVPU_HW_IP_40XX:
- case IVPU_HW_IP_50XX:
- ret = soc_cpu_boot_40xx(vdev);
- break;
- default:
- ret = soc_cpu_boot_60xx(vdev);
- }
- if (ret)
- return ret;
- ivpu_dbg(vdev, PM, "Booting firmware, mode: %s\n",
- ivpu_fw_is_warm_boot(vdev) ? "warm boot" : "cold boot");
- return 0;
- }
- static void wdt_disable_37xx(struct ivpu_device *vdev)
- {
- u32 val;
- /* Enable writing and set non-zero WDT value */
- REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
- REGV_WR32(VPU_37XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
- /* Enable writing and disable watchdog timer */
- REGV_WR32(VPU_37XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
- REGV_WR32(VPU_37XX_CPU_SS_TIM_WDOG_EN, 0);
- /* Now clear the timeout interrupt */
- val = REGV_RD32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG);
- val = REG_CLR_FLD(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
- REGV_WR32(VPU_37XX_CPU_SS_TIM_GEN_CONFIG, val);
- }
- static void wdt_disable_40xx(struct ivpu_device *vdev)
- {
- u32 val;
- REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
- REGV_WR32(VPU_40XX_CPU_SS_TIM_WATCHDOG, TIM_WATCHDOG_RESET_VALUE);
- REGV_WR32(VPU_40XX_CPU_SS_TIM_SAFE, TIM_SAFE_ENABLE);
- REGV_WR32(VPU_40XX_CPU_SS_TIM_WDOG_EN, 0);
- val = REGV_RD32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG);
- val = REG_CLR_FLD(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, WDOG_TO_INT_CLR, val);
- REGV_WR32(VPU_40XX_CPU_SS_TIM_GEN_CONFIG, val);
- }
- void ivpu_hw_ip_wdt_disable(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return wdt_disable_37xx(vdev);
- else
- return wdt_disable_40xx(vdev);
- }
- static u32 ipc_rx_count_get_37xx(struct ivpu_device *vdev)
- {
- u32 count = readl(vdev->regv + VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT);
- return REG_GET_FLD(VPU_37XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
- }
- static u32 ipc_rx_count_get_40xx(struct ivpu_device *vdev)
- {
- u32 count = readl(vdev->regv + VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT);
- return REG_GET_FLD(VPU_40XX_HOST_SS_TIM_IPC_FIFO_STAT, FILL_LEVEL, count);
- }
- u32 ivpu_hw_ip_ipc_rx_count_get(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return ipc_rx_count_get_37xx(vdev);
- else
- return ipc_rx_count_get_40xx(vdev);
- }
- void ivpu_hw_ip_irq_enable(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
- REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK_37XX);
- REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK_37XX);
- } else {
- REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, ITF_FIREWALL_VIOLATION_MASK_40XX);
- REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, ICB_0_1_IRQ_MASK_40XX);
- }
- }
- void ivpu_hw_ip_irq_disable(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX) {
- REGV_WR64(VPU_37XX_HOST_SS_ICB_ENABLE_0, 0x0ull);
- REGV_WR32(VPU_37XX_HOST_SS_FW_SOC_IRQ_EN, 0x0);
- } else {
- REGV_WR64(VPU_40XX_HOST_SS_ICB_ENABLE_0, 0x0ull);
- REGV_WR32(VPU_40XX_HOST_SS_FW_SOC_IRQ_EN, 0x0ul);
- }
- }
- static void diagnose_failure_37xx(struct ivpu_device *vdev)
- {
- u32 reg = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_37XX;
- if (ipc_rx_count_get_37xx(vdev))
- ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, reg))
- ivpu_err(vdev, "WDT MSS timeout detected\n");
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, reg))
- ivpu_err(vdev, "WDT NCE timeout detected\n");
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, reg))
- ivpu_err(vdev, "NOC Firewall irq detected\n");
- }
- static void diagnose_failure_40xx(struct ivpu_device *vdev)
- {
- u32 reg = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_40XX;
- if (ipc_rx_count_get_40xx(vdev))
- ivpu_err(vdev, "IPC FIFO queue not empty, missed IPC IRQ");
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, reg))
- ivpu_err(vdev, "WDT MSS timeout detected\n");
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, reg))
- ivpu_err(vdev, "WDT NCE timeout detected\n");
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, reg))
- ivpu_err(vdev, "NOC Firewall irq detected\n");
- }
- void ivpu_hw_ip_diagnose_failure(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- diagnose_failure_37xx(vdev);
- else
- diagnose_failure_40xx(vdev);
- }
- void ivpu_hw_ip_irq_clear(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- REGV_WR64(VPU_37XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK_37XX);
- else
- REGV_WR64(VPU_40XX_HOST_SS_ICB_CLEAR_0, ICB_0_1_IRQ_MASK_40XX);
- }
- static void irq_wdt_nce_handler(struct ivpu_device *vdev)
- {
- ivpu_pm_trigger_recovery(vdev, "WDT NCE IRQ");
- }
- static void irq_wdt_mss_handler(struct ivpu_device *vdev)
- {
- ivpu_hw_ip_wdt_disable(vdev);
- ivpu_pm_trigger_recovery(vdev, "WDT MSS IRQ");
- }
- static void irq_noc_firewall_handler(struct ivpu_device *vdev)
- {
- atomic_inc(&vdev->hw->firewall_irq_counter);
- ivpu_dbg(vdev, IRQ, "NOC Firewall interrupt detected, counter %d\n",
- atomic_read(&vdev->hw->firewall_irq_counter));
- }
- /* Handler for IRQs from NPU core */
- bool ivpu_hw_ip_irq_handler_37xx(struct ivpu_device *vdev, int irq)
- {
- u32 status = REGV_RD32(VPU_37XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_37XX;
- if (!status)
- return false;
- REGV_WR32(VPU_37XX_HOST_SS_ICB_CLEAR_0, status);
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
- ivpu_mmu_irq_evtq_handler(vdev);
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
- ivpu_ipc_irq_handler(vdev);
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
- ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))
- ivpu_mmu_irq_gerr_handler(vdev);
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
- irq_wdt_mss_handler(vdev);
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
- irq_wdt_nce_handler(vdev);
- if (REG_TEST_FLD(VPU_37XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
- irq_noc_firewall_handler(vdev);
- return true;
- }
- /* Handler for IRQs from NPU core */
- bool ivpu_hw_ip_irq_handler_40xx(struct ivpu_device *vdev, int irq)
- {
- u32 status = REGV_RD32(VPU_40XX_HOST_SS_ICB_STATUS_0) & ICB_0_IRQ_MASK_40XX;
- if (!status)
- return false;
- REGV_WR32(VPU_40XX_HOST_SS_ICB_CLEAR_0, status);
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_0_INT, status))
- ivpu_mmu_irq_evtq_handler(vdev);
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, HOST_IPC_FIFO_INT, status))
- ivpu_ipc_irq_handler(vdev);
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_1_INT, status))
- ivpu_dbg(vdev, IRQ, "MMU sync complete\n");
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, MMU_IRQ_2_INT, status))
- ivpu_mmu_irq_gerr_handler(vdev);
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_0_INT, status))
- irq_wdt_mss_handler(vdev);
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, CPU_INT_REDIRECT_1_INT, status))
- irq_wdt_nce_handler(vdev);
- if (REG_TEST_FLD(VPU_40XX_HOST_SS_ICB_STATUS_0, NOC_FIREWALL_INT, status))
- irq_noc_firewall_handler(vdev);
- return true;
- }
- static void db_set_37xx(struct ivpu_device *vdev, u32 db_id)
- {
- u32 reg_stride = VPU_37XX_CPU_SS_DOORBELL_1 - VPU_37XX_CPU_SS_DOORBELL_0;
- u32 val = REG_FLD(VPU_37XX_CPU_SS_DOORBELL_0, SET);
- REGV_WR32I(VPU_37XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
- }
- static void db_set_40xx(struct ivpu_device *vdev, u32 db_id)
- {
- u32 reg_stride = VPU_40XX_CPU_SS_DOORBELL_1 - VPU_40XX_CPU_SS_DOORBELL_0;
- u32 val = REG_FLD(VPU_40XX_CPU_SS_DOORBELL_0, SET);
- REGV_WR32I(VPU_40XX_CPU_SS_DOORBELL_0, reg_stride, db_id, val);
- }
- void ivpu_hw_ip_db_set(struct ivpu_device *vdev, u32 db_id)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- db_set_37xx(vdev, db_id);
- else
- db_set_40xx(vdev, db_id);
- }
- u32 ivpu_hw_ip_ipc_rx_addr_get(struct ivpu_device *vdev)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- return REGV_RD32(VPU_37XX_HOST_SS_TIM_IPC_FIFO_ATM);
- else
- return REGV_RD32(VPU_40XX_HOST_SS_TIM_IPC_FIFO_ATM);
- }
- void ivpu_hw_ip_ipc_tx_set(struct ivpu_device *vdev, u32 vpu_addr)
- {
- if (ivpu_hw_ip_gen(vdev) == IVPU_HW_IP_37XX)
- REGV_WR32(VPU_37XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);
- else
- REGV_WR32(VPU_40XX_CPU_SS_TIM_IPC_FIFO, vpu_addr);
- }
|