+static tbm_backend_bufmgr_data *
+tbm_sprd_init(tbm_bufmgr bufmgr, tbm_error_e *error)
+{
+ tbm_bufmgr_sprd bufmgr_sprd = NULL;
+ tbm_backend_bufmgr_func *bufmgr_func = NULL;
+ tbm_backend_bo_func *bo_func = NULL;
+ int fp;
+ tbm_error_e err;
+ int set_master = 0;
+
+ if (!bufmgr) {
+ TBM_ERR("bufmgr is null.\n");
+ if (error)
+ *error = TBM_ERROR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ bufmgr_sprd = calloc(1, sizeof(struct _tbm_bufmgr_sprd));
+ if (!bufmgr_sprd) {
+ TBM_ERR("fail to alloc bufmgr_sprd!\n");
+ if (error)
+ *error = TBM_ERROR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ /* check the master_fd which already had opened */
+ bufmgr_sprd->fd = tbm_drm_helper_get_master_fd();
+ if (bufmgr_sprd->fd < 0) {
+ bufmgr_sprd->fd = _tbm_sprd_open_drm();
+ if (bufmgr_sprd->fd < 0) {
+ TBM_ERR("fail to open drm!\n");
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ goto fail_open_drm;
+ }
+
+ if (drmIsMaster(bufmgr_sprd->fd)) {
+ tbm_drm_helper_set_tbm_master_fd(bufmgr_sprd->fd);
+ set_master = 1;
+
+ bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
+ if (!bufmgr_sprd->device_name) {
+ TBM_ERR("fail to get device name!\n");
+ tbm_drm_helper_unset_tbm_master_fd();
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ goto fail_get_device_name;
+ }
+ TBM_INFO("This is Master FD(%d) from open_drm.", bufmgr_sprd->fd);
+ } else {
+ /* close the fd and get the authenticated fd from the master fd */
+ close(bufmgr_sprd->fd);
+ bufmgr_sprd->fd = -1;
+
+ /* get the authenticated drm fd from the master fd */
+ if (!tbm_drm_helper_get_auth_info(&(bufmgr_sprd->fd), &(bufmgr_sprd->device_name), NULL)) {
+ TBM_ERR("fail to get auth drm info!\n");
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ goto fail_get_auth_info;
+ }
+ TBM_INFO("This is Authenticated FD(%d)", bufmgr_sprd->fd);
+ }
+ } else {
+ bufmgr_sprd->device_name = drmGetDeviceNameFromFd(bufmgr_sprd->fd);
+ if (!bufmgr_sprd->device_name) {
+ TBM_ERR("fail to get device name!\n");
+ tbm_drm_helper_unset_tbm_master_fd();
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ goto fail_get_device_name;
+ }
+ TBM_INFO("This is Master FD from tbm_drm_helper_get_master_fd(%d)", bufmgr_sprd->fd);
+ }
+ tbm_drm_helper_set_fd(bufmgr_sprd->fd);
+
+ //Check if the tbm manager supports dma fence or not.
+ fp = open("/sys/module/dmabuf_sync/parameters/enabled", O_RDONLY);
+ if (fp != -1) {
+ char buf[1];
+ int length = read(fp, buf, 1);
+
+ if (length == 1 && buf[0] == '1')
+ bufmgr_sprd->use_dma_fence = 1;
+
+ close(fp);
+ }
+
+ if (!_bufmgr_init_cache_state(bufmgr_sprd)) {
+ TBM_ERR("fail to init bufmgr cache state\n");
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ goto fail_init_cache_state;
+ }
+
+ /*Create Hash Table*/
+ bufmgr_sprd->hashBos = drmHashCreate();
+
+ /* alloc and register bufmgr_funcs */
+ bufmgr_func = tbm_backend_bufmgr_alloc_bufmgr_func(bufmgr, &err);
+ if (!bufmgr_func) {
+ TBM_ERR("fail to alloc bufmgr_func! err(%d)\n", err);
+ if (error)
+ *error = TBM_ERROR_OUT_OF_MEMORY;
+ goto fail_alloc_bufmgr_func;
+ }
+
+ bufmgr_func->bufmgr_get_capabilities = tbm_sprd_bufmgr_get_capabilities;
+ bufmgr_func->bufmgr_bind_native_display = tbm_sprd_bufmgr_bind_native_display;
+ bufmgr_func->bufmgr_get_supported_formats = tbm_sprd_bufmgr_get_supported_formats;
+ bufmgr_func->bufmgr_get_plane_data = tbm_sprd_bufmgr_get_plane_data;
+ bufmgr_func->bufmgr_alloc_bo = tbm_sprd_bufmgr_alloc_bo;
+ bufmgr_func->bufmgr_alloc_bo_with_format = NULL;
+ bufmgr_func->bufmgr_import_fd = tbm_sprd_bufmgr_import_fd;
+ bufmgr_func->bufmgr_import_key = tbm_sprd_bufmgr_import_key;
+
+ err = tbm_backend_bufmgr_register_bufmgr_func(bufmgr, bufmgr_func);
+ if (err != TBM_ERROR_NONE) {
+ TBM_ERR("fail to register bufmgr_func! err(%d)\n", err);
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ goto fail_register_bufmgr_func;
+ }
+ bufmgr_sprd->bufmgr_func = bufmgr_func;
+
+ /* alloc and register bo_funcs */
+ bo_func = tbm_backend_bufmgr_alloc_bo_func(bufmgr, &err);
+ if (!bo_func) {
+ TBM_ERR("fail to alloc bo_func! err(%d)\n", err);
+ if (error)
+ *error = TBM_ERROR_OUT_OF_MEMORY;
+ goto fail_alloc_bo_func;
+ }
+
+ bo_func->bo_free = tbm_sprd_bo_free;
+ bo_func->bo_get_size = tbm_sprd_bo_get_size;
+ bo_func->bo_get_memory_types = tbm_sprd_bo_get_memory_type;
+ bo_func->bo_get_handle = tbm_sprd_bo_get_handle;
+ bo_func->bo_map = tbm_sprd_bo_map;
+ bo_func->bo_unmap = tbm_sprd_bo_unmap;
+ bo_func->bo_lock = NULL;
+ bo_func->bo_unlock = NULL;
+ bo_func->bo_export_fd = tbm_sprd_bo_export_fd;
+ bo_func->bo_export_key = tbm_sprd_bo_export_key;
+
+ err = tbm_backend_bufmgr_register_bo_func(bufmgr, bo_func);
+ if (err != TBM_ERROR_NONE) {
+ TBM_ERR("fail to register bo_func! err(%d)\n", err);
+ if (error)
+ *error = TBM_ERROR_INVALID_OPERATION;
+ goto fail_register_bo_func;
+ }
+ bufmgr_sprd->bo_func = bo_func;
+
+ TBM_DBG("DMABUF FENCE is %s\n",
+ bufmgr_sprd->use_dma_fence ? "supported!" : "NOT supported!");
+ TBM_DBG("fd:%d\n", bufmgr_sprd->fd);
+
+ if (error)
+ *error = TBM_ERROR_NONE;
+
+ bufmgr_sprd->bufmgr = bufmgr;
+
+ return (tbm_backend_bufmgr_data *)bufmgr_sprd;
+
+fail_register_bo_func:
+ tbm_backend_bufmgr_free_bo_func(bufmgr, bo_func);
+fail_alloc_bo_func:
+fail_register_bufmgr_func:
+ tbm_backend_bufmgr_free_bufmgr_func(bufmgr, bufmgr_func);
+fail_alloc_bufmgr_func:
+ _bufmgr_deinit_cache_state(bufmgr_sprd);
+ if (bufmgr_sprd->hashBos)
+ drmHashDestroy(bufmgr_sprd->hashBos);
+fail_init_cache_state:
+ if (set_master)
+ tbm_drm_helper_unset_tbm_master_fd();
+ tbm_drm_helper_unset_fd();
+ if (bufmgr_sprd->device_name)
+ free(bufmgr_sprd->device_name);
+fail_get_device_name:
+ close(bufmgr_sprd->fd);
+fail_get_auth_info:
+fail_open_drm:
+ free(bufmgr_sprd);
+ return NULL;
+}