diff mbox

[1/2] OMAP: DSS2: OMAPFB: implement OMAPFB_RESERVE_BUFFER

Message ID 1265297486-22438-1-git-send-email-tomi.valkeinen@nokia.com (mailing list archive)
State Not Applicable, archived
Delegated to: Tomi Valkeinen
Headers show

Commit Message

Tomi Valkeinen Feb. 4, 2010, 3:31 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
index 4c4bafd..5562a76 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
@@ -155,6 +155,47 @@  static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
 	return 0;
 }
 
+static int omapfb_reserve_buffer(struct fb_info *fbi,
+		struct omapfb_res_buf_info *bi)
+{
+	struct omapfb_info *ofbi = FB2OFB(fbi);
+	struct omapfb2_device *fbdev = ofbi->fbdev;
+	struct omapfb2_mem_region *rg;
+	int r, i;
+	size_t size;
+	unsigned w = bi->width;
+	unsigned h = bi->height;
+
+	if (bi->type > OMAPFB_MEMTYPE_MAX)
+		return -EINVAL;
+
+	if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB) {
+		size = max(omap_vrfb_min_phys_size(w, h, bi->bytespp),
+				omap_vrfb_min_phys_size(h, w, bi->bytespp));
+	} else {
+		size = w * h * bi->bytespp;
+	}
+
+	size = PAGE_ALIGN(size);
+
+	rg = &ofbi->region;
+
+	for (i = 0; i < ofbi->num_overlays; i++) {
+		if (ofbi->overlays[i]->info.enabled)
+			return -EBUSY;
+	}
+
+	if (rg->size != size || rg->type != bi->type) {
+		r = omapfb_realloc_fbmem(fbi, size, bi->type);
+		if (r) {
+			dev_err(fbdev->dev, "realloc fbmem failed\n");
+			return r;
+		}
+	}
+
+	return 0;
+}
+
 static int omapfb_update_window_nolock(struct fb_info *fbi,
 		u32 x, u32 y, u32 w, u32 h)
 {
@@ -476,6 +517,7 @@  int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
 		struct omapfb_plane_info	plane_info;
 		struct omapfb_caps		caps;
 		struct omapfb_mem_info          mem_info;
+		struct omapfb_res_buf_info	res_buf_info;
 		struct omapfb_color_key		color_key;
 		struct omapfb_ovl_colormode	ovl_colormode;
 		enum omapfb_update_mode		update_mode;
@@ -572,6 +614,15 @@  int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
 			r = -EFAULT;
 		break;
 
+	case OMAPFB_RESERVE_BUFFER:
+		DBG("ioctl RESERVE_BUFFER\n");
+		if (copy_from_user(&p.res_buf_info, (void __user *)arg,
+					sizeof(p.res_buf_info)))
+			r = -EFAULT;
+		else
+			r = omapfb_reserve_buffer(fbi, &p.res_buf_info);
+		break;
+
 	case OMAPFB_GET_CAPS:
 		DBG("ioctl GET_CAPS\n");
 		if (!display) {
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
index 62bb88f..9cd7957 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
@@ -413,8 +413,19 @@  static ssize_t store_size(struct device *dev, struct device_attribute *attr,
 	unsigned long size;
 	int r;
 	int i;
+	unsigned w, h, bytespp;
+
+	if (sscanf(buf, "%u,%u,%u", &w, &h, &bytespp) == 3) {
+		if (ofbi->rotation_type == OMAP_DSS_ROT_VRFB)
+			size = max(omap_vrfb_min_phys_size(w, h, bytespp),
+					omap_vrfb_min_phys_size(h, w, bytespp));
+		else
+			size = w * h * bytespp;
+	} else {
+		size = simple_strtoul(buf, NULL, 0);
+	}
 
-	size = PAGE_ALIGN(simple_strtoul(buf, NULL, 0));
+	size = PAGE_ALIGN(size);
 
 	lock_fb_info(fbi);
 
diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
index f46c40a..ef4c2cf 100644
--- a/include/linux/omapfb.h
+++ b/include/linux/omapfb.h
@@ -57,6 +57,7 @@ 
 #define OMAPFB_WAITFORGO	OMAP_IO(60)
 #define OMAPFB_GET_VRAM_INFO	OMAP_IOR(61, struct omapfb_vram_info)
 #define OMAPFB_SET_TEARSYNC	OMAP_IOW(62, struct omapfb_tearsync_info)
+#define OMAPFB_RESERVE_BUFFER	OMAP_IOW(63, struct omapfb_res_buf_info)
 
 #define OMAPFB_CAPS_GENERIC_MASK	0x00000fff
 #define OMAPFB_CAPS_LCDC_MASK		0x00fff000
@@ -147,6 +148,15 @@  struct omapfb_mem_info {
 	__u8  reserved[3];
 };
 
+struct omapfb_res_buf_info {
+	__u16	width;
+	__u16	height;
+	__u8	bytespp;
+	__u8	type;
+	__u8	reserved[2];
+	__u32	reserved2[6];
+};
+
 struct omapfb_caps {
 	__u32 ctrl;
 	__u32 plane_color;