diff options
author | Ben Widawsky <benjamin.widawsky@intel.com> | 2013-11-04 22:32:22 -0500 |
---|---|---|
committer | Daniel Vetter <daniel.vetter@ffwll.ch> | 2013-11-08 12:09:43 -0500 |
commit | 63340133f3d58634b068f15f9f43f905ea94b837 (patch) | |
tree | a2628c7ad0061c67c0a8e7510e3f34c3792db756 | |
parent | d0582ed2ff119eae26c74a5ec85c08fbd6ae0e18 (diff) |
drm/i915/bdw: Make gen8_gmch_probe
Probing gen8 is similar to gen6. To make the code cleaner and more
maintainable however we can use the probe functions to split it out.
v2: Rebased on top of update gtt probe infrastructure.
v3: Rebased on top of Kenneth' Graunke's ->pte_encode refactoring.
V4: Resolve conflicts with Ben's latest ppgtt patches, also switch to
gen < 8 testing instead of gen <= 7.
v5: Resolve conflicts with address space vfunc changes in upstream.
v6: Use 39b DMA mask. At least, for this mode, it is the correct mask.
(Imre)
Cc: Imre Deak <imre.deak@intel.com>
Signed-off-by: Ben Widawsky <ben@bwidawsk.net>
Reviewed-by: Imre Deak <imre.deak@intel.com>
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
-rw-r--r-- | drivers/gpu/drm/i915/i915_gem_gtt.c | 92 |
1 files changed, 68 insertions, 24 deletions
diff --git a/drivers/gpu/drm/i915/i915_gem_gtt.c b/drivers/gpu/drm/i915/i915_gem_gtt.c index 074aec11fc9b..ee71aa558f9a 100644 --- a/drivers/gpu/drm/i915/i915_gem_gtt.c +++ b/drivers/gpu/drm/i915/i915_gem_gtt.c | |||
@@ -892,6 +892,66 @@ static inline size_t gen8_get_stolen_size(u16 bdw_gmch_ctl) | |||
892 | return bdw_gmch_ctl << 25; /* 32 MB units */ | 892 | return bdw_gmch_ctl << 25; /* 32 MB units */ |
893 | } | 893 | } |
894 | 894 | ||
895 | static int ggtt_probe_common(struct drm_device *dev, | ||
896 | size_t gtt_size) | ||
897 | { | ||
898 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
899 | phys_addr_t gtt_bus_addr; | ||
900 | int ret; | ||
901 | |||
902 | /* For Modern GENs the PTEs and register space are split in the BAR */ | ||
903 | gtt_bus_addr = pci_resource_start(dev->pdev, 0) + | ||
904 | (pci_resource_len(dev->pdev, 0) / 2); | ||
905 | |||
906 | dev_priv->gtt.gsm = ioremap_wc(gtt_bus_addr, gtt_size); | ||
907 | if (!dev_priv->gtt.gsm) { | ||
908 | DRM_ERROR("Failed to map the gtt page table\n"); | ||
909 | return -ENOMEM; | ||
910 | } | ||
911 | |||
912 | ret = setup_scratch_page(dev); | ||
913 | if (ret) { | ||
914 | DRM_ERROR("Scratch setup failed\n"); | ||
915 | /* iounmap will also get called at remove, but meh */ | ||
916 | iounmap(dev_priv->gtt.gsm); | ||
917 | } | ||
918 | |||
919 | return ret; | ||
920 | } | ||
921 | |||
922 | static int gen8_gmch_probe(struct drm_device *dev, | ||
923 | size_t *gtt_total, | ||
924 | size_t *stolen, | ||
925 | phys_addr_t *mappable_base, | ||
926 | unsigned long *mappable_end) | ||
927 | { | ||
928 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
929 | unsigned int gtt_size; | ||
930 | u16 snb_gmch_ctl; | ||
931 | int ret; | ||
932 | |||
933 | /* TODO: We're not aware of mappable constraints on gen8 yet */ | ||
934 | *mappable_base = pci_resource_start(dev->pdev, 2); | ||
935 | *mappable_end = pci_resource_len(dev->pdev, 2); | ||
936 | |||
937 | if (!pci_set_dma_mask(dev->pdev, DMA_BIT_MASK(39))) | ||
938 | pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(39)); | ||
939 | |||
940 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); | ||
941 | |||
942 | *stolen = gen8_get_stolen_size(snb_gmch_ctl); | ||
943 | |||
944 | gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl); | ||
945 | *gtt_total = (gtt_size / 8) << PAGE_SHIFT; | ||
946 | |||
947 | ret = ggtt_probe_common(dev, gtt_size); | ||
948 | |||
949 | dev_priv->gtt.base.clear_range = NULL; | ||
950 | dev_priv->gtt.base.insert_entries = NULL; | ||
951 | |||
952 | return ret; | ||
953 | } | ||
954 | |||
895 | static int gen6_gmch_probe(struct drm_device *dev, | 955 | static int gen6_gmch_probe(struct drm_device *dev, |
896 | size_t *gtt_total, | 956 | size_t *gtt_total, |
897 | size_t *stolen, | 957 | size_t *stolen, |
@@ -899,7 +959,6 @@ static int gen6_gmch_probe(struct drm_device *dev, | |||
899 | unsigned long *mappable_end) | 959 | unsigned long *mappable_end) |
900 | { | 960 | { |
901 | struct drm_i915_private *dev_priv = dev->dev_private; | 961 | struct drm_i915_private *dev_priv = dev->dev_private; |
902 | phys_addr_t gtt_bus_addr; | ||
903 | unsigned int gtt_size; | 962 | unsigned int gtt_size; |
904 | u16 snb_gmch_ctl; | 963 | u16 snb_gmch_ctl; |
905 | int ret; | 964 | int ret; |
@@ -920,30 +979,12 @@ static int gen6_gmch_probe(struct drm_device *dev, | |||
920 | pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(40)); | 979 | pci_set_consistent_dma_mask(dev->pdev, DMA_BIT_MASK(40)); |
921 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); | 980 | pci_read_config_word(dev->pdev, SNB_GMCH_CTRL, &snb_gmch_ctl); |
922 | 981 | ||
923 | if (IS_GEN8(dev)) { | 982 | *stolen = gen6_get_stolen_size(snb_gmch_ctl); |
924 | gtt_size = gen8_get_total_gtt_size(snb_gmch_ctl); | ||
925 | *gtt_total = (gtt_size / 8) << PAGE_SHIFT; | ||
926 | *stolen = gen8_get_stolen_size(snb_gmch_ctl); | ||
927 | } else { | ||
928 | gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); | ||
929 | *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT; | ||
930 | *stolen = gen6_get_stolen_size(snb_gmch_ctl); | ||
931 | } | ||
932 | 983 | ||
933 | /* For Modern GENs the PTEs and register space are split in the BAR */ | 984 | gtt_size = gen6_get_total_gtt_size(snb_gmch_ctl); |
934 | gtt_bus_addr = pci_resource_start(dev->pdev, 0) + | 985 | *gtt_total = (gtt_size / sizeof(gen6_gtt_pte_t)) << PAGE_SHIFT; |
935 | (pci_resource_len(dev->pdev, 0) / 2); | ||
936 | 986 | ||
937 | dev_priv->gtt.gsm = ioremap_wc(gtt_bus_addr, gtt_size); | 987 | ret = ggtt_probe_common(dev, gtt_size); |
938 | if (!dev_priv->gtt.gsm) { | ||
939 | DRM_ERROR("Failed to map the gtt page table\n"); | ||
940 | return -ENOMEM; | ||
941 | |||
942 | } | ||
943 | |||
944 | ret = setup_scratch_page(dev); | ||
945 | if (ret) | ||
946 | DRM_ERROR("Scratch setup failed\n"); | ||
947 | 988 | ||
948 | dev_priv->gtt.base.clear_range = gen6_ggtt_clear_range; | 989 | dev_priv->gtt.base.clear_range = gen6_ggtt_clear_range; |
949 | dev_priv->gtt.base.insert_entries = gen6_ggtt_insert_entries; | 990 | dev_priv->gtt.base.insert_entries = gen6_ggtt_insert_entries; |
@@ -997,7 +1038,7 @@ int i915_gem_gtt_init(struct drm_device *dev) | |||
997 | if (INTEL_INFO(dev)->gen <= 5) { | 1038 | if (INTEL_INFO(dev)->gen <= 5) { |
998 | gtt->gtt_probe = i915_gmch_probe; | 1039 | gtt->gtt_probe = i915_gmch_probe; |
999 | gtt->base.cleanup = i915_gmch_remove; | 1040 | gtt->base.cleanup = i915_gmch_remove; |
1000 | } else { | 1041 | } else if (INTEL_INFO(dev)->gen < 8) { |
1001 | gtt->gtt_probe = gen6_gmch_probe; | 1042 | gtt->gtt_probe = gen6_gmch_probe; |
1002 | gtt->base.cleanup = gen6_gmch_remove; | 1043 | gtt->base.cleanup = gen6_gmch_remove; |
1003 | if (IS_HASWELL(dev) && dev_priv->ellc_size) | 1044 | if (IS_HASWELL(dev) && dev_priv->ellc_size) |
@@ -1010,6 +1051,9 @@ int i915_gem_gtt_init(struct drm_device *dev) | |||
1010 | gtt->base.pte_encode = ivb_pte_encode; | 1051 | gtt->base.pte_encode = ivb_pte_encode; |
1011 | else | 1052 | else |
1012 | gtt->base.pte_encode = snb_pte_encode; | 1053 | gtt->base.pte_encode = snb_pte_encode; |
1054 | } else { | ||
1055 | dev_priv->gtt.gtt_probe = gen8_gmch_probe; | ||
1056 | dev_priv->gtt.base.cleanup = gen6_gmch_remove; | ||
1013 | } | 1057 | } |
1014 | 1058 | ||
1015 | ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, | 1059 | ret = gtt->gtt_probe(dev, >t->base.total, >t->stolen_size, |