hc
2023-12-11 6778948f9de86c3cfaf36725a7c87dcff9ba247f
kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
....@@ -83,10 +83,24 @@
8383 enum lvds_format {
8484 LVDS_8BIT_MODE_FORMAT_1,
8585 LVDS_8BIT_MODE_FORMAT_2,
86
- LVDS_8BIT_MODE_FORMAT_3,
87
- LVDS_6BIT_MODE,
86
+ LVDS_6BIT_MODE_FORMAT_1,
87
+ LVDS_6BIT_MODE_FORMAT_2,
8888 LVDS_10BIT_MODE_FORMAT_1,
8989 LVDS_10BIT_MODE_FORMAT_2,
90
+};
91
+
92
+enum rockchip_lvds_dual_link_pixels {
93
+ ROCKCHIP_LVDS_DUAL_LINK_EVEN_ODD_PIXELS = 0,
94
+ ROCKCHIP_LVDS_DUAL_LINK_ODD_EVEN_PIXELS = 1,
95
+ ROCKCHIP_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS = 2,
96
+ ROCKCHIP_LVDS_DUAL_LINK_RIGHT_LEFT_PIXELS = 3,
97
+};
98
+
99
+enum rockchip_of_lvds_pixels {
100
+ ROCKCHIP_OF_LVDS_EVEN = BIT(0),
101
+ ROCKCHIP_OF_LVDS_ODD = BIT(1),
102
+ ROCKCHIP_OF_LVDS_LEFT = BIT(2),
103
+ ROCKCHIP_OF_LVDS_RIGHT = BIT(3),
90104 };
91105
92106 struct rockchip_lvds;
....@@ -107,7 +121,7 @@
107121 bool data_swap;
108122 bool dual_channel;
109123 bool phy_enabled;
110
- enum drm_lvds_dual_link_pixels pixel_order;
124
+ enum rockchip_lvds_dual_link_pixels pixel_order;
111125
112126 struct rockchip_lvds *primary;
113127 struct rockchip_lvds *secondary;
....@@ -119,6 +133,99 @@
119133 struct drm_display_mode mode;
120134 struct rockchip_drm_sub_dev sub_dev;
121135 };
136
+
137
+static int rockchip_of_lvds_get_port_pixels_type(struct device_node *port_node)
138
+{
139
+ bool even_pixels =
140
+ of_property_read_bool(port_node, "dual-lvds-even-pixels");
141
+ bool odd_pixels =
142
+ of_property_read_bool(port_node, "dual-lvds-odd-pixels");
143
+ bool left_pixels =
144
+ of_property_read_bool(port_node, "dual-lvds-left-pixels");
145
+ bool right_pixels =
146
+ of_property_read_bool(port_node, "dual-lvds-right-pixels");
147
+
148
+ return (even_pixels ? ROCKCHIP_OF_LVDS_EVEN : 0) |
149
+ (odd_pixels ? ROCKCHIP_OF_LVDS_ODD : 0) |
150
+ (left_pixels ? ROCKCHIP_OF_LVDS_LEFT : 0) |
151
+ (right_pixels ? ROCKCHIP_OF_LVDS_RIGHT : 0);
152
+}
153
+
154
+static int rockchip_of_lvds_get_remote_pixels_type(
155
+ const struct device_node *port_node)
156
+{
157
+ struct device_node *endpoint = NULL;
158
+ int pixels_type = -EPIPE;
159
+
160
+ for_each_child_of_node(port_node, endpoint) {
161
+ struct device_node *remote_port;
162
+ int current_pt;
163
+
164
+ if (!of_node_name_eq(endpoint, "endpoint"))
165
+ continue;
166
+
167
+ remote_port = of_graph_get_remote_port(endpoint);
168
+ if (!remote_port) {
169
+ of_node_put(endpoint);
170
+ return -EPIPE;
171
+ }
172
+
173
+ current_pt = rockchip_of_lvds_get_port_pixels_type(remote_port);
174
+ of_node_put(remote_port);
175
+ if (pixels_type < 0)
176
+ pixels_type = current_pt;
177
+
178
+ /*
179
+ * Sanity check, ensure that all remote endpoints have the same
180
+ * pixel type. We may lift this restriction later if we need to
181
+ * support multiple sinks with different dual-link
182
+ * configurations by passing the endpoints explicitly to
183
+ * rockchip_of_lvds_get_dual_link_pixel_order().
184
+ */
185
+ if (!current_pt || pixels_type != current_pt) {
186
+ of_node_put(endpoint);
187
+ return -EINVAL;
188
+ }
189
+ }
190
+
191
+ return pixels_type;
192
+}
193
+
194
+static int rockchip_of_lvds_get_dual_link_pixel_order(const struct device_node *port1,
195
+ const struct device_node *port2)
196
+{
197
+ int remote_p1_pt, remote_p2_pt;
198
+
199
+ if (!port1 || !port2)
200
+ return -EINVAL;
201
+
202
+ remote_p1_pt = rockchip_of_lvds_get_remote_pixels_type(port1);
203
+ if (remote_p1_pt < 0)
204
+ return remote_p1_pt;
205
+
206
+ remote_p2_pt = rockchip_of_lvds_get_remote_pixels_type(port2);
207
+ if (remote_p2_pt < 0)
208
+ return remote_p2_pt;
209
+
210
+ /*
211
+ * A valid dual-lVDS bus is found when one remote port is marked with
212
+ * "dual-lvds-even-pixels" or "dual-lvds-left-pixels", and the other
213
+ * remote port is marked with "dual-lvds-odd-pixels"or
214
+ * "dual-lvds-right-pixels", bail out if the markers are not right.
215
+ */
216
+ if ((remote_p1_pt + remote_p2_pt != ROCKCHIP_OF_LVDS_EVEN + ROCKCHIP_OF_LVDS_ODD) &&
217
+ (remote_p1_pt + remote_p2_pt != ROCKCHIP_OF_LVDS_LEFT + ROCKCHIP_OF_LVDS_RIGHT))
218
+ return -EINVAL;
219
+
220
+ if (remote_p1_pt == ROCKCHIP_OF_LVDS_EVEN)
221
+ return ROCKCHIP_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
222
+ else if (remote_p1_pt == ROCKCHIP_OF_LVDS_ODD)
223
+ return ROCKCHIP_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
224
+ else if (remote_p1_pt == ROCKCHIP_OF_LVDS_LEFT)
225
+ return ROCKCHIP_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS;
226
+ else
227
+ return ROCKCHIP_LVDS_DUAL_LINK_RIGHT_LEFT_PIXELS;
228
+}
122229
123230 static inline struct rockchip_lvds *connector_to_lvds(struct drm_connector *c)
124231 {
....@@ -190,8 +297,8 @@
190297 case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA: /* jeida-30 */
191298 lvds->format = LVDS_10BIT_MODE_FORMAT_2;
192299 break;
193
- case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* vesa-18 */
194
- lvds->format = LVDS_8BIT_MODE_FORMAT_3;
300
+ case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* jeida-18, compatible with the [JEIDA], [LDI] and [VESA] specifications */
301
+ lvds->format = LVDS_6BIT_MODE_FORMAT_1;
195302 break;
196303 case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG: /* vesa-30 */
197304 lvds->format = LVDS_10BIT_MODE_FORMAT_1;
....@@ -236,29 +343,24 @@
236343 s->color_space = V4L2_COLORSPACE_DEFAULT;
237344
238345 switch (lvds->pixel_order) {
239
- case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
346
+ case ROCKCHIP_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
240347 s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE;
241348 s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
242349 break;
243
- case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
350
+ case ROCKCHIP_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
244351 s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE;
245352 s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
246353 s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
247354 break;
248
-/*
249
- * Fix me: To do it with a GKI compatible version.
250
- */
251
-#if 0
252
- case DRM_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS:
355
+ case ROCKCHIP_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS:
253356 s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
254357 s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
255358 break;
256
- case DRM_LVDS_DUAL_LINK_RIGHT_LEFT_PIXELS:
359
+ case ROCKCHIP_LVDS_DUAL_LINK_RIGHT_LEFT_PIXELS:
257360 s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
258361 s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
259362 s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
260363 break;
261
-#endif
262364 default:
263365 if (lvds->id)
264366 s->output_if |= VOP_OUTPUT_IF_LVDS1;
....@@ -646,7 +748,7 @@
646748 .disable = rk3368_lvds_disable,
647749 };
648750
649
-static int __maybe_unused rockchip_secondary_lvds_probe(struct rockchip_lvds *lvds)
751
+static int rk3568_lvds_probe(struct rockchip_lvds *lvds)
650752 {
651753 if (lvds->dual_channel) {
652754 struct rockchip_lvds *secondary = NULL;
....@@ -659,7 +761,7 @@
659761
660762 port0 = of_graph_get_port_by_id(lvds->dev->of_node, 1);
661763 port1 = of_graph_get_port_by_id(secondary->dev->of_node, 1);
662
- pixel_order = drm_of_lvds_get_dual_link_pixel_order(port0, port1);
764
+ pixel_order = rockchip_of_lvds_get_dual_link_pixel_order(port0, port1);
663765 of_node_put(port1);
664766 of_node_put(port0);
665767
....@@ -692,19 +794,37 @@
692794
693795 static void rk3568_lvds_enable(struct rockchip_lvds *lvds)
694796 {
695
- regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
696
- RK3568_LVDS0_MODE_EN(1) | RK3568_LVDS0_P2S_EN(1) |
697
- RK3568_LVDS0_DCLK_INV_SEL(1));
698
- regmap_write(lvds->grf, RK3568_GRF_VO_CON0,
699
- RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1));
797
+ if (lvds->id) {
798
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON3,
799
+ RK3568_LVDS1_MODE_EN(1) |
800
+ RK3568_LVDS1_P2S_EN(1) |
801
+ RK3568_LVDS1_DCLK_INV_SEL(1));
802
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON0,
803
+ RK3568_LVDS1_SELECT(lvds->format) |
804
+ RK3568_LVDS1_MSBSEL(1));
805
+ } else {
806
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
807
+ RK3568_LVDS0_MODE_EN(1) |
808
+ RK3568_LVDS0_P2S_EN(1) |
809
+ RK3568_LVDS0_DCLK_INV_SEL(1));
810
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON0,
811
+ RK3568_LVDS0_SELECT(lvds->format) |
812
+ RK3568_LVDS0_MSBSEL(1));
813
+ }
700814 }
701815
702816 static void rk3568_lvds_disable(struct rockchip_lvds *lvds)
703817 {
704
- regmap_write(lvds->grf, RK3568_GRF_VO_CON2, RK3568_LVDS0_MODE_EN(0));
818
+ if (lvds->id)
819
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON3,
820
+ RK3568_LVDS1_MODE_EN(0));
821
+ else
822
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
823
+ RK3568_LVDS0_MODE_EN(0));
705824 }
706825
707826 static const struct rockchip_lvds_funcs rk3568_lvds_funcs = {
827
+ .probe = rk3568_lvds_probe,
708828 .enable = rk3568_lvds_enable,
709829 .disable = rk3568_lvds_disable,
710830 };