Re: [RFC PATCH 2/2] drm/mediatek: add mtk8195 hdmi display driver
flat view
From: CK Hu <hidden>
Date: 2022-01-14 08:48:42
Also in:
dri-devel, linux-mediatek, lkml
Hi, Guillaume: On Mon, 2021-11-08 at 01:08 +0100, Guillaume Ranquet wrote:
quoted hunk ↗ jump to hunk
Signed-off-by: Guillaume Ranquet <redacted> Change-Id: I6399dec26cfe56a338c2ca96989cb7cbd14e292b --- drivers/gpu/drm/mediatek/Kconfig | 9 + drivers/gpu/drm/mediatek/Makefile | 2 + drivers/gpu/drm/mediatek/mtk_hdmi_common.c | 219 +- drivers/gpu/drm/mediatek/mtk_hdmi_common.h | 24 +- drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c | 1835 +++++++++++++++++ drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h | 26 + .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c | 530 +++++ .../gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h | 20 + .../gpu/drm/mediatek/mtk_mt8195_hdmi_regs.h | 329 +++ 9 files changed, 2932 insertions(+), 62 deletions(-) create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.c create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi.h create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.c create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_ddc.h create mode 100644 drivers/gpu/drm/mediatek/mtk_mt8195_hdmi_regs.hdiff --git a/drivers/gpu/drm/mediatek/Kconfigb/drivers/gpu/drm/mediatek/Kconfig index 0df75bceb74e..76cc402cbd75 100644--- a/drivers/gpu/drm/mediatek/Kconfig +++ b/drivers/gpu/drm/mediatek/Kconfig@@ -31,3 +31,12 @@ config DRM_MEDIATEK_HDMI help DRM/KMS HDMI driver for Mediatek SoCs +config DRM_MEDIATEK_HDMI_MT8195_SUSPEND_LOW_POWER + tristate "DRM HDMI SUSPEND LOW POWER Support for Mediatekmt8195 SoCs" + depends on DRM_MEDIATEK_HDMI + help + DRM/KMS HDMI SUSPEND_LOW_POWER for Mediatek SoCs. + Choose this option if you want to disable/enable + clock and power domain when platform enter suspend, + and this config depends on DRM_MEDIATEK_HDMI. +diff --git a/drivers/gpu/drm/mediatek/Makefileb/drivers/gpu/drm/mediatek/Makefile index 107b6fbbdbf7..477c0648643c 100644--- a/drivers/gpu/drm/mediatek/Makefile +++ b/drivers/gpu/drm/mediatek/Makefile@@ -26,6 +26,8 @@ mediatek-drm-hdmi-objs := mtk_cec.o \ mtk_hdmi.o \ mtk_hdmi_ddc.o \ mtk_hdmi_common.o \ + mtk_mt8195_hdmi.o \ + mtk_mt8195_hdmi_ddc.o \ obj-$(CONFIG_DRM_MEDIATEK_HDMI) += mediatek-drm-hdmi.odiff --git a/drivers/gpu/drm/mediatek/mtk_hdmi_common.cb/drivers/gpu/drm/mediatek/mtk_hdmi_common.c index 3c38a3e73920..19083be0978a 100644--- a/drivers/gpu/drm/mediatek/mtk_hdmi_common.c +++ b/drivers/gpu/drm/mediatek/mtk_hdmi_common.c@@ -1,5 +1,15 @@ #include "mtk_hdmi_common.h" +const char *constmtk_hdmi_clk_names_mt8195[MTK_MT8195_HDMI_CLK_COUNT] = { + [MTK_MT8195_HDMI_CLK_UNIVPLL_D6D4] = "univpll_d6_d4", + [MTK_MT8195_HDMI_CLK_MSDCPLL_D2] = "msdcpll_d2", + [MTK_MT8195_HDMI_CLK_HDMI_APB_SEL] = "hdmi_apb_sel", + [MTK_MT8195_HDMI_UNIVPLL_D4D8] = "univpll_d4_d8", + [MTK_MT8195_HDIM_HDCP_SEL] = "hdcp_sel", + [MTK_MT8195_HDMI_HDCP_24M_SEL] = "hdcp24_sel", + [MTK_MT8195_HDMI_VPP_SPLIT_HDMI] = "split_hdmi", +}; + const char * const mtk_hdmi_clk_names_mt8183[MTK_MT8183_HDMI_CLK_COUNT] = { [MTK_MT8183_HDMI_CLK_HDMI_PIXEL] = "pixel", [MTK_MT8183_HDMI_CLK_HDMI_PLL] = "pll",@@ -138,6 +148,18 @@ int mtk_hdmi_setup_avi_infoframe(struct mtk_hdmi*hdmi, u8 *buffer, size_t bufsz return err; } + if(hdmi->conf && hdmi->conf->is_mt8195) { + frame.colorimetry = hdmi->colorimtery; + //no need, since we cannot support other extended colorimetry? + if (frame.colorimetry == HDMI_COLORIMETRY_EXTENDED) + frame.extended_colorimetry = hdmi-quoted
extended_colorimetry;
Separate colorimetry related part to an independent patch and use hdmi-
conf->colorimetry_support instead of hdmi->conf->is_mt8195.
quoted hunk ↗ jump to hunk
+ + /* quantiation range:limited or full */ + if (frame.colorspace == HDMI_COLORSPACE_RGB) + frame.quantization_range = hdmi-quoted
quantization_range;+ else + frame.ycc_quantization_range = hdmi-quoted
ycc_quantization_range;+ } err = hdmi_avi_infoframe_pack(&frame, buffer, bufsz); if (err < 0) {@@ -155,6 +177,11 @@ void mtk_hdmi_send_infoframe(struct mtk_hdmi*hdmi, u8 *buffer_spd, size_t bufsz mtk_hdmi_setup_spd_infoframe(hdmi, buffer_spd, bufsz_spd, "mediatek", "On-chip HDMI"); } +static struct mtk_hdmi_ddc *hdmi_ddc_ctx_from_mtk_hdmi(struct mtk_hdmi *hdmi) +{ + return container_of(hdmi->ddc_adpt, struct mtk_hdmi_ddc, adap); +} + int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi *hdmi, struct platform_device *pdev, const char *const *clk_names, size_t num_clocks) {@@ -173,39 +200,41 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi*hdmi, return ret; } - /* The CEC module handles HDMI hotplug detection */ - cec_np = of_get_compatible_child(np->parent, "mediatek,mt8173- cec"); - if (!cec_np) { - dev_err(dev, "Failed to find CEC node\n"); - return -EINVAL; - } + if (!hdmi->conf || !hdmi->conf->is_mt8195) { + /* The CEC module handles HDMI hotplug detection */
Separate CEC hoplug related part to an independent patch.
+ cec_np = of_get_compatible_child(np->parent,
"mediatek,mt8173-cec");
+ if (!cec_np) {
+ dev_err(dev, "Failed to find CEC node\n");
+ return -EINVAL;
+ }
- cec_pdev = of_find_device_by_node(cec_np);
- if (!cec_pdev) {
- dev_err(hdmi->dev, "Waiting for CEC device %pOF\n",
- cec_np);
+ cec_pdev = of_find_device_by_node(cec_np);
+ if (!cec_pdev) {
+ dev_err(hdmi->dev, "Waiting for CEC device
%pOF\n",
+ cec_np);
+ of_node_put(cec_np);
+ return -EPROBE_DEFER;
+ }
of_node_put(cec_np);
- return -EPROBE_DEFER;
- }
- of_node_put(cec_np);
- hdmi->cec_dev = &cec_pdev->dev;
- /*
- * The mediatek,syscon-hdmi property contains a phandle link to
the
- * MMSYS_CONFIG device and the register offset of the
HDMI_SYS_CFG
- * registers it contains.
- */
- regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-
hdmi");
- ret = of_property_read_u32_index(np, "mediatek,syscon-hdmi", 1,
- &hdmi->sys_offset);
- if (IS_ERR(regmap))
- ret = PTR_ERR(regmap);
- if (ret) {
- dev_err(dev,
- "Failed to get system configuration
registers: %d\n",
- ret);
- goto put_device;
+ hdmi->cec_dev = &cec_pdev->dev;
+ /*
+ * The mediatek,syscon-hdmi property contains a phandle
link to the
+ * MMSYS_CONFIG device and the register offset of the
HDMI_SYS_CFGSeparate HDMI_SYS_CFG related part to an independent patch.
quoted hunk ↗ jump to hunk
+ * registers it contains. + */ + regmap = syscon_regmap_lookup_by_phandle(np, "mediatek,syscon-hdmi"); + ret = of_property_read_u32_index(np, "mediatek,syscon- hdmi", 1, + &hdmi->sys_offset); + if (IS_ERR(regmap)) + ret = PTR_ERR(regmap); + if (ret) { + dev_err(dev, + "Failed to get system configuration registers: %d\n", + ret); + goto put_device; + } + hdmi->sys_regmap = regmap; } - hdmi->sys_regmap = regmap; mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!mem) {@@ -219,20 +248,22 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi*hdmi, goto put_device; } - remote = of_graph_get_remote_node(np, 1, 0); - if (!remote) { - ret = -EINVAL; - goto put_device; - } - - if (!of_device_is_compatible(remote, "hdmi-connector")) { - hdmi->next_bridge = of_drm_find_bridge(remote); - if (!hdmi->next_bridge) { - dev_err(dev, "Waiting for external bridge\n"); - of_node_put(remote); - ret = -EPROBE_DEFER; + if (!hdmi->conf || !hdmi->conf->is_mt8195) { + remote = of_graph_get_remote_node(np, 1, 0); + if (!remote) { + ret = -EINVAL; goto put_device; } + + if (!of_device_is_compatible(remote, "hdmi-connector")) { + hdmi->next_bridge = of_drm_find_bridge(remote); + if (!hdmi->next_bridge) { + dev_err(dev, "Waiting for external bridge\n"); + of_node_put(remote); + ret = -EPROBE_DEFER; + goto put_device; + } + } } i2c_np = of_parse_phandle(pdev->dev.of_node, "ddc-i2c-bus", 0);@@ -251,9 +282,16 @@ int mtk_hdmi_dt_parse_pdata(struct mtk_hdmi*hdmi, goto put_device; } + //TODO: rework this... this is ugly + if (hdmi->conf && hdmi->conf->is_mt8195) { + ddc = hdmi_ddc_ctx_from_mtk_hdmi(hdmi); + ddc->regs = hdmi->regs; + }
Separate ddc related part to an independent patch.
quoted hunk ↗ jump to hunk
+ return 0; put_device: - put_device(hdmi->cec_dev); + if (!hdmi->conf || !hdmi->conf->is_mt8195) + put_device(hdmi->cec_dev); return ret; }@@ -265,7 +303,10 @@ static int mtk_hdmi_register_audio_driver(structdevice *dev) .data = hdmi, }; - set_hdmi_codec_pdata_mt8183(&codec_data); + if(hdmi->conf && hdmi->conf->is_mt8195) + set_hdmi_codec_pdata_mt8195(&codec_data); + else + set_hdmi_codec_pdata_mt8183(&codec_data);
set_hdmi_codec_pdata_mt8195() and set_hdmi_codec_pdata_mt8183() has the same statement: codec_data->ops = &mtk_hdmi_audio_codec_ops; codec_data->max_i2s_channels = 2; codec_data->i2s = 1; I think you could move these three lines out of that function, and set ops as codec_data->ops = hdmi->conf->audio_codec_ops;
quoted hunk ↗ jump to hunk
pdev = platform_device_register_data(dev, HDMI_CODEC_DRV_NAME, PLATFORM_DEVID_AUTO, &codec_data,@@ -297,15 +338,23 @@ int mtk_drm_hdmi_probe(struct platform_device*pdev) return ret; } - ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, mtk_hdmi_clk_names_mt8183, ARRAY_SIZE(mtk_hdmi_clk_names_mt8183)); + if(hdmi->conf && hdmi->conf->is_mt8195) + ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, mtk_hdmi_clk_names_mt8195, ARRAY_SIZE(mtk_hdmi_clk_names_mt8195)); + else + ret = mtk_hdmi_dt_parse_pdata(hdmi, pdev, mtk_hdmi_clk_names_mt8183, ARRAY_SIZE(mtk_hdmi_clk_names_mt8183)); if (ret) return ret; platform_set_drvdata(pdev, hdmi); - mtk_hdmi_output_init_mt8183(hdmi); - hdmi->bridge.funcs = &mtk_mt8183_hdmi_bridge_funcs; + if (hdmi->conf && hdmi->conf->is_mt8195) { + mtk_hdmi_output_init_mt8195(hdmi); + hdmi->bridge.funcs = &mtk_mt8195_hdmi_bridge_funcs; + } else { + mtk_hdmi_output_init_mt8183(hdmi); + hdmi->bridge.funcs = &mtk_mt8183_hdmi_bridge_funcs; + }
mtk_hdmi_output_init_mt8195() and mtk_hdmi_output_init_mt8183() has common code, try to merge the common part. I review partially here. And I would keep on reviewing the rest. Regards, CK
quoted hunk ↗ jump to hunk
hdmi->bridge.of_node = pdev->dev.of_node; drm_bridge_add(&hdmi->bridge);@@ -324,7 +373,10 @@ int mtk_drm_hdmi_remove(struct platform_device*pdev) drm_bridge_remove(&hdmi->bridge); - mtk_hdmi_clk_disable_mt8183(hdmi); + if(hdmi->conf && hdmi->conf->is_mt8195) + mtk_hdmi_clk_disable_mt8195(hdmi); + else + mtk_hdmi_clk_disable_mt8183(hdmi); i2c_put_adapter(hdmi->ddc_adpt); return 0;@@ -339,6 +391,13 @@ static const struct mtk_hdmi_confmtk_hdmi_conf_mt8167 = { .cea_modes_only = true, };
_______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel