10ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs/* 20ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * Copyright 2014 Red Hat Inc. 30ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * 40ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * Permission is hereby granted, free of charge, to any person obtaining a 50ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * copy of this software and associated documentation files (the "Software"), 60ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * to deal in the Software without restriction, including without limitation 70ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense, 80ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * and/or sell copies of the Software, and to permit persons to whom the 90ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * Software is furnished to do so, subject to the following conditions: 100ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * 110ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * The above copyright notice and this permission notice shall be included in 120ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * all copies or substantial portions of the Software. 130ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * 140ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 150ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 160ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 170ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 180ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 190ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 200ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * OTHER DEALINGS IN THE SOFTWARE. 210ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * 220ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * Authors: Ben Skeggs <bskeggs@redhat.com> 230ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs */ 240ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 250ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs/******************************************************************************* 260ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs * NVIF client driver - NVKM directly linked 270ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs ******************************************************************************/ 280ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 290ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include <core/client.h> 300ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include <core/notify.h> 310ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include <core/ioctl.h> 320ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 330ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include <nvif/client.h> 340ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include <nvif/driver.h> 350ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include <nvif/notify.h> 360ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include <nvif/event.h> 370ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include <nvif/ioctl.h> 380ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 390ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs#include "nouveau_drm.h" 4027111a23d01c1dba3180c998629004ab4c9ac985Ben Skeggs#include "nouveau_usif.h" 410ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 420ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsstatic void 433cfb2face6205d30ecfc0145d68cd9e0c3dfe6f1Al Vironvkm_client_unmap(void *priv, void __iomem *ptr, u32 size) 440ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs{ 450ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs iounmap(ptr); 460ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs} 470ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 483cfb2face6205d30ecfc0145d68cd9e0c3dfe6f1Al Virostatic void __iomem * 490ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsnvkm_client_map(void *priv, u64 handle, u32 size) 500ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs{ 510ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return ioremap(handle, size); 520ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs} 530ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 540ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsstatic int 550ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsnvkm_client_ioctl(void *priv, bool super, void *data, u32 size, void **hack) 560ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs{ 570ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return nvkm_ioctl(priv, super, data, size, hack); 580ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs} 590ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 600ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsstatic int 610ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsnvkm_client_resume(void *priv) 620ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs{ 630ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return nouveau_client_init(priv); 640ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs} 650ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 660ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsstatic int 670ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsnvkm_client_suspend(void *priv) 680ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs{ 690ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return nouveau_client_fini(priv, true); 700ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs} 710ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 720ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsstatic void 730ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsnvkm_client_fini(void *priv) 740ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs{ 750ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs struct nouveau_object *client = priv; 760ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs nouveau_client_fini(nv_client(client), false); 770ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs atomic_set(&client->refcount, 1); 780ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs nouveau_object_ref(NULL, &client); 790ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs} 800ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 810ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsstatic int 820ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsnvkm_client_ntfy(const void *header, u32 length, const void *data, u32 size) 830ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs{ 840ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs const union { 850ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs struct nvif_notify_req_v0 v0; 860ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs } *args = header; 870ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs u8 route; 880ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 890ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs if (length == sizeof(args->v0) && args->v0.version == 0) { 900ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs route = args->v0.route; 910ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs } else { 920ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs WARN_ON(1); 930ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return NVKM_NOTIFY_DROP; 940ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs } 950ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 960ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs switch (route) { 970ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs case NVDRM_NOTIFY_NVIF: 980ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return nvif_notify(header, length, data, size); 9927111a23d01c1dba3180c998629004ab4c9ac985Ben Skeggs case NVDRM_NOTIFY_USIF: 10027111a23d01c1dba3180c998629004ab4c9ac985Ben Skeggs return usif_notify(header, length, data, size); 1010ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs default: 1020ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs WARN_ON(1); 1030ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs break; 1040ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs } 1050ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 1060ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return NVKM_NOTIFY_DROP; 1070ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs} 1080ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 1090ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsstatic int 1100ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsnvkm_client_init(const char *name, u64 device, const char *cfg, 1110ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs const char *dbg, void **ppriv) 1120ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs{ 1130ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs struct nouveau_client *client; 1140ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs int ret; 1150ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 1160ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs ret = nouveau_client_create(name, device, cfg, dbg, &client); 1170ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs *ppriv = client; 1180ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs if (ret) 1190ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return ret; 1200ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 1210ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs client->ntfy = nvkm_client_ntfy; 1220ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs return 0; 1230ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs} 1240ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs 1250ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsconst struct nvif_driver 1260ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggsnvif_driver_nvkm = { 1270ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .name = "nvkm", 1280ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .init = nvkm_client_init, 1290ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .fini = nvkm_client_fini, 1300ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .suspend = nvkm_client_suspend, 1310ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .resume = nvkm_client_resume, 1320ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .ioctl = nvkm_client_ioctl, 1330ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .map = nvkm_client_map, 1340ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .unmap = nvkm_client_unmap, 1350ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs .keep = false, 1360ad72863ea426d46b2786cba9430e122a40aad0bBen Skeggs}; 137