Skip to content

Commit

Permalink
Merge tag 'du-next-20190318' of git://linuxtv.org/pinchartl/media int…
Browse files Browse the repository at this point in the history
…o drm-next

Renesas display drivers changes for v5.2:

- Display writeback (includes VSP changes and DRM/KMS API changes)
(All v4l patches acked by Mauro)
Signed-off-by: Dave Airlie <airlied@redhat.com>

From: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Link: https://patchwork.freedesktop.org/patch/msgid/20190318153613.GE12707@pendragon.ideasonboard.com
  • Loading branch information
Dave Airlie committed Mar 25, 2019
2 parents b9e687f + 12e32f5 commit 535f6f5
Show file tree
Hide file tree
Showing 40 changed files with 774 additions and 199 deletions.
3 changes: 1 addition & 2 deletions drivers/gpu/drm/arm/malidp_mw.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,7 @@ void malidp_mw_atomic_commit(struct drm_device *drm,
&mw_state->addrs[0],
mw_state->format);

drm_writeback_queue_job(mw_conn, conn_state->writeback_job);
conn_state->writeback_job = NULL;
drm_writeback_queue_job(mw_conn, conn_state);
hwdev->hw->enable_memwrite(hwdev, mw_state->addrs,
mw_state->pitches, mw_state->n_planes,
fb->width, fb->height, mw_state->format,
Expand Down
11 changes: 11 additions & 0 deletions drivers/gpu/drm/drm_atomic_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -2261,10 +2261,21 @@ EXPORT_SYMBOL(drm_atomic_helper_commit_cleanup_done);
int drm_atomic_helper_prepare_planes(struct drm_device *dev,
struct drm_atomic_state *state)
{
struct drm_connector *connector;
struct drm_connector_state *new_conn_state;
struct drm_plane *plane;
struct drm_plane_state *new_plane_state;
int ret, i, j;

for_each_new_connector_in_state(state, connector, new_conn_state, i) {
if (!new_conn_state->writeback_job)
continue;

ret = drm_writeback_prepare_job(new_conn_state->writeback_job);
if (ret < 0)
return ret;
}

for_each_new_plane_in_state(state, plane, new_plane_state, i) {
const struct drm_plane_helper_funcs *funcs;

Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/drm_atomic_state_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <drm/drm_connector.h>
#include <drm/drm_atomic.h>
#include <drm/drm_device.h>
#include <drm/drm_writeback.h>

#include <linux/slab.h>
#include <linux/dma-fence.h>
Expand Down Expand Up @@ -412,6 +413,9 @@ __drm_atomic_helper_connector_destroy_state(struct drm_connector_state *state)

if (state->commit)
drm_crtc_commit_put(state->commit);

if (state->writeback_job)
drm_writeback_cleanup_job(state->writeback_job);
}
EXPORT_SYMBOL(__drm_atomic_helper_connector_destroy_state);

Expand Down
31 changes: 8 additions & 23 deletions drivers/gpu/drm/drm_atomic_uapi.c
Original file line number Diff line number Diff line change
Expand Up @@ -647,28 +647,15 @@ drm_atomic_plane_get_property(struct drm_plane *plane,
return 0;
}

static struct drm_writeback_job *
drm_atomic_get_writeback_job(struct drm_connector_state *conn_state)
{
WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK);

if (!conn_state->writeback_job)
conn_state->writeback_job =
kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL);

return conn_state->writeback_job;
}

static int drm_atomic_set_writeback_fb_for_connector(
struct drm_connector_state *conn_state,
struct drm_framebuffer *fb)
{
struct drm_writeback_job *job =
drm_atomic_get_writeback_job(conn_state);
if (!job)
return -ENOMEM;
int ret;

drm_framebuffer_assign(&job->fb, fb);
ret = drm_writeback_set_fb(conn_state, fb);
if (ret < 0)
return ret;

if (fb)
DRM_DEBUG_ATOMIC("Set [FB:%d] for connector state %p\n",
Expand Down Expand Up @@ -1158,19 +1145,17 @@ static int prepare_signaling(struct drm_device *dev,

for_each_new_connector_in_state(state, conn, conn_state, i) {
struct drm_writeback_connector *wb_conn;
struct drm_writeback_job *job;
struct drm_out_fence_state *f;
struct dma_fence *fence;
s32 __user *fence_ptr;

if (!conn_state->writeback_job)
continue;

fence_ptr = get_out_fence_for_connector(state, conn);
if (!fence_ptr)
continue;

job = drm_atomic_get_writeback_job(conn_state);
if (!job)
return -ENOMEM;

f = krealloc(*fence_state, sizeof(**fence_state) *
(*num_fences + 1), GFP_KERNEL);
if (!f)
Expand All @@ -1192,7 +1177,7 @@ static int prepare_signaling(struct drm_device *dev,
return ret;
}

job->out_fence = fence;
conn_state->writeback_job->out_fence = fence;
}

/*
Expand Down
73 changes: 65 additions & 8 deletions drivers/gpu/drm/drm_writeback.c
Original file line number Diff line number Diff line change
Expand Up @@ -239,14 +239,52 @@ int drm_writeback_connector_init(struct drm_device *dev,
}
EXPORT_SYMBOL(drm_writeback_connector_init);

int drm_writeback_set_fb(struct drm_connector_state *conn_state,
struct drm_framebuffer *fb)
{
WARN_ON(conn_state->connector->connector_type != DRM_MODE_CONNECTOR_WRITEBACK);

if (!conn_state->writeback_job) {
conn_state->writeback_job =
kzalloc(sizeof(*conn_state->writeback_job), GFP_KERNEL);
if (!conn_state->writeback_job)
return -ENOMEM;

conn_state->writeback_job->connector =
drm_connector_to_writeback(conn_state->connector);
}

drm_framebuffer_assign(&conn_state->writeback_job->fb, fb);
return 0;
}

int drm_writeback_prepare_job(struct drm_writeback_job *job)
{
struct drm_writeback_connector *connector = job->connector;
const struct drm_connector_helper_funcs *funcs =
connector->base.helper_private;
int ret;

if (funcs->prepare_writeback_job) {
ret = funcs->prepare_writeback_job(connector, job);
if (ret < 0)
return ret;
}

job->prepared = true;
return 0;
}
EXPORT_SYMBOL(drm_writeback_prepare_job);

/**
* drm_writeback_queue_job - Queue a writeback job for later signalling
* @wb_connector: The writeback connector to queue a job on
* @job: The job to queue
* @conn_state: The connector state containing the job to queue
*
* This function adds a job to the job_queue for a writeback connector. It
* should be considered to take ownership of the writeback job, and so any other
* references to the job must be cleared after calling this function.
* This function adds the job contained in @conn_state to the job_queue for a
* writeback connector. It takes ownership of the writeback job and sets the
* @conn_state->writeback_job to NULL, and so no access to the job may be
* performed by the caller after this function returns.
*
* Drivers must ensure that for a given writeback connector, jobs are queued in
* exactly the same order as they will be completed by the hardware (and
Expand All @@ -258,16 +296,36 @@ EXPORT_SYMBOL(drm_writeback_connector_init);
* See also: drm_writeback_signal_completion()
*/
void drm_writeback_queue_job(struct drm_writeback_connector *wb_connector,
struct drm_writeback_job *job)
struct drm_connector_state *conn_state)
{
struct drm_writeback_job *job;
unsigned long flags;

job = conn_state->writeback_job;
conn_state->writeback_job = NULL;

spin_lock_irqsave(&wb_connector->job_lock, flags);
list_add_tail(&job->list_entry, &wb_connector->job_queue);
spin_unlock_irqrestore(&wb_connector->job_lock, flags);
}
EXPORT_SYMBOL(drm_writeback_queue_job);

void drm_writeback_cleanup_job(struct drm_writeback_job *job)
{
struct drm_writeback_connector *connector = job->connector;
const struct drm_connector_helper_funcs *funcs =
connector->base.helper_private;

if (job->prepared && funcs->cleanup_writeback_job)
funcs->cleanup_writeback_job(connector, job);

if (job->fb)
drm_framebuffer_put(job->fb);

kfree(job);
}
EXPORT_SYMBOL(drm_writeback_cleanup_job);

/*
* @cleanup_work: deferred cleanup of a writeback job
*
Expand All @@ -280,10 +338,9 @@ static void cleanup_work(struct work_struct *work)
struct drm_writeback_job *job = container_of(work,
struct drm_writeback_job,
cleanup_work);
drm_framebuffer_put(job->fb);
kfree(job);
}

drm_writeback_cleanup_job(job);
}

/**
* drm_writeback_signal_completion - Signal the completion of a writeback job
Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/rcar-du/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,7 @@ config DRM_RCAR_VSP
depends on VIDEO_RENESAS_VSP1=y || (VIDEO_RENESAS_VSP1 && DRM_RCAR_DU=m)
help
Enable support to expose the R-Car VSP Compositor as KMS planes.

config DRM_RCAR_WRITEBACK
bool
default y if ARM64
3 changes: 2 additions & 1 deletion drivers/gpu/drm/rcar-du/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ rcar-du-drm-y := rcar_du_crtc.o \
rcar_du_encoder.o \
rcar_du_group.o \
rcar_du_kms.o \
rcar_du_plane.o
rcar_du_plane.o \

rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS) += rcar_du_of.o \
rcar_du_of_lvds_r8a7790.dtb.o \
Expand All @@ -13,6 +13,7 @@ rcar-du-drm-$(CONFIG_DRM_RCAR_LVDS) += rcar_du_of.o \
rcar_du_of_lvds_r8a7795.dtb.o \
rcar_du_of_lvds_r8a7796.dtb.o
rcar-du-drm-$(CONFIG_DRM_RCAR_VSP) += rcar_du_vsp.o
rcar-du-drm-$(CONFIG_DRM_RCAR_WRITEBACK) += rcar_du_writeback.o

obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o
obj-$(CONFIG_DRM_RCAR_DW_HDMI) += rcar_dw_hdmi.o
Expand Down
7 changes: 6 additions & 1 deletion drivers/gpu/drm/rcar-du/rcar_du_crtc.c
Original file line number Diff line number Diff line change
Expand Up @@ -648,8 +648,13 @@ static int rcar_du_crtc_atomic_check(struct drm_crtc *crtc,
rstate->outputs = 0;

drm_for_each_encoder_mask(encoder, crtc->dev, state->encoder_mask) {
struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
struct rcar_du_encoder *renc;

/* Skip the writeback encoder. */
if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
continue;

renc = to_rcar_encoder(encoder);
rstate->outputs |= BIT(renc->output);
}

Expand Down
9 changes: 7 additions & 2 deletions drivers/gpu/drm/rcar-du/rcar_du_crtc.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#include <linux/wait.h>

#include <drm/drm_crtc.h>
#include <drm/drm_writeback.h>

#include <media/vsp1.h>

Expand All @@ -27,7 +28,7 @@ struct rcar_du_vsp;
* @clock: the CRTC functional clock
* @extclock: external pixel dot clock (optional)
* @mmio_offset: offset of the CRTC registers in the DU MMIO block
* @index: CRTC software and hardware index
* @index: CRTC hardware index
* @initialized: whether the CRTC has been initialized and clocks enabled
* @dsysr: cached value of the DSYSR register
* @vblank_enable: whether vblank events are enabled on this CRTC
Expand All @@ -39,6 +40,7 @@ struct rcar_du_vsp;
* @group: CRTC group this CRTC belongs to
* @vsp: VSP feeding video to this CRTC
* @vsp_pipe: index of the VSP pipeline feeding video to this CRTC
* @writeback: the writeback connector
*/
struct rcar_du_crtc {
struct drm_crtc crtc;
Expand All @@ -65,9 +67,12 @@ struct rcar_du_crtc {

const char *const *sources;
unsigned int sources_count;

struct drm_writeback_connector writeback;
};

#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc)
#define to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, crtc)
#define wb_to_rcar_crtc(c) container_of(c, struct rcar_du_crtc, writeback)

/**
* struct rcar_du_crtc_state - Driver-specific CRTC state
Expand Down
Loading

0 comments on commit 535f6f5

Please sign in to comment.