Skip to content

Commit 9595930

Browse files
committed
Merge tag 'drm-misc-fixes-2020-11-26' of ssh://git.freedesktop.org/git/drm/drm-misc into drm-fixes
A bunch of fixes for vc4 fixing some coexistence issue between wifi and HDMI, unsupported modes, and vblank timeouts, a fix for ast to reload the gamma LUT after changing the plane format and a double-free fix for nouveau Signed-off-by: Dave Airlie <airlied@redhat.com> From: Maxime Ripard <maxime@cerno.tech> Link: https://patchwork.freedesktop.org/patch/msgid/20201126085450.r3i7wvj7pizsa4l6@gilmour
2 parents d45618c + 2be6564 commit 9595930

7 files changed

Lines changed: 271 additions & 67 deletions

File tree

Documentation/devicetree/bindings/display/brcm,bcm2711-hdmi.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ properties:
7676
resets:
7777
maxItems: 1
7878

79+
wifi-2.4ghz-coexistence:
80+
type: boolean
81+
description: >
82+
Should the pixel frequencies in the WiFi frequencies range be
83+
avoided?
84+
7985
required:
8086
- compatible
8187
- reg

drivers/gpu/drm/ast/ast_mode.c

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -742,7 +742,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
742742
case DRM_MODE_DPMS_SUSPEND:
743743
if (ast->tx_chip_type == AST_TX_DP501)
744744
ast_set_dp501_video_output(crtc->dev, 1);
745-
ast_crtc_load_lut(ast, crtc);
746745
break;
747746
case DRM_MODE_DPMS_OFF:
748747
if (ast->tx_chip_type == AST_TX_DP501)
@@ -777,6 +776,21 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
777776
return 0;
778777
}
779778

779+
static void
780+
ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state)
781+
{
782+
struct ast_private *ast = to_ast_private(crtc->dev);
783+
struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc->state);
784+
struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);
785+
786+
/*
787+
* The gamma LUT has to be reloaded after changing the primary
788+
* plane's color format.
789+
*/
790+
if (old_ast_crtc_state->format != ast_crtc_state->format)
791+
ast_crtc_load_lut(ast, crtc);
792+
}
793+
780794
static void
781795
ast_crtc_helper_atomic_enable(struct drm_crtc *crtc,
782796
struct drm_crtc_state *old_crtc_state)
@@ -830,6 +844,7 @@ ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,
830844

831845
static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
832846
.atomic_check = ast_crtc_helper_atomic_check,
847+
.atomic_flush = ast_crtc_helper_atomic_flush,
833848
.atomic_enable = ast_crtc_helper_atomic_enable,
834849
.atomic_disable = ast_crtc_helper_atomic_disable,
835850
};

drivers/gpu/drm/nouveau/nouveau_gem.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -558,8 +558,10 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
558558
NV_PRINTK(err, cli, "validating bo list\n");
559559
validate_fini(op, chan, NULL, NULL);
560560
return ret;
561+
} else if (ret > 0) {
562+
*apply_relocs = true;
561563
}
562-
*apply_relocs = ret;
564+
563565
return 0;
564566
}
565567

@@ -662,7 +664,6 @@ nouveau_gem_pushbuf_reloc_apply(struct nouveau_cli *cli,
662664
nouveau_bo_wr32(nvbo, r->reloc_bo_offset >> 2, data);
663665
}
664666

665-
u_free(reloc);
666667
return ret;
667668
}
668669

@@ -872,9 +873,10 @@ nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data,
872873
break;
873874
}
874875
}
875-
u_free(reloc);
876876
}
877877
out_prevalid:
878+
if (!IS_ERR(reloc))
879+
u_free(reloc);
878880
u_free(bo);
879881
u_free(push);
880882

drivers/gpu/drm/vc4/vc4_drv.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,7 @@ struct vc4_dev {
219219

220220
struct drm_modeset_lock ctm_state_lock;
221221
struct drm_private_obj ctm_manager;
222+
struct drm_private_obj hvs_channels;
222223
struct drm_private_obj load_tracker;
223224

224225
/* List of vc4_debugfs_info_entry for adding to debugfs once
@@ -531,6 +532,9 @@ struct vc4_crtc_state {
531532
unsigned int top;
532533
unsigned int bottom;
533534
} margins;
535+
536+
/* Transitional state below, only valid during atomic commits */
537+
bool update_muxing;
534538
};
535539

536540
#define VC4_HVS_CHANNEL_DISABLED ((unsigned int)-1)

drivers/gpu/drm/vc4/vc4_hdmi.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -760,19 +760,62 @@ 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+
766+
static int vc4_hdmi_encoder_atomic_check(struct drm_encoder *encoder,
767+
struct drm_crtc_state *crtc_state,
768+
struct drm_connector_state *conn_state)
769+
{
770+
struct drm_display_mode *mode = &crtc_state->adjusted_mode;
771+
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
772+
unsigned long long pixel_rate = mode->clock * 1000;
773+
unsigned long long tmds_rate;
774+
775+
if (vc4_hdmi->variant->unsupported_odd_h_timings &&
776+
((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
777+
(mode->hsync_end % 2) || (mode->htotal % 2)))
778+
return -EINVAL;
779+
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+
794+
if (pixel_rate > vc4_hdmi->variant->max_pixel_clock)
795+
return -EINVAL;
796+
797+
return 0;
798+
}
799+
763800
static enum drm_mode_status
764801
vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
765802
const struct drm_display_mode *mode)
766803
{
767804
struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);
768805

806+
if (vc4_hdmi->variant->unsupported_odd_h_timings &&
807+
((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
808+
(mode->hsync_end % 2) || (mode->htotal % 2)))
809+
return MODE_H_ILLEGAL;
810+
769811
if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock)
770812
return MODE_CLOCK_HIGH;
771813

772814
return MODE_OK;
773815
}
774816

775817
static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
818+
.atomic_check = vc4_hdmi_encoder_atomic_check,
776819
.mode_valid = vc4_hdmi_encoder_mode_valid,
777820
.disable = vc4_hdmi_encoder_disable,
778821
.enable = vc4_hdmi_encoder_enable,
@@ -1694,6 +1737,9 @@ static int vc4_hdmi_bind(struct device *dev, struct device *master, void *data)
16941737
vc4_hdmi->hpd_active_low = hpd_gpio_flags & OF_GPIO_ACTIVE_LOW;
16951738
}
16961739

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

16991745
drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_TMDS);
@@ -1817,6 +1863,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = {
18171863
PHY_LANE_2,
18181864
PHY_LANE_CK,
18191865
},
1866+
.unsupported_odd_h_timings = true,
18201867

18211868
.init_resources = vc5_hdmi_init_resources,
18221869
.csc_setup = vc5_hdmi_csc_setup,
@@ -1842,6 +1889,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
18421889
PHY_LANE_CK,
18431890
PHY_LANE_2,
18441891
},
1892+
.unsupported_odd_h_timings = true,
18451893

18461894
.init_resources = vc5_hdmi_init_resources,
18471895
.csc_setup = vc5_hdmi_csc_setup,

drivers/gpu/drm/vc4/vc4_hdmi.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,9 @@ struct vc4_hdmi_variant {
6262
*/
6363
enum vc4_hdmi_phy_channel phy_lane_mapping[4];
6464

65+
/* The BCM2711 cannot deal with odd horizontal pixel timings */
66+
bool unsupported_odd_h_timings;
67+
6568
/* Callback to get the resources (memory region, interrupts,
6669
* clocks, etc) for that variant.
6770
*/
@@ -139,6 +142,14 @@ struct vc4_hdmi {
139142
int hpd_gpio;
140143
bool hpd_active_low;
141144

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+
142153
struct cec_adapter *cec_adap;
143154
struct cec_msg cec_rx_msg;
144155
bool cec_tx_ok;

0 commit comments

Comments
 (0)