Home | History | Annotate | Download | only in android
      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_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 
    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