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/sun4i/sun4i_hdmi_enc.c | 93 ++++++++++++++++++++++++++++++----------------
1 files changed, 61 insertions(+), 32 deletions(-)
diff --git a/kernel/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c b/kernel/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
index 8ba19a8..2f2c9f0 100644
--- a/kernel/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
+++ b/kernel/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
@@ -1,30 +1,28 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* Copyright (C) 2016 Maxime Ripard
*
* Maxime Ripard <maxime.ripard@free-electrons.com>
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License as
- * published by the Free Software Foundation; either version 2 of
- * the License, or (at your option) any later version.
*/
-
-#include <drm/drmP.h>
-#include <drm/drm_atomic_helper.h>
-#include <drm/drm_crtc_helper.h>
-#include <drm/drm_edid.h>
-#include <drm/drm_encoder.h>
-#include <drm/drm_of.h>
-#include <drm/drm_panel.h>
#include <linux/clk.h>
#include <linux/component.h>
#include <linux/iopoll.h>
+#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/reset.h>
+
+#include <drm/drm_atomic_helper.h>
+#include <drm/drm_edid.h>
+#include <drm/drm_encoder.h>
+#include <drm/drm_of.h>
+#include <drm/drm_panel.h>
+#include <drm/drm_print.h>
+#include <drm/drm_probe_helper.h>
+#include <drm/drm_simple_kms_helper.h>
#include "sun4i_backend.h"
#include "sun4i_crtc.h"
@@ -52,7 +50,8 @@
u8 buffer[17];
int i, ret;
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
+ &hdmi->connector, mode);
if (ret < 0) {
DRM_ERROR("Failed to get infoframes from mode\n");
return ret;
@@ -206,17 +205,13 @@
.mode_valid = sun4i_hdmi_mode_valid,
};
-static const struct drm_encoder_funcs sun4i_hdmi_funcs = {
- .destroy = drm_encoder_cleanup,
-};
-
static int sun4i_hdmi_get_modes(struct drm_connector *connector)
{
struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
struct edid *edid;
int ret;
- edid = drm_get_edid(connector, hdmi->i2c);
+ edid = drm_get_edid(connector, hdmi->ddc_i2c ?: hdmi->i2c);
if (!edid)
return 0;
@@ -230,6 +225,28 @@
kfree(edid);
return ret;
+}
+
+static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
+{
+ struct device_node *phandle, *remote;
+ struct i2c_adapter *ddc;
+
+ remote = of_graph_get_remote_node(dev->of_node, 1, -1);
+ if (!remote)
+ return ERR_PTR(-EINVAL);
+
+ phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0);
+ of_node_put(remote);
+ if (!phandle)
+ return ERR_PTR(-ENODEV);
+
+ ddc = of_get_i2c_adapter_by_node(phandle);
+ of_node_put(phandle);
+ if (!ddc)
+ return ERR_PTR(-EPROBE_DEFER);
+
+ return ddc;
}
static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
@@ -261,7 +278,7 @@
};
#ifdef CONFIG_DRM_SUN4I_HDMI_CEC
-static bool sun4i_hdmi_cec_pin_read(struct cec_adapter *adap)
+static int sun4i_hdmi_cec_pin_read(struct cec_adapter *adap)
{
struct sun4i_hdmi *hdmi = cec_get_drvdata(adap);
@@ -469,6 +486,7 @@
{
struct platform_device *pdev = to_platform_device(dev);
struct drm_device *drm = data;
+ struct cec_connector_info conn_info;
struct sun4i_drv *drv = drm->dev_private;
struct sun4i_hdmi *hdmi;
struct resource *res;
@@ -578,29 +596,34 @@
goto err_disable_mod_clk;
}
+ hdmi->ddc_i2c = sun4i_hdmi_get_ddc(dev);
+ if (IS_ERR(hdmi->ddc_i2c)) {
+ ret = PTR_ERR(hdmi->ddc_i2c);
+ if (ret == -ENODEV)
+ hdmi->ddc_i2c = NULL;
+ else
+ goto err_del_i2c_adapter;
+ }
+
drm_encoder_helper_add(&hdmi->encoder,
&sun4i_hdmi_helper_funcs);
- ret = drm_encoder_init(drm,
- &hdmi->encoder,
- &sun4i_hdmi_funcs,
- DRM_MODE_ENCODER_TMDS,
- NULL);
+ ret = drm_simple_encoder_init(drm, &hdmi->encoder,
+ DRM_MODE_ENCODER_TMDS);
if (ret) {
dev_err(dev, "Couldn't initialise the HDMI encoder\n");
- goto err_del_i2c_adapter;
+ goto err_put_ddc_i2c;
}
hdmi->encoder.possible_crtcs = drm_of_find_possible_crtcs(drm,
dev->of_node);
if (!hdmi->encoder.possible_crtcs) {
ret = -EPROBE_DEFER;
- goto err_del_i2c_adapter;
+ goto err_put_ddc_i2c;
}
#ifdef CONFIG_DRM_SUN4I_HDMI_CEC
hdmi->cec_adap = cec_pin_allocate_adapter(&sun4i_hdmi_cec_pin_ops,
- hdmi, "sun4i", CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS |
- CEC_CAP_PASSTHROUGH | CEC_CAP_RC);
+ hdmi, "sun4i", CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO);
ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
if (ret < 0)
goto err_cleanup_connector;
@@ -610,14 +633,17 @@
drm_connector_helper_add(&hdmi->connector,
&sun4i_hdmi_connector_helper_funcs);
- ret = drm_connector_init(drm, &hdmi->connector,
- &sun4i_hdmi_connector_funcs,
- DRM_MODE_CONNECTOR_HDMIA);
+ ret = drm_connector_init_with_ddc(drm, &hdmi->connector,
+ &sun4i_hdmi_connector_funcs,
+ DRM_MODE_CONNECTOR_HDMIA,
+ hdmi->ddc_i2c);
if (ret) {
dev_err(dev,
"Couldn't initialise the HDMI connector\n");
goto err_cleanup_connector;
}
+ cec_fill_conn_info_from_drm(&conn_info, &hdmi->connector);
+ cec_s_conn_info(hdmi->cec_adap, &conn_info);
/* There is no HPD interrupt, so we need to poll the controller */
hdmi->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
@@ -633,6 +659,8 @@
err_cleanup_connector:
cec_delete_adapter(hdmi->cec_adap);
drm_encoder_cleanup(&hdmi->encoder);
+err_put_ddc_i2c:
+ i2c_put_adapter(hdmi->ddc_i2c);
err_del_i2c_adapter:
i2c_del_adapter(hdmi->i2c);
err_disable_mod_clk:
@@ -651,6 +679,7 @@
cec_unregister_adapter(hdmi->cec_adap);
i2c_del_adapter(hdmi->i2c);
+ i2c_put_adapter(hdmi->ddc_i2c);
clk_disable_unprepare(hdmi->mod_clk);
clk_disable_unprepare(hdmi->bus_clk);
}
--
Gitblit v1.6.2