summaryrefslogtreecommitdiff
path: root/drivers/gpu
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c46
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c27
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h1
3 files changed, 61 insertions, 13 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 79b200aee18a..4cec678dba94 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -40,7 +40,7 @@ struct omap_crtc {
* mgr->id.) Eventually this will be replaced w/ something
* more common-panel-framework-y
*/
- struct omap_overlay_manager mgr;
+ struct omap_overlay_manager *mgr;
struct omap_video_timings timings;
bool enabled;
@@ -90,7 +90,32 @@ uint32_t pipe2vbl(struct drm_crtc *crtc)
* job of sequencing the setup of the video pipe in the proper order
*/
+/* ovl-mgr-id -> crtc */
+static struct omap_crtc *omap_crtcs[8];
+
/* we can probably ignore these until we support command-mode panels: */
+static int omap_crtc_connect(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dst)
+{
+ if (mgr->output)
+ return -EINVAL;
+
+ if ((mgr->supported_outputs & dst->id) == 0)
+ return -EINVAL;
+
+ dst->manager = mgr;
+ mgr->output = dst;
+
+ return 0;
+}
+
+static void omap_crtc_disconnect(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dst)
+{
+ mgr->output->manager = NULL;
+ mgr->output = NULL;
+}
+
static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
{
}
@@ -107,7 +132,7 @@ static void omap_crtc_disable(struct omap_overlay_manager *mgr)
static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings)
{
- struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr);
+ struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
DBG("%s", omap_crtc->name);
omap_crtc->timings = *timings;
omap_crtc->full_update = true;
@@ -116,7 +141,7 @@ static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr,
const struct dss_lcd_mgr_config *config)
{
- struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr);
+ struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
DBG("%s", omap_crtc->name);
dispc_mgr_set_lcd_config(omap_crtc->channel, config);
}
@@ -135,6 +160,8 @@ static void omap_crtc_unregister_framedone_handler(
}
static const struct dss_mgr_ops mgr_ops = {
+ .connect = omap_crtc_connect,
+ .disconnect = omap_crtc_disconnect,
.start_update = omap_crtc_start_update,
.enable = omap_crtc_enable,
.disable = omap_crtc_disable,
@@ -569,7 +596,7 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
} else {
if (encoder) {
omap_encoder_set_enabled(encoder, false);
- omap_encoder_update(encoder, &omap_crtc->mgr,
+ omap_encoder_update(encoder, omap_crtc->mgr,
&omap_crtc->timings);
omap_encoder_set_enabled(encoder, true);
omap_crtc->full_update = false;
@@ -595,6 +622,11 @@ static const char *channel_names[] = {
[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
};
+void omap_crtc_pre_init(void)
+{
+ dss_install_mgr_ops(&mgr_ops);
+}
+
/* initialize crtc */
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id)
@@ -635,9 +667,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
omap_irq_register(dev, &omap_crtc->error_irq);
/* temporary: */
- omap_crtc->mgr.id = channel;
-
- dss_install_mgr_ops(&mgr_ops);
+ omap_crtc->mgr = omap_dss_get_overlay_manager(channel);
/* TODO: fix hard-coded setup.. add properties! */
info = &omap_crtc->info;
@@ -651,6 +681,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
omap_plane_install_properties(omap_crtc->plane, &crtc->base);
+ omap_crtcs[channel] = omap_crtc;
+
return crtc;
fail:
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 826586ffbe83..a3004f12b9a3 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -65,10 +65,8 @@ static int get_connector_type(struct omap_dss_device *dssdev)
switch (dssdev->type) {
case OMAP_DISPLAY_TYPE_HDMI:
return DRM_MODE_CONNECTOR_HDMIA;
- case OMAP_DISPLAY_TYPE_DPI:
- if (!strcmp(dssdev->name, "dvi"))
- return DRM_MODE_CONNECTOR_DVID;
- /* fallthrough */
+ case OMAP_DISPLAY_TYPE_DVI:
+ return DRM_MODE_CONNECTOR_DVID;
default:
return DRM_MODE_CONNECTOR_Unknown;
}
@@ -97,6 +95,9 @@ static int omap_modeset_init(struct drm_device *dev)
int num_mgrs = dss_feat_get_num_mgrs();
int num_crtcs;
int i, id = 0;
+ int r;
+
+ omap_crtc_pre_init();
drm_mode_config_init(dev);
@@ -116,6 +117,7 @@ static int omap_modeset_init(struct drm_device *dev)
struct drm_connector *connector;
struct drm_encoder *encoder;
enum omap_channel channel;
+ struct omap_overlay_manager *mgr;
if (!dssdev->driver) {
dev_warn(dev->dev, "%s has no driver.. skipping it\n",
@@ -131,6 +133,13 @@ static int omap_modeset_init(struct drm_device *dev)
continue;
}
+ r = dssdev->driver->connect(dssdev);
+ if (r) {
+ dev_err(dev->dev, "could not connect display: %s\n",
+ dssdev->name);
+ continue;
+ }
+
encoder = omap_encoder_init(dev, dssdev);
if (!encoder) {
@@ -172,8 +181,9 @@ static int omap_modeset_init(struct drm_device *dev)
* other possible channels to which the encoder can connect are
* not considered.
*/
- channel = dssdev->output->dispc_channel;
+ mgr = omapdss_find_mgr_from_display(dssdev);
+ channel = mgr->id;
/*
* if this channel hasn't already been taken by a previously
* allocated crtc, we create a new crtc for it
@@ -247,6 +257,9 @@ static int omap_modeset_init(struct drm_device *dev)
struct drm_encoder *encoder = priv->encoders[i];
struct omap_dss_device *dssdev =
omap_encoder_get_dssdev(encoder);
+ struct omap_dss_device *output;
+
+ output = omapdss_find_output_from_display(dssdev);
/* figure out which crtc's we can connect the encoder to: */
encoder->possible_crtcs = 0;
@@ -259,9 +272,11 @@ static int omap_modeset_init(struct drm_device *dev)
supported_outputs =
dss_feat_get_supported_outputs(crtc_channel);
- if (supported_outputs & dssdev->output->id)
+ if (supported_outputs & output->id)
encoder->possible_crtcs |= (1 << id);
}
+
+ omap_dss_put_device(output);
}
DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 215a20dd340c..14f17da2ce25 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -157,6 +157,7 @@ const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc);
enum omap_channel omap_crtc_channel(struct drm_crtc *crtc);
int omap_crtc_apply(struct drm_crtc *crtc,
struct omap_drm_apply *apply);
+void omap_crtc_pre_init(void);
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id);