forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-10 61598093bbdd283a7edc367d900f223070ead8d2
kernel/drivers/gpu/drm/nouveau/nvkm/engine/disp/outp.c
....@@ -112,8 +112,35 @@
112112 return 0;
113113 }
114114
115
+static inline int
116
+nvkm_outp_acquire_hda(struct nvkm_outp *outp, enum nvkm_ior_type type,
117
+ u8 user, bool hda)
118
+{
119
+ struct nvkm_ior *ior;
120
+
121
+ /* Failing that, a completely unused OR is the next best thing. */
122
+ list_for_each_entry(ior, &outp->disp->ior, head) {
123
+ if (!ior->identity && !!ior->func->hda.hpd == hda &&
124
+ !ior->asy.outp && ior->type == type && !ior->arm.outp &&
125
+ (ior->func->route.set || ior->id == __ffs(outp->info.or)))
126
+ return nvkm_outp_acquire_ior(outp, user, ior);
127
+ }
128
+
129
+ /* Last resort is to assign an OR that's already active on HW,
130
+ * but will be released during the next modeset.
131
+ */
132
+ list_for_each_entry(ior, &outp->disp->ior, head) {
133
+ if (!ior->identity && !!ior->func->hda.hpd == hda &&
134
+ !ior->asy.outp && ior->type == type &&
135
+ (ior->func->route.set || ior->id == __ffs(outp->info.or)))
136
+ return nvkm_outp_acquire_ior(outp, user, ior);
137
+ }
138
+
139
+ return -ENOSPC;
140
+}
141
+
115142 int
116
-nvkm_outp_acquire(struct nvkm_outp *outp, u8 user)
143
+nvkm_outp_acquire(struct nvkm_outp *outp, u8 user, bool hda)
117144 {
118145 struct nvkm_ior *ior = outp->ior;
119146 enum nvkm_ior_proto proto;
....@@ -142,28 +169,42 @@
142169 * on HW, if any, in order to prevent unnecessary switching.
143170 */
144171 list_for_each_entry(ior, &outp->disp->ior, head) {
145
- if (!ior->identity && !ior->asy.outp && ior->arm.outp == outp)
172
+ if (!ior->identity && !ior->asy.outp && ior->arm.outp == outp) {
173
+ /*XXX: For various complicated reasons, we can't outright switch
174
+ * the boot-time OR on the first modeset without some fairly
175
+ * invasive changes.
176
+ *
177
+ * The systems that were fixed by modifying the OR selection
178
+ * code to account for HDA support shouldn't regress here as
179
+ * the HDA-enabled ORs match the relevant output's pad macro
180
+ * index, and the firmware seems to select an OR this way.
181
+ *
182
+ * This warning is to make it obvious if that proves wrong.
183
+ */
184
+ WARN_ON(hda && !ior->func->hda.hpd);
146185 return nvkm_outp_acquire_ior(outp, user, ior);
186
+ }
147187 }
148188
149
- /* Failing that, a completely unused OR is the next best thing. */
150
- list_for_each_entry(ior, &outp->disp->ior, head) {
151
- if (!ior->identity &&
152
- !ior->asy.outp && ior->type == type && !ior->arm.outp &&
153
- (ior->func->route.set || ior->id == __ffs(outp->info.or)))
154
- return nvkm_outp_acquire_ior(outp, user, ior);
155
- }
156
-
157
- /* Last resort is to assign an OR that's already active on HW,
158
- * but will be released during the next modeset.
189
+ /* If we don't need HDA, first try to acquire an OR that doesn't
190
+ * support it to leave free the ones that do.
159191 */
160
- list_for_each_entry(ior, &outp->disp->ior, head) {
161
- if (!ior->identity && !ior->asy.outp && ior->type == type &&
162
- (ior->func->route.set || ior->id == __ffs(outp->info.or)))
163
- return nvkm_outp_acquire_ior(outp, user, ior);
192
+ if (!hda) {
193
+ if (!nvkm_outp_acquire_hda(outp, type, user, false))
194
+ return 0;
195
+
196
+ /* Use a HDA-supporting SOR anyway. */
197
+ return nvkm_outp_acquire_hda(outp, type, user, true);
164198 }
165199
166
- return -ENOSPC;
200
+ /* We want HDA, try to acquire an OR that supports it. */
201
+ if (!nvkm_outp_acquire_hda(outp, type, user, true))
202
+ return 0;
203
+
204
+ /* There weren't any free ORs that support HDA, grab one that
205
+ * doesn't and at least allow display to work still.
206
+ */
207
+ return nvkm_outp_acquire_hda(outp, type, user, false);
167208 }
168209
169210 void