5757
5858#define ICB_0_1_IRQ_MASK ((((u64)ICB_1_IRQ_MASK) << 32) | ICB_0_IRQ_MASK)
5959
60- #define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, FREQ_CHANGE)) | \
61- (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
60+ #define BUTTRESS_IRQ_MASK ((REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, ATS_ERR)) | \
6261 (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI0_ERR)) | \
6362 (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, CFI1_ERR)) | \
6463 (REG_FLD(VPU_40XX_BUTTRESS_INTERRUPT_STAT, IMR0_ERR)) | \
@@ -196,6 +195,14 @@ static int ivpu_pll_wait_for_status_ready(struct ivpu_device *vdev)
196195 return REGB_POLL_FLD (VPU_40XX_BUTTRESS_VPU_STATUS , READY , 1 , PLL_TIMEOUT_US );
197196}
198197
198+ static int ivpu_wait_for_clock_own_resource_ack (struct ivpu_device * vdev )
199+ {
200+ if (ivpu_is_simics (vdev ))
201+ return 0 ;
202+
203+ return REGB_POLL_FLD (VPU_40XX_BUTTRESS_VPU_STATUS , CLOCK_RESOURCE_OWN_ACK , 1 , TIMEOUT_US );
204+ }
205+
199206static void ivpu_pll_init_frequency_ratios (struct ivpu_device * vdev )
200207{
201208 struct ivpu_hw_info * hw = vdev -> hw ;
@@ -556,6 +563,12 @@ static int ivpu_boot_pwr_domain_enable(struct ivpu_device *vdev)
556563{
557564 int ret ;
558565
566+ ret = ivpu_wait_for_clock_own_resource_ack (vdev );
567+ if (ret ) {
568+ ivpu_err (vdev , "Timed out waiting for clock own resource ACK\n" );
569+ return ret ;
570+ }
571+
559572 ivpu_boot_pwr_island_trickle_drive (vdev , true);
560573 ivpu_boot_pwr_island_drive (vdev , true);
561574
@@ -1046,9 +1059,6 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
10461059 if (status == 0 )
10471060 return IRQ_NONE ;
10481061
1049- /* Disable global interrupt before handling local buttress interrupts */
1050- REGB_WR32 (VPU_40XX_BUTTRESS_GLOBAL_INT_MASK , 0x1 );
1051-
10521062 if (REG_TEST_FLD (VPU_40XX_BUTTRESS_INTERRUPT_STAT , FREQ_CHANGE , status ))
10531063 ivpu_dbg (vdev , IRQ , "FREQ_CHANGE" );
10541064
@@ -1096,9 +1106,6 @@ static irqreturn_t ivpu_hw_40xx_irqb_handler(struct ivpu_device *vdev, int irq)
10961106 /* This must be done after interrupts are cleared at the source. */
10971107 REGB_WR32 (VPU_40XX_BUTTRESS_INTERRUPT_STAT , status );
10981108
1099- /* Re-enable global interrupt */
1100- REGB_WR32 (VPU_40XX_BUTTRESS_GLOBAL_INT_MASK , 0x0 );
1101-
11021109 if (schedule_recovery )
11031110 ivpu_pm_schedule_recovery (vdev );
11041111
@@ -1110,9 +1117,14 @@ static irqreturn_t ivpu_hw_40xx_irq_handler(int irq, void *ptr)
11101117 struct ivpu_device * vdev = ptr ;
11111118 irqreturn_t ret = IRQ_NONE ;
11121119
1120+ REGB_WR32 (VPU_40XX_BUTTRESS_GLOBAL_INT_MASK , 0x1 );
1121+
11131122 ret |= ivpu_hw_40xx_irqv_handler (vdev , irq );
11141123 ret |= ivpu_hw_40xx_irqb_handler (vdev , irq );
11151124
1125+ /* Re-enable global interrupts to re-trigger MSI for pending interrupts */
1126+ REGB_WR32 (VPU_40XX_BUTTRESS_GLOBAL_INT_MASK , 0x0 );
1127+
11161128 if (ret & IRQ_WAKE_THREAD )
11171129 return IRQ_WAKE_THREAD ;
11181130
0 commit comments