mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
Merge commit 'fc87ca81ee14b8313e90c0264b9703cb680d685a'
* commit 'fc87ca81ee14b8313e90c0264b9703cb680d685a': drm/rockchip: dw-dp: use low link rate for low pixel clock timing phy: rockchip: csi2-dphy: fixes dphy open/close stuck issue for rk3576 media: i2c: rk628: fix mutex_lock when get_fmt if nosignal Change-Id: I3e3577f04e1411de5c57f1353bc4eef502b92034
This commit is contained in:
@@ -313,6 +313,7 @@ struct drm_dp_link_train {
|
||||
struct dw_dp_link {
|
||||
u8 dpcd[DP_RECEIVER_CAP_SIZE];
|
||||
unsigned char revision;
|
||||
unsigned int max_rate;
|
||||
unsigned int rate;
|
||||
unsigned int lanes;
|
||||
struct drm_dp_link_caps caps;
|
||||
@@ -1573,6 +1574,7 @@ static void dw_dp_link_reset(struct dw_dp_link *link)
|
||||
|
||||
link->rate = 0;
|
||||
link->lanes = 0;
|
||||
link->max_rate = 0;
|
||||
}
|
||||
|
||||
static int dw_dp_link_power_up(struct dw_dp *dp)
|
||||
@@ -1668,10 +1670,11 @@ static int dw_dp_link_probe(struct dw_dp *dp)
|
||||
!!(dpcd & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED);
|
||||
|
||||
link->revision = link->dpcd[DP_DPCD_REV];
|
||||
link->rate = min_t(u32, min(dp->max_link_rate, dp->phy->attrs.max_link_rate * 100),
|
||||
drm_dp_max_link_rate(link->dpcd));
|
||||
link->max_rate = min_t(u32, min(dp->max_link_rate, dp->phy->attrs.max_link_rate * 100),
|
||||
drm_dp_max_link_rate(link->dpcd));
|
||||
link->lanes = min_t(u8, phy_get_bus_width(dp->phy),
|
||||
drm_dp_max_lane_count(link->dpcd));
|
||||
drm_dp_max_lane_count(link->dpcd));
|
||||
link->rate = link->max_rate;
|
||||
|
||||
link->caps.enhanced_framing = drm_dp_enhanced_frame_cap(link->dpcd);
|
||||
link->caps.tps3_supported = drm_dp_tps3_supported(link->dpcd);
|
||||
@@ -3135,7 +3138,7 @@ dw_dp_bridge_mode_valid(struct drm_bridge *bridge,
|
||||
drm_mode_is_420_only(info, &m))
|
||||
return MODE_NO_420;
|
||||
|
||||
if (!dw_dp_bandwidth_ok(dp, &m, min_bpp, link->lanes, link->rate))
|
||||
if (!dw_dp_bandwidth_ok(dp, &m, min_bpp, link->lanes, link->max_rate))
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
return MODE_OK;
|
||||
@@ -3171,17 +3174,21 @@ static void _dw_dp_loader_protect(struct dw_dp *dp, bool on)
|
||||
switch (FIELD_GET(PHY_RATE, value)) {
|
||||
case 3:
|
||||
link->rate = 810000;
|
||||
link->max_rate = 810000;
|
||||
break;
|
||||
case 2:
|
||||
link->rate = 540000;
|
||||
link->max_rate = 540000;
|
||||
break;
|
||||
case 1:
|
||||
link->rate = 270000;
|
||||
link->max_rate = 270000;
|
||||
break;
|
||||
case 0:
|
||||
fallthrough;
|
||||
default:
|
||||
link->rate = 162000;
|
||||
link->max_rate = 162000;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -3418,7 +3425,7 @@ dw_dp_mst_connector_mode_valid(struct drm_connector *connector, struct drm_displ
|
||||
if (drm_connector_is_unregistered(connector))
|
||||
return MODE_ERROR;
|
||||
|
||||
if (!dw_dp_bandwidth_ok(dp, mode, min_bpp, dp->link.lanes, dp->link.rate))
|
||||
if (!dw_dp_bandwidth_ok(dp, mode, min_bpp, dp->link.lanes, dp->link.max_rate))
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
if (drm_dp_calc_pbn_mode(mode->clock, min_bpp, false) > port->full_pbn)
|
||||
@@ -3561,6 +3568,32 @@ static void dw_dp_enable_vop_gate(struct dw_dp *dp, struct drm_crtc *crtc,
|
||||
rockchip_drm_crtc_output_pre_disable(crtc, output_if);
|
||||
}
|
||||
|
||||
/*
|
||||
* When DPTX controller config 2 pixe mode and work in sst mode,
|
||||
* and a low pixel clock image transmit in high link rate(HBR3),
|
||||
* some monitor may display flicker. To avoid this issue appear, use
|
||||
* lower link rate(HBR2) when transmit a low pixel clock image.
|
||||
*/
|
||||
static void dw_dp_limit_max_link_rate(struct dw_dp *dp)
|
||||
{
|
||||
struct dw_dp_link *link = &dp->link;
|
||||
struct dw_dp_video *video = &dp->video;
|
||||
|
||||
link->rate = link->max_rate;
|
||||
|
||||
if (dp->is_mst)
|
||||
return;
|
||||
|
||||
if (dp->pixel_mode != DPTX_MP_DUAL_PIXEL)
|
||||
return;
|
||||
|
||||
if (video->mode.clock > 50000)
|
||||
return;
|
||||
|
||||
if (link->max_rate > 540000)
|
||||
link->rate = 540000;
|
||||
}
|
||||
|
||||
static void dw_dp_mst_encoder_atomic_enable(struct drm_encoder *encoder,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
@@ -3597,6 +3630,8 @@ static void dw_dp_mst_encoder_atomic_enable(struct drm_encoder *encoder,
|
||||
mst_enc->mst_conn = mst_conn;
|
||||
|
||||
if (first_mst_stream) {
|
||||
dw_dp_limit_max_link_rate(dp);
|
||||
|
||||
ret = phy_power_on(dp->phy);
|
||||
if (ret)
|
||||
dev_err(dp->dev, "phy power on failed: %d\n", ret);
|
||||
@@ -4155,6 +4190,8 @@ static int dw_dp_link_enable(struct dw_dp *dp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
dw_dp_limit_max_link_rate(dp);
|
||||
|
||||
ret = phy_power_on(dp->phy);
|
||||
if (ret)
|
||||
return ret;
|
||||
@@ -4412,7 +4449,7 @@ static u32 *dw_dp_bridge_atomic_get_output_bus_fmts(struct drm_bridge *bridge,
|
||||
fmt->color_format != DRM_COLOR_FORMAT_YCBCR420)
|
||||
continue;
|
||||
|
||||
if (!dw_dp_bandwidth_ok(dp, &mode, fmt->bpp, link->lanes, link->rate))
|
||||
if (!dw_dp_bandwidth_ok(dp, &mode, fmt->bpp, link->lanes, link->max_rate))
|
||||
continue;
|
||||
|
||||
if (dp_state->bpc != 0) {
|
||||
|
||||
@@ -1729,10 +1729,9 @@ static int rk628_hdmirx_general_isr(struct v4l2_subdev *sd, u32 status, bool *ha
|
||||
__func__, hact, vact);
|
||||
|
||||
rk628_csi_enable_interrupts(sd, false);
|
||||
if (csi->rk628->version < RK628F_VERSION) {
|
||||
if (csi->rk628->version < RK628F_VERSION)
|
||||
enable_stream(sd, false);
|
||||
csi->nosignal = true;
|
||||
}
|
||||
csi->nosignal = true;
|
||||
v4l2_event_queue(sd->devnode, &evt_signal_lost);
|
||||
schedule_delayed_work(&csi->delayed_work_res_change, msecs_to_jiffies(100));
|
||||
|
||||
@@ -2066,15 +2065,15 @@ static int rk628_csi_get_fmt(struct v4l2_subdev *sd,
|
||||
{
|
||||
struct rk628_csi *csi = to_csi(sd);
|
||||
|
||||
/* The application don't wants this to be blocked, so use mutex_trylock() */
|
||||
if (!mutex_trylock(&csi->confctl_mutex)) {
|
||||
if (!tx_5v_power_present(sd) || csi->nosignal) {
|
||||
v4l2_info(sd, "%s hdmirx no signal\n", __func__);
|
||||
format->format.code = csi->mbus_fmt_code;
|
||||
format->format.width = RK628_DEFAULT_WIDTH;
|
||||
format->format.height = RK628_DEFAULT_HEIGHT;
|
||||
format->format.field = V4L2_FIELD_NONE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
mutex_lock(&csi->confctl_mutex);
|
||||
format->format.code = csi->mbus_fmt_code;
|
||||
format->format.width = ALIGN_DOWN(csi->timings.bt.width, 8);
|
||||
format->format.height = csi->timings.bt.height;
|
||||
@@ -2943,6 +2942,7 @@ static irqreturn_t plugin_detect_irq(int irq, void *dev_id)
|
||||
rk628_csi_enable_csi_interrupts(sd, false);
|
||||
rk628_csi_disable_stream(sd);
|
||||
}
|
||||
csi->nosignal = true;
|
||||
/* control hpd after 50ms */
|
||||
schedule_delayed_work(&csi->delayed_work_enable_hotplug, HZ / 20);
|
||||
v4l2_event_queue(sd->devnode, &evt_signal_lost);
|
||||
|
||||
@@ -294,6 +294,7 @@ static int rockchip_csi2_dphy_attach_hw(struct csi2_dphy *dphy, int csi_idx, int
|
||||
else
|
||||
dphy->phy_index = 5;
|
||||
}
|
||||
dphy_hw->dphy_dev[dphy_hw->dphy_dev_num] = dphy;
|
||||
dphy_hw->dphy_dev_num++;
|
||||
dphy->dphy_hw = dphy_hw;
|
||||
dphy->phy_hw[index] = (void *)dphy_hw;
|
||||
|
||||
Reference in New Issue
Block a user