tegra_dc_ext_unpin_handles(unpin_handles, nr_unpin);
}
+static void tegra_dc_ext_read_user_data(struct tegra_dc_ext_flip_data *data,
+ struct tegra_dc_ext_flip_user_data *flip_user_data,
+ int nr_user_data)
+{
+ /*Add support for reading user data (HDR data for intance) here*/
+}
+
+
static int tegra_dc_ext_flip(struct tegra_dc_ext_user *user,
struct tegra_dc_ext_flip_windowattr *win,
int win_num,
__u32 *syncpt_id, __u32 *syncpt_val,
- int *syncpt_fd, __u16 *dirty_rect, u8 flip_flags)
+ int *syncpt_fd, __u16 *dirty_rect, u8 flip_flags,
+ struct tegra_dc_ext_flip_user_data *flip_user_data,
+ int nr_user_data)
{
struct tegra_dc_ext *ext = user->ext;
struct tegra_dc_ext_flip_data *data;
goto unlock;
}
+ tegra_dc_ext_read_user_data(data, flip_user_data, nr_user_data);
+
BUG_ON(win_num > DC_N_WINDOWS);
for (i = 0; i < win_num; i++) {
u32 syncpt_max;
ret = tegra_dc_ext_flip(user, args.win,
TEGRA_DC_EXT_FLIP_N_WINDOWS,
&args.post_syncpt_id, &args.post_syncpt_val, NULL,
- NULL, 0);
+ NULL, 0, NULL, 0);
if (copy_to_user(user_arg, &args, sizeof(args)))
return -EFAULT;
ret = tegra_dc_ext_flip(user, win, win_num,
&args.post_syncpt_id, &args.post_syncpt_val, NULL,
- args.dirty_rect, 0);
+ args.dirty_rect, 0, NULL, 0);
if (copy_to_user(compat_ptr(args.win), win,
sizeof(*win) * win_num) ||
ret = tegra_dc_ext_flip(user, win, win_num,
&args.post_syncpt_id, &args.post_syncpt_val, NULL,
- args.dirty_rect, 0);
+ args.dirty_rect, 0, NULL, 0);
if (copy_to_user(args.win, win, sizeof(*win) * win_num) ||
copy_to_user(user_arg, &args, sizeof(args))) {
ret = tegra_dc_ext_flip(user, win, win_num,
NULL, NULL, &args.post_syncpt_fd, args.dirty_rect,
- args.flags);
+ args.flags, NULL, 0);
if (copy_to_user((void __user *)(uintptr_t)args.win, win,
sizeof(*win) * win_num) ||
kfree(win);
return ret;
}
+ case TEGRA_DC_EXT_FLIP4:
+ {
+ int ret;
+ int win_num;
+ int nr_user_data;
+ struct tegra_dc_ext_flip_4 args;
+ struct tegra_dc_ext_flip_windowattr *win;
+ struct tegra_dc_ext_flip_user_data *flip_user_data;
+ bool bypass;
+
+ if (copy_from_user(&args, user_arg, sizeof(args)))
+ return -EFAULT;
+
+ bypass = !!(args.flags & TEGRA_DC_EXT_FLIP_HEAD_FLAG_YUVBYPASS);
+
+ if (!!(user->ext->dc->mode.vmode & FB_VMODE_YUV_MASK) !=
+ bypass)
+ return -EINVAL;
+
+ user->ext->dc->yuv_bypass = bypass;
+ win_num = args.win_num;
+ win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
+
+ if (copy_from_user(win, (void __user *) (uintptr_t)args.win,
+ sizeof(*win) * win_num)) {
+ kfree(win);
+ return -EFAULT;
+ }
+
+ nr_user_data = args.nr_elements;
+ flip_user_data = kzalloc(sizeof(*flip_user_data)
+ * nr_user_data, GFP_KERNEL);
+ if (nr_user_data > 0) {
+ if (copy_from_user(flip_user_data,
+ (void __user *) (uintptr_t)args.data,
+ sizeof(*flip_user_data) * nr_user_data)) {
+ kfree(win);
+ return -EFAULT;
+ }
+ }
+ ret = tegra_dc_ext_flip(user, win, win_num,
+ NULL, NULL, &args.post_syncpt_fd, args.dirty_rect,
+ args.flags, flip_user_data, nr_user_data);
+
+ if (nr_user_data > 0)
+ kfree(flip_user_data);
+
+ if (copy_to_user((void __user *)(uintptr_t)args.win, win,
+ sizeof(*win) * win_num) ||
+ copy_to_user(user_arg, &args, sizeof(args))) {
+ kfree(win);
+ return -EFAULT;
+ }
+
+ kfree(win);
+ return ret;
+ }
+
#ifdef CONFIG_TEGRA_ISOMGR
#ifdef CONFIG_COMPAT
case TEGRA_DC_EXT_SET_PROPOSED_BW32:
__u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */
};
+/* size of the this sturct is 32 bytes */
+struct tegra_dc_ext_flip_user_data {
+ __u8 data_type;
+ __u8 reserved0;
+ __u16 flags;
+ __u16 reserved1;
+ union { /* data to be packed into 26 bytes */
+ __u8 data8[26];
+ __u16 data16[13];
+ /*Add HDR data struct here*/
+ };
+};
+
+/*
+ *tegra_dc_flip_4 : Incorporates a new pointer to an array of 32 bytes of data
+ *to pass head specific info. The new nr_elements carries the number of such
+ *elements. Everything else remains the same as in tegra_dc_ext_flip_3
+ */
+struct tegra_dc_ext_flip_4 {
+ __u64 __user win;
+ __u8 win_num;
+ __u8 flags;
+ __u16 reserved2; /* unused - must be 0 */
+ __s32 post_syncpt_fd;
+ __u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */
+ __u32 nr_elements; /* number of data entities pointed to by data */
+ __u64 __user data; /* pointer to struct tegra_dc_ext_flip_user_data*/
+};
+
/*
* vblank control - enable or disable vblank events
*/
#define TEGRA_DC_EXT_GET_CMU_ADBRGB\
_IOR('D', 0x1C, struct tegra_dc_ext_cmu)
+#define TEGRA_DC_EXT_FLIP4\
+ _IOW('D', 0x1D, struct tegra_dc_ext_flip_4)
+
enum tegra_dc_ext_control_output_type {
TEGRA_DC_EXT_DSI,
TEGRA_DC_EXT_LVDS,