aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDave Airlie <airlied@redhat.com>2013-04-15 23:20:03 -0400
committerDave Airlie <airlied@redhat.com>2013-04-15 23:20:03 -0400
commitdea14dfab9d1fdf5695ae61dc72c587533706edc (patch)
treeb30f80f3581c706f29911cbe334f6b35569a5847 /drivers
parente4fda9f264e154946c678ca7ff07023f573abf6a (diff)
parent3d62fe5b214fce69ae14abbdb88794a753418614 (diff)
Merge tag 'omapdss-for-3.10' of git://gitorious.org/linux-omap-dss2/linux into drm-next
Omapdss patches for 3.10 merge window The biggest changes are: * DSI video mode: automatic clock and timing calculation * Lots of platform data related panel driver cleanups, to prepare for DT * tag 'omapdss-for-3.10' of git://gitorious.org/linux-omap-dss2/linux: (69 commits) drm/omap: add statics to a few structs drm/omap: Fix and improve crtc and overlay manager correlation drm/omap: Take a fb reference in omap_plane_update() drm/omap: Make fixed resolution panels work drm/omap: fix modeset_init if a panel doesn't satisfy omapdrm requirements OMAPDSS: DPI: widen the pck search when using dss fck OMAPDSS: fix dss_fck clock rate rounding omapdss: use devm_clk_get() OMAPDSS: nec-nl8048 panel: Use dev_pm_ops OMAPDSS: DISPC: Revert to older DISPC Smart Standby mechanism for OMAP5 OMAPDSS: DISPC: Configure doublestride for NV12 when using 2D Tiler buffers omapdss: Features: Fix some parameter ranges omapdss: DISPC: add max pixel clock limits for LCD and TV managers OMAPDSS: DSI: Use devm_clk_get() drivers: video: omap2: dss: Use PTR_RET function OMAPDSS: VENC: remove platform_enable/disable calls OMAPDSS: n8x0 panel: remove use of platform_enable/disable OMAPDSS: n8x0 panel: handle gpio data in panel driver OMAPDSS: picodlp panel: remove platform_enable/disable callbacks OMAPDSS: picodlp panel: handle gpio data in panel driver ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/gpu/drm/omapdrm/omap_connector.c27
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c21
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c165
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h38
-rw-r--r--drivers/gpu/drm/omapdrm/omap_encoder.c24
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_irq.c17
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c6
-rw-r--r--drivers/video/omap2/displays/panel-acx565akm.c59
-rw-r--r--drivers/video/omap2/displays/panel-generic-dpi.c39
-rw-r--r--drivers/video/omap2/displays/panel-lgphilips-lb035q02.c58
-rw-r--r--drivers/video/omap2/displays/panel-n8x0.c95
-rw-r--r--drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c135
-rw-r--r--drivers/video/omap2/displays/panel-picodlp.c49
-rw-r--r--drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c126
-rw-r--r--drivers/video/omap2/displays/panel-taal.c300
-rw-r--r--drivers/video/omap2/displays/panel-tfp410.c2
-rw-r--r--drivers/video/omap2/displays/panel-tpo-td043mtea1.c45
-rw-r--r--drivers/video/omap2/dss/apply.c15
-rw-r--r--drivers/video/omap2/dss/core.c5
-rw-r--r--drivers/video/omap2/dss/dispc.c176
-rw-r--r--drivers/video/omap2/dss/dispc.h1
-rw-r--r--drivers/video/omap2/dss/dpi.c316
-rw-r--r--drivers/video/omap2/dss/dsi.c1221
-rw-r--r--drivers/video/omap2/dss/dss.c181
-rw-r--r--drivers/video/omap2/dss/dss.h36
-rw-r--r--drivers/video/omap2/dss/dss_features.c8
-rw-r--r--drivers/video/omap2/dss/hdmi.c35
-rw-r--r--drivers/video/omap2/dss/output.c1
-rw-r--r--drivers/video/omap2/dss/rfbi.c2
-rw-r--r--drivers/video/omap2/dss/sdi.c70
-rw-r--r--drivers/video/omap2/dss/venc.c23
-rw-r--r--drivers/video/omap2/omapfb/omapfb-main.c2
33 files changed, 1767 insertions, 1533 deletions
diff --git a/drivers/gpu/drm/omapdrm/omap_connector.c b/drivers/gpu/drm/omapdrm/omap_connector.c
index c451c41a7a7d..912759daf562 100644
--- a/drivers/gpu/drm/omapdrm/omap_connector.c
+++ b/drivers/gpu/drm/omapdrm/omap_connector.c
@@ -110,6 +110,11 @@ static enum drm_connector_status omap_connector_detect(
110 ret = connector_status_connected; 110 ret = connector_status_connected;
111 else 111 else
112 ret = connector_status_disconnected; 112 ret = connector_status_disconnected;
113 } else if (dssdev->type == OMAP_DISPLAY_TYPE_DPI ||
114 dssdev->type == OMAP_DISPLAY_TYPE_DBI ||
115 dssdev->type == OMAP_DISPLAY_TYPE_SDI ||
116 dssdev->type == OMAP_DISPLAY_TYPE_DSI) {
117 ret = connector_status_connected;
113 } else { 118 } else {
114 ret = connector_status_unknown; 119 ret = connector_status_unknown;
115 } 120 }
@@ -189,12 +194,30 @@ static int omap_connector_mode_valid(struct drm_connector *connector,
189 struct omap_video_timings timings = {0}; 194 struct omap_video_timings timings = {0};
190 struct drm_device *dev = connector->dev; 195 struct drm_device *dev = connector->dev;
191 struct drm_display_mode *new_mode; 196 struct drm_display_mode *new_mode;
192 int ret = MODE_BAD; 197 int r, ret = MODE_BAD;
193 198
194 copy_timings_drm_to_omap(&timings, mode); 199 copy_timings_drm_to_omap(&timings, mode);
195 mode->vrefresh = drm_mode_vrefresh(mode); 200 mode->vrefresh = drm_mode_vrefresh(mode);
196 201
197 if (!dssdrv->check_timings(dssdev, &timings)) { 202 /*
203 * if the panel driver doesn't have a check_timings, it's most likely
204 * a fixed resolution panel, check if the timings match with the
205 * panel's timings
206 */
207 if (dssdrv->check_timings) {
208 r = dssdrv->check_timings(dssdev, &timings);
209 } else {
210 struct omap_video_timings t = {0};
211
212 dssdrv->get_timings(dssdev, &t);
213
214 if (memcmp(&timings, &t, sizeof(struct omap_video_timings)))
215 r = -EINVAL;
216 else
217 r = 0;
218 }
219
220 if (!r) {
198 /* check if vrefresh is still valid */ 221 /* check if vrefresh is still valid */
199 new_mode = drm_mode_duplicate(dev, mode); 222 new_mode = drm_mode_duplicate(dev, mode);
200 new_mode->clock = timings.pixel_clock; 223 new_mode->clock = timings.pixel_clock;
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index bec66a490b8f..79b200aee18a 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -74,6 +74,13 @@ struct omap_crtc {
74 struct work_struct page_flip_work; 74 struct work_struct page_flip_work;
75}; 75};
76 76
77uint32_t pipe2vbl(struct drm_crtc *crtc)
78{
79 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
80
81 return dispc_mgr_get_vsync_irq(omap_crtc->channel);
82}
83
77/* 84/*
78 * Manager-ops, callbacks from output when they need to configure 85 * Manager-ops, callbacks from output when they need to configure
79 * the upstream part of the video pipe. 86 * the upstream part of the video pipe.
@@ -613,7 +620,13 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
613 omap_crtc->apply.pre_apply = omap_crtc_pre_apply; 620 omap_crtc->apply.pre_apply = omap_crtc_pre_apply;
614 omap_crtc->apply.post_apply = omap_crtc_post_apply; 621 omap_crtc->apply.post_apply = omap_crtc_post_apply;
615 622
616 omap_crtc->apply_irq.irqmask = pipe2vbl(id); 623 omap_crtc->channel = channel;
624 omap_crtc->plane = plane;
625 omap_crtc->plane->crtc = crtc;
626 omap_crtc->name = channel_names[channel];
627 omap_crtc->pipe = id;
628
629 omap_crtc->apply_irq.irqmask = pipe2vbl(crtc);
617 omap_crtc->apply_irq.irq = omap_crtc_apply_irq; 630 omap_crtc->apply_irq.irq = omap_crtc_apply_irq;
618 631
619 omap_crtc->error_irq.irqmask = 632 omap_crtc->error_irq.irqmask =
@@ -621,12 +634,6 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev,
621 omap_crtc->error_irq.irq = omap_crtc_error_irq; 634 omap_crtc->error_irq.irq = omap_crtc_error_irq;
622 omap_irq_register(dev, &omap_crtc->error_irq); 635 omap_irq_register(dev, &omap_crtc->error_irq);
623 636
624 omap_crtc->channel = channel;
625 omap_crtc->plane = plane;
626 omap_crtc->plane->crtc = crtc;
627 omap_crtc->name = channel_names[channel];
628 omap_crtc->pipe = id;
629
630 /* temporary: */ 637 /* temporary: */
631 omap_crtc->mgr.id = channel; 638 omap_crtc->mgr.id = channel;
632 639
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index 079c54c6f94c..9c53c25e5201 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -74,54 +74,53 @@ static int get_connector_type(struct omap_dss_device *dssdev)
74 } 74 }
75} 75}
76 76
77static bool channel_used(struct drm_device *dev, enum omap_channel channel)
78{
79 struct omap_drm_private *priv = dev->dev_private;
80 int i;
81
82 for (i = 0; i < priv->num_crtcs; i++) {
83 struct drm_crtc *crtc = priv->crtcs[i];
84
85 if (omap_crtc_channel(crtc) == channel)
86 return true;
87 }
88
89 return false;
90}
91
77static int omap_modeset_init(struct drm_device *dev) 92static int omap_modeset_init(struct drm_device *dev)
78{ 93{
79 struct omap_drm_private *priv = dev->dev_private; 94 struct omap_drm_private *priv = dev->dev_private;
80 struct omap_dss_device *dssdev = NULL; 95 struct omap_dss_device *dssdev = NULL;
81 int num_ovls = dss_feat_get_num_ovls(); 96 int num_ovls = dss_feat_get_num_ovls();
82 int id; 97 int num_mgrs = dss_feat_get_num_mgrs();
98 int num_crtcs;
99 int i, id = 0;
83 100
84 drm_mode_config_init(dev); 101 drm_mode_config_init(dev);
85 102
86 omap_drm_irq_install(dev); 103 omap_drm_irq_install(dev);
87 104
88 /* 105 /*
89 * Create private planes and CRTCs for the last NUM_CRTCs overlay 106 * We usually don't want to create a CRTC for each manager, at least
90 * plus manager: 107 * not until we have a way to expose private planes to userspace.
108 * Otherwise there would not be enough video pipes left for drm planes.
109 * We use the num_crtc argument to limit the number of crtcs we create.
91 */ 110 */
92 for (id = 0; id < min(num_crtc, num_ovls); id++) { 111 num_crtcs = min3(num_crtc, num_mgrs, num_ovls);
93 struct drm_plane *plane;
94 struct drm_crtc *crtc;
95
96 plane = omap_plane_init(dev, id, true);
97 crtc = omap_crtc_init(dev, plane, pipe2chan(id), id);
98 112
99 BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs)); 113 dssdev = NULL;
100 priv->crtcs[id] = crtc;
101 priv->num_crtcs++;
102
103 priv->planes[id] = plane;
104 priv->num_planes++;
105 }
106
107 /*
108 * Create normal planes for the remaining overlays:
109 */
110 for (; id < num_ovls; id++) {
111 struct drm_plane *plane = omap_plane_init(dev, id, false);
112
113 BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes));
114 priv->planes[priv->num_planes++] = plane;
115 }
116 114
117 for_each_dss_dev(dssdev) { 115 for_each_dss_dev(dssdev) {
118 struct drm_connector *connector; 116 struct drm_connector *connector;
119 struct drm_encoder *encoder; 117 struct drm_encoder *encoder;
118 enum omap_channel channel;
120 119
121 if (!dssdev->driver) { 120 if (!dssdev->driver) {
122 dev_warn(dev->dev, "%s has no driver.. skipping it\n", 121 dev_warn(dev->dev, "%s has no driver.. skipping it\n",
123 dssdev->name); 122 dssdev->name);
124 return 0; 123 continue;
125 } 124 }
126 125
127 if (!(dssdev->driver->get_timings || 126 if (!(dssdev->driver->get_timings ||
@@ -129,7 +128,7 @@ static int omap_modeset_init(struct drm_device *dev)
129 dev_warn(dev->dev, "%s driver does not support " 128 dev_warn(dev->dev, "%s driver does not support "
130 "get_timings or read_edid.. skipping it!\n", 129 "get_timings or read_edid.. skipping it!\n",
131 dssdev->name); 130 dssdev->name);
132 return 0; 131 continue;
133 } 132 }
134 133
135 encoder = omap_encoder_init(dev, dssdev); 134 encoder = omap_encoder_init(dev, dssdev);
@@ -157,16 +156,118 @@ static int omap_modeset_init(struct drm_device *dev)
157 156
158 drm_mode_connector_attach_encoder(connector, encoder); 157 drm_mode_connector_attach_encoder(connector, encoder);
159 158
159 /*
160 * if we have reached the limit of the crtcs we are allowed to
161 * create, let's not try to look for a crtc for this
162 * panel/encoder and onwards, we will, of course, populate the
163 * the possible_crtcs field for all the encoders with the final
164 * set of crtcs we create
165 */
166 if (id == num_crtcs)
167 continue;
168
169 /*
170 * get the recommended DISPC channel for this encoder. For now,
171 * we only try to get create a crtc out of the recommended, the
172 * other possible channels to which the encoder can connect are
173 * not considered.
174 */
175 channel = dssdev->output->dispc_channel;
176
177 /*
178 * if this channel hasn't already been taken by a previously
179 * allocated crtc, we create a new crtc for it
180 */
181 if (!channel_used(dev, channel)) {
182 struct drm_plane *plane;
183 struct drm_crtc *crtc;
184
185 plane = omap_plane_init(dev, id, true);
186 crtc = omap_crtc_init(dev, plane, channel, id);
187
188 BUG_ON(priv->num_crtcs >= ARRAY_SIZE(priv->crtcs));
189 priv->crtcs[id] = crtc;
190 priv->num_crtcs++;
191
192 priv->planes[id] = plane;
193 priv->num_planes++;
194
195 id++;
196 }
197 }
198
199 /*
200 * we have allocated crtcs according to the need of the panels/encoders,
201 * adding more crtcs here if needed
202 */
203 for (; id < num_crtcs; id++) {
204
205 /* find a free manager for this crtc */
206 for (i = 0; i < num_mgrs; i++) {
207 if (!channel_used(dev, i)) {
208 struct drm_plane *plane;
209 struct drm_crtc *crtc;
210
211 plane = omap_plane_init(dev, id, true);
212 crtc = omap_crtc_init(dev, plane, i, id);
213
214 BUG_ON(priv->num_crtcs >=
215 ARRAY_SIZE(priv->crtcs));
216
217 priv->crtcs[id] = crtc;
218 priv->num_crtcs++;
219
220 priv->planes[id] = plane;
221 priv->num_planes++;
222
223 break;
224 } else {
225 continue;
226 }
227 }
228
229 if (i == num_mgrs) {
230 /* this shouldn't really happen */
231 dev_err(dev->dev, "no managers left for crtc\n");
232 return -ENOMEM;
233 }
234 }
235
236 /*
237 * Create normal planes for the remaining overlays:
238 */
239 for (; id < num_ovls; id++) {
240 struct drm_plane *plane = omap_plane_init(dev, id, false);
241
242 BUG_ON(priv->num_planes >= ARRAY_SIZE(priv->planes));
243 priv->planes[priv->num_planes++] = plane;
244 }
245
246 for (i = 0; i < priv->num_encoders; i++) {
247 struct drm_encoder *encoder = priv->encoders[i];
248 struct omap_dss_device *dssdev =
249 omap_encoder_get_dssdev(encoder);
250
160 /* figure out which crtc's we can connect the encoder to: */ 251 /* figure out which crtc's we can connect the encoder to: */
161 encoder->possible_crtcs = 0; 252 encoder->possible_crtcs = 0;
162 for (id = 0; id < priv->num_crtcs; id++) { 253 for (id = 0; id < priv->num_crtcs; id++) {
163 enum omap_dss_output_id supported_outputs = 254 struct drm_crtc *crtc = priv->crtcs[id];
164 dss_feat_get_supported_outputs(pipe2chan(id)); 255 enum omap_channel crtc_channel;
256 enum omap_dss_output_id supported_outputs;
257
258 crtc_channel = omap_crtc_channel(crtc);
259 supported_outputs =
260 dss_feat_get_supported_outputs(crtc_channel);
261
165 if (supported_outputs & dssdev->output->id) 262 if (supported_outputs & dssdev->output->id)
166 encoder->possible_crtcs |= (1 << id); 263 encoder->possible_crtcs |= (1 << id);
167 } 264 }
168 } 265 }
169 266
267 DBG("registered %d planes, %d crtcs, %d encoders and %d connectors\n",
268 priv->num_planes, priv->num_crtcs, priv->num_encoders,
269 priv->num_connectors);
270
170 dev->mode_config.min_width = 32; 271 dev->mode_config.min_width = 32;
171 dev->mode_config.min_height = 32; 272 dev->mode_config.min_height = 32;
172 273
@@ -303,7 +404,7 @@ static int ioctl_gem_info(struct drm_device *dev, void *data,
303 return ret; 404 return ret;
304} 405}
305 406
306struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = { 407static struct drm_ioctl_desc ioctls[DRM_COMMAND_END - DRM_COMMAND_BASE] = {
307 DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH), 408 DRM_IOCTL_DEF_DRV(OMAP_GET_PARAM, ioctl_get_param, DRM_UNLOCKED|DRM_AUTH),
308 DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), 409 DRM_IOCTL_DEF_DRV(OMAP_SET_PARAM, ioctl_set_param, DRM_UNLOCKED|DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY),
309 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH), 410 DRM_IOCTL_DEF_DRV(OMAP_GEM_NEW, ioctl_gem_new, DRM_UNLOCKED|DRM_AUTH),
@@ -567,7 +668,7 @@ static const struct dev_pm_ops omapdrm_pm_ops = {
567}; 668};
568#endif 669#endif
569 670
570struct platform_driver pdev = { 671static struct platform_driver pdev = {
571 .driver = { 672 .driver = {
572 .name = DRIVER_NAME, 673 .name = DRIVER_NAME,
573 .owner = THIS_MODULE, 674 .owner = THIS_MODULE,
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index d4f997bb4ac0..215a20dd340c 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -139,8 +139,8 @@ void omap_gem_describe_objects(struct list_head *list, struct seq_file *m);
139int omap_gem_resume(struct device *dev); 139int omap_gem_resume(struct device *dev);
140#endif 140#endif
141 141
142int omap_irq_enable_vblank(struct drm_device *dev, int crtc); 142int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id);
143void omap_irq_disable_vblank(struct drm_device *dev, int crtc); 143void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id);
144irqreturn_t omap_irq_handler(DRM_IRQ_ARGS); 144irqreturn_t omap_irq_handler(DRM_IRQ_ARGS);
145void omap_irq_preinstall(struct drm_device *dev); 145void omap_irq_preinstall(struct drm_device *dev);
146int omap_irq_postinstall(struct drm_device *dev); 146int omap_irq_postinstall(struct drm_device *dev);
@@ -271,39 +271,9 @@ static inline int align_pitch(int pitch, int width, int bpp)
271 return ALIGN(pitch, 8 * bytespp); 271 return ALIGN(pitch, 8 * bytespp);
272} 272}
273 273
274static inline enum omap_channel pipe2chan(int pipe)
275{
276 int num_mgrs = dss_feat_get_num_mgrs();
277
278 /*
279 * We usually don't want to create a CRTC for each manager,
280 * at least not until we have a way to expose private planes
281 * to userspace. Otherwise there would not be enough video
282 * pipes left for drm planes. The higher #'d managers tend
283 * to have more features so start in reverse order.
284 */
285 return num_mgrs - pipe - 1;
286}
287
288/* map crtc to vblank mask */ 274/* map crtc to vblank mask */
289static inline uint32_t pipe2vbl(int crtc) 275uint32_t pipe2vbl(struct drm_crtc *crtc);
290{ 276struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder);
291 enum omap_channel channel = pipe2chan(crtc);
292 return dispc_mgr_get_vsync_irq(channel);
293}
294
295static inline int crtc2pipe(struct drm_device *dev, struct drm_crtc *crtc)
296{
297 struct omap_drm_private *priv = dev->dev_private;
298 int i;
299
300 for (i = 0; i < ARRAY_SIZE(priv->crtcs); i++)
301 if (priv->crtcs[i] == crtc)
302 return i;
303
304 BUG(); /* bogus CRTC ptr */
305 return -1;
306}
307 277
308/* should these be made into common util helpers? 278/* should these be made into common util helpers?
309 */ 279 */
diff --git a/drivers/gpu/drm/omapdrm/omap_encoder.c b/drivers/gpu/drm/omapdrm/omap_encoder.c
index 21d126d0317e..c29451ba65da 100644
--- a/drivers/gpu/drm/omapdrm/omap_encoder.c
+++ b/drivers/gpu/drm/omapdrm/omap_encoder.c
@@ -41,6 +41,13 @@ struct omap_encoder {
41 struct omap_dss_device *dssdev; 41 struct omap_dss_device *dssdev;
42}; 42};
43 43
44struct omap_dss_device *omap_encoder_get_dssdev(struct drm_encoder *encoder)
45{
46 struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
47
48 return omap_encoder->dssdev;
49}
50
44static void omap_encoder_destroy(struct drm_encoder *encoder) 51static void omap_encoder_destroy(struct drm_encoder *encoder)
45{ 52{
46 struct omap_encoder *omap_encoder = to_omap_encoder(encoder); 53 struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
@@ -128,13 +135,26 @@ int omap_encoder_update(struct drm_encoder *encoder,
128 135
129 dssdev->output->manager = mgr; 136 dssdev->output->manager = mgr;
130 137
131 ret = dssdrv->check_timings(dssdev, timings); 138 if (dssdrv->check_timings) {
139 ret = dssdrv->check_timings(dssdev, timings);
140 } else {
141 struct omap_video_timings t = {0};
142
143 dssdrv->get_timings(dssdev, &t);
144
145 if (memcmp(timings, &t, sizeof(struct omap_video_timings)))
146 ret = -EINVAL;
147 else
148 ret = 0;
149 }
150
132 if (ret) { 151 if (ret) {
133 dev_err(dev->dev, "could not set timings: %d\n", ret); 152 dev_err(dev->dev, "could not set timings: %d\n", ret);
134 return ret; 153 return ret;
135 } 154 }
136 155
137 dssdrv->set_timings(dssdev, timings); 156 if (dssdrv->set_timings)
157 dssdrv->set_timings(dssdev, timings);
138 158
139 return 0; 159 return 0;
140} 160}
diff --git a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
index ac74d1bc67bf..0682cb5c0150 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem_dmabuf.c
@@ -178,7 +178,7 @@ out_unlock:
178 return omap_gem_mmap_obj(obj, vma); 178 return omap_gem_mmap_obj(obj, vma);
179} 179}
180 180
181struct dma_buf_ops omap_dmabuf_ops = { 181static struct dma_buf_ops omap_dmabuf_ops = {
182 .map_dma_buf = omap_gem_map_dma_buf, 182 .map_dma_buf = omap_gem_map_dma_buf,
183 .unmap_dma_buf = omap_gem_unmap_dma_buf, 183 .unmap_dma_buf = omap_gem_unmap_dma_buf,
184 .release = omap_gem_dmabuf_release, 184 .release = omap_gem_dmabuf_release,
diff --git a/drivers/gpu/drm/omapdrm/omap_irq.c b/drivers/gpu/drm/omapdrm/omap_irq.c
index e01303ee00c3..9263db117ff8 100644
--- a/drivers/gpu/drm/omapdrm/omap_irq.c
+++ b/drivers/gpu/drm/omapdrm/omap_irq.c
@@ -130,12 +130,13 @@ int omap_irq_wait(struct drm_device *dev, struct omap_irq_wait *wait,
130 * Zero on success, appropriate errno if the given @crtc's vblank 130 * Zero on success, appropriate errno if the given @crtc's vblank
131 * interrupt cannot be enabled. 131 * interrupt cannot be enabled.
132 */ 132 */
133int omap_irq_enable_vblank(struct drm_device *dev, int crtc) 133int omap_irq_enable_vblank(struct drm_device *dev, int crtc_id)
134{ 134{
135 struct omap_drm_private *priv = dev->dev_private; 135 struct omap_drm_private *priv = dev->dev_private;
136 struct drm_crtc *crtc = priv->crtcs[crtc_id];
136 unsigned long flags; 137 unsigned long flags;
137 138
138 DBG("dev=%p, crtc=%d", dev, crtc); 139 DBG("dev=%p, crtc=%d", dev, crtc_id);
139 140
140 dispc_runtime_get(); 141 dispc_runtime_get();
141 spin_lock_irqsave(&list_lock, flags); 142 spin_lock_irqsave(&list_lock, flags);
@@ -156,12 +157,13 @@ int omap_irq_enable_vblank(struct drm_device *dev, int crtc)
156 * a hardware vblank counter, this routine should be a no-op, since 157 * a hardware vblank counter, this routine should be a no-op, since
157 * interrupts will have to stay on to keep the count accurate. 158 * interrupts will have to stay on to keep the count accurate.
158 */ 159 */
159void omap_irq_disable_vblank(struct drm_device *dev, int crtc) 160void omap_irq_disable_vblank(struct drm_device *dev, int crtc_id)
160{ 161{
161 struct omap_drm_private *priv = dev->dev_private; 162 struct omap_drm_private *priv = dev->dev_private;
163 struct drm_crtc *crtc = priv->crtcs[crtc_id];
162 unsigned long flags; 164 unsigned long flags;
163 165
164 DBG("dev=%p, crtc=%d", dev, crtc); 166 DBG("dev=%p, crtc=%d", dev, crtc_id);
165 167
166 dispc_runtime_get(); 168 dispc_runtime_get();
167 spin_lock_irqsave(&list_lock, flags); 169 spin_lock_irqsave(&list_lock, flags);
@@ -186,9 +188,12 @@ irqreturn_t omap_irq_handler(DRM_IRQ_ARGS)
186 188
187 VERB("irqs: %08x", irqstatus); 189 VERB("irqs: %08x", irqstatus);
188 190
189 for (id = 0; id < priv->num_crtcs; id++) 191 for (id = 0; id < priv->num_crtcs; id++) {
190 if (irqstatus & pipe2vbl(id)) 192 struct drm_crtc *crtc = priv->crtcs[id];
193
194 if (irqstatus & pipe2vbl(crtc))
191 drm_handle_vblank(dev, id); 195 drm_handle_vblank(dev, id);
196 }
192 197
193 spin_lock_irqsave(&list_lock, flags); 198 spin_lock_irqsave(&list_lock, flags);
194 list_for_each_entry_safe(handler, n, &priv->irq_list, node) { 199 list_for_each_entry_safe(handler, n, &priv->irq_list, node) {
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 2882cda6ea19..8d225d7ff4e3 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -247,6 +247,12 @@ static int omap_plane_update(struct drm_plane *plane,
247{ 247{
248 struct omap_plane *omap_plane = to_omap_plane(plane); 248 struct omap_plane *omap_plane = to_omap_plane(plane);
249 omap_plane->enabled = true; 249 omap_plane->enabled = true;
250
251 if (plane->fb)
252 drm_framebuffer_unreference(plane->fb);
253
254 drm_framebuffer_reference(fb);
255
250 return omap_plane_mode_set(plane, crtc, fb, 256 return omap_plane_mode_set(plane, crtc, fb,
251 crtc_x, crtc_y, crtc_w, crtc_h, 257 crtc_x, crtc_y, crtc_w, crtc_h,
252 src_x, src_y, src_w, src_h, 258 src_x, src_y, src_w, src_h,
diff --git a/drivers/video/omap2/displays/panel-acx565akm.c b/drivers/video/omap2/displays/panel-acx565akm.c
index 72699f88c002..d7f69c09ecf1 100644
--- a/drivers/video/omap2/displays/panel-acx565akm.c
+++ b/drivers/video/omap2/displays/panel-acx565akm.c
@@ -29,8 +29,10 @@
29#include <linux/sched.h> 29#include <linux/sched.h>
30#include <linux/backlight.h> 30#include <linux/backlight.h>
31#include <linux/fb.h> 31#include <linux/fb.h>
32#include <linux/gpio.h>
32 33
33#include <video/omapdss.h> 34#include <video/omapdss.h>
35#include <video/omap-panel-data.h>
34 36
35#define MIPID_CMD_READ_DISP_ID 0x04 37#define MIPID_CMD_READ_DISP_ID 0x04
36#define MIPID_CMD_READ_RED 0x06 38#define MIPID_CMD_READ_RED 0x06
@@ -336,8 +338,6 @@ static int acx565akm_bl_update_status(struct backlight_device *dev)
336 r = 0; 338 r = 0;
337 if (md->has_bc) 339 if (md->has_bc)
338 acx565akm_set_brightness(md, level); 340 acx565akm_set_brightness(md, level);
339 else if (md->dssdev->set_backlight)
340 r = md->dssdev->set_backlight(md->dssdev, level);
341 else 341 else
342 r = -ENODEV; 342 r = -ENODEV;
343 343
@@ -352,7 +352,7 @@ static int acx565akm_bl_get_intensity(struct backlight_device *dev)
352 352
353 dev_dbg(&dev->dev, "%s\n", __func__); 353 dev_dbg(&dev->dev, "%s\n", __func__);
354 354
355 if (!md->has_bc && md->dssdev->set_backlight == NULL) 355 if (!md->has_bc)
356 return -ENODEV; 356 return -ENODEV;
357 357
358 if (dev->props.fb_blank == FB_BLANK_UNBLANK && 358 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
@@ -496,21 +496,38 @@ static struct omap_video_timings acx_panel_timings = {
496 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, 496 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
497}; 497};
498 498
499static struct panel_acx565akm_data *get_panel_data(struct omap_dss_device *dssdev)
500{
501 return (struct panel_acx565akm_data *) dssdev->data;
502}
503
499static int acx_panel_probe(struct omap_dss_device *dssdev) 504static int acx_panel_probe(struct omap_dss_device *dssdev)
500{ 505{
501 int r; 506 int r;
502 struct acx565akm_device *md = &acx_dev; 507 struct acx565akm_device *md = &acx_dev;
508 struct panel_acx565akm_data *panel_data = get_panel_data(dssdev);
503 struct backlight_device *bldev; 509 struct backlight_device *bldev;
504 int max_brightness, brightness; 510 int max_brightness, brightness;
505 struct backlight_properties props; 511 struct backlight_properties props;
506 512
507 dev_dbg(&dssdev->dev, "%s\n", __func__); 513 dev_dbg(&dssdev->dev, "%s\n", __func__);
508 514
515 if (!panel_data)
516 return -EINVAL;
517
509 /* FIXME AC bias ? */ 518 /* FIXME AC bias ? */
510 dssdev->panel.timings = acx_panel_timings; 519 dssdev->panel.timings = acx_panel_timings;
511 520
512 if (dssdev->platform_enable) 521 if (gpio_is_valid(panel_data->reset_gpio)) {
513 dssdev->platform_enable(dssdev); 522 r = devm_gpio_request_one(&dssdev->dev, panel_data->reset_gpio,
523 GPIOF_OUT_INIT_LOW, "lcd reset");
524 if (r)
525 return r;
526 }
527
528 if (gpio_is_valid(panel_data->reset_gpio))
529 gpio_set_value(panel_data->reset_gpio, 1);
530
514 /* 531 /*
515 * After reset we have to wait 5 msec before the first 532 * After reset we have to wait 5 msec before the first
516 * command can be sent. 533 * command can be sent.
@@ -522,8 +539,9 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
522 r = panel_detect(md); 539 r = panel_detect(md);
523 if (r) { 540 if (r) {
524 dev_err(&dssdev->dev, "%s panel detect error\n", __func__); 541 dev_err(&dssdev->dev, "%s panel detect error\n", __func__);
525 if (!md->enabled && dssdev->platform_disable) 542 if (!md->enabled && gpio_is_valid(panel_data->reset_gpio))
526 dssdev->platform_disable(dssdev); 543 gpio_set_value(panel_data->reset_gpio, 0);
544
527 return r; 545 return r;
528 } 546 }
529 547
@@ -532,8 +550,8 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
532 mutex_unlock(&acx_dev.mutex); 550 mutex_unlock(&acx_dev.mutex);
533 551
534 if (!md->enabled) { 552 if (!md->enabled) {
535 if (dssdev->platform_disable) 553 if (gpio_is_valid(panel_data->reset_gpio))
536 dssdev->platform_disable(dssdev); 554 gpio_set_value(panel_data->reset_gpio, 0);
537 } 555 }
538 556
539 /*------- Backlight control --------*/ 557 /*------- Backlight control --------*/
@@ -557,15 +575,10 @@ static int acx_panel_probe(struct omap_dss_device *dssdev)
557 md->cabc_mode = get_hw_cabc_mode(md); 575 md->cabc_mode = get_hw_cabc_mode(md);
558 } 576 }
559 577
560 if (md->has_bc) 578 max_brightness = 255;
561 max_brightness = 255;
562 else
563 max_brightness = dssdev->max_backlight_level;
564 579
565 if (md->has_bc) 580 if (md->has_bc)
566 brightness = acx565akm_get_actual_brightness(md); 581 brightness = acx565akm_get_actual_brightness(md);
567 else if (dssdev->get_backlight)
568 brightness = dssdev->get_backlight(dssdev);
569 else 582 else
570 brightness = 0; 583 brightness = 0;
571 584
@@ -591,6 +604,7 @@ static void acx_panel_remove(struct omap_dss_device *dssdev)
591static int acx_panel_power_on(struct omap_dss_device *dssdev) 604static int acx_panel_power_on(struct omap_dss_device *dssdev)
592{ 605{
593 struct acx565akm_device *md = &acx_dev; 606 struct acx565akm_device *md = &acx_dev;
607 struct panel_acx565akm_data *panel_data = get_panel_data(dssdev);
594 int r; 608 int r;
595 609
596 dev_dbg(&dssdev->dev, "%s\n", __func__); 610 dev_dbg(&dssdev->dev, "%s\n", __func__);
@@ -612,11 +626,8 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
612 /*FIXME tweak me */ 626 /*FIXME tweak me */
613 msleep(50); 627 msleep(50);
614 628
615 if (dssdev->platform_enable) { 629 if (gpio_is_valid(panel_data->reset_gpio))
616 r = dssdev->platform_enable(dssdev); 630 gpio_set_value(panel_data->reset_gpio, 1);
617 if (r)
618 goto fail;
619 }
620 631
621 if (md->enabled) { 632 if (md->enabled) {
622 dev_dbg(&md->spi->dev, "panel already enabled\n"); 633 dev_dbg(&md->spi->dev, "panel already enabled\n");
@@ -645,8 +656,7 @@ static int acx_panel_power_on(struct omap_dss_device *dssdev)
645 mutex_unlock(&md->mutex); 656 mutex_unlock(&md->mutex);
646 657
647 return acx565akm_bl_update_status(md->bl_dev); 658 return acx565akm_bl_update_status(md->bl_dev);
648fail: 659
649 omapdss_sdi_display_disable(dssdev);
650fail_unlock: 660fail_unlock:
651 mutex_unlock(&md->mutex); 661 mutex_unlock(&md->mutex);
652 return r; 662 return r;
@@ -655,6 +665,7 @@ fail_unlock:
655static void acx_panel_power_off(struct omap_dss_device *dssdev) 665static void acx_panel_power_off(struct omap_dss_device *dssdev)
656{ 666{
657 struct acx565akm_device *md = &acx_dev; 667 struct acx565akm_device *md = &acx_dev;
668 struct panel_acx565akm_data *panel_data = get_panel_data(dssdev);
658 669
659 dev_dbg(&dssdev->dev, "%s\n", __func__); 670 dev_dbg(&dssdev->dev, "%s\n", __func__);
660 671
@@ -678,8 +689,8 @@ static void acx_panel_power_off(struct omap_dss_device *dssdev)
678 */ 689 */
679 msleep(50); 690 msleep(50);
680 691
681 if (dssdev->platform_disable) 692 if (gpio_is_valid(panel_data->reset_gpio))
682 dssdev->platform_disable(dssdev); 693 gpio_set_value(panel_data->reset_gpio, 0);
683 694
684 /* FIXME need to tweak this delay */ 695 /* FIXME need to tweak this delay */
685 msleep(100); 696 msleep(100);
diff --git a/drivers/video/omap2/displays/panel-generic-dpi.c b/drivers/video/omap2/displays/panel-generic-dpi.c
index c904f42d81c1..97363f733683 100644
--- a/drivers/video/omap2/displays/panel-generic-dpi.c
+++ b/drivers/video/omap2/displays/panel-generic-dpi.c
@@ -33,9 +33,10 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/delay.h> 34#include <linux/delay.h>
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/gpio.h>
36#include <video/omapdss.h> 37#include <video/omapdss.h>
37 38
38#include <video/omap-panel-generic-dpi.h> 39#include <video/omap-panel-data.h>
39 40
40struct panel_config { 41struct panel_config {
41 struct omap_video_timings timings; 42 struct omap_video_timings timings;
@@ -533,7 +534,7 @@ static inline struct panel_generic_dpi_data
533 534
534static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev) 535static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
535{ 536{
536 int r; 537 int r, i;
537 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); 538 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
538 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 539 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
539 struct panel_config *panel_config = drv_data->panel_config; 540 struct panel_config *panel_config = drv_data->panel_config;
@@ -552,15 +553,13 @@ static int generic_dpi_panel_power_on(struct omap_dss_device *dssdev)
552 if (panel_config->power_on_delay) 553 if (panel_config->power_on_delay)
553 msleep(panel_config->power_on_delay); 554 msleep(panel_config->power_on_delay);
554 555
555 if (panel_data->platform_enable) { 556 for (i = 0; i < panel_data->num_gpios; ++i) {
556 r = panel_data->platform_enable(dssdev); 557 gpio_set_value_cansleep(panel_data->gpios[i],
557 if (r) 558 panel_data->gpio_invert[i] ? 0 : 1);
558 goto err1;
559 } 559 }
560 560
561 return 0; 561 return 0;
562err1: 562
563 omapdss_dpi_display_disable(dssdev);
564err0: 563err0:
565 return r; 564 return r;
566} 565}
@@ -570,12 +569,15 @@ static void generic_dpi_panel_power_off(struct omap_dss_device *dssdev)
570 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); 569 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
571 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev); 570 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
572 struct panel_config *panel_config = drv_data->panel_config; 571 struct panel_config *panel_config = drv_data->panel_config;
572 int i;
573 573
574 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 574 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
575 return; 575 return;
576 576
577 if (panel_data->platform_disable) 577 for (i = panel_data->num_gpios - 1; i >= 0; --i) {
578 panel_data->platform_disable(dssdev); 578 gpio_set_value_cansleep(panel_data->gpios[i],
579 panel_data->gpio_invert[i] ? 1 : 0);
580 }
579 581
580 /* wait couple of vsyncs after disabling the LCD */ 582 /* wait couple of vsyncs after disabling the LCD */
581 if (panel_config->power_off_delay) 583 if (panel_config->power_off_delay)
@@ -589,7 +591,7 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
589 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev); 591 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
590 struct panel_config *panel_config = NULL; 592 struct panel_config *panel_config = NULL;
591 struct panel_drv_data *drv_data = NULL; 593 struct panel_drv_data *drv_data = NULL;
592 int i; 594 int i, r;
593 595
594 dev_dbg(&dssdev->dev, "probe\n"); 596 dev_dbg(&dssdev->dev, "probe\n");
595 597
@@ -606,9 +608,18 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
606 if (!panel_config) 608 if (!panel_config)
607 return -EINVAL; 609 return -EINVAL;
608 610
611 for (i = 0; i < panel_data->num_gpios; ++i) {
612 r = devm_gpio_request_one(&dssdev->dev, panel_data->gpios[i],
613 panel_data->gpio_invert[i] ?
614 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
615 "panel gpio");
616 if (r)
617 return r;
618 }
619
609 dssdev->panel.timings = panel_config->timings; 620 dssdev->panel.timings = panel_config->timings;
610 621
611 drv_data = kzalloc(sizeof(*drv_data), GFP_KERNEL); 622 drv_data = devm_kzalloc(&dssdev->dev, sizeof(*drv_data), GFP_KERNEL);
612 if (!drv_data) 623 if (!drv_data)
613 return -ENOMEM; 624 return -ENOMEM;
614 625
@@ -624,12 +635,8 @@ static int generic_dpi_panel_probe(struct omap_dss_device *dssdev)
624 635
625static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev) 636static void __exit generic_dpi_panel_remove(struct omap_dss_device *dssdev)
626{ 637{
627 struct panel_drv_data *drv_data = dev_get_drvdata(&dssdev->dev);
628
629 dev_dbg(&dssdev->dev, "remove\n"); 638 dev_dbg(&dssdev->dev, "remove\n");
630 639
631 kfree(drv_data);
632
633 dev_set_drvdata(&dssdev->dev, NULL); 640 dev_set_drvdata(&dssdev->dev, NULL);
634} 641}
635 642
diff --git a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
index 6e5abe8fd2dd..4ea6548c0ae9 100644
--- a/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
+++ b/drivers/video/omap2/displays/panel-lgphilips-lb035q02.c
@@ -20,8 +20,10 @@
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/mutex.h> 22#include <linux/mutex.h>
23#include <linux/gpio.h>
23 24
24#include <video/omapdss.h> 25#include <video/omapdss.h>
26#include <video/omap-panel-data.h>
25 27
26struct lb035q02_data { 28struct lb035q02_data {
27 struct mutex lock; 29 struct mutex lock;
@@ -48,9 +50,16 @@ static struct omap_video_timings lb035q02_timings = {
48 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, 50 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
49}; 51};
50 52
53static inline struct panel_generic_dpi_data
54*get_panel_data(const struct omap_dss_device *dssdev)
55{
56 return (struct panel_generic_dpi_data *) dssdev->data;
57}
58
51static int lb035q02_panel_power_on(struct omap_dss_device *dssdev) 59static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
52{ 60{
53 int r; 61 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
62 int r, i;
54 63
55 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 64 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
56 return 0; 65 return 0;
@@ -62,54 +71,65 @@ static int lb035q02_panel_power_on(struct omap_dss_device *dssdev)
62 if (r) 71 if (r)
63 goto err0; 72 goto err0;
64 73
65 if (dssdev->platform_enable) { 74 for (i = 0; i < panel_data->num_gpios; ++i) {
66 r = dssdev->platform_enable(dssdev); 75 gpio_set_value_cansleep(panel_data->gpios[i],
67 if (r) 76 panel_data->gpio_invert[i] ? 0 : 1);
68 goto err1;
69 } 77 }
70 78
71 return 0; 79 return 0;
72err1: 80
73 omapdss_dpi_display_disable(dssdev);
74err0: 81err0:
75 return r; 82 return r;
76} 83}
77 84
78static void lb035q02_panel_power_off(struct omap_dss_device *dssdev) 85static void lb035q02_panel_power_off(struct omap_dss_device *dssdev)
79{ 86{
87 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
88 int i;
89
80 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 90 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
81 return; 91 return;
82 92
83 if (dssdev->platform_disable) 93 for (i = panel_data->num_gpios - 1; i >= 0; --i) {
84 dssdev->platform_disable(dssdev); 94 gpio_set_value_cansleep(panel_data->gpios[i],
95 panel_data->gpio_invert[i] ? 1 : 0);
96 }
85 97
86 omapdss_dpi_display_disable(dssdev); 98 omapdss_dpi_display_disable(dssdev);
87} 99}
88 100
89static int lb035q02_panel_probe(struct omap_dss_device *dssdev) 101static int lb035q02_panel_probe(struct omap_dss_device *dssdev)
90{ 102{
103 struct panel_generic_dpi_data *panel_data = get_panel_data(dssdev);
91 struct lb035q02_data *ld; 104 struct lb035q02_data *ld;
92 int r; 105 int r, i;
106
107 if (!panel_data)
108 return -EINVAL;
93 109
94 dssdev->panel.timings = lb035q02_timings; 110 dssdev->panel.timings = lb035q02_timings;
95 111
96 ld = kzalloc(sizeof(*ld), GFP_KERNEL); 112 ld = devm_kzalloc(&dssdev->dev, sizeof(*ld), GFP_KERNEL);
97 if (!ld) { 113 if (!ld)
98 r = -ENOMEM; 114 return -ENOMEM;
99 goto err; 115
116 for (i = 0; i < panel_data->num_gpios; ++i) {
117 r = devm_gpio_request_one(&dssdev->dev, panel_data->gpios[i],
118 panel_data->gpio_invert[i] ?
119 GPIOF_OUT_INIT_HIGH : GPIOF_OUT_INIT_LOW,
120 "panel gpio");
121 if (r)
122 return r;
100 } 123 }
124
101 mutex_init(&ld->lock); 125 mutex_init(&ld->lock);
102 dev_set_drvdata(&dssdev->dev, ld); 126 dev_set_drvdata(&dssdev->dev, ld);
127
103 return 0; 128 return 0;
104err:
105 return r;
106} 129}
107 130
108static void lb035q02_panel_remove(struct omap_dss_device *dssdev) 131static void lb035q02_panel_remove(struct omap_dss_device *dssdev)
109{ 132{
110 struct lb035q02_data *ld = dev_get_drvdata(&dssdev->dev);
111
112 kfree(ld);
113} 133}
114 134
115static int lb035q02_panel_enable(struct omap_dss_device *dssdev) 135static int lb035q02_panel_enable(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-n8x0.c b/drivers/video/omap2/displays/panel-n8x0.c
index dd1294750802..f94ead6a3183 100644
--- a/drivers/video/omap2/displays/panel-n8x0.c
+++ b/drivers/video/omap2/displays/panel-n8x0.c
@@ -5,11 +5,10 @@
5#include <linux/slab.h> 5#include <linux/slab.h>
6#include <linux/gpio.h> 6#include <linux/gpio.h>
7#include <linux/spi/spi.h> 7#include <linux/spi/spi.h>
8#include <linux/backlight.h>
9#include <linux/fb.h> 8#include <linux/fb.h>
10 9
11#include <video/omapdss.h> 10#include <video/omapdss.h>
12#include <video/omap-panel-n8x0.h> 11#include <video/omap-panel-data.h>
13 12
14#define BLIZZARD_REV_CODE 0x00 13#define BLIZZARD_REV_CODE 0x00
15#define BLIZZARD_CONFIG 0x02 14#define BLIZZARD_CONFIG 0x02
@@ -69,7 +68,6 @@ static struct panel_drv_data {
69 68
70 struct omap_dss_device *dssdev; 69 struct omap_dss_device *dssdev;
71 struct spi_device *spidev; 70 struct spi_device *spidev;
72 struct backlight_device *bldev;
73 71
74 int blizzard_ver; 72 int blizzard_ver;
75} s_drv_data; 73} s_drv_data;
@@ -297,12 +295,6 @@ static int n8x0_panel_power_on(struct omap_dss_device *dssdev)
297 295
298 gpio_direction_output(bdata->ctrl_pwrdown, 1); 296 gpio_direction_output(bdata->ctrl_pwrdown, 1);
299 297
300 if (bdata->platform_enable) {
301 r = bdata->platform_enable(dssdev);
302 if (r)
303 goto err_plat_en;
304 }
305
306 omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res, 298 omapdss_rfbi_set_size(dssdev, dssdev->panel.timings.x_res,
307 dssdev->panel.timings.y_res); 299 dssdev->panel.timings.y_res);
308 omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size); 300 omapdss_rfbi_set_pixel_size(dssdev, dssdev->ctrl.pixel_size);
@@ -375,9 +367,6 @@ err_inv_panel:
375err_inv_chip: 367err_inv_chip:
376 omapdss_rfbi_display_disable(dssdev); 368 omapdss_rfbi_display_disable(dssdev);
377err_rfbi_en: 369err_rfbi_en:
378 if (bdata->platform_disable)
379 bdata->platform_disable(dssdev);
380err_plat_en:
381 gpio_direction_output(bdata->ctrl_pwrdown, 0); 370 gpio_direction_output(bdata->ctrl_pwrdown, 0);
382 return r; 371 return r;
383} 372}
@@ -394,9 +383,6 @@ static void n8x0_panel_power_off(struct omap_dss_device *dssdev)
394 send_display_off(spi); 383 send_display_off(spi);
395 send_sleep_in(spi); 384 send_sleep_in(spi);
396 385
397 if (bdata->platform_disable)
398 bdata->platform_disable(dssdev);
399
400 /* 386 /*
401 * HACK: we should turn off the panel here, but there is some problem 387 * HACK: we should turn off the panel here, but there is some problem
402 * with the initialization sequence, and we fail to init the panel if we 388 * with the initialization sequence, and we fail to init the panel if we
@@ -424,54 +410,10 @@ static const struct rfbi_timings n8x0_panel_timings = {
424 .cs_pulse_width = 0, 410 .cs_pulse_width = 0,
425}; 411};
426 412
427static int n8x0_bl_update_status(struct backlight_device *dev)
428{
429 struct omap_dss_device *dssdev = dev_get_drvdata(&dev->dev);
430 struct panel_n8x0_data *bdata = get_board_data(dssdev);
431 struct panel_drv_data *ddata = get_drv_data(dssdev);
432 int r;
433 int level;
434
435 mutex_lock(&ddata->lock);
436
437 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
438 dev->props.power == FB_BLANK_UNBLANK)
439 level = dev->props.brightness;
440 else
441 level = 0;
442
443 dev_dbg(&dssdev->dev, "update brightness to %d\n", level);
444
445 if (!bdata->set_backlight)
446 r = -EINVAL;
447 else
448 r = bdata->set_backlight(dssdev, level);
449
450 mutex_unlock(&ddata->lock);
451
452 return r;
453}
454
455static int n8x0_bl_get_intensity(struct backlight_device *dev)
456{
457 if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
458 dev->props.power == FB_BLANK_UNBLANK)
459 return dev->props.brightness;
460
461 return 0;
462}
463
464static const struct backlight_ops n8x0_bl_ops = {
465 .get_brightness = n8x0_bl_get_intensity,
466 .update_status = n8x0_bl_update_status,
467};
468
469static int n8x0_panel_probe(struct omap_dss_device *dssdev) 413static int n8x0_panel_probe(struct omap_dss_device *dssdev)
470{ 414{
471 struct panel_n8x0_data *bdata = get_board_data(dssdev); 415 struct panel_n8x0_data *bdata = get_board_data(dssdev);
472 struct panel_drv_data *ddata; 416 struct panel_drv_data *ddata;
473 struct backlight_device *bldev;
474 struct backlight_properties props;
475 int r; 417 int r;
476 418
477 dev_dbg(&dssdev->dev, "probe\n"); 419 dev_dbg(&dssdev->dev, "probe\n");
@@ -491,40 +433,27 @@ static int n8x0_panel_probe(struct omap_dss_device *dssdev)
491 dssdev->ctrl.rfbi_timings = n8x0_panel_timings; 433 dssdev->ctrl.rfbi_timings = n8x0_panel_timings;
492 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE; 434 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
493 435
494 memset(&props, 0, sizeof(props)); 436 if (gpio_is_valid(bdata->panel_reset)) {
495 props.max_brightness = 127; 437 r = devm_gpio_request_one(&dssdev->dev, bdata->panel_reset,
496 props.type = BACKLIGHT_PLATFORM; 438 GPIOF_OUT_INIT_LOW, "PANEL RESET");
497 bldev = backlight_device_register(dev_name(&dssdev->dev), &dssdev->dev, 439 if (r)
498 dssdev, &n8x0_bl_ops, &props); 440 return r;
499 if (IS_ERR(bldev)) {
500 r = PTR_ERR(bldev);
501 dev_err(&dssdev->dev, "register backlight failed\n");
502 return r;
503 } 441 }
504 442
505 ddata->bldev = bldev; 443 if (gpio_is_valid(bdata->ctrl_pwrdown)) {
506 444 r = devm_gpio_request_one(&dssdev->dev, bdata->ctrl_pwrdown,
507 bldev->props.fb_blank = FB_BLANK_UNBLANK; 445 GPIOF_OUT_INIT_LOW, "PANEL PWRDOWN");
508 bldev->props.power = FB_BLANK_UNBLANK; 446 if (r)
509 bldev->props.brightness = 127; 447 return r;
510 448 }
511 n8x0_bl_update_status(bldev);
512 449
513 return 0; 450 return 0;
514} 451}
515 452
516static void n8x0_panel_remove(struct omap_dss_device *dssdev) 453static void n8x0_panel_remove(struct omap_dss_device *dssdev)
517{ 454{
518 struct panel_drv_data *ddata = get_drv_data(dssdev);
519 struct backlight_device *bldev;
520
521 dev_dbg(&dssdev->dev, "remove\n"); 455 dev_dbg(&dssdev->dev, "remove\n");
522 456
523 bldev = ddata->bldev;
524 bldev->props.power = FB_BLANK_POWERDOWN;
525 n8x0_bl_update_status(bldev);
526 backlight_device_unregister(bldev);
527
528 dev_set_drvdata(&dssdev->dev, NULL); 457 dev_set_drvdata(&dssdev->dev, NULL);
529} 458}
530 459
diff --git a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
index c4e9c2b1b465..20c3cd91ff9b 100644
--- a/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
+++ b/drivers/video/omap2/displays/panel-nec-nl8048hl11-01b.c
@@ -19,10 +19,11 @@
19#include <linux/module.h> 19#include <linux/module.h>
20#include <linux/delay.h> 20#include <linux/delay.h>
21#include <linux/spi/spi.h> 21#include <linux/spi/spi.h>
22#include <linux/backlight.h>
23#include <linux/fb.h> 22#include <linux/fb.h>
23#include <linux/gpio.h>
24 24
25#include <video/omapdss.h> 25#include <video/omapdss.h>
26#include <video/omap-panel-data.h>
26 27
27#define LCD_XRES 800 28#define LCD_XRES 800
28#define LCD_YRES 480 29#define LCD_YRES 480
@@ -32,10 +33,6 @@
32 */ 33 */
33#define LCD_PIXEL_CLOCK 23800 34#define LCD_PIXEL_CLOCK 23800
34 35
35struct nec_8048_data {
36 struct backlight_device *bl;
37};
38
39static const struct { 36static const struct {
40 unsigned char addr; 37 unsigned char addr;
41 unsigned char dat; 38 unsigned char dat;
@@ -84,93 +81,47 @@ static struct omap_video_timings nec_8048_panel_timings = {
84 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE, 81 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE,
85}; 82};
86 83
87static int nec_8048_bl_update_status(struct backlight_device *bl) 84static inline struct panel_nec_nl8048_data
88{ 85*get_panel_data(const struct omap_dss_device *dssdev)
89 struct omap_dss_device *dssdev = dev_get_drvdata(&bl->dev);
90 int level;
91
92 if (!dssdev->set_backlight)
93 return -EINVAL;
94
95 if (bl->props.fb_blank == FB_BLANK_UNBLANK &&
96 bl->props.power == FB_BLANK_UNBLANK)
97 level = bl->props.brightness;
98 else
99 level = 0;
100
101 return dssdev->set_backlight(dssdev, level);
102}
103
104static int nec_8048_bl_get_brightness(struct backlight_device *bl)
105{ 86{
106 if (bl->props.fb_blank == FB_BLANK_UNBLANK && 87 return (struct panel_nec_nl8048_data *) dssdev->data;
107 bl->props.power == FB_BLANK_UNBLANK)
108 return bl->props.brightness;
109
110 return 0;
111} 88}
112 89
113static const struct backlight_ops nec_8048_bl_ops = {
114 .get_brightness = nec_8048_bl_get_brightness,
115 .update_status = nec_8048_bl_update_status,
116};
117
118static int nec_8048_panel_probe(struct omap_dss_device *dssdev) 90static int nec_8048_panel_probe(struct omap_dss_device *dssdev)
119{ 91{
120 struct backlight_device *bl; 92 struct panel_nec_nl8048_data *pd = get_panel_data(dssdev);
121 struct nec_8048_data *necd;
122 struct backlight_properties props;
123 int r; 93 int r;
124 94
125 dssdev->panel.timings = nec_8048_panel_timings; 95 if (!pd)
126 96 return -EINVAL;
127 necd = kzalloc(sizeof(*necd), GFP_KERNEL);
128 if (!necd)
129 return -ENOMEM;
130
131 dev_set_drvdata(&dssdev->dev, necd);
132 97
133 memset(&props, 0, sizeof(struct backlight_properties)); 98 dssdev->panel.timings = nec_8048_panel_timings;
134 props.max_brightness = 255;
135 99
136 bl = backlight_device_register("nec-8048", &dssdev->dev, dssdev, 100 if (gpio_is_valid(pd->qvga_gpio)) {
137 &nec_8048_bl_ops, &props); 101 r = devm_gpio_request_one(&dssdev->dev, pd->qvga_gpio,
138 if (IS_ERR(bl)) { 102 GPIOF_OUT_INIT_HIGH, "lcd QVGA");
139 r = PTR_ERR(bl); 103 if (r)
140 kfree(necd); 104 return r;
141 return r;
142 } 105 }
143 necd->bl = bl;
144
145 bl->props.fb_blank = FB_BLANK_UNBLANK;
146 bl->props.power = FB_BLANK_UNBLANK;
147 bl->props.max_brightness = dssdev->max_backlight_level;
148 bl->props.brightness = dssdev->max_backlight_level;
149 106
150 r = nec_8048_bl_update_status(bl); 107 if (gpio_is_valid(pd->res_gpio)) {
151 if (r < 0) 108 r = devm_gpio_request_one(&dssdev->dev, pd->res_gpio,
152 dev_err(&dssdev->dev, "failed to set lcd brightness\n"); 109 GPIOF_OUT_INIT_LOW, "lcd RES");
110 if (r)
111 return r;
112 }
153 113
154 return 0; 114 return 0;
155} 115}
156 116
157static void nec_8048_panel_remove(struct omap_dss_device *dssdev) 117static void nec_8048_panel_remove(struct omap_dss_device *dssdev)
158{ 118{
159 struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
160 struct backlight_device *bl = necd->bl;
161
162 bl->props.power = FB_BLANK_POWERDOWN;
163 nec_8048_bl_update_status(bl);
164 backlight_device_unregister(bl);
165
166 kfree(necd);
167} 119}
168 120
169static int nec_8048_panel_power_on(struct omap_dss_device *dssdev) 121static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
170{ 122{
123 struct panel_nec_nl8048_data *pd = get_panel_data(dssdev);
171 int r; 124 int r;
172 struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev);
173 struct backlight_device *bl = necd->bl;
174 125
175 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 126 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
176 return 0; 127 return 0;
@@ -182,36 +133,24 @@ static int nec_8048_panel_power_on(struct omap_dss_device *dssdev)
182 if (r) 133 if (r)
183 goto err0; 134 goto err0;
184 135
185 if (dssdev->platform_enable) { 136 if (gpio_is_valid(pd->res_gpio))
186 r = dssdev->platform_enable(dssdev); 137 gpio_set_value_cansleep(pd->res_gpio, 1);
187 if (r)
188 goto err1;
189 }
190
191 r = nec_8048_bl_update_status(bl);
192 if (r < 0)
193 dev_err(&dssdev->dev, "failed to set lcd brightness\n");
194 138
195 return 0; 139 return 0;
196err1: 140
197 omapdss_dpi_display_disable(dssdev);
198err0: 141err0:
199 return r; 142 return r;
200} 143}
201 144
202static void nec_8048_panel_power_off(struct omap_dss_device *dssdev) 145static void nec_8048_panel_power_off(struct omap_dss_device *dssdev)
203{ 146{
204 struct nec_8048_data *necd = dev_get_drvdata(&dssdev->dev); 147 struct panel_nec_nl8048_data *pd = get_panel_data(dssdev);
205 struct backlight_device *bl = necd->bl;
206 148
207 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 149 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
208 return; 150 return;
209 151
210 bl->props.brightness = 0; 152 if (gpio_is_valid(pd->res_gpio))
211 nec_8048_bl_update_status(bl); 153 gpio_set_value_cansleep(pd->res_gpio, 0);
212
213 if (dssdev->platform_disable)
214 dssdev->platform_disable(dssdev);
215 154
216 omapdss_dpi_display_disable(dssdev); 155 omapdss_dpi_display_disable(dssdev);
217} 156}
@@ -303,16 +242,22 @@ static int nec_8048_spi_remove(struct spi_device *spi)
303 return 0; 242 return 0;
304} 243}
305 244
306static int nec_8048_spi_suspend(struct spi_device *spi, pm_message_t mesg) 245#ifdef CONFIG_PM_SLEEP
246
247static int nec_8048_spi_suspend(struct device *dev)
307{ 248{
249 struct spi_device *spi = to_spi_device(dev);
250
308 nec_8048_spi_send(spi, 2, 0x01); 251 nec_8048_spi_send(spi, 2, 0x01);
309 mdelay(40); 252 mdelay(40);
310 253
311 return 0; 254 return 0;
312} 255}
313 256
314static int nec_8048_spi_resume(struct spi_device *spi) 257static int nec_8048_spi_resume(struct device *dev)
315{ 258{
259 struct spi_device *spi = to_spi_device(dev);
260
316 /* reinitialize the panel */ 261 /* reinitialize the panel */
317 spi_setup(spi); 262 spi_setup(spi);
318 nec_8048_spi_send(spi, 2, 0x00); 263 nec_8048_spi_send(spi, 2, 0x00);
@@ -321,14 +266,20 @@ static int nec_8048_spi_resume(struct spi_device *spi)
321 return 0; 266 return 0;
322} 267}
323 268
269static SIMPLE_DEV_PM_OPS(nec_8048_spi_pm_ops, nec_8048_spi_suspend,
270 nec_8048_spi_resume);
271#define NEC_8048_SPI_PM_OPS (&nec_8048_spi_pm_ops)
272#else
273#define NEC_8048_SPI_PM_OPS NULL
274#endif
275
324static struct spi_driver nec_8048_spi_driver = { 276static struct spi_driver nec_8048_spi_driver = {
325 .probe = nec_8048_spi_probe, 277 .probe = nec_8048_spi_probe,
326 .remove = nec_8048_spi_remove, 278 .remove = nec_8048_spi_remove,
327 .suspend = nec_8048_spi_suspend,
328 .resume = nec_8048_spi_resume,
329 .driver = { 279 .driver = {
330 .name = "nec_8048_spi", 280 .name = "nec_8048_spi",
331 .owner = THIS_MODULE, 281 .owner = THIS_MODULE,
282 .pm = NEC_8048_SPI_PM_OPS,
332 }, 283 },
333}; 284};
334 285
diff --git a/drivers/video/omap2/displays/panel-picodlp.c b/drivers/video/omap2/displays/panel-picodlp.c
index 1b94018aac3e..62f2db04fbc8 100644
--- a/drivers/video/omap2/displays/panel-picodlp.c
+++ b/drivers/video/omap2/displays/panel-picodlp.c
@@ -31,7 +31,7 @@
31#include <linux/gpio.h> 31#include <linux/gpio.h>
32 32
33#include <video/omapdss.h> 33#include <video/omapdss.h>
34#include <video/omap-panel-picodlp.h> 34#include <video/omap-panel-data.h>
35 35
36#include "panel-picodlp.h" 36#include "panel-picodlp.h"
37 37
@@ -354,12 +354,6 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
354 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev); 354 struct picodlp_data *picod = dev_get_drvdata(&dssdev->dev);
355 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); 355 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
356 356
357 if (dssdev->platform_enable) {
358 r = dssdev->platform_enable(dssdev);
359 if (r)
360 return r;
361 }
362
363 gpio_set_value(picodlp_pdata->pwrgood_gpio, 0); 357 gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
364 msleep(1); 358 msleep(1);
365 gpio_set_value(picodlp_pdata->pwrgood_gpio, 1); 359 gpio_set_value(picodlp_pdata->pwrgood_gpio, 1);
@@ -398,9 +392,6 @@ static int picodlp_panel_power_on(struct omap_dss_device *dssdev)
398err: 392err:
399 omapdss_dpi_display_disable(dssdev); 393 omapdss_dpi_display_disable(dssdev);
400err1: 394err1:
401 if (dssdev->platform_disable)
402 dssdev->platform_disable(dssdev);
403
404 return r; 395 return r;
405} 396}
406 397
@@ -412,9 +403,6 @@ static void picodlp_panel_power_off(struct omap_dss_device *dssdev)
412 403
413 gpio_set_value(picodlp_pdata->emu_done_gpio, 0); 404 gpio_set_value(picodlp_pdata->emu_done_gpio, 0);
414 gpio_set_value(picodlp_pdata->pwrgood_gpio, 0); 405 gpio_set_value(picodlp_pdata->pwrgood_gpio, 0);
415
416 if (dssdev->platform_disable)
417 dssdev->platform_disable(dssdev);
418} 406}
419 407
420static int picodlp_panel_probe(struct omap_dss_device *dssdev) 408static int picodlp_panel_probe(struct omap_dss_device *dssdev)
@@ -423,11 +411,14 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
423 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev); 411 struct picodlp_panel_data *picodlp_pdata = get_panel_data(dssdev);
424 struct i2c_adapter *adapter; 412 struct i2c_adapter *adapter;
425 struct i2c_client *picodlp_i2c_client; 413 struct i2c_client *picodlp_i2c_client;
426 int r = 0, picodlp_adapter_id; 414 int r, picodlp_adapter_id;
427 415
428 dssdev->panel.timings = pico_ls_timings; 416 dssdev->panel.timings = pico_ls_timings;
429 417
430 picod = kzalloc(sizeof(struct picodlp_data), GFP_KERNEL); 418 if (!picodlp_pdata)
419 return -EINVAL;
420
421 picod = devm_kzalloc(&dssdev->dev, sizeof(*picod), GFP_KERNEL);
431 if (!picod) 422 if (!picod)
432 return -ENOMEM; 423 return -ENOMEM;
433 424
@@ -438,25 +429,37 @@ static int picodlp_panel_probe(struct omap_dss_device *dssdev)
438 adapter = i2c_get_adapter(picodlp_adapter_id); 429 adapter = i2c_get_adapter(picodlp_adapter_id);
439 if (!adapter) { 430 if (!adapter) {
440 dev_err(&dssdev->dev, "can't get i2c adapter\n"); 431 dev_err(&dssdev->dev, "can't get i2c adapter\n");
441 r = -ENODEV; 432 return -ENODEV;
442 goto err;
443 } 433 }
444 434
445 picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info); 435 picodlp_i2c_client = i2c_new_device(adapter, &picodlp_i2c_board_info);
446 if (!picodlp_i2c_client) { 436 if (!picodlp_i2c_client) {
447 dev_err(&dssdev->dev, "can't add i2c device::" 437 dev_err(&dssdev->dev, "can't add i2c device::"
448 " picodlp_i2c_client is NULL\n"); 438 " picodlp_i2c_client is NULL\n");
449 r = -ENODEV; 439 return -ENODEV;
450 goto err;
451 } 440 }
452 441
453 picod->picodlp_i2c_client = picodlp_i2c_client; 442 picod->picodlp_i2c_client = picodlp_i2c_client;
454 443
455 dev_set_drvdata(&dssdev->dev, picod); 444 dev_set_drvdata(&dssdev->dev, picod);
456 return r; 445
457err: 446 if (gpio_is_valid(picodlp_pdata->emu_done_gpio)) {
458 kfree(picod); 447 r = devm_gpio_request_one(&dssdev->dev,
459 return r; 448 picodlp_pdata->emu_done_gpio,
449 GPIOF_IN, "DLP EMU DONE");
450 if (r)
451 return r;
452 }
453
454 if (gpio_is_valid(picodlp_pdata->pwrgood_gpio)) {
455 r = devm_gpio_request_one(&dssdev->dev,
456 picodlp_pdata->pwrgood_gpio,
457 GPIOF_OUT_INIT_LOW, "DLP PWRGOOD");
458 if (r)
459 return r;
460 }
461
462 return 0;
460} 463}
461 464
462static void picodlp_panel_remove(struct omap_dss_device *dssdev) 465static void picodlp_panel_remove(struct omap_dss_device *dssdev)
diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
index cada8c621e01..74cb0eb45311 100644
--- a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
@@ -20,16 +20,13 @@
20#include <linux/module.h> 20#include <linux/module.h>
21#include <linux/delay.h> 21#include <linux/delay.h>
22#include <linux/device.h> 22#include <linux/device.h>
23#include <linux/backlight.h>
24#include <linux/fb.h> 23#include <linux/fb.h>
25#include <linux/err.h> 24#include <linux/err.h>
26#include <linux/slab.h> 25#include <linux/slab.h>
26#include <linux/gpio.h>
27 27
28#include <video/omapdss.h> 28#include <video/omapdss.h>
29 29#include <video/omap-panel-data.h>
30struct sharp_data {
31 struct backlight_device *bl;
32};
33 30
34static struct omap_video_timings sharp_ls_timings = { 31static struct omap_video_timings sharp_ls_timings = {
35 .x_res = 480, 32 .x_res = 480,
@@ -52,91 +49,67 @@ static struct omap_video_timings sharp_ls_timings = {
52 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, 49 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
53}; 50};
54 51
55static int sharp_ls_bl_update_status(struct backlight_device *bl) 52static inline struct panel_sharp_ls037v7dw01_data
53*get_panel_data(const struct omap_dss_device *dssdev)
56{ 54{
57 struct omap_dss_device *dssdev = dev_get_drvdata(&bl->dev); 55 return (struct panel_sharp_ls037v7dw01_data *) dssdev->data;
58 int level;
59
60 if (!dssdev->set_backlight)
61 return -EINVAL;
62
63 if (bl->props.fb_blank == FB_BLANK_UNBLANK &&
64 bl->props.power == FB_BLANK_UNBLANK)
65 level = bl->props.brightness;
66 else
67 level = 0;
68
69 return dssdev->set_backlight(dssdev, level);
70} 56}
71 57
72static int sharp_ls_bl_get_brightness(struct backlight_device *bl)
73{
74 if (bl->props.fb_blank == FB_BLANK_UNBLANK &&
75 bl->props.power == FB_BLANK_UNBLANK)
76 return bl->props.brightness;
77
78 return 0;
79}
80
81static const struct backlight_ops sharp_ls_bl_ops = {
82 .get_brightness = sharp_ls_bl_get_brightness,
83 .update_status = sharp_ls_bl_update_status,
84};
85
86
87
88static int sharp_ls_panel_probe(struct omap_dss_device *dssdev) 58static int sharp_ls_panel_probe(struct omap_dss_device *dssdev)
89{ 59{
90 struct backlight_properties props; 60 struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);
91 struct backlight_device *bl;
92 struct sharp_data *sd;
93 int r; 61 int r;
94 62
63 if (!pd)
64 return -EINVAL;
65
95 dssdev->panel.timings = sharp_ls_timings; 66 dssdev->panel.timings = sharp_ls_timings;
96 67
97 sd = kzalloc(sizeof(*sd), GFP_KERNEL); 68 if (gpio_is_valid(pd->mo_gpio)) {
98 if (!sd) 69 r = devm_gpio_request_one(&dssdev->dev, pd->mo_gpio,
99 return -ENOMEM; 70 GPIOF_OUT_INIT_LOW, "lcd MO");
71 if (r)
72 return r;
73 }
100 74
101 dev_set_drvdata(&dssdev->dev, sd); 75 if (gpio_is_valid(pd->lr_gpio)) {
76 r = devm_gpio_request_one(&dssdev->dev, pd->lr_gpio,
77 GPIOF_OUT_INIT_HIGH, "lcd LR");
78 if (r)
79 return r;
80 }
102 81
103 memset(&props, 0, sizeof(struct backlight_properties)); 82 if (gpio_is_valid(pd->ud_gpio)) {
104 props.max_brightness = dssdev->max_backlight_level; 83 r = devm_gpio_request_one(&dssdev->dev, pd->ud_gpio,
105 props.type = BACKLIGHT_RAW; 84 GPIOF_OUT_INIT_HIGH, "lcd UD");
85 if (r)
86 return r;
87 }
106 88
107 bl = backlight_device_register("sharp-ls", &dssdev->dev, dssdev, 89 if (gpio_is_valid(pd->resb_gpio)) {
108 &sharp_ls_bl_ops, &props); 90 r = devm_gpio_request_one(&dssdev->dev, pd->resb_gpio,
109 if (IS_ERR(bl)) { 91 GPIOF_OUT_INIT_LOW, "lcd RESB");
110 r = PTR_ERR(bl); 92 if (r)
111 kfree(sd); 93 return r;
112 return r;
113 } 94 }
114 sd->bl = bl;
115 95
116 bl->props.fb_blank = FB_BLANK_UNBLANK; 96 if (gpio_is_valid(pd->ini_gpio)) {
117 bl->props.power = FB_BLANK_UNBLANK; 97 r = devm_gpio_request_one(&dssdev->dev, pd->ini_gpio,
118 bl->props.brightness = dssdev->max_backlight_level; 98 GPIOF_OUT_INIT_LOW, "lcd INI");
119 r = sharp_ls_bl_update_status(bl); 99 if (r)
120 if (r < 0) 100 return r;
121 dev_err(&dssdev->dev, "failed to set lcd brightness\n"); 101 }
122 102
123 return 0; 103 return 0;
124} 104}
125 105
126static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev) 106static void __exit sharp_ls_panel_remove(struct omap_dss_device *dssdev)
127{ 107{
128 struct sharp_data *sd = dev_get_drvdata(&dssdev->dev);
129 struct backlight_device *bl = sd->bl;
130
131 bl->props.power = FB_BLANK_POWERDOWN;
132 sharp_ls_bl_update_status(bl);
133 backlight_device_unregister(bl);
134
135 kfree(sd);
136} 108}
137 109
138static int sharp_ls_power_on(struct omap_dss_device *dssdev) 110static int sharp_ls_power_on(struct omap_dss_device *dssdev)
139{ 111{
112 struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);
140 int r = 0; 113 int r = 0;
141 114
142 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) 115 if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
@@ -152,26 +125,29 @@ static int sharp_ls_power_on(struct omap_dss_device *dssdev)
152 /* wait couple of vsyncs until enabling the LCD */ 125 /* wait couple of vsyncs until enabling the LCD */
153 msleep(50); 126 msleep(50);
154 127
155 if (dssdev->platform_enable) { 128 if (gpio_is_valid(pd->resb_gpio))
156 r = dssdev->platform_enable(dssdev); 129 gpio_set_value_cansleep(pd->resb_gpio, 1);
157 if (r) 130
158 goto err1; 131 if (gpio_is_valid(pd->ini_gpio))
159 } 132 gpio_set_value_cansleep(pd->ini_gpio, 1);
160 133
161 return 0; 134 return 0;
162err1:
163 omapdss_dpi_display_disable(dssdev);
164err0: 135err0:
165 return r; 136 return r;
166} 137}
167 138
168static void sharp_ls_power_off(struct omap_dss_device *dssdev) 139static void sharp_ls_power_off(struct omap_dss_device *dssdev)
169{ 140{
141 struct panel_sharp_ls037v7dw01_data *pd = get_panel_data(dssdev);
142
170 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 143 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
171 return; 144 return;
172 145
173 if (dssdev->platform_disable) 146 if (gpio_is_valid(pd->ini_gpio))
174 dssdev->platform_disable(dssdev); 147 gpio_set_value_cansleep(pd->ini_gpio, 0);
148
149 if (gpio_is_valid(pd->resb_gpio))
150 gpio_set_value_cansleep(pd->resb_gpio, 0);
175 151
176 /* wait at least 5 vsyncs after disabling the LCD */ 152 /* wait at least 5 vsyncs after disabling the LCD */
177 153
diff --git a/drivers/video/omap2/displays/panel-taal.c b/drivers/video/omap2/displays/panel-taal.c
index a32407a5735a..c4f78bda115a 100644
--- a/drivers/video/omap2/displays/panel-taal.c
+++ b/drivers/video/omap2/displays/panel-taal.c
@@ -33,7 +33,7 @@
33#include <linux/mutex.h> 33#include <linux/mutex.h>
34 34
35#include <video/omapdss.h> 35#include <video/omapdss.h>
36#include <video/omap-panel-nokia-dsi.h> 36#include <video/omap-panel-data.h>
37#include <video/mipi_display.h> 37#include <video/mipi_display.h>
38 38
39/* DSI Virtual channel. Hardcoded for now. */ 39/* DSI Virtual channel. Hardcoded for now. */
@@ -54,61 +54,6 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable);
54 54
55static int taal_panel_reset(struct omap_dss_device *dssdev); 55static int taal_panel_reset(struct omap_dss_device *dssdev);
56 56
57/**
58 * struct panel_config - panel configuration
59 * @name: panel name
60 * @type: panel type
61 * @timings: panel resolution
62 * @sleep: various panel specific delays, passed to msleep() if non-zero
63 * @reset_sequence: reset sequence timings, passed to udelay() if non-zero
64 * @regulators: array of panel regulators
65 * @num_regulators: number of regulators in the array
66 */
67struct panel_config {
68 const char *name;
69 int type;
70
71 struct omap_video_timings timings;
72
73 struct {
74 unsigned int sleep_in;
75 unsigned int sleep_out;
76 unsigned int hw_reset;
77 unsigned int enable_te;
78 } sleep;
79
80 struct {
81 unsigned int high;
82 unsigned int low;
83 } reset_sequence;
84
85};
86
87enum {
88 PANEL_TAAL,
89};
90
91static struct panel_config panel_configs[] = {
92 {
93 .name = "taal",
94 .type = PANEL_TAAL,
95 .timings = {
96 .x_res = 864,
97 .y_res = 480,
98 },
99 .sleep = {
100 .sleep_in = 5,
101 .sleep_out = 5,
102 .hw_reset = 5,
103 .enable_te = 100, /* possible panel bug */
104 },
105 .reset_sequence = {
106 .high = 10,
107 .low = 10,
108 },
109 },
110};
111
112struct taal_data { 57struct taal_data {
113 struct mutex lock; 58 struct mutex lock;
114 59
@@ -121,9 +66,6 @@ struct taal_data {
121 66
122 struct omap_dss_device *dssdev; 67 struct omap_dss_device *dssdev;
123 68
124 /* panel specific HW info */
125 struct panel_config *panel_config;
126
127 /* panel HW configuration from DT or platform data */ 69 /* panel HW configuration from DT or platform data */
128 int reset_gpio; 70 int reset_gpio;
129 int ext_te_gpio; 71 int ext_te_gpio;
@@ -134,8 +76,6 @@ struct taal_data {
134 76
135 /* runtime variables */ 77 /* runtime variables */
136 bool enabled; 78 bool enabled;
137 u8 rotate;
138 bool mirror;
139 79
140 bool te_enabled; 80 bool te_enabled;
141 81
@@ -221,8 +161,7 @@ static int taal_sleep_in(struct taal_data *td)
221 161
222 hw_guard_start(td, 120); 162 hw_guard_start(td, 120);
223 163
224 if (td->panel_config->sleep.sleep_in) 164 msleep(5);
225 msleep(td->panel_config->sleep.sleep_in);
226 165
227 return 0; 166 return 0;
228} 167}
@@ -239,8 +178,7 @@ static int taal_sleep_out(struct taal_data *td)
239 178
240 hw_guard_start(td, 120); 179 hw_guard_start(td, 120);
241 180
242 if (td->panel_config->sleep.sleep_out) 181 msleep(5);
243 msleep(td->panel_config->sleep.sleep_out);
244 182
245 return 0; 183 return 0;
246} 184}
@@ -262,49 +200,6 @@ static int taal_get_id(struct taal_data *td, u8 *id1, u8 *id2, u8 *id3)
262 return 0; 200 return 0;
263} 201}
264 202
265static int taal_set_addr_mode(struct taal_data *td, u8 rotate, bool mirror)
266{
267 int r;
268 u8 mode;
269 int b5, b6, b7;
270
271 r = taal_dcs_read_1(td, MIPI_DCS_GET_ADDRESS_MODE, &mode);
272 if (r)
273 return r;
274
275 switch (rotate) {
276 default:
277 case 0:
278 b7 = 0;
279 b6 = 0;
280 b5 = 0;
281 break;
282 case 1:
283 b7 = 0;
284 b6 = 1;
285 b5 = 1;
286 break;
287 case 2:
288 b7 = 1;
289 b6 = 1;
290 b5 = 0;
291 break;
292 case 3:
293 b7 = 1;
294 b6 = 0;
295 b5 = 1;
296 break;
297 }
298
299 if (mirror)
300 b6 = !b6;
301
302 mode &= ~((1<<7) | (1<<6) | (1<<5));
303 mode |= (b7 << 7) | (b6 << 6) | (b5 << 5);
304
305 return taal_dcs_write_1(td, MIPI_DCS_SET_ADDRESS_MODE, mode);
306}
307
308static int taal_set_update_window(struct taal_data *td, 203static int taal_set_update_window(struct taal_data *td,
309 u16 x, u16 y, u16 w, u16 h) 204 u16 x, u16 y, u16 w, u16 h)
310{ 205{
@@ -515,15 +410,8 @@ static const struct backlight_ops taal_bl_ops = {
515static void taal_get_resolution(struct omap_dss_device *dssdev, 410static void taal_get_resolution(struct omap_dss_device *dssdev,
516 u16 *xres, u16 *yres) 411 u16 *xres, u16 *yres)
517{ 412{
518 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 413 *xres = dssdev->panel.timings.x_res;
519 414 *yres = dssdev->panel.timings.y_res;
520 if (td->rotate == 0 || td->rotate == 2) {
521 *xres = dssdev->panel.timings.x_res;
522 *yres = dssdev->panel.timings.y_res;
523 } else {
524 *yres = dssdev->panel.timings.x_res;
525 *xres = dssdev->panel.timings.y_res;
526 }
527} 415}
528 416
529static ssize_t taal_num_errors_show(struct device *dev, 417static ssize_t taal_num_errors_show(struct device *dev,
@@ -845,17 +733,14 @@ static void taal_hw_reset(struct omap_dss_device *dssdev)
845 return; 733 return;
846 734
847 gpio_set_value(td->reset_gpio, 1); 735 gpio_set_value(td->reset_gpio, 1);
848 if (td->panel_config->reset_sequence.high) 736 udelay(10);
849 udelay(td->panel_config->reset_sequence.high);
850 /* reset the panel */ 737 /* reset the panel */
851 gpio_set_value(td->reset_gpio, 0); 738 gpio_set_value(td->reset_gpio, 0);
852 /* assert reset */ 739 /* assert reset */
853 if (td->panel_config->reset_sequence.low) 740 udelay(10);
854 udelay(td->panel_config->reset_sequence.low);
855 gpio_set_value(td->reset_gpio, 1); 741 gpio_set_value(td->reset_gpio, 1);
856 /* wait after releasing reset */ 742 /* wait after releasing reset */
857 if (td->panel_config->sleep.hw_reset) 743 msleep(5);
858 msleep(td->panel_config->sleep.hw_reset);
859} 744}
860 745
861static void taal_probe_pdata(struct taal_data *td, 746static void taal_probe_pdata(struct taal_data *td,
@@ -881,8 +766,7 @@ static int taal_probe(struct omap_dss_device *dssdev)
881 struct backlight_properties props; 766 struct backlight_properties props;
882 struct taal_data *td; 767 struct taal_data *td;
883 struct backlight_device *bldev = NULL; 768 struct backlight_device *bldev = NULL;
884 int r, i; 769 int r;
885 const char *panel_name;
886 770
887 dev_dbg(&dssdev->dev, "probe\n"); 771 dev_dbg(&dssdev->dev, "probe\n");
888 772
@@ -897,26 +781,13 @@ static int taal_probe(struct omap_dss_device *dssdev)
897 const struct nokia_dsi_panel_data *pdata = dssdev->data; 781 const struct nokia_dsi_panel_data *pdata = dssdev->data;
898 782
899 taal_probe_pdata(td, pdata); 783 taal_probe_pdata(td, pdata);
900
901 panel_name = pdata->name;
902 } else { 784 } else {
903 return -ENODEV; 785 return -ENODEV;
904 } 786 }
905 787
906 if (panel_name == NULL) 788 dssdev->panel.timings.x_res = 864;
907 return -EINVAL; 789 dssdev->panel.timings.y_res = 480;
908 790 dssdev->panel.timings.pixel_clock = DIV_ROUND_UP(864 * 480 * 60, 1000);
909 for (i = 0; i < ARRAY_SIZE(panel_configs); i++) {
910 if (strcmp(panel_name, panel_configs[i].name) == 0) {
911 td->panel_config = &panel_configs[i];
912 break;
913 }
914 }
915
916 if (!td->panel_config)
917 return -EINVAL;
918
919 dssdev->panel.timings = td->panel_config->timings;
920 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888; 791 dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
921 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE | 792 dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
922 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM; 793 OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
@@ -1049,6 +920,15 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1049 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 920 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1050 u8 id1, id2, id3; 921 u8 id1, id2, id3;
1051 int r; 922 int r;
923 struct omap_dss_dsi_config dsi_config = {
924 .mode = OMAP_DSS_DSI_CMD_MODE,
925 .pixel_format = OMAP_DSS_DSI_FMT_RGB888,
926 .timings = &dssdev->panel.timings,
927 .hs_clk_min = 150000000,
928 .hs_clk_max = 300000000,
929 .lp_clk_min = 7000000,
930 .lp_clk_max = 10000000,
931 };
1052 932
1053 r = omapdss_dsi_configure_pins(dssdev, &td->pin_config); 933 r = omapdss_dsi_configure_pins(dssdev, &td->pin_config);
1054 if (r) { 934 if (r) {
@@ -1056,14 +936,9 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1056 goto err0; 936 goto err0;
1057 }; 937 };
1058 938
1059 omapdss_dsi_set_size(dssdev, dssdev->panel.timings.x_res, 939 r = omapdss_dsi_set_config(dssdev, &dsi_config);
1060 dssdev->panel.timings.y_res);
1061 omapdss_dsi_set_pixel_format(dssdev, OMAP_DSS_DSI_FMT_RGB888);
1062 omapdss_dsi_set_operation_mode(dssdev, OMAP_DSS_DSI_CMD_MODE);
1063
1064 r = omapdss_dsi_set_clocks(dssdev, 216000000, 10000000);
1065 if (r) { 940 if (r) {
1066 dev_err(&dssdev->dev, "failed to set HS and LP clocks\n"); 941 dev_err(&dssdev->dev, "failed to configure DSI\n");
1067 goto err0; 942 goto err0;
1068 } 943 }
1069 944
@@ -1086,8 +961,7 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1086 goto err; 961 goto err;
1087 962
1088 /* on early Taal revisions CABC is broken */ 963 /* on early Taal revisions CABC is broken */
1089 if (td->panel_config->type == PANEL_TAAL && 964 if (id2 == 0x00 || id2 == 0xff || id2 == 0x81)
1090 (id2 == 0x00 || id2 == 0xff || id2 == 0x81))
1091 td->cabc_broken = true; 965 td->cabc_broken = true;
1092 966
1093 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff); 967 r = taal_dcs_write_1(td, DCS_BRIGHTNESS, 0xff);
@@ -1104,10 +978,6 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1104 if (r) 978 if (r)
1105 goto err; 979 goto err;
1106 980
1107 r = taal_set_addr_mode(td, td->rotate, td->mirror);
1108 if (r)
1109 goto err;
1110
1111 if (!td->cabc_broken) { 981 if (!td->cabc_broken) {
1112 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode); 982 r = taal_dcs_write_1(td, DCS_WRITE_CABC, td->cabc_mode);
1113 if (r) 983 if (r)
@@ -1129,8 +999,8 @@ static int taal_power_on(struct omap_dss_device *dssdev)
1129 td->enabled = 1; 999 td->enabled = 1;
1130 1000
1131 if (!td->intro_printed) { 1001 if (!td->intro_printed) {
1132 dev_info(&dssdev->dev, "%s panel revision %02x.%02x.%02x\n", 1002 dev_info(&dssdev->dev, "panel revision %02x.%02x.%02x\n",
1133 td->panel_config->name, id1, id2, id3); 1003 id1, id2, id3);
1134 if (td->cabc_broken) 1004 if (td->cabc_broken)
1135 dev_info(&dssdev->dev, 1005 dev_info(&dssdev->dev,
1136 "old Taal version, CABC disabled\n"); 1006 "old Taal version, CABC disabled\n");
@@ -1311,8 +1181,8 @@ static int taal_update(struct omap_dss_device *dssdev,
1311 1181
1312 /* XXX no need to send this every frame, but dsi break if not done */ 1182 /* XXX no need to send this every frame, but dsi break if not done */
1313 r = taal_set_update_window(td, 0, 0, 1183 r = taal_set_update_window(td, 0, 0,
1314 td->panel_config->timings.x_res, 1184 dssdev->panel.timings.x_res,
1315 td->panel_config->timings.y_res); 1185 dssdev->panel.timings.y_res);
1316 if (r) 1186 if (r)
1317 goto err; 1187 goto err;
1318 1188
@@ -1365,8 +1235,8 @@ static int _taal_enable_te(struct omap_dss_device *dssdev, bool enable)
1365 if (!gpio_is_valid(td->ext_te_gpio)) 1235 if (!gpio_is_valid(td->ext_te_gpio))
1366 omapdss_dsi_enable_te(dssdev, enable); 1236 omapdss_dsi_enable_te(dssdev, enable);
1367 1237
1368 if (td->panel_config->sleep.enable_te) 1238 /* possible panel bug */
1369 msleep(td->panel_config->sleep.enable_te); 1239 msleep(100);
1370 1240
1371 return r; 1241 return r;
1372} 1242}
@@ -1419,112 +1289,6 @@ static int taal_get_te(struct omap_dss_device *dssdev)
1419 return r; 1289 return r;
1420} 1290}
1421 1291
1422static int taal_rotate(struct omap_dss_device *dssdev, u8 rotate)
1423{
1424 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1425 u16 dw, dh;
1426 int r;
1427
1428 dev_dbg(&dssdev->dev, "rotate %d\n", rotate);
1429
1430 mutex_lock(&td->lock);
1431
1432 if (td->rotate == rotate)
1433 goto end;
1434
1435 dsi_bus_lock(dssdev);
1436
1437 if (td->enabled) {
1438 r = taal_wake_up(dssdev);
1439 if (r)
1440 goto err;
1441
1442 r = taal_set_addr_mode(td, rotate, td->mirror);
1443 if (r)
1444 goto err;
1445 }
1446
1447 if (rotate == 0 || rotate == 2) {
1448 dw = dssdev->panel.timings.x_res;
1449 dh = dssdev->panel.timings.y_res;
1450 } else {
1451 dw = dssdev->panel.timings.y_res;
1452 dh = dssdev->panel.timings.x_res;
1453 }
1454
1455 omapdss_dsi_set_size(dssdev, dw, dh);
1456
1457 td->rotate = rotate;
1458
1459 dsi_bus_unlock(dssdev);
1460end:
1461 mutex_unlock(&td->lock);
1462 return 0;
1463err:
1464 dsi_bus_unlock(dssdev);
1465 mutex_unlock(&td->lock);
1466 return r;
1467}
1468
1469static u8 taal_get_rotate(struct omap_dss_device *dssdev)
1470{
1471 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1472 int r;
1473
1474 mutex_lock(&td->lock);
1475 r = td->rotate;
1476 mutex_unlock(&td->lock);
1477
1478 return r;
1479}
1480
1481static int taal_mirror(struct omap_dss_device *dssdev, bool enable)
1482{
1483 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1484 int r;
1485
1486 dev_dbg(&dssdev->dev, "mirror %d\n", enable);
1487
1488 mutex_lock(&td->lock);
1489
1490 if (td->mirror == enable)
1491 goto end;
1492
1493 dsi_bus_lock(dssdev);
1494 if (td->enabled) {
1495 r = taal_wake_up(dssdev);
1496 if (r)
1497 goto err;
1498
1499 r = taal_set_addr_mode(td, td->rotate, enable);
1500 if (r)
1501 goto err;
1502 }
1503
1504 td->mirror = enable;
1505
1506 dsi_bus_unlock(dssdev);
1507end:
1508 mutex_unlock(&td->lock);
1509 return 0;
1510err:
1511 dsi_bus_unlock(dssdev);
1512 mutex_unlock(&td->lock);
1513 return r;
1514}
1515
1516static bool taal_get_mirror(struct omap_dss_device *dssdev)
1517{
1518 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
1519 int r;
1520
1521 mutex_lock(&td->lock);
1522 r = td->mirror;
1523 mutex_unlock(&td->lock);
1524
1525 return r;
1526}
1527
1528static int taal_run_test(struct omap_dss_device *dssdev, int test_num) 1292static int taal_run_test(struct omap_dss_device *dssdev, int test_num)
1529{ 1293{
1530 struct taal_data *td = dev_get_drvdata(&dssdev->dev); 1294 struct taal_data *td = dev_get_drvdata(&dssdev->dev);
@@ -1758,10 +1522,6 @@ static struct omap_dss_driver taal_driver = {
1758 .enable_te = taal_enable_te, 1522 .enable_te = taal_enable_te,
1759 .get_te = taal_get_te, 1523 .get_te = taal_get_te,
1760 1524
1761 .set_rotate = taal_rotate,
1762 .get_rotate = taal_get_rotate,
1763 .set_mirror = taal_mirror,
1764 .get_mirror = taal_get_mirror,
1765 .run_test = taal_run_test, 1525 .run_test = taal_run_test,
1766 .memory_read = taal_memory_read, 1526 .memory_read = taal_memory_read,
1767 1527
diff --git a/drivers/video/omap2/displays/panel-tfp410.c b/drivers/video/omap2/displays/panel-tfp410.c
index 8281baafe1ef..a1dba868cef1 100644
--- a/drivers/video/omap2/displays/panel-tfp410.c
+++ b/drivers/video/omap2/displays/panel-tfp410.c
@@ -24,7 +24,7 @@
24#include <linux/gpio.h> 24#include <linux/gpio.h>
25#include <drm/drm_edid.h> 25#include <drm/drm_edid.h>
26 26
27#include <video/omap-panel-tfp410.h> 27#include <video/omap-panel-data.h>
28 28
29static const struct omap_video_timings tfp410_default_timings = { 29static const struct omap_video_timings tfp410_default_timings = {
30 .x_res = 640, 30 .x_res = 640,
diff --git a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
index 048c98381ef6..abf2bc4a18ab 100644
--- a/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
+++ b/drivers/video/omap2/displays/panel-tpo-td043mtea1.c
@@ -18,6 +18,7 @@
18#include <linux/slab.h> 18#include <linux/slab.h>
19 19
20#include <video/omapdss.h> 20#include <video/omapdss.h>
21#include <video/omap-panel-data.h>
21 22
22#define TPO_R02_MODE(x) ((x) & 7) 23#define TPO_R02_MODE(x) ((x) & 7)
23#define TPO_R02_MODE_800x480 7 24#define TPO_R02_MODE_800x480 7
@@ -278,9 +279,14 @@ static const struct omap_video_timings tpo_td043_timings = {
278 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES, 279 .sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES,
279}; 280};
280 281
282static inline struct panel_tpo_td043_data
283*get_panel_data(const struct omap_dss_device *dssdev)
284{
285 return (struct panel_tpo_td043_data *) dssdev->data;
286}
287
281static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043) 288static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
282{ 289{
283 int nreset_gpio = tpo_td043->nreset_gpio;
284 int r; 290 int r;
285 291
286 if (tpo_td043->powered_on) 292 if (tpo_td043->powered_on)
@@ -293,8 +299,8 @@ static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
293 /* wait for panel to stabilize */ 299 /* wait for panel to stabilize */
294 msleep(160); 300 msleep(160);
295 301
296 if (gpio_is_valid(nreset_gpio)) 302 if (gpio_is_valid(tpo_td043->nreset_gpio))
297 gpio_set_value(nreset_gpio, 1); 303 gpio_set_value(tpo_td043->nreset_gpio, 1);
298 304
299 tpo_td043_write(tpo_td043->spi, 2, 305 tpo_td043_write(tpo_td043->spi, 2,
300 TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING); 306 TPO_R02_MODE(tpo_td043->mode) | TPO_R02_NCLK_RISING);
@@ -311,16 +317,14 @@ static int tpo_td043_power_on(struct tpo_td043_device *tpo_td043)
311 317
312static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043) 318static void tpo_td043_power_off(struct tpo_td043_device *tpo_td043)
313{ 319{
314 int nreset_gpio = tpo_td043->nreset_gpio;
315
316 if (!tpo_td043->powered_on) 320 if (!tpo_td043->powered_on)
317 return; 321 return;
318 322
319 tpo_td043_write(tpo_td043->spi, 3, 323 tpo_td043_write(tpo_td043->spi, 3,
320 TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM); 324 TPO_R03_VAL_STANDBY | TPO_R03_EN_PWM);
321 325
322 if (gpio_is_valid(nreset_gpio)) 326 if (gpio_is_valid(tpo_td043->nreset_gpio))
323 gpio_set_value(nreset_gpio, 0); 327 gpio_set_value(tpo_td043->nreset_gpio, 0);
324 328
325 /* wait for at least 2 vsyncs before cutting off power */ 329 /* wait for at least 2 vsyncs before cutting off power */
326 msleep(50); 330 msleep(50);
@@ -347,12 +351,6 @@ static int tpo_td043_enable_dss(struct omap_dss_device *dssdev)
347 if (r) 351 if (r)
348 goto err0; 352 goto err0;
349 353
350 if (dssdev->platform_enable) {
351 r = dssdev->platform_enable(dssdev);
352 if (r)
353 goto err1;
354 }
355
356 /* 354 /*
357 * If we are resuming from system suspend, SPI clocks might not be 355 * If we are resuming from system suspend, SPI clocks might not be
358 * enabled yet, so we'll program the LCD from SPI PM resume callback. 356 * enabled yet, so we'll program the LCD from SPI PM resume callback.
@@ -379,9 +377,6 @@ static void tpo_td043_disable_dss(struct omap_dss_device *dssdev)
379 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) 377 if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
380 return; 378 return;
381 379
382 if (dssdev->platform_disable)
383 dssdev->platform_disable(dssdev);
384
385 omapdss_dpi_display_disable(dssdev); 380 omapdss_dpi_display_disable(dssdev);
386 381
387 if (!tpo_td043->spi_suspended) 382 if (!tpo_td043->spi_suspended)
@@ -407,7 +402,7 @@ static void tpo_td043_disable(struct omap_dss_device *dssdev)
407static int tpo_td043_probe(struct omap_dss_device *dssdev) 402static int tpo_td043_probe(struct omap_dss_device *dssdev)
408{ 403{
409 struct tpo_td043_device *tpo_td043 = g_tpo_td043; 404 struct tpo_td043_device *tpo_td043 = g_tpo_td043;
410 int nreset_gpio = dssdev->reset_gpio; 405 struct panel_tpo_td043_data *pdata = get_panel_data(dssdev);
411 int ret = 0; 406 int ret = 0;
412 407
413 dev_dbg(&dssdev->dev, "probe\n"); 408 dev_dbg(&dssdev->dev, "probe\n");
@@ -417,6 +412,11 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
417 return -ENODEV; 412 return -ENODEV;
418 } 413 }
419 414
415 if (!pdata)
416 return -EINVAL;
417
418 tpo_td043->nreset_gpio = pdata->nreset_gpio;
419
420 dssdev->panel.timings = tpo_td043_timings; 420 dssdev->panel.timings = tpo_td043_timings;
421 dssdev->ctrl.pixel_size = 24; 421 dssdev->ctrl.pixel_size = 24;
422 422
@@ -430,9 +430,10 @@ static int tpo_td043_probe(struct omap_dss_device *dssdev)
430 goto fail_regulator; 430 goto fail_regulator;
431 } 431 }
432 432
433 if (gpio_is_valid(nreset_gpio)) { 433 if (gpio_is_valid(tpo_td043->nreset_gpio)) {
434 ret = gpio_request_one(nreset_gpio, GPIOF_OUT_INIT_LOW, 434 ret = devm_gpio_request_one(&dssdev->dev,
435 "lcd reset"); 435 tpo_td043->nreset_gpio, GPIOF_OUT_INIT_LOW,
436 "lcd reset");
436 if (ret < 0) { 437 if (ret < 0) {
437 dev_err(&dssdev->dev, "couldn't request reset GPIO\n"); 438 dev_err(&dssdev->dev, "couldn't request reset GPIO\n");
438 goto fail_gpio_req; 439 goto fail_gpio_req;
@@ -457,14 +458,11 @@ fail_regulator:
457static void tpo_td043_remove(struct omap_dss_device *dssdev) 458static void tpo_td043_remove(struct omap_dss_device *dssdev)
458{ 459{
459 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev); 460 struct tpo_td043_device *tpo_td043 = dev_get_drvdata(&dssdev->dev);
460 int nreset_gpio = dssdev->reset_gpio;
461 461
462 dev_dbg(&dssdev->dev, "remove\n"); 462 dev_dbg(&dssdev->dev, "remove\n");
463 463
464 sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group); 464 sysfs_remove_group(&dssdev->dev.kobj, &tpo_td043_attr_group);
465 regulator_put(tpo_td043->vcc_reg); 465 regulator_put(tpo_td043->vcc_reg);
466 if (gpio_is_valid(nreset_gpio))
467 gpio_free(nreset_gpio);
468} 466}
469 467
470static void tpo_td043_set_timings(struct omap_dss_device *dssdev, 468static void tpo_td043_set_timings(struct omap_dss_device *dssdev,
@@ -527,7 +525,6 @@ static int tpo_td043_spi_probe(struct spi_device *spi)
527 return -ENOMEM; 525 return -ENOMEM;
528 526
529 tpo_td043->spi = spi; 527 tpo_td043->spi = spi;
530 tpo_td043->nreset_gpio = dssdev->reset_gpio;
531 dev_set_drvdata(&spi->dev, tpo_td043); 528 dev_set_drvdata(&spi->dev, tpo_td043);
532 g_tpo_td043 = tpo_td043; 529 g_tpo_td043 = tpo_td043;
533 530
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d446bdfc4c82..a4b356a9780d 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -435,20 +435,27 @@ static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_man
435static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) 435static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
436{ 436{
437 unsigned long timeout = msecs_to_jiffies(500); 437 unsigned long timeout = msecs_to_jiffies(500);
438 struct omap_dss_device *dssdev = mgr->get_device(mgr);
439 u32 irq; 438 u32 irq;
440 int r; 439 int r;
441 440
441 if (mgr->output == NULL)
442 return -ENODEV;
443
442 r = dispc_runtime_get(); 444 r = dispc_runtime_get();
443 if (r) 445 if (r)
444 return r; 446 return r;
445 447
446 if (dssdev->type == OMAP_DISPLAY_TYPE_VENC) 448 switch (mgr->output->id) {
449 case OMAP_DSS_OUTPUT_VENC:
447 irq = DISPC_IRQ_EVSYNC_ODD; 450 irq = DISPC_IRQ_EVSYNC_ODD;
448 else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI) 451 break;
452 case OMAP_DSS_OUTPUT_HDMI:
449 irq = DISPC_IRQ_EVSYNC_EVEN; 453 irq = DISPC_IRQ_EVSYNC_EVEN;
450 else 454 break;
455 default:
451 irq = dispc_mgr_get_vsync_irq(mgr->id); 456 irq = dispc_mgr_get_vsync_irq(mgr->id);
457 break;
458 }
452 459
453 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout); 460 r = omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
454 461
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index f8779d4750ba..60cc6fee6548 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -181,10 +181,7 @@ int dss_debugfs_create_file(const char *name, void (*write)(struct seq_file *))
181 d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir, 181 d = debugfs_create_file(name, S_IRUGO, dss_debugfs_dir,
182 write, &dss_debug_fops); 182 write, &dss_debug_fops);
183 183
184 if (IS_ERR(d)) 184 return PTR_RET(d);
185 return PTR_ERR(d);
186
187 return 0;
188} 185}
189#else /* CONFIG_OMAP2_DSS_DEBUGFS */ 186#else /* CONFIG_OMAP2_DSS_DEBUGFS */
190static inline int dss_initialize_debugfs(void) 187static inline int dss_initialize_debugfs(void)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 05ff2b91d9e8..b33b0169bb3b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -69,6 +69,8 @@ struct dispc_features {
69 u8 mgr_height_start; 69 u8 mgr_height_start;
70 u16 mgr_width_max; 70 u16 mgr_width_max;
71 u16 mgr_height_max; 71 u16 mgr_height_max;
72 unsigned long max_lcd_pclk;
73 unsigned long max_tv_pclk;
72 int (*calc_scaling) (unsigned long pclk, unsigned long lclk, 74 int (*calc_scaling) (unsigned long pclk, unsigned long lclk,
73 const struct omap_video_timings *mgr_timings, 75 const struct omap_video_timings *mgr_timings,
74 u16 width, u16 height, u16 out_width, u16 out_height, 76 u16 width, u16 height, u16 out_width, u16 out_height,
@@ -85,6 +87,9 @@ struct dispc_features {
85 87
86 /* no DISPC_IRQ_FRAMEDONETV on this SoC */ 88 /* no DISPC_IRQ_FRAMEDONETV on this SoC */
87 bool no_framedone_tv:1; 89 bool no_framedone_tv:1;
90
91 /* revert to the OMAP4 mechanism of DISPC Smart Standby operation */
92 bool mstandby_workaround:1;
88}; 93};
89 94
90#define DISPC_MAX_NR_FIFOS 5 95#define DISPC_MAX_NR_FIFOS 5
@@ -97,6 +102,8 @@ static struct {
97 102
98 int irq; 103 int irq;
99 104
105 unsigned long core_clk_rate;
106
100 u32 fifo_size[DISPC_MAX_NR_FIFOS]; 107 u32 fifo_size[DISPC_MAX_NR_FIFOS];
101 /* maps which plane is using a fifo. fifo-id -> plane-id */ 108 /* maps which plane is using a fifo. fifo-id -> plane-id */
102 int fifo_assignment[DISPC_MAX_NR_FIFOS]; 109 int fifo_assignment[DISPC_MAX_NR_FIFOS];
@@ -1584,6 +1591,7 @@ static void dispc_ovl_set_scaling(enum omap_plane plane,
1584} 1591}
1585 1592
1586static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation, 1593static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1594 enum omap_dss_rotation_type rotation_type,
1587 bool mirroring, enum omap_color_mode color_mode) 1595 bool mirroring, enum omap_color_mode color_mode)
1588{ 1596{
1589 bool row_repeat = false; 1597 bool row_repeat = false;
@@ -1634,6 +1642,15 @@ static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation,
1634 if (dss_has_feature(FEAT_ROWREPEATENABLE)) 1642 if (dss_has_feature(FEAT_ROWREPEATENABLE))
1635 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), 1643 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane),
1636 row_repeat ? 1 : 0, 18, 18); 1644 row_repeat ? 1 : 0, 18, 18);
1645
1646 if (color_mode == OMAP_DSS_COLOR_NV12) {
1647 bool doublestride = (rotation_type == OMAP_DSS_ROT_TILER) &&
1648 (rotation == OMAP_DSS_ROT_0 ||
1649 rotation == OMAP_DSS_ROT_180);
1650 /* DOUBLESTRIDE */
1651 REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), doublestride, 22, 22);
1652 }
1653
1637} 1654}
1638 1655
1639static int color_mode_to_bpp(enum omap_color_mode color_mode) 1656static int color_mode_to_bpp(enum omap_color_mode color_mode)
@@ -2512,7 +2529,8 @@ static int dispc_ovl_setup_common(enum omap_plane plane,
2512 dispc_ovl_set_vid_color_conv(plane, cconv); 2529 dispc_ovl_set_vid_color_conv(plane, cconv);
2513 } 2530 }
2514 2531
2515 dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode); 2532 dispc_ovl_set_rotation_attrs(plane, rotation, rotation_type, mirror,
2533 color_mode);
2516 2534
2517 dispc_ovl_set_zorder(plane, caps, zorder); 2535 dispc_ovl_set_zorder(plane, caps, zorder);
2518 dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha); 2536 dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha);
@@ -2823,6 +2841,15 @@ static bool _dispc_lcd_timings_ok(int hsw, int hfp, int hbp,
2823 return true; 2841 return true;
2824} 2842}
2825 2843
2844static bool _dispc_mgr_pclk_ok(enum omap_channel channel,
2845 unsigned long pclk)
2846{
2847 if (dss_mgr_is_lcd(channel))
2848 return pclk <= dispc.feat->max_lcd_pclk ? true : false;
2849 else
2850 return pclk <= dispc.feat->max_tv_pclk ? true : false;
2851}
2852
2826bool dispc_mgr_timings_ok(enum omap_channel channel, 2853bool dispc_mgr_timings_ok(enum omap_channel channel,
2827 const struct omap_video_timings *timings) 2854 const struct omap_video_timings *timings)
2828{ 2855{
@@ -2830,11 +2857,13 @@ bool dispc_mgr_timings_ok(enum omap_channel channel,
2830 2857
2831 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res); 2858 timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
2832 2859
2833 if (dss_mgr_is_lcd(channel)) 2860 timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixel_clock * 1000);
2834 timings_ok = timings_ok && _dispc_lcd_timings_ok(timings->hsw, 2861
2835 timings->hfp, timings->hbp, 2862 if (dss_mgr_is_lcd(channel)) {
2836 timings->vsw, timings->vfp, 2863 timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
2837 timings->vbp); 2864 timings->hbp, timings->vsw, timings->vfp,
2865 timings->vbp);
2866 }
2838 2867
2839 return timings_ok; 2868 return timings_ok;
2840} 2869}
@@ -2951,6 +2980,10 @@ static void dispc_mgr_set_lcd_divisor(enum omap_channel channel, u16 lck_div,
2951 2980
2952 dispc_write_reg(DISPC_DIVISORo(channel), 2981 dispc_write_reg(DISPC_DIVISORo(channel),
2953 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0)); 2982 FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
2983
2984 if (dss_has_feature(FEAT_CORE_CLK_DIV) == false &&
2985 channel == OMAP_DSS_CHANNEL_LCD)
2986 dispc.core_clk_rate = dispc_fclk_rate() / lck_div;
2954} 2987}
2955 2988
2956static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div, 2989static void dispc_mgr_get_lcd_divisor(enum omap_channel channel, int *lck_div,
@@ -3056,15 +3089,7 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
3056 3089
3057unsigned long dispc_core_clk_rate(void) 3090unsigned long dispc_core_clk_rate(void)
3058{ 3091{
3059 int lcd; 3092 return dispc.core_clk_rate;
3060 unsigned long fclk = dispc_fclk_rate();
3061
3062 if (dss_has_feature(FEAT_CORE_CLK_DIV))
3063 lcd = REG_GET(DISPC_DIVISOR, 23, 16);
3064 else
3065 lcd = REG_GET(DISPC_DIVISORo(OMAP_DSS_CHANNEL_LCD), 23, 16);
3066
3067 return fclk / lcd;
3068} 3093}
3069 3094
3070static unsigned long dispc_plane_pclk_rate(enum omap_plane plane) 3095static unsigned long dispc_plane_pclk_rate(enum omap_plane plane)
@@ -3313,67 +3338,79 @@ static void dispc_dump_regs(struct seq_file *s)
3313#undef DUMPREG 3338#undef DUMPREG
3314} 3339}
3315 3340
3316/* with fck as input clock rate, find dispc dividers that produce req_pck */ 3341/* calculate clock rates using dividers in cinfo */
3317void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck, 3342int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
3318 struct dispc_clock_info *cinfo) 3343 struct dispc_clock_info *cinfo)
3319{ 3344{
3320 u16 pcd_min, pcd_max; 3345 if (cinfo->lck_div > 255 || cinfo->lck_div == 0)
3321 unsigned long best_pck; 3346 return -EINVAL;
3322 u16 best_ld, cur_ld; 3347 if (cinfo->pck_div < 1 || cinfo->pck_div > 255)
3323 u16 best_pd, cur_pd; 3348 return -EINVAL;
3324 3349
3325 pcd_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD); 3350 cinfo->lck = dispc_fclk_rate / cinfo->lck_div;
3326 pcd_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD); 3351 cinfo->pck = cinfo->lck / cinfo->pck_div;
3327 3352
3328 best_pck = 0; 3353 return 0;
3329 best_ld = 0; 3354}
3330 best_pd = 0;
3331 3355
3332 for (cur_ld = 1; cur_ld <= 255; ++cur_ld) { 3356bool dispc_div_calc(unsigned long dispc,
3333 unsigned long lck = fck / cur_ld; 3357 unsigned long pck_min, unsigned long pck_max,
3358 dispc_div_calc_func func, void *data)
3359{
3360 int lckd, lckd_start, lckd_stop;
3361 int pckd, pckd_start, pckd_stop;
3362 unsigned long pck, lck;
3363 unsigned long lck_max;
3364 unsigned long pckd_hw_min, pckd_hw_max;
3365 unsigned min_fck_per_pck;
3366 unsigned long fck;
3334 3367
3335 for (cur_pd = pcd_min; cur_pd <= pcd_max; ++cur_pd) { 3368#ifdef CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK
3336 unsigned long pck = lck / cur_pd; 3369 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
3337 long old_delta = abs(best_pck - req_pck); 3370#else
3338 long new_delta = abs(pck - req_pck); 3371 min_fck_per_pck = 0;
3372#endif
3339 3373
3340 if (best_pck == 0 || new_delta < old_delta) { 3374 pckd_hw_min = dss_feat_get_param_min(FEAT_PARAM_DSS_PCD);
3341 best_pck = pck; 3375 pckd_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_PCD);
3342 best_ld = cur_ld;
3343 best_pd = cur_pd;
3344 3376
3345 if (pck == req_pck) 3377 lck_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
3346 goto found;
3347 }
3348 3378
3349 if (pck < req_pck) 3379 pck_min = pck_min ? pck_min : 1;
3350 break; 3380 pck_max = pck_max ? pck_max : ULONG_MAX;
3351 }
3352 3381
3353 if (lck / pcd_min < req_pck) 3382 lckd_start = max(DIV_ROUND_UP(dispc, lck_max), 1ul);
3354 break; 3383 lckd_stop = min(dispc / pck_min, 255ul);
3355 }
3356 3384
3357found: 3385 for (lckd = lckd_start; lckd <= lckd_stop; ++lckd) {
3358 cinfo->lck_div = best_ld; 3386 lck = dispc / lckd;
3359 cinfo->pck_div = best_pd;
3360 cinfo->lck = fck / cinfo->lck_div;
3361 cinfo->pck = cinfo->lck / cinfo->pck_div;
3362}
3363 3387
3364/* calculate clock rates using dividers in cinfo */ 3388 pckd_start = max(DIV_ROUND_UP(lck, pck_max), pckd_hw_min);
3365int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 3389 pckd_stop = min(lck / pck_min, pckd_hw_max);
3366 struct dispc_clock_info *cinfo)
3367{
3368 if (cinfo->lck_div > 255 || cinfo->lck_div == 0)
3369 return -EINVAL;
3370 if (cinfo->pck_div < 1 || cinfo->pck_div > 255)
3371 return -EINVAL;
3372 3390
3373 cinfo->lck = dispc_fclk_rate / cinfo->lck_div; 3391 for (pckd = pckd_start; pckd <= pckd_stop; ++pckd) {
3374 cinfo->pck = cinfo->lck / cinfo->pck_div; 3392 pck = lck / pckd;
3375 3393
3376 return 0; 3394 /*
3395 * For OMAP2/3 the DISPC fclk is the same as LCD's logic
3396 * clock, which means we're configuring DISPC fclk here
3397 * also. Thus we need to use the calculated lck. For
3398 * OMAP4+ the DISPC fclk is a separate clock.
3399 */
3400 if (dss_has_feature(FEAT_CORE_CLK_DIV))
3401 fck = dispc_core_clk_rate();
3402 else
3403 fck = lck;
3404
3405 if (fck < pck * min_fck_per_pck)
3406 continue;
3407
3408 if (func(lckd, pckd, lck, pck, data))
3409 return true;
3410 }
3411 }
3412
3413 return false;
3377} 3414}
3378 3415
3379void dispc_mgr_set_clock_div(enum omap_channel channel, 3416void dispc_mgr_set_clock_div(enum omap_channel channel,
@@ -3451,6 +3488,8 @@ static void _omap_dispc_initial_config(void)
3451 l = FLD_MOD(l, 1, 0, 0); 3488 l = FLD_MOD(l, 1, 0, 0);
3452 l = FLD_MOD(l, 1, 23, 16); 3489 l = FLD_MOD(l, 1, 23, 16);
3453 dispc_write_reg(DISPC_DIVISOR, l); 3490 dispc_write_reg(DISPC_DIVISOR, l);
3491
3492 dispc.core_clk_rate = dispc_fclk_rate();
3454 } 3493 }
3455 3494
3456 /* FUNCGATED */ 3495 /* FUNCGATED */
@@ -3466,6 +3505,9 @@ static void _omap_dispc_initial_config(void)
3466 dispc_configure_burst_sizes(); 3505 dispc_configure_burst_sizes();
3467 3506
3468 dispc_ovl_enable_zorder_planes(); 3507 dispc_ovl_enable_zorder_planes();
3508
3509 if (dispc.feat->mstandby_workaround)
3510 REG_FLD_MOD(DISPC_MSTANDBY_CTRL, 1, 0, 0);
3469} 3511}
3470 3512
3471static const struct dispc_features omap24xx_dispc_feats __initconst = { 3513static const struct dispc_features omap24xx_dispc_feats __initconst = {
@@ -3479,6 +3521,7 @@ static const struct dispc_features omap24xx_dispc_feats __initconst = {
3479 .mgr_height_start = 26, 3521 .mgr_height_start = 26,
3480 .mgr_width_max = 2048, 3522 .mgr_width_max = 2048,
3481 .mgr_height_max = 2048, 3523 .mgr_height_max = 2048,
3524 .max_lcd_pclk = 66500000,
3482 .calc_scaling = dispc_ovl_calc_scaling_24xx, 3525 .calc_scaling = dispc_ovl_calc_scaling_24xx,
3483 .calc_core_clk = calc_core_clk_24xx, 3526 .calc_core_clk = calc_core_clk_24xx,
3484 .num_fifos = 3, 3527 .num_fifos = 3,
@@ -3496,6 +3539,8 @@ static const struct dispc_features omap34xx_rev1_0_dispc_feats __initconst = {
3496 .mgr_height_start = 26, 3539 .mgr_height_start = 26,
3497 .mgr_width_max = 2048, 3540 .mgr_width_max = 2048,
3498 .mgr_height_max = 2048, 3541 .mgr_height_max = 2048,
3542 .max_lcd_pclk = 173000000,
3543 .max_tv_pclk = 59000000,
3499 .calc_scaling = dispc_ovl_calc_scaling_34xx, 3544 .calc_scaling = dispc_ovl_calc_scaling_34xx,
3500 .calc_core_clk = calc_core_clk_34xx, 3545 .calc_core_clk = calc_core_clk_34xx,
3501 .num_fifos = 3, 3546 .num_fifos = 3,
@@ -3513,6 +3558,8 @@ static const struct dispc_features omap34xx_rev3_0_dispc_feats __initconst = {
3513 .mgr_height_start = 26, 3558 .mgr_height_start = 26,
3514 .mgr_width_max = 2048, 3559 .mgr_width_max = 2048,
3515 .mgr_height_max = 2048, 3560 .mgr_height_max = 2048,
3561 .max_lcd_pclk = 173000000,
3562 .max_tv_pclk = 59000000,
3516 .calc_scaling = dispc_ovl_calc_scaling_34xx, 3563 .calc_scaling = dispc_ovl_calc_scaling_34xx,
3517 .calc_core_clk = calc_core_clk_34xx, 3564 .calc_core_clk = calc_core_clk_34xx,
3518 .num_fifos = 3, 3565 .num_fifos = 3,
@@ -3530,6 +3577,8 @@ static const struct dispc_features omap44xx_dispc_feats __initconst = {
3530 .mgr_height_start = 26, 3577 .mgr_height_start = 26,
3531 .mgr_width_max = 2048, 3578 .mgr_width_max = 2048,
3532 .mgr_height_max = 2048, 3579 .mgr_height_max = 2048,
3580 .max_lcd_pclk = 170000000,
3581 .max_tv_pclk = 185625000,
3533 .calc_scaling = dispc_ovl_calc_scaling_44xx, 3582 .calc_scaling = dispc_ovl_calc_scaling_44xx,
3534 .calc_core_clk = calc_core_clk_44xx, 3583 .calc_core_clk = calc_core_clk_44xx,
3535 .num_fifos = 5, 3584 .num_fifos = 5,
@@ -3547,10 +3596,13 @@ static const struct dispc_features omap54xx_dispc_feats __initconst = {
3547 .mgr_height_start = 27, 3596 .mgr_height_start = 27,
3548 .mgr_width_max = 4096, 3597 .mgr_width_max = 4096,
3549 .mgr_height_max = 4096, 3598 .mgr_height_max = 4096,
3599 .max_lcd_pclk = 170000000,
3600 .max_tv_pclk = 186000000,
3550 .calc_scaling = dispc_ovl_calc_scaling_44xx, 3601 .calc_scaling = dispc_ovl_calc_scaling_44xx,
3551 .calc_core_clk = calc_core_clk_44xx, 3602 .calc_core_clk = calc_core_clk_44xx,
3552 .num_fifos = 5, 3603 .num_fifos = 5,
3553 .gfx_fifo_workaround = true, 3604 .gfx_fifo_workaround = true,
3605 .mstandby_workaround = true,
3554}; 3606};
3555 3607
3556static int __init dispc_init_features(struct platform_device *pdev) 3608static int __init dispc_init_features(struct platform_device *pdev)
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 222363c6e623..de4863d21ab7 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -39,6 +39,7 @@
39#define DISPC_GLOBAL_BUFFER 0x0800 39#define DISPC_GLOBAL_BUFFER 0x0800
40#define DISPC_CONTROL3 0x0848 40#define DISPC_CONTROL3 0x0848
41#define DISPC_CONFIG3 0x084C 41#define DISPC_CONFIG3 0x084C
42#define DISPC_MSTANDBY_CTRL 0x0858
42 43
43/* DISPC overlay registers */ 44/* DISPC overlay registers */
44#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \ 45#define DISPC_OVL_BA0(n) (DISPC_OVL_BASE(n) + \
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 4af136a04e53..e93c4debea7f 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/omap2/dss/dpi.c
@@ -63,15 +63,29 @@ static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
63 case OMAPDSS_VER_OMAP3630: 63 case OMAPDSS_VER_OMAP3630:
64 case OMAPDSS_VER_AM35xx: 64 case OMAPDSS_VER_AM35xx:
65 return NULL; 65 return NULL;
66 default:
67 break;
68 }
69 66
70 switch (channel) { 67 case OMAPDSS_VER_OMAP4430_ES1:
71 case OMAP_DSS_CHANNEL_LCD: 68 case OMAPDSS_VER_OMAP4430_ES2:
72 return dsi_get_dsidev_from_id(0); 69 case OMAPDSS_VER_OMAP4:
73 case OMAP_DSS_CHANNEL_LCD2: 70 switch (channel) {
74 return dsi_get_dsidev_from_id(1); 71 case OMAP_DSS_CHANNEL_LCD:
72 return dsi_get_dsidev_from_id(0);
73 case OMAP_DSS_CHANNEL_LCD2:
74 return dsi_get_dsidev_from_id(1);
75 default:
76 return NULL;
77 }
78
79 case OMAPDSS_VER_OMAP5:
80 switch (channel) {
81 case OMAP_DSS_CHANNEL_LCD:
82 return dsi_get_dsidev_from_id(0);
83 case OMAP_DSS_CHANNEL_LCD3:
84 return dsi_get_dsidev_from_id(1);
85 default:
86 return NULL;
87 }
88
75 default: 89 default:
76 return NULL; 90 return NULL;
77 } 91 }
@@ -91,75 +105,211 @@ static enum omap_dss_clk_source dpi_get_alt_clk_src(enum omap_channel channel)
91 } 105 }
92} 106}
93 107
94static int dpi_set_dsi_clk(struct omap_dss_device *dssdev, 108struct dpi_clk_calc_ctx {
109 struct platform_device *dsidev;
110
111 /* inputs */
112
113 unsigned long pck_min, pck_max;
114
115 /* outputs */
116
117 struct dsi_clock_info dsi_cinfo;
118 struct dss_clock_info dss_cinfo;
119 struct dispc_clock_info dispc_cinfo;
120};
121
122static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
123 unsigned long pck, void *data)
124{
125 struct dpi_clk_calc_ctx *ctx = data;
126
127 /*
128 * Odd dividers give us uneven duty cycle, causing problem when level
129 * shifted. So skip all odd dividers when the pixel clock is on the
130 * higher side.
131 */
132 if (ctx->pck_min >= 1000000) {
133 if (lckd > 1 && lckd % 2 != 0)
134 return false;
135
136 if (pckd > 1 && pckd % 2 != 0)
137 return false;
138 }
139
140 ctx->dispc_cinfo.lck_div = lckd;
141 ctx->dispc_cinfo.pck_div = pckd;
142 ctx->dispc_cinfo.lck = lck;
143 ctx->dispc_cinfo.pck = pck;
144
145 return true;
146}
147
148
149static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
150 void *data)
151{
152 struct dpi_clk_calc_ctx *ctx = data;
153
154 /*
155 * Odd dividers give us uneven duty cycle, causing problem when level
156 * shifted. So skip all odd dividers when the pixel clock is on the
157 * higher side.
158 */
159 if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 1000000)
160 return false;
161
162 ctx->dsi_cinfo.regm_dispc = regm_dispc;
163 ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc;
164
165 return dispc_div_calc(dispc, ctx->pck_min, ctx->pck_max,
166 dpi_calc_dispc_cb, ctx);
167}
168
169
170static bool dpi_calc_pll_cb(int regn, int regm, unsigned long fint,
171 unsigned long pll,
172 void *data)
173{
174 struct dpi_clk_calc_ctx *ctx = data;
175
176 ctx->dsi_cinfo.regn = regn;
177 ctx->dsi_cinfo.regm = regm;
178 ctx->dsi_cinfo.fint = fint;
179 ctx->dsi_cinfo.clkin4ddr = pll;
180
181 return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->pck_min,
182 dpi_calc_hsdiv_cb, ctx);
183}
184
185static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data)
186{
187 struct dpi_clk_calc_ctx *ctx = data;
188
189 ctx->dss_cinfo.fck = fck;
190 ctx->dss_cinfo.fck_div = fckd;
191
192 return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
193 dpi_calc_dispc_cb, ctx);
194}
195
196static bool dpi_dsi_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
197{
198 unsigned long clkin;
199 unsigned long pll_min, pll_max;
200
201 clkin = dsi_get_pll_clkin(dpi.dsidev);
202
203 memset(ctx, 0, sizeof(*ctx));
204 ctx->dsidev = dpi.dsidev;
205 ctx->pck_min = pck - 1000;
206 ctx->pck_max = pck + 1000;
207 ctx->dsi_cinfo.clkin = clkin;
208
209 pll_min = 0;
210 pll_max = 0;
211
212 return dsi_pll_calc(dpi.dsidev, clkin,
213 pll_min, pll_max,
214 dpi_calc_pll_cb, ctx);
215}
216
217static bool dpi_dss_clk_calc(unsigned long pck, struct dpi_clk_calc_ctx *ctx)
218{
219 int i;
220
221 /*
222 * DSS fck gives us very few possibilities, so finding a good pixel
223 * clock may not be possible. We try multiple times to find the clock,
224 * each time widening the pixel clock range we look for, up to
225 * +/- ~15MHz.
226 */
227
228 for (i = 0; i < 25; ++i) {
229 bool ok;
230
231 memset(ctx, 0, sizeof(*ctx));
232 if (pck > 1000 * i * i * i)
233 ctx->pck_min = max(pck - 1000 * i * i * i, 0lu);
234 else
235 ctx->pck_min = 0;
236 ctx->pck_max = pck + 1000 * i * i * i;
237
238 ok = dss_div_calc(ctx->pck_min, dpi_calc_dss_cb, ctx);
239 if (ok)
240 return ok;
241 }
242
243 return false;
244}
245
246
247
248static int dpi_set_dsi_clk(enum omap_channel channel,
95 unsigned long pck_req, unsigned long *fck, int *lck_div, 249 unsigned long pck_req, unsigned long *fck, int *lck_div,
96 int *pck_div) 250 int *pck_div)
97{ 251{
98 struct omap_overlay_manager *mgr = dssdev->output->manager; 252 struct dpi_clk_calc_ctx ctx;
99 struct dsi_clock_info dsi_cinfo;
100 struct dispc_clock_info dispc_cinfo;
101 int r; 253 int r;
254 bool ok;
102 255
103 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, pck_req, &dsi_cinfo, 256 ok = dpi_dsi_clk_calc(pck_req, &ctx);
104 &dispc_cinfo); 257 if (!ok)
105 if (r) 258 return -EINVAL;
106 return r;
107 259
108 r = dsi_pll_set_clock_div(dpi.dsidev, &dsi_cinfo); 260 r = dsi_pll_set_clock_div(dpi.dsidev, &ctx.dsi_cinfo);
109 if (r) 261 if (r)
110 return r; 262 return r;
111 263
112 dss_select_lcd_clk_source(mgr->id, 264 dss_select_lcd_clk_source(channel,
113 dpi_get_alt_clk_src(mgr->id)); 265 dpi_get_alt_clk_src(channel));
114 266
115 dpi.mgr_config.clock_info = dispc_cinfo; 267 dpi.mgr_config.clock_info = ctx.dispc_cinfo;
116 268
117 *fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 269 *fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
118 *lck_div = dispc_cinfo.lck_div; 270 *lck_div = ctx.dispc_cinfo.lck_div;
119 *pck_div = dispc_cinfo.pck_div; 271 *pck_div = ctx.dispc_cinfo.pck_div;
120 272
121 return 0; 273 return 0;
122} 274}
123 275
124static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, 276static int dpi_set_dispc_clk(unsigned long pck_req, unsigned long *fck,
125 unsigned long pck_req, unsigned long *fck, int *lck_div, 277 int *lck_div, int *pck_div)
126 int *pck_div)
127{ 278{
128 struct dss_clock_info dss_cinfo; 279 struct dpi_clk_calc_ctx ctx;
129 struct dispc_clock_info dispc_cinfo;
130 int r; 280 int r;
281 bool ok;
131 282
132 r = dss_calc_clock_div(pck_req, &dss_cinfo, &dispc_cinfo); 283 ok = dpi_dss_clk_calc(pck_req, &ctx);
133 if (r) 284 if (!ok)
134 return r; 285 return -EINVAL;
135 286
136 r = dss_set_clock_div(&dss_cinfo); 287 r = dss_set_clock_div(&ctx.dss_cinfo);
137 if (r) 288 if (r)
138 return r; 289 return r;
139 290
140 dpi.mgr_config.clock_info = dispc_cinfo; 291 dpi.mgr_config.clock_info = ctx.dispc_cinfo;
141 292
142 *fck = dss_cinfo.fck; 293 *fck = ctx.dss_cinfo.fck;
143 *lck_div = dispc_cinfo.lck_div; 294 *lck_div = ctx.dispc_cinfo.lck_div;
144 *pck_div = dispc_cinfo.pck_div; 295 *pck_div = ctx.dispc_cinfo.pck_div;
145 296
146 return 0; 297 return 0;
147} 298}
148 299
149static int dpi_set_mode(struct omap_dss_device *dssdev) 300static int dpi_set_mode(struct omap_overlay_manager *mgr)
150{ 301{
151 struct omap_video_timings *t = &dpi.timings; 302 struct omap_video_timings *t = &dpi.timings;
152 struct omap_overlay_manager *mgr = dssdev->output->manager;
153 int lck_div = 0, pck_div = 0; 303 int lck_div = 0, pck_div = 0;
154 unsigned long fck = 0; 304 unsigned long fck = 0;
155 unsigned long pck; 305 unsigned long pck;
156 int r = 0; 306 int r = 0;
157 307
158 if (dpi.dsidev) 308 if (dpi.dsidev)
159 r = dpi_set_dsi_clk(dssdev, t->pixel_clock * 1000, &fck, 309 r = dpi_set_dsi_clk(mgr->id, t->pixel_clock * 1000, &fck,
160 &lck_div, &pck_div); 310 &lck_div, &pck_div);
161 else 311 else
162 r = dpi_set_dispc_clk(dssdev, t->pixel_clock * 1000, &fck, 312 r = dpi_set_dispc_clk(t->pixel_clock * 1000, &fck,
163 &lck_div, &pck_div); 313 &lck_div, &pck_div);
164 if (r) 314 if (r)
165 return r; 315 return r;
@@ -179,10 +329,8 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
179 return 0; 329 return 0;
180} 330}
181 331
182static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) 332static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr)
183{ 333{
184 struct omap_overlay_manager *mgr = dssdev->output->manager;
185
186 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; 334 dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
187 335
188 dpi.mgr_config.stallmode = false; 336 dpi.mgr_config.stallmode = false;
@@ -197,7 +345,7 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
197 345
198int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) 346int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
199{ 347{
200 struct omap_dss_output *out = dssdev->output; 348 struct omap_dss_output *out = &dpi.output;
201 int r; 349 int r;
202 350
203 mutex_lock(&dpi.lock); 351 mutex_lock(&dpi.lock);
@@ -230,7 +378,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
230 if (r) 378 if (r)
231 goto err_get_dispc; 379 goto err_get_dispc;
232 380
233 r = dss_dpi_select_source(dssdev->channel); 381 r = dss_dpi_select_source(out->manager->id);
234 if (r) 382 if (r)
235 goto err_src_sel; 383 goto err_src_sel;
236 384
@@ -244,11 +392,11 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
244 goto err_dsi_pll_init; 392 goto err_dsi_pll_init;
245 } 393 }
246 394
247 r = dpi_set_mode(dssdev); 395 r = dpi_set_mode(out->manager);
248 if (r) 396 if (r)
249 goto err_set_mode; 397 goto err_set_mode;
250 398
251 dpi_config_lcd_manager(dssdev); 399 dpi_config_lcd_manager(out->manager);
252 400
253 mdelay(2); 401 mdelay(2);
254 402
@@ -285,7 +433,7 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
285 433
286void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) 434void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
287{ 435{
288 struct omap_overlay_manager *mgr = dssdev->output->manager; 436 struct omap_overlay_manager *mgr = dpi.output.manager;
289 437
290 mutex_lock(&dpi.lock); 438 mutex_lock(&dpi.lock);
291 439
@@ -324,12 +472,12 @@ EXPORT_SYMBOL(omapdss_dpi_set_timings);
324int dpi_check_timings(struct omap_dss_device *dssdev, 472int dpi_check_timings(struct omap_dss_device *dssdev,
325 struct omap_video_timings *timings) 473 struct omap_video_timings *timings)
326{ 474{
327 int r; 475 struct omap_overlay_manager *mgr = dpi.output.manager;
328 struct omap_overlay_manager *mgr = dssdev->output->manager;
329 int lck_div, pck_div; 476 int lck_div, pck_div;
330 unsigned long fck; 477 unsigned long fck;
331 unsigned long pck; 478 unsigned long pck;
332 struct dispc_clock_info dispc_cinfo; 479 struct dpi_clk_calc_ctx ctx;
480 bool ok;
333 481
334 if (mgr && !dispc_mgr_timings_ok(mgr->id, timings)) 482 if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
335 return -EINVAL; 483 return -EINVAL;
@@ -338,28 +486,21 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
338 return -EINVAL; 486 return -EINVAL;
339 487
340 if (dpi.dsidev) { 488 if (dpi.dsidev) {
341 struct dsi_clock_info dsi_cinfo; 489 ok = dpi_dsi_clk_calc(timings->pixel_clock * 1000, &ctx);
342 r = dsi_pll_calc_clock_div_pck(dpi.dsidev, 490 if (!ok)
343 timings->pixel_clock * 1000, 491 return -EINVAL;
344 &dsi_cinfo, &dispc_cinfo);
345
346 if (r)
347 return r;
348 492
349 fck = dsi_cinfo.dsi_pll_hsdiv_dispc_clk; 493 fck = ctx.dsi_cinfo.dsi_pll_hsdiv_dispc_clk;
350 } else { 494 } else {
351 struct dss_clock_info dss_cinfo; 495 ok = dpi_dss_clk_calc(timings->pixel_clock * 1000, &ctx);
352 r = dss_calc_clock_div(timings->pixel_clock * 1000, 496 if (!ok)
353 &dss_cinfo, &dispc_cinfo); 497 return -EINVAL;
354 498
355 if (r) 499 fck = ctx.dss_cinfo.fck;
356 return r;
357
358 fck = dss_cinfo.fck;
359 } 500 }
360 501
361 lck_div = dispc_cinfo.lck_div; 502 lck_div = ctx.dispc_cinfo.lck_div;
362 pck_div = dispc_cinfo.pck_div; 503 pck_div = ctx.dispc_cinfo.pck_div;
363 504
364 pck = fck / lck_div / pck_div / 1000; 505 pck = fck / lck_div / pck_div / 1000;
365 506
@@ -401,6 +542,36 @@ static int __init dpi_verify_dsi_pll(struct platform_device *dsidev)
401 return 0; 542 return 0;
402} 543}
403 544
545/*
546 * Return a hardcoded channel for the DPI output. This should work for
547 * current use cases, but this can be later expanded to either resolve
548 * the channel in some more dynamic manner, or get the channel as a user
549 * parameter.
550 */
551static enum omap_channel dpi_get_channel(void)
552{
553 switch (omapdss_get_version()) {
554 case OMAPDSS_VER_OMAP24xx:
555 case OMAPDSS_VER_OMAP34xx_ES1:
556 case OMAPDSS_VER_OMAP34xx_ES3:
557 case OMAPDSS_VER_OMAP3630:
558 case OMAPDSS_VER_AM35xx:
559 return OMAP_DSS_CHANNEL_LCD;
560
561 case OMAPDSS_VER_OMAP4430_ES1:
562 case OMAPDSS_VER_OMAP4430_ES2:
563 case OMAPDSS_VER_OMAP4:
564 return OMAP_DSS_CHANNEL_LCD2;
565
566 case OMAPDSS_VER_OMAP5:
567 return OMAP_DSS_CHANNEL_LCD3;
568
569 default:
570 DSSWARN("unsupported DSS version\n");
571 return OMAP_DSS_CHANNEL_LCD;
572 }
573}
574
404static int __init dpi_init_display(struct omap_dss_device *dssdev) 575static int __init dpi_init_display(struct omap_dss_device *dssdev)
405{ 576{
406 struct platform_device *dsidev; 577 struct platform_device *dsidev;
@@ -421,12 +592,7 @@ static int __init dpi_init_display(struct omap_dss_device *dssdev)
421 dpi.vdds_dsi_reg = vdds_dsi; 592 dpi.vdds_dsi_reg = vdds_dsi;
422 } 593 }
423 594
424 /* 595 dsidev = dpi_get_dsidev(dpi.output.dispc_channel);
425 * XXX We shouldn't need dssdev->channel for this. The dsi pll clock
426 * source for DPI is SoC integration detail, not something that should
427 * be configured in the dssdev
428 */
429 dsidev = dpi_get_dsidev(dssdev->channel);
430 596
431 if (dsidev && dpi_verify_dsi_pll(dsidev)) { 597 if (dsidev && dpi_verify_dsi_pll(dsidev)) {
432 dsidev = NULL; 598 dsidev = NULL;
@@ -517,6 +683,8 @@ static void __init dpi_init_output(struct platform_device *pdev)
517 out->pdev = pdev; 683 out->pdev = pdev;
518 out->id = OMAP_DSS_OUTPUT_DPI; 684 out->id = OMAP_DSS_OUTPUT_DPI;
519 out->type = OMAP_DISPLAY_TYPE_DPI; 685 out->type = OMAP_DISPLAY_TYPE_DPI;
686 out->name = "dpi.0";
687 out->dispc_channel = dpi_get_channel();
520 688
521 dss_register_output(out); 689 dss_register_output(out);
522} 690}
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
index 28d41d16b7be..9b1c5ecee115 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -200,6 +200,11 @@ struct dsi_reg { u16 idx; };
200 200
201typedef void (*omap_dsi_isr_t) (void *arg, u32 mask); 201typedef void (*omap_dsi_isr_t) (void *arg, u32 mask);
202 202
203static int dsi_display_init_dispc(struct platform_device *dsidev,
204 struct omap_overlay_manager *mgr);
205static void dsi_display_uninit_dispc(struct platform_device *dsidev,
206 struct omap_overlay_manager *mgr);
207
203#define DSI_MAX_NR_ISRS 2 208#define DSI_MAX_NR_ISRS 2
204#define DSI_MAX_NR_LANES 5 209#define DSI_MAX_NR_LANES 5
205 210
@@ -250,6 +255,24 @@ struct dsi_isr_tables {
250 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS]; 255 struct dsi_isr_data isr_table_cio[DSI_MAX_NR_ISRS];
251}; 256};
252 257
258struct dsi_clk_calc_ctx {
259 struct platform_device *dsidev;
260
261 /* inputs */
262
263 const struct omap_dss_dsi_config *config;
264
265 unsigned long req_pck_min, req_pck_nom, req_pck_max;
266
267 /* outputs */
268
269 struct dsi_clock_info dsi_cinfo;
270 struct dispc_clock_info dispc_cinfo;
271
272 struct omap_video_timings dispc_vm;
273 struct omap_dss_dsi_videomode_timings dsi_vm;
274};
275
253struct dsi_data { 276struct dsi_data {
254 struct platform_device *pdev; 277 struct platform_device *pdev;
255 void __iomem *base; 278 void __iomem *base;
@@ -261,6 +284,9 @@ struct dsi_data {
261 struct clk *dss_clk; 284 struct clk *dss_clk;
262 struct clk *sys_clk; 285 struct clk *sys_clk;
263 286
287 struct dispc_clock_info user_dispc_cinfo;
288 struct dsi_clock_info user_dsi_cinfo;
289
264 struct dsi_clock_info current_cinfo; 290 struct dsi_clock_info current_cinfo;
265 291
266 bool vdds_dsi_enabled; 292 bool vdds_dsi_enabled;
@@ -324,6 +350,7 @@ struct dsi_data {
324 unsigned long lpdiv_max; 350 unsigned long lpdiv_max;
325 351
326 unsigned num_lanes_supported; 352 unsigned num_lanes_supported;
353 unsigned line_buffer_size;
327 354
328 struct dsi_lane_config lanes[DSI_MAX_NR_LANES]; 355 struct dsi_lane_config lanes[DSI_MAX_NR_LANES];
329 unsigned num_lanes_used; 356 unsigned num_lanes_used;
@@ -1192,15 +1219,33 @@ static unsigned long dsi_fclk_rate(struct platform_device *dsidev)
1192 return r; 1219 return r;
1193} 1220}
1194 1221
1195static int dsi_set_lp_clk_divisor(struct omap_dss_device *dssdev) 1222static int dsi_lp_clock_calc(struct dsi_clock_info *cinfo,
1223 unsigned long lp_clk_min, unsigned long lp_clk_max)
1224{
1225 unsigned long dsi_fclk = cinfo->dsi_pll_hsdiv_dsi_clk;
1226 unsigned lp_clk_div;
1227 unsigned long lp_clk;
1228
1229 lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk_max * 2);
1230 lp_clk = dsi_fclk / 2 / lp_clk_div;
1231
1232 if (lp_clk < lp_clk_min || lp_clk > lp_clk_max)
1233 return -EINVAL;
1234
1235 cinfo->lp_clk_div = lp_clk_div;
1236 cinfo->lp_clk = lp_clk;
1237
1238 return 0;
1239}
1240
1241static int dsi_set_lp_clk_divisor(struct platform_device *dsidev)
1196{ 1242{
1197 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
1198 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 1243 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1199 unsigned long dsi_fclk; 1244 unsigned long dsi_fclk;
1200 unsigned lp_clk_div; 1245 unsigned lp_clk_div;
1201 unsigned long lp_clk; 1246 unsigned long lp_clk;
1202 1247
1203 lp_clk_div = dssdev->clocks.dsi.lp_clk_div; 1248 lp_clk_div = dsi->user_dsi_cinfo.lp_clk_div;
1204 1249
1205 if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max) 1250 if (lp_clk_div == 0 || lp_clk_div > dsi->lpdiv_max)
1206 return -EINVAL; 1251 return -EINVAL;
@@ -1272,6 +1317,75 @@ static int dsi_pll_power(struct platform_device *dsidev,
1272 return 0; 1317 return 0;
1273} 1318}
1274 1319
1320unsigned long dsi_get_pll_clkin(struct platform_device *dsidev)
1321{
1322 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1323 return clk_get_rate(dsi->sys_clk);
1324}
1325
1326bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll,
1327 unsigned long out_min, dsi_hsdiv_calc_func func, void *data)
1328{
1329 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1330 int regm, regm_start, regm_stop;
1331 unsigned long out_max;
1332 unsigned long out;
1333
1334 out_min = out_min ? out_min : 1;
1335 out_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1336
1337 regm_start = max(DIV_ROUND_UP(pll, out_max), 1ul);
1338 regm_stop = min(pll / out_min, dsi->regm_dispc_max);
1339
1340 for (regm = regm_start; regm <= regm_stop; ++regm) {
1341 out = pll / regm;
1342
1343 if (func(regm, out, data))
1344 return true;
1345 }
1346
1347 return false;
1348}
1349
1350bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin,
1351 unsigned long pll_min, unsigned long pll_max,
1352 dsi_pll_calc_func func, void *data)
1353{
1354 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1355 int regn, regn_start, regn_stop;
1356 int regm, regm_start, regm_stop;
1357 unsigned long fint, pll;
1358 const unsigned long pll_hw_max = 1800000000;
1359 unsigned long fint_hw_min, fint_hw_max;
1360
1361 fint_hw_min = dsi->fint_min;
1362 fint_hw_max = dsi->fint_max;
1363
1364 regn_start = max(DIV_ROUND_UP(clkin, fint_hw_max), 1ul);
1365 regn_stop = min(clkin / fint_hw_min, dsi->regn_max);
1366
1367 pll_max = pll_max ? pll_max : ULONG_MAX;
1368
1369 for (regn = regn_start; regn <= regn_stop; ++regn) {
1370 fint = clkin / regn;
1371
1372 regm_start = max(DIV_ROUND_UP(DIV_ROUND_UP(pll_min, fint), 2),
1373 1ul);
1374 regm_stop = min3(pll_max / fint / 2,
1375 pll_hw_max / fint / 2,
1376 dsi->regm_max);
1377
1378 for (regm = regm_start; regm <= regm_stop; ++regm) {
1379 pll = 2 * regm * fint;
1380
1381 if (func(regn, regm, fint, pll, data))
1382 return true;
1383 }
1384 }
1385
1386 return false;
1387}
1388
1275/* calculate clock rates using dividers in cinfo */ 1389/* calculate clock rates using dividers in cinfo */
1276static int dsi_calc_clock_rates(struct platform_device *dsidev, 1390static int dsi_calc_clock_rates(struct platform_device *dsidev,
1277 struct dsi_clock_info *cinfo) 1391 struct dsi_clock_info *cinfo)
@@ -1316,192 +1430,7 @@ static int dsi_calc_clock_rates(struct platform_device *dsidev,
1316 return 0; 1430 return 0;
1317} 1431}
1318 1432
1319int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev, 1433static void dsi_pll_calc_dsi_fck(struct dsi_clock_info *cinfo)
1320 unsigned long req_pck, struct dsi_clock_info *dsi_cinfo,
1321 struct dispc_clock_info *dispc_cinfo)
1322{
1323 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1324 struct dsi_clock_info cur, best;
1325 struct dispc_clock_info best_dispc;
1326 int min_fck_per_pck;
1327 int match = 0;
1328 unsigned long dss_sys_clk, max_dss_fck;
1329
1330 dss_sys_clk = clk_get_rate(dsi->sys_clk);
1331
1332 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1333
1334 if (req_pck == dsi->cache_req_pck &&
1335 dsi->cache_cinfo.clkin == dss_sys_clk) {
1336 DSSDBG("DSI clock info found from cache\n");
1337 *dsi_cinfo = dsi->cache_cinfo;
1338 dispc_find_clk_divs(req_pck, dsi_cinfo->dsi_pll_hsdiv_dispc_clk,
1339 dispc_cinfo);
1340 return 0;
1341 }
1342
1343 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
1344
1345 if (min_fck_per_pck &&
1346 req_pck * min_fck_per_pck > max_dss_fck) {
1347 DSSERR("Requested pixel clock not possible with the current "
1348 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
1349 "the constraint off.\n");
1350 min_fck_per_pck = 0;
1351 }
1352
1353 DSSDBG("dsi_pll_calc\n");
1354
1355retry:
1356 memset(&best, 0, sizeof(best));
1357 memset(&best_dispc, 0, sizeof(best_dispc));
1358
1359 memset(&cur, 0, sizeof(cur));
1360 cur.clkin = dss_sys_clk;
1361
1362 /* 0.75MHz < Fint = clkin / regn < 2.1MHz */
1363 /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
1364 for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
1365 cur.fint = cur.clkin / cur.regn;
1366
1367 if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
1368 continue;
1369
1370 /* DSIPHY(MHz) = (2 * regm / regn) * clkin */
1371 for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
1372 unsigned long a, b;
1373
1374 a = 2 * cur.regm * (cur.clkin/1000);
1375 b = cur.regn;
1376 cur.clkin4ddr = a / b * 1000;
1377
1378 if (cur.clkin4ddr > 1800 * 1000 * 1000)
1379 break;
1380
1381 /* dsi_pll_hsdiv_dispc_clk(MHz) =
1382 * DSIPHY(MHz) / regm_dispc < 173MHz/186Mhz */
1383 for (cur.regm_dispc = 1; cur.regm_dispc <
1384 dsi->regm_dispc_max; ++cur.regm_dispc) {
1385 struct dispc_clock_info cur_dispc;
1386 cur.dsi_pll_hsdiv_dispc_clk =
1387 cur.clkin4ddr / cur.regm_dispc;
1388
1389 if (cur.regm_dispc > 1 &&
1390 cur.regm_dispc % 2 != 0 &&
1391 req_pck >= 1000000)
1392 continue;
1393
1394 /* this will narrow down the search a bit,
1395 * but still give pixclocks below what was
1396 * requested */
1397 if (cur.dsi_pll_hsdiv_dispc_clk < req_pck)
1398 break;
1399
1400 if (cur.dsi_pll_hsdiv_dispc_clk > max_dss_fck)
1401 continue;
1402
1403 if (min_fck_per_pck &&
1404 cur.dsi_pll_hsdiv_dispc_clk <
1405 req_pck * min_fck_per_pck)
1406 continue;
1407
1408 match = 1;
1409
1410 dispc_find_clk_divs(req_pck,
1411 cur.dsi_pll_hsdiv_dispc_clk,
1412 &cur_dispc);
1413
1414 if (abs(cur_dispc.pck - req_pck) <
1415 abs(best_dispc.pck - req_pck)) {
1416 best = cur;
1417 best_dispc = cur_dispc;
1418
1419 if (cur_dispc.pck == req_pck)
1420 goto found;
1421 }
1422 }
1423 }
1424 }
1425found:
1426 if (!match) {
1427 if (min_fck_per_pck) {
1428 DSSERR("Could not find suitable clock settings.\n"
1429 "Turning FCK/PCK constraint off and"
1430 "trying again.\n");
1431 min_fck_per_pck = 0;
1432 goto retry;
1433 }
1434
1435 DSSERR("Could not find suitable clock settings.\n");
1436
1437 return -EINVAL;
1438 }
1439
1440 /* dsi_pll_hsdiv_dsi_clk (regm_dsi) is not used */
1441 best.regm_dsi = 0;
1442 best.dsi_pll_hsdiv_dsi_clk = 0;
1443
1444 if (dsi_cinfo)
1445 *dsi_cinfo = best;
1446 if (dispc_cinfo)
1447 *dispc_cinfo = best_dispc;
1448
1449 dsi->cache_req_pck = req_pck;
1450 dsi->cache_clk_freq = 0;
1451 dsi->cache_cinfo = best;
1452
1453 return 0;
1454}
1455
1456static int dsi_pll_calc_ddrfreq(struct platform_device *dsidev,
1457 unsigned long req_clkin4ddr, struct dsi_clock_info *cinfo)
1458{
1459 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1460 struct dsi_clock_info cur, best;
1461
1462 DSSDBG("dsi_pll_calc_ddrfreq\n");
1463
1464 memset(&best, 0, sizeof(best));
1465 memset(&cur, 0, sizeof(cur));
1466
1467 cur.clkin = clk_get_rate(dsi->sys_clk);
1468
1469 for (cur.regn = 1; cur.regn < dsi->regn_max; ++cur.regn) {
1470 cur.fint = cur.clkin / cur.regn;
1471
1472 if (cur.fint > dsi->fint_max || cur.fint < dsi->fint_min)
1473 continue;
1474
1475 /* DSIPHY(MHz) = (2 * regm / regn) * clkin */
1476 for (cur.regm = 1; cur.regm < dsi->regm_max; ++cur.regm) {
1477 unsigned long a, b;
1478
1479 a = 2 * cur.regm * (cur.clkin/1000);
1480 b = cur.regn;
1481 cur.clkin4ddr = a / b * 1000;
1482
1483 if (cur.clkin4ddr > 1800 * 1000 * 1000)
1484 break;
1485
1486 if (abs(cur.clkin4ddr - req_clkin4ddr) <
1487 abs(best.clkin4ddr - req_clkin4ddr)) {
1488 best = cur;
1489 DSSDBG("best %ld\n", best.clkin4ddr);
1490 }
1491
1492 if (cur.clkin4ddr == req_clkin4ddr)
1493 goto found;
1494 }
1495 }
1496found:
1497 if (cinfo)
1498 *cinfo = best;
1499
1500 return 0;
1501}
1502
1503static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev,
1504 struct dsi_clock_info *cinfo)
1505{ 1434{
1506 unsigned long max_dsi_fck; 1435 unsigned long max_dsi_fck;
1507 1436
@@ -1511,90 +1440,6 @@ static void dsi_pll_calc_dsi_fck(struct platform_device *dsidev,
1511 cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi; 1440 cinfo->dsi_pll_hsdiv_dsi_clk = cinfo->clkin4ddr / cinfo->regm_dsi;
1512} 1441}
1513 1442
1514static int dsi_pll_calc_dispc_fck(struct platform_device *dsidev,
1515 unsigned long req_pck, struct dsi_clock_info *cinfo,
1516 struct dispc_clock_info *dispc_cinfo)
1517{
1518 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
1519 unsigned regm_dispc, best_regm_dispc;
1520 unsigned long dispc_clk, best_dispc_clk;
1521 int min_fck_per_pck;
1522 unsigned long max_dss_fck;
1523 struct dispc_clock_info best_dispc;
1524 bool match;
1525
1526 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
1527
1528 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
1529
1530 if (min_fck_per_pck &&
1531 req_pck * min_fck_per_pck > max_dss_fck) {
1532 DSSERR("Requested pixel clock not possible with the current "
1533 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
1534 "the constraint off.\n");
1535 min_fck_per_pck = 0;
1536 }
1537
1538retry:
1539 best_regm_dispc = 0;
1540 best_dispc_clk = 0;
1541 memset(&best_dispc, 0, sizeof(best_dispc));
1542 match = false;
1543
1544 for (regm_dispc = 1; regm_dispc < dsi->regm_dispc_max; ++regm_dispc) {
1545 struct dispc_clock_info cur_dispc;
1546
1547 dispc_clk = cinfo->clkin4ddr / regm_dispc;
1548
1549 /* this will narrow down the search a bit,
1550 * but still give pixclocks below what was
1551 * requested */
1552 if (dispc_clk < req_pck)
1553 break;
1554
1555 if (dispc_clk > max_dss_fck)
1556 continue;
1557
1558 if (min_fck_per_pck && dispc_clk < req_pck * min_fck_per_pck)
1559 continue;
1560
1561 match = true;
1562
1563 dispc_find_clk_divs(req_pck, dispc_clk, &cur_dispc);
1564
1565 if (abs(cur_dispc.pck - req_pck) <
1566 abs(best_dispc.pck - req_pck)) {
1567 best_regm_dispc = regm_dispc;
1568 best_dispc_clk = dispc_clk;
1569 best_dispc = cur_dispc;
1570
1571 if (cur_dispc.pck == req_pck)
1572 goto found;
1573 }
1574 }
1575
1576 if (!match) {
1577 if (min_fck_per_pck) {
1578 DSSERR("Could not find suitable clock settings.\n"
1579 "Turning FCK/PCK constraint off and"
1580 "trying again.\n");
1581 min_fck_per_pck = 0;
1582 goto retry;
1583 }
1584
1585 DSSERR("Could not find suitable clock settings.\n");
1586
1587 return -EINVAL;
1588 }
1589found:
1590 cinfo->regm_dispc = best_regm_dispc;
1591 cinfo->dsi_pll_hsdiv_dispc_clk = best_dispc_clk;
1592
1593 *dispc_cinfo = best_dispc;
1594
1595 return 0;
1596}
1597
1598int dsi_pll_set_clock_div(struct platform_device *dsidev, 1443int dsi_pll_set_clock_div(struct platform_device *dsidev,
1599 struct dsi_clock_info *cinfo) 1444 struct dsi_clock_info *cinfo)
1600{ 1445{
@@ -2783,6 +2628,7 @@ static int dsi_vc_enable(struct platform_device *dsidev, int channel,
2783 2628
2784static void dsi_vc_initial_config(struct platform_device *dsidev, int channel) 2629static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
2785{ 2630{
2631 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
2786 u32 r; 2632 u32 r;
2787 2633
2788 DSSDBG("Initial config of virtual channel %d", channel); 2634 DSSDBG("Initial config of virtual channel %d", channel);
@@ -2807,6 +2653,8 @@ static void dsi_vc_initial_config(struct platform_device *dsidev, int channel)
2807 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */ 2653 r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
2808 2654
2809 dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r); 2655 dsi_write_reg(dsidev, DSI_VC_CTRL(channel), r);
2656
2657 dsi->vc[channel].source = DSI_VC_SOURCE_L4;
2810} 2658}
2811 2659
2812static int dsi_vc_config_source(struct platform_device *dsidev, int channel, 2660static int dsi_vc_config_source(struct platform_device *dsidev, int channel,
@@ -3777,13 +3625,12 @@ static void dsi_config_vp_num_line_buffers(struct platform_device *dsidev)
3777 3625
3778 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 3626 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
3779 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 3627 int bpp = dsi_get_pixel_size(dsi->pix_fmt);
3780 unsigned line_buf_size = dsi_get_line_buf_size(dsidev);
3781 struct omap_video_timings *timings = &dsi->timings; 3628 struct omap_video_timings *timings = &dsi->timings;
3782 /* 3629 /*
3783 * Don't use line buffers if width is greater than the video 3630 * Don't use line buffers if width is greater than the video
3784 * port's line buffer size 3631 * port's line buffer size
3785 */ 3632 */
3786 if (line_buf_size <= timings->x_res * bpp / 8) 3633 if (dsi->line_buffer_size <= timings->x_res * bpp / 8)
3787 num_line_buffers = 0; 3634 num_line_buffers = 0;
3788 else 3635 else
3789 num_line_buffers = 2; 3636 num_line_buffers = 2;
@@ -3799,18 +3646,22 @@ static void dsi_config_vp_num_line_buffers(struct platform_device *dsidev)
3799static void dsi_config_vp_sync_events(struct platform_device *dsidev) 3646static void dsi_config_vp_sync_events(struct platform_device *dsidev)
3800{ 3647{
3801 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3648 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3802 bool vsync_end = dsi->vm_timings.vp_vsync_end; 3649 bool sync_end;
3803 bool hsync_end = dsi->vm_timings.vp_hsync_end;
3804 u32 r; 3650 u32 r;
3805 3651
3652 if (dsi->vm_timings.trans_mode == OMAP_DSS_DSI_PULSE_MODE)
3653 sync_end = true;
3654 else
3655 sync_end = false;
3656
3806 r = dsi_read_reg(dsidev, DSI_CTRL); 3657 r = dsi_read_reg(dsidev, DSI_CTRL);
3807 r = FLD_MOD(r, 1, 9, 9); /* VP_DE_POL */ 3658 r = FLD_MOD(r, 1, 9, 9); /* VP_DE_POL */
3808 r = FLD_MOD(r, 1, 10, 10); /* VP_HSYNC_POL */ 3659 r = FLD_MOD(r, 1, 10, 10); /* VP_HSYNC_POL */
3809 r = FLD_MOD(r, 1, 11, 11); /* VP_VSYNC_POL */ 3660 r = FLD_MOD(r, 1, 11, 11); /* VP_VSYNC_POL */
3810 r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */ 3661 r = FLD_MOD(r, 1, 15, 15); /* VP_VSYNC_START */
3811 r = FLD_MOD(r, vsync_end, 16, 16); /* VP_VSYNC_END */ 3662 r = FLD_MOD(r, sync_end, 16, 16); /* VP_VSYNC_END */
3812 r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */ 3663 r = FLD_MOD(r, 1, 17, 17); /* VP_HSYNC_START */
3813 r = FLD_MOD(r, hsync_end, 18, 18); /* VP_HSYNC_END */ 3664 r = FLD_MOD(r, sync_end, 18, 18); /* VP_HSYNC_END */
3814 dsi_write_reg(dsidev, DSI_CTRL, r); 3665 dsi_write_reg(dsidev, DSI_CTRL, r);
3815} 3666}
3816 3667
@@ -3897,9 +3748,8 @@ static int dsi_compute_interleave_lp(int blank, int enter_hs, int exit_hs,
3897 return max(lp_inter, 0); 3748 return max(lp_inter, 0);
3898} 3749}
3899 3750
3900static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev) 3751static void dsi_config_cmd_mode_interleaving(struct platform_device *dsidev)
3901{ 3752{
3902 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
3903 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3753 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
3904 int blanking_mode; 3754 int blanking_mode;
3905 int hfp_blanking_mode, hbp_blanking_mode, hsa_blanking_mode; 3755 int hfp_blanking_mode, hbp_blanking_mode, hsa_blanking_mode;
@@ -3910,7 +3760,7 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
3910 struct omap_video_timings *timings = &dsi->timings; 3760 struct omap_video_timings *timings = &dsi->timings;
3911 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 3761 int bpp = dsi_get_pixel_size(dsi->pix_fmt);
3912 int ndl = dsi->num_lanes_used - 1; 3762 int ndl = dsi->num_lanes_used - 1;
3913 int dsi_fclk_hsdiv = dssdev->clocks.dsi.regm_dsi + 1; 3763 int dsi_fclk_hsdiv = dsi->user_dsi_cinfo.regm_dsi + 1;
3914 int hsa_interleave_hs = 0, hsa_interleave_lp = 0; 3764 int hsa_interleave_hs = 0, hsa_interleave_lp = 0;
3915 int hfp_interleave_hs = 0, hfp_interleave_lp = 0; 3765 int hfp_interleave_hs = 0, hfp_interleave_lp = 0;
3916 int hbp_interleave_hs = 0, hbp_interleave_lp = 0; 3766 int hbp_interleave_hs = 0, hbp_interleave_lp = 0;
@@ -4015,9 +3865,8 @@ static void dsi_config_cmd_mode_interleaving(struct omap_dss_device *dssdev)
4015 dsi_write_reg(dsidev, DSI_VM_TIMING6, r); 3865 dsi_write_reg(dsidev, DSI_VM_TIMING6, r);
4016} 3866}
4017 3867
4018static int dsi_proto_config(struct omap_dss_device *dssdev) 3868static int dsi_proto_config(struct platform_device *dsidev)
4019{ 3869{
4020 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4021 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 3870 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4022 u32 r; 3871 u32 r;
4023 int buswidth = 0; 3872 int buswidth = 0;
@@ -4075,7 +3924,7 @@ static int dsi_proto_config(struct omap_dss_device *dssdev)
4075 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 3924 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
4076 dsi_config_vp_sync_events(dsidev); 3925 dsi_config_vp_sync_events(dsidev);
4077 dsi_config_blanking_modes(dsidev); 3926 dsi_config_blanking_modes(dsidev);
4078 dsi_config_cmd_mode_interleaving(dssdev); 3927 dsi_config_cmd_mode_interleaving(dsidev);
4079 } 3928 }
4080 3929
4081 dsi_vc_initial_config(dsidev, 0); 3930 dsi_vc_initial_config(dsidev, 0);
@@ -4159,11 +4008,12 @@ static void dsi_proto_timings(struct platform_device *dsidev)
4159 int vfp = dsi->vm_timings.vfp; 4008 int vfp = dsi->vm_timings.vfp;
4160 int vbp = dsi->vm_timings.vbp; 4009 int vbp = dsi->vm_timings.vbp;
4161 int window_sync = dsi->vm_timings.window_sync; 4010 int window_sync = dsi->vm_timings.window_sync;
4162 bool hsync_end = dsi->vm_timings.vp_hsync_end; 4011 bool hsync_end;
4163 struct omap_video_timings *timings = &dsi->timings; 4012 struct omap_video_timings *timings = &dsi->timings;
4164 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 4013 int bpp = dsi_get_pixel_size(dsi->pix_fmt);
4165 int tl, t_he, width_bytes; 4014 int tl, t_he, width_bytes;
4166 4015
4016 hsync_end = dsi->vm_timings.trans_mode == OMAP_DSS_DSI_PULSE_MODE;
4167 t_he = hsync_end ? 4017 t_he = hsync_end ?
4168 ((hsa == 0 && ndl == 3) ? 1 : DIV_ROUND_UP(4, ndl)) : 0; 4018 ((hsa == 0 && ndl == 3) ? 1 : DIV_ROUND_UP(4, ndl)) : 0;
4169 4019
@@ -4266,82 +4116,26 @@ int omapdss_dsi_configure_pins(struct omap_dss_device *dssdev,
4266} 4116}
4267EXPORT_SYMBOL(omapdss_dsi_configure_pins); 4117EXPORT_SYMBOL(omapdss_dsi_configure_pins);
4268 4118
4269int omapdss_dsi_set_clocks(struct omap_dss_device *dssdev,
4270 unsigned long ddr_clk, unsigned long lp_clk)
4271{
4272 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4273 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4274 struct dsi_clock_info cinfo;
4275 struct dispc_clock_info dispc_cinfo;
4276 unsigned lp_clk_div;
4277 unsigned long dsi_fclk;
4278 int bpp = dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt);
4279 unsigned long pck;
4280 int r;
4281
4282 DSSDBG("Setting DSI clocks: ddr_clk %lu, lp_clk %lu", ddr_clk, lp_clk);
4283
4284 mutex_lock(&dsi->lock);
4285
4286 /* Calculate PLL output clock */
4287 r = dsi_pll_calc_ddrfreq(dsidev, ddr_clk * 4, &cinfo);
4288 if (r)
4289 goto err;
4290
4291 /* Calculate PLL's DSI clock */
4292 dsi_pll_calc_dsi_fck(dsidev, &cinfo);
4293
4294 /* Calculate PLL's DISPC clock and pck & lck divs */
4295 pck = cinfo.clkin4ddr / 16 * (dsi->num_lanes_used - 1) * 8 / bpp;
4296 DSSDBG("finding dispc dividers for pck %lu\n", pck);
4297 r = dsi_pll_calc_dispc_fck(dsidev, pck, &cinfo, &dispc_cinfo);
4298 if (r)
4299 goto err;
4300
4301 /* Calculate LP clock */
4302 dsi_fclk = cinfo.dsi_pll_hsdiv_dsi_clk;
4303 lp_clk_div = DIV_ROUND_UP(dsi_fclk, lp_clk * 2);
4304
4305 dssdev->clocks.dsi.regn = cinfo.regn;
4306 dssdev->clocks.dsi.regm = cinfo.regm;
4307 dssdev->clocks.dsi.regm_dispc = cinfo.regm_dispc;
4308 dssdev->clocks.dsi.regm_dsi = cinfo.regm_dsi;
4309
4310 dssdev->clocks.dsi.lp_clk_div = lp_clk_div;
4311
4312 dssdev->clocks.dispc.channel.lck_div = dispc_cinfo.lck_div;
4313 dssdev->clocks.dispc.channel.pck_div = dispc_cinfo.pck_div;
4314
4315 dssdev->clocks.dispc.dispc_fclk_src = OMAP_DSS_CLK_SRC_FCK;
4316
4317 dssdev->clocks.dispc.channel.lcd_clk_src =
4318 dsi->module_id == 0 ?
4319 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
4320 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC;
4321
4322 dssdev->clocks.dsi.dsi_fclk_src =
4323 dsi->module_id == 0 ?
4324 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
4325 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI;
4326
4327 mutex_unlock(&dsi->lock);
4328 return 0;
4329err:
4330 mutex_unlock(&dsi->lock);
4331 return r;
4332}
4333EXPORT_SYMBOL(omapdss_dsi_set_clocks);
4334
4335int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel) 4119int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
4336{ 4120{
4337 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4121 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4338 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4122 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4339 struct omap_overlay_manager *mgr = dssdev->output->manager; 4123 struct omap_overlay_manager *mgr = dsi->output.manager;
4340 int bpp = dsi_get_pixel_size(dsi->pix_fmt); 4124 int bpp = dsi_get_pixel_size(dsi->pix_fmt);
4125 struct omap_dss_output *out = &dsi->output;
4341 u8 data_type; 4126 u8 data_type;
4342 u16 word_count; 4127 u16 word_count;
4343 int r; 4128 int r;
4344 4129
4130 if (out == NULL || out->manager == NULL) {
4131 DSSERR("failed to enable display: no output/manager\n");
4132 return -ENODEV;
4133 }
4134
4135 r = dsi_display_init_dispc(dsidev, mgr);
4136 if (r)
4137 goto err_init_dispc;
4138
4345 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4139 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
4346 switch (dsi->pix_fmt) { 4140 switch (dsi->pix_fmt) {
4347 case OMAP_DSS_DSI_FMT_RGB888: 4141 case OMAP_DSS_DSI_FMT_RGB888:
@@ -4357,8 +4151,8 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
4357 data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16; 4151 data_type = MIPI_DSI_PACKED_PIXEL_STREAM_16;
4358 break; 4152 break;
4359 default: 4153 default:
4360 BUG(); 4154 r = -EINVAL;
4361 return -EINVAL; 4155 goto err_pix_fmt;
4362 }; 4156 };
4363 4157
4364 dsi_if_enable(dsidev, false); 4158 dsi_if_enable(dsidev, false);
@@ -4377,16 +4171,20 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
4377 } 4171 }
4378 4172
4379 r = dss_mgr_enable(mgr); 4173 r = dss_mgr_enable(mgr);
4380 if (r) { 4174 if (r)
4381 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4175 goto err_mgr_enable;
4382 dsi_if_enable(dsidev, false);
4383 dsi_vc_enable(dsidev, channel, false);
4384 }
4385
4386 return r;
4387 }
4388 4176
4389 return 0; 4177 return 0;
4178
4179err_mgr_enable:
4180 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
4181 dsi_if_enable(dsidev, false);
4182 dsi_vc_enable(dsidev, channel, false);
4183 }
4184err_pix_fmt:
4185 dsi_display_uninit_dispc(dsidev, mgr);
4186err_init_dispc:
4187 return r;
4390} 4188}
4391EXPORT_SYMBOL(dsi_enable_video_output); 4189EXPORT_SYMBOL(dsi_enable_video_output);
4392 4190
@@ -4394,7 +4192,7 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
4394{ 4192{
4395 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4193 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4396 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4194 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4397 struct omap_overlay_manager *mgr = dssdev->output->manager; 4195 struct omap_overlay_manager *mgr = dsi->output.manager;
4398 4196
4399 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) { 4197 if (dsi->mode == OMAP_DSS_DSI_VIDEO_MODE) {
4400 dsi_if_enable(dsidev, false); 4198 dsi_if_enable(dsidev, false);
@@ -4408,14 +4206,15 @@ void dsi_disable_video_output(struct omap_dss_device *dssdev, int channel)
4408 } 4206 }
4409 4207
4410 dss_mgr_disable(mgr); 4208 dss_mgr_disable(mgr);
4209
4210 dsi_display_uninit_dispc(dsidev, mgr);
4411} 4211}
4412EXPORT_SYMBOL(dsi_disable_video_output); 4212EXPORT_SYMBOL(dsi_disable_video_output);
4413 4213
4414static void dsi_update_screen_dispc(struct omap_dss_device *dssdev) 4214static void dsi_update_screen_dispc(struct platform_device *dsidev)
4415{ 4215{
4416 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4417 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4216 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4418 struct omap_overlay_manager *mgr = dssdev->output->manager; 4217 struct omap_overlay_manager *mgr = dsi->output.manager;
4419 unsigned bytespp; 4218 unsigned bytespp;
4420 unsigned bytespl; 4219 unsigned bytespl;
4421 unsigned bytespf; 4220 unsigned bytespf;
@@ -4425,7 +4224,7 @@ static void dsi_update_screen_dispc(struct omap_dss_device *dssdev)
4425 u32 l; 4224 u32 l;
4426 int r; 4225 int r;
4427 const unsigned channel = dsi->update_channel; 4226 const unsigned channel = dsi->update_channel;
4428 const unsigned line_buf_size = dsi_get_line_buf_size(dsidev); 4227 const unsigned line_buf_size = dsi->line_buffer_size;
4429 u16 w = dsi->timings.x_res; 4228 u16 w = dsi->timings.x_res;
4430 u16 h = dsi->timings.y_res; 4229 u16 h = dsi->timings.y_res;
4431 4230
@@ -4571,7 +4370,7 @@ int omap_dsi_update(struct omap_dss_device *dssdev, int channel,
4571 dsi->update_bytes = dw * dh * 4370 dsi->update_bytes = dw * dh *
4572 dsi_get_pixel_size(dsi->pix_fmt) / 8; 4371 dsi_get_pixel_size(dsi->pix_fmt) / 8;
4573#endif 4372#endif
4574 dsi_update_screen_dispc(dssdev); 4373 dsi_update_screen_dispc(dsidev);
4575 4374
4576 return 0; 4375 return 0;
4577} 4376}
@@ -4579,18 +4378,17 @@ EXPORT_SYMBOL(omap_dsi_update);
4579 4378
4580/* Display funcs */ 4379/* Display funcs */
4581 4380
4582static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev) 4381static int dsi_configure_dispc_clocks(struct platform_device *dsidev)
4583{ 4382{
4584 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4585 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4383 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4586 struct dispc_clock_info dispc_cinfo; 4384 struct dispc_clock_info dispc_cinfo;
4587 int r; 4385 int r;
4588 unsigned long long fck; 4386 unsigned long fck;
4589 4387
4590 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev); 4388 fck = dsi_get_pll_hsdiv_dispc_rate(dsidev);
4591 4389
4592 dispc_cinfo.lck_div = dssdev->clocks.dispc.channel.lck_div; 4390 dispc_cinfo.lck_div = dsi->user_dispc_cinfo.lck_div;
4593 dispc_cinfo.pck_div = dssdev->clocks.dispc.channel.pck_div; 4391 dispc_cinfo.pck_div = dsi->user_dispc_cinfo.pck_div;
4594 4392
4595 r = dispc_calc_clock_rates(fck, &dispc_cinfo); 4393 r = dispc_calc_clock_rates(fck, &dispc_cinfo);
4596 if (r) { 4394 if (r) {
@@ -4603,21 +4401,17 @@ static int dsi_configure_dispc_clocks(struct omap_dss_device *dssdev)
4603 return 0; 4401 return 0;
4604} 4402}
4605 4403
4606static int dsi_display_init_dispc(struct omap_dss_device *dssdev) 4404static int dsi_display_init_dispc(struct platform_device *dsidev,
4405 struct omap_overlay_manager *mgr)
4607{ 4406{
4608 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4609 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4407 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4610 struct omap_overlay_manager *mgr = dssdev->output->manager;
4611 int r; 4408 int r;
4612 4409
4613 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) { 4410 dss_select_lcd_clk_source(mgr->id, dsi->module_id == 0 ?
4614 dsi->timings.hsw = 1; 4411 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DISPC :
4615 dsi->timings.hfp = 1; 4412 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DISPC);
4616 dsi->timings.hbp = 1;
4617 dsi->timings.vsw = 1;
4618 dsi->timings.vfp = 0;
4619 dsi->timings.vbp = 0;
4620 4413
4414 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) {
4621 r = dss_mgr_register_framedone_handler(mgr, 4415 r = dss_mgr_register_framedone_handler(mgr,
4622 dsi_framedone_irq_callback, dsidev); 4416 dsi_framedone_irq_callback, dsidev);
4623 if (r) { 4417 if (r) {
@@ -4645,7 +4439,7 @@ static int dsi_display_init_dispc(struct omap_dss_device *dssdev)
4645 4439
4646 dss_mgr_set_timings(mgr, &dsi->timings); 4440 dss_mgr_set_timings(mgr, &dsi->timings);
4647 4441
4648 r = dsi_configure_dispc_clocks(dssdev); 4442 r = dsi_configure_dispc_clocks(dsidev);
4649 if (r) 4443 if (r)
4650 goto err1; 4444 goto err1;
4651 4445
@@ -4662,30 +4456,30 @@ err1:
4662 dss_mgr_unregister_framedone_handler(mgr, 4456 dss_mgr_unregister_framedone_handler(mgr,
4663 dsi_framedone_irq_callback, dsidev); 4457 dsi_framedone_irq_callback, dsidev);
4664err: 4458err:
4459 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
4665 return r; 4460 return r;
4666} 4461}
4667 4462
4668static void dsi_display_uninit_dispc(struct omap_dss_device *dssdev) 4463static void dsi_display_uninit_dispc(struct platform_device *dsidev,
4464 struct omap_overlay_manager *mgr)
4669{ 4465{
4670 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4671 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4466 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4672 struct omap_overlay_manager *mgr = dssdev->output->manager;
4673 4467
4674 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE) 4468 if (dsi->mode == OMAP_DSS_DSI_CMD_MODE)
4675 dss_mgr_unregister_framedone_handler(mgr, 4469 dss_mgr_unregister_framedone_handler(mgr,
4676 dsi_framedone_irq_callback, dsidev); 4470 dsi_framedone_irq_callback, dsidev);
4471
4472 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
4677} 4473}
4678 4474
4679static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev) 4475static int dsi_configure_dsi_clocks(struct platform_device *dsidev)
4680{ 4476{
4681 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4477 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4682 struct dsi_clock_info cinfo; 4478 struct dsi_clock_info cinfo;
4683 int r; 4479 int r;
4684 4480
4685 cinfo.regn = dssdev->clocks.dsi.regn; 4481 cinfo = dsi->user_dsi_cinfo;
4686 cinfo.regm = dssdev->clocks.dsi.regm; 4482
4687 cinfo.regm_dispc = dssdev->clocks.dsi.regm_dispc;
4688 cinfo.regm_dsi = dssdev->clocks.dsi.regm_dsi;
4689 r = dsi_calc_clock_rates(dsidev, &cinfo); 4483 r = dsi_calc_clock_rates(dsidev, &cinfo);
4690 if (r) { 4484 if (r) {
4691 DSSERR("Failed to calc dsi clocks\n"); 4485 DSSERR("Failed to calc dsi clocks\n");
@@ -4701,24 +4495,22 @@ static int dsi_configure_dsi_clocks(struct omap_dss_device *dssdev)
4701 return 0; 4495 return 0;
4702} 4496}
4703 4497
4704static int dsi_display_init_dsi(struct omap_dss_device *dssdev) 4498static int dsi_display_init_dsi(struct platform_device *dsidev)
4705{ 4499{
4706 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4707 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4500 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4708 struct omap_overlay_manager *mgr = dssdev->output->manager;
4709 int r; 4501 int r;
4710 4502
4711 r = dsi_pll_init(dsidev, true, true); 4503 r = dsi_pll_init(dsidev, true, true);
4712 if (r) 4504 if (r)
4713 goto err0; 4505 goto err0;
4714 4506
4715 r = dsi_configure_dsi_clocks(dssdev); 4507 r = dsi_configure_dsi_clocks(dsidev);
4716 if (r) 4508 if (r)
4717 goto err1; 4509 goto err1;
4718 4510
4719 dss_select_dsi_clk_source(dsi->module_id, dssdev->clocks.dsi.dsi_fclk_src); 4511 dss_select_dsi_clk_source(dsi->module_id, dsi->module_id == 0 ?
4720 dss_select_lcd_clk_source(mgr->id, 4512 OMAP_DSS_CLK_SRC_DSI_PLL_HSDIV_DSI :
4721 dssdev->clocks.dispc.channel.lcd_clk_src); 4513 OMAP_DSS_CLK_SRC_DSI2_PLL_HSDIV_DSI);
4722 4514
4723 DSSDBG("PLL OK\n"); 4515 DSSDBG("PLL OK\n");
4724 4516
@@ -4729,12 +4521,12 @@ static int dsi_display_init_dsi(struct omap_dss_device *dssdev)
4729 _dsi_print_reset_status(dsidev); 4521 _dsi_print_reset_status(dsidev);
4730 4522
4731 dsi_proto_timings(dsidev); 4523 dsi_proto_timings(dsidev);
4732 dsi_set_lp_clk_divisor(dssdev); 4524 dsi_set_lp_clk_divisor(dsidev);
4733 4525
4734 if (1) 4526 if (1)
4735 _dsi_print_reset_status(dsidev); 4527 _dsi_print_reset_status(dsidev);
4736 4528
4737 r = dsi_proto_config(dssdev); 4529 r = dsi_proto_config(dsidev);
4738 if (r) 4530 if (r)
4739 goto err3; 4531 goto err3;
4740 4532
@@ -4751,20 +4543,16 @@ err3:
4751 dsi_cio_uninit(dsidev); 4543 dsi_cio_uninit(dsidev);
4752err2: 4544err2:
4753 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4545 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
4754 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
4755
4756err1: 4546err1:
4757 dsi_pll_uninit(dsidev, true); 4547 dsi_pll_uninit(dsidev, true);
4758err0: 4548err0:
4759 return r; 4549 return r;
4760} 4550}
4761 4551
4762static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev, 4552static void dsi_display_uninit_dsi(struct platform_device *dsidev,
4763 bool disconnect_lanes, bool enter_ulps) 4553 bool disconnect_lanes, bool enter_ulps)
4764{ 4554{
4765 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4766 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4555 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4767 struct omap_overlay_manager *mgr = dssdev->output->manager;
4768 4556
4769 if (enter_ulps && !dsi->ulps_enabled) 4557 if (enter_ulps && !dsi->ulps_enabled)
4770 dsi_enter_ulps(dsidev); 4558 dsi_enter_ulps(dsidev);
@@ -4777,7 +4565,6 @@ static void dsi_display_uninit_dsi(struct omap_dss_device *dssdev,
4777 dsi_vc_enable(dsidev, 3, 0); 4565 dsi_vc_enable(dsidev, 3, 0);
4778 4566
4779 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK); 4567 dss_select_dsi_clk_source(dsi->module_id, OMAP_DSS_CLK_SRC_FCK);
4780 dss_select_lcd_clk_source(mgr->id, OMAP_DSS_CLK_SRC_FCK);
4781 dsi_cio_uninit(dsidev); 4568 dsi_cio_uninit(dsidev);
4782 dsi_pll_uninit(dsidev, disconnect_lanes); 4569 dsi_pll_uninit(dsidev, disconnect_lanes);
4783} 4570}
@@ -4786,7 +4573,6 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4786{ 4573{
4787 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4574 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4788 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4575 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4789 struct omap_dss_output *out = dssdev->output;
4790 int r = 0; 4576 int r = 0;
4791 4577
4792 DSSDBG("dsi_display_enable\n"); 4578 DSSDBG("dsi_display_enable\n");
@@ -4795,12 +4581,6 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4795 4581
4796 mutex_lock(&dsi->lock); 4582 mutex_lock(&dsi->lock);
4797 4583
4798 if (out == NULL || out->manager == NULL) {
4799 DSSERR("failed to enable display: no output/manager\n");
4800 r = -ENODEV;
4801 goto err_start_dev;
4802 }
4803
4804 r = omap_dss_start_device(dssdev); 4584 r = omap_dss_start_device(dssdev);
4805 if (r) { 4585 if (r) {
4806 DSSERR("failed to start device\n"); 4586 DSSERR("failed to start device\n");
@@ -4815,11 +4595,7 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4815 4595
4816 _dsi_initialize_irq(dsidev); 4596 _dsi_initialize_irq(dsidev);
4817 4597
4818 r = dsi_display_init_dispc(dssdev); 4598 r = dsi_display_init_dsi(dsidev);
4819 if (r)
4820 goto err_init_dispc;
4821
4822 r = dsi_display_init_dsi(dssdev);
4823 if (r) 4599 if (r)
4824 goto err_init_dsi; 4600 goto err_init_dsi;
4825 4601
@@ -4828,8 +4604,6 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
4828 return 0; 4604 return 0;
4829 4605
4830err_init_dsi: 4606err_init_dsi:
4831 dsi_display_uninit_dispc(dssdev);
4832err_init_dispc:
4833 dsi_enable_pll_clock(dsidev, 0); 4607 dsi_enable_pll_clock(dsidev, 0);
4834 dsi_runtime_put(dsidev); 4608 dsi_runtime_put(dsidev);
4835err_get_dsi: 4609err_get_dsi:
@@ -4858,9 +4632,7 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
4858 dsi_sync_vc(dsidev, 2); 4632 dsi_sync_vc(dsidev, 2);
4859 dsi_sync_vc(dsidev, 3); 4633 dsi_sync_vc(dsidev, 3);
4860 4634
4861 dsi_display_uninit_dispc(dssdev); 4635 dsi_display_uninit_dsi(dsidev, disconnect_lanes, enter_ulps);
4862
4863 dsi_display_uninit_dsi(dssdev, disconnect_lanes, enter_ulps);
4864 4636
4865 dsi_runtime_put(dsidev); 4637 dsi_runtime_put(dsidev);
4866 dsi_enable_pll_clock(dsidev, 0); 4638 dsi_enable_pll_clock(dsidev, 0);
@@ -4881,75 +4653,577 @@ int omapdss_dsi_enable_te(struct omap_dss_device *dssdev, bool enable)
4881} 4653}
4882EXPORT_SYMBOL(omapdss_dsi_enable_te); 4654EXPORT_SYMBOL(omapdss_dsi_enable_te);
4883 4655
4884void omapdss_dsi_set_timings(struct omap_dss_device *dssdev, 4656#ifdef PRINT_VERBOSE_VM_TIMINGS
4885 struct omap_video_timings *timings) 4657static void print_dsi_vm(const char *str,
4658 const struct omap_dss_dsi_videomode_timings *t)
4659{
4660 unsigned long byteclk = t->hsclk / 4;
4661 int bl, wc, pps, tot;
4662
4663 wc = DIV_ROUND_UP(t->hact * t->bitspp, 8);
4664 pps = DIV_ROUND_UP(wc + 6, t->ndl); /* pixel packet size */
4665 bl = t->hss + t->hsa + t->hse + t->hbp + t->hfp;
4666 tot = bl + pps;
4667
4668#define TO_DSI_T(x) ((u32)div64_u64((u64)x * 1000000000llu, byteclk))
4669
4670 pr_debug("%s bck %lu, %u/%u/%u/%u/%u/%u = %u+%u = %u, "
4671 "%u/%u/%u/%u/%u/%u = %u + %u = %u\n",
4672 str,
4673 byteclk,
4674 t->hss, t->hsa, t->hse, t->hbp, pps, t->hfp,
4675 bl, pps, tot,
4676 TO_DSI_T(t->hss),
4677 TO_DSI_T(t->hsa),
4678 TO_DSI_T(t->hse),
4679 TO_DSI_T(t->hbp),
4680 TO_DSI_T(pps),
4681 TO_DSI_T(t->hfp),
4682
4683 TO_DSI_T(bl),
4684 TO_DSI_T(pps),
4685
4686 TO_DSI_T(tot));
4687#undef TO_DSI_T
4688}
4689
4690static void print_dispc_vm(const char *str, const struct omap_video_timings *t)
4691{
4692 unsigned long pck = t->pixel_clock * 1000;
4693 int hact, bl, tot;
4694
4695 hact = t->x_res;
4696 bl = t->hsw + t->hbp + t->hfp;
4697 tot = hact + bl;
4698
4699#define TO_DISPC_T(x) ((u32)div64_u64((u64)x * 1000000000llu, pck))
4700
4701 pr_debug("%s pck %lu, %u/%u/%u/%u = %u+%u = %u, "
4702 "%u/%u/%u/%u = %u + %u = %u\n",
4703 str,
4704 pck,
4705 t->hsw, t->hbp, hact, t->hfp,
4706 bl, hact, tot,
4707 TO_DISPC_T(t->hsw),
4708 TO_DISPC_T(t->hbp),
4709 TO_DISPC_T(hact),
4710 TO_DISPC_T(t->hfp),
4711 TO_DISPC_T(bl),
4712 TO_DISPC_T(hact),
4713 TO_DISPC_T(tot));
4714#undef TO_DISPC_T
4715}
4716
4717/* note: this is not quite accurate */
4718static void print_dsi_dispc_vm(const char *str,
4719 const struct omap_dss_dsi_videomode_timings *t)
4720{
4721 struct omap_video_timings vm = { 0 };
4722 unsigned long byteclk = t->hsclk / 4;
4723 unsigned long pck;
4724 u64 dsi_tput;
4725 int dsi_hact, dsi_htot;
4726
4727 dsi_tput = (u64)byteclk * t->ndl * 8;
4728 pck = (u32)div64_u64(dsi_tput, t->bitspp);
4729 dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(t->hact * t->bitspp, 8) + 6, t->ndl);
4730 dsi_htot = t->hss + t->hsa + t->hse + t->hbp + dsi_hact + t->hfp;
4731
4732 vm.pixel_clock = pck / 1000;
4733 vm.hsw = div64_u64((u64)(t->hsa + t->hse) * pck, byteclk);
4734 vm.hbp = div64_u64((u64)t->hbp * pck, byteclk);
4735 vm.hfp = div64_u64((u64)t->hfp * pck, byteclk);
4736 vm.x_res = t->hact;
4737
4738 print_dispc_vm(str, &vm);
4739}
4740#endif /* PRINT_VERBOSE_VM_TIMINGS */
4741
4742static bool dsi_cm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
4743 unsigned long pck, void *data)
4886{ 4744{
4887 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4745 struct dsi_clk_calc_ctx *ctx = data;
4888 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4746 struct omap_video_timings *t = &ctx->dispc_vm;
4889 4747
4890 mutex_lock(&dsi->lock); 4748 ctx->dispc_cinfo.lck_div = lckd;
4749 ctx->dispc_cinfo.pck_div = pckd;
4750 ctx->dispc_cinfo.lck = lck;
4751 ctx->dispc_cinfo.pck = pck;
4891 4752
4892 dsi->timings = *timings; 4753 *t = *ctx->config->timings;
4754 t->pixel_clock = pck / 1000;
4755 t->x_res = ctx->config->timings->x_res;
4756 t->y_res = ctx->config->timings->y_res;
4757 t->hsw = t->hfp = t->hbp = t->vsw = 1;
4758 t->vfp = t->vbp = 0;
4893 4759
4894 mutex_unlock(&dsi->lock); 4760 return true;
4895} 4761}
4896EXPORT_SYMBOL(omapdss_dsi_set_timings);
4897 4762
4898void omapdss_dsi_set_size(struct omap_dss_device *dssdev, u16 w, u16 h) 4763static bool dsi_cm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
4764 void *data)
4899{ 4765{
4900 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4766 struct dsi_clk_calc_ctx *ctx = data;
4901 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
4902 4767
4903 mutex_lock(&dsi->lock); 4768 ctx->dsi_cinfo.regm_dispc = regm_dispc;
4769 ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc;
4904 4770
4905 dsi->timings.x_res = w; 4771 return dispc_div_calc(dispc, ctx->req_pck_min, ctx->req_pck_max,
4906 dsi->timings.y_res = h; 4772 dsi_cm_calc_dispc_cb, ctx);
4773}
4907 4774
4908 mutex_unlock(&dsi->lock); 4775static bool dsi_cm_calc_pll_cb(int regn, int regm, unsigned long fint,
4776 unsigned long pll, void *data)
4777{
4778 struct dsi_clk_calc_ctx *ctx = data;
4779
4780 ctx->dsi_cinfo.regn = regn;
4781 ctx->dsi_cinfo.regm = regm;
4782 ctx->dsi_cinfo.fint = fint;
4783 ctx->dsi_cinfo.clkin4ddr = pll;
4784
4785 return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min,
4786 dsi_cm_calc_hsdiv_cb, ctx);
4909} 4787}
4910EXPORT_SYMBOL(omapdss_dsi_set_size);
4911 4788
4912void omapdss_dsi_set_pixel_format(struct omap_dss_device *dssdev, 4789static bool dsi_cm_calc(struct dsi_data *dsi,
4913 enum omap_dss_dsi_pixel_format fmt) 4790 const struct omap_dss_dsi_config *cfg,
4791 struct dsi_clk_calc_ctx *ctx)
4914{ 4792{
4915 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4793 unsigned long clkin;
4916 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4794 int bitspp, ndl;
4795 unsigned long pll_min, pll_max;
4796 unsigned long pck, txbyteclk;
4917 4797
4918 mutex_lock(&dsi->lock); 4798 clkin = clk_get_rate(dsi->sys_clk);
4799 bitspp = dsi_get_pixel_size(cfg->pixel_format);
4800 ndl = dsi->num_lanes_used - 1;
4801
4802 /*
4803 * Here we should calculate minimum txbyteclk to be able to send the
4804 * frame in time, and also to handle TE. That's not very simple, though,
4805 * especially as we go to LP between each pixel packet due to HW
4806 * "feature". So let's just estimate very roughly and multiply by 1.5.
4807 */
4808 pck = cfg->timings->pixel_clock * 1000;
4809 pck = pck * 3 / 2;
4810 txbyteclk = pck * bitspp / 8 / ndl;
4919 4811
4920 dsi->pix_fmt = fmt; 4812 memset(ctx, 0, sizeof(*ctx));
4813 ctx->dsidev = dsi->pdev;
4814 ctx->config = cfg;
4815 ctx->req_pck_min = pck;
4816 ctx->req_pck_nom = pck;
4817 ctx->req_pck_max = pck * 3 / 2;
4818 ctx->dsi_cinfo.clkin = clkin;
4921 4819
4922 mutex_unlock(&dsi->lock); 4820 pll_min = max(cfg->hs_clk_min * 4, txbyteclk * 4 * 4);
4821 pll_max = cfg->hs_clk_max * 4;
4822
4823 return dsi_pll_calc(dsi->pdev, clkin,
4824 pll_min, pll_max,
4825 dsi_cm_calc_pll_cb, ctx);
4923} 4826}
4924EXPORT_SYMBOL(omapdss_dsi_set_pixel_format);
4925 4827
4926void omapdss_dsi_set_operation_mode(struct omap_dss_device *dssdev, 4828static bool dsi_vm_calc_blanking(struct dsi_clk_calc_ctx *ctx)
4927 enum omap_dss_dsi_mode mode)
4928{ 4829{
4929 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 4830 struct dsi_data *dsi = dsi_get_dsidrv_data(ctx->dsidev);
4930 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 4831 const struct omap_dss_dsi_config *cfg = ctx->config;
4832 int bitspp = dsi_get_pixel_size(cfg->pixel_format);
4833 int ndl = dsi->num_lanes_used - 1;
4834 unsigned long hsclk = ctx->dsi_cinfo.clkin4ddr / 4;
4835 unsigned long byteclk = hsclk / 4;
4931 4836
4932 mutex_lock(&dsi->lock); 4837 unsigned long dispc_pck, req_pck_min, req_pck_nom, req_pck_max;
4838 int xres;
4839 int panel_htot, panel_hbl; /* pixels */
4840 int dispc_htot, dispc_hbl; /* pixels */
4841 int dsi_htot, dsi_hact, dsi_hbl, hss, hse; /* byteclks */
4842 int hfp, hsa, hbp;
4843 const struct omap_video_timings *req_vm;
4844 struct omap_video_timings *dispc_vm;
4845 struct omap_dss_dsi_videomode_timings *dsi_vm;
4846 u64 dsi_tput, dispc_tput;
4933 4847
4934 dsi->mode = mode; 4848 dsi_tput = (u64)byteclk * ndl * 8;
4935 4849
4936 mutex_unlock(&dsi->lock); 4850 req_vm = cfg->timings;
4851 req_pck_min = ctx->req_pck_min;
4852 req_pck_max = ctx->req_pck_max;
4853 req_pck_nom = ctx->req_pck_nom;
4854
4855 dispc_pck = ctx->dispc_cinfo.pck;
4856 dispc_tput = (u64)dispc_pck * bitspp;
4857
4858 xres = req_vm->x_res;
4859
4860 panel_hbl = req_vm->hfp + req_vm->hbp + req_vm->hsw;
4861 panel_htot = xres + panel_hbl;
4862
4863 dsi_hact = DIV_ROUND_UP(DIV_ROUND_UP(xres * bitspp, 8) + 6, ndl);
4864
4865 /*
4866 * When there are no line buffers, DISPC and DSI must have the
4867 * same tput. Otherwise DISPC tput needs to be higher than DSI's.
4868 */
4869 if (dsi->line_buffer_size < xres * bitspp / 8) {
4870 if (dispc_tput != dsi_tput)
4871 return false;
4872 } else {
4873 if (dispc_tput < dsi_tput)
4874 return false;
4875 }
4876
4877 /* DSI tput must be over the min requirement */
4878 if (dsi_tput < (u64)bitspp * req_pck_min)
4879 return false;
4880
4881 /* When non-burst mode, DSI tput must be below max requirement. */
4882 if (cfg->trans_mode != OMAP_DSS_DSI_BURST_MODE) {
4883 if (dsi_tput > (u64)bitspp * req_pck_max)
4884 return false;
4885 }
4886
4887 hss = DIV_ROUND_UP(4, ndl);
4888
4889 if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) {
4890 if (ndl == 3 && req_vm->hsw == 0)
4891 hse = 1;
4892 else
4893 hse = DIV_ROUND_UP(4, ndl);
4894 } else {
4895 hse = 0;
4896 }
4897
4898 /* DSI htot to match the panel's nominal pck */
4899 dsi_htot = div64_u64((u64)panel_htot * byteclk, req_pck_nom);
4900
4901 /* fail if there would be no time for blanking */
4902 if (dsi_htot < hss + hse + dsi_hact)
4903 return false;
4904
4905 /* total DSI blanking needed to achieve panel's TL */
4906 dsi_hbl = dsi_htot - dsi_hact;
4907
4908 /* DISPC htot to match the DSI TL */
4909 dispc_htot = div64_u64((u64)dsi_htot * dispc_pck, byteclk);
4910
4911 /* verify that the DSI and DISPC TLs are the same */
4912 if ((u64)dsi_htot * dispc_pck != (u64)dispc_htot * byteclk)
4913 return false;
4914
4915 dispc_hbl = dispc_htot - xres;
4916
4917 /* setup DSI videomode */
4918
4919 dsi_vm = &ctx->dsi_vm;
4920 memset(dsi_vm, 0, sizeof(*dsi_vm));
4921
4922 dsi_vm->hsclk = hsclk;
4923
4924 dsi_vm->ndl = ndl;
4925 dsi_vm->bitspp = bitspp;
4926
4927 if (cfg->trans_mode != OMAP_DSS_DSI_PULSE_MODE) {
4928 hsa = 0;
4929 } else if (ndl == 3 && req_vm->hsw == 0) {
4930 hsa = 0;
4931 } else {
4932 hsa = div64_u64((u64)req_vm->hsw * byteclk, req_pck_nom);
4933 hsa = max(hsa - hse, 1);
4934 }
4935
4936 hbp = div64_u64((u64)req_vm->hbp * byteclk, req_pck_nom);
4937 hbp = max(hbp, 1);
4938
4939 hfp = dsi_hbl - (hss + hsa + hse + hbp);
4940 if (hfp < 1) {
4941 int t;
4942 /* we need to take cycles from hbp */
4943
4944 t = 1 - hfp;
4945 hbp = max(hbp - t, 1);
4946 hfp = dsi_hbl - (hss + hsa + hse + hbp);
4947
4948 if (hfp < 1 && hsa > 0) {
4949 /* we need to take cycles from hsa */
4950 t = 1 - hfp;
4951 hsa = max(hsa - t, 1);
4952 hfp = dsi_hbl - (hss + hsa + hse + hbp);
4953 }
4954 }
4955
4956 if (hfp < 1)
4957 return false;
4958
4959 dsi_vm->hss = hss;
4960 dsi_vm->hsa = hsa;
4961 dsi_vm->hse = hse;
4962 dsi_vm->hbp = hbp;
4963 dsi_vm->hact = xres;
4964 dsi_vm->hfp = hfp;
4965
4966 dsi_vm->vsa = req_vm->vsw;
4967 dsi_vm->vbp = req_vm->vbp;
4968 dsi_vm->vact = req_vm->y_res;
4969 dsi_vm->vfp = req_vm->vfp;
4970
4971 dsi_vm->trans_mode = cfg->trans_mode;
4972
4973 dsi_vm->blanking_mode = 0;
4974 dsi_vm->hsa_blanking_mode = 1;
4975 dsi_vm->hfp_blanking_mode = 1;
4976 dsi_vm->hbp_blanking_mode = 1;
4977
4978 dsi_vm->ddr_clk_always_on = cfg->ddr_clk_always_on;
4979 dsi_vm->window_sync = 4;
4980
4981 /* setup DISPC videomode */
4982
4983 dispc_vm = &ctx->dispc_vm;
4984 *dispc_vm = *req_vm;
4985 dispc_vm->pixel_clock = dispc_pck / 1000;
4986
4987 if (cfg->trans_mode == OMAP_DSS_DSI_PULSE_MODE) {
4988 hsa = div64_u64((u64)req_vm->hsw * dispc_pck,
4989 req_pck_nom);
4990 hsa = max(hsa, 1);
4991 } else {
4992 hsa = 1;
4993 }
4994
4995 hbp = div64_u64((u64)req_vm->hbp * dispc_pck, req_pck_nom);
4996 hbp = max(hbp, 1);
4997
4998 hfp = dispc_hbl - hsa - hbp;
4999 if (hfp < 1) {
5000 int t;
5001 /* we need to take cycles from hbp */
5002
5003 t = 1 - hfp;
5004 hbp = max(hbp - t, 1);
5005 hfp = dispc_hbl - hsa - hbp;
5006
5007 if (hfp < 1) {
5008 /* we need to take cycles from hsa */
5009 t = 1 - hfp;
5010 hsa = max(hsa - t, 1);
5011 hfp = dispc_hbl - hsa - hbp;
5012 }
5013 }
5014
5015 if (hfp < 1)
5016 return false;
5017
5018 dispc_vm->hfp = hfp;
5019 dispc_vm->hsw = hsa;
5020 dispc_vm->hbp = hbp;
5021
5022 return true;
5023}
5024
5025
5026static bool dsi_vm_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
5027 unsigned long pck, void *data)
5028{
5029 struct dsi_clk_calc_ctx *ctx = data;
5030
5031 ctx->dispc_cinfo.lck_div = lckd;
5032 ctx->dispc_cinfo.pck_div = pckd;
5033 ctx->dispc_cinfo.lck = lck;
5034 ctx->dispc_cinfo.pck = pck;
5035
5036 if (dsi_vm_calc_blanking(ctx) == false)
5037 return false;
5038
5039#ifdef PRINT_VERBOSE_VM_TIMINGS
5040 print_dispc_vm("dispc", &ctx->dispc_vm);
5041 print_dsi_vm("dsi ", &ctx->dsi_vm);
5042 print_dispc_vm("req ", ctx->config->timings);
5043 print_dsi_dispc_vm("act ", &ctx->dsi_vm);
5044#endif
5045
5046 return true;
5047}
5048
5049static bool dsi_vm_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
5050 void *data)
5051{
5052 struct dsi_clk_calc_ctx *ctx = data;
5053 unsigned long pck_max;
5054
5055 ctx->dsi_cinfo.regm_dispc = regm_dispc;
5056 ctx->dsi_cinfo.dsi_pll_hsdiv_dispc_clk = dispc;
5057
5058 /*
5059 * In burst mode we can let the dispc pck be arbitrarily high, but it
5060 * limits our scaling abilities. So for now, don't aim too high.
5061 */
5062
5063 if (ctx->config->trans_mode == OMAP_DSS_DSI_BURST_MODE)
5064 pck_max = ctx->req_pck_max + 10000000;
5065 else
5066 pck_max = ctx->req_pck_max;
5067
5068 return dispc_div_calc(dispc, ctx->req_pck_min, pck_max,
5069 dsi_vm_calc_dispc_cb, ctx);
5070}
5071
5072static bool dsi_vm_calc_pll_cb(int regn, int regm, unsigned long fint,
5073 unsigned long pll, void *data)
5074{
5075 struct dsi_clk_calc_ctx *ctx = data;
5076
5077 ctx->dsi_cinfo.regn = regn;
5078 ctx->dsi_cinfo.regm = regm;
5079 ctx->dsi_cinfo.fint = fint;
5080 ctx->dsi_cinfo.clkin4ddr = pll;
5081
5082 return dsi_hsdiv_calc(ctx->dsidev, pll, ctx->req_pck_min,
5083 dsi_vm_calc_hsdiv_cb, ctx);
5084}
5085
5086static bool dsi_vm_calc(struct dsi_data *dsi,
5087 const struct omap_dss_dsi_config *cfg,
5088 struct dsi_clk_calc_ctx *ctx)
5089{
5090 const struct omap_video_timings *t = cfg->timings;
5091 unsigned long clkin;
5092 unsigned long pll_min;
5093 unsigned long pll_max;
5094 int ndl = dsi->num_lanes_used - 1;
5095 int bitspp = dsi_get_pixel_size(cfg->pixel_format);
5096 unsigned long byteclk_min;
5097
5098 clkin = clk_get_rate(dsi->sys_clk);
5099
5100 memset(ctx, 0, sizeof(*ctx));
5101 ctx->dsidev = dsi->pdev;
5102 ctx->config = cfg;
5103
5104 ctx->dsi_cinfo.clkin = clkin;
5105
5106 /* these limits should come from the panel driver */
5107 ctx->req_pck_min = t->pixel_clock * 1000 - 1000;
5108 ctx->req_pck_nom = t->pixel_clock * 1000;
5109 ctx->req_pck_max = t->pixel_clock * 1000 + 1000;
5110
5111 byteclk_min = div64_u64((u64)ctx->req_pck_min * bitspp, ndl * 8);
5112 pll_min = max(cfg->hs_clk_min * 4, byteclk_min * 4 * 4);
5113
5114 if (cfg->trans_mode == OMAP_DSS_DSI_BURST_MODE) {
5115 pll_max = cfg->hs_clk_max * 4;
5116 } else {
5117 unsigned long byteclk_max;
5118 byteclk_max = div64_u64((u64)ctx->req_pck_max * bitspp,
5119 ndl * 8);
5120
5121 pll_max = byteclk_max * 4 * 4;
5122 }
5123
5124 return dsi_pll_calc(dsi->pdev, clkin,
5125 pll_min, pll_max,
5126 dsi_vm_calc_pll_cb, ctx);
4937} 5127}
4938EXPORT_SYMBOL(omapdss_dsi_set_operation_mode);
4939 5128
4940void omapdss_dsi_set_videomode_timings(struct omap_dss_device *dssdev, 5129int omapdss_dsi_set_config(struct omap_dss_device *dssdev,
4941 struct omap_dss_dsi_videomode_timings *timings) 5130 const struct omap_dss_dsi_config *config)
4942{ 5131{
4943 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); 5132 struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
4944 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5133 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5134 struct dsi_clk_calc_ctx ctx;
5135 bool ok;
5136 int r;
4945 5137
4946 mutex_lock(&dsi->lock); 5138 mutex_lock(&dsi->lock);
4947 5139
4948 dsi->vm_timings = *timings; 5140 dsi->pix_fmt = config->pixel_format;
5141 dsi->mode = config->mode;
5142
5143 if (config->mode == OMAP_DSS_DSI_VIDEO_MODE)
5144 ok = dsi_vm_calc(dsi, config, &ctx);
5145 else
5146 ok = dsi_cm_calc(dsi, config, &ctx);
5147
5148 if (!ok) {
5149 DSSERR("failed to find suitable DSI clock settings\n");
5150 r = -EINVAL;
5151 goto err;
5152 }
5153
5154 dsi_pll_calc_dsi_fck(&ctx.dsi_cinfo);
5155
5156 r = dsi_lp_clock_calc(&ctx.dsi_cinfo, config->lp_clk_min,
5157 config->lp_clk_max);
5158 if (r) {
5159 DSSERR("failed to find suitable DSI LP clock settings\n");
5160 goto err;
5161 }
5162
5163 dsi->user_dsi_cinfo = ctx.dsi_cinfo;
5164 dsi->user_dispc_cinfo = ctx.dispc_cinfo;
5165
5166 dsi->timings = ctx.dispc_vm;
5167 dsi->vm_timings = ctx.dsi_vm;
4949 5168
4950 mutex_unlock(&dsi->lock); 5169 mutex_unlock(&dsi->lock);
5170
5171 return 0;
5172err:
5173 mutex_unlock(&dsi->lock);
5174
5175 return r;
5176}
5177EXPORT_SYMBOL(omapdss_dsi_set_config);
5178
5179/*
5180 * Return a hardcoded channel for the DSI output. This should work for
5181 * current use cases, but this can be later expanded to either resolve
5182 * the channel in some more dynamic manner, or get the channel as a user
5183 * parameter.
5184 */
5185static enum omap_channel dsi_get_channel(int module_id)
5186{
5187 switch (omapdss_get_version()) {
5188 case OMAPDSS_VER_OMAP24xx:
5189 DSSWARN("DSI not supported\n");
5190 return OMAP_DSS_CHANNEL_LCD;
5191
5192 case OMAPDSS_VER_OMAP34xx_ES1:
5193 case OMAPDSS_VER_OMAP34xx_ES3:
5194 case OMAPDSS_VER_OMAP3630:
5195 case OMAPDSS_VER_AM35xx:
5196 return OMAP_DSS_CHANNEL_LCD;
5197
5198 case OMAPDSS_VER_OMAP4430_ES1:
5199 case OMAPDSS_VER_OMAP4430_ES2:
5200 case OMAPDSS_VER_OMAP4:
5201 switch (module_id) {
5202 case 0:
5203 return OMAP_DSS_CHANNEL_LCD;
5204 case 1:
5205 return OMAP_DSS_CHANNEL_LCD2;
5206 default:
5207 DSSWARN("unsupported module id\n");
5208 return OMAP_DSS_CHANNEL_LCD;
5209 }
5210
5211 case OMAPDSS_VER_OMAP5:
5212 switch (module_id) {
5213 case 0:
5214 return OMAP_DSS_CHANNEL_LCD;
5215 case 1:
5216 return OMAP_DSS_CHANNEL_LCD3;
5217 default:
5218 DSSWARN("unsupported module id\n");
5219 return OMAP_DSS_CHANNEL_LCD;
5220 }
5221
5222 default:
5223 DSSWARN("unsupported DSS version\n");
5224 return OMAP_DSS_CHANNEL_LCD;
5225 }
4951} 5226}
4952EXPORT_SYMBOL(omapdss_dsi_set_videomode_timings);
4953 5227
4954static int __init dsi_init_display(struct omap_dss_device *dssdev) 5228static int __init dsi_init_display(struct omap_dss_device *dssdev)
4955{ 5229{
@@ -5073,7 +5347,7 @@ static int dsi_get_clocks(struct platform_device *dsidev)
5073 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); 5347 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5074 struct clk *clk; 5348 struct clk *clk;
5075 5349
5076 clk = clk_get(&dsidev->dev, "fck"); 5350 clk = devm_clk_get(&dsidev->dev, "fck");
5077 if (IS_ERR(clk)) { 5351 if (IS_ERR(clk)) {
5078 DSSERR("can't get fck\n"); 5352 DSSERR("can't get fck\n");
5079 return PTR_ERR(clk); 5353 return PTR_ERR(clk);
@@ -5081,11 +5355,9 @@ static int dsi_get_clocks(struct platform_device *dsidev)
5081 5355
5082 dsi->dss_clk = clk; 5356 dsi->dss_clk = clk;
5083 5357
5084 clk = clk_get(&dsidev->dev, "sys_clk"); 5358 clk = devm_clk_get(&dsidev->dev, "sys_clk");
5085 if (IS_ERR(clk)) { 5359 if (IS_ERR(clk)) {
5086 DSSERR("can't get sys_clk\n"); 5360 DSSERR("can't get sys_clk\n");
5087 clk_put(dsi->dss_clk);
5088 dsi->dss_clk = NULL;
5089 return PTR_ERR(clk); 5361 return PTR_ERR(clk);
5090 } 5362 }
5091 5363
@@ -5094,16 +5366,6 @@ static int dsi_get_clocks(struct platform_device *dsidev)
5094 return 0; 5366 return 0;
5095} 5367}
5096 5368
5097static void dsi_put_clocks(struct platform_device *dsidev)
5098{
5099 struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
5100
5101 if (dsi->dss_clk)
5102 clk_put(dsi->dss_clk);
5103 if (dsi->sys_clk)
5104 clk_put(dsi->sys_clk);
5105}
5106
5107static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev) 5369static struct omap_dss_device * __init dsi_find_dssdev(struct platform_device *pdev)
5108{ 5370{
5109 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 5371 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
@@ -5188,6 +5450,8 @@ static void __init dsi_init_output(struct platform_device *dsidev)
5188 OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2; 5450 OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
5189 5451
5190 out->type = OMAP_DISPLAY_TYPE_DSI; 5452 out->type = OMAP_DISPLAY_TYPE_DSI;
5453 out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
5454 out->dispc_channel = dsi_get_channel(dsi->module_id);
5191 5455
5192 dss_register_output(out); 5456 dss_register_output(out);
5193} 5457}
@@ -5293,6 +5557,8 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
5293 else 5557 else
5294 dsi->num_lanes_supported = 3; 5558 dsi->num_lanes_supported = 3;
5295 5559
5560 dsi->line_buffer_size = dsi_get_line_buf_size(dsidev);
5561
5296 dsi_init_output(dsidev); 5562 dsi_init_output(dsidev);
5297 5563
5298 dsi_probe_pdata(dsidev); 5564 dsi_probe_pdata(dsidev);
@@ -5314,7 +5580,6 @@ static int __init omap_dsihw_probe(struct platform_device *dsidev)
5314 5580
5315err_runtime_get: 5581err_runtime_get:
5316 pm_runtime_disable(&dsidev->dev); 5582 pm_runtime_disable(&dsidev->dev);
5317 dsi_put_clocks(dsidev);
5318 return r; 5583 return r;
5319} 5584}
5320 5585
@@ -5330,8 +5595,6 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
5330 5595
5331 pm_runtime_disable(&dsidev->dev); 5596 pm_runtime_disable(&dsidev->dev);
5332 5597
5333 dsi_put_clocks(dsidev);
5334
5335 if (dsi->vdds_dsi_reg != NULL) { 5598 if (dsi->vdds_dsi_reg != NULL) {
5336 if (dsi->vdds_dsi_enabled) { 5599 if (dsi->vdds_dsi_enabled) {
5337 regulator_disable(dsi->vdds_dsi_reg); 5600 regulator_disable(dsi->vdds_dsi_reg);
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 054c2a22b3f1..94f66f9f10a3 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/omap2/dss/dss.c
@@ -473,6 +473,47 @@ int dss_calc_clock_rates(struct dss_clock_info *cinfo)
473 return 0; 473 return 0;
474} 474}
475 475
476bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data)
477{
478 int fckd, fckd_start, fckd_stop;
479 unsigned long fck;
480 unsigned long fck_hw_max;
481 unsigned long fckd_hw_max;
482 unsigned long prate;
483 unsigned m;
484
485 if (dss.dpll4_m4_ck == NULL) {
486 /*
487 * TODO: dss1_fclk can be changed on OMAP2, but the available
488 * dividers are not continuous. We just use the pre-set rate for
489 * now.
490 */
491 fck = clk_get_rate(dss.dss_clk);
492 fckd = 1;
493 return func(fckd, fck, data);
494 }
495
496 fck_hw_max = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
497 fckd_hw_max = dss.feat->fck_div_max;
498
499 m = dss.feat->dss_fck_multiplier;
500 prate = dss_get_dpll4_rate();
501
502 fck_min = fck_min ? fck_min : 1;
503
504 fckd_start = min(prate * m / fck_min, fckd_hw_max);
505 fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
506
507 for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
508 fck = prate / fckd * m;
509
510 if (func(fckd, fck, data))
511 return true;
512 }
513
514 return false;
515}
516
476int dss_set_clock_div(struct dss_clock_info *cinfo) 517int dss_set_clock_div(struct dss_clock_info *cinfo)
477{ 518{
478 if (dss.dpll4_m4_ck) { 519 if (dss.dpll4_m4_ck) {
@@ -482,7 +523,8 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
482 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck)); 523 prate = clk_get_rate(clk_get_parent(dss.dpll4_m4_ck));
483 DSSDBG("dpll4_m4 = %ld\n", prate); 524 DSSDBG("dpll4_m4 = %ld\n", prate);
484 525
485 r = clk_set_rate(dss.dpll4_m4_ck, prate / cinfo->fck_div); 526 r = clk_set_rate(dss.dpll4_m4_ck,
527 DIV_ROUND_UP(prate, cinfo->fck_div));
486 if (r) 528 if (r)
487 return r; 529 return r;
488 } else { 530 } else {
@@ -492,7 +534,9 @@ int dss_set_clock_div(struct dss_clock_info *cinfo)
492 534
493 dss.dss_clk_rate = clk_get_rate(dss.dss_clk); 535 dss.dss_clk_rate = clk_get_rate(dss.dss_clk);
494 536
495 WARN_ONCE(dss.dss_clk_rate != cinfo->fck, "clk rate mismatch"); 537 WARN_ONCE(dss.dss_clk_rate != cinfo->fck,
538 "clk rate mismatch: %lu != %lu", dss.dss_clk_rate,
539 cinfo->fck);
496 540
497 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div); 541 DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
498 542
@@ -542,121 +586,6 @@ static int dss_setup_default_clock(void)
542 return 0; 586 return 0;
543} 587}
544 588
545int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo,
546 struct dispc_clock_info *dispc_cinfo)
547{
548 unsigned long prate;
549 struct dss_clock_info best_dss;
550 struct dispc_clock_info best_dispc;
551
552 unsigned long fck, max_dss_fck;
553
554 u16 fck_div;
555
556 int match = 0;
557 int min_fck_per_pck;
558
559 prate = dss_get_dpll4_rate();
560
561 max_dss_fck = dss_feat_get_param_max(FEAT_PARAM_DSS_FCK);
562
563 fck = clk_get_rate(dss.dss_clk);
564 if (req_pck == dss.cache_req_pck && prate == dss.cache_prate &&
565 dss.cache_dss_cinfo.fck == fck) {
566 DSSDBG("dispc clock info found from cache.\n");
567 *dss_cinfo = dss.cache_dss_cinfo;
568 *dispc_cinfo = dss.cache_dispc_cinfo;
569 return 0;
570 }
571
572 min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
573
574 if (min_fck_per_pck &&
575 req_pck * min_fck_per_pck > max_dss_fck) {
576 DSSERR("Requested pixel clock not possible with the current "
577 "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
578 "the constraint off.\n");
579 min_fck_per_pck = 0;
580 }
581
582retry:
583 memset(&best_dss, 0, sizeof(best_dss));
584 memset(&best_dispc, 0, sizeof(best_dispc));
585
586 if (dss.dpll4_m4_ck == NULL) {
587 struct dispc_clock_info cur_dispc;
588 /* XXX can we change the clock on omap2? */
589 fck = clk_get_rate(dss.dss_clk);
590 fck_div = 1;
591
592 dispc_find_clk_divs(req_pck, fck, &cur_dispc);
593 match = 1;
594
595 best_dss.fck = fck;
596 best_dss.fck_div = fck_div;
597
598 best_dispc = cur_dispc;
599
600 goto found;
601 } else {
602 for (fck_div = dss.feat->fck_div_max; fck_div > 0; --fck_div) {
603 struct dispc_clock_info cur_dispc;
604
605 fck = prate / fck_div * dss.feat->dss_fck_multiplier;
606
607 if (fck > max_dss_fck)
608 continue;
609
610 if (min_fck_per_pck &&
611 fck < req_pck * min_fck_per_pck)
612 continue;
613
614 match = 1;
615
616 dispc_find_clk_divs(req_pck, fck, &cur_dispc);
617
618 if (abs(cur_dispc.pck - req_pck) <
619 abs(best_dispc.pck - req_pck)) {
620
621 best_dss.fck = fck;
622 best_dss.fck_div = fck_div;
623
624 best_dispc = cur_dispc;
625
626 if (cur_dispc.pck == req_pck)
627 goto found;
628 }
629 }
630 }
631
632found:
633 if (!match) {
634 if (min_fck_per_pck) {
635 DSSERR("Could not find suitable clock settings.\n"
636 "Turning FCK/PCK constraint off and"
637 "trying again.\n");
638 min_fck_per_pck = 0;
639 goto retry;
640 }
641
642 DSSERR("Could not find suitable clock settings.\n");
643
644 return -EINVAL;
645 }
646
647 if (dss_cinfo)
648 *dss_cinfo = best_dss;
649 if (dispc_cinfo)
650 *dispc_cinfo = best_dispc;
651
652 dss.cache_req_pck = req_pck;
653 dss.cache_prate = prate;
654 dss.cache_dss_cinfo = best_dss;
655 dss.cache_dispc_cinfo = best_dispc;
656
657 return 0;
658}
659
660void dss_set_venc_output(enum omap_dss_venc_type type) 589void dss_set_venc_output(enum omap_dss_venc_type type)
661{ 590{
662 int l = 0; 591 int l = 0;
@@ -767,13 +696,11 @@ int dss_dpi_select_source(enum omap_channel channel)
767static int dss_get_clocks(void) 696static int dss_get_clocks(void)
768{ 697{
769 struct clk *clk; 698 struct clk *clk;
770 int r;
771 699
772 clk = clk_get(&dss.pdev->dev, "fck"); 700 clk = devm_clk_get(&dss.pdev->dev, "fck");
773 if (IS_ERR(clk)) { 701 if (IS_ERR(clk)) {
774 DSSERR("can't get clock fck\n"); 702 DSSERR("can't get clock fck\n");
775 r = PTR_ERR(clk); 703 return PTR_ERR(clk);
776 goto err;
777 } 704 }
778 705
779 dss.dss_clk = clk; 706 dss.dss_clk = clk;
@@ -782,8 +709,7 @@ static int dss_get_clocks(void)
782 clk = clk_get(NULL, dss.feat->clk_name); 709 clk = clk_get(NULL, dss.feat->clk_name);
783 if (IS_ERR(clk)) { 710 if (IS_ERR(clk)) {
784 DSSERR("Failed to get %s\n", dss.feat->clk_name); 711 DSSERR("Failed to get %s\n", dss.feat->clk_name);
785 r = PTR_ERR(clk); 712 return PTR_ERR(clk);
786 goto err;
787 } 713 }
788 } else { 714 } else {
789 clk = NULL; 715 clk = NULL;
@@ -792,21 +718,12 @@ static int dss_get_clocks(void)
792 dss.dpll4_m4_ck = clk; 718 dss.dpll4_m4_ck = clk;
793 719
794 return 0; 720 return 0;
795
796err:
797 if (dss.dss_clk)
798 clk_put(dss.dss_clk);
799 if (dss.dpll4_m4_ck)
800 clk_put(dss.dpll4_m4_ck);
801
802 return r;
803} 721}
804 722
805static void dss_put_clocks(void) 723static void dss_put_clocks(void)
806{ 724{
807 if (dss.dpll4_m4_ck) 725 if (dss.dpll4_m4_ck)
808 clk_put(dss.dpll4_m4_ck); 726 clk_put(dss.dpll4_m4_ck);
809 clk_put(dss.dss_clk);
810} 727}
811 728
812static int dss_runtime_get(void) 729static int dss_runtime_get(void)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 610c8e563daa..faaf35857b0e 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -268,8 +268,9 @@ void dss_set_dac_pwrdn_bgz(bool enable);
268unsigned long dss_get_dpll4_rate(void); 268unsigned long dss_get_dpll4_rate(void);
269int dss_calc_clock_rates(struct dss_clock_info *cinfo); 269int dss_calc_clock_rates(struct dss_clock_info *cinfo);
270int dss_set_clock_div(struct dss_clock_info *cinfo); 270int dss_set_clock_div(struct dss_clock_info *cinfo);
271int dss_calc_clock_div(unsigned long req_pck, struct dss_clock_info *dss_cinfo, 271
272 struct dispc_clock_info *dispc_cinfo); 272typedef bool (*dss_div_calc_func)(int fckd, unsigned long fck, void *data);
273bool dss_div_calc(unsigned long fck_min, dss_div_calc_func func, void *data);
273 274
274/* SDI */ 275/* SDI */
275int sdi_init_platform_driver(void) __init; 276int sdi_init_platform_driver(void) __init;
@@ -292,12 +293,21 @@ void dsi_dump_clocks(struct seq_file *s);
292void dsi_irq_handler(void); 293void dsi_irq_handler(void);
293u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt); 294u8 dsi_get_pixel_size(enum omap_dss_dsi_pixel_format fmt);
294 295
296unsigned long dsi_get_pll_clkin(struct platform_device *dsidev);
297
298typedef bool (*dsi_pll_calc_func)(int regn, int regm, unsigned long fint,
299 unsigned long pll, void *data);
300typedef bool (*dsi_hsdiv_calc_func)(int regm_dispc, unsigned long dispc,
301 void *data);
302bool dsi_hsdiv_calc(struct platform_device *dsidev, unsigned long pll,
303 unsigned long out_min, dsi_hsdiv_calc_func func, void *data);
304bool dsi_pll_calc(struct platform_device *dsidev, unsigned long clkin,
305 unsigned long pll_min, unsigned long pll_max,
306 dsi_pll_calc_func func, void *data);
307
295unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev); 308unsigned long dsi_get_pll_hsdiv_dispc_rate(struct platform_device *dsidev);
296int dsi_pll_set_clock_div(struct platform_device *dsidev, 309int dsi_pll_set_clock_div(struct platform_device *dsidev,
297 struct dsi_clock_info *cinfo); 310 struct dsi_clock_info *cinfo);
298int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
299 unsigned long req_pck, struct dsi_clock_info *cinfo,
300 struct dispc_clock_info *dispc_cinfo);
301int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, 311int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk,
302 bool enable_hsdiv); 312 bool enable_hsdiv);
303void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes); 313void dsi_pll_uninit(struct platform_device *dsidev, bool disconnect_lanes);
@@ -328,14 +338,6 @@ static inline int dsi_pll_set_clock_div(struct platform_device *dsidev,
328 WARN("%s: DSI not compiled in\n", __func__); 338 WARN("%s: DSI not compiled in\n", __func__);
329 return -ENODEV; 339 return -ENODEV;
330} 340}
331static inline int dsi_pll_calc_clock_div_pck(struct platform_device *dsidev,
332 unsigned long req_pck,
333 struct dsi_clock_info *dsi_cinfo,
334 struct dispc_clock_info *dispc_cinfo)
335{
336 WARN("%s: DSI not compiled in\n", __func__);
337 return -ENODEV;
338}
339static inline int dsi_pll_init(struct platform_device *dsidev, 341static inline int dsi_pll_init(struct platform_device *dsidev,
340 bool enable_hsclk, bool enable_hsdiv) 342 bool enable_hsclk, bool enable_hsdiv)
341{ 343{
@@ -376,11 +378,15 @@ void dispc_enable_fifomerge(bool enable);
376void dispc_enable_gamma_table(bool enable); 378void dispc_enable_gamma_table(bool enable);
377void dispc_set_loadmode(enum omap_dss_load_mode mode); 379void dispc_set_loadmode(enum omap_dss_load_mode mode);
378 380
381typedef bool (*dispc_div_calc_func)(int lckd, int pckd, unsigned long lck,
382 unsigned long pck, void *data);
383bool dispc_div_calc(unsigned long dispc,
384 unsigned long pck_min, unsigned long pck_max,
385 dispc_div_calc_func func, void *data);
386
379bool dispc_mgr_timings_ok(enum omap_channel channel, 387bool dispc_mgr_timings_ok(enum omap_channel channel,
380 const struct omap_video_timings *timings); 388 const struct omap_video_timings *timings);
381unsigned long dispc_fclk_rate(void); 389unsigned long dispc_fclk_rate(void);
382void dispc_find_clk_divs(unsigned long req_pck, unsigned long fck,
383 struct dispc_clock_info *cinfo);
384int dispc_calc_clock_rates(unsigned long dispc_fclk_rate, 390int dispc_calc_clock_rates(unsigned long dispc_fclk_rate,
385 struct dispc_clock_info *cinfo); 391 struct dispc_clock_info *cinfo);
386 392
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 7f791aeda4d2..77dbe0cfb34c 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -414,7 +414,7 @@ static const char * const omap5_dss_clk_source_names[] = {
414}; 414};
415 415
416static const struct dss_param_range omap2_dss_param_range[] = { 416static const struct dss_param_range omap2_dss_param_range[] = {
417 [FEAT_PARAM_DSS_FCK] = { 0, 173000000 }, 417 [FEAT_PARAM_DSS_FCK] = { 0, 133000000 },
418 [FEAT_PARAM_DSS_PCD] = { 2, 255 }, 418 [FEAT_PARAM_DSS_PCD] = { 2, 255 },
419 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 }, 419 [FEAT_PARAM_DSIPLL_REGN] = { 0, 0 },
420 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 }, 420 [FEAT_PARAM_DSIPLL_REGM] = { 0, 0 },
@@ -459,15 +459,15 @@ static const struct dss_param_range omap4_dss_param_range[] = {
459}; 459};
460 460
461static const struct dss_param_range omap5_dss_param_range[] = { 461static const struct dss_param_range omap5_dss_param_range[] = {
462 [FEAT_PARAM_DSS_FCK] = { 0, 200000000 }, 462 [FEAT_PARAM_DSS_FCK] = { 0, 209250000 },
463 [FEAT_PARAM_DSS_PCD] = { 1, 255 }, 463 [FEAT_PARAM_DSS_PCD] = { 1, 255 },
464 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 }, 464 [FEAT_PARAM_DSIPLL_REGN] = { 0, (1 << 8) - 1 },
465 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 }, 465 [FEAT_PARAM_DSIPLL_REGM] = { 0, (1 << 12) - 1 },
466 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 }, 466 [FEAT_PARAM_DSIPLL_REGM_DISPC] = { 0, (1 << 5) - 1 },
467 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 }, 467 [FEAT_PARAM_DSIPLL_REGM_DSI] = { 0, (1 << 5) - 1 },
468 [FEAT_PARAM_DSIPLL_FINT] = { 500000, 2500000 }, 468 [FEAT_PARAM_DSIPLL_FINT] = { 150000, 52000000 },
469 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 }, 469 [FEAT_PARAM_DSIPLL_LPDIV] = { 0, (1 << 13) - 1 },
470 [FEAT_PARAM_DSI_FCK] = { 0, 170000000 }, 470 [FEAT_PARAM_DSI_FCK] = { 0, 209250000 },
471 [FEAT_PARAM_DOWNSCALE] = { 1, 4 }, 471 [FEAT_PARAM_DOWNSCALE] = { 1, 4 },
472 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 }, 472 [FEAT_PARAM_LINEWIDTH] = { 1, 2048 },
473}; 473};
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 72923645dcce..79393099d505 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -472,17 +472,12 @@ static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
472 * Input clock is predivided by N + 1 472 * Input clock is predivided by N + 1
473 * out put of which is reference clk 473 * out put of which is reference clk
474 */ 474 */
475 if (dssdev->clocks.hdmi.regn == 0) 475
476 pi->regn = HDMI_DEFAULT_REGN; 476 pi->regn = HDMI_DEFAULT_REGN;
477 else
478 pi->regn = dssdev->clocks.hdmi.regn;
479 477
480 refclk = clkin / pi->regn; 478 refclk = clkin / pi->regn;
481 479
482 if (dssdev->clocks.hdmi.regm2 == 0) 480 pi->regm2 = HDMI_DEFAULT_REGM2;
483 pi->regm2 = HDMI_DEFAULT_REGM2;
484 else
485 pi->regm2 = dssdev->clocks.hdmi.regm2;
486 481
487 /* 482 /*
488 * multiplier is pixel_clk/ref_clk 483 * multiplier is pixel_clk/ref_clk
@@ -804,7 +799,7 @@ static int hdmi_get_clocks(struct platform_device *pdev)
804{ 799{
805 struct clk *clk; 800 struct clk *clk;
806 801
807 clk = clk_get(&pdev->dev, "sys_clk"); 802 clk = devm_clk_get(&pdev->dev, "sys_clk");
808 if (IS_ERR(clk)) { 803 if (IS_ERR(clk)) {
809 DSSERR("can't get sys_clk\n"); 804 DSSERR("can't get sys_clk\n");
810 return PTR_ERR(clk); 805 return PTR_ERR(clk);
@@ -815,12 +810,6 @@ static int hdmi_get_clocks(struct platform_device *pdev)
815 return 0; 810 return 0;
816} 811}
817 812
818static void hdmi_put_clocks(void)
819{
820 if (hdmi.sys_clk)
821 clk_put(hdmi.sys_clk);
822}
823
824#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO) 813#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
825int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts) 814int hdmi_compute_acr(u32 sample_freq, u32 *n, u32 *cts)
826{ 815{
@@ -1017,8 +1006,6 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
1017 hdmi.ls_oe_gpio = priv->ls_oe_gpio; 1006 hdmi.ls_oe_gpio = priv->ls_oe_gpio;
1018 hdmi.hpd_gpio = priv->hpd_gpio; 1007 hdmi.hpd_gpio = priv->hpd_gpio;
1019 1008
1020 dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
1021
1022 r = hdmi_init_display(dssdev); 1009 r = hdmi_init_display(dssdev);
1023 if (r) { 1010 if (r) {
1024 DSSERR("device %s init failed: %d\n", dssdev->name, r); 1011 DSSERR("device %s init failed: %d\n", dssdev->name, r);
@@ -1051,6 +1038,8 @@ static void __init hdmi_init_output(struct platform_device *pdev)
1051 out->pdev = pdev; 1038 out->pdev = pdev;
1052 out->id = OMAP_DSS_OUTPUT_HDMI; 1039 out->id = OMAP_DSS_OUTPUT_HDMI;
1053 out->type = OMAP_DISPLAY_TYPE_HDMI; 1040 out->type = OMAP_DISPLAY_TYPE_HDMI;
1041 out->name = "hdmi.0";
1042 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
1054 1043
1055 dss_register_output(out); 1044 dss_register_output(out);
1056} 1045}
@@ -1097,23 +1086,19 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
1097 hdmi.ip_data.pll_offset = HDMI_PLLCTRL; 1086 hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
1098 hdmi.ip_data.phy_offset = HDMI_PHY; 1087 hdmi.ip_data.phy_offset = HDMI_PHY;
1099 1088
1089 hdmi_init_output(pdev);
1090
1100 r = hdmi_panel_init(); 1091 r = hdmi_panel_init();
1101 if (r) { 1092 if (r) {
1102 DSSERR("can't init panel\n"); 1093 DSSERR("can't init panel\n");
1103 goto err_panel_init; 1094 return r;
1104 } 1095 }
1105 1096
1106 dss_debugfs_create_file("hdmi", hdmi_dump_regs); 1097 dss_debugfs_create_file("hdmi", hdmi_dump_regs);
1107 1098
1108 hdmi_init_output(pdev);
1109
1110 hdmi_probe_pdata(pdev); 1099 hdmi_probe_pdata(pdev);
1111 1100
1112 return 0; 1101 return 0;
1113
1114err_panel_init:
1115 hdmi_put_clocks();
1116 return r;
1117} 1102}
1118 1103
1119static int __exit hdmi_remove_child(struct device *dev, void *data) 1104static int __exit hdmi_remove_child(struct device *dev, void *data)
@@ -1135,8 +1120,6 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
1135 1120
1136 pm_runtime_disable(&pdev->dev); 1121 pm_runtime_disable(&pdev->dev);
1137 1122
1138 hdmi_put_clocks();
1139
1140 return 0; 1123 return 0;
1141} 1124}
1142 1125
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 79dea1a1a732..5214df63e0a9 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -113,6 +113,7 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
113 113
114 return NULL; 114 return NULL;
115} 115}
116EXPORT_SYMBOL(omap_dss_get_output);
116 117
117static const struct dss_mgr_ops *dss_mgr_ops; 118static const struct dss_mgr_ops *dss_mgr_ops;
118 119
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index e903dd3f54d9..1a691bb27547 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -1025,6 +1025,8 @@ static void __init rfbi_init_output(struct platform_device *pdev)
1025 out->pdev = pdev; 1025 out->pdev = pdev;
1026 out->id = OMAP_DSS_OUTPUT_DBI; 1026 out->id = OMAP_DSS_OUTPUT_DBI;
1027 out->type = OMAP_DISPLAY_TYPE_DBI; 1027 out->type = OMAP_DISPLAY_TYPE_DBI;
1028 out->name = "rfbi.0";
1029 out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
1028 1030
1029 dss_register_output(out); 1031 dss_register_output(out);
1030} 1032}
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
index 62b5374ce438..e6baee2e84f8 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/omap2/dss/sdi.c
@@ -41,6 +41,72 @@ static struct {
41 struct omap_dss_output output; 41 struct omap_dss_output output;
42} sdi; 42} sdi;
43 43
44struct sdi_clk_calc_ctx {
45 unsigned long pck_min, pck_max;
46
47 struct dss_clock_info dss_cinfo;
48 struct dispc_clock_info dispc_cinfo;
49};
50
51static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
52 unsigned long pck, void *data)
53{
54 struct sdi_clk_calc_ctx *ctx = data;
55
56 ctx->dispc_cinfo.lck_div = lckd;
57 ctx->dispc_cinfo.pck_div = pckd;
58 ctx->dispc_cinfo.lck = lck;
59 ctx->dispc_cinfo.pck = pck;
60
61 return true;
62}
63
64static bool dpi_calc_dss_cb(int fckd, unsigned long fck, void *data)
65{
66 struct sdi_clk_calc_ctx *ctx = data;
67
68 ctx->dss_cinfo.fck = fck;
69 ctx->dss_cinfo.fck_div = fckd;
70
71 return dispc_div_calc(fck, ctx->pck_min, ctx->pck_max,
72 dpi_calc_dispc_cb, ctx);
73}
74
75static int sdi_calc_clock_div(unsigned long pclk,
76 struct dss_clock_info *dss_cinfo,
77 struct dispc_clock_info *dispc_cinfo)
78{
79 int i;
80 struct sdi_clk_calc_ctx ctx;
81
82 /*
83 * DSS fclk gives us very few possibilities, so finding a good pixel
84 * clock may not be possible. We try multiple times to find the clock,
85 * each time widening the pixel clock range we look for, up to
86 * +/- 1MHz.
87 */
88
89 for (i = 0; i < 10; ++i) {
90 bool ok;
91
92 memset(&ctx, 0, sizeof(ctx));
93 if (pclk > 1000 * i * i * i)
94 ctx.pck_min = max(pclk - 1000 * i * i * i, 0lu);
95 else
96 ctx.pck_min = 0;
97 ctx.pck_max = pclk + 1000 * i * i * i;
98
99 ok = dss_div_calc(ctx.pck_min, dpi_calc_dss_cb, &ctx);
100 if (ok) {
101 *dss_cinfo = ctx.dss_cinfo;
102 *dispc_cinfo = ctx.dispc_cinfo;
103 return 0;
104 }
105 }
106
107 return -EINVAL;
108}
109
44static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) 110static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
45{ 111{
46 struct omap_overlay_manager *mgr = dssdev->output->manager; 112 struct omap_overlay_manager *mgr = dssdev->output->manager;
@@ -88,7 +154,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
88 t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 154 t->data_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
89 t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE; 155 t->sync_pclk_edge = OMAPDSS_DRIVE_SIG_RISING_EDGE;
90 156
91 r = dss_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo); 157 r = sdi_calc_clock_div(t->pixel_clock * 1000, &dss_cinfo, &dispc_cinfo);
92 if (r) 158 if (r)
93 goto err_calc_clock_div; 159 goto err_calc_clock_div;
94 160
@@ -278,6 +344,8 @@ static void __init sdi_init_output(struct platform_device *pdev)
278 out->pdev = pdev; 344 out->pdev = pdev;
279 out->id = OMAP_DSS_OUTPUT_SDI; 345 out->id = OMAP_DSS_OUTPUT_SDI;
280 out->type = OMAP_DISPLAY_TYPE_SDI; 346 out->type = OMAP_DISPLAY_TYPE_SDI;
347 out->name = "sdi.0";
348 out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
281 349
282 dss_register_output(out); 350 dss_register_output(out);
283} 351}
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 006caf3cb509..17764d136398 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -519,10 +519,6 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
519 goto err0; 519 goto err0;
520 } 520 }
521 521
522 if (dssdev->platform_enable)
523 dssdev->platform_enable(dssdev);
524
525
526 r = venc_power_on(dssdev); 522 r = venc_power_on(dssdev);
527 if (r) 523 if (r)
528 goto err1; 524 goto err1;
@@ -533,8 +529,6 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
533 529
534 return 0; 530 return 0;
535err1: 531err1:
536 if (dssdev->platform_disable)
537 dssdev->platform_disable(dssdev);
538 omap_dss_stop_device(dssdev); 532 omap_dss_stop_device(dssdev);
539err0: 533err0:
540 mutex_unlock(&venc.venc_lock); 534 mutex_unlock(&venc.venc_lock);
@@ -551,9 +545,6 @@ void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
551 545
552 omap_dss_stop_device(dssdev); 546 omap_dss_stop_device(dssdev);
553 547
554 if (dssdev->platform_disable)
555 dssdev->platform_disable(dssdev);
556
557 mutex_unlock(&venc.venc_lock); 548 mutex_unlock(&venc.venc_lock);
558} 549}
559 550
@@ -721,7 +712,7 @@ static int venc_get_clocks(struct platform_device *pdev)
721 struct clk *clk; 712 struct clk *clk;
722 713
723 if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) { 714 if (dss_has_feature(FEAT_VENC_REQUIRES_TV_DAC_CLK)) {
724 clk = clk_get(&pdev->dev, "tv_dac_clk"); 715 clk = devm_clk_get(&pdev->dev, "tv_dac_clk");
725 if (IS_ERR(clk)) { 716 if (IS_ERR(clk)) {
726 DSSERR("can't get tv_dac_clk\n"); 717 DSSERR("can't get tv_dac_clk\n");
727 return PTR_ERR(clk); 718 return PTR_ERR(clk);
@@ -735,12 +726,6 @@ static int venc_get_clocks(struct platform_device *pdev)
735 return 0; 726 return 0;
736} 727}
737 728
738static void venc_put_clocks(void)
739{
740 if (venc.tv_dac_clk)
741 clk_put(venc.tv_dac_clk);
742}
743
744static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev) 729static struct omap_dss_device * __init venc_find_dssdev(struct platform_device *pdev)
745{ 730{
746 struct omap_dss_board_info *pdata = pdev->dev.platform_data; 731 struct omap_dss_board_info *pdata = pdev->dev.platform_data;
@@ -786,8 +771,6 @@ static void __init venc_probe_pdata(struct platform_device *vencdev)
786 771
787 dss_copy_device_pdata(dssdev, plat_dssdev); 772 dss_copy_device_pdata(dssdev, plat_dssdev);
788 773
789 dssdev->channel = OMAP_DSS_CHANNEL_DIGIT;
790
791 r = venc_init_display(dssdev); 774 r = venc_init_display(dssdev);
792 if (r) { 775 if (r) {
793 DSSERR("device %s init failed: %d\n", dssdev->name, r); 776 DSSERR("device %s init failed: %d\n", dssdev->name, r);
@@ -819,6 +802,8 @@ static void __init venc_init_output(struct platform_device *pdev)
819 out->pdev = pdev; 802 out->pdev = pdev;
820 out->id = OMAP_DSS_OUTPUT_VENC; 803 out->id = OMAP_DSS_OUTPUT_VENC;
821 out->type = OMAP_DISPLAY_TYPE_VENC; 804 out->type = OMAP_DISPLAY_TYPE_VENC;
805 out->name = "venc.0";
806 out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
822 807
823 dss_register_output(out); 808 dss_register_output(out);
824} 809}
@@ -886,7 +871,6 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
886err_panel_init: 871err_panel_init:
887err_runtime_get: 872err_runtime_get:
888 pm_runtime_disable(&pdev->dev); 873 pm_runtime_disable(&pdev->dev);
889 venc_put_clocks();
890 return r; 874 return r;
891} 875}
892 876
@@ -904,7 +888,6 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
904 venc_uninit_output(pdev); 888 venc_uninit_output(pdev);
905 889
906 pm_runtime_disable(&pdev->dev); 890 pm_runtime_disable(&pdev->dev);
907 venc_put_clocks();
908 891
909 return 0; 892 return 0;
910} 893}
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index ca585ef37f25..f38348ea3375 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2388,7 +2388,7 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev,
2388 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; 2388 struct omap_dss_device *dssdev = fbdev->displays[i].dssdev;
2389 struct omap_dss_output *out = dssdev->output; 2389 struct omap_dss_output *out = dssdev->output;
2390 2390
2391 mgr = omap_dss_get_overlay_manager(dssdev->channel); 2391 mgr = omap_dss_get_overlay_manager(out->dispc_channel);
2392 2392
2393 if (!mgr || !out) 2393 if (!mgr || !out)
2394 continue; 2394 continue;