#include "exynos_drm_display.h"
#include "exynos_drm_gem.h"
#include "exynos_trace.h"
+#include "exynos_drm_plane.h"
#define KDS_WAITALL_MAX_TRIES 15
* Exynos specific crtc structure.
*
* @drm_crtc: crtc object.
- * @overlay: contain information common to display controller and hdmi and
- * contents of this overlay object would be copied to sub driver size.
* @current_fb: current fb that is being scanned out
* @event: vblank event that is currently queued for flip
+ * @plane: pointer of private plane object for this crtc
* @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
*/
struct exynos_drm_crtc {
struct drm_crtc drm_crtc;
- struct exynos_drm_overlay overlay;
struct drm_pending_vblank_event *event;
DECLARE_KFIFO(flip_fifo, struct exynos_drm_flip_desc, 2);
struct exynos_drm_flip_desc scanout_desc;
struct exynos_drm_display *display;
+ struct drm_plane *plane;
unsigned int pipe;
atomic_t flip_pending;
};
struct drm_display_mode *mode = &crtc->mode;
exynos_crtc = to_exynos_crtc(crtc);
- overlay = &exynos_crtc->overlay;
+ overlay = get_exynos_drm_overlay(exynos_crtc->plane);
memset(&pos, 0, sizeof(struct exynos_drm_crtc_pos));
to_exynos_fb(next_desc.fb)->rendered = true;
exynos_drm_crtc_update(crtc, next_desc.fb);
- exynos_drm_crtc_apply(crtc, &exynos_crtc->overlay);
+ exynos_drm_crtc_apply(crtc, get_exynos_drm_overlay(exynos_crtc->plane));
to_exynos_fb(next_desc.fb)->prepared = true;
if (exynos_crtc->event) {
if (display->controller_ops && display->controller_ops->mode_set)
display->controller_ops->mode_set(display->controller_ctx,
- &exynos_crtc->overlay);
+ get_exynos_drm_overlay(exynos_crtc->plane));
return 0;
}
to_exynos_fb(fb)->rendered = true;
if (!atomic_cmpxchg(&exynos_crtc->flip_pending, 0, 1)) {
+ struct exynos_drm_overlay *overlay;
+
+ overlay = get_exynos_drm_overlay(exynos_crtc->plane);
exynos_drm_crtc_update(crtc, fb);
- exynos_drm_crtc_apply(crtc, &exynos_crtc->overlay);
+ exynos_drm_crtc_apply(crtc, overlay);
to_exynos_fb(fb)->prepared = true;
}
}
if (kfifo_peek(&exynos_crtc->flip_fifo, &next_desc)) {
if (unlikely(to_exynos_fb(next_desc.fb)->rendered) &&
!atomic_cmpxchg(&exynos_crtc->flip_pending, 0, 1)) {
+ struct exynos_drm_overlay *overlay;
+
+ overlay = get_exynos_drm_overlay(exynos_crtc->plane);
exynos_drm_crtc_update(crtc, next_desc.fb);
- exynos_drm_crtc_apply(crtc, &exynos_crtc->overlay);
+ exynos_drm_crtc_apply(crtc, overlay);
to_exynos_fb(next_desc.fb)->prepared = true;
}
}
INIT_KFIFO(exynos_crtc->flip_fifo);
exynos_crtc->pipe = nr;
exynos_crtc->display = display;
- exynos_crtc->overlay.zpos = DEFAULT_ZPOS;
+
+ exynos_crtc->plane = exynos_plane_init(dev, 1 << nr, true);
+ if (!exynos_crtc->plane) {
+ kfree(exynos_crtc);
+ return -ENOMEM;
+ }
+
crtc = &exynos_crtc->drm_crtc;
private->crtc[nr] = crtc;
#include "exynos_drm_drv.h"
#include "exynos_drm_encoder.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;
.destroy = exynos_plane_destroy,
};
-int exynos_plane_init(struct drm_device *dev, unsigned int nr)
+struct drm_plane *exynos_plane_init(struct drm_device *dev,
+ unsigned int possible_crtcs, bool priv)
{
struct exynos_plane *exynos_plane;
- uint32_t possible_crtcs;
+ int err;
- DRM_DEBUG_KMS("[DEV:%s] nr: %u\n", dev->devname, nr);
+ DRM_DEBUG_KMS("[DEV:%s]\n", dev->devname);
exynos_plane = kzalloc(sizeof(struct exynos_plane), GFP_KERNEL);
- if (!exynos_plane)
- return -ENOMEM;
-
- /* all CRTCs are available */
- possible_crtcs = (1 << EXYNOS_DRM_DISPLAY_NUM_DISPLAYS) - 1;
+ if (!exynos_plane) {
+ DRM_ERROR("failed to allocate plane\n");
+ return NULL;
+ }
exynos_plane->overlay.zpos = DEFAULT_ZPOS;
- return drm_plane_init(dev, &exynos_plane->base, possible_crtcs,
+ err = drm_plane_init(dev, &exynos_plane->base, possible_crtcs,
&exynos_plane_funcs, formats, ARRAY_SIZE(formats),
- false);
+ priv);
+ if (err) {
+ DRM_ERROR("failed to initialize plane\n");
+ kfree(exynos_plane);
+ return NULL;
+ }
+
+ return &exynos_plane->base;
}
int exynos_plane_set_zpos_ioctl(struct drm_device *dev, void *data,
mutex_unlock(&dev->mode_config.mutex);
return ret;
}
+
+struct exynos_drm_overlay *get_exynos_drm_overlay(struct drm_plane *plane)
+{
+ struct exynos_plane *exynos_plane = to_exynos_plane(plane);
+
+ return &exynos_plane->overlay;
+}