drm/nouveau/pm: embed timings into perflvl structs
authorBen Skeggs <bskeggs@redhat.com>
Tue, 17 Jan 2012 23:02:28 +0000 (09:02 +1000)
committerBen Skeggs <bskeggs@redhat.com>
Tue, 13 Mar 2012 07:08:06 +0000 (17:08 +1000)
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Signed-off-by: Martin Peres <martin.peres@labri.fr>
drivers/gpu/drm/nouveau/nouveau_drv.h
drivers/gpu/drm/nouveau/nouveau_mem.c
drivers/gpu/drm/nouveau/nouveau_perf.c
drivers/gpu/drm/nouveau/nouveau_pm.c

index a8344c3..531e435 100644 (file)
@@ -491,8 +491,11 @@ struct nouveau_pm_level {
        char name[32];
        int id;
 
-       u32 core;
        u32 memory;
+       u16 memscript;
+       struct nouveau_pm_memtiming timing;
+
+       u32 core;
        u32 shader;
        u32 rop;
        u32 copy;
@@ -507,9 +510,6 @@ struct nouveau_pm_level {
        u32 volt_min; /* microvolts */
        u32 volt_max;
        u8  fanspeed;
-
-       u16 memscript;
-       struct nouveau_pm_memtiming *timing;
 };
 
 struct nouveau_pm_temp_sensor_constants {
@@ -542,7 +542,6 @@ struct nouveau_pm_engine {
        struct nouveau_pm_threshold_temp threshold_temp;
        struct nouveau_pm_fan fan;
 
-       struct nouveau_pm_memtiming boot_timing;
        struct nouveau_pm_level boot;
        struct nouveau_pm_level *cur;
 
@@ -914,10 +913,10 @@ extern int  nouveau_mem_init_agp(struct drm_device *);
 extern int  nouveau_mem_reset_agp(struct drm_device *);
 extern void nouveau_mem_close(struct drm_device *);
 extern bool nouveau_mem_flags_valid(struct drm_device *, u32 tile_flags);
+extern int  nouveau_mem_timing_calc(struct drm_device *, u32 freq,
+                                   struct nouveau_pm_memtiming *);
 extern void nouveau_mem_timing_read(struct drm_device *,
                                    struct nouveau_pm_memtiming *);
-extern struct nouveau_pm_memtiming *
-nouveau_mem_timing(struct drm_device *, u32 freq);
 extern int nouveau_mem_vbios_type(struct drm_device *);
 extern struct nouveau_tile_reg *nv10_mem_set_tiling(
        struct drm_device *dev, uint32_t addr, uint32_t size,
index 33de772..cc46811 100644 (file)
@@ -812,63 +812,59 @@ nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq,
        return 0;
 }
 
-struct nouveau_pm_memtiming *
-nouveau_mem_timing(struct drm_device *dev, u32 freq)
+int
+nouveau_mem_timing_calc(struct drm_device *dev, u32 freq,
+                       struct nouveau_pm_memtiming *t)
 {
        struct drm_nouveau_private *dev_priv = dev->dev_private;
        struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
-       struct nouveau_pm_memtiming *boot = &pm->boot_timing;
-       struct nouveau_pm_memtiming *t;
+       struct nouveau_pm_memtiming *boot = &pm->boot.timing;
        struct nouveau_pm_tbl_entry *e;
        u8 ver, len, *ptr;
        int ret;
 
        ptr = nouveau_perf_timing(dev, freq, &ver, &len);
-       if (!ptr || ptr[0] == 0x00)
-               return boot;
+       if (!ptr || ptr[0] == 0x00) {
+               *t = *boot;
+               return 0;
+       }
        e = (struct nouveau_pm_tbl_entry *)ptr;
 
-       t = kzalloc(sizeof(*t), GFP_KERNEL);
-       if (t) {
-               t->tCWL = boot->tCWL;
-
-               switch (dev_priv->card_type) {
-               case NV_40:
-                       ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t);
-                       break;
-               case NV_50:
-                       ret = nv50_mem_timing_calc(dev, freq, e, len, boot, t);
-                       break;
-               case NV_C0:
-                       ret = nvc0_mem_timing_calc(dev, freq, e, len, boot, t);
-                       break;
-               default:
-                       ret = -ENODEV;
-                       break;
-               }
+       t->tCWL = boot->tCWL;
 
-               switch (dev_priv->vram_type * !ret) {
-               case NV_MEM_TYPE_GDDR3:
-                       ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
-                       break;
-               case NV_MEM_TYPE_GDDR5:
-                       ret = nouveau_mem_gddr5_mr(dev, freq, e, len, boot, t);
-                       break;
-               case NV_MEM_TYPE_DDR2:
-                       ret = nouveau_mem_ddr2_mr(dev, freq, e, len, boot, t);
-                       break;
-               case NV_MEM_TYPE_DDR3:
-                       ret = nouveau_mem_ddr3_mr(dev, freq, e, len, boot, t);
-                       break;
-               }
+       switch (dev_priv->card_type) {
+       case NV_40:
+               ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t);
+               break;
+       case NV_50:
+               ret = nv50_mem_timing_calc(dev, freq, e, len, boot, t);
+               break;
+       case NV_C0:
+               ret = nvc0_mem_timing_calc(dev, freq, e, len, boot, t);
+               break;
+       default:
+               ret = -ENODEV;
+               break;
+       }
 
-               if (ret) {
-                       kfree(t);
-                       t = NULL;
-               }
+       switch (dev_priv->vram_type * !ret) {
+       case NV_MEM_TYPE_GDDR3:
+               ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t);
+               break;
+       case NV_MEM_TYPE_GDDR5:
+               ret = nouveau_mem_gddr5_mr(dev, freq, e, len, boot, t);
+               break;
+       case NV_MEM_TYPE_DDR2:
+               ret = nouveau_mem_ddr2_mr(dev, freq, e, len, boot, t);
+               break;
+       case NV_MEM_TYPE_DDR3:
+               ret = nouveau_mem_ddr3_mr(dev, freq, e, len, boot, t);
+               break;
+       default:
+               ret = -EINVAL;
        }
 
-       return t;
+       return ret;
 }
 
 void
index 150ff41..bd6071f 100644 (file)
@@ -293,7 +293,7 @@ nouveau_perf_init(struct drm_device *dev)
        struct nouveau_pm_engine *pm = &dev_priv->engine.pm;
        struct nvbios *bios = &dev_priv->vbios;
        u8 *perf, ver, hdr, cnt, len;
-       int vid, i = -1;
+       int ret, vid, i = -1;
 
        if (bios->type == NVBIOS_BMP && bios->data[bios->offset + 6] < 0x25) {
                legacy_perf_init(dev);
@@ -384,7 +384,12 @@ nouveau_perf_init(struct drm_device *dev)
                }
 
                /* get the corresponding memory timings */
-               perflvl->timing = nouveau_mem_timing(dev, perflvl->memory);
+               ret = nouveau_mem_timing_calc(dev, perflvl->memory,
+                                                 &perflvl->timing);
+               if (ret) {
+                       NV_DEBUG(dev, "perflvl %d, bad timing: %d\n", i, ret);
+                       continue;
+               }
 
                snprintf(perflvl->name, sizeof(perflvl->name),
                         "performance_level_%d", i);
index 4f299f4..7c25567 100644 (file)
@@ -245,7 +245,7 @@ nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
 static void
 nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
 {
-       char c[16], s[16], v[32], f[16], t[16], m[16];
+       char c[16], s[16], v[32], f[16], m[16];
 
        c[0] = '\0';
        if (perflvl->core)
@@ -273,11 +273,7 @@ nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len)
        if (perflvl->fanspeed)
                snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed);
 
-       t[0] = '\0';
-       if (perflvl->timing)
-               snprintf(t, sizeof(t), " timing %d", perflvl->timing->id);
-
-       snprintf(ptr, len, "%s%s%s%s%s%s\n", c, s, m, t, v, f);
+       snprintf(ptr, len, "%s%s%s%s%s\n", c, s, m,  v, f);
 }
 
 static ssize_t