]> git.saurik.com Git - apple/xnu.git/blob - iokit/Drivers/platform/drvAppleGossamerPE/Gossamer.cpp
cefb2921242a77dbc4256569e3b26ef685bfd9c4
[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 return true;
153 }
154
155 IOReturn GossamerPE::callPlatformFunction(const OSSymbol *functionName,
156 bool waitForFunction,
157 void *param1, void *param2,
158 void *param3, void *param4)
159 {
160 if (functionName == gGetDefaultBusSpeedsKey) {
161 getDefaultBusSpeeds((long *)param1, (unsigned long **)param2);
162 return kIOReturnSuccess;
163 }
164
165 return super::callPlatformFunction(functionName, waitForFunction,
166 param1, param2, param3, param4);
167 }
168
169 static unsigned long gossamerSpeed[] = { 66820000, 1 };
170 static unsigned long yosemiteSpeed[] = { 99730000, 1 };
171
172 void GossamerPE::getDefaultBusSpeeds(long *numSpeeds,
173 unsigned long **speedList)
174 {
175 if ((numSpeeds == 0) || (speedList == 0)) return;
176
177 switch (getMachineType()) {
178 case kGossamerTypeGossamer :
179 case kGossamerTypeSilk :
180 *numSpeeds = 1;
181 *speedList = gossamerSpeed;
182 break;
183
184 case kGossamerTypeYosemite :
185 *numSpeeds = 1;
186 *speedList = yosemiteSpeed;
187 break;
188
189 default :
190 *numSpeeds = 0;
191 *speedList = 0;
192 break;
193 }
194 }
195
196
197 //*********************************************************************************
198 // PMInstantiatePowerDomains
199 //
200 // This overrides the vanilla implementation in IOPlatformExpert. It instantiates
201 // a root domain with two children, one for the USB bus (to handle the USB idle
202 // power budget), and one for the expansions slots on the PCI bus (to handle
203 // the idle PCI power budget)
204 //*********************************************************************************
205
206 void GossamerPE::PMInstantiatePowerDomains ( void )
207 {
208 root = new IOPMrootDomain;
209 root->init();
210 root->attach(this);
211 root->start(this);
212 root->youAreRoot();
213
214 /* All G3s support sleep (or pseudo-sleep) now
215 if ((getMachineType() == kGossamerType101) ||
216 (getMachineType() == kGossamerTypeWallstreet))
217 */
218 root->setSleepSupported(kRootDomainSleepSupported);
219 }
220
221
222 //*********************************************************************************
223 // PMRegisterDevice
224 //
225 // This overrides the vanilla implementation in IOPlatformExpert.
226 //*********************************************************************************
227
228 //#define DONOTREGISTERATACONTROLLER 1
229
230 void GossamerPE::PMRegisterDevice(IOService * theNub, IOService * theDevice)
231 {
232 //#ifdef DONOTREGISTERATACONTROLLER
233 // do not add IOATAStandardDriver to the tree since on this platform they do not need resets
234 // if (OSDynamicCast(IOATAStandardDriver, theDevice) != NULL)
235 // return;
236 //#endif
237
238 // Checks if the nub handles power states, if it does not gets its parent and so
239 // up until we reach the root, or we do not find anything:
240 while ((theNub != NULL) && ( theNub->addPowerChild(theDevice) != IOPMNoErr )) {
241 theNub = theNub->getProvider();
242
243 //#ifdef DONOTREGISTERATACONTROLLER
244 // IOATAStandardDriver are detached, and so would be evrething I attach to them so
245 // their childs go directly on the tree.
246 // if (OSDynamicCast(IOATAStandardDriver, theNub) != NULL) {
247 // theNub = theNub->getProvider();
248 // }
249 //#endif
250 }
251
252 if ( theNub == NULL ) {
253 root->addPowerChild ( theDevice );
254 return;
255 }
256 }