hc
2024-05-10 9999e48639b3cecb08ffb37358bcba3b48161b29
kernel/drivers/gpu/drm/omapdrm/omap_crtc.c
....@@ -1,27 +1,17 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) 2011 Texas Instruments Incorporated - http://www.ti.com/
34 * Author: Rob Clark <rob@ti.com>
4
- *
5
- * This program is free software; you can redistribute it and/or modify it
6
- * under the terms of the GNU General Public License version 2 as published by
7
- * the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope that it will be useful, but WITHOUT
10
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
- * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12
- * more details.
13
- *
14
- * You should have received a copy of the GNU General Public License along with
15
- * this program. If not, see <http://www.gnu.org/licenses/>.
165 */
6
+
7
+#include <linux/math64.h>
178
189 #include <drm/drm_atomic.h>
1910 #include <drm/drm_atomic_helper.h>
2011 #include <drm/drm_crtc.h>
21
-#include <drm/drm_crtc_helper.h>
2212 #include <drm/drm_mode.h>
2313 #include <drm/drm_plane_helper.h>
24
-#include <linux/math64.h>
14
+#include <drm/drm_vblank.h>
2515
2616 #include "omap_drv.h"
2717
....@@ -33,6 +23,7 @@
3323 /* Shadow values for legacy userspace support. */
3424 unsigned int rotation;
3525 unsigned int zpos;
26
+ bool manually_updated;
3627 };
3728
3829 #define to_omap_crtc(x) container_of(x, struct omap_crtc, base)
....@@ -41,6 +32,7 @@
4132 struct drm_crtc base;
4233
4334 const char *name;
35
+ struct omap_drm_pipeline *pipe;
4436 enum omap_channel channel;
4537
4638 struct videomode vm;
....@@ -51,6 +43,10 @@
5143 bool pending;
5244 wait_queue_head_t pending_wait;
5345 struct drm_pending_vblank_event *event;
46
+ struct delayed_work update_work;
47
+
48
+ void (*framedone_handler)(void *);
49
+ void *framedone_handler_data;
5450 };
5551
5652 /* -----------------------------------------------------------------------------
....@@ -102,52 +98,18 @@
10298 /*
10399 * Manager-ops, callbacks from output when they need to configure
104100 * the upstream part of the video pipe.
105
- *
106
- * Most of these we can ignore until we add support for command-mode
107
- * panels.. for video-mode the crtc-helpers already do an adequate
108
- * job of sequencing the setup of the video pipe in the proper order
109101 */
110
-
111
-/* ovl-mgr-id -> crtc */
112
-static struct omap_crtc *omap_crtcs[8];
113
-static struct omap_dss_device *omap_crtc_output[8];
114
-
115
-/* we can probably ignore these until we support command-mode panels: */
116
-static int omap_crtc_dss_connect(struct omap_drm_private *priv,
117
- enum omap_channel channel,
118
- struct omap_dss_device *dst)
119
-{
120
- const struct dispc_ops *dispc_ops = priv->dispc_ops;
121
- struct dispc_device *dispc = priv->dispc;
122
-
123
- if (omap_crtc_output[channel])
124
- return -EINVAL;
125
-
126
- if (!(dispc_ops->mgr_get_supported_outputs(dispc, channel) & dst->id))
127
- return -EINVAL;
128
-
129
- omap_crtc_output[channel] = dst;
130
- dst->dispc_channel_connected = true;
131
-
132
- return 0;
133
-}
134
-
135
-static void omap_crtc_dss_disconnect(struct omap_drm_private *priv,
136
- enum omap_channel channel,
137
- struct omap_dss_device *dst)
138
-{
139
- omap_crtc_output[channel] = NULL;
140
- dst->dispc_channel_connected = false;
141
-}
142102
143103 static void omap_crtc_dss_start_update(struct omap_drm_private *priv,
144104 enum omap_channel channel)
145105 {
106
+ priv->dispc_ops->mgr_enable(priv->dispc, channel, true);
146107 }
147108
148109 /* Called only from the encoder enable/disable and suspend/resume handlers. */
149110 static void omap_crtc_set_enabled(struct drm_crtc *crtc, bool enable)
150111 {
112
+ struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
151113 struct drm_device *dev = crtc->dev;
152114 struct omap_drm_private *priv = dev->dev_private;
153115 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
....@@ -159,7 +121,13 @@
159121 if (WARN_ON(omap_crtc->enabled == enable))
160122 return;
161123
162
- if (omap_crtc_output[channel]->output_type == OMAP_DISPLAY_TYPE_HDMI) {
124
+ if (omap_state->manually_updated) {
125
+ omap_irq_enable_framedone(crtc, enable);
126
+ omap_crtc->enabled = enable;
127
+ return;
128
+ }
129
+
130
+ if (omap_crtc->pipe->output->type == OMAP_DISPLAY_TYPE_HDMI) {
163131 priv->dispc_ops->mgr_enable(priv->dispc, channel, enable);
164132 omap_crtc->enabled = enable;
165133 return;
....@@ -215,7 +183,8 @@
215183 static int omap_crtc_dss_enable(struct omap_drm_private *priv,
216184 enum omap_channel channel)
217185 {
218
- struct omap_crtc *omap_crtc = omap_crtcs[channel];
186
+ struct drm_crtc *crtc = priv->channels[channel]->crtc;
187
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
219188
220189 priv->dispc_ops->mgr_set_timings(priv->dispc, omap_crtc->channel,
221190 &omap_crtc->vm);
....@@ -227,7 +196,8 @@
227196 static void omap_crtc_dss_disable(struct omap_drm_private *priv,
228197 enum omap_channel channel)
229198 {
230
- struct omap_crtc *omap_crtc = omap_crtcs[channel];
199
+ struct drm_crtc *crtc = priv->channels[channel]->crtc;
200
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
231201
232202 omap_crtc_set_enabled(&omap_crtc->base, false);
233203 }
....@@ -236,7 +206,9 @@
236206 enum omap_channel channel,
237207 const struct videomode *vm)
238208 {
239
- struct omap_crtc *omap_crtc = omap_crtcs[channel];
209
+ struct drm_crtc *crtc = priv->channels[channel]->crtc;
210
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
211
+
240212 DBG("%s", omap_crtc->name);
241213 omap_crtc->vm = *vm;
242214 }
....@@ -245,7 +217,8 @@
245217 enum omap_channel channel,
246218 const struct dss_lcd_mgr_config *config)
247219 {
248
- struct omap_crtc *omap_crtc = omap_crtcs[channel];
220
+ struct drm_crtc *crtc = priv->channels[channel]->crtc;
221
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
249222
250223 DBG("%s", omap_crtc->name);
251224 priv->dispc_ops->mgr_set_lcd_config(priv->dispc, omap_crtc->channel,
....@@ -256,6 +229,18 @@
256229 struct omap_drm_private *priv, enum omap_channel channel,
257230 void (*handler)(void *), void *data)
258231 {
232
+ struct drm_crtc *crtc = priv->channels[channel]->crtc;
233
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
234
+ struct drm_device *dev = omap_crtc->base.dev;
235
+
236
+ if (omap_crtc->framedone_handler)
237
+ return -EBUSY;
238
+
239
+ dev_dbg(dev->dev, "register framedone %s", omap_crtc->name);
240
+
241
+ omap_crtc->framedone_handler = handler;
242
+ omap_crtc->framedone_handler_data = data;
243
+
259244 return 0;
260245 }
261246
....@@ -263,11 +248,20 @@
263248 struct omap_drm_private *priv, enum omap_channel channel,
264249 void (*handler)(void *), void *data)
265250 {
251
+ struct drm_crtc *crtc = priv->channels[channel]->crtc;
252
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
253
+ struct drm_device *dev = omap_crtc->base.dev;
254
+
255
+ dev_dbg(dev->dev, "unregister framedone %s", omap_crtc->name);
256
+
257
+ WARN_ON(omap_crtc->framedone_handler != handler);
258
+ WARN_ON(omap_crtc->framedone_handler_data != data);
259
+
260
+ omap_crtc->framedone_handler = NULL;
261
+ omap_crtc->framedone_handler_data = NULL;
266262 }
267263
268264 static const struct dss_mgr_ops mgr_ops = {
269
- .connect = omap_crtc_dss_connect,
270
- .disconnect = omap_crtc_dss_disconnect,
271265 .start_update = omap_crtc_dss_start_update,
272266 .enable = omap_crtc_dss_enable,
273267 .disable = omap_crtc_dss_disable,
....@@ -330,6 +324,73 @@
330324 DBG("%s: apply done", omap_crtc->name);
331325 }
332326
327
+void omap_crtc_framedone_irq(struct drm_crtc *crtc, uint32_t irqstatus)
328
+{
329
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
330
+
331
+ if (!omap_crtc->framedone_handler)
332
+ return;
333
+
334
+ omap_crtc->framedone_handler(omap_crtc->framedone_handler_data);
335
+
336
+ spin_lock(&crtc->dev->event_lock);
337
+ /* Send the vblank event if one has been requested. */
338
+ if (omap_crtc->event) {
339
+ drm_crtc_send_vblank_event(crtc, omap_crtc->event);
340
+ omap_crtc->event = NULL;
341
+ }
342
+ omap_crtc->pending = false;
343
+ spin_unlock(&crtc->dev->event_lock);
344
+
345
+ /* Wake up omap_atomic_complete. */
346
+ wake_up(&omap_crtc->pending_wait);
347
+}
348
+
349
+void omap_crtc_flush(struct drm_crtc *crtc)
350
+{
351
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
352
+ struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
353
+
354
+ if (!omap_state->manually_updated)
355
+ return;
356
+
357
+ if (!delayed_work_pending(&omap_crtc->update_work))
358
+ schedule_delayed_work(&omap_crtc->update_work, 0);
359
+}
360
+
361
+static void omap_crtc_manual_display_update(struct work_struct *data)
362
+{
363
+ struct omap_crtc *omap_crtc =
364
+ container_of(data, struct omap_crtc, update_work.work);
365
+ struct drm_display_mode *mode = &omap_crtc->pipe->crtc->mode;
366
+ struct omap_dss_device *dssdev = omap_crtc->pipe->output->next;
367
+ struct drm_device *dev = omap_crtc->base.dev;
368
+ const struct omap_dss_driver *dssdrv;
369
+ int ret;
370
+
371
+ if (!dssdev) {
372
+ dev_err_once(dev->dev, "missing display dssdev!");
373
+ return;
374
+ }
375
+
376
+ dssdrv = dssdev->driver;
377
+ if (!dssdrv || !dssdrv->update) {
378
+ dev_err_once(dev->dev, "missing or incorrect dssdrv!");
379
+ return;
380
+ }
381
+
382
+ if (dssdrv->sync)
383
+ dssdrv->sync(dssdev);
384
+
385
+ ret = dssdrv->update(dssdev, 0, 0, mode->hdisplay, mode->vdisplay);
386
+ if (ret < 0) {
387
+ spin_lock_irq(&dev->event_lock);
388
+ omap_crtc->pending = false;
389
+ spin_unlock_irq(&dev->event_lock);
390
+ wake_up(&omap_crtc->pending_wait);
391
+ }
392
+}
393
+
333394 static void omap_crtc_write_crtc_properties(struct drm_crtc *crtc)
334395 {
335396 struct omap_drm_private *priv = crtc->dev->dev_private;
....@@ -377,16 +438,25 @@
377438 static void omap_crtc_atomic_enable(struct drm_crtc *crtc,
378439 struct drm_crtc_state *old_state)
379440 {
441
+ struct omap_drm_private *priv = crtc->dev->dev_private;
380442 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
443
+ struct omap_crtc_state *omap_state = to_omap_crtc_state(crtc->state);
381444 int ret;
382445
383446 DBG("%s", omap_crtc->name);
384447
385
- spin_lock_irq(&crtc->dev->event_lock);
448
+ priv->dispc_ops->runtime_get(priv->dispc);
449
+
450
+ /* manual updated display will not trigger vsync irq */
451
+ if (omap_state->manually_updated)
452
+ return;
453
+
386454 drm_crtc_vblank_on(crtc);
455
+
387456 ret = drm_crtc_vblank_get(crtc);
388457 WARN_ON(ret != 0);
389458
459
+ spin_lock_irq(&crtc->dev->event_lock);
390460 omap_crtc_arm_event(crtc);
391461 spin_unlock_irq(&crtc->dev->event_lock);
392462 }
....@@ -394,7 +464,9 @@
394464 static void omap_crtc_atomic_disable(struct drm_crtc *crtc,
395465 struct drm_crtc_state *old_state)
396466 {
467
+ struct omap_drm_private *priv = crtc->dev->dev_private;
397468 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
469
+ struct drm_device *dev = crtc->dev;
398470
399471 DBG("%s", omap_crtc->name);
400472
....@@ -405,13 +477,39 @@
405477 }
406478 spin_unlock_irq(&crtc->dev->event_lock);
407479
480
+ cancel_delayed_work(&omap_crtc->update_work);
481
+
482
+ if (!omap_crtc_wait_pending(crtc))
483
+ dev_warn(dev->dev, "manual display update did not finish!");
484
+
408485 drm_crtc_vblank_off(crtc);
486
+
487
+ priv->dispc_ops->runtime_put(priv->dispc);
409488 }
410489
411490 static enum drm_mode_status omap_crtc_mode_valid(struct drm_crtc *crtc,
412491 const struct drm_display_mode *mode)
413492 {
414493 struct omap_drm_private *priv = crtc->dev->dev_private;
494
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
495
+ struct videomode vm = {0};
496
+ int r;
497
+
498
+ drm_display_mode_to_videomode(mode, &vm);
499
+
500
+ /*
501
+ * DSI might not call this, since the supplied mode is not a
502
+ * valid DISPC mode. DSI will calculate and configure the
503
+ * proper DISPC mode later.
504
+ */
505
+ if (omap_crtc->pipe->output->next == NULL ||
506
+ omap_crtc->pipe->output->next->type != OMAP_DISPLAY_TYPE_DSI) {
507
+ r = priv->dispc_ops->mgr_check_timings(priv->dispc,
508
+ omap_crtc->channel,
509
+ &vm);
510
+ if (r)
511
+ return r;
512
+ }
415513
416514 /* Check for bandwidth limit */
417515 if (priv->max_bandwidth) {
....@@ -447,52 +545,27 @@
447545 {
448546 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
449547 struct drm_display_mode *mode = &crtc->state->adjusted_mode;
450
- struct omap_drm_private *priv = crtc->dev->dev_private;
451
- const u32 flags_mask = DISPLAY_FLAGS_DE_HIGH | DISPLAY_FLAGS_DE_LOW |
452
- DISPLAY_FLAGS_PIXDATA_POSEDGE | DISPLAY_FLAGS_PIXDATA_NEGEDGE |
453
- DISPLAY_FLAGS_SYNC_POSEDGE | DISPLAY_FLAGS_SYNC_NEGEDGE;
454
- unsigned int i;
455548
456
- DBG("%s: set mode: %d:\"%s\" %d %d %d %d %d %d %d %d %d %d 0x%x 0x%x",
457
- omap_crtc->name, mode->base.id, mode->name,
458
- mode->vrefresh, mode->clock,
459
- mode->hdisplay, mode->hsync_start, mode->hsync_end, mode->htotal,
460
- mode->vdisplay, mode->vsync_start, mode->vsync_end, mode->vtotal,
461
- mode->type, mode->flags);
549
+ DBG("%s: set mode: " DRM_MODE_FMT,
550
+ omap_crtc->name, DRM_MODE_ARG(mode));
462551
463552 drm_display_mode_to_videomode(mode, &omap_crtc->vm);
553
+}
464554
465
- /*
466
- * HACK: This fixes the vm flags.
467
- * struct drm_display_mode does not contain the VSYNC/HSYNC/DE flags
468
- * and they get lost when converting back and forth between
469
- * struct drm_display_mode and struct videomode. The hack below
470
- * goes and fetches the missing flags from the panel drivers.
471
- *
472
- * Correct solution would be to use DRM's bus-flags, but that's not
473
- * easily possible before the omapdrm's panel/encoder driver model
474
- * has been changed to the DRM model.
475
- */
555
+static bool omap_crtc_is_manually_updated(struct drm_crtc *crtc)
556
+{
557
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
558
+ struct omap_dss_device *display = omap_crtc->pipe->output->next;
476559
477
- for (i = 0; i < priv->num_encoders; ++i) {
478
- struct drm_encoder *encoder = priv->encoders[i];
560
+ if (!display)
561
+ return false;
479562
480
- if (encoder->crtc == crtc) {
481
- struct omap_dss_device *dssdev;
482
-
483
- dssdev = omap_encoder_get_dssdev(encoder);
484
-
485
- if (dssdev) {
486
- struct videomode vm = {0};
487
-
488
- dssdev->driver->get_timings(dssdev, &vm);
489
-
490
- omap_crtc->vm.flags |= vm.flags & flags_mask;
491
- }
492
-
493
- break;
494
- }
563
+ if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
564
+ DBG("detected manually updated display!");
565
+ return true;
495566 }
567
+
568
+ return false;
496569 }
497570
498571 static int omap_crtc_atomic_check(struct drm_crtc *crtc,
....@@ -516,6 +589,9 @@
516589 /* Mirror new values for zpos and rotation in omap_crtc_state */
517590 omap_crtc_state->zpos = pri_state->zpos;
518591 omap_crtc_state->rotation = pri_state->rotation;
592
+
593
+ /* Check if this CRTC is for a manually updated display */
594
+ omap_crtc_state->manually_updated = omap_crtc_is_manually_updated(crtc);
519595 }
520596
521597 return 0;
....@@ -531,6 +607,7 @@
531607 {
532608 struct omap_drm_private *priv = crtc->dev->dev_private;
533609 struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
610
+ struct omap_crtc_state *omap_crtc_state = to_omap_crtc_state(crtc->state);
534611 int ret;
535612
536613 if (crtc->state->color_mgmt_changed) {
....@@ -554,6 +631,15 @@
554631 return;
555632
556633 DBG("%s: GO", omap_crtc->name);
634
+
635
+ if (omap_crtc_state->manually_updated) {
636
+ /* send new image for page flips and modeset changes */
637
+ spin_lock_irq(&crtc->dev->event_lock);
638
+ omap_crtc_flush(crtc);
639
+ omap_crtc_arm_event(crtc);
640
+ spin_unlock_irq(&crtc->dev->event_lock);
641
+ return;
642
+ }
557643
558644 ret = drm_crtc_vblank_get(crtc);
559645 WARN_ON(ret != 0);
....@@ -612,14 +698,16 @@
612698
613699 static void omap_crtc_reset(struct drm_crtc *crtc)
614700 {
701
+ struct omap_crtc_state *state;
702
+
615703 if (crtc->state)
616704 __drm_atomic_helper_crtc_destroy_state(crtc->state);
617705
618706 kfree(crtc->state);
619
- crtc->state = kzalloc(sizeof(struct omap_crtc_state), GFP_KERNEL);
620707
621
- if (crtc->state)
622
- crtc->state->crtc = crtc;
708
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
709
+ if (state)
710
+ __drm_atomic_helper_crtc_reset(crtc, &state->base);
623711 }
624712
625713 static struct drm_crtc_state *
....@@ -640,6 +728,7 @@
640728
641729 state->zpos = current_state->zpos;
642730 state->rotation = current_state->rotation;
731
+ state->manually_updated = current_state->manually_updated;
643732
644733 return &state->base;
645734 }
....@@ -681,36 +770,28 @@
681770
682771 void omap_crtc_pre_init(struct omap_drm_private *priv)
683772 {
684
- memset(omap_crtcs, 0, sizeof(omap_crtcs));
685
-
686
- dss_install_mgr_ops(&mgr_ops, priv);
773
+ dss_install_mgr_ops(priv->dss, &mgr_ops, priv);
687774 }
688775
689
-void omap_crtc_pre_uninit(void)
776
+void omap_crtc_pre_uninit(struct omap_drm_private *priv)
690777 {
691
- dss_uninstall_mgr_ops();
778
+ dss_uninstall_mgr_ops(priv->dss);
692779 }
693780
694781 /* initialize crtc */
695782 struct drm_crtc *omap_crtc_init(struct drm_device *dev,
696
- struct drm_plane *plane, struct omap_dss_device *dssdev)
783
+ struct omap_drm_pipeline *pipe,
784
+ struct drm_plane *plane)
697785 {
698786 struct omap_drm_private *priv = dev->dev_private;
699787 struct drm_crtc *crtc = NULL;
700788 struct omap_crtc *omap_crtc;
701789 enum omap_channel channel;
702
- struct omap_dss_device *out;
703790 int ret;
704791
705
- out = omapdss_find_output_from_display(dssdev);
706
- channel = out->dispc_channel;
707
- omap_dss_put_device(out);
792
+ channel = pipe->output->dispc_channel;
708793
709794 DBG("%s", channel_names[channel]);
710
-
711
- /* Multiple displays on same channel is not allowed */
712
- if (WARN_ON(omap_crtcs[channel] != NULL))
713
- return ERR_PTR(-EINVAL);
714795
715796 omap_crtc = kzalloc(sizeof(*omap_crtc), GFP_KERNEL);
716797 if (!omap_crtc)
....@@ -720,14 +801,28 @@
720801
721802 init_waitqueue_head(&omap_crtc->pending_wait);
722803
804
+ omap_crtc->pipe = pipe;
723805 omap_crtc->channel = channel;
724806 omap_crtc->name = channel_names[channel];
807
+
808
+ /*
809
+ * We want to refresh manually updated displays from dirty callback,
810
+ * which is called quite often (e.g. for each drawn line). This will
811
+ * be used to do the display update asynchronously to avoid blocking
812
+ * the rendering process and merges multiple dirty calls into one
813
+ * update if they arrive very fast. We also call this function for
814
+ * atomic display updates (e.g. for page flips), which means we do
815
+ * not need extra locking. Atomic updates should be synchronous, but
816
+ * need to wait for the framedone interrupt anyways.
817
+ */
818
+ INIT_DELAYED_WORK(&omap_crtc->update_work,
819
+ omap_crtc_manual_display_update);
725820
726821 ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
727822 &omap_crtc_funcs, NULL);
728823 if (ret < 0) {
729824 dev_err(dev->dev, "%s(): could not init crtc for: %s\n",
730
- __func__, dssdev->name);
825
+ __func__, pipe->output->name);
731826 kfree(omap_crtc);
732827 return ERR_PTR(ret);
733828 }
....@@ -739,7 +834,7 @@
739834 * OMAP_DSS_CHANNEL_DIGIT. X server assumes 256 element gamma
740835 * tables so lets use that. Size of HW gamma table can be
741836 * extracted with dispc_mgr_gamma_size(). If it returns 0
742
- * gamma table is not supprted.
837
+ * gamma table is not supported.
743838 */
744839 if (priv->dispc_ops->mgr_gamma_size(priv->dispc, channel)) {
745840 unsigned int gamma_lut_size = 256;
....@@ -749,8 +844,6 @@
749844 }
750845
751846 omap_plane_install_properties(crtc->primary, &crtc->base);
752
-
753
- omap_crtcs[channel] = omap_crtc;
754847
755848 return crtc;
756849 }