Commit 9a782488 authored by Roy Spliet's avatar Roy Spliet Committed by Ben Skeggs

drm/nouveau/pm: add initial NV3x/NVCx memtiming support, improve other cards

NV30: Create framework for memtm
NV50: Improve reg creation,
NV50: Use P.version instead of card codename/stepping,
NVC0: Initial memtiming code for Fermi,
Renamed regs for consistency,
Overall redesign to improve readability,
Avoid kfree on null-pointer
Signed-off-by: default avatarRoy Spliet <r.spliet@student.tudelft.nl>
parent 1cb70b30
...@@ -429,17 +429,43 @@ struct nouveau_pm_voltage { ...@@ -429,17 +429,43 @@ struct nouveau_pm_voltage {
struct nouveau_pm_memtiming { struct nouveau_pm_memtiming {
int id; int id;
u32 reg_100220; u32 reg_0; /* 0x10f290 on Fermi, 0x100220 for older */
u32 reg_100224; u32 reg_1;
u32 reg_100228; u32 reg_2;
u32 reg_10022c; u32 reg_3;
u32 reg_100230; u32 reg_4;
u32 reg_100234; u32 reg_5;
u32 reg_100238; u32 reg_6;
u32 reg_10023c; u32 reg_7;
u32 reg_100240; u32 reg_8;
}; };
struct nouveau_pm_tbl_header{
u8 version;
u8 header_len;
u8 entry_cnt;
u8 entry_len;
};
struct nouveau_pm_tbl_entry{
u8 tUNK_0, tUNK_1, tUNK_2;
u8 tRP; /* Byte 3 */
u8 empty_4;
u8 tRAS; /* Byte 5 */
u8 empty_6;
u8 tRFC; /* Byte 7 */
u8 empty_8;
u8 tRC; /* Byte 9 */
u8 tUNK_10, tUNK_11, tUNK_12, tUNK_13, tUNK_14;
u8 empty_15,empty_16,empty_17;
u8 tUNK_18, tUNK_19, tUNK_20, tUNK_21;
};
/* nouveau_mem.c */
void nv30_mem_timing_entry(struct drm_device *dev, struct nouveau_pm_tbl_header *hdr,
struct nouveau_pm_tbl_entry *e, uint8_t magic_number,
struct nouveau_pm_memtiming *timing);
#define NOUVEAU_PM_MAX_LEVEL 8 #define NOUVEAU_PM_MAX_LEVEL 8
struct nouveau_pm_level { struct nouveau_pm_level {
struct device_attribute dev_attr; struct device_attribute dev_attr;
...@@ -648,7 +674,6 @@ struct drm_nouveau_private { ...@@ -648,7 +674,6 @@ struct drm_nouveau_private {
enum nouveau_card_type card_type; enum nouveau_card_type card_type;
/* exact chipset, derived from NV_PMC_BOOT_0 */ /* exact chipset, derived from NV_PMC_BOOT_0 */
int chipset; int chipset;
int stepping;
int flags; int flags;
void __iomem *mmio; void __iomem *mmio;
......
This diff is collapsed.
...@@ -185,6 +185,8 @@ nouveau_perf_init(struct drm_device *dev) ...@@ -185,6 +185,8 @@ nouveau_perf_init(struct drm_device *dev)
struct nouveau_pm_engine *pm = &dev_priv->engine.pm; struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
struct nvbios *bios = &dev_priv->vbios; struct nvbios *bios = &dev_priv->vbios;
struct bit_entry P; struct bit_entry P;
struct nouveau_pm_memtimings *memtimings = &pm->memtimings;
struct nouveau_pm_tbl_header mt_hdr;
u8 version, headerlen, recordlen, entries; u8 version, headerlen, recordlen, entries;
u8 *perf, *entry; u8 *perf, *entry;
int vid, i; int vid, i;
...@@ -232,6 +234,22 @@ nouveau_perf_init(struct drm_device *dev) ...@@ -232,6 +234,22 @@ nouveau_perf_init(struct drm_device *dev)
} }
entry = perf + headerlen; entry = perf + headerlen;
/* For version 0x15, initialize memtiming table */
if(version == 0x15) {
memtimings->timing =
kcalloc(entries, sizeof(*memtimings->timing), GFP_KERNEL);
if(!memtimings) {
NV_WARN(dev,"Could not allocate memtiming table\n");
return;
}
mt_hdr.entry_cnt = entries;
mt_hdr.entry_len = 14;
mt_hdr.version = version;
mt_hdr.header_len = 4;
}
for (i = 0; i < entries; i++) { for (i = 0; i < entries; i++) {
struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl]; struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl];
...@@ -321,7 +339,11 @@ nouveau_perf_init(struct drm_device *dev) ...@@ -321,7 +339,11 @@ nouveau_perf_init(struct drm_device *dev)
} }
/* get the corresponding memory timings */ /* get the corresponding memory timings */
if (version > 0x15) { if (version == 0x15) {
memtimings->timing[i].id = i;
nv30_mem_timing_entry(dev,&mt_hdr,(struct nouveau_pm_tbl_entry*) &entry[41],0,&memtimings->timing[i]);
perflvl->timing = &memtimings->timing[i];
} else if (version > 0x15) {
/* last 3 args are for < 0x40, ignored for >= 0x40 */ /* last 3 args are for < 0x40, ignored for >= 0x40 */
perflvl->timing = perflvl->timing =
nouveau_perf_timing(dev, &P, nouveau_perf_timing(dev, &P,
......
...@@ -1028,13 +1028,11 @@ int nouveau_load(struct drm_device *dev, unsigned long flags) ...@@ -1028,13 +1028,11 @@ int nouveau_load(struct drm_device *dev, unsigned long flags)
/* Time to determine the card architecture */ /* Time to determine the card architecture */
reg0 = nv_rd32(dev, NV03_PMC_BOOT_0); reg0 = nv_rd32(dev, NV03_PMC_BOOT_0);
dev_priv->stepping = 0; /* XXX: add stepping for pre-NV10? */
/* We're dealing with >=NV10 */ /* We're dealing with >=NV10 */
if ((reg0 & 0x0f000000) > 0) { if ((reg0 & 0x0f000000) > 0) {
/* Bit 27-20 contain the architecture in hex */ /* Bit 27-20 contain the architecture in hex */
dev_priv->chipset = (reg0 & 0xff00000) >> 20; dev_priv->chipset = (reg0 & 0xff00000) >> 20;
dev_priv->stepping = (reg0 & 0xff);
/* NV04 or NV05 */ /* NV04 or NV05 */
} else if ((reg0 & 0xff00fff0) == 0x20004000) { } else if ((reg0 & 0xff00fff0) == 0x20004000) {
if (reg0 & 0x00f00000) if (reg0 & 0x00f00000)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment