forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-01-04 1543e317f1da31b75942316931e8f491a8920811
kernel/drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c
....@@ -1,30 +1,28 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /*
23 * Copyright (C) 2016 Maxime Ripard
34 *
45 * Maxime Ripard <maxime.ripard@free-electrons.com>
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of the GNU General Public License as
8
- * published by the Free Software Foundation; either version 2 of
9
- * the License, or (at your option) any later version.
106 */
11
-
12
-#include <drm/drmP.h>
13
-#include <drm/drm_atomic_helper.h>
14
-#include <drm/drm_crtc_helper.h>
15
-#include <drm/drm_edid.h>
16
-#include <drm/drm_encoder.h>
17
-#include <drm/drm_of.h>
18
-#include <drm/drm_panel.h>
197
208 #include <linux/clk.h>
219 #include <linux/component.h>
2210 #include <linux/iopoll.h>
11
+#include <linux/module.h>
2312 #include <linux/of_device.h>
2413 #include <linux/platform_device.h>
2514 #include <linux/pm_runtime.h>
2615 #include <linux/regmap.h>
2716 #include <linux/reset.h>
17
+
18
+#include <drm/drm_atomic_helper.h>
19
+#include <drm/drm_edid.h>
20
+#include <drm/drm_encoder.h>
21
+#include <drm/drm_of.h>
22
+#include <drm/drm_panel.h>
23
+#include <drm/drm_print.h>
24
+#include <drm/drm_probe_helper.h>
25
+#include <drm/drm_simple_kms_helper.h>
2826
2927 #include "sun4i_backend.h"
3028 #include "sun4i_crtc.h"
....@@ -52,7 +50,8 @@
5250 u8 buffer[17];
5351 int i, ret;
5452
55
- ret = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
53
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame,
54
+ &hdmi->connector, mode);
5655 if (ret < 0) {
5756 DRM_ERROR("Failed to get infoframes from mode\n");
5857 return ret;
....@@ -206,17 +205,13 @@
206205 .mode_valid = sun4i_hdmi_mode_valid,
207206 };
208207
209
-static const struct drm_encoder_funcs sun4i_hdmi_funcs = {
210
- .destroy = drm_encoder_cleanup,
211
-};
212
-
213208 static int sun4i_hdmi_get_modes(struct drm_connector *connector)
214209 {
215210 struct sun4i_hdmi *hdmi = drm_connector_to_sun4i_hdmi(connector);
216211 struct edid *edid;
217212 int ret;
218213
219
- edid = drm_get_edid(connector, hdmi->i2c);
214
+ edid = drm_get_edid(connector, hdmi->ddc_i2c ?: hdmi->i2c);
220215 if (!edid)
221216 return 0;
222217
....@@ -230,6 +225,28 @@
230225 kfree(edid);
231226
232227 return ret;
228
+}
229
+
230
+static struct i2c_adapter *sun4i_hdmi_get_ddc(struct device *dev)
231
+{
232
+ struct device_node *phandle, *remote;
233
+ struct i2c_adapter *ddc;
234
+
235
+ remote = of_graph_get_remote_node(dev->of_node, 1, -1);
236
+ if (!remote)
237
+ return ERR_PTR(-EINVAL);
238
+
239
+ phandle = of_parse_phandle(remote, "ddc-i2c-bus", 0);
240
+ of_node_put(remote);
241
+ if (!phandle)
242
+ return ERR_PTR(-ENODEV);
243
+
244
+ ddc = of_get_i2c_adapter_by_node(phandle);
245
+ of_node_put(phandle);
246
+ if (!ddc)
247
+ return ERR_PTR(-EPROBE_DEFER);
248
+
249
+ return ddc;
233250 }
234251
235252 static const struct drm_connector_helper_funcs sun4i_hdmi_connector_helper_funcs = {
....@@ -261,7 +278,7 @@
261278 };
262279
263280 #ifdef CONFIG_DRM_SUN4I_HDMI_CEC
264
-static bool sun4i_hdmi_cec_pin_read(struct cec_adapter *adap)
281
+static int sun4i_hdmi_cec_pin_read(struct cec_adapter *adap)
265282 {
266283 struct sun4i_hdmi *hdmi = cec_get_drvdata(adap);
267284
....@@ -469,6 +486,7 @@
469486 {
470487 struct platform_device *pdev = to_platform_device(dev);
471488 struct drm_device *drm = data;
489
+ struct cec_connector_info conn_info;
472490 struct sun4i_drv *drv = drm->dev_private;
473491 struct sun4i_hdmi *hdmi;
474492 struct resource *res;
....@@ -578,29 +596,34 @@
578596 goto err_disable_mod_clk;
579597 }
580598
599
+ hdmi->ddc_i2c = sun4i_hdmi_get_ddc(dev);
600
+ if (IS_ERR(hdmi->ddc_i2c)) {
601
+ ret = PTR_ERR(hdmi->ddc_i2c);
602
+ if (ret == -ENODEV)
603
+ hdmi->ddc_i2c = NULL;
604
+ else
605
+ goto err_del_i2c_adapter;
606
+ }
607
+
581608 drm_encoder_helper_add(&hdmi->encoder,
582609 &sun4i_hdmi_helper_funcs);
583
- ret = drm_encoder_init(drm,
584
- &hdmi->encoder,
585
- &sun4i_hdmi_funcs,
586
- DRM_MODE_ENCODER_TMDS,
587
- NULL);
610
+ ret = drm_simple_encoder_init(drm, &hdmi->encoder,
611
+ DRM_MODE_ENCODER_TMDS);
588612 if (ret) {
589613 dev_err(dev, "Couldn't initialise the HDMI encoder\n");
590
- goto err_del_i2c_adapter;
614
+ goto err_put_ddc_i2c;
591615 }
592616
593617 hdmi->encoder.possible_crtcs = drm_of_find_possible_crtcs(drm,
594618 dev->of_node);
595619 if (!hdmi->encoder.possible_crtcs) {
596620 ret = -EPROBE_DEFER;
597
- goto err_del_i2c_adapter;
621
+ goto err_put_ddc_i2c;
598622 }
599623
600624 #ifdef CONFIG_DRM_SUN4I_HDMI_CEC
601625 hdmi->cec_adap = cec_pin_allocate_adapter(&sun4i_hdmi_cec_pin_ops,
602
- hdmi, "sun4i", CEC_CAP_TRANSMIT | CEC_CAP_LOG_ADDRS |
603
- CEC_CAP_PASSTHROUGH | CEC_CAP_RC);
626
+ hdmi, "sun4i", CEC_CAP_DEFAULTS | CEC_CAP_CONNECTOR_INFO);
604627 ret = PTR_ERR_OR_ZERO(hdmi->cec_adap);
605628 if (ret < 0)
606629 goto err_cleanup_connector;
....@@ -610,14 +633,17 @@
610633
611634 drm_connector_helper_add(&hdmi->connector,
612635 &sun4i_hdmi_connector_helper_funcs);
613
- ret = drm_connector_init(drm, &hdmi->connector,
614
- &sun4i_hdmi_connector_funcs,
615
- DRM_MODE_CONNECTOR_HDMIA);
636
+ ret = drm_connector_init_with_ddc(drm, &hdmi->connector,
637
+ &sun4i_hdmi_connector_funcs,
638
+ DRM_MODE_CONNECTOR_HDMIA,
639
+ hdmi->ddc_i2c);
616640 if (ret) {
617641 dev_err(dev,
618642 "Couldn't initialise the HDMI connector\n");
619643 goto err_cleanup_connector;
620644 }
645
+ cec_fill_conn_info_from_drm(&conn_info, &hdmi->connector);
646
+ cec_s_conn_info(hdmi->cec_adap, &conn_info);
621647
622648 /* There is no HPD interrupt, so we need to poll the controller */
623649 hdmi->connector.polled = DRM_CONNECTOR_POLL_CONNECT |
....@@ -633,6 +659,8 @@
633659 err_cleanup_connector:
634660 cec_delete_adapter(hdmi->cec_adap);
635661 drm_encoder_cleanup(&hdmi->encoder);
662
+err_put_ddc_i2c:
663
+ i2c_put_adapter(hdmi->ddc_i2c);
636664 err_del_i2c_adapter:
637665 i2c_del_adapter(hdmi->i2c);
638666 err_disable_mod_clk:
....@@ -651,6 +679,7 @@
651679
652680 cec_unregister_adapter(hdmi->cec_adap);
653681 i2c_del_adapter(hdmi->i2c);
682
+ i2c_put_adapter(hdmi->ddc_i2c);
654683 clk_disable_unprepare(hdmi->mod_clk);
655684 clk_disable_unprepare(hdmi->bus_clk);
656685 }