diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2010-09-18 08:13:04 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-09-24 02:27:48 -0400 |
commit | 07b1266962085412e85af2e7df471ec9ed0c35f5 (patch) | |
tree | 5b200821f274126a28365ad19f004160e2e928f7 | |
parent | e022878571690e09e965e8c6bfc837b3dc5b6b74 (diff) |
drm/nouveau: fix potential accuracy loss when parsing perf 0x1c tables
Reported-by: Roy Spliet <r.spliet@student.tudelft.nl>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_perf.c | 34 |
1 files changed, 14 insertions, 20 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c index a882a366487f..a397420e46c6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_perf.c +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c | |||
@@ -90,50 +90,44 @@ nouveau_perf_init(struct drm_device *dev) | |||
90 | case 0x15: | 90 | case 0x15: |
91 | perflvl->fanspeed = entry[55]; | 91 | perflvl->fanspeed = entry[55]; |
92 | perflvl->voltage = entry[56]; | 92 | perflvl->voltage = entry[56]; |
93 | perflvl->core = ROM32(entry[1]) / 100; | 93 | perflvl->core = ROM32(entry[1]) * 10; |
94 | perflvl->memory = ROM32(entry[5]) / 100; | 94 | perflvl->memory = ROM32(entry[5]) * 10; |
95 | break; | 95 | break; |
96 | case 0x21: | 96 | case 0x21: |
97 | case 0x23: | 97 | case 0x23: |
98 | case 0x24: | 98 | case 0x24: |
99 | perflvl->fanspeed = entry[4]; | 99 | perflvl->fanspeed = entry[4]; |
100 | perflvl->voltage = entry[5]; | 100 | perflvl->voltage = entry[5]; |
101 | perflvl->core = ROM16(entry[6]); | 101 | perflvl->core = ROM16(entry[6]) * 1000; |
102 | perflvl->memory = ROM16(entry[11]); | 102 | perflvl->memory = ROM16(entry[11]) * 1000; |
103 | break; | 103 | break; |
104 | case 0x25: | 104 | case 0x25: |
105 | perflvl->fanspeed = entry[4]; | 105 | perflvl->fanspeed = entry[4]; |
106 | perflvl->voltage = entry[5]; | 106 | perflvl->voltage = entry[5]; |
107 | perflvl->core = ROM16(entry[6]); | 107 | perflvl->core = ROM16(entry[6]) * 1000; |
108 | perflvl->shader = ROM16(entry[10]); | 108 | perflvl->shader = ROM16(entry[10]) * 1000; |
109 | perflvl->memory = ROM16(entry[12]); | 109 | perflvl->memory = ROM16(entry[12]) * 1000; |
110 | break; | 110 | break; |
111 | case 0x30: | 111 | case 0x30: |
112 | case 0x35: | 112 | case 0x35: |
113 | perflvl->fanspeed = entry[6]; | 113 | perflvl->fanspeed = entry[6]; |
114 | perflvl->voltage = entry[7]; | 114 | perflvl->voltage = entry[7]; |
115 | perflvl->core = ROM16(entry[8]); | 115 | perflvl->core = ROM16(entry[8]) * 1000; |
116 | perflvl->shader = ROM16(entry[10]); | 116 | perflvl->shader = ROM16(entry[10]) * 1000; |
117 | perflvl->memory = ROM16(entry[12]); | 117 | perflvl->memory = ROM16(entry[12]) * 1000; |
118 | /*XXX: confirm on 0x35 */ | 118 | /*XXX: confirm on 0x35 */ |
119 | perflvl->unk05 = ROM16(entry[16]); | 119 | perflvl->unk05 = ROM16(entry[16]) * 1000; |
120 | break; | 120 | break; |
121 | case 0x40: | 121 | case 0x40: |
122 | #define subent(n) entry[perf[2] + ((n) * perf[3])] | 122 | #define subent(n) entry[perf[2] + ((n) * perf[3])] |
123 | perflvl->fanspeed = 0; /*XXX*/ | 123 | perflvl->fanspeed = 0; /*XXX*/ |
124 | perflvl->voltage = 0; /*XXX: entry[2] */; | 124 | perflvl->voltage = 0; /*XXX: entry[2] */; |
125 | perflvl->core = ROM16(subent(0)) & 0xfff; | 125 | perflvl->core = (ROM16(subent(0)) & 0xfff) * 1000; |
126 | perflvl->shader = ROM16(subent(1)) & 0xfff; | 126 | perflvl->shader = (ROM16(subent(1)) & 0xfff) * 1000; |
127 | perflvl->memory = ROM16(subent(2)) & 0xfff; | 127 | perflvl->memory = (ROM16(subent(2)) & 0xfff) * 1000; |
128 | break; | 128 | break; |
129 | } | 129 | } |
130 | 130 | ||
131 | /* convert MHz -> KHz, it's more convenient */ | ||
132 | perflvl->core *= 1000; | ||
133 | perflvl->memory *= 1000; | ||
134 | perflvl->shader *= 1000; | ||
135 | perflvl->unk05 *= 1000; | ||
136 | |||
137 | /* make sure vid is valid */ | 131 | /* make sure vid is valid */ |
138 | if (pm->voltage.supported && perflvl->voltage) { | 132 | if (pm->voltage.supported && perflvl->voltage) { |
139 | vid = nouveau_volt_vid_lookup(dev, perflvl->voltage); | 133 | vid = nouveau_volt_vid_lookup(dev, perflvl->voltage); |