[go: nahoru, domu]

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