diff options
author | Daniel Vetter <daniel.vetter@ffwll.ch> | 2010-09-11 15:31:04 -0400 |
---|---|---|
committer | Chris Wilson <chris@chris-wilson.co.uk> | 2010-09-21 06:36:25 -0400 |
commit | 5cbecafce4ee8ab73c194911e01a77a7a07f034e (patch) | |
tree | 1434a04f60faec36094bad48db0f3938367df361 /drivers/char | |
parent | a87aa5cc0074fea871c8c6d2660d9b6cd7699d3d (diff) |
intel-gtt: generic (insert|remove)_entries for i830
Well, not all too generic because it does not yet support dmar.
Add a new function check_flags to ensure that non-gem code does
not try to screw us over.
v2: Beautify i830_check_flags with an idea from Chris Wilson.
Signed-off-by: Daniel Vetter <daniel.vetter@ffwll.ch>
Signed-off-by: Chris Wilson <chris@chris-wilson.co.uk>
Diffstat (limited to 'drivers/char')
-rw-r--r-- | drivers/char/agp/intel-gtt.c | 53 |
1 files changed, 28 insertions, 25 deletions
diff --git a/drivers/char/agp/intel-gtt.c b/drivers/char/agp/intel-gtt.c index 64a62d9afb75..c1b766dbef4d 100644 --- a/drivers/char/agp/intel-gtt.c +++ b/drivers/char/agp/intel-gtt.c | |||
@@ -94,6 +94,7 @@ struct intel_gtt_driver { | |||
94 | /* Flags is a more or less chipset specific opaque value. | 94 | /* Flags is a more or less chipset specific opaque value. |
95 | * For chipsets that need to support old ums (non-gem) code, this | 95 | * For chipsets that need to support old ums (non-gem) code, this |
96 | * needs to be identical to the various supported agp memory types! */ | 96 | * needs to be identical to the various supported agp memory types! */ |
97 | bool (*check_flags)(unsigned int flags); | ||
97 | }; | 98 | }; |
98 | 99 | ||
99 | static struct _intel_private { | 100 | static struct _intel_private { |
@@ -1037,20 +1038,28 @@ static int intel_fake_agp_configure(void) | |||
1037 | return 0; | 1038 | return 0; |
1038 | } | 1039 | } |
1039 | 1040 | ||
1040 | static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | 1041 | static bool i830_check_flags(unsigned int flags) |
1041 | int type) | ||
1042 | { | 1042 | { |
1043 | int i, j, num_entries; | 1043 | switch (flags) { |
1044 | void *temp; | 1044 | case 0: |
1045 | case AGP_PHYS_MEMORY: | ||
1046 | case AGP_USER_CACHED_MEMORY: | ||
1047 | case AGP_USER_MEMORY: | ||
1048 | return true; | ||
1049 | } | ||
1050 | |||
1051 | return false; | ||
1052 | } | ||
1053 | |||
1054 | static int intel_fake_agp_insert_entries(struct agp_memory *mem, | ||
1055 | off_t pg_start, int type) | ||
1056 | { | ||
1057 | int i, j; | ||
1045 | int ret = -EINVAL; | 1058 | int ret = -EINVAL; |
1046 | int mask_type; | ||
1047 | 1059 | ||
1048 | if (mem->page_count == 0) | 1060 | if (mem->page_count == 0) |
1049 | goto out; | 1061 | goto out; |
1050 | 1062 | ||
1051 | temp = agp_bridge->current_size; | ||
1052 | num_entries = A_SIZE_FIX(temp)->num_entries; | ||
1053 | |||
1054 | if (pg_start < intel_private.base.gtt_stolen_entries) { | 1063 | if (pg_start < intel_private.base.gtt_stolen_entries) { |
1055 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, | 1064 | dev_printk(KERN_DEBUG, &intel_private.pcidev->dev, |
1056 | "pg_start == 0x%.8lx, gtt_stolen_entries == 0x%.8x\n", | 1065 | "pg_start == 0x%.8lx, gtt_stolen_entries == 0x%.8x\n", |
@@ -1061,29 +1070,21 @@ static int intel_i830_insert_entries(struct agp_memory *mem, off_t pg_start, | |||
1061 | goto out_err; | 1070 | goto out_err; |
1062 | } | 1071 | } |
1063 | 1072 | ||
1064 | if ((pg_start + mem->page_count) > num_entries) | 1073 | if ((pg_start + mem->page_count) > intel_private.base.gtt_total_entries) |
1065 | goto out_err; | 1074 | goto out_err; |
1066 | 1075 | ||
1067 | /* The i830 can't check the GTT for entries since its read only, | ||
1068 | * depend on the caller to make the correct offset decisions. | ||
1069 | */ | ||
1070 | |||
1071 | if (type != mem->type) | 1076 | if (type != mem->type) |
1072 | goto out_err; | 1077 | goto out_err; |
1073 | 1078 | ||
1074 | mask_type = agp_bridge->driver->agp_type_to_mask_type(agp_bridge, type); | 1079 | if (!intel_private.driver->check_flags(type)) |
1075 | |||
1076 | if (mask_type != 0 && mask_type != AGP_PHYS_MEMORY && | ||
1077 | mask_type != INTEL_AGP_CACHED_MEMORY) | ||
1078 | goto out_err; | 1080 | goto out_err; |
1079 | 1081 | ||
1080 | if (!mem->is_flushed) | 1082 | if (!mem->is_flushed) |
1081 | global_cache_flush(); | 1083 | global_cache_flush(); |
1082 | 1084 | ||
1083 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { | 1085 | for (i = 0, j = pg_start; i < mem->page_count; i++, j++) { |
1084 | writel(agp_bridge->driver->mask_memory(agp_bridge, | 1086 | intel_private.driver->write_entry(page_to_phys(mem->pages[i]), |
1085 | page_to_phys(mem->pages[i]), mask_type), | 1087 | j, type); |
1086 | intel_private.gtt+j); | ||
1087 | } | 1088 | } |
1088 | readl(intel_private.gtt+j-1); | 1089 | readl(intel_private.gtt+j-1); |
1089 | 1090 | ||
@@ -1094,8 +1095,8 @@ out_err: | |||
1094 | return ret; | 1095 | return ret; |
1095 | } | 1096 | } |
1096 | 1097 | ||
1097 | static int intel_i830_remove_entries(struct agp_memory *mem, off_t pg_start, | 1098 | static int intel_fake_agp_remove_entries(struct agp_memory *mem, |
1098 | int type) | 1099 | off_t pg_start, int type) |
1099 | { | 1100 | { |
1100 | int i; | 1101 | int i; |
1101 | 1102 | ||
@@ -1109,7 +1110,8 @@ static int intel_i830_remove_entries(struct agp_memory *mem, off_t pg_start, | |||
1109 | } | 1110 | } |
1110 | 1111 | ||
1111 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { | 1112 | for (i = pg_start; i < (mem->page_count + pg_start); i++) { |
1112 | writel(agp_bridge->scratch_page, intel_private.gtt+i); | 1113 | intel_private.driver->write_entry(intel_private.scratch_page_dma, |
1114 | i, 0); | ||
1113 | } | 1115 | } |
1114 | readl(intel_private.gtt+i-1); | 1116 | readl(intel_private.gtt+i-1); |
1115 | 1117 | ||
@@ -1441,8 +1443,8 @@ static const struct agp_bridge_driver intel_830_driver = { | |||
1441 | .cache_flush = global_cache_flush, | 1443 | .cache_flush = global_cache_flush, |
1442 | .create_gatt_table = intel_fake_agp_create_gatt_table, | 1444 | .create_gatt_table = intel_fake_agp_create_gatt_table, |
1443 | .free_gatt_table = intel_fake_agp_free_gatt_table, | 1445 | .free_gatt_table = intel_fake_agp_free_gatt_table, |
1444 | .insert_memory = intel_i830_insert_entries, | 1446 | .insert_memory = intel_fake_agp_insert_entries, |
1445 | .remove_memory = intel_i830_remove_entries, | 1447 | .remove_memory = intel_fake_agp_remove_entries, |
1446 | .alloc_by_type = intel_fake_agp_alloc_by_type, | 1448 | .alloc_by_type = intel_fake_agp_alloc_by_type, |
1447 | .free_by_type = intel_i810_free_by_type, | 1449 | .free_by_type = intel_i810_free_by_type, |
1448 | .agp_alloc_page = agp_generic_alloc_page, | 1450 | .agp_alloc_page = agp_generic_alloc_page, |
@@ -1577,6 +1579,7 @@ static const struct intel_gtt_driver i8xx_gtt_driver = { | |||
1577 | .gen = 2, | 1579 | .gen = 2, |
1578 | .setup = i830_setup, | 1580 | .setup = i830_setup, |
1579 | .write_entry = i830_write_entry, | 1581 | .write_entry = i830_write_entry, |
1582 | .check_flags = i830_check_flags, | ||
1580 | }; | 1583 | }; |
1581 | static const struct intel_gtt_driver i915_gtt_driver = { | 1584 | static const struct intel_gtt_driver i915_gtt_driver = { |
1582 | .gen = 3, | 1585 | .gen = 3, |