nouveau_display.c revision 6ee738610f41b59733f63718f0bdbcba7d3a3f12
16ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs/* 26ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * Copyright (C) 2008 Maarten Maathuis. 36ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * All Rights Reserved. 46ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 56ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * Permission is hereby granted, free of charge, to any person obtaining 66ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * a copy of this software and associated documentation files (the 76ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * "Software"), to deal in the Software without restriction, including 86ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * without limitation the rights to use, copy, modify, merge, publish, 96ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * distribute, sublicense, and/or sell copies of the Software, and to 106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * permit persons to whom the Software is furnished to do so, subject to 116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * the following conditions: 126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * The above copyright notice and this permission notice (including the 146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * next paragraph) shall be included in all copies or substantial 156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * portions of the Software. 166ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 176ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 186ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 196ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 206ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) AND/OR ITS SUPPLIERS BE 216ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 226ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 236ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 246ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs * 256ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs */ 266ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 276ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "drmP.h" 286ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "drm_crtc_helper.h" 296ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "nouveau_drv.h" 306ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "nouveau_fb.h" 316ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs#include "nouveau_fbcon.h" 326ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 336ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic void 346ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) 356ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 366ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 376ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_device *dev = drm_fb->dev; 386ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 396ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (drm_fb->fbdev) 406ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs nouveau_fbcon_remove(dev, drm_fb); 416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 426ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (fb->nvbo) { 436ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs mutex_lock(&dev->struct_mutex); 446ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs drm_gem_object_unreference(fb->nvbo->gem); 456ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs mutex_unlock(&dev->struct_mutex); 466ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs } 476ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 486ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs drm_framebuffer_cleanup(drm_fb); 496ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs kfree(fb); 506ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 516ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 526ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic int 536ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, 546ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_file *file_priv, 556ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs unsigned int *handle) 566ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 576ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); 586ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 596ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle); 606ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 616ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 626ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { 636ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .destroy = nouveau_user_framebuffer_destroy, 646ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .create_handle = nouveau_user_framebuffer_create_handle, 656ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}; 666ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 676ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstruct drm_framebuffer * 686ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_framebuffer_create(struct drm_device *dev, struct nouveau_bo *nvbo, 696ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_mode_fb_cmd *mode_cmd) 706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 716ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct nouveau_framebuffer *fb; 726ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs int ret; 736ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 746ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL); 756ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (!fb) 766ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return NULL; 776ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 786ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs ret = drm_framebuffer_init(dev, &fb->base, &nouveau_framebuffer_funcs); 796ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (ret) { 806ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs kfree(fb); 816ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return NULL; 826ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs } 836ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 846ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs drm_helper_mode_fill_fb_struct(&fb->base, mode_cmd); 856ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 866ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs fb->nvbo = nvbo; 876ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return &fb->base; 886ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 896ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 906ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic struct drm_framebuffer * 916ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create(struct drm_device *dev, 926ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_file *file_priv, 936ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_mode_fb_cmd *mode_cmd) 946ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{ 956ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_framebuffer *fb; 966ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs struct drm_gem_object *gem; 976ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 986ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle); 996ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (!gem) 1006ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return NULL; 1016ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1026ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs fb = nouveau_framebuffer_create(dev, nouveau_gem_object(gem), mode_cmd); 1036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs if (!fb) { 1046ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs drm_gem_object_unreference(gem); 1056ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return NULL; 1066ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs } 1076ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1086ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs return fb; 1096ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs} 1106ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 1116ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsconst struct drm_mode_config_funcs nouveau_mode_config_funcs = { 1126ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .fb_create = nouveau_user_framebuffer_create, 1136ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs .fb_changed = nouveau_fbcon_probe, 1146ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}; 1156ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs 116