Commit 923e0575 authored by Dave Airlie's avatar Dave Airlie

Merge branch 'exynos-drm-next' of...

Merge branch 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos into drm-next

  This pull request includes some code refactoring which removes
   Exynos specific structure names and uses generic structure
   names instead, and makes all plane updating to be done
   by only exynos_update_plane function. And also it includes
   some cleanup and fixup patches.

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos: (22 commits)
  drm/exynos: fimd: check error status for drm_iommu_attach_device
  drm/exynos: create exynos_check_plane()
  drm/exynos: remove mode_set() ops from exynos_crtc
  drm/exynos: don't duplicate drm_display_mode in fimd context
  drm/exynos: remove struct exynos_drm_manager
  drm/exynos: remove drm_dev from struct exynos_drm_manager
  drm/exynos: move 'type' from manager to crtc struct
  drm/exynos: remove pipe member of struct exynos_drm_manager
  drm/exynos: add pipe param to exynos_drm_crtc_create()
  drm/exynos: rename base object of struct exynos_drm_crtc to 'base'
  drm/exynos: remove exynos_drm_crtc_mode_set_commit()
  drm/exynos: call exynos_update_plane() directly on page flips
  drm/exynos: unify plane update on exynos_update_plane()
  drm/exynos: remove exynos_plane_commit() wrapper
  drm/exynos: don't do any DPMS operation while updating planes
  drm/exynos: Don't touch DPMS when updating overlay planes
  drm/exynos/vidi: remove useless ops->commit()
  drm/exynos/fimd: don't initialize 'ret' variable in fimd_probe()
  drm/exynos: remove struct exynos_drm_overlay
  drm/exynos: remove exynos_drm_crtc_plane_* wrappers
  ...
parents f43dff0e efa75bcd
This diff is collapsed.
......@@ -17,14 +17,18 @@
#include "exynos_drm_drv.h"
int exynos_drm_crtc_create(struct exynos_drm_manager *manager);
struct exynos_drm_crtc *exynos_drm_crtc_create(struct drm_device *drm_dev,
int pipe,
enum exynos_drm_output_type type,
struct exynos_drm_crtc_ops *ops,
void *context);
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int pipe);
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int pipe);
void exynos_drm_crtc_finish_pageflip(struct drm_device *dev, int pipe);
void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb);
void exynos_drm_crtc_plane_mode_set(struct drm_crtc *crtc,
struct exynos_drm_overlay *overlay);
struct exynos_drm_plane *plane);
void exynos_drm_crtc_plane_commit(struct drm_crtc *crtc, int zpos);
void exynos_drm_crtc_plane_enable(struct drm_crtc *crtc, int zpos);
void exynos_drm_crtc_plane_disable(struct drm_crtc *crtc, int zpos);
......
......@@ -23,6 +23,9 @@
#define MAX_FB_BUFFER 4
#define DEFAULT_ZPOS -1
#define to_exynos_crtc(x) container_of(x, struct exynos_drm_crtc, base)
#define to_exynos_plane(x) container_of(x, struct exynos_drm_plane, base)
/* This enumerates device type. */
enum exynos_drm_device_type {
EXYNOS_DEVICE_TYPE_NONE,
......@@ -44,6 +47,7 @@ enum exynos_drm_output_type {
/*
* Exynos drm common overlay structure.
*
* @base: plane object
* @fb_x: offset x on a framebuffer to be displayed.
* - the unit is screen coordinates.
* @fb_y: offset y on a framebuffer to be displayed.
......@@ -73,11 +77,14 @@ enum exynos_drm_output_type {
* @local_path: in case of lcd type, local path mode on or off.
* @transparency: transparency on or off.
* @activated: activated or not.
* @enabled: enabled or not.
*
* this structure is common to exynos SoC and its contents would be copied
* to hardware specific overlay info.
*/
struct exynos_drm_overlay {
struct exynos_drm_plane {
struct drm_plane base;
unsigned int fb_x;
unsigned int fb_y;
unsigned int fb_width;
......@@ -104,6 +111,7 @@ struct exynos_drm_overlay {
bool local_path:1;
bool transparency:1;
bool activated:1;
bool enabled:1;
};
/*
......@@ -155,11 +163,10 @@ struct exynos_drm_display {
};
/*
* Exynos drm manager ops
* Exynos drm crtc ops
*
* @dpms: control device power.
* @mode_fixup: fix mode data before applying it
* @mode_set: set the given mode to the manager
* @commit: set current hw specific display mode to hw.
* @enable_vblank: specific driver callback for enabling vblank interrupt.
* @disable_vblank: specific driver callback for disabling vblank interrupt.
......@@ -172,44 +179,56 @@ struct exynos_drm_display {
* @te_handler: trigger to transfer video image at the tearing effect
* synchronization signal if there is a page flip request.
*/
struct exynos_drm_manager;
struct exynos_drm_manager_ops {
void (*dpms)(struct exynos_drm_manager *mgr, int mode);
bool (*mode_fixup)(struct exynos_drm_manager *mgr,
struct exynos_drm_crtc;
struct exynos_drm_crtc_ops {
void (*dpms)(struct exynos_drm_crtc *crtc, int mode);
bool (*mode_fixup)(struct exynos_drm_crtc *crtc,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
void (*mode_set)(struct exynos_drm_manager *mgr,
const struct drm_display_mode *mode);
void (*commit)(struct exynos_drm_manager *mgr);
int (*enable_vblank)(struct exynos_drm_manager *mgr);
void (*disable_vblank)(struct exynos_drm_manager *mgr);
void (*wait_for_vblank)(struct exynos_drm_manager *mgr);
void (*win_mode_set)(struct exynos_drm_manager *mgr,
struct exynos_drm_overlay *overlay);
void (*win_commit)(struct exynos_drm_manager *mgr, int zpos);
void (*win_enable)(struct exynos_drm_manager *mgr, int zpos);
void (*win_disable)(struct exynos_drm_manager *mgr, int zpos);
void (*te_handler)(struct exynos_drm_manager *mgr);
void (*commit)(struct exynos_drm_crtc *crtc);
int (*enable_vblank)(struct exynos_drm_crtc *crtc);
void (*disable_vblank)(struct exynos_drm_crtc *crtc);
void (*wait_for_vblank)(struct exynos_drm_crtc *crtc);
void (*win_mode_set)(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane);
void (*win_commit)(struct exynos_drm_crtc *crtc, int zpos);
void (*win_enable)(struct exynos_drm_crtc *crtc, int zpos);
void (*win_disable)(struct exynos_drm_crtc *crtc, int zpos);
void (*te_handler)(struct exynos_drm_crtc *crtc);
};
enum exynos_crtc_mode {
CRTC_MODE_NORMAL, /* normal mode */
CRTC_MODE_BLANK, /* The private plane of crtc is blank */
};
/*
* Exynos drm common manager structure, maps 1:1 with a crtc
* Exynos specific crtc structure.
*
* @list: the list entry for this manager
* @base: crtc object.
* @type: one of EXYNOS_DISPLAY_TYPE_LCD and HDMI.
* @drm_dev: pointer to the drm device
* @crtc: crtc object.
* @pipe: the pipe number for this crtc/manager
* @pipe: a crtc index created at load() with a new crtc object creation
* and the crtc object would be set to private->crtc array
* to get a crtc object corresponding to this pipe from private->crtc
* array when irq interrupt occurred. the reason of using this pipe is that
* drm framework doesn't support multiple irq yet.
* we can refer to the crtc to current hardware interrupt occurred through
* this pipe value.
* @dpms: store the crtc dpms value
* @mode: store the crtc mode value
* @ops: pointer to callbacks for exynos drm specific functionality
* @ctx: A pointer to the manager's implementation specific context
* @ctx: A pointer to the crtc's implementation specific context
*/
struct exynos_drm_manager {
struct list_head list;
enum exynos_drm_output_type type;
struct drm_device *drm_dev;
struct drm_crtc *crtc;
int pipe;
struct exynos_drm_manager_ops *ops;
struct exynos_drm_crtc {
struct drm_crtc base;
enum exynos_drm_output_type type;
unsigned int pipe;
unsigned int dpms;
enum exynos_crtc_mode mode;
wait_queue_head_t pending_flip_queue;
atomic_t pending_flip;
struct exynos_drm_crtc_ops *ops;
void *ctx;
};
struct exynos_drm_g2d_private {
......
This diff is collapsed.
......@@ -12,20 +12,13 @@
#include <drm/drmP.h>
#include <drm/exynos_drm.h>
#include <drm/drm_plane_helper.h>
#include "exynos_drm_drv.h"
#include "exynos_drm_crtc.h"
#include "exynos_drm_fb.h"
#include "exynos_drm_gem.h"
#include "exynos_drm_plane.h"
#define to_exynos_plane(x) container_of(x, struct exynos_plane, base)
struct exynos_plane {
struct drm_plane base;
struct exynos_drm_overlay overlay;
bool enabled;
};
static const uint32_t formats[] = {
DRM_FORMAT_XRGB8888,
DRM_FORMAT_ARGB8888,
......@@ -69,16 +62,9 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
return size;
}
int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb)
{
struct exynos_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
unsigned int actual_w;
unsigned int actual_h;
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
int nr;
int i;
......@@ -91,12 +77,26 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
return -EFAULT;
}
overlay->dma_addr[i] = buffer->dma_addr;
exynos_plane->dma_addr[i] = buffer->dma_addr;
DRM_DEBUG_KMS("buffer: %d, dma_addr = 0x%lx\n",
i, (unsigned long)overlay->dma_addr[i]);
i, (unsigned long)exynos_plane->dma_addr[i]);
}
return 0;
}
void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
{
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
unsigned int actual_w;
unsigned int actual_h;
actual_w = exynos_plane_get_size(crtc_x, crtc_w, crtc->mode.hdisplay);
actual_h = exynos_plane_get_size(crtc_y, crtc_h, crtc->mode.vdisplay);
......@@ -113,84 +113,86 @@ int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
}
/* set drm framebuffer data. */
overlay->fb_x = src_x;
overlay->fb_y = src_y;
overlay->fb_width = fb->width;
overlay->fb_height = fb->height;
overlay->src_width = src_w;
overlay->src_height = src_h;
overlay->bpp = fb->bits_per_pixel;
overlay->pitch = fb->pitches[0];
overlay->pixel_format = fb->pixel_format;
/* set overlay range to be displayed. */
overlay->crtc_x = crtc_x;
overlay->crtc_y = crtc_y;
overlay->crtc_width = actual_w;
overlay->crtc_height = actual_h;
exynos_plane->fb_x = src_x;
exynos_plane->fb_y = src_y;
exynos_plane->fb_width = fb->width;
exynos_plane->fb_height = fb->height;
exynos_plane->src_width = src_w;
exynos_plane->src_height = src_h;
exynos_plane->bpp = fb->bits_per_pixel;
exynos_plane->pitch = fb->pitches[0];
exynos_plane->pixel_format = fb->pixel_format;
/* set plane range to be displayed. */
exynos_plane->crtc_x = crtc_x;
exynos_plane->crtc_y = crtc_y;
exynos_plane->crtc_width = actual_w;
exynos_plane->crtc_height = actual_h;
/* set drm mode data. */
overlay->mode_width = crtc->mode.hdisplay;
overlay->mode_height = crtc->mode.vdisplay;
overlay->refresh = crtc->mode.vrefresh;
overlay->scan_flag = crtc->mode.flags;
exynos_plane->mode_width = crtc->mode.hdisplay;
exynos_plane->mode_height = crtc->mode.vdisplay;
exynos_plane->refresh = crtc->mode.vrefresh;
exynos_plane->scan_flag = crtc->mode.flags;
DRM_DEBUG_KMS("overlay : offset_x/y(%d,%d), width/height(%d,%d)",
overlay->crtc_x, overlay->crtc_y,
overlay->crtc_width, overlay->crtc_height);
DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)",
exynos_plane->crtc_x, exynos_plane->crtc_y,
exynos_plane->crtc_width, exynos_plane->crtc_height);
plane->crtc = crtc;
exynos_drm_crtc_plane_mode_set(crtc, overlay);
return 0;
}
void exynos_plane_commit(struct drm_plane *plane)
{
struct exynos_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
exynos_drm_crtc_plane_commit(plane->crtc, overlay->zpos);
if (exynos_crtc->ops->win_mode_set)
exynos_crtc->ops->win_mode_set(exynos_crtc, exynos_plane);
}
void exynos_plane_dpms(struct drm_plane *plane, int mode)
{
struct exynos_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_overlay *overlay = &exynos_plane->overlay;
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(plane->crtc);
if (mode == DRM_MODE_DPMS_ON) {
if (exynos_plane->enabled)
return;
exynos_drm_crtc_plane_enable(plane->crtc, overlay->zpos);
if (exynos_crtc->ops->win_enable)
exynos_crtc->ops->win_enable(exynos_crtc,
exynos_plane->zpos);
exynos_plane->enabled = true;
} else {
if (!exynos_plane->enabled)
return;
exynos_drm_crtc_plane_disable(plane->crtc, overlay->zpos);
if (exynos_crtc->ops->win_disable)
exynos_crtc->ops->win_disable(exynos_crtc,
exynos_plane->zpos);
exynos_plane->enabled = false;
}
}
static int
int
exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
int ret;
ret = exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
crtc_w, crtc_h, src_x >> 16, src_y >> 16,
src_w >> 16, src_h >> 16);
ret = exynos_check_plane(plane, fb);
if (ret < 0)
return ret;
exynos_plane_commit(plane);
exynos_plane_dpms(plane, DRM_MODE_DPMS_ON);
exynos_plane_mode_set(plane, crtc, fb, crtc_x, crtc_y,
crtc_w, crtc_h, src_x >> 16, src_y >> 16,
src_w >> 16, src_h >> 16);
if (exynos_crtc->ops->win_commit)
exynos_crtc->ops->win_commit(exynos_crtc, exynos_plane->zpos);
return 0;
}
......@@ -204,7 +206,7 @@ static int exynos_disable_plane(struct drm_plane *plane)
static void exynos_plane_destroy(struct drm_plane *plane)
{
struct exynos_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
exynos_disable_plane(plane);
drm_plane_cleanup(plane);
......@@ -216,11 +218,11 @@ static int exynos_plane_set_property(struct drm_plane *plane,
uint64_t val)
{
struct drm_device *dev = plane->dev;
struct exynos_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_private *dev_priv = dev->dev_private;
if (property == dev_priv->plane_zpos_property) {
exynos_plane->overlay.zpos = val;
exynos_plane->zpos = val;
return 0;
}
......@@ -257,10 +259,10 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
unsigned long possible_crtcs,
enum drm_plane_type type)
{
struct exynos_plane *exynos_plane;
struct exynos_drm_plane *exynos_plane;
int err;
exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
exynos_plane = kzalloc(sizeof(struct exynos_drm_plane), GFP_KERNEL);
if (!exynos_plane)
return ERR_PTR(-ENOMEM);
......@@ -274,7 +276,7 @@ struct drm_plane *exynos_plane_init(struct drm_device *dev,
}
if (type == DRM_PLANE_TYPE_PRIMARY)
exynos_plane->overlay.zpos = DEFAULT_ZPOS;
exynos_plane->zpos = DEFAULT_ZPOS;
else
exynos_plane_attach_zpos_property(&exynos_plane->base);
......
......@@ -9,12 +9,17 @@
*
*/
int exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h);
void exynos_plane_commit(struct drm_plane *plane);
int exynos_check_plane(struct drm_plane *plane, struct drm_framebuffer *fb);
void exynos_plane_mode_set(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h);
int exynos_update_plane(struct drm_plane *plane, struct drm_crtc *crtc,
struct drm_framebuffer *fb, int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h);
void exynos_plane_dpms(struct drm_plane *plane, int mode);
struct drm_plane *exynos_plane_init(struct drm_device *dev,
unsigned long possible_crtcs,
......
......@@ -47,11 +47,10 @@ struct vidi_win_data {
};
struct vidi_context {
struct exynos_drm_manager manager;
struct exynos_drm_display display;
struct platform_device *pdev;
struct drm_device *drm_dev;
struct drm_crtc *crtc;
struct exynos_drm_crtc *crtc;
struct drm_encoder *encoder;
struct drm_connector connector;
struct vidi_win_data win_data[WINDOWS_NR];
......@@ -68,11 +67,6 @@ struct vidi_context {
int pipe;
};
static inline struct vidi_context *manager_to_vidi(struct exynos_drm_manager *m)
{
return container_of(m, struct vidi_context, manager);
}
static inline struct vidi_context *display_to_vidi(struct exynos_drm_display *d)
{
return container_of(d, struct vidi_context, display);
......@@ -103,34 +97,23 @@ static const char fake_edid_info[] = {
0x00, 0x00, 0x00, 0x06
};
static void vidi_apply(struct exynos_drm_manager *mgr)
static void vidi_apply(struct exynos_drm_crtc *crtc)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct exynos_drm_manager_ops *mgr_ops = mgr->ops;
struct vidi_context *ctx = crtc->ctx;
struct exynos_drm_crtc_ops *crtc_ops = crtc->ops;
struct vidi_win_data *win_data;
int i;
for (i = 0; i < WINDOWS_NR; i++) {
win_data = &ctx->win_data[i];
if (win_data->enabled && (mgr_ops && mgr_ops->win_commit))
mgr_ops->win_commit(mgr, i);
if (win_data->enabled && (crtc_ops && crtc_ops->win_commit))
crtc_ops->win_commit(crtc, i);
}
if (mgr_ops && mgr_ops->commit)
mgr_ops->commit(mgr);
}
static void vidi_commit(struct exynos_drm_manager *mgr)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
if (ctx->suspended)
return;
}
static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
static int vidi_enable_vblank(struct exynos_drm_crtc *crtc)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct vidi_context *ctx = crtc->ctx;
if (ctx->suspended)
return -EPERM;
......@@ -143,16 +126,16 @@ static int vidi_enable_vblank(struct exynos_drm_manager *mgr)
/*
* in case of page flip request, vidi_finish_pageflip function
* will not be called because direct_vblank is true and then
* that function will be called by manager_ops->win_commit callback
* that function will be called by crtc_ops->win_commit callback
*/
schedule_work(&ctx->work);
return 0;
}
static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
static void vidi_disable_vblank(struct exynos_drm_crtc *crtc)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct vidi_context *ctx = crtc->ctx;
if (ctx->suspended)
return;
......@@ -161,44 +144,44 @@ static void vidi_disable_vblank(struct exynos_drm_manager *mgr)
ctx->vblank_on = false;
}
static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
struct exynos_drm_overlay *overlay)
static void vidi_win_mode_set(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct vidi_context *ctx = crtc->ctx;
struct vidi_win_data *win_data;
int win;
unsigned long offset;
if (!overlay) {
DRM_ERROR("overlay is NULL\n");
if (!plane) {
DRM_ERROR("plane is NULL\n");
return;
}
win = overlay->zpos;
win = plane->zpos;
if (win == DEFAULT_ZPOS)
win = ctx->default_win;
if (win < 0 || win >= WINDOWS_NR)
return;
offset = overlay->fb_x * (overlay->bpp >> 3);
offset += overlay->fb_y * overlay->pitch;
offset = plane->fb_x * (plane->bpp >> 3);
offset += plane->fb_y * plane->pitch;
DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, overlay->pitch);
DRM_DEBUG_KMS("offset = 0x%lx, pitch = %x\n", offset, plane->pitch);
win_data = &ctx->win_data[win];
win_data->offset_x = overlay->crtc_x;
win_data->offset_y = overlay->crtc_y;
win_data->ovl_width = overlay->crtc_width;
win_data->ovl_height = overlay->crtc_height;
win_data->fb_width = overlay->fb_width;
win_data->fb_height = overlay->fb_height;
win_data->dma_addr = overlay->dma_addr[0] + offset;
win_data->bpp = overlay->bpp;
win_data->buf_offsize = (overlay->fb_width - overlay->crtc_width) *
(overlay->bpp >> 3);
win_data->line_size = overlay->crtc_width * (overlay->bpp >> 3);
win_data->offset_x = plane->crtc_x;
win_data->offset_y = plane->crtc_y;
win_data->ovl_width = plane->crtc_width;
win_data->ovl_height = plane->crtc_height;
win_data->fb_width = plane->fb_width;
win_data->fb_height = plane->fb_height;
win_data->dma_addr = plane->dma_addr[0] + offset;
win_data->bpp = plane->bpp;
win_data->buf_offsize = (plane->fb_width - plane->crtc_width) *
(plane->bpp >> 3);
win_data->line_size = plane->crtc_width * (plane->bpp >> 3);
/*
* some parts of win_data should be transferred to user side
......@@ -211,12 +194,12 @@ static void vidi_win_mode_set(struct exynos_drm_manager *mgr,
win_data->ovl_width, win_data->ovl_height);
DRM_DEBUG_KMS("paddr = 0x%lx\n", (unsigned long)win_data->dma_addr);
DRM_DEBUG_KMS("fb_width = %d, crtc_width = %d\n",
overlay->fb_width, overlay->crtc_width);
plane->fb_width, plane->crtc_width);
}
static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
static void vidi_win_commit(struct exynos_drm_crtc *crtc, int zpos)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct vidi_context *ctx = crtc->ctx;
struct vidi_win_data *win_data;
int win = zpos;
......@@ -239,9 +222,9 @@ static void vidi_win_commit(struct exynos_drm_manager *mgr, int zpos)
schedule_work(&ctx->work);
}
static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
static void vidi_win_disable(struct exynos_drm_crtc *crtc, int zpos)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct vidi_context *ctx = crtc->ctx;
struct vidi_win_data *win_data;
int win = zpos;
......@@ -257,9 +240,9 @@ static void vidi_win_disable(struct exynos_drm_manager *mgr, int zpos)
/* TODO. */
}
static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
static int vidi_power_on(struct exynos_drm_crtc *crtc, bool enable)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct vidi_context *ctx = crtc->ctx;
DRM_DEBUG_KMS("%s\n", __FILE__);
......@@ -271,9 +254,9 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
/* if vblank was enabled status, enable it again. */
if (test_and_clear_bit(0, &ctx->irq_flags))
vidi_enable_vblank(mgr);
vidi_enable_vblank(crtc);
vidi_apply(mgr);
vidi_apply(crtc);
} else {
ctx->suspended = true;
}
......@@ -281,9 +264,9 @@ static int vidi_power_on(struct exynos_drm_manager *mgr, bool enable)
return 0;
}
static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
static void vidi_dpms(struct exynos_drm_crtc *crtc, int mode)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct vidi_context *ctx = crtc->ctx;
DRM_DEBUG_KMS("%d\n", mode);
......@@ -291,12 +274,12 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
switch (mode) {
case DRM_MODE_DPMS_ON:
vidi_power_on(mgr, true);
vidi_power_on(crtc, true);
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
vidi_power_on(mgr, false);
vidi_power_on(crtc, false);
break;
default:
DRM_DEBUG_KMS("unspecified mode %d\n", mode);
......@@ -306,21 +289,19 @@ static void vidi_dpms(struct exynos_drm_manager *mgr, int mode)
mutex_unlock(&ctx->lock);
}
static int vidi_mgr_initialize(struct exynos_drm_manager *mgr,
static int vidi_ctx_initialize(struct vidi_context *ctx,
struct drm_device *drm_dev)
{
struct vidi_context *ctx = manager_to_vidi(mgr);
struct exynos_drm_private *priv = drm_dev->dev_private;
mgr->drm_dev = ctx->drm_dev = drm_dev;
mgr->pipe = ctx->pipe = priv->pipe++;
ctx->drm_dev = drm_dev;
ctx->pipe = priv->pipe++;
return 0;
}
static struct exynos_drm_manager_ops vidi_manager_ops = {
static struct exynos_drm_crtc_ops vidi_crtc_ops = {
.dpms = vidi_dpms,
.commit = vidi_commit,
.enable_vblank = vidi_enable_vblank,
.disable_vblank = vidi_disable_vblank,
.win_mode_set = vidi_win_mode_set,
......@@ -565,21 +546,21 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
{
struct vidi_context *ctx = dev_get_drvdata(dev);
struct drm_device *drm_dev = data;
struct drm_crtc *crtc = ctx->crtc;
int ret;
vidi_mgr_initialize(&ctx->manager, drm_dev);
ret = exynos_drm_crtc_create(&ctx->manager);
if (ret) {
ctx->crtc = exynos_drm_crtc_create(drm_dev, ctx->pipe,
EXYNOS_DISPLAY_TYPE_VIDI,
&vidi_crtc_ops, ctx);
if (IS_ERR(ctx->crtc)) {
DRM_ERROR("failed to create crtc.\n");
return ret;
return PTR_ERR(ctx->crtc);
}
vidi_ctx_initialize(ctx, drm_dev);
ret = exynos_drm_create_enc_conn(drm_dev, &ctx->display);
if (ret) {
crtc->funcs->destroy(crtc);
DRM_ERROR("failed to create encoder and connector.\n");
ctx->crtc->base.funcs->destroy(&ctx->crtc->base);
return ret;
}
......@@ -605,15 +586,13 @@ static int vidi_probe(struct platform_device *pdev)
if (!ctx)
return -ENOMEM;
ctx->manager.type = EXYNOS_DISPLAY_TYPE_VIDI;
ctx->manager.ops = &vidi_manager_ops;
ctx->display.type = EXYNOS_DISPLAY_TYPE_VIDI;
ctx->display.ops = &vidi_display_ops;
ctx->default_win = 0;
ctx->pdev = pdev;
ret = exynos_drm_component_add(&pdev->dev, EXYNOS_DEVICE_TYPE_CRTC,
ctx->manager.type);
EXYNOS_DISPLAY_TYPE_VIDI);
if (ret)
return ret;
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment