Skip to content

Commit 6ca12d0

Browse files
Xiangxu Yinriteshk-quic
authored andcommitted
FROMLIST: drm/msm/dp: Add support for lane mapping configuration
QCS615 platform requires non-default logical-to-physical lane mapping due to its unique hardware routing. Unlike the standard mapping sequence <0 1 2 3>, QCS615 uses <3 2 0 1>, which necessitates explicit configuration via the data-lanes property in the device tree. This ensures correct signal routing between the DP controller and PHY. For partial definitions, fill remaining lanes with unused physical lanes in ascending order. Reviewed-by: Dmitry Baryshkov <[email protected]> Signed-off-by: Xiangxu Yin <[email protected]> Link: https://lore.kernel.org/all/20250926-add-displayport-support-for-qcs615-platform-v7-14-dc5edaac6c2b@oss.qualcomm.com/
1 parent a69aa7a commit 6ca12d0

File tree

3 files changed

+67
-5
lines changed

3 files changed

+67
-5
lines changed

drivers/gpu/drm/msm/dp/dp_ctrl.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -423,13 +423,13 @@ static void msm_dp_ctrl_config_ctrl(struct msm_dp_ctrl_private *ctrl)
423423

424424
static void msm_dp_ctrl_lane_mapping(struct msm_dp_ctrl_private *ctrl)
425425
{
426-
u32 ln_0 = 0, ln_1 = 1, ln_2 = 2, ln_3 = 3; /* One-to-One mapping */
426+
u32 *lane_map = ctrl->link->lane_map;
427427
u32 ln_mapping;
428428

429-
ln_mapping = ln_0 << LANE0_MAPPING_SHIFT;
430-
ln_mapping |= ln_1 << LANE1_MAPPING_SHIFT;
431-
ln_mapping |= ln_2 << LANE2_MAPPING_SHIFT;
432-
ln_mapping |= ln_3 << LANE3_MAPPING_SHIFT;
429+
ln_mapping = lane_map[0] << LANE0_MAPPING_SHIFT;
430+
ln_mapping |= lane_map[1] << LANE1_MAPPING_SHIFT;
431+
ln_mapping |= lane_map[2] << LANE2_MAPPING_SHIFT;
432+
ln_mapping |= lane_map[3] << LANE3_MAPPING_SHIFT;
433433

434434
msm_dp_write_link(ctrl, REG_DP_LOGICAL2PHYSICAL_LANE_MAPPING,
435435
ln_mapping);

drivers/gpu/drm/msm/dp/dp_link.c

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1236,6 +1236,62 @@ static u32 msm_dp_link_link_frequencies(struct device_node *of_node)
12361236
return frequency;
12371237
}
12381238

1239+
/*
1240+
* Always populate msm_dp_link->lane_map with 4 lanes.
1241+
* - Use DTS "data-lanes" if present; otherwise fall back to default mapping.
1242+
* - For partial definitions, fill remaining entries with unused lanes in
1243+
* ascending order.
1244+
*/
1245+
static int msm_dp_link_lane_map(struct device *dev, struct msm_dp_link *msm_dp_link)
1246+
{
1247+
struct device_node *of_node = dev->of_node;
1248+
struct device_node *endpoint;
1249+
int cnt = msm_dp_link->max_dp_lanes;
1250+
u32 tmp[DP_MAX_NUM_DP_LANES];
1251+
u32 map[DP_MAX_NUM_DP_LANES] = {0, 1, 2, 3}; /* default 1:1 mapping */
1252+
bool used[DP_MAX_NUM_DP_LANES] = {false};
1253+
int i, ret = -EINVAL;
1254+
1255+
endpoint = of_graph_get_endpoint_by_regs(of_node, 1, -1);
1256+
if (endpoint) {
1257+
ret = of_property_read_u32_array(endpoint, "data-lanes", tmp, cnt);
1258+
if (ret)
1259+
dev_dbg(dev, "endpoint data-lanes read failed (ret=%d)\n", ret);
1260+
}
1261+
1262+
if (ret) {
1263+
ret = of_property_read_u32_array(of_node, "data-lanes", tmp, cnt);
1264+
if (ret) {
1265+
dev_info(dev, "data-lanes not defined, set to default\n");
1266+
goto out;
1267+
}
1268+
}
1269+
1270+
for (i = 0; i < cnt; i++) {
1271+
if (tmp[i] >= DP_MAX_NUM_DP_LANES) {
1272+
dev_err(dev, "data-lanes[%d]=%u out of range\n", i, tmp[i]);
1273+
return -EINVAL;
1274+
}
1275+
used[tmp[i]] = true;
1276+
map[i] = tmp[i];
1277+
}
1278+
1279+
/* Fill the remaining entries with unused physical lanes (ascending) */
1280+
i = cnt;
1281+
for (int j = 0; i < DP_MAX_NUM_DP_LANES && j < DP_MAX_NUM_DP_LANES; j++) {
1282+
if (!used[j])
1283+
map[i++] = j;
1284+
}
1285+
1286+
out:
1287+
if (endpoint)
1288+
of_node_put(endpoint);
1289+
1290+
dev_dbg(dev, "data-lanes count %d <%d %d %d %d>\n", cnt, map[0], map[1], map[2], map[3]);
1291+
memcpy(msm_dp_link->lane_map, map, sizeof(map));
1292+
return 0;
1293+
}
1294+
12391295
static int msm_dp_link_parse_dt(struct device *dev, struct msm_dp_link *msm_dp_link)
12401296
{
12411297
struct device_node *of_node = dev->of_node;
@@ -1255,6 +1311,11 @@ static int msm_dp_link_parse_dt(struct device *dev, struct msm_dp_link *msm_dp_l
12551311
else
12561312
msm_dp_link->max_dp_lanes = DP_MAX_NUM_DP_LANES; /* 4 lanes */
12571313

1314+
if (msm_dp_link_lane_map(dev, msm_dp_link)) {
1315+
dev_err(dev, "failed to parse data-lanes\n");
1316+
return -EINVAL;
1317+
}
1318+
12581319
msm_dp_link->max_dp_link_rate = msm_dp_link_link_frequencies(of_node);
12591320
if (!msm_dp_link->max_dp_link_rate)
12601321
msm_dp_link->max_dp_link_rate = DP_LINK_RATE_HBR2;

drivers/gpu/drm/msm/dp/dp_link.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ struct msm_dp_link {
7474
struct msm_dp_link_phy_params phy_params;
7575
struct msm_dp_link_info link_params;
7676

77+
u32 lane_map[DP_MAX_NUM_DP_LANES];
7778
u32 max_dp_lanes;
7879
u32 max_dp_link_rate;
7980
};

0 commit comments

Comments
 (0)