@@ -173,7 +173,7 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
{
struct drm_crtc *crtc = &rcrtc->crtc;
struct rcar_du_device *rcdu = crtc->dev->dev_private;
- struct drm_plane *plane;
+ unsigned int i;
if (rcrtc->started)
return;
@@ -198,7 +198,6 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
rcar_du_write(rcdu, DORCR, DORCR_DPRS);
rcar_du_crtc_set_display_timing(rcrtc);
- rcar_du_plane_setup(rcrtc->plane);
mutex_lock(&rcdu->planes.lock);
rcrtc->plane->enabled = true;
@@ -206,13 +205,13 @@ static void rcar_du_crtc_start(struct rcar_du_crtc *rcrtc)
mutex_unlock(&rcdu->planes.lock);
/* Setup planes. */
- list_for_each_entry(plane, &rcdu->ddev->mode_config.plane_list, head) {
- struct rcar_du_plane *rplane = to_rcar_plane(plane);
+ for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes); ++i) {
+ struct rcar_du_plane *plane = &rcdu->planes.planes[i];
- if (plane->crtc != crtc)
+ if (plane->crtc != crtc || !plane->enabled)
continue;
- rcar_du_plane_setup(rplane);
+ rcar_du_plane_setup(plane);
}
rcar_du_crtc_start_stop(rcrtc, true);
@@ -155,6 +155,10 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
for (i = 0; i < ARRAY_SIZE(rcdu->crtc); ++i)
rcar_du_crtc_create(rcdu, i);
+ ret = rcar_du_plane_register(rcdu);
+ if (ret < 0)
+ return ret;
+
drm_kms_helper_poll_init(rcdu->ddev);
drm_helper_disable_unused_functions(rcdu->ddev);
@@ -26,6 +26,16 @@
#define RCAR_DU_COLORKEY_SOURCE (1 << 24)
#define RCAR_DU_COLORKEY_MASK (1 << 24)
+struct rcar_du_kms_plane {
+ struct drm_plane plane;
+ struct rcar_du_plane *hwplane;
+};
+
+static inline struct rcar_du_plane *to_rcar_plane(struct drm_plane *plane)
+{
+ return container_of(plane, struct rcar_du_kms_plane, plane)->hwplane;
+}
+
static u32 rcar_du_plane_read(struct rcar_du_device *rcdu,
unsigned int index, u32 reg)
{
@@ -389,7 +399,6 @@ static const uint32_t formats[] = {
int rcar_du_plane_init(struct rcar_du_device *rcdu)
{
unsigned int i;
- int ret;
mutex_init(&rcdu->planes.lock);
rcdu->planes.free = 0xff;
@@ -417,13 +426,29 @@ int rcar_du_plane_init(struct rcar_du_device *rcdu)
plane->dev = rcdu;
plane->hwindex = -1;
plane->colorkey = RCAR_DU_COLORKEY_NONE;
- plane->zpos = 1;
+ plane->zpos = 0;
+ }
- /* Reserve one plane per CRTC */
- if (i < ARRAY_SIZE(rcdu->crtc)) {
- plane->zpos = 0;
- continue;
- }
+ return 0;
+}
+
+int rcar_du_plane_register(struct rcar_du_device *rcdu)
+{
+ unsigned int i;
+ int ret;
+
+ /* As at least one hardware plane will always be used by one of the
+ * CRTCs only register N-1 KMS planes.
+ */
+ for (i = 0; i < ARRAY_SIZE(rcdu->planes.planes) - 1; ++i) {
+ struct rcar_du_kms_plane *plane;
+
+ plane = devm_kzalloc(rcdu->dev, sizeof(*plane), GFP_KERNEL);
+ if (plane == NULL)
+ return -ENOMEM;
+
+ plane->hwplane = &rcdu->planes.planes[i + 1];
+ plane->hwplane->zpos = 1;
ret = drm_plane_init(rcdu->ddev, &plane->plane, 1,
&rcar_du_plane_funcs, formats,
@@ -14,16 +14,12 @@
#ifndef __RCAR_DU_PLANE_H__
#define __RCAR_DU_PLANE_H__
-#include <drm/drmP.h>
-#include <drm/drm_crtc.h>
-
+struct drm_crtc;
struct drm_framebuffer;
struct rcar_du_device;
struct rcar_du_format_info;
struct rcar_du_plane {
- struct drm_plane plane;
-
struct rcar_du_device *dev;
struct drm_crtc *crtc;
@@ -47,9 +43,8 @@ struct rcar_du_plane {
unsigned int dst_y;
};
-#define to_rcar_plane(p) container_of(p, struct rcar_du_plane, plane)
-
int rcar_du_plane_init(struct rcar_du_device *rcdu);
+int rcar_du_plane_register(struct rcar_du_device *rcdu);
void rcar_du_plane_setup(struct rcar_du_plane *plane);
void rcar_du_plane_update_base(struct rcar_du_plane *plane);
void rcar_du_plane_compute_base(struct rcar_du_plane *plane,