From 0a20012605033c8acd8b2c209c422d78880e2896 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 16 Nov 2012 14:59:56 +0200 Subject: OMAPDSS: add pdata->default_display_name We can currently set the default display (i.e. the initial display) in the omapdss platform data by using a pointer to the default omap_dss_device. Internally omapdss uses the device's name to resolve the default display. As it's difficult to get the omap_dss_device pointer in the future, after we've changed the omapdss device model, this patch adds a new way to define the default display, by using the name of the display. Signed-off-by: Tomi Valkeinen Reviewed-by: Archit Taneja diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index c9c2252..710e9f9 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -243,6 +243,8 @@ static int __init omap_dss_probe(struct platform_device *pdev) if (def_disp_name) core.default_display_name = def_disp_name; + else if (pdata->default_display_name) + core.default_display_name = pdata->default_display_name; else if (pdata->default_device) core.default_display_name = pdata->default_device->name; diff --git a/include/video/omapdss.h b/include/video/omapdss.h index aeb4e9a..6462f68 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -365,6 +365,7 @@ struct omap_dss_board_info { int num_devices; struct omap_dss_device **devices; struct omap_dss_device *default_device; + const char *default_display_name; int (*dsi_enable_pads)(int dsi_id, unsigned lane_mask); void (*dsi_disable_pads)(int dsi_id, unsigned lane_mask); int (*set_min_bus_tput)(struct device *dev, unsigned long r); -- cgit v0.10.2 From c6ca5b2201289995f70ee19c0eaf4b5f2ae09923 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Thu, 14 Mar 2013 15:47:29 +0200 Subject: OMAPDSS: only probe pdata if there's one omapdss output drivers always read the platform data. This crashes when there's no platform data when using DT. Add a check to read the platform data only if it exists. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 757b57f..ef8fca2 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -706,13 +706,17 @@ static int omap_dpi_probe(struct platform_device *pdev) dpi_init_output(pdev); - r = dpi_probe_pdata(pdev); - if (r) { - dpi_uninit_output(pdev); - return r; + if (pdev->dev.platform_data) { + r = dpi_probe_pdata(pdev); + if (r) + goto err_probe; } return 0; + +err_probe: + dpi_uninit_output(pdev); + return r; } static int __exit omap_dpi_remove(struct platform_device *pdev) diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index a73dedc..bdddd0d 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -5563,12 +5563,10 @@ static int omap_dsihw_probe(struct platform_device *dsidev) dsi_init_output(dsidev); - r = dsi_probe_pdata(dsidev); - if (r) { - dsi_runtime_put(dsidev); - dsi_uninit_output(dsidev); - pm_runtime_disable(&dsidev->dev); - return r; + if (dsidev->dev.platform_data) { + r = dsi_probe_pdata(dsidev); + if (r) + goto err_probe; } dsi_runtime_put(dsidev); @@ -5586,6 +5584,9 @@ static int omap_dsihw_probe(struct platform_device *dsidev) #endif return 0; +err_probe: + dsi_runtime_put(dsidev); + dsi_uninit_output(dsidev); err_runtime_get: pm_runtime_disable(&dsidev->dev); return r; diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index a109934..fe72746 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -1094,15 +1094,19 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev) dss_debugfs_create_file("hdmi", hdmi_dump_regs); - r = hdmi_probe_pdata(pdev); - if (r) { - hdmi_panel_exit(); - hdmi_uninit_output(pdev); - pm_runtime_disable(&pdev->dev); - return r; + if (pdev->dev.platform_data) { + r = hdmi_probe_pdata(pdev); + if (r) + goto err_probe; } return 0; + +err_probe: + hdmi_panel_exit(); + hdmi_uninit_output(pdev); + pm_runtime_disable(&pdev->dev); + return r; } static int __exit hdmi_remove_child(struct device *dev, void *data) diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c index 1a17dd1..1ff221e 100644 --- a/drivers/video/omap2/dss/rfbi.c +++ b/drivers/video/omap2/dss/rfbi.c @@ -1093,15 +1093,16 @@ static int omap_rfbihw_probe(struct platform_device *pdev) rfbi_init_output(pdev); - r = rfbi_probe_pdata(pdev); - if (r) { - rfbi_uninit_output(pdev); - pm_runtime_disable(&pdev->dev); - return r; + if (pdev->dev.platform_data) { + r = rfbi_probe_pdata(pdev); + if (r) + goto err_probe; } return 0; +err_probe: + rfbi_uninit_output(pdev); err_runtime_get: pm_runtime_disable(&pdev->dev); return r; diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 0bcd302..6277c05 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -365,13 +365,17 @@ static int omap_sdi_probe(struct platform_device *pdev) sdi_init_output(pdev); - r = sdi_probe_pdata(pdev); - if (r) { - sdi_uninit_output(pdev); - return r; + if (pdev->dev.platform_data) { + r = sdi_probe_pdata(pdev); + if (r) + goto err_probe; } return 0; + +err_probe: + sdi_uninit_output(pdev); + return r; } static int __exit omap_sdi_remove(struct platform_device *pdev) diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 74fdb3e..7b2e3ae 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -866,16 +866,17 @@ static int omap_venchw_probe(struct platform_device *pdev) venc_init_output(pdev); - r = venc_probe_pdata(pdev); - if (r) { - venc_panel_exit(); - venc_uninit_output(pdev); - pm_runtime_disable(&pdev->dev); - return r; + if (pdev->dev.platform_data) { + r = venc_probe_pdata(pdev); + if (r) + goto err_probe; } return 0; +err_probe: + venc_panel_exit(); + venc_uninit_output(pdev); err_panel_init: err_runtime_get: pm_runtime_disable(&pdev->dev); -- cgit v0.10.2 From 805cc2d19cce6bbd25fcefa24de7259508729e8a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 13 Mar 2013 13:56:42 +0200 Subject: OMAPDSS: add omap_dss_find_output() Add a support function to find a DSS output by given name. This is used in later patches to link the panels to DSS outputs. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c index 5214df6..3274628 100644 --- a/drivers/video/omap2/dss/output.c +++ b/drivers/video/omap2/dss/output.c @@ -115,6 +115,19 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id) } EXPORT_SYMBOL(omap_dss_get_output); +struct omap_dss_output *omap_dss_find_output(const char *name) +{ + struct omap_dss_output *out; + + list_for_each_entry(out, &output_list, list) { + if (strcmp(out->name, name) == 0) + return out; + } + + return NULL; +} +EXPORT_SYMBOL(omap_dss_find_output); + static const struct dss_mgr_ops *dss_mgr_ops; int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 6462f68..0b4f718 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -780,6 +780,7 @@ int omap_dss_get_num_overlays(void); struct omap_overlay *omap_dss_get_overlay(int num); struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id); +struct omap_dss_output *omap_dss_find_output(const char *name); int omapdss_output_set_device(struct omap_dss_output *out, struct omap_dss_device *dssdev); int omapdss_output_unset_device(struct omap_dss_output *out); -- cgit v0.10.2 From 12ca755ba1c8714175f55ac069d8b51d9448778c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 13 Mar 2013 14:22:30 +0200 Subject: OMAPDSS: add omap_dss_find_output_by_node() Add a support function to find a DSS output by given DT node. This is used in later patches to link the panels to DSS outputs. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c index 3274628..4d01001 100644 --- a/drivers/video/omap2/dss/output.c +++ b/drivers/video/omap2/dss/output.c @@ -128,6 +128,19 @@ struct omap_dss_output *omap_dss_find_output(const char *name) } EXPORT_SYMBOL(omap_dss_find_output); +struct omap_dss_output *omap_dss_find_output_by_node(struct device_node *node) +{ + struct omap_dss_output *out; + + list_for_each_entry(out, &output_list, list) { + if (out->pdev->dev.of_node == node) + return out; + } + + return NULL; +} +EXPORT_SYMBOL(omap_dss_find_output_by_node); + static const struct dss_mgr_ops *dss_mgr_ops; int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 0b4f718..25a944e 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -781,6 +781,7 @@ struct omap_overlay *omap_dss_get_overlay(int num); struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id); struct omap_dss_output *omap_dss_find_output(const char *name); +struct omap_dss_output *omap_dss_find_output_by_node(struct device_node *node); int omapdss_output_set_device(struct omap_dss_output *out, struct omap_dss_device *dssdev); int omapdss_output_unset_device(struct omap_dss_output *out); -- cgit v0.10.2 From 679852dbee81c81c1165fe08b6cefd28252b463c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Mon, 10 Dec 2012 13:52:55 +0200 Subject: OMAPDSS: fix dss_get_ctx_loss_count for DT When using DT, dss device does not have platform data. However, dss_get_ctx_loss_count() uses dss device's platform data to find the get_ctx_loss_count function pointer. To fix this, dss_get_ctx_loss_count() needs to be changed to get the platform data from the omapdss device, which is a "virtual" device and always has platform data. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c index 94f66f9..bd01608 100644 --- a/drivers/video/omap2/dss/dss.c +++ b/drivers/video/omap2/dss/dss.c @@ -157,7 +157,8 @@ static void dss_restore_context(void) int dss_get_ctx_loss_count(void) { - struct omap_dss_board_info *board_data = dss.pdev->dev.platform_data; + struct platform_device *core_pdev = dss_get_core_pdev(); + struct omap_dss_board_info *board_data = core_pdev->dev.platform_data; int cnt; if (!board_data->get_context_loss_count) -- cgit v0.10.2 From e724366498ead17579686f7ad83235f911a9c4f7 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 23 Apr 2013 15:23:42 +0300 Subject: OMAPDSS: clean up dss_[ovl|mgr]_get_device() Minor cleanup for the dss_[ovl|mgr]_get_device() functions to make them more readable. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index a4b356a..b84bd99 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -420,16 +420,14 @@ static void wait_pending_extra_info_updates(void) DSSWARN("timeout in wait_pending_extra_info_updates\n"); } -static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl) +static struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr) { - return ovl->manager ? - (ovl->manager->output ? ovl->manager->output->device : NULL) : - NULL; + return mgr->output ? mgr->output->device : NULL; } -static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr) +static struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl) { - return mgr->output ? mgr->output->device : NULL; + return ovl->manager ? dss_mgr_get_device(ovl->manager) : NULL; } static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) -- cgit v0.10.2 From be8e8e1c62678765868c0bc7b8b5209c38af105c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 23 Apr 2013 15:35:35 +0300 Subject: OMAPDSS: add helpers to get mgr or output from display Add two helper functions that can be used to find either the DSS output or the overlay manager that is connected to the given display. This hides how the output and the manager are actually connected, making it easier to change the connections in the future. Signed-off-by: Tomi Valkeinen diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index 826586f..b3577cb 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -247,6 +247,9 @@ static int omap_modeset_init(struct drm_device *dev) struct drm_encoder *encoder = priv->encoders[i]; struct omap_dss_device *dssdev = omap_encoder_get_dssdev(encoder); + struct omap_dss_output *output; + + output = omapdss_find_output_from_display(dssdev); /* figure out which crtc's we can connect the encoder to: */ encoder->possible_crtcs = 0; @@ -259,7 +262,7 @@ static int omap_modeset_init(struct drm_device *dev) supported_outputs = dss_feat_get_supported_outputs(crtc_channel); - if (supported_outputs & dssdev->output->id) + if (supported_outputs & output->id) encoder->possible_crtcs |= (1 << id); } } diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c index 9a2fb59..5104681 100644 --- a/drivers/video/omap2/dss/manager-sysfs.c +++ b/drivers/video/omap2/dss/manager-sysfs.c @@ -78,7 +78,9 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, } if (dssdev) { - struct omap_dss_output *out = dssdev->output; + struct omap_dss_output *out; + + out = omapdss_find_output_from_display(dssdev); /* * a registered device should have an output connected to it diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c index 4d01001..ab2c0f0 100644 --- a/drivers/video/omap2/dss/output.c +++ b/drivers/video/omap2/dss/output.c @@ -141,6 +141,25 @@ struct omap_dss_output *omap_dss_find_output_by_node(struct device_node *node) } EXPORT_SYMBOL(omap_dss_find_output_by_node); +struct omap_dss_output *omapdss_find_output_from_display(struct omap_dss_device *dssdev) +{ + return dssdev->output; +} +EXPORT_SYMBOL(omapdss_find_output_from_display); + +struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev) +{ + struct omap_dss_output *out; + + out = omapdss_find_output_from_display(dssdev); + + if (out == NULL) + return NULL; + + return out->manager; +} +EXPORT_SYMBOL(omapdss_find_mgr_from_display); + static const struct dss_mgr_ops *dss_mgr_ops; int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops) diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c index d30b45d..146b6f5 100644 --- a/drivers/video/omap2/omapfb/omapfb-ioctl.c +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c @@ -770,12 +770,17 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) case OMAPFB_WAITFORVSYNC: DBG("ioctl WAITFORVSYNC\n"); - if (!display || !display->output || !display->output->manager) { + + if (!display) { r = -EINVAL; break; } - mgr = display->output->manager; + mgr = omapdss_find_mgr_from_display(display); + if (!mgr) { + r = -EINVAL; + break; + } r = mgr->wait_for_vsync(mgr); break; diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index 856917b..cc8953c 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -2363,18 +2363,16 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev, int i, r; struct omap_overlay_manager *mgr; - if (!def_dssdev->output) { - dev_err(fbdev->dev, "no output for the default display\n"); - return -EINVAL; - } - for (i = 0; i < fbdev->num_displays; ++i) { struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; - struct omap_dss_output *out = dssdev->output; + struct omap_dss_output *out; - mgr = omap_dss_get_overlay_manager(out->dispc_channel); + out = omapdss_find_output_from_display(dssdev); + if (!out) + continue; - if (!mgr || !out) + mgr = omap_dss_get_overlay_manager(out->dispc_channel); + if (!mgr) continue; if (mgr->output) @@ -2383,7 +2381,7 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev, mgr->set_output(mgr, out); } - mgr = def_dssdev->output->manager; + mgr = omapdss_find_mgr_from_display(def_dssdev); if (!mgr) { dev_err(fbdev->dev, "no ovl manager for the default display\n"); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 25a944e..898f812 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -786,6 +786,9 @@ int omapdss_output_set_device(struct omap_dss_output *out, struct omap_dss_device *dssdev); int omapdss_output_unset_device(struct omap_dss_output *out); +struct omap_dss_output *omapdss_find_output_from_display(struct omap_dss_device *dssdev); +struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev); + void omapdss_default_get_resolution(struct omap_dss_device *dssdev, u16 *xres, u16 *yres); int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev); -- cgit v0.10.2 From 7f7cdbd6883fd58cfc4e538d451b455ca849bd63 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 14 May 2013 10:53:21 +0300 Subject: OMAPDSS: split overlay manager creation Split the function that creates overlay manager structs into two: one that creates just the structs, and one that creates the sysfs files for the manager. This will help us use the overlay manager structs with omapdrm in the following patches, while still leaving the sysfs files out. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index b84bd99..74d1d00 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -1577,7 +1577,8 @@ int omapdss_compat_init(void) apply_init_priv(); - dss_init_overlay_managers(pdev); + dss_init_overlay_managers(); + dss_init_overlay_managers_sysfs(pdev); dss_init_overlays(pdev); for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) { @@ -1640,7 +1641,8 @@ err_disp_sysfs: dss_uninstall_mgr_ops(); err_mgr_ops: - dss_uninit_overlay_managers(pdev); + dss_uninit_overlay_managers_sysfs(pdev); + dss_uninit_overlay_managers(); dss_uninit_overlays(pdev); compat_refcnt--; @@ -1668,7 +1670,8 @@ void omapdss_compat_uninit(void) dss_uninstall_mgr_ops(); - dss_uninit_overlay_managers(pdev); + dss_uninit_overlay_managers_sysfs(pdev); + dss_uninit_overlay_managers(); dss_uninit_overlays(pdev); out: mutex_unlock(&compat_init_lock); diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h index 8475893..7964d3b 100644 --- a/drivers/video/omap2/dss/dss.h +++ b/drivers/video/omap2/dss/dss.h @@ -194,8 +194,10 @@ void display_uninit_sysfs(struct platform_device *pdev, struct omap_dss_device *dssdev); /* manager */ -int dss_init_overlay_managers(struct platform_device *pdev); -void dss_uninit_overlay_managers(struct platform_device *pdev); +int dss_init_overlay_managers(void); +void dss_uninit_overlay_managers(void); +int dss_init_overlay_managers_sysfs(struct platform_device *pdev); +void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev); int dss_mgr_simple_check(struct omap_overlay_manager *mgr, const struct omap_overlay_manager_info *info); int dss_mgr_check_timings(struct omap_overlay_manager *mgr, diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c index 5104681..72784b3 100644 --- a/drivers/video/omap2/dss/manager-sysfs.c +++ b/drivers/video/omap2/dss/manager-sysfs.c @@ -511,4 +511,6 @@ void dss_manager_kobj_uninit(struct omap_overlay_manager *mgr) { kobject_del(&mgr->kobj); kobject_put(&mgr->kobj); + + memset(&mgr->kobj, 0, sizeof(mgr->kobj)); } diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c index 2551eaa..1aac9b4 100644 --- a/drivers/video/omap2/dss/manager.c +++ b/drivers/video/omap2/dss/manager.c @@ -36,9 +36,9 @@ static int num_managers; static struct omap_overlay_manager *managers; -int dss_init_overlay_managers(struct platform_device *pdev) +int dss_init_overlay_managers(void) { - int i, r; + int i; num_managers = dss_feat_get_num_mgrs(); @@ -76,6 +76,17 @@ int dss_init_overlay_managers(struct platform_device *pdev) dss_feat_get_supported_outputs(mgr->id); INIT_LIST_HEAD(&mgr->overlays); + } + + return 0; +} + +int dss_init_overlay_managers_sysfs(struct platform_device *pdev) +{ + int i, r; + + for (i = 0; i < num_managers; ++i) { + struct omap_overlay_manager *mgr = &managers[i]; r = dss_manager_kobj_init(mgr, pdev); if (r) @@ -85,18 +96,22 @@ int dss_init_overlay_managers(struct platform_device *pdev) return 0; } -void dss_uninit_overlay_managers(struct platform_device *pdev) +void dss_uninit_overlay_managers(void) +{ + kfree(managers); + managers = NULL; + num_managers = 0; +} + +void dss_uninit_overlay_managers_sysfs(struct platform_device *pdev) { int i; for (i = 0; i < num_managers; ++i) { struct omap_overlay_manager *mgr = &managers[i]; + dss_manager_kobj_uninit(mgr); } - - kfree(managers); - managers = NULL; - num_managers = 0; } int omap_dss_get_num_overlay_managers(void) -- cgit v0.10.2 From 04b1fc0291674666110fffd09b30d8304aaa4602 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 14 May 2013 10:55:19 +0300 Subject: OMAPDRM: fix overlay manager handling Currently omapdrm creates crtcs, which map directly to DSS overlay managers, only on demand at init time. This would make it difficult to manage connecting the display entities in the future, as the code cannot just search for a suitable overlay manager. We cannot fix this the sane way, which would be to create crtcs for each overlay manager, because we need an overlay for each crtc. With limited number of overlays, that's not possible. So the solution for now is to detach the overlay manager from the crtc. crtcs are still created on demand at init time, but all overlay managers are always initialized by the omapdss. This way we can create and connect whole display pipelines from the overlay manager to the display, regardless of which crtcs omapdrm would create. Signed-off-by: Tomi Valkeinen diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 79b200a..02075bf 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -40,7 +40,7 @@ struct omap_crtc { * mgr->id.) Eventually this will be replaced w/ something * more common-panel-framework-y */ - struct omap_overlay_manager mgr; + struct omap_overlay_manager *mgr; struct omap_video_timings timings; bool enabled; @@ -90,6 +90,9 @@ uint32_t pipe2vbl(struct drm_crtc *crtc) * job of sequencing the setup of the video pipe in the proper order */ +/* ovl-mgr-id -> crtc */ +static struct omap_crtc *omap_crtcs[8]; + /* we can probably ignore these until we support command-mode panels: */ static void omap_crtc_start_update(struct omap_overlay_manager *mgr) { @@ -107,7 +110,7 @@ static void omap_crtc_disable(struct omap_overlay_manager *mgr) static void omap_crtc_set_timings(struct omap_overlay_manager *mgr, const struct omap_video_timings *timings) { - struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); + struct omap_crtc *omap_crtc = omap_crtcs[mgr->id]; DBG("%s", omap_crtc->name); omap_crtc->timings = *timings; omap_crtc->full_update = true; @@ -116,7 +119,7 @@ static void omap_crtc_set_timings(struct omap_overlay_manager *mgr, static void omap_crtc_set_lcd_config(struct omap_overlay_manager *mgr, const struct dss_lcd_mgr_config *config) { - struct omap_crtc *omap_crtc = container_of(mgr, struct omap_crtc, mgr); + struct omap_crtc *omap_crtc = omap_crtcs[mgr->id]; DBG("%s", omap_crtc->name); dispc_mgr_set_lcd_config(omap_crtc->channel, config); } @@ -569,7 +572,7 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply) } else { if (encoder) { omap_encoder_set_enabled(encoder, false); - omap_encoder_update(encoder, &omap_crtc->mgr, + omap_encoder_update(encoder, omap_crtc->mgr, &omap_crtc->timings); omap_encoder_set_enabled(encoder, true); omap_crtc->full_update = false; @@ -595,6 +598,11 @@ static const char *channel_names[] = { [OMAP_DSS_CHANNEL_LCD2] = "lcd2", }; +void omap_crtc_pre_init(void) +{ + dss_install_mgr_ops(&mgr_ops); +} + /* initialize crtc */ struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct drm_plane *plane, enum omap_channel channel, int id) @@ -635,9 +643,7 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_irq_register(dev, &omap_crtc->error_irq); /* temporary: */ - omap_crtc->mgr.id = channel; - - dss_install_mgr_ops(&mgr_ops); + omap_crtc->mgr = omap_dss_get_overlay_manager(channel); /* TODO: fix hard-coded setup.. add properties! */ info = &omap_crtc->info; @@ -651,6 +657,8 @@ struct drm_crtc *omap_crtc_init(struct drm_device *dev, omap_plane_install_properties(omap_crtc->plane, &crtc->base); + omap_crtcs[channel] = omap_crtc; + return crtc; fail: diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index b3577cb..ff9b492 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -98,6 +98,8 @@ static int omap_modeset_init(struct drm_device *dev) int num_crtcs; int i, id = 0; + omap_crtc_pre_init(); + drm_mode_config_init(dev); omap_drm_irq_install(dev); diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h index 215a20d..14f17da 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.h +++ b/drivers/gpu/drm/omapdrm/omap_drv.h @@ -157,6 +157,7 @@ const struct omap_video_timings *omap_crtc_timings(struct drm_crtc *crtc); enum omap_channel omap_crtc_channel(struct drm_crtc *crtc); int omap_crtc_apply(struct drm_crtc *crtc, struct omap_drm_apply *apply); +void omap_crtc_pre_init(void); struct drm_crtc *omap_crtc_init(struct drm_device *dev, struct drm_plane *plane, enum omap_channel channel, int id); diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index 74d1d00..c844071 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -1577,7 +1577,6 @@ int omapdss_compat_init(void) apply_init_priv(); - dss_init_overlay_managers(); dss_init_overlay_managers_sysfs(pdev); dss_init_overlays(pdev); @@ -1642,7 +1641,6 @@ err_disp_sysfs: err_mgr_ops: dss_uninit_overlay_managers_sysfs(pdev); - dss_uninit_overlay_managers(); dss_uninit_overlays(pdev); compat_refcnt--; @@ -1671,7 +1669,6 @@ void omapdss_compat_uninit(void) dss_uninstall_mgr_ops(); dss_uninit_overlay_managers_sysfs(pdev); - dss_uninit_overlay_managers(); dss_uninit_overlays(pdev); out: mutex_unlock(&compat_init_lock); diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c index b33b016..83d7bb9 100644 --- a/drivers/video/omap2/dss/dispc.c +++ b/drivers/video/omap2/dss/dispc.c @@ -3710,6 +3710,8 @@ static int __init omap_dispchw_probe(struct platform_device *pdev) dispc_runtime_put(); + dss_init_overlay_managers(); + dss_debugfs_create_file("dispc", dispc_dump_regs); return 0; @@ -3723,6 +3725,8 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev) { pm_runtime_disable(&pdev->dev); + dss_uninit_overlay_managers(); + return 0; } -- cgit v0.10.2 From a7e71e7f9fc7924921081aa55ceafca00d2c9f49 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Wed, 8 May 2013 16:23:32 +0300 Subject: OMAPDSS: Implement display (dis)connect support We currently have two steps in panel initialization and startup: probing and enabling. After the panel has been probed, it's ready and can be configured and later enabled. This model is not enough with more complex display pipelines, where we may have, for example, two panels, of which only one can be used at a time, connected to the same video output. To support that kind of scenarios, we need to add new step to the initialization: connect. This patch adds support for connecting and disconnecting panels. After probe, but before connect, no panel ops should be called. When the connect is called, a proper video pipeline is established, and the panel is ready for use. If some part in the video pipeline is already connected (by some other panel), the connect call fails. One key difference with the old style setup is that connect() handles also connecting to the overlay manager. This means that the omapfb (or omapdrm) no longer needs to figure out which overlay manager to use, but it can just call connect() on the panel, and the proper overlay manager is connected by omapdss. This also allows us to add back the support for dynamic switching between two exclusive panels. However, the current panel device model is not changed to support this, as the new device model is implemented in the following patches and the old model will be removed. The new device model supports dynamic switching. Signed-off-by: Tomi Valkeinen diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c index 02075bf..b2ab2f5 100644 --- a/drivers/gpu/drm/omapdrm/omap_crtc.c +++ b/drivers/gpu/drm/omapdrm/omap_crtc.c @@ -94,6 +94,28 @@ uint32_t pipe2vbl(struct drm_crtc *crtc) static struct omap_crtc *omap_crtcs[8]; /* we can probably ignore these until we support command-mode panels: */ +static int omap_crtc_connect(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst) +{ + if (mgr->output) + return -EINVAL; + + if ((mgr->supported_outputs & dst->id) == 0) + return -EINVAL; + + dst->manager = mgr; + mgr->output = dst; + + return 0; +} + +static void omap_crtc_disconnect(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst) +{ + mgr->output->manager = NULL; + mgr->output = NULL; +} + static void omap_crtc_start_update(struct omap_overlay_manager *mgr) { } @@ -138,6 +160,8 @@ static void omap_crtc_unregister_framedone_handler( } static const struct dss_mgr_ops mgr_ops = { + .connect = omap_crtc_connect, + .disconnect = omap_crtc_disconnect, .start_update = omap_crtc_start_update, .enable = omap_crtc_enable, .disable = omap_crtc_disable, diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c index ff9b492..c65dd0d6 100644 --- a/drivers/gpu/drm/omapdrm/omap_drv.c +++ b/drivers/gpu/drm/omapdrm/omap_drv.c @@ -97,6 +97,7 @@ static int omap_modeset_init(struct drm_device *dev) int num_mgrs = dss_feat_get_num_mgrs(); int num_crtcs; int i, id = 0; + int r; omap_crtc_pre_init(); @@ -118,6 +119,7 @@ static int omap_modeset_init(struct drm_device *dev) struct drm_connector *connector; struct drm_encoder *encoder; enum omap_channel channel; + struct omap_overlay_manager *mgr; if (!dssdev->driver) { dev_warn(dev->dev, "%s has no driver.. skipping it\n", @@ -133,6 +135,13 @@ static int omap_modeset_init(struct drm_device *dev) continue; } + r = dssdev->driver->connect(dssdev); + if (r) { + dev_err(dev->dev, "could not connect display: %s\n", + dssdev->name); + continue; + } + encoder = omap_encoder_init(dev, dssdev); if (!encoder) { @@ -174,8 +183,9 @@ static int omap_modeset_init(struct drm_device *dev) * other possible channels to which the encoder can connect are * not considered. */ - channel = dssdev->output->dispc_channel; + mgr = omapdss_find_mgr_from_display(dssdev); + channel = mgr->id; /* * if this channel hasn't already been taken by a previously * allocated crtc, we create a new crtc for it diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c index c844071..dbd3c2f 100644 --- a/drivers/video/omap2/dss/apply.c +++ b/drivers/video/omap2/dss/apply.c @@ -790,6 +790,18 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr) } } +static int dss_mgr_connect_compat(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst) +{ + return mgr->set_output(mgr, dst); +} + +static void dss_mgr_disconnect_compat(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst) +{ + mgr->unset_output(mgr); +} + static void dss_mgr_start_update_compat(struct omap_overlay_manager *mgr) { struct mgr_priv_data *mp = get_mgr_priv(mgr); @@ -1552,6 +1564,8 @@ static void dss_mgr_unregister_framedone_handler_compat(struct omap_overlay_mana } static const struct dss_mgr_ops apply_mgr_ops = { + .connect = dss_mgr_connect_compat, + .disconnect = dss_mgr_disconnect_compat, .start_update = dss_mgr_start_update_compat, .enable = dss_mgr_enable_compat, .disable = dss_mgr_disable_compat, diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 710e9f9..831abec 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -379,6 +379,46 @@ static int dss_driver_remove(struct device *dev) return 0; } +static int omapdss_default_connect(struct omap_dss_device *dssdev) +{ + struct omap_dss_output *out; + struct omap_overlay_manager *mgr; + int r; + + out = dssdev->output; + + if (out == NULL) + return -ENODEV; + + mgr = omap_dss_get_overlay_manager(out->dispc_channel); + if (!mgr) + return -ENODEV; + + r = dss_mgr_connect(mgr, out); + if (r) + return r; + + return 0; +} + +static void omapdss_default_disconnect(struct omap_dss_device *dssdev) +{ + struct omap_dss_output *out; + struct omap_overlay_manager *mgr; + + out = dssdev->output; + + if (out == NULL) + return; + + mgr = out->manager; + + if (mgr == NULL) + return; + + dss_mgr_disconnect(mgr, out); +} + int omap_dss_register_driver(struct omap_dss_driver *dssdriver) { dssdriver->driver.bus = &dss_bus_type; @@ -392,6 +432,10 @@ int omap_dss_register_driver(struct omap_dss_driver *dssdriver) omapdss_default_get_recommended_bpp; if (dssdriver->get_timings == NULL) dssdriver->get_timings = omapdss_default_get_timings; + if (dssdriver->connect == NULL) + dssdriver->connect = omapdss_default_connect; + if (dssdriver->disconnect == NULL) + dssdriver->disconnect = omapdss_default_disconnect; return driver_register(&dssdriver->driver); } diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/omap2/dss/display-sysfs.c index 18211a9..81d5dc6 100644 --- a/drivers/video/omap2/dss/display-sysfs.c +++ b/drivers/video/omap2/dss/display-sysfs.c @@ -33,9 +33,9 @@ static ssize_t display_enabled_show(struct device *dev, struct device_attribute *attr, char *buf) { struct omap_dss_device *dssdev = to_dss_device(dev); - bool enabled = dssdev->state != OMAP_DSS_DISPLAY_DISABLED; - return snprintf(buf, PAGE_SIZE, "%d\n", enabled); + return snprintf(buf, PAGE_SIZE, "%d\n", + omapdss_device_is_enabled(dssdev)); } static ssize_t display_enabled_store(struct device *dev, @@ -44,20 +44,24 @@ static ssize_t display_enabled_store(struct device *dev, { struct omap_dss_device *dssdev = to_dss_device(dev); int r; - bool enabled; + bool enable; - r = strtobool(buf, &enabled); + r = strtobool(buf, &enable); if (r) return r; - if (enabled != (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)) { - if (enabled) { - r = dssdev->driver->enable(dssdev); - if (r) - return r; - } else { - dssdev->driver->disable(dssdev); - } + if (enable == omapdss_device_is_enabled(dssdev)) + return size; + + if (omapdss_device_is_connected(dssdev) == false) + return -ENODEV; + + if (enable) { + r = dssdev->driver->enable(dssdev); + if (r) + return r; + } else { + dssdev->driver->disable(dssdev); } return size; diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c index 72784b3..de7e7b5 100644 --- a/drivers/video/omap2/dss/manager-sysfs.c +++ b/drivers/video/omap2/dss/manager-sysfs.c @@ -50,6 +50,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, int r = 0; size_t len = size; struct omap_dss_device *dssdev = NULL; + struct omap_dss_device *old_dssdev; int match(struct omap_dss_device *dssdev, void *data) { @@ -66,34 +67,44 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, if (len > 0 && dssdev == NULL) return -EINVAL; - if (dssdev) + if (dssdev) { DSSDBG("display %s found\n", dssdev->name); - if (mgr->output) { - r = mgr->unset_output(mgr); - if (r) { - DSSERR("failed to unset current output\n"); + if (omapdss_device_is_connected(dssdev)) { + DSSERR("new display is already connected\n"); + r = -EINVAL; + goto put_device; + } + + if (omapdss_device_is_enabled(dssdev)) { + DSSERR("new display is not disabled\n"); + r = -EINVAL; goto put_device; } } - if (dssdev) { - struct omap_dss_output *out; + old_dssdev = mgr->get_device(mgr); + if (old_dssdev) { + if (omapdss_device_is_enabled(old_dssdev)) { + DSSERR("old display is not disabled\n"); + r = -EINVAL; + goto put_device; + } - out = omapdss_find_output_from_display(dssdev); + old_dssdev->driver->disconnect(old_dssdev); + } - /* - * a registered device should have an output connected to it - * already - */ - if (!out) { - DSSERR("device has no output connected to it\n"); + if (dssdev) { + r = dssdev->driver->connect(dssdev); + if (r) { + DSSERR("failed to connect new device\n"); goto put_device; } - r = mgr->set_output(mgr, out); - if (r) { - DSSERR("failed to set manager output\n"); + old_dssdev = mgr->get_device(mgr); + if (old_dssdev != dssdev) { + DSSERR("failed to connect device to this manager\n"); + dssdev->driver->disconnect(dssdev); goto put_device; } diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c index ab2c0f0..a53b08b 100644 --- a/drivers/video/omap2/dss/output.c +++ b/drivers/video/omap2/dss/output.c @@ -179,6 +179,20 @@ void dss_uninstall_mgr_ops(void) } EXPORT_SYMBOL(dss_uninstall_mgr_ops); +int dss_mgr_connect(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst) +{ + return dss_mgr_ops->connect(mgr, dst); +} +EXPORT_SYMBOL(dss_mgr_connect); + +void dss_mgr_disconnect(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst) +{ + dss_mgr_ops->disconnect(mgr, dst); +} +EXPORT_SYMBOL(dss_mgr_disconnect); + void dss_mgr_set_timings(struct omap_overlay_manager *mgr, const struct omap_video_timings *timings) { diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c index cc8953c..528e453 100644 --- a/drivers/video/omap2/omapfb/omapfb-main.c +++ b/drivers/video/omap2/omapfb/omapfb-main.c @@ -1853,6 +1853,8 @@ static void omapfb_free_resources(struct omapfb2_device *fbdev) if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED) dssdev->driver->disable(dssdev); + dssdev->driver->disconnect(dssdev); + omap_dss_put_device(dssdev); } @@ -2363,22 +2365,23 @@ static int omapfb_init_connections(struct omapfb2_device *fbdev, int i, r; struct omap_overlay_manager *mgr; + r = def_dssdev->driver->connect(def_dssdev); + if (r) { + dev_err(fbdev->dev, "failed to connect default display\n"); + return r; + } + for (i = 0; i < fbdev->num_displays; ++i) { struct omap_dss_device *dssdev = fbdev->displays[i].dssdev; - struct omap_dss_output *out; - out = omapdss_find_output_from_display(dssdev); - if (!out) + if (dssdev == def_dssdev) continue; - mgr = omap_dss_get_overlay_manager(out->dispc_channel); - if (!mgr) - continue; - - if (mgr->output) - mgr->unset_output(mgr); - - mgr->set_output(mgr, out); + /* + * We don't care if the connect succeeds or not. We just want to + * connect as many displays as possible. + */ + dssdev->driver->connect(dssdev); } mgr = omapdss_find_mgr_from_display(def_dssdev); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 898f812..4f52f52 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -689,6 +689,9 @@ struct omap_dss_driver { int (*probe)(struct omap_dss_device *); void (*remove)(struct omap_dss_device *); + int (*connect)(struct omap_dss_device *dssdev); + void (*disconnect)(struct omap_dss_device *dssdev); + int (*enable)(struct omap_dss_device *display); void (*disable)(struct omap_dss_device *display); int (*run_test)(struct omap_dss_device *display, int test); @@ -889,6 +892,11 @@ int omapdss_compat_init(void); void omapdss_compat_uninit(void); struct dss_mgr_ops { + int (*connect)(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst); + void (*disconnect)(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst); + void (*start_update)(struct omap_overlay_manager *mgr); int (*enable)(struct omap_overlay_manager *mgr); void (*disable)(struct omap_overlay_manager *mgr); @@ -905,6 +913,10 @@ struct dss_mgr_ops { int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops); void dss_uninstall_mgr_ops(void); +int dss_mgr_connect(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst); +void dss_mgr_disconnect(struct omap_overlay_manager *mgr, + struct omap_dss_output *dst); void dss_mgr_set_timings(struct omap_overlay_manager *mgr, const struct omap_video_timings *timings); void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, @@ -916,4 +928,15 @@ int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr, void (*handler)(void *), void *data); void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr, void (*handler)(void *), void *data); + +static inline bool omapdss_device_is_connected(struct omap_dss_device *dssdev) +{ + return dssdev->output; +} + +static inline bool omapdss_device_is_enabled(struct omap_dss_device *dssdev) +{ + return dssdev->state == OMAP_DSS_DISPLAY_ACTIVE; +} + #endif -- cgit v0.10.2 From 51930bba8e9a19401247a4147daa828851d400ce Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 3 May 2013 13:35:07 +0300 Subject: OMAPDSS: CORE: use devm_regulator_get Use devm_regulator_get() instead of regulator_get() to simplify code. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c index 831abec..7b2df2f 100644 --- a/drivers/video/omap2/dss/core.c +++ b/drivers/video/omap2/dss/core.c @@ -88,7 +88,7 @@ struct regulator *dss_get_vdds_dsi(void) if (core.vdds_dsi_reg != NULL) return core.vdds_dsi_reg; - reg = regulator_get(&core.pdev->dev, "vdds_dsi"); + reg = devm_regulator_get(&core.pdev->dev, "vdds_dsi"); if (!IS_ERR(reg)) core.vdds_dsi_reg = reg; @@ -102,7 +102,7 @@ struct regulator *dss_get_vdds_sdi(void) if (core.vdds_sdi_reg != NULL) return core.vdds_sdi_reg; - reg = regulator_get(&core.pdev->dev, "vdds_sdi"); + reg = devm_regulator_get(&core.pdev->dev, "vdds_sdi"); if (!IS_ERR(reg)) core.vdds_sdi_reg = reg; @@ -664,16 +664,6 @@ static int __init omap_dss_init(void) static void __exit omap_dss_exit(void) { - if (core.vdds_dsi_reg != NULL) { - regulator_put(core.vdds_dsi_reg); - core.vdds_dsi_reg = NULL; - } - - if (core.vdds_sdi_reg != NULL) { - regulator_put(core.vdds_sdi_reg); - core.vdds_sdi_reg = NULL; - } - omap_dss_unregister_drivers(); omap_dss_bus_unregister(); -- cgit v0.10.2 From b2541c40aad3024cd6187f4f93af899654127ccc Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 3 May 2013 13:42:24 +0300 Subject: OMAPDSS: DSI: cleanup regulator init Separate the regulator initialization code to its own function, removing duplicate code. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c index bdddd0d..7d9e5cc 100644 --- a/drivers/video/omap2/dss/dsi.c +++ b/drivers/video/omap2/dss/dsi.c @@ -1114,6 +1114,30 @@ void dsi_runtime_put(struct platform_device *dsidev) WARN_ON(r < 0 && r != -ENOSYS); } +static int dsi_regulator_init(struct platform_device *dsidev) +{ + struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); + struct regulator *vdds_dsi; + + if (dsi->vdds_dsi_reg != NULL) + return 0; + + vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "vdds_dsi"); + + /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */ + if (IS_ERR(vdds_dsi)) + vdds_dsi = devm_regulator_get(&dsi->pdev->dev, "VCXIO"); + + if (IS_ERR(vdds_dsi)) { + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(vdds_dsi); + } + + dsi->vdds_dsi_reg = vdds_dsi; + + return 0; +} + /* source clock for DSI PLL. this could also be PCLKFREE */ static inline void dsi_enable_pll_clock(struct platform_device *dsidev, bool enable) @@ -1592,22 +1616,9 @@ int dsi_pll_init(struct platform_device *dsidev, bool enable_hsclk, */ enable_hsclk = enable_hsdiv = true; - if (dsi->vdds_dsi_reg == NULL) { - struct regulator *vdds_dsi; - - vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); - - /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */ - if (IS_ERR(vdds_dsi)) - vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO"); - - if (IS_ERR(vdds_dsi)) { - DSSERR("can't get VDDS_DSI regulator\n"); - return PTR_ERR(vdds_dsi); - } - - dsi->vdds_dsi_reg = vdds_dsi; - } + r = dsi_regulator_init(dsidev); + if (r) + return r; dsi_enable_pll_clock(dsidev, 1); /* @@ -5225,34 +5236,6 @@ static enum omap_channel dsi_get_channel(int module_id) } } -static int dsi_init_display(struct omap_dss_device *dssdev) -{ - struct platform_device *dsidev = - dsi_get_dsidev_from_id(dssdev->phy.dsi.module); - struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev); - - DSSDBG("DSI init\n"); - - if (dsi->vdds_dsi_reg == NULL) { - struct regulator *vdds_dsi; - - vdds_dsi = regulator_get(&dsi->pdev->dev, "vdds_dsi"); - - /* DT HACK: try VCXIO to make omapdss work for o4 sdp/panda */ - if (IS_ERR(vdds_dsi)) - vdds_dsi = regulator_get(&dsi->pdev->dev, "VCXIO"); - - if (IS_ERR(vdds_dsi)) { - DSSERR("can't get VDDS_DSI regulator\n"); - return PTR_ERR(vdds_dsi); - } - - dsi->vdds_dsi_reg = vdds_dsi; - } - - return 0; -} - int omap_dsi_request_vc(struct omap_dss_device *dssdev, int *channel) { struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev); @@ -5410,19 +5393,16 @@ static int dsi_probe_pdata(struct platform_device *dsidev) if (!plat_dssdev) return 0; + r = dsi_regulator_init(dsidev); + if (r) + return r; + dssdev = dss_alloc_and_init_device(&dsidev->dev); if (!dssdev) return -ENOMEM; dss_copy_device_pdata(dssdev, plat_dssdev); - r = dsi_init_display(dssdev); - if (r) { - DSSERR("device %s init failed: %d\n", dssdev->name, r); - dss_put_device(dssdev); - return r; - } - r = omapdss_output_set_device(&dsi->output, dssdev); if (r) { DSSERR("failed to connect output to new device: %s\n", @@ -5604,14 +5584,9 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev) pm_runtime_disable(&dsidev->dev); - if (dsi->vdds_dsi_reg != NULL) { - if (dsi->vdds_dsi_enabled) { - regulator_disable(dsi->vdds_dsi_reg); - dsi->vdds_dsi_enabled = false; - } - - regulator_put(dsi->vdds_dsi_reg); - dsi->vdds_dsi_reg = NULL; + if (dsi->vdds_dsi_reg != NULL && dsi->vdds_dsi_enabled) { + regulator_disable(dsi->vdds_dsi_reg); + dsi->vdds_dsi_enabled = false; } return 0; -- cgit v0.10.2 From 2795f646a798767523a91c2b147c9774d0c3070f Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 19 Apr 2013 16:52:27 +0300 Subject: OMAPDSS: DPI: cleanup pll & regulator init Split regulator and DSI PLL init code to their own functions for clarity. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index ef8fca2..0aa396b 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -542,6 +542,47 @@ static int dpi_verify_dsi_pll(struct platform_device *dsidev) return 0; } +static int dpi_init_regulator(void) +{ + struct regulator *vdds_dsi; + + if (!dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) + return 0; + + if (dpi.vdds_dsi_reg) + return 0; + + vdds_dsi = dss_get_vdds_dsi(); + + if (IS_ERR(vdds_dsi)) { + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(vdds_dsi); + } + + dpi.vdds_dsi_reg = vdds_dsi; + + return 0; +} + +static void dpi_init_pll(void) +{ + struct platform_device *dsidev; + + if (dpi.dsidev) + return; + + dsidev = dpi_get_dsidev(dpi.output.dispc_channel); + if (!dsidev) + return; + + if (dpi_verify_dsi_pll(dsidev)) { + DSSWARN("DSI PLL not operational\n"); + return; + } + + dpi.dsidev = dsidev; +} + /* * Return a hardcoded channel for the DPI output. This should work for * current use cases, but this can be later expanded to either resolve @@ -572,41 +613,6 @@ static enum omap_channel dpi_get_channel(void) } } -static int dpi_init_display(struct omap_dss_device *dssdev) -{ - struct platform_device *dsidev; - - DSSDBG("init_display\n"); - - if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI) && - dpi.vdds_dsi_reg == NULL) { - struct regulator *vdds_dsi; - - vdds_dsi = dss_get_vdds_dsi(); - - if (IS_ERR(vdds_dsi)) { - DSSERR("can't get VDDS_DSI regulator\n"); - return PTR_ERR(vdds_dsi); - } - - dpi.vdds_dsi_reg = vdds_dsi; - } - - dsidev = dpi_get_dsidev(dpi.output.dispc_channel); - - if (dsidev && dpi_verify_dsi_pll(dsidev)) { - dsidev = NULL; - DSSWARN("DSI PLL not operational\n"); - } - - if (dsidev) - DSSDBG("using DSI PLL for DPI clock\n"); - - dpi.dsidev = dsidev; - - return 0; -} - static struct omap_dss_device *dpi_find_dssdev(struct platform_device *pdev) { struct omap_dss_board_info *pdata = pdev->dev.platform_data; @@ -646,19 +652,18 @@ static int dpi_probe_pdata(struct platform_device *dpidev) if (!plat_dssdev) return 0; + r = dpi_init_regulator(); + if (r) + return r; + + dpi_init_pll(); + dssdev = dss_alloc_and_init_device(&dpidev->dev); if (!dssdev) return -ENOMEM; dss_copy_device_pdata(dssdev, plat_dssdev); - r = dpi_init_display(dssdev); - if (r) { - DSSERR("device %s init failed: %d\n", dssdev->name, r); - dss_put_device(dssdev); - return r; - } - r = omapdss_output_set_device(&dpi.output, dssdev); if (r) { DSSERR("failed to connect output to new device: %s\n", -- cgit v0.10.2 From 00df43b8227dbb0100625b279ccbd66d4a03110c Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 19 Mar 2013 11:33:52 +0200 Subject: OMAPDSS: DPI: fix regulators for DT On some platforms DPI requires a regulator to be enabled to power up the output pins. This regulator is, for some reason, currently attached to the virtual omapdss device, instead of the DPI device. This does not work for DT, as the regulator mappings need to be described in the DT data, and the virtual omapdss device is not present there. Fix the issue by acquiring the regulator in the DPI device. To retain compatibility with the current board files, the old method of getting the regulator is kept. The old method can be removed when the board files have been changed to pass the regulator to DPI. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c index 0aa396b..aa653c46 100644 --- a/drivers/video/omap2/dss/dpi.c +++ b/drivers/video/omap2/dss/dpi.c @@ -37,6 +37,8 @@ #include "dss_features.h" static struct { + struct platform_device *pdev; + struct regulator *vdds_dsi_reg; struct platform_device *dsidev; @@ -555,8 +557,11 @@ static int dpi_init_regulator(void) vdds_dsi = dss_get_vdds_dsi(); if (IS_ERR(vdds_dsi)) { - DSSERR("can't get VDDS_DSI regulator\n"); - return PTR_ERR(vdds_dsi); + vdds_dsi = devm_regulator_get(&dpi.pdev->dev, "vdds_dsi"); + if (IS_ERR(vdds_dsi)) { + DSSERR("can't get VDDS_DSI regulator\n"); + return PTR_ERR(vdds_dsi); + } } dpi.vdds_dsi_reg = vdds_dsi; @@ -707,6 +712,8 @@ static int omap_dpi_probe(struct platform_device *pdev) { int r; + dpi.pdev = pdev; + mutex_init(&dpi.lock); dpi_init_output(pdev); -- cgit v0.10.2 From e25001d8be225b09a9a660f121892961bb58a09a Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 10 May 2013 15:20:52 +0300 Subject: OMAPDSS: HDMI: add hdmi_init_regulator Separate regulator init code into its own function for clarity. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c index fe72746..98341fe 100644 --- a/drivers/video/omap2/dss/hdmi.c +++ b/drivers/video/omap2/dss/hdmi.c @@ -328,6 +328,29 @@ static void hdmi_runtime_put(void) WARN_ON(r < 0 && r != -ENOSYS); } +static int hdmi_init_regulator(void) +{ + struct regulator *reg; + + if (hdmi.vdda_hdmi_dac_reg != NULL) + return 0; + + reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); + + /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */ + if (IS_ERR(reg)) + reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC"); + + if (IS_ERR(reg)) { + DSSERR("can't get VDDA_HDMI_DAC regulator\n"); + return PTR_ERR(reg); + } + + hdmi.vdda_hdmi_dac_reg = reg; + + return 0; +} + static int hdmi_init_display(struct omap_dss_device *dssdev) { int r; @@ -342,22 +365,9 @@ static int hdmi_init_display(struct omap_dss_device *dssdev) dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version()); - if (hdmi.vdda_hdmi_dac_reg == NULL) { - struct regulator *reg; - - reg = devm_regulator_get(&hdmi.pdev->dev, "vdda_hdmi_dac"); - - /* DT HACK: try VDAC to make omapdss work for o4 sdp/panda */ - if (IS_ERR(reg)) - reg = devm_regulator_get(&hdmi.pdev->dev, "VDAC"); - - if (IS_ERR(reg)) { - DSSERR("can't get VDDA_HDMI_DAC regulator\n"); - return PTR_ERR(reg); - } - - hdmi.vdda_hdmi_dac_reg = reg; - } + r = hdmi_init_regulator(); + if (r) + return r; r = gpio_request_array(gpios, ARRAY_SIZE(gpios)); if (r) -- cgit v0.10.2 From d37801b3a23c8aeeb9ab803a1b2177a8f51967d2 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 17 May 2013 11:00:15 +0300 Subject: OMAPDSS: SDI: clean up regulator init Clean up the SDI driver's regulator init to remove the (unused) omap_dss_device parameter, renaming the function to a more sensible name, and making the code slightly clearer. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index 6277c05..d362fe1 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -248,23 +248,22 @@ void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs) } EXPORT_SYMBOL(omapdss_sdi_set_datapairs); -static int sdi_init_display(struct omap_dss_device *dssdev) +static int sdi_init_regulator(void) { - DSSDBG("SDI init\n"); + struct regulator *vdds_sdi; - if (sdi.vdds_sdi_reg == NULL) { - struct regulator *vdds_sdi; - - vdds_sdi = dss_get_vdds_sdi(); + if (sdi.vdds_sdi_reg) + return 0; - if (IS_ERR(vdds_sdi)) { - DSSERR("can't get VDDS_SDI regulator\n"); - return PTR_ERR(vdds_sdi); - } + vdds_sdi = dss_get_vdds_sdi(); - sdi.vdds_sdi_reg = vdds_sdi; + if (IS_ERR(vdds_sdi)) { + DSSERR("can't get VDDS_SDI regulator\n"); + return PTR_ERR(vdds_sdi); } + sdi.vdds_sdi_reg = vdds_sdi; + return 0; } @@ -313,7 +312,7 @@ static int sdi_probe_pdata(struct platform_device *sdidev) dss_copy_device_pdata(dssdev, plat_dssdev); - r = sdi_init_display(dssdev); + r = sdi_init_regulator(); if (r) { DSSERR("device %s init failed: %d\n", dssdev->name, r); dss_put_device(dssdev); -- cgit v0.10.2 From 46c4b64516d54d149a3050c29e3ca06842f609b3 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Tue, 19 Mar 2013 13:46:40 +0200 Subject: OMAPDSS: SDI: fix regulators for DT SDI requires a regulator to operate. This regulator is, for some reason, currently attached to the virtual omapdss device, instead of the SDI device. This does not work for DT, as the regulator mappings need to be described in the DT data, and the virtual omapdss device is not present there. Fix the issue by acquiring the regulator in the SDI device. To retain compatibility with the current board files, the old method of getting the regulator is kept. The old method can be removed when the board files have been changed to pass the regulator to SDI. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c index d362fe1..89e53eb 100644 --- a/drivers/video/omap2/dss/sdi.c +++ b/drivers/video/omap2/dss/sdi.c @@ -31,6 +31,8 @@ #include "dss.h" static struct { + struct platform_device *pdev; + bool update_enabled; struct regulator *vdds_sdi_reg; @@ -258,8 +260,11 @@ static int sdi_init_regulator(void) vdds_sdi = dss_get_vdds_sdi(); if (IS_ERR(vdds_sdi)) { - DSSERR("can't get VDDS_SDI regulator\n"); - return PTR_ERR(vdds_sdi); + vdds_sdi = devm_regulator_get(&sdi.pdev->dev, "vdds_sdi"); + if (IS_ERR(vdds_sdi)) { + DSSERR("can't get VDDS_SDI regulator\n"); + return PTR_ERR(vdds_sdi); + } } sdi.vdds_sdi_reg = vdds_sdi; @@ -362,6 +367,8 @@ static int omap_sdi_probe(struct platform_device *pdev) { int r; + sdi.pdev = pdev; + sdi_init_output(pdev); if (pdev->dev.platform_data) { -- cgit v0.10.2 From 7e436bb2e3b14706a8bbed21d8d244a89199a907 Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 17 May 2013 12:48:55 +0300 Subject: OMAPDSS: VENC: clean up regulator init Clean up the VENC driver's regulator init to remove the (unused) omap_dss_device parameter, renaming the function to a more sensible name, and making the code slightly clearer. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c index 7b2e3ae..a06c860 100644 --- a/drivers/video/omap2/dss/venc.c +++ b/drivers/video/omap2/dss/venc.c @@ -633,23 +633,22 @@ void omapdss_venc_invert_vid_out_polarity(struct omap_dss_device *dssdev, mutex_unlock(&venc.venc_lock); } -static int venc_init_display(struct omap_dss_device *dssdev) +static int venc_init_regulator(void) { - DSSDBG("init_display\n"); + struct regulator *vdda_dac; - if (venc.vdda_dac_reg == NULL) { - struct regulator *vdda_dac; - - vdda_dac = regulator_get(&venc.pdev->dev, "vdda_dac"); + if (venc.vdda_dac_reg != NULL) + return 0; - if (IS_ERR(vdda_dac)) { - DSSERR("can't get VDDA_DAC regulator\n"); - return PTR_ERR(vdda_dac); - } + vdda_dac = devm_regulator_get(&venc.pdev->dev, "vdda_dac"); - venc.vdda_dac_reg = vdda_dac; + if (IS_ERR(vdda_dac)) { + DSSERR("can't get VDDA_DAC regulator\n"); + return PTR_ERR(vdda_dac); } + venc.vdda_dac_reg = vdda_dac; + return 0; } @@ -765,19 +764,16 @@ static int venc_probe_pdata(struct platform_device *vencdev) if (!plat_dssdev) return 0; + r = venc_init_regulator(); + if (r) + return r; + dssdev = dss_alloc_and_init_device(&vencdev->dev); if (!dssdev) return -ENOMEM; dss_copy_device_pdata(dssdev, plat_dssdev); - r = venc_init_display(dssdev); - if (r) { - DSSERR("device %s init failed: %d\n", dssdev->name, r); - dss_put_device(dssdev); - return r; - } - r = omapdss_output_set_device(&venc.output, dssdev); if (r) { DSSERR("failed to connect output to new device: %s\n", @@ -887,11 +883,6 @@ static int __exit omap_venchw_remove(struct platform_device *pdev) { dss_unregister_child_devices(&pdev->dev); - if (venc.vdda_dac_reg != NULL) { - regulator_put(venc.vdda_dac_reg); - venc.vdda_dac_reg = NULL; - } - venc_panel_exit(); venc_uninit_output(pdev); -- cgit v0.10.2 From 6fcd485b04e67c370026b41a951e0dc410a8d47b Mon Sep 17 00:00:00 2001 From: Tomi Valkeinen Date: Fri, 10 May 2013 13:02:32 +0300 Subject: OMAPDSS: add videomode conversion support Add helper functions to convert between omapdss specific video timings and the common videomode. Eventually omapdss will be changed to use only the common video timings, and these helper functions will make the transition easier. Signed-off-by: Tomi Valkeinen diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig index cb0f145..8f70a83 100644 --- a/drivers/video/omap2/dss/Kconfig +++ b/drivers/video/omap2/dss/Kconfig @@ -1,5 +1,6 @@ menuconfig OMAP2_DSS tristate "OMAP2+ Display Subsystem support" + select VIDEOMODE_HELPERS help OMAP2+ Display Subsystem support. diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c index 0aa8ad8..72ac058 100644 --- a/drivers/video/omap2/dss/display.c +++ b/drivers/video/omap2/dss/display.c @@ -219,3 +219,72 @@ void omap_dss_stop_device(struct omap_dss_device *dssdev) } EXPORT_SYMBOL(omap_dss_stop_device); +void videomode_to_omap_video_timings(const struct videomode *vm, + struct omap_video_timings *ovt) +{ + memset(ovt, 0, sizeof(*ovt)); + + ovt->pixel_clock = vm->pixelclock / 1000; + ovt->x_res = vm->hactive; + ovt->hbp = vm->hback_porch; + ovt->hfp = vm->hfront_porch; + ovt->hsw = vm->hsync_len; + ovt->y_res = vm->vactive; + ovt->vbp = vm->vback_porch; + ovt->vfp = vm->vfront_porch; + ovt->vsw = vm->vsync_len; + + ovt->vsync_level = vm->flags & DISPLAY_FLAGS_VSYNC_HIGH ? + OMAPDSS_SIG_ACTIVE_HIGH : + OMAPDSS_SIG_ACTIVE_LOW; + ovt->hsync_level = vm->flags & DISPLAY_FLAGS_HSYNC_HIGH ? + OMAPDSS_SIG_ACTIVE_HIGH : + OMAPDSS_SIG_ACTIVE_LOW; + ovt->de_level = vm->flags & DISPLAY_FLAGS_DE_HIGH ? + OMAPDSS_SIG_ACTIVE_HIGH : + OMAPDSS_SIG_ACTIVE_HIGH; + ovt->data_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ? + OMAPDSS_DRIVE_SIG_RISING_EDGE : + OMAPDSS_DRIVE_SIG_FALLING_EDGE; + + ovt->sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; +} +EXPORT_SYMBOL(videomode_to_omap_video_timings); + +void omap_video_timings_to_videomode(const struct omap_video_timings *ovt, + struct videomode *vm) +{ + memset(vm, 0, sizeof(*vm)); + + vm->pixelclock = ovt->pixel_clock * 1000; + + vm->hactive = ovt->x_res; + vm->hback_porch = ovt->hbp; + vm->hfront_porch = ovt->hfp; + vm->hsync_len = ovt->hsw; + vm->vactive = ovt->y_res; + vm->vback_porch = ovt->vbp; + vm->vfront_porch = ovt->vfp; + vm->vsync_len = ovt->vsw; + + if (ovt->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH) + vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH; + else + vm->flags |= DISPLAY_FLAGS_HSYNC_LOW; + + if (ovt->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH) + vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH; + else + vm->flags |= DISPLAY_FLAGS_VSYNC_LOW; + + if (ovt->de_level == OMAPDSS_SIG_ACTIVE_HIGH) + vm->flags |= DISPLAY_FLAGS_DE_HIGH; + else + vm->flags |= DISPLAY_FLAGS_DE_LOW; + + if (ovt->data_pclk_edge == OMAPDSS_DRIVE_SIG_RISING_EDGE) + vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE; + else + vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE; +} +EXPORT_SYMBOL(omap_video_timings_to_videomode); diff --git a/include/video/omapdss.h b/include/video/omapdss.h index 4f52f52..0324c7b 100644 --- a/include/video/omapdss.h +++ b/include/video/omapdss.h @@ -23,6 +23,8 @@ #include #include +#include