Mercurial > mplayer.hg
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"); |