aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch
diff options
context:
space:
mode:
authorÁlvaro Fernández Rojas <noltari@gmail.com>2021-02-18 18:04:33 +0100
committerÁlvaro Fernández Rojas <noltari@gmail.com>2021-02-18 23:42:32 +0100
commitf07e572f6447465d8938679533d604e402b0f066 (patch)
treecb333bd2a67e59e7c07659514850a0fd55fc825e /target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch
parent5d3a6fd970619dfc55f8259035c3027d7613a2a6 (diff)
downloadupstream-f07e572f6447465d8938679533d604e402b0f066.tar.gz
upstream-f07e572f6447465d8938679533d604e402b0f066.tar.bz2
upstream-f07e572f6447465d8938679533d604e402b0f066.zip
bcm27xx: import latest patches from the RPi foundation
bcm2708: boot tested on RPi B+ v1.2 bcm2709: boot tested on RPi 3B v1.2 and RPi 4B v1.1 4G bcm2710: boot tested on RPi 3B v1.2 bcm2711: boot tested on RPi 4B v1.1 4G Signed-off-by: Álvaro Fernández Rojas <noltari@gmail.com>
Diffstat (limited to 'target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch')
-rw-r--r--target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch348
1 files changed, 348 insertions, 0 deletions
diff --git a/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch b/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch
new file mode 100644
index 0000000000..ebe6432913
--- /dev/null
+++ b/target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch
@@ -0,0 +1,348 @@
+From 50e7e810cf403c4b217c68c8ae2544d16f8063d1 Mon Sep 17 00:00:00 2001
+From: Maxime Ripard <maxime@cerno.tech>
+Date: Mon, 6 Jan 2020 17:17:29 +0100
+Subject: [PATCH] drm/vc4: hdmi: rework connectors and encoders
+
+the vc4_hdmi driver has some custom structures to hold the data it needs to
+associate with the drm_encoder and drm_connector structures.
+
+However, it allocates them separately from the vc4_hdmi structure which
+makes it more complicated than it needs to be.
+
+Move those structures to be contained by vc4_hdmi and update the code
+accordingly.
+
+Signed-off-by: Maxime Ripard <maxime@cerno.tech>
+---
+ drivers/gpu/drm/vc4/vc4_hdmi.c | 84 ++++++++++++++++------------------
+ drivers/gpu/drm/vc4/vc4_hdmi.h | 64 +++++++++++++-------------
+ 2 files changed, 71 insertions(+), 77 deletions(-)
+
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.c
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.c
+@@ -190,19 +190,14 @@ static const struct drm_connector_helper
+ .get_modes = vc4_hdmi_connector_get_modes,
+ };
+
+-static struct drm_connector *vc4_hdmi_connector_init(struct drm_device *dev,
+- struct drm_encoder *encoder)
++static int vc4_hdmi_connector_init(struct drm_device *dev,
++ struct vc4_hdmi *vc4_hdmi)
+ {
+- struct drm_connector *connector;
+- struct vc4_hdmi_connector *hdmi_connector;
++ struct vc4_hdmi_connector *hdmi_connector = &vc4_hdmi->connector;
++ struct drm_connector *connector = &hdmi_connector->base;
++ struct drm_encoder *encoder = &vc4_hdmi->encoder.base.base;
+ int ret;
+
+- hdmi_connector = devm_kzalloc(dev->dev, sizeof(*hdmi_connector),
+- GFP_KERNEL);
+- if (!hdmi_connector)
+- return ERR_PTR(-ENOMEM);
+- connector = &hdmi_connector->base;
+-
+ hdmi_connector->encoder = encoder;
+
+ drm_connector_init(dev, connector, &vc4_hdmi_connector_funcs,
+@@ -212,7 +207,7 @@ static struct drm_connector *vc4_hdmi_co
+ /* Create and attach TV margin props to this connector. */
+ ret = drm_mode_create_tv_margin_properties(dev);
+ if (ret)
+- return ERR_PTR(ret);
++ return ret;
+
+ drm_connector_attach_tv_margin_properties(connector);
+
+@@ -224,7 +219,7 @@ static struct drm_connector *vc4_hdmi_co
+
+ drm_connector_attach_encoder(connector, encoder);
+
+- return connector;
++ return 0;
+ }
+
+ static void vc4_hdmi_encoder_destroy(struct drm_encoder *encoder)
+@@ -303,21 +298,22 @@ static void vc4_hdmi_set_avi_infoframe(s
+ struct vc4_hdmi_encoder *vc4_encoder = to_vc4_hdmi_encoder(encoder);
+ struct vc4_dev *vc4 = encoder->dev->dev_private;
+ struct vc4_hdmi *hdmi = vc4->hdmi;
+- struct drm_connector_state *cstate = hdmi->connector->state;
++ struct drm_connector *connector = &hdmi->connector.base;
++ struct drm_connector_state *cstate = connector->state;
+ struct drm_crtc *crtc = encoder->crtc;
+ const struct drm_display_mode *mode = &crtc->state->adjusted_mode;
+ union hdmi_infoframe frame;
+ int ret;
+
+ ret = drm_hdmi_avi_infoframe_from_display_mode(&frame.avi,
+- hdmi->connector, mode);
++ connector, mode);
+ if (ret < 0) {
+ DRM_ERROR("couldn't fill AVI infoframe\n");
+ return;
+ }
+
+ drm_hdmi_avi_infoframe_quant_range(&frame.avi,
+- hdmi->connector, mode,
++ connector, mode,
+ vc4_encoder->limited_rgb_range ?
+ HDMI_QUANTIZATION_RANGE_LIMITED :
+ HDMI_QUANTIZATION_RANGE_FULL);
+@@ -636,7 +632,8 @@ static const struct drm_encoder_helper_f
+ /* HDMI audio codec callbacks */
+ static void vc4_hdmi_audio_set_mai_clock(struct vc4_hdmi *hdmi)
+ {
+- struct drm_device *drm = hdmi->encoder->dev;
++ struct drm_encoder *encoder = &hdmi->encoder.base.base;
++ struct drm_device *drm = encoder->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+ u32 hsm_clock = clk_get_rate(hdmi->hsm_clock);
+ unsigned long n, m;
+@@ -655,7 +652,7 @@ static void vc4_hdmi_audio_set_mai_clock
+
+ static void vc4_hdmi_set_n_cts(struct vc4_hdmi *hdmi)
+ {
+- struct drm_encoder *encoder = hdmi->encoder;
++ struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_crtc *crtc = encoder->crtc;
+ struct drm_device *drm = encoder->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+@@ -693,7 +690,8 @@ static int vc4_hdmi_audio_startup(struct
+ struct snd_soc_dai *dai)
+ {
+ struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
+- struct drm_encoder *encoder = hdmi->encoder;
++ struct drm_encoder *encoder = &hdmi->encoder.base.base;
++ struct drm_connector *connector = &hdmi->connector.base;
+ struct vc4_dev *vc4 = to_vc4_dev(encoder->dev);
+ int ret;
+
+@@ -710,8 +708,7 @@ static int vc4_hdmi_audio_startup(struct
+ VC4_HDMI_RAM_PACKET_ENABLE))
+ return -ENODEV;
+
+- ret = snd_pcm_hw_constraint_eld(substream->runtime,
+- hdmi->connector->eld);
++ ret = snd_pcm_hw_constraint_eld(substream->runtime, connector->eld);
+ if (ret)
+ return ret;
+
+@@ -725,7 +722,7 @@ static int vc4_hdmi_audio_set_fmt(struct
+
+ static void vc4_hdmi_audio_reset(struct vc4_hdmi *hdmi)
+ {
+- struct drm_encoder *encoder = hdmi->encoder;
++ struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_device *drm = encoder->dev;
+ struct device *dev = &hdmi->pdev->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+@@ -759,7 +756,7 @@ static int vc4_hdmi_audio_hw_params(stru
+ struct snd_soc_dai *dai)
+ {
+ struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
+- struct drm_encoder *encoder = hdmi->encoder;
++ struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_device *drm = encoder->dev;
+ struct device *dev = &hdmi->pdev->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+@@ -832,7 +829,7 @@ static int vc4_hdmi_audio_trigger(struct
+ struct snd_soc_dai *dai)
+ {
+ struct vc4_hdmi *hdmi = dai_to_hdmi(dai);
+- struct drm_encoder *encoder = hdmi->encoder;
++ struct drm_encoder *encoder = &hdmi->encoder.base.base;
+ struct drm_device *drm = encoder->dev;
+ struct vc4_dev *vc4 = to_vc4_dev(drm);
+
+@@ -876,9 +873,10 @@ static int vc4_hdmi_audio_eld_ctl_info(s
+ {
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+ struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
++ struct drm_connector *connector = &hdmi->connector.base;
+
+ uinfo->type = SNDRV_CTL_ELEM_TYPE_BYTES;
+- uinfo->count = sizeof(hdmi->connector->eld);
++ uinfo->count = sizeof(connector->eld);
+
+ return 0;
+ }
+@@ -888,9 +886,10 @@ static int vc4_hdmi_audio_eld_ctl_get(st
+ {
+ struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
+ struct vc4_hdmi *hdmi = snd_component_to_hdmi(component);
++ struct drm_connector *connector = &hdmi->connector.base;
+
+- memcpy(ucontrol->value.bytes.data, hdmi->connector->eld,
+- sizeof(hdmi->connector->eld));
++ memcpy(ucontrol->value.bytes.data, connector->eld,
++ sizeof(connector->eld));
+
+ return 0;
+ }
+@@ -1231,7 +1230,7 @@ static int vc4_hdmi_bind(struct device *
+ struct drm_device *drm = dev_get_drvdata(master);
+ struct vc4_dev *vc4 = drm->dev_private;
+ struct vc4_hdmi *hdmi;
+- struct vc4_hdmi_encoder *vc4_hdmi_encoder;
++ struct drm_encoder *encoder;
+ struct device_node *ddc_node;
+ u32 value;
+ int ret;
+@@ -1240,14 +1239,10 @@ static int vc4_hdmi_bind(struct device *
+ if (!hdmi)
+ return -ENOMEM;
+
+- vc4_hdmi_encoder = devm_kzalloc(dev, sizeof(*vc4_hdmi_encoder),
+- GFP_KERNEL);
+- if (!vc4_hdmi_encoder)
+- return -ENOMEM;
+- vc4_hdmi_encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
+- hdmi->encoder = &vc4_hdmi_encoder->base.base;
+-
+ hdmi->pdev = pdev;
++ encoder = &hdmi->encoder.base.base;
++ encoder->base.type = VC4_ENCODER_TYPE_HDMI0;
++
+ hdmi->hdmicore_regs = vc4_ioremap_regs(pdev, 0);
+ if (IS_ERR(hdmi->hdmicore_regs))
+ return PTR_ERR(hdmi->hdmicore_regs);
+@@ -1333,15 +1328,14 @@ static int vc4_hdmi_bind(struct device *
+ }
+ pm_runtime_enable(dev);
+
+- drm_encoder_init(drm, hdmi->encoder, &vc4_hdmi_encoder_funcs,
++ drm_encoder_init(drm, encoder, &vc4_hdmi_encoder_funcs,
+ DRM_MODE_ENCODER_TMDS, NULL);
+- drm_encoder_helper_add(hdmi->encoder, &vc4_hdmi_encoder_helper_funcs);
++ drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
+
+- hdmi->connector = vc4_hdmi_connector_init(drm, hdmi->encoder);
+- if (IS_ERR(hdmi->connector)) {
+- ret = PTR_ERR(hdmi->connector);
++ ret = vc4_hdmi_connector_init(drm, hdmi);
++ if (ret)
+ goto err_destroy_encoder;
+- }
++
+ #ifdef CONFIG_DRM_VC4_HDMI_CEC
+ hdmi->cec_adap = cec_allocate_adapter(&vc4_hdmi_cec_adap_ops,
+ vc4, "vc4",
+@@ -1351,7 +1345,7 @@ static int vc4_hdmi_bind(struct device *
+ if (ret < 0)
+ goto err_destroy_conn;
+
+- cec_fill_conn_info_from_drm(&conn_info, hdmi->connector);
++ cec_fill_conn_info_from_drm(&conn_info, &hdmi->connector.base);
+ cec_s_conn_info(hdmi->cec_adap, &conn_info);
+
+ HDMI_WRITE(VC4_HDMI_CPU_MASK_SET, 0xffffffff);
+@@ -1388,10 +1382,10 @@ static int vc4_hdmi_bind(struct device *
+ err_delete_cec_adap:
+ cec_delete_adapter(hdmi->cec_adap);
+ err_destroy_conn:
+- vc4_hdmi_connector_destroy(hdmi->connector);
++ vc4_hdmi_connector_destroy(&hdmi->connector.base);
+ #endif
+ err_destroy_encoder:
+- vc4_hdmi_encoder_destroy(hdmi->encoder);
++ vc4_hdmi_encoder_destroy(encoder);
+ err_unprepare_hsm:
+ clk_disable_unprepare(hdmi->hsm_clock);
+ pm_runtime_disable(dev);
+@@ -1409,8 +1403,8 @@ static void vc4_hdmi_unbind(struct devic
+ struct vc4_hdmi *hdmi = vc4->hdmi;
+
+ cec_unregister_adapter(hdmi->cec_adap);
+- vc4_hdmi_connector_destroy(hdmi->connector);
+- vc4_hdmi_encoder_destroy(hdmi->encoder);
++ vc4_hdmi_connector_destroy(&hdmi->connector.base);
++ vc4_hdmi_encoder_destroy(&hdmi->encoder.base.base);
+
+ clk_disable_unprepare(hdmi->hsm_clock);
+ pm_runtime_disable(dev);
+--- a/drivers/gpu/drm/vc4/vc4_hdmi.h
++++ b/drivers/gpu/drm/vc4/vc4_hdmi.h
+@@ -8,6 +8,36 @@
+
+ #include "vc4_drv.h"
+
++/* VC4 HDMI encoder KMS struct */
++struct vc4_hdmi_encoder {
++ struct vc4_encoder base;
++ bool hdmi_monitor;
++ bool limited_rgb_range;
++};
++
++static inline struct vc4_hdmi_encoder *
++to_vc4_hdmi_encoder(struct drm_encoder *encoder)
++{
++ return container_of(encoder, struct vc4_hdmi_encoder, base.base);
++}
++
++/* VC4 HDMI connector KMS struct */
++struct vc4_hdmi_connector {
++ struct drm_connector base;
++
++ /* Since the connector is attached to just the one encoder,
++ * this is the reference to it so we can do the best_encoder()
++ * hook.
++ */
++ struct drm_encoder *encoder;
++};
++
++static inline struct vc4_hdmi_connector *
++to_vc4_hdmi_connector(struct drm_connector *connector)
++{
++ return container_of(connector, struct vc4_hdmi_connector, base);
++}
++
+ /* HDMI audio information */
+ struct vc4_hdmi_audio {
+ struct snd_soc_card card;
+@@ -25,8 +55,8 @@ struct vc4_hdmi_audio {
+ struct vc4_hdmi {
+ struct platform_device *pdev;
+
+- struct drm_encoder *encoder;
+- struct drm_connector *connector;
++ struct vc4_hdmi_encoder encoder;
++ struct vc4_hdmi_connector connector;
+
+ struct vc4_hdmi_audio audio;
+
+@@ -53,34 +83,4 @@ struct vc4_hdmi {
+ #define HD_READ(offset) readl(vc4->hdmi->hd_regs + offset)
+ #define HD_WRITE(offset, val) writel(val, vc4->hdmi->hd_regs + offset)
+
+-/* VC4 HDMI encoder KMS struct */
+-struct vc4_hdmi_encoder {
+- struct vc4_encoder base;
+- bool hdmi_monitor;
+- bool limited_rgb_range;
+-};
+-
+-static inline struct vc4_hdmi_encoder *
+-to_vc4_hdmi_encoder(struct drm_encoder *encoder)
+-{
+- return container_of(encoder, struct vc4_hdmi_encoder, base.base);
+-}
+-
+-/* VC4 HDMI connector KMS struct */
+-struct vc4_hdmi_connector {
+- struct drm_connector base;
+-
+- /* Since the connector is attached to just the one encoder,
+- * this is the reference to it so we can do the best_encoder()
+- * hook.
+- */
+- struct drm_encoder *encoder;
+-};
+-
+-static inline struct vc4_hdmi_connector *
+-to_vc4_hdmi_connector(struct drm_connector *connector)
+-{
+- return container_of(connector, struct vc4_hdmi_connector, base);
+-}
+-
+ #endif /* _VC4_HDMI_H_ */