1cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs/*
2cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * Copyright 2012 Red Hat Inc.
3cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs *
4cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * Permission is hereby granted, free of charge, to any person obtaining a
5cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * copy of this software and associated documentation files (the "Software"),
6cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * to deal in the Software without restriction, including without limitation
7cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * and/or sell copies of the Software, and to permit persons to whom the
9cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * Software is furnished to do so, subject to the following conditions:
10cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs *
11cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * The above copyright notice and this permission notice shall be included in
12cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * all copies or substantial portions of the Software.
13cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs *
14cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
17cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * OTHER DEALINGS IN THE SOFTWARE.
21cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs *
22cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs * Authors: Ben Skeggs
23cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs */
24cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs
25cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs#include <core/option.h>
26cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs
27cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs#include <subdev/bios.h>
28cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs#include <subdev/bios/init.h>
29f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin#include <subdev/vga.h>
30cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs
31cf336014c6dc3ef1431d84b5a94e47a22660493bBen Skeggs#include "priv.h"
32cf336014c6dc3ef1431d84b5a94e47a22660493bBen Skeggs
33cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggsint
3488524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs_nouveau_devinit_fini(struct nouveau_object *object, bool suspend)
35cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs{
3688524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs	struct nouveau_devinit *devinit = (void *)object;
37cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs
38cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	/* force full reinit on resume */
39cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	if (suspend)
40cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs		devinit->post = true;
41cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs
42f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin	/* unlock the extended vga crtc regs */
43f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin	nv_lockvgac(devinit, false);
44f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin
45cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	return nouveau_subdev_fini(&devinit->base, suspend);
46cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs}
47cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs
48cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggsint
4988524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs_nouveau_devinit_init(struct nouveau_object *object)
5088524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs{
514019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin	struct nouveau_devinit_impl *impl = (void *)object->oclass;
5288524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs	struct nouveau_devinit *devinit = (void *)object;
534019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin	int ret;
544019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin
554019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin	ret = nouveau_subdev_init(&devinit->base);
564019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin	if (ret)
574019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin		return ret;
584019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin
594019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin	ret = nvbios_init(&devinit->base, devinit->post);
6088524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs	if (ret)
6188524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs		return ret;
6288524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs
634019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin	if (impl->disable)
644019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin		nv_device(devinit)->disable_mask |= impl->disable(devinit);
654019aaa2b314a5be9886ae1db64ff8c6d3c060edIlia Mirkin	return 0;
6688524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs}
6788524bc06926b243c75e5751eb3403c602b6a904Ben Skeggs
68f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkinvoid
69f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin_nouveau_devinit_dtor(struct nouveau_object *object)
70f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin{
71f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin	struct nouveau_devinit *devinit = (void *)object;
72f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin
73f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin	/* lock crtc regs */
74f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin	nv_lockvgac(devinit, true);
75f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin
76f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin	nouveau_subdev_destroy(&devinit->base);
77f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin}
78f87cd8b695d372087685976460fac1ec6ba2fca9Ilia Mirkin
7988524bc06926b243c75e5751eb3403c602b6a904Ben Skeggsint
80cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggsnouveau_devinit_create_(struct nouveau_object *parent,
81cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs			struct nouveau_object *engine,
82cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs			struct nouveau_oclass *oclass,
83cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs			int size, void **pobject)
84cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs{
85cf336014c6dc3ef1431d84b5a94e47a22660493bBen Skeggs	struct nouveau_devinit_impl *impl = (void *)oclass;
86cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	struct nouveau_device *device = nv_device(parent);
87cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	struct nouveau_devinit *devinit;
88cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	int ret;
89cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs
90cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	ret = nouveau_subdev_create_(parent, engine, oclass, 0, "DEVINIT",
91cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs				     "init", size, pobject);
92cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	devinit = *pobject;
93cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	if (ret)
94cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs		return ret;
95cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs
96cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	devinit->post = nouveau_boolopt(device->cfgopt, "NvForcePost", false);
97cf336014c6dc3ef1431d84b5a94e47a22660493bBen Skeggs	devinit->meminit = impl->meminit;
98cf336014c6dc3ef1431d84b5a94e47a22660493bBen Skeggs	devinit->pll_set = impl->pll_set;
993219adc29ccb1706de4f1453d0386c5a2487ab14Ben Skeggs	devinit->mmio    = impl->mmio;
100cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs	return 0;
101cb75d97e9c77743ecfcc43375be135a55a4d9b25Ben Skeggs}
102