drm_fb_cma_helper.c 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. // SPDX-License-Identifier: GPL-2.0-or-later
  2. /*
  3. * drm kms/fb cma (contiguous memory allocator) helper functions
  4. *
  5. * Copyright (C) 2012 Analog Devices Inc.
  6. * Author: Lars-Peter Clausen <lars@metafoo.de>
  7. *
  8. * Based on udl_fbdev.c
  9. * Copyright (C) 2012 Red Hat
  10. */
  11. #include <drm/drm_fb_cma_helper.h>
  12. #include <drm/drm_fourcc.h>
  13. #include <drm/drm_framebuffer.h>
  14. #include <drm/drm_gem_cma_helper.h>
  15. #include <drm/drm_gem_framebuffer_helper.h>
  16. #include <drm/drm_plane.h>
  17. #include <linux/module.h>
  18. /**
  19. * DOC: framebuffer cma helper functions
  20. *
  21. * Provides helper functions for creating a cma (contiguous memory allocator)
  22. * backed framebuffer.
  23. *
  24. * drm_gem_fb_create() is used in the &drm_mode_config_funcs.fb_create
  25. * callback function to create a cma backed framebuffer.
  26. */
  27. /**
  28. * drm_fb_cma_get_gem_obj() - Get CMA GEM object for framebuffer
  29. * @fb: The framebuffer
  30. * @plane: Which plane
  31. *
  32. * Return the CMA GEM object for given framebuffer.
  33. *
  34. * This function will usually be called from the CRTC callback functions.
  35. */
  36. struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
  37. unsigned int plane)
  38. {
  39. struct drm_gem_object *gem;
  40. gem = drm_gem_fb_get_obj(fb, plane);
  41. if (!gem)
  42. return NULL;
  43. return to_drm_gem_cma_obj(gem);
  44. }
  45. EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
  46. /**
  47. * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel
  48. * formats where values are grouped in blocks this will get you the beginning of
  49. * the block
  50. * @fb: The framebuffer
  51. * @state: Which state of drm plane
  52. * @plane: Which plane
  53. * Return the CMA GEM address for given framebuffer.
  54. *
  55. * This function will usually be called from the PLANE callback functions.
  56. */
  57. dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
  58. struct drm_plane_state *state,
  59. unsigned int plane)
  60. {
  61. struct drm_gem_cma_object *obj;
  62. dma_addr_t paddr;
  63. u8 h_div = 1, v_div = 1;
  64. u32 block_w = drm_format_info_block_width(fb->format, plane);
  65. u32 block_h = drm_format_info_block_height(fb->format, plane);
  66. u32 block_size = fb->format->char_per_block[plane];
  67. u32 sample_x;
  68. u32 sample_y;
  69. u32 block_start_y;
  70. u32 num_hblocks;
  71. obj = drm_fb_cma_get_gem_obj(fb, plane);
  72. if (!obj)
  73. return 0;
  74. paddr = obj->paddr + fb->offsets[plane];
  75. if (plane > 0) {
  76. h_div = fb->format->hsub;
  77. v_div = fb->format->vsub;
  78. }
  79. sample_x = (state->src_x >> 16) / h_div;
  80. sample_y = (state->src_y >> 16) / v_div;
  81. block_start_y = (sample_y / block_h) * block_h;
  82. num_hblocks = sample_x / block_w;
  83. paddr += fb->pitches[plane] * block_start_y;
  84. paddr += block_size * num_hblocks;
  85. return paddr;
  86. }
  87. EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_addr);