forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-05-13 9d77db3c730780c8ef5ccd4b66403ff5675cfe4e
kernel/drivers/gpu/drm/mediatek/mtk_hdmi.c
....@@ -1,21 +1,9 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2014 MediaTek Inc.
34 * Author: Jie Qiu <jie.qiu@mediatek.com>
4
- *
5
- * This program is free software; you can redistribute it and/or modify
6
- * it under the terms of the GNU General Public License version 2 as
7
- * published by the Free Software Foundation.
8
- *
9
- * This program is distributed in the hope that it will be useful,
10
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
- * GNU General Public License for more details.
135 */
14
-#include <drm/drmP.h>
15
-#include <drm/drm_atomic_helper.h>
16
-#include <drm/drm_crtc.h>
17
-#include <drm/drm_crtc_helper.h>
18
-#include <drm/drm_edid.h>
6
+
197 #include <linux/arm-smccc.h>
208 #include <linux/clk.h>
219 #include <linux/delay.h>
....@@ -24,6 +12,8 @@
2412 #include <linux/io.h>
2513 #include <linux/kernel.h>
2614 #include <linux/mfd/syscon.h>
15
+#include <linux/module.h>
16
+#include <linux/mutex.h>
2717 #include <linux/of_platform.h>
2818 #include <linux/of.h>
2919 #include <linux/of_gpio.h>
....@@ -31,7 +21,16 @@
3121 #include <linux/phy/phy.h>
3222 #include <linux/platform_device.h>
3323 #include <linux/regmap.h>
24
+
3425 #include <sound/hdmi-codec.h>
26
+
27
+#include <drm/drm_atomic_helper.h>
28
+#include <drm/drm_bridge.h>
29
+#include <drm/drm_crtc.h>
30
+#include <drm/drm_edid.h>
31
+#include <drm/drm_print.h>
32
+#include <drm/drm_probe_helper.h>
33
+
3534 #include "mtk_cec.h"
3635 #include "mtk_hdmi.h"
3736 #include "mtk_hdmi_regs.h"
....@@ -147,11 +146,16 @@
147146 struct hdmi_codec_params codec_params;
148147 };
149148
149
+struct mtk_hdmi_conf {
150
+ bool tz_disabled;
151
+};
152
+
150153 struct mtk_hdmi {
151154 struct drm_bridge bridge;
152155 struct drm_bridge *next_bridge;
153156 struct drm_connector conn;
154157 struct device *dev;
158
+ const struct mtk_hdmi_conf *conf;
155159 struct phy *phy;
156160 struct device *cec_dev;
157161 struct i2c_adapter *ddc_adpt;
....@@ -172,6 +176,9 @@
172176 bool audio_enable;
173177 bool powered;
174178 bool enabled;
179
+ hdmi_codec_plugged_cb plugged_cb;
180
+ struct device *codec_dev;
181
+ struct mutex update_plugged_status_lock;
175182 };
176183
177184 static inline struct mtk_hdmi *hdmi_ctx_from_bridge(struct drm_bridge *b)
....@@ -240,8 +247,13 @@
240247 * The ARM trusted firmware provides an API for the HDMI driver to set
241248 * this control bit to enable HDMI output in supervisor mode.
242249 */
243
- arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904, 0x80000000,
244
- 0, 0, 0, 0, 0, &res);
250
+ if (hdmi->conf && hdmi->conf->tz_disabled)
251
+ regmap_update_bits(hdmi->sys_regmap,
252
+ hdmi->sys_offset + HDMI_SYS_CFG20,
253
+ 0x80008005, enable ? 0x80000005 : 0x8000);
254
+ else
255
+ arm_smccc_smc(MTK_SIP_SET_AUTHORIZED_SECURE_REG, 0x14000904,
256
+ 0x80000000, 0, 0, 0, 0, 0, &res);
245257
246258 regmap_update_bits(hdmi->sys_regmap, hdmi->sys_offset + HDMI_SYS_CFG20,
247259 HDMI_PCLK_FREE_RUN, enable ? HDMI_PCLK_FREE_RUN : 0);
....@@ -304,14 +316,10 @@
304316 u8 checksum;
305317 int ctrl_frame_en = 0;
306318
307
- frame_type = *buffer;
308
- buffer += 1;
309
- frame_ver = *buffer;
310
- buffer += 1;
311
- frame_len = *buffer;
312
- buffer += 1;
313
- checksum = *buffer;
314
- buffer += 1;
319
+ frame_type = *buffer++;
320
+ frame_ver = *buffer++;
321
+ frame_len = *buffer++;
322
+ checksum = *buffer++;
315323 frame_data = buffer;
316324
317325 dev_dbg(hdmi->dev,
....@@ -335,6 +343,9 @@
335343 ctrl_frame_en = VS_EN;
336344 ctrl_reg = GRL_ACP_ISRC_CTRL;
337345 break;
346
+ default:
347
+ dev_err(hdmi->dev, "Unknown infoframe type %d\n", frame_type);
348
+ return;
338349 }
339350 mtk_hdmi_clear_bits(hdmi, ctrl_reg, ctrl_frame_en);
340351 mtk_hdmi_write(hdmi, GRL_INFOFRM_TYPE, frame_type);
....@@ -972,10 +983,11 @@
972983 struct drm_display_mode *mode)
973984 {
974985 struct hdmi_avi_infoframe frame;
975
- u8 buffer[17];
986
+ u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AVI_INFOFRAME_SIZE];
976987 ssize_t err;
977988
978
- err = drm_hdmi_avi_infoframe_from_display_mode(&frame, mode, false);
989
+ err = drm_hdmi_avi_infoframe_from_display_mode(&frame,
990
+ &hdmi->conn, mode);
979991 if (err < 0) {
980992 dev_err(hdmi->dev,
981993 "Failed to get AVI infoframe from mode: %zd\n", err);
....@@ -997,7 +1009,7 @@
9971009 const char *product)
9981010 {
9991011 struct hdmi_spd_infoframe frame;
1000
- u8 buffer[29];
1012
+ u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_SPD_INFOFRAME_SIZE];
10011013 ssize_t err;
10021014
10031015 err = hdmi_spd_infoframe_init(&frame, vendor, product);
....@@ -1020,7 +1032,7 @@
10201032 static int mtk_hdmi_setup_audio_infoframe(struct mtk_hdmi *hdmi)
10211033 {
10221034 struct hdmi_audio_infoframe frame;
1023
- u8 buffer[14];
1035
+ u8 buffer[HDMI_INFOFRAME_HEADER_SIZE + HDMI_AUDIO_INFOFRAME_SIZE];
10241036 ssize_t err;
10251037
10261038 err = hdmi_audio_infoframe_init(&frame);
....@@ -1187,13 +1199,26 @@
11871199 clk_disable_unprepare(hdmi->clk[MTK_HDMI_CLK_AUD_SPDIF]);
11881200 }
11891201
1202
+static enum drm_connector_status
1203
+mtk_hdmi_update_plugged_status(struct mtk_hdmi *hdmi)
1204
+{
1205
+ bool connected;
1206
+
1207
+ mutex_lock(&hdmi->update_plugged_status_lock);
1208
+ connected = mtk_cec_hpd_high(hdmi->cec_dev);
1209
+ if (hdmi->plugged_cb && hdmi->codec_dev)
1210
+ hdmi->plugged_cb(hdmi->codec_dev, connected);
1211
+ mutex_unlock(&hdmi->update_plugged_status_lock);
1212
+
1213
+ return connected ?
1214
+ connector_status_connected : connector_status_disconnected;
1215
+}
1216
+
11901217 static enum drm_connector_status hdmi_conn_detect(struct drm_connector *conn,
11911218 bool force)
11921219 {
11931220 struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
1194
-
1195
- return mtk_cec_hpd_high(hdmi->cec_dev) ?
1196
- connector_status_connected : connector_status_disconnected;
1221
+ return mtk_hdmi_update_plugged_status(hdmi);
11971222 }
11981223
11991224 static void hdmi_conn_destroy(struct drm_connector *conn)
....@@ -1231,17 +1256,19 @@
12311256 struct drm_display_mode *mode)
12321257 {
12331258 struct mtk_hdmi *hdmi = hdmi_ctx_from_conn(conn);
1259
+ struct drm_bridge *next_bridge;
12341260
12351261 dev_dbg(hdmi->dev, "xres=%d, yres=%d, refresh=%d, intl=%d clock=%d\n",
1236
- mode->hdisplay, mode->vdisplay, mode->vrefresh,
1262
+ mode->hdisplay, mode->vdisplay, drm_mode_vrefresh(mode),
12371263 !!(mode->flags & DRM_MODE_FLAG_INTERLACE), mode->clock * 1000);
12381264
1239
- if (hdmi->bridge.next) {
1265
+ next_bridge = drm_bridge_get_next_bridge(&hdmi->bridge);
1266
+ if (next_bridge) {
12401267 struct drm_display_mode adjusted_mode;
12411268
12421269 drm_mode_copy(&adjusted_mode, mode);
1243
- if (!drm_bridge_mode_fixup(hdmi->bridge.next, mode,
1244
- &adjusted_mode))
1270
+ if (!drm_bridge_chain_mode_fixup(next_bridge, mode,
1271
+ &adjusted_mode))
12451272 return MODE_BAD;
12461273 }
12471274
....@@ -1288,14 +1315,21 @@
12881315 * Bridge callbacks
12891316 */
12901317
1291
-static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge)
1318
+static int mtk_hdmi_bridge_attach(struct drm_bridge *bridge,
1319
+ enum drm_bridge_attach_flags flags)
12921320 {
12931321 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
12941322 int ret;
12951323
1296
- ret = drm_connector_init(bridge->encoder->dev, &hdmi->conn,
1297
- &mtk_hdmi_connector_funcs,
1298
- DRM_MODE_CONNECTOR_HDMIA);
1324
+ if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR) {
1325
+ DRM_ERROR("Fix bridge driver to make connector optional!");
1326
+ return -EINVAL;
1327
+ }
1328
+
1329
+ ret = drm_connector_init_with_ddc(bridge->encoder->dev, &hdmi->conn,
1330
+ &mtk_hdmi_connector_funcs,
1331
+ DRM_MODE_CONNECTOR_HDMIA,
1332
+ hdmi->ddc_adpt);
12991333 if (ret) {
13001334 dev_err(hdmi->dev, "Failed to initialize connector: %d\n", ret);
13011335 return ret;
....@@ -1316,7 +1350,7 @@
13161350
13171351 if (hdmi->next_bridge) {
13181352 ret = drm_bridge_attach(bridge->encoder, hdmi->next_bridge,
1319
- bridge);
1353
+ bridge, flags);
13201354 if (ret) {
13211355 dev_err(hdmi->dev,
13221356 "Failed to attach external bridge: %d\n", ret);
....@@ -1364,8 +1398,8 @@
13641398 }
13651399
13661400 static void mtk_hdmi_bridge_mode_set(struct drm_bridge *bridge,
1367
- struct drm_display_mode *mode,
1368
- struct drm_display_mode *adjusted_mode)
1401
+ const struct drm_display_mode *mode,
1402
+ const struct drm_display_mode *adjusted_mode)
13691403 {
13701404 struct mtk_hdmi *hdmi = hdmi_ctx_from_bridge(bridge);
13711405
....@@ -1441,7 +1475,9 @@
14411475
14421476 ret = mtk_hdmi_get_all_clk(hdmi, np);
14431477 if (ret) {
1444
- dev_err(dev, "Failed to get clocks: %d\n", ret);
1478
+ if (ret != -EPROBE_DEFER)
1479
+ dev_err(dev, "Failed to get clocks: %d\n", ret);
1480
+
14451481 return ret;
14461482 }
14471483
....@@ -1586,6 +1622,11 @@
15861622 hdmi_params.aud_i2s_fmt = HDMI_I2S_MODE_I2S_24BIT;
15871623 hdmi_params.aud_mclk = HDMI_AUD_MCLK_128FS;
15881624 break;
1625
+ case HDMI_SPDIF:
1626
+ hdmi_params.aud_codec = HDMI_AUDIO_CODING_TYPE_PCM;
1627
+ hdmi_params.aud_sampe_size = HDMI_AUDIO_SAMPLE_SIZE_16;
1628
+ hdmi_params.aud_input_type = HDMI_AUD_INPUT_SPDIF;
1629
+ break;
15891630 default:
15901631 dev_err(hdmi->dev, "%s: Invalid DAI format %d\n", __func__,
15911632 daifmt->fmt);
....@@ -1604,8 +1645,6 @@
16041645 {
16051646 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
16061647
1607
- dev_dbg(dev, "%s\n", __func__);
1608
-
16091648 mtk_hdmi_audio_enable(hdmi);
16101649
16111650 return 0;
....@@ -1615,17 +1654,14 @@
16151654 {
16161655 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
16171656
1618
- dev_dbg(dev, "%s\n", __func__);
1619
-
16201657 mtk_hdmi_audio_disable(hdmi);
16211658 }
16221659
16231660 static int
1624
-mtk_hdmi_audio_digital_mute(struct device *dev, void *data, bool enable)
1661
+mtk_hdmi_audio_mute(struct device *dev, void *data,
1662
+ bool enable, int direction)
16251663 {
16261664 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
1627
-
1628
- dev_dbg(dev, "%s(%d)\n", __func__, enable);
16291665
16301666 if (enable)
16311667 mtk_hdmi_hw_aud_mute(hdmi);
....@@ -1639,9 +1675,23 @@
16391675 {
16401676 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
16411677
1642
- dev_dbg(dev, "%s\n", __func__);
1643
-
16441678 memcpy(buf, hdmi->conn.eld, min(sizeof(hdmi->conn.eld), len));
1679
+
1680
+ return 0;
1681
+}
1682
+
1683
+static int mtk_hdmi_audio_hook_plugged_cb(struct device *dev, void *data,
1684
+ hdmi_codec_plugged_cb fn,
1685
+ struct device *codec_dev)
1686
+{
1687
+ struct mtk_hdmi *hdmi = data;
1688
+
1689
+ mutex_lock(&hdmi->update_plugged_status_lock);
1690
+ hdmi->plugged_cb = fn;
1691
+ hdmi->codec_dev = codec_dev;
1692
+ mutex_unlock(&hdmi->update_plugged_status_lock);
1693
+
1694
+ mtk_hdmi_update_plugged_status(hdmi);
16451695
16461696 return 0;
16471697 }
....@@ -1650,16 +1700,20 @@
16501700 .hw_params = mtk_hdmi_audio_hw_params,
16511701 .audio_startup = mtk_hdmi_audio_startup,
16521702 .audio_shutdown = mtk_hdmi_audio_shutdown,
1653
- .digital_mute = mtk_hdmi_audio_digital_mute,
1703
+ .mute_stream = mtk_hdmi_audio_mute,
16541704 .get_eld = mtk_hdmi_audio_get_eld,
1705
+ .hook_plugged_cb = mtk_hdmi_audio_hook_plugged_cb,
1706
+ .no_capture_mute = 1,
16551707 };
16561708
1657
-static void mtk_hdmi_register_audio_driver(struct device *dev)
1709
+static int mtk_hdmi_register_audio_driver(struct device *dev)
16581710 {
1711
+ struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
16591712 struct hdmi_codec_pdata codec_data = {
16601713 .ops = &mtk_hdmi_audio_codec_ops,
16611714 .max_i2s_channels = 2,
16621715 .i2s = 1,
1716
+ .data = hdmi,
16631717 };
16641718 struct platform_device *pdev;
16651719
....@@ -1667,9 +1721,10 @@
16671721 PLATFORM_DEVID_AUTO, &codec_data,
16681722 sizeof(codec_data));
16691723 if (IS_ERR(pdev))
1670
- return;
1724
+ return PTR_ERR(pdev);
16711725
16721726 DRM_INFO("%s driver bound to HDMI\n", HDMI_CODEC_DRV_NAME);
1727
+ return 0;
16731728 }
16741729
16751730 static int mtk_drm_hdmi_probe(struct platform_device *pdev)
....@@ -1683,6 +1738,7 @@
16831738 return -ENOMEM;
16841739
16851740 hdmi->dev = dev;
1741
+ hdmi->conf = of_device_get_match_data(dev);
16861742
16871743 ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev);
16881744 if (ret)
....@@ -1695,6 +1751,7 @@
16951751 return ret;
16961752 }
16971753
1754
+ mutex_init(&hdmi->update_plugged_status_lock);
16981755 platform_set_drvdata(pdev, hdmi);
16991756
17001757 ret = mtk_hdmi_output_init(hdmi);
....@@ -1703,7 +1760,11 @@
17031760 return ret;
17041761 }
17051762
1706
- mtk_hdmi_register_audio_driver(dev);
1763
+ ret = mtk_hdmi_register_audio_driver(dev);
1764
+ if (ret) {
1765
+ dev_err(dev, "Failed to register audio driver: %d\n", ret);
1766
+ return ret;
1767
+ }
17071768
17081769 hdmi->bridge.funcs = &mtk_hdmi_bridge_funcs;
17091770 hdmi->bridge.of_node = pdev->dev.of_node;
....@@ -1715,7 +1776,6 @@
17151776 goto err_bridge_remove;
17161777 }
17171778
1718
- dev_dbg(dev, "mediatek hdmi probe success\n");
17191779 return 0;
17201780
17211781 err_bridge_remove:
....@@ -1738,7 +1798,7 @@
17381798 struct mtk_hdmi *hdmi = dev_get_drvdata(dev);
17391799
17401800 mtk_hdmi_clk_disable_audio(hdmi);
1741
- dev_dbg(dev, "hdmi suspend success!\n");
1801
+
17421802 return 0;
17431803 }
17441804
....@@ -1753,15 +1813,22 @@
17531813 return ret;
17541814 }
17551815
1756
- dev_dbg(dev, "hdmi resume success!\n");
17571816 return 0;
17581817 }
17591818 #endif
17601819 static SIMPLE_DEV_PM_OPS(mtk_hdmi_pm_ops,
17611820 mtk_hdmi_suspend, mtk_hdmi_resume);
17621821
1822
+static const struct mtk_hdmi_conf mtk_hdmi_conf_mt2701 = {
1823
+ .tz_disabled = true,
1824
+};
1825
+
17631826 static const struct of_device_id mtk_drm_hdmi_of_ids[] = {
1764
- { .compatible = "mediatek,mt8173-hdmi", },
1827
+ { .compatible = "mediatek,mt2701-hdmi",
1828
+ .data = &mtk_hdmi_conf_mt2701,
1829
+ },
1830
+ { .compatible = "mediatek,mt8173-hdmi",
1831
+ },
17651832 {}
17661833 };
17671834
....@@ -1776,7 +1843,6 @@
17761843 };
17771844
17781845 static struct platform_driver * const mtk_hdmi_drivers[] = {
1779
- &mtk_hdmi_phy_driver,
17801846 &mtk_hdmi_ddc_driver,
17811847 &mtk_cec_driver,
17821848 &mtk_hdmi_driver,