Commit b7716735 authored by Dave Airlie's avatar Dave Airlie

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
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
#include <drm/bridge/mhl.h> #include <drm/bridge/mhl.h>
#include <drm/drm_crtc.h> #include <drm/drm_crtc.h>
#include <drm/drm_edid.h> #include <drm/drm_edid.h>
#include <drm/drm_encoder.h>
#include <linux/clk.h> #include <linux/clk.h>
#include <linux/delay.h> #include <linux/delay.h>
...@@ -72,9 +73,7 @@ struct sii8620 { ...@@ -72,9 +73,7 @@ struct sii8620 {
struct regulator_bulk_data supplies[2]; struct regulator_bulk_data supplies[2];
struct mutex lock; /* context lock, protects fields below */ struct mutex lock; /* context lock, protects fields below */
int error; int error;
int pixel_clock;
unsigned int use_packed_pixel:1; unsigned int use_packed_pixel:1;
int video_code;
enum sii8620_mode mode; enum sii8620_mode mode;
enum sii8620_sink_type sink_type; enum sii8620_sink_type sink_type;
u8 cbus_status; u8 cbus_status;
...@@ -82,7 +81,6 @@ struct sii8620 { ...@@ -82,7 +81,6 @@ struct sii8620 {
u8 xstat[MHL_XDS_SIZE]; u8 xstat[MHL_XDS_SIZE];
u8 devcap[MHL_DCAP_SIZE]; u8 devcap[MHL_DCAP_SIZE];
u8 xdevcap[MHL_XDC_SIZE]; u8 xdevcap[MHL_XDC_SIZE];
u8 avif[HDMI_INFOFRAME_SIZE(AVI)];
bool feature_complete; bool feature_complete;
bool devcap_read; bool devcap_read;
bool sink_detected; bool sink_detected;
...@@ -1017,21 +1015,36 @@ static void sii8620_stop_video(struct sii8620 *ctx) ...@@ -1017,21 +1015,36 @@ static void sii8620_stop_video(struct sii8620 *ctx)
static void sii8620_set_format(struct sii8620 *ctx) static void sii8620_set_format(struct sii8620 *ctx)
{ {
u8 out_fmt;
if (sii8620_is_mhl3(ctx)) { if (sii8620_is_mhl3(ctx)) {
sii8620_setbits(ctx, REG_M3_P0CTRL, sii8620_setbits(ctx, REG_M3_P0CTRL,
BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED, BIT_M3_P0CTRL_MHL3_P0_PIXEL_MODE_PACKED,
ctx->use_packed_pixel ? ~0 : 0); ctx->use_packed_pixel ? ~0 : 0);
} else { } 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, sii8620_write_seq_static(ctx,
REG_VID_MODE, 0, REG_VID_MODE, 0,
REG_MHL_TOP_CTL, 1, REG_MHL_TOP_CTL, 1,
REG_MHLTX_CTL6, 0xa0 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, sii8620_write_seq(ctx,
REG_TPI_INPUT, VAL_TPI_FORMAT(RGB, FULL), 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, ...@@ -1082,18 +1095,28 @@ static ssize_t mhl3_infoframe_pack(struct mhl3_infoframe *frame,
return frm_len; 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; struct mhl3_infoframe mhl_frm;
union hdmi_infoframe frm; union hdmi_infoframe frm;
u8 buf[31]; u8 buf[31];
int ret; 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) { if (!sii8620_is_mhl3(ctx) || !ctx->use_packed_pixel) {
sii8620_write(ctx, REG_TPI_SC, sii8620_write(ctx, REG_TPI_SC,
BIT_TPI_SC_TPI_OUTPUT_MODE_0_HDMI); 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, sii8620_write(ctx, REG_PKT_FILTER_0,
BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT | BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
BIT_PKT_FILTER_0_DROP_MPEG_PKT | BIT_PKT_FILTER_0_DROP_MPEG_PKT |
...@@ -1102,16 +1125,6 @@ static void sii8620_set_infoframes(struct sii8620 *ctx) ...@@ -1102,16 +1125,6 @@ static void sii8620_set_infoframes(struct sii8620 *ctx)
return; 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, sii8620_write(ctx, REG_PKT_FILTER_0,
BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT | BIT_PKT_FILTER_0_DROP_CEA_GAMUT_PKT |
BIT_PKT_FILTER_0_DROP_MPEG_PKT | BIT_PKT_FILTER_0_DROP_MPEG_PKT |
...@@ -1131,6 +1144,9 @@ static void sii8620_set_infoframes(struct sii8620 *ctx) ...@@ -1131,6 +1144,9 @@ static void sii8620_set_infoframes(struct sii8620 *ctx)
static void sii8620_start_video(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)) if (!sii8620_is_mhl3(ctx))
sii8620_stop_video(ctx); sii8620_stop_video(ctx);
...@@ -1149,8 +1165,14 @@ static void sii8620_start_video(struct sii8620 *ctx) ...@@ -1149,8 +1165,14 @@ static void sii8620_start_video(struct sii8620 *ctx)
sii8620_set_format(ctx); sii8620_set_format(ctx);
if (!sii8620_is_mhl3(ctx)) { if (!sii8620_is_mhl3(ctx)) {
sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), u8 link_mode = MHL_DST_LM_PATH_ENABLED;
MHL_DST_LM_CLK_MODE_NORMAL | 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); sii8620_set_auto_zone(ctx);
} else { } else {
static const struct { static const struct {
...@@ -1167,7 +1189,7 @@ static void sii8620_start_video(struct sii8620 *ctx) ...@@ -1167,7 +1189,7 @@ static void sii8620_start_video(struct sii8620 *ctx)
MHL_XDS_LINK_RATE_6_0_GBPS, 0x40 }, MHL_XDS_LINK_RATE_6_0_GBPS, 0x40 },
}; };
u8 p0_ctrl = BIT_M3_P0CTRL_MHL3_P0_PORT_EN; 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; int i;
for (i = 0; i < ARRAY_SIZE(clk_spec) - 1; ++i) for (i = 0; i < ARRAY_SIZE(clk_spec) - 1; ++i)
...@@ -1196,7 +1218,7 @@ static void sii8620_start_video(struct sii8620 *ctx) ...@@ -1196,7 +1218,7 @@ static void sii8620_start_video(struct sii8620 *ctx)
clk_spec[i].link_rate); clk_spec[i].link_rate);
} }
sii8620_set_infoframes(ctx); sii8620_set_infoframes(ctx, mode);
} }
static void sii8620_disable_hpd(struct sii8620 *ctx) static void sii8620_disable_hpd(struct sii8620 *ctx)
...@@ -1661,14 +1683,18 @@ static void sii8620_status_dcap_ready(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) static void sii8620_status_changed_path(struct sii8620 *ctx)
{ {
if (ctx->stat[MHL_DST_LINK_MODE] & MHL_DST_LM_PATH_ENABLED) { u8 link_mode;
sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE),
MHL_DST_LM_CLK_MODE_NORMAL if (ctx->use_packed_pixel)
| MHL_DST_LM_PATH_ENABLED); link_mode = MHL_DST_LM_CLK_MODE_PACKED_PIXEL;
} else { else
sii8620_mt_write_stat(ctx, MHL_DST_REG(LINK_MODE), link_mode = MHL_DST_LM_CLK_MODE_NORMAL;
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),
link_mode);
} }
static void sii8620_msc_mr_write_stat(struct sii8620 *ctx) static void sii8620_msc_mr_write_stat(struct sii8620 *ctx)
...@@ -2242,8 +2268,6 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge, ...@@ -2242,8 +2268,6 @@ static bool sii8620_mode_fixup(struct drm_bridge *bridge,
mutex_lock(&ctx->lock); mutex_lock(&ctx->lock);
ctx->use_packed_pixel = sii8620_is_packing_required(ctx, adjusted_mode); 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); mutex_unlock(&ctx->lock);
......
...@@ -532,7 +532,7 @@ static void drm_property_free_blob(struct kref *kref) ...@@ -532,7 +532,7 @@ static void drm_property_free_blob(struct kref *kref)
drm_mode_object_unregister(blob->dev, &blob->base); 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, ...@@ -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)) if (!length || length > ULONG_MAX - sizeof(struct drm_property_blob))
return ERR_PTR(-EINVAL); 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) if (!blob)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
...@@ -576,7 +576,7 @@ drm_property_create_blob(struct drm_device *dev, size_t length, ...@@ -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, ret = __drm_mode_object_add(dev, &blob->base, DRM_MODE_OBJECT_BLOB,
true, drm_property_free_blob); true, drm_property_free_blob);
if (ret) { if (ret) {
kfree(blob); kvfree(blob);
return ERR_PTR(-EINVAL); return ERR_PTR(-EINVAL);
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment