diff options
author | Martin Peres <martin.peres@free.fr> | 2015-10-15 01:36:18 +0200 |
---|---|---|
committer | Martin Peres <martin.peres@free.fr> | 2015-10-15 01:39:16 +0200 |
commit | 5c2116436d35247e4133509ed0146b135069706a (patch) | |
tree | 5dc271a91cbb52710060c6079e4b309c6347b728 | |
parent | 392c5d11201ac38737602ab5c5bc448268b02557 (diff) |
WIP power sensorpwr_sensor
-rwxr-xr-x[-rw-r--r--] | drm/nouveau/include/nvkm/core/device.h | 83 | ||||
-rwxr-xr-x[-rw-r--r--] | drm/nouveau/include/nvkm/subdev/bios/extdev.h | 2 | ||||
-rwxr-xr-x[-rw-r--r--] | drm/nouveau/include/nvkm/subdev/i2c.h | 31 | ||||
-rwxr-xr-x[-rw-r--r--] | drm/nouveau/nvkm/core/subdev.c | 83 | ||||
-rwxr-xr-x[-rw-r--r--] | drm/nouveau/nvkm/engine/device/base.c | 125 | ||||
-rwxr-xr-x[-rw-r--r--] | drm/nouveau/nvkm/engine/device/priv.h | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | drm/nouveau/nvkm/subdev/Kbuild | 1 | ||||
-rwxr-xr-x[-rw-r--r--] | drm/nouveau/nvkm/subdev/bios/Kbuild | 1 | ||||
-rwxr-xr-x | drm/nouveau/nvkm/subdev/bios/iccsense.c | 102 | ||||
-rwxr-xr-x | drm/nouveau/nvkm/subdev/iccsense/Kbuild | 3 | ||||
-rwxr-xr-x | drm/nouveau/nvkm/subdev/iccsense/base.c | 37 | ||||
-rwxr-xr-x | drm/nouveau/nvkm/subdev/iccsense/gf100.c | 38 | ||||
-rwxr-xr-x | drm/nouveau/nvkm/subdev/iccsense/ina3221.c | 146 | ||||
-rwxr-xr-x | drm/nouveau/nvkm/subdev/iccsense/priv.h | 20 |
14 files changed, 531 insertions, 142 deletions
diff --git a/drm/nouveau/include/nvkm/core/device.h b/drm/nouveau/include/nvkm/core/device.h index 8f760002..13e5cc17 100644..100755 --- a/drm/nouveau/include/nvkm/core/device.h +++ b/drm/nouveau/include/nvkm/core/device.h @@ -22,6 +22,7 @@ enum nvkm_devidx { NVKM_SUBDEV_BAR, NVKM_SUBDEV_PMU, NVKM_SUBDEV_VOLT, + NVKM_SUBDEV_ICCSENSE, NVKM_SUBDEV_THERM, NVKM_SUBDEV_CLK, @@ -109,6 +110,7 @@ struct nvkm_device { struct nvkm_gpio *gpio; struct nvkm_i2c *i2c; struct nvkm_subdev *ibus; + struct nvkm_iccsense *iccsense; struct nvkm_instmem *imem; struct nvkm_ltc *ltc; struct nvkm_mc *mc; @@ -165,46 +167,47 @@ struct nvkm_device_quirk { struct nvkm_device_chip { const char *name; - int (*bar )(struct nvkm_device *, int idx, struct nvkm_bar **); - int (*bios )(struct nvkm_device *, int idx, struct nvkm_bios **); - int (*bus )(struct nvkm_device *, int idx, struct nvkm_bus **); - int (*clk )(struct nvkm_device *, int idx, struct nvkm_clk **); - int (*devinit)(struct nvkm_device *, int idx, struct nvkm_devinit **); - int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **); - int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **); - int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **); - int (*i2c )(struct nvkm_device *, int idx, struct nvkm_i2c **); - int (*ibus )(struct nvkm_device *, int idx, struct nvkm_subdev **); - int (*imem )(struct nvkm_device *, int idx, struct nvkm_instmem **); - int (*ltc )(struct nvkm_device *, int idx, struct nvkm_ltc **); - int (*mc )(struct nvkm_device *, int idx, struct nvkm_mc **); - int (*mmu )(struct nvkm_device *, int idx, struct nvkm_mmu **); - int (*mxm )(struct nvkm_device *, int idx, struct nvkm_subdev **); - int (*pci )(struct nvkm_device *, int idx, struct nvkm_pci **); - int (*pmu )(struct nvkm_device *, int idx, struct nvkm_pmu **); - int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **); - int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **); - int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **); - - int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*ce[3] )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*cipher )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*disp )(struct nvkm_device *, int idx, struct nvkm_disp **); - int (*dma )(struct nvkm_device *, int idx, struct nvkm_dma **); - int (*fifo )(struct nvkm_device *, int idx, struct nvkm_fifo **); - int (*gr )(struct nvkm_device *, int idx, struct nvkm_gr **); - int (*ifb )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*me )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*mpeg )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*msenc )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*mspdec )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*msppp )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*msvld )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **); - int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*sw )(struct nvkm_device *, int idx, struct nvkm_sw **); - int (*vic )(struct nvkm_device *, int idx, struct nvkm_engine **); - int (*vp )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*bar )(struct nvkm_device *, int idx, struct nvkm_bar **); + int (*bios )(struct nvkm_device *, int idx, struct nvkm_bios **); + int (*bus )(struct nvkm_device *, int idx, struct nvkm_bus **); + int (*clk )(struct nvkm_device *, int idx, struct nvkm_clk **); + int (*devinit )(struct nvkm_device *, int idx, struct nvkm_devinit **); + int (*fb )(struct nvkm_device *, int idx, struct nvkm_fb **); + int (*fuse )(struct nvkm_device *, int idx, struct nvkm_fuse **); + int (*gpio )(struct nvkm_device *, int idx, struct nvkm_gpio **); + int (*i2c )(struct nvkm_device *, int idx, struct nvkm_i2c **); + int (*ibus )(struct nvkm_device *, int idx, struct nvkm_subdev **); + int (*iccsense)(struct nvkm_device *, int idx, struct nvkm_iccsense **); + int (*imem )(struct nvkm_device *, int idx, struct nvkm_instmem **); + int (*ltc )(struct nvkm_device *, int idx, struct nvkm_ltc **); + int (*mc )(struct nvkm_device *, int idx, struct nvkm_mc **); + int (*mmu )(struct nvkm_device *, int idx, struct nvkm_mmu **); + int (*mxm )(struct nvkm_device *, int idx, struct nvkm_subdev **); + int (*pci )(struct nvkm_device *, int idx, struct nvkm_pci **); + int (*pmu )(struct nvkm_device *, int idx, struct nvkm_pmu **); + int (*therm )(struct nvkm_device *, int idx, struct nvkm_therm **); + int (*timer )(struct nvkm_device *, int idx, struct nvkm_timer **); + int (*volt )(struct nvkm_device *, int idx, struct nvkm_volt **); + + int (*bsp )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*ce[3] )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*cipher )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*disp )(struct nvkm_device *, int idx, struct nvkm_disp **); + int (*dma )(struct nvkm_device *, int idx, struct nvkm_dma **); + int (*fifo )(struct nvkm_device *, int idx, struct nvkm_fifo **); + int (*gr )(struct nvkm_device *, int idx, struct nvkm_gr **); + int (*ifb )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*me )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*mpeg )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*msenc )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*mspdec )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*msppp )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*msvld )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*pm )(struct nvkm_device *, int idx, struct nvkm_pm **); + int (*sec )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*sw )(struct nvkm_device *, int idx, struct nvkm_sw **); + int (*vic )(struct nvkm_device *, int idx, struct nvkm_engine **); + int (*vp )(struct nvkm_device *, int idx, struct nvkm_engine **); }; struct nvkm_device *nvkm_device_find(u64 name); diff --git a/drm/nouveau/include/nvkm/subdev/bios/extdev.h b/drm/nouveau/include/nvkm/subdev/bios/extdev.h index 6d3bedc6..174b1614 100644..100755 --- a/drm/nouveau/include/nvkm/subdev/bios/extdev.h +++ b/drm/nouveau/include/nvkm/subdev/bios/extdev.h @@ -5,6 +5,8 @@ enum nvbios_extdev_type { NVBIOS_EXTDEV_VT1103M = 0x40, NVBIOS_EXTDEV_PX3540 = 0x41, NVBIOS_EXTDEV_VT1105M = 0x42, /* or close enough... */ + NVBIOS_EXTDEV_INA219 = 0x4c, + NVBIOS_EXTDEV_INA3221 = 0x4e, NVBIOS_EXTDEV_ADT7473 = 0x70, /* can also be a LM64 */ NVBIOS_EXTDEV_HDCP_EEPROM = 0x90, NVBIOS_EXTDEV_NONE = 0xff, diff --git a/drm/nouveau/include/nvkm/subdev/i2c.h b/drm/nouveau/include/nvkm/subdev/i2c.h index 6b6224db..d4aa5429 100644..100755 --- a/drm/nouveau/include/nvkm/subdev/i2c.h +++ b/drm/nouveau/include/nvkm/subdev/i2c.h @@ -108,6 +108,22 @@ nvkm_rdi2cr(struct i2c_adapter *adap, u8 addr, u8 reg) } static inline int +nv_rd16i2cr(struct i2c_adapter *adap, u8 addr, u8 reg) +{ + u8 val[2]; + struct i2c_msg msgs[] = { + { .addr = addr, .flags = 0, .len = 1, .buf = ® }, + { .addr = addr, .flags = I2C_M_RD, .len = 2, .buf = val }, + }; + + int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs)); + if (ret != 2) + return -EIO; + + return val[0] << 8 | val[1]; +} + +static inline int nvkm_wri2cr(struct i2c_adapter *adap, u8 addr, u8 reg, u8 val) { u8 buf[2] = { reg, val }; @@ -122,6 +138,21 @@ nvkm_wri2cr(struct i2c_adapter *adap, u8 addr, u8 reg, u8 val) return 0; } +static inline int +nv_wri162cr(struct i2c_adapter *adap, u8 addr, u8 reg, u16 val) +{ + u8 buf[3] = { reg, val >> 8, val & 0xff}; + struct i2c_msg msgs[] = { + { .addr = addr, .flags = 0, .len = 3, .buf = buf }, + }; + + int ret = i2c_transfer(adap, msgs, ARRAY_SIZE(msgs)); + if (ret != 1) + return -EIO; + + return 0; +} + static inline bool nvkm_probe_i2c(struct i2c_adapter *adap, u8 addr) { diff --git a/drm/nouveau/nvkm/core/subdev.c b/drm/nouveau/nvkm/core/subdev.c index 7de98470..370041f6 100644..100755 --- a/drm/nouveau/nvkm/core/subdev.c +++ b/drm/nouveau/nvkm/core/subdev.c @@ -29,47 +29,48 @@ static struct lock_class_key nvkm_subdev_lock_class[NVKM_SUBDEV_NR]; const char * nvkm_subdev_name[NVKM_SUBDEV_NR] = { - [NVKM_SUBDEV_BAR ] = "bar", - [NVKM_SUBDEV_VBIOS ] = "bios", - [NVKM_SUBDEV_BUS ] = "bus", - [NVKM_SUBDEV_CLK ] = "clk", - [NVKM_SUBDEV_DEVINIT] = "devinit", - [NVKM_SUBDEV_FB ] = "fb", - [NVKM_SUBDEV_FUSE ] = "fuse", - [NVKM_SUBDEV_GPIO ] = "gpio", - [NVKM_SUBDEV_I2C ] = "i2c", - [NVKM_SUBDEV_IBUS ] = "priv", - [NVKM_SUBDEV_INSTMEM] = "imem", - [NVKM_SUBDEV_LTC ] = "ltc", - [NVKM_SUBDEV_MC ] = "mc", - [NVKM_SUBDEV_MMU ] = "mmu", - [NVKM_SUBDEV_MXM ] = "mxm", - [NVKM_SUBDEV_PCI ] = "pci", - [NVKM_SUBDEV_PMU ] = "pmu", - [NVKM_SUBDEV_THERM ] = "therm", - [NVKM_SUBDEV_TIMER ] = "tmr", - [NVKM_SUBDEV_VOLT ] = "volt", - [NVKM_ENGINE_BSP ] = "bsp", - [NVKM_ENGINE_CE0 ] = "ce0", - [NVKM_ENGINE_CE1 ] = "ce1", - [NVKM_ENGINE_CE2 ] = "ce2", - [NVKM_ENGINE_CIPHER ] = "cipher", - [NVKM_ENGINE_DISP ] = "disp", - [NVKM_ENGINE_DMAOBJ ] = "dma", - [NVKM_ENGINE_FIFO ] = "fifo", - [NVKM_ENGINE_GR ] = "gr", - [NVKM_ENGINE_IFB ] = "ifb", - [NVKM_ENGINE_ME ] = "me", - [NVKM_ENGINE_MPEG ] = "mpeg", - [NVKM_ENGINE_MSENC ] = "msenc", - [NVKM_ENGINE_MSPDEC ] = "mspdec", - [NVKM_ENGINE_MSPPP ] = "msppp", - [NVKM_ENGINE_MSVLD ] = "msvld", - [NVKM_ENGINE_PM ] = "pm", - [NVKM_ENGINE_SEC ] = "sec", - [NVKM_ENGINE_SW ] = "sw", - [NVKM_ENGINE_VIC ] = "vic", - [NVKM_ENGINE_VP ] = "vp", + [NVKM_SUBDEV_BAR ] = "bar", + [NVKM_SUBDEV_VBIOS ] = "bios", + [NVKM_SUBDEV_BUS ] = "bus", + [NVKM_SUBDEV_CLK ] = "clk", + [NVKM_SUBDEV_DEVINIT ] = "devinit", + [NVKM_SUBDEV_FB ] = "fb", + [NVKM_SUBDEV_FUSE ] = "fuse", + [NVKM_SUBDEV_GPIO ] = "gpio", + [NVKM_SUBDEV_I2C ] = "i2c", + [NVKM_SUBDEV_IBUS ] = "priv", + [NVKM_SUBDEV_ICCSENSE] = "iccsense", + [NVKM_SUBDEV_INSTMEM ] = "imem", + [NVKM_SUBDEV_LTC ] = "ltc", + [NVKM_SUBDEV_MC ] = "mc", + [NVKM_SUBDEV_MMU ] = "mmu", + [NVKM_SUBDEV_MXM ] = "mxm", + [NVKM_SUBDEV_PCI ] = "pci", + [NVKM_SUBDEV_PMU ] = "pmu", + [NVKM_SUBDEV_THERM ] = "therm", + [NVKM_SUBDEV_TIMER ] = "tmr", + [NVKM_SUBDEV_VOLT ] = "volt", + [NVKM_ENGINE_BSP ] = "bsp", + [NVKM_ENGINE_CE0 ] = "ce0", + [NVKM_ENGINE_CE1 ] = "ce1", + [NVKM_ENGINE_CE2 ] = "ce2", + [NVKM_ENGINE_CIPHER ] = "cipher", + [NVKM_ENGINE_DISP ] = "disp", + [NVKM_ENGINE_DMAOBJ ] = "dma", + [NVKM_ENGINE_FIFO ] = "fifo", + [NVKM_ENGINE_GR ] = "gr", + [NVKM_ENGINE_IFB ] = "ifb", + [NVKM_ENGINE_ME ] = "me", + [NVKM_ENGINE_MPEG ] = "mpeg", + [NVKM_ENGINE_MSENC ] = "msenc", + [NVKM_ENGINE_MSPDEC ] = "mspdec", + [NVKM_ENGINE_MSPPP ] = "msppp", + [NVKM_ENGINE_MSVLD ] = "msvld", + [NVKM_ENGINE_PM ] = "pm", + [NVKM_ENGINE_SEC ] = "sec", + [NVKM_ENGINE_SW ] = "sw", + [NVKM_ENGINE_VIC ] = "vic", + [NVKM_ENGINE_VP ] = "vp", }; void diff --git a/drm/nouveau/nvkm/engine/device/base.c b/drm/nouveau/nvkm/engine/device/base.c index bbc9824a..549ed712 100644..100755 --- a/drm/nouveau/nvkm/engine/device/base.c +++ b/drm/nouveau/nvkm/engine/device/base.c @@ -1701,6 +1701,7 @@ nve6_chipset = { .gpio = gk104_gpio_new, .i2c = gk104_i2c_new, .ibus = gk104_ibus_new, + .iccsense = gf100_iccsense_new, .imem = nv50_instmem_new, .ltc = gk104_ltc_new, .mc = gf100_mc_new, @@ -2072,26 +2073,27 @@ nvkm_device_subdev(struct nvkm_device *device, int index) switch (index) { #define _(n,p,m) case NVKM_SUBDEV_##n: if (p) return (m); break - _(BAR , device->bar , &device->bar->subdev); - _(VBIOS , device->bios , &device->bios->subdev); - _(BUS , device->bus , &device->bus->subdev); - _(CLK , device->clk , &device->clk->subdev); - _(DEVINIT, device->devinit, &device->devinit->subdev); - _(FB , device->fb , &device->fb->subdev); - _(FUSE , device->fuse , &device->fuse->subdev); - _(GPIO , device->gpio , &device->gpio->subdev); - _(I2C , device->i2c , &device->i2c->subdev); - _(IBUS , device->ibus , device->ibus); - _(INSTMEM, device->imem , &device->imem->subdev); - _(LTC , device->ltc , &device->ltc->subdev); - _(MC , device->mc , &device->mc->subdev); - _(MMU , device->mmu , &device->mmu->subdev); - _(MXM , device->mxm , device->mxm); - _(PCI , device->pci , &device->pci->subdev); - _(PMU , device->pmu , &device->pmu->subdev); - _(THERM , device->therm , &device->therm->subdev); - _(TIMER , device->timer , &device->timer->subdev); - _(VOLT , device->volt , &device->volt->subdev); + _(BAR , device->bar , &device->bar->subdev); + _(VBIOS , device->bios , &device->bios->subdev); + _(BUS , device->bus , &device->bus->subdev); + _(CLK , device->clk , &device->clk->subdev); + _(DEVINIT , device->devinit , &device->devinit->subdev); + _(FB , device->fb , &device->fb->subdev); + _(FUSE , device->fuse , &device->fuse->subdev); + _(GPIO , device->gpio , &device->gpio->subdev); + _(I2C , device->i2c , &device->i2c->subdev); + _(IBUS , device->ibus , device->ibus); + _(ICCSENSE, device->iccsense, &device->iccsense->subdev); + _(INSTMEM , device->imem , &device->imem->subdev); + _(LTC , device->ltc , &device->ltc->subdev); + _(MC , device->mc , &device->mc->subdev); + _(MMU , device->mmu , &device->mmu->subdev); + _(MXM , device->mxm , device->mxm); + _(PCI , device->pci , &device->pci->subdev); + _(PMU , device->pmu , &device->pmu->subdev); + _(THERM , device->therm , &device->therm->subdev); + _(TIMER , device->timer , &device->timer->subdev); + _(VOLT , device->volt , &device->volt->subdev); #undef _ default: engine = nvkm_device_engine(device, index); @@ -2517,47 +2519,48 @@ nvkm_device_ctor(const struct nvkm_device_func *func, } \ break switch (i) { - _(NVKM_SUBDEV_BAR , bar); - _(NVKM_SUBDEV_VBIOS , bios); - _(NVKM_SUBDEV_BUS , bus); - _(NVKM_SUBDEV_CLK , clk); - _(NVKM_SUBDEV_DEVINIT, devinit); - _(NVKM_SUBDEV_FB , fb); - _(NVKM_SUBDEV_FUSE , fuse); - _(NVKM_SUBDEV_GPIO , gpio); - _(NVKM_SUBDEV_I2C , i2c); - _(NVKM_SUBDEV_IBUS , ibus); - _(NVKM_SUBDEV_INSTMEM, imem); - _(NVKM_SUBDEV_LTC , ltc); - _(NVKM_SUBDEV_MC , mc); - _(NVKM_SUBDEV_MMU , mmu); - _(NVKM_SUBDEV_MXM , mxm); - _(NVKM_SUBDEV_PCI , pci); - _(NVKM_SUBDEV_PMU , pmu); - _(NVKM_SUBDEV_THERM , therm); - _(NVKM_SUBDEV_TIMER , timer); - _(NVKM_SUBDEV_VOLT , volt); - _(NVKM_ENGINE_BSP , bsp); - _(NVKM_ENGINE_CE0 , ce[0]); - _(NVKM_ENGINE_CE1 , ce[1]); - _(NVKM_ENGINE_CE2 , ce[2]); - _(NVKM_ENGINE_CIPHER , cipher); - _(NVKM_ENGINE_DISP , disp); - _(NVKM_ENGINE_DMAOBJ , dma); - _(NVKM_ENGINE_FIFO , fifo); - _(NVKM_ENGINE_GR , gr); - _(NVKM_ENGINE_IFB , ifb); - _(NVKM_ENGINE_ME , me); - _(NVKM_ENGINE_MPEG , mpeg); - _(NVKM_ENGINE_MSENC , msenc); - _(NVKM_ENGINE_MSPDEC , mspdec); - _(NVKM_ENGINE_MSPPP , msppp); - _(NVKM_ENGINE_MSVLD , msvld); - _(NVKM_ENGINE_PM , pm); - _(NVKM_ENGINE_SEC , sec); - _(NVKM_ENGINE_SW , sw); - _(NVKM_ENGINE_VIC , vic); - _(NVKM_ENGINE_VP , vp); + _(NVKM_SUBDEV_BAR , bar); + _(NVKM_SUBDEV_VBIOS , bios); + _(NVKM_SUBDEV_BUS , bus); + _(NVKM_SUBDEV_CLK , clk); + _(NVKM_SUBDEV_DEVINIT , devinit); + _(NVKM_SUBDEV_FB , fb); + _(NVKM_SUBDEV_FUSE , fuse); + _(NVKM_SUBDEV_GPIO , gpio); + _(NVKM_SUBDEV_I2C , i2c); + _(NVKM_SUBDEV_IBUS , ibus); + _(NVKM_SUBDEV_ICCSENSE, iccsense); + _(NVKM_SUBDEV_INSTMEM , imem); + _(NVKM_SUBDEV_LTC , ltc); + _(NVKM_SUBDEV_MC , mc); + _(NVKM_SUBDEV_MMU , mmu); + _(NVKM_SUBDEV_MXM , mxm); + _(NVKM_SUBDEV_PCI , pci); + _(NVKM_SUBDEV_PMU , pmu); + _(NVKM_SUBDEV_THERM , therm); + _(NVKM_SUBDEV_TIMER , timer); + _(NVKM_SUBDEV_VOLT , volt); + _(NVKM_ENGINE_BSP , bsp); + _(NVKM_ENGINE_CE0 , ce[0]); + _(NVKM_ENGINE_CE1 , ce[1]); + _(NVKM_ENGINE_CE2 , ce[2]); + _(NVKM_ENGINE_CIPHER , cipher); + _(NVKM_ENGINE_DISP , disp); + _(NVKM_ENGINE_DMAOBJ , dma); + _(NVKM_ENGINE_FIFO , fifo); + _(NVKM_ENGINE_GR , gr); + _(NVKM_ENGINE_IFB , ifb); + _(NVKM_ENGINE_ME , me); + _(NVKM_ENGINE_MPEG , mpeg); + _(NVKM_ENGINE_MSENC , msenc); + _(NVKM_ENGINE_MSPDEC , mspdec); + _(NVKM_ENGINE_MSPPP , msppp); + _(NVKM_ENGINE_MSVLD , msvld); + _(NVKM_ENGINE_PM , pm); + _(NVKM_ENGINE_SEC , sec); + _(NVKM_ENGINE_SW , sw); + _(NVKM_ENGINE_VIC , vic); + _(NVKM_ENGINE_VP , vp); default: WARN_ON(1); continue; diff --git a/drm/nouveau/nvkm/engine/device/priv.h b/drm/nouveau/nvkm/engine/device/priv.h index ed3ad2c3..49981a11 100644..100755 --- a/drm/nouveau/nvkm/engine/device/priv.h +++ b/drm/nouveau/nvkm/engine/device/priv.h @@ -12,6 +12,7 @@ #include <subdev/gpio.h> #include <subdev/i2c.h> #include <subdev/ibus.h> +#include <subdev/iccsense.h> #include <subdev/instmem.h> #include <subdev/ltc.h> #include <subdev/mc.h> diff --git a/drm/nouveau/nvkm/subdev/Kbuild b/drm/nouveau/nvkm/subdev/Kbuild index ee2c38f5..63d0587c 100644..100755 --- a/drm/nouveau/nvkm/subdev/Kbuild +++ b/drm/nouveau/nvkm/subdev/Kbuild @@ -8,6 +8,7 @@ include $(src)/nvkm/subdev/fuse/Kbuild include $(src)/nvkm/subdev/gpio/Kbuild include $(src)/nvkm/subdev/i2c/Kbuild include $(src)/nvkm/subdev/ibus/Kbuild +include $(src)/nvkm/subdev/iccsense/Kbuild include $(src)/nvkm/subdev/instmem/Kbuild include $(src)/nvkm/subdev/ltc/Kbuild include $(src)/nvkm/subdev/mc/Kbuild diff --git a/drm/nouveau/nvkm/subdev/bios/Kbuild b/drm/nouveau/nvkm/subdev/bios/Kbuild index 64730d5e..dbcb0ef2 100644..100755 --- a/drm/nouveau/nvkm/subdev/bios/Kbuild +++ b/drm/nouveau/nvkm/subdev/bios/Kbuild @@ -10,6 +10,7 @@ nvkm-y += nvkm/subdev/bios/extdev.o nvkm-y += nvkm/subdev/bios/fan.o nvkm-y += nvkm/subdev/bios/gpio.o nvkm-y += nvkm/subdev/bios/i2c.o +nvkm-y += nvkm/subdev/bios/iccsense.o nvkm-y += nvkm/subdev/bios/image.o nvkm-y += nvkm/subdev/bios/init.o nvkm-y += nvkm/subdev/bios/mxm.o diff --git a/drm/nouveau/nvkm/subdev/bios/iccsense.c b/drm/nouveau/nvkm/subdev/bios/iccsense.c new file mode 100755 index 00000000..e18793dd --- /dev/null +++ b/drm/nouveau/nvkm/subdev/bios/iccsense.c @@ -0,0 +1,102 @@ +/* + * Copyright 2015 Martin Peres + * + * 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: Martin Peres + */ +#include <subdev/bios.h> +#include <subdev/bios/bit.h> +#include <subdev/bios/iccsense.h> + +static u16 +nvbios_iccsense_table(struct nvkm_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, + u8 *len) +{ + struct bit_entry bit_P; + u16 iccsense = 0x0000; + + if (!bit_entry(bios, 'P', &bit_P)) { + if (bit_P.version == 2 && bit_P.length >= 0x2c) + iccsense = nvbios_rd16(bios, bit_P.offset + 0x28); + + if (iccsense) { + *ver = nvbios_rd08(bios, iccsense + 0); + switch (*ver) { + case 0x10: + case 0x20: + *hdr = nvbios_rd08(bios, iccsense + 1); + *len = nvbios_rd08(bios, iccsense + 2); + *cnt = nvbios_rd08(bios, iccsense + 3); + return iccsense; + default: + break; + } + } + } + + return 0x0000; +} + +int +nvbios_iccsense_parse(struct nvkm_bios *bios, struct nvbios_iccsense *iccsense) +{ + u8 ver, hdr, cnt, len, i; + u16 table, entry; + + table = nvbios_iccsense_table(bios, &ver, &hdr, &cnt, &len); + if (!table) + return -EINVAL; + + if (cnt > 3) { + nvkm_info(&bios->subdev, + "iccsense: Got more entries than expected (%d)\n", + cnt); + cnt = 3; + } + + iccsense->nr_entry = 0; + i = 0; + while (i < cnt) { + entry = table + hdr + i * len; + + switch(ver) { + case 0x10: + iccsense->rail[iccsense->nr_entry].extdev_id = + nvbios_rd08(bios, entry + 0x2); + iccsense->rail[iccsense->nr_entry].resistor_mohm = + nvbios_rd08(bios, entry + 0x3); + break; + case 0x20: + iccsense->rail[iccsense->nr_entry].extdev_id = + nvbios_rd08(bios, entry + 0x1); + iccsense->rail[iccsense->nr_entry].resistor_mohm = + nvbios_rd08(bios, entry + 0x5); + break; + }; + + /* only store entries where the resistor is > 0 */ + if (iccsense->rail[iccsense->nr_entry].resistor_mohm > 0) + iccsense->nr_entry++; + + i++; + } + + return 0; +} diff --git a/drm/nouveau/nvkm/subdev/iccsense/Kbuild b/drm/nouveau/nvkm/subdev/iccsense/Kbuild new file mode 100755 index 00000000..fd8afd87 --- /dev/null +++ b/drm/nouveau/nvkm/subdev/iccsense/Kbuild @@ -0,0 +1,3 @@ +nvkm-y += nvkm/subdev/iccsense/base.o +nvkm-y += nvkm/subdev/iccsense/gf100.o +nvkm-y += nvkm/subdev/iccsense/ina3221.o diff --git a/drm/nouveau/nvkm/subdev/iccsense/base.c b/drm/nouveau/nvkm/subdev/iccsense/base.c new file mode 100755 index 00000000..287cf53f --- /dev/null +++ b/drm/nouveau/nvkm/subdev/iccsense/base.c @@ -0,0 +1,37 @@ +/* + * Copyright 2015 Martin Peres + * + * 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: Martin Peres + */ +#include "priv.h" + +void +nvkm_iccsense_ctor(const struct nvkm_subdev_func *subdev, + const struct nvkm_iccsense_driver *driver, + struct nvkm_device *device, int index, + struct nvkm_iccsense *iccsense) +{ + nvkm_subdev_ctor(subdev, device, index, 0, &iccsense->subdev); + iccsense->driver = driver; + + nvkm_debug(&iccsense->subdev, "using %s\n", driver->name); +} + diff --git a/drm/nouveau/nvkm/subdev/iccsense/gf100.c b/drm/nouveau/nvkm/subdev/iccsense/gf100.c new file mode 100755 index 00000000..ace8c52a --- /dev/null +++ b/drm/nouveau/nvkm/subdev/iccsense/gf100.c @@ -0,0 +1,38 @@ +/* + * Copyright 2015 Martin Peres + * + * 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: Martin Peres + */ +#include "priv.h" + +int +gf100_iccsense_new(struct nvkm_device *device, int index, + struct nvkm_iccsense **piccsense) +{ + if (!nvkm_iccsense_ina3221_new(device, index, piccsense)) + return 0; + + /* parse the list of devices */ + + /* call the right _new function */ + + return -EINVAL; +} diff --git a/drm/nouveau/nvkm/subdev/iccsense/ina3221.c b/drm/nouveau/nvkm/subdev/iccsense/ina3221.c new file mode 100755 index 00000000..83b910b1 --- /dev/null +++ b/drm/nouveau/nvkm/subdev/iccsense/ina3221.c @@ -0,0 +1,146 @@ +/* + * Copyright 2015 Martin Peres + * + * 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: Martin Peres + */ +#include "priv.h" + +#include <subdev/i2c.h> +#include <subdev/bios.h> +#include <subdev/bios/extdev.h> +#include <subdev/bios/iccsense.h> + +struct iccsense_ina3221_priv { + struct nvkm_iccsense base; + + struct nvkm_i2c_bus *i2c_bus; + u8 rails_mohm[3]; +}; + +static int +ina3221_poll_power_lane(struct i2c_adapter *adap, uint8_t id, uint8_t shunt) +{ + int vbus, vshunt; + + if (id > 2) + return -EINVAL; + + if (shunt == 0) + return 0; + + vshunt = nv_rd16i2cr(adap, 0x40, 1 + (id * 2)); + vbus = nv_rd16i2cr(adap, 0x40, 2 + (id * 2)); + + if (vshunt < 0 || vbus < 0) + return -EINVAL; + + return vbus * vshunt * 5 / shunt; +} + + +static int +ina3221_pwr_get(struct nvkm_iccsense *iccsense) +{ + struct iccsense_ina3221_priv *priv; + uint32_t pwr = 0; + int ret, i; + + priv = (struct iccsense_ina3221_priv*) iccsense; + + for(i = 0; i < 3; i++) { + int lane = ina3221_poll_power_lane(&priv->i2c_bus->i2c, i, + priv->rails_mohm[i]); + if (lane >= 0) + pwr += lane; + } + + return pwr; +} + +static int +ina3221_init(struct nvkm_subdev *subdev) +{ + return 0; +} + +static void * +ina3221_dtor(struct nvkm_subdev *subdev) +{ + return nvkm_iccsense(subdev); +} + +static const struct nvkm_subdev_func +ina3221_iccsense = { + .dtor = ina3221_dtor, + .init = ina3221_init, +}; + +static const struct nvkm_iccsense_driver +iccsense_ina3221_driver = { + .name = "INA3221", + .pwr_get = ina3221_pwr_get, +}; + +int +nvkm_iccsense_ina3221_new(struct nvkm_device *device, int index, + struct nvkm_iccsense **piccsense) +{ + struct nvkm_bios *bios = device->bios; + struct nvbios_iccsense iccsense_tbl; + struct iccsense_ina3221_priv *priv; + struct nvkm_i2c *i2c = device->i2c; + struct nvbios_extdev_func extdev; + struct nvkm_i2c_bus *i2c_bus; + int i; + + /* Look for an INA3221 */ + if (nvbios_extdev_find(bios, NVBIOS_EXTDEV_INA3221, &extdev)) + return -EINVAL; + + /* check if the bus exists */ + /* TODO: Actually check if the device is present and if not, iterate + * to the next bus! + */ + i2c_bus = nvkm_i2c_bus_find(i2c, 2 /*extdev.bus*/); + if (!i2c_bus) + return -EINVAL; + + /* check that we do have a iccsense table */ + if (nvbios_iccsense_parse(bios, &iccsense_tbl)) + return -EINVAL; + + /* parse the iccsense table */ + if (!(*piccsense = kzalloc(sizeof(struct iccsense_ina3221_priv), GFP_KERNEL))) + return -ENOMEM; + priv = (struct iccsense_ina3221_priv*) *piccsense; + nvkm_iccsense_ctor(&ina3221_iccsense, &iccsense_ina3221_driver, device, index, *piccsense); + + priv->i2c_bus = i2c_bus; + + /* copy the shunt resistors' values to the right lane index */ + for (i = 0; i < iccsense_tbl.nr_entry; i++) { + struct pwr_rail_t r = iccsense_tbl.rail[i]; + priv->rails_mohm[r.extdev_id] = r.resistor_mohm; + nvkm_debug(&priv->base.subdev, "rail[%i] = %i mOhm\n", r.extdev_id, r.resistor_mohm); + } + + return 0; +} diff --git a/drm/nouveau/nvkm/subdev/iccsense/priv.h b/drm/nouveau/nvkm/subdev/iccsense/priv.h new file mode 100755 index 00000000..53ddfcdd --- /dev/null +++ b/drm/nouveau/nvkm/subdev/iccsense/priv.h @@ -0,0 +1,20 @@ +#ifndef __NVKM_ICCSENSE_PRIV_H__ +#define __NVKM_ICCSENSE_PRIV_H__ +#define nvkm_iccsense(p) container_of((p), struct nvkm_iccsense, subdev) +#include <subdev/iccsense.h> + +void +nvkm_iccsense_ctor(const struct nvkm_subdev_func *, + const struct nvkm_iccsense_driver *, + struct nvkm_device *, int , struct nvkm_iccsense *); + +struct nvkm_iccsense_driver { + const char *name; + int (*pwr_get)(struct nvkm_iccsense *); +}; + +int +nvkm_iccsense_ina3221_new(struct nvkm_device *device, int index, + struct nvkm_iccsense **piccsense); + +#endif |