From 1543e317f1da31b75942316931e8f491a8920811 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Thu, 04 Jan 2024 10:08:02 +0000
Subject: [PATCH] disable FB
---
kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c | 173 ++++++++++++++++++++++++++++++++++++++++++++++++++-------
1 files changed, 151 insertions(+), 22 deletions(-)
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c b/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
index d4bd2fb..bc21bf4 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -83,10 +83,24 @@
enum lvds_format {
LVDS_8BIT_MODE_FORMAT_1,
LVDS_8BIT_MODE_FORMAT_2,
- LVDS_8BIT_MODE_FORMAT_3,
- LVDS_6BIT_MODE,
+ LVDS_6BIT_MODE_FORMAT_1,
+ LVDS_6BIT_MODE_FORMAT_2,
LVDS_10BIT_MODE_FORMAT_1,
LVDS_10BIT_MODE_FORMAT_2,
+};
+
+enum rockchip_lvds_dual_link_pixels {
+ ROCKCHIP_LVDS_DUAL_LINK_EVEN_ODD_PIXELS = 0,
+ ROCKCHIP_LVDS_DUAL_LINK_ODD_EVEN_PIXELS = 1,
+ ROCKCHIP_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS = 2,
+ ROCKCHIP_LVDS_DUAL_LINK_RIGHT_LEFT_PIXELS = 3,
+};
+
+enum rockchip_of_lvds_pixels {
+ ROCKCHIP_OF_LVDS_EVEN = BIT(0),
+ ROCKCHIP_OF_LVDS_ODD = BIT(1),
+ ROCKCHIP_OF_LVDS_LEFT = BIT(2),
+ ROCKCHIP_OF_LVDS_RIGHT = BIT(3),
};
struct rockchip_lvds;
@@ -107,7 +121,7 @@
bool data_swap;
bool dual_channel;
bool phy_enabled;
- enum drm_lvds_dual_link_pixels pixel_order;
+ enum rockchip_lvds_dual_link_pixels pixel_order;
struct rockchip_lvds *primary;
struct rockchip_lvds *secondary;
@@ -119,6 +133,99 @@
struct drm_display_mode mode;
struct rockchip_drm_sub_dev sub_dev;
};
+
+static int rockchip_of_lvds_get_port_pixels_type(struct device_node *port_node)
+{
+ bool even_pixels =
+ of_property_read_bool(port_node, "dual-lvds-even-pixels");
+ bool odd_pixels =
+ of_property_read_bool(port_node, "dual-lvds-odd-pixels");
+ bool left_pixels =
+ of_property_read_bool(port_node, "dual-lvds-left-pixels");
+ bool right_pixels =
+ of_property_read_bool(port_node, "dual-lvds-right-pixels");
+
+ return (even_pixels ? ROCKCHIP_OF_LVDS_EVEN : 0) |
+ (odd_pixels ? ROCKCHIP_OF_LVDS_ODD : 0) |
+ (left_pixels ? ROCKCHIP_OF_LVDS_LEFT : 0) |
+ (right_pixels ? ROCKCHIP_OF_LVDS_RIGHT : 0);
+}
+
+static int rockchip_of_lvds_get_remote_pixels_type(
+ const struct device_node *port_node)
+{
+ struct device_node *endpoint = NULL;
+ int pixels_type = -EPIPE;
+
+ for_each_child_of_node(port_node, endpoint) {
+ struct device_node *remote_port;
+ int current_pt;
+
+ if (!of_node_name_eq(endpoint, "endpoint"))
+ continue;
+
+ remote_port = of_graph_get_remote_port(endpoint);
+ if (!remote_port) {
+ of_node_put(endpoint);
+ return -EPIPE;
+ }
+
+ current_pt = rockchip_of_lvds_get_port_pixels_type(remote_port);
+ of_node_put(remote_port);
+ if (pixels_type < 0)
+ pixels_type = current_pt;
+
+ /*
+ * Sanity check, ensure that all remote endpoints have the same
+ * pixel type. We may lift this restriction later if we need to
+ * support multiple sinks with different dual-link
+ * configurations by passing the endpoints explicitly to
+ * rockchip_of_lvds_get_dual_link_pixel_order().
+ */
+ if (!current_pt || pixels_type != current_pt) {
+ of_node_put(endpoint);
+ return -EINVAL;
+ }
+ }
+
+ return pixels_type;
+}
+
+static int rockchip_of_lvds_get_dual_link_pixel_order(const struct device_node *port1,
+ const struct device_node *port2)
+{
+ int remote_p1_pt, remote_p2_pt;
+
+ if (!port1 || !port2)
+ return -EINVAL;
+
+ remote_p1_pt = rockchip_of_lvds_get_remote_pixels_type(port1);
+ if (remote_p1_pt < 0)
+ return remote_p1_pt;
+
+ remote_p2_pt = rockchip_of_lvds_get_remote_pixels_type(port2);
+ if (remote_p2_pt < 0)
+ return remote_p2_pt;
+
+ /*
+ * A valid dual-lVDS bus is found when one remote port is marked with
+ * "dual-lvds-even-pixels" or "dual-lvds-left-pixels", and the other
+ * remote port is marked with "dual-lvds-odd-pixels"or
+ * "dual-lvds-right-pixels", bail out if the markers are not right.
+ */
+ if ((remote_p1_pt + remote_p2_pt != ROCKCHIP_OF_LVDS_EVEN + ROCKCHIP_OF_LVDS_ODD) &&
+ (remote_p1_pt + remote_p2_pt != ROCKCHIP_OF_LVDS_LEFT + ROCKCHIP_OF_LVDS_RIGHT))
+ return -EINVAL;
+
+ if (remote_p1_pt == ROCKCHIP_OF_LVDS_EVEN)
+ return ROCKCHIP_LVDS_DUAL_LINK_EVEN_ODD_PIXELS;
+ else if (remote_p1_pt == ROCKCHIP_OF_LVDS_ODD)
+ return ROCKCHIP_LVDS_DUAL_LINK_ODD_EVEN_PIXELS;
+ else if (remote_p1_pt == ROCKCHIP_OF_LVDS_LEFT)
+ return ROCKCHIP_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS;
+ else
+ return ROCKCHIP_LVDS_DUAL_LINK_RIGHT_LEFT_PIXELS;
+}
static inline struct rockchip_lvds *connector_to_lvds(struct drm_connector *c)
{
@@ -190,8 +297,8 @@
case MEDIA_BUS_FMT_RGB101010_1X7X5_JEIDA: /* jeida-30 */
lvds->format = LVDS_10BIT_MODE_FORMAT_2;
break;
- case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* vesa-18 */
- lvds->format = LVDS_8BIT_MODE_FORMAT_3;
+ case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG: /* jeida-18, compatible with the [JEIDA], [LDI] and [VESA] specifications */
+ lvds->format = LVDS_6BIT_MODE_FORMAT_1;
break;
case MEDIA_BUS_FMT_RGB101010_1X7X5_SPWG: /* vesa-30 */
lvds->format = LVDS_10BIT_MODE_FORMAT_1;
@@ -236,29 +343,24 @@
s->color_space = V4L2_COLORSPACE_DEFAULT;
switch (lvds->pixel_order) {
- case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
+ case ROCKCHIP_LVDS_DUAL_LINK_ODD_EVEN_PIXELS:
s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE;
s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
break;
- case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
+ case ROCKCHIP_LVDS_DUAL_LINK_EVEN_ODD_PIXELS:
s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_ODD_EVEN_MODE;
s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
break;
-/*
- * Fix me: To do it with a GKI compatible version.
- */
-#if 0
- case DRM_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS:
+ case ROCKCHIP_LVDS_DUAL_LINK_LEFT_RIGHT_PIXELS:
s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
break;
- case DRM_LVDS_DUAL_LINK_RIGHT_LEFT_PIXELS:
+ case ROCKCHIP_LVDS_DUAL_LINK_RIGHT_LEFT_PIXELS:
s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
s->output_flags |= ROCKCHIP_OUTPUT_DATA_SWAP;
s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
break;
-#endif
default:
if (lvds->id)
s->output_if |= VOP_OUTPUT_IF_LVDS1;
@@ -429,6 +531,15 @@
DRM_DEV_ERROR(drm_dev->dev,
"failed to initialize connector: %d\n", ret);
goto err_free_encoder;
+ }
+
+ if (lvds->secondary) {
+ kfree(connector->name);
+ connector->name = kasprintf(GFP_KERNEL, "LVDS-DUAL");
+ if (!connector->name) {
+ ret = -ENOMEM;
+ goto err_free_connector;
+ }
}
drm_connector_helper_add(connector,
@@ -646,7 +757,7 @@
.disable = rk3368_lvds_disable,
};
-static int __maybe_unused rockchip_secondary_lvds_probe(struct rockchip_lvds *lvds)
+static int rk3568_lvds_probe(struct rockchip_lvds *lvds)
{
if (lvds->dual_channel) {
struct rockchip_lvds *secondary = NULL;
@@ -659,7 +770,7 @@
port0 = of_graph_get_port_by_id(lvds->dev->of_node, 1);
port1 = of_graph_get_port_by_id(secondary->dev->of_node, 1);
- pixel_order = drm_of_lvds_get_dual_link_pixel_order(port0, port1);
+ pixel_order = rockchip_of_lvds_get_dual_link_pixel_order(port0, port1);
of_node_put(port1);
of_node_put(port0);
@@ -692,19 +803,37 @@
static void rk3568_lvds_enable(struct rockchip_lvds *lvds)
{
- regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
- RK3568_LVDS0_MODE_EN(1) | RK3568_LVDS0_P2S_EN(1) |
- RK3568_LVDS0_DCLK_INV_SEL(1));
- regmap_write(lvds->grf, RK3568_GRF_VO_CON0,
- RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1));
+ if (lvds->id) {
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON3,
+ RK3568_LVDS1_MODE_EN(1) |
+ RK3568_LVDS1_P2S_EN(1) |
+ RK3568_LVDS1_DCLK_INV_SEL(1));
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON0,
+ RK3568_LVDS1_SELECT(lvds->format) |
+ RK3568_LVDS1_MSBSEL(1));
+ } else {
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
+ RK3568_LVDS0_MODE_EN(1) |
+ RK3568_LVDS0_P2S_EN(1) |
+ RK3568_LVDS0_DCLK_INV_SEL(1));
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON0,
+ RK3568_LVDS0_SELECT(lvds->format) |
+ RK3568_LVDS0_MSBSEL(1));
+ }
}
static void rk3568_lvds_disable(struct rockchip_lvds *lvds)
{
- regmap_write(lvds->grf, RK3568_GRF_VO_CON2, RK3568_LVDS0_MODE_EN(0));
+ if (lvds->id)
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON3,
+ RK3568_LVDS1_MODE_EN(0));
+ else
+ regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
+ RK3568_LVDS0_MODE_EN(0));
}
static const struct rockchip_lvds_funcs rk3568_lvds_funcs = {
+ .probe = rk3568_lvds_probe,
.enable = rk3568_lvds_enable,
.disable = rk3568_lvds_disable,
};
--
Gitblit v1.6.2