Commit 866f0956 authored by Tomi Valkeinen's avatar Tomi Valkeinen

Merge branch 'archit/outputs-for-3.7'

Merge omapdss output work, that creates a new entity "output" to represent the
outputs (DPI, DSI, HDMI, ...) from DSS. An output sits in between an overlay
manager and a panel, and helps us to remove references to panel devices from
the omapdss core.

* archit/outputs-for-3.7: (23 commits)
  OMAPDSS: Remove old way of setting manager and device links
  OMAPDSS: APPLY: Remove omap_dss_device references from dss_ovl_enable/disable
  OMAPDSS: OVERLAY/MANAGER: Get device via output
  OMAPDSS: MANAGER: Update display sysfs store
  OMAPFB: Change dssdev->manager references
  OMAPDSS: HDMI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: VENC: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: RFBI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: SDI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: DSI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: DSI: Remove dsi_pdev_map global struct
  OMAPDSS: DPI: Replace dssdev->manager with dssdev->output->manager references
  OMAPDSS: Create links between managers, outputs and devices
  OMAPDRM: Remove manager->device references
  OMAPFB: remove manager->device references
  OMAP_VOUT: Remove manager->device references
  OMAPDSS: Remove manager->device references
  OMAPDSS: APPLY: Add manager set/unset output ops for omap_overlay_manager
  OMAPDSS: output: Add set/unset device ops for omap_dss_output
  OMAPDSS: outputs: Create and register output instances
  ...
parents e84dc1cc 3c2995ac
...@@ -454,11 +454,15 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr) ...@@ -454,11 +454,15 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
win = &vout->win; win = &vout->win;
for (i = 0; i < ovid->num_overlays; i++) { for (i = 0; i < ovid->num_overlays; i++) {
struct omap_dss_device *dssdev;
ovl = ovid->overlays[i]; ovl = ovid->overlays[i];
if (!ovl->manager || !ovl->manager->device) dssdev = ovl->get_device(ovl);
if (!dssdev)
return -EINVAL; return -EINVAL;
timing = &ovl->manager->device->panel.timings; timing = &dssdev->panel.timings;
outw = win->w.width; outw = win->w.width;
outh = win->w.height; outh = win->w.height;
...@@ -515,8 +519,11 @@ static int omapvid_apply_changes(struct omap_vout_device *vout) ...@@ -515,8 +519,11 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
struct omapvideo_info *ovid = &vout->vid_info; struct omapvideo_info *ovid = &vout->vid_info;
for (i = 0; i < ovid->num_overlays; i++) { for (i = 0; i < ovid->num_overlays; i++) {
struct omap_dss_device *dssdev;
ovl = ovid->overlays[i]; ovl = ovid->overlays[i];
if (!ovl->manager || !ovl->manager->device) dssdev = ovl->get_device(ovl);
if (!dssdev)
return -EINVAL; return -EINVAL;
ovl->manager->apply(ovl->manager); ovl->manager->apply(ovl->manager);
} }
...@@ -579,12 +586,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus) ...@@ -579,12 +586,14 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
ovid = &vout->vid_info; ovid = &vout->vid_info;
ovl = ovid->overlays[0]; ovl = ovid->overlays[0];
/* get the display device attached to the overlay */
if (!ovl->manager || !ovl->manager->device)
return;
mgr_id = ovl->manager->id; mgr_id = ovl->manager->id;
cur_display = ovl->manager->device;
/* get the display device attached to the overlay */
cur_display = ovl->get_device(ovl);
if (!cur_display)
return;
spin_lock(&vout->vbq_lock); spin_lock(&vout->vbq_lock);
do_gettimeofday(&timevalue); do_gettimeofday(&timevalue);
...@@ -948,7 +957,9 @@ static int omap_vout_release(struct file *file) ...@@ -948,7 +957,9 @@ static int omap_vout_release(struct file *file)
/* Disable all the overlay managers connected with this interface */ /* Disable all the overlay managers connected with this interface */
for (i = 0; i < ovid->num_overlays; i++) { for (i = 0; i < ovid->num_overlays; i++) {
struct omap_overlay *ovl = ovid->overlays[i]; struct omap_overlay *ovl = ovid->overlays[i];
if (ovl->manager && ovl->manager->device) struct omap_dss_device *dssdev = ovl->get_device(ovl);
if (dssdev)
ovl->disable(ovl); ovl->disable(ovl);
} }
/* Turn off the pipeline */ /* Turn off the pipeline */
...@@ -1081,14 +1092,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh, ...@@ -1081,14 +1092,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
struct omapvideo_info *ovid; struct omapvideo_info *ovid;
struct omap_video_timings *timing; struct omap_video_timings *timing;
struct omap_vout_device *vout = fh; struct omap_vout_device *vout = fh;
struct omap_dss_device *dssdev;
ovid = &vout->vid_info; ovid = &vout->vid_info;
ovl = ovid->overlays[0]; ovl = ovid->overlays[0];
/* get the display device attached to the overlay */
dssdev = ovl->get_device(ovl);
if (!ovl->manager || !ovl->manager->device) if (!dssdev)
return -EINVAL; return -EINVAL;
/* get the display device attached to the overlay */
timing = &ovl->manager->device->panel.timings; timing = &dssdev->panel.timings;
vout->fbuf.fmt.height = timing->y_res; vout->fbuf.fmt.height = timing->y_res;
vout->fbuf.fmt.width = timing->x_res; vout->fbuf.fmt.width = timing->x_res;
...@@ -1105,6 +1119,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh, ...@@ -1105,6 +1119,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
struct omapvideo_info *ovid; struct omapvideo_info *ovid;
struct omap_video_timings *timing; struct omap_video_timings *timing;
struct omap_vout_device *vout = fh; struct omap_vout_device *vout = fh;
struct omap_dss_device *dssdev;
if (vout->streaming) if (vout->streaming)
return -EBUSY; return -EBUSY;
...@@ -1113,13 +1128,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh, ...@@ -1113,13 +1128,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
ovid = &vout->vid_info; ovid = &vout->vid_info;
ovl = ovid->overlays[0]; ovl = ovid->overlays[0];
dssdev = ovl->get_device(ovl);
/* get the display device attached to the overlay */ /* get the display device attached to the overlay */
if (!ovl->manager || !ovl->manager->device) { if (!dssdev) {
ret = -EINVAL; ret = -EINVAL;
goto s_fmt_vid_out_exit; goto s_fmt_vid_out_exit;
} }
timing = &ovl->manager->device->panel.timings; timing = &dssdev->panel.timings;
/* We dont support RGB24-packed mode if vrfb rotation /* We dont support RGB24-packed mode if vrfb rotation
* is enabled*/ * is enabled*/
...@@ -1298,6 +1314,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) ...@@ -1298,6 +1314,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
struct omapvideo_info *ovid; struct omapvideo_info *ovid;
struct omap_overlay *ovl; struct omap_overlay *ovl;
struct omap_video_timings *timing; struct omap_video_timings *timing;
struct omap_dss_device *dssdev;
if (vout->streaming) if (vout->streaming)
return -EBUSY; return -EBUSY;
...@@ -1305,13 +1322,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop) ...@@ -1305,13 +1322,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
mutex_lock(&vout->lock); mutex_lock(&vout->lock);
ovid = &vout->vid_info; ovid = &vout->vid_info;
ovl = ovid->overlays[0]; ovl = ovid->overlays[0];
/* get the display device attached to the overlay */
dssdev = ovl->get_device(ovl);
if (!ovl->manager || !ovl->manager->device) { if (!dssdev) {
ret = -EINVAL; ret = -EINVAL;
goto s_crop_err; goto s_crop_err;
} }
/* get the display device attached to the overlay */
timing = &ovl->manager->device->panel.timings; timing = &dssdev->panel.timings;
if (is_rotation_90_or_270(vout)) { if (is_rotation_90_or_270(vout)) {
vout->fbuf.fmt.height = timing->x_res; vout->fbuf.fmt.height = timing->x_res;
...@@ -1667,7 +1686,7 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) ...@@ -1667,7 +1686,7 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) { for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j]; struct omap_overlay *ovl = ovid->overlays[j];
if (ovl->manager && ovl->manager->device) { if (ovl->get_device(ovl)) {
struct omap_overlay_info info; struct omap_overlay_info info;
ovl->get_overlay_info(ovl, &info); ovl->get_overlay_info(ovl, &info);
info.paddr = addr; info.paddr = addr;
...@@ -1690,8 +1709,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i) ...@@ -1690,8 +1709,9 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) { for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j]; struct omap_overlay *ovl = ovid->overlays[j];
struct omap_dss_device *dssdev = ovl->get_device(ovl);
if (ovl->manager && ovl->manager->device) { if (dssdev) {
ret = ovl->enable(ovl); ret = ovl->enable(ovl);
if (ret) if (ret)
goto streamon_err1; goto streamon_err1;
...@@ -1726,8 +1746,9 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i) ...@@ -1726,8 +1746,9 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
for (j = 0; j < ovid->num_overlays; j++) { for (j = 0; j < ovid->num_overlays; j++) {
struct omap_overlay *ovl = ovid->overlays[j]; struct omap_overlay *ovl = ovid->overlays[j];
struct omap_dss_device *dssdev = ovl->get_device(ovl);
if (ovl->manager && ovl->manager->device) if (dssdev)
ovl->disable(ovl); ovl->disable(ovl);
} }
...@@ -1890,8 +1911,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout) ...@@ -1890,8 +1911,8 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
struct video_device *vfd; struct video_device *vfd;
struct v4l2_pix_format *pix; struct v4l2_pix_format *pix;
struct v4l2_control *control; struct v4l2_control *control;
struct omap_dss_device *display = struct omap_overlay *ovl = vout->vid_info.overlays[0];
vout->vid_info.overlays[0]->manager->device; struct omap_dss_device *display = ovl->get_device(ovl);
/* set the default pix */ /* set the default pix */
pix = &vout->pix; pix = &vout->pix;
...@@ -2205,8 +2226,10 @@ static int __init omap_vout_probe(struct platform_device *pdev) ...@@ -2205,8 +2226,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
*/ */
for (i = 1; i < vid_dev->num_overlays; i++) { for (i = 1; i < vid_dev->num_overlays; i++) {
ovl = omap_dss_get_overlay(i); ovl = omap_dss_get_overlay(i);
if (ovl->manager && ovl->manager->device) { dssdev = ovl->get_device(ovl);
def_display = ovl->manager->device;
if (dssdev) {
def_display = dssdev;
} else { } else {
dev_warn(&pdev->dev, "cannot find display\n"); dev_warn(&pdev->dev, "cannot find display\n");
def_display = NULL; def_display = NULL;
...@@ -2253,8 +2276,10 @@ static int __init omap_vout_probe(struct platform_device *pdev) ...@@ -2253,8 +2276,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
for (i = 1; i < vid_dev->num_overlays; i++) { for (i = 1; i < vid_dev->num_overlays; i++) {
def_display = NULL; def_display = NULL;
ovl = omap_dss_get_overlay(i); ovl = omap_dss_get_overlay(i);
if (ovl->manager && ovl->manager->device) dssdev = ovl->get_device(ovl);
def_display = ovl->manager->device;
if (dssdev)
def_display = dssdev;
if (def_display && def_display->driver) if (def_display && def_display->driver)
def_display->driver->disable(def_display); def_display->driver->disable(def_display);
......
...@@ -106,7 +106,8 @@ static void dump_video_chains(void) ...@@ -106,7 +106,8 @@ static void dump_video_chains(void)
for (i = 0; i < omap_dss_get_num_overlays(); i++) { for (i = 0; i < omap_dss_get_num_overlays(); i++) {
struct omap_overlay *ovl = omap_dss_get_overlay(i); struct omap_overlay *ovl = omap_dss_get_overlay(i);
struct omap_overlay_manager *mgr = ovl->manager; struct omap_overlay_manager *mgr = ovl->manager;
struct omap_dss_device *dssdev = mgr ? mgr->device : NULL; struct omap_dss_device *dssdev = mgr ?
mgr->get_device(mgr) : NULL;
if (dssdev) { if (dssdev) {
DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name, DBG("%d: %s -> %s -> %s", i, ovl->name, mgr->name,
dssdev->name); dssdev->name);
...@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev, ...@@ -185,7 +186,7 @@ static int create_connector(struct drm_device *dev,
for (j = 0; j < priv->num_encoders; j++) { for (j = 0; j < priv->num_encoders; j++) {
struct omap_overlay_manager *mgr = struct omap_overlay_manager *mgr =
omap_encoder_get_manager(priv->encoders[j]); omap_encoder_get_manager(priv->encoders[j]);
if (mgr->device == dssdev) { if (mgr->get_device(mgr) == dssdev) {
drm_mode_connector_attach_encoder(connector, drm_mode_connector_attach_encoder(connector,
priv->encoders[j]); priv->encoders[j]);
} }
......
obj-$(CONFIG_OMAP2_DSS) += omapdss.o obj-$(CONFIG_OMAP2_DSS) += omapdss.o
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \ omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
manager.o manager-sysfs.o overlay.o overlay-sysfs.o apply.o manager.o manager-sysfs.o overlay.o overlay-sysfs.o output.o apply.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o venc_panel.o
......
...@@ -421,17 +421,25 @@ static void wait_pending_extra_info_updates(void) ...@@ -421,17 +421,25 @@ static void wait_pending_extra_info_updates(void)
int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
{ {
unsigned long timeout = msecs_to_jiffies(500); unsigned long timeout = msecs_to_jiffies(500);
struct mgr_priv_data *mp; struct mgr_priv_data *mp = get_mgr_priv(mgr);
u32 irq; u32 irq;
unsigned long flags;
int r; int r;
int i; int i;
struct omap_dss_device *dssdev = mgr->device;
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) spin_lock_irqsave(&data_lock, flags);
if (mgr_manual_update(mgr)) {
spin_unlock_irqrestore(&data_lock, flags);
return 0; return 0;
}
if (mgr_manual_update(mgr)) if (!mp->enabled) {
spin_unlock_irqrestore(&data_lock, flags);
return 0; return 0;
}
spin_unlock_irqrestore(&data_lock, flags);
r = dispc_runtime_get(); r = dispc_runtime_get();
if (r) if (r)
...@@ -439,10 +447,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr) ...@@ -439,10 +447,8 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
irq = dispc_mgr_get_vsync_irq(mgr->id); irq = dispc_mgr_get_vsync_irq(mgr->id);
mp = get_mgr_priv(mgr);
i = 0; i = 0;
while (1) { while (1) {
unsigned long flags;
bool shadow_dirty, dirty; bool shadow_dirty, dirty;
spin_lock_irqsave(&data_lock, flags); spin_lock_irqsave(&data_lock, flags);
...@@ -486,21 +492,30 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) ...@@ -486,21 +492,30 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
{ {
unsigned long timeout = msecs_to_jiffies(500); unsigned long timeout = msecs_to_jiffies(500);
struct ovl_priv_data *op; struct ovl_priv_data *op;
struct omap_dss_device *dssdev; struct mgr_priv_data *mp;
u32 irq; u32 irq;
unsigned long flags;
int r; int r;
int i; int i;
if (!ovl->manager) if (!ovl->manager)
return 0; return 0;
dssdev = ovl->manager->device; mp = get_mgr_priv(ovl->manager);
spin_lock_irqsave(&data_lock, flags);
if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE) if (ovl_manual_update(ovl)) {
spin_unlock_irqrestore(&data_lock, flags);
return 0; return 0;
}
if (ovl_manual_update(ovl)) if (!mp->enabled) {
spin_unlock_irqrestore(&data_lock, flags);
return 0; return 0;
}
spin_unlock_irqrestore(&data_lock, flags);
r = dispc_runtime_get(); r = dispc_runtime_get();
if (r) if (r)
...@@ -511,7 +526,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl) ...@@ -511,7 +526,6 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
op = get_ovl_priv(ovl); op = get_ovl_priv(ovl);
i = 0; i = 0;
while (1) { while (1) {
unsigned long flags;
bool shadow_dirty, dirty; bool shadow_dirty, dirty;
spin_lock_irqsave(&data_lock, flags); spin_lock_irqsave(&data_lock, flags);
...@@ -1096,29 +1110,29 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr, ...@@ -1096,29 +1110,29 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
spin_unlock_irqrestore(&data_lock, flags); spin_unlock_irqrestore(&data_lock, flags);
} }
int dss_mgr_set_device(struct omap_overlay_manager *mgr, int dss_mgr_set_output(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev) struct omap_dss_output *output)
{ {
int r; int r;
mutex_lock(&apply_lock); mutex_lock(&apply_lock);
if (dssdev->manager) { if (mgr->output) {
DSSERR("display '%s' already has a manager '%s'\n", DSSERR("manager %s is already connected to an output\n",
dssdev->name, dssdev->manager->name); mgr->name);
r = -EINVAL; r = -EINVAL;
goto err; goto err;
} }
if ((mgr->supported_displays & dssdev->type) == 0) { if ((mgr->supported_outputs & output->id) == 0) {
DSSERR("display '%s' does not support manager '%s'\n", DSSERR("output does not support manager %s\n",
dssdev->name, mgr->name); mgr->name);
r = -EINVAL; r = -EINVAL;
goto err; goto err;
} }
dssdev->manager = mgr; output->manager = mgr;
mgr->device = dssdev; mgr->output = output;
mutex_unlock(&apply_lock); mutex_unlock(&apply_lock);
...@@ -1128,35 +1142,41 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr, ...@@ -1128,35 +1142,41 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
return r; return r;
} }
int dss_mgr_unset_device(struct omap_overlay_manager *mgr) int dss_mgr_unset_output(struct omap_overlay_manager *mgr)
{ {
int r; int r;
struct mgr_priv_data *mp = get_mgr_priv(mgr);
unsigned long flags;
mutex_lock(&apply_lock); mutex_lock(&apply_lock);
if (!mgr->device) { if (!mgr->output) {
DSSERR("failed to unset display, display not set.\n"); DSSERR("failed to unset output, output not set\n");
r = -EINVAL; r = -EINVAL;
goto err; goto err;
} }
/* spin_lock_irqsave(&data_lock, flags);
* Don't allow currently enabled displays to have the overlay manager
* pulled out from underneath them if (mp->enabled) {
*/ DSSERR("output can't be unset when manager is enabled\n");
if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
r = -EINVAL; r = -EINVAL;
goto err; goto err1;
} }
mgr->device->manager = NULL; spin_unlock_irqrestore(&data_lock, flags);
mgr->device = NULL;
mgr->output->manager = NULL;
mgr->output = NULL;
mutex_unlock(&apply_lock); mutex_unlock(&apply_lock);
return 0; return 0;
err1:
spin_unlock_irqrestore(&data_lock, flags);
err: err:
mutex_unlock(&apply_lock); mutex_unlock(&apply_lock);
return r; return r;
} }
...@@ -1380,7 +1400,7 @@ int dss_ovl_enable(struct omap_overlay *ovl) ...@@ -1380,7 +1400,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
goto err1; goto err1;
} }
if (ovl->manager == NULL || ovl->manager->device == NULL) { if (ovl->manager == NULL || ovl->manager->output == NULL) {
r = -EINVAL; r = -EINVAL;
goto err1; goto err1;
} }
...@@ -1430,7 +1450,7 @@ int dss_ovl_disable(struct omap_overlay *ovl) ...@@ -1430,7 +1450,7 @@ int dss_ovl_disable(struct omap_overlay *ovl)
goto err; goto err;
} }
if (ovl->manager == NULL || ovl->manager->device == NULL) { if (ovl->manager == NULL || ovl->manager->output == NULL) {
r = -EINVAL; r = -EINVAL;
goto err; goto err;
} }
......
...@@ -3595,7 +3595,7 @@ static void dispc_error_worker(struct work_struct *work) ...@@ -3595,7 +3595,7 @@ static void dispc_error_worker(struct work_struct *work)
bit = mgr_desc[i].sync_lost_irq; bit = mgr_desc[i].sync_lost_irq;
if (bit & errors) { if (bit & errors) {
struct omap_dss_device *dssdev = mgr->device; struct omap_dss_device *dssdev = mgr->get_device(mgr);
bool enable; bool enable;
DSSERR("SYNC_LOST on channel %s, restarting the output " DSSERR("SYNC_LOST on channel %s, restarting the output "
...@@ -3626,9 +3626,13 @@ static void dispc_error_worker(struct work_struct *work) ...@@ -3626,9 +3626,13 @@ static void dispc_error_worker(struct work_struct *work)
DSSERR("OCP_ERR\n"); DSSERR("OCP_ERR\n");
for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) { for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
struct omap_overlay_manager *mgr; struct omap_overlay_manager *mgr;
struct omap_dss_device *dssdev;
mgr = omap_dss_get_overlay_manager(i); mgr = omap_dss_get_overlay_manager(i);
if (mgr->device && mgr->device->driver) dssdev = mgr->get_device(mgr);
mgr->device->driver->disable(mgr->device);
if (dssdev && dssdev->driver)
dssdev->driver->disable(dssdev);
} }
} }
......
...@@ -327,22 +327,35 @@ EXPORT_SYMBOL(omapdss_default_get_timings); ...@@ -327,22 +327,35 @@ EXPORT_SYMBOL(omapdss_default_get_timings);
*/ */
static int dss_init_connections(struct omap_dss_device *dssdev, bool force) static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
{ {
struct omap_dss_output *out;
struct omap_overlay_manager *mgr; struct omap_overlay_manager *mgr;
int i, r; int i, r;
WARN_ON(dssdev->manager); out = omapdss_get_output_from_dssdev(dssdev);
WARN_ON(dssdev->output);
WARN_ON(out->device);
r = omapdss_output_set_device(out, dssdev);
if (r) {
DSSERR("failed to connect output to new device\n");
return r;
}
mgr = omap_dss_get_overlay_manager(dssdev->channel); mgr = omap_dss_get_overlay_manager(dssdev->channel);
if (mgr->device && !force) if (mgr->output && !force)
return 0; return 0;
if (mgr->device) if (mgr->output)
mgr->unset_device(mgr); mgr->unset_output(mgr);
r = mgr->set_device(mgr, dssdev); r = mgr->set_output(mgr, out);
if (r) { if (r) {
DSSERR("failed to set initial manager\n"); DSSERR("failed to connect manager to output of new device\n");
/* remove the output-device connection we just made */
omapdss_output_unset_device(out);
return r; return r;
} }
...@@ -366,8 +379,14 @@ static int dss_init_connections(struct omap_dss_device *dssdev, bool force) ...@@ -366,8 +379,14 @@ static int dss_init_connections(struct omap_dss_device *dssdev, bool force)
static void dss_uninit_connections(struct omap_dss_device *dssdev) static void dss_uninit_connections(struct omap_dss_device *dssdev)
{ {
if (dssdev->manager) if (dssdev->output) {
dssdev->manager->unset_device(dssdev->manager); struct omap_overlay_manager *mgr = dssdev->output->manager;
if (mgr)
mgr->unset_output(mgr);
omapdss_output_unset_device(dssdev->output);
}
} }
int dss_init_device(struct platform_device *pdev, int dss_init_device(struct platform_device *pdev,
......
...@@ -44,6 +44,8 @@ static struct { ...@@ -44,6 +44,8 @@ static struct {
struct omap_video_timings timings; struct omap_video_timings timings;
struct dss_lcd_mgr_config mgr_config; struct dss_lcd_mgr_config mgr_config;
int data_lines; int data_lines;
struct omap_dss_output output;
} dpi; } dpi;
static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk) static struct platform_device *dpi_get_dsidev(enum omap_dss_clk_source clk)
...@@ -126,6 +128,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev, ...@@ -126,6 +128,7 @@ static int dpi_set_dispc_clk(struct omap_dss_device *dssdev,
static int dpi_set_mode(struct omap_dss_device *dssdev) static int dpi_set_mode(struct omap_dss_device *dssdev)
{ {
struct omap_video_timings *t = &dpi.timings; struct omap_video_timings *t = &dpi.timings;
struct omap_overlay_manager *mgr = dssdev->output->manager;
int lck_div = 0, pck_div = 0; int lck_div = 0, pck_div = 0;
unsigned long fck = 0; unsigned long fck = 0;
unsigned long pck; unsigned long pck;
...@@ -150,13 +153,15 @@ static int dpi_set_mode(struct omap_dss_device *dssdev) ...@@ -150,13 +153,15 @@ static int dpi_set_mode(struct omap_dss_device *dssdev)
t->pixel_clock = pck; t->pixel_clock = pck;
} }
dss_mgr_set_timings(dssdev->manager, t); dss_mgr_set_timings(mgr, t);
return 0; return 0;
} }
static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager;
dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; dpi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
dpi.mgr_config.stallmode = false; dpi.mgr_config.stallmode = false;
...@@ -166,11 +171,12 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev) ...@@ -166,11 +171,12 @@ static void dpi_config_lcd_manager(struct omap_dss_device *dssdev)
dpi.mgr_config.lcden_sig_polarity = 0; dpi.mgr_config.lcden_sig_polarity = 0;
dss_mgr_set_lcd_config(dssdev->manager, &dpi.mgr_config); dss_mgr_set_lcd_config(mgr, &dpi.mgr_config);
} }
int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output;
int r; int r;
mutex_lock(&dpi.lock); mutex_lock(&dpi.lock);
...@@ -181,10 +187,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) ...@@ -181,10 +187,10 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
goto err_no_reg; goto err_no_reg;
} }
if (dssdev->manager == NULL) { if (out == NULL || out->manager == NULL) {
DSSERR("failed to enable display: no manager\n"); DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV; r = -ENODEV;
goto err_no_mgr; goto err_no_out_mgr;
} }
r = omap_dss_start_device(dssdev); r = omap_dss_start_device(dssdev);
...@@ -225,7 +231,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) ...@@ -225,7 +231,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
mdelay(2); mdelay(2);
r = dss_mgr_enable(dssdev->manager); r = dss_mgr_enable(out->manager);
if (r) if (r)
goto err_mgr_enable; goto err_mgr_enable;
...@@ -249,7 +255,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev) ...@@ -249,7 +255,7 @@ int omapdss_dpi_display_enable(struct omap_dss_device *dssdev)
err_reg_enable: err_reg_enable:
omap_dss_stop_device(dssdev); omap_dss_stop_device(dssdev);
err_start_dev: err_start_dev:
err_no_mgr: err_no_out_mgr:
err_no_reg: err_no_reg:
mutex_unlock(&dpi.lock); mutex_unlock(&dpi.lock);
return r; return r;
...@@ -258,9 +264,11 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable); ...@@ -258,9 +264,11 @@ EXPORT_SYMBOL(omapdss_dpi_display_enable);
void omapdss_dpi_display_disable(struct omap_dss_device *dssdev) void omapdss_dpi_display_disable(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager;
mutex_lock(&dpi.lock); mutex_lock(&dpi.lock);
dss_mgr_disable(dssdev->manager); dss_mgr_disable(mgr);
if (dpi_use_dsi_pll(dssdev)) { if (dpi_use_dsi_pll(dssdev)) {
dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK); dss_select_dispc_clk_source(OMAP_DSS_CLK_SRC_FCK);
...@@ -296,12 +304,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev, ...@@ -296,12 +304,13 @@ int dpi_check_timings(struct omap_dss_device *dssdev,
struct omap_video_timings *timings) struct omap_video_timings *timings)
{ {
int r; int r;
struct omap_overlay_manager *mgr = dssdev->output->manager;
int lck_div, pck_div; int lck_div, pck_div;
unsigned long fck; unsigned long fck;
unsigned long pck; unsigned long pck;
struct dispc_clock_info dispc_cinfo; struct dispc_clock_info dispc_cinfo;
if (dss_mgr_check_timings(dssdev->manager, timings)) if (dss_mgr_check_timings(mgr, timings))
return -EINVAL; return -EINVAL;
if (timings->pixel_clock == 0) if (timings->pixel_clock == 0)
...@@ -436,10 +445,30 @@ static void __init dpi_probe_pdata(struct platform_device *dpidev) ...@@ -436,10 +445,30 @@ static void __init dpi_probe_pdata(struct platform_device *dpidev)
} }
} }
static void __init dpi_init_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &dpi.output;
out->pdev = pdev;
out->id = OMAP_DSS_OUTPUT_DPI;
out->type = OMAP_DISPLAY_TYPE_DPI;
dss_register_output(out);
}
static void __exit dpi_uninit_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &dpi.output;
dss_unregister_output(out);
}
static int __init omap_dpi_probe(struct platform_device *pdev) static int __init omap_dpi_probe(struct platform_device *pdev)
{ {
mutex_init(&dpi.lock); mutex_init(&dpi.lock);
dpi_init_output(pdev);
dpi_probe_pdata(pdev); dpi_probe_pdata(pdev);
return 0; return 0;
...@@ -449,6 +478,8 @@ static int __exit omap_dpi_remove(struct platform_device *pdev) ...@@ -449,6 +478,8 @@ static int __exit omap_dpi_remove(struct platform_device *pdev)
{ {
dss_unregister_child_devices(&pdev->dev); dss_unregister_child_devices(&pdev->dev);
dpi_uninit_output(pdev);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -209,6 +209,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr, ...@@ -209,6 +209,9 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
int dss_mgr_set_device(struct omap_overlay_manager *mgr, int dss_mgr_set_device(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev); struct omap_dss_device *dssdev);
int dss_mgr_unset_device(struct omap_overlay_manager *mgr); int dss_mgr_unset_device(struct omap_overlay_manager *mgr);
int dss_mgr_set_output(struct omap_overlay_manager *mgr,
struct omap_dss_output *output);
int dss_mgr_unset_output(struct omap_overlay_manager *mgr);
void dss_mgr_set_timings(struct omap_overlay_manager *mgr, void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
const struct omap_video_timings *timings); const struct omap_video_timings *timings);
void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr, void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
...@@ -226,6 +229,11 @@ int dss_ovl_set_manager(struct omap_overlay *ovl, ...@@ -226,6 +229,11 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
struct omap_overlay_manager *mgr); struct omap_overlay_manager *mgr);
int dss_ovl_unset_manager(struct omap_overlay *ovl); int dss_ovl_unset_manager(struct omap_overlay *ovl);
/* output */
void dss_register_output(struct omap_dss_output *out);
void dss_unregister_output(struct omap_dss_output *out);
struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev);
/* display */ /* display */
int dss_suspend_all_devices(void); int dss_suspend_all_devices(void);
int dss_resume_all_devices(void); int dss_resume_all_devices(void);
......
...@@ -47,6 +47,7 @@ struct omap_dss_features { ...@@ -47,6 +47,7 @@ struct omap_dss_features {
const int num_mgrs; const int num_mgrs;
const int num_ovls; const int num_ovls;
const enum omap_display_type *supported_displays; const enum omap_display_type *supported_displays;
const enum omap_dss_output_id *supported_outputs;
const enum omap_color_mode *supported_color_modes; const enum omap_color_mode *supported_color_modes;
const enum omap_overlay_caps *overlay_caps; const enum omap_overlay_caps *overlay_caps;
const char * const *clksrc_names; const char * const *clksrc_names;
...@@ -172,6 +173,63 @@ static const enum omap_display_type omap5_dss_supported_displays[] = { ...@@ -172,6 +173,63 @@ static const enum omap_display_type omap5_dss_supported_displays[] = {
OMAP_DISPLAY_TYPE_DSI, OMAP_DISPLAY_TYPE_DSI,
}; };
static const enum omap_dss_output_id omap2_dss_supported_outputs[] = {
/* OMAP_DSS_CHANNEL_LCD */
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI,
/* OMAP_DSS_CHANNEL_DIGIT */
OMAP_DSS_OUTPUT_VENC,
};
static const enum omap_dss_output_id omap3430_dss_supported_outputs[] = {
/* OMAP_DSS_CHANNEL_LCD */
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
OMAP_DSS_OUTPUT_SDI | OMAP_DSS_OUTPUT_DSI1,
/* OMAP_DSS_CHANNEL_DIGIT */
OMAP_DSS_OUTPUT_VENC,
};
static const enum omap_dss_output_id omap3630_dss_supported_outputs[] = {
/* OMAP_DSS_CHANNEL_LCD */
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
OMAP_DSS_OUTPUT_DSI1,
/* OMAP_DSS_CHANNEL_DIGIT */
OMAP_DSS_OUTPUT_VENC,
};
static const enum omap_dss_output_id omap4_dss_supported_outputs[] = {
/* OMAP_DSS_CHANNEL_LCD */
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
OMAP_DSS_OUTPUT_DSI1,
/* OMAP_DSS_CHANNEL_DIGIT */
OMAP_DSS_OUTPUT_VENC | OMAP_DSS_OUTPUT_HDMI |
OMAP_DSS_OUTPUT_DPI,
/* OMAP_DSS_CHANNEL_LCD2 */
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
OMAP_DSS_OUTPUT_DSI2,
};
static const enum omap_dss_output_id omap5_dss_supported_outputs[] = {
/* OMAP_DSS_CHANNEL_LCD */
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
OMAP_DSS_OUTPUT_DSI1 | OMAP_DSS_OUTPUT_DSI2,
/* OMAP_DSS_CHANNEL_DIGIT */
OMAP_DSS_OUTPUT_HDMI | OMAP_DSS_OUTPUT_DPI,
/* OMAP_DSS_CHANNEL_LCD2 */
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
OMAP_DSS_OUTPUT_DSI1,
/* OMAP_DSS_CHANNEL_LCD3 */
OMAP_DSS_OUTPUT_DPI | OMAP_DSS_OUTPUT_DBI |
OMAP_DSS_OUTPUT_DSI2,
};
static const enum omap_color_mode omap2_dss_supported_color_modes[] = { static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
/* OMAP_DSS_GFX */ /* OMAP_DSS_GFX */
OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 | OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
...@@ -554,6 +612,7 @@ static const struct omap_dss_features omap2_dss_features = { ...@@ -554,6 +612,7 @@ static const struct omap_dss_features omap2_dss_features = {
.num_mgrs = 2, .num_mgrs = 2,
.num_ovls = 3, .num_ovls = 3,
.supported_displays = omap2_dss_supported_displays, .supported_displays = omap2_dss_supported_displays,
.supported_outputs = omap2_dss_supported_outputs,
.supported_color_modes = omap2_dss_supported_color_modes, .supported_color_modes = omap2_dss_supported_color_modes,
.overlay_caps = omap2_dss_overlay_caps, .overlay_caps = omap2_dss_overlay_caps,
.clksrc_names = omap2_dss_clk_source_names, .clksrc_names = omap2_dss_clk_source_names,
...@@ -574,6 +633,7 @@ static const struct omap_dss_features omap3430_dss_features = { ...@@ -574,6 +633,7 @@ static const struct omap_dss_features omap3430_dss_features = {
.num_mgrs = 2, .num_mgrs = 2,
.num_ovls = 3, .num_ovls = 3,
.supported_displays = omap3430_dss_supported_displays, .supported_displays = omap3430_dss_supported_displays,
.supported_outputs = omap3430_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes, .supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3430_dss_overlay_caps, .overlay_caps = omap3430_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names, .clksrc_names = omap3_dss_clk_source_names,
...@@ -597,6 +657,7 @@ static const struct omap_dss_features am35xx_dss_features = { ...@@ -597,6 +657,7 @@ static const struct omap_dss_features am35xx_dss_features = {
.num_mgrs = 2, .num_mgrs = 2,
.num_ovls = 3, .num_ovls = 3,
.supported_displays = omap3430_dss_supported_displays, .supported_displays = omap3430_dss_supported_displays,
.supported_outputs = omap3430_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes, .supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3430_dss_overlay_caps, .overlay_caps = omap3430_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names, .clksrc_names = omap3_dss_clk_source_names,
...@@ -616,6 +677,7 @@ static const struct omap_dss_features omap3630_dss_features = { ...@@ -616,6 +677,7 @@ static const struct omap_dss_features omap3630_dss_features = {
.num_mgrs = 2, .num_mgrs = 2,
.num_ovls = 3, .num_ovls = 3,
.supported_displays = omap3630_dss_supported_displays, .supported_displays = omap3630_dss_supported_displays,
.supported_outputs = omap3630_dss_supported_outputs,
.supported_color_modes = omap3_dss_supported_color_modes, .supported_color_modes = omap3_dss_supported_color_modes,
.overlay_caps = omap3630_dss_overlay_caps, .overlay_caps = omap3630_dss_overlay_caps,
.clksrc_names = omap3_dss_clk_source_names, .clksrc_names = omap3_dss_clk_source_names,
...@@ -637,6 +699,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = { ...@@ -637,6 +699,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features = {
.num_mgrs = 3, .num_mgrs = 3,
.num_ovls = 4, .num_ovls = 4,
.supported_displays = omap4_dss_supported_displays, .supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes, .supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps, .overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names, .clksrc_names = omap4_dss_clk_source_names,
...@@ -657,6 +720,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = { ...@@ -657,6 +720,7 @@ static const struct omap_dss_features omap4430_es2_0_1_2_dss_features = {
.num_mgrs = 3, .num_mgrs = 3,
.num_ovls = 4, .num_ovls = 4,
.supported_displays = omap4_dss_supported_displays, .supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes, .supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps, .overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names, .clksrc_names = omap4_dss_clk_source_names,
...@@ -677,6 +741,7 @@ static const struct omap_dss_features omap4_dss_features = { ...@@ -677,6 +741,7 @@ static const struct omap_dss_features omap4_dss_features = {
.num_mgrs = 3, .num_mgrs = 3,
.num_ovls = 4, .num_ovls = 4,
.supported_displays = omap4_dss_supported_displays, .supported_displays = omap4_dss_supported_displays,
.supported_outputs = omap4_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes, .supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps, .overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap4_dss_clk_source_names, .clksrc_names = omap4_dss_clk_source_names,
...@@ -697,6 +762,7 @@ static const struct omap_dss_features omap5_dss_features = { ...@@ -697,6 +762,7 @@ static const struct omap_dss_features omap5_dss_features = {
.num_mgrs = 3, .num_mgrs = 3,
.num_ovls = 4, .num_ovls = 4,
.supported_displays = omap5_dss_supported_displays, .supported_displays = omap5_dss_supported_displays,
.supported_outputs = omap5_dss_supported_outputs,
.supported_color_modes = omap4_dss_supported_color_modes, .supported_color_modes = omap4_dss_supported_color_modes,
.overlay_caps = omap4_dss_overlay_caps, .overlay_caps = omap4_dss_overlay_caps,
.clksrc_names = omap5_dss_clk_source_names, .clksrc_names = omap5_dss_clk_source_names,
...@@ -766,6 +832,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel ...@@ -766,6 +832,11 @@ enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel
return omap_current_dss_features->supported_displays[channel]; return omap_current_dss_features->supported_displays[channel];
} }
enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel)
{
return omap_current_dss_features->supported_outputs[channel];
}
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane) enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane)
{ {
return omap_current_dss_features->supported_color_modes[plane]; return omap_current_dss_features->supported_color_modes[plane];
......
...@@ -108,6 +108,7 @@ int dss_feat_get_num_ovls(void); ...@@ -108,6 +108,7 @@ int dss_feat_get_num_ovls(void);
unsigned long dss_feat_get_param_min(enum dss_range_param param); unsigned long dss_feat_get_param_min(enum dss_range_param param);
unsigned long dss_feat_get_param_max(enum dss_range_param param); unsigned long dss_feat_get_param_max(enum dss_range_param param);
enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel); enum omap_display_type dss_feat_get_supported_displays(enum omap_channel channel);
enum omap_dss_output_id dss_feat_get_supported_outputs(enum omap_channel channel);
enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane); enum omap_color_mode dss_feat_get_supported_color_modes(enum omap_plane plane);
enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane); enum omap_overlay_caps dss_feat_get_overlay_caps(enum omap_plane plane);
bool dss_feat_color_mode_supported(enum omap_plane plane, bool dss_feat_color_mode_supported(enum omap_plane plane,
......
...@@ -68,6 +68,8 @@ static struct { ...@@ -68,6 +68,8 @@ static struct {
int ct_cp_hpd_gpio; int ct_cp_hpd_gpio;
int ls_oe_gpio; int ls_oe_gpio;
int hpd_gpio; int hpd_gpio;
struct omap_dss_output output;
} hdmi; } hdmi;
/* /*
...@@ -502,6 +504,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) ...@@ -502,6 +504,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
{ {
int r; int r;
struct omap_video_timings *p; struct omap_video_timings *p;
struct omap_overlay_manager *mgr = dssdev->output->manager;
unsigned long phy; unsigned long phy;
gpio_set_value(hdmi.ct_cp_hpd_gpio, 1); gpio_set_value(hdmi.ct_cp_hpd_gpio, 1);
...@@ -518,7 +521,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) ...@@ -518,7 +521,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
if (r) if (r)
goto err_runtime_get; goto err_runtime_get;
dss_mgr_disable(dssdev->manager); dss_mgr_disable(mgr);
p = &hdmi.ip_data.cfg.timings; p = &hdmi.ip_data.cfg.timings;
...@@ -560,13 +563,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) ...@@ -560,13 +563,13 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dispc_enable_gamma_table(0); dispc_enable_gamma_table(0);
/* tv size */ /* tv size */
dss_mgr_set_timings(dssdev->manager, p); dss_mgr_set_timings(mgr, p);
r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data); r = hdmi.ip_data.ops->video_enable(&hdmi.ip_data);
if (r) if (r)
goto err_vid_enable; goto err_vid_enable;
r = dss_mgr_enable(dssdev->manager); r = dss_mgr_enable(mgr);
if (r) if (r)
goto err_mgr_enable; goto err_mgr_enable;
...@@ -590,7 +593,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev) ...@@ -590,7 +593,9 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
static void hdmi_power_off(struct omap_dss_device *dssdev) static void hdmi_power_off(struct omap_dss_device *dssdev)
{ {
dss_mgr_disable(dssdev->manager); struct omap_overlay_manager *mgr = dssdev->output->manager;
dss_mgr_disable(mgr);
hdmi.ip_data.ops->video_disable(&hdmi.ip_data); hdmi.ip_data.ops->video_disable(&hdmi.ip_data);
hdmi.ip_data.ops->phy_disable(&hdmi.ip_data); hdmi.ip_data.ops->phy_disable(&hdmi.ip_data);
...@@ -687,14 +692,15 @@ bool omapdss_hdmi_detect(void) ...@@ -687,14 +692,15 @@ bool omapdss_hdmi_detect(void)
int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev) int omapdss_hdmi_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output;
int r = 0; int r = 0;
DSSDBG("ENTER hdmi_display_enable\n"); DSSDBG("ENTER hdmi_display_enable\n");
mutex_lock(&hdmi.lock); mutex_lock(&hdmi.lock);
if (dssdev->manager == NULL) { if (out == NULL || out->manager == NULL) {
DSSERR("failed to enable display: no manager\n"); DSSERR("failed to enable display: no output/manager\n");
r = -ENODEV; r = -ENODEV;
goto err0; goto err0;
} }
...@@ -970,6 +976,24 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev) ...@@ -970,6 +976,24 @@ static void __init hdmi_probe_pdata(struct platform_device *pdev)
} }
} }
static void __init hdmi_init_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &hdmi.output;
out->pdev = pdev;
out->id = OMAP_DSS_OUTPUT_HDMI;
out->type = OMAP_DISPLAY_TYPE_HDMI;
dss_register_output(out);
}
static void __exit hdmi_uninit_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &hdmi.output;
dss_unregister_output(out);
}
/* HDMI HW IP initialisation */ /* HDMI HW IP initialisation */
static int __init omapdss_hdmihw_probe(struct platform_device *pdev) static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
{ {
...@@ -1013,6 +1037,8 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev) ...@@ -1013,6 +1037,8 @@ static int __init omapdss_hdmihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("hdmi", hdmi_dump_regs); dss_debugfs_create_file("hdmi", hdmi_dump_regs);
hdmi_init_output(pdev);
hdmi_probe_pdata(pdev); hdmi_probe_pdata(pdev);
return 0; return 0;
...@@ -1033,6 +1059,8 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev) ...@@ -1033,6 +1059,8 @@ static int __exit omapdss_hdmihw_remove(struct platform_device *pdev)
hdmi_panel_exit(); hdmi_panel_exit();
hdmi_uninit_output(pdev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
hdmi_put_clocks(); hdmi_put_clocks();
......
...@@ -38,8 +38,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf) ...@@ -38,8 +38,10 @@ static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf) static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
{ {
return snprintf(buf, PAGE_SIZE, "%s\n", struct omap_dss_device *dssdev = mgr->get_device(mgr);
mgr->device ? mgr->device->name : "<none>");
return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
dssdev->name : "<none>");
} }
static ssize_t manager_display_store(struct omap_overlay_manager *mgr, static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
...@@ -67,18 +69,29 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr, ...@@ -67,18 +69,29 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
if (dssdev) if (dssdev)
DSSDBG("display %s found\n", dssdev->name); DSSDBG("display %s found\n", dssdev->name);
if (mgr->device) { if (mgr->output) {
r = mgr->unset_device(mgr); r = mgr->unset_output(mgr);
if (r) { if (r) {
DSSERR("failed to unset display\n"); DSSERR("failed to unset current output\n");
goto put_device; goto put_device;
} }
} }
if (dssdev) { if (dssdev) {
r = mgr->set_device(mgr, 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");
goto put_device;
}
r = mgr->set_output(mgr, out);
if (r) { if (r) {
DSSERR("failed to set manager\n"); DSSERR("failed to set manager output\n");
goto put_device; goto put_device;
} }
......
...@@ -36,9 +36,15 @@ ...@@ -36,9 +36,15 @@
static int num_managers; static int num_managers;
static struct omap_overlay_manager *managers; static struct omap_overlay_manager *managers;
static inline struct omap_dss_device *dss_mgr_get_device(struct omap_overlay_manager *mgr)
{
return mgr->output ? mgr->output->device : NULL;
}
static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
{ {
unsigned long timeout = msecs_to_jiffies(500); unsigned long timeout = msecs_to_jiffies(500);
struct omap_dss_device *dssdev = mgr->get_device(mgr);
u32 irq; u32 irq;
int r; int r;
...@@ -46,9 +52,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr) ...@@ -46,9 +52,9 @@ static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
if (r) if (r)
return r; return r;
if (mgr->device->type == OMAP_DISPLAY_TYPE_VENC) if (dssdev->type == OMAP_DISPLAY_TYPE_VENC)
irq = DISPC_IRQ_EVSYNC_ODD; irq = DISPC_IRQ_EVSYNC_ODD;
else if (mgr->device->type == OMAP_DISPLAY_TYPE_HDMI) else if (dssdev->type == OMAP_DISPLAY_TYPE_HDMI)
irq = DISPC_IRQ_EVSYNC_EVEN; irq = DISPC_IRQ_EVSYNC_EVEN;
else else
irq = dispc_mgr_get_vsync_irq(mgr->id); irq = dispc_mgr_get_vsync_irq(mgr->id);
...@@ -93,17 +99,20 @@ int dss_init_overlay_managers(struct platform_device *pdev) ...@@ -93,17 +99,20 @@ int dss_init_overlay_managers(struct platform_device *pdev)
break; break;
} }
mgr->set_device = &dss_mgr_set_device; mgr->set_output = &dss_mgr_set_output;
mgr->unset_device = &dss_mgr_unset_device; mgr->unset_output = &dss_mgr_unset_output;
mgr->apply = &omap_dss_mgr_apply; mgr->apply = &omap_dss_mgr_apply;
mgr->set_manager_info = &dss_mgr_set_info; mgr->set_manager_info = &dss_mgr_set_info;
mgr->get_manager_info = &dss_mgr_get_info; mgr->get_manager_info = &dss_mgr_get_info;
mgr->wait_for_go = &dss_mgr_wait_for_go; mgr->wait_for_go = &dss_mgr_wait_for_go;
mgr->wait_for_vsync = &dss_mgr_wait_for_vsync; mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
mgr->get_device = &dss_mgr_get_device;
mgr->caps = 0; mgr->caps = 0;
mgr->supported_displays = mgr->supported_displays =
dss_feat_get_supported_displays(mgr->id); dss_feat_get_supported_displays(mgr->id);
mgr->supported_outputs =
dss_feat_get_supported_outputs(mgr->id);
INIT_LIST_HEAD(&mgr->overlays); INIT_LIST_HEAD(&mgr->overlays);
......
/*
* Copyright (C) 2012 Texas Instruments Ltd
* Author: Archit Taneja <archit@ti.com>
*
* This program is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 as published by
* the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <video/omapdss.h>
#include "dss.h"
static LIST_HEAD(output_list);
static DEFINE_MUTEX(output_lock);
int omapdss_output_set_device(struct omap_dss_output *out,
struct omap_dss_device *dssdev)
{
int r;
mutex_lock(&output_lock);
if (out->device) {
DSSERR("output already has device %s connected to it\n",
out->device->name);
r = -EINVAL;
goto err;
}
if (out->type != dssdev->type) {
DSSERR("output type and display type don't match\n");
r = -EINVAL;
goto err;
}
out->device = dssdev;
dssdev->output = out;
mutex_unlock(&output_lock);
return 0;
err:
mutex_unlock(&output_lock);
return r;
}
EXPORT_SYMBOL(omapdss_output_set_device);
int omapdss_output_unset_device(struct omap_dss_output *out)
{
int r;
mutex_lock(&output_lock);
if (!out->device) {
DSSERR("output doesn't have a device connected to it\n");
r = -EINVAL;
goto err;
}
if (out->device->state != OMAP_DSS_DISPLAY_DISABLED) {
DSSERR("device %s is not disabled, cannot unset device\n",
out->device->name);
r = -EINVAL;
goto err;
}
out->device->output = NULL;
out->device = NULL;
mutex_unlock(&output_lock);
return 0;
err:
mutex_unlock(&output_lock);
return r;
}
EXPORT_SYMBOL(omapdss_output_unset_device);
void dss_register_output(struct omap_dss_output *out)
{
list_add_tail(&out->list, &output_list);
}
void dss_unregister_output(struct omap_dss_output *out)
{
list_del(&out->list);
}
struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id)
{
struct omap_dss_output *out;
list_for_each_entry(out, &output_list, list) {
if (out->id == id)
return out;
}
return NULL;
}
struct omap_dss_output *omapdss_get_output_from_dssdev(struct omap_dss_device *dssdev)
{
struct omap_dss_output *out = NULL;
enum omap_dss_output_id id;
switch (dssdev->type) {
case OMAP_DISPLAY_TYPE_DPI:
out = omap_dss_get_output(OMAP_DSS_OUTPUT_DPI);
break;
case OMAP_DISPLAY_TYPE_DBI:
out = omap_dss_get_output(OMAP_DSS_OUTPUT_DBI);
break;
case OMAP_DISPLAY_TYPE_SDI:
out = omap_dss_get_output(OMAP_DSS_OUTPUT_SDI);
break;
case OMAP_DISPLAY_TYPE_VENC:
out = omap_dss_get_output(OMAP_DSS_OUTPUT_VENC);
break;
case OMAP_DISPLAY_TYPE_HDMI:
out = omap_dss_get_output(OMAP_DSS_OUTPUT_HDMI);
break;
case OMAP_DISPLAY_TYPE_DSI:
id = dssdev->phy.dsi.module == 0 ? OMAP_DSS_OUTPUT_DSI1 :
OMAP_DSS_OUTPUT_DSI2;
out = omap_dss_get_output(id);
break;
default:
break;
}
return out;
}
...@@ -38,6 +38,13 @@ ...@@ -38,6 +38,13 @@
static int num_overlays; static int num_overlays;
static struct omap_overlay *overlays; static struct omap_overlay *overlays;
static inline struct omap_dss_device *dss_ovl_get_device(struct omap_overlay *ovl)
{
return ovl->manager ?
(ovl->manager->output ? ovl->manager->output->device : NULL) :
NULL;
}
int omap_dss_get_num_overlays(void) int omap_dss_get_num_overlays(void)
{ {
return num_overlays; return num_overlays;
...@@ -94,6 +101,7 @@ void dss_init_overlays(struct platform_device *pdev) ...@@ -94,6 +101,7 @@ void dss_init_overlays(struct platform_device *pdev)
ovl->set_overlay_info = &dss_ovl_set_info; ovl->set_overlay_info = &dss_ovl_set_info;
ovl->get_overlay_info = &dss_ovl_get_info; ovl->get_overlay_info = &dss_ovl_get_info;
ovl->wait_for_go = &dss_mgr_wait_for_go_ovl; ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
ovl->get_device = &dss_ovl_get_device;
ovl->caps = dss_feat_get_overlay_caps(ovl->id); ovl->caps = dss_feat_get_overlay_caps(ovl->id);
ovl->supported_modes = ovl->supported_modes =
......
...@@ -116,6 +116,8 @@ static struct { ...@@ -116,6 +116,8 @@ static struct {
int pixel_size; int pixel_size;
int data_lines; int data_lines;
struct rfbi_timings intf_timings; struct rfbi_timings intf_timings;
struct omap_dss_output output;
} rfbi; } rfbi;
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val) static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
...@@ -310,6 +312,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev, ...@@ -310,6 +312,7 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
{ {
u32 l; u32 l;
int r; int r;
struct omap_overlay_manager *mgr = dssdev->output->manager;
u16 width = rfbi.timings.x_res; u16 width = rfbi.timings.x_res;
u16 height = rfbi.timings.y_res; u16 height = rfbi.timings.y_res;
...@@ -318,9 +321,9 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev, ...@@ -318,9 +321,9 @@ static int rfbi_transfer_area(struct omap_dss_device *dssdev,
DSSDBG("rfbi_transfer_area %dx%d\n", width, height); DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
dss_mgr_set_timings(dssdev->manager, &rfbi.timings); dss_mgr_set_timings(mgr, &rfbi.timings);
r = dss_mgr_enable(dssdev->manager); r = dss_mgr_enable(mgr);
if (r) if (r)
return r; return r;
...@@ -849,6 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s) ...@@ -849,6 +852,7 @@ static void rfbi_dump_regs(struct seq_file *s)
static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager;
struct dss_lcd_mgr_config mgr_config; struct dss_lcd_mgr_config mgr_config;
mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI; mgr_config.io_pad_mode = DSS_IO_PAD_MODE_RFBI;
...@@ -860,7 +864,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) ...@@ -860,7 +864,7 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
mgr_config.video_port_width = rfbi.pixel_size; mgr_config.video_port_width = rfbi.pixel_size;
mgr_config.lcden_sig_polarity = 0; mgr_config.lcden_sig_polarity = 0;
dss_mgr_set_lcd_config(dssdev->manager, &mgr_config); dss_mgr_set_lcd_config(mgr, &mgr_config);
/* /*
* Set rfbi.timings with default values, the x_res and y_res fields * Set rfbi.timings with default values, the x_res and y_res fields
...@@ -881,15 +885,16 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev) ...@@ -881,15 +885,16 @@ static void rfbi_config_lcd_manager(struct omap_dss_device *dssdev)
rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH; rfbi.timings.de_level = OMAPDSS_SIG_ACTIVE_HIGH;
rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES; rfbi.timings.sync_pclk_edge = OMAPDSS_DRIVE_SIG_OPPOSITE_EDGES;
dss_mgr_set_timings(dssdev->manager, &rfbi.timings); dss_mgr_set_timings(mgr, &rfbi.timings);
} }
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev) int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output;
int r; int r;
if (dssdev->manager == NULL) { if (out == NULL || out->manager == NULL) {
DSSERR("failed to enable display: no manager\n"); DSSERR("failed to enable display: no output/manager\n");
return -ENODEV; return -ENODEV;
} }
...@@ -1002,6 +1007,24 @@ static void __init rfbi_probe_pdata(struct platform_device *rfbidev) ...@@ -1002,6 +1007,24 @@ static void __init rfbi_probe_pdata(struct platform_device *rfbidev)
} }
} }
static void __init rfbi_init_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &rfbi.output;
out->pdev = pdev;
out->id = OMAP_DSS_OUTPUT_DBI;
out->type = OMAP_DISPLAY_TYPE_DBI;
dss_register_output(out);
}
static void __exit rfbi_uninit_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &rfbi.output;
dss_unregister_output(out);
}
/* RFBI HW IP initialisation */ /* RFBI HW IP initialisation */
static int __init omap_rfbihw_probe(struct platform_device *pdev) static int __init omap_rfbihw_probe(struct platform_device *pdev)
{ {
...@@ -1053,6 +1076,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev) ...@@ -1053,6 +1076,8 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
dss_debugfs_create_file("rfbi", rfbi_dump_regs); dss_debugfs_create_file("rfbi", rfbi_dump_regs);
rfbi_init_output(pdev);
rfbi_probe_pdata(pdev); rfbi_probe_pdata(pdev);
return 0; return 0;
...@@ -1065,7 +1090,11 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev) ...@@ -1065,7 +1090,11 @@ static int __init omap_rfbihw_probe(struct platform_device *pdev)
static int __exit omap_rfbihw_remove(struct platform_device *pdev) static int __exit omap_rfbihw_remove(struct platform_device *pdev)
{ {
dss_unregister_child_devices(&pdev->dev); dss_unregister_child_devices(&pdev->dev);
rfbi_uninit_output(pdev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
return 0; return 0;
} }
......
...@@ -36,10 +36,14 @@ static struct { ...@@ -36,10 +36,14 @@ static struct {
struct dss_lcd_mgr_config mgr_config; struct dss_lcd_mgr_config mgr_config;
struct omap_video_timings timings; struct omap_video_timings timings;
int datapairs; int datapairs;
struct omap_dss_output output;
} sdi; } sdi;
static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager;
sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS; sdi.mgr_config.io_pad_mode = DSS_IO_PAD_MODE_BYPASS;
sdi.mgr_config.stallmode = false; sdi.mgr_config.stallmode = false;
...@@ -48,19 +52,20 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev) ...@@ -48,19 +52,20 @@ static void sdi_config_lcd_manager(struct omap_dss_device *dssdev)
sdi.mgr_config.video_port_width = 24; sdi.mgr_config.video_port_width = 24;
sdi.mgr_config.lcden_sig_polarity = 1; sdi.mgr_config.lcden_sig_polarity = 1;
dss_mgr_set_lcd_config(dssdev->manager, &sdi.mgr_config); dss_mgr_set_lcd_config(mgr, &sdi.mgr_config);
} }
int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output;
struct omap_video_timings *t = &sdi.timings; struct omap_video_timings *t = &sdi.timings;
struct dss_clock_info dss_cinfo; struct dss_clock_info dss_cinfo;
struct dispc_clock_info dispc_cinfo; struct dispc_clock_info dispc_cinfo;
unsigned long pck; unsigned long pck;
int r; int r;
if (dssdev->manager == NULL) { if (out == NULL || out->manager == NULL) {
DSSERR("failed to enable display: no manager\n"); DSSERR("failed to enable display: no output/manager\n");
return -ENODEV; return -ENODEV;
} }
...@@ -99,7 +104,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) ...@@ -99,7 +104,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
} }
dss_mgr_set_timings(dssdev->manager, t); dss_mgr_set_timings(out->manager, t);
r = dss_set_clock_div(&dss_cinfo); r = dss_set_clock_div(&dss_cinfo);
if (r) if (r)
...@@ -118,8 +123,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) ...@@ -118,8 +123,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
* need to care about the shadow register mechanism for pck-free. The * need to care about the shadow register mechanism for pck-free. The
* exact reason for this is unknown. * exact reason for this is unknown.
*/ */
dispc_mgr_set_clock_div(dssdev->manager->id, dispc_mgr_set_clock_div(out->manager->id, &sdi.mgr_config.clock_info);
&sdi.mgr_config.clock_info);
dss_sdi_init(sdi.datapairs); dss_sdi_init(sdi.datapairs);
r = dss_sdi_enable(); r = dss_sdi_enable();
...@@ -127,7 +131,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev) ...@@ -127,7 +131,7 @@ int omapdss_sdi_display_enable(struct omap_dss_device *dssdev)
goto err_sdi_enable; goto err_sdi_enable;
mdelay(2); mdelay(2);
r = dss_mgr_enable(dssdev->manager); r = dss_mgr_enable(out->manager);
if (r) if (r)
goto err_mgr_enable; goto err_mgr_enable;
...@@ -150,7 +154,9 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable); ...@@ -150,7 +154,9 @@ EXPORT_SYMBOL(omapdss_sdi_display_enable);
void omapdss_sdi_display_disable(struct omap_dss_device *dssdev) void omapdss_sdi_display_disable(struct omap_dss_device *dssdev)
{ {
dss_mgr_disable(dssdev->manager); struct omap_overlay_manager *mgr = dssdev->output->manager;
dss_mgr_disable(mgr);
dss_sdi_disable(); dss_sdi_disable();
...@@ -255,8 +261,28 @@ static void __init sdi_probe_pdata(struct platform_device *sdidev) ...@@ -255,8 +261,28 @@ static void __init sdi_probe_pdata(struct platform_device *sdidev)
} }
} }
static void __init sdi_init_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &sdi.output;
out->pdev = pdev;
out->id = OMAP_DSS_OUTPUT_SDI;
out->type = OMAP_DISPLAY_TYPE_SDI;
dss_register_output(out);
}
static void __exit sdi_uninit_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &sdi.output;
dss_unregister_output(out);
}
static int __init omap_sdi_probe(struct platform_device *pdev) static int __init omap_sdi_probe(struct platform_device *pdev)
{ {
sdi_init_output(pdev);
sdi_probe_pdata(pdev); sdi_probe_pdata(pdev);
return 0; return 0;
...@@ -266,6 +292,8 @@ static int __exit omap_sdi_remove(struct platform_device *pdev) ...@@ -266,6 +292,8 @@ static int __exit omap_sdi_remove(struct platform_device *pdev)
{ {
dss_unregister_child_devices(&pdev->dev); dss_unregister_child_devices(&pdev->dev);
sdi_uninit_output(pdev);
return 0; return 0;
} }
......
...@@ -303,6 +303,8 @@ static struct { ...@@ -303,6 +303,8 @@ static struct {
struct omap_video_timings timings; struct omap_video_timings timings;
enum omap_dss_venc_type type; enum omap_dss_venc_type type;
bool invert_polarity; bool invert_polarity;
struct omap_dss_output output;
} venc; } venc;
static inline void venc_write_reg(int idx, u32 val) static inline void venc_write_reg(int idx, u32 val)
...@@ -427,6 +429,7 @@ static const struct venc_config *venc_timings_to_config( ...@@ -427,6 +429,7 @@ static const struct venc_config *venc_timings_to_config(
static int venc_power_on(struct omap_dss_device *dssdev) static int venc_power_on(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager;
u32 l; u32 l;
int r; int r;
...@@ -452,13 +455,13 @@ static int venc_power_on(struct omap_dss_device *dssdev) ...@@ -452,13 +455,13 @@ static int venc_power_on(struct omap_dss_device *dssdev)
venc_write_reg(VENC_OUTPUT_CONTROL, l); venc_write_reg(VENC_OUTPUT_CONTROL, l);
dss_mgr_set_timings(dssdev->manager, &venc.timings); dss_mgr_set_timings(mgr, &venc.timings);
r = regulator_enable(venc.vdda_dac_reg); r = regulator_enable(venc.vdda_dac_reg);
if (r) if (r)
goto err1; goto err1;
r = dss_mgr_enable(dssdev->manager); r = dss_mgr_enable(mgr);
if (r) if (r)
goto err2; goto err2;
...@@ -477,10 +480,12 @@ static int venc_power_on(struct omap_dss_device *dssdev) ...@@ -477,10 +480,12 @@ static int venc_power_on(struct omap_dss_device *dssdev)
static void venc_power_off(struct omap_dss_device *dssdev) static void venc_power_off(struct omap_dss_device *dssdev)
{ {
struct omap_overlay_manager *mgr = dssdev->output->manager;
venc_write_reg(VENC_OUTPUT_CONTROL, 0); venc_write_reg(VENC_OUTPUT_CONTROL, 0);
dss_set_dac_pwrdn_bgz(0); dss_set_dac_pwrdn_bgz(0);
dss_mgr_disable(dssdev->manager); dss_mgr_disable(mgr);
regulator_disable(venc.vdda_dac_reg); regulator_disable(venc.vdda_dac_reg);
...@@ -495,14 +500,15 @@ unsigned long venc_get_pixel_clock(void) ...@@ -495,14 +500,15 @@ unsigned long venc_get_pixel_clock(void)
int omapdss_venc_display_enable(struct omap_dss_device *dssdev) int omapdss_venc_display_enable(struct omap_dss_device *dssdev)
{ {
struct omap_dss_output *out = dssdev->output;
int r; int r;
DSSDBG("venc_display_enable\n"); DSSDBG("venc_display_enable\n");
mutex_lock(&venc.venc_lock); mutex_lock(&venc.venc_lock);
if (dssdev->manager == NULL) { if (out == NULL || out->manager == NULL) {
DSSERR("Failed to enable display: no manager\n"); DSSERR("Failed to enable display: no output/manager\n");
r = -ENODEV; r = -ENODEV;
goto err0; goto err0;
} }
...@@ -797,6 +803,24 @@ static void __init venc_probe_pdata(struct platform_device *vencdev) ...@@ -797,6 +803,24 @@ static void __init venc_probe_pdata(struct platform_device *vencdev)
} }
} }
static void __init venc_init_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &venc.output;
out->pdev = pdev;
out->id = OMAP_DSS_OUTPUT_VENC;
out->type = OMAP_DISPLAY_TYPE_VENC;
dss_register_output(out);
}
static void __exit venc_uninit_output(struct platform_device *pdev)
{
struct omap_dss_output *out = &venc.output;
dss_unregister_output(out);
}
/* VENC HW IP initialisation */ /* VENC HW IP initialisation */
static int __init omap_venchw_probe(struct platform_device *pdev) static int __init omap_venchw_probe(struct platform_device *pdev)
{ {
...@@ -844,6 +868,8 @@ static int __init omap_venchw_probe(struct platform_device *pdev) ...@@ -844,6 +868,8 @@ static int __init omap_venchw_probe(struct platform_device *pdev)
dss_debugfs_create_file("venc", venc_dump_regs); dss_debugfs_create_file("venc", venc_dump_regs);
venc_init_output(pdev);
venc_probe_pdata(pdev); venc_probe_pdata(pdev);
return 0; return 0;
...@@ -866,6 +892,8 @@ static int __exit omap_venchw_remove(struct platform_device *pdev) ...@@ -866,6 +892,8 @@ static int __exit omap_venchw_remove(struct platform_device *pdev)
venc_panel_exit(); venc_panel_exit();
venc_uninit_output(pdev);
pm_runtime_disable(&pdev->dev); pm_runtime_disable(&pdev->dev);
venc_put_clocks(); venc_put_clocks();
......
...@@ -599,6 +599,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) ...@@ -599,6 +599,7 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
struct omapfb_info *ofbi = FB2OFB(fbi); struct omapfb_info *ofbi = FB2OFB(fbi);
struct omapfb2_device *fbdev = ofbi->fbdev; struct omapfb2_device *fbdev = ofbi->fbdev;
struct omap_dss_device *display = fb2display(fbi); struct omap_dss_device *display = fb2display(fbi);
struct omap_overlay_manager *mgr;
union { union {
struct omapfb_update_window_old uwnd_o; struct omapfb_update_window_old uwnd_o;
...@@ -786,12 +787,14 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg) ...@@ -786,12 +787,14 @@ int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
case OMAPFB_WAITFORVSYNC: case OMAPFB_WAITFORVSYNC:
DBG("ioctl WAITFORVSYNC\n"); DBG("ioctl WAITFORVSYNC\n");
if (!display) { if (!display && !display->output && !display->output->manager) {
r = -EINVAL; r = -EINVAL;
break; break;
} }
r = display->manager->wait_for_vsync(display->manager); mgr = display->output->manager;
r = mgr->wait_for_vsync(mgr);
break; break;
case OMAPFB_WAITFORGO: case OMAPFB_WAITFORGO:
......
...@@ -2379,6 +2379,7 @@ static int __init omapfb_probe(struct platform_device *pdev) ...@@ -2379,6 +2379,7 @@ static int __init omapfb_probe(struct platform_device *pdev)
struct omap_overlay *ovl; struct omap_overlay *ovl;
struct omap_dss_device *def_display; struct omap_dss_device *def_display;
struct omap_dss_device *dssdev; struct omap_dss_device *dssdev;
struct omap_dss_device *ovl_device;
DBG("omapfb_probe\n"); DBG("omapfb_probe\n");
...@@ -2452,8 +2453,9 @@ static int __init omapfb_probe(struct platform_device *pdev) ...@@ -2452,8 +2453,9 @@ static int __init omapfb_probe(struct platform_device *pdev)
/* gfx overlay should be the default one. find a display /* gfx overlay should be the default one. find a display
* connected to that, and use it as default display */ * connected to that, and use it as default display */
ovl = omap_dss_get_overlay(0); ovl = omap_dss_get_overlay(0);
if (ovl->manager && ovl->manager->device) { ovl_device = ovl->get_device(ovl);
def_display = ovl->manager->device; if (ovl_device) {
def_display = ovl_device;
} else { } else {
dev_warn(&pdev->dev, "cannot find default display\n"); dev_warn(&pdev->dev, "cannot find default display\n");
def_display = NULL; def_display = NULL;
......
...@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi) ...@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
/* XXX: returns the display connected to first attached overlay */ /* XXX: returns the display connected to first attached overlay */
for (i = 0; i < ofbi->num_overlays; i++) { for (i = 0; i < ofbi->num_overlays; i++) {
if (ofbi->overlays[i]->manager) struct omap_overlay *ovl = ofbi->overlays[i];
return ofbi->overlays[i]->manager->device;
return ovl->get_device(ovl);
} }
return NULL; return NULL;
......
...@@ -208,6 +208,16 @@ enum omap_hdmi_flags { ...@@ -208,6 +208,16 @@ enum omap_hdmi_flags {
OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0, OMAP_HDMI_SDA_SCL_EXTERNAL_PULLUP = 1 << 0,
}; };
enum omap_dss_output_id {
OMAP_DSS_OUTPUT_DPI = 1 << 0,
OMAP_DSS_OUTPUT_DBI = 1 << 1,
OMAP_DSS_OUTPUT_SDI = 1 << 2,
OMAP_DSS_OUTPUT_DSI1 = 1 << 3,
OMAP_DSS_OUTPUT_DSI2 = 1 << 4,
OMAP_DSS_OUTPUT_VENC = 1 << 5,
OMAP_DSS_OUTPUT_HDMI = 1 << 6,
};
/* RFBI */ /* RFBI */
struct rfbi_timings { struct rfbi_timings {
...@@ -425,6 +435,8 @@ struct omap_overlay { ...@@ -425,6 +435,8 @@ struct omap_overlay {
struct omap_overlay_info *info); struct omap_overlay_info *info);
int (*wait_for_go)(struct omap_overlay *ovl); int (*wait_for_go)(struct omap_overlay *ovl);
struct omap_dss_device *(*get_device)(struct omap_overlay *ovl);
}; };
struct omap_overlay_manager_info { struct omap_overlay_manager_info {
...@@ -449,9 +461,10 @@ struct omap_overlay_manager { ...@@ -449,9 +461,10 @@ struct omap_overlay_manager {
enum omap_overlay_manager_caps caps; enum omap_overlay_manager_caps caps;
struct list_head overlays; struct list_head overlays;
enum omap_display_type supported_displays; enum omap_display_type supported_displays;
enum omap_dss_output_id supported_outputs;
/* dynamic fields */ /* dynamic fields */
struct omap_dss_device *device; struct omap_dss_output *output;
/* /*
* The following functions do not block: * The following functions do not block:
...@@ -464,9 +477,9 @@ struct omap_overlay_manager { ...@@ -464,9 +477,9 @@ struct omap_overlay_manager {
* interrupt context * interrupt context
*/ */
int (*set_device)(struct omap_overlay_manager *mgr, int (*set_output)(struct omap_overlay_manager *mgr,
struct omap_dss_device *dssdev); struct omap_dss_output *output);
int (*unset_device)(struct omap_overlay_manager *mgr); int (*unset_output)(struct omap_overlay_manager *mgr);
int (*set_manager_info)(struct omap_overlay_manager *mgr, int (*set_manager_info)(struct omap_overlay_manager *mgr,
struct omap_overlay_manager_info *info); struct omap_overlay_manager_info *info);
...@@ -476,6 +489,8 @@ struct omap_overlay_manager { ...@@ -476,6 +489,8 @@ struct omap_overlay_manager {
int (*apply)(struct omap_overlay_manager *mgr); int (*apply)(struct omap_overlay_manager *mgr);
int (*wait_for_go)(struct omap_overlay_manager *mgr); int (*wait_for_go)(struct omap_overlay_manager *mgr);
int (*wait_for_vsync)(struct omap_overlay_manager *mgr); int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
struct omap_dss_device *(*get_device)(struct omap_overlay_manager *mgr);
}; };
/* 22 pins means 1 clk lane and 10 data lanes */ /* 22 pins means 1 clk lane and 10 data lanes */
...@@ -493,6 +508,24 @@ struct omap_dsi_pin_config { ...@@ -493,6 +508,24 @@ struct omap_dsi_pin_config {
int pins[OMAP_DSS_MAX_DSI_PINS]; int pins[OMAP_DSS_MAX_DSI_PINS];
}; };
struct omap_dss_output {
struct list_head list;
/* display type supported by the output */
enum omap_display_type type;
/* output instance */
enum omap_dss_output_id id;
/* output's platform device pointer */
struct platform_device *pdev;
/* dynamic fields */
struct omap_overlay_manager *manager;
struct omap_dss_device *device;
};
struct omap_dss_device { struct omap_dss_device {
struct device dev; struct device dev;
...@@ -591,7 +624,7 @@ struct omap_dss_device { ...@@ -591,7 +624,7 @@ struct omap_dss_device {
enum omap_display_caps caps; enum omap_display_caps caps;
struct omap_overlay_manager *manager; struct omap_dss_output *output;
enum omap_dss_display_state state; enum omap_dss_display_state state;
...@@ -702,6 +735,11 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num); ...@@ -702,6 +735,11 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
int omap_dss_get_num_overlays(void); int omap_dss_get_num_overlays(void);
struct omap_overlay *omap_dss_get_overlay(int num); struct omap_overlay *omap_dss_get_overlay(int num);
struct omap_dss_output *omap_dss_get_output(enum omap_dss_output_id id);
int omapdss_output_set_device(struct omap_dss_output *out,
struct omap_dss_device *dssdev);
int omapdss_output_unset_device(struct omap_dss_output *out);
void omapdss_default_get_resolution(struct omap_dss_device *dssdev, void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
u16 *xres, u16 *yres); u16 *xres, u16 *yres);
int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev); int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment