diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-25 16:46:44 -0800 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-02-25 16:46:44 -0800 | 
| commit | fffddfd6c8e0c10c42c6e2cc54ba880fcc36ebbb (patch) | |
| tree | 71bc5e597124dbaf7550f1e089d675718b3ed5c0 /drivers/gpu/drm/drm_mm.c | |
| parent | 69086a78bdc973ec0b722be790b146e84ba8a8c4 (diff) | |
| parent | be88298b0a3f771a4802f20c5e66af74bfd1dff1 (diff) | |
| download | olio-linux-3.10-fffddfd6c8e0c10c42c6e2cc54ba880fcc36ebbb.tar.xz olio-linux-3.10-fffddfd6c8e0c10c42c6e2cc54ba880fcc36ebbb.zip  | |
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm merge from Dave Airlie:
 "Highlights:
   - TI LCD controller KMS driver
   - TI OMAP KMS driver merged from staging
   - drop gma500 stub driver
   - the fbcon locking fixes
   - the vgacon dirty like zebra fix.
   - open firmware videomode and hdmi common code helpers
   - major locking rework for kms object handling - pageflip/cursor
     won't block on polling anymore!
   - fbcon helper and prime helper cleanups
   - i915: all over the map, haswell power well enhancements, valleyview
     macro horrors cleaned up, killing lots of legacy GTT code,
   - radeon: CS ioctl unification, deprecated UMS support, gpu reset
     rework, VM fixes
   - nouveau: reworked thermal code, external dp/tmds encoder support
     (anx9805), fences sleep instead of polling,
   - exynos: all over the driver fixes."
Lovely conflict in radeon/evergreen_cs.c between commit de0babd60d8d
("drm/radeon: enforce use of radeon_get_ib_value when reading user cmd")
and the new changes that modified that evergreen_dma_cs_parse()
function.
* 'drm-next' of git://people.freedesktop.org/~airlied/linux: (508 commits)
  drm/tilcdc: only build on arm
  drm/i915: Revert hdmi HDP pin checks
  drm/tegra: Add list of framebuffers to debugfs
  drm/tegra: Fix color expansion
  drm/tegra: Split DC_CMD_STATE_CONTROL register write
  drm/tegra: Implement page-flipping support
  drm/tegra: Implement VBLANK support
  drm/tegra: Implement .mode_set_base()
  drm/tegra: Add plane support
  drm/tegra: Remove bogus tegra_framebuffer structure
  drm: Add consistency check for page-flipping
  drm/radeon: Use generic HDMI infoframe helpers
  drm/tegra: Use generic HDMI infoframe helpers
  drm: Add EDID helper documentation
  drm: Add HDMI infoframe helpers
  video: Add generic HDMI infoframe helpers
  drm: Add some missing forward declarations
  drm: Move mode tables to drm_edid.c
  drm: Remove duplicate drm_mode_cea_vic()
  gma500: Fix n, m1 and m2 clock limits for sdvo and lvds
  ...
Diffstat (limited to 'drivers/gpu/drm/drm_mm.c')
| -rw-r--r-- | drivers/gpu/drm/drm_mm.c | 96 | 
1 files changed, 63 insertions, 33 deletions
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c index 2aa331499f8..db1e2d6f90d 100644 --- a/drivers/gpu/drm/drm_mm.c +++ b/drivers/gpu/drm/drm_mm.c @@ -102,20 +102,6 @@ int drm_mm_pre_get(struct drm_mm *mm)  }  EXPORT_SYMBOL(drm_mm_pre_get); -static inline unsigned long drm_mm_hole_node_start(struct drm_mm_node *hole_node) -{ -	return hole_node->start + hole_node->size; -} - -static inline unsigned long drm_mm_hole_node_end(struct drm_mm_node *hole_node) -{ -	struct drm_mm_node *next_node = -		list_entry(hole_node->node_list.next, struct drm_mm_node, -			   node_list); - -	return next_node->start; -} -  static void drm_mm_insert_helper(struct drm_mm_node *hole_node,  				 struct drm_mm_node *node,  				 unsigned long size, unsigned alignment, @@ -127,7 +113,7 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node,  	unsigned long adj_start = hole_start;  	unsigned long adj_end = hole_end; -	BUG_ON(!hole_node->hole_follows || node->allocated); +	BUG_ON(node->allocated);  	if (mm->color_adjust)  		mm->color_adjust(hole_node, color, &adj_start, &adj_end); @@ -155,12 +141,57 @@ static void drm_mm_insert_helper(struct drm_mm_node *hole_node,  	BUG_ON(node->start + node->size > adj_end);  	node->hole_follows = 0; -	if (node->start + node->size < hole_end) { +	if (__drm_mm_hole_node_start(node) < hole_end) {  		list_add(&node->hole_stack, &mm->hole_stack);  		node->hole_follows = 1;  	}  } +struct drm_mm_node *drm_mm_create_block(struct drm_mm *mm, +					unsigned long start, +					unsigned long size, +					bool atomic) +{ +	struct drm_mm_node *hole, *node; +	unsigned long end = start + size; +	unsigned long hole_start; +	unsigned long hole_end; + +	drm_mm_for_each_hole(hole, mm, hole_start, hole_end) { +		if (hole_start > start || hole_end < end) +			continue; + +		node = drm_mm_kmalloc(mm, atomic); +		if (unlikely(node == NULL)) +			return NULL; + +		node->start = start; +		node->size = size; +		node->mm = mm; +		node->allocated = 1; + +		INIT_LIST_HEAD(&node->hole_stack); +		list_add(&node->node_list, &hole->node_list); + +		if (start == hole_start) { +			hole->hole_follows = 0; +			list_del_init(&hole->hole_stack); +		} + +		node->hole_follows = 0; +		if (end != hole_end) { +			list_add(&node->hole_stack, &mm->hole_stack); +			node->hole_follows = 1; +		} + +		return node; +	} + +	WARN(1, "no hole found for block 0x%lx + 0x%lx\n", start, size); +	return NULL; +} +EXPORT_SYMBOL(drm_mm_create_block); +  struct drm_mm_node *drm_mm_get_block_generic(struct drm_mm_node *hole_node,  					     unsigned long size,  					     unsigned alignment, @@ -253,7 +284,7 @@ static void drm_mm_insert_helper_range(struct drm_mm_node *hole_node,  	BUG_ON(node->start + node->size > end);  	node->hole_follows = 0; -	if (node->start + node->size < hole_end) { +	if (__drm_mm_hole_node_start(node) < hole_end) {  		list_add(&node->hole_stack, &mm->hole_stack);  		node->hole_follows = 1;  	} @@ -327,12 +358,13 @@ void drm_mm_remove_node(struct drm_mm_node *node)  	    list_entry(node->node_list.prev, struct drm_mm_node, node_list);  	if (node->hole_follows) { -		BUG_ON(drm_mm_hole_node_start(node) -				== drm_mm_hole_node_end(node)); +		BUG_ON(__drm_mm_hole_node_start(node) == +		       __drm_mm_hole_node_end(node));  		list_del(&node->hole_stack);  	} else -		BUG_ON(drm_mm_hole_node_start(node) -				!= drm_mm_hole_node_end(node)); +		BUG_ON(__drm_mm_hole_node_start(node) != +		       __drm_mm_hole_node_end(node)); +  	if (!prev_node->hole_follows) {  		prev_node->hole_follows = 1; @@ -390,6 +422,8 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,  {  	struct drm_mm_node *entry;  	struct drm_mm_node *best; +	unsigned long adj_start; +	unsigned long adj_end;  	unsigned long best_size;  	BUG_ON(mm->scanned_blocks); @@ -397,17 +431,13 @@ struct drm_mm_node *drm_mm_search_free_generic(const struct drm_mm *mm,  	best = NULL;  	best_size = ~0UL; -	list_for_each_entry(entry, &mm->hole_stack, hole_stack) { -		unsigned long adj_start = drm_mm_hole_node_start(entry); -		unsigned long adj_end = drm_mm_hole_node_end(entry); - +	drm_mm_for_each_hole(entry, mm, adj_start, adj_end) {  		if (mm->color_adjust) {  			mm->color_adjust(entry, color, &adj_start, &adj_end);  			if (adj_end <= adj_start)  				continue;  		} -		BUG_ON(!entry->hole_follows);  		if (!check_free_hole(adj_start, adj_end, size, alignment))  			continue; @@ -434,6 +464,8 @@ struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,  {  	struct drm_mm_node *entry;  	struct drm_mm_node *best; +	unsigned long adj_start; +	unsigned long adj_end;  	unsigned long best_size;  	BUG_ON(mm->scanned_blocks); @@ -441,13 +473,11 @@ struct drm_mm_node *drm_mm_search_free_in_range_generic(const struct drm_mm *mm,  	best = NULL;  	best_size = ~0UL; -	list_for_each_entry(entry, &mm->hole_stack, hole_stack) { -		unsigned long adj_start = drm_mm_hole_node_start(entry) < start ? -			start : drm_mm_hole_node_start(entry); -		unsigned long adj_end = drm_mm_hole_node_end(entry) > end ? -			end : drm_mm_hole_node_end(entry); - -		BUG_ON(!entry->hole_follows); +	drm_mm_for_each_hole(entry, mm, adj_start, adj_end) { +		if (adj_start < start) +			adj_start = start; +		if (adj_end > end) +			adj_end = end;  		if (mm->color_adjust) {  			mm->color_adjust(entry, color, &adj_start, &adj_end);  |