mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 02:24:24 +02:00
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
This commit is contained in:
parent
8d15aa4ed0
commit
9fa1d7e60a
|
|
@ -760,6 +760,9 @@ static void vc4_hdmi_encoder_enable(struct drm_encoder *encoder)
|
|||
{
|
||||
}
|
||||
|
||||
#define WIFI_2_4GHz_CH1_MIN_FREQ 2400000000ULL
|
||||
#define WIFI_2_4GHz_CH1_MAX_FREQ 2422000000ULL
|
||||
|
||||
static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_connector_state *conn_state)
|
||||
|
|
@ -767,12 +770,27 @@ static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
|
|||
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
|
||||
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
|
||||
unsigned long long pixel_rate = mode->clock * 1000;
|
||||
unsigned long long tmds_rate;
|
||||
|
||||
if (vc4_hdmi->variant->unsupported_odd_h_timings &&
|
||||
((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
|
||||
(mode->hsync_end % 2) || (mode->htotal % 2)))
|
||||
return -EINVAL;
|
||||
|
||||
/*
|
||||
* The 1440p@60 pixel rate is in the same range than the first
|
||||
* WiFi channel (between 2.4GHz and 2.422GHz with 22MHz
|
||||
* bandwidth). Slightly lower the frequency to bring it out of
|
||||
* the WiFi range.
|
||||
*/
|
||||
tmds_rate = pixel_rate * 10;
|
||||
if (vc4_hdmi->disable_wifi_frequencies &&
|
||||
(tmds_rate >= WIFI_2_4GHz_CH1_MIN_FREQ &&
|
||||
tmds_rate <= WIFI_2_4GHz_CH1_MAX_FREQ)) {
|
||||
mode->clock = 238560;
|
||||
pixel_rate = mode->clock * 1000;
|
||||
}
|
||||
|
||||
if (pixel_rate > vc4_hdmi->variant->max_pixel_clock)
|
||||
return -EINVAL;
|
||||
|
||||
|
|
@ -1719,6 +1737,9 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
|
|||
vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
|
||||
}
|
||||
|
||||
vc4_hdmi->disable_wifi_frequencies =
|
||||
of_property_read_bool(dev->of_node, "wifi-2.4ghz-coexistence");
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
|
||||
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
|
||||
|
|
|
|||
|
|
@ -142,6 +142,14 @@ struct vc4_hdmi {
|
|||
int hpd_gpio;
|
||||
bool hpd_active_low;
|
||||
|
||||
/*
|
||||
* On some systems (like the RPi4), some modes are in the same
|
||||
* frequency range than the WiFi channels (1440p@60Hz for
|
||||
* example). Should we take evasive actions because that system
|
||||
* has a wifi adapter?
|
||||
*/
|
||||
bool disable_wifi_frequencies;
|
||||
|
||||
struct cec_adapter *cec_adap;
|
||||
struct cec_msg cec_rx_msg;
|
||||
bool cec_tx_ok;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user