How to Modify a Core’s Voltage by Writing revision 1.1

How to Modify a Core’s Voltage by Writing
the SCC RPC Register
revision 1.1
Revision History for Document
1.0
Initial release.
1.1
Correct typo; 0x07 shsould have been 0x70
1 Introduction
You do not have to use the RCCE power management calls to change the voltage in an SCC
power domain. With RCCE, you can only change the frequency, and the voltage may then
change along with it. This ensures that you do not enter an unacceptable electrical state.
You do still have the capability of changing the voltage on a core directly, but not with the
RCCE API. Note that when you change the voltage on a core, you actually change the
voltage for all cores in that core’s power domain. You do not modify the frequency.
The best way to see how to change the voltage is to look at the way RCCE does it. RCCE is
more than a message-passing library you can use for your applications. The entire RCCE
source code is available and reading RCCE code is an excellent way to understand how the
SCC works.
2 The RPC Register
Change the voltage by writing a value to the RPC register. RPC stands for Rock Creek Power
Controller. This is sometimes called the VRC register for Voltage Regulator Controller.
The RPC register is at physical address 0xfb000000. You cannot read this register. You won’t
get an error if you try; you’ll just get a returned value that doesn’t mean anything.
Bit 16 must be 1. Bits 10-8 specify the SCC power domain. A power domain is a set of 2x2
tiles or 8 cores. Note that this is the SCC power domain number, not the RCCE power
domain number. The SCC domain number reads 4, 5, and 7 on the bottom row left to right
and 0, 1, and 3 on the upper row, left to right.
RCCE: 3
RCCE: 4
RCCE: 5
SCC:
SCC:
SCC:
0
1
3
RCCE: 0
RCCE: 10
RCCE: 2
SCC:
SCC:
SCC:
7
5
4
4
5
The bit pattern for the RPC register looks as follows.
16
October 2, 2011
15
14
13
12
11
10
9
8
Page 1 of 4
7
6
3
2
1
0
Intel Labs
1
SCC pwr dmn
voltage value
Bits 7 through 0 specify the voltage. The choices for the voltage value are 0x70 through
0xd0. The values start at 0.7v (the 0x70) and increment by 0.1v to 1.3v (the 0xd0.
3 How RCCE Sets the Voltage
RCCE calls an internal routine called RC_set_voltage(). Note that external RCCE routines
begin with RCCE and internal ones begin with RC.
RC_set_voltage(RCCE_voltage_domain(RCCE_IAM),Vlevel, &error);
RCCE_voltage_domain()
returns the RCCE voltage domain number. RCCE_IAM is the
number of the calling core. Vlevel is a number from 0 through 6. It is the index into the
array called RC_V_MHz_cap[].
triple RC_V_MHz_cap[] = {
/* 0 */ {0.7, 0x70, 460},
/* 1 */ {0.8, 0x80, 598},
/* 2 */ {0.9, 0x90, 644},
/* 3 */ {1.0, 0xA0, 748},
/* 4 */ {1.1, 0xB0, 875},
/* 5 */ {1.2, 0xC0, 1024},
/* 6 */ {1.3, 0xD0, 1198}
};
RCCE does the memory-mapped I/O and assigns RPC_virtual_address as the memorymapped address for the RPC register. The actual setting of the voltage happens as
*RPC_virtual_address = VID_word(Vlevel, domain);
Here Vlevel is the previously mentioned array index and domain is the RCCE power domain
number. VID_word() calls VID_control_value() which translates the RCCE power
domain number to the SCC power domain number and returns a value for the RPC register
with zeroes for the voltage value. VID_word() shifts in the voltage value using Vlevel.
4 Example
This section shows an example of writing 0x10480 to the RPC register. This example does
not use the RCCE API and does not link with the RCCE library. It runs on rck00. First off,
the SCC is initialized with Tile533_Mesh800_DDR800. The command sccBmc –c status
returns
Tertiary supplies:
OPVR VCC0: 1.0957
OPVR VCC1: 1.0951
OPVR VCC2: 1.0951
OPVR VCC3: 1.0951
OPVR VCC4: 1.0954
October 2, 2011
V
V
V
V
V
Page 2 of 4
Intel Labs
OPVR VCC5: 1.0961 V
OPVR VCC7: 1.0945 V
Now log onto rck00 and run the example as follows. rck00 belongs to RCCE power domain
0 and SCC power domain 4.
[email protected]:~/C_programs/POW$ ssh [email protected]
rck00:/root # cd /shared/tekubasx/
rck00:tekubasx # cd Power
rck00:Power # ls
FV*
powertest* rc.hosts
setvolt*
status*
rck00:Power # ./setvolt
ConfigAddr, PAGE_SIZE: fb000000 1000
Wrote 0x10480 to address b77b9000
rck00:Power #
After running the program sccBmc –c status returns the following.
Tertiary supplies:
OPVR VCC0: 1.0946
OPVR VCC1: 1.0939
OPVR VCC2: 1.0910
OPVR VCC3: 1.0937
OPVR VCC4: 0.8422
OPVR VCC5: 1.0898
OPVR VCC7: 1.0873
V
V
V
V
V
V
V
Note the voltage drop in SCC power domain 4.
5 Source Code Listing
Setvolt.c:
typedef volatile unsigned char* t_vcharp;
typedef volatile unsigned int* t_vintp;
#include
#include
#include
#include
#include
#include
#include
<stdio.h>
<unistd.h>
<sys/mman.h>
<sys/types.h>
<sys/stat.h>
<fcntl.h>
<stdlib.h>
#define RPC_PHYSICAL_ADDRESS 0xfb000000
main() {
int PAGE_SIZE, NCMDeviceFD;
// NCMDeviceFD is the file descriptor
// for non-cacheable memory
unsigned int alignedAddr,ConfigAddr;
t_vcharp MappedAddr;
t_vintp RPC_virtual_address;
ConfigAddr = RPC_PHYSICAL_ADDRESS;
PAGE_SIZE = getpagesize();
October 2, 2011
Page 3 of 4
Intel Labs
if ((NCMDeviceFD=open("/dev/rckncm", O_RDWR|O_SYNC))<0) {
perror("open"); exit(-1);
}
printf("ConfigAddr, PAGE_SIZE: %x %x\n",ConfigAddr, PAGE_SIZE);
MappedAddr
= (t_vcharp) mmap(NULL, PAGE_SIZE, PROT_WRITE|PROT_READ,
MAP_SHARED, NCMDeviceFD, ConfigAddr);
if (MappedAddr== MAP_FAILED) {
perror("mmap MappedAddr");exit(-1);
}
RPC_virtual_address = (t_vintp)MappedAddr;
*RPC_virtual_address = 0x10480;
printf("Wrote 0x10480 to address %x\n",RPC_virtual_address);
munmap((void*)MappedAddr, PAGE_SIZE);
}
Makefile:
setvolt: setvolt.c Makefile
icc -static -gcc-version=340 -mcpu=pentium -o setvolt setvolt.c
cp setvolt /shared/tekubasx/Power
clean:
rm -rf *.o setvolt
October 2, 2011
Page 4 of 4
Intel Labs