From: Fabrizio Castro <fabrizio.castro@bp.renesas.com> To: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>, Geert Uytterhoeven <geert+renesas@glider.be>, David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>, Rob Herring <robh+dt@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Thierry Reding <thierry.reding@gmail.com>, Maarten Lankhorst <maarten.lankhorst@linux.intel.com>, Maxime Ripard <mripard@kernel.org>, Sean Paul <sean@poorly.run>, Andrzej Hajda <a.hajda@samsung.com> Cc: Fabrizio Castro <fabrizio.castro@bp.renesas.com>, Sam Ravnborg <sam@ravnborg.org>, Simon Horman <horms@verge.net.au>, Magnus Damm <magnus.damm@gmail.com>, Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>, dri-devel@lists.freedesktop.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-renesas-soc@vger.kernel.org, Chris Paterson <Chris.Paterson2@renesas.com>, Biju Das <biju.das@bp.renesas.com>, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Jacopo Mondi <jacopo+renesas@jmondi.org>, ebiharaml@si-linux.co.jp Subject: [PATCH v6 4/6] drm: rcar-du: lvds: Allow for even and odd pixels swap Date: Tue, 17 Dec 2019 13:45:59 +0000 [thread overview] Message-ID: <1576590361-28244-5-git-send-email-fabrizio.castro@bp.renesas.com> (raw) In-Reply-To: <1576590361-28244-1-git-send-email-fabrizio.castro@bp.renesas.com> DT properties dual-lvds-even-pixels and dual-lvds-odd-pixels can be used to work out if the driver needs to swap even and odd pixels around. This patch makes use of the return value from function drm_of_lvds_get_dual_link_pixel_order to determine if we need to swap odd and even pixels around for things to work properly. The dual_link boolean field from struct rcar_lvds is not sufficient to describe the type of LVDS link anymore, since we now have information related to pixel order, therefore rename it to link_type and repurpose its usage to fit the new requirements. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- v5->v6: * Renamed dual_link to link_type and reworked its usage v4->v5: * Addressed comments from Laurent's review v3->v4: * New patch extracted from patch: "drm: rcar-du: lvds: Add dual-LVDS panels support" --- drivers/gpu/drm/rcar-du/rcar_lvds.c | 77 ++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index fdbd36b..8ffa4fb 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -37,6 +37,12 @@ enum rcar_lvds_mode { RCAR_LVDS_MODE_VESA = 4, }; +enum rcar_lvds_link_type { + RCAR_LVDS_SINGLE_LINK = 0, + RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS = 1, + RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS = 2, +}; + #define RCAR_LVDS_QUIRK_LANES BIT(0) /* LVDS lanes 1 and 3 inverted */ #define RCAR_LVDS_QUIRK_GEN3_LVEN BIT(1) /* LVEN bit needs to be set on R8A77970/R8A7799x */ #define RCAR_LVDS_QUIRK_PWD BIT(2) /* PWD bit available (all of Gen3 but E3) */ @@ -67,7 +73,7 @@ struct rcar_lvds { } clocks; struct drm_bridge *companion; - bool dual_link; + enum rcar_lvds_link_type link_type; }; #define bridge_to_rcar_lvds(b) \ @@ -456,7 +462,7 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge, return; /* Enable the companion LVDS encoder in dual-link mode. */ - if (lvds->dual_link && lvds->companion) + if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion) __rcar_lvds_atomic_enable(lvds->companion, state, crtc, connector); @@ -482,19 +488,38 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge, rcar_lvds_write(lvds, LVDCHCR, lvdhcr); if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) { - /* - * Configure vertical stripe based on the mode of operation of - * the connected device. - */ - rcar_lvds_write(lvds, LVDSTRIPE, - lvds->dual_link ? LVDSTRIPE_ST_ON : 0); + u32 lvdstripe = 0; + + if (lvds->link_type != RCAR_LVDS_SINGLE_LINK) { + /* + * By default we generate even pixels from the primary + * encoder and odd pixels from the companion encoder. + * Swap pixels around if the sink requires odd pixels + * from the primary encoder and even pixels from the + * companion encoder. + */ + bool swap_pixels = lvds->link_type == + RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS; + + /* + * Configure vertical stripe since we are dealing with + * an LVDS dual-link connection. + * + * ST_SWAP is reserved for the companion encoder, only + * set it in the primary encoder. + */ + lvdstripe = LVDSTRIPE_ST_ON + | (lvds->companion && swap_pixels ? + LVDSTRIPE_ST_SWAP : 0); + } + rcar_lvds_write(lvds, LVDSTRIPE, lvdstripe); } /* * PLL clock configuration on all instances but the companion in * dual-link mode. */ - if (!lvds->dual_link || lvds->companion) { + if (lvds->link_type == RCAR_LVDS_SINGLE_LINK || lvds->companion) { const struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); const struct drm_display_mode *mode = @@ -592,7 +617,7 @@ static void rcar_lvds_atomic_disable(struct drm_bridge *bridge, rcar_lvds_write(lvds, LVDPLLCR, 0); /* Disable the companion LVDS encoder in dual-link mode. */ - if (lvds->dual_link && lvds->companion) + if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion) lvds->companion->funcs->atomic_disable(lvds->companion, state); clk_disable_unprepare(lvds->clocks.mod); @@ -666,7 +691,7 @@ bool rcar_lvds_dual_link(struct drm_bridge *bridge) { struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); - return lvds->dual_link; + return lvds->link_type != RCAR_LVDS_SINGLE_LINK; } EXPORT_SYMBOL_GPL(rcar_lvds_dual_link); @@ -712,17 +737,28 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds) of_node_put(port0); of_node_put(port1); - if (dual_link >= DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) - lvds->dual_link = true; - else if (lvds->next_bridge && lvds->next_bridge->timings) + switch (dual_link) { + case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS: + lvds->link_type = RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS; + break; + case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS: + lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS; + break; + default: /* * Early dual-link bridge specific implementations populate the - * timings field of drm_bridge, read the dual_link flag off the - * bridge directly for backward compatibility. + * timings field of drm_bridge. If the flag is set, we assume + * that we are expected to generate even pixels from the primary + * encoder, and odd pixels from the companion encoder. */ - lvds->dual_link = lvds->next_bridge->timings->dual_link; + if (lvds->next_bridge && lvds->next_bridge->timings && + lvds->next_bridge->timings->dual_link) + lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS; + else + lvds->link_type = RCAR_LVDS_SINGLE_LINK; + } - if (!lvds->dual_link) { + if (lvds->link_type == RCAR_LVDS_SINGLE_LINK) { dev_dbg(dev, "Single-link configuration detected\n"); goto done; } @@ -737,6 +773,9 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds) "Dual-link configuration detected (companion encoder %pOF)\n", companion); + if (lvds->link_type == RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS) + dev_dbg(dev, "Data swapping required\n"); + /* * FIXME: We should not be messing with the companion encoder private * data from the primary encoder, we should rather let the companion @@ -747,7 +786,7 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds) * for the time being. */ companion_lvds = bridge_to_rcar_lvds(lvds->companion); - companion_lvds->dual_link = true; + companion_lvds->link_type = lvds->link_type; done: of_node_put(companion); -- 2.7.4
WARNING: multiple messages have this Message-ID (diff)
From: Fabrizio Castro <fabrizio.castro@bp.renesas.com> To: Laurent Pinchart <Laurent.pinchart@ideasonboard.com>, Geert Uytterhoeven <geert+renesas@glider.be>, David Airlie <airlied@linux.ie>, Daniel Vetter <daniel@ffwll.ch>, Rob Herring <robh+dt@kernel.org>, Mark Rutland <mark.rutland@arm.com>, Thierry Reding <thierry.reding@gmail.com>, Maarten Lankhorst <maarten.lankhorst@linux.intel.com>, Maxime Ripard <mripard@kernel.org>, Sean Paul <sean@poorly.run>, Andrzej Hajda <a.hajda@samsung.com> Cc: Fabrizio Castro <fabrizio.castro@bp.renesas.com>, devicetree@vger.kernel.org, Chris Paterson <Chris.Paterson2@renesas.com>, ebiharaml@si-linux.co.jp, Kieran Bingham <kieran.bingham+renesas@ideasonboard.com>, Magnus Damm <magnus.damm@gmail.com>, linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Biju Das <biju.das@bp.renesas.com>, linux-renesas-soc@vger.kernel.org, Simon Horman <horms@verge.net.au>, Jacopo Mondi <jacopo+renesas@jmondi.org>, Laurent Pinchart <laurent.pinchart@ideasonboard.com>, Sam Ravnborg <sam@ravnborg.org> Subject: [PATCH v6 4/6] drm: rcar-du: lvds: Allow for even and odd pixels swap Date: Tue, 17 Dec 2019 13:45:59 +0000 [thread overview] Message-ID: <1576590361-28244-5-git-send-email-fabrizio.castro@bp.renesas.com> (raw) In-Reply-To: <1576590361-28244-1-git-send-email-fabrizio.castro@bp.renesas.com> DT properties dual-lvds-even-pixels and dual-lvds-odd-pixels can be used to work out if the driver needs to swap even and odd pixels around. This patch makes use of the return value from function drm_of_lvds_get_dual_link_pixel_order to determine if we need to swap odd and even pixels around for things to work properly. The dual_link boolean field from struct rcar_lvds is not sufficient to describe the type of LVDS link anymore, since we now have information related to pixel order, therefore rename it to link_type and repurpose its usage to fit the new requirements. Signed-off-by: Fabrizio Castro <fabrizio.castro@bp.renesas.com> Reviewed-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> --- v5->v6: * Renamed dual_link to link_type and reworked its usage v4->v5: * Addressed comments from Laurent's review v3->v4: * New patch extracted from patch: "drm: rcar-du: lvds: Add dual-LVDS panels support" --- drivers/gpu/drm/rcar-du/rcar_lvds.c | 77 ++++++++++++++++++++++++++++--------- 1 file changed, 58 insertions(+), 19 deletions(-) diff --git a/drivers/gpu/drm/rcar-du/rcar_lvds.c b/drivers/gpu/drm/rcar-du/rcar_lvds.c index fdbd36b..8ffa4fb 100644 --- a/drivers/gpu/drm/rcar-du/rcar_lvds.c +++ b/drivers/gpu/drm/rcar-du/rcar_lvds.c @@ -37,6 +37,12 @@ enum rcar_lvds_mode { RCAR_LVDS_MODE_VESA = 4, }; +enum rcar_lvds_link_type { + RCAR_LVDS_SINGLE_LINK = 0, + RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS = 1, + RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS = 2, +}; + #define RCAR_LVDS_QUIRK_LANES BIT(0) /* LVDS lanes 1 and 3 inverted */ #define RCAR_LVDS_QUIRK_GEN3_LVEN BIT(1) /* LVEN bit needs to be set on R8A77970/R8A7799x */ #define RCAR_LVDS_QUIRK_PWD BIT(2) /* PWD bit available (all of Gen3 but E3) */ @@ -67,7 +73,7 @@ struct rcar_lvds { } clocks; struct drm_bridge *companion; - bool dual_link; + enum rcar_lvds_link_type link_type; }; #define bridge_to_rcar_lvds(b) \ @@ -456,7 +462,7 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge, return; /* Enable the companion LVDS encoder in dual-link mode. */ - if (lvds->dual_link && lvds->companion) + if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion) __rcar_lvds_atomic_enable(lvds->companion, state, crtc, connector); @@ -482,19 +488,38 @@ static void __rcar_lvds_atomic_enable(struct drm_bridge *bridge, rcar_lvds_write(lvds, LVDCHCR, lvdhcr); if (lvds->info->quirks & RCAR_LVDS_QUIRK_DUAL_LINK) { - /* - * Configure vertical stripe based on the mode of operation of - * the connected device. - */ - rcar_lvds_write(lvds, LVDSTRIPE, - lvds->dual_link ? LVDSTRIPE_ST_ON : 0); + u32 lvdstripe = 0; + + if (lvds->link_type != RCAR_LVDS_SINGLE_LINK) { + /* + * By default we generate even pixels from the primary + * encoder and odd pixels from the companion encoder. + * Swap pixels around if the sink requires odd pixels + * from the primary encoder and even pixels from the + * companion encoder. + */ + bool swap_pixels = lvds->link_type == + RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS; + + /* + * Configure vertical stripe since we are dealing with + * an LVDS dual-link connection. + * + * ST_SWAP is reserved for the companion encoder, only + * set it in the primary encoder. + */ + lvdstripe = LVDSTRIPE_ST_ON + | (lvds->companion && swap_pixels ? + LVDSTRIPE_ST_SWAP : 0); + } + rcar_lvds_write(lvds, LVDSTRIPE, lvdstripe); } /* * PLL clock configuration on all instances but the companion in * dual-link mode. */ - if (!lvds->dual_link || lvds->companion) { + if (lvds->link_type == RCAR_LVDS_SINGLE_LINK || lvds->companion) { const struct drm_crtc_state *crtc_state = drm_atomic_get_new_crtc_state(state, crtc); const struct drm_display_mode *mode = @@ -592,7 +617,7 @@ static void rcar_lvds_atomic_disable(struct drm_bridge *bridge, rcar_lvds_write(lvds, LVDPLLCR, 0); /* Disable the companion LVDS encoder in dual-link mode. */ - if (lvds->dual_link && lvds->companion) + if (lvds->link_type != RCAR_LVDS_SINGLE_LINK && lvds->companion) lvds->companion->funcs->atomic_disable(lvds->companion, state); clk_disable_unprepare(lvds->clocks.mod); @@ -666,7 +691,7 @@ bool rcar_lvds_dual_link(struct drm_bridge *bridge) { struct rcar_lvds *lvds = bridge_to_rcar_lvds(bridge); - return lvds->dual_link; + return lvds->link_type != RCAR_LVDS_SINGLE_LINK; } EXPORT_SYMBOL_GPL(rcar_lvds_dual_link); @@ -712,17 +737,28 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds) of_node_put(port0); of_node_put(port1); - if (dual_link >= DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS) - lvds->dual_link = true; - else if (lvds->next_bridge && lvds->next_bridge->timings) + switch (dual_link) { + case DRM_LVDS_DUAL_LINK_ODD_EVEN_PIXELS: + lvds->link_type = RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS; + break; + case DRM_LVDS_DUAL_LINK_EVEN_ODD_PIXELS: + lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS; + break; + default: /* * Early dual-link bridge specific implementations populate the - * timings field of drm_bridge, read the dual_link flag off the - * bridge directly for backward compatibility. + * timings field of drm_bridge. If the flag is set, we assume + * that we are expected to generate even pixels from the primary + * encoder, and odd pixels from the companion encoder. */ - lvds->dual_link = lvds->next_bridge->timings->dual_link; + if (lvds->next_bridge && lvds->next_bridge->timings && + lvds->next_bridge->timings->dual_link) + lvds->link_type = RCAR_LVDS_DUAL_LINK_EVEN_ODD_PIXELS; + else + lvds->link_type = RCAR_LVDS_SINGLE_LINK; + } - if (!lvds->dual_link) { + if (lvds->link_type == RCAR_LVDS_SINGLE_LINK) { dev_dbg(dev, "Single-link configuration detected\n"); goto done; } @@ -737,6 +773,9 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds) "Dual-link configuration detected (companion encoder %pOF)\n", companion); + if (lvds->link_type == RCAR_LVDS_DUAL_LINK_ODD_EVEN_PIXELS) + dev_dbg(dev, "Data swapping required\n"); + /* * FIXME: We should not be messing with the companion encoder private * data from the primary encoder, we should rather let the companion @@ -747,7 +786,7 @@ static int rcar_lvds_parse_dt_companion(struct rcar_lvds *lvds) * for the time being. */ companion_lvds = bridge_to_rcar_lvds(lvds->companion); - companion_lvds->dual_link = true; + companion_lvds->link_type = lvds->link_type; done: of_node_put(companion); -- 2.7.4 _______________________________________________ dri-devel mailing list dri-devel@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/dri-devel
next prev parent reply other threads:[~2019-12-17 13:46 UTC|newest] Thread overview: 24+ messages / expand[flat|nested] mbox.gz Atom feed top 2019-12-17 13:45 [PATCH v6 0/6] Add dual-LVDS panel support to EK874 Fabrizio Castro 2019-12-17 13:45 ` Fabrizio Castro 2019-12-17 13:45 ` [PATCH v6 1/6] drm: of: Add drm_of_lvds_get_dual_link_pixel_order Fabrizio Castro 2019-12-17 13:45 ` Fabrizio Castro 2019-12-17 13:45 ` [PATCH v6 2/6] drm: rcar-du: lvds: Improve identification of panels Fabrizio Castro 2019-12-17 13:45 ` Fabrizio Castro 2019-12-17 13:45 ` [PATCH v6 3/6] drm: rcar-du: lvds: Get dual link configuration from DT Fabrizio Castro 2019-12-17 13:45 ` Fabrizio Castro 2019-12-17 13:45 ` Fabrizio Castro [this message] 2019-12-17 13:45 ` [PATCH v6 4/6] drm: rcar-du: lvds: Allow for even and odd pixels swap Fabrizio Castro 2019-12-17 13:46 ` [PATCH v6 5/6] dt-bindings: display: Add idk-2121wr binding Fabrizio Castro 2019-12-17 13:46 ` Fabrizio Castro 2019-12-18 20:20 ` Rob Herring 2019-12-18 20:20 ` Rob Herring 2019-12-18 20:21 ` Rob Herring 2019-12-18 20:21 ` Rob Herring 2019-12-17 13:46 ` [PATCH v6 6/6] arm64: dts: renesas: Add EK874 board with idk-2121wr display support Fabrizio Castro 2019-12-17 13:46 ` Fabrizio Castro 2019-12-17 23:13 ` [PATCH v6 0/6] Add dual-LVDS panel support to EK874 Laurent Pinchart 2019-12-17 23:13 ` Laurent Pinchart 2020-01-17 8:47 ` Geert Uytterhoeven 2020-01-17 8:47 ` Geert Uytterhoeven 2020-01-17 9:22 ` Sam Ravnborg 2020-01-17 9:22 ` Sam Ravnborg
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=1576590361-28244-5-git-send-email-fabrizio.castro@bp.renesas.com \ --to=fabrizio.castro@bp.renesas.com \ --cc=Chris.Paterson2@renesas.com \ --cc=Laurent.pinchart@ideasonboard.com \ --cc=a.hajda@samsung.com \ --cc=airlied@linux.ie \ --cc=biju.das@bp.renesas.com \ --cc=daniel@ffwll.ch \ --cc=devicetree@vger.kernel.org \ --cc=dri-devel@lists.freedesktop.org \ --cc=ebiharaml@si-linux.co.jp \ --cc=geert+renesas@glider.be \ --cc=horms@verge.net.au \ --cc=jacopo+renesas@jmondi.org \ --cc=kieran.bingham+renesas@ideasonboard.com \ --cc=linux-kernel@vger.kernel.org \ --cc=linux-renesas-soc@vger.kernel.org \ --cc=maarten.lankhorst@linux.intel.com \ --cc=magnus.damm@gmail.com \ --cc=mark.rutland@arm.com \ --cc=mripard@kernel.org \ --cc=robh+dt@kernel.org \ --cc=sam@ravnborg.org \ --cc=sean@poorly.run \ --cc=thierry.reding@gmail.com \ /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: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.