Commit b2eab3b8 authored by Vladimir Bashkirtsev's avatar Vladimir Bashkirtsev

Fixed VC4 driver in Raspberry Pi patch

parent d9237d13
...@@ -74298,7 +74298,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/Makefile linux-5.12.10-rpi/drivers/g ...@@ -74298,7 +74298,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/Makefile linux-5.12.10-rpi/drivers/g
vc4_hdmi.o \ vc4_hdmi.o \
diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_crtc.c diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_crtc.c
--- linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c 2021-06-10 11:41:49.000000000 +0000 --- linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c 2021-06-10 11:41:49.000000000 +0000
+++ linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_crtc.c 2025-06-20 00:09:07.027997723 +0000 +++ linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_crtc.c 2025-06-19 12:13:33.443261180 +0000
@@ -279,19 +279,15 @@ @@ -279,19 +279,15 @@
* allows drivers to push pixels to more than one encoder from the * allows drivers to push pixels to more than one encoder from the
* same CRTC. * same CRTC.
...@@ -74326,7 +74326,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers ...@@ -74326,7 +74326,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers
return NULL; return NULL;
} }
@@ -305,11 +301,11 @@ @@ -305,22 +301,29 @@
CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR); CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_FIFO_CLR);
} }
...@@ -74340,7 +74340,11 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers ...@@ -74340,7 +74340,11 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder); struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc); struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc); const struct vc4_pv_data *pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
@@ -319,8 +315,15 @@ - struct drm_crtc_state *state = crtc->state;
- struct drm_display_mode *mode = &state->adjusted_mode;
+ struct drm_crtc_state *crtc_state = crtc->state;
+ struct drm_display_mode *mode = &crtc_state->adjusted_mode;
bool interlace = mode->flags & DRM_MODE_FLAG_INTERLACE;
u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1; u32 pixel_rep = (mode->flags & DRM_MODE_FLAG_DBLCLK) ? 2 : 1;
bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 || bool is_dsi = (vc4_encoder->type == VC4_ENCODER_TYPE_DSI0 ||
vc4_encoder->type == VC4_ENCODER_TYPE_DSI1); vc4_encoder->type == VC4_ENCODER_TYPE_DSI1);
...@@ -74443,7 +74447,68 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers ...@@ -74443,7 +74447,68 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers
if (is_dsi) if (is_dsi)
CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep); CRTC_WRITE(PV_HACT_ACT, mode->hdisplay * pixel_rep);
@@ -496,8 +510,12 @@ @@ -421,10 +435,10 @@
}
static int vc4_crtc_disable(struct drm_crtc *crtc,
+ struct drm_encoder *encoder,
struct drm_atomic_state *state,
unsigned int channel)
{
- struct drm_encoder *encoder = vc4_get_crtc_encoder(crtc);
struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
struct drm_device *dev = crtc->dev;
@@ -465,10 +479,29 @@
return 0;
}
+static struct drm_encoder *vc4_crtc_get_encoder_by_type(struct drm_crtc *crtc,
+ enum vc4_encoder_type type)
+{
+ struct drm_encoder *encoder;
+
+ drm_for_each_encoder(encoder, crtc->dev) {
+ struct vc4_encoder *vc4_encoder = to_vc4_encoder(encoder);
+
+ if (vc4_encoder->type == type)
+ return encoder;
+ }
+
+ return NULL;
+}
+
int vc4_crtc_disable_at_boot(struct drm_crtc *crtc)
{
struct drm_device *drm = crtc->dev;
struct vc4_crtc *vc4_crtc = to_vc4_crtc(crtc);
+ enum vc4_encoder_type encoder_type;
+ const struct vc4_pv_data *pv_data;
+ struct drm_encoder *encoder;
+ unsigned encoder_sel;
int channel;
if (!(of_device_is_compatible(vc4_crtc->pdev->dev.of_node,
@@ -487,7 +520,17 @@
if (channel < 0)
return 0;
- return vc4_crtc_disable(crtc, NULL, channel);
+ encoder_sel = VC4_GET_FIELD(CRTC_READ(PV_CONTROL), PV_CONTROL_CLK_SELECT);
+ if (WARN_ON(encoder_sel != 0))
+ return 0;
+
+ pv_data = vc4_crtc_to_vc4_pv_data(vc4_crtc);
+ encoder_type = pv_data->encoder_types[encoder_sel];
+ encoder = vc4_crtc_get_encoder_by_type(crtc, encoder_type);
+ if (WARN_ON(!encoder))
+ return 0;
+
+ return vc4_crtc_disable(crtc, encoder, NULL, channel);
}
static void vc4_crtc_atomic_disable(struct drm_crtc *crtc,
@@ -496,14 +539,18 @@
struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state, struct drm_crtc_state *old_state = drm_atomic_get_old_crtc_state(state,
crtc); crtc);
struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state); struct vc4_crtc_state *old_vc4_state = to_vc4_crtc_state(old_state);
...@@ -74456,7 +74521,14 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers ...@@ -74456,7 +74521,14 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers
require_hvs_enabled(dev); require_hvs_enabled(dev);
/* Disable vblank irq handling before crtc is disabled. */ /* Disable vblank irq handling before crtc is disabled. */
@@ -522,11 +540,16 @@ drm_crtc_vblank_off(crtc);
- vc4_crtc_disable(crtc, state, old_vc4_state->assigned_channel);
+ vc4_crtc_disable(crtc, encoder, state, old_vc4_state->assigned_channel);
/*
* Make sure we issue a vblank event after disabling the CRTC if
@@ -522,11 +569,16 @@
static void vc4_crtc_atomic_enable(struct drm_crtc *crtc, static void vc4_crtc_atomic_enable(struct drm_crtc *crtc,
struct drm_atomic_state *state) struct drm_atomic_state *state)
{ {
...@@ -74474,7 +74546,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers ...@@ -74474,7 +74546,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers
require_hvs_enabled(dev); require_hvs_enabled(dev);
/* Enable vblank irq handling before crtc is started otherwise /* Enable vblank irq handling before crtc is started otherwise
@@ -539,7 +562,7 @@ @@ -539,7 +591,7 @@
if (vc4_encoder->pre_crtc_configure) if (vc4_encoder->pre_crtc_configure)
vc4_encoder->pre_crtc_configure(encoder, state); vc4_encoder->pre_crtc_configure(encoder, state);
...@@ -74483,7 +74555,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers ...@@ -74483,7 +74555,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers
CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN); CRTC_WRITE(PV_CONTROL, CRTC_READ(PV_CONTROL) | PV_CONTROL_EN);
@@ -608,12 +631,27 @@ @@ -608,12 +660,27 @@
struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state); struct vc4_crtc_state *vc4_state = to_vc4_crtc_state(crtc_state);
struct drm_connector *conn; struct drm_connector *conn;
struct drm_connector_state *conn_state; struct drm_connector_state *conn_state;
...@@ -74511,6 +74583,25 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers ...@@ -74511,6 +74583,25 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_crtc.c linux-5.12.10-rpi/drivers
for_each_new_connector_in_state(state, conn, conn_state, for_each_new_connector_in_state(state, conn, conn_state,
i) { i) {
if (conn_state->crtc != crtc) if (conn_state->crtc != crtc)
@@ -994,7 +1061,7 @@
.fifo_depth = 64,
.pixels_per_clock = 1,
.encoder_types = {
- [0] = VC4_ENCODER_TYPE_VEC,
+ [PV_CONTROL_CLK_SELECT_VEC] = VC4_ENCODER_TYPE_VEC,
},
};
@@ -1035,6 +1102,9 @@
struct vc4_encoder *vc4_encoder;
int i;
+ if (encoder->encoder_type == DRM_MODE_ENCODER_VIRTUAL)
+ continue;
+
vc4_encoder = to_vc4_encoder(encoder);
for (i = 0; i < ARRAY_SIZE(pv_data->encoder_types); i++) {
if (vc4_encoder->type == encoder_types[i]) {
diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_debugfs.c linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_debugfs.c diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_debugfs.c linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_debugfs.c
--- linux-5.12.10/drivers/gpu/drm/vc4/vc4_debugfs.c 2021-06-10 11:41:49.000000000 +0000 --- linux-5.12.10/drivers/gpu/drm/vc4/vc4_debugfs.c 2021-06-10 11:41:49.000000000 +0000
+++ linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_debugfs.c 2025-06-19 19:37:20.021894985 +0000 +++ linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_debugfs.c 2025-06-19 19:37:20.021894985 +0000
...@@ -77103,7 +77194,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_firmware_kms.c linux-5.12.10-rpi ...@@ -77103,7 +77194,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_firmware_kms.c linux-5.12.10-rpi
+}; +};
diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_hdmi.c diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_hdmi.c
--- linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c 2021-06-10 11:41:49.000000000 +0000 --- linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c 2021-06-10 11:41:49.000000000 +0000
+++ linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_hdmi.c 2025-06-20 00:26:58.693402678 +0000 +++ linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_hdmi.c 2025-06-19 12:13:33.455261053 +0000
@@ -35,6 +35,7 @@ @@ -35,6 +35,7 @@
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include <drm/drm_probe_helper.h> #include <drm/drm_probe_helper.h>
...@@ -77169,7 +77260,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77169,7 +77260,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
return 0; return 0;
} }
@@ -153,6 +172,8 @@ @@ -153,18 +172,20 @@
static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {} static void vc4_hdmi_cec_update_clk_div(struct vc4_hdmi *vc4_hdmi) {}
#endif #endif
...@@ -77178,7 +77269,12 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77178,7 +77269,12 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
static enum drm_connector_status static enum drm_connector_status
vc4_hdmi_connector_detect(struct drm_connector *connector, bool force) vc4_hdmi_connector_detect(struct drm_connector *connector, bool force)
{ {
@@ -163,8 +184,6 @@ struct vc4_hdmi *vc4_hdmi = connector_to_vc4_hdmi(connector);
bool connected = false;
+ WARN_ON(pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev));
+
if (vc4_hdmi->hpd_gpio) {
if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^ if (gpio_get_value_cansleep(vc4_hdmi->hpd_gpio) ^
vc4_hdmi->hpd_active_low) vc4_hdmi->hpd_active_low)
connected = true; connected = true;
...@@ -77187,16 +77283,22 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77187,16 +77283,22 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
} else if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) { } else if (HDMI_READ(HDMI_HOTPLUG) & VC4_HDMI_HOTPLUG_CONNECTED) {
connected = true; connected = true;
} }
@@ -180,6 +199,8 @@ @@ -180,10 +201,14 @@
} }
} }
+ vc4_hdmi_enable_scrambling(&vc4_hdmi->encoder.base.base); + vc4_hdmi_enable_scrambling(&vc4_hdmi->encoder.base.base);
+ +
+ pm_runtime_put(&vc4_hdmi->pdev->dev);
return connector_status_connected; return connector_status_connected;
} }
@@ -211,9 +232,47 @@ cec_phys_addr_invalidate(vc4_hdmi->cec_adap);
+ pm_runtime_put(&vc4_hdmi->pdev->dev);
return connector_status_disconnected;
}
@@ -211,9 +236,47 @@
ret = drm_add_edid_modes(connector, edid); ret = drm_add_edid_modes(connector, edid);
kfree(edid); kfree(edid);
...@@ -77244,7 +77346,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77244,7 +77346,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
static void vc4_hdmi_connector_reset(struct drm_connector *connector) static void vc4_hdmi_connector_reset(struct drm_connector *connector)
{ {
struct vc4_hdmi_connector_state *old_state = struct vc4_hdmi_connector_state *old_state =
@@ -263,6 +322,7 @@ @@ -263,6 +326,7 @@
static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = { static const struct drm_connector_helper_funcs vc4_hdmi_connector_helper_funcs = {
.get_modes = vc4_hdmi_connector_get_modes, .get_modes = vc4_hdmi_connector_get_modes,
...@@ -77252,7 +77354,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77252,7 +77354,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
}; };
static int vc4_hdmi_connector_init(struct drm_device *dev, static int vc4_hdmi_connector_init(struct drm_device *dev,
@@ -290,6 +350,11 @@ @@ -290,6 +354,11 @@
if (ret) if (ret)
return ret; return ret;
...@@ -77264,7 +77366,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77264,7 +77366,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
drm_connector_attach_tv_margin_properties(connector); drm_connector_attach_tv_margin_properties(connector);
drm_connector_attach_max_bpc_property(connector, 8, 12); drm_connector_attach_max_bpc_property(connector, 8, 12);
@@ -298,6 +363,10 @@ @@ -298,6 +367,10 @@
connector->interlace_allowed = 1; connector->interlace_allowed = 1;
connector->doublescan_allowed = 0; connector->doublescan_allowed = 0;
...@@ -77275,7 +77377,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77275,7 +77377,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
drm_connector_attach_encoder(connector, encoder); drm_connector_attach_encoder(connector, encoder);
@@ -329,9 +398,11 @@ @@ -329,9 +402,11 @@
const struct vc4_hdmi_register *ram_packet_start = const struct vc4_hdmi_register *ram_packet_start =
&vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START]; &vc4_hdmi->variant->registers[HDMI_RAM_PACKET_START];
u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id; u32 packet_reg = ram_packet_start->offset + VC4_HDMI_PACKET_STRIDE * packet_id;
...@@ -77288,7 +77390,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77288,7 +77390,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
ssize_t len, i; ssize_t len, i;
int ret; int ret;
@@ -364,6 +435,13 @@ @@ -364,6 +439,13 @@
packet_reg += 4; packet_reg += 4;
} }
...@@ -77302,7 +77404,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77302,7 +77404,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, HDMI_WRITE(HDMI_RAM_PACKET_CONFIG,
HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id)); HDMI_READ(HDMI_RAM_PACKET_CONFIG) | BIT(packet_id));
ret = wait_for((HDMI_READ(HDMI_RAM_PACKET_STATUS) & ret = wait_for((HDMI_READ(HDMI_RAM_PACKET_STATUS) &
@@ -395,7 +473,7 @@ @@ -395,7 +477,7 @@
vc4_encoder->limited_rgb_range ? vc4_encoder->limited_rgb_range ?
HDMI_QUANTIZATION_RANGE_LIMITED : HDMI_QUANTIZATION_RANGE_LIMITED :
HDMI_QUANTIZATION_RANGE_FULL); HDMI_QUANTIZATION_RANGE_FULL);
...@@ -77311,32 +77413,32 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77311,32 +77413,32 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
drm_hdmi_avi_infoframe_bars(&frame.avi, cstate); drm_hdmi_avi_infoframe_bars(&frame.avi, cstate);
vc4_hdmi_write_infoframe(encoder, &frame); vc4_hdmi_write_infoframe(encoder, &frame);
@@ -420,14 +498,28 @@ @@ -420,14 +502,28 @@
static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder) static void vc4_hdmi_set_audio_infoframe(struct drm_encoder *encoder)
{ {
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+ struct hdmi_audio_infoframe *audio = &vc4_hdmi->audio.infoframe; + struct hdmi_audio_infoframe *audio = &vc4_hdmi->audio.infoframe;
union hdmi_infoframe frame; + union hdmi_infoframe frame;
+
- hdmi_audio_infoframe_init(&frame.audio);
+ memcpy(&frame.audio, audio, sizeof(*audio)); + memcpy(&frame.audio, audio, sizeof(*audio));
+ vc4_hdmi_write_infoframe(encoder, &frame); + vc4_hdmi_write_infoframe(encoder, &frame);
+} +}
+
- frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
- frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
- frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
- frame.audio.channels = vc4_hdmi->audio.channels;
+static void vc4_hdmi_set_hdr_infoframe(struct drm_encoder *encoder) +static void vc4_hdmi_set_hdr_infoframe(struct drm_encoder *encoder)
+{ +{
+ struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); + struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
+ struct drm_connector *connector = &vc4_hdmi->connector; + struct drm_connector *connector = &vc4_hdmi->connector;
+ struct drm_connector_state *conn_state = connector->state; + struct drm_connector_state *conn_state = connector->state;
+ union hdmi_infoframe frame; union hdmi_infoframe frame;
+
- hdmi_audio_infoframe_init(&frame.audio);
+ if (!vc4_hdmi->variant->supports_hdr) + if (!vc4_hdmi->variant->supports_hdr)
+ return; + return;
+
- frame.audio.coding_type = HDMI_AUDIO_CODING_TYPE_STREAM;
- frame.audio.sample_frequency = HDMI_AUDIO_SAMPLE_FREQUENCY_STREAM;
- frame.audio.sample_size = HDMI_AUDIO_SAMPLE_SIZE_STREAM;
- frame.audio.channels = vc4_hdmi->audio.channels;
+ if (!conn_state->hdr_output_metadata) + if (!conn_state->hdr_output_metadata)
+ return; + return;
+ +
...@@ -77345,7 +77447,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77345,7 +77447,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
vc4_hdmi_write_infoframe(encoder, &frame); vc4_hdmi_write_infoframe(encoder, &frame);
} }
@@ -444,6 +536,94 @@ @@ -444,6 +540,94 @@
*/ */
if (vc4_hdmi->audio.streaming) if (vc4_hdmi->audio.streaming)
vc4_hdmi_set_audio_infoframe(encoder); vc4_hdmi_set_audio_infoframe(encoder);
...@@ -77440,7 +77542,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77440,7 +77542,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
} }
static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder, static void vc4_hdmi_encoder_post_crtc_disable(struct drm_encoder *encoder,
@@ -453,11 +633,13 @@ @@ -453,11 +637,13 @@
HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0); HDMI_WRITE(HDMI_RAM_PACKET_CONFIG, 0);
...@@ -77457,7 +77559,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77457,7 +77559,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
} }
static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder, static void vc4_hdmi_encoder_post_crtc_powerdown(struct drm_encoder *encoder,
@@ -466,13 +648,16 @@ @@ -466,14 +652,16 @@
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
int ret; int ret;
...@@ -77471,13 +77573,14 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77471,13 +77573,14 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
- HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE); - HDMI_READ(HDMI_VID_CTL) & ~VC4_HD_VID_CTL_ENABLE);
- -
clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock); clk_disable_unprepare(vc4_hdmi->pixel_bvb_clock);
- clk_disable_unprepare(vc4_hdmi->hsm_clock);
+ if (vc4_hdmi->bvb_req) + if (vc4_hdmi->bvb_req)
+ clk_request_done(vc4_hdmi->bvb_req); + clk_request_done(vc4_hdmi->bvb_req);
+ clk_request_done(vc4_hdmi->hsm_req); + clk_request_done(vc4_hdmi->hsm_req);
clk_disable_unprepare(vc4_hdmi->hsm_clock);
clk_disable_unprepare(vc4_hdmi->pixel_clock); clk_disable_unprepare(vc4_hdmi->pixel_clock);
@@ -573,12 +758,12 @@ ret = pm_runtime_put(&vc4_hdmi->pdev->dev);
@@ -573,12 +761,12 @@
VC4_HDMI_VERTA_VFP) | VC4_HDMI_VERTA_VFP) |
VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL)); VC4_SET_FIELD(mode->crtc_vdisplay, VC4_HDMI_VERTA_VAL));
u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) | u32 vertb = (VC4_SET_FIELD(0, VC4_HDMI_VERTB_VSPO) |
...@@ -77493,7 +77596,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77493,7 +77596,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
VC4_HDMI_VERTB_VBP)); VC4_HDMI_VERTB_VBP));
HDMI_WRITE(HDMI_HORZA, HDMI_WRITE(HDMI_HORZA,
@@ -619,12 +804,12 @@ @@ -619,12 +807,12 @@
VC5_HDMI_VERTA_VFP) | VC5_HDMI_VERTA_VFP) |
VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL)); VC4_SET_FIELD(mode->crtc_vdisplay, VC5_HDMI_VERTA_VAL));
u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) | u32 vertb = (VC4_SET_FIELD(0, VC5_HDMI_VERTB_VSPO) |
...@@ -77509,7 +77612,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77509,7 +77612,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
VC4_HDMI_VERTB_VBP)); VC4_HDMI_VERTB_VBP));
unsigned char gcp; unsigned char gcp;
bool gcp_en; bool gcp_en;
@@ -687,6 +872,11 @@ @@ -687,6 +875,11 @@
reg |= gcp_en ? VC5_HDMI_GCP_CONFIG_GCP_ENABLE : 0; reg |= gcp_en ? VC5_HDMI_GCP_CONFIG_GCP_ENABLE : 0;
HDMI_WRITE(HDMI_GCP_CONFIG, reg); HDMI_WRITE(HDMI_GCP_CONFIG, reg);
...@@ -77521,7 +77624,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77521,7 +77624,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
HDMI_WRITE(HDMI_CLOCK_STOP, 0); HDMI_WRITE(HDMI_CLOCK_STOP, 0);
} }
@@ -714,32 +904,17 @@ @@ -714,32 +907,17 @@
"VC4_HDMI_FIFO_CTL_RECENTER_DONE"); "VC4_HDMI_FIFO_CTL_RECENTER_DONE");
} }
...@@ -77558,7 +77661,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77558,7 +77661,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
int ret; int ret;
ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev); ret = pm_runtime_get_sync(&vc4_hdmi->pdev->dev);
@@ -752,36 +927,20 @@ @@ -752,66 +930,42 @@
ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate); ret = clk_set_rate(vc4_hdmi->pixel_clock, pixel_rate);
if (ret) { if (ret) {
DRM_ERROR("Failed to set pixel clock rate: %d\n", ret); DRM_ERROR("Failed to set pixel clock rate: %d\n", ret);
...@@ -77594,6 +77697,13 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77594,6 +77697,13 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
- if (ret) { - if (ret) {
- DRM_ERROR("Failed to set HSM clock rate: %d\n", ret); - DRM_ERROR("Failed to set HSM clock rate: %d\n", ret);
- return; - return;
- }
-
- ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
- if (ret) {
- DRM_ERROR("Failed to turn on HSM clock: %d\n", ret);
- clk_disable_unprepare(vc4_hdmi->pixel_clock);
- return;
+ hsm_rate = vc4_hdmi->variant->calc_hsm_clock(vc4_hdmi, pixel_rate); + hsm_rate = vc4_hdmi->variant->calc_hsm_clock(vc4_hdmi, pixel_rate);
+ vc4_hdmi->hsm_req = clk_request_start(vc4_hdmi->hsm_clock, hsm_rate); + vc4_hdmi->hsm_req = clk_request_start(vc4_hdmi->hsm_clock, hsm_rate);
+ if (IS_ERR(vc4_hdmi->hsm_req)) { + if (IS_ERR(vc4_hdmi->hsm_req)) {
...@@ -77601,9 +77711,6 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77601,9 +77711,6 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
+ goto err_disable_pixel_clk; + goto err_disable_pixel_clk;
} }
ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
@@ -793,25 +952,24 @@
vc4_hdmi_cec_update_clk_div(vc4_hdmi); vc4_hdmi_cec_update_clk_div(vc4_hdmi);
- /* - /*
...@@ -77641,7 +77748,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77641,7 +77748,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
} }
if (vc4_hdmi->variant->phy_init) if (vc4_hdmi->variant->phy_init)
@@ -824,6 +982,19 @@ @@ -824,6 +978,19 @@
if (vc4_hdmi->variant->set_timings) if (vc4_hdmi->variant->set_timings)
vc4_hdmi->variant->set_timings(vc4_hdmi, conn_state, mode); vc4_hdmi->variant->set_timings(vc4_hdmi, conn_state, mode);
...@@ -77661,7 +77768,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77661,7 +77768,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
} }
static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder, static void vc4_hdmi_encoder_pre_crtc_enable(struct drm_encoder *encoder,
@@ -861,6 +1032,7 @@ @@ -861,6 +1028,7 @@
HDMI_WRITE(HDMI_VID_CTL, HDMI_WRITE(HDMI_VID_CTL,
VC4_HD_VID_CTL_ENABLE | VC4_HD_VID_CTL_ENABLE |
...@@ -77669,7 +77776,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77669,7 +77776,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
VC4_HD_VID_CTL_UNDERFLOW_ENABLE | VC4_HD_VID_CTL_UNDERFLOW_ENABLE |
VC4_HD_VID_CTL_FRAME_COUNTER_RESET | VC4_HD_VID_CTL_FRAME_COUNTER_RESET |
(vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) | (vsync_pos ? 0 : VC4_HD_VID_CTL_VSYNC_LOW) |
@@ -906,6 +1078,7 @@ @@ -906,6 +1074,7 @@
} }
vc4_hdmi_recenter_fifo(vc4_hdmi); vc4_hdmi_recenter_fifo(vc4_hdmi);
...@@ -77677,7 +77784,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77677,7 +77784,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
} }
static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder) static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
@@ -926,6 +1099,7 @@ @@ -926,6 +1095,7 @@
unsigned long long tmds_rate; unsigned long long tmds_rate;
if (vc4_hdmi->variant->unsupported_odd_h_timings && if (vc4_hdmi->variant->unsupported_odd_h_timings &&
...@@ -77685,7 +77792,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77685,7 +77792,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
((mode->hdisplay % 2) || (mode->hsync_start % 2) || ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
(mode->hsync_end % 2) || (mode->htotal % 2))) (mode->hsync_end % 2) || (mode->htotal % 2)))
return -EINVAL; return -EINVAL;
@@ -958,6 +1132,9 @@ @@ -958,6 +1128,9 @@
if (pixel_rate > vc4_hdmi->variant->max_pixel_clock) if (pixel_rate > vc4_hdmi->variant->max_pixel_clock)
return -EINVAL; return -EINVAL;
...@@ -77695,7 +77802,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77695,7 +77802,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
vc4_state->pixel_rate = pixel_rate; vc4_state->pixel_rate = pixel_rate;
return 0; return 0;
@@ -970,6 +1147,7 @@ @@ -970,6 +1143,7 @@
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder); struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
if (vc4_hdmi->variant->unsupported_odd_h_timings && if (vc4_hdmi->variant->unsupported_odd_h_timings &&
...@@ -77703,7 +77810,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77703,7 +77810,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
((mode->hdisplay % 2) || (mode->hsync_start % 2) || ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
(mode->hsync_end % 2) || (mode->htotal % 2))) (mode->hsync_end % 2) || (mode->htotal % 2)))
return MODE_H_ILLEGAL; return MODE_H_ILLEGAL;
@@ -977,6 +1155,9 @@ @@ -977,6 +1151,9 @@
if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock) if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock)
return MODE_CLOCK_HIGH; return MODE_CLOCK_HIGH;
...@@ -77713,7 +77820,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77713,7 +77820,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
return MODE_OK; return MODE_OK;
} }
@@ -987,6 +1168,39 @@ @@ -987,6 +1164,39 @@
.enable = vc4_hdmi_encoder_enable, .enable = vc4_hdmi_encoder_enable,
}; };
...@@ -77753,7 +77860,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77753,7 +77860,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask) static u32 vc4_hdmi_channel_map(struct vc4_hdmi *vc4_hdmi, u32 channel_mask)
{ {
int i; int i;
@@ -1012,12 +1226,13 @@ @@ -1012,12 +1222,13 @@
} }
/* HDMI audio codec callbacks */ /* HDMI audio codec callbacks */
...@@ -77769,7 +77876,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77769,7 +77876,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
VC4_HD_MAI_SMP_N_MASK >> VC4_HD_MAI_SMP_N_MASK >>
VC4_HD_MAI_SMP_N_SHIFT, VC4_HD_MAI_SMP_N_SHIFT,
(VC4_HD_MAI_SMP_M_MASK >> (VC4_HD_MAI_SMP_M_MASK >>
@@ -1029,12 +1244,11 @@ @@ -1029,12 +1240,11 @@
VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M)); VC4_SET_FIELD(m - 1, VC4_HD_MAI_SMP_M));
} }
...@@ -77783,7 +77890,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77783,7 +77890,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
u32 n, cts; u32 n, cts;
u64 tmp; u64 tmp;
@@ -1063,18 +1277,10 @@ @@ -1063,18 +1273,10 @@
return snd_soc_card_get_drvdata(card); return snd_soc_card_get_drvdata(card);
} }
...@@ -77804,7 +77911,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77804,7 +77911,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
/* /*
* If the HDMI encoder hasn't probed, or the encoder is * If the HDMI encoder hasn't probed, or the encoder is
@@ -1084,15 +1290,18 @@ @@ -1084,15 +1286,18 @@
VC4_HDMI_RAM_PACKET_ENABLE)) VC4_HDMI_RAM_PACKET_ENABLE))
return -ENODEV; return -ENODEV;
...@@ -77830,7 +77937,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77830,7 +77937,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
return 0; return 0;
} }
@@ -1112,48 +1321,96 @@ @@ -1112,48 +1317,96 @@
HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_FLUSH); HDMI_WRITE(HDMI_MAI_CTL, VC4_HD_MAI_CTL_FLUSH);
} }
...@@ -77847,10 +77954,10 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77847,10 +77954,10 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
+ VC4_HD_MAI_CTL_DLATE | + VC4_HD_MAI_CTL_DLATE |
+ VC4_HD_MAI_CTL_ERRORE | + VC4_HD_MAI_CTL_ERRORE |
+ VC4_HD_MAI_CTL_ERRORF); + VC4_HD_MAI_CTL_ERRORF);
+
+ if (vc4_hdmi->variant->phy_rng_disable) + if (vc4_hdmi->variant->phy_rng_disable)
+ vc4_hdmi->variant->phy_rng_disable(vc4_hdmi); + vc4_hdmi->variant->phy_rng_disable(vc4_hdmi);
+
+ vc4_hdmi->audio.streaming = false; + vc4_hdmi->audio.streaming = false;
vc4_hdmi_audio_reset(vc4_hdmi); vc4_hdmi_audio_reset(vc4_hdmi);
+} +}
...@@ -77953,7 +78060,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -77953,7 +78060,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
/* The B frame identifier should match the value used by alsa-lib (8) */ /* The B frame identifier should match the value used by alsa-lib (8) */
audio_packet_config = audio_packet_config =
@@ -1161,122 +1418,33 @@ @@ -1161,122 +1414,33 @@
VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_INACTIVE_CHANNELS | VC4_HDMI_AUDIO_PACKET_ZERO_DATA_ON_INACTIVE_CHANNELS |
VC4_SET_FIELD(0x8, VC4_HDMI_AUDIO_PACKET_B_FRAME_IDENTIFIER); VC4_SET_FIELD(0x8, VC4_HDMI_AUDIO_PACKET_B_FRAME_IDENTIFIER);
...@@ -78086,7 +78193,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78086,7 +78193,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = { static const struct snd_soc_dapm_widget vc4_hdmi_audio_widgets[] = {
SND_SOC_DAPM_OUTPUT("TX"), SND_SOC_DAPM_OUTPUT("TX"),
}; };
@@ -1287,8 +1455,6 @@ @@ -1287,8 +1451,6 @@
static const struct snd_soc_component_driver vc4_hdmi_audio_component_drv = { static const struct snd_soc_component_driver vc4_hdmi_audio_component_drv = {
.name = "vc4-hdmi-codec-dai-component", .name = "vc4-hdmi-codec-dai-component",
...@@ -78095,7 +78202,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78095,7 +78202,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
.dapm_widgets = vc4_hdmi_audio_widgets, .dapm_widgets = vc4_hdmi_audio_widgets,
.num_dapm_widgets = ARRAY_SIZE(vc4_hdmi_audio_widgets), .num_dapm_widgets = ARRAY_SIZE(vc4_hdmi_audio_widgets),
.dapm_routes = vc4_hdmi_audio_routes, .dapm_routes = vc4_hdmi_audio_routes,
@@ -1299,28 +1465,6 @@ @@ -1299,28 +1461,6 @@
.non_legacy_dai_naming = 1, .non_legacy_dai_naming = 1,
}; };
...@@ -78124,7 +78231,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78124,7 +78231,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
static const struct snd_soc_component_driver vc4_hdmi_audio_cpu_dai_comp = { static const struct snd_soc_component_driver vc4_hdmi_audio_cpu_dai_comp = {
.name = "vc4-hdmi-cpu-dai-component", .name = "vc4-hdmi-cpu-dai-component",
}; };
@@ -1347,7 +1491,6 @@ @@ -1347,7 +1487,6 @@
SNDRV_PCM_RATE_192000, SNDRV_PCM_RATE_192000,
.formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE, .formats = SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE,
}, },
...@@ -78132,7 +78239,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78132,7 +78239,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
}; };
static const struct snd_dmaengine_pcm_config pcm_conf = { static const struct snd_dmaengine_pcm_config pcm_conf = {
@@ -1355,6 +1498,31 @@ @@ -1355,6 +1494,31 @@
.prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config, .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
}; };
...@@ -78164,7 +78271,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78164,7 +78271,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi) static int vc4_hdmi_audio_init(struct vc4_hdmi *vc4_hdmi)
{ {
const struct vc4_hdmi_register *mai_data = const struct vc4_hdmi_register *mai_data =
@@ -1362,13 +1530,16 @@ @@ -1362,13 +1526,16 @@
struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link; struct snd_soc_dai_link *dai_link = &vc4_hdmi->audio.link;
struct snd_soc_card *card = &vc4_hdmi->audio.card; struct snd_soc_card *card = &vc4_hdmi->audio.card;
struct device *dev = &vc4_hdmi->pdev->dev; struct device *dev = &vc4_hdmi->pdev->dev;
...@@ -78183,7 +78290,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78183,7 +78290,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
return 0; return 0;
} }
@@ -1408,12 +1579,13 @@ @@ -1408,12 +1575,13 @@
return ret; return ret;
} }
...@@ -78203,7 +78310,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78203,7 +78310,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
} }
dai_link->cpus = &vc4_hdmi->audio.cpu; dai_link->cpus = &vc4_hdmi->audio.cpu;
@@ -1426,9 +1598,9 @@ @@ -1426,9 +1594,9 @@
dai_link->name = "MAI"; dai_link->name = "MAI";
dai_link->stream_name = "MAI PCM"; dai_link->stream_name = "MAI PCM";
...@@ -78215,7 +78322,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78215,7 +78322,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
dai_link->platforms->name = dev_name(dev); dai_link->platforms->name = dev_name(dev);
card->dai_link = dai_link; card->dai_link = dai_link;
@@ -1454,6 +1626,60 @@ @@ -1454,6 +1622,60 @@
} }
...@@ -78276,7 +78383,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78276,7 +78383,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
#ifdef CONFIG_DRM_VC4_HDMI_CEC #ifdef CONFIG_DRM_VC4_HDMI_CEC
static irqreturn_t vc4_cec_irq_handler_rx_thread(int irq, void *priv) static irqreturn_t vc4_cec_irq_handler_rx_thread(int irq, void *priv)
{ {
@@ -1572,51 +1798,74 @@ @@ -1572,51 +1794,74 @@
return ret; return ret;
} }
...@@ -78289,11 +78396,11 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78289,11 +78396,11 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
- u32 val = HDMI_READ(HDMI_CEC_CNTRL_5); - u32 val = HDMI_READ(HDMI_CEC_CNTRL_5);
+ u32 val; + u32 val;
+ int ret; + int ret;
+
+ ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev); + ret = pm_runtime_resume_and_get(&vc4_hdmi->pdev->dev);
+ if (ret) + if (ret)
+ return ret; + return ret;
+
+ val = HDMI_READ(HDMI_CEC_CNTRL_5); + val = HDMI_READ(HDMI_CEC_CNTRL_5);
val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET | val &= ~(VC4_HDMI_CEC_TX_SW_RESET | VC4_HDMI_CEC_RX_SW_RESET |
VC4_HDMI_CEC_CNT_TO_4700_US_MASK | VC4_HDMI_CEC_CNT_TO_4700_US_MASK |
...@@ -78381,7 +78488,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78381,7 +78488,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr) static int vc4_hdmi_cec_adap_log_addr(struct cec_adapter *adap, u8 log_addr)
{ {
struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap); struct vc4_hdmi *vc4_hdmi = cec_get_drvdata(adap);
@@ -1696,38 +1945,46 @@ @@ -1696,38 +1941,46 @@
vc4_hdmi_cec_update_clk_div(vc4_hdmi); vc4_hdmi_cec_update_clk_div(vc4_hdmi);
if (vc4_hdmi->variant->external_irq_controller) { if (vc4_hdmi->variant->external_irq_controller) {
...@@ -78444,7 +78551,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78444,7 +78551,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
err_delete_cec_adap: err_delete_cec_adap:
cec_delete_adapter(vc4_hdmi->cec_adap); cec_delete_adapter(vc4_hdmi->cec_adap);
@@ -1736,6 +1993,15 @@ @@ -1736,6 +1989,15 @@
static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi) static void vc4_hdmi_cec_exit(struct vc4_hdmi *vc4_hdmi)
{ {
...@@ -78460,7 +78567,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78460,7 +78567,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
cec_unregister_adapter(vc4_hdmi->cec_adap); cec_unregister_adapter(vc4_hdmi->cec_adap);
} }
#else #else
@@ -1830,6 +2096,7 @@ @@ -1830,6 +2092,7 @@
struct platform_device *pdev = vc4_hdmi->pdev; struct platform_device *pdev = vc4_hdmi->pdev;
struct device *dev = &pdev->dev; struct device *dev = &pdev->dev;
struct resource *res; struct resource *res;
...@@ -78468,7 +78575,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78468,7 +78575,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi"); res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "hdmi");
if (!res) if (!res)
@@ -1926,6 +2193,38 @@ @@ -1926,9 +2189,64 @@
return PTR_ERR(vc4_hdmi->reset); return PTR_ERR(vc4_hdmi->reset);
} }
...@@ -78503,11 +78610,37 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78503,11 +78610,37 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
+ ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->rm_regset, VC5_RM); + ret = vc4_hdmi_build_regset(vc4_hdmi, &vc4_hdmi->rm_regset, VC5_RM);
+ if (ret) + if (ret)
+ return ret; + return ret;
+
+ return 0;
+}
+
+#ifdef CONFIG_PM
+static int vc4_hdmi_runtime_suspend(struct device *dev)
+{
+ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+
+ clk_disable_unprepare(vc4_hdmi->hsm_clock);
+ +
return 0; return 0;
} }
@@ -1943,6 +2242,7 @@ +static int vc4_hdmi_runtime_resume(struct device *dev)
+{
+ struct vc4_hdmi *vc4_hdmi = dev_get_drvdata(dev);
+ int ret;
+
+ ret = clk_prepare_enable(vc4_hdmi->hsm_clock);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+#endif
+
static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
{
const struct vc4_hdmi_variant *variant = of_device_get_match_data(dev);
@@ -1943,6 +2261,7 @@
vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL); vc4_hdmi = devm_kzalloc(dev, sizeof(*vc4_hdmi), GFP_KERNEL);
if (!vc4_hdmi) if (!vc4_hdmi)
return -ENOMEM; return -ENOMEM;
...@@ -78515,12 +78648,19 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78515,12 +78648,19 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
dev_set_drvdata(dev, vc4_hdmi); dev_set_drvdata(dev, vc4_hdmi);
encoder = &vc4_hdmi->encoder.base.base; encoder = &vc4_hdmi->encoder.base.base;
@@ -1992,11 +2292,55 @@ @@ -1983,7 +2302,7 @@
&hpd_gpio_flags);
if (vc4_hdmi->hpd_gpio < 0) {
ret = vc4_hdmi->hpd_gpio;
- goto err_unprepare_hsm;
+ goto err_put_ddc;
}
vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
@@ -1992,10 +2311,62 @@
vc4_hdmi->disable_wifi_frequencies = vc4_hdmi->disable_wifi_frequencies =
of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence"); of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
- if (vc4_hdmi->variant->reset)
- vc4_hdmi->variant->reset(vc4_hdmi);
+ if (variant->max_pixel_clock == 600000000) { + if (variant->max_pixel_clock == 600000000) {
+ struct vc4_dev *vc4 = to_vc4_dev(drm); + struct vc4_dev *vc4 = to_vc4_dev(drm);
+ long max_rate = clk_round_rate(vc4->hvs->core_clk, 550000000); + long max_rate = clk_round_rate(vc4->hvs->core_clk, 550000000);
...@@ -78562,18 +78702,26 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78562,18 +78702,26 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
+ ret = vc4_hdmi_runtime_resume(dev); + ret = vc4_hdmi_runtime_resume(dev);
+ if (ret) + if (ret)
+ goto err_put_ddc; + goto err_put_ddc;
+
+ pm_runtime_get_noresume(dev); + pm_runtime_get_noresume(dev);
+ pm_runtime_set_active(dev); + pm_runtime_set_active(dev);
pm_runtime_enable(dev); + pm_runtime_enable(dev);
+ if (vc4_hdmi->variant->reset)
+ vc4_hdmi->variant->reset(vc4_hdmi);
+ +
if (vc4_hdmi->variant->reset)
vc4_hdmi->variant->reset(vc4_hdmi);
- pm_runtime_enable(dev);
+ if ((of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi0") ||
+ of_device_is_compatible(dev->of_node, "brcm,bcm2711-hdmi1")) &&
+ HDMI_READ(HDMI_VID_CTL) & VC4_HD_VID_CTL_ENABLE) {
+ clk_prepare_enable(vc4_hdmi->pixel_clock);
+ clk_prepare_enable(vc4_hdmi->hsm_clock);
+ clk_prepare_enable(vc4_hdmi->pixel_bvb_clock);
+ }
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS); drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs); drm_encoder_helper_add(encoder, &vc4_hdmi_encoder_helper_funcs);
@@ -2004,10 +2375,14 @@
@@ -2004,10 +2348,14 @@
if (ret) if (ret)
goto err_destroy_encoder; goto err_destroy_encoder;
...@@ -78589,7 +78737,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78589,7 +78737,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
ret = vc4_hdmi_audio_init(vc4_hdmi); ret = vc4_hdmi_audio_init(vc4_hdmi);
if (ret) if (ret)
goto err_free_cec; goto err_free_cec;
@@ -2016,14 +2364,19 @@ @@ -2016,16 +2391,21 @@
vc4_hdmi_debugfs_regs, vc4_hdmi_debugfs_regs,
vc4_hdmi); vc4_hdmi);
...@@ -78605,11 +78753,14 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78605,11 +78753,14 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
vc4_hdmi_connector_destroy(&vc4_hdmi->connector); vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
err_destroy_encoder: err_destroy_encoder:
drm_encoder_cleanup(encoder); drm_encoder_cleanup(encoder);
-err_unprepare_hsm:
+ pm_runtime_put_sync(dev); + pm_runtime_put_sync(dev);
err_unprepare_hsm:
pm_runtime_disable(dev); pm_runtime_disable(dev);
+err_put_ddc:
put_device(&vc4_hdmi->ddc->dev); put_device(&vc4_hdmi->ddc->dev);
@@ -2061,6 +2414,7 @@
return ret;
@@ -2061,6 +2441,7 @@
kfree(vc4_hdmi->hd_regset.regs); kfree(vc4_hdmi->hd_regset.regs);
vc4_hdmi_cec_exit(vc4_hdmi); vc4_hdmi_cec_exit(vc4_hdmi);
...@@ -78617,7 +78768,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78617,7 +78768,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
vc4_hdmi_connector_destroy(&vc4_hdmi->connector); vc4_hdmi_connector_destroy(&vc4_hdmi->connector);
drm_encoder_cleanup(&vc4_hdmi->encoder.base.base); drm_encoder_cleanup(&vc4_hdmi->encoder.base.base);
@@ -2101,14 +2455,16 @@ @@ -2101,14 +2482,16 @@
.phy_disable = vc4_hdmi_phy_disable, .phy_disable = vc4_hdmi_phy_disable,
.phy_rng_enable = vc4_hdmi_phy_rng_enable, .phy_rng_enable = vc4_hdmi_phy_rng_enable,
.phy_rng_disable = vc4_hdmi_phy_rng_disable, .phy_rng_disable = vc4_hdmi_phy_rng_disable,
...@@ -78635,7 +78786,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78635,7 +78786,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
.registers = vc5_hdmi_hdmi0_fields, .registers = vc5_hdmi_hdmi0_fields,
.num_registers = ARRAY_SIZE(vc5_hdmi_hdmi0_fields), .num_registers = ARRAY_SIZE(vc5_hdmi_hdmi0_fields),
.phy_lane_mapping = { .phy_lane_mapping = {
@@ -2128,7 +2484,9 @@ @@ -2128,7 +2511,9 @@
.phy_disable = vc5_hdmi_phy_disable, .phy_disable = vc5_hdmi_phy_disable,
.phy_rng_enable = vc5_hdmi_phy_rng_enable, .phy_rng_enable = vc5_hdmi_phy_rng_enable,
.phy_rng_disable = vc5_hdmi_phy_rng_disable, .phy_rng_disable = vc5_hdmi_phy_rng_disable,
...@@ -78645,7 +78796,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78645,7 +78796,7 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
}; };
static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = { static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
@@ -2155,7 +2513,9 @@ @@ -2155,7 +2540,9 @@
.phy_disable = vc5_hdmi_phy_disable, .phy_disable = vc5_hdmi_phy_disable,
.phy_rng_enable = vc5_hdmi_phy_rng_enable, .phy_rng_enable = vc5_hdmi_phy_rng_enable,
.phy_rng_disable = vc5_hdmi_phy_rng_disable, .phy_rng_disable = vc5_hdmi_phy_rng_disable,
...@@ -78655,6 +78806,25 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers ...@@ -78655,6 +78806,25 @@ diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.c linux-5.12.10-rpi/drivers
}; };
static const struct of_device_id vc4_hdmi_dt_match[] = { static const struct of_device_id vc4_hdmi_dt_match[] = {
@@ -2165,11 +2552,18 @@
{}
};
+static const struct dev_pm_ops vc4_hdmi_pm_ops = {
+ SET_RUNTIME_PM_OPS(vc4_hdmi_runtime_suspend,
+ vc4_hdmi_runtime_resume,
+ NULL)
+};
+
struct platform_driver vc4_hdmi_driver = {
.probe = vc4_hdmi_dev_probe,
.remove = vc4_hdmi_dev_remove,
.driver = {
.name = "vc4_hdmi",
.of_match_table = vc4_hdmi_dt_match,
+ .pm = &vc4_hdmi_pm_ops,
},
};
diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.h linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_hdmi.h diff -uNr linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.h linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_hdmi.h
--- linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.h 2021-06-10 11:41:49.000000000 +0000 --- linux-5.12.10/drivers/gpu/drm/vc4/vc4_hdmi.h 2021-06-10 11:41:49.000000000 +0000
+++ linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_hdmi.h 2025-06-19 19:37:20.049894724 +0000 +++ linux-5.12.10-rpi/drivers/gpu/drm/vc4/vc4_hdmi.h 2025-06-19 19:37:20.049894724 +0000
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment