forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/rcar-du/rcar_du_group.c
....@@ -1,14 +1,10 @@
1
+// SPDX-License-Identifier: GPL-2.0+
12 /*
23 * rcar_du_group.c -- R-Car Display Unit Channels Pair
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
1410 /*
....@@ -60,8 +56,6 @@
6056 static void rcar_du_group_setup_defr8(struct rcar_du_group *rgrp)
6157 {
6258 struct rcar_du_device *rcdu = rgrp->dev;
63
- unsigned int possible_crtcs =
64
- rcdu->info->routes[RCAR_DU_OUTPUT_DPAD0].possible_crtcs;
6559 u32 defr8 = DEFR8_CODE;
6660
6761 if (rcdu->info->gen < 3) {
....@@ -73,29 +67,75 @@
7367 * DU instances that support it.
7468 */
7569 if (rgrp->index == 0) {
76
- if (possible_crtcs > 1)
77
- defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
70
+ defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
7871 if (rgrp->dev->vspd1_sink == 2)
7972 defr8 |= DEFR8_VSCS;
8073 }
8174 } else {
8275 /*
83
- * On Gen3 VSPD routing can't be configured, but DPAD routing
84
- * needs to be set despite having a single option available.
76
+ * On Gen3 VSPD routing can't be configured, and DPAD routing
77
+ * is set in the group corresponding to the DPAD output (no Gen3
78
+ * SoC has multiple DPAD sources belonging to separate groups).
8579 */
86
- unsigned int rgb_crtc = ffs(possible_crtcs) - 1;
87
- struct rcar_du_crtc *crtc = &rcdu->crtcs[rgb_crtc];
88
-
89
- if (crtc->index / 2 == rgrp->index)
90
- defr8 |= DEFR8_DRGBS_DU(crtc->index);
80
+ if (rgrp->index == rcdu->dpad0_source / 2)
81
+ defr8 |= DEFR8_DRGBS_DU(rcdu->dpad0_source);
9182 }
9283
9384 rcar_du_group_write(rgrp, DEFR8, defr8);
9485 }
9586
87
+static void rcar_du_group_setup_didsr(struct rcar_du_group *rgrp)
88
+{
89
+ struct rcar_du_device *rcdu = rgrp->dev;
90
+ struct rcar_du_crtc *rcrtc;
91
+ unsigned int num_crtcs = 0;
92
+ unsigned int i;
93
+ u32 didsr;
94
+
95
+ /*
96
+ * Configure input dot clock routing with a hardcoded configuration. If
97
+ * the DU channel can use the LVDS encoder output clock as the dot
98
+ * clock, do so. Otherwise route DU_DOTCLKINn signal to DUn.
99
+ *
100
+ * Each channel can then select between the dot clock configured here
101
+ * and the clock provided by the CPG through the ESCR register.
102
+ */
103
+ if (rcdu->info->gen < 3 && rgrp->index == 0) {
104
+ /*
105
+ * On Gen2 a single register in the first group controls dot
106
+ * clock selection for all channels.
107
+ */
108
+ rcrtc = rcdu->crtcs;
109
+ num_crtcs = rcdu->num_crtcs;
110
+ } else if (rcdu->info->gen == 3 && rgrp->num_crtcs > 1) {
111
+ /*
112
+ * On Gen3 dot clocks are setup through per-group registers,
113
+ * only available when the group has two channels.
114
+ */
115
+ rcrtc = &rcdu->crtcs[rgrp->index * 2];
116
+ num_crtcs = rgrp->num_crtcs;
117
+ }
118
+
119
+ if (!num_crtcs)
120
+ return;
121
+
122
+ didsr = DIDSR_CODE;
123
+ for (i = 0; i < num_crtcs; ++i, ++rcrtc) {
124
+ if (rcdu->info->lvds_clk_mask & BIT(rcrtc->index))
125
+ didsr |= DIDSR_LCDS_LVDS0(i)
126
+ | DIDSR_PDCS_CLK(i, 0);
127
+ else
128
+ didsr |= DIDSR_LCDS_DCLKIN(i)
129
+ | DIDSR_PDCS_CLK(i, 0);
130
+ }
131
+
132
+ rcar_du_group_write(rgrp, DIDSR, didsr);
133
+}
134
+
96135 static void rcar_du_group_setup(struct rcar_du_group *rgrp)
97136 {
98137 struct rcar_du_device *rcdu = rgrp->dev;
138
+ u32 defr7 = DEFR7_CODE;
99139
100140 /* Enable extended features */
101141 rcar_du_group_write(rgrp, DEFR, DEFR_CODE | DEFR_DEFE);
....@@ -108,23 +148,18 @@
108148
109149 rcar_du_group_setup_pins(rgrp);
110150
111
- if (rcar_du_has(rgrp->dev, RCAR_DU_FEATURE_EXT_CTRL_REGS)) {
112
- rcar_du_group_setup_defr8(rgrp);
151
+ /*
152
+ * TODO: Handle routing of the DU output to CMM dynamically, as we
153
+ * should bypass CMM completely when no color management feature is
154
+ * used.
155
+ */
156
+ defr7 |= (rgrp->cmms_mask & BIT(1) ? DEFR7_CMME1 : 0) |
157
+ (rgrp->cmms_mask & BIT(0) ? DEFR7_CMME0 : 0);
158
+ rcar_du_group_write(rgrp, DEFR7, defr7);
113159
114
- /*
115
- * Configure input dot clock routing. We currently hardcode the
116
- * configuration to routing DOTCLKINn to DUn. Register fields
117
- * depend on the DU generation, but the resulting value is 0 in
118
- * all cases.
119
- *
120
- * On Gen2 a single register in the first group controls dot
121
- * clock selection for all channels, while on Gen3 dot clocks
122
- * are setup through per-group registers, only available when
123
- * the group has two channels.
124
- */
125
- if ((rcdu->info->gen < 3 && rgrp->index == 0) ||
126
- (rcdu->info->gen == 3 && rgrp->num_crtcs > 1))
127
- rcar_du_group_write(rgrp, DIDSR, DIDSR_CODE);
160
+ if (rcdu->info->gen >= 2) {
161
+ rcar_du_group_setup_defr8(rgrp);
162
+ rcar_du_group_setup_didsr(rgrp);
128163 }
129164
130165 if (rcdu->info->gen >= 3)
....@@ -177,9 +212,25 @@
177212
178213 static void __rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
179214 {
180
- rcar_du_group_write(rgrp, DSYSR,
181
- (rcar_du_group_read(rgrp, DSYSR) & ~(DSYSR_DRES | DSYSR_DEN)) |
182
- (start ? DSYSR_DEN : DSYSR_DRES));
215
+ struct rcar_du_device *rcdu = rgrp->dev;
216
+
217
+ /*
218
+ * Group start/stop is controlled by the DRES and DEN bits of DSYSR0
219
+ * for the first group and DSYSR2 for the second group. On most DU
220
+ * instances, this maps to the first CRTC of the group, and we can just
221
+ * use rcar_du_crtc_dsysr_clr_set() to access the correct DSYSR. On
222
+ * M3-N, however, DU2 doesn't exist, but DSYSR2 does. We thus need to
223
+ * access the register directly using group read/write.
224
+ */
225
+ if (rcdu->info->channels_mask & BIT(rgrp->index * 2)) {
226
+ struct rcar_du_crtc *rcrtc = &rgrp->dev->crtcs[rgrp->index * 2];
227
+
228
+ rcar_du_crtc_dsysr_clr_set(rcrtc, DSYSR_DRES | DSYSR_DEN,
229
+ start ? DSYSR_DEN : DSYSR_DRES);
230
+ } else {
231
+ rcar_du_group_write(rgrp, DSYSR,
232
+ start ? DSYSR_DEN : DSYSR_DRES);
233
+ }
183234 }
184235
185236 void rcar_du_group_start_stop(struct rcar_du_group *rgrp, bool start)
....@@ -221,7 +272,7 @@
221272 unsigned int index;
222273 int ret;
223274
224
- if (!rcar_du_has(rcdu, RCAR_DU_FEATURE_EXT_CTRL_REGS))
275
+ if (rcdu->info->gen < 2)
225276 return 0;
226277
227278 /*
....@@ -246,9 +297,50 @@
246297 return 0;
247298 }
248299
300
+static void rcar_du_group_set_dpad_levels(struct rcar_du_group *rgrp)
301
+{
302
+ static const u32 doflr_values[2] = {
303
+ DOFLR_HSYCFL0 | DOFLR_VSYCFL0 | DOFLR_ODDFL0 |
304
+ DOFLR_DISPFL0 | DOFLR_CDEFL0 | DOFLR_RGBFL0,
305
+ DOFLR_HSYCFL1 | DOFLR_VSYCFL1 | DOFLR_ODDFL1 |
306
+ DOFLR_DISPFL1 | DOFLR_CDEFL1 | DOFLR_RGBFL1,
307
+ };
308
+ static const u32 dpad_mask = BIT(RCAR_DU_OUTPUT_DPAD1)
309
+ | BIT(RCAR_DU_OUTPUT_DPAD0);
310
+ struct rcar_du_device *rcdu = rgrp->dev;
311
+ u32 doflr = DOFLR_CODE;
312
+ unsigned int i;
313
+
314
+ if (rcdu->info->gen < 2)
315
+ return;
316
+
317
+ /*
318
+ * The DPAD outputs can't be controlled directly. However, the parallel
319
+ * output of the DU channels routed to DPAD can be set to fixed levels
320
+ * through the DOFLR group register. Use this to turn the DPAD on or off
321
+ * by driving fixed low-level signals at the output of any DU channel
322
+ * not routed to a DPAD output. This doesn't affect the DU output
323
+ * signals going to other outputs, such as the internal LVDS and HDMI
324
+ * encoders.
325
+ */
326
+
327
+ for (i = 0; i < rgrp->num_crtcs; ++i) {
328
+ struct rcar_du_crtc_state *rstate;
329
+ struct rcar_du_crtc *rcrtc;
330
+
331
+ rcrtc = &rcdu->crtcs[rgrp->index * 2 + i];
332
+ rstate = to_rcar_crtc_state(rcrtc->crtc.state);
333
+
334
+ if (!(rstate->outputs & dpad_mask))
335
+ doflr |= doflr_values[i];
336
+ }
337
+
338
+ rcar_du_group_write(rgrp, DOFLR, doflr);
339
+}
340
+
249341 int rcar_du_group_set_routing(struct rcar_du_group *rgrp)
250342 {
251
- struct rcar_du_crtc *crtc0 = &rgrp->dev->crtcs[rgrp->index * 2];
343
+ struct rcar_du_device *rcdu = rgrp->dev;
252344 u32 dorcr = rcar_du_group_read(rgrp, DORCR);
253345
254346 dorcr &= ~(DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_MASK);
....@@ -258,12 +350,14 @@
258350 * CRTC 1 in all other cases to avoid cloning CRTC 0 to DPAD0 and DPAD1
259351 * by default.
260352 */
261
- if (crtc0->outputs & BIT(RCAR_DU_OUTPUT_DPAD1))
353
+ if (rcdu->dpad1_source == rgrp->index * 2)
262354 dorcr |= DORCR_PG2D_DS1;
263355 else
264356 dorcr |= DORCR_PG2T | DORCR_DK2S | DORCR_PG2D_DS2;
265357
266358 rcar_du_group_write(rgrp, DORCR, dorcr);
267359
360
+ rcar_du_group_set_dpad_levels(rgrp);
361
+
268362 return rcar_du_set_dpad0_vsp1_routing(rgrp->dev);
269363 }