1 /* 2 * Copyright (c) 2011 Intel Corporation. All Rights Reserved. 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the 6 * "Software"), to deal in the Software without restriction, including 7 * without limitation the rights to use, copy, modify, merge, publish, 8 * distribute, sub license, and/or sell copies of the Software, and to 9 * permit persons to whom the Software is furnished to do so, subject to 10 * the following conditions: 11 * 12 * The above copyright notice and this permission notice (including the 13 * next paragraph) shall be included in all copies or substantial portions 14 * of the Software. 15 * 16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. 19 * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR 20 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 * 24 * Authors: 25 * Jason Hu <jason.hu (at) intel.com> 26 */ 27 28 #include "psb_HDMIExtMode.h" 29 #include "psb_output_android.h" 30 #include "pvr2d.h" 31 #include "psb_drv_video.h" 32 #include "psb_drv_debug.h" 33 34 #define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData 35 36 VAStatus psb_HDMIExt_get_prop(psb_android_output_p output, 37 unsigned short *xres, unsigned short *yres) 38 { 39 psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info; 40 41 if (!psb_HDMIExt_info || !psb_HDMIExt_info->hdmi_extvideo_prop || 42 (psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode == OFF)) { 43 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get HDMI prop\n", __FUNCTION__); 44 return VA_STATUS_ERROR_UNKNOWN; 45 } 46 *xres = psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode_XRes; 47 *yres = psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode_YRes; 48 49 return VA_STATUS_SUCCESS; 50 } 51 52 psb_hdmi_mode psb_HDMIExt_get_mode(psb_android_output_p output) 53 { 54 psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info; 55 56 if (!psb_HDMIExt_info) { 57 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get HDMI mode\n", __FUNCTION__); 58 return VA_STATUS_ERROR_UNKNOWN; 59 } 60 return psb_HDMIExt_info->hdmi_mode; 61 } 62 63 VAStatus psb_HDMIExt_update(VADriverContextP ctx, psb_HDMIExt_info_p psb_HDMIExt_info) 64 { 65 INIT_DRIVER_DATA; 66 drmModeCrtc *hdmi_crtc = NULL; 67 drmModeConnector *hdmi_connector = NULL; 68 drmModeEncoder *hdmi_encoder = NULL; 69 char *strHeight = NULL; 70 struct drm_lnc_video_getparam_arg arg; 71 int hdmi_state = 0; 72 static int hdmi_connected_frame = 0; 73 74 arg.key = IMG_VIDEO_GET_HDMI_STATE; 75 arg.value = (uint64_t)((unsigned int)&hdmi_state); 76 drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 77 &arg, sizeof(arg)); 78 79 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : hdmi_state = %d\n", __FUNCTION__, hdmi_state); 80 if (psb_HDMIExt_info->hdmi_state != hdmi_state) { 81 psb_HDMIExt_info->hdmi_state = hdmi_state; 82 switch (hdmi_state) { 83 case HDMI_MODE_EXT_VIDEO: 84 psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode = EXTENDED_VIDEO; 85 psb_HDMIExt_info->hdmi_mode = EXTENDED_VIDEO; 86 87 psb_extvideo_prop_p hdmi_extvideo_prop = psb_HDMIExt_info->hdmi_extvideo_prop; 88 89 hdmi_connector = drmModeGetConnector(driver_data->drm_fd, psb_HDMIExt_info->hdmi_connector_id); 90 if (!hdmi_connector) { 91 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get hdmi connector\n", __FUNCTION__); 92 return VA_STATUS_ERROR_UNKNOWN; 93 } 94 95 hdmi_encoder = drmModeGetEncoder(driver_data->drm_fd, hdmi_connector->encoder_id); 96 if (!hdmi_encoder) { 97 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get hdmi encoder\n", __FUNCTION__); 98 return VA_STATUS_ERROR_UNKNOWN; 99 } 100 101 hdmi_crtc = drmModeGetCrtc(driver_data->drm_fd, hdmi_encoder->crtc_id); 102 if (!hdmi_crtc) { 103 /* No CRTC attached to HDMI. */ 104 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get hdmi crtc\n", __FUNCTION__); 105 return VA_STATUS_ERROR_UNKNOWN; 106 } 107 108 strHeight = strstr(hdmi_crtc->mode.name, "x"); 109 hdmi_extvideo_prop->ExtVideoMode_XRes = (unsigned short)atoi(hdmi_crtc->mode.name); 110 hdmi_extvideo_prop->ExtVideoMode_YRes = (unsigned short)atoi(strHeight + 1); 111 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : size = %d x %d\n", __FUNCTION__, 112 hdmi_extvideo_prop->ExtVideoMode_XRes, hdmi_extvideo_prop->ExtVideoMode_YRes); 113 drmModeFreeCrtc(hdmi_crtc); 114 drmModeFreeEncoder(hdmi_encoder); 115 drmModeFreeConnector(hdmi_connector); 116 break; 117 case HDMI_MODE_OFF: 118 psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode = OFF; 119 psb_HDMIExt_info->hdmi_mode = OFF; 120 hdmi_connected_frame = 0; 121 break; 122 default: 123 psb_HDMIExt_info->hdmi_extvideo_prop->ExtVideoMode = UNDEFINED; 124 psb_HDMIExt_info->hdmi_mode = UNDEFINED; 125 } 126 } 127 128 return VA_STATUS_SUCCESS; 129 } 130 131 psb_HDMIExt_info_p psb_HDMIExt_init(VADriverContextP ctx, psb_android_output_p output) 132 { 133 INIT_DRIVER_DATA; 134 drmModeRes *resources; 135 drmModeConnector *connector = NULL; 136 drmModeEncoder *mipi_encoder = NULL; 137 int mipi_connector_id = 0, mipi_encoder_id = 0, mipi_crtc_id = 0, i; 138 psb_HDMIExt_info_p psb_HDMIExt_info = NULL; 139 140 psb_HDMIExt_info = (psb_HDMIExt_info_p)calloc(1, sizeof(psb_HDMIExt_info_s)); 141 if (!psb_HDMIExt_info) { 142 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to create psb_HDMIExt_info.\n", __FUNCTION__); 143 return NULL; 144 } 145 memset(psb_HDMIExt_info, 0, sizeof(psb_HDMIExt_info_s)); 146 147 psb_HDMIExt_info->hdmi_extvideo_prop = (psb_extvideo_prop_p)calloc(1, sizeof(psb_extvideo_prop_s)); 148 if (!psb_HDMIExt_info->hdmi_extvideo_prop) { 149 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to create hdmi_extvideo_prop.\n", __FUNCTION__); 150 free(psb_HDMIExt_info); 151 return NULL; 152 } 153 memset(psb_HDMIExt_info->hdmi_extvideo_prop, 0, sizeof(psb_extvideo_prop_s)); 154 155 /*Get Resources.*/ 156 resources = drmModeGetResources(driver_data->drm_fd); 157 if (!resources) { 158 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : drmModeGetResources failed.\n", __FUNCTION__); 159 goto exit; 160 } 161 162 /*Get MIPI and HDMI connector id.*/ 163 for (i = 0; i < resources->count_connectors; i++) { 164 connector = drmModeGetConnector(driver_data->drm_fd, resources->connectors[i]); 165 166 if (!connector) { 167 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get connector %i\n", __FUNCTION__, 168 resources->connectors[i]); 169 continue; 170 } 171 172 if (connector->connector_type == DRM_MODE_CONNECTOR_DVID) 173 psb_HDMIExt_info->hdmi_connector_id = connector->connector_id; 174 175 if ((connector->connector_type == DRM_MODE_CONNECTOR_MIPI) && 176 (!mipi_connector_id)) { 177 mipi_connector_id = connector->connector_id; 178 mipi_encoder_id = connector->encoder_id; 179 } 180 181 drmModeFreeConnector(connector); 182 connector = NULL; 183 } 184 185 if (!mipi_connector_id || 186 !psb_HDMIExt_info->hdmi_connector_id || 187 !mipi_encoder_id) { 188 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get connector id or mipi encoder id. mipi_connector_id=%d, hdmi_connector_id=%d, mipi_encoder_id=%d\n", __FUNCTION__, 189 mipi_connector_id, psb_HDMIExt_info->hdmi_connector_id, mipi_encoder_id); 190 goto exit; 191 } 192 193 mipi_encoder = drmModeGetEncoder(driver_data->drm_fd, mipi_encoder_id); 194 if (!mipi_encoder) { 195 drv_debug_msg(VIDEO_DEBUG_ERROR, "%s : Failed to get mipi encoder %i\n", __FUNCTION__); 196 goto exit; 197 } 198 199 psb_HDMIExt_info->mipi_crtc_id = mipi_encoder->crtc_id; 200 drv_debug_msg(VIDEO_DEBUG_GENERAL, "%s : mipi_crtc_id = %d\n", __FUNCTION__, 201 mipi_crtc_id); 202 203 drmModeFreeEncoder(mipi_encoder); 204 205 if (psb_HDMIExt_update(ctx, psb_HDMIExt_info)) 206 goto exit; 207 208 if (resources) 209 drmModeFreeResources(resources); 210 211 return psb_HDMIExt_info; 212 213 exit: 214 if (resources) 215 drmModeFreeResources(resources); 216 217 if (connector) 218 drmModeFreeConnector(connector); 219 220 return psb_HDMIExt_info; 221 } 222 223 VAStatus psb_HDMIExt_deinit(psb_android_output_p output) 224 { 225 psb_HDMIExt_info_p psb_HDMIExt_info = (psb_HDMIExt_info_p)output->psb_HDMIExt_info; 226 227 if (psb_HDMIExt_info->hdmi_extvideo_prop) 228 free(psb_HDMIExt_info->hdmi_extvideo_prop); 229 230 if (psb_HDMIExt_info) 231 free(psb_HDMIExt_info); 232 233 return VA_STATUS_SUCCESS; 234 } 235 236