summaryrefslogtreecommitdiffstats
path: root/drivers/video/omap2/dss
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/video/omap2/dss')
-rw-r--r--drivers/video/omap2/dss/Kconfig1
-rw-r--r--drivers/video/omap2/dss/apply.c59
-rw-r--r--drivers/video/omap2/dss/core.c108
-rw-r--r--drivers/video/omap2/dss/dispc-compat.c3
-rw-r--r--drivers/video/omap2/dss/dispc.c24
-rw-r--r--drivers/video/omap2/dss/display-sysfs.c154
-rw-r--r--drivers/video/omap2/dss/display.c247
-rw-r--r--drivers/video/omap2/dss/dpi.c209
-rw-r--r--drivers/video/omap2/dss/dsi.c232
-rw-r--r--drivers/video/omap2/dss/dss.c3
-rw-r--r--drivers/video/omap2/dss/dss.h35
-rw-r--r--drivers/video/omap2/dss/dss_features.c1
-rw-r--r--drivers/video/omap2/dss/hdmi.c345
-rw-r--r--drivers/video/omap2/dss/manager-sysfs.c47
-rw-r--r--drivers/video/omap2/dss/manager.c29
-rw-r--r--drivers/video/omap2/dss/output.c87
-rw-r--r--drivers/video/omap2/dss/rfbi.c43
-rw-r--r--drivers/video/omap2/dss/sdi.c143
-rw-r--r--drivers/video/omap2/dss/ti_hdmi.h5
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c87
-rw-r--r--drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h1
-rw-r--r--drivers/video/omap2/dss/venc.c163
-rw-r--r--drivers/video/omap2/dss/venc_panel.c16
23 files changed, 1376 insertions, 666 deletions
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
index cb0f145c707..8f70a8300b8 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/apply.c b/drivers/video/omap2/dss/apply.c
index a4b356a9780..d6212d63cfb 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -420,16 +420,26 @@ 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;
+ struct omap_dss_device *dssdev;
+
+ dssdev = mgr->output;
+ if (dssdev == NULL)
+ return NULL;
+
+ while (dssdev->device)
+ dssdev = dssdev->device;
+
+ if (dssdev->driver)
+ return dssdev;
+ else
+ return 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)
@@ -792,6 +802,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_device *dst)
+{
+ return mgr->set_output(mgr, dst);
+}
+
+static void dss_mgr_disconnect_compat(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *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);
@@ -1156,7 +1178,7 @@ static void dss_mgr_get_info(struct omap_overlay_manager *mgr,
}
static int dss_mgr_set_output(struct omap_overlay_manager *mgr,
- struct omap_dss_output *output)
+ struct omap_dss_device *output)
{
int r;
@@ -1554,6 +1576,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,
@@ -1569,7 +1593,6 @@ static DEFINE_MUTEX(compat_init_lock);
int omapdss_compat_init(void)
{
struct platform_device *pdev = dss_get_core_pdev();
- struct omap_dss_device *dssdev = NULL;
int i, r;
mutex_lock(&compat_init_lock);
@@ -1579,7 +1602,7 @@ int omapdss_compat_init(void)
apply_init_priv();
- dss_init_overlay_managers(pdev);
+ dss_init_overlay_managers_sysfs(pdev);
dss_init_overlays(pdev);
for (i = 0; i < omap_dss_get_num_overlay_managers(); i++) {
@@ -1615,12 +1638,9 @@ int omapdss_compat_init(void)
if (r)
goto err_mgr_ops;
- for_each_dss_dev(dssdev) {
- r = display_init_sysfs(pdev, dssdev);
- /* XXX uninit sysfs files on error */
- if (r)
- goto err_disp_sysfs;
- }
+ r = display_init_sysfs(pdev);
+ if (r)
+ goto err_disp_sysfs;
dispc_runtime_get();
@@ -1637,12 +1657,13 @@ out:
err_init_irq:
dispc_runtime_put();
+ display_uninit_sysfs(pdev);
err_disp_sysfs:
dss_uninstall_mgr_ops();
err_mgr_ops:
- dss_uninit_overlay_managers(pdev);
+ dss_uninit_overlay_managers_sysfs(pdev);
dss_uninit_overlays(pdev);
compat_refcnt--;
@@ -1656,7 +1677,6 @@ EXPORT_SYMBOL(omapdss_compat_init);
void omapdss_compat_uninit(void)
{
struct platform_device *pdev = dss_get_core_pdev();
- struct omap_dss_device *dssdev = NULL;
mutex_lock(&compat_init_lock);
@@ -1665,12 +1685,11 @@ void omapdss_compat_uninit(void)
dss_dispc_uninitialize_irq();
- for_each_dss_dev(dssdev)
- display_uninit_sysfs(pdev, dssdev);
+ display_uninit_sysfs(pdev);
dss_uninstall_mgr_ops();
- dss_uninit_overlay_managers(pdev);
+ dss_uninit_overlay_managers_sysfs(pdev);
dss_uninit_overlays(pdev);
out:
mutex_unlock(&compat_init_lock);
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index c9c2252e371..1aeb274e30f 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;
@@ -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;
@@ -290,37 +292,9 @@ static int dss_bus_match(struct device *dev, struct device_driver *driver)
return strcmp(dssdev->driver_name, driver->name) == 0;
}
-static ssize_t device_name_show(struct device *dev,
- struct device_attribute *attr, char *buf)
-{
- struct omap_dss_device *dssdev = to_dss_device(dev);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- dssdev->name ?
- dssdev->name : "");
-}
-
-static struct device_attribute default_dev_attrs[] = {
- __ATTR(name, S_IRUGO, device_name_show, NULL),
- __ATTR_NULL,
-};
-
-static ssize_t driver_name_show(struct device_driver *drv, char *buf)
-{
- struct omap_dss_driver *dssdrv = to_dss_driver(drv);
- return snprintf(buf, PAGE_SIZE, "%s\n",
- dssdrv->driver.name ?
- dssdrv->driver.name : "");
-}
-static struct driver_attribute default_drv_attrs[] = {
- __ATTR(name, S_IRUGO, driver_name_show, NULL),
- __ATTR_NULL,
-};
-
static struct bus_type dss_bus_type = {
.name = "omapdss",
.match = dss_bus_match,
- .dev_attrs = default_dev_attrs,
- .drv_attrs = default_drv_attrs,
};
static void dss_bus_release(struct device *dev)
@@ -377,6 +351,46 @@ static int dss_driver_remove(struct device *dev)
return 0;
}
+static int omapdss_default_connect(struct omap_dss_device *dssdev)
+{
+ struct omap_dss_device *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_device *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;
@@ -390,6 +404,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);
}
@@ -419,29 +437,33 @@ struct omap_dss_device *dss_alloc_and_init_device(struct device *parent)
if (!dssdev)
return NULL;
- dssdev->dev.bus = &dss_bus_type;
- dssdev->dev.parent = parent;
- dssdev->dev.release = omap_dss_dev_release;
- dev_set_name(&dssdev->dev, "display%d", disp_num_counter++);
+ dssdev->old_dev.bus = &dss_bus_type;
+ dssdev->old_dev.parent = parent;
+ dssdev->old_dev.release = omap_dss_dev_release;
+ dev_set_name(&dssdev->old_dev, "display%d", disp_num_counter++);
- device_initialize(&dssdev->dev);
+ device_initialize(&dssdev->old_dev);
return dssdev;
}
int dss_add_device(struct omap_dss_device *dssdev)
{
- return device_add(&dssdev->dev);
+ dssdev->dev = &dssdev->old_dev;
+
+ omapdss_register_display(dssdev);
+ return device_add(&dssdev->old_dev);
}
void dss_put_device(struct omap_dss_device *dssdev)
{
- put_device(&dssdev->dev);
+ put_device(&dssdev->old_dev);
}
void dss_unregister_device(struct omap_dss_device *dssdev)
{
- device_unregister(&dssdev->dev);
+ device_unregister(&dssdev->old_dev);
+ omapdss_unregister_display(dssdev);
}
static int dss_unregister_dss_dev(struct device *dev, void *data)
@@ -618,16 +640,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();
diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/omap2/dss/dispc-compat.c
index 928884c9a0a..83779c2b292 100644
--- a/drivers/video/omap2/dss/dispc-compat.c
+++ b/drivers/video/omap2/dss/dispc-compat.c
@@ -360,8 +360,7 @@ static void dispc_error_worker(struct work_struct *work)
if (bit & errors) {
DSSERR("FIFO UNDERFLOW on %s, disabling the overlay\n",
ovl->name);
- dispc_ovl_enable(ovl->id, false);
- dispc_mgr_go(ovl->manager->id);
+ ovl->disable(ovl);
msleep(50);
}
}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b33b0169bb3..02a7340111d 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -103,6 +103,7 @@ static struct {
int irq;
unsigned long core_clk_rate;
+ unsigned long tv_pclk_rate;
u32 fifo_size[DISPC_MAX_NR_FIFOS];
/* maps which plane is using a fifo. fifo-id -> plane-id */
@@ -3071,22 +3072,15 @@ unsigned long dispc_mgr_pclk_rate(enum omap_channel channel)
return r / pcd;
} else {
- enum dss_hdmi_venc_clk_source_select source;
-
- source = dss_get_hdmi_venc_clk_source();
-
- switch (source) {
- case DSS_VENC_TV_CLK:
- return venc_get_pixel_clock();
- case DSS_HDMI_M_PCLK:
- return hdmi_get_pixel_clock();
- default:
- BUG();
- return 0;
- }
+ return dispc.tv_pclk_rate;
}
}
+void dispc_set_tv_pclk(unsigned long pclk)
+{
+ dispc.tv_pclk_rate = pclk;
+}
+
unsigned long dispc_core_clk_rate(void)
{
return dispc.core_clk_rate;
@@ -3710,6 +3704,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 +3719,8 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
{
pm_runtime_disable(&pdev->dev);
+ dss_uninit_overlay_managers();
+
return 0;
}
diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/omap2/dss/display-sysfs.c
index 18211a9ab35..21d7f77df70 100644
--- a/drivers/video/omap2/dss/display-sysfs.c
+++ b/drivers/video/omap2/dss/display-sysfs.c
@@ -22,42 +22,69 @@
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/jiffies.h>
#include <linux/platform_device.h>
+#include <linux/sysfs.h>
#include <video/omapdss.h>
#include "dss.h"
-#include "dss_features.h"
+
+static struct omap_dss_device *to_dss_device_sysfs(struct device *dev)
+{
+ struct omap_dss_device *dssdev = NULL;
+
+ for_each_dss_dev(dssdev) {
+ if (dssdev->dev == dev) {
+ omap_dss_put_device(dssdev);
+ return dssdev;
+ }
+ }
+
+ return NULL;
+}
+
+static ssize_t display_name_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
+
+ return snprintf(buf, PAGE_SIZE, "%s\n",
+ dssdev->name ?
+ dssdev->name : "");
+}
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;
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
- 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,
struct device_attribute *attr,
const char *buf, size_t size)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(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;
@@ -66,7 +93,7 @@ static ssize_t display_enabled_store(struct device *dev,
static ssize_t display_tear_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
return snprintf(buf, PAGE_SIZE, "%d\n",
dssdev->driver->get_te ?
dssdev->driver->get_te(dssdev) : 0);
@@ -75,7 +102,7 @@ static ssize_t display_tear_show(struct device *dev,
static ssize_t display_tear_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int r;
bool te;
@@ -96,7 +123,7 @@ static ssize_t display_tear_store(struct device *dev,
static ssize_t display_timings_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
struct omap_video_timings t;
if (!dssdev->driver->get_timings)
@@ -113,7 +140,7 @@ static ssize_t display_timings_show(struct device *dev,
static ssize_t display_timings_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
struct omap_video_timings t = dssdev->panel.timings;
int r, found;
@@ -152,7 +179,7 @@ static ssize_t display_timings_store(struct device *dev,
static ssize_t display_rotate_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int rotate;
if (!dssdev->driver->get_rotate)
return -ENOENT;
@@ -163,7 +190,7 @@ static ssize_t display_rotate_show(struct device *dev,
static ssize_t display_rotate_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int rot, r;
if (!dssdev->driver->set_rotate || !dssdev->driver->get_rotate)
@@ -183,7 +210,7 @@ static ssize_t display_rotate_store(struct device *dev,
static ssize_t display_mirror_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int mirror;
if (!dssdev->driver->get_mirror)
return -ENOENT;
@@ -194,7 +221,7 @@ static ssize_t display_mirror_show(struct device *dev,
static ssize_t display_mirror_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
int r;
bool mirror;
@@ -215,7 +242,7 @@ static ssize_t display_mirror_store(struct device *dev,
static ssize_t display_wss_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
unsigned int wss;
if (!dssdev->driver->get_wss)
@@ -229,7 +256,7 @@ static ssize_t display_wss_show(struct device *dev,
static ssize_t display_wss_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = to_dss_device_sysfs(dev);
u32 wss;
int r;
@@ -250,6 +277,7 @@ static ssize_t display_wss_store(struct device *dev,
return size;
}
+static DEVICE_ATTR(name, S_IRUGO, display_name_show, NULL);
static DEVICE_ATTR(enabled, S_IRUGO|S_IWUSR,
display_enabled_show, display_enabled_store);
static DEVICE_ATTR(tear_elim, S_IRUGO|S_IWUSR,
@@ -263,59 +291,55 @@ static DEVICE_ATTR(mirror, S_IRUGO|S_IWUSR,
static DEVICE_ATTR(wss, S_IRUGO|S_IWUSR,
display_wss_show, display_wss_store);
-static struct device_attribute *display_sysfs_attrs[] = {
- &dev_attr_enabled,
- &dev_attr_tear_elim,
- &dev_attr_timings,
- &dev_attr_rotate,
- &dev_attr_mirror,
- &dev_attr_wss,
+static const struct attribute *display_sysfs_attrs[] = {
+ &dev_attr_name.attr,
+ &dev_attr_enabled.attr,
+ &dev_attr_tear_elim.attr,
+ &dev_attr_timings.attr,
+ &dev_attr_rotate.attr,
+ &dev_attr_mirror.attr,
+ &dev_attr_wss.attr,
NULL
};
-int display_init_sysfs(struct platform_device *pdev,
- struct omap_dss_device *dssdev)
+int display_init_sysfs(struct platform_device *pdev)
{
- struct device_attribute *attr;
- int i, r;
+ struct omap_dss_device *dssdev = NULL;
+ int r;
- /* create device sysfs files */
- i = 0;
- while ((attr = display_sysfs_attrs[i++]) != NULL) {
- r = device_create_file(&dssdev->dev, attr);
- if (r) {
- for (i = i - 2; i >= 0; i--) {
- attr = display_sysfs_attrs[i];
- device_remove_file(&dssdev->dev, attr);
- }
+ for_each_dss_dev(dssdev) {
+ struct kobject *kobj = &dssdev->dev->kobj;
- DSSERR("failed to create sysfs file\n");
- return r;
+ r = sysfs_create_files(kobj, display_sysfs_attrs);
+ if (r) {
+ DSSERR("failed to create sysfs files\n");
+ goto err;
}
- }
- /* create display? sysfs links */
- r = sysfs_create_link(&pdev->dev.kobj, &dssdev->dev.kobj,
- dev_name(&dssdev->dev));
- if (r) {
- while ((attr = display_sysfs_attrs[i++]) != NULL)
- device_remove_file(&dssdev->dev, attr);
+ r = sysfs_create_link(&pdev->dev.kobj, kobj, dssdev->alias);
+ if (r) {
+ sysfs_remove_files(kobj, display_sysfs_attrs);
- DSSERR("failed to create sysfs display link\n");
- return r;
+ DSSERR("failed to create sysfs display link\n");
+ goto err;
+ }
}
return 0;
+
+err:
+ display_uninit_sysfs(pdev);
+
+ return r;
}
-void display_uninit_sysfs(struct platform_device *pdev,
- struct omap_dss_device *dssdev)
+void display_uninit_sysfs(struct platform_device *pdev)
{
- struct device_attribute *attr;
- int i = 0;
-
- sysfs_remove_link(&pdev->dev.kobj, dev_name(&dssdev->dev));
+ struct omap_dss_device *dssdev = NULL;
- while ((attr = display_sysfs_attrs[i++]) != NULL)
- device_remove_file(&dssdev->dev, attr);
+ for_each_dss_dev(dssdev) {
+ sysfs_remove_link(&pdev->dev.kobj, dssdev->alias);
+ sysfs_remove_files(&dssdev->dev->kobj,
+ display_sysfs_attrs);
+ }
}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 0aa8ad8f966..fafe7c941a6 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -61,6 +61,7 @@ int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
case OMAP_DISPLAY_TYPE_VENC:
case OMAP_DISPLAY_TYPE_SDI:
case OMAP_DISPLAY_TYPE_HDMI:
+ case OMAP_DISPLAY_TYPE_DVI:
return 24;
default:
BUG();
@@ -76,110 +77,154 @@ void omapdss_default_get_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_default_get_timings);
-static int dss_suspend_device(struct device *dev, void *data)
+int dss_suspend_all_devices(void)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
-
- if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) {
- dssdev->activate_after_resume = false;
- return 0;
- }
-
- dssdev->driver->disable(dssdev);
-
- dssdev->activate_after_resume = true;
+ struct omap_dss_device *dssdev = NULL;
- return 0;
-}
+ for_each_dss_dev(dssdev) {
+ if (!dssdev->driver)
+ continue;
-int dss_suspend_all_devices(void)
-{
- int r;
- struct bus_type *bus = dss_get_bus();
-
- r = bus_for_each_dev(bus, NULL, NULL, dss_suspend_device);
- if (r) {
- /* resume all displays that were suspended */
- dss_resume_all_devices();
- return r;
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
+ dssdev->driver->disable(dssdev);
+ dssdev->activate_after_resume = true;
+ } else {
+ dssdev->activate_after_resume = false;
+ }
}
return 0;
}
-static int dss_resume_device(struct device *dev, void *data)
+int dss_resume_all_devices(void)
{
- int r;
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_device *dssdev = NULL;
- if (dssdev->activate_after_resume) {
- r = dssdev->driver->enable(dssdev);
- if (r)
- return r;
- }
+ for_each_dss_dev(dssdev) {
+ if (!dssdev->driver)
+ continue;
- dssdev->activate_after_resume = false;
+ if (dssdev->activate_after_resume) {
+ dssdev->driver->enable(dssdev);
+ dssdev->activate_after_resume = false;
+ }
+ }
return 0;
}
-int dss_resume_all_devices(void)
+void dss_disable_all_devices(void)
{
- struct bus_type *bus = dss_get_bus();
+ struct omap_dss_device *dssdev = NULL;
+
+ for_each_dss_dev(dssdev) {
+ if (!dssdev->driver)
+ continue;
- return bus_for_each_dev(bus, NULL, NULL, dss_resume_device);
+ if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
+ dssdev->driver->disable(dssdev);
+ }
}
-static int dss_disable_device(struct device *dev, void *data)
+static LIST_HEAD(panel_list);
+static DEFINE_MUTEX(panel_list_mutex);
+static int disp_num_counter;
+
+int omapdss_register_display(struct omap_dss_device *dssdev)
{
- struct omap_dss_device *dssdev = to_dss_device(dev);
+ struct omap_dss_driver *drv = dssdev->driver;
- if (dssdev->state != OMAP_DSS_DISPLAY_DISABLED)
- dssdev->driver->disable(dssdev);
+ snprintf(dssdev->alias, sizeof(dssdev->alias),
+ "display%d", disp_num_counter++);
+ if (drv && drv->get_resolution == NULL)
+ drv->get_resolution = omapdss_default_get_resolution;
+ if (drv && drv->get_recommended_bpp == NULL)
+ drv->get_recommended_bpp = omapdss_default_get_recommended_bpp;
+ if (drv && drv->get_timings == NULL)
+ drv->get_timings = omapdss_default_get_timings;
+
+ mutex_lock(&panel_list_mutex);
+ list_add_tail(&dssdev->panel_list, &panel_list);
+ mutex_unlock(&panel_list_mutex);
return 0;
}
+EXPORT_SYMBOL(omapdss_register_display);
-void dss_disable_all_devices(void)
+void omapdss_unregister_display(struct omap_dss_device *dssdev)
{
- struct bus_type *bus = dss_get_bus();
- bus_for_each_dev(bus, NULL, NULL, dss_disable_device);
+ mutex_lock(&panel_list_mutex);
+ list_del(&dssdev->panel_list);
+ mutex_unlock(&panel_list_mutex);
}
+EXPORT_SYMBOL(omapdss_unregister_display);
-
-void omap_dss_get_device(struct omap_dss_device *dssdev)
+struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev)
{
- get_device(&dssdev->dev);
+ if (!try_module_get(dssdev->owner))
+ return NULL;
+
+ if (get_device(dssdev->dev) == NULL) {
+ module_put(dssdev->owner);
+ return NULL;
+ }
+
+ return dssdev;
}
EXPORT_SYMBOL(omap_dss_get_device);
void omap_dss_put_device(struct omap_dss_device *dssdev)
{
- put_device(&dssdev->dev);
+ put_device(dssdev->dev);
+ module_put(dssdev->owner);
}
EXPORT_SYMBOL(omap_dss_put_device);
-/* ref count of the found device is incremented. ref count
- * of from-device is decremented. */
+/*
+ * ref count of the found device is incremented.
+ * ref count of from-device is decremented.
+ */
struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
{
- struct device *dev;
- struct device *dev_start = NULL;
- struct omap_dss_device *dssdev = NULL;
+ struct list_head *l;
+ struct omap_dss_device *dssdev;
+
+ mutex_lock(&panel_list_mutex);
- int match(struct device *dev, void *data)
- {
- return 1;
+ if (list_empty(&panel_list)) {
+ dssdev = NULL;
+ goto out;
}
- if (from)
- dev_start = &from->dev;
- dev = bus_find_device(dss_get_bus(), dev_start, NULL, match);
- if (dev)
- dssdev = to_dss_device(dev);
- if (from)
- put_device(&from->dev);
+ if (from == NULL) {
+ dssdev = list_first_entry(&panel_list, struct omap_dss_device,
+ panel_list);
+ omap_dss_get_device(dssdev);
+ goto out;
+ }
+
+ omap_dss_put_device(from);
+
+ list_for_each(l, &panel_list) {
+ dssdev = list_entry(l, struct omap_dss_device, panel_list);
+ if (dssdev == from) {
+ if (list_is_last(l, &panel_list)) {
+ dssdev = NULL;
+ goto out;
+ }
+
+ dssdev = list_entry(l->next, struct omap_dss_device,
+ panel_list);
+ omap_dss_get_device(dssdev);
+ goto out;
+ }
+ }
+ WARN(1, "'from' dssdev not found\n");
+
+ dssdev = NULL;
+out:
+ mutex_unlock(&panel_list_mutex);
return dssdev;
}
EXPORT_SYMBOL(omap_dss_get_next_device);
@@ -198,24 +243,72 @@ struct omap_dss_device *omap_dss_find_device(void *data,
}
EXPORT_SYMBOL(omap_dss_find_device);
-int omap_dss_start_device(struct omap_dss_device *dssdev)
+void videomode_to_omap_video_timings(const struct videomode *vm,
+ struct omap_video_timings *ovt)
{
- if (!dssdev->driver) {
- DSSDBG("no driver\n");
- return -ENODEV;
- }
-
- if (!try_module_get(dssdev->dev.driver->owner)) {
- return -ENODEV;
- }
-
- return 0;
+ 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(omap_dss_start_device);
+EXPORT_SYMBOL(videomode_to_omap_video_timings);
-void omap_dss_stop_device(struct omap_dss_device *dssdev)
+void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
+ struct videomode *vm)
{
- module_put(dssdev->dev.driver->owner);
+ 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_dss_stop_device);
-
+EXPORT_SYMBOL(omap_video_timings_to_videomode);
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
index 757b57f7275..a6b331ef776 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;
@@ -46,7 +48,7 @@ static struct {
struct dss_lcd_mgr_config mgr_config;
int data_lines;
- struct omap_dss_output output;
+ struct omap_dss_device output;
} dpi;
static struct platform_device *dpi_get_dsidev(enum omap_channel channel)
@@ -129,7 +131,7 @@ static bool dpi_calc_dispc_cb(int lckd, int pckd, unsigned long lck,
* shifted. So skip all odd dividers when the pixel clock is on the
* higher side.
*/
- if (ctx->pck_min >= 1000000) {
+ if (ctx->pck_min >= 100000000) {
if (lckd > 1 && lckd % 2 != 0)
return false;
@@ -156,7 +158,7 @@ static bool dpi_calc_hsdiv_cb(int regm_dispc, unsigned long dispc,
* shifted. So skip all odd dividers when the pixel clock is on the
* higher side.
*/
- if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 1000000)
+ if (regm_dispc > 1 && regm_dispc % 2 != 0 && ctx->pck_min >= 100000000)
return false;
ctx->dsi_cinfo.regm_dispc = regm_dispc;
@@ -345,7 +347,7 @@ static void dpi_config_lcd_manager(struct omap_overlay_manager *mgr)
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_output *out = &dpi.output;
+ struct omap_dss_device *out = &dpi.output;
int r;
mutex_lock(&dpi.lock);
@@ -362,12 +364,6 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_no_out_mgr;
}
- r = omap_dss_start_device(dssdev);
- if (r) {
- DSSERR("failed to start device\n");
- goto err_start_dev;
- }
-
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI)) {
r = regulator_enable(dpi.vdds_dsi_reg);
if (r)
@@ -422,8 +418,6 @@ err_get_dispc:
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
regulator_disable(dpi.vdds_dsi_reg);
err_reg_enable:
- omap_dss_stop_device(dssdev);
-err_start_dev:
err_no_out_mgr:
err_no_reg:
mutex_unlock(&dpi.lock);
@@ -450,8 +444,6 @@ void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
if (dss_has_feature(FEAT_DPI_USES_VDDS_DSI))
regulator_disable(dpi.vdds_dsi_reg);
- omap_dss_stop_device(dssdev);
-
mutex_unlock(&dpi.lock);
}
EXPORT_SYMBOL(omapdss_dpi_display_disable);
@@ -469,6 +461,16 @@ void omapdss_dpi_set_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_dpi_set_timings);
+static void dpi_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ mutex_lock(&dpi.lock);
+
+ *timings = dpi.timings;
+
+ mutex_unlock(&dpi.lock);
+}
+
int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
@@ -542,6 +544,50 @@ 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)) {
+ 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;
+
+ 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 +618,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 +657,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",
@@ -678,41 +688,108 @@ static int dpi_probe_pdata(struct platform_device *dpidev)
return 0;
}
+static int dpi_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ r = dpi_init_regulator();
+ if (r)
+ return r;
+
+ dpi_init_pll();
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dst->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void dpi_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static const struct omapdss_dpi_ops dpi_ops = {
+ .connect = dpi_connect,
+ .disconnect = dpi_disconnect,
+
+ .enable = omapdss_dpi_display_enable,
+ .disable = omapdss_dpi_display_disable,
+
+ .check_timings = dpi_check_timings,
+ .set_timings = omapdss_dpi_set_timings,
+ .get_timings = dpi_get_timings,
+
+ .set_data_lines = omapdss_dpi_set_data_lines,
+};
+
static void dpi_init_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &dpi.output;
+ struct omap_dss_device *out = &dpi.output;
- out->pdev = pdev;
+ out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_DPI;
- out->type = OMAP_DISPLAY_TYPE_DPI;
+ out->output_type = OMAP_DISPLAY_TYPE_DPI;
out->name = "dpi.0";
out->dispc_channel = dpi_get_channel();
+ out->ops.dpi = &dpi_ops;
+ out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit dpi_uninit_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &dpi.output;
+ struct omap_dss_device *out = &dpi.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
static int omap_dpi_probe(struct platform_device *pdev)
{
int r;
+ dpi.pdev = pdev;
+
mutex_init(&dpi.lock);
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 a73dedc3310..99a043b08f0 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/omap2/dss/dsi.c
@@ -363,7 +363,7 @@ struct dsi_data {
enum omap_dss_dsi_mode mode;
struct omap_dss_dsi_videomode_timings vm_timings;
- struct omap_dss_output output;
+ struct omap_dss_device output;
};
struct dsi_packet_sent_handler_data {
@@ -383,12 +383,21 @@ static inline struct dsi_data *dsi_get_dsidrv_data(struct platform_device *dside
static inline struct platform_device *dsi_get_dsidev_from_dssdev(struct omap_dss_device *dssdev)
{
- return dssdev->output->pdev;
+ /* HACK: dssdev can be either the panel device, when using old API, or
+ * the dsi device itself, when using the new API. So we solve this for
+ * now by checking the dssdev->id. This will be removed when the old API
+ * is removed.
+ */
+ if (dssdev->id == OMAP_DSS_OUTPUT_DSI1 ||
+ dssdev->id == OMAP_DSS_OUTPUT_DSI2)
+ return to_platform_device(dssdev->dev);
+
+ return to_platform_device(dssdev->output->dev);
}
struct platform_device *dsi_get_dsidev_from_id(int module)
{
- struct omap_dss_output *out;
+ struct omap_dss_device *out;
enum omap_dss_output_id id;
switch (module) {
@@ -404,7 +413,7 @@ struct platform_device *dsi_get_dsidev_from_id(int module)
out = omap_dss_get_output(id);
- return out ? out->pdev : NULL;
+ return out ? to_platform_device(out->dev) : NULL;
}
static inline void dsi_write_reg(struct platform_device *dsidev,
@@ -1114,6 +1123,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 +1625,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);
/*
@@ -4122,7 +4142,7 @@ int dsi_enable_video_output(struct omap_dss_device *dssdev, int channel)
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
struct omap_overlay_manager *mgr = dsi->output.manager;
int bpp = dsi_get_pixel_size(dsi->pix_fmt);
- struct omap_dss_output *out = &dsi->output;
+ struct omap_dss_device *out = &dsi->output;
u8 data_type;
u16 word_count;
int r;
@@ -4581,12 +4601,6 @@ int omapdss_dsi_display_enable(struct omap_dss_device *dssdev)
mutex_lock(&dsi->lock);
- r = omap_dss_start_device(dssdev);
- if (r) {
- DSSERR("failed to start device\n");
- goto err_start_dev;
- }
-
r = dsi_runtime_get(dsidev);
if (r)
goto err_get_dsi;
@@ -4607,8 +4621,6 @@ err_init_dsi:
dsi_enable_pll_clock(dsidev, 0);
dsi_runtime_put(dsidev);
err_get_dsi:
- omap_dss_stop_device(dssdev);
-err_start_dev:
mutex_unlock(&dsi->lock);
DSSDBG("dsi_display_enable FAILED\n");
return r;
@@ -4637,8 +4649,6 @@ void omapdss_dsi_display_disable(struct omap_dss_device *dssdev,
dsi_runtime_put(dsidev);
dsi_enable_pll_clock(dsidev, 0);
- omap_dss_stop_device(dssdev);
-
mutex_unlock(&dsi->lock);
}
EXPORT_SYMBOL(omapdss_dsi_display_disable);
@@ -5225,34 +5235,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 +5392,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",
@@ -5442,28 +5421,113 @@ static int dsi_probe_pdata(struct platform_device *dsidev)
return 0;
}
+static int dsi_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct platform_device *dsidev = dsi_get_dsidev_from_dssdev(dssdev);
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ r = dsi_regulator_init(dsidev);
+ if (r)
+ return r;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dssdev->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void dsi_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static const struct omapdss_dsi_ops dsi_ops = {
+ .connect = dsi_connect,
+ .disconnect = dsi_disconnect,
+
+ .bus_lock = dsi_bus_lock,
+ .bus_unlock = dsi_bus_unlock,
+
+ .enable = omapdss_dsi_display_enable,
+ .disable = omapdss_dsi_display_disable,
+
+ .enable_hs = omapdss_dsi_vc_enable_hs,
+
+ .configure_pins = omapdss_dsi_configure_pins,
+ .set_config = omapdss_dsi_set_config,
+
+ .enable_video_output = dsi_enable_video_output,
+ .disable_video_output = dsi_disable_video_output,
+
+ .update = omap_dsi_update,
+
+ .enable_te = omapdss_dsi_enable_te,
+
+ .request_vc = omap_dsi_request_vc,
+ .set_vc_id = omap_dsi_set_vc_id,
+ .release_vc = omap_dsi_release_vc,
+
+ .dcs_write = dsi_vc_dcs_write,
+ .dcs_write_nosync = dsi_vc_dcs_write_nosync,
+ .dcs_read = dsi_vc_dcs_read,
+
+ .gen_write = dsi_vc_generic_write,
+ .gen_write_nosync = dsi_vc_generic_write_nosync,
+ .gen_read = dsi_vc_generic_read,
+
+ .bta_sync = dsi_vc_send_bta_sync,
+
+ .set_max_rx_packet_size = dsi_vc_set_max_rx_packet_size,
+};
+
static void dsi_init_output(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- struct omap_dss_output *out = &dsi->output;
+ struct omap_dss_device *out = &dsi->output;
- out->pdev = dsidev;
+ out->dev = &dsidev->dev;
out->id = dsi->module_id == 0 ?
OMAP_DSS_OUTPUT_DSI1 : OMAP_DSS_OUTPUT_DSI2;
- out->type = OMAP_DISPLAY_TYPE_DSI;
+ out->output_type = OMAP_DISPLAY_TYPE_DSI;
out->name = dsi->module_id == 0 ? "dsi.0" : "dsi.1";
out->dispc_channel = dsi_get_channel(dsi->module_id);
+ out->ops.dsi = &dsi_ops;
+ out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void dsi_uninit_output(struct platform_device *dsidev)
{
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
- struct omap_dss_output *out = &dsi->output;
+ struct omap_dss_device *out = &dsi->output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
/* DSI1 HW IP initialisation */
@@ -5563,12 +5627,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 +5648,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;
@@ -5603,14 +5668,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;
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
index 94f66f9f10a..bd01608e67e 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)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 84758936429..50a2362ef8f 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -179,23 +179,19 @@ void dss_put_device(struct omap_dss_device *dssdev);
void dss_copy_device_pdata(struct omap_dss_device *dst,
const struct omap_dss_device *src);
-/* output */
-void dss_register_output(struct omap_dss_output *out);
-void dss_unregister_output(struct omap_dss_output *out);
-
/* display */
int dss_suspend_all_devices(void);
int dss_resume_all_devices(void);
void dss_disable_all_devices(void);
-int display_init_sysfs(struct platform_device *pdev,
- struct omap_dss_device *dssdev);
-void display_uninit_sysfs(struct platform_device *pdev,
- struct omap_dss_device *dssdev);
+int display_init_sysfs(struct platform_device *pdev);
+void display_uninit_sysfs(struct platform_device *pdev);
/* 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,
@@ -426,6 +422,7 @@ void dispc_mgr_set_clock_div(enum omap_channel channel,
const struct dispc_clock_info *cinfo);
int dispc_mgr_get_clock_div(enum omap_channel channel,
struct dispc_clock_info *cinfo);
+void dispc_set_tv_pclk(unsigned long pclk);
u32 dispc_wb_get_framedone_irq(void);
bool dispc_wb_go_busy(void);
@@ -437,17 +434,8 @@ int dispc_wb_setup(const struct omap_dss_writeback_info *wi,
bool mem_to_mem, const struct omap_video_timings *timings);
/* VENC */
-#ifdef CONFIG_OMAP2_DSS_VENC
int venc_init_platform_driver(void) __init;
void venc_uninit_platform_driver(void) __exit;
-unsigned long venc_get_pixel_clock(void);
-#else
-static inline unsigned long venc_get_pixel_clock(void)
-{
- WARN("%s: VENC not compiled in, returning pclk as 0\n", __func__);
- return 0;
-}
-#endif
int omapdss_venc_display_enable(struct omap_dss_device *dssdev);
void omapdss_venc_display_disable(struct omap_dss_device *dssdev);
void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
@@ -464,17 +452,8 @@ int venc_panel_init(void);
void venc_panel_exit(void);
/* HDMI */
-#ifdef CONFIG_OMAP4_DSS_HDMI
int hdmi_init_platform_driver(void) __init;
void hdmi_uninit_platform_driver(void) __exit;
-unsigned long hdmi_get_pixel_clock(void);
-#else
-static inline unsigned long hdmi_get_pixel_clock(void)
-{
- WARN("%s: HDMI not compiled in, returning pclk as 0\n", __func__);
- return 0;
-}
-#endif
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev);
void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev);
int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 77dbe0cfb34..b9cfebb378a 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -797,7 +797,6 @@ static const struct ti_hdmi_ip_ops omap4_hdmi_functions = {
.phy_enable = ti_hdmi_4xxx_phy_enable,
.phy_disable = ti_hdmi_4xxx_phy_disable,
.read_edid = ti_hdmi_4xxx_read_edid,
- .detect = ti_hdmi_4xxx_detect,
.pll_enable = ti_hdmi_4xxx_pll_enable,
.pll_disable = ti_hdmi_4xxx_pll_disable,
.video_enable = ti_hdmi_4xxx_wp_video_start,
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index a109934c047..44a885b9282 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -70,7 +70,9 @@ static struct {
int ls_oe_gpio;
int hpd_gpio;
- struct omap_dss_output output;
+ bool core_enabled;
+
+ struct omap_dss_device output;
} hdmi;
/*
@@ -328,6 +330,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 +367,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)
@@ -455,12 +467,6 @@ end: return cm;
}
-unsigned long hdmi_get_pixel_clock(void)
-{
- /* HDMI Pixel Clock in Mhz */
- return hdmi.ip_data.cfg.timings.pixel_clock * 1000;
-}
-
static void hdmi_compute_pll(struct omap_dss_device *dssdev, int phy,
struct hdmi_pll_info *pi)
{
@@ -511,8 +517,10 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
{
int r;
- gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
- gpio_set_value(hdmi.ls_oe_gpio, 1);
+ if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
+ if (gpio_is_valid(hdmi.ls_oe_gpio))
+ gpio_set_value(hdmi.ls_oe_gpio, 1);
/* wait 300us after CT_CP_HPD for the 5V power output to reach 90% */
udelay(300);
@@ -528,29 +536,37 @@ static int hdmi_power_on_core(struct omap_dss_device *dssdev)
/* Make selection of HDMI in DSS */
dss_select_hdmi_venc_clk_source(DSS_HDMI_M_PCLK);
+ hdmi.core_enabled = true;
+
return 0;
err_runtime_get:
regulator_disable(hdmi.vdda_hdmi_dac_reg);
err_vdac_enable:
- gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
- gpio_set_value(hdmi.ls_oe_gpio, 0);
+ if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ if (gpio_is_valid(hdmi.ls_oe_gpio))
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
return r;
}
static void hdmi_power_off_core(struct omap_dss_device *dssdev)
{
+ hdmi.core_enabled = false;
+
hdmi_runtime_put();
regulator_disable(hdmi.vdda_hdmi_dac_reg);
- gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
- gpio_set_value(hdmi.ls_oe_gpio, 0);
+ if (gpio_is_valid(hdmi.ct_cp_hpd_gpio))
+ gpio_set_value(hdmi.ct_cp_hpd_gpio, 0);
+ if (gpio_is_valid(hdmi.ls_oe_gpio))
+ gpio_set_value(hdmi.ls_oe_gpio, 0);
}
static int hdmi_power_on_full(struct omap_dss_device *dssdev)
{
int r;
struct omap_video_timings *p;
- struct omap_overlay_manager *mgr = dssdev->output->manager;
+ struct omap_overlay_manager *mgr = hdmi.output.manager;
unsigned long phy;
r = hdmi_power_on_core(dssdev);
@@ -613,7 +629,7 @@ err_pll_enable:
static void hdmi_power_off_full(struct omap_dss_device *dssdev)
{
- struct omap_overlay_manager *mgr = dssdev->output->manager;
+ struct omap_overlay_manager *mgr = hdmi.output.manager;
dss_mgr_disable(mgr);
@@ -653,9 +669,23 @@ void omapdss_hdmi_display_set_timing(struct omap_dss_device *dssdev,
if (t != NULL)
hdmi.ip_data.cfg = *t;
+ dispc_set_tv_pclk(t->timings.pixel_clock * 1000);
+
mutex_unlock(&hdmi.lock);
}
+static void omapdss_hdmi_display_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ const struct hdmi_config *cfg;
+
+ cfg = hdmi_get_timings();
+ if (cfg == NULL)
+ cfg = &vesa_timings[0];
+
+ memcpy(timings, &cfg->timings, sizeof(cfg->timings));
+}
+
static void hdmi_dump_regs(struct seq_file *s)
{
mutex_lock(&hdmi.lock);
@@ -700,7 +730,7 @@ bool omapdss_hdmi_detect(void)
r = hdmi_runtime_get();
BUG_ON(r);
- r = hdmi.ip_data.ops->detect(&hdmi.ip_data);
+ r = gpio_get_value(hdmi.hpd_gpio);
hdmi_runtime_put();
mutex_unlock(&hdmi.lock);
@@ -710,7 +740,7 @@ bool omapdss_hdmi_detect(void)
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_output *out = dssdev->output;
+ struct omap_dss_device *out = &hdmi.output;
int r = 0;
DSSDBG("ENTER hdmi_display_enable\n");
@@ -723,25 +753,15 @@ int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
- hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
-
- r = omap_dss_start_device(dssdev);
- if (r) {
- DSSERR("failed to start device\n");
- goto err0;
- }
-
r = hdmi_power_on_full(dssdev);
if (r) {
DSSERR("failed to power on device\n");
- goto err1;
+ goto err0;
}
mutex_unlock(&hdmi.lock);
return 0;
-err1:
- omap_dss_stop_device(dssdev);
err0:
mutex_unlock(&hdmi.lock);
return r;
@@ -755,8 +775,6 @@ void omapdss_hdmi_display_disable(struct omap_dss_device *dssdev)
hdmi_power_off_full(dssdev);
- omap_dss_stop_device(dssdev);
-
mutex_unlock(&hdmi.lock);
}
@@ -768,8 +786,6 @@ int omapdss_hdmi_core_enable(struct omap_dss_device *dssdev)
mutex_lock(&hdmi.lock);
- hdmi.ip_data.hpd_gpio = hdmi.hpd_gpio;
-
r = hdmi_power_on_core(dssdev);
if (r) {
DSSERR("failed to power on device\n");
@@ -1033,24 +1049,219 @@ static int hdmi_probe_pdata(struct platform_device *pdev)
return 0;
}
+static int hdmi_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ dss_init_hdmi_ip_ops(&hdmi.ip_data, omapdss_get_version());
+
+ r = hdmi_init_regulator();
+ if (r)
+ return r;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dst->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void hdmi_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static int hdmi_read_edid(struct omap_dss_device *dssdev,
+ u8 *edid, int len)
+{
+ bool need_enable;
+ int r;
+
+ need_enable = hdmi.core_enabled == false;
+
+ if (need_enable) {
+ r = omapdss_hdmi_core_enable(dssdev);
+ if (r)
+ return r;
+ }
+
+ r = omapdss_hdmi_read_edid(edid, len);
+
+ if (need_enable)
+ omapdss_hdmi_core_disable(dssdev);
+
+ return r;
+}
+
+#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
+static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
+{
+ int r;
+
+ mutex_lock(&hdmi.lock);
+
+ if (!hdmi_mode_has_audio()) {
+ r = -EPERM;
+ goto err;
+ }
+
+ r = hdmi_audio_enable();
+ if (r)
+ goto err;
+
+ mutex_unlock(&hdmi.lock);
+ return 0;
+
+err:
+ mutex_unlock(&hdmi.lock);
+ return r;
+}
+
+static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev)
+{
+ hdmi_audio_disable();
+}
+
+static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev)
+{
+ return hdmi_audio_start();
+}
+
+static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev)
+{
+ hdmi_audio_stop();
+}
+
+static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
+{
+ bool r;
+
+ mutex_lock(&hdmi.lock);
+
+ r = hdmi_mode_has_audio();
+
+ mutex_unlock(&hdmi.lock);
+ return r;
+}
+
+static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
+ struct omap_dss_audio *audio)
+{
+ int r;
+
+ mutex_lock(&hdmi.lock);
+
+ if (!hdmi_mode_has_audio()) {
+ r = -EPERM;
+ goto err;
+ }
+
+ r = hdmi_audio_config(audio);
+ if (r)
+ goto err;
+
+ mutex_unlock(&hdmi.lock);
+ return 0;
+
+err:
+ mutex_unlock(&hdmi.lock);
+ return r;
+}
+#else
+static int omapdss_hdmi_audio_enable(struct omap_dss_device *dssdev)
+{
+ return -EPERM;
+}
+
+static void omapdss_hdmi_audio_disable(struct omap_dss_device *dssdev)
+{
+}
+
+static int omapdss_hdmi_audio_start(struct omap_dss_device *dssdev)
+{
+ return -EPERM;
+}
+
+static void omapdss_hdmi_audio_stop(struct omap_dss_device *dssdev)
+{
+}
+
+static bool omapdss_hdmi_audio_supported(struct omap_dss_device *dssdev)
+{
+ return false;
+}
+
+static int omapdss_hdmi_audio_config(struct omap_dss_device *dssdev,
+ struct omap_dss_audio *audio)
+{
+ return -EPERM;
+}
+#endif
+
+static const struct omapdss_hdmi_ops hdmi_ops = {
+ .connect = hdmi_connect,
+ .disconnect = hdmi_disconnect,
+
+ .enable = omapdss_hdmi_display_enable,
+ .disable = omapdss_hdmi_display_disable,
+
+ .check_timings = omapdss_hdmi_display_check_timing,
+ .set_timings = omapdss_hdmi_display_set_timing,
+ .get_timings = omapdss_hdmi_display_get_timings,
+
+ .read_edid = hdmi_read_edid,
+
+ .audio_enable = omapdss_hdmi_audio_enable,
+ .audio_disable = omapdss_hdmi_audio_disable,
+ .audio_start = omapdss_hdmi_audio_start,
+ .audio_stop = omapdss_hdmi_audio_stop,
+ .audio_supported = omapdss_hdmi_audio_supported,
+ .audio_config = omapdss_hdmi_audio_config,
+};
+
static void hdmi_init_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &hdmi.output;
+ struct omap_dss_device *out = &hdmi.output;
- out->pdev = pdev;
+ out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_HDMI;
- out->type = OMAP_DISPLAY_TYPE_HDMI;
+ out->output_type = OMAP_DISPLAY_TYPE_HDMI;
out->name = "hdmi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
+ out->ops.hdmi = &hdmi_ops;
+ out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit hdmi_uninit_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &hdmi.output;
+ struct omap_dss_device *out = &hdmi.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
/* HDMI HW IP initialisation */
@@ -1071,6 +1282,12 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
if (IS_ERR(hdmi.ip_data.base_wp))
return PTR_ERR(hdmi.ip_data.base_wp);
+ hdmi.ip_data.irq = platform_get_irq(pdev, 0);
+ if (hdmi.ip_data.irq < 0) {
+ DSSERR("platform_get_irq failed\n");
+ return -ENODEV;
+ }
+
r = hdmi_get_clocks(pdev);
if (r) {
DSSERR("can't get clocks\n");
@@ -1084,6 +1301,10 @@ static int omapdss_hdmihw_probe(struct platform_device *pdev)
hdmi.ip_data.pll_offset = HDMI_PLLCTRL;
hdmi.ip_data.phy_offset = HDMI_PHY;
+ hdmi.ct_cp_hpd_gpio = -1;
+ hdmi.ls_oe_gpio = -1;
+ hdmi.hpd_gpio = -1;
+
hdmi_init_output(pdev);
r = hdmi_panel_init();
@@ -1094,15 +1315,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/manager-sysfs.c b/drivers/video/omap2/dss/manager-sysfs.c
index 9a2fb59b6f8..de7e7b5b1b7 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,32 +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 = dssdev->output;
-
- /*
- * a registered device should have an output connected to it
- * already
- */
- if (!out) {
- DSSERR("device has no output connected to it\n");
+ 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;
}
- r = mgr->set_output(mgr, out);
+ old_dssdev->driver->disconnect(old_dssdev);
+ }
+
+ if (dssdev) {
+ r = dssdev->driver->connect(dssdev);
if (r) {
- DSSERR("failed to set manager output\n");
+ DSSERR("failed to connect new device\n");
+ goto put_device;
+ }
+
+ 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;
}
@@ -509,4 +522,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 2551eaa14c4..1aac9b4191a 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)
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/omap2/dss/output.c
index 5214df63e0a..3f5c0a758b3 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/omap2/dss/output.c
@@ -27,7 +27,7 @@
static LIST_HEAD(output_list);
static DEFINE_MUTEX(output_lock);
-int omapdss_output_set_device(struct omap_dss_output *out,
+int omapdss_output_set_device(struct omap_dss_device *out,
struct omap_dss_device *dssdev)
{
int r;
@@ -41,7 +41,7 @@ int omapdss_output_set_device(struct omap_dss_output *out,
goto err;
}
- if (out->type != dssdev->type) {
+ if (out->output_type != dssdev->type) {
DSSERR("output type and display type don't match\n");
r = -EINVAL;
goto err;
@@ -60,7 +60,7 @@ err:
}
EXPORT_SYMBOL(omapdss_output_set_device);
-int omapdss_output_unset_device(struct omap_dss_output *out)
+int omapdss_output_unset_device(struct omap_dss_device *out)
{
int r;
@@ -92,19 +92,22 @@ err:
}
EXPORT_SYMBOL(omapdss_output_unset_device);
-void dss_register_output(struct omap_dss_output *out)
+int omapdss_register_output(struct omap_dss_device *out)
{
list_add_tail(&out->list, &output_list);
+ return 0;
}
+EXPORT_SYMBOL(omapdss_register_output);
-void dss_unregister_output(struct omap_dss_output *out)
+void omapdss_unregister_output(struct omap_dss_device *out)
{
list_del(&out->list);
}
+EXPORT_SYMBOL(omapdss_unregister_output);
-struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
+struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id)
{
- struct omap_dss_output *out;
+ struct omap_dss_device *out;
list_for_each_entry(out, &output_list, list) {
if (out->id == id)
@@ -115,6 +118,62 @@ struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
}
EXPORT_SYMBOL(omap_dss_get_output);
+struct omap_dss_device *omap_dss_find_output(const char *name)
+{
+ struct omap_dss_device *out;
+
+ list_for_each_entry(out, &output_list, list) {
+ if (strcmp(out->name, name) == 0)
+ return omap_dss_get_device(out);
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(omap_dss_find_output);
+
+struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node)
+{
+ struct omap_dss_device *out;
+
+ list_for_each_entry(out, &output_list, list) {
+ if (out->dev->of_node == node)
+ return omap_dss_get_device(out);
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(omap_dss_find_output_by_node);
+
+struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
+{
+ while (dssdev->output)
+ dssdev = dssdev->output;
+
+ if (dssdev->id != 0)
+ return omap_dss_get_device(dssdev);
+
+ return NULL;
+}
+EXPORT_SYMBOL(omapdss_find_output_from_display);
+
+struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev)
+{
+ struct omap_dss_device *out;
+ struct omap_overlay_manager *mgr;
+
+ out = omapdss_find_output_from_display(dssdev);
+
+ if (out == NULL)
+ return NULL;
+
+ mgr = out->manager;
+
+ omap_dss_put_device(out);
+
+ return mgr;
+}
+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)
@@ -134,6 +193,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_device *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_device *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/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
index 1a17dd1447d..fdfe6e6f25d 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/omap2/dss/rfbi.c
@@ -117,7 +117,7 @@ static struct {
int data_lines;
struct rfbi_timings intf_timings;
- struct omap_dss_output output;
+ struct omap_dss_device output;
} rfbi;
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
@@ -312,7 +312,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
{
u32 l;
int r;
- struct omap_overlay_manager *mgr = dssdev->output->manager;
+ struct omap_overlay_manager *mgr = rfbi.output.manager;
u16 width = rfbi.timings.x_res;
u16 height = rfbi.timings.y_res;
@@ -852,7 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s)
static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
{
- struct omap_overlay_manager *mgr = dssdev->output->manager;
+ struct omap_overlay_manager *mgr = rfbi.output.manager;
struct dss_lcd_mgr_config mgr_config;
mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
@@ -890,7 +890,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_output *out = dssdev->output;
+ struct omap_dss_device *out = &rfbi.output;
int r;
if (out == NULL || out->manager == NULL) {
@@ -902,12 +902,6 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
if (r)
return r;
- r = omap_dss_start_device(dssdev);
- if (r) {
- DSSERR("failed to start device\n");
- goto err0;
- }
-
r = dss_mgr_register_framedone_handler(out->manager,
framedone_callback, NULL);
if (r) {
@@ -924,8 +918,6 @@ int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
return 0;
err1:
- omap_dss_stop_device(dssdev);
-err0:
rfbi_runtime_put();
return r;
}
@@ -933,11 +925,10 @@ EXPORT_SYMBOL(omapdss_rfbi_display_enable);
void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
{
- struct omap_dss_output *out = dssdev->output;
+ struct omap_dss_device *out = &rfbi.output;
dss_mgr_unregister_framedone_handler(out->manager,
framedone_callback, NULL);
- omap_dss_stop_device(dssdev);
rfbi_runtime_put();
}
@@ -1022,22 +1013,23 @@ static int rfbi_probe_pdata(struct platform_device *rfbidev)
static void rfbi_init_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &rfbi.output;
+ struct omap_dss_device *out = &rfbi.output;
- out->pdev = pdev;
+ out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_DBI;
- out->type = OMAP_DISPLAY_TYPE_DBI;
+ out->output_type = OMAP_DISPLAY_TYPE_DBI;
out->name = "rfbi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
+ out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit rfbi_uninit_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &rfbi.output;
+ struct omap_dss_device *out = &rfbi.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
/* RFBI HW IP initialisation */
@@ -1093,15 +1085,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 0bcd30272f6..856af2e8976 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;
@@ -38,7 +40,7 @@ static struct {
struct omap_video_timings timings;
int datapairs;
- struct omap_dss_output output;
+ struct omap_dss_device output;
} sdi;
struct sdi_clk_calc_ctx {
@@ -109,7 +111,7 @@ static int sdi_calc_clock_div(unsigned long pclk,
static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
{
- struct omap_overlay_manager *mgr = dssdev->output->manager;
+ struct omap_overlay_manager *mgr = sdi.output.manager;
sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
@@ -124,7 +126,7 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_output *out = dssdev->output;
+ struct omap_dss_device *out = &sdi.output;
struct omap_video_timings *t = &sdi.timings;
struct dss_clock_info dss_cinfo;
struct dispc_clock_info dispc_cinfo;
@@ -136,12 +138,6 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
return -ENODEV;
}
- r = omap_dss_start_device(dssdev);
- if (r) {
- DSSERR("failed to start device\n");
- goto err_start_dev;
- }
-
r = regulator_enable(sdi.vdds_sdi_reg);
if (r)
goto err_reg_enable;
@@ -213,15 +209,13 @@ err_calc_clock_div:
err_get_dispc:
regulator_disable(sdi.vdds_sdi_reg);
err_reg_enable:
- omap_dss_stop_device(dssdev);
-err_start_dev:
return r;
}
EXPORT_SYMBOL(omapdss_sdi_display_enable);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
{
- struct omap_overlay_manager *mgr = dssdev->output->manager;
+ struct omap_overlay_manager *mgr = sdi.output.manager;
dss_mgr_disable(mgr);
@@ -230,8 +224,6 @@ void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
dispc_runtime_put();
regulator_disable(sdi.vdds_sdi_reg);
-
- omap_dss_stop_device(dssdev);
}
EXPORT_SYMBOL(omapdss_sdi_display_disable);
@@ -242,29 +234,51 @@ void omapdss_sdi_set_timings(struct omap_dss_device *dssdev,
}
EXPORT_SYMBOL(omapdss_sdi_set_timings);
+static void sdi_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ *timings = sdi.timings;
+}
+
+static int sdi_check_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ struct omap_overlay_manager *mgr = sdi.output.manager;
+
+ if (mgr && !dispc_mgr_timings_ok(mgr->id, timings))
+ return -EINVAL;
+
+ if (timings->pixel_clock == 0)
+ return -EINVAL;
+
+ return 0;
+}
+
void omapdss_sdi_set_datapairs(struct omap_dss_device *dssdev, int datapairs)
{
sdi.datapairs = 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;
+ if (sdi.vdds_sdi_reg)
+ return 0;
- vdds_sdi = dss_get_vdds_sdi();
+ vdds_sdi = dss_get_vdds_sdi();
+ if (IS_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;
}
+ sdi.vdds_sdi_reg = vdds_sdi;
+
return 0;
}
@@ -313,7 +327,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);
@@ -339,39 +353,104 @@ static int sdi_probe_pdata(struct platform_device *sdidev)
return 0;
}
+static int sdi_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ r = sdi_init_regulator();
+ if (r)
+ return r;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dst->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void sdi_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static const struct omapdss_sdi_ops sdi_ops = {
+ .connect = sdi_connect,
+ .disconnect = sdi_disconnect,
+
+ .enable = omapdss_sdi_display_enable,
+ .disable = omapdss_sdi_display_disable,
+
+ .check_timings = sdi_check_timings,
+ .set_timings = omapdss_sdi_set_timings,
+ .get_timings = sdi_get_timings,
+
+ .set_datapairs = omapdss_sdi_set_datapairs,
+};
+
static void sdi_init_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &sdi.output;
+ struct omap_dss_device *out = &sdi.output;
- out->pdev = pdev;
+ out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_SDI;
- out->type = OMAP_DISPLAY_TYPE_SDI;
+ out->output_type = OMAP_DISPLAY_TYPE_SDI;
out->name = "sdi.0";
out->dispc_channel = OMAP_DSS_CHANNEL_LCD;
+ out->ops.sdi = &sdi_ops;
+ out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit sdi_uninit_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &sdi.output;
+ struct omap_dss_device *out = &sdi.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
static int omap_sdi_probe(struct platform_device *pdev)
{
int r;
+ sdi.pdev = 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/ti_hdmi.h b/drivers/video/omap2/dss/ti_hdmi.h
index 216aa704f9d..45215f44617 100644
--- a/drivers/video/omap2/dss/ti_hdmi.h
+++ b/drivers/video/omap2/dss/ti_hdmi.h
@@ -73,8 +73,6 @@ struct ti_hdmi_ip_ops {
int (*read_edid)(struct hdmi_ip_data *ip_data, u8 *edid, int len);
- bool (*detect)(struct hdmi_ip_data *ip_data);
-
int (*pll_enable)(struct hdmi_ip_data *ip_data);
void (*pll_disable)(struct hdmi_ip_data *ip_data);
@@ -155,19 +153,18 @@ struct hdmi_ip_data {
unsigned long core_av_offset;
unsigned long pll_offset;
unsigned long phy_offset;
+ int irq;
const struct ti_hdmi_ip_ops *ops;
struct hdmi_config cfg;
struct hdmi_pll_info pll_data;
struct hdmi_core_infoframe_avi avi_cfg;
/* ti_hdmi_4xxx_ip private data. These should be in a separate struct */
- int hpd_gpio;
struct mutex lock;
};
int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data);
void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data);
int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data, u8 *edid, int len);
-bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data);
int ti_hdmi_4xxx_wp_video_start(struct hdmi_ip_data *ip_data);
void ti_hdmi_4xxx_wp_video_stop(struct hdmi_ip_data *ip_data);
int ti_hdmi_4xxx_pll_enable(struct hdmi_ip_data *ip_data);
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
index e18b222ed73..e242ed85cb0 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.c
@@ -28,7 +28,6 @@
#include <linux/delay.h>
#include <linux/string.h>
#include <linux/seq_file.h>
-#include <linux/gpio.h>
#if defined(CONFIG_OMAP4_DSS_HDMI_AUDIO)
#include <sound/asound.h>
#include <sound/asoundef.h>
@@ -38,6 +37,9 @@
#include "dss.h"
#include "dss_features.h"
+#define HDMI_IRQ_LINK_CONNECT (1 << 25)
+#define HDMI_IRQ_LINK_DISCONNECT (1 << 26)
+
static inline void hdmi_write_reg(void __iomem *base_addr,
const u16 idx, u32 val)
{
@@ -233,37 +235,39 @@ void ti_hdmi_4xxx_pll_disable(struct hdmi_ip_data *ip_data)
hdmi_set_pll_pwr(ip_data, HDMI_PLLPWRCMD_ALLOFF);
}
-static int hdmi_check_hpd_state(struct hdmi_ip_data *ip_data)
+static irqreturn_t hdmi_irq_handler(int irq, void *data)
{
- bool hpd;
- int r;
-
- mutex_lock(&ip_data->lock);
-
- hpd = gpio_get_value(ip_data->hpd_gpio);
+ struct hdmi_ip_data *ip_data = data;
+ void __iomem *wp_base = hdmi_wp_base(ip_data);
+ u32 irqstatus;
+
+ irqstatus = hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
+ hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS, irqstatus);
+ /* flush posted write */
+ hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
+
+ if ((irqstatus & HDMI_IRQ_LINK_CONNECT) &&
+ irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
+ /*
+ * If we get both connect and disconnect interrupts at the same
+ * time, turn off the PHY, clear interrupts, and restart, which
+ * raises connect interrupt if a cable is connected, or nothing
+ * if cable is not connected.
+ */
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
- if (hpd)
- r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
- else
- r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
+ hdmi_write_reg(wp_base, HDMI_WP_IRQSTATUS,
+ HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
+ /* flush posted write */
+ hdmi_read_reg(wp_base, HDMI_WP_IRQSTATUS);
- if (r) {
- DSSERR("Failed to %s PHY TX power\n",
- hpd ? "enable" : "disable");
- goto err;
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
+ } else if (irqstatus & HDMI_IRQ_LINK_CONNECT) {
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_TXON);
+ } else if (irqstatus & HDMI_IRQ_LINK_DISCONNECT) {
+ hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
}
-err:
- mutex_unlock(&ip_data->lock);
- return r;
-}
-
-static irqreturn_t hpd_irq_handler(int irq, void *data)
-{
- struct hdmi_ip_data *ip_data = data;
-
- hdmi_check_hpd_state(ip_data);
-
return IRQ_HANDLED;
}
@@ -272,6 +276,12 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
u16 r = 0;
void __iomem *phy_base = hdmi_phy_base(ip_data);
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_CLR,
+ 0xffffffff);
+
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQSTATUS,
+ HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
+
r = hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_LDOON);
if (r)
return r;
@@ -297,29 +307,23 @@ int ti_hdmi_4xxx_phy_enable(struct hdmi_ip_data *ip_data)
/* Write to phy address 3 to change the polarity control */
REG_FLD_MOD(phy_base, HDMI_TXPHY_PAD_CFG_CTRL, 0x1, 27, 27);
- r = request_threaded_irq(gpio_to_irq(ip_data->hpd_gpio),
- NULL, hpd_irq_handler,
- IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING |
- IRQF_ONESHOT, "hpd", ip_data);
+ r = request_threaded_irq(ip_data->irq, NULL, hdmi_irq_handler,
+ IRQF_ONESHOT, "OMAP HDMI", ip_data);
if (r) {
- DSSERR("HPD IRQ request failed\n");
+ DSSERR("HDMI IRQ request failed\n");
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
return r;
}
- r = hdmi_check_hpd_state(ip_data);
- if (r) {
- free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
- hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
- return r;
- }
+ hdmi_write_reg(hdmi_wp_base(ip_data), HDMI_WP_IRQENABLE_SET,
+ HDMI_IRQ_LINK_CONNECT | HDMI_IRQ_LINK_DISCONNECT);
return 0;
}
void ti_hdmi_4xxx_phy_disable(struct hdmi_ip_data *ip_data)
{
- free_irq(gpio_to_irq(ip_data->hpd_gpio), ip_data);
+ free_irq(ip_data->irq, ip_data);
hdmi_set_phy_pwr(ip_data, HDMI_PHYPWRCMD_OFF);
}
@@ -476,11 +480,6 @@ int ti_hdmi_4xxx_read_edid(struct hdmi_ip_data *ip_data,
return l;
}
-bool ti_hdmi_4xxx_detect(struct hdmi_ip_data *ip_data)
-{
- return gpio_get_value(ip_data->hpd_gpio);
-}
-
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
struct hdmi_core_infoframe_avi *avi_cfg,
struct hdmi_core_packet_enable_repeat *repeat_cfg)
diff --git a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
index 8366ae19e82..6ef2f929a76 100644
--- a/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
+++ b/drivers/video/omap2/dss/ti_hdmi_4xxx_ip.h
@@ -33,6 +33,7 @@
#define HDMI_WP_IRQSTATUS 0x28
#define HDMI_WP_PWR_CTRL 0x40
#define HDMI_WP_IRQENABLE_SET 0x2C
+#define HDMI_WP_IRQENABLE_CLR 0x30
#define HDMI_WP_VIDEO_CFG 0x50
#define HDMI_WP_VIDEO_SIZE 0x60
#define HDMI_WP_VIDEO_TIMING_H 0x68
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
index 74fdb3ee209..496a106fe82 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/omap2/dss/venc.c
@@ -304,7 +304,7 @@ static struct {
enum omap_dss_venc_type type;
bool invert_polarity;
- struct omap_dss_output output;
+ struct omap_dss_device output;
} venc;
static inline void venc_write_reg(int idx, u32 val)
@@ -429,7 +429,7 @@ static const struct venc_config *venc_timings_to_config(
static int venc_power_on(struct omap_dss_device *dssdev)
{
- struct omap_overlay_manager *mgr = dssdev->output->manager;
+ struct omap_overlay_manager *mgr = venc.output.manager;
u32 l;
int r;
@@ -480,7 +480,7 @@ err0:
static void venc_power_off(struct omap_dss_device *dssdev)
{
- struct omap_overlay_manager *mgr = dssdev->output->manager;
+ struct omap_overlay_manager *mgr = venc.output.manager;
venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0);
@@ -492,15 +492,9 @@ static void venc_power_off(struct omap_dss_device *dssdev)
venc_runtime_put();
}
-unsigned long venc_get_pixel_clock(void)
-{
- /* VENC Pixel Clock in Mhz */
- return 13500000;
-}
-
int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
{
- struct omap_dss_output *out = dssdev->output;
+ struct omap_dss_device *out = &venc.output;
int r;
DSSDBG("venc_display_enable\n");
@@ -513,23 +507,15 @@ int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
goto err0;
}
- r = omap_dss_start_device(dssdev);
- if (r) {
- DSSERR("failed to start device\n");
- goto err0;
- }
-
r = venc_power_on(dssdev);
if (r)
- goto err1;
+ goto err0;
venc.wss_data = 0;
mutex_unlock(&venc.venc_lock);
return 0;
-err1:
- omap_dss_stop_device(dssdev);
err0:
mutex_unlock(&venc.venc_lock);
return r;
@@ -543,8 +529,6 @@ void omapdss_venc_display_disable(struct omap_dss_device *dssdev)
venc_power_off(dssdev);
- omap_dss_stop_device(dssdev);
-
mutex_unlock(&venc.venc_lock);
}
@@ -561,6 +545,8 @@ void omapdss_venc_set_timings(struct omap_dss_device *dssdev,
venc.timings = *timings;
+ dispc_set_tv_pclk(13500000);
+
mutex_unlock(&venc.venc_lock);
}
@@ -578,6 +564,16 @@ int omapdss_venc_check_timings(struct omap_dss_device *dssdev,
return -EINVAL;
}
+static void venc_get_timings(struct omap_dss_device *dssdev,
+ struct omap_video_timings *timings)
+{
+ mutex_lock(&venc.venc_lock);
+
+ *timings = venc.timings;
+
+ mutex_unlock(&venc.venc_lock);
+}
+
u32 omapdss_venc_get_wss(struct omap_dss_device *dssdev)
{
/* Invert due to VENC_L21_WC_CTL:INV=1 */
@@ -633,23 +629,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");
-
- if (venc.vdda_dac_reg == NULL) {
- struct regulator *vdda_dac;
+ 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 +760,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",
@@ -797,24 +789,87 @@ static int venc_probe_pdata(struct platform_device *vencdev)
return 0;
}
+static int venc_connect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ struct omap_overlay_manager *mgr;
+ int r;
+
+ r = venc_init_regulator();
+ if (r)
+ return r;
+
+ mgr = omap_dss_get_overlay_manager(dssdev->dispc_channel);
+ if (!mgr)
+ return -ENODEV;
+
+ r = dss_mgr_connect(mgr, dssdev);
+ if (r)
+ return r;
+
+ r = omapdss_output_set_device(dssdev, dst);
+ if (r) {
+ DSSERR("failed to connect output to new device: %s\n",
+ dst->name);
+ dss_mgr_disconnect(mgr, dssdev);
+ return r;
+ }
+
+ return 0;
+}
+
+static void venc_disconnect(struct omap_dss_device *dssdev,
+ struct omap_dss_device *dst)
+{
+ WARN_ON(dst != dssdev->device);
+
+ if (dst != dssdev->device)
+ return;
+
+ omapdss_output_unset_device(dssdev);
+
+ if (dssdev->manager)
+ dss_mgr_disconnect(dssdev->manager, dssdev);
+}
+
+static const struct omapdss_atv_ops venc_ops = {
+ .connect = venc_connect,
+ .disconnect = venc_disconnect,
+
+ .enable = omapdss_venc_display_enable,
+ .disable = omapdss_venc_display_disable,
+
+ .check_timings = omapdss_venc_check_timings,
+ .set_timings = omapdss_venc_set_timings,
+ .get_timings = venc_get_timings,
+
+ .set_type = omapdss_venc_set_type,
+ .invert_vid_out_polarity = omapdss_venc_invert_vid_out_polarity,
+
+ .set_wss = omapdss_venc_set_wss,
+ .get_wss = omapdss_venc_get_wss,
+};
+
static void venc_init_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &venc.output;
+ struct omap_dss_device *out = &venc.output;
- out->pdev = pdev;
+ out->dev = &pdev->dev;
out->id = OMAP_DSS_OUTPUT_VENC;
- out->type = OMAP_DISPLAY_TYPE_VENC;
+ out->output_type = OMAP_DISPLAY_TYPE_VENC;
out->name = "venc.0";
out->dispc_channel = OMAP_DSS_CHANNEL_DIGIT;
+ out->ops.atv = &venc_ops;
+ out->owner = THIS_MODULE;
- dss_register_output(out);
+ omapdss_register_output(out);
}
static void __exit venc_uninit_output(struct platform_device *pdev)
{
- struct omap_dss_output *out = &venc.output;
+ struct omap_dss_device *out = &venc.output;
- dss_unregister_output(out);
+ omapdss_unregister_output(out);
}
/* VENC HW IP initialisation */
@@ -866,16 +921,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);
@@ -886,11 +942,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);
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/omap2/dss/venc_panel.c
index 0d2b1a0834a..f7d92c57bd7 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/omap2/dss/venc_panel.c
@@ -107,19 +107,19 @@ static int venc_panel_probe(struct omap_dss_device *dssdev)
dssdev->panel.timings = default_timings;
- return device_create_file(&dssdev->dev, &dev_attr_output_type);
+ return device_create_file(dssdev->dev, &dev_attr_output_type);
}
static void venc_panel_remove(struct omap_dss_device *dssdev)
{
- device_remove_file(&dssdev->dev, &dev_attr_output_type);
+ device_remove_file(dssdev->dev, &dev_attr_output_type);
}
static int venc_panel_enable(struct omap_dss_device *dssdev)
{
int r;
- dev_dbg(&dssdev->dev, "venc_panel_enable\n");
+ dev_dbg(dssdev->dev, "venc_panel_enable\n");
mutex_lock(&venc_panel.lock);
@@ -150,7 +150,7 @@ err:
static void venc_panel_disable(struct omap_dss_device *dssdev)
{
- dev_dbg(&dssdev->dev, "venc_panel_disable\n");
+ dev_dbg(dssdev->dev, "venc_panel_disable\n");
mutex_lock(&venc_panel.lock);
@@ -167,7 +167,7 @@ end:
static void venc_panel_set_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- dev_dbg(&dssdev->dev, "venc_panel_set_timings\n");
+ dev_dbg(dssdev->dev, "venc_panel_set_timings\n");
mutex_lock(&venc_panel.lock);
@@ -180,21 +180,21 @@ static void venc_panel_set_timings(struct omap_dss_device *dssdev,
static int venc_panel_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings)
{
- dev_dbg(&dssdev->dev, "venc_panel_check_timings\n");
+ dev_dbg(dssdev->dev, "venc_panel_check_timings\n");
return omapdss_venc_check_timings(dssdev, timings);
}
static u32 venc_panel_get_wss(struct omap_dss_device *dssdev)
{
- dev_dbg(&dssdev->dev, "venc_panel_get_wss\n");
+ dev_dbg(dssdev->dev, "venc_panel_get_wss\n");
return omapdss_venc_get_wss(dssdev);
}
static int venc_panel_set_wss(struct omap_dss_device *dssdev, u32 wss)
{
- dev_dbg(&dssdev->dev, "venc_panel_set_wss\n");
+ dev_dbg(dssdev->dev, "venc_panel_set_wss\n");
return omapdss_venc_set_wss(dssdev, wss);
}