linux/drivers/gpu/drm/sti/sti_layer.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) STMicroelectronics SA 2014
   3 * Authors: Benjamin Gaignard <benjamin.gaignard@st.com>
   4 *          Fabien Dessenne <fabien.dessenne@st.com>
   5 *          for STMicroelectronics.
   6 * License terms:  GNU General Public License (GPL), version 2
   7 */
   8
   9#include <drm/drmP.h>
  10#include <drm/drm_gem_cma_helper.h>
  11#include <drm/drm_fb_cma_helper.h>
  12
  13#include "sti_compositor.h"
  14#include "sti_cursor.h"
  15#include "sti_gdp.h"
  16#include "sti_hqvdp.h"
  17#include "sti_layer.h"
  18#include "sti_vid.h"
  19
  20const char *sti_layer_to_str(struct sti_layer *layer)
  21{
  22        switch (layer->desc) {
  23        case STI_GDP_0:
  24                return "GDP0";
  25        case STI_GDP_1:
  26                return "GDP1";
  27        case STI_GDP_2:
  28                return "GDP2";
  29        case STI_GDP_3:
  30                return "GDP3";
  31        case STI_VID_0:
  32                return "VID0";
  33        case STI_VID_1:
  34                return "VID1";
  35        case STI_CURSOR:
  36                return "CURSOR";
  37        case STI_HQVDP_0:
  38                return "HQVDP0";
  39        default:
  40                return "<UNKNOWN LAYER>";
  41        }
  42}
  43EXPORT_SYMBOL(sti_layer_to_str);
  44
  45struct sti_layer *sti_layer_create(struct device *dev, int desc,
  46                                   void __iomem *baseaddr)
  47{
  48
  49        struct sti_layer *layer = NULL;
  50
  51        switch (desc & STI_LAYER_TYPE_MASK) {
  52        case STI_GDP:
  53                layer = sti_gdp_create(dev, desc);
  54                break;
  55        case STI_VID:
  56                layer = sti_vid_create(dev);
  57                break;
  58        case STI_CUR:
  59                layer = sti_cursor_create(dev);
  60                break;
  61        case STI_VDP:
  62                layer = sti_hqvdp_create(dev);
  63                break;
  64        }
  65
  66        if (!layer) {
  67                DRM_ERROR("Failed to create layer\n");
  68                return NULL;
  69        }
  70
  71        layer->desc = desc;
  72        layer->dev = dev;
  73        layer->regs = baseaddr;
  74
  75        layer->ops->init(layer);
  76
  77        DRM_DEBUG_DRIVER("%s created\n", sti_layer_to_str(layer));
  78
  79        return layer;
  80}
  81EXPORT_SYMBOL(sti_layer_create);
  82
  83int sti_layer_prepare(struct sti_layer *layer,
  84                      struct drm_crtc *crtc,
  85                      struct drm_framebuffer *fb,
  86                      struct drm_display_mode *mode, int mixer_id,
  87                      int dest_x, int dest_y, int dest_w, int dest_h,
  88                      int src_x, int src_y, int src_w, int src_h)
  89{
  90        int ret;
  91        unsigned int i;
  92        struct drm_gem_cma_object *cma_obj;
  93
  94        if (!layer || !fb || !mode) {
  95                DRM_ERROR("Null fb, layer or mode\n");
  96                return 1;
  97        }
  98
  99        cma_obj = drm_fb_cma_get_gem_obj(fb, 0);
 100        if (!cma_obj) {
 101                DRM_ERROR("Can't get CMA GEM object for fb\n");
 102                return 1;
 103        }
 104
 105        layer->crtc = crtc;
 106        layer->fb = fb;
 107        layer->mode = mode;
 108        layer->mixer_id = mixer_id;
 109        layer->dst_x = dest_x;
 110        layer->dst_y = dest_y;
 111        layer->dst_w = clamp_val(dest_w, 0, mode->crtc_hdisplay - dest_x);
 112        layer->dst_h = clamp_val(dest_h, 0, mode->crtc_vdisplay - dest_y);
 113        layer->src_x = src_x;
 114        layer->src_y = src_y;
 115        layer->src_w = src_w;
 116        layer->src_h = src_h;
 117        layer->format = fb->pixel_format;
 118        layer->vaddr = cma_obj->vaddr;
 119        layer->paddr = cma_obj->paddr;
 120        for (i = 0; i < 4; i++) {
 121                layer->pitches[i] = fb->pitches[i];
 122                layer->offsets[i] = fb->offsets[i];
 123        }
 124
 125        DRM_DEBUG_DRIVER("%s is associated with mixer_id %d\n",
 126                         sti_layer_to_str(layer),
 127                         layer->mixer_id);
 128        DRM_DEBUG_DRIVER("%s dst=(%dx%d)@(%d,%d) - src=(%dx%d)@(%d,%d)\n",
 129                         sti_layer_to_str(layer),
 130                         layer->dst_w, layer->dst_h, layer->dst_x, layer->dst_y,
 131                         layer->src_w, layer->src_h, layer->src_x,
 132                         layer->src_y);
 133
 134        DRM_DEBUG_DRIVER("drm FB:%d format:%.4s phys@:0x%lx\n", fb->base.id,
 135                         (char *)&layer->format, (unsigned long)layer->paddr);
 136
 137        if (!layer->ops->prepare)
 138                goto err_no_prepare;
 139
 140        ret = layer->ops->prepare(layer, !layer->enabled);
 141        if (!ret)
 142                layer->enabled = true;
 143
 144        return ret;
 145
 146err_no_prepare:
 147        DRM_ERROR("Cannot prepare\n");
 148        return 1;
 149}
 150
 151int sti_layer_commit(struct sti_layer *layer)
 152{
 153        if (!layer)
 154                return 1;
 155
 156        if (!layer->ops->commit)
 157                goto err_no_commit;
 158
 159        return layer->ops->commit(layer);
 160
 161err_no_commit:
 162        DRM_ERROR("Cannot commit\n");
 163        return 1;
 164}
 165
 166int sti_layer_disable(struct sti_layer *layer)
 167{
 168        int ret;
 169
 170        DRM_DEBUG_DRIVER("%s\n", sti_layer_to_str(layer));
 171        if (!layer)
 172                return 1;
 173
 174        if (!layer->enabled)
 175                return 0;
 176
 177        if (!layer->ops->disable)
 178                goto err_no_disable;
 179
 180        ret = layer->ops->disable(layer);
 181        if (!ret)
 182                layer->enabled = false;
 183        else
 184                DRM_ERROR("Disable failed\n");
 185
 186        return ret;
 187
 188err_no_disable:
 189        DRM_ERROR("Cannot disable\n");
 190        return 1;
 191}
 192
 193const uint32_t *sti_layer_get_formats(struct sti_layer *layer)
 194{
 195        if (!layer)
 196                return NULL;
 197
 198        if (!layer->ops->get_formats)
 199                return NULL;
 200
 201        return layer->ops->get_formats(layer);
 202}
 203
 204unsigned int sti_layer_get_nb_formats(struct sti_layer *layer)
 205{
 206        if (!layer)
 207                return 0;
 208
 209        if (!layer->ops->get_nb_formats)
 210                return 0;
 211
 212        return layer->ops->get_nb_formats(layer);
 213}
 214