diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/core/engine')
51 files changed, 2687 insertions, 653 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index 4c72571655ad..9135b25a29d0 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/base.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c @@ -29,7 +29,7 @@ #include <core/class.h> -#include <engine/device.h> +#include "priv.h" static DEFINE_MUTEX(nv_devices_mutex); static LIST_HEAD(nv_devices); @@ -75,7 +75,9 @@ static const u64 disable_map[] = { [NVDEV_SUBDEV_BAR] = NV_DEVICE_DISABLE_CORE, [NVDEV_SUBDEV_VOLT] = NV_DEVICE_DISABLE_CORE, [NVDEV_SUBDEV_THERM] = NV_DEVICE_DISABLE_CORE, + [NVDEV_SUBDEV_PWR] = NV_DEVICE_DISABLE_CORE, [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_DISABLE_CORE, + [NVDEV_ENGINE_PERFMON] = NV_DEVICE_DISABLE_CORE, [NVDEV_ENGINE_FIFO] = NV_DEVICE_DISABLE_FIFO, [NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO, [NVDEV_ENGINE_GR] = NV_DEVICE_DISABLE_GRAPH, @@ -87,7 +89,7 @@ static const u64 disable_map[] = { [NVDEV_ENGINE_PPP] = NV_DEVICE_DISABLE_PPP, [NVDEV_ENGINE_COPY0] = NV_DEVICE_DISABLE_COPY0, [NVDEV_ENGINE_COPY1] = NV_DEVICE_DISABLE_COPY1, - [NVDEV_ENGINE_UNK1C1] = NV_DEVICE_DISABLE_UNK1C1, + [NVDEV_ENGINE_VIC] = NV_DEVICE_DISABLE_VIC, [NVDEV_ENGINE_VENC] = NV_DEVICE_DISABLE_VENC, [NVDEV_ENGINE_DISP] = NV_DEVICE_DISABLE_DISP, [NVDEV_SUBDEV_NR] = 0, @@ -119,10 +121,12 @@ nouveau_devobj_ctor(struct nouveau_object *parent, return -ENODEV; } - ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, NULL, + ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, + nouveau_control_oclass, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_FIFO) | - (1ULL << NVDEV_ENGINE_DISP), &devobj); + (1ULL << NVDEV_ENGINE_DISP) | + (1ULL << NVDEV_ENGINE_PERFMON), &devobj); *pobject = nv_object(devobj); if (ret) return ret; @@ -158,22 +162,29 @@ nouveau_devobj_ctor(struct nouveau_object *parent, iounmap(map); /* determine chipset and derive architecture from it */ - if ((boot0 & 0x0f000000) > 0) { - device->chipset = (boot0 & 0xff00000) >> 20; - switch (device->chipset & 0xf0) { - case 0x10: device->card_type = NV_10; break; - case 0x20: device->card_type = NV_20; break; - case 0x30: device->card_type = NV_30; break; - case 0x40: - case 0x60: device->card_type = NV_40; break; - case 0x50: - case 0x80: - case 0x90: - case 0xa0: device->card_type = NV_50; break; - case 0xc0: device->card_type = NV_C0; break; - case 0xd0: device->card_type = NV_D0; break; - case 0xe0: - case 0xf0: device->card_type = NV_E0; break; + if ((boot0 & 0x1f000000) > 0) { + device->chipset = (boot0 & 0x1ff00000) >> 20; + switch (device->chipset & 0x1f0) { + case 0x010: { + if (0x461 & (1 << (device->chipset & 0xf))) + device->card_type = NV_10; + else + device->card_type = NV_11; + break; + } + case 0x020: device->card_type = NV_20; break; + case 0x030: device->card_type = NV_30; break; + case 0x040: + case 0x060: device->card_type = NV_40; break; + case 0x050: + case 0x080: + case 0x090: + case 0x0a0: device->card_type = NV_50; break; + case 0x0c0: device->card_type = NV_C0; break; + case 0x0d0: device->card_type = NV_D0; break; + case 0x0e0: + case 0x0f0: + case 0x100: device->card_type = NV_E0; break; default: break; } @@ -188,7 +199,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent, switch (device->card_type) { case NV_04: ret = nv04_identify(device); break; - case NV_10: ret = nv10_identify(device); break; + case NV_10: + case NV_11: ret = nv10_identify(device); break; case NV_20: ret = nv20_identify(device); break; case NV_30: ret = nv30_identify(device); break; case NV_40: ret = nv40_identify(device); break; @@ -212,7 +224,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent, nv_info(device, "Family : NV%02X\n", device->card_type); /* determine frequency of timing crystal */ - if ( device->chipset < 0x17 || + if ( device->card_type <= NV_10 || device->chipset < 0x17 || (device->chipset >= 0x20 && device->chipset < 0x25)) strap &= 0x00000040; else diff --git a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c new file mode 100644 index 000000000000..4b69bf56ed01 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c @@ -0,0 +1,144 @@ +/* + * Copyright 2013 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 <bskeggs@redhat.com> + */ + +#include <core/object.h> +#include <core/class.h> + +#include <subdev/clock.h> + +#include "priv.h" + +static int +nouveau_control_mthd_pstate_info(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + struct nouveau_clock *clk = nouveau_clock(object); + struct nv_control_pstate_info *args = data; + + if (size < sizeof(*args)) + return -EINVAL; + + if (clk) { + args->count = clk->state_nr; + args->ustate = clk->ustate; + args->pstate = clk->pstate; + } else { + args->count = 0; + args->ustate = NV_CONTROL_PSTATE_INFO_USTATE_DISABLE; + args->pstate = NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN; + } + + return 0; +} + +static int +nouveau_control_mthd_pstate_attr(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + struct nouveau_clock *clk = nouveau_clock(object); + struct nv_control_pstate_attr *args = data; + struct nouveau_clocks *domain; + struct nouveau_pstate *pstate; + struct nouveau_cstate *cstate; + int i = 0, j = -1; + u32 lo, hi; + + if ((size < sizeof(*args)) || !clk || + (args->state >= 0 && args->state >= clk->state_nr)) + return -EINVAL; + domain = clk->domains; + + while (domain->name != nv_clk_src_max) { + if (domain->mname && ++j == args->index) + break; + domain++; + } + + if (domain->name == nv_clk_src_max) + return -EINVAL; + + if (args->state != NV_CONTROL_PSTATE_ATTR_STATE_CURRENT) { + list_for_each_entry(pstate, &clk->states, head) { + if (i++ == args->state) + break; + } + + lo = pstate->base.domain[domain->name]; + hi = lo; + list_for_each_entry(cstate, &pstate->list, head) { + lo = min(lo, cstate->domain[domain->name]); + hi = max(hi, cstate->domain[domain->name]); + } + + args->state = pstate->pstate; + } else { + lo = max(clk->read(clk, domain->name), 0); + hi = lo; + } + + snprintf(args->name, sizeof(args->name), "%s", domain->mname); + snprintf(args->unit, sizeof(args->unit), "MHz"); + args->min = lo / domain->mdiv; + args->max = hi / domain->mdiv; + + args->index = 0; + while ((++domain)->name != nv_clk_src_max) { + if (domain->mname) { + args->index = ++j; + break; + } + } + + return 0; +} + +static int +nouveau_control_mthd_pstate_user(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + struct nouveau_clock *clk = nouveau_clock(object); + struct nv_control_pstate_user *args = data; + + if (size < sizeof(*args) || !clk) + return -EINVAL; + + return nouveau_clock_ustate(clk, args->state); +} + +struct nouveau_oclass +nouveau_control_oclass[] = { + { .handle = NV_CONTROL_CLASS, + .ofuncs = &nouveau_object_ofuncs, + .omthds = (struct nouveau_omthds[]) { + { NV_CONTROL_PSTATE_INFO, + NV_CONTROL_PSTATE_INFO, nouveau_control_mthd_pstate_info }, + { NV_CONTROL_PSTATE_ATTR, + NV_CONTROL_PSTATE_ATTR, nouveau_control_mthd_pstate_attr }, + { NV_CONTROL_PSTATE_USER, + NV_CONTROL_PSTATE_USER, nouveau_control_mthd_pstate_user }, + {}, + }, + }, + {} +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c index a0284cf09c0f..dbd2dde7b7e7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv04.c @@ -50,15 +50,15 @@ nv04_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv04_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv04_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv04_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -68,15 +68,15 @@ nv04_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv05_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv04_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv04_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv04_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv04_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv04_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv04_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv04_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c index 1b7809a095c3..6e03dd6abeea 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv10.c @@ -52,10 +52,10 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; @@ -69,15 +69,15 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -88,15 +88,15 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -107,15 +107,15 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv1a_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -126,15 +126,15 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv10_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv10_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -145,15 +145,15 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -164,15 +164,15 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv1a_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv1a_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -183,15 +183,15 @@ nv10_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv10_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c index 12a4005fa619..dcde53b9f07f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv20.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv20.c @@ -53,15 +53,15 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv20_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv20_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv20_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -72,15 +72,15 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -91,15 +91,15 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv25_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -110,15 +110,15 @@ nv20_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv25_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv25_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv2a_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c index cef0f1ea4c21..7b8662ef4f59 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv30.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv30.c @@ -53,15 +53,15 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -72,15 +72,15 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv04_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv04_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv35_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv35_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; break; @@ -91,15 +91,15 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv30_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv30_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv30_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; @@ -111,15 +111,15 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv20_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv36_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv36_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv35_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; @@ -131,15 +131,15 @@ nv30_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_I2C ] = &nv04_i2c_oclass; device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv04_clock_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv10_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv04_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv10_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv10_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv04_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv17_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv17_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv34_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv31_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c index 1719cb0ee595..c8c41e93695e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c @@ -35,6 +35,7 @@ #include <subdev/fb.h> #include <subdev/instmem.h> #include <subdev/vm.h> +#include <subdev/volt.h> #include <engine/device.h> #include <engine/dmaobj.h> @@ -43,6 +44,7 @@ #include <engine/graph.h> #include <engine/mpeg.h> #include <engine/disp.h> +#include <engine/perfmon.h> int nv40_identify(struct nouveau_device *device) @@ -56,18 +58,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x41: device->cname = "NV41"; @@ -77,18 +81,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv41_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x42: device->cname = "NV42"; @@ -98,18 +104,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv41_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x43: device->cname = "NV43"; @@ -119,18 +127,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv41_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv41_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x45: device->cname = "NV45"; @@ -140,18 +150,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv40_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv40_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv04_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x47: device->cname = "G70"; @@ -161,18 +173,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv47_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv47_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x49: device->cname = "G71"; @@ -182,18 +196,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv49_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv49_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x4b: device->cname = "G73"; @@ -203,18 +219,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv04_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv40_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv49_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv49_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv41_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x44: device->cname = "NV44"; @@ -224,18 +242,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv44_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv44_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x46: device->cname = "G72"; @@ -245,18 +265,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x4a: device->cname = "NV44A"; @@ -266,18 +288,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv44_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv44_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x4c: device->cname = "C61"; @@ -287,18 +311,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x4e: device->cname = "C51"; @@ -308,18 +334,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv4e_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv4e_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x63: device->cname = "C73"; @@ -329,18 +357,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x67: device->cname = "C67"; @@ -350,18 +380,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; case 0x68: device->cname = "C68"; @@ -371,18 +403,20 @@ nv40_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv40_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv40_therm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv1a_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv44_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv31_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv44_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv31_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv46_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv46_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv40_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv44_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv04_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv40_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv10_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv40_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv10_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv40_graph_oclass; - device->oclass[NVDEV_ENGINE_MPEG ] = &nv40_mpeg_oclass; + device->oclass[NVDEV_ENGINE_MPEG ] = &nv44_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv04_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv40_perfmon_oclass; break; default: nv_fatal(device, "unknown Curie chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c index ffc18b80c5d9..db139827047c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c @@ -36,6 +36,8 @@ #include <subdev/instmem.h> #include <subdev/vm.h> #include <subdev/bar.h> +#include <subdev/pwr.h> +#include <subdev/volt.h> #include <engine/device.h> #include <engine/dmaobj.h> @@ -49,6 +51,7 @@ #include <engine/ppp.h> #include <engine/copy.h> #include <engine/disp.h> +#include <engine/perfmon.h> int nv50_identify(struct nouveau_device *device) @@ -59,257 +62,277 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv50_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv50_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv50_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv50_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv50_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv50_mpeg_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv50_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv50_perfmon_oclass; break; case 0x84: device->cname = "G84"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x86: device->cname = "G86"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x92: device->cname = "G92"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv50_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv84_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x94: device->cname = "G94"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv94_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x96: device->cname = "G96"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv50_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv94_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0x98: device->cname = "G98"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0xa0: device->cname = "G200"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv50_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nv84_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv84_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv84_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv84_bsp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva0_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0xaa: device->cname = "MCP77/MCP78"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvaa_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0xac: device->cname = "MCP79/MCP7A"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nv50_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nv94_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = nv84_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nv84_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nv50_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvaa_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass; device->oclass[NVDEV_ENGINE_CRYPT ] = &nv98_crypt_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nv94_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nv84_perfmon_oclass; break; case 0xa3: device->cname = "GT215"; @@ -320,16 +343,18 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_MPEG ] = &nv84_mpeg_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass; @@ -337,6 +362,7 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; break; case 0xa5: device->cname = "GT216"; @@ -347,22 +373,25 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; break; case 0xa8: device->cname = "GT218"; @@ -373,22 +402,25 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nva3_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; break; case 0xaf: device->cname = "MCP89"; @@ -399,22 +431,25 @@ nv50_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nva3_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nv94_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nv50_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvaf_fb_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nv50_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nv50_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nva3_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nv84_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nv50_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = &nv50_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nv98_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nv98_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nv98_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nva3_copy_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = nva3_perfmon_oclass; break; default: nv_fatal(device, "unknown Tesla chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c index 418f51f50d7a..8d06eef2b9ee 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c @@ -38,6 +38,8 @@ #include <subdev/instmem.h> #include <subdev/vm.h> #include <subdev/bar.h> +#include <subdev/pwr.h> +#include <subdev/volt.h> #include <engine/device.h> #include <engine/dmaobj.h> @@ -49,6 +51,7 @@ #include <engine/ppp.h> #include <engine/copy.h> #include <engine/disp.h> +#include <engine/perfmon.h> int nvc0_identify(struct nouveau_device *device) @@ -63,18 +66,20 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc0_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; @@ -82,6 +87,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xc4: device->cname = "GF104"; @@ -92,18 +98,20 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc3_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; @@ -111,6 +119,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xc3: device->cname = "GF106"; @@ -121,24 +130,27 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc3_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xce: device->cname = "GF114"; @@ -149,18 +161,20 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc3_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; @@ -168,6 +182,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xcf: device->cname = "GF116"; @@ -178,18 +193,20 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc3_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; @@ -197,6 +214,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xc1: device->cname = "GF108"; @@ -207,24 +225,27 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc1_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xc8: device->cname = "GF110"; @@ -235,18 +256,20 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nva3_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc0_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvc0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvc8_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; @@ -254,6 +277,7 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_COPY1 ] = &nvc0_copy1_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nva3_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xd9: device->cname = "GF119"; @@ -264,24 +288,27 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvd9_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; case 0xd7: device->cname = "GF117"; @@ -292,24 +319,25 @@ nvc0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nvc0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nvc0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nvc0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvd7_graph_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nvc0_vp_oclass; device->oclass[NVDEV_ENGINE_BSP ] = &nvc0_bsp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nvc0_copy0_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nvd0_disp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nvc0_perfmon_oclass; break; default: nv_fatal(device, "unknown Fermi chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 7aca1877add4..3900104976fc 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c @@ -38,6 +38,8 @@ #include <subdev/instmem.h> #include <subdev/vm.h> #include <subdev/bar.h> +#include <subdev/pwr.h> +#include <subdev/volt.h> #include <engine/device.h> #include <engine/dmaobj.h> @@ -49,6 +51,7 @@ #include <engine/bsp.h> #include <engine/vp.h> #include <engine/ppp.h> +#include <engine/perfmon.h> int nve0_identify(struct nouveau_device *device) @@ -59,22 +62,24 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; @@ -83,28 +88,31 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; break; case 0xe7: device->cname = "GK107"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; @@ -113,28 +121,31 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; break; case 0xe6: device->cname = "GK106"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nve4_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nve0_disp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; @@ -143,28 +154,31 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; + device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; break; case 0xf0: device->cname = "GK110"; device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; - device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; - device->oclass[NVDEV_SUBDEV_MC ] = &nvc0_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = &nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nvd0_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; - device->oclass[NVDEV_ENGINE_FIFO ] = &nve0_fifo_oclass; - device->oclass[NVDEV_ENGINE_SW ] = &nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass; device->oclass[NVDEV_ENGINE_DISP ] = &nvf0_disp_oclass; device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; @@ -175,6 +189,43 @@ nve0_identify(struct nouveau_device *device) device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; #endif + device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; + break; + case 0x108: + device->cname = "GK208"; + device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; + device->oclass[NVDEV_SUBDEV_GPIO ] = &nve0_gpio_oclass; + device->oclass[NVDEV_SUBDEV_I2C ] = &nvd0_i2c_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; + device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; + device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; + device->oclass[NVDEV_SUBDEV_DEVINIT] = &nvc0_devinit_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = nvc3_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; + device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; + device->oclass[NVDEV_SUBDEV_LTCG ] = &nvc0_ltcg_oclass; + device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; + device->oclass[NVDEV_SUBDEV_INSTMEM] = &nv50_instmem_oclass; + device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; + device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; + device->oclass[NVDEV_SUBDEV_PWR ] = &nv108_pwr_oclass; + device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; + device->oclass[NVDEV_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass; +#if 0 + device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass; + device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; + device->oclass[NVDEV_ENGINE_GR ] = nvf0_graph_oclass; +#endif + device->oclass[NVDEV_ENGINE_DISP ] = &nvf0_disp_oclass; +#if 0 + device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; + device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; + device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; + device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; + device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; + device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; +#endif break; default: nv_fatal(device, "unknown Kepler chipset\n"); diff --git a/drivers/gpu/drm/nouveau/core/engine/device/priv.h b/drivers/gpu/drm/nouveau/core/engine/device/priv.h new file mode 100644 index 000000000000..035fd5b9cfc3 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/device/priv.h @@ -0,0 +1,8 @@ +#ifndef __NVKM_DEVICE_PRIV_H__ +#define __NVKM_DEVICE_PRIV_H__ + +#include <engine/device.h> + +extern struct nouveau_oclass nouveau_control_oclass[]; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c index 054d9cff4f53..1bd4c63369c1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c @@ -70,17 +70,10 @@ dp_set_link_config(struct dp_state *dp) }; u32 lnkcmp; u8 sink[2]; + int ret; DBG("%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); - /* set desired link configuration on the sink */ - sink[0] = dp->link_bw / 27000; - sink[1] = dp->link_nr; - if (dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP) - sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN; - - nv_wraux(dp->aux, DPCD_LC00, sink, 2); - /* set desired link configuration on the source */ if ((lnkcmp = dp->info.lnkcmp)) { if (dp->version < 0x30) { @@ -96,10 +89,22 @@ dp_set_link_config(struct dp_state *dp) nvbios_exec(&init); } - return dp->func->lnk_ctl(dp->disp, dp->outp, dp->head, - dp->link_nr, dp->link_bw / 27000, - dp->dpcd[DPCD_RC02] & - DPCD_RC02_ENHANCED_FRAME_CAP); + ret = dp->func->lnk_ctl(dp->disp, dp->outp, dp->head, + dp->link_nr, dp->link_bw / 27000, + dp->dpcd[DPCD_RC02] & + DPCD_RC02_ENHANCED_FRAME_CAP); + if (ret) { + ERR("lnk_ctl failed with %d\n", ret); + return ret; + } + + /* set desired link configuration on the sink */ + sink[0] = dp->link_bw / 27000; + sink[1] = dp->link_nr; + if (dp->dpcd[DPCD_RC02] & DPCD_RC02_ENHANCED_FRAME_CAP) + sink[1] |= DPCD_LC01_ENHANCED_FRAME_EN; + + return nv_wraux(dp->aux, DPCD_LC00, sink, 2); } static void @@ -294,8 +299,17 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, ret = nv_rdaux(dp->aux, 0x00000, dp->dpcd, sizeof(dp->dpcd)); if (ret) { + /* it's possible the display has been unplugged before we + * get here. we still need to execute the full set of + * vbios scripts, and program the OR at a high enough + * frequency to satisfy the target mode. failure to do + * so results at best in an UPDATE hanging, and at worst + * with PDISP running away to join the circus. + */ + dp->dpcd[1] = link_bw[0] / 27000; + dp->dpcd[2] = 4; + dp->dpcd[3] = 0x00; ERR("failed to read DPCD\n"); - return ret; } /* adjust required bandwidth for 8B/10B coding overhead */ @@ -308,7 +322,7 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, while (*link_bw > (dp->dpcd[1] * 27000)) link_bw++; - while (link_bw[0]) { + while ((ret = -EIO) && link_bw[0]) { /* find minimum required lane count at this link rate */ dp->link_nr = dp->dpcd[2] & DPCD_RC02_MAX_LANE_COUNT; while ((dp->link_nr >> 1) * link_bw[0] > datarate) @@ -328,8 +342,10 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, !dp_link_train_eq(dp)) break; } else - if (ret >= 1) { - /* dp_set_link_config() handled training */ + if (ret) { + /* dp_set_link_config() handled training, or + * we failed to communicate with the sink. + */ break; } @@ -339,8 +355,10 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, /* finish link training */ dp_set_training_pattern(dp, 0); + if (ret < 0) + ERR("link training failed\n"); /* execute post-train script from vbios */ dp_link_train_fini(dp); - return true; + return (ret < 0) ? false : true; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c index 05e903f08a36..a0bc8a89b699 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c @@ -59,6 +59,7 @@ nv04_disp_intr(struct nouveau_subdev *subdev) struct nv04_disp_priv *priv = (void *)subdev; u32 crtc0 = nv_rd32(priv, 0x600100); u32 crtc1 = nv_rd32(priv, 0x602100); + u32 pvideo; if (crtc0 & 0x00000001) { nouveau_event_trigger(priv->base.vblank, 0); @@ -69,6 +70,14 @@ nv04_disp_intr(struct nouveau_subdev *subdev) nouveau_event_trigger(priv->base.vblank, 1); nv_wr32(priv, 0x602100, 0x00000001); } + + if (nv_device(priv)->chipset >= 0x10 && + nv_device(priv)->chipset <= 0x40) { + pvideo = nv_rd32(priv, 0x8100); + if (pvideo & ~0x11) + nv_info(priv, "PVIDEO intr: %08x\n", pvideo); + nv_wr32(priv, 0x8100, pvideo); + } } static int diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index 52dd7a1db729..378a015091d2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -541,6 +541,15 @@ nvd0_disp_base_init(struct nouveau_object *object) nv_wr32(priv, 0x6100a0, 0x00000000); nv_wr32(priv, 0x6100b0, 0x00000307); + /* disable underflow reporting, preventing an intermittent issue + * on some nve4 boards where the production vbios left this + * setting enabled by default. + * + * ftp://download.nvidia.com/open-gpu-doc/gk104-disable-underflow-reporting/1/gk104-disable-underflow-reporting.txt + */ + for (i = 0; i < priv->head.nr; i++) + nv_mask(priv, 0x616308 + (i * 0x800), 0x00000111, 0x00000010); + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c index 7ec4ee83fb64..eea3ef59693d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c @@ -97,8 +97,9 @@ nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, { struct nouveau_bios *bios = nouveau_bios(disp); struct nv50_disp_priv *priv = (void *)disp; + const u32 shift = nv94_sor_dp_lane_map(priv, lane); const u32 loff = nv94_sor_loff(outp); - u32 addr, shift = nv94_sor_dp_lane_map(priv, lane); + u32 addr, data[3]; u8 ver, hdr, cnt, len; struct nvbios_dpout info; struct nvbios_dpcfg ocfg; @@ -113,9 +114,12 @@ nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, if (!addr) return -EINVAL; - nv_mask(priv, 0x61c118 + loff, 0x000000ff << shift, ocfg.drv << shift); - nv_mask(priv, 0x61c120 + loff, 0x000000ff << shift, ocfg.pre << shift); - nv_mask(priv, 0x61c130 + loff, 0x0000ff00, ocfg.unk << 8); + data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift); + data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift); + data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00); + nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift)); + nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift)); + nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8)); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c index 9e1d435d7282..d2df572f16a3 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c @@ -93,8 +93,9 @@ nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, { struct nouveau_bios *bios = nouveau_bios(disp); struct nv50_disp_priv *priv = (void *)disp; + const u32 shift = nvd0_sor_dp_lane_map(priv, lane); const u32 loff = nvd0_sor_loff(outp); - u32 addr, shift = nvd0_sor_dp_lane_map(priv, lane); + u32 addr, data[3]; u8 ver, hdr, cnt, len; struct nvbios_dpout info; struct nvbios_dpcfg ocfg; @@ -109,9 +110,12 @@ nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, if (!addr) return -EINVAL; - nv_mask(priv, 0x61c118 + loff, 0x000000ff << shift, ocfg.drv << shift); - nv_mask(priv, 0x61c120 + loff, 0x000000ff << shift, ocfg.pre << shift); - nv_mask(priv, 0x61c130 + loff, 0x0000ff00, ocfg.unk << 8); + data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift); + data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift); + data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00); + nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift)); + nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift)); + nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8)); nv_mask(priv, 0x61c13c + loff, 0x00000000, 0x00000000); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c index f877bd524a92..54f26cc801c7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv04.c @@ -632,8 +632,8 @@ nv04_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass -nv04_fifo_oclass = { +struct nouveau_oclass * +nv04_fifo_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(FIFO, 0x04), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv04_fifo_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c index 2c927c1d173b..571a22aa1ae5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv10.c @@ -159,8 +159,8 @@ nv10_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -struct nouveau_oclass -nv10_fifo_oclass = { +struct nouveau_oclass * +nv10_fifo_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(FIFO, 0x10), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv10_fifo_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c index a9cb51d38c57..f25760209316 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv17.c @@ -196,8 +196,8 @@ nv17_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass -nv17_fifo_oclass = { +struct nouveau_oclass * +nv17_fifo_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(FIFO, 0x17), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv17_fifo_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c index 5c7433d5069f..343487ed2238 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv40.c @@ -337,8 +337,8 @@ nv40_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass -nv40_fifo_oclass = { +struct nouveau_oclass * +nv40_fifo_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(FIFO, 0x40), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv40_fifo_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c index 7e5dff51d3c5..5f555788121c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -502,8 +502,8 @@ nv50_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass -nv50_fifo_oclass = { +struct nouveau_oclass * +nv50_fifo_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(FIFO, 0x50), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_fifo_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c index 91a87cd7195a..0908dc834c84 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -144,7 +144,7 @@ nv84_fifo_object_attach(struct nouveau_object *parent, case NVDEV_ENGINE_COPY0 : context |= 0x00300000; break; case NVDEV_ENGINE_VP : context |= 0x00400000; break; case NVDEV_ENGINE_CRYPT : - case NVDEV_ENGINE_UNK1C1: context |= 0x00500000; break; + case NVDEV_ENGINE_VIC : context |= 0x00500000; break; case NVDEV_ENGINE_BSP : context |= 0x00600000; break; default: return -EINVAL; @@ -180,7 +180,7 @@ nv84_fifo_chan_ctor_dma(struct nouveau_object *parent, (1ULL << NVDEV_ENGINE_BSP) | (1ULL << NVDEV_ENGINE_PPP) | (1ULL << NVDEV_ENGINE_COPY0) | - (1ULL << NVDEV_ENGINE_UNK1C1), &chan); + (1ULL << NVDEV_ENGINE_VIC), &chan); *pobject = nv_object(chan); if (ret) return ret; @@ -243,7 +243,7 @@ nv84_fifo_chan_ctor_ind(struct nouveau_object *parent, (1ULL << NVDEV_ENGINE_BSP) | (1ULL << NVDEV_ENGINE_PPP) | (1ULL << NVDEV_ENGINE_COPY0) | - (1ULL << NVDEV_ENGINE_UNK1C1), &chan); + (1ULL << NVDEV_ENGINE_VIC), &chan); *pobject = nv_object(chan); if (ret) return ret; @@ -435,8 +435,8 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -struct nouveau_oclass -nv84_fifo_oclass = { +struct nouveau_oclass * +nv84_fifo_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(FIFO, 0x84), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv84_fifo_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c index ce92f289e751..9ac94d4e5646 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -494,13 +494,6 @@ nvc0_fifo_isr_subfifo_intr(struct nvc0_fifo_priv *priv, int unit) u32 mthd = (addr & 0x00003ffc); u32 show = stat; - if (stat & 0x00200000) { - if (mthd == 0x0054) { - if (!nvc0_fifo_swmthd(priv, chid, 0x0500, 0x00000000)) - show &= ~0x00200000; - } - } - if (stat & 0x00800000) { if (!nvc0_fifo_swmthd(priv, chid, mthd, data)) show &= ~0x00800000; @@ -720,8 +713,8 @@ nvc0_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass -nvc0_fifo_oclass = { +struct nouveau_oclass * +nvc0_fifo_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(FIFO, 0xc0), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nvc0_fifo_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c index 8e8121abe31b..04f412922d2d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -481,13 +481,6 @@ nve0_fifo_isr_subfifo_intr(struct nve0_fifo_priv *priv, int unit) u32 mthd = (addr & 0x00003ffc); u32 show = stat; - if (stat & 0x00200000) { - if (mthd == 0x0054) { - if (!nve0_fifo_swmthd(priv, chid, 0x0500, 0x00000000)) - show &= ~0x00200000; - } - } - if (stat & 0x00800000) { if (!nve0_fifo_swmthd(priv, chid, mthd, data)) show &= ~0x00800000; @@ -675,8 +668,8 @@ nve0_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass -nve0_fifo_oclass = { +struct nouveau_oclass * +nve0_fifo_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(FIFO, 0xe0), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nve0_fifo_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c index 64dca260912f..fe67415c3e17 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc0.c @@ -1039,7 +1039,7 @@ nvc0_grctx_generate_r406800(struct nvc0_graph_priv *priv) } while (!tpcnr[gpc]); tpc = priv->tpc_nr[gpc] - tpcnr[gpc]--; - tpc_set |= 1 << ((gpc * 8) + tpc); + tpc_set |= 1ULL << ((gpc * 8) + tpc); } nv_wr32(priv, 0x406800 + (i * 0x20), lower_32_bits(tpc_set)); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c index e5be3ee7f172..71b4283f7fad 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c @@ -587,6 +587,7 @@ nvc1_grctx_init_unk58xx[] = { { 0x405870, 4, 0x04, 0x00000001 }, { 0x405a00, 2, 0x04, 0x00000000 }, { 0x405a18, 1, 0x04, 0x00000000 }, + {} }; static struct nvc0_graph_init @@ -598,6 +599,7 @@ nvc1_grctx_init_rop[] = { { 0x408904, 1, 0x04, 0x62000001 }, { 0x408908, 1, 0x04, 0x00c80929 }, { 0x408980, 1, 0x04, 0x0000011d }, + {} }; static struct nvc0_graph_init @@ -671,6 +673,7 @@ nvc1_grctx_init_gpc_0[] = { { 0x419000, 1, 0x04, 0x00000780 }, { 0x419004, 2, 0x04, 0x00000000 }, { 0x419014, 1, 0x04, 0x00000004 }, + {} }; static struct nvc0_graph_init @@ -717,6 +720,7 @@ nvc1_grctx_init_tpc[] = { { 0x419e98, 1, 0x04, 0x00000000 }, { 0x419ee0, 1, 0x04, 0x00011110 }, { 0x419f30, 11, 0x04, 0x00000000 }, + {} }; void diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c index 438e78410808..c4740d528532 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c @@ -258,6 +258,7 @@ nvd7_grctx_init_hub[] = { nvc0_grctx_init_unk78xx, nvc0_grctx_init_unk80xx, nvd9_grctx_init_rop, + NULL }; struct nvc0_graph_init * diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c index 818a4751df46..a1102cbf2fdc 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c @@ -466,6 +466,7 @@ nvd9_grctx_init_hub[] = { nvc0_grctx_init_unk78xx, nvc0_grctx_init_unk80xx, nvd9_grctx_init_rop, + NULL }; struct nvc0_graph_init * diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c index 23c143aaa556..4532f7e5618c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c @@ -945,7 +945,8 @@ nv10_graph_load_context(struct nv10_graph_chan *chan, int chid) for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) nv_wr32(priv, nv10_graph_ctx_regs[i], chan->nv10[i]); - if (nv_device(priv)->chipset >= 0x17) { + if (nv_device(priv)->card_type >= NV_11 && + nv_device(priv)->chipset >= 0x17) { for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) nv_wr32(priv, nv17_graph_ctx_regs[i], chan->nv17[i]); } @@ -970,7 +971,8 @@ nv10_graph_unload_context(struct nv10_graph_chan *chan) for (i = 0; i < ARRAY_SIZE(nv10_graph_ctx_regs); i++) chan->nv10[i] = nv_rd32(priv, nv10_graph_ctx_regs[i]); - if (nv_device(priv)->chipset >= 0x17) { + if (nv_device(priv)->card_type >= NV_11 && + nv_device(priv)->chipset >= 0x17) { for (i = 0; i < ARRAY_SIZE(nv17_graph_ctx_regs); i++) chan->nv17[i] = nv_rd32(priv, nv17_graph_ctx_regs[i]); } @@ -1052,7 +1054,8 @@ nv10_graph_context_ctor(struct nouveau_object *parent, NV_WRITE_CTX(0x00400e14, 0x00001000); NV_WRITE_CTX(0x00400e30, 0x00080008); NV_WRITE_CTX(0x00400e34, 0x00080008); - if (nv_device(priv)->chipset >= 0x17) { + if (nv_device(priv)->card_type >= NV_11 && + nv_device(priv)->chipset >= 0x17) { /* is it really needed ??? */ NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, nv_rd32(priv, NV10_PGRAPH_DEBUG_4)); @@ -1231,7 +1234,7 @@ nv10_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_engine(priv)->sclass = nv10_graph_sclass; else if (nv_device(priv)->chipset < 0x17 || - nv_device(priv)->chipset == 0x1a) + nv_device(priv)->card_type < NV_11) nv_engine(priv)->sclass = nv15_graph_sclass; else nv_engine(priv)->sclass = nv17_graph_sclass; @@ -1270,7 +1273,8 @@ nv10_graph_init(struct nouveau_object *object) nv_wr32(priv, NV04_PGRAPH_DEBUG_2, 0x25f92ad9); nv_wr32(priv, NV04_PGRAPH_DEBUG_3, 0x55DE0830 | (1 << 29) | (1 << 31)); - if (nv_device(priv)->chipset >= 0x17) { + if (nv_device(priv)->card_type >= NV_11 && + nv_device(priv)->chipset >= 0x17) { nv_wr32(priv, NV10_PGRAPH_DEBUG_4, 0x1f000000); nv_wr32(priv, 0x400a10, 0x03ff3fb6); nv_wr32(priv, 0x400838, 0x002f8684); diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c index 3f4f35cc3848..434bb4b0fa2e 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c @@ -1138,7 +1138,7 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_subdev(priv)->unit = 0x18001000; + nv_subdev(priv)->unit = 0x08001000; nv_subdev(priv)->intr = nvc0_graph_intr; priv->base.units = nvc0_graph_units; diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c index c19004301309..7eb6d94c84e2 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c @@ -34,16 +34,7 @@ #include <engine/fifo.h> #include <engine/mpeg.h> -#include <engine/graph/nv40.h> - -struct nv31_mpeg_priv { - struct nouveau_mpeg base; - atomic_t refcount; -}; - -struct nv31_mpeg_chan { - struct nouveau_object base; -}; +#include <engine/mpeg/nv31.h> /******************************************************************************* * MPEG object classes @@ -89,18 +80,18 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len) if (mthd == 0x0190) { /* DMA_CMD */ - nv_mask(priv, 0x00b300, 0x00030000, (dma0 & 0x00030000)); + nv_mask(priv, 0x00b300, 0x00010000, (dma0 & 0x00030000) ? 0x00010000 : 0); nv_wr32(priv, 0x00b334, base); nv_wr32(priv, 0x00b324, size); } else if (mthd == 0x01a0) { /* DMA_DATA */ - nv_mask(priv, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2); + nv_mask(priv, 0x00b300, 0x00020000, (dma0 & 0x00030000) ? 0x00020000 : 0); nv_wr32(priv, 0x00b360, base); nv_wr32(priv, 0x00b364, size); } else { /* DMA_IMAGE, VRAM only */ - if (dma0 & 0x000c0000) + if (dma0 & 0x00030000) return -EINVAL; nv_wr32(priv, 0x00b370, base); @@ -110,7 +101,7 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len) return 0; } -static struct nouveau_ofuncs +struct nouveau_ofuncs nv31_mpeg_ofuncs = { .ctor = nv31_mpeg_object_ctor, .dtor = _nouveau_gpuobj_dtor, @@ -146,16 +137,23 @@ nv31_mpeg_context_ctor(struct nouveau_object *parent, { struct nv31_mpeg_priv *priv = (void *)engine; struct nv31_mpeg_chan *chan; + unsigned long flags; int ret; - if (!atomic_add_unless(&priv->refcount, 1, 1)) - return -EBUSY; - ret = nouveau_object_create(parent, engine, oclass, 0, &chan); *pobject = nv_object(chan); if (ret) return ret; + spin_lock_irqsave(&nv_engine(priv)->lock, flags); + if (priv->chan) { + spin_unlock_irqrestore(&nv_engine(priv)->lock, flags); + nouveau_object_destroy(&chan->base); + *pobject = NULL; + return -EBUSY; + } + priv->chan = chan; + spin_unlock_irqrestore(&nv_engine(priv)->lock, flags); return 0; } @@ -164,11 +162,15 @@ nv31_mpeg_context_dtor(struct nouveau_object *object) { struct nv31_mpeg_priv *priv = (void *)object->engine; struct nv31_mpeg_chan *chan = (void *)object; - atomic_dec(&priv->refcount); + unsigned long flags; + + spin_lock_irqsave(&nv_engine(priv)->lock, flags); + priv->chan = NULL; + spin_unlock_irqrestore(&nv_engine(priv)->lock, flags); nouveau_object_destroy(&chan->base); } -static struct nouveau_oclass +struct nouveau_oclass nv31_mpeg_cclass = { .handle = NV_ENGCTX(MPEG, 0x31), .ofuncs = &(struct nouveau_ofuncs) { @@ -197,21 +199,19 @@ nv31_mpeg_tile_prog(struct nouveau_engine *engine, int i) void nv31_mpeg_intr(struct nouveau_subdev *subdev) { + struct nv31_mpeg_priv *priv = (void *)subdev; struct nouveau_fifo *pfifo = nouveau_fifo(subdev); - struct nouveau_engine *engine = nv_engine(subdev); - struct nouveau_object *engctx; struct nouveau_handle *handle; - struct nv31_mpeg_priv *priv = (void *)subdev; - u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff; + struct nouveau_object *engctx; u32 stat = nv_rd32(priv, 0x00b100); u32 type = nv_rd32(priv, 0x00b230); u32 mthd = nv_rd32(priv, 0x00b234); u32 data = nv_rd32(priv, 0x00b238); u32 show = stat; - int chid; + unsigned long flags; - engctx = nouveau_engctx_get(engine, inst); - chid = pfifo->chid(pfifo, engctx); + spin_lock_irqsave(&nv_engine(priv)->lock, flags); + engctx = nv_object(priv->chan); if (stat & 0x01000000) { /* happens on initial binding of the object */ @@ -220,7 +220,7 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev) show &= ~0x01000000; } - if (type == 0x00000010) { + if (type == 0x00000010 && engctx) { handle = nouveau_handle_get_class(engctx, 0x3174); if (handle && !nv_call(handle->object, mthd, data)) show &= ~0x01000000; @@ -232,13 +232,12 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev) nv_wr32(priv, 0x00b230, 0x00000001); if (show) { - nv_error(priv, - "ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n", - chid, inst << 4, nouveau_client_name(engctx), stat, - type, mthd, data); + nv_error(priv, "ch %d [%s] 0x%08x 0x%08x 0x%08x 0x%08x\n", + pfifo->chid(pfifo, engctx), + nouveau_client_name(engctx), stat, type, mthd, data); } - nouveau_engctx_put(engctx); + spin_unlock_irqrestore(&nv_engine(priv)->lock, flags); } static int @@ -284,10 +283,7 @@ nv31_mpeg_init(struct nouveau_object *object) /* PMPEG init */ nv_wr32(priv, 0x00b32c, 0x00000000); nv_wr32(priv, 0x00b314, 0x00000100); - if (nv_device(priv)->chipset >= 0x40 && nv44_graph_class(priv)) - nv_wr32(priv, 0x00b220, 0x00000044); - else - nv_wr32(priv, 0x00b220, 0x00000031); + nv_wr32(priv, 0x00b220, 0x00000031); nv_wr32(priv, 0x00b300, 0x02001ec1); nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001); diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h new file mode 100644 index 000000000000..d08629d0b6ad --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h @@ -0,0 +1,15 @@ +#ifndef __NV31_MPEG_H__ +#define __NV31_MPEG_H__ + +#include <engine/mpeg.h> + +struct nv31_mpeg_chan { + struct nouveau_object base; +}; + +struct nv31_mpeg_priv { + struct nouveau_mpeg base; + struct nv31_mpeg_chan *chan; +}; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c index dd6196072e9c..d4e7ec0ba68c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c @@ -31,66 +31,63 @@ #include <subdev/instmem.h> #include <engine/mpeg.h> -#include <engine/graph/nv40.h> - -struct nv40_mpeg_priv { - struct nouveau_mpeg base; -}; - -struct nv40_mpeg_chan { - struct nouveau_mpeg_chan base; -}; +#include <engine/mpeg/nv31.h> /******************************************************************************* - * PMPEG context + * MPEG object classes ******************************************************************************/ static int -nv40_mpeg_context_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) +nv40_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len) { - struct nv40_mpeg_chan *chan; - int ret; - - ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL, - 264 * 4, 16, - NVOBJ_FLAG_ZERO_ALLOC, &chan); - *pobject = nv_object(chan); - if (ret) - return ret; + struct nouveau_instmem *imem = nouveau_instmem(object); + struct nv31_mpeg_priv *priv = (void *)object->engine; + u32 inst = *(u32 *)arg << 4; + u32 dma0 = nv_ro32(imem, inst + 0); + u32 dma1 = nv_ro32(imem, inst + 4); + u32 dma2 = nv_ro32(imem, inst + 8); + u32 base = (dma2 & 0xfffff000) | (dma0 >> 20); + u32 size = dma1 + 1; + + /* only allow linear DMA objects */ + if (!(dma0 & 0x00002000)) + return -EINVAL; + + if (mthd == 0x0190) { + /* DMA_CMD */ + nv_mask(priv, 0x00b300, 0x00030000, (dma0 & 0x00030000)); + nv_wr32(priv, 0x00b334, base); + nv_wr32(priv, 0x00b324, size); + } else + if (mthd == 0x01a0) { + /* DMA_DATA */ + nv_mask(priv, 0x00b300, 0x000c0000, (dma0 & 0x00030000) << 2); + nv_wr32(priv, 0x00b360, base); + nv_wr32(priv, 0x00b364, size); + } else { + /* DMA_IMAGE, VRAM only */ + if (dma0 & 0x00030000) + return -EINVAL; + + nv_wr32(priv, 0x00b370, base); + nv_wr32(priv, 0x00b374, size); + } - nv_wo32(&chan->base.base, 0x78, 0x02001ec1); return 0; } -static int -nv40_mpeg_context_fini(struct nouveau_object *object, bool suspend) -{ - - struct nv40_mpeg_priv *priv = (void *)object->engine; - struct nv40_mpeg_chan *chan = (void *)object; - u32 inst = 0x80000000 | nv_gpuobj(chan)->addr >> 4; - - nv_mask(priv, 0x00b32c, 0x00000001, 0x00000000); - if (nv_rd32(priv, 0x00b318) == inst) - nv_mask(priv, 0x00b318, 0x80000000, 0x00000000); - nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001); - return 0; -} +static struct nouveau_omthds +nv40_mpeg_omthds[] = { + { 0x0190, 0x0190, nv40_mpeg_mthd_dma }, + { 0x01a0, 0x01a0, nv40_mpeg_mthd_dma }, + { 0x01b0, 0x01b0, nv40_mpeg_mthd_dma }, + {} +}; -static struct nouveau_oclass -nv40_mpeg_cclass = { - .handle = NV_ENGCTX(MPEG, 0x40), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv40_mpeg_context_ctor, - .dtor = _nouveau_mpeg_context_dtor, - .init = _nouveau_mpeg_context_init, - .fini = nv40_mpeg_context_fini, - .rd32 = _nouveau_mpeg_context_rd32, - .wr32 = _nouveau_mpeg_context_wr32, - }, +struct nouveau_oclass +nv40_mpeg_sclass[] = { + { 0x3174, &nv31_mpeg_ofuncs, nv40_mpeg_omthds }, + {} }; /******************************************************************************* @@ -100,7 +97,7 @@ nv40_mpeg_cclass = { static void nv40_mpeg_intr(struct nouveau_subdev *subdev) { - struct nv40_mpeg_priv *priv = (void *)subdev; + struct nv31_mpeg_priv *priv = (void *)subdev; u32 stat; if ((stat = nv_rd32(priv, 0x00b100))) @@ -117,7 +114,7 @@ nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv40_mpeg_priv *priv; + struct nv31_mpeg_priv *priv; int ret; ret = nouveau_mpeg_create(parent, engine, oclass, &priv); @@ -127,8 +124,8 @@ nv40_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_subdev(priv)->unit = 0x00000002; nv_subdev(priv)->intr = nv40_mpeg_intr; - nv_engine(priv)->cclass = &nv40_mpeg_cclass; - nv_engine(priv)->sclass = nv31_mpeg_sclass; + nv_engine(priv)->cclass = &nv31_mpeg_cclass; + nv_engine(priv)->sclass = nv40_mpeg_sclass; nv_engine(priv)->tile_prog = nv31_mpeg_tile_prog; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c new file mode 100644 index 000000000000..3d8c2133e0e8 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c @@ -0,0 +1,194 @@ +/* + * Copyright 2012 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 <core/os.h> +#include <core/class.h> +#include <core/client.h> +#include <core/engctx.h> +#include <core/handle.h> + +#include <subdev/fb.h> +#include <subdev/timer.h> +#include <subdev/instmem.h> + +#include <engine/fifo.h> +#include <engine/mpeg.h> + +struct nv44_mpeg_priv { + struct nouveau_mpeg base; +}; + +struct nv44_mpeg_chan { + struct nouveau_mpeg_chan base; +}; + +/******************************************************************************* + * PMPEG context + ******************************************************************************/ + +static int +nv44_mpeg_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv44_mpeg_chan *chan; + int ret; + + ret = nouveau_mpeg_context_create(parent, engine, oclass, NULL, + 264 * 4, 16, + NVOBJ_FLAG_ZERO_ALLOC, &chan); + *pobject = nv_object(chan); + if (ret) + return ret; + + nv_wo32(&chan->base.base, 0x78, 0x02001ec1); + return 0; +} + +static int +nv44_mpeg_context_fini(struct nouveau_object *object, bool suspend) +{ + + struct nv44_mpeg_priv *priv = (void *)object->engine; + struct nv44_mpeg_chan *chan = (void *)object; + u32 inst = 0x80000000 | nv_gpuobj(chan)->addr >> 4; + + nv_mask(priv, 0x00b32c, 0x00000001, 0x00000000); + if (nv_rd32(priv, 0x00b318) == inst) + nv_mask(priv, 0x00b318, 0x80000000, 0x00000000); + nv_mask(priv, 0x00b32c, 0x00000001, 0x00000001); + return 0; +} + +static struct nouveau_oclass +nv44_mpeg_cclass = { + .handle = NV_ENGCTX(MPEG, 0x44), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv44_mpeg_context_ctor, + .dtor = _nouveau_mpeg_context_dtor, + .init = _nouveau_mpeg_context_init, + .fini = nv44_mpeg_context_fini, + .rd32 = _nouveau_mpeg_context_rd32, + .wr32 = _nouveau_mpeg_context_wr32, + }, +}; + +/******************************************************************************* + * PMPEG engine/subdev functions + ******************************************************************************/ + +static void +nv44_mpeg_intr(struct nouveau_subdev *subdev) +{ + struct nouveau_fifo *pfifo = nouveau_fifo(subdev); + struct nouveau_engine *engine = nv_engine(subdev); + struct nouveau_object *engctx; + struct nouveau_handle *handle; + struct nv44_mpeg_priv *priv = (void *)subdev; + u32 inst = nv_rd32(priv, 0x00b318) & 0x000fffff; + u32 stat = nv_rd32(priv, 0x00b100); + u32 type = nv_rd32(priv, 0x00b230); + u32 mthd = nv_rd32(priv, 0x00b234); + u32 data = nv_rd32(priv, 0x00b238); + u32 show = stat; + int chid; + + engctx = nouveau_engctx_get(engine, inst); + chid = pfifo->chid(pfifo, engctx); + + if (stat & 0x01000000) { + /* happens on initial binding of the object */ + if (type == 0x00000020 && mthd == 0x0000) { + nv_mask(priv, 0x00b308, 0x00000000, 0x00000000); + show &= ~0x01000000; + } + + if (type == 0x00000010) { + handle = nouveau_handle_get_class(engctx, 0x3174); + if (handle && !nv_call(handle->object, mthd, data)) + show &= ~0x01000000; + nouveau_handle_put(handle); + } + } + + nv_wr32(priv, 0x00b100, stat); + nv_wr32(priv, 0x00b230, 0x00000001); + + if (show) { + nv_error(priv, + "ch %d [0x%08x %s] 0x%08x 0x%08x 0x%08x 0x%08x\n", + chid, inst << 4, nouveau_client_name(engctx), stat, + type, mthd, data); + } + + nouveau_engctx_put(engctx); +} + +static void +nv44_mpeg_me_intr(struct nouveau_subdev *subdev) +{ + struct nv44_mpeg_priv *priv = (void *)subdev; + u32 stat; + + if ((stat = nv_rd32(priv, 0x00b100))) + nv44_mpeg_intr(subdev); + + if ((stat = nv_rd32(priv, 0x00b800))) { + nv_error(priv, "PMSRCH 0x%08x\n", stat); + nv_wr32(priv, 0x00b800, stat); + } +} + +static int +nv44_mpeg_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv44_mpeg_priv *priv; + int ret; + + ret = nouveau_mpeg_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->unit = 0x00000002; + nv_subdev(priv)->intr = nv44_mpeg_me_intr; + nv_engine(priv)->cclass = &nv44_mpeg_cclass; + nv_engine(priv)->sclass = nv40_mpeg_sclass; + nv_engine(priv)->tile_prog = nv31_mpeg_tile_prog; + return 0; +} + +struct nouveau_oclass +nv44_mpeg_oclass = { + .handle = NV_ENGINE(MPEG, 0x44), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv44_mpeg_ctor, + .dtor = _nouveau_mpeg_dtor, + .init = nv31_mpeg_init, + .fini = _nouveau_mpeg_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c new file mode 100644 index 000000000000..e9c5e51943ef --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c @@ -0,0 +1,449 @@ +/* + * Copyright 2013 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 <core/option.h> +#include <core/class.h> + +#include <subdev/clock.h> + +#include "priv.h" + +#define QUAD_MASK 0x0f +#define QUAD_FREE 0x01 + +static struct nouveau_perfsig * +nouveau_perfsig_find_(struct nouveau_perfdom *dom, const char *name, u32 size) +{ + char path[64]; + int i; + + if (name[0] != '/') { + for (i = 0; i < dom->signal_nr; i++) { + if ( dom->signal[i].name && + !strncmp(name, dom->signal[i].name, size)) + return &dom->signal[i]; + } + } else { + for (i = 0; i < dom->signal_nr; i++) { + snprintf(path, sizeof(path), "/%s/%02x", dom->name, i); + if (!strncmp(name, path, size)) + return &dom->signal[i]; + } + } + + return NULL; +} + +struct nouveau_perfsig * +nouveau_perfsig_find(struct nouveau_perfmon *ppm, const char *name, u32 size, + struct nouveau_perfdom **pdom) +{ + struct nouveau_perfdom *dom = *pdom; + struct nouveau_perfsig *sig; + + if (dom == NULL) { + list_for_each_entry(dom, &ppm->domains, head) { + sig = nouveau_perfsig_find_(dom, name, size); + if (sig) { + *pdom = dom; + return sig; + } + } + + return NULL; + } + + return nouveau_perfsig_find_(dom, name, size); +} + +struct nouveau_perfctr * +nouveau_perfsig_wrap(struct nouveau_perfmon *ppm, const char *name, + struct nouveau_perfdom **pdom) +{ + struct nouveau_perfsig *sig; + struct nouveau_perfctr *ctr; + + sig = nouveau_perfsig_find(ppm, name, strlen(name), pdom); + if (!sig) + return NULL; + + ctr = kzalloc(sizeof(*ctr), GFP_KERNEL); + if (ctr) { + ctr->signal[0] = sig; + ctr->logic_op = 0xaaaa; + } + + return ctr; +} + +/******************************************************************************* + * Perfmon object classes + ******************************************************************************/ +static int +nouveau_perfctr_query(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + struct nouveau_device *device = nv_device(object); + struct nouveau_perfmon *ppm = (void *)object->engine; + struct nouveau_perfdom *dom = NULL, *chk; + struct nv_perfctr_query *args = data; + const bool all = nouveau_boolopt(device->cfgopt, "NvPmShowAll", false); + const bool raw = nouveau_boolopt(device->cfgopt, "NvPmUnnamed", all); + const char *name; + int tmp = 0, di, si; + char path[64]; + + if (size < sizeof(*args)) + return -EINVAL; + + di = (args->iter & 0xff000000) >> 24; + si = (args->iter & 0x00ffffff) - 1; + + list_for_each_entry(chk, &ppm->domains, head) { + if (tmp++ == di) { + dom = chk; + break; + } + } + + if (dom == NULL || si >= (int)dom->signal_nr) + return -EINVAL; + + if (si >= 0) { + if (raw || !(name = dom->signal[si].name)) { + snprintf(path, sizeof(path), "/%s/%02x", dom->name, si); + name = path; + } + + if (args->name) + strncpy(args->name, name, args->size); + args->size = strlen(name) + 1; + } + + do { + while (++si < dom->signal_nr) { + if (all || dom->signal[si].name) { + args->iter = (di << 24) | ++si; + return 0; + } + } + si = -1; + di = di + 1; + dom = list_entry(dom->head.next, typeof(*dom), head); + } while (&dom->head != &ppm->domains); + + args->iter = 0xffffffff; + return 0; +} + +static int +nouveau_perfctr_sample(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + struct nouveau_perfmon *ppm = (void *)object->engine; + struct nouveau_perfctr *ctr, *tmp; + struct nouveau_perfdom *dom; + struct nv_perfctr_sample *args = data; + + if (size < sizeof(*args)) + return -EINVAL; + ppm->sequence++; + + list_for_each_entry(dom, &ppm->domains, head) { + /* sample previous batch of counters */ + if (dom->quad != QUAD_MASK) { + dom->func->next(ppm, dom); + tmp = NULL; + while (!list_empty(&dom->list)) { + ctr = list_first_entry(&dom->list, + typeof(*ctr), head); + if (ctr->slot < 0) break; + if ( tmp && tmp == ctr) break; + if (!tmp) tmp = ctr; + dom->func->read(ppm, dom, ctr); + ctr->slot = -1; + list_move_tail(&ctr->head, &dom->list); + } + } + + dom->quad = QUAD_MASK; + + /* setup next batch of counters for sampling */ + list_for_each_entry(ctr, &dom->list, head) { + ctr->slot = ffs(dom->quad) - 1; + if (ctr->slot < 0) + break; + dom->quad &= ~(QUAD_FREE << ctr->slot); + dom->func->init(ppm, dom, ctr); + } + + if (dom->quad != QUAD_MASK) + dom->func->next(ppm, dom); + } + + return 0; +} + +static int +nouveau_perfctr_read(struct nouveau_object *object, u32 mthd, + void *data, u32 size) +{ + struct nouveau_perfctr *ctr = (void *)object; + struct nv_perfctr_read *args = data; + + if (size < sizeof(*args)) + return -EINVAL; + if (!ctr->clk) + return -EAGAIN; + + args->clk = ctr->clk; + args->ctr = ctr->ctr; + return 0; +} + +static void +nouveau_perfctr_dtor(struct nouveau_object *object) +{ + struct nouveau_perfctr *ctr = (void *)object; + if (ctr->head.next) + list_del(&ctr->head); + nouveau_object_destroy(&ctr->base); +} + +static int +nouveau_perfctr_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_perfmon *ppm = (void *)engine; + struct nouveau_perfdom *dom = NULL; + struct nouveau_perfsig *sig[4] = {}; + struct nouveau_perfctr *ctr; + struct nv_perfctr_class *args = data; + int ret, i; + + if (size < sizeof(*args)) + return -EINVAL; + + for (i = 0; i < ARRAY_SIZE(args->signal) && args->signal[i].name; i++) { + sig[i] = nouveau_perfsig_find(ppm, args->signal[i].name, + args->signal[i].size, &dom); + if (!sig[i]) + return -EINVAL; + } + + ret = nouveau_object_create(parent, engine, oclass, 0, &ctr); + *pobject = nv_object(ctr); + if (ret) + return ret; + + ctr->slot = -1; + ctr->logic_op = args->logic_op; + ctr->signal[0] = sig[0]; + ctr->signal[1] = sig[1]; + ctr->signal[2] = sig[2]; + ctr->signal[3] = sig[3]; + if (dom) + list_add_tail(&ctr->head, &dom->list); + return 0; +} + +static struct nouveau_ofuncs +nouveau_perfctr_ofuncs = { + .ctor = nouveau_perfctr_ctor, + .dtor = nouveau_perfctr_dtor, + .init = nouveau_object_init, + .fini = nouveau_object_fini, +}; + +static struct nouveau_omthds +nouveau_perfctr_omthds[] = { + { NV_PERFCTR_QUERY, NV_PERFCTR_QUERY, nouveau_perfctr_query }, + { NV_PERFCTR_SAMPLE, NV_PERFCTR_SAMPLE, nouveau_perfctr_sample }, + { NV_PERFCTR_READ, NV_PERFCTR_READ, nouveau_perfctr_read }, + {} +}; + +struct nouveau_oclass +nouveau_perfmon_sclass[] = { + { .handle = NV_PERFCTR_CLASS, + .ofuncs = &nouveau_perfctr_ofuncs, + .omthds = nouveau_perfctr_omthds, + }, + {}, +}; + +/******************************************************************************* + * PPM context + ******************************************************************************/ +static void +nouveau_perfctx_dtor(struct nouveau_object *object) +{ + struct nouveau_perfmon *ppm = (void *)object->engine; + mutex_lock(&nv_subdev(ppm)->mutex); + ppm->context = NULL; + mutex_unlock(&nv_subdev(ppm)->mutex); +} + +static int +nouveau_perfctx_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nouveau_perfmon *ppm = (void *)engine; + struct nouveau_perfctx *ctx; + int ret; + + ret = nouveau_engctx_create(parent, engine, oclass, NULL, + 0, 0, 0, &ctx); + *pobject = nv_object(ctx); + if (ret) + return ret; + + mutex_lock(&nv_subdev(ppm)->mutex); + if (ppm->context == NULL) + ppm->context = ctx; + mutex_unlock(&nv_subdev(ppm)->mutex); + + if (ctx != ppm->context) + return -EBUSY; + + return 0; +} + +struct nouveau_oclass +nouveau_perfmon_cclass = { + .handle = NV_ENGCTX(PERFMON, 0x00), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nouveau_perfctx_ctor, + .dtor = nouveau_perfctx_dtor, + .init = _nouveau_engctx_init, + .fini = _nouveau_engctx_fini, + }, +}; + +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ +int +nouveau_perfdom_new(struct nouveau_perfmon *ppm, const char *name, u32 mask, + u32 base, u32 size_unit, u32 size_domain, + const struct nouveau_specdom *spec) +{ + const struct nouveau_specdom *sdom; + const struct nouveau_specsig *ssig; + struct nouveau_perfdom *dom; + int i; + + for (i = 0; i == 0 || mask; i++) { + u32 addr = base + (i * size_unit); + if (i && !(mask & (1 << i))) + continue; + + sdom = spec; + while (sdom->signal_nr) { + dom = kzalloc(sizeof(*dom) + sdom->signal_nr * + sizeof(*dom->signal), GFP_KERNEL); + if (!dom) + return -ENOMEM; + + if (mask) { + snprintf(dom->name, sizeof(dom->name), + "%s/%02x/%02x", name, i, + (int)(sdom - spec)); + } else { + snprintf(dom->name, sizeof(dom->name), + "%s/%02x", name, (int)(sdom - spec)); + } + + list_add_tail(&dom->head, &ppm->domains); + INIT_LIST_HEAD(&dom->list); + dom->func = sdom->func; + dom->addr = addr; + dom->quad = QUAD_MASK; + dom->signal_nr = sdom->signal_nr; + + ssig = (sdom++)->signal; + while (ssig->name) { + dom->signal[ssig->signal].name = ssig->name; + ssig++; + } + + addr += size_domain; + } + + mask &= ~(1 << i); + } + + return 0; +} + +int +_nouveau_perfmon_fini(struct nouveau_object *object, bool suspend) +{ + struct nouveau_perfmon *ppm = (void *)object; + return nouveau_engine_fini(&ppm->base, suspend); +} + +int +_nouveau_perfmon_init(struct nouveau_object *object) +{ + struct nouveau_perfmon *ppm = (void *)object; + return nouveau_engine_init(&ppm->base); +} + +void +_nouveau_perfmon_dtor(struct nouveau_object *object) +{ + struct nouveau_perfmon *ppm = (void *)object; + struct nouveau_perfdom *dom, *tmp; + + list_for_each_entry_safe(dom, tmp, &ppm->domains, head) { + list_del(&dom->head); + kfree(dom); + } + + nouveau_engine_destroy(&ppm->base); +} + +int +nouveau_perfmon_create_(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, + int length, void **pobject) +{ + struct nouveau_perfmon *ppm; + int ret; + + ret = nouveau_engine_create_(parent, engine, oclass, true, "PPM", + "perfmon", length, pobject); + ppm = *pobject; + if (ret) + return ret; + + INIT_LIST_HEAD(&ppm->domains); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c new file mode 100644 index 000000000000..50696cc7b7d7 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c @@ -0,0 +1,109 @@ +/* + * Copyright 2013 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 "priv.h" + +static void +pwr_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, + struct nouveau_perfctr *ctr) +{ + u32 mask = 0x00000000; + u32 ctrl = 0x00000001; + int i; + + for (i = 0; i < ARRAY_SIZE(ctr->signal) && ctr->signal[i]; i++) + mask |= 1 << (ctr->signal[i] - dom->signal); + + nv_wr32(ppm, 0x10a504 + (ctr->slot * 0x10), mask); + nv_wr32(ppm, 0x10a50c + (ctr->slot * 0x10), ctrl); + nv_wr32(ppm, 0x10a50c + (ppm->last * 0x10), 0x00000003); +} + +static void +pwr_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, + struct nouveau_perfctr *ctr) +{ + ctr->ctr = ppm->pwr[ctr->slot]; + ctr->clk = ppm->pwr[ppm->last]; +} + +static void +pwr_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom) +{ + int i; + + for (i = 0; i <= ppm->last; i++) { + ppm->pwr[i] = nv_rd32(ppm, 0x10a508 + (i * 0x10)); + nv_wr32(ppm, 0x10a508 + (i * 0x10), 0x80000000); + } +} + +static const struct nouveau_funcdom +pwr_perfctr_func = { + .init = pwr_perfctr_init, + .read = pwr_perfctr_read, + .next = pwr_perfctr_next, +}; + +const struct nouveau_specdom +nva3_perfmon_pwr[] = { + { 0x20, (const struct nouveau_specsig[]) { + { 0x00, "pwr_gr_idle" }, + { 0x04, "pwr_bsp_idle" }, + { 0x05, "pwr_vp_idle" }, + { 0x06, "pwr_ppp_idle" }, + { 0x13, "pwr_ce0_idle" }, + {} + }, &pwr_perfctr_func }, + {} +}; + +const struct nouveau_specdom +nvc0_perfmon_pwr[] = { + { 0x20, (const struct nouveau_specsig[]) { + { 0x00, "pwr_gr_idle" }, + { 0x04, "pwr_bsp_idle" }, + { 0x05, "pwr_vp_idle" }, + { 0x06, "pwr_ppp_idle" }, + { 0x13, "pwr_ce0_idle" }, + { 0x14, "pwr_ce1_idle" }, + {} + }, &pwr_perfctr_func }, + {} +}; + +const struct nouveau_specdom +nve0_perfmon_pwr[] = { + { 0x20, (const struct nouveau_specsig[]) { + { 0x00, "pwr_gr_idle" }, + { 0x04, "pwr_bsp_idle" }, + { 0x05, "pwr_vp_idle" }, + { 0x06, "pwr_ppp_idle" }, + { 0x13, "pwr_ce0_idle" }, + { 0x14, "pwr_ce1_idle" }, + { 0x15, "pwr_ce2_idle" }, + {} + }, &pwr_perfctr_func }, + {} +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c new file mode 100644 index 000000000000..b2a10785adb1 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c @@ -0,0 +1,143 @@ +/* + * Copyright 2013 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 "nv40.h" + +/******************************************************************************* + * Perfmon object classes + ******************************************************************************/ + +/******************************************************************************* + * PPM context + ******************************************************************************/ + +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + +static void +nv40_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, + struct nouveau_perfctr *ctr) +{ + struct nv40_perfmon_priv *priv = (void *)ppm; + struct nv40_perfmon_cntr *cntr = (void *)ctr; + u32 log = ctr->logic_op; + u32 src = 0x00000000; + int i; + + for (i = 0; i < 4 && ctr->signal[i]; i++) + src |= (ctr->signal[i] - dom->signal) << (i * 8); + + nv_wr32(priv, 0x00a7c0 + dom->addr, 0x00000001); + nv_wr32(priv, 0x00a400 + dom->addr + (cntr->base.slot * 0x40), src); + nv_wr32(priv, 0x00a420 + dom->addr + (cntr->base.slot * 0x40), log); +} + +static void +nv40_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, + struct nouveau_perfctr *ctr) +{ + struct nv40_perfmon_priv *priv = (void *)ppm; + struct nv40_perfmon_cntr *cntr = (void *)ctr; + + switch (cntr->base.slot) { + case 0: cntr->base.ctr = nv_rd32(priv, 0x00a700 + dom->addr); break; + case 1: cntr->base.ctr = nv_rd32(priv, 0x00a6c0 + dom->addr); break; + case 2: cntr->base.ctr = nv_rd32(priv, 0x00a680 + dom->addr); break; + case 3: cntr->base.ctr = nv_rd32(priv, 0x00a740 + dom->addr); break; + } + cntr->base.clk = nv_rd32(priv, 0x00a600 + dom->addr); +} + +static void +nv40_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom) +{ + struct nv40_perfmon_priv *priv = (void *)ppm; + if (priv->sequence != ppm->sequence) { + nv_wr32(priv, 0x400084, 0x00000020); + priv->sequence = ppm->sequence; + } +} + +const struct nouveau_funcdom +nv40_perfctr_func = { + .init = nv40_perfctr_init, + .read = nv40_perfctr_read, + .next = nv40_perfctr_next, +}; + +static const struct nouveau_specdom +nv40_perfmon[] = { + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + {} +}; + +int +nv40_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv40_perfmon_oclass *mclass = (void *)oclass; + struct nv40_perfmon_priv *priv; + int ret; + + ret = nouveau_perfmon_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_perfdom_new(&priv->base, "pm", 0, 0, 0, 4, mclass->doms); + if (ret) + return ret; + + nv_engine(priv)->cclass = &nouveau_perfmon_cclass; + nv_engine(priv)->sclass = nouveau_perfmon_sclass; + return 0; +} + +struct nouveau_oclass * +nv40_perfmon_oclass = &(struct nv40_perfmon_oclass) { + .base.handle = NV_ENGINE(PERFMON, 0x40), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv40_perfmon_ctor, + .dtor = _nouveau_perfmon_dtor, + .init = _nouveau_perfmon_init, + .fini = _nouveau_perfmon_fini, + }, + .doms = nv40_perfmon, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h new file mode 100644 index 000000000000..1b5792d1df14 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h @@ -0,0 +1,26 @@ +#ifndef __NVKM_PM_NV40_H__ +#define __NVKM_PM_NV40_H__ + +#include "priv.h" + +struct nv40_perfmon_oclass { + struct nouveau_oclass base; + const struct nouveau_specdom *doms; +}; + +struct nv40_perfmon_priv { + struct nouveau_perfmon base; + u32 sequence; +}; + +int nv40_perfmon_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *data, u32 size, + struct nouveau_object **pobject); + +struct nv40_perfmon_cntr { + struct nouveau_perfctr base; +}; + +extern const struct nouveau_funcdom nv40_perfctr_func; + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c new file mode 100644 index 000000000000..94217691fe67 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c @@ -0,0 +1,70 @@ +/* + * Copyright 2013 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 "nv40.h" + +/******************************************************************************* + * Perfmon object classes + ******************************************************************************/ + +/******************************************************************************* + * PPM context + ******************************************************************************/ + +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + +static const struct nouveau_specdom +nv50_perfmon[] = { + { 0x040, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x100, (const struct nouveau_specsig[]) { + { 0xc8, "gr_idle" }, + {} + }, &nv40_perfctr_func }, + { 0x100, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x020, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x040, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + {} +}; + +struct nouveau_oclass * +nv50_perfmon_oclass = &(struct nv40_perfmon_oclass) { + .base.handle = NV_ENGINE(PERFMON, 0x50), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv40_perfmon_ctor, + .dtor = _nouveau_perfmon_dtor, + .init = _nouveau_perfmon_init, + .fini = _nouveau_perfmon_fini, + }, + .doms = nv50_perfmon, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c new file mode 100644 index 000000000000..9232c7fc6253 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c @@ -0,0 +1,78 @@ +/* + * Copyright 2013 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 "nv40.h" + +/******************************************************************************* + * Perfmon object classes + ******************************************************************************/ + +/******************************************************************************* + * PPM context + ******************************************************************************/ + +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + +static const struct nouveau_specdom +nv84_perfmon[] = { + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + {} +}; + +struct nouveau_oclass * +nv84_perfmon_oclass = &(struct nv40_perfmon_oclass) { + .base.handle = NV_ENGINE(PERFMON, 0x84), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv40_perfmon_ctor, + .dtor = _nouveau_perfmon_dtor, + .init = _nouveau_perfmon_init, + .fini = _nouveau_perfmon_fini, + }, + .doms = nv84_perfmon, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c new file mode 100644 index 000000000000..6197ebdeb648 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c @@ -0,0 +1,96 @@ +/* + * Copyright 2013 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 "nv40.h" + +/******************************************************************************* + * Perfmon object classes + ******************************************************************************/ + +/******************************************************************************* + * PPM context + ******************************************************************************/ + +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + +static const struct nouveau_specdom +nva3_perfmon[] = { + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + { 0x20, (const struct nouveau_specsig[]) { + {} + }, &nv40_perfctr_func }, + {} +}; + +static int +nva3_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **object) +{ + int ret = nv40_perfmon_ctor(parent, engine, oclass, data, size, object); + if (ret == 0) { + struct nv40_perfmon_priv *priv = (void *)*object; + ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, + nva3_perfmon_pwr); + if (ret) + return ret; + + priv->base.last = 3; + } + return ret; +} + +struct nouveau_oclass * +nva3_perfmon_oclass = &(struct nv40_perfmon_oclass) { + .base.handle = NV_ENGINE(PERFMON, 0xa3), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nva3_perfmon_ctor, + .dtor = _nouveau_perfmon_dtor, + .init = _nouveau_perfmon_init, + .fini = _nouveau_perfmon_fini, + }, + .doms = nva3_perfmon, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c new file mode 100644 index 000000000000..74b241042502 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c @@ -0,0 +1,173 @@ +/* + * Copyright 2013 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 "nvc0.h" + +/******************************************************************************* + * Perfmon object classes + ******************************************************************************/ + +/******************************************************************************* + * PPM context + ******************************************************************************/ + +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + +static const struct nouveau_specdom +nvc0_perfmon_hub[] = { + {} +}; + +static const struct nouveau_specdom +nvc0_perfmon_gpc[] = { + {} +}; + +static const struct nouveau_specdom +nvc0_perfmon_part[] = { + {} +}; + +static void +nvc0_perfctr_init(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, + struct nouveau_perfctr *ctr) +{ + struct nvc0_perfmon_priv *priv = (void *)ppm; + struct nvc0_perfmon_cntr *cntr = (void *)ctr; + u32 log = ctr->logic_op; + u32 src = 0x00000000; + int i; + + for (i = 0; i < 4 && ctr->signal[i]; i++) + src |= (ctr->signal[i] - dom->signal) << (i * 8); + + nv_wr32(priv, dom->addr + 0x09c, 0x00040002); + nv_wr32(priv, dom->addr + 0x100, 0x00000000); + nv_wr32(priv, dom->addr + 0x040 + (cntr->base.slot * 0x08), src); + nv_wr32(priv, dom->addr + 0x044 + (cntr->base.slot * 0x08), log); +} + +static void +nvc0_perfctr_read(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom, + struct nouveau_perfctr *ctr) +{ + struct nvc0_perfmon_priv *priv = (void *)ppm; + struct nvc0_perfmon_cntr *cntr = (void *)ctr; + + switch (cntr->base.slot) { + case 0: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x08c); break; + case 1: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x088); break; + case 2: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x080); break; + case 3: cntr->base.ctr = nv_rd32(priv, dom->addr + 0x090); break; + } + cntr->base.clk = nv_rd32(priv, dom->addr + 0x070); +} + +static void +nvc0_perfctr_next(struct nouveau_perfmon *ppm, struct nouveau_perfdom *dom) +{ + struct nvc0_perfmon_priv *priv = (void *)ppm; + nv_wr32(priv, dom->addr + 0x06c, dom->signal_nr - 0x40 + 0x27); + nv_wr32(priv, dom->addr + 0x0ec, 0x00000011); +} + +const struct nouveau_funcdom +nvc0_perfctr_func = { + .init = nvc0_perfctr_init, + .read = nvc0_perfctr_read, + .next = nvc0_perfctr_next, +}; + +int +nvc0_perfmon_fini(struct nouveau_object *object, bool suspend) +{ + struct nvc0_perfmon_priv *priv = (void *)object; + nv_mask(priv, 0x000200, 0x10000000, 0x00000000); + nv_mask(priv, 0x000200, 0x10000000, 0x10000000); + return nouveau_perfmon_fini(&priv->base, suspend); +} + +static int +nvc0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nvc0_perfmon_priv *priv; + u32 mask; + int ret; + + ret = nouveau_perfmon_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, + nvc0_perfmon_pwr); + if (ret) + return ret; + + /* HUB */ + ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200, + nvc0_perfmon_hub); + if (ret) + return ret; + + /* GPC */ + mask = (1 << nv_rd32(priv, 0x022430)) - 1; + mask &= ~nv_rd32(priv, 0x022504); + mask &= ~nv_rd32(priv, 0x022584); + + ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000, + 0x1000, 0x200, nvc0_perfmon_gpc); + if (ret) + return ret; + + /* PART */ + mask = (1 << nv_rd32(priv, 0x022438)) - 1; + mask &= ~nv_rd32(priv, 0x022548); + mask &= ~nv_rd32(priv, 0x0225c8); + + ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000, + 0x1000, 0x200, nvc0_perfmon_part); + if (ret) + return ret; + + nv_engine(priv)->cclass = &nouveau_perfmon_cclass; + nv_engine(priv)->sclass = nouveau_perfmon_sclass; + priv->base.last = 7; + return 0; +} + +struct nouveau_oclass +nvc0_perfmon_oclass = { + .handle = NV_ENGINE(PERFMON, 0xc0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_perfmon_ctor, + .dtor = _nouveau_perfmon_dtor, + .init = _nouveau_perfmon_init, + .fini = nvc0_perfmon_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h new file mode 100644 index 000000000000..f66bca484263 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h @@ -0,0 +1,17 @@ +#ifndef __NVKM_PM_NVC0_H__ +#define __NVKM_PM_NVC0_H__ + +#include "priv.h" + +struct nvc0_perfmon_priv { + struct nouveau_perfmon base; +}; + +struct nvc0_perfmon_cntr { + struct nouveau_perfctr base; +}; + +extern const struct nouveau_funcdom nvc0_perfctr_func; +int nvc0_perfmon_fini(struct nouveau_object *, bool); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c new file mode 100644 index 000000000000..71d718c12075 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c @@ -0,0 +1,162 @@ +/* + * Copyright 2013 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 "nvc0.h" + +/******************************************************************************* + * Perfmon object classes + ******************************************************************************/ + +/******************************************************************************* + * PPM context + ******************************************************************************/ + +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + +static const struct nouveau_specdom +nve0_perfmon_hub[] = { + { 0x60, (const struct nouveau_specsig[]) { + { 0x47, "hub00_user_0" }, + {} + }, &nvc0_perfctr_func }, + { 0x40, (const struct nouveau_specsig[]) { + { 0x27, "hub01_user_0" }, + {} + }, &nvc0_perfctr_func }, + { 0x60, (const struct nouveau_specsig[]) { + { 0x47, "hub02_user_0" }, + {} + }, &nvc0_perfctr_func }, + { 0x60, (const struct nouveau_specsig[]) { + { 0x47, "hub03_user_0" }, + {} + }, &nvc0_perfctr_func }, + { 0x40, (const struct nouveau_specsig[]) { + { 0x03, "host_mmio_rd" }, + { 0x27, "hub04_user_0" }, + {} + }, &nvc0_perfctr_func }, + { 0x60, (const struct nouveau_specsig[]) { + { 0x47, "hub05_user_0" }, + {} + }, &nvc0_perfctr_func }, + { 0xc0, (const struct nouveau_specsig[]) { + { 0x74, "host_fb_rd3x" }, + { 0x75, "host_fb_rd3x_2" }, + { 0xa7, "hub06_user_0" }, + {} + }, &nvc0_perfctr_func }, + { 0x60, (const struct nouveau_specsig[]) { + { 0x47, "hub07_user_0" }, + {} + }, &nvc0_perfctr_func }, + {} +}; + +static const struct nouveau_specdom +nve0_perfmon_gpc[] = { + { 0xe0, (const struct nouveau_specsig[]) { + { 0xc7, "gpc00_user_0" }, + {} + }, &nvc0_perfctr_func }, + {} +}; + +static const struct nouveau_specdom +nve0_perfmon_part[] = { + { 0x60, (const struct nouveau_specsig[]) { + { 0x47, "part00_user_0" }, + {} + }, &nvc0_perfctr_func }, + { 0x60, (const struct nouveau_specsig[]) { + { 0x47, "part01_user_0" }, + {} + }, &nvc0_perfctr_func }, + {} +}; + +static int +nve0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nvc0_perfmon_priv *priv; + u32 mask; + int ret; + + ret = nouveau_perfmon_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + /* PDAEMON */ + ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, + nve0_perfmon_pwr); + if (ret) + return ret; + + /* HUB */ + ret = nouveau_perfdom_new(&priv->base, "hub", 0, 0x1b0000, 0, 0x200, + nve0_perfmon_hub); + if (ret) + return ret; + + /* GPC */ + mask = (1 << nv_rd32(priv, 0x022430)) - 1; + mask &= ~nv_rd32(priv, 0x022504); + mask &= ~nv_rd32(priv, 0x022584); + + ret = nouveau_perfdom_new(&priv->base, "gpc", mask, 0x180000, + 0x1000, 0x200, nve0_perfmon_gpc); + if (ret) + return ret; + + /* PART */ + mask = (1 << nv_rd32(priv, 0x022438)) - 1; + mask &= ~nv_rd32(priv, 0x022548); + mask &= ~nv_rd32(priv, 0x0225c8); + + ret = nouveau_perfdom_new(&priv->base, "part", mask, 0x1a0000, + 0x1000, 0x200, nve0_perfmon_part); + if (ret) + return ret; + + nv_engine(priv)->cclass = &nouveau_perfmon_cclass; + nv_engine(priv)->sclass = nouveau_perfmon_sclass; + priv->base.last = 7; + return 0; +} + +struct nouveau_oclass +nve0_perfmon_oclass = { + .handle = NV_ENGINE(PERFMON, 0xe0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nve0_perfmon_ctor, + .dtor = _nouveau_perfmon_dtor, + .init = _nouveau_perfmon_init, + .fini = nvc0_perfmon_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c new file mode 100644 index 000000000000..47256f78a895 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c @@ -0,0 +1,71 @@ +/* + * Copyright 2013 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 "nvc0.h" + +/******************************************************************************* + * Perfmon object classes + ******************************************************************************/ + +/******************************************************************************* + * PPM context + ******************************************************************************/ + +/******************************************************************************* + * PPM engine/subdev functions + ******************************************************************************/ + +static int +nvf0_perfmon_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nvc0_perfmon_priv *priv; + int ret; + + ret = nouveau_perfmon_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + ret = nouveau_perfdom_new(&priv->base, "pwr", 0, 0, 0, 0, + nve0_perfmon_pwr); + if (ret) + return ret; + + nv_engine(priv)->cclass = &nouveau_perfmon_cclass; + nv_engine(priv)->sclass = nouveau_perfmon_sclass; + return 0; +} + +struct nouveau_oclass +nvf0_perfmon_oclass = { + .handle = NV_ENGINE(PERFMON, 0xf0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvf0_perfmon_ctor, + .dtor = _nouveau_perfmon_dtor, + .init = _nouveau_perfmon_init, + .fini = nvc0_perfmon_fini, + }, +}; diff --git a/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h b/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h new file mode 100644 index 000000000000..0ac8714fe0ba --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h @@ -0,0 +1,91 @@ +#ifndef __NVKM_PERFMON_PRIV_H__ +#define __NVKM_PERFMON_PRIV_H__ + +#include <engine/perfmon.h> + +struct nouveau_perfctr { + struct nouveau_object base; + struct list_head head; + struct nouveau_perfsig *signal[4]; + int slot; + u32 logic_op; + u32 clk; + u32 ctr; +}; + +extern struct nouveau_oclass nouveau_perfmon_sclass[]; + +struct nouveau_perfctx { + struct nouveau_engctx base; +}; + +extern struct nouveau_oclass nouveau_perfmon_cclass; + +struct nouveau_specsig { + u8 signal; + const char *name; +}; + +struct nouveau_perfsig { + const char *name; +}; + +struct nouveau_perfdom; +struct nouveau_perfctr * +nouveau_perfsig_wrap(struct nouveau_perfmon *, const char *, + struct nouveau_perfdom **); + +struct nouveau_specdom { + u16 signal_nr; + const struct nouveau_specsig *signal; + const struct nouveau_funcdom *func; +}; + +extern const struct nouveau_specdom nva3_perfmon_pwr[]; +extern const struct nouveau_specdom nvc0_perfmon_pwr[]; +extern const struct nouveau_specdom nve0_perfmon_pwr[]; + +struct nouveau_perfdom { + struct list_head head; + struct list_head list; + const struct nouveau_funcdom *func; + char name[32]; + u32 addr; + u8 quad; + u32 signal_nr; + struct nouveau_perfsig signal[]; +}; + +struct nouveau_funcdom { + void (*init)(struct nouveau_perfmon *, struct nouveau_perfdom *, + struct nouveau_perfctr *); + void (*read)(struct nouveau_perfmon *, struct nouveau_perfdom *, + struct nouveau_perfctr *); + void (*next)(struct nouveau_perfmon *, struct nouveau_perfdom *); +}; + +int nouveau_perfdom_new(struct nouveau_perfmon *, const char *, u32, + u32, u32, u32, const struct nouveau_specdom *); + +#define nouveau_perfmon_create(p,e,o,d) \ + nouveau_perfmon_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_perfmon_dtor(p) ({ \ + struct nouveau_perfmon *c = (p); \ + _nouveau_perfmon_dtor(nv_object(c)); \ +}) +#define nouveau_perfmon_init(p) ({ \ + struct nouveau_perfmon *c = (p); \ + _nouveau_perfmon_init(nv_object(c)); \ +}) +#define nouveau_perfmon_fini(p,s) ({ \ + struct nouveau_perfmon *c = (p); \ + _nouveau_perfmon_fini(nv_object(c), (s)); \ +}) + +int nouveau_perfmon_create_(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, int, void **); +void _nouveau_perfmon_dtor(struct nouveau_object *); +int _nouveau_perfmon_init(struct nouveau_object *); +int _nouveau_perfmon_fini(struct nouveau_object *, bool); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c b/drivers/gpu/drm/nouveau/core/engine/software/nv04.c index 2a859a31c30d..c571758e4a27 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv04.c @@ -135,8 +135,8 @@ nv04_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -struct nouveau_oclass -nv04_software_oclass = { +struct nouveau_oclass * +nv04_software_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(SW, 0x04), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv04_software_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c b/drivers/gpu/drm/nouveau/core/engine/software/nv10.c index a019364b1e13..a62f11a78430 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv10.c @@ -117,8 +117,8 @@ nv10_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -struct nouveau_oclass -nv10_software_oclass = { +struct nouveau_oclass * +nv10_software_oclass = &(struct nouveau_oclass) { .handle = NV_ENGINE(SW, 0x10), .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv10_software_ctor, diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c index c48e74953771..b574dd4bb828 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c @@ -32,16 +32,9 @@ #include <subdev/bar.h> -#include <engine/software.h> #include <engine/disp.h> -struct nv50_software_priv { - struct nouveau_software base; -}; - -struct nv50_software_chan { - struct nouveau_software_chan base; -}; +#include "nv50.h" /******************************************************************************* * software object classes @@ -62,7 +55,7 @@ nv50_software_mthd_dma_vblsem(struct nouveau_object *object, u32 mthd, if (nv_iclass(handle->object, NV_GPUOBJ_CLASS)) { struct nouveau_gpuobj *gpuobj = nv_gpuobj(handle->object); - chan->base.vblank.ctxdma = gpuobj->node->offset >> 4; + chan->vblank.ctxdma = gpuobj->node->offset >> 4; ret = 0; } nouveau_namedb_put(handle); @@ -74,34 +67,33 @@ nv50_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); - chan->base.vblank.offset = *(u32 *)args; + chan->vblank.offset = *(u32 *)args; return 0; } -static int +int nv50_software_mthd_vblsem_value(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); - chan->base.vblank.value = *(u32 *)args; + chan->vblank.value = *(u32 *)args; return 0; } -static int +int nv50_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd, void *args, u32 size) { struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); - struct nouveau_disp *disp = nouveau_disp(object); - u32 crtc = *(u32 *)args; - if (crtc > 1) + u32 head = *(u32 *)args; + if (head >= chan->vblank.nr_event) return -EINVAL; - nouveau_event_get(disp->vblank, crtc, &chan->base.vblank.event); + nouveau_event_get(chan->vblank.event[head]); return 0; } -static int +int nv50_software_mthd_flip(struct nouveau_object *object, u32 mthd, void *args, u32 size) { @@ -132,10 +124,9 @@ nv50_software_sclass[] = { ******************************************************************************/ static int -nv50_software_vblsem_release(struct nouveau_eventh *event, int head) +nv50_software_vblsem_release(void *data, int head) { - struct nouveau_software_chan *chan = - container_of(event, struct nouveau_software_chan, vblank.event); + struct nv50_software_chan *chan = data; struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; struct nouveau_bar *bar = nouveau_bar(priv); @@ -154,45 +145,76 @@ nv50_software_vblsem_release(struct nouveau_eventh *event, int head) return NVKM_EVENT_DROP; } -static int +void +nv50_software_context_dtor(struct nouveau_object *object) +{ + struct nv50_software_chan *chan = (void *)object; + int i; + + if (chan->vblank.event) { + for (i = 0; i < chan->vblank.nr_event; i++) + nouveau_event_ref(NULL, &chan->vblank.event[i]); + kfree(chan->vblank.event); + } + + nouveau_software_context_destroy(&chan->base); +} + +int nv50_software_context_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + struct nouveau_disp *pdisp = nouveau_disp(parent); + struct nv50_software_cclass *pclass = (void *)oclass; struct nv50_software_chan *chan; - int ret; + int ret, i; ret = nouveau_software_context_create(parent, engine, oclass, &chan); *pobject = nv_object(chan); if (ret) return ret; - chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12; - chan->base.vblank.event.func = nv50_software_vblsem_release; + chan->vblank.nr_event = pdisp->vblank->index_nr; + chan->vblank.event = kzalloc(chan->vblank.nr_event * + sizeof(*chan->vblank.event), GFP_KERNEL); + if (!chan->vblank.event) + return -ENOMEM; + + for (i = 0; i < chan->vblank.nr_event; i++) { + ret = nouveau_event_new(pdisp->vblank, i, pclass->vblank, + chan, &chan->vblank.event[i]); + if (ret) + return ret; + } + + chan->vblank.channel = nv_gpuobj(parent->parent)->addr >> 12; return 0; } -static struct nouveau_oclass +static struct nv50_software_cclass nv50_software_cclass = { - .handle = NV_ENGCTX(SW, 0x50), - .ofuncs = &(struct nouveau_ofuncs) { + .base.handle = NV_ENGCTX(SW, 0x50), + .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_software_context_ctor, .dtor = _nouveau_software_context_dtor, .init = _nouveau_software_context_init, .fini = _nouveau_software_context_fini, }, + .vblank = nv50_software_vblsem_release, }; /******************************************************************************* * software engine/subdev functions ******************************************************************************/ -static int +int nv50_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { + struct nv50_software_oclass *pclass = (void *)oclass; struct nv50_software_priv *priv; int ret; @@ -201,19 +223,21 @@ nv50_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_engine(priv)->cclass = &nv50_software_cclass; - nv_engine(priv)->sclass = nv50_software_sclass; + nv_engine(priv)->cclass = pclass->cclass; + nv_engine(priv)->sclass = pclass->sclass; nv_subdev(priv)->intr = nv04_software_intr; return 0; } -struct nouveau_oclass -nv50_software_oclass = { - .handle = NV_ENGINE(SW, 0x50), - .ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass * +nv50_software_oclass = &(struct nv50_software_oclass) { + .base.handle = NV_ENGINE(SW, 0x50), + .base.ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_software_ctor, .dtor = _nouveau_software_dtor, .init = _nouveau_software_init, .fini = _nouveau_software_fini, }, -}; + .cclass = &nv50_software_cclass.base, + .sclass = nv50_software_sclass, +}.base; diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h b/drivers/gpu/drm/nouveau/core/engine/software/nv50.h new file mode 100644 index 000000000000..2de370c21279 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.h @@ -0,0 +1,47 @@ +#ifndef __NVKM_SW_NV50_H__ +#define __NVKM_SW_NV50_H__ + +#include <engine/software.h> + +struct nv50_software_oclass { + struct nouveau_oclass base; + struct nouveau_oclass *cclass; + struct nouveau_oclass *sclass; +}; + +struct nv50_software_priv { + struct nouveau_software base; +}; + +int nv50_software_ctor(struct nouveau_object *, struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); + +struct nv50_software_cclass { + struct nouveau_oclass base; + int (*vblank)(void *, int); +}; + +struct nv50_software_chan { + struct nouveau_software_chan base; + struct { + struct nouveau_eventh **event; + int nr_event; + u32 channel; + u32 ctxdma; + u64 offset; + u32 value; + } vblank; +}; + +int nv50_software_context_ctor(struct nouveau_object *, + struct nouveau_object *, + struct nouveau_oclass *, void *, u32, + struct nouveau_object **); +void nv50_software_context_dtor(struct nouveau_object *); + +int nv50_software_mthd_vblsem_value(struct nouveau_object *, u32, void *, u32); +int nv50_software_mthd_vblsem_release(struct nouveau_object *, u32, void *, u32); +int nv50_software_mthd_flip(struct nouveau_object *, u32, void *, u32); + +#endif diff --git a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c index d698e710ddd4..f9430c1bf3e5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c @@ -32,13 +32,7 @@ #include <engine/software.h> #include <engine/disp.h> -struct nvc0_software_priv { - struct nouveau_software base; -}; - -struct nvc0_software_chan { - struct nouveau_software_chan base; -}; +#include "nv50.h" /******************************************************************************* * software object classes @@ -48,58 +42,24 @@ static int nvc0_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd, void *args, u32 size) { - struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); + struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); u64 data = *(u32 *)args; if (mthd == 0x0400) { - chan->base.vblank.offset &= 0x00ffffffffULL; - chan->base.vblank.offset |= data << 32; + chan->vblank.offset &= 0x00ffffffffULL; + chan->vblank.offset |= data << 32; } else { - chan->base.vblank.offset &= 0xff00000000ULL; - chan->base.vblank.offset |= data; + chan->vblank.offset &= 0xff00000000ULL; + chan->vblank.offset |= data; } return 0; } static int -nvc0_software_mthd_vblsem_value(struct nouveau_object *object, u32 mthd, - void *args, u32 size) -{ - struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); - chan->base.vblank.value = *(u32 *)args; - return 0; -} - -static int -nvc0_software_mthd_vblsem_release(struct nouveau_object *object, u32 mthd, - void *args, u32 size) -{ - struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); - struct nouveau_disp *disp = nouveau_disp(object); - u32 crtc = *(u32 *)args; - - if ((nv_device(object)->card_type < NV_E0 && crtc > 1) || crtc > 3) - return -EINVAL; - - nouveau_event_get(disp->vblank, crtc, &chan->base.vblank.event); - return 0; -} - -static int -nvc0_software_mthd_flip(struct nouveau_object *object, u32 mthd, - void *args, u32 size) -{ - struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); - if (chan->base.flip) - return chan->base.flip(chan->base.flip_data); - return -EINVAL; -} - -static int nvc0_software_mthd_mp_control(struct nouveau_object *object, u32 mthd, void *args, u32 size) { - struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); - struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine; + struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); + struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; u32 data = *(u32 *)args; switch (mthd) { @@ -124,9 +84,9 @@ static struct nouveau_omthds nvc0_software_omthds[] = { { 0x0400, 0x0400, nvc0_software_mthd_vblsem_offset }, { 0x0404, 0x0404, nvc0_software_mthd_vblsem_offset }, - { 0x0408, 0x0408, nvc0_software_mthd_vblsem_value }, - { 0x040c, 0x040c, nvc0_software_mthd_vblsem_release }, - { 0x0500, 0x0500, nvc0_software_mthd_flip }, + { 0x0408, 0x0408, nv50_software_mthd_vblsem_value }, + { 0x040c, 0x040c, nv50_software_mthd_vblsem_release }, + { 0x0500, 0x0500, nv50_software_mthd_flip }, { 0x0600, 0x0600, nvc0_software_mthd_mp_control }, { 0x0644, 0x0644, nvc0_software_mthd_mp_control }, { 0x06ac, 0x06ac, nvc0_software_mthd_mp_control }, @@ -144,11 +104,10 @@ nvc0_software_sclass[] = { ******************************************************************************/ static int -nvc0_software_vblsem_release(struct nouveau_eventh *event, int head) +nvc0_software_vblsem_release(void *data, int head) { - struct nouveau_software_chan *chan = - container_of(event, struct nouveau_software_chan, vblank.event); - struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine; + struct nv50_software_chan *chan = data; + struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; struct nouveau_bar *bar = nouveau_bar(priv); nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); @@ -160,66 +119,31 @@ nvc0_software_vblsem_release(struct nouveau_eventh *event, int head) return NVKM_EVENT_DROP; } -static int -nvc0_software_context_ctor(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nvc0_software_chan *chan; - int ret; - - ret = nouveau_software_context_create(parent, engine, oclass, &chan); - *pobject = nv_object(chan); - if (ret) - return ret; - - chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12; - chan->base.vblank.event.func = nvc0_software_vblsem_release; - return 0; -} - -static struct nouveau_oclass +static struct nv50_software_cclass nvc0_software_cclass = { - .handle = NV_ENGCTX(SW, 0xc0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvc0_software_context_ctor, + .base.handle = NV_ENGCTX(SW, 0xc0), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_software_context_ctor, .dtor = _nouveau_software_context_dtor, .init = _nouveau_software_context_init, .fini = _nouveau_software_context_fini, }, + .vblank = nvc0_software_vblsem_release, }; /******************************************************************************* * software engine/subdev functions ******************************************************************************/ -static int -nvc0_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nvc0_software_priv *priv; - int ret; - - ret = nouveau_software_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - nv_engine(priv)->cclass = &nvc0_software_cclass; - nv_engine(priv)->sclass = nvc0_software_sclass; - nv_subdev(priv)->intr = nv04_software_intr; - return 0; -} - -struct nouveau_oclass -nvc0_software_oclass = { - .handle = NV_ENGINE(SW, 0xc0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvc0_software_ctor, +struct nouveau_oclass * +nvc0_software_oclass = &(struct nv50_software_oclass) { + .base.handle = NV_ENGINE(SW, 0xc0), + .base.ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_software_ctor, .dtor = _nouveau_software_dtor, .init = _nouveau_software_init, .fini = _nouveau_software_fini, }, -}; + .cclass = &nvc0_software_cclass.base, + .sclass = nvc0_software_sclass, +}.base; |