linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support
@ 2011-12-27 12:48 Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 01/29] omapdss/omapfb/omap_vout: Introduce manager output struct Archit Taneja
                   ` (28 more replies)
  0 siblings, 29 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

DSS HW on OMAP4 supports a new pipeline called writeback. Unlike other
pipelines(called overlays in DSS2 SW), writeback takes pixel data from an
overlay output or a overlay manager output and writes it back into a specified
address in memory.

writeback allows us to take benefit of the hardware processing available inside
the DISPC like color space conversion, rescaling, compositing etc and do either
a) perform memory-to-memory transfer with data processing, b) capture a
displayed frame. The former is known as memory to memory mode of the writeback
pipeline, and the latter is known as capture mode. More details about writeback
can be found in the Display Subsystem section of the OMAP4 TRM.

In the current DSS2 design, there are 3 major entities: overlay(represents
pipelines), overlay manager(represents a compositor of pipelines and the output
going to a display) and a omap_dss_device(to represent a display). These
entities can be linked to each other. One or more overlays can connect to a
manager, and a manager connects to a display.

Writeback HW has some properties of an overlay, and some of an overlay manager.
But as far as DSS2 design is concerned, it best fits as a special panel. This
panel connects to a manager and displays/writes the content back to memory after
doing some optional data processing.

The design adopted for writeback support in DSS2 is as follows:
- Writeback exists as an entity of its own, this entity is used to configure and
  represent the actual writeback HW.
- This entity doesn't connect itself directly to a manager, it connects to a
  manager via a dummy writeback panel.
- The dummy writeback panel is just a place holder of the actual writeback
  entity. To do any writeback configuration, we extract the writeback pointer
  through the dummy writeback panel pointer. 
- In capture mode, an overlay manager needs to be connected to 2 outputs at the
  same time. The first output is the display device, and the second is the
  writeback panel. For this requirement, managers don't connect to a dss device,
  they now connect to an entity called output. This entity is just a container
  for 2 omap_dss_devices, one for display and one for writeback.

With the design mentioned above. The three different ways writeback is used is
explained:
- capture mode: A manager is connected to both display and writeback
  dss_devices.
- memory to memory mode(connected to a manager): A manager is connected to only
  the writeback dss_device.
- memory to memory mode(connected to an overlay): A dummy writeback manager is
  connect to the writeback dss_device.

This patch series only enables capture mode support, i.e., allowing us to write
to the memory a processed version of the frame that we display onto a panel
through an overlay manager. The memory to memory mode support will be extended
later.

In order to use writeback, we need a capture device driver of some sort, a v4l2
capture device is currently in the works. The patches are currently tested by
extending writeback panel's sysfs attributes to allow us to configure the
destination addresses and other parameters via sysfs.

This can be tried out here:

git://gitorious.org:~boddob/linux-omap-dss2/archit-dss2-clone.git wb-v1

The patches are based on the following tree:

git://gitorious.org/linux-omap-dss2/linux.git master

Tested on a OMAP4 based blaze tablet. Note that this isn't tested thoroughly for
all possible writeback configurations, the aim is to get comments on the design.

Archit Taneja (29):
  omapdss/omapfb/omap_vout: Introduce manager output struct
  OMAPDSS: Add writeback to omap_dss_mgr_output
  OMAPDSS: Writeback: Add writeback interface and panel driver
  OMAPDSS: APPLY/Writeback: Add writeback_info
  OMAPDSS: APPLY/Writeback: Apply writeback configurations
  OMAPDSS: APPLY: Add writeback enable/disable functions
  OMAPDSS: APPLY: Add extra_info for writeback
  OMAPDSS: APPLY: Modify manager unset device op
  OMAPDSS: APPLY: Allow manager set/unset_device ops to set/unset
    writeback
  OMAPDSS: APPLY: Calculate channel_in for writeback
  OMAPDSS: DISPC: Add writeback as a new plane
  OMAPDSS: Writeback: Add check for color_mode in dss_wb_simple_check()
  OMAPDSS: APPLY: Configure writeback FIFOs
  OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma
  OMAPDSS: DISPC: Pass overlay caps as a parameter to dispc overlay
    related functions
  OMAPDSS: OVERLAY: Add position and replication as overlay caps
  OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_plane_setup
  OMAPDSS: DISPC: Make chroma_upscale an argument to dispc_plane_setup
  OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
  OMAPDSS: Writeback: Add writeback capabilities
  OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
  OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions
  OMAPDSS: Writeback: Configure writeback specific parameters
  OMAPDSS: Writeback: Use panel driver ops to configure mirroring
    rotation and buffer size
  OMAPDSS: Writeback: Add sysfs attributes to writeback panel
  OMAPDSS: DISPLAY: Add a manager apply to sysfs store attributes for
    writeback
  OMAPDSS: MANAGER: Split manager_display_store into smaller functions
  OMAPDSS: MANAGER: Add writeback as a sysfs attribute
  OMAPDSS: FEATURES: Allow WB panels to attach to managers

 drivers/media/video/omap/omap_vout.c     |   78 +++--
 drivers/video/omap2/dss/Makefile         |    2 +-
 drivers/video/omap2/dss/apply.c          |  549 +++++++++++++++++++++++++--
 drivers/video/omap2/dss/core.c           |    2 +
 drivers/video/omap2/dss/dispc.c          |  343 ++++++++++++-----
 drivers/video/omap2/dss/dispc.h          |   36 ++
 drivers/video/omap2/dss/display.c        |   23 +-
 drivers/video/omap2/dss/dss.h            |   39 ++-
 drivers/video/omap2/dss/dss_features.c   |   24 +-
 drivers/video/omap2/dss/dss_features.h   |    2 +
 drivers/video/omap2/dss/manager.c        |  125 ++++++-
 drivers/video/omap2/dss/overlay.c        |   27 +-
 drivers/video/omap2/dss/writeback.c      |  615 ++++++++++++++++++++++++++++++
 drivers/video/omap2/omapfb/omapfb-main.c |    7 +-
 drivers/video/omap2/omapfb/omapfb.h      |    5 +-
 include/video/omapdss.h                  |   52 +++-
 16 files changed, 1749 insertions(+), 180 deletions(-)
 create mode 100644 drivers/video/omap2/dss/writeback.c

-- 
1.7.4.1


^ permalink raw reply	[flat|nested] 32+ messages in thread

* [RFC PATCH 01/29] omapdss/omapfb/omap_vout: Introduce manager output struct
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 02/29] OMAPDSS: Add writeback to omap_dss_mgr_output Archit Taneja
                   ` (27 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Introduce struct omap_dss_mgr_output, this describes the output connected to the
manager. This has been introduced as the output of a manager may not be just a
a display device, it could be connected to writeback or both.

The output struct will act as a container for 2 omap_dss_device pointers, one
for the display attached, and one for the writeback panel if that manager is
using writeback pipeline. The mode of operation(only displaying on a panel,
writeback capture mode, writeback memory to memory mode) is configured within
DSS2 based on how the user sets these outputs.

The omap_dss_device pointer connected to a manager is accessed by a omap_overlay
or a omap_overlay_manager pointer by references like manager->device and
ovl->manager->device. Replace such accesses by creating a helper function
get_output() in the overlay_manager struct.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/media/video/omap/omap_vout.c     |   78 +++++++++++++++++++++---------
 drivers/video/omap2/dss/apply.c          |   73 +++++++++++++++++++--------
 drivers/video/omap2/dss/dispc.c          |   11 +++--
 drivers/video/omap2/dss/manager.c        |   29 +++++++++--
 drivers/video/omap2/dss/overlay.c        |   12 ++--
 drivers/video/omap2/omapfb/omapfb-main.c |    7 ++-
 drivers/video/omap2/omapfb/omapfb.h      |    5 +-
 include/video/omapdss.h                  |    8 +++-
 8 files changed, 158 insertions(+), 65 deletions(-)

diff --git a/drivers/media/video/omap/omap_vout.c b/drivers/media/video/omap/omap_vout.c
index 27c19fe..b9cdb1e 100644
--- a/drivers/media/video/omap/omap_vout.c
+++ b/drivers/media/video/omap/omap_vout.c
@@ -453,11 +453,16 @@ static int omapvid_init(struct omap_vout_device *vout, u32 addr)
 
 	win = &vout->win;
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_output(ovl->manager) : NULL;
+
+		if (!dssdev)
 			return -EINVAL;
 
-		timing = &ovl->manager->device->panel.timings;
+		timing = &dssdev->panel.timings;
 
 		outw = win->w.width;
 		outh = win->w.height;
@@ -514,8 +519,12 @@ static int omapvid_apply_changes(struct omap_vout_device *vout)
 	struct omapvideo_info *ovid = &vout->vid_info;
 
 	for (i = 0; i < ovid->num_overlays; i++) {
+		struct omap_dss_device *dssdev;
+
 		ovl = ovid->overlays[i];
-		if (!ovl->manager || !ovl->manager->device)
+		dssdev = ovl->manager ?
+			ovl->manager->get_output(ovl->manager) : NULL;
+		if (!dssdev)
 			return -EINVAL;
 		ovl->manager->apply(ovl->manager);
 	}
@@ -539,10 +548,11 @@ static void omap_vout_isr(void *arg, unsigned int irqstatus)
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
 	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device)
-		return;
+	cur_display = ovl->manager ?
+		ovl->manager->get_output(ovl->manager) : NULL;
 
-	cur_display = ovl->manager->device;
+	if (!cur_display)
+		return;
 
 	spin_lock(&vout->vbq_lock);
 	do_gettimeofday(&timevalue);
@@ -942,7 +952,10 @@ static int omap_vout_release(struct file *file)
 	/* Disable all the overlay managers connected with this interface */
 	for (i = 0; i < ovid->num_overlays; i++) {
 		struct omap_overlay *ovl = ovid->overlays[i];
-		if (ovl->manager && ovl->manager->device)
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_output(ovl->manager) : NULL;
+
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 	/* Turn off the pipeline */
@@ -1074,14 +1087,17 @@ static int vidioc_try_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_output(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device)
+	if (!dssdev)
 		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.width = timing->x_res;
@@ -1098,6 +1114,7 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 	struct omapvideo_info *ovid;
 	struct omap_video_timings *timing;
 	struct omap_vout_device *vout = fh;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1106,13 +1123,14 @@ static int vidioc_s_fmt_vid_out(struct file *file, void *fh,
 
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	dssdev = ovl->manager ? ovl->manager->get_output(ovl->manager) : NULL;
 
 	/* get the display device attached to the overlay */
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		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
 	 * is enabled*/
@@ -1291,6 +1309,7 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	struct omapvideo_info *ovid;
 	struct omap_overlay *ovl;
 	struct omap_video_timings *timing;
+	struct omap_dss_device *dssdev;
 
 	if (vout->streaming)
 		return -EBUSY;
@@ -1298,13 +1317,15 @@ static int vidioc_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
 	mutex_lock(&vout->lock);
 	ovid = &vout->vid_info;
 	ovl = ovid->overlays[0];
+	/* get the display device attached to the overlay */
+	dssdev = ovl->manager ? ovl->manager->get_output(ovl->manager) : NULL;
 
-	if (!ovl->manager || !ovl->manager->device) {
+	if (!dssdev) {
 		ret = -EINVAL;
 		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)) {
 		vout->fbuf.fmt.height = timing->x_res;
@@ -1659,8 +1680,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_output(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (dssdev) {
 			struct omap_overlay_info info;
 			ovl->get_overlay_info(ovl, &info);
 			info.paddr = addr;
@@ -1683,8 +1706,10 @@ static int vidioc_streamon(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_output(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device) {
+		if (dssdev) {
 			ret = ovl->enable(ovl);
 			if (ret)
 				goto streamon_err1;
@@ -1719,8 +1744,10 @@ static int vidioc_streamoff(struct file *file, void *fh, enum v4l2_buf_type i)
 
 	for (j = 0; j < ovid->num_overlays; j++) {
 		struct omap_overlay *ovl = ovid->overlays[j];
+		struct omap_dss_device *dssdev = ovl->manager ?
+			ovl->manager->get_output(ovl->manager) : NULL;
 
-		if (ovl->manager && ovl->manager->device)
+		if (dssdev)
 			ovl->disable(ovl);
 	}
 
@@ -1881,8 +1908,9 @@ static int __init omap_vout_setup_video_data(struct omap_vout_device *vout)
 	struct video_device *vfd;
 	struct v4l2_pix_format *pix;
 	struct v4l2_control *control;
+	struct omap_overlay *ovl = vout->vid_info.overlays[0];
 	struct omap_dss_device *display -		vout->vid_info.overlays[0]->manager->device;
+		ovl->manager->get_output(ovl->manager);
 
 	/* set the default pix */
 	pix = &vout->pix;
@@ -2188,8 +2216,10 @@ static int __init omap_vout_probe(struct platform_device *pdev)
 	 */
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device) {
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_output(ovl->manager) :
+				NULL;
+		if (dssdev) {
+			def_display = dssdev;
 		} else {
 			dev_warn(&pdev->dev, "cannot find display\n");
 			def_display = NULL;
@@ -2236,8 +2266,10 @@ probe_err1:
 	for (i = 1; i < vid_dev->num_overlays; i++) {
 		def_display = NULL;
 		ovl = omap_dss_get_overlay(i);
-		if (ovl->manager && ovl->manager->device)
-			def_display = ovl->manager->device;
+		dssdev = ovl->manager ? ovl->manager->get_output(ovl->manager) :
+				NULL;
+		if (dssdev)
+			def_display = dssdev;
 
 		if (def_display && def_display->driver)
 			def_display->driver->disable(def_display);
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 052dc87..d529664 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -164,12 +164,16 @@ void dss_apply_init(void)
 
 static bool ovl_manual_update(struct omap_overlay *ovl)
 {
-	return ovl->manager->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+	struct omap_dss_device *dssdev = ovl->manager->get_output(ovl->manager);
+
+	return dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 }
 
 static bool mgr_manual_update(struct omap_overlay_manager *mgr)
 {
-	return mgr->device->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
+	struct omap_dss_device *dssdev = mgr->get_output(mgr);
+
+	return dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 }
 
 static int dss_check_settings_low(struct omap_overlay_manager *mgr,
@@ -380,7 +384,7 @@ int dss_mgr_wait_for_go(struct omap_overlay_manager *mgr)
 	u32 irq;
 	int r;
 	int i;
-	struct omap_dss_device *dssdev = mgr->device;
+	struct omap_dss_device *dssdev = mgr->get_output(mgr);
 
 	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
@@ -443,7 +447,7 @@ int dss_mgr_wait_for_go_ovl(struct omap_overlay *ovl)
 	if (!ovl->manager)
 		return 0;
 
-	dssdev = ovl->manager->device;
+	dssdev = ovl->manager->get_output(ovl->manager);
 
 	if (!dssdev || dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
 		return 0;
@@ -500,18 +504,21 @@ static void dss_ovl_write_regs(struct omap_overlay *ovl)
 	struct omap_overlay_info *oi;
 	bool ilace, replication;
 	struct mgr_priv_data *mp;
+	struct omap_dss_device *dssdev;
 	int r;
 
 	DSSDBGF("%d", ovl->id);
 
+	dssdev = ovl->manager->get_output(ovl->manager);
+
 	if (!op->enabled || !op->info_dirty)
 		return;
 
 	oi = &op->info;
 
-	replication = dss_use_replication(ovl->manager->device, oi->color_mode);
+	replication = dss_use_replication(dssdev, oi->color_mode);
 
-	ilace = ovl->manager->device->type = OMAP_DISPLAY_TYPE_VENC;
+	ilace = dssdev->type = OMAP_DISPLAY_TYPE_VENC;
 
 	r = dispc_ovl_setup(ovl->id, oi, ilace, replication);
 	if (r) {
@@ -593,15 +600,17 @@ static void dss_write_regs(void)
 	for (i = 0; i < num_mgrs; ++i) {
 		struct omap_overlay_manager *mgr;
 		struct mgr_priv_data *mp;
+		struct omap_dss_device *dssdev;
 		int r;
 
 		mgr = omap_dss_get_overlay_manager(i);
 		mp = get_mgr_priv(mgr);
+		dssdev = mgr->get_output(mgr);
 
 		if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
 			continue;
 
-		r = dss_check_settings(mgr, mgr->device);
+		r = dss_check_settings(mgr, dssdev);
 		if (r) {
 			DSSERR("cannot write registers for manager %s: "
 					"illegal configuration\n", mgr->name);
@@ -643,6 +652,7 @@ static void dss_set_go_bits(void)
 void dss_mgr_start_update(struct omap_overlay_manager *mgr)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	struct omap_dss_device *dssdev;
 	unsigned long flags;
 	int r;
 
@@ -650,7 +660,9 @@ void dss_mgr_start_update(struct omap_overlay_manager *mgr)
 
 	WARN_ON(mp->updating);
 
-	r = dss_check_settings(mgr, mgr->device);
+	dssdev = mgr->get_output(mgr);
+
+	r = dss_check_settings(mgr, dssdev);
 	if (r) {
 		DSSERR("cannot start manual update: illegal configuration\n");
 		spin_unlock_irqrestore(&data_lock, flags);
@@ -805,13 +817,16 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 {
 	unsigned long flags;
 	struct omap_overlay *ovl;
+	struct omap_dss_device *dssdev;
 	int r;
 
 	DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
 
 	spin_lock_irqsave(&data_lock, flags);
 
-	r = dss_check_settings_apply(mgr, mgr->device);
+	dssdev = mgr->get_output(mgr);
+
+	r = dss_check_settings_apply(mgr, dssdev);
 	if (r) {
 		spin_unlock_irqrestore(&data_lock, flags);
 		DSSERR("failed to apply settings: illegal configuration.\n");
@@ -869,7 +884,7 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
 	if (!op->enabled && !op->enabling)
 		return;
 
-	dssdev = ovl->manager->device;
+	dssdev = ovl->manager->get_output(ovl->manager);
 
 	size = dispc_ovl_get_fifo_size(ovl->id);
 
@@ -926,6 +941,7 @@ static void dss_setup_fifos(void)
 int dss_mgr_enable(struct omap_overlay_manager *mgr)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	struct omap_dss_device *dssdev;
 	unsigned long flags;
 	int r;
 
@@ -938,7 +954,9 @@ int dss_mgr_enable(struct omap_overlay_manager *mgr)
 
 	mp->enabled = true;
 
-	r = dss_check_settings(mgr, mgr->device);
+	dssdev = mgr->get_output(mgr);
+
+	r = dss_check_settings(mgr, dssdev);
 	if (r) {
 		DSSERR("failed to enable manager %d: check_settings failed\n",
 				mgr->id);
@@ -1036,21 +1054,21 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 	mutex_lock(&apply_lock);
 
 	if (dssdev->manager) {
-		DSSERR("display '%s' already has a manager '%s'\n",
+		DSSERR("device '%s' already has a manager '%s'\n",
 			       dssdev->name, dssdev->manager->name);
 		r = -EINVAL;
 		goto err;
 	}
 
 	if ((mgr->supported_displays & dssdev->type) = 0) {
-		DSSERR("display '%s' does not support manager '%s'\n",
+		DSSERR("device '%s' does not support manager '%s'\n",
 			       dssdev->name, mgr->name);
 		r = -EINVAL;
 		goto err;
 	}
 
 	dssdev->manager = mgr;
-	mgr->device = dssdev;
+	mgr->output->device = dssdev;
 
 	mutex_unlock(&apply_lock);
 
@@ -1063,11 +1081,14 @@ err:
 int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
 {
 	int r;
+	struct omap_dss_device *curr_dssdev;
 
 	mutex_lock(&apply_lock);
 
-	if (!mgr->device) {
-		DSSERR("failed to unset display, display not set.\n");
+	curr_dssdev = mgr->output->device;
+
+	if (!curr_dssdev) {
+		DSSERR("failed to unset device, device not set.\n");
 		r = -EINVAL;
 		goto err;
 	}
@@ -1076,13 +1097,13 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
 	 * Don't allow currently enabled displays to have the overlay manager
 	 * pulled out from underneath them
 	 */
-	if (mgr->device->state != OMAP_DSS_DISPLAY_DISABLED) {
+	if (curr_dssdev->state != OMAP_DSS_DISPLAY_DISABLED) {
 		r = -EINVAL;
 		goto err;
 	}
 
-	mgr->device->manager = NULL;
-	mgr->device = NULL;
+	curr_dssdev->manager = NULL;
+	mgr->output->device = NULL;
 
 	mutex_unlock(&apply_lock);
 
@@ -1240,6 +1261,7 @@ bool dss_ovl_is_enabled(struct omap_overlay *ovl)
 int dss_ovl_enable(struct omap_overlay *ovl)
 {
 	struct ovl_priv_data *op = get_ovl_priv(ovl);
+	struct omap_dss_device *dssdev;
 	unsigned long flags;
 	int r;
 
@@ -1250,7 +1272,10 @@ int dss_ovl_enable(struct omap_overlay *ovl)
 		goto err1;
 	}
 
-	if (ovl->manager = NULL || ovl->manager->device = NULL) {
+	dssdev = ovl->manager ?
+		ovl->manager->get_output(ovl->manager) : NULL;
+
+	if (!dssdev) {
 		r = -EINVAL;
 		goto err1;
 	}
@@ -1259,7 +1284,7 @@ int dss_ovl_enable(struct omap_overlay *ovl)
 
 	op->enabling = true;
 
-	r = dss_check_settings(ovl->manager, ovl->manager->device);
+	r = dss_check_settings(ovl->manager, dssdev);
 	if (r) {
 		DSSERR("failed to enable overlay %d: check_settings failed\n",
 				ovl->id);
@@ -1290,6 +1315,7 @@ err1:
 int dss_ovl_disable(struct omap_overlay *ovl)
 {
 	struct ovl_priv_data *op = get_ovl_priv(ovl);
+	struct omap_dss_device *dssdev;
 	unsigned long flags;
 	int r;
 
@@ -1300,7 +1326,10 @@ int dss_ovl_disable(struct omap_overlay *ovl)
 		goto err;
 	}
 
-	if (ovl->manager = NULL || ovl->manager->device = NULL) {
+	dssdev = ovl->manager ?
+		ovl->manager->get_output(ovl->manager) : NULL;
+
+	if (!dssdev) {
 		r = -EINVAL;
 		goto err;
 	}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a5ec7f3..b228e05 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -419,7 +419,7 @@ static struct omap_dss_device *dispc_mgr_get_device(enum omap_channel channel)
 	struct omap_overlay_manager *mgr  		omap_dss_get_overlay_manager(channel);
 
-	return mgr ? mgr->device : NULL;
+	return mgr ? mgr->get_output(mgr) : NULL;
 }
 
 u32 dispc_mgr_get_vsync_irq(enum omap_channel channel)
@@ -3096,7 +3096,7 @@ static void dispc_error_worker(struct work_struct *work)
 		bit = sync_lost_bits[i];
 
 		if (bit & errors) {
-			struct omap_dss_device *dssdev = mgr->device;
+			struct omap_dss_device *dssdev = mgr->get_output(mgr);
 			bool enable;
 
 			DSSERR("SYNC_LOST on channel %s, restarting the output "
@@ -3127,9 +3127,12 @@ static void dispc_error_worker(struct work_struct *work)
 		DSSERR("OCP_ERR\n");
 		for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
 			struct omap_overlay_manager *mgr;
+			struct omap_dss_device *dssdev;
+
 			mgr = omap_dss_get_overlay_manager(i);
-			if (mgr->device && mgr->device->driver)
-				mgr->device->driver->disable(mgr->device);
+			dssdev = mgr->get_output(mgr);
+			if (dssdev && dssdev->driver)
+				dssdev->driver->disable(dssdev);
 		}
 	}
 
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index d1858e7..094c96c 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -43,8 +43,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)
 {
-	return snprintf(buf, PAGE_SIZE, "%s\n",
-			mgr->device ? mgr->device->name : "<none>");
+	struct omap_dss_device *dssdev = mgr->get_output(mgr);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
+			dssdev->name : "<none>");
 }
 
 static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
@@ -72,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (dssdev)
 		DSSDBG("display %s found\n", dssdev->name);
 
-	if (mgr->device) {
+	if (mgr->get_output(mgr)) {
 		r = mgr->unset_device(mgr);
 		if (r) {
 			DSSERR("failed to unset display\n");
@@ -490,14 +492,23 @@ static struct kobj_type manager_ktype = {
 	.default_attrs = manager_sysfs_attrs,
 };
 
+static inline struct omap_dss_device *dss_mgr_get_output(struct omap_overlay_manager *mgr)
+{
+	return mgr->output->device;
+}
+
 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
+	struct omap_dss_device *dssdev = mgr->get_output(mgr);
 	u32 irq;
 
-	if (mgr->device->type = OMAP_DISPLAY_TYPE_VENC) {
+	if (!dssdev)
+		return 0;
+
+	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC) {
 		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;
 	} else {
 		if (mgr->id = OMAP_DSS_CHANNEL_LCD)
@@ -522,6 +533,11 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 	for (i = 0; i < num_managers; ++i) {
 		struct omap_overlay_manager *mgr = &managers[i];
 
+		mgr->output = kzalloc(sizeof(struct omap_dss_mgr_output *),
+				GFP_KERNEL);
+
+		BUG_ON(mgr->output = NULL);
+
 		switch (i) {
 		case 0:
 			mgr->name = "lcd";
@@ -545,6 +561,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->wait_for_go = &dss_mgr_wait_for_go;
 		mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
 
+		mgr->get_output = &dss_mgr_get_output;
+
 		mgr->caps = 0;
 		mgr->supported_displays  			dss_feat_get_supported_displays(mgr->id);
@@ -568,6 +586,7 @@ void dss_uninit_overlay_managers(struct platform_device *pdev)
 	for (i = 0; i < num_managers; ++i) {
 		struct omap_overlay_manager *mgr = &managers[i];
 
+		kfree(mgr->output);
 		kobject_del(&mgr->kobj);
 		kobject_put(&mgr->kobj);
 	}
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index 6e82181..c72275e 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -536,16 +536,16 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 		lcd2_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD2);
 
 	if (dssdev->channel = OMAP_DSS_CHANNEL_LCD2) {
-		if (!lcd2_mgr->device || force) {
-			if (lcd2_mgr->device)
+		if (!lcd2_mgr->output->device || force) {
+			if (lcd2_mgr->output->device)
 				lcd2_mgr->unset_device(lcd2_mgr);
 			lcd2_mgr->set_device(lcd2_mgr, dssdev);
 			mgr = lcd2_mgr;
 		}
 	} else if (dssdev->type != OMAP_DISPLAY_TYPE_VENC
 			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
-		if (!lcd_mgr->device || force) {
-			if (lcd_mgr->device)
+		if (!lcd_mgr->output->device || force) {
+			if (lcd_mgr->output->device)
 				lcd_mgr->unset_device(lcd_mgr);
 			lcd_mgr->set_device(lcd_mgr, dssdev);
 			mgr = lcd_mgr;
@@ -554,8 +554,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 
 	if (dssdev->type = OMAP_DISPLAY_TYPE_VENC
 			|| dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
-		if (!tv_mgr->device || force) {
-			if (tv_mgr->device)
+		if (!tv_mgr->output->device || force) {
+			if (tv_mgr->output->device)
 				tv_mgr->unset_device(tv_mgr);
 			tv_mgr->set_device(tv_mgr, dssdev);
 			mgr = tv_mgr;
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
index 46024ab..fe0aa98 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/omap2/omapfb/omapfb-main.c
@@ -2412,6 +2412,7 @@ static int omapfb_probe(struct platform_device *pdev)
 	struct omap_overlay *ovl;
 	struct omap_dss_device *def_display;
 	struct omap_dss_device *dssdev;
+	struct omap_dss_device *mgr_device;
 
 	DBG("omapfb_probe\n");
 
@@ -2485,8 +2486,10 @@ static int omapfb_probe(struct platform_device *pdev)
 	/* gfx overlay should be the default one. find a display
 	 * connected to that, and use it as default display */
 	ovl = omap_dss_get_overlay(0);
-	if (ovl->manager && ovl->manager->device) {
-		def_display = ovl->manager->device;
+	mgr_device = ovl->manager ?
+		ovl->manager->get_output(ovl->manager) : NULL;
+	if (mgr_device) {
+		def_display = mgr_device;
 	} else {
 		dev_warn(&pdev->dev, "cannot find default display\n");
 		def_display = NULL;
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
index b03fb13..45b1f81 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/omap2/omapfb/omapfb.h
@@ -148,8 +148,9 @@ static inline struct omap_dss_device *fb2display(struct fb_info *fbi)
 
 	/* XXX: returns the display connected to first attached overlay */
 	for (i = 0; i < ofbi->num_overlays; i++) {
-		if (ofbi->overlays[i]->manager)
-			return ofbi->overlays[i]->manager->device;
+		struct omap_overlay_manager *mgr = ofbi->overlays[i]->manager;
+		if (mgr)
+			return mgr->get_output(mgr);
 	}
 
 	return NULL;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 39862b8..1b968bb 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -411,6 +411,10 @@ struct omap_overlay {
 	int (*wait_for_go)(struct omap_overlay *ovl);
 };
 
+struct omap_dss_mgr_output {
+	struct omap_dss_device *device;
+};
+
 struct omap_overlay_manager_info {
 	u32 default_color;
 
@@ -435,7 +439,7 @@ struct omap_overlay_manager {
 	enum omap_display_type supported_displays;
 
 	/* dynamic fields */
-	struct omap_dss_device *device;
+	struct omap_dss_mgr_output *output;
 
 	/*
 	 * The following functions do not block:
@@ -460,6 +464,8 @@ struct omap_overlay_manager {
 	int (*apply)(struct omap_overlay_manager *mgr);
 	int (*wait_for_go)(struct omap_overlay_manager *mgr);
 	int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
+
+	struct omap_dss_device *(*get_output)(struct omap_overlay_manager *mgr);
 };
 
 struct omap_dss_device {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 02/29] OMAPDSS: Add writeback to omap_dss_mgr_output
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 01/29] omapdss/omapfb/omap_vout: Introduce manager output struct Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 03/29] OMAPDSS: Writeback: Add writeback interface and panel driver Archit Taneja
                   ` (26 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add a omap_dss_device pointer in omap_dss_mgr_output to represent a writeback
device. The writeback device is a dummy omap_dss_device pointer connected to
the manager. It is a place holder for the actual writeback entity and is used
for compatibility with the existing DSS2 code.

Create helper overlay manager functions get_display() and get_writeback() which
return mgr->output->device and mgr->output->writeback devices. Modify
get_output() to return the display device if both device and writeback pointers
are set. Otherwise, return the omap_dss_device pointer which is set.

If writeback is in use, get_output() returns the display device if we are in
capture mode, and it returns the writeback device if we are in memory to memory
mode. This is beneficial as most checks/configurations for overlays and managers
should be done on the basis of the manager's output display in capture mode, and
the writeback device in case of memory to memory mode.

get_display() should be used when we are interested specifically in the
connected display, the same holds for get_writeback().

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/manager.c |   19 +++++++++++++++++--
 include/video/omapdss.h           |    3 +++
 2 files changed, 20 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 094c96c..4962f7b 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -43,7 +43,7 @@ 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)
 {
-	struct omap_dss_device *dssdev = mgr->get_output(mgr);
+	struct omap_dss_device *dssdev = mgr->get_display(mgr);
 
 	return snprintf(buf, PAGE_SIZE, "%s\n", dssdev ?
 			dssdev->name : "<none>");
@@ -74,7 +74,7 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (dssdev)
 		DSSDBG("display %s found\n", dssdev->name);
 
-	if (mgr->get_output(mgr)) {
+	if (mgr->get_display(mgr)) {
 		r = mgr->unset_device(mgr);
 		if (r) {
 			DSSERR("failed to unset display\n");
@@ -494,9 +494,22 @@ static struct kobj_type manager_ktype = {
 
 static inline struct omap_dss_device *dss_mgr_get_output(struct omap_overlay_manager *mgr)
 {
+	if (mgr->output->device)
+		return mgr->output->device;
+
+	return mgr->output->writeback;
+}
+
+static inline struct omap_dss_device *dss_mgr_get_display(struct omap_overlay_manager *mgr)
+{
 	return mgr->output->device;
 }
 
+static inline struct omap_dss_device *dss_mgr_get_writeback(struct omap_overlay_manager *mgr)
+{
+	return mgr->output->writeback;
+}
+
 static int dss_mgr_wait_for_vsync(struct omap_overlay_manager *mgr)
 {
 	unsigned long timeout = msecs_to_jiffies(500);
@@ -562,6 +575,8 @@ int dss_init_overlay_managers(struct platform_device *pdev)
 		mgr->wait_for_vsync = &dss_mgr_wait_for_vsync;
 
 		mgr->get_output = &dss_mgr_get_output;
+		mgr->get_display = &dss_mgr_get_display;
+		mgr->get_writeback = &dss_mgr_get_writeback;
 
 		mgr->caps = 0;
 		mgr->supported_displays diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 1b968bb..93a1cd3 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -413,6 +413,7 @@ struct omap_overlay {
 
 struct omap_dss_mgr_output {
 	struct omap_dss_device *device;
+	struct omap_dss_device *writeback;
 };
 
 struct omap_overlay_manager_info {
@@ -466,6 +467,8 @@ struct omap_overlay_manager {
 	int (*wait_for_vsync)(struct omap_overlay_manager *mgr);
 
 	struct omap_dss_device *(*get_output)(struct omap_overlay_manager *mgr);
+	struct omap_dss_device *(*get_display)(struct omap_overlay_manager *mgr);
+	struct omap_dss_device *(*get_writeback)(struct omap_overlay_manager *mgr);
 };
 
 struct omap_dss_device {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 03/29] OMAPDSS: Writeback: Add writeback interface and panel driver
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 01/29] omapdss/omapfb/omap_vout: Introduce manager output struct Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 02/29] OMAPDSS: Add writeback to omap_dss_mgr_output Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 04/29] OMAPDSS: APPLY/Writeback: Add writeback_info Archit Taneja
                   ` (25 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Create a new struct called omap_dss_writeback. This will represent a writeback
pipeline the way omap_overlay and omap_overlay_manager represent overlay and
managers respectively.

Create a writeback interface and a dummy writeback panel driver. The writeback
panel driver is needed for the omap_dss_device pointer which represents
writeback in omap_dss_mgr_output.

Add a omap_dss_device pointer to the omap_dss_writeback struct, and a
omap_dss_writeback pointer in omap_dss_device struct, link the writeback and
dss_device together when the latter is added.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/Makefile       |    2 +-
 drivers/video/omap2/dss/core.c         |    2 +
 drivers/video/omap2/dss/display.c      |    3 +
 drivers/video/omap2/dss/dss.h          |    5 +
 drivers/video/omap2/dss/dss_features.c |    8 +
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/writeback.c    |  223 ++++++++++++++++++++++++++++++++
 include/video/omapdss.h                |   13 ++
 8 files changed, 256 insertions(+), 1 deletions(-)
 create mode 100644 drivers/video/omap2/dss/writeback.c

diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
index 5c450b0..51c544e 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/omap2/dss/Makefile
@@ -1,6 +1,6 @@
 obj-$(CONFIG_OMAP2_DSS) += omapdss.o
 omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
-	manager.o overlay.o apply.o
+	manager.o overlay.o apply.o writeback.o
 omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
 omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
 omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 5c46430..21bfd0a 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -182,6 +182,7 @@ static int omap_dss_probe(struct platform_device *pdev)
 
 	dss_init_overlay_managers(pdev);
 	dss_init_overlays(pdev);
+	dss_init_writeback();
 
 	r = dss_init_platform_driver();
 	if (r) {
@@ -276,6 +277,7 @@ static int omap_dss_remove(struct platform_device *pdev)
 	dispc_uninit_platform_driver();
 	dss_uninit_platform_driver();
 
+	dss_uninit_writeback();
 	dss_uninit_overlays(pdev);
 	dss_uninit_overlay_managers(pdev);
 
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index be331dc..a712bad 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -391,6 +391,9 @@ void dss_init_device(struct platform_device *pdev,
 	case OMAP_DISPLAY_TYPE_HDMI:
 		r = hdmi_init_display(dssdev);
 		break;
+	case OMAP_DISPLAY_TYPE_WB:
+		r = writeback_init_display(dssdev);
+		break;
 	default:
 		DSSERR("Support for display '%s' not compiled in.\n",
 				dssdev->name);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 3cf99a9..607e730 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -226,6 +226,11 @@ int dss_ovl_simple_check(struct omap_overlay *ovl,
 int dss_ovl_check(struct omap_overlay *ovl,
 		struct omap_overlay_info *info, struct omap_dss_device *dssdev);
 
+/* writeback */
+void dss_init_writeback(void);
+void dss_uninit_writeback(void);
+int writeback_init_display(struct omap_dss_device *dssdev);
+
 /* DSS */
 int dss_init_platform_driver(void);
 void dss_uninit_platform_driver(void);
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 5e4b829..ca41620 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -45,6 +45,7 @@ struct omap_dss_features {
 
 	const int num_mgrs;
 	const int num_ovls;
+	const int num_wb;
 	const enum omap_display_type *supported_displays;
 	const enum omap_color_mode *supported_color_modes;
 	const enum omap_overlay_caps *overlay_caps;
@@ -423,6 +424,7 @@ static const struct omap_dss_features omap4430_es1_0_dss_features  = {
 
 	.num_mgrs = 3,
 	.num_ovls = 4,
+	.num_wb = 1,
 	.supported_displays = omap4_dss_supported_displays,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
@@ -447,6 +449,7 @@ static const struct omap_dss_features omap4_dss_features = {
 
 	.num_mgrs = 3,
 	.num_ovls = 4,
+	.num_wb = 1,
 	.supported_displays = omap4_dss_supported_displays,
 	.supported_color_modes = omap4_dss_supported_color_modes,
 	.overlay_caps = omap4_dss_overlay_caps,
@@ -493,6 +496,11 @@ int dss_feat_get_num_ovls(void)
 	return omap_current_dss_features->num_ovls;
 }
 
+int dss_feat_get_num_wb(void)
+{
+	return omap_current_dss_features->num_wb;
+}
+
 unsigned long dss_feat_get_param_min(enum dss_range_param param)
 {
 	return omap_current_dss_features->dss_params[param].min;
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index cd833bb..75ee1f1 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -92,6 +92,7 @@ enum dss_range_param {
 /* DSS Feature Functions */
 int dss_feat_get_num_mgrs(void);
 int dss_feat_get_num_ovls(void);
+int dss_feat_get_num_wb(void);
 unsigned long dss_feat_get_param_min(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);
diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
new file mode 100644
index 0000000..ac5d3ba
--- /dev/null
+++ b/drivers/video/omap2/dss/writeback.c
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2011 Texas Instruments
+ * 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/>.
+ */
+
+#define DSS_SUBSYS_NAME "WRITEBACK"
+
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/err.h>
+#include <linux/sysfs.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+#include "dss_features.h"
+
+static int num_writeback, num_wb_panels;
+static struct omap_dss_writeback *writeback;
+static struct omap_dss_driver writeback_panel_driver;
+
+static int dss_writeback_enable(struct omap_dss_writeback *wb)
+{
+	int r;
+
+	r = dispc_runtime_get();
+	if (r)
+		return r;
+
+	return 0;
+}
+
+static void dss_writeback_disable(struct omap_dss_writeback *wb)
+{
+	dispc_runtime_put();
+}
+
+struct omap_dss_writeback *omap_dss_get_writeback(int id)
+{
+	if (id >= num_writeback)
+		return NULL;
+
+	return &writeback[id];
+}
+EXPORT_SYMBOL(omap_dss_get_writeback);
+
+int omap_dss_get_num_writeback(void)
+{
+	return num_writeback;
+}
+EXPORT_SYMBOL(omap_dss_get_num_writeback);
+
+void dss_init_writeback(void)
+{
+	int i;
+
+	num_writeback = dss_feat_get_num_wb();
+
+	writeback = kzalloc(sizeof(struct omap_dss_writeback) * num_writeback,
+		GFP_KERNEL);
+
+	BUG_ON(writeback = NULL);
+
+	for (i = 0; i < num_writeback; i++) {
+		struct omap_dss_writeback *wb = &writeback[i];
+
+		wb->id = i;
+	}
+
+	omap_dss_register_driver(&writeback_panel_driver);
+}
+
+void dss_uninit_writeback(void)
+{
+	kfree(writeback);
+	writeback = NULL;
+	num_writeback = 0;
+
+	omap_dss_unregister_driver(&writeback_panel_driver);
+}
+
+int writeback_init_display(struct omap_dss_device *dssdev)
+{
+	struct omap_dss_writeback *wb;
+
+	DSSDBG("init_display\n");
+
+	if (num_wb_panels >= num_writeback)
+		return -EINVAL;
+
+	wb = omap_dss_get_writeback(num_wb_panels++);
+
+	wb->dssdev = dssdev;
+	dssdev->wbdev = wb;
+
+	return 0;
+}
+
+/* Dummy Writeback Panel driver */
+
+static int writeback_panel_probe(struct omap_dss_device *dssdev)
+{
+	return 0;
+}
+
+static void __exit writeback_panel_remove(struct omap_dss_device *dssdev)
+{
+}
+
+static int writeback_panel_power_on(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	if (dssdev->state = OMAP_DSS_DISPLAY_ACTIVE)
+		return 0;
+
+	r = dss_writeback_enable(dssdev->wbdev);
+	if (r)
+		return r;
+
+	return 0;
+}
+
+static void writeback_panel_power_off(struct omap_dss_device *dssdev)
+{
+	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE)
+		return;
+
+	dss_writeback_disable(dssdev->wbdev);
+}
+
+static int writeback_panel_enable(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	r = writeback_panel_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static void writeback_panel_disable(struct omap_dss_device *dssdev)
+{
+	writeback_panel_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
+}
+
+static int writeback_panel_suspend(struct omap_dss_device *dssdev)
+{
+	writeback_panel_power_off(dssdev);
+
+	dssdev->state = OMAP_DSS_DISPLAY_SUSPENDED;
+
+	return 0;
+}
+
+static int writeback_panel_resume(struct omap_dss_device *dssdev)
+{
+	int r;
+
+	r = writeback_panel_power_on(dssdev);
+	if (r)
+		return r;
+
+	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
+
+	return 0;
+}
+
+static void writeback_panel_set_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	dssdev->panel.timings.x_res = timings->x_res;
+	dssdev->panel.timings.y_res = timings->y_res;
+}
+
+static void writeback_panel_get_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	*timings = dssdev->panel.timings;
+}
+
+static int writeback_panel_check_timings(struct omap_dss_device *dssdev,
+		struct omap_video_timings *timings)
+{
+	return 0;
+}
+
+static struct omap_dss_driver writeback_panel_driver = {
+	.probe = writeback_panel_probe,
+	.remove = writeback_panel_remove,
+
+	.enable = writeback_panel_enable,
+	.disable = writeback_panel_disable,
+	.suspend = writeback_panel_suspend,
+	.resume = writeback_panel_resume,
+
+	.set_timings = writeback_panel_set_timings,
+	.get_timings = writeback_panel_get_timings,
+	.check_timings = writeback_panel_check_timings,
+
+	.driver = {
+		.name = "writeback",
+		.owner = THIS_MODULE,
+	},
+};
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 93a1cd3..77e2ca4 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -60,6 +60,7 @@ enum omap_display_type {
 	OMAP_DISPLAY_TYPE_DSI		= 1 << 3,
 	OMAP_DISPLAY_TYPE_VENC		= 1 << 4,
 	OMAP_DISPLAY_TYPE_HDMI		= 1 << 5,
+	OMAP_DISPLAY_TYPE_WB		= 1 << 6,
 };
 
 enum omap_plane {
@@ -471,6 +472,13 @@ struct omap_overlay_manager {
 	struct omap_dss_device *(*get_writeback)(struct omap_overlay_manager *mgr);
 };
 
+struct omap_dss_writeback {
+	int id;
+
+	/* dummy panel we are connected to */
+	struct omap_dss_device *dssdev;
+};
+
 struct omap_dss_device {
 	struct device dev;
 
@@ -584,6 +592,8 @@ struct omap_dss_device {
 
 	struct omap_overlay_manager *manager;
 
+	struct omap_dss_writeback *wbdev;
+
 	enum omap_dss_display_state state;
 
 	/* platform specific  */
@@ -661,6 +671,9 @@ struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
 int omap_dss_get_num_overlays(void);
 struct omap_overlay *omap_dss_get_overlay(int num);
 
+struct omap_dss_writeback *omap_dss_get_writeback(int id);
+int omap_dss_get_num_writeback(void);
+
 void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
 		u16 *xres, u16 *yres);
 int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 04/29] OMAPDSS: APPLY/Writeback: Add writeback_info
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (2 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 03/29] OMAPDSS: Writeback: Add writeback interface and panel driver Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 05/29] OMAPDSS: APPLY/Writeback: Apply writeback configurations Archit Taneja
                   ` (24 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Create a struct called omap_dss_writeback_info. This contains 'overlay like'
parameters of the writeback pipeline. These parameters are expected to be
configured via get/set_info ops by the DSS2 user similar to how overlay and
manager parameters are configured. These will also be configurable via sysfs
attributes of the dummy writeback panel.

Add get_wb_info/set_wb_info ops in omap_dss_writeback struct. Create a minimal
wb_priv_data structure and a writeback simple_check function used for
dss_wb_get_info and dss_wb_set_info functions in apply.c

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c        |   45 ++++++++++++++++++++++++++++++++
 drivers/video/omap2/dss/dss.h          |    7 +++++
 drivers/video/omap2/dss/dss_features.h |    1 +
 drivers/video/omap2/dss/writeback.c    |   27 +++++++++++++++++++
 include/video/omapdss.h                |   18 ++++++++++++
 5 files changed, 98 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index d529664..19120c1 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -101,9 +101,16 @@ struct mgr_priv_data {
 	bool enabled;
 };
 
+struct wb_priv_data {
+
+	bool user_info_dirty;
+	struct omap_dss_writeback_info user_info;
+};
+
 static struct {
 	struct ovl_priv_data ovl_priv_data_array[MAX_DSS_OVERLAYS];
 	struct mgr_priv_data mgr_priv_data_array[MAX_DSS_MANAGERS];
+	struct wb_priv_data wb_priv_data_array[MAX_DSS_WB];
 
 	bool irq_enabled;
 } dss_data;
@@ -126,6 +133,11 @@ static struct mgr_priv_data *get_mgr_priv(struct omap_overlay_manager *mgr)
 	return &dss_data.mgr_priv_data_array[mgr->id];
 }
 
+static struct wb_priv_data *get_wb_priv(struct omap_dss_writeback *wb)
+{
+	return &dss_data.wb_priv_data_array[wb->id];
+}
+
 void dss_apply_init(void)
 {
 	const int num_ovls = dss_feat_get_num_ovls();
@@ -1351,3 +1363,36 @@ err:
 	return r;
 }
 
+int dss_wb_set_info(struct omap_dss_writeback *wb,
+		struct omap_dss_writeback_info *info)
+{
+	struct wb_priv_data *wp = get_wb_priv(wb);
+	unsigned long flags;
+	int r;
+
+	r = dss_wb_simple_check(wb, info);
+	if (r)
+		return r;
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	wp->user_info = *info;
+	wp->user_info_dirty = true;
+
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	return 0;
+}
+
+void dss_wb_get_info(struct omap_dss_writeback *wb,
+		struct omap_dss_writeback_info *info)
+{
+	struct wb_priv_data *wp = get_wb_priv(wb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	*info = wp->user_info;
+
+	spin_unlock_irqrestore(&data_lock, flags);
+}
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 607e730..9b3b93c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -191,6 +191,11 @@ int dss_ovl_set_manager(struct omap_overlay *ovl,
 		struct omap_overlay_manager *mgr);
 int dss_ovl_unset_manager(struct omap_overlay *ovl);
 
+int dss_wb_set_info(struct omap_dss_writeback *wb,
+		struct omap_dss_writeback_info *info);
+void dss_wb_get_info(struct omap_dss_writeback *wb,
+		struct omap_dss_writeback_info *info);
+
 /* display */
 int dss_suspend_all_devices(void);
 int dss_resume_all_devices(void);
@@ -230,6 +235,8 @@ int dss_ovl_check(struct omap_overlay *ovl,
 void dss_init_writeback(void);
 void dss_uninit_writeback(void);
 int writeback_init_display(struct omap_dss_device *dssdev);
+int dss_wb_simple_check(struct omap_dss_writeback *wb,
+		const struct omap_dss_writeback_info *info);
 
 /* DSS */
 int dss_init_platform_driver(void);
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/omap2/dss/dss_features.h
index 75ee1f1..b3486da 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/omap2/dss/dss_features.h
@@ -28,6 +28,7 @@
 #define MAX_DSS_OVERLAYS	4
 #define MAX_DSS_LCD_MANAGERS	2
 #define MAX_NUM_DSI		2
+#define MAX_DSS_WB		1
 
 /* DSS has feature id */
 enum dss_feat_id {
diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index ac5d3ba..5e54221 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -78,6 +78,9 @@ void dss_init_writeback(void)
 		struct omap_dss_writeback *wb = &writeback[i];
 
 		wb->id = i;
+
+		wb->set_wb_info = &dss_wb_set_info;
+		wb->get_wb_info = &dss_wb_get_info;
 	}
 
 	omap_dss_register_driver(&writeback_panel_driver);
@@ -109,6 +112,30 @@ int writeback_init_display(struct omap_dss_device *dssdev)
 	return 0;
 }
 
+int dss_wb_simple_check(struct omap_dss_writeback *wb,
+		const struct omap_dss_writeback_info *info)
+{
+	if (info->paddr = 0) {
+		DSSERR("wb_simple_check: paddr cannot be 0\n");
+		return -EINVAL;
+	}
+
+	if (info->color_mode = OMAP_DSS_COLOR_NV12 &&
+			info->p_uv_addr = 0) {
+		DSSERR("wb_simple_check: p_uv_addr cannot be 0 for NV12"
+			" format\n");
+		return -EINVAL;
+	}
+
+	if (info->capture_rate < 0 || info->capture_rate > 7) {
+		DSSERR("wb_simple_check: capture rate cannot be %d\n",
+			info->capture_rate);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
 /* Dummy Writeback Panel driver */
 
 static int writeback_panel_probe(struct omap_dss_device *dssdev)
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 77e2ca4..01092e4 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -472,11 +472,29 @@ struct omap_overlay_manager {
 	struct omap_dss_device *(*get_writeback)(struct omap_overlay_manager *mgr);
 };
 
+struct omap_dss_writeback_info {
+	u32 paddr;
+	u32 p_uv_addr;
+	u16 buf_width;
+	u16 buf_height;
+	enum omap_color_mode color_mode;
+	u8 rotation;
+	enum omap_dss_rotation_type rotation_type;
+	bool mirror;
+	u8 pre_mult_alpha;
+	int capture_rate;
+};
+
 struct omap_dss_writeback {
 	int id;
 
 	/* dummy panel we are connected to */
 	struct omap_dss_device *dssdev;
+
+	int (*set_wb_info)(struct omap_dss_writeback *wb,
+		struct omap_dss_writeback_info *info);
+	void (*get_wb_info)(struct omap_dss_writeback *wb,
+		struct omap_dss_writeback_info *info);
 };
 
 struct omap_dss_device {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 05/29] OMAPDSS: APPLY/Writeback: Apply writeback configurations
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (3 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 04/29] OMAPDSS: APPLY/Writeback: Add writeback_info Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 06/29] OMAPDSS: APPLY: Add writeback enable/disable functions Archit Taneja
                   ` (23 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

The writeback pipeline has properties of both overlays and overlay managers.
It is like an overlay as it has programmable base addresses and contains blocks
like scalar, color conversion unit, truncation unit, DISPC DMA FIFO. It is like
a manager as enabling it immediately starts transfer to the memory, and it has
a GO bit to use a new writeback configuration. Hence, writeback is a separate
entity when it comes to applying configurations.

When it comes to applying user_info to the private info maintained by DSS2, the
writeback pipeline can be considered tightly coupled with the manager it is
connected to. This makes sense as in the current DSS2 design as writeback is
always connected to a manager in all its modes. In capture mode, writeback is
connected to the manager from which we are capturing the frames. In memory to
memory mode, we would either connected to a manager if we are capturing the
manager's output, or we would connect to a dummy writeback manager when we are
capturing data from just one overlay.Calling a manager's apply() calls
omap_dss_mgr_apply_wb(), which copies the user_info to the private info struct
only if that manager has writeback connected to it. Hence, copying user_info
to private info for writeback is similar to how it is done for overlays.

Unlike overlays, writeback configurations can't be totally governed by the state
of the manager. In capture mode, writeback registers are governed by the GO bit
of WB. Hence, a new configuration can be written to writeback shadow registers
even if the manager it is connected to is busy. Hence, copying of private info
to shadow register and setting GO bit for writeback is similar to how it is done
for managers.

We register to dss_apply_irq_handler() if writeback needs to write a pending
configuration or clear the busy and shadow_dirty status if the previous
configuration was transferred from the shadow registers successfully. This
isn't optimal for capture mode as a new/pending writeback configuration is
applied sometime later than the connected manager's VSYNC interrupt. The new
configuration is taken only after WBDELAYCOUNT lines(in time) are generated by
the manager after the VSYNC interrupt.

Since we don't have any interrupt to get this event. We currently register
to the manager's VSYNC interrupt itself. The correct approach would be to
generate a timer based interrupt event after approximately WBDELAYCOUNT lines
after we get the VSYNC interrupts. This is not done for now.

Create dummy dispc_wb_go/go_busy and wb_setup functions. These will be filled
up in a later commit.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c |  164 ++++++++++++++++++++++++++++++++++++++-
 drivers/video/omap2/dss/dispc.c |   15 ++++
 drivers/video/omap2/dss/dss.h   |    4 +
 3 files changed, 181 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 19120c1..f40f58c 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -105,6 +105,15 @@ struct wb_priv_data {
 
 	bool user_info_dirty;
 	struct omap_dss_writeback_info user_info;
+
+	bool info_dirty;
+	struct omap_dss_writeback_info info;
+
+	bool shadow_info_dirty;
+
+	/* If true, GO bit is up and shadow registers cannot be written.
+	 * Never true for writeback in memory to memory mode */
+	bool busy;
 };
 
 static struct {
@@ -250,6 +259,7 @@ static bool need_isr(void)
 		struct omap_overlay_manager *mgr;
 		struct mgr_priv_data *mp;
 		struct omap_overlay *ovl;
+		struct omap_dss_device *dssdev;
 
 		mgr = omap_dss_get_overlay_manager(i);
 		mp = get_mgr_priv(mgr);
@@ -304,13 +314,29 @@ static bool need_isr(void)
 				if (op->shadow_info_dirty)
 					return true;
 			}
+
+			dssdev = mgr->get_writeback(mgr);
+			if (dssdev) {
+				struct omap_dss_writeback *wb = dssdev->wbdev;
+				struct wb_priv_data *wp = get_wb_priv(wb);
+
+				if (wp->busy)
+					return true;
+
+				if (wp->info_dirty)
+					return true;
+
+				if (wp->shadow_info_dirty)
+					return true;
+
+			}
 		}
 	}
 
 	return false;
 }
 
-static bool need_go(struct omap_overlay_manager *mgr)
+static bool need_mgr_go(struct omap_overlay_manager *mgr)
 {
 	struct omap_overlay *ovl;
 	struct mgr_priv_data *mp;
@@ -330,6 +356,18 @@ static bool need_go(struct omap_overlay_manager *mgr)
 	return false;
 }
 
+static bool need_wb_go(struct omap_dss_writeback *wb)
+{
+	struct wb_priv_data *wp;
+
+	wp = get_wb_priv(wb);
+
+	if (wp->shadow_info_dirty)
+		return true;
+
+	return false;
+}
+
 /* returns true if an extra_info field is currently being updated */
 static bool extra_info_update_ongoing(void)
 {
@@ -577,6 +615,29 @@ static void dss_ovl_write_regs_extra(struct omap_overlay *ovl)
 		op->shadow_extra_info_dirty = true;
 }
 
+static void dss_wb_write_regs(struct omap_dss_writeback *wb)
+{
+	struct wb_priv_data *wp = get_wb_priv(wb);
+	struct omap_dss_writeback_info *wi;
+	int r;
+
+	if (!wp->info_dirty)
+		return;
+
+	WARN_ON(wp->busy);
+
+	wi = &wp->info;
+
+	r = dispc_wb_setup(wb->id, wi);
+	if (r) {
+		DSSERR("dispc_wb_setup failed\n");
+		return;
+	}
+
+	wp->info_dirty = false;
+	wp->shadow_info_dirty = true;
+}
+
 static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -607,6 +668,7 @@ static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
 static void dss_write_regs(void)
 {
 	const int num_mgrs = omap_dss_get_num_overlay_managers();
+	const int num_wb = dss_feat_get_num_wb();
 	int i;
 
 	for (i = 0; i < num_mgrs; ++i) {
@@ -631,11 +693,30 @@ static void dss_write_regs(void)
 
 		dss_mgr_write_regs(mgr);
 	}
+
+	for (i = 0; i < num_wb; ++i) {
+		struct omap_dss_writeback *wb;
+		struct wb_priv_data *wp;
+		struct mgr_priv_data *mp;
+
+		wb = omap_dss_get_writeback(i);
+		wp = get_wb_priv(wb);
+		mp = get_mgr_priv(wb->dssdev->manager);
+
+		if (!mp->enabled)
+			continue;
+
+		if (wp->busy)
+			continue;
+
+		dss_wb_write_regs(wb);
+	}
 }
 
 static void dss_set_go_bits(void)
 {
 	const int num_mgrs = omap_dss_get_num_overlay_managers();
+	const int num_wb = dss_feat_get_num_wb();
 	int i;
 
 	for (i = 0; i < num_mgrs; ++i) {
@@ -648,7 +729,7 @@ static void dss_set_go_bits(void)
 		if (!mp->enabled || mgr_manual_update(mgr) || mp->busy)
 			continue;
 
-		if (!need_go(mgr))
+		if (!need_mgr_go(mgr))
 			continue;
 
 		mp->busy = true;
@@ -659,6 +740,31 @@ static void dss_set_go_bits(void)
 		dispc_mgr_go(mgr->id);
 	}
 
+	for (i = 0; i < num_wb; ++i) {
+		struct omap_dss_writeback *wb;
+		struct wb_priv_data *wp;
+		struct mgr_priv_data *mp;
+
+		wb = omap_dss_get_writeback(i);
+		wp = get_wb_priv(wb);
+		mp = get_mgr_priv(wb->dssdev->manager);
+
+		if (!mp->enabled)
+			continue;
+
+		if (wp->busy)
+			continue;
+
+		if (!need_wb_go(wb))
+			continue;
+
+		wp->busy = true;
+
+		if (!dss_data.irq_enabled && need_isr())
+			dss_register_vsync_isr();
+
+		dispc_wb_go(wb->id);
+	}
 }
 
 void dss_mgr_start_update(struct omap_overlay_manager *mgr)
@@ -749,9 +855,18 @@ static void mgr_clear_shadow_dirty(struct omap_overlay_manager *mgr)
 	}
 }
 
+static void wb_clear_shadow_dirty(struct omap_dss_writeback *wb)
+{
+	struct wb_priv_data *wp;
+
+	wp = get_wb_priv(wb);
+	wp->shadow_info_dirty = false;
+}
+
 static void dss_apply_irq_handler(void *data, u32 mask)
 {
 	const int num_mgrs = dss_feat_get_num_mgrs();
+	const int num_wb = dss_feat_get_num_wb();
 	int i;
 	bool extra_updating;
 
@@ -784,6 +899,32 @@ static void dss_apply_irq_handler(void *data, u32 mask)
 		}
 	}
 
+
+	for (i = 0; i < num_wb; i++) {
+		struct omap_dss_writeback *wb;
+		struct wb_priv_data *wp;
+		bool was_busy;
+
+		wb = omap_dss_get_writeback(i);
+		wp = get_wb_priv(wb);
+
+		was_busy = wp->busy;
+		wp->busy = dispc_wb_go_busy(i);
+
+		/*
+		 * In writeback capture mode, the GO bit doesn't get reset
+		 * at the manager's VSYNC interrupt. It takes an extra
+		 * 'WBDELAYCOUNTER' time after VSYNC when the writeback
+		 * FIFOs are flushed and the shadow registers are taken in.
+		 * There isn't any DSS interrupt to notify this point in time.
+		 * The correct solution would be to set off a timer here which
+		 * generates an interrupt approximately after WBDELAYCOUNTER
+		 * time.
+		 */
+		if (was_busy && !wp->busy)
+			wb_clear_shadow_dirty(wb);
+	}
+
 	dss_write_regs();
 	dss_set_go_bits();
 
@@ -825,6 +966,20 @@ static void omap_dss_mgr_apply_mgr(struct omap_overlay_manager *mgr)
 	mp->info = mp->user_info;
 }
 
+static void omap_dss_mgr_apply_wb(struct omap_dss_writeback *wb)
+{
+	struct wb_priv_data *wp;
+
+	wp = get_wb_priv(wb);
+
+	if (!wp->user_info_dirty)
+		return;
+
+	wp->user_info_dirty = false;
+	wp->info_dirty = true;
+	wp->info = wp->user_info;
+}
+
 int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 {
 	unsigned long flags;
@@ -852,6 +1007,11 @@ int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
 	/* Configure manager */
 	omap_dss_mgr_apply_mgr(mgr);
 
+	/* Configure writeback */
+	dssdev = mgr->get_writeback(mgr);
+	if (dssdev)
+		omap_dss_mgr_apply_wb(dssdev->wbdev);
+
 	dss_write_regs();
 	dss_set_go_bits();
 
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index b228e05..d98905f 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -508,6 +508,16 @@ void dispc_mgr_go(enum omap_channel channel)
 		REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
 }
 
+bool dispc_wb_go_busy(int id)
+{
+	return false;
+}
+
+void dispc_wb_go(int id)
+{
+	return;
+}
+
 static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
 {
 	dispc_write_reg(DISPC_OVL_FIR_COEF_H(plane, reg), value);
@@ -1888,6 +1898,11 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 	return 0;
 }
 
+int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi)
+{
+	return 0;
+}
+
 int dispc_ovl_enable(enum omap_plane plane, bool enable)
 {
 	DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 9b3b93c..556bc7c 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -476,6 +476,10 @@ int dispc_mgr_get_clock_div(enum omap_channel channel,
 void dispc_mgr_setup(enum omap_channel channel,
 		struct omap_overlay_manager_info *info);
 
+bool dispc_wb_go_busy(int id);
+void dispc_wb_go(int id);
+int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi);
+
 /* VENC */
 #ifdef CONFIG_OMAP2_DSS_VENC
 int venc_init_platform_driver(void);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 06/29] OMAPDSS: APPLY: Add writeback enable/disable functions
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (4 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 05/29] OMAPDSS: APPLY/Writeback: Apply writeback configurations Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 07/29] OMAPDSS: APPLY: Add extra_info for writeback Archit Taneja
                   ` (22 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

In writeback capture mode, enabling writeback is similar to enabling an overlay
manager. It leads to an immediate copy of shadow registers to main registers and
starts DISPC DMA for frame transfer to the destination base addresses.

Hence, 'enabled' parameter for writeback is not a part of the writeback_info
struct. Its is maintained as a separate parameter like it's done for an overlay
manager.

Add dss_wb_enable/disable functions. Since we need to be connected to an enabled
manager when enabling writeback. Add checks to ensure that the connected manager
is enabled, add a check in dss_mgr_disable to issue a warning if writeback is in
use.

Call dss_setup_fifos() in dss_wb_enable(), this would be used to configure
writeback FIFOs in the future. Create a dummy dispc_wb_enable() function which
will be later filled up. Call dss_mgr_enable/disable through the dummy writeback
panel's enable/disable ops.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c     |   92 +++++++++++++++++++++++++++++++++-
 drivers/video/omap2/dss/dispc.c     |    5 ++
 drivers/video/omap2/dss/dss.h       |    3 +
 drivers/video/omap2/dss/writeback.c |   12 ++++-
 4 files changed, 108 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index f40f58c..5263ae7 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -114,6 +114,9 @@ struct wb_priv_data {
 	/* If true, GO bit is up and shadow registers cannot be written.
 	 * Never true for writeback in memory to memory mode */
 	bool busy;
+
+	/* If true, someone is using writeback */
+	bool enabled;
 };
 
 static struct {
@@ -320,6 +323,9 @@ static bool need_isr(void)
 				struct omap_dss_writeback *wb = dssdev->wbdev;
 				struct wb_priv_data *wp = get_wb_priv(wb);
 
+				if (!wp->enabled)
+					continue;
+
 				if (wp->busy)
 					return true;
 
@@ -621,7 +627,7 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb)
 	struct omap_dss_writeback_info *wi;
 	int r;
 
-	if (!wp->info_dirty)
+	if (!wp->enabled || !wp->info_dirty)
 		return;
 
 	WARN_ON(wp->busy);
@@ -703,7 +709,7 @@ static void dss_write_regs(void)
 		wp = get_wb_priv(wb);
 		mp = get_mgr_priv(wb->dssdev->manager);
 
-		if (!mp->enabled)
+		if (!mp->enabled || !wp->enabled)
 			continue;
 
 		if (wp->busy)
@@ -752,7 +758,7 @@ static void dss_set_go_bits(void)
 		if (!mp->enabled)
 			continue;
 
-		if (wp->busy)
+		if (!wp->enabled || wp->busy)
 			continue;
 
 		if (!need_wb_go(wb))
@@ -1163,6 +1169,7 @@ err:
 void dss_mgr_disable(struct omap_overlay_manager *mgr)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
+	struct omap_dss_device *dssdev = mgr->get_writeback(mgr);
 	unsigned long flags;
 
 	mutex_lock(&apply_lock);
@@ -1170,6 +1177,13 @@ void dss_mgr_disable(struct omap_overlay_manager *mgr)
 	if (!mp->enabled)
 		goto out;
 
+	if (dssdev) {
+		/* if writeback is connected to the manager, issue a warning
+		 * if it is enabled */
+		struct wb_priv_data *wp = get_wb_priv(dssdev->wbdev);
+		WARN_ON(wp->enabled);
+	}
+
 	if (!mgr_manual_update(mgr))
 		dispc_mgr_enable(mgr->id, false);
 
@@ -1556,3 +1570,75 @@ void dss_wb_get_info(struct omap_dss_writeback *wb,
 
 	spin_unlock_irqrestore(&data_lock, flags);
 }
+
+int dss_wb_enable(struct omap_dss_writeback *wb)
+{
+	struct wb_priv_data *wp = get_wb_priv(wb);
+	struct mgr_priv_data *mp;
+	unsigned long flags;
+	int r = 0;
+
+	mutex_lock(&apply_lock);
+
+	/* don't enable if it isn't connected to any manager */
+	if (!wb->dssdev->manager) {
+		r = -EINVAL;
+		goto out;
+	}
+
+	mp = get_mgr_priv(wb->dssdev->manager);
+
+	/* don't enable if the manager WB is connected to is disabled */
+	if (!mp->enabled) {
+		r = -EINVAL;
+		goto out;
+	}
+
+	if (wp->enabled)
+		goto out;
+
+	/* use a simple check for now */
+	r = dss_wb_simple_check(wb, &wp->info);
+	if (r)
+		goto out;
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	wp->enabled = true;
+
+	dss_setup_fifos();
+
+	dss_write_regs();
+	dss_set_go_bits();
+
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	dispc_wb_enable(wb->id, true);
+
+out:
+	mutex_unlock(&apply_lock);
+
+	return r;
+}
+
+void dss_wb_disable(struct omap_dss_writeback *wb)
+{
+	struct wb_priv_data *wp = get_wb_priv(wb);
+	unsigned long flags;
+
+	mutex_lock(&apply_lock);
+
+	if (!wp->enabled)
+		goto out;
+
+	dispc_wb_enable(wb->id, false);
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	wp->enabled = false;
+
+	spin_unlock_irqrestore(&data_lock, flags);
+
+out:
+	mutex_unlock(&apply_lock);
+}
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d98905f..35ed6ca 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -2070,6 +2070,11 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable)
 		BUG();
 }
 
+void dispc_wb_enable(int id, bool enable)
+{
+	return;
+}
+
 void dispc_lcd_enable_signal_polarity(bool act_high)
 {
 	if (!dss_has_feature(FEAT_LCDENABLEPOL))
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 556bc7c..bb25d96 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -195,6 +195,8 @@ int dss_wb_set_info(struct omap_dss_writeback *wb,
 		struct omap_dss_writeback_info *info);
 void dss_wb_get_info(struct omap_dss_writeback *wb,
 		struct omap_dss_writeback_info *info);
+int dss_wb_enable(struct omap_dss_writeback *wb);
+void dss_wb_disable(struct omap_dss_writeback *wb);
 
 /* display */
 int dss_suspend_all_devices(void);
@@ -479,6 +481,7 @@ void dispc_mgr_setup(enum omap_channel channel,
 bool dispc_wb_go_busy(int id);
 void dispc_wb_go(int id);
 int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi);
+void dispc_wb_enable(int id, bool enable);
 
 /* VENC */
 #ifdef CONFIG_OMAP2_DSS_VENC
diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index 5e54221..eefab4e 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -38,13 +38,23 @@ static int dss_writeback_enable(struct omap_dss_writeback *wb)
 
 	r = dispc_runtime_get();
 	if (r)
-		return r;
+		goto err0;
+
+	r = dss_wb_enable(wb);
+	if (r)
+		goto err1;
 
 	return 0;
+err1:
+	dispc_runtime_put();
+err0:
+	return r;
 }
 
 static void dss_writeback_disable(struct omap_dss_writeback *wb)
 {
+	dss_wb_disable(wb);
+
 	dispc_runtime_put();
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 07/29] OMAPDSS: APPLY: Add extra_info for writeback
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (5 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 06/29] OMAPDSS: APPLY: Add writeback enable/disable functions Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 08/29] OMAPDSS: APPLY: Modify manager unset device op Archit Taneja
                   ` (21 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Like overlays, writeback pipeline has a a FIFO and a channel which shouldn't
be configured along with the other info struct. Introduce flags extra_info
dirty and shadow_dirty flags. Configure them like done for overlays.

No extra parameters have been added for now. They will be added on later.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c |   48 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 47 insertions(+), 1 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 5263ae7..ff0baeb 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -111,6 +111,9 @@ struct wb_priv_data {
 
 	bool shadow_info_dirty;
 
+	bool extra_info_dirty;
+	bool shadow_extra_info_dirty;
+
 	/* If true, GO bit is up and shadow registers cannot be written.
 	 * Never true for writeback in memory to memory mode */
 	bool busy;
@@ -335,6 +338,12 @@ static bool need_isr(void)
 				if (wp->shadow_info_dirty)
 					return true;
 
+				if (wp->extra_info_dirty)
+					return true;
+
+				if (wp->shadow_extra_info_dirty)
+					return true;
+
 			}
 		}
 	}
@@ -368,7 +377,7 @@ static bool need_wb_go(struct omap_dss_writeback *wb)
 
 	wp = get_wb_priv(wb);
 
-	if (wp->shadow_info_dirty)
+	if (wp->shadow_info_dirty || wp->shadow_extra_info_dirty)
 		return true;
 
 	return false;
@@ -378,6 +387,7 @@ static bool need_wb_go(struct omap_dss_writeback *wb)
 static bool extra_info_update_ongoing(void)
 {
 	const int num_ovls = omap_dss_get_num_overlays();
+	const int num_wb = dss_feat_get_num_wb();
 	struct ovl_priv_data *op;
 	struct omap_overlay *ovl;
 	struct mgr_priv_data *mp;
@@ -402,6 +412,27 @@ static bool extra_info_update_ongoing(void)
 			return true;
 	}
 
+	for (i = 0; i < num_wb; ++i) {
+		struct omap_dss_writeback *wb;
+		struct wb_priv_data *wp;
+
+		wb = omap_dss_get_writeback(i);
+		wp = get_wb_priv(wb);
+		mp = get_mgr_priv(wb->dssdev->manager);
+
+		if (!mp->enabled)
+			continue;
+
+		if (!mp->updating)
+			continue;
+
+		if (!wp->enabled)
+			continue;
+
+		if (wp->extra_info_dirty || wp->shadow_extra_info_dirty)
+			return true;
+	}
+
 	return false;
 }
 
@@ -644,6 +675,19 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb)
 	wp->shadow_info_dirty = true;
 }
 
+static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb)
+{
+	struct wb_priv_data *wp = get_wb_priv(wb);
+
+	if (!wp->extra_info_dirty)
+		return;
+
+	/* Write extra registers here */
+
+	wp->extra_info_dirty = false;
+	wp->shadow_extra_info_dirty = true;
+}
+
 static void dss_mgr_write_regs(struct omap_overlay_manager *mgr)
 {
 	struct mgr_priv_data *mp = get_mgr_priv(mgr);
@@ -716,6 +760,7 @@ static void dss_write_regs(void)
 			continue;
 
 		dss_wb_write_regs(wb);
+		dss_wb_write_regs_extra(wb);
 	}
 }
 
@@ -867,6 +912,7 @@ static void wb_clear_shadow_dirty(struct omap_dss_writeback *wb)
 
 	wp = get_wb_priv(wb);
 	wp->shadow_info_dirty = false;
+	wp->shadow_extra_info_dirty = false;
 }
 
 static void dss_apply_irq_handler(void *data, u32 mask)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 08/29] OMAPDSS: APPLY: Modify manager unset device op
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (6 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 07/29] OMAPDSS: APPLY: Add extra_info for writeback Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 09/29] OMAPDSS: APPLY: Allow manager set/unset_device ops to set/unset writeback Archit Taneja
                   ` (20 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Modify manager's unset_device op so that it can be used to unset any one of the
devices connected to the overlay manager output.

The unset_device function now takes a pointer to omap_dss_device struct which
needs to be unset. The function ignores it for now, but since there can be two
devices connected to a manager now, it will be used later to unset either the
display or writeback device.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c   |    3 ++-
 drivers/video/omap2/dss/display.c |    2 +-
 drivers/video/omap2/dss/dss.h     |    3 ++-
 drivers/video/omap2/dss/manager.c |    7 +++++--
 drivers/video/omap2/dss/overlay.c |    9 ++++++---
 include/video/omapdss.h           |    3 ++-
 6 files changed, 18 insertions(+), 9 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index ff0baeb..4624f86 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1310,7 +1310,8 @@ err:
 	return r;
 }
 
-int dss_mgr_unset_device(struct omap_overlay_manager *mgr)
+int dss_mgr_unset_device(struct omap_overlay_manager *mgr,
+		struct omap_dss_device *dssdev)
 {
 	int r;
 	struct omap_dss_device *curr_dssdev;
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index a712bad..03d7fb0 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -432,7 +432,7 @@ void dss_uninit_device(struct platform_device *pdev,
 		device_remove_file(&dssdev->dev, attr);
 
 	if (dssdev->manager)
-		dssdev->manager->unset_device(dssdev->manager);
+		dssdev->manager->unset_device(dssdev->manager, dssdev);
 }
 
 static int dss_suspend_device(struct device *dev, void *data)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index bb25d96..b4b60fc 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -178,7 +178,8 @@ void dss_mgr_get_info(struct omap_overlay_manager *mgr,
 		struct omap_overlay_manager_info *info);
 int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 		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,
+		struct omap_dss_device *dssdev);
 
 bool dss_ovl_is_enabled(struct omap_overlay *ovl);
 int dss_ovl_enable(struct omap_overlay *ovl);
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index 4962f7b..f4fd3d8 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -55,6 +55,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 *curr_display;
 
 	int match(struct omap_dss_device *dssdev, void *data)
 	{
@@ -74,8 +75,10 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (dssdev)
 		DSSDBG("display %s found\n", dssdev->name);
 
-	if (mgr->get_display(mgr)) {
-		r = mgr->unset_device(mgr);
+	curr_display = mgr->get_display(mgr);
+
+	if (curr_display) {
+		r = mgr->unset_device(mgr, curr_display);
 		if (r) {
 			DSSERR("failed to unset display\n");
 			goto put_device;
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index c72275e..dc0cc52 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -538,7 +538,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 	if (dssdev->channel = OMAP_DSS_CHANNEL_LCD2) {
 		if (!lcd2_mgr->output->device || force) {
 			if (lcd2_mgr->output->device)
-				lcd2_mgr->unset_device(lcd2_mgr);
+				lcd2_mgr->unset_device(lcd2_mgr,
+					lcd2_mgr->output->device);
 			lcd2_mgr->set_device(lcd2_mgr, dssdev);
 			mgr = lcd2_mgr;
 		}
@@ -546,7 +547,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 			&& dssdev->type != OMAP_DISPLAY_TYPE_HDMI) {
 		if (!lcd_mgr->output->device || force) {
 			if (lcd_mgr->output->device)
-				lcd_mgr->unset_device(lcd_mgr);
+				lcd_mgr->unset_device(lcd_mgr,
+					lcd_mgr->output->device);
 			lcd_mgr->set_device(lcd_mgr, dssdev);
 			mgr = lcd_mgr;
 		}
@@ -556,7 +558,8 @@ void dss_recheck_connections(struct omap_dss_device *dssdev, bool force)
 			|| dssdev->type = OMAP_DISPLAY_TYPE_HDMI) {
 		if (!tv_mgr->output->device || force) {
 			if (tv_mgr->output->device)
-				tv_mgr->unset_device(tv_mgr);
+				tv_mgr->unset_device(tv_mgr,
+					tv_mgr->output->device);
 			tv_mgr->set_device(tv_mgr, dssdev);
 			mgr = tv_mgr;
 		}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 01092e4..d19a7d3 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -456,7 +456,8 @@ struct omap_overlay_manager {
 
 	int (*set_device)(struct omap_overlay_manager *mgr,
 		struct omap_dss_device *dssdev);
-	int (*unset_device)(struct omap_overlay_manager *mgr);
+	int (*unset_device)(struct omap_overlay_manager *mgr,
+		struct omap_dss_device *dssdev);
 
 	int (*set_manager_info)(struct omap_overlay_manager *mgr,
 			struct omap_overlay_manager_info *info);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 09/29] OMAPDSS: APPLY: Allow manager set/unset_device ops to set/unset writeback
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (7 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 08/29] OMAPDSS: APPLY: Modify manager unset device op Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 10/29] OMAPDSS: APPLY: Calculate channel_in for writeback Archit Taneja
                   ` (19 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Allow dss_mgr_set_device/unset_device to set/unset either display or writeback
based on the dssdev argument passed to the function. Check if the device is a
writeback device by seeing if the wbdev pointer is populated for it or not.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c |   15 ++++++++++++---
 1 files changed, 12 insertions(+), 3 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 4624f86..aee0420 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -1300,7 +1300,11 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 	}
 
 	dssdev->manager = mgr;
-	mgr->output->device = dssdev;
+
+	if (dssdev->wbdev)
+		mgr->output->writeback = dssdev;
+	else
+		mgr->output->device = dssdev;
 
 	mutex_unlock(&apply_lock);
 
@@ -1318,7 +1322,8 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr,
 
 	mutex_lock(&apply_lock);
 
-	curr_dssdev = mgr->output->device;
+	curr_dssdev = dssdev->wbdev ? mgr->get_writeback(mgr) :
+			mgr->get_display(mgr);
 
 	if (!curr_dssdev) {
 		DSSERR("failed to unset device, device not set.\n");
@@ -1336,7 +1341,11 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr,
 	}
 
 	curr_dssdev->manager = NULL;
-	mgr->output->device = NULL;
+
+	if (dssdev->wbdev)
+		mgr->output->writeback = NULL;
+	else
+		mgr->output->device = NULL;
 
 	mutex_unlock(&apply_lock);
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 10/29] OMAPDSS: APPLY: Calculate channel_in for writeback
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (8 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 09/29] OMAPDSS: APPLY: Allow manager set/unset_device ops to set/unset writeback Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 11/29] OMAPDSS: DISPC: Add writeback as a new plane Archit Taneja
                   ` (18 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add channel_in as a parameter in writeback's private data. This sets the
extra_info_dirty flag as this parameter is configured when we set/unset the
dummy writeback panel's manager unlike the other parameter which are
configured through set/unset_wb_info ops by the DSS2 user.

Add a helper function dss_mgr_set_writeback() which is called by the manager
set/unset_device ops to configure the channel_in parameter and set the
extra_info_dirty flags. It returns an error if we try to unset writeback when
it is enabled.

Add a dummy dispc_wb_set_channel_in() function. This will be filled up later.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c     |   59 +++++++++++++++++++++++++++++-----
 drivers/video/omap2/dss/dispc.c     |    5 +++
 drivers/video/omap2/dss/dss.h       |   12 +++++++
 drivers/video/omap2/dss/writeback.c |   15 +++++++++
 4 files changed, 82 insertions(+), 9 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index aee0420..9f3c174 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -114,6 +114,8 @@ struct wb_priv_data {
 	bool extra_info_dirty;
 	bool shadow_extra_info_dirty;
 
+	enum dss_writeback_channel_in channel_in;
+
 	/* If true, GO bit is up and shadow registers cannot be written.
 	 * Never true for writeback in memory to memory mode */
 	bool busy;
@@ -137,6 +139,8 @@ static DEFINE_MUTEX(apply_lock);
 static DECLARE_COMPLETION(extra_updated_completion);
 
 static void dss_register_vsync_isr(void);
+static int dss_mgr_set_writeback(struct omap_overlay_manager *mgr,
+		struct omap_dss_writeback *wb, bool set);
 
 static struct ovl_priv_data *get_ovl_priv(struct omap_overlay *ovl)
 {
@@ -682,7 +686,7 @@ static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb)
 	if (!wp->extra_info_dirty)
 		return;
 
-	/* Write extra registers here */
+	dispc_wb_set_channel_in(wb->id, wp->channel_in);
 
 	wp->extra_info_dirty = false;
 	wp->shadow_extra_info_dirty = true;
@@ -1282,6 +1286,7 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 		struct omap_dss_device *dssdev)
 {
 	int r;
+	struct omap_dss_writeback *wb = dssdev->wbdev;
 
 	mutex_lock(&apply_lock);
 
@@ -1301,10 +1306,13 @@ int dss_mgr_set_device(struct omap_overlay_manager *mgr,
 
 	dssdev->manager = mgr;
 
-	if (dssdev->wbdev)
-		mgr->output->writeback = dssdev;
-	else
+	if (wb) {
+		r = dss_mgr_set_writeback(mgr, wb, true);
+		if (r)
+			goto err;
+	} else {
 		mgr->output->device = dssdev;
+	}
 
 	mutex_unlock(&apply_lock);
 
@@ -1319,11 +1327,11 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr,
 {
 	int r;
 	struct omap_dss_device *curr_dssdev;
+	struct omap_dss_writeback *wb = dssdev->wbdev;
 
 	mutex_lock(&apply_lock);
 
-	curr_dssdev = dssdev->wbdev ? mgr->get_writeback(mgr) :
-			mgr->get_display(mgr);
+	curr_dssdev = wb ? mgr->get_writeback(mgr) : mgr->get_display(mgr);
 
 	if (!curr_dssdev) {
 		DSSERR("failed to unset device, device not set.\n");
@@ -1342,10 +1350,13 @@ int dss_mgr_unset_device(struct omap_overlay_manager *mgr,
 
 	curr_dssdev->manager = NULL;
 
-	if (dssdev->wbdev)
-		mgr->output->writeback = NULL;
-	else
+	if (wb) {
+		r = dss_mgr_set_writeback(mgr, wb, false);
+		if (r)
+			goto err;
+	} else {
 		mgr->output->device = NULL;
+	}
 
 	mutex_unlock(&apply_lock);
 
@@ -1593,6 +1604,36 @@ err:
 	return r;
 }
 
+static int dss_mgr_set_writeback(struct omap_overlay_manager *mgr,
+		struct omap_dss_writeback *wb, bool set)
+{
+	struct wb_priv_data *wp = get_wb_priv(wb);
+	unsigned long flags;
+
+	spin_lock_irqsave(&data_lock, flags);
+
+	if (set) {
+		wp->channel_in = dss_wb_calc_channel_in(wb);
+		wp->extra_info_dirty = true;
+		mgr->output->writeback = wb->dssdev;
+
+	} else {
+		if (wp->enabled) {
+			DSSERR("Failed to unset writeback%d from manager%d\n",
+				wb->id, mgr->id);
+			spin_unlock_irqrestore(&data_lock, flags);
+			return -EINVAL;
+		}
+
+		wp->channel_in = -1;
+		mgr->output->writeback = NULL;
+	}
+
+	spin_unlock_irqrestore(&data_lock, flags);
+
+	return 0;
+}
+
 int dss_wb_set_info(struct omap_dss_writeback *wb,
 		struct omap_dss_writeback_info *info)
 {
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 35ed6ca..a4d5504 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -899,6 +899,11 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
 	return channel;
 }
 
+void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in)
+{
+	return;
+}
+
 static void dispc_ovl_set_burst_size(enum omap_plane plane,
 		enum omap_burst_size burst_size)
 {
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index b4b60fc..1b128f1 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -113,6 +113,16 @@ enum dss_dsi_content_type {
 	DSS_DSI_CONTENT_GENERIC,
 };
 
+enum dss_writeback_channel_in {
+	OMAP_DSS_WB_LCD1_MGR	= 0,
+	OMAP_DSS_WB_LCD2_MGR	= 1,
+	OMAP_DSS_WB_TV_MGR	= 2,
+	OMAP_DSS_WB_OVL0	= 3,
+	OMAP_DSS_WB_OVL1	= 4,
+	OMAP_DSS_WB_OVL2	= 5,
+	OMAP_DSS_WB_OVL3	= 6,
+};
+
 struct dss_clock_info {
 	/* rates that we get with dividers below */
 	unsigned long fck;
@@ -238,6 +248,7 @@ int dss_ovl_check(struct omap_overlay *ovl,
 void dss_init_writeback(void);
 void dss_uninit_writeback(void);
 int writeback_init_display(struct omap_dss_device *dssdev);
+enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *wb);
 int dss_wb_simple_check(struct omap_dss_writeback *wb,
 		const struct omap_dss_writeback_info *info);
 
@@ -483,6 +494,7 @@ bool dispc_wb_go_busy(int id);
 void dispc_wb_go(int id);
 int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi);
 void dispc_wb_enable(int id, bool enable);
+void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in);
 
 /* VENC */
 #ifdef CONFIG_OMAP2_DSS_VENC
diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index eefab4e..89738a4 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -122,6 +122,21 @@ int writeback_init_display(struct omap_dss_device *dssdev)
 	return 0;
 }
 
+enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *wb)
+{
+	struct omap_overlay_manager *mgr = wb->dssdev->manager;
+
+	switch (mgr->id) {
+	case OMAP_DSS_CHANNEL_LCD2:
+		return OMAP_DSS_WB_LCD2_MGR;
+	case OMAP_DSS_CHANNEL_DIGIT:
+		return OMAP_DSS_WB_TV_MGR;
+	case OMAP_DSS_CHANNEL_LCD:
+	default:
+		return OMAP_DSS_WB_LCD1_MGR;
+	}
+}
+
 int dss_wb_simple_check(struct omap_dss_writeback *wb,
 		const struct omap_dss_writeback_info *info)
 {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 11/29] OMAPDSS: DISPC: Add writeback as a new plane
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (9 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 10/29] OMAPDSS: APPLY: Calculate channel_in for writeback Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 12/29] OMAPDSS: Writeback: Add check for color_mode in dss_wb_simple_check() Archit Taneja
                   ` (17 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Since writeback has many overlay like properties, and most of it's registers are
similar to that of overlays, it's possible to reuse most of the overlay related
DISPC code for writeback if it is added as a plane.

Add OMAP_DSS_WB as new plane in the omap_plane struct. Add the writeback
register offsets in dispc.h, add minimal WB plane related info needed in
dss_features.

Add a new omap_dss_writeback parameter called plane_id, this represents the
plane or pipeline number out of all the pipelines.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dispc.h        |   36 ++++++++++++++++++++++++++++++++
 drivers/video/omap2/dss/dss_features.c |   10 ++++++++
 drivers/video/omap2/dss/writeback.c    |    1 +
 include/video/omapdss.h                |    2 +
 4 files changed, 49 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/omap2/dss/dispc.h
index 5836bd1..7f69a51 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/omap2/dss/dispc.h
@@ -304,6 +304,8 @@ static inline u16 DISPC_OVL_BASE(enum omap_plane plane)
 		return 0x014C;
 	case OMAP_DSS_VIDEO3:
 		return 0x0300;
+	case OMAP_DSS_WB:
+		return 0x0500;
 	default:
 		BUG();
 	}
@@ -318,6 +320,7 @@ static inline u16 DISPC_BA0_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0000;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0008;
 	default:
 		BUG();
@@ -332,6 +335,7 @@ static inline u16 DISPC_BA1_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0004;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x000C;
 	default:
 		BUG();
@@ -349,6 +353,8 @@ static inline u16 DISPC_BA0_UV_OFFSET(enum omap_plane plane)
 		return 0x04BC;
 	case OMAP_DSS_VIDEO3:
 		return 0x0310;
+	case OMAP_DSS_WB:
+		return 0x0118;
 	default:
 		BUG();
 	}
@@ -365,6 +371,8 @@ static inline u16 DISPC_BA1_UV_OFFSET(enum omap_plane plane)
 		return 0x04C0;
 	case OMAP_DSS_VIDEO3:
 		return 0x0314;
+	case OMAP_DSS_WB:
+		return 0x011C;
 	default:
 		BUG();
 	}
@@ -392,6 +400,7 @@ static inline u16 DISPC_SIZE_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x000C;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x00A8;
 	default:
 		BUG();
@@ -407,6 +416,7 @@ static inline u16 DISPC_ATTR_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0010;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0070;
 	default:
 		BUG();
@@ -424,6 +434,8 @@ static inline u16 DISPC_ATTR2_OFFSET(enum omap_plane plane)
 		return 0x04DC;
 	case OMAP_DSS_VIDEO3:
 		return 0x032C;
+	case OMAP_DSS_WB:
+		return 0x0310;
 	default:
 		BUG();
 	}
@@ -438,6 +450,7 @@ static inline u16 DISPC_FIFO_THRESH_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0014;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x008C;
 	default:
 		BUG();
@@ -453,6 +466,7 @@ static inline u16 DISPC_FIFO_SIZE_STATUS_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0018;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0088;
 	default:
 		BUG();
@@ -468,6 +482,7 @@ static inline u16 DISPC_ROW_INC_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x001C;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x00A4;
 	default:
 		BUG();
@@ -483,6 +498,7 @@ static inline u16 DISPC_PIX_INC_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0020;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0098;
 	default:
 		BUG();
@@ -526,6 +542,7 @@ static inline u16 DISPC_FIR_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0024;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0090;
 	default:
 		BUG();
@@ -543,6 +560,8 @@ static inline u16 DISPC_FIR2_OFFSET(enum omap_plane plane)
 		return 0x055C;
 	case OMAP_DSS_VIDEO3:
 		return 0x0424;
+	case OMAP_DSS_WB:
+		return 0x290;
 	default:
 		BUG();
 	}
@@ -557,6 +576,7 @@ static inline u16 DISPC_PIC_SIZE_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0028;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0094;
 	default:
 		BUG();
@@ -573,6 +593,7 @@ static inline u16 DISPC_ACCU0_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x002C;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0000;
 	default:
 		BUG();
@@ -590,6 +611,8 @@ static inline u16 DISPC_ACCU2_0_OFFSET(enum omap_plane plane)
 		return 0x0560;
 	case OMAP_DSS_VIDEO3:
 		return 0x0428;
+	case OMAP_DSS_WB:
+		return 0x0294;
 	default:
 		BUG();
 	}
@@ -604,6 +627,7 @@ static inline u16 DISPC_ACCU1_OFFSET(enum omap_plane plane)
 	case OMAP_DSS_VIDEO2:
 		return 0x0030;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0004;
 	default:
 		BUG();
@@ -621,6 +645,8 @@ static inline u16 DISPC_ACCU2_1_OFFSET(enum omap_plane plane)
 		return 0x0564;
 	case OMAP_DSS_VIDEO3:
 		return 0x042C;
+	case OMAP_DSS_WB:
+		return 0x0298;
 	default:
 		BUG();
 	}
@@ -636,6 +662,7 @@ static inline u16 DISPC_FIR_COEF_H_OFFSET(enum omap_plane plane, u16 i)
 	case OMAP_DSS_VIDEO2:
 		return 0x0034 + i * 0x8;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0010 + i * 0x8;
 	default:
 		BUG();
@@ -654,6 +681,8 @@ static inline u16 DISPC_FIR_COEF_H2_OFFSET(enum omap_plane plane, u16 i)
 		return 0x0568 + i * 0x8;
 	case OMAP_DSS_VIDEO3:
 		return 0x0430 + i * 0x8;
+	case OMAP_DSS_WB:
+		return 0x02A0 + i * 0x8;
 	default:
 		BUG();
 	}
@@ -669,6 +698,7 @@ static inline u16 DISPC_FIR_COEF_HV_OFFSET(enum omap_plane plane, u16 i)
 	case OMAP_DSS_VIDEO2:
 		return 0x0038 + i * 0x8;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0014 + i * 0x8;
 	default:
 		BUG();
@@ -687,6 +717,8 @@ static inline u16 DISPC_FIR_COEF_HV2_OFFSET(enum omap_plane plane, u16 i)
 		return 0x056C + i * 0x8;
 	case OMAP_DSS_VIDEO3:
 		return 0x0434 + i * 0x8;
+	case OMAP_DSS_WB:
+		return 0x02A4 + i * 0x8;
 	default:
 		BUG();
 	}
@@ -701,6 +733,7 @@ static inline u16 DISPC_CONV_COEF_OFFSET(enum omap_plane plane, u16 i)
 	case OMAP_DSS_VIDEO1:
 	case OMAP_DSS_VIDEO2:
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0074 + i * 0x4;
 	default:
 		BUG();
@@ -718,6 +751,7 @@ static inline u16 DISPC_FIR_COEF_V_OFFSET(enum omap_plane plane, u16 i)
 	case OMAP_DSS_VIDEO2:
 		return 0x00B4 + i * 0x4;
 	case OMAP_DSS_VIDEO3:
+	case OMAP_DSS_WB:
 		return 0x0050 + i * 0x4;
 	default:
 		BUG();
@@ -736,6 +770,8 @@ static inline u16 DISPC_FIR_COEF_V2_OFFSET(enum omap_plane plane, u16 i)
 		return 0x05A8 + i * 0x4;
 	case OMAP_DSS_VIDEO3:
 		return 0x0470 + i * 0x4;
+	case OMAP_DSS_WB:
+		return 0x02E0 + i * 0x4;
 	default:
 		BUG();
 	}
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index ca41620..9478ed8 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -221,6 +221,16 @@ static const enum omap_color_mode omap4_dss_supported_color_modes[] = {
 	OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
 	OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
 	OMAP_DSS_COLOR_RGBX32,
+
+	/* OMAP_DSS_WB */
+	OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB12U |
+	OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_ARGB16_1555 |
+	OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_NV12 |
+	OMAP_DSS_COLOR_RGBA16 | OMAP_DSS_COLOR_RGB24U |
+	OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_UYVY |
+	OMAP_DSS_COLOR_ARGB16 | OMAP_DSS_COLOR_XRGB16_1555 |
+	OMAP_DSS_COLOR_ARGB32 | OMAP_DSS_COLOR_RGBX16 |
+	OMAP_DSS_COLOR_RGBX32,
 };
 
 static const enum omap_overlay_caps omap2_dss_overlay_caps[] = {
diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index 89738a4..8b2c9b8 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -88,6 +88,7 @@ void dss_init_writeback(void)
 		struct omap_dss_writeback *wb = &writeback[i];
 
 		wb->id = i;
+		wb->plane_id = OMAP_DSS_WB + i;
 
 		wb->set_wb_info = &dss_wb_set_info;
 		wb->get_wb_info = &dss_wb_get_info;
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index d19a7d3..6bf84b2 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -68,6 +68,7 @@ enum omap_plane {
 	OMAP_DSS_VIDEO1	= 1,
 	OMAP_DSS_VIDEO2	= 2,
 	OMAP_DSS_VIDEO3	= 3,
+	OMAP_DSS_WB	= 4,
 };
 
 enum omap_channel {
@@ -488,6 +489,7 @@ struct omap_dss_writeback_info {
 
 struct omap_dss_writeback {
 	int id;
+	int plane_id;
 
 	/* dummy panel we are connected to */
 	struct omap_dss_device *dssdev;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 12/29] OMAPDSS: Writeback: Add check for color_mode in dss_wb_simple_check()
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (10 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 11/29] OMAPDSS: DISPC: Add writeback as a new plane Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 13/29] OMAPDSS: APPLY: Configure writeback FIFOs Archit Taneja
                   ` (16 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add a check for the color_mode parameter provided by the user in
dss_wb_simple_check().

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/writeback.c |    7 +++++++
 1 files changed, 7 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index 8b2c9b8..540e61d 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -153,6 +153,13 @@ int dss_wb_simple_check(struct omap_dss_writeback *wb,
 		return -EINVAL;
 	}
 
+	if ((dss_feat_get_supported_color_modes(wb->plane_id) &
+			info->color_mode) = 0) {
+		DSSERR("wb_simple_check: wb%d doesn't support mode %d\n",
+			wb->id, info->color_mode);
+		return -EINVAL;
+	}
+
 	if (info->capture_rate < 0 || info->capture_rate > 7) {
 		DSSERR("wb_simple_check: capture rate cannot be %d\n",
 			info->capture_rate);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 13/29] OMAPDSS: APPLY: Configure writeback FIFOs
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (11 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 12/29] OMAPDSS: Writeback: Add check for color_mode in dss_wb_simple_check() Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 14/29] OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma Archit Taneja
                   ` (15 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add writeback FIFO thresholds as extra_info parameters. Modify function
dss_ovl_fifo_setup() so that it can also also configure writeback pipeline
FIFOs. Extend the DISPC fifo functions to also configure the writeback
registers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c |   70 +++++++++++++++++++++++++++++++++-----
 drivers/video/omap2/dss/dispc.c |    8 +++--
 2 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 9f3c174..a17cc47 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -115,6 +115,7 @@ struct wb_priv_data {
 	bool shadow_extra_info_dirty;
 
 	enum dss_writeback_channel_in channel_in;
+	u32 fifo_low, fifo_high;
 
 	/* If true, GO bit is up and shadow registers cannot be written.
 	 * Never true for writeback in memory to memory mode */
@@ -687,6 +688,7 @@ static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb)
 		return;
 
 	dispc_wb_set_channel_in(wb->id, wp->channel_in);
+	dispc_ovl_set_fifo_threshold(wb->plane_id, wp->fifo_low, wp->fifo_high);
 
 	wp->extra_info_dirty = false;
 	wp->shadow_extra_info_dirty = true;
@@ -1102,21 +1104,59 @@ static void dss_apply_ovl_fifo_thresholds(struct omap_overlay *ovl,
 	op->extra_info_dirty = true;
 }
 
-static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
+static void dss_apply_wb_fifo_thresholds(struct omap_dss_writeback *wb,
+		u32 fifo_low, u32 fifo_high)
 {
-	struct ovl_priv_data *op = get_ovl_priv(ovl);
+	struct wb_priv_data *wp = get_wb_priv(wb);
+
+	if (wp->fifo_low = fifo_low && wp->fifo_high = fifo_high)
+		return;
+
+	wp->fifo_low = fifo_low;
+	wp->fifo_high = fifo_high;
+	wp->extra_info_dirty = true;
+}
+
+static void dss_plane_setup_fifo(struct omap_overlay *ovl,
+		struct omap_dss_writeback *wb)
+{
+	enum omap_plane plane;
+	struct omap_overlay_manager *mgr;
 	struct omap_dss_device *dssdev;
+	bool enabled, enabling;
 	u32 size, burst_size;
 	u32 fifo_low, fifo_high;
 
-	if (!op->enabled && !op->enabling)
+	if (ovl) {
+		struct ovl_priv_data *op;
+
+		mgr = ovl->manager;
+		op = get_ovl_priv(ovl);
+
+		enabled = op->enabled;
+		enabling = op->enabling;
+
+		plane = ovl->id;
+	} else {
+		struct wb_priv_data *wp;
+
+		mgr = wb->dssdev->manager;
+		wp = get_wb_priv(wb);
+
+		enabled = wp->enabled;
+		enabling = false;
+
+		plane = wb->plane_id;
+	}
+
+	if (!enabled && !enabling)
 		return;
 
-	dssdev = ovl->manager->get_output(ovl->manager);
+	dssdev = mgr->get_output(mgr);
 
-	size = dispc_ovl_get_fifo_size(ovl->id);
+	size = dispc_ovl_get_fifo_size(plane);
 
-	burst_size = dispc_ovl_get_burst_size(ovl->id);
+	burst_size = dispc_ovl_get_burst_size(plane);
 
 	switch (dssdev->type) {
 	case OMAP_DISPLAY_TYPE_DPI:
@@ -1124,12 +1164,12 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
 	case OMAP_DISPLAY_TYPE_SDI:
 	case OMAP_DISPLAY_TYPE_VENC:
 	case OMAP_DISPLAY_TYPE_HDMI:
-		default_get_overlay_fifo_thresholds(ovl->id, size,
+		default_get_overlay_fifo_thresholds(plane, size,
 				burst_size, &fifo_low, &fifo_high);
 		break;
 #ifdef CONFIG_OMAP2_DSS_DSI
 	case OMAP_DISPLAY_TYPE_DSI:
-		dsi_get_overlay_fifo_thresholds(ovl->id, size,
+		dsi_get_overlay_fifo_thresholds(plane, size,
 				burst_size, &fifo_low, &fifo_high);
 		break;
 #endif
@@ -1137,13 +1177,17 @@ static void dss_ovl_setup_fifo(struct omap_overlay *ovl)
 		BUG();
 	}
 
-	dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
+	if (ovl)
+		dss_apply_ovl_fifo_thresholds(ovl, fifo_low, fifo_high);
+	else
+		dss_apply_wb_fifo_thresholds(wb, fifo_low, fifo_high);
 }
 
 static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
 {
 	struct omap_overlay *ovl;
 	struct mgr_priv_data *mp;
+	struct omap_dss_device *dssdev;
 
 	mp = get_mgr_priv(mgr);
 
@@ -1151,7 +1195,13 @@ static void dss_mgr_setup_fifos(struct omap_overlay_manager *mgr)
 		return;
 
 	list_for_each_entry(ovl, &mgr->overlays, list)
-		dss_ovl_setup_fifo(ovl);
+		dss_plane_setup_fifo(ovl, NULL);
+
+	dssdev = mgr->get_writeback(mgr);
+	if (dssdev) {
+		struct omap_dss_writeback *wb = dssdev->wbdev;
+		dss_plane_setup_fifo(NULL, wb);
+	}
 }
 
 static void dss_setup_fifos(void)
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index a4d5504..231369a 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -91,7 +91,7 @@ static struct {
 	int irq;
 	struct clk *dss_clk;
 
-	u32	fifo_size[MAX_DSS_OVERLAYS];
+	u32	fifo_size[MAX_DSS_OVERLAYS + MAX_DSS_WB];
 
 	spinlock_t irq_lock;
 	u32 irq_error_mask;
@@ -907,7 +907,7 @@ void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in)
 static void dispc_ovl_set_burst_size(enum omap_plane plane,
 		enum omap_burst_size burst_size)
 {
-	static const unsigned shifts[] = { 6, 14, 14, 14, };
+	static const unsigned shifts[] = { 6, 14, 14, 14, 14, };
 	int shift;
 
 	shift = shifts[plane];
@@ -1021,12 +1021,14 @@ static void dispc_read_plane_fifo_sizes(void)
 	int plane;
 	u8 start, end;
 	u32 unit;
+	int num_ovl = dss_feat_get_num_ovls();
+	int num_wb = dss_feat_get_num_wb();
 
 	unit = dss_feat_get_buffer_size_unit();
 
 	dss_feat_get_reg_field(FEAT_REG_FIFOSIZE, &start, &end);
 
-	for (plane = 0; plane < dss_feat_get_num_ovls(); ++plane) {
+	for (plane = 0; plane < num_ovl + num_wb; ++plane) {
 		size = REG_GET(DISPC_OVL_FIFO_SIZE_STATUS(plane), start, end);
 		size *= unit;
 		dispc.fifo_size[plane] = size;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 14/29] OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (12 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 13/29] OMAPDSS: APPLY: Configure writeback FIFOs Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 15/29] OMAPDSS: DISPC: Pass overlay caps as a parameter to DISPC overlay related function Archit Taneja
                   ` (14 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Make the function dispc_ovl_set_scaling_uv() take a boolean argument which tells
if we want to upscale or downscale the chroma plane.

Downscaling of chroma is required by writeback pipeline for converting the input
YUV444 color format to YUV422 or NV12.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dispc.c |   17 ++++++++++-------
 1 files changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 231369a..dfbb39b 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1219,7 +1219,7 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
 		u16 out_width, u16 out_height,
 		bool ilace, bool five_taps,
 		bool fieldmode, enum omap_color_mode color_mode,
-		u8 rotation)
+		u8 rotation, bool chroma_upscale)
 {
 	int scale_x = out_width != orig_width;
 	int scale_y = out_height != orig_height;
@@ -1236,9 +1236,11 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
 	switch (color_mode) {
 	case OMAP_DSS_COLOR_NV12:
 		/* UV is subsampled by 2 vertically*/
-		orig_height >>= 1;
+		orig_height = chroma_upscale ?
+			orig_height >> 1 : orig_height << 1;
 		/* UV is subsampled by 2 horz.*/
-		orig_width >>= 1;
+		orig_width = chroma_upscale ?
+			orig_width >> 1 : orig_width << 1;
 		break;
 	case OMAP_DSS_COLOR_YUV2:
 	case OMAP_DSS_COLOR_UYVY:
@@ -1248,7 +1250,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
 		if (rotation = OMAP_DSS_ROT_0 ||
 			rotation = OMAP_DSS_ROT_180)
 			/* UV is subsampled by 2 hrz*/
-			orig_width >>= 1;
+			orig_width = chroma_upscale ?
+				orig_width >> 1 : orig_width << 1;
 		/* must use FIR for YUV422 if rotated */
 		if (rotation != OMAP_DSS_ROT_0)
 			scale_x = scale_y = true;
@@ -1282,7 +1285,7 @@ static void dispc_ovl_set_scaling(enum omap_plane plane,
 		u16 out_width, u16 out_height,
 		bool ilace, bool five_taps,
 		bool fieldmode, enum omap_color_mode color_mode,
-		u8 rotation)
+		u8 rotation, bool chroma_upscale)
 {
 	BUG_ON(plane = OMAP_DSS_GFX);
 
@@ -1298,7 +1301,7 @@ static void dispc_ovl_set_scaling(enum omap_plane plane,
 		out_width, out_height,
 		ilace, five_taps,
 		fieldmode, color_mode,
-		rotation);
+		rotation, chroma_upscale);
 }
 
 static void dispc_ovl_set_rotation_attrs(enum omap_plane plane, u8 rotation,
@@ -1888,7 +1891,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 		dispc_ovl_set_scaling(plane, oi->width, oi->height,
 				   outw, outh,
 				   ilace, five_taps, fieldmode,
-				   oi->color_mode, oi->rotation);
+				   oi->color_mode, oi->rotation, true);
 		dispc_ovl_set_vid_size(plane, outw, outh);
 		dispc_ovl_set_vid_color_conv(plane, cconv);
 	}
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 15/29] OMAPDSS: DISPC: Pass overlay caps as a parameter to DISPC overlay related function
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (13 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 14/29] OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:48 ` [RFC PATCH 16/29] OMAPDSS: OVERLAY: Add position and replication as overlay caps Archit Taneja
                   ` (13 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Currently, the functions below take the omap_plane parameter and derive the
overlay caps within them. Pass the overlay caps as a parameter to the function
to allow writeback functions to use them too.

- dispc_ovl_set_zorder()
- dispc_ovl_set_pre_mult_alpha()
- dispc_ovl_setup_global_alpha()
- dispc_ovl_calc_scaling()
- dispc_ovl_setup()

These functions will be used for writeback later, and the caps will help in
deciding if they are to be used for writeback or not. This allows reuse of
overlay caps for writeback.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dispc.c |   38 ++++++++++++++++++--------------------
 1 files changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index dfbb39b..d9e04f0 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -684,11 +684,10 @@ static void dispc_ovl_set_vid_size(enum omap_plane plane, int width, int height)
 	dispc_write_reg(DISPC_OVL_SIZE(plane), val);
 }
 
-static void dispc_ovl_set_zorder(enum omap_plane plane, u8 zorder)
+static void dispc_ovl_set_zorder(enum omap_plane plane,
+		enum omap_overlay_caps caps, u8 zorder)
 {
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_ZORDER) = 0)
+	if ((caps & OMAP_DSS_OVL_CAP_ZORDER) = 0)
 		return;
 
 	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), zorder, 27, 26);
@@ -705,23 +704,22 @@ static void dispc_ovl_enable_zorder_planes(void)
 		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(i), 1, 25, 25);
 }
 
-static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane, bool enable)
+static void dispc_ovl_set_pre_mult_alpha(enum omap_plane plane,
+		enum omap_overlay_caps caps, bool enable)
 {
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) = 0)
+	if ((caps & OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA) = 0)
 		return;
 
 	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 28, 28);
 }
 
-static void dispc_ovl_setup_global_alpha(enum omap_plane plane, u8 global_alpha)
+static void dispc_ovl_setup_global_alpha(enum omap_plane plane,
+		enum omap_overlay_caps caps, u8 global_alpha)
 {
 	static const unsigned shifts[] = { 0, 8, 16, 24, };
 	int shift;
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) = 0)
+	if ((caps & OMAP_DSS_OVL_CAP_GLOBAL_ALPHA) = 0)
 		return;
 
 	shift = shifts[plane];
@@ -1704,11 +1702,10 @@ static unsigned long calc_fclk(enum omap_channel channel, u16 width,
 }
 
 static int dispc_ovl_calc_scaling(enum omap_plane plane,
-		enum omap_channel channel, u16 width, u16 height,
-		u16 out_width, u16 out_height,
+		enum omap_channel channel, enum omap_overlay_caps caps,
+		u16 width, u16 height, u16 out_width, u16 out_height,
 		enum omap_color_mode color_mode, bool *five_taps)
 {
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
 	const int maxdownscale = dss_feat_get_param_max(FEAT_PARAM_DOWNSCALE);
 	const int maxsinglelinewidth  				dss_feat_get_param_max(FEAT_PARAM_LINEWIDTH);
@@ -1717,7 +1714,7 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	if (width = out_width && height = out_height)
 		return 0;
 
-	if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) = 0)
+	if ((caps & OMAP_DSS_OVL_CAP_SCALE) = 0)
 		return -EINVAL;
 
 	if (out_width < width / maxdownscale ||
@@ -1780,6 +1777,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 		bool ilace, bool replication)
 {
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+	enum omap_overlay_caps caps = ovl->caps;
 	bool five_taps = true;
 	bool fieldmode = 0;
 	int r, cconv = 0;
@@ -1823,7 +1821,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 	if (!dss_feat_color_mode_supported(plane, oi->color_mode))
 		return -EINVAL;
 
-	r = dispc_ovl_calc_scaling(plane, channel, oi->width, oi->height,
+	r = dispc_ovl_calc_scaling(plane, channel, caps, oi->width, oi->height,
 			outw, outh, oi->color_mode,
 			&five_taps);
 	if (r)
@@ -1887,7 +1885,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 
 	dispc_ovl_set_pic_size(plane, oi->width, oi->height);
 
-	if (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) {
+	if (caps & OMAP_DSS_OVL_CAP_SCALE) {
 		dispc_ovl_set_scaling(plane, oi->width, oi->height,
 				   outw, outh,
 				   ilace, five_taps, fieldmode,
@@ -1899,9 +1897,9 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 	dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
 			oi->color_mode);
 
-	dispc_ovl_set_zorder(plane, oi->zorder);
-	dispc_ovl_set_pre_mult_alpha(plane, oi->pre_mult_alpha);
-	dispc_ovl_setup_global_alpha(plane, oi->global_alpha);
+	dispc_ovl_set_zorder(plane, caps, oi->zorder);
+	dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
+	dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha);
 
 	dispc_ovl_enable_replication(plane, replication);
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 16/29] OMAPDSS: OVERLAY: Add position and replication as overlay caps
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (14 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 15/29] OMAPDSS: DISPC: Pass overlay caps as a parameter to DISPC overlay related function Archit Taneja
@ 2011-12-27 12:48 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 17/29] OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_plane_setup Archit Taneja
                   ` (12 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:48 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add position and replication as overlay caps. Pass overlay caps as an argument
to the corresponding functions.

These caps will be set for all overlays, but not for writeback. This is done
so writeback can reuse dispc_ovl_setup() to the maximum.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dispc.c   |   20 +++++++++++++++-----
 drivers/video/omap2/dss/overlay.c |    6 ++++++
 include/video/omapdss.h           |    2 ++
 3 files changed, 23 insertions(+), 5 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index d9e04f0..58de7d7 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -656,9 +656,15 @@ static void dispc_ovl_set_ba1_uv(enum omap_plane plane, u32 paddr)
 	dispc_write_reg(DISPC_OVL_BA1_UV(plane), paddr);
 }
 
-static void dispc_ovl_set_pos(enum omap_plane plane, int x, int y)
+static void dispc_ovl_set_pos(enum omap_plane plane,
+		enum omap_overlay_caps caps, int x, int y)
 {
-	u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
+	u32 val;
+
+	if ((caps & OMAP_DSS_OVL_CAP_POS) = 0)
+		return;
+
+	val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
 
 	dispc_write_reg(DISPC_OVL_POSITION(plane), val);
 }
@@ -988,11 +994,15 @@ static void dispc_ovl_set_vid_color_conv(enum omap_plane plane, bool enable)
 	dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), val);
 }
 
-static void dispc_ovl_enable_replication(enum omap_plane plane, bool enable)
+static void dispc_ovl_enable_replication(enum omap_plane plane,
+		enum omap_overlay_caps caps, bool enable)
 {
 	static const unsigned shifts[] = { 5, 10, 10, 10 };
 	int shift;
 
+	if ((caps & OMAP_DSS_OVL_CAP_REPLICATION) = 0)
+		return;
+
 	shift = shifts[plane];
 	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable, shift, shift);
 }
@@ -1881,7 +1891,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 	DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width,
 			oi->height, outw, outh);
 
-	dispc_ovl_set_pos(plane, oi->pos_x, oi->pos_y);
+	dispc_ovl_set_pos(plane, caps, oi->pos_x, oi->pos_y);
 
 	dispc_ovl_set_pic_size(plane, oi->width, oi->height);
 
@@ -1901,7 +1911,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 	dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
 	dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha);
 
-	dispc_ovl_enable_replication(plane, replication);
+	dispc_ovl_enable_replication(plane, caps, replication);
 
 	return 0;
 }
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
index dc0cc52..cb548c0 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/omap2/dss/overlay.c
@@ -509,6 +509,12 @@ void dss_init_overlays(struct platform_device *pdev)
 		ovl->wait_for_go = &dss_mgr_wait_for_go_ovl;
 
 		ovl->caps = dss_feat_get_overlay_caps(ovl->id);
+
+		/* these caps are common to all ovelays across all OMAPs, they
+		 * are used to differentiate between an overlay and writeback */
+		ovl->caps |= OMAP_DSS_OVL_CAP_POS |
+				OMAP_DSS_OVL_CAP_REPLICATION;
+
 		ovl->supported_modes  			dss_feat_get_supported_color_modes(ovl->id);
 
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 6bf84b2..49e3ccb 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -185,6 +185,8 @@ enum omap_overlay_caps {
 	OMAP_DSS_OVL_CAP_GLOBAL_ALPHA = 1 << 1,
 	OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA = 1 << 2,
 	OMAP_DSS_OVL_CAP_ZORDER = 1 << 3,
+	OMAP_DSS_OVL_CAP_POS = 1 << 4,
+	OMAP_DSS_OVL_CAP_REPLICATION = 1 << 5,
 };
 
 enum omap_overlay_manager_caps {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 17/29] OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_plane_setup
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (15 preceding siblings ...)
  2011-12-27 12:48 ` [RFC PATCH 16/29] OMAPDSS: OVERLAY: Add position and replication as overlay caps Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 18/29] OMAPDSS: DISPC: Make chroma_upscale an argument to dispc_plane_setup Archit Taneja
                   ` (11 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add a new static function called dispc_plane_setup(). This function is used by
dispc_ovl_setup() to configure the overlay registers.

This split is done so that dispc_wb_setup() can reuse the common overlay related
registers configured in dispc_plane_setup().

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dispc.c |  126 ++++++++++++++++++++++-----------------
 1 files changed, 71 insertions(+), 55 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 58de7d7..eca6157 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1783,63 +1783,54 @@ static int dispc_ovl_calc_scaling(enum omap_plane plane,
 	return 0;
 }
 
-int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
+static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel,
+		enum omap_overlay_caps caps, u32 paddr, u32 p_uv_addr,
+		u16 screen_width, int pos_x, int pos_y, u16 width, u16 height,
+		u16 out_width, u16 out_height, enum omap_color_mode color_mode,
+		u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
+		u8 global_alpha, enum omap_dss_rotation_type rotation_type,
 		bool ilace, bool replication)
 {
-	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
-	enum omap_overlay_caps caps = ovl->caps;
 	bool five_taps = true;
 	bool fieldmode = 0;
 	int r, cconv = 0;
 	unsigned offset0, offset1;
 	s32 row_inc;
 	s32 pix_inc;
-	u16 frame_height = oi->height;
+	u16 frame_height = height;
 	unsigned int field_offset = 0;
 	u16 outw, outh;
-	enum omap_channel channel;
-
-	channel = dispc_ovl_get_channel_out(plane);
 
-	DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
-		"%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
-		plane, oi->paddr, oi->p_uv_addr,
-		oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
-		oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
-		oi->mirror, ilace, channel, replication);
-
-	if (oi->paddr = 0)
+	if (paddr = 0)
 		return -EINVAL;
 
-	outw = oi->out_width = 0 ? oi->width : oi->out_width;
-	outh = oi->out_height = 0 ? oi->height : oi->out_height;
+	outw = out_width = 0 ? width : out_width;
+	outh = out_height = 0 ? height : out_height;
 
-	if (ilace && oi->height = outh)
+	if (ilace && height = outh)
 		fieldmode = 1;
 
 	if (ilace) {
 		if (fieldmode)
-			oi->height /= 2;
-		oi->pos_y /= 2;
+			height /= 2;
+		pos_y /= 2;
 		outh /= 2;
 
 		DSSDBG("adjusting for ilace: height %d, pos_y %d, "
-				"out_height %d\n",
-				oi->height, oi->pos_y, outh);
+				"out_height %d\n", height, pos_y, outh);
 	}
 
-	if (!dss_feat_color_mode_supported(plane, oi->color_mode))
+	if (!dss_feat_color_mode_supported(plane, color_mode))
 		return -EINVAL;
 
-	r = dispc_ovl_calc_scaling(plane, channel, caps, oi->width, oi->height,
-			outw, outh, oi->color_mode,
-			&five_taps);
+	r = dispc_ovl_calc_scaling(plane, channel, caps, width, height,
+			outw, outh, color_mode, &five_taps);
 	if (r)
 		return r;
 
-	if (oi->color_mode = OMAP_DSS_COLOR_YUV2 ||
-			oi->color_mode = OMAP_DSS_COLOR_UYVY ||
-			oi->color_mode = OMAP_DSS_COLOR_NV12)
+	if (color_mode = OMAP_DSS_COLOR_YUV2 ||
+			color_mode = OMAP_DSS_COLOR_UYVY ||
+			color_mode = OMAP_DSS_COLOR_NV12)
 		cconv = 1;
 
 	if (ilace && !fieldmode) {
@@ -1850,72 +1841,97 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 		 * so the integer part must be added to the base address of the
 		 * bottom field.
 		 */
-		if (!oi->height || oi->height = outh)
+		if (!height || height = outh)
 			field_offset = 0;
 		else
-			field_offset = oi->height / outh / 2;
+			field_offset = height / outh / 2;
 	}
 
 	/* Fields are independent but interleaved in memory. */
 	if (fieldmode)
 		field_offset = 1;
 
-	if (oi->rotation_type = OMAP_DSS_ROT_DMA)
-		calc_dma_rotation_offset(oi->rotation, oi->mirror,
-				oi->screen_width, oi->width, frame_height,
-				oi->color_mode, fieldmode, field_offset,
+	if (rotation_type = OMAP_DSS_ROT_DMA)
+		calc_dma_rotation_offset(rotation, mirror,
+				screen_width, width, frame_height,
+				color_mode, fieldmode, field_offset,
 				&offset0, &offset1, &row_inc, &pix_inc);
 	else
-		calc_vrfb_rotation_offset(oi->rotation, oi->mirror,
-				oi->screen_width, oi->width, frame_height,
-				oi->color_mode, fieldmode, field_offset,
+		calc_vrfb_rotation_offset(rotation, mirror,
+				screen_width, width, frame_height,
+				color_mode, fieldmode, field_offset,
 				&offset0, &offset1, &row_inc, &pix_inc);
 
 	DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
 			offset0, offset1, row_inc, pix_inc);
 
-	dispc_ovl_set_color_mode(plane, oi->color_mode);
+	dispc_ovl_set_color_mode(plane, color_mode);
 
-	dispc_ovl_set_ba0(plane, oi->paddr + offset0);
-	dispc_ovl_set_ba1(plane, oi->paddr + offset1);
+	dispc_ovl_set_ba0(plane, paddr + offset0);
+	dispc_ovl_set_ba1(plane, paddr + offset1);
 
-	if (OMAP_DSS_COLOR_NV12 = oi->color_mode) {
-		dispc_ovl_set_ba0_uv(plane, oi->p_uv_addr + offset0);
-		dispc_ovl_set_ba1_uv(plane, oi->p_uv_addr + offset1);
+	if (OMAP_DSS_COLOR_NV12 = color_mode) {
+		dispc_ovl_set_ba0_uv(plane, p_uv_addr + offset0);
+		dispc_ovl_set_ba1_uv(plane, p_uv_addr + offset1);
 	}
 
 
 	dispc_ovl_set_row_inc(plane, row_inc);
 	dispc_ovl_set_pix_inc(plane, pix_inc);
 
-	DSSDBG("%d,%d %dx%d -> %dx%d\n", oi->pos_x, oi->pos_y, oi->width,
-			oi->height, outw, outh);
+	DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, width, height,
+			outw, outh);
 
-	dispc_ovl_set_pos(plane, caps, oi->pos_x, oi->pos_y);
+	dispc_ovl_set_pos(plane, caps, pos_x, pos_y);
 
-	dispc_ovl_set_pic_size(plane, oi->width, oi->height);
+	dispc_ovl_set_pic_size(plane, width, height);
 
 	if (caps & OMAP_DSS_OVL_CAP_SCALE) {
-		dispc_ovl_set_scaling(plane, oi->width, oi->height,
+		dispc_ovl_set_scaling(plane, width, height,
 				   outw, outh,
 				   ilace, five_taps, fieldmode,
-				   oi->color_mode, oi->rotation, true);
+				   color_mode, rotation, true);
 		dispc_ovl_set_vid_size(plane, outw, outh);
 		dispc_ovl_set_vid_color_conv(plane, cconv);
 	}
 
-	dispc_ovl_set_rotation_attrs(plane, oi->rotation, oi->mirror,
-			oi->color_mode);
+	dispc_ovl_set_rotation_attrs(plane, rotation, mirror, color_mode);
 
-	dispc_ovl_set_zorder(plane, caps, oi->zorder);
-	dispc_ovl_set_pre_mult_alpha(plane, caps, oi->pre_mult_alpha);
-	dispc_ovl_setup_global_alpha(plane, caps, oi->global_alpha);
+	dispc_ovl_set_zorder(plane, caps, zorder);
+	dispc_ovl_set_pre_mult_alpha(plane, caps, pre_mult_alpha);
+	dispc_ovl_setup_global_alpha(plane, caps, global_alpha);
 
 	dispc_ovl_enable_replication(plane, caps, replication);
 
 	return 0;
 }
 
+int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
+		bool ilace, bool replication)
+{
+	int r;
+	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+	enum omap_channel channel;
+
+	channel = dispc_ovl_get_channel_out(plane);
+
+	DSSDBG("dispc_ovl_setup %d, pa %x, pa_uv %x, sw %d, %d,%d, %dx%d -> "
+		"%dx%d, cmode %x, rot %d, mir %d, ilace %d chan %d repl %d\n",
+		plane, oi->paddr, oi->p_uv_addr,
+		oi->screen_width, oi->pos_x, oi->pos_y, oi->width, oi->height,
+		oi->out_width, oi->out_height, oi->color_mode, oi->rotation,
+		oi->mirror, ilace, channel, replication);
+
+	r = dispc_plane_setup(plane, channel, ovl->caps, oi->paddr,
+		oi->p_uv_addr, oi->screen_width, oi->pos_x, oi->pos_y,
+		oi->width, oi->height, oi->out_width, oi->out_height,
+		oi->color_mode, oi->rotation, oi->mirror, oi->zorder,
+		oi->pre_mult_alpha, oi->global_alpha, oi->rotation_type,
+		ilace, replication);
+
+	return r;
+}
+
 int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi)
 {
 	return 0;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 18/29] OMAPDSS: DISPC: Make chroma_upscale an argument to dispc_plane_setup
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (16 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 17/29] OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_plane_setup Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 19/29] OMAPDSS: DISPC: Don't set chroma resampling bit for writeback Archit Taneja
                   ` (10 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Pass chroma_upscale boolean parameter to dispc_plane_setup(), this will be set
to true when dispc_plane_setup() is called from dispc_ovl_setup() and false when
called from dispc_wb_setup().

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dispc.c |   12 ++++++------
 1 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index eca6157..21d6286 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1789,7 +1789,7 @@ static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel,
 		u16 out_width, u16 out_height, enum omap_color_mode color_mode,
 		u8 rotation, bool mirror, u8 zorder, u8 pre_mult_alpha,
 		u8 global_alpha, enum omap_dss_rotation_type rotation_type,
-		bool ilace, bool replication)
+		bool chroma_upscale, bool ilace, bool replication)
 {
 	bool five_taps = true;
 	bool fieldmode = 0;
@@ -1887,10 +1887,9 @@ static int dispc_plane_setup(enum omap_plane plane, enum omap_channel channel,
 	dispc_ovl_set_pic_size(plane, width, height);
 
 	if (caps & OMAP_DSS_OVL_CAP_SCALE) {
-		dispc_ovl_set_scaling(plane, width, height,
-				   outw, outh,
-				   ilace, five_taps, fieldmode,
-				   color_mode, rotation, true);
+		dispc_ovl_set_scaling(plane, width, height, outw, outh,
+				ilace, five_taps, fieldmode, color_mode,
+				rotation, chroma_upscale);
 		dispc_ovl_set_vid_size(plane, outw, outh);
 		dispc_ovl_set_vid_color_conv(plane, cconv);
 	}
@@ -1911,6 +1910,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 {
 	int r;
 	struct omap_overlay *ovl = omap_dss_get_overlay(plane);
+	const bool chroma_upscale = true;
 	enum omap_channel channel;
 
 	channel = dispc_ovl_get_channel_out(plane);
@@ -1927,7 +1927,7 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 		oi->width, oi->height, oi->out_width, oi->out_height,
 		oi->color_mode, oi->rotation, oi->mirror, oi->zorder,
 		oi->pre_mult_alpha, oi->global_alpha, oi->rotation_type,
-		ilace, replication);
+		chroma_upscale, ilace, replication);
 
 	return r;
 }
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 19/29] OMAPDSS: DISPC: Don't set chroma resampling bit for writeback
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (17 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 18/29] OMAPDSS: DISPC: Make chroma_upscale an argument to dispc_plane_setup Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 20/29] OMAPDSS: Writeback: Add writeback capabilities Archit Taneja
                   ` (9 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

The bit YUVCHROMARESAMPLING isn't there for writeback in DISPC_WB_ATTRIBUTES2.
Ignore this bit in dispc_ovl_set_scaling_uv() if the plane is OMAP_DSS_WB.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dispc.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 21d6286..3a40f8e 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1238,7 +1238,8 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
 			color_mode != OMAP_DSS_COLOR_UYVY &&
 			color_mode != OMAP_DSS_COLOR_NV12)) {
 		/* reset chroma resampling for RGB formats  */
-		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
+		if (plane != OMAP_DSS_WB)
+			REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), 0, 8, 8);
 		return;
 	}
 	switch (color_mode) {
@@ -1277,8 +1278,10 @@ static void dispc_ovl_set_scaling_uv(enum omap_plane plane,
 			out_width, out_height, five_taps,
 				rotation, DISPC_COLOR_COMPONENT_UV);
 
-	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
-		(scale_x || scale_y) ? 1 : 0, 8, 8);
+	if (plane != OMAP_DSS_WB)
+		REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane),
+			(scale_x || scale_y) ? 1 : 0, 8, 8);
+
 	/* set H scaling */
 	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), scale_x ? 1 : 0, 5, 5);
 	/* set V scaling */
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 20/29] OMAPDSS: Writeback: Add writeback capabilities
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (18 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 19/29] OMAPDSS: DISPC: Don't set chroma resampling bit for writeback Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 21/29] OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup Archit Taneja
                   ` (8 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add a capabilities parameter of type omap_overlay_caps to omap_dss_writeback.
These caps let us reuse some of the DISPC overlay functions. Set the
capabilities so the writeback supports scaling and pre multiplied alpha.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/writeback.c |    3 +++
 include/video/omapdss.h             |    3 +++
 2 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index 540e61d..14103bf 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -90,6 +90,9 @@ void dss_init_writeback(void)
 		wb->id = i;
 		wb->plane_id = OMAP_DSS_WB + i;
 
+		wb->caps = OMAP_DSS_OVL_CAP_SCALE |
+				OMAP_DSS_OVL_CAP_PRE_MULT_ALPHA;
+
 		wb->set_wb_info = &dss_wb_set_info;
 		wb->get_wb_info = &dss_wb_get_info;
 	}
diff --git a/include/video/omapdss.h b/include/video/omapdss.h
index 49e3ccb..291457c 100644
--- a/include/video/omapdss.h
+++ b/include/video/omapdss.h
@@ -493,6 +493,9 @@ struct omap_dss_writeback {
 	int id;
 	int plane_id;
 
+	/* overlay-like capabilities writeback supports */
+	enum omap_overlay_caps caps;
+
 	/* dummy panel we are connected to */
 	struct omap_dss_device *dssdev;
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 21/29] OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (19 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 20/29] OMAPDSS: Writeback: Add writeback capabilities Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2012-08-02 10:22   ` Chandrabhanu Mahapatra
  2011-12-27 12:49 ` [RFC PATCH 22/29] OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions Archit Taneja
                   ` (7 subsequent siblings)
  28 siblings, 1 reply; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Call dispc_plane_setup() through dispc_wb_setup() to configure overlay-like
parameters. Create a helper function in writeback.c called dss_wb_calc_params()
which for now calculates the input width and height which goes to writeback.
Create a dummy dispc function which returns the channel of the manager to which
the writeback pipeline is connected.

The parameters in dispc_plane_setup() which do not hold for writeback are filled
passed as zeroes or false, dispc_plane_setup() takes care of not configuring
them if the plane is writeback.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c     |    5 ++++-
 drivers/video/omap2/dss/dispc.c     |   33 +++++++++++++++++++++++++++++++--
 drivers/video/omap2/dss/dss.h       |    6 +++++-
 drivers/video/omap2/dss/writeback.c |   17 +++++++++++++++++
 4 files changed, 57 insertions(+), 4 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index a17cc47..dd1fd419 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -661,6 +661,7 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb)
 {
 	struct wb_priv_data *wp = get_wb_priv(wb);
 	struct omap_dss_writeback_info *wi;
+	u16 in_width, in_height;
 	int r;
 
 	if (!wp->enabled || !wp->info_dirty)
@@ -670,7 +671,9 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb)
 
 	wi = &wp->info;
 
-	r = dispc_wb_setup(wb->id, wi);
+	dss_wb_calc_params(wb, wi, &in_width, &in_height);
+
+	r = dispc_wb_setup(wb->id, wi, in_width, in_height);
 	if (r) {
 		DSSERR("dispc_wb_setup failed\n");
 		return;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index 3a40f8e..c7de56d 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -908,6 +908,13 @@ void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in)
 	return;
 }
 
+static enum omap_channel dispc_wb_get_channel_in(int plane)
+{
+	/* Return LCD channel for now */
+
+	return OMAP_DSS_CHANNEL_LCD;
+}
+
 static void dispc_ovl_set_burst_size(enum omap_plane plane,
 		enum omap_burst_size burst_size)
 {
@@ -1935,9 +1942,31 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 	return r;
 }
 
-int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi)
+int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi,
+		u16 in_width, u16 in_height)
 {
-	return 0;
+	int r;
+	struct omap_dss_writeback *wb = omap_dss_get_writeback(id);
+	const int pos_x = 0, pos_y = 0;
+	const u8 zorder = 0, global_alpha = 0;
+	const bool chroma_upscale = false, ilace = false, replication = false;
+	enum omap_channel channel;
+
+	channel = dispc_wb_get_channel_in(wb->plane_id);
+
+	DSSDBG("dispc_wb_setup %d, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, "
+		"rot %d, mir %d, chan %d\n",
+		wb->id, wi->paddr, wi->p_uv_addr, in_width, in_height,
+		wi->buf_width, wi->buf_height, wi->color_mode, wi->rotation,
+		wi->mirror, channel);
+
+	r = dispc_plane_setup(wb->plane_id, channel, wb->caps, wi->paddr,
+		wi->p_uv_addr, in_width, pos_x, pos_y, in_width, in_height,
+		wi->buf_width, wi->buf_height, wi->color_mode, wi->rotation,
+		wi->mirror, zorder, wi->pre_mult_alpha, global_alpha,
+		wi->rotation_type, chroma_upscale, ilace, replication);
+
+	return r;
 }
 
 int dispc_ovl_enable(enum omap_plane plane, bool enable)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 1b128f1..69b4793 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -249,6 +249,9 @@ void dss_init_writeback(void);
 void dss_uninit_writeback(void);
 int writeback_init_display(struct omap_dss_device *dssdev);
 enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *wb);
+void dss_wb_calc_params(struct omap_dss_writeback *wb,
+		struct omap_dss_writeback_info *wi, u16 *in_width,
+		u16 *in_height);
 int dss_wb_simple_check(struct omap_dss_writeback *wb,
 		const struct omap_dss_writeback_info *info);
 
@@ -492,7 +495,8 @@ void dispc_mgr_setup(enum omap_channel channel,
 
 bool dispc_wb_go_busy(int id);
 void dispc_wb_go(int id);
-int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi);
+int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi,
+		u16 in_width, u16 in_height);
 void dispc_wb_enable(int id, bool enable);
 void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in);
 
diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index 14103bf..7c4e9c0 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -141,6 +141,23 @@ enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *
 	}
 }
 
+void dss_wb_calc_params(struct omap_dss_writeback *wb,
+		struct omap_dss_writeback_info *wi, u16 *in_width,
+		u16 *in_height)
+{
+	struct omap_video_timings timings;
+	struct omap_dss_device *dssdev;
+	struct omap_overlay_manager *mgr;
+
+	mgr = wb->dssdev->manager;
+	dssdev = mgr->get_display(mgr);
+
+	dssdev->driver->get_timings(dssdev, &timings);
+
+	*in_width = timings.x_res;
+	*in_height = timings.y_res;
+}
+
 int dss_wb_simple_check(struct omap_dss_writeback *wb,
 		const struct omap_dss_writeback_info *info)
 {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 22/29] OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (20 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 21/29] OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2012-08-02 10:07   ` Mahapatra, Chandrabhanu
  2011-12-27 12:49 ` [RFC PATCH 23/29] OMAPDSS: Writeback: Configure writeback specific parameters Archit Taneja
                   ` (6 subsequent siblings)
  28 siblings, 1 reply; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Fill up dispc_wb_go(), dispc_wb_go_busy(), dispc_wb_enable() and
dispc_wb_get_channel_in()/set_channel_in() with writeback register writes. Make
a minor modification in dss_wb_write_regs_extra() to pass the plane_id instead
of the writeback id when calling dispc_wb_set_channel_in().

Setup dispc_wb_enable() as dispc_enable_lcd_out() function and wait for the
FRAMEDONEWB interrupt while disabling writeback.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c |    2 +-
 drivers/video/omap2/dss/dispc.c |   68 +++++++++++++++++++++++++++++++++++----
 drivers/video/omap2/dss/dss.h   |    2 +-
 3 files changed, 63 insertions(+), 9 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index dd1fd419..57b061f 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -690,7 +690,7 @@ static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb)
 	if (!wp->extra_info_dirty)
 		return;
 
-	dispc_wb_set_channel_in(wb->id, wp->channel_in);
+	dispc_wb_set_channel_in(wb->plane_id, wp->channel_in);
 	dispc_ovl_set_fifo_threshold(wb->plane_id, wp->fifo_low, wp->fifo_high);
 
 	wp->extra_info_dirty = false;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index c7de56d..cbce120 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -510,12 +510,26 @@ void dispc_mgr_go(enum omap_channel channel)
 
 bool dispc_wb_go_busy(int id)
 {
-	return false;
+	return REG_GET(DISPC_CONTROL2, 6, 6) = 1;
 }
 
 void dispc_wb_go(int id)
 {
-	return;
+	struct omap_dss_writeback *wb = omap_dss_get_writeback(id);
+	bool enable, go;
+
+	enable = REG_GET(DISPC_OVL_ATTRIBUTES(wb->plane_id), 0, 0) = 1;
+
+	if (!enable)
+		return;
+
+	go = REG_GET(DISPC_CONTROL2, 6, 6) = 1;
+	if (go) {
+		DSSERR("GO bit not down for WB\n");
+		return;
+	}
+
+	REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6);
 }
 
 static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
@@ -903,16 +917,24 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
 	return channel;
 }
 
-void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in)
+void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in)
 {
-	return;
+	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ch_in, 18, 16);
 }
 
 static enum omap_channel dispc_wb_get_channel_in(int plane)
 {
-	/* Return LCD channel for now */
+	int channel_in = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 18, 16);
 
-	return OMAP_DSS_CHANNEL_LCD;
+	switch (channel_in) {
+	case OMAP_DSS_WB_LCD2_MGR:
+		return OMAP_DSS_CHANNEL_LCD2;
+	case OMAP_DSS_WB_TV_MGR:
+		return OMAP_DSS_CHANNEL_DIGIT;
+	case OMAP_DSS_WB_LCD1_MGR:
+	default:
+		return OMAP_DSS_CHANNEL_LCD;
+	};
 }
 
 static void dispc_ovl_set_burst_size(enum omap_plane plane,
@@ -2138,7 +2160,39 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable)
 
 void dispc_wb_enable(int id, bool enable)
 {
-	return;
+	struct omap_dss_writeback *wb = omap_dss_get_writeback(id);
+	enum omap_plane plane = wb->plane_id;
+	struct completion frame_done_completion;
+	bool is_on;
+	int r;
+	u32 irq;
+
+	is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
+	irq = DISPC_IRQ_FRAMEDONEWB;
+
+	if (!enable && is_on) {
+		init_completion(&frame_done_completion);
+
+		r = omap_dispc_register_isr(dispc_disable_isr,
+				&frame_done_completion, irq);
+
+		if (r)
+			DSSERR("failed to register FRAMEDONEWB isr\n");
+	}
+
+	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
+
+	if (!enable && is_on) {
+		if (!wait_for_completion_timeout(&frame_done_completion,
+					msecs_to_jiffies(100)))
+			DSSERR("timeout waiting for FRAMEDONEWB\n");
+
+		r = omap_dispc_unregister_isr(dispc_disable_isr,
+				&frame_done_completion, irq);
+
+		if (r)
+			DSSERR("failed to unregister FRAMEDONEWB isr\n");
+	}
 }
 
 void dispc_lcd_enable_signal_polarity(bool act_high)
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index 69b4793..c05658b 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -498,7 +498,7 @@ void dispc_wb_go(int id);
 int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi,
 		u16 in_width, u16 in_height);
 void dispc_wb_enable(int id, bool enable);
-void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in);
+void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in);
 
 /* VENC */
 #ifdef CONFIG_OMAP2_DSS_VENC
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 23/29] OMAPDSS: Writeback: Configure writeback specific parameters
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (21 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 22/29] OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 24/29] OMAPDSS: Writeback: Use panel driver ops to configure mirroring rotation and buffe Archit Taneja
                   ` (5 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Calculate writeback specific parameters capture mode, truncation and delay count
in dss_wb_calc_params(). The writeback parameters calculated are:

truncation: This is needs to be set if the color depth input to writeback is more
than the color depth of the color mode we want to store in memory.

writeback mode: This configures whether we want to use writeback in mem to mem
or capture mode. A helper function called wb_manual_update() is created, it
returns true if we are in mem to mem mode. It will be used later again when mem
to mem support is added.

delay_count: This specifies the time(in lines) when the HW flushes writeback
FIFOs and takes in new register configurations after the VSYNC is generated by
the manager to which writeback is connected.

Pass these parameters to dispc_wb_setup() so that they can be written in
writeback registers.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/apply.c     |   15 +++++++++++++--
 drivers/video/omap2/dss/dispc.c     |   28 +++++++++++++++++++++-------
 drivers/video/omap2/dss/dss.h       |    5 +++--
 drivers/video/omap2/dss/writeback.c |   31 +++++++++++++++++++++++++++----
 4 files changed, 64 insertions(+), 15 deletions(-)

diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
index 57b061f..b941d95 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/omap2/dss/apply.c
@@ -208,6 +208,13 @@ static bool mgr_manual_update(struct omap_overlay_manager *mgr)
 	return dssdev->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 }
 
+static bool wb_manual_update(struct omap_dss_writeback *wb)
+{
+	struct omap_overlay_manager *mgr = wb->dssdev->manager;
+
+	return mgr->get_display(mgr) ? false : true;
+}
+
 static int dss_check_settings_low(struct omap_overlay_manager *mgr,
 		struct omap_dss_device *dssdev, bool applying)
 {
@@ -662,6 +669,8 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb)
 	struct wb_priv_data *wp = get_wb_priv(wb);
 	struct omap_dss_writeback_info *wi;
 	u16 in_width, in_height;
+	bool truncation;
+	int delay_count;
 	int r;
 
 	if (!wp->enabled || !wp->info_dirty)
@@ -671,9 +680,11 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb)
 
 	wi = &wp->info;
 
-	dss_wb_calc_params(wb, wi, &in_width, &in_height);
+	dss_wb_calc_params(wb, wi, &in_width, &in_height, &truncation,
+		&delay_count);
 
-	r = dispc_wb_setup(wb->id, wi, in_width, in_height);
+	r = dispc_wb_setup(wb->id, wi, in_width, in_height,
+		wb_manual_update(wb), truncation, delay_count);
 	if (r) {
 		DSSERR("dispc_wb_setup failed\n");
 		return;
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
index cbce120..73ba7cd 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/omap2/dss/dispc.c
@@ -1965,29 +1965,43 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
 }
 
 int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi,
-		u16 in_width, u16 in_height)
+		u16 in_width, u16 in_height, bool mem_to_mem_mode,
+		bool truncation, int delay_count)
 {
 	int r;
 	struct omap_dss_writeback *wb = omap_dss_get_writeback(id);
+	enum omap_plane plane = wb->plane_id;
 	const int pos_x = 0, pos_y = 0;
 	const u8 zorder = 0, global_alpha = 0;
 	const bool chroma_upscale = false, ilace = false, replication = false;
 	enum omap_channel channel;
+	u32 l;
 
-	channel = dispc_wb_get_channel_in(wb->plane_id);
+	channel = dispc_wb_get_channel_in(plane);
 
 	DSSDBG("dispc_wb_setup %d, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, "
-		"rot %d, mir %d, chan %d\n",
-		wb->id, wi->paddr, wi->p_uv_addr, in_width, in_height,
-		wi->buf_width, wi->buf_height, wi->color_mode, wi->rotation,
-		wi->mirror, channel);
+		"rot %d, mir %d, chan %d, wb_mode %d, trunc %d, "
+		"delay_count %d\n", wb->id, wi->paddr, wi->p_uv_addr, in_width,
+		in_height, wi->buf_width, wi->buf_height, wi->color_mode,
+		wi->rotation, wi->mirror, channel, mem_to_mem_mode, truncation,
+		delay_count);
 
-	r = dispc_plane_setup(wb->plane_id, channel, wb->caps, wi->paddr,
+	r = dispc_plane_setup(plane, channel, wb->caps, wi->paddr,
 		wi->p_uv_addr, in_width, pos_x, pos_y, in_width, in_height,
 		wi->buf_width, wi->buf_height, wi->color_mode, wi->rotation,
 		wi->mirror, zorder, wi->pre_mult_alpha, global_alpha,
 		wi->rotation_type, chroma_upscale, ilace, replication);
 
+	/* setup extra DISPC_WB_ATTRIBUTES */
+	l = dispc_read_reg(DISPC_OVL_ATTRIBUTES(plane));
+	l = FLD_MOD(l, truncation, 10, 10);		/* TRUNCATIONENABLE */
+	l = FLD_MOD(l, mem_to_mem_mode, 19, 19);	/* WRITEBACKMODE */
+	l = FLD_MOD(l, wi->capture_rate, 26, 24);	/* CAPTUREMODE */
+	dispc_write_reg(DISPC_OVL_ATTRIBUTES(plane), l);
+
+	/* setup DISPC_WB_ATTRIBUTES2 */
+	REG_FLD_MOD(DISPC_OVL_ATTRIBUTES2(plane), delay_count, 7, 0);
+
 	return r;
 }
 
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
index c05658b..c656aed 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/omap2/dss/dss.h
@@ -251,7 +251,7 @@ int writeback_init_display(struct omap_dss_device *dssdev);
 enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *wb);
 void dss_wb_calc_params(struct omap_dss_writeback *wb,
 		struct omap_dss_writeback_info *wi, u16 *in_width,
-		u16 *in_height);
+		u16 *in_height, bool *truncation, int *delay_count);
 int dss_wb_simple_check(struct omap_dss_writeback *wb,
 		const struct omap_dss_writeback_info *info);
 
@@ -496,7 +496,8 @@ void dispc_mgr_setup(enum omap_channel channel,
 bool dispc_wb_go_busy(int id);
 void dispc_wb_go(int id);
 int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi,
-		u16 in_width, u16 in_height);
+		u16 in_width, u16 in_height, bool mem_to_mem_mode,
+		bool truncation, int delay_count);
 void dispc_wb_enable(int id, bool enable);
 void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in);
 
diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index 7c4e9c0..82d601c 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -143,7 +143,7 @@ enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *
 
 void dss_wb_calc_params(struct omap_dss_writeback *wb,
 		struct omap_dss_writeback_info *wi, u16 *in_width,
-		u16 *in_height)
+		u16 *in_height, bool *truncation, int *delay_count)
 {
 	struct omap_video_timings timings;
 	struct omap_dss_device *dssdev;
@@ -152,10 +152,33 @@ void dss_wb_calc_params(struct omap_dss_writeback *wb,
 	mgr = wb->dssdev->manager;
 	dssdev = mgr->get_display(mgr);
 
-	dssdev->driver->get_timings(dssdev, &timings);
+	if (dssdev) {
+		/* we are in capture mode */
+		dssdev->driver->get_timings(dssdev, &timings);
 
-	*in_width = timings.x_res;
-	*in_height = timings.y_res;
+		*in_width = timings.x_res;
+		*in_height = timings.y_res;
+
+		/* TODO: Find more optimal values of delay_count */
+		*delay_count = timings.vsw + timings.vbp + timings.vfp - 1;
+		*delay_count = *delay_count < 255 ? : 255;
+	}
+
+	switch (wi->color_mode) {
+	case OMAP_DSS_COLOR_RGB16:
+	case OMAP_DSS_COLOR_RGB24P:
+	case OMAP_DSS_COLOR_ARGB16:
+	case OMAP_DSS_COLOR_RGBA16:
+	case OMAP_DSS_COLOR_RGB12U:
+	case OMAP_DSS_COLOR_ARGB16_1555:
+	case OMAP_DSS_COLOR_XRGB16_1555:
+	case OMAP_DSS_COLOR_RGBX16:
+		*truncation = true;
+		break;
+	default:
+		*truncation = false;
+		break;
+	}
 }
 
 int dss_wb_simple_check(struct omap_dss_writeback *wb,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 24/29] OMAPDSS: Writeback: Use panel driver ops to configure mirroring rotation and buffe
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (22 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 23/29] OMAPDSS: Writeback: Configure writeback specific parameters Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 25/29] OMAPDSS: Writeback: Add sysfs attributes to writeback panel Archit Taneja
                   ` (4 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add rotation and mirroring ops to writeback panel driver. Use these ops to
get/set wb info.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/writeback.c |   79 +++++++++++++++++++++++++++++++++++
 1 files changed, 79 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index 82d601c..215958e 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -287,9 +287,83 @@ static int writeback_panel_resume(struct omap_dss_device *dssdev)
 	return 0;
 }
 
+static int writeback_panel_rotate(struct omap_dss_device *dssdev, u8 rotate)
+{
+	int r;
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+	struct omap_dss_writeback_info info;
+
+	wb->get_wb_info(wb, &info);
+
+	info.rotation = rotate;
+
+	r = wb->set_wb_info(wb, &info);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to set rotation %d\n", rotate);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static u8 writeback_panel_get_rotate(struct omap_dss_device *dssdev)
+{
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+	struct omap_dss_writeback_info info;
+
+	wb->get_wb_info(wb, &info);
+
+	return info.rotation;
+}
+
+static int writeback_panel_mirror(struct omap_dss_device *dssdev, bool mirror)
+{
+	int r;
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+	struct omap_dss_writeback_info info;
+
+	wb->get_wb_info(wb, &info);
+
+	info.mirror = mirror;
+
+	r = wb->set_wb_info(wb, &info);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to set mirror %d\n", mirror);
+		return -EINVAL;
+	}
+
+	return 0;
+}
+
+static bool writeback_panel_get_mirror(struct omap_dss_device *dssdev)
+{
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+	struct omap_dss_writeback_info info;
+
+	wb->get_wb_info(wb, &info);
+
+	return info.mirror;
+}
+
 static void writeback_panel_set_timings(struct omap_dss_device *dssdev,
 		struct omap_video_timings *timings)
 {
+	int r;
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+	struct omap_dss_writeback_info info;
+
+	wb->get_wb_info(wb, &info);
+
+	info.buf_width = timings->x_res;
+	info.buf_height = timings->y_res;
+
+	r = wb->set_wb_info(wb, &info);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to set timings %d, %d\n",
+			timings->x_res, timings->y_res);
+		return;
+	}
+
 	dssdev->panel.timings.x_res = timings->x_res;
 	dssdev->panel.timings.y_res = timings->y_res;
 }
@@ -315,6 +389,11 @@ static struct omap_dss_driver writeback_panel_driver = {
 	.suspend = writeback_panel_suspend,
 	.resume = writeback_panel_resume,
 
+	.set_rotate = writeback_panel_rotate,
+	.get_rotate = writeback_panel_get_rotate,
+	.set_mirror = writeback_panel_mirror,
+	.get_mirror = writeback_panel_get_mirror,
+
 	.set_timings = writeback_panel_set_timings,
 	.get_timings = writeback_panel_get_timings,
 	.check_timings = writeback_panel_check_timings,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 25/29] OMAPDSS: Writeback: Add sysfs attributes to writeback panel
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (23 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 24/29] OMAPDSS: Writeback: Use panel driver ops to configure mirroring rotation and buffe Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 26/29] OMAPDSS: DISPLAY: Add a manager apply to sysfs store attributes for writeback Archit Taneja
                   ` (3 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add the following sysfs attributes to the writeback panel driver:
- paddr
- p_uv_addr
- rotation_type
- color_mode
- pre_mult_alpha
- capture_rate

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/writeback.c |  210 +++++++++++++++++++++++++++++++++++
 1 files changed, 210 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
index 215958e..c6450e7 100644
--- a/drivers/video/omap2/dss/writeback.c
+++ b/drivers/video/omap2/dss/writeback.c
@@ -214,8 +214,218 @@ int dss_wb_simple_check(struct omap_dss_writeback *wb,
 
 /* Dummy Writeback Panel driver */
 
+static ssize_t writeback_panel_paddr_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	wb->get_wb_info(wb, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%x\n", info.paddr);
+}
+
+static ssize_t writeback_panel_p_uv_addr_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	wb->get_wb_info(wb, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%x\n", info.p_uv_addr);
+}
+
+static ssize_t writeback_panel_rotation_type_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	wb->get_wb_info(wb, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.rotation_type);
+}
+
+static ssize_t writeback_panel_color_mode_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	wb->get_wb_info(wb, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.color_mode);
+}
+
+static ssize_t writeback_panel_color_mode_store(struct device *dev,
+		struct device_attribute *attr, const char *buf,
+		size_t size)
+{
+	int r;
+	int color_mode;
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	r = kstrtoint(buf, 0, &color_mode);
+	if (r)
+		return r;
+
+	wb->get_wb_info(wb, &info);
+
+	info.color_mode = color_mode;
+
+	r = wb->set_wb_info(wb, &info);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to set color mode %d\n",
+			color_mode);
+		return r;
+	}
+
+	if (dssdev->manager) {
+		r = dssdev->manager->apply(dssdev->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t writeback_panel_pre_mult_alpha_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	wb->get_wb_info(wb, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.pre_mult_alpha);
+}
+
+static ssize_t writeback_panel_pre_mult_alpha_store(struct device *dev,
+		struct device_attribute *attr, const char *buf,
+		size_t size)
+{
+	int r;
+	u8 pre_mult_alpha;
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	r = kstrtou8(buf, 0, &pre_mult_alpha);
+	if (r)
+		return r;
+
+	wb->get_wb_info(wb, &info);
+
+	info.pre_mult_alpha = pre_mult_alpha;
+
+	r = wb->set_wb_info(wb, &info);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to set pre_mult_alpha %d\n",
+			pre_mult_alpha);
+		return r;
+	}
+
+	if (dssdev->manager) {
+		r = dssdev->manager->apply(dssdev->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static ssize_t writeback_panel_capture_rate_show(struct device *dev,
+		struct device_attribute *attr, char *buf)
+{
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	wb->get_wb_info(wb, &info);
+
+	return snprintf(buf, PAGE_SIZE, "%d\n", info.capture_rate);
+}
+
+static ssize_t writeback_panel_capture_rate_store(struct device *dev,
+		struct device_attribute *attr, const char *buf,
+		size_t size)
+{
+	int r;
+	int capture_rate;
+	struct omap_dss_writeback_info info;
+	struct omap_dss_device *dssdev = to_dss_device(dev);
+	struct omap_dss_writeback *wb = dssdev->wbdev;
+
+	r = kstrtoint(buf, 0, &capture_rate);
+	if (r)
+		return r;
+
+	wb->get_wb_info(wb, &info);
+
+	info.capture_rate = capture_rate;
+
+	r = wb->set_wb_info(wb, &info);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to set capture_rate %d\n",
+			capture_rate);
+		return r;
+	}
+
+	if (dssdev->manager) {
+		r = dssdev->manager->apply(dssdev->manager);
+		if (r)
+			return r;
+	}
+
+	return size;
+}
+
+static DEVICE_ATTR(paddr, S_IRUGO, writeback_panel_paddr_show, NULL);
+static DEVICE_ATTR(p_uv_addr, S_IRUGO, writeback_panel_p_uv_addr_show, NULL);
+static DEVICE_ATTR(rotation_type, S_IRUGO, writeback_panel_rotation_type_show,
+		NULL);
+static DEVICE_ATTR(color_mode, S_IRUGO | S_IWUSR,
+		writeback_panel_color_mode_show,
+		writeback_panel_color_mode_store);
+static DEVICE_ATTR(pre_mult_alpha, S_IRUGO | S_IWUSR,
+		writeback_panel_pre_mult_alpha_show,
+		writeback_panel_pre_mult_alpha_store);
+static DEVICE_ATTR(capture_rate, S_IRUGO | S_IWUSR,
+		writeback_panel_capture_rate_show,
+		writeback_panel_capture_rate_store);
+
+static struct attribute *writeback_attrs[] = {
+	&dev_attr_paddr.attr,
+	&dev_attr_p_uv_addr.attr,
+	&dev_attr_rotation_type.attr,
+	&dev_attr_color_mode.attr,
+	&dev_attr_pre_mult_alpha.attr,
+	&dev_attr_capture_rate.attr,
+	NULL,
+};
+
+static struct attribute_group writeback_attr_group = {
+	.attrs = writeback_attrs,
+};
+
 static int writeback_panel_probe(struct omap_dss_device *dssdev)
 {
+	int r;
+
+	r = sysfs_create_group(&dssdev->dev.kobj, &writeback_attr_group);
+	if (r) {
+		dev_err(&dssdev->dev, "failed to create sysfs files\n");
+		return r;
+	}
+
 	return 0;
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 26/29] OMAPDSS: DISPLAY: Add a manager apply to sysfs store attributes for writeback
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (24 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 25/29] OMAPDSS: Writeback: Add sysfs attributes to writeback panel Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 27/29] OMAPDSS: MANAGER: Split manager_display_store into smaller functions Archit Taneja
                   ` (2 subsequent siblings)
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Writeback driver ops don't apply the writeback attribute changes, they just set
the writeback info parameters. Add manager apply calls in sysfs store ops for
timings, rotation and mirroring when its the writeback panel.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/display.c |   18 ++++++++++++++++++
 1 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 03d7fb0..71ef0d7 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -144,6 +144,12 @@ static ssize_t display_timings_store(struct device *dev,
 
 	dssdev->driver->set_timings(dssdev, &t);
 
+	if (dssdev->wbdev && dssdev->manager) {
+		r = dssdev->manager->apply(dssdev->manager);
+		if (r)
+			return r;
+	}
+
 	return size;
 }
 
@@ -175,6 +181,12 @@ static ssize_t display_rotate_store(struct device *dev,
 	if (r)
 		return r;
 
+	if (dssdev->wbdev && dssdev->manager) {
+		r = dssdev->manager->apply(dssdev->manager);
+		if (r)
+			return r;
+	}
+
 	return size;
 }
 
@@ -207,6 +219,12 @@ static ssize_t display_mirror_store(struct device *dev,
 	if (r)
 		return r;
 
+	if (dssdev->wbdev && dssdev->manager) {
+		r = dssdev->manager->apply(dssdev->manager);
+		if (r)
+			return r;
+	}
+
 	return size;
 }
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 27/29] OMAPDSS: MANAGER: Split manager_display_store into smaller functions
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (25 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 26/29] OMAPDSS: DISPLAY: Add a manager apply to sysfs store attributes for writeback Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 28/29] OMAPDSS: MANAGER: Add writeback as a sysfs attribute Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 29/29] OMAPDSS: FEATURES: Allow WB panels to attach to managers Archit Taneja
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Split manager_display_store() into two function, the first function finds a
device with the same name. The second unsets the current output attached and
sets the one we had searched for.

This is done so that there can be re use between display store and writeback
store sysfs ops.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/manager.c |   46 ++++++++++++++++++++++++++++++------
 1 files changed, 38 insertions(+), 8 deletions(-)

diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index f4fd3d8..fb7c1e6 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -49,13 +49,11 @@ static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
 			dssdev->name : "<none>");
 }
 
-static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
+static int dss_find_device_buf(struct omap_dss_device **pdssdev,
 		const char *buf, size_t size)
 {
-	int r = 0;
 	size_t len = size;
 	struct omap_dss_device *dssdev = NULL;
-	struct omap_dss_device *curr_display;
 
 	int match(struct omap_dss_device *dssdev, void *data)
 	{
@@ -73,12 +71,25 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 		return -EINVAL;
 
 	if (dssdev)
-		DSSDBG("display %s found\n", dssdev->name);
+		DSSDBG("device %s found\n", dssdev->name);
+
+	*pdssdev = dssdev;
+
+	return 0;
+}
+static int dss_mgr_set_output(struct omap_overlay_manager *mgr,
+		struct omap_dss_device *dssdev)
+{
+	int r;
+	struct omap_dss_device *curr_dssdev;
 
-	curr_display = mgr->get_display(mgr);
+	if (dssdev->wbdev)
+		curr_dssdev = mgr->get_writeback(mgr);
+	else
+		curr_dssdev = mgr->get_display(mgr);
 
-	if (curr_display) {
-		r = mgr->unset_device(mgr, curr_display);
+	if (curr_dssdev) {
+		r = mgr->unset_device(mgr, curr_dssdev);
 		if (r) {
 			DSSERR("failed to unset display\n");
 			goto put_device;
@@ -99,11 +110,30 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 		}
 	}
 
+	return 0;
+
 put_device:
 	if (dssdev)
 		omap_dss_put_device(dssdev);
 
-	return r ? r : size;
+	return r;
+}
+
+static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
+		const char *buf, size_t size)
+{
+	int r;
+	struct omap_dss_device *dssdev;
+
+	r = dss_find_device_buf(&dssdev, buf, size);
+	if (r)
+		return r;
+
+	r = dss_mgr_set_output(mgr, dssdev);
+	if (r)
+		return r;
+
+	return size;
 }
 
 static ssize_t manager_default_color_show(struct omap_overlay_manager *mgr,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 28/29] OMAPDSS: MANAGER: Add writeback as a sysfs attribute
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (26 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 27/29] OMAPDSS: MANAGER: Split manager_display_store into smaller functions Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  2011-12-27 12:49 ` [RFC PATCH 29/29] OMAPDSS: FEATURES: Allow WB panels to attach to managers Archit Taneja
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add writeback as a sysfs attribute. This can be used to show and store the dummy
writeback panel that the manager can connect to.

Add checks so that in the store functions so that a display store cant set a
writeback device and vice versa.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/manager.c |   38 +++++++++++++++++++++++++++++++++++++
 1 files changed, 38 insertions(+), 0 deletions(-)

diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
index fb7c1e6..a064656 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/omap2/dss/manager.c
@@ -129,6 +129,41 @@ static ssize_t manager_display_store(struct omap_overlay_manager *mgr,
 	if (r)
 		return r;
 
+	if (dssdev->wbdev) {
+		r = -EINVAL;
+		return r;
+	}
+
+	r = dss_mgr_set_output(mgr, dssdev);
+	if (r)
+		return r;
+
+	return size;
+}
+
+static ssize_t manager_writeback_show(struct omap_overlay_manager *mgr, char *buf)
+{
+	struct omap_dss_device *wb_device = mgr->get_writeback(mgr);
+
+	return snprintf(buf, PAGE_SIZE, "%s\n", wb_device ?
+			wb_device->name : "<none>");
+}
+
+static ssize_t manager_writeback_store(struct omap_overlay_manager *mgr,
+		const char *buf, size_t size)
+{
+	int r;
+	struct omap_dss_device *dssdev;
+
+	r = dss_find_device_buf(&dssdev, buf, size);
+	if (r)
+		return r;
+
+	if (!dssdev->wbdev) {
+		r = -EINVAL;
+		return r;
+	}
+
 	r = dss_mgr_set_output(mgr, dssdev);
 	if (r)
 		return r;
@@ -452,6 +487,8 @@ struct manager_attribute {
 static MANAGER_ATTR(name, S_IRUGO, manager_name_show, NULL);
 static MANAGER_ATTR(display, S_IRUGO|S_IWUSR,
 		manager_display_show, manager_display_store);
+static MANAGER_ATTR(writeback, S_IRUGO|S_IWUSR,
+		manager_writeback_show, manager_writeback_store);
 static MANAGER_ATTR(default_color, S_IRUGO|S_IWUSR,
 		manager_default_color_show, manager_default_color_store);
 static MANAGER_ATTR(trans_key_type, S_IRUGO|S_IWUSR,
@@ -475,6 +512,7 @@ static MANAGER_ATTR(cpr_coef, S_IRUGO|S_IWUSR,
 static struct attribute *manager_sysfs_attrs[] = {
 	&manager_attr_name.attr,
 	&manager_attr_display.attr,
+	&manager_attr_writeback.attr,
 	&manager_attr_default_color.attr,
 	&manager_attr_trans_key_type.attr,
 	&manager_attr_trans_key_value.attr,
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [RFC PATCH 29/29] OMAPDSS: FEATURES: Allow WB panels to attach to managers
  2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
                   ` (27 preceding siblings ...)
  2011-12-27 12:49 ` [RFC PATCH 28/29] OMAPDSS: MANAGER: Add writeback as a sysfs attribute Archit Taneja
@ 2011-12-27 12:49 ` Archit Taneja
  28 siblings, 0 replies; 32+ messages in thread
From: Archit Taneja @ 2011-12-27 12:49 UTC (permalink / raw)
  To: tomi.valkeinen; +Cc: rohitkc, linux-omap, linux-fbdev, Archit Taneja

Add WB panel type in supported displays for all managers of OMAP4. A manager can
now use set/unset ops on the dummy writeback panel.

Signed-off-by: Archit Taneja <archit@ti.com>
---
 drivers/video/omap2/dss/dss_features.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/omap2/dss/dss_features.c
index 9478ed8..dbde3b9 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/omap2/dss/dss_features.c
@@ -132,14 +132,16 @@ static const enum omap_display_type omap3630_dss_supported_displays[] = {
 
 static const enum omap_display_type omap4_dss_supported_displays[] = {
 	/* OMAP_DSS_CHANNEL_LCD */
-	OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
+	OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI |
+	OMAP_DISPLAY_TYPE_WB,
 
 	/* OMAP_DSS_CHANNEL_DIGIT */
 	OMAP_DISPLAY_TYPE_VENC | OMAP_DISPLAY_TYPE_HDMI,
+	OMAP_DISPLAY_TYPE_WB,
 
 	/* OMAP_DSS_CHANNEL_LCD2 */
 	OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
-	OMAP_DISPLAY_TYPE_DSI,
+	OMAP_DISPLAY_TYPE_DSI | OMAP_DISPLAY_TYPE_WB,
 };
 
 static const enum omap_color_mode omap2_dss_supported_color_modes[] = {
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 32+ messages in thread

* Re: [RFC PATCH 22/29] OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions
  2011-12-27 12:49 ` [RFC PATCH 22/29] OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions Archit Taneja
@ 2012-08-02 10:07   ` Mahapatra, Chandrabhanu
  0 siblings, 0 replies; 32+ messages in thread
From: Mahapatra, Chandrabhanu @ 2012-08-02 10:07 UTC (permalink / raw)
  To: Archit Taneja; +Cc: tomi.valkeinen, rohitkc, linux-omap, linux-fbdev

On Tue, Dec 27, 2011 at 6:07 PM, Archit Taneja <archit@ti.com> wrote:
> Fill up dispc_wb_go(), dispc_wb_go_busy(), dispc_wb_enable() and
> dispc_wb_get_channel_in()/set_channel_in() with writeback register writes. Make
> a minor modification in dss_wb_write_regs_extra() to pass the plane_id instead
> of the writeback id when calling dispc_wb_set_channel_in().
>
> Setup dispc_wb_enable() as dispc_enable_lcd_out() function and wait for the
> FRAMEDONEWB interrupt while disabling writeback.
>
> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/apply.c |    2 +-
>  drivers/video/omap2/dss/dispc.c |   68 +++++++++++++++++++++++++++++++++++----
>  drivers/video/omap2/dss/dss.h   |    2 +-
>  3 files changed, 63 insertions(+), 9 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
> index dd1fd419..57b061f 100644
> --- a/drivers/video/omap2/dss/apply.c
> +++ b/drivers/video/omap2/dss/apply.c
> @@ -690,7 +690,7 @@ static void dss_wb_write_regs_extra(struct omap_dss_writeback *wb)
>         if (!wp->extra_info_dirty)
>                 return;
>
> -       dispc_wb_set_channel_in(wb->id, wp->channel_in);
> +       dispc_wb_set_channel_in(wb->plane_id, wp->channel_in);
>         dispc_ovl_set_fifo_threshold(wb->plane_id, wp->fifo_low, wp->fifo_high);
>
>         wp->extra_info_dirty = false;
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index c7de56d..cbce120 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -510,12 +510,26 @@ void dispc_mgr_go(enum omap_channel channel)
>
>  bool dispc_wb_go_busy(int id)
>  {
> -       return false;
> +       return REG_GET(DISPC_CONTROL2, 6, 6) = 1;
>  }
>
>  void dispc_wb_go(int id)
>  {
> -       return;
> +       struct omap_dss_writeback *wb = omap_dss_get_writeback(id);
> +       bool enable, go;
> +
> +       enable = REG_GET(DISPC_OVL_ATTRIBUTES(wb->plane_id), 0, 0) = 1;
> +
> +       if (!enable)
> +               return;
> +
> +       go = REG_GET(DISPC_CONTROL2, 6, 6) = 1;
> +       if (go) {
> +               DSSERR("GO bit not down for WB\n");
> +               return;
> +       }
> +
> +       REG_FLD_MOD(DISPC_CONTROL2, 1, 6, 6);
>  }
>
>  static void dispc_ovl_write_firh_reg(enum omap_plane plane, int reg, u32 value)
> @@ -903,16 +917,24 @@ static enum omap_channel dispc_ovl_get_channel_out(enum omap_plane plane)
>         return channel;
>  }
>
> -void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in)
> +void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in)
>  {
> -       return;
> +       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), ch_in, 18, 16);
>  }
>
>  static enum omap_channel dispc_wb_get_channel_in(int plane)
>  {
> -       /* Return LCD channel for now */
> +       int channel_in = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 18, 16);
>
> -       return OMAP_DSS_CHANNEL_LCD;
> +       switch (channel_in) {
> +       case OMAP_DSS_WB_LCD2_MGR:
> +               return OMAP_DSS_CHANNEL_LCD2;
> +       case OMAP_DSS_WB_TV_MGR:
> +               return OMAP_DSS_CHANNEL_DIGIT;
> +       case OMAP_DSS_WB_LCD1_MGR:
> +       default:
> +               return OMAP_DSS_CHANNEL_LCD;
> +       };
>  }
>

What about other cases of pipelines and overlays here? You have
considered only overlays and that too ignored OMAP_DSS_CHANNEL_LCD3.

The channel_in parameter of DISPC_WB_ATTRIBUTES does handle the
following cases as well:
0x0: Primary LCD overlay output
0x1: Secondary LCD output
0x2: TV overlay output
0x7: Third LCD output

0x3: Graphics pipeline output
0x4: Video1 pipeline output
0x5: Video2 pipeline output
0x6: Video3 pipeline output

>  static void dispc_ovl_set_burst_size(enum omap_plane plane,
> @@ -2138,7 +2160,39 @@ void dispc_mgr_enable(enum omap_channel channel, bool enable)
>
>  void dispc_wb_enable(int id, bool enable)
>  {
> -       return;
> +       struct omap_dss_writeback *wb = omap_dss_get_writeback(id);
> +       enum omap_plane plane = wb->plane_id;
> +       struct completion frame_done_completion;
> +       bool is_on;
> +       int r;
> +       u32 irq;
> +
> +       is_on = REG_GET(DISPC_OVL_ATTRIBUTES(plane), 0, 0);
> +       irq = DISPC_IRQ_FRAMEDONEWB;
> +
> +       if (!enable && is_on) {
> +               init_completion(&frame_done_completion);
> +
> +               r = omap_dispc_register_isr(dispc_disable_isr,
> +                               &frame_done_completion, irq);
> +
> +               if (r)
> +                       DSSERR("failed to register FRAMEDONEWB isr\n");
> +       }
> +
> +       REG_FLD_MOD(DISPC_OVL_ATTRIBUTES(plane), enable ? 1 : 0, 0, 0);
> +
> +       if (!enable && is_on) {
> +               if (!wait_for_completion_timeout(&frame_done_completion,
> +                                       msecs_to_jiffies(100)))
> +                       DSSERR("timeout waiting for FRAMEDONEWB\n");
> +
> +               r = omap_dispc_unregister_isr(dispc_disable_isr,
> +                               &frame_done_completion, irq);
> +
> +               if (r)
> +                       DSSERR("failed to unregister FRAMEDONEWB isr\n");
> +       }
>  }
>
>  void dispc_lcd_enable_signal_polarity(bool act_high)
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index 69b4793..c05658b 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -498,7 +498,7 @@ void dispc_wb_go(int id);
>  int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi,
>                 u16 in_width, u16 in_height);
>  void dispc_wb_enable(int id, bool enable);
> -void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in);
> +void dispc_wb_set_channel_in(int plane, enum dss_writeback_channel_in ch_in);
>
>  /* VENC */
>  #ifdef CONFIG_OMAP2_DSS_VENC
> --
> 1.7.4.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html



-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* Re: [RFC PATCH 21/29] OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup
  2011-12-27 12:49 ` [RFC PATCH 21/29] OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup Archit Taneja
@ 2012-08-02 10:22   ` Chandrabhanu Mahapatra
  0 siblings, 0 replies; 32+ messages in thread
From: Chandrabhanu Mahapatra @ 2012-08-02 10:22 UTC (permalink / raw)
  To: Archit Taneja; +Cc: tomi.valkeinen, rohitkc, linux-omap, linux-fbdev

On Tuesday 27 December 2011 06:07 PM, Archit Taneja wrote:
> Call dispc_plane_setup() through dispc_wb_setup() to configure overlay-like
> parameters. Create a helper function in writeback.c called dss_wb_calc_params()
> which for now calculates the input width and height which goes to writeback.
> Create a dummy dispc function which returns the channel of the manager to which
> the writeback pipeline is connected.
>
> The parameters in dispc_plane_setup() which do not hold for writeback are filled
> passed as zeroes or false, dispc_plane_setup() takes care of not configuring
> them if the plane is writeback.
>
> Signed-off-by: Archit Taneja <archit@ti.com>
> ---
>  drivers/video/omap2/dss/apply.c     |    5 ++++-
>  drivers/video/omap2/dss/dispc.c     |   33 +++++++++++++++++++++++++++++++--
>  drivers/video/omap2/dss/dss.h       |    6 +++++-
>  drivers/video/omap2/dss/writeback.c |   17 +++++++++++++++++
>  4 files changed, 57 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/omap2/dss/apply.c
> index a17cc47..dd1fd419 100644
> --- a/drivers/video/omap2/dss/apply.c
> +++ b/drivers/video/omap2/dss/apply.c
> @@ -661,6 +661,7 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb)
>  {
>  	struct wb_priv_data *wp = get_wb_priv(wb);
>  	struct omap_dss_writeback_info *wi;
> +	u16 in_width, in_height;
>  	int r;
>  
>  	if (!wp->enabled || !wp->info_dirty)
> @@ -670,7 +671,9 @@ static void dss_wb_write_regs(struct omap_dss_writeback *wb)
>  
>  	wi = &wp->info;
>  
> -	r = dispc_wb_setup(wb->id, wi);
> +	dss_wb_calc_params(wb, wi, &in_width, &in_height);
> +
> +	r = dispc_wb_setup(wb->id, wi, in_width, in_height);
>  	if (r) {
>  		DSSERR("dispc_wb_setup failed\n");
>  		return;
> diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
> index 3a40f8e..c7de56d 100644
> --- a/drivers/video/omap2/dss/dispc.c
> +++ b/drivers/video/omap2/dss/dispc.c
> @@ -908,6 +908,13 @@ void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in)
>  	return;
>  }
>  
> +static enum omap_channel dispc_wb_get_channel_in(int plane)
> +{
> +	/* Return LCD channel for now */
> +
> +	return OMAP_DSS_CHANNEL_LCD;
> +}
> +
>  static void dispc_ovl_set_burst_size(enum omap_plane plane,
>  		enum omap_burst_size burst_size)
>  {
> @@ -1935,9 +1942,31 @@ int dispc_ovl_setup(enum omap_plane plane, struct omap_overlay_info *oi,
>  	return r;
>  }
>  
> -int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi)
> +int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi,
> +		u16 in_width, u16 in_height)
>  {
> -	return 0;
> +	int r;
> +	struct omap_dss_writeback *wb = omap_dss_get_writeback(id);
> +	const int pos_x = 0, pos_y = 0;
> +	const u8 zorder = 0, global_alpha = 0;
> +	const bool chroma_upscale = false, ilace = false, replication = false;
> +	enum omap_channel channel;
> +
> +	channel = dispc_wb_get_channel_in(wb->plane_id);
> +
> +	DSSDBG("dispc_wb_setup %d, pa %x, pa_uv %x, %d,%d -> %dx%d, cmode %x, "
> +		"rot %d, mir %d, chan %d\n",
> +		wb->id, wi->paddr, wi->p_uv_addr, in_width, in_height,
> +		wi->buf_width, wi->buf_height, wi->color_mode, wi->rotation,
> +		wi->mirror, channel);
> +
> +	r = dispc_plane_setup(wb->plane_id, channel, wb->caps, wi->paddr,
> +		wi->p_uv_addr, in_width, pos_x, pos_y, in_width, in_height,
> +		wi->buf_width, wi->buf_height, wi->color_mode, wi->rotation,
> +		wi->mirror, zorder, wi->pre_mult_alpha, global_alpha,
> +		wi->rotation_type, chroma_upscale, ilace, replication);
The only note worthy difference here is use of omap_dss_writeback_info
*wi instead of omap_overlay_info *oi in dispc_ovl_setup(). If
omap_overlay_info can be used instead of omap_dss_writeback_info then
the same dispc_ovl_setup() would have been used to handle writeback as a
plane just like others but with extra checks for (plane = OMAP_DSS_WB).
I think this way it would have been much cleaner otherwise it looks good.
> +
> +	return r;
>  }
>  
>  int dispc_ovl_enable(enum omap_plane plane, bool enable)
> diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
> index 1b128f1..69b4793 100644
> --- a/drivers/video/omap2/dss/dss.h
> +++ b/drivers/video/omap2/dss/dss.h
> @@ -249,6 +249,9 @@ void dss_init_writeback(void);
>  void dss_uninit_writeback(void);
>  int writeback_init_display(struct omap_dss_device *dssdev);
>  enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *wb);
> +void dss_wb_calc_params(struct omap_dss_writeback *wb,
> +		struct omap_dss_writeback_info *wi, u16 *in_width,
> +		u16 *in_height);
>  int dss_wb_simple_check(struct omap_dss_writeback *wb,
>  		const struct omap_dss_writeback_info *info);
>  
> @@ -492,7 +495,8 @@ void dispc_mgr_setup(enum omap_channel channel,
>  
>  bool dispc_wb_go_busy(int id);
>  void dispc_wb_go(int id);
> -int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi);
> +int dispc_wb_setup(int id, struct omap_dss_writeback_info *wi,
> +		u16 in_width, u16 in_height);
>  void dispc_wb_enable(int id, bool enable);
>  void dispc_wb_set_channel_in(int id, enum dss_writeback_channel_in ch_in);
>  
> diff --git a/drivers/video/omap2/dss/writeback.c b/drivers/video/omap2/dss/writeback.c
> index 14103bf..7c4e9c0 100644
> --- a/drivers/video/omap2/dss/writeback.c
> +++ b/drivers/video/omap2/dss/writeback.c
> @@ -141,6 +141,23 @@ enum dss_writeback_channel_in dss_wb_calc_channel_in(struct omap_dss_writeback *
>  	}
>  }
>  
> +void dss_wb_calc_params(struct omap_dss_writeback *wb,
> +		struct omap_dss_writeback_info *wi, u16 *in_width,
> +		u16 *in_height)
> +{
> +	struct omap_video_timings timings;
> +	struct omap_dss_device *dssdev;
> +	struct omap_overlay_manager *mgr;
> +
> +	mgr = wb->dssdev->manager;
> +	dssdev = mgr->get_display(mgr);
> +
> +	dssdev->driver->get_timings(dssdev, &timings);
> +
> +	*in_width = timings.x_res;
> +	*in_height = timings.y_res;
> +}
> +
>  int dss_wb_simple_check(struct omap_dss_writeback *wb,
>  		const struct omap_dss_writeback_info *info)
>  {


-- 
Chandrabhanu Mahapatra
Texas Instruments India Pvt. Ltd.


^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2012-08-02 10:22 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-12-27 12:48 [RFC PATCH 00/29] OMAPDSS: Initial Writeback Capture mode support Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 01/29] omapdss/omapfb/omap_vout: Introduce manager output struct Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 02/29] OMAPDSS: Add writeback to omap_dss_mgr_output Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 03/29] OMAPDSS: Writeback: Add writeback interface and panel driver Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 04/29] OMAPDSS: APPLY/Writeback: Add writeback_info Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 05/29] OMAPDSS: APPLY/Writeback: Apply writeback configurations Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 06/29] OMAPDSS: APPLY: Add writeback enable/disable functions Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 07/29] OMAPDSS: APPLY: Add extra_info for writeback Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 08/29] OMAPDSS: APPLY: Modify manager unset device op Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 09/29] OMAPDSS: APPLY: Allow manager set/unset_device ops to set/unset writeback Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 10/29] OMAPDSS: APPLY: Calculate channel_in for writeback Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 11/29] OMAPDSS: DISPC: Add writeback as a new plane Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 12/29] OMAPDSS: Writeback: Add check for color_mode in dss_wb_simple_check() Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 13/29] OMAPDSS: APPLY: Configure writeback FIFOs Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 14/29] OMAPDSS: DISPC: Allow both upscaling and downscaling of chroma Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 15/29] OMAPDSS: DISPC: Pass overlay caps as a parameter to DISPC overlay related function Archit Taneja
2011-12-27 12:48 ` [RFC PATCH 16/29] OMAPDSS: OVERLAY: Add position and replication as overlay caps Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 17/29] OMAPDSS: DISPC: Make dispc_ovl_setup call dispc_plane_setup Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 18/29] OMAPDSS: DISPC: Make chroma_upscale an argument to dispc_plane_setup Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 19/29] OMAPDSS: DISPC: Don't set chroma resampling bit for writeback Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 20/29] OMAPDSS: Writeback: Add writeback capabilities Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 21/29] OMAPDSS: DISPC: Configure overlay-like parameters in dispc_wb_setup Archit Taneja
2012-08-02 10:22   ` Chandrabhanu Mahapatra
2011-12-27 12:49 ` [RFC PATCH 22/29] OMAPDSS: DISPC: Setup writeback go, enable and channel_in functions Archit Taneja
2012-08-02 10:07   ` Mahapatra, Chandrabhanu
2011-12-27 12:49 ` [RFC PATCH 23/29] OMAPDSS: Writeback: Configure writeback specific parameters Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 24/29] OMAPDSS: Writeback: Use panel driver ops to configure mirroring rotation and buffe Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 25/29] OMAPDSS: Writeback: Add sysfs attributes to writeback panel Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 26/29] OMAPDSS: DISPLAY: Add a manager apply to sysfs store attributes for writeback Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 27/29] OMAPDSS: MANAGER: Split manager_display_store into smaller functions Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 28/29] OMAPDSS: MANAGER: Add writeback as a sysfs attribute Archit Taneja
2011-12-27 12:49 ` [RFC PATCH 29/29] OMAPDSS: FEATURES: Allow WB panels to attach to managers Archit Taneja

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).