aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu
diff options
context:
space:
mode:
authorDaniel Vetter <daniel.vetter@ffwll.ch>2012-02-23 08:54:20 -0500
committerDaniel Vetter <daniel.vetter@ffwll.ch>2012-02-23 08:56:11 -0500
commitff5f4b0585620e5c158ecaad84d91c5bf3c5d0a1 (patch)
tree18867fdd805f1beefd3592bca76f4794bdc094b8 /drivers/gpu
parentde67cba65944f26c0f147035bd62e30c5f456b96 (diff)
parent019d96cb55ade38a4b4a52bba0304e8cd681f30a (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')
-rw-r--r--drivers/gpu/drm/drm_crtc.c201
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c12
-rw-r--r--drivers/gpu/drm/drm_drv.c12
-rw-r--r--drivers/gpu/drm/drm_edid.c7
-rw-r--r--drivers/gpu/drm/drm_fb_helper.c88
-rw-r--r--drivers/gpu/drm/drm_ioctl.c6
-rw-r--r--drivers/gpu/drm/drm_modes.c2
-rw-r--r--drivers/gpu/drm/drm_pci.c2
-rw-r--r--drivers/gpu/drm/exynos/exynos_drm_fbdev.c28
-rw-r--r--drivers/gpu/drm/gma500/framebuffer.c11
-rw-r--r--drivers/gpu/drm/gma500/intel_gmbus.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_drv.c2
-rw-r--r--drivers/gpu/drm/gma500/psb_intel_sdvo.c28
-rw-r--r--drivers/gpu/drm/i2c/ch7006_drv.c5
-rw-r--r--drivers/gpu/drm/i810/i810_dma.c2
-rw-r--r--drivers/gpu/drm/i915/i915_dma.c2
-rw-r--r--drivers/gpu/drm/i915/intel_display.c3
-rw-r--r--drivers/gpu/drm/i915/intel_fb.c6
-rw-r--r--drivers/gpu/drm/i915/intel_i2c.c4
-rw-r--r--drivers/gpu/drm/i915/intel_modes.c31
-rw-r--r--drivers/gpu/drm/i915/intel_sdvo.c30
-rw-r--r--drivers/gpu/drm/mga/mga_dma.c2
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_display.c20
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_fbcon.c6
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_state.c2
-rw-r--r--drivers/gpu/drm/r128/r128_drv.c1
-rw-r--r--drivers/gpu/drm/radeon/Makefile2
-rw-r--r--drivers/gpu/drm/radeon/atombios_crtc.c20
-rw-r--r--drivers/gpu/drm/radeon/atombios_i2c.c139
-rw-r--r--drivers/gpu/drm/radeon/evergreen.c31
-rw-r--r--drivers/gpu/drm/radeon/evergreen_blit_kms.c12
-rw-r--r--drivers/gpu/drm/radeon/evergreen_cs.c958
-rw-r--r--drivers/gpu/drm/radeon/evergreend.h377
-rw-r--r--drivers/gpu/drm/radeon/r100.c58
-rw-r--r--drivers/gpu/drm/radeon/r200.c29
-rw-r--r--drivers/gpu/drm/radeon/r600_blit_kms.c15
-rw-r--r--drivers/gpu/drm/radeon/r600_cs.c282
-rw-r--r--drivers/gpu/drm/radeon/r600d.h20
-rw-r--r--drivers/gpu/drm/radeon/radeon.h13
-rw-r--r--drivers/gpu/drm/radeon/radeon_benchmark.c12
-rw-r--r--drivers/gpu/drm/radeon/radeon_blit_common.h44
-rw-r--r--drivers/gpu/drm/radeon/radeon_cp.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c73
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c5
-rw-r--r--drivers/gpu/drm/radeon/radeon_fb.c6
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c27
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_object.c46
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/cayman11
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/evergreen11
-rw-r--r--drivers/gpu/drm/radeon/reg_srcs/r60019
-rw-r--r--drivers/gpu/drm/sis/sis_drv.c2
-rw-r--r--drivers/gpu/drm/via/via_map.c2
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.c55
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_drv.h10
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_execbuf.c15
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fb.c22
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.c252
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_fence.h9
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.c91
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_kms.h8
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_ldu.c4
-rw-r--r--drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c38
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
41struct 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}
447EXPORT_SYMBOL(drm_mode_remove); 442EXPORT_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);
845int drm_mode_create_scaling_mode_property(struct drm_device *dev) 792int 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);
874int drm_mode_create_dithering_property(struct drm_device *dev) 817int 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);
902int drm_mode_create_dirty_info_property(struct drm_device *dev) 841int 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}
1052EXPORT_SYMBOL(drm_mode_config_cleanup); 989EXPORT_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 */
1558int drm_mode_getplane_res(struct drm_device *dev, void *data, 1498int 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}
2618EXPORT_SYMBOL(drm_property_create); 2564EXPORT_SYMBOL(drm_property_create);
2619 2565
2566struct 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}
2592EXPORT_SYMBOL(drm_property_create_enum);
2593
2594struct 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}
2611EXPORT_SYMBOL(drm_property_create_range);
2612
2620int drm_property_add_enum(struct drm_property *property, int index, 2613int 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}
3022EXPORT_SYMBOL(drm_mode_connector_detach_encoder); 3015EXPORT_SYMBOL(drm_mode_connector_detach_encoder);
3023 3016
3024bool drm_mode_crtc_set_gamma_size(struct drm_crtc *crtc, 3017int 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}
3037EXPORT_SYMBOL(drm_mode_crtc_set_gamma_size); 3030EXPORT_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);
44static void drm_mode_validate_flag(struct drm_connector *connector, 44static 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 = {
306static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { }; 306static struct sysrq_key_op sysrq_drm_fb_helper_restore_op = { };
307#endif 307#endif
308 308
309static void drm_fb_helper_on(struct fb_info *info) 309static 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
354static 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;
483out_free: 425out_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
49static 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
75static struct fb_ops exynos_drm_fb_ops = { 49static 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
42static inline struct intel_gmbus * 42static inline struct intel_gmbus *
43to_intel_gmbus(struct i2c_adapter *i2c) 43to_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
86static const char *force_audio_names[] = { 86static 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
93void 93void
@@ -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
118static const char *broadcast_rgb_names[] = { 114static 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
123void 119void
@@ -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
158struct drm_prop_enum_list { 158struct 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
164static struct drm_prop_enum_list underscan[] = { 164static 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
171static struct drm_prop_enum_list dither_mode[] = { 171static 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
181static struct drm_prop_enum_list dither_depth[] = { 181static 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
86int r128_driver_load(struct drm_device *dev, unsigned long flags) 86int 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
76radeon-$(CONFIG_COMPAT) += radeon_ioc32.o 76radeon-$(CONFIG_COMPAT) += radeon_ioc32.o
77radeon-$(CONFIG_VGA_SWITCHEROO) += radeon_atpx_handler.o 77radeon-$(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
36static 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
85int 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
135u32 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);
43extern void cayman_cp_int_cntl_setup(struct radeon_device *rdev, 43extern 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
46void 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
46void evergreen_fix_pci_max_read_req_size(struct radeon_device *rdev) 77void 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 */
48static void 38static 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
34static int evergreen_cs_packet_next_reloc(struct radeon_cs_parser *p, 37static 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
106static 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
119static void evergreen_cs_track_init(struct evergreen_cs_track *track) 115static 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
164static int evergreen_cs_track_check(struct radeon_cs_parser *p) 167struct 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
187static 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
198static 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
220static 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
251static 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
292static 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
316static 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
389static 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
457static 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
546static 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
633static 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
795static 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/** 1758static 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 */
1009static 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
1017static int evergreen_packet3_check(struct radeon_cs_parser *p, 1784static 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 */
49static void 36static 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
165static bool fmt_is_valid_color(u32 format) 170bool 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
176static bool fmt_is_valid_texture(u32 format, enum radeon_family family) 181bool 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
190static int fmt_get_blocksize(u32 format) 195int 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
198static int fmt_get_nblocksx(u32 format, u32 w) 203int 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
212static int fmt_get_nblocksy(u32 format, u32 h) 217int 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
315static int r600_cs_track_validate_cb(struct radeon_cs_parser *p, int i) 327static 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
1201static unsigned mip_minify(unsigned size, unsigned level) 1289unsigned 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
1494static 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
1400static int r600_packet3_check(struct radeon_cs_parser *p, 1510static 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);
242extern int rv770_get_temp(struct radeon_device *rdev); 242extern int rv770_get_temp(struct radeon_device *rdev);
243extern int evergreen_get_temp(struct radeon_device *rdev); 243extern int evergreen_get_temp(struct radeon_device *rdev);
244extern int sumo_get_temp(struct radeon_device *rdev); 244extern int sumo_get_temp(struct radeon_device *rdev);
245extern 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);
1750void r600_vram_scratch_fini(struct radeon_device *rdev); 1753void r600_vram_scratch_fini(struct radeon_device *rdev);
1751 1754
1752/* 1755/*
1756 * r600 cs checking helper
1757 */
1758unsigned r600_mip_minify(unsigned size, unsigned level);
1759bool r600_fmt_is_valid_color(u32 format);
1760bool r600_fmt_is_valid_texture(u32 format, enum radeon_family family);
1761int r600_fmt_get_blocksize(u32 format);
1762int r600_fmt_get_nblocksx(u32 format, u32 w);
1763int 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 */
1755extern void r600_hdmi_enable(struct drm_encoder *encoder); 1768extern 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
1127struct drm_prop_enum_list {
1128 int type;
1129 char *name;
1130};
1131
1132static struct drm_prop_enum_list radeon_tmds_pll_enum_list[] = 1127static 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
1154static int radeon_modeset_create_props(struct radeon_device *rdev) 1149static 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
62int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags); 63int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags);
63int radeon_driver_unload_kms(struct drm_device *dev); 64int 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
33extern int radeon_atom_hw_i2c_xfer(struct i2c_adapter *i2c_adap,
34 struct i2c_msg *msgs, int num);
35extern 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
889static 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
885struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev, 894struct 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)
445int radeon_bo_set_tiling_flags(struct radeon_bo *bo, 445int 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 @@
1cayman 0x9400 1cayman 0x9400
20x0000802C GRBM_GFX_INDEX 20x0000802C GRBM_GFX_INDEX
30x000084FC CP_STRMOUT_CNTL
40x000085F0 CP_COHER_CNTL
50x000085F4 CP_COHER_SIZE
30x000088B0 VGT_VTX_VECT_EJECT_REG 60x000088B0 VGT_VTX_VECT_EJECT_REG
40x000088C4 VGT_CACHE_INVALIDATION 70x000088C4 VGT_CACHE_INVALIDATION
50x000088D4 VGT_GS_VERTEX_REUSE 80x000088D4 VGT_GS_VERTEX_REUSE
@@ -77,7 +80,6 @@ cayman 0x9400
770x0002802C DB_DEPTH_CLEAR 800x0002802C DB_DEPTH_CLEAR
780x00028030 PA_SC_SCREEN_SCISSOR_TL 810x00028030 PA_SC_SCREEN_SCISSOR_TL
790x00028034 PA_SC_SCREEN_SCISSOR_BR 820x00028034 PA_SC_SCREEN_SCISSOR_BR
800x0002805C DB_DEPTH_SLICE
810x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 830x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
820x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 840x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
830x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 850x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
@@ -512,6 +514,13 @@ cayman 0x9400
5120x00028AC0 DB_SRESULTS_COMPARE_STATE0 5140x00028AC0 DB_SRESULTS_COMPARE_STATE0
5130x00028AC4 DB_SRESULTS_COMPARE_STATE1 5150x00028AC4 DB_SRESULTS_COMPARE_STATE1
5140x00028AC8 DB_PRELOAD_CONTROL 5160x00028AC8 DB_PRELOAD_CONTROL
5170x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
5180x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
5190x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
5200x00028B04 VGT_STRMOUT_VTX_STRIDE_3
5210x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
5220x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
5230x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
5150x00028B38 VGT_GS_MAX_VERT_OUT 5240x00028B38 VGT_GS_MAX_VERT_OUT
5160x00028B54 VGT_SHADER_STAGES_EN 5250x00028B54 VGT_SHADER_STAGES_EN
5170x00028B58 VGT_LS_HS_CONFIG 5260x00028B58 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
40x00008044 WAIT_UNTIL_POLL_CNTL 40x00008044 WAIT_UNTIL_POLL_CNTL
50x00008048 WAIT_UNTIL_POLL_MASK 50x00008048 WAIT_UNTIL_POLL_MASK
60x0000804c WAIT_UNTIL_POLL_REFDATA 60x0000804c WAIT_UNTIL_POLL_REFDATA
70x000084FC CP_STRMOUT_CNTL
80x000085F0 CP_COHER_CNTL
90x000085F4 CP_COHER_SIZE
70x000088B0 VGT_VTX_VECT_EJECT_REG 100x000088B0 VGT_VTX_VECT_EJECT_REG
80x000088C4 VGT_CACHE_INVALIDATION 110x000088C4 VGT_CACHE_INVALIDATION
90x000088D4 VGT_GS_VERTEX_REUSE 120x000088D4 VGT_GS_VERTEX_REUSE
@@ -93,7 +96,6 @@ evergreen 0x9400
930x0002802C DB_DEPTH_CLEAR 960x0002802C DB_DEPTH_CLEAR
940x00028030 PA_SC_SCREEN_SCISSOR_TL 970x00028030 PA_SC_SCREEN_SCISSOR_TL
950x00028034 PA_SC_SCREEN_SCISSOR_BR 980x00028034 PA_SC_SCREEN_SCISSOR_BR
960x0002805C DB_DEPTH_SLICE
970x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0 990x00028140 SQ_ALU_CONST_BUFFER_SIZE_PS_0
980x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1 1000x00028144 SQ_ALU_CONST_BUFFER_SIZE_PS_1
990x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2 1010x00028148 SQ_ALU_CONST_BUFFER_SIZE_PS_2
@@ -522,6 +524,13 @@ evergreen 0x9400
5220x00028AC0 DB_SRESULTS_COMPARE_STATE0 5240x00028AC0 DB_SRESULTS_COMPARE_STATE0
5230x00028AC4 DB_SRESULTS_COMPARE_STATE1 5250x00028AC4 DB_SRESULTS_COMPARE_STATE1
5240x00028AC8 DB_PRELOAD_CONTROL 5260x00028AC8 DB_PRELOAD_CONTROL
5270x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
5280x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
5290x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
5300x00028B04 VGT_STRMOUT_VTX_STRIDE_3
5310x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
5320x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
5330x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
5250x00028B38 VGT_GS_MAX_VERT_OUT 5340x00028B38 VGT_GS_MAX_VERT_OUT
5260x00028B54 VGT_SHADER_STAGES_EN 5350x00028B54 VGT_SHADER_STAGES_EN
5270x00028B58 VGT_LS_HS_CONFIG 5360x00028B58 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
30x00028230 R7xx_PA_SC_EDGERULE 30x00028230 R7xx_PA_SC_EDGERULE
40x000286C8 R7xx_SPI_THREAD_GROUPING 40x000286C8 R7xx_SPI_THREAD_GROUPING
50x00008D8C R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ 50x00008D8C R7xx_SQ_DYN_GPR_CNTL_PS_FLUSH_REQ
60x00008490 CP_STRMOUT_CNTL
70x000085F0 CP_COHER_CNTL
80x000085F4 CP_COHER_SIZE
60x000088C4 VGT_CACHE_INVALIDATION 90x000088C4 VGT_CACHE_INVALIDATION
70x00028A50 VGT_ENHANCE 100x00028A50 VGT_ENHANCE
80x000088CC VGT_ES_PER_GS 110x000088CC VGT_ES_PER_GS
@@ -38,6 +41,13 @@ r600 0x9400
380x00028AB4 VGT_REUSE_OFF 410x00028AB4 VGT_REUSE_OFF
390x00028AB8 VGT_VTX_CNT_EN 420x00028AB8 VGT_VTX_CNT_EN
400x000088B0 VGT_VTX_VECT_EJECT_REG 430x000088B0 VGT_VTX_VECT_EJECT_REG
440x00028AD4 VGT_STRMOUT_VTX_STRIDE_0
450x00028AE4 VGT_STRMOUT_VTX_STRIDE_1
460x00028AF4 VGT_STRMOUT_VTX_STRIDE_2
470x00028B04 VGT_STRMOUT_VTX_STRIDE_3
480x00028B28 VGT_STRMOUT_DRAW_OPAQUE_OFFSET
490x00028B2C VGT_STRMOUT_DRAW_OPAQUE_BUFFER_FILLED_SIZE
500x00028B30 VGT_STRMOUT_DRAW_OPAQUE_VERTEX_STRIDE
410x00028810 PA_CL_CLIP_CNTL 510x00028810 PA_CL_CLIP_CNTL
420x00008A14 PA_CL_ENHANCE 520x00008A14 PA_CL_ENHANCE
430x00028C14 PA_CL_GB_HORZ_CLIP_ADJ 530x00028C14 PA_CL_GB_HORZ_CLIP_ADJ
@@ -429,6 +439,7 @@ r600 0x9400
4290x00028438 SX_ALPHA_REF 4390x00028438 SX_ALPHA_REF
4300x00028410 SX_ALPHA_TEST_CONTROL 4400x00028410 SX_ALPHA_TEST_CONTROL
4310x00028350 SX_MISC 4410x00028350 SX_MISC
4420x00028354 SX_SURFACE_SYNC
4320x00009014 SX_MEMORY_EXPORT_SIZE 4430x00009014 SX_MEMORY_EXPORT_SIZE
4330x00009604 TC_INVALIDATE 4440x00009604 TC_INVALIDATE
4340x00009400 TD_FILTER4 4450x00009400 TD_FILTER4
@@ -743,14 +754,6 @@ r600 0x9400
7430x00028114 CB_COLOR5_MASK 7540x00028114 CB_COLOR5_MASK
7440x00028118 CB_COLOR6_MASK 7550x00028118 CB_COLOR6_MASK
7450x0002811C CB_COLOR7_MASK 7560x0002811C CB_COLOR7_MASK
7460x00028080 CB_COLOR0_VIEW
7470x00028084 CB_COLOR1_VIEW
7480x00028088 CB_COLOR2_VIEW
7490x0002808C CB_COLOR3_VIEW
7500x00028090 CB_COLOR4_VIEW
7510x00028094 CB_COLOR5_VIEW
7520x00028098 CB_COLOR6_VIEW
7530x0002809C CB_COLOR7_VIEW
7540x00028808 CB_COLOR_CONTROL 7570x00028808 CB_COLOR_CONTROL
7550x0002842C CB_FOG_BLUE 7580x0002842C CB_FOG_BLUE
7560x00028428 CB_FOG_GREEN 7590x00028428 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 */
403static 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
390static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) 429static 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
735static 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
691static void vmw_postclose(struct drm_device *dev, 744static 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 @@
62struct vmw_fpriv { 62struct 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
67struct vmw_dma_buffer { 68struct 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
538extern void 542extern void
539vmw_execbuf_release_pinned_bo(struct vmw_private *dev_priv, 543vmw_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 */
71struct vmw_event_fence_action { 71struct 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 */
796static 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 */
821static void vmw_event_fence_action_delivered(struct drm_pending_event *e) 800void 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 }
820out_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 */
842static void vmw_event_fence_action_seq_passed(struct vmw_fence_action *action) 836static 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
949int vmw_event_fence_action_create(struct drm_file *file_priv, 955int 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
991struct vmw_event_fence_pending {
992 struct drm_pending_event base;
993 struct drm_vmw_event_fence event;
994};
995
996int 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
1052out_no_queue:
1053 event->base.destroy(&event->base);
1054out_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);
1058out_no_space:
1059 return ret;
1060}
1061
999int vmw_fence_event_ioctl(struct drm_device *dev, void *data, 1062int 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;
1111out_no_attach: 1147out_no_create:
1112 kfree(event);
1113out_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);
1117out_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);
110extern int vmw_fence_event_ioctl(struct drm_device *dev, void *data, 110extern int vmw_fence_event_ioctl(struct drm_device *dev, void *data,
111 struct drm_file *file_priv); 111 struct drm_file *file_priv);
112 112extern void vmw_event_fence_fpriv_gone(struct vmw_fence_manager *fman,
113 struct list_head *event_list);
114extern 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
1684int 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
1742out_no_fence:
1743 crtc->fb = old_fb;
1744 return ret;
1745}
1746
1747
1675void vmw_du_crtc_save(struct drm_crtc *crtc) 1748void 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 */
123void vmw_display_unit_cleanup(struct vmw_display_unit *du); 123void vmw_display_unit_cleanup(struct vmw_display_unit *du);
124int vmw_du_page_flip(struct drm_crtc *crtc,
125 struct drm_framebuffer *fb,
126 struct drm_pending_vblank_event *event);
124void vmw_du_crtc_save(struct drm_crtc *crtc); 127void vmw_du_crtc_save(struct drm_crtc *crtc);
125void vmw_du_crtc_restore(struct drm_crtc *crtc); 128void vmw_du_crtc_restore(struct drm_crtc *crtc);
126void vmw_du_crtc_gamma_set(struct drm_crtc *crtc, 129void 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);
154int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv); 157int vmw_kms_close_screen_object_display(struct vmw_private *dev_priv);
155int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num, 158int vmw_kms_sou_update_layout(struct vmw_private *dev_priv, unsigned num,
156 struct drm_vmw_rect *rects); 159 struct drm_vmw_rect *rects);
160bool vmw_kms_screen_object_flippable(struct vmw_private *dev_priv,
161 struct drm_crtc *crtc);
162void 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 */
544bool 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 */
562void 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}