aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/omapdrm/omap_encoder.c
diff options
context:
space:
mode:
authorRob Clark <robdclark@gmail.com>2013-02-11 12:43:09 -0500
committerRob Clark <robdclark@gmail.com>2013-02-16 17:38:06 -0500
commit8bb0daffb0b8e45188066255b4203446eae181f1 (patch)
treec1a324b863df57becdfab54c9325231bbb853b56 /drivers/gpu/drm/omapdrm/omap_encoder.c
parenta4462f246c8821f625f45bce52c7ca7e0207dffe (diff)
drm/omap: move out of staging
Now that the omapdss interface has been reworked so that omapdrm can use dispc directly, we have been able to fix the remaining functional kms issues with omapdrm. And in the mean time the PM sequencing and many other of that open issues have been solved. So I think it makes sense to finally move omapdrm out of staging. Signed-off-by: Rob Clark <robdclark@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/omapdrm/omap_encoder.c')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_encoder.c170
1 files changed, 170 insertions, 0 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
new file mode 100644
index 000000000000..7e1f2ab65372
--- /dev/null
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -0,0 +1,170 @@
1/*
2 * drivers/gpu/drm/omapdrm/omap_encoder.c
3 *
4 * Copyright (C) 2011 Texas Instruments
5 * Author: Rob Clark <rob@ti.com>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License version 2 as published by
9 * the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include "omap_drv.h"
21
22#include "drm_crtc.h"
23#include "drm_crtc_helper.h"
24
25#include <linux/list.h>
26
27
28/*
29 * encoder funcs
30 */
31
32#define to_omap_encoder(x) container_of(x, struct omap_encoder, base)
33
34/* The encoder and connector both map to same dssdev.. the encoder
35 * handles the 'active' parts, ie. anything the modifies the state
36 * of the hw, and the connector handles the 'read-only' parts, like
37 * detecting connection and reading edid.
38 */
39struct omap_encoder {
40 struct drm_encoder base;
41 struct omap_dss_device *dssdev;
42};
43
44static void omap_encoder_destroy(struct drm_encoder *encoder)
45{
46 struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
47 drm_encoder_cleanup(encoder);
48 kfree(omap_encoder);
49}
50
51static const struct drm_encoder_funcs omap_encoder_funcs = {
52 .destroy = omap_encoder_destroy,
53};
54
55/*
56 * The CRTC drm_crtc_helper_set_mode() doesn't really give us the right
57 * order.. the easiest way to work around this for now is to make all
58 * the encoder-helper's no-op's and have the omap_crtc code take care
59 * of the sequencing and call us in the right points.
60 *
61 * Eventually to handle connecting CRTCs to different encoders properly,
62 * either the CRTC helpers need to change or we need to replace
63 * drm_crtc_helper_set_mode(), but lets wait until atomic-modeset for
64 * that.
65 */
66
67static void omap_encoder_dpms(struct drm_encoder *encoder, int mode)
68{
69}
70
71static bool omap_encoder_mode_fixup(struct drm_encoder *encoder,
72 const struct drm_display_mode *mode,
73 struct drm_display_mode *adjusted_mode)
74{
75 return true;
76}
77
78static void omap_encoder_mode_set(struct drm_encoder *encoder,
79 struct drm_display_mode *mode,
80 struct drm_display_mode *adjusted_mode)
81{
82}
83
84static void omap_encoder_prepare(struct drm_encoder *encoder)
85{
86}
87
88static void omap_encoder_commit(struct drm_encoder *encoder)
89{
90}
91
92static const struct drm_encoder_helper_funcs omap_encoder_helper_funcs = {
93 .dpms = omap_encoder_dpms,
94 .mode_fixup = omap_encoder_mode_fixup,
95 .mode_set = omap_encoder_mode_set,
96 .prepare = omap_encoder_prepare,
97 .commit = omap_encoder_commit,
98};
99
100/*
101 * Instead of relying on the helpers for modeset, the omap_crtc code
102 * calls these functions in the proper sequence.
103 */
104
105int omap_encoder_set_enabled(struct drm_encoder *encoder, bool enabled)
106{
107 struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
108 struct omap_dss_device *dssdev = omap_encoder->dssdev;
109 struct omap_dss_driver *dssdrv = dssdev->driver;
110
111 if (enabled) {
112 return dssdrv->enable(dssdev);
113 } else {
114 dssdrv->disable(dssdev);
115 return 0;
116 }
117}
118
119int omap_encoder_update(struct drm_encoder *encoder,
120 struct omap_overlay_manager *mgr,
121 struct omap_video_timings *timings)
122{
123 struct drm_device *dev = encoder->dev;
124 struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
125 struct omap_dss_device *dssdev = omap_encoder->dssdev;
126 struct omap_dss_driver *dssdrv = dssdev->driver;
127 int ret;
128
129 dssdev->output->manager = mgr;
130
131 ret = dssdrv->check_timings(dssdev, timings);
132 if (ret) {
133 dev_err(dev->dev, "could not set timings: %d\n", ret);
134 return ret;
135 }
136
137 dssdrv->set_timings(dssdev, timings);
138
139 return 0;
140}
141
142/* initialize encoder */
143struct drm_encoder *omap_encoder_init(struct drm_device *dev,
144 struct omap_dss_device *dssdev)
145{
146 struct drm_encoder *encoder = NULL;
147 struct omap_encoder *omap_encoder;
148
149 omap_encoder = kzalloc(sizeof(*omap_encoder), GFP_KERNEL);
150 if (!omap_encoder) {
151 dev_err(dev->dev, "could not allocate encoder\n");
152 goto fail;
153 }
154
155 omap_encoder->dssdev = dssdev;
156
157 encoder = &omap_encoder->base;
158
159 drm_encoder_init(dev, encoder, &omap_encoder_funcs,
160 DRM_MODE_ENCODER_TMDS);
161 drm_encoder_helper_add(encoder, &omap_encoder_helper_funcs);
162
163 return encoder;
164
165fail:
166 if (encoder)
167 omap_encoder_destroy(encoder);
168
169 return NULL;
170}