]> git.saurik.com Git - apple/xnu.git/blob - iokit/Drivers/platform/drvAppleGossamerPE/Gossamer.cpp
xnu-123.5.tar.gz
[apple/xnu.git] / iokit / Drivers / platform / drvAppleGossamerPE / Gossamer.cpp
1 /*
2 * Copyright (c) 1998-2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
24 *
25 * DRI: Josh de Cesare
26 *
27 */
28
29 extern "C" {
30 #include <machine/machine_routines.h>
31 }
32
33 #include <IOKit/pwr_mgt/RootDomain.h>
34
35 #include <IOKit/IODeviceTreeSupport.h>
36 //#include <IOKit/ata/IOATAStandardInterface.h>
37
38 #include "Gossamer.h"
39
40 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
41
42 #define super ApplePlatformExpert
43
44 OSDefineMetaClassAndStructors(GossamerPE, ApplePlatformExpert);
45
46 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
47
48 bool GossamerPE::start(IOService *provider)
49 {
50 unsigned int tmpVal;
51 long machineType;
52 long allInOne;
53
54 setChipSetType(kChipSetTypeGossamer);
55
56 // Set the machine type.
57 if (IODTMatchNubWithKeys(provider, "'AAPL,Gossamer'"))
58 machineType = kGossamerTypeGossamer;
59 else if (IODTMatchNubWithKeys(provider, "'AAPL,PowerMac G3'"))
60 machineType = kGossamerTypeSilk;
61 else if (IODTMatchNubWithKeys(provider, "'AAPL,PowerBook1998'"))
62 machineType = kGossamerTypeWallstreet;
63 else if (IODTMatchNubWithKeys(provider, "'iMac,1'"))
64 machineType = kGossamerTypeiMac;
65 else if (IODTMatchNubWithKeys(provider, "('PowerMac1,1', 'PowerMac1,2')"))
66 machineType = kGossamerTypeYosemite;
67 else if (IODTMatchNubWithKeys(provider, "'PowerBook1,1'"))
68 machineType = kGossamerType101;
69 else return false;
70
71 setMachineType(machineType);
72
73 // Find out if this an all in one.
74 allInOne = 0;
75 if (ml_probe_read(kGossamerMachineIDReg, &tmpVal)) {
76 switch (getMachineType()) {
77 case kGossamerTypeGossamer :
78 case kGossamerTypeSilk :
79 if (!(tmpVal & kGossamerAllInOneMask)) allInOne = 1;
80 break;
81
82 case kGossamerTypeiMac :
83 allInOne = 1;
84 break;
85 }
86 }
87 if (allInOne) setProperty("AllInOne", this);
88
89 // setup default power mgr features per machine
90 // NOTE: on Core99 and later hardware, this information
91 // is available from the "prim-info" property in the power-mgt
92 // node of the device tree. Prior to that, this information
93 // was just another hard-coded part of the ROM.
94
95 switch (getMachineType()) {
96 case kGossamerTypeGossamer:
97 case kGossamerTypeSilk:
98 case kGossamerTypeiMac:
99 case kGossamerTypeYosemite:
100 _pePMFeatures = kStdDesktopPMFeatures;
101 _pePrivPMFeatures = kStdDesktopPrivPMFeatures;
102 _peNumBatteriesSupported = kStdDesktopNumBatteries;
103 break;
104
105 case kGossamerTypeWallstreet:
106 _pePMFeatures = kWallstreetPMFeatures;
107 _pePrivPMFeatures = kWallstreetPrivPMFeatures;
108 _peNumBatteriesSupported = kStdPowerBookNumBatteries;
109 break;
110
111 case kGossamerType101:
112 _pePMFeatures = k101PMFeatures;
113 _pePrivPMFeatures = k101PrivPMFeatures;
114 _peNumBatteriesSupported = kStdPowerBookNumBatteries;
115 break;
116 }
117
118 return super::start(provider);
119 }
120
121
122 bool GossamerPE::platformAdjustService(IOService *service)
123 {
124 long tmpNum;
125 OSData *tmpData;
126
127 // Add the extra sound properties for Gossamer AIO
128 if (getProperty("AllInOne") &&
129 ((getMachineType() == kGossamerTypeGossamer) ||
130 (getMachineType() == kGossamerTypeSilk))) {
131 if (!strcmp(service->getName(), "sound")) {
132 tmpNum = 3;
133 tmpData = OSData::withBytes(&tmpNum, sizeof(tmpNum));
134 if (tmpData) {
135 service->setProperty("#-detects", tmpData);
136 service->setProperty("#-outputs", tmpData);
137 tmpData->release();
138 }
139 return true;
140 }
141 }
142
143 // Set the loop snoop property for Wallstreet or Mainstreet.
144 if (getMachineType() == kGossamerTypeWallstreet) {
145 if (IODTMatchNubWithKeys(service, "('grackle', 'MOT,PPC106')")) {
146 // Add the property for set loop snoop.
147 service->setProperty("set-loop-snoop", service);
148 return true;
149 }
150 }
151
152 // Publish out the dual display heads on 101.
153 if (getMachineType() == kGossamerType101) {
154 if (!strcmp(service->getName(), "ATY,LTProParent")) {
155 if (kIOReturnSuccess == IONDRVLibrariesInitialize(service)) {
156 createNubs(this, service->getChildIterator( gIODTPlane ));
157 }
158 return true;
159 }
160 }
161
162 return true;
163 }
164
165 IOReturn GossamerPE::callPlatformFunction(const OSSymbol *functionName,
166 bool waitForFunction,
167 void *param1, void *param2,
168 void *param3, void *param4)
169 {
170 if (functionName == gGetDefaultBusSpeedsKey) {
171 getDefaultBusSpeeds((long *)param1, (unsigned long **)param2);
172 return kIOReturnSuccess;
173 }
174
175 return super::callPlatformFunction(functionName, waitForFunction,
176 param1, param2, param3, param4);
177 }
178
179 static unsigned long gossamerSpeed[] = { 66820000, 1 };
180 static unsigned long yosemiteSpeed[] = { 99730000, 1 };
181
182 void GossamerPE::getDefaultBusSpeeds(long *numSpeeds,
183 unsigned long **speedList)
184 {
185 if ((numSpeeds == 0) || (speedList == 0)) return;
186
187 switch (getMachineType()) {
188 case kGossamerTypeGossamer :
189 case kGossamerTypeSilk :
190 *numSpeeds = 1;
191 *speedList = gossamerSpeed;
192 break;
193
194 case kGossamerTypeYosemite :
195 *numSpeeds = 1;
196 *speedList = yosemiteSpeed;
197 break;
198
199 default :
200 *numSpeeds = 0;
201 *speedList = 0;
202 break;
203 }
204 }
205
206
207 //*********************************************************************************
208 // PMInstantiatePowerDomains
209 //
210 // This overrides the vanilla implementation in IOPlatformExpert. It instantiates
211 // a root domain with two children, one for the USB bus (to handle the USB idle
212 // power budget), and one for the expansions slots on the PCI bus (to handle
213 // the idle PCI power budget)
214 //*********************************************************************************
215
216 void GossamerPE::PMInstantiatePowerDomains ( void )
217 {
218 root = new IOPMrootDomain;
219 root->init();
220 root->attach(this);
221 root->start(this);
222 root->youAreRoot();
223
224 /* All G3s support sleep (or pseudo-sleep) now
225 if ((getMachineType() == kGossamerType101) ||
226 (getMachineType() == kGossamerTypeWallstreet))
227 */
228 root->setSleepSupported(kRootDomainSleepSupported);
229 }
230
231
232 //*********************************************************************************
233 // PMRegisterDevice
234 //
235 // This overrides the vanilla implementation in IOPlatformExpert.
236 //*********************************************************************************
237
238 //#define DONOTREGISTERATACONTROLLER 1
239
240 void GossamerPE::PMRegisterDevice(IOService * theNub, IOService * theDevice)
241 {
242 //#ifdef DONOTREGISTERATACONTROLLER
243 // do not add IOATAStandardDriver to the tree since on this platform they do not need resets
244 // if (OSDynamicCast(IOATAStandardDriver, theDevice) != NULL)
245 // return;
246 //#endif
247
248 // Checks if the nub handles power states, if it does not gets its parent and so
249 // up until we reach the root, or we do not find anything:
250 while ((theNub != NULL) && ( theNub->addPowerChild(theDevice) != IOPMNoErr )) {
251 theNub = theNub->getProvider();
252
253 //#ifdef DONOTREGISTERATACONTROLLER
254 // IOATAStandardDriver are detached, and so would be evrething I attach to them so
255 // their childs go directly on the tree.
256 // if (OSDynamicCast(IOATAStandardDriver, theNub) != NULL) {
257 // theNub = theNub->getProvider();
258 // }
259 //#endif
260 }
261
262 if ( theNub == NULL ) {
263 root->addPowerChild ( theDevice );
264 return;
265 }
266 }