Commit fd562112 authored by Geert Uytterhoeven's avatar Geert Uytterhoeven Committed by Linus Torvalds

ps3av: add autodetection for VESA modes

add autodetection for VESA modes
Signed-off-by: default avatarGeert Uytterhoeven <Geert.Uytterhoeven@sonycom.com>
Signed-off-by: default avatarAntonino Daplas <adaplas@gmail.com>
Signed-off-by: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent 101aa56d
...@@ -585,54 +585,73 @@ static void ps3avd(struct work_struct *work) ...@@ -585,54 +585,73 @@ static void ps3avd(struct work_struct *work)
complete(&ps3av->done); complete(&ps3av->done);
} }
static int ps3av_resbit2id(u32 res_50, u32 res_60) #define SHIFT_50 0
#define SHIFT_60 4
#define SHIFT_VESA 8
static const struct {
unsigned mask : 19;
unsigned id : 4;
} ps3av_preferred_modes[] = {
{ .mask = PS3AV_RESBIT_WUXGA << SHIFT_VESA, .id = 13 },
{ .mask = PS3AV_RESBIT_1920x1080P << SHIFT_60, .id = 5 },
{ .mask = PS3AV_RESBIT_1920x1080P << SHIFT_50, .id = 10 },
{ .mask = PS3AV_RESBIT_1920x1080I << SHIFT_60, .id = 4 },
{ .mask = PS3AV_RESBIT_1920x1080I << SHIFT_50, .id = 9 },
{ .mask = PS3AV_RESBIT_SXGA << SHIFT_VESA, .id = 12 },
{ .mask = PS3AV_RESBIT_WXGA << SHIFT_VESA, .id = 11 },
{ .mask = PS3AV_RESBIT_1280x720P << SHIFT_60, .id = 3 },
{ .mask = PS3AV_RESBIT_1280x720P << SHIFT_50, .id = 8 },
{ .mask = PS3AV_RESBIT_720x480P << SHIFT_60, .id = 2 },
{ .mask = PS3AV_RESBIT_720x576P << SHIFT_50, .id = 7 },
};
static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa)
{ {
int id = 0; unsigned int i;
u32 res_all;
if (res_50 > res_60) { /* if res_50 == res_60, res_60 will be used */
if (res_50 & PS3AV_RESBIT_1920x1080P) /*
id = 10; * We mask off the resolution bits we care about and combine the
else if (res_50 & PS3AV_RESBIT_1920x1080I) * results in one bitfield, so make sure there's no overlap
id = 9; */
else if (res_50 & PS3AV_RESBIT_1280x720P) BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
id = 8; PS3AV_RES_MASK_60 << SHIFT_60);
else if (res_50 & PS3AV_RESBIT_720x576P) BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
id = 7; PS3AV_RES_MASK_VESA << SHIFT_VESA);
else BUILD_BUG_ON(PS3AV_RES_MASK_60 << SHIFT_60 &
id = 0; PS3AV_RES_MASK_VESA << SHIFT_VESA);
} else { res_all = (res_50 & PS3AV_RES_MASK_50) << SHIFT_50 |
if (res_60 & PS3AV_RESBIT_1920x1080P) (res_60 & PS3AV_RES_MASK_60) << SHIFT_60 |
id = 5; (res_vesa & PS3AV_RES_MASK_VESA) << SHIFT_VESA;
else if (res_60 & PS3AV_RESBIT_1920x1080I)
id = 4; if (!res_all)
else if (res_60 & PS3AV_RESBIT_1280x720P) return 0;
id = 3;
else if (res_60 & PS3AV_RESBIT_720x480P) for (i = 0; i < ARRAY_SIZE(ps3av_preferred_modes); i++)
id = 2; if (res_all & ps3av_preferred_modes[i].mask)
else return ps3av_preferred_modes[i].id;
id = 0;
} return 0;
return id;
} }
static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info) static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
{ {
u32 res_50, res_60;
int id; int id;
/* check native resolution */ /* check native resolution */
res_50 = info->res_50.native & PS3AV_RES_MASK_50; id = ps3av_resbit2id(info->res_50.native, info->res_60.native,
res_60 = info->res_60.native & PS3AV_RES_MASK_60; info->res_vesa.native);
if (res_50 || res_60) { if (id) {
id = ps3av_resbit2id(res_50, res_60); pr_debug("%s: Using native mode %d\n", __func__, id);
return id; return id;
} }
/* check resolution */ /* check supported resolutions */
res_50 = info->res_50.res_bits & PS3AV_RES_MASK_50; id = ps3av_resbit2id(info->res_50.res_bits, info->res_60.res_bits,
res_60 = info->res_60.res_bits & PS3AV_RES_MASK_60; info->res_vesa.res_bits);
if (res_50 || res_60) { if (id) {
id = ps3av_resbit2id(res_50, res_60); pr_debug("%s: Using supported mode %d\n", __func__, id);
return id; return id;
} }
...@@ -640,6 +659,7 @@ static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info) ...@@ -640,6 +659,7 @@ static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60; id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
else else
id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50; id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50;
pr_debug("%s: Using default mode %d\n", __func__, id);
return id; return id;
} }
...@@ -737,6 +757,7 @@ static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf, ...@@ -737,6 +757,7 @@ static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf,
id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50; id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50;
if (ps3av->region & PS3AV_REGION_RGB) if (ps3av->region & PS3AV_REGION_RGB)
rgb = PS3AV_MODE_RGB; rgb = PS3AV_MODE_RGB;
pr_debug("%s: Using avmulti mode %d\n", __func__, id);
} else if (boot) { } else if (boot) {
/* HDMI: using DEFAULT HDMI_MODE_ID while booting up */ /* HDMI: using DEFAULT HDMI_MODE_ID while booting up */
info = &monitor_info.info; info = &monitor_info.info;
......
...@@ -283,7 +283,7 @@ ...@@ -283,7 +283,7 @@
#define PS3AV_CMD_VIDEO_CS_YUV422 0x0002 #define PS3AV_CMD_VIDEO_CS_YUV422 0x0002
#define PS3AV_CMD_VIDEO_CS_YUV444 0x0003 #define PS3AV_CMD_VIDEO_CS_YUV444 0x0003
/* for automode */ /* for broadcast automode */
#define PS3AV_RESBIT_720x480P 0x0003 /* 0x0001 | 0x0002 */ #define PS3AV_RESBIT_720x480P 0x0003 /* 0x0001 | 0x0002 */
#define PS3AV_RESBIT_720x576P 0x0003 /* 0x0001 | 0x0002 */ #define PS3AV_RESBIT_720x576P 0x0003 /* 0x0001 | 0x0002 */
#define PS3AV_RESBIT_1280x720P 0x0004 #define PS3AV_RESBIT_1280x720P 0x0004
...@@ -298,6 +298,15 @@ ...@@ -298,6 +298,15 @@
| PS3AV_RESBIT_1920x1080I \ | PS3AV_RESBIT_1920x1080I \
| PS3AV_RESBIT_1920x1080P) | PS3AV_RESBIT_1920x1080P)
/* for VESA automode */
#define PS3AV_RESBIT_VGA 0x0001
#define PS3AV_RESBIT_WXGA 0x0002
#define PS3AV_RESBIT_SXGA 0x0004
#define PS3AV_RESBIT_WUXGA 0x0008
#define PS3AV_RES_MASK_VESA (PS3AV_RESBIT_WXGA |\
PS3AV_RESBIT_SXGA |\
PS3AV_RESBIT_WUXGA)
#define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */ #define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */
#define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */ #define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment