1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
|
*=============*
* DVFS Framework *
*=============*
(C) 2011 Vishwnath BS <vishwanath.bs@ti.com>, Texas Instruments Incorporated
Contents
--------
1. Introduction
2. Data Structure Organization
3. DVFS APIs
1. Introduction
===============
DVFS is a technique that uses the optimal operating frequency and voltage to
allow a task to be performed in the required amount of time.
OMAP processors have voltage domains whose voltage can be scaled to
various levels depending on which the operating frequencies of certain
devices belonging to the domain will also need to be scaled. This voltage
frequency tuple is known as Operating Performance Point (OPP). A device
can have multiple OPP's. Also a voltage domain could be shared between
multiple devices. Also there could be dependencies between various
voltage domains for maintaining system performance like VDD<X>
should be at voltage v1 when VDD<Y> is at voltage v2.
The design of this framework takes into account all the above mentioned points.
To summarize the basic design of DVFS framework:-
1. Have device opp tables for each device whose operating frequency can be
scaled. This is easy now due to the existance of hwmod layer which
allow storing of device specific info. The device opp tables contain
the opp pairs (frequency voltage tuples), the voltage domain pointer
to which the device belongs to, the device specific set_rate and
get_rate API's which will do the actual scaling of the device frequency
and retrieve the current device frequency.
2. Introduce use counting on a per VDD basis. This is to take care multiple
requests to scale a VDD. The VDD will be scaled to the maximum of the
voltages requested.
3. Keep track of all scalable devices belonging to a particular voltage
domain the voltage layer.
4. Keep track of frequency requests for each of the device. This will enable
to scale individual devices to different frequency (even w/o scaling voltage
aka frequency throttling)
5. Generic dvfs API that can be called by anybody to scale a device opp.
This API takes the device pointer and frequency to which the device
needs to be scaled to. This API then internally finds out the voltage
domain to which the device belongs to and the voltage to which the voltage
domain needs to be put to for the device to be scaled to the new frequency
from he device opp table. Then this API will add requested frequency into
the corresponding target device frequency list and add voltage request to
the corresponding vdd. Subsequently it calls voltage scale function which
will find out the highest requested voltage for the given vdd and scales
the voltage to the required one. It also runs through the list of all
scalable devices belonging to this voltage domain and scale them to the
appropriate frequencies using the set_rate pointer in the device opp tables.
6. Handle inter VDD dependecies.
2. The Core DVFS data structure:
=================================
|-------------------| |-------------------|
|User2 (dev2, freq2)| |User4 (dev4, freq4)|
|-------^-----------| |-------^-----------|
| |
|-------|-----------| |-------|-----------|
|User1 (dev1, freq1)| |User3 (dev3, freq3)|(omap_dev_user_list)
|-------^-----------| |-------^-----------|
| |
|---|--------------| |------------------|
|--------->| DEV1 (dev) |------------>| DEV2 (dev) |(omap_vdd_dev_list)
| |omap_dev_user_list| |omap_dev_user_list|
| |------------------| |------------------|
|
|---------|-----------|
| VDD_n |
| omap_vdd_dev_list |
| omap_vdd_user_list |(omap_vdd_dvfs_info)
| |
|--------|------------|
|
| |------------| |------------| |--------------|
|---------> | vdd_user1 |->| vdd_user2 |->| vdd_user3 | (omap_vdd_user_list)
| (dev, volt)| | (dev, volt)| | (dev, volt) |
|------------| |------------| |--------------|
3. APIs:
=====
1. omap_device_scale - Set a new rate at which the device is to operate
Examples:
1. Simple Device scaling:
Suppose module M wants to put device dev1 to frequency f1. Let's say that mdev
is the device * for module M. Then this could be achieved by
ret = omap_device_scale(mdev, dev1, f1)
if (ret)
/* handle error *.
2. Frequency Throttling
Suppose say there are 2 modules M1 and M2 in Voltage domain VDDx.
Module M1 wants to set VDDx to OPP100 voltage which means M1 and M2 will
be running at OPP100 frequency. Suppose Module M2 wants to run at OPP50
frequency (say f2_opp50) instead of OPP100. This can be achieved by
/* this operation will place M1 and M2 to run at OPP100 */
ret = omap_device_scale(mdev1, dev1, f1_opp100);
if (ret)
/* handle error *.
/* This operation will bring M2 to run at f2_opp50 w/o decreasing VDDx voltage */
ret = omap_device_scale(mdev2, dev2, f2_opp50);
if (ret)
/* handle error *.
|