linux/drivers/gpu/drm/nouveau/nouveau_pm.h
<<
>>
Prefs
   1/*
   2 * Copyright 2010 Red Hat Inc.
   3 *
   4 * Permission is hereby granted, free of charge, to any person obtaining a
   5 * copy of this software and associated documentation files (the "Software"),
   6 * to deal in the Software without restriction, including without limitation
   7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
   8 * and/or sell copies of the Software, and to permit persons to whom the
   9 * Software is furnished to do so, subject to the following conditions:
  10 *
  11 * The above copyright notice and this permission notice shall be included in
  12 * all copies or substantial portions of the Software.
  13 *
  14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
  18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  20 * OTHER DEALINGS IN THE SOFTWARE.
  21 *
  22 * Authors: Ben Skeggs
  23 */
  24
  25#ifndef __NOUVEAU_PM_H__
  26#define __NOUVEAU_PM_H__
  27
  28#include <subdev/bios/pll.h>
  29#include <subdev/clock.h>
  30
  31struct nouveau_pm_voltage_level {
  32        u32 voltage; /* microvolts */
  33        u8  vid;
  34};
  35
  36struct nouveau_pm_voltage {
  37        bool supported;
  38        u8 version;
  39        u8 vid_mask;
  40
  41        struct nouveau_pm_voltage_level *level;
  42        int nr_level;
  43};
  44
  45/* Exclusive upper limits */
  46#define NV_MEM_CL_DDR2_MAX 8
  47#define NV_MEM_WR_DDR2_MAX 9
  48#define NV_MEM_CL_DDR3_MAX 17
  49#define NV_MEM_WR_DDR3_MAX 17
  50#define NV_MEM_CL_GDDR3_MAX 16
  51#define NV_MEM_WR_GDDR3_MAX 18
  52#define NV_MEM_CL_GDDR5_MAX 21
  53#define NV_MEM_WR_GDDR5_MAX 20
  54
  55struct nouveau_pm_memtiming {
  56        int id;
  57
  58        u32 reg[9];
  59        u32 mr[4];
  60
  61        u8 tCWL;
  62
  63        u8 odt;
  64        u8 drive_strength;
  65};
  66
  67struct nouveau_pm_tbl_header {
  68        u8 version;
  69        u8 header_len;
  70        u8 entry_cnt;
  71        u8 entry_len;
  72};
  73
  74struct nouveau_pm_tbl_entry {
  75        u8 tWR;
  76        u8 tWTR;
  77        u8 tCL;
  78        u8 tRC;
  79        u8 empty_4;
  80        u8 tRFC;        /* Byte 5 */
  81        u8 empty_6;
  82        u8 tRAS;        /* Byte 7 */
  83        u8 empty_8;
  84        u8 tRP;         /* Byte 9 */
  85        u8 tRCDRD;
  86        u8 tRCDWR;
  87        u8 tRRD;
  88        u8 tUNK_13;
  89        u8 RAM_FT1;             /* 14, a bitmask of random RAM features */
  90        u8 empty_15;
  91        u8 tUNK_16;
  92        u8 empty_17;
  93        u8 tUNK_18;
  94        u8 tCWL;
  95        u8 tUNK_20, tUNK_21;
  96};
  97
  98struct nouveau_pm_profile;
  99struct nouveau_pm_profile_func {
 100        void (*destroy)(struct nouveau_pm_profile *);
 101        void (*init)(struct nouveau_pm_profile *);
 102        void (*fini)(struct nouveau_pm_profile *);
 103        struct nouveau_pm_level *(*select)(struct nouveau_pm_profile *);
 104};
 105
 106struct nouveau_pm_profile {
 107        const struct nouveau_pm_profile_func *func;
 108        struct list_head head;
 109        char name[8];
 110};
 111
 112#define NOUVEAU_PM_MAX_LEVEL 8
 113struct nouveau_pm_level {
 114        struct nouveau_pm_profile profile;
 115        struct device_attribute dev_attr;
 116        char name[32];
 117        int id;
 118
 119        struct nouveau_pm_memtiming timing;
 120        u32 memory;
 121        u16 memscript;
 122
 123        u32 core;
 124        u32 shader;
 125        u32 rop;
 126        u32 copy;
 127        u32 daemon;
 128        u32 vdec;
 129        u32 dom6;
 130        u32 unka0;      /* nva3:nvc0 */
 131        u32 hub01;      /* nvc0- */
 132        u32 hub06;      /* nvc0- */
 133        u32 hub07;      /* nvc0- */
 134
 135        u32 volt_min; /* microvolts */
 136        u32 volt_max;
 137        u8  fanspeed;
 138};
 139
 140struct nouveau_pm_temp_sensor_constants {
 141        u16 offset_constant;
 142        s16 offset_mult;
 143        s16 offset_div;
 144        s16 slope_mult;
 145        s16 slope_div;
 146};
 147
 148struct nouveau_pm_threshold_temp {
 149        s16 critical;
 150        s16 down_clock;
 151};
 152
 153struct nouveau_pm {
 154        struct drm_device *dev;
 155
 156        struct nouveau_pm_voltage voltage;
 157        struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL];
 158        int nr_perflvl;
 159        struct nouveau_pm_temp_sensor_constants sensor_constants;
 160        struct nouveau_pm_threshold_temp threshold_temp;
 161
 162        struct nouveau_pm_profile *profile_ac;
 163        struct nouveau_pm_profile *profile_dc;
 164        struct nouveau_pm_profile *profile;
 165        struct list_head profiles;
 166
 167        struct nouveau_pm_level boot;
 168        struct nouveau_pm_level *cur;
 169
 170        struct device *hwmon;
 171        struct notifier_block acpi_nb;
 172
 173        int  (*clocks_get)(struct drm_device *, struct nouveau_pm_level *);
 174        void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *);
 175        int (*clocks_set)(struct drm_device *, void *);
 176
 177        int (*voltage_get)(struct drm_device *);
 178        int (*voltage_set)(struct drm_device *, int voltage);
 179};
 180
 181static inline struct nouveau_pm *
 182nouveau_pm(struct drm_device *dev)
 183{
 184        return nouveau_drm(dev)->pm;
 185}
 186
 187struct nouveau_mem_exec_func {
 188        struct drm_device *dev;
 189        void (*precharge)(struct nouveau_mem_exec_func *);
 190        void (*refresh)(struct nouveau_mem_exec_func *);
 191        void (*refresh_auto)(struct nouveau_mem_exec_func *, bool);
 192        void (*refresh_self)(struct nouveau_mem_exec_func *, bool);
 193        void (*wait)(struct nouveau_mem_exec_func *, u32 nsec);
 194        u32  (*mrg)(struct nouveau_mem_exec_func *, int mr);
 195        void (*mrs)(struct nouveau_mem_exec_func *, int mr, u32 data);
 196        void (*clock_set)(struct nouveau_mem_exec_func *);
 197        void (*timing_set)(struct nouveau_mem_exec_func *);
 198        void *priv;
 199};
 200
 201/* nouveau_mem.c */
 202int  nouveau_mem_exec(struct nouveau_mem_exec_func *,
 203                      struct nouveau_pm_level *);
 204
 205/* nouveau_pm.c */
 206int  nouveau_pm_init(struct drm_device *dev);
 207void nouveau_pm_fini(struct drm_device *dev);
 208void nouveau_pm_resume(struct drm_device *dev);
 209extern const struct nouveau_pm_profile_func nouveau_pm_static_profile_func;
 210void nouveau_pm_trigger(struct drm_device *dev);
 211
 212/* nouveau_volt.c */
 213void nouveau_volt_init(struct drm_device *);
 214void nouveau_volt_fini(struct drm_device *);
 215int  nouveau_volt_vid_lookup(struct drm_device *, int voltage);
 216int  nouveau_volt_lvl_lookup(struct drm_device *, int vid);
 217int  nouveau_voltage_gpio_get(struct drm_device *);
 218int  nouveau_voltage_gpio_set(struct drm_device *, int voltage);
 219
 220/* nouveau_perf.c */
 221void nouveau_perf_init(struct drm_device *);
 222void nouveau_perf_fini(struct drm_device *);
 223u8 *nouveau_perf_rammap(struct drm_device *, u32 freq, u8 *ver,
 224                        u8 *hdr, u8 *cnt, u8 *len);
 225u8 *nouveau_perf_ramcfg(struct drm_device *, u32 freq, u8 *ver, u8 *len);
 226u8 *nouveau_perf_timing(struct drm_device *, u32 freq, u8 *ver, u8 *len);
 227
 228/* nouveau_mem.c */
 229void nouveau_mem_timing_init(struct drm_device *);
 230void nouveau_mem_timing_fini(struct drm_device *);
 231
 232/* nv04_pm.c */
 233int nv04_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
 234void *nv04_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
 235int nv04_pm_clocks_set(struct drm_device *, void *);
 236
 237/* nv40_pm.c */
 238int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
 239void *nv40_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
 240int nv40_pm_clocks_set(struct drm_device *, void *);
 241int nv40_pm_pwm_get(struct drm_device *, int, u32 *, u32 *);
 242int nv40_pm_pwm_set(struct drm_device *, int, u32, u32);
 243
 244/* nv50_pm.c */
 245int nv50_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
 246void *nv50_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
 247int nv50_pm_clocks_set(struct drm_device *, void *);
 248int nv50_pm_pwm_get(struct drm_device *, int, u32 *, u32 *);
 249int nv50_pm_pwm_set(struct drm_device *, int, u32, u32);
 250
 251/* nva3_pm.c */
 252int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
 253void *nva3_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
 254int nva3_pm_clocks_set(struct drm_device *, void *);
 255
 256/* nvc0_pm.c */
 257int nvc0_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *);
 258void *nvc0_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *);
 259int nvc0_pm_clocks_set(struct drm_device *, void *);
 260
 261/* nouveau_mem.c */
 262int  nouveau_mem_timing_calc(struct drm_device *, u32 freq,
 263                             struct nouveau_pm_memtiming *);
 264void nouveau_mem_timing_read(struct drm_device *,
 265                             struct nouveau_pm_memtiming *);
 266
 267static inline int
 268nva3_calc_pll(struct drm_device *dev, struct nvbios_pll *pll, u32 freq,
 269              int *N, int *fN, int *M, int *P)
 270{
 271        struct nouveau_device *device = nouveau_dev(dev);
 272        struct nouveau_clock *clk = nouveau_clock(device);
 273        struct nouveau_pll_vals pv;
 274        int ret;
 275
 276        ret = clk->pll_calc(clk, pll, freq, &pv);
 277        *N = pv.N1;
 278        *M = pv.M1;
 279        *P = pv.log2P;
 280        return ret;
 281}
 282
 283#endif
 284