forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-02-20 ea08eeccae9297f7aabd2ef7f0c2517ac4549acc
kernel/drivers/gpu/drm/drm_crtc_helper.c
....@@ -29,20 +29,26 @@
2929 * Jesse Barnes <jesse.barnes@intel.com>
3030 */
3131
32
-#include <linux/kernel.h>
3332 #include <linux/export.h>
33
+#include <linux/kernel.h>
3434 #include <linux/moduleparam.h>
3535
36
-#include <drm/drmP.h>
3736 #include <drm/drm_atomic.h>
38
-#include <drm/drm_crtc.h>
39
-#include <drm/drm_encoder.h>
40
-#include <drm/drm_fourcc.h>
41
-#include <drm/drm_crtc_helper.h>
42
-#include <drm/drm_fb_helper.h>
43
-#include <drm/drm_plane_helper.h>
4437 #include <drm/drm_atomic_helper.h>
38
+#include <drm/drm_atomic_uapi.h>
39
+#include <drm/drm_bridge.h>
40
+#include <drm/drm_crtc.h>
41
+#include <drm/drm_crtc_helper.h>
42
+#include <drm/drm_drv.h>
4543 #include <drm/drm_edid.h>
44
+#include <drm/drm_encoder.h>
45
+#include <drm/drm_fb_helper.h>
46
+#include <drm/drm_fourcc.h>
47
+#include <drm/drm_plane_helper.h>
48
+#include <drm/drm_print.h>
49
+#include <drm/drm_vblank.h>
50
+
51
+#include "drm_crtc_helper_internal.h"
4652
4753 /**
4854 * DOC: overview
....@@ -92,6 +98,8 @@
9298 struct drm_connector_list_iter conn_iter;
9399 struct drm_device *dev = encoder->dev;
94100
101
+ WARN_ON(drm_drv_uses_atomic_modeset(dev));
102
+
95103 /*
96104 * We can expect this mutex to be locked if we are not panicking.
97105 * Locking is currently fubar in the panic handler.
....@@ -130,6 +138,8 @@
130138 struct drm_encoder *encoder;
131139 struct drm_device *dev = crtc->dev;
132140
141
+ WARN_ON(drm_drv_uses_atomic_modeset(dev));
142
+
133143 /*
134144 * We can expect this mutex to be locked if we are not panicking.
135145 * Locking is currently fubar in the panic handler.
....@@ -152,14 +162,10 @@
152162 if (!encoder_funcs)
153163 return;
154164
155
- drm_bridge_disable(encoder->bridge);
156
-
157165 if (encoder_funcs->disable)
158166 (*encoder_funcs->disable)(encoder);
159167 else if (encoder_funcs->dpms)
160168 (*encoder_funcs->dpms)(encoder, DRM_MODE_DPMS_OFF);
161
-
162
- drm_bridge_post_disable(encoder->bridge);
163169 }
164170
165171 static void __drm_helper_disable_unused_functions(struct drm_device *dev)
....@@ -179,6 +185,7 @@
179185
180186 drm_for_each_crtc(crtc, dev) {
181187 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
188
+
182189 crtc->enabled = drm_helper_crtc_in_use(crtc);
183190 if (!crtc->enabled) {
184191 if (crtc_funcs->disable)
....@@ -211,8 +218,7 @@
211218 */
212219 void drm_helper_disable_unused_functions(struct drm_device *dev)
213220 {
214
- if (drm_core_check_feature(dev, DRIVER_ATOMIC))
215
- DRM_ERROR("Called for atomic driver, this is not what you want.\n");
221
+ WARN_ON(drm_drv_uses_atomic_modeset(dev));
216222
217223 drm_modeset_lock_all(dev);
218224 __drm_helper_disable_unused_functions(dev);
....@@ -238,10 +244,6 @@
238244
239245 /* Disable unused encoders */
240246 if (encoder->crtc == NULL)
241
- drm_encoder_disable(encoder);
242
- /* Disable encoders whose CRTC is about to change */
243
- if (encoder_funcs->get_crtc &&
244
- encoder->crtc != (*encoder_funcs->get_crtc)(encoder))
245247 drm_encoder_disable(encoder);
246248 }
247249 }
....@@ -279,6 +281,8 @@
279281 bool saved_enabled;
280282 struct drm_encoder *encoder;
281283 bool ret = true;
284
+
285
+ WARN_ON(drm_drv_uses_atomic_modeset(dev));
282286
283287 drm_warn_on_modeset_not_all_locked(dev);
284288
....@@ -318,13 +322,6 @@
318322 if (!encoder_funcs)
319323 continue;
320324
321
- ret = drm_bridge_mode_fixup(encoder->bridge,
322
- mode, adjusted_mode);
323
- if (!ret) {
324
- DRM_DEBUG_KMS("Bridge fixup failed\n");
325
- goto done;
326
- }
327
-
328325 encoder_funcs = encoder->helper_private;
329326 if (encoder_funcs->mode_fixup) {
330327 if (!(ret = encoder_funcs->mode_fixup(encoder, mode,
....@@ -356,13 +353,9 @@
356353 if (!encoder_funcs)
357354 continue;
358355
359
- drm_bridge_disable(encoder->bridge);
360
-
361356 /* Disable the encoders as the first thing we do. */
362357 if (encoder_funcs->prepare)
363358 encoder_funcs->prepare(encoder);
364
-
365
- drm_bridge_post_disable(encoder->bridge);
366359 }
367360
368361 drm_crtc_prepare_encoders(dev);
....@@ -385,13 +378,10 @@
385378 if (!encoder_funcs)
386379 continue;
387380
388
- DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%d:%s]\n",
389
- encoder->base.id, encoder->name,
390
- mode->base.id, mode->name);
381
+ DRM_DEBUG_KMS("[ENCODER:%d:%s] set [MODE:%s]\n",
382
+ encoder->base.id, encoder->name, mode->name);
391383 if (encoder_funcs->mode_set)
392384 encoder_funcs->mode_set(encoder, mode, adjusted_mode);
393
-
394
- drm_bridge_mode_set(encoder->bridge, mode, adjusted_mode);
395385 }
396386
397387 /* Now enable the clocks, plane, pipe, and connectors that we set up. */
....@@ -406,12 +396,8 @@
406396 if (!encoder_funcs)
407397 continue;
408398
409
- drm_bridge_pre_enable(encoder->bridge);
410
-
411399 if (encoder_funcs->commit)
412400 encoder_funcs->commit(encoder);
413
-
414
- drm_bridge_enable(encoder->bridge);
415401 }
416402
417403 /* Calculate and store various constants which
....@@ -471,6 +457,22 @@
471457 }
472458
473459 __drm_helper_disable_unused_functions(dev);
460
+}
461
+
462
+/*
463
+ * For connectors that support multiple encoders, either the
464
+ * .atomic_best_encoder() or .best_encoder() operation must be implemented.
465
+ */
466
+struct drm_encoder *
467
+drm_connector_get_single_encoder(struct drm_connector *connector)
468
+{
469
+ struct drm_encoder *encoder;
470
+
471
+ WARN_ON(hweight32(connector->possible_encoders) > 1);
472
+ drm_connector_for_each_possible_encoder(connector, encoder)
473
+ return encoder;
474
+
475
+ return NULL;
474476 }
475477
476478 /**
....@@ -539,6 +541,9 @@
539541
540542 crtc_funcs = set->crtc->helper_private;
541543
544
+ dev = set->crtc->dev;
545
+ WARN_ON(drm_drv_uses_atomic_modeset(dev));
546
+
542547 if (!set->mode)
543548 set->fb = NULL;
544549
....@@ -553,8 +558,6 @@
553558 drm_crtc_helper_disable(set->crtc);
554559 return 0;
555560 }
556
-
557
- dev = set->crtc->dev;
558561
559562 drm_warn_on_modeset_not_all_locked(dev);
560563
....@@ -637,7 +640,11 @@
637640 new_encoder = connector->encoder;
638641 for (ro = 0; ro < set->num_connectors; ro++) {
639642 if (set->connectors[ro] == connector) {
640
- new_encoder = connector_funcs->best_encoder(connector);
643
+ if (connector_funcs->best_encoder)
644
+ new_encoder = connector_funcs->best_encoder(connector);
645
+ else
646
+ new_encoder = drm_connector_get_single_encoder(connector);
647
+
641648 /* if we can't get an encoder for a connector
642649 we are setting now - then fail */
643650 if (new_encoder == NULL)
....@@ -809,25 +816,14 @@
809816 /* Helper which handles bridge ordering around encoder dpms */
810817 static void drm_helper_encoder_dpms(struct drm_encoder *encoder, int mode)
811818 {
812
- struct drm_bridge *bridge = encoder->bridge;
813819 const struct drm_encoder_helper_funcs *encoder_funcs;
814820
815821 encoder_funcs = encoder->helper_private;
816822 if (!encoder_funcs)
817823 return;
818824
819
- if (mode == DRM_MODE_DPMS_ON)
820
- drm_bridge_pre_enable(bridge);
821
- else
822
- drm_bridge_disable(bridge);
823
-
824825 if (encoder_funcs->dpms)
825826 encoder_funcs->dpms(encoder, mode);
826
-
827
- if (mode == DRM_MODE_DPMS_ON)
828
- drm_bridge_enable(bridge);
829
- else
830
- drm_bridge_post_disable(bridge);
831827 }
832828
833829 static int drm_helper_choose_crtc_dpms(struct drm_crtc *crtc)
....@@ -874,6 +870,8 @@
874870 struct drm_crtc *crtc = encoder ? encoder->crtc : NULL;
875871 int old_dpms, encoder_dpms = DRM_MODE_DPMS_OFF;
876872
873
+ WARN_ON(drm_drv_uses_atomic_modeset(connector->dev));
874
+
877875 if (mode == connector->dpms)
878876 return 0;
879877
....@@ -887,6 +885,7 @@
887885 if (mode < old_dpms) {
888886 if (crtc) {
889887 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
888
+
890889 if (crtc_funcs->dpms)
891890 (*crtc_funcs->dpms) (crtc,
892891 drm_helper_choose_crtc_dpms(crtc));
....@@ -901,6 +900,7 @@
901900 drm_helper_encoder_dpms(encoder, encoder_dpms);
902901 if (crtc) {
903902 const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
903
+
904904 if (crtc_funcs->dpms)
905905 (*crtc_funcs->dpms) (crtc,
906906 drm_helper_choose_crtc_dpms(crtc));
....@@ -945,6 +945,8 @@
945945 int encoder_dpms;
946946 bool ret;
947947
948
+ WARN_ON(drm_drv_uses_atomic_modeset(dev));
949
+
948950 drm_modeset_lock_all(dev);
949951 drm_for_each_crtc(crtc, dev) {
950952
....@@ -985,116 +987,36 @@
985987 EXPORT_SYMBOL(drm_helper_resume_force_mode);
986988
987989 /**
988
- * drm_helper_crtc_mode_set - mode_set implementation for atomic plane helpers
989
- * @crtc: DRM CRTC
990
- * @mode: DRM display mode which userspace requested
991
- * @adjusted_mode: DRM display mode adjusted by ->mode_fixup callbacks
992
- * @x: x offset of the CRTC scanout area on the underlying framebuffer
993
- * @y: y offset of the CRTC scanout area on the underlying framebuffer
994
- * @old_fb: previous framebuffer
990
+ * drm_helper_force_disable_all - Forcibly turn off all enabled CRTCs
991
+ * @dev: DRM device whose CRTCs to turn off
995992 *
996
- * This function implements a callback useable as the ->mode_set callback
997
- * required by the CRTC helpers. Besides the atomic plane helper functions for
998
- * the primary plane the driver must also provide the ->mode_set_nofb callback
999
- * to set up the CRTC.
993
+ * Drivers may want to call this on unload to ensure that all displays are
994
+ * unlit and the GPU is in a consistent, low power state. Takes modeset locks.
1000995 *
1001
- * This is a transitional helper useful for converting drivers to the atomic
1002
- * interfaces.
996
+ * Note: This should only be used by non-atomic legacy drivers. For an atomic
997
+ * version look at drm_atomic_helper_shutdown().
998
+ *
999
+ * Returns:
1000
+ * Zero on success, error code on failure.
10031001 */
1004
-int drm_helper_crtc_mode_set(struct drm_crtc *crtc, struct drm_display_mode *mode,
1005
- struct drm_display_mode *adjusted_mode, int x, int y,
1006
- struct drm_framebuffer *old_fb)
1002
+int drm_helper_force_disable_all(struct drm_device *dev)
10071003 {
1008
- struct drm_crtc_state *crtc_state;
1009
- const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
1010
- int ret;
1004
+ struct drm_crtc *crtc;
1005
+ int ret = 0;
10111006
1012
- if (crtc->funcs->atomic_duplicate_state)
1013
- crtc_state = crtc->funcs->atomic_duplicate_state(crtc);
1014
- else {
1015
- if (!crtc->state)
1016
- drm_atomic_helper_crtc_reset(crtc);
1007
+ drm_modeset_lock_all(dev);
1008
+ drm_for_each_crtc(crtc, dev)
1009
+ if (crtc->enabled) {
1010
+ struct drm_mode_set set = {
1011
+ .crtc = crtc,
1012
+ };
10171013
1018
- crtc_state = drm_atomic_helper_crtc_duplicate_state(crtc);
1019
- }
1020
-
1021
- if (!crtc_state)
1022
- return -ENOMEM;
1023
-
1024
- crtc_state->planes_changed = true;
1025
- crtc_state->mode_changed = true;
1026
- ret = drm_atomic_set_mode_for_crtc(crtc_state, mode);
1027
- if (ret)
1028
- goto out;
1029
- drm_mode_copy(&crtc_state->adjusted_mode, adjusted_mode);
1030
-
1031
- if (crtc_funcs->atomic_check) {
1032
- ret = crtc_funcs->atomic_check(crtc, crtc_state);
1033
- if (ret)
1034
- goto out;
1035
- }
1036
-
1037
- swap(crtc->state, crtc_state);
1038
-
1039
- crtc_funcs->mode_set_nofb(crtc);
1040
-
1041
- ret = drm_helper_crtc_mode_set_base(crtc, x, y, old_fb);
1042
-
1014
+ ret = drm_mode_set_config_internal(&set);
1015
+ if (ret)
1016
+ goto out;
1017
+ }
10431018 out:
1044
- if (crtc_state) {
1045
- if (crtc->funcs->atomic_destroy_state)
1046
- crtc->funcs->atomic_destroy_state(crtc, crtc_state);
1047
- else
1048
- drm_atomic_helper_crtc_destroy_state(crtc, crtc_state);
1049
- }
1050
-
1019
+ drm_modeset_unlock_all(dev);
10511020 return ret;
10521021 }
1053
-EXPORT_SYMBOL(drm_helper_crtc_mode_set);
1054
-
1055
-/**
1056
- * drm_helper_crtc_mode_set_base - mode_set_base implementation for atomic plane helpers
1057
- * @crtc: DRM CRTC
1058
- * @x: x offset of the CRTC scanout area on the underlying framebuffer
1059
- * @y: y offset of the CRTC scanout area on the underlying framebuffer
1060
- * @old_fb: previous framebuffer
1061
- *
1062
- * This function implements a callback useable as the ->mode_set_base used
1063
- * required by the CRTC helpers. The driver must provide the atomic plane helper
1064
- * functions for the primary plane.
1065
- *
1066
- * This is a transitional helper useful for converting drivers to the atomic
1067
- * interfaces.
1068
- */
1069
-int drm_helper_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
1070
- struct drm_framebuffer *old_fb)
1071
-{
1072
- struct drm_plane_state *plane_state;
1073
- struct drm_plane *plane = crtc->primary;
1074
-
1075
- if (plane->funcs->atomic_duplicate_state)
1076
- plane_state = plane->funcs->atomic_duplicate_state(plane);
1077
- else {
1078
- if (!plane->state)
1079
- drm_atomic_helper_plane_reset(plane);
1080
-
1081
- plane_state = drm_atomic_helper_plane_duplicate_state(plane);
1082
- }
1083
- if (!plane_state)
1084
- return -ENOMEM;
1085
- plane_state->plane = plane;
1086
-
1087
- plane_state->crtc = crtc;
1088
- drm_atomic_set_fb_for_plane(plane_state, crtc->primary->fb);
1089
- plane_state->crtc_x = 0;
1090
- plane_state->crtc_y = 0;
1091
- plane_state->crtc_h = crtc->mode.vdisplay;
1092
- plane_state->crtc_w = crtc->mode.hdisplay;
1093
- plane_state->src_x = x << 16;
1094
- plane_state->src_y = y << 16;
1095
- plane_state->src_h = crtc->mode.vdisplay << 16;
1096
- plane_state->src_w = crtc->mode.hdisplay << 16;
1097
-
1098
- return drm_plane_helper_commit(plane, plane_state, old_fb);
1099
-}
1100
-EXPORT_SYMBOL(drm_helper_crtc_mode_set_base);
1022
+EXPORT_SYMBOL(drm_helper_force_disable_all);