/*
* drivers/video/tegra/dc/dc_config.c
*
- * Copyright (c) 2012-2013, NVIDIA CORPORATION, All rights reserved.
+ * Copyright (c) 2012-2014, NVIDIA CORPORATION, All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
return -EINVAL;
}
-long *tegra_dc_parse_feature(struct tegra_dc *dc, int win_idx, int operation)
+u32 *tegra_dc_parse_feature(struct tegra_dc *dc, int win_idx, int operation)
{
int idx;
struct tegra_dc_feature_entry *entry;
int tegra_dc_feature_has_scaling(struct tegra_dc *dc, int win_idx)
{
int i;
- long *addr = tegra_dc_parse_feature(dc, win_idx, HAS_SCALE);
+ u32 *addr = tegra_dc_parse_feature(dc, win_idx, HAS_SCALE);
if (WARN_ONCE(!addr, "window does not exist"))
return 0;
int tegra_dc_feature_has_tiling(struct tegra_dc *dc, int win_idx)
{
- long *addr = tegra_dc_parse_feature(dc, win_idx, HAS_TILED);
+ u32 *addr = tegra_dc_parse_feature(dc, win_idx, HAS_TILED);
if (WARN_ONCE(!addr, "window does not exist"))
return 0;
int tegra_dc_feature_has_blocklinear(struct tegra_dc *dc, int win_idx)
{
- long *addr = tegra_dc_parse_feature(dc, win_idx, HAS_BLOCKLINEAR);
+ u32 *addr = tegra_dc_parse_feature(dc, win_idx, HAS_BLOCKLINEAR);
if (WARN_ONCE(!addr, "window does not exist"))
return 0;
int tegra_dc_feature_has_interlace(struct tegra_dc *dc, int win_idx)
{
- long *addr = tegra_dc_parse_feature(dc, win_idx, HAS_INTERLACE);
+ u32 *addr = tegra_dc_parse_feature(dc, win_idx, HAS_INTERLACE);
if (WARN_ONCE(!addr, "window does not exist"))
return 0;
int tegra_dc_feature_has_filter(struct tegra_dc *dc, int win_idx, int operation)
{
- long *addr = tegra_dc_parse_feature(dc, win_idx, operation);
+ u32 *addr = tegra_dc_parse_feature(dc, win_idx, operation);
if (WARN_ONCE(!addr, "window does not exist"))
return 0;
int tegra_dc_feature_is_gen2_blender(struct tegra_dc *dc, int win_idx)
{
- long *addr = tegra_dc_parse_feature(dc, win_idx, HAS_GEN2_BLEND);
+ u32 *addr = tegra_dc_parse_feature(dc, win_idx, HAS_GEN2_BLEND);
if (WARN_ONCE(!addr, "window does not exist"))
return 0;
#include "../../../staging/android/sync.h"
#endif
+#ifdef CONFIG_COMPAT
+/* compat versions that happen to be the same size as the uapi version. */
+
+struct tegra_dc_ext_lut32 {
+ __u32 win_index; /* window index to set lut for */
+ __u32 flags; /* Flag bitmask, see TEGRA_DC_EXT_LUT_FLAGS_* */
+ __u32 start; /* start index to update lut from */
+ __u32 len; /* number of valid lut entries */
+ __u32 r; /* array of 16-bit red values, 0 to reset */
+ __u32 g; /* array of 16-bit green values, 0 to reset */
+ __u32 b; /* array of 16-bit blue values, 0 to reset */
+};
+
+#define TEGRA_DC_EXT_SET_LUT32 \
+ _IOW('D', 0x0A, struct tegra_dc_ext_lut32)
+
+struct tegra_dc_ext_feature32 {
+ __u32 length;
+ __u32 entries; /* pointer to array of 32-bit entries */
+};
+
+#define TEGRA_DC_EXT_GET_FEATURES32 \
+ _IOW('D', 0x0B, struct tegra_dc_ext_feature32)
+
+struct tegra_dc_ext_flip_2_32 {
+ __u32 win; /* struct tegra_dc_ext_flip_windowattr* */
+ __u8 win_num;
+ __u8 reserved1; /* unused - must be 0 */
+ __u16 reserved2; /* unused - must be 0 */
+ __u32 post_syncpt_id;
+ __u32 post_syncpt_val;
+ __u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */
+};
+
+#define TEGRA_DC_EXT_FLIP2_32 \
+ _IOWR('D', 0x0E, struct tegra_dc_ext_flip_2_32)
+
+#define TEGRA_DC_EXT_SET_PROPOSED_BW32 \
+ _IOR('D', 0x13, struct tegra_dc_ext_flip_2_32)
+
+#endif
+
int tegra_dc_ext_devno;
struct class *tegra_dc_ext_class;
static int head_count;
int act_window_num;
};
+static inline s64 tegra_timespec_to_ns(const struct tegra_timespec *ts)
+{
+ return ((s64) ts->tv_sec * NSEC_PER_SEC) + ts->tv_nsec;
+}
+
+static inline int test_bit_u32(int nr, const u32 *addr)
+{
+ return 1UL & (addr[BIT_WORD(nr)] >> (nr & (BITS_PER_LONG-1)));
+}
+
int tegra_dc_ext_get_num_outputs(void)
{
/* TODO: decouple output count from head count */
int tegra_dc_ext_check_windowattr(struct tegra_dc_ext *ext,
struct tegra_dc_win *win)
{
- long *addr;
+ u32 *addr;
struct tegra_dc *dc = ext->dc;
addr = tegra_dc_parse_feature(dc, win->idx, GET_WIN_FORMATS);
goto fail;
}
/* Check the window format */
- if (!test_bit(win->fmt, addr)) {
+ if (!test_bit_u32(win->fmt, addr)) {
dev_err(&dc->ndev->dev,
"Color format of window %d is invalid.\n", win->idx);
goto fail;
return err;
if (tegra_platform_is_silicon()) {
- timestamp_ns = timespec_to_ns(&flip_win->attr.timestamp);
+ timestamp_ns = tegra_timespec_to_ns(&flip_win->attr.timestamp);
if (timestamp_ns) {
/* XXX: Should timestamping be overridden by "no_vsync"
dev_err(&win->dc->ndev->dev,
"work queue did NOT dequeue head!!!");
else
- head_timestamp =
- timespec_to_ns(&flip_win->attr.timestamp);
+ head_timestamp = tegra_timespec_to_ns(
+ &flip_win->attr.timestamp);
} else {
- s64 timestamp =
- timespec_to_ns(&temp->win[i].attr.timestamp);
+ s64 timestamp = tegra_timespec_to_ns(
+ &temp->win[i].attr.timestamp);
skip_flip = !tegra_dc_does_vsync_separate(ext->dc,
timestamp, head_timestamp);
int index = wins[i].index;
memcpy(&flip_win->attr, &wins[i], sizeof(flip_win->attr));
- if (has_timestamp && timespec_to_ns(&flip_win->attr.timestamp))
+ if (has_timestamp && tegra_timespec_to_ns(
+ &flip_win->attr.timestamp))
*has_timestamp = true;
if (index < 0 || !test_bit(index, &dc->valid_windows))
return ret;
}
+#ifdef CONFIG_COMPAT
+ case TEGRA_DC_EXT_FLIP2_32:
+ {
+ int ret;
+ int win_num;
+ struct tegra_dc_ext_flip_2_32 args;
+ struct tegra_dc_ext_flip_windowattr *win;
+
+ if (copy_from_user(&args, user_arg, sizeof(args)))
+ return -EFAULT;
+
+ win_num = args.win_num;
+ win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
+
+ if (copy_from_user(win, compat_ptr(args.win),
+ sizeof(*win) * win_num)) {
+ kfree(win);
+ return -EFAULT;
+ }
+
+ ret = tegra_dc_ext_flip(user, win, win_num,
+ &args.post_syncpt_id, &args.post_syncpt_val, NULL);
+
+ if (copy_to_user(compat_ptr(args.win), win,
+ sizeof(*win) * win_num) ||
+ copy_to_user(user_arg, &args, sizeof(args))) {
+ kfree(win);
+ return -EFAULT;
+ }
+
+ kfree(win);
+ return ret;
+ }
+
+#endif
case TEGRA_DC_EXT_FLIP2:
{
int ret;
return ret;
}
#ifdef CONFIG_TEGRA_ISOMGR
+#ifdef CONFIG_COMPAT
+ case TEGRA_DC_EXT_SET_PROPOSED_BW32:
+ {
+ int ret;
+ int win_num;
+ struct tegra_dc_ext_flip_2_32 args;
+ struct tegra_dc_ext_flip_windowattr *win;
+
+ if (copy_from_user(&args, user_arg, sizeof(args)))
+ return -EFAULT;
+
+ win_num = args.win_num;
+ win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
+
+ if (copy_from_user(win, compat_ptr(args.win),
+ sizeof(*win) * win_num)) {
+ kfree(win);
+ return -EFAULT;
+ }
+
+ ret = tegra_dc_ext_negotiate_bw(user, win, win_num);
+
+ kfree(win);
+
+ return ret;
+ }
+#endif
case TEGRA_DC_EXT_SET_PROPOSED_BW:
{
int ret;
win_num = args.win_num;
win = kzalloc(sizeof(*win) * win_num, GFP_KERNEL);
- if (copy_from_user(win, (void *)(uintptr_t)args.win,
- sizeof(*win) * win_num)) {
+ if (copy_from_user(win, args.win, sizeof(*win) * win_num)) {
kfree(win);
return -EFAULT;
}
return ret;
}
+#ifdef CONFIG_COMPAT
+ case TEGRA_DC_EXT_SET_LUT32:
+ {
+ struct tegra_dc_ext_lut32 args;
+ struct tegra_dc_ext_lut tmp;
+
+ if (copy_from_user(&args, user_arg, sizeof(args)))
+ return -EFAULT;
+
+ /* translate 32-bit version to 64-bit */
+ tmp.win_index = args.win_index;
+ tmp.flags = args.flags;
+ tmp.start = args.start;
+ tmp.len = args.len;
+ tmp.r = compat_ptr(args.r);
+ tmp.g = compat_ptr(args.g);
+ tmp.b = compat_ptr(args.b);
+
+ return tegra_dc_ext_set_lut(user, &tmp);
+ }
+#endif
case TEGRA_DC_EXT_SET_LUT:
{
struct tegra_dc_ext_lut args;
return tegra_dc_ext_set_lut(user, &args);
}
+#ifdef CONFIG_COMPAT
+ case TEGRA_DC_EXT_GET_FEATURES32:
+ {
+ struct tegra_dc_ext_feature32 args;
+ struct tegra_dc_ext_feature tmp;
+ int ret;
+
+ if (copy_from_user(&args, user_arg, sizeof(args)))
+ return -EFAULT;
+
+ /* convert 32-bit to 64-bit version */
+ tmp.length = args.length;
+ tmp.entries = compat_ptr(args.entries);
+
+ ret = tegra_dc_ext_get_feature(user, &tmp);
+
+ /* convert back to 32-bit version, tmp.entries not modified */
+ args.length = tmp.length;
+
+ if (copy_to_user(user_arg, &args, sizeof(args)))
+ return -EFAULT;
+
+ return ret;
+ }
+#endif
case TEGRA_DC_EXT_GET_FEATURES:
{
struct tegra_dc_ext_feature args;
.release = tegra_dc_release,
.unlocked_ioctl = tegra_dc_ioctl,
#ifdef CONFIG_COMPAT
- .compat_ioctl = tegra_dc_ioctl,
+ .compat_ioctl = tegra_dc_ioctl,
#endif
};
/*
- * Copyright (C) 2011-2013, NVIDIA Corporation. All rights reserved.
+ * Copyright (C) 2011-2014, NVIDIA Corporation. All rights reserved.
*
* Author: Robert Morell <rmorell@nvidia.com>
* Some code based on fbdev extensions written by:
#define TEGRA_DC_EXT_FLIP_FLAG_SCAN_COLUMN (1 << 6)
#define TEGRA_DC_EXT_FLIP_FLAG_INTERLACE (1 << 7)
+struct tegra_timespec {
+ __s32 tv_sec; /* seconds */
+ __s32 tv_nsec; /* nanoseconds */
+};
+
struct tegra_dc_ext_flip_windowattr {
__s32 index;
__u32 buff_id;
__u32 out_h;
__u32 z;
__u32 swap_interval;
- struct timespec timestamp;
+ struct tegra_timespec timestamp;
union {
struct {
__u32 pre_syncpt_id;
__u32 pre_syncpt_val;
};
- int pre_syncpt_fd;
+ __s32 pre_syncpt_fd;
};
/* These two are optional; if zero, U and V are taken from buff_id */
__u32 buff_id_u;
};
struct tegra_dc_ext_flip_3 {
- __u64 win; /* window attributes stored as __u64 for portability. */
+ __u64 win; /* pointer: struct tegra_dc_ext_flip_windowattr* */
__u8 win_num;
__u8 reserved1; /* unused - must be 0 */
__u16 reserved2; /* unused - must be 0 */
- int post_syncpt_fd;
+ __s32 post_syncpt_fd;
__u16 dirty_rect[4]; /* x,y,w,h for partial screen update. 0 ignores */
};
#define TEGRA_DC_EXT_GET_CUSTOM_CMU \
_IOR('D', 0x10, struct tegra_dc_ext_cmu)
+/* obsolete - do not use */
#define TEGRA_DC_EXT_SET_CURSOR_IMAGE_LOW_LATENCY \
_IOW('D', 0x11, struct tegra_dc_ext_cursor_image)
+/* obsolete - do not use */
#define TEGRA_DC_EXT_SET_CURSOR_LOW_LATENCY \
_IOW('D', 0x12, struct tegra_dc_ext_cursor_image)
struct tegra_dc_ext_event {
__u32 type;
- ssize_t data_size;
+ __u32 data_size;
char data[0];
};