forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/nouveau/dispnv04/disp.c
....@@ -22,7 +22,6 @@
2222 * Author: Ben Skeggs
2323 */
2424
25
-#include <drm/drmP.h>
2625 #include <drm/drm_crtc_helper.h>
2726
2827 #include "nouveau_drv.h"
....@@ -30,6 +29,186 @@
3029 #include "hw.h"
3130 #include "nouveau_encoder.h"
3231 #include "nouveau_connector.h"
32
+#include "nouveau_bo.h"
33
+#include "nouveau_gem.h"
34
+#include "nouveau_chan.h"
35
+
36
+#include <nvif/if0004.h>
37
+
38
+struct nouveau_connector *
39
+nv04_encoder_get_connector(struct nouveau_encoder *encoder)
40
+{
41
+ struct drm_device *dev = to_drm_encoder(encoder)->dev;
42
+ struct drm_connector *connector;
43
+ struct drm_connector_list_iter conn_iter;
44
+ struct nouveau_connector *nv_connector = NULL;
45
+
46
+ drm_connector_list_iter_begin(dev, &conn_iter);
47
+ drm_for_each_connector_iter(connector, &conn_iter) {
48
+ if (connector->encoder == to_drm_encoder(encoder))
49
+ nv_connector = nouveau_connector(connector);
50
+ }
51
+ drm_connector_list_iter_end(&conn_iter);
52
+
53
+ return nv_connector;
54
+}
55
+
56
+static void
57
+nv04_display_fini(struct drm_device *dev, bool runtime, bool suspend)
58
+{
59
+ struct nouveau_drm *drm = nouveau_drm(dev);
60
+ struct nv04_display *disp = nv04_display(dev);
61
+ struct drm_crtc *crtc;
62
+
63
+ /* Disable flip completion events. */
64
+ nvif_notify_put(&disp->flip);
65
+
66
+ /* Disable vblank interrupts. */
67
+ NVWriteCRTC(dev, 0, NV_PCRTC_INTR_EN_0, 0);
68
+ if (nv_two_heads(dev))
69
+ NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
70
+
71
+ if (!runtime)
72
+ cancel_work_sync(&drm->hpd_work);
73
+
74
+ if (!suspend)
75
+ return;
76
+
77
+ /* Un-pin FB and cursors so they'll be evicted to system memory. */
78
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
79
+ struct drm_framebuffer *fb = crtc->primary->fb;
80
+ struct nouveau_bo *nvbo;
81
+
82
+ if (!fb || !fb->obj[0])
83
+ continue;
84
+ nvbo = nouveau_gem_object(fb->obj[0]);
85
+ nouveau_bo_unpin(nvbo);
86
+ }
87
+
88
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
89
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
90
+ if (nv_crtc->cursor.nvbo) {
91
+ if (nv_crtc->cursor.set_offset)
92
+ nouveau_bo_unmap(nv_crtc->cursor.nvbo);
93
+ nouveau_bo_unpin(nv_crtc->cursor.nvbo);
94
+ }
95
+ }
96
+}
97
+
98
+static int
99
+nv04_display_init(struct drm_device *dev, bool resume, bool runtime)
100
+{
101
+ struct nv04_display *disp = nv04_display(dev);
102
+ struct nouveau_drm *drm = nouveau_drm(dev);
103
+ struct nouveau_encoder *encoder;
104
+ struct drm_crtc *crtc;
105
+ int ret;
106
+
107
+ /* meh.. modeset apparently doesn't setup all the regs and depends
108
+ * on pre-existing state, for now load the state of the card *before*
109
+ * nouveau was loaded, and then do a modeset.
110
+ *
111
+ * best thing to do probably is to make save/restore routines not
112
+ * save/restore "pre-load" state, but more general so we can save
113
+ * on suspend too.
114
+ */
115
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
116
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
117
+ nv_crtc->save(&nv_crtc->base);
118
+ }
119
+
120
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
121
+ encoder->enc_save(&encoder->base.base);
122
+
123
+ /* Enable flip completion events. */
124
+ nvif_notify_get(&disp->flip);
125
+
126
+ if (!resume)
127
+ return 0;
128
+
129
+ /* Re-pin FB/cursors. */
130
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
131
+ struct drm_framebuffer *fb = crtc->primary->fb;
132
+ struct nouveau_bo *nvbo;
133
+
134
+ if (!fb || !fb->obj[0])
135
+ continue;
136
+ nvbo = nouveau_gem_object(fb->obj[0]);
137
+ ret = nouveau_bo_pin(nvbo, NOUVEAU_GEM_DOMAIN_VRAM, true);
138
+ if (ret)
139
+ NV_ERROR(drm, "Could not pin framebuffer\n");
140
+ }
141
+
142
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
143
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
144
+ if (!nv_crtc->cursor.nvbo)
145
+ continue;
146
+
147
+ ret = nouveau_bo_pin(nv_crtc->cursor.nvbo,
148
+ NOUVEAU_GEM_DOMAIN_VRAM, true);
149
+ if (!ret && nv_crtc->cursor.set_offset)
150
+ ret = nouveau_bo_map(nv_crtc->cursor.nvbo);
151
+ if (ret)
152
+ NV_ERROR(drm, "Could not pin/map cursor.\n");
153
+ }
154
+
155
+ /* Force CLUT to get re-loaded during modeset. */
156
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
157
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
158
+
159
+ nv_crtc->lut.depth = 0;
160
+ }
161
+
162
+ /* This should ensure we don't hit a locking problem when someone
163
+ * wakes us up via a connector. We should never go into suspend
164
+ * while the display is on anyways.
165
+ */
166
+ if (runtime)
167
+ return 0;
168
+
169
+ /* Restore mode. */
170
+ drm_helper_resume_force_mode(dev);
171
+
172
+ list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
173
+ struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc);
174
+
175
+ if (!nv_crtc->cursor.nvbo)
176
+ continue;
177
+
178
+ if (nv_crtc->cursor.set_offset)
179
+ nv_crtc->cursor.set_offset(nv_crtc,
180
+ nv_crtc->cursor.nvbo->offset);
181
+ nv_crtc->cursor.set_pos(nv_crtc, nv_crtc->cursor_saved_x,
182
+ nv_crtc->cursor_saved_y);
183
+ }
184
+
185
+ return 0;
186
+}
187
+
188
+static void
189
+nv04_display_destroy(struct drm_device *dev)
190
+{
191
+ struct nv04_display *disp = nv04_display(dev);
192
+ struct nouveau_drm *drm = nouveau_drm(dev);
193
+ struct nouveau_encoder *encoder;
194
+ struct nouveau_crtc *nv_crtc;
195
+
196
+ /* Restore state */
197
+ list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
198
+ encoder->enc_restore(&encoder->base.base);
199
+
200
+ list_for_each_entry(nv_crtc, &dev->mode_config.crtc_list, base.head)
201
+ nv_crtc->restore(&nv_crtc->base);
202
+
203
+ nouveau_hw_save_vga_fonts(dev, 0);
204
+
205
+ nvif_notify_dtor(&disp->flip);
206
+
207
+ nouveau_display(dev)->priv = NULL;
208
+ vfree(disp);
209
+
210
+ nvif_object_unmap(&drm->client.device.object);
211
+}
33212
34213 int
35214 nv04_display_create(struct drm_device *dev)
....@@ -44,7 +223,7 @@
44223 struct nv04_display *disp;
45224 int i, ret;
46225
47
- disp = kzalloc(sizeof(*disp), GFP_KERNEL);
226
+ disp = vzalloc(sizeof(*disp));
48227 if (!disp)
49228 return -ENOMEM;
50229
....@@ -56,7 +235,14 @@
56235 nouveau_display(dev)->fini = nv04_display_fini;
57236
58237 /* Pre-nv50 doesn't support atomic, so don't expose the ioctls */
59
- dev->driver->driver_features &= ~DRIVER_ATOMIC;
238
+ dev->driver_features &= ~DRIVER_ATOMIC;
239
+
240
+ /* Request page flip completion event. */
241
+ if (drm->channel) {
242
+ nvif_notify_ctor(&drm->channel->nvsw, "kmsFlip", nv04_flip_complete,
243
+ false, NV04_NVSW_NTFY_UEVENT,
244
+ NULL, 0, 0, &disp->flip);
245
+ }
60246
61247 nouveau_hw_save_vga_fonts(dev, 1);
62248
....@@ -67,7 +253,7 @@
67253 for (i = 0; i < dcb->entries; i++) {
68254 struct dcb_output *dcbent = &dcb->entry[i];
69255
70
- connector = nouveau_connector_create(dev, dcbent->connector);
256
+ connector = nouveau_connector_create(dev, dcbent);
71257 if (IS_ERR(connector))
72258 continue;
73259
....@@ -96,7 +282,7 @@
96282
97283 list_for_each_entry_safe(connector, ct,
98284 &dev->mode_config.connector_list, head) {
99
- if (!connector->encoder_ids[0]) {
285
+ if (!connector->possible_encoders) {
100286 NV_WARN(drm, "%s has no encoders, removing\n",
101287 connector->name);
102288 connector->funcs->destroy(connector);
....@@ -120,59 +306,4 @@
120306 nouveau_overlay_init(dev);
121307
122308 return 0;
123
-}
124
-
125
-void
126
-nv04_display_destroy(struct drm_device *dev)
127
-{
128
- struct nv04_display *disp = nv04_display(dev);
129
- struct nouveau_drm *drm = nouveau_drm(dev);
130
- struct nouveau_encoder *encoder;
131
- struct nouveau_crtc *nv_crtc;
132
-
133
- /* Restore state */
134
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
135
- encoder->enc_restore(&encoder->base.base);
136
-
137
- list_for_each_entry(nv_crtc, &dev->mode_config.crtc_list, base.head)
138
- nv_crtc->restore(&nv_crtc->base);
139
-
140
- nouveau_hw_save_vga_fonts(dev, 0);
141
-
142
- nouveau_display(dev)->priv = NULL;
143
- kfree(disp);
144
-
145
- nvif_object_unmap(&drm->client.device.object);
146
-}
147
-
148
-int
149
-nv04_display_init(struct drm_device *dev)
150
-{
151
- struct nouveau_encoder *encoder;
152
- struct nouveau_crtc *crtc;
153
-
154
- /* meh.. modeset apparently doesn't setup all the regs and depends
155
- * on pre-existing state, for now load the state of the card *before*
156
- * nouveau was loaded, and then do a modeset.
157
- *
158
- * best thing to do probably is to make save/restore routines not
159
- * save/restore "pre-load" state, but more general so we can save
160
- * on suspend too.
161
- */
162
- list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head)
163
- crtc->save(&crtc->base);
164
-
165
- list_for_each_entry(encoder, &dev->mode_config.encoder_list, base.base.head)
166
- encoder->enc_save(&encoder->base.base);
167
-
168
- return 0;
169
-}
170
-
171
-void
172
-nv04_display_fini(struct drm_device *dev)
173
-{
174
- /* disable vblank interrupts */
175
- NVWriteCRTC(dev, 0, NV_PCRTC_INTR_EN_0, 0);
176
- if (nv_two_heads(dev))
177
- NVWriteCRTC(dev, 1, NV_PCRTC_INTR_EN_0, 0);
178309 }