|
@@ -146,6 +146,8 @@ struct ps3fb_par {
|
|
|
};
|
|
|
|
|
|
|
|
|
+#define FIRST_NATIVE_MODE_INDEX 10
|
|
|
+
|
|
|
static const struct fb_videomode ps3fb_modedb[] = {
|
|
|
/* 60 Hz broadcast modes (modes "1" to "5") */
|
|
|
{
|
|
@@ -193,24 +195,7 @@ static const struct fb_videomode ps3fb_modedb[] = {
|
|
|
FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
|
|
|
},
|
|
|
|
|
|
- /* VESA modes (modes "11" to "13") */
|
|
|
- {
|
|
|
- /* WXGA */
|
|
|
- "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6,
|
|
|
- 0, FB_VMODE_NONINTERLACED,
|
|
|
- FB_MODE_IS_VESA
|
|
|
- }, {
|
|
|
- /* SXGA */
|
|
|
- "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
|
|
|
- FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED,
|
|
|
- FB_MODE_IS_VESA
|
|
|
- }, {
|
|
|
- /* WUXGA */
|
|
|
- "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6,
|
|
|
- FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED,
|
|
|
- FB_MODE_IS_VESA
|
|
|
- },
|
|
|
-
|
|
|
+ [FIRST_NATIVE_MODE_INDEX] =
|
|
|
/* 60 Hz broadcast modes (full resolution versions of modes "1" to "5") */
|
|
|
{
|
|
|
/* 480if */
|
|
@@ -255,6 +240,24 @@ static const struct fb_videomode ps3fb_modedb[] = {
|
|
|
/* 1080pf */
|
|
|
"1080pf", 50, 1920, 1080, 6734, 148, 484, 36, 4, 88, 5,
|
|
|
FB_SYNC_BROADCAST, FB_VMODE_NONINTERLACED
|
|
|
+ },
|
|
|
+
|
|
|
+ /* VESA modes (modes "11" to "13") */
|
|
|
+ {
|
|
|
+ /* WXGA */
|
|
|
+ "wxga", 60, 1280, 768, 12924, 160, 24, 29, 3, 136, 6,
|
|
|
+ 0, FB_VMODE_NONINTERLACED,
|
|
|
+ FB_MODE_IS_VESA
|
|
|
+ }, {
|
|
|
+ /* SXGA */
|
|
|
+ "sxga", 60, 1280, 1024, 9259, 248, 48, 38, 1, 112, 3,
|
|
|
+ FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED,
|
|
|
+ FB_MODE_IS_VESA
|
|
|
+ }, {
|
|
|
+ /* WUXGA */
|
|
|
+ "wuxga", 60, 1920, 1200, 6494, 80, 48, 26, 3, 32, 6,
|
|
|
+ FB_SYNC_HOR_HIGH_ACT, FB_VMODE_NONINTERLACED,
|
|
|
+ FB_MODE_IS_VESA
|
|
|
}
|
|
|
};
|
|
|
|
|
@@ -298,20 +301,43 @@ static int ps3fb_cmp_mode(const struct fb_videomode *vmode,
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
+static const struct fb_videomode *ps3fb_native_vmode(enum ps3av_mode_num id)
|
|
|
+{
|
|
|
+ return &ps3fb_modedb[FIRST_NATIVE_MODE_INDEX + id - 1];
|
|
|
+}
|
|
|
+
|
|
|
+static const struct fb_videomode *ps3fb_vmode(int id)
|
|
|
+{
|
|
|
+ u32 mode = id & PS3AV_MODE_MASK;
|
|
|
+
|
|
|
+ if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA)
|
|
|
+ return NULL;
|
|
|
+
|
|
|
+ if (mode <= PS3AV_MODE_1080P50 && !(id & PS3AV_MODE_FULL)) {
|
|
|
+ /* Non-fullscreen broadcast mode */
|
|
|
+ return &ps3fb_modedb[mode - 1];
|
|
|
+ }
|
|
|
+
|
|
|
+ return ps3fb_native_vmode(mode);
|
|
|
+}
|
|
|
+
|
|
|
static unsigned int ps3fb_find_mode(struct fb_var_screeninfo *var,
|
|
|
u32 *ddr_line_length, u32 *xdr_line_length)
|
|
|
{
|
|
|
- unsigned int i, mode;
|
|
|
+ unsigned int id;
|
|
|
+ const struct fb_videomode *vmode;
|
|
|
|
|
|
- for (i = PS3AV_MODE_1080P50; i < ARRAY_SIZE(ps3fb_modedb); i++)
|
|
|
- if (!ps3fb_cmp_mode(&ps3fb_modedb[i], var))
|
|
|
+ for (id = PS3AV_MODE_480I; id <= PS3AV_MODE_WUXGA; id++) {
|
|
|
+ vmode = ps3fb_native_vmode(id);
|
|
|
+ if (!ps3fb_cmp_mode(vmode, var))
|
|
|
goto found;
|
|
|
+ }
|
|
|
|
|
|
- pr_debug("ps3fb_find_mode: mode not found\n");
|
|
|
+ pr_debug("%s: mode not found\n", __func__);
|
|
|
return 0;
|
|
|
|
|
|
found:
|
|
|
- *ddr_line_length = ps3fb_modedb[i].xres * BPP;
|
|
|
+ *ddr_line_length = vmode->xres * BPP;
|
|
|
|
|
|
if (!var->xres) {
|
|
|
var->xres = 1;
|
|
@@ -330,36 +356,14 @@ found:
|
|
|
} else
|
|
|
*xdr_line_length = *ddr_line_length;
|
|
|
|
|
|
- mode = i+1;
|
|
|
- if (mode > PS3AV_MODE_WUXGA) {
|
|
|
- mode -= PS3AV_MODE_WUXGA;
|
|
|
+ if (vmode->sync & FB_SYNC_BROADCAST) {
|
|
|
/* Full broadcast modes have the full mode bit set */
|
|
|
- if (ps3fb_modedb[i].xres == var->xres &&
|
|
|
- ps3fb_modedb[i].yres == var->yres)
|
|
|
- mode |= PS3AV_MODE_FULL;
|
|
|
- }
|
|
|
-
|
|
|
- pr_debug("ps3fb_find_mode: mode %u\n", mode);
|
|
|
-
|
|
|
- return mode;
|
|
|
-}
|
|
|
-
|
|
|
-static const struct fb_videomode *ps3fb_default_mode(int id)
|
|
|
-{
|
|
|
- u32 mode = id & PS3AV_MODE_MASK;
|
|
|
- u32 flags;
|
|
|
-
|
|
|
- if (mode < PS3AV_MODE_480I || mode > PS3AV_MODE_WUXGA)
|
|
|
- return NULL;
|
|
|
-
|
|
|
- flags = id & ~PS3AV_MODE_MASK;
|
|
|
-
|
|
|
- if (mode <= PS3AV_MODE_1080P50 && flags & PS3AV_MODE_FULL) {
|
|
|
- /* Full broadcast mode */
|
|
|
- return &ps3fb_modedb[mode + PS3AV_MODE_WUXGA - 1];
|
|
|
+ if (vmode->xres == var->xres && vmode->yres == var->yres)
|
|
|
+ id |= PS3AV_MODE_FULL;
|
|
|
}
|
|
|
|
|
|
- return &ps3fb_modedb[mode - 1];
|
|
|
+ pr_debug("%s: mode %u\n", __func__, id);
|
|
|
+ return id;
|
|
|
}
|
|
|
|
|
|
static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
|
|
@@ -553,7 +557,7 @@ static int ps3fb_set_par(struct fb_info *info)
|
|
|
if (!mode)
|
|
|
return -EINVAL;
|
|
|
|
|
|
- vmode = ps3fb_default_mode(mode | PS3AV_MODE_FULL);
|
|
|
+ vmode = ps3fb_native_vmode(mode & PS3AV_MODE_MASK);
|
|
|
|
|
|
info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
|
|
|
info->fix.smem_len = ps3fb.xdr_size;
|
|
@@ -767,7 +771,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
|
|
|
case PS3FB_IOCTL_SETMODE:
|
|
|
{
|
|
|
struct ps3fb_par *par = info->par;
|
|
|
- const struct fb_videomode *mode;
|
|
|
+ const struct fb_videomode *vmode;
|
|
|
struct fb_var_screeninfo var;
|
|
|
|
|
|
if (copy_from_user(&val, argp, sizeof(val)))
|
|
@@ -780,10 +784,10 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
|
|
|
}
|
|
|
dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val);
|
|
|
retval = -EINVAL;
|
|
|
- mode = ps3fb_default_mode(val);
|
|
|
- if (mode) {
|
|
|
+ vmode = ps3fb_vmode(val);
|
|
|
+ if (vmode) {
|
|
|
var = info->var;
|
|
|
- fb_videomode_to_var(&var, mode);
|
|
|
+ fb_videomode_to_var(&var, vmode);
|
|
|
acquire_console_sem();
|
|
|
info->flags |= FBINFO_MISC_USEREVENT;
|
|
|
/* Force, in case only special bits changed */
|
|
@@ -1141,7 +1145,7 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
|
|
|
|
|
|
if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
|
|
|
ARRAY_SIZE(ps3fb_modedb),
|
|
|
- ps3fb_default_mode(par->new_mode_id), 32)) {
|
|
|
+ ps3fb_vmode(par->new_mode_id), 32)) {
|
|
|
retval = -EINVAL;
|
|
|
goto err_fb_dealloc;
|
|
|
}
|