@@ -338,6 +338,7 @@ typedef struct virge_t {
338
338
event_t * fifo_not_full_event ;
339
339
340
340
atomic_int virge_busy ;
341
+ atomic_uint irq_pending ;
341
342
342
343
uint8_t subsys_stat ;
343
344
uint8_t subsys_cntl ;
@@ -375,6 +376,8 @@ typedef struct virge_t {
375
376
376
377
int pci ;
377
378
int is_agp ;
379
+
380
+ pc_timer_t irq_timer ;
378
381
} virge_t ;
379
382
380
383
static __inline void
@@ -471,6 +474,19 @@ s3_virge_update_irqs(virge_t *virge)
471
474
pci_clear_irq (virge -> pci_slot , PCI_INTA , & virge -> irq_state );
472
475
}
473
476
477
+ static void
478
+ s3_virge_update_irq_timer (void * priv )
479
+ {
480
+ virge_t * virge = (virge_t * ) priv ;
481
+
482
+ if (virge -> irq_pending ) {
483
+ virge -> irq_pending -- ;
484
+ s3_virge_update_irqs (virge );
485
+ }
486
+
487
+ timer_on_auto (& virge -> irq_timer , 100. );
488
+ }
489
+
474
490
static void
475
491
s3_virge_out (uint16_t addr , uint8_t val , void * priv )
476
492
{
@@ -1101,6 +1117,8 @@ static void
1101
1117
s3_virge_vblank_start (svga_t * svga ) {
1102
1118
virge_t * virge = (virge_t * ) svga -> priv ;
1103
1119
1120
+ if (virge -> irq_pending )
1121
+ virge -> irq_pending -- ;
1104
1122
virge -> subsys_stat |= INT_VSY ;
1105
1123
s3_virge_update_irqs (virge );
1106
1124
}
@@ -1784,18 +1802,18 @@ fifo_thread(void *param)
1784
1802
virge -> fifo_read_idx ++ ;
1785
1803
fifo -> addr_type = FIFO_INVALID ;
1786
1804
1787
- if (FIFO_ENTRIES > 0xe000 )
1788
- thread_set_event (virge -> fifo_not_full_event );
1805
+ if (FIFO_ENTRIES > 0xe000 )
1806
+ thread_set_event (virge -> fifo_not_full_event );
1789
1807
1790
- end_time = plat_timer_read ();
1791
- virge_time += end_time - start_time ;
1792
- }
1793
- virge -> virge_busy = 0 ;
1794
- virge -> subsys_stat |= (INT_FIFO_EMP | INT_3DF_EMP );
1795
- if (virge -> cmd_dma )
1796
- virge -> subsys_stat |= (INT_HOST_DONE | INT_CMD_DONE );
1808
+ end_time = plat_timer_read ();
1809
+ virge_time += end_time - start_time ;
1810
+ }
1811
+ virge -> virge_busy = 0 ;
1812
+ virge -> subsys_stat |= (INT_FIFO_EMP | INT_3DF_EMP );
1813
+ if (virge -> cmd_dma )
1814
+ virge -> subsys_stat |= (INT_HOST_DONE | INT_CMD_DONE );
1797
1815
1798
- s3_virge_update_irqs ( virge ) ;
1816
+ virge -> irq_pending ++ ;
1799
1817
}
1800
1818
}
1801
1819
@@ -4404,7 +4422,7 @@ render_thread(void *param)
4404
4422
}
4405
4423
virge -> s3d_busy = 0 ;
4406
4424
virge -> subsys_stat |= INT_S3D_DONE ;
4407
- s3_virge_update_irqs ( virge ) ;
4425
+ virge -> irq_pending ++ ;
4408
4426
}
4409
4427
}
4410
4428
@@ -5062,6 +5080,7 @@ s3_virge_disable_handlers(virge_t *dev)
5062
5080
5063
5081
reset_state -> svga .timer = dev -> svga .timer ;
5064
5082
reset_state -> svga .timer8514 = dev -> svga .timer8514 ;
5083
+ reset_state -> irq_timer = dev -> irq_timer ;
5065
5084
}
5066
5085
5067
5086
static void
@@ -5333,6 +5352,8 @@ s3_virge_init(const device_t *info)
5333
5352
virge -> fifo_not_full_event = thread_create_event ();
5334
5353
virge -> fifo_thread = thread_create (fifo_thread , virge );
5335
5354
5355
+ timer_add (& virge -> irq_timer , s3_virge_update_irq_timer , virge , 1 );
5356
+
5336
5357
virge -> local = info -> local ;
5337
5358
5338
5359
* reset_state = * virge ;
0 commit comments