hc
2024-05-10 cde9070d9970eef1f7ec2360586c802a16230ad8
kernel/drivers/gpu/drm/rcar-du/rcar_du_kms.c
....@@ -1,26 +1,25 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * rcar_du_kms.c -- R-Car Display Unit Mode Setting
34 *
45 * Copyright (C) 2013-2015 Renesas Electronics Corporation
56 *
67 * Contact: Laurent Pinchart (laurent.pinchart@ideasonboard.com)
7
- *
8
- * This program is free software; you can redistribute it and/or modify
9
- * it under the terms of the GNU General Public License as published by
10
- * the Free Software Foundation; either version 2 of the License, or
11
- * (at your option) any later version.
128 */
139
14
-#include <drm/drmP.h>
1510 #include <drm/drm_atomic.h>
1611 #include <drm/drm_atomic_helper.h>
1712 #include <drm/drm_crtc.h>
18
-#include <drm/drm_crtc_helper.h>
13
+#include <drm/drm_device.h>
1914 #include <drm/drm_fb_cma_helper.h>
2015 #include <drm/drm_gem_cma_helper.h>
2116 #include <drm/drm_gem_framebuffer_helper.h>
17
+#include <drm/drm_probe_helper.h>
18
+#include <drm/drm_vblank.h>
2219
20
+#include <linux/device.h>
2321 #include <linux/of_graph.h>
22
+#include <linux/of_platform.h>
2423 #include <linux/wait.h>
2524
2625 #include "rcar_du_crtc.h"
....@@ -29,6 +28,7 @@
2928 #include "rcar_du_kms.h"
3029 #include "rcar_du_regs.h"
3130 #include "rcar_du_vsp.h"
31
+#include "rcar_du_writeback.h"
3232
3333 /* -----------------------------------------------------------------------------
3434 * Format helpers
....@@ -37,62 +37,81 @@
3737 static const struct rcar_du_format_info rcar_du_format_infos[] = {
3838 {
3939 .fourcc = DRM_FORMAT_RGB565,
40
+ .v4l2 = V4L2_PIX_FMT_RGB565,
4041 .bpp = 16,
4142 .planes = 1,
43
+ .hsub = 1,
4244 .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
4345 .edf = PnDDCR4_EDF_NONE,
4446 }, {
4547 .fourcc = DRM_FORMAT_ARGB1555,
48
+ .v4l2 = V4L2_PIX_FMT_ARGB555,
4649 .bpp = 16,
4750 .planes = 1,
51
+ .hsub = 1,
4852 .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
4953 .edf = PnDDCR4_EDF_NONE,
5054 }, {
5155 .fourcc = DRM_FORMAT_XRGB1555,
56
+ .v4l2 = V4L2_PIX_FMT_XRGB555,
5257 .bpp = 16,
5358 .planes = 1,
5459 .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_ARGB,
5560 .edf = PnDDCR4_EDF_NONE,
5661 }, {
5762 .fourcc = DRM_FORMAT_XRGB8888,
63
+ .v4l2 = V4L2_PIX_FMT_XBGR32,
5864 .bpp = 32,
5965 .planes = 1,
66
+ .hsub = 1,
6067 .pnmr = PnMR_SPIM_TP | PnMR_DDDF_16BPP,
6168 .edf = PnDDCR4_EDF_RGB888,
6269 }, {
6370 .fourcc = DRM_FORMAT_ARGB8888,
71
+ .v4l2 = V4L2_PIX_FMT_ABGR32,
6472 .bpp = 32,
6573 .planes = 1,
74
+ .hsub = 1,
6675 .pnmr = PnMR_SPIM_ALP | PnMR_DDDF_16BPP,
6776 .edf = PnDDCR4_EDF_ARGB8888,
6877 }, {
6978 .fourcc = DRM_FORMAT_UYVY,
79
+ .v4l2 = V4L2_PIX_FMT_UYVY,
7080 .bpp = 16,
7181 .planes = 1,
82
+ .hsub = 2,
7283 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
7384 .edf = PnDDCR4_EDF_NONE,
7485 }, {
7586 .fourcc = DRM_FORMAT_YUYV,
87
+ .v4l2 = V4L2_PIX_FMT_YUYV,
7688 .bpp = 16,
7789 .planes = 1,
90
+ .hsub = 2,
7891 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
7992 .edf = PnDDCR4_EDF_NONE,
8093 }, {
8194 .fourcc = DRM_FORMAT_NV12,
95
+ .v4l2 = V4L2_PIX_FMT_NV12M,
8296 .bpp = 12,
8397 .planes = 2,
98
+ .hsub = 2,
8499 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
85100 .edf = PnDDCR4_EDF_NONE,
86101 }, {
87102 .fourcc = DRM_FORMAT_NV21,
103
+ .v4l2 = V4L2_PIX_FMT_NV21M,
88104 .bpp = 12,
89105 .planes = 2,
106
+ .hsub = 2,
90107 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
91108 .edf = PnDDCR4_EDF_NONE,
92109 }, {
93110 .fourcc = DRM_FORMAT_NV16,
111
+ .v4l2 = V4L2_PIX_FMT_NV16M,
94112 .bpp = 16,
95113 .planes = 2,
114
+ .hsub = 2,
96115 .pnmr = PnMR_SPIM_TP_OFF | PnMR_DDDF_YC,
97116 .edf = PnDDCR4_EDF_NONE,
98117 },
....@@ -101,33 +120,191 @@
101120 * associated .pnmr or .edf settings.
102121 */
103122 {
123
+ .fourcc = DRM_FORMAT_RGB332,
124
+ .v4l2 = V4L2_PIX_FMT_RGB332,
125
+ .bpp = 8,
126
+ .planes = 1,
127
+ .hsub = 1,
128
+ }, {
129
+ .fourcc = DRM_FORMAT_ARGB4444,
130
+ .v4l2 = V4L2_PIX_FMT_ARGB444,
131
+ .bpp = 16,
132
+ .planes = 1,
133
+ .hsub = 1,
134
+ }, {
135
+ .fourcc = DRM_FORMAT_XRGB4444,
136
+ .v4l2 = V4L2_PIX_FMT_XRGB444,
137
+ .bpp = 16,
138
+ .planes = 1,
139
+ .hsub = 1,
140
+ }, {
141
+ .fourcc = DRM_FORMAT_RGBA4444,
142
+ .v4l2 = V4L2_PIX_FMT_RGBA444,
143
+ .bpp = 16,
144
+ .planes = 1,
145
+ .hsub = 1,
146
+ }, {
147
+ .fourcc = DRM_FORMAT_RGBX4444,
148
+ .v4l2 = V4L2_PIX_FMT_RGBX444,
149
+ .bpp = 16,
150
+ .planes = 1,
151
+ .hsub = 1,
152
+ }, {
153
+ .fourcc = DRM_FORMAT_ABGR4444,
154
+ .v4l2 = V4L2_PIX_FMT_ABGR444,
155
+ .bpp = 16,
156
+ .planes = 1,
157
+ .hsub = 1,
158
+ }, {
159
+ .fourcc = DRM_FORMAT_XBGR4444,
160
+ .v4l2 = V4L2_PIX_FMT_XBGR444,
161
+ .bpp = 16,
162
+ .planes = 1,
163
+ .hsub = 1,
164
+ }, {
165
+ .fourcc = DRM_FORMAT_BGRA4444,
166
+ .v4l2 = V4L2_PIX_FMT_BGRA444,
167
+ .bpp = 16,
168
+ .planes = 1,
169
+ .hsub = 1,
170
+ }, {
171
+ .fourcc = DRM_FORMAT_BGRX4444,
172
+ .v4l2 = V4L2_PIX_FMT_BGRX444,
173
+ .bpp = 16,
174
+ .planes = 1,
175
+ .hsub = 1,
176
+ }, {
177
+ .fourcc = DRM_FORMAT_RGBA5551,
178
+ .v4l2 = V4L2_PIX_FMT_RGBA555,
179
+ .bpp = 16,
180
+ .planes = 1,
181
+ .hsub = 1,
182
+ }, {
183
+ .fourcc = DRM_FORMAT_RGBX5551,
184
+ .v4l2 = V4L2_PIX_FMT_RGBX555,
185
+ .bpp = 16,
186
+ .planes = 1,
187
+ .hsub = 1,
188
+ }, {
189
+ .fourcc = DRM_FORMAT_ABGR1555,
190
+ .v4l2 = V4L2_PIX_FMT_ABGR555,
191
+ .bpp = 16,
192
+ .planes = 1,
193
+ .hsub = 1,
194
+ }, {
195
+ .fourcc = DRM_FORMAT_XBGR1555,
196
+ .v4l2 = V4L2_PIX_FMT_XBGR555,
197
+ .bpp = 16,
198
+ .planes = 1,
199
+ .hsub = 1,
200
+ }, {
201
+ .fourcc = DRM_FORMAT_BGRA5551,
202
+ .v4l2 = V4L2_PIX_FMT_BGRA555,
203
+ .bpp = 16,
204
+ .planes = 1,
205
+ .hsub = 1,
206
+ }, {
207
+ .fourcc = DRM_FORMAT_BGRX5551,
208
+ .v4l2 = V4L2_PIX_FMT_BGRX555,
209
+ .bpp = 16,
210
+ .planes = 1,
211
+ .hsub = 1,
212
+ }, {
213
+ .fourcc = DRM_FORMAT_BGR888,
214
+ .v4l2 = V4L2_PIX_FMT_RGB24,
215
+ .bpp = 24,
216
+ .planes = 1,
217
+ .hsub = 1,
218
+ }, {
219
+ .fourcc = DRM_FORMAT_RGB888,
220
+ .v4l2 = V4L2_PIX_FMT_BGR24,
221
+ .bpp = 24,
222
+ .planes = 1,
223
+ .hsub = 1,
224
+ }, {
225
+ .fourcc = DRM_FORMAT_RGBA8888,
226
+ .v4l2 = V4L2_PIX_FMT_BGRA32,
227
+ .bpp = 32,
228
+ .planes = 1,
229
+ .hsub = 1,
230
+ }, {
231
+ .fourcc = DRM_FORMAT_RGBX8888,
232
+ .v4l2 = V4L2_PIX_FMT_BGRX32,
233
+ .bpp = 32,
234
+ .planes = 1,
235
+ .hsub = 1,
236
+ }, {
237
+ .fourcc = DRM_FORMAT_ABGR8888,
238
+ .v4l2 = V4L2_PIX_FMT_RGBA32,
239
+ .bpp = 32,
240
+ .planes = 1,
241
+ .hsub = 1,
242
+ }, {
243
+ .fourcc = DRM_FORMAT_XBGR8888,
244
+ .v4l2 = V4L2_PIX_FMT_RGBX32,
245
+ .bpp = 32,
246
+ .planes = 1,
247
+ .hsub = 1,
248
+ }, {
249
+ .fourcc = DRM_FORMAT_BGRA8888,
250
+ .v4l2 = V4L2_PIX_FMT_ARGB32,
251
+ .bpp = 32,
252
+ .planes = 1,
253
+ .hsub = 1,
254
+ }, {
255
+ .fourcc = DRM_FORMAT_BGRX8888,
256
+ .v4l2 = V4L2_PIX_FMT_XRGB32,
257
+ .bpp = 32,
258
+ .planes = 1,
259
+ .hsub = 1,
260
+ }, {
261
+ .fourcc = DRM_FORMAT_YVYU,
262
+ .v4l2 = V4L2_PIX_FMT_YVYU,
263
+ .bpp = 16,
264
+ .planes = 1,
265
+ .hsub = 2,
266
+ }, {
104267 .fourcc = DRM_FORMAT_NV61,
268
+ .v4l2 = V4L2_PIX_FMT_NV61M,
105269 .bpp = 16,
106270 .planes = 2,
271
+ .hsub = 2,
107272 }, {
108273 .fourcc = DRM_FORMAT_YUV420,
274
+ .v4l2 = V4L2_PIX_FMT_YUV420M,
109275 .bpp = 12,
110276 .planes = 3,
277
+ .hsub = 2,
111278 }, {
112279 .fourcc = DRM_FORMAT_YVU420,
280
+ .v4l2 = V4L2_PIX_FMT_YVU420M,
113281 .bpp = 12,
114282 .planes = 3,
283
+ .hsub = 2,
115284 }, {
116285 .fourcc = DRM_FORMAT_YUV422,
286
+ .v4l2 = V4L2_PIX_FMT_YUV422M,
117287 .bpp = 16,
118288 .planes = 3,
289
+ .hsub = 2,
119290 }, {
120291 .fourcc = DRM_FORMAT_YVU422,
292
+ .v4l2 = V4L2_PIX_FMT_YVU422M,
121293 .bpp = 16,
122294 .planes = 3,
295
+ .hsub = 2,
123296 }, {
124297 .fourcc = DRM_FORMAT_YUV444,
298
+ .v4l2 = V4L2_PIX_FMT_YUV444M,
125299 .bpp = 24,
126300 .planes = 3,
301
+ .hsub = 1,
127302 }, {
128303 .fourcc = DRM_FORMAT_YVU444,
304
+ .v4l2 = V4L2_PIX_FMT_YVU444M,
129305 .bpp = 24,
130306 .planes = 3,
307
+ .hsub = 1,
131308 },
132309 };
133310
....@@ -174,9 +351,9 @@
174351 {
175352 struct rcar_du_device *rcdu = dev->dev_private;
176353 const struct rcar_du_format_info *format;
354
+ unsigned int chroma_pitch;
177355 unsigned int max_pitch;
178356 unsigned int align;
179
- unsigned int bpp;
180357 unsigned int i;
181358
182359 format = rcar_du_format_info(mode_cmd->pixel_format);
....@@ -186,41 +363,55 @@
186363 return ERR_PTR(-EINVAL);
187364 }
188365
189
- /*
190
- * The pitch and alignment constraints are expressed in pixels on the
191
- * hardware side and in bytes in the DRM API.
192
- */
193
- bpp = format->planes == 1 ? format->bpp / 8 : 1;
194
- max_pitch = 4096 * bpp;
366
+ if (rcdu->info->gen < 3) {
367
+ /*
368
+ * On Gen2 the DU limits the pitch to 4095 pixels and requires
369
+ * buffers to be aligned to a 16 pixels boundary (or 128 bytes
370
+ * on some platforms).
371
+ */
372
+ unsigned int bpp = format->planes == 1 ? format->bpp / 8 : 1;
195373
196
- if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
197
- align = 128;
198
- else
199
- align = 16 * bpp;
374
+ max_pitch = 4095 * bpp;
375
+
376
+ if (rcar_du_needs(rcdu, RCAR_DU_QUIRK_ALIGN_128B))
377
+ align = 128;
378
+ else
379
+ align = 16 * bpp;
380
+ } else {
381
+ /*
382
+ * On Gen3 the memory interface is handled by the VSP that
383
+ * limits the pitch to 65535 bytes and has no alignment
384
+ * constraint.
385
+ */
386
+ max_pitch = 65535;
387
+ align = 1;
388
+ }
200389
201390 if (mode_cmd->pitches[0] & (align - 1) ||
202
- mode_cmd->pitches[0] >= max_pitch) {
391
+ mode_cmd->pitches[0] > max_pitch) {
203392 dev_dbg(dev->dev, "invalid pitch value %u\n",
204393 mode_cmd->pitches[0]);
205394 return ERR_PTR(-EINVAL);
206395 }
207396
397
+ /*
398
+ * Calculate the chroma plane(s) pitch using the horizontal subsampling
399
+ * factor. For semi-planar formats, the U and V planes are combined, the
400
+ * pitch must thus be doubled.
401
+ */
402
+ chroma_pitch = mode_cmd->pitches[0] / format->hsub;
403
+ if (format->planes == 2)
404
+ chroma_pitch *= 2;
405
+
208406 for (i = 1; i < format->planes; ++i) {
209
- if (mode_cmd->pitches[i] != mode_cmd->pitches[0]) {
407
+ if (mode_cmd->pitches[i] != chroma_pitch) {
210408 dev_dbg(dev->dev,
211
- "luma and chroma pitches do not match\n");
409
+ "luma and chroma pitches are not compatible\n");
212410 return ERR_PTR(-EINVAL);
213411 }
214412 }
215413
216414 return drm_gem_fb_create(dev, file_priv, mode_cmd);
217
-}
218
-
219
-static void rcar_du_output_poll_changed(struct drm_device *dev)
220
-{
221
- struct rcar_du_device *rcdu = dev->dev_private;
222
-
223
- drm_fbdev_cma_hotplug_event(rcdu->fbdev);
224415 }
225416
226417 /* -----------------------------------------------------------------------------
....@@ -246,6 +437,28 @@
246437 static void rcar_du_atomic_commit_tail(struct drm_atomic_state *old_state)
247438 {
248439 struct drm_device *dev = old_state->dev;
440
+ struct rcar_du_device *rcdu = dev->dev_private;
441
+ struct drm_crtc_state *crtc_state;
442
+ struct drm_crtc *crtc;
443
+ unsigned int i;
444
+
445
+ /*
446
+ * Store RGB routing to DPAD0 and DPAD1, the hardware will be configured
447
+ * when starting the CRTCs.
448
+ */
449
+ rcdu->dpad1_source = -1;
450
+
451
+ for_each_new_crtc_in_state(old_state, crtc, crtc_state, i) {
452
+ struct rcar_du_crtc_state *rcrtc_state =
453
+ to_rcar_crtc_state(crtc_state);
454
+ struct rcar_du_crtc *rcrtc = to_rcar_crtc(crtc);
455
+
456
+ if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD0))
457
+ rcdu->dpad0_source = rcrtc->index;
458
+
459
+ if (rcrtc_state->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
460
+ rcdu->dpad1_source = rcrtc->index;
461
+ }
249462
250463 /* Apply the atomic update. */
251464 drm_atomic_helper_commit_modeset_disables(dev, old_state);
....@@ -269,7 +482,6 @@
269482
270483 static const struct drm_mode_config_funcs rcar_du_mode_config_funcs = {
271484 .fb_create = rcar_du_fb_create,
272
- .output_poll_changed = rcar_du_output_poll_changed,
273485 .atomic_check = rcar_du_atomic_check,
274486 .atomic_commit = drm_atomic_helper_commit,
275487 };
....@@ -278,17 +490,10 @@
278490 enum rcar_du_output output,
279491 struct of_endpoint *ep)
280492 {
281
- struct device_node *connector = NULL;
282
- struct device_node *encoder = NULL;
283
- struct device_node *ep_node = NULL;
284
- struct device_node *entity_ep_node;
285493 struct device_node *entity;
286494 int ret;
287495
288
- /*
289
- * Locate the connected entity and infer its type from the number of
290
- * endpoints.
291
- */
496
+ /* Locate the connected entity and initialize the encoder. */
292497 entity = of_graph_get_remote_port_parent(ep->local_node);
293498 if (!entity) {
294499 dev_dbg(rcdu->dev, "unconnected endpoint %pOF, skipping\n",
....@@ -304,50 +509,13 @@
304509 return -ENODEV;
305510 }
306511
307
- entity_ep_node = of_graph_get_remote_endpoint(ep->local_node);
308
-
309
- for_each_endpoint_of_node(entity, ep_node) {
310
- if (ep_node == entity_ep_node)
311
- continue;
312
-
313
- /*
314
- * We've found one endpoint other than the input, this must
315
- * be an encoder. Locate the connector.
316
- */
317
- encoder = entity;
318
- connector = of_graph_get_remote_port_parent(ep_node);
319
- of_node_put(ep_node);
320
-
321
- if (!connector) {
322
- dev_warn(rcdu->dev,
323
- "no connector for encoder %pOF, skipping\n",
324
- encoder);
325
- of_node_put(entity_ep_node);
326
- of_node_put(encoder);
327
- return -ENODEV;
328
- }
329
-
330
- break;
331
- }
332
-
333
- of_node_put(entity_ep_node);
334
-
335
- if (!encoder) {
336
- dev_warn(rcdu->dev,
337
- "no encoder found for endpoint %pOF, skipping\n",
338
- ep->local_node);
339
- of_node_put(entity);
340
- return -ENODEV;
341
- }
342
-
343
- ret = rcar_du_encoder_init(rcdu, output, encoder, connector);
344
- if (ret && ret != -EPROBE_DEFER)
512
+ ret = rcar_du_encoder_init(rcdu, output, entity);
513
+ if (ret && ret != -EPROBE_DEFER && ret != -ENOLINK)
345514 dev_warn(rcdu->dev,
346515 "failed to initialize encoder %pOF on output %u (%d), skipping\n",
347
- encoder, output, ret);
516
+ entity, output, ret);
348517
349
- of_node_put(encoder);
350
- of_node_put(connector);
518
+ of_node_put(entity);
351519
352520 return ret;
353521 }
....@@ -426,6 +594,7 @@
426594 static int rcar_du_vsps_init(struct rcar_du_device *rcdu)
427595 {
428596 const struct device_node *np = rcdu->dev->of_node;
597
+ const char *vsps_prop_name = "renesas,vsps";
429598 struct of_phandle_args args;
430599 struct {
431600 struct device_node *np;
....@@ -441,15 +610,21 @@
441610 * entry contains a pointer to the VSP DT node and a bitmask of the
442611 * connected DU CRTCs.
443612 */
444
- cells = of_property_count_u32_elems(np, "vsps") / rcdu->num_crtcs - 1;
613
+ ret = of_property_count_u32_elems(np, vsps_prop_name);
614
+ if (ret < 0) {
615
+ /* Backward compatibility with old DTBs. */
616
+ vsps_prop_name = "vsps";
617
+ ret = of_property_count_u32_elems(np, vsps_prop_name);
618
+ }
619
+ cells = ret / rcdu->num_crtcs - 1;
445620 if (cells > 1)
446621 return -EINVAL;
447622
448623 for (i = 0; i < rcdu->num_crtcs; ++i) {
449624 unsigned int j;
450625
451
- ret = of_parse_phandle_with_fixed_args(np, "vsps", cells, i,
452
- &args);
626
+ ret = of_parse_phandle_with_fixed_args(np, vsps_prop_name,
627
+ cells, i, &args);
453628 if (ret < 0)
454629 goto error;
455630
....@@ -469,7 +644,11 @@
469644
470645 vsps[j].crtcs_mask |= BIT(i);
471646
472
- /* Store the VSP pointer and pipe index in the CRTC. */
647
+ /*
648
+ * Store the VSP pointer and pipe index in the CRTC. If the
649
+ * second cell of the 'renesas,vsps' specifier isn't present,
650
+ * default to 0 to remain compatible with older DT bindings.
651
+ */
473652 rcdu->crtcs[i].vsp = &rcdu->vsps[j];
474653 rcdu->crtcs[i].vsp_pipe = cells >= 1 ? args.args[0] : 0;
475654 }
....@@ -498,6 +677,75 @@
498677 return ret;
499678 }
500679
680
+static int rcar_du_cmm_init(struct rcar_du_device *rcdu)
681
+{
682
+ const struct device_node *np = rcdu->dev->of_node;
683
+ unsigned int i;
684
+ int cells;
685
+
686
+ cells = of_property_count_u32_elems(np, "renesas,cmms");
687
+ if (cells == -EINVAL)
688
+ return 0;
689
+
690
+ if (cells > rcdu->num_crtcs) {
691
+ dev_err(rcdu->dev,
692
+ "Invalid number of entries in 'renesas,cmms'\n");
693
+ return -EINVAL;
694
+ }
695
+
696
+ for (i = 0; i < cells; ++i) {
697
+ struct platform_device *pdev;
698
+ struct device_link *link;
699
+ struct device_node *cmm;
700
+ int ret;
701
+
702
+ cmm = of_parse_phandle(np, "renesas,cmms", i);
703
+ if (!cmm) {
704
+ dev_err(rcdu->dev,
705
+ "Failed to parse 'renesas,cmms' property\n");
706
+ return -EINVAL;
707
+ }
708
+
709
+ if (!of_device_is_available(cmm)) {
710
+ /* It's fine to have a phandle to a non-enabled CMM. */
711
+ of_node_put(cmm);
712
+ continue;
713
+ }
714
+
715
+ pdev = of_find_device_by_node(cmm);
716
+ if (!pdev) {
717
+ dev_err(rcdu->dev, "No device found for CMM%u\n", i);
718
+ of_node_put(cmm);
719
+ return -EINVAL;
720
+ }
721
+
722
+ of_node_put(cmm);
723
+
724
+ /*
725
+ * -ENODEV is used to report that the CMM config option is
726
+ * disabled: return 0 and let the DU continue probing.
727
+ */
728
+ ret = rcar_cmm_init(pdev);
729
+ if (ret)
730
+ return ret == -ENODEV ? 0 : ret;
731
+
732
+ /*
733
+ * Enforce suspend/resume ordering by making the CMM a provider
734
+ * of the DU: CMM is suspended after and resumed before the DU.
735
+ */
736
+ link = device_link_add(rcdu->dev, &pdev->dev, DL_FLAG_STATELESS);
737
+ if (!link) {
738
+ dev_err(rcdu->dev,
739
+ "Failed to create device link to CMM%u\n", i);
740
+ return -EINVAL;
741
+ }
742
+
743
+ rcdu->cmms[i] = pdev;
744
+ }
745
+
746
+ return 0;
747
+}
748
+
501749 int rcar_du_modeset_init(struct rcar_du_device *rcdu)
502750 {
503751 static const unsigned int mmio_offsets[] = {
....@@ -506,7 +754,7 @@
506754
507755 struct drm_device *dev = rcdu->ddev;
508756 struct drm_encoder *encoder;
509
- struct drm_fbdev_cma *fbdev;
757
+ unsigned int dpad0_sources;
510758 unsigned int num_encoders;
511759 unsigned int num_groups;
512760 unsigned int swindex;
....@@ -514,7 +762,9 @@
514762 unsigned int i;
515763 int ret;
516764
517
- drm_mode_config_init(dev);
765
+ ret = drmm_mode_config_init(dev);
766
+ if (ret)
767
+ return ret;
518768
519769 dev->mode_config.min_width = 0;
520770 dev->mode_config.min_height = 0;
....@@ -588,6 +838,11 @@
588838 return ret;
589839 }
590840
841
+ /* Initialize the Color Management Modules. */
842
+ ret = rcar_du_cmm_init(rcdu);
843
+ if (ret)
844
+ return ret;
845
+
591846 /* Create the CRTCs. */
592847 for (swindex = 0, hwindex = 0; swindex < rcdu->num_crtcs; ++hwindex) {
593848 struct rcar_du_group *rgrp;
....@@ -629,21 +884,31 @@
629884 encoder->possible_clones = (1 << num_encoders) - 1;
630885 }
631886
887
+ /* Create the writeback connectors. */
888
+ if (rcdu->info->gen >= 3) {
889
+ for (i = 0; i < rcdu->num_crtcs; ++i) {
890
+ struct rcar_du_crtc *rcrtc = &rcdu->crtcs[i];
891
+
892
+ ret = rcar_du_writeback_init(rcdu, rcrtc);
893
+ if (ret < 0)
894
+ return ret;
895
+ }
896
+ }
897
+
898
+ /*
899
+ * Initialize the default DPAD0 source to the index of the first DU
900
+ * channel that can be connected to DPAD0. The exact value doesn't
901
+ * matter as it should be overwritten by mode setting for the RGB
902
+ * output, but it is nonetheless required to ensure a valid initial
903
+ * hardware configuration on Gen3 where DU0 can't always be connected to
904
+ * DPAD0.
905
+ */
906
+ dpad0_sources = rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
907
+ rcdu->dpad0_source = ffs(dpad0_sources) - 1;
908
+
632909 drm_mode_config_reset(dev);
633910
634911 drm_kms_helper_poll_init(dev);
635
-
636
- if (dev->mode_config.num_connector) {
637
- fbdev = drm_fbdev_cma_init(dev, 32,
638
- dev->mode_config.num_connector);
639
- if (IS_ERR(fbdev))
640
- return PTR_ERR(fbdev);
641
-
642
- rcdu->fbdev = fbdev;
643
- } else {
644
- dev_info(rcdu->dev,
645
- "no connector found, disabling fbdev emulation\n");
646
- }
647912
648913 return 0;
649914 }