aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/char/drm/mga_dma.c
diff options
context:
space:
mode:
authorDave Airlie <airlied@starflyer.(none)>2005-11-11 07:11:34 -0500
committerDave Airlie <airlied@linux.ie>2005-11-11 07:11:34 -0500
commit7ccf800e9415daf9214eb667318e356f9a3d81fc (patch)
tree90c60097909170f1248854d27f86aac71bdbe3b0 /drivers/char/drm/mga_dma.c
parentc0be4d240483f3ebd138db467b5e8fbe15c520e2 (diff)
drm: update mga driver for new bootstrap code
The MGA driver needs to use the full AGP interface. From: Ian Romanick <idr@us.ibm.com> Signed-off-by: Dave Airlie <airlied@linux.ie>
Diffstat (limited to 'drivers/char/drm/mga_dma.c')
-rw-r--r--drivers/char/drm/mga_dma.c144
1 files changed, 87 insertions, 57 deletions
diff --git a/drivers/char/drm/mga_dma.c b/drivers/char/drm/mga_dma.c
index 9b09d786b158..c2a4bac14521 100644
--- a/drivers/char/drm/mga_dma.c
+++ b/drivers/char/drm/mga_dma.c
@@ -44,7 +44,9 @@
44#define MGA_DEFAULT_USEC_TIMEOUT 10000 44#define MGA_DEFAULT_USEC_TIMEOUT 10000
45#define MGA_FREELIST_DEBUG 0 45#define MGA_FREELIST_DEBUG 0
46 46
47static int mga_do_cleanup_dma(drm_device_t * dev); 47#define MINIMAL_CLEANUP 0
48#define FULL_CLEANUP 1
49static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup);
48 50
49/* ================================================================ 51/* ================================================================
50 * Engine control 52 * Engine control
@@ -446,17 +448,19 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
446 drm_buf_desc_t req; 448 drm_buf_desc_t req;
447 drm_agp_mode_t mode; 449 drm_agp_mode_t mode;
448 drm_agp_info_t info; 450 drm_agp_info_t info;
451 drm_agp_buffer_t agp_req;
452 drm_agp_binding_t bind_req;
449 453
450 /* Acquire AGP. */ 454 /* Acquire AGP. */
451 err = drm_agp_acquire(dev); 455 err = drm_agp_acquire(dev);
452 if (err) { 456 if (err) {
453 DRM_ERROR("Unable to acquire AGP\n"); 457 DRM_ERROR("Unable to acquire AGP: %d\n", err);
454 return err; 458 return err;
455 } 459 }
456 460
457 err = drm_agp_info(dev, &info); 461 err = drm_agp_info(dev, &info);
458 if (err) { 462 if (err) {
459 DRM_ERROR("Unable to get AGP info\n"); 463 DRM_ERROR("Unable to get AGP info: %d\n", err);
460 return err; 464 return err;
461 } 465 }
462 466
@@ -480,18 +484,24 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
480 } 484 }
481 485
482 /* Allocate and bind AGP memory. */ 486 /* Allocate and bind AGP memory. */
483 dev_priv->agp_pages = agp_size / PAGE_SIZE; 487 agp_req.size = agp_size;
484 dev_priv->agp_mem = drm_alloc_agp(dev, dev_priv->agp_pages, 0); 488 agp_req.type = 0;
485 if (dev_priv->agp_mem == NULL) { 489 err = drm_agp_alloc(dev, &agp_req);
486 dev_priv->agp_pages = 0; 490 if (err) {
491 dev_priv->agp_size = 0;
487 DRM_ERROR("Unable to allocate %uMB AGP memory\n", 492 DRM_ERROR("Unable to allocate %uMB AGP memory\n",
488 dma_bs->agp_size); 493 dma_bs->agp_size);
489 return DRM_ERR(ENOMEM); 494 return err;
490 } 495 }
496
497 dev_priv->agp_size = agp_size;
498 dev_priv->agp_handle = agp_req.handle;
491 499
492 err = drm_bind_agp(dev_priv->agp_mem, 0); 500 bind_req.handle = agp_req.handle;
501 bind_req.offset = 0;
502 err = drm_agp_bind(dev, &bind_req);
493 if (err) { 503 if (err) {
494 DRM_ERROR("Unable to bind AGP memory\n"); 504 DRM_ERROR("Unable to bind AGP memory: %d\n", err);
495 return err; 505 return err;
496 } 506 }
497 507
@@ -505,7 +515,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
505 err = drm_addmap(dev, offset, warp_size, 515 err = drm_addmap(dev, offset, warp_size,
506 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp); 516 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->warp);
507 if (err) { 517 if (err) {
508 DRM_ERROR("Unable to map WARP microcode\n"); 518 DRM_ERROR("Unable to map WARP microcode: %d\n", err);
509 return err; 519 return err;
510 } 520 }
511 521
@@ -513,7 +523,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
513 err = drm_addmap(dev, offset, dma_bs->primary_size, 523 err = drm_addmap(dev, offset, dma_bs->primary_size,
514 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary); 524 _DRM_AGP, _DRM_READ_ONLY, &dev_priv->primary);
515 if (err) { 525 if (err) {
516 DRM_ERROR("Unable to map primary DMA region\n"); 526 DRM_ERROR("Unable to map primary DMA region: %d\n", err);
517 return err; 527 return err;
518 } 528 }
519 529
@@ -521,7 +531,7 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
521 err = drm_addmap(dev, offset, secondary_size, 531 err = drm_addmap(dev, offset, secondary_size,
522 _DRM_AGP, 0, &dev->agp_buffer_map); 532 _DRM_AGP, 0, &dev->agp_buffer_map);
523 if (err) { 533 if (err) {
524 DRM_ERROR("Unable to map secondary DMA region\n"); 534 DRM_ERROR("Unable to map secondary DMA region: %d\n", err);
525 return err; 535 return err;
526 } 536 }
527 537
@@ -533,15 +543,29 @@ static int mga_do_agp_dma_bootstrap(drm_device_t * dev,
533 543
534 err = drm_addbufs_agp(dev, &req); 544 err = drm_addbufs_agp(dev, &req);
535 if (err) { 545 if (err) {
536 DRM_ERROR("Unable to add secondary DMA buffers\n"); 546 DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
537 return err; 547 return err;
538 } 548 }
539 549
550 {
551 drm_map_list_t *_entry;
552 unsigned long agp_token = 0;
553
554 list_for_each_entry(_entry, &dev->maplist->head, head) {
555 if (_entry->map == dev->agp_buffer_map)
556 agp_token = _entry->user_token;
557 }
558 if (!agp_token)
559 return -EFAULT;
560
561 dev->agp_buffer_token = agp_token;
562 }
563
540 offset += secondary_size; 564 offset += secondary_size;
541 err = drm_addmap(dev, offset, agp_size - offset, 565 err = drm_addmap(dev, offset, agp_size - offset,
542 _DRM_AGP, 0, &dev_priv->agp_textures); 566 _DRM_AGP, 0, &dev_priv->agp_textures);
543 if (err) { 567 if (err) {
544 DRM_ERROR("Unable to map AGP texture region\n"); 568 DRM_ERROR("Unable to map AGP texture region %d\n", err);
545 return err; 569 return err;
546 } 570 }
547 571
@@ -611,7 +635,8 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
611 err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT, 635 err = drm_addmap(dev, 0, warp_size, _DRM_CONSISTENT,
612 _DRM_READ_ONLY, &dev_priv->warp); 636 _DRM_READ_ONLY, &dev_priv->warp);
613 if (err != 0) { 637 if (err != 0) {
614 DRM_ERROR("Unable to create mapping for WARP microcode\n"); 638 DRM_ERROR("Unable to create mapping for WARP microcode: %d\n",
639 err);
615 return err; 640 return err;
616 } 641 }
617 642
@@ -630,7 +655,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
630 } 655 }
631 656
632 if (err != 0) { 657 if (err != 0) {
633 DRM_ERROR("Unable to allocate primary DMA region\n"); 658 DRM_ERROR("Unable to allocate primary DMA region: %d\n", err);
634 return DRM_ERR(ENOMEM); 659 return DRM_ERR(ENOMEM);
635 } 660 }
636 661
@@ -654,7 +679,7 @@ static int mga_do_pci_dma_bootstrap(drm_device_t * dev,
654 } 679 }
655 680
656 if (bin_count == 0) { 681 if (bin_count == 0) {
657 DRM_ERROR("Unable to add secondary DMA buffers\n"); 682 DRM_ERROR("Unable to add secondary DMA buffers: %d\n", err);
658 return err; 683 return err;
659 } 684 }
660 685
@@ -690,7 +715,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
690 err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size, 715 err = drm_addmap(dev, dev_priv->mmio_base, dev_priv->mmio_size,
691 _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio); 716 _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio);
692 if (err) { 717 if (err) {
693 DRM_ERROR("Unable to map MMIO region\n"); 718 DRM_ERROR("Unable to map MMIO region: %d\n", err);
694 return err; 719 return err;
695 } 720 }
696 721
@@ -698,7 +723,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
698 _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL, 723 _DRM_READ_ONLY | _DRM_LOCKED | _DRM_KERNEL,
699 &dev_priv->status); 724 &dev_priv->status);
700 if (err) { 725 if (err) {
701 DRM_ERROR("Unable to map status region\n"); 726 DRM_ERROR("Unable to map status region: %d\n", err);
702 return err; 727 return err;
703 } 728 }
704 729
@@ -716,7 +741,7 @@ static int mga_do_dma_bootstrap(drm_device_t * dev,
716 */ 741 */
717 742
718 if (err) { 743 if (err) {
719 mga_do_cleanup_dma(dev); 744 mga_do_cleanup_dma(dev, MINIMAL_CLEANUP);
720 } 745 }
721 746
722 /* Not only do we want to try and initialized PCI cards for PCI DMA, 747 /* Not only do we want to try and initialized PCI cards for PCI DMA,
@@ -739,35 +764,32 @@ int mga_dma_bootstrap(DRM_IOCTL_ARGS)
739 DRM_DEVICE; 764 DRM_DEVICE;
740 drm_mga_dma_bootstrap_t bootstrap; 765 drm_mga_dma_bootstrap_t bootstrap;
741 int err; 766 int err;
767 static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 };
768 const drm_mga_private_t *const dev_priv =
769 (drm_mga_private_t *) dev->dev_private;
742 770
743 DRM_COPY_FROM_USER_IOCTL(bootstrap, 771 DRM_COPY_FROM_USER_IOCTL(bootstrap,
744 (drm_mga_dma_bootstrap_t __user *) data, 772 (drm_mga_dma_bootstrap_t __user *) data,
745 sizeof(bootstrap)); 773 sizeof(bootstrap));
746 774
747 err = mga_do_dma_bootstrap(dev, &bootstrap); 775 err = mga_do_dma_bootstrap(dev, &bootstrap);
748 if (!err) { 776 if (err) {
749 static const int modes[] = { 0, 1, 2, 2, 4, 4, 4, 4 }; 777 mga_do_cleanup_dma(dev, FULL_CLEANUP);
750 const drm_mga_private_t *const dev_priv = 778 return err;
751 (drm_mga_private_t *) dev->dev_private; 779 }
752
753 if (dev_priv->agp_textures != NULL) {
754 bootstrap.texture_handle =
755 dev_priv->agp_textures->offset;
756 bootstrap.texture_size = dev_priv->agp_textures->size;
757 } else {
758 bootstrap.texture_handle = 0;
759 bootstrap.texture_size = 0;
760 }
761 780
762 bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07]; 781 if (dev_priv->agp_textures != NULL) {
763 if (DRM_COPY_TO_USER((void __user *)data, &bootstrap, 782 bootstrap.texture_handle = dev_priv->agp_textures->offset;
764 sizeof(bootstrap))) { 783 bootstrap.texture_size = dev_priv->agp_textures->size;
765 err = DRM_ERR(EFAULT);
766 }
767 } else { 784 } else {
768 mga_do_cleanup_dma(dev); 785 bootstrap.texture_handle = 0;
786 bootstrap.texture_size = 0;
769 } 787 }
770 788
789 bootstrap.agp_mode = modes[bootstrap.agp_mode & 0x07];
790 DRM_COPY_TO_USER_IOCTL((drm_mga_dma_bootstrap_t __user *)data,
791 bootstrap, sizeof(bootstrap));
792
771 return err; 793 return err;
772} 794}
773 795
@@ -861,13 +883,13 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
861 883
862 ret = mga_warp_install_microcode(dev_priv); 884 ret = mga_warp_install_microcode(dev_priv);
863 if (ret < 0) { 885 if (ret < 0) {
864 DRM_ERROR("failed to install WARP ucode!\n"); 886 DRM_ERROR("failed to install WARP ucode!: %d\n", ret);
865 return ret; 887 return ret;
866 } 888 }
867 889
868 ret = mga_warp_init(dev_priv); 890 ret = mga_warp_init(dev_priv);
869 if (ret < 0) { 891 if (ret < 0) {
870 DRM_ERROR("failed to init WARP engine!\n"); 892 DRM_ERROR("failed to init WARP engine!: %d\n", ret);
871 return ret; 893 return ret;
872 } 894 }
873 895
@@ -912,7 +934,7 @@ static int mga_do_init_dma(drm_device_t * dev, drm_mga_init_t * init)
912 return 0; 934 return 0;
913} 935}
914 936
915static int mga_do_cleanup_dma(drm_device_t * dev) 937static int mga_do_cleanup_dma(drm_device_t *dev, int full_cleanup)
916{ 938{
917 int err = 0; 939 int err = 0;
918 DRM_DEBUG("\n"); 940 DRM_DEBUG("\n");
@@ -940,31 +962,39 @@ static int mga_do_cleanup_dma(drm_device_t * dev)
940 962
941 if (dev_priv->used_new_dma_init) { 963 if (dev_priv->used_new_dma_init) {
942#if __OS_HAS_AGP 964#if __OS_HAS_AGP
943 if (dev_priv->agp_mem != NULL) { 965 if (dev_priv->agp_handle != 0) {
944 dev_priv->agp_textures = NULL; 966 drm_agp_binding_t unbind_req;
945 drm_unbind_agp(dev_priv->agp_mem); 967 drm_agp_buffer_t free_req;
946 968
947 drm_free_agp(dev_priv->agp_mem, 969 unbind_req.handle = dev_priv->agp_handle;
948 dev_priv->agp_pages); 970 drm_agp_unbind(dev, &unbind_req);
949 dev_priv->agp_pages = 0; 971
950 dev_priv->agp_mem = NULL; 972 free_req.handle = dev_priv->agp_handle;
973 drm_agp_free(dev, &free_req);
974
975 dev_priv->agp_textures = NULL;
976 dev_priv->agp_size = 0;
977 dev_priv->agp_handle = 0;
951 } 978 }
952 979
953 if ((dev->agp != NULL) && dev->agp->acquired) { 980 if ((dev->agp != NULL) && dev->agp->acquired) {
954 err = drm_agp_release(dev); 981 err = drm_agp_release(dev);
955 } 982 }
956#endif 983#endif
957 dev_priv->used_new_dma_init = 0;
958 } 984 }
959 985
960 dev_priv->warp = NULL; 986 dev_priv->warp = NULL;
961 dev_priv->primary = NULL; 987 dev_priv->primary = NULL;
962 dev_priv->mmio = NULL;
963 dev_priv->status = NULL;
964 dev_priv->sarea = NULL; 988 dev_priv->sarea = NULL;
965 dev_priv->sarea_priv = NULL; 989 dev_priv->sarea_priv = NULL;
966 dev->agp_buffer_map = NULL; 990 dev->agp_buffer_map = NULL;
967 991
992 if (full_cleanup) {
993 dev_priv->mmio = NULL;
994 dev_priv->status = NULL;
995 dev_priv->used_new_dma_init = 0;
996 }
997
968 memset(&dev_priv->prim, 0, sizeof(dev_priv->prim)); 998 memset(&dev_priv->prim, 0, sizeof(dev_priv->prim));
969 dev_priv->warp_pipe = 0; 999 dev_priv->warp_pipe = 0;
970 memset(dev_priv->warp_pipe_phys, 0, 1000 memset(dev_priv->warp_pipe_phys, 0,
@@ -975,7 +1005,7 @@ static int mga_do_cleanup_dma(drm_device_t * dev)
975 } 1005 }
976 } 1006 }
977 1007
978 return err; 1008 return 0;
979} 1009}
980 1010
981int mga_dma_init(DRM_IOCTL_ARGS) 1011int mga_dma_init(DRM_IOCTL_ARGS)
@@ -993,11 +1023,11 @@ int mga_dma_init(DRM_IOCTL_ARGS)
993 case MGA_INIT_DMA: 1023 case MGA_INIT_DMA:
994 err = mga_do_init_dma(dev, &init); 1024 err = mga_do_init_dma(dev, &init);
995 if (err) { 1025 if (err) {
996 (void)mga_do_cleanup_dma(dev); 1026 (void)mga_do_cleanup_dma(dev, FULL_CLEANUP);
997 } 1027 }
998 return err; 1028 return err;
999 case MGA_CLEANUP_DMA: 1029 case MGA_CLEANUP_DMA:
1000 return mga_do_cleanup_dma(dev); 1030 return mga_do_cleanup_dma(dev, FULL_CLEANUP);
1001 } 1031 }
1002 1032
1003 return DRM_ERR(EINVAL); 1033 return DRM_ERR(EINVAL);
@@ -1139,7 +1169,7 @@ int mga_driver_unload(drm_device_t * dev)
1139 */ 1169 */
1140void mga_driver_lastclose(drm_device_t * dev) 1170void mga_driver_lastclose(drm_device_t * dev)
1141{ 1171{
1142 mga_do_cleanup_dma(dev); 1172 mga_do_cleanup_dma(dev, FULL_CLEANUP);
1143} 1173}
1144 1174
1145int mga_driver_dma_quiescent(drm_device_t * dev) 1175int mga_driver_dma_quiescent(drm_device_t * dev)