Skip to content

Commit 9fa1d7e

Browse files
committed
drm/vc4: hdmi: Disable Wifi Frequencies
There's cross-talk on the RPi4 between the 2.4GHz channels used by the WiFi chip and some resolutions, most notably 1440p at 60Hz. In such a case, we can either reject entirely the mode, or lower slightly the pixel frequency to remove the overlap. Let's go for the latter. Signed-off-by: Maxime Ripard <maxime@cerno.tech> Acked-by: Thomas Zimmermann <tzimmermann@suse.de> Link: https://patchwork.freedesktop.org/patch/msgid/20201029134018.1948636-2-maxime@cerno.tech
1 parent 8d15aa4 commit 9fa1d7e

2 files changed

Lines changed: 29 additions & 0 deletions

File tree

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,19 +760,37 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
760760
{
761761
}
762762

763+
#define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL
764+
#define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL
765+
763766
static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
764767
struct drm_crtc_state *crtc_state,
765768
struct drm_connector_state *conn_state)
766769
{
767770
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
768771
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
769772
unsigned long long pixel_rate = mode->clock * 1000;
773+
unsigned long long tmds_rate;
770774

771775
if (vc4_hdmi->variant->unsupported_odd_h_timings &&
772776
((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
773777
(mode->hsync_end % 2) || (mode->htotal % 2)))
774778
return -EINVAL;
775779

780+
/*
781+
* The 1440p@60 pixel rate is in the same range than the first
782+
* WiFi channel (between 2.4GHz and 2.422GHz with 22MHz
783+
* bandwidth). Slightly lower the frequency to bring it out of
784+
* the WiFi range.
785+
*/
786+
tmds_rate = pixel_rate * 10;
787+
if (vc4_hdmi->disable_wifi_frequencies &&
788+
(tmds_rate >= WIFI_2_4GHz_CH1_MIN_FREQ &&
789+
tmds_rate <= WIFI_2_4GHz_CH1_MAX_FREQ)) {
790+
mode->clock = 238560;
791+
pixel_rate = mode->clock * 1000;
792+
}
793+
776794
if (pixel_rate > vc4_hdmi->variant->max_pixel_clock)
777795
return -EINVAL;
778796

@@ -1719,6 +1737,9 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
17191737
vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
17201738
}
17211739

1740+
vc4_hdmi->disable_wifi_frequencies =
1741+
of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
1742+
17221743
pm_runtime_enable(dev);
17231744

17241745
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);

drivers/gpu/drm/vc4/vc4_hdmi.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,14 @@ struct vc4_hdmi {
142142
int hpd_gpio;
143143
bool hpd_active_low;
144144

145+
/*
146+
* On some systems (like the RPi4), some modes are in the same
147+
* frequency range than the WiFi channels (1440p@60Hz for
148+
* example). Should we take evasive actions because that system
149+
* has a wifi adapter?
150+
*/
151+
bool disable_wifi_frequencies;
152+
145153
struct cec_adapter *cec_adap;
146154
struct cec_msg cec_rx_msg;
147155
bool cec_tx_ok;

0 commit comments

Comments
 (0)