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