Skip to content

Commit

Permalink
Merge branch 'exynos-drm-next' of git://git.infradead.org/users/kmpar…
Browse files Browse the repository at this point in the history
…k/linux-samsung into drm-core-next

* 'exynos-drm-next' of git://git.infradead.org/users/kmpark/linux-samsung:
  drm/exynos: Add plane support with fimd
  drm/exynos: add runtime pm feature for fimd
  drm/exynos: updated crtc and encoder dpms framework.
  drm/exynos: Use struct drm_mode_fb_cmd2
  drm/exynos: Fix compile errors
  • Loading branch information
Dave Airlie committed Dec 21, 2011
2 parents d0d110e + 864ee9e commit 3e54f5b
Show file tree
Hide file tree
Showing 13 changed files with 563 additions and 123 deletions.
3 changes: 2 additions & 1 deletion drivers/gpu/drm/exynos/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@
ccflags-y := -Iinclude/drm -Idrivers/gpu/drm/exynos
exynosdrm-y := exynos_drm_drv.o exynos_drm_encoder.o exynos_drm_connector.o \
exynos_drm_crtc.o exynos_drm_fbdev.o exynos_drm_fb.o \
exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o
exynos_drm_buf.o exynos_drm_gem.o exynos_drm_core.o \
exynos_drm_plane.o

obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o
obj-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o
59 changes: 53 additions & 6 deletions drivers/gpu/drm/exynos/exynos_drm_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,13 @@
* drm framework doesn't support multiple irq yet.
* we can refer to the crtc to current hardware interrupt occured through
* this pipe value.
* @dpms: store the crtc dpms value
*/
struct exynos_drm_crtc {
struct drm_crtc drm_crtc;
struct exynos_drm_overlay overlay;
unsigned int pipe;
unsigned int dpms;
};

static void exynos_drm_crtc_apply(struct drm_crtc *crtc)
Expand Down Expand Up @@ -153,26 +155,37 @@ static int exynos_drm_crtc_update(struct drm_crtc *crtc)

static void exynos_drm_crtc_dpms(struct drm_crtc *crtc, int mode)
{
struct drm_device *dev = crtc->dev;
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);

DRM_DEBUG_KMS("crtc[%d] mode[%d]\n", crtc->base.id, mode);

if (exynos_crtc->dpms == mode) {
DRM_DEBUG_KMS("desired dpms mode is same as previous one.\n");
return;
}

mutex_lock(&dev->struct_mutex);

switch (mode) {
case DRM_MODE_DPMS_ON:
exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
exynos_drm_encoder_crtc_commit);
exynos_drm_fn_encoder(crtc, &mode,
exynos_drm_encoder_crtc_dpms);
exynos_crtc->dpms = mode;
break;
case DRM_MODE_DPMS_STANDBY:
case DRM_MODE_DPMS_SUSPEND:
case DRM_MODE_DPMS_OFF:
/* TODO */
exynos_drm_fn_encoder(crtc, NULL,
exynos_drm_encoder_crtc_disable);
exynos_drm_fn_encoder(crtc, &mode,
exynos_drm_encoder_crtc_dpms);
exynos_crtc->dpms = mode;
break;
default:
DRM_DEBUG_KMS("unspecified mode %d\n", mode);
DRM_ERROR("unspecified mode %d\n", mode);
break;
}

mutex_unlock(&dev->struct_mutex);
}

static void exynos_drm_crtc_prepare(struct drm_crtc *crtc)
Expand All @@ -188,6 +201,28 @@ static void exynos_drm_crtc_commit(struct drm_crtc *crtc)

DRM_DEBUG_KMS("%s\n", __FILE__);

/*
* when set_crtc is requested from user or at booting time,
* crtc->commit would be called without dpms call so if dpms is
* no power on then crtc->dpms should be called
* with DRM_MODE_DPMS_ON for the hardware power to be on.
*/
if (exynos_crtc->dpms != DRM_MODE_DPMS_ON) {
int mode = DRM_MODE_DPMS_ON;

/*
* enable hardware(power on) to all encoders hdmi connected
* to current crtc.
*/
exynos_drm_crtc_dpms(crtc, mode);
/*
* enable dma to all encoders connected to current crtc and
* lcd panel.
*/
exynos_drm_fn_encoder(crtc, &mode,
exynos_drm_encoder_dpms_from_crtc);
}

exynos_drm_fn_encoder(crtc, &exynos_crtc->pipe,
exynos_drm_encoder_crtc_commit);
}
Expand Down Expand Up @@ -344,6 +379,8 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
}

exynos_crtc->pipe = nr;
exynos_crtc->dpms = DRM_MODE_DPMS_OFF;
exynos_crtc->overlay.zpos = DEFAULT_ZPOS;
crtc = &exynos_crtc->drm_crtc;

private->crtc[nr] = crtc;
Expand All @@ -357,9 +394,14 @@ int exynos_drm_crtc_create(struct drm_device *dev, unsigned int nr)
int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc)
{
struct exynos_drm_private *private = dev->dev_private;
struct exynos_drm_crtc *exynos_crtc =
to_exynos_crtc(private->crtc[crtc]);

DRM_DEBUG_KMS("%s\n", __FILE__);

if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
return -EPERM;

exynos_drm_fn_encoder(private->crtc[crtc], &crtc,
exynos_drm_enable_vblank);

Expand All @@ -369,9 +411,14 @@ int exynos_drm_crtc_enable_vblank(struct drm_device *dev, int crtc)
void exynos_drm_crtc_disable_vblank(struct drm_device *dev, int crtc)
{
struct exynos_drm_private *private = dev->dev_private;
struct exynos_drm_crtc *exynos_crtc =
to_exynos_crtc(private->crtc[crtc]);

DRM_DEBUG_KMS("%s\n", __FILE__);

if (exynos_crtc->dpms != DRM_MODE_DPMS_ON)
return;

exynos_drm_fn_encoder(private->crtc[crtc], &crtc,
exynos_drm_disable_vblank);
}
Expand Down
29 changes: 20 additions & 9 deletions drivers/gpu/drm/exynos/exynos_drm_drv.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "exynos_drm_fbdev.h"
#include "exynos_drm_fb.h"
#include "exynos_drm_gem.h"
#include "exynos_drm_plane.h"

#define DRIVER_NAME "exynos-drm"
#define DRIVER_DESC "Samsung SoC DRM"
Expand Down Expand Up @@ -77,6 +78,12 @@ static int exynos_drm_load(struct drm_device *dev, unsigned long flags)
goto err_crtc;
}

for (nr = 0; nr < MAX_PLANE; nr++) {
ret = exynos_plane_init(dev, nr);
if (ret)
goto err_crtc;
}

ret = drm_vblank_init(dev, MAX_CRTC);
if (ret)
goto err_crtc;
Expand Down Expand Up @@ -163,6 +170,18 @@ static struct drm_ioctl_desc exynos_ioctls[] = {
DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_GEM_MMAP,
exynos_drm_gem_mmap_ioctl, DRM_UNLOCKED | DRM_AUTH),
DRM_IOCTL_DEF_DRV(EXYNOS_PLANE_SET_ZPOS, exynos_plane_set_zpos_ioctl,
DRM_UNLOCKED | DRM_AUTH),
};

static const struct file_operations exynos_drm_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
.mmap = exynos_drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
.release = drm_release,
};

static struct drm_driver exynos_drm_driver = {
Expand All @@ -182,15 +201,7 @@ static struct drm_driver exynos_drm_driver = {
.dumb_map_offset = exynos_drm_gem_dumb_map_offset,
.dumb_destroy = exynos_drm_gem_dumb_destroy,
.ioctls = exynos_ioctls,
.fops = {
.owner = THIS_MODULE,
.open = drm_open,
.mmap = exynos_drm_gem_mmap,
.poll = drm_poll,
.read = drm_read,
.unlocked_ioctl = drm_ioctl,
.release = drm_release,
},
.fops = &exynos_drm_driver_fops,
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
.date = DRIVER_DATE,
Expand Down
14 changes: 10 additions & 4 deletions drivers/gpu/drm/exynos/exynos_drm_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
#include "drm.h"

#define MAX_CRTC 2
#define MAX_PLANE 5
#define DEFAULT_ZPOS -1

struct drm_device;
struct exynos_drm_overlay;
Expand All @@ -57,8 +59,8 @@ enum exynos_drm_output_type {
struct exynos_drm_overlay_ops {
void (*mode_set)(struct device *subdrv_dev,
struct exynos_drm_overlay *overlay);
void (*commit)(struct device *subdrv_dev);
void (*disable)(struct device *subdrv_dev);
void (*commit)(struct device *subdrv_dev, int zpos);
void (*disable)(struct device *subdrv_dev, int zpos);
};

/*
Expand All @@ -83,6 +85,7 @@ struct exynos_drm_overlay_ops {
* @dma_addr: bus(accessed by dma) address to the memory region allocated
* for a overlay.
* @vaddr: virtual memory addresss to this overlay.
* @zpos: order of overlay layer(z position).
* @default_win: a window to be enabled.
* @color_key: color key on or off.
* @index_color: if using color key feature then this value would be used
Expand Down Expand Up @@ -111,6 +114,7 @@ struct exynos_drm_overlay {
unsigned int pitch;
dma_addr_t dma_addr;
void __iomem *vaddr;
int zpos;

bool default_win;
bool color_key;
Expand Down Expand Up @@ -144,17 +148,19 @@ struct exynos_drm_display_ops {
/*
* Exynos drm manager ops
*
* @dpms: control device power.
* @apply: set timing, vblank and overlay data to registers.
* @mode_set: convert drm_display_mode to hw specific display mode and
* would be called by encoder->mode_set().
* @commit: set current hw specific display mode to hw.
* @disable: disable hardware specific display mode.
* @enable_vblank: specific driver callback for enabling vblank interrupt.
* @disable_vblank: specific driver callback for disabling vblank interrupt.
*/
struct exynos_drm_manager_ops {
void (*dpms)(struct device *subdrv_dev, int mode);
void (*apply)(struct device *subdrv_dev);
void (*mode_set)(struct device *subdrv_dev, void *mode);
void (*commit)(struct device *subdrv_dev);
void (*disable)(struct device *subdrv_dev);
int (*enable_vblank)(struct device *subdrv_dev);
void (*disable_vblank)(struct device *subdrv_dev);
};
Expand Down
Loading

0 comments on commit 3e54f5b

Please sign in to comment.