diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c index fae4f9ec05a1..e1e3e90aa723 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c @@ -1698,6 +1698,8 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp) { struct device_node *dp_node = dp->dev->of_node; struct video_info *video_info = &dp->video_info; + struct property *prop; + int ret, len, num_lanes; switch (dp->plat_data->dev_type) { case RK3288_DP: @@ -1729,6 +1731,32 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp) video_info->video_bist_enable = of_property_read_bool(dp_node, "analogix,video-bist-enable"); + prop = of_find_property(dp_node, "data-lanes", &len); + if (!prop) { + video_info->lane_map[0] = 0; + video_info->lane_map[1] = 1; + video_info->lane_map[2] = 2; + video_info->lane_map[3] = 3; + DRM_DEV_DEBUG(dp->dev, "failed to find data lane mapping, using default\n"); + return 0; + } + + num_lanes = len / sizeof(u32); + + if (num_lanes < 1 || num_lanes > 4 || num_lanes == 3) { + DRM_DEV_ERROR(dp->dev, "bad number of data lanes\n"); + return -EINVAL; + } + + video_info->max_lane_count = num_lanes; + + ret = of_property_read_u32_array(dp_node, "data-lanes", + video_info->lane_map, num_lanes); + if (ret) { + DRM_DEV_ERROR(dp->dev, "failed to read lane data\n"); + return ret; + } + return 0; } diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h index 059b1a229ad3..9ef5b6b3bfb2 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h @@ -137,6 +137,7 @@ struct video_info { int max_link_rate; enum link_lane_count_type max_lane_count; + u32 lane_map[4]; bool video_bist_enable; }; @@ -186,7 +187,6 @@ struct analogix_dp_device { /* analogix_dp_reg.c */ void analogix_dp_enable_video_mute(struct analogix_dp_device *dp, bool enable); void analogix_dp_stop_video(struct analogix_dp_device *dp); -void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable); void analogix_dp_init_analog_param(struct analogix_dp_device *dp); void analogix_dp_init_interrupt(struct analogix_dp_device *dp); void analogix_dp_reset(struct analogix_dp_device *dp); diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c index e2ac2d720b36..aa2ba8d08d91 100644 --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c @@ -61,16 +61,13 @@ void analogix_dp_stop_video(struct analogix_dp_device *dp) analogix_dp_write(dp, ANALOGIX_DP_VIDEO_CTL_1, reg); } -void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable) +static void analogix_dp_set_lane_map(struct analogix_dp_device *dp) { - u32 reg; + struct video_info *video_info = &dp->video_info; + u32 i, reg = 0; - if (enable) - reg = LANE3_MAP_LOGIC_LANE_0 | LANE2_MAP_LOGIC_LANE_1 | - LANE1_MAP_LOGIC_LANE_2 | LANE0_MAP_LOGIC_LANE_3; - else - reg = LANE3_MAP_LOGIC_LANE_3 | LANE2_MAP_LOGIC_LANE_2 | - LANE1_MAP_LOGIC_LANE_1 | LANE0_MAP_LOGIC_LANE_0; + for (i = 0; i < video_info->max_lane_count; i++) + reg |= video_info->lane_map[i] << (2 * i); analogix_dp_write(dp, ANALOGIX_DP_LANE_MAP, reg); } @@ -154,7 +151,7 @@ void analogix_dp_reset(struct analogix_dp_device *dp) usleep_range(20, 30); - analogix_dp_lane_swap(dp, 0); + analogix_dp_set_lane_map(dp); analogix_dp_write(dp, ANALOGIX_DP_SYS_CTL_1, 0x0); analogix_dp_write(dp, ANALOGIX_DP_SYS_CTL_2, 0x40);