The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/osfmk/ppc/pmsCPU.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2004-2005 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 #include <ppc/machine_routines.h>
   23 #include <ppc/machine_cpu.h>
   24 #include <ppc/exception.h>
   25 #include <ppc/misc_protos.h>
   26 #include <ppc/Firmware.h>
   27 #include <ppc/pmap.h>
   28 #include <ppc/asm.h>
   29 #include <ppc/proc_reg.h>
   30 #include <ppc/pms.h>
   31 #include <ppc/savearea.h>
   32 #include <ppc/Diagnostics.h>
   33 #include <kern/processor.h>
   34 
   35 
   36 pmsDef pmsDefault[] = {
   37         {
   38                 .pmsLimit = century,                                                    /* We can normally stay here for 100 years */
   39                 .pmsStepID = pmsIdle,                                                   /* Unique identifier to this step */
   40                 .pmsSetCmd = 0,                                                                 /* Dummy platform power level */
   41                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
   42                 .pmsDown = pmsIdle,                                                             /* We stay here */
   43                 .pmsNext = pmsNorm                                                              /* Next step */
   44         },
   45         {
   46                 .pmsLimit = century,                                                    /* We can normally stay here for 100 years */
   47                 .pmsStepID = pmsNorm,                                                   /* Unique identifier to this step */
   48                 .pmsSetCmd = 0,                                                                 /* Dummy platform power level */
   49                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
   50                 .pmsDown = pmsIdle,                                                             /* Down to idle */
   51                 .pmsNext = pmsNorm                                                              /* Next step */
   52         },
   53         {
   54                 .pmsLimit = century,                                                    /* We can normally stay here for 100 years */
   55                 .pmsStepID = pmsNormHigh,                                               /* Unique identifier to this step */
   56                 .pmsSetCmd = 0,                                                                 /* Dummy platform power level */
   57                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
   58                 .pmsDown = pmsIdle,                                                             /* Down to idle */
   59                 .pmsNext = pmsNormHigh                                                  /* Next step */
   60         },
   61         {
   62                 .pmsLimit = century,                                                    /* We can normally stay here for 100 years */
   63                 .pmsStepID = pmsBoost,                                                  /* Unique identifier to this step */
   64                 .pmsSetCmd = 0,                                                                 /* Dummy platform power level */
   65                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
   66                 .pmsDown = pmsIdle,                                                             /* Step down */
   67                 .pmsNext = pmsBoost                                                             /* Next step */
   68         },      
   69         {       
   70                 .pmsLimit = century,                                                    /* We can normally stay here for 100 years */
   71                 .pmsStepID = pmsLow,                                                    /* Unique identifier to this step */
   72                 .pmsSetCmd = 0,                                                                 /* Dummy platform power level */
   73                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
   74                 .pmsDown = pmsLow,                                                              /* We always stay here */
   75                 .pmsNext = pmsLow                                                               /* We always stay here */
   76         },      
   77         {       
   78                 .pmsLimit = century,                                                    /* We can normally stay here for 100 years */
   79                 .pmsStepID = pmsHigh,                                                   /* Unique identifier to this step */
   80                 .pmsSetCmd = 0,                                                                 /* Dummy platform power level */
   81                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
   82                 .pmsDown = pmsHigh,                                                             /* We always stay here */
   83                 .pmsNext = pmsHigh                                                              /* We always stay here */
   84         },      
   85         {       
   86                 .pmsLimit = 0,                                                                  /* Time doesn't matter for a prepare for change */
   87                 .pmsStepID = pmsPrepCng,                                                /* Unique identifier to this step */
   88                 .pmsSetCmd = pmsParkIt,                                                 /* Force us to be parked */
   89                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
   90                 .pmsDown = pmsPrepCng,                                                  /* We always stay here */
   91                 .pmsNext = pmsPrepCng                                                   /* We always stay here */
   92         },      
   93         {       
   94                 .pmsLimit = 0,                                                                  /* Time doesn't matter for a prepare for sleep */
   95                 .pmsStepID = pmsPrepSleep,                                              /* Unique identifier to this step */
   96                 .pmsSetCmd = pmsParkIt,                                                 /* Force us to be parked */
   97                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
   98                 .pmsDown = pmsPrepSleep,                                                /* We always stay here */
   99                 .pmsNext = pmsPrepSleep                                                 /* We always stay here */
  100         },      
  101         {       
  102                 .pmsLimit = 0,                                                                  /* Time doesn't matter for a prepare for sleep */
  103                 .pmsStepID = pmsOverTemp,                                               /* Unique identifier to this step */
  104                 .pmsSetCmd = 0,                                                                 /* Dummy platform power level */
  105                 .sf.pmsSetFuncInd = 0,                                                  /* Dummy platform set function */
  106                 .pmsDown = pmsOverTemp,                                                 /* We always stay here */
  107                 .pmsNext = pmsOverTemp                                                  /* We always stay here */
  108         }       
  109 };
  110 
  111 
  112 
  113 /*
  114  *      This is where the CPU part of the stepper code lives.   
  115  *
  116  *      It also contains the "hacked kext" experimental code.  This is/was used for
  117  *      experimentation and bringup.  It should neither live long nor prosper.
  118  *
  119  */
  120 
  121 /*
  122  *      Set the processor frequency and stuff
  123  */
  124 
  125 void pmsCPUSet(uint32_t sel) {
  126         int nvoltage, nfreq;
  127         uint32_t oldaack;
  128         struct per_proc_info *pp;
  129 
  130         pp = getPerProc();                                                                      /* Get our per_proc */
  131 
  132         if(!((sel ^ pp->pms.pmsCSetCmd) & pmsCPU)) return;      /* If there aren't any changes, bail now... */
  133 
  134         nfreq = (sel & pmsCPU) >> 16;                                           /* Isolate the new frequency */
  135         
  136         switch(pp->pf.pfPowerModes & pmType) {                          /* Figure out what type to do */
  137         
  138                 case pmDFS:                                                                             /* This is a DFS machine */
  139                         ml_set_processor_speed_dfs(nfreq);                      /* Yes, set it */
  140                         break;
  141         
  142                 case pmDualPLL:
  143                         ml_set_processor_speed_dpll(nfreq);                     /* THIS IS COMPLETELY UNTESTED!!! */
  144                         break;
  145 
  146                 case pmPowerTune:                                                               /* This is a PowerTune machine */
  147                         ml_set_processor_speed_powertune(nfreq);        /* Diddle the deal */
  148                         break;
  149                         
  150                 default:                                                                                /* Not this time dolt!!! */
  151                         panic("pmsCPUSet: unsupported power manager type: %08X\n", pp->pf.pfPowerModes);
  152                         break;
  153         
  154         }
  155         
  156 }
  157 
  158 /*
  159  *      This code configures the initial step tables.  It should be called after the timebase frequency is initialized.
  160  */
  161 
  162 void pmsCPUConf(void) {
  163 
  164         int i;
  165         kern_return_t ret;
  166         pmsSetFunc_t pmsDfltFunc[pmsSetFuncMax];                        /* List of functions for the external power control to use */
  167 
  168         for(i = 0; i < pmsSetFuncMax; i++) pmsDfltFunc[i] = 0;  /* Clear this */
  169 
  170 
  171         ret = pmsBuild((pmsDef *)&pmsDefault, sizeof(pmsDefault), pmsDfltFunc, 0, (pmsQueryFunc_t)0);   /* Configure the default stepper */
  172 
  173 pCCfinish:
  174         if(ret != KERN_SUCCESS) {                                                       /* Some screw up? */
  175                 panic("pmsCPUConf: initial stepper table build failed, ret = %08X\n", ret);     /* Squeal */
  176         }
  177         
  178         pmsSetStep(pmsHigh, 1);                                                         /* Slew to high speed */
  179         pmsPark();                                                                                      /* Then park */
  180         return;
  181 }
  182 
  183 /*
  184  *      This function should be called once for each processor to force the
  185  *      processor to the correct voltage and frequency.
  186  */
  187  
  188 void pmsCPUInit(void) {
  189 
  190         int cpu;
  191 
  192         cpu = cpu_number();                                                                     /* Who are we? */
  193         
  194         kprintf("************ Initializing stepper hardware, cpu %d ******************\n", cpu);        /* (BRINGUP) */
  195         
  196         pmsSetStep(pmsHigh, 1);                                                         /* Slew to high speed */
  197         pmsPark();                                                                                      /* Then park */
  198 
  199         kprintf("************ Stepper hardware initialized, cpu %d ******************\n", cpu); /* (BRINGUP) */
  200 
  201         return;
  202 }
  203 
  204 uint32_t pmsCPUquery(void) {
  205 
  206         uint32_t result;
  207         struct per_proc_info *pp;
  208         uint64_t scdata;
  209 
  210         pp = getPerProc();                                                                      /* Get our per_proc */
  211 
  212         switch(pp->pf.pfPowerModes & pmType) {                          /* Figure out what type to do */
  213         
  214                 case pmDFS:                                                                             /* This is a DFS machine */
  215                         result = hid1get();                                                     /* Get HID1 */
  216                         result = (result >> 6) & 0x00030000;            /* Isolate the DFS bits */
  217                         break;
  218                         
  219                 case pmPowerTune:                                                               /* This is a PowerTune machine */               
  220                         (void)ml_scom_read(PowerTuneStatusReg, &scdata);        /* Get the current power level */
  221                         result = (scdata >> (32 + 8)) & 0x00030000;     /* Shift the data to align with the set command */
  222                         break;
  223                         
  224                 default:                                                                                /* Query not supported for this kind */
  225                         result = 0;                                                                     /* Return highest if not supported */
  226                         break;
  227         
  228         }
  229 
  230         return result;
  231 }
  232 
  233 

Cache object: a5e7493115fd17fa9eec2678841a214b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.