blob: 5f8074ffe7d9d5fe7ec47c3a3dbc4847ddd0c44e [file] [log] [blame]
Lars-Peter Clausen2e3b3c42012-07-02 16:37:47 +02001/*
2 * drm kms/fb cma (contiguous memory allocator) helper functions
3 *
4 * Copyright (C) 2012 Analog Device Inc.
5 * Author: Lars-Peter Clausen <lars@metafoo.de>
6 *
7 * Based on udl_fbdev.c
8 * Copyright (C) 2012 Red Hat
9 *
10 * This program is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU General Public License
12 * as published by the Free Software Foundation; either version 2
13 * of the License, or (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 */
19
Noralf Trønnes2de304b2019-01-14 13:10:59 +010020#include <drm/drm_fourcc.h>
Noralf Trønnes56286482017-08-13 15:31:45 +020021#include <drm/drm_framebuffer.h>
Lars-Peter Clausen2e3b3c42012-07-02 16:37:47 +020022#include <drm/drm_gem_cma_helper.h>
Noralf Trønnes56286482017-08-13 15:31:45 +020023#include <drm/drm_gem_framebuffer_helper.h>
Noralf Trønnes2de304b2019-01-14 13:10:59 +010024#include <drm/drm_plane.h>
Lars-Peter Clausen2e3b3c42012-07-02 16:37:47 +020025#include <linux/module.h>
26
Noralf Trønnes199c7712016-04-28 17:18:35 +020027/**
28 * DOC: framebuffer cma helper functions
29 *
30 * Provides helper functions for creating a cma (contiguous memory allocator)
31 * backed framebuffer.
32 *
Noralf Trønnesc0f095f2017-09-24 14:26:25 +020033 * drm_gem_fb_create() is used in the &drm_mode_config_funcs.fb_create
Noralf Trønnes02da16d2016-05-11 18:09:18 +020034 * callback function to create a cma backed framebuffer.
Noralf Trønnes199c7712016-04-28 17:18:35 +020035 */
36
Lars-Peter Clausen2e3b3c42012-07-02 16:37:47 +020037/**
38 * drm_fb_cma_get_gem_obj() - Get CMA GEM object for framebuffer
39 * @fb: The framebuffer
40 * @plane: Which plane
41 *
42 * Return the CMA GEM object for given framebuffer.
43 *
44 * This function will usually be called from the CRTC callback functions.
45 */
46struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
Daniel Vetter890358a2016-05-31 23:11:12 +020047 unsigned int plane)
Lars-Peter Clausen2e3b3c42012-07-02 16:37:47 +020048{
Noralf Trønnes56286482017-08-13 15:31:45 +020049 struct drm_gem_object *gem;
Lars-Peter Clausen2e3b3c42012-07-02 16:37:47 +020050
Noralf Trønnes56286482017-08-13 15:31:45 +020051 gem = drm_gem_fb_get_obj(fb, plane);
52 if (!gem)
Lars-Peter Clausen2e3b3c42012-07-02 16:37:47 +020053 return NULL;
54
Noralf Trønnes56286482017-08-13 15:31:45 +020055 return to_drm_gem_cma_obj(gem);
Lars-Peter Clausen2e3b3c42012-07-02 16:37:47 +020056}
57EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
58
Marek Vasut14d7f962016-11-14 11:07:31 +010059/**
Alexandru Gheorghe042bf752018-11-01 17:02:05 +000060 * drm_fb_cma_get_gem_addr() - Get physical address for framebuffer, for pixel
61 * formats where values are grouped in blocks this will get you the beginning of
62 * the block
Yannick Fertre4636ce92017-04-14 12:13:32 +020063 * @fb: The framebuffer
64 * @state: Which state of drm plane
65 * @plane: Which plane
66 * Return the CMA GEM address for given framebuffer.
67 *
68 * This function will usually be called from the PLANE callback functions.
69 */
70dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
71 struct drm_plane_state *state,
72 unsigned int plane)
73{
Noralf Trønnes56286482017-08-13 15:31:45 +020074 struct drm_gem_cma_object *obj;
Yannick Fertre4636ce92017-04-14 12:13:32 +020075 dma_addr_t paddr;
Ayan Kumar Halderc76abab2018-08-17 17:54:00 +010076 u8 h_div = 1, v_div = 1;
Alexandru Gheorghe042bf752018-11-01 17:02:05 +000077 u32 block_w = drm_format_info_block_width(fb->format, plane);
78 u32 block_h = drm_format_info_block_height(fb->format, plane);
79 u32 block_size = fb->format->char_per_block[plane];
80 u32 sample_x;
81 u32 sample_y;
82 u32 block_start_y;
83 u32 num_hblocks;
Yannick Fertre4636ce92017-04-14 12:13:32 +020084
Noralf Trønnes56286482017-08-13 15:31:45 +020085 obj = drm_fb_cma_get_gem_obj(fb, plane);
86 if (!obj)
Yannick Fertre4636ce92017-04-14 12:13:32 +020087 return 0;
88
Noralf Trønnes56286482017-08-13 15:31:45 +020089 paddr = obj->paddr + fb->offsets[plane];
Ayan Kumar Halderc76abab2018-08-17 17:54:00 +010090
91 if (plane > 0) {
92 h_div = fb->format->hsub;
93 v_div = fb->format->vsub;
94 }
95
Alexandru Gheorghe042bf752018-11-01 17:02:05 +000096 sample_x = (state->src_x >> 16) / h_div;
97 sample_y = (state->src_y >> 16) / v_div;
98 block_start_y = (sample_y / block_h) * block_h;
99 num_hblocks = sample_x / block_w;
100
101 paddr += fb->pitches[plane] * block_start_y;
102 paddr += block_size * num_hblocks;
Yannick Fertre4636ce92017-04-14 12:13:32 +0200103
104 return paddr;
105}
106EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_addr);