The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags. Use an open coded version of of_get_drm_display_mode() to get access to these flags and make sure they are passed on to the ipu-di driver.
Changes vs. v2: - removed patches which have already been applied - created a drm_bus_flags_from_videomode() helper to prevent code duplication as suggested by Philipp Zabel
Changes vs. v1: - rebased on top of https://patchwork.kernel.org/patch/9113791/ as per Philipp Zabel's request
GIT: [PATCHv2 1/3] drm/imx: imx-ldb: honor 'native-mode' property when GIT: [PATCHv2 2/3] drm/imx: convey the pixelclk-active and de-active flags GIT: [PATCHv2 3/3] drm/imx: remove dead code Signed-off-by: Lothar Waßmann LW@KARO-electronics.de --- drivers/gpu/drm/drm_modes.c | 20 +++++++++++++++++++- drivers/gpu/drm/imx/imx-ldb.c | 15 ++++++++++----- drivers/gpu/drm/imx/parallel-display.c | 16 +++++++++++++--- include/drm/drm_modes.h | 5 +++-- 4 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 7def3d5..7c97d5b 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -655,6 +655,21 @@ void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, } EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
+void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags) +{ + *bus_flags = 0; + if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) + *bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE; + if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) + *bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE; + + if (vm->flags & DISPLAY_FLAGS_DE_LOW) + *bus_flags |= DRM_BUS_FLAG_DE_LOW; + if (vm->flags & DISPLAY_FLAGS_DE_HIGH) + *bus_flags |= DRM_BUS_FLAG_DE_HIGH; +} +EXPORT_SYMBOL_GPL(drm_bus_flags_from_videomode); + #ifdef CONFIG_OF /** * of_get_drm_display_mode - get a drm_display_mode from devicetree @@ -670,7 +685,8 @@ EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode); * 0 on success, a negative errno code when no of videomode node was found. */ int of_get_drm_display_mode(struct device_node *np, - struct drm_display_mode *dmode, int index) + struct drm_display_mode *dmode, u32 *bus_flags, + int index) { struct videomode vm; int ret; @@ -680,6 +696,8 @@ int of_get_drm_display_mode(struct device_node *np, return ret;
drm_display_mode_from_videomode(&vm, dmode); + if (bus_flags) + drm_bus_flags_from_videomode(&vm, bus_flags);
pr_debug("%s: got %dx%d display mode from %s\n", of_node_full_name(np), vm.hactive, vm.vactive, np->name); diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index b2dc4df..bb9d745 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -65,7 +65,8 @@ struct imx_ldb_channel { int edid_len; struct drm_display_mode mode; int mode_valid; - int bus_format; + u32 bus_format; + u32 bus_flags; };
struct bus_mux { @@ -102,8 +103,10 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info;
num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); - if (!imx_ldb_ch->bus_format && di->num_bus_formats) + if (!imx_ldb_ch->bus_format && di->num_bus_formats) { imx_ldb_ch->bus_format = di->bus_formats[0]; + imx_ldb_ch->bus_flags = di->bus_flags; + } if (num_modes > 0) return num_modes; } @@ -202,7 +205,8 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) break; }
- imx_drm_set_bus_format(encoder, bus_format); + imx_drm_set_bus_config(encoder, bus_format, 2, 3, + imx_ldb_ch->bus_flags); }
static void imx_ldb_encoder_commit(struct drm_encoder *encoder) @@ -558,7 +562,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
ret = of_property_read_u32(child, "reg", &i); if (ret || i < 0 || i > 1) - return -EINVAL; + return ret ?: -EINVAL;
if (dual && i > 0) { dev_warn(dev, "dual-channel mode, ignoring second output\n"); @@ -602,7 +606,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) GFP_KERNEL); } else if (!channel->panel) { ret = of_get_drm_display_mode(child, &channel->mode, - OF_USE_NATIVE_MODE); + &channel->bus_flags, + OF_USE_NATIVE_MODE); if (!ret) channel->mode_valid = 1; } diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 2a81079..002d4d5 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -35,6 +35,7 @@ struct imx_parallel_display { void *edid; int edid_len; u32 bus_format; + u32 bus_flags; struct drm_display_mode mode; struct drm_panel *panel; }; @@ -56,8 +57,10 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info;
num_modes = imxpd->panel->funcs->get_modes(imxpd->panel); - if (!imxpd->bus_format && di->num_bus_formats) + if (!imxpd->bus_format && di->num_bus_formats) { imxpd->bus_format = di->bus_formats[0]; + imxpd->bus_flags = di->bus_flags; + } if (num_modes > 0) return num_modes; } @@ -69,10 +72,17 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
if (np) { struct drm_display_mode *mode = drm_mode_create(connector->dev); + int ret;
if (!mode) return -EINVAL; - of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE); + + ret = of_get_drm_display_mode(np, &imxpd->mode, + &imxpd->bus_flags, + OF_USE_NATIVE_MODE); + if (ret) + return ret; + drm_mode_copy(mode, &imxpd->mode); mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, drm_mode_probed_add(connector, mode); @@ -104,7 +114,7 @@ static void imx_pd_encoder_prepare(struct drm_encoder *encoder) { struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3, - imxpd->connector.display_info.bus_flags); + imxpd->bus_flags); }
static void imx_pd_encoder_commit(struct drm_encoder *encoder) diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 625966a..a243533 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -432,7 +432,7 @@ struct drm_cmdline_mode; struct drm_display_mode *drm_mode_create(struct drm_device *dev); void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, - const struct drm_display_mode *in); + const struct drm_display_mode *in); int drm_mode_convert_umode(struct drm_display_mode *out, const struct drm_mode_modeinfo *in); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); @@ -455,8 +455,9 @@ void drm_display_mode_from_videomode(const struct videomode *vm, struct drm_display_mode *dmode); void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, struct videomode *vm); +void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags); int of_get_drm_display_mode(struct device_node *np, - struct drm_display_mode *dmode, + struct drm_display_mode *dmode, u32 *bus_flags, int index);
void drm_mode_set_name(struct drm_display_mode *mode);
Hi,
On Wed, 25 May 2016 15:18:16 +0200 Lothar Waßmann wrote:
The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags. Use an open coded version of of_get_drm_display_mode() to get access to these flags and make sure they are passed on to the ipu-di driver.
Changes vs. v2:
- removed patches which have already been applied
- created a drm_bus_flags_from_videomode() helper to prevent code duplication as suggested by Philipp Zabel
Changes vs. v1:
- rebased on top of https://patchwork.kernel.org/patch/9113791/ as per Philipp Zabel's request
GIT: [PATCHv2 1/3] drm/imx: imx-ldb: honor 'native-mode' property when GIT: [PATCHv2 2/3] drm/imx: convey the pixelclk-active and de-active flags GIT: [PATCHv2 3/3] drm/imx: remove dead code Signed-off-by: Lothar Waßmann LW@KARO-electronics.de
drivers/gpu/drm/drm_modes.c | 20 +++++++++++++++++++- drivers/gpu/drm/imx/imx-ldb.c | 15 ++++++++++----- drivers/gpu/drm/imx/parallel-display.c | 16 +++++++++++++--- include/drm/drm_modes.h | 5 +++-- 4 files changed, 45 insertions(+), 11 deletions(-)
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 7def3d5..7c97d5b 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -655,6 +655,21 @@ void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, } EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
+void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags) +{
- *bus_flags = 0;
- if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
*bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE;
- if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
*bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE;
- if (vm->flags & DISPLAY_FLAGS_DE_LOW)
*bus_flags |= DRM_BUS_FLAG_DE_LOW;
- if (vm->flags & DISPLAY_FLAGS_DE_HIGH)
*bus_flags |= DRM_BUS_FLAG_DE_HIGH;
+} +EXPORT_SYMBOL_GPL(drm_bus_flags_from_videomode);
#ifdef CONFIG_OF /**
- of_get_drm_display_mode - get a drm_display_mode from devicetree
@@ -670,7 +685,8 @@ EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
- 0 on success, a negative errno code when no of videomode node was found.
*/ int of_get_drm_display_mode(struct device_node *np,
struct drm_display_mode *dmode, int index)
struct drm_display_mode *dmode, u32 *bus_flags,
int index)
{ struct videomode vm; int ret; @@ -680,6 +696,8 @@ int of_get_drm_display_mode(struct device_node *np, return ret;
drm_display_mode_from_videomode(&vm, dmode);
if (bus_flags)
drm_bus_flags_from_videomode(&vm, bus_flags);
pr_debug("%s: got %dx%d display mode from %s\n", of_node_full_name(np), vm.hactive, vm.vactive, np->name);
diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index b2dc4df..bb9d745 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -65,7 +65,8 @@ struct imx_ldb_channel { int edid_len; struct drm_display_mode mode; int mode_valid;
- int bus_format;
- u32 bus_format;
- u32 bus_flags;
};
struct bus_mux { @@ -102,8 +103,10 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info;
num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel);
if (!imx_ldb_ch->bus_format && di->num_bus_formats)
if (!imx_ldb_ch->bus_format && di->num_bus_formats) { imx_ldb_ch->bus_format = di->bus_formats[0];
imx_ldb_ch->bus_flags = di->bus_flags;
if (num_modes > 0) return num_modes; }}
@@ -202,7 +205,8 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) break; }
- imx_drm_set_bus_format(encoder, bus_format);
- imx_drm_set_bus_config(encoder, bus_format, 2, 3,
imx_ldb_ch->bus_flags);
}
static void imx_ldb_encoder_commit(struct drm_encoder *encoder) @@ -558,7 +562,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data)
ret = of_property_read_u32(child, "reg", &i); if (ret || i < 0 || i > 1)
return -EINVAL;
return ret ?: -EINVAL;
if (dual && i > 0) { dev_warn(dev, "dual-channel mode, ignoring second output\n");
@@ -602,7 +606,8 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) GFP_KERNEL); } else if (!channel->panel) { ret = of_get_drm_display_mode(child, &channel->mode,
OF_USE_NATIVE_MODE);
&channel->bus_flags,
}OF_USE_NATIVE_MODE); if (!ret) channel->mode_valid = 1;
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 2a81079..002d4d5 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -35,6 +35,7 @@ struct imx_parallel_display { void *edid; int edid_len; u32 bus_format;
- u32 bus_flags; struct drm_display_mode mode; struct drm_panel *panel;
}; @@ -56,8 +57,10 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info;
num_modes = imxpd->panel->funcs->get_modes(imxpd->panel);
if (!imxpd->bus_format && di->num_bus_formats)
if (!imxpd->bus_format && di->num_bus_formats) { imxpd->bus_format = di->bus_formats[0];
imxpd->bus_flags = di->bus_flags;
if (num_modes > 0) return num_modes; }}
@@ -69,10 +72,17 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
if (np) { struct drm_display_mode *mode = drm_mode_create(connector->dev);
int ret;
if (!mode) return -EINVAL;
of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE);
ret = of_get_drm_display_mode(np, &imxpd->mode,
&imxpd->bus_flags,
OF_USE_NATIVE_MODE);
if (ret)
return ret;
- drm_mode_copy(mode, &imxpd->mode); mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, drm_mode_probed_add(connector, mode);
@@ -104,7 +114,7 @@ static void imx_pd_encoder_prepare(struct drm_encoder *encoder) { struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3,
imxpd->connector.display_info.bus_flags);
imxpd->bus_flags);
}
static void imx_pd_encoder_commit(struct drm_encoder *encoder) diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index 625966a..a243533 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -432,7 +432,7 @@ struct drm_cmdline_mode; struct drm_display_mode *drm_mode_create(struct drm_device *dev); void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
const struct drm_display_mode *in);
const struct drm_display_mode *in);
int drm_mode_convert_umode(struct drm_display_mode *out, const struct drm_mode_modeinfo *in); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); @@ -455,8 +455,9 @@ void drm_display_mode_from_videomode(const struct videomode *vm, struct drm_display_mode *dmode); void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, struct videomode *vm); +void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags); int of_get_drm_display_mode(struct device_node *np,
struct drm_display_mode *dmode,
struct drm_display_mode *dmode, u32 *bus_flags, int index);
void drm_mode_set_name(struct drm_display_mode *mode);
Ping?!
Lothar Waßmann
On Tue, Jul 12, 2016 at 01:54:28PM +0200, Lothar Waßmann wrote:
Hi,
On Wed, 25 May 2016 15:18:16 +0200 Lothar Waßmann wrote:
The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags. Use an open coded version of of_get_drm_display_mode() to get access to these flags and make sure they are passed on to the ipu-di driver.
Changes vs. v2:
- removed patches which have already been applied
- created a drm_bus_flags_from_videomode() helper to prevent code duplication as suggested by Philipp Zabel
Changes vs. v1:
- rebased on top of https://patchwork.kernel.org/patch/9113791/ as per Philipp Zabel's request
GIT: [PATCHv2 1/3] drm/imx: imx-ldb: honor 'native-mode' property when GIT: [PATCHv2 2/3] drm/imx: convey the pixelclk-active and de-active flags GIT: [PATCHv2 3/3] drm/imx: remove dead code
Should this be split up into 3 patches? At least it's good practice to split up the drm core helper functions into it's own patch, instead of hiding it behind something with the drm/imx prefix - no one will spot it that way.
Ping?!
If imx maintainers keep being asleep at the helm I can merge this through drm-misc, but I'd like some more tested-by from other folks if possible. Even better when there's a review. -Daniel
Am Dienstag, den 12.07.2016, 14:43 +0200 schrieb Daniel Vetter:
On Tue, Jul 12, 2016 at 01:54:28PM +0200, Lothar Waßmann wrote:
Hi,
On Wed, 25 May 2016 15:18:16 +0200 Lothar Waßmann wrote:
The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags. Use an open coded version of of_get_drm_display_mode() to get access to these flags and make sure they are passed on to the ipu-di driver.
Changes vs. v2:
- removed patches which have already been applied
- created a drm_bus_flags_from_videomode() helper to prevent code duplication as suggested by Philipp Zabel
Changes vs. v1:
- rebased on top of https://patchwork.kernel.org/patch/9113791/ as per Philipp Zabel's request
GIT: [PATCHv2 1/3] drm/imx: imx-ldb: honor 'native-mode' property when GIT: [PATCHv2 2/3] drm/imx: convey the pixelclk-active and de-active flags GIT: [PATCHv2 3/3] drm/imx: remove dead code
Should this be split up into 3 patches? At least it's good practice to split up the drm core helper functions into it's own patch, instead of hiding it behind something with the drm/imx prefix - no one will spot it that way.
Ping?!
If imx maintainers keep being asleep at the helm I can merge this through drm-misc, but I'd like some more tested-by from other folks if possible. Even better when there's a review.
This clashes with the atomic modeset changes. If you don't disagree with the core change, I can include it with the next imx-drm/next pull request.
regards Philipp
Hi Lothar,
Am Dienstag, den 12.07.2016, 13:54 +0200 schrieb Lothar Waßmann:
Hi,
On Wed, 25 May 2016 15:18:16 +0200 Lothar Waßmann wrote:
The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags. Use an open coded version of of_get_drm_display_mode() to get access to these flags and make sure they are passed on to the ipu-di driver.
Changes vs. v2:
- removed patches which have already been applied
- created a drm_bus_flags_from_videomode() helper to prevent code duplication as suggested by Philipp Zabel
[...]
Ping?!
Sorry for the delay. I wanted to get the atomic modeset changes underneath this because your patches are easier to rebase than the other way around. I've applied v4 patch 1 and 2, patch 3 has to be rebased onto imx-drm/next.
regards Philipp
The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags.
Changes vs. v3: - split the patch as suggested by Daniel Vetter
Changes vs. v2: - removed patches which have already been applied - created a drm_bus_flags_from_videomode() helper to prevent code duplication as suggested by Philipp Zabel
Changes vs. v1: - rebased on top of https://patchwork.kernel.org/patch/9113791/ as per Philipp Zabel's request
of_get_drm_display_mode() may fail. Check its return code and bail out on error.
Signed-off-by: Lothar Waßmann LW@KARO-electronics.de --- drivers/gpu/drm/imx/parallel-display.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 2d1fd02..4b2ec5d 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -69,10 +69,16 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector)
if (np) { struct drm_display_mode *mode = drm_mode_create(connector->dev); + int ret;
if (!mode) return -EINVAL; - of_get_drm_display_mode(np, &imxpd->mode, OF_USE_NATIVE_MODE); + + ret = of_get_drm_display_mode(np, &imxpd->mode, + OF_USE_NATIVE_MODE); + if (ret) + return ret; + drm_mode_copy(mode, &imxpd->mode); mode->type |= DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED, drm_mode_probed_add(connector, mode);
add a helper function to extract information about pixel clock and DE polarity from DT for use by of_get_drm_display_mode(). While at it, convert spaces to tabs in indentation in drm_modes.h.
Signed-off-by: Lothar Waßmann LW@KARO-electronics.de --- drivers/gpu/drm/drm_modes.c | 15 +++++++++++++++ include/drm/drm_modes.h | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index fc5040a..51804e5 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -657,6 +657,21 @@ void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, } EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
+void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags) +{ + *bus_flags = 0; + if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE) + *bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE; + if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE) + *bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE; + + if (vm->flags & DISPLAY_FLAGS_DE_LOW) + *bus_flags |= DRM_BUS_FLAG_DE_LOW; + if (vm->flags & DISPLAY_FLAGS_DE_HIGH) + *bus_flags |= DRM_BUS_FLAG_DE_HIGH; +} +EXPORT_SYMBOL_GPL(drm_bus_flags_from_videomode); + #ifdef CONFIG_OF /** * of_get_drm_display_mode - get a drm_display_mode from devicetree diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index ff48177..a8164d2 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -434,7 +434,7 @@ struct drm_cmdline_mode; struct drm_display_mode *drm_mode_create(struct drm_device *dev); void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out, - const struct drm_display_mode *in); + const struct drm_display_mode *in); int drm_mode_convert_umode(struct drm_display_mode *out, const struct drm_mode_modeinfo *in); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); @@ -457,6 +457,7 @@ void drm_display_mode_from_videomode(const struct videomode *vm, struct drm_display_mode *dmode); void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, struct videomode *vm); +void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags); int of_get_drm_display_mode(struct device_node *np, struct drm_display_mode *dmode, int index);
On Tue, Jul 12, 2016 at 03:30:02PM +0200, Lothar Waßmann wrote:
add a helper function to extract information about pixel clock and DE polarity from DT for use by of_get_drm_display_mode(). While at it, convert spaces to tabs in indentation in drm_modes.h.
Signed-off-by: Lothar Waßmann LW@KARO-electronics.de
drivers/gpu/drm/drm_modes.c | 15 +++++++++++++++ include/drm/drm_modes.h | 3 ++- 2 files changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index fc5040a..51804e5 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -657,6 +657,21 @@ void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, } EXPORT_SYMBOL_GPL(drm_display_mode_to_videomode);
+void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags)
Missing kerneldoc. Please create a patch to fix that so I can pick it up. Thanks. -Daniel
+{
- *bus_flags = 0;
- if (vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE)
*bus_flags |= DRM_BUS_FLAG_PIXDATA_POSEDGE;
- if (vm->flags & DISPLAY_FLAGS_PIXDATA_NEGEDGE)
*bus_flags |= DRM_BUS_FLAG_PIXDATA_NEGEDGE;
- if (vm->flags & DISPLAY_FLAGS_DE_LOW)
*bus_flags |= DRM_BUS_FLAG_DE_LOW;
- if (vm->flags & DISPLAY_FLAGS_DE_HIGH)
*bus_flags |= DRM_BUS_FLAG_DE_HIGH;
+} +EXPORT_SYMBOL_GPL(drm_bus_flags_from_videomode);
#ifdef CONFIG_OF /**
- of_get_drm_display_mode - get a drm_display_mode from devicetree
diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index ff48177..a8164d2 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -434,7 +434,7 @@ struct drm_cmdline_mode; struct drm_display_mode *drm_mode_create(struct drm_device *dev); void drm_mode_destroy(struct drm_device *dev, struct drm_display_mode *mode); void drm_mode_convert_to_umode(struct drm_mode_modeinfo *out,
const struct drm_display_mode *in);
const struct drm_display_mode *in);
int drm_mode_convert_umode(struct drm_display_mode *out, const struct drm_mode_modeinfo *in); void drm_mode_probed_add(struct drm_connector *connector, struct drm_display_mode *mode); @@ -457,6 +457,7 @@ void drm_display_mode_from_videomode(const struct videomode *vm, struct drm_display_mode *dmode); void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, struct videomode *vm); +void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags); int of_get_drm_display_mode(struct device_node *np, struct drm_display_mode *dmode, int index); -- 2.1.4
The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags. Enhance of_get_drm_display_mode() to also return the bus flags in a separate variable, so that they can be passed on to the ipu-di driver.
Signed-off-by: Lothar Waßmann LW@KARO-electronics.de --- drivers/gpu/drm/drm_modes.c | 5 ++++- drivers/gpu/drm/imx/imx-ldb.c | 11 ++++++++--- drivers/gpu/drm/imx/parallel-display.c | 8 ++++++-- include/drm/drm_modes.h | 2 +- 4 files changed, 19 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/drm_modes.c b/drivers/gpu/drm/drm_modes.c index 51804e5..1570487 100644 --- a/drivers/gpu/drm/drm_modes.c +++ b/drivers/gpu/drm/drm_modes.c @@ -687,7 +687,8 @@ EXPORT_SYMBOL_GPL(drm_bus_flags_from_videomode); * 0 on success, a negative errno code when no of videomode node was found. */ int of_get_drm_display_mode(struct device_node *np, - struct drm_display_mode *dmode, int index) + struct drm_display_mode *dmode, u32 *bus_flags, + int index) { struct videomode vm; int ret; @@ -697,6 +698,8 @@ int of_get_drm_display_mode(struct device_node *np, return ret;
drm_display_mode_from_videomode(&vm, dmode); + if (bus_flags) + drm_bus_flags_from_videomode(&vm, bus_flags);
pr_debug("%s: got %dx%d display mode from %s\n", of_node_full_name(np), vm.hactive, vm.vactive, np->name); diff --git a/drivers/gpu/drm/imx/imx-ldb.c b/drivers/gpu/drm/imx/imx-ldb.c index beff793..e445182 100644 --- a/drivers/gpu/drm/imx/imx-ldb.c +++ b/drivers/gpu/drm/imx/imx-ldb.c @@ -66,7 +66,8 @@ struct imx_ldb_channel { int edid_len; struct drm_display_mode mode; int mode_valid; - int bus_format; + u32 bus_format; + u32 bus_flags; };
struct bus_mux { @@ -103,8 +104,10 @@ static int imx_ldb_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info;
num_modes = imx_ldb_ch->panel->funcs->get_modes(imx_ldb_ch->panel); - if (!imx_ldb_ch->bus_format && di->num_bus_formats) + if (!imx_ldb_ch->bus_format && di->num_bus_formats) { imx_ldb_ch->bus_format = di->bus_formats[0]; + imx_ldb_ch->bus_flags = di->bus_flags; + } if (num_modes > 0) return num_modes; } @@ -206,7 +209,8 @@ static void imx_ldb_encoder_prepare(struct drm_encoder *encoder) break; }
- imx_drm_set_bus_format(encoder, bus_format); + imx_drm_set_bus_config(encoder, bus_format, 2, 3, + imx_ldb_ch->bus_flags); }
static void imx_ldb_encoder_commit(struct drm_encoder *encoder) @@ -626,6 +630,7 @@ static int imx_ldb_bind(struct device *dev, struct device *master, void *data) /* fallback to display-timings node */ ret = of_get_drm_display_mode(child, &channel->mode, + &channel->bus_flags, OF_USE_NATIVE_MODE); if (!ret) channel->mode_valid = 1; diff --git a/drivers/gpu/drm/imx/parallel-display.c b/drivers/gpu/drm/imx/parallel-display.c index 4b2ec5d..f956387 100644 --- a/drivers/gpu/drm/imx/parallel-display.c +++ b/drivers/gpu/drm/imx/parallel-display.c @@ -35,6 +35,7 @@ struct imx_parallel_display { void *edid; int edid_len; u32 bus_format; + u32 bus_flags; struct drm_display_mode mode; struct drm_panel *panel; }; @@ -56,8 +57,10 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) struct drm_display_info *di = &connector->display_info;
num_modes = imxpd->panel->funcs->get_modes(imxpd->panel); - if (!imxpd->bus_format && di->num_bus_formats) + if (!imxpd->bus_format && di->num_bus_formats) { imxpd->bus_format = di->bus_formats[0]; + imxpd->bus_flags = di->bus_flags; + } if (num_modes > 0) return num_modes; } @@ -75,6 +78,7 @@ static int imx_pd_connector_get_modes(struct drm_connector *connector) return -EINVAL;
ret = of_get_drm_display_mode(np, &imxpd->mode, + &imxpd->bus_flags, OF_USE_NATIVE_MODE); if (ret) return ret; @@ -110,7 +114,7 @@ static void imx_pd_encoder_prepare(struct drm_encoder *encoder) { struct imx_parallel_display *imxpd = enc_to_imxpd(encoder); imx_drm_set_bus_config(encoder, imxpd->bus_format, 2, 3, - imxpd->connector.display_info.bus_flags); + imxpd->bus_flags); }
static void imx_pd_encoder_commit(struct drm_encoder *encoder) diff --git a/include/drm/drm_modes.h b/include/drm/drm_modes.h index a8164d2..48e1a56 100644 --- a/include/drm/drm_modes.h +++ b/include/drm/drm_modes.h @@ -459,7 +459,7 @@ void drm_display_mode_to_videomode(const struct drm_display_mode *dmode, struct videomode *vm); void drm_bus_flags_from_videomode(const struct videomode *vm, u32 *bus_flags); int of_get_drm_display_mode(struct device_node *np, - struct drm_display_mode *dmode, + struct drm_display_mode *dmode, u32 *bus_flags, int index);
void drm_mode_set_name(struct drm_display_mode *mode);
On Wed, May 25, 2016 at 03:18:16PM +0200, Lothar Waßmann wrote:
The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags. Use an open coded version of of_get_drm_display_mode() to get access to these flags and make sure they are passed on to the ipu-di driver.
Changes vs. v2:
- removed patches which have already been applied
- created a drm_bus_flags_from_videomode() helper to prevent code duplication as suggested by Philipp Zabel
Changes vs. v1:
- rebased on top of https://patchwork.kernel.org/patch/9113791/ as per Philipp Zabel's request
GIT: [PATCHv2 1/3] drm/imx: imx-ldb: honor 'native-mode' property when GIT: [PATCHv2 2/3] drm/imx: convey the pixelclk-active and de-active flags GIT: [PATCHv2 3/3] drm/imx: remove dead code Signed-off-by: Lothar Waßmann LW@KARO-electronics.de
drivers/gpu/drm/drm_modes.c | 20 +++++++++++++++++++- drivers/gpu/drm/imx/imx-ldb.c | 15 ++++++++++----- drivers/gpu/drm/imx/parallel-display.c | 16 +++++++++++++--- include/drm/drm_modes.h | 5 +++-- 4 files changed, 45 insertions(+), 11 deletions(-)
Maybe a stupid question, but why does i.MX even allow video timings to be specified in DT instead of going through panel drivers like everyone else?
Thierry
Am Dienstag, den 12.07.2016, 16:39 +0200 schrieb Thierry Reding:
On Wed, May 25, 2016 at 03:18:16PM +0200, Lothar Waßmann wrote:
The 'de-active' and 'pixelclk-active' DT properties are evaluated by of_parse_display_timing() called from of_get_drm_display_mode(), but later lost in the conversion from videomode.flags to drm_display_mode.flags. Use an open coded version of of_get_drm_display_mode() to get access to these flags and make sure they are passed on to the ipu-di driver.
Changes vs. v2:
- removed patches which have already been applied
- created a drm_bus_flags_from_videomode() helper to prevent code duplication as suggested by Philipp Zabel
Changes vs. v1:
- rebased on top of https://patchwork.kernel.org/patch/9113791/ as per Philipp Zabel's request
GIT: [PATCHv2 1/3] drm/imx: imx-ldb: honor 'native-mode' property when GIT: [PATCHv2 2/3] drm/imx: convey the pixelclk-active and de-active flags GIT: [PATCHv2 3/3] drm/imx: remove dead code Signed-off-by: Lothar Waßmann LW@KARO-electronics.de
drivers/gpu/drm/drm_modes.c | 20 +++++++++++++++++++- drivers/gpu/drm/imx/imx-ldb.c | 15 ++++++++++----- drivers/gpu/drm/imx/parallel-display.c | 16 +++++++++++++--- include/drm/drm_modes.h | 5 +++-- 4 files changed, 45 insertions(+), 11 deletions(-)
Maybe a stupid question, but why does i.MX even allow video timings to be specified in DT instead of going through panel drivers like everyone else?
DT backwards compatibility. Arguably setting the pixel clock polarity in DT was always possible, even though it was never hooked up properly in mainline. We should encourage moving towards panel drivers though. There are a lot of i.MX6 device trees that could be converted.
regards Philipp
dri-devel@lists.freedesktop.org