comparison drivers/mga_vid.c @ 48:66ae768fe0ea

vsync (4 buffers) implemented
author arpi_esp
date Wed, 07 Mar 2001 01:12:18 +0000
parents 71ac847ba504
children baa0a12438eb
comparison
equal deleted inserted replaced
47:9d68da5d8a9a 48:66ae768fe0ea
145 145
146 static struct pci_dev *pci_dev; 146 static struct pci_dev *pci_dev;
147 147
148 static mga_vid_config_t mga_config; 148 static mga_vid_config_t mga_config;
149 149
150 static int mga_irq = -1;
150 151
151 //All register offsets are converted to word aligned offsets (32 bit) 152 //All register offsets are converted to word aligned offsets (32 bit)
152 //because we want all our register accesses to be 32 bits 153 //because we want all our register accesses to be 32 bits
153 #define VCOUNT 0x1e20 154 #define VCOUNT 0x1e20
154 155
176 // Backend Scaler registers 177 // Backend Scaler registers
177 #define BESCTL 0x3d20 178 #define BESCTL 0x3d20
178 #define BESGLOBCTL 0x3dc0 179 #define BESGLOBCTL 0x3dc0
179 #define BESLUMACTL 0x3d40 180 #define BESLUMACTL 0x3d40
180 #define BESPITCH 0x3d24 181 #define BESPITCH 0x3d24
182
181 #define BESA1C3ORG 0x3d60 183 #define BESA1C3ORG 0x3d60
182 #define BESA1CORG 0x3d10 184 #define BESA1CORG 0x3d10
183 #define BESA1ORG 0x3d00 185 #define BESA1ORG 0x3d00
186
184 #define BESA2C3ORG 0x3d64 187 #define BESA2C3ORG 0x3d64
185 #define BESA2CORG 0x3d14 188 #define BESA2CORG 0x3d14
186 #define BESA2ORG 0x3d04 189 #define BESA2ORG 0x3d04
190
187 #define BESB1C3ORG 0x3d68 191 #define BESB1C3ORG 0x3d68
188 #define BESB1CORG 0x3d18 192 #define BESB1CORG 0x3d18
189 #define BESB1ORG 0x3d08 193 #define BESB1ORG 0x3d08
194
190 #define BESB2C3ORG 0x3d6C 195 #define BESB2C3ORG 0x3d6C
191 #define BESB2CORG 0x3d1C 196 #define BESB2CORG 0x3d1C
192 #define BESB2ORG 0x3d0C 197 #define BESB2ORG 0x3d0C
198
193 #define BESHCOORD 0x3d28 199 #define BESHCOORD 0x3d28
194 #define BESHISCAL 0x3d30 200 #define BESHISCAL 0x3d30
195 #define BESHSRCEND 0x3d3C 201 #define BESHSRCEND 0x3d3C
196 #define BESHSRCLST 0x3d50 202 #define BESHSRCLST 0x3d50
197 #define BESHSRCST 0x3d38 203 #define BESHSRCST 0x3d38
201 #define BESV2SRCLST 0x3d58 207 #define BESV2SRCLST 0x3d58
202 #define BESVISCAL 0x3d34 208 #define BESVISCAL 0x3d34
203 #define BESVCOORD 0x3d2c 209 #define BESVCOORD 0x3d2c
204 #define BESSTATUS 0x3dc4 210 #define BESSTATUS 0x3dc4
205 211
212 #define CRTCX 0x1fd4
213 #define CRTCD 0x1fd5
214 #define IEN 0x1e1c
215 #define ICLEAR 0x1e18
216 #define STATUS 0x1e14
217
218 static int mga_next_frame=0;
206 219
207 static void mga_vid_frame_sel(int frame) 220 static void mga_vid_frame_sel(int frame)
208 { 221 {
222 if ( mga_irq != -1 ) {
223 mga_next_frame=frame;
224 } else {
225
209 //we don't need the vcount protection as we're only hitting 226 //we don't need the vcount protection as we're only hitting
210 //one register (and it doesn't seem to be double buffered) 227 //one register (and it doesn't seem to be double buffered)
211 regs.besctl = (regs.besctl & ~0x07000000) + (frame << 25); 228 regs.besctl = (regs.besctl & ~0x07000000) + (frame << 25);
212 writel( regs.besctl, mga_mmio_base + BESCTL ); 229 writel( regs.besctl, mga_mmio_base + BESCTL );
230 }
213 } 231 }
214 232
215 233
216 static void mga_vid_write_regs(void) 234 static void mga_vid_write_regs(void)
217 { 235 {
284 writel( regs.beslumactl, mga_mmio_base + BESLUMACTL); 302 writel( regs.beslumactl, mga_mmio_base + BESLUMACTL);
285 writel( regs.bespitch, mga_mmio_base + BESPITCH); 303 writel( regs.bespitch, mga_mmio_base + BESPITCH);
286 304
287 writel( regs.besa1org, mga_mmio_base + BESA1ORG); 305 writel( regs.besa1org, mga_mmio_base + BESA1ORG);
288 writel( regs.besa1corg, mga_mmio_base + BESA1CORG); 306 writel( regs.besa1corg, mga_mmio_base + BESA1CORG);
307 writel( regs.besa2org, mga_mmio_base + BESA2ORG);
308 writel( regs.besa2corg, mga_mmio_base + BESA2CORG);
289 writel( regs.besb1org, mga_mmio_base + BESB1ORG); 309 writel( regs.besb1org, mga_mmio_base + BESB1ORG);
290 writel( regs.besb1corg, mga_mmio_base + BESB1CORG); 310 writel( regs.besb1corg, mga_mmio_base + BESB1CORG);
311 writel( regs.besb2org, mga_mmio_base + BESB2ORG);
312 writel( regs.besb2corg, mga_mmio_base + BESB2CORG);
291 if(is_g400) 313 if(is_g400)
292 { 314 {
293 writel( regs.besa1c3org, mga_mmio_base + BESA1C3ORG); 315 writel( regs.besa1c3org, mga_mmio_base + BESA1C3ORG);
316 writel( regs.besa2c3org, mga_mmio_base + BESA2C3ORG);
294 writel( regs.besb1c3org, mga_mmio_base + BESB1C3ORG); 317 writel( regs.besb1c3org, mga_mmio_base + BESB1C3ORG);
318 writel( regs.besb2c3org, mga_mmio_base + BESB2C3ORG);
295 } 319 }
296 320
297 writel( regs.beshcoord, mga_mmio_base + BESHCOORD); 321 writel( regs.beshcoord, mga_mmio_base + BESHCOORD);
298 writel( regs.beshiscal, mga_mmio_base + BESHISCAL); 322 writel( regs.beshiscal, mga_mmio_base + BESHISCAL);
299 writel( regs.beshsrcst, mga_mmio_base + BESHSRCST); 323 writel( regs.beshsrcst, mga_mmio_base + BESHSRCST);
300 writel( regs.beshsrcend, mga_mmio_base + BESHSRCEND); 324 writel( regs.beshsrcend, mga_mmio_base + BESHSRCEND);
301 writel( regs.beshsrclst, mga_mmio_base + BESHSRCLST); 325 writel( regs.beshsrclst, mga_mmio_base + BESHSRCLST);
302 326
303 writel( regs.besvcoord, mga_mmio_base + BESVCOORD); 327 writel( regs.besvcoord, mga_mmio_base + BESVCOORD);
304 writel( regs.besviscal, mga_mmio_base + BESVISCAL); 328 writel( regs.besviscal, mga_mmio_base + BESVISCAL);
329
305 writel( regs.besv1srclst, mga_mmio_base + BESV1SRCLST); 330 writel( regs.besv1srclst, mga_mmio_base + BESV1SRCLST);
306 writel( regs.besv1wght, mga_mmio_base + BESV1WGHT); 331 writel( regs.besv1wght, mga_mmio_base + BESV1WGHT);
332 writel( regs.besv2srclst, mga_mmio_base + BESV2SRCLST);
333 writel( regs.besv2wght, mga_mmio_base + BESV2WGHT);
307 334
308 //update the registers somewhere between 1 and 2 frames from now. 335 //update the registers somewhere between 1 and 2 frames from now.
309 writel( regs.besglobctl + ((readl(mga_mmio_base + VCOUNT)+2)<<16), 336 writel( regs.besglobctl + ((readl(mga_mmio_base + VCOUNT)+2)<<16),
310 mga_mmio_base + BESGLOBCTL); 337 mga_mmio_base + BESGLOBCTL);
311 338
336 //FIXME check that window is valid and inside desktop 363 //FIXME check that window is valid and inside desktop
337 364
338 //FIXME figure out a better way to allocate memory on card 365 //FIXME figure out a better way to allocate memory on card
339 //allocate 2 megs 366 //allocate 2 megs
340 //mga_src_base = mga_mem_base + (MGA_VIDMEM_SIZE-2) * 0x100000; 367 //mga_src_base = mga_mem_base + (MGA_VIDMEM_SIZE-2) * 0x100000;
341 mga_src_base = (MGA_VIDMEM_SIZE-2) * 0x100000; 368 mga_src_base = (MGA_VIDMEM_SIZE-3) * 0x100000;
342 369
343 370
344 //Setup the BES registers for a three plane 4:2:0 video source 371 //Setup the BES registers for a three plane 4:2:0 video source
345 372
346 switch(config->format){ 373 switch(config->format){
413 regs.besviscal = ifactor<<2; 440 regs.besviscal = ifactor<<2;
414 441
415 baseadrofs = ((ofstop*regs.besviscal)>>16)*regs.bespitch; 442 baseadrofs = ((ofstop*regs.besviscal)>>16)*regs.bespitch;
416 frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2; 443 frame_size = ((sw + 31) & ~31) * sh + (((sw + 31) & ~31) * sh) / 2;
417 regs.besa1org = (uint32_t) mga_src_base + baseadrofs; 444 regs.besa1org = (uint32_t) mga_src_base + baseadrofs;
418 regs.besb1org = (uint32_t) mga_src_base + baseadrofs + frame_size; 445 regs.besa2org = (uint32_t) mga_src_base + baseadrofs + 1*frame_size;
446 regs.besb1org = (uint32_t) mga_src_base + baseadrofs + 2*frame_size;
447 regs.besb2org = (uint32_t) mga_src_base + baseadrofs + 3*frame_size;
419 448
420 if (is_g400) 449 if (is_g400)
421 baseadrofs = (((ofstop*regs.besviscal)/4)>>16)*regs.bespitch; 450 baseadrofs = (((ofstop*regs.besviscal)/4)>>16)*regs.bespitch;
422 else 451 else
423 baseadrofs = (((ofstop*regs.besviscal)/2)>>16)*regs.bespitch; 452 baseadrofs = (((ofstop*regs.besviscal)/2)>>16)*regs.bespitch;
424 453
425 regs.besa1corg = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ; 454 regs.besa1corg = (uint32_t) mga_src_base + baseadrofs + regs.bespitch * sh ;
426 regs.besb1corg = (uint32_t) mga_src_base + baseadrofs + frame_size + regs.bespitch * sh; 455 regs.besa2corg = (uint32_t) mga_src_base + baseadrofs + 1*frame_size + regs.bespitch * sh;
456 regs.besb1corg = (uint32_t) mga_src_base + baseadrofs + 2*frame_size + regs.bespitch * sh;
457 regs.besb2corg = (uint32_t) mga_src_base + baseadrofs + 3*frame_size + regs.bespitch * sh;
427 regs.besa1c3org = regs.besa1corg + ((regs.bespitch * sh) / 4); 458 regs.besa1c3org = regs.besa1corg + ((regs.bespitch * sh) / 4);
459 regs.besa2c3org = regs.besa2corg + ((regs.bespitch * sh) / 4);
428 regs.besb1c3org = regs.besb1corg + ((regs.bespitch * sh) / 4); 460 regs.besb1c3org = regs.besb1corg + ((regs.bespitch * sh) / 4);
461 regs.besb2c3org = regs.besb2corg + ((regs.bespitch * sh) / 4);
429 462
430 weight = ofstop * (regs.besviscal >> 2); 463 weight = ofstop * (regs.besviscal >> 2);
431 weights = weight < 0 ? 1 : 0; 464 weights = weight < 0 ? 1 : 0;
432 regs.besv1wght = (weights << 16) + ((weight & 0x3FFF) << 2); 465 regs.besv2wght = regs.besv1wght = (weights << 16) + ((weight & 0x3FFF) << 2);
433 regs.besv1srclst = sh - 1 - (((ofstop * regs.besviscal) >> 16) & 0x03FF); 466 regs.besv2srclst = regs.besv1srclst = sh - 1 - (((ofstop * regs.besviscal) >> 16) & 0x03FF);
434 467
435 mga_vid_write_regs(); 468 mga_vid_write_regs();
436 return 0; 469 return 0;
437 } 470 }
471
472 static void enable_irq(){
473 long int cc;
474
475 cc = readl(mga_mmio_base + IEN);
476 printk("<1>*** !!! IRQREG = %d\n", (int)(cc&0xff));
477
478 writeb( 0x11, mga_mmio_base + CRTCX);
479
480 writeb(0x20, mga_mmio_base + CRTCD ); /* clear 0, enable off */
481 writeb(0x00, mga_mmio_base + CRTCD ); /* enable on */
482 writeb(0x10, mga_mmio_base + CRTCD ); /* clear = 1 */
483
484 writel( regs.besglobctl , mga_mmio_base + BESGLOBCTL);
485
486 }
487
488 static void disable_irq(){
489
490 writeb( 0x11, mga_mmio_base + CRTCX);
491 writeb(0x20, mga_mmio_base + CRTCD ); /* clear 0, enable off */
492
493 }
494
495 void mga_handle_irq(int irq, void *dev_id, struct pt_regs *pregs) {
496 // static int frame=0;
497 static int counter=0;
498 long int cc;
499 // if ( ! mga_enabled_flag ) return;
500
501 //printk("mga_interrupt #%d\n", irq);
502
503 if ( irq != -1 ) {
504
505 cc = readl(mga_mmio_base + STATUS);
506 if ( ! (cc & 0x10) ) return; /* vsyncpen */
507 // debug_irqcnt++;
508 }
509
510 // if ( debug_irqignore ) {
511 // debug_irqignore = 0;
512
513
514 /*
515 if ( mga_conf_deinterlace ) {
516 if ( mga_first_field ) {
517 // printk("mga_interrupt first field\n");
518 if ( syncfb_interrupt() )
519 mga_first_field = 0;
520 } else {
521 // printk("mga_interrupt second field\n");
522 mga_select_buffer( mga_current_field | 2 );
523 mga_first_field = 1;
524 }
525 } else {
526 syncfb_interrupt();
527 }
528 */
529
530 // frame=(frame+1)&1;
531 regs.besctl = (regs.besctl & ~0x07000000) + (mga_next_frame << 25);
532 writel( regs.besctl, mga_mmio_base + BESCTL );
533
534 #if 0
535 ++counter;
536 if(!(counter&63)){
537 printk("mga irq counter = %d\n",counter);
538 }
539 #endif
540
541 // } else {
542 // debug_irqignore = 1;
543 // }
544
545 if ( irq != -1 ) {
546 writeb( 0x11, mga_mmio_base + CRTCX);
547 writeb( 0, mga_mmio_base + CRTCD );
548 writeb( 0x10, mga_mmio_base + CRTCD );
549 }
550
551 // writel( regs.besglobctl, mga_mmio_base + BESGLOBCTL);
552
553
554 return;
555
556 }
557
438 558
439 559
440 static int mga_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) 560 static int mga_vid_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
441 { 561 {
442 int frame; 562 int frame;
478 if(vid_overlay_on) 598 if(vid_overlay_on)
479 { 599 {
480 regs.besctl |= 1; 600 regs.besctl |= 1;
481 mga_vid_write_regs(); 601 mga_vid_write_regs();
482 } 602 }
603 if ( mga_irq != -1 ) enable_irq();
604 mga_next_frame=0;
483 break; 605 break;
484 606
485 case MGA_VID_OFF: 607 case MGA_VID_OFF:
486 printk("mga_vid: Video OFF\n"); 608 printk("mga_vid: Video OFF\n");
487 vid_src_ready = 0; 609 vid_src_ready = 0;
610 if ( mga_irq != -1 ) disable_irq();
488 regs.besctl &= ~1; 611 regs.besctl &= ~1;
489 mga_vid_write_regs(); 612 mga_vid_write_regs();
490 break; 613 break;
491 614
492 case MGA_VID_FSEL: 615 case MGA_VID_FSEL:
533 printk("mga_vid: No supported cards found\n"); 656 printk("mga_vid: No supported cards found\n");
534 return FALSE; 657 return FALSE;
535 } 658 }
536 659
537 pci_dev = dev; 660 pci_dev = dev;
661
662 mga_irq = pci_dev->irq;
538 663
539 #if LINUX_VERSION_CODE >= 0x020300 664 #if LINUX_VERSION_CODE >= 0x020300
540 mga_mmio_base = ioremap_nocache(dev->resource[1].start,0x4000); 665 mga_mmio_base = ioremap_nocache(dev->resource[1].start,0x4000);
541 mga_mem_base = dev->resource[0].start; 666 mga_mem_base = dev->resource[0].start;
542 #else 667 #else
543 mga_mmio_base = ioremap_nocache(dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK,0x4000); 668 mga_mmio_base = ioremap_nocache(dev->base_address[1] & PCI_BASE_ADDRESS_MEM_MASK,0x4000);
544 mga_mem_base = dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK; 669 mga_mem_base = dev->base_address[0] & PCI_BASE_ADDRESS_MEM_MASK;
545 #endif 670 #endif
546 printk("mga_vid: MMIO at 0x%p\n", mga_mmio_base); 671 // printk("mga_vid: MMIO at 0x%p\n", mga_mmio_base);
672 printk("syncfb (mga): MMIO at 0x%p IRQ: %d\n", mga_mmio_base, mga_irq);
547 printk("mga_vid: Frame Buffer at 0x%08lX\n", mga_mem_base); 673 printk("mga_vid: Frame Buffer at 0x%08lX\n", mga_mem_base);
548 674
549 pci_read_config_dword(dev, 0x40, &card_option); 675 pci_read_config_dword(dev, 0x40, &card_option);
550 printk("OPTION word: 0x%08x\n", card_option); 676 printk("OPTION word: 0x%08x\n", card_option);
551 677
568 mga_ram_size = 8; 694 mga_ram_size = 8;
569 } 695 }
570 } 696 }
571 697
572 printk("mga_vid: RAMSIZE seems to be %d MB\n", (unsigned int) mga_ram_size); 698 printk("mga_vid: RAMSIZE seems to be %d MB\n", (unsigned int) mga_ram_size);
699
700 if ( mga_irq != -1 ) {
701 int tmp = request_irq(mga_irq, mga_handle_irq, SA_INTERRUPT | SA_SHIRQ, "Syncfb Time Base", &mga_irq);
702 if ( tmp ) {
703 printk("syncfb (mga): cannot register irq %d (Err: %d)\n", mga_irq, tmp);
704 mga_irq=-1;
705 } else {
706 printk("syncfb (mga): registered irq %d\n", mga_irq);
707 }
708 } else {
709 printk("syncfb (mga): No valid irq was found\n");
710 mga_irq=-1;
711 }
712
573 713
574 return TRUE; 714 return TRUE;
575 } 715 }
576 716
577 717
587 727
588 static int mga_vid_mmap(struct file *file, struct vm_area_struct *vma) 728 static int mga_vid_mmap(struct file *file, struct vm_area_struct *vma)
589 { 729 {
590 730
591 printk("mga_vid: mapping video memory into userspace\n"); 731 printk("mga_vid: mapping video memory into userspace\n");
592 if(remap_page_range(vma->vm_start, mga_mem_base + (MGA_VIDMEM_SIZE-2) * 0x100000, 732 if(remap_page_range(vma->vm_start, mga_mem_base + (MGA_VIDMEM_SIZE-3) * 0x100000,
593 vma->vm_end - vma->vm_start, vma->vm_page_prot)) 733 vma->vm_end - vma->vm_start, vma->vm_page_prot))
594 { 734 {
595 printk("mga_vid: error mapping video memory\n"); 735 printk("mga_vid: error mapping video memory\n");
596 return(-EAGAIN); 736 return(-EAGAIN);
597 } 737 }
692 return mga_vid_initialize(); 832 return mga_vid_initialize();
693 } 833 }
694 834
695 void cleanup_module(void) 835 void cleanup_module(void)
696 { 836 {
837
838 if ( mga_irq != -1)
839 free_irq(mga_irq, &mga_irq);
840
697 if(mga_mmio_base) 841 if(mga_mmio_base)
698 iounmap(mga_mmio_base); 842 iounmap(mga_mmio_base);
699 843
700 //FIXME turn off BES 844 //FIXME turn off BES
701 printk("mga_vid: Cleaning up module\n"); 845 printk("mga_vid: Cleaning up module\n");