Commit 9595930d authored by Dave Airlie's avatar Dave Airlie
Browse files

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: default avatarDave Airlie <airlied@redhat.com>

From: Maxime Ripard <maxime@cerno.tech>
Link: https://patchwork.freedesktop.org/patch/msgid/20201126085450.r3i7wvj7pizsa4l6@gilmour
parents d45618c2 2be65641
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -76,6 +76,12 @@ properties:
  resets:
    maxItems: 1

  wifi-2.4ghz-coexistence:
    type: boolean
    description: >
      Should the pixel frequencies in the WiFi frequencies range be
      avoided?

required:
  - compatible
  - reg
+16 −1
Original line number Diff line number Diff line
@@ -742,7 +742,6 @@ static void ast_crtc_dpms(struct drm_crtc *crtc, int mode)
	case DRM_MODE_DPMS_SUSPEND:
		if (ast->tx_chip_type == AST_TX_DP501)
			ast_set_dp501_video_output(crtc->dev, 1);
		ast_crtc_load_lut(ast, crtc);
		break;
	case DRM_MODE_DPMS_OFF:
		if (ast->tx_chip_type == AST_TX_DP501)
@@ -777,6 +776,21 @@ static int ast_crtc_helper_atomic_check(struct drm_crtc *crtc,
	return 0;
}

static void
ast_crtc_helper_atomic_flush(struct drm_crtc *crtc, struct drm_crtc_state *old_crtc_state)
{
	struct ast_private *ast = to_ast_private(crtc->dev);
	struct ast_crtc_state *ast_crtc_state = to_ast_crtc_state(crtc->state);
	struct ast_crtc_state *old_ast_crtc_state = to_ast_crtc_state(old_crtc_state);

	/*
	 * The gamma LUT has to be reloaded after changing the primary
	 * plane's color format.
	 */
	if (old_ast_crtc_state->format != ast_crtc_state->format)
		ast_crtc_load_lut(ast, crtc);
}

static void
ast_crtc_helper_atomic_enable(struct drm_crtc *crtc,
			      struct drm_crtc_state *old_crtc_state)
@@ -830,6 +844,7 @@ ast_crtc_helper_atomic_disable(struct drm_crtc *crtc,

static const struct drm_crtc_helper_funcs ast_crtc_helper_funcs = {
	.atomic_check = ast_crtc_helper_atomic_check,
	.atomic_flush = ast_crtc_helper_atomic_flush,
	.atomic_enable = ast_crtc_helper_atomic_enable,
	.atomic_disable = ast_crtc_helper_atomic_disable,
};
+5 −3
Original line number Diff line number Diff line
@@ -558,8 +558,10 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan,
			NV_PRINTK(err, cli, "validating bo list\n");
		validate_fini(op, chan, NULL, NULL);
		return ret;
	} else if (ret > 0) {
		*apply_relocs = true;
	}
	*apply_relocs = ret;

	return 0;
}

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

	u_free(reloc);
	return ret;
}

@@ -872,9 +873,10 @@ out:
				break;
			}
		}
		u_free(reloc);
	}
out_prevalid:
	if (!IS_ERR(reloc))
		u_free(reloc);
	u_free(bo);
	u_free(push);

+4 −0
Original line number Diff line number Diff line
@@ -219,6 +219,7 @@ struct vc4_dev {

	struct drm_modeset_lock ctm_state_lock;
	struct drm_private_obj ctm_manager;
	struct drm_private_obj hvs_channels;
	struct drm_private_obj load_tracker;

	/* List of vc4_debugfs_info_entry for adding to debugfs once
@@ -531,6 +532,9 @@ struct vc4_crtc_state {
		unsigned int top;
		unsigned int bottom;
	} margins;

	/* Transitional state below, only valid during atomic commits */
	bool update_muxing;
};

#define VC4_HVS_CHANNEL_DISABLED ((unsigned int)-1)
+48 −0
Original line number Diff line number Diff line
@@ -760,12 +760,54 @@ 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)
{
	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;

	return 0;
}

static enum drm_mode_status
vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
			    const struct drm_display_mode *mode)
{
	struct vc4_hdmi *vc4_hdmi = encoder_to_vc4_hdmi(encoder);

	if (vc4_hdmi->variant->unsupported_odd_h_timings &&
	    ((mode->hdisplay % 2) || (mode->hsync_start % 2) ||
	     (mode->hsync_end % 2) || (mode->htotal % 2)))
		return MODE_H_ILLEGAL;

	if ((mode->clock * 1000) > vc4_hdmi->variant->max_pixel_clock)
		return MODE_CLOCK_HIGH;

@@ -773,6 +815,7 @@ vc4_hdmi_encoder_mode_valid(struct drm_encoder *encoder,
}

static const struct drm_encoder_helper_funcs vc4_hdmi_encoder_helper_funcs = {
	.atomic_check = vc4_hdmi_encoder_atomic_check,
	.mode_valid = vc4_hdmi_encoder_mode_valid,
	.disable = vc4_hdmi_encoder_disable,
	.enable = vc4_hdmi_encoder_enable,
@@ -1694,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);
@@ -1817,6 +1863,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi0_variant = {
		PHY_LANE_2,
		PHY_LANE_CK,
	},
	.unsupported_odd_h_timings	= true,

	.init_resources		= vc5_hdmi_init_resources,
	.csc_setup		= vc5_hdmi_csc_setup,
@@ -1842,6 +1889,7 @@ static const struct vc4_hdmi_variant bcm2711_hdmi1_variant = {
		PHY_LANE_CK,
		PHY_LANE_2,
	},
	.unsupported_odd_h_timings	= true,

	.init_resources		= vc5_hdmi_init_resources,
	.csc_setup		= vc5_hdmi_csc_setup,
Loading