diff options
Diffstat (limited to 'drivers/gpu/drm/drm_format_helper.c')
| -rw-r--r-- | drivers/gpu/drm/drm_format_helper.c | 215 | 
1 files changed, 162 insertions, 53 deletions
| diff --git a/drivers/gpu/drm/drm_format_helper.c b/drivers/gpu/drm/drm_format_helper.c index f93a4efcee90..b1be458ed4dd 100644 --- a/drivers/gpu/drm/drm_format_helper.c +++ b/drivers/gpu/drm/drm_format_helper.c @@ -20,6 +20,97 @@  #include <drm/drm_print.h>  #include <drm/drm_rect.h> +/** + * drm_format_conv_state_init - Initialize format-conversion state + * @state: The state to initialize + * + * Clears all fields in struct drm_format_conv_state. The state will + * be empty with no preallocated resources. + */ +void drm_format_conv_state_init(struct drm_format_conv_state *state) +{ +	state->tmp.mem = NULL; +	state->tmp.size = 0; +	state->tmp.preallocated = false; +} +EXPORT_SYMBOL(drm_format_conv_state_init); + +/** + * drm_format_conv_state_copy - Copy format-conversion state + * @state: Destination state + * @old_state: Source state + * + * Copies format-conversion state from @old_state to @state; except for + * temporary storage. + */ +void drm_format_conv_state_copy(struct drm_format_conv_state *state, +				const struct drm_format_conv_state *old_state) +{ +	/* +	 * So far, there's only temporary storage here, which we don't +	 * duplicate. Just clear the fields. +	 */ +	state->tmp.mem = NULL; +	state->tmp.size = 0; +	state->tmp.preallocated = false; +} +EXPORT_SYMBOL(drm_format_conv_state_copy); + +/** + * drm_format_conv_state_reserve - Allocates storage for format conversion + * @state: The format-conversion state + * @new_size: The minimum allocation size + * @flags: Flags for kmalloc() + * + * Allocates at least @new_size bytes and returns a pointer to the memory + * range. After calling this function, previously returned memory blocks + * are invalid. It's best to collect all memory requirements of a format + * conversion and call this function once to allocate the range. + * + * Returns: + * A pointer to the allocated memory range, or NULL otherwise. + */ +void *drm_format_conv_state_reserve(struct drm_format_conv_state *state, +				    size_t new_size, gfp_t flags) +{ +	void *mem; + +	if (new_size <= state->tmp.size) +		goto out; +	else if (state->tmp.preallocated) +		return NULL; + +	mem = krealloc(state->tmp.mem, new_size, flags); +	if (!mem) +		return NULL; + +	state->tmp.mem = mem; +	state->tmp.size = new_size; + +out: +	return state->tmp.mem; +} +EXPORT_SYMBOL(drm_format_conv_state_reserve); + +/** + * drm_format_conv_state_release - Releases an format-conversion storage + * @state: The format-conversion state + * + * Releases the memory range references by the format-conversion state. + * After this call, all pointers to the memory are invalid. Prefer + * drm_format_conv_state_init() for cleaning up and unloading a driver. + */ +void drm_format_conv_state_release(struct drm_format_conv_state *state) +{ +	if (state->tmp.preallocated) +		return; + +	kfree(state->tmp.mem); +	state->tmp.mem = NULL; +	state->tmp.size = 0; +} +EXPORT_SYMBOL(drm_format_conv_state_release); +  static unsigned int clip_offset(const struct drm_rect *clip, unsigned int pitch, unsigned int cpp)  {  	return clip->y1 * pitch + clip->x1 * cpp; @@ -45,6 +136,7 @@ EXPORT_SYMBOL(drm_fb_clip_offset);  static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_pixsize,  			 const void *vaddr, const struct drm_framebuffer *fb,  			 const struct drm_rect *clip, bool vaddr_cached_hint, +			 struct drm_format_conv_state *state,  			 void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))  {  	unsigned long linepixels = drm_rect_width(clip); @@ -60,7 +152,7 @@ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_p  	 * one line at a time.  	 */  	if (!vaddr_cached_hint) { -		stmp = kmalloc(sbuf_len, GFP_KERNEL); +		stmp = drm_format_conv_state_reserve(state, sbuf_len, GFP_KERNEL);  		if (!stmp)  			return -ENOMEM;  	} @@ -79,8 +171,6 @@ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_p  		dst += dst_pitch;  	} -	kfree(stmp); -  	return 0;  } @@ -88,6 +178,7 @@ static int __drm_fb_xfrm(void *dst, unsigned long dst_pitch, unsigned long dst_p  static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsigned long dst_pixsize,  			      const void *vaddr, const struct drm_framebuffer *fb,  			      const struct drm_rect *clip, bool vaddr_cached_hint, +			      struct drm_format_conv_state *state,  			      void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))  {  	unsigned long linepixels = drm_rect_width(clip); @@ -101,9 +192,9 @@ static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsign  	void *dbuf;  	if (vaddr_cached_hint) { -		dbuf = kmalloc(dbuf_len, GFP_KERNEL); +		dbuf = drm_format_conv_state_reserve(state, dbuf_len, GFP_KERNEL);  	} else { -		dbuf = kmalloc(stmp_off + sbuf_len, GFP_KERNEL); +		dbuf = drm_format_conv_state_reserve(state, stmp_off + sbuf_len, GFP_KERNEL);  		stmp = dbuf + stmp_off;  	}  	if (!dbuf) @@ -124,8 +215,6 @@ static int __drm_fb_xfrm_toio(void __iomem *dst, unsigned long dst_pitch, unsign  		dst += dst_pitch;  	} -	kfree(dbuf); -  	return 0;  } @@ -134,6 +223,7 @@ static int drm_fb_xfrm(struct iosys_map *dst,  		       const unsigned int *dst_pitch, const u8 *dst_pixsize,  		       const struct iosys_map *src, const struct drm_framebuffer *fb,  		       const struct drm_rect *clip, bool vaddr_cached_hint, +		       struct drm_format_conv_state *state,  		       void (*xfrm_line)(void *dbuf, const void *sbuf, unsigned int npixels))  {  	static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = { @@ -146,10 +236,12 @@ static int drm_fb_xfrm(struct iosys_map *dst,  	/* TODO: handle src in I/O memory here */  	if (dst[0].is_iomem)  		return __drm_fb_xfrm_toio(dst[0].vaddr_iomem, dst_pitch[0], dst_pixsize[0], -					  src[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line); +					  src[0].vaddr, fb, clip, vaddr_cached_hint, state, +					  xfrm_line);  	else  		return __drm_fb_xfrm(dst[0].vaddr, dst_pitch[0], dst_pixsize[0], -				     src[0].vaddr, fb, clip, vaddr_cached_hint, xfrm_line); +				     src[0].vaddr, fb, clip, vaddr_cached_hint, state, +				     xfrm_line);  }  /** @@ -235,6 +327,7 @@ static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy   * @cached: Source buffer is mapped cached (eg. not write-combined) + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and swaps per-pixel   * bytes during the process. Destination and framebuffer formats must match. The @@ -249,7 +342,8 @@ static void drm_fb_swab32_line(void *dbuf, const void *sbuf, unsigned int pixels   */  void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch,  		 const struct iosys_map *src, const struct drm_framebuffer *fb, -		 const struct drm_rect *clip, bool cached) +		 const struct drm_rect *clip, bool cached, +		 struct drm_format_conv_state *state)  {  	const struct drm_format_info *format = fb->format;  	u8 cpp = DIV_ROUND_UP(drm_format_info_bpp(format, 0), 8); @@ -268,7 +362,7 @@ void drm_fb_swab(struct iosys_map *dst, const unsigned int *dst_pitch,  		return;  	} -	drm_fb_xfrm(dst, dst_pitch, &cpp, src, fb, clip, cached, swab_line); +	drm_fb_xfrm(dst, dst_pitch, &cpp, src, fb, clip, cached, state, swab_line);  }  EXPORT_SYMBOL(drm_fb_swab); @@ -295,6 +389,7 @@ static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigne   * @src: Array of XRGB8888 source buffers   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts the   * color format during the process. Destination and framebuffer formats must match. The @@ -309,13 +404,13 @@ static void drm_fb_xrgb8888_to_rgb332_line(void *dbuf, const void *sbuf, unsigne   */  void drm_fb_xrgb8888_to_rgb332(struct iosys_map *dst, const unsigned int *dst_pitch,  			       const struct iosys_map *src, const struct drm_framebuffer *fb, -			       const struct drm_rect *clip) +			       const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		1,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_rgb332_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb332); @@ -364,6 +459,7 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf,   * @src: Array of XRGB8888 source buffer   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   * @swab: Swap bytes   *   * This function copies parts of a framebuffer to display memory and converts the @@ -379,7 +475,8 @@ static void drm_fb_xrgb8888_to_rgb565_swab_line(void *dbuf, const void *sbuf,   */  void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pitch,  			       const struct iosys_map *src, const struct drm_framebuffer *fb, -			       const struct drm_rect *clip, bool swab) +			       const struct drm_rect *clip, struct drm_format_conv_state *state, +			       bool swab)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		2, @@ -392,7 +489,7 @@ void drm_fb_xrgb8888_to_rgb565(struct iosys_map *dst, const unsigned int *dst_pi  	else  		xfrm_line = drm_fb_xrgb8888_to_rgb565_line; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, xfrm_line); +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, xfrm_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb565); @@ -421,6 +518,7 @@ static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsig   * @src: Array of XRGB8888 source buffer   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts   * the color format during the process. The parameters @dst, @dst_pitch and @@ -436,13 +534,13 @@ static void drm_fb_xrgb8888_to_xrgb1555_line(void *dbuf, const void *sbuf, unsig   */  void drm_fb_xrgb8888_to_xrgb1555(struct iosys_map *dst, const unsigned int *dst_pitch,  				 const struct iosys_map *src, const struct drm_framebuffer *fb, -				 const struct drm_rect *clip) +				 const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		2,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_xrgb1555_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb1555); @@ -473,6 +571,7 @@ static void drm_fb_xrgb8888_to_argb1555_line(void *dbuf, const void *sbuf, unsig   * @src: Array of XRGB8888 source buffer   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts   * the color format during the process. The parameters @dst, @dst_pitch and @@ -488,13 +587,13 @@ static void drm_fb_xrgb8888_to_argb1555_line(void *dbuf, const void *sbuf, unsig   */  void drm_fb_xrgb8888_to_argb1555(struct iosys_map *dst, const unsigned int *dst_pitch,  				 const struct iosys_map *src, const struct drm_framebuffer *fb, -				 const struct drm_rect *clip) +				 const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		2,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_argb1555_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb1555); @@ -525,6 +624,7 @@ static void drm_fb_xrgb8888_to_rgba5551_line(void *dbuf, const void *sbuf, unsig   * @src: Array of XRGB8888 source buffer   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts   * the color format during the process. The parameters @dst, @dst_pitch and @@ -540,13 +640,13 @@ static void drm_fb_xrgb8888_to_rgba5551_line(void *dbuf, const void *sbuf, unsig   */  void drm_fb_xrgb8888_to_rgba5551(struct iosys_map *dst, const unsigned int *dst_pitch,  				 const struct iosys_map *src, const struct drm_framebuffer *fb, -				 const struct drm_rect *clip) +				 const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		2,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_rgba5551_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgba5551); @@ -575,6 +675,7 @@ static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigne   * @src: Array of XRGB8888 source buffers   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts the   * color format during the process. Destination and framebuffer formats must match. The @@ -590,13 +691,13 @@ static void drm_fb_xrgb8888_to_rgb888_line(void *dbuf, const void *sbuf, unsigne   */  void drm_fb_xrgb8888_to_rgb888(struct iosys_map *dst, const unsigned int *dst_pitch,  			       const struct iosys_map *src, const struct drm_framebuffer *fb, -			       const struct drm_rect *clip) +			       const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		3,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_rgb888_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_rgb888); @@ -623,6 +724,7 @@ static void drm_fb_xrgb8888_to_argb8888_line(void *dbuf, const void *sbuf, unsig   * @src: Array of XRGB8888 source buffer   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts the   * color format during the process. The parameters @dst, @dst_pitch and @src refer @@ -638,13 +740,13 @@ static void drm_fb_xrgb8888_to_argb8888_line(void *dbuf, const void *sbuf, unsig   */  void drm_fb_xrgb8888_to_argb8888(struct iosys_map *dst, const unsigned int *dst_pitch,  				 const struct iosys_map *src, const struct drm_framebuffer *fb, -				 const struct drm_rect *clip) +				 const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		4,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_argb8888_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb8888); @@ -669,13 +771,14 @@ static void drm_fb_xrgb8888_to_abgr8888_line(void *dbuf, const void *sbuf, unsig  static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned int *dst_pitch,  					const struct iosys_map *src,  					const struct drm_framebuffer *fb, -					const struct drm_rect *clip) +					const struct drm_rect *clip, +					struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		4,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_abgr8888_line);  } @@ -699,13 +802,14 @@ static void drm_fb_xrgb8888_to_xbgr8888_line(void *dbuf, const void *sbuf, unsig  static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned int *dst_pitch,  					const struct iosys_map *src,  					const struct drm_framebuffer *fb, -					const struct drm_rect *clip) +					const struct drm_rect *clip, +					struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		4,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_xbgr8888_line);  } @@ -735,6 +839,7 @@ static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, un   * @src: Array of XRGB8888 source buffers   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts the   * color format during the process. Destination and framebuffer formats must match. The @@ -750,13 +855,14 @@ static void drm_fb_xrgb8888_to_xrgb2101010_line(void *dbuf, const void *sbuf, un   */  void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch,  				    const struct iosys_map *src, const struct drm_framebuffer *fb, -				    const struct drm_rect *clip) +				    const struct drm_rect *clip, +				    struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		4,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_xrgb2101010_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_xrgb2101010); @@ -788,6 +894,7 @@ static void drm_fb_xrgb8888_to_argb2101010_line(void *dbuf, const void *sbuf, un   * @src: Array of XRGB8888 source buffers   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts   * the color format during the process. The parameters @dst, @dst_pitch and @@ -803,13 +910,14 @@ static void drm_fb_xrgb8888_to_argb2101010_line(void *dbuf, const void *sbuf, un   */  void drm_fb_xrgb8888_to_argb2101010(struct iosys_map *dst, const unsigned int *dst_pitch,  				    const struct iosys_map *src, const struct drm_framebuffer *fb, -				    const struct drm_rect *clip) +				    const struct drm_rect *clip, +				    struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		4,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_argb2101010_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_argb2101010); @@ -839,6 +947,7 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned   * @src: Array of XRGB8888 source buffers   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts the   * color format during the process. Destination and framebuffer formats must match. The @@ -858,13 +967,13 @@ static void drm_fb_xrgb8888_to_gray8_line(void *dbuf, const void *sbuf, unsigned   */  void drm_fb_xrgb8888_to_gray8(struct iosys_map *dst, const unsigned int *dst_pitch,  			      const struct iosys_map *src, const struct drm_framebuffer *fb, -			      const struct drm_rect *clip) +			      const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES] = {  		1,  	}; -	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, +	drm_fb_xfrm(dst, dst_pitch, dst_pixsize, src, fb, clip, false, state,  		    drm_fb_xrgb8888_to_gray8_line);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8); @@ -878,6 +987,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8);   * @src:	The framebuffer memory to copy from   * @fb:		The framebuffer to copy from   * @clip:	Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory. If the   * formats of the display and the framebuffer mismatch, the blit function @@ -896,7 +1006,7 @@ EXPORT_SYMBOL(drm_fb_xrgb8888_to_gray8);   */  int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t dst_format,  		const struct iosys_map *src, const struct drm_framebuffer *fb, -		const struct drm_rect *clip) +		const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	uint32_t fb_format = fb->format->format; @@ -904,44 +1014,44 @@ int drm_fb_blit(struct iosys_map *dst, const unsigned int *dst_pitch, uint32_t d  		drm_fb_memcpy(dst, dst_pitch, src, fb, clip);  		return 0;  	} else if (fb_format == (dst_format | DRM_FORMAT_BIG_ENDIAN)) { -		drm_fb_swab(dst, dst_pitch, src, fb, clip, false); +		drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state);  		return 0;  	} else if (fb_format == (dst_format & ~DRM_FORMAT_BIG_ENDIAN)) { -		drm_fb_swab(dst, dst_pitch, src, fb, clip, false); +		drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state);  		return 0;  	} else if (fb_format == DRM_FORMAT_XRGB8888) {  		if (dst_format == DRM_FORMAT_RGB565) { -			drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, false); +			drm_fb_xrgb8888_to_rgb565(dst, dst_pitch, src, fb, clip, state, false);  			return 0;  		} else if (dst_format == DRM_FORMAT_XRGB1555) { -			drm_fb_xrgb8888_to_xrgb1555(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_xrgb1555(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_ARGB1555) { -			drm_fb_xrgb8888_to_argb1555(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_argb1555(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_RGBA5551) { -			drm_fb_xrgb8888_to_rgba5551(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_rgba5551(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_RGB888) { -			drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_rgb888(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_ARGB8888) { -			drm_fb_xrgb8888_to_argb8888(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_argb8888(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_XBGR8888) { -			drm_fb_xrgb8888_to_xbgr8888(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_xbgr8888(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_ABGR8888) { -			drm_fb_xrgb8888_to_abgr8888(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_abgr8888(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_XRGB2101010) { -			drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_xrgb2101010(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_ARGB2101010) { -			drm_fb_xrgb8888_to_argb2101010(dst, dst_pitch, src, fb, clip); +			drm_fb_xrgb8888_to_argb2101010(dst, dst_pitch, src, fb, clip, state);  			return 0;  		} else if (dst_format == DRM_FORMAT_BGRX8888) { -			drm_fb_swab(dst, dst_pitch, src, fb, clip, false); +			drm_fb_swab(dst, dst_pitch, src, fb, clip, false, state);  			return 0;  		}  	} @@ -978,6 +1088,7 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int   * @src: Array of XRGB8888 source buffers   * @fb: DRM framebuffer   * @clip: Clip rectangle area to copy + * @state: Transform and conversion state   *   * This function copies parts of a framebuffer to display memory and converts the   * color format during the process. Destination and framebuffer formats must match. The @@ -1002,7 +1113,7 @@ static void drm_fb_gray8_to_mono_line(void *dbuf, const void *sbuf, unsigned int   */  void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitch,  			     const struct iosys_map *src, const struct drm_framebuffer *fb, -			     const struct drm_rect *clip) +			     const struct drm_rect *clip, struct drm_format_conv_state *state)  {  	static const unsigned int default_dst_pitch[DRM_FORMAT_MAX_PLANES] = {  		0, 0, 0, 0 @@ -1042,7 +1153,7 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc  	 * Allocate a buffer to be used for both copying from the cma  	 * memory and to store the intermediate grayscale line pixels.  	 */ -	src32 = kmalloc(len_src32 + linepixels, GFP_KERNEL); +	src32 = drm_format_conv_state_reserve(state, len_src32 + linepixels, GFP_KERNEL);  	if (!src32)  		return; @@ -1056,8 +1167,6 @@ void drm_fb_xrgb8888_to_mono(struct iosys_map *dst, const unsigned int *dst_pitc  		vaddr += fb->pitches[0];  		mono += dst_pitch_0;  	} - -	kfree(src32);  }  EXPORT_SYMBOL(drm_fb_xrgb8888_to_mono); | 
