Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 218201
b: refs/heads/master
c: 330c598
h: refs/heads/master
i:
  218199: b9f0b72
v: v3
  • Loading branch information
Ben Skeggs committed Sep 24, 2010
1 parent a3c5e1a commit 6c44a48
Show file tree
Hide file tree
Showing 8 changed files with 679 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 4709bff02adcb0d05d2d1a397e60581baa562de9
refs/heads/master: 330c5988ee78045e6a731c3693251aaa5b0d14e3
1 change: 1 addition & 0 deletions trunk/drivers/gpu/drm/nouveau/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \
nouveau_hw.o nouveau_calc.o nouveau_bios.o nouveau_i2c.o \
nouveau_display.o nouveau_connector.o nouveau_fbcon.o \
nouveau_dp.o nouveau_ramht.o \
nouveau_pm.o nouveau_volt.o nouveau_perf.o \
nv04_timer.o \
nv04_mc.o nv40_mc.o nv50_mc.o \
nv04_fb.o nv10_fb.o nv30_fb.o nv40_fb.o nv50_fb.o nvc0_fb.o \
Expand Down
46 changes: 46 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_drv.h
Original file line number Diff line number Diff line change
Expand Up @@ -359,6 +359,51 @@ struct nouveau_gpio_engine {
void (*irq_enable)(struct drm_device *, enum dcb_gpio_tag, bool on);
};

struct nouveau_pm_voltage_level {
u8 voltage;
u8 vid;
};

struct nouveau_pm_voltage {
bool supported;
u8 vid_mask;

struct nouveau_pm_voltage_level *level;
int nr_level;
};

#define NOUVEAU_PM_MAX_LEVEL 8
struct nouveau_pm_level {
struct device_attribute dev_attr;
char name[32];
int id;

u32 core;
u32 memory;
u32 shader;
u32 unk05;

u8 voltage;
u8 fanspeed;
};

struct nouveau_pm_engine {
struct nouveau_pm_voltage voltage;
struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
int nr_perflvl;

struct nouveau_pm_level boot;
struct nouveau_pm_level *cur;

int (*clock_get)(struct drm_device *, u32 id);
void *(*clock_pre)(struct drm_device *, u32 id, int khz);
void (*clock_set)(struct drm_device *, void *);
int (*voltage_get)(struct drm_device *);
int (*voltage_set)(struct drm_device *, int voltage);
int (*fanspeed_get)(struct drm_device *);
int (*fanspeed_set)(struct drm_device *, int fanspeed);
};

struct nouveau_engine {
struct nouveau_instmem_engine instmem;
struct nouveau_mc_engine mc;
Expand All @@ -368,6 +413,7 @@ struct nouveau_engine {
struct nouveau_fifo_engine fifo;
struct nouveau_display_engine display;
struct nouveau_gpio_engine gpio;
struct nouveau_pm_engine pm;
};

struct nouveau_pll_vals {
Expand Down
159 changes: 159 additions & 0 deletions trunk/drivers/gpu/drm/nouveau/nouveau_perf.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,159 @@
/*
* Copyright 2010 Red Hat Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors: Ben Skeggs
*/

#include "drmP.h"

#include "nouveau_drv.h"
#include "nouveau_pm.h"

void
nouveau_perf_init(struct drm_device *dev)
{
struct drm_nouveau_private *dev_priv = dev->dev_private;
struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
struct nvbios *bios = &dev_priv->vbios;
struct bit_entry P;
u8 version, headerlen, recordlen, entries;
u8 *perf, *entry;
int vid, i;

if (bios->type == NVBIOS_BIT) {
if (bit_table(dev, 'P', &P))
return;

if (P.version != 1 && P.version != 2) {
NV_WARN(dev, "unknown perf for BIT P %d\n", P.version);
return;
}

perf = ROMPTR(bios, P.data[0]);
version = perf[0];
headerlen = perf[1];
if (version < 0x40) {
recordlen = perf[3] + (perf[4] * perf[5]);
entries = perf[2];
} else {
recordlen = perf[2] + (perf[3] * perf[4]);
entries = perf[5];
}
} else {
if (bios->data[bios->offset + 6] < 0x27) {
NV_DEBUG(dev, "BMP version too old for perf\n");
return;
}

perf = ROMPTR(bios, bios->data[bios->offset + 0x94]);
if (!perf) {
NV_DEBUG(dev, "perf table pointer invalid\n");
return;
}

version = perf[1];
headerlen = perf[0];
recordlen = perf[3];
entries = perf[2];
}

entry = perf + headerlen;
for (i = 0; i < entries; i++) {
struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];

if (entry[0] == 0xff) {
entry += recordlen;
continue;
}

switch (version) {
case 0x12:
case 0x13:
case 0x15:
perflvl->fanspeed = entry[55];
perflvl->voltage = entry[56];
perflvl->core = ROM32(entry[1]) / 100;
perflvl->memory = ROM32(entry[5]) / 100;
break;
case 0x21:
case 0x23:
case 0x24:
perflvl->fanspeed = entry[4];
perflvl->voltage = entry[5];
perflvl->core = ROM16(entry[6]);
perflvl->memory = ROM16(entry[11]);
break;
case 0x25:
perflvl->fanspeed = entry[4];
perflvl->voltage = entry[5];
perflvl->core = ROM16(entry[6]);
perflvl->shader = ROM16(entry[10]);
perflvl->memory = ROM16(entry[12]);
break;
case 0x30:
case 0x35:
perflvl->fanspeed = entry[6];
perflvl->voltage = entry[7];
perflvl->core = ROM16(entry[8]);
perflvl->shader = ROM16(entry[10]);
perflvl->memory = ROM16(entry[12]);
/*XXX: confirm on 0x35 */
perflvl->unk05 = ROM16(entry[16]);
break;
case 0x40:
#define subent(n) entry[perf[2] + ((n) * perf[3])]
perflvl->fanspeed = 0; /*XXX*/
perflvl->voltage = 0; /*XXX: entry[2] */;
perflvl->core = ROM16(subent(0)) & 0xfff;
perflvl->shader = ROM16(subent(1)) & 0xfff;
perflvl->memory = ROM16(subent(2)) & 0xfff;
break;
}

/* convert MHz -> KHz, it's more convenient */
perflvl->core *= 1000;
perflvl->memory *= 1000;
perflvl->shader *= 1000;
perflvl->unk05 *= 1000;

/* make sure vid is valid */
if (pm->voltage.supported && perflvl->voltage) {
vid = nouveau_volt_vid_lookup(dev, perflvl->voltage);
if (vid < 0) {
NV_DEBUG(dev, "drop perflvl %d, bad vid\n", i);
entry += recordlen;
continue;
}
}

snprintf(perflvl->name, sizeof(perflvl->name),
"performance_level_%d", i);
perflvl->id = i;
pm->nr_perflvl++;

entry += recordlen;
}
}

void
nouveau_perf_fini(struct drm_device *dev)
{
}
Loading

0 comments on commit 6c44a48

Please sign in to comment.