From f07e572f6447465d8938679533d604e402b0f066 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=81lvaro=20Fern=C3=A1ndez=20Rojas?= Date: Thu, 18 Feb 2021 18:04:33 +0100 Subject: bcm27xx: import latest patches from the RPi foundation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- ...m-vc4-hdmi-rework-connectors-and-encoders.patch | 348 +++++++++++++++++++++ 1 file changed, 348 insertions(+) create mode 100644 target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch (limited to 'target/linux/bcm27xx/patches-5.4/950-0566-drm-vc4-hdmi-rework-connectors-and-encoders.patch') 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 +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 +--- + 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_ */ -- cgit v1.2.3