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@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
psb_HDMIExt_get_prop(psb_android_output_p output,unsigned short * xres,unsigned short * yres)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
psb_HDMIExt_get_mode(psb_android_output_p output)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
psb_HDMIExt_update(VADriverContextP ctx,psb_HDMIExt_info_p psb_HDMIExt_info)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
psb_HDMIExt_init(VADriverContextP ctx,psb_android_output_p output)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_DSI) &&
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
psb_HDMIExt_deinit(psb_android_output_p output)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