From 95099d4622f8cb224d94e314c7a8e0df60b13f87 Mon Sep 17 00:00:00 2001
From: hc <hc@nodka.com>
Date: Sat, 09 Dec 2023 08:38:01 +0000
Subject: [PATCH] enable docker ppp
---
kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c | 115 +++++++++++++++++++++++++++++++++++++--------------------
1 files changed, 74 insertions(+), 41 deletions(-)
diff --git a/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c b/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
index ee701cc..d4bd2fb 100644
--- a/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
+++ b/kernel/drivers/gpu/drm/rockchip/rockchip_lvds.c
@@ -1,30 +1,24 @@
+// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
* Author:
* Mark Yao <mark.yao@rock-chips.com>
* Sandy Huang <hjc@rock-chips.com>
- *
- * This software is licensed under the terms of the GNU General Public
- * License version 2, as published by the Free Software Foundation, and
- * may be copied, distributed, and modified under those terms.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
*/
-
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_panel.h>
-#include <drm/drm_of.h>
#include <linux/component.h>
#include <linux/mfd/syscon.h>
-#include <linux/of_device.h>
#include <linux/of_graph.h>
-#include <linux/regmap.h>
#include <linux/phy/phy.h>
+#include <linux/of_platform.h>
+#include <linux/regmap.h>
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_bridge.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
+
#include <uapi/linux/videodev2.h>
#include "rockchip_drm_drv.h"
@@ -66,6 +60,9 @@
#define RK3368_LVDS_MODE_EN(x) HIWORD_UPDATE(x, 12, 12)
#define RK3368_LVDS_MSBSEL(x) HIWORD_UPDATE(x, 11, 11)
#define RK3368_LVDS_P2S_EN(x) HIWORD_UPDATE(x, 6, 6)
+
+#define RK3562_GRF_VO_CON0 0x05d0
+#define RK3562_GRF_VO_CON1 0x05d4
#define RK3568_GRF_VO_CON0 0x0360
#define RK3568_LVDS1_SELECT(x) HIWORD_UPDATE(x, 13, 12)
@@ -109,6 +106,7 @@
enum lvds_format format;
bool data_swap;
bool dual_channel;
+ bool phy_enabled;
enum drm_lvds_dual_link_pixels pixel_order;
struct rockchip_lvds *primary;
@@ -164,7 +162,7 @@
struct rockchip_lvds *lvds = connector_to_lvds(connector);
struct drm_panel *panel = lvds->panel;
- return drm_panel_get_modes(panel);
+ return drm_panel_get_modes(panel, connector);
}
static const
@@ -186,9 +184,6 @@
bus_format = info->bus_formats[0];
switch (bus_format) {
- case MEDIA_BUS_FMT_RGB666_1X7X3_JEIDA: /* jeida-18 */
- lvds->format = LVDS_6BIT_MODE;
- break;
case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA: /* jeida-24 */
lvds->format = LVDS_8BIT_MODE_FORMAT_2;
break;
@@ -237,7 +232,7 @@
s->output_type = DRM_MODE_CONNECTOR_LVDS;
s->bus_flags = info->bus_flags;
s->tv_state = &conn_state->tv;
- s->eotf = TRADITIONAL_GAMMA_SDR;
+ s->eotf = HDMI_EOTF_TRADITIONAL_GAMMA_SDR;
s->color_space = V4L2_COLORSPACE_DEFAULT;
switch (lvds->pixel_order) {
@@ -250,6 +245,10 @@
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:
s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
s->output_if |= VOP_OUTPUT_IF_LVDS1 | VOP_OUTPUT_IF_LVDS0;
@@ -259,6 +258,7 @@
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;
@@ -277,13 +277,16 @@
if (lvds->funcs->enable)
lvds->funcs->enable(lvds);
- ret = phy_set_mode(lvds->phy, PHY_MODE_VIDEO_LVDS);
+ ret = phy_set_mode(lvds->phy, PHY_MODE_LVDS);
if (ret) {
DRM_DEV_ERROR(lvds->dev, "failed to set phy mode: %d\n", ret);
return;
}
- phy_power_on(lvds->phy);
+ if (lvds->phy && !lvds->phy_enabled) {
+ phy_power_on(lvds->phy);
+ lvds->phy_enabled = true;
+ }
if (lvds->secondary)
rockchip_lvds_enable(lvds->secondary);
@@ -294,7 +297,10 @@
if (lvds->funcs->disable)
lvds->funcs->disable(lvds);
- phy_power_off(lvds->phy);
+ if (lvds->phy && lvds->phy_enabled) {
+ phy_power_off(lvds->phy);
+ lvds->phy_enabled = false;
+ }
if (lvds->secondary)
rockchip_lvds_disable(lvds->secondary);
@@ -328,7 +334,22 @@
struct rockchip_lvds *lvds = encoder_to_lvds(encoder);
if (lvds->panel)
- return drm_panel_loader_protect(lvds->panel, on);
+ panel_simple_loader_protect(lvds->panel);
+
+
+ if (on) {
+ phy_init(lvds->phy);
+ if (lvds->phy) {
+ lvds->phy->power_count++;
+ lvds->phy_enabled = true;
+ }
+ } else {
+ phy_exit(lvds->phy);
+ if (lvds->phy) {
+ lvds->phy->power_count--;
+ lvds->phy_enabled = false;
+ }
+ }
return 0;
}
@@ -339,23 +360,22 @@
.disable = rockchip_lvds_encoder_disable,
.atomic_check = rockchip_lvds_encoder_atomic_check,
.atomic_mode_set = rockchip_lvds_encoder_atomic_mode_set,
- .loader_protect = rockchip_lvds_encoder_loader_protect,
};
static const struct drm_encoder_funcs rockchip_lvds_encoder_funcs = {
.destroy = drm_encoder_cleanup,
};
-static int rockchip_lvds_match_by_id(struct device *dev, void *data)
+static int rockchip_lvds_match_by_id(struct device *dev, const void *data)
{
struct rockchip_lvds *lvds = dev_get_drvdata(dev);
- unsigned int *id = data;
+ unsigned int *id = (unsigned int *)data;
return lvds->id == *id;
}
static struct rockchip_lvds *rockchip_lvds_find_by_id(struct device_driver *drv,
- unsigned int id)
+ unsigned int id)
{
struct device *dev;
@@ -386,8 +406,8 @@
if (ret)
return ret;
- encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
- dev->of_node);
+ encoder->possible_crtcs = rockchip_drm_of_find_possible_crtcs(drm_dev,
+ dev->of_node);
ret = drm_encoder_init(drm_dev, encoder, &rockchip_lvds_encoder_funcs,
DRM_MODE_ENCODER_LVDS, NULL);
@@ -421,18 +441,13 @@
goto err_free_connector;
}
- ret = drm_panel_attach(lvds->panel, connector);
- if (ret < 0) {
- DRM_DEV_ERROR(lvds->dev,
- "failed to attach panel: %d\n", ret);
- goto err_free_connector;
- }
lvds->sub_dev.connector = &lvds->connector;
lvds->sub_dev.of_node = lvds->dev->of_node;
+ lvds->sub_dev.loader_protect = rockchip_lvds_encoder_loader_protect;
rockchip_drm_register_sub_dev(&lvds->sub_dev);
drm_object_attach_property(&connector->base, private->connector_id_prop, 0);
} else {
- ret = drm_bridge_attach(encoder, lvds->bridge, NULL);
+ ret = drm_bridge_attach(encoder, lvds->bridge, NULL, 0);
if (ret) {
DRM_DEV_ERROR(lvds->dev,
"failed to attach bridge: %d\n", ret);
@@ -456,10 +471,8 @@
if (lvds->sub_dev.connector)
rockchip_drm_unregister_sub_dev(&lvds->sub_dev);
- if (lvds->panel) {
- drm_panel_detach(lvds->panel);
+ if (lvds->panel)
drm_connector_cleanup(&lvds->connector);
- }
if (lvds->encoder.dev)
drm_encoder_cleanup(&lvds->encoder);
@@ -658,6 +671,25 @@
return 0;
}
+static void rk3562_lvds_enable(struct rockchip_lvds *lvds)
+{
+ regmap_write(lvds->grf, RK3562_GRF_VO_CON1,
+ RK3568_LVDS0_MODE_EN(1) | RK3568_LVDS0_P2S_EN(1) |
+ RK3568_LVDS0_DCLK_INV_SEL(1));
+ regmap_write(lvds->grf, RK3562_GRF_VO_CON0,
+ RK3568_LVDS0_SELECT(lvds->format) | RK3568_LVDS0_MSBSEL(1));
+}
+
+static void rk3562_lvds_disable(struct rockchip_lvds *lvds)
+{
+ regmap_write(lvds->grf, RK3562_GRF_VO_CON1, RK3568_LVDS0_MODE_EN(0));
+}
+
+static const struct rockchip_lvds_funcs rk3562_lvds_funcs = {
+ .enable = rk3562_lvds_enable,
+ .disable = rk3562_lvds_disable,
+};
+
static void rk3568_lvds_enable(struct rockchip_lvds *lvds)
{
regmap_write(lvds->grf, RK3568_GRF_VO_CON2,
@@ -682,6 +714,7 @@
{ .compatible = "rockchip,rk3126-lvds", .data = &rk3126_lvds_funcs },
{ .compatible = "rockchip,rk3288-lvds", .data = &rk3288_lvds_funcs },
{ .compatible = "rockchip,rk3368-lvds", .data = &rk3368_lvds_funcs },
+ { .compatible = "rockchip,rk3562-lvds", .data = &rk3562_lvds_funcs },
{ .compatible = "rockchip,rk3568-lvds", .data = &rk3568_lvds_funcs },
{}
};
--
Gitblit v1.6.2