Skip to contentSkip to conversation

Add cpufreq driver for the IBM PowerPC 750GX

PATCH In review Kevin Diggs 1 participant 1 message Aug 30, 2008

lore
Share & tools
lore
#0 lore raw

PATCH v2 2/5 Add cpufreq driver for the IBM PowerPC 750GX

This adds the actual cpufreq driver for the 750GX. It supports all integer ratios that are valid for the processor model and bus frequency. It is called cf750gx.

It has two modes of operation. Normal mode uses all valid frequencies. In minmaxmode, only the minimum and maximum are used. This provides the ability for very low latency frequency switches.

There is also a sysfs attribute to have it switch off the unused PLL for additional power savings.

This does NOT support SMP.

I fixed a deadlock if the module is unloaded before _target() is ever called.

My name is Kevin Diggs and I approve this patch.

DocBook/cf750gx.tmpl new file +441 -0
Index: Documentation/DocBook/cf750gx.tmpl
===================================================================
@@ -0,0 +1,441 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.1.2//EN"
+	"http://www.oasis-open.org/docbook/xml/4.1.2/docbookx.dtd" []>
+
+<book id="ppc750gx-cpufreq-guide">
+ <bookinfo>
+  <title>PowerPC 750GX (and FX?) cpufreq driver guide</title>
+
+  <authorgroup>
+   <author>
+    <firstname>Kevin</firstname>
+    <surname>Diggs</surname>
+   </author>
+  </authorgroup>
+
+    <revhistory>
+      <revision>
+	<revnumber>1.0&nbsp;</revnumber>
+	<date>August 12, 2008</date>
+	<revremark>Initial revision posted to linuxppc-dev</revremark>
+      </revision>
+    </revhistory>
+
+  <copyright>
+   <year>2008</year>
+   <holder>Kevin Diggs</holder>
+  </copyright>
+
+  <legalnotice>
+   <para>
+    This documentation is free software; you can redistribute
+    it and/or modify it under the terms of the GNU General Public
+    License as published by the Free Software Foundation; either
+    version 2 of the License, or (at your option) any later
+    version.
+   </para>
+
+   <para>
+    This program is distributed in the hope that it will be
+    useful, but WITHOUT ANY WARRANTY; without even the implied
+    warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+    See the GNU General Public License for more details.
+   </para>
+
+   <para>
+    You should have received a copy of the GNU General Public
+    License along with this program; if not, write to the Free
+    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+    MA 02111-1307 USA
+   </para>
+
+   <para>
+    For more details see the file COPYING in the source
+    distribution of Linux.
+   </para>
+  </legalnotice>
+
+  <releaseinfo>
+   This is the first release of this document coincident with submission of the
+   driver for inclusion in the kernel.
+  </releaseinfo>
+
+ </bookinfo>
+
+ <toc></toc>
+
+ <chapter id="introduction">
+  <title>Introduction</title>
+  <para>
+   This guide documents the cpufreq driver for the IBM PowerPC 750GX processor.
+   It "should" also work with the 750FX but has not been tested.
+  </para>
+  <para>
+   The driver is split into two main parts. The first provides the low level
+   interface to the PLL configuration register (HID1 - SPR 1009). It is called
+   pll_if. The second is the actual cpufreq driver, called cf750gx. The pll_if
+   component handles the details of dealing with the PLL like PLL lock delay
+   requirements and preventing illegal operations. The cf750gx driver provides
+   the interface to the cpufreq subsystem. Under control of the specified
+   governor it will generate the required commands to switch the processor
+   frequency as requested and send them to pll_if to carry them out.
+  </para>
+ </chapter>
+
+ <chapter id="MajorComponents">
+  <title>Major Components</title>
+
+  <para>
+   The IBM 750GX (and FX) processor has a pair of PLLs that can be programmed to
+   operate at a number of different frequencies. The frequencies are specified
+   as ratios to the system bus and range from 2 to 20. From 2 to 10 it also
+   supports half ratios (i.e. 2.5, 3.5) though they are not supported in the
+   cpufreq driver due to a limitation of not being able to switch from one half
+   ratio directly to another. It takes 100 usec for a PLL to relock to a
+   new frequency before it can be used [750GX_ds2-17-05.pdf, Table 3-7,
+   page 18]. It takes 3 bus clocks for the cpu to switch from one PLL to
+   another [750GX_ds2-17-05.pdf, paragraph 3, page 44].
+  </para>
+
+  <para>
+   The cpufreq driver consists of two main parts:
+  </para>
+
+  <itemizedlist>
+   <listitem>
+    <para>
+     cf750gx - the cpufreq driver module
+    </para>
+   </listitem>
+
+   <listitem>
+    <para>
+     pll_if - a low level interface that encapsulates the details of dealing
+     with the PLL register
+    </para>
+   </listitem>
+  </itemizedlist>
+
+  <sect1 id="cf750gx">
+   <title>cf750gx - The CPUFreq 750GX driver</title>
+
+   <para>
+    cf750gx provides the standard entry points required of a cpufreq driver. They
+    are:
+
+   <itemizedlist>
+    <listitem>
+     <para>
+      cf750gx_verify - verify
+     </para>
+    </listitem>
+
+    <listitem>
+     <para>
+      cf750gx_target - target
+     </para>
+    </listitem>
+
+    <listitem>
+     <para>
+      cf750gx_cpu_init - cpu init
+     </para>
+    </listitem>
+
+    <listitem>
+     <para>
+      cf750gx_cpu_exit - cpu exit
+     </para>
+    </listitem>
+   </itemizedlist>
+
+    These routines perform functions as required by the cpufreq subsystem.
+   </para>
+
+   <para>
+    The driver functions in one of 2 modes:  normal and minmax. In normal mode
+    it switches between the available frequencies as requested by the current
+    cpufreq subsystem governor. In minmax mode, it switches between the minimum
+    and maximum frequencies only.
+   </para>
+
+   <sect2 id="cf750gxModesNormal"><title>Normal Mode</title>
+    <para>
+     In normal mode the driver switches between all valid frequencies under
+     control of the selected governor. The list of valid frequencies is
+     determined at startup based on the cpu model (FX or GX) and the determined
+     bus frequency. The cpu model determines the minimum and maximum core
+     frequencies, though these can be overriden at start up via module
+     parameters. See Module Parameters. The bus frequency is obtained from
+     pll_if.
+    </para>
+   </sect2>
+
+   <sect2 id="cf750gxModesMinMax"><title>MinMax Mode</title>
+    <para>
+     In minmax mode the driver switches between the minimum and maximum core
+     frequencies only. This provides the capability for very low latency
+     frequency switches. See Module Parameters and sysfs Attributes.
+    </para>
+   </sect2>
+
+   <sect2 id="cf750gxModuleParameters"><title>Module Parameters</title>
+    <para>
+     cf750gx has 3 module parameters:
+    </para>
+
+    <itemizedlist>
+     <listitem>
+      <para>
+       maxcore
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       mincore
+      </para>
+     </listitem>
+     <listitem>
+      <para>
+       minmax
+      </para>
+     </listitem>
+    </itemizedlist>
+
+    <sect3 id="cf750gxParamOverrideMaxCore"><title>maxcore</title>
+     <para>
+      Normally the maximum frequency the cpu can be clocked is defined by the
+      cpu model. For the FX it is 800 MHz and 1,000 MHz for the GX. This
+      parameter allows you to override this maximum. It is specified in KHz.
+     </para>
+    </sect3>
+
+    <sect3 id="cf750gxParamOverrideMinCore"><title>mincore</title>
+     <para>
+      Likewise for cpu minimum frequency.
+     </para>
+
+     <note>
+      <para>
+       The 750GX on my PowerForce 750GX cpu upgrade seems stable at 250 MHz.
+       The spec says the minimum for the GX is 500 MHz.
+      </para>
+     </note>
+    </sect3>
+
+    <sect3 id="cf750gxParamMinMaxMode"><title>minmax</title>
+     <para>
+      This boolean parameter allows one to enable minmax mode on startup.
+     </para>
+    </sect3>
+   </sect2>
+
+   <sect2 id="cf750gxsysfsAttributes"><title>sysfs Attributes</title>
+    <para>
+     cf750gx has 2 sysfs attributes that can be used to modify its operation.
+     They are:
+
+     <itemizedlist>
+      <listitem>
+       <para>
+	idle_pll_off
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        minmax
+       </para>
+      </listitem>
+     </itemizedlist>
+
+     Both are booleans.
+    </para>
+
+    <sect3 id="IdlePllOffAttr"><title>idle_pll_off</title>
+     <para>
+      This boolean tells the driver to switch the idle PLL (the one NOT
+      currently used to drive the cpu core clock) off. Turning the unused PLL
+      off results in a modest power savings [750GX_ds2-17-05.pdf,
+      section 5.2.1, page 44].
+     </para>
+    </sect3>
+
+    <sect3 id="MinMaxModeAttr"><title>minmax</title>
+     <para>
+      This attribute controls the same feature as the similarly named module
+      parameter.
+     </para>
+
+     <note>
+      <para>
+       In order to get this to work with the conservative governor, the
+       "freq_step" attribute must be set to a value that will pick the max
+       frequency from the 2 element frequency table. A good value is 80 (which
+       says to jump in frequency by 80% of the maximum on each change).
+      </para>
+     </note>
+    </sect3>
+   </sect2>
+  </sect1>
+
+  <sect1 id="pll_if">
+   <title>pll_if - The Low Level PLL Interface Module</title>
+   <para>
+    pll_if provides the choice of two interfaces to control the PLL register.
+    One is via a sysfs attribute. The other is through an exported, public
+    routine. At least one interface must be selected during kernel
+    configuration.
+   </para>
+
+   <sect2 id="sysfsInterface"><title>sysfs Interface - ppc750gxpll</title>
+    <para>
+     This interface provides a sysfs attribute that can be written to to
+     directly control the PLL configuration register. The upper 8 or so bits of
+     the PLL configuration register are read only. This interface takes
+     advantage of this by using these bits to define which of the writeable
+     bits contain valid data. The header file
+     <filename class="headerfile">include/asm-powerpc/pll_if.h</filename>
+     defines the following macros:
+
+     <itemizedlist>
+      <listitem>
+       <para>
+        PLL0_DO_CFG - PLL 0 config (ratio) valid
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        PLL0_DO_RNG - PLL 0 range valid
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        PLL1_DO_CFG - PLL 1 config (ratio) valid
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        PLL1_DO_RNG - PLL 1 range valid
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        PLL_DO_SEL - PLL selection bit valid
+       </para>
+      </listitem>
+     </itemizedlist>
+
+     See the PERL script pll.pl for an example of using the sysfs attribute.
+    </para>
+   </sect2>
+
+   <sect2 id="PublicAPI"><title>Exported, Public Functions Interface</title>
+    <para>
+     This interface provides a public API that other code can use. The list of
+     functions is:
+
+     <itemizedlist>
+      <listitem>
+       <para>
+        pllif_pack_state
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        pllif_get_latency
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        pllif_modify_PLL
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        pllif_get_bus_clock
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        pllif_cfg_to_freq
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        pllif_register_pll_switch_cb
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        pllif_unregister_pll_switch_cb
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        pllif_register_pll_lock_cb
+       </para>
+      </listitem>
+
+      <listitem>
+       <para>
+        pllif_unregister_pll_lock_cb
+       </para>
+      </listitem>
+     </itemizedlist>
+
+
+     The embedded documentation from
+     <filename class="headerfile">include/asm-powerpc/pll_if.h</filename>
+     and
+     <filename class="headerfile">arch/powerpc/kernel/cpu/pll_if.c</filename>
+     is included in the appendix.
+
+    </para>
+   </sect2>
+
+   <sect2 id="pllifModuleParameters"><title>Module Parameters</title>
+    <para>
+     pll_if has one tunable parameter. busclock allows you to specify
+     the bus frequency. This is useful if the code can not determine the value
+     or gets it wrong. It is in KHz.
+    </para>
+
+    <note>
+     <para>
+      This code was developed on a PowerMac 8600 with a PowerLogix 750GX
+      upgrade card in it. The method used in the code to get the bus frequency
+      is what worked on this system.
+     </para>
+    </note>
+   </sect2>
+  </sect1>
+ </chapter>
+
+ <chapter id="Misc"><title>Misc</title>
+  <sect1 id="pll.pl"><title>pll.pl - A User Friendly pll_if sysfs utility</title>
+   <para>
+    pll.pl is a PERL script that provides a user friendly interface to the
+    pll_if sysfs attribute, cf750gxpll. It provides options to query the
+    current PLL state, change the configuration of either PLL (when inactive),
+    and to switch the PLL in use. See the embedded documentation in pll.pl
+    for details.
+   </para>
+  </sect1>
+ </chapter>
+ <chapter id="Appendix"><title>Appendix</title>
+!Finclude/asm-powerpc/pll_if.h pllifGetLatency pllifPackState
+!Earch/powerpc/kernel/cpu/pll_if.c
+ </chapter>
+</book>
DocBook/Makefile renamed from DocBook/Makefile.orig +1 -1
Index: Documentation/DocBook/Makefile
===================================================================
@@ -12,7 +12,7 @@ DOCBOOKS := wanbook.xml z8530book.xml mc
 	    kernel-api.xml filesystems.xml lsm.xml usb.xml kgdb.xml \
 	    gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \
 	    genericirq.xml s390-drivers.xml uio-howto.xml scsi.xml \
-	    mac80211.xml debugobjects.xml
+	    mac80211.xml debugobjects.xml cf750gx.xml
 
 ###
 # The build process is as follows (targets):
powerpc/kernel/cpu/cpufreq/Kconfig new file +33 -0
Index: arch/powerpc/kernel/cpu/cpufreq/Kconfig
===================================================================
@@ -0,0 +1,33 @@
+#
+# CPU Frequency scaling
+#
+
+menu "CPU Frequency scaling"
+
+source "drivers/cpufreq/Kconfig"
+
+if CPU_FREQ
+
+comment "CPUFreq processor drivers"
+
+config CPU_FREQ_PPC_750GX_DUAL_PLL
+	tristate "PowerPC 750 FX/GX Dual PLL driver"
+	depends on !SMP
+	select PPC_750GX_DUAL_PLL_IF
+	select CPU_FREQ_TABLE
+	help
+	  This driver adds a CPUFreq driver which utilizes the dual
+	  PLLs found in the IBM 750 FX & GX cpus. This will automatically
+	  select the pll_if module. It does NOT support SMP.
+
+	  To compile this driver as a module, choose M here: the
+	  module will be called cf750gx.
+
+	  For details, take a look at <file:Documentation/cpu-freq/> and also
+	  see the cf750gx DocBook.
+
+	  If in doubt, say N.
+
+endif	# CPU_FREQ
+
+endmenu
powerpc/kernel/cpu/cpufreq/Makefile new file +1 -0
Index: arch/powerpc/kernel/cpu/cpufreq/Makefile
===================================================================
@@ -0,0 +1 @@
+obj-$(CONFIG_CPU_FREQ_PPC_750GX_DUAL_PLL)	+= cf750gx.o
powerpc/kernel/cpu/cpufreq/cf750gx.c new file +741 -0

741 lines not on this page · raw message

powerpc/kernel/cpu/Makefile new file +6 -0
Index: arch/powerpc/kernel/cpu/Makefile
===================================================================
@@ -0,0 +1,6 @@
+#
+# Makefile for ppc CPU details and quirks
+#
+
+obj-$(CONFIG_CPU_FREQ)	+= cpufreq/
+obj-$(CONFIG_PPC_750GX_DUAL_PLL_IF)	+= pll_if.o