Commit 6978f123 authored by Laurent Pinchart's avatar Laurent Pinchart

drm/rcar-du: Merge LVDS and VGA encoder code

Create a single rcar_du_encoder structure that implements a KMS encoder.
The current implementation is straightforward and only configures CRTC
output routing.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart+renesas@ideasonboard.com>
parent 9e8be272
rcar-du-drm-y := rcar_du_crtc.o \ rcar-du-drm-y := rcar_du_crtc.o \
rcar_du_drv.o \ rcar_du_drv.o \
rcar_du_encoder.o \
rcar_du_kms.o \ rcar_du_kms.o \
rcar_du_lvds.o \
rcar_du_lvdscon.o \ rcar_du_lvdscon.o \
rcar_du_plane.o \ rcar_du_plane.o \
rcar_du_vga.o \
rcar_du_vgacon.o rcar_du_vgacon.o
obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o obj-$(CONFIG_DRM_RCAR_DU) += rcar-du-drm.o
...@@ -23,10 +23,8 @@ ...@@ -23,10 +23,8 @@
#include "rcar_du_crtc.h" #include "rcar_du_crtc.h"
#include "rcar_du_drv.h" #include "rcar_du_drv.h"
#include "rcar_du_kms.h" #include "rcar_du_kms.h"
#include "rcar_du_lvds.h"
#include "rcar_du_plane.h" #include "rcar_du_plane.h"
#include "rcar_du_regs.h" #include "rcar_du_regs.h"
#include "rcar_du_vga.h"
#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)
......
/* /*
* rcar_du_lvds.c -- R-Car Display Unit LVDS Encoder * rcar_du_encoder.c -- R-Car Display Unit Encoder
* *
* Copyright (C) 2013 Renesas Corporation * Copyright (C) 2013 Renesas Corporation
* *
...@@ -16,15 +16,32 @@ ...@@ -16,15 +16,32 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include "rcar_du_drv.h" #include "rcar_du_drv.h"
#include "rcar_du_encoder.h"
#include "rcar_du_kms.h" #include "rcar_du_kms.h"
#include "rcar_du_lvds.h"
#include "rcar_du_lvdscon.h" #include "rcar_du_lvdscon.h"
#include "rcar_du_vgacon.h"
static void rcar_du_lvds_encoder_dpms(struct drm_encoder *encoder, int mode) /* -----------------------------------------------------------------------------
* Common connector functions
*/
struct drm_encoder *
rcar_du_connector_best_encoder(struct drm_connector *connector)
{
struct rcar_du_connector *rcon = to_rcar_connector(connector);
return &rcon->encoder->encoder;
}
/* -----------------------------------------------------------------------------
* Encoder
*/
static void rcar_du_encoder_dpms(struct drm_encoder *encoder, int mode)
{ {
} }
static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder, static bool rcar_du_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode, const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode) struct drm_display_mode *adjusted_mode)
{ {
...@@ -33,6 +50,10 @@ static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder, ...@@ -33,6 +50,10 @@ static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder,
struct drm_connector *connector; struct drm_connector *connector;
bool found = false; bool found = false;
/* DAC encoders have currently no restriction on the mode. */
if (encoder->encoder_type == DRM_MODE_ENCODER_DAC)
return true;
list_for_each_entry(connector, &dev->mode_config.connector_list, head) { list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
if (connector->encoder == encoder) { if (connector->encoder == encoder) {
found = true; found = true;
...@@ -64,9 +85,26 @@ static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder, ...@@ -64,9 +85,26 @@ static bool rcar_du_lvds_encoder_mode_fixup(struct drm_encoder *encoder,
return true; return true;
} }
static void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder)
{
}
static void rcar_du_encoder_mode_commit(struct drm_encoder *encoder)
{
}
static void rcar_du_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
rcar_du_crtc_route_output(encoder->crtc, renc->output);
}
static const struct drm_encoder_helper_funcs encoder_helper_funcs = { static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
.dpms = rcar_du_lvds_encoder_dpms, .dpms = rcar_du_encoder_dpms,
.mode_fixup = rcar_du_lvds_encoder_mode_fixup, .mode_fixup = rcar_du_encoder_mode_fixup,
.prepare = rcar_du_encoder_mode_prepare, .prepare = rcar_du_encoder_mode_prepare,
.commit = rcar_du_encoder_mode_commit, .commit = rcar_du_encoder_mode_commit,
.mode_set = rcar_du_encoder_mode_set, .mode_set = rcar_du_encoder_mode_set,
...@@ -76,9 +114,9 @@ static const struct drm_encoder_funcs encoder_funcs = { ...@@ -76,9 +114,9 @@ static const struct drm_encoder_funcs encoder_funcs = {
.destroy = drm_encoder_cleanup, .destroy = drm_encoder_cleanup,
}; };
int rcar_du_lvds_init(struct rcar_du_device *rcdu, int rcar_du_encoder_init(struct rcar_du_device *rcdu,
const struct rcar_du_encoder_lvds_data *data, enum rcar_du_encoder_type type, unsigned int output,
unsigned int output) const struct rcar_du_encoder_data *data)
{ {
struct rcar_du_encoder *renc; struct rcar_du_encoder *renc;
int ret; int ret;
...@@ -90,11 +128,21 @@ int rcar_du_lvds_init(struct rcar_du_device *rcdu, ...@@ -90,11 +128,21 @@ int rcar_du_lvds_init(struct rcar_du_device *rcdu,
renc->output = output; renc->output = output;
ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs, ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs,
DRM_MODE_ENCODER_LVDS); type);
if (ret < 0) if (ret < 0)
return ret; return ret;
drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs); drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs);
return rcar_du_lvds_connector_init(rcdu, renc, &data->panel); switch (type) {
case RCAR_DU_ENCODER_LVDS:
return rcar_du_lvds_connector_init(rcdu, renc,
&data->u.lvds.panel);
case RCAR_DU_ENCODER_VGA:
return rcar_du_vga_connector_init(rcdu, renc);
default:
return -EINVAL;
}
} }
/* /*
* rcar_du_lvds.h -- R-Car Display Unit LVDS Encoder and Connector * rcar_du_encoder.h -- R-Car Display Unit Encoder
* *
* Copyright (C) 2013 Renesas Corporation * Copyright (C) 2013 Renesas Corporation
* *
...@@ -11,14 +11,35 @@ ...@@ -11,14 +11,35 @@
* (at your option) any later version. * (at your option) any later version.
*/ */
#ifndef __RCAR_DU_LVDS_H__ #ifndef __RCAR_DU_ENCODER_H__
#define __RCAR_DU_LVDS_H__ #define __RCAR_DU_ENCODER_H__
#include <drm/drm_crtc.h>
struct rcar_du_device; struct rcar_du_device;
struct rcar_du_encoder_lvds_data; struct rcar_du_encoder_data;
struct rcar_du_encoder {
struct drm_encoder encoder;
unsigned int output;
};
#define to_rcar_encoder(e) \
container_of(e, struct rcar_du_encoder, encoder)
struct rcar_du_connector {
struct drm_connector connector;
struct rcar_du_encoder *encoder;
};
#define to_rcar_connector(c) \
container_of(c, struct rcar_du_connector, connector)
struct drm_encoder *
rcar_du_connector_best_encoder(struct drm_connector *connector);
int rcar_du_lvds_init(struct rcar_du_device *rcdu, int rcar_du_encoder_init(struct rcar_du_device *rcdu,
const struct rcar_du_encoder_lvds_data *data, enum rcar_du_encoder_type type, unsigned int output,
unsigned int output); const struct rcar_du_encoder_data *data);
#endif /* __RCAR_DU_LVDS_H__ */ #endif /* __RCAR_DU_ENCODER_H__ */
...@@ -19,10 +19,9 @@ ...@@ -19,10 +19,9 @@
#include "rcar_du_crtc.h" #include "rcar_du_crtc.h"
#include "rcar_du_drv.h" #include "rcar_du_drv.h"
#include "rcar_du_encoder.h"
#include "rcar_du_kms.h" #include "rcar_du_kms.h"
#include "rcar_du_lvds.h"
#include "rcar_du_regs.h" #include "rcar_du_regs.h"
#include "rcar_du_vga.h"
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Format helpers * Format helpers
...@@ -105,35 +104,6 @@ const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc) ...@@ -105,35 +104,6 @@ const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc)
return NULL; return NULL;
} }
/* -----------------------------------------------------------------------------
* Common connector and encoder functions
*/
struct drm_encoder *
rcar_du_connector_best_encoder(struct drm_connector *connector)
{
struct rcar_du_connector *rcon = to_rcar_connector(connector);
return &rcon->encoder->encoder;
}
void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder)
{
}
void rcar_du_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
struct rcar_du_encoder *renc = to_rcar_encoder(encoder);
rcar_du_crtc_route_output(encoder->crtc, renc->output);
}
void rcar_du_encoder_mode_commit(struct drm_encoder *encoder)
{
}
/* ----------------------------------------------------------------------------- /* -----------------------------------------------------------------------------
* Frame buffer * Frame buffer
*/ */
...@@ -221,6 +191,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) ...@@ -221,6 +191,9 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
const struct rcar_du_encoder_data *pdata = const struct rcar_du_encoder_data *pdata =
&rcdu->pdata->encoders[i]; &rcdu->pdata->encoders[i];
if (pdata->encoder == RCAR_DU_ENCODER_UNUSED)
continue;
if (pdata->output >= ARRAY_SIZE(rcdu->crtcs)) { if (pdata->output >= ARRAY_SIZE(rcdu->crtcs)) {
dev_warn(rcdu->dev, dev_warn(rcdu->dev,
"encoder %u references unexisting output %u, skipping\n", "encoder %u references unexisting output %u, skipping\n",
...@@ -228,18 +201,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu) ...@@ -228,18 +201,8 @@ int rcar_du_modeset_init(struct rcar_du_device *rcdu)
continue; continue;
} }
switch (pdata->encoder) { rcar_du_encoder_init(rcdu, pdata->encoder, pdata->output,
case RCAR_DU_ENCODER_VGA: pdata);
rcar_du_vga_init(rcdu, &pdata->u.vga, pdata->output);
break;
case RCAR_DU_ENCODER_LVDS:
rcar_du_lvds_init(rcdu, &pdata->u.lvds, pdata->output);
break;
default:
break;
}
} }
/* Set the possible CRTCs and possible clones. All encoders can be /* Set the possible CRTCs and possible clones. All encoders can be
......
...@@ -16,8 +16,9 @@ ...@@ -16,8 +16,9 @@
#include <linux/types.h> #include <linux/types.h>
#include <drm/drm_crtc.h> struct drm_file;
struct drm_device;
struct drm_mode_create_dumb;
struct rcar_du_device; struct rcar_du_device;
struct rcar_du_format_info { struct rcar_du_format_info {
...@@ -28,32 +29,8 @@ struct rcar_du_format_info { ...@@ -28,32 +29,8 @@ struct rcar_du_format_info {
unsigned int edf; unsigned int edf;
}; };
struct rcar_du_encoder {
struct drm_encoder encoder;
unsigned int output;
};
#define to_rcar_encoder(e) \
container_of(e, struct rcar_du_encoder, encoder)
struct rcar_du_connector {
struct drm_connector connector;
struct rcar_du_encoder *encoder;
};
#define to_rcar_connector(c) \
container_of(c, struct rcar_du_connector, connector)
const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc); const struct rcar_du_format_info *rcar_du_format_info(u32 fourcc);
struct drm_encoder *
rcar_du_connector_best_encoder(struct drm_connector *connector);
void rcar_du_encoder_mode_prepare(struct drm_encoder *encoder);
void rcar_du_encoder_mode_set(struct drm_encoder *encoder,
struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode);
void rcar_du_encoder_mode_commit(struct drm_encoder *encoder);
int rcar_du_modeset_init(struct rcar_du_device *rcdu); int rcar_du_modeset_init(struct rcar_du_device *rcdu);
int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev, int rcar_du_dumb_create(struct drm_file *file, struct drm_device *dev,
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include "rcar_du_drv.h" #include "rcar_du_drv.h"
#include "rcar_du_encoder.h"
#include "rcar_du_kms.h" #include "rcar_du_kms.h"
#include "rcar_du_lvdscon.h" #include "rcar_du_lvdscon.h"
......
/*
* rcar_du_vga.c -- R-Car Display Unit VGA DAC
*
* Copyright (C) 2013 Renesas Corporation
*
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_crtc_helper.h>
#include "rcar_du_drv.h"
#include "rcar_du_kms.h"
#include "rcar_du_vga.h"
#include "rcar_du_vgacon.h"
static void rcar_du_vga_encoder_dpms(struct drm_encoder *encoder, int mode)
{
}
static bool rcar_du_vga_encoder_mode_fixup(struct drm_encoder *encoder,
const struct drm_display_mode *mode,
struct drm_display_mode *adjusted_mode)
{
return true;
}
static const struct drm_encoder_helper_funcs encoder_helper_funcs = {
.dpms = rcar_du_vga_encoder_dpms,
.mode_fixup = rcar_du_vga_encoder_mode_fixup,
.prepare = rcar_du_encoder_mode_prepare,
.commit = rcar_du_encoder_mode_commit,
.mode_set = rcar_du_encoder_mode_set,
};
static const struct drm_encoder_funcs encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
int rcar_du_vga_init(struct rcar_du_device *rcdu,
const struct rcar_du_encoder_vga_data *data,
unsigned int output)
{
struct rcar_du_encoder *renc;
int ret;
renc = devm_kzalloc(rcdu->dev, sizeof(*renc), GFP_KERNEL);
if (renc == NULL)
return -ENOMEM;
renc->output = output;
ret = drm_encoder_init(rcdu->ddev, &renc->encoder, &encoder_funcs,
DRM_MODE_ENCODER_DAC);
if (ret < 0)
return ret;
drm_encoder_helper_add(&renc->encoder, &encoder_helper_funcs);
return rcar_du_vga_connector_init(rcdu, renc);
}
/*
* rcar_du_vga.h -- R-Car Display Unit VGA DAC
*
* Copyright (C) 2013 Renesas Corporation
*
* Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __RCAR_DU_VGA_H__
#define __RCAR_DU_VGA_H__
struct rcar_du_device;
struct rcar_du_encoder_vga_data;
int rcar_du_vga_init(struct rcar_du_device *rcdu,
const struct rcar_du_encoder_vga_data *data,
unsigned int output);
#endif /* __RCAR_DU_VGA_H__ */
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <drm/drm_crtc_helper.h> #include <drm/drm_crtc_helper.h>
#include "rcar_du_drv.h" #include "rcar_du_drv.h"
#include "rcar_du_encoder.h"
#include "rcar_du_kms.h" #include "rcar_du_kms.h"
#include "rcar_du_vgacon.h" #include "rcar_du_vgacon.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