diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-02-23 08:54:20 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2012-02-23 08:56:11 -0500 |
commit | ff5f4b0585620e5c158ecaad84d91c5bf3c5d0a1 (patch) | |
tree | 18867fdd805f1beefd3592bca76f4794bdc094b8 /drivers/gpu | |
parent | de67cba65944f26c0f147035bd62e30c5f456b96 (diff) | |
parent | 019d96cb55ade38a4b4a52bba0304e8cd681f30a (diff) |
Merge remote-tracking branch 'airlied/drm-next' into for-airlied
Manually resolve the conflict between the new enum drm property
helpers in drm-next and the new "force-dvi" option that the "audio" output
property gained in drm-intel-next.
While resolving this conflict, switch the new drm_prop_enum_list to
use the newly introduced enum defines instead of magic values.
Conflicts:
drivers/gpu/drm/i915/intel_modes.c
Signed-Off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Diffstat (limited to 'drivers/gpu')
63 files changed, 2531 insertions, 706 deletions
diff --git a/drivers/gpu/drm/drm_crtc.c b/drivers/gpu/drm/drm_crtc.c index 5e818a808ace..6fdaf6fe94eb 100644 --- a/drivers/gpu/drm/drm_crtc.c +++ b/drivers/gpu/drm/drm_crtc.c | |||
@@ -38,11 +38,6 @@ | |||
38 | #include "drm_edid.h" | 38 | #include "drm_edid.h" |
39 | #include "drm_fourcc.h" | 39 | #include "drm_fourcc.h" |
40 | 40 | ||
41 | struct drm_prop_enum_list { | ||
42 | int type; | ||
43 | char *name; | ||
44 | }; | ||
45 | |||
46 | /* Avoid boilerplate. I'm tired of typing. */ | 41 | /* Avoid boilerplate. I'm tired of typing. */ |
47 | #define DRM_ENUM_NAME_FN(fnname, list) \ | 42 | #define DRM_ENUM_NAME_FN(fnname, list) \ |
48 | char *fnname(int val) \ | 43 | char *fnname(int val) \ |
@@ -442,7 +437,7 @@ void drm_mode_remove(struct drm_connector *connector, | |||
442 | struct drm_display_mode *mode) | 437 | struct drm_display_mode *mode) |
443 | { | 438 | { |
444 | list_del(&mode->head); | 439 | list_del(&mode->head); |
445 | kfree(mode); | 440 | drm_mode_destroy(connector->dev, mode); |
446 | } | 441 | } |
447 | EXPORT_SYMBOL(drm_mode_remove); | 442 | EXPORT_SYMBOL(drm_mode_remove); |
448 | 443 | ||
@@ -454,7 +449,7 @@ EXPORT_SYMBOL(drm_mode_remove); | |||
454 | * @name: user visible name of the connector | 449 | * @name: user visible name of the connector |
455 | * | 450 | * |
456 | * LOCKING: | 451 | * LOCKING: |
457 | * Caller must hold @dev's mode_config lock. | 452 | * Takes mode config lock. |
458 | * | 453 | * |
459 | * Initialises a preallocated connector. Connectors should be | 454 | * Initialises a preallocated connector. Connectors should be |
460 | * subclassed as part of driver connector objects. | 455 | * subclassed as part of driver connector objects. |
@@ -497,7 +492,7 @@ EXPORT_SYMBOL(drm_connector_init); | |||
497 | * @connector: connector to cleanup | 492 | * @connector: connector to cleanup |
498 | * | 493 | * |
499 | * LOCKING: | 494 | * LOCKING: |
500 | * Caller must hold @dev's mode_config lock. | 495 | * Takes mode config lock. |
501 | * | 496 | * |
502 | * Cleans up the connector but doesn't free the object. | 497 | * Cleans up the connector but doesn't free the object. |
503 | */ | 498 | */ |
@@ -658,7 +653,6 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) | |||
658 | { | 653 | { |
659 | struct drm_property *edid; | 654 | struct drm_property *edid; |
660 | struct drm_property *dpms; | 655 | struct drm_property *dpms; |
661 | int i; | ||
662 | 656 | ||
663 | /* | 657 | /* |
664 | * Standard properties (apply to all connectors) | 658 | * Standard properties (apply to all connectors) |
@@ -668,11 +662,9 @@ static int drm_mode_create_standard_connector_properties(struct drm_device *dev) | |||
668 | "EDID", 0); | 662 | "EDID", 0); |
669 | dev->mode_config.edid_property = edid; | 663 | dev->mode_config.edid_property = edid; |
670 | 664 | ||
671 | dpms = drm_property_create(dev, DRM_MODE_PROP_ENUM, | 665 | dpms = drm_property_create_enum(dev, 0, |
672 | "DPMS", ARRAY_SIZE(drm_dpms_enum_list)); | 666 | "DPMS", drm_dpms_enum_list, |
673 | for (i = 0; i < ARRAY_SIZE(drm_dpms_enum_list); i++) | 667 | ARRAY_SIZE(drm_dpms_enum_list)); |
674 | drm_property_add_enum(dpms, i, drm_dpms_enum_list[i].type, | ||
675 | drm_dpms_enum_list[i].name); | ||
676 | dev->mode_config.dpms_property = dpms; | 668 | dev->mode_config.dpms_property = dpms; |
677 | 669 | ||
678 | return 0; | 670 | return 0; |
@@ -688,30 +680,21 @@ int drm_mode_create_dvi_i_properties(struct drm_device *dev) | |||
688 | { | 680 | { |
689 | struct drm_property *dvi_i_selector; | 681 | struct drm_property *dvi_i_selector; |
690 | struct drm_property *dvi_i_subconnector; | 682 | struct drm_property *dvi_i_subconnector; |
691 | int i; | ||
692 | 683 | ||
693 | if (dev->mode_config.dvi_i_select_subconnector_property) | 684 | if (dev->mode_config.dvi_i_select_subconnector_property) |
694 | return 0; | 685 | return 0; |
695 | 686 | ||
696 | dvi_i_selector = | 687 | dvi_i_selector = |
697 | drm_property_create(dev, DRM_MODE_PROP_ENUM, | 688 | drm_property_create_enum(dev, 0, |
698 | "select subconnector", | 689 | "select subconnector", |
690 | drm_dvi_i_select_enum_list, | ||
699 | ARRAY_SIZE(drm_dvi_i_select_enum_list)); | 691 | ARRAY_SIZE(drm_dvi_i_select_enum_list)); |
700 | for (i = 0; i < ARRAY_SIZE(drm_dvi_i_select_enum_list); i++) | ||
701 | drm_property_add_enum(dvi_i_selector, i, | ||
702 | drm_dvi_i_select_enum_list[i].type, | ||
703 | drm_dvi_i_select_enum_list[i].name); | ||
704 | dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector; | 692 | dev->mode_config.dvi_i_select_subconnector_property = dvi_i_selector; |
705 | 693 | ||
706 | dvi_i_subconnector = | 694 | dvi_i_subconnector = drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, |
707 | drm_property_create(dev, DRM_MODE_PROP_ENUM | | ||
708 | DRM_MODE_PROP_IMMUTABLE, | ||
709 | "subconnector", | 695 | "subconnector", |
696 | drm_dvi_i_subconnector_enum_list, | ||
710 | ARRAY_SIZE(drm_dvi_i_subconnector_enum_list)); | 697 | ARRAY_SIZE(drm_dvi_i_subconnector_enum_list)); |
711 | for (i = 0; i < ARRAY_SIZE(drm_dvi_i_subconnector_enum_list); i++) | ||
712 | drm_property_add_enum(dvi_i_subconnector, i, | ||
713 | drm_dvi_i_subconnector_enum_list[i].type, | ||
714 | drm_dvi_i_subconnector_enum_list[i].name); | ||
715 | dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector; | 698 | dev->mode_config.dvi_i_subconnector_property = dvi_i_subconnector; |
716 | 699 | ||
717 | return 0; | 700 | return 0; |
@@ -742,51 +725,33 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, | |||
742 | /* | 725 | /* |
743 | * Basic connector properties | 726 | * Basic connector properties |
744 | */ | 727 | */ |
745 | tv_selector = drm_property_create(dev, DRM_MODE_PROP_ENUM, | 728 | tv_selector = drm_property_create_enum(dev, 0, |
746 | "select subconnector", | 729 | "select subconnector", |
730 | drm_tv_select_enum_list, | ||
747 | ARRAY_SIZE(drm_tv_select_enum_list)); | 731 | ARRAY_SIZE(drm_tv_select_enum_list)); |
748 | for (i = 0; i < ARRAY_SIZE(drm_tv_select_enum_list); i++) | ||
749 | drm_property_add_enum(tv_selector, i, | ||
750 | drm_tv_select_enum_list[i].type, | ||
751 | drm_tv_select_enum_list[i].name); | ||
752 | dev->mode_config.tv_select_subconnector_property = tv_selector; | 732 | dev->mode_config.tv_select_subconnector_property = tv_selector; |
753 | 733 | ||
754 | tv_subconnector = | 734 | tv_subconnector = |
755 | drm_property_create(dev, DRM_MODE_PROP_ENUM | | 735 | drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, |
756 | DRM_MODE_PROP_IMMUTABLE, "subconnector", | 736 | "subconnector", |
737 | drm_tv_subconnector_enum_list, | ||
757 | ARRAY_SIZE(drm_tv_subconnector_enum_list)); | 738 | ARRAY_SIZE(drm_tv_subconnector_enum_list)); |
758 | for (i = 0; i < ARRAY_SIZE(drm_tv_subconnector_enum_list); i++) | ||
759 | drm_property_add_enum(tv_subconnector, i, | ||
760 | drm_tv_subconnector_enum_list[i].type, | ||
761 | drm_tv_subconnector_enum_list[i].name); | ||
762 | dev->mode_config.tv_subconnector_property = tv_subconnector; | 739 | dev->mode_config.tv_subconnector_property = tv_subconnector; |
763 | 740 | ||
764 | /* | 741 | /* |
765 | * Other, TV specific properties: margins & TV modes. | 742 | * Other, TV specific properties: margins & TV modes. |
766 | */ | 743 | */ |
767 | dev->mode_config.tv_left_margin_property = | 744 | dev->mode_config.tv_left_margin_property = |
768 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 745 | drm_property_create_range(dev, 0, "left margin", 0, 100); |
769 | "left margin", 2); | ||
770 | dev->mode_config.tv_left_margin_property->values[0] = 0; | ||
771 | dev->mode_config.tv_left_margin_property->values[1] = 100; | ||
772 | 746 | ||
773 | dev->mode_config.tv_right_margin_property = | 747 | dev->mode_config.tv_right_margin_property = |
774 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 748 | drm_property_create_range(dev, 0, "right margin", 0, 100); |
775 | "right margin", 2); | ||
776 | dev->mode_config.tv_right_margin_property->values[0] = 0; | ||
777 | dev->mode_config.tv_right_margin_property->values[1] = 100; | ||
778 | 749 | ||
779 | dev->mode_config.tv_top_margin_property = | 750 | dev->mode_config.tv_top_margin_property = |
780 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 751 | drm_property_create_range(dev, 0, "top margin", 0, 100); |
781 | "top margin", 2); | ||
782 | dev->mode_config.tv_top_margin_property->values[0] = 0; | ||
783 | dev->mode_config.tv_top_margin_property->values[1] = 100; | ||
784 | 752 | ||
785 | dev->mode_config.tv_bottom_margin_property = | 753 | dev->mode_config.tv_bottom_margin_property = |
786 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 754 | drm_property_create_range(dev, 0, "bottom margin", 0, 100); |
787 | "bottom margin", 2); | ||
788 | dev->mode_config.tv_bottom_margin_property->values[0] = 0; | ||
789 | dev->mode_config.tv_bottom_margin_property->values[1] = 100; | ||
790 | 755 | ||
791 | dev->mode_config.tv_mode_property = | 756 | dev->mode_config.tv_mode_property = |
792 | drm_property_create(dev, DRM_MODE_PROP_ENUM, | 757 | drm_property_create(dev, DRM_MODE_PROP_ENUM, |
@@ -796,40 +761,22 @@ int drm_mode_create_tv_properties(struct drm_device *dev, int num_modes, | |||
796 | i, modes[i]); | 761 | i, modes[i]); |
797 | 762 | ||
798 | dev->mode_config.tv_brightness_property = | 763 | dev->mode_config.tv_brightness_property = |
799 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 764 | drm_property_create_range(dev, 0, "brightness", 0, 100); |
800 | "brightness", 2); | ||
801 | dev->mode_config.tv_brightness_property->values[0] = 0; | ||
802 | dev->mode_config.tv_brightness_property->values[1] = 100; | ||
803 | 765 | ||
804 | dev->mode_config.tv_contrast_property = | 766 | dev->mode_config.tv_contrast_property = |
805 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 767 | drm_property_create_range(dev, 0, "contrast", 0, 100); |
806 | "contrast", 2); | ||
807 | dev->mode_config.tv_contrast_property->values[0] = 0; | ||
808 | dev->mode_config.tv_contrast_property->values[1] = 100; | ||
809 | 768 | ||
810 | dev->mode_config.tv_flicker_reduction_property = | 769 | dev->mode_config.tv_flicker_reduction_property = |
811 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 770 | drm_property_create_range(dev, 0, "flicker reduction", 0, 100); |
812 | "flicker reduction", 2); | ||
813 | dev->mode_config.tv_flicker_reduction_property->values[0] = 0; | ||
814 | dev->mode_config.tv_flicker_reduction_property->values[1] = 100; | ||
815 | 771 | ||
816 | dev->mode_config.tv_overscan_property = | 772 | dev->mode_config.tv_overscan_property = |
817 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 773 | drm_property_create_range(dev, 0, "overscan", 0, 100); |
818 | "overscan", 2); | ||
819 | dev->mode_config.tv_overscan_property->values[0] = 0; | ||
820 | dev->mode_config.tv_overscan_property->values[1] = 100; | ||
821 | 774 | ||
822 | dev->mode_config.tv_saturation_property = | 775 | dev->mode_config.tv_saturation_property = |
823 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 776 | drm_property_create_range(dev, 0, "saturation", 0, 100); |
824 | "saturation", 2); | ||
825 | dev->mode_config.tv_saturation_property->values[0] = 0; | ||
826 | dev->mode_config.tv_saturation_property->values[1] = 100; | ||
827 | 777 | ||
828 | dev->mode_config.tv_hue_property = | 778 | dev->mode_config.tv_hue_property = |
829 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 779 | drm_property_create_range(dev, 0, "hue", 0, 100); |
830 | "hue", 2); | ||
831 | dev->mode_config.tv_hue_property->values[0] = 0; | ||
832 | dev->mode_config.tv_hue_property->values[1] = 100; | ||
833 | 780 | ||
834 | return 0; | 781 | return 0; |
835 | } | 782 | } |
@@ -845,18 +792,14 @@ EXPORT_SYMBOL(drm_mode_create_tv_properties); | |||
845 | int drm_mode_create_scaling_mode_property(struct drm_device *dev) | 792 | int drm_mode_create_scaling_mode_property(struct drm_device *dev) |
846 | { | 793 | { |
847 | struct drm_property *scaling_mode; | 794 | struct drm_property *scaling_mode; |
848 | int i; | ||
849 | 795 | ||
850 | if (dev->mode_config.scaling_mode_property) | 796 | if (dev->mode_config.scaling_mode_property) |
851 | return 0; | 797 | return 0; |
852 | 798 | ||
853 | scaling_mode = | 799 | scaling_mode = |
854 | drm_property_create(dev, DRM_MODE_PROP_ENUM, "scaling mode", | 800 | drm_property_create_enum(dev, 0, "scaling mode", |
801 | drm_scaling_mode_enum_list, | ||
855 | ARRAY_SIZE(drm_scaling_mode_enum_list)); | 802 | ARRAY_SIZE(drm_scaling_mode_enum_list)); |
856 | for (i = 0; i < ARRAY_SIZE(drm_scaling_mode_enum_list); i++) | ||
857 | drm_property_add_enum(scaling_mode, i, | ||
858 | drm_scaling_mode_enum_list[i].type, | ||
859 | drm_scaling_mode_enum_list[i].name); | ||
860 | 803 | ||
861 | dev->mode_config.scaling_mode_property = scaling_mode; | 804 | dev->mode_config.scaling_mode_property = scaling_mode; |
862 | 805 | ||
@@ -874,18 +817,14 @@ EXPORT_SYMBOL(drm_mode_create_scaling_mode_property); | |||
874 | int drm_mode_create_dithering_property(struct drm_device *dev) | 817 | int drm_mode_create_dithering_property(struct drm_device *dev) |
875 | { | 818 | { |
876 | struct drm_property *dithering_mode; | 819 | struct drm_property *dithering_mode; |
877 | int i; | ||
878 | 820 | ||
879 | if (dev->mode_config.dithering_mode_property) | 821 | if (dev->mode_config.dithering_mode_property) |
880 | return 0; | 822 | return 0; |
881 | 823 | ||
882 | dithering_mode = | 824 | dithering_mode = |
883 | drm_property_create(dev, DRM_MODE_PROP_ENUM, "dithering", | 825 | drm_property_create_enum(dev, 0, "dithering", |
826 | drm_dithering_mode_enum_list, | ||
884 | ARRAY_SIZE(drm_dithering_mode_enum_list)); | 827 | ARRAY_SIZE(drm_dithering_mode_enum_list)); |
885 | for (i = 0; i < ARRAY_SIZE(drm_dithering_mode_enum_list); i++) | ||
886 | drm_property_add_enum(dithering_mode, i, | ||
887 | drm_dithering_mode_enum_list[i].type, | ||
888 | drm_dithering_mode_enum_list[i].name); | ||
889 | dev->mode_config.dithering_mode_property = dithering_mode; | 828 | dev->mode_config.dithering_mode_property = dithering_mode; |
890 | 829 | ||
891 | return 0; | 830 | return 0; |
@@ -902,20 +841,15 @@ EXPORT_SYMBOL(drm_mode_create_dithering_property); | |||
902 | int drm_mode_create_dirty_info_property(struct drm_device *dev) | 841 | int drm_mode_create_dirty_info_property(struct drm_device *dev) |
903 | { | 842 | { |
904 | struct drm_property *dirty_info; | 843 | struct drm_property *dirty_info; |
905 | int i; | ||
906 | 844 | ||
907 | if (dev->mode_config.dirty_info_property) | 845 | if (dev->mode_config.dirty_info_property) |
908 | return 0; | 846 | return 0; |
909 | 847 | ||
910 | dirty_info = | 848 | dirty_info = |
911 | drm_property_create(dev, DRM_MODE_PROP_ENUM | | 849 | drm_property_create_enum(dev, DRM_MODE_PROP_IMMUTABLE, |
912 | DRM_MODE_PROP_IMMUTABLE, | ||
913 | "dirty", | 850 | "dirty", |
851 | drm_dirty_info_enum_list, | ||
914 | ARRAY_SIZE(drm_dirty_info_enum_list)); | 852 | ARRAY_SIZE(drm_dirty_info_enum_list)); |
915 | for (i = 0; i < ARRAY_SIZE(drm_dirty_info_enum_list); i++) | ||
916 | drm_property_add_enum(dirty_info, i, | ||
917 | drm_dirty_info_enum_list[i].type, | ||
918 | drm_dirty_info_enum_list[i].name); | ||
919 | dev->mode_config.dirty_info_property = dirty_info; | 853 | dev->mode_config.dirty_info_property = dirty_info; |
920 | 854 | ||
921 | return 0; | 855 | return 0; |
@@ -1048,6 +982,9 @@ void drm_mode_config_cleanup(struct drm_device *dev) | |||
1048 | head) { | 982 | head) { |
1049 | plane->funcs->destroy(plane); | 983 | plane->funcs->destroy(plane); |
1050 | } | 984 | } |
985 | |||
986 | idr_remove_all(&dev->mode_config.crtc_idr); | ||
987 | idr_destroy(&dev->mode_config.crtc_idr); | ||
1051 | } | 988 | } |
1052 | EXPORT_SYMBOL(drm_mode_config_cleanup); | 989 | EXPORT_SYMBOL(drm_mode_config_cleanup); |
1053 | 990 | ||
@@ -1311,7 +1248,7 @@ out: | |||
1311 | * @arg: arg from ioctl | 1248 | * @arg: arg from ioctl |
1312 | * | 1249 | * |
1313 | * LOCKING: | 1250 | * LOCKING: |
1314 | * Caller? (FIXME) | 1251 | * Takes mode config lock. |
1315 | * | 1252 | * |
1316 | * Construct a CRTC configuration structure to return to the user. | 1253 | * Construct a CRTC configuration structure to return to the user. |
1317 | * | 1254 | * |
@@ -1371,7 +1308,7 @@ out: | |||
1371 | * @arg: arg from ioctl | 1308 | * @arg: arg from ioctl |
1372 | * | 1309 | * |
1373 | * LOCKING: | 1310 | * LOCKING: |
1374 | * Caller? (FIXME) | 1311 | * Takes mode config lock. |
1375 | * | 1312 | * |
1376 | * Construct a connector configuration structure to return to the user. | 1313 | * Construct a connector configuration structure to return to the user. |
1377 | * | 1314 | * |
@@ -1553,6 +1490,9 @@ out: | |||
1553 | * @data: ioctl data | 1490 | * @data: ioctl data |
1554 | * @file_priv: DRM file info | 1491 | * @file_priv: DRM file info |
1555 | * | 1492 | * |
1493 | * LOCKING: | ||
1494 | * Takes mode config lock. | ||
1495 | * | ||
1556 | * Return an plane count and set of IDs. | 1496 | * Return an plane count and set of IDs. |
1557 | */ | 1497 | */ |
1558 | int drm_mode_getplane_res(struct drm_device *dev, void *data, | 1498 | int drm_mode_getplane_res(struct drm_device *dev, void *data, |
@@ -1599,6 +1539,9 @@ out: | |||
1599 | * @data: ioctl data | 1539 | * @data: ioctl data |
1600 | * @file_priv: DRM file info | 1540 | * @file_priv: DRM file info |
1601 | * | 1541 | * |
1542 | * LOCKING: | ||
1543 | * Takes mode config lock. | ||
1544 | * | ||
1602 | * Return plane info, including formats supported, gamma size, any | 1545 | * Return plane info, including formats supported, gamma size, any |
1603 | * current fb, etc. | 1546 | * current fb, etc. |
1604 | */ | 1547 | */ |
@@ -1664,6 +1607,9 @@ out: | |||
1664 | * @data: ioctl data* | 1607 | * @data: ioctl data* |
1665 | * @file_prive: DRM file info | 1608 | * @file_prive: DRM file info |
1666 | * | 1609 | * |
1610 | * LOCKING: | ||
1611 | * Takes mode config lock. | ||
1612 | * | ||
1667 | * Set plane info, including placement, fb, scaling, and other factors. | 1613 | * Set plane info, including placement, fb, scaling, and other factors. |
1668 | * Or pass a NULL fb to disable. | 1614 | * Or pass a NULL fb to disable. |
1669 | */ | 1615 | */ |
@@ -1794,7 +1740,7 @@ out: | |||
1794 | * @arg: arg from ioctl | 1740 | * @arg: arg from ioctl |
1795 | * | 1741 | * |
1796 | * LOCKING: | 1742 | * LOCKING: |
1797 | * Caller? (FIXME) | 1743 | * Takes mode config lock. |
1798 | * | 1744 | * |
1799 | * Build a new CRTC configuration based on user request. | 1745 | * Build a new CRTC configuration based on user request. |
1800 | * | 1746 | * |
@@ -2275,7 +2221,7 @@ out: | |||
2275 | * @arg: arg from ioctl | 2221 | * @arg: arg from ioctl |
2276 | * | 2222 | * |
2277 | * LOCKING: | 2223 | * LOCKING: |
2278 | * Caller? (FIXME) | 2224 | * Takes mode config lock. |
2279 | * | 2225 | * |
2280 | * Lookup the FB given its ID and return info about it. | 2226 | * Lookup the FB given its ID and return info about it. |
2281 | * | 2227 | * |
@@ -2617,6 +2563,53 @@ fail: | |||
2617 | } | 2563 | } |
2618 | EXPORT_SYMBOL(drm_property_create); | 2564 | EXPORT_SYMBOL(drm_property_create); |
2619 | 2565 | ||
2566 | struct drm_property *drm_property_create_enum(struct drm_device *dev, int flags, | ||
2567 | const char *name, | ||
2568 | const struct drm_prop_enum_list *props, | ||
2569 | int num_values) | ||
2570 | { | ||
2571 | struct drm_property *property; | ||
2572 | int i, ret; | ||
2573 | |||
2574 | flags |= DRM_MODE_PROP_ENUM; | ||
2575 | |||
2576 | property = drm_property_create(dev, flags, name, num_values); | ||
2577 | if (!property) | ||
2578 | return NULL; | ||
2579 | |||
2580 | for (i = 0; i < num_values; i++) { | ||
2581 | ret = drm_property_add_enum(property, i, | ||
2582 | props[i].type, | ||
2583 | props[i].name); | ||
2584 | if (ret) { | ||
2585 | drm_property_destroy(dev, property); | ||
2586 | return NULL; | ||
2587 | } | ||
2588 | } | ||
2589 | |||
2590 | return property; | ||
2591 | } | ||
2592 | EXPORT_SYMBOL(drm_property_create_enum); | ||
2593 | |||
2594 | struct drm_property *drm_property_create_range(struct drm_device *dev, int flags, | ||
2595 | const char *name, | ||
2596 | uint64_t min, uint64_t max) | ||
2597 | { | ||
2598 | struct drm_property *property; | ||
2599 | |||
2600 | flags |= DRM_MODE_PROP_RANGE; | ||
2601 | |||
2602 | property = drm_property_create(dev, flags, name, 2); | ||
2603 | if (!property) | ||
2604 | return NULL; | ||
2605 | |||
2606 | property->values[0] = min; | ||
2607 | property->values[1] = max; | ||
2608 | |||
2609 | return property; | ||
2610 | } | ||
2611 | EXPORT_SYMBOL(drm_property_create_range); | ||
2612 | |||
2620 | int drm_property_add_enum(struct drm_property *property, int index, | 2613 | int drm_property_add_enum(struct drm_property *property, int index, |
2621 | uint64_t value, const char *name) | 2614 | uint64_t value, const char *name) |
2622 | { | 2615 | { |
@@ -3021,7 +3014,7 @@ void drm_mode_connector_detach_encoder(struct drm_connector *connector, | |||
3021 | } | 3014 | } |
3022 | EXPORT_SYMBOL(drm_mode_connector_detach_encoder); | 3015 | EXPORT_SYMBOL(drm_mode_connector_detach_encoder); |
3023 | 3016 | ||
3024 | bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, | 3017 | int drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, |
3025 | int gamma_size) | 3018 | int gamma_size) |
3026 | { | 3019 | { |
3027 | crtc->gamma_size = gamma_size; | 3020 | crtc->gamma_size = gamma_size; |
@@ -3029,10 +3022,10 @@ bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, | |||
3029 | crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); | 3022 | crtc->gamma_store = kzalloc(gamma_size * sizeof(uint16_t) * 3, GFP_KERNEL); |
3030 | if (!crtc->gamma_store) { | 3023 | if (!crtc->gamma_store) { |
3031 | crtc->gamma_size = 0; | 3024 | crtc->gamma_size = 0; |
3032 | return false; | 3025 | return -ENOMEM; |
3033 | } | 3026 | } |
3034 | 3027 | ||
3035 | return true; | 3028 | return 0; |
3036 | } | 3029 | } |
3037 | EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); | 3030 | EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); |
3038 | 3031 | ||
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c index 84a4a809793f..d761d1241152 100644 --- a/drivers/gpu/drm/drm_crtc_helper.c +++ b/drivers/gpu/drm/drm_crtc_helper.c | |||
@@ -44,12 +44,12 @@ module_param_named(poll, drm_kms_helper_poll, bool, 0600); | |||
44 | static void drm_mode_validate_flag(struct drm_connector *connector, | 44 | static void drm_mode_validate_flag(struct drm_connector *connector, |
45 | int flags) | 45 | int flags) |
46 | { | 46 | { |
47 | struct drm_display_mode *mode, *t; | 47 | struct drm_display_mode *mode; |
48 | 48 | ||
49 | if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE)) | 49 | if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE)) |
50 | return; | 50 | return; |
51 | 51 | ||
52 | list_for_each_entry_safe(mode, t, &connector->modes, head) { | 52 | list_for_each_entry(mode, &connector->modes, head) { |
53 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && | 53 | if ((mode->flags & DRM_MODE_FLAG_INTERLACE) && |
54 | !(flags & DRM_MODE_FLAG_INTERLACE)) | 54 | !(flags & DRM_MODE_FLAG_INTERLACE)) |
55 | mode->status = MODE_NO_INTERLACE; | 55 | mode->status = MODE_NO_INTERLACE; |
@@ -87,7 +87,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
87 | uint32_t maxX, uint32_t maxY) | 87 | uint32_t maxX, uint32_t maxY) |
88 | { | 88 | { |
89 | struct drm_device *dev = connector->dev; | 89 | struct drm_device *dev = connector->dev; |
90 | struct drm_display_mode *mode, *t; | 90 | struct drm_display_mode *mode; |
91 | struct drm_connector_helper_funcs *connector_funcs = | 91 | struct drm_connector_helper_funcs *connector_funcs = |
92 | connector->helper_private; | 92 | connector->helper_private; |
93 | int count = 0; | 93 | int count = 0; |
@@ -96,7 +96,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
96 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, | 96 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id, |
97 | drm_get_connector_name(connector)); | 97 | drm_get_connector_name(connector)); |
98 | /* set all modes to the unverified state */ | 98 | /* set all modes to the unverified state */ |
99 | list_for_each_entry_safe(mode, t, &connector->modes, head) | 99 | list_for_each_entry(mode, &connector->modes, head) |
100 | mode->status = MODE_UNVERIFIED; | 100 | mode->status = MODE_UNVERIFIED; |
101 | 101 | ||
102 | if (connector->force) { | 102 | if (connector->force) { |
@@ -136,7 +136,7 @@ int drm_helper_probe_single_connector_modes(struct drm_connector *connector, | |||
136 | mode_flags |= DRM_MODE_FLAG_DBLSCAN; | 136 | mode_flags |= DRM_MODE_FLAG_DBLSCAN; |
137 | drm_mode_validate_flag(connector, mode_flags); | 137 | drm_mode_validate_flag(connector, mode_flags); |
138 | 138 | ||
139 | list_for_each_entry_safe(mode, t, &connector->modes, head) { | 139 | list_for_each_entry(mode, &connector->modes, head) { |
140 | if (mode->status == MODE_OK) | 140 | if (mode->status == MODE_OK) |
141 | mode->status = connector_funcs->mode_valid(connector, | 141 | mode->status = connector_funcs->mode_valid(connector, |
142 | mode); | 142 | mode); |
@@ -152,7 +152,7 @@ prune: | |||
152 | 152 | ||
153 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, | 153 | DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id, |
154 | drm_get_connector_name(connector)); | 154 | drm_get_connector_name(connector)); |
155 | list_for_each_entry_safe(mode, t, &connector->modes, head) { | 155 | list_for_each_entry(mode, &connector->modes, head) { |
156 | mode->vrefresh = drm_mode_vrefresh(mode); | 156 | mode->vrefresh = drm_mode_vrefresh(mode); |
157 | 157 | ||
158 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); | 158 | drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V); |
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c index ebf7d3f68fc4..d166bd080400 100644 --- a/drivers/gpu/drm/drm_drv.c +++ b/drivers/gpu/drm/drm_drv.c | |||
@@ -135,23 +135,23 @@ static struct drm_ioctl_desc drm_ioctls[] = { | |||
135 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), | 135 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_FLINK, drm_gem_flink_ioctl, DRM_AUTH|DRM_UNLOCKED), |
136 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), | 136 | DRM_IOCTL_DEF(DRM_IOCTL_GEM_OPEN, drm_gem_open_ioctl, DRM_AUTH|DRM_UNLOCKED), |
137 | 137 | ||
138 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 138 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETRESOURCES, drm_mode_getresources, DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
139 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 139 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANERESOURCES, drm_mode_getplane_res, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
140 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 140 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCRTC, drm_mode_getcrtc, DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
141 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 141 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETCRTC, drm_mode_setcrtc, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
142 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 142 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPLANE, drm_mode_getplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
143 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 143 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPLANE, drm_mode_setplane, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
144 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 144 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_CURSOR, drm_mode_cursor_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
145 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_MASTER|DRM_UNLOCKED), | 145 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETGAMMA, drm_mode_gamma_get_ioctl, DRM_UNLOCKED), |
146 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), | 146 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETGAMMA, drm_mode_gamma_set_ioctl, DRM_MASTER|DRM_UNLOCKED), |
147 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 147 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETENCODER, drm_mode_getencoder, DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
148 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 148 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETCONNECTOR, drm_mode_getconnector, DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
149 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 149 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ATTACHMODE, drm_mode_attachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
150 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 150 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_DETACHMODE, drm_mode_detachmode_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
151 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 151 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPERTY, drm_mode_getproperty_ioctl, DRM_MASTER | DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
152 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 152 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_SETPROPERTY, drm_mode_connector_property_set_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
153 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 153 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETPROPBLOB, drm_mode_getblob_ioctl, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
154 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 154 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_GETFB, drm_mode_getfb, DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
155 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 155 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB, drm_mode_addfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
156 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 156 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_ADDFB2, drm_mode_addfb2, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
157 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), | 157 | DRM_IOCTL_DEF(DRM_IOCTL_MODE_RMFB, drm_mode_rmfb, DRM_MASTER|DRM_CONTROL_ALLOW|DRM_UNLOCKED), |
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c index ece03fc2d386..7ee7be1e5ce6 100644 --- a/drivers/gpu/drm/drm_edid.c +++ b/drivers/gpu/drm/drm_edid.c | |||
@@ -266,6 +266,11 @@ drm_do_probe_ddc_edid(struct i2c_adapter *adapter, unsigned char *buf, | |||
266 | } | 266 | } |
267 | }; | 267 | }; |
268 | ret = i2c_transfer(adapter, msgs, 2); | 268 | ret = i2c_transfer(adapter, msgs, 2); |
269 | if (ret == -ENXIO) { | ||
270 | DRM_DEBUG_KMS("drm: skipping non-existent adapter %s\n", | ||
271 | adapter->name); | ||
272 | break; | ||
273 | } | ||
269 | } while (ret != 2 && --retries); | 274 | } while (ret != 2 && --retries); |
270 | 275 | ||
271 | return ret == 2 ? 0 : -1; | 276 | return ret == 2 ? 0 : -1; |
@@ -745,7 +750,7 @@ drm_mode_std(struct drm_connector *connector, struct edid *edid, | |||
745 | */ | 750 | */ |
746 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); | 751 | mode = drm_gtf_mode(dev, hsize, vsize, vrefresh_rate, 0, 0); |
747 | if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { | 752 | if (drm_mode_hsync(mode) > drm_gtf2_hbreak(edid)) { |
748 | kfree(mode); | 753 | drm_mode_destroy(dev, mode); |
749 | mode = drm_gtf_mode_complex(dev, hsize, vsize, | 754 | mode = drm_gtf_mode_complex(dev, hsize, vsize, |
750 | vrefresh_rate, 0, 0, | 755 | vrefresh_rate, 0, 0, |
751 | drm_gtf2_m(edid), | 756 | drm_gtf2_m(edid), |
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c index aada26f63dec..7740dd26f007 100644 --- a/drivers/gpu/drm/drm_fb_helper.c +++ b/drivers/gpu/drm/drm_fb_helper.c | |||
@@ -306,91 +306,31 @@ static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { | |||
306 | static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; | 306 | static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; |
307 | #endif | 307 | #endif |
308 | 308 | ||
309 | static void drm_fb_helper_on(struct fb_info *info) | 309 | static void drm_fb_helper_dpms(struct fb_info *info, int dpms_mode) |
310 | { | 310 | { |
311 | struct drm_fb_helper *fb_helper = info->par; | 311 | struct drm_fb_helper *fb_helper = info->par; |
312 | struct drm_device *dev = fb_helper->dev; | 312 | struct drm_device *dev = fb_helper->dev; |
313 | struct drm_crtc *crtc; | 313 | struct drm_crtc *crtc; |
314 | struct drm_crtc_helper_funcs *crtc_funcs; | ||
315 | struct drm_connector *connector; | ||
316 | struct drm_encoder *encoder; | ||
317 | int i, j; | ||
318 | |||
319 | /* | ||
320 | * For each CRTC in this fb, turn the crtc on then, | ||
321 | * find all associated encoders and turn them on. | ||
322 | */ | ||
323 | mutex_lock(&dev->mode_config.mutex); | ||
324 | for (i = 0; i < fb_helper->crtc_count; i++) { | ||
325 | crtc = fb_helper->crtc_info[i].mode_set.crtc; | ||
326 | crtc_funcs = crtc->helper_private; | ||
327 | |||
328 | if (!crtc->enabled) | ||
329 | continue; | ||
330 | |||
331 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON); | ||
332 | |||
333 | /* Walk the connectors & encoders on this fb turning them on */ | ||
334 | for (j = 0; j < fb_helper->connector_count; j++) { | ||
335 | connector = fb_helper->connector_info[j]->connector; | ||
336 | connector->dpms = DRM_MODE_DPMS_ON; | ||
337 | drm_connector_property_set_value(connector, | ||
338 | dev->mode_config.dpms_property, | ||
339 | DRM_MODE_DPMS_ON); | ||
340 | } | ||
341 | /* Found a CRTC on this fb, now find encoders */ | ||
342 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
343 | if (encoder->crtc == crtc) { | ||
344 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
345 | |||
346 | encoder_funcs = encoder->helper_private; | ||
347 | encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON); | ||
348 | } | ||
349 | } | ||
350 | } | ||
351 | mutex_unlock(&dev->mode_config.mutex); | ||
352 | } | ||
353 | |||
354 | static void drm_fb_helper_off(struct fb_info *info, int dpms_mode) | ||
355 | { | ||
356 | struct drm_fb_helper *fb_helper = info->par; | ||
357 | struct drm_device *dev = fb_helper->dev; | ||
358 | struct drm_crtc *crtc; | ||
359 | struct drm_crtc_helper_funcs *crtc_funcs; | ||
360 | struct drm_connector *connector; | 314 | struct drm_connector *connector; |
361 | struct drm_encoder *encoder; | ||
362 | int i, j; | 315 | int i, j; |
363 | 316 | ||
364 | /* | 317 | /* |
365 | * For each CRTC in this fb, find all associated encoders | 318 | * For each CRTC in this fb, turn the connectors on/off. |
366 | * and turn them off, then turn off the CRTC. | ||
367 | */ | 319 | */ |
368 | mutex_lock(&dev->mode_config.mutex); | 320 | mutex_lock(&dev->mode_config.mutex); |
369 | for (i = 0; i < fb_helper->crtc_count; i++) { | 321 | for (i = 0; i < fb_helper->crtc_count; i++) { |
370 | crtc = fb_helper->crtc_info[i].mode_set.crtc; | 322 | crtc = fb_helper->crtc_info[i].mode_set.crtc; |
371 | crtc_funcs = crtc->helper_private; | ||
372 | 323 | ||
373 | if (!crtc->enabled) | 324 | if (!crtc->enabled) |
374 | continue; | 325 | continue; |
375 | 326 | ||
376 | /* Walk the connectors on this fb and mark them off */ | 327 | /* Walk the connectors & encoders on this fb turning them on/off */ |
377 | for (j = 0; j < fb_helper->connector_count; j++) { | 328 | for (j = 0; j < fb_helper->connector_count; j++) { |
378 | connector = fb_helper->connector_info[j]->connector; | 329 | connector = fb_helper->connector_info[j]->connector; |
379 | connector->dpms = dpms_mode; | 330 | drm_helper_connector_dpms(connector, dpms_mode); |
380 | drm_connector_property_set_value(connector, | 331 | drm_connector_property_set_value(connector, |
381 | dev->mode_config.dpms_property, | 332 | dev->mode_config.dpms_property, dpms_mode); |
382 | dpms_mode); | ||
383 | } | ||
384 | /* Found a CRTC on this fb, now find encoders */ | ||
385 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
386 | if (encoder->crtc == crtc) { | ||
387 | struct drm_encoder_helper_funcs *encoder_funcs; | ||
388 | |||
389 | encoder_funcs = encoder->helper_private; | ||
390 | encoder_funcs->dpms(encoder, dpms_mode); | ||
391 | } | ||
392 | } | 333 | } |
393 | crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF); | ||
394 | } | 334 | } |
395 | mutex_unlock(&dev->mode_config.mutex); | 335 | mutex_unlock(&dev->mode_config.mutex); |
396 | } | 336 | } |
@@ -400,23 +340,23 @@ int drm_fb_helper_blank(int blank, struct fb_info *info) | |||
400 | switch (blank) { | 340 | switch (blank) { |
401 | /* Display: On; HSync: On, VSync: On */ | 341 | /* Display: On; HSync: On, VSync: On */ |
402 | case FB_BLANK_UNBLANK: | 342 | case FB_BLANK_UNBLANK: |
403 | drm_fb_helper_on(info); | 343 | drm_fb_helper_dpms(info, DRM_MODE_DPMS_ON); |
404 | break; | 344 | break; |
405 | /* Display: Off; HSync: On, VSync: On */ | 345 | /* Display: Off; HSync: On, VSync: On */ |
406 | case FB_BLANK_NORMAL: | 346 | case FB_BLANK_NORMAL: |
407 | drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); | 347 | drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); |
408 | break; | 348 | break; |
409 | /* Display: Off; HSync: Off, VSync: On */ | 349 | /* Display: Off; HSync: Off, VSync: On */ |
410 | case FB_BLANK_HSYNC_SUSPEND: | 350 | case FB_BLANK_HSYNC_SUSPEND: |
411 | drm_fb_helper_off(info, DRM_MODE_DPMS_STANDBY); | 351 | drm_fb_helper_dpms(info, DRM_MODE_DPMS_STANDBY); |
412 | break; | 352 | break; |
413 | /* Display: Off; HSync: On, VSync: Off */ | 353 | /* Display: Off; HSync: On, VSync: Off */ |
414 | case FB_BLANK_VSYNC_SUSPEND: | 354 | case FB_BLANK_VSYNC_SUSPEND: |
415 | drm_fb_helper_off(info, DRM_MODE_DPMS_SUSPEND); | 355 | drm_fb_helper_dpms(info, DRM_MODE_DPMS_SUSPEND); |
416 | break; | 356 | break; |
417 | /* Display: Off; HSync: Off, VSync: Off */ | 357 | /* Display: Off; HSync: Off, VSync: Off */ |
418 | case FB_BLANK_POWERDOWN: | 358 | case FB_BLANK_POWERDOWN: |
419 | drm_fb_helper_off(info, DRM_MODE_DPMS_OFF); | 359 | drm_fb_helper_dpms(info, DRM_MODE_DPMS_OFF); |
420 | break; | 360 | break; |
421 | } | 361 | } |
422 | return 0; | 362 | return 0; |
@@ -430,8 +370,11 @@ static void drm_fb_helper_crtc_free(struct drm_fb_helper *helper) | |||
430 | for (i = 0; i < helper->connector_count; i++) | 370 | for (i = 0; i < helper->connector_count; i++) |
431 | kfree(helper->connector_info[i]); | 371 | kfree(helper->connector_info[i]); |
432 | kfree(helper->connector_info); | 372 | kfree(helper->connector_info); |
433 | for (i = 0; i < helper->crtc_count; i++) | 373 | for (i = 0; i < helper->crtc_count; i++) { |
434 | kfree(helper->crtc_info[i].mode_set.connectors); | 374 | kfree(helper->crtc_info[i].mode_set.connectors); |
375 | if (helper->crtc_info[i].mode_set.mode) | ||
376 | drm_mode_destroy(helper->dev, helper->crtc_info[i].mode_set.mode); | ||
377 | } | ||
435 | kfree(helper->crtc_info); | 378 | kfree(helper->crtc_info); |
436 | } | 379 | } |
437 | 380 | ||
@@ -474,11 +417,10 @@ int drm_fb_helper_init(struct drm_device *dev, | |||
474 | 417 | ||
475 | i = 0; | 418 | i = 0; |
476 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { | 419 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { |
477 | fb_helper->crtc_info[i].crtc_id = crtc->base.id; | ||
478 | fb_helper->crtc_info[i].mode_set.crtc = crtc; | 420 | fb_helper->crtc_info[i].mode_set.crtc = crtc; |
479 | i++; | 421 | i++; |
480 | } | 422 | } |
481 | fb_helper->conn_limit = max_conn_count; | 423 | |
482 | return 0; | 424 | return 0; |
483 | out_free: | 425 | out_free: |
484 | drm_fb_helper_crtc_free(fb_helper); | 426 | drm_fb_helper_crtc_free(fb_helper); |
diff --git a/drivers/gpu/drm/drm_ioctl.c b/drivers/gpu/drm/drm_ioctl.c index 2300ab1a2a77..cf85155da2a0 100644 --- a/drivers/gpu/drm/drm_ioctl.c +++ b/drivers/gpu/drm/drm_ioctl.c | |||
@@ -277,6 +277,12 @@ int drm_getcap(struct drm_device *dev, void *data, struct drm_file *file_priv) | |||
277 | case DRM_CAP_VBLANK_HIGH_CRTC: | 277 | case DRM_CAP_VBLANK_HIGH_CRTC: |
278 | req->value = 1; | 278 | req->value = 1; |
279 | break; | 279 | break; |
280 | case DRM_CAP_DUMB_PREFERRED_DEPTH: | ||
281 | req->value = dev->mode_config.preferred_depth; | ||
282 | break; | ||
283 | case DRM_CAP_DUMB_PREFER_SHADOW: | ||
284 | req->value = dev->mode_config.prefer_shadow; | ||
285 | break; | ||
280 | default: | 286 | default: |
281 | return -EINVAL; | 287 | return -EINVAL; |
282 | } | 288 | } |
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index fb8e46b4e8bc..7ff13bc47ca2 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c | |||
@@ -686,8 +686,6 @@ void drm_mode_set_crtcinfo(struct drm_display_mode *p, int adjust_flags) | |||
686 | p->crtc_vsync_end /= 2; | 686 | p->crtc_vsync_end /= 2; |
687 | p->crtc_vtotal /= 2; | 687 | p->crtc_vtotal /= 2; |
688 | } | 688 | } |
689 | |||
690 | p->crtc_vtotal |= 1; | ||
691 | } | 689 | } |
692 | 690 | ||
693 | if (p->flags & DRM_MODE_FLAG_DBLSCAN) { | 691 | if (p->flags & DRM_MODE_FLAG_DBLSCAN) { |
diff --git a/drivers/gpu/drm/drm_pci.c b/drivers/gpu/drm/drm_pci.c index d4d10b7880cf..13f3d936472f 100644 --- a/drivers/gpu/drm/drm_pci.c +++ b/drivers/gpu/drm/drm_pci.c | |||
@@ -324,8 +324,6 @@ int drm_get_pci_dev(struct pci_dev *pdev, const struct pci_device_id *ent, | |||
324 | if (ret) | 324 | if (ret) |
325 | goto err_g1; | 325 | goto err_g1; |
326 | 326 | ||
327 | pci_set_master(pdev); | ||
328 | |||
329 | dev->pdev = pdev; | 327 | dev->pdev = pdev; |
330 | dev->dev = &pdev->dev; | 328 | dev->dev = &pdev->dev; |
331 | 329 | ||
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c index d7ae29d2f3d6..5737bc5e6ed2 100644 --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c | |||
@@ -46,39 +46,13 @@ struct exynos_drm_fbdev { | |||
46 | struct exynos_drm_gem_obj *exynos_gem_obj; | 46 | struct exynos_drm_gem_obj *exynos_gem_obj; |
47 | }; | 47 | }; |
48 | 48 | ||
49 | static int exynos_drm_fbdev_set_par(struct fb_info *info) | ||
50 | { | ||
51 | struct fb_var_screeninfo *var = &info->var; | ||
52 | |||
53 | switch (var->bits_per_pixel) { | ||
54 | case 32: | ||
55 | case 24: | ||
56 | case 18: | ||
57 | case 16: | ||
58 | case 12: | ||
59 | info->fix.visual = FB_VISUAL_TRUECOLOR; | ||
60 | break; | ||
61 | case 1: | ||
62 | info->fix.visual = FB_VISUAL_MONO01; | ||
63 | break; | ||
64 | default: | ||
65 | info->fix.visual = FB_VISUAL_PSEUDOCOLOR; | ||
66 | break; | ||
67 | } | ||
68 | |||
69 | info->fix.line_length = (var->xres_virtual * var->bits_per_pixel) / 8; | ||
70 | |||
71 | return drm_fb_helper_set_par(info); | ||
72 | } | ||
73 | |||
74 | |||
75 | static struct fb_ops exynos_drm_fb_ops = { | 49 | static struct fb_ops exynos_drm_fb_ops = { |
76 | .owner = THIS_MODULE, | 50 | .owner = THIS_MODULE, |
77 | .fb_fillrect = cfb_fillrect, | 51 | .fb_fillrect = cfb_fillrect, |
78 | .fb_copyarea = cfb_copyarea, | 52 | .fb_copyarea = cfb_copyarea, |
79 | .fb_imageblit = cfb_imageblit, | 53 | .fb_imageblit = cfb_imageblit, |
80 | .fb_check_var = drm_fb_helper_check_var, | 54 | .fb_check_var = drm_fb_helper_check_var, |
81 | .fb_set_par = exynos_drm_fbdev_set_par, | 55 | .fb_set_par = drm_fb_helper_set_par, |
82 | .fb_blank = drm_fb_helper_blank, | 56 | .fb_blank = drm_fb_helper_blank, |
83 | .fb_pan_display = drm_fb_helper_pan_display, | 57 | .fb_pan_display = drm_fb_helper_pan_display, |
84 | .fb_setcmap = drm_fb_helper_setcmap, | 58 | .fb_setcmap = drm_fb_helper_setcmap, |
diff --git a/drivers/gpu/drm/gma500/framebuffer.c b/drivers/gpu/drm/gma500/framebuffer.c index 830dfdd6bf15..c1c4dc174fa2 100644 --- a/drivers/gpu/drm/gma500/framebuffer.c +++ b/drivers/gpu/drm/gma500/framebuffer.c | |||
@@ -507,11 +507,7 @@ static int psbfb_create(struct psb_fbdev *fbdev, | |||
507 | info->fix.mmio_start = pci_resource_start(dev->pdev, 0); | 507 | info->fix.mmio_start = pci_resource_start(dev->pdev, 0); |
508 | info->fix.mmio_len = pci_resource_len(dev->pdev, 0); | 508 | info->fix.mmio_len = pci_resource_len(dev->pdev, 0); |
509 | 509 | ||
510 | info->pixmap.size = 64 * 1024; | 510 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
511 | info->pixmap.buf_align = 8; | ||
512 | info->pixmap.access_align = 32; | ||
513 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
514 | info->pixmap.scan_align = 1; | ||
515 | 511 | ||
516 | dev_info(dev->dev, "allocated %dx%d fb\n", | 512 | dev_info(dev->dev, "allocated %dx%d fb\n", |
517 | psbfb->base.width, psbfb->base.height); | 513 | psbfb->base.width, psbfb->base.height); |
@@ -725,10 +721,7 @@ static int psb_create_backlight_property(struct drm_device *dev) | |||
725 | if (dev_priv->backlight_property) | 721 | if (dev_priv->backlight_property) |
726 | return 0; | 722 | return 0; |
727 | 723 | ||
728 | backlight = drm_property_create(dev, DRM_MODE_PROP_RANGE, | 724 | backlight = drm_property_create_range(dev, 0, "backlight", 0, 100); |
729 | "backlight", 2); | ||
730 | backlight->values[0] = 0; | ||
731 | backlight->values[1] = 100; | ||
732 | 725 | ||
733 | dev_priv->backlight_property = backlight; | 726 | dev_priv->backlight_property = backlight; |
734 | 727 | ||
diff --git a/drivers/gpu/drm/gma500/intel_gmbus.c b/drivers/gpu/drm/gma500/intel_gmbus.c index 147584ac8d02..9db90527bf0f 100644 --- a/drivers/gpu/drm/gma500/intel_gmbus.c +++ b/drivers/gpu/drm/gma500/intel_gmbus.c | |||
@@ -395,7 +395,7 @@ int gma_intel_setup_gmbus(struct drm_device *dev) | |||
395 | struct drm_psb_private *dev_priv = dev->dev_private; | 395 | struct drm_psb_private *dev_priv = dev->dev_private; |
396 | int ret, i; | 396 | int ret, i; |
397 | 397 | ||
398 | dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS, | 398 | dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus), |
399 | GFP_KERNEL); | 399 | GFP_KERNEL); |
400 | if (dev_priv->gmbus == NULL) | 400 | if (dev_priv->gmbus == NULL) |
401 | return -ENOMEM; | 401 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/gma500/psb_drv.c b/drivers/gpu/drm/gma500/psb_drv.c index f14768f2b364..1f57aac2cf80 100644 --- a/drivers/gpu/drm/gma500/psb_drv.c +++ b/drivers/gpu/drm/gma500/psb_drv.c | |||
@@ -283,6 +283,8 @@ static int psb_driver_load(struct drm_device *dev, unsigned long chipset) | |||
283 | dev_priv->dev = dev; | 283 | dev_priv->dev = dev; |
284 | dev->dev_private = (void *) dev_priv; | 284 | dev->dev_private = (void *) dev_priv; |
285 | 285 | ||
286 | pci_set_master(dev->pdev); | ||
287 | |||
286 | if (!IS_PSB(dev)) { | 288 | if (!IS_PSB(dev)) { |
287 | if (pci_enable_msi(dev->pdev)) | 289 | if (pci_enable_msi(dev->pdev)) |
288 | dev_warn(dev->dev, "Enabling MSI failed!\n"); | 290 | dev_warn(dev->dev, "Enabling MSI failed!\n"); |
diff --git a/drivers/gpu/drm/gma500/psb_intel_sdvo.c b/drivers/gpu/drm/gma500/psb_intel_sdvo.c index 88b42971c0fd..41b55d7a7bf8 100644 --- a/drivers/gpu/drm/gma500/psb_intel_sdvo.c +++ b/drivers/gpu/drm/gma500/psb_intel_sdvo.c | |||
@@ -2312,10 +2312,8 @@ static bool psb_intel_sdvo_tv_create_property(struct psb_intel_sdvo *psb_intel_s | |||
2312 | psb_intel_sdvo_connector->max_##name = data_value[0]; \ | 2312 | psb_intel_sdvo_connector->max_##name = data_value[0]; \ |
2313 | psb_intel_sdvo_connector->cur_##name = response; \ | 2313 | psb_intel_sdvo_connector->cur_##name = response; \ |
2314 | psb_intel_sdvo_connector->name = \ | 2314 | psb_intel_sdvo_connector->name = \ |
2315 | drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ | 2315 | drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ |
2316 | if (!psb_intel_sdvo_connector->name) return false; \ | 2316 | if (!psb_intel_sdvo_connector->name) return false; \ |
2317 | psb_intel_sdvo_connector->name->values[0] = 0; \ | ||
2318 | psb_intel_sdvo_connector->name->values[1] = data_value[0]; \ | ||
2319 | drm_connector_attach_property(connector, \ | 2317 | drm_connector_attach_property(connector, \ |
2320 | psb_intel_sdvo_connector->name, \ | 2318 | psb_intel_sdvo_connector->name, \ |
2321 | psb_intel_sdvo_connector->cur_##name); \ | 2319 | psb_intel_sdvo_connector->cur_##name); \ |
@@ -2349,25 +2347,19 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, | |||
2349 | psb_intel_sdvo_connector->left_margin = data_value[0] - response; | 2347 | psb_intel_sdvo_connector->left_margin = data_value[0] - response; |
2350 | psb_intel_sdvo_connector->right_margin = psb_intel_sdvo_connector->left_margin; | 2348 | psb_intel_sdvo_connector->right_margin = psb_intel_sdvo_connector->left_margin; |
2351 | psb_intel_sdvo_connector->left = | 2349 | psb_intel_sdvo_connector->left = |
2352 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2350 | drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); |
2353 | "left_margin", 2); | ||
2354 | if (!psb_intel_sdvo_connector->left) | 2351 | if (!psb_intel_sdvo_connector->left) |
2355 | return false; | 2352 | return false; |
2356 | 2353 | ||
2357 | psb_intel_sdvo_connector->left->values[0] = 0; | ||
2358 | psb_intel_sdvo_connector->left->values[1] = data_value[0]; | ||
2359 | drm_connector_attach_property(connector, | 2354 | drm_connector_attach_property(connector, |
2360 | psb_intel_sdvo_connector->left, | 2355 | psb_intel_sdvo_connector->left, |
2361 | psb_intel_sdvo_connector->left_margin); | 2356 | psb_intel_sdvo_connector->left_margin); |
2362 | 2357 | ||
2363 | psb_intel_sdvo_connector->right = | 2358 | psb_intel_sdvo_connector->right = |
2364 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2359 | drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); |
2365 | "right_margin", 2); | ||
2366 | if (!psb_intel_sdvo_connector->right) | 2360 | if (!psb_intel_sdvo_connector->right) |
2367 | return false; | 2361 | return false; |
2368 | 2362 | ||
2369 | psb_intel_sdvo_connector->right->values[0] = 0; | ||
2370 | psb_intel_sdvo_connector->right->values[1] = data_value[0]; | ||
2371 | drm_connector_attach_property(connector, | 2363 | drm_connector_attach_property(connector, |
2372 | psb_intel_sdvo_connector->right, | 2364 | psb_intel_sdvo_connector->right, |
2373 | psb_intel_sdvo_connector->right_margin); | 2365 | psb_intel_sdvo_connector->right_margin); |
@@ -2391,25 +2383,19 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, | |||
2391 | psb_intel_sdvo_connector->top_margin = data_value[0] - response; | 2383 | psb_intel_sdvo_connector->top_margin = data_value[0] - response; |
2392 | psb_intel_sdvo_connector->bottom_margin = psb_intel_sdvo_connector->top_margin; | 2384 | psb_intel_sdvo_connector->bottom_margin = psb_intel_sdvo_connector->top_margin; |
2393 | psb_intel_sdvo_connector->top = | 2385 | psb_intel_sdvo_connector->top = |
2394 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2386 | drm_property_create_range(dev, 0, "top_margin", 0, data_value[0]); |
2395 | "top_margin", 2); | ||
2396 | if (!psb_intel_sdvo_connector->top) | 2387 | if (!psb_intel_sdvo_connector->top) |
2397 | return false; | 2388 | return false; |
2398 | 2389 | ||
2399 | psb_intel_sdvo_connector->top->values[0] = 0; | ||
2400 | psb_intel_sdvo_connector->top->values[1] = data_value[0]; | ||
2401 | drm_connector_attach_property(connector, | 2390 | drm_connector_attach_property(connector, |
2402 | psb_intel_sdvo_connector->top, | 2391 | psb_intel_sdvo_connector->top, |
2403 | psb_intel_sdvo_connector->top_margin); | 2392 | psb_intel_sdvo_connector->top_margin); |
2404 | 2393 | ||
2405 | psb_intel_sdvo_connector->bottom = | 2394 | psb_intel_sdvo_connector->bottom = |
2406 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2395 | drm_property_create_range(dev, 0, "bottom_margin", 0, data_value[0]); |
2407 | "bottom_margin", 2); | ||
2408 | if (!psb_intel_sdvo_connector->bottom) | 2396 | if (!psb_intel_sdvo_connector->bottom) |
2409 | return false; | 2397 | return false; |
2410 | 2398 | ||
2411 | psb_intel_sdvo_connector->bottom->values[0] = 0; | ||
2412 | psb_intel_sdvo_connector->bottom->values[1] = data_value[0]; | ||
2413 | drm_connector_attach_property(connector, | 2399 | drm_connector_attach_property(connector, |
2414 | psb_intel_sdvo_connector->bottom, | 2400 | psb_intel_sdvo_connector->bottom, |
2415 | psb_intel_sdvo_connector->bottom_margin); | 2401 | psb_intel_sdvo_connector->bottom_margin); |
@@ -2438,12 +2424,10 @@ psb_intel_sdvo_create_enhance_property_tv(struct psb_intel_sdvo *psb_intel_sdvo, | |||
2438 | psb_intel_sdvo_connector->max_dot_crawl = 1; | 2424 | psb_intel_sdvo_connector->max_dot_crawl = 1; |
2439 | psb_intel_sdvo_connector->cur_dot_crawl = response & 0x1; | 2425 | psb_intel_sdvo_connector->cur_dot_crawl = response & 0x1; |
2440 | psb_intel_sdvo_connector->dot_crawl = | 2426 | psb_intel_sdvo_connector->dot_crawl = |
2441 | drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); | 2427 | drm_property_create_range(dev, 0, "dot_crawl", 0, 1); |
2442 | if (!psb_intel_sdvo_connector->dot_crawl) | 2428 | if (!psb_intel_sdvo_connector->dot_crawl) |
2443 | return false; | 2429 | return false; |
2444 | 2430 | ||
2445 | psb_intel_sdvo_connector->dot_crawl->values[0] = 0; | ||
2446 | psb_intel_sdvo_connector->dot_crawl->values[1] = 1; | ||
2447 | drm_connector_attach_property(connector, | 2431 | drm_connector_attach_property(connector, |
2448 | psb_intel_sdvo_connector->dot_crawl, | 2432 | psb_intel_sdvo_connector->dot_crawl, |
2449 | psb_intel_sdvo_connector->cur_dot_crawl); | 2433 | psb_intel_sdvo_connector->cur_dot_crawl); |
diff --git a/drivers/gpu/drm/i2c/ch7006_drv.c b/drivers/gpu/drm/i2c/ch7006_drv.c index 07d55df6623e..d3f2e8785010 100644 --- a/drivers/gpu/drm/i2c/ch7006_drv.c +++ b/drivers/gpu/drm/i2c/ch7006_drv.c | |||
@@ -252,10 +252,7 @@ static int ch7006_encoder_create_resources(struct drm_encoder *encoder, | |||
252 | 252 | ||
253 | drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names); | 253 | drm_mode_create_tv_properties(dev, NUM_TV_NORMS, ch7006_tv_norm_names); |
254 | 254 | ||
255 | priv->scale_property = drm_property_create(dev, DRM_MODE_PROP_RANGE, | 255 | priv->scale_property = drm_property_create_range(dev, 0, "scale", 0, 2); |
256 | "scale", 2); | ||
257 | priv->scale_property->values[0] = 0; | ||
258 | priv->scale_property->values[1] = 2; | ||
259 | 256 | ||
260 | drm_connector_attach_property(connector, conf->tv_select_subconnector_property, | 257 | drm_connector_attach_property(connector, conf->tv_select_subconnector_property, |
261 | priv->select_subconnector); | 258 | priv->select_subconnector); |
diff --git a/drivers/gpu/drm/i810/i810_dma.c b/drivers/gpu/drm/i810/i810_dma.c index 7f4b4e10246e..64a989ed5b8f 100644 --- a/drivers/gpu/drm/i810/i810_dma.c +++ b/drivers/gpu/drm/i810/i810_dma.c | |||
@@ -1208,6 +1208,8 @@ int i810_driver_load(struct drm_device *dev, unsigned long flags) | |||
1208 | dev->types[8] = _DRM_STAT_SECONDARY; | 1208 | dev->types[8] = _DRM_STAT_SECONDARY; |
1209 | dev->types[9] = _DRM_STAT_DMA; | 1209 | dev->types[9] = _DRM_STAT_DMA; |
1210 | 1210 | ||
1211 | pci_set_master(dev->pdev); | ||
1212 | |||
1211 | return 0; | 1213 | return 0; |
1212 | } | 1214 | } |
1213 | 1215 | ||
diff --git a/drivers/gpu/drm/i915/i915_dma.c b/drivers/gpu/drm/i915/i915_dma.c index 39728fbb3f07..9341eb8ce93b 100644 --- a/drivers/gpu/drm/i915/i915_dma.c +++ b/drivers/gpu/drm/i915/i915_dma.c | |||
@@ -1951,6 +1951,8 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags) | |||
1951 | goto free_priv; | 1951 | goto free_priv; |
1952 | } | 1952 | } |
1953 | 1953 | ||
1954 | pci_set_master(dev->pdev); | ||
1955 | |||
1954 | /* overlay on gen2 is broken and can't address above 1G */ | 1956 | /* overlay on gen2 is broken and can't address above 1G */ |
1955 | if (IS_GEN2(dev)) | 1957 | if (IS_GEN2(dev)) |
1956 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); | 1958 | dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30)); |
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index cdcf99bf9de8..b65dc04f1289 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -9098,6 +9098,9 @@ void intel_modeset_init(struct drm_device *dev) | |||
9098 | dev->mode_config.min_width = 0; | 9098 | dev->mode_config.min_width = 0; |
9099 | dev->mode_config.min_height = 0; | 9099 | dev->mode_config.min_height = 0; |
9100 | 9100 | ||
9101 | dev->mode_config.preferred_depth = 24; | ||
9102 | dev->mode_config.prefer_shadow = 1; | ||
9103 | |||
9101 | dev->mode_config.funcs = (void *)&intel_mode_funcs; | 9104 | dev->mode_config.funcs = (void *)&intel_mode_funcs; |
9102 | 9105 | ||
9103 | intel_init_quirks(dev); | 9106 | intel_init_quirks(dev); |
diff --git a/drivers/gpu/drm/i915/intel_fb.c b/drivers/gpu/drm/i915/intel_fb.c index 571375a3eef4..2d8766978388 100644 --- a/drivers/gpu/drm/i915/intel_fb.c +++ b/drivers/gpu/drm/i915/intel_fb.c | |||
@@ -152,11 +152,7 @@ static int intelfb_create(struct intel_fbdev *ifbdev, | |||
152 | drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); | 152 | drm_fb_helper_fill_fix(info, fb->pitches[0], fb->depth); |
153 | drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); | 153 | drm_fb_helper_fill_var(info, &ifbdev->helper, sizes->fb_width, sizes->fb_height); |
154 | 154 | ||
155 | info->pixmap.size = 64*1024; | 155 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
156 | info->pixmap.buf_align = 8; | ||
157 | info->pixmap.access_align = 32; | ||
158 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
159 | info->pixmap.scan_align = 1; | ||
160 | 156 | ||
161 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", | 157 | DRM_DEBUG_KMS("allocated %dx%d fb: 0x%08x, bo %p\n", |
162 | fb->width, fb->height, | 158 | fb->width, fb->height, |
diff --git a/drivers/gpu/drm/i915/intel_i2c.c b/drivers/gpu/drm/i915/intel_i2c.c index fc75d71de53b..068617f7256a 100644 --- a/drivers/gpu/drm/i915/intel_i2c.c +++ b/drivers/gpu/drm/i915/intel_i2c.c | |||
@@ -37,7 +37,7 @@ | |||
37 | 37 | ||
38 | /* Intel GPIO access functions */ | 38 | /* Intel GPIO access functions */ |
39 | 39 | ||
40 | #define I2C_RISEFALL_TIME 20 | 40 | #define I2C_RISEFALL_TIME 10 |
41 | 41 | ||
42 | static inline struct intel_gmbus * | 42 | static inline struct intel_gmbus * |
43 | to_intel_gmbus(struct i2c_adapter *i2c) | 43 | to_intel_gmbus(struct i2c_adapter *i2c) |
@@ -383,7 +383,7 @@ int intel_setup_gmbus(struct drm_device *dev) | |||
383 | struct drm_i915_private *dev_priv = dev->dev_private; | 383 | struct drm_i915_private *dev_priv = dev->dev_private; |
384 | int ret, i; | 384 | int ret, i; |
385 | 385 | ||
386 | dev_priv->gmbus = kcalloc(sizeof(struct intel_gmbus), GMBUS_NUM_PORTS, | 386 | dev_priv->gmbus = kcalloc(GMBUS_NUM_PORTS, sizeof(struct intel_gmbus), |
387 | GFP_KERNEL); | 387 | GFP_KERNEL); |
388 | if (dev_priv->gmbus == NULL) | 388 | if (dev_priv->gmbus == NULL) |
389 | return -ENOMEM; | 389 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/i915/intel_modes.c b/drivers/gpu/drm/i915/intel_modes.c index 7be46163f421..2978a3f61b58 100644 --- a/drivers/gpu/drm/i915/intel_modes.c +++ b/drivers/gpu/drm/i915/intel_modes.c | |||
@@ -83,11 +83,11 @@ int intel_ddc_get_modes(struct drm_connector *connector, | |||
83 | return ret; | 83 | return ret; |
84 | } | 84 | } |
85 | 85 | ||
86 | static const char *force_audio_names[] = { | 86 | static const struct drm_prop_enum_list force_audio_names[] = { |
87 | "force-dvi", | 87 | { HDMI_AUDIO_OFF_DVI, "force-dvi" }, |
88 | "off", | 88 | { HDMI_AUDIO_OFF, "off" }, |
89 | "auto", | 89 | { HDMI_AUDIO_AUTO, "auto" }, |
90 | "on", | 90 | { HDMI_AUDIO_ON, "on" }, |
91 | }; | 91 | }; |
92 | 92 | ||
93 | void | 93 | void |
@@ -96,28 +96,24 @@ intel_attach_force_audio_property(struct drm_connector *connector) | |||
96 | struct drm_device *dev = connector->dev; | 96 | struct drm_device *dev = connector->dev; |
97 | struct drm_i915_private *dev_priv = dev->dev_private; | 97 | struct drm_i915_private *dev_priv = dev->dev_private; |
98 | struct drm_property *prop; | 98 | struct drm_property *prop; |
99 | int i; | ||
100 | 99 | ||
101 | prop = dev_priv->force_audio_property; | 100 | prop = dev_priv->force_audio_property; |
102 | if (prop == NULL) { | 101 | if (prop == NULL) { |
103 | prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, | 102 | prop = drm_property_create_enum(dev, 0, |
104 | "audio", | 103 | "audio", |
104 | force_audio_names, | ||
105 | ARRAY_SIZE(force_audio_names)); | 105 | ARRAY_SIZE(force_audio_names)); |
106 | if (prop == NULL) | 106 | if (prop == NULL) |
107 | return; | 107 | return; |
108 | 108 | ||
109 | for (i = 0; i < ARRAY_SIZE(force_audio_names); i++) | ||
110 | drm_property_add_enum(prop, i, i-2, | ||
111 | force_audio_names[i]); | ||
112 | |||
113 | dev_priv->force_audio_property = prop; | 109 | dev_priv->force_audio_property = prop; |
114 | } | 110 | } |
115 | drm_connector_attach_property(connector, prop, 0); | 111 | drm_connector_attach_property(connector, prop, 0); |
116 | } | 112 | } |
117 | 113 | ||
118 | static const char *broadcast_rgb_names[] = { | 114 | static const struct drm_prop_enum_list broadcast_rgb_names[] = { |
119 | "Full", | 115 | { 0, "Full" }, |
120 | "Limited 16:235", | 116 | { 1, "Limited 16:235" }, |
121 | }; | 117 | }; |
122 | 118 | ||
123 | void | 119 | void |
@@ -126,19 +122,16 @@ intel_attach_broadcast_rgb_property(struct drm_connector *connector) | |||
126 | struct drm_device *dev = connector->dev; | 122 | struct drm_device *dev = connector->dev; |
127 | struct drm_i915_private *dev_priv = dev->dev_private; | 123 | struct drm_i915_private *dev_priv = dev->dev_private; |
128 | struct drm_property *prop; | 124 | struct drm_property *prop; |
129 | int i; | ||
130 | 125 | ||
131 | prop = dev_priv->broadcast_rgb_property; | 126 | prop = dev_priv->broadcast_rgb_property; |
132 | if (prop == NULL) { | 127 | if (prop == NULL) { |
133 | prop = drm_property_create(dev, DRM_MODE_PROP_ENUM, | 128 | prop = drm_property_create_enum(dev, DRM_MODE_PROP_ENUM, |
134 | "Broadcast RGB", | 129 | "Broadcast RGB", |
130 | broadcast_rgb_names, | ||
135 | ARRAY_SIZE(broadcast_rgb_names)); | 131 | ARRAY_SIZE(broadcast_rgb_names)); |
136 | if (prop == NULL) | 132 | if (prop == NULL) |
137 | return; | 133 | return; |
138 | 134 | ||
139 | for (i = 0; i < ARRAY_SIZE(broadcast_rgb_names); i++) | ||
140 | drm_property_add_enum(prop, i, i, broadcast_rgb_names[i]); | ||
141 | |||
142 | dev_priv->broadcast_rgb_property = prop; | 135 | dev_priv->broadcast_rgb_property = prop; |
143 | } | 136 | } |
144 | 137 | ||
diff --git a/drivers/gpu/drm/i915/intel_sdvo.c b/drivers/gpu/drm/i915/intel_sdvo.c index 80fb5da421f8..724190ec496b 100644 --- a/drivers/gpu/drm/i915/intel_sdvo.c +++ b/drivers/gpu/drm/i915/intel_sdvo.c | |||
@@ -2276,10 +2276,8 @@ static bool intel_sdvo_tv_create_property(struct intel_sdvo *intel_sdvo, | |||
2276 | intel_sdvo_connector->max_##name = data_value[0]; \ | 2276 | intel_sdvo_connector->max_##name = data_value[0]; \ |
2277 | intel_sdvo_connector->cur_##name = response; \ | 2277 | intel_sdvo_connector->cur_##name = response; \ |
2278 | intel_sdvo_connector->name = \ | 2278 | intel_sdvo_connector->name = \ |
2279 | drm_property_create(dev, DRM_MODE_PROP_RANGE, #name, 2); \ | 2279 | drm_property_create_range(dev, 0, #name, 0, data_value[0]); \ |
2280 | if (!intel_sdvo_connector->name) return false; \ | 2280 | if (!intel_sdvo_connector->name) return false; \ |
2281 | intel_sdvo_connector->name->values[0] = 0; \ | ||
2282 | intel_sdvo_connector->name->values[1] = data_value[0]; \ | ||
2283 | drm_connector_attach_property(connector, \ | 2281 | drm_connector_attach_property(connector, \ |
2284 | intel_sdvo_connector->name, \ | 2282 | intel_sdvo_connector->name, \ |
2285 | intel_sdvo_connector->cur_##name); \ | 2283 | intel_sdvo_connector->cur_##name); \ |
@@ -2313,25 +2311,19 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, | |||
2313 | intel_sdvo_connector->left_margin = data_value[0] - response; | 2311 | intel_sdvo_connector->left_margin = data_value[0] - response; |
2314 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; | 2312 | intel_sdvo_connector->right_margin = intel_sdvo_connector->left_margin; |
2315 | intel_sdvo_connector->left = | 2313 | intel_sdvo_connector->left = |
2316 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2314 | drm_property_create_range(dev, 0, "left_margin", 0, data_value[0]); |
2317 | "left_margin", 2); | ||
2318 | if (!intel_sdvo_connector->left) | 2315 | if (!intel_sdvo_connector->left) |
2319 | return false; | 2316 | return false; |
2320 | 2317 | ||
2321 | intel_sdvo_connector->left->values[0] = 0; | ||
2322 | intel_sdvo_connector->left->values[1] = data_value[0]; | ||
2323 | drm_connector_attach_property(connector, | 2318 | drm_connector_attach_property(connector, |
2324 | intel_sdvo_connector->left, | 2319 | intel_sdvo_connector->left, |
2325 | intel_sdvo_connector->left_margin); | 2320 | intel_sdvo_connector->left_margin); |
2326 | 2321 | ||
2327 | intel_sdvo_connector->right = | 2322 | intel_sdvo_connector->right = |
2328 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2323 | drm_property_create_range(dev, 0, "right_margin", 0, data_value[0]); |
2329 | "right_margin", 2); | ||
2330 | if (!intel_sdvo_connector->right) | 2324 | if (!intel_sdvo_connector->right) |
2331 | return false; | 2325 | return false; |
2332 | 2326 | ||
2333 | intel_sdvo_connector->right->values[0] = 0; | ||
2334 | intel_sdvo_connector->right->values[1] = data_value[0]; | ||
2335 | drm_connector_attach_property(connector, | 2327 | drm_connector_attach_property(connector, |
2336 | intel_sdvo_connector->right, | 2328 | intel_sdvo_connector->right, |
2337 | intel_sdvo_connector->right_margin); | 2329 | intel_sdvo_connector->right_margin); |
@@ -2355,25 +2347,21 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, | |||
2355 | intel_sdvo_connector->top_margin = data_value[0] - response; | 2347 | intel_sdvo_connector->top_margin = data_value[0] - response; |
2356 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; | 2348 | intel_sdvo_connector->bottom_margin = intel_sdvo_connector->top_margin; |
2357 | intel_sdvo_connector->top = | 2349 | intel_sdvo_connector->top = |
2358 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2350 | drm_property_create_range(dev, 0, |
2359 | "top_margin", 2); | 2351 | "top_margin", 0, data_value[0]); |
2360 | if (!intel_sdvo_connector->top) | 2352 | if (!intel_sdvo_connector->top) |
2361 | return false; | 2353 | return false; |
2362 | 2354 | ||
2363 | intel_sdvo_connector->top->values[0] = 0; | ||
2364 | intel_sdvo_connector->top->values[1] = data_value[0]; | ||
2365 | drm_connector_attach_property(connector, | 2355 | drm_connector_attach_property(connector, |
2366 | intel_sdvo_connector->top, | 2356 | intel_sdvo_connector->top, |
2367 | intel_sdvo_connector->top_margin); | 2357 | intel_sdvo_connector->top_margin); |
2368 | 2358 | ||
2369 | intel_sdvo_connector->bottom = | 2359 | intel_sdvo_connector->bottom = |
2370 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 2360 | drm_property_create_range(dev, 0, |
2371 | "bottom_margin", 2); | 2361 | "bottom_margin", 0, data_value[0]); |
2372 | if (!intel_sdvo_connector->bottom) | 2362 | if (!intel_sdvo_connector->bottom) |
2373 | return false; | 2363 | return false; |
2374 | 2364 | ||
2375 | intel_sdvo_connector->bottom->values[0] = 0; | ||
2376 | intel_sdvo_connector->bottom->values[1] = data_value[0]; | ||
2377 | drm_connector_attach_property(connector, | 2365 | drm_connector_attach_property(connector, |
2378 | intel_sdvo_connector->bottom, | 2366 | intel_sdvo_connector->bottom, |
2379 | intel_sdvo_connector->bottom_margin); | 2367 | intel_sdvo_connector->bottom_margin); |
@@ -2402,12 +2390,10 @@ intel_sdvo_create_enhance_property_tv(struct intel_sdvo *intel_sdvo, | |||
2402 | intel_sdvo_connector->max_dot_crawl = 1; | 2390 | intel_sdvo_connector->max_dot_crawl = 1; |
2403 | intel_sdvo_connector->cur_dot_crawl = response & 0x1; | 2391 | intel_sdvo_connector->cur_dot_crawl = response & 0x1; |
2404 | intel_sdvo_connector->dot_crawl = | 2392 | intel_sdvo_connector->dot_crawl = |
2405 | drm_property_create(dev, DRM_MODE_PROP_RANGE, "dot_crawl", 2); | 2393 | drm_property_create_range(dev, 0, "dot_crawl", 0, 1); |
2406 | if (!intel_sdvo_connector->dot_crawl) | 2394 | if (!intel_sdvo_connector->dot_crawl) |
2407 | return false; | 2395 | return false; |
2408 | 2396 | ||
2409 | intel_sdvo_connector->dot_crawl->values[0] = 0; | ||
2410 | intel_sdvo_connector->dot_crawl->values[1] = 1; | ||
2411 | drm_connector_attach_property(connector, | 2397 | drm_connector_attach_property(connector, |
2412 | intel_sdvo_connector->dot_crawl, | 2398 | intel_sdvo_connector->dot_crawl, |
2413 | intel_sdvo_connector->cur_dot_crawl); | 2399 | intel_sdvo_connector->cur_dot_crawl); |
diff --git a/drivers/gpu/drm/mga/mga_dma.c b/drivers/gpu/drm/mga/mga_dma.c index 5ccb65deb83c..507aa3df0168 100644 --- a/drivers/gpu/drm/mga/mga_dma.c +++ b/drivers/gpu/drm/mga/mga_dma.c | |||
@@ -403,6 +403,8 @@ int mga_driver_load(struct drm_device *dev, unsigned long flags) | |||
403 | dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; | 403 | dev_priv->usec_timeout = MGA_DEFAULT_USEC_TIMEOUT; |
404 | dev_priv->chipset = flags; | 404 | dev_priv->chipset = flags; |
405 | 405 | ||
406 | pci_set_master(dev->pdev); | ||
407 | |||
406 | dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); | 408 | dev_priv->mmio_base = pci_resource_start(dev->pdev, 1); |
407 | dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); | 409 | dev_priv->mmio_size = pci_resource_len(dev->pdev, 1); |
408 | 410 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 795a9e3c990a..5565e5056ba1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c | |||
@@ -155,20 +155,20 @@ static const struct drm_mode_config_funcs nouveau_mode_config_funcs = { | |||
155 | }; | 155 | }; |
156 | 156 | ||
157 | 157 | ||
158 | struct drm_prop_enum_list { | 158 | struct nouveau_drm_prop_enum_list { |
159 | u8 gen_mask; | 159 | u8 gen_mask; |
160 | int type; | 160 | int type; |
161 | char *name; | 161 | char *name; |
162 | }; | 162 | }; |
163 | 163 | ||
164 | static struct drm_prop_enum_list underscan[] = { | 164 | static struct nouveau_drm_prop_enum_list underscan[] = { |
165 | { 6, UNDERSCAN_AUTO, "auto" }, | 165 | { 6, UNDERSCAN_AUTO, "auto" }, |
166 | { 6, UNDERSCAN_OFF, "off" }, | 166 | { 6, UNDERSCAN_OFF, "off" }, |
167 | { 6, UNDERSCAN_ON, "on" }, | 167 | { 6, UNDERSCAN_ON, "on" }, |
168 | {} | 168 | {} |
169 | }; | 169 | }; |
170 | 170 | ||
171 | static struct drm_prop_enum_list dither_mode[] = { | 171 | static struct nouveau_drm_prop_enum_list dither_mode[] = { |
172 | { 7, DITHERING_MODE_AUTO, "auto" }, | 172 | { 7, DITHERING_MODE_AUTO, "auto" }, |
173 | { 7, DITHERING_MODE_OFF, "off" }, | 173 | { 7, DITHERING_MODE_OFF, "off" }, |
174 | { 1, DITHERING_MODE_ON, "on" }, | 174 | { 1, DITHERING_MODE_ON, "on" }, |
@@ -178,7 +178,7 @@ static struct drm_prop_enum_list dither_mode[] = { | |||
178 | {} | 178 | {} |
179 | }; | 179 | }; |
180 | 180 | ||
181 | static struct drm_prop_enum_list dither_depth[] = { | 181 | static struct nouveau_drm_prop_enum_list dither_depth[] = { |
182 | { 6, DITHERING_DEPTH_AUTO, "auto" }, | 182 | { 6, DITHERING_DEPTH_AUTO, "auto" }, |
183 | { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, | 183 | { 6, DITHERING_DEPTH_6BPC, "6 bpc" }, |
184 | { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, | 184 | { 6, DITHERING_DEPTH_8BPC, "8 bpc" }, |
@@ -186,7 +186,7 @@ static struct drm_prop_enum_list dither_depth[] = { | |||
186 | }; | 186 | }; |
187 | 187 | ||
188 | #define PROP_ENUM(p,gen,n,list) do { \ | 188 | #define PROP_ENUM(p,gen,n,list) do { \ |
189 | struct drm_prop_enum_list *l = (list); \ | 189 | struct nouveau_drm_prop_enum_list *l = (list); \ |
190 | int c = 0; \ | 190 | int c = 0; \ |
191 | while (l->gen_mask) { \ | 191 | while (l->gen_mask) { \ |
192 | if (l->gen_mask & (1 << (gen))) \ | 192 | if (l->gen_mask & (1 << (gen))) \ |
@@ -281,16 +281,10 @@ nouveau_display_create(struct drm_device *dev) | |||
281 | PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); | 281 | PROP_ENUM(disp->underscan_property, gen, "underscan", underscan); |
282 | 282 | ||
283 | disp->underscan_hborder_property = | 283 | disp->underscan_hborder_property = |
284 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 284 | drm_property_create_range(dev, 0, "underscan hborder", 0, 128); |
285 | "underscan hborder", 2); | ||
286 | disp->underscan_hborder_property->values[0] = 0; | ||
287 | disp->underscan_hborder_property->values[1] = 128; | ||
288 | 285 | ||
289 | disp->underscan_vborder_property = | 286 | disp->underscan_vborder_property = |
290 | drm_property_create(dev, DRM_MODE_PROP_RANGE, | 287 | drm_property_create_range(dev, 0, "underscan vborder", 0, 128); |
291 | "underscan vborder", 2); | ||
292 | disp->underscan_vborder_property->values[0] = 0; | ||
293 | disp->underscan_vborder_property->values[1] = 128; | ||
294 | 288 | ||
295 | dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; | 289 | dev->mode_config.funcs = (void *)&nouveau_mode_config_funcs; |
296 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1); | 290 | dev->mode_config.fb_base = pci_resource_start(dev->pdev, 1); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 9892218d7452..8113e9201ed9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c | |||
@@ -381,11 +381,7 @@ nouveau_fbcon_create(struct nouveau_fbdev *nfbdev, | |||
381 | goto out_unref; | 381 | goto out_unref; |
382 | } | 382 | } |
383 | 383 | ||
384 | info->pixmap.size = 64*1024; | 384 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
385 | info->pixmap.buf_align = 8; | ||
386 | info->pixmap.access_align = 32; | ||
387 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
388 | info->pixmap.scan_align = 1; | ||
389 | 385 | ||
390 | mutex_unlock(&dev->struct_mutex); | 386 | mutex_unlock(&dev->struct_mutex); |
391 | 387 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index f80c5e0762ff..912839c2bc16 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -1002,6 +1002,8 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) | |||
1002 | dev->dev_private = dev_priv; | 1002 | dev->dev_private = dev_priv; |
1003 | dev_priv->dev = dev; | 1003 | dev_priv->dev = dev; |
1004 | 1004 | ||
1005 | pci_set_master(dev->pdev); | ||
1006 | |||
1005 | dev_priv->flags = flags & NOUVEAU_FLAGS; | 1007 | dev_priv->flags = flags & NOUVEAU_FLAGS; |
1006 | 1008 | ||
1007 | NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", | 1009 | NV_DEBUG(dev, "vendor: 0x%X device: 0x%X class: 0x%X\n", |
diff --git a/drivers/gpu/drm/r128/r128_drv.c b/drivers/gpu/drm/r128/r128_drv.c index 6a5f4395838f..88718fad5d6d 100644 --- a/drivers/gpu/drm/r128/r128_drv.c +++ b/drivers/gpu/drm/r128/r128_drv.c | |||
@@ -85,6 +85,7 @@ static struct drm_driver driver = { | |||
85 | 85 | ||
86 | int r128_driver_load(struct drm_device *dev, unsigned long flags) | 86 | int r128_driver_load(struct drm_device *dev, unsigned long flags) |
87 | { | 87 | { |
88 | pci_set_master(dev->pdev); | ||
88 | return drm_vblank_init(dev, 1); | 89 | return drm_vblank_init(dev, 1); |
89 | } | 90 | } |
90 | 91 | ||
diff --git a/drivers/gpu/drm/radeon/Makefile b/drivers/gpu/drm/radeon/Makefile index 2139fe893ec5..84104153a684 100644 --- a/drivers/gpu/drm/radeon/Makefile +++ b/drivers/gpu/drm/radeon/Makefile | |||
@@ -71,7 +71,7 @@ radeon-y += radeon_device.o radeon_asic.o radeon_kms.o \ | |||
71 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ | 71 | r600_blit_kms.o radeon_pm.o atombios_dp.o r600_audio.o r600_hdmi.o \ |
72 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ | 72 | evergreen.o evergreen_cs.o evergreen_blit_shaders.o evergreen_blit_kms.o \ |
73 | radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \ | 73 | radeon_trace_points.o ni.o cayman_blit_shaders.o atombios_encoders.o \ |
74 | radeon_semaphore.o radeon_sa.o | 74 | radeon_semaphore.o radeon_sa.o atombios_i2c.o |
75 | 75 | ||
76 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o | 76 | radeon-$(CONFIG_COMPAT) += radeon_ioc32.o |
77 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o | 77 | radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index 742f17f009a9..72672ea3f6d3 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1031,6 +1031,7 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1031 | struct radeon_bo *rbo; | 1031 | struct radeon_bo *rbo; |
1032 | uint64_t fb_location; | 1032 | uint64_t fb_location; |
1033 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; | 1033 | uint32_t fb_format, fb_pitch_pixels, tiling_flags; |
1034 | unsigned bankw, bankh, mtaspect, tile_split; | ||
1034 | u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); | 1035 | u32 fb_swap = EVERGREEN_GRPH_ENDIAN_SWAP(EVERGREEN_GRPH_ENDIAN_NONE); |
1035 | u32 tmp, viewport_w, viewport_h; | 1036 | u32 tmp, viewport_w, viewport_h; |
1036 | int r; | 1037 | int r; |
@@ -1121,20 +1122,13 @@ static int dce4_crtc_do_set_base(struct drm_crtc *crtc, | |||
1121 | break; | 1122 | break; |
1122 | } | 1123 | } |
1123 | 1124 | ||
1124 | switch ((tmp & 0xf000) >> 12) { | ||
1125 | case 0: /* 1KB rows */ | ||
1126 | default: | ||
1127 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_1KB); | ||
1128 | break; | ||
1129 | case 1: /* 2KB rows */ | ||
1130 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_2KB); | ||
1131 | break; | ||
1132 | case 2: /* 4KB rows */ | ||
1133 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(EVERGREEN_ADDR_SURF_TILE_SPLIT_4KB); | ||
1134 | break; | ||
1135 | } | ||
1136 | |||
1137 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); | 1125 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_2D_TILED_THIN1); |
1126 | |||
1127 | evergreen_tiling_fields(tiling_flags, &bankw, &bankh, &mtaspect, &tile_split); | ||
1128 | fb_format |= EVERGREEN_GRPH_TILE_SPLIT(tile_split); | ||
1129 | fb_format |= EVERGREEN_GRPH_BANK_WIDTH(bankw); | ||
1130 | fb_format |= EVERGREEN_GRPH_BANK_HEIGHT(bankh); | ||
1131 | fb_format |= EVERGREEN_GRPH_MACRO_TILE_ASPECT(mtaspect); | ||
1138 | } else if (tiling_flags & RADEON_TILING_MICRO) | 1132 | } else if (tiling_flags & RADEON_TILING_MICRO) |
1139 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); | 1133 | fb_format |= EVERGREEN_GRPH_ARRAY_MODE(EVERGREEN_GRPH_ARRAY_1D_TILED_THIN1); |
1140 | 1134 | ||
diff --git a/drivers/gpu/drm/radeon/atombios_i2c.c b/drivers/gpu/drm/radeon/atombios_i2c.c new file mode 100644 index 000000000000..44d87b6b4220 --- /dev/null +++ b/drivers/gpu/drm/radeon/atombios_i2c.c | |||
@@ -0,0 +1,139 @@ | |||
1 | /* | ||
2 | * Copyright 2011 Advanced Micro Devices, Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Alex Deucher | ||
23 | * | ||
24 | */ | ||
25 | #include "drmP.h" | ||
26 | #include "radeon_drm.h" | ||
27 | #include "radeon.h" | ||
28 | #include "atom.h" | ||
29 | |||
30 | #define TARGET_HW_I2C_CLOCK 50 | ||
31 | |||
32 | /* these are a limitation of ProcessI2cChannelTransaction not the hw */ | ||
33 | #define ATOM_MAX_HW_I2C_WRITE 2 | ||
34 | #define ATOM_MAX_HW_I2C_READ 255 | ||
35 | |||
36 | static int radeon_process_i2c_ch(struct radeon_i2c_chan *chan, | ||
37 | u8 slave_addr, u8 flags, | ||
38 | u8 *buf, u8 num) | ||
39 | { | ||
40 | struct drm_device *dev = chan->dev; | ||
41 | struct radeon_device *rdev = dev->dev_private; | ||
42 | PROCESS_I2C_CHANNEL_TRANSACTION_PS_ALLOCATION args; | ||
43 | int index = GetIndexIntoMasterTable(COMMAND, ProcessI2cChannelTransaction); | ||
44 | unsigned char *base; | ||
45 | u16 out; | ||
46 | |||
47 | memset(&args, 0, sizeof(args)); | ||
48 | |||
49 | base = (unsigned char *)rdev->mode_info.atom_context->scratch; | ||
50 | |||
51 | if (flags & HW_I2C_WRITE) { | ||
52 | if (num > ATOM_MAX_HW_I2C_WRITE) { | ||
53 | DRM_ERROR("hw i2c: tried to write too many bytes (%d vs 2)\n", num); | ||
54 | return -EINVAL; | ||
55 | } | ||
56 | memcpy(&out, buf, num); | ||
57 | args.lpI2CDataOut = cpu_to_le16(out); | ||
58 | } else { | ||
59 | if (num > ATOM_MAX_HW_I2C_READ) { | ||
60 | DRM_ERROR("hw i2c: tried to read too many bytes (%d vs 255)\n", num); | ||
61 | return -EINVAL; | ||
62 | } | ||
63 | } | ||
64 | |||
65 | args.ucI2CSpeed = TARGET_HW_I2C_CLOCK; | ||
66 | args.ucRegIndex = 0; | ||
67 | args.ucTransBytes = num; | ||
68 | args.ucSlaveAddr = slave_addr << 1; | ||
69 | args.ucLineNumber = chan->rec.i2c_id; | ||
70 | |||
71 | atom_execute_table(rdev->mode_info.atom_context, index, (uint32_t *)&args); | ||
72 | |||
73 | /* error */ | ||
74 | if (args.ucStatus != HW_ASSISTED_I2C_STATUS_SUCCESS) { | ||
75 | DRM_DEBUG_KMS("hw_i2c error\n"); | ||
76 | return -EIO; | ||
77 | } | ||
78 | |||
79 | if (!(flags & HW_I2C_WRITE)) | ||
80 | memcpy(buf, base, num); | ||
81 | |||
82 | return 0; | ||
83 | } | ||
84 | |||
85 | int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
86 | struct i2c_msg *msgs, int num) | ||
87 | { | ||
88 | struct radeon_i2c_chan *i2c = i2c_get_adapdata(i2c_adap); | ||
89 | struct i2c_msg *p; | ||
90 | int i, remaining, current_count, buffer_offset, max_bytes, ret; | ||
91 | u8 buf = 0, flags; | ||
92 | |||
93 | /* check for bus probe */ | ||
94 | p = &msgs[0]; | ||
95 | if ((num == 1) && (p->len == 0)) { | ||
96 | ret = radeon_process_i2c_ch(i2c, | ||
97 | p->addr, HW_I2C_WRITE, | ||
98 | &buf, 1); | ||
99 | if (ret) | ||
100 | return ret; | ||
101 | else | ||
102 | return num; | ||
103 | } | ||
104 | |||
105 | for (i = 0; i < num; i++) { | ||
106 | p = &msgs[i]; | ||
107 | remaining = p->len; | ||
108 | buffer_offset = 0; | ||
109 | /* max_bytes are a limitation of ProcessI2cChannelTransaction not the hw */ | ||
110 | if (p->flags & I2C_M_RD) { | ||
111 | max_bytes = ATOM_MAX_HW_I2C_READ; | ||
112 | flags = HW_I2C_READ; | ||
113 | } else { | ||
114 | max_bytes = ATOM_MAX_HW_I2C_WRITE; | ||
115 | flags = HW_I2C_WRITE; | ||
116 | } | ||
117 | while (remaining) { | ||
118 | if (remaining > max_bytes) | ||
119 | current_count = max_bytes; | ||
120 | else | ||
121 | current_count = remaining; | ||
122 | ret = radeon_process_i2c_ch(i2c, | ||
123 | p->addr, flags, | ||
124 | &p->buf[buffer_offset], current_count); | ||
125 | if (ret) | ||
126 | return ret; | ||
127 | remaining -= current_count; | ||
128 | buffer_offset += current_count; | ||
129 | } | ||
130 | } | ||
131 | |||
132 | return num; | ||
133 | } | ||
134 | |||
135 | u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap) | ||
136 | { | ||
137 | return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | ||
138 | } | ||
139 | |||
diff --git a/drivers/gpu/drm/radeon/evergreen.c b/drivers/gpu/drm/radeon/evergreen.c index 9be353b894cc..1a816ea51226 100644 --- a/drivers/gpu/drm/radeon/evergreen.c +++ b/drivers/gpu/drm/radeon/evergreen.c | |||
@@ -43,6 +43,37 @@ void evergreen_pcie_gen2_enable(struct radeon_device *rdev); | |||
43 | extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, | 43 | extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, |
44 | int ring, u32 cp_int_cntl); | 44 | int ring, u32 cp_int_cntl); |
45 | 45 | ||
46 | void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw, | ||
47 | unsigned *bankh, unsigned *mtaspect, | ||
48 | unsigned *tile_split) | ||
49 | { | ||
50 | *bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK; | ||
51 | *bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK; | ||
52 | *mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK; | ||
53 | *tile_split = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK; | ||
54 | switch (*bankw) { | ||
55 | default: | ||
56 | case 1: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_1; break; | ||
57 | case 2: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_2; break; | ||
58 | case 4: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_4; break; | ||
59 | case 8: *bankw = EVERGREEN_ADDR_SURF_BANK_WIDTH_8; break; | ||
60 | } | ||
61 | switch (*bankh) { | ||
62 | default: | ||
63 | case 1: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_1; break; | ||
64 | case 2: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_2; break; | ||
65 | case 4: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_4; break; | ||
66 | case 8: *bankh = EVERGREEN_ADDR_SURF_BANK_HEIGHT_8; break; | ||
67 | } | ||
68 | switch (*mtaspect) { | ||
69 | default: | ||
70 | case 1: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_1; break; | ||
71 | case 2: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_2; break; | ||
72 | case 4: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_4; break; | ||
73 | case 8: *mtaspect = EVERGREEN_ADDR_SURF_MACRO_TILE_ASPECT_8; break; | ||
74 | } | ||
75 | } | ||
76 | |||
46 | void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) | 77 | void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) |
47 | { | 78 | { |
48 | u16 ctl, v; | 79 | u16 ctl, v; |
diff --git a/drivers/gpu/drm/radeon/evergreen_blit_kms.c b/drivers/gpu/drm/radeon/evergreen_blit_kms.c index 2379849515c7..4e83fdcf4bc5 100644 --- a/drivers/gpu/drm/radeon/evergreen_blit_kms.c +++ b/drivers/gpu/drm/radeon/evergreen_blit_kms.c | |||
@@ -32,17 +32,7 @@ | |||
32 | #include "evergreend.h" | 32 | #include "evergreend.h" |
33 | #include "evergreen_blit_shaders.h" | 33 | #include "evergreen_blit_shaders.h" |
34 | #include "cayman_blit_shaders.h" | 34 | #include "cayman_blit_shaders.h" |
35 | 35 | #include "radeon_blit_common.h" | |
36 | #define DI_PT_RECTLIST 0x11 | ||
37 | #define DI_INDEX_SIZE_16_BIT 0x0 | ||
38 | #define DI_SRC_SEL_AUTO_INDEX 0x2 | ||
39 | |||
40 | #define FMT_8 0x1 | ||
41 | #define FMT_5_6_5 0x8 | ||
42 | #define FMT_8_8_8_8 0x1a | ||
43 | #define COLOR_8 0x1 | ||
44 | #define COLOR_5_6_5 0x8 | ||
45 | #define COLOR_8_8_8_8 0x1a | ||
46 | 36 | ||
47 | /* emits 17 */ | 37 | /* emits 17 */ |
48 | static void | 38 | static void |
diff --git a/drivers/gpu/drm/radeon/evergreen_cs.c b/drivers/gpu/drm/radeon/evergreen_cs.c index 8e8cd85e5c00..49203b67b81b 100644 --- a/drivers/gpu/drm/radeon/evergreen_cs.c +++ b/drivers/gpu/drm/radeon/evergreen_cs.c | |||
@@ -31,6 +31,9 @@ | |||
31 | #include "evergreen_reg_safe.h" | 31 | #include "evergreen_reg_safe.h" |
32 | #include "cayman_reg_safe.h" | 32 | #include "cayman_reg_safe.h" |
33 | 33 | ||
34 | #define MAX(a,b) (((a)>(b))?(a):(b)) | ||
35 | #define MIN(a,b) (((a)<(b))?(a):(b)) | ||
36 | |||
34 | static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, | 37 | static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, |
35 | struct radeon_cs_reloc **cs_reloc); | 38 | struct radeon_cs_reloc **cs_reloc); |
36 | 39 | ||
@@ -54,14 +57,20 @@ struct evergreen_cs_track { | |||
54 | u32 cb_color_dim[12]; | 57 | u32 cb_color_dim[12]; |
55 | u32 cb_color_pitch[12]; | 58 | u32 cb_color_pitch[12]; |
56 | u32 cb_color_slice[12]; | 59 | u32 cb_color_slice[12]; |
60 | u32 cb_color_attrib[12]; | ||
57 | u32 cb_color_cmask_slice[8]; | 61 | u32 cb_color_cmask_slice[8]; |
58 | u32 cb_color_fmask_slice[8]; | 62 | u32 cb_color_fmask_slice[8]; |
59 | u32 cb_target_mask; | 63 | u32 cb_target_mask; |
60 | u32 cb_shader_mask; | 64 | u32 cb_shader_mask; |
61 | u32 vgt_strmout_config; | 65 | u32 vgt_strmout_config; |
62 | u32 vgt_strmout_buffer_config; | 66 | u32 vgt_strmout_buffer_config; |
67 | struct radeon_bo *vgt_strmout_bo[4]; | ||
68 | u64 vgt_strmout_bo_mc[4]; | ||
69 | u32 vgt_strmout_bo_offset[4]; | ||
70 | u32 vgt_strmout_size[4]; | ||
63 | u32 db_depth_control; | 71 | u32 db_depth_control; |
64 | u32 db_depth_view; | 72 | u32 db_depth_view; |
73 | u32 db_depth_slice; | ||
65 | u32 db_depth_size; | 74 | u32 db_depth_size; |
66 | u32 db_depth_size_idx; | 75 | u32 db_depth_size_idx; |
67 | u32 db_z_info; | 76 | u32 db_z_info; |
@@ -103,19 +112,6 @@ static u32 evergreen_cs_get_num_banks(u32 nbanks) | |||
103 | } | 112 | } |
104 | } | 113 | } |
105 | 114 | ||
106 | static u32 evergreen_cs_get_tile_split(u32 row_size) | ||
107 | { | ||
108 | switch (row_size) { | ||
109 | case 1: | ||
110 | default: | ||
111 | return ADDR_SURF_TILE_SPLIT_1KB; | ||
112 | case 2: | ||
113 | return ADDR_SURF_TILE_SPLIT_2KB; | ||
114 | case 4: | ||
115 | return ADDR_SURF_TILE_SPLIT_4KB; | ||
116 | } | ||
117 | } | ||
118 | |||
119 | static void evergreen_cs_track_init(struct evergreen_cs_track *track) | 115 | static void evergreen_cs_track_init(struct evergreen_cs_track *track) |
120 | { | 116 | { |
121 | int i; | 117 | int i; |
@@ -132,7 +128,7 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track) | |||
132 | track->cb_color_bo[i] = NULL; | 128 | track->cb_color_bo[i] = NULL; |
133 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; | 129 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; |
134 | track->cb_color_info[i] = 0; | 130 | track->cb_color_info[i] = 0; |
135 | track->cb_color_view[i] = 0; | 131 | track->cb_color_view[i] = 0xFFFFFFFF; |
136 | track->cb_color_pitch_idx[i] = 0; | 132 | track->cb_color_pitch_idx[i] = 0; |
137 | track->cb_color_slice_idx[i] = 0; | 133 | track->cb_color_slice_idx[i] = 0; |
138 | track->cb_color_dim[i] = 0; | 134 | track->cb_color_dim[i] = 0; |
@@ -159,19 +155,704 @@ static void evergreen_cs_track_init(struct evergreen_cs_track *track) | |||
159 | track->db_s_write_offset = 0xFFFFFFFF; | 155 | track->db_s_write_offset = 0xFFFFFFFF; |
160 | track->db_s_read_bo = NULL; | 156 | track->db_s_read_bo = NULL; |
161 | track->db_s_write_bo = NULL; | 157 | track->db_s_write_bo = NULL; |
158 | |||
159 | for (i = 0; i < 4; i++) { | ||
160 | track->vgt_strmout_size[i] = 0; | ||
161 | track->vgt_strmout_bo[i] = NULL; | ||
162 | track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF; | ||
163 | track->vgt_strmout_bo_mc[i] = 0xFFFFFFFF; | ||
164 | } | ||
162 | } | 165 | } |
163 | 166 | ||
164 | static int evergreen_cs_track_check(struct radeon_cs_parser *p) | 167 | struct eg_surface { |
168 | /* value gathered from cs */ | ||
169 | unsigned nbx; | ||
170 | unsigned nby; | ||
171 | unsigned format; | ||
172 | unsigned mode; | ||
173 | unsigned nbanks; | ||
174 | unsigned bankw; | ||
175 | unsigned bankh; | ||
176 | unsigned tsplit; | ||
177 | unsigned mtilea; | ||
178 | unsigned nsamples; | ||
179 | /* output value */ | ||
180 | unsigned bpe; | ||
181 | unsigned layer_size; | ||
182 | unsigned palign; | ||
183 | unsigned halign; | ||
184 | unsigned long base_align; | ||
185 | }; | ||
186 | |||
187 | static int evergreen_surface_check_linear(struct radeon_cs_parser *p, | ||
188 | struct eg_surface *surf, | ||
189 | const char *prefix) | ||
190 | { | ||
191 | surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples; | ||
192 | surf->base_align = surf->bpe; | ||
193 | surf->palign = 1; | ||
194 | surf->halign = 1; | ||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int evergreen_surface_check_linear_aligned(struct radeon_cs_parser *p, | ||
199 | struct eg_surface *surf, | ||
200 | const char *prefix) | ||
201 | { | ||
202 | struct evergreen_cs_track *track = p->track; | ||
203 | unsigned palign; | ||
204 | |||
205 | palign = MAX(64, track->group_size / surf->bpe); | ||
206 | surf->layer_size = surf->nbx * surf->nby * surf->bpe * surf->nsamples; | ||
207 | surf->base_align = track->group_size; | ||
208 | surf->palign = palign; | ||
209 | surf->halign = 1; | ||
210 | if (surf->nbx & (palign - 1)) { | ||
211 | if (prefix) { | ||
212 | dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n", | ||
213 | __func__, __LINE__, prefix, surf->nbx, palign); | ||
214 | } | ||
215 | return -EINVAL; | ||
216 | } | ||
217 | return 0; | ||
218 | } | ||
219 | |||
220 | static int evergreen_surface_check_1d(struct radeon_cs_parser *p, | ||
221 | struct eg_surface *surf, | ||
222 | const char *prefix) | ||
223 | { | ||
224 | struct evergreen_cs_track *track = p->track; | ||
225 | unsigned palign; | ||
226 | |||
227 | palign = track->group_size / (8 * surf->bpe * surf->nsamples); | ||
228 | palign = MAX(8, palign); | ||
229 | surf->layer_size = surf->nbx * surf->nby * surf->bpe; | ||
230 | surf->base_align = track->group_size; | ||
231 | surf->palign = palign; | ||
232 | surf->halign = 8; | ||
233 | if ((surf->nbx & (palign - 1))) { | ||
234 | if (prefix) { | ||
235 | dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d (%d %d %d)\n", | ||
236 | __func__, __LINE__, prefix, surf->nbx, palign, | ||
237 | track->group_size, surf->bpe, surf->nsamples); | ||
238 | } | ||
239 | return -EINVAL; | ||
240 | } | ||
241 | if ((surf->nby & (8 - 1))) { | ||
242 | if (prefix) { | ||
243 | dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with 8\n", | ||
244 | __func__, __LINE__, prefix, surf->nby); | ||
245 | } | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | static int evergreen_surface_check_2d(struct radeon_cs_parser *p, | ||
252 | struct eg_surface *surf, | ||
253 | const char *prefix) | ||
254 | { | ||
255 | struct evergreen_cs_track *track = p->track; | ||
256 | unsigned palign, halign, tileb, slice_pt; | ||
257 | |||
258 | tileb = 64 * surf->bpe * surf->nsamples; | ||
259 | palign = track->group_size / (8 * surf->bpe * surf->nsamples); | ||
260 | palign = MAX(8, palign); | ||
261 | slice_pt = 1; | ||
262 | if (tileb > surf->tsplit) { | ||
263 | slice_pt = tileb / surf->tsplit; | ||
264 | } | ||
265 | tileb = tileb / slice_pt; | ||
266 | /* macro tile width & height */ | ||
267 | palign = (8 * surf->bankw * track->npipes) * surf->mtilea; | ||
268 | halign = (8 * surf->bankh * surf->nbanks) / surf->mtilea; | ||
269 | surf->layer_size = surf->nbx * surf->nby * surf->bpe * slice_pt; | ||
270 | surf->base_align = (palign / 8) * (halign / 8) * tileb; | ||
271 | surf->palign = palign; | ||
272 | surf->halign = halign; | ||
273 | |||
274 | if ((surf->nbx & (palign - 1))) { | ||
275 | if (prefix) { | ||
276 | dev_warn(p->dev, "%s:%d %s pitch %d invalid must be aligned with %d\n", | ||
277 | __func__, __LINE__, prefix, surf->nbx, palign); | ||
278 | } | ||
279 | return -EINVAL; | ||
280 | } | ||
281 | if ((surf->nby & (halign - 1))) { | ||
282 | if (prefix) { | ||
283 | dev_warn(p->dev, "%s:%d %s height %d invalid must be aligned with %d\n", | ||
284 | __func__, __LINE__, prefix, surf->nby, halign); | ||
285 | } | ||
286 | return -EINVAL; | ||
287 | } | ||
288 | |||
289 | return 0; | ||
290 | } | ||
291 | |||
292 | static int evergreen_surface_check(struct radeon_cs_parser *p, | ||
293 | struct eg_surface *surf, | ||
294 | const char *prefix) | ||
295 | { | ||
296 | /* some common value computed here */ | ||
297 | surf->bpe = r600_fmt_get_blocksize(surf->format); | ||
298 | |||
299 | switch (surf->mode) { | ||
300 | case ARRAY_LINEAR_GENERAL: | ||
301 | return evergreen_surface_check_linear(p, surf, prefix); | ||
302 | case ARRAY_LINEAR_ALIGNED: | ||
303 | return evergreen_surface_check_linear_aligned(p, surf, prefix); | ||
304 | case ARRAY_1D_TILED_THIN1: | ||
305 | return evergreen_surface_check_1d(p, surf, prefix); | ||
306 | case ARRAY_2D_TILED_THIN1: | ||
307 | return evergreen_surface_check_2d(p, surf, prefix); | ||
308 | default: | ||
309 | dev_warn(p->dev, "%s:%d invalid array mode %d\n", | ||
310 | __func__, __LINE__, surf->mode); | ||
311 | return -EINVAL; | ||
312 | } | ||
313 | return -EINVAL; | ||
314 | } | ||
315 | |||
316 | static int evergreen_surface_value_conv_check(struct radeon_cs_parser *p, | ||
317 | struct eg_surface *surf, | ||
318 | const char *prefix) | ||
319 | { | ||
320 | switch (surf->mode) { | ||
321 | case ARRAY_2D_TILED_THIN1: | ||
322 | break; | ||
323 | case ARRAY_LINEAR_GENERAL: | ||
324 | case ARRAY_LINEAR_ALIGNED: | ||
325 | case ARRAY_1D_TILED_THIN1: | ||
326 | return 0; | ||
327 | default: | ||
328 | dev_warn(p->dev, "%s:%d invalid array mode %d\n", | ||
329 | __func__, __LINE__, surf->mode); | ||
330 | return -EINVAL; | ||
331 | } | ||
332 | |||
333 | switch (surf->nbanks) { | ||
334 | case 0: surf->nbanks = 2; break; | ||
335 | case 1: surf->nbanks = 4; break; | ||
336 | case 2: surf->nbanks = 8; break; | ||
337 | case 3: surf->nbanks = 16; break; | ||
338 | default: | ||
339 | dev_warn(p->dev, "%s:%d %s invalid number of banks %d\n", | ||
340 | __func__, __LINE__, prefix, surf->nbanks); | ||
341 | return -EINVAL; | ||
342 | } | ||
343 | switch (surf->bankw) { | ||
344 | case 0: surf->bankw = 1; break; | ||
345 | case 1: surf->bankw = 2; break; | ||
346 | case 2: surf->bankw = 4; break; | ||
347 | case 3: surf->bankw = 8; break; | ||
348 | default: | ||
349 | dev_warn(p->dev, "%s:%d %s invalid bankw %d\n", | ||
350 | __func__, __LINE__, prefix, surf->bankw); | ||
351 | return -EINVAL; | ||
352 | } | ||
353 | switch (surf->bankh) { | ||
354 | case 0: surf->bankh = 1; break; | ||
355 | case 1: surf->bankh = 2; break; | ||
356 | case 2: surf->bankh = 4; break; | ||
357 | case 3: surf->bankh = 8; break; | ||
358 | default: | ||
359 | dev_warn(p->dev, "%s:%d %s invalid bankh %d\n", | ||
360 | __func__, __LINE__, prefix, surf->bankh); | ||
361 | return -EINVAL; | ||
362 | } | ||
363 | switch (surf->mtilea) { | ||
364 | case 0: surf->mtilea = 1; break; | ||
365 | case 1: surf->mtilea = 2; break; | ||
366 | case 2: surf->mtilea = 4; break; | ||
367 | case 3: surf->mtilea = 8; break; | ||
368 | default: | ||
369 | dev_warn(p->dev, "%s:%d %s invalid macro tile aspect %d\n", | ||
370 | __func__, __LINE__, prefix, surf->mtilea); | ||
371 | return -EINVAL; | ||
372 | } | ||
373 | switch (surf->tsplit) { | ||
374 | case 0: surf->tsplit = 64; break; | ||
375 | case 1: surf->tsplit = 128; break; | ||
376 | case 2: surf->tsplit = 256; break; | ||
377 | case 3: surf->tsplit = 512; break; | ||
378 | case 4: surf->tsplit = 1024; break; | ||
379 | case 5: surf->tsplit = 2048; break; | ||
380 | case 6: surf->tsplit = 4096; break; | ||
381 | default: | ||
382 | dev_warn(p->dev, "%s:%d %s invalid tile split %d\n", | ||
383 | __func__, __LINE__, prefix, surf->tsplit); | ||
384 | return -EINVAL; | ||
385 | } | ||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | static int evergreen_cs_track_validate_cb(struct radeon_cs_parser *p, unsigned id) | ||
390 | { | ||
391 | struct evergreen_cs_track *track = p->track; | ||
392 | struct eg_surface surf; | ||
393 | unsigned pitch, slice, mslice; | ||
394 | unsigned long offset; | ||
395 | int r; | ||
396 | |||
397 | mslice = G_028C6C_SLICE_MAX(track->cb_color_view[id]) + 1; | ||
398 | pitch = track->cb_color_pitch[id]; | ||
399 | slice = track->cb_color_slice[id]; | ||
400 | surf.nbx = (pitch + 1) * 8; | ||
401 | surf.nby = ((slice + 1) * 64) / surf.nbx; | ||
402 | surf.mode = G_028C70_ARRAY_MODE(track->cb_color_info[id]); | ||
403 | surf.format = G_028C70_FORMAT(track->cb_color_info[id]); | ||
404 | surf.tsplit = G_028C74_TILE_SPLIT(track->cb_color_attrib[id]); | ||
405 | surf.nbanks = G_028C74_NUM_BANKS(track->cb_color_attrib[id]); | ||
406 | surf.bankw = G_028C74_BANK_WIDTH(track->cb_color_attrib[id]); | ||
407 | surf.bankh = G_028C74_BANK_HEIGHT(track->cb_color_attrib[id]); | ||
408 | surf.mtilea = G_028C74_MACRO_TILE_ASPECT(track->cb_color_attrib[id]); | ||
409 | surf.nsamples = 1; | ||
410 | |||
411 | if (!r600_fmt_is_valid_color(surf.format)) { | ||
412 | dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08x)\n", | ||
413 | __func__, __LINE__, surf.format, | ||
414 | id, track->cb_color_info[id]); | ||
415 | return -EINVAL; | ||
416 | } | ||
417 | |||
418 | r = evergreen_surface_value_conv_check(p, &surf, "cb"); | ||
419 | if (r) { | ||
420 | return r; | ||
421 | } | ||
422 | |||
423 | r = evergreen_surface_check(p, &surf, "cb"); | ||
424 | if (r) { | ||
425 | dev_warn(p->dev, "%s:%d cb[%d] invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", | ||
426 | __func__, __LINE__, id, track->cb_color_pitch[id], | ||
427 | track->cb_color_slice[id], track->cb_color_attrib[id], | ||
428 | track->cb_color_info[id]); | ||
429 | return r; | ||
430 | } | ||
431 | |||
432 | offset = track->cb_color_bo_offset[id] << 8; | ||
433 | if (offset & (surf.base_align - 1)) { | ||
434 | dev_warn(p->dev, "%s:%d cb[%d] bo base %ld not aligned with %ld\n", | ||
435 | __func__, __LINE__, id, offset, surf.base_align); | ||
436 | return -EINVAL; | ||
437 | } | ||
438 | |||
439 | offset += surf.layer_size * mslice; | ||
440 | if (offset > radeon_bo_size(track->cb_color_bo[id])) { | ||
441 | dev_warn(p->dev, "%s:%d cb[%d] bo too small (layer size %d, " | ||
442 | "offset %d, max layer %d, bo size %ld, slice %d)\n", | ||
443 | __func__, __LINE__, id, surf.layer_size, | ||
444 | track->cb_color_bo_offset[id] << 8, mslice, | ||
445 | radeon_bo_size(track->cb_color_bo[id]), slice); | ||
446 | dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n", | ||
447 | __func__, __LINE__, surf.nbx, surf.nby, | ||
448 | surf.mode, surf.bpe, surf.nsamples, | ||
449 | surf.bankw, surf.bankh, | ||
450 | surf.tsplit, surf.mtilea); | ||
451 | return -EINVAL; | ||
452 | } | ||
453 | |||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | static int evergreen_cs_track_validate_stencil(struct radeon_cs_parser *p) | ||
165 | { | 458 | { |
166 | struct evergreen_cs_track *track = p->track; | 459 | struct evergreen_cs_track *track = p->track; |
460 | struct eg_surface surf; | ||
461 | unsigned pitch, slice, mslice; | ||
462 | unsigned long offset; | ||
463 | int r; | ||
464 | |||
465 | mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; | ||
466 | pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size); | ||
467 | slice = track->db_depth_slice; | ||
468 | surf.nbx = (pitch + 1) * 8; | ||
469 | surf.nby = ((slice + 1) * 64) / surf.nbx; | ||
470 | surf.mode = G_028040_ARRAY_MODE(track->db_z_info); | ||
471 | surf.format = G_028044_FORMAT(track->db_s_info); | ||
472 | surf.tsplit = G_028044_TILE_SPLIT(track->db_s_info); | ||
473 | surf.nbanks = G_028040_NUM_BANKS(track->db_z_info); | ||
474 | surf.bankw = G_028040_BANK_WIDTH(track->db_z_info); | ||
475 | surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info); | ||
476 | surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info); | ||
477 | surf.nsamples = 1; | ||
478 | |||
479 | if (surf.format != 1) { | ||
480 | dev_warn(p->dev, "%s:%d stencil invalid format %d\n", | ||
481 | __func__, __LINE__, surf.format); | ||
482 | return -EINVAL; | ||
483 | } | ||
484 | /* replace by color format so we can use same code */ | ||
485 | surf.format = V_028C70_COLOR_8; | ||
486 | |||
487 | r = evergreen_surface_value_conv_check(p, &surf, "stencil"); | ||
488 | if (r) { | ||
489 | return r; | ||
490 | } | ||
491 | |||
492 | r = evergreen_surface_check(p, &surf, NULL); | ||
493 | if (r) { | ||
494 | /* old userspace doesn't compute proper depth/stencil alignment | ||
495 | * check that alignment against a bigger byte per elements and | ||
496 | * only report if that alignment is wrong too. | ||
497 | */ | ||
498 | surf.format = V_028C70_COLOR_8_8_8_8; | ||
499 | r = evergreen_surface_check(p, &surf, "stencil"); | ||
500 | if (r) { | ||
501 | dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", | ||
502 | __func__, __LINE__, track->db_depth_size, | ||
503 | track->db_depth_slice, track->db_s_info, track->db_z_info); | ||
504 | } | ||
505 | return r; | ||
506 | } | ||
507 | |||
508 | offset = track->db_s_read_offset << 8; | ||
509 | if (offset & (surf.base_align - 1)) { | ||
510 | dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", | ||
511 | __func__, __LINE__, offset, surf.base_align); | ||
512 | return -EINVAL; | ||
513 | } | ||
514 | offset += surf.layer_size * mslice; | ||
515 | if (offset > radeon_bo_size(track->db_s_read_bo)) { | ||
516 | dev_warn(p->dev, "%s:%d stencil read bo too small (layer size %d, " | ||
517 | "offset %ld, max layer %d, bo size %ld)\n", | ||
518 | __func__, __LINE__, surf.layer_size, | ||
519 | (unsigned long)track->db_s_read_offset << 8, mslice, | ||
520 | radeon_bo_size(track->db_s_read_bo)); | ||
521 | dev_warn(p->dev, "%s:%d stencil invalid (0x%08x 0x%08x 0x%08x 0x%08x)\n", | ||
522 | __func__, __LINE__, track->db_depth_size, | ||
523 | track->db_depth_slice, track->db_s_info, track->db_z_info); | ||
524 | return -EINVAL; | ||
525 | } | ||
526 | |||
527 | offset = track->db_s_write_offset << 8; | ||
528 | if (offset & (surf.base_align - 1)) { | ||
529 | dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", | ||
530 | __func__, __LINE__, offset, surf.base_align); | ||
531 | return -EINVAL; | ||
532 | } | ||
533 | offset += surf.layer_size * mslice; | ||
534 | if (offset > radeon_bo_size(track->db_s_write_bo)) { | ||
535 | dev_warn(p->dev, "%s:%d stencil write bo too small (layer size %d, " | ||
536 | "offset %ld, max layer %d, bo size %ld)\n", | ||
537 | __func__, __LINE__, surf.layer_size, | ||
538 | (unsigned long)track->db_s_write_offset << 8, mslice, | ||
539 | radeon_bo_size(track->db_s_write_bo)); | ||
540 | return -EINVAL; | ||
541 | } | ||
542 | |||
543 | return 0; | ||
544 | } | ||
545 | |||
546 | static int evergreen_cs_track_validate_depth(struct radeon_cs_parser *p) | ||
547 | { | ||
548 | struct evergreen_cs_track *track = p->track; | ||
549 | struct eg_surface surf; | ||
550 | unsigned pitch, slice, mslice; | ||
551 | unsigned long offset; | ||
552 | int r; | ||
553 | |||
554 | mslice = G_028008_SLICE_MAX(track->db_depth_view) + 1; | ||
555 | pitch = G_028058_PITCH_TILE_MAX(track->db_depth_size); | ||
556 | slice = track->db_depth_slice; | ||
557 | surf.nbx = (pitch + 1) * 8; | ||
558 | surf.nby = ((slice + 1) * 64) / surf.nbx; | ||
559 | surf.mode = G_028040_ARRAY_MODE(track->db_z_info); | ||
560 | surf.format = G_028040_FORMAT(track->db_z_info); | ||
561 | surf.tsplit = G_028040_TILE_SPLIT(track->db_z_info); | ||
562 | surf.nbanks = G_028040_NUM_BANKS(track->db_z_info); | ||
563 | surf.bankw = G_028040_BANK_WIDTH(track->db_z_info); | ||
564 | surf.bankh = G_028040_BANK_HEIGHT(track->db_z_info); | ||
565 | surf.mtilea = G_028040_MACRO_TILE_ASPECT(track->db_z_info); | ||
566 | surf.nsamples = 1; | ||
567 | |||
568 | switch (surf.format) { | ||
569 | case V_028040_Z_16: | ||
570 | surf.format = V_028C70_COLOR_16; | ||
571 | break; | ||
572 | case V_028040_Z_24: | ||
573 | case V_028040_Z_32_FLOAT: | ||
574 | surf.format = V_028C70_COLOR_8_8_8_8; | ||
575 | break; | ||
576 | default: | ||
577 | dev_warn(p->dev, "%s:%d depth invalid format %d\n", | ||
578 | __func__, __LINE__, surf.format); | ||
579 | return -EINVAL; | ||
580 | } | ||
581 | |||
582 | r = evergreen_surface_value_conv_check(p, &surf, "depth"); | ||
583 | if (r) { | ||
584 | dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n", | ||
585 | __func__, __LINE__, track->db_depth_size, | ||
586 | track->db_depth_slice, track->db_z_info); | ||
587 | return r; | ||
588 | } | ||
589 | |||
590 | r = evergreen_surface_check(p, &surf, "depth"); | ||
591 | if (r) { | ||
592 | dev_warn(p->dev, "%s:%d depth invalid (0x%08x 0x%08x 0x%08x)\n", | ||
593 | __func__, __LINE__, track->db_depth_size, | ||
594 | track->db_depth_slice, track->db_z_info); | ||
595 | return r; | ||
596 | } | ||
597 | |||
598 | offset = track->db_z_read_offset << 8; | ||
599 | if (offset & (surf.base_align - 1)) { | ||
600 | dev_warn(p->dev, "%s:%d stencil read bo base %ld not aligned with %ld\n", | ||
601 | __func__, __LINE__, offset, surf.base_align); | ||
602 | return -EINVAL; | ||
603 | } | ||
604 | offset += surf.layer_size * mslice; | ||
605 | if (offset > radeon_bo_size(track->db_z_read_bo)) { | ||
606 | dev_warn(p->dev, "%s:%d depth read bo too small (layer size %d, " | ||
607 | "offset %ld, max layer %d, bo size %ld)\n", | ||
608 | __func__, __LINE__, surf.layer_size, | ||
609 | (unsigned long)track->db_z_read_offset << 8, mslice, | ||
610 | radeon_bo_size(track->db_z_read_bo)); | ||
611 | return -EINVAL; | ||
612 | } | ||
613 | |||
614 | offset = track->db_z_write_offset << 8; | ||
615 | if (offset & (surf.base_align - 1)) { | ||
616 | dev_warn(p->dev, "%s:%d stencil write bo base %ld not aligned with %ld\n", | ||
617 | __func__, __LINE__, offset, surf.base_align); | ||
618 | return -EINVAL; | ||
619 | } | ||
620 | offset += surf.layer_size * mslice; | ||
621 | if (offset > radeon_bo_size(track->db_z_write_bo)) { | ||
622 | dev_warn(p->dev, "%s:%d depth write bo too small (layer size %d, " | ||
623 | "offset %ld, max layer %d, bo size %ld)\n", | ||
624 | __func__, __LINE__, surf.layer_size, | ||
625 | (unsigned long)track->db_z_write_offset << 8, mslice, | ||
626 | radeon_bo_size(track->db_z_write_bo)); | ||
627 | return -EINVAL; | ||
628 | } | ||
629 | |||
630 | return 0; | ||
631 | } | ||
632 | |||
633 | static int evergreen_cs_track_validate_texture(struct radeon_cs_parser *p, | ||
634 | struct radeon_bo *texture, | ||
635 | struct radeon_bo *mipmap, | ||
636 | unsigned idx) | ||
637 | { | ||
638 | struct eg_surface surf; | ||
639 | unsigned long toffset, moffset; | ||
640 | unsigned dim, llevel, mslice, width, height, depth, i; | ||
641 | u32 texdw[8]; | ||
642 | int r; | ||
643 | |||
644 | texdw[0] = radeon_get_ib_value(p, idx + 0); | ||
645 | texdw[1] = radeon_get_ib_value(p, idx + 1); | ||
646 | texdw[2] = radeon_get_ib_value(p, idx + 2); | ||
647 | texdw[3] = radeon_get_ib_value(p, idx + 3); | ||
648 | texdw[4] = radeon_get_ib_value(p, idx + 4); | ||
649 | texdw[5] = radeon_get_ib_value(p, idx + 5); | ||
650 | texdw[6] = radeon_get_ib_value(p, idx + 6); | ||
651 | texdw[7] = radeon_get_ib_value(p, idx + 7); | ||
652 | dim = G_030000_DIM(texdw[0]); | ||
653 | llevel = G_030014_LAST_LEVEL(texdw[5]); | ||
654 | mslice = G_030014_LAST_ARRAY(texdw[5]) + 1; | ||
655 | width = G_030000_TEX_WIDTH(texdw[0]) + 1; | ||
656 | height = G_030004_TEX_HEIGHT(texdw[1]) + 1; | ||
657 | depth = G_030004_TEX_DEPTH(texdw[1]) + 1; | ||
658 | surf.format = G_03001C_DATA_FORMAT(texdw[7]); | ||
659 | surf.nbx = (G_030000_PITCH(texdw[0]) + 1) * 8; | ||
660 | surf.nbx = r600_fmt_get_nblocksx(surf.format, surf.nbx); | ||
661 | surf.nby = r600_fmt_get_nblocksy(surf.format, height); | ||
662 | surf.mode = G_030004_ARRAY_MODE(texdw[1]); | ||
663 | surf.tsplit = G_030018_TILE_SPLIT(texdw[6]); | ||
664 | surf.nbanks = G_03001C_NUM_BANKS(texdw[7]); | ||
665 | surf.bankw = G_03001C_BANK_WIDTH(texdw[7]); | ||
666 | surf.bankh = G_03001C_BANK_HEIGHT(texdw[7]); | ||
667 | surf.mtilea = G_03001C_MACRO_TILE_ASPECT(texdw[7]); | ||
668 | surf.nsamples = 1; | ||
669 | toffset = texdw[2] << 8; | ||
670 | moffset = texdw[3] << 8; | ||
167 | 671 | ||
168 | /* we don't support stream out buffer yet */ | 672 | if (!r600_fmt_is_valid_texture(surf.format, p->family)) { |
169 | if (track->vgt_strmout_config || track->vgt_strmout_buffer_config) { | 673 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
170 | dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n"); | 674 | __func__, __LINE__, surf.format); |
171 | return -EINVAL; | 675 | return -EINVAL; |
172 | } | 676 | } |
677 | switch (dim) { | ||
678 | case V_030000_SQ_TEX_DIM_1D: | ||
679 | case V_030000_SQ_TEX_DIM_2D: | ||
680 | case V_030000_SQ_TEX_DIM_CUBEMAP: | ||
681 | case V_030000_SQ_TEX_DIM_1D_ARRAY: | ||
682 | case V_030000_SQ_TEX_DIM_2D_ARRAY: | ||
683 | depth = 1; | ||
684 | case V_030000_SQ_TEX_DIM_3D: | ||
685 | break; | ||
686 | default: | ||
687 | dev_warn(p->dev, "%s:%d texture invalid dimension %d\n", | ||
688 | __func__, __LINE__, dim); | ||
689 | return -EINVAL; | ||
690 | } | ||
691 | |||
692 | r = evergreen_surface_value_conv_check(p, &surf, "texture"); | ||
693 | if (r) { | ||
694 | return r; | ||
695 | } | ||
696 | |||
697 | /* align height */ | ||
698 | evergreen_surface_check(p, &surf, NULL); | ||
699 | surf.nby = ALIGN(surf.nby, surf.halign); | ||
700 | |||
701 | r = evergreen_surface_check(p, &surf, "texture"); | ||
702 | if (r) { | ||
703 | dev_warn(p->dev, "%s:%d texture invalid 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n", | ||
704 | __func__, __LINE__, texdw[0], texdw[1], texdw[4], | ||
705 | texdw[5], texdw[6], texdw[7]); | ||
706 | return r; | ||
707 | } | ||
708 | |||
709 | /* check texture size */ | ||
710 | if (toffset & (surf.base_align - 1)) { | ||
711 | dev_warn(p->dev, "%s:%d texture bo base %ld not aligned with %ld\n", | ||
712 | __func__, __LINE__, toffset, surf.base_align); | ||
713 | return -EINVAL; | ||
714 | } | ||
715 | if (moffset & (surf.base_align - 1)) { | ||
716 | dev_warn(p->dev, "%s:%d mipmap bo base %ld not aligned with %ld\n", | ||
717 | __func__, __LINE__, moffset, surf.base_align); | ||
718 | return -EINVAL; | ||
719 | } | ||
720 | if (dim == SQ_TEX_DIM_3D) { | ||
721 | toffset += surf.layer_size * depth; | ||
722 | } else { | ||
723 | toffset += surf.layer_size * mslice; | ||
724 | } | ||
725 | if (toffset > radeon_bo_size(texture)) { | ||
726 | dev_warn(p->dev, "%s:%d texture bo too small (layer size %d, " | ||
727 | "offset %ld, max layer %d, depth %d, bo size %ld) (%d %d)\n", | ||
728 | __func__, __LINE__, surf.layer_size, | ||
729 | (unsigned long)texdw[2] << 8, mslice, | ||
730 | depth, radeon_bo_size(texture), | ||
731 | surf.nbx, surf.nby); | ||
732 | return -EINVAL; | ||
733 | } | ||
734 | |||
735 | /* check mipmap size */ | ||
736 | for (i = 1; i <= llevel; i++) { | ||
737 | unsigned w, h, d; | ||
738 | |||
739 | w = r600_mip_minify(width, i); | ||
740 | h = r600_mip_minify(height, i); | ||
741 | d = r600_mip_minify(depth, i); | ||
742 | surf.nbx = r600_fmt_get_nblocksx(surf.format, w); | ||
743 | surf.nby = r600_fmt_get_nblocksy(surf.format, h); | ||
744 | |||
745 | switch (surf.mode) { | ||
746 | case ARRAY_2D_TILED_THIN1: | ||
747 | if (surf.nbx < surf.palign || surf.nby < surf.halign) { | ||
748 | surf.mode = ARRAY_1D_TILED_THIN1; | ||
749 | } | ||
750 | /* recompute alignment */ | ||
751 | evergreen_surface_check(p, &surf, NULL); | ||
752 | break; | ||
753 | case ARRAY_LINEAR_GENERAL: | ||
754 | case ARRAY_LINEAR_ALIGNED: | ||
755 | case ARRAY_1D_TILED_THIN1: | ||
756 | break; | ||
757 | default: | ||
758 | dev_warn(p->dev, "%s:%d invalid array mode %d\n", | ||
759 | __func__, __LINE__, surf.mode); | ||
760 | return -EINVAL; | ||
761 | } | ||
762 | surf.nbx = ALIGN(surf.nbx, surf.palign); | ||
763 | surf.nby = ALIGN(surf.nby, surf.halign); | ||
764 | |||
765 | r = evergreen_surface_check(p, &surf, "mipmap"); | ||
766 | if (r) { | ||
767 | return r; | ||
768 | } | ||
769 | |||
770 | if (dim == SQ_TEX_DIM_3D) { | ||
771 | moffset += surf.layer_size * d; | ||
772 | } else { | ||
773 | moffset += surf.layer_size * mslice; | ||
774 | } | ||
775 | if (moffset > radeon_bo_size(mipmap)) { | ||
776 | dev_warn(p->dev, "%s:%d mipmap [%d] bo too small (layer size %d, " | ||
777 | "offset %ld, coffset %ld, max layer %d, depth %d, " | ||
778 | "bo size %ld) level0 (%d %d %d)\n", | ||
779 | __func__, __LINE__, i, surf.layer_size, | ||
780 | (unsigned long)texdw[3] << 8, moffset, mslice, | ||
781 | d, radeon_bo_size(mipmap), | ||
782 | width, height, depth); | ||
783 | dev_warn(p->dev, "%s:%d problematic surf: (%d %d) (%d %d %d %d %d %d %d)\n", | ||
784 | __func__, __LINE__, surf.nbx, surf.nby, | ||
785 | surf.mode, surf.bpe, surf.nsamples, | ||
786 | surf.bankw, surf.bankh, | ||
787 | surf.tsplit, surf.mtilea); | ||
788 | return -EINVAL; | ||
789 | } | ||
790 | } | ||
791 | |||
792 | return 0; | ||
793 | } | ||
794 | |||
795 | static int evergreen_cs_track_check(struct radeon_cs_parser *p) | ||
796 | { | ||
797 | struct evergreen_cs_track *track = p->track; | ||
798 | unsigned tmp, i, j; | ||
799 | int r; | ||
800 | |||
801 | /* check streamout */ | ||
802 | for (i = 0; i < 4; i++) { | ||
803 | if (track->vgt_strmout_config & (1 << i)) { | ||
804 | for (j = 0; j < 4; j++) { | ||
805 | if ((track->vgt_strmout_buffer_config >> (i * 4)) & (1 << j)) { | ||
806 | if (track->vgt_strmout_bo[j]) { | ||
807 | u64 offset = (u64)track->vgt_strmout_bo_offset[j] + | ||
808 | (u64)track->vgt_strmout_size[j]; | ||
809 | if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) { | ||
810 | DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n", | ||
811 | j, offset, | ||
812 | radeon_bo_size(track->vgt_strmout_bo[j])); | ||
813 | return -EINVAL; | ||
814 | } | ||
815 | } else { | ||
816 | dev_warn(p->dev, "No buffer for streamout %d\n", j); | ||
817 | return -EINVAL; | ||
818 | } | ||
819 | } | ||
820 | } | ||
821 | } | ||
822 | } | ||
823 | |||
824 | /* check that we have a cb for each enabled target | ||
825 | */ | ||
826 | tmp = track->cb_target_mask; | ||
827 | for (i = 0; i < 8; i++) { | ||
828 | if ((tmp >> (i * 4)) & 0xF) { | ||
829 | /* at least one component is enabled */ | ||
830 | if (track->cb_color_bo[i] == NULL) { | ||
831 | dev_warn(p->dev, "%s:%d mask 0x%08X | 0x%08X no cb for %d\n", | ||
832 | __func__, __LINE__, track->cb_target_mask, track->cb_shader_mask, i); | ||
833 | return -EINVAL; | ||
834 | } | ||
835 | /* check cb */ | ||
836 | r = evergreen_cs_track_validate_cb(p, i); | ||
837 | if (r) { | ||
838 | return r; | ||
839 | } | ||
840 | } | ||
841 | } | ||
842 | |||
843 | /* Check stencil buffer */ | ||
844 | if (G_028800_STENCIL_ENABLE(track->db_depth_control)) { | ||
845 | r = evergreen_cs_track_validate_stencil(p); | ||
846 | if (r) | ||
847 | return r; | ||
848 | } | ||
849 | /* Check depth buffer */ | ||
850 | if (G_028800_Z_WRITE_ENABLE(track->db_depth_control)) { | ||
851 | r = evergreen_cs_track_validate_depth(p); | ||
852 | if (r) | ||
853 | return r; | ||
854 | } | ||
173 | 855 | ||
174 | /* XXX fill in */ | ||
175 | return 0; | 856 | return 0; |
176 | } | 857 | } |
177 | 858 | ||
@@ -532,8 +1213,16 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
532 | ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | 1213 | ib[idx] |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
533 | track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | 1214 | track->db_z_info |= Z_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
534 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 1215 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { |
1216 | unsigned bankw, bankh, mtaspect, tile_split; | ||
1217 | |||
1218 | evergreen_tiling_fields(reloc->lobj.tiling_flags, | ||
1219 | &bankw, &bankh, &mtaspect, | ||
1220 | &tile_split); | ||
535 | ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | 1221 | ib[idx] |= DB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); |
536 | ib[idx] |= DB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); | 1222 | ib[idx] |= DB_TILE_SPLIT(tile_split) | |
1223 | DB_BANK_WIDTH(bankw) | | ||
1224 | DB_BANK_HEIGHT(bankh) | | ||
1225 | DB_MACRO_TILE_ASPECT(mtaspect); | ||
537 | } | 1226 | } |
538 | } | 1227 | } |
539 | break; | 1228 | break; |
@@ -547,6 +1236,9 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
547 | track->db_depth_size = radeon_get_ib_value(p, idx); | 1236 | track->db_depth_size = radeon_get_ib_value(p, idx); |
548 | track->db_depth_size_idx = idx; | 1237 | track->db_depth_size_idx = idx; |
549 | break; | 1238 | break; |
1239 | case R_02805C_DB_DEPTH_SLICE: | ||
1240 | track->db_depth_slice = radeon_get_ib_value(p, idx); | ||
1241 | break; | ||
550 | case DB_Z_READ_BASE: | 1242 | case DB_Z_READ_BASE: |
551 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 1243 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
552 | if (r) { | 1244 | if (r) { |
@@ -597,6 +1289,38 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
597 | case VGT_STRMOUT_BUFFER_CONFIG: | 1289 | case VGT_STRMOUT_BUFFER_CONFIG: |
598 | track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx); | 1290 | track->vgt_strmout_buffer_config = radeon_get_ib_value(p, idx); |
599 | break; | 1291 | break; |
1292 | case VGT_STRMOUT_BUFFER_BASE_0: | ||
1293 | case VGT_STRMOUT_BUFFER_BASE_1: | ||
1294 | case VGT_STRMOUT_BUFFER_BASE_2: | ||
1295 | case VGT_STRMOUT_BUFFER_BASE_3: | ||
1296 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
1297 | if (r) { | ||
1298 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
1299 | "0x%04X\n", reg); | ||
1300 | return -EINVAL; | ||
1301 | } | ||
1302 | tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16; | ||
1303 | track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; | ||
1304 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1305 | track->vgt_strmout_bo[tmp] = reloc->robj; | ||
1306 | track->vgt_strmout_bo_mc[tmp] = reloc->lobj.gpu_offset; | ||
1307 | break; | ||
1308 | case VGT_STRMOUT_BUFFER_SIZE_0: | ||
1309 | case VGT_STRMOUT_BUFFER_SIZE_1: | ||
1310 | case VGT_STRMOUT_BUFFER_SIZE_2: | ||
1311 | case VGT_STRMOUT_BUFFER_SIZE_3: | ||
1312 | tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16; | ||
1313 | /* size in register is DWs, convert to bytes */ | ||
1314 | track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4; | ||
1315 | break; | ||
1316 | case CP_COHER_BASE: | ||
1317 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
1318 | if (r) { | ||
1319 | dev_warn(p->dev, "missing reloc for CP_COHER_BASE " | ||
1320 | "0x%04X\n", reg); | ||
1321 | return -EINVAL; | ||
1322 | } | ||
1323 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
600 | case CB_TARGET_MASK: | 1324 | case CB_TARGET_MASK: |
601 | track->cb_target_mask = radeon_get_ib_value(p, idx); | 1325 | track->cb_target_mask = radeon_get_ib_value(p, idx); |
602 | break; | 1326 | break; |
@@ -725,6 +1449,29 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
725 | case CB_COLOR5_ATTRIB: | 1449 | case CB_COLOR5_ATTRIB: |
726 | case CB_COLOR6_ATTRIB: | 1450 | case CB_COLOR6_ATTRIB: |
727 | case CB_COLOR7_ATTRIB: | 1451 | case CB_COLOR7_ATTRIB: |
1452 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
1453 | if (r) { | ||
1454 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
1455 | "0x%04X\n", reg); | ||
1456 | return -EINVAL; | ||
1457 | } | ||
1458 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { | ||
1459 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | ||
1460 | unsigned bankw, bankh, mtaspect, tile_split; | ||
1461 | |||
1462 | evergreen_tiling_fields(reloc->lobj.tiling_flags, | ||
1463 | &bankw, &bankh, &mtaspect, | ||
1464 | &tile_split); | ||
1465 | ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | ||
1466 | ib[idx] |= CB_TILE_SPLIT(tile_split) | | ||
1467 | CB_BANK_WIDTH(bankw) | | ||
1468 | CB_BANK_HEIGHT(bankh) | | ||
1469 | CB_MACRO_TILE_ASPECT(mtaspect); | ||
1470 | } | ||
1471 | } | ||
1472 | tmp = ((reg - CB_COLOR0_ATTRIB) / 0x3c); | ||
1473 | track->cb_color_attrib[tmp] = ib[idx]; | ||
1474 | break; | ||
728 | case CB_COLOR8_ATTRIB: | 1475 | case CB_COLOR8_ATTRIB: |
729 | case CB_COLOR9_ATTRIB: | 1476 | case CB_COLOR9_ATTRIB: |
730 | case CB_COLOR10_ATTRIB: | 1477 | case CB_COLOR10_ATTRIB: |
@@ -735,10 +1482,22 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
735 | "0x%04X\n", reg); | 1482 | "0x%04X\n", reg); |
736 | return -EINVAL; | 1483 | return -EINVAL; |
737 | } | 1484 | } |
738 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 1485 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
739 | ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | 1486 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { |
740 | ib[idx] |= CB_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); | 1487 | unsigned bankw, bankh, mtaspect, tile_split; |
1488 | |||
1489 | evergreen_tiling_fields(reloc->lobj.tiling_flags, | ||
1490 | &bankw, &bankh, &mtaspect, | ||
1491 | &tile_split); | ||
1492 | ib[idx] |= CB_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | ||
1493 | ib[idx] |= CB_TILE_SPLIT(tile_split) | | ||
1494 | CB_BANK_WIDTH(bankw) | | ||
1495 | CB_BANK_HEIGHT(bankh) | | ||
1496 | CB_MACRO_TILE_ASPECT(mtaspect); | ||
1497 | } | ||
741 | } | 1498 | } |
1499 | tmp = ((reg - CB_COLOR8_ATTRIB) / 0x1c) + 8; | ||
1500 | track->cb_color_attrib[tmp] = ib[idx]; | ||
742 | break; | 1501 | break; |
743 | case CB_COLOR0_DIM: | 1502 | case CB_COLOR0_DIM: |
744 | case CB_COLOR1_DIM: | 1503 | case CB_COLOR1_DIM: |
@@ -996,22 +1755,30 @@ static int evergreen_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
996 | return 0; | 1755 | return 0; |
997 | } | 1756 | } |
998 | 1757 | ||
999 | /** | 1758 | static bool evergreen_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) |
1000 | * evergreen_check_texture_resource() - check if register is authorized or not | ||
1001 | * @p: parser structure holding parsing context | ||
1002 | * @idx: index into the cs buffer | ||
1003 | * @texture: texture's bo structure | ||
1004 | * @mipmap: mipmap's bo structure | ||
1005 | * | ||
1006 | * This function will check that the resource has valid field and that | ||
1007 | * the texture and mipmap bo object are big enough to cover this resource. | ||
1008 | */ | ||
1009 | static int evergreen_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | ||
1010 | struct radeon_bo *texture, | ||
1011 | struct radeon_bo *mipmap) | ||
1012 | { | 1759 | { |
1013 | /* XXX fill in */ | 1760 | u32 last_reg, m, i; |
1014 | return 0; | 1761 | |
1762 | if (p->rdev->family >= CHIP_CAYMAN) | ||
1763 | last_reg = ARRAY_SIZE(cayman_reg_safe_bm); | ||
1764 | else | ||
1765 | last_reg = ARRAY_SIZE(evergreen_reg_safe_bm); | ||
1766 | |||
1767 | i = (reg >> 7); | ||
1768 | if (i >= last_reg) { | ||
1769 | dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); | ||
1770 | return false; | ||
1771 | } | ||
1772 | m = 1 << ((reg >> 2) & 31); | ||
1773 | if (p->rdev->family >= CHIP_CAYMAN) { | ||
1774 | if (!(cayman_reg_safe_bm[i] & m)) | ||
1775 | return true; | ||
1776 | } else { | ||
1777 | if (!(evergreen_reg_safe_bm[i] & m)) | ||
1778 | return true; | ||
1779 | } | ||
1780 | dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); | ||
1781 | return false; | ||
1015 | } | 1782 | } |
1016 | 1783 | ||
1017 | static int evergreen_packet3_check(struct radeon_cs_parser *p, | 1784 | static int evergreen_packet3_check(struct radeon_cs_parser *p, |
@@ -1344,6 +2111,7 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
1344 | } | 2111 | } |
1345 | for (i = 0; i < (pkt->count / 8); i++) { | 2112 | for (i = 0; i < (pkt->count / 8); i++) { |
1346 | struct radeon_bo *texture, *mipmap; | 2113 | struct radeon_bo *texture, *mipmap; |
2114 | u32 toffset, moffset; | ||
1347 | u32 size, offset; | 2115 | u32 size, offset; |
1348 | 2116 | ||
1349 | switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { | 2117 | switch (G__SQ_CONSTANT_TYPE(radeon_get_ib_value(p, idx+1+(i*8)+7))) { |
@@ -1354,30 +2122,38 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
1354 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); | 2122 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); |
1355 | return -EINVAL; | 2123 | return -EINVAL; |
1356 | } | 2124 | } |
1357 | ib[idx+1+(i*8)+2] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1358 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { | 2125 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
1359 | ib[idx+1+(i*8)+1] |= | 2126 | ib[idx+1+(i*8)+1] |= |
1360 | TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); | 2127 | TEX_ARRAY_MODE(evergreen_cs_get_aray_mode(reloc->lobj.tiling_flags)); |
1361 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { | 2128 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) { |
1362 | ib[idx+1+(i*8)+6] |= | 2129 | unsigned bankw, bankh, mtaspect, tile_split; |
1363 | TEX_TILE_SPLIT(evergreen_cs_get_tile_split(track->row_size)); | 2130 | |
2131 | evergreen_tiling_fields(reloc->lobj.tiling_flags, | ||
2132 | &bankw, &bankh, &mtaspect, | ||
2133 | &tile_split); | ||
2134 | ib[idx+1+(i*8)+6] |= TEX_TILE_SPLIT(tile_split); | ||
1364 | ib[idx+1+(i*8)+7] |= | 2135 | ib[idx+1+(i*8)+7] |= |
2136 | TEX_BANK_WIDTH(bankw) | | ||
2137 | TEX_BANK_HEIGHT(bankh) | | ||
2138 | MACRO_TILE_ASPECT(mtaspect) | | ||
1365 | TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); | 2139 | TEX_NUM_BANKS(evergreen_cs_get_num_banks(track->nbanks)); |
1366 | } | 2140 | } |
1367 | } | 2141 | } |
1368 | texture = reloc->robj; | 2142 | texture = reloc->robj; |
2143 | toffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1369 | /* tex mip base */ | 2144 | /* tex mip base */ |
1370 | r = evergreen_cs_packet_next_reloc(p, &reloc); | 2145 | r = evergreen_cs_packet_next_reloc(p, &reloc); |
1371 | if (r) { | 2146 | if (r) { |
1372 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); | 2147 | DRM_ERROR("bad SET_RESOURCE (tex)\n"); |
1373 | return -EINVAL; | 2148 | return -EINVAL; |
1374 | } | 2149 | } |
1375 | ib[idx+1+(i*8)+3] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | 2150 | moffset = (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); |
1376 | mipmap = reloc->robj; | 2151 | mipmap = reloc->robj; |
1377 | r = evergreen_check_texture_resource(p, idx+1+(i*8), | 2152 | r = evergreen_cs_track_validate_texture(p, texture, mipmap, idx+1+(i*8)); |
1378 | texture, mipmap); | ||
1379 | if (r) | 2153 | if (r) |
1380 | return r; | 2154 | return r; |
2155 | ib[idx+1+(i*8)+2] += toffset; | ||
2156 | ib[idx+1+(i*8)+3] += moffset; | ||
1381 | break; | 2157 | break; |
1382 | case SQ_TEX_VTX_VALID_BUFFER: | 2158 | case SQ_TEX_VTX_VALID_BUFFER: |
1383 | /* vtx base */ | 2159 | /* vtx base */ |
@@ -1451,6 +2227,100 @@ static int evergreen_packet3_check(struct radeon_cs_parser *p, | |||
1451 | return -EINVAL; | 2227 | return -EINVAL; |
1452 | } | 2228 | } |
1453 | break; | 2229 | break; |
2230 | case PACKET3_STRMOUT_BUFFER_UPDATE: | ||
2231 | if (pkt->count != 4) { | ||
2232 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n"); | ||
2233 | return -EINVAL; | ||
2234 | } | ||
2235 | /* Updating memory at DST_ADDRESS. */ | ||
2236 | if (idx_value & 0x1) { | ||
2237 | u64 offset; | ||
2238 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2239 | if (r) { | ||
2240 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); | ||
2241 | return -EINVAL; | ||
2242 | } | ||
2243 | offset = radeon_get_ib_value(p, idx+1); | ||
2244 | offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; | ||
2245 | if ((offset + 4) > radeon_bo_size(reloc->robj)) { | ||
2246 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n", | ||
2247 | offset + 4, radeon_bo_size(reloc->robj)); | ||
2248 | return -EINVAL; | ||
2249 | } | ||
2250 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
2251 | ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
2252 | } | ||
2253 | /* Reading data from SRC_ADDRESS. */ | ||
2254 | if (((idx_value >> 1) & 0x3) == 2) { | ||
2255 | u64 offset; | ||
2256 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2257 | if (r) { | ||
2258 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); | ||
2259 | return -EINVAL; | ||
2260 | } | ||
2261 | offset = radeon_get_ib_value(p, idx+3); | ||
2262 | offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; | ||
2263 | if ((offset + 4) > radeon_bo_size(reloc->robj)) { | ||
2264 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n", | ||
2265 | offset + 4, radeon_bo_size(reloc->robj)); | ||
2266 | return -EINVAL; | ||
2267 | } | ||
2268 | ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
2269 | ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
2270 | } | ||
2271 | break; | ||
2272 | case PACKET3_COPY_DW: | ||
2273 | if (pkt->count != 4) { | ||
2274 | DRM_ERROR("bad COPY_DW (invalid count)\n"); | ||
2275 | return -EINVAL; | ||
2276 | } | ||
2277 | if (idx_value & 0x1) { | ||
2278 | u64 offset; | ||
2279 | /* SRC is memory. */ | ||
2280 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2281 | if (r) { | ||
2282 | DRM_ERROR("bad COPY_DW (missing src reloc)\n"); | ||
2283 | return -EINVAL; | ||
2284 | } | ||
2285 | offset = radeon_get_ib_value(p, idx+1); | ||
2286 | offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; | ||
2287 | if ((offset + 4) > radeon_bo_size(reloc->robj)) { | ||
2288 | DRM_ERROR("bad COPY_DW src bo too small: 0x%llx, 0x%lx\n", | ||
2289 | offset + 4, radeon_bo_size(reloc->robj)); | ||
2290 | return -EINVAL; | ||
2291 | } | ||
2292 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
2293 | ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
2294 | } else { | ||
2295 | /* SRC is a reg. */ | ||
2296 | reg = radeon_get_ib_value(p, idx+1) << 2; | ||
2297 | if (!evergreen_is_safe_reg(p, reg, idx+1)) | ||
2298 | return -EINVAL; | ||
2299 | } | ||
2300 | if (idx_value & 0x2) { | ||
2301 | u64 offset; | ||
2302 | /* DST is memory. */ | ||
2303 | r = evergreen_cs_packet_next_reloc(p, &reloc); | ||
2304 | if (r) { | ||
2305 | DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); | ||
2306 | return -EINVAL; | ||
2307 | } | ||
2308 | offset = radeon_get_ib_value(p, idx+3); | ||
2309 | offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; | ||
2310 | if ((offset + 4) > radeon_bo_size(reloc->robj)) { | ||
2311 | DRM_ERROR("bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n", | ||
2312 | offset + 4, radeon_bo_size(reloc->robj)); | ||
2313 | return -EINVAL; | ||
2314 | } | ||
2315 | ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
2316 | ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
2317 | } else { | ||
2318 | /* DST is a reg. */ | ||
2319 | reg = radeon_get_ib_value(p, idx+3) << 2; | ||
2320 | if (!evergreen_is_safe_reg(p, reg, idx+3)) | ||
2321 | return -EINVAL; | ||
2322 | } | ||
2323 | break; | ||
1454 | case PACKET3_NOP: | 2324 | case PACKET3_NOP: |
1455 | break; | 2325 | break; |
1456 | default: | 2326 | default: |
diff --git a/drivers/gpu/drm/radeon/evergreend.h b/drivers/gpu/drm/radeon/evergreend.h index 74713d42df29..eb5708c7159d 100644 --- a/drivers/gpu/drm/radeon/evergreend.h +++ b/drivers/gpu/drm/radeon/evergreend.h | |||
@@ -77,6 +77,7 @@ | |||
77 | 77 | ||
78 | #define CONFIG_MEMSIZE 0x5428 | 78 | #define CONFIG_MEMSIZE 0x5428 |
79 | 79 | ||
80 | #define CP_COHER_BASE 0x85F8 | ||
80 | #define CP_ME_CNTL 0x86D8 | 81 | #define CP_ME_CNTL 0x86D8 |
81 | #define CP_ME_HALT (1 << 28) | 82 | #define CP_ME_HALT (1 << 28) |
82 | #define CP_PFP_HALT (1 << 26) | 83 | #define CP_PFP_HALT (1 << 26) |
@@ -925,7 +926,70 @@ | |||
925 | #define DB_DEBUG4 0x983C | 926 | #define DB_DEBUG4 0x983C |
926 | #define DB_WATERMARKS 0x9854 | 927 | #define DB_WATERMARKS 0x9854 |
927 | #define DB_DEPTH_CONTROL 0x28800 | 928 | #define DB_DEPTH_CONTROL 0x28800 |
929 | #define R_028800_DB_DEPTH_CONTROL 0x028800 | ||
930 | #define S_028800_STENCIL_ENABLE(x) (((x) & 0x1) << 0) | ||
931 | #define G_028800_STENCIL_ENABLE(x) (((x) >> 0) & 0x1) | ||
932 | #define C_028800_STENCIL_ENABLE 0xFFFFFFFE | ||
933 | #define S_028800_Z_ENABLE(x) (((x) & 0x1) << 1) | ||
934 | #define G_028800_Z_ENABLE(x) (((x) >> 1) & 0x1) | ||
935 | #define C_028800_Z_ENABLE 0xFFFFFFFD | ||
936 | #define S_028800_Z_WRITE_ENABLE(x) (((x) & 0x1) << 2) | ||
937 | #define G_028800_Z_WRITE_ENABLE(x) (((x) >> 2) & 0x1) | ||
938 | #define C_028800_Z_WRITE_ENABLE 0xFFFFFFFB | ||
939 | #define S_028800_ZFUNC(x) (((x) & 0x7) << 4) | ||
940 | #define G_028800_ZFUNC(x) (((x) >> 4) & 0x7) | ||
941 | #define C_028800_ZFUNC 0xFFFFFF8F | ||
942 | #define S_028800_BACKFACE_ENABLE(x) (((x) & 0x1) << 7) | ||
943 | #define G_028800_BACKFACE_ENABLE(x) (((x) >> 7) & 0x1) | ||
944 | #define C_028800_BACKFACE_ENABLE 0xFFFFFF7F | ||
945 | #define S_028800_STENCILFUNC(x) (((x) & 0x7) << 8) | ||
946 | #define G_028800_STENCILFUNC(x) (((x) >> 8) & 0x7) | ||
947 | #define C_028800_STENCILFUNC 0xFFFFF8FF | ||
948 | #define V_028800_STENCILFUNC_NEVER 0x00000000 | ||
949 | #define V_028800_STENCILFUNC_LESS 0x00000001 | ||
950 | #define V_028800_STENCILFUNC_EQUAL 0x00000002 | ||
951 | #define V_028800_STENCILFUNC_LEQUAL 0x00000003 | ||
952 | #define V_028800_STENCILFUNC_GREATER 0x00000004 | ||
953 | #define V_028800_STENCILFUNC_NOTEQUAL 0x00000005 | ||
954 | #define V_028800_STENCILFUNC_GEQUAL 0x00000006 | ||
955 | #define V_028800_STENCILFUNC_ALWAYS 0x00000007 | ||
956 | #define S_028800_STENCILFAIL(x) (((x) & 0x7) << 11) | ||
957 | #define G_028800_STENCILFAIL(x) (((x) >> 11) & 0x7) | ||
958 | #define C_028800_STENCILFAIL 0xFFFFC7FF | ||
959 | #define V_028800_STENCIL_KEEP 0x00000000 | ||
960 | #define V_028800_STENCIL_ZERO 0x00000001 | ||
961 | #define V_028800_STENCIL_REPLACE 0x00000002 | ||
962 | #define V_028800_STENCIL_INCR 0x00000003 | ||
963 | #define V_028800_STENCIL_DECR 0x00000004 | ||
964 | #define V_028800_STENCIL_INVERT 0x00000005 | ||
965 | #define V_028800_STENCIL_INCR_WRAP 0x00000006 | ||
966 | #define V_028800_STENCIL_DECR_WRAP 0x00000007 | ||
967 | #define S_028800_STENCILZPASS(x) (((x) & 0x7) << 14) | ||
968 | #define G_028800_STENCILZPASS(x) (((x) >> 14) & 0x7) | ||
969 | #define C_028800_STENCILZPASS 0xFFFE3FFF | ||
970 | #define S_028800_STENCILZFAIL(x) (((x) & 0x7) << 17) | ||
971 | #define G_028800_STENCILZFAIL(x) (((x) >> 17) & 0x7) | ||
972 | #define C_028800_STENCILZFAIL 0xFFF1FFFF | ||
973 | #define S_028800_STENCILFUNC_BF(x) (((x) & 0x7) << 20) | ||
974 | #define G_028800_STENCILFUNC_BF(x) (((x) >> 20) & 0x7) | ||
975 | #define C_028800_STENCILFUNC_BF 0xFF8FFFFF | ||
976 | #define S_028800_STENCILFAIL_BF(x) (((x) & 0x7) << 23) | ||
977 | #define G_028800_STENCILFAIL_BF(x) (((x) >> 23) & 0x7) | ||
978 | #define C_028800_STENCILFAIL_BF 0xFC7FFFFF | ||
979 | #define S_028800_STENCILZPASS_BF(x) (((x) & 0x7) << 26) | ||
980 | #define G_028800_STENCILZPASS_BF(x) (((x) >> 26) & 0x7) | ||
981 | #define C_028800_STENCILZPASS_BF 0xE3FFFFFF | ||
982 | #define S_028800_STENCILZFAIL_BF(x) (((x) & 0x7) << 29) | ||
983 | #define G_028800_STENCILZFAIL_BF(x) (((x) >> 29) & 0x7) | ||
984 | #define C_028800_STENCILZFAIL_BF 0x1FFFFFFF | ||
928 | #define DB_DEPTH_VIEW 0x28008 | 985 | #define DB_DEPTH_VIEW 0x28008 |
986 | #define R_028008_DB_DEPTH_VIEW 0x00028008 | ||
987 | #define S_028008_SLICE_START(x) (((x) & 0x7FF) << 0) | ||
988 | #define G_028008_SLICE_START(x) (((x) >> 0) & 0x7FF) | ||
989 | #define C_028008_SLICE_START 0xFFFFF800 | ||
990 | #define S_028008_SLICE_MAX(x) (((x) & 0x7FF) << 13) | ||
991 | #define G_028008_SLICE_MAX(x) (((x) >> 13) & 0x7FF) | ||
992 | #define C_028008_SLICE_MAX 0xFF001FFF | ||
929 | #define DB_HTILE_DATA_BASE 0x28014 | 993 | #define DB_HTILE_DATA_BASE 0x28014 |
930 | #define DB_Z_INFO 0x28040 | 994 | #define DB_Z_INFO 0x28040 |
931 | # define Z_ARRAY_MODE(x) ((x) << 4) | 995 | # define Z_ARRAY_MODE(x) ((x) << 4) |
@@ -933,12 +997,59 @@ | |||
933 | # define DB_NUM_BANKS(x) (((x) & 0x3) << 12) | 997 | # define DB_NUM_BANKS(x) (((x) & 0x3) << 12) |
934 | # define DB_BANK_WIDTH(x) (((x) & 0x3) << 16) | 998 | # define DB_BANK_WIDTH(x) (((x) & 0x3) << 16) |
935 | # define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20) | 999 | # define DB_BANK_HEIGHT(x) (((x) & 0x3) << 20) |
1000 | # define DB_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 24) | ||
1001 | #define R_028040_DB_Z_INFO 0x028040 | ||
1002 | #define S_028040_FORMAT(x) (((x) & 0x3) << 0) | ||
1003 | #define G_028040_FORMAT(x) (((x) >> 0) & 0x3) | ||
1004 | #define C_028040_FORMAT 0xFFFFFFFC | ||
1005 | #define V_028040_Z_INVALID 0x00000000 | ||
1006 | #define V_028040_Z_16 0x00000001 | ||
1007 | #define V_028040_Z_24 0x00000002 | ||
1008 | #define V_028040_Z_32_FLOAT 0x00000003 | ||
1009 | #define S_028040_ARRAY_MODE(x) (((x) & 0xF) << 4) | ||
1010 | #define G_028040_ARRAY_MODE(x) (((x) >> 4) & 0xF) | ||
1011 | #define C_028040_ARRAY_MODE 0xFFFFFF0F | ||
1012 | #define S_028040_READ_SIZE(x) (((x) & 0x1) << 28) | ||
1013 | #define G_028040_READ_SIZE(x) (((x) >> 28) & 0x1) | ||
1014 | #define C_028040_READ_SIZE 0xEFFFFFFF | ||
1015 | #define S_028040_TILE_SURFACE_ENABLE(x) (((x) & 0x1) << 29) | ||
1016 | #define G_028040_TILE_SURFACE_ENABLE(x) (((x) >> 29) & 0x1) | ||
1017 | #define C_028040_TILE_SURFACE_ENABLE 0xDFFFFFFF | ||
1018 | #define S_028040_ZRANGE_PRECISION(x) (((x) & 0x1) << 31) | ||
1019 | #define G_028040_ZRANGE_PRECISION(x) (((x) >> 31) & 0x1) | ||
1020 | #define C_028040_ZRANGE_PRECISION 0x7FFFFFFF | ||
1021 | #define S_028040_TILE_SPLIT(x) (((x) & 0x7) << 8) | ||
1022 | #define G_028040_TILE_SPLIT(x) (((x) >> 8) & 0x7) | ||
1023 | #define S_028040_NUM_BANKS(x) (((x) & 0x3) << 12) | ||
1024 | #define G_028040_NUM_BANKS(x) (((x) >> 12) & 0x3) | ||
1025 | #define S_028040_BANK_WIDTH(x) (((x) & 0x3) << 16) | ||
1026 | #define G_028040_BANK_WIDTH(x) (((x) >> 16) & 0x3) | ||
1027 | #define S_028040_BANK_HEIGHT(x) (((x) & 0x3) << 20) | ||
1028 | #define G_028040_BANK_HEIGHT(x) (((x) >> 20) & 0x3) | ||
1029 | #define S_028040_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 24) | ||
1030 | #define G_028040_MACRO_TILE_ASPECT(x) (((x) >> 24) & 0x3) | ||
936 | #define DB_STENCIL_INFO 0x28044 | 1031 | #define DB_STENCIL_INFO 0x28044 |
1032 | #define R_028044_DB_STENCIL_INFO 0x028044 | ||
1033 | #define S_028044_FORMAT(x) (((x) & 0x1) << 0) | ||
1034 | #define G_028044_FORMAT(x) (((x) >> 0) & 0x1) | ||
1035 | #define C_028044_FORMAT 0xFFFFFFFE | ||
1036 | #define G_028044_TILE_SPLIT(x) (((x) >> 8) & 0x7) | ||
937 | #define DB_Z_READ_BASE 0x28048 | 1037 | #define DB_Z_READ_BASE 0x28048 |
938 | #define DB_STENCIL_READ_BASE 0x2804c | 1038 | #define DB_STENCIL_READ_BASE 0x2804c |
939 | #define DB_Z_WRITE_BASE 0x28050 | 1039 | #define DB_Z_WRITE_BASE 0x28050 |
940 | #define DB_STENCIL_WRITE_BASE 0x28054 | 1040 | #define DB_STENCIL_WRITE_BASE 0x28054 |
941 | #define DB_DEPTH_SIZE 0x28058 | 1041 | #define DB_DEPTH_SIZE 0x28058 |
1042 | #define R_028058_DB_DEPTH_SIZE 0x028058 | ||
1043 | #define S_028058_PITCH_TILE_MAX(x) (((x) & 0x7FF) << 0) | ||
1044 | #define G_028058_PITCH_TILE_MAX(x) (((x) >> 0) & 0x7FF) | ||
1045 | #define C_028058_PITCH_TILE_MAX 0xFFFFF800 | ||
1046 | #define S_028058_HEIGHT_TILE_MAX(x) (((x) & 0x7FF) << 11) | ||
1047 | #define G_028058_HEIGHT_TILE_MAX(x) (((x) >> 11) & 0x7FF) | ||
1048 | #define C_028058_HEIGHT_TILE_MAX 0xFFC007FF | ||
1049 | #define R_02805C_DB_DEPTH_SLICE 0x02805C | ||
1050 | #define S_02805C_SLICE_TILE_MAX(x) (((x) & 0x3FFFFF) << 0) | ||
1051 | #define G_02805C_SLICE_TILE_MAX(x) (((x) >> 0) & 0x3FFFFF) | ||
1052 | #define C_02805C_SLICE_TILE_MAX 0xFFC00000 | ||
942 | 1053 | ||
943 | #define SQ_PGM_START_PS 0x28840 | 1054 | #define SQ_PGM_START_PS 0x28840 |
944 | #define SQ_PGM_START_VS 0x2885c | 1055 | #define SQ_PGM_START_VS 0x2885c |
@@ -948,6 +1059,14 @@ | |||
948 | #define SQ_PGM_START_HS 0x288b8 | 1059 | #define SQ_PGM_START_HS 0x288b8 |
949 | #define SQ_PGM_START_LS 0x288d0 | 1060 | #define SQ_PGM_START_LS 0x288d0 |
950 | 1061 | ||
1062 | #define VGT_STRMOUT_BUFFER_BASE_0 0x28AD8 | ||
1063 | #define VGT_STRMOUT_BUFFER_BASE_1 0x28AE8 | ||
1064 | #define VGT_STRMOUT_BUFFER_BASE_2 0x28AF8 | ||
1065 | #define VGT_STRMOUT_BUFFER_BASE_3 0x28B08 | ||
1066 | #define VGT_STRMOUT_BUFFER_SIZE_0 0x28AD0 | ||
1067 | #define VGT_STRMOUT_BUFFER_SIZE_1 0x28AE0 | ||
1068 | #define VGT_STRMOUT_BUFFER_SIZE_2 0x28AF0 | ||
1069 | #define VGT_STRMOUT_BUFFER_SIZE_3 0x28B00 | ||
951 | #define VGT_STRMOUT_CONFIG 0x28b94 | 1070 | #define VGT_STRMOUT_CONFIG 0x28b94 |
952 | #define VGT_STRMOUT_BUFFER_CONFIG 0x28b98 | 1071 | #define VGT_STRMOUT_BUFFER_CONFIG 0x28b98 |
953 | 1072 | ||
@@ -974,6 +1093,114 @@ | |||
974 | #define CB_COLOR0_PITCH 0x28c64 | 1093 | #define CB_COLOR0_PITCH 0x28c64 |
975 | #define CB_COLOR0_SLICE 0x28c68 | 1094 | #define CB_COLOR0_SLICE 0x28c68 |
976 | #define CB_COLOR0_VIEW 0x28c6c | 1095 | #define CB_COLOR0_VIEW 0x28c6c |
1096 | #define R_028C6C_CB_COLOR0_VIEW 0x00028C6C | ||
1097 | #define S_028C6C_SLICE_START(x) (((x) & 0x7FF) << 0) | ||
1098 | #define G_028C6C_SLICE_START(x) (((x) >> 0) & 0x7FF) | ||
1099 | #define C_028C6C_SLICE_START 0xFFFFF800 | ||
1100 | #define S_028C6C_SLICE_MAX(x) (((x) & 0x7FF) << 13) | ||
1101 | #define G_028C6C_SLICE_MAX(x) (((x) >> 13) & 0x7FF) | ||
1102 | #define C_028C6C_SLICE_MAX 0xFF001FFF | ||
1103 | #define R_028C70_CB_COLOR0_INFO 0x028C70 | ||
1104 | #define S_028C70_ENDIAN(x) (((x) & 0x3) << 0) | ||
1105 | #define G_028C70_ENDIAN(x) (((x) >> 0) & 0x3) | ||
1106 | #define C_028C70_ENDIAN 0xFFFFFFFC | ||
1107 | #define S_028C70_FORMAT(x) (((x) & 0x3F) << 2) | ||
1108 | #define G_028C70_FORMAT(x) (((x) >> 2) & 0x3F) | ||
1109 | #define C_028C70_FORMAT 0xFFFFFF03 | ||
1110 | #define V_028C70_COLOR_INVALID 0x00000000 | ||
1111 | #define V_028C70_COLOR_8 0x00000001 | ||
1112 | #define V_028C70_COLOR_4_4 0x00000002 | ||
1113 | #define V_028C70_COLOR_3_3_2 0x00000003 | ||
1114 | #define V_028C70_COLOR_16 0x00000005 | ||
1115 | #define V_028C70_COLOR_16_FLOAT 0x00000006 | ||
1116 | #define V_028C70_COLOR_8_8 0x00000007 | ||
1117 | #define V_028C70_COLOR_5_6_5 0x00000008 | ||
1118 | #define V_028C70_COLOR_6_5_5 0x00000009 | ||
1119 | #define V_028C70_COLOR_1_5_5_5 0x0000000A | ||
1120 | #define V_028C70_COLOR_4_4_4_4 0x0000000B | ||
1121 | #define V_028C70_COLOR_5_5_5_1 0x0000000C | ||
1122 | #define V_028C70_COLOR_32 0x0000000D | ||
1123 | #define V_028C70_COLOR_32_FLOAT 0x0000000E | ||
1124 | #define V_028C70_COLOR_16_16 0x0000000F | ||
1125 | #define V_028C70_COLOR_16_16_FLOAT 0x00000010 | ||
1126 | #define V_028C70_COLOR_8_24 0x00000011 | ||
1127 | #define V_028C70_COLOR_8_24_FLOAT 0x00000012 | ||
1128 | #define V_028C70_COLOR_24_8 0x00000013 | ||
1129 | #define V_028C70_COLOR_24_8_FLOAT 0x00000014 | ||
1130 | #define V_028C70_COLOR_10_11_11 0x00000015 | ||
1131 | #define V_028C70_COLOR_10_11_11_FLOAT 0x00000016 | ||
1132 | #define V_028C70_COLOR_11_11_10 0x00000017 | ||
1133 | #define V_028C70_COLOR_11_11_10_FLOAT 0x00000018 | ||
1134 | #define V_028C70_COLOR_2_10_10_10 0x00000019 | ||
1135 | #define V_028C70_COLOR_8_8_8_8 0x0000001A | ||
1136 | #define V_028C70_COLOR_10_10_10_2 0x0000001B | ||
1137 | #define V_028C70_COLOR_X24_8_32_FLOAT 0x0000001C | ||
1138 | #define V_028C70_COLOR_32_32 0x0000001D | ||
1139 | #define V_028C70_COLOR_32_32_FLOAT 0x0000001E | ||
1140 | #define V_028C70_COLOR_16_16_16_16 0x0000001F | ||
1141 | #define V_028C70_COLOR_16_16_16_16_FLOAT 0x00000020 | ||
1142 | #define V_028C70_COLOR_32_32_32_32 0x00000022 | ||
1143 | #define V_028C70_COLOR_32_32_32_32_FLOAT 0x00000023 | ||
1144 | #define V_028C70_COLOR_32_32_32_FLOAT 0x00000030 | ||
1145 | #define S_028C70_ARRAY_MODE(x) (((x) & 0xF) << 8) | ||
1146 | #define G_028C70_ARRAY_MODE(x) (((x) >> 8) & 0xF) | ||
1147 | #define C_028C70_ARRAY_MODE 0xFFFFF0FF | ||
1148 | #define V_028C70_ARRAY_LINEAR_GENERAL 0x00000000 | ||
1149 | #define V_028C70_ARRAY_LINEAR_ALIGNED 0x00000001 | ||
1150 | #define V_028C70_ARRAY_1D_TILED_THIN1 0x00000002 | ||
1151 | #define V_028C70_ARRAY_2D_TILED_THIN1 0x00000004 | ||
1152 | #define S_028C70_NUMBER_TYPE(x) (((x) & 0x7) << 12) | ||
1153 | #define G_028C70_NUMBER_TYPE(x) (((x) >> 12) & 0x7) | ||
1154 | #define C_028C70_NUMBER_TYPE 0xFFFF8FFF | ||
1155 | #define V_028C70_NUMBER_UNORM 0x00000000 | ||
1156 | #define V_028C70_NUMBER_SNORM 0x00000001 | ||
1157 | #define V_028C70_NUMBER_USCALED 0x00000002 | ||
1158 | #define V_028C70_NUMBER_SSCALED 0x00000003 | ||
1159 | #define V_028C70_NUMBER_UINT 0x00000004 | ||
1160 | #define V_028C70_NUMBER_SINT 0x00000005 | ||
1161 | #define V_028C70_NUMBER_SRGB 0x00000006 | ||
1162 | #define V_028C70_NUMBER_FLOAT 0x00000007 | ||
1163 | #define S_028C70_COMP_SWAP(x) (((x) & 0x3) << 15) | ||
1164 | #define G_028C70_COMP_SWAP(x) (((x) >> 15) & 0x3) | ||
1165 | #define C_028C70_COMP_SWAP 0xFFFE7FFF | ||
1166 | #define V_028C70_SWAP_STD 0x00000000 | ||
1167 | #define V_028C70_SWAP_ALT 0x00000001 | ||
1168 | #define V_028C70_SWAP_STD_REV 0x00000002 | ||
1169 | #define V_028C70_SWAP_ALT_REV 0x00000003 | ||
1170 | #define S_028C70_FAST_CLEAR(x) (((x) & 0x1) << 17) | ||
1171 | #define G_028C70_FAST_CLEAR(x) (((x) >> 17) & 0x1) | ||
1172 | #define C_028C70_FAST_CLEAR 0xFFFDFFFF | ||
1173 | #define S_028C70_COMPRESSION(x) (((x) & 0x3) << 18) | ||
1174 | #define G_028C70_COMPRESSION(x) (((x) >> 18) & 0x3) | ||
1175 | #define C_028C70_COMPRESSION 0xFFF3FFFF | ||
1176 | #define S_028C70_BLEND_CLAMP(x) (((x) & 0x1) << 19) | ||
1177 | #define G_028C70_BLEND_CLAMP(x) (((x) >> 19) & 0x1) | ||
1178 | #define C_028C70_BLEND_CLAMP 0xFFF7FFFF | ||
1179 | #define S_028C70_BLEND_BYPASS(x) (((x) & 0x1) << 20) | ||
1180 | #define G_028C70_BLEND_BYPASS(x) (((x) >> 20) & 0x1) | ||
1181 | #define C_028C70_BLEND_BYPASS 0xFFEFFFFF | ||
1182 | #define S_028C70_SIMPLE_FLOAT(x) (((x) & 0x1) << 21) | ||
1183 | #define G_028C70_SIMPLE_FLOAT(x) (((x) >> 21) & 0x1) | ||
1184 | #define C_028C70_SIMPLE_FLOAT 0xFFDFFFFF | ||
1185 | #define S_028C70_ROUND_MODE(x) (((x) & 0x1) << 22) | ||
1186 | #define G_028C70_ROUND_MODE(x) (((x) >> 22) & 0x1) | ||
1187 | #define C_028C70_ROUND_MODE 0xFFBFFFFF | ||
1188 | #define S_028C70_TILE_COMPACT(x) (((x) & 0x1) << 23) | ||
1189 | #define G_028C70_TILE_COMPACT(x) (((x) >> 23) & 0x1) | ||
1190 | #define C_028C70_TILE_COMPACT 0xFF7FFFFF | ||
1191 | #define S_028C70_SOURCE_FORMAT(x) (((x) & 0x3) << 24) | ||
1192 | #define G_028C70_SOURCE_FORMAT(x) (((x) >> 24) & 0x3) | ||
1193 | #define C_028C70_SOURCE_FORMAT 0xFCFFFFFF | ||
1194 | #define V_028C70_EXPORT_4C_32BPC 0x0 | ||
1195 | #define V_028C70_EXPORT_4C_16BPC 0x1 | ||
1196 | #define V_028C70_EXPORT_2C_32BPC 0x2 /* Do not use */ | ||
1197 | #define S_028C70_RAT(x) (((x) & 0x1) << 26) | ||
1198 | #define G_028C70_RAT(x) (((x) >> 26) & 0x1) | ||
1199 | #define C_028C70_RAT 0xFBFFFFFF | ||
1200 | #define S_028C70_RESOURCE_TYPE(x) (((x) & 0x7) << 27) | ||
1201 | #define G_028C70_RESOURCE_TYPE(x) (((x) >> 27) & 0x7) | ||
1202 | #define C_028C70_RESOURCE_TYPE 0xC7FFFFFF | ||
1203 | |||
977 | #define CB_COLOR0_INFO 0x28c70 | 1204 | #define CB_COLOR0_INFO 0x28c70 |
978 | # define CB_FORMAT(x) ((x) << 2) | 1205 | # define CB_FORMAT(x) ((x) << 2) |
979 | # define CB_ARRAY_MODE(x) ((x) << 8) | 1206 | # define CB_ARRAY_MODE(x) ((x) << 8) |
@@ -984,6 +1211,20 @@ | |||
984 | # define CB_SOURCE_FORMAT(x) ((x) << 24) | 1211 | # define CB_SOURCE_FORMAT(x) ((x) << 24) |
985 | # define CB_SF_EXPORT_FULL 0 | 1212 | # define CB_SF_EXPORT_FULL 0 |
986 | # define CB_SF_EXPORT_NORM 1 | 1213 | # define CB_SF_EXPORT_NORM 1 |
1214 | #define R_028C74_CB_COLOR0_ATTRIB 0x028C74 | ||
1215 | #define S_028C74_NON_DISP_TILING_ORDER(x) (((x) & 0x1) << 4) | ||
1216 | #define G_028C74_NON_DISP_TILING_ORDER(x) (((x) >> 4) & 0x1) | ||
1217 | #define C_028C74_NON_DISP_TILING_ORDER 0xFFFFFFEF | ||
1218 | #define S_028C74_TILE_SPLIT(x) (((x) & 0xf) << 5) | ||
1219 | #define G_028C74_TILE_SPLIT(x) (((x) >> 5) & 0xf) | ||
1220 | #define S_028C74_NUM_BANKS(x) (((x) & 0x3) << 10) | ||
1221 | #define G_028C74_NUM_BANKS(x) (((x) >> 10) & 0x3) | ||
1222 | #define S_028C74_BANK_WIDTH(x) (((x) & 0x3) << 13) | ||
1223 | #define G_028C74_BANK_WIDTH(x) (((x) >> 13) & 0x3) | ||
1224 | #define S_028C74_BANK_HEIGHT(x) (((x) & 0x3) << 16) | ||
1225 | #define G_028C74_BANK_HEIGHT(x) (((x) >> 16) & 0x3) | ||
1226 | #define S_028C74_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 19) | ||
1227 | #define G_028C74_MACRO_TILE_ASPECT(x) (((x) >> 19) & 0x3) | ||
987 | #define CB_COLOR0_ATTRIB 0x28c74 | 1228 | #define CB_COLOR0_ATTRIB 0x28c74 |
988 | # define CB_TILE_SPLIT(x) (((x) & 0x7) << 5) | 1229 | # define CB_TILE_SPLIT(x) (((x) & 0x7) << 5) |
989 | # define ADDR_SURF_TILE_SPLIT_64B 0 | 1230 | # define ADDR_SURF_TILE_SPLIT_64B 0 |
@@ -1008,6 +1249,7 @@ | |||
1008 | # define ADDR_SURF_BANK_HEIGHT_2 1 | 1249 | # define ADDR_SURF_BANK_HEIGHT_2 1 |
1009 | # define ADDR_SURF_BANK_HEIGHT_4 2 | 1250 | # define ADDR_SURF_BANK_HEIGHT_4 2 |
1010 | # define ADDR_SURF_BANK_HEIGHT_8 3 | 1251 | # define ADDR_SURF_BANK_HEIGHT_8 3 |
1252 | # define CB_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 19) | ||
1011 | #define CB_COLOR0_DIM 0x28c78 | 1253 | #define CB_COLOR0_DIM 0x28c78 |
1012 | /* only CB0-7 blocks have these regs */ | 1254 | /* only CB0-7 blocks have these regs */ |
1013 | #define CB_COLOR0_CMASK 0x28c7c | 1255 | #define CB_COLOR0_CMASK 0x28c7c |
@@ -1196,9 +1438,144 @@ | |||
1196 | #define SQ_TEX_RESOURCE_WORD6_0 0x30018 | 1438 | #define SQ_TEX_RESOURCE_WORD6_0 0x30018 |
1197 | # define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29) | 1439 | # define TEX_TILE_SPLIT(x) (((x) & 0x7) << 29) |
1198 | #define SQ_TEX_RESOURCE_WORD7_0 0x3001c | 1440 | #define SQ_TEX_RESOURCE_WORD7_0 0x3001c |
1441 | # define MACRO_TILE_ASPECT(x) (((x) & 0x3) << 6) | ||
1199 | # define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8) | 1442 | # define TEX_BANK_WIDTH(x) (((x) & 0x3) << 8) |
1200 | # define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10) | 1443 | # define TEX_BANK_HEIGHT(x) (((x) & 0x3) << 10) |
1201 | # define TEX_NUM_BANKS(x) (((x) & 0x3) << 16) | 1444 | # define TEX_NUM_BANKS(x) (((x) & 0x3) << 16) |
1445 | #define R_030000_SQ_TEX_RESOURCE_WORD0_0 0x030000 | ||
1446 | #define S_030000_DIM(x) (((x) & 0x7) << 0) | ||
1447 | #define G_030000_DIM(x) (((x) >> 0) & 0x7) | ||
1448 | #define C_030000_DIM 0xFFFFFFF8 | ||
1449 | #define V_030000_SQ_TEX_DIM_1D 0x00000000 | ||
1450 | #define V_030000_SQ_TEX_DIM_2D 0x00000001 | ||
1451 | #define V_030000_SQ_TEX_DIM_3D 0x00000002 | ||
1452 | #define V_030000_SQ_TEX_DIM_CUBEMAP 0x00000003 | ||
1453 | #define V_030000_SQ_TEX_DIM_1D_ARRAY 0x00000004 | ||
1454 | #define V_030000_SQ_TEX_DIM_2D_ARRAY 0x00000005 | ||
1455 | #define V_030000_SQ_TEX_DIM_2D_MSAA 0x00000006 | ||
1456 | #define V_030000_SQ_TEX_DIM_2D_ARRAY_MSAA 0x00000007 | ||
1457 | #define S_030000_NON_DISP_TILING_ORDER(x) (((x) & 0x1) << 5) | ||
1458 | #define G_030000_NON_DISP_TILING_ORDER(x) (((x) >> 5) & 0x1) | ||
1459 | #define C_030000_NON_DISP_TILING_ORDER 0xFFFFFFDF | ||
1460 | #define S_030000_PITCH(x) (((x) & 0xFFF) << 6) | ||
1461 | #define G_030000_PITCH(x) (((x) >> 6) & 0xFFF) | ||
1462 | #define C_030000_PITCH 0xFFFC003F | ||
1463 | #define S_030000_TEX_WIDTH(x) (((x) & 0x3FFF) << 18) | ||
1464 | #define G_030000_TEX_WIDTH(x) (((x) >> 18) & 0x3FFF) | ||
1465 | #define C_030000_TEX_WIDTH 0x0003FFFF | ||
1466 | #define R_030004_SQ_TEX_RESOURCE_WORD1_0 0x030004 | ||
1467 | #define S_030004_TEX_HEIGHT(x) (((x) & 0x3FFF) << 0) | ||
1468 | #define G_030004_TEX_HEIGHT(x) (((x) >> 0) & 0x3FFF) | ||
1469 | #define C_030004_TEX_HEIGHT 0xFFFFC000 | ||
1470 | #define S_030004_TEX_DEPTH(x) (((x) & 0x1FFF) << 14) | ||
1471 | #define G_030004_TEX_DEPTH(x) (((x) >> 14) & 0x1FFF) | ||
1472 | #define C_030004_TEX_DEPTH 0xF8003FFF | ||
1473 | #define S_030004_ARRAY_MODE(x) (((x) & 0xF) << 28) | ||
1474 | #define G_030004_ARRAY_MODE(x) (((x) >> 28) & 0xF) | ||
1475 | #define C_030004_ARRAY_MODE 0x0FFFFFFF | ||
1476 | #define R_030008_SQ_TEX_RESOURCE_WORD2_0 0x030008 | ||
1477 | #define S_030008_BASE_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) | ||
1478 | #define G_030008_BASE_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) | ||
1479 | #define C_030008_BASE_ADDRESS 0x00000000 | ||
1480 | #define R_03000C_SQ_TEX_RESOURCE_WORD3_0 0x03000C | ||
1481 | #define S_03000C_MIP_ADDRESS(x) (((x) & 0xFFFFFFFF) << 0) | ||
1482 | #define G_03000C_MIP_ADDRESS(x) (((x) >> 0) & 0xFFFFFFFF) | ||
1483 | #define C_03000C_MIP_ADDRESS 0x00000000 | ||
1484 | #define R_030010_SQ_TEX_RESOURCE_WORD4_0 0x030010 | ||
1485 | #define S_030010_FORMAT_COMP_X(x) (((x) & 0x3) << 0) | ||
1486 | #define G_030010_FORMAT_COMP_X(x) (((x) >> 0) & 0x3) | ||
1487 | #define C_030010_FORMAT_COMP_X 0xFFFFFFFC | ||
1488 | #define V_030010_SQ_FORMAT_COMP_UNSIGNED 0x00000000 | ||
1489 | #define V_030010_SQ_FORMAT_COMP_SIGNED 0x00000001 | ||
1490 | #define V_030010_SQ_FORMAT_COMP_UNSIGNED_BIASED 0x00000002 | ||
1491 | #define S_030010_FORMAT_COMP_Y(x) (((x) & 0x3) << 2) | ||
1492 | #define G_030010_FORMAT_COMP_Y(x) (((x) >> 2) & 0x3) | ||
1493 | #define C_030010_FORMAT_COMP_Y 0xFFFFFFF3 | ||
1494 | #define S_030010_FORMAT_COMP_Z(x) (((x) & 0x3) << 4) | ||
1495 | #define G_030010_FORMAT_COMP_Z(x) (((x) >> 4) & 0x3) | ||
1496 | #define C_030010_FORMAT_COMP_Z 0xFFFFFFCF | ||
1497 | #define S_030010_FORMAT_COMP_W(x) (((x) & 0x3) << 6) | ||
1498 | #define G_030010_FORMAT_COMP_W(x) (((x) >> 6) & 0x3) | ||
1499 | #define C_030010_FORMAT_COMP_W 0xFFFFFF3F | ||
1500 | #define S_030010_NUM_FORMAT_ALL(x) (((x) & 0x3) << 8) | ||
1501 | #define G_030010_NUM_FORMAT_ALL(x) (((x) >> 8) & 0x3) | ||
1502 | #define C_030010_NUM_FORMAT_ALL 0xFFFFFCFF | ||
1503 | #define V_030010_SQ_NUM_FORMAT_NORM 0x00000000 | ||
1504 | #define V_030010_SQ_NUM_FORMAT_INT 0x00000001 | ||
1505 | #define V_030010_SQ_NUM_FORMAT_SCALED 0x00000002 | ||
1506 | #define S_030010_SRF_MODE_ALL(x) (((x) & 0x1) << 10) | ||
1507 | #define G_030010_SRF_MODE_ALL(x) (((x) >> 10) & 0x1) | ||
1508 | #define C_030010_SRF_MODE_ALL 0xFFFFFBFF | ||
1509 | #define V_030010_SRF_MODE_ZERO_CLAMP_MINUS_ONE 0x00000000 | ||
1510 | #define V_030010_SRF_MODE_NO_ZERO 0x00000001 | ||
1511 | #define S_030010_FORCE_DEGAMMA(x) (((x) & 0x1) << 11) | ||
1512 | #define G_030010_FORCE_DEGAMMA(x) (((x) >> 11) & 0x1) | ||
1513 | #define C_030010_FORCE_DEGAMMA 0xFFFFF7FF | ||
1514 | #define S_030010_ENDIAN_SWAP(x) (((x) & 0x3) << 12) | ||
1515 | #define G_030010_ENDIAN_SWAP(x) (((x) >> 12) & 0x3) | ||
1516 | #define C_030010_ENDIAN_SWAP 0xFFFFCFFF | ||
1517 | #define S_030010_DST_SEL_X(x) (((x) & 0x7) << 16) | ||
1518 | #define G_030010_DST_SEL_X(x) (((x) >> 16) & 0x7) | ||
1519 | #define C_030010_DST_SEL_X 0xFFF8FFFF | ||
1520 | #define V_030010_SQ_SEL_X 0x00000000 | ||
1521 | #define V_030010_SQ_SEL_Y 0x00000001 | ||
1522 | #define V_030010_SQ_SEL_Z 0x00000002 | ||
1523 | #define V_030010_SQ_SEL_W 0x00000003 | ||
1524 | #define V_030010_SQ_SEL_0 0x00000004 | ||
1525 | #define V_030010_SQ_SEL_1 0x00000005 | ||
1526 | #define S_030010_DST_SEL_Y(x) (((x) & 0x7) << 19) | ||
1527 | #define G_030010_DST_SEL_Y(x) (((x) >> 19) & 0x7) | ||
1528 | #define C_030010_DST_SEL_Y 0xFFC7FFFF | ||
1529 | #define S_030010_DST_SEL_Z(x) (((x) & 0x7) << 22) | ||
1530 | #define G_030010_DST_SEL_Z(x) (((x) >> 22) & 0x7) | ||
1531 | #define C_030010_DST_SEL_Z 0xFE3FFFFF | ||
1532 | #define S_030010_DST_SEL_W(x) (((x) & 0x7) << 25) | ||
1533 | #define G_030010_DST_SEL_W(x) (((x) >> 25) & 0x7) | ||
1534 | #define C_030010_DST_SEL_W 0xF1FFFFFF | ||
1535 | #define S_030010_BASE_LEVEL(x) (((x) & 0xF) << 28) | ||
1536 | #define G_030010_BASE_LEVEL(x) (((x) >> 28) & 0xF) | ||
1537 | #define C_030010_BASE_LEVEL 0x0FFFFFFF | ||
1538 | #define R_030014_SQ_TEX_RESOURCE_WORD5_0 0x030014 | ||
1539 | #define S_030014_LAST_LEVEL(x) (((x) & 0xF) << 0) | ||
1540 | #define G_030014_LAST_LEVEL(x) (((x) >> 0) & 0xF) | ||
1541 | #define C_030014_LAST_LEVEL 0xFFFFFFF0 | ||
1542 | #define S_030014_BASE_ARRAY(x) (((x) & 0x1FFF) << 4) | ||
1543 | #define G_030014_BASE_ARRAY(x) (((x) >> 4) & 0x1FFF) | ||
1544 | #define C_030014_BASE_ARRAY 0xFFFE000F | ||
1545 | #define S_030014_LAST_ARRAY(x) (((x) & 0x1FFF) << 17) | ||
1546 | #define G_030014_LAST_ARRAY(x) (((x) >> 17) & 0x1FFF) | ||
1547 | #define C_030014_LAST_ARRAY 0xC001FFFF | ||
1548 | #define R_030018_SQ_TEX_RESOURCE_WORD6_0 0x030018 | ||
1549 | #define S_030018_MAX_ANISO(x) (((x) & 0x7) << 0) | ||
1550 | #define G_030018_MAX_ANISO(x) (((x) >> 0) & 0x7) | ||
1551 | #define C_030018_MAX_ANISO 0xFFFFFFF8 | ||
1552 | #define S_030018_PERF_MODULATION(x) (((x) & 0x7) << 3) | ||
1553 | #define G_030018_PERF_MODULATION(x) (((x) >> 3) & 0x7) | ||
1554 | #define C_030018_PERF_MODULATION 0xFFFFFFC7 | ||
1555 | #define S_030018_INTERLACED(x) (((x) & 0x1) << 6) | ||
1556 | #define G_030018_INTERLACED(x) (((x) >> 6) & 0x1) | ||
1557 | #define C_030018_INTERLACED 0xFFFFFFBF | ||
1558 | #define S_030018_TILE_SPLIT(x) (((x) & 0x7) << 29) | ||
1559 | #define G_030018_TILE_SPLIT(x) (((x) >> 29) & 0x7) | ||
1560 | #define R_03001C_SQ_TEX_RESOURCE_WORD7_0 0x03001C | ||
1561 | #define S_03001C_MACRO_TILE_ASPECT(x) (((x) & 0x3) << 6) | ||
1562 | #define G_03001C_MACRO_TILE_ASPECT(x) (((x) >> 6) & 0x3) | ||
1563 | #define S_03001C_BANK_WIDTH(x) (((x) & 0x3) << 8) | ||
1564 | #define G_03001C_BANK_WIDTH(x) (((x) >> 8) & 0x3) | ||
1565 | #define S_03001C_BANK_HEIGHT(x) (((x) & 0x3) << 10) | ||
1566 | #define G_03001C_BANK_HEIGHT(x) (((x) >> 10) & 0x3) | ||
1567 | #define S_03001C_NUM_BANKS(x) (((x) & 0x3) << 16) | ||
1568 | #define G_03001C_NUM_BANKS(x) (((x) >> 16) & 0x3) | ||
1569 | #define S_03001C_TYPE(x) (((x) & 0x3) << 30) | ||
1570 | #define G_03001C_TYPE(x) (((x) >> 30) & 0x3) | ||
1571 | #define C_03001C_TYPE 0x3FFFFFFF | ||
1572 | #define V_03001C_SQ_TEX_VTX_INVALID_TEXTURE 0x00000000 | ||
1573 | #define V_03001C_SQ_TEX_VTX_INVALID_BUFFER 0x00000001 | ||
1574 | #define V_03001C_SQ_TEX_VTX_VALID_TEXTURE 0x00000002 | ||
1575 | #define V_03001C_SQ_TEX_VTX_VALID_BUFFER 0x00000003 | ||
1576 | #define S_03001C_DATA_FORMAT(x) (((x) & 0x3F) << 0) | ||
1577 | #define G_03001C_DATA_FORMAT(x) (((x) >> 0) & 0x3F) | ||
1578 | #define C_03001C_DATA_FORMAT 0xFFFFFFC0 | ||
1202 | 1579 | ||
1203 | #define SQ_VTX_CONSTANT_WORD0_0 0x30000 | 1580 | #define SQ_VTX_CONSTANT_WORD0_0 0x30000 |
1204 | #define SQ_VTX_CONSTANT_WORD1_0 0x30004 | 1581 | #define SQ_VTX_CONSTANT_WORD1_0 0x30004 |
diff --git a/drivers/gpu/drm/radeon/r100.c b/drivers/gpu/drm/radeon/r100.c index bfd36ab643a6..99bb00649357 100644 --- a/drivers/gpu/drm/radeon/r100.c +++ b/drivers/gpu/drm/radeon/r100.c | |||
@@ -87,23 +87,27 @@ int r100_reloc_pitch_offset(struct radeon_cs_parser *p, | |||
87 | r100_cs_dump_packet(p, pkt); | 87 | r100_cs_dump_packet(p, pkt); |
88 | return r; | 88 | return r; |
89 | } | 89 | } |
90 | |||
90 | value = radeon_get_ib_value(p, idx); | 91 | value = radeon_get_ib_value(p, idx); |
91 | tmp = value & 0x003fffff; | 92 | tmp = value & 0x003fffff; |
92 | tmp += (((u32)reloc->lobj.gpu_offset) >> 10); | 93 | tmp += (((u32)reloc->lobj.gpu_offset) >> 10); |
93 | 94 | ||
94 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 95 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
95 | tile_flags |= RADEON_DST_TILE_MACRO; | 96 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
96 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { | 97 | tile_flags |= RADEON_DST_TILE_MACRO; |
97 | if (reg == RADEON_SRC_PITCH_OFFSET) { | 98 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) { |
98 | DRM_ERROR("Cannot src blit from microtiled surface\n"); | 99 | if (reg == RADEON_SRC_PITCH_OFFSET) { |
99 | r100_cs_dump_packet(p, pkt); | 100 | DRM_ERROR("Cannot src blit from microtiled surface\n"); |
100 | return -EINVAL; | 101 | r100_cs_dump_packet(p, pkt); |
102 | return -EINVAL; | ||
103 | } | ||
104 | tile_flags |= RADEON_DST_TILE_MICRO; | ||
101 | } | 105 | } |
102 | tile_flags |= RADEON_DST_TILE_MICRO; | ||
103 | } | ||
104 | 106 | ||
105 | tmp |= tile_flags; | 107 | tmp |= tile_flags; |
106 | p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; | 108 | p->ib->ptr[idx] = (value & 0x3fc00000) | tmp; |
109 | } else | ||
110 | p->ib->ptr[idx] = (value & 0xffc00000) | tmp; | ||
107 | return 0; | 111 | return 0; |
108 | } | 112 | } |
109 | 113 | ||
@@ -1554,7 +1558,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1554 | r100_cs_dump_packet(p, pkt); | 1558 | r100_cs_dump_packet(p, pkt); |
1555 | return r; | 1559 | return r; |
1556 | } | 1560 | } |
1557 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 1561 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
1562 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | ||
1563 | tile_flags |= RADEON_TXO_MACRO_TILE; | ||
1564 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | ||
1565 | tile_flags |= RADEON_TXO_MICRO_TILE_X2; | ||
1566 | |||
1567 | tmp = idx_value & ~(0x7 << 2); | ||
1568 | tmp |= tile_flags; | ||
1569 | ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); | ||
1570 | } else | ||
1571 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | ||
1558 | track->textures[i].robj = reloc->robj; | 1572 | track->textures[i].robj = reloc->robj; |
1559 | track->tex_dirty = true; | 1573 | track->tex_dirty = true; |
1560 | break; | 1574 | break; |
@@ -1625,15 +1639,17 @@ static int r100_packet0_check(struct radeon_cs_parser *p, | |||
1625 | r100_cs_dump_packet(p, pkt); | 1639 | r100_cs_dump_packet(p, pkt); |
1626 | return r; | 1640 | return r; |
1627 | } | 1641 | } |
1628 | 1642 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { | |
1629 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 1643 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
1630 | tile_flags |= RADEON_COLOR_TILE_ENABLE; | 1644 | tile_flags |= RADEON_COLOR_TILE_ENABLE; |
1631 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 1645 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
1632 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; | 1646 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; |
1633 | 1647 | ||
1634 | tmp = idx_value & ~(0x7 << 16); | 1648 | tmp = idx_value & ~(0x7 << 16); |
1635 | tmp |= tile_flags; | 1649 | tmp |= tile_flags; |
1636 | ib[idx] = tmp; | 1650 | ib[idx] = tmp; |
1651 | } else | ||
1652 | ib[idx] = idx_value; | ||
1637 | 1653 | ||
1638 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; | 1654 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
1639 | track->cb_dirty = true; | 1655 | track->cb_dirty = true; |
diff --git a/drivers/gpu/drm/radeon/r200.c b/drivers/gpu/drm/radeon/r200.c index eba4cbfa78f6..a59cc474d537 100644 --- a/drivers/gpu/drm/radeon/r200.c +++ b/drivers/gpu/drm/radeon/r200.c | |||
@@ -215,7 +215,17 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
215 | r100_cs_dump_packet(p, pkt); | 215 | r100_cs_dump_packet(p, pkt); |
216 | return r; | 216 | return r; |
217 | } | 217 | } |
218 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | 218 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
219 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | ||
220 | tile_flags |= R200_TXO_MACRO_TILE; | ||
221 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | ||
222 | tile_flags |= R200_TXO_MICRO_TILE; | ||
223 | |||
224 | tmp = idx_value & ~(0x7 << 2); | ||
225 | tmp |= tile_flags; | ||
226 | ib[idx] = tmp + ((u32)reloc->lobj.gpu_offset); | ||
227 | } else | ||
228 | ib[idx] = idx_value + ((u32)reloc->lobj.gpu_offset); | ||
219 | track->textures[i].robj = reloc->robj; | 229 | track->textures[i].robj = reloc->robj; |
220 | track->tex_dirty = true; | 230 | track->tex_dirty = true; |
221 | break; | 231 | break; |
@@ -277,14 +287,17 @@ int r200_packet0_check(struct radeon_cs_parser *p, | |||
277 | return r; | 287 | return r; |
278 | } | 288 | } |
279 | 289 | ||
280 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) | 290 | if (!(p->cs_flags & RADEON_CS_KEEP_TILING_FLAGS)) { |
281 | tile_flags |= RADEON_COLOR_TILE_ENABLE; | 291 | if (reloc->lobj.tiling_flags & RADEON_TILING_MACRO) |
282 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) | 292 | tile_flags |= RADEON_COLOR_TILE_ENABLE; |
283 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; | 293 | if (reloc->lobj.tiling_flags & RADEON_TILING_MICRO) |
294 | tile_flags |= RADEON_COLOR_MICROTILE_ENABLE; | ||
284 | 295 | ||
285 | tmp = idx_value & ~(0x7 << 16); | 296 | tmp = idx_value & ~(0x7 << 16); |
286 | tmp |= tile_flags; | 297 | tmp |= tile_flags; |
287 | ib[idx] = tmp; | 298 | ib[idx] = tmp; |
299 | } else | ||
300 | ib[idx] = idx_value; | ||
288 | 301 | ||
289 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; | 302 | track->cb[0].pitch = idx_value & RADEON_COLORPITCH_MASK; |
290 | track->cb_dirty = true; | 303 | track->cb_dirty = true; |
diff --git a/drivers/gpu/drm/radeon/r600_blit_kms.c b/drivers/gpu/drm/radeon/r600_blit_kms.c index accc032c103f..db38f587f27a 100644 --- a/drivers/gpu/drm/radeon/r600_blit_kms.c +++ b/drivers/gpu/drm/radeon/r600_blit_kms.c | |||
@@ -30,20 +30,7 @@ | |||
30 | 30 | ||
31 | #include "r600d.h" | 31 | #include "r600d.h" |
32 | #include "r600_blit_shaders.h" | 32 | #include "r600_blit_shaders.h" |
33 | 33 | #include "radeon_blit_common.h" | |
34 | #define DI_PT_RECTLIST 0x11 | ||
35 | #define DI_INDEX_SIZE_16_BIT 0x0 | ||
36 | #define DI_SRC_SEL_AUTO_INDEX 0x2 | ||
37 | |||
38 | #define FMT_8 0x1 | ||
39 | #define FMT_5_6_5 0x8 | ||
40 | #define FMT_8_8_8_8 0x1a | ||
41 | #define COLOR_8 0x1 | ||
42 | #define COLOR_5_6_5 0x8 | ||
43 | #define COLOR_8_8_8_8 0x1a | ||
44 | |||
45 | #define RECT_UNIT_H 32 | ||
46 | #define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H) | ||
47 | 34 | ||
48 | /* emits 21 on rv770+, 23 on r600 */ | 35 | /* emits 21 on rv770+, 23 on r600 */ |
49 | static void | 36 | static void |
diff --git a/drivers/gpu/drm/radeon/r600_cs.c b/drivers/gpu/drm/radeon/r600_cs.c index 38ce5d0427e3..5cbe948ef16e 100644 --- a/drivers/gpu/drm/radeon/r600_cs.c +++ b/drivers/gpu/drm/radeon/r600_cs.c | |||
@@ -55,12 +55,17 @@ struct r600_cs_track { | |||
55 | struct radeon_bo *cb_color_frag_bo[8]; | 55 | struct radeon_bo *cb_color_frag_bo[8]; |
56 | struct radeon_bo *cb_color_tile_bo[8]; | 56 | struct radeon_bo *cb_color_tile_bo[8]; |
57 | u32 cb_color_info[8]; | 57 | u32 cb_color_info[8]; |
58 | u32 cb_color_view[8]; | ||
58 | u32 cb_color_size_idx[8]; | 59 | u32 cb_color_size_idx[8]; |
59 | u32 cb_target_mask; | 60 | u32 cb_target_mask; |
60 | u32 cb_shader_mask; | 61 | u32 cb_shader_mask; |
61 | u32 cb_color_size[8]; | 62 | u32 cb_color_size[8]; |
62 | u32 vgt_strmout_en; | 63 | u32 vgt_strmout_en; |
63 | u32 vgt_strmout_buffer_en; | 64 | u32 vgt_strmout_buffer_en; |
65 | struct radeon_bo *vgt_strmout_bo[4]; | ||
66 | u64 vgt_strmout_bo_mc[4]; | ||
67 | u32 vgt_strmout_bo_offset[4]; | ||
68 | u32 vgt_strmout_size[4]; | ||
64 | u32 db_depth_control; | 69 | u32 db_depth_control; |
65 | u32 db_depth_info; | 70 | u32 db_depth_info; |
66 | u32 db_depth_size_idx; | 71 | u32 db_depth_size_idx; |
@@ -73,9 +78,9 @@ struct r600_cs_track { | |||
73 | 78 | ||
74 | #define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 } | 79 | #define FMT_8_BIT(fmt, vc) [fmt] = { 1, 1, 1, vc, CHIP_R600 } |
75 | #define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc, CHIP_R600 } | 80 | #define FMT_16_BIT(fmt, vc) [fmt] = { 1, 1, 2, vc, CHIP_R600 } |
76 | #define FMT_24_BIT(fmt) [fmt] = { 1, 1, 3, 0, CHIP_R600 } | 81 | #define FMT_24_BIT(fmt) [fmt] = { 1, 1, 4, 0, CHIP_R600 } |
77 | #define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc, CHIP_R600 } | 82 | #define FMT_32_BIT(fmt, vc) [fmt] = { 1, 1, 4, vc, CHIP_R600 } |
78 | #define FMT_48_BIT(fmt) [fmt] = { 1, 1, 6, 0, CHIP_R600 } | 83 | #define FMT_48_BIT(fmt) [fmt] = { 1, 1, 8, 0, CHIP_R600 } |
79 | #define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc, CHIP_R600 } | 84 | #define FMT_64_BIT(fmt, vc) [fmt] = { 1, 1, 8, vc, CHIP_R600 } |
80 | #define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0, CHIP_R600 } | 85 | #define FMT_96_BIT(fmt) [fmt] = { 1, 1, 12, 0, CHIP_R600 } |
81 | #define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 } | 86 | #define FMT_128_BIT(fmt, vc) [fmt] = { 1, 1, 16,vc, CHIP_R600 } |
@@ -107,7 +112,7 @@ static const struct gpu_formats color_formats_table[] = { | |||
107 | 112 | ||
108 | /* 24-bit */ | 113 | /* 24-bit */ |
109 | FMT_24_BIT(V_038004_FMT_8_8_8), | 114 | FMT_24_BIT(V_038004_FMT_8_8_8), |
110 | 115 | ||
111 | /* 32-bit */ | 116 | /* 32-bit */ |
112 | FMT_32_BIT(V_038004_COLOR_32, 1), | 117 | FMT_32_BIT(V_038004_COLOR_32, 1), |
113 | FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1), | 118 | FMT_32_BIT(V_038004_COLOR_32_FLOAT, 1), |
@@ -162,22 +167,22 @@ static const struct gpu_formats color_formats_table[] = { | |||
162 | [V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR}, | 167 | [V_038004_FMT_32_AS_32_32_32_32] = { 1, 1, 4, 0, CHIP_CEDAR}, |
163 | }; | 168 | }; |
164 | 169 | ||
165 | static bool fmt_is_valid_color(u32 format) | 170 | bool r600_fmt_is_valid_color(u32 format) |
166 | { | 171 | { |
167 | if (format >= ARRAY_SIZE(color_formats_table)) | 172 | if (format >= ARRAY_SIZE(color_formats_table)) |
168 | return false; | 173 | return false; |
169 | 174 | ||
170 | if (color_formats_table[format].valid_color) | 175 | if (color_formats_table[format].valid_color) |
171 | return true; | 176 | return true; |
172 | 177 | ||
173 | return false; | 178 | return false; |
174 | } | 179 | } |
175 | 180 | ||
176 | static bool fmt_is_valid_texture(u32 format, enum radeon_family family) | 181 | bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family) |
177 | { | 182 | { |
178 | if (format >= ARRAY_SIZE(color_formats_table)) | 183 | if (format >= ARRAY_SIZE(color_formats_table)) |
179 | return false; | 184 | return false; |
180 | 185 | ||
181 | if (family < color_formats_table[format].min_family) | 186 | if (family < color_formats_table[format].min_family) |
182 | return false; | 187 | return false; |
183 | 188 | ||
@@ -187,7 +192,7 @@ static bool fmt_is_valid_texture(u32 format, enum radeon_family family) | |||
187 | return false; | 192 | return false; |
188 | } | 193 | } |
189 | 194 | ||
190 | static int fmt_get_blocksize(u32 format) | 195 | int r600_fmt_get_blocksize(u32 format) |
191 | { | 196 | { |
192 | if (format >= ARRAY_SIZE(color_formats_table)) | 197 | if (format >= ARRAY_SIZE(color_formats_table)) |
193 | return 0; | 198 | return 0; |
@@ -195,7 +200,7 @@ static int fmt_get_blocksize(u32 format) | |||
195 | return color_formats_table[format].blocksize; | 200 | return color_formats_table[format].blocksize; |
196 | } | 201 | } |
197 | 202 | ||
198 | static int fmt_get_nblocksx(u32 format, u32 w) | 203 | int r600_fmt_get_nblocksx(u32 format, u32 w) |
199 | { | 204 | { |
200 | unsigned bw; | 205 | unsigned bw; |
201 | 206 | ||
@@ -209,7 +214,7 @@ static int fmt_get_nblocksx(u32 format, u32 w) | |||
209 | return (w + bw - 1) / bw; | 214 | return (w + bw - 1) / bw; |
210 | } | 215 | } |
211 | 216 | ||
212 | static int fmt_get_nblocksy(u32 format, u32 h) | 217 | int r600_fmt_get_nblocksy(u32 format, u32 h) |
213 | { | 218 | { |
214 | unsigned bh; | 219 | unsigned bh; |
215 | 220 | ||
@@ -256,7 +261,7 @@ static int r600_get_array_mode_alignment(struct array_mode_checker *values, | |||
256 | break; | 261 | break; |
257 | case ARRAY_LINEAR_ALIGNED: | 262 | case ARRAY_LINEAR_ALIGNED: |
258 | *pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize)); | 263 | *pitch_align = max((u32)64, (u32)(values->group_size / values->blocksize)); |
259 | *height_align = tile_height; | 264 | *height_align = 1; |
260 | *depth_align = 1; | 265 | *depth_align = 1; |
261 | *base_align = values->group_size; | 266 | *base_align = values->group_size; |
262 | break; | 267 | break; |
@@ -269,10 +274,9 @@ static int r600_get_array_mode_alignment(struct array_mode_checker *values, | |||
269 | *base_align = values->group_size; | 274 | *base_align = values->group_size; |
270 | break; | 275 | break; |
271 | case ARRAY_2D_TILED_THIN1: | 276 | case ARRAY_2D_TILED_THIN1: |
272 | *pitch_align = max((u32)macro_tile_width, | 277 | *pitch_align = max((u32)macro_tile_width * tile_width, |
273 | (u32)(((values->group_size / tile_height) / | 278 | (u32)((values->group_size * values->nbanks) / |
274 | (values->blocksize * values->nsamples)) * | 279 | (values->blocksize * values->nsamples * tile_width))); |
275 | values->nbanks)) * tile_width; | ||
276 | *height_align = macro_tile_height * tile_height; | 280 | *height_align = macro_tile_height * tile_height; |
277 | *depth_align = 1; | 281 | *depth_align = 1; |
278 | *base_align = max(macro_tile_bytes, | 282 | *base_align = max(macro_tile_bytes, |
@@ -296,6 +300,7 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
296 | track->cb_color_size[i] = 0; | 300 | track->cb_color_size[i] = 0; |
297 | track->cb_color_size_idx[i] = 0; | 301 | track->cb_color_size_idx[i] = 0; |
298 | track->cb_color_info[i] = 0; | 302 | track->cb_color_info[i] = 0; |
303 | track->cb_color_view[i] = 0xFFFFFFFF; | ||
299 | track->cb_color_bo[i] = NULL; | 304 | track->cb_color_bo[i] = NULL; |
300 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; | 305 | track->cb_color_bo_offset[i] = 0xFFFFFFFF; |
301 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; | 306 | track->cb_color_bo_mc[i] = 0xFFFFFFFF; |
@@ -310,6 +315,13 @@ static void r600_cs_track_init(struct r600_cs_track *track) | |||
310 | track->db_depth_size = 0xFFFFFFFF; | 315 | track->db_depth_size = 0xFFFFFFFF; |
311 | track->db_depth_size_idx = 0; | 316 | track->db_depth_size_idx = 0; |
312 | track->db_depth_control = 0xFFFFFFFF; | 317 | track->db_depth_control = 0xFFFFFFFF; |
318 | |||
319 | for (i = 0; i < 4; i++) { | ||
320 | track->vgt_strmout_size[i] = 0; | ||
321 | track->vgt_strmout_bo[i] = NULL; | ||
322 | track->vgt_strmout_bo_offset[i] = 0xFFFFFFFF; | ||
323 | track->vgt_strmout_bo_mc[i] = 0xFFFFFFFF; | ||
324 | } | ||
313 | } | 325 | } |
314 | 326 | ||
315 | static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | 327 | static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) |
@@ -322,13 +334,14 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
322 | volatile u32 *ib = p->ib->ptr; | 334 | volatile u32 *ib = p->ib->ptr; |
323 | unsigned array_mode; | 335 | unsigned array_mode; |
324 | u32 format; | 336 | u32 format; |
337 | |||
325 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { | 338 | if (G_0280A0_TILE_MODE(track->cb_color_info[i])) { |
326 | dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); | 339 | dev_warn(p->dev, "FMASK or CMASK buffer are not supported by this kernel\n"); |
327 | return -EINVAL; | 340 | return -EINVAL; |
328 | } | 341 | } |
329 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; | 342 | size = radeon_bo_size(track->cb_color_bo[i]) - track->cb_color_bo_offset[i]; |
330 | format = G_0280A0_FORMAT(track->cb_color_info[i]); | 343 | format = G_0280A0_FORMAT(track->cb_color_info[i]); |
331 | if (!fmt_is_valid_color(format)) { | 344 | if (!r600_fmt_is_valid_color(format)) { |
332 | dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n", | 345 | dev_warn(p->dev, "%s:%d cb invalid format %d for %d (0x%08X)\n", |
333 | __func__, __LINE__, format, | 346 | __func__, __LINE__, format, |
334 | i, track->cb_color_info[i]); | 347 | i, track->cb_color_info[i]); |
@@ -349,7 +362,7 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
349 | array_check.nbanks = track->nbanks; | 362 | array_check.nbanks = track->nbanks; |
350 | array_check.npipes = track->npipes; | 363 | array_check.npipes = track->npipes; |
351 | array_check.nsamples = track->nsamples; | 364 | array_check.nsamples = track->nsamples; |
352 | array_check.blocksize = fmt_get_blocksize(format); | 365 | array_check.blocksize = r600_fmt_get_blocksize(format); |
353 | if (r600_get_array_mode_alignment(&array_check, | 366 | if (r600_get_array_mode_alignment(&array_check, |
354 | &pitch_align, &height_align, &depth_align, &base_align)) { | 367 | &pitch_align, &height_align, &depth_align, &base_align)) { |
355 | dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, | 368 | dev_warn(p->dev, "%s invalid tiling %d for %d (0x%08X)\n", __func__, |
@@ -393,7 +406,18 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
393 | } | 406 | } |
394 | 407 | ||
395 | /* check offset */ | 408 | /* check offset */ |
396 | tmp = fmt_get_nblocksy(format, height) * fmt_get_nblocksx(format, pitch) * fmt_get_blocksize(format); | 409 | tmp = r600_fmt_get_nblocksy(format, height) * r600_fmt_get_nblocksx(format, pitch) * r600_fmt_get_blocksize(format); |
410 | switch (array_mode) { | ||
411 | default: | ||
412 | case V_0280A0_ARRAY_LINEAR_GENERAL: | ||
413 | case V_0280A0_ARRAY_LINEAR_ALIGNED: | ||
414 | tmp += track->cb_color_view[i] & 0xFF; | ||
415 | break; | ||
416 | case V_0280A0_ARRAY_1D_TILED_THIN1: | ||
417 | case V_0280A0_ARRAY_2D_TILED_THIN1: | ||
418 | tmp += G_028080_SLICE_MAX(track->cb_color_view[i]) * tmp; | ||
419 | break; | ||
420 | } | ||
397 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { | 421 | if ((tmp + track->cb_color_bo_offset[i]) > radeon_bo_size(track->cb_color_bo[i])) { |
398 | if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { | 422 | if (array_mode == V_0280A0_ARRAY_LINEAR_GENERAL) { |
399 | /* the initial DDX does bad things with the CB size occasionally */ | 423 | /* the initial DDX does bad things with the CB size occasionally */ |
@@ -403,10 +427,13 @@ static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) | |||
403 | * broken userspace. | 427 | * broken userspace. |
404 | */ | 428 | */ |
405 | } else { | 429 | } else { |
406 | dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big\n", __func__, i, | 430 | dev_warn(p->dev, "%s offset[%d] %d %d %d %lu too big (%d %d) (%d %d %d)\n", |
407 | array_mode, | 431 | __func__, i, array_mode, |
408 | track->cb_color_bo_offset[i], tmp, | 432 | track->cb_color_bo_offset[i], tmp, |
409 | radeon_bo_size(track->cb_color_bo[i])); | 433 | radeon_bo_size(track->cb_color_bo[i]), |
434 | pitch, height, r600_fmt_get_nblocksx(format, pitch), | ||
435 | r600_fmt_get_nblocksy(format, height), | ||
436 | r600_fmt_get_blocksize(format)); | ||
410 | return -EINVAL; | 437 | return -EINVAL; |
411 | } | 438 | } |
412 | } | 439 | } |
@@ -430,11 +457,28 @@ static int r600_cs_track_check(struct radeon_cs_parser *p) | |||
430 | /* on legacy kernel we don't perform advanced check */ | 457 | /* on legacy kernel we don't perform advanced check */ |
431 | if (p->rdev == NULL) | 458 | if (p->rdev == NULL) |
432 | return 0; | 459 | return 0; |
433 | /* we don't support out buffer yet */ | 460 | |
434 | if (track->vgt_strmout_en || track->vgt_strmout_buffer_en) { | 461 | /* check streamout */ |
435 | dev_warn(p->dev, "this kernel doesn't support SMX output buffer\n"); | 462 | if (track->vgt_strmout_en) { |
436 | return -EINVAL; | 463 | for (i = 0; i < 4; i++) { |
464 | if (track->vgt_strmout_buffer_en & (1 << i)) { | ||
465 | if (track->vgt_strmout_bo[i]) { | ||
466 | u64 offset = (u64)track->vgt_strmout_bo_offset[i] + | ||
467 | (u64)track->vgt_strmout_size[i]; | ||
468 | if (offset > radeon_bo_size(track->vgt_strmout_bo[i])) { | ||
469 | DRM_ERROR("streamout %d bo too small: 0x%llx, 0x%lx\n", | ||
470 | i, offset, | ||
471 | radeon_bo_size(track->vgt_strmout_bo[i])); | ||
472 | return -EINVAL; | ||
473 | } | ||
474 | } else { | ||
475 | dev_warn(p->dev, "No buffer for streamout %d\n", i); | ||
476 | return -EINVAL; | ||
477 | } | ||
478 | } | ||
479 | } | ||
437 | } | 480 | } |
481 | |||
438 | /* check that we have a cb for each enabled target, we don't check | 482 | /* check that we have a cb for each enabled target, we don't check |
439 | * shader_mask because it seems mesa isn't always setting it :( | 483 | * shader_mask because it seems mesa isn't always setting it :( |
440 | */ | 484 | */ |
@@ -975,6 +1019,39 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
975 | case R_028B20_VGT_STRMOUT_BUFFER_EN: | 1019 | case R_028B20_VGT_STRMOUT_BUFFER_EN: |
976 | track->vgt_strmout_buffer_en = radeon_get_ib_value(p, idx); | 1020 | track->vgt_strmout_buffer_en = radeon_get_ib_value(p, idx); |
977 | break; | 1021 | break; |
1022 | case VGT_STRMOUT_BUFFER_BASE_0: | ||
1023 | case VGT_STRMOUT_BUFFER_BASE_1: | ||
1024 | case VGT_STRMOUT_BUFFER_BASE_2: | ||
1025 | case VGT_STRMOUT_BUFFER_BASE_3: | ||
1026 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
1027 | if (r) { | ||
1028 | dev_warn(p->dev, "bad SET_CONTEXT_REG " | ||
1029 | "0x%04X\n", reg); | ||
1030 | return -EINVAL; | ||
1031 | } | ||
1032 | tmp = (reg - VGT_STRMOUT_BUFFER_BASE_0) / 16; | ||
1033 | track->vgt_strmout_bo_offset[tmp] = radeon_get_ib_value(p, idx) << 8; | ||
1034 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1035 | track->vgt_strmout_bo[tmp] = reloc->robj; | ||
1036 | track->vgt_strmout_bo_mc[tmp] = reloc->lobj.gpu_offset; | ||
1037 | break; | ||
1038 | case VGT_STRMOUT_BUFFER_SIZE_0: | ||
1039 | case VGT_STRMOUT_BUFFER_SIZE_1: | ||
1040 | case VGT_STRMOUT_BUFFER_SIZE_2: | ||
1041 | case VGT_STRMOUT_BUFFER_SIZE_3: | ||
1042 | tmp = (reg - VGT_STRMOUT_BUFFER_SIZE_0) / 16; | ||
1043 | /* size in register is DWs, convert to bytes */ | ||
1044 | track->vgt_strmout_size[tmp] = radeon_get_ib_value(p, idx) * 4; | ||
1045 | break; | ||
1046 | case CP_COHER_BASE: | ||
1047 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
1048 | if (r) { | ||
1049 | dev_warn(p->dev, "missing reloc for CP_COHER_BASE " | ||
1050 | "0x%04X\n", reg); | ||
1051 | return -EINVAL; | ||
1052 | } | ||
1053 | ib[idx] += (u32)((reloc->lobj.gpu_offset >> 8) & 0xffffffff); | ||
1054 | break; | ||
978 | case R_028238_CB_TARGET_MASK: | 1055 | case R_028238_CB_TARGET_MASK: |
979 | track->cb_target_mask = radeon_get_ib_value(p, idx); | 1056 | track->cb_target_mask = radeon_get_ib_value(p, idx); |
980 | break; | 1057 | break; |
@@ -1014,6 +1091,17 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1014 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); | 1091 | track->cb_color_info[tmp] = radeon_get_ib_value(p, idx); |
1015 | } | 1092 | } |
1016 | break; | 1093 | break; |
1094 | case R_028080_CB_COLOR0_VIEW: | ||
1095 | case R_028084_CB_COLOR1_VIEW: | ||
1096 | case R_028088_CB_COLOR2_VIEW: | ||
1097 | case R_02808C_CB_COLOR3_VIEW: | ||
1098 | case R_028090_CB_COLOR4_VIEW: | ||
1099 | case R_028094_CB_COLOR5_VIEW: | ||
1100 | case R_028098_CB_COLOR6_VIEW: | ||
1101 | case R_02809C_CB_COLOR7_VIEW: | ||
1102 | tmp = (reg - R_028080_CB_COLOR0_VIEW) / 4; | ||
1103 | track->cb_color_view[tmp] = radeon_get_ib_value(p, idx); | ||
1104 | break; | ||
1017 | case R_028060_CB_COLOR0_SIZE: | 1105 | case R_028060_CB_COLOR0_SIZE: |
1018 | case R_028064_CB_COLOR1_SIZE: | 1106 | case R_028064_CB_COLOR1_SIZE: |
1019 | case R_028068_CB_COLOR2_SIZE: | 1107 | case R_028068_CB_COLOR2_SIZE: |
@@ -1198,7 +1286,7 @@ static int r600_cs_check_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | |||
1198 | return 0; | 1286 | return 0; |
1199 | } | 1287 | } |
1200 | 1288 | ||
1201 | static unsigned mip_minify(unsigned size, unsigned level) | 1289 | unsigned r600_mip_minify(unsigned size, unsigned level) |
1202 | { | 1290 | { |
1203 | unsigned val; | 1291 | unsigned val; |
1204 | 1292 | ||
@@ -1220,22 +1308,22 @@ static void r600_texture_size(unsigned nfaces, unsigned blevel, unsigned llevel, | |||
1220 | unsigned nlevels = llevel - blevel + 1; | 1308 | unsigned nlevels = llevel - blevel + 1; |
1221 | 1309 | ||
1222 | *l0_size = -1; | 1310 | *l0_size = -1; |
1223 | blocksize = fmt_get_blocksize(format); | 1311 | blocksize = r600_fmt_get_blocksize(format); |
1224 | 1312 | ||
1225 | w0 = mip_minify(w0, 0); | 1313 | w0 = r600_mip_minify(w0, 0); |
1226 | h0 = mip_minify(h0, 0); | 1314 | h0 = r600_mip_minify(h0, 0); |
1227 | d0 = mip_minify(d0, 0); | 1315 | d0 = r600_mip_minify(d0, 0); |
1228 | for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { | 1316 | for(i = 0, offset = 0, level = blevel; i < nlevels; i++, level++) { |
1229 | width = mip_minify(w0, i); | 1317 | width = r600_mip_minify(w0, i); |
1230 | nbx = fmt_get_nblocksx(format, width); | 1318 | nbx = r600_fmt_get_nblocksx(format, width); |
1231 | 1319 | ||
1232 | nbx = round_up(nbx, block_align); | 1320 | nbx = round_up(nbx, block_align); |
1233 | 1321 | ||
1234 | height = mip_minify(h0, i); | 1322 | height = r600_mip_minify(h0, i); |
1235 | nby = fmt_get_nblocksy(format, height); | 1323 | nby = r600_fmt_get_nblocksy(format, height); |
1236 | nby = round_up(nby, height_align); | 1324 | nby = round_up(nby, height_align); |
1237 | 1325 | ||
1238 | depth = mip_minify(d0, i); | 1326 | depth = r600_mip_minify(d0, i); |
1239 | 1327 | ||
1240 | size = nbx * nby * blocksize; | 1328 | size = nbx * nby * blocksize; |
1241 | if (nfaces) | 1329 | if (nfaces) |
@@ -1326,7 +1414,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1326 | return -EINVAL; | 1414 | return -EINVAL; |
1327 | } | 1415 | } |
1328 | format = G_038004_DATA_FORMAT(word1); | 1416 | format = G_038004_DATA_FORMAT(word1); |
1329 | if (!fmt_is_valid_texture(format, p->family)) { | 1417 | if (!r600_fmt_is_valid_texture(format, p->family)) { |
1330 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", | 1418 | dev_warn(p->dev, "%s:%d texture invalid format %d\n", |
1331 | __func__, __LINE__, format); | 1419 | __func__, __LINE__, format); |
1332 | return -EINVAL; | 1420 | return -EINVAL; |
@@ -1339,7 +1427,7 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1339 | array_check.nbanks = track->nbanks; | 1427 | array_check.nbanks = track->nbanks; |
1340 | array_check.npipes = track->npipes; | 1428 | array_check.npipes = track->npipes; |
1341 | array_check.nsamples = 1; | 1429 | array_check.nsamples = 1; |
1342 | array_check.blocksize = fmt_get_blocksize(format); | 1430 | array_check.blocksize = r600_fmt_get_blocksize(format); |
1343 | if (r600_get_array_mode_alignment(&array_check, | 1431 | if (r600_get_array_mode_alignment(&array_check, |
1344 | &pitch_align, &height_align, &depth_align, &base_align)) { | 1432 | &pitch_align, &height_align, &depth_align, &base_align)) { |
1345 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", | 1433 | dev_warn(p->dev, "%s:%d tex array mode (%d) invalid\n", |
@@ -1372,6 +1460,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1372 | word1 = radeon_get_ib_value(p, idx + 5); | 1460 | word1 = radeon_get_ib_value(p, idx + 5); |
1373 | blevel = G_038010_BASE_LEVEL(word0); | 1461 | blevel = G_038010_BASE_LEVEL(word0); |
1374 | llevel = G_038014_LAST_LEVEL(word1); | 1462 | llevel = G_038014_LAST_LEVEL(word1); |
1463 | if (blevel > llevel) { | ||
1464 | dev_warn(p->dev, "texture blevel %d > llevel %d\n", | ||
1465 | blevel, llevel); | ||
1466 | } | ||
1375 | if (array == 1) { | 1467 | if (array == 1) { |
1376 | barray = G_038014_BASE_ARRAY(word1); | 1468 | barray = G_038014_BASE_ARRAY(word1); |
1377 | larray = G_038014_LAST_ARRAY(word1); | 1469 | larray = G_038014_LAST_ARRAY(word1); |
@@ -1383,8 +1475,10 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1383 | &l0_size, &mipmap_size); | 1475 | &l0_size, &mipmap_size); |
1384 | /* using get ib will give us the offset into the texture bo */ | 1476 | /* using get ib will give us the offset into the texture bo */ |
1385 | if ((l0_size + word2) > radeon_bo_size(texture)) { | 1477 | if ((l0_size + word2) > radeon_bo_size(texture)) { |
1386 | dev_warn(p->dev, "texture bo too small (%d %d %d %d -> %d have %ld)\n", | 1478 | dev_warn(p->dev, "texture bo too small ((%d %d) (%d %d) %d %d %d -> %d have %ld)\n", |
1387 | w0, h0, format, word2, l0_size, radeon_bo_size(texture)); | 1479 | w0, h0, pitch_align, height_align, |
1480 | array_check.array_mode, format, word2, | ||
1481 | l0_size, radeon_bo_size(texture)); | ||
1388 | dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align); | 1482 | dev_warn(p->dev, "alignments %d %d %d %lld\n", pitch, pitch_align, height_align, base_align); |
1389 | return -EINVAL; | 1483 | return -EINVAL; |
1390 | } | 1484 | } |
@@ -1397,6 +1491,22 @@ static int r600_check_texture_resource(struct radeon_cs_parser *p, u32 idx, | |||
1397 | return 0; | 1491 | return 0; |
1398 | } | 1492 | } |
1399 | 1493 | ||
1494 | static bool r600_is_safe_reg(struct radeon_cs_parser *p, u32 reg, u32 idx) | ||
1495 | { | ||
1496 | u32 m, i; | ||
1497 | |||
1498 | i = (reg >> 7); | ||
1499 | if (i >= ARRAY_SIZE(r600_reg_safe_bm)) { | ||
1500 | dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); | ||
1501 | return false; | ||
1502 | } | ||
1503 | m = 1 << ((reg >> 2) & 31); | ||
1504 | if (!(r600_reg_safe_bm[i] & m)) | ||
1505 | return true; | ||
1506 | dev_warn(p->dev, "forbidden register 0x%08x at %d\n", reg, idx); | ||
1507 | return false; | ||
1508 | } | ||
1509 | |||
1400 | static int r600_packet3_check(struct radeon_cs_parser *p, | 1510 | static int r600_packet3_check(struct radeon_cs_parser *p, |
1401 | struct radeon_cs_packet *pkt) | 1511 | struct radeon_cs_packet *pkt) |
1402 | { | 1512 | { |
@@ -1742,6 +1852,100 @@ static int r600_packet3_check(struct radeon_cs_parser *p, | |||
1742 | return -EINVAL; | 1852 | return -EINVAL; |
1743 | } | 1853 | } |
1744 | break; | 1854 | break; |
1855 | case PACKET3_STRMOUT_BUFFER_UPDATE: | ||
1856 | if (pkt->count != 4) { | ||
1857 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (invalid count)\n"); | ||
1858 | return -EINVAL; | ||
1859 | } | ||
1860 | /* Updating memory at DST_ADDRESS. */ | ||
1861 | if (idx_value & 0x1) { | ||
1862 | u64 offset; | ||
1863 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
1864 | if (r) { | ||
1865 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing dst reloc)\n"); | ||
1866 | return -EINVAL; | ||
1867 | } | ||
1868 | offset = radeon_get_ib_value(p, idx+1); | ||
1869 | offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; | ||
1870 | if ((offset + 4) > radeon_bo_size(reloc->robj)) { | ||
1871 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE dst bo too small: 0x%llx, 0x%lx\n", | ||
1872 | offset + 4, radeon_bo_size(reloc->robj)); | ||
1873 | return -EINVAL; | ||
1874 | } | ||
1875 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
1876 | ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
1877 | } | ||
1878 | /* Reading data from SRC_ADDRESS. */ | ||
1879 | if (((idx_value >> 1) & 0x3) == 2) { | ||
1880 | u64 offset; | ||
1881 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
1882 | if (r) { | ||
1883 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE (missing src reloc)\n"); | ||
1884 | return -EINVAL; | ||
1885 | } | ||
1886 | offset = radeon_get_ib_value(p, idx+3); | ||
1887 | offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; | ||
1888 | if ((offset + 4) > radeon_bo_size(reloc->robj)) { | ||
1889 | DRM_ERROR("bad STRMOUT_BUFFER_UPDATE src bo too small: 0x%llx, 0x%lx\n", | ||
1890 | offset + 4, radeon_bo_size(reloc->robj)); | ||
1891 | return -EINVAL; | ||
1892 | } | ||
1893 | ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
1894 | ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
1895 | } | ||
1896 | break; | ||
1897 | case PACKET3_COPY_DW: | ||
1898 | if (pkt->count != 4) { | ||
1899 | DRM_ERROR("bad COPY_DW (invalid count)\n"); | ||
1900 | return -EINVAL; | ||
1901 | } | ||
1902 | if (idx_value & 0x1) { | ||
1903 | u64 offset; | ||
1904 | /* SRC is memory. */ | ||
1905 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
1906 | if (r) { | ||
1907 | DRM_ERROR("bad COPY_DW (missing src reloc)\n"); | ||
1908 | return -EINVAL; | ||
1909 | } | ||
1910 | offset = radeon_get_ib_value(p, idx+1); | ||
1911 | offset += ((u64)(radeon_get_ib_value(p, idx+2) & 0xff)) << 32; | ||
1912 | if ((offset + 4) > radeon_bo_size(reloc->robj)) { | ||
1913 | DRM_ERROR("bad COPY_DW src bo too small: 0x%llx, 0x%lx\n", | ||
1914 | offset + 4, radeon_bo_size(reloc->robj)); | ||
1915 | return -EINVAL; | ||
1916 | } | ||
1917 | ib[idx+1] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
1918 | ib[idx+2] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
1919 | } else { | ||
1920 | /* SRC is a reg. */ | ||
1921 | reg = radeon_get_ib_value(p, idx+1) << 2; | ||
1922 | if (!r600_is_safe_reg(p, reg, idx+1)) | ||
1923 | return -EINVAL; | ||
1924 | } | ||
1925 | if (idx_value & 0x2) { | ||
1926 | u64 offset; | ||
1927 | /* DST is memory. */ | ||
1928 | r = r600_cs_packet_next_reloc(p, &reloc); | ||
1929 | if (r) { | ||
1930 | DRM_ERROR("bad COPY_DW (missing dst reloc)\n"); | ||
1931 | return -EINVAL; | ||
1932 | } | ||
1933 | offset = radeon_get_ib_value(p, idx+3); | ||
1934 | offset += ((u64)(radeon_get_ib_value(p, idx+4) & 0xff)) << 32; | ||
1935 | if ((offset + 4) > radeon_bo_size(reloc->robj)) { | ||
1936 | DRM_ERROR("bad COPY_DW dst bo too small: 0x%llx, 0x%lx\n", | ||
1937 | offset + 4, radeon_bo_size(reloc->robj)); | ||
1938 | return -EINVAL; | ||
1939 | } | ||
1940 | ib[idx+3] += (u32)(reloc->lobj.gpu_offset & 0xffffffff); | ||
1941 | ib[idx+4] += upper_32_bits(reloc->lobj.gpu_offset) & 0xff; | ||
1942 | } else { | ||
1943 | /* DST is a reg. */ | ||
1944 | reg = radeon_get_ib_value(p, idx+3) << 2; | ||
1945 | if (!r600_is_safe_reg(p, reg, idx+3)) | ||
1946 | return -EINVAL; | ||
1947 | } | ||
1948 | break; | ||
1745 | case PACKET3_NOP: | 1949 | case PACKET3_NOP: |
1746 | break; | 1950 | break; |
1747 | default: | 1951 | default: |
diff --git a/drivers/gpu/drm/radeon/r600d.h b/drivers/gpu/drm/radeon/r600d.h index 3ee1fd7ef394..2ba460b5b62f 100644 --- a/drivers/gpu/drm/radeon/r600d.h +++ b/drivers/gpu/drm/radeon/r600d.h | |||
@@ -78,6 +78,20 @@ | |||
78 | 78 | ||
79 | #define CB_COLOR0_SIZE 0x28060 | 79 | #define CB_COLOR0_SIZE 0x28060 |
80 | #define CB_COLOR0_VIEW 0x28080 | 80 | #define CB_COLOR0_VIEW 0x28080 |
81 | #define R_028080_CB_COLOR0_VIEW 0x028080 | ||
82 | #define S_028080_SLICE_START(x) (((x) & 0x7FF) << 0) | ||
83 | #define G_028080_SLICE_START(x) (((x) >> 0) & 0x7FF) | ||
84 | #define C_028080_SLICE_START 0xFFFFF800 | ||
85 | #define S_028080_SLICE_MAX(x) (((x) & 0x7FF) << 13) | ||
86 | #define G_028080_SLICE_MAX(x) (((x) >> 13) & 0x7FF) | ||
87 | #define C_028080_SLICE_MAX 0xFF001FFF | ||
88 | #define R_028084_CB_COLOR1_VIEW 0x028084 | ||
89 | #define R_028088_CB_COLOR2_VIEW 0x028088 | ||
90 | #define R_02808C_CB_COLOR3_VIEW 0x02808C | ||
91 | #define R_028090_CB_COLOR4_VIEW 0x028090 | ||
92 | #define R_028094_CB_COLOR5_VIEW 0x028094 | ||
93 | #define R_028098_CB_COLOR6_VIEW 0x028098 | ||
94 | #define R_02809C_CB_COLOR7_VIEW 0x02809C | ||
81 | #define CB_COLOR0_INFO 0x280a0 | 95 | #define CB_COLOR0_INFO 0x280a0 |
82 | # define CB_FORMAT(x) ((x) << 2) | 96 | # define CB_FORMAT(x) ((x) << 2) |
83 | # define CB_ARRAY_MODE(x) ((x) << 8) | 97 | # define CB_ARRAY_MODE(x) ((x) << 8) |
@@ -493,6 +507,11 @@ | |||
493 | #define VGT_STRMOUT_BUFFER_OFFSET_1 0x28AEC | 507 | #define VGT_STRMOUT_BUFFER_OFFSET_1 0x28AEC |
494 | #define VGT_STRMOUT_BUFFER_OFFSET_2 0x28AFC | 508 | #define VGT_STRMOUT_BUFFER_OFFSET_2 0x28AFC |
495 | #define VGT_STRMOUT_BUFFER_OFFSET_3 0x28B0C | 509 | #define VGT_STRMOUT_BUFFER_OFFSET_3 0x28B0C |
510 | #define VGT_STRMOUT_BUFFER_SIZE_0 0x28AD0 | ||
511 | #define VGT_STRMOUT_BUFFER_SIZE_1 0x28AE0 | ||
512 | #define VGT_STRMOUT_BUFFER_SIZE_2 0x28AF0 | ||
513 | #define VGT_STRMOUT_BUFFER_SIZE_3 0x28B00 | ||
514 | |||
496 | #define VGT_STRMOUT_EN 0x28AB0 | 515 | #define VGT_STRMOUT_EN 0x28AB0 |
497 | #define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 | 516 | #define VGT_VERTEX_REUSE_BLOCK_CNTL 0x28C58 |
498 | #define VTX_REUSE_DEPTH_MASK 0x000000FF | 517 | #define VTX_REUSE_DEPTH_MASK 0x000000FF |
@@ -834,6 +853,7 @@ | |||
834 | # define PACKET3_SEM_SEL_SIGNAL (0x6 << 29) | 853 | # define PACKET3_SEM_SEL_SIGNAL (0x6 << 29) |
835 | # define PACKET3_SEM_SEL_WAIT (0x7 << 29) | 854 | # define PACKET3_SEM_SEL_WAIT (0x7 << 29) |
836 | #define PACKET3_MPEG_INDEX 0x3A | 855 | #define PACKET3_MPEG_INDEX 0x3A |
856 | #define PACKET3_COPY_DW 0x3B | ||
837 | #define PACKET3_WAIT_REG_MEM 0x3C | 857 | #define PACKET3_WAIT_REG_MEM 0x3C |
838 | #define PACKET3_MEM_WRITE 0x3D | 858 | #define PACKET3_MEM_WRITE 0x3D |
839 | #define PACKET3_INDIRECT_BUFFER 0x32 | 859 | #define PACKET3_INDIRECT_BUFFER 0x32 |
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h index 1668ec1ee770..884e0d4b114f 100644 --- a/drivers/gpu/drm/radeon/radeon.h +++ b/drivers/gpu/drm/radeon/radeon.h | |||
@@ -242,6 +242,9 @@ extern int rv6xx_get_temp(struct radeon_device *rdev); | |||
242 | extern int rv770_get_temp(struct radeon_device *rdev); | 242 | extern int rv770_get_temp(struct radeon_device *rdev); |
243 | extern int evergreen_get_temp(struct radeon_device *rdev); | 243 | extern int evergreen_get_temp(struct radeon_device *rdev); |
244 | extern int sumo_get_temp(struct radeon_device *rdev); | 244 | extern int sumo_get_temp(struct radeon_device *rdev); |
245 | extern void evergreen_tiling_fields(unsigned tiling_flags, unsigned *bankw, | ||
246 | unsigned *bankh, unsigned *mtaspect, | ||
247 | unsigned *tile_split); | ||
245 | 248 | ||
246 | /* | 249 | /* |
247 | * Fences. | 250 | * Fences. |
@@ -1750,6 +1753,16 @@ int r600_vram_scratch_init(struct radeon_device *rdev); | |||
1750 | void r600_vram_scratch_fini(struct radeon_device *rdev); | 1753 | void r600_vram_scratch_fini(struct radeon_device *rdev); |
1751 | 1754 | ||
1752 | /* | 1755 | /* |
1756 | * r600 cs checking helper | ||
1757 | */ | ||
1758 | unsigned r600_mip_minify(unsigned size, unsigned level); | ||
1759 | bool r600_fmt_is_valid_color(u32 format); | ||
1760 | bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family); | ||
1761 | int r600_fmt_get_blocksize(u32 format); | ||
1762 | int r600_fmt_get_nblocksx(u32 format, u32 w); | ||
1763 | int r600_fmt_get_nblocksy(u32 format, u32 h); | ||
1764 | |||
1765 | /* | ||
1753 | * r600 functions used by radeon_encoder.c | 1766 | * r600 functions used by radeon_encoder.c |
1754 | */ | 1767 | */ |
1755 | extern void r600_hdmi_enable(struct drm_encoder *encoder); | 1768 | extern void r600_hdmi_enable(struct drm_encoder *encoder); |
diff --git a/drivers/gpu/drm/radeon/radeon_benchmark.c b/drivers/gpu/drm/radeon/radeon_benchmark.c index 815f2341ab94..58cee89215c7 100644 --- a/drivers/gpu/drm/radeon/radeon_benchmark.c +++ b/drivers/gpu/drm/radeon/radeon_benchmark.c | |||
@@ -208,22 +208,22 @@ void radeon_benchmark(struct radeon_device *rdev, int test_number) | |||
208 | break; | 208 | break; |
209 | case 3: | 209 | case 3: |
210 | /* GTT to VRAM, buffer size sweep, powers of 2 */ | 210 | /* GTT to VRAM, buffer size sweep, powers of 2 */ |
211 | for (i = 1; i <= 65536; i <<= 1) | 211 | for (i = 1; i <= 16384; i <<= 1) |
212 | radeon_benchmark_move(rdev, i*1024, | 212 | radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, |
213 | RADEON_GEM_DOMAIN_GTT, | 213 | RADEON_GEM_DOMAIN_GTT, |
214 | RADEON_GEM_DOMAIN_VRAM); | 214 | RADEON_GEM_DOMAIN_VRAM); |
215 | break; | 215 | break; |
216 | case 4: | 216 | case 4: |
217 | /* VRAM to GTT, buffer size sweep, powers of 2 */ | 217 | /* VRAM to GTT, buffer size sweep, powers of 2 */ |
218 | for (i = 1; i <= 65536; i <<= 1) | 218 | for (i = 1; i <= 16384; i <<= 1) |
219 | radeon_benchmark_move(rdev, i*1024, | 219 | radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, |
220 | RADEON_GEM_DOMAIN_VRAM, | 220 | RADEON_GEM_DOMAIN_VRAM, |
221 | RADEON_GEM_DOMAIN_GTT); | 221 | RADEON_GEM_DOMAIN_GTT); |
222 | break; | 222 | break; |
223 | case 5: | 223 | case 5: |
224 | /* VRAM to VRAM, buffer size sweep, powers of 2 */ | 224 | /* VRAM to VRAM, buffer size sweep, powers of 2 */ |
225 | for (i = 1; i <= 65536; i <<= 1) | 225 | for (i = 1; i <= 16384; i <<= 1) |
226 | radeon_benchmark_move(rdev, i*1024, | 226 | radeon_benchmark_move(rdev, i * RADEON_GPU_PAGE_SIZE, |
227 | RADEON_GEM_DOMAIN_VRAM, | 227 | RADEON_GEM_DOMAIN_VRAM, |
228 | RADEON_GEM_DOMAIN_VRAM); | 228 | RADEON_GEM_DOMAIN_VRAM); |
229 | break; | 229 | break; |
diff --git a/drivers/gpu/drm/radeon/radeon_blit_common.h b/drivers/gpu/drm/radeon/radeon_blit_common.h new file mode 100644 index 000000000000..4ecbe72c9d2d --- /dev/null +++ b/drivers/gpu/drm/radeon/radeon_blit_common.h | |||
@@ -0,0 +1,44 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Advanced Micro Devices, Inc. | ||
3 | * Copyright 2009 Red Hat Inc. | ||
4 | * Copyright 2012 Alcatel-Lucent, Inc. | ||
5 | * | ||
6 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
7 | * copy of this software and associated documentation files (the "Software"), | ||
8 | * to deal in the Software without restriction, including without limitation | ||
9 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
10 | * and/or sell copies of the Software, and to permit persons to whom the | ||
11 | * Software is furnished to do so, subject to the following conditions: | ||
12 | * | ||
13 | * The above copyright notice and this permission notice (including the next | ||
14 | * paragraph) shall be included in all copies or substantial portions of the | ||
15 | * Software. | ||
16 | * | ||
17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
20 | * THE COPYRIGHT HOLDER(S) AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
21 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
22 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER | ||
23 | * DEALINGS IN THE SOFTWARE. | ||
24 | * | ||
25 | */ | ||
26 | |||
27 | #ifndef __RADEON_BLIT_COMMON_H__ | ||
28 | |||
29 | #define DI_PT_RECTLIST 0x11 | ||
30 | #define DI_INDEX_SIZE_16_BIT 0x0 | ||
31 | #define DI_SRC_SEL_AUTO_INDEX 0x2 | ||
32 | |||
33 | #define FMT_8 0x1 | ||
34 | #define FMT_5_6_5 0x8 | ||
35 | #define FMT_8_8_8_8 0x1a | ||
36 | #define COLOR_8 0x1 | ||
37 | #define COLOR_5_6_5 0x8 | ||
38 | #define COLOR_8_8_8_8 0x1a | ||
39 | |||
40 | #define RECT_UNIT_H 32 | ||
41 | #define RECT_UNIT_W (RADEON_GPU_PAGE_SIZE / 4 / RECT_UNIT_H) | ||
42 | |||
43 | #define __RADEON_BLIT_COMMON_H__ | ||
44 | #endif | ||
diff --git a/drivers/gpu/drm/radeon/radeon_cp.c b/drivers/gpu/drm/radeon/radeon_cp.c index 72ae8266b8e9..0ebb7d4796fa 100644 --- a/drivers/gpu/drm/radeon/radeon_cp.c +++ b/drivers/gpu/drm/radeon/radeon_cp.c | |||
@@ -2115,6 +2115,8 @@ int radeon_driver_load(struct drm_device *dev, unsigned long flags) | |||
2115 | break; | 2115 | break; |
2116 | } | 2116 | } |
2117 | 2117 | ||
2118 | pci_set_master(dev->pdev); | ||
2119 | |||
2118 | if (drm_pci_device_is_agp(dev)) | 2120 | if (drm_pci_device_is_agp(dev)) |
2119 | dev_priv->flags |= RADEON_IS_AGP; | 2121 | dev_priv->flags |= RADEON_IS_AGP; |
2120 | else if (pci_is_pcie(dev->pdev)) | 2122 | else if (pci_is_pcie(dev->pdev)) |
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c index 8c49fef1ce78..7cb062daa71e 100644 --- a/drivers/gpu/drm/radeon/radeon_display.c +++ b/drivers/gpu/drm/radeon/radeon_display.c | |||
@@ -1124,11 +1124,6 @@ static const struct drm_mode_config_funcs radeon_mode_funcs = { | |||
1124 | .output_poll_changed = radeon_output_poll_changed | 1124 | .output_poll_changed = radeon_output_poll_changed |
1125 | }; | 1125 | }; |
1126 | 1126 | ||
1127 | struct drm_prop_enum_list { | ||
1128 | int type; | ||
1129 | char *name; | ||
1130 | }; | ||
1131 | |||
1132 | static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] = | 1127 | static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] = |
1133 | { { 0, "driver" }, | 1128 | { { 0, "driver" }, |
1134 | { 1, "bios" }, | 1129 | { 1, "bios" }, |
@@ -1153,86 +1148,53 @@ static struct drm_prop_enum_list radeon_underscan_enum_list[] = | |||
1153 | 1148 | ||
1154 | static int radeon_modeset_create_props(struct radeon_device *rdev) | 1149 | static int radeon_modeset_create_props(struct radeon_device *rdev) |
1155 | { | 1150 | { |
1156 | int i, sz; | 1151 | int sz; |
1157 | 1152 | ||
1158 | if (rdev->is_atom_bios) { | 1153 | if (rdev->is_atom_bios) { |
1159 | rdev->mode_info.coherent_mode_property = | 1154 | rdev->mode_info.coherent_mode_property = |
1160 | drm_property_create(rdev->ddev, | 1155 | drm_property_create_range(rdev->ddev, 0 , "coherent", 0, 1); |
1161 | DRM_MODE_PROP_RANGE, | ||
1162 | "coherent", 2); | ||
1163 | if (!rdev->mode_info.coherent_mode_property) | 1156 | if (!rdev->mode_info.coherent_mode_property) |
1164 | return -ENOMEM; | 1157 | return -ENOMEM; |
1165 | |||
1166 | rdev->mode_info.coherent_mode_property->values[0] = 0; | ||
1167 | rdev->mode_info.coherent_mode_property->values[1] = 1; | ||
1168 | } | 1158 | } |
1169 | 1159 | ||
1170 | if (!ASIC_IS_AVIVO(rdev)) { | 1160 | if (!ASIC_IS_AVIVO(rdev)) { |
1171 | sz = ARRAY_SIZE(radeon_tmds_pll_enum_list); | 1161 | sz = ARRAY_SIZE(radeon_tmds_pll_enum_list); |
1172 | rdev->mode_info.tmds_pll_property = | 1162 | rdev->mode_info.tmds_pll_property = |
1173 | drm_property_create(rdev->ddev, | 1163 | drm_property_create_enum(rdev->ddev, 0, |
1174 | DRM_MODE_PROP_ENUM, | 1164 | "tmds_pll", |
1175 | "tmds_pll", sz); | 1165 | radeon_tmds_pll_enum_list, sz); |
1176 | for (i = 0; i < sz; i++) { | ||
1177 | drm_property_add_enum(rdev->mode_info.tmds_pll_property, | ||
1178 | i, | ||
1179 | radeon_tmds_pll_enum_list[i].type, | ||
1180 | radeon_tmds_pll_enum_list[i].name); | ||
1181 | } | ||
1182 | } | 1166 | } |
1183 | 1167 | ||
1184 | rdev->mode_info.load_detect_property = | 1168 | rdev->mode_info.load_detect_property = |
1185 | drm_property_create(rdev->ddev, | 1169 | drm_property_create_range(rdev->ddev, 0, "load detection", 0, 1); |
1186 | DRM_MODE_PROP_RANGE, | ||
1187 | "load detection", 2); | ||
1188 | if (!rdev->mode_info.load_detect_property) | 1170 | if (!rdev->mode_info.load_detect_property) |
1189 | return -ENOMEM; | 1171 | return -ENOMEM; |
1190 | rdev->mode_info.load_detect_property->values[0] = 0; | ||
1191 | rdev->mode_info.load_detect_property->values[1] = 1; | ||
1192 | 1172 | ||
1193 | drm_mode_create_scaling_mode_property(rdev->ddev); | 1173 | drm_mode_create_scaling_mode_property(rdev->ddev); |
1194 | 1174 | ||
1195 | sz = ARRAY_SIZE(radeon_tv_std_enum_list); | 1175 | sz = ARRAY_SIZE(radeon_tv_std_enum_list); |
1196 | rdev->mode_info.tv_std_property = | 1176 | rdev->mode_info.tv_std_property = |
1197 | drm_property_create(rdev->ddev, | 1177 | drm_property_create_enum(rdev->ddev, 0, |
1198 | DRM_MODE_PROP_ENUM, | 1178 | "tv standard", |
1199 | "tv standard", sz); | 1179 | radeon_tv_std_enum_list, sz); |
1200 | for (i = 0; i < sz; i++) { | ||
1201 | drm_property_add_enum(rdev->mode_info.tv_std_property, | ||
1202 | i, | ||
1203 | radeon_tv_std_enum_list[i].type, | ||
1204 | radeon_tv_std_enum_list[i].name); | ||
1205 | } | ||
1206 | 1180 | ||
1207 | sz = ARRAY_SIZE(radeon_underscan_enum_list); | 1181 | sz = ARRAY_SIZE(radeon_underscan_enum_list); |
1208 | rdev->mode_info.underscan_property = | 1182 | rdev->mode_info.underscan_property = |
1209 | drm_property_create(rdev->ddev, | 1183 | drm_property_create_enum(rdev->ddev, 0, |
1210 | DRM_MODE_PROP_ENUM, | 1184 | "underscan", |
1211 | "underscan", sz); | 1185 | radeon_underscan_enum_list, sz); |
1212 | for (i = 0; i < sz; i++) { | ||
1213 | drm_property_add_enum(rdev->mode_info.underscan_property, | ||
1214 | i, | ||
1215 | radeon_underscan_enum_list[i].type, | ||
1216 | radeon_underscan_enum_list[i].name); | ||
1217 | } | ||
1218 | 1186 | ||
1219 | rdev->mode_info.underscan_hborder_property = | 1187 | rdev->mode_info.underscan_hborder_property = |
1220 | drm_property_create(rdev->ddev, | 1188 | drm_property_create_range(rdev->ddev, 0, |
1221 | DRM_MODE_PROP_RANGE, | 1189 | "underscan hborder", 0, 128); |
1222 | "underscan hborder", 2); | ||
1223 | if (!rdev->mode_info.underscan_hborder_property) | 1190 | if (!rdev->mode_info.underscan_hborder_property) |
1224 | return -ENOMEM; | 1191 | return -ENOMEM; |
1225 | rdev->mode_info.underscan_hborder_property->values[0] = 0; | ||
1226 | rdev->mode_info.underscan_hborder_property->values[1] = 128; | ||
1227 | 1192 | ||
1228 | rdev->mode_info.underscan_vborder_property = | 1193 | rdev->mode_info.underscan_vborder_property = |
1229 | drm_property_create(rdev->ddev, | 1194 | drm_property_create_range(rdev->ddev, 0, |
1230 | DRM_MODE_PROP_RANGE, | 1195 | "underscan vborder", 0, 128); |
1231 | "underscan vborder", 2); | ||
1232 | if (!rdev->mode_info.underscan_vborder_property) | 1196 | if (!rdev->mode_info.underscan_vborder_property) |
1233 | return -ENOMEM; | 1197 | return -ENOMEM; |
1234 | rdev->mode_info.underscan_vborder_property->values[0] = 0; | ||
1235 | rdev->mode_info.underscan_vborder_property->values[1] = 128; | ||
1236 | 1198 | ||
1237 | return 0; | 1199 | return 0; |
1238 | } | 1200 | } |
@@ -1278,6 +1240,9 @@ int radeon_modeset_init(struct radeon_device *rdev) | |||
1278 | rdev->ddev->mode_config.max_height = 4096; | 1240 | rdev->ddev->mode_config.max_height = 4096; |
1279 | } | 1241 | } |
1280 | 1242 | ||
1243 | rdev->ddev->mode_config.preferred_depth = 24; | ||
1244 | rdev->ddev->mode_config.prefer_shadow = 1; | ||
1245 | |||
1281 | rdev->ddev->mode_config.fb_base = rdev->mc.aper_base; | 1246 | rdev->ddev->mode_config.fb_base = rdev->mc.aper_base; |
1282 | 1247 | ||
1283 | ret = radeon_modeset_create_props(rdev); | 1248 | ret = radeon_modeset_create_props(rdev); |
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c index 8032f1fedb11..498d21d50ba3 100644 --- a/drivers/gpu/drm/radeon/radeon_drv.c +++ b/drivers/gpu/drm/radeon/radeon_drv.c | |||
@@ -54,10 +54,11 @@ | |||
54 | * 2.10.0 - fusion 2D tiling | 54 | * 2.10.0 - fusion 2D tiling |
55 | * 2.11.0 - backend map, initial compute support for the CS checker | 55 | * 2.11.0 - backend map, initial compute support for the CS checker |
56 | * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS | 56 | * 2.12.0 - RADEON_CS_KEEP_TILING_FLAGS |
57 | * 2.13.0 - virtual memory support | 57 | * 2.13.0 - virtual memory support, streamout |
58 | * 2.14.0 - add evergreen tiling informations | ||
58 | */ | 59 | */ |
59 | #define KMS_DRIVER_MAJOR 2 | 60 | #define KMS_DRIVER_MAJOR 2 |
60 | #define KMS_DRIVER_MINOR 13 | 61 | #define KMS_DRIVER_MINOR 14 |
61 | #define KMS_DRIVER_PATCHLEVEL 0 | 62 | #define KMS_DRIVER_PATCHLEVEL 0 |
62 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); | 63 | int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); |
63 | int radeon_driver_unload_kms(struct drm_device *dev); | 64 | int radeon_driver_unload_kms(struct drm_device *dev); |
diff --git a/drivers/gpu/drm/radeon/radeon_fb.c b/drivers/gpu/drm/radeon/radeon_fb.c index cf2bf35b56b8..a5692d5f415d 100644 --- a/drivers/gpu/drm/radeon/radeon_fb.c +++ b/drivers/gpu/drm/radeon/radeon_fb.c | |||
@@ -254,11 +254,7 @@ static int radeonfb_create(struct radeon_fbdev *rfbdev, | |||
254 | info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; | 254 | info->apertures->ranges[0].base = rdev->ddev->mode_config.fb_base; |
255 | info->apertures->ranges[0].size = rdev->mc.aper_size; | 255 | info->apertures->ranges[0].size = rdev->mc.aper_size; |
256 | 256 | ||
257 | info->pixmap.size = 64*1024; | 257 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
258 | info->pixmap.buf_align = 8; | ||
259 | info->pixmap.access_align = 32; | ||
260 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
261 | info->pixmap.scan_align = 1; | ||
262 | 258 | ||
263 | if (info->screen_base == NULL) { | 259 | if (info->screen_base == NULL) { |
264 | ret = -ENOSPC; | 260 | ret = -ENOSPC; |
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c index 98a8ad680109..3265a7a57977 100644 --- a/drivers/gpu/drm/radeon/radeon_i2c.c +++ b/drivers/gpu/drm/radeon/radeon_i2c.c | |||
@@ -30,6 +30,10 @@ | |||
30 | #include "radeon.h" | 30 | #include "radeon.h" |
31 | #include "atom.h" | 31 | #include "atom.h" |
32 | 32 | ||
33 | extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap, | ||
34 | struct i2c_msg *msgs, int num); | ||
35 | extern u32 radeon_atom_hw_i2c_func(struct i2c_adapter *adap); | ||
36 | |||
33 | /** | 37 | /** |
34 | * radeon_ddc_probe | 38 | * radeon_ddc_probe |
35 | * | 39 | * |
@@ -882,6 +886,11 @@ static const struct i2c_algorithm radeon_i2c_algo = { | |||
882 | .functionality = radeon_hw_i2c_func, | 886 | .functionality = radeon_hw_i2c_func, |
883 | }; | 887 | }; |
884 | 888 | ||
889 | static const struct i2c_algorithm radeon_atom_i2c_algo = { | ||
890 | .master_xfer = radeon_atom_hw_i2c_xfer, | ||
891 | .functionality = radeon_atom_hw_i2c_func, | ||
892 | }; | ||
893 | |||
885 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | 894 | struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, |
886 | struct radeon_i2c_bus_rec *rec, | 895 | struct radeon_i2c_bus_rec *rec, |
887 | const char *name) | 896 | const char *name) |
@@ -914,6 +923,18 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
914 | DRM_ERROR("Failed to register hw i2c %s\n", name); | 923 | DRM_ERROR("Failed to register hw i2c %s\n", name); |
915 | goto out_free; | 924 | goto out_free; |
916 | } | 925 | } |
926 | } else if (rec->hw_capable && | ||
927 | radeon_hw_i2c && | ||
928 | ASIC_IS_DCE3(rdev)) { | ||
929 | /* hw i2c using atom */ | ||
930 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), | ||
931 | "Radeon i2c hw bus %s", name); | ||
932 | i2c->adapter.algo = &radeon_atom_i2c_algo; | ||
933 | ret = i2c_add_adapter(&i2c->adapter); | ||
934 | if (ret) { | ||
935 | DRM_ERROR("Failed to register hw i2c %s\n", name); | ||
936 | goto out_free; | ||
937 | } | ||
917 | } else { | 938 | } else { |
918 | /* set the radeon bit adapter */ | 939 | /* set the radeon bit adapter */ |
919 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), | 940 | snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), |
@@ -925,10 +946,8 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, | |||
925 | i2c->algo.bit.setscl = set_clock; | 946 | i2c->algo.bit.setscl = set_clock; |
926 | i2c->algo.bit.getsda = get_data; | 947 | i2c->algo.bit.getsda = get_data; |
927 | i2c->algo.bit.getscl = get_clock; | 948 | i2c->algo.bit.getscl = get_clock; |
928 | i2c->algo.bit.udelay = 20; | 949 | i2c->algo.bit.udelay = 10; |
929 | /* vesa says 2.2 ms is enough, 1 jiffy doesn't seem to always | 950 | i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */ |
930 | * make this, 2 jiffies is a lot more reliable */ | ||
931 | i2c->algo.bit.timeout = 2; | ||
932 | i2c->algo.bit.data = i2c; | 951 | i2c->algo.bit.data = i2c; |
933 | ret = i2c_bit_add_bus(&i2c->adapter); | 952 | ret = i2c_bit_add_bus(&i2c->adapter); |
934 | if (ret) { | 953 | if (ret) { |
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c index d3352889a870..1986ebae1ef2 100644 --- a/drivers/gpu/drm/radeon/radeon_kms.c +++ b/drivers/gpu/drm/radeon/radeon_kms.c | |||
@@ -57,6 +57,8 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags) | |||
57 | } | 57 | } |
58 | dev->dev_private = (void *)rdev; | 58 | dev->dev_private = (void *)rdev; |
59 | 59 | ||
60 | pci_set_master(dev->pdev); | ||
61 | |||
60 | /* update BUS flag */ | 62 | /* update BUS flag */ |
61 | if (drm_pci_device_is_agp(dev)) { | 63 | if (drm_pci_device_is_agp(dev)) { |
62 | flags |= RADEON_IS_AGP; | 64 | flags |= RADEON_IS_AGP; |
diff --git a/drivers/gpu/drm/radeon/radeon_object.c b/drivers/gpu/drm/radeon/radeon_object.c index d45df1763598..342deaccc152 100644 --- a/drivers/gpu/drm/radeon/radeon_object.c +++ b/drivers/gpu/drm/radeon/radeon_object.c | |||
@@ -445,8 +445,54 @@ static void radeon_bo_clear_surface_reg(struct radeon_bo *bo) | |||
445 | int radeon_bo_set_tiling_flags(struct radeon_bo *bo, | 445 | int radeon_bo_set_tiling_flags(struct radeon_bo *bo, |
446 | uint32_t tiling_flags, uint32_t pitch) | 446 | uint32_t tiling_flags, uint32_t pitch) |
447 | { | 447 | { |
448 | struct radeon_device *rdev = bo->rdev; | ||
448 | int r; | 449 | int r; |
449 | 450 | ||
451 | if (rdev->family >= CHIP_CEDAR) { | ||
452 | unsigned bankw, bankh, mtaspect, tilesplit, stilesplit; | ||
453 | |||
454 | bankw = (tiling_flags >> RADEON_TILING_EG_BANKW_SHIFT) & RADEON_TILING_EG_BANKW_MASK; | ||
455 | bankh = (tiling_flags >> RADEON_TILING_EG_BANKH_SHIFT) & RADEON_TILING_EG_BANKH_MASK; | ||
456 | mtaspect = (tiling_flags >> RADEON_TILING_EG_MACRO_TILE_ASPECT_SHIFT) & RADEON_TILING_EG_MACRO_TILE_ASPECT_MASK; | ||
457 | tilesplit = (tiling_flags >> RADEON_TILING_EG_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_TILE_SPLIT_MASK; | ||
458 | stilesplit = (tiling_flags >> RADEON_TILING_EG_STENCIL_TILE_SPLIT_SHIFT) & RADEON_TILING_EG_STENCIL_TILE_SPLIT_MASK; | ||
459 | switch (bankw) { | ||
460 | case 0: | ||
461 | case 1: | ||
462 | case 2: | ||
463 | case 4: | ||
464 | case 8: | ||
465 | break; | ||
466 | default: | ||
467 | return -EINVAL; | ||
468 | } | ||
469 | switch (bankh) { | ||
470 | case 0: | ||
471 | case 1: | ||
472 | case 2: | ||
473 | case 4: | ||
474 | case 8: | ||
475 | break; | ||
476 | default: | ||
477 | return -EINVAL; | ||
478 | } | ||
479 | switch (mtaspect) { | ||
480 | case 0: | ||
481 | case 1: | ||
482 | case 2: | ||
483 | case 4: | ||
484 | case 8: | ||
485 | break; | ||
486 | default: | ||
487 | return -EINVAL; | ||
488 | } | ||
489 | if (tilesplit > 6) { | ||
490 | return -EINVAL; | ||
491 | } | ||
492 | if (stilesplit > 6) { | ||
493 | return -EINVAL; | ||
494 | } | ||
495 | } | ||
450 | r = radeon_bo_reserve(bo, false); | 496 | r = radeon_bo_reserve(bo, false); |
451 | if (unlikely(r != 0)) | 497 | if (unlikely(r != 0)) |
452 | return r; | 498 | return r; |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/cayman b/drivers/gpu/drm/radeon/reg_srcs/cayman index 2316977eb924..7b526d3ceac1 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/cayman +++ b/drivers/gpu/drm/radeon/reg_srcs/cayman | |||
@@ -1,5 +1,8 @@ | |||
1 | cayman 0x9400 | 1 | cayman 0x9400 |
2 | 0x0000802C GRBM_GFX_INDEX | 2 | 0x0000802C GRBM_GFX_INDEX |
3 | 0x000084FC CP_STRMOUT_CNTL | ||
4 | 0x000085F0 CP_COHER_CNTL | ||
5 | 0x000085F4 CP_COHER_SIZE | ||
3 | 0x000088B0 VGT_VTX_VECT_EJECT_REG | 6 | 0x000088B0 VGT_VTX_VECT_EJECT_REG |
4 | 0x000088C4 VGT_CACHE_INVALIDATION | 7 | 0x000088C4 VGT_CACHE_INVALIDATION |
5 | 0x000088D4 VGT_GS_VERTEX_REUSE | 8 | 0x000088D4 VGT_GS_VERTEX_REUSE |
@@ -77,7 +80,6 @@ cayman 0x9400 | |||
77 | 0x0002802C DB_DEPTH_CLEAR | 80 | 0x0002802C DB_DEPTH_CLEAR |
78 | 0x00028030 PA_SC_SCREEN_SCISSOR_TL | 81 | 0x00028030 PA_SC_SCREEN_SCISSOR_TL |
79 | 0x00028034 PA_SC_SCREEN_SCISSOR_BR | 82 | 0x00028034 PA_SC_SCREEN_SCISSOR_BR |
80 | 0x0002805C DB_DEPTH_SLICE | ||
81 | 0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 | 83 | 0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 |
82 | 0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 | 84 | 0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 |
83 | 0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 | 85 | 0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 |
@@ -512,6 +514,13 @@ cayman 0x9400 | |||
512 | 0x00028AC0 DB_SRESULTS_COMPARE_STATE0 | 514 | 0x00028AC0 DB_SRESULTS_COMPARE_STATE0 |
513 | 0x00028AC4 DB_SRESULTS_COMPARE_STATE1 | 515 | 0x00028AC4 DB_SRESULTS_COMPARE_STATE1 |
514 | 0x00028AC8 DB_PRELOAD_CONTROL | 516 | 0x00028AC8 DB_PRELOAD_CONTROL |
517 | 0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0 | ||
518 | 0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1 | ||
519 | 0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2 | ||
520 | 0x00028B04 VGT_STRMOUT_VTX_STRIDE_3 | ||
521 | 0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET | ||
522 | 0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE | ||
523 | 0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE | ||
515 | 0x00028B38 VGT_GS_MAX_VERT_OUT | 524 | 0x00028B38 VGT_GS_MAX_VERT_OUT |
516 | 0x00028B54 VGT_SHADER_STAGES_EN | 525 | 0x00028B54 VGT_SHADER_STAGES_EN |
517 | 0x00028B58 VGT_LS_HS_CONFIG | 526 | 0x00028B58 VGT_LS_HS_CONFIG |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/evergreen b/drivers/gpu/drm/radeon/reg_srcs/evergreen index 161737a28c23..7f4339463e31 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/evergreen +++ b/drivers/gpu/drm/radeon/reg_srcs/evergreen | |||
@@ -4,6 +4,9 @@ evergreen 0x9400 | |||
4 | 0x00008044 WAIT_UNTIL_POLL_CNTL | 4 | 0x00008044 WAIT_UNTIL_POLL_CNTL |
5 | 0x00008048 WAIT_UNTIL_POLL_MASK | 5 | 0x00008048 WAIT_UNTIL_POLL_MASK |
6 | 0x0000804c WAIT_UNTIL_POLL_REFDATA | 6 | 0x0000804c WAIT_UNTIL_POLL_REFDATA |
7 | 0x000084FC CP_STRMOUT_CNTL | ||
8 | 0x000085F0 CP_COHER_CNTL | ||
9 | 0x000085F4 CP_COHER_SIZE | ||
7 | 0x000088B0 VGT_VTX_VECT_EJECT_REG | 10 | 0x000088B0 VGT_VTX_VECT_EJECT_REG |
8 | 0x000088C4 VGT_CACHE_INVALIDATION | 11 | 0x000088C4 VGT_CACHE_INVALIDATION |
9 | 0x000088D4 VGT_GS_VERTEX_REUSE | 12 | 0x000088D4 VGT_GS_VERTEX_REUSE |
@@ -93,7 +96,6 @@ evergreen 0x9400 | |||
93 | 0x0002802C DB_DEPTH_CLEAR | 96 | 0x0002802C DB_DEPTH_CLEAR |
94 | 0x00028030 PA_SC_SCREEN_SCISSOR_TL | 97 | 0x00028030 PA_SC_SCREEN_SCISSOR_TL |
95 | 0x00028034 PA_SC_SCREEN_SCISSOR_BR | 98 | 0x00028034 PA_SC_SCREEN_SCISSOR_BR |
96 | 0x0002805C DB_DEPTH_SLICE | ||
97 | 0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 | 99 | 0x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 |
98 | 0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 | 100 | 0x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 |
99 | 0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 | 101 | 0x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 |
@@ -522,6 +524,13 @@ evergreen 0x9400 | |||
522 | 0x00028AC0 DB_SRESULTS_COMPARE_STATE0 | 524 | 0x00028AC0 DB_SRESULTS_COMPARE_STATE0 |
523 | 0x00028AC4 DB_SRESULTS_COMPARE_STATE1 | 525 | 0x00028AC4 DB_SRESULTS_COMPARE_STATE1 |
524 | 0x00028AC8 DB_PRELOAD_CONTROL | 526 | 0x00028AC8 DB_PRELOAD_CONTROL |
527 | 0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0 | ||
528 | 0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1 | ||
529 | 0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2 | ||
530 | 0x00028B04 VGT_STRMOUT_VTX_STRIDE_3 | ||
531 | 0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET | ||
532 | 0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE | ||
533 | 0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE | ||
525 | 0x00028B38 VGT_GS_MAX_VERT_OUT | 534 | 0x00028B38 VGT_GS_MAX_VERT_OUT |
526 | 0x00028B54 VGT_SHADER_STAGES_EN | 535 | 0x00028B54 VGT_SHADER_STAGES_EN |
527 | 0x00028B58 VGT_LS_HS_CONFIG | 536 | 0x00028B58 VGT_LS_HS_CONFIG |
diff --git a/drivers/gpu/drm/radeon/reg_srcs/r600 b/drivers/gpu/drm/radeon/reg_srcs/r600 index 0380c5c15f80..79d245527ba8 100644 --- a/drivers/gpu/drm/radeon/reg_srcs/r600 +++ b/drivers/gpu/drm/radeon/reg_srcs/r600 | |||
@@ -3,6 +3,9 @@ r600 0x9400 | |||
3 | 0x00028230 R7xx_PA_SC_EDGERULE | 3 | 0x00028230 R7xx_PA_SC_EDGERULE |
4 | 0x000286C8 R7xx_SPI_THREAD_GROUPING | 4 | 0x000286C8 R7xx_SPI_THREAD_GROUPING |
5 | 0x00008D8C R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ | 5 | 0x00008D8C R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ |
6 | 0x00008490 CP_STRMOUT_CNTL | ||
7 | 0x000085F0 CP_COHER_CNTL | ||
8 | 0x000085F4 CP_COHER_SIZE | ||
6 | 0x000088C4 VGT_CACHE_INVALIDATION | 9 | 0x000088C4 VGT_CACHE_INVALIDATION |
7 | 0x00028A50 VGT_ENHANCE | 10 | 0x00028A50 VGT_ENHANCE |
8 | 0x000088CC VGT_ES_PER_GS | 11 | 0x000088CC VGT_ES_PER_GS |
@@ -38,6 +41,13 @@ r600 0x9400 | |||
38 | 0x00028AB4 VGT_REUSE_OFF | 41 | 0x00028AB4 VGT_REUSE_OFF |
39 | 0x00028AB8 VGT_VTX_CNT_EN | 42 | 0x00028AB8 VGT_VTX_CNT_EN |
40 | 0x000088B0 VGT_VTX_VECT_EJECT_REG | 43 | 0x000088B0 VGT_VTX_VECT_EJECT_REG |
44 | 0x00028AD4 VGT_STRMOUT_VTX_STRIDE_0 | ||
45 | 0x00028AE4 VGT_STRMOUT_VTX_STRIDE_1 | ||
46 | 0x00028AF4 VGT_STRMOUT_VTX_STRIDE_2 | ||
47 | 0x00028B04 VGT_STRMOUT_VTX_STRIDE_3 | ||
48 | 0x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET | ||
49 | 0x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE | ||
50 | 0x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE | ||
41 | 0x00028810 PA_CL_CLIP_CNTL | 51 | 0x00028810 PA_CL_CLIP_CNTL |
42 | 0x00008A14 PA_CL_ENHANCE | 52 | 0x00008A14 PA_CL_ENHANCE |
43 | 0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ | 53 | 0x00028C14 PA_CL_GB_HORZ_CLIP_ADJ |
@@ -429,6 +439,7 @@ r600 0x9400 | |||
429 | 0x00028438 SX_ALPHA_REF | 439 | 0x00028438 SX_ALPHA_REF |
430 | 0x00028410 SX_ALPHA_TEST_CONTROL | 440 | 0x00028410 SX_ALPHA_TEST_CONTROL |
431 | 0x00028350 SX_MISC | 441 | 0x00028350 SX_MISC |
442 | 0x00028354 SX_SURFACE_SYNC | ||
432 | 0x00009014 SX_MEMORY_EXPORT_SIZE | 443 | 0x00009014 SX_MEMORY_EXPORT_SIZE |
433 | 0x00009604 TC_INVALIDATE | 444 | 0x00009604 TC_INVALIDATE |
434 | 0x00009400 TD_FILTER4 | 445 | 0x00009400 TD_FILTER4 |
@@ -743,14 +754,6 @@ r600 0x9400 | |||
743 | 0x00028114 CB_COLOR5_MASK | 754 | 0x00028114 CB_COLOR5_MASK |
744 | 0x00028118 CB_COLOR6_MASK | 755 | 0x00028118 CB_COLOR6_MASK |
745 | 0x0002811C CB_COLOR7_MASK | 756 | 0x0002811C CB_COLOR7_MASK |
746 | 0x00028080 CB_COLOR0_VIEW | ||
747 | 0x00028084 CB_COLOR1_VIEW | ||
748 | 0x00028088 CB_COLOR2_VIEW | ||
749 | 0x0002808C CB_COLOR3_VIEW | ||
750 | 0x00028090 CB_COLOR4_VIEW | ||
751 | 0x00028094 CB_COLOR5_VIEW | ||
752 | 0x00028098 CB_COLOR6_VIEW | ||
753 | 0x0002809C CB_COLOR7_VIEW | ||
754 | 0x00028808 CB_COLOR_CONTROL | 757 | 0x00028808 CB_COLOR_CONTROL |
755 | 0x0002842C CB_FOG_BLUE | 758 | 0x0002842C CB_FOG_BLUE |
756 | 0x00028428 CB_FOG_GREEN | 759 | 0x00028428 CB_FOG_GREEN |
diff --git a/drivers/gpu/drm/sis/sis_drv.c b/drivers/gpu/drm/sis/sis_drv.c index 573220cc5269..30d98d14b5c5 100644 --- a/drivers/gpu/drm/sis/sis_drv.c +++ b/drivers/gpu/drm/sis/sis_drv.c | |||
@@ -41,6 +41,8 @@ static int sis_driver_load(struct drm_device *dev, unsigned long chipset) | |||
41 | { | 41 | { |
42 | drm_sis_private_t *dev_priv; | 42 | drm_sis_private_t *dev_priv; |
43 | 43 | ||
44 | pci_set_master(dev->pdev); | ||
45 | |||
44 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); | 46 | dev_priv = kzalloc(sizeof(drm_sis_private_t), GFP_KERNEL); |
45 | if (dev_priv == NULL) | 47 | if (dev_priv == NULL) |
46 | return -ENOMEM; | 48 | return -ENOMEM; |
diff --git a/drivers/gpu/drm/via/via_map.c b/drivers/gpu/drm/via/via_map.c index a2ab34365151..1f182254e81e 100644 --- a/drivers/gpu/drm/via/via_map.c +++ b/drivers/gpu/drm/via/via_map.c | |||
@@ -106,6 +106,8 @@ int via_driver_load(struct drm_device *dev, unsigned long chipset) | |||
106 | 106 | ||
107 | idr_init(&dev->object_name_idr); | 107 | idr_init(&dev->object_name_idr); |
108 | 108 | ||
109 | pci_set_master(dev->pdev); | ||
110 | |||
109 | ret = drm_vblank_init(dev, 1); | 111 | ret = drm_vblank_init(dev, 1); |
110 | if (ret) { | 112 | if (ret) { |
111 | kfree(dev_priv); | 113 | kfree(dev_priv); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c index f390f5f9cb68..1760aba9ecef 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.c | |||
@@ -38,6 +38,10 @@ | |||
38 | #define VMWGFX_CHIP_SVGAII 0 | 38 | #define VMWGFX_CHIP_SVGAII 0 |
39 | #define VMW_FB_RESERVATION 0 | 39 | #define VMW_FB_RESERVATION 0 |
40 | 40 | ||
41 | #define VMW_MIN_INITIAL_WIDTH 800 | ||
42 | #define VMW_MIN_INITIAL_HEIGHT 600 | ||
43 | |||
44 | |||
41 | /** | 45 | /** |
42 | * Fully encoded drm commands. Might move to vmw_drm.h | 46 | * Fully encoded drm commands. Might move to vmw_drm.h |
43 | */ | 47 | */ |
@@ -387,6 +391,41 @@ void vmw_3d_resource_dec(struct vmw_private *dev_priv, | |||
387 | BUG_ON(n3d < 0); | 391 | BUG_ON(n3d < 0); |
388 | } | 392 | } |
389 | 393 | ||
394 | /** | ||
395 | * Sets the initial_[width|height] fields on the given vmw_private. | ||
396 | * | ||
397 | * It does so by reading SVGA_REG_[WIDTH|HEIGHT] regs and then | ||
398 | * clamping the value to fb_max_[width|height] fields and the | ||
399 | * VMW_MIN_INITIAL_[WIDTH|HEIGHT]. | ||
400 | * If the values appear to be invalid, set them to | ||
401 | * VMW_MIN_INITIAL_[WIDTH|HEIGHT]. | ||
402 | */ | ||
403 | static void vmw_get_initial_size(struct vmw_private *dev_priv) | ||
404 | { | ||
405 | uint32_t width; | ||
406 | uint32_t height; | ||
407 | |||
408 | width = vmw_read(dev_priv, SVGA_REG_WIDTH); | ||
409 | height = vmw_read(dev_priv, SVGA_REG_HEIGHT); | ||
410 | |||
411 | width = max_t(uint32_t, width, VMW_MIN_INITIAL_WIDTH); | ||
412 | height = max_t(uint32_t, height, VMW_MIN_INITIAL_HEIGHT); | ||
413 | |||
414 | if (width > dev_priv->fb_max_width || | ||
415 | height > dev_priv->fb_max_height) { | ||
416 | |||
417 | /* | ||
418 | * This is a host error and shouldn't occur. | ||
419 | */ | ||
420 | |||
421 | width = VMW_MIN_INITIAL_WIDTH; | ||
422 | height = VMW_MIN_INITIAL_HEIGHT; | ||
423 | } | ||
424 | |||
425 | dev_priv->initial_width = width; | ||
426 | dev_priv->initial_height = height; | ||
427 | } | ||
428 | |||
390 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | 429 | static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) |
391 | { | 430 | { |
392 | struct vmw_private *dev_priv; | 431 | struct vmw_private *dev_priv; |
@@ -400,6 +439,8 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
400 | } | 439 | } |
401 | memset(dev_priv, 0, sizeof(*dev_priv)); | 440 | memset(dev_priv, 0, sizeof(*dev_priv)); |
402 | 441 | ||
442 | pci_set_master(dev->pdev); | ||
443 | |||
403 | dev_priv->dev = dev; | 444 | dev_priv->dev = dev; |
404 | dev_priv->vmw_chipset = chipset; | 445 | dev_priv->vmw_chipset = chipset; |
405 | dev_priv->last_read_seqno = (uint32_t) -100; | 446 | dev_priv->last_read_seqno = (uint32_t) -100; |
@@ -441,6 +482,9 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) | |||
441 | dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE); | 482 | dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE); |
442 | dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH); | 483 | dev_priv->fb_max_width = vmw_read(dev_priv, SVGA_REG_MAX_WIDTH); |
443 | dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT); | 484 | dev_priv->fb_max_height = vmw_read(dev_priv, SVGA_REG_MAX_HEIGHT); |
485 | |||
486 | vmw_get_initial_size(dev_priv); | ||
487 | |||
444 | if (dev_priv->capabilities & SVGA_CAP_GMR) { | 488 | if (dev_priv->capabilities & SVGA_CAP_GMR) { |
445 | dev_priv->max_gmr_descriptors = | 489 | dev_priv->max_gmr_descriptors = |
446 | vmw_read(dev_priv, | 490 | vmw_read(dev_priv, |
@@ -688,6 +732,15 @@ static int vmw_driver_unload(struct drm_device *dev) | |||
688 | return 0; | 732 | return 0; |
689 | } | 733 | } |
690 | 734 | ||
735 | static void vmw_preclose(struct drm_device *dev, | ||
736 | struct drm_file *file_priv) | ||
737 | { | ||
738 | struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); | ||
739 | struct vmw_private *dev_priv = vmw_priv(dev); | ||
740 | |||
741 | vmw_event_fence_fpriv_gone(dev_priv->fman, &vmw_fp->fence_events); | ||
742 | } | ||
743 | |||
691 | static void vmw_postclose(struct drm_device *dev, | 744 | static void vmw_postclose(struct drm_device *dev, |
692 | struct drm_file *file_priv) | 745 | struct drm_file *file_priv) |
693 | { | 746 | { |
@@ -710,6 +763,7 @@ static int vmw_driver_open(struct drm_device *dev, struct drm_file *file_priv) | |||
710 | if (unlikely(vmw_fp == NULL)) | 763 | if (unlikely(vmw_fp == NULL)) |
711 | return ret; | 764 | return ret; |
712 | 765 | ||
766 | INIT_LIST_HEAD(&vmw_fp->fence_events); | ||
713 | vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10); | 767 | vmw_fp->tfile = ttm_object_file_init(dev_priv->tdev, 10); |
714 | if (unlikely(vmw_fp->tfile == NULL)) | 768 | if (unlikely(vmw_fp->tfile == NULL)) |
715 | goto out_no_tfile; | 769 | goto out_no_tfile; |
@@ -1102,6 +1156,7 @@ static struct drm_driver driver = { | |||
1102 | .master_set = vmw_master_set, | 1156 | .master_set = vmw_master_set, |
1103 | .master_drop = vmw_master_drop, | 1157 | .master_drop = vmw_master_drop, |
1104 | .open = vmw_driver_open, | 1158 | .open = vmw_driver_open, |
1159 | .preclose = vmw_preclose, | ||
1105 | .postclose = vmw_postclose, | 1160 | .postclose = vmw_postclose, |
1106 | .fops = &vmwgfx_driver_fops, | 1161 | .fops = &vmwgfx_driver_fops, |
1107 | .name = VMWGFX_DRIVER_NAME, | 1162 | .name = VMWGFX_DRIVER_NAME, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h index dc279706ca70..d0f2c079ee27 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_drv.h | |||
@@ -40,9 +40,9 @@ | |||
40 | #include "ttm/ttm_module.h" | 40 | #include "ttm/ttm_module.h" |
41 | #include "vmwgfx_fence.h" | 41 | #include "vmwgfx_fence.h" |
42 | 42 | ||
43 | #define VMWGFX_DRIVER_DATE "20111025" | 43 | #define VMWGFX_DRIVER_DATE "20120209" |
44 | #define VMWGFX_DRIVER_MAJOR 2 | 44 | #define VMWGFX_DRIVER_MAJOR 2 |
45 | #define VMWGFX_DRIVER_MINOR 3 | 45 | #define VMWGFX_DRIVER_MINOR 4 |
46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 | 46 | #define VMWGFX_DRIVER_PATCHLEVEL 0 |
47 | #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 | 47 | #define VMWGFX_FILE_PAGE_OFFSET 0x00100000 |
48 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) | 48 | #define VMWGFX_FIFO_STATIC_SIZE (1024*1024) |
@@ -62,6 +62,7 @@ | |||
62 | struct vmw_fpriv { | 62 | struct vmw_fpriv { |
63 | struct drm_master *locked_master; | 63 | struct drm_master *locked_master; |
64 | struct ttm_object_file *tfile; | 64 | struct ttm_object_file *tfile; |
65 | struct list_head fence_events; | ||
65 | }; | 66 | }; |
66 | 67 | ||
67 | struct vmw_dma_buffer { | 68 | struct vmw_dma_buffer { |
@@ -202,6 +203,8 @@ struct vmw_private { | |||
202 | uint32_t mmio_size; | 203 | uint32_t mmio_size; |
203 | uint32_t fb_max_width; | 204 | uint32_t fb_max_width; |
204 | uint32_t fb_max_height; | 205 | uint32_t fb_max_height; |
206 | uint32_t initial_width; | ||
207 | uint32_t initial_height; | ||
205 | __le32 __iomem *mmio_virt; | 208 | __le32 __iomem *mmio_virt; |
206 | int mmio_mtrr; | 209 | int mmio_mtrr; |
207 | uint32_t capabilities; | 210 | uint32_t capabilities; |
@@ -533,7 +536,8 @@ extern int vmw_execbuf_process(struct drm_file *file_priv, | |||
533 | uint32_t command_size, | 536 | uint32_t command_size, |
534 | uint64_t throttle_us, | 537 | uint64_t throttle_us, |
535 | struct drm_vmw_fence_rep __user | 538 | struct drm_vmw_fence_rep __user |
536 | *user_fence_rep); | 539 | *user_fence_rep, |
540 | struct vmw_fence_obj **out_fence); | ||
537 | 541 | ||
538 | extern void | 542 | extern void |
539 | vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, | 543 | vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c index 40932fbdac0f..4acced44a623 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c | |||
@@ -1109,10 +1109,11 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
1109 | void *kernel_commands, | 1109 | void *kernel_commands, |
1110 | uint32_t command_size, | 1110 | uint32_t command_size, |
1111 | uint64_t throttle_us, | 1111 | uint64_t throttle_us, |
1112 | struct drm_vmw_fence_rep __user *user_fence_rep) | 1112 | struct drm_vmw_fence_rep __user *user_fence_rep, |
1113 | struct vmw_fence_obj **out_fence) | ||
1113 | { | 1114 | { |
1114 | struct vmw_sw_context *sw_context = &dev_priv->ctx; | 1115 | struct vmw_sw_context *sw_context = &dev_priv->ctx; |
1115 | struct vmw_fence_obj *fence; | 1116 | struct vmw_fence_obj *fence = NULL; |
1116 | uint32_t handle; | 1117 | uint32_t handle; |
1117 | void *cmd; | 1118 | void *cmd; |
1118 | int ret; | 1119 | int ret; |
@@ -1208,8 +1209,13 @@ int vmw_execbuf_process(struct drm_file *file_priv, | |||
1208 | vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, | 1209 | vmw_execbuf_copy_fence_user(dev_priv, vmw_fpriv(file_priv), ret, |
1209 | user_fence_rep, fence, handle); | 1210 | user_fence_rep, fence, handle); |
1210 | 1211 | ||
1211 | if (likely(fence != NULL)) | 1212 | /* Don't unreference when handing fence out */ |
1213 | if (unlikely(out_fence != NULL)) { | ||
1214 | *out_fence = fence; | ||
1215 | fence = NULL; | ||
1216 | } else if (likely(fence != NULL)) { | ||
1212 | vmw_fence_obj_unreference(&fence); | 1217 | vmw_fence_obj_unreference(&fence); |
1218 | } | ||
1213 | 1219 | ||
1214 | mutex_unlock(&dev_priv->cmdbuf_mutex); | 1220 | mutex_unlock(&dev_priv->cmdbuf_mutex); |
1215 | return 0; | 1221 | return 0; |
@@ -1362,7 +1368,8 @@ int vmw_execbuf_ioctl(struct drm_device *dev, void *data, | |||
1362 | ret = vmw_execbuf_process(file_priv, dev_priv, | 1368 | ret = vmw_execbuf_process(file_priv, dev_priv, |
1363 | (void __user *)(unsigned long)arg->commands, | 1369 | (void __user *)(unsigned long)arg->commands, |
1364 | NULL, arg->command_size, arg->throttle_us, | 1370 | NULL, arg->command_size, arg->throttle_us, |
1365 | (void __user *)(unsigned long)arg->fence_rep); | 1371 | (void __user *)(unsigned long)arg->fence_rep, |
1372 | NULL); | ||
1366 | 1373 | ||
1367 | if (unlikely(ret != 0)) | 1374 | if (unlikely(ret != 0)) |
1368 | goto out_unlock; | 1375 | goto out_unlock; |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c index 34e51a1695b8..3c447bf317cb 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c | |||
@@ -414,10 +414,6 @@ int vmw_fb_init(struct vmw_private *vmw_priv) | |||
414 | unsigned fb_bpp, fb_depth, fb_offset, fb_pitch, fb_size; | 414 | unsigned fb_bpp, fb_depth, fb_offset, fb_pitch, fb_size; |
415 | int ret; | 415 | int ret; |
416 | 416 | ||
417 | /* XXX These shouldn't be hardcoded. */ | ||
418 | initial_width = 800; | ||
419 | initial_height = 600; | ||
420 | |||
421 | fb_bpp = 32; | 417 | fb_bpp = 32; |
422 | fb_depth = 24; | 418 | fb_depth = 24; |
423 | 419 | ||
@@ -425,8 +421,8 @@ int vmw_fb_init(struct vmw_private *vmw_priv) | |||
425 | fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); | 421 | fb_width = min(vmw_priv->fb_max_width, (unsigned)2048); |
426 | fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); | 422 | fb_height = min(vmw_priv->fb_max_height, (unsigned)2048); |
427 | 423 | ||
428 | initial_width = min(fb_width, initial_width); | 424 | initial_width = min(vmw_priv->initial_width, fb_width); |
429 | initial_height = min(fb_height, initial_height); | 425 | initial_height = min(vmw_priv->initial_height, fb_height); |
430 | 426 | ||
431 | fb_pitch = fb_width * fb_bpp / 8; | 427 | fb_pitch = fb_width * fb_bpp / 8; |
432 | fb_size = fb_pitch * fb_height; | 428 | fb_size = fb_pitch * fb_height; |
@@ -515,19 +511,7 @@ int vmw_fb_init(struct vmw_private *vmw_priv) | |||
515 | info->var.xres = initial_width; | 511 | info->var.xres = initial_width; |
516 | info->var.yres = initial_height; | 512 | info->var.yres = initial_height; |
517 | 513 | ||
518 | #if 0 | 514 | /* Use default scratch pixmap (info->pixmap.flags = FB_PIXMAP_SYSTEM) */ |
519 | info->pixmap.size = 64*1024; | ||
520 | info->pixmap.buf_align = 8; | ||
521 | info->pixmap.access_align = 32; | ||
522 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
523 | info->pixmap.scan_align = 1; | ||
524 | #else | ||
525 | info->pixmap.size = 0; | ||
526 | info->pixmap.buf_align = 8; | ||
527 | info->pixmap.access_align = 32; | ||
528 | info->pixmap.flags = FB_PIXMAP_SYSTEM; | ||
529 | info->pixmap.scan_align = 1; | ||
530 | #endif | ||
531 | 515 | ||
532 | info->apertures = alloc_apertures(1); | 516 | info->apertures = alloc_apertures(1); |
533 | if (!info->apertures) { | 517 | if (!info->apertures) { |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c index 15fb26088d68..f2fb8f15e2f1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.c | |||
@@ -69,12 +69,13 @@ struct vmw_user_fence { | |||
69 | * be assigned the current time tv_usec val when the fence signals. | 69 | * be assigned the current time tv_usec val when the fence signals. |
70 | */ | 70 | */ |
71 | struct vmw_event_fence_action { | 71 | struct vmw_event_fence_action { |
72 | struct drm_pending_event e; | ||
73 | struct vmw_fence_action action; | 72 | struct vmw_fence_action action; |
73 | struct list_head fpriv_head; | ||
74 | |||
75 | struct drm_pending_event *event; | ||
74 | struct vmw_fence_obj *fence; | 76 | struct vmw_fence_obj *fence; |
75 | struct drm_device *dev; | 77 | struct drm_device *dev; |
76 | struct kref kref; | 78 | |
77 | uint32_t size; | ||
78 | uint32_t *tv_sec; | 79 | uint32_t *tv_sec; |
79 | uint32_t *tv_usec; | 80 | uint32_t *tv_usec; |
80 | }; | 81 | }; |
@@ -784,46 +785,40 @@ int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data, | |||
784 | } | 785 | } |
785 | 786 | ||
786 | /** | 787 | /** |
787 | * vmw_event_fence_action_destroy | 788 | * vmw_event_fence_fpriv_gone - Remove references to struct drm_file objects |
788 | * | ||
789 | * @kref: The struct kref embedded in a struct vmw_event_fence_action. | ||
790 | * | ||
791 | * The vmw_event_fence_action destructor that may be called either after | ||
792 | * the fence action cleanup, or when the event is delivered. | ||
793 | * It frees both the vmw_event_fence_action struct and the actual | ||
794 | * event structure copied to user-space. | ||
795 | */ | ||
796 | static void vmw_event_fence_action_destroy(struct kref *kref) | ||
797 | { | ||
798 | struct vmw_event_fence_action *eaction = | ||
799 | container_of(kref, struct vmw_event_fence_action, kref); | ||
800 | struct ttm_mem_global *mem_glob = | ||
801 | vmw_mem_glob(vmw_priv(eaction->dev)); | ||
802 | uint32_t size = eaction->size; | ||
803 | |||
804 | kfree(eaction->e.event); | ||
805 | kfree(eaction); | ||
806 | ttm_mem_global_free(mem_glob, size); | ||
807 | } | ||
808 | |||
809 | |||
810 | /** | ||
811 | * vmw_event_fence_action_delivered | ||
812 | * | 789 | * |
813 | * @e: The struct drm_pending_event embedded in a struct | 790 | * @fman: Pointer to a struct vmw_fence_manager |
814 | * vmw_event_fence_action. | 791 | * @event_list: Pointer to linked list of struct vmw_event_fence_action objects |
792 | * with pointers to a struct drm_file object about to be closed. | ||
815 | * | 793 | * |
816 | * The struct drm_pending_event destructor that is called by drm | 794 | * This function removes all pending fence events with references to a |
817 | * once the event is delivered. Since we don't know whether this function | 795 | * specific struct drm_file object about to be closed. The caller is required |
818 | * will be called before or after the fence action destructor, we | 796 | * to pass a list of all struct vmw_event_fence_action objects with such |
819 | * free a refcount and destroy if it becomes zero. | 797 | * events attached. This function is typically called before the |
798 | * struct drm_file object's event management is taken down. | ||
820 | */ | 799 | */ |
821 | static void vmw_event_fence_action_delivered(struct drm_pending_event *e) | 800 | void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman, |
801 | struct list_head *event_list) | ||
822 | { | 802 | { |
823 | struct vmw_event_fence_action *eaction = | 803 | struct vmw_event_fence_action *eaction; |
824 | container_of(e, struct vmw_event_fence_action, e); | 804 | struct drm_pending_event *event; |
805 | unsigned long irq_flags; | ||
825 | 806 | ||
826 | kref_put(&eaction->kref, vmw_event_fence_action_destroy); | 807 | while (1) { |
808 | spin_lock_irqsave(&fman->lock, irq_flags); | ||
809 | if (list_empty(event_list)) | ||
810 | goto out_unlock; | ||
811 | eaction = list_first_entry(event_list, | ||
812 | struct vmw_event_fence_action, | ||
813 | fpriv_head); | ||
814 | list_del_init(&eaction->fpriv_head); | ||
815 | event = eaction->event; | ||
816 | eaction->event = NULL; | ||
817 | spin_unlock_irqrestore(&fman->lock, irq_flags); | ||
818 | event->destroy(event); | ||
819 | } | ||
820 | out_unlock: | ||
821 | spin_unlock_irqrestore(&fman->lock, irq_flags); | ||
827 | } | 822 | } |
828 | 823 | ||
829 | 824 | ||
@@ -836,18 +831,21 @@ static void vmw_event_fence_action_delivered(struct drm_pending_event *e) | |||
836 | * This function is called when the seqno of the fence where @action is | 831 | * This function is called when the seqno of the fence where @action is |
837 | * attached has passed. It queues the event on the submitter's event list. | 832 | * attached has passed. It queues the event on the submitter's event list. |
838 | * This function is always called from atomic context, and may be called | 833 | * This function is always called from atomic context, and may be called |
839 | * from irq context. It ups a refcount reflecting that we now have two | 834 | * from irq context. |
840 | * destructors. | ||
841 | */ | 835 | */ |
842 | static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) | 836 | static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) |
843 | { | 837 | { |
844 | struct vmw_event_fence_action *eaction = | 838 | struct vmw_event_fence_action *eaction = |
845 | container_of(action, struct vmw_event_fence_action, action); | 839 | container_of(action, struct vmw_event_fence_action, action); |
846 | struct drm_device *dev = eaction->dev; | 840 | struct drm_device *dev = eaction->dev; |
847 | struct drm_file *file_priv = eaction->e.file_priv; | 841 | struct drm_pending_event *event = eaction->event; |
842 | struct drm_file *file_priv; | ||
848 | unsigned long irq_flags; | 843 | unsigned long irq_flags; |
849 | 844 | ||
850 | kref_get(&eaction->kref); | 845 | if (unlikely(event == NULL)) |
846 | return; | ||
847 | |||
848 | file_priv = event->file_priv; | ||
851 | spin_lock_irqsave(&dev->event_lock, irq_flags); | 849 | spin_lock_irqsave(&dev->event_lock, irq_flags); |
852 | 850 | ||
853 | if (likely(eaction->tv_sec != NULL)) { | 851 | if (likely(eaction->tv_sec != NULL)) { |
@@ -858,7 +856,9 @@ static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) | |||
858 | *eaction->tv_usec = tv.tv_usec; | 856 | *eaction->tv_usec = tv.tv_usec; |
859 | } | 857 | } |
860 | 858 | ||
861 | list_add_tail(&eaction->e.link, &file_priv->event_list); | 859 | list_del_init(&eaction->fpriv_head); |
860 | list_add_tail(&eaction->event->link, &file_priv->event_list); | ||
861 | eaction->event = NULL; | ||
862 | wake_up_all(&file_priv->event_wait); | 862 | wake_up_all(&file_priv->event_wait); |
863 | spin_unlock_irqrestore(&dev->event_lock, irq_flags); | 863 | spin_unlock_irqrestore(&dev->event_lock, irq_flags); |
864 | } | 864 | } |
@@ -876,9 +876,15 @@ static void vmw_event_fence_action_cleanup(struct vmw_fence_action *action) | |||
876 | { | 876 | { |
877 | struct vmw_event_fence_action *eaction = | 877 | struct vmw_event_fence_action *eaction = |
878 | container_of(action, struct vmw_event_fence_action, action); | 878 | container_of(action, struct vmw_event_fence_action, action); |
879 | struct vmw_fence_manager *fman = eaction->fence->fman; | ||
880 | unsigned long irq_flags; | ||
881 | |||
882 | spin_lock_irqsave(&fman->lock, irq_flags); | ||
883 | list_del(&eaction->fpriv_head); | ||
884 | spin_unlock_irqrestore(&fman->lock, irq_flags); | ||
879 | 885 | ||
880 | vmw_fence_obj_unreference(&eaction->fence); | 886 | vmw_fence_obj_unreference(&eaction->fence); |
881 | kref_put(&eaction->kref, vmw_event_fence_action_destroy); | 887 | kfree(eaction); |
882 | } | 888 | } |
883 | 889 | ||
884 | 890 | ||
@@ -946,39 +952,23 @@ void vmw_fence_obj_add_action(struct vmw_fence_obj *fence, | |||
946 | * an error code, the caller needs to free that object. | 952 | * an error code, the caller needs to free that object. |
947 | */ | 953 | */ |
948 | 954 | ||
949 | int vmw_event_fence_action_create(struct drm_file *file_priv, | 955 | int vmw_event_fence_action_queue(struct drm_file *file_priv, |
950 | struct vmw_fence_obj *fence, | 956 | struct vmw_fence_obj *fence, |
951 | struct drm_event *event, | 957 | struct drm_pending_event *event, |
952 | uint32_t *tv_sec, | 958 | uint32_t *tv_sec, |
953 | uint32_t *tv_usec, | 959 | uint32_t *tv_usec, |
954 | bool interruptible) | 960 | bool interruptible) |
955 | { | 961 | { |
956 | struct vmw_event_fence_action *eaction; | 962 | struct vmw_event_fence_action *eaction; |
957 | struct ttm_mem_global *mem_glob = | ||
958 | vmw_mem_glob(fence->fman->dev_priv); | ||
959 | struct vmw_fence_manager *fman = fence->fman; | 963 | struct vmw_fence_manager *fman = fence->fman; |
960 | uint32_t size = fman->event_fence_action_size + | 964 | struct vmw_fpriv *vmw_fp = vmw_fpriv(file_priv); |
961 | ttm_round_pot(event->length); | 965 | unsigned long irq_flags; |
962 | int ret; | ||
963 | |||
964 | /* | ||
965 | * Account for internal structure size as well as the | ||
966 | * event size itself. | ||
967 | */ | ||
968 | |||
969 | ret = ttm_mem_global_alloc(mem_glob, size, false, interruptible); | ||
970 | if (unlikely(ret != 0)) | ||
971 | return ret; | ||
972 | 966 | ||
973 | eaction = kzalloc(sizeof(*eaction), GFP_KERNEL); | 967 | eaction = kzalloc(sizeof(*eaction), GFP_KERNEL); |
974 | if (unlikely(eaction == NULL)) { | 968 | if (unlikely(eaction == NULL)) |
975 | ttm_mem_global_free(mem_glob, size); | ||
976 | return -ENOMEM; | 969 | return -ENOMEM; |
977 | } | ||
978 | 970 | ||
979 | eaction->e.event = event; | 971 | eaction->event = event; |
980 | eaction->e.file_priv = file_priv; | ||
981 | eaction->e.destroy = vmw_event_fence_action_delivered; | ||
982 | 972 | ||
983 | eaction->action.seq_passed = vmw_event_fence_action_seq_passed; | 973 | eaction->action.seq_passed = vmw_event_fence_action_seq_passed; |
984 | eaction->action.cleanup = vmw_event_fence_action_cleanup; | 974 | eaction->action.cleanup = vmw_event_fence_action_cleanup; |
@@ -986,16 +976,89 @@ int vmw_event_fence_action_create(struct drm_file *file_priv, | |||
986 | 976 | ||
987 | eaction->fence = vmw_fence_obj_reference(fence); | 977 | eaction->fence = vmw_fence_obj_reference(fence); |
988 | eaction->dev = fman->dev_priv->dev; | 978 | eaction->dev = fman->dev_priv->dev; |
989 | eaction->size = size; | ||
990 | eaction->tv_sec = tv_sec; | 979 | eaction->tv_sec = tv_sec; |
991 | eaction->tv_usec = tv_usec; | 980 | eaction->tv_usec = tv_usec; |
992 | 981 | ||
993 | kref_init(&eaction->kref); | 982 | spin_lock_irqsave(&fman->lock, irq_flags); |
983 | list_add_tail(&eaction->fpriv_head, &vmw_fp->fence_events); | ||
984 | spin_unlock_irqrestore(&fman->lock, irq_flags); | ||
985 | |||
994 | vmw_fence_obj_add_action(fence, &eaction->action); | 986 | vmw_fence_obj_add_action(fence, &eaction->action); |
995 | 987 | ||
996 | return 0; | 988 | return 0; |
997 | } | 989 | } |
998 | 990 | ||
991 | struct vmw_event_fence_pending { | ||
992 | struct drm_pending_event base; | ||
993 | struct drm_vmw_event_fence event; | ||
994 | }; | ||
995 | |||
996 | int vmw_event_fence_action_create(struct drm_file *file_priv, | ||
997 | struct vmw_fence_obj *fence, | ||
998 | uint32_t flags, | ||
999 | uint64_t user_data, | ||
1000 | bool interruptible) | ||
1001 | { | ||
1002 | struct vmw_event_fence_pending *event; | ||
1003 | struct drm_device *dev = fence->fman->dev_priv->dev; | ||
1004 | unsigned long irq_flags; | ||
1005 | int ret; | ||
1006 | |||
1007 | spin_lock_irqsave(&dev->event_lock, irq_flags); | ||
1008 | |||
1009 | ret = (file_priv->event_space < sizeof(event->event)) ? -EBUSY : 0; | ||
1010 | if (likely(ret == 0)) | ||
1011 | file_priv->event_space -= sizeof(event->event); | ||
1012 | |||
1013 | spin_unlock_irqrestore(&dev->event_lock, irq_flags); | ||
1014 | |||
1015 | if (unlikely(ret != 0)) { | ||
1016 | DRM_ERROR("Failed to allocate event space for this file.\n"); | ||
1017 | goto out_no_space; | ||
1018 | } | ||
1019 | |||
1020 | |||
1021 | event = kzalloc(sizeof(event->event), GFP_KERNEL); | ||
1022 | if (unlikely(event == NULL)) { | ||
1023 | DRM_ERROR("Failed to allocate an event.\n"); | ||
1024 | ret = -ENOMEM; | ||
1025 | goto out_no_event; | ||
1026 | } | ||
1027 | |||
1028 | event->event.base.type = DRM_VMW_EVENT_FENCE_SIGNALED; | ||
1029 | event->event.base.length = sizeof(*event); | ||
1030 | event->event.user_data = user_data; | ||
1031 | |||
1032 | event->base.event = &event->event.base; | ||
1033 | event->base.file_priv = file_priv; | ||
1034 | event->base.destroy = (void (*) (struct drm_pending_event *)) kfree; | ||
1035 | |||
1036 | |||
1037 | if (flags & DRM_VMW_FE_FLAG_REQ_TIME) | ||
1038 | ret = vmw_event_fence_action_queue(file_priv, fence, | ||
1039 | &event->base, | ||
1040 | &event->event.tv_sec, | ||
1041 | &event->event.tv_usec, | ||
1042 | interruptible); | ||
1043 | else | ||
1044 | ret = vmw_event_fence_action_queue(file_priv, fence, | ||
1045 | &event->base, | ||
1046 | NULL, | ||
1047 | NULL, | ||
1048 | interruptible); | ||
1049 | if (ret != 0) | ||
1050 | goto out_no_queue; | ||
1051 | |||
1052 | out_no_queue: | ||
1053 | event->base.destroy(&event->base); | ||
1054 | out_no_event: | ||
1055 | spin_lock_irqsave(&dev->event_lock, irq_flags); | ||
1056 | file_priv->event_space += sizeof(*event); | ||
1057 | spin_unlock_irqrestore(&dev->event_lock, irq_flags); | ||
1058 | out_no_space: | ||
1059 | return ret; | ||
1060 | } | ||
1061 | |||
999 | int vmw_fence_event_ioctl(struct drm_device *dev, void *data, | 1062 | int vmw_fence_event_ioctl(struct drm_device *dev, void *data, |
1000 | struct drm_file *file_priv) | 1063 | struct drm_file *file_priv) |
1001 | { | 1064 | { |
@@ -1008,8 +1071,6 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, | |||
1008 | (struct drm_vmw_fence_rep __user *)(unsigned long) | 1071 | (struct drm_vmw_fence_rep __user *)(unsigned long) |
1009 | arg->fence_rep; | 1072 | arg->fence_rep; |
1010 | uint32_t handle; | 1073 | uint32_t handle; |
1011 | unsigned long irq_flags; | ||
1012 | struct drm_vmw_event_fence *event; | ||
1013 | int ret; | 1074 | int ret; |
1014 | 1075 | ||
1015 | /* | 1076 | /* |
@@ -1062,59 +1123,28 @@ int vmw_fence_event_ioctl(struct drm_device *dev, void *data, | |||
1062 | 1123 | ||
1063 | BUG_ON(fence == NULL); | 1124 | BUG_ON(fence == NULL); |
1064 | 1125 | ||
1065 | spin_lock_irqsave(&dev->event_lock, irq_flags); | ||
1066 | |||
1067 | ret = (file_priv->event_space < sizeof(*event)) ? -EBUSY : 0; | ||
1068 | if (likely(ret == 0)) | ||
1069 | file_priv->event_space -= sizeof(*event); | ||
1070 | |||
1071 | spin_unlock_irqrestore(&dev->event_lock, irq_flags); | ||
1072 | |||
1073 | if (unlikely(ret != 0)) { | ||
1074 | DRM_ERROR("Failed to allocate event space for this file.\n"); | ||
1075 | goto out_no_event_space; | ||
1076 | } | ||
1077 | |||
1078 | event = kzalloc(sizeof(*event), GFP_KERNEL); | ||
1079 | if (unlikely(event == NULL)) { | ||
1080 | DRM_ERROR("Failed to allocate an event.\n"); | ||
1081 | goto out_no_event; | ||
1082 | } | ||
1083 | |||
1084 | event->base.type = DRM_VMW_EVENT_FENCE_SIGNALED; | ||
1085 | event->base.length = sizeof(*event); | ||
1086 | event->user_data = arg->user_data; | ||
1087 | |||
1088 | if (arg->flags & DRM_VMW_FE_FLAG_REQ_TIME) | 1126 | if (arg->flags & DRM_VMW_FE_FLAG_REQ_TIME) |
1089 | ret = vmw_event_fence_action_create(file_priv, fence, | 1127 | ret = vmw_event_fence_action_create(file_priv, fence, |
1090 | &event->base, | 1128 | arg->flags, |
1091 | &event->tv_sec, | 1129 | arg->user_data, |
1092 | &event->tv_usec, | ||
1093 | true); | 1130 | true); |
1094 | else | 1131 | else |
1095 | ret = vmw_event_fence_action_create(file_priv, fence, | 1132 | ret = vmw_event_fence_action_create(file_priv, fence, |
1096 | &event->base, | 1133 | arg->flags, |
1097 | NULL, | 1134 | arg->user_data, |
1098 | NULL, | ||
1099 | true); | 1135 | true); |
1100 | 1136 | ||
1101 | if (unlikely(ret != 0)) { | 1137 | if (unlikely(ret != 0)) { |
1102 | if (ret != -ERESTARTSYS) | 1138 | if (ret != -ERESTARTSYS) |
1103 | DRM_ERROR("Failed to attach event to fence.\n"); | 1139 | DRM_ERROR("Failed to attach event to fence.\n"); |
1104 | goto out_no_attach; | 1140 | goto out_no_create; |
1105 | } | 1141 | } |
1106 | 1142 | ||
1107 | vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence, | 1143 | vmw_execbuf_copy_fence_user(dev_priv, vmw_fp, 0, user_fence_rep, fence, |
1108 | handle); | 1144 | handle); |
1109 | vmw_fence_obj_unreference(&fence); | 1145 | vmw_fence_obj_unreference(&fence); |
1110 | return 0; | 1146 | return 0; |
1111 | out_no_attach: | 1147 | out_no_create: |
1112 | kfree(event); | ||
1113 | out_no_event: | ||
1114 | spin_lock_irqsave(&dev->event_lock, irq_flags); | ||
1115 | file_priv->event_space += sizeof(*event); | ||
1116 | spin_unlock_irqrestore(&dev->event_lock, irq_flags); | ||
1117 | out_no_event_space: | ||
1118 | if (user_fence_rep != NULL) | 1148 | if (user_fence_rep != NULL) |
1119 | ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, | 1149 | ttm_ref_object_base_unref(vmw_fpriv(file_priv)->tfile, |
1120 | handle, TTM_REF_USAGE); | 1150 | handle, TTM_REF_USAGE); |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h index 0854a2096b55..faf2e7873860 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_fence.h | |||
@@ -109,5 +109,12 @@ extern int vmw_fence_obj_unref_ioctl(struct drm_device *dev, void *data, | |||
109 | struct drm_file *file_priv); | 109 | struct drm_file *file_priv); |
110 | extern int vmw_fence_event_ioctl(struct drm_device *dev, void *data, | 110 | extern int vmw_fence_event_ioctl(struct drm_device *dev, void *data, |
111 | struct drm_file *file_priv); | 111 | struct drm_file *file_priv); |
112 | 112 | extern void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman, | |
113 | struct list_head *event_list); | ||
114 | extern int vmw_event_fence_action_queue(struct drm_file *filee_priv, | ||
115 | struct vmw_fence_obj *fence, | ||
116 | struct drm_pending_event *event, | ||
117 | uint32_t *tv_sec, | ||
118 | uint32_t *tv_usec, | ||
119 | bool interruptible); | ||
113 | #endif /* _VMWGFX_FENCE_H_ */ | 120 | #endif /* _VMWGFX_FENCE_H_ */ |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c index b66ef0e3cde1..2286d47e5022 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.c | |||
@@ -422,7 +422,8 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
422 | struct vmw_framebuffer *framebuffer, | 422 | struct vmw_framebuffer *framebuffer, |
423 | unsigned flags, unsigned color, | 423 | unsigned flags, unsigned color, |
424 | struct drm_clip_rect *clips, | 424 | struct drm_clip_rect *clips, |
425 | unsigned num_clips, int inc) | 425 | unsigned num_clips, int inc, |
426 | struct vmw_fence_obj **out_fence) | ||
426 | { | 427 | { |
427 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; | 428 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; |
428 | struct drm_clip_rect *clips_ptr; | 429 | struct drm_clip_rect *clips_ptr; |
@@ -542,12 +543,15 @@ static int do_surface_dirty_sou(struct vmw_private *dev_priv, | |||
542 | if (num == 0) | 543 | if (num == 0) |
543 | continue; | 544 | continue; |
544 | 545 | ||
546 | /* only return the last fence */ | ||
547 | if (out_fence && *out_fence) | ||
548 | vmw_fence_obj_unreference(out_fence); | ||
545 | 549 | ||
546 | /* recalculate package length */ | 550 | /* recalculate package length */ |
547 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num; | 551 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num; |
548 | cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); | 552 | cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); |
549 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, | 553 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, |
550 | fifo_size, 0, NULL); | 554 | fifo_size, 0, NULL, out_fence); |
551 | 555 | ||
552 | if (unlikely(ret != 0)) | 556 | if (unlikely(ret != 0)) |
553 | break; | 557 | break; |
@@ -598,7 +602,7 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, | |||
598 | 602 | ||
599 | ret = do_surface_dirty_sou(dev_priv, file_priv, &vfbs->base, | 603 | ret = do_surface_dirty_sou(dev_priv, file_priv, &vfbs->base, |
600 | flags, color, | 604 | flags, color, |
601 | clips, num_clips, inc); | 605 | clips, num_clips, inc, NULL); |
602 | 606 | ||
603 | ttm_read_unlock(&vmaster->lock); | 607 | ttm_read_unlock(&vmaster->lock); |
604 | return 0; | 608 | return 0; |
@@ -809,7 +813,7 @@ static int do_dmabuf_define_gmrfb(struct drm_file *file_priv, | |||
809 | cmd->body.ptr.offset = 0; | 813 | cmd->body.ptr.offset = 0; |
810 | 814 | ||
811 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, | 815 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, |
812 | fifo_size, 0, NULL); | 816 | fifo_size, 0, NULL, NULL); |
813 | 817 | ||
814 | kfree(cmd); | 818 | kfree(cmd); |
815 | 819 | ||
@@ -821,7 +825,8 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, | |||
821 | struct vmw_framebuffer *framebuffer, | 825 | struct vmw_framebuffer *framebuffer, |
822 | unsigned flags, unsigned color, | 826 | unsigned flags, unsigned color, |
823 | struct drm_clip_rect *clips, | 827 | struct drm_clip_rect *clips, |
824 | unsigned num_clips, int increment) | 828 | unsigned num_clips, int increment, |
829 | struct vmw_fence_obj **out_fence) | ||
825 | { | 830 | { |
826 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; | 831 | struct vmw_display_unit *units[VMWGFX_NUM_DISPLAY_UNITS]; |
827 | struct drm_clip_rect *clips_ptr; | 832 | struct drm_clip_rect *clips_ptr; |
@@ -894,9 +899,13 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, | |||
894 | if (hit_num == 0) | 899 | if (hit_num == 0) |
895 | continue; | 900 | continue; |
896 | 901 | ||
902 | /* only return the last fence */ | ||
903 | if (out_fence && *out_fence) | ||
904 | vmw_fence_obj_unreference(out_fence); | ||
905 | |||
897 | fifo_size = sizeof(*blits) * hit_num; | 906 | fifo_size = sizeof(*blits) * hit_num; |
898 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, blits, | 907 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, blits, |
899 | fifo_size, 0, NULL); | 908 | fifo_size, 0, NULL, out_fence); |
900 | 909 | ||
901 | if (unlikely(ret != 0)) | 910 | if (unlikely(ret != 0)) |
902 | break; | 911 | break; |
@@ -942,7 +951,7 @@ int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, | |||
942 | } else { | 951 | } else { |
943 | ret = do_dmabuf_dirty_sou(file_priv, dev_priv, &vfbd->base, | 952 | ret = do_dmabuf_dirty_sou(file_priv, dev_priv, &vfbd->base, |
944 | flags, color, | 953 | flags, color, |
945 | clips, num_clips, increment); | 954 | clips, num_clips, increment, NULL); |
946 | } | 955 | } |
947 | 956 | ||
948 | ttm_read_unlock(&vmaster->lock); | 957 | ttm_read_unlock(&vmaster->lock); |
@@ -1296,7 +1305,7 @@ int vmw_kms_present(struct vmw_private *dev_priv, | |||
1296 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num; | 1305 | fifo_size = sizeof(*cmd) + sizeof(SVGASignedRect) * num; |
1297 | cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); | 1306 | cmd->header.size = cpu_to_le32(fifo_size - sizeof(cmd->header)); |
1298 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, | 1307 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, |
1299 | fifo_size, 0, NULL); | 1308 | fifo_size, 0, NULL, NULL); |
1300 | 1309 | ||
1301 | if (unlikely(ret != 0)) | 1310 | if (unlikely(ret != 0)) |
1302 | break; | 1311 | break; |
@@ -1409,7 +1418,7 @@ int vmw_kms_readback(struct vmw_private *dev_priv, | |||
1409 | fifo_size = sizeof(*cmd) + sizeof(*blits) * blits_pos; | 1418 | fifo_size = sizeof(*cmd) + sizeof(*blits) * blits_pos; |
1410 | 1419 | ||
1411 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size, | 1420 | ret = vmw_execbuf_process(file_priv, dev_priv, NULL, cmd, fifo_size, |
1412 | 0, user_fence_rep); | 1421 | 0, user_fence_rep, NULL); |
1413 | 1422 | ||
1414 | kfree(cmd); | 1423 | kfree(cmd); |
1415 | 1424 | ||
@@ -1672,6 +1681,70 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, | |||
1672 | return 0; | 1681 | return 0; |
1673 | } | 1682 | } |
1674 | 1683 | ||
1684 | int vmw_du_page_flip(struct drm_crtc *crtc, | ||
1685 | struct drm_framebuffer *fb, | ||
1686 | struct drm_pending_vblank_event *event) | ||
1687 | { | ||
1688 | struct vmw_private *dev_priv = vmw_priv(crtc->dev); | ||
1689 | struct drm_framebuffer *old_fb = crtc->fb; | ||
1690 | struct vmw_framebuffer *vfb = vmw_framebuffer_to_vfb(fb); | ||
1691 | struct drm_file *file_priv = event->base.file_priv; | ||
1692 | struct vmw_fence_obj *fence = NULL; | ||
1693 | struct drm_clip_rect clips; | ||
1694 | int ret; | ||
1695 | |||
1696 | /* require ScreenObject support for page flipping */ | ||
1697 | if (!dev_priv->sou_priv) | ||
1698 | return -ENOSYS; | ||
1699 | |||
1700 | if (!vmw_kms_screen_object_flippable(dev_priv, crtc)) | ||
1701 | return -EINVAL; | ||
1702 | |||
1703 | crtc->fb = fb; | ||
1704 | |||
1705 | /* do a full screen dirty update */ | ||
1706 | clips.x1 = clips.y1 = 0; | ||
1707 | clips.x2 = fb->width; | ||
1708 | clips.y2 = fb->height; | ||
1709 | |||
1710 | if (vfb->dmabuf) | ||
1711 | ret = do_dmabuf_dirty_sou(file_priv, dev_priv, vfb, | ||
1712 | 0, 0, &clips, 1, 1, &fence); | ||
1713 | else | ||
1714 | ret = do_surface_dirty_sou(dev_priv, file_priv, vfb, | ||
1715 | 0, 0, &clips, 1, 1, &fence); | ||
1716 | |||
1717 | |||
1718 | if (ret != 0) | ||
1719 | goto out_no_fence; | ||
1720 | if (!fence) { | ||
1721 | ret = -EINVAL; | ||
1722 | goto out_no_fence; | ||
1723 | } | ||
1724 | |||
1725 | ret = vmw_event_fence_action_queue(file_priv, fence, | ||
1726 | &event->base, | ||
1727 | &event->event.tv_sec, | ||
1728 | &event->event.tv_usec, | ||
1729 | true); | ||
1730 | |||
1731 | /* | ||
1732 | * No need to hold on to this now. The only cleanup | ||
1733 | * we need to do if we fail is unref the fence. | ||
1734 | */ | ||
1735 | vmw_fence_obj_unreference(&fence); | ||
1736 | |||
1737 | if (vmw_crtc_to_du(crtc)->is_implicit) | ||
1738 | vmw_kms_screen_object_update_implicit_fb(dev_priv, crtc); | ||
1739 | |||
1740 | return ret; | ||
1741 | |||
1742 | out_no_fence: | ||
1743 | crtc->fb = old_fb; | ||
1744 | return ret; | ||
1745 | } | ||
1746 | |||
1747 | |||
1675 | void vmw_du_crtc_save(struct drm_crtc *crtc) | 1748 | void vmw_du_crtc_save(struct drm_crtc *crtc) |
1676 | { | 1749 | { |
1677 | } | 1750 | } |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h index a4f7f034996a..8184bc5b1730 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_kms.h | |||
@@ -121,6 +121,9 @@ struct vmw_display_unit { | |||
121 | * Shared display unit functions - vmwgfx_kms.c | 121 | * Shared display unit functions - vmwgfx_kms.c |
122 | */ | 122 | */ |
123 | void vmw_display_unit_cleanup(struct vmw_display_unit *du); | 123 | void vmw_display_unit_cleanup(struct vmw_display_unit *du); |
124 | int vmw_du_page_flip(struct drm_crtc *crtc, | ||
125 | struct drm_framebuffer *fb, | ||
126 | struct drm_pending_vblank_event *event); | ||
124 | void vmw_du_crtc_save(struct drm_crtc *crtc); | 127 | void vmw_du_crtc_save(struct drm_crtc *crtc); |
125 | void vmw_du_crtc_restore(struct drm_crtc *crtc); | 128 | void vmw_du_crtc_restore(struct drm_crtc *crtc); |
126 | void vmw_du_crtc_gamma_set(struct drm_crtc *crtc, | 129 | void vmw_du_crtc_gamma_set(struct drm_crtc *crtc, |
@@ -154,5 +157,10 @@ int vmw_kms_init_screen_object_display(struct vmw_private *dev_priv); | |||
154 | int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv); | 157 | int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv); |
155 | int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num, | 158 | int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num, |
156 | struct drm_vmw_rect *rects); | 159 | struct drm_vmw_rect *rects); |
160 | bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv, | ||
161 | struct drm_crtc *crtc); | ||
162 | void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv, | ||
163 | struct drm_crtc *crtc); | ||
164 | |||
157 | 165 | ||
158 | #endif | 166 | #endif |
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c index f77b184be807..070fb239c5af 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c | |||
@@ -354,8 +354,8 @@ static int vmw_ldu_init(struct vmw_private *dev_priv, unsigned unit) | |||
354 | INIT_LIST_HEAD(&ldu->active); | 354 | INIT_LIST_HEAD(&ldu->active); |
355 | 355 | ||
356 | ldu->base.pref_active = (unit == 0); | 356 | ldu->base.pref_active = (unit == 0); |
357 | ldu->base.pref_width = 800; | 357 | ldu->base.pref_width = dev_priv->initial_width; |
358 | ldu->base.pref_height = 600; | 358 | ldu->base.pref_height = dev_priv->initial_height; |
359 | ldu->base.pref_mode = NULL; | 359 | ldu->base.pref_mode = NULL; |
360 | ldu->base.is_implicit = true; | 360 | ldu->base.is_implicit = true; |
361 | 361 | ||
diff --git a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c index 4defdcf1c72e..6deaf2f8bab1 100644 --- a/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c | |||
@@ -394,6 +394,7 @@ static struct drm_crtc_funcs vmw_screen_object_crtc_funcs = { | |||
394 | .gamma_set = vmw_du_crtc_gamma_set, | 394 | .gamma_set = vmw_du_crtc_gamma_set, |
395 | .destroy = vmw_sou_crtc_destroy, | 395 | .destroy = vmw_sou_crtc_destroy, |
396 | .set_config = vmw_sou_crtc_set_config, | 396 | .set_config = vmw_sou_crtc_set_config, |
397 | .page_flip = vmw_du_page_flip, | ||
397 | }; | 398 | }; |
398 | 399 | ||
399 | /* | 400 | /* |
@@ -448,8 +449,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) | |||
448 | sou->active_implicit = false; | 449 | sou->active_implicit = false; |
449 | 450 | ||
450 | sou->base.pref_active = (unit == 0); | 451 | sou->base.pref_active = (unit == 0); |
451 | sou->base.pref_width = 800; | 452 | sou->base.pref_width = dev_priv->initial_width; |
452 | sou->base.pref_height = 600; | 453 | sou->base.pref_height = dev_priv->initial_height; |
453 | sou->base.pref_mode = NULL; | 454 | sou->base.pref_mode = NULL; |
454 | sou->base.is_implicit = true; | 455 | sou->base.is_implicit = true; |
455 | 456 | ||
@@ -535,3 +536,36 @@ int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv) | |||
535 | 536 | ||
536 | return 0; | 537 | return 0; |
537 | } | 538 | } |
539 | |||
540 | /** | ||
541 | * Returns if this unit can be page flipped. | ||
542 | * Must be called with the mode_config mutex held. | ||
543 | */ | ||
544 | bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv, | ||
545 | struct drm_crtc *crtc) | ||
546 | { | ||
547 | struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc); | ||
548 | |||
549 | if (!sou->base.is_implicit) | ||
550 | return true; | ||
551 | |||
552 | if (dev_priv->sou_priv->num_implicit != 1) | ||
553 | return false; | ||
554 | |||
555 | return true; | ||
556 | } | ||
557 | |||
558 | /** | ||
559 | * Update the implicit fb to the current fb of this crtc. | ||
560 | * Must be called with the mode_config mutex held. | ||
561 | */ | ||
562 | void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv, | ||
563 | struct drm_crtc *crtc) | ||
564 | { | ||
565 | struct vmw_screen_object_unit *sou = vmw_crtc_to_sou(crtc); | ||
566 | |||
567 | BUG_ON(!sou->base.is_implicit); | ||
568 | |||
569 | dev_priv->sou_priv->implicit_fb = | ||
570 | vmw_framebuffer_to_vfb(sou->base.crtc.fb); | ||
571 | } | ||