Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b7716735 authored by Dave Airlie's avatar Dave Airlie
Browse files

Merge tag 'drm-misc-fixes-2018-07-05' of git://anongit.freedesktop.org/drm/drm-misc into drm-fixes



Fixes for v4.18-rc4:
- A few small fixes for the sii8620 bridge.
- Allocate blob property memory using kvzalloc instead of kmalloc.

Signed-off-by: default avatarDave Airlie <airlied@redhat.com>

Link: https://patchwork.freedesktop.org/patch/msgid/4267636e-bb7c-8f69-eeff-12e045b3e7e1@linux.intel.com
parents 99ec9e77 44f9a4b0
Loading
Loading
Loading
Loading
+55 −31
Original line number Diff line number Diff line
@@ -14,6 +14,7 @@
#include <drm/bridge/mhl.h>
#include <drm/drm_crtc.h>
#include <drm/drm_edid.h>
#include <drm/drm_encoder.h>

#include <linux/clk.h>
#include <linux/delay.h>
@@ -72,9 +73,7 @@ struct sii8620 {
	struct regulator_bulk_data supplies[2];
	struct mutex lock; /* context lock, protects fields below */
	int error;
	int pixel_clock;
	unsigned int use_packed_pixel:1;
	int video_code;
	enum sii8620_mode mode;
	enum sii8620_sink_type sink_type;
	u8 cbus_status;
@@ -82,7 +81,6 @@ struct sii8620 {
	u8 xstat[MHL_XDS_SIZE];
	u8 devcap[MHL_DCAP_SIZE];
	u8 xdevcap[MHL_XDC_SIZE];
	u8 avif[HDMI_INFOFRAME_SIZE(AVI)];
	bool feature_complete;
	bool devcap_read;
	bool sink_detected;
@@ -1017,10 +1015,19 @@ static void sii8620_stop_video(struct sii8620 *ctx)

static void sii8620_set_format(struct sii8620 *ctx)
{
	u8 out_fmt;

	if (sii8620_is_mhl3(ctx)) {
		sii8620_setbits(ctx, REG_M3_P0CTRL,
				BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED,
				ctx->use_packed_pixel ? ~0 : 0);
	} else {
		if (ctx->use_packed_pixel) {
			sii8620_write_seq_static(ctx,
				REG_VID_MODE, BIT_VID_MODE_M1080P,
				REG_MHL_TOP_CTL, BIT_MHL_TOP_CTL_MHL_PP_SEL | 1,
				REG_MHLTX_CTL6, 0x60
			);
		} else {
			sii8620_write_seq_static(ctx,
				REG_VID_MODE, 0,
@@ -1028,10 +1035,16 @@ static void sii8620_set_format(struct sii8620 *ctx)
				REG_MHLTX_CTL6, 0xa0
			);
		}
	}

	if (ctx->use_packed_pixel)
		out_fmt = VAL_TPI_FORMAT(YCBCR422, FULL);
	else
		out_fmt = VAL_TPI_FORMAT(RGB, FULL);

	sii8620_write_seq(ctx,
		REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL),
		REG_TPI_OUTPUT, VAL_TPI_FORMAT(RGB, FULL),
		REG_TPI_OUTPUT, out_fmt,
	);
}

@@ -1082,18 +1095,28 @@ static ssize_t mhl3_infoframe_pack(struct mhl3_infoframe *frame,
	return frm_len;
}

static void sii8620_set_infoframes(struct sii8620 *ctx)
static void sii8620_set_infoframes(struct sii8620 *ctx,
				   struct drm_display_mode *mode)
{
	struct mhl3_infoframe mhl_frm;
	union hdmi_infoframe frm;
	u8 buf[31];
	int ret;

	ret = drm_hdmi_avi_infoframe_from_display_mode(&frm.avi,
						       mode,
						       true);
	if (ctx->use_packed_pixel)
		frm.avi.colorspace = HDMI_COLORSPACE_YUV422;

	if (!ret)
		ret = hdmi_avi_infoframe_pack(&frm.avi, buf, ARRAY_SIZE(buf));
	if (ret > 0)
		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, buf + 3, ret - 3);

	if (!sii8620_is_mhl3(ctx) || !ctx->use_packed_pixel) {
		sii8620_write(ctx, REG_TPI_SC,
			BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI);
		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, ctx->avif + 3,
			ARRAY_SIZE(ctx->avif) - 3);
		sii8620_write(ctx, REG_PKT_FILTER_0,
			BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
			BIT_PKT_FILTER_0_DROP_MPEG_PKT |
@@ -1102,16 +1125,6 @@ static void sii8620_set_infoframes(struct sii8620 *ctx)
		return;
	}

	ret = hdmi_avi_infoframe_init(&frm.avi);
	frm.avi.colorspace = HDMI_COLORSPACE_YUV422;
	frm.avi.active_aspect = HDMI_ACTIVE_ASPECT_PICTURE;
	frm.avi.picture_aspect = HDMI_PICTURE_ASPECT_16_9;
	frm.avi.colorimetry = HDMI_COLORIMETRY_ITU_709;
	frm.avi.video_code = ctx->video_code;
	if (!ret)
		ret = hdmi_avi_infoframe_pack(&frm.avi, buf, ARRAY_SIZE(buf));
	if (ret > 0)
		sii8620_write_buf(ctx, REG_TPI_AVI_CHSUM, buf + 3, ret - 3);
	sii8620_write(ctx, REG_PKT_FILTER_0,
		BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
		BIT_PKT_FILTER_0_DROP_MPEG_PKT |
@@ -1131,6 +1144,9 @@ static void sii8620_set_infoframes(struct sii8620 *ctx)

static void sii8620_start_video(struct sii8620 *ctx)
{
	struct drm_display_mode *mode =
		&ctx->bridge.encoder->crtc->state->adjusted_mode;

	if (!sii8620_is_mhl3(ctx))
		sii8620_stop_video(ctx);

@@ -1149,8 +1165,14 @@ static void sii8620_start_video(struct sii8620 *ctx)
	sii8620_set_format(ctx);

	if (!sii8620_is_mhl3(ctx)) {
		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
			MHL_DST_LM_CLK_MODE_NORMAL | MHL_DST_LM_PATH_ENABLED);
		u8 link_mode = MHL_DST_LM_PATH_ENABLED;

		if (ctx->use_packed_pixel)
			link_mode |= MHL_DST_LM_CLK_MODE_PACKED_PIXEL;
		else
			link_mode |= MHL_DST_LM_CLK_MODE_NORMAL;

		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), link_mode);
		sii8620_set_auto_zone(ctx);
	} else {
		static const struct {
@@ -1167,7 +1189,7 @@ static void sii8620_start_video(struct sii8620 *ctx)
			  MHL_XDS_LINK_RATE_6_0_GBPS, 0x40 },
		};
		u8 p0_ctrl = BIT_M3_P0CTRL_MHL3_P0_PORT_EN;
		int clk = ctx->pixel_clock * (ctx->use_packed_pixel ? 2 : 3);
		int clk = mode->clock * (ctx->use_packed_pixel ? 2 : 3);
		int i;

		for (i = 0; i < ARRAY_SIZE(clk_spec) - 1; ++i)
@@ -1196,7 +1218,7 @@ static void sii8620_start_video(struct sii8620 *ctx)
			clk_spec[i].link_rate);
	}

	sii8620_set_infoframes(ctx);
	sii8620_set_infoframes(ctx, mode);
}

static void sii8620_disable_hpd(struct sii8620 *ctx)
@@ -1661,14 +1683,18 @@ static void sii8620_status_dcap_ready(struct sii8620 *ctx)

static void sii8620_status_changed_path(struct sii8620 *ctx)
{
	if (ctx->stat[MHL_DST_LINK_MODE] & MHL_DST_LM_PATH_ENABLED) {
		sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
				      MHL_DST_LM_CLK_MODE_NORMAL
				      | MHL_DST_LM_PATH_ENABLED);
	} else {
	u8 link_mode;

	if (ctx->use_packed_pixel)
		link_mode = MHL_DST_LM_CLK_MODE_PACKED_PIXEL;
	else
		link_mode = MHL_DST_LM_CLK_MODE_NORMAL;

	if (ctx->stat[MHL_DST_LINK_MODE] & MHL_DST_LM_PATH_ENABLED)
		link_mode |= MHL_DST_LM_PATH_ENABLED;

	sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
				      MHL_DST_LM_CLK_MODE_NORMAL);
	}
			      link_mode);
}

static void sii8620_msc_mr_write_stat(struct sii8620 *ctx)
@@ -2242,8 +2268,6 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge,
	mutex_lock(&ctx->lock);

	ctx->use_packed_pixel = sii8620_is_packing_required(ctx, adjusted_mode);
	ctx->video_code = drm_match_cea_mode(adjusted_mode);
	ctx->pixel_clock = adjusted_mode->clock;

	mutex_unlock(&ctx->lock);

+3 −3
Original line number Diff line number Diff line
@@ -532,7 +532,7 @@ static void drm_property_free_blob(struct kref *kref)

	drm_mode_object_unregister(blob->dev, &blob->base);

	kfree(blob);
	kvfree(blob);
}

/**
@@ -559,7 +559,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
	if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
		return ERR_PTR(-EINVAL);

	blob = kzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
	blob = kvzalloc(sizeof(struct drm_property_blob)+length, GFP_KERNEL);
	if (!blob)
		return ERR_PTR(-ENOMEM);

@@ -576,7 +576,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length,
	ret = __drm_mode_object_add(dev, &blob->base, DRM_MODE_OBJECT_BLOB,
				    true, drm_property_free_blob);
	if (ret) {
		kfree(blob);
		kvfree(blob);
		return ERR_PTR(-EINVAL);
	}