From: Sebastian Reichel <sebastian.reichel@collabora.com>
To: Damon Ding <damon.ding@rock-chips.com>
Cc: hjc@rock-chips.com, heiko@sntech.de, andy.yan@rock-chips.com,
maarten.lankhorst@linux.intel.com, mripard@kernel.org,
tzimmermann@suse.de, airlied@gmail.com, simona@ffwll.ch,
robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
andrzej.hajda@intel.com, neil.armstrong@linaro.org,
rfoss@kernel.org, Laurent.pinchart@ideasonboard.com,
jonas@kwiboo.se, jernej.skrabec@gmail.com,
nicolas.frattaroli@collabora.com,
cristian.ciocaltea@collabora.com,
dmitry.baryshkov@oss.qualcomm.com, luca.ceresoli@bootlin.com,
dianders@chromium.org, m.szyprowski@samsung.com,
dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org,
linux-arm-kernel@lists.infradead.org,
linux-rockchip@lists.infradead.org, linux-kernel@vger.kernel.org
Subject: Re: [PATCH v4 3/3] drm/bridge: analogix_dp: Add support for optional data-lanes mapping
Date: Mon, 1 Jun 2026 13:59:29 +0200 [thread overview]
Message-ID: <ah1zPfYFYYLNzbqV@venus> (raw)
In-Reply-To: <20260529040530.741336-4-damon.ding@rock-chips.com>
[-- Attachment #1: Type: text/plain, Size: 6783 bytes --]
Hi,
On Fri, May 29, 2026 at 12:05:30PM +0800, Damon Ding wrote:
> Parse the optional 'data-lanes' device tree property to support
> custom physical lane mapping configuration.
>
> If no valid configuration is found, fall back to the default
> lane map (0, 1, 2, 3) automatically and keep the driver running.
>
> Lane mapping is mainly used for below scenarios:
> 1. Correct PCB lane swap and differential line routing crossover
> without hardware changes;
> 2. Adapt mismatched lane pin definitions between SoC and eDP panel;
> 3. Support multiple panel hardware variants on the same board
> by configuring data-lanes in device tree only.
>
> Signed-off-by: Damon Ding <damon.ding@rock-chips.com>
>
> ---
Reviewed-by: Sebastian Reichel <sebastian.reichel@collabora.com>
Greetings,
-- Sebastian
>
> Changes in v2:
> - Add lane mapping application scenarios in commit message.
> ---
> .../drm/bridge/analogix/analogix_dp_core.c | 56 +++++++++++++++++++
> .../drm/bridge/analogix/analogix_dp_core.h | 4 +-
> .../gpu/drm/bridge/analogix/analogix_dp_reg.c | 15 +++--
> .../gpu/drm/bridge/analogix/analogix_dp_reg.h | 4 ++
> 4 files changed, 70 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> index 699a7f380c56..b2e729850391 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.c
> @@ -1234,6 +1234,59 @@ static const struct drm_bridge_funcs analogix_dp_bridge_funcs = {
> .detect = analogix_dp_bridge_detect,
> };
>
> +static int analogix_dp_dt_parse_lanes_map(struct analogix_dp_device *dp)
> +{
> + struct video_info *video_info = &dp->video_info;
> + struct device_node *endpoint;
> + u32 tmp[LANE_COUNT4];
> + u32 map[LANE_COUNT4] = {0, 1, 2, 3};
> + bool used[LANE_COUNT4] = {false};
> + int num_lanes;
> + int ret, i;
> +
> + memcpy(video_info->lane_map, map, sizeof(map));
> +
> + num_lanes = drm_of_get_data_lanes_count_ep(dp->dev->of_node, 1, 0, 1,
> + video_info->max_lane_count);
> + if (num_lanes < 0)
> + return -EINVAL;
> +
> + endpoint = of_graph_get_endpoint_by_regs(dp->dev->of_node, 1, -1);
> + if (!endpoint)
> + return -EINVAL;
> +
> + ret = of_property_read_u32_array(endpoint, "data-lanes", tmp, num_lanes);
> + of_node_put(endpoint);
> + if (ret)
> + return -EINVAL;
> +
> + for (i = 0; i < num_lanes; i++) {
> + if (tmp[i] >= LANE_COUNT4) {
> + dev_dbg(dp->dev, "data-lanes[%d] = %u is out of range\n", i, tmp[i]);
> + return -EINVAL;
> + }
> +
> + if (used[tmp[i]]) {
> + dev_dbg(dp->dev, "data-lanes[%d] = %u is duplicate\n", i, tmp[i]);
> + return -EINVAL;
> + }
> +
> + used[tmp[i]] = true;
> + map[i] = tmp[i];
> + }
> +
> + for (i = 0; i < LANE_COUNT4 && num_lanes < LANE_COUNT4; i++) {
> + if (!used[i])
> + map[num_lanes++] = i;
> + }
> +
> + dev_dbg(dp->dev, "Using parsed lane map: <%u %u %u %u>\n", map[0], map[1], map[2], map[3]);
> +
> + memcpy(video_info->lane_map, map, sizeof(map));
> +
> + return 0;
> +}
> +
> static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
> {
> struct device_node *dp_node = dp->dev->of_node;
> @@ -1274,6 +1327,9 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
> break;
> }
>
> + if (analogix_dp_dt_parse_lanes_map(dp))
> + dev_dbg(dp->dev, "No valid data-lanes found, using default lane map\n");
> +
> 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 17347448c6b0..634fad241e69 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_core.h
> @@ -137,6 +137,8 @@ struct video_info {
>
> int max_link_rate;
> enum link_lane_count_type max_lane_count;
> +
> + u32 lane_map[LANE_COUNT4];
> };
>
> struct link_train {
> @@ -175,7 +177,7 @@ 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_lane_mapping(struct analogix_dp_device *dp);
> 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 38fd8d5014d2..45c7652645a1 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.c
> @@ -48,16 +48,15 @@ void analogix_dp_stop_video(struct analogix_dp_device *dp)
> writel(reg, dp->reg_base + ANALOGIX_DP_VIDEO_CTL_1);
> }
>
> -void analogix_dp_lane_swap(struct analogix_dp_device *dp, bool enable)
> +void analogix_dp_lane_mapping(struct analogix_dp_device *dp)
> {
> + u32 *lane_map = dp->video_info.lane_map;
> u32 reg;
>
> - 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;
> + reg = lane_map[0] << LANE0_MAP_SHIFT;
> + reg |= lane_map[1] << LANE1_MAP_SHIFT;
> + reg |= lane_map[2] << LANE2_MAP_SHIFT;
> + reg |= lane_map[3] << LANE3_MAP_SHIFT;
>
> writel(reg, dp->reg_base + ANALOGIX_DP_LANE_MAP);
> }
> @@ -140,7 +139,7 @@ void analogix_dp_reset(struct analogix_dp_device *dp)
>
> usleep_range(20, 30);
>
> - analogix_dp_lane_swap(dp, 0);
> + analogix_dp_lane_mapping(dp);
>
> writel(0x0, dp->reg_base + ANALOGIX_DP_SYS_CTL_1);
> writel(0x40, dp->reg_base + ANALOGIX_DP_SYS_CTL_2);
> diff --git a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
> index 12735139046c..ac914e37089b 100644
> --- a/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
> +++ b/drivers/gpu/drm/bridge/analogix/analogix_dp_reg.h
> @@ -209,6 +209,10 @@
> #define LANE0_MAP_LOGIC_LANE_1 (0x1 << 0)
> #define LANE0_MAP_LOGIC_LANE_2 (0x2 << 0)
> #define LANE0_MAP_LOGIC_LANE_3 (0x3 << 0)
> +#define LANE3_MAP_SHIFT (6)
> +#define LANE2_MAP_SHIFT (4)
> +#define LANE1_MAP_SHIFT (2)
> +#define LANE0_MAP_SHIFT (0)
>
> /* ANALOGIX_DP_ANALOG_CTL_1 */
> #define TX_TERMINAL_CTRL_50_OHM (0x1 << 4)
> --
> 2.34.1
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 833 bytes --]
prev parent reply other threads:[~2026-06-01 12:00 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-05-29 4:05 [PATCH v4 0/3] Add eDP lane mapping support Damon Ding
2026-05-29 4:05 ` [PATCH v4 1/3] dt-bindings: display: bridge: analogix-dp: Add data-lanes support for endpoint Damon Ding
2026-05-29 4:46 ` sashiko-bot
2026-05-29 16:43 ` Conor Dooley
2026-06-01 11:55 ` Sebastian Reichel
2026-05-29 4:05 ` [PATCH v4 2/3] drm/bridge: analogix_dp: Add validation for samsung,lane-count property Damon Ding
2026-05-29 5:31 ` sashiko-bot
2026-05-30 13:33 ` Luca Ceresoli
2026-05-30 13:38 ` Luca Ceresoli
2026-06-01 2:59 ` Damon Ding
2026-06-01 12:02 ` Luca Ceresoli
2026-06-01 12:24 ` Damon Ding
2026-05-29 4:05 ` [PATCH v4 3/3] drm/bridge: analogix_dp: Add support for optional data-lanes mapping Damon Ding
2026-05-29 5:56 ` sashiko-bot
2026-06-01 11:59 ` Sebastian Reichel [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=ah1zPfYFYYLNzbqV@venus \
--to=sebastian.reichel@collabora.com \
--cc=Laurent.pinchart@ideasonboard.com \
--cc=airlied@gmail.com \
--cc=andrzej.hajda@intel.com \
--cc=andy.yan@rock-chips.com \
--cc=conor+dt@kernel.org \
--cc=cristian.ciocaltea@collabora.com \
--cc=damon.ding@rock-chips.com \
--cc=devicetree@vger.kernel.org \
--cc=dianders@chromium.org \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=heiko@sntech.de \
--cc=hjc@rock-chips.com \
--cc=jernej.skrabec@gmail.com \
--cc=jonas@kwiboo.se \
--cc=krzk+dt@kernel.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=luca.ceresoli@bootlin.com \
--cc=m.szyprowski@samsung.com \
--cc=maarten.lankhorst@linux.intel.com \
--cc=mripard@kernel.org \
--cc=neil.armstrong@linaro.org \
--cc=nicolas.frattaroli@collabora.com \
--cc=rfoss@kernel.org \
--cc=robh@kernel.org \
--cc=simona@ffwll.ch \
--cc=tzimmermann@suse.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox