linux/drivers/gpu/drm/drm_fb_cma_helper.c
<<
>>
Prefs
   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 Device Inc.
   6 *   Author: Lars-Peter Clausen <lars@metafoo.de>
   7 *
   8 * Based on udl_fbdev.c
   9 *  Copyright (C) 2012 Red Hat
  10 */
  11
  12#include <drm/drm_fb_cma_helper.h>
  13#include <drm/drm_fourcc.h>
  14#include <drm/drm_framebuffer.h>
  15#include <drm/drm_gem_cma_helper.h>
  16#include <drm/drm_gem_framebuffer_helper.h>
  17#include <drm/drm_plane.h>
  18#include <linux/module.h>
  19
  20/**
  21 * DOC: framebuffer cma helper functions
  22 *
  23 * Provides helper functions for creating a cma (contiguous memory allocator)
  24 * backed framebuffer.
  25 *
  26 * drm_gem_fb_create() is used in the &drm_mode_config_funcs.fb_create
  27 * callback function to create a cma backed framebuffer.
  28 */
  29
  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 */
  39struct drm_gem_cma_object *drm_fb_cma_get_gem_obj(struct drm_framebuffer *fb,
  40                                                  unsigned int plane)
  41{
  42        struct drm_gem_object *gem;
  43
  44        gem = drm_gem_fb_get_obj(fb, plane);
  45        if (!gem)
  46                return NULL;
  47
  48        return to_drm_gem_cma_obj(gem);
  49}
  50EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_obj);
  51
  52/**
  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
  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 */
  63dma_addr_t drm_fb_cma_get_gem_addr(struct drm_framebuffer *fb,
  64                                   struct drm_plane_state *state,
  65                                   unsigned int plane)
  66{
  67        struct drm_gem_cma_object *obj;
  68        dma_addr_t paddr;
  69        u8 h_div = 1, v_div = 1;
  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;
  77
  78        obj = drm_fb_cma_get_gem_obj(fb, plane);
  79        if (!obj)
  80                return 0;
  81
  82        paddr = obj->paddr + fb->offsets[plane];
  83
  84        if (plane > 0) {
  85                h_div = fb->format->hsub;
  86                v_div = fb->format->vsub;
  87        }
  88
  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;
  96
  97        return paddr;
  98}
  99EXPORT_SYMBOL_GPL(drm_fb_cma_get_gem_addr);
 100