forked from ~ljy/RK356X_SDK_RELEASE

hc
2023-12-09 95099d4622f8cb224d94e314c7a8e0df60b13f87
kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
....@@ -1,30 +1,24 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
34 * Author:
45 * Mark Yao <mark.yao@rock-chips.com>
56 * Sandy Huang <hjc@rock-chips.com>
6
- *
7
- * This software is licensed under the terms of the GNU General Public
8
- * License version 2, as published by the Free Software Foundation, and
9
- * may be copied, distributed, and modified under those terms.
10
- *
11
- * This program is distributed in the hope that it will be useful,
12
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
13
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
- * GNU General Public License for more details.
157 */
16
-
17
-#include <drm/drm_atomic_helper.h>
18
-#include <drm/drm_crtc_helper.h>
19
-#include <drm/drm_panel.h>
20
-#include <drm/drm_of.h>
218
229 #include <linux/component.h>
2310 #include <linux/mfd/syscon.h>
24
-#include <linux/of_device.h>
2511 #include <linux/of_graph.h>
26
-#include <linux/regmap.h>
2712 #include <linux/phy/phy.h>
13
+#include <linux/of_platform.h>
14
+#include <linux/regmap.h>
15
+#include <drm/drm_atomic_helper.h>
16
+#include <drm/drm_bridge.h>
17
+#include <drm/drm_of.h>
18
+#include <drm/drm_panel.h>
19
+#include <drm/drm_probe_helper.h>
20
+#include <drm/drm_simple_kms_helper.h>
21
+
2822 #include <uapi/linux/videodev2.h>
2923
3024 #include "rockchip_drm_drv.h"
....@@ -66,6 +60,9 @@
6660 #define RK3368_LVDS_MODE_EN(x) HIWORD_UPDATE(x, 12, 12)
6761 #define RK3368_LVDS_MSBSEL(x) HIWORD_UPDATE(x, 11, 11)
6862 #define RK3368_LVDS_P2S_EN(x) HIWORD_UPDATE(x, 6, 6)
63
+
64
+#define RK3562_GRF_VO_CON0 0x05d0
65
+#define RK3562_GRF_VO_CON1 0x05d4
6966
7067 #define RK3568_GRF_VO_CON0 0x0360
7168 #define RK3568_LVDS1_SELECT(x) HIWORD_UPDATE(x, 13, 12)
....@@ -109,6 +106,7 @@
109106 enum lvds_format format;
110107 bool data_swap;
111108 bool dual_channel;
109
+ bool phy_enabled;
112110 enum drm_lvds_dual_link_pixels pixel_order;
113111
114112 struct rockchip_lvds *primary;
....@@ -164,7 +162,7 @@
164162 struct rockchip_lvds *lvds = connector_to_lvds(connector);
165163 struct drm_panel *panel = lvds->panel;
166164
167
- return drm_panel_get_modes(panel);
165
+ return drm_panel_get_modes(panel, connector);
168166 }
169167
170168 static const
....@@ -186,9 +184,6 @@
186184 bus_format = info->bus_formats[0];
187185
188186 switch (bus_format) {
189
- case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: /* jeida-18 */
190
- lvds->format = LVDS_6BIT_MODE;
191
- break;
192187 case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* jeida-24 */
193188 lvds->format = LVDS_8BIT_MODE_FORMAT_2;
194189 break;
....@@ -237,7 +232,7 @@
237232 s->output_type = DRM_MODE_CONNECTOR_LVDS;
238233 s->bus_flags = info->bus_flags;
239234 s->tv_state = &conn_state->tv;
240
- s->eotf = TRADITIONAL_GAMMA_SDR;
235
+ s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
241236 s->color_space = V4L2_COLORSPACE_DEFAULT;
242237
243238 switch (lvds->pixel_order) {
....@@ -250,6 +245,10 @@
250245 s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
251246 s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
252247 break;
248
+/*
249
+ * Fix me: To do it with a GKI compatible version.
250
+ */
251
+#if 0
253252 case DRM_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS:
254253 s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
255254 s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
....@@ -259,6 +258,7 @@
259258 s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
260259 s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
261260 break;
261
+#endif
262262 default:
263263 if (lvds->id)
264264 s->output_if |= VOP_OUTPUT_IF_LVDS1;
....@@ -277,13 +277,16 @@
277277 if (lvds->funcs->enable)
278278 lvds->funcs->enable(lvds);
279279
280
- ret = phy_set_mode(lvds->phy, PHY_MODE_VIDEO_LVDS);
280
+ ret = phy_set_mode(lvds->phy, PHY_MODE_LVDS);
281281 if (ret) {
282282 DRM_DEV_ERROR(lvds->dev, "failed to set phy mode: %d\n", ret);
283283 return;
284284 }
285285
286
- phy_power_on(lvds->phy);
286
+ if (lvds->phy && !lvds->phy_enabled) {
287
+ phy_power_on(lvds->phy);
288
+ lvds->phy_enabled = true;
289
+ }
287290
288291 if (lvds->secondary)
289292 rockchip_lvds_enable(lvds->secondary);
....@@ -294,7 +297,10 @@
294297 if (lvds->funcs->disable)
295298 lvds->funcs->disable(lvds);
296299
297
- phy_power_off(lvds->phy);
300
+ if (lvds->phy && lvds->phy_enabled) {
301
+ phy_power_off(lvds->phy);
302
+ lvds->phy_enabled = false;
303
+ }
298304
299305 if (lvds->secondary)
300306 rockchip_lvds_disable(lvds->secondary);
....@@ -328,7 +334,22 @@
328334 struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
329335
330336 if (lvds->panel)
331
- return drm_panel_loader_protect(lvds->panel, on);
337
+ panel_simple_loader_protect(lvds->panel);
338
+
339
+
340
+ if (on) {
341
+ phy_init(lvds->phy);
342
+ if (lvds->phy) {
343
+ lvds->phy->power_count++;
344
+ lvds->phy_enabled = true;
345
+ }
346
+ } else {
347
+ phy_exit(lvds->phy);
348
+ if (lvds->phy) {
349
+ lvds->phy->power_count--;
350
+ lvds->phy_enabled = false;
351
+ }
352
+ }
332353
333354 return 0;
334355 }
....@@ -339,23 +360,22 @@
339360 .disable = rockchip_lvds_encoder_disable,
340361 .atomic_check = rockchip_lvds_encoder_atomic_check,
341362 .atomic_mode_set = rockchip_lvds_encoder_atomic_mode_set,
342
- .loader_protect = rockchip_lvds_encoder_loader_protect,
343363 };
344364
345365 static const struct drm_encoder_funcs rockchip_lvds_encoder_funcs = {
346366 .destroy = drm_encoder_cleanup,
347367 };
348368
349
-static int rockchip_lvds_match_by_id(struct device *dev, void *data)
369
+static int rockchip_lvds_match_by_id(struct device *dev, const void *data)
350370 {
351371 struct rockchip_lvds *lvds = dev_get_drvdata(dev);
352
- unsigned int *id = data;
372
+ unsigned int *id = (unsigned int *)data;
353373
354374 return lvds->id == *id;
355375 }
356376
357377 static struct rockchip_lvds *rockchip_lvds_find_by_id(struct device_driver *drv,
358
- unsigned int id)
378
+ unsigned int id)
359379 {
360380 struct device *dev;
361381
....@@ -386,8 +406,8 @@
386406 if (ret)
387407 return ret;
388408
389
- encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
390
- dev->of_node);
409
+ encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
410
+ dev->of_node);
391411
392412 ret = drm_encoder_init(drm_dev, encoder, &rockchip_lvds_encoder_funcs,
393413 DRM_MODE_ENCODER_LVDS, NULL);
....@@ -421,18 +441,13 @@
421441 goto err_free_connector;
422442 }
423443
424
- ret = drm_panel_attach(lvds->panel, connector);
425
- if (ret < 0) {
426
- DRM_DEV_ERROR(lvds->dev,
427
- "failed to attach panel: %d\n", ret);
428
- goto err_free_connector;
429
- }
430444 lvds->sub_dev.connector = &lvds->connector;
431445 lvds->sub_dev.of_node = lvds->dev->of_node;
446
+ lvds->sub_dev.loader_protect = rockchip_lvds_encoder_loader_protect;
432447 rockchip_drm_register_sub_dev(&lvds->sub_dev);
433448 drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
434449 } else {
435
- ret = drm_bridge_attach(encoder, lvds->bridge, NULL);
450
+ ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0);
436451 if (ret) {
437452 DRM_DEV_ERROR(lvds->dev,
438453 "failed to attach bridge: %d\n", ret);
....@@ -456,10 +471,8 @@
456471
457472 if (lvds->sub_dev.connector)
458473 rockchip_drm_unregister_sub_dev(&lvds->sub_dev);
459
- if (lvds->panel) {
460
- drm_panel_detach(lvds->panel);
474
+ if (lvds->panel)
461475 drm_connector_cleanup(&lvds->connector);
462
- }
463476
464477 if (lvds->encoder.dev)
465478 drm_encoder_cleanup(&lvds->encoder);
....@@ -658,6 +671,25 @@
658671 return 0;
659672 }
660673
674
+static void rk3562_lvds_enable(struct rockchip_lvds *lvds)
675
+{
676
+ regmap_write(lvds->grf, RK3562_GRF_VO_CON1,
677
+ RK3568_LVDS0_MODE_EN(1) | RK3568_LVDS0_P2S_EN(1) |
678
+ RK3568_LVDS0_DCLK_INV_SEL(1));
679
+ regmap_write(lvds->grf, RK3562_GRF_VO_CON0,
680
+ RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1));
681
+}
682
+
683
+static void rk3562_lvds_disable(struct rockchip_lvds *lvds)
684
+{
685
+ regmap_write(lvds->grf, RK3562_GRF_VO_CON1, RK3568_LVDS0_MODE_EN(0));
686
+}
687
+
688
+static const struct rockchip_lvds_funcs rk3562_lvds_funcs = {
689
+ .enable = rk3562_lvds_enable,
690
+ .disable = rk3562_lvds_disable,
691
+};
692
+
661693 static void rk3568_lvds_enable(struct rockchip_lvds *lvds)
662694 {
663695 regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
....@@ -682,6 +714,7 @@
682714 { .compatible = "rockchip,rk3126-lvds", .data = &rk3126_lvds_funcs },
683715 { .compatible = "rockchip,rk3288-lvds", .data = &rk3288_lvds_funcs },
684716 { .compatible = "rockchip,rk3368-lvds", .data = &rk3368_lvds_funcs },
717
+ { .compatible = "rockchip,rk3562-lvds", .data = &rk3562_lvds_funcs },
685718 { .compatible = "rockchip,rk3568-lvds", .data = &rk3568_lvds_funcs },
686719 {}
687720 };