nouveau_display.c revision 386516744ba45d50f42c6999151cc210cb4f96e4
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
38bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri	if (fb->nvbo)
39bc9025bdc4e2b591734cca17697093845007b63dLuca Barbieri		drm_gem_object_unreference_unlocked(fb->nvbo->gem);
406ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
416ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	drm_framebuffer_cleanup(drm_fb);
426ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	kfree(fb);
436ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}
446ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
456ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic int
466ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb,
476ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs				       struct drm_file *file_priv,
486ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs				       unsigned int *handle)
496ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{
506ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb);
516ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
526ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle);
536ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}
546ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
556ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = {
566ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	.destroy = nouveau_user_framebuffer_destroy,
576ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	.create_handle = nouveau_user_framebuffer_create_handle,
586ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs};
596ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
60386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlieint
61386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlienouveau_framebuffer_init(struct drm_device *dev, struct nouveau_framebuffer *nouveau_fb,
62386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie			 struct drm_mode_fb_cmd *mode_cmd, struct nouveau_bo *nvbo)
636ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{
646ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	int ret;
656ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
66386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	ret = drm_framebuffer_init(dev, &nouveau_fb->base, &nouveau_framebuffer_funcs);
676ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	if (ret) {
68386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie		return ret;
696ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	}
706ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
71386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	drm_helper_mode_fill_fb_struct(&nouveau_fb->base, mode_cmd);
72386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	nouveau_fb->nvbo = nvbo;
73386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	return 0;
746ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}
756ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
766ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsstatic struct drm_framebuffer *
776ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsnouveau_user_framebuffer_create(struct drm_device *dev,
786ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs				struct drm_file *file_priv,
796ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs				struct drm_mode_fb_cmd *mode_cmd)
806ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs{
81386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	struct nouveau_framebuffer *nouveau_fb;
826ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	struct drm_gem_object *gem;
83386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	int ret;
846ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
856ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	gem = drm_gem_object_lookup(dev, file_priv, mode_cmd->handle);
866ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	if (!gem)
876ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs		return NULL;
886ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
89386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	nouveau_fb = kzalloc(sizeof(struct nouveau_framebuffer), GFP_KERNEL);
90386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	if (!nouveau_fb)
91386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie		return NULL;
92386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie
93386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	ret = nouveau_framebuffer_init(dev, nouveau_fb, mode_cmd, nouveau_gem_object(gem));
94386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	if (ret) {
956ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs		drm_gem_object_unreference(gem);
966ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs		return NULL;
976ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	}
986ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
99386516744ba45d50f42c6999151cc210cb4f96e4Dave Airlie	return &nouveau_fb->base;
1006ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs}
1016ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
1026ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggsconst struct drm_mode_config_funcs nouveau_mode_config_funcs = {
1036ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs	.fb_create = nouveau_user_framebuffer_create,
1046ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs};
1056ee738610f41b59733f63718f0bdbcba7d3a3f12Ben Skeggs
106