Commit d6f7a18c 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 2nd pull request includes the following,
   - add configurable plane support and relevant cleanups.
   - fixup kernel panic issue at drm releasing.
   - remove unnecessary codes.

   This has been delayed to resolve a critical issue - which incurrs
   a kernel panic when driver is released - and review it.

* 'exynos-drm-next' of git://git.kernel.org/pub/scm/linux/kernel/git/daeinki/drm-exynos:
  drm/exynos: fix kernel panic issue at drm releasing
  drm/exynos: crtc: do not wait for the scanout completion
  drm/exynos: mixer: properly update all planes on the same vblank event
  drm/exynos: crtc: rework atomic_{begin,flush}
  drm/exynos: mixer: unify a check for video-processor window
  drm/exynos: mixer: also allow ARGB1555 and ARGB4444
  drm/exynos: mixer: refactor layer setup
  drm/exynos: mixer: remove all static blending setup
  drm/exynos: mixer: set window priority based on zpos
  drm/exynos: make zpos property configurable
  drm/exynos: rename zpos to index
parents 06249e69 c74d8eb5
...@@ -248,15 +248,16 @@ static void decon_shadow_protect_win(struct decon_context *ctx, int win, ...@@ -248,15 +248,16 @@ static void decon_shadow_protect_win(struct decon_context *ctx, int win,
protect ? ~0 : 0); protect ? ~0 : 0);
} }
static void decon_atomic_begin(struct exynos_drm_crtc *crtc, static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
struct exynos_drm_plane *plane)
{ {
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
int i;
if (test_bit(BIT_SUSPENDED, &ctx->flags)) if (test_bit(BIT_SUSPENDED, &ctx->flags))
return; return;
decon_shadow_protect_win(ctx, plane->zpos, true); for (i = ctx->first_win; i < WINDOWS_NR; i++)
decon_shadow_protect_win(ctx, i, true);
} }
#define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s)) #define BIT_VAL(x, e, s) (((x) & ((1 << ((e) - (s) + 1)) - 1)) << (s))
...@@ -270,7 +271,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -270,7 +271,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
to_exynos_plane_state(plane->base.state); to_exynos_plane_state(plane->base.state);
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
struct drm_framebuffer *fb = state->base.fb; struct drm_framebuffer *fb = state->base.fb;
unsigned int win = plane->zpos; unsigned int win = plane->index;
unsigned int bpp = fb->bits_per_pixel >> 3; unsigned int bpp = fb->bits_per_pixel >> 3;
unsigned int pitch = fb->pitches[0]; unsigned int pitch = fb->pitches[0];
dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0); dma_addr_t dma_addr = exynos_drm_fb_dma_addr(fb, 0);
...@@ -320,7 +321,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, ...@@ -320,7 +321,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
unsigned int win = plane->zpos; unsigned int win = plane->index;
if (test_bit(BIT_SUSPENDED, &ctx->flags)) if (test_bit(BIT_SUSPENDED, &ctx->flags))
return; return;
...@@ -336,15 +337,16 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, ...@@ -336,15 +337,16 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0); decon_set_bits(ctx, DECON_UPDATE, STANDALONE_UPDATE_F, ~0);
} }
static void decon_atomic_flush(struct exynos_drm_crtc *crtc, static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
struct exynos_drm_plane *plane)
{ {
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
int i;
if (test_bit(BIT_SUSPENDED, &ctx->flags)) if (test_bit(BIT_SUSPENDED, &ctx->flags))
return; return;
decon_shadow_protect_win(ctx, plane->zpos, false); for (i = ctx->first_win; i < WINDOWS_NR; i++)
decon_shadow_protect_win(ctx, i, false);
if (ctx->out_type == IFTYPE_I80) if (ctx->out_type == IFTYPE_I80)
set_bit(BIT_WIN_UPDATED, &ctx->flags); set_bit(BIT_WIN_UPDATED, &ctx->flags);
...@@ -502,7 +504,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) ...@@ -502,7 +504,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
ctx->configs[win].zpos = win; ctx->configs[win].zpos = win;
ctx->configs[win].type = decon_win_types[tmp]; ctx->configs[win].type = decon_win_types[tmp];
ret = exynos_plane_init(drm_dev, &ctx->planes[win], ret = exynos_plane_init(drm_dev, &ctx->planes[win], win,
1 << ctx->pipe, &ctx->configs[win]); 1 << ctx->pipe, &ctx->configs[win]);
if (ret) if (ret)
return ret; return ret;
......
...@@ -385,15 +385,16 @@ static void decon_shadow_protect_win(struct decon_context *ctx, ...@@ -385,15 +385,16 @@ static void decon_shadow_protect_win(struct decon_context *ctx,
writel(val, ctx->regs + SHADOWCON); writel(val, ctx->regs + SHADOWCON);
} }
static void decon_atomic_begin(struct exynos_drm_crtc *crtc, static void decon_atomic_begin(struct exynos_drm_crtc *crtc)
struct exynos_drm_plane *plane)
{ {
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
int i;
if (ctx->suspended) if (ctx->suspended)
return; return;
decon_shadow_protect_win(ctx, plane->zpos, true); for (i = 0; i < WINDOWS_NR; i++)
decon_shadow_protect_win(ctx, i, true);
} }
static void decon_update_plane(struct exynos_drm_crtc *crtc, static void decon_update_plane(struct exynos_drm_crtc *crtc,
...@@ -407,7 +408,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -407,7 +408,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
unsigned long val, alpha; unsigned long val, alpha;
unsigned int last_x; unsigned int last_x;
unsigned int last_y; unsigned int last_y;
unsigned int win = plane->zpos; unsigned int win = plane->index;
unsigned int bpp = fb->bits_per_pixel >> 3; unsigned int bpp = fb->bits_per_pixel >> 3;
unsigned int pitch = fb->pitches[0]; unsigned int pitch = fb->pitches[0];
...@@ -498,7 +499,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, ...@@ -498,7 +499,7 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
unsigned int win = plane->zpos; unsigned int win = plane->index;
u32 val; u32 val;
if (ctx->suspended) if (ctx->suspended)
...@@ -517,15 +518,16 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc, ...@@ -517,15 +518,16 @@ static void decon_disable_plane(struct exynos_drm_crtc *crtc,
writel(val, ctx->regs + DECON_UPDATE); writel(val, ctx->regs + DECON_UPDATE);
} }
static void decon_atomic_flush(struct exynos_drm_crtc *crtc, static void decon_atomic_flush(struct exynos_drm_crtc *crtc)
struct exynos_drm_plane *plane)
{ {
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
int i;
if (ctx->suspended) if (ctx->suspended)
return; return;
decon_shadow_protect_win(ctx, plane->zpos, false); for (i = 0; i < WINDOWS_NR; i++)
decon_shadow_protect_win(ctx, i, false);
} }
static void decon_init(struct decon_context *ctx) static void decon_init(struct decon_context *ctx)
...@@ -657,7 +659,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data) ...@@ -657,7 +659,7 @@ static int decon_bind(struct device *dev, struct device *master, void *data)
ctx->configs[i].zpos = i; ctx->configs[i].zpos = i;
ctx->configs[i].type = decon_win_types[i]; ctx->configs[i].type = decon_win_types[i];
ret = exynos_plane_init(drm_dev, &ctx->planes[i], ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
1 << ctx->pipe, &ctx->configs[i]); 1 << ctx->pipe, &ctx->configs[i]);
if (ret) if (ret)
return ret; return ret;
......
...@@ -68,32 +68,20 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc, ...@@ -68,32 +68,20 @@ static void exynos_crtc_atomic_begin(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state) struct drm_crtc_state *old_crtc_state)
{ {
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct drm_plane *plane;
exynos_crtc->event = crtc->state->event; exynos_crtc->event = crtc->state->event;
drm_atomic_crtc_for_each_plane(plane, crtc) {
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
if (exynos_crtc->ops->atomic_begin) if (exynos_crtc->ops->atomic_begin)
exynos_crtc->ops->atomic_begin(exynos_crtc, exynos_crtc->ops->atomic_begin(exynos_crtc);
exynos_plane);
}
} }
static void exynos_crtc_atomic_flush(struct drm_crtc *crtc, static void exynos_crtc_atomic_flush(struct drm_crtc *crtc,
struct drm_crtc_state *old_crtc_state) struct drm_crtc_state *old_crtc_state)
{ {
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc); struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct drm_plane *plane;
drm_atomic_crtc_for_each_plane(plane, crtc) {
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
if (exynos_crtc->ops->atomic_flush) if (exynos_crtc->ops->atomic_flush)
exynos_crtc->ops->atomic_flush(exynos_crtc, exynos_crtc->ops->atomic_flush(exynos_crtc);
exynos_plane);
}
} }
static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = { static const struct drm_crtc_helper_funcs exynos_crtc_helper_funcs = {
...@@ -215,29 +203,6 @@ void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, ...@@ -215,29 +203,6 @@ void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
spin_unlock_irqrestore(&crtc->dev->event_lock, flags); spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
} }
void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb)
{
struct exynos_drm_crtc *exynos_crtc;
struct drm_device *dev = fb->dev;
struct drm_crtc *crtc;
/*
* make sure that overlay data are updated to real hardware
* for all encoders.
*/
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
exynos_crtc = to_exynos_crtc(crtc);
/*
* wait for vblank interrupt
* - this makes sure that overlay data are updated to
* real hardware.
*/
if (exynos_crtc->ops->wait_for_vblank)
exynos_crtc->ops->wait_for_vblank(exynos_crtc);
}
}
int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
enum exynos_drm_output_type out_type) enum exynos_drm_output_type out_type)
{ {
...@@ -261,3 +226,29 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc) ...@@ -261,3 +226,29 @@ void exynos_drm_crtc_te_handler(struct drm_crtc *crtc)
if (exynos_crtc->ops->te_handler) if (exynos_crtc->ops->te_handler)
exynos_crtc->ops->te_handler(exynos_crtc); exynos_crtc->ops->te_handler(exynos_crtc);
} }
void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
struct drm_file *file)
{
struct exynos_drm_crtc *exynos_crtc = to_exynos_crtc(crtc);
struct drm_pending_vblank_event *e;
unsigned long flags;
spin_lock_irqsave(&crtc->dev->event_lock, flags);
e = exynos_crtc->event;
if (e && e->base.file_priv == file) {
exynos_crtc->event = NULL;
/*
* event will be destroyed by core part
* so below line should be removed later with core changes
*/
e->base.destroy(&e->base);
/*
* event_space will be increased by core part
* so below line should be removed later with core changes.
*/
file->event_space += sizeof(e->event);
atomic_dec(&exynos_crtc->pending_update);
}
spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
}
...@@ -28,7 +28,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe); ...@@ -28,7 +28,6 @@ void exynos_drm_crtc_disable_vblank(struct drm_device *dev, unsigned int pipe);
void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc); void exynos_drm_crtc_wait_pending_update(struct exynos_drm_crtc *exynos_crtc);
void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc, void exynos_drm_crtc_finish_update(struct exynos_drm_crtc *exynos_crtc,
struct exynos_drm_plane *exynos_plane); struct exynos_drm_plane *exynos_plane);
void exynos_drm_crtc_complete_scanout(struct drm_framebuffer *fb);
/* This function gets pipe value to crtc device matched with out_type. */ /* This function gets pipe value to crtc device matched with out_type. */
int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
...@@ -41,4 +40,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev, ...@@ -41,4 +40,8 @@ int exynos_drm_crtc_get_pipe_from_type(struct drm_device *drm_dev,
*/ */
void exynos_drm_crtc_te_handler(struct drm_crtc *crtc); void exynos_drm_crtc_te_handler(struct drm_crtc *crtc);
/* This function cancels a page flip request. */
void exynos_drm_crtc_cancel_page_flip(struct drm_crtc *crtc,
struct drm_file *file);
#endif #endif
...@@ -330,7 +330,12 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file) ...@@ -330,7 +330,12 @@ static int exynos_drm_open(struct drm_device *dev, struct drm_file *file)
static void exynos_drm_preclose(struct drm_device *dev, static void exynos_drm_preclose(struct drm_device *dev,
struct drm_file *file) struct drm_file *file)
{ {
struct drm_crtc *crtc;
exynos_drm_subdrv_close(dev, file); exynos_drm_subdrv_close(dev, file);
list_for_each_entry(crtc, &dev->mode_config.crtc_list, head)
exynos_drm_crtc_cancel_page_flip(crtc, file);
} }
static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file) static void exynos_drm_postclose(struct drm_device *dev, struct drm_file *file)
......
...@@ -64,6 +64,7 @@ struct exynos_drm_plane_state { ...@@ -64,6 +64,7 @@ struct exynos_drm_plane_state {
struct exynos_drm_rect src; struct exynos_drm_rect src;
unsigned int h_ratio; unsigned int h_ratio;
unsigned int v_ratio; unsigned int v_ratio;
unsigned int zpos;
}; };
static inline struct exynos_drm_plane_state * static inline struct exynos_drm_plane_state *
...@@ -76,7 +77,7 @@ to_exynos_plane_state(struct drm_plane_state *state) ...@@ -76,7 +77,7 @@ to_exynos_plane_state(struct drm_plane_state *state)
* Exynos drm common overlay structure. * Exynos drm common overlay structure.
* *
* @base: plane object * @base: plane object
* @zpos: order of overlay layer(z position). * @index: hardware index of the overlay layer
* *
* this structure is common to exynos SoC and its contents would be copied * this structure is common to exynos SoC and its contents would be copied
* to hardware specific overlay info. * to hardware specific overlay info.
...@@ -85,17 +86,18 @@ to_exynos_plane_state(struct drm_plane_state *state) ...@@ -85,17 +86,18 @@ to_exynos_plane_state(struct drm_plane_state *state)
struct exynos_drm_plane { struct exynos_drm_plane {
struct drm_plane base; struct drm_plane base;
const struct exynos_drm_plane_config *config; const struct exynos_drm_plane_config *config;
unsigned int zpos; unsigned int index;
struct drm_framebuffer *pending_fb; struct drm_framebuffer *pending_fb;
}; };
#define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0) #define EXYNOS_DRM_PLANE_CAP_DOUBLE (1 << 0)
#define EXYNOS_DRM_PLANE_CAP_SCALE (1 << 1) #define EXYNOS_DRM_PLANE_CAP_SCALE (1 << 1)
#define EXYNOS_DRM_PLANE_CAP_ZPOS (1 << 2)
/* /*
* Exynos DRM plane configuration structure. * Exynos DRM plane configuration structure.
* *
* @zpos: z-position of the plane. * @zpos: initial z-position of the plane.
* @type: type of the plane (primary, cursor or overlay). * @type: type of the plane (primary, cursor or overlay).
* @pixel_formats: supported pixel formats. * @pixel_formats: supported pixel formats.
* @num_pixel_formats: number of elements in 'pixel_formats'. * @num_pixel_formats: number of elements in 'pixel_formats'.
...@@ -121,8 +123,8 @@ struct exynos_drm_plane_config { ...@@ -121,8 +123,8 @@ struct exynos_drm_plane_config {
* @wait_for_vblank: wait for vblank interrupt to make sure that * @wait_for_vblank: wait for vblank interrupt to make sure that
* hardware overlay is updated. * hardware overlay is updated.
* @atomic_check: validate state * @atomic_check: validate state
* @atomic_begin: prepare a window to receive a update * @atomic_begin: prepare device to receive an update
* @atomic_flush: mark the end of a window update * @atomic_flush: mark the end of device update
* @update_plane: apply hardware specific overlay data to registers. * @update_plane: apply hardware specific overlay data to registers.
* @disable_plane: disable hardware specific overlay. * @disable_plane: disable hardware specific overlay.
* @te_handler: trigger to transfer video image at the tearing effect * @te_handler: trigger to transfer video image at the tearing effect
...@@ -142,14 +144,12 @@ struct exynos_drm_crtc_ops { ...@@ -142,14 +144,12 @@ struct exynos_drm_crtc_ops {
void (*wait_for_vblank)(struct exynos_drm_crtc *crtc); void (*wait_for_vblank)(struct exynos_drm_crtc *crtc);
int (*atomic_check)(struct exynos_drm_crtc *crtc, int (*atomic_check)(struct exynos_drm_crtc *crtc,
struct drm_crtc_state *state); struct drm_crtc_state *state);
void (*atomic_begin)(struct exynos_drm_crtc *crtc, void (*atomic_begin)(struct exynos_drm_crtc *crtc);
struct exynos_drm_plane *plane);
void (*update_plane)(struct exynos_drm_crtc *crtc, void (*update_plane)(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane); struct exynos_drm_plane *plane);
void (*disable_plane)(struct exynos_drm_crtc *crtc, void (*disable_plane)(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane); struct exynos_drm_plane *plane);
void (*atomic_flush)(struct exynos_drm_crtc *crtc, void (*atomic_flush)(struct exynos_drm_crtc *crtc);
struct exynos_drm_plane *plane);
void (*te_handler)(struct exynos_drm_crtc *crtc); void (*te_handler)(struct exynos_drm_crtc *crtc);
void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable); void (*clock_enable)(struct exynos_drm_crtc *crtc, bool enable);
}; };
......
...@@ -71,9 +71,6 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb) ...@@ -71,9 +71,6 @@ static void exynos_drm_fb_destroy(struct drm_framebuffer *fb)
struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb); struct exynos_drm_fb *exynos_fb = to_exynos_fb(fb);
unsigned int i; unsigned int i;
/* make sure that overlay data are updated before relesing fb. */
exynos_drm_crtc_complete_scanout(fb);
drm_framebuffer_cleanup(fb); drm_framebuffer_cleanup(fb);
for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) { for (i = 0; i < ARRAY_SIZE(exynos_fb->exynos_gem); i++) {
......
...@@ -622,26 +622,28 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx, ...@@ -622,26 +622,28 @@ static void fimd_shadow_protect_win(struct fimd_context *ctx,
writel(val, ctx->regs + reg); writel(val, ctx->regs + reg);
} }
static void fimd_atomic_begin(struct exynos_drm_crtc *crtc, static void fimd_atomic_begin(struct exynos_drm_crtc *crtc)
struct exynos_drm_plane *plane)
{ {
struct fimd_context *ctx = crtc->ctx; struct fimd_context *ctx = crtc->ctx;
int i;
if (ctx->suspended) if (ctx->suspended)
return; return;
fimd_shadow_protect_win(ctx, plane->zpos, true); for (i = 0; i < WINDOWS_NR; i++)
fimd_shadow_protect_win(ctx, i, true);
} }
static void fimd_atomic_flush(struct exynos_drm_crtc *crtc, static void fimd_atomic_flush(struct exynos_drm_crtc *crtc)
struct exynos_drm_plane *plane)
{ {
struct fimd_context *ctx = crtc->ctx; struct fimd_context *ctx = crtc->ctx;
int i;
if (ctx->suspended) if (ctx->suspended)
return; return;
fimd_shadow_protect_win(ctx, plane->zpos, false); for (i = 0; i < WINDOWS_NR; i++)
fimd_shadow_protect_win(ctx, i, false);
} }
static void fimd_update_plane(struct exynos_drm_crtc *crtc, static void fimd_update_plane(struct exynos_drm_crtc *crtc,
...@@ -654,7 +656,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, ...@@ -654,7 +656,7 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
dma_addr_t dma_addr; dma_addr_t dma_addr;
unsigned long val, size, offset; unsigned long val, size, offset;
unsigned int last_x, last_y, buf_offsize, line_size; unsigned int last_x, last_y, buf_offsize, line_size;
unsigned int win = plane->zpos; unsigned int win = plane->index;
unsigned int bpp = fb->bits_per_pixel >> 3; unsigned int bpp = fb->bits_per_pixel >> 3;
unsigned int pitch = fb->pitches[0]; unsigned int pitch = fb->pitches[0];
...@@ -740,7 +742,7 @@ static void fimd_disable_plane(struct exynos_drm_crtc *crtc, ...@@ -740,7 +742,7 @@ static void fimd_disable_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
struct fimd_context *ctx = crtc->ctx; struct fimd_context *ctx = crtc->ctx;
unsigned int win = plane->zpos; unsigned int win = plane->index;
if (ctx->suspended) if (ctx->suspended)
return; return;
...@@ -944,7 +946,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data) ...@@ -944,7 +946,7 @@ static int fimd_bind(struct device *dev, struct device *master, void *data)
ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats); ctx->configs[i].num_pixel_formats = ARRAY_SIZE(fimd_formats);
ctx->configs[i].zpos = i; ctx->configs[i].zpos = i;
ctx->configs[i].type = fimd_win_types[i]; ctx->configs[i].type = fimd_win_types[i];
ret = exynos_plane_init(drm_dev, &ctx->planes[i], ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
1 << ctx->pipe, &ctx->configs[i]); 1 << ctx->pipe, &ctx->configs[i]);
if (ret) if (ret)
return ret; return ret;
......
...@@ -124,6 +124,7 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state) ...@@ -124,6 +124,7 @@ static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
static void exynos_drm_plane_reset(struct drm_plane *plane) static void exynos_drm_plane_reset(struct drm_plane *plane)
{ {
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_plane_state *exynos_state; struct exynos_drm_plane_state *exynos_state;
if (plane->state) { if (plane->state) {
...@@ -136,6 +137,7 @@ static void exynos_drm_plane_reset(struct drm_plane *plane) ...@@ -136,6 +137,7 @@ static void exynos_drm_plane_reset(struct drm_plane *plane)
exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL); exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
if (exynos_state) { if (exynos_state) {
exynos_state->zpos = exynos_plane->config->zpos;
plane->state = &exynos_state->base; plane->state = &exynos_state->base;
plane->state->plane = plane; plane->state->plane = plane;
} }
...@@ -153,6 +155,7 @@ exynos_drm_plane_duplicate_state(struct drm_plane *plane) ...@@ -153,6 +155,7 @@ exynos_drm_plane_duplicate_state(struct drm_plane *plane)
return NULL; return NULL;
__drm_atomic_helper_plane_duplicate_state(plane, &copy->base); __drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
copy->zpos = exynos_state->zpos;
return &copy->base; return &copy->base;
} }
...@@ -165,13 +168,53 @@ static void exynos_drm_plane_destroy_state(struct drm_plane *plane, ...@@ -165,13 +168,53 @@ static void exynos_drm_plane_destroy_state(struct drm_plane *plane,
kfree(old_exynos_state); kfree(old_exynos_state);
} }
static int exynos_drm_plane_atomic_set_property(struct drm_plane *plane,
struct drm_plane_state *state,
struct drm_property *property,
uint64_t val)
{
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_plane_state *exynos_state =
to_exynos_plane_state(state);
struct exynos_drm_private *dev_priv = plane->dev->dev_private;
const struct exynos_drm_plane_config *config = exynos_plane->config;
if (property == dev_priv->plane_zpos_property &&
(config->capabilities & EXYNOS_DRM_PLANE_CAP_ZPOS))
exynos_state->zpos = val;
else
return -EINVAL;
return 0;
}
static int exynos_drm_plane_atomic_get_property(struct drm_plane *plane,
const struct drm_plane_state *state,
struct drm_property *property,
uint64_t *val)
{
const struct exynos_drm_plane_state *exynos_state =
container_of(state, const struct exynos_drm_plane_state, base);
struct exynos_drm_private *dev_priv = plane->dev->dev_private;
if (property == dev_priv->plane_zpos_property)
*val = exynos_state->zpos;
else
return -EINVAL;
return 0;
}
static struct drm_plane_funcs exynos_plane_funcs = { static struct drm_plane_funcs exynos_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane, .update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane, .disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup, .destroy = drm_plane_cleanup,
.set_property = drm_atomic_helper_plane_set_property,
.reset = exynos_drm_plane_reset, .reset = exynos_drm_plane_reset,
.atomic_duplicate_state = exynos_drm_plane_duplicate_state, .atomic_duplicate_state = exynos_drm_plane_duplicate_state,
.atomic_destroy_state = exynos_drm_plane_destroy_state, .atomic_destroy_state = exynos_drm_plane_destroy_state,
.atomic_set_property = exynos_drm_plane_atomic_set_property,
.atomic_get_property = exynos_drm_plane_atomic_get_property,
}; };
static int static int
...@@ -267,8 +310,8 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane, ...@@ -267,8 +310,8 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
prop = dev_priv->plane_zpos_property; prop = dev_priv->plane_zpos_property;
if (!prop) { if (!prop) {
prop = drm_property_create_range(dev, DRM_MODE_PROP_IMMUTABLE, prop = drm_property_create_range(dev, 0, "zpos",
"zpos", 0, MAX_PLANE - 1); 0, MAX_PLANE - 1);
if (!prop) if (!prop)
return; return;
...@@ -280,7 +323,7 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane, ...@@ -280,7 +323,7 @@ static void exynos_plane_attach_zpos_property(struct drm_plane *plane,
int exynos_plane_init(struct drm_device *dev, int exynos_plane_init(struct drm_device *dev,
struct exynos_drm_plane *exynos_plane, struct exynos_drm_plane *exynos_plane,
unsigned long possible_crtcs, unsigned int index, unsigned long possible_crtcs,
const struct exynos_drm_plane_config *config) const struct exynos_drm_plane_config *config)
{ {
int err; int err;
...@@ -298,12 +341,10 @@ int exynos_plane_init(struct drm_device *dev, ...@@ -298,12 +341,10 @@ int exynos_plane_init(struct drm_device *dev,
drm_plane_helper_add(&exynos_plane->base, &plane_helper_funcs); drm_plane_helper_add(&exynos_plane->base, &plane_helper_funcs);
exynos_plane->zpos = config->zpos; exynos_plane->index = index;
exynos_plane->config = config; exynos_plane->config = config;
if (config->type == DRM_PLANE_TYPE_OVERLAY) exynos_plane_attach_zpos_property(&exynos_plane->base, config->zpos);
exynos_plane_attach_zpos_property(&exynos_plane->base,
config->zpos);
return 0; return 0;
} }
...@@ -10,6 +10,6 @@ ...@@ -10,6 +10,6 @@
*/ */
int exynos_plane_init(struct drm_device *dev, int exynos_plane_init(struct drm_device *dev,
struct exynos_drm_plane *exynos_plane, struct exynos_drm_plane *exynos_plane, unsigned int index,
unsigned long possible_crtcs, unsigned long possible_crtcs,
const struct exynos_drm_plane_config *config); const struct exynos_drm_plane_config *config);
...@@ -461,7 +461,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data) ...@@ -461,7 +461,7 @@ static int vidi_bind(struct device *dev, struct device *master, void *data)
plane_config.zpos = i; plane_config.zpos = i;
plane_config.type = vidi_win_types[i]; plane_config.type = vidi_win_types[i];
ret = exynos_plane_init(drm_dev, &ctx->planes[i], ret = exynos_plane_init(drm_dev, &ctx->planes[i], i,
1 << ctx->pipe, &plane_config); 1 << ctx->pipe, &plane_config);
if (ret) if (ret)
return ret; return ret;
......
This diff is collapsed.
...@@ -113,6 +113,7 @@ ...@@ -113,6 +113,7 @@
#define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20) #define MXR_GRP_CFG_BLEND_PRE_MUL (1 << 20)
#define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17) #define MXR_GRP_CFG_WIN_BLEND_EN (1 << 17)
#define MXR_GRP_CFG_PIXEL_BLEND_EN (1 << 16) #define MXR_GRP_CFG_PIXEL_BLEND_EN (1 << 16)
#define MXR_GRP_CFG_MISC_MASK ((3 << 16) | (3 << 20))
#define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8) #define MXR_GRP_CFG_FORMAT_VAL(x) MXR_MASK_VAL(x, 11, 8)
#define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0) #define MXR_GRP_CFG_FORMAT_MASK MXR_GRP_CFG_FORMAT_VAL(~0)
#define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0) #define MXR_GRP_CFG_ALPHA_VAL(x) MXR_MASK_VAL(x, 7, 0)
...@@ -145,8 +146,11 @@ ...@@ -145,8 +146,11 @@
/* bit for MXR_LAYER_CFG */ /* bit for MXR_LAYER_CFG */
#define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8) #define MXR_LAYER_CFG_GRP1_VAL(x) MXR_MASK_VAL(x, 11, 8)
#define MXR_LAYER_CFG_GRP1_MASK MXR_LAYER_CFG_GRP1_VAL(~0)
#define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4) #define MXR_LAYER_CFG_GRP0_VAL(x) MXR_MASK_VAL(x, 7, 4)
#define MXR_LAYER_CFG_GRP0_MASK MXR_LAYER_CFG_GRP0_VAL(~0)
#define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0) #define MXR_LAYER_CFG_VP_VAL(x) MXR_MASK_VAL(x, 3, 0)
#define MXR_LAYER_CFG_VP_MASK MXR_LAYER_CFG_VP_VAL(~0)
#endif /* SAMSUNG_REGS_MIXER_H */ #endif /* SAMSUNG_REGS_MIXER_H */
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