libexternal: clean up HDMI modes
- Userspace was maintaining its own display mode timing table
- Change that to include the header from kernel
Change-Id: I19823e60d188b5a30445866c7df1860e269975bc
CRs-fixed: 470335
diff --git a/libexternal/external.cpp b/libexternal/external.cpp
index cf84a39..4385a3d 100644
--- a/libexternal/external.cpp
+++ b/libexternal/external.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2010 The Android Open Source Project
- * Copyright (C) 2012, The Linux Foundation. All rights reserved.
+ * Copyright (C) 2012-2013, The Linux Foundation. All rights reserved.
*
* Not a Contribution, Apache license notifications and license are
* retained for attribution purposes only.
@@ -28,6 +28,7 @@
#include <utils/Log.h>
#include <linux/msm_mdp.h>
+#include <video/msm_hdmi_modes.h>
#include <linux/fb.h>
#include <sys/ioctl.h>
#include <sys/poll.h>
@@ -171,6 +172,15 @@
// This helps for framework reboot or adb shell stop/start
writeHPDOption(0);
+ // for HDMI - retreive all the modes supported by the driver
+ if(mHdmiFbNum != -1) {
+ supported_video_mode_lut =
+ new msm_hdmi_mode_timing_info[HDMI_VFRMT_MAX];
+ // Populate the mode table for supported modes
+ MSM_HDMI_MODES_INIT_TIMINGS(supported_video_mode_lut);
+ MSM_HDMI_MODES_SET_SUPP_TIMINGS(supported_video_mode_lut,
+ MSM_HDMI_MODES_ALL);
+ }
}
void ExternalDisplay::setEDIDMode(int resMode) {
@@ -285,93 +295,40 @@
ExternalDisplay::~ExternalDisplay()
{
+ delete [] supported_video_mode_lut;
closeFrameBuffer();
}
-struct disp_mode_timing_type {
- int video_format;
-
- int active_h;
- int active_v;
-
- int front_porch_h;
- int pulse_width_h;
- int back_porch_h;
-
- int front_porch_v;
- int pulse_width_v;
- int back_porch_v;
-
- int pixel_freq;
- bool interlaced;
-
- void set_info(struct fb_var_screeninfo &info) const;
-};
-
-void disp_mode_timing_type::set_info(struct fb_var_screeninfo &info) const
+/*
+ * sets the fb_var_screeninfo from the hdmi_mode_timing_info
+ */
+void setDisplayTiming(struct fb_var_screeninfo &info,
+ const msm_hdmi_mode_timing_info* mode)
{
info.reserved[0] = 0;
info.reserved[1] = 0;
info.reserved[2] = 0;
#ifndef FB_METADATA_VIDEO_INFO_CODE_SUPPORT
- info.reserved[3] = (info.reserved[3] & 0xFFFF) | (video_format << 16);
+ info.reserved[3] = (info.reserved[3] & 0xFFFF) |
+ (mode->video_format << 16);
#endif
info.xoffset = 0;
info.yoffset = 0;
- info.xres = active_h;
- info.yres = active_v;
+ info.xres = mode->active_h;
+ info.yres = mode->active_v;
- info.pixclock = pixel_freq*1000;
- info.vmode = interlaced ? FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
+ info.pixclock = (mode->pixel_freq)*1000;
+ info.vmode = mode->interlaced ?
+ FB_VMODE_INTERLACED : FB_VMODE_NONINTERLACED;
- info.right_margin = front_porch_h;
- info.hsync_len = pulse_width_h;
- info.left_margin = back_porch_h;
- info.lower_margin = front_porch_v;
- info.vsync_len = pulse_width_v;
- info.upper_margin = back_porch_v;
+ info.right_margin = mode->front_porch_h;
+ info.hsync_len = mode->pulse_width_h;
+ info.left_margin = mode->back_porch_h;
+ info.lower_margin = mode->front_porch_v;
+ info.vsync_len = mode->pulse_width_v;
+ info.upper_margin = mode->back_porch_v;
}
-/* Video formates supported by the HDMI Standard */
-/* Indicates the resolution, pix clock and the aspect ratio */
-#define m640x480p60_4_3 1
-#define m720x480p60_4_3 2
-#define m720x480p60_16_9 3
-#define m1280x720p60_16_9 4
-#define m1920x1080i60_16_9 5
-#define m1440x480i60_4_3 6
-#define m1440x480i60_16_9 7
-#define m1920x1080p60_16_9 16
-#define m720x576p50_4_3 17
-#define m720x576p50_16_9 18
-#define m1280x720p50_16_9 19
-#define m1440x576i50_4_3 21
-#define m1440x576i50_16_9 22
-#define m1920x1080p50_16_9 31
-#define m1920x1080p24_16_9 32
-#define m1920x1080p25_16_9 33
-#define m1920x1080p30_16_9 34
-
-static struct disp_mode_timing_type supported_video_mode_lut[] = {
- {m640x480p60_4_3, 640, 480, 16, 96, 48, 10, 2, 33, 25200, false},
- {m720x480p60_4_3, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false},
- {m720x480p60_16_9, 720, 480, 16, 62, 60, 9, 6, 30, 27030, false},
- {m1280x720p60_16_9, 1280, 720, 110, 40, 220, 5, 5, 20, 74250, false},
- {m1920x1080i60_16_9, 1920, 540, 88, 44, 148, 2, 5, 5, 74250, false},
- {m1440x480i60_4_3, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true},
- {m1440x480i60_16_9, 1440, 240, 38, 124, 114, 4, 3, 15, 27000, true},
- {m1920x1080p60_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 148500, false},
- {m720x576p50_4_3, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false},
- {m720x576p50_16_9, 720, 576, 12, 64, 68, 5, 5, 39, 27000, false},
- {m1280x720p50_16_9, 1280, 720, 440, 40, 220, 5, 5, 20, 74250, false},
- {m1440x576i50_4_3, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true},
- {m1440x576i50_16_9, 1440, 288, 24, 126, 138, 2, 3, 19, 27000, true},
- {m1920x1080p50_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 148500, false},
- {m1920x1080p24_16_9, 1920, 1080, 638, 44, 148, 4, 5, 36, 74250, false},
- {m1920x1080p25_16_9, 1920, 1080, 528, 44, 148, 4, 5, 36, 74250, false},
- {m1920x1080p30_16_9, 1920, 1080, 88, 44, 148, 4, 5, 36, 74250, false},
-};
-
int ExternalDisplay::parseResolution(char* edidStr, int* edidModes)
{
char delim = ',';
@@ -475,42 +432,42 @@
int ExternalDisplay::getModeOrder(int mode)
{
// XXX: We dont support interlaced modes but having
- // it here for for future
+ // it here for future
switch (mode) {
default:
- case m1440x480i60_4_3:
+ case HDMI_VFRMT_1440x480i60_4_3:
return 1; // 480i 4:3
- case m1440x480i60_16_9:
+ case HDMI_VFRMT_1440x480i60_16_9:
return 2; // 480i 16:9
- case m1440x576i50_4_3:
+ case HDMI_VFRMT_1440x576i50_4_3:
return 3; // i576i 4:3
- case m1440x576i50_16_9:
+ case HDMI_VFRMT_1440x576i50_16_9:
return 4; // 576i 16:9
- case m640x480p60_4_3:
+ case HDMI_VFRMT_640x480p60_4_3:
return 5; // 640x480 4:3
- case m720x480p60_4_3:
+ case HDMI_VFRMT_720x480p60_4_3:
return 6; // 480p 4:3
- case m720x480p60_16_9:
+ case HDMI_VFRMT_720x480p60_16_9:
return 7; // 480p 16:9
- case m720x576p50_4_3:
+ case HDMI_VFRMT_720x576p50_4_3:
return 8; // 576p 4:3
- case m720x576p50_16_9:
+ case HDMI_VFRMT_720x576p50_16_9:
return 9; // 576p 16:9
- case m1920x1080i60_16_9:
+ case HDMI_VFRMT_1920x1080i60_16_9:
return 10; // 1080i 16:9
- case m1280x720p50_16_9:
+ case HDMI_VFRMT_1280x720p50_16_9:
return 11; // 720p@50Hz
- case m1280x720p60_16_9:
+ case HDMI_VFRMT_1280x720p60_16_9:
return 12; // 720p@60Hz
- case m1920x1080p24_16_9:
+ case HDMI_VFRMT_1920x1080p24_16_9:
return 13; //1080p@24Hz
- case m1920x1080p25_16_9:
+ case HDMI_VFRMT_1920x1080p25_16_9:
return 14; //108-p@25Hz
- case m1920x1080p30_16_9:
+ case HDMI_VFRMT_1920x1080p30_16_9:
return 15; //1080p@30Hz
- case m1920x1080p50_16_9:
+ case HDMI_VFRMT_1920x1080p50_16_9:
return 16; //1080p@50Hz
- case m1920x1080p60_16_9:
+ case HDMI_VFRMT_1920x1080p60_16_9:
return 17; //1080p@60Hz
}
}
@@ -532,7 +489,7 @@
// Get the best mode for the current HD TV
int ExternalDisplay::getBestMode() {
int bestOrder = 0;
- int bestMode = m640x480p60_4_3;
+ int bestMode = HDMI_VFRMT_640x480p60_4_3;
Mutex::Autolock lock(mExtDispLock);
// for all the edid read, get the best mode
for(int i = 0; i < mModeCount; i++) {
@@ -562,11 +519,11 @@
bool ExternalDisplay::isInterlacedMode(int ID) {
bool interlaced = false;
switch(ID) {
- case m1440x480i60_4_3:
- case m1440x480i60_16_9:
- case m1440x576i50_4_3:
- case m1440x576i50_16_9:
- case m1920x1080i60_16_9:
+ case HDMI_VFRMT_1440x480i60_4_3:
+ case HDMI_VFRMT_1440x480i60_16_9:
+ case HDMI_VFRMT_1440x576i50_4_3:
+ case HDMI_VFRMT_1440x576i50_16_9:
+ case HDMI_VFRMT_1920x1080i60_16_9:
interlaced = true;
default:
interlaced = false;
@@ -583,7 +540,6 @@
ALOGD("In %s: FBIOGET_VSCREENINFO failed Err Str = %s", __FUNCTION__,
strerror(errno));
}
-
ALOGD_IF(DEBUG, "%s: GET Info<ID=%d %dx%d (%d,%d,%d),"
"(%d,%d,%d) %dMHz>", __FUNCTION__,
mVInfo.reserved[3], mVInfo.xres, mVInfo.yres,
@@ -592,17 +548,17 @@
mVInfo.pixclock/1000/1000);
//If its a new ID - update var_screeninfo
if ((isValidMode(ID)) && mCurrentMode != ID) {
- const struct disp_mode_timing_type *mode =
+ const struct msm_hdmi_mode_timing_info *mode =
&supported_video_mode_lut[0];
- unsigned count = sizeof(supported_video_mode_lut)/sizeof
- (*supported_video_mode_lut);
- for (unsigned int i = 0; i < count; ++i) {
- const struct disp_mode_timing_type *cur =
- &supported_video_mode_lut[i];
- if (cur->video_format == ID)
+ for (unsigned int i = 0; i < HDMI_VFRMT_MAX; ++i) {
+ const struct msm_hdmi_mode_timing_info *cur =
+ &supported_video_mode_lut[i];
+ if (cur->video_format == (uint32_t)ID) {
mode = cur;
+ break;
+ }
}
- mode->set_info(mVInfo);
+ setDisplayTiming(mVInfo, mode);
ALOGD_IF(DEBUG, "%s: SET Info<ID=%d => Info<ID=%d %dx %d"
"(%d,%d,%d), (%d,%d,%d) %dMHz>", __FUNCTION__, ID,
mode->video_format, mVInfo.xres, mVInfo.yres,
@@ -703,54 +659,54 @@
void ExternalDisplay::getAttrForMode(int& width, int& height, int& fps) {
switch (mCurrentMode) {
- case m640x480p60_4_3:
+ case HDMI_VFRMT_640x480p60_4_3:
width = 640;
height = 480;
fps = 60;
break;
- case m720x480p60_4_3:
- case m720x480p60_16_9:
+ case HDMI_VFRMT_720x480p60_4_3:
+ case HDMI_VFRMT_720x480p60_16_9:
width = 720;
height = 480;
fps = 60;
break;
- case m720x576p50_4_3:
- case m720x576p50_16_9:
+ case HDMI_VFRMT_720x576p50_4_3:
+ case HDMI_VFRMT_720x576p50_16_9:
width = 720;
height = 576;
fps = 50;
break;
- case m1280x720p50_16_9:
+ case HDMI_VFRMT_1280x720p50_16_9:
width = 1280;
height = 720;
fps = 50;
break;
- case m1280x720p60_16_9:
+ case HDMI_VFRMT_1280x720p60_16_9:
width = 1280;
height = 720;
fps = 60;
break;
- case m1920x1080p24_16_9:
+ case HDMI_VFRMT_1920x1080p24_16_9:
width = 1920;
height = 1080;
fps = 24;
break;
- case m1920x1080p25_16_9:
+ case HDMI_VFRMT_1920x1080p25_16_9:
width = 1920;
height = 1080;
fps = 25;
break;
- case m1920x1080p30_16_9:
+ case HDMI_VFRMT_1920x1080p30_16_9:
width = 1920;
height = 1080;
fps = 30;
break;
- case m1920x1080p50_16_9:
+ case HDMI_VFRMT_1920x1080p50_16_9:
width = 1920;
height = 1080;
fps = 50;
break;
- case m1920x1080p60_16_9:
+ case HDMI_VFRMT_1920x1080p60_16_9:
width = 1920;
height = 1080;
fps = 60;