diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau')
250 files changed, 7018 insertions, 20125 deletions
diff --git a/drivers/gpu/drm/nouveau/Kconfig b/drivers/gpu/drm/nouveau/Kconfig index 7cf787d..ff80f12 100644 --- a/drivers/gpu/drm/nouveau/Kconfig +++ b/drivers/gpu/drm/nouveau/Kconfig @@ -3,7 +3,6 @@ config DRM_NOUVEAU depends on DRM && PCI select FW_LOADER select DRM_KMS_HELPER - select DRM_KMS_FB_HELPER select DRM_TTM select FB_CFB_FILLRECT select FB_CFB_COPYAREA diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index b3fa1ba..d939a1d 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile @@ -28,9 +28,7 @@ nouveau-y += core/subdev/bar/nv50.o nouveau-y += core/subdev/bar/nvc0.o nouveau-y += core/subdev/bios/base.o nouveau-y += core/subdev/bios/bit.o -nouveau-y += core/subdev/bios/boost.o nouveau-y += core/subdev/bios/conn.o -nouveau-y += core/subdev/bios/cstep.o nouveau-y += core/subdev/bios/dcb.o nouveau-y += core/subdev/bios/disp.o nouveau-y += core/subdev/bios/dp.o @@ -41,27 +39,17 @@ nouveau-y += core/subdev/bios/init.o nouveau-y += core/subdev/bios/mxm.o nouveau-y += core/subdev/bios/perf.o nouveau-y += core/subdev/bios/pll.o -nouveau-y += core/subdev/bios/rammap.o -nouveau-y += core/subdev/bios/timing.o nouveau-y += core/subdev/bios/therm.o -nouveau-y += core/subdev/bios/vmap.o -nouveau-y += core/subdev/bios/volt.o nouveau-y += core/subdev/bios/xpio.o -nouveau-y += core/subdev/bus/hwsq.o nouveau-y += core/subdev/bus/nv04.o nouveau-y += core/subdev/bus/nv31.o nouveau-y += core/subdev/bus/nv50.o -nouveau-y += core/subdev/bus/nv94.o nouveau-y += core/subdev/bus/nvc0.o -nouveau-y += core/subdev/clock/base.o nouveau-y += core/subdev/clock/nv04.o nouveau-y += core/subdev/clock/nv40.o nouveau-y += core/subdev/clock/nv50.o -nouveau-y += core/subdev/clock/nv84.o nouveau-y += core/subdev/clock/nva3.o -nouveau-y += core/subdev/clock/nvaa.o nouveau-y += core/subdev/clock/nvc0.o -nouveau-y += core/subdev/clock/nve0.o nouveau-y += core/subdev/clock/pllnv04.o nouveau-y += core/subdev/clock/pllnva3.o nouveau-y += core/subdev/devinit/base.o @@ -90,12 +78,7 @@ nouveau-y += core/subdev/fb/nv47.o nouveau-y += core/subdev/fb/nv49.o nouveau-y += core/subdev/fb/nv4e.o nouveau-y += core/subdev/fb/nv50.o -nouveau-y += core/subdev/fb/nv84.o -nouveau-y += core/subdev/fb/nva3.o -nouveau-y += core/subdev/fb/nvaa.o -nouveau-y += core/subdev/fb/nvaf.o nouveau-y += core/subdev/fb/nvc0.o -nouveau-y += core/subdev/fb/nve0.o nouveau-y += core/subdev/fb/ramnv04.o nouveau-y += core/subdev/fb/ramnv10.o nouveau-y += core/subdev/fb/ramnv1a.o @@ -106,12 +89,7 @@ nouveau-y += core/subdev/fb/ramnv44.o nouveau-y += core/subdev/fb/ramnv49.o nouveau-y += core/subdev/fb/ramnv4e.o nouveau-y += core/subdev/fb/ramnv50.o -nouveau-y += core/subdev/fb/ramnva3.o -nouveau-y += core/subdev/fb/ramnvaa.o nouveau-y += core/subdev/fb/ramnvc0.o -nouveau-y += core/subdev/fb/ramnve0.o -nouveau-y += core/subdev/fb/sddr3.o -nouveau-y += core/subdev/fb/gddr5.o nouveau-y += core/subdev/gpio/base.o nouveau-y += core/subdev/gpio/nv10.o nouveau-y += core/subdev/gpio/nv50.o @@ -135,22 +113,13 @@ nouveau-y += core/subdev/instmem/nv50.o nouveau-y += core/subdev/ltcg/nvc0.o nouveau-y += core/subdev/mc/base.o nouveau-y += core/subdev/mc/nv04.o -nouveau-y += core/subdev/mc/nv40.o nouveau-y += core/subdev/mc/nv44.o nouveau-y += core/subdev/mc/nv50.o -nouveau-y += core/subdev/mc/nv94.o nouveau-y += core/subdev/mc/nv98.o nouveau-y += core/subdev/mc/nvc0.o -nouveau-y += core/subdev/mc/nvc3.o nouveau-y += core/subdev/mxm/base.o nouveau-y += core/subdev/mxm/mxms.o nouveau-y += core/subdev/mxm/nv50.o -nouveau-y += core/subdev/pwr/base.o -nouveau-y += core/subdev/pwr/memx.o -nouveau-y += core/subdev/pwr/nva3.o -nouveau-y += core/subdev/pwr/nvc0.o -nouveau-y += core/subdev/pwr/nvd0.o -nouveau-y += core/subdev/pwr/nv108.o nouveau-y += core/subdev/therm/base.o nouveau-y += core/subdev/therm/fan.o nouveau-y += core/subdev/therm/fannil.o @@ -171,9 +140,6 @@ nouveau-y += core/subdev/vm/nv41.o nouveau-y += core/subdev/vm/nv44.o nouveau-y += core/subdev/vm/nv50.o nouveau-y += core/subdev/vm/nvc0.o -nouveau-y += core/subdev/volt/base.o -nouveau-y += core/subdev/volt/gpio.o -nouveau-y += core/subdev/volt/nv40.o nouveau-y += core/engine/falcon.o nouveau-y += core/engine/xtensa.o @@ -192,7 +158,6 @@ nouveau-y += core/engine/copy/nve0.o nouveau-y += core/engine/crypt/nv84.o nouveau-y += core/engine/crypt/nv98.o nouveau-y += core/engine/device/base.o -nouveau-y += core/engine/device/ctrl.o nouveau-y += core/engine/device/nv04.o nouveau-y += core/engine/device/nv10.o nouveau-y += core/engine/device/nv20.o @@ -262,18 +227,8 @@ nouveau-y += core/engine/graph/nve4.o nouveau-y += core/engine/graph/nvf0.o nouveau-y += core/engine/mpeg/nv31.o nouveau-y += core/engine/mpeg/nv40.o -nouveau-y += core/engine/mpeg/nv44.o nouveau-y += core/engine/mpeg/nv50.o nouveau-y += core/engine/mpeg/nv84.o -nouveau-y += core/engine/perfmon/base.o -nouveau-y += core/engine/perfmon/daemon.o -nouveau-y += core/engine/perfmon/nv40.o -nouveau-y += core/engine/perfmon/nv50.o -nouveau-y += core/engine/perfmon/nv84.o -nouveau-y += core/engine/perfmon/nva3.o -nouveau-y += core/engine/perfmon/nvc0.o -nouveau-y += core/engine/perfmon/nve0.o -nouveau-y += core/engine/perfmon/nvf0.o nouveau-y += core/engine/ppp/nv98.o nouveau-y += core/engine/ppp/nvc0.o nouveau-y += core/engine/software/nv04.o @@ -305,7 +260,9 @@ include $(src)/dispnv04/Makefile nouveau-y += nv50_display.o # drm/pm -nouveau-y += nouveau_hwmon.o nouveau_sysfs.o +nouveau-y += nouveau_pm.o nouveau_volt.o nouveau_perf.o +nouveau-y += nv04_pm.o nv40_pm.o nv50_pm.o nva3_pm.o nvc0_pm.o +nouveau-y += nouveau_mem.o # other random bits nouveau-$(CONFIG_COMPAT) += nouveau_ioc32.o diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c index 3f3c765..7eb81c1 100644 --- a/drivers/gpu/drm/nouveau/core/core/event.c +++ b/drivers/gpu/drm/nouveau/core/core/event.c @@ -23,114 +23,62 @@ #include <core/os.h> #include <core/event.h> -void -nouveau_event_put(struct nouveau_eventh *handler) +static void +nouveau_event_put_locked(struct nouveau_event *event, int index, + struct nouveau_eventh *handler) { - struct nouveau_event *event = handler->event; - unsigned long flags; - if (__test_and_clear_bit(NVKM_EVENT_ENABLE, &handler->flags)) { - spin_lock_irqsave(&event->refs_lock, flags); - if (!--event->index[handler->index].refs) { - if (event->disable) - event->disable(event, handler->index); - } - spin_unlock_irqrestore(&event->refs_lock, flags); + if (!--event->index[index].refs) { + if (event->disable) + event->disable(event, index); } + list_del(&handler->head); } void -nouveau_event_get(struct nouveau_eventh *handler) +nouveau_event_put(struct nouveau_event *event, int index, + struct nouveau_eventh *handler) { - struct nouveau_event *event = handler->event; unsigned long flags; - if (!__test_and_set_bit(NVKM_EVENT_ENABLE, &handler->flags)) { - spin_lock_irqsave(&event->refs_lock, flags); - if (!event->index[handler->index].refs++) { - if (event->enable) - event->enable(event, handler->index); - } - spin_unlock_irqrestore(&event->refs_lock, flags); - } -} -static void -nouveau_event_fini(struct nouveau_eventh *handler) -{ - struct nouveau_event *event = handler->event; - unsigned long flags; - nouveau_event_put(handler); - spin_lock_irqsave(&event->list_lock, flags); - list_del(&handler->head); - spin_unlock_irqrestore(&event->list_lock, flags); + spin_lock_irqsave(&event->lock, flags); + if (index < event->index_nr) + nouveau_event_put_locked(event, index, handler); + spin_unlock_irqrestore(&event->lock, flags); } -static int -nouveau_event_init(struct nouveau_event *event, int index, - int (*func)(void *, int), void *priv, - struct nouveau_eventh *handler) +void +nouveau_event_get(struct nouveau_event *event, int index, + struct nouveau_eventh *handler) { unsigned long flags; - if (index >= event->index_nr) - return -EINVAL; - - handler->event = event; - handler->flags = 0; - handler->index = index; - handler->func = func; - handler->priv = priv; - - spin_lock_irqsave(&event->list_lock, flags); - list_add_tail(&handler->head, &event->index[index].list); - spin_unlock_irqrestore(&event->list_lock, flags); - return 0; -} - -int -nouveau_event_new(struct nouveau_event *event, int index, - int (*func)(void *, int), void *priv, - struct nouveau_eventh **phandler) -{ - struct nouveau_eventh *handler; - int ret = -ENOMEM; - - handler = *phandler = kmalloc(sizeof(*handler), GFP_KERNEL); - if (handler) { - ret = nouveau_event_init(event, index, func, priv, handler); - if (ret) - kfree(handler); - } - - return ret; -} - -void -nouveau_event_ref(struct nouveau_eventh *handler, struct nouveau_eventh **ref) -{ - BUG_ON(handler != NULL); - if (*ref) { - nouveau_event_fini(*ref); - kfree(*ref); + spin_lock_irqsave(&event->lock, flags); + if (index < event->index_nr) { + list_add(&handler->head, &event->index[index].list); + if (!event->index[index].refs++) { + if (event->enable) + event->enable(event, index); + } } - *ref = handler; + spin_unlock_irqrestore(&event->lock, flags); } void nouveau_event_trigger(struct nouveau_event *event, int index) { - struct nouveau_eventh *handler; + struct nouveau_eventh *handler, *temp; unsigned long flags; - if (WARN_ON(index >= event->index_nr)) + if (index >= event->index_nr) return; - spin_lock_irqsave(&event->list_lock, flags); - list_for_each_entry(handler, &event->index[index].list, head) { - if (test_bit(NVKM_EVENT_ENABLE, &handler->flags) && - handler->func(handler->priv, index) == NVKM_EVENT_DROP) - nouveau_event_put(handler); + spin_lock_irqsave(&event->lock, flags); + list_for_each_entry_safe(handler, temp, &event->index[index].list, head) { + if (handler->func(handler, index) == NVKM_EVENT_DROP) { + nouveau_event_put_locked(event, index, handler); + } } - spin_unlock_irqrestore(&event->list_lock, flags); + spin_unlock_irqrestore(&event->lock, flags); } void @@ -154,8 +102,7 @@ nouveau_event_create(int index_nr, struct nouveau_event **pevent) if (!event) return -ENOMEM; - spin_lock_init(&event->list_lock); - spin_lock_init(&event->refs_lock); + spin_lock_init(&event->lock); for (i = 0; i < index_nr; i++) INIT_LIST_HEAD(&event->index[i].list); event->index_nr = index_nr; diff --git a/drivers/gpu/drm/nouveau/core/core/option.c b/drivers/gpu/drm/nouveau/core/core/option.c index 9f6fcc5..62a432e 100644 --- a/drivers/gpu/drm/nouveau/core/core/option.c +++ b/drivers/gpu/drm/nouveau/core/core/option.c @@ -25,6 +25,15 @@ #include <core/option.h> #include <core/debug.h> +/* compares unterminated string 'str' with zero-terminated string 'cmp' */ +static inline int +strncasecmpz(const char *str, const char *cmp, size_t len) +{ + if (strlen(cmp) != len) + return len; + return strncasecmp(str, cmp, len); +} + const char * nouveau_stropt(const char *optstr, const char *opt, int *arglen) { @@ -96,7 +105,7 @@ nouveau_dbgopt(const char *optstr, const char *sub) else if (!strncasecmpz(optstr, "warn", len)) level = NV_DBG_WARN; else if (!strncasecmpz(optstr, "info", len)) - level = NV_DBG_INFO_NORMAL; + level = NV_DBG_INFO; else if (!strncasecmpz(optstr, "debug", len)) level = NV_DBG_DEBUG; else if (!strncasecmpz(optstr, "trace", len)) diff --git a/drivers/gpu/drm/nouveau/core/core/printk.c b/drivers/gpu/drm/nouveau/core/core/printk.c index 03e0060..52fb2aa 100644 --- a/drivers/gpu/drm/nouveau/core/core/printk.c +++ b/drivers/gpu/drm/nouveau/core/core/printk.c @@ -27,38 +27,16 @@ #include <core/subdev.h> #include <core/printk.h> -int nv_info_debug_level = NV_DBG_INFO_NORMAL; +int nv_printk_suspend_level = NV_DBG_DEBUG; void -nv_printk_(struct nouveau_object *object, int level, const char *fmt, ...) +nv_printk_(struct nouveau_object *object, const char *pfx, int level, + const char *fmt, ...) { static const char name[] = { '!', 'E', 'W', ' ', 'D', 'T', 'P', 'S' }; - const char *pfx; char mfmt[256]; va_list args; - switch (level) { - case NV_DBG_FATAL: - pfx = KERN_CRIT; - break; - case NV_DBG_ERROR: - pfx = KERN_ERR; - break; - case NV_DBG_WARN: - pfx = KERN_WARNING; - break; - case NV_DBG_INFO_NORMAL: - pfx = KERN_INFO; - break; - case NV_DBG_DEBUG: - case NV_DBG_PARANOIA: - case NV_DBG_TRACE: - case NV_DBG_SPAM: - default: - pfx = KERN_DEBUG; - break; - } - if (object && !nv_iclass(object, NV_CLIENT_CLASS)) { struct nouveau_object *device = object; struct nouveau_object *subdev = object; @@ -96,3 +74,20 @@ nv_printk_(struct nouveau_object *object, int level, const char *fmt, ...) vprintk(mfmt, args); va_end(args); } + +#define CONV_LEVEL(x) case NV_DBG_##x: return NV_PRINTK_##x + +const char *nv_printk_level_to_pfx(int level) +{ + switch (level) { + CONV_LEVEL(FATAL); + CONV_LEVEL(ERROR); + CONV_LEVEL(WARN); + CONV_LEVEL(INFO); + CONV_LEVEL(DEBUG); + CONV_LEVEL(PARANOIA); + CONV_LEVEL(TRACE); + CONV_LEVEL(SPAM); + } + return NV_PRINTK_DEBUG; +} diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c index 9135b25a..4c72571 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 "priv.h" +#include <engine/device.h> static DEFINE_MUTEX(nv_devices_mutex); static LIST_HEAD(nv_devices); @@ -75,9 +75,7 @@ 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, @@ -89,7 +87,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_VIC] = NV_DEVICE_DISABLE_VIC, + [NVDEV_ENGINE_UNK1C1] = NV_DEVICE_DISABLE_UNK1C1, [NVDEV_ENGINE_VENC] = NV_DEVICE_DISABLE_VENC, [NVDEV_ENGINE_DISP] = NV_DEVICE_DISABLE_DISP, [NVDEV_SUBDEV_NR] = 0, @@ -121,12 +119,10 @@ nouveau_devobj_ctor(struct nouveau_object *parent, return -ENODEV; } - ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, - nouveau_control_oclass, + ret = nouveau_parent_create(parent, nv_object(device), oclass, 0, NULL, (1ULL << NVDEV_ENGINE_DMAOBJ) | (1ULL << NVDEV_ENGINE_FIFO) | - (1ULL << NVDEV_ENGINE_DISP) | - (1ULL << NVDEV_ENGINE_PERFMON), &devobj); + (1ULL << NVDEV_ENGINE_DISP), &devobj); *pobject = nv_object(devobj); if (ret) return ret; @@ -162,29 +158,22 @@ nouveau_devobj_ctor(struct nouveau_object *parent, iounmap(map); /* determine chipset and derive architecture from it */ - 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; + 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; default: break; } @@ -199,8 +188,7 @@ nouveau_devobj_ctor(struct nouveau_object *parent, switch (device->card_type) { case NV_04: ret = nv04_identify(device); break; - case NV_10: - case NV_11: ret = nv10_identify(device); break; + case NV_10: 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; @@ -224,7 +212,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->card_type <= NV_10 || device->chipset < 0x17 || + if ( 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 deleted file mode 100644 index 4b69bf5..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/device/ctrl.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * 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 dbd2dde..a0284cf 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 6e03dd6..1b7809a 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 dcde53b..12a4005 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 7b8662e..cef0f1e 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 c8c41e9..1719cb0 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv40.c @@ -35,7 +35,6 @@ #include <subdev/fb.h> #include <subdev/instmem.h> #include <subdev/vm.h> -#include <subdev/volt.h> #include <engine/device.h> #include <engine/dmaobj.h> @@ -44,7 +43,6 @@ #include <engine/graph.h> #include <engine/mpeg.h> #include <engine/disp.h> -#include <engine/perfmon.h> int nv40_identify(struct nouveau_device *device) @@ -58,20 +56,18 @@ 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 ] = nv40_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 ] = 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"; @@ -81,20 +77,18 @@ 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 ] = nv40_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 ] = 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"; @@ -104,20 +98,18 @@ 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 ] = nv40_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 ] = 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"; @@ -127,20 +119,18 @@ 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 ] = nv40_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 ] = 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"; @@ -150,20 +140,18 @@ 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 ] = nv40_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 ] = 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 ] = &nv44_mpeg_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 0x47: device->cname = "G70"; @@ -173,20 +161,18 @@ 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 ] = nv40_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 ] = 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 ] = &nv44_mpeg_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 0x49: device->cname = "G71"; @@ -196,20 +182,18 @@ 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 ] = nv40_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 ] = 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 ] = &nv44_mpeg_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 0x4b: device->cname = "G73"; @@ -219,20 +203,18 @@ 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 ] = nv40_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 ] = 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 ] = &nv44_mpeg_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 0x44: device->cname = "NV44"; @@ -242,20 +224,18 @@ 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 ] = &nv44_mpeg_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 0x46: device->cname = "G72"; @@ -265,20 +245,18 @@ 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 ] = &nv44_mpeg_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 0x4a: device->cname = "NV44A"; @@ -288,20 +266,18 @@ 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 ] = &nv44_mpeg_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 0x4c: device->cname = "C61"; @@ -311,20 +287,18 @@ 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 ] = &nv44_mpeg_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 0x4e: device->cname = "C51"; @@ -334,20 +308,18 @@ 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 ] = &nv44_mpeg_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 0x63: device->cname = "C73"; @@ -357,20 +329,18 @@ 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 ] = &nv44_mpeg_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 0x67: device->cname = "C67"; @@ -380,20 +350,18 @@ 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 ] = &nv44_mpeg_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 0x68: device->cname = "C68"; @@ -403,20 +371,18 @@ 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 ] = &nv44_mpeg_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; 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 db3fc7b..ffc18b8 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nv50.c @@ -36,8 +36,6 @@ #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> @@ -51,7 +49,6 @@ #include <engine/ppp.h> #include <engine/copy.h> #include <engine/disp.h> -#include <engine/perfmon.h> int nv50_identify(struct nouveau_device *device) @@ -62,277 +59,257 @@ 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 ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv84_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 ] = 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 ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv84_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 ] = 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 ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv84_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 ] = 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 ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv94_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = nv94_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 ] = nv84_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 ] = 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 ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv94_mc_oclass; - device->oclass[NVDEV_SUBDEV_BUS ] = nv94_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 ] = nv84_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 ] = 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 ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv94_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = nv84_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 ] = 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 ] = nv84_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv94_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = nv84_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 ] = 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 ] = nvaa_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv94_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = nvaa_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 ] = 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 ] = nvaa_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nv50_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 ] = nv94_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = nvaa_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 ] = 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"; @@ -343,18 +320,16 @@ 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 ] = nv94_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = nva3_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_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; @@ -362,7 +337,6 @@ 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"; @@ -373,25 +347,22 @@ 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 ] = nv94_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = nva3_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_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"; @@ -402,25 +373,22 @@ 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 ] = nv94_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = nva3_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_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"; @@ -431,25 +399,22 @@ 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 ] = nv94_bus_oclass; + device->oclass[NVDEV_SUBDEV_MC ] = &nv98_mc_oclass; + device->oclass[NVDEV_SUBDEV_BUS ] = &nv50_bus_oclass; device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; - device->oclass[NVDEV_SUBDEV_FB ] = nvaf_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_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 8d06eef..418f51f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nvc0.c @@ -38,8 +38,6 @@ #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> @@ -51,7 +49,6 @@ #include <engine/ppp.h> #include <engine/copy.h> #include <engine/disp.h> -#include <engine/perfmon.h> int nvc0_identify(struct nouveau_device *device) @@ -66,20 +63,18 @@ 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; @@ -87,7 +82,6 @@ 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"; @@ -98,20 +92,18 @@ 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; @@ -119,7 +111,6 @@ 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"; @@ -130,27 +121,24 @@ 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 ] = nvc3_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; 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"; @@ -161,20 +149,18 @@ 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 ] = nvc3_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; @@ -182,7 +168,6 @@ 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"; @@ -193,20 +178,18 @@ 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 ] = nvc3_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; @@ -214,7 +197,6 @@ 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"; @@ -225,27 +207,24 @@ 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 ] = nvc3_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 ] = 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"; @@ -256,20 +235,18 @@ 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; @@ -277,7 +254,6 @@ 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"; @@ -288,27 +264,24 @@ 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 ] = nvc3_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 ] = &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"; @@ -319,25 +292,24 @@ 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 ] = nvc3_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_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 3900104..7aca187 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c @@ -38,8 +38,6 @@ #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> @@ -51,7 +49,6 @@ #include <engine/bsp.h> #include <engine/vp.h> #include <engine/ppp.h> -#include <engine/perfmon.h> int nve0_identify(struct nouveau_device *device) @@ -62,24 +59,22 @@ 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 ] = &nve0_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_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_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 ] = nve0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_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; @@ -88,31 +83,28 @@ 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 ] = &nve0_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_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_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 ] = nve0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_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; @@ -121,31 +113,28 @@ 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 ] = &nve0_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_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_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 ] = nve0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_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; @@ -154,31 +143,28 @@ 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 ] = &nve0_clock_oclass; + device->oclass[NVDEV_SUBDEV_CLOCK ] = &nvc0_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_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 ] = nve0_fb_oclass; + device->oclass[NVDEV_SUBDEV_FB ] = &nvc0_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; @@ -189,43 +175,6 @@ 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 deleted file mode 100644 index 035fd5b..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/device/priv.h +++ /dev/null @@ -1,8 +0,0 @@ -#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 1bd4c63..054d9cf 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c @@ -70,10 +70,17 @@ 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) { @@ -89,22 +96,10 @@ dp_set_link_config(struct dp_state *dp) nvbios_exec(&init); } - 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); + 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); } static void @@ -299,17 +294,8 @@ 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 */ @@ -322,7 +308,7 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, while (*link_bw > (dp->dpcd[1] * 27000)) link_bw++; - while ((ret = -EIO) && link_bw[0]) { + while (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) @@ -342,10 +328,8 @@ nouveau_dp_train(struct nouveau_disp *disp, const struct nouveau_dp_func *func, !dp_link_train_eq(dp)) break; } else - if (ret) { - /* dp_set_link_config() handled training, or - * we failed to communicate with the sink. - */ + if (ret >= 1) { + /* dp_set_link_config() handled training */ break; } @@ -355,10 +339,8 @@ 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 (ret < 0) ? false : true; + return true; } diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c index a0bc8a8..05e903f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv04.c @@ -59,7 +59,6 @@ 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); @@ -70,14 +69,6 @@ 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 378a015..52dd7a1 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c @@ -541,15 +541,6 @@ 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 eea3ef5..7ec4ee83 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c @@ -97,9 +97,8 @@ 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, data[3]; + u32 addr, shift = nv94_sor_dp_lane_map(priv, lane); u8 ver, hdr, cnt, len; struct nvbios_dpout info; struct nvbios_dpcfg ocfg; @@ -114,12 +113,9 @@ nv94_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, if (!addr) return -EINVAL; - 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, 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); 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 d2df572..9e1d435 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c @@ -93,9 +93,8 @@ 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, data[3]; + u32 addr, shift = nvd0_sor_dp_lane_map(priv, lane); u8 ver, hdr, cnt, len; struct nvbios_dpout info; struct nvbios_dpcfg ocfg; @@ -110,12 +109,9 @@ nvd0_sor_dp_drv_ctl(struct nouveau_disp *disp, struct dcb_output *outp, if (!addr) return -EINVAL; - 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, 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); 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 54f26cc..f877bd5 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) { +struct nouveau_oclass +nv04_fifo_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 571a22a..2c927c1 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) { +struct nouveau_oclass +nv10_fifo_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 f257602..a9cb51d 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) { +struct nouveau_oclass +nv17_fifo_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 343487e..5c7433d 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) { +struct nouveau_oclass +nv40_fifo_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 e6352bd..7e5dff5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv50.c @@ -33,7 +33,6 @@ #include <engine/dmaobj.h> #include <engine/fifo.h> -#include "nv04.h" #include "nv50.h" /******************************************************************************* @@ -461,8 +460,6 @@ nv50_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_subdev(priv)->intr = nv04_fifo_intr; nv_engine(priv)->cclass = &nv50_fifo_cclass; nv_engine(priv)->sclass = nv50_fifo_sclass; - priv->base.pause = nv04_fifo_pause; - priv->base.start = nv04_fifo_start; return 0; } @@ -505,8 +502,8 @@ nv50_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nv50_fifo_oclass = &(struct nouveau_oclass) { +struct nouveau_oclass +nv50_fifo_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 fe0f41e..91a87cd 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nv84.c @@ -35,7 +35,6 @@ #include <engine/dmaobj.h> #include <engine/fifo.h> -#include "nv04.h" #include "nv50.h" /******************************************************************************* @@ -145,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_VIC : context |= 0x00500000; break; + case NVDEV_ENGINE_UNK1C1: context |= 0x00500000; break; case NVDEV_ENGINE_BSP : context |= 0x00600000; break; default: return -EINVAL; @@ -181,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_VIC), &chan); + (1ULL << NVDEV_ENGINE_UNK1C1), &chan); *pobject = nv_object(chan); if (ret) return ret; @@ -244,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_VIC), &chan); + (1ULL << NVDEV_ENGINE_UNK1C1), &chan); *pobject = nv_object(chan); if (ret) return ret; @@ -433,13 +432,11 @@ nv84_fifo_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_subdev(priv)->intr = nv04_fifo_intr; nv_engine(priv)->cclass = &nv84_fifo_cclass; nv_engine(priv)->sclass = nv84_fifo_sclass; - priv->base.pause = nv04_fifo_pause; - priv->base.start = nv04_fifo_start; return 0; } -struct nouveau_oclass * -nv84_fifo_oclass = &(struct nouveau_oclass) { +struct nouveau_oclass +nv84_fifo_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 9ac94d4..ce92f28 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nvc0.c @@ -494,6 +494,13 @@ 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; @@ -713,8 +720,8 @@ nvc0_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nvc0_fifo_oclass = &(struct nouveau_oclass) { +struct nouveau_oclass +nvc0_fifo_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 04f4129..8e8121a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c @@ -481,6 +481,13 @@ 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; @@ -668,8 +675,8 @@ nve0_fifo_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nve0_fifo_oclass = &(struct nouveau_oclass) { +struct nouveau_oclass +nve0_fifo_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 fe67415..64dca26 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 |= 1ULL << ((gpc * 8) + tpc); + tpc_set |= 1 << ((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 71b4283..e5be3ee 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvc1.c @@ -587,7 +587,6 @@ nvc1_grctx_init_unk58xx[] = { { 0x405870, 4, 0x04, 0x00000001 }, { 0x405a00, 2, 0x04, 0x00000000 }, { 0x405a18, 1, 0x04, 0x00000000 }, - {} }; static struct nvc0_graph_init @@ -599,7 +598,6 @@ nvc1_grctx_init_rop[] = { { 0x408904, 1, 0x04, 0x62000001 }, { 0x408908, 1, 0x04, 0x00c80929 }, { 0x408980, 1, 0x04, 0x0000011d }, - {} }; static struct nvc0_graph_init @@ -673,7 +671,6 @@ nvc1_grctx_init_gpc_0[] = { { 0x419000, 1, 0x04, 0x00000780 }, { 0x419004, 2, 0x04, 0x00000000 }, { 0x419014, 1, 0x04, 0x00000004 }, - {} }; static struct nvc0_graph_init @@ -720,7 +717,6 @@ 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 c4740d5..438e784 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd7.c @@ -258,7 +258,6 @@ 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 a1102cb..818a475 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/ctxnvd9.c @@ -466,7 +466,6 @@ 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 4532f7e..23c143a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c +++ b/drivers/gpu/drm/nouveau/core/engine/graph/nv10.c @@ -945,8 +945,7 @@ 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)->card_type >= NV_11 && - nv_device(priv)->chipset >= 0x17) { + if (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]); } @@ -971,8 +970,7 @@ 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)->card_type >= NV_11 && - nv_device(priv)->chipset >= 0x17) { + if (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]); } @@ -1054,8 +1052,7 @@ 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)->card_type >= NV_11 && - nv_device(priv)->chipset >= 0x17) { + if (nv_device(priv)->chipset >= 0x17) { /* is it really needed ??? */ NV17_WRITE_CTX(NV10_PGRAPH_DEBUG_4, nv_rd32(priv, NV10_PGRAPH_DEBUG_4)); @@ -1234,7 +1231,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)->card_type < NV_11) + nv_device(priv)->chipset == 0x1a) nv_engine(priv)->sclass = nv15_graph_sclass; else nv_engine(priv)->sclass = nv17_graph_sclass; @@ -1273,8 +1270,7 @@ 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)->card_type >= NV_11 && - nv_device(priv)->chipset >= 0x17) { + if (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 434bb4b..3f4f35c 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 = 0x08001000; + nv_subdev(priv)->unit = 0x18001000; 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 7eb6d94c..c190043 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.c @@ -34,7 +34,16 @@ #include <engine/fifo.h> #include <engine/mpeg.h> -#include <engine/mpeg/nv31.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; +}; /******************************************************************************* * MPEG object classes @@ -80,18 +89,18 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len) if (mthd == 0x0190) { /* DMA_CMD */ - nv_mask(priv, 0x00b300, 0x00010000, (dma0 & 0x00030000) ? 0x00010000 : 0); + 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, 0x00020000, (dma0 & 0x00030000) ? 0x00020000 : 0); + 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) + if (dma0 & 0x000c0000) return -EINVAL; nv_wr32(priv, 0x00b370, base); @@ -101,7 +110,7 @@ nv31_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len) return 0; } -struct nouveau_ofuncs +static struct nouveau_ofuncs nv31_mpeg_ofuncs = { .ctor = nv31_mpeg_object_ctor, .dtor = _nouveau_gpuobj_dtor, @@ -137,23 +146,16 @@ 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; } @@ -162,15 +164,11 @@ nv31_mpeg_context_dtor(struct nouveau_object *object) { struct nv31_mpeg_priv *priv = (void *)object->engine; struct nv31_mpeg_chan *chan = (void *)object; - unsigned long flags; - - spin_lock_irqsave(&nv_engine(priv)->lock, flags); - priv->chan = NULL; - spin_unlock_irqrestore(&nv_engine(priv)->lock, flags); + atomic_dec(&priv->refcount); nouveau_object_destroy(&chan->base); } -struct nouveau_oclass +static struct nouveau_oclass nv31_mpeg_cclass = { .handle = NV_ENGCTX(MPEG, 0x31), .ofuncs = &(struct nouveau_ofuncs) { @@ -199,19 +197,21 @@ 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_handle *handle; + 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; 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; - unsigned long flags; + int chid; - spin_lock_irqsave(&nv_engine(priv)->lock, flags); - engctx = nv_object(priv->chan); + engctx = nouveau_engctx_get(engine, inst); + chid = pfifo->chid(pfifo, engctx); 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 && engctx) { + if (type == 0x00000010) { handle = nouveau_handle_get_class(engctx, 0x3174); if (handle && !nv_call(handle->object, mthd, data)) show &= ~0x01000000; @@ -232,12 +232,13 @@ nv31_mpeg_intr(struct nouveau_subdev *subdev) nv_wr32(priv, 0x00b230, 0x00000001); if (show) { - 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); + 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); } - spin_unlock_irqrestore(&nv_engine(priv)->lock, flags); + nouveau_engctx_put(engctx); } static int @@ -283,7 +284,10 @@ nv31_mpeg_init(struct nouveau_object *object) /* PMPEG init */ nv_wr32(priv, 0x00b32c, 0x00000000); nv_wr32(priv, 0x00b314, 0x00000100); - nv_wr32(priv, 0x00b220, 0x00000031); + if (nv_device(priv)->chipset >= 0x40 && nv44_graph_class(priv)) + nv_wr32(priv, 0x00b220, 0x00000044); + else + 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 deleted file mode 100644 index d08629d..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv31.h +++ /dev/null @@ -1,15 +0,0 @@ -#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 d4e7ec0..dd61960 100644 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c +++ b/drivers/gpu/drm/nouveau/core/engine/mpeg/nv40.c @@ -31,63 +31,66 @@ #include <subdev/instmem.h> #include <engine/mpeg.h> -#include <engine/mpeg/nv31.h> +#include <engine/graph/nv40.h> + +struct nv40_mpeg_priv { + struct nouveau_mpeg base; +}; + +struct nv40_mpeg_chan { + struct nouveau_mpeg_chan base; +}; /******************************************************************************* - * MPEG object classes + * PMPEG context ******************************************************************************/ static int -nv40_mpeg_mthd_dma(struct nouveau_object *object, u32 mthd, void *arg, u32 len) +nv40_mpeg_context_ctor(struct nouveau_object *parent, + struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { - 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); - } + 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; + + nv_wo32(&chan->base.base, 0x78, 0x02001ec1); 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 int +nv40_mpeg_context_fini(struct nouveau_object *object, bool suspend) +{ -struct nouveau_oclass -nv40_mpeg_sclass[] = { - { 0x3174, &nv31_mpeg_ofuncs, nv40_mpeg_omthds }, - {} + 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_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, + }, }; /******************************************************************************* @@ -97,7 +100,7 @@ nv40_mpeg_sclass[] = { static void nv40_mpeg_intr(struct nouveau_subdev *subdev) { - struct nv31_mpeg_priv *priv = (void *)subdev; + struct nv40_mpeg_priv *priv = (void *)subdev; u32 stat; if ((stat = nv_rd32(priv, 0x00b100))) @@ -114,7 +117,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 nv31_mpeg_priv *priv; + struct nv40_mpeg_priv *priv; int ret; ret = nouveau_mpeg_create(parent, engine, oclass, &priv); @@ -124,8 +127,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 = &nv31_mpeg_cclass; - nv_engine(priv)->sclass = nv40_mpeg_sclass; + nv_engine(priv)->cclass = &nv40_mpeg_cclass; + nv_engine(priv)->sclass = nv31_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 deleted file mode 100644 index 3d8c213..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/mpeg/nv44.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * 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 deleted file mode 100644 index e9c5e51..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/base.c +++ /dev/null @@ -1,449 +0,0 @@ -/* - * 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 deleted file mode 100644 index 50696cc..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/daemon.c +++ /dev/null @@ -1,109 +0,0 @@ -/* - * 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 deleted file mode 100644 index b2a1078..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * 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 deleted file mode 100644 index 1b5792d..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv40.h +++ /dev/null @@ -1,26 +0,0 @@ -#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 deleted file mode 100644 index 9421769..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv50.c +++ /dev/null @@ -1,70 +0,0 @@ -/* - * 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 deleted file mode 100644 index 9232c7f..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nv84.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * 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 deleted file mode 100644 index 6197ebd..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nva3.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 deleted file mode 100644 index 74b2410..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.c +++ /dev/null @@ -1,173 +0,0 @@ -/* - * 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 deleted file mode 100644 index f66bca4..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvc0.h +++ /dev/null @@ -1,17 +0,0 @@ -#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 deleted file mode 100644 index 71d718c..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nve0.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 deleted file mode 100644 index 47256f7..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/nvf0.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 deleted file mode 100644 index 0ac8714..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/perfmon/priv.h +++ /dev/null @@ -1,91 +0,0 @@ -#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 c571758..2a859a3 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) { +struct nouveau_oclass +nv04_software_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 a62f11a..a019364 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) { +struct nouveau_oclass +nv10_software_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 5ce686e..c48e749 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nv50.c @@ -32,9 +32,16 @@ #include <subdev/bar.h> +#include <engine/software.h> #include <engine/disp.h> -#include "nv50.h" +struct nv50_software_priv { + struct nouveau_software base; +}; + +struct nv50_software_chan { + struct nouveau_software_chan base; +}; /******************************************************************************* * software object classes @@ -55,7 +62,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->vblank.ctxdma = gpuobj->node->offset >> 4; + chan->base.vblank.ctxdma = gpuobj->node->offset >> 4; ret = 0; } nouveau_namedb_put(handle); @@ -67,33 +74,34 @@ 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->vblank.offset = *(u32 *)args; + chan->base.vblank.offset = *(u32 *)args; return 0; } -int +static 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->vblank.value = *(u32 *)args; + chan->base.vblank.value = *(u32 *)args; return 0; } -int +static 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); - u32 head = *(u32 *)args; - if (head >= chan->vblank.nr_event) + struct nouveau_disp *disp = nouveau_disp(object); + u32 crtc = *(u32 *)args; + if (crtc > 1) return -EINVAL; - nouveau_event_get(chan->vblank.event[head]); + nouveau_event_get(disp->vblank, crtc, &chan->base.vblank.event); return 0; } -int +static int nv50_software_mthd_flip(struct nouveau_object *object, u32 mthd, void *args, u32 size) { @@ -124,9 +132,10 @@ nv50_software_sclass[] = { ******************************************************************************/ static int -nv50_software_vblsem_release(void *data, int head) +nv50_software_vblsem_release(struct nouveau_eventh *event, int head) { - struct nv50_software_chan *chan = data; + struct nouveau_software_chan *chan = + container_of(event, struct nouveau_software_chan, vblank.event); struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; struct nouveau_bar *bar = nouveau_bar(priv); @@ -145,76 +154,45 @@ nv50_software_vblsem_release(void *data, int head) return NVKM_EVENT_DROP; } -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 +static 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, i; + int ret; ret = nouveau_software_context_create(parent, engine, oclass, &chan); *pobject = nv_object(chan); if (ret) return ret; - chan->vblank.nr_event = pdisp ? pdisp->vblank->index_nr : 0; - 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; + chan->base.vblank.channel = nv_gpuobj(parent->parent)->addr >> 12; + chan->base.vblank.event.func = nv50_software_vblsem_release; return 0; } -static struct nv50_software_cclass +static struct nouveau_oclass nv50_software_cclass = { - .base.handle = NV_ENGCTX(SW, 0x50), - .base.ofuncs = &(struct nouveau_ofuncs) { + .handle = NV_ENGCTX(SW, 0x50), + .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 ******************************************************************************/ -int +static 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; @@ -223,21 +201,19 @@ nv50_software_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_engine(priv)->cclass = pclass->cclass; - nv_engine(priv)->sclass = pclass->sclass; + nv_engine(priv)->cclass = &nv50_software_cclass; + nv_engine(priv)->sclass = nv50_software_sclass; nv_subdev(priv)->intr = nv04_software_intr; return 0; } -struct nouveau_oclass * -nv50_software_oclass = &(struct nv50_software_oclass) { - .base.handle = NV_ENGINE(SW, 0x50), - .base.ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass +nv50_software_oclass = { + .handle = NV_ENGINE(SW, 0x50), + .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 deleted file mode 100644 index 2de370c..0000000 --- a/drivers/gpu/drm/nouveau/core/engine/software/nv50.h +++ /dev/null @@ -1,47 +0,0 @@ -#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 f9430c1..d698e71 100644 --- a/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/engine/software/nvc0.c @@ -32,7 +32,13 @@ #include <engine/software.h> #include <engine/disp.h> -#include "nv50.h" +struct nvc0_software_priv { + struct nouveau_software base; +}; + +struct nvc0_software_chan { + struct nouveau_software_chan base; +}; /******************************************************************************* * software object classes @@ -42,24 +48,58 @@ static int nvc0_software_mthd_vblsem_offset(struct nouveau_object *object, u32 mthd, void *args, u32 size) { - struct nv50_software_chan *chan = (void *)nv_engctx(object->parent); + struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); u64 data = *(u32 *)args; if (mthd == 0x0400) { - chan->vblank.offset &= 0x00ffffffffULL; - chan->vblank.offset |= data << 32; + chan->base.vblank.offset &= 0x00ffffffffULL; + chan->base.vblank.offset |= data << 32; } else { - chan->vblank.offset &= 0xff00000000ULL; - chan->vblank.offset |= data; + chan->base.vblank.offset &= 0xff00000000ULL; + chan->base.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 nv50_software_chan *chan = (void *)nv_engctx(object->parent); - struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; + struct nvc0_software_chan *chan = (void *)nv_engctx(object->parent); + struct nvc0_software_priv *priv = (void *)nv_object(chan)->engine; u32 data = *(u32 *)args; switch (mthd) { @@ -84,9 +124,9 @@ static struct nouveau_omthds nvc0_software_omthds[] = { { 0x0400, 0x0400, nvc0_software_mthd_vblsem_offset }, { 0x0404, 0x0404, nvc0_software_mthd_vblsem_offset }, - { 0x0408, 0x0408, nv50_software_mthd_vblsem_value }, - { 0x040c, 0x040c, nv50_software_mthd_vblsem_release }, - { 0x0500, 0x0500, nv50_software_mthd_flip }, + { 0x0408, 0x0408, nvc0_software_mthd_vblsem_value }, + { 0x040c, 0x040c, nvc0_software_mthd_vblsem_release }, + { 0x0500, 0x0500, nvc0_software_mthd_flip }, { 0x0600, 0x0600, nvc0_software_mthd_mp_control }, { 0x0644, 0x0644, nvc0_software_mthd_mp_control }, { 0x06ac, 0x06ac, nvc0_software_mthd_mp_control }, @@ -104,10 +144,11 @@ nvc0_software_sclass[] = { ******************************************************************************/ static int -nvc0_software_vblsem_release(void *data, int head) +nvc0_software_vblsem_release(struct nouveau_eventh *event, int head) { - struct nv50_software_chan *chan = data; - struct nv50_software_priv *priv = (void *)nv_object(chan)->engine; + 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 nouveau_bar *bar = nouveau_bar(priv); nv_wr32(priv, 0x001718, 0x80000000 | chan->vblank.channel); @@ -119,31 +160,66 @@ nvc0_software_vblsem_release(void *data, int head) return NVKM_EVENT_DROP; } -static struct nv50_software_cclass +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 nvc0_software_cclass = { - .base.handle = NV_ENGCTX(SW, 0xc0), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_software_context_ctor, + .handle = NV_ENGCTX(SW, 0xc0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_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 ******************************************************************************/ -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, +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, .dtor = _nouveau_software_dtor, .init = _nouveau_software_init, .fini = _nouveau_software_fini, }, - .cclass = &nvc0_software_cclass.base, - .sclass = nvc0_software_sclass, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index 560c359..5a5961b 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h @@ -22,7 +22,7 @@ #define NV_DEVICE_DISABLE_PPP 0x0000004000000000ULL #define NV_DEVICE_DISABLE_COPY0 0x0000008000000000ULL #define NV_DEVICE_DISABLE_COPY1 0x0000010000000000ULL -#define NV_DEVICE_DISABLE_VIC 0x0000020000000000ULL +#define NV_DEVICE_DISABLE_UNK1C1 0x0000020000000000ULL #define NV_DEVICE_DISABLE_VENC 0x0000040000000000ULL struct nv_device_class { @@ -98,77 +98,6 @@ struct nv_dma_class { u32 conf0; }; -/* Perfmon counter class - * - * XXXX: NV_PERFCTR - */ -#define NV_PERFCTR_CLASS 0x0000ffff -#define NV_PERFCTR_QUERY 0x00000000 -#define NV_PERFCTR_SAMPLE 0x00000001 -#define NV_PERFCTR_READ 0x00000002 - -struct nv_perfctr_class { - u16 logic_op; - struct { - char __user *name; /*XXX: use cfu when exposed to userspace */ - u32 size; - } signal[4]; -}; - -struct nv_perfctr_query { - u32 iter; - u32 size; - char __user *name; /*XXX: use ctu when exposed to userspace */ -}; - -struct nv_perfctr_sample { -}; - -struct nv_perfctr_read { - u32 ctr; - u32 clk; -}; - -/* Device control class - * - * XXXX: NV_CONTROL - */ -#define NV_CONTROL_CLASS 0x0000fffe - -#define NV_CONTROL_PSTATE_INFO 0x00000000 -#define NV_CONTROL_PSTATE_INFO_USTATE_DISABLE (-1) -#define NV_CONTROL_PSTATE_INFO_USTATE_PERFMON (-2) -#define NV_CONTROL_PSTATE_INFO_PSTATE_UNKNOWN (-1) -#define NV_CONTROL_PSTATE_INFO_PSTATE_PERFMON (-2) -#define NV_CONTROL_PSTATE_ATTR 0x00000001 -#define NV_CONTROL_PSTATE_ATTR_STATE_CURRENT (-1) -#define NV_CONTROL_PSTATE_USER 0x00000002 -#define NV_CONTROL_PSTATE_USER_STATE_UNKNOWN (-1) -#define NV_CONTROL_PSTATE_USER_STATE_PERFMON (-2) - -struct nv_control_pstate_info { - u32 count; /* out: number of power states */ - s32 ustate; /* out: current target pstate index */ - u32 pstate; /* out: current pstate index */ -}; - -struct nv_control_pstate_attr { - s32 state; /* in: index of pstate to query - * out: pstate identifier - */ - u32 index; /* in: index of attribute to query - * out: index of next attribute, or 0 if no more - */ - char name[32]; - char unit[16]; - u32 min; - u32 max; -}; - -struct nv_control_pstate_user { - s32 state; /* in: pstate identifier */ -}; - /* DMA FIFO channel classes * * 006b: NV03_CHANNEL_DMA diff --git a/drivers/gpu/drm/nouveau/core/include/core/debug.h b/drivers/gpu/drm/nouveau/core/include/core/debug.h index 8092e2e..9ea18df 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/debug.h +++ b/drivers/gpu/drm/nouveau/core/include/core/debug.h @@ -1,20 +1,13 @@ #ifndef __NOUVEAU_DEBUG_H__ #define __NOUVEAU_DEBUG_H__ -extern int nv_info_debug_level; - #define NV_DBG_FATAL 0 #define NV_DBG_ERROR 1 #define NV_DBG_WARN 2 -#define NV_DBG_INFO nv_info_debug_level +#define NV_DBG_INFO 3 #define NV_DBG_DEBUG 4 #define NV_DBG_TRACE 5 #define NV_DBG_PARANOIA 6 #define NV_DBG_SPAM 7 -#define NV_DBG_INFO_NORMAL 3 -#define NV_DBG_INFO_SILENT NV_DBG_DEBUG - -#define nv_debug_level(a) nv_info_debug_level = NV_DBG_INFO_##a - #endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h index ac2881d..99b6600 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/device.h +++ b/drivers/gpu/drm/nouveau/core/include/core/device.h @@ -33,10 +33,9 @@ enum nv_subdev_type { NVDEV_SUBDEV_INSTMEM, NVDEV_SUBDEV_VM, NVDEV_SUBDEV_BAR, - NVDEV_SUBDEV_PWR, NVDEV_SUBDEV_VOLT, - NVDEV_SUBDEV_THERM, NVDEV_SUBDEV_CLOCK, + NVDEV_SUBDEV_THERM, NVDEV_ENGINE_DMAOBJ, NVDEV_ENGINE_FIFO, @@ -51,10 +50,9 @@ enum nv_subdev_type { NVDEV_ENGINE_COPY0, NVDEV_ENGINE_COPY1, NVDEV_ENGINE_COPY2, - NVDEV_ENGINE_VIC, + NVDEV_ENGINE_UNK1C1, NVDEV_ENGINE_VENC, NVDEV_ENGINE_DISP, - NVDEV_ENGINE_PERFMON, NVDEV_SUBDEV_NR, }; @@ -74,7 +72,6 @@ struct nouveau_device { enum { NV_04 = 0x04, NV_10 = 0x10, - NV_11 = 0x11, NV_20 = 0x20, NV_30 = 0x30, NV_40 = 0x40, diff --git a/drivers/gpu/drm/nouveau/core/include/core/event.h b/drivers/gpu/drm/nouveau/core/include/core/event.h index 5d539eb..9e09440 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/event.h +++ b/drivers/gpu/drm/nouveau/core/include/core/event.h @@ -5,21 +5,13 @@ #define NVKM_EVENT_DROP 0 #define NVKM_EVENT_KEEP 1 -/* nouveau_eventh.flags bit #s */ -#define NVKM_EVENT_ENABLE 0 - struct nouveau_eventh { - struct nouveau_event *event; struct list_head head; - unsigned long flags; - int index; - int (*func)(void *, int); - void *priv; + int (*func)(struct nouveau_eventh *, int index); }; struct nouveau_event { - spinlock_t list_lock; - spinlock_t refs_lock; + spinlock_t lock; void *priv; void (*enable)(struct nouveau_event *, int index); @@ -36,11 +28,9 @@ int nouveau_event_create(int index_nr, struct nouveau_event **); void nouveau_event_destroy(struct nouveau_event **); void nouveau_event_trigger(struct nouveau_event *, int index); -int nouveau_event_new(struct nouveau_event *, int index, - int (*func)(void *, int), void *, - struct nouveau_eventh **); -void nouveau_event_ref(struct nouveau_eventh *, struct nouveau_eventh **); -void nouveau_event_get(struct nouveau_eventh *); -void nouveau_event_put(struct nouveau_eventh *); +void nouveau_event_get(struct nouveau_event *, int index, + struct nouveau_eventh *); +void nouveau_event_put(struct nouveau_event *, int index, + struct nouveau_eventh *); #endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/option.h b/drivers/gpu/drm/nouveau/core/include/core/option.h index ed05584..2707495 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/option.h +++ b/drivers/gpu/drm/nouveau/core/include/core/option.h @@ -8,13 +8,4 @@ bool nouveau_boolopt(const char *optstr, const char *opt, bool value); int nouveau_dbgopt(const char *optstr, const char *sub); -/* compares unterminated string 'str' with zero-terminated string 'cmp' */ -static inline int -strncasecmpz(const char *str, const char *cmp, size_t len) -{ - if (strlen(cmp) != len) - return len; - return strncasecmp(str, cmp, len); -} - #endif diff --git a/drivers/gpu/drm/nouveau/core/include/core/printk.h b/drivers/gpu/drm/nouveau/core/include/core/printk.h index 0f9a37b..d87836e 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/printk.h +++ b/drivers/gpu/drm/nouveau/core/include/core/printk.h @@ -6,12 +6,27 @@ struct nouveau_object; -void __printf(3, 4) -nv_printk_(struct nouveau_object *, int, const char *, ...); +#define NV_PRINTK_FATAL KERN_CRIT +#define NV_PRINTK_ERROR KERN_ERR +#define NV_PRINTK_WARN KERN_WARNING +#define NV_PRINTK_INFO KERN_INFO +#define NV_PRINTK_DEBUG KERN_DEBUG +#define NV_PRINTK_PARANOIA KERN_DEBUG +#define NV_PRINTK_TRACE KERN_DEBUG +#define NV_PRINTK_SPAM KERN_DEBUG + +extern int nv_printk_suspend_level; + +#define NV_DBG_SUSPEND (nv_printk_suspend_level) +#define NV_PRINTK_SUSPEND (nv_printk_level_to_pfx(nv_printk_suspend_level)) + +const char *nv_printk_level_to_pfx(int level); +void __printf(4, 5) +nv_printk_(struct nouveau_object *, const char *, int, const char *, ...); #define nv_printk(o,l,f,a...) do { \ if (NV_DBG_##l <= CONFIG_NOUVEAU_DEBUG) \ - nv_printk_(nv_object(o), NV_DBG_##l, f, ##a); \ + nv_printk_(nv_object(o), NV_PRINTK_##l, NV_DBG_##l, f, ##a); \ } while(0) #define nv_fatal(o,f,a...) nv_printk((o), FATAL, f, ##a) @@ -22,9 +37,16 @@ nv_printk_(struct nouveau_object *, int, const char *, ...); #define nv_trace(o,f,a...) nv_printk((o), TRACE, f, ##a) #define nv_spam(o,f,a...) nv_printk((o), SPAM, f, ##a) +#define nv_suspend(o,f,a...) nv_printk((o), SUSPEND, f, ##a) + +static inline void nv_suspend_set_printk_level(int level) +{ + nv_printk_suspend_level = level; +} + #define nv_assert(f,a...) do { \ if (NV_DBG_FATAL <= CONFIG_NOUVEAU_DEBUG) \ - nv_printk_(NULL, NV_DBG_FATAL, f "\n", ##a); \ + nv_printk_(NULL, NV_PRINTK_FATAL, NV_DBG_FATAL, f "\n", ##a); \ BUG_ON(1); \ } while(0) diff --git a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h index 8c32cf4..633c2f8 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/fifo.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/fifo.h @@ -101,14 +101,14 @@ nouveau_client_name_for_fifo_chid(struct nouveau_fifo *fifo, u32 chid); #define _nouveau_fifo_init _nouveau_engine_init #define _nouveau_fifo_fini _nouveau_engine_fini -extern struct nouveau_oclass *nv04_fifo_oclass; -extern struct nouveau_oclass *nv10_fifo_oclass; -extern struct nouveau_oclass *nv17_fifo_oclass; -extern struct nouveau_oclass *nv40_fifo_oclass; -extern struct nouveau_oclass *nv50_fifo_oclass; -extern struct nouveau_oclass *nv84_fifo_oclass; -extern struct nouveau_oclass *nvc0_fifo_oclass; -extern struct nouveau_oclass *nve0_fifo_oclass; +extern struct nouveau_oclass nv04_fifo_oclass; +extern struct nouveau_oclass nv10_fifo_oclass; +extern struct nouveau_oclass nv17_fifo_oclass; +extern struct nouveau_oclass nv40_fifo_oclass; +extern struct nouveau_oclass nv50_fifo_oclass; +extern struct nouveau_oclass nv84_fifo_oclass; +extern struct nouveau_oclass nvc0_fifo_oclass; +extern struct nouveau_oclass nve0_fifo_oclass; void nv04_fifo_intr(struct nouveau_subdev *); int nv04_fifo_context_attach(struct nouveau_object *, struct nouveau_object *); diff --git a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h index 9b0d938..1d1a89a 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/mpeg.h @@ -42,13 +42,10 @@ struct nouveau_mpeg { extern struct nouveau_oclass nv31_mpeg_oclass; extern struct nouveau_oclass nv40_mpeg_oclass; -extern struct nouveau_oclass nv44_mpeg_oclass; extern struct nouveau_oclass nv50_mpeg_oclass; extern struct nouveau_oclass nv84_mpeg_oclass; -extern struct nouveau_ofuncs nv31_mpeg_ofuncs; -extern struct nouveau_oclass nv31_mpeg_cclass; + extern struct nouveau_oclass nv31_mpeg_sclass[]; -extern struct nouveau_oclass nv40_mpeg_sclass[]; void nv31_mpeg_intr(struct nouveau_subdev *); void nv31_mpeg_tile_prog(struct nouveau_engine *, int); int nv31_mpeg_init(struct nouveau_object *); diff --git a/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h b/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h deleted file mode 100644 index 49b0024..0000000 --- a/drivers/gpu/drm/nouveau/core/include/engine/perfmon.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef __NVKM_PERFMON_H__ -#define __NVKM_PERFMON_H__ - -#include <core/device.h> -#include <core/engine.h> -#include <core/engctx.h> -#include <core/class.h> - -struct nouveau_perfdom; -struct nouveau_perfctr; -struct nouveau_perfmon { - struct nouveau_engine base; - - struct nouveau_perfctx *context; - void *profile_data; - - struct list_head domains; - u32 sequence; - - /*XXX: temp for daemon backend */ - u32 pwr[8]; - u32 last; -}; - -static inline struct nouveau_perfmon * -nouveau_perfmon(void *obj) -{ - return (void *)nv_device(obj)->subdev[NVDEV_ENGINE_PERFMON]; -} - -extern struct nouveau_oclass *nv40_perfmon_oclass; -extern struct nouveau_oclass *nv50_perfmon_oclass; -extern struct nouveau_oclass *nv84_perfmon_oclass; -extern struct nouveau_oclass *nva3_perfmon_oclass; -extern struct nouveau_oclass nvc0_perfmon_oclass; -extern struct nouveau_oclass nve0_perfmon_oclass; -extern struct nouveau_oclass nvf0_perfmon_oclass; - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/engine/software.h b/drivers/gpu/drm/nouveau/core/include/engine/software.h index 23a462b..4579948 100644 --- a/drivers/gpu/drm/nouveau/core/include/engine/software.h +++ b/drivers/gpu/drm/nouveau/core/include/engine/software.h @@ -3,10 +3,19 @@ #include <core/engine.h> #include <core/engctx.h> +#include <core/event.h> struct nouveau_software_chan { struct nouveau_engctx base; + struct { + struct nouveau_eventh event; + u32 channel; + u32 ctxdma; + u64 offset; + u32 value; + } vblank; + int (*flip)(void *); void *flip_data; }; @@ -41,10 +50,10 @@ struct nouveau_software { #define _nouveau_software_init _nouveau_engine_init #define _nouveau_software_fini _nouveau_engine_fini -extern struct nouveau_oclass *nv04_software_oclass; -extern struct nouveau_oclass *nv10_software_oclass; -extern struct nouveau_oclass *nv50_software_oclass; -extern struct nouveau_oclass *nvc0_software_oclass; +extern struct nouveau_oclass nv04_software_oclass; +extern struct nouveau_oclass nv10_software_oclass; +extern struct nouveau_oclass nv50_software_oclass; +extern struct nouveau_oclass nvc0_software_oclass; void nv04_software_intr(struct nouveau_subdev *); diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h deleted file mode 100644 index 662b207..0000000 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/boost.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __NVBIOS_BOOST_H__ -#define __NVBIOS_BOOST_H__ - -u16 nvbios_boostTe(struct nouveau_bios *, u8 *, u8 *, u8 *, u8 *, u8 *, u8 *); - -struct nvbios_boostE { - u8 pstate; - u32 min; - u32 max; -}; - -u16 nvbios_boostEe(struct nouveau_bios *, int idx, u8 *, u8 *, u8 *, u8 *); -u16 nvbios_boostEp(struct nouveau_bios *, int idx, u8 *, u8 *, u8 *, u8 *, - struct nvbios_boostE *); -u16 nvbios_boostEm(struct nouveau_bios *, u8, u8 *, u8 *, u8 *, u8 *, - struct nvbios_boostE *); - -struct nvbios_boostS { - u8 domain; - u8 percent; - u32 min; - u32 max; -}; - -u16 nvbios_boostSe(struct nouveau_bios *, int, u16, u8 *, u8 *, u8, u8); -u16 nvbios_boostSp(struct nouveau_bios *, int, u16, u8 *, u8 *, u8, u8, - struct nvbios_boostS *); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h deleted file mode 100644 index a80a4380..0000000 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/cstep.h +++ /dev/null @@ -1,28 +0,0 @@ -#ifndef __NVBIOS_CSTEP_H__ -#define __NVBIOS_CSTEP_H__ - -u16 nvbios_cstepTe(struct nouveau_bios *, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz); - -struct nvbios_cstepE { - u8 pstate; - u8 index; -}; - -u16 nvbios_cstepEe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr); -u16 nvbios_cstepEp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr, - struct nvbios_cstepE *); -u16 nvbios_cstepEm(struct nouveau_bios *, u8 pstate, u8 *ver, u8 *hdr, - struct nvbios_cstepE *); - -struct nvbios_cstepX { - u32 freq; - u8 unkn[2]; - u8 voltage; -}; - -u16 nvbios_cstepXe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr); -u16 nvbios_cstepXp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr, - struct nvbios_cstepX *); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h index c7b2e58..96d3364 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/gpio.h @@ -7,15 +7,7 @@ enum dcb_gpio_func_name { DCB_GPIO_TVDAC1 = 0x2d, DCB_GPIO_FAN = 0x09, DCB_GPIO_FAN_SENSE = 0x3d, - DCB_GPIO_UNUSED = 0xff, - DCB_GPIO_VID0 = 0x04, - DCB_GPIO_VID1 = 0x05, - DCB_GPIO_VID2 = 0x06, - DCB_GPIO_VID3 = 0x1a, - DCB_GPIO_VID4 = 0x73, - DCB_GPIO_VID5 = 0x74, - DCB_GPIO_VID6 = 0x75, - DCB_GPIO_VID7 = 0x76, + DCB_GPIO_UNUSED = 0xff }; #define DCB_GPIO_LOG_DIR 0x02 diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h index 16ff06e..0b285e9 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/perf.h @@ -3,39 +3,6 @@ struct nouveau_bios; -u16 nvbios_perf_table(struct nouveau_bios *, u8 *ver, u8 *hdr, - u8 *cnt, u8 *len, u8 *snr, u8 *ssz); - -struct nvbios_perfE { - u8 pstate; - u8 fanspeed; - u8 voltage; - u32 core; - u32 shader; - u32 memory; - u32 vdec; - u32 disp; - u32 script; -}; - -u16 nvbios_perf_entry(struct nouveau_bios *, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len); -u16 nvbios_perfEp(struct nouveau_bios *, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_perfE *); - -struct nvbios_perfS { - union { - struct { - u32 freq; - } v40; - }; -}; - -u32 nvbios_perfSe(struct nouveau_bios *, u32 data, int idx, - u8 *ver, u8 *hdr, u8 cnt, u8 len); -u32 nvbios_perfSp(struct nouveau_bios *, u32 data, int idx, - u8 *ver, u8 *hdr, u8 cnt, u8 len, struct nvbios_perfS *); - struct nvbios_perf_fan { u32 pwm_divisor; }; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h deleted file mode 100644 index bc15e03..0000000 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/rammap.h +++ /dev/null @@ -1,11 +0,0 @@ -#ifndef __NVBIOS_RAMMAP_H__ -#define __NVBIOS_RAMMAP_H__ - -u16 nvbios_rammap_table(struct nouveau_bios *, u8 *ver, u8 *hdr, - u8 *cnt, u8 *len, u8 *snr, u8 *ssz); -u16 nvbios_rammap_entry(struct nouveau_bios *, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len); -u16 nvbios_rammap_match(struct nouveau_bios *, u16 khz, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h deleted file mode 100644 index 963694b..0000000 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/timing.h +++ /dev/null @@ -1,8 +0,0 @@ -#ifndef __NVBIOS_TIMING_H__ -#define __NVBIOS_TIMING_H__ - -u16 nvbios_timing_table(struct nouveau_bios *, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len); -u16 nvbios_timing_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h deleted file mode 100644 index ad5a8f2..0000000 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/vmap.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef __NVBIOS_VMAP_H__ -#define __NVBIOS_VMAP_H__ - -struct nouveau_bios; - -struct nvbios_vmap { -}; - -u16 nvbios_vmap_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); -u16 nvbios_vmap_parse(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, - struct nvbios_vmap *); - -struct nvbios_vmap_entry { - u8 unk0; - u8 link; - u32 min; - u32 max; - s32 arg[6]; -}; - -u16 nvbios_vmap_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *len); -u16 nvbios_vmap_entry_parse(struct nouveau_bios *, int idx, u8 *ver, u8 *len, - struct nvbios_vmap_entry *); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h deleted file mode 100644 index 6a11dcd..0000000 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/volt.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __NVBIOS_VOLT_H__ -#define __NVBIOS_VOLT_H__ - -struct nouveau_bios; - -struct nvbios_volt { - u8 vidmask; - u32 min; - u32 max; - u32 base; - s16 step; -}; - -u16 nvbios_volt_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); -u16 nvbios_volt_parse(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, - struct nvbios_volt *); - -struct nvbios_volt_entry { - u32 voltage; - u8 vid; -}; - -u16 nvbios_volt_entry(struct nouveau_bios *, int idx, u8 *ver, u8 *len); -u16 nvbios_volt_entry_parse(struct nouveau_bios *, int idx, u8 *ver, u8 *len, - struct nvbios_volt_entry *); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bus.h b/drivers/gpu/drm/nouveau/core/include/subdev/bus.h index 697f7ce..7d88ec4 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bus.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bus.h @@ -11,8 +11,6 @@ struct nouveau_bus_intr { struct nouveau_bus { struct nouveau_subdev base; - int (*hwsq_exec)(struct nouveau_bus *, u32 *, u32); - u32 hwsq_size; }; static inline struct nouveau_bus * @@ -35,19 +33,9 @@ nouveau_bus(void *obj) #define _nouveau_bus_init _nouveau_subdev_init #define _nouveau_bus_fini _nouveau_subdev_fini -extern struct nouveau_oclass *nv04_bus_oclass; -extern struct nouveau_oclass *nv31_bus_oclass; -extern struct nouveau_oclass *nv50_bus_oclass; -extern struct nouveau_oclass *nv94_bus_oclass; -extern struct nouveau_oclass *nvc0_bus_oclass; - -/* interface to sequencer */ -struct nouveau_hwsq; -int nouveau_hwsq_init(struct nouveau_bus *, struct nouveau_hwsq **); -int nouveau_hwsq_fini(struct nouveau_hwsq **, bool exec); -void nouveau_hwsq_wr32(struct nouveau_hwsq *, u32 addr, u32 data); -void nouveau_hwsq_setf(struct nouveau_hwsq *, u8 flag, int data); -void nouveau_hwsq_wait(struct nouveau_hwsq *, u8 flag, u8 data); -void nouveau_hwsq_nsec(struct nouveau_hwsq *, u32 nsec); +extern struct nouveau_oclass nv04_bus_oclass; +extern struct nouveau_oclass nv31_bus_oclass; +extern struct nouveau_oclass nv50_bus_oclass; +extern struct nouveau_oclass nvc0_bus_oclass; #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h index 8f4ced7..89ee289 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/clock.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/clock.h @@ -7,81 +7,9 @@ struct nouveau_pll_vals; struct nvbios_pll; -enum nv_clk_src { - nv_clk_src_crystal, - nv_clk_src_href, - - nv_clk_src_hclk, - nv_clk_src_hclkm3, - nv_clk_src_hclkm3d2, - nv_clk_src_hclkm2d3, /* NVAA */ - nv_clk_src_hclkm4, /* NVAA */ - nv_clk_src_cclk, /* NVAA */ - - nv_clk_src_host, - - nv_clk_src_sppll0, - nv_clk_src_sppll1, - - nv_clk_src_mpllsrcref, - nv_clk_src_mpllsrc, - nv_clk_src_mpll, - nv_clk_src_mdiv, - - nv_clk_src_core, - nv_clk_src_shader, - - nv_clk_src_mem, - - nv_clk_src_gpc, - nv_clk_src_rop, - nv_clk_src_hubk01, - nv_clk_src_hubk06, - nv_clk_src_hubk07, - nv_clk_src_copy, - nv_clk_src_daemon, - nv_clk_src_disp, - nv_clk_src_vdec, - - nv_clk_src_dom6, - - nv_clk_src_max, -}; - -struct nouveau_cstate { - struct list_head head; - u8 voltage; - u32 domain[nv_clk_src_max]; -}; - -struct nouveau_pstate { - struct list_head head; - struct list_head list; /* c-states */ - struct nouveau_cstate base; - u8 pstate; - u8 fanspeed; -}; - struct nouveau_clock { struct nouveau_subdev base; - struct nouveau_clocks *domains; - struct nouveau_pstate bstate; - - struct list_head states; - int state_nr; - - int pstate; /* current */ - int ustate; /* user-requested (-1 disabled, -2 perfmon) */ - int astate; /* perfmon adjustment (base) */ - int tstate; /* thermal adjustment (max-) */ - int dstate; /* display adjustment (min+) */ - - int (*read)(struct nouveau_clock *, enum nv_clk_src); - int (*calc)(struct nouveau_clock *, struct nouveau_cstate *); - int (*prog)(struct nouveau_clock *); - void (*tidy)(struct nouveau_clock *); - /*XXX: die, these are here *only* to support the completely * bat-shit insane what-was-nouveau_hw.c code */ @@ -97,43 +25,27 @@ nouveau_clock(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_CLOCK]; } -struct nouveau_clocks { - enum nv_clk_src name; - u8 bios; /* 0xff for none */ -#define NVKM_CLK_DOM_FLAG_CORE 0x01 - u8 flags; - const char *mname; - int mdiv; -}; - -#define nouveau_clock_create(p,e,o,i,d) \ - nouveau_clock_create_((p), (e), (o), (i), sizeof(**d), (void **)d) -#define nouveau_clock_destroy(p) ({ \ - struct nouveau_clock *clk = (p); \ - _nouveau_clock_dtor(nv_object(clk)); \ -}) -#define nouveau_clock_init(p) ({ \ - struct nouveau_clock *clk = (p); \ - _nouveau_clock_init(nv_object(clk)); \ -}) +#define nouveau_clock_create(p,e,o,d) \ + nouveau_subdev_create((p), (e), (o), 0, "CLOCK", "clock", d) +#define nouveau_clock_destroy(p) \ + nouveau_subdev_destroy(&(p)->base) +#define nouveau_clock_init(p) \ + nouveau_subdev_init(&(p)->base) #define nouveau_clock_fini(p,s) \ nouveau_subdev_fini(&(p)->base, (s)) int nouveau_clock_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, - struct nouveau_clocks *, int, void **); -void _nouveau_clock_dtor(struct nouveau_object *); -int _nouveau_clock_init(struct nouveau_object *); + struct nouveau_oclass *, void *, u32, int, void **); + +#define _nouveau_clock_dtor _nouveau_subdev_dtor +#define _nouveau_clock_init _nouveau_subdev_init #define _nouveau_clock_fini _nouveau_subdev_fini extern struct nouveau_oclass nv04_clock_oclass; extern struct nouveau_oclass nv40_clock_oclass; -extern struct nouveau_oclass *nv50_clock_oclass; -extern struct nouveau_oclass *nv84_clock_oclass; -extern struct nouveau_oclass *nvaa_clock_oclass; +extern struct nouveau_oclass nv50_clock_oclass; extern struct nouveau_oclass nva3_clock_oclass; extern struct nouveau_oclass nvc0_clock_oclass; -extern struct nouveau_oclass nve0_clock_oclass; int nv04_clock_pll_set(struct nouveau_clock *, u32 type, u32 freq); int nv04_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, @@ -143,9 +55,4 @@ int nv04_clock_pll_prog(struct nouveau_clock *, u32 reg1, int nva3_clock_pll_calc(struct nouveau_clock *, struct nvbios_pll *, int clk, struct nouveau_pll_vals *); -int nouveau_clock_ustate(struct nouveau_clock *, int req); -int nouveau_clock_astate(struct nouveau_clock *, int req, int rel); -int nouveau_clock_dstate(struct nouveau_clock *, int req, int rel); -int nouveau_clock_tstate(struct nouveau_clock *, int req, int rel); - #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h index 8541aa3..2e74050 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/fb.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/fb.h @@ -78,28 +78,23 @@ nouveau_fb(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_FB]; } -extern struct nouveau_oclass *nv04_fb_oclass; -extern struct nouveau_oclass *nv10_fb_oclass; -extern struct nouveau_oclass *nv1a_fb_oclass; -extern struct nouveau_oclass *nv20_fb_oclass; -extern struct nouveau_oclass *nv25_fb_oclass; -extern struct nouveau_oclass *nv30_fb_oclass; -extern struct nouveau_oclass *nv35_fb_oclass; -extern struct nouveau_oclass *nv36_fb_oclass; -extern struct nouveau_oclass *nv40_fb_oclass; -extern struct nouveau_oclass *nv41_fb_oclass; -extern struct nouveau_oclass *nv44_fb_oclass; -extern struct nouveau_oclass *nv46_fb_oclass; -extern struct nouveau_oclass *nv47_fb_oclass; -extern struct nouveau_oclass *nv49_fb_oclass; -extern struct nouveau_oclass *nv4e_fb_oclass; -extern struct nouveau_oclass *nv50_fb_oclass; -extern struct nouveau_oclass *nv84_fb_oclass; -extern struct nouveau_oclass *nva3_fb_oclass; -extern struct nouveau_oclass *nvaa_fb_oclass; -extern struct nouveau_oclass *nvaf_fb_oclass; -extern struct nouveau_oclass *nvc0_fb_oclass; -extern struct nouveau_oclass *nve0_fb_oclass; +extern struct nouveau_oclass nv04_fb_oclass; +extern struct nouveau_oclass nv10_fb_oclass; +extern struct nouveau_oclass nv1a_fb_oclass; +extern struct nouveau_oclass nv20_fb_oclass; +extern struct nouveau_oclass nv25_fb_oclass; +extern struct nouveau_oclass nv30_fb_oclass; +extern struct nouveau_oclass nv35_fb_oclass; +extern struct nouveau_oclass nv36_fb_oclass; +extern struct nouveau_oclass nv40_fb_oclass; +extern struct nouveau_oclass nv41_fb_oclass; +extern struct nouveau_oclass nv44_fb_oclass; +extern struct nouveau_oclass nv46_fb_oclass; +extern struct nouveau_oclass nv47_fb_oclass; +extern struct nouveau_oclass nv49_fb_oclass; +extern struct nouveau_oclass nv4e_fb_oclass; +extern struct nouveau_oclass nv50_fb_oclass; +extern struct nouveau_oclass nvc0_fb_oclass; struct nouveau_ram { struct nouveau_object base; @@ -126,17 +121,6 @@ struct nouveau_ram { int (*get)(struct nouveau_fb *, u64 size, u32 align, u32 size_nc, u32 type, struct nouveau_mem **); void (*put)(struct nouveau_fb *, struct nouveau_mem **); - - int (*calc)(struct nouveau_fb *, u32 freq); - int (*prog)(struct nouveau_fb *); - void (*tidy)(struct nouveau_fb *); - struct { - u8 version; - u32 data; - u8 size; - } rammap, ramcfg, timing; - u32 freq; - u32 mr[16]; }; #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h index 9fa5da7..7e4e277 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h @@ -60,18 +60,13 @@ void _nouveau_i2c_port_dtor(struct nouveau_object *); #define _nouveau_i2c_port_init nouveau_object_init #define _nouveau_i2c_port_fini nouveau_object_fini -struct nouveau_i2c_board_info { - struct i2c_board_info dev; - u8 udelay; /* set to 0 to use the standard delay */ -}; - struct nouveau_i2c { struct nouveau_subdev base; struct nouveau_i2c_port *(*find)(struct nouveau_i2c *, u8 index); struct nouveau_i2c_port *(*find_type)(struct nouveau_i2c *, u16 type); int (*identify)(struct nouveau_i2c *, int index, - const char *what, struct nouveau_i2c_board_info *, + const char *what, struct i2c_board_info *, bool (*match)(struct nouveau_i2c_port *, struct i2c_board_info *)); struct list_head ports; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h index adc88b7..ce6569f 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/mc.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/mc.h @@ -11,6 +11,7 @@ struct nouveau_mc_intr { struct nouveau_mc { struct nouveau_subdev base; + const struct nouveau_mc_intr *intr_map; bool use_msi; }; @@ -20,8 +21,8 @@ nouveau_mc(void *obj) return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_MC]; } -#define nouveau_mc_create(p,e,o,d) \ - nouveau_mc_create_((p), (e), (o), sizeof(**d), (void **)d) +#define nouveau_mc_create(p,e,o,m,d) \ + nouveau_mc_create_((p), (e), (o), (m), sizeof(**d), (void **)d) #define nouveau_mc_destroy(p) ({ \ struct nouveau_mc *pmc = (p); _nouveau_mc_dtor(nv_object(pmc)); \ }) @@ -33,24 +34,20 @@ nouveau_mc(void *obj) }) int nouveau_mc_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, void **); + struct nouveau_oclass *, const struct nouveau_mc_intr *, + int, void **); void _nouveau_mc_dtor(struct nouveau_object *); int _nouveau_mc_init(struct nouveau_object *); int _nouveau_mc_fini(struct nouveau_object *, bool); -struct nouveau_mc_oclass { - struct nouveau_oclass base; - const struct nouveau_mc_intr *intr; - void (*msi_rearm)(struct nouveau_mc *); -}; +extern struct nouveau_oclass nv04_mc_oclass; +extern struct nouveau_oclass nv44_mc_oclass; +extern struct nouveau_oclass nv50_mc_oclass; +extern struct nouveau_oclass nv98_mc_oclass; +extern struct nouveau_oclass nvc0_mc_oclass; -extern struct nouveau_oclass *nv04_mc_oclass; -extern struct nouveau_oclass *nv40_mc_oclass; -extern struct nouveau_oclass *nv44_mc_oclass; -extern struct nouveau_oclass *nv50_mc_oclass; -extern struct nouveau_oclass *nv94_mc_oclass; -extern struct nouveau_oclass *nv98_mc_oclass; -extern struct nouveau_oclass *nvc0_mc_oclass; -extern struct nouveau_oclass *nvc3_mc_oclass; +extern const struct nouveau_mc_intr nv04_mc_intr[]; +int nv04_mc_init(struct nouveau_object *); +int nv50_mc_init(struct nouveau_object *); #endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h deleted file mode 100644 index c5c92cb..0000000 --- a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h +++ /dev/null @@ -1,80 +0,0 @@ -#ifndef __NOUVEAU_PWR_H__ -#define __NOUVEAU_PWR_H__ - -#include <core/subdev.h> -#include <core/device.h> - -struct nouveau_pwr { - struct nouveau_subdev base; - - struct { - u32 limit; - u32 *data; - u32 size; - } code; - - struct { - u32 limit; - u32 *data; - u32 size; - } data; - - struct { - u32 base; - u32 size; - } send; - - struct { - u32 base; - u32 size; - - struct work_struct work; - wait_queue_head_t wait; - u32 process; - u32 message; - u32 data[2]; - } recv; - - int (*message)(struct nouveau_pwr *, u32[2], u32, u32, u32, u32); -}; - -static inline struct nouveau_pwr * -nouveau_pwr(void *obj) -{ - return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_PWR]; -} - -#define nouveau_pwr_create(p, e, o, d) \ - nouveau_pwr_create_((p), (e), (o), sizeof(**d), (void **)d) -#define nouveau_pwr_destroy(p) \ - nouveau_subdev_destroy(&(p)->base) -#define nouveau_pwr_init(p) ({ \ - struct nouveau_pwr *ppwr = (p); \ - _nouveau_pwr_init(nv_object(ppwr)); \ -}) -#define nouveau_pwr_fini(p,s) ({ \ - struct nouveau_pwr *ppwr = (p); \ - _nouveau_pwr_fini(nv_object(ppwr), (s)); \ -}) - -int nouveau_pwr_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, void **); -#define _nouveau_pwr_dtor _nouveau_subdev_dtor -int _nouveau_pwr_init(struct nouveau_object *); -int _nouveau_pwr_fini(struct nouveau_object *, bool); - -extern struct nouveau_oclass nva3_pwr_oclass; -extern struct nouveau_oclass nvc0_pwr_oclass; -extern struct nouveau_oclass nvd0_pwr_oclass; -extern struct nouveau_oclass nv108_pwr_oclass; - -/* interface to MEMX process running on PPWR */ -struct nouveau_memx; -int nouveau_memx_init(struct nouveau_pwr *, struct nouveau_memx **); -int nouveau_memx_fini(struct nouveau_memx **, bool exec); -void nouveau_memx_wr32(struct nouveau_memx *, u32 addr, u32 data); -void nouveau_memx_wait(struct nouveau_memx *, - u32 addr, u32 mask, u32 data, u32 nsec); -void nouveau_memx_nsec(struct nouveau_memx *, u32 nsec); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h index 69891d4..c075998 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/therm.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/therm.h @@ -71,8 +71,6 @@ void _nouveau_therm_dtor(struct nouveau_object *); int _nouveau_therm_init(struct nouveau_object *); int _nouveau_therm_fini(struct nouveau_object *, bool); -int nouveau_therm_cstate(struct nouveau_therm *, int, int); - extern struct nouveau_oclass nv40_therm_oclass; extern struct nouveau_oclass nv50_therm_oclass; extern struct nouveau_oclass nv84_therm_oclass; diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/volt.h b/drivers/gpu/drm/nouveau/core/include/subdev/volt.h deleted file mode 100644 index 820b62f..0000000 --- a/drivers/gpu/drm/nouveau/core/include/subdev/volt.h +++ /dev/null @@ -1,60 +0,0 @@ -#ifndef __NOUVEAU_VOLT_H__ -#define __NOUVEAU_VOLT_H__ - -#include <core/subdev.h> -#include <core/device.h> - -struct nouveau_voltage { - u32 uv; - u8 id; -}; - -struct nouveau_volt { - struct nouveau_subdev base; - - int (*vid_get)(struct nouveau_volt *); - int (*get)(struct nouveau_volt *); - int (*vid_set)(struct nouveau_volt *, u8 vid); - int (*set)(struct nouveau_volt *, u32 uv); - int (*set_id)(struct nouveau_volt *, u8 id, int condition); - - u8 vid_mask; - u8 vid_nr; - struct { - u32 uv; - u8 vid; - } vid[256]; -}; - -static inline struct nouveau_volt * -nouveau_volt(void *obj) -{ - return (void *)nv_device(obj)->subdev[NVDEV_SUBDEV_VOLT]; -} - -#define nouveau_volt_create(p, e, o, d) \ - nouveau_volt_create_((p), (e), (o), sizeof(**d), (void **)d) -#define nouveau_volt_destroy(p) ({ \ - struct nouveau_volt *v = (p); \ - _nouveau_volt_dtor(nv_object(v)); \ -}) -#define nouveau_volt_init(p) ({ \ - struct nouveau_volt *v = (p); \ - _nouveau_volt_init(nv_object(v)); \ -}) -#define nouveau_volt_fini(p,s) \ - nouveau_subdev_fini((p), (s)) - -int nouveau_volt_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, void **); -void _nouveau_volt_dtor(struct nouveau_object *); -int _nouveau_volt_init(struct nouveau_object *); -#define _nouveau_volt_fini _nouveau_subdev_fini - -extern struct nouveau_oclass nv40_volt_oclass; - -int nouveau_voltgpio_init(struct nouveau_volt *); -int nouveau_voltgpio_get(struct nouveau_volt *); -int nouveau_voltgpio_set(struct nouveau_volt *, u8); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/boost.c b/drivers/gpu/drm/nouveau/core/subdev/bios/boost.c deleted file mode 100644 index c1835e5..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/boost.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * 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 <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/boost.h> - -u16 -nvbios_boostTe(struct nouveau_bios *bios, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *snr, u8 *ssz) -{ - struct bit_entry bit_P; - u16 boost = 0x0000; - - if (!bit_entry(bios, 'P', &bit_P)) { - if (bit_P.version == 2) - boost = nv_ro16(bios, bit_P.offset + 0x30); - - if (boost) { - *ver = nv_ro08(bios, boost + 0); - switch (*ver) { - case 0x11: - *hdr = nv_ro08(bios, boost + 1); - *cnt = nv_ro08(bios, boost + 5); - *len = nv_ro08(bios, boost + 2); - *snr = nv_ro08(bios, boost + 4); - *ssz = nv_ro08(bios, boost + 3); - return boost; - default: - break; - } - } - } - - return 0x0000; -} - -u16 -nvbios_boostEe(struct nouveau_bios *bios, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - u8 snr, ssz; - u16 data = nvbios_boostTe(bios, ver, hdr, cnt, len, &snr, &ssz); - if (data && idx < *cnt) { - data = data + *hdr + (idx * (*len + (snr * ssz))); - *hdr = *len; - *cnt = snr; - *len = ssz; - return data; - } - return 0x0000; -} - -u16 -nvbios_boostEp(struct nouveau_bios *bios, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info) -{ - u16 data = nvbios_boostEe(bios, idx, ver, hdr, cnt, len); - memset(info, 0x00, sizeof(*info)); - if (data) { - info->pstate = (nv_ro16(bios, data + 0x00) & 0x01e0) >> 5; - info->min = nv_ro16(bios, data + 0x02) * 1000; - info->max = nv_ro16(bios, data + 0x04) * 1000; - } - return data; -} - -u16 -nvbios_boostEm(struct nouveau_bios *bios, u8 pstate, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, struct nvbios_boostE *info) -{ - u32 data, idx = 0; - while ((data = nvbios_boostEp(bios, idx++, ver, hdr, cnt, len, info))) { - if (info->pstate == pstate) - break; - } - return data; -} - -u16 -nvbios_boostSe(struct nouveau_bios *bios, int idx, - u16 data, u8 *ver, u8 *hdr, u8 cnt, u8 len) -{ - if (data && idx < cnt) { - data = data + *hdr + (idx * len); - *hdr = len; - return data; - } - return 0x0000; -} - -u16 -nvbios_boostSp(struct nouveau_bios *bios, int idx, - u16 data, u8 *ver, u8 *hdr, u8 cnt, u8 len, - struct nvbios_boostS *info) -{ - data = nvbios_boostSe(bios, idx, data, ver, hdr, cnt, len); - memset(info, 0x00, sizeof(*info)); - if (data) { - info->domain = nv_ro08(bios, data + 0x00); - info->percent = nv_ro08(bios, data + 0x01); - info->min = nv_ro16(bios, data + 0x02) * 1000; - info->max = nv_ro16(bios, data + 0x04) * 1000; - } - return data; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c b/drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c deleted file mode 100644 index d3b1532..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/cstep.c +++ /dev/null @@ -1,123 +0,0 @@ -/* - * 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 <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/cstep.h> - -u16 -nvbios_cstepTe(struct nouveau_bios *bios, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, u8 *xnr, u8 *xsz) -{ - struct bit_entry bit_P; - u16 cstep = 0x0000; - - if (!bit_entry(bios, 'P', &bit_P)) { - if (bit_P.version == 2) - cstep = nv_ro16(bios, bit_P.offset + 0x34); - - if (cstep) { - *ver = nv_ro08(bios, cstep + 0); - switch (*ver) { - case 0x10: - *hdr = nv_ro08(bios, cstep + 1); - *cnt = nv_ro08(bios, cstep + 3); - *len = nv_ro08(bios, cstep + 2); - *xnr = nv_ro08(bios, cstep + 5); - *xsz = nv_ro08(bios, cstep + 4); - return cstep; - default: - break; - } - } - } - - return 0x0000; -} - -u16 -nvbios_cstepEe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr) -{ - u8 cnt, len, xnr, xsz; - u16 data = nvbios_cstepTe(bios, ver, hdr, &cnt, &len, &xnr, &xsz); - if (data && idx < cnt) { - data = data + *hdr + (idx * len); - *hdr = len; - return data; - } - return 0x0000; -} - -u16 -nvbios_cstepEp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr, - struct nvbios_cstepE *info) -{ - u16 data = nvbios_cstepEe(bios, idx, ver, hdr); - memset(info, 0x00, sizeof(*info)); - if (data) { - info->pstate = (nv_ro16(bios, data + 0x00) & 0x01e0) >> 5; - info->index = nv_ro08(bios, data + 0x03); - } - return data; -} - -u16 -nvbios_cstepEm(struct nouveau_bios *bios, u8 pstate, u8 *ver, u8 *hdr, - struct nvbios_cstepE *info) -{ - u32 data, idx = 0; - while ((data = nvbios_cstepEp(bios, idx++, ver, hdr, info))) { - if (info->pstate == pstate) - break; - } - return data; -} - -u16 -nvbios_cstepXe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr) -{ - u8 cnt, len, xnr, xsz; - u16 data = nvbios_cstepTe(bios, ver, hdr, &cnt, &len, &xnr, &xsz); - if (data && idx < xnr) { - data = data + *hdr + (cnt * len) + (idx * xsz); - *hdr = xsz; - return data; - } - return 0x0000; -} - -u16 -nvbios_cstepXp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr, - struct nvbios_cstepX *info) -{ - u16 data = nvbios_cstepXe(bios, idx, ver, hdr); - memset(info, 0x00, sizeof(*info)); - if (data) { - info->freq = nv_ro16(bios, data + 0x00) * 1000; - info->unkn[0] = nv_ro08(bios, data + 0x02); - info->unkn[1] = nv_ro08(bios, data + 0x03); - info->voltage = nv_ro08(bios, data + 0x04); - } - return data; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c index 7628fe7..663853b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c @@ -89,7 +89,6 @@ nvbios_dpout_parse(struct nouveau_bios *bios, u8 idx, struct nvbios_dpout *info) { u16 data = nvbios_dpout_entry(bios, idx, ver, hdr, cnt, len); - memset(info, 0x00, sizeof(*info)); if (data && *ver) { info->type = nv_ro16(bios, data + 0x00); info->mask = nv_ro16(bios, data + 0x02); @@ -100,12 +99,9 @@ nvbios_dpout_parse(struct nouveau_bios *bios, u8 idx, info->script[0] = nv_ro16(bios, data + 0x06); info->script[1] = nv_ro16(bios, data + 0x08); info->lnkcmp = nv_ro16(bios, data + 0x0a); - if (*len >= 0x0f) { - info->script[2] = nv_ro16(bios, data + 0x0c); - info->script[3] = nv_ro16(bios, data + 0x0e); - } - if (*len >= 0x11) - info->script[4] = nv_ro16(bios, data + 0x10); + info->script[2] = nv_ro16(bios, data + 0x0c); + info->script[3] = nv_ro16(bios, data + 0x0e); + info->script[4] = nv_ro16(bios, data + 0x10); break; case 0x40: info->flags = nv_ro08(bios, data + 0x04); diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index 420908c..57cda2a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -2180,7 +2180,7 @@ nvbios_init(struct nouveau_subdev *subdev, bool execute) u16 data; if (execute) - nv_info(bios, "running init tables\n"); + nv_suspend(bios, "running init tables\n"); while (!ret && (data = (init_script(bios, ++i)))) { struct nvbios_init init = { .subdev = subdev, @@ -2210,5 +2210,5 @@ nvbios_init(struct nouveau_subdev *subdev, bool execute) ret = nvbios_exec(&init); } - return ret; + return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c b/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c index 675e221..bcbb056 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/perf.c @@ -26,9 +26,8 @@ #include <subdev/bios/bit.h> #include <subdev/bios/perf.h> -u16 -nvbios_perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, - u8 *cnt, u8 *len, u8 *snr, u8 *ssz) +static u16 +perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) { struct bit_entry bit_P; u16 perf = 0x0000; @@ -39,22 +38,10 @@ nvbios_perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, if (perf) { *ver = nv_ro08(bios, perf + 0); *hdr = nv_ro08(bios, perf + 1); - if (*ver >= 0x40 && *ver < 0x41) { - *cnt = nv_ro08(bios, perf + 5); - *len = nv_ro08(bios, perf + 2); - *snr = nv_ro08(bios, perf + 4); - *ssz = nv_ro08(bios, perf + 3); - return perf; - } else - if (*ver >= 0x20 && *ver < 0x40) { - *cnt = nv_ro08(bios, perf + 2); - *len = nv_ro08(bios, perf + 3); - *snr = nv_ro08(bios, perf + 4); - *ssz = nv_ro08(bios, perf + 5); - return perf; - } } - } + } else + nv_error(bios, "unknown offset for perf in BIT P %d\n", + bit_P.version); } if (bios->bmp_offset) { @@ -63,132 +50,19 @@ nvbios_perf_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, if (perf) { *hdr = nv_ro08(bios, perf + 0); *ver = nv_ro08(bios, perf + 1); - *cnt = nv_ro08(bios, perf + 2); - *len = nv_ro08(bios, perf + 3); - *snr = 0; - *ssz = 0; - return perf; } } } - return 0x0000; -} - -u16 -nvbios_perf_entry(struct nouveau_bios *bios, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - u8 snr, ssz; - u16 perf = nvbios_perf_table(bios, ver, hdr, cnt, len, &snr, &ssz); - if (perf && idx < *cnt) { - perf = perf + *hdr + (idx * (*len + (snr * ssz))); - *hdr = *len; - *cnt = snr; - *len = ssz; - return perf; - } - return 0x0000; -} - -u16 -nvbios_perfEp(struct nouveau_bios *bios, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len, - struct nvbios_perfE *info) -{ - u16 perf = nvbios_perf_entry(bios, idx, ver, hdr, cnt, len); - memset(info, 0x00, sizeof(*info)); - info->pstate = nv_ro08(bios, perf + 0x00); - switch (!!perf * *ver) { - case 0x12: - case 0x13: - case 0x14: - info->core = nv_ro32(bios, perf + 0x01) * 10; - info->memory = nv_ro32(bios, perf + 0x05) * 20; - info->fanspeed = nv_ro08(bios, perf + 0x37); - if (*hdr > 0x38) - info->voltage = nv_ro08(bios, perf + 0x38); - break; - case 0x21: - case 0x23: - case 0x24: - info->fanspeed = nv_ro08(bios, perf + 0x04); - info->voltage = nv_ro08(bios, perf + 0x05); - info->shader = nv_ro16(bios, perf + 0x06) * 1000; - info->core = info->shader + (signed char) - nv_ro08(bios, perf + 0x08) * 1000; - switch (nv_device(bios)->chipset) { - case 0x49: - case 0x4b: - info->memory = nv_ro16(bios, perf + 0x0b) * 1000; - break; - default: - info->memory = nv_ro16(bios, perf + 0x0b) * 2000; - break; - } - break; - case 0x25: - info->fanspeed = nv_ro08(bios, perf + 0x04); - info->voltage = nv_ro08(bios, perf + 0x05); - info->core = nv_ro16(bios, perf + 0x06) * 1000; - info->shader = nv_ro16(bios, perf + 0x0a) * 1000; - info->memory = nv_ro16(bios, perf + 0x0c) * 1000; - break; - case 0x30: - info->script = nv_ro16(bios, perf + 0x02); - case 0x35: - info->fanspeed = nv_ro08(bios, perf + 0x06); - info->voltage = nv_ro08(bios, perf + 0x07); - info->core = nv_ro16(bios, perf + 0x08) * 1000; - info->shader = nv_ro16(bios, perf + 0x0a) * 1000; - info->memory = nv_ro16(bios, perf + 0x0c) * 1000; - info->vdec = nv_ro16(bios, perf + 0x10) * 1000; - info->disp = nv_ro16(bios, perf + 0x14) * 1000; - break; - case 0x40: - info->voltage = nv_ro08(bios, perf + 0x02); - break; - default: - return 0x0000; - } return perf; } -u32 -nvbios_perfSe(struct nouveau_bios *bios, u32 perfE, int idx, - u8 *ver, u8 *hdr, u8 cnt, u8 len) -{ - u32 data = 0x00000000; - if (idx < cnt) { - data = perfE + *hdr + (idx * len); - *hdr = len; - } - return data; -} - -u32 -nvbios_perfSp(struct nouveau_bios *bios, u32 perfE, int idx, - u8 *ver, u8 *hdr, u8 cnt, u8 len, - struct nvbios_perfS *info) -{ - u32 data = nvbios_perfSe(bios, perfE, idx, ver, hdr, cnt, len); - memset(info, 0x00, sizeof(*info)); - switch (!!data * *ver) { - case 0x40: - info->v40.freq = (nv_ro16(bios, data + 0x00) & 0x3fff) * 1000; - break; - default: - break; - } - return data; -} - int nvbios_perf_fan_parse(struct nouveau_bios *bios, struct nvbios_perf_fan *fan) { - u8 ver, hdr, cnt, len, snr, ssz; - u16 perf = nvbios_perf_table(bios, &ver, &hdr, &cnt, &len, &snr, &ssz); + u8 ver = 0, hdr = 0, cnt = 0, len = 0; + u16 perf = perf_table(bios, &ver, &hdr, &cnt, &len); if (!perf) return -ENODEV; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c index 1f76de5..f835501 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pll.c @@ -114,7 +114,6 @@ pll_map(struct nouveau_bios *bios) switch (nv_device(bios)->card_type) { case NV_04: case NV_10: - case NV_11: case NV_20: case NV_30: return nv04_pll_mapping; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c deleted file mode 100644 index 916fa9d..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c +++ /dev/null @@ -1,88 +0,0 @@ -/* - * 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 <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/rammap.h> - -u16 -nvbios_rammap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, - u8 *cnt, u8 *len, u8 *snr, u8 *ssz) -{ - struct bit_entry bit_P; - u16 rammap = 0x0000; - - if (!bit_entry(bios, 'P', &bit_P)) { - if (bit_P.version == 2) - rammap = nv_ro16(bios, bit_P.offset + 4); - - if (rammap) { - *ver = nv_ro08(bios, rammap + 0); - switch (*ver) { - case 0x10: - case 0x11: - *hdr = nv_ro08(bios, rammap + 1); - *cnt = nv_ro08(bios, rammap + 5); - *len = nv_ro08(bios, rammap + 2); - *snr = nv_ro08(bios, rammap + 4); - *ssz = nv_ro08(bios, rammap + 3); - return rammap; - default: - break; - } - } - } - - return 0x0000; -} - -u16 -nvbios_rammap_entry(struct nouveau_bios *bios, int idx, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - u8 snr, ssz; - u16 rammap = nvbios_rammap_table(bios, ver, hdr, cnt, len, &snr, &ssz); - if (rammap && idx < *cnt) { - rammap = rammap + *hdr + (idx * (*len + (snr * ssz))); - *hdr = *len; - *cnt = snr; - *len = ssz; - return rammap; - } - return 0x0000; -} - -u16 -nvbios_rammap_match(struct nouveau_bios *bios, u16 khz, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - int idx = 0; - u32 data; - while ((data = nvbios_rammap_entry(bios, idx++, ver, hdr, cnt, len))) { - if (khz >= nv_ro16(bios, data + 0x00) && - khz <= nv_ro16(bios, data + 0x02)) - break; - } - return data; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c b/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c deleted file mode 100644 index 151c2d6..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * 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 <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/timing.h> - -u16 -nvbios_timing_table(struct nouveau_bios *bios, - u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - struct bit_entry bit_P; - u16 timing = 0x0000; - - if (!bit_entry(bios, 'P', &bit_P)) { - if (bit_P.version == 1) - timing = nv_ro16(bios, bit_P.offset + 4); - else - if (bit_P.version == 2) - timing = nv_ro16(bios, bit_P.offset + 8); - - if (timing) { - *ver = nv_ro08(bios, timing + 0); - switch (*ver) { - case 0x10: - *hdr = nv_ro08(bios, timing + 1); - *cnt = nv_ro08(bios, timing + 2); - *len = nv_ro08(bios, timing + 3); - return timing; - case 0x20: - *hdr = nv_ro08(bios, timing + 1); - *cnt = nv_ro08(bios, timing + 3); - *len = nv_ro08(bios, timing + 2); - return timing; - default: - break; - } - } - } - - return 0x0000; -} - -u16 -nvbios_timing_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len) -{ - u8 hdr, cnt; - u16 timing = nvbios_timing_table(bios, ver, &hdr, &cnt, len); - if (timing && idx < cnt) - return timing + hdr + (idx * *len); - return 0x0000; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c b/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c deleted file mode 100644 index f343a1b..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/vmap.c +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2012 Nouveau Community - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Martin Peres - */ - -#include <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/vmap.h> - -u16 -nvbios_vmap_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - struct bit_entry bit_P; - u16 vmap = 0x0000; - - if (!bit_entry(bios, 'P', &bit_P)) { - if (bit_P.version == 2) { - vmap = nv_ro16(bios, bit_P.offset + 0x20); - if (vmap) { - *ver = nv_ro08(bios, vmap + 0); - switch (*ver) { - case 0x10: - case 0x20: - *hdr = nv_ro08(bios, vmap + 1); - *cnt = nv_ro08(bios, vmap + 3); - *len = nv_ro08(bios, vmap + 2); - return vmap; - default: - break; - } - } - } - } - - return 0x0000; -} - -u16 -nvbios_vmap_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, - struct nvbios_vmap *info) -{ - u16 vmap = nvbios_vmap_table(bios, ver, hdr, cnt, len); - memset(info, 0x00, sizeof(*info)); - switch (!!vmap * *ver) { - case 0x10: - case 0x20: - break; - } - return vmap; -} - -u16 -nvbios_vmap_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len) -{ - u8 hdr, cnt; - u16 vmap = nvbios_vmap_table(bios, ver, &hdr, &cnt, len); - if (vmap && idx < cnt) { - vmap = vmap + hdr + (idx * *len); - return vmap; - } - return 0x0000; -} - -u16 -nvbios_vmap_entry_parse(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len, - struct nvbios_vmap_entry *info) -{ - u16 vmap = nvbios_vmap_entry(bios, idx, ver, len); - memset(info, 0x00, sizeof(*info)); - switch (!!vmap * *ver) { - case 0x10: - info->link = 0xff; - info->min = nv_ro32(bios, vmap + 0x00); - info->max = nv_ro32(bios, vmap + 0x04); - info->arg[0] = nv_ro32(bios, vmap + 0x08); - info->arg[1] = nv_ro32(bios, vmap + 0x0c); - info->arg[2] = nv_ro32(bios, vmap + 0x10); - break; - case 0x20: - info->unk0 = nv_ro08(bios, vmap + 0x00); - info->link = nv_ro08(bios, vmap + 0x01); - info->min = nv_ro32(bios, vmap + 0x02); - info->max = nv_ro32(bios, vmap + 0x06); - info->arg[0] = nv_ro32(bios, vmap + 0x0a); - info->arg[1] = nv_ro32(bios, vmap + 0x0e); - info->arg[2] = nv_ro32(bios, vmap + 0x12); - info->arg[3] = nv_ro32(bios, vmap + 0x16); - info->arg[4] = nv_ro32(bios, vmap + 0x1a); - info->arg[5] = nv_ro32(bios, vmap + 0x1e); - break; - } - return vmap; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/volt.c b/drivers/gpu/drm/nouveau/core/subdev/bios/volt.c deleted file mode 100644 index bb590de..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/volt.c +++ /dev/null @@ -1,137 +0,0 @@ -/* - * Copyright 2012 Nouveau Community - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Martin Peres - */ - -#include <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/volt.h> - -u16 -nvbios_volt_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len) -{ - struct bit_entry bit_P; - u16 volt = 0x0000; - - if (!bit_entry(bios, 'P', &bit_P)) { - if (bit_P.version == 2) - volt = nv_ro16(bios, bit_P.offset + 0x0c); - else - if (bit_P.version == 1) - volt = nv_ro16(bios, bit_P.offset + 0x10); - - if (volt) { - *ver = nv_ro08(bios, volt + 0); - switch (*ver) { - case 0x12: - *hdr = 5; - *cnt = nv_ro08(bios, volt + 2); - *len = nv_ro08(bios, volt + 1); - return volt; - case 0x20: - *hdr = nv_ro08(bios, volt + 1); - *cnt = nv_ro08(bios, volt + 2); - *len = nv_ro08(bios, volt + 3); - return volt; - case 0x30: - case 0x40: - case 0x50: - *hdr = nv_ro08(bios, volt + 1); - *cnt = nv_ro08(bios, volt + 3); - *len = nv_ro08(bios, volt + 2); - return volt; - } - } - } - - return 0x0000; -} - -u16 -nvbios_volt_parse(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len, - struct nvbios_volt *info) -{ - u16 volt = nvbios_volt_table(bios, ver, hdr, cnt, len); - memset(info, 0x00, sizeof(*info)); - switch (!!volt * *ver) { - case 0x12: - info->vidmask = nv_ro08(bios, volt + 0x04); - break; - case 0x20: - info->vidmask = nv_ro08(bios, volt + 0x05); - break; - case 0x30: - info->vidmask = nv_ro08(bios, volt + 0x04); - break; - case 0x40: - info->base = nv_ro32(bios, volt + 0x04); - info->step = nv_ro16(bios, volt + 0x08); - info->vidmask = nv_ro08(bios, volt + 0x0b); - /*XXX*/ - info->min = 0; - info->max = info->base; - break; - case 0x50: - info->vidmask = nv_ro08(bios, volt + 0x06); - info->min = nv_ro32(bios, volt + 0x0a); - info->max = nv_ro32(bios, volt + 0x0e); - info->base = nv_ro32(bios, volt + 0x12) & 0x00ffffff; - info->step = nv_ro16(bios, volt + 0x16); - break; - } - return volt; -} - -u16 -nvbios_volt_entry(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len) -{ - u8 hdr, cnt; - u16 volt = nvbios_volt_table(bios, ver, &hdr, &cnt, len); - if (volt && idx < cnt) { - volt = volt + hdr + (idx * *len); - return volt; - } - return 0x0000; -} - -u16 -nvbios_volt_entry_parse(struct nouveau_bios *bios, int idx, u8 *ver, u8 *len, - struct nvbios_volt_entry *info) -{ - u16 volt = nvbios_volt_entry(bios, idx, ver, len); - memset(info, 0x00, sizeof(*info)); - switch (!!volt * *ver) { - case 0x12: - case 0x20: - info->voltage = nv_ro08(bios, volt + 0x00) * 10000; - info->vid = nv_ro08(bios, volt + 0x01); - break; - case 0x30: - info->voltage = nv_ro08(bios, volt + 0x00) * 10000; - info->vid = nv_ro08(bios, volt + 0x01) >> 2; - break; - case 0x40: - case 0x50: - break; - } - return volt; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c b/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c deleted file mode 100644 index f757470..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.c +++ /dev/null @@ -1,145 +0,0 @@ -/* - * 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 <subdev/timer.h> -#include <subdev/bus.h> - -struct nouveau_hwsq { - struct nouveau_bus *pbus; - u32 addr; - u32 data; - struct { - u8 data[512]; - u8 size; - } c; -}; - -static void -hwsq_cmd(struct nouveau_hwsq *hwsq, int size, u8 data[]) -{ - memcpy(&hwsq->c.data[hwsq->c.size], data, size * sizeof(data[0])); - hwsq->c.size += size; -} - -int -nouveau_hwsq_init(struct nouveau_bus *pbus, struct nouveau_hwsq **phwsq) -{ - struct nouveau_hwsq *hwsq; - - hwsq = *phwsq = kmalloc(sizeof(*hwsq), GFP_KERNEL); - if (hwsq) { - hwsq->pbus = pbus; - hwsq->addr = ~0; - hwsq->data = ~0; - memset(hwsq->c.data, 0x7f, sizeof(hwsq->c.data)); - hwsq->c.size = 0; - } - - return hwsq ? 0 : -ENOMEM; -} - -int -nouveau_hwsq_fini(struct nouveau_hwsq **phwsq, bool exec) -{ - struct nouveau_hwsq *hwsq = *phwsq; - int ret = 0, i; - if (hwsq) { - struct nouveau_bus *pbus = hwsq->pbus; - hwsq->c.size = (hwsq->c.size + 4) / 4; - if (hwsq->c.size <= pbus->hwsq_size) { - if (exec) - ret = pbus->hwsq_exec(pbus, (u32 *)hwsq->c.data, - hwsq->c.size); - if (ret) - nv_error(pbus, "hwsq exec failed: %d\n", ret); - } else { - nv_error(pbus, "hwsq ucode too large\n"); - ret = -ENOSPC; - } - - for (i = 0; ret && i < hwsq->c.size; i++) - nv_error(pbus, "\t0x%08x\n", ((u32 *)hwsq->c.data)[i]); - - *phwsq = NULL; - kfree(hwsq); - } - return ret; -} - -void -nouveau_hwsq_wr32(struct nouveau_hwsq *hwsq, u32 addr, u32 data) -{ - nv_debug(hwsq->pbus, "R[%06x] = 0x%08x\n", addr, data); - - if (hwsq->data != data) { - if ((data & 0xffff0000) != (hwsq->data & 0xffff0000)) { - hwsq_cmd(hwsq, 5, (u8[]){ 0xe2, data, data >> 8, - data >> 16, data >> 24 }); - } else { - hwsq_cmd(hwsq, 3, (u8[]){ 0x42, data, data >> 8 }); - } - } - - if ((addr & 0xffff0000) != (hwsq->addr & 0xffff0000)) { - hwsq_cmd(hwsq, 5, (u8[]){ 0xe0, addr, addr >> 8, - addr >> 16, addr >> 24 }); - } else { - hwsq_cmd(hwsq, 3, (u8[]){ 0x40, addr, addr >> 8 }); - } - - hwsq->addr = addr; - hwsq->data = data; -} - -void -nouveau_hwsq_setf(struct nouveau_hwsq *hwsq, u8 flag, int data) -{ - nv_debug(hwsq->pbus, " FLAG[%02x] = %d\n", flag, data); - flag += 0x80; - if (data >= 0) - flag += 0x20; - if (data >= 1) - flag += 0x20; - hwsq_cmd(hwsq, 1, (u8[]){ flag }); -} - -void -nouveau_hwsq_wait(struct nouveau_hwsq *hwsq, u8 flag, u8 data) -{ - nv_debug(hwsq->pbus, " WAIT[%02x] = %d\n", flag, data); - hwsq_cmd(hwsq, 3, (u8[]){ 0x5f, flag, data }); -} - -void -nouveau_hwsq_nsec(struct nouveau_hwsq *hwsq, u32 nsec) -{ - u8 shift = 0, usec = nsec / 1000; - while (usec & ~3) { - usec >>= 2; - shift++; - } - - nv_debug(hwsq->pbus, " DELAY = %d ns\n", nsec); - hwsq_cmd(hwsq, 1, (u8[]){ 0x00 | (shift << 2) | usec }); -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h b/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h deleted file mode 100644 index 12176f9..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bus/hwsq.h +++ /dev/null @@ -1,113 +0,0 @@ -#ifndef __NVKM_BUS_HWSQ_H__ -#define __NVKM_BUS_HWSQ_H__ - -#include <subdev/bus.h> - -struct hwsq { - struct nouveau_subdev *subdev; - struct nouveau_hwsq *hwsq; - int sequence; -}; - -struct hwsq_reg { - int sequence; - bool force; - u32 addr[2]; - u32 data; -}; - -static inline struct hwsq_reg -hwsq_reg2(u32 addr1, u32 addr2) -{ - return (struct hwsq_reg) { - .sequence = 0, - .force = 0, - .addr = { addr1, addr2 }, - .data = 0xdeadbeef, - }; -} - -static inline struct hwsq_reg -hwsq_reg(u32 addr) -{ - return hwsq_reg2(addr, addr); -} - -static inline int -hwsq_init(struct hwsq *ram, struct nouveau_subdev *subdev) -{ - struct nouveau_bus *pbus = nouveau_bus(subdev); - int ret; - - ret = nouveau_hwsq_init(pbus, &ram->hwsq); - if (ret) - return ret; - - ram->sequence++; - ram->subdev = subdev; - return 0; -} - -static inline int -hwsq_exec(struct hwsq *ram, bool exec) -{ - int ret = 0; - if (ram->subdev) { - ret = nouveau_hwsq_fini(&ram->hwsq, exec); - ram->subdev = NULL; - } - return ret; -} - -static inline u32 -hwsq_rd32(struct hwsq *ram, struct hwsq_reg *reg) -{ - if (reg->sequence != ram->sequence) - reg->data = nv_rd32(ram->subdev, reg->addr[0]); - return reg->data; -} - -static inline void -hwsq_wr32(struct hwsq *ram, struct hwsq_reg *reg, u32 data) -{ - reg->sequence = ram->sequence; - reg->data = data; - if (reg->addr[0] != reg->addr[1]) - nouveau_hwsq_wr32(ram->hwsq, reg->addr[1], reg->data); - nouveau_hwsq_wr32(ram->hwsq, reg->addr[0], reg->data); -} - -static inline void -hwsq_nuke(struct hwsq *ram, struct hwsq_reg *reg) -{ - reg->force = true; -} - -static inline u32 -hwsq_mask(struct hwsq *ram, struct hwsq_reg *reg, u32 mask, u32 data) -{ - u32 temp = hwsq_rd32(ram, reg); - if (temp != ((temp & ~mask) | data) || reg->force) - hwsq_wr32(ram, reg, (temp & ~mask) | data); - return temp; -} - -static inline void -hwsq_setf(struct hwsq *ram, u8 flag, int data) -{ - nouveau_hwsq_setf(ram->hwsq, flag, data); -} - -static inline void -hwsq_wait(struct hwsq *ram, u8 flag, u8 data) -{ - nouveau_hwsq_wait(ram->hwsq, flag, data); -} - -static inline void -hwsq_nsec(struct hwsq *ram, u32 nsec) -{ - nouveau_hwsq_nsec(ram->hwsq, nsec); -} - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c index 23921b5..8c7f805 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.c @@ -23,7 +23,11 @@ * Ben Skeggs */ -#include "nv04.h" +#include <subdev/bus.h> + +struct nv04_bus_priv { + struct nouveau_bus base; +}; static void nv04_bus_intr(struct nouveau_subdev *subdev) @@ -52,22 +56,10 @@ nv04_bus_intr(struct nouveau_subdev *subdev) } static int -nv04_bus_init(struct nouveau_object *object) -{ - struct nv04_bus_priv *priv = (void *)object; - - nv_wr32(priv, 0x001100, 0xffffffff); - nv_wr32(priv, 0x001140, 0x00000111); - - return nouveau_bus_init(&priv->base); -} - -int nv04_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv04_bus_impl *impl = (void *)oclass; struct nv04_bus_priv *priv; int ret; @@ -76,20 +68,28 @@ nv04_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - nv_subdev(priv)->intr = impl->intr; - priv->base.hwsq_exec = impl->hwsq_exec; - priv->base.hwsq_size = impl->hwsq_size; + nv_subdev(priv)->intr = nv04_bus_intr; return 0; } -struct nouveau_oclass * -nv04_bus_oclass = &(struct nv04_bus_impl) { - .base.handle = NV_SUBDEV(BUS, 0x04), - .base.ofuncs = &(struct nouveau_ofuncs) { +static int +nv04_bus_init(struct nouveau_object *object) +{ + struct nv04_bus_priv *priv = (void *)object; + + nv_wr32(priv, 0x001100, 0xffffffff); + nv_wr32(priv, 0x001140, 0x00000111); + + return nouveau_bus_init(&priv->base); +} + +struct nouveau_oclass +nv04_bus_oclass = { + .handle = NV_SUBDEV(BUS, 0x04), + .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv04_bus_ctor, .dtor = _nouveau_bus_dtor, .init = nv04_bus_init, .fini = _nouveau_bus_fini, }, - .intr = nv04_bus_intr, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h deleted file mode 100644 index 4d76024..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv04.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef __NVKM_BUS_NV04_H__ -#define __NVKM_BUS_NV04_H__ - -#include <subdev/bus.h> - -struct nv04_bus_priv { - struct nouveau_bus base; -}; - -int nv04_bus_ctor(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, void *, u32, - struct nouveau_object **); -int nv50_bus_init(struct nouveau_object *); -void nv50_bus_intr(struct nouveau_subdev *); - -struct nv04_bus_impl { - struct nouveau_oclass base; - void (*intr)(struct nouveau_subdev *); - int (*hwsq_exec)(struct nouveau_bus *, u32 *, u32); - u32 hwsq_size; -}; - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c index 94da46f..34132ae 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bus/nv31.c @@ -23,7 +23,11 @@ * Ben Skeggs */ -#include "nv04.h" +#include <subdev/bus.h> + +struct nv31_bus_priv { + struct nouveau_bus base; +}; static void nv31_bus_intr(struct nouveau_subdev *subdev) @@ -67,7 +71,7 @@ nv31_bus_intr(struct nouveau_subdev *subdev) static int nv31_bus_init(struct nouveau_object *object) { - struct nv04_bus_priv *priv = (void *)object; + struct nv31_bus_priv *priv = (void *)object; int ret; ret = nouveau_bus_init(&priv->base); @@ -79,14 +83,30 @@ nv31_bus_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nv31_bus_oclass = &(struct nv04_bus_impl) { - .base.handle = NV_SUBDEV(BUS, 0x31), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_bus_ctor, +static int +nv31_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv31_bus_priv *priv; + int ret; + + ret = nouveau_bus_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->intr = nv31_bus_intr; + return 0; +} + +struct nouveau_oclass +nv31_bus_oclass = { + .handle = NV_SUBDEV(BUS, 0x31), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv31_bus_ctor, .dtor = _nouveau_bus_dtor, .init = nv31_bus_init, .fini = _nouveau_bus_fini, }, - .intr = nv31_bus_intr, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c index 11918f7..f5b2117 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bus/nv50.c @@ -23,27 +23,13 @@ * Ben Skeggs */ -#include <subdev/timer.h> +#include <subdev/bus.h> -#include "nv04.h" +struct nv50_bus_priv { + struct nouveau_bus base; +}; -static int -nv50_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size) -{ - struct nv50_bus_priv *priv = (void *)pbus; - int i; - - nv_mask(pbus, 0x001098, 0x00000008, 0x00000000); - nv_wr32(pbus, 0x001304, 0x00000000); - for (i = 0; i < size; i++) - nv_wr32(priv, 0x001400 + (i * 4), data[i]); - nv_mask(pbus, 0x001098, 0x00000018, 0x00000018); - nv_wr32(pbus, 0x00130c, 0x00000003); - - return nv_wait(pbus, 0x001308, 0x00000100, 0x00000000) ? 0 : -ETIMEDOUT; -} - -void +static void nv50_bus_intr(struct nouveau_subdev *subdev) { struct nouveau_bus *pbus = nouveau_bus(subdev); @@ -75,10 +61,10 @@ nv50_bus_intr(struct nouveau_subdev *subdev) } } -int +static int nv50_bus_init(struct nouveau_object *object) { - struct nv04_bus_priv *priv = (void *)object; + struct nv50_bus_priv *priv = (void *)object; int ret; ret = nouveau_bus_init(&priv->base); @@ -90,16 +76,30 @@ nv50_bus_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nv50_bus_oclass = &(struct nv04_bus_impl) { - .base.handle = NV_SUBDEV(BUS, 0x50), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_bus_ctor, +static int +nv50_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv50_bus_priv *priv; + int ret; + + ret = nouveau_bus_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->intr = nv50_bus_intr; + return 0; +} + +struct nouveau_oclass +nv50_bus_oclass = { + .handle = NV_SUBDEV(BUS, 0x50), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_bus_ctor, .dtor = _nouveau_bus_dtor, .init = nv50_bus_init, .fini = _nouveau_bus_fini, }, - .intr = nv50_bus_intr, - .hwsq_exec = nv50_bus_hwsq_exec, - .hwsq_size = 64, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c deleted file mode 100644 index d365905..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/bus/nv94.c +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Copyright 2012 Nouveau Community - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR - * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, - * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - * OTHER DEALINGS IN THE SOFTWARE. - * - * Authors: Martin Peres <martin.peres@labri.fr> - * Ben Skeggs - */ - -#include <subdev/timer.h> - -#include "nv04.h" - -static int -nv94_bus_hwsq_exec(struct nouveau_bus *pbus, u32 *data, u32 size) -{ - struct nv50_bus_priv *priv = (void *)pbus; - int i; - - nv_mask(pbus, 0x001098, 0x00000008, 0x00000000); - nv_wr32(pbus, 0x001304, 0x00000000); - nv_wr32(pbus, 0x001318, 0x00000000); - for (i = 0; i < size; i++) - nv_wr32(priv, 0x080000 + (i * 4), data[i]); - nv_mask(pbus, 0x001098, 0x00000018, 0x00000018); - nv_wr32(pbus, 0x00130c, 0x00000001); - - return nv_wait(pbus, 0x001308, 0x00000100, 0x00000000) ? 0 : -ETIMEDOUT; -} - -struct nouveau_oclass * -nv94_bus_oclass = &(struct nv04_bus_impl) { - .base.handle = NV_SUBDEV(BUS, 0x94), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_bus_ctor, - .dtor = _nouveau_bus_dtor, - .init = nv50_bus_init, - .fini = _nouveau_bus_fini, - }, - .intr = nv50_bus_intr, - .hwsq_exec = nv94_bus_hwsq_exec, - .hwsq_size = 128, -}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c index 73839d7..b192d62 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bus/nvc0.c @@ -23,7 +23,11 @@ * Ben Skeggs */ -#include "nv04.h" +#include <subdev/bus.h> + +struct nvc0_bus_priv { + struct nouveau_bus base; +}; static void nvc0_bus_intr(struct nouveau_subdev *subdev) @@ -56,7 +60,7 @@ nvc0_bus_intr(struct nouveau_subdev *subdev) static int nvc0_bus_init(struct nouveau_object *object) { - struct nv04_bus_priv *priv = (void *)object; + struct nvc0_bus_priv *priv = (void *)object; int ret; ret = nouveau_bus_init(&priv->base); @@ -68,14 +72,30 @@ nvc0_bus_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nvc0_bus_oclass = &(struct nv04_bus_impl) { - .base.handle = NV_SUBDEV(BUS, 0xc0), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_bus_ctor, +static int +nvc0_bus_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nvc0_bus_priv *priv; + int ret; + + ret = nouveau_bus_create(parent, engine, oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + nv_subdev(priv)->intr = nvc0_bus_intr; + return 0; +} + +struct nouveau_oclass +nvc0_bus_oclass = { + .handle = NV_SUBDEV(BUS, 0xc0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_bus_ctor, .dtor = _nouveau_bus_dtor, .init = nvc0_bus_init, .fini = _nouveau_bus_fini, }, - .intr = nvc0_bus_intr, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c b/drivers/gpu/drm/nouveau/core/subdev/clock/base.c deleted file mode 100644 index e2938a2..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/base.c +++ /dev/null @@ -1,494 +0,0 @@ -/* - * 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 <subdev/clock.h> -#include <subdev/therm.h> -#include <subdev/volt.h> -#include <subdev/fb.h> - -#include <subdev/bios.h> -#include <subdev/bios/boost.h> -#include <subdev/bios/cstep.h> -#include <subdev/bios/perf.h> - -/****************************************************************************** - * misc - *****************************************************************************/ -static u32 -nouveau_clock_adjust(struct nouveau_clock *clk, bool adjust, - u8 pstate, u8 domain, u32 input) -{ - struct nouveau_bios *bios = nouveau_bios(clk); - struct nvbios_boostE boostE; - u8 ver, hdr, cnt, len; - u16 data; - - data = nvbios_boostEm(bios, pstate, &ver, &hdr, &cnt, &len, &boostE); - if (data) { - struct nvbios_boostS boostS; - u8 idx = 0, sver, shdr; - u16 subd; - - input = max(boostE.min, input); - input = min(boostE.max, input); - do { - sver = ver; - shdr = hdr; - subd = nvbios_boostSp(bios, idx++, data, &sver, &shdr, - cnt, len, &boostS); - if (subd && boostS.domain == domain) { - if (adjust) - input = input * boostS.percent / 100; - input = max(boostS.min, input); - input = min(boostS.max, input); - break; - } - } while (subd); - } - - return input; -} - -/****************************************************************************** - * C-States - *****************************************************************************/ -static int -nouveau_cstate_prog(struct nouveau_clock *clk, - struct nouveau_pstate *pstate, int cstatei) -{ - struct nouveau_therm *ptherm = nouveau_therm(clk); - struct nouveau_volt *volt = nouveau_volt(clk); - struct nouveau_cstate *cstate; - int ret; - - if (!list_empty(&pstate->list)) { - cstate = list_entry(pstate->list.prev, typeof(*cstate), head); - } else { - cstate = &pstate->base; - } - - ret = nouveau_therm_cstate(ptherm, pstate->fanspeed, +1); - if (ret && ret != -ENODEV) { - nv_error(clk, "failed to raise fan speed: %d\n", ret); - return ret; - } - - ret = volt->set_id(volt, cstate->voltage, +1); - if (ret && ret != -ENODEV) { - nv_error(clk, "failed to raise voltage: %d\n", ret); - return ret; - } - - ret = clk->calc(clk, cstate); - if (ret == 0) { - ret = clk->prog(clk); - clk->tidy(clk); - } - - ret = volt->set_id(volt, cstate->voltage, -1); - if (ret && ret != -ENODEV) - nv_error(clk, "failed to lower voltage: %d\n", ret); - - ret = nouveau_therm_cstate(ptherm, pstate->fanspeed, -1); - if (ret && ret != -ENODEV) - nv_error(clk, "failed to lower fan speed: %d\n", ret); - - return 0; -} - -static void -nouveau_cstate_del(struct nouveau_cstate *cstate) -{ - list_del(&cstate->head); - kfree(cstate); -} - -static int -nouveau_cstate_new(struct nouveau_clock *clk, int idx, - struct nouveau_pstate *pstate) -{ - struct nouveau_bios *bios = nouveau_bios(clk); - struct nouveau_clocks *domain = clk->domains; - struct nouveau_cstate *cstate = NULL; - struct nvbios_cstepX cstepX; - u8 ver, hdr; - u16 data; - - data = nvbios_cstepXp(bios, idx, &ver, &hdr, &cstepX); - if (!data) - return -ENOENT; - - cstate = kzalloc(sizeof(*cstate), GFP_KERNEL); - if (!cstate) - return -ENOMEM; - - *cstate = pstate->base; - cstate->voltage = cstepX.voltage; - - while (domain && domain->name != nv_clk_src_max) { - if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) { - u32 freq = nouveau_clock_adjust(clk, true, - pstate->pstate, - domain->bios, - cstepX.freq); - cstate->domain[domain->name] = freq; - } - domain++; - } - - list_add(&cstate->head, &pstate->list); - return 0; -} - -/****************************************************************************** - * P-States - *****************************************************************************/ -static int -nouveau_pstate_prog(struct nouveau_clock *clk, int pstatei) -{ - struct nouveau_fb *pfb = nouveau_fb(clk); - struct nouveau_pstate *pstate; - int ret, idx = 0; - - list_for_each_entry(pstate, &clk->states, head) { - if (idx++ == pstatei) - break; - } - - nv_debug(clk, "setting performance state %d\n", pstatei); - clk->pstate = pstatei; - - if (pfb->ram->calc) { - ret = pfb->ram->calc(pfb, pstate->base.domain[nv_clk_src_mem]); - if (ret == 0) - ret = pfb->ram->prog(pfb); - pfb->ram->tidy(pfb); - } - - return nouveau_cstate_prog(clk, pstate, 0); -} - -static int -nouveau_pstate_calc(struct nouveau_clock *clk) -{ - int pstate, ret = 0; - - nv_trace(clk, "P %d U %d A %d T %d D %d\n", clk->pstate, - clk->ustate, clk->astate, clk->tstate, clk->dstate); - - if (clk->state_nr && clk->ustate != -1) { - pstate = (clk->ustate < 0) ? clk->astate : clk->ustate; - pstate = min(pstate, clk->state_nr - 1 - clk->tstate); - pstate = max(pstate, clk->dstate); - } else { - pstate = clk->pstate = -1; - } - - nv_trace(clk, "-> %d\n", pstate); - if (pstate != clk->pstate) - ret = nouveau_pstate_prog(clk, pstate); - return ret; -} - -static void -nouveau_pstate_info(struct nouveau_clock *clk, struct nouveau_pstate *pstate) -{ - struct nouveau_clocks *clock = clk->domains - 1; - struct nouveau_cstate *cstate; - char info[3][32] = { "", "", "" }; - char name[4] = "--"; - int i = -1; - - if (pstate->pstate != 0xff) - snprintf(name, sizeof(name), "%02x", pstate->pstate); - - while ((++clock)->name != nv_clk_src_max) { - u32 lo = pstate->base.domain[clock->name]; - u32 hi = lo; - if (hi == 0) - continue; - - nv_debug(clk, "%02x: %10d KHz\n", clock->name, lo); - list_for_each_entry(cstate, &pstate->list, head) { - u32 freq = cstate->domain[clock->name]; - lo = min(lo, freq); - hi = max(hi, freq); - nv_debug(clk, "%10d KHz\n", freq); - } - - if (clock->mname && ++i < ARRAY_SIZE(info)) { - lo /= clock->mdiv; - hi /= clock->mdiv; - if (lo == hi) { - snprintf(info[i], sizeof(info[i]), "%s %d MHz", - clock->mname, lo); - } else { - snprintf(info[i], sizeof(info[i]), - "%s %d-%d MHz", clock->mname, lo, hi); - } - } - } - - nv_info(clk, "%s: %s %s %s\n", name, info[0], info[1], info[2]); -} - -static void -nouveau_pstate_del(struct nouveau_pstate *pstate) -{ - struct nouveau_cstate *cstate, *temp; - - list_for_each_entry_safe(cstate, temp, &pstate->list, head) { - nouveau_cstate_del(cstate); - } - - list_del(&pstate->head); - kfree(pstate); -} - -static int -nouveau_pstate_new(struct nouveau_clock *clk, int idx) -{ - struct nouveau_bios *bios = nouveau_bios(clk); - struct nouveau_clocks *domain = clk->domains - 1; - struct nouveau_pstate *pstate; - struct nouveau_cstate *cstate; - struct nvbios_cstepE cstepE; - struct nvbios_perfE perfE; - u8 ver, hdr, cnt, len; - u16 data; - - data = nvbios_perfEp(bios, idx, &ver, &hdr, &cnt, &len, &perfE); - if (!data) - return -EINVAL; - if (perfE.pstate == 0xff) - return 0; - - pstate = kzalloc(sizeof(*pstate), GFP_KERNEL); - cstate = &pstate->base; - if (!pstate) - return -ENOMEM; - - INIT_LIST_HEAD(&pstate->list); - - pstate->pstate = perfE.pstate; - pstate->fanspeed = perfE.fanspeed; - cstate->voltage = perfE.voltage; - cstate->domain[nv_clk_src_core] = perfE.core; - cstate->domain[nv_clk_src_shader] = perfE.shader; - cstate->domain[nv_clk_src_mem] = perfE.memory; - cstate->domain[nv_clk_src_vdec] = perfE.vdec; - cstate->domain[nv_clk_src_dom6] = perfE.disp; - - while (ver >= 0x40 && (++domain)->name != nv_clk_src_max) { - struct nvbios_perfS perfS; - u8 sver = ver, shdr = hdr; - u32 perfSe = nvbios_perfSp(bios, data, domain->bios, - &sver, &shdr, cnt, len, &perfS); - if (perfSe == 0 || sver != 0x40) - continue; - - if (domain->flags & NVKM_CLK_DOM_FLAG_CORE) { - perfS.v40.freq = nouveau_clock_adjust(clk, false, - pstate->pstate, - domain->bios, - perfS.v40.freq); - } - - cstate->domain[domain->name] = perfS.v40.freq; - } - - data = nvbios_cstepEm(bios, pstate->pstate, &ver, &hdr, &cstepE); - if (data) { - int idx = cstepE.index; - do { - nouveau_cstate_new(clk, idx, pstate); - } while(idx--); - } - - nouveau_pstate_info(clk, pstate); - list_add_tail(&pstate->head, &clk->states); - clk->state_nr++; - return 0; -} - -/****************************************************************************** - * Adjustment triggers - *****************************************************************************/ -static int -nouveau_clock_ustate_update(struct nouveau_clock *clk, int req) -{ - struct nouveau_pstate *pstate; - int i = 0; - - /* YKW repellant */ - return -ENOSYS; - - if (req != -1 && req != -2) { - list_for_each_entry(pstate, &clk->states, head) { - if (pstate->pstate == req) - break; - i++; - } - - if (pstate->pstate != req) - return -EINVAL; - req = i; - } - - clk->ustate = req; - return 0; -} - -int -nouveau_clock_ustate(struct nouveau_clock *clk, int req) -{ - int ret = nouveau_clock_ustate_update(clk, req); - if (ret) - return ret; - return nouveau_pstate_calc(clk); -} - -int -nouveau_clock_astate(struct nouveau_clock *clk, int req, int rel) -{ - if (!rel) clk->astate = req; - if ( rel) clk->astate += rel; - clk->astate = min(clk->astate, clk->state_nr - 1); - clk->astate = max(clk->astate, 0); - return nouveau_pstate_calc(clk); -} - -int -nouveau_clock_tstate(struct nouveau_clock *clk, int req, int rel) -{ - if (!rel) clk->tstate = req; - if ( rel) clk->tstate += rel; - clk->tstate = min(clk->tstate, 0); - clk->tstate = max(clk->tstate, -(clk->state_nr - 1)); - return nouveau_pstate_calc(clk); -} - -int -nouveau_clock_dstate(struct nouveau_clock *clk, int req, int rel) -{ - if (!rel) clk->dstate = req; - if ( rel) clk->dstate += rel; - clk->dstate = min(clk->dstate, clk->state_nr - 1); - clk->dstate = max(clk->dstate, 0); - return nouveau_pstate_calc(clk); -} - -/****************************************************************************** - * subdev base class implementation - *****************************************************************************/ -int -_nouveau_clock_init(struct nouveau_object *object) -{ - struct nouveau_clock *clk = (void *)object; - struct nouveau_clocks *clock = clk->domains; - int ret; - - memset(&clk->bstate, 0x00, sizeof(clk->bstate)); - INIT_LIST_HEAD(&clk->bstate.list); - clk->bstate.pstate = 0xff; - - while (clock->name != nv_clk_src_max) { - ret = clk->read(clk, clock->name); - if (ret < 0) { - nv_error(clk, "%02x freq unknown\n", clock->name); - return ret; - } - clk->bstate.base.domain[clock->name] = ret; - clock++; - } - - nouveau_pstate_info(clk, &clk->bstate); - - clk->astate = clk->state_nr - 1; - clk->tstate = 0; - clk->dstate = 0; - clk->pstate = -1; - nouveau_pstate_calc(clk); - return 0; -} - -void -_nouveau_clock_dtor(struct nouveau_object *object) -{ - struct nouveau_clock *clk = (void *)object; - struct nouveau_pstate *pstate, *temp; - - list_for_each_entry_safe(pstate, temp, &clk->states, head) { - nouveau_pstate_del(pstate); - } - - nouveau_subdev_destroy(&clk->base); -} - -int -nouveau_clock_create_(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, - struct nouveau_clocks *clocks, - int length, void **object) -{ - struct nouveau_device *device = nv_device(parent); - struct nouveau_clock *clk; - int ret, idx, arglen; - const char *mode; - - ret = nouveau_subdev_create_(parent, engine, oclass, 0, "CLK", - "clock", length, object); - clk = *object; - if (ret) - return ret; - - INIT_LIST_HEAD(&clk->states); - clk->domains = clocks; - clk->ustate = -1; - - idx = 0; - do { - ret = nouveau_pstate_new(clk, idx++); - } while (ret == 0); - - mode = nouveau_stropt(device->cfgopt, "NvClkMode", &arglen); - if (mode) { - if (!strncasecmpz(mode, "disabled", arglen)) { - clk->ustate = -1; - } else { - char save = mode[arglen]; - long v; - - ((char *)mode)[arglen] = '\0'; - if (!kstrtol(mode, 0, &v)) - nouveau_clock_ustate_update(clk, v); - ((char *)mode)[arglen] = save; - } - } - - return 0; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c index 30c1f3a..a142775 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv04.c @@ -69,11 +69,6 @@ nv04_clock_pll_prog(struct nouveau_clock *clk, u32 reg1, return 0; } -static struct nouveau_clocks -nv04_domain[] = { - { nv_clk_src_max } -}; - static int nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -82,7 +77,7 @@ nv04_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv04_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nv04_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c index db7346f..0db5dbf 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv40.c @@ -23,188 +23,11 @@ */ #include <subdev/clock.h> -#include <subdev/bios.h> -#include <subdev/bios/pll.h> - -#include "pll.h" struct nv40_clock_priv { struct nouveau_clock base; - u32 ctrl; - u32 npll_ctrl; - u32 npll_coef; - u32 spll; -}; - -static struct nouveau_clocks -nv40_domain[] = { - { nv_clk_src_crystal, 0xff }, - { nv_clk_src_href , 0xff }, - { nv_clk_src_core , 0xff, 0, "core", 1000 }, - { nv_clk_src_shader , 0xff, 0, "shader", 1000 }, - { nv_clk_src_mem , 0xff, 0, "memory", 1000 }, - { nv_clk_src_max } }; -static u32 -read_pll_1(struct nv40_clock_priv *priv, u32 reg) -{ - u32 ctrl = nv_rd32(priv, reg + 0x00); - int P = (ctrl & 0x00070000) >> 16; - int N = (ctrl & 0x0000ff00) >> 8; - int M = (ctrl & 0x000000ff) >> 0; - u32 ref = 27000, clk = 0; - - if (ctrl & 0x80000000) - clk = ref * N / M; - - return clk >> P; -} - -static u32 -read_pll_2(struct nv40_clock_priv *priv, u32 reg) -{ - u32 ctrl = nv_rd32(priv, reg + 0x00); - u32 coef = nv_rd32(priv, reg + 0x04); - int N2 = (coef & 0xff000000) >> 24; - int M2 = (coef & 0x00ff0000) >> 16; - int N1 = (coef & 0x0000ff00) >> 8; - int M1 = (coef & 0x000000ff) >> 0; - int P = (ctrl & 0x00070000) >> 16; - u32 ref = 27000, clk = 0; - - if ((ctrl & 0x80000000) && M1) { - clk = ref * N1 / M1; - if ((ctrl & 0x40000100) == 0x40000000) { - if (M2) - clk = clk * N2 / M2; - else - clk = 0; - } - } - - return clk >> P; -} - -static u32 -read_clk(struct nv40_clock_priv *priv, u32 src) -{ - switch (src) { - case 3: - return read_pll_2(priv, 0x004000); - case 2: - return read_pll_1(priv, 0x004008); - default: - break; - } - - return 0; -} - -static int -nv40_clock_read(struct nouveau_clock *clk, enum nv_clk_src src) -{ - struct nv40_clock_priv *priv = (void *)clk; - u32 mast = nv_rd32(priv, 0x00c040); - - switch (src) { - case nv_clk_src_crystal: - return nv_device(priv)->crystal; - case nv_clk_src_href: - return 100000; /*XXX: PCIE/AGP differ*/ - case nv_clk_src_core: - return read_clk(priv, (mast & 0x00000003) >> 0); - case nv_clk_src_shader: - return read_clk(priv, (mast & 0x00000030) >> 4); - case nv_clk_src_mem: - return read_pll_2(priv, 0x4020); - default: - break; - } - - nv_debug(priv, "unknown clock source %d 0x%08x\n", src, mast); - return -EINVAL; -} - -static int -nv40_clock_calc_pll(struct nv40_clock_priv *priv, u32 reg, u32 clk, - int *N1, int *M1, int *N2, int *M2, int *log2P) -{ - struct nouveau_bios *bios = nouveau_bios(priv); - struct nvbios_pll pll; - int ret; - - ret = nvbios_pll_parse(bios, reg, &pll); - if (ret) - return ret; - - if (clk < pll.vco1.max_freq) - pll.vco2.max_freq = 0; - - ret = nv04_pll_calc(nv_subdev(priv), &pll, clk, N1, M1, N2, M2, log2P); - if (ret == 0) - return -ERANGE; - return ret; -} - -static int -nv40_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate) -{ - struct nv40_clock_priv *priv = (void *)clk; - int gclk = cstate->domain[nv_clk_src_core]; - int sclk = cstate->domain[nv_clk_src_shader]; - int N1, M1, N2, M2, log2P; - int ret; - - /* core/geometric clock */ - ret = nv40_clock_calc_pll(priv, 0x004000, gclk, - &N1, &M1, &N2, &M2, &log2P); - if (ret < 0) - return ret; - - if (N2 == M2) { - priv->npll_ctrl = 0x80000100 | (log2P << 16); - priv->npll_coef = (N1 << 8) | M1; - } else { - priv->npll_ctrl = 0xc0000000 | (log2P << 16); - priv->npll_coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1; - } - - /* use the second pll for shader/rop clock, if it differs from core */ - if (sclk && sclk != gclk) { - ret = nv40_clock_calc_pll(priv, 0x004008, sclk, - &N1, &M1, NULL, NULL, &log2P); - if (ret < 0) - return ret; - - priv->spll = 0xc0000000 | (log2P << 16) | (N1 << 8) | M1; - priv->ctrl = 0x00000223; - } else { - priv->spll = 0x00000000; - priv->ctrl = 0x00000333; - } - - return 0; -} - -static int -nv40_clock_prog(struct nouveau_clock *clk) -{ - struct nv40_clock_priv *priv = (void *)clk; - nv_mask(priv, 0x00c040, 0x00000333, 0x00000000); - nv_wr32(priv, 0x004004, priv->npll_coef); - nv_mask(priv, 0x004000, 0xc0070100, priv->npll_ctrl); - nv_mask(priv, 0x004008, 0xc007ffff, priv->spll); - mdelay(5); - nv_mask(priv, 0x00c040, 0x00000333, priv->ctrl); - return 0; -} - -static void -nv40_clock_tidy(struct nouveau_clock *clk) -{ -} - static int nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, @@ -213,17 +36,13 @@ nv40_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv40_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nv40_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; priv->base.pll_calc = nv04_clock_pll_calc; priv->base.pll_prog = nv04_clock_pll_prog; - priv->base.read = nv40_clock_read; - priv->base.calc = nv40_clock_calc; - priv->base.prog = nv40_clock_prog; - priv->base.tidy = nv40_clock_tidy; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c index 250a6d9..d09d3e7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.c @@ -22,538 +22,40 @@ * Authors: Ben Skeggs */ +#include <subdev/clock.h> #include <subdev/bios.h> #include <subdev/bios/pll.h> -#include "nv50.h" #include "pll.h" -#include "seq.h" -static u32 -read_div(struct nv50_clock_priv *priv) -{ - switch (nv_device(priv)->chipset) { - case 0x50: /* it exists, but only has bit 31, not the dividers.. */ - case 0x84: - case 0x86: - case 0x98: - case 0xa0: - return nv_rd32(priv, 0x004700); - case 0x92: - case 0x94: - case 0x96: - return nv_rd32(priv, 0x004800); - default: - return 0x00000000; - } -} - -static u32 -read_pll_src(struct nv50_clock_priv *priv, u32 base) -{ - struct nouveau_clock *clk = &priv->base; - u32 coef, ref = clk->read(clk, nv_clk_src_crystal); - u32 rsel = nv_rd32(priv, 0x00e18c); - int P, N, M, id; - - switch (nv_device(priv)->chipset) { - case 0x50: - case 0xa0: - switch (base) { - case 0x4020: - case 0x4028: id = !!(rsel & 0x00000004); break; - case 0x4008: id = !!(rsel & 0x00000008); break; - case 0x4030: id = 0; break; - default: - nv_error(priv, "ref: bad pll 0x%06x\n", base); - return 0; - } - - coef = nv_rd32(priv, 0x00e81c + (id * 0x0c)); - ref *= (coef & 0x01000000) ? 2 : 4; - P = (coef & 0x00070000) >> 16; - N = ((coef & 0x0000ff00) >> 8) + 1; - M = ((coef & 0x000000ff) >> 0) + 1; - break; - case 0x84: - case 0x86: - case 0x92: - coef = nv_rd32(priv, 0x00e81c); - P = (coef & 0x00070000) >> 16; - N = (coef & 0x0000ff00) >> 8; - M = (coef & 0x000000ff) >> 0; - break; - case 0x94: - case 0x96: - case 0x98: - rsel = nv_rd32(priv, 0x00c050); - switch (base) { - case 0x4020: rsel = (rsel & 0x00000003) >> 0; break; - case 0x4008: rsel = (rsel & 0x0000000c) >> 2; break; - case 0x4028: rsel = (rsel & 0x00001800) >> 11; break; - case 0x4030: rsel = 3; break; - default: - nv_error(priv, "ref: bad pll 0x%06x\n", base); - return 0; - } - - switch (rsel) { - case 0: id = 1; break; - case 1: return clk->read(clk, nv_clk_src_crystal); - case 2: return clk->read(clk, nv_clk_src_href); - case 3: id = 0; break; - } - - coef = nv_rd32(priv, 0x00e81c + (id * 0x28)); - P = (nv_rd32(priv, 0x00e824 + (id * 0x28)) >> 16) & 7; - P += (coef & 0x00070000) >> 16; - N = (coef & 0x0000ff00) >> 8; - M = (coef & 0x000000ff) >> 0; - break; - default: - BUG_ON(1); - } - - if (M) - return (ref * N / M) >> P; - return 0; -} - -static u32 -read_pll_ref(struct nv50_clock_priv *priv, u32 base) -{ - struct nouveau_clock *clk = &priv->base; - u32 src, mast = nv_rd32(priv, 0x00c040); - - switch (base) { - case 0x004028: - src = !!(mast & 0x00200000); - break; - case 0x004020: - src = !!(mast & 0x00400000); - break; - case 0x004008: - src = !!(mast & 0x00010000); - break; - case 0x004030: - src = !!(mast & 0x02000000); - break; - case 0x00e810: - return clk->read(clk, nv_clk_src_crystal); - default: - nv_error(priv, "bad pll 0x%06x\n", base); - return 0; - } - - if (src) - return clk->read(clk, nv_clk_src_href); - return read_pll_src(priv, base); -} - -static u32 -read_pll(struct nv50_clock_priv *priv, u32 base) -{ - struct nouveau_clock *clk = &priv->base; - u32 mast = nv_rd32(priv, 0x00c040); - u32 ctrl = nv_rd32(priv, base + 0); - u32 coef = nv_rd32(priv, base + 4); - u32 ref = read_pll_ref(priv, base); - u32 freq = 0; - int N1, N2, M1, M2; - - if (base == 0x004028 && (mast & 0x00100000)) { - /* wtf, appears to only disable post-divider on nva0 */ - if (nv_device(priv)->chipset != 0xa0) - return clk->read(clk, nv_clk_src_dom6); - } - - N2 = (coef & 0xff000000) >> 24; - M2 = (coef & 0x00ff0000) >> 16; - N1 = (coef & 0x0000ff00) >> 8; - M1 = (coef & 0x000000ff); - if ((ctrl & 0x80000000) && M1) { - freq = ref * N1 / M1; - if ((ctrl & 0x40000100) == 0x40000000) { - if (M2) - freq = freq * N2 / M2; - else - freq = 0; - } - } - - return freq; -} - -static int -nv50_clock_read(struct nouveau_clock *clk, enum nv_clk_src src) -{ - struct nv50_clock_priv *priv = (void *)clk; - u32 mast = nv_rd32(priv, 0x00c040); - u32 P = 0; - - switch (src) { - case nv_clk_src_crystal: - return nv_device(priv)->crystal; - case nv_clk_src_href: - return 100000; /* PCIE reference clock */ - case nv_clk_src_hclk: - return div_u64((u64)clk->read(clk, nv_clk_src_href) * 27778, 10000); - case nv_clk_src_hclkm3: - return clk->read(clk, nv_clk_src_hclk) * 3; - case nv_clk_src_hclkm3d2: - return clk->read(clk, nv_clk_src_hclk) * 3 / 2; - case nv_clk_src_host: - switch (mast & 0x30000000) { - case 0x00000000: return clk->read(clk, nv_clk_src_href); - case 0x10000000: break; - case 0x20000000: /* !0x50 */ - case 0x30000000: return clk->read(clk, nv_clk_src_hclk); - } - break; - case nv_clk_src_core: - if (!(mast & 0x00100000)) - P = (nv_rd32(priv, 0x004028) & 0x00070000) >> 16; - switch (mast & 0x00000003) { - case 0x00000000: return clk->read(clk, nv_clk_src_crystal) >> P; - case 0x00000001: return clk->read(clk, nv_clk_src_dom6); - case 0x00000002: return read_pll(priv, 0x004020) >> P; - case 0x00000003: return read_pll(priv, 0x004028) >> P; - } - break; - case nv_clk_src_shader: - P = (nv_rd32(priv, 0x004020) & 0x00070000) >> 16; - switch (mast & 0x00000030) { - case 0x00000000: - if (mast & 0x00000080) - return clk->read(clk, nv_clk_src_host) >> P; - return clk->read(clk, nv_clk_src_crystal) >> P; - case 0x00000010: break; - case 0x00000020: return read_pll(priv, 0x004028) >> P; - case 0x00000030: return read_pll(priv, 0x004020) >> P; - } - break; - case nv_clk_src_mem: - P = (nv_rd32(priv, 0x004008) & 0x00070000) >> 16; - if (nv_rd32(priv, 0x004008) & 0x00000200) { - switch (mast & 0x0000c000) { - case 0x00000000: - return clk->read(clk, nv_clk_src_crystal) >> P; - case 0x00008000: - case 0x0000c000: - return clk->read(clk, nv_clk_src_href) >> P; - } - } else { - return read_pll(priv, 0x004008) >> P; - } - break; - case nv_clk_src_vdec: - P = (read_div(priv) & 0x00000700) >> 8; - switch (nv_device(priv)->chipset) { - case 0x84: - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0xa0: - switch (mast & 0x00000c00) { - case 0x00000000: - if (nv_device(priv)->chipset == 0xa0) /* wtf?? */ - return clk->read(clk, nv_clk_src_core) >> P; - return clk->read(clk, nv_clk_src_crystal) >> P; - case 0x00000400: - return 0; - case 0x00000800: - if (mast & 0x01000000) - return read_pll(priv, 0x004028) >> P; - return read_pll(priv, 0x004030) >> P; - case 0x00000c00: - return clk->read(clk, nv_clk_src_core) >> P; - } - break; - case 0x98: - switch (mast & 0x00000c00) { - case 0x00000000: - return clk->read(clk, nv_clk_src_core) >> P; - case 0x00000400: - return 0; - case 0x00000800: - return clk->read(clk, nv_clk_src_hclkm3d2) >> P; - case 0x00000c00: - return clk->read(clk, nv_clk_src_mem) >> P; - } - break; - } - break; - case nv_clk_src_dom6: - switch (nv_device(priv)->chipset) { - case 0x50: - case 0xa0: - return read_pll(priv, 0x00e810) >> 2; - case 0x84: - case 0x86: - case 0x92: - case 0x94: - case 0x96: - case 0x98: - P = (read_div(priv) & 0x00000007) >> 0; - switch (mast & 0x0c000000) { - case 0x00000000: return clk->read(clk, nv_clk_src_href); - case 0x04000000: break; - case 0x08000000: return clk->read(clk, nv_clk_src_hclk); - case 0x0c000000: - return clk->read(clk, nv_clk_src_hclkm3) >> P; - } - break; - default: - break; - } - default: - break; - } - - nv_debug(priv, "unknown clock source %d 0x%08x\n", src, mast); - return -EINVAL; -} - -static u32 -calc_pll(struct nv50_clock_priv *priv, u32 reg, u32 clk, int *N, int *M, int *P) -{ - struct nouveau_bios *bios = nouveau_bios(priv); - struct nvbios_pll pll; - int ret; - - ret = nvbios_pll_parse(bios, reg, &pll); - if (ret) - return 0; - - pll.vco2.max_freq = 0; - pll.refclk = read_pll_ref(priv, reg); - if (!pll.refclk) - return 0; - - return nv04_pll_calc(nv_subdev(priv), &pll, clk, N, M, NULL, NULL, P); -} - -static inline u32 -calc_div(u32 src, u32 target, int *div) -{ - u32 clk0 = src, clk1 = src; - for (*div = 0; *div <= 7; (*div)++) { - if (clk0 <= target) { - clk1 = clk0 << (*div ? 1 : 0); - break; - } - clk0 >>= 1; - } - - if (target - clk0 <= clk1 - target) - return clk0; - (*div)--; - return clk1; -} - -static inline u32 -clk_same(u32 a, u32 b) -{ - return ((a / 1000) == (b / 1000)); -} - -static int -nv50_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate) -{ - struct nv50_clock_priv *priv = (void *)clk; - struct nv50_clock_hwsq *hwsq = &priv->hwsq; - const int shader = cstate->domain[nv_clk_src_shader]; - const int core = cstate->domain[nv_clk_src_core]; - const int vdec = cstate->domain[nv_clk_src_vdec]; - const int dom6 = cstate->domain[nv_clk_src_dom6]; - u32 mastm = 0, mastv = 0; - u32 divsm = 0, divsv = 0; - int N, M, P1, P2; - int freq, out; - - /* prepare a hwsq script from which we'll perform the reclock */ - out = clk_init(hwsq, nv_subdev(clk)); - if (out) - return out; - - clk_wr32(hwsq, fifo, 0x00000001); /* block fifo */ - clk_nsec(hwsq, 8000); - clk_setf(hwsq, 0x10, 0x00); /* disable fb */ - clk_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */ - - /* vdec: avoid modifying xpll until we know exactly how the other - * clock domains work, i suspect at least some of them can also be - * tied to xpll... - */ - if (vdec) { - /* see how close we can get using nvclk as a source */ - freq = calc_div(core, vdec, &P1); - - /* see how close we can get using xpll/hclk as a source */ - if (nv_device(priv)->chipset != 0x98) - out = read_pll(priv, 0x004030); - else - out = clk->read(clk, nv_clk_src_hclkm3d2); - out = calc_div(out, vdec, &P2); - - /* select whichever gets us closest */ - if (abs(vdec - freq) <= abs(vdec - out)) { - if (nv_device(priv)->chipset != 0x98) - mastv |= 0x00000c00; - divsv |= P1 << 8; - } else { - mastv |= 0x00000800; - divsv |= P2 << 8; - } - - mastm |= 0x00000c00; - divsm |= 0x00000700; - } - - /* dom6: nfi what this is, but we're limited to various combinations - * of the host clock frequency - */ - if (dom6) { - if (clk_same(dom6, clk->read(clk, nv_clk_src_href))) { - mastv |= 0x00000000; - } else - if (clk_same(dom6, clk->read(clk, nv_clk_src_hclk))) { - mastv |= 0x08000000; - } else { - freq = clk->read(clk, nv_clk_src_hclk) * 3; - freq = calc_div(freq, dom6, &P1); - - mastv |= 0x0c000000; - divsv |= P1; - } - - mastm |= 0x0c000000; - divsm |= 0x00000007; - } - - /* vdec/dom6: switch to "safe" clocks temporarily, update dividers - * and then switch to target clocks - */ - clk_mask(hwsq, mast, mastm, 0x00000000); - clk_mask(hwsq, divs, divsm, divsv); - clk_mask(hwsq, mast, mastm, mastv); - - /* core/shader: disconnect nvclk/sclk from their PLLs (nvclk to dom6, - * sclk to hclk) before reprogramming - */ - if (nv_device(priv)->chipset < 0x92) - clk_mask(hwsq, mast, 0x001000b0, 0x00100080); - else - clk_mask(hwsq, mast, 0x000000b3, 0x00000081); - - /* core: for the moment at least, always use nvpll */ - freq = calc_pll(priv, 0x4028, core, &N, &M, &P1); - if (freq == 0) - return -ERANGE; - - clk_mask(hwsq, nvpll[0], 0xc03f0100, - 0x80000000 | (P1 << 19) | (P1 << 16)); - clk_mask(hwsq, nvpll[1], 0x0000ffff, (N << 8) | M); - - /* shader: tie to nvclk if possible, otherwise use spll. have to be - * very careful that the shader clock is at least twice the core, or - * some chipsets will be very unhappy. i expect most or all of these - * cases will be handled by tying to nvclk, but it's possible there's - * corners - */ - if (P1-- && shader == (core << 1)) { - clk_mask(hwsq, spll[0], 0xc03f0100, (P1 << 19) | (P1 << 16)); - clk_mask(hwsq, mast, 0x00100033, 0x00000023); - } else { - freq = calc_pll(priv, 0x4020, shader, &N, &M, &P1); - if (freq == 0) - return -ERANGE; - - clk_mask(hwsq, spll[0], 0xc03f0100, - 0x80000000 | (P1 << 19) | (P1 << 16)); - clk_mask(hwsq, spll[1], 0x0000ffff, (N << 8) | M); - clk_mask(hwsq, mast, 0x00100033, 0x00000033); - } - - /* restore normal operation */ - clk_setf(hwsq, 0x10, 0x01); /* enable fb */ - clk_wait(hwsq, 0x00, 0x00); /* wait for fb enabled */ - clk_wr32(hwsq, fifo, 0x00000000); /* un-block fifo */ - return 0; -} +struct nv50_clock_priv { + struct nouveau_clock base; +}; static int -nv50_clock_prog(struct nouveau_clock *clk) -{ - struct nv50_clock_priv *priv = (void *)clk; - return clk_exec(&priv->hwsq, true); -} - -static void -nv50_clock_tidy(struct nouveau_clock *clk) -{ - struct nv50_clock_priv *priv = (void *)clk; - clk_exec(&priv->hwsq, false); -} - -int nv50_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv50_clock_oclass *pclass = (void *)oclass; struct nv50_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, pclass->domains, - &priv); + ret = nouveau_clock_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; - priv->hwsq.r_fifo = hwsq_reg(0x002504); - priv->hwsq.r_spll[0] = hwsq_reg(0x004020); - priv->hwsq.r_spll[1] = hwsq_reg(0x004024); - priv->hwsq.r_nvpll[0] = hwsq_reg(0x004028); - priv->hwsq.r_nvpll[1] = hwsq_reg(0x00402c); - switch (nv_device(priv)->chipset) { - case 0x92: - case 0x94: - case 0x96: - priv->hwsq.r_divs = hwsq_reg(0x004800); - break; - default: - priv->hwsq.r_divs = hwsq_reg(0x004700); - break; - } - priv->hwsq.r_mast = hwsq_reg(0x00c040); - - priv->base.read = nv50_clock_read; - priv->base.calc = nv50_clock_calc; - priv->base.prog = nv50_clock_prog; - priv->base.tidy = nv50_clock_tidy; + priv->base.pll_calc = nv04_clock_pll_calc; return 0; } -static struct nouveau_clocks -nv50_domains[] = { - { nv_clk_src_crystal, 0xff }, - { nv_clk_src_href , 0xff }, - { nv_clk_src_core , 0xff, 0, "core", 1000 }, - { nv_clk_src_shader , 0xff, 0, "shader", 1000 }, - { nv_clk_src_mem , 0xff, 0, "memory", 1000 }, - { nv_clk_src_max } -}; - -struct nouveau_oclass * -nv50_clock_oclass = &(struct nv50_clock_oclass) { - .base.handle = NV_SUBDEV(CLOCK, 0x50), - .base.ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass +nv50_clock_oclass = { + .handle = NV_SUBDEV(CLOCK, 0x50), + .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_clock_ctor, .dtor = _nouveau_clock_dtor, .init = _nouveau_clock_init, .fini = _nouveau_clock_fini, }, - .domains = nv50_domains, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h deleted file mode 100644 index f10917d..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv50.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef __NVKM_CLK_NV50_H__ -#define __NVKM_CLK_NV50_H__ - -#include <subdev/bus.h> -#include <subdev/bus/hwsq.h> -#include <subdev/clock.h> - -struct nv50_clock_hwsq { - struct hwsq base; - struct hwsq_reg r_fifo; - struct hwsq_reg r_spll[2]; - struct hwsq_reg r_nvpll[2]; - struct hwsq_reg r_divs; - struct hwsq_reg r_mast; -}; - -struct nv50_clock_priv { - struct nouveau_clock base; - struct nv50_clock_hwsq hwsq; -}; - -int nv50_clock_ctor(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, void *, u32, - struct nouveau_object **); - -struct nv50_clock_oclass { - struct nouveau_oclass base; - struct nouveau_clocks *domains; -}; - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c deleted file mode 100644 index b0b7c14..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nv84.c +++ /dev/null @@ -1,48 +0,0 @@ -/* - * 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 "nv50.h" - -static struct nouveau_clocks -nv84_domains[] = { - { nv_clk_src_crystal, 0xff }, - { nv_clk_src_href , 0xff }, - { nv_clk_src_core , 0xff, 0, "core", 1000 }, - { nv_clk_src_shader , 0xff, 0, "shader", 1000 }, - { nv_clk_src_mem , 0xff, 0, "memory", 1000 }, - { nv_clk_src_vdec , 0xff }, - { nv_clk_src_max } -}; - -struct nouveau_oclass * -nv84_clock_oclass = &(struct nv50_clock_oclass) { - .base.handle = NV_SUBDEV(CLOCK, 0x84), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_clock_ctor, - .dtor = _nouveau_clock_dtor, - .init = _nouveau_clock_init, - .fini = _nouveau_clock_fini, - }, - .domains = nv84_domains, -}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c index 4f5a137..f074cd2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c @@ -22,277 +22,33 @@ * Authors: Ben Skeggs */ +#include <subdev/clock.h> #include <subdev/bios.h> #include <subdev/bios/pll.h> -#include <subdev/timer.h> #include "pll.h" -#include "nva3.h" - struct nva3_clock_priv { struct nouveau_clock base; - struct nva3_clock_info eng[nv_clk_src_max]; }; -static u32 read_clk(struct nva3_clock_priv *, int, bool); -static u32 read_pll(struct nva3_clock_priv *, int, u32); - -static u32 -read_vco(struct nva3_clock_priv *priv, int clk) -{ - u32 sctl = nv_rd32(priv, 0x4120 + (clk * 4)); - if ((sctl & 0x00000030) != 0x00000030) - return read_pll(priv, 0x41, 0x00e820); - return read_pll(priv, 0x42, 0x00e8a0); -} - -static u32 -read_clk(struct nva3_clock_priv *priv, int clk, bool ignore_en) -{ - u32 sctl, sdiv, sclk; - - /* refclk for the 0xe8xx plls is a fixed frequency */ - if (clk >= 0x40) { - if (nv_device(priv)->chipset == 0xaf) { - /* no joke.. seriously.. sigh.. */ - return nv_rd32(priv, 0x00471c) * 1000; - } - - return nv_device(priv)->crystal; - } - - sctl = nv_rd32(priv, 0x4120 + (clk * 4)); - if (!ignore_en && !(sctl & 0x00000100)) - return 0; - - switch (sctl & 0x00003000) { - case 0x00000000: - return nv_device(priv)->crystal; - case 0x00002000: - if (sctl & 0x00000040) - return 108000; - return 100000; - case 0x00003000: - sclk = read_vco(priv, clk); - sdiv = ((sctl & 0x003f0000) >> 16) + 2; - return (sclk * 2) / sdiv; - default: - return 0; - } -} - -static u32 -read_pll(struct nva3_clock_priv *priv, int clk, u32 pll) -{ - u32 ctrl = nv_rd32(priv, pll + 0); - u32 sclk = 0, P = 1, N = 1, M = 1; - - if (!(ctrl & 0x00000008)) { - if (ctrl & 0x00000001) { - u32 coef = nv_rd32(priv, pll + 4); - M = (coef & 0x000000ff) >> 0; - N = (coef & 0x0000ff00) >> 8; - P = (coef & 0x003f0000) >> 16; - - /* no post-divider on these.. */ - if ((pll & 0x00ff00) == 0x00e800) - P = 1; - - sclk = read_clk(priv, 0x00 + clk, false); - } - } else { - sclk = read_clk(priv, 0x10 + clk, false); - } - - if (M * P) - return sclk * N / (M * P); - return 0; -} - -static int -nva3_clock_read(struct nouveau_clock *clk, enum nv_clk_src src) -{ - struct nva3_clock_priv *priv = (void *)clk; - - switch (src) { - case nv_clk_src_crystal: - return nv_device(priv)->crystal; - case nv_clk_src_href: - return 100000; - case nv_clk_src_core: - return read_pll(priv, 0x00, 0x4200); - case nv_clk_src_shader: - return read_pll(priv, 0x01, 0x4220); - case nv_clk_src_mem: - return read_pll(priv, 0x02, 0x4000); - case nv_clk_src_disp: - return read_clk(priv, 0x20, false); - case nv_clk_src_vdec: - return read_clk(priv, 0x21, false); - case nv_clk_src_daemon: - return read_clk(priv, 0x25, false); - default: - nv_error(clk, "invalid clock source %d\n", src); - return -EINVAL; - } -} - int -nva3_clock_info(struct nouveau_clock *clock, int clk, u32 pll, u32 khz, - struct nva3_clock_info *info) +nva3_clock_pll_calc(struct nouveau_clock *clock, struct nvbios_pll *info, + int clk, struct nouveau_pll_vals *pv) { - struct nouveau_bios *bios = nouveau_bios(clock); - struct nva3_clock_priv *priv = (void *)clock; - struct nvbios_pll limits; - u32 oclk, sclk, sdiv; - int P, N, M, diff; - int ret; - - info->pll = 0; - info->clk = 0; - - switch (khz) { - case 27000: - info->clk = 0x00000100; - return khz; - case 100000: - info->clk = 0x00002100; - return khz; - case 108000: - info->clk = 0x00002140; - return khz; - default: - sclk = read_vco(priv, clk); - sdiv = min((sclk * 2) / (khz - 2999), (u32)65); - /* if the clock has a PLL attached, and we can get a within - * [-2, 3) MHz of a divider, we'll disable the PLL and use - * the divider instead. - * - * divider can go as low as 2, limited here because NVIDIA - * and the VBIOS on my NVA8 seem to prefer using the PLL - * for 810MHz - is there a good reason? - */ - if (sdiv > 4) { - oclk = (sclk * 2) / sdiv; - diff = khz - oclk; - if (!pll || (diff >= -2000 && diff < 3000)) { - info->clk = (((sdiv - 2) << 16) | 0x00003100); - return oclk; - } - } - - if (!pll) - return -ERANGE; - break; - } + int ret, N, M, P; - ret = nvbios_pll_parse(bios, pll, &limits); - if (ret) - return ret; - - limits.refclk = read_clk(priv, clk - 0x10, true); - if (!limits.refclk) - return -EINVAL; + ret = nva3_pll_calc(nv_subdev(clock), info, clk, &N, NULL, &M, &P); - ret = nva3_pll_calc(nv_subdev(priv), &limits, khz, &N, NULL, &M, &P); - if (ret >= 0) { - info->clk = nv_rd32(priv, 0x4120 + (clk * 4)); - info->pll = (P << 16) | (N << 8) | M; + if (ret > 0) { + pv->refclk = info->refclk; + pv->N1 = N; + pv->M1 = M; + pv->log2P = P; } - - return ret ? ret : -ERANGE; -} - -static int -calc_clk(struct nva3_clock_priv *priv, struct nouveau_cstate *cstate, - int clk, u32 pll, int idx) -{ - int ret = nva3_clock_info(&priv->base, clk, pll, cstate->domain[idx], - &priv->eng[idx]); - if (ret >= 0) - return 0; return ret; } -static void -prog_pll(struct nva3_clock_priv *priv, int clk, u32 pll, int idx) -{ - struct nva3_clock_info *info = &priv->eng[idx]; - const u32 src0 = 0x004120 + (clk * 4); - const u32 src1 = 0x004160 + (clk * 4); - const u32 ctrl = pll + 0; - const u32 coef = pll + 4; - - if (info->pll) { - nv_mask(priv, src0, 0x00000101, 0x00000101); - nv_wr32(priv, coef, info->pll); - nv_mask(priv, ctrl, 0x00000015, 0x00000015); - nv_mask(priv, ctrl, 0x00000010, 0x00000000); - nv_wait(priv, ctrl, 0x00020000, 0x00020000); - nv_mask(priv, ctrl, 0x00000010, 0x00000010); - nv_mask(priv, ctrl, 0x00000008, 0x00000000); - nv_mask(priv, src1, 0x00000100, 0x00000000); - nv_mask(priv, src1, 0x00000001, 0x00000000); - } else { - nv_mask(priv, src1, 0x003f3141, 0x00000101 | info->clk); - nv_mask(priv, ctrl, 0x00000018, 0x00000018); - udelay(20); - nv_mask(priv, ctrl, 0x00000001, 0x00000000); - nv_mask(priv, src0, 0x00000100, 0x00000000); - nv_mask(priv, src0, 0x00000001, 0x00000000); - } -} - -static void -prog_clk(struct nva3_clock_priv *priv, int clk, int idx) -{ - struct nva3_clock_info *info = &priv->eng[idx]; - nv_mask(priv, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | info->clk); -} - -static int -nva3_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate) -{ - struct nva3_clock_priv *priv = (void *)clk; - int ret; - - if ((ret = calc_clk(priv, cstate, 0x10, 0x4200, nv_clk_src_core)) || - (ret = calc_clk(priv, cstate, 0x11, 0x4220, nv_clk_src_shader)) || - (ret = calc_clk(priv, cstate, 0x20, 0x0000, nv_clk_src_disp)) || - (ret = calc_clk(priv, cstate, 0x21, 0x0000, nv_clk_src_vdec))) - return ret; - - return 0; -} - -static int -nva3_clock_prog(struct nouveau_clock *clk) -{ - struct nva3_clock_priv *priv = (void *)clk; - prog_pll(priv, 0x00, 0x004200, nv_clk_src_core); - prog_pll(priv, 0x01, 0x004220, nv_clk_src_shader); - prog_clk(priv, 0x20, nv_clk_src_disp); - prog_clk(priv, 0x21, nv_clk_src_vdec); - return 0; -} - -static void -nva3_clock_tidy(struct nouveau_clock *clk) -{ -} - -static struct nouveau_clocks -nva3_domain[] = { - { nv_clk_src_crystal, 0xff }, - { nv_clk_src_href , 0xff }, - { nv_clk_src_core , 0x00, 0, "core", 1000 }, - { nv_clk_src_shader , 0x01, 0, "shader", 1000 }, - { nv_clk_src_mem , 0x02, 0, "memory", 1000 }, - { nv_clk_src_vdec , 0x03 }, - { nv_clk_src_disp , 0x04 }, - { nv_clk_src_max } -}; static int nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, @@ -302,15 +58,12 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nva3_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; - priv->base.read = nva3_clock_read; - priv->base.calc = nva3_clock_calc; - priv->base.prog = nva3_clock_prog; - priv->base.tidy = nva3_clock_tidy; + priv->base.pll_calc = nva3_clock_pll_calc; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h deleted file mode 100644 index 6229a50..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef __NVKM_CLK_NVA3_H__ -#define __NVKM_CLK_NVA3_H__ - -#include <subdev/clock.h> - -struct nva3_clock_info { - u32 clk; - u32 pll; -}; - -int nva3_clock_info(struct nouveau_clock *, int, u32, u32, - struct nva3_clock_info *); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c deleted file mode 100644 index 7a723b4..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvaa.c +++ /dev/null @@ -1,445 +0,0 @@ -/* - * 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 <engine/fifo.h> -#include <subdev/bios.h> -#include <subdev/bios/pll.h> -#include <subdev/timer.h> -#include <subdev/clock.h> - -#include "pll.h" - -struct nvaa_clock_priv { - struct nouveau_clock base; - enum nv_clk_src csrc, ssrc, vsrc; - u32 cctrl, sctrl; - u32 ccoef, scoef; - u32 cpost, spost; - u32 vdiv; -}; - -static u32 -read_div(struct nouveau_clock *clk) -{ - return nv_rd32(clk, 0x004600); -} - -static u32 -read_pll(struct nouveau_clock *clk, u32 base) -{ - u32 ctrl = nv_rd32(clk, base + 0); - u32 coef = nv_rd32(clk, base + 4); - u32 ref = clk->read(clk, nv_clk_src_href); - u32 post_div = 0; - u32 clock = 0; - int N1, M1; - - switch (base){ - case 0x4020: - post_div = 1 << ((nv_rd32(clk, 0x4070) & 0x000f0000) >> 16); - break; - case 0x4028: - post_div = (nv_rd32(clk, 0x4040) & 0x000f0000) >> 16; - break; - default: - break; - } - - N1 = (coef & 0x0000ff00) >> 8; - M1 = (coef & 0x000000ff); - if ((ctrl & 0x80000000) && M1) { - clock = ref * N1 / M1; - clock = clock / post_div; - } - - return clock; -} - -static int -nvaa_clock_read(struct nouveau_clock *clk, enum nv_clk_src src) -{ - struct nvaa_clock_priv *priv = (void *)clk; - u32 mast = nv_rd32(clk, 0x00c054); - u32 P = 0; - - switch (src) { - case nv_clk_src_crystal: - return nv_device(priv)->crystal; - case nv_clk_src_href: - return 100000; /* PCIE reference clock */ - case nv_clk_src_hclkm4: - return clk->read(clk, nv_clk_src_href) * 4; - case nv_clk_src_hclkm2d3: - return clk->read(clk, nv_clk_src_href) * 2 / 3; - case nv_clk_src_host: - switch (mast & 0x000c0000) { - case 0x00000000: return clk->read(clk, nv_clk_src_hclkm2d3); - case 0x00040000: break; - case 0x00080000: return clk->read(clk, nv_clk_src_hclkm4); - case 0x000c0000: return clk->read(clk, nv_clk_src_cclk); - } - break; - case nv_clk_src_core: - P = (nv_rd32(clk, 0x004028) & 0x00070000) >> 16; - - switch (mast & 0x00000003) { - case 0x00000000: return clk->read(clk, nv_clk_src_crystal) >> P; - case 0x00000001: return 0; - case 0x00000002: return clk->read(clk, nv_clk_src_hclkm4) >> P; - case 0x00000003: return read_pll(clk, 0x004028) >> P; - } - break; - case nv_clk_src_cclk: - if ((mast & 0x03000000) != 0x03000000) - return clk->read(clk, nv_clk_src_core); - - if ((mast & 0x00000200) == 0x00000000) - return clk->read(clk, nv_clk_src_core); - - switch (mast & 0x00000c00) { - case 0x00000000: return clk->read(clk, nv_clk_src_href); - case 0x00000400: return clk->read(clk, nv_clk_src_hclkm4); - case 0x00000800: return clk->read(clk, nv_clk_src_hclkm2d3); - default: return 0; - } - case nv_clk_src_shader: - P = (nv_rd32(clk, 0x004020) & 0x00070000) >> 16; - switch (mast & 0x00000030) { - case 0x00000000: - if (mast & 0x00000040) - return clk->read(clk, nv_clk_src_href) >> P; - return clk->read(clk, nv_clk_src_crystal) >> P; - case 0x00000010: break; - case 0x00000020: return read_pll(clk, 0x004028) >> P; - case 0x00000030: return read_pll(clk, 0x004020) >> P; - } - break; - case nv_clk_src_mem: - return 0; - break; - case nv_clk_src_vdec: - P = (read_div(clk) & 0x00000700) >> 8; - - switch (mast & 0x00400000) { - case 0x00400000: - return clk->read(clk, nv_clk_src_core) >> P; - break; - default: - return 500000 >> P; - break; - } - break; - default: - break; - } - - nv_debug(priv, "unknown clock source %d 0x%08x\n", src, mast); - return 0; -} - -static u32 -calc_pll(struct nvaa_clock_priv *priv, u32 reg, - u32 clock, int *N, int *M, int *P) -{ - struct nouveau_bios *bios = nouveau_bios(priv); - struct nvbios_pll pll; - struct nouveau_clock *clk = &priv->base; - int ret; - - ret = nvbios_pll_parse(bios, reg, &pll); - if (ret) - return 0; - - pll.vco2.max_freq = 0; - pll.refclk = clk->read(clk, nv_clk_src_href); - if (!pll.refclk) - return 0; - - return nv04_pll_calc(nv_subdev(priv), &pll, clock, N, M, NULL, NULL, P); -} - -static inline u32 -calc_P(u32 src, u32 target, int *div) -{ - u32 clk0 = src, clk1 = src; - for (*div = 0; *div <= 7; (*div)++) { - if (clk0 <= target) { - clk1 = clk0 << (*div ? 1 : 0); - break; - } - clk0 >>= 1; - } - - if (target - clk0 <= clk1 - target) - return clk0; - (*div)--; - return clk1; -} - -static int -nvaa_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate) -{ - struct nvaa_clock_priv *priv = (void *)clk; - const int shader = cstate->domain[nv_clk_src_shader]; - const int core = cstate->domain[nv_clk_src_core]; - const int vdec = cstate->domain[nv_clk_src_vdec]; - u32 out = 0, clock = 0; - int N, M, P1, P2 = 0; - int divs = 0; - - /* cclk: find suitable source, disable PLL if we can */ - if (core < clk->read(clk, nv_clk_src_hclkm4)) - out = calc_P(clk->read(clk, nv_clk_src_hclkm4), core, &divs); - - /* Calculate clock * 2, so shader clock can use it too */ - clock = calc_pll(priv, 0x4028, (core << 1), &N, &M, &P1); - - if (abs(core - out) <= - abs(core - (clock >> 1))) { - priv->csrc = nv_clk_src_hclkm4; - priv->cctrl = divs << 16; - } else { - /* NVCTRL is actually used _after_ NVPOST, and after what we - * call NVPLL. To make matters worse, NVPOST is an integer - * divider instead of a right-shift number. */ - if(P1 > 2) { - P2 = P1 - 2; - P1 = 2; - } - - priv->csrc = nv_clk_src_core; - priv->ccoef = (N << 8) | M; - - priv->cctrl = (P2 + 1) << 16; - priv->cpost = (1 << P1) << 16; - } - - /* sclk: nvpll + divisor, href or spll */ - out = 0; - if (shader == clk->read(clk, nv_clk_src_href)) { - priv->ssrc = nv_clk_src_href; - } else { - clock = calc_pll(priv, 0x4020, shader, &N, &M, &P1); - if (priv->csrc == nv_clk_src_core) { - out = calc_P((core << 1), shader, &divs); - } - - if (abs(shader - out) <= - abs(shader - clock) && - (divs + P2) <= 7) { - priv->ssrc = nv_clk_src_core; - priv->sctrl = (divs + P2) << 16; - } else { - priv->ssrc = nv_clk_src_shader; - priv->scoef = (N << 8) | M; - priv->sctrl = P1 << 16; - } - } - - /* vclk */ - out = calc_P(core, vdec, &divs); - clock = calc_P(500000, vdec, &P1); - if(abs(vdec - out) <= - abs(vdec - clock)) { - priv->vsrc = nv_clk_src_cclk; - priv->vdiv = divs << 16; - } else { - priv->vsrc = nv_clk_src_vdec; - priv->vdiv = P1 << 16; - } - - /* Print strategy! */ - nv_debug(priv, "nvpll: %08x %08x %08x\n", - priv->ccoef, priv->cpost, priv->cctrl); - nv_debug(priv, " spll: %08x %08x %08x\n", - priv->scoef, priv->spost, priv->sctrl); - nv_debug(priv, " vdiv: %08x\n", priv->vdiv); - if (priv->csrc == nv_clk_src_hclkm4) - nv_debug(priv, "core: hrefm4\n"); - else - nv_debug(priv, "core: nvpll\n"); - - if (priv->ssrc == nv_clk_src_hclkm4) - nv_debug(priv, "shader: hrefm4\n"); - else if (priv->ssrc == nv_clk_src_core) - nv_debug(priv, "shader: nvpll\n"); - else - nv_debug(priv, "shader: spll\n"); - - if (priv->vsrc == nv_clk_src_hclkm4) - nv_debug(priv, "vdec: 500MHz\n"); - else - nv_debug(priv, "vdec: core\n"); - - return 0; -} - -static int -nvaa_clock_prog(struct nouveau_clock *clk) -{ - struct nvaa_clock_priv *priv = (void *)clk; - struct nouveau_fifo *pfifo = nouveau_fifo(clk); - unsigned long flags; - u32 pllmask = 0, mast, ptherm_gate; - int ret = -EBUSY; - - /* halt and idle execution engines */ - ptherm_gate = nv_mask(clk, 0x020060, 0x00070000, 0x00000000); - nv_mask(clk, 0x002504, 0x00000001, 0x00000001); - /* Wait until the interrupt handler is finished */ - if (!nv_wait(clk, 0x000100, 0xffffffff, 0x00000000)) - goto resume; - - if (pfifo) - pfifo->pause(pfifo, &flags); - - if (!nv_wait(clk, 0x002504, 0x00000010, 0x00000010)) - goto resume; - if (!nv_wait(clk, 0x00251c, 0x0000003f, 0x0000003f)) - goto resume; - - /* First switch to safe clocks: href */ - mast = nv_mask(clk, 0xc054, 0x03400e70, 0x03400640); - mast &= ~0x00400e73; - mast |= 0x03000000; - - switch (priv->csrc) { - case nv_clk_src_hclkm4: - nv_mask(clk, 0x4028, 0x00070000, priv->cctrl); - mast |= 0x00000002; - break; - case nv_clk_src_core: - nv_wr32(clk, 0x402c, priv->ccoef); - nv_wr32(clk, 0x4028, 0x80000000 | priv->cctrl); - nv_wr32(clk, 0x4040, priv->cpost); - pllmask |= (0x3 << 8); - mast |= 0x00000003; - break; - default: - nv_warn(priv,"Reclocking failed: unknown core clock\n"); - goto resume; - } - - switch (priv->ssrc) { - case nv_clk_src_href: - nv_mask(clk, 0x4020, 0x00070000, 0x00000000); - /* mast |= 0x00000000; */ - break; - case nv_clk_src_core: - nv_mask(clk, 0x4020, 0x00070000, priv->sctrl); - mast |= 0x00000020; - break; - case nv_clk_src_shader: - nv_wr32(clk, 0x4024, priv->scoef); - nv_wr32(clk, 0x4020, 0x80000000 | priv->sctrl); - nv_wr32(clk, 0x4070, priv->spost); - pllmask |= (0x3 << 12); - mast |= 0x00000030; - break; - default: - nv_warn(priv,"Reclocking failed: unknown sclk clock\n"); - goto resume; - } - - if (!nv_wait(clk, 0x004080, pllmask, pllmask)) { - nv_warn(priv,"Reclocking failed: unstable PLLs\n"); - goto resume; - } - - switch (priv->vsrc) { - case nv_clk_src_cclk: - mast |= 0x00400000; - default: - nv_wr32(clk, 0x4600, priv->vdiv); - } - - nv_wr32(clk, 0xc054, mast); - ret = 0; - -resume: - if (pfifo) - pfifo->start(pfifo, &flags); - - nv_mask(clk, 0x002504, 0x00000001, 0x00000000); - nv_wr32(clk, 0x020060, ptherm_gate); - - /* Disable some PLLs and dividers when unused */ - if (priv->csrc != nv_clk_src_core) { - nv_wr32(clk, 0x4040, 0x00000000); - nv_mask(clk, 0x4028, 0x80000000, 0x00000000); - } - - if (priv->ssrc != nv_clk_src_shader) { - nv_wr32(clk, 0x4070, 0x00000000); - nv_mask(clk, 0x4020, 0x80000000, 0x00000000); - } - - return ret; -} - -static void -nvaa_clock_tidy(struct nouveau_clock *clk) -{ -} - -static struct nouveau_clocks -nvaa_domains[] = { - { nv_clk_src_crystal, 0xff }, - { nv_clk_src_href , 0xff }, - { nv_clk_src_core , 0xff, 0, "core", 1000 }, - { nv_clk_src_shader , 0xff, 0, "shader", 1000 }, - { nv_clk_src_vdec , 0xff, 0, "vdec", 1000 }, - { nv_clk_src_max } -}; - -static int -nvaa_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nvaa_clock_priv *priv; - int ret; - - ret = nouveau_clock_create(parent, engine, oclass, nvaa_domains, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.read = nvaa_clock_read; - priv->base.calc = nvaa_clock_calc; - priv->base.prog = nvaa_clock_prog; - priv->base.tidy = nvaa_clock_tidy; - return 0; -} - -struct nouveau_oclass * -nvaa_clock_oclass = &(struct nouveau_oclass) { - .handle = NV_SUBDEV(CLOCK, 0xaa), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvaa_clock_ctor, - .dtor = _nouveau_clock_dtor, - .init = _nouveau_clock_init, - .fini = _nouveau_clock_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c index c310572..439d81c2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nvc0.c @@ -25,408 +25,11 @@ #include <subdev/clock.h> #include <subdev/bios.h> #include <subdev/bios/pll.h> -#include <subdev/timer.h> #include "pll.h" -struct nvc0_clock_info { - u32 freq; - u32 ssel; - u32 mdiv; - u32 dsrc; - u32 ddiv; - u32 coef; -}; - struct nvc0_clock_priv { struct nouveau_clock base; - struct nvc0_clock_info eng[16]; -}; - -static u32 read_div(struct nvc0_clock_priv *, int, u32, u32); - -static u32 -read_vco(struct nvc0_clock_priv *priv, u32 dsrc) -{ - struct nouveau_clock *clk = &priv->base; - u32 ssrc = nv_rd32(priv, dsrc); - if (!(ssrc & 0x00000100)) - return clk->read(clk, nv_clk_src_sppll0); - return clk->read(clk, nv_clk_src_sppll1); -} - -static u32 -read_pll(struct nvc0_clock_priv *priv, u32 pll) -{ - struct nouveau_clock *clk = &priv->base; - u32 ctrl = nv_rd32(priv, pll + 0x00); - u32 coef = nv_rd32(priv, pll + 0x04); - u32 P = (coef & 0x003f0000) >> 16; - u32 N = (coef & 0x0000ff00) >> 8; - u32 M = (coef & 0x000000ff) >> 0; - u32 sclk; - - if (!(ctrl & 0x00000001)) - return 0; - - switch (pll) { - case 0x00e800: - case 0x00e820: - sclk = nv_device(priv)->crystal; - P = 1; - break; - case 0x132000: - sclk = clk->read(clk, nv_clk_src_mpllsrc); - break; - case 0x132020: - sclk = clk->read(clk, nv_clk_src_mpllsrcref); - break; - case 0x137000: - case 0x137020: - case 0x137040: - case 0x1370e0: - sclk = read_div(priv, (pll & 0xff) / 0x20, 0x137120, 0x137140); - break; - default: - return 0; - } - - return sclk * N / M / P; -} - -static u32 -read_div(struct nvc0_clock_priv *priv, int doff, u32 dsrc, u32 dctl) -{ - u32 ssrc = nv_rd32(priv, dsrc + (doff * 4)); - u32 sctl = nv_rd32(priv, dctl + (doff * 4)); - - switch (ssrc & 0x00000003) { - case 0: - if ((ssrc & 0x00030000) != 0x00030000) - return nv_device(priv)->crystal; - return 108000; - case 2: - return 100000; - case 3: - if (sctl & 0x80000000) { - u32 sclk = read_vco(priv, dsrc + (doff * 4)); - u32 sdiv = (sctl & 0x0000003f) + 2; - return (sclk * 2) / sdiv; - } - - return read_vco(priv, dsrc + (doff * 4)); - default: - return 0; - } -} - -static u32 -read_clk(struct nvc0_clock_priv *priv, int clk) -{ - u32 sctl = nv_rd32(priv, 0x137250 + (clk * 4)); - u32 ssel = nv_rd32(priv, 0x137100); - u32 sclk, sdiv; - - if (ssel & (1 << clk)) { - if (clk < 7) - sclk = read_pll(priv, 0x137000 + (clk * 0x20)); - else - sclk = read_pll(priv, 0x1370e0); - sdiv = ((sctl & 0x00003f00) >> 8) + 2; - } else { - sclk = read_div(priv, clk, 0x137160, 0x1371d0); - sdiv = ((sctl & 0x0000003f) >> 0) + 2; - } - - if (sctl & 0x80000000) - return (sclk * 2) / sdiv; - - return sclk; -} - -static int -nvc0_clock_read(struct nouveau_clock *clk, enum nv_clk_src src) -{ - struct nouveau_device *device = nv_device(clk); - struct nvc0_clock_priv *priv = (void *)clk; - - switch (src) { - case nv_clk_src_crystal: - return device->crystal; - case nv_clk_src_href: - return 100000; - case nv_clk_src_sppll0: - return read_pll(priv, 0x00e800); - case nv_clk_src_sppll1: - return read_pll(priv, 0x00e820); - - case nv_clk_src_mpllsrcref: - return read_div(priv, 0, 0x137320, 0x137330); - case nv_clk_src_mpllsrc: - return read_pll(priv, 0x132020); - case nv_clk_src_mpll: - return read_pll(priv, 0x132000); - case nv_clk_src_mdiv: - return read_div(priv, 0, 0x137300, 0x137310); - case nv_clk_src_mem: - if (nv_rd32(priv, 0x1373f0) & 0x00000002) - return clk->read(clk, nv_clk_src_mpll); - return clk->read(clk, nv_clk_src_mdiv); - - case nv_clk_src_gpc: - return read_clk(priv, 0x00); - case nv_clk_src_rop: - return read_clk(priv, 0x01); - case nv_clk_src_hubk07: - return read_clk(priv, 0x02); - case nv_clk_src_hubk06: - return read_clk(priv, 0x07); - case nv_clk_src_hubk01: - return read_clk(priv, 0x08); - case nv_clk_src_copy: - return read_clk(priv, 0x09); - case nv_clk_src_daemon: - return read_clk(priv, 0x0c); - case nv_clk_src_vdec: - return read_clk(priv, 0x0e); - default: - nv_error(clk, "invalid clock source %d\n", src); - return -EINVAL; - } -} - -static u32 -calc_div(struct nvc0_clock_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv) -{ - u32 div = min((ref * 2) / freq, (u32)65); - if (div < 2) - div = 2; - - *ddiv = div - 2; - return (ref * 2) / div; -} - -static u32 -calc_src(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv) -{ - u32 sclk; - - /* use one of the fixed frequencies if possible */ - *ddiv = 0x00000000; - switch (freq) { - case 27000: - case 108000: - *dsrc = 0x00000000; - if (freq == 108000) - *dsrc |= 0x00030000; - return freq; - case 100000: - *dsrc = 0x00000002; - return freq; - default: - *dsrc = 0x00000003; - break; - } - - /* otherwise, calculate the closest divider */ - sclk = read_vco(priv, 0x137160 + (clk * 4)); - if (clk < 7) - sclk = calc_div(priv, clk, sclk, freq, ddiv); - return sclk; -} - -static u32 -calc_pll(struct nvc0_clock_priv *priv, int clk, u32 freq, u32 *coef) -{ - struct nouveau_bios *bios = nouveau_bios(priv); - struct nvbios_pll limits; - int N, M, P, ret; - - ret = nvbios_pll_parse(bios, 0x137000 + (clk * 0x20), &limits); - if (ret) - return 0; - - limits.refclk = read_div(priv, clk, 0x137120, 0x137140); - if (!limits.refclk) - return 0; - - ret = nva3_pll_calc(nv_subdev(priv), &limits, freq, &N, NULL, &M, &P); - if (ret <= 0) - return 0; - - *coef = (P << 16) | (N << 8) | M; - return ret; -} - -static int -calc_clk(struct nvc0_clock_priv *priv, - struct nouveau_cstate *cstate, int clk, int dom) -{ - struct nvc0_clock_info *info = &priv->eng[clk]; - u32 freq = cstate->domain[dom]; - u32 src0, div0, div1D, div1P = 0; - u32 clk0, clk1 = 0; - - /* invalid clock domain */ - if (!freq) - return 0; - - /* first possible path, using only dividers */ - clk0 = calc_src(priv, clk, freq, &src0, &div0); - clk0 = calc_div(priv, clk, clk0, freq, &div1D); - - /* see if we can get any closer using PLLs */ - if (clk0 != freq && (0x00004387 & (1 << clk))) { - if (clk <= 7) - clk1 = calc_pll(priv, clk, freq, &info->coef); - else - clk1 = cstate->domain[nv_clk_src_hubk06]; - clk1 = calc_div(priv, clk, clk1, freq, &div1P); - } - - /* select the method which gets closest to target freq */ - if (abs((int)freq - clk0) <= abs((int)freq - clk1)) { - info->dsrc = src0; - if (div0) { - info->ddiv |= 0x80000000; - info->ddiv |= div0 << 8; - info->ddiv |= div0; - } - if (div1D) { - info->mdiv |= 0x80000000; - info->mdiv |= div1D; - } - info->ssel = info->coef = 0; - info->freq = clk0; - } else { - if (div1P) { - info->mdiv |= 0x80000000; - info->mdiv |= div1P << 8; - } - info->ssel = (1 << clk); - info->freq = clk1; - } - - return 0; -} - -static int -nvc0_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate) -{ - struct nvc0_clock_priv *priv = (void *)clk; - int ret; - - if ((ret = calc_clk(priv, cstate, 0x00, nv_clk_src_gpc)) || - (ret = calc_clk(priv, cstate, 0x01, nv_clk_src_rop)) || - (ret = calc_clk(priv, cstate, 0x02, nv_clk_src_hubk07)) || - (ret = calc_clk(priv, cstate, 0x07, nv_clk_src_hubk06)) || - (ret = calc_clk(priv, cstate, 0x08, nv_clk_src_hubk01)) || - (ret = calc_clk(priv, cstate, 0x09, nv_clk_src_copy)) || - (ret = calc_clk(priv, cstate, 0x0c, nv_clk_src_daemon)) || - (ret = calc_clk(priv, cstate, 0x0e, nv_clk_src_vdec))) - return ret; - - return 0; -} - -static void -nvc0_clock_prog_0(struct nvc0_clock_priv *priv, int clk) -{ - struct nvc0_clock_info *info = &priv->eng[clk]; - if (clk < 7 && !info->ssel) { - nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv); - nv_wr32(priv, 0x137160 + (clk * 0x04), info->dsrc); - } -} - -static void -nvc0_clock_prog_1(struct nvc0_clock_priv *priv, int clk) -{ - nv_mask(priv, 0x137100, (1 << clk), 0x00000000); - nv_wait(priv, 0x137100, (1 << clk), 0x00000000); -} - -static void -nvc0_clock_prog_2(struct nvc0_clock_priv *priv, int clk) -{ - struct nvc0_clock_info *info = &priv->eng[clk]; - const u32 addr = 0x137000 + (clk * 0x20); - if (clk <= 7) { - nv_mask(priv, addr + 0x00, 0x00000004, 0x00000000); - nv_mask(priv, addr + 0x00, 0x00000001, 0x00000000); - if (info->coef) { - nv_wr32(priv, addr + 0x04, info->coef); - nv_mask(priv, addr + 0x00, 0x00000001, 0x00000001); - nv_wait(priv, addr + 0x00, 0x00020000, 0x00020000); - nv_mask(priv, addr + 0x00, 0x00020004, 0x00000004); - } - } -} - -static void -nvc0_clock_prog_3(struct nvc0_clock_priv *priv, int clk) -{ - struct nvc0_clock_info *info = &priv->eng[clk]; - if (info->ssel) { - nv_mask(priv, 0x137100, (1 << clk), info->ssel); - nv_wait(priv, 0x137100, (1 << clk), info->ssel); - } -} - -static void -nvc0_clock_prog_4(struct nvc0_clock_priv *priv, int clk) -{ - struct nvc0_clock_info *info = &priv->eng[clk]; - nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv); -} - -static int -nvc0_clock_prog(struct nouveau_clock *clk) -{ - struct nvc0_clock_priv *priv = (void *)clk; - struct { - void (*exec)(struct nvc0_clock_priv *, int); - } stage[] = { - { nvc0_clock_prog_0 }, /* div programming */ - { nvc0_clock_prog_1 }, /* select div mode */ - { nvc0_clock_prog_2 }, /* (maybe) program pll */ - { nvc0_clock_prog_3 }, /* (maybe) select pll mode */ - { nvc0_clock_prog_4 }, /* final divider */ - }; - int i, j; - - for (i = 0; i < ARRAY_SIZE(stage); i++) { - for (j = 0; j < ARRAY_SIZE(priv->eng); j++) { - if (!priv->eng[j].freq) - continue; - stage[i].exec(priv, j); - } - } - - return 0; -} - -static void -nvc0_clock_tidy(struct nouveau_clock *clk) -{ - struct nvc0_clock_priv *priv = (void *)clk; - memset(priv->eng, 0x00, sizeof(priv->eng)); -} - -static struct nouveau_clocks -nvc0_domain[] = { - { nv_clk_src_crystal, 0xff }, - { nv_clk_src_href , 0xff }, - { nv_clk_src_hubk06 , 0x00 }, - { nv_clk_src_hubk01 , 0x01 }, - { nv_clk_src_copy , 0x02 }, - { nv_clk_src_gpc , 0x03, 0, "core", 2000 }, - { nv_clk_src_rop , 0x04 }, - { nv_clk_src_mem , 0x05, 0, "memory", 1000 }, - { nv_clk_src_vdec , 0x06 }, - { nv_clk_src_daemon , 0x0a }, - { nv_clk_src_hubk07 , 0x0b }, - { nv_clk_src_max } }; static int @@ -437,15 +40,12 @@ nvc0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nvc0_clock_priv *priv; int ret; - ret = nouveau_clock_create(parent, engine, oclass, nvc0_domain, &priv); + ret = nouveau_clock_create(parent, engine, oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; - priv->base.read = nvc0_clock_read; - priv->base.calc = nvc0_clock_calc; - priv->base.prog = nvc0_clock_prog; - priv->base.tidy = nvc0_clock_tidy; + priv->base.pll_calc = nva3_clock_pll_calc; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c deleted file mode 100644 index 4c62e84..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/nve0.c +++ /dev/null @@ -1,497 +0,0 @@ -/* - * 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 <subdev/clock.h> -#include <subdev/timer.h> -#include <subdev/bios.h> -#include <subdev/bios/pll.h> - -#include "pll.h" - -struct nve0_clock_info { - u32 freq; - u32 ssel; - u32 mdiv; - u32 dsrc; - u32 ddiv; - u32 coef; -}; - -struct nve0_clock_priv { - struct nouveau_clock base; - struct nve0_clock_info eng[16]; -}; - -static u32 read_div(struct nve0_clock_priv *, int, u32, u32); -static u32 read_pll(struct nve0_clock_priv *, u32); - -static u32 -read_vco(struct nve0_clock_priv *priv, u32 dsrc) -{ - u32 ssrc = nv_rd32(priv, dsrc); - if (!(ssrc & 0x00000100)) - return read_pll(priv, 0x00e800); - return read_pll(priv, 0x00e820); -} - -static u32 -read_pll(struct nve0_clock_priv *priv, u32 pll) -{ - u32 ctrl = nv_rd32(priv, pll + 0x00); - u32 coef = nv_rd32(priv, pll + 0x04); - u32 P = (coef & 0x003f0000) >> 16; - u32 N = (coef & 0x0000ff00) >> 8; - u32 M = (coef & 0x000000ff) >> 0; - u32 sclk; - u16 fN = 0xf000; - - if (!(ctrl & 0x00000001)) - return 0; - - switch (pll) { - case 0x00e800: - case 0x00e820: - sclk = nv_device(priv)->crystal; - P = 1; - break; - case 0x132000: - sclk = read_pll(priv, 0x132020); - P = (coef & 0x10000000) ? 2 : 1; - break; - case 0x132020: - sclk = read_div(priv, 0, 0x137320, 0x137330); - fN = nv_rd32(priv, pll + 0x10) >> 16; - break; - case 0x137000: - case 0x137020: - case 0x137040: - case 0x1370e0: - sclk = read_div(priv, (pll & 0xff) / 0x20, 0x137120, 0x137140); - break; - default: - return 0; - } - - if (P == 0) - P = 1; - - sclk = (sclk * N) + (((u16)(fN + 4096) * sclk) >> 13); - return sclk / (M * P); -} - -static u32 -read_div(struct nve0_clock_priv *priv, int doff, u32 dsrc, u32 dctl) -{ - u32 ssrc = nv_rd32(priv, dsrc + (doff * 4)); - u32 sctl = nv_rd32(priv, dctl + (doff * 4)); - - switch (ssrc & 0x00000003) { - case 0: - if ((ssrc & 0x00030000) != 0x00030000) - return nv_device(priv)->crystal; - return 108000; - case 2: - return 100000; - case 3: - if (sctl & 0x80000000) { - u32 sclk = read_vco(priv, dsrc + (doff * 4)); - u32 sdiv = (sctl & 0x0000003f) + 2; - return (sclk * 2) / sdiv; - } - - return read_vco(priv, dsrc + (doff * 4)); - default: - return 0; - } -} - -static u32 -read_mem(struct nve0_clock_priv *priv) -{ - switch (nv_rd32(priv, 0x1373f4) & 0x0000000f) { - case 1: return read_pll(priv, 0x132020); - case 2: return read_pll(priv, 0x132000); - default: - return 0; - } -} - -static u32 -read_clk(struct nve0_clock_priv *priv, int clk) -{ - u32 sctl = nv_rd32(priv, 0x137250 + (clk * 4)); - u32 sclk, sdiv; - - if (clk < 7) { - u32 ssel = nv_rd32(priv, 0x137100); - if (ssel & (1 << clk)) { - sclk = read_pll(priv, 0x137000 + (clk * 0x20)); - sdiv = 1; - } else { - sclk = read_div(priv, clk, 0x137160, 0x1371d0); - sdiv = 0; - } - } else { - u32 ssrc = nv_rd32(priv, 0x137160 + (clk * 0x04)); - if ((ssrc & 0x00000003) == 0x00000003) { - sclk = read_div(priv, clk, 0x137160, 0x1371d0); - if (ssrc & 0x00000100) { - if (ssrc & 0x40000000) - sclk = read_pll(priv, 0x1370e0); - sdiv = 1; - } else { - sdiv = 0; - } - } else { - sclk = read_div(priv, clk, 0x137160, 0x1371d0); - sdiv = 0; - } - } - - if (sctl & 0x80000000) { - if (sdiv) - sdiv = ((sctl & 0x00003f00) >> 8) + 2; - else - sdiv = ((sctl & 0x0000003f) >> 0) + 2; - return (sclk * 2) / sdiv; - } - - return sclk; -} - -static int -nve0_clock_read(struct nouveau_clock *clk, enum nv_clk_src src) -{ - struct nouveau_device *device = nv_device(clk); - struct nve0_clock_priv *priv = (void *)clk; - - switch (src) { - case nv_clk_src_crystal: - return device->crystal; - case nv_clk_src_href: - return 100000; - case nv_clk_src_mem: - return read_mem(priv); - case nv_clk_src_gpc: - return read_clk(priv, 0x00); - case nv_clk_src_rop: - return read_clk(priv, 0x01); - case nv_clk_src_hubk07: - return read_clk(priv, 0x02); - case nv_clk_src_hubk06: - return read_clk(priv, 0x07); - case nv_clk_src_hubk01: - return read_clk(priv, 0x08); - case nv_clk_src_daemon: - return read_clk(priv, 0x0c); - case nv_clk_src_vdec: - return read_clk(priv, 0x0e); - default: - nv_error(clk, "invalid clock source %d\n", src); - return -EINVAL; - } -} - -static u32 -calc_div(struct nve0_clock_priv *priv, int clk, u32 ref, u32 freq, u32 *ddiv) -{ - u32 div = min((ref * 2) / freq, (u32)65); - if (div < 2) - div = 2; - - *ddiv = div - 2; - return (ref * 2) / div; -} - -static u32 -calc_src(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *dsrc, u32 *ddiv) -{ - u32 sclk; - - /* use one of the fixed frequencies if possible */ - *ddiv = 0x00000000; - switch (freq) { - case 27000: - case 108000: - *dsrc = 0x00000000; - if (freq == 108000) - *dsrc |= 0x00030000; - return freq; - case 100000: - *dsrc = 0x00000002; - return freq; - default: - *dsrc = 0x00000003; - break; - } - - /* otherwise, calculate the closest divider */ - sclk = read_vco(priv, 0x137160 + (clk * 4)); - if (clk < 7) - sclk = calc_div(priv, clk, sclk, freq, ddiv); - return sclk; -} - -static u32 -calc_pll(struct nve0_clock_priv *priv, int clk, u32 freq, u32 *coef) -{ - struct nouveau_bios *bios = nouveau_bios(priv); - struct nvbios_pll limits; - int N, M, P, ret; - - ret = nvbios_pll_parse(bios, 0x137000 + (clk * 0x20), &limits); - if (ret) - return 0; - - limits.refclk = read_div(priv, clk, 0x137120, 0x137140); - if (!limits.refclk) - return 0; - - ret = nva3_pll_calc(nv_subdev(priv), &limits, freq, &N, NULL, &M, &P); - if (ret <= 0) - return 0; - - *coef = (P << 16) | (N << 8) | M; - return ret; -} - -static int -calc_clk(struct nve0_clock_priv *priv, - struct nouveau_cstate *cstate, int clk, int dom) -{ - struct nve0_clock_info *info = &priv->eng[clk]; - u32 freq = cstate->domain[dom]; - u32 src0, div0, div1D, div1P = 0; - u32 clk0, clk1 = 0; - - /* invalid clock domain */ - if (!freq) - return 0; - - /* first possible path, using only dividers */ - clk0 = calc_src(priv, clk, freq, &src0, &div0); - clk0 = calc_div(priv, clk, clk0, freq, &div1D); - - /* see if we can get any closer using PLLs */ - if (clk0 != freq && (0x0000ff87 & (1 << clk))) { - if (clk <= 7) - clk1 = calc_pll(priv, clk, freq, &info->coef); - else - clk1 = cstate->domain[nv_clk_src_hubk06]; - clk1 = calc_div(priv, clk, clk1, freq, &div1P); - } - - /* select the method which gets closest to target freq */ - if (abs((int)freq - clk0) <= abs((int)freq - clk1)) { - info->dsrc = src0; - if (div0) { - info->ddiv |= 0x80000000; - info->ddiv |= div0 << 8; - info->ddiv |= div0; - } - if (div1D) { - info->mdiv |= 0x80000000; - info->mdiv |= div1D; - } - info->ssel = 0; - info->freq = clk0; - } else { - if (div1P) { - info->mdiv |= 0x80000000; - info->mdiv |= div1P << 8; - } - info->ssel = (1 << clk); - info->dsrc = 0x40000100; - info->freq = clk1; - } - - return 0; -} - -static int -nve0_clock_calc(struct nouveau_clock *clk, struct nouveau_cstate *cstate) -{ - struct nve0_clock_priv *priv = (void *)clk; - int ret; - - if ((ret = calc_clk(priv, cstate, 0x00, nv_clk_src_gpc)) || - (ret = calc_clk(priv, cstate, 0x01, nv_clk_src_rop)) || - (ret = calc_clk(priv, cstate, 0x02, nv_clk_src_hubk07)) || - (ret = calc_clk(priv, cstate, 0x07, nv_clk_src_hubk06)) || - (ret = calc_clk(priv, cstate, 0x08, nv_clk_src_hubk01)) || - (ret = calc_clk(priv, cstate, 0x0c, nv_clk_src_daemon)) || - (ret = calc_clk(priv, cstate, 0x0e, nv_clk_src_vdec))) - return ret; - - return 0; -} - -static void -nve0_clock_prog_0(struct nve0_clock_priv *priv, int clk) -{ - struct nve0_clock_info *info = &priv->eng[clk]; - if (!info->ssel) { - nv_mask(priv, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv); - nv_wr32(priv, 0x137160 + (clk * 0x04), info->dsrc); - } -} - -static void -nve0_clock_prog_1_0(struct nve0_clock_priv *priv, int clk) -{ - nv_mask(priv, 0x137100, (1 << clk), 0x00000000); - nv_wait(priv, 0x137100, (1 << clk), 0x00000000); -} - -static void -nve0_clock_prog_1_1(struct nve0_clock_priv *priv, int clk) -{ - nv_mask(priv, 0x137160 + (clk * 0x04), 0x00000100, 0x00000000); -} - -static void -nve0_clock_prog_2(struct nve0_clock_priv *priv, int clk) -{ - struct nve0_clock_info *info = &priv->eng[clk]; - const u32 addr = 0x137000 + (clk * 0x20); - nv_mask(priv, addr + 0x00, 0x00000004, 0x00000000); - nv_mask(priv, addr + 0x00, 0x00000001, 0x00000000); - if (info->coef) { - nv_wr32(priv, addr + 0x04, info->coef); - nv_mask(priv, addr + 0x00, 0x00000001, 0x00000001); - nv_wait(priv, addr + 0x00, 0x00020000, 0x00020000); - nv_mask(priv, addr + 0x00, 0x00020004, 0x00000004); - } -} - -static void -nve0_clock_prog_3(struct nve0_clock_priv *priv, int clk) -{ - struct nve0_clock_info *info = &priv->eng[clk]; - nv_mask(priv, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv); -} - -static void -nve0_clock_prog_4_0(struct nve0_clock_priv *priv, int clk) -{ - struct nve0_clock_info *info = &priv->eng[clk]; - if (info->ssel) { - nv_mask(priv, 0x137100, (1 << clk), info->ssel); - nv_wait(priv, 0x137100, (1 << clk), info->ssel); - } -} - -static void -nve0_clock_prog_4_1(struct nve0_clock_priv *priv, int clk) -{ - struct nve0_clock_info *info = &priv->eng[clk]; - if (info->ssel) { - nv_mask(priv, 0x137160 + (clk * 0x04), 0x40000000, 0x40000000); - nv_mask(priv, 0x137160 + (clk * 0x04), 0x00000100, 0x00000100); - } -} - -static int -nve0_clock_prog(struct nouveau_clock *clk) -{ - struct nve0_clock_priv *priv = (void *)clk; - struct { - u32 mask; - void (*exec)(struct nve0_clock_priv *, int); - } stage[] = { - { 0x007f, nve0_clock_prog_0 }, /* div programming */ - { 0x007f, nve0_clock_prog_1_0 }, /* select div mode */ - { 0xff80, nve0_clock_prog_1_1 }, - { 0x00ff, nve0_clock_prog_2 }, /* (maybe) program pll */ - { 0xff80, nve0_clock_prog_3 }, /* final divider */ - { 0x007f, nve0_clock_prog_4_0 }, /* (maybe) select pll mode */ - { 0xff80, nve0_clock_prog_4_1 }, - }; - int i, j; - - for (i = 0; i < ARRAY_SIZE(stage); i++) { - for (j = 0; j < ARRAY_SIZE(priv->eng); j++) { - if (!(stage[i].mask & (1 << j))) - continue; - if (!priv->eng[j].freq) - continue; - stage[i].exec(priv, j); - } - } - - return 0; -} - -static void -nve0_clock_tidy(struct nouveau_clock *clk) -{ - struct nve0_clock_priv *priv = (void *)clk; - memset(priv->eng, 0x00, sizeof(priv->eng)); -} - -static struct nouveau_clocks -nve0_domain[] = { - { nv_clk_src_crystal, 0xff }, - { nv_clk_src_href , 0xff }, - { nv_clk_src_gpc , 0x00, NVKM_CLK_DOM_FLAG_CORE, "core", 2000 }, - { nv_clk_src_hubk07 , 0x01, NVKM_CLK_DOM_FLAG_CORE }, - { nv_clk_src_rop , 0x02, NVKM_CLK_DOM_FLAG_CORE }, - { nv_clk_src_mem , 0x03, 0, "memory", 1000 }, - { nv_clk_src_hubk06 , 0x04, NVKM_CLK_DOM_FLAG_CORE }, - { nv_clk_src_hubk01 , 0x05 }, - { nv_clk_src_vdec , 0x06 }, - { nv_clk_src_daemon , 0x07 }, - { nv_clk_src_max } -}; - -static int -nve0_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nve0_clock_priv *priv; - int ret; - - ret = nouveau_clock_create(parent, engine, oclass, nve0_domain, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.read = nve0_clock_read; - priv->base.calc = nve0_clock_calc; - priv->base.prog = nve0_clock_prog; - priv->base.tidy = nve0_clock_tidy; - return 0; -} - -struct nouveau_oclass -nve0_clock_oclass = { - .handle = NV_SUBDEV(CLOCK, 0xe0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nve0_clock_ctor, - .dtor = _nouveau_clock_dtor, - .init = _nouveau_clock_init, - .fini = _nouveau_clock_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c index b47d543..cf1ed0d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnv04.c @@ -38,7 +38,7 @@ getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk, * "clk" parameter in kHz * returns calculated clock */ - struct nouveau_bios *bios = nouveau_bios(subdev); + int cv = nouveau_bios(subdev)->version.chip; int minvco = info->vco1.min_freq, maxvco = info->vco1.max_freq; int minM = info->vco1.min_m, maxM = info->vco1.max_m; int minN = info->vco1.min_n, maxN = info->vco1.max_n; @@ -54,21 +54,18 @@ getMNP_single(struct nouveau_subdev *subdev, struct nvbios_pll *info, int clk, /* this division verified for nv20, nv18, nv28 (Haiku), and nv34 */ /* possibly correlated with introduction of 27MHz crystal */ - if (bios->version.major < 0x60) { - int cv = bios->version.chip; - if (cv < 0x17 || cv == 0x1a || cv == 0x20) { - if (clk > 250000) - maxM = 6; - if (clk > 340000) - maxM = 2; - } else if (cv < 0x40) { - if (clk > 150000) - maxM = 6; - if (clk > 200000) - maxM = 4; - if (clk > 340000) - maxM = 2; - } + if (cv < 0x17 || cv == 0x1a || cv == 0x20) { + if (clk > 250000) + maxM = 6; + if (clk > 340000) + maxM = 2; + } else if (cv < 0x40) { + if (clk > 150000) + maxM = 6; + if (clk > 200000) + maxM = 4; + if (clk > 340000) + maxM = 2; } P = 1 << maxP; @@ -230,12 +227,10 @@ nv04_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info, u32 freq, { int ret; - if (!info->vco2.max_freq || !N2) { + if (!info->vco2.max_freq) { ret = getMNP_single(subdev, info, freq, N1, M1, P); - if (N2) { - *N2 = 1; - *M2 = 1; - } + *N2 = 1; + *M2 = 1; } else { ret = getMNP_double(subdev, info, freq, N1, M1, N2, M2, P); } diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c index 8eca457..2fe1f71 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/clock/pllnva3.c @@ -45,7 +45,6 @@ nva3_pll_calc(struct nouveau_subdev *subdev, struct nvbios_pll *info, lM = max(lM, (int)info->vco1.min_m); hM = (info->refclk + info->vco1.min_inputfreq) / info->vco1.min_inputfreq; hM = min(hM, (int)info->vco1.max_m); - lM = min(lM, hM); for (M = lM; M <= hM; M++) { u32 tmp = freq * *P * M; diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/seq.h b/drivers/gpu/drm/nouveau/core/subdev/clock/seq.h deleted file mode 100644 index fb33f06..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/clock/seq.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __NVKM_CLK_SEQ_H__ -#define __NVKM_CLK_SEQ_H__ - -#include <subdev/bus.h> -#include <subdev/bus/hwsq.h> - -#define clk_init(s,p) hwsq_init(&(s)->base, (p)) -#define clk_exec(s,e) hwsq_exec(&(s)->base, (e)) -#define clk_have(s,r) ((s)->r_##r.addr != 0x000000) -#define clk_rd32(s,r) hwsq_rd32(&(s)->base, &(s)->r_##r) -#define clk_wr32(s,r,d) hwsq_wr32(&(s)->base, &(s)->r_##r, (d)) -#define clk_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d)) -#define clk_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d)) -#define clk_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d)) -#define clk_nsec(s,n) hwsq_nsec(&(s)->base, (n)) - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c index 27c8235..b22357d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c @@ -168,8 +168,7 @@ setPLL_single(struct nouveau_devinit *devinit, u32 reg, /* downclock -- write new NM first */ nv_wr32(devinit, reg, (oldpll & 0xffff0000) | pv->NM1); - if ((chip_version < 0x17 || chip_version == 0x1a) && - chip_version != 0x11) + if (chip_version < 0x17 && chip_version != 0x11) /* wait a bit on older chips */ msleep(64); nv_rd32(devinit, reg); diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c index 8d274db..463b08f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c @@ -38,18 +38,12 @@ static void nv10_devinit_meminit(struct nouveau_devinit *devinit) { struct nv10_devinit_priv *priv = (void *)devinit; - static const int mem_width[] = { 0x10, 0x00, 0x20 }; - int mem_width_count; + const int mem_width[] = { 0x10, 0x00, 0x20 }; + const int mem_width_count = nv_device(priv)->chipset >= 0x17 ? 3 : 2; uint32_t patt = 0xdeadbeef; struct io_mapping *fb; int i, j, k; - if (nv_device(priv)->card_type >= NV_11 && - nv_device(priv)->chipset >= 0x17) - mem_width_count = 3; - else - mem_width_count = 2; - /* Map the framebuffer aperture */ fb = fbmem_init(nv_device(priv)->pdev); if (!fb) { diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c index f009d8a..821cd75 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c @@ -22,10 +22,9 @@ * Authors: Ben Skeggs */ -#include <subdev/bios.h> -#include <subdev/bios/bit.h> - -#include "priv.h" +#include "subdev/fb.h" +#include "subdev/bios.h" +#include "subdev/bios/bit.h" int nouveau_fb_bios_memtype(struct nouveau_bios *bios) @@ -107,9 +106,9 @@ _nouveau_fb_dtor(struct nouveau_object *object) int nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, int length, void **pobject) + struct nouveau_oclass *oclass, struct nouveau_oclass *ramcls, + int length, void **pobject) { - struct nouveau_fb_impl *impl = (void *)oclass; static const char *name[] = { [NV_MEM_TYPE_UNKNOWN] = "unknown", [NV_MEM_TYPE_STOLEN ] = "stolen system memory", @@ -133,10 +132,8 @@ nouveau_fb_create_(struct nouveau_object *parent, struct nouveau_object *engine, if (ret) return ret; - pfb->memtype_valid = impl->memtype; - ret = nouveau_object_ctor(nv_object(pfb), nv_object(pfb), - impl->ram, NULL, 0, &ram); + ramcls, NULL, 0, &ram); if (ret) { nv_fatal(pfb, "error detecting memory configuration!!\n"); return ret; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c deleted file mode 100644 index 34f9605..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr5.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 <subdev/bios.h> -#include "priv.h" - -int -nouveau_gddr5_calc(struct nouveau_ram *ram) -{ - struct nouveau_bios *bios = nouveau_bios(ram); - int pd, lf, xd, vh, vr, vo; - int WL, CL, WR, at, dt, ds; - int rq = ram->freq < 1000000; /* XXX */ - - switch (!!ram->ramcfg.data * ram->ramcfg.version) { - case 0x11: - pd = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x80) >> 7; - lf = (nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x40) >> 6; - xd = !(nv_ro08(bios, ram->ramcfg.data + 0x01) & 0x20); - vh = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x10) >> 4; - vr = (nv_ro08(bios, ram->ramcfg.data + 0x02) & 0x04) >> 2; - vo = nv_ro08(bios, ram->ramcfg.data + 0x06) & 0xff; - break; - default: - return -ENOSYS; - } - - switch (!!ram->timing.data * ram->timing.version) { - case 0x20: - WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7; - CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f; - WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f; - at = (nv_ro08(bios, ram->timing.data + 0x2e) & 0xc0) >> 6; - dt = nv_ro08(bios, ram->timing.data + 0x2e) & 0x03; - ds = nv_ro08(bios, ram->timing.data + 0x2f) & 0x03; - break; - default: - return -ENOSYS; - } - - if (WL < 1 || WL > 7 || CL < 5 || CL > 36 || WR < 4 || WR > 35) - return -EINVAL; - CL -= 5; - WR -= 4; - - ram->mr[0] &= ~0xf7f; - ram->mr[0] |= (WR & 0x0f) << 8; - ram->mr[0] |= (CL & 0x0f) << 3; - ram->mr[0] |= (WL & 0x07) << 0; - - ram->mr[1] &= ~0x0bf; - ram->mr[1] |= (xd & 0x01) << 7; - ram->mr[1] |= (at & 0x03) << 4; - ram->mr[1] |= (dt & 0x03) << 2; - ram->mr[1] |= (ds & 0x03) << 0; - - ram->mr[3] &= ~0x020; - ram->mr[3] |= (rq & 0x01) << 5; - - if (!vo) - vo = (ram->mr[6] & 0xff0) >> 4; - if (ram->mr[6] & 0x001) - pd = 1; /* binary driver does this.. bug? */ - ram->mr[6] &= ~0xff1; - ram->mr[6] |= (vo & 0xff) << 4; - ram->mr[6] |= (pd & 0x01) << 0; - - if (!(ram->mr[7] & 0x100)) - vr = 0; /* binary driver does this.. bug? */ - ram->mr[7] &= ~0x188; - ram->mr[7] |= (vr & 0x01) << 8; - ram->mr[7] |= (vh & 0x01) << 7; - ram->mr[7] |= (lf & 0x01) << 3; - return 0; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c index 8309fe3..1f103c7 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.c @@ -22,10 +22,14 @@ * Authors: Ben Skeggs */ -#include "nv04.h" +#include "priv.h" #define NV04_PFB_CFG0 0x00100200 +struct nv04_fb_priv { + struct nouveau_fb base; +}; + bool nv04_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags) { @@ -53,37 +57,30 @@ nv04_fb_init(struct nouveau_object *object) return 0; } -int +static int nv04_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) { - struct nv04_fb_impl *impl = (void *)oclass; struct nv04_fb_priv *priv; int ret; - ret = nouveau_fb_create(parent, engine, oclass, &priv); + ret = nouveau_fb_create(parent, engine, oclass, &nv04_ram_oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; - priv->base.tile.regions = impl->tile.regions; - priv->base.tile.init = impl->tile.init; - priv->base.tile.comp = impl->tile.comp; - priv->base.tile.fini = impl->tile.fini; - priv->base.tile.prog = impl->tile.prog; + priv->base.memtype_valid = nv04_fb_memtype_valid; return 0; } -struct nouveau_oclass * -nv04_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x04), - .base.base.ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass +nv04_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x04), + .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv04_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv04_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv04_ram_oclass, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h deleted file mode 100644 index 06ce71f..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv04.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef __NVKM_FB_NV04_H__ -#define __NVKM_FB_NV04_H__ - -#include "priv.h" - -struct nv04_fb_priv { - struct nouveau_fb base; -}; - -int nv04_fb_ctor(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, void *, u32, - struct nouveau_object **); - -struct nv04_fb_impl { - struct nouveau_fb_impl base; - struct { - int regions; - void (*init)(struct nouveau_fb *, int i, u32 addr, u32 size, - u32 pitch, u32 flags, struct nouveau_fb_tile *); - void (*comp)(struct nouveau_fb *, int i, u32 size, u32 flags, - struct nouveau_fb_tile *); - void (*fini)(struct nouveau_fb *, int i, - struct nouveau_fb_tile *); - void (*prog)(struct nouveau_fb *, int i, - struct nouveau_fb_tile *); - } tile; -}; - -void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, - u32 pitch, u32 flags, struct nouveau_fb_tile *); -void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *); -void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); - -void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, - u32 pitch, u32 flags, struct nouveau_fb_tile *); -void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *); -void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); - -int nv30_fb_init(struct nouveau_object *); -void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, - u32 pitch, u32 flags, struct nouveau_fb_tile *); - -void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags, - struct nouveau_fb_tile *); - -int nv41_fb_init(struct nouveau_object *); -void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); - -int nv44_fb_init(struct nouveau_object *); -void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); - -void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, - u32 pitch, u32 flags, struct nouveau_fb_tile *); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c index ffb7ec6..be069b5 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv10.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv10_fb_priv { + struct nouveau_fb base; +}; void nv10_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch, @@ -53,19 +57,34 @@ nv10_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile) nv_rd32(pfb, 0x100240 + (i * 0x10)); } -struct nouveau_oclass * -nv10_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x10), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv10_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv10_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv10_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 8; + priv->base.tile.init = nv10_fb_tile_init; + priv->base.tile.fini = nv10_fb_tile_fini; + priv->base.tile.prog = nv10_fb_tile_prog; + return 0; +} + +struct nouveau_oclass +nv10_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x10), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv10_fb_ctor, .dtor = _nouveau_fb_dtor, .init = _nouveau_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv10_ram_oclass, - .tile.regions = 8, - .tile.init = nv10_fb_tile_init, - .tile.fini = nv10_fb_tile_fini, - .tile.prog = nv10_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c index 9159a5c..57a2af0 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv1a.c @@ -24,21 +24,40 @@ * */ -#include "nv04.h" +#include "priv.h" -struct nouveau_oclass * -nv1a_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x1a), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +struct nv1a_fb_priv { + struct nouveau_fb base; +}; + +static int +nv1a_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv1a_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv1a_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 8; + priv->base.tile.init = nv10_fb_tile_init; + priv->base.tile.fini = nv10_fb_tile_fini; + priv->base.tile.prog = nv10_fb_tile_prog; + return 0; +} + +struct nouveau_oclass +nv1a_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x1a), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv1a_fb_ctor, .dtor = _nouveau_fb_dtor, .init = _nouveau_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv10_ram_oclass, - .tile.regions = 8, - .tile.init = nv10_fb_tile_init, - .tile.fini = nv10_fb_tile_fini, - .tile.prog = nv10_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c index f003c1b..b18c4e6 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv20.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv20_fb_priv { + struct nouveau_fb base; +}; void nv20_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch, @@ -76,20 +80,35 @@ nv20_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile) nv_wr32(pfb, 0x100300 + (i * 0x04), tile->zcomp); } -struct nouveau_oclass * -nv20_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x20), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv20_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv20_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 8; + priv->base.tile.init = nv20_fb_tile_init; + priv->base.tile.comp = nv20_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv20_fb_tile_prog; + return 0; +} + +struct nouveau_oclass +nv20_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x20), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv20_fb_ctor, .dtor = _nouveau_fb_dtor, .init = _nouveau_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv20_ram_oclass, - .tile.regions = 8, - .tile.init = nv20_fb_tile_init, - .tile.comp = nv20_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv20_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c index f34f422..32ccabf 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv25.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv25_fb_priv { + struct nouveau_fb base; +}; static void nv25_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, @@ -42,20 +46,35 @@ nv25_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, } } -struct nouveau_oclass * -nv25_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x25), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv25_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv25_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 8; + priv->base.tile.init = nv20_fb_tile_init; + priv->base.tile.comp = nv25_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv20_fb_tile_prog; + return 0; +} + +struct nouveau_oclass +nv25_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x25), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv25_fb_ctor, .dtor = _nouveau_fb_dtor, .init = _nouveau_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv20_ram_oclass, - .tile.regions = 8, - .tile.init = nv20_fb_tile_init, - .tile.comp = nv25_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv20_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c index 69093f7..bef756d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv30.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv30_fb_priv { + struct nouveau_fb base; +}; void nv30_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch, @@ -63,7 +67,7 @@ nv30_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, } static int -calc_bias(struct nv04_fb_priv *priv, int k, int i, int j) +calc_bias(struct nv30_fb_priv *priv, int k, int i, int j) { struct nouveau_device *device = nv_device(priv); int b = (device->chipset > 0x30 ? @@ -74,7 +78,7 @@ calc_bias(struct nv04_fb_priv *priv, int k, int i, int j) } static int -calc_ref(struct nv04_fb_priv *priv, int l, int k, int i) +calc_ref(struct nv30_fb_priv *priv, int l, int k, int i) { int j, x = 0; @@ -91,7 +95,7 @@ int nv30_fb_init(struct nouveau_object *object) { struct nouveau_device *device = nv_device(object); - struct nv04_fb_priv *priv = (void *)object; + struct nv30_fb_priv *priv = (void *)object; int ret, i, j; ret = nouveau_fb_init(&priv->base); @@ -120,20 +124,35 @@ nv30_fb_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nv30_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x30), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv30_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv30_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 8; + priv->base.tile.init = nv30_fb_tile_init; + priv->base.tile.comp = nv30_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv20_fb_tile_prog; + return 0; +} + +struct nouveau_oclass +nv30_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x30), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv30_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv30_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv20_ram_oclass, - .tile.regions = 8, - .tile.init = nv30_fb_tile_init, - .tile.comp = nv30_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv20_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c index 161b06e..097d8e3 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv35.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv35_fb_priv { + struct nouveau_fb base; +}; static void nv35_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, @@ -43,20 +47,35 @@ nv35_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, } } -struct nouveau_oclass * -nv35_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x35), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv35_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv35_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 8; + priv->base.tile.init = nv30_fb_tile_init; + priv->base.tile.comp = nv35_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv20_fb_tile_prog; + return 0; +} + +struct nouveau_oclass +nv35_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x35), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv35_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv30_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv20_ram_oclass, - .tile.regions = 8, - .tile.init = nv30_fb_tile_init, - .tile.comp = nv35_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv20_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c index 2dd3d0a..9d6d9df 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv36.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv36_fb_priv { + struct nouveau_fb base; +}; static void nv36_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, @@ -43,20 +47,35 @@ nv36_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, } } -struct nouveau_oclass * -nv36_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x36), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv36_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv36_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv20_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 8; + priv->base.tile.init = nv30_fb_tile_init; + priv->base.tile.comp = nv36_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv20_fb_tile_prog; + return 0; +} + +struct nouveau_oclass +nv36_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x36), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv36_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv30_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv20_ram_oclass, - .tile.regions = 8, - .tile.init = nv30_fb_tile_init, - .tile.comp = nv36_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv20_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c index 95a115a..33b4393 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv40_fb_priv { + struct nouveau_fb base; +}; void nv40_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, @@ -46,7 +50,7 @@ nv40_fb_tile_comp(struct nouveau_fb *pfb, int i, u32 size, u32 flags, static int nv40_fb_init(struct nouveau_object *object) { - struct nv04_fb_priv *priv = (void *)object; + struct nv40_fb_priv *priv = (void *)object; int ret; ret = nouveau_fb_init(&priv->base); @@ -57,20 +61,36 @@ nv40_fb_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nv40_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x40), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv40_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv40_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv40_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 8; + priv->base.tile.init = nv30_fb_tile_init; + priv->base.tile.comp = nv40_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv20_fb_tile_prog; + return 0; +} + + +struct nouveau_oclass +nv40_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x40), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv40_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv40_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv40_ram_oclass, - .tile.regions = 8, - .tile.init = nv30_fb_tile_init, - .tile.comp = nv40_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv20_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h deleted file mode 100644 index 581f808..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv40.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef __NVKM_FB_NV40_H__ -#define __NVKM_FB_NV40_H__ - -#include "priv.h" - -struct nv40_ram { - struct nouveau_ram base; - u32 ctrl; - u32 coef; -}; - - -int nv40_ram_calc(struct nouveau_fb *, u32); -int nv40_ram_prog(struct nouveau_fb *); -void nv40_ram_tidy(struct nouveau_fb *); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c index b239a86..02cd837 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv41.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv41_fb_priv { + struct nouveau_fb base; +}; void nv41_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile) @@ -39,7 +43,7 @@ nv41_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile) int nv41_fb_init(struct nouveau_object *object) { - struct nv04_fb_priv *priv = (void *)object; + struct nv41_fb_priv *priv = (void *)object; int ret; ret = nouveau_fb_init(&priv->base); @@ -50,20 +54,36 @@ nv41_fb_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nv41_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x41), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv41_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv41_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv41_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 12; + priv->base.tile.init = nv30_fb_tile_init; + priv->base.tile.comp = nv40_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv41_fb_tile_prog; + return 0; +} + + +struct nouveau_oclass +nv41_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x41), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv41_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv41_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv41_ram_oclass, - .tile.regions = 12, - .tile.init = nv30_fb_tile_init, - .tile.comp = nv40_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv41_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c index d847820..c5246c2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv44.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv44_fb_priv { + struct nouveau_fb base; +}; static void nv44_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch, @@ -48,7 +52,7 @@ nv44_fb_tile_prog(struct nouveau_fb *pfb, int i, struct nouveau_fb_tile *tile) int nv44_fb_init(struct nouveau_object *object) { - struct nv04_fb_priv *priv = (void *)object; + struct nv44_fb_priv *priv = (void *)object; int ret; ret = nouveau_fb_init(&priv->base); @@ -60,19 +64,35 @@ nv44_fb_init(struct nouveau_object *object) return 0; } -struct nouveau_oclass * -nv44_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x44), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv44_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv44_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv44_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 12; + priv->base.tile.init = nv44_fb_tile_init; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv44_fb_tile_prog; + return 0; +} + + +struct nouveau_oclass +nv44_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x44), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv44_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv44_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv44_ram_oclass, - .tile.regions = 12, - .tile.init = nv44_fb_tile_init, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv44_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c index a5b7751..e2b5790 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv46.c @@ -24,7 +24,11 @@ * */ -#include "nv04.h" +#include "priv.h" + +struct nv46_fb_priv { + struct nouveau_fb base; +}; void nv46_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch, @@ -40,19 +44,35 @@ nv46_fb_tile_init(struct nouveau_fb *pfb, int i, u32 addr, u32 size, u32 pitch, tile->pitch = pitch; } -struct nouveau_oclass * -nv46_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x46), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +static int +nv46_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv46_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv44_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 15; + priv->base.tile.init = nv46_fb_tile_init; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv44_fb_tile_prog; + return 0; +} + + +struct nouveau_oclass +nv46_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x46), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv46_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv44_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv44_ram_oclass, - .tile.regions = 15, - .tile.init = nv46_fb_tile_init, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv44_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c index 3bea142..fe6a227 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv47.c @@ -24,22 +24,42 @@ * */ -#include "nv04.h" +#include "priv.h" -struct nouveau_oclass * -nv47_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x47), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +struct nv47_fb_priv { + struct nouveau_fb base; +}; + +static int +nv47_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv47_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv41_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 15; + priv->base.tile.init = nv30_fb_tile_init; + priv->base.tile.comp = nv40_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv41_fb_tile_prog; + return 0; +} + + +struct nouveau_oclass +nv47_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x47), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv47_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv41_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv41_ram_oclass, - .tile.regions = 15, - .tile.init = nv30_fb_tile_init, - .tile.comp = nv40_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv41_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c index 666cbd5..5eca99b 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv49.c @@ -24,22 +24,42 @@ * */ -#include "nv04.h" +#include "priv.h" -struct nouveau_oclass * -nv49_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x49), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +struct nv49_fb_priv { + struct nouveau_fb base; +}; + +static int +nv49_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv49_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv49_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 15; + priv->base.tile.init = nv30_fb_tile_init; + priv->base.tile.comp = nv40_fb_tile_comp; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv41_fb_tile_prog; + return 0; +} + + +struct nouveau_oclass +nv49_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x49), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv49_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv41_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv49_ram_oclass, - .tile.regions = 15, - .tile.init = nv30_fb_tile_init, - .tile.comp = nv40_fb_tile_comp, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv41_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c index 42e64f3..1190b78 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv4e.c @@ -24,21 +24,40 @@ * */ -#include "nv04.h" +#include "priv.h" -struct nouveau_oclass * -nv4e_fb_oclass = &(struct nv04_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x4e), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_fb_ctor, +struct nv4e_fb_priv { + struct nouveau_fb base; +}; + +static int +nv4e_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv4e_fb_priv *priv; + int ret; + + ret = nouveau_fb_create(parent, engine, oclass, &nv4e_ram_oclass, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + priv->base.memtype_valid = nv04_fb_memtype_valid; + priv->base.tile.regions = 12; + priv->base.tile.init = nv46_fb_tile_init; + priv->base.tile.fini = nv20_fb_tile_fini; + priv->base.tile.prog = nv44_fb_tile_prog; + return 0; +} + +struct nouveau_oclass +nv4e_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x4e), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv4e_fb_ctor, .dtor = _nouveau_fb_dtor, .init = nv44_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv04_fb_memtype_valid, - .base.ram = &nv4e_ram_oclass, - .tile.regions = 12, - .tile.init = nv46_fb_tile_init, - .tile.fini = nv20_fb_tile_fini, - .tile.prog = nv44_fb_tile_prog, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c index cbc7f00..da614ec 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.c @@ -27,9 +27,14 @@ #include <core/engctx.h> #include <core/object.h> +#include "priv.h" #include <subdev/bios.h> -#include "nv50.h" +struct nv50_fb_priv { + struct nouveau_fb base; + struct page *r100c08_page; + dma_addr_t r100c08; +}; int nv50_fb_memtype[0x80] = { @@ -43,7 +48,7 @@ nv50_fb_memtype[0x80] = { 1, 0, 2, 0, 1, 0, 2, 0, 1, 1, 2, 2, 1, 1, 0, 0 }; -bool +static bool nv50_fb_memtype_valid(struct nouveau_fb *pfb, u32 memtype) { return nv50_fb_memtype[(memtype & 0xff00) >> 8] != 0; @@ -234,7 +239,7 @@ nv50_fb_intr(struct nouveau_subdev *subdev) pr_cont("0x%08x\n", st1); } -int +static int nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) @@ -243,7 +248,7 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv50_fb_priv *priv; int ret; - ret = nouveau_fb_create(parent, engine, oclass, &priv); + ret = nouveau_fb_create(parent, engine, oclass, &nv50_ram_oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; @@ -259,11 +264,12 @@ nv50_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, nv_warn(priv, "failed 0x100c08 page alloc\n"); } + priv->base.memtype_valid = nv50_fb_memtype_valid; nv_subdev(priv)->intr = nv50_fb_intr; return 0; } -void +static void nv50_fb_dtor(struct nouveau_object *object) { struct nouveau_device *device = nv_device(object); @@ -278,10 +284,10 @@ nv50_fb_dtor(struct nouveau_object *object) nouveau_fb_destroy(&priv->base); } -int +static int nv50_fb_init(struct nouveau_object *object) { - struct nv50_fb_impl *impl = (void *)object->oclass; + struct nouveau_device *device = nv_device(object); struct nv50_fb_priv *priv = (void *)object; int ret; @@ -297,20 +303,33 @@ nv50_fb_init(struct nouveau_object *object) /* This is needed to get meaningful information from 100c90 * on traps. No idea what these values mean exactly. */ - nv_wr32(priv, 0x100c90, impl->trap); + switch (device->chipset) { + case 0x50: + nv_wr32(priv, 0x100c90, 0x000707ff); + break; + case 0xa3: + case 0xa5: + case 0xa8: + nv_wr32(priv, 0x100c90, 0x000d0fff); + break; + case 0xaf: + nv_wr32(priv, 0x100c90, 0x089d1fff); + break; + default: + nv_wr32(priv, 0x100c90, 0x001d07ff); + break; + } + return 0; } -struct nouveau_oclass * -nv50_fb_oclass = &(struct nv50_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x50), - .base.base.ofuncs = &(struct nouveau_ofuncs) { +struct nouveau_oclass +nv50_fb_oclass = { + .handle = NV_SUBDEV(FB, 0x50), + .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv50_fb_ctor, .dtor = nv50_fb_dtor, .init = nv50_fb_init, .fini = _nouveau_fb_fini, }, - .base.memtype = nv50_fb_memtype_valid, - .base.ram = &nv50_ram_oclass, - .trap = 0x000707ff, -}.base.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h deleted file mode 100644 index c5e5a88..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv50.h +++ /dev/null @@ -1,33 +0,0 @@ -#ifndef __NVKM_FB_NV50_H__ -#define __NVKM_FB_NV50_H__ - -#include "priv.h" - -struct nv50_fb_priv { - struct nouveau_fb base; - struct page *r100c08_page; - dma_addr_t r100c08; -}; - -int nv50_fb_ctor(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, void *, u32, - struct nouveau_object **); -void nv50_fb_dtor(struct nouveau_object *); -int nv50_fb_init(struct nouveau_object *); - -struct nv50_fb_impl { - struct nouveau_fb_impl base; - u32 trap; -}; - -#define nv50_ram_create(p,e,o,d) \ - nv50_ram_create_((p), (e), (o), sizeof(**d), (void **)d) -int nv50_ram_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, void **); -int nv50_ram_get(struct nouveau_fb *, u64 size, u32 align, u32 ncmin, - u32 memtype, struct nouveau_mem **); -void nv50_ram_put(struct nouveau_fb *, struct nouveau_mem **); -void __nv50_ram_put(struct nouveau_fb *, struct nouveau_mem *); -extern int nv50_fb_memtype[0x80]; - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c deleted file mode 100644 index cf0e767..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nv84.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 "nv50.h" - -struct nouveau_oclass * -nv84_fb_oclass = &(struct nv50_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0x84), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_fb_ctor, - .dtor = nv50_fb_dtor, - .init = nv50_fb_init, - .fini = _nouveau_fb_fini, - }, - .base.memtype = nv50_fb_memtype_valid, - .base.ram = &nv50_ram_oclass, - .trap = 0x001d07ff, -}.base.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c deleted file mode 100644 index dab6e1c..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nva3.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 "nv50.h" - -struct nouveau_oclass * -nva3_fb_oclass = &(struct nv50_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0xa3), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_fb_ctor, - .dtor = nv50_fb_dtor, - .init = nv50_fb_init, - .fini = _nouveau_fb_fini, - }, - .base.memtype = nv50_fb_memtype_valid, - .base.ram = &nva3_ram_oclass, - .trap = 0x000d0fff, -}.base.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c deleted file mode 100644 index cba8e68..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaa.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 "nv50.h" - -struct nouveau_oclass * -nvaa_fb_oclass = &(struct nv50_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0xaa), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_fb_ctor, - .dtor = nv50_fb_dtor, - .init = nv50_fb_init, - .fini = _nouveau_fb_fini, - }, - .base.memtype = nv50_fb_memtype_valid, - .base.ram = &nvaa_ram_oclass, - .trap = 0x001d07ff, -}.base.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c deleted file mode 100644 index 5423faa..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvaf.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * 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 "nv50.h" - -struct nouveau_oclass * -nvaf_fb_oclass = &(struct nv50_fb_impl) { - .base.base.handle = NV_SUBDEV(FB, 0xaf), - .base.base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_fb_ctor, - .dtor = nv50_fb_dtor, - .init = nv50_fb_init, - .fini = _nouveau_fb_fini, - }, - .base.memtype = nv50_fb_memtype_valid, - .base.ram = &nvaa_ram_oclass, - .trap = 0x089d1fff, -}.base.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c index e5fc37c..f35d76f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.c @@ -22,18 +22,24 @@ * Authors: Ben Skeggs */ -#include "nvc0.h" +#include "priv.h" + +struct nvc0_fb_priv { + struct nouveau_fb base; + struct page *r100c10_page; + dma_addr_t r100c10; +}; extern const u8 nvc0_pte_storage_type_map[256]; -bool +static bool nvc0_fb_memtype_valid(struct nouveau_fb *pfb, u32 tile_flags) { u8 memtype = (tile_flags & 0x0000ff00) >> 8; return likely((nvc0_pte_storage_type_map[memtype] != 0xff)); } -int +static int nvc0_fb_init(struct nouveau_object *object) { struct nvc0_fb_priv *priv = (void *)object; @@ -48,7 +54,7 @@ nvc0_fb_init(struct nouveau_object *object) return 0; } -void +static void nvc0_fb_dtor(struct nouveau_object *object) { struct nouveau_device *device = nv_device(object); @@ -63,7 +69,7 @@ nvc0_fb_dtor(struct nouveau_object *object) nouveau_fb_destroy(&priv->base); } -int +static int nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) @@ -72,11 +78,13 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nvc0_fb_priv *priv; int ret; - ret = nouveau_fb_create(parent, engine, oclass, &priv); + ret = nouveau_fb_create(parent, engine, oclass, &nvc0_ram_oclass, &priv); *pobject = nv_object(priv); if (ret) return ret; + priv->base.memtype_valid = nvc0_fb_memtype_valid; + priv->r100c10_page = alloc_page(GFP_KERNEL | __GFP_ZERO); if (priv->r100c10_page) { priv->r100c10 = pci_map_page(device->pdev, priv->r100c10_page, @@ -89,15 +97,14 @@ nvc0_fb_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -struct nouveau_oclass * -nvc0_fb_oclass = &(struct nouveau_fb_impl) { - .base.handle = NV_SUBDEV(FB, 0xc0), - .base.ofuncs = &(struct nouveau_ofuncs) { + +struct nouveau_oclass +nvc0_fb_oclass = { + .handle = NV_SUBDEV(FB, 0xc0), + .ofuncs = &(struct nouveau_ofuncs) { .ctor = nvc0_fb_ctor, .dtor = nvc0_fb_dtor, .init = nvc0_fb_init, .fini = _nouveau_fb_fini, }, - .memtype = nvc0_fb_memtype_valid, - .ram = &nvc0_ram_oclass, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h b/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h deleted file mode 100644 index 9e1931e..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nvc0.h +++ /dev/null @@ -1,29 +0,0 @@ -#ifndef __NVKM_RAM_NVC0_H__ -#define __NVKM_RAM_NVC0_H__ - -#include "priv.h" -#include "nv50.h" - -struct nvc0_fb_priv { - struct nouveau_fb base; - struct page *r100c10_page; - dma_addr_t r100c10; -}; - -int nvc0_fb_ctor(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, void *, u32, - struct nouveau_object **); -void nvc0_fb_dtor(struct nouveau_object *); -int nvc0_fb_init(struct nouveau_object *); -bool nvc0_fb_memtype_valid(struct nouveau_fb *, u32); - - -#define nvc0_ram_create(p,e,o,d) \ - nvc0_ram_create_((p), (e), (o), sizeof(**d), (void **)d) -int nvc0_ram_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, void **); -int nvc0_ram_get(struct nouveau_fb *, u64, u32, u32, u32, - struct nouveau_mem **); -void nvc0_ram_put(struct nouveau_fb *, struct nouveau_mem **); - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c deleted file mode 100644 index 595db50..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/nve0.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 "nvc0.h" - -struct nouveau_oclass * -nve0_fb_oclass = &(struct nouveau_fb_impl) { - .base.handle = NV_SUBDEV(FB, 0xe0), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvc0_fb_ctor, - .dtor = nvc0_fb_dtor, - .init = nvc0_fb_init, - .fini = _nouveau_fb_fini, - }, - .memtype = nvc0_fb_memtype_valid, - .ram = &nve0_ram_oclass, -}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h index 4931252..db9d6dd 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h @@ -12,8 +12,6 @@ #define nouveau_ram_fini(p,s) \ nouveau_object_fini(&(p)->base, (s)) -#define nouveau_ram_create_(p,e,o,s,d) \ - nouveau_object_create_((p), (e), (o), 0, (s), (void **)d) #define _nouveau_ram_dtor nouveau_object_destroy #define _nouveau_ram_init nouveau_object_init #define _nouveau_ram_fini nouveau_object_fini @@ -28,16 +26,10 @@ extern struct nouveau_oclass nv44_ram_oclass; extern struct nouveau_oclass nv49_ram_oclass; extern struct nouveau_oclass nv4e_ram_oclass; extern struct nouveau_oclass nv50_ram_oclass; -extern struct nouveau_oclass nva3_ram_oclass; -extern struct nouveau_oclass nvaa_ram_oclass; extern struct nouveau_oclass nvc0_ram_oclass; -extern struct nouveau_oclass nve0_ram_oclass; -int nouveau_sddr3_calc(struct nouveau_ram *ram); -int nouveau_gddr5_calc(struct nouveau_ram *ram); - -#define nouveau_fb_create(p,e,c,d) \ - nouveau_fb_create_((p), (e), (c), sizeof(**d), (void **)d) +#define nouveau_fb_create(p,e,c,r,d) \ + nouveau_fb_create_((p), (e), (c), (r), sizeof(**d), (void **)d) #define nouveau_fb_destroy(p) ({ \ struct nouveau_fb *pfb = (p); \ _nouveau_fb_dtor(nv_object(pfb)); \ @@ -52,21 +44,44 @@ int nouveau_gddr5_calc(struct nouveau_ram *ram); }) int nouveau_fb_create_(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, int, void **); + struct nouveau_oclass *, struct nouveau_oclass *, + int length, void **pobject); void _nouveau_fb_dtor(struct nouveau_object *); int _nouveau_fb_init(struct nouveau_object *); int _nouveau_fb_fini(struct nouveau_object *, bool); -struct nouveau_fb_impl { - struct nouveau_oclass base; - struct nouveau_oclass *ram; - bool (*memtype)(struct nouveau_fb *, u32); -}; +struct nouveau_bios; +int nouveau_fb_bios_memtype(struct nouveau_bios *); bool nv04_fb_memtype_valid(struct nouveau_fb *, u32 memtype); -bool nv50_fb_memtype_valid(struct nouveau_fb *, u32 memtype); -struct nouveau_bios; -int nouveau_fb_bios_memtype(struct nouveau_bios *); +void nv10_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); +void nv10_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *); +void nv10_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); + +void nv20_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); +void nv20_fb_tile_fini(struct nouveau_fb *, int i, struct nouveau_fb_tile *); +void nv20_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); + +int nv30_fb_init(struct nouveau_object *); +void nv30_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); + +void nv40_fb_tile_comp(struct nouveau_fb *, int i, u32 size, u32 flags, + struct nouveau_fb_tile *); + +int nv41_fb_init(struct nouveau_object *); +void nv41_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); + +int nv44_fb_init(struct nouveau_object *); +void nv44_fb_tile_prog(struct nouveau_fb *, int, struct nouveau_fb_tile *); + +void nv46_fb_tile_init(struct nouveau_fb *, int i, u32 addr, u32 size, + u32 pitch, u32 flags, struct nouveau_fb_tile *); + +void __nv50_ram_put(struct nouveau_fb *, struct nouveau_mem *); +extern int nv50_fb_memtype[0x80]; #endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h deleted file mode 100644 index 0f57fcf..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h +++ /dev/null @@ -1,118 +0,0 @@ -#ifndef __NVKM_FBRAM_FUC_H__ -#define __NVKM_FBRAM_FUC_H__ - -#include <subdev/pwr.h> - -struct ramfuc { - struct nouveau_memx *memx; - struct nouveau_fb *pfb; - int sequence; -}; - -struct ramfuc_reg { - int sequence; - bool force; - u32 addr[2]; - u32 data; -}; - -static inline struct ramfuc_reg -ramfuc_reg2(u32 addr1, u32 addr2) -{ - return (struct ramfuc_reg) { - .sequence = 0, - .addr = { addr1, addr2 }, - .data = 0xdeadbeef, - }; -} - -static inline struct ramfuc_reg -ramfuc_reg(u32 addr) -{ - return ramfuc_reg2(addr, addr); -} - -static inline int -ramfuc_init(struct ramfuc *ram, struct nouveau_fb *pfb) -{ - struct nouveau_pwr *ppwr = nouveau_pwr(pfb); - int ret; - - ret = nouveau_memx_init(ppwr, &ram->memx); - if (ret) - return ret; - - ram->sequence++; - ram->pfb = pfb; - return 0; -} - -static inline int -ramfuc_exec(struct ramfuc *ram, bool exec) -{ - int ret = 0; - if (ram->pfb) { - ret = nouveau_memx_fini(&ram->memx, exec); - ram->pfb = NULL; - } - return ret; -} - -static inline u32 -ramfuc_rd32(struct ramfuc *ram, struct ramfuc_reg *reg) -{ - if (reg->sequence != ram->sequence) - reg->data = nv_rd32(ram->pfb, reg->addr[0]); - return reg->data; -} - -static inline void -ramfuc_wr32(struct ramfuc *ram, struct ramfuc_reg *reg, u32 data) -{ - reg->sequence = ram->sequence; - reg->data = data; - if (reg->addr[0] != reg->addr[1]) - nouveau_memx_wr32(ram->memx, reg->addr[1], reg->data); - nouveau_memx_wr32(ram->memx, reg->addr[0], reg->data); -} - -static inline void -ramfuc_nuke(struct ramfuc *ram, struct ramfuc_reg *reg) -{ - reg->force = true; -} - -static inline u32 -ramfuc_mask(struct ramfuc *ram, struct ramfuc_reg *reg, u32 mask, u32 data) -{ - u32 temp = ramfuc_rd32(ram, reg); - if (temp != ((temp & ~mask) | data) || reg->force) { - ramfuc_wr32(ram, reg, (temp & ~mask) | data); - reg->force = false; - } - return temp; -} - -static inline void -ramfuc_wait(struct ramfuc *ram, u32 addr, u32 mask, u32 data, u32 nsec) -{ - nouveau_memx_wait(ram->memx, addr, mask, data, nsec); -} - -static inline void -ramfuc_nsec(struct ramfuc *ram, u32 nsec) -{ - nouveau_memx_nsec(ram->memx, nsec); -} - -#define ram_init(s,p) ramfuc_init(&(s)->base, (p)) -#define ram_exec(s,e) ramfuc_exec(&(s)->base, (e)) -#define ram_have(s,r) ((s)->r_##r.addr != 0x000000) -#define ram_rd32(s,r) ramfuc_rd32(&(s)->base, &(s)->r_##r) -#define ram_wr32(s,r,d) ramfuc_wr32(&(s)->base, &(s)->r_##r, (d)) -#define ram_nuke(s,r) ramfuc_nuke(&(s)->base, &(s)->r_##r) -#define ram_mask(s,r,m,d) ramfuc_mask(&(s)->base, &(s)->r_##r, (m), (d)) -#define ram_wait(s,r,m,d,n) ramfuc_wait(&(s)->base, (r), (m), (d), (n)) -#define ram_nsec(s,n) ramfuc_nsec(&(s)->base, (n)) - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c index 7648beb..ee49ac4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv40.c @@ -22,154 +22,7 @@ * Authors: Ben Skeggs */ -#include <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/pll.h> -#include <subdev/bios/init.h> -#include <subdev/clock.h> -#include <subdev/clock/pll.h> -#include <subdev/timer.h> - -#include <engine/fifo.h> - -#include "nv40.h" - -int -nv40_ram_calc(struct nouveau_fb *pfb, u32 freq) -{ - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nv40_ram *ram = (void *)pfb->ram; - struct nvbios_pll pll; - int N1, M1, N2, M2; - int log2P, ret; - - ret = nvbios_pll_parse(bios, 0x04, &pll); - if (ret) { - nv_error(pfb, "mclk pll data not found\n"); - return ret; - } - - ret = nv04_pll_calc(nv_subdev(pfb), &pll, freq, - &N1, &M1, &N2, &M2, &log2P); - if (ret < 0) - return ret; - - ram->ctrl = 0x80000000 | (log2P << 16); - ram->ctrl |= min(pll.bias_p + log2P, (int)pll.max_p) << 20; - if (N2 == M2) { - ram->ctrl |= 0x00000100; - ram->coef = (N1 << 8) | M1; - } else { - ram->ctrl |= 0x40000000; - ram->coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1; - } - - return 0; -} - -int -nv40_ram_prog(struct nouveau_fb *pfb) -{ - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nv40_ram *ram = (void *)pfb->ram; - struct bit_entry M; - u32 crtc_mask = 0; - u8 sr1[2]; - int i; - - /* determine which CRTCs are active, fetch VGA_SR1 for each */ - for (i = 0; i < 2; i++) { - u32 vbl = nv_rd32(pfb, 0x600808 + (i * 0x2000)); - u32 cnt = 0; - do { - if (vbl != nv_rd32(pfb, 0x600808 + (i * 0x2000))) { - nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01); - sr1[i] = nv_rd08(pfb, 0x0c03c5 + (i * 0x2000)); - if (!(sr1[i] & 0x20)) - crtc_mask |= (1 << i); - break; - } - udelay(1); - } while (cnt++ < 32); - } - - /* wait for vblank start on active crtcs, disable memory access */ - for (i = 0; i < 2; i++) { - if (!(crtc_mask & (1 << i))) - continue; - nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000); - nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000); - nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01); - nv_wr08(pfb, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20); - } - - /* prepare ram for reclocking */ - nv_wr32(pfb, 0x1002d4, 0x00000001); /* precharge */ - nv_wr32(pfb, 0x1002d0, 0x00000001); /* refresh */ - nv_wr32(pfb, 0x1002d0, 0x00000001); /* refresh */ - nv_mask(pfb, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */ - nv_wr32(pfb, 0x1002dc, 0x00000001); /* enable self-refresh */ - - /* change the PLL of each memory partition */ - nv_mask(pfb, 0x00c040, 0x0000c000, 0x00000000); - switch (nv_device(pfb)->chipset) { - case 0x40: - case 0x45: - case 0x41: - case 0x42: - case 0x47: - nv_mask(pfb, 0x004044, 0xc0771100, ram->ctrl); - nv_mask(pfb, 0x00402c, 0xc0771100, ram->ctrl); - nv_wr32(pfb, 0x004048, ram->coef); - nv_wr32(pfb, 0x004030, ram->coef); - case 0x43: - case 0x49: - case 0x4b: - nv_mask(pfb, 0x004038, 0xc0771100, ram->ctrl); - nv_wr32(pfb, 0x00403c, ram->coef); - default: - nv_mask(pfb, 0x004020, 0xc0771100, ram->ctrl); - nv_wr32(pfb, 0x004024, ram->coef); - break; - } - udelay(100); - nv_mask(pfb, 0x00c040, 0x0000c000, 0x0000c000); - - /* re-enable normal operation of memory controller */ - nv_wr32(pfb, 0x1002dc, 0x00000000); - nv_mask(pfb, 0x100210, 0x80000000, 0x80000000); - udelay(100); - - /* execute memory reset script from vbios */ - if (!bit_entry(bios, 'M', &M)) { - struct nvbios_init init = { - .subdev = nv_subdev(pfb), - .bios = bios, - .offset = nv_ro16(bios, M.offset + 0x00), - .execute = 1, - }; - - nvbios_exec(&init); - } - - /* make sure we're in vblank (hopefully the same one as before), and - * then re-enable crtc memory access - */ - for (i = 0; i < 2; i++) { - if (!(crtc_mask & (1 << i))) - continue; - nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000); - nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01); - nv_wr08(pfb, 0x0c03c5 + (i * 0x2000), sr1[i]); - } - - return 0; -} - -void -nv40_ram_tidy(struct nouveau_fb *pfb) -{ -} +#include "priv.h" static int nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, @@ -177,7 +30,7 @@ nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_object **pobject) { struct nouveau_fb *pfb = nouveau_fb(parent); - struct nv40_ram *ram; + struct nouveau_ram *ram; u32 pbus1218 = nv_rd32(pfb, 0x001218); int ret; @@ -187,18 +40,15 @@ nv40_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, return ret; switch (pbus1218 & 0x00000300) { - case 0x00000000: ram->base.type = NV_MEM_TYPE_SDRAM; break; - case 0x00000100: ram->base.type = NV_MEM_TYPE_DDR1; break; - case 0x00000200: ram->base.type = NV_MEM_TYPE_GDDR3; break; - case 0x00000300: ram->base.type = NV_MEM_TYPE_DDR2; break; + case 0x00000000: ram->type = NV_MEM_TYPE_SDRAM; break; + case 0x00000100: ram->type = NV_MEM_TYPE_DDR1; break; + case 0x00000200: ram->type = NV_MEM_TYPE_GDDR3; break; + case 0x00000300: ram->type = NV_MEM_TYPE_DDR2; break; } - ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000; - ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; - ram->base.tags = nv_rd32(pfb, 0x100320); - ram->base.calc = nv40_ram_calc; - ram->base.prog = nv40_ram_prog; - ram->base.tidy = nv40_ram_tidy; + ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000; + ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; + ram->tags = nv_rd32(pfb, 0x100320); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c index d64498a..1dab7e1 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv41.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "nv40.h" +#include "priv.h" static int nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, @@ -30,7 +30,7 @@ nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_object **pobject) { struct nouveau_fb *pfb = nouveau_fb(parent); - struct nv40_ram *ram; + struct nouveau_ram *ram; u32 pfb474 = nv_rd32(pfb, 0x100474); int ret; @@ -40,18 +40,15 @@ nv41_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, return ret; if (pfb474 & 0x00000004) - ram->base.type = NV_MEM_TYPE_GDDR3; + ram->type = NV_MEM_TYPE_GDDR3; if (pfb474 & 0x00000002) - ram->base.type = NV_MEM_TYPE_DDR2; + ram->type = NV_MEM_TYPE_DDR2; if (pfb474 & 0x00000001) - ram->base.type = NV_MEM_TYPE_DDR1; + ram->type = NV_MEM_TYPE_DDR1; - ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000; - ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; - ram->base.tags = nv_rd32(pfb, 0x100320); - ram->base.calc = nv40_ram_calc; - ram->base.prog = nv40_ram_prog; - ram->base.tidy = nv40_ram_tidy; + ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000; + ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; + ram->tags = nv_rd32(pfb, 0x100320); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c index 089acac..25fff84 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv44.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "nv40.h" +#include "priv.h" static int nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, @@ -30,7 +30,7 @@ nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_object **pobject) { struct nouveau_fb *pfb = nouveau_fb(parent); - struct nv40_ram *ram; + struct nouveau_ram *ram; u32 pfb474 = nv_rd32(pfb, 0x100474); int ret; @@ -40,16 +40,13 @@ nv44_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, return ret; if (pfb474 & 0x00000004) - ram->base.type = NV_MEM_TYPE_GDDR3; + ram->type = NV_MEM_TYPE_GDDR3; if (pfb474 & 0x00000002) - ram->base.type = NV_MEM_TYPE_DDR2; + ram->type = NV_MEM_TYPE_DDR2; if (pfb474 & 0x00000001) - ram->base.type = NV_MEM_TYPE_DDR1; + ram->type = NV_MEM_TYPE_DDR1; - ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000; - ram->base.calc = nv40_ram_calc; - ram->base.prog = nv40_ram_prog; - ram->base.tidy = nv40_ram_tidy; + ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c index baa013a..ab7ef0a 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv49.c @@ -22,7 +22,7 @@ * Authors: Ben Skeggs */ -#include "nv40.h" +#include "priv.h" static int nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, @@ -30,7 +30,7 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_object **pobject) { struct nouveau_fb *pfb = nouveau_fb(parent); - struct nv40_ram *ram; + struct nouveau_ram *ram; u32 pfb914 = nv_rd32(pfb, 0x100914); int ret; @@ -40,18 +40,15 @@ nv49_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, return ret; switch (pfb914 & 0x00000003) { - case 0x00000000: ram->base.type = NV_MEM_TYPE_DDR1; break; - case 0x00000001: ram->base.type = NV_MEM_TYPE_DDR2; break; - case 0x00000002: ram->base.type = NV_MEM_TYPE_GDDR3; break; + case 0x00000000: ram->type = NV_MEM_TYPE_DDR1; break; + case 0x00000001: ram->type = NV_MEM_TYPE_DDR2; break; + case 0x00000002: ram->type = NV_MEM_TYPE_GDDR3; break; case 0x00000003: break; } - ram->base.size = nv_rd32(pfb, 0x10020c) & 0xff000000; - ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; - ram->base.tags = nv_rd32(pfb, 0x100320); - ram->base.calc = nv40_ram_calc; - ram->base.prog = nv40_ram_prog; - ram->base.tidy = nv40_ram_tidy; + ram->size = nv_rd32(pfb, 0x10020c) & 0xff000000; + ram->parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1; + ram->tags = nv_rd32(pfb, 0x100320); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c index 76762a1..903baff 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnv50.c @@ -23,215 +23,8 @@ */ #include <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/pll.h> -#include <subdev/bios/perf.h> -#include <subdev/bios/timing.h> -#include <subdev/clock/pll.h> -#include <subdev/fb.h> - -#include <core/option.h> #include <core/mm.h> - -#include "ramseq.h" - -#include "nv50.h" - -struct nv50_ramseq { - struct hwsq base; - struct hwsq_reg r_0x002504; - struct hwsq_reg r_0x004008; - struct hwsq_reg r_0x00400c; - struct hwsq_reg r_0x00c040; - struct hwsq_reg r_0x100210; - struct hwsq_reg r_0x1002d0; - struct hwsq_reg r_0x1002d4; - struct hwsq_reg r_0x1002dc; - struct hwsq_reg r_0x100da0[8]; - struct hwsq_reg r_0x100e20; - struct hwsq_reg r_0x100e24; - struct hwsq_reg r_0x611200; - struct hwsq_reg r_timing[9]; - struct hwsq_reg r_mr[4]; -}; - -struct nv50_ram { - struct nouveau_ram base; - struct nv50_ramseq hwsq; -}; - -#define QFX5800NVA0 1 - -static int -nv50_ram_calc(struct nouveau_fb *pfb, u32 freq) -{ - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nv50_ram *ram = (void *)pfb->ram; - struct nv50_ramseq *hwsq = &ram->hwsq; - struct nvbios_perfE perfE; - struct nvbios_pll mpll; - struct bit_entry M; - struct { - u32 data; - u8 size; - } ramcfg, timing; - u8 ver, hdr, cnt, strap; - u32 data; - int N1, M1, N2, M2, P; - int ret, i; - - /* lookup closest matching performance table entry for frequency */ - i = 0; - do { - ramcfg.data = nvbios_perfEp(bios, i++, &ver, &hdr, &cnt, - &ramcfg.size, &perfE); - if (!ramcfg.data || (ver < 0x25 || ver >= 0x40) || - (ramcfg.size < 2)) { - nv_error(pfb, "invalid/missing perftab entry\n"); - return -EINVAL; - } - } while (perfE.memory < freq); - - /* locate specific data set for the attached memory */ - if (bit_entry(bios, 'M', &M) || M.version != 1 || M.length < 5) { - nv_error(pfb, "invalid/missing memory table\n"); - return -EINVAL; - } - - strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2; - data = nv_ro16(bios, M.offset + 3); - if (data) - strap = nv_ro08(bios, data + strap); - - if (strap >= cnt) { - nv_error(pfb, "invalid ramcfg strap\n"); - return -EINVAL; - } - - ramcfg.data += hdr + (strap * ramcfg.size); - - /* lookup memory timings, if bios says they're present */ - strap = nv_ro08(bios, ramcfg.data + 0x01); - if (strap != 0xff) { - timing.data = nvbios_timing_entry(bios, strap, &ver, &hdr); - if (!timing.data || ver != 0x10 || hdr < 0x12) { - nv_error(pfb, "invalid/missing timing entry " - "%02x %04x %02x %02x\n", - strap, timing.data, ver, hdr); - return -EINVAL; - } - } else { - timing.data = 0; - } - - ret = ram_init(hwsq, nv_subdev(pfb)); - if (ret) - return ret; - - ram_wait(hwsq, 0x01, 0x00); /* wait for !vblank */ - ram_wait(hwsq, 0x01, 0x01); /* wait for vblank */ - ram_wr32(hwsq, 0x611200, 0x00003300); - ram_wr32(hwsq, 0x002504, 0x00000001); /* block fifo */ - ram_nsec(hwsq, 8000); - ram_setf(hwsq, 0x10, 0x00); /* disable fb */ - ram_wait(hwsq, 0x00, 0x01); /* wait for fb disabled */ - - ram_wr32(hwsq, 0x1002d4, 0x00000001); /* precharge */ - ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */ - ram_wr32(hwsq, 0x1002d0, 0x00000001); /* refresh */ - ram_wr32(hwsq, 0x100210, 0x00000000); /* disable auto-refresh */ - ram_wr32(hwsq, 0x1002dc, 0x00000001); /* enable self-refresh */ - - ret = nvbios_pll_parse(bios, 0x004008, &mpll); - mpll.vco2.max_freq = 0; - if (ret == 0) { - ret = nv04_pll_calc(nv_subdev(pfb), &mpll, freq, - &N1, &M1, &N2, &M2, &P); - if (ret == 0) - ret = -EINVAL; - } - - if (ret < 0) - return ret; - - ram_mask(hwsq, 0x00c040, 0xc000c000, 0x0000c000); - ram_mask(hwsq, 0x004008, 0x00000200, 0x00000200); - ram_mask(hwsq, 0x00400c, 0x0000ffff, (N1 << 8) | M1); - ram_mask(hwsq, 0x004008, 0x81ff0000, 0x80000000 | (mpll.bias_p << 19) | - (P << 22) | (P << 16)); -#if QFX5800NVA0 - for (i = 0; i < 8; i++) - ram_mask(hwsq, 0x100da0[i], 0x00000000, 0x00000000); /*XXX*/ -#endif - ram_nsec(hwsq, 96000); /*XXX*/ - ram_mask(hwsq, 0x004008, 0x00002200, 0x00002000); - - ram_wr32(hwsq, 0x1002dc, 0x00000000); /* disable self-refresh */ - ram_wr32(hwsq, 0x100210, 0x80000000); /* enable auto-refresh */ - - ram_nsec(hwsq, 12000); - - switch (ram->base.type) { - case NV_MEM_TYPE_DDR2: - ram_nuke(hwsq, mr[0]); /* force update */ - ram_mask(hwsq, mr[0], 0x000, 0x000); - break; - case NV_MEM_TYPE_GDDR3: - ram_mask(hwsq, mr[2], 0x000, 0x000); - ram_nuke(hwsq, mr[0]); /* force update */ - ram_mask(hwsq, mr[0], 0x000, 0x000); - break; - default: - break; - } - - ram_mask(hwsq, timing[3], 0x00000000, 0x00000000); /*XXX*/ - ram_mask(hwsq, timing[1], 0x00000000, 0x00000000); /*XXX*/ - ram_mask(hwsq, timing[6], 0x00000000, 0x00000000); /*XXX*/ - ram_mask(hwsq, timing[7], 0x00000000, 0x00000000); /*XXX*/ - ram_mask(hwsq, timing[8], 0x00000000, 0x00000000); /*XXX*/ - ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/ - ram_mask(hwsq, timing[2], 0x00000000, 0x00000000); /*XXX*/ - ram_mask(hwsq, timing[4], 0x00000000, 0x00000000); /*XXX*/ - ram_mask(hwsq, timing[5], 0x00000000, 0x00000000); /*XXX*/ - - ram_mask(hwsq, timing[0], 0x00000000, 0x00000000); /*XXX*/ - -#if QFX5800NVA0 - ram_nuke(hwsq, 0x100e24); - ram_mask(hwsq, 0x100e24, 0x00000000, 0x00000000); - ram_nuke(hwsq, 0x100e20); - ram_mask(hwsq, 0x100e20, 0x00000000, 0x00000000); -#endif - - ram_mask(hwsq, mr[0], 0x100, 0x100); - ram_mask(hwsq, mr[0], 0x100, 0x000); - - ram_setf(hwsq, 0x10, 0x01); /* enable fb */ - ram_wait(hwsq, 0x00, 0x00); /* wait for fb enabled */ - ram_wr32(hwsq, 0x611200, 0x00003330); - ram_wr32(hwsq, 0x002504, 0x00000000); /* un-block fifo */ - return 0; -} - -static int -nv50_ram_prog(struct nouveau_fb *pfb) -{ - struct nouveau_device *device = nv_device(pfb); - struct nv50_ram *ram = (void *)pfb->ram; - struct nv50_ramseq *hwsq = &ram->hwsq; - - ram_exec(hwsq, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); - return 0; -} - -static void -nv50_ram_tidy(struct nouveau_fb *pfb) -{ - struct nv50_ram *ram = (void *)pfb->ram; - struct nv50_ramseq *hwsq = &ram->hwsq; - ram_exec(hwsq, false); -} +#include "priv.h" void __nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem *mem) @@ -264,7 +57,7 @@ nv50_ram_put(struct nouveau_fb *pfb, struct nouveau_mem **pmem) kfree(mem); } -int +static int nv50_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, u32 memtype, struct nouveau_mem **pmem) { @@ -367,114 +160,77 @@ nv50_fb_vram_rblock(struct nouveau_fb *pfb, struct nouveau_ram *ram) return rblock_size; } -int -nv50_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, int length, void **pobject) +static int +nv50_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 datasize, + struct nouveau_object **pobject) { - const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ - const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ - struct nouveau_bios *bios = nouveau_bios(parent); struct nouveau_fb *pfb = nouveau_fb(parent); + struct nouveau_device *device = nv_device(pfb); + struct nouveau_bios *bios = nouveau_bios(device); struct nouveau_ram *ram; + const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ + const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ + u32 size; int ret; - ret = nouveau_ram_create_(parent, engine, oclass, length, pobject); - ram = *pobject; + ret = nouveau_ram_create(parent, engine, oclass, &ram); + *pobject = nv_object(ram); if (ret) return ret; ram->size = nv_rd32(pfb, 0x10020c); - ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32); + ram->size = (ram->size & 0xffffff00) | + ((ram->size & 0x000000ff) << 32); + + size = (ram->size >> 12) - rsvd_head - rsvd_tail; + switch (device->chipset) { + case 0xaa: + case 0xac: + case 0xaf: /* IGPs, no reordering, no real VRAM */ + ret = nouveau_mm_init(&pfb->vram, rsvd_head, size, 1); + if (ret) + return ret; - switch (nv_rd32(pfb, 0x100714) & 0x00000007) { - case 0: ram->type = NV_MEM_TYPE_DDR1; break; - case 1: - if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3) - ram->type = NV_MEM_TYPE_DDR3; - else - ram->type = NV_MEM_TYPE_DDR2; + ram->type = NV_MEM_TYPE_STOLEN; + ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; break; - case 2: ram->type = NV_MEM_TYPE_GDDR3; break; - case 3: ram->type = NV_MEM_TYPE_GDDR4; break; - case 4: ram->type = NV_MEM_TYPE_GDDR5; break; default: - break; - } - - ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) - - (rsvd_head + rsvd_tail), - nv50_fb_vram_rblock(pfb, ram) >> 12); - if (ret) - return ret; - - ram->ranks = (nv_rd32(pfb, 0x100200) & 0x4) ? 2 : 1; - ram->tags = nv_rd32(pfb, 0x100320); - ram->get = nv50_ram_get; - ram->put = nv50_ram_put; - return 0; -} - -static int -nv50_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 datasize, - struct nouveau_object **pobject) -{ - struct nv50_ram *ram; - int ret, i; + switch (nv_rd32(pfb, 0x100714) & 0x00000007) { + case 0: ram->type = NV_MEM_TYPE_DDR1; break; + case 1: + if (nouveau_fb_bios_memtype(bios) == NV_MEM_TYPE_DDR3) + ram->type = NV_MEM_TYPE_DDR3; + else + ram->type = NV_MEM_TYPE_DDR2; + break; + case 2: ram->type = NV_MEM_TYPE_GDDR3; break; + case 3: ram->type = NV_MEM_TYPE_GDDR4; break; + case 4: ram->type = NV_MEM_TYPE_GDDR5; break; + default: + break; + } - ret = nv50_ram_create(parent, engine, oclass, &ram); - *pobject = nv_object(ram); - if (ret) - return ret; + ret = nouveau_mm_init(&pfb->vram, rsvd_head, size, + nv50_fb_vram_rblock(pfb, ram) >> 12); + if (ret) + return ret; - switch (ram->base.type) { - case NV_MEM_TYPE_DDR2: - case NV_MEM_TYPE_GDDR3: - ram->base.calc = nv50_ram_calc; - ram->base.prog = nv50_ram_prog; - ram->base.tidy = nv50_ram_tidy; + ram->ranks = (nv_rd32(pfb, 0x100200) & 0x4) ? 2 : 1; + ram->tags = nv_rd32(pfb, 0x100320); break; - default: - nv_warn(ram, "reclocking of this ram type unsupported\n"); - return 0; - } - - ram->hwsq.r_0x002504 = hwsq_reg(0x002504); - ram->hwsq.r_0x00c040 = hwsq_reg(0x00c040); - ram->hwsq.r_0x004008 = hwsq_reg(0x004008); - ram->hwsq.r_0x00400c = hwsq_reg(0x00400c); - ram->hwsq.r_0x100210 = hwsq_reg(0x100210); - ram->hwsq.r_0x1002d0 = hwsq_reg(0x1002d0); - ram->hwsq.r_0x1002d4 = hwsq_reg(0x1002d4); - ram->hwsq.r_0x1002dc = hwsq_reg(0x1002dc); - for (i = 0; i < 8; i++) - ram->hwsq.r_0x100da0[i] = hwsq_reg(0x100da0 + (i * 0x04)); - ram->hwsq.r_0x100e20 = hwsq_reg(0x100e20); - ram->hwsq.r_0x100e24 = hwsq_reg(0x100e24); - ram->hwsq.r_0x611200 = hwsq_reg(0x611200); - - for (i = 0; i < 9; i++) - ram->hwsq.r_timing[i] = hwsq_reg(0x100220 + (i * 0x04)); - - if (ram->base.ranks > 1) { - ram->hwsq.r_mr[0] = hwsq_reg2(0x1002c0, 0x1002c8); - ram->hwsq.r_mr[1] = hwsq_reg2(0x1002c4, 0x1002cc); - ram->hwsq.r_mr[2] = hwsq_reg2(0x1002e0, 0x1002e8); - ram->hwsq.r_mr[3] = hwsq_reg2(0x1002e4, 0x1002ec); - } else { - ram->hwsq.r_mr[0] = hwsq_reg(0x1002c0); - ram->hwsq.r_mr[1] = hwsq_reg(0x1002c4); - ram->hwsq.r_mr[2] = hwsq_reg(0x1002e0); - ram->hwsq.r_mr[3] = hwsq_reg(0x1002e4); } + ram->get = nv50_ram_get; + ram->put = nv50_ram_put; return 0; } struct nouveau_oclass nv50_ram_oclass = { + .handle = 0, .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv50_ram_ctor, + .ctor = nv50_ram_create, .dtor = _nouveau_ram_dtor, .init = _nouveau_ram_init, .fini = _nouveau_ram_fini, diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c deleted file mode 100644 index f6292cd..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c +++ /dev/null @@ -1,447 +0,0 @@ -/* - * 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 <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/pll.h> -#include <subdev/bios/rammap.h> -#include <subdev/bios/timing.h> - -#include <subdev/clock/nva3.h> -#include <subdev/clock/pll.h> - -#include <core/option.h> - -#include "ramfuc.h" - -#include "nv50.h" - -struct nva3_ramfuc { - struct ramfuc base; - struct ramfuc_reg r_0x004000; - struct ramfuc_reg r_0x004004; - struct ramfuc_reg r_0x004018; - struct ramfuc_reg r_0x004128; - struct ramfuc_reg r_0x004168; - struct ramfuc_reg r_0x100200; - struct ramfuc_reg r_0x100210; - struct ramfuc_reg r_0x100220[9]; - struct ramfuc_reg r_0x1002d0; - struct ramfuc_reg r_0x1002d4; - struct ramfuc_reg r_0x1002dc; - struct ramfuc_reg r_0x10053c; - struct ramfuc_reg r_0x1005a0; - struct ramfuc_reg r_0x1005a4; - struct ramfuc_reg r_0x100714; - struct ramfuc_reg r_0x100718; - struct ramfuc_reg r_0x10071c; - struct ramfuc_reg r_0x100760; - struct ramfuc_reg r_0x1007a0; - struct ramfuc_reg r_0x1007e0; - struct ramfuc_reg r_0x10f804; - struct ramfuc_reg r_0x1110e0; - struct ramfuc_reg r_0x111100; - struct ramfuc_reg r_0x111104; - struct ramfuc_reg r_0x611200; - struct ramfuc_reg r_mr[4]; -}; - -struct nva3_ram { - struct nouveau_ram base; - struct nva3_ramfuc fuc; -}; - -static int -nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) -{ - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nva3_ram *ram = (void *)pfb->ram; - struct nva3_ramfuc *fuc = &ram->fuc; - struct nva3_clock_info mclk; - struct bit_entry M; - u8 ver, cnt, strap; - u32 data; - struct { - u32 data; - u8 size; - } rammap, ramcfg, timing; - u32 r004018, r100760, ctrl; - u32 unk714, unk718, unk71c; - int ret; - - /* lookup memory config data relevant to the target frequency */ - rammap.data = nvbios_rammap_match(bios, freq / 1000, &ver, &rammap.size, - &cnt, &ramcfg.size); - if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) { - nv_error(pfb, "invalid/missing rammap entry\n"); - return -EINVAL; - } - - /* locate specific data set for the attached memory */ - if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) { - nv_error(pfb, "invalid/missing memory table\n"); - return -EINVAL; - } - - strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2; - data = nv_ro16(bios, M.offset + 1); - if (data) - strap = nv_ro08(bios, data + strap); - - if (strap >= cnt) { - nv_error(pfb, "invalid ramcfg strap\n"); - return -EINVAL; - } - - ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size); - if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) { - nv_error(pfb, "invalid/missing ramcfg entry\n"); - return -EINVAL; - } - - /* lookup memory timings, if bios says they're present */ - strap = nv_ro08(bios, ramcfg.data + 0x01); - if (strap != 0xff) { - timing.data = nvbios_timing_entry(bios, strap, &ver, - &timing.size); - if (!timing.data || ver != 0x10 || timing.size < 0x19) { - nv_error(pfb, "invalid/missing timing entry\n"); - return -EINVAL; - } - } else { - timing.data = 0; - } - - ret = nva3_clock_info(nouveau_clock(pfb), 0x12, 0x4000, freq, &mclk); - if (ret < 0) { - nv_error(pfb, "failed mclk calculation\n"); - return ret; - } - - ret = ram_init(fuc, pfb); - if (ret) - return ret; - - /* XXX: where the fuck does 750MHz come from? */ - if (freq <= 750000) { - r004018 = 0x10000000; - r100760 = 0x22222222; - } else { - r004018 = 0x00000000; - r100760 = 0x00000000; - } - - ctrl = ram_rd32(fuc, 0x004000); - if (ctrl & 0x00000008) { - if (mclk.pll) { - ram_mask(fuc, 0x004128, 0x00000101, 0x00000101); - ram_wr32(fuc, 0x004004, mclk.pll); - ram_wr32(fuc, 0x004000, (ctrl |= 0x00000001)); - ram_wr32(fuc, 0x004000, (ctrl &= 0xffffffef)); - ram_wait(fuc, 0x004000, 0x00020000, 0x00020000, 64000); - ram_wr32(fuc, 0x004000, (ctrl |= 0x00000010)); - ram_wr32(fuc, 0x004018, 0x00005000 | r004018); - ram_wr32(fuc, 0x004000, (ctrl |= 0x00000004)); - } - } else { - u32 ssel = 0x00000101; - if (mclk.clk) - ssel |= mclk.clk; - else - ssel |= 0x00080000; /* 324MHz, shouldn't matter... */ - ram_mask(fuc, 0x004168, 0x003f3141, ctrl); - } - - if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) { - ram_mask(fuc, 0x111104, 0x00000600, 0x00000000); - } else { - ram_mask(fuc, 0x111100, 0x40000000, 0x40000000); - ram_mask(fuc, 0x111104, 0x00000180, 0x00000000); - } - - if (!(nv_ro08(bios, rammap.data + 0x04) & 0x02)) - ram_mask(fuc, 0x100200, 0x00000800, 0x00000000); - ram_wr32(fuc, 0x611200, 0x00003300); - if (!(nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) - ram_wr32(fuc, 0x111100, 0x4c020000); /*XXX*/ - - ram_wr32(fuc, 0x1002d4, 0x00000001); - ram_wr32(fuc, 0x1002d0, 0x00000001); - ram_wr32(fuc, 0x1002d0, 0x00000001); - ram_wr32(fuc, 0x100210, 0x00000000); - ram_wr32(fuc, 0x1002dc, 0x00000001); - ram_nsec(fuc, 2000); - - ctrl = ram_rd32(fuc, 0x004000); - if (!(ctrl & 0x00000008) && mclk.pll) { - ram_wr32(fuc, 0x004000, (ctrl |= 0x00000008)); - ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000); - ram_wr32(fuc, 0x004018, 0x00001000); - ram_wr32(fuc, 0x004000, (ctrl &= ~0x00000001)); - ram_wr32(fuc, 0x004004, mclk.pll); - ram_wr32(fuc, 0x004000, (ctrl |= 0x00000001)); - udelay(64); - ram_wr32(fuc, 0x004018, 0x00005000 | r004018); - udelay(20); - } else - if (!mclk.pll) { - ram_mask(fuc, 0x004168, 0x003f3040, mclk.clk); - ram_wr32(fuc, 0x004000, (ctrl |= 0x00000008)); - ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000); - ram_wr32(fuc, 0x004018, 0x0000d000 | r004018); - } - - if ( (nv_ro08(bios, rammap.data + 0x04) & 0x08)) { - u32 unk5a0 = (nv_ro16(bios, ramcfg.data + 0x05) << 8) | - nv_ro08(bios, ramcfg.data + 0x05); - u32 unk5a4 = (nv_ro16(bios, ramcfg.data + 0x07)); - u32 unk804 = (nv_ro08(bios, ramcfg.data + 0x09) & 0xf0) << 16 | - (nv_ro08(bios, ramcfg.data + 0x03) & 0x0f) << 16 | - (nv_ro08(bios, ramcfg.data + 0x09) & 0x0f) | - 0x80000000; - ram_wr32(fuc, 0x1005a0, unk5a0); - ram_wr32(fuc, 0x1005a4, unk5a4); - ram_wr32(fuc, 0x10f804, unk804); - ram_mask(fuc, 0x10053c, 0x00001000, 0x00000000); - } else { - ram_mask(fuc, 0x10053c, 0x00001000, 0x00001000); - ram_mask(fuc, 0x10f804, 0x80000000, 0x00000000); - ram_mask(fuc, 0x100760, 0x22222222, r100760); - ram_mask(fuc, 0x1007a0, 0x22222222, r100760); - ram_mask(fuc, 0x1007e0, 0x22222222, r100760); - } - - if (mclk.pll) { - ram_mask(fuc, 0x1110e0, 0x00088000, 0x00011000); - ram_wr32(fuc, 0x004000, (ctrl &= ~0x00000008)); - } - - /*XXX: LEAVE */ - ram_wr32(fuc, 0x1002dc, 0x00000000); - ram_wr32(fuc, 0x1002d4, 0x00000001); - ram_wr32(fuc, 0x100210, 0x80000000); - ram_nsec(fuc, 1000); - ram_nsec(fuc, 1000); - - ram_mask(fuc, mr[2], 0x00000000, 0x00000000); - ram_nsec(fuc, 1000); - ram_nuke(fuc, mr[0]); - ram_mask(fuc, mr[0], 0x00000000, 0x00000000); - ram_nsec(fuc, 1000); - - ram_mask(fuc, 0x100220[3], 0x00000000, 0x00000000); - ram_mask(fuc, 0x100220[1], 0x00000000, 0x00000000); - ram_mask(fuc, 0x100220[6], 0x00000000, 0x00000000); - ram_mask(fuc, 0x100220[7], 0x00000000, 0x00000000); - ram_mask(fuc, 0x100220[2], 0x00000000, 0x00000000); - ram_mask(fuc, 0x100220[4], 0x00000000, 0x00000000); - ram_mask(fuc, 0x100220[5], 0x00000000, 0x00000000); - ram_mask(fuc, 0x100220[0], 0x00000000, 0x00000000); - ram_mask(fuc, 0x100220[8], 0x00000000, 0x00000000); - - data = (nv_ro08(bios, ramcfg.data + 0x02) & 0x08) ? 0x00000000 : 0x00001000; - ram_mask(fuc, 0x100200, 0x00001000, data); - - unk714 = ram_rd32(fuc, 0x100714) & ~0xf0000010; - unk718 = ram_rd32(fuc, 0x100718) & ~0x00000100; - unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100; - if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x20)) - unk714 |= 0xf0000000; - if (!(nv_ro08(bios, ramcfg.data + 0x02) & 0x04)) - unk714 |= 0x00000010; - ram_wr32(fuc, 0x100714, unk714); - - if (nv_ro08(bios, ramcfg.data + 0x02) & 0x01) - unk71c |= 0x00000100; - ram_wr32(fuc, 0x10071c, unk71c); - - if (nv_ro08(bios, ramcfg.data + 0x02) & 0x02) - unk718 |= 0x00000100; - ram_wr32(fuc, 0x100718, unk718); - - if (nv_ro08(bios, ramcfg.data + 0x02) & 0x10) - ram_wr32(fuc, 0x111100, 0x48000000); /*XXX*/ - - ram_mask(fuc, mr[0], 0x100, 0x100); - ram_nsec(fuc, 1000); - ram_mask(fuc, mr[0], 0x100, 0x000); - ram_nsec(fuc, 1000); - - ram_nsec(fuc, 2000); - ram_nsec(fuc, 12000); - - ram_wr32(fuc, 0x611200, 0x00003330); - if ( (nv_ro08(bios, rammap.data + 0x04) & 0x02)) - ram_mask(fuc, 0x100200, 0x00000800, 0x00000800); - if ( (nv_ro08(bios, ramcfg.data + 0x02) & 0x10)) { - ram_mask(fuc, 0x111104, 0x00000180, 0x00000180); - ram_mask(fuc, 0x111100, 0x40000000, 0x00000000); - } else { - ram_mask(fuc, 0x111104, 0x00000600, 0x00000600); - } - - if (mclk.pll) { - ram_mask(fuc, 0x004168, 0x00000001, 0x00000000); - ram_mask(fuc, 0x004168, 0x00000100, 0x00000000); - } else { - ram_mask(fuc, 0x004000, 0x00000001, 0x00000000); - ram_mask(fuc, 0x004128, 0x00000001, 0x00000000); - ram_mask(fuc, 0x004128, 0x00000100, 0x00000000); - } - - return 0; -} - -static int -nva3_ram_prog(struct nouveau_fb *pfb) -{ - struct nouveau_device *device = nv_device(pfb); - struct nva3_ram *ram = (void *)pfb->ram; - struct nva3_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); - return 0; -} - -static void -nva3_ram_tidy(struct nouveau_fb *pfb) -{ - struct nva3_ram *ram = (void *)pfb->ram; - struct nva3_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, false); -} - -static int -nva3_ram_init(struct nouveau_object *object) -{ - struct nouveau_fb *pfb = (void *)object->parent; - struct nva3_ram *ram = (void *)object; - int ret, i; - - ret = nouveau_ram_init(&ram->base); - if (ret) - return ret; - - /* prepare for ddr link training, and load training patterns */ - switch (ram->base.type) { - case NV_MEM_TYPE_DDR3: { - static const u32 pattern[16] = { - 0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee, - 0x00000000, 0x11111111, 0x44444444, 0xdddddddd, - 0x33333333, 0x55555555, 0x77777777, 0x66666666, - 0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb, - }; - - nv_wr32(pfb, 0x100538, 0x10001ff6); /*XXX*/ - nv_wr32(pfb, 0x1005a8, 0x0000ffff); - nv_mask(pfb, 0x10f800, 0x00000001, 0x00000001); - for (i = 0; i < 0x30; i++) { - nv_wr32(pfb, 0x10f8c0, (i << 8) | i); - nv_wr32(pfb, 0x10f8e0, (i << 8) | i); - nv_wr32(pfb, 0x10f900, pattern[i % 16]); - nv_wr32(pfb, 0x10f920, pattern[i % 16]); - } - } - break; - default: - break; - } - - return 0; -} - -static int -nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 datasize, - struct nouveau_object **pobject) -{ - struct nva3_ram *ram; - int ret, i; - - ret = nv50_ram_create(parent, engine, oclass, &ram); - *pobject = nv_object(ram); - if (ret) - return ret; - - switch (ram->base.type) { - case NV_MEM_TYPE_DDR3: - ram->base.calc = nva3_ram_calc; - ram->base.prog = nva3_ram_prog; - ram->base.tidy = nva3_ram_tidy; - break; - default: - nv_warn(ram, "reclocking of this ram type unsupported\n"); - return 0; - } - - ram->fuc.r_0x004000 = ramfuc_reg(0x004000); - ram->fuc.r_0x004004 = ramfuc_reg(0x004004); - ram->fuc.r_0x004018 = ramfuc_reg(0x004018); - ram->fuc.r_0x004128 = ramfuc_reg(0x004128); - ram->fuc.r_0x004168 = ramfuc_reg(0x004168); - ram->fuc.r_0x100200 = ramfuc_reg(0x100200); - ram->fuc.r_0x100210 = ramfuc_reg(0x100210); - for (i = 0; i < 9; i++) - ram->fuc.r_0x100220[i] = ramfuc_reg(0x100220 + (i * 4)); - ram->fuc.r_0x1002d0 = ramfuc_reg(0x1002d0); - ram->fuc.r_0x1002d4 = ramfuc_reg(0x1002d4); - ram->fuc.r_0x1002dc = ramfuc_reg(0x1002dc); - ram->fuc.r_0x10053c = ramfuc_reg(0x10053c); - ram->fuc.r_0x1005a0 = ramfuc_reg(0x1005a0); - ram->fuc.r_0x1005a4 = ramfuc_reg(0x1005a4); - ram->fuc.r_0x100714 = ramfuc_reg(0x100714); - ram->fuc.r_0x100718 = ramfuc_reg(0x100718); - ram->fuc.r_0x10071c = ramfuc_reg(0x10071c); - ram->fuc.r_0x100760 = ramfuc_reg(0x100760); - ram->fuc.r_0x1007a0 = ramfuc_reg(0x1007a0); - ram->fuc.r_0x1007e0 = ramfuc_reg(0x1007e0); - ram->fuc.r_0x10f804 = ramfuc_reg(0x10f804); - ram->fuc.r_0x1110e0 = ramfuc_reg(0x1110e0); - ram->fuc.r_0x111100 = ramfuc_reg(0x111100); - ram->fuc.r_0x111104 = ramfuc_reg(0x111104); - ram->fuc.r_0x611200 = ramfuc_reg(0x611200); - - if (ram->base.ranks > 1) { - ram->fuc.r_mr[0] = ramfuc_reg2(0x1002c0, 0x1002c8); - ram->fuc.r_mr[1] = ramfuc_reg2(0x1002c4, 0x1002cc); - ram->fuc.r_mr[2] = ramfuc_reg2(0x1002e0, 0x1002e8); - ram->fuc.r_mr[3] = ramfuc_reg2(0x1002e4, 0x1002ec); - } else { - ram->fuc.r_mr[0] = ramfuc_reg(0x1002c0); - ram->fuc.r_mr[1] = ramfuc_reg(0x1002c4); - ram->fuc.r_mr[2] = ramfuc_reg(0x1002e0); - ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4); - } - - return 0; -} - -struct nouveau_oclass -nva3_ram_oclass = { - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nva3_ram_ctor, - .dtor = _nouveau_ram_dtor, - .init = nva3_ram_init, - .fini = _nouveau_ram_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c deleted file mode 100644 index 00f2ca7..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * 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 "nv50.h" - -static int -nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 datasize, - struct nouveau_object **pobject) -{ - const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ - const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ - struct nouveau_fb *pfb = nouveau_fb(parent); - struct nouveau_ram *ram; - int ret; - - ret = nouveau_ram_create(parent, engine, oclass, &ram); - *pobject = nv_object(ram); - if (ret) - return ret; - - ram->size = nv_rd32(pfb, 0x10020c); - ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32); - - ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) - - (rsvd_head + rsvd_tail), 1); - if (ret) - return ret; - - ram->type = NV_MEM_TYPE_STOLEN; - ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; - ram->get = nv50_ram_get; - ram->put = nv50_ram_put; - return 0; -} - -struct nouveau_oclass -nvaa_ram_oclass = { - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvaa_ram_ctor, - .dtor = _nouveau_ram_dtor, - .init = _nouveau_ram_init, - .fini = _nouveau_ram_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c index f464547..cf97c4d 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvc0.c @@ -23,414 +23,9 @@ */ #include <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/pll.h> -#include <subdev/bios/rammap.h> -#include <subdev/bios/timing.h> #include <subdev/ltcg.h> -#include <subdev/clock.h> -#include <subdev/clock/pll.h> - -#include <core/option.h> - -#include "ramfuc.h" - -#include "nvc0.h" - -struct nvc0_ramfuc { - struct ramfuc base; - - struct ramfuc_reg r_0x10fe20; - struct ramfuc_reg r_0x10fe24; - struct ramfuc_reg r_0x137320; - struct ramfuc_reg r_0x137330; - - struct ramfuc_reg r_0x132000; - struct ramfuc_reg r_0x132004; - struct ramfuc_reg r_0x132100; - - struct ramfuc_reg r_0x137390; - - struct ramfuc_reg r_0x10f290; - struct ramfuc_reg r_0x10f294; - struct ramfuc_reg r_0x10f298; - struct ramfuc_reg r_0x10f29c; - struct ramfuc_reg r_0x10f2a0; - - struct ramfuc_reg r_0x10f300; - struct ramfuc_reg r_0x10f338; - struct ramfuc_reg r_0x10f340; - struct ramfuc_reg r_0x10f344; - struct ramfuc_reg r_0x10f348; - - struct ramfuc_reg r_0x10f910; - struct ramfuc_reg r_0x10f914; - - struct ramfuc_reg r_0x100b0c; - struct ramfuc_reg r_0x10f050; - struct ramfuc_reg r_0x10f090; - struct ramfuc_reg r_0x10f200; - struct ramfuc_reg r_0x10f210; - struct ramfuc_reg r_0x10f310; - struct ramfuc_reg r_0x10f314; - struct ramfuc_reg r_0x10f610; - struct ramfuc_reg r_0x10f614; - struct ramfuc_reg r_0x10f800; - struct ramfuc_reg r_0x10f808; - struct ramfuc_reg r_0x10f824; - struct ramfuc_reg r_0x10f830; - struct ramfuc_reg r_0x10f988; - struct ramfuc_reg r_0x10f98c; - struct ramfuc_reg r_0x10f990; - struct ramfuc_reg r_0x10f998; - struct ramfuc_reg r_0x10f9b0; - struct ramfuc_reg r_0x10f9b4; - struct ramfuc_reg r_0x10fb04; - struct ramfuc_reg r_0x10fb08; - struct ramfuc_reg r_0x137300; - struct ramfuc_reg r_0x137310; - struct ramfuc_reg r_0x137360; - struct ramfuc_reg r_0x1373ec; - struct ramfuc_reg r_0x1373f0; - struct ramfuc_reg r_0x1373f8; - - struct ramfuc_reg r_0x61c140; - struct ramfuc_reg r_0x611200; - - struct ramfuc_reg r_0x13d8f4; -}; - -struct nvc0_ram { - struct nouveau_ram base; - struct nvc0_ramfuc fuc; - struct nvbios_pll refpll; - struct nvbios_pll mempll; -}; - -static void -nvc0_ram_train(struct nvc0_ramfuc *fuc, u32 magic) -{ - struct nvc0_ram *ram = container_of(fuc, typeof(*ram), fuc); - struct nouveau_fb *pfb = nouveau_fb(ram); - u32 part = nv_rd32(pfb, 0x022438), i; - u32 mask = nv_rd32(pfb, 0x022554); - u32 addr = 0x110974; - - ram_wr32(fuc, 0x10f910, magic); - ram_wr32(fuc, 0x10f914, magic); - - for (i = 0; (magic & 0x80000000) && i < part; addr += 0x1000, i++) { - if (mask & (1 << i)) - continue; - ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000); - } -} - -static int -nvc0_ram_calc(struct nouveau_fb *pfb, u32 freq) -{ - struct nouveau_clock *clk = nouveau_clock(pfb); - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nvc0_ram *ram = (void *)pfb->ram; - struct nvc0_ramfuc *fuc = &ram->fuc; - struct bit_entry M; - u8 ver, cnt, strap; - u32 data; - struct { - u32 data; - u8 size; - } rammap, ramcfg, timing; - int ref, div, out; - int from, mode; - int N1, M1, P; - int ret; - - /* lookup memory config data relevant to the target frequency */ - rammap.data = nvbios_rammap_match(bios, freq / 1000, &ver, &rammap.size, - &cnt, &ramcfg.size); - if (!rammap.data || ver != 0x10 || rammap.size < 0x0e) { - nv_error(pfb, "invalid/missing rammap entry\n"); - return -EINVAL; - } - - /* locate specific data set for the attached memory */ - if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) { - nv_error(pfb, "invalid/missing memory table\n"); - return -EINVAL; - } - - strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2; - data = nv_ro16(bios, M.offset + 1); - if (data) - strap = nv_ro08(bios, data + strap); - - if (strap >= cnt) { - nv_error(pfb, "invalid ramcfg strap\n"); - return -EINVAL; - } - - ramcfg.data = rammap.data + rammap.size + (strap * ramcfg.size); - if (!ramcfg.data || ver != 0x10 || ramcfg.size < 0x0e) { - nv_error(pfb, "invalid/missing ramcfg entry\n"); - return -EINVAL; - } - - /* lookup memory timings, if bios says they're present */ - strap = nv_ro08(bios, ramcfg.data + 0x01); - if (strap != 0xff) { - timing.data = nvbios_timing_entry(bios, strap, &ver, - &timing.size); - if (!timing.data || ver != 0x10 || timing.size < 0x19) { - nv_error(pfb, "invalid/missing timing entry\n"); - return -EINVAL; - } - } else { - timing.data = 0; - } - - ret = ram_init(fuc, pfb); - if (ret) - return ret; - - /* determine current mclk configuration */ - from = !!(ram_rd32(fuc, 0x1373f0) & 0x00000002); /*XXX: ok? */ - - /* determine target mclk configuration */ - if (!(ram_rd32(fuc, 0x137300) & 0x00000100)) - ref = clk->read(clk, nv_clk_src_sppll0); - else - ref = clk->read(clk, nv_clk_src_sppll1); - div = max(min((ref * 2) / freq, (u32)65), (u32)2) - 2; - out = (ref * 2) / (div + 2); - mode = freq != out; - - ram_mask(fuc, 0x137360, 0x00000002, 0x00000000); - - if ((ram_rd32(fuc, 0x132000) & 0x00000002) || 0 /*XXX*/) { - ram_nuke(fuc, 0x132000); - ram_mask(fuc, 0x132000, 0x00000002, 0x00000002); - ram_mask(fuc, 0x132000, 0x00000002, 0x00000000); - } - - if (mode == 1) { - ram_nuke(fuc, 0x10fe20); - ram_mask(fuc, 0x10fe20, 0x00000002, 0x00000002); - ram_mask(fuc, 0x10fe20, 0x00000002, 0x00000000); - } - -// 0x00020034 // 0x0000000a - ram_wr32(fuc, 0x132100, 0x00000001); - - if (mode == 1 && from == 0) { - /* calculate refpll */ - ret = nva3_pll_calc(nv_subdev(pfb), &ram->refpll, - ram->mempll.refclk, &N1, NULL, &M1, &P); - if (ret <= 0) { - nv_error(pfb, "unable to calc refpll\n"); - return ret ? ret : -ERANGE; - } - - ram_wr32(fuc, 0x10fe20, 0x20010000); - ram_wr32(fuc, 0x137320, 0x00000003); - ram_wr32(fuc, 0x137330, 0x81200006); - ram_wr32(fuc, 0x10fe24, (P << 16) | (N1 << 8) | M1); - ram_wr32(fuc, 0x10fe20, 0x20010001); - ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000); - - /* calculate mempll */ - ret = nva3_pll_calc(nv_subdev(pfb), &ram->mempll, freq, - &N1, NULL, &M1, &P); - if (ret <= 0) { - nv_error(pfb, "unable to calc refpll\n"); - return ret ? ret : -ERANGE; - } - - ram_wr32(fuc, 0x10fe20, 0x20010005); - ram_wr32(fuc, 0x132004, (P << 16) | (N1 << 8) | M1); - ram_wr32(fuc, 0x132000, 0x18010101); - ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000); - } else - if (mode == 0) { - ram_wr32(fuc, 0x137300, 0x00000003); - } - - if (from == 0) { - ram_nuke(fuc, 0x10fb04); - ram_mask(fuc, 0x10fb04, 0x0000ffff, 0x00000000); - ram_nuke(fuc, 0x10fb08); - ram_mask(fuc, 0x10fb08, 0x0000ffff, 0x00000000); - ram_wr32(fuc, 0x10f988, 0x2004ff00); - ram_wr32(fuc, 0x10f98c, 0x003fc040); - ram_wr32(fuc, 0x10f990, 0x20012001); - ram_wr32(fuc, 0x10f998, 0x00011a00); - ram_wr32(fuc, 0x13d8f4, 0x00000000); - } else { - ram_wr32(fuc, 0x10f988, 0x20010000); - ram_wr32(fuc, 0x10f98c, 0x00000000); - ram_wr32(fuc, 0x10f990, 0x20012001); - ram_wr32(fuc, 0x10f998, 0x00010a00); - } - - if (from == 0) { -// 0x00020039 // 0x000000ba - } - -// 0x0002003a // 0x00000002 - ram_wr32(fuc, 0x100b0c, 0x00080012); -// 0x00030014 // 0x00000000 // 0x02b5f070 -// 0x00030014 // 0x00010000 // 0x02b5f070 - ram_wr32(fuc, 0x611200, 0x00003300); -// 0x00020034 // 0x0000000a -// 0x00030020 // 0x00000001 // 0x00000000 - - ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000); - ram_wr32(fuc, 0x10f210, 0x00000000); - ram_nsec(fuc, 1000); - if (mode == 0) - nvc0_ram_train(fuc, 0x000c1001); - ram_wr32(fuc, 0x10f310, 0x00000001); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f090, 0x00000061); - ram_wr32(fuc, 0x10f090, 0xc000007f); - ram_nsec(fuc, 1000); - - if (from == 0) { - ram_wr32(fuc, 0x10f824, 0x00007fd4); - } else { - ram_wr32(fuc, 0x1373ec, 0x00020404); - } - - if (mode == 0) { - ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000); - ram_mask(fuc, 0x10f200, 0x00008000, 0x00008000); - ram_wr32(fuc, 0x10f830, 0x41500010); - ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000); - ram_mask(fuc, 0x132100, 0x00000100, 0x00000100); - ram_wr32(fuc, 0x10f050, 0xff000090); - ram_wr32(fuc, 0x1373ec, 0x00020f0f); - ram_wr32(fuc, 0x1373f0, 0x00000003); - ram_wr32(fuc, 0x137310, 0x81201616); - ram_wr32(fuc, 0x132100, 0x00000001); -// 0x00020039 // 0x000000ba - ram_wr32(fuc, 0x10f830, 0x00300017); - ram_wr32(fuc, 0x1373f0, 0x00000001); - ram_wr32(fuc, 0x10f824, 0x00007e77); - ram_wr32(fuc, 0x132000, 0x18030001); - ram_wr32(fuc, 0x10f090, 0x4000007e); - ram_nsec(fuc, 2000); - ram_wr32(fuc, 0x10f314, 0x00000001); - ram_wr32(fuc, 0x10f210, 0x80000000); - ram_wr32(fuc, 0x10f338, 0x00300220); - ram_wr32(fuc, 0x10f300, 0x0000011d); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f290, 0x02060505); - ram_wr32(fuc, 0x10f294, 0x34208288); - ram_wr32(fuc, 0x10f298, 0x44050411); - ram_wr32(fuc, 0x10f29c, 0x0000114c); - ram_wr32(fuc, 0x10f2a0, 0x42e10069); - ram_wr32(fuc, 0x10f614, 0x40044f77); - ram_wr32(fuc, 0x10f610, 0x40044f77); - ram_wr32(fuc, 0x10f344, 0x00600009); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f348, 0x00700008); - ram_wr32(fuc, 0x61c140, 0x19240000); - ram_wr32(fuc, 0x10f830, 0x00300017); - nvc0_ram_train(fuc, 0x80021001); - nvc0_ram_train(fuc, 0x80081001); - ram_wr32(fuc, 0x10f340, 0x00500004); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f830, 0x01300017); - ram_wr32(fuc, 0x10f830, 0x00300017); -// 0x00030020 // 0x00000000 // 0x00000000 -// 0x00020034 // 0x0000000b - ram_wr32(fuc, 0x100b0c, 0x00080028); - ram_wr32(fuc, 0x611200, 0x00003330); - } else { - ram_wr32(fuc, 0x10f800, 0x00001800); - ram_wr32(fuc, 0x13d8f4, 0x00000000); - ram_wr32(fuc, 0x1373ec, 0x00020404); - ram_wr32(fuc, 0x1373f0, 0x00000003); - ram_wr32(fuc, 0x10f830, 0x40700010); - ram_wr32(fuc, 0x10f830, 0x40500010); - ram_wr32(fuc, 0x13d8f4, 0x00000000); - ram_wr32(fuc, 0x1373f8, 0x00000000); - ram_wr32(fuc, 0x132100, 0x00000101); - ram_wr32(fuc, 0x137310, 0x89201616); - ram_wr32(fuc, 0x10f050, 0xff000090); - ram_wr32(fuc, 0x1373ec, 0x00030404); - ram_wr32(fuc, 0x1373f0, 0x00000002); - // 0x00020039 // 0x00000011 - ram_wr32(fuc, 0x132100, 0x00000001); - ram_wr32(fuc, 0x1373f8, 0x00002000); - ram_nsec(fuc, 2000); - ram_wr32(fuc, 0x10f808, 0x7aaa0050); - ram_wr32(fuc, 0x10f830, 0x00500010); - ram_wr32(fuc, 0x10f200, 0x00ce1000); - ram_wr32(fuc, 0x10f090, 0x4000007e); - ram_nsec(fuc, 2000); - ram_wr32(fuc, 0x10f314, 0x00000001); - ram_wr32(fuc, 0x10f210, 0x80000000); - ram_wr32(fuc, 0x10f338, 0x00300200); - ram_wr32(fuc, 0x10f300, 0x0000084d); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f290, 0x0b343825); - ram_wr32(fuc, 0x10f294, 0x3483028e); - ram_wr32(fuc, 0x10f298, 0x440c0600); - ram_wr32(fuc, 0x10f29c, 0x0000214c); - ram_wr32(fuc, 0x10f2a0, 0x42e20069); - ram_wr32(fuc, 0x10f200, 0x00ce0000); - ram_wr32(fuc, 0x10f614, 0x60044e77); - ram_wr32(fuc, 0x10f610, 0x60044e77); - ram_wr32(fuc, 0x10f340, 0x00500000); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f344, 0x00600228); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f348, 0x00700000); - ram_wr32(fuc, 0x13d8f4, 0x00000000); - ram_wr32(fuc, 0x61c140, 0x09a40000); - - nvc0_ram_train(fuc, 0x800e1008); - - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f800, 0x00001804); - // 0x00030020 // 0x00000000 // 0x00000000 - // 0x00020034 // 0x0000000b - ram_wr32(fuc, 0x13d8f4, 0x00000000); - ram_wr32(fuc, 0x100b0c, 0x00080028); - ram_wr32(fuc, 0x611200, 0x00003330); - ram_nsec(fuc, 100000); - ram_wr32(fuc, 0x10f9b0, 0x05313f41); - ram_wr32(fuc, 0x10f9b4, 0x00002f50); - - nvc0_ram_train(fuc, 0x010c1001); - } - - ram_mask(fuc, 0x10f200, 0x00000800, 0x00000800); -// 0x00020016 // 0x00000000 - - if (mode == 0) - ram_mask(fuc, 0x132000, 0x00000001, 0x00000000); - return 0; -} - -static int -nvc0_ram_prog(struct nouveau_fb *pfb) -{ - struct nouveau_device *device = nv_device(pfb); - struct nvc0_ram *ram = (void *)pfb->ram; - struct nvc0_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); - return 0; -} - -static void -nvc0_ram_tidy(struct nouveau_fb *pfb) -{ - struct nvc0_ram *ram = (void *)pfb->ram; - struct nvc0_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, false); -} +#include "priv.h" extern const u8 nvc0_pte_storage_type_map[256]; @@ -515,9 +110,10 @@ nvc0_ram_get(struct nouveau_fb *pfb, u64 size, u32 align, u32 ncmin, return 0; } -int -nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, int size, void **pobject) +static int +nvc0_ram_create(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { struct nouveau_fb *pfb = nouveau_fb(parent); struct nouveau_bios *bios = nouveau_bios(pfb); @@ -531,8 +127,8 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine, bool uniform = true; int ret, part; - ret = nouveau_ram_create_(parent, engine, oclass, size, pobject); - ram = *pobject; + ret = nouveau_ram_create(parent, engine, oclass, &ram); + *pobject = nv_object(ram); if (ret) return ret; @@ -586,158 +182,13 @@ nvc0_ram_create_(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -static int -nvc0_ram_init(struct nouveau_object *object) -{ - struct nouveau_fb *pfb = (void *)object->parent; - struct nvc0_ram *ram = (void *)object; - int ret, i; - - ret = nouveau_ram_init(&ram->base); - if (ret) - return ret; - - /* prepare for ddr link training, and load training patterns */ - switch (ram->base.type) { - case NV_MEM_TYPE_GDDR5: { - static const u8 train0[] = { - 0x00, 0xff, 0x55, 0xaa, 0x33, 0xcc, - 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, - }; - static const u32 train1[] = { - 0x00000000, 0xffffffff, - 0x55555555, 0xaaaaaaaa, - 0x33333333, 0xcccccccc, - 0xf0f0f0f0, 0x0f0f0f0f, - 0x00ff00ff, 0xff00ff00, - 0x0000ffff, 0xffff0000, - }; - - for (i = 0; i < 0x30; i++) { - nv_wr32(pfb, 0x10f968, 0x00000000 | (i << 8)); - nv_wr32(pfb, 0x10f96c, 0x00000000 | (i << 8)); - nv_wr32(pfb, 0x10f920, 0x00000100 | train0[i % 12]); - nv_wr32(pfb, 0x10f924, 0x00000100 | train0[i % 12]); - nv_wr32(pfb, 0x10f918, train1[i % 12]); - nv_wr32(pfb, 0x10f91c, train1[i % 12]); - nv_wr32(pfb, 0x10f920, 0x00000000 | train0[i % 12]); - nv_wr32(pfb, 0x10f924, 0x00000000 | train0[i % 12]); - nv_wr32(pfb, 0x10f918, train1[i % 12]); - nv_wr32(pfb, 0x10f91c, train1[i % 12]); - } - } break; - default: - break; - } - - return 0; -} - -static int -nvc0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nouveau_bios *bios = nouveau_bios(parent); - struct nvc0_ram *ram; - int ret; - - ret = nvc0_ram_create(parent, engine, oclass, &ram); - *pobject = nv_object(ram); - if (ret) - return ret; - - ret = nvbios_pll_parse(bios, 0x0c, &ram->refpll); - if (ret) { - nv_error(ram, "mclk refpll data not found\n"); - return ret; - } - - ret = nvbios_pll_parse(bios, 0x04, &ram->mempll); - if (ret) { - nv_error(ram, "mclk pll data not found\n"); - return ret; - } - - switch (ram->base.type) { - case NV_MEM_TYPE_GDDR5: - ram->base.calc = nvc0_ram_calc; - ram->base.prog = nvc0_ram_prog; - ram->base.tidy = nvc0_ram_tidy; - break; - default: - nv_warn(ram, "reclocking of this ram type unsupported\n"); - return 0; - } - - ram->fuc.r_0x10fe20 = ramfuc_reg(0x10fe20); - ram->fuc.r_0x10fe24 = ramfuc_reg(0x10fe24); - ram->fuc.r_0x137320 = ramfuc_reg(0x137320); - ram->fuc.r_0x137330 = ramfuc_reg(0x137330); - - ram->fuc.r_0x132000 = ramfuc_reg(0x132000); - ram->fuc.r_0x132004 = ramfuc_reg(0x132004); - ram->fuc.r_0x132100 = ramfuc_reg(0x132100); - - ram->fuc.r_0x137390 = ramfuc_reg(0x137390); - - ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290); - ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294); - ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298); - ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c); - ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0); - - ram->fuc.r_0x10f300 = ramfuc_reg(0x10f300); - ram->fuc.r_0x10f338 = ramfuc_reg(0x10f338); - ram->fuc.r_0x10f340 = ramfuc_reg(0x10f340); - ram->fuc.r_0x10f344 = ramfuc_reg(0x10f344); - ram->fuc.r_0x10f348 = ramfuc_reg(0x10f348); - - ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910); - ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914); - - ram->fuc.r_0x100b0c = ramfuc_reg(0x100b0c); - ram->fuc.r_0x10f050 = ramfuc_reg(0x10f050); - ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090); - ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200); - ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210); - ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310); - ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314); - ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610); - ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614); - ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800); - ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808); - ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824); - ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830); - ram->fuc.r_0x10f988 = ramfuc_reg(0x10f988); - ram->fuc.r_0x10f98c = ramfuc_reg(0x10f98c); - ram->fuc.r_0x10f990 = ramfuc_reg(0x10f990); - ram->fuc.r_0x10f998 = ramfuc_reg(0x10f998); - ram->fuc.r_0x10f9b0 = ramfuc_reg(0x10f9b0); - ram->fuc.r_0x10f9b4 = ramfuc_reg(0x10f9b4); - ram->fuc.r_0x10fb04 = ramfuc_reg(0x10fb04); - ram->fuc.r_0x10fb08 = ramfuc_reg(0x10fb08); - ram->fuc.r_0x137310 = ramfuc_reg(0x137300); - ram->fuc.r_0x137310 = ramfuc_reg(0x137310); - ram->fuc.r_0x137360 = ramfuc_reg(0x137360); - ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec); - ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0); - ram->fuc.r_0x1373f8 = ramfuc_reg(0x1373f8); - - ram->fuc.r_0x61c140 = ramfuc_reg(0x61c140); - ram->fuc.r_0x611200 = ramfuc_reg(0x611200); - - ram->fuc.r_0x13d8f4 = ramfuc_reg(0x13d8f4); - return 0; -} - struct nouveau_oclass nvc0_ram_oclass = { .handle = 0, .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvc0_ram_ctor, + .ctor = nvc0_ram_create, .dtor = _nouveau_ram_dtor, - .init = nvc0_ram_init, + .init = _nouveau_ram_init, .fini = _nouveau_ram_fini, } }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c deleted file mode 100644 index bc86cfd..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnve0.c +++ /dev/null @@ -1,1264 +0,0 @@ -/* - * 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 <subdev/gpio.h> - -#include <subdev/bios.h> -#include <subdev/bios/bit.h> -#include <subdev/bios/pll.h> -#include <subdev/bios/init.h> -#include <subdev/bios/rammap.h> -#include <subdev/bios/timing.h> - -#include <subdev/clock.h> -#include <subdev/clock/pll.h> - -#include <subdev/timer.h> - -#include <core/option.h> - -#include "nvc0.h" - -#include "ramfuc.h" - -struct nve0_ramfuc { - struct ramfuc base; - - struct nvbios_pll refpll; - struct nvbios_pll mempll; - - struct ramfuc_reg r_gpioMV; - u32 r_funcMV[2]; - struct ramfuc_reg r_gpio2E; - u32 r_func2E[2]; - struct ramfuc_reg r_gpiotrig; - - struct ramfuc_reg r_0x132020; - struct ramfuc_reg r_0x132028; - struct ramfuc_reg r_0x132024; - struct ramfuc_reg r_0x132030; - struct ramfuc_reg r_0x132034; - struct ramfuc_reg r_0x132000; - struct ramfuc_reg r_0x132004; - struct ramfuc_reg r_0x132040; - - struct ramfuc_reg r_0x10f248; - struct ramfuc_reg r_0x10f290; - struct ramfuc_reg r_0x10f294; - struct ramfuc_reg r_0x10f298; - struct ramfuc_reg r_0x10f29c; - struct ramfuc_reg r_0x10f2a0; - struct ramfuc_reg r_0x10f2a4; - struct ramfuc_reg r_0x10f2a8; - struct ramfuc_reg r_0x10f2ac; - struct ramfuc_reg r_0x10f2cc; - struct ramfuc_reg r_0x10f2e8; - struct ramfuc_reg r_0x10f250; - struct ramfuc_reg r_0x10f24c; - struct ramfuc_reg r_0x10fec4; - struct ramfuc_reg r_0x10fec8; - struct ramfuc_reg r_0x10f604; - struct ramfuc_reg r_0x10f614; - struct ramfuc_reg r_0x10f610; - struct ramfuc_reg r_0x100770; - struct ramfuc_reg r_0x100778; - struct ramfuc_reg r_0x10f224; - - struct ramfuc_reg r_0x10f870; - struct ramfuc_reg r_0x10f698; - struct ramfuc_reg r_0x10f694; - struct ramfuc_reg r_0x10f6b8; - struct ramfuc_reg r_0x10f808; - struct ramfuc_reg r_0x10f670; - struct ramfuc_reg r_0x10f60c; - struct ramfuc_reg r_0x10f830; - struct ramfuc_reg r_0x1373ec; - struct ramfuc_reg r_0x10f800; - struct ramfuc_reg r_0x10f82c; - - struct ramfuc_reg r_0x10f978; - struct ramfuc_reg r_0x10f910; - struct ramfuc_reg r_0x10f914; - - struct ramfuc_reg r_mr[16]; /* MR0 - MR8, MR15 */ - - struct ramfuc_reg r_0x62c000; - struct ramfuc_reg r_0x10f200; - struct ramfuc_reg r_0x10f210; - struct ramfuc_reg r_0x10f310; - struct ramfuc_reg r_0x10f314; - struct ramfuc_reg r_0x10f318; - struct ramfuc_reg r_0x10f090; - struct ramfuc_reg r_0x10f69c; - struct ramfuc_reg r_0x10f824; - struct ramfuc_reg r_0x1373f0; - struct ramfuc_reg r_0x1373f4; - struct ramfuc_reg r_0x137320; - struct ramfuc_reg r_0x10f65c; - struct ramfuc_reg r_0x10f6bc; - struct ramfuc_reg r_0x100710; - struct ramfuc_reg r_0x10f750; -}; - -struct nve0_ram { - struct nouveau_ram base; - struct nve0_ramfuc fuc; - int from; - int mode; - int N1, fN1, M1, P1; - int N2, M2, P2; -}; - -/******************************************************************************* - * GDDR5 - ******************************************************************************/ -static void -train(struct nve0_ramfuc *fuc, u32 magic) -{ - struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc); - struct nouveau_fb *pfb = nouveau_fb(ram); - const int mc = nv_rd32(pfb, 0x02243c); - int i; - - ram_mask(fuc, 0x10f910, 0xbc0e0000, magic); - ram_mask(fuc, 0x10f914, 0xbc0e0000, magic); - for (i = 0; i < mc; i++) { - const u32 addr = 0x110974 + (i * 0x1000); - ram_wait(fuc, addr, 0x0000000f, 0x00000000, 500000); - } -} - -static void -r1373f4_init(struct nve0_ramfuc *fuc) -{ - struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc); - const u32 mcoef = ((--ram->P2 << 28) | (ram->N2 << 8) | ram->M2); - const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1); - const u32 runk0 = ram->fN1 << 16; - const u32 runk1 = ram->fN1; - - if (ram->from == 2) { - ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100); - ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010); - } else { - ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010); - } - - ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000); - ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000); - - /* (re)program refpll, if required */ - if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef || - (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) { - ram_mask(fuc, 0x132000, 0x00000001, 0x00000000); - ram_mask(fuc, 0x132020, 0x00000001, 0x00000000); - ram_wr32(fuc, 0x137320, 0x00000000); - ram_mask(fuc, 0x132030, 0xffff0000, runk0); - ram_mask(fuc, 0x132034, 0x0000ffff, runk1); - ram_wr32(fuc, 0x132024, rcoef); - ram_mask(fuc, 0x132028, 0x00080000, 0x00080000); - ram_mask(fuc, 0x132020, 0x00000001, 0x00000001); - ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000); - ram_mask(fuc, 0x132028, 0x00080000, 0x00000000); - } - - /* (re)program mempll, if required */ - if (ram->mode == 2) { - ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000); - ram_mask(fuc, 0x132000, 0x00000001, 0x00000000); - ram_mask(fuc, 0x132004, 0x103fffff, mcoef); - ram_mask(fuc, 0x132000, 0x00000001, 0x00000001); - ram_wait(fuc, 0x137390, 0x00000002, 0x00000002, 64000); - ram_mask(fuc, 0x1373f4, 0x00000000, 0x00001100); - } else { - ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010100); - } - - ram_mask(fuc, 0x1373f4, 0x00000000, 0x00000010); -} - -static void -r1373f4_fini(struct nve0_ramfuc *fuc, u32 ramcfg) -{ - struct nve0_ram *ram = container_of(fuc, typeof(*ram), fuc); - struct nouveau_bios *bios = nouveau_bios(ram); - u8 v0 = (nv_ro08(bios, ramcfg + 0x03) & 0xc0) >> 6; - u8 v1 = (nv_ro08(bios, ramcfg + 0x03) & 0x30) >> 4; - u32 tmp; - - tmp = ram_rd32(fuc, 0x1373ec) & ~0x00030000; - ram_wr32(fuc, 0x1373ec, tmp | (v1 << 16)); - ram_mask(fuc, 0x1373f0, (~ram->mode & 3), 0x00000000); - if (ram->mode == 2) { - ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000002); - ram_mask(fuc, 0x1373f4, 0x00001100, 0x000000000); - } else { - ram_mask(fuc, 0x1373f4, 0x00000003, 0x000000001); - ram_mask(fuc, 0x1373f4, 0x00010000, 0x000000000); - } - ram_mask(fuc, 0x10f800, 0x00000030, (v0 ^ v1) << 4); -} - -static int -nve0_ram_calc_gddr5(struct nouveau_fb *pfb, u32 freq) -{ - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nve0_ram *ram = (void *)pfb->ram; - struct nve0_ramfuc *fuc = &ram->fuc; - const u32 rammap = ram->base.rammap.data; - const u32 ramcfg = ram->base.ramcfg.data; - const u32 timing = ram->base.timing.data; - int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08); - int mv = 1; /*XXX*/ - u32 mask, data; - - ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000); - ram_wr32(fuc, 0x62c000, 0x0f0f0000); - - /* MR1: turn termination on early, for some reason.. */ - if ((ram->base.mr[1] & 0x03c) != 0x030) - ram_mask(fuc, mr[1], 0x03c, ram->base.mr[1] & 0x03c); - - if (vc == 1 && ram_have(fuc, gpio2E)) { - u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]); - if (temp != ram_rd32(fuc, gpio2E)) { - ram_wr32(fuc, gpiotrig, 1); - ram_nsec(fuc, 20000); - } - } - - ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000); - - ram_mask(fuc, 0x10f914, 0x01020000, 0x000c0000); - ram_mask(fuc, 0x10f910, 0x01020000, 0x000c0000); - - ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */ - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ - ram_nsec(fuc, 1000); - - ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000); - ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */ - ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000); - ram_wr32(fuc, 0x10f090, 0x00000061); - ram_wr32(fuc, 0x10f090, 0xc000007f); - ram_nsec(fuc, 1000); - - ram_wr32(fuc, 0x10f698, 0x00000000); - ram_wr32(fuc, 0x10f69c, 0x00000000); - - /*XXX: there does appear to be some kind of condition here, simply - * modifying these bits in the vbios from the default pl0 - * entries shows no change. however, the data does appear to - * be correct and may be required for the transition back - */ - mask = 0x800f07e0; - data = 0x00030000; - if (ram_rd32(fuc, 0x10f978) & 0x00800000) - data |= 0x00040000; - - if (1) { - data |= 0x800807e0; - switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) { - case 0xc0: data &= ~0x00000040; break; - case 0x80: data &= ~0x00000100; break; - case 0x40: data &= ~0x80000000; break; - case 0x00: data &= ~0x00000400; break; - } - - switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) { - case 0x30: data &= ~0x00000020; break; - case 0x20: data &= ~0x00000080; break; - case 0x10: data &= ~0x00080000; break; - case 0x00: data &= ~0x00000200; break; - } - } - - if (nv_ro08(bios, ramcfg + 0x02) & 0x80) - mask |= 0x03000000; - if (nv_ro08(bios, ramcfg + 0x02) & 0x40) - mask |= 0x00002000; - if (nv_ro08(bios, ramcfg + 0x07) & 0x10) - mask |= 0x00004000; - if (nv_ro08(bios, ramcfg + 0x07) & 0x08) - mask |= 0x00000003; - else { - mask |= 0x34000000; - if (ram_rd32(fuc, 0x10f978) & 0x00800000) - mask |= 0x40000000; - } - ram_mask(fuc, 0x10f824, mask, data); - - ram_mask(fuc, 0x132040, 0x00010000, 0x00000000); - - if (ram->from == 2 && ram->mode != 2) { - ram_mask(fuc, 0x10f808, 0x00080000, 0x00000000); - ram_mask(fuc, 0x10f200, 0x00008000, 0x00008000); - ram_mask(fuc, 0x10f800, 0x00000000, 0x00000004); - ram_mask(fuc, 0x10f830, 0x00008000, 0x01040010); - ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000); - r1373f4_init(fuc); - ram_mask(fuc, 0x1373f0, 0x00000002, 0x00000001); - r1373f4_fini(fuc, ramcfg); - ram_mask(fuc, 0x10f830, 0x00c00000, 0x00240001); - } else - if (ram->from != 2 && ram->mode != 2) { - r1373f4_init(fuc); - r1373f4_fini(fuc, ramcfg); - } - - if (ram_have(fuc, gpioMV)) { - u32 temp = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]); - if (temp != ram_rd32(fuc, gpioMV)) { - ram_wr32(fuc, gpiotrig, 1); - ram_nsec(fuc, 64000); - } - } - - if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) || - (nv_ro08(bios, ramcfg + 0x07) & 0x10)) { - ram_mask(fuc, 0x132040, 0x00010000, 0x00010000); - ram_nsec(fuc, 20000); - } - - if (ram->from != 2 && ram->mode == 2) { - ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000); - ram_mask(fuc, 0x1373f0, 0x00000000, 0x00000002); - ram_mask(fuc, 0x10f830, 0x00800001, 0x00408010); - r1373f4_init(fuc); - r1373f4_fini(fuc, ramcfg); - ram_mask(fuc, 0x10f808, 0x00000000, 0x00080000); - ram_mask(fuc, 0x10f200, 0x00808000, 0x00800000); - } else - if (ram->from == 2 && ram->mode == 2) { - ram_mask(fuc, 0x10f800, 0x00000004, 0x00000000); - r1373f4_init(fuc); - r1373f4_fini(fuc, ramcfg); - } - - if (ram->mode != 2) /*XXX*/ { - if (nv_ro08(bios, ramcfg + 0x07) & 0x40) - ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000); - } - - data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2; - ram_wr32(fuc, 0x10f65c, 0x00000011 * data); - ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09)); - ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09)); - - data = nv_ro08(bios, ramcfg + 0x04); - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) { - ram_wr32(fuc, 0x10f698, 0x01010101 * data); - ram_wr32(fuc, 0x10f69c, 0x01010101 * data); - } - - if (ram->mode != 2) { - u32 temp = ram_rd32(fuc, 0x10f694) & ~0xff00ff00; - ram_wr32(fuc, 0x10f694, temp | (0x01000100 * data)); - } - - if (ram->mode == 2 && (nv_ro08(bios, ramcfg + 0x08) & 0x10)) - data = 0x00000080; - else - data = 0x00000000; - ram_mask(fuc, 0x10f60c, 0x00000080, data); - - mask = 0x00070000; - data = 0x00000000; - if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80)) - data |= 0x03000000; - if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40)) - data |= 0x00002000; - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10)) - data |= 0x00004000; - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) - data |= 0x00000003; - else - data |= 0x74000000; - ram_mask(fuc, 0x10f824, mask, data); - - if (nv_ro08(bios, ramcfg + 0x01) & 0x08) - data = 0x00000000; - else - data = 0x00001000; - ram_mask(fuc, 0x10f200, 0x00001000, data); - - if (ram_rd32(fuc, 0x10f670) & 0x80000000) { - ram_nsec(fuc, 10000); - ram_mask(fuc, 0x10f670, 0x80000000, 0x00000000); - } - - if (nv_ro08(bios, ramcfg + 0x08) & 0x01) - data = 0x00100000; - else - data = 0x00000000; - ram_mask(fuc, 0x10f82c, 0x00100000, data); - - data = 0x00000000; - if (nv_ro08(bios, ramcfg + 0x08) & 0x08) - data |= 0x00002000; - if (nv_ro08(bios, ramcfg + 0x08) & 0x04) - data |= 0x00001000; - if (nv_ro08(bios, ramcfg + 0x08) & 0x02) - data |= 0x00004000; - ram_mask(fuc, 0x10f830, 0x00007000, data); - - /* PFB timing */ - ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28)); - ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00)); - ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04)); - ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08)); - ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c)); - ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10)); - ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14)); - ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18)); - ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c)); - ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20)); - ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24)); - - data = (nv_ro08(bios, ramcfg + 0x02) & 0x03) << 8; - if (nv_ro08(bios, ramcfg + 0x01) & 0x10) - data |= 0x70000000; - ram_mask(fuc, 0x10f604, 0x70000300, data); - - data = (nv_ro08(bios, timing + 0x30) & 0x07) << 28; - if (nv_ro08(bios, ramcfg + 0x01) & 0x01) - data |= 0x00000100; - ram_mask(fuc, 0x10f614, 0x70000000, data); - - data = (nv_ro08(bios, timing + 0x30) & 0x07) << 28; - if (nv_ro08(bios, ramcfg + 0x01) & 0x02) - data |= 0x00000100; - ram_mask(fuc, 0x10f610, 0x70000000, data); - - mask = 0x33f00000; - data = 0x00000000; - if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04)) - data |= 0x20200000; - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80)) - data |= 0x12800000; - /*XXX: see note above about there probably being some condition - * for the 10f824 stuff that uses ramcfg 3... - */ - if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) { - if (nv_ro08(bios, rammap + 0x08) & 0x0c) { - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80)) - mask |= 0x00000020; - else - data |= 0x00000020; - mask |= 0x00000004; - } - } else { - mask |= 0x40000020; - data |= 0x00000004; - } - - ram_mask(fuc, 0x10f808, mask, data); - - data = nv_ro08(bios, ramcfg + 0x03) & 0x0f; - ram_wr32(fuc, 0x10f870, 0x11111111 * data); - - data = nv_ro08(bios, ramcfg + 0x02) & 0x03; - if (nv_ro08(bios, ramcfg + 0x01) & 0x10) - data |= 0x00000004; - if ((nv_rd32(bios, 0x100770) & 0x00000004) != (data & 0x00000004)) { - ram_wr32(fuc, 0x10f750, 0x04000009); - ram_wr32(fuc, 0x100710, 0x00000000); - ram_wait(fuc, 0x100710, 0x80000000, 0x80000000, 200000); - } - ram_mask(fuc, 0x100770, 0x00000007, data); - - data = (nv_ro08(bios, timing + 0x30) & 0x07) << 8; - if (nv_ro08(bios, ramcfg + 0x01) & 0x01) - data |= 0x80000000; - ram_mask(fuc, 0x100778, 0x00000700, data); - - data = nv_ro16(bios, timing + 0x2c); - ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) << 4); - ram_mask(fuc, 0x10f24c, 0x7f000000, (data & 0x1fc0) << 18); - - data = nv_ro08(bios, timing + 0x30); - ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13); - - data = nv_ro16(bios, timing + 0x31); - ram_mask(fuc, 0x10fec4, 0x041e0f07, (data & 0x0800) << 15 | - (data & 0x0780) << 10 | - (data & 0x0078) << 5 | - (data & 0x0007)); - ram_mask(fuc, 0x10fec8, 0x00000027, (data & 0x8000) >> 10 | - (data & 0x7000) >> 12); - - ram_wr32(fuc, 0x10f090, 0x4000007e); - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */ - ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ - ram_nsec(fuc, 2000); - ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */ - - if ((nv_ro08(bios, ramcfg + 0x08) & 0x10) && (ram->mode == 2) /*XXX*/) { - u32 temp = ram_mask(fuc, 0x10f294, 0xff000000, 0x24000000); - train(fuc, 0xa4010000); /*XXX*/ - ram_nsec(fuc, 1000); - ram_wr32(fuc, 0x10f294, temp); - } - - ram_mask(fuc, mr[3], 0xfff, ram->base.mr[3]); - ram_wr32(fuc, mr[0], ram->base.mr[0]); - ram_mask(fuc, mr[8], 0xfff, ram->base.mr[8]); - ram_nsec(fuc, 1000); - ram_mask(fuc, mr[1], 0xfff, ram->base.mr[1]); - ram_mask(fuc, mr[5], 0xfff, ram->base.mr[5]); - ram_mask(fuc, mr[6], 0xfff, ram->base.mr[6]); - ram_mask(fuc, mr[7], 0xfff, ram->base.mr[7]); - - if (vc == 0 && ram_have(fuc, gpio2E)) { - u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]); - if (temp != ram_rd32(fuc, gpio2E)) { - ram_wr32(fuc, gpiotrig, 1); - ram_nsec(fuc, 20000); - } - } - - ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000); - ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */ - ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000); - ram_nsec(fuc, 1000); - - data = ram_rd32(fuc, 0x10f978); - data &= ~0x00046144; - data |= 0x0000000b; - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) { - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x04)) - data |= 0x0000200c; - else - data |= 0x00000000; - } else { - data |= 0x00040044; - } - ram_wr32(fuc, 0x10f978, data); - - if (ram->mode == 1) { - data = ram_rd32(fuc, 0x10f830) | 0x00000001; - ram_wr32(fuc, 0x10f830, data); - } - - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) { - data = 0x88020000; - if ( (nv_ro08(bios, ramcfg + 0x07) & 0x04)) - data |= 0x10000000; - if (!(nv_ro08(bios, rammap + 0x08) & 0x10)) - data |= 0x00080000; - } else { - data = 0xa40e0000; - } - train(fuc, data); - ram_nsec(fuc, 1000); - - if (ram->mode == 2) { /*XXX*/ - ram_mask(fuc, 0x10f800, 0x00000004, 0x00000004); - } - - /* MR5: (re)enable LP3 if necessary - * XXX: need to find the switch, keeping off for now - */ - ram_mask(fuc, mr[5], 0x00000004, 0x00000000); - - if (ram->mode != 2) { - ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000); - ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000); - } - - if (nv_ro08(bios, ramcfg + 0x07) & 0x02) { - ram_mask(fuc, 0x10f910, 0x80020000, 0x01000000); - ram_mask(fuc, 0x10f914, 0x80020000, 0x01000000); - } - - ram_wr32(fuc, 0x62c000, 0x0f0f0f00); - - if (nv_ro08(bios, rammap + 0x08) & 0x01) - data = 0x00000800; - else - data = 0x00000000; - ram_mask(fuc, 0x10f200, 0x00000800, data); - return 0; -} - -/******************************************************************************* - * DDR3 - ******************************************************************************/ - -static int -nve0_ram_calc_sddr3(struct nouveau_fb *pfb, u32 freq) -{ - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nve0_ram *ram = (void *)pfb->ram; - struct nve0_ramfuc *fuc = &ram->fuc; - const u32 rcoef = (( ram->P1 << 16) | (ram->N1 << 8) | ram->M1); - const u32 runk0 = ram->fN1 << 16; - const u32 runk1 = ram->fN1; - const u32 rammap = ram->base.rammap.data; - const u32 ramcfg = ram->base.ramcfg.data; - const u32 timing = ram->base.timing.data; - int vc = !(nv_ro08(bios, ramcfg + 0x02) & 0x08); - int mv = 1; /*XXX*/ - u32 mask, data; - - ram_mask(fuc, 0x10f808, 0x40000000, 0x40000000); - ram_wr32(fuc, 0x62c000, 0x0f0f0000); - - if (vc == 1 && ram_have(fuc, gpio2E)) { - u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[1]); - if (temp != ram_rd32(fuc, gpio2E)) { - ram_wr32(fuc, gpiotrig, 1); - ram_nsec(fuc, 20000); - } - } - - ram_mask(fuc, 0x10f200, 0x00000800, 0x00000000); - if ((nv_ro08(bios, ramcfg + 0x03) & 0xf0)) - ram_mask(fuc, 0x10f808, 0x04000000, 0x04000000); - - ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */ - ram_wr32(fuc, 0x10f210, 0x00000000); /* REFRESH_AUTO = 0 */ - ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ - ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000); - ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ - ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000); - ram_nsec(fuc, 1000); - - ram_wr32(fuc, 0x10f090, 0x00000060); - ram_wr32(fuc, 0x10f090, 0xc000007e); - - /*XXX: there does appear to be some kind of condition here, simply - * modifying these bits in the vbios from the default pl0 - * entries shows no change. however, the data does appear to - * be correct and may be required for the transition back - */ - mask = 0x00010000; - data = 0x00010000; - - if (1) { - mask |= 0x800807e0; - data |= 0x800807e0; - switch (nv_ro08(bios, ramcfg + 0x03) & 0xc0) { - case 0xc0: data &= ~0x00000040; break; - case 0x80: data &= ~0x00000100; break; - case 0x40: data &= ~0x80000000; break; - case 0x00: data &= ~0x00000400; break; - } - - switch (nv_ro08(bios, ramcfg + 0x03) & 0x30) { - case 0x30: data &= ~0x00000020; break; - case 0x20: data &= ~0x00000080; break; - case 0x10: data &= ~0x00080000; break; - case 0x00: data &= ~0x00000200; break; - } - } - - if (nv_ro08(bios, ramcfg + 0x02) & 0x80) - mask |= 0x03000000; - if (nv_ro08(bios, ramcfg + 0x02) & 0x40) - mask |= 0x00002000; - if (nv_ro08(bios, ramcfg + 0x07) & 0x10) - mask |= 0x00004000; - if (nv_ro08(bios, ramcfg + 0x07) & 0x08) - mask |= 0x00000003; - else - mask |= 0x14000000; - ram_mask(fuc, 0x10f824, mask, data); - - ram_mask(fuc, 0x132040, 0x00010000, 0x00000000); - - ram_mask(fuc, 0x1373f4, 0x00000000, 0x00010010); - data = ram_rd32(fuc, 0x1373ec) & ~0x00030000; - data |= (nv_ro08(bios, ramcfg + 0x03) & 0x30) << 12; - ram_wr32(fuc, 0x1373ec, data); - ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000000); - ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000000); - - /* (re)program refpll, if required */ - if ((ram_rd32(fuc, 0x132024) & 0xffffffff) != rcoef || - (ram_rd32(fuc, 0x132034) & 0x0000ffff) != runk1) { - ram_mask(fuc, 0x132000, 0x00000001, 0x00000000); - ram_mask(fuc, 0x132020, 0x00000001, 0x00000000); - ram_wr32(fuc, 0x137320, 0x00000000); - ram_mask(fuc, 0x132030, 0xffff0000, runk0); - ram_mask(fuc, 0x132034, 0x0000ffff, runk1); - ram_wr32(fuc, 0x132024, rcoef); - ram_mask(fuc, 0x132028, 0x00080000, 0x00080000); - ram_mask(fuc, 0x132020, 0x00000001, 0x00000001); - ram_wait(fuc, 0x137390, 0x00020000, 0x00020000, 64000); - ram_mask(fuc, 0x132028, 0x00080000, 0x00000000); - } - - ram_mask(fuc, 0x1373f4, 0x00000010, 0x00000010); - ram_mask(fuc, 0x1373f4, 0x00000003, 0x00000001); - ram_mask(fuc, 0x1373f4, 0x00010000, 0x00000000); - - if (ram_have(fuc, gpioMV)) { - u32 temp = ram_mask(fuc, gpioMV, 0x3000, fuc->r_funcMV[mv]); - if (temp != ram_rd32(fuc, gpioMV)) { - ram_wr32(fuc, gpiotrig, 1); - ram_nsec(fuc, 64000); - } - } - - if ( (nv_ro08(bios, ramcfg + 0x02) & 0x40) || - (nv_ro08(bios, ramcfg + 0x07) & 0x10)) { - ram_mask(fuc, 0x132040, 0x00010000, 0x00010000); - ram_nsec(fuc, 20000); - } - - if (ram->mode != 2) /*XXX*/ { - if (nv_ro08(bios, ramcfg + 0x07) & 0x40) - ram_mask(fuc, 0x10f670, 0x80000000, 0x80000000); - } - - data = (nv_ro08(bios, rammap + 0x11) & 0x0c) >> 2; - ram_wr32(fuc, 0x10f65c, 0x00000011 * data); - ram_wr32(fuc, 0x10f6b8, 0x01010101 * nv_ro08(bios, ramcfg + 0x09)); - ram_wr32(fuc, 0x10f6bc, 0x01010101 * nv_ro08(bios, ramcfg + 0x09)); - - mask = 0x00010000; - data = 0x00000000; - if (!(nv_ro08(bios, ramcfg + 0x02) & 0x80)) - data |= 0x03000000; - if (!(nv_ro08(bios, ramcfg + 0x02) & 0x40)) - data |= 0x00002000; - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x10)) - data |= 0x00004000; - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x08)) - data |= 0x00000003; - else - data |= 0x14000000; - ram_mask(fuc, 0x10f824, mask, data); - ram_nsec(fuc, 1000); - - if (nv_ro08(bios, ramcfg + 0x08) & 0x01) - data = 0x00100000; - else - data = 0x00000000; - ram_mask(fuc, 0x10f82c, 0x00100000, data); - - /* PFB timing */ - ram_mask(fuc, 0x10f248, 0xffffffff, nv_ro32(bios, timing + 0x28)); - ram_mask(fuc, 0x10f290, 0xffffffff, nv_ro32(bios, timing + 0x00)); - ram_mask(fuc, 0x10f294, 0xffffffff, nv_ro32(bios, timing + 0x04)); - ram_mask(fuc, 0x10f298, 0xffffffff, nv_ro32(bios, timing + 0x08)); - ram_mask(fuc, 0x10f29c, 0xffffffff, nv_ro32(bios, timing + 0x0c)); - ram_mask(fuc, 0x10f2a0, 0xffffffff, nv_ro32(bios, timing + 0x10)); - ram_mask(fuc, 0x10f2a4, 0xffffffff, nv_ro32(bios, timing + 0x14)); - ram_mask(fuc, 0x10f2a8, 0xffffffff, nv_ro32(bios, timing + 0x18)); - ram_mask(fuc, 0x10f2ac, 0xffffffff, nv_ro32(bios, timing + 0x1c)); - ram_mask(fuc, 0x10f2cc, 0xffffffff, nv_ro32(bios, timing + 0x20)); - ram_mask(fuc, 0x10f2e8, 0xffffffff, nv_ro32(bios, timing + 0x24)); - - mask = 0x33f00000; - data = 0x00000000; - if (!(nv_ro08(bios, ramcfg + 0x01) & 0x04)) - data |= 0x20200000; - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80)) - data |= 0x12800000; - /*XXX: see note above about there probably being some condition - * for the 10f824 stuff that uses ramcfg 3... - */ - if ( (nv_ro08(bios, ramcfg + 0x03) & 0xf0)) { - if (nv_ro08(bios, rammap + 0x08) & 0x0c) { - if (!(nv_ro08(bios, ramcfg + 0x07) & 0x80)) - mask |= 0x00000020; - else - data |= 0x00000020; - mask |= 0x08000004; - } - data |= 0x04000000; - } else { - mask |= 0x44000020; - data |= 0x08000004; - } - - ram_mask(fuc, 0x10f808, mask, data); - - data = nv_ro08(bios, ramcfg + 0x03) & 0x0f; - ram_wr32(fuc, 0x10f870, 0x11111111 * data); - - data = nv_ro16(bios, timing + 0x2c); - ram_mask(fuc, 0x10f250, 0x000003f0, (data & 0x003f) << 4); - - if (((nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >> 6) > - ((nv_ro32(bios, timing + 0x28) & 0x7f000000) >> 24)) - data = (nv_ro32(bios, timing + 0x2c) & 0x00001fc0) >> 6; - else - data = (nv_ro32(bios, timing + 0x28) & 0x1f000000) >> 24; - ram_mask(fuc, 0x10f24c, 0x7f000000, data << 24); - - data = nv_ro08(bios, timing + 0x30); - ram_mask(fuc, 0x10f224, 0x001f0000, (data & 0xf8) << 13); - - ram_wr32(fuc, 0x10f090, 0x4000007f); - ram_nsec(fuc, 1000); - - ram_wr32(fuc, 0x10f314, 0x00000001); /* PRECHARGE */ - ram_wr32(fuc, 0x10f310, 0x00000001); /* REFRESH */ - ram_wr32(fuc, 0x10f210, 0x80000000); /* REFRESH_AUTO = 1 */ - ram_nsec(fuc, 1000); - - ram_nuke(fuc, mr[0]); - ram_mask(fuc, mr[0], 0x100, 0x100); - ram_mask(fuc, mr[0], 0x100, 0x000); - - ram_mask(fuc, mr[2], 0xfff, ram->base.mr[2]); - ram_wr32(fuc, mr[0], ram->base.mr[0]); - ram_nsec(fuc, 1000); - - ram_nuke(fuc, mr[0]); - ram_mask(fuc, mr[0], 0x100, 0x100); - ram_mask(fuc, mr[0], 0x100, 0x000); - - if (vc == 0 && ram_have(fuc, gpio2E)) { - u32 temp = ram_mask(fuc, gpio2E, 0x3000, fuc->r_func2E[0]); - if (temp != ram_rd32(fuc, gpio2E)) { - ram_wr32(fuc, gpiotrig, 1); - ram_nsec(fuc, 20000); - } - } - - if (ram->mode != 2) { - ram_mask(fuc, 0x10f830, 0x01000000, 0x01000000); - ram_mask(fuc, 0x10f830, 0x01000000, 0x00000000); - } - - ram_mask(fuc, 0x10f200, 0x80000000, 0x80000000); - ram_wr32(fuc, 0x10f318, 0x00000001); /* NOP? */ - ram_mask(fuc, 0x10f200, 0x80000000, 0x00000000); - ram_nsec(fuc, 1000); - - ram_wr32(fuc, 0x62c000, 0x0f0f0f00); - - if (nv_ro08(bios, rammap + 0x08) & 0x01) - data = 0x00000800; - else - data = 0x00000000; - ram_mask(fuc, 0x10f200, 0x00000800, data); - return 0; -} - -/******************************************************************************* - * main hooks - ******************************************************************************/ - -static int -nve0_ram_calc(struct nouveau_fb *pfb, u32 freq) -{ - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nve0_ram *ram = (void *)pfb->ram; - struct nve0_ramfuc *fuc = &ram->fuc; - struct bit_entry M; - int ret, refclk, strap, i; - u32 data; - u8 cnt; - - /* lookup memory config data relevant to the target frequency */ - ram->base.rammap.data = nvbios_rammap_match(bios, freq / 1000, - &ram->base.rammap.version, - &ram->base.rammap.size, &cnt, - &ram->base.ramcfg.size); - if (!ram->base.rammap.data || ram->base.rammap.version != 0x11 || - ram->base.rammap.size < 0x09) { - nv_error(pfb, "invalid/missing rammap entry\n"); - return -EINVAL; - } - - /* locate specific data set for the attached memory */ - if (bit_entry(bios, 'M', &M) || M.version != 2 || M.length < 3) { - nv_error(pfb, "invalid/missing memory table\n"); - return -EINVAL; - } - - strap = (nv_rd32(pfb, 0x101000) & 0x0000003c) >> 2; - data = nv_ro16(bios, M.offset + 1); - if (data) - strap = nv_ro08(bios, data + strap); - - if (strap >= cnt) { - nv_error(pfb, "invalid ramcfg strap\n"); - return -EINVAL; - } - - ram->base.ramcfg.version = ram->base.rammap.version; - ram->base.ramcfg.data = ram->base.rammap.data + ram->base.rammap.size + - (ram->base.ramcfg.size * strap); - if (!ram->base.ramcfg.data || ram->base.ramcfg.version != 0x11 || - ram->base.ramcfg.size < 0x08) { - nv_error(pfb, "invalid/missing ramcfg entry\n"); - return -EINVAL; - } - - /* lookup memory timings, if bios says they're present */ - strap = nv_ro08(bios, ram->base.ramcfg.data + 0x00); - if (strap != 0xff) { - ram->base.timing.data = - nvbios_timing_entry(bios, strap, - &ram->base.timing.version, - &ram->base.timing.size); - if (!ram->base.timing.data || - ram->base.timing.version != 0x20 || - ram->base.timing.size < 0x33) { - nv_error(pfb, "invalid/missing timing entry\n"); - return -EINVAL; - } - } else { - ram->base.timing.data = 0; - } - - ret = ram_init(fuc, pfb); - if (ret) - return ret; - - ram->mode = (freq > fuc->refpll.vco1.max_freq) ? 2 : 1; - ram->from = ram_rd32(fuc, 0x1373f4) & 0x0000000f; - - /* XXX: this is *not* what nvidia do. on fermi nvidia generally - * select, based on some unknown condition, one of the two possible - * reference frequencies listed in the vbios table for mempll and - * program refpll to that frequency. - * - * so far, i've seen very weird values being chosen by nvidia on - * kepler boards, no idea how/why they're chosen. - */ - refclk = freq; - if (ram->mode == 2) - refclk = fuc->mempll.refclk; - - /* calculate refpll coefficients */ - ret = nva3_pll_calc(nv_subdev(pfb), &fuc->refpll, refclk, &ram->N1, - &ram->fN1, &ram->M1, &ram->P1); - fuc->mempll.refclk = ret; - if (ret <= 0) { - nv_error(pfb, "unable to calc refpll\n"); - return -EINVAL; - } - - /* calculate mempll coefficients, if we're using it */ - if (ram->mode == 2) { - /* post-divider doesn't work... the reg takes the values but - * appears to completely ignore it. there *is* a bit at - * bit 28 that appears to divide the clock by 2 if set. - */ - fuc->mempll.min_p = 1; - fuc->mempll.max_p = 2; - - ret = nva3_pll_calc(nv_subdev(pfb), &fuc->mempll, freq, - &ram->N2, NULL, &ram->M2, &ram->P2); - if (ret <= 0) { - nv_error(pfb, "unable to calc mempll\n"); - return -EINVAL; - } - } - - for (i = 0; i < ARRAY_SIZE(fuc->r_mr); i++) { - if (ram_have(fuc, mr[i])) - ram->base.mr[i] = ram_rd32(fuc, mr[i]); - } - - switch (ram->base.type) { - case NV_MEM_TYPE_DDR3: - ret = nouveau_sddr3_calc(&ram->base); - if (ret == 0) - ret = nve0_ram_calc_sddr3(pfb, freq); - break; - case NV_MEM_TYPE_GDDR5: - ret = nouveau_gddr5_calc(&ram->base); - if (ret == 0) - ret = nve0_ram_calc_gddr5(pfb, freq); - break; - default: - ret = -ENOSYS; - break; - } - - return ret; -} - -static int -nve0_ram_prog(struct nouveau_fb *pfb) -{ - struct nouveau_device *device = nv_device(pfb); - struct nve0_ram *ram = (void *)pfb->ram; - struct nve0_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", false)); - return 0; -} - -static void -nve0_ram_tidy(struct nouveau_fb *pfb) -{ - struct nve0_ram *ram = (void *)pfb->ram; - struct nve0_ramfuc *fuc = &ram->fuc; - ram_exec(fuc, false); -} - -static int -nve0_ram_init(struct nouveau_object *object) -{ - struct nouveau_fb *pfb = (void *)object->parent; - struct nve0_ram *ram = (void *)object; - struct nouveau_bios *bios = nouveau_bios(pfb); - static const u8 train0[] = { - 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, - 0x00, 0xff, 0xff, 0x00, 0xff, 0x00, - }; - static const u32 train1[] = { - 0x00000000, 0xffffffff, - 0x55555555, 0xaaaaaaaa, - 0x33333333, 0xcccccccc, - 0xf0f0f0f0, 0x0f0f0f0f, - 0x00ff00ff, 0xff00ff00, - 0x0000ffff, 0xffff0000, - }; - u8 ver, hdr, cnt, len, snr, ssz; - u32 data, save; - int ret, i; - - ret = nouveau_ram_init(&ram->base); - if (ret) - return ret; - - /* run a bunch of tables from rammap table. there's actually - * individual pointers for each rammap entry too, but, nvidia - * seem to just run the last two entries' scripts early on in - * their init, and never again.. we'll just run 'em all once - * for now. - * - * i strongly suspect that each script is for a separate mode - * (likely selected by 0x10f65c's lower bits?), and the - * binary driver skips the one that's already been setup by - * the init tables. - */ - data = nvbios_rammap_table(bios, &ver, &hdr, &cnt, &len, &snr, &ssz); - if (!data || hdr < 0x15) - return -EINVAL; - - cnt = nv_ro08(bios, data + 0x14); /* guess at count */ - data = nv_ro32(bios, data + 0x10); /* guess u32... */ - save = nv_rd32(pfb, 0x10f65c); - for (i = 0; i < cnt; i++) { - nv_mask(pfb, 0x10f65c, 0x000000f0, i << 4); - nvbios_exec(&(struct nvbios_init) { - .subdev = nv_subdev(pfb), - .bios = bios, - .offset = nv_ro32(bios, data), /* guess u32 */ - .execute = 1, - }); - data += 4; - } - nv_wr32(pfb, 0x10f65c, save); - - switch (ram->base.type) { - case NV_MEM_TYPE_GDDR5: - for (i = 0; i < 0x30; i++) { - nv_wr32(pfb, 0x10f968, 0x00000000 | (i << 8)); - nv_wr32(pfb, 0x10f920, 0x00000000 | train0[i % 12]); - nv_wr32(pfb, 0x10f918, train1[i % 12]); - nv_wr32(pfb, 0x10f920, 0x00000100 | train0[i % 12]); - nv_wr32(pfb, 0x10f918, train1[i % 12]); - - nv_wr32(pfb, 0x10f96c, 0x00000000 | (i << 8)); - nv_wr32(pfb, 0x10f924, 0x00000000 | train0[i % 12]); - nv_wr32(pfb, 0x10f91c, train1[i % 12]); - nv_wr32(pfb, 0x10f924, 0x00000100 | train0[i % 12]); - nv_wr32(pfb, 0x10f91c, train1[i % 12]); - } - - for (i = 0; i < 0x100; i++) { - nv_wr32(pfb, 0x10f968, i); - nv_wr32(pfb, 0x10f900, train1[2 + (i & 1)]); - } - - for (i = 0; i < 0x100; i++) { - nv_wr32(pfb, 0x10f96c, i); - nv_wr32(pfb, 0x10f900, train1[2 + (i & 1)]); - } - break; - default: - break; - } - - return 0; -} - -static int -nve0_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nouveau_fb *pfb = nouveau_fb(parent); - struct nouveau_bios *bios = nouveau_bios(pfb); - struct nouveau_gpio *gpio = nouveau_gpio(pfb); - struct dcb_gpio_func func; - struct nve0_ram *ram; - int ret; - - ret = nvc0_ram_create(parent, engine, oclass, &ram); - *pobject = nv_object(ram); - if (ret) - return ret; - - switch (ram->base.type) { - case NV_MEM_TYPE_DDR3: - case NV_MEM_TYPE_GDDR5: - ram->base.calc = nve0_ram_calc; - ram->base.prog = nve0_ram_prog; - ram->base.tidy = nve0_ram_tidy; - break; - default: - nv_warn(pfb, "reclocking of this RAM type is unsupported\n"); - break; - } - - // parse bios data for both pll's - ret = nvbios_pll_parse(bios, 0x0c, &ram->fuc.refpll); - if (ret) { - nv_error(pfb, "mclk refpll data not found\n"); - return ret; - } - - ret = nvbios_pll_parse(bios, 0x04, &ram->fuc.mempll); - if (ret) { - nv_error(pfb, "mclk pll data not found\n"); - return ret; - } - - ret = gpio->find(gpio, 0, 0x18, DCB_GPIO_UNUSED, &func); - if (ret == 0) { - ram->fuc.r_gpioMV = ramfuc_reg(0x00d610 + (func.line * 0x04)); - ram->fuc.r_funcMV[0] = (func.log[0] ^ 2) << 12; - ram->fuc.r_funcMV[1] = (func.log[1] ^ 2) << 12; - } - - ret = gpio->find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func); - if (ret == 0) { - ram->fuc.r_gpio2E = ramfuc_reg(0x00d610 + (func.line * 0x04)); - ram->fuc.r_func2E[0] = (func.log[0] ^ 2) << 12; - ram->fuc.r_func2E[1] = (func.log[1] ^ 2) << 12; - } - - ram->fuc.r_gpiotrig = ramfuc_reg(0x00d604); - - ram->fuc.r_0x132020 = ramfuc_reg(0x132020); - ram->fuc.r_0x132028 = ramfuc_reg(0x132028); - ram->fuc.r_0x132024 = ramfuc_reg(0x132024); - ram->fuc.r_0x132030 = ramfuc_reg(0x132030); - ram->fuc.r_0x132034 = ramfuc_reg(0x132034); - ram->fuc.r_0x132000 = ramfuc_reg(0x132000); - ram->fuc.r_0x132004 = ramfuc_reg(0x132004); - ram->fuc.r_0x132040 = ramfuc_reg(0x132040); - - ram->fuc.r_0x10f248 = ramfuc_reg(0x10f248); - ram->fuc.r_0x10f290 = ramfuc_reg(0x10f290); - ram->fuc.r_0x10f294 = ramfuc_reg(0x10f294); - ram->fuc.r_0x10f298 = ramfuc_reg(0x10f298); - ram->fuc.r_0x10f29c = ramfuc_reg(0x10f29c); - ram->fuc.r_0x10f2a0 = ramfuc_reg(0x10f2a0); - ram->fuc.r_0x10f2a4 = ramfuc_reg(0x10f2a4); - ram->fuc.r_0x10f2a8 = ramfuc_reg(0x10f2a8); - ram->fuc.r_0x10f2ac = ramfuc_reg(0x10f2ac); - ram->fuc.r_0x10f2cc = ramfuc_reg(0x10f2cc); - ram->fuc.r_0x10f2e8 = ramfuc_reg(0x10f2e8); - ram->fuc.r_0x10f250 = ramfuc_reg(0x10f250); - ram->fuc.r_0x10f24c = ramfuc_reg(0x10f24c); - ram->fuc.r_0x10fec4 = ramfuc_reg(0x10fec4); - ram->fuc.r_0x10fec8 = ramfuc_reg(0x10fec8); - ram->fuc.r_0x10f604 = ramfuc_reg(0x10f604); - ram->fuc.r_0x10f614 = ramfuc_reg(0x10f614); - ram->fuc.r_0x10f610 = ramfuc_reg(0x10f610); - ram->fuc.r_0x100770 = ramfuc_reg(0x100770); - ram->fuc.r_0x100778 = ramfuc_reg(0x100778); - ram->fuc.r_0x10f224 = ramfuc_reg(0x10f224); - - ram->fuc.r_0x10f870 = ramfuc_reg(0x10f870); - ram->fuc.r_0x10f698 = ramfuc_reg(0x10f698); - ram->fuc.r_0x10f694 = ramfuc_reg(0x10f694); - ram->fuc.r_0x10f6b8 = ramfuc_reg(0x10f6b8); - ram->fuc.r_0x10f808 = ramfuc_reg(0x10f808); - ram->fuc.r_0x10f670 = ramfuc_reg(0x10f670); - ram->fuc.r_0x10f60c = ramfuc_reg(0x10f60c); - ram->fuc.r_0x10f830 = ramfuc_reg(0x10f830); - ram->fuc.r_0x1373ec = ramfuc_reg(0x1373ec); - ram->fuc.r_0x10f800 = ramfuc_reg(0x10f800); - ram->fuc.r_0x10f82c = ramfuc_reg(0x10f82c); - - ram->fuc.r_0x10f978 = ramfuc_reg(0x10f978); - ram->fuc.r_0x10f910 = ramfuc_reg(0x10f910); - ram->fuc.r_0x10f914 = ramfuc_reg(0x10f914); - - switch (ram->base.type) { - case NV_MEM_TYPE_GDDR5: - ram->fuc.r_mr[0] = ramfuc_reg(0x10f300); - ram->fuc.r_mr[1] = ramfuc_reg(0x10f330); - ram->fuc.r_mr[2] = ramfuc_reg(0x10f334); - ram->fuc.r_mr[3] = ramfuc_reg(0x10f338); - ram->fuc.r_mr[4] = ramfuc_reg(0x10f33c); - ram->fuc.r_mr[5] = ramfuc_reg(0x10f340); - ram->fuc.r_mr[6] = ramfuc_reg(0x10f344); - ram->fuc.r_mr[7] = ramfuc_reg(0x10f348); - ram->fuc.r_mr[8] = ramfuc_reg(0x10f354); - ram->fuc.r_mr[15] = ramfuc_reg(0x10f34c); - break; - case NV_MEM_TYPE_DDR3: - ram->fuc.r_mr[0] = ramfuc_reg(0x10f300); - ram->fuc.r_mr[2] = ramfuc_reg(0x10f320); - break; - default: - break; - } - - ram->fuc.r_0x62c000 = ramfuc_reg(0x62c000); - ram->fuc.r_0x10f200 = ramfuc_reg(0x10f200); - ram->fuc.r_0x10f210 = ramfuc_reg(0x10f210); - ram->fuc.r_0x10f310 = ramfuc_reg(0x10f310); - ram->fuc.r_0x10f314 = ramfuc_reg(0x10f314); - ram->fuc.r_0x10f318 = ramfuc_reg(0x10f318); - ram->fuc.r_0x10f090 = ramfuc_reg(0x10f090); - ram->fuc.r_0x10f69c = ramfuc_reg(0x10f69c); - ram->fuc.r_0x10f824 = ramfuc_reg(0x10f824); - ram->fuc.r_0x1373f0 = ramfuc_reg(0x1373f0); - ram->fuc.r_0x1373f4 = ramfuc_reg(0x1373f4); - ram->fuc.r_0x137320 = ramfuc_reg(0x137320); - ram->fuc.r_0x10f65c = ramfuc_reg(0x10f65c); - ram->fuc.r_0x10f6bc = ramfuc_reg(0x10f6bc); - ram->fuc.r_0x100710 = ramfuc_reg(0x100710); - ram->fuc.r_0x10f750 = ramfuc_reg(0x10f750); - return 0; -} - -struct nouveau_oclass -nve0_ram_oclass = { - .handle = 0, - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nve0_ram_ctor, - .dtor = _nouveau_ram_dtor, - .init = nve0_ram_init, - .fini = _nouveau_ram_fini, - } -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h deleted file mode 100644 index 571077e..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramseq.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __NVKM_FBRAM_SEQ_H__ -#define __NVKM_FBRAM_SEQ_H__ - -#include <subdev/bus.h> -#include <subdev/bus/hwsq.h> - -#define ram_init(s,p) hwsq_init(&(s)->base, (p)) -#define ram_exec(s,e) hwsq_exec(&(s)->base, (e)) -#define ram_have(s,r) ((s)->r_##r.addr != 0x000000) -#define ram_rd32(s,r) hwsq_rd32(&(s)->base, &(s)->r_##r) -#define ram_wr32(s,r,d) hwsq_wr32(&(s)->base, &(s)->r_##r, (d)) -#define ram_nuke(s,r) hwsq_nuke(&(s)->base, &(s)->r_##r) -#define ram_mask(s,r,m,d) hwsq_mask(&(s)->base, &(s)->r_##r, (m), (d)) -#define ram_setf(s,f,d) hwsq_setf(&(s)->base, (f), (d)) -#define ram_wait(s,f,d) hwsq_wait(&(s)->base, (f), (d)) -#define ram_nsec(s,n) hwsq_nsec(&(s)->base, (n)) - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c deleted file mode 100644 index ebd4cd9..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c +++ /dev/null @@ -1,99 +0,0 @@ -/* - * 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 <subdev/bios.h> -#include "priv.h" - -struct ramxlat { - int id; - u8 enc; -}; - -static inline int -ramxlat(const struct ramxlat *xlat, int id) -{ - while (xlat->id >= 0) { - if (xlat->id == id) - return xlat->enc; - xlat++; - } - return -EINVAL; -} - -static const struct ramxlat -ramddr3_cl[] = { - { 5, 2 }, { 6, 4 }, { 7, 6 }, { 8, 8 }, { 9, 10 }, { 10, 12 }, - { 11, 14 }, - /* the below are mentioned in some, but not all, ddr3 docs */ - { 12, 1 }, { 13, 3 }, { 14, 5 }, - { -1 } -}; - -static const struct ramxlat -ramddr3_wr[] = { - { 5, 1 }, { 6, 2 }, { 7, 3 }, { 8, 4 }, { 10, 5 }, { 12, 6 }, - /* the below are mentioned in some, but not all, ddr3 docs */ - { 14, 7 }, { 16, 0 }, - { -1 } -}; - -static const struct ramxlat -ramddr3_cwl[] = { - { 5, 0 }, { 6, 1 }, { 7, 2 }, { 8, 3 }, - /* the below are mentioned in some, but not all, ddr3 docs */ - { 9, 4 }, - { -1 } -}; - -int -nouveau_sddr3_calc(struct nouveau_ram *ram) -{ - struct nouveau_bios *bios = nouveau_bios(ram); - int WL, CL, WR; - - switch (!!ram->timing.data * ram->timing.version) { - case 0x20: - WL = (nv_ro16(bios, ram->timing.data + 0x04) & 0x0f80) >> 7; - CL = nv_ro08(bios, ram->timing.data + 0x04) & 0x1f; - WR = nv_ro08(bios, ram->timing.data + 0x0a) & 0x7f; - break; - default: - return -ENOSYS; - } - - WL = ramxlat(ramddr3_cwl, WL); - CL = ramxlat(ramddr3_cl, CL); - WR = ramxlat(ramddr3_wr, WR); - if (WL < 0 || CL < 0 || WR < 0) - return -EINVAL; - - ram->mr[0] &= ~0xe74; - ram->mr[0] |= (WR & 0x07) << 9; - ram->mr[0] |= (CL & 0x0e) << 3; - ram->mr[0] |= (CL & 0x01) << 2; - - ram->mr[2] &= ~0x038; - ram->mr[2] |= (WL & 0x07) << 3; - return 0; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c index f572c28..d422acc 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/base.c @@ -67,7 +67,7 @@ nouveau_gpio_find(struct nouveau_gpio *gpio, int idx, u8 tag, u8 line, } } - return -ENOENT; + return -EINVAL; } static int diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c index 041fd5e..2895c19 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c @@ -195,7 +195,7 @@ nouveau_i2c_find_type(struct nouveau_i2c *i2c, u16 type) static int nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what, - struct nouveau_i2c_board_info *info, + struct i2c_board_info *info, bool (*match)(struct nouveau_i2c_port *, struct i2c_board_info *)) { @@ -208,29 +208,12 @@ nouveau_i2c_identify(struct nouveau_i2c *i2c, int index, const char *what, } nv_debug(i2c, "probing %ss on bus: %d\n", what, port->index); - for (i = 0; info[i].dev.addr; i++) { - u8 orig_udelay = 0; - - if ((port->adapter.algo == &i2c_bit_algo) && - (info[i].udelay != 0)) { - struct i2c_algo_bit_data *algo = port->adapter.algo_data; - nv_debug(i2c, "using custom udelay %d instead of %d\n", - info[i].udelay, algo->udelay); - orig_udelay = algo->udelay; - algo->udelay = info[i].udelay; - } - - if (nv_probe_i2c(port, info[i].dev.addr) && - (!match || match(port, &info[i].dev))) { - nv_info(i2c, "detected %s: %s\n", what, - info[i].dev.type); + for (i = 0; info[i].addr; i++) { + if (nv_probe_i2c(port, info[i].addr) && + (!match || match(port, &info[i]))) { + nv_info(i2c, "detected %s: %s\n", what, info[i].type); return i; } - - if (orig_udelay) { - struct i2c_algo_bit_data *algo = port->adapter.algo_data; - algo->udelay = orig_udelay; - } } nv_debug(i2c, "no devices found.\n"); diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c index b4b9943..e290cfa 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/base.c @@ -25,48 +25,38 @@ #include <subdev/mc.h> #include <core/option.h> -static inline u32 -nouveau_mc_intr_mask(struct nouveau_mc *pmc) -{ - u32 intr = nv_rd32(pmc, 0x000100); - if (intr == 0xffffffff) /* likely fallen off the bus */ - intr = 0x00000000; - return intr; -} - static irqreturn_t nouveau_mc_intr(int irq, void *arg) { struct nouveau_mc *pmc = arg; - const struct nouveau_mc_oclass *oclass = (void *)nv_object(pmc)->oclass; - const struct nouveau_mc_intr *map = oclass->intr; + const struct nouveau_mc_intr *map = pmc->intr_map; + struct nouveau_device *device = nv_device(pmc); struct nouveau_subdev *unit; - u32 intr; + u32 stat, intr; + + intr = stat = nv_rd32(pmc, 0x000100); + if (intr == 0xffffffff) + return IRQ_NONE; + while (stat && map->stat) { + if (stat & map->stat) { + unit = nouveau_subdev(pmc, map->unit); + if (unit && unit->intr) + unit->intr(unit); + intr &= ~map->stat; + } + map++; + } - nv_wr32(pmc, 0x000140, 0x00000000); - nv_rd32(pmc, 0x000140); - intr = nouveau_mc_intr_mask(pmc); if (pmc->use_msi) - oclass->msi_rearm(pmc); + nv_wr08(pmc->base.base.parent, 0x00088068, 0xff); if (intr) { - u32 stat = intr = nouveau_mc_intr_mask(pmc); - while (map->stat) { - if (intr & map->stat) { - unit = nouveau_subdev(pmc, map->unit); - if (unit && unit->intr) - unit->intr(unit); - stat &= ~map->stat; - } - map++; - } - - if (stat) - nv_error(pmc, "unknown intr 0x%08x\n", stat); + nv_error(pmc, "unknown intr 0x%08x\n", stat); } - nv_wr32(pmc, 0x000140, 0x00000001); - return intr ? IRQ_HANDLED : IRQ_NONE; + if (stat == IRQ_HANDLED) + pm_runtime_mark_last_busy(&device->pdev->dev); + return stat ? IRQ_HANDLED : IRQ_NONE; } int @@ -101,42 +91,37 @@ _nouveau_mc_dtor(struct nouveau_object *object) int nouveau_mc_create_(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *bclass, int length, void **pobject) + struct nouveau_oclass *oclass, + const struct nouveau_mc_intr *intr_map, + int length, void **pobject) { - const struct nouveau_mc_oclass *oclass = (void *)bclass; struct nouveau_device *device = nv_device(parent); struct nouveau_mc *pmc; int ret; - ret = nouveau_subdev_create_(parent, engine, bclass, 0, "PMC", + ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PMC", "master", length, pobject); pmc = *pobject; if (ret) return ret; + pmc->intr_map = intr_map; + switch (device->pdev->device & 0x0ff0) { - case 0x00f0: - case 0x02e0: - /* BR02? NFI how these would be handled yet exactly */ + case 0x00f0: /* BR02? */ + case 0x02e0: /* BR02? */ + pmc->use_msi = false; break; default: - switch (device->chipset) { - case 0xaa: break; /* reported broken, nv also disable it */ - default: - pmc->use_msi = true; - break; - } - } - - pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", pmc->use_msi); - if (pmc->use_msi && oclass->msi_rearm) { - pmc->use_msi = pci_enable_msi(device->pdev) == 0; + pmc->use_msi = nouveau_boolopt(device->cfgopt, "NvMSI", false); if (pmc->use_msi) { - nv_info(pmc, "MSI interrupts enabled\n"); - oclass->msi_rearm(pmc); + pmc->use_msi = pci_enable_msi(device->pdev) == 0; + if (pmc->use_msi) { + nv_info(pmc, "MSI interrupts enabled\n"); + nv_wr08(device, 0x00088068, 0xff); + } } - } else { - pmc->use_msi = false; + break; } ret = request_irq(device->pdev->irq, nouveau_mc_intr, diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c index 2d787e4..64aa4ed 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.c @@ -22,14 +22,17 @@ * Authors: Ben Skeggs */ -#include "nv04.h" +#include <subdev/mc.h> + +struct nv04_mc_priv { + struct nouveau_mc base; +}; const struct nouveau_mc_intr nv04_mc_intr[] = { { 0x00000001, NVDEV_ENGINE_MPEG }, /* NV17- MPEG/ME */ { 0x00000100, NVDEV_ENGINE_FIFO }, { 0x00001000, NVDEV_ENGINE_GR }, - { 0x00010000, NVDEV_ENGINE_DISP }, { 0x00020000, NVDEV_ENGINE_VP }, /* NV40- */ { 0x00100000, NVDEV_SUBDEV_TIMER }, { 0x01000000, NVDEV_ENGINE_DISP }, /* NV04- PCRTC0 */ @@ -39,18 +42,7 @@ nv04_mc_intr[] = { {} }; -int -nv04_mc_init(struct nouveau_object *object) -{ - struct nv04_mc_priv *priv = (void *)object; - - nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */ - nv_wr32(priv, 0x001850, 0x00000001); /* disable rom access */ - - return nouveau_mc_init(&priv->base); -} - -int +static int nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nouveau_oclass *oclass, void *data, u32 size, struct nouveau_object **pobject) @@ -58,7 +50,7 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, struct nv04_mc_priv *priv; int ret; - ret = nouveau_mc_create(parent, engine, oclass, &priv); + ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv); *pobject = nv_object(priv); if (ret) return ret; @@ -66,14 +58,24 @@ nv04_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, return 0; } -struct nouveau_oclass * -nv04_mc_oclass = &(struct nouveau_mc_oclass) { - .base.handle = NV_SUBDEV(MC, 0x04), - .base.ofuncs = &(struct nouveau_ofuncs) { +int +nv04_mc_init(struct nouveau_object *object) +{ + struct nv04_mc_priv *priv = (void *)object; + + nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */ + nv_wr32(priv, 0x001850, 0x00000001); /* disable rom access */ + + return nouveau_mc_init(&priv->base); +} + +struct nouveau_oclass +nv04_mc_oclass = { + .handle = NV_SUBDEV(MC, 0x04), + .ofuncs = &(struct nouveau_ofuncs) { .ctor = nv04_mc_ctor, .dtor = _nouveau_mc_dtor, .init = nv04_mc_init, .fini = _nouveau_mc_fini, }, - .intr = nv04_mc_intr, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h b/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h deleted file mode 100644 index b0d5c31..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv04.h +++ /dev/null @@ -1,21 +0,0 @@ -#ifndef __NVKM_MC_NV04_H__ -#define __NVKM_MC_NV04_H__ - -#include <subdev/mc.h> - -struct nv04_mc_priv { - struct nouveau_mc base; -}; - -int nv04_mc_ctor(struct nouveau_object *, struct nouveau_object *, - struct nouveau_oclass *, void *, u32, - struct nouveau_object **); - -extern const struct nouveau_mc_intr nv04_mc_intr[]; -int nv04_mc_init(struct nouveau_object *); -void nv40_mc_msi_rearm(struct nouveau_mc *); -int nv50_mc_init(struct nouveau_object *); -extern const struct nouveau_mc_intr nv50_mc_intr[]; -extern const struct nouveau_mc_intr nvc0_mc_intr[]; - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c deleted file mode 100644 index 5b1faec..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv40.c +++ /dev/null @@ -1,45 +0,0 @@ -/* - * 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 "nv04.h" - -void -nv40_mc_msi_rearm(struct nouveau_mc *pmc) -{ - struct nv04_mc_priv *priv = (void *)pmc; - nv_wr08(priv, 0x088068, 0xff); -} - -struct nouveau_oclass * -nv40_mc_oclass = &(struct nouveau_mc_oclass) { - .base.handle = NV_SUBDEV(MC, 0x40), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_mc_ctor, - .dtor = _nouveau_mc_dtor, - .init = nv04_mc_init, - .fini = _nouveau_mc_fini, - }, - .intr = nv04_mc_intr, - .msi_rearm = nv40_mc_msi_rearm, -}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c index 3bfee5c..d989178 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv44.c @@ -22,12 +22,32 @@ * Authors: Ben Skeggs */ -#include "nv04.h" +#include <subdev/mc.h> + +struct nv44_mc_priv { + struct nouveau_mc base; +}; + +static int +nv44_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv44_mc_priv *priv; + int ret; + + ret = nouveau_mc_create(parent, engine, oclass, nv04_mc_intr, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + return 0; +} static int nv44_mc_init(struct nouveau_object *object) { - struct nv04_mc_priv *priv = (void *)object; + struct nv44_mc_priv *priv = (void *)object; u32 tmp = nv_rd32(priv, 0x10020c); nv_wr32(priv, 0x000200, 0xffffffff); /* everything enabled */ @@ -40,15 +60,13 @@ nv44_mc_init(struct nouveau_object *object) return nouveau_mc_init(&priv->base); } -struct nouveau_oclass * -nv44_mc_oclass = &(struct nouveau_mc_oclass) { - .base.handle = NV_SUBDEV(MC, 0x44), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_mc_ctor, +struct nouveau_oclass +nv44_mc_oclass = { + .handle = NV_SUBDEV(MC, 0x44), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv44_mc_ctor, .dtor = _nouveau_mc_dtor, .init = nv44_mc_init, .fini = _nouveau_mc_fini, }, - .intr = nv04_mc_intr, - .msi_rearm = nv40_mc_msi_rearm, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c index e8822a9..2b1afe2 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv50.c @@ -22,9 +22,13 @@ * Authors: Ben Skeggs */ -#include "nv04.h" +#include <subdev/mc.h> -const struct nouveau_mc_intr +struct nv50_mc_priv { + struct nouveau_mc base; +}; + +static const struct nouveau_mc_intr nv50_mc_intr[] = { { 0x00000001, NVDEV_ENGINE_MPEG }, { 0x00000100, NVDEV_ENGINE_FIFO }, @@ -41,30 +45,37 @@ nv50_mc_intr[] = { {}, }; -static void -nv50_mc_msi_rearm(struct nouveau_mc *pmc) +static int +nv50_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { - struct nouveau_device *device = nv_device(pmc); - pci_write_config_byte(device->pdev, 0x68, 0xff); + struct nv50_mc_priv *priv; + int ret; + + ret = nouveau_mc_create(parent, engine, oclass, nv50_mc_intr, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + return 0; } int nv50_mc_init(struct nouveau_object *object) { - struct nv04_mc_priv *priv = (void *)object; + struct nv50_mc_priv *priv = (void *)object; nv_wr32(priv, 0x000200, 0xffffffff); /* everything on */ return nouveau_mc_init(&priv->base); } -struct nouveau_oclass * -nv50_mc_oclass = &(struct nouveau_mc_oclass) { - .base.handle = NV_SUBDEV(MC, 0x50), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_mc_ctor, +struct nouveau_oclass +nv50_mc_oclass = { + .handle = NV_SUBDEV(MC, 0x50), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv50_mc_ctor, .dtor = _nouveau_mc_dtor, .init = nv50_mc_init, .fini = _nouveau_mc_fini, }, - .intr = nv50_mc_intr, - .msi_rearm = nv50_mc_msi_rearm, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c deleted file mode 100644 index 5f45411..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv94.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 "nv04.h" - -struct nouveau_oclass * -nv94_mc_oclass = &(struct nouveau_mc_oclass) { - .base.handle = NV_SUBDEV(MC, 0x94), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_mc_ctor, - .dtor = _nouveau_mc_dtor, - .init = nv50_mc_init, - .fini = _nouveau_mc_fini, - }, - .intr = nv50_mc_intr, - .msi_rearm = nv40_mc_msi_rearm, -}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c index f8a6f18..0671041 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv98.c @@ -22,7 +22,11 @@ * Authors: Ben Skeggs */ -#include "nv04.h" +#include <subdev/mc.h> + +struct nv98_mc_priv { + struct nouveau_mc base; +}; static const struct nouveau_mc_intr nv98_mc_intr[] = { @@ -32,7 +36,6 @@ nv98_mc_intr[] = { { 0x00004000, NVDEV_ENGINE_CRYPT }, /* NV84:NVA3 */ { 0x00008000, NVDEV_ENGINE_BSP }, { 0x00020000, NVDEV_ENGINE_VP }, - { 0x00040000, NVDEV_SUBDEV_PWR }, /* NVA3:NVC0 */ { 0x00080000, NVDEV_SUBDEV_THERM }, /* NVA3:NVC0 */ { 0x00100000, NVDEV_SUBDEV_TIMER }, { 0x00200000, NVDEV_SUBDEV_GPIO }, @@ -44,15 +47,29 @@ nv98_mc_intr[] = { {}, }; -struct nouveau_oclass * -nv98_mc_oclass = &(struct nouveau_mc_oclass) { - .base.handle = NV_SUBDEV(MC, 0x98), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_mc_ctor, +static int +nv98_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) +{ + struct nv98_mc_priv *priv; + int ret; + + ret = nouveau_mc_create(parent, engine, oclass, nv98_mc_intr, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + return 0; +} + +struct nouveau_oclass +nv98_mc_oclass = { + .handle = NV_SUBDEV(MC, 0x98), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nv98_mc_ctor, .dtor = _nouveau_mc_dtor, .init = nv50_mc_init, .fini = _nouveau_mc_fini, }, - .intr = nv98_mc_intr, - .msi_rearm = nv40_mc_msi_rearm, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c index c02b476..104175c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc0.c @@ -22,9 +22,13 @@ * Authors: Ben Skeggs */ -#include "nv04.h" +#include <subdev/mc.h> -const struct nouveau_mc_intr +struct nvc0_mc_priv { + struct nouveau_mc base; +}; + +static const struct nouveau_mc_intr nvc0_mc_intr[] = { { 0x00000001, NVDEV_ENGINE_PPP }, { 0x00000020, NVDEV_ENGINE_COPY0 }, @@ -37,7 +41,6 @@ nvc0_mc_intr[] = { { 0x00020000, NVDEV_ENGINE_VP }, { 0x00100000, NVDEV_SUBDEV_TIMER }, { 0x00200000, NVDEV_SUBDEV_GPIO }, - { 0x01000000, NVDEV_SUBDEV_PWR }, { 0x02000000, NVDEV_SUBDEV_LTCG }, { 0x04000000, NVDEV_ENGINE_DISP }, { 0x10000000, NVDEV_SUBDEV_BUS }, @@ -46,22 +49,29 @@ nvc0_mc_intr[] = { {}, }; -static void -nvc0_mc_msi_rearm(struct nouveau_mc *pmc) +static int +nvc0_mc_ctor(struct nouveau_object *parent, struct nouveau_object *engine, + struct nouveau_oclass *oclass, void *data, u32 size, + struct nouveau_object **pobject) { - struct nv04_mc_priv *priv = (void *)pmc; - nv_wr32(priv, 0x088704, 0x00000000); + struct nvc0_mc_priv *priv; + int ret; + + ret = nouveau_mc_create(parent, engine, oclass, nvc0_mc_intr, &priv); + *pobject = nv_object(priv); + if (ret) + return ret; + + return 0; } -struct nouveau_oclass * -nvc0_mc_oclass = &(struct nouveau_mc_oclass) { - .base.handle = NV_SUBDEV(MC, 0xc0), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_mc_ctor, +struct nouveau_oclass +nvc0_mc_oclass = { + .handle = NV_SUBDEV(MC, 0xc0), + .ofuncs = &(struct nouveau_ofuncs) { + .ctor = nvc0_mc_ctor, .dtor = _nouveau_mc_dtor, .init = nv50_mc_init, .fini = _nouveau_mc_fini, }, - .intr = nvc0_mc_intr, - .msi_rearm = nvc0_mc_msi_rearm, -}.base; +}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c deleted file mode 100644 index 837e545..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nvc3.c +++ /dev/null @@ -1,38 +0,0 @@ -/* - * 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 "nv04.h" - -struct nouveau_oclass * -nvc3_mc_oclass = &(struct nouveau_mc_oclass) { - .base.handle = NV_SUBDEV(MC, 0xc3), - .base.ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv04_mc_ctor, - .dtor = _nouveau_mc_dtor, - .init = nv50_mc_init, - .fini = _nouveau_mc_fini, - }, - .intr = nvc0_mc_intr, - .msi_rearm = nv40_mc_msi_rearm, -}.base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c index 1291204..e286e13 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mxm/base.c @@ -116,7 +116,7 @@ mxm_shadow_dsm(struct nouveau_mxm *mxm, u8 version) acpi_handle handle; int ret; - handle = ACPI_HANDLE(&device->pdev->dev); + handle = DEVICE_ACPI_HANDLE(&device->pdev->dev); if (!handle) return false; diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c deleted file mode 100644 index d4fd3bc9..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/base.c +++ /dev/null @@ -1,247 +0,0 @@ -/* - * 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 <subdev/pwr.h> -#include <subdev/timer.h> - -static int -nouveau_pwr_send(struct nouveau_pwr *ppwr, u32 reply[2], - u32 process, u32 message, u32 data0, u32 data1) -{ - struct nouveau_subdev *subdev = nv_subdev(ppwr); - u32 addr; - - /* wait for a free slot in the fifo */ - addr = nv_rd32(ppwr, 0x10a4a0); - if (!nv_wait_ne(ppwr, 0x10a4b0, 0xffffffff, addr ^ 8)) - return -EBUSY; - - /* we currently only support a single process at a time waiting - * on a synchronous reply, take the PPWR mutex and tell the - * receive handler what we're waiting for - */ - if (reply) { - mutex_lock(&subdev->mutex); - ppwr->recv.message = message; - ppwr->recv.process = process; - } - - /* acquire data segment access */ - do { - nv_wr32(ppwr, 0x10a580, 0x00000001); - } while (nv_rd32(ppwr, 0x10a580) != 0x00000001); - - /* write the packet */ - nv_wr32(ppwr, 0x10a1c0, 0x01000000 | (((addr & 0x07) << 4) + - ppwr->send.base)); - nv_wr32(ppwr, 0x10a1c4, process); - nv_wr32(ppwr, 0x10a1c4, message); - nv_wr32(ppwr, 0x10a1c4, data0); - nv_wr32(ppwr, 0x10a1c4, data1); - nv_wr32(ppwr, 0x10a4a0, (addr + 1) & 0x0f); - - /* release data segment access */ - nv_wr32(ppwr, 0x10a580, 0x00000000); - - /* wait for reply, if requested */ - if (reply) { - wait_event(ppwr->recv.wait, (ppwr->recv.process == 0)); - reply[0] = ppwr->recv.data[0]; - reply[1] = ppwr->recv.data[1]; - mutex_unlock(&subdev->mutex); - } - - return 0; -} - -static void -nouveau_pwr_recv(struct work_struct *work) -{ - struct nouveau_pwr *ppwr = - container_of(work, struct nouveau_pwr, recv.work); - u32 process, message, data0, data1; - - /* nothing to do if GET == PUT */ - u32 addr = nv_rd32(ppwr, 0x10a4cc); - if (addr == nv_rd32(ppwr, 0x10a4c8)) - return; - - /* acquire data segment access */ - do { - nv_wr32(ppwr, 0x10a580, 0x00000002); - } while (nv_rd32(ppwr, 0x10a580) != 0x00000002); - - /* read the packet */ - nv_wr32(ppwr, 0x10a1c0, 0x02000000 | (((addr & 0x07) << 4) + - ppwr->recv.base)); - process = nv_rd32(ppwr, 0x10a1c4); - message = nv_rd32(ppwr, 0x10a1c4); - data0 = nv_rd32(ppwr, 0x10a1c4); - data1 = nv_rd32(ppwr, 0x10a1c4); - nv_wr32(ppwr, 0x10a4cc, (addr + 1) & 0x0f); - - /* release data segment access */ - nv_wr32(ppwr, 0x10a580, 0x00000000); - - /* wake process if it's waiting on a synchronous reply */ - if (ppwr->recv.process) { - if (process == ppwr->recv.process && - message == ppwr->recv.message) { - ppwr->recv.data[0] = data0; - ppwr->recv.data[1] = data1; - ppwr->recv.process = 0; - wake_up(&ppwr->recv.wait); - return; - } - } - - /* right now there's no other expected responses from the engine, - * so assume that any unexpected message is an error. - */ - nv_warn(ppwr, "%c%c%c%c 0x%08x 0x%08x 0x%08x 0x%08x\n", - (char)((process & 0x000000ff) >> 0), - (char)((process & 0x0000ff00) >> 8), - (char)((process & 0x00ff0000) >> 16), - (char)((process & 0xff000000) >> 24), - process, message, data0, data1); -} - -static void -nouveau_pwr_intr(struct nouveau_subdev *subdev) -{ - struct nouveau_pwr *ppwr = (void *)subdev; - u32 disp = nv_rd32(ppwr, 0x10a01c); - u32 intr = nv_rd32(ppwr, 0x10a008) & disp & ~(disp >> 16); - - if (intr & 0x00000020) { - u32 stat = nv_rd32(ppwr, 0x10a16c); - if (stat & 0x80000000) { - nv_error(ppwr, "UAS fault at 0x%06x addr 0x%08x\n", - stat & 0x00ffffff, nv_rd32(ppwr, 0x10a168)); - nv_wr32(ppwr, 0x10a16c, 0x00000000); - intr &= ~0x00000020; - } - } - - if (intr & 0x00000040) { - schedule_work(&ppwr->recv.work); - nv_wr32(ppwr, 0x10a004, 0x00000040); - intr &= ~0x00000040; - } - - if (intr & 0x00000080) { - nv_info(ppwr, "wr32 0x%06x 0x%08x\n", nv_rd32(ppwr, 0x10a7a0), - nv_rd32(ppwr, 0x10a7a4)); - nv_wr32(ppwr, 0x10a004, 0x00000080); - intr &= ~0x00000080; - } - - if (intr) { - nv_error(ppwr, "intr 0x%08x\n", intr); - nv_wr32(ppwr, 0x10a004, intr); - } -} - -int -_nouveau_pwr_fini(struct nouveau_object *object, bool suspend) -{ - struct nouveau_pwr *ppwr = (void *)object; - - nv_wr32(ppwr, 0x10a014, 0x00000060); - flush_work(&ppwr->recv.work); - - return nouveau_subdev_fini(&ppwr->base, suspend); -} - -int -_nouveau_pwr_init(struct nouveau_object *object) -{ - struct nouveau_pwr *ppwr = (void *)object; - int ret, i; - - ret = nouveau_subdev_init(&ppwr->base); - if (ret) - return ret; - - nv_subdev(ppwr)->intr = nouveau_pwr_intr; - ppwr->message = nouveau_pwr_send; - - /* prevent previous ucode from running, wait for idle, reset */ - nv_wr32(ppwr, 0x10a014, 0x0000ffff); /* INTR_EN_CLR = ALL */ - nv_wait(ppwr, 0x10a04c, 0xffffffff, 0x00000000); - nv_mask(ppwr, 0x000200, 0x00002000, 0x00000000); - nv_mask(ppwr, 0x000200, 0x00002000, 0x00002000); - - /* upload data segment */ - nv_wr32(ppwr, 0x10a1c0, 0x01000000); - for (i = 0; i < ppwr->data.size / 4; i++) - nv_wr32(ppwr, 0x10a1c4, ppwr->data.data[i]); - - /* upload code segment */ - nv_wr32(ppwr, 0x10a180, 0x01000000); - for (i = 0; i < ppwr->code.size / 4; i++) { - if ((i & 0x3f) == 0) - nv_wr32(ppwr, 0x10a188, i >> 6); - nv_wr32(ppwr, 0x10a184, ppwr->code.data[i]); - } - - /* start it running */ - nv_wr32(ppwr, 0x10a10c, 0x00000000); - nv_wr32(ppwr, 0x10a104, 0x00000000); - nv_wr32(ppwr, 0x10a100, 0x00000002); - - /* wait for valid host->pwr ring configuration */ - if (!nv_wait_ne(ppwr, 0x10a4d0, 0xffffffff, 0x00000000)) - return -EBUSY; - ppwr->send.base = nv_rd32(ppwr, 0x10a4d0) & 0x0000ffff; - ppwr->send.size = nv_rd32(ppwr, 0x10a4d0) >> 16; - - /* wait for valid pwr->host ring configuration */ - if (!nv_wait_ne(ppwr, 0x10a4dc, 0xffffffff, 0x00000000)) - return -EBUSY; - ppwr->recv.base = nv_rd32(ppwr, 0x10a4dc) & 0x0000ffff; - ppwr->recv.size = nv_rd32(ppwr, 0x10a4dc) >> 16; - - nv_wr32(ppwr, 0x10a010, 0x000000e0); - return 0; -} - -int -nouveau_pwr_create_(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, int length, void **pobject) -{ - struct nouveau_pwr *ppwr; - int ret; - - ret = nouveau_subdev_create_(parent, engine, oclass, 0, "PPWR", - "pwr", length, pobject); - ppwr = *pobject; - if (ret) - return ret; - - INIT_WORK(&ppwr->recv.work, nouveau_pwr_recv); - init_waitqueue_head(&ppwr->recv.wait); - return 0; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc deleted file mode 100644 index 2284ecb..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc +++ /dev/null @@ -1,151 +0,0 @@ -/* - * 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 - */ - -#ifdef INCLUDE_PROC -process(PROC_HOST, #host_init, #host_recv) -#endif - -/****************************************************************************** - * HOST data segment - *****************************************************************************/ -#ifdef INCLUDE_DATA -// HOST (R)FIFO packet format -.equ #fifo_process 0x00 -.equ #fifo_message 0x04 -.equ #fifo_data0 0x08 -.equ #fifo_data1 0x0c - -// HOST HOST->PWR queue description -.equ #fifo_qlen 4 // log2(size of queue entry in bytes) -.equ #fifo_qnum 3 // log2(max number of entries in queue) -.equ #fifo_qmaskb (1 << #fifo_qnum) // max number of entries in queue -.equ #fifo_qmaskp (#fifo_qmaskb - 1) -.equ #fifo_qmaskf ((#fifo_qmaskb << 1) - 1) -.equ #fifo_qsize (1 << (#fifo_qlen + #fifo_qnum)) -fifo_queue: .skip 128 // #fifo_qsize - -// HOST PWR->HOST queue description -.equ #rfifo_qlen 4 // log2(size of queue entry in bytes) -.equ #rfifo_qnum 3 // log2(max number of entries in queue) -.equ #rfifo_qmaskb (1 << #rfifo_qnum) // max number of entries in queue -.equ #rfifo_qmaskp (#rfifo_qmaskb - 1) -.equ #rfifo_qmaskf ((#rfifo_qmaskb << 1) - 1) -.equ #rfifo_qsize (1 << (#rfifo_qlen + #rfifo_qnum)) -rfifo_queue: .skip 128 // #rfifo_qsize -#endif - -/****************************************************************************** - * HOST code segment - *****************************************************************************/ -#ifdef INCLUDE_CODE -// HOST->PWR comms - dequeue message(s) for process(es) from FIFO -// -// $r15 - current (host) -// $r0 - zero -host_send: - nv_iord($r1, NV_PPWR_FIFO_GET(0)) - nv_iord($r2, NV_PPWR_FIFO_PUT(0)) - cmp b32 $r1 $r2 - bra e #host_send_done - // calculate address of message - and $r14 $r1 #fifo_qmaskp - shl b32 $r14 $r14 #fifo_qlen - add b32 $r14 #fifo_queue - - // read message data, and pass to appropriate process - ld b32 $r11 D[$r14 + #fifo_data1] - ld b32 $r12 D[$r14 + #fifo_data0] - ld b32 $r13 D[$r14 + #fifo_message] - ld b32 $r14 D[$r14 + #fifo_process] - call(send) - - // increment GET - add b32 $r1 0x1 - and $r14 $r1 #fifo_qmaskf - nv_iowr(NV_PPWR_FIFO_GET(0), $r1) - bra #host_send - host_send_done: - ret - -// PWR->HOST comms - enqueue message for HOST to RFIFO -// -// $r15 - current (host) -// $r14 - process -// $r13 - message -// $r12 - message data 0 -// $r11 - message data 1 -// $r0 - zero -host_recv: - // message from intr handler == HOST->PWR comms pending - mov $r1 (PROC_KERN & 0x0000ffff) - sethi $r1 (PROC_KERN & 0xffff0000) - cmp b32 $r14 $r1 - bra e #host_send - - // wait for space in RFIFO - host_recv_wait: - nv_iord($r1, NV_PPWR_RFIFO_GET) - nv_iord($r2, NV_PPWR_RFIFO_PUT) - xor $r1 #rfifo_qmaskb - cmp b32 $r1 $r2 - bra e #host_recv_wait - - and $r3 $r2 #rfifo_qmaskp - shl b32 $r3 #rfifo_qlen - add b32 $r3 #rfifo_queue - - // enqueue message - st b32 D[$r3 + #fifo_data1] $r11 - st b32 D[$r3 + #fifo_data0] $r12 - st b32 D[$r3 + #fifo_message] $r13 - st b32 D[$r3 + #fifo_process] $r14 - - add b32 $r2 0x1 - and $r2 #rfifo_qmaskf - nv_iowr(NV_PPWR_RFIFO_PUT, $r2) - - // notify host of pending message - mov $r2 NV_PPWR_INTR_TRIGGER_USER0 - nv_iowr(NV_PPWR_INTR_TRIGGER, $r2) - ret - -// $r15 - current (host) -// $r0 - zero -host_init: - // store each fifo's base/size in H2D/D2H scratch regs - mov $r1 #fifo_qsize - shl b32 $r1 16 - or $r1 #fifo_queue - nv_iowr(NV_PPWR_H2D, $r1); - - mov $r1 #rfifo_qsize - shl b32 $r1 16 - or $r1 #rfifo_queue - nv_iowr(NV_PPWR_D2H, $r1); - - // enable fifo subintr for first fifo - mov $r1 1 - nv_iowr(NV_PPWR_FIFO_INTR_EN, $r1) - ret -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc deleted file mode 100644 index 98f1c37..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc +++ /dev/null @@ -1,84 +0,0 @@ -/* - * 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 - */ - -#ifdef INCLUDE_PROC -process(PROC_IDLE, #idle, #idle_recv) -#endif - -/****************************************************************************** - * IDLE data segment - *****************************************************************************/ -#ifdef INCLUDE_DATA -#endif - -/****************************************************************************** - * IDLE code segment - *****************************************************************************/ -#ifdef INCLUDE_CODE -// description -// -// $r15 - current (idle) -// $r14 - message -// $r0 - zero -idle_recv: - ret - -// description -// -// $r15 - current (idle) -// $r0 - zero -idle: - // set our "no interrupt has occurred during our execution" flag - bset $flags $p0 - - // count IDLE invocations for debugging purposes - nv_iord($r1, NV_PPWR_DSCRATCH(1)) - add b32 $r1 1 - nv_iowr(NV_PPWR_DSCRATCH(1), $r1) - - // keep looping while there's pending messages for any process - idle_loop: - mov $r1 #proc_list_head - bclr $flags $p2 - idle_proc: - // process the process' messages until there's none left - idle_proc_exec: - push $r1 - mov b32 $r14 $r1 - call(recv) - pop $r1 - bra not $p1 #idle_proc_next - bset $flags $p2 - bra #idle_proc_exec - // next process! - idle_proc_next: - add b32 $r1 #proc_size - cmp b32 $r1 $r15 - bra ne #idle_proc - bra $p2 #idle_loop - - // sleep if no interrupts have occurred - sleep $p0 - bra #idle -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc deleted file mode 100644 index 0a7b05f..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc +++ /dev/null @@ -1,452 +0,0 @@ -/* - * 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 - */ - -/****************************************************************************** - * kernel data segment - *****************************************************************************/ -#ifdef INCLUDE_PROC -proc_kern: -process(PROC_KERN, 0, 0) -proc_list_head: -#endif - -#ifdef INCLUDE_DATA -proc_list_tail: -time_prev: .b32 0 -time_next: .b32 0 -#endif - -/****************************************************************************** - * kernel code segment - *****************************************************************************/ -#ifdef INCLUDE_CODE - bra #init - -// read nv register -// -// $r15 - current -// $r14 - addr -// $r13 - data (return) -// $r0 - zero -rd32: - nv_iowr(NV_PPWR_MMIO_ADDR, $r14) - mov $r14 NV_PPWR_MMIO_CTRL_OP_RD - sethi $r14 NV_PPWR_MMIO_CTRL_TRIGGER - nv_iowr(NV_PPWR_MMIO_CTRL, $r14) - rd32_wait: - nv_iord($r14, NV_PPWR_MMIO_CTRL) - and $r14 NV_PPWR_MMIO_CTRL_STATUS - bra nz #rd32_wait - nv_iord($r13, NV_PPWR_MMIO_DATA) - ret - -// write nv register -// -// $r15 - current -// $r14 - addr -// $r13 - data -// $r0 - zero -wr32: - nv_iowr(NV_PPWR_MMIO_ADDR, $r14) - nv_iowr(NV_PPWR_MMIO_DATA, $r13) - mov $r14 NV_PPWR_MMIO_CTRL_OP_WR - or $r14 NV_PPWR_MMIO_CTRL_MASK_B32_0 - sethi $r14 NV_PPWR_MMIO_CTRL_TRIGGER - -#ifdef NVKM_FALCON_MMIO_TRAP - mov $r8 NV_PPWR_INTR_TRIGGER_USER1 - nv_iowr(NV_PPWR_INTR_TRIGGER, $r8) - wr32_host: - nv_iord($r8, NV_PPWR_INTR) - and $r8 NV_PPWR_INTR_USER1 - bra nz #wr32_host -#endif - - nv_iowr(NV_PPWR_MMIO_CTRL, $r14) - wr32_wait: - nv_iord($r14, NV_PPWR_MMIO_CTRL) - and $r14 NV_PPWR_MMIO_CTRL_STATUS - bra nz #wr32_wait - ret - -// busy-wait for a period of time -// -// $r15 - current -// $r14 - ns -// $r0 - zero -nsec: - nv_iord($r8, NV_PPWR_TIMER_LOW) - nsec_loop: - nv_iord($r9, NV_PPWR_TIMER_LOW) - sub b32 $r9 $r8 - cmp b32 $r9 $r14 - bra l #nsec_loop - ret - -// busy-wait for a period of time -// -// $r15 - current -// $r14 - addr -// $r13 - mask -// $r12 - data -// $r11 - timeout (ns) -// $r0 - zero -wait: - nv_iord($r8, NV_PPWR_TIMER_LOW) - wait_loop: - nv_rd32($r10, $r14) - and $r10 $r13 - cmp b32 $r10 $r12 - bra e #wait_done - nv_iord($r9, NV_PPWR_TIMER_LOW) - sub b32 $r9 $r8 - cmp b32 $r9 $r11 - bra l #wait_loop - wait_done: - ret - -// $r15 - current (kern) -// $r14 - process -// $r8 - NV_PPWR_INTR -intr_watchdog: - // read process' timer status, skip if not enabled - ld b32 $r9 D[$r14 + #proc_time] - cmp b32 $r9 0 - bra z #intr_watchdog_next_proc - - // subtract last timer's value from process' timer, - // if it's <= 0 then the timer has expired - ld b32 $r10 D[$r0 + #time_prev] - sub b32 $r9 $r10 - bra g #intr_watchdog_next_time - mov $r13 KMSG_ALARM - call(send_proc) - clear b32 $r9 - bra #intr_watchdog_next_proc - - // otherwise, update the next timer's value if this - // process' timer is the soonest - intr_watchdog_next_time: - // ... or if there's no next timer yet - ld b32 $r10 D[$r0 + #time_next] - cmp b32 $r10 0 - bra z #intr_watchdog_next_time_set - - cmp b32 $r9 $r10 - bra g #intr_watchdog_next_proc - intr_watchdog_next_time_set: - st b32 D[$r0 + #time_next] $r9 - - // update process' timer status, and advance - intr_watchdog_next_proc: - st b32 D[$r14 + #proc_time] $r9 - add b32 $r14 #proc_size - cmp b32 $r14 #proc_list_tail - bra ne #intr_watchdog - ret - -intr: - push $r0 - clear b32 $r0 - push $r8 - push $r9 - push $r10 - push $r11 - push $r12 - push $r13 - push $r14 - push $r15 - mov $r15 #proc_kern - mov $r8 $flags - push $r8 - - nv_iord($r8, NV_PPWR_DSCRATCH(0)) - add b32 $r8 1 - nv_iowr(NV_PPWR_DSCRATCH(0), $r8) - - nv_iord($r8, NV_PPWR_INTR) - and $r9 $r8 NV_PPWR_INTR_WATCHDOG - bra z #intr_skip_watchdog - st b32 D[$r0 + #time_next] $r0 - mov $r14 #proc_list_head - call(intr_watchdog) - ld b32 $r9 D[$r0 + #time_next] - cmp b32 $r9 0 - bra z #intr_skip_watchdog - nv_iowr(NV_PPWR_WATCHDOG_TIME, $r9) - st b32 D[$r0 + #time_prev] $r9 - - intr_skip_watchdog: - and $r9 $r8 NV_PPWR_INTR_SUBINTR - bra z #intr_skip_subintr - nv_iord($r9, NV_PPWR_SUBINTR) - and $r10 $r9 NV_PPWR_SUBINTR_FIFO - bra z #intr_subintr_skip_fifo - nv_iord($r12, NV_PPWR_FIFO_INTR) - push $r12 - mov $r14 (PROC_HOST & 0x0000ffff) - sethi $r14 (PROC_HOST & 0xffff0000) - mov $r13 KMSG_FIFO - call(send) - pop $r12 - nv_iowr(NV_PPWR_FIFO_INTR, $r12) - intr_subintr_skip_fifo: - nv_iowr(NV_PPWR_SUBINTR, $r9) - - intr_skip_subintr: - and $r9 $r8 NV_PPWR_INTR_PAUSE - bra z #intr_skip_pause - and $r10 0xffbf - - intr_skip_pause: - and $r9 $r8 NV_PPWR_INTR_USER0 - bra z #intr_skip_user0 - and $r10 0xffbf - - intr_skip_user0: - nv_iowr(NV_PPWR_INTR_ACK, $r8) - pop $r8 - mov $flags $r8 - pop $r15 - pop $r14 - pop $r13 - pop $r12 - pop $r11 - pop $r10 - pop $r9 - pop $r8 - pop $r0 - bclr $flags $p0 - iret - -// request the current process be sent a message after a timeout expires -// -// $r15 - current -// $r14 - ticks -// $r0 - zero -timer: - // interrupts off to prevent racing with timer isr - bclr $flags ie0 - - // if current process already has a timer set, bail - ld b32 $r8 D[$r15 + #proc_time] - cmp b32 $r8 0 - bra g #timer_done - st b32 D[$r15 + #proc_time] $r14 - - // halt watchdog timer temporarily and check for a pending - // interrupt. if there's one already pending, we can just - // bail since the timer isr will queue the next soonest - // right after it's done - nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r8) - nv_iord($r8, NV_PPWR_INTR) - and $r8 NV_PPWR_INTR_WATCHDOG - bra nz #timer_enable - - // update the watchdog if this timer should expire first, - // or if there's no timeout already set - nv_iord($r8, NV_PPWR_WATCHDOG_TIME) - cmp b32 $r14 $r0 - bra e #timer_reset - cmp b32 $r14 $r8 - bra l #timer_done - timer_reset: - nv_iowr(NV_PPWR_WATCHDOG_TIME, $r14) - st b32 D[$r0 + #time_prev] $r14 - - // re-enable the watchdog timer - timer_enable: - mov $r8 1 - nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r8) - - // interrupts back on - timer_done: - bset $flags ie0 - ret - -// send message to another process -// -// $r15 - current -// $r14 - process -// $r13 - message -// $r12 - message data 0 -// $r11 - message data 1 -// $r0 - zero -send_proc: - push $r8 - push $r9 - // check for space in queue - ld b32 $r8 D[$r14 + #proc_qget] - ld b32 $r9 D[$r14 + #proc_qput] - xor $r8 #proc_qmaskb - cmp b32 $r8 $r9 - bra e #send_done - - // enqueue message - and $r8 $r9 #proc_qmaskp - shl b32 $r8 $r8 #proc_qlen - add b32 $r8 #proc_queue - add b32 $r8 $r14 - - ld b32 $r10 D[$r15 + #proc_id] - st b32 D[$r8 + #msg_process] $r10 - st b32 D[$r8 + #msg_message] $r13 - st b32 D[$r8 + #msg_data0] $r12 - st b32 D[$r8 + #msg_data1] $r11 - - // increment PUT - add b32 $r9 1 - and $r9 #proc_qmaskf - st b32 D[$r14 + #proc_qput] $r9 - bset $flags $p2 - send_done: - pop $r9 - pop $r8 - ret - -// lookup process structure by its name -// -// $r15 - current -// $r14 - process name -// $r0 - zero -// -// $r14 - process -// $p1 - success -find: - push $r8 - mov $r8 #proc_list_head - bset $flags $p1 - find_loop: - ld b32 $r10 D[$r8 + #proc_id] - cmp b32 $r10 $r14 - bra e #find_done - add b32 $r8 #proc_size - cmp b32 $r8 #proc_list_tail - bra ne #find_loop - bclr $flags $p1 - find_done: - mov b32 $r14 $r8 - pop $r8 - ret - -// send message to another process -// -// $r15 - current -// $r14 - process id -// $r13 - message -// $r12 - message data 0 -// $r11 - message data 1 -// $r0 - zero -send: - call(find) - bra $p1 #send_proc - ret - -// process single message for a given process -// -// $r15 - current -// $r14 - process -// $r0 - zero -recv: - ld b32 $r8 D[$r14 + #proc_qget] - ld b32 $r9 D[$r14 + #proc_qput] - bclr $flags $p1 - cmp b32 $r8 $r9 - bra e #recv_done - // dequeue message - and $r9 $r8 #proc_qmaskp - add b32 $r8 1 - and $r8 #proc_qmaskf - st b32 D[$r14 + #proc_qget] $r8 - ld b32 $r10 D[$r14 + #proc_recv] - - push $r15 - mov $r15 $flags - push $r15 - mov b32 $r15 $r14 - - shl b32 $r9 $r9 #proc_qlen - add b32 $r14 $r9 - add b32 $r14 #proc_queue - ld b32 $r11 D[$r14 + #msg_data1] - ld b32 $r12 D[$r14 + #msg_data0] - ld b32 $r13 D[$r14 + #msg_message] - ld b32 $r14 D[$r14 + #msg_process] - - // process it - call $r10 - pop $r15 - mov $flags $r15 - bset $flags $p1 - pop $r15 - recv_done: - ret - -init: - // setup stack - nv_iord($r1, NV_PPWR_CAPS) - extr $r1 $r1 9:17 - shl b32 $r1 8 - mov $sp $r1 - -#ifdef NVKM_FALCON_MMIO_UAS - // somehow allows the magic "access mmio via D[]" stuff that's - // used by the nv_rd32/nv_wr32 macros to work - mov $r1 0x0010 - sethi $r1 NV_PPWR_UAS_CONFIG_ENABLE - nv_iowrs(NV_PPWR_UAS_CONFIG, $r1) -#endif - - // route all interrupts except user0/1 and pause to fuc - mov $r1 0x00e0 - sethi $r1 0x00000000 - nv_iowr(NV_PPWR_INTR_ROUTE, $r1) - - // enable watchdog and subintr intrs - mov $r1 NV_PPWR_INTR_EN_CLR_MASK - nv_iowr(NV_PPWR_INTR_EN_CLR, $r1) - mov $r1 NV_PPWR_INTR_EN_SET_WATCHDOG - or $r1 NV_PPWR_INTR_EN_SET_SUBINTR - nv_iowr(NV_PPWR_INTR_EN_SET, $r1) - - // enable interrupts globally - mov $r1 #intr - sethi $r1 0x00000000 - mov $iv0 $r1 - bset $flags ie0 - - // enable watchdog timer - mov $r1 1 - nv_iowr(NV_PPWR_WATCHDOG_ENABLE, $r1) - - // bootstrap processes, idle process will be last, and not return - mov $r15 #proc_list_head - init_proc: - ld b32 $r1 D[$r15 + #proc_init] - cmp b32 $r1 0 - bra z #init_proc - call $r1 - add b32 $r15 #proc_size - bra #init_proc -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc deleted file mode 100644 index 2a74ea9..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc +++ /dev/null @@ -1,199 +0,0 @@ -/* - * 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 - */ - -#define GT215 0xa3 -#define GF100 0xc0 -#define GF119 0xd9 -#define GK208 0x108 - -#include "os.h" - -// IO addresses -#define NV_PPWR_INTR_TRIGGER 0x0000 -#define NV_PPWR_INTR_TRIGGER_USER1 0x00000080 -#define NV_PPWR_INTR_TRIGGER_USER0 0x00000040 -#define NV_PPWR_INTR_ACK 0x0004 -#define NV_PPWR_INTR_ACK_SUBINTR 0x00000800 -#define NV_PPWR_INTR_ACK_WATCHDOG 0x00000002 -#define NV_PPWR_INTR 0x0008 -#define NV_PPWR_INTR_SUBINTR 0x00000800 -#define NV_PPWR_INTR_USER1 0x00000080 -#define NV_PPWR_INTR_USER0 0x00000040 -#define NV_PPWR_INTR_PAUSE 0x00000020 -#define NV_PPWR_INTR_WATCHDOG 0x00000002 -#define NV_PPWR_INTR_EN_SET 0x0010 -#define NV_PPWR_INTR_EN_SET_SUBINTR 0x00000800 -#define NV_PPWR_INTR_EN_SET_WATCHDOG 0x00000002 -#define NV_PPWR_INTR_EN_CLR 0x0014 -#define NV_PPWR_INTR_EN_CLR_MASK /* fuck i hate envyas */ -1 -#define NV_PPWR_INTR_ROUTE 0x001c -#define NV_PPWR_TIMER_LOW 0x002c -#define NV_PPWR_WATCHDOG_TIME 0x0034 -#define NV_PPWR_WATCHDOG_ENABLE 0x0038 -#define NV_PPWR_CAPS 0x0108 -#define NV_PPWR_UAS_CONFIG 0x0164 -#define NV_PPWR_UAS_CONFIG_ENABLE 0x00010000 -#if NVKM_PPWR_CHIPSET >= GK208 -#define NV_PPWR_DSCRATCH(i) (4 * (i) + 0x0450) -#endif -#define NV_PPWR_FIFO_PUT(i) (4 * (i) + 0x04a0) -#define NV_PPWR_FIFO_GET(i) (4 * (i) + 0x04b0) -#define NV_PPWR_FIFO_INTR 0x04c0 -#define NV_PPWR_FIFO_INTR_EN 0x04c4 -#define NV_PPWR_RFIFO_PUT 0x04c8 -#define NV_PPWR_RFIFO_GET 0x04cc -#define NV_PPWR_H2D 0x04d0 -#define NV_PPWR_D2H 0x04dc -#if NVKM_PPWR_CHIPSET < GK208 -#define NV_PPWR_DSCRATCH(i) (4 * (i) + 0x05d0) -#endif -#define NV_PPWR_SUBINTR 0x0688 -#define NV_PPWR_SUBINTR_FIFO 0x00000002 -#define NV_PPWR_MMIO_ADDR 0x07a0 -#define NV_PPWR_MMIO_DATA 0x07a4 -#define NV_PPWR_MMIO_CTRL 0x07ac -#define NV_PPWR_MMIO_CTRL_TRIGGER 0x00010000 -#define NV_PPWR_MMIO_CTRL_STATUS 0x00007000 -#define NV_PPWR_MMIO_CTRL_STATUS_IDLE 0x00000000 -#define NV_PPWR_MMIO_CTRL_MASK 0x000000f0 -#define NV_PPWR_MMIO_CTRL_MASK_B32_0 0x000000f0 -#define NV_PPWR_MMIO_CTRL_OP 0x00000003 -#define NV_PPWR_MMIO_CTRL_OP_RD 0x00000001 -#define NV_PPWR_MMIO_CTRL_OP_WR 0x00000002 -#define NV_PPWR_OUTPUT 0x07c0 -#define NV_PPWR_OUTPUT_FB_PAUSE 0x00000004 -#define NV_PPWR_OUTPUT_SET 0x07e0 -#define NV_PPWR_OUTPUT_SET_FB_PAUSE 0x00000004 -#define NV_PPWR_OUTPUT_CLR 0x07e4 -#define NV_PPWR_OUTPUT_CLR_FB_PAUSE 0x00000004 - -// Inter-process message format -.equ #msg_process 0x00 /* send() target, recv() sender */ -.equ #msg_message 0x04 -.equ #msg_data0 0x08 -.equ #msg_data1 0x0c - -// Kernel message IDs -#define KMSG_FIFO 0x00000000 -#define KMSG_ALARM 0x00000001 - -// Process message queue description -.equ #proc_qlen 4 // log2(size of queue entry in bytes) -.equ #proc_qnum 2 // log2(max number of entries in queue) -.equ #proc_qmaskb (1 << #proc_qnum) // max number of entries in queue -.equ #proc_qmaskp (#proc_qmaskb - 1) -.equ #proc_qmaskf ((#proc_qmaskb << 1) - 1) -.equ #proc_qsize (1 << (#proc_qlen + #proc_qnum)) - -// Process table entry -.equ #proc_id 0x00 -.equ #proc_init 0x04 -.equ #proc_recv 0x08 -.equ #proc_time 0x0c -.equ #proc_qput 0x10 -.equ #proc_qget 0x14 -.equ #proc_queue 0x18 -.equ #proc_size (0x18 + #proc_qsize) - -#define process(id,init,recv) /* -*/ .b32 id /* -*/ .b32 init /* -*/ .b32 recv /* -*/ .b32 0 /* -*/ .b32 0 /* -*/ .b32 0 /* -*/ .skip 64 - -#ifndef NVKM_FALCON_UNSHIFTED_IO -#define nv_iord(reg,ior) /* -*/ mov reg ior /* -*/ shl b32 reg 6 /* -*/ iord reg I[reg + 0x000] -#else -#define nv_iord(reg,ior) /* -*/ mov reg ior /* -*/ iord reg I[reg + 0x000] -#endif - -#ifndef NVKM_FALCON_UNSHIFTED_IO -#define nv_iowr(ior,reg) /* -*/ mov $r0 ior /* -*/ shl b32 $r0 6 /* -*/ iowr I[$r0 + 0x000] reg /* -*/ clear b32 $r0 -#else -#define nv_iowr(ior,reg) /* -*/ mov $r0 ior /* -*/ iowr I[$r0 + 0x000] reg /* -*/ clear b32 $r0 -#endif - -#ifndef NVKM_FALCON_UNSHIFTED_IO -#define nv_iowrs(ior,reg) /* -*/ mov $r0 ior /* -*/ shl b32 $r0 6 /* -*/ iowrs I[$r0 + 0x000] reg /* -*/ clear b32 $r0 -#else -#define nv_iowrs(ior,reg) /* -*/ mov $r0 ior /* -*/ iowrs I[$r0 + 0x000] reg /* -*/ clear b32 $r0 -#endif - -#define hash # -#define fn(a) a -#ifndef NVKM_FALCON_PC24 -#define call(a) call fn(hash)a -#else -#define call(a) lcall fn(hash)a -#endif - -#ifndef NVKM_FALCON_MMIO_UAS -#define nv_rd32(reg,addr) /* -*/ mov b32 $r14 addr /* -*/ call(rd32) /* -*/ mov b32 reg $r13 -#else -#define nv_rd32(reg,addr) /* -*/ sethi $r0 0x14000000 /* -*/ or $r0 addr /* -*/ ld b32 reg D[$r0] /* -*/ clear b32 $r0 -#endif - -#if !defined(NVKM_FALCON_MMIO_UAS) || defined(NVKM_FALCON_MMIO_TRAP) -#define nv_wr32(addr,reg) /* -*/ push addr /* -*/ push reg /* -*/ pop $r13 /* -*/ pop $r14 /* -*/ call(wr32) /* -#else -#define nv_wr32(addr,reg) /* -*/ sethi $r0 0x14000000 /* -*/ or $r0 addr /* -*/ st b32 D[$r0] reg /* -*/ clear b32 $r0 -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc deleted file mode 100644 index d43741e..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc +++ /dev/null @@ -1,219 +0,0 @@ -/* - * 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 - */ - -#ifdef INCLUDE_PROC -process(PROC_MEMX, #memx_init, #memx_recv) -#endif - -/****************************************************************************** - * MEMX data segment - *****************************************************************************/ -#ifdef INCLUDE_DATA -.equ #memx_opcode 0 -.equ #memx_header 2 -.equ #memx_length 4 -.equ #memx_func 8 - -#define handler(cmd,hdr,len,func) /* -*/ .b16 MEMX_##cmd /* -*/ .b16 hdr /* -*/ .b16 len /* -*/ .b16 0 /* -*/ .b32 func - -memx_func_head: -handler(ENTER , 0x0001, 0x0000, #memx_func_enter) -memx_func_next: -handler(LEAVE , 0x0000, 0x0000, #memx_func_leave) -handler(WR32 , 0x0000, 0x0002, #memx_func_wr32) -handler(WAIT , 0x0004, 0x0000, #memx_func_wait) -handler(DELAY , 0x0001, 0x0000, #memx_func_delay) -memx_func_tail: - -.equ #memx_func_size #memx_func_next - #memx_func_head -.equ #memx_func_num (#memx_func_tail - #memx_func_head) / #memx_func_size - -memx_data_head: -.skip 0x0800 -memx_data_tail: -#endif - -/****************************************************************************** - * MEMX code segment - *****************************************************************************/ -#ifdef INCLUDE_CODE -// description -// -// $r15 - current (memx) -// $r4 - packet length -// +00: bitmask of heads to wait for vblank on -// $r3 - opcode desciption -// $r0 - zero -memx_func_enter: - mov $r6 NV_PPWR_OUTPUT_SET_FB_PAUSE - nv_iowr(NV_PPWR_OUTPUT_SET, $r6) - memx_func_enter_wait: - nv_iord($r6, NV_PPWR_OUTPUT) - and $r6 NV_PPWR_OUTPUT_FB_PAUSE - bra z #memx_func_enter_wait - //XXX: TODO - ld b32 $r6 D[$r1 + 0x00] - add b32 $r1 0x04 - ret - -// description -// -// $r15 - current (memx) -// $r4 - packet length -// $r3 - opcode desciption -// $r0 - zero -memx_func_leave: - mov $r6 NV_PPWR_OUTPUT_CLR_FB_PAUSE - nv_iowr(NV_PPWR_OUTPUT_CLR, $r6) - memx_func_leave_wait: - nv_iord($r6, NV_PPWR_OUTPUT) - and $r6 NV_PPWR_OUTPUT_FB_PAUSE - bra nz #memx_func_leave_wait - ret - -// description -// -// $r15 - current (memx) -// $r4 - packet length -// +00*n: addr -// +04*n: data -// $r3 - opcode desciption -// $r0 - zero -memx_func_wr32: - ld b32 $r6 D[$r1 + 0x00] - ld b32 $r5 D[$r1 + 0x04] - add b32 $r1 0x08 - nv_wr32($r6, $r5) - sub b32 $r4 0x02 - bra nz #memx_func_wr32 - ret - -// description -// -// $r15 - current (memx) -// $r4 - packet length -// +00: addr -// +04: mask -// +08: data -// +0c: timeout (ns) -// $r3 - opcode desciption -// $r0 - zero -memx_func_wait: - nv_iord($r8, NV_PPWR_TIMER_LOW) - ld b32 $r14 D[$r1 + 0x00] - ld b32 $r13 D[$r1 + 0x04] - ld b32 $r12 D[$r1 + 0x08] - ld b32 $r11 D[$r1 + 0x0c] - add b32 $r1 0x10 - call(wait) - ret - -// description -// -// $r15 - current (memx) -// $r4 - packet length -// +00: time (ns) -// $r3 - opcode desciption -// $r0 - zero -memx_func_delay: - ld b32 $r14 D[$r1 + 0x00] - add b32 $r1 0x04 - call(nsec) - ret - -// description -// -// $r15 - current (memx) -// $r14 - sender process name -// $r13 - message (exec) -// $r12 - head of script -// $r11 - tail of script -// $r0 - zero -memx_exec: - push $r14 - push $r13 - mov b32 $r1 $r12 - mov b32 $r2 $r11 - memx_exec_next: - // fetch the packet header, and locate opcode info - ld b32 $r3 D[$r1] - add b32 $r1 4 - shr b32 $r4 $r3 16 - mulu $r3 #memx_func_size - - // execute the opcode handler - ld b32 $r5 D[$r3 + #memx_func_head + #memx_func] - call $r5 - - // keep going, if we haven't reached the end - cmp b32 $r1 $r2 - bra l #memx_exec_next - - // send completion reply - pop $r13 - pop $r14 - call(send) - ret - -// description -// -// $r15 - current (memx) -// $r14 - sender process name -// $r13 - message -// $r12 - data0 -// $r11 - data1 -// $r0 - zero -memx_info: - mov $r12 #memx_data_head - mov $r11 #memx_data_tail - #memx_data_head - call(send) - ret - -// description -// -// $r15 - current (memx) -// $r14 - sender process name -// $r13 - message -// $r12 - data0 -// $r11 - data1 -// $r0 - zero -memx_recv: - cmp b32 $r13 MEMX_MSG_EXEC - bra e #memx_exec - cmp b32 $r13 MEMX_MSG_INFO - bra e #memx_info - ret - -// description -// -// $r15 - current (memx) -// $r0 - zero -memx_init: - ret -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc deleted file mode 100644 index 947be53..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 - */ - -#define NVKM_PPWR_CHIPSET GK208 - -#define NVKM_FALCON_PC24 -#define NVKM_FALCON_UNSHIFTED_IO -//#define NVKM_FALCON_MMIO_UAS -//#define NVKM_FALCON_MMIO_TRAP - -#include "macros.fuc" - -.section #nv108_pwr_data -#define INCLUDE_PROC -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_PROC - -#define INCLUDE_DATA -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_DATA -.align 256 - -.section #nv108_pwr_code -#define INCLUDE_CODE -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_CODE -.align 256 diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h deleted file mode 100644 index 9342e2d..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h +++ /dev/null @@ -1,1165 +0,0 @@ -uint32_t nv108_pwr_data[] = { -/* 0x0000: proc_kern */ - 0x52544e49, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0058: proc_list_head */ - 0x54534f48, - 0x00000379, - 0x0000032a, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x584d454d, - 0x0000046f, - 0x00000461, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x46524550, - 0x00000473, - 0x00000471, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x54534554, - 0x00000494, - 0x00000475, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x454c4449, - 0x0000049f, - 0x0000049d, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0210: proc_list_tail */ -/* 0x0210: time_prev */ - 0x00000000, -/* 0x0214: time_next */ - 0x00000000, -/* 0x0218: fifo_queue */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0298: rfifo_queue */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0318: memx_func_head */ - 0x00010000, - 0x00000000, - 0x000003a9, -/* 0x0324: memx_func_next */ - 0x00000001, - 0x00000000, - 0x000003c7, - 0x00000002, - 0x00000002, - 0x000003df, - 0x00040003, - 0x00000000, - 0x00000407, - 0x00010004, - 0x00000000, - 0x00000421, -/* 0x0354: memx_func_tail */ -/* 0x0354: memx_data_head */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0b54: memx_data_tail */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -uint32_t nv108_pwr_code[] = { - 0x02910ef5, -/* 0x0004: rd32 */ - 0xf607a040, - 0x04bd000e, - 0xe3f0010e, - 0x07ac4001, - 0xbd000ef6, -/* 0x0019: rd32_wait */ - 0x07ac4e04, - 0xf100eecf, - 0xf47000e4, - 0xa44df61b, - 0x00ddcf07, -/* 0x002e: wr32 */ - 0xa04000f8, - 0x000ef607, - 0xa44004bd, - 0x000df607, - 0x020e04bd, - 0xf0f0e5f0, - 0xac4001e3, - 0x000ef607, -/* 0x004e: wr32_wait */ - 0xac4e04bd, - 0x00eecf07, - 0x7000e4f1, - 0xf8f61bf4, -/* 0x005d: nsec */ - 0xcf2c0800, -/* 0x0062: nsec_loop */ - 0x2c090088, - 0xbb0099cf, - 0x9ea60298, - 0xf8f61ef4, -/* 0x0071: wait */ - 0xcf2c0800, -/* 0x0076: wait_loop */ - 0xeeb20088, - 0x0000047e, - 0xadfddab2, - 0xf4aca604, - 0x2c09100b, - 0xbb0099cf, - 0x9ba60298, -/* 0x0093: wait_done */ - 0xf8e61ef4, -/* 0x0095: intr_watchdog */ - 0x03e99800, - 0xf40096b0, - 0x0a98280b, - 0x029abb84, - 0x0d0e1cf4, - 0x01de7e01, - 0xf494bd00, -/* 0x00b2: intr_watchdog_next_time */ - 0x0a98140e, - 0x00a6b085, - 0xa6080bf4, - 0x061cf49a, -/* 0x00c0: intr_watchdog_next_time_set */ -/* 0x00c3: intr_watchdog_next_proc */ - 0xb58509b5, - 0xe0b603e9, - 0x10e6b158, - 0xc81bf402, -/* 0x00d2: intr */ - 0x00f900f8, - 0x80f904bd, - 0xa0f990f9, - 0xc0f9b0f9, - 0xe0f9d0f9, - 0x000ff0f9, - 0xf90188fe, - 0x04504880, - 0xb60088cf, - 0x50400180, - 0x0008f604, - 0x080804bd, - 0xc40088cf, - 0x0bf40289, - 0x8500b51f, - 0x957e580e, - 0x09980000, - 0x0096b085, - 0x000d0bf4, - 0x0009f634, - 0x09b504bd, -/* 0x0125: intr_skip_watchdog */ - 0x0089e484, - 0x360bf408, - 0xcf068849, - 0x9ac40099, - 0x220bf402, - 0xcf04c04c, - 0xc0f900cc, - 0xf14f484e, - 0x0d5453e3, - 0x023f7e00, - 0x40c0fc00, - 0x0cf604c0, -/* 0x0157: intr_subintr_skip_fifo */ - 0x4004bd00, - 0x09f60688, -/* 0x015f: intr_skip_subintr */ - 0xc404bd00, - 0x0bf42089, - 0xbfa4f107, -/* 0x0169: intr_skip_pause */ - 0x4089c4ff, - 0xf1070bf4, -/* 0x0173: intr_skip_user0 */ - 0x00ffbfa4, - 0x0008f604, - 0x80fc04bd, - 0xfc0088fe, - 0xfce0fcf0, - 0xfcc0fcd0, - 0xfca0fcb0, - 0xfc80fc90, - 0x0032f400, -/* 0x0196: timer */ - 0x32f401f8, - 0x03f89810, - 0xf40086b0, - 0xfeb53a1c, - 0xf6380003, - 0x04bd0008, - 0x88cf0808, - 0x0284f000, - 0x081c1bf4, - 0x0088cf34, - 0x0bf4e0a6, - 0xf4e8a608, -/* 0x01c6: timer_reset */ - 0x3400161e, - 0xbd000ef6, - 0x840eb504, -/* 0x01d0: timer_enable */ - 0x38000108, - 0xbd0008f6, -/* 0x01d9: timer_done */ - 0x1031f404, -/* 0x01de: send_proc */ - 0x80f900f8, - 0xe89890f9, - 0x04e99805, - 0xa60486f0, - 0x2a0bf489, - 0x940398c4, - 0x80b60488, - 0x008ebb18, - 0xb500fa98, - 0x8db5008a, - 0x028cb501, - 0xb6038bb5, - 0x94f00190, - 0x04e9b507, -/* 0x0217: send_done */ - 0xfc0231f4, - 0xf880fc90, -/* 0x021d: find */ - 0x0880f900, - 0x0131f458, -/* 0x0224: find_loop */ - 0xa6008a98, - 0x100bf4ae, - 0xb15880b6, - 0xf4021086, - 0x32f4f11b, -/* 0x0239: find_done */ - 0xfc8eb201, -/* 0x023f: send */ - 0x7e00f880, - 0xf400021d, - 0x00f89b01, -/* 0x0248: recv */ - 0x9805e898, - 0x32f404e9, - 0xf489a601, - 0x89c43c0b, - 0x0180b603, - 0xb50784f0, - 0xea9805e8, - 0xfef0f902, - 0xf0f9018f, - 0x9994efb2, - 0x00e9bb04, - 0x9818e0b6, - 0xec9803eb, - 0x01ed9802, - 0xf900ee98, - 0xfef0fca5, - 0x31f400f8, -/* 0x028f: recv_done */ - 0xf8f0fc01, -/* 0x0291: init */ - 0x01084100, - 0xe70011cf, - 0xb6010911, - 0x14fe0814, - 0x00e04100, - 0x000013f0, - 0x0001f61c, - 0xff0104bd, - 0x01f61400, - 0x0104bd00, - 0x0015f102, - 0xf6100008, - 0x04bd0001, - 0xf000d241, - 0x10fe0013, - 0x1031f400, - 0x38000101, - 0xbd0001f6, -/* 0x02db: init_proc */ - 0x98580f04, - 0x16b001f1, - 0xfa0bf400, - 0xf0b615f9, - 0xf20ef458, -/* 0x02ec: host_send */ - 0xcf04b041, - 0xa0420011, - 0x0022cf04, - 0x0bf412a6, - 0x071ec42e, - 0xb704ee94, - 0x980218e0, - 0xec9803eb, - 0x01ed9802, - 0x7e00ee98, - 0xb600023f, - 0x1ec40110, - 0x04b0400f, - 0xbd0001f6, - 0xc70ef404, -/* 0x0328: host_send_done */ -/* 0x032a: host_recv */ - 0x494100f8, - 0x5413f14e, - 0xf4e1a652, -/* 0x0336: host_recv_wait */ - 0xcc41b90b, - 0x0011cf04, - 0xcf04c842, - 0x16f00022, - 0xf412a608, - 0x23c4ef0b, - 0x0434b607, - 0x029830b7, - 0xb5033bb5, - 0x3db5023c, - 0x003eb501, - 0xf00120b6, - 0xc8400f24, - 0x0002f604, - 0x400204bd, - 0x02f60000, - 0xf804bd00, -/* 0x0379: host_init */ - 0x00804100, - 0xf11014b6, - 0x40021815, - 0x01f604d0, - 0x4104bd00, - 0x14b60080, - 0x9815f110, - 0x04dc4002, - 0xbd0001f6, - 0x40010104, - 0x01f604c4, - 0xf804bd00, -/* 0x03a9: memx_func_enter */ - 0x40040600, - 0x06f607e0, -/* 0x03b3: memx_func_enter_wait */ - 0x4604bd00, - 0x66cf07c0, - 0x0464f000, - 0x98f70bf4, - 0x10b60016, -/* 0x03c7: memx_func_leave */ - 0x0600f804, - 0x07e44004, - 0xbd0006f6, -/* 0x03d1: memx_func_leave_wait */ - 0x07c04604, - 0xf00066cf, - 0x1bf40464, -/* 0x03df: memx_func_wr32 */ - 0x9800f8f7, - 0x15980016, - 0x0810b601, - 0x50f960f9, - 0xe0fcd0fc, - 0x00002e7e, - 0x140003f1, - 0xa00506fd, - 0xb604bd05, - 0x1bf40242, -/* 0x0407: memx_func_wait */ - 0x0800f8dd, - 0x0088cf2c, - 0x98001e98, - 0x1c98011d, - 0x031b9802, - 0x7e1010b6, - 0xf8000071, -/* 0x0421: memx_func_delay */ - 0x001e9800, - 0x7e0410b6, - 0xf800005d, -/* 0x042d: memx_exec */ - 0xf9e0f900, - 0xb2c1b2d0, -/* 0x0435: memx_exec_next */ - 0x001398b2, - 0x950410b6, - 0x30f01034, - 0xc835980c, - 0x12a655f9, - 0xfced1ef4, - 0x7ee0fcd0, - 0xf800023f, -/* 0x0455: memx_info */ - 0x03544c00, - 0x7e08004b, - 0xf800023f, -/* 0x0461: memx_recv */ - 0x01d6b000, - 0xb0c90bf4, - 0x0bf400d6, -/* 0x046f: memx_init */ - 0xf800f8eb, -/* 0x0471: perf_recv */ -/* 0x0473: perf_init */ - 0xf800f800, -/* 0x0475: test_recv */ - 0x04584100, - 0xb60011cf, - 0x58400110, - 0x0001f604, - 0xe7f104bd, - 0xe3f1d900, - 0x967e134f, - 0x00f80001, -/* 0x0494: test_init */ - 0x7e08004e, - 0xf8000196, -/* 0x049d: idle_recv */ -/* 0x049f: idle */ - 0xf400f800, - 0x54410031, - 0x0011cf04, - 0x400110b6, - 0x01f60454, -/* 0x04b3: idle_loop */ - 0x0104bd00, - 0x0232f458, -/* 0x04b8: idle_proc */ -/* 0x04b8: idle_proc_exec */ - 0x1eb210f9, - 0x0002487e, - 0x11f410fc, - 0x0231f409, -/* 0x04cb: idle_proc_next */ - 0xb6f00ef4, - 0x1fa65810, - 0xf4e81bf4, - 0x28f4e002, - 0xc60ef400, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc deleted file mode 100644 index 6fde0b8..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 - */ - -#define NVKM_PPWR_CHIPSET GT215 - -//#define NVKM_FALCON_PC24 -//#define NVKM_FALCON_UNSHIFTED_IO -//#define NVKM_FALCON_MMIO_UAS -//#define NVKM_FALCON_MMIO_TRAP - -#include "macros.fuc" - -.section #nva3_pwr_data -#define INCLUDE_PROC -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_PROC - -#define INCLUDE_DATA -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_DATA -.align 256 - -.section #nva3_pwr_code -#define INCLUDE_CODE -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_CODE -.align 256 diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h deleted file mode 100644 index 0fa4d7d..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h +++ /dev/null @@ -1,1229 +0,0 @@ -uint32_t nva3_pwr_data[] = { -/* 0x0000: proc_kern */ - 0x52544e49, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0058: proc_list_head */ - 0x54534f48, - 0x00000430, - 0x000003cd, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x584d454d, - 0x0000054e, - 0x00000540, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x46524550, - 0x00000552, - 0x00000550, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x54534554, - 0x0000057b, - 0x00000554, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x454c4449, - 0x00000587, - 0x00000585, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0210: proc_list_tail */ -/* 0x0210: time_prev */ - 0x00000000, -/* 0x0214: time_next */ - 0x00000000, -/* 0x0218: fifo_queue */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0298: rfifo_queue */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0318: memx_func_head */ - 0x00010000, - 0x00000000, - 0x0000046f, -/* 0x0324: memx_func_next */ - 0x00000001, - 0x00000000, - 0x00000496, - 0x00000002, - 0x00000002, - 0x000004b7, - 0x00040003, - 0x00000000, - 0x000004df, - 0x00010004, - 0x00000000, - 0x000004fc, -/* 0x0354: memx_func_tail */ -/* 0x0354: memx_data_head */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0b54: memx_data_tail */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -uint32_t nva3_pwr_code[] = { - 0x030d0ef5, -/* 0x0004: rd32 */ - 0x07a007f1, - 0xd00604b6, - 0x04bd000e, - 0xf001e7f0, - 0x07f101e3, - 0x04b607ac, - 0x000ed006, -/* 0x0022: rd32_wait */ - 0xe7f104bd, - 0xe4b607ac, - 0x00eecf06, - 0x7000e4f1, - 0xf1f21bf4, - 0xb607a4d7, - 0xddcf06d4, -/* 0x003f: wr32 */ - 0xf100f800, - 0xb607a007, - 0x0ed00604, - 0xf104bd00, - 0xb607a407, - 0x0dd00604, - 0xf004bd00, - 0xe5f002e7, - 0x01e3f0f0, - 0x07ac07f1, - 0xd00604b6, - 0x04bd000e, -/* 0x006c: wr32_wait */ - 0x07ace7f1, - 0xcf06e4b6, - 0xe4f100ee, - 0x1bf47000, -/* 0x007f: nsec */ - 0xf000f8f2, - 0x84b62c87, - 0x0088cf06, -/* 0x0088: nsec_loop */ - 0xb62c97f0, - 0x99cf0694, - 0x0298bb00, - 0xf4069eb8, - 0x00f8f11e, -/* 0x009c: wait */ - 0xb62c87f0, - 0x88cf0684, -/* 0x00a5: wait_loop */ - 0x02eeb900, - 0xb90421f4, - 0xadfd02da, - 0x06acb804, - 0xf0150bf4, - 0x94b62c97, - 0x0099cf06, - 0xb80298bb, - 0x1ef4069b, -/* 0x00c9: wait_done */ -/* 0x00cb: intr_watchdog */ - 0x9800f8df, - 0x96b003e9, - 0x2a0bf400, - 0xbb840a98, - 0x1cf4029a, - 0x01d7f00f, - 0x025421f5, - 0x0ef494bd, -/* 0x00e9: intr_watchdog_next_time */ - 0x850a9815, - 0xf400a6b0, - 0x9ab8090b, - 0x061cf406, -/* 0x00f8: intr_watchdog_next_time_set */ -/* 0x00fb: intr_watchdog_next_proc */ - 0x80850980, - 0xe0b603e9, - 0x10e6b158, - 0xc61bf402, -/* 0x010a: intr */ - 0x00f900f8, - 0x80f904bd, - 0xa0f990f9, - 0xc0f9b0f9, - 0xe0f9d0f9, - 0xf7f0f0f9, - 0x0188fe00, - 0x87f180f9, - 0x84b605d0, - 0x0088cf06, - 0xf10180b6, - 0xb605d007, - 0x08d00604, - 0xf004bd00, - 0x84b60887, - 0x0088cf06, - 0xf40289c4, - 0x0080230b, - 0x58e7f085, - 0x98cb21f4, - 0x96b08509, - 0x110bf400, - 0xb63407f0, - 0x09d00604, - 0x8004bd00, -/* 0x016e: intr_skip_watchdog */ - 0x89e48409, - 0x0bf40800, - 0x8897f148, - 0x0694b606, - 0xc40099cf, - 0x0bf4029a, - 0xc0c7f12c, - 0x06c4b604, - 0xf900cccf, - 0x48e7f1c0, - 0x53e3f14f, - 0x00d7f054, - 0x02b921f5, - 0x07f1c0fc, - 0x04b604c0, - 0x000cd006, -/* 0x01ae: intr_subintr_skip_fifo */ - 0x07f104bd, - 0x04b60688, - 0x0009d006, -/* 0x01ba: intr_skip_subintr */ - 0x89c404bd, - 0x070bf420, - 0xffbfa4f1, -/* 0x01c4: intr_skip_pause */ - 0xf44089c4, - 0xa4f1070b, -/* 0x01ce: intr_skip_user0 */ - 0x07f0ffbf, - 0x0604b604, - 0xbd0008d0, - 0xfe80fc04, - 0xf0fc0088, - 0xd0fce0fc, - 0xb0fcc0fc, - 0x90fca0fc, - 0x00fc80fc, - 0xf80032f4, -/* 0x01f5: timer */ - 0x1032f401, - 0xb003f898, - 0x1cf40086, - 0x03fe8051, - 0xb63807f0, - 0x08d00604, - 0xf004bd00, - 0x84b60887, - 0x0088cf06, - 0xf40284f0, - 0x87f0261b, - 0x0684b634, - 0xb80088cf, - 0x0bf406e0, - 0x06e8b809, -/* 0x0233: timer_reset */ - 0xf01f1ef4, - 0x04b63407, - 0x000ed006, - 0x0e8004bd, -/* 0x0241: timer_enable */ - 0x0187f084, - 0xb63807f0, - 0x08d00604, -/* 0x024f: timer_done */ - 0xf404bd00, - 0x00f81031, -/* 0x0254: send_proc */ - 0x90f980f9, - 0x9805e898, - 0x86f004e9, - 0x0689b804, - 0xc42a0bf4, - 0x88940398, - 0x1880b604, - 0x98008ebb, - 0x8a8000fa, - 0x018d8000, - 0x80028c80, - 0x90b6038b, - 0x0794f001, - 0xf404e980, -/* 0x028e: send_done */ - 0x90fc0231, - 0x00f880fc, -/* 0x0294: find */ - 0x87f080f9, - 0x0131f458, -/* 0x029c: find_loop */ - 0xb8008a98, - 0x0bf406ae, - 0x5880b610, - 0x021086b1, - 0xf4f01bf4, -/* 0x02b2: find_done */ - 0x8eb90132, - 0xf880fc02, -/* 0x02b9: send */ - 0x9421f500, - 0x9701f402, -/* 0x02c2: recv */ - 0xe89800f8, - 0x04e99805, - 0xb80132f4, - 0x0bf40689, - 0x0389c43d, - 0xf00180b6, - 0xe8800784, - 0x02ea9805, - 0x8ffef0f9, - 0xb9f0f901, - 0x999402ef, - 0x00e9bb04, - 0x9818e0b6, - 0xec9803eb, - 0x01ed9802, - 0xf900ee98, - 0xfef0fca5, - 0x31f400f8, -/* 0x030b: recv_done */ - 0xf8f0fc01, -/* 0x030d: init */ - 0x0817f100, - 0x0614b601, - 0xe70011cf, - 0xb6010911, - 0x14fe0814, - 0xe017f100, - 0x0013f000, - 0xb61c07f0, - 0x01d00604, - 0xf004bd00, - 0x07f0ff17, - 0x0604b614, - 0xbd0001d0, - 0x0217f004, - 0x080015f1, - 0xb61007f0, - 0x01d00604, - 0xf104bd00, - 0xf0010a17, - 0x10fe0013, - 0x1031f400, - 0xf00117f0, - 0x04b63807, - 0x0001d006, - 0xf7f004bd, -/* 0x0371: init_proc */ - 0x01f19858, - 0xf40016b0, - 0x15f9fa0b, - 0xf458f0b6, -/* 0x0382: host_send */ - 0x17f1f20e, - 0x14b604b0, - 0x0011cf06, - 0x04a027f1, - 0xcf0624b6, - 0x12b80022, - 0x320bf406, - 0x94071ec4, - 0xe0b704ee, - 0xeb980218, - 0x02ec9803, - 0x9801ed98, - 0x21f500ee, - 0x10b602b9, - 0x0f1ec401, - 0x04b007f1, - 0xd00604b6, - 0x04bd0001, -/* 0x03cb: host_send_done */ - 0xf8ba0ef4, -/* 0x03cd: host_recv */ - 0x4917f100, - 0x5413f14e, - 0x06e1b852, -/* 0x03db: host_recv_wait */ - 0xf1aa0bf4, - 0xb604cc17, - 0x11cf0614, - 0xc827f100, - 0x0624b604, - 0xf00022cf, - 0x12b80816, - 0xe60bf406, - 0xb60723c4, - 0x30b70434, - 0x3b800298, - 0x023c8003, - 0x80013d80, - 0x20b6003e, - 0x0f24f001, - 0x04c807f1, - 0xd00604b6, - 0x04bd0002, - 0xf04027f0, - 0x04b60007, - 0x0002d006, - 0x00f804bd, -/* 0x0430: host_init */ - 0x008017f1, - 0xf11014b6, - 0xf1021815, - 0xb604d007, - 0x01d00604, - 0xf104bd00, - 0xb6008017, - 0x15f11014, - 0x07f10298, - 0x04b604dc, - 0x0001d006, - 0x17f004bd, - 0xc407f101, - 0x0604b604, - 0xbd0001d0, -/* 0x046f: memx_func_enter */ - 0xf000f804, - 0x07f10467, - 0x04b607e0, - 0x0006d006, -/* 0x047e: memx_func_enter_wait */ - 0x67f104bd, - 0x64b607c0, - 0x0066cf06, - 0xf40464f0, - 0x1698f30b, - 0x0410b600, -/* 0x0496: memx_func_leave */ - 0x67f000f8, - 0xe407f104, - 0x0604b607, - 0xbd0006d0, -/* 0x04a5: memx_func_leave_wait */ - 0xc067f104, - 0x0664b607, - 0xf00066cf, - 0x1bf40464, -/* 0x04b7: memx_func_wr32 */ - 0x9800f8f3, - 0x15980016, - 0x0810b601, - 0x50f960f9, - 0xe0fcd0fc, - 0xf13f21f4, - 0xfd140003, - 0x05800506, - 0xb604bd00, - 0x1bf40242, -/* 0x04df: memx_func_wait */ - 0xf000f8dd, - 0x84b62c87, - 0x0088cf06, - 0x98001e98, - 0x1c98011d, - 0x031b9802, - 0xf41010b6, - 0x00f89c21, -/* 0x04fc: memx_func_delay */ - 0xb6001e98, - 0x21f40410, -/* 0x0507: memx_exec */ - 0xf900f87f, - 0xb9d0f9e0, - 0xb2b902c1, -/* 0x0511: memx_exec_next */ - 0x00139802, - 0x950410b6, - 0x30f01034, - 0xc835980c, - 0x12b855f9, - 0xec1ef406, - 0xe0fcd0fc, - 0x02b921f5, -/* 0x0532: memx_info */ - 0xc7f100f8, - 0xb7f10354, - 0x21f50800, - 0x00f802b9, -/* 0x0540: memx_recv */ - 0xf401d6b0, - 0xd6b0c40b, - 0xe90bf400, -/* 0x054e: memx_init */ - 0x00f800f8, -/* 0x0550: perf_recv */ -/* 0x0552: perf_init */ - 0x00f800f8, -/* 0x0554: test_recv */ - 0x05d817f1, - 0xcf0614b6, - 0x10b60011, - 0xd807f101, - 0x0604b605, - 0xbd0001d0, - 0x00e7f104, - 0x4fe3f1d9, - 0xf521f513, -/* 0x057b: test_init */ - 0xf100f801, - 0xf50800e7, - 0xf801f521, -/* 0x0585: idle_recv */ -/* 0x0587: idle */ - 0xf400f800, - 0x17f10031, - 0x14b605d4, - 0x0011cf06, - 0xf10110b6, - 0xb605d407, - 0x01d00604, -/* 0x05a3: idle_loop */ - 0xf004bd00, - 0x32f45817, -/* 0x05a9: idle_proc */ -/* 0x05a9: idle_proc_exec */ - 0xb910f902, - 0x21f5021e, - 0x10fc02c2, - 0xf40911f4, - 0x0ef40231, -/* 0x05bd: idle_proc_next */ - 0x5810b6ef, - 0xf4061fb8, - 0x02f4e61b, - 0x0028f4dd, - 0x00bb0ef4, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc deleted file mode 100644 index eaa64da..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 - */ - -#define NVKM_PPWR_CHIPSET GF100 - -//#define NVKM_FALCON_PC24 -//#define NVKM_FALCON_UNSHIFTED_IO -//#define NVKM_FALCON_MMIO_UAS -//#define NVKM_FALCON_MMIO_TRAP - -#include "macros.fuc" - -.section #nvc0_pwr_data -#define INCLUDE_PROC -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_PROC - -#define INCLUDE_DATA -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_DATA -.align 256 - -.section #nvc0_pwr_code -#define INCLUDE_CODE -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_CODE -.align 256 diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h deleted file mode 100644 index 82c8e8b..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h +++ /dev/null @@ -1,1229 +0,0 @@ -uint32_t nvc0_pwr_data[] = { -/* 0x0000: proc_kern */ - 0x52544e49, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0058: proc_list_head */ - 0x54534f48, - 0x00000430, - 0x000003cd, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x584d454d, - 0x0000054e, - 0x00000540, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x46524550, - 0x00000552, - 0x00000550, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x54534554, - 0x0000057b, - 0x00000554, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x454c4449, - 0x00000587, - 0x00000585, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0210: proc_list_tail */ -/* 0x0210: time_prev */ - 0x00000000, -/* 0x0214: time_next */ - 0x00000000, -/* 0x0218: fifo_queue */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0298: rfifo_queue */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0318: memx_func_head */ - 0x00010000, - 0x00000000, - 0x0000046f, -/* 0x0324: memx_func_next */ - 0x00000001, - 0x00000000, - 0x00000496, - 0x00000002, - 0x00000002, - 0x000004b7, - 0x00040003, - 0x00000000, - 0x000004df, - 0x00010004, - 0x00000000, - 0x000004fc, -/* 0x0354: memx_func_tail */ -/* 0x0354: memx_data_head */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0b54: memx_data_tail */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -uint32_t nvc0_pwr_code[] = { - 0x030d0ef5, -/* 0x0004: rd32 */ - 0x07a007f1, - 0xd00604b6, - 0x04bd000e, - 0xf001e7f0, - 0x07f101e3, - 0x04b607ac, - 0x000ed006, -/* 0x0022: rd32_wait */ - 0xe7f104bd, - 0xe4b607ac, - 0x00eecf06, - 0x7000e4f1, - 0xf1f21bf4, - 0xb607a4d7, - 0xddcf06d4, -/* 0x003f: wr32 */ - 0xf100f800, - 0xb607a007, - 0x0ed00604, - 0xf104bd00, - 0xb607a407, - 0x0dd00604, - 0xf004bd00, - 0xe5f002e7, - 0x01e3f0f0, - 0x07ac07f1, - 0xd00604b6, - 0x04bd000e, -/* 0x006c: wr32_wait */ - 0x07ace7f1, - 0xcf06e4b6, - 0xe4f100ee, - 0x1bf47000, -/* 0x007f: nsec */ - 0xf000f8f2, - 0x84b62c87, - 0x0088cf06, -/* 0x0088: nsec_loop */ - 0xb62c97f0, - 0x99cf0694, - 0x0298bb00, - 0xf4069eb8, - 0x00f8f11e, -/* 0x009c: wait */ - 0xb62c87f0, - 0x88cf0684, -/* 0x00a5: wait_loop */ - 0x02eeb900, - 0xb90421f4, - 0xadfd02da, - 0x06acb804, - 0xf0150bf4, - 0x94b62c97, - 0x0099cf06, - 0xb80298bb, - 0x1ef4069b, -/* 0x00c9: wait_done */ -/* 0x00cb: intr_watchdog */ - 0x9800f8df, - 0x96b003e9, - 0x2a0bf400, - 0xbb840a98, - 0x1cf4029a, - 0x01d7f00f, - 0x025421f5, - 0x0ef494bd, -/* 0x00e9: intr_watchdog_next_time */ - 0x850a9815, - 0xf400a6b0, - 0x9ab8090b, - 0x061cf406, -/* 0x00f8: intr_watchdog_next_time_set */ -/* 0x00fb: intr_watchdog_next_proc */ - 0x80850980, - 0xe0b603e9, - 0x10e6b158, - 0xc61bf402, -/* 0x010a: intr */ - 0x00f900f8, - 0x80f904bd, - 0xa0f990f9, - 0xc0f9b0f9, - 0xe0f9d0f9, - 0xf7f0f0f9, - 0x0188fe00, - 0x87f180f9, - 0x84b605d0, - 0x0088cf06, - 0xf10180b6, - 0xb605d007, - 0x08d00604, - 0xf004bd00, - 0x84b60887, - 0x0088cf06, - 0xf40289c4, - 0x0080230b, - 0x58e7f085, - 0x98cb21f4, - 0x96b08509, - 0x110bf400, - 0xb63407f0, - 0x09d00604, - 0x8004bd00, -/* 0x016e: intr_skip_watchdog */ - 0x89e48409, - 0x0bf40800, - 0x8897f148, - 0x0694b606, - 0xc40099cf, - 0x0bf4029a, - 0xc0c7f12c, - 0x06c4b604, - 0xf900cccf, - 0x48e7f1c0, - 0x53e3f14f, - 0x00d7f054, - 0x02b921f5, - 0x07f1c0fc, - 0x04b604c0, - 0x000cd006, -/* 0x01ae: intr_subintr_skip_fifo */ - 0x07f104bd, - 0x04b60688, - 0x0009d006, -/* 0x01ba: intr_skip_subintr */ - 0x89c404bd, - 0x070bf420, - 0xffbfa4f1, -/* 0x01c4: intr_skip_pause */ - 0xf44089c4, - 0xa4f1070b, -/* 0x01ce: intr_skip_user0 */ - 0x07f0ffbf, - 0x0604b604, - 0xbd0008d0, - 0xfe80fc04, - 0xf0fc0088, - 0xd0fce0fc, - 0xb0fcc0fc, - 0x90fca0fc, - 0x00fc80fc, - 0xf80032f4, -/* 0x01f5: timer */ - 0x1032f401, - 0xb003f898, - 0x1cf40086, - 0x03fe8051, - 0xb63807f0, - 0x08d00604, - 0xf004bd00, - 0x84b60887, - 0x0088cf06, - 0xf40284f0, - 0x87f0261b, - 0x0684b634, - 0xb80088cf, - 0x0bf406e0, - 0x06e8b809, -/* 0x0233: timer_reset */ - 0xf01f1ef4, - 0x04b63407, - 0x000ed006, - 0x0e8004bd, -/* 0x0241: timer_enable */ - 0x0187f084, - 0xb63807f0, - 0x08d00604, -/* 0x024f: timer_done */ - 0xf404bd00, - 0x00f81031, -/* 0x0254: send_proc */ - 0x90f980f9, - 0x9805e898, - 0x86f004e9, - 0x0689b804, - 0xc42a0bf4, - 0x88940398, - 0x1880b604, - 0x98008ebb, - 0x8a8000fa, - 0x018d8000, - 0x80028c80, - 0x90b6038b, - 0x0794f001, - 0xf404e980, -/* 0x028e: send_done */ - 0x90fc0231, - 0x00f880fc, -/* 0x0294: find */ - 0x87f080f9, - 0x0131f458, -/* 0x029c: find_loop */ - 0xb8008a98, - 0x0bf406ae, - 0x5880b610, - 0x021086b1, - 0xf4f01bf4, -/* 0x02b2: find_done */ - 0x8eb90132, - 0xf880fc02, -/* 0x02b9: send */ - 0x9421f500, - 0x9701f402, -/* 0x02c2: recv */ - 0xe89800f8, - 0x04e99805, - 0xb80132f4, - 0x0bf40689, - 0x0389c43d, - 0xf00180b6, - 0xe8800784, - 0x02ea9805, - 0x8ffef0f9, - 0xb9f0f901, - 0x999402ef, - 0x00e9bb04, - 0x9818e0b6, - 0xec9803eb, - 0x01ed9802, - 0xf900ee98, - 0xfef0fca5, - 0x31f400f8, -/* 0x030b: recv_done */ - 0xf8f0fc01, -/* 0x030d: init */ - 0x0817f100, - 0x0614b601, - 0xe70011cf, - 0xb6010911, - 0x14fe0814, - 0xe017f100, - 0x0013f000, - 0xb61c07f0, - 0x01d00604, - 0xf004bd00, - 0x07f0ff17, - 0x0604b614, - 0xbd0001d0, - 0x0217f004, - 0x080015f1, - 0xb61007f0, - 0x01d00604, - 0xf104bd00, - 0xf0010a17, - 0x10fe0013, - 0x1031f400, - 0xf00117f0, - 0x04b63807, - 0x0001d006, - 0xf7f004bd, -/* 0x0371: init_proc */ - 0x01f19858, - 0xf40016b0, - 0x15f9fa0b, - 0xf458f0b6, -/* 0x0382: host_send */ - 0x17f1f20e, - 0x14b604b0, - 0x0011cf06, - 0x04a027f1, - 0xcf0624b6, - 0x12b80022, - 0x320bf406, - 0x94071ec4, - 0xe0b704ee, - 0xeb980218, - 0x02ec9803, - 0x9801ed98, - 0x21f500ee, - 0x10b602b9, - 0x0f1ec401, - 0x04b007f1, - 0xd00604b6, - 0x04bd0001, -/* 0x03cb: host_send_done */ - 0xf8ba0ef4, -/* 0x03cd: host_recv */ - 0x4917f100, - 0x5413f14e, - 0x06e1b852, -/* 0x03db: host_recv_wait */ - 0xf1aa0bf4, - 0xb604cc17, - 0x11cf0614, - 0xc827f100, - 0x0624b604, - 0xf00022cf, - 0x12b80816, - 0xe60bf406, - 0xb60723c4, - 0x30b70434, - 0x3b800298, - 0x023c8003, - 0x80013d80, - 0x20b6003e, - 0x0f24f001, - 0x04c807f1, - 0xd00604b6, - 0x04bd0002, - 0xf04027f0, - 0x04b60007, - 0x0002d006, - 0x00f804bd, -/* 0x0430: host_init */ - 0x008017f1, - 0xf11014b6, - 0xf1021815, - 0xb604d007, - 0x01d00604, - 0xf104bd00, - 0xb6008017, - 0x15f11014, - 0x07f10298, - 0x04b604dc, - 0x0001d006, - 0x17f004bd, - 0xc407f101, - 0x0604b604, - 0xbd0001d0, -/* 0x046f: memx_func_enter */ - 0xf000f804, - 0x07f10467, - 0x04b607e0, - 0x0006d006, -/* 0x047e: memx_func_enter_wait */ - 0x67f104bd, - 0x64b607c0, - 0x0066cf06, - 0xf40464f0, - 0x1698f30b, - 0x0410b600, -/* 0x0496: memx_func_leave */ - 0x67f000f8, - 0xe407f104, - 0x0604b607, - 0xbd0006d0, -/* 0x04a5: memx_func_leave_wait */ - 0xc067f104, - 0x0664b607, - 0xf00066cf, - 0x1bf40464, -/* 0x04b7: memx_func_wr32 */ - 0x9800f8f3, - 0x15980016, - 0x0810b601, - 0x50f960f9, - 0xe0fcd0fc, - 0xf13f21f4, - 0xfd140003, - 0x05800506, - 0xb604bd00, - 0x1bf40242, -/* 0x04df: memx_func_wait */ - 0xf000f8dd, - 0x84b62c87, - 0x0088cf06, - 0x98001e98, - 0x1c98011d, - 0x031b9802, - 0xf41010b6, - 0x00f89c21, -/* 0x04fc: memx_func_delay */ - 0xb6001e98, - 0x21f40410, -/* 0x0507: memx_exec */ - 0xf900f87f, - 0xb9d0f9e0, - 0xb2b902c1, -/* 0x0511: memx_exec_next */ - 0x00139802, - 0x950410b6, - 0x30f01034, - 0xc835980c, - 0x12b855f9, - 0xec1ef406, - 0xe0fcd0fc, - 0x02b921f5, -/* 0x0532: memx_info */ - 0xc7f100f8, - 0xb7f10354, - 0x21f50800, - 0x00f802b9, -/* 0x0540: memx_recv */ - 0xf401d6b0, - 0xd6b0c40b, - 0xe90bf400, -/* 0x054e: memx_init */ - 0x00f800f8, -/* 0x0550: perf_recv */ -/* 0x0552: perf_init */ - 0x00f800f8, -/* 0x0554: test_recv */ - 0x05d817f1, - 0xcf0614b6, - 0x10b60011, - 0xd807f101, - 0x0604b605, - 0xbd0001d0, - 0x00e7f104, - 0x4fe3f1d9, - 0xf521f513, -/* 0x057b: test_init */ - 0xf100f801, - 0xf50800e7, - 0xf801f521, -/* 0x0585: idle_recv */ -/* 0x0587: idle */ - 0xf400f800, - 0x17f10031, - 0x14b605d4, - 0x0011cf06, - 0xf10110b6, - 0xb605d407, - 0x01d00604, -/* 0x05a3: idle_loop */ - 0xf004bd00, - 0x32f45817, -/* 0x05a9: idle_proc */ -/* 0x05a9: idle_proc_exec */ - 0xb910f902, - 0x21f5021e, - 0x10fc02c2, - 0xf40911f4, - 0x0ef40231, -/* 0x05bd: idle_proc_next */ - 0x5810b6ef, - 0xf4061fb8, - 0x02f4e61b, - 0x0028f4dd, - 0x00bb0ef4, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc deleted file mode 100644 index 32d65ea..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc +++ /dev/null @@ -1,63 +0,0 @@ -/* - * 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 - */ - -#define NVKM_PPWR_CHIPSET GF119 - -//#define NVKM_FALCON_PC24 -#define NVKM_FALCON_UNSHIFTED_IO -//#define NVKM_FALCON_MMIO_UAS -//#define NVKM_FALCON_MMIO_TRAP - -#include "macros.fuc" - -.section #nvd0_pwr_data -#define INCLUDE_PROC -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_PROC - -#define INCLUDE_DATA -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_DATA -.align 256 - -.section #nvd0_pwr_code -#define INCLUDE_CODE -#include "kernel.fuc" -#include "host.fuc" -#include "memx.fuc" -#include "perf.fuc" -#include "test.fuc" -#include "idle.fuc" -#undef INCLUDE_CODE -.align 256 diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h deleted file mode 100644 index ce65e2a..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h +++ /dev/null @@ -1,1229 +0,0 @@ -uint32_t nvd0_pwr_data[] = { -/* 0x0000: proc_kern */ - 0x52544e49, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0058: proc_list_head */ - 0x54534f48, - 0x000003be, - 0x00000367, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x584d454d, - 0x000004c4, - 0x000004b6, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x46524550, - 0x000004c8, - 0x000004c6, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x54534554, - 0x000004eb, - 0x000004ca, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x454c4449, - 0x000004f7, - 0x000004f5, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0210: proc_list_tail */ -/* 0x0210: time_prev */ - 0x00000000, -/* 0x0214: time_next */ - 0x00000000, -/* 0x0218: fifo_queue */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0298: rfifo_queue */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0318: memx_func_head */ - 0x00010000, - 0x00000000, - 0x000003f4, -/* 0x0324: memx_func_next */ - 0x00000001, - 0x00000000, - 0x00000415, - 0x00000002, - 0x00000002, - 0x00000430, - 0x00040003, - 0x00000000, - 0x00000458, - 0x00010004, - 0x00000000, - 0x00000472, -/* 0x0354: memx_func_tail */ -/* 0x0354: memx_data_head */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -/* 0x0b54: memx_data_tail */ - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; - -uint32_t nvd0_pwr_code[] = { - 0x02bf0ef5, -/* 0x0004: rd32 */ - 0x07a007f1, - 0xbd000ed0, - 0x01e7f004, - 0xf101e3f0, - 0xd007ac07, - 0x04bd000e, -/* 0x001c: rd32_wait */ - 0x07ace7f1, - 0xf100eecf, - 0xf47000e4, - 0xd7f1f51b, - 0xddcf07a4, -/* 0x0033: wr32 */ - 0xf100f800, - 0xd007a007, - 0x04bd000e, - 0x07a407f1, - 0xbd000dd0, - 0x02e7f004, - 0xf0f0e5f0, - 0x07f101e3, - 0x0ed007ac, -/* 0x0057: wr32_wait */ - 0xf104bd00, - 0xcf07ace7, - 0xe4f100ee, - 0x1bf47000, -/* 0x0067: nsec */ - 0xf000f8f5, - 0x88cf2c87, -/* 0x006d: nsec_loop */ - 0x2c97f000, - 0xbb0099cf, - 0x9eb80298, - 0xf41ef406, -/* 0x007e: wait */ - 0x87f000f8, - 0x0088cf2c, -/* 0x0084: wait_loop */ - 0xf402eeb9, - 0xdab90421, - 0x04adfd02, - 0xf406acb8, - 0x97f0120b, - 0x0099cf2c, - 0xb80298bb, - 0x1ef4069b, -/* 0x00a5: wait_done */ -/* 0x00a7: intr_watchdog */ - 0x9800f8e2, - 0x96b003e9, - 0x2a0bf400, - 0xbb840a98, - 0x1cf4029a, - 0x01d7f00f, - 0x020621f5, - 0x0ef494bd, -/* 0x00c5: intr_watchdog_next_time */ - 0x850a9815, - 0xf400a6b0, - 0x9ab8090b, - 0x061cf406, -/* 0x00d4: intr_watchdog_next_time_set */ -/* 0x00d7: intr_watchdog_next_proc */ - 0x80850980, - 0xe0b603e9, - 0x10e6b158, - 0xc61bf402, -/* 0x00e6: intr */ - 0x00f900f8, - 0x80f904bd, - 0xa0f990f9, - 0xc0f9b0f9, - 0xe0f9d0f9, - 0xf7f0f0f9, - 0x0188fe00, - 0x87f180f9, - 0x88cf05d0, - 0x0180b600, - 0x05d007f1, - 0xbd0008d0, - 0x0887f004, - 0xc40088cf, - 0x0bf40289, - 0x85008020, - 0xf458e7f0, - 0x0998a721, - 0x0096b085, - 0xf00e0bf4, - 0x09d03407, - 0x8004bd00, -/* 0x013e: intr_skip_watchdog */ - 0x89e48409, - 0x0bf40800, - 0x8897f13c, - 0x0099cf06, - 0xf4029ac4, - 0xc7f1260b, - 0xcccf04c0, - 0xf1c0f900, - 0xf14f48e7, - 0xf05453e3, - 0x21f500d7, - 0xc0fc026b, - 0x04c007f1, - 0xbd000cd0, -/* 0x0175: intr_subintr_skip_fifo */ - 0x8807f104, - 0x0009d006, -/* 0x017e: intr_skip_subintr */ - 0x89c404bd, - 0x070bf420, - 0xffbfa4f1, -/* 0x0188: intr_skip_pause */ - 0xf44089c4, - 0xa4f1070b, -/* 0x0192: intr_skip_user0 */ - 0x07f0ffbf, - 0x0008d004, - 0x80fc04bd, - 0xfc0088fe, - 0xfce0fcf0, - 0xfcc0fcd0, - 0xfca0fcb0, - 0xfc80fc90, - 0x0032f400, -/* 0x01b6: timer */ - 0x32f401f8, - 0x03f89810, - 0xf40086b0, - 0xfe80421c, - 0x3807f003, - 0xbd0008d0, - 0x0887f004, - 0xf00088cf, - 0x1bf40284, - 0x3487f020, - 0xb80088cf, - 0x0bf406e0, - 0x06e8b809, -/* 0x01eb: timer_reset */ - 0xf0191ef4, - 0x0ed03407, - 0x8004bd00, -/* 0x01f6: timer_enable */ - 0x87f0840e, - 0x3807f001, - 0xbd0008d0, -/* 0x0201: timer_done */ - 0x1031f404, -/* 0x0206: send_proc */ - 0x80f900f8, - 0xe89890f9, - 0x04e99805, - 0xb80486f0, - 0x0bf40689, - 0x0398c42a, - 0xb6048894, - 0x8ebb1880, - 0x00fa9800, - 0x80008a80, - 0x8c80018d, - 0x038b8002, - 0xf00190b6, - 0xe9800794, - 0x0231f404, -/* 0x0240: send_done */ - 0x80fc90fc, -/* 0x0246: find */ - 0x80f900f8, - 0xf45887f0, -/* 0x024e: find_loop */ - 0x8a980131, - 0x06aeb800, - 0xb6100bf4, - 0x86b15880, - 0x1bf40210, - 0x0132f4f0, -/* 0x0264: find_done */ - 0xfc028eb9, -/* 0x026b: send */ - 0xf500f880, - 0xf4024621, - 0x00f89701, -/* 0x0274: recv */ - 0x9805e898, - 0x32f404e9, - 0x0689b801, - 0xc43d0bf4, - 0x80b60389, - 0x0784f001, - 0x9805e880, - 0xf0f902ea, - 0xf9018ffe, - 0x02efb9f0, - 0xbb049994, - 0xe0b600e9, - 0x03eb9818, - 0x9802ec98, - 0xee9801ed, - 0xfca5f900, - 0x00f8fef0, - 0xfc0131f4, -/* 0x02bd: recv_done */ -/* 0x02bf: init */ - 0xf100f8f0, - 0xcf010817, - 0x11e70011, - 0x14b60109, - 0x0014fe08, - 0x00e017f1, - 0xf00013f0, - 0x01d01c07, - 0xf004bd00, - 0x07f0ff17, - 0x0001d014, - 0x17f004bd, - 0x0015f102, - 0x1007f008, - 0xbd0001d0, - 0xe617f104, - 0x0013f000, - 0xf40010fe, - 0x17f01031, - 0x3807f001, - 0xbd0001d0, - 0x58f7f004, -/* 0x0314: init_proc */ - 0xb001f198, - 0x0bf40016, - 0xb615f9fa, - 0x0ef458f0, -/* 0x0325: host_send */ - 0xb017f1f2, - 0x0011cf04, - 0x04a027f1, - 0xb80022cf, - 0x0bf40612, - 0x071ec42f, - 0xb704ee94, - 0x980218e0, - 0xec9803eb, - 0x01ed9802, - 0xf500ee98, - 0xb6026b21, - 0x1ec40110, - 0xb007f10f, - 0x0001d004, - 0x0ef404bd, -/* 0x0365: host_send_done */ -/* 0x0367: host_recv */ - 0xf100f8c3, - 0xf14e4917, - 0xb8525413, - 0x0bf406e1, -/* 0x0375: host_recv_wait */ - 0xcc17f1b3, - 0x0011cf04, - 0x04c827f1, - 0xf00022cf, - 0x12b80816, - 0xec0bf406, - 0xb60723c4, - 0x30b70434, - 0x3b800298, - 0x023c8003, - 0x80013d80, - 0x20b6003e, - 0x0f24f001, - 0x04c807f1, - 0xbd0002d0, - 0x4027f004, - 0xd00007f0, - 0x04bd0002, -/* 0x03be: host_init */ - 0x17f100f8, - 0x14b60080, - 0x1815f110, - 0xd007f102, - 0x0001d004, - 0x17f104bd, - 0x14b60080, - 0x9815f110, - 0xdc07f102, - 0x0001d004, - 0x17f004bd, - 0xc407f101, - 0x0001d004, - 0x00f804bd, -/* 0x03f4: memx_func_enter */ - 0xf10467f0, - 0xd007e007, - 0x04bd0006, -/* 0x0400: memx_func_enter_wait */ - 0x07c067f1, - 0xf00066cf, - 0x0bf40464, - 0x001698f6, - 0xf80410b6, -/* 0x0415: memx_func_leave */ - 0x0467f000, - 0x07e407f1, - 0xbd0006d0, -/* 0x0421: memx_func_leave_wait */ - 0xc067f104, - 0x0066cf07, - 0xf40464f0, - 0x00f8f61b, -/* 0x0430: memx_func_wr32 */ - 0x98001698, - 0x10b60115, - 0xf960f908, - 0xfcd0fc50, - 0x3321f4e0, - 0x140003f1, - 0x800506fd, - 0x04bd0005, - 0xf40242b6, - 0x00f8dd1b, -/* 0x0458: memx_func_wait */ - 0xcf2c87f0, - 0x1e980088, - 0x011d9800, - 0x98021c98, - 0x10b6031b, - 0x7e21f410, -/* 0x0472: memx_func_delay */ - 0x1e9800f8, - 0x0410b600, - 0xf86721f4, -/* 0x047d: memx_exec */ - 0xf9e0f900, - 0x02c1b9d0, -/* 0x0487: memx_exec_next */ - 0x9802b2b9, - 0x10b60013, - 0x10349504, - 0x980c30f0, - 0x55f9c835, - 0xf40612b8, - 0xd0fcec1e, - 0x21f5e0fc, - 0x00f8026b, -/* 0x04a8: memx_info */ - 0x0354c7f1, - 0x0800b7f1, - 0x026b21f5, -/* 0x04b6: memx_recv */ - 0xd6b000f8, - 0xc40bf401, - 0xf400d6b0, - 0x00f8e90b, -/* 0x04c4: memx_init */ -/* 0x04c6: perf_recv */ - 0x00f800f8, -/* 0x04c8: perf_init */ -/* 0x04ca: test_recv */ - 0x17f100f8, - 0x11cf05d8, - 0x0110b600, - 0x05d807f1, - 0xbd0001d0, - 0x00e7f104, - 0x4fe3f1d9, - 0xb621f513, -/* 0x04eb: test_init */ - 0xf100f801, - 0xf50800e7, - 0xf801b621, -/* 0x04f5: idle_recv */ -/* 0x04f7: idle */ - 0xf400f800, - 0x17f10031, - 0x11cf05d4, - 0x0110b600, - 0x05d407f1, - 0xbd0001d0, -/* 0x050d: idle_loop */ - 0x5817f004, -/* 0x0513: idle_proc */ -/* 0x0513: idle_proc_exec */ - 0xf90232f4, - 0x021eb910, - 0x027421f5, - 0x11f410fc, - 0x0231f409, -/* 0x0527: idle_proc_next */ - 0xb6ef0ef4, - 0x1fb85810, - 0xe61bf406, - 0xf4dd02f4, - 0x0ef40028, - 0x000000c1, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, - 0x00000000, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h deleted file mode 100644 index 5fb0ccc..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h +++ /dev/null @@ -1,27 +0,0 @@ -#ifndef __NVKM_PWR_OS_H__ -#define __NVKM_PWR_OS_H__ - -/* Process names */ -#define PROC_KERN 0x52544e49 -#define PROC_IDLE 0x454c4449 -#define PROC_HOST 0x54534f48 -#define PROC_MEMX 0x584d454d -#define PROC_PERF 0x46524550 -#define PROC_TEST 0x54534554 - -/* KERN: message identifiers */ -#define KMSG_FIFO 0x00000000 -#define KMSG_ALARM 0x00000001 - -/* MEMX: message identifiers */ -#define MEMX_MSG_INFO 0 -#define MEMX_MSG_EXEC 1 - -/* MEMX: script opcode definitions */ -#define MEMX_ENTER 0 -#define MEMX_LEAVE 1 -#define MEMX_WR32 2 -#define MEMX_WAIT 3 -#define MEMX_DELAY 4 - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc deleted file mode 100644 index 38eadf7..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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 - */ - -#ifdef INCLUDE_PROC -process(PROC_PERF, #perf_init, #perf_recv) -#endif - -/****************************************************************************** - * PERF data segment - *****************************************************************************/ -#ifdef INCLUDE_DATA -#endif - -/****************************************************************************** - * PERF code segment - *****************************************************************************/ -#ifdef INCLUDE_CODE - -// description -// -// $r15 - current (perf) -// $r14 - sender process name -// $r13 - message -// $r12 - data0 -// $r11 - data1 -// $r0 - zero -perf_recv: - ret - -// description -// -// $r15 - current (perf) -// $r0 - zero -perf_init: - ret -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc deleted file mode 100644 index 0c3a71b..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc +++ /dev/null @@ -1,64 +0,0 @@ -/* - * 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 - */ - -#ifdef INCLUDE_PROC -process(PROC_TEST, #test_init, #test_recv) -#endif - -/****************************************************************************** - * TEST data segment - *****************************************************************************/ -#ifdef INCLUDE_DATA -#endif - -/****************************************************************************** - * TEST code segment - *****************************************************************************/ -#ifdef INCLUDE_CODE -// description -// -// $r15 - current (test) -// $r14 - sender process name -// $r13 - message -// $r12 - data0 -// $r11 - data1 -// $r0 - zero -test_recv: - nv_iord($r1, NV_PPWR_DSCRATCH(2)) - add b32 $r1 1 - nv_iowr(NV_PPWR_DSCRATCH(2), $r1) - mov $r14 -0x2700 /* 0xd900, envyas grrr! */ - sethi $r14 0x134f0000 - call(timer) - ret - -// description -// -// $r15 - current (test) -// $r0 - zero -test_init: - mov $r14 0x800 - call(timer) - ret -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c deleted file mode 100644 index 03de310..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c +++ /dev/null @@ -1,121 +0,0 @@ -#ifndef __NVKM_PWR_MEMX_H__ -#define __NVKM_PWR_MEMX_H__ - -#include <subdev/pwr.h> -#include <subdev/pwr/fuc/os.h> - -struct nouveau_memx { - struct nouveau_pwr *ppwr; - u32 base; - u32 size; - struct { - u32 mthd; - u32 size; - u32 data[64]; - } c; -}; - -static void -memx_out(struct nouveau_memx *memx) -{ - struct nouveau_pwr *ppwr = memx->ppwr; - int i; - - if (memx->c.size) { - nv_wr32(ppwr, 0x10a1c4, (memx->c.size << 16) | memx->c.mthd); - for (i = 0; i < memx->c.size; i++) - nv_wr32(ppwr, 0x10a1c4, memx->c.data[i]); - memx->c.size = 0; - } -} - -static void -memx_cmd(struct nouveau_memx *memx, u32 mthd, u32 size, u32 data[]) -{ - if ((memx->c.size + size >= ARRAY_SIZE(memx->c.data)) || - (memx->c.size && memx->c.mthd != mthd)) - memx_out(memx); - memcpy(&memx->c.data[memx->c.size], data, size * sizeof(data[0])); - memx->c.size += size; - memx->c.mthd = mthd; -} - -int -nouveau_memx_init(struct nouveau_pwr *ppwr, struct nouveau_memx **pmemx) -{ - struct nouveau_memx *memx; - u32 reply[2]; - int ret; - - ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO, 0, 0); - if (ret) - return ret; - - memx = *pmemx = kzalloc(sizeof(*memx), GFP_KERNEL); - if (!memx) - return -ENOMEM; - memx->ppwr = ppwr; - memx->base = reply[0]; - memx->size = reply[1]; - - /* acquire data segment access */ - do { - nv_wr32(ppwr, 0x10a580, 0x00000003); - } while (nv_rd32(ppwr, 0x10a580) != 0x00000003); - nv_wr32(ppwr, 0x10a1c0, 0x01000000 | memx->base); - nv_wr32(ppwr, 0x10a1c4, 0x00010000 | MEMX_ENTER); - nv_wr32(ppwr, 0x10a1c4, 0x00000000); - return 0; -} - -int -nouveau_memx_fini(struct nouveau_memx **pmemx, bool exec) -{ - struct nouveau_memx *memx = *pmemx; - struct nouveau_pwr *ppwr = memx->ppwr; - u32 finish, reply[2]; - - /* flush the cache... */ - memx_out(memx); - - /* release data segment access */ - nv_wr32(ppwr, 0x10a1c4, 0x00000000 | MEMX_LEAVE); - finish = nv_rd32(ppwr, 0x10a1c0) & 0x00ffffff; - nv_wr32(ppwr, 0x10a580, 0x00000000); - - /* call MEMX process to execute the script, and wait for reply */ - if (exec) { - ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_EXEC, - memx->base, finish); - } - - kfree(memx); - return 0; -} - -void -nouveau_memx_wr32(struct nouveau_memx *memx, u32 addr, u32 data) -{ - nv_debug(memx->ppwr, "R[%06x] = 0x%08x\n", addr, data); - memx_cmd(memx, MEMX_WR32, 2, (u32[]){ addr, data }); -} - -void -nouveau_memx_wait(struct nouveau_memx *memx, - u32 addr, u32 mask, u32 data, u32 nsec) -{ - nv_debug(memx->ppwr, "R[%06x] & 0x%08x == 0x%08x, %d us\n", - addr, mask, data, nsec); - memx_cmd(memx, MEMX_WAIT, 4, (u32[]){ addr, ~mask, data, nsec }); - memx_out(memx); /* fuc can't handle multiple */ -} - -void -nouveau_memx_nsec(struct nouveau_memx *memx, u32 nsec) -{ - nv_debug(memx->ppwr, " DELAY = %d ns\n", nsec); - memx_cmd(memx, MEMX_DELAY, 1, (u32[]){ nsec }); - memx_out(memx); /* fuc can't handle multiple */ -} - -#endif diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c deleted file mode 100644 index 52c8541..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 <subdev/pwr.h> - -#include "fuc/nv108.fuc.h" - -struct nv108_pwr_priv { - struct nouveau_pwr base; -}; - -static int -nv108_pwr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv108_pwr_priv *priv; - int ret; - - ret = nouveau_pwr_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.code.data = nv108_pwr_code; - priv->base.code.size = sizeof(nv108_pwr_code); - priv->base.data.data = nv108_pwr_data; - priv->base.data.size = sizeof(nv108_pwr_data); - return 0; -} - -struct nouveau_oclass -nv108_pwr_oclass = { - .handle = NV_SUBDEV(PWR, 0x00), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv108_pwr_ctor, - .dtor = _nouveau_pwr_dtor, - .init = _nouveau_pwr_init, - .fini = _nouveau_pwr_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c deleted file mode 100644 index c132b7c..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * 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 <subdev/pwr.h> - -#include "fuc/nva3.fuc.h" - -struct nva3_pwr_priv { - struct nouveau_pwr base; -}; - -static int -nva3_pwr_init(struct nouveau_object *object) -{ - struct nva3_pwr_priv *priv = (void *)object; - nv_mask(priv, 0x022210, 0x00000001, 0x00000000); - nv_mask(priv, 0x022210, 0x00000001, 0x00000001); - return nouveau_pwr_init(&priv->base); -} - -static int -nva3_pwr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nva3_pwr_priv *priv; - int ret; - - ret = nouveau_pwr_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.code.data = nva3_pwr_code; - priv->base.code.size = sizeof(nva3_pwr_code); - priv->base.data.data = nva3_pwr_data; - priv->base.data.size = sizeof(nva3_pwr_data); - return 0; -} - -struct nouveau_oclass -nva3_pwr_oclass = { - .handle = NV_SUBDEV(PWR, 0xa3), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nva3_pwr_ctor, - .dtor = _nouveau_pwr_dtor, - .init = nva3_pwr_init, - .fini = _nouveau_pwr_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c deleted file mode 100644 index 495f685..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 <subdev/pwr.h> - -#include "fuc/nvc0.fuc.h" - -struct nvc0_pwr_priv { - struct nouveau_pwr base; -}; - -static int -nvc0_pwr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nvc0_pwr_priv *priv; - int ret; - - ret = nouveau_pwr_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.code.data = nvc0_pwr_code; - priv->base.code.size = sizeof(nvc0_pwr_code); - priv->base.data.data = nvc0_pwr_data; - priv->base.data.size = sizeof(nvc0_pwr_data); - return 0; -} - -struct nouveau_oclass -nvc0_pwr_oclass = { - .handle = NV_SUBDEV(PWR, 0xc0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvc0_pwr_ctor, - .dtor = _nouveau_pwr_dtor, - .init = _nouveau_pwr_init, - .fini = _nouveau_pwr_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c deleted file mode 100644 index 043aa14..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c +++ /dev/null @@ -1,62 +0,0 @@ -/* - * 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 <subdev/pwr.h> - -#include "fuc/nvd0.fuc.h" - -struct nvd0_pwr_priv { - struct nouveau_pwr base; -}; - -static int -nvd0_pwr_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nvd0_pwr_priv *priv; - int ret; - - ret = nouveau_pwr_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - priv->base.code.data = nvd0_pwr_code; - priv->base.code.size = sizeof(nvd0_pwr_code); - priv->base.data.data = nvd0_pwr_data; - priv->base.data.size = sizeof(nvd0_pwr_data); - return 0; -} - -struct nouveau_oclass -nvd0_pwr_oclass = { - .handle = NV_SUBDEV(PWR, 0xd0), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nvd0_pwr_ctor, - .dtor = _nouveau_pwr_dtor, - .init = _nouveau_pwr_init, - .fini = _nouveau_pwr_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c index 80e584a..f1de7a9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/base.c @@ -92,11 +92,10 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode) struct nouveau_timer *ptimer = nouveau_timer(therm); struct nouveau_therm_priv *priv = (void *)therm; unsigned long flags; - bool immd = true; - bool poll = true; - int duty = -1; + int duty; spin_lock_irqsave(&priv->lock, flags); + nv_debug(therm, "FAN speed check\n"); if (mode < 0) mode = priv->mode; priv->mode = mode; @@ -107,49 +106,28 @@ nouveau_therm_update(struct nouveau_therm *therm, int mode) duty = nouveau_therm_fan_get(therm); if (duty < 0) duty = 100; - poll = false; break; case NOUVEAU_THERM_CTRL_AUTO: - if (priv->fan->bios.nr_fan_trip) { + if (priv->fan->bios.nr_fan_trip) duty = nouveau_therm_update_trip(therm); - } else - if (priv->fan->bios.linear_min_temp || - priv->fan->bios.linear_max_temp) { + else duty = nouveau_therm_update_linear(therm); - } else { - if (priv->cstate) - duty = priv->cstate; - poll = false; - } - immd = false; break; case NOUVEAU_THERM_CTRL_NONE: default: ptimer->alarm_cancel(ptimer, &priv->alarm); - poll = false; + goto done; } - if (list_empty(&priv->alarm.head) && poll) + nv_debug(therm, "FAN target request: %d%%\n", duty); + nouveau_therm_fan_set(therm, (mode != NOUVEAU_THERM_CTRL_AUTO), duty); + +done: + if (list_empty(&priv->alarm.head) && (mode == NOUVEAU_THERM_CTRL_AUTO)) ptimer->alarm(ptimer, 1000000000ULL, &priv->alarm); + else if (!list_empty(&priv->alarm.head)) + nv_debug(therm, "therm fan alarm list is not empty\n"); spin_unlock_irqrestore(&priv->lock, flags); - - if (duty >= 0) { - nv_debug(therm, "FAN target request: %d%%\n", duty); - nouveau_therm_fan_set(therm, immd, duty); - } -} - -int -nouveau_therm_cstate(struct nouveau_therm *ptherm, int fan, int dir) -{ - struct nouveau_therm_priv *priv = (void *)ptherm; - if (!dir || (dir < 0 && fan < priv->cstate) || - (dir > 0 && fan > priv->cstate)) { - nv_debug(ptherm, "default fan speed -> %d%%\n", fan); - priv->cstate = fan; - nouveau_therm_update(ptherm, -1); - } - return 0; } static void @@ -171,15 +149,14 @@ nouveau_therm_fan_mode(struct nouveau_therm *therm, int mode) "automatic" }; - /* The default PPWR ucode on fermi interferes with fan management */ + /* The default PDAEMON ucode interferes with fan management */ if ((mode >= ARRAY_SIZE(name)) || - (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0 && - !nouveau_subdev(device, NVDEV_SUBDEV_PWR))) + (mode != NOUVEAU_THERM_CTRL_NONE && device->card_type >= NV_C0)) return -EINVAL; /* do not allow automatic fan management if the thermal sensor is * not available */ - if (priv->mode == NOUVEAU_THERM_CTRL_AUTO && therm->temp_get(therm) < 0) + if (priv->mode == 2 && therm->temp_get(therm) < 0) return -EINVAL; if (priv->mode == mode) @@ -358,7 +335,7 @@ nouveau_therm_preinit(struct nouveau_therm *therm) nouveau_therm_ic_ctor(therm); nouveau_therm_fan_ctor(therm); - nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_AUTO); + nouveau_therm_fan_mode(therm, NOUVEAU_THERM_CTRL_NONE); nouveau_therm_sensor_preinit(therm); return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c index 95f6129..39f47b9 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fan.c @@ -185,11 +185,8 @@ nouveau_therm_fan_set_defaults(struct nouveau_therm *therm) priv->fan->bios.max_duty = 100; priv->fan->bios.bump_period = 500; priv->fan->bios.slow_down_period = 2000; -/*XXX: talk to mupuf */ -#if 0 priv->fan->bios.linear_min_temp = 40; priv->fan->bios.linear_max_temp = 85; -#endif } static void diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c b/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c index f69dab1..e601773 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/fantog.c @@ -97,13 +97,6 @@ nouveau_fantog_create(struct nouveau_therm *therm, struct dcb_gpio_func *func) { struct nouveau_therm_priv *tpriv = (void *)therm; struct nouveau_fantog_priv *priv; - int ret; - - if (therm->pwm_ctrl) { - ret = therm->pwm_ctrl(therm, func->line, false); - if (ret) - return ret; - } priv = kzalloc(sizeof(*priv), GFP_KERNEL); tpriv->fan = &priv->base; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c index e44ed7b..8b3adec 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/ic.c @@ -41,8 +41,7 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c, if (!client) return false; - if (!client->dev.driver || - to_i2c_driver(client->dev.driver)->detect(client, info)) { + if (!client->driver || client->driver->detect(client, info)) { i2c_unregister_device(client); return false; } @@ -56,28 +55,28 @@ probe_monitoring_device(struct nouveau_i2c_port *i2c, return true; } -static struct nouveau_i2c_board_info +static struct i2c_board_info nv_board_infos[] = { - { { I2C_BOARD_INFO("w83l785ts", 0x2d) }, 0 }, - { { I2C_BOARD_INFO("w83781d", 0x2d) }, 0 }, - { { I2C_BOARD_INFO("adt7473", 0x2e) }, 20 }, - { { I2C_BOARD_INFO("adt7473", 0x2d) }, 20 }, - { { I2C_BOARD_INFO("adt7473", 0x2c) }, 20 }, - { { I2C_BOARD_INFO("f75375", 0x2e) }, 0 }, - { { I2C_BOARD_INFO("lm99", 0x4c) }, 0 }, - { { I2C_BOARD_INFO("lm90", 0x4c) }, 0 }, - { { I2C_BOARD_INFO("lm90", 0x4d) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x18) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x19) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x1a) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x29) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x2a) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x2b) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x4c) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x4d) }, 0 }, - { { I2C_BOARD_INFO("adm1021", 0x4e) }, 0 }, - { { I2C_BOARD_INFO("lm63", 0x18) }, 0 }, - { { I2C_BOARD_INFO("lm63", 0x4e) }, 0 }, + { I2C_BOARD_INFO("w83l785ts", 0x2d) }, + { I2C_BOARD_INFO("w83781d", 0x2d) }, + { I2C_BOARD_INFO("adt7473", 0x2e) }, + { I2C_BOARD_INFO("adt7473", 0x2d) }, + { I2C_BOARD_INFO("adt7473", 0x2c) }, + { I2C_BOARD_INFO("f75375", 0x2e) }, + { I2C_BOARD_INFO("lm99", 0x4c) }, + { I2C_BOARD_INFO("lm90", 0x4c) }, + { I2C_BOARD_INFO("lm90", 0x4d) }, + { I2C_BOARD_INFO("adm1021", 0x18) }, + { I2C_BOARD_INFO("adm1021", 0x19) }, + { I2C_BOARD_INFO("adm1021", 0x1a) }, + { I2C_BOARD_INFO("adm1021", 0x29) }, + { I2C_BOARD_INFO("adm1021", 0x2a) }, + { I2C_BOARD_INFO("adm1021", 0x2b) }, + { I2C_BOARD_INFO("adm1021", 0x4c) }, + { I2C_BOARD_INFO("adm1021", 0x4d) }, + { I2C_BOARD_INFO("adm1021", 0x4e) }, + { I2C_BOARD_INFO("lm63", 0x18) }, + { I2C_BOARD_INFO("lm63", 0x4e) }, { } }; @@ -90,9 +89,9 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm) struct nvbios_extdev_func extdev_entry; if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_LM89, &extdev_entry)) { - struct nouveau_i2c_board_info board[] = { - { { I2C_BOARD_INFO("lm90", extdev_entry.addr >> 1) }, 0}, - { } + struct i2c_board_info board[] = { + { I2C_BOARD_INFO("lm90", extdev_entry.addr >> 1) }, + { } }; i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", @@ -102,9 +101,9 @@ nouveau_therm_ic_ctor(struct nouveau_therm *therm) } if (!nvbios_extdev_find(bios, NVBIOS_EXTDEV_ADT7473, &extdev_entry)) { - struct nouveau_i2c_board_info board[] = { - { { I2C_BOARD_INFO("adt7473", extdev_entry.addr >> 1) }, 20 }, - { } + struct i2c_board_info board[] = { + { I2C_BOARD_INFO("adt7473", extdev_entry.addr >> 1) }, + { } }; i2c->identify(i2c, NV_I2C_DEFAULT(0), "monitoring device", diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c index 1d15c52..42ba633 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nv84.c @@ -126,7 +126,7 @@ nv84_therm_intr(struct nouveau_subdev *subdev) spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags); - intr = nv_rd32(therm, 0x20100) & 0x3ff; + intr = nv_rd32(therm, 0x20100); /* THRS_4: downclock */ if (intr & 0x002) { @@ -209,19 +209,6 @@ nv84_therm_ctor(struct nouveau_object *parent, return nouveau_therm_preinit(&priv->base.base); } -int -nv84_therm_fini(struct nouveau_object *object, bool suspend) -{ - /* Disable PTherm IRQs */ - nv_wr32(object, 0x20000, 0x00000000); - - /* ACK all PTherm IRQs */ - nv_wr32(object, 0x20100, 0xffffffff); - nv_wr32(object, 0x1100, 0x10000); /* PBUS */ - - return _nouveau_therm_fini(object, suspend); -} - struct nouveau_oclass nv84_therm_oclass = { .handle = NV_SUBDEV(THERM, 0x84), @@ -229,6 +216,6 @@ nv84_therm_oclass = { .ctor = nv84_therm_ctor, .dtor = _nouveau_therm_dtor, .init = _nouveau_therm_init, - .fini = nv84_therm_fini, + .fini = _nouveau_therm_fini, }, }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c index 3b2c458..d11a7c4 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nva3.c @@ -94,6 +94,6 @@ nva3_therm_oclass = { .ctor = nva3_therm_ctor, .dtor = _nouveau_therm_dtor, .init = nva3_therm_init, - .fini = nv84_therm_fini, + .fini = _nouveau_therm_fini, }, }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c index 4dd4f81..54c28bd 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/nvd0.c @@ -148,6 +148,6 @@ nvd0_therm_oclass = { .ctor = nvd0_therm_ctor, .dtor = _nouveau_therm_dtor, .init = nvd0_therm_init, - .fini = nv84_therm_fini, + .fini = _nouveau_therm_fini, }, }; diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h index 96f8f95..dd38529 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/priv.h @@ -76,7 +76,6 @@ struct nouveau_therm_priv { spinlock_t lock; struct nouveau_therm_trip_point *last_trip; int mode; - int cstate; int suspend; /* bios */ @@ -145,7 +144,6 @@ int nv50_fan_pwm_get(struct nouveau_therm *, int, u32 *, u32 *); int nv50_fan_pwm_set(struct nouveau_therm *, int, u32, u32); int nv50_fan_pwm_clock(struct nouveau_therm *); int nv84_temp_get(struct nouveau_therm *therm); -int nv84_therm_fini(struct nouveau_object *object, bool suspend); int nva3_therm_fan_sense(struct nouveau_therm *); diff --git a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c index cfde9eb..b80a330 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/therm/temp.c @@ -180,6 +180,8 @@ alarm_timer_callback(struct nouveau_alarm *alarm) spin_lock_irqsave(&priv->sensor.alarm_program_lock, flags); + nv_debug(therm, "polling the internal temperature\n"); + nouveau_therm_threshold_hyst_polling(therm, &sensor->thrs_fan_boost, NOUVEAU_THERM_THRS_FANBOOST); diff --git a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c index c0bdd10..57711ec 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c +++ b/drivers/gpu/drm/nouveau/core/subdev/timer/nv04.c @@ -119,8 +119,16 @@ nv04_timer_alarm_cancel(struct nouveau_timer *ptimer, { struct nv04_timer_priv *priv = (void *)ptimer; unsigned long flags; + + /* avoid deleting an entry while the alarm intr is running */ spin_lock_irqsave(&priv->lock, flags); - list_del_init(&alarm->head); + + /* delete the alarm from the list */ + list_del(&alarm->head); + + /* reset the head so as list_empty returns 1 */ + INIT_LIST_HEAD(&alarm->head); + spin_unlock_irqrestore(&priv->lock, flags); } diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c b/drivers/gpu/drm/nouveau/core/subdev/volt/base.c deleted file mode 100644 index 32794a9..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c +++ /dev/null @@ -1,198 +0,0 @@ -/* - * 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 <subdev/volt.h> - -#include <subdev/bios.h> -#include <subdev/bios/vmap.h> -#include <subdev/bios/volt.h> - -static int -nouveau_volt_get(struct nouveau_volt *volt) -{ - if (volt->vid_get) { - int ret = volt->vid_get(volt), i; - if (ret >= 0) { - for (i = 0; i < volt->vid_nr; i++) { - if (volt->vid[i].vid == ret) - return volt->vid[i].uv; - } - ret = -EINVAL; - } - return ret; - } - return -ENODEV; -} - -static int -nouveau_volt_set(struct nouveau_volt *volt, u32 uv) -{ - if (volt->vid_set) { - int i, ret = -EINVAL; - for (i = 0; i < volt->vid_nr; i++) { - if (volt->vid[i].uv == uv) { - ret = volt->vid_set(volt, volt->vid[i].vid); - nv_debug(volt, "set %duv: %d\n", uv, ret); - break; - } - } - return ret; - } - return -ENODEV; -} - -static int -nouveau_volt_map(struct nouveau_volt *volt, u8 id) -{ - struct nouveau_bios *bios = nouveau_bios(volt); - struct nvbios_vmap_entry info; - u8 ver, len; - u16 vmap; - - vmap = nvbios_vmap_entry_parse(bios, id, &ver, &len, &info); - if (vmap) { - if (info.link != 0xff) { - int ret = nouveau_volt_map(volt, info.link); - if (ret < 0) - return ret; - info.min += ret; - } - return info.min; - } - - return id ? id * 10000 : -ENODEV; -} - -static int -nouveau_volt_set_id(struct nouveau_volt *volt, u8 id, int condition) -{ - int ret = nouveau_volt_map(volt, id); - if (ret >= 0) { - int prev = nouveau_volt_get(volt); - if (!condition || prev < 0 || - (condition < 0 && ret < prev) || - (condition > 0 && ret > prev)) { - ret = nouveau_volt_set(volt, ret); - } else { - ret = 0; - } - } - return ret; -} - -int -_nouveau_volt_init(struct nouveau_object *object) -{ - struct nouveau_volt *volt = (void *)object; - int ret; - - ret = nouveau_subdev_init(&volt->base); - if (ret) - return ret; - - ret = volt->get(volt); - if (ret < 0) { - if (ret != -ENODEV) - nv_debug(volt, "current voltage unknown\n"); - return 0; - } - - nv_info(volt, "GPU voltage: %duv\n", ret); - return 0; -} - -void -_nouveau_volt_dtor(struct nouveau_object *object) -{ - struct nouveau_volt *volt = (void *)object; - nouveau_subdev_destroy(&volt->base); -} - -int -nouveau_volt_create_(struct nouveau_object *parent, - struct nouveau_object *engine, - struct nouveau_oclass *oclass, int length, void **pobject) -{ - struct nouveau_bios *bios = nouveau_bios(parent); - struct nouveau_volt *volt; - struct nvbios_volt_entry ivid; - struct nvbios_volt info; - u8 ver, hdr, cnt, len; - u16 data; - int ret, i; - - ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT", - "voltage", length, pobject); - volt = *pobject; - if (ret) - return ret; - - volt->get = nouveau_volt_get; - volt->set = nouveau_volt_set; - volt->set_id = nouveau_volt_set_id; - - data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info); - if (data && info.vidmask && info.base && info.step) { - for (i = 0; i < info.vidmask + 1; i++) { - if (info.base >= info.min && - info.base <= info.max) { - volt->vid[volt->vid_nr].uv = info.base; - volt->vid[volt->vid_nr].vid = i; - volt->vid_nr++; - } - info.base += info.step; - } - volt->vid_mask = info.vidmask; - } else - if (data && info.vidmask) { - for (i = 0; i < cnt; i++) { - data = nvbios_volt_entry_parse(bios, i, &ver, &hdr, - &ivid); - if (data) { - volt->vid[volt->vid_nr].uv = ivid.voltage; - volt->vid[volt->vid_nr].vid = ivid.vid; - volt->vid_nr++; - } - } - volt->vid_mask = info.vidmask; - } - - if (volt->vid_nr) { - for (i = 0; i < volt->vid_nr; i++) { - nv_debug(volt, "VID %02x: %duv\n", - volt->vid[i].vid, volt->vid[i].uv); - } - - /*XXX: this is an assumption.. there probably exists boards - * out there with i2c-connected voltage controllers too.. - */ - ret = nouveau_voltgpio_init(volt); - if (ret == 0) { - volt->vid_get = nouveau_voltgpio_get; - volt->vid_set = nouveau_voltgpio_set; - } - } - - return ret; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c b/drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c deleted file mode 100644 index 755fa91..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/volt/gpio.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - * 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 <subdev/volt.h> -#include <subdev/gpio.h> -#include <subdev/bios/gpio.h> - -static const u8 tags[] = { - DCB_GPIO_VID0, DCB_GPIO_VID1, DCB_GPIO_VID2, DCB_GPIO_VID3, - DCB_GPIO_VID4, DCB_GPIO_VID5, DCB_GPIO_VID6, DCB_GPIO_VID7, -}; - -int -nouveau_voltgpio_get(struct nouveau_volt *volt) -{ - struct nouveau_gpio *gpio = nouveau_gpio(volt); - u8 vid = 0; - int i; - - for (i = 0; i < ARRAY_SIZE(tags); i++) { - if (volt->vid_mask & (1 << i)) { - int ret = gpio->get(gpio, 0, tags[i], 0xff); - if (ret < 0) - return ret; - vid |= ret << i; - } - } - - return vid; -} - -int -nouveau_voltgpio_set(struct nouveau_volt *volt, u8 vid) -{ - struct nouveau_gpio *gpio = nouveau_gpio(volt); - int i; - - for (i = 0; i < ARRAY_SIZE(tags); i++, vid >>= 1) { - if (volt->vid_mask & (1 << i)) { - int ret = gpio->set(gpio, 0, tags[i], 0xff, vid & 1); - if (ret < 0) - return ret; - } - } - - return 0; -} - -int -nouveau_voltgpio_init(struct nouveau_volt *volt) -{ - struct nouveau_gpio *gpio = nouveau_gpio(volt); - struct dcb_gpio_func func; - int i; - - /* check we have gpio function info for each vid bit. on some - * boards (ie. nvs295) the vid mask has more bits than there - * are valid gpio functions... from traces, nvidia appear to - * just touch the existing ones, so let's mask off the invalid - * bits and continue with life - */ - for (i = 0; i < ARRAY_SIZE(tags); i++) { - if (volt->vid_mask & (1 << i)) { - int ret = gpio->find(gpio, 0, tags[i], 0xff, &func); - if (ret) { - if (ret != -ENOENT) - return ret; - nv_debug(volt, "VID bit %d has no GPIO\n", i); - volt->vid_mask &= ~(1 << i); - } - } - } - - return 0; -} diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c b/drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c deleted file mode 100644 index 87d5358..0000000 --- a/drivers/gpu/drm/nouveau/core/subdev/volt/nv40.c +++ /dev/null @@ -1,56 +0,0 @@ -/* - * 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 <subdev/volt.h> - -struct nv40_volt_priv { - struct nouveau_volt base; -}; - -static int -nv40_volt_ctor(struct nouveau_object *parent, struct nouveau_object *engine, - struct nouveau_oclass *oclass, void *data, u32 size, - struct nouveau_object **pobject) -{ - struct nv40_volt_priv *priv; - int ret; - - ret = nouveau_volt_create(parent, engine, oclass, &priv); - *pobject = nv_object(priv); - if (ret) - return ret; - - return 0; -} - -struct nouveau_oclass -nv40_volt_oclass = { - .handle = NV_SUBDEV(VOLT, 0x40), - .ofuncs = &(struct nouveau_ofuncs) { - .ctor = nv40_volt_ctor, - .dtor = _nouveau_volt_dtor, - .init = _nouveau_volt_init, - .fini = _nouveau_volt_fini, - }, -}; diff --git a/drivers/gpu/drm/nouveau/dispnv04/Makefile b/drivers/gpu/drm/nouveau/dispnv04/Makefile index 424a489..ea3f5b8 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/Makefile +++ b/drivers/gpu/drm/nouveau/dispnv04/Makefile @@ -5,7 +5,6 @@ nouveau-y += dispnv04/dac.o nouveau-y += dispnv04/dfp.o nouveau-y += dispnv04/disp.o nouveau-y += dispnv04/hw.o -nouveau-y += dispnv04/overlay.o nouveau-y += dispnv04/tvmodesnv17.o nouveau-y += dispnv04/tvnv04.o nouveau-y += dispnv04/tvnv17.o diff --git a/drivers/gpu/drm/nouveau/dispnv04/arb.c b/drivers/gpu/drm/nouveau/dispnv04/arb.c index 2a15b98..2e70462 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/arb.c +++ b/drivers/gpu/drm/nouveau/dispnv04/arb.c @@ -210,8 +210,8 @@ nv04_update_arb(struct drm_device *dev, int VClk, int bpp, sim_data.nvclk_khz = NVClk; sim_data.bpp = bpp; sim_data.two_heads = nv_two_heads(dev); - if ((dev->pdev->device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ || - (dev->pdev->device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) { + if ((dev->pci_device & 0xffff) == 0x01a0 /*CHIPSET_NFORCE*/ || + (dev->pci_device & 0xffff) == 0x01f0 /*CHIPSET_NFORCE2*/) { uint32_t type; pci_read_config_dword(pci_get_bus_and_slot(0, 1), 0x7c, &type); @@ -256,8 +256,8 @@ nouveau_calc_arb(struct drm_device *dev, int vclk, int bpp, int *burst, int *lwm if (nv_device(drm->device)->card_type < NV_20) nv04_update_arb(dev, vclk, bpp, burst, lwm); - else if ((dev->pdev->device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ || - (dev->pdev->device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) { + else if ((dev->pci_device & 0xfff0) == 0x0240 /*CHIPSET_C51*/ || + (dev->pci_device & 0xfff0) == 0x03d0 /*CHIPSET_C512*/) { *burst = 128; *lwm = 0x0480; } else diff --git a/drivers/gpu/drm/nouveau/dispnv04/crtc.c b/drivers/gpu/drm/nouveau/dispnv04/crtc.c index 0e3270c..d4fbf11 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/crtc.c +++ b/drivers/gpu/drm/nouveau/dispnv04/crtc.c @@ -326,6 +326,8 @@ nv_crtc_mode_set_vga(struct drm_crtc *crtc, struct drm_display_mode *mode) regp->MiscOutReg = 0x23; /* +hsync +vsync */ } + regp->MiscOutReg |= (mode->clock_index & 0x03) << 2; + /* * Time Sequencer */ diff --git a/drivers/gpu/drm/nouveau/dispnv04/dfp.c b/drivers/gpu/drm/nouveau/dispnv04/dfp.c index 936a71c..93dd23ff 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/dfp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/dfp.c @@ -490,10 +490,10 @@ static void nv04_dfp_update_backlight(struct drm_encoder *encoder, int mode) /* BIOS scripts usually take care of the backlight, thanks * Apple for your consistency. */ - if (dev->pdev->device == 0x0174 || dev->pdev->device == 0x0179 || - dev->pdev->device == 0x0189 || dev->pdev->device == 0x0329) { + if (dev->pci_device == 0x0174 || dev->pci_device == 0x0179 || + dev->pci_device == 0x0189 || dev->pci_device == 0x0329) { if (mode == DRM_MODE_DPMS_ON) { - nv_mask(device, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 1 << 31); + nv_mask(device, NV_PBUS_DEBUG_DUALHEAD_CTL, 0, 1 << 31); nv_mask(device, NV_PCRTC_GPIO_EXT, 3, 1); } else { nv_mask(device, NV_PBUS_DEBUG_DUALHEAD_CTL, 1 << 31, 0); @@ -625,15 +625,13 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_i2c *i2c = nouveau_i2c(drm->device); struct nouveau_i2c_port *port = i2c->find(i2c, 2); - struct nouveau_i2c_board_info info[] = { + struct i2c_board_info info[] = { { - { - .type = "sil164", - .addr = (dcb->tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38), - .platform_data = &(struct sil164_encoder_params) { - SIL164_INPUT_EDGE_RISING - } - }, 0 + .type = "sil164", + .addr = (dcb->tmdsconf.slave_addr == 0x7 ? 0x3a : 0x38), + .platform_data = &(struct sil164_encoder_params) { + SIL164_INPUT_EDGE_RISING + } }, { } }; @@ -648,7 +646,7 @@ static void nv04_tmds_slave_init(struct drm_encoder *encoder) return; drm_i2c_encoder_init(dev, to_encoder_slave(encoder), - &port->adapter, &info[type].dev); + &port->adapter, &info[type]); } static const struct drm_encoder_helper_funcs nv04_lvds_helper_funcs = { diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.c b/drivers/gpu/drm/nouveau/dispnv04/disp.c index b13ff0f..4908d3f 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.c +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.c @@ -140,8 +140,6 @@ nv04_display_create(struct drm_device *dev) func->save(encoder); } - nouveau_overlay_init(dev); - return 0; } diff --git a/drivers/gpu/drm/nouveau/dispnv04/disp.h b/drivers/gpu/drm/nouveau/dispnv04/disp.h index 56a28db..9928187 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/disp.h +++ b/drivers/gpu/drm/nouveau/dispnv04/disp.h @@ -123,14 +123,11 @@ int nv04_tv_create(struct drm_connector *, struct dcb_output *); /* nv17_tv.c */ int nv17_tv_create(struct drm_connector *, struct dcb_output *); -/* overlay.c */ -void nouveau_overlay_init(struct drm_device *dev); - static inline bool nv_two_heads(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - const int impl = dev->pdev->device & 0x0ff0; + const int impl = dev->pci_device & 0x0ff0; if (nv_device(drm->device)->card_type >= NV_10 && impl != 0x0100 && impl != 0x0150 && impl != 0x01a0 && impl != 0x0200) @@ -142,14 +139,14 @@ nv_two_heads(struct drm_device *dev) static inline bool nv_gf4_disp_arch(struct drm_device *dev) { - return nv_two_heads(dev) && (dev->pdev->device & 0x0ff0) != 0x0110; + return nv_two_heads(dev) && (dev->pci_device & 0x0ff0) != 0x0110; } static inline bool nv_two_reg_pll(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - const int impl = dev->pdev->device & 0x0ff0; + const int impl = dev->pci_device & 0x0ff0; if (impl == 0x0310 || impl == 0x0340 || nv_device(drm->device)->card_type >= NV_40) return true; diff --git a/drivers/gpu/drm/nouveau/dispnv04/hw.c b/drivers/gpu/drm/nouveau/dispnv04/hw.c index aca76af..973056b 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/hw.c +++ b/drivers/gpu/drm/nouveau/dispnv04/hw.c @@ -27,7 +27,6 @@ #include "hw.h" #include <subdev/bios/pll.h> -#include <subdev/fb.h> #include <subdev/clock.h> #include <subdev/timer.h> @@ -221,7 +220,7 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype) int ret; if (plltype == PLL_MEMORY && - (dev->pdev->device & 0x0ff0) == CHIPSET_NFORCE) { + (dev->pci_device & 0x0ff0) == CHIPSET_NFORCE) { uint32_t mpllP; pci_read_config_dword(pci_get_bus_and_slot(0, 3), 0x6c, &mpllP); @@ -231,7 +230,7 @@ nouveau_hw_get_clock(struct drm_device *dev, enum nvbios_pll_type plltype) return 400000 / mpllP; } else if (plltype == PLL_MEMORY && - (dev->pdev->device & 0xff0) == CHIPSET_NFORCE2) { + (dev->pci_device & 0xff0) == CHIPSET_NFORCE2) { uint32_t clock; pci_read_config_dword(pci_get_bus_and_slot(0, 5), 0x4c, &clock); @@ -665,7 +664,6 @@ nv_load_state_ext(struct drm_device *dev, int head, struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_device *device = nv_device(drm->device); struct nouveau_timer *ptimer = nouveau_timer(device); - struct nouveau_fb *pfb = nouveau_fb(device); struct nv04_crtc_reg *regp = &state->crtc_reg[head]; uint32_t reg900; int i; @@ -682,10 +680,10 @@ nv_load_state_ext(struct drm_device *dev, int head, nv_wr32(device, NV_PVIDEO_INTR_EN, 0); nv_wr32(device, NV_PVIDEO_OFFSET_BUFF(0), 0); nv_wr32(device, NV_PVIDEO_OFFSET_BUFF(1), 0); - nv_wr32(device, NV_PVIDEO_LIMIT(0), pfb->ram->size - 1); - nv_wr32(device, NV_PVIDEO_LIMIT(1), pfb->ram->size - 1); - nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(0), pfb->ram->size - 1); - nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(1), pfb->ram->size - 1); + nv_wr32(device, NV_PVIDEO_LIMIT(0), 0); //drm->fb_available_size - 1); + nv_wr32(device, NV_PVIDEO_LIMIT(1), 0); //drm->fb_available_size - 1); + nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(0), 0); //drm->fb_available_size - 1); + nv_wr32(device, NV_PVIDEO_UVPLANE_LIMIT(1), 0); //drm->fb_available_size - 1); nv_wr32(device, NV_PBUS_POWERCTRL_2, 0); NVWriteCRTC(dev, head, NV_PCRTC_CURSOR_CONFIG, regp->cursor_cfg); @@ -742,7 +740,7 @@ nv_load_state_ext(struct drm_device *dev, int head, } /* NV11 and NV20 stop at 0x52. */ if (nv_gf4_disp_arch(dev)) { - if (nv_device(drm->device)->card_type < NV_20) { + if (nv_device(drm->device)->card_type == NV_10) { /* Not waiting for vertical retrace before modifying CRE_53/CRE_54 causes lockups. */ nouveau_timer_wait_eq(ptimer, 650000000, NV_PRMCIO_INP0__COLOR, 0x8, 0x8); diff --git a/drivers/gpu/drm/nouveau/dispnv04/overlay.c b/drivers/gpu/drm/nouveau/dispnv04/overlay.c deleted file mode 100644 index 32e7064..0000000 --- a/drivers/gpu/drm/nouveau/dispnv04/overlay.c +++ /dev/null @@ -1,340 +0,0 @@ -/* - * Copyright 2013 Ilia Mirkin - * - * 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 AUTHORS 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. - * - * Implementation based on the pre-KMS implementation in xf86-video-nouveau, - * written by Arthur Huillet. - */ - -#include <drm/drmP.h> -#include <drm/drm_crtc.h> -#include <drm/drm_fourcc.h> - -#include "nouveau_drm.h" - -#include "nouveau_bo.h" -#include "nouveau_connector.h" -#include "nouveau_display.h" -#include "nvreg.h" - - -struct nouveau_plane { - struct drm_plane base; - bool flip; - struct nouveau_bo *cur; - - struct { - struct drm_property *colorkey; - struct drm_property *contrast; - struct drm_property *brightness; - struct drm_property *hue; - struct drm_property *saturation; - struct drm_property *iturbt_709; - } props; - - int colorkey; - int contrast; - int brightness; - int hue; - int saturation; - int iturbt_709; -}; - -static uint32_t formats[] = { - DRM_FORMAT_UYVY, - DRM_FORMAT_NV12, -}; - -/* Sine can be approximated with - * http://en.wikipedia.org/wiki/Bhaskara_I's_sine_approximation_formula - * sin(x degrees) ~= 4 x (180 - x) / (40500 - x (180 - x) ) - * Note that this only works for the range [0, 180]. - * Also note that sin(x) == -sin(x - 180) - */ -static inline int -sin_mul(int degrees, int factor) -{ - if (degrees > 180) { - degrees -= 180; - factor *= -1; - } - return factor * 4 * degrees * (180 - degrees) / - (40500 - degrees * (180 - degrees)); -} - -/* cos(x) = sin(x + 90) */ -static inline int -cos_mul(int degrees, int factor) -{ - return sin_mul((degrees + 90) % 360, factor); -} - -static int -nv10_update_plane(struct drm_plane *plane, struct drm_crtc *crtc, - struct drm_framebuffer *fb, int crtc_x, int crtc_y, - unsigned int crtc_w, unsigned int crtc_h, - uint32_t src_x, uint32_t src_y, - uint32_t src_w, uint32_t src_h) -{ - struct nouveau_device *dev = nouveau_dev(plane->dev); - struct nouveau_plane *nv_plane = (struct nouveau_plane *)plane; - struct nouveau_framebuffer *nv_fb = nouveau_framebuffer(fb); - struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - struct nouveau_bo *cur = nv_plane->cur; - bool flip = nv_plane->flip; - int soff = NV_PCRTC0_SIZE * nv_crtc->index; - int soff2 = NV_PCRTC0_SIZE * !nv_crtc->index; - int format, ret; - - /* Source parameters given in 16.16 fixed point, ignore fractional. */ - src_x >>= 16; - src_y >>= 16; - src_w >>= 16; - src_h >>= 16; - - format = ALIGN(src_w * 4, 0x100); - - if (format > 0xffff) - return -ERANGE; - - if (dev->chipset >= 0x30) { - if (crtc_w < (src_w >> 1) || crtc_h < (src_h >> 1)) - return -ERANGE; - } else { - if (crtc_w < (src_w >> 3) || crtc_h < (src_h >> 3)) - return -ERANGE; - } - - ret = nouveau_bo_pin(nv_fb->nvbo, TTM_PL_FLAG_VRAM); - if (ret) - return ret; - - nv_plane->cur = nv_fb->nvbo; - - nv_mask(dev, NV_PCRTC_ENGINE_CTRL + soff, NV_CRTC_FSEL_OVERLAY, NV_CRTC_FSEL_OVERLAY); - nv_mask(dev, NV_PCRTC_ENGINE_CTRL + soff2, NV_CRTC_FSEL_OVERLAY, 0); - - nv_wr32(dev, NV_PVIDEO_BASE(flip), 0); - nv_wr32(dev, NV_PVIDEO_OFFSET_BUFF(flip), nv_fb->nvbo->bo.offset); - nv_wr32(dev, NV_PVIDEO_SIZE_IN(flip), src_h << 16 | src_w); - nv_wr32(dev, NV_PVIDEO_POINT_IN(flip), src_y << 16 | src_x); - nv_wr32(dev, NV_PVIDEO_DS_DX(flip), (src_w << 20) / crtc_w); - nv_wr32(dev, NV_PVIDEO_DT_DY(flip), (src_h << 20) / crtc_h); - nv_wr32(dev, NV_PVIDEO_POINT_OUT(flip), crtc_y << 16 | crtc_x); - nv_wr32(dev, NV_PVIDEO_SIZE_OUT(flip), crtc_h << 16 | crtc_w); - - if (fb->pixel_format == DRM_FORMAT_NV12) { - format |= NV_PVIDEO_FORMAT_COLOR_LE_CR8YB8CB8YA8; - format |= NV_PVIDEO_FORMAT_PLANAR; - } - if (nv_plane->iturbt_709) - format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709; - if (nv_plane->colorkey & (1 << 24)) - format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; - - if (fb->pixel_format == DRM_FORMAT_NV12) { - nv_wr32(dev, NV_PVIDEO_UVPLANE_BASE(flip), 0); - nv_wr32(dev, NV_PVIDEO_UVPLANE_OFFSET_BUFF(flip), - nv_fb->nvbo->bo.offset + fb->offsets[1]); - } - nv_wr32(dev, NV_PVIDEO_FORMAT(flip), format); - nv_wr32(dev, NV_PVIDEO_STOP, 0); - /* TODO: wait for vblank? */ - nv_wr32(dev, NV_PVIDEO_BUFFER, flip ? 0x10 : 0x1); - nv_plane->flip = !flip; - - if (cur) - nouveau_bo_unpin(cur); - - return 0; -} - -static int -nv10_disable_plane(struct drm_plane *plane) -{ - struct nouveau_device *dev = nouveau_dev(plane->dev); - struct nouveau_plane *nv_plane = (struct nouveau_plane *)plane; - - nv_wr32(dev, NV_PVIDEO_STOP, 1); - if (nv_plane->cur) { - nouveau_bo_unpin(nv_plane->cur); - nv_plane->cur = NULL; - } - - return 0; -} - -static void -nv10_destroy_plane(struct drm_plane *plane) -{ - nv10_disable_plane(plane); - drm_plane_cleanup(plane); - kfree(plane); -} - -static void -nv10_set_params(struct nouveau_plane *plane) -{ - struct nouveau_device *dev = nouveau_dev(plane->base.dev); - u32 luma = (plane->brightness - 512) << 16 | plane->contrast; - u32 chroma = ((sin_mul(plane->hue, plane->saturation) & 0xffff) << 16) | - (cos_mul(plane->hue, plane->saturation) & 0xffff); - u32 format = 0; - - nv_wr32(dev, NV_PVIDEO_LUMINANCE(0), luma); - nv_wr32(dev, NV_PVIDEO_LUMINANCE(1), luma); - nv_wr32(dev, NV_PVIDEO_CHROMINANCE(0), chroma); - nv_wr32(dev, NV_PVIDEO_CHROMINANCE(1), chroma); - nv_wr32(dev, NV_PVIDEO_COLOR_KEY, plane->colorkey & 0xffffff); - - if (plane->cur) { - if (plane->iturbt_709) - format |= NV_PVIDEO_FORMAT_MATRIX_ITURBT709; - if (plane->colorkey & (1 << 24)) - format |= NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY; - nv_mask(dev, NV_PVIDEO_FORMAT(plane->flip), - NV_PVIDEO_FORMAT_MATRIX_ITURBT709 | - NV_PVIDEO_FORMAT_DISPLAY_COLOR_KEY, - format); - } -} - -static int -nv10_set_property(struct drm_plane *plane, - struct drm_property *property, - uint64_t value) -{ - struct nouveau_plane *nv_plane = (struct nouveau_plane *)plane; - - if (property == nv_plane->props.colorkey) - nv_plane->colorkey = value; - else if (property == nv_plane->props.contrast) - nv_plane->contrast = value; - else if (property == nv_plane->props.brightness) - nv_plane->brightness = value; - else if (property == nv_plane->props.hue) - nv_plane->hue = value; - else if (property == nv_plane->props.saturation) - nv_plane->saturation = value; - else if (property == nv_plane->props.iturbt_709) - nv_plane->iturbt_709 = value; - else - return -EINVAL; - - nv10_set_params(nv_plane); - return 0; -} - -static const struct drm_plane_funcs nv10_plane_funcs = { - .update_plane = nv10_update_plane, - .disable_plane = nv10_disable_plane, - .set_property = nv10_set_property, - .destroy = nv10_destroy_plane, -}; - -static void -nv10_overlay_init(struct drm_device *device) -{ - struct nouveau_device *dev = nouveau_dev(device); - struct nouveau_plane *plane = kzalloc(sizeof(struct nouveau_plane), GFP_KERNEL); - int num_formats = ARRAY_SIZE(formats); - int ret; - - if (!plane) - return; - - switch (dev->chipset) { - case 0x10: - case 0x11: - case 0x15: - case 0x1a: - case 0x20: - num_formats = 1; - break; - } - - ret = drm_plane_init(device, &plane->base, 3 /* both crtc's */, - &nv10_plane_funcs, - formats, num_formats, false); - if (ret) - goto err; - - /* Set up the plane properties */ - plane->props.colorkey = drm_property_create_range( - device, 0, "colorkey", 0, 0x01ffffff); - plane->props.contrast = drm_property_create_range( - device, 0, "contrast", 0, 8192 - 1); - plane->props.brightness = drm_property_create_range( - device, 0, "brightness", 0, 1024); - plane->props.hue = drm_property_create_range( - device, 0, "hue", 0, 359); - plane->props.saturation = drm_property_create_range( - device, 0, "saturation", 0, 8192 - 1); - plane->props.iturbt_709 = drm_property_create_range( - device, 0, "iturbt_709", 0, 1); - if (!plane->props.colorkey || - !plane->props.contrast || - !plane->props.brightness || - !plane->props.hue || - !plane->props.saturation || - !plane->props.iturbt_709) - goto cleanup; - - plane->colorkey = 0; - drm_object_attach_property(&plane->base.base, - plane->props.colorkey, plane->colorkey); - - plane->contrast = 0x1000; - drm_object_attach_property(&plane->base.base, - plane->props.contrast, plane->contrast); - - plane->brightness = 512; - drm_object_attach_property(&plane->base.base, - plane->props.brightness, plane->brightness); - - plane->hue = 0; - drm_object_attach_property(&plane->base.base, - plane->props.hue, plane->hue); - - plane->saturation = 0x1000; - drm_object_attach_property(&plane->base.base, - plane->props.saturation, plane->saturation); - - plane->iturbt_709 = 0; - drm_object_attach_property(&plane->base.base, - plane->props.iturbt_709, plane->iturbt_709); - - nv10_set_params(plane); - nv_wr32(dev, NV_PVIDEO_STOP, 1); - return; -cleanup: - drm_plane_cleanup(&plane->base); -err: - kfree(plane); - nv_error(dev, "Failed to create plane\n"); -} - -void -nouveau_overlay_init(struct drm_device *device) -{ - struct nouveau_device *dev = nouveau_dev(device); - if (dev->chipset >= 0x10 && dev->chipset <= 0x40) - nv10_overlay_init(device); -} diff --git a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c index cc4b208..bf13db4 100644 --- a/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c +++ b/drivers/gpu/drm/nouveau/dispnv04/tvnv04.c @@ -37,18 +37,15 @@ #include <subdev/i2c.h> -static struct nouveau_i2c_board_info nv04_tv_encoder_info[] = { +static struct i2c_board_info nv04_tv_encoder_info[] = { { - { - I2C_BOARD_INFO("ch7006", 0x75), - .platform_data = &(struct ch7006_encoder_params) { - CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, - 0, 0, 0, - CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, - CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC - } - }, - 0 + I2C_BOARD_INFO("ch7006", 0x75), + .platform_data = &(struct ch7006_encoder_params) { + CH7006_FORMAT_RGB24m12I, CH7006_CLOCK_MASTER, + 0, 0, 0, + CH7006_SYNC_SLAVE, CH7006_SYNC_SEPARATED, + CH7006_POUT_3_3V, CH7006_ACTIVE_HSYNC + } }, { } }; @@ -232,8 +229,7 @@ nv04_tv_create(struct drm_connector *connector, struct dcb_output *entry) /* Run the slave-specific initialization */ ret = drm_i2c_encoder_init(dev, to_encoder_slave(encoder), - &port->adapter, - &nv04_tv_encoder_info[type].dev); + &port->adapter, &nv04_tv_encoder_info[type]); if (ret < 0) goto fail_cleanup; diff --git a/drivers/gpu/drm/nouveau/nouveau_abi16.c b/drivers/gpu/drm/nouveau/nouveau_abi16.c index 6828d81..8f467e7 100644 --- a/drivers/gpu/drm/nouveau/nouveau_abi16.c +++ b/drivers/gpu/drm/nouveau/nouveau_abi16.c @@ -87,7 +87,6 @@ nouveau_abi16_swclass(struct nouveau_drm *drm) case NV_04: return 0x006e; case NV_10: - case NV_11: case NV_20: case NV_30: case NV_40: @@ -131,7 +130,7 @@ nouveau_abi16_chan_fini(struct nouveau_abi16 *abi16, if (chan->ntfy) { nouveau_bo_vma_del(chan->ntfy, &chan->ntfy_vma); nouveau_bo_unpin(chan->ntfy); - drm_gem_object_unreference_unlocked(&chan->ntfy->gem); + drm_gem_object_unreference_unlocked(chan->ntfy->gem); } if (chan->heap.block_size) @@ -179,10 +178,10 @@ nouveau_abi16_ioctl_getparam(ABI16_IOCTL_ARGS) getparam->value = device->chipset; break; case NOUVEAU_GETPARAM_PCI_VENDOR: - getparam->value = dev->pdev->vendor; + getparam->value = dev->pci_vendor; break; case NOUVEAU_GETPARAM_PCI_DEVICE: - getparam->value = dev->pdev->device; + getparam->value = dev->pci_device; break; case NOUVEAU_GETPARAM_BUS_TYPE: if (drm_pci_device_is_agp(dev)) @@ -298,7 +297,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) else init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; - if (device->card_type < NV_10) { + if (device->card_type < NV_C0) { init->subchan[0].handle = 0x00000000; init->subchan[0].grclass = 0x0000; init->subchan[1].handle = NvSw; @@ -321,7 +320,7 @@ nouveau_abi16_ioctl_channel_alloc(ABI16_IOCTL_ARGS) goto done; } - ret = drm_gem_handle_create(file_priv, &chan->ntfy->gem, + ret = drm_gem_handle_create(file_priv, chan->ntfy->gem, &init->notifier_handle); if (ret) goto done; diff --git a/drivers/gpu/drm/nouveau/nouveau_acpi.c b/drivers/gpu/drm/nouveau/nouveau_acpi.c index 95c7404..dd7d2e1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_acpi.c +++ b/drivers/gpu/drm/nouveau/nouveau_acpi.c @@ -253,15 +253,18 @@ static struct vga_switcheroo_handler nouveau_dsm_handler = { static int nouveau_dsm_pci_probe(struct pci_dev *pdev) { - acpi_handle dhandle; + acpi_handle dhandle, nvidia_handle; + acpi_status status; int retval = 0; - dhandle = ACPI_HANDLE(&pdev->dev); + dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); if (!dhandle) return false; - if (!acpi_has_method(dhandle, "_DSM")) + status = acpi_get_handle(dhandle, "_DSM", &nvidia_handle); + if (ACPI_FAILURE(status)) { return false; + } if (nouveau_test_dsm(dhandle, nouveau_dsm, NOUVEAU_DSM_POWER)) retval |= NOUVEAU_DSM_HAS_MUX; @@ -314,16 +317,6 @@ static bool nouveau_dsm_detect(void) has_optimus = 1; } - while ((pdev = pci_get_class(PCI_CLASS_DISPLAY_3D << 8, pdev)) != NULL) { - vga_count++; - - retval = nouveau_dsm_pci_probe(pdev); - if (retval & NOUVEAU_DSM_HAS_MUX) - has_dsm |= 1; - if (retval & NOUVEAU_DSM_HAS_OPT) - has_optimus = 1; - } - /* find the optimus DSM or the old v1 DSM */ if (has_optimus == 1) { acpi_get_name(nouveau_dsm_priv.dhandle, ACPI_FULL_PATHNAME, @@ -414,7 +407,7 @@ bool nouveau_acpi_rom_supported(struct pci_dev *pdev) if (!nouveau_dsm_priv.dsm_detected && !nouveau_dsm_priv.optimus_detected) return false; - dhandle = ACPI_HANDLE(&pdev->dev); + dhandle = DEVICE_ACPI_HANDLE(&pdev->dev); if (!dhandle) return false; @@ -448,7 +441,7 @@ nouveau_acpi_edid(struct drm_device *dev, struct drm_connector *connector) return NULL; } - handle = ACPI_HANDLE(&dev->pdev->dev); + handle = DEVICE_ACPI_HANDLE(&dev->pdev->dev); if (!handle) return NULL; diff --git a/drivers/gpu/drm/nouveau/nouveau_agp.c b/drivers/gpu/drm/nouveau/nouveau_agp.c index 2953c4e..6e7a55f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_agp.c +++ b/drivers/gpu/drm/nouveau/nouveau_agp.c @@ -11,28 +11,10 @@ MODULE_PARM_DESC(agpmode, "AGP mode (0 to disable AGP)"); static int nouveau_agpmode = -1; module_param_named(agpmode, nouveau_agpmode, int, 0400); -struct nouveau_agpmode_quirk { - u16 hostbridge_vendor; - u16 hostbridge_device; - u16 chip_vendor; - u16 chip_device; - int mode; -}; - -static struct nouveau_agpmode_quirk nouveau_agpmode_quirk_list[] = { - /* VIA Apollo PRO133x / GeForce FX 5600 Ultra, max agpmode 2, fdo #20341 */ - { PCI_VENDOR_ID_VIA, 0x0691, PCI_VENDOR_ID_NVIDIA, 0x0311, 2 }, - - {}, -}; - static unsigned long -get_agp_mode(struct nouveau_drm *drm, const struct drm_agp_info *info) +get_agp_mode(struct nouveau_drm *drm, unsigned long mode) { struct nouveau_device *device = nv_device(drm->device); - struct nouveau_agpmode_quirk *quirk = nouveau_agpmode_quirk_list; - int agpmode = nouveau_agpmode; - unsigned long mode = info->mode; /* * FW seems to be broken on nv18, it makes the card lock up @@ -42,27 +24,11 @@ get_agp_mode(struct nouveau_drm *drm, const struct drm_agp_info *info) mode &= ~PCI_AGP_COMMAND_FW; /* - * Go through the quirks list and adjust the agpmode accordingly. - */ - while (agpmode == -1 && quirk->hostbridge_vendor) { - if (info->id_vendor == quirk->hostbridge_vendor && - info->id_device == quirk->hostbridge_device && - device->pdev->vendor == quirk->chip_vendor && - device->pdev->device == quirk->chip_device) { - agpmode = quirk->mode; - nv_info(device, "Forcing agp mode to %dX. Use agpmode to override.\n", - agpmode); - break; - } - ++quirk; - } - - /* * AGP mode set in the command line. */ - if (agpmode > 0) { + if (nouveau_agpmode > 0) { bool agpv3 = mode & 0x8; - int rate = agpv3 ? agpmode / 4 : agpmode; + int rate = agpv3 ? nouveau_agpmode / 4 : nouveau_agpmode; mode = (mode & ~0x7) | (rate & 0x7); } @@ -124,7 +90,7 @@ nouveau_agp_reset(struct nouveau_drm *drm) if (ret) return; - mode.mode = get_agp_mode(drm, &info); + mode.mode = get_agp_mode(drm, info.mode); mode.mode &= ~PCI_AGP_COMMAND_FW; ret = drm_agp_enable(dev, mode); @@ -173,7 +139,7 @@ nouveau_agp_init(struct nouveau_drm *drm) } /* see agp.h for the AGPSTAT_* modes available */ - mode.mode = get_agp_mode(drm, &info); + mode.mode = get_agp_mode(drm, info.mode); ret = drm_agp_enable(dev, mode); if (ret) { diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 630f6e8..2ffad21 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c @@ -82,7 +82,7 @@ nv40_backlight_init(struct drm_connector *connector) memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = 31; - bd = backlight_device_register("nv_backlight", connector->kdev, drm, + bd = backlight_device_register("nv_backlight", &connector->kdev, drm, &nv40_bl_ops, &props); if (IS_ERR(bd)) return PTR_ERR(bd); @@ -204,7 +204,7 @@ nv50_backlight_init(struct drm_connector *connector) memset(&props, 0, sizeof(struct backlight_properties)); props.type = BACKLIGHT_RAW; props.max_brightness = 100; - bd = backlight_device_register("nv_backlight", connector->kdev, + bd = backlight_device_register("nv_backlight", &connector->kdev, nv_encoder, ops, &props); if (IS_ERR(bd)) return PTR_ERR(bd); diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 4c3feaa..3e72876 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c @@ -127,8 +127,8 @@ static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_outp #ifdef __powerpc__ /* Powerbook specific quirks */ if (script == LVDS_RESET && - (dev->pdev->device == 0x0179 || dev->pdev->device == 0x0189 || - dev->pdev->device == 0x0329)) + (dev->pci_device == 0x0179 || dev->pci_device == 0x0189 || + dev->pci_device == 0x0329)) nv_write_tmds(dev, dcbent->or, 0, 0x02, 0x72); #endif diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index c0fde6b..755c38d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c @@ -98,7 +98,12 @@ nv10_bo_put_tile_region(struct drm_device *dev, struct nouveau_drm_tile *tile, if (tile) { spin_lock(&drm->tile.lock); - tile->fence = nouveau_fence_ref(fence); + if (fence) { + /* Mark it as pending. */ + tile->fence = fence; + nouveau_fence_ref(fence); + } + tile->used = false; spin_unlock(&drm->tile.lock); } @@ -141,7 +146,7 @@ nouveau_bo_del_ttm(struct ttm_buffer_object *bo) struct drm_device *dev = drm->dev; struct nouveau_bo *nvbo = nouveau_bo(bo); - if (unlikely(nvbo->gem.filp)) + if (unlikely(nvbo->gem)) DRM_ERROR("bo %p still attached to GEM object\n", bo); WARN_ON(nvbo->pin_refcnt > 0); nv10_bo_put_tile_region(dev, nvbo->tile, NULL); @@ -264,8 +269,7 @@ set_placement_range(struct nouveau_bo *nvbo, uint32_t type) struct nouveau_fb *pfb = nouveau_fb(drm->device); u32 vram_pages = pfb->ram->size >> PAGE_SHIFT; - if ((nv_device(drm->device)->card_type == NV_10 || - nv_device(drm->device)->card_type == NV_11) && + if (nv_device(drm->device)->card_type == NV_10 && nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM) && nvbo->bo.mem.num_pages < vram_pages / 4) { /* @@ -978,7 +982,7 @@ nouveau_bo_move_m2mf(struct ttm_buffer_object *bo, int evict, bool intr, bool no_wait_gpu, struct ttm_mem_reg *new_mem) { struct nouveau_drm *drm = nouveau_bdev(bo->bdev); - struct nouveau_channel *chan = drm->ttm.chan; + struct nouveau_channel *chan = chan = drm->ttm.chan; struct nouveau_bo *nvbo = nouveau_bo(bo); struct ttm_mem_reg *old_mem = &bo->mem; int ret; @@ -1263,7 +1267,7 @@ nouveau_bo_verify_access(struct ttm_buffer_object *bo, struct file *filp) { struct nouveau_bo *nvbo = nouveau_bo(bo); - return drm_vma_node_verify_access(&nvbo->gem.vma_node, filp); + return drm_vma_node_verify_access(&nvbo->gem->vma_node, filp); } static int @@ -1457,12 +1461,14 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) void nouveau_bo_fence(struct nouveau_bo *nvbo, struct nouveau_fence *fence) { - struct nouveau_fence *new_fence = nouveau_fence_ref(fence); struct nouveau_fence *old_fence = NULL; + if (likely(fence)) + nouveau_fence_ref(fence); + spin_lock(&nvbo->bo.bdev->fence_lock); old_fence = nvbo->bo.sync_obj; - nvbo->bo.sync_obj = new_fence; + nvbo->bo.sync_obj = fence; spin_unlock(&nvbo->bo.bdev->fence_lock); nouveau_fence_unref(&old_fence); @@ -1545,8 +1551,7 @@ nouveau_bo_vma_add(struct nouveau_bo *nvbo, struct nouveau_vm *vm, if (nvbo->bo.mem.mem_type == TTM_PL_VRAM) nouveau_vm_map(vma, nvbo->bo.mem.mm_node); - else if (nvbo->bo.mem.mem_type == TTM_PL_TT && - nvbo->page_shift == vma->vm->vmm->spg_shift) { + else if (nvbo->bo.mem.mem_type == TTM_PL_TT) { if (node->sg) nouveau_vm_map_sg_table(vma, 0, size, node); else diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h b/drivers/gpu/drm/nouveau/nouveau_bo.h index ff17c1f..653dbbb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.h +++ b/drivers/gpu/drm/nouveau/nouveau_bo.h @@ -27,10 +27,7 @@ struct nouveau_bo { u32 tile_flags; struct nouveau_drm_tile *tile; - /* Only valid if allocated via nouveau_gem_new() and iff you hold a - * gem reference to it! For debugging, use gem.filp != NULL to test - * whether it is valid. */ - struct drm_gem_object gem; + struct drm_gem_object *gem; /* protect by the ttm reservation lock */ int pin_refcnt; diff --git a/drivers/gpu/drm/nouveau/nouveau_chan.c b/drivers/gpu/drm/nouveau/nouveau_chan.c index cc5152b..e84f4c3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_chan.c +++ b/drivers/gpu/drm/nouveau/nouveau_chan.c @@ -346,17 +346,22 @@ nouveau_channel_init(struct nouveau_channel *chan, u32 vram, u32 gart) for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) OUT_RING(chan, 0x00000000); - /* allocate software object class (used for fences on <= nv05) */ - if (device->card_type < NV_10) { + /* allocate software object class (used for fences on <= nv05, and + * to signal flip completion), bind it to a subchannel. + */ + if ((device->card_type < NV_E0) || gart /* nve0: want_nvsw */) { ret = nouveau_object_new(nv_object(client), chan->handle, - NvSw, 0x006e, NULL, 0, &object); + NvSw, nouveau_abi16_swclass(chan->drm), + NULL, 0, &object); if (ret) return ret; swch = (void *)object->parent; swch->flip = nouveau_flip_complete; swch->flip_data = chan; + } + if (device->card_type < NV_C0) { ret = RING_SPACE(chan, 2); if (ret) return ret; diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 1674882..c5b36f9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c @@ -100,7 +100,6 @@ static void nouveau_connector_destroy(struct drm_connector *connector) { struct nouveau_connector *nv_connector = nouveau_connector(connector); - nouveau_event_ref(NULL, &nv_connector->hpd_func); kfree(nv_connector->edid); drm_sysfs_connector_remove(connector); drm_connector_cleanup(connector); @@ -215,10 +214,9 @@ nouveau_connector_set_encoder(struct drm_connector *connector, } else { connector->doublescan_allowed = true; if (nv_device(drm->device)->card_type == NV_20 || - ((nv_device(drm->device)->card_type == NV_10 || - nv_device(drm->device)->card_type == NV_11) && - (dev->pdev->device & 0x0ff0) != 0x0100 && - (dev->pdev->device & 0x0ff0) != 0x0150)) + (nv_device(drm->device)->card_type == NV_10 && + (dev->pci_device & 0x0ff0) != 0x0100 && + (dev->pci_device & 0x0ff0) != 0x0150)) /* HW is broken */ connector->interlace_allowed = false; else @@ -934,9 +932,10 @@ nouveau_connector_hotplug_work(struct work_struct *work) } static int -nouveau_connector_hotplug(void *data, int index) +nouveau_connector_hotplug(struct nouveau_eventh *event, int index) { - struct nouveau_connector *nv_connector = data; + struct nouveau_connector *nv_connector = + container_of(event, struct nouveau_connector, hpd_func); schedule_work(&nv_connector->hpd_work); return NVKM_EVENT_KEEP; } @@ -1008,16 +1007,10 @@ nouveau_connector_create(struct drm_device *dev, int index) ret = gpio->find(gpio, 0, hpd[ffs((entry & 0x07033000) >> 12)], DCB_GPIO_UNUSED, &nv_connector->hpd); + nv_connector->hpd_func.func = nouveau_connector_hotplug; if (ret) nv_connector->hpd.func = DCB_GPIO_UNUSED; - if (nv_connector->hpd.func != DCB_GPIO_UNUSED) { - nouveau_event_new(gpio->events, nv_connector->hpd.line, - nouveau_connector_hotplug, - nv_connector, - &nv_connector->hpd_func); - } - nv_connector->type = nv_connector->dcb[0]; if (drm_conntype_from_dcb(nv_connector->type) == DRM_MODE_CONNECTOR_Unknown) { diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index 264a778..6e399aa 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h @@ -69,7 +69,7 @@ struct nouveau_connector { struct dcb_gpio_func hpd; struct work_struct hpd_work; - struct nouveau_eventh *hpd_func; + struct nouveau_eventh hpd_func; int dithering_mode; int dithering_depth; @@ -107,4 +107,7 @@ nouveau_crtc_connector_get(struct nouveau_crtc *nv_crtc) struct drm_connector * nouveau_connector_create(struct drm_device *, int index); +int +nouveau_connector_bpp(struct drm_connector *); + #endif /* __NOUVEAU_CONNECTOR_H__ */ diff --git a/drivers/gpu/drm/nouveau/nouveau_display.c b/drivers/gpu/drm/nouveau/nouveau_display.c index 29c3efd..7848590 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.c +++ b/drivers/gpu/drm/nouveau/nouveau_display.c @@ -26,6 +26,7 @@ #include <drm/drmP.h> #include <drm/drm_crtc_helper.h> +#include <drm/ttm/ttm_execbuf_util.h> #include "nouveau_fbcon.h" #include "dispnv04/hw.h" @@ -37,92 +38,19 @@ #include "nouveau_fence.h" +#include <subdev/bios/gpio.h> +#include <subdev/gpio.h> #include <engine/disp.h> #include <core/class.h> -static int -nouveau_display_vblank_handler(void *data, int head) -{ - struct nouveau_drm *drm = data; - drm_handle_vblank(drm->dev, head); - return NVKM_EVENT_KEEP; -} - -int -nouveau_display_vblank_enable(struct drm_device *dev, int head) -{ - struct nouveau_display *disp = nouveau_display(dev); - if (disp) { - nouveau_event_get(disp->vblank[head]); - return 0; - } - return -EIO; -} - -void -nouveau_display_vblank_disable(struct drm_device *dev, int head) -{ - struct nouveau_display *disp = nouveau_display(dev); - if (disp) - nouveau_event_put(disp->vblank[head]); -} - -static void -nouveau_display_vblank_fini(struct drm_device *dev) -{ - struct nouveau_display *disp = nouveau_display(dev); - int i; - - if (disp->vblank) { - for (i = 0; i < dev->mode_config.num_crtc; i++) - nouveau_event_ref(NULL, &disp->vblank[i]); - kfree(disp->vblank); - disp->vblank = NULL; - } - - drm_vblank_cleanup(dev); -} - -static int -nouveau_display_vblank_init(struct drm_device *dev) -{ - struct nouveau_display *disp = nouveau_display(dev); - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_disp *pdisp = nouveau_disp(drm->device); - int ret, i; - - disp->vblank = kzalloc(dev->mode_config.num_crtc * - sizeof(*disp->vblank), GFP_KERNEL); - if (!disp->vblank) - return -ENOMEM; - - for (i = 0; i < dev->mode_config.num_crtc; i++) { - ret = nouveau_event_new(pdisp->vblank, i, - nouveau_display_vblank_handler, - drm, &disp->vblank[i]); - if (ret) { - nouveau_display_vblank_fini(dev); - return ret; - } - } - - ret = drm_vblank_init(dev, dev->mode_config.num_crtc); - if (ret) { - nouveau_display_vblank_fini(dev); - return ret; - } - - return 0; -} - static void nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb) { struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); if (fb->nvbo) - drm_gem_object_unreference_unlocked(&fb->nvbo->gem); + drm_gem_object_unreference_unlocked(fb->nvbo->gem); drm_framebuffer_cleanup(drm_fb); kfree(fb); @@ -135,7 +63,7 @@ nouveau_user_framebuffer_create_handle(struct drm_framebuffer *drm_fb, { struct nouveau_framebuffer *fb = nouveau_framebuffer(drm_fb); - return drm_gem_handle_create(file_priv, &fb->nvbo->gem, handle); + return drm_gem_handle_create(file_priv, fb->nvbo->gem, handle); } static const struct drm_framebuffer_funcs nouveau_framebuffer_funcs = { @@ -299,7 +227,9 @@ static struct nouveau_drm_prop_enum_list dither_depth[] = { int nouveau_display_init(struct drm_device *dev) { + struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_display *disp = nouveau_display(dev); + struct nouveau_gpio *gpio = nouveau_gpio(drm->device); struct drm_connector *connector; int ret; @@ -313,7 +243,10 @@ nouveau_display_init(struct drm_device *dev) /* enable hotplug interrupts */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct nouveau_connector *conn = nouveau_connector(connector); - if (conn->hpd_func) nouveau_event_get(conn->hpd_func); + if (gpio && conn->hpd.func != DCB_GPIO_UNUSED) { + nouveau_event_get(gpio->events, conn->hpd.line, + &conn->hpd_func); + } } return ret; @@ -322,13 +255,18 @@ nouveau_display_init(struct drm_device *dev) void nouveau_display_fini(struct drm_device *dev) { + struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_display *disp = nouveau_display(dev); + struct nouveau_gpio *gpio = nouveau_gpio(drm->device); struct drm_connector *connector; /* disable hotplug interrupts */ list_for_each_entry(connector, &dev->mode_config.connector_list, head) { struct nouveau_connector *conn = nouveau_connector(connector); - if (conn->hpd_func) nouveau_event_put(conn->hpd_func); + if (gpio && conn->hpd.func != DCB_GPIO_UNUSED) { + nouveau_event_put(gpio->events, conn->hpd.line, + &conn->hpd_func); + } } drm_kms_helper_poll_disable(dev); @@ -398,11 +336,6 @@ nouveau_display_create(struct drm_device *dev) dev->mode_config.preferred_depth = 24; dev->mode_config.prefer_shadow = 1; - if (nv_device(drm->device)->chipset < 0x11) - dev->mode_config.async_page_flip = false; - else - dev->mode_config.async_page_flip = true; - drm_kms_helper_poll_init(dev); drm_kms_helper_poll_disable(dev); @@ -419,7 +352,7 @@ nouveau_display_create(struct drm_device *dev) goto disp_create_err; if (dev->mode_config.num_crtc) { - ret = nouveau_display_vblank_init(dev); + ret = drm_vblank_init(dev, dev->mode_config.num_crtc); if (ret) goto vblank_err; } @@ -441,7 +374,7 @@ nouveau_display_destroy(struct drm_device *dev) struct nouveau_display *disp = nouveau_display(dev); nouveau_backlight_exit(dev); - nouveau_display_vblank_fini(dev); + drm_vblank_cleanup(dev); drm_kms_helper_poll_fini(dev); drm_mode_config_cleanup(dev); @@ -461,7 +394,7 @@ nouveau_display_suspend(struct drm_device *dev) nouveau_display_fini(dev); - NV_INFO(drm, "unpinning framebuffer(s)...\n"); + NV_SUSPEND(drm, "unpinning framebuffer(s)...\n"); list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) { struct nouveau_framebuffer *nouveau_fb; @@ -559,15 +492,19 @@ nouveau_page_flip_emit(struct nouveau_channel *chan, goto fail; /* Emit the pageflip */ - ret = RING_SPACE(chan, 2); + ret = RING_SPACE(chan, 3); if (ret) goto fail; - if (nv_device(drm->device)->card_type < NV_C0) + if (nv_device(drm->device)->card_type < NV_C0) { BEGIN_NV04(chan, NvSubSw, NV_SW_PAGE_FLIP, 1); - else - BEGIN_NVC0(chan, FermiSw, NV_SW_PAGE_FLIP, 1); - OUT_RING (chan, 0x00000000); + OUT_RING (chan, 0x00000000); + OUT_RING (chan, 0x00000000); + } else { + BEGIN_NVC0(chan, 0, NV10_SUBCHAN_REF_CNT, 1); + OUT_RING (chan, 0); + BEGIN_IMC0(chan, 0, NVSW_SUBCHAN_PAGE_FLIP, 0x0000); + } FIRE_RING (chan); ret = nouveau_fence_new(chan, false, pfence); @@ -584,16 +521,22 @@ fail: int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event, u32 flags) + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) { - const int swap_interval = (flags & DRM_MODE_PAGE_FLIP_ASYNC) ? 0 : 1; struct drm_device *dev = crtc->dev; struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_bo *old_bo = nouveau_framebuffer(crtc->fb)->nvbo; struct nouveau_bo *new_bo = nouveau_framebuffer(fb)->nvbo; struct nouveau_page_flip_state *s; - struct nouveau_channel *chan = drm->channel; + struct nouveau_channel *chan = NULL; struct nouveau_fence *fence; + struct ttm_validate_buffer resv[2] = { + { .bo = &old_bo->bo }, + { .bo = &new_bo->bo }, + }; + struct ww_acquire_ctx ticket; + LIST_HEAD(res); int ret; if (!drm->channel) @@ -603,23 +546,26 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, if (!s) return -ENOMEM; - /* synchronise rendering channel with the kernel's channel */ - spin_lock(&new_bo->bo.bdev->fence_lock); - fence = nouveau_fence_ref(new_bo->bo.sync_obj); - spin_unlock(&new_bo->bo.bdev->fence_lock); - ret = nouveau_fence_sync(fence, chan); - nouveau_fence_unref(&fence); - if (ret) - return ret; + /* Choose the channel the flip will be handled in */ + spin_lock(&old_bo->bo.bdev->fence_lock); + fence = new_bo->bo.sync_obj; + if (fence) + chan = fence->channel; + if (!chan) + chan = drm->channel; + spin_unlock(&old_bo->bo.bdev->fence_lock); if (new_bo != old_bo) { ret = nouveau_bo_pin(new_bo, TTM_PL_FLAG_VRAM); if (ret) goto fail_free; + + list_add(&resv[1].head, &res); } + list_add(&resv[0].head, &res); mutex_lock(&chan->cli->mutex); - ret = ttm_bo_reserve(&old_bo->bo, true, false, false, NULL); + ret = ttm_eu_reserve_buffers(&ticket, &res); if (ret) goto fail_unpin; @@ -631,29 +577,12 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, /* Emit a page flip */ if (nv_device(drm->device)->card_type >= NV_50) { - ret = nv50_display_flip_next(crtc, fb, chan, swap_interval); + ret = nv50_display_flip_next(crtc, fb, chan, 0); if (ret) goto fail_unreserve; } else { struct nv04_display *dispnv04 = nv04_display(dev); - int head = nouveau_crtc(crtc)->index; - - if (swap_interval) { - ret = RING_SPACE(chan, 8); - if (ret) - goto fail_unreserve; - - BEGIN_NV04(chan, NvSubImageBlit, 0x012c, 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NvSubImageBlit, 0x0134, 1); - OUT_RING (chan, head); - BEGIN_NV04(chan, NvSubImageBlit, 0x0100, 1); - OUT_RING (chan, 0); - BEGIN_NV04(chan, NvSubImageBlit, 0x0130, 1); - OUT_RING (chan, 0); - } - - nouveau_bo_ref(new_bo, &dispnv04->image[head]); + nouveau_bo_ref(new_bo, &dispnv04->image[nouveau_crtc(crtc)->index]); } ret = nouveau_page_flip_emit(chan, old_bo, new_bo, s, &fence); @@ -664,15 +593,14 @@ nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, /* Update the crtc struct and cleanup */ crtc->fb = fb; - nouveau_bo_fence(old_bo, fence); - ttm_bo_unreserve(&old_bo->bo); + ttm_eu_fence_buffer_objects(&ticket, &res, fence); if (old_bo != new_bo) nouveau_bo_unpin(old_bo); nouveau_fence_unref(&fence); return 0; fail_unreserve: - ttm_bo_unreserve(&old_bo->bo); + ttm_eu_backoff_reservation(&ticket, &res); fail_unpin: mutex_unlock(&chan->cli->mutex); if (old_bo != new_bo) @@ -702,7 +630,7 @@ nouveau_finish_page_flip(struct nouveau_channel *chan, s = list_first_entry(&fctx->flip, struct nouveau_page_flip_state, head); if (s->event) - drm_send_vblank_event(dev, s->crtc, s->event); + drm_send_vblank_event(dev, -1, s->event); list_del(&s->head); if (ps) @@ -746,8 +674,8 @@ nouveau_display_dumb_create(struct drm_file *file_priv, struct drm_device *dev, if (ret) return ret; - ret = drm_gem_handle_create(file_priv, &bo->gem, &args->handle); - drm_gem_object_unreference_unlocked(&bo->gem); + ret = drm_gem_handle_create(file_priv, bo->gem, &args->handle); + drm_gem_object_unreference_unlocked(bo->gem); return ret; } @@ -760,7 +688,7 @@ nouveau_display_dumb_map_offset(struct drm_file *file_priv, gem = drm_gem_object_lookup(dev, file_priv, handle); if (gem) { - struct nouveau_bo *bo = nouveau_gem_object(gem); + struct nouveau_bo *bo = gem->driver_private; *poffset = drm_vma_node_offset_addr(&bo->bo.vma_node); drm_gem_object_unreference_unlocked(gem); return 0; diff --git a/drivers/gpu/drm/nouveau/nouveau_display.h b/drivers/gpu/drm/nouveau/nouveau_display.h index 8bc8bab..025c66f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_display.h +++ b/drivers/gpu/drm/nouveau/nouveau_display.h @@ -36,8 +36,6 @@ struct nouveau_display { int (*init)(struct drm_device *); void (*fini)(struct drm_device *); - struct nouveau_eventh **vblank; - struct drm_property *dithering_mode; struct drm_property *dithering_depth; struct drm_property *underscan_property; @@ -61,8 +59,6 @@ void nouveau_display_fini(struct drm_device *dev); int nouveau_display_suspend(struct drm_device *dev); void nouveau_display_repin(struct drm_device *dev); void nouveau_display_resume(struct drm_device *dev); -int nouveau_display_vblank_enable(struct drm_device *, int); -void nouveau_display_vblank_disable(struct drm_device *, int); int nouveau_crtc_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, struct drm_pending_vblank_event *event, diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index 984004d..690d593 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h @@ -51,11 +51,9 @@ enum { NvSubCtxSurf2D = 0, NvSubSw = 1, NvSubImageBlit = 2, + NvSub2D = 3, NvSubGdiRect = 3, - - NvSub2D = 3, /* DO NOT CHANGE - hardcoded for kepler gr fifo */ - NvSubCopy = 4, /* DO NOT CHANGE - hardcoded for kepler gr fifo */ - FermiSw = 5, /* DO NOT CHANGE (well.. 6/7 will work...) */ + NvSubCopy = 4, }; /* Object handles. */ @@ -196,6 +194,7 @@ WIND_RING(struct nouveau_channel *chan) #define NV84_SUBCHAN_UEVENT 0x00000020 #define NV84_SUBCHAN_WRCACHE_FLUSH 0x00000024 #define NV10_SUBCHAN_REF_CNT 0x00000050 +#define NVSW_SUBCHAN_PAGE_FLIP 0x00000054 #define NV11_SUBCHAN_DMA_SEMAPHORE 0x00000060 #define NV11_SUBCHAN_SEMAPHORE_OFFSET 0x00000064 #define NV11_SUBCHAN_SEMAPHORE_ACQUIRE 0x00000068 diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.c b/drivers/gpu/drm/nouveau/nouveau_drm.c index 7a3759f..e893c53 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.c +++ b/drivers/gpu/drm/nouveau/nouveau_drm.c @@ -37,7 +37,6 @@ #include <engine/device.h> #include <engine/disp.h> #include <engine/fifo.h> -#include <engine/software.h> #include <subdev/vm.h> @@ -47,8 +46,7 @@ #include "nouveau_gem.h" #include "nouveau_agp.h" #include "nouveau_vga.h" -#include "nouveau_sysfs.h" -#include "nouveau_hwmon.h" +#include "nouveau_pm.h" #include "nouveau_acpi.h" #include "nouveau_bios.h" #include "nouveau_ioctl.h" @@ -80,6 +78,41 @@ module_param_named(runpm, nouveau_runtime_pm, int, 0400); static struct drm_driver driver; +static int +nouveau_drm_vblank_handler(struct nouveau_eventh *event, int head) +{ + struct nouveau_drm *drm = + container_of(event, struct nouveau_drm, vblank[head]); + drm_handle_vblank(drm->dev, head); + return NVKM_EVENT_KEEP; +} + +static int +nouveau_drm_vblank_enable(struct drm_device *dev, int head) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_disp *pdisp = nouveau_disp(drm->device); + + if (WARN_ON_ONCE(head > ARRAY_SIZE(drm->vblank))) + return -EIO; + WARN_ON_ONCE(drm->vblank[head].func); + drm->vblank[head].func = nouveau_drm_vblank_handler; + nouveau_event_get(pdisp->vblank, head, &drm->vblank[head]); + return 0; +} + +static void +nouveau_drm_vblank_disable(struct drm_device *dev, int head) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_disp *pdisp = nouveau_disp(drm->device); + if (drm->vblank[head].func) + nouveau_event_put(pdisp->vblank, head, &drm->vblank[head]); + else + WARN_ON_ONCE(1); + drm->vblank[head].func = NULL; +} + static u64 nouveau_name(struct pci_dev *pdev) { @@ -144,8 +177,7 @@ nouveau_accel_init(struct nouveau_drm *drm) /* initialise synchronisation routines */ if (device->card_type < NV_10) ret = nv04_fence_create(drm); - else if (device->card_type < NV_11 || - device->chipset < 0x17) ret = nv10_fence_create(drm); + else if (device->chipset < 0x17) ret = nv10_fence_create(drm); else if (device->card_type < NV_50) ret = nv17_fence_create(drm); else if (device->chipset < 0x84) ret = nv50_fence_create(drm); else if (device->card_type < NV_C0) ret = nv84_fence_create(drm); @@ -192,32 +224,6 @@ nouveau_accel_init(struct nouveau_drm *drm) return; } - ret = nouveau_object_new(nv_object(drm), NVDRM_CHAN, NVDRM_NVSW, - nouveau_abi16_swclass(drm), NULL, 0, &object); - if (ret == 0) { - struct nouveau_software_chan *swch = (void *)object->parent; - ret = RING_SPACE(drm->channel, 2); - if (ret == 0) { - if (device->card_type < NV_C0) { - BEGIN_NV04(drm->channel, NvSubSw, 0, 1); - OUT_RING (drm->channel, NVDRM_NVSW); - } else - if (device->card_type < NV_E0) { - BEGIN_NVC0(drm->channel, FermiSw, 0, 1); - OUT_RING (drm->channel, 0x001f0000); - } - } - swch = (void *)object->parent; - swch->flip = nouveau_flip_complete; - swch->flip_data = drm->channel; - } - - if (ret) { - NV_ERROR(drm, "failed to allocate software object, %d\n", ret); - nouveau_accel_fini(drm); - return; - } - if (device->card_type < NV_C0) { ret = nouveau_gpuobj_new(drm->device, NULL, 32, 0, 0, &drm->notify); @@ -412,8 +418,8 @@ nouveau_drm_load(struct drm_device *dev, unsigned long flags) goto fail_dispinit; } - nouveau_sysfs_init(dev); - nouveau_hwmon_init(dev); + nouveau_pm_init(dev); + nouveau_accel_init(drm); nouveau_fbcon_init(dev); @@ -449,8 +455,8 @@ nouveau_drm_unload(struct drm_device *dev) pm_runtime_get_sync(dev->dev); nouveau_fbcon_fini(dev); nouveau_accel_fini(drm); - nouveau_hwmon_fini(dev); - nouveau_sysfs_fini(dev); + + nouveau_pm_fini(dev); if (dev->mode_config.num_crtc) nouveau_display_fini(dev); @@ -490,16 +496,16 @@ nouveau_do_suspend(struct drm_device *dev) int ret; if (dev->mode_config.num_crtc) { - NV_INFO(drm, "suspending display...\n"); + NV_SUSPEND(drm, "suspending display...\n"); ret = nouveau_display_suspend(dev); if (ret) return ret; } - NV_INFO(drm, "evicting buffers...\n"); + NV_SUSPEND(drm, "evicting buffers...\n"); ttm_bo_evict_mm(&drm->ttm.bdev, TTM_PL_VRAM); - NV_INFO(drm, "waiting for kernel channels to go idle...\n"); + NV_SUSPEND(drm, "waiting for kernel channels to go idle...\n"); if (drm->cechan) { ret = nouveau_channel_idle(drm->cechan); if (ret) @@ -512,7 +518,7 @@ nouveau_do_suspend(struct drm_device *dev) return ret; } - NV_INFO(drm, "suspending client object trees...\n"); + NV_SUSPEND(drm, "suspending client object trees...\n"); if (drm->fence && nouveau_fence(drm)->suspend) { if (!nouveau_fence(drm)->suspend(drm)) return -ENOMEM; @@ -524,7 +530,7 @@ nouveau_do_suspend(struct drm_device *dev) goto fail_client; } - NV_INFO(drm, "suspending kernel object tree...\n"); + NV_SUSPEND(drm, "suspending kernel object tree...\n"); ret = nouveau_client_fini(&drm->client.base, true); if (ret) goto fail_client; @@ -538,7 +544,7 @@ fail_client: } if (dev->mode_config.num_crtc) { - NV_INFO(drm, "resuming display...\n"); + NV_SUSPEND(drm, "resuming display...\n"); nouveau_display_resume(dev); } return ret; @@ -557,6 +563,7 @@ int nouveau_pmops_suspend(struct device *dev) if (drm_dev->mode_config.num_crtc) nouveau_fbcon_set_suspend(drm_dev, 1); + nv_suspend_set_printk_level(NV_DBG_INFO); ret = nouveau_do_suspend(drm_dev); if (ret) return ret; @@ -564,6 +571,8 @@ int nouveau_pmops_suspend(struct device *dev) pci_save_state(pdev); pci_disable_device(pdev); pci_set_power_state(pdev, PCI_D3hot); + nv_suspend_set_printk_level(NV_DBG_DEBUG); + return 0; } @@ -573,15 +582,15 @@ nouveau_do_resume(struct drm_device *dev) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_cli *cli; - NV_INFO(drm, "re-enabling device...\n"); + NV_SUSPEND(drm, "re-enabling device...\n"); nouveau_agp_reset(drm); - NV_INFO(drm, "resuming kernel object tree...\n"); + NV_SUSPEND(drm, "resuming kernel object tree...\n"); nouveau_client_init(&drm->client.base); nouveau_agp_init(drm); - NV_INFO(drm, "resuming client object trees...\n"); + NV_SUSPEND(drm, "resuming client object trees...\n"); if (drm->fence && nouveau_fence(drm)->resume) nouveau_fence(drm)->resume(drm); @@ -590,9 +599,10 @@ nouveau_do_resume(struct drm_device *dev) } nouveau_run_vbios_init(dev); + nouveau_pm_resume(dev); if (dev->mode_config.num_crtc) { - NV_INFO(drm, "resuming display...\n"); + NV_SUSPEND(drm, "resuming display...\n"); nouveau_display_repin(dev); } @@ -616,15 +626,19 @@ int nouveau_pmops_resume(struct device *dev) return ret; pci_set_master(pdev); + nv_suspend_set_printk_level(NV_DBG_INFO); ret = nouveau_do_resume(drm_dev); - if (ret) + if (ret) { + nv_suspend_set_printk_level(NV_DBG_DEBUG); return ret; + } if (drm_dev->mode_config.num_crtc) nouveau_fbcon_set_suspend(drm_dev, 0); nouveau_fbcon_zfill_all(drm_dev); if (drm_dev->mode_config.num_crtc) nouveau_display_resume(drm_dev); + nv_suspend_set_printk_level(NV_DBG_DEBUG); return 0; } @@ -634,10 +648,12 @@ static int nouveau_pmops_freeze(struct device *dev) struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; + nv_suspend_set_printk_level(NV_DBG_INFO); if (drm_dev->mode_config.num_crtc) nouveau_fbcon_set_suspend(drm_dev, 1); ret = nouveau_do_suspend(drm_dev); + nv_suspend_set_printk_level(NV_DBG_DEBUG); return ret; } @@ -647,14 +663,18 @@ static int nouveau_pmops_thaw(struct device *dev) struct drm_device *drm_dev = pci_get_drvdata(pdev); int ret; + nv_suspend_set_printk_level(NV_DBG_INFO); ret = nouveau_do_resume(drm_dev); - if (ret) + if (ret) { + nv_suspend_set_printk_level(NV_DBG_DEBUG); return ret; + } if (drm_dev->mode_config.num_crtc) nouveau_fbcon_set_suspend(drm_dev, 0); nouveau_fbcon_zfill_all(drm_dev); if (drm_dev->mode_config.num_crtc) nouveau_display_resume(drm_dev); + nv_suspend_set_printk_level(NV_DBG_DEBUG); return 0; } @@ -796,8 +816,8 @@ driver = { #endif .get_vblank_counter = drm_vblank_count, - .enable_vblank = nouveau_display_vblank_enable, - .disable_vblank = nouveau_display_vblank_disable, + .enable_vblank = nouveau_drm_vblank_enable, + .disable_vblank = nouveau_drm_vblank_disable, .ioctls = nouveau_ioctls, .num_ioctls = ARRAY_SIZE(nouveau_ioctls), @@ -814,6 +834,7 @@ driver = { .gem_prime_vmap = nouveau_gem_prime_vmap, .gem_prime_vunmap = nouveau_gem_prime_vunmap, + .gem_init_object = nouveau_gem_object_new, .gem_free_object = nouveau_gem_object_del, .gem_open_object = nouveau_gem_object_open, .gem_close_object = nouveau_gem_object_close, @@ -858,7 +879,6 @@ static int nouveau_pmops_runtime_suspend(struct device *dev) if (nouveau_runtime_pm == 0) return -EINVAL; - nv_debug_level(SILENT); drm_kms_helper_poll_disable(drm_dev); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_OFF); nouveau_switcheroo_optimus_dsm(); @@ -895,7 +915,6 @@ static int nouveau_pmops_runtime_resume(struct device *dev) nv_mask(device, 0x88488, (1 << 25), (1 << 25)); vga_switcheroo_set_dynamic_switch(pdev, VGA_SWITCHEROO_ON); drm_dev->switch_power_state = DRM_SWITCH_POWER_ON; - nv_debug_level(NORMAL); return ret; } diff --git a/drivers/gpu/drm/nouveau/nouveau_drm.h b/drivers/gpu/drm/nouveau/nouveau_drm.h index 4b0fb6c..994fd6e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drm.h +++ b/drivers/gpu/drm/nouveau/nouveau_drm.h @@ -51,12 +51,10 @@ struct nouveau_drm_tile { }; enum nouveau_drm_handle { - NVDRM_CLIENT = 0xffffffff, - NVDRM_DEVICE = 0xdddddddd, - NVDRM_CONTROL = 0xdddddddc, - NVDRM_PUSH = 0xbbbb0000, /* |= client chid */ - NVDRM_CHAN = 0xcccc0000, /* |= client chid */ - NVDRM_NVSW = 0x55550000, + NVDRM_CLIENT = 0xffffffff, + NVDRM_DEVICE = 0xdddddddd, + NVDRM_PUSH = 0xbbbb0000, /* |= client chid */ + NVDRM_CHAN = 0xcccc0000, /* |= client chid */ }; struct nouveau_cli { @@ -129,10 +127,10 @@ struct nouveau_drm { struct nvbios vbios; struct nouveau_display *display; struct backlight_device *backlight; + struct nouveau_eventh vblank[4]; /* power management */ - struct nouveau_hwmon *hwmon; - struct nouveau_sysfs *sysfs; + struct nouveau_pm *pm; /* display power reference */ bool have_disp_power_ref; @@ -156,6 +154,7 @@ nouveau_dev(struct drm_device *dev) int nouveau_pmops_suspend(struct device *); int nouveau_pmops_resume(struct device *); +#define NV_SUSPEND(cli, fmt, args...) nv_suspend((cli), fmt, ##args) #define NV_FATAL(cli, fmt, args...) nv_fatal((cli), fmt, ##args) #define NV_ERROR(cli, fmt, args...) nv_error((cli), fmt, ##args) #define NV_WARN(cli, fmt, args...) nv_warn((cli), fmt, ##args) diff --git a/drivers/gpu/drm/nouveau/nouveau_fbcon.c b/drivers/gpu/drm/nouveau/nouveau_fbcon.c index 7903e0e..a86ecf6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fbcon.c +++ b/drivers/gpu/drm/nouveau/nouveau_fbcon.c @@ -420,7 +420,7 @@ nouveau_fbcon_destroy(struct drm_device *dev, struct nouveau_fbdev *fbcon) nouveau_bo_unmap(nouveau_fb->nvbo); nouveau_bo_vma_del(nouveau_fb->nvbo, &nouveau_fb->vma); nouveau_bo_unpin(nouveau_fb->nvbo); - drm_gem_object_unreference_unlocked(&nouveau_fb->nvbo->gem); + drm_gem_object_unreference_unlocked(nouveau_fb->nvbo->gem); nouveau_fb->nvbo = NULL; } drm_fb_helper_fini(&fbcon->helper); @@ -503,45 +503,34 @@ nouveau_fbcon_fini(struct drm_device *dev) drm->fbcon = NULL; } -void -nouveau_fbcon_save_disable_accel(struct drm_device *dev) +void nouveau_fbcon_save_disable_accel(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { - drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags; - drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; - } + + drm->fbcon->saved_flags = drm->fbcon->helper.fbdev->flags; + drm->fbcon->helper.fbdev->flags |= FBINFO_HWACCEL_DISABLED; } -void -nouveau_fbcon_restore_accel(struct drm_device *dev) +void nouveau_fbcon_restore_accel(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { - drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags; - } + drm->fbcon->helper.fbdev->flags = drm->fbcon->saved_flags; } -void -nouveau_fbcon_set_suspend(struct drm_device *dev, int state) +void nouveau_fbcon_set_suspend(struct drm_device *dev, int state) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { - console_lock(); - if (state == 0) - nouveau_fbcon_save_disable_accel(dev); - fb_set_suspend(drm->fbcon->helper.fbdev, state); - if (state == 1) - nouveau_fbcon_restore_accel(dev); - console_unlock(); - } + console_lock(); + if (state == 0) + nouveau_fbcon_save_disable_accel(dev); + fb_set_suspend(drm->fbcon->helper.fbdev, state); + if (state == 1) + nouveau_fbcon_restore_accel(dev); + console_unlock(); } -void -nouveau_fbcon_zfill_all(struct drm_device *dev) +void nouveau_fbcon_zfill_all(struct drm_device *dev) { struct nouveau_drm *drm = nouveau_drm(dev); - if (drm->fbcon) { - nouveau_fbcon_zfill(dev, drm->fbcon); - } + nouveau_fbcon_zfill(dev, drm->fbcon); } diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 40cf52e..be31499 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c @@ -165,11 +165,17 @@ nouveau_fence_done(struct nouveau_fence *fence) return !fence->channel; } +struct nouveau_fence_uevent { + struct nouveau_eventh handler; + struct nouveau_fence_priv *priv; +}; + static int -nouveau_fence_wait_uevent_handler(void *data, int index) +nouveau_fence_wait_uevent_handler(struct nouveau_eventh *event, int index) { - struct nouveau_fence_priv *priv = data; - wake_up_all(&priv->waiting); + struct nouveau_fence_uevent *uevent = + container_of(event, struct nouveau_fence_uevent, handler); + wake_up_all(&uevent->priv->waiting); return NVKM_EVENT_KEEP; } @@ -180,16 +186,13 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) struct nouveau_channel *chan = fence->channel; struct nouveau_fifo *pfifo = nouveau_fifo(chan->drm->device); struct nouveau_fence_priv *priv = chan->drm->fence; - struct nouveau_eventh *handler; + struct nouveau_fence_uevent uevent = { + .handler.func = nouveau_fence_wait_uevent_handler, + .priv = priv, + }; int ret = 0; - ret = nouveau_event_new(pfifo->uevent, 0, - nouveau_fence_wait_uevent_handler, - priv, &handler); - if (ret) - return ret; - - nouveau_event_get(handler); + nouveau_event_get(pfifo->uevent, 0, &uevent.handler); if (fence->timeout) { unsigned long timeout = fence->timeout - jiffies; @@ -221,7 +224,7 @@ nouveau_fence_wait_uevent(struct nouveau_fence *fence, bool intr) } } - nouveau_event_ref(NULL, &handler); + nouveau_event_put(pfifo->uevent, 0, &uevent.handler); if (unlikely(ret < 0)) return ret; @@ -306,8 +309,7 @@ nouveau_fence_unref(struct nouveau_fence **pfence) struct nouveau_fence * nouveau_fence_ref(struct nouveau_fence *fence) { - if (fence) - kref_get(&fence->kref); + kref_get(&fence->kref); return fence; } diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 78a27f8..f32b712 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c @@ -34,20 +34,29 @@ #include "nouveau_ttm.h" #include "nouveau_gem.h" +int +nouveau_gem_object_new(struct drm_gem_object *gem) +{ + return 0; +} + void nouveau_gem_object_del(struct drm_gem_object *gem) { - struct nouveau_bo *nvbo = nouveau_gem_object(gem); + struct nouveau_bo *nvbo = gem->driver_private; struct ttm_buffer_object *bo = &nvbo->bo; + if (!nvbo) + return; + nvbo->gem = NULL; + if (gem->import_attach) drm_prime_gem_destroy(gem, nvbo->bo.sg); - drm_gem_object_release(gem); - - /* reset filp so nouveau_bo_del_ttm() can test for it */ - gem->filp = NULL; ttm_bo_unref(&bo); + + drm_gem_object_release(gem); + kfree(gem); } int @@ -106,7 +115,8 @@ nouveau_gem_object_unmap(struct nouveau_bo *nvbo, struct nouveau_vma *vma) if (mapped) { spin_lock(&nvbo->bo.bdev->fence_lock); - fence = nouveau_fence_ref(nvbo->bo.sync_obj); + if (nvbo->bo.sync_obj) + fence = nouveau_fence_ref(nvbo->bo.sync_obj); spin_unlock(&nvbo->bo.bdev->fence_lock); } @@ -176,15 +186,14 @@ nouveau_gem_new(struct drm_device *dev, int size, int align, uint32_t domain, if (nv_device(drm->device)->card_type >= NV_50) nvbo->valid_domains &= domain; - /* Initialize the embedded gem-object. We return a single gem-reference - * to the caller, instead of a normal nouveau_bo ttm reference. */ - ret = drm_gem_object_init(dev, &nvbo->gem, nvbo->bo.mem.size); - if (ret) { + nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size); + if (!nvbo->gem) { nouveau_bo_ref(NULL, pnvbo); return -ENOMEM; } - nvbo->bo.persistent_swap_storage = nvbo->gem.filp; + nvbo->bo.persistent_swap_storage = nvbo->gem->filp; + nvbo->gem->driver_private = nvbo; return 0; } @@ -241,15 +250,15 @@ nouveau_gem_ioctl_new(struct drm_device *dev, void *data, if (ret) return ret; - ret = drm_gem_handle_create(file_priv, &nvbo->gem, &req->info.handle); + ret = drm_gem_handle_create(file_priv, nvbo->gem, &req->info.handle); if (ret == 0) { - ret = nouveau_gem_info(file_priv, &nvbo->gem, &req->info); + ret = nouveau_gem_info(file_priv, nvbo->gem, &req->info); if (ret) drm_gem_handle_delete(file_priv, req->info.handle); } /* drop reference from allocate - handle holds it now */ - drm_gem_object_unreference_unlocked(&nvbo->gem); + drm_gem_object_unreference_unlocked(nvbo->gem); return ret; } @@ -257,7 +266,7 @@ static int nouveau_gem_set_domain(struct drm_gem_object *gem, uint32_t read_domains, uint32_t write_domains, uint32_t valid_domains) { - struct nouveau_bo *nvbo = nouveau_gem_object(gem); + struct nouveau_bo *nvbo = gem->driver_private; struct ttm_buffer_object *bo = &nvbo->bo; uint32_t domains = valid_domains & nvbo->valid_domains & (write_domains ? write_domains : read_domains); @@ -308,8 +317,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence, list_for_each_safe(entry, tmp, list) { nvbo = list_entry(entry, struct nouveau_bo, entry); - if (likely(fence)) - nouveau_bo_fence(nvbo, fence); + nouveau_bo_fence(nvbo, fence); if (unlikely(nvbo->validate_mapped)) { ttm_bo_kunmap(&nvbo->kmap); @@ -319,7 +327,7 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence, list_del(&nvbo->entry); nvbo->reserved_by = NULL; ttm_bo_unreserve_ticket(&nvbo->bo, ticket); - drm_gem_object_unreference_unlocked(&nvbo->gem); + drm_gem_object_unreference_unlocked(nvbo->gem); } } @@ -368,7 +376,7 @@ retry: validate_fini(op, NULL); return -ENOENT; } - nvbo = nouveau_gem_object(gem); + nvbo = gem->driver_private; if (nvbo == res_bo) { res_bo = NULL; drm_gem_object_unreference_unlocked(gem); @@ -438,7 +446,8 @@ validate_sync(struct nouveau_channel *chan, struct nouveau_bo *nvbo) int ret = 0; spin_lock(&nvbo->bo.bdev->fence_lock); - fence = nouveau_fence_ref(nvbo->bo.sync_obj); + if (nvbo->bo.sync_obj) + fence = nouveau_fence_ref(nvbo->bo.sync_obj); spin_unlock(&nvbo->bo.bdev->fence_lock); if (fence) { @@ -469,7 +478,7 @@ validate_list(struct nouveau_channel *chan, struct nouveau_cli *cli, return ret; } - ret = nouveau_gem_set_domain(&nvbo->gem, b->read_domains, + ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, b->write_domains, b->valid_domains); if (unlikely(ret)) { diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.h b/drivers/gpu/drm/nouveau/nouveau_gem.h index 7caca05..502e429 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.h +++ b/drivers/gpu/drm/nouveau/nouveau_gem.h @@ -12,13 +12,14 @@ static inline struct nouveau_bo * nouveau_gem_object(struct drm_gem_object *gem) { - return gem ? container_of(gem, struct nouveau_bo, gem) : NULL; + return gem ? gem->driver_private : NULL; } /* nouveau_gem.c */ extern int nouveau_gem_new(struct drm_device *, int size, int align, uint32_t domain, uint32_t tile_mode, uint32_t tile_flags, struct nouveau_bo **); +extern int nouveau_gem_object_new(struct drm_gem_object *); extern void nouveau_gem_object_del(struct drm_gem_object *); extern int nouveau_gem_object_open(struct drm_gem_object *, struct drm_file *); extern void nouveau_gem_object_close(struct drm_gem_object *, diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.h b/drivers/gpu/drm/nouveau/nouveau_hwmon.h deleted file mode 100644 index 62ccbb3..0000000 --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright 2010 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 - */ - -#ifndef __NOUVEAU_PM_H__ -#define __NOUVEAU_PM_H__ - -struct nouveau_hwmon { - struct drm_device *dev; - struct device *hwmon; -}; - -static inline struct nouveau_hwmon * -nouveau_hwmon(struct drm_device *dev) -{ - return nouveau_drm(dev)->hwmon; -} - -/* nouveau_hwmon.c */ -int nouveau_hwmon_init(struct drm_device *dev); -void nouveau_hwmon_fini(struct drm_device *dev); - -#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_hwsq.h b/drivers/gpu/drm/nouveau/nouveau_hwsq.h new file mode 100644 index 0000000..6976875 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_hwsq.h @@ -0,0 +1,115 @@ +/* + * Copyright 2010 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 + */ + +#ifndef __NOUVEAU_HWSQ_H__ +#define __NOUVEAU_HWSQ_H__ + +struct hwsq_ucode { + u8 data[0x200]; + union { + u8 *u08; + u16 *u16; + u32 *u32; + } ptr; + u16 len; + + u32 reg; + u32 val; +}; + +static inline void +hwsq_init(struct hwsq_ucode *hwsq) +{ + hwsq->ptr.u08 = hwsq->data; + hwsq->reg = 0xffffffff; + hwsq->val = 0xffffffff; +} + +static inline void +hwsq_fini(struct hwsq_ucode *hwsq) +{ + do { + *hwsq->ptr.u08++ = 0x7f; + hwsq->len = hwsq->ptr.u08 - hwsq->data; + } while (hwsq->len & 3); + hwsq->ptr.u08 = hwsq->data; +} + +static inline void +hwsq_usec(struct hwsq_ucode *hwsq, u8 usec) +{ + u32 shift = 0; + while (usec & ~3) { + usec >>= 2; + shift++; + } + + *hwsq->ptr.u08++ = (shift << 2) | usec; +} + +static inline void +hwsq_setf(struct hwsq_ucode *hwsq, u8 flag, int val) +{ + flag += 0x80; + if (val >= 0) + flag += 0x20; + if (val >= 1) + flag += 0x20; + *hwsq->ptr.u08++ = flag; +} + +static inline void +hwsq_op5f(struct hwsq_ucode *hwsq, u8 v0, u8 v1) +{ + *hwsq->ptr.u08++ = 0x5f; + *hwsq->ptr.u08++ = v0; + *hwsq->ptr.u08++ = v1; +} + +static inline void +hwsq_wr32(struct hwsq_ucode *hwsq, u32 reg, u32 val) +{ + if (val != hwsq->val) { + if ((val & 0xffff0000) == (hwsq->val & 0xffff0000)) { + *hwsq->ptr.u08++ = 0x42; + *hwsq->ptr.u16++ = (val & 0x0000ffff); + } else { + *hwsq->ptr.u08++ = 0xe2; + *hwsq->ptr.u32++ = val; + } + + hwsq->val = val; + } + + if ((reg & 0xffff0000) == (hwsq->reg & 0xffff0000)) { + *hwsq->ptr.u08++ = 0x40; + *hwsq->ptr.u16++ = (reg & 0x0000ffff); + } else { + *hwsq->ptr.u08++ = 0xe0; + *hwsq->ptr.u32++ = reg; + } + hwsq->reg = reg; +} + +#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c new file mode 100644 index 0000000..4f6a572 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c @@ -0,0 +1,647 @@ +/* + * Copyright (C) The Weather Channel, Inc. 2002. All Rights Reserved. + * Copyright 2005 Stephane Marchesin + * + * The Weather Channel (TM) funded Tungsten Graphics to develop the + * initial release of the Radeon 8500 driver under the XFree86 license. + * This notice must be preserved. + * + * 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 (including the next + * paragraph) 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 AUTHORS AND/OR THEIR SUPPLIERS 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> + * Roy Spliet <r.spliet@student.tudelft.nl> + */ + +#include "nouveau_drm.h" +#include "nouveau_pm.h" + +#include <subdev/fb.h> + +static int +nv40_mem_timing_calc(struct drm_device *dev, u32 freq, + struct nouveau_pm_tbl_entry *e, u8 len, + struct nouveau_pm_memtiming *boot, + struct nouveau_pm_memtiming *t) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + + t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC); + + /* XXX: I don't trust the -1's and +1's... they must come + * from somewhere! */ + t->reg[1] = (e->tWR + 2 + (t->tCWL - 1)) << 24 | + 1 << 16 | + (e->tWTR + 2 + (t->tCWL - 1)) << 8 | + (e->tCL + 2 - (t->tCWL - 1)); + + t->reg[2] = 0x20200000 | + ((t->tCWL - 1) << 24 | + e->tRRD << 16 | + e->tRCDWR << 8 | + e->tRCDRD); + + NV_DEBUG(drm, "Entry %d: 220: %08x %08x %08x\n", t->id, + t->reg[0], t->reg[1], t->reg[2]); + return 0; +} + +static int +nv50_mem_timing_calc(struct drm_device *dev, u32 freq, + struct nouveau_pm_tbl_entry *e, u8 len, + struct nouveau_pm_memtiming *boot, + struct nouveau_pm_memtiming *t) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_fb *pfb = nouveau_fb(device); + struct nouveau_drm *drm = nouveau_drm(dev); + struct bit_entry P; + uint8_t unk18 = 1, unk20 = 0, unk21 = 0, tmp7_3; + + if (bit_table(dev, 'P', &P)) + return -EINVAL; + + switch (min(len, (u8) 22)) { + case 22: + unk21 = e->tUNK_21; + case 21: + unk20 = e->tUNK_20; + case 20: + if (e->tCWL > 0) + t->tCWL = e->tCWL; + case 19: + unk18 = e->tUNK_18; + break; + } + + t->reg[0] = (e->tRP << 24 | e->tRAS << 16 | e->tRFC << 8 | e->tRC); + + t->reg[1] = (e->tWR + 2 + (t->tCWL - 1)) << 24 | + max(unk18, (u8) 1) << 16 | + (e->tWTR + 2 + (t->tCWL - 1)) << 8; + + t->reg[2] = ((t->tCWL - 1) << 24 | + e->tRRD << 16 | + e->tRCDWR << 8 | + e->tRCDRD); + + t->reg[4] = e->tUNK_13 << 8 | e->tUNK_13; + + t->reg[5] = (e->tRFC << 24 | max(e->tRCDRD, e->tRCDWR) << 16 | e->tRP); + + t->reg[8] = boot->reg[8] & 0xffffff00; + + if (P.version == 1) { + t->reg[1] |= (e->tCL + 2 - (t->tCWL - 1)); + + t->reg[3] = (0x14 + e->tCL) << 24 | + 0x16 << 16 | + (e->tCL - 1) << 8 | + (e->tCL - 1); + + t->reg[4] |= boot->reg[4] & 0xffff0000; + + t->reg[6] = (0x33 - t->tCWL) << 16 | + t->tCWL << 8 | + (0x2e + e->tCL - t->tCWL); + + t->reg[7] = 0x4000202 | (e->tCL - 1) << 16; + + /* XXX: P.version == 1 only has DDR2 and GDDR3? */ + if (pfb->ram->type == NV_MEM_TYPE_DDR2) { + t->reg[5] |= (e->tCL + 3) << 8; + t->reg[6] |= (t->tCWL - 2) << 8; + t->reg[8] |= (e->tCL - 4); + } else { + t->reg[5] |= (e->tCL + 2) << 8; + t->reg[6] |= t->tCWL << 8; + t->reg[8] |= (e->tCL - 2); + } + } else { + t->reg[1] |= (5 + e->tCL - (t->tCWL)); + + /* XXX: 0xb? 0x30? */ + t->reg[3] = (0x30 + e->tCL) << 24 | + (boot->reg[3] & 0x00ff0000)| + (0xb + e->tCL) << 8 | + (e->tCL - 1); + + t->reg[4] |= (unk20 << 24 | unk21 << 16); + + /* XXX: +6? */ + t->reg[5] |= (t->tCWL + 6) << 8; + + t->reg[6] = (0x5a + e->tCL) << 16 | + (6 - e->tCL + t->tCWL) << 8 | + (0x50 + e->tCL - t->tCWL); + + tmp7_3 = (boot->reg[7] & 0xff000000) >> 24; + t->reg[7] = (tmp7_3 << 24) | + ((tmp7_3 - 6 + e->tCL) << 16) | + 0x202; + } + + NV_DEBUG(drm, "Entry %d: 220: %08x %08x %08x %08x\n", t->id, + t->reg[0], t->reg[1], t->reg[2], t->reg[3]); + NV_DEBUG(drm, " 230: %08x %08x %08x %08x\n", + t->reg[4], t->reg[5], t->reg[6], t->reg[7]); + NV_DEBUG(drm, " 240: %08x\n", t->reg[8]); + return 0; +} + +static int +nvc0_mem_timing_calc(struct drm_device *dev, u32 freq, + struct nouveau_pm_tbl_entry *e, u8 len, + struct nouveau_pm_memtiming *boot, + struct nouveau_pm_memtiming *t) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + + if (e->tCWL > 0) + t->tCWL = e->tCWL; + + t->reg[0] = (e->tRP << 24 | (e->tRAS & 0x7f) << 17 | + e->tRFC << 8 | e->tRC); + + t->reg[1] = (boot->reg[1] & 0xff000000) | + (e->tRCDWR & 0x0f) << 20 | + (e->tRCDRD & 0x0f) << 14 | + (t->tCWL << 7) | + (e->tCL & 0x0f); + + t->reg[2] = (boot->reg[2] & 0xff0000ff) | + e->tWR << 16 | e->tWTR << 8; + + t->reg[3] = (e->tUNK_20 & 0x1f) << 9 | + (e->tUNK_21 & 0xf) << 5 | + (e->tUNK_13 & 0x1f); + + t->reg[4] = (boot->reg[4] & 0xfff00fff) | + (e->tRRD&0x1f) << 15; + + NV_DEBUG(drm, "Entry %d: 290: %08x %08x %08x %08x\n", t->id, + t->reg[0], t->reg[1], t->reg[2], t->reg[3]); + NV_DEBUG(drm, " 2a0: %08x\n", t->reg[4]); + return 0; +} + +/** + * MR generation methods + */ + +static int +nouveau_mem_ddr2_mr(struct drm_device *dev, u32 freq, + struct nouveau_pm_tbl_entry *e, u8 len, + struct nouveau_pm_memtiming *boot, + struct nouveau_pm_memtiming *t) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + + t->drive_strength = 0; + if (len < 15) { + t->odt = boot->odt; + } else { + t->odt = e->RAM_FT1 & 0x07; + } + + if (e->tCL >= NV_MEM_CL_DDR2_MAX) { + NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL); + return -ERANGE; + } + + if (e->tWR >= NV_MEM_WR_DDR2_MAX) { + NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR); + return -ERANGE; + } + + if (t->odt > 3) { + NV_WARN(drm, "(%u) Invalid odt value, assuming disabled: %x", + t->id, t->odt); + t->odt = 0; + } + + t->mr[0] = (boot->mr[0] & 0x100f) | + (e->tCL) << 4 | + (e->tWR - 1) << 9; + t->mr[1] = (boot->mr[1] & 0x101fbb) | + (t->odt & 0x1) << 2 | + (t->odt & 0x2) << 5; + + NV_DEBUG(drm, "(%u) MR: %08x", t->id, t->mr[0]); + return 0; +} + +static const uint8_t nv_mem_wr_lut_ddr3[NV_MEM_WR_DDR3_MAX] = { + 0, 0, 0, 0, 0, 1, 2, 3, 4, 5, 5, 6, 6, 7, 7, 0, 0}; + +static int +nouveau_mem_ddr3_mr(struct drm_device *dev, u32 freq, + struct nouveau_pm_tbl_entry *e, u8 len, + struct nouveau_pm_memtiming *boot, + struct nouveau_pm_memtiming *t) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + u8 cl = e->tCL - 4; + + t->drive_strength = 0; + if (len < 15) { + t->odt = boot->odt; + } else { + t->odt = e->RAM_FT1 & 0x07; + } + + if (e->tCL >= NV_MEM_CL_DDR3_MAX || e->tCL < 4) { + NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL); + return -ERANGE; + } + + if (e->tWR >= NV_MEM_WR_DDR3_MAX || e->tWR < 4) { + NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR); + return -ERANGE; + } + + if (e->tCWL < 5) { + NV_WARN(drm, "(%u) Invalid tCWL: %u", t->id, e->tCWL); + return -ERANGE; + } + + t->mr[0] = (boot->mr[0] & 0x180b) | + /* CAS */ + (cl & 0x7) << 4 | + (cl & 0x8) >> 1 | + (nv_mem_wr_lut_ddr3[e->tWR]) << 9; + t->mr[1] = (boot->mr[1] & 0x101dbb) | + (t->odt & 0x1) << 2 | + (t->odt & 0x2) << 5 | + (t->odt & 0x4) << 7; + t->mr[2] = (boot->mr[2] & 0x20ffb7) | (e->tCWL - 5) << 3; + + NV_DEBUG(drm, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[2]); + return 0; +} + +static const uint8_t nv_mem_cl_lut_gddr3[NV_MEM_CL_GDDR3_MAX] = { + 0, 0, 0, 0, 4, 5, 6, 7, 0, 1, 2, 3, 8, 9, 10, 11}; +static const uint8_t nv_mem_wr_lut_gddr3[NV_MEM_WR_GDDR3_MAX] = { + 0, 0, 0, 0, 0, 2, 3, 8, 9, 10, 11, 0, 0, 1, 1, 0, 3}; + +static int +nouveau_mem_gddr3_mr(struct drm_device *dev, u32 freq, + struct nouveau_pm_tbl_entry *e, u8 len, + struct nouveau_pm_memtiming *boot, + struct nouveau_pm_memtiming *t) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + + if (len < 15) { + t->drive_strength = boot->drive_strength; + t->odt = boot->odt; + } else { + t->drive_strength = (e->RAM_FT1 & 0x30) >> 4; + t->odt = e->RAM_FT1 & 0x07; + } + + if (e->tCL >= NV_MEM_CL_GDDR3_MAX) { + NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL); + return -ERANGE; + } + + if (e->tWR >= NV_MEM_WR_GDDR3_MAX) { + NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR); + return -ERANGE; + } + + if (t->odt > 3) { + NV_WARN(drm, "(%u) Invalid odt value, assuming autocal: %x", + t->id, t->odt); + t->odt = 0; + } + + t->mr[0] = (boot->mr[0] & 0xe0b) | + /* CAS */ + ((nv_mem_cl_lut_gddr3[e->tCL] & 0x7) << 4) | + ((nv_mem_cl_lut_gddr3[e->tCL] & 0x8) >> 2); + t->mr[1] = (boot->mr[1] & 0x100f40) | t->drive_strength | + (t->odt << 2) | + (nv_mem_wr_lut_gddr3[e->tWR] & 0xf) << 4; + t->mr[2] = boot->mr[2]; + + NV_DEBUG(drm, "(%u) MR: %08x %08x %08x", t->id, + t->mr[0], t->mr[1], t->mr[2]); + return 0; +} + +static int +nouveau_mem_gddr5_mr(struct drm_device *dev, u32 freq, + struct nouveau_pm_tbl_entry *e, u8 len, + struct nouveau_pm_memtiming *boot, + struct nouveau_pm_memtiming *t) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + + if (len < 15) { + t->drive_strength = boot->drive_strength; + t->odt = boot->odt; + } else { + t->drive_strength = (e->RAM_FT1 & 0x30) >> 4; + t->odt = e->RAM_FT1 & 0x03; + } + + if (e->tCL >= NV_MEM_CL_GDDR5_MAX) { + NV_WARN(drm, "(%u) Invalid tCL: %u", t->id, e->tCL); + return -ERANGE; + } + + if (e->tWR >= NV_MEM_WR_GDDR5_MAX) { + NV_WARN(drm, "(%u) Invalid tWR: %u", t->id, e->tWR); + return -ERANGE; + } + + if (t->odt > 3) { + NV_WARN(drm, "(%u) Invalid odt value, assuming autocal: %x", + t->id, t->odt); + t->odt = 0; + } + + t->mr[0] = (boot->mr[0] & 0x007) | + ((e->tCL - 5) << 3) | + ((e->tWR - 4) << 8); + t->mr[1] = (boot->mr[1] & 0x1007f0) | + t->drive_strength | + (t->odt << 2); + + NV_DEBUG(drm, "(%u) MR: %08x %08x", t->id, t->mr[0], t->mr[1]); + return 0; +} + +int +nouveau_mem_timing_calc(struct drm_device *dev, u32 freq, + struct nouveau_pm_memtiming *t) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_fb *pfb = nouveau_fb(device); + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_pm_memtiming *boot = &pm->boot.timing; + struct nouveau_pm_tbl_entry *e; + u8 ver, len, *ptr, *ramcfg; + int ret; + + ptr = nouveau_perf_timing(dev, freq, &ver, &len); + if (!ptr || ptr[0] == 0x00) { + *t = *boot; + return 0; + } + e = (struct nouveau_pm_tbl_entry *)ptr; + + t->tCWL = boot->tCWL; + + switch (device->card_type) { + case NV_40: + ret = nv40_mem_timing_calc(dev, freq, e, len, boot, t); + break; + case NV_50: + ret = nv50_mem_timing_calc(dev, freq, e, len, boot, t); + break; + case NV_C0: + case NV_D0: + ret = nvc0_mem_timing_calc(dev, freq, e, len, boot, t); + break; + default: + ret = -ENODEV; + break; + } + + switch (pfb->ram->type * !ret) { + case NV_MEM_TYPE_GDDR3: + ret = nouveau_mem_gddr3_mr(dev, freq, e, len, boot, t); + break; + case NV_MEM_TYPE_GDDR5: + ret = nouveau_mem_gddr5_mr(dev, freq, e, len, boot, t); + break; + case NV_MEM_TYPE_DDR2: + ret = nouveau_mem_ddr2_mr(dev, freq, e, len, boot, t); + break; + case NV_MEM_TYPE_DDR3: + ret = nouveau_mem_ddr3_mr(dev, freq, e, len, boot, t); + break; + default: + ret = -EINVAL; + break; + } + + ramcfg = nouveau_perf_ramcfg(dev, freq, &ver, &len); + if (ramcfg) { + int dll_off; + + if (ver == 0x00) + dll_off = !!(ramcfg[3] & 0x04); + else + dll_off = !!(ramcfg[2] & 0x40); + + switch (pfb->ram->type) { + case NV_MEM_TYPE_GDDR3: + t->mr[1] &= ~0x00000040; + t->mr[1] |= 0x00000040 * dll_off; + break; + default: + t->mr[1] &= ~0x00000001; + t->mr[1] |= 0x00000001 * dll_off; + break; + } + } + + return ret; +} + +void +nouveau_mem_timing_read(struct drm_device *dev, struct nouveau_pm_memtiming *t) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_fb *pfb = nouveau_fb(device); + u32 timing_base, timing_regs, mr_base; + int i; + + if (device->card_type >= 0xC0) { + timing_base = 0x10f290; + mr_base = 0x10f300; + } else { + timing_base = 0x100220; + mr_base = 0x1002c0; + } + + t->id = -1; + + switch (device->card_type) { + case NV_50: + timing_regs = 9; + break; + case NV_C0: + case NV_D0: + timing_regs = 5; + break; + case NV_30: + case NV_40: + timing_regs = 3; + break; + default: + timing_regs = 0; + return; + } + for(i = 0; i < timing_regs; i++) + t->reg[i] = nv_rd32(device, timing_base + (0x04 * i)); + + t->tCWL = 0; + if (device->card_type < NV_C0) { + t->tCWL = ((nv_rd32(device, 0x100228) & 0x0f000000) >> 24) + 1; + } else if (device->card_type <= NV_D0) { + t->tCWL = ((nv_rd32(device, 0x10f294) & 0x00000f80) >> 7); + } + + t->mr[0] = nv_rd32(device, mr_base); + t->mr[1] = nv_rd32(device, mr_base + 0x04); + t->mr[2] = nv_rd32(device, mr_base + 0x20); + t->mr[3] = nv_rd32(device, mr_base + 0x24); + + t->odt = 0; + t->drive_strength = 0; + + switch (pfb->ram->type) { + case NV_MEM_TYPE_DDR3: + t->odt |= (t->mr[1] & 0x200) >> 7; + case NV_MEM_TYPE_DDR2: + t->odt |= (t->mr[1] & 0x04) >> 2 | + (t->mr[1] & 0x40) >> 5; + break; + case NV_MEM_TYPE_GDDR3: + case NV_MEM_TYPE_GDDR5: + t->drive_strength = t->mr[1] & 0x03; + t->odt = (t->mr[1] & 0x0c) >> 2; + break; + default: + break; + } +} + +int +nouveau_mem_exec(struct nouveau_mem_exec_func *exec, + struct nouveau_pm_level *perflvl) +{ + struct nouveau_drm *drm = nouveau_drm(exec->dev); + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nouveau_fb *pfb = nouveau_fb(device); + struct nouveau_pm_memtiming *info = &perflvl->timing; + u32 tMRD = 1000, tCKSRE = 0, tCKSRX = 0, tXS = 0, tDLLK = 0; + u32 mr[3] = { info->mr[0], info->mr[1], info->mr[2] }; + u32 mr1_dlloff; + + switch (pfb->ram->type) { + case NV_MEM_TYPE_DDR2: + tDLLK = 2000; + mr1_dlloff = 0x00000001; + break; + case NV_MEM_TYPE_DDR3: + tDLLK = 12000; + tCKSRE = 2000; + tXS = 1000; + mr1_dlloff = 0x00000001; + break; + case NV_MEM_TYPE_GDDR3: + tDLLK = 40000; + mr1_dlloff = 0x00000040; + break; + default: + NV_ERROR(drm, "cannot reclock unsupported memtype\n"); + return -ENODEV; + } + + /* fetch current MRs */ + switch (pfb->ram->type) { + case NV_MEM_TYPE_GDDR3: + case NV_MEM_TYPE_DDR3: + mr[2] = exec->mrg(exec, 2); + default: + mr[1] = exec->mrg(exec, 1); + mr[0] = exec->mrg(exec, 0); + break; + } + + /* DLL 'on' -> DLL 'off' mode, disable before entering self-refresh */ + if (!(mr[1] & mr1_dlloff) && (info->mr[1] & mr1_dlloff)) { + exec->precharge(exec); + exec->mrs (exec, 1, mr[1] | mr1_dlloff); + exec->wait(exec, tMRD); + } + + /* enter self-refresh mode */ + exec->precharge(exec); + exec->refresh(exec); + exec->refresh(exec); + exec->refresh_auto(exec, false); + exec->refresh_self(exec, true); + exec->wait(exec, tCKSRE); + + /* modify input clock frequency */ + exec->clock_set(exec); + + /* exit self-refresh mode */ + exec->wait(exec, tCKSRX); + exec->precharge(exec); + exec->refresh_self(exec, false); + exec->refresh_auto(exec, true); + exec->wait(exec, tXS); + exec->wait(exec, tXS); + + /* update MRs */ + if (mr[2] != info->mr[2]) { + exec->mrs (exec, 2, info->mr[2]); + exec->wait(exec, tMRD); + } + + if (mr[1] != info->mr[1]) { + /* need to keep DLL off until later, at least on GDDR3 */ + exec->mrs (exec, 1, info->mr[1] | (mr[1] & mr1_dlloff)); + exec->wait(exec, tMRD); + } + + if (mr[0] != info->mr[0]) { + exec->mrs (exec, 0, info->mr[0]); + exec->wait(exec, tMRD); + } + + /* update PFB timing registers */ + exec->timing_set(exec); + + /* DLL (enable + ) reset */ + if (!(info->mr[1] & mr1_dlloff)) { + if (mr[1] & mr1_dlloff) { + exec->mrs (exec, 1, info->mr[1]); + exec->wait(exec, tMRD); + } + exec->mrs (exec, 0, info->mr[0] | 0x00000100); + exec->wait(exec, tMRD); + exec->mrs (exec, 0, info->mr[0] | 0x00000000); + exec->wait(exec, tMRD); + exec->wait(exec, tDLLK); + if (pfb->ram->type == NV_MEM_TYPE_GDDR3) + exec->precharge(exec); + } + + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nouveau_perf.c b/drivers/gpu/drm/nouveau/nouveau_perf.c new file mode 100644 index 0000000..4fe883c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_perf.c @@ -0,0 +1,416 @@ +/* + * Copyright 2010 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 <drm/drmP.h> + +#include "nouveau_drm.h" +#include "nouveau_reg.h" +#include "nouveau_pm.h" + +static u8 * +nouveau_perf_table(struct drm_device *dev, u8 *ver) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvbios *bios = &drm->vbios; + struct bit_entry P; + + if (!bit_table(dev, 'P', &P) && P.version && P.version <= 2) { + u8 *perf = ROMPTR(dev, P.data[0]); + if (perf) { + *ver = perf[0]; + return perf; + } + } + + if (bios->type == NVBIOS_BMP) { + if (bios->data[bios->offset + 6] >= 0x25) { + u8 *perf = ROMPTR(dev, bios->data[bios->offset + 0x94]); + if (perf) { + *ver = perf[1]; + return perf; + } + } + } + + return NULL; +} + +static u8 * +nouveau_perf_entry(struct drm_device *dev, int idx, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len) +{ + u8 *perf = nouveau_perf_table(dev, ver); + if (perf) { + if (*ver >= 0x12 && *ver < 0x20 && idx < perf[2]) { + *hdr = perf[3]; + *cnt = 0; + *len = 0; + return perf + perf[0] + idx * perf[3]; + } else + if (*ver >= 0x20 && *ver < 0x40 && idx < perf[2]) { + *hdr = perf[3]; + *cnt = perf[4]; + *len = perf[5]; + return perf + perf[1] + idx * (*hdr + (*cnt * *len)); + } else + if (*ver >= 0x40 && *ver < 0x41 && idx < perf[5]) { + *hdr = perf[2]; + *cnt = perf[4]; + *len = perf[3]; + return perf + perf[1] + idx * (*hdr + (*cnt * *len)); + } + } + return NULL; +} + +u8 * +nouveau_perf_rammap(struct drm_device *dev, u32 freq, + u8 *ver, u8 *hdr, u8 *cnt, u8 *len) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct bit_entry P; + u8 *perf, i = 0; + + if (!bit_table(dev, 'P', &P) && P.version == 2) { + u8 *rammap = ROMPTR(dev, P.data[4]); + if (rammap) { + u8 *ramcfg = rammap + rammap[1]; + + *ver = rammap[0]; + *hdr = rammap[2]; + *cnt = rammap[4]; + *len = rammap[3]; + + freq /= 1000; + for (i = 0; i < rammap[5]; i++) { + if (freq >= ROM16(ramcfg[0]) && + freq <= ROM16(ramcfg[2])) + return ramcfg; + + ramcfg += *hdr + (*cnt * *len); + } + } + + return NULL; + } + + if (nv_device(drm->device)->chipset == 0x49 || + nv_device(drm->device)->chipset == 0x4b) + freq /= 2; + + while ((perf = nouveau_perf_entry(dev, i++, ver, hdr, cnt, len))) { + if (*ver >= 0x20 && *ver < 0x25) { + if (perf[0] != 0xff && freq <= ROM16(perf[11]) * 1000) + break; + } else + if (*ver >= 0x25 && *ver < 0x40) { + if (perf[0] != 0xff && freq <= ROM16(perf[12]) * 1000) + break; + } + } + + if (perf) { + u8 *ramcfg = perf + *hdr; + *ver = 0x00; + *hdr = 0; + return ramcfg; + } + + return NULL; +} + +u8 * +nouveau_perf_ramcfg(struct drm_device *dev, u32 freq, u8 *ver, u8 *len) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvbios *bios = &drm->vbios; + u8 strap, hdr, cnt; + u8 *rammap; + + strap = (nv_rd32(device, 0x101000) & 0x0000003c) >> 2; + if (bios->ram_restrict_tbl_ptr) + strap = bios->data[bios->ram_restrict_tbl_ptr + strap]; + + rammap = nouveau_perf_rammap(dev, freq, ver, &hdr, &cnt, len); + if (rammap && strap < cnt) + return rammap + hdr + (strap * *len); + + return NULL; +} + +u8 * +nouveau_perf_timing(struct drm_device *dev, u32 freq, u8 *ver, u8 *len) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvbios *bios = &drm->vbios; + struct bit_entry P; + u8 *perf, *timing = NULL; + u8 i = 0, hdr, cnt; + + if (bios->type == NVBIOS_BMP) { + while ((perf = nouveau_perf_entry(dev, i++, ver, &hdr, &cnt, + len)) && *ver == 0x15) { + if (freq <= ROM32(perf[5]) * 20) { + *ver = 0x00; + *len = 14; + return perf + 41; + } + } + return NULL; + } + + if (!bit_table(dev, 'P', &P)) { + if (P.version == 1) + timing = ROMPTR(dev, P.data[4]); + else + if (P.version == 2) + timing = ROMPTR(dev, P.data[8]); + } + + if (timing && timing[0] == 0x10) { + u8 *ramcfg = nouveau_perf_ramcfg(dev, freq, ver, len); + if (ramcfg && ramcfg[1] < timing[2]) { + *ver = timing[0]; + *len = timing[3]; + return timing + timing[1] + (ramcfg[1] * timing[3]); + } + } + + return NULL; +} + +static void +legacy_perf_init(struct drm_device *dev) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nvbios *bios = &drm->vbios; + struct nouveau_pm *pm = nouveau_pm(dev); + char *perf, *entry, *bmp = &bios->data[bios->offset]; + int headerlen, use_straps; + + if (bmp[5] < 0x5 || bmp[6] < 0x14) { + NV_DEBUG(drm, "BMP version too old for perf\n"); + return; + } + + perf = ROMPTR(dev, bmp[0x73]); + if (!perf) { + NV_DEBUG(drm, "No memclock table pointer found.\n"); + return; + } + + switch (perf[0]) { + case 0x12: + case 0x14: + case 0x18: + use_straps = 0; + headerlen = 1; + break; + case 0x01: + use_straps = perf[1] & 1; + headerlen = (use_straps ? 8 : 2); + break; + default: + NV_WARN(drm, "Unknown memclock table version %x.\n", perf[0]); + return; + } + + entry = perf + headerlen; + if (use_straps) + entry += (nv_rd32(device, NV_PEXTDEV_BOOT_0) & 0x3c) >> 1; + + sprintf(pm->perflvl[0].name, "performance_level_0"); + pm->perflvl[0].memory = ROM16(entry[0]) * 20; + pm->nr_perflvl = 1; +} + +static void +nouveau_perf_voltage(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct bit_entry P; + u8 *vmap; + int id; + + id = perflvl->volt_min; + perflvl->volt_min = 0; + + /* boards using voltage table version <0x40 store the voltage + * level directly in the perflvl entry as a multiple of 10mV + */ + if (drm->pm->voltage.version < 0x40) { + perflvl->volt_min = id * 10000; + perflvl->volt_max = perflvl->volt_min; + return; + } + + /* on newer ones, the perflvl stores an index into yet another + * vbios table containing a min/max voltage value for the perflvl + */ + if (bit_table(dev, 'P', &P) || P.version != 2 || P.length < 34) { + NV_DEBUG(drm, "where's our volt map table ptr? %d %d\n", + P.version, P.length); + return; + } + + vmap = ROMPTR(dev, P.data[32]); + if (!vmap) { + NV_DEBUG(drm, "volt map table pointer invalid\n"); + return; + } + + if (id < vmap[3]) { + vmap += vmap[1] + (vmap[2] * id); + perflvl->volt_min = ROM32(vmap[0]); + perflvl->volt_max = ROM32(vmap[4]); + } +} + +void +nouveau_perf_init(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_pm *pm = nouveau_pm(dev); + struct nvbios *bios = &drm->vbios; + u8 *perf, ver, hdr, cnt, len; + int ret, vid, i = -1; + + if (bios->type == NVBIOS_BMP && bios->data[bios->offset + 6] < 0x25) { + legacy_perf_init(dev); + return; + } + + perf = nouveau_perf_table(dev, &ver); + + while ((perf = nouveau_perf_entry(dev, ++i, &ver, &hdr, &cnt, &len))) { + struct nouveau_pm_level *perflvl = &pm->perflvl[pm->nr_perflvl]; + + if (perf[0] == 0xff) + continue; + + switch (ver) { + case 0x12: + case 0x13: + case 0x15: + perflvl->fanspeed = perf[55]; + if (hdr > 56) + perflvl->volt_min = perf[56]; + perflvl->core = ROM32(perf[1]) * 10; + perflvl->memory = ROM32(perf[5]) * 20; + break; + case 0x21: + case 0x23: + case 0x24: + perflvl->fanspeed = perf[4]; + perflvl->volt_min = perf[5]; + perflvl->shader = ROM16(perf[6]) * 1000; + perflvl->core = perflvl->shader; + perflvl->core += (signed char)perf[8] * 1000; + if (nv_device(drm->device)->chipset == 0x49 || + nv_device(drm->device)->chipset == 0x4b) + perflvl->memory = ROM16(perf[11]) * 1000; + else + perflvl->memory = ROM16(perf[11]) * 2000; + break; + case 0x25: + perflvl->fanspeed = perf[4]; + perflvl->volt_min = perf[5]; + perflvl->core = ROM16(perf[6]) * 1000; + perflvl->shader = ROM16(perf[10]) * 1000; + perflvl->memory = ROM16(perf[12]) * 1000; + break; + case 0x30: + perflvl->memscript = ROM16(perf[2]); + case 0x35: + perflvl->fanspeed = perf[6]; + perflvl->volt_min = perf[7]; + perflvl->core = ROM16(perf[8]) * 1000; + perflvl->shader = ROM16(perf[10]) * 1000; + perflvl->memory = ROM16(perf[12]) * 1000; + perflvl->vdec = ROM16(perf[16]) * 1000; + perflvl->dom6 = ROM16(perf[20]) * 1000; + break; + case 0x40: +#define subent(n) ((ROM16(perf[hdr + (n) * len]) & 0xfff) * 1000) + perflvl->fanspeed = 0; /*XXX*/ + perflvl->volt_min = perf[2]; + if (nv_device(drm->device)->card_type == NV_50) { + perflvl->core = subent(0); + perflvl->shader = subent(1); + perflvl->memory = subent(2); + perflvl->vdec = subent(3); + perflvl->unka0 = subent(4); + } else { + perflvl->hub06 = subent(0); + perflvl->hub01 = subent(1); + perflvl->copy = subent(2); + perflvl->shader = subent(3); + perflvl->rop = subent(4); + perflvl->memory = subent(5); + perflvl->vdec = subent(6); + perflvl->daemon = subent(10); + perflvl->hub07 = subent(11); + perflvl->core = perflvl->shader / 2; + } + break; + } + + /* make sure vid is valid */ + nouveau_perf_voltage(dev, perflvl); + if (pm->voltage.supported && perflvl->volt_min) { + vid = nouveau_volt_vid_lookup(dev, perflvl->volt_min); + if (vid < 0) { + NV_DEBUG(drm, "perflvl %d, bad vid\n", i); + continue; + } + } + + /* get the corresponding memory timings */ + ret = nouveau_mem_timing_calc(dev, perflvl->memory, + &perflvl->timing); + if (ret) { + NV_DEBUG(drm, "perflvl %d, bad timing: %d\n", i, ret); + continue; + } + + snprintf(perflvl->name, sizeof(perflvl->name), + "performance_level_%d", i); + perflvl->id = i; + + snprintf(perflvl->profile.name, sizeof(perflvl->profile.name), + "%d", perflvl->id); + perflvl->profile.func = &nouveau_pm_static_profile_func; + list_add_tail(&perflvl->profile.head, &pm->profiles); + + + pm->nr_perflvl++; + } +} + +void +nouveau_perf_fini(struct drm_device *dev) +{ +} diff --git a/drivers/gpu/drm/nouveau/nouveau_hwmon.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 4aff04f..936b442 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hwmon.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c @@ -32,12 +32,369 @@ #include <drm/drmP.h> #include "nouveau_drm.h" -#include "nouveau_hwmon.h" +#include "nouveau_pm.h" #include <subdev/gpio.h> #include <subdev/timer.h> #include <subdev/therm.h> +MODULE_PARM_DESC(perflvl, "Performance level (default: boot)"); +static char *nouveau_perflvl; +module_param_named(perflvl, nouveau_perflvl, charp, 0400); + +MODULE_PARM_DESC(perflvl_wr, "Allow perflvl changes (warning: dangerous!)"); +static int nouveau_perflvl_wr; +module_param_named(perflvl_wr, nouveau_perflvl_wr, int, 0400); + +static int +nouveau_pm_perflvl_aux(struct drm_device *dev, struct nouveau_pm_level *perflvl, + struct nouveau_pm_level *a, struct nouveau_pm_level *b) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_therm *therm = nouveau_therm(drm->device); + int ret; + + /*XXX: not on all boards, we should control based on temperature + * on recent boards.. or maybe on some other factor we don't + * know about? + */ + if (therm && therm->fan_set && + a->fanspeed && b->fanspeed && b->fanspeed > a->fanspeed) { + ret = therm->fan_set(therm, perflvl->fanspeed); + if (ret && ret != -ENODEV) { + NV_ERROR(drm, "fanspeed set failed: %d\n", ret); + } + } + + if (pm->voltage.supported && pm->voltage_set) { + if (perflvl->volt_min && b->volt_min > a->volt_min) { + ret = pm->voltage_set(dev, perflvl->volt_min); + if (ret) { + NV_ERROR(drm, "voltage set failed: %d\n", ret); + return ret; + } + } + } + + return 0; +} + +static int +nouveau_pm_perflvl_set(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nouveau_pm *pm = nouveau_pm(dev); + void *state; + int ret; + + if (perflvl == pm->cur) + return 0; + + ret = nouveau_pm_perflvl_aux(dev, perflvl, pm->cur, perflvl); + if (ret) + return ret; + + state = pm->clocks_pre(dev, perflvl); + if (IS_ERR(state)) { + ret = PTR_ERR(state); + goto error; + } + ret = pm->clocks_set(dev, state); + if (ret) + goto error; + + ret = nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur); + if (ret) + return ret; + + pm->cur = perflvl; + return 0; + +error: + /* restore the fan speed and voltage before leaving */ + nouveau_pm_perflvl_aux(dev, perflvl, perflvl, pm->cur); + return ret; +} + +void +nouveau_pm_trigger(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_timer *ptimer = nouveau_timer(drm->device); + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_pm_profile *profile = NULL; + struct nouveau_pm_level *perflvl = NULL; + int ret; + + /* select power profile based on current power source */ + if (power_supply_is_system_supplied()) + profile = pm->profile_ac; + else + profile = pm->profile_dc; + + if (profile != pm->profile) { + pm->profile->func->fini(pm->profile); + pm->profile = profile; + pm->profile->func->init(pm->profile); + } + + /* select performance level based on profile */ + perflvl = profile->func->select(profile); + + /* change perflvl, if necessary */ + if (perflvl != pm->cur) { + u64 time0 = ptimer->read(ptimer); + + NV_INFO(drm, "setting performance level: %d", perflvl->id); + ret = nouveau_pm_perflvl_set(dev, perflvl); + if (ret) + NV_INFO(drm, "> reclocking failed: %d\n\n", ret); + + NV_INFO(drm, "> reclocking took %lluns\n\n", + ptimer->read(ptimer) - time0); + } +} + +static struct nouveau_pm_profile * +profile_find(struct drm_device *dev, const char *string) +{ + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_pm_profile *profile; + + list_for_each_entry(profile, &pm->profiles, head) { + if (!strncmp(profile->name, string, sizeof(profile->name))) + return profile; + } + + return NULL; +} + +static int +nouveau_pm_profile_set(struct drm_device *dev, const char *profile) +{ + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_pm_profile *ac = NULL, *dc = NULL; + char string[16], *cur = string, *ptr; + + /* safety precaution, for now */ + if (nouveau_perflvl_wr != 7777) + return -EPERM; + + strncpy(string, profile, sizeof(string)); + string[sizeof(string) - 1] = 0; + if ((ptr = strchr(string, '\n'))) + *ptr = '\0'; + + ptr = strsep(&cur, ","); + if (ptr) + ac = profile_find(dev, ptr); + + ptr = strsep(&cur, ","); + if (ptr) + dc = profile_find(dev, ptr); + else + dc = ac; + + if (ac == NULL || dc == NULL) + return -EINVAL; + + pm->profile_ac = ac; + pm->profile_dc = dc; + nouveau_pm_trigger(dev); + return 0; +} + +static void +nouveau_pm_static_dummy(struct nouveau_pm_profile *profile) +{ +} + +static struct nouveau_pm_level * +nouveau_pm_static_select(struct nouveau_pm_profile *profile) +{ + return container_of(profile, struct nouveau_pm_level, profile); +} + +const struct nouveau_pm_profile_func nouveau_pm_static_profile_func = { + .destroy = nouveau_pm_static_dummy, + .init = nouveau_pm_static_dummy, + .fini = nouveau_pm_static_dummy, + .select = nouveau_pm_static_select, +}; + +static int +nouveau_pm_perflvl_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_therm *therm = nouveau_therm(drm->device); + int ret; + + memset(perflvl, 0, sizeof(*perflvl)); + + if (pm->clocks_get) { + ret = pm->clocks_get(dev, perflvl); + if (ret) + return ret; + } + + if (pm->voltage.supported && pm->voltage_get) { + ret = pm->voltage_get(dev); + if (ret > 0) { + perflvl->volt_min = ret; + perflvl->volt_max = ret; + } + } + + if (therm && therm->fan_get) { + ret = therm->fan_get(therm); + if (ret >= 0) + perflvl->fanspeed = ret; + } + + nouveau_mem_timing_read(dev, &perflvl->timing); + return 0; +} + +static void +nouveau_pm_perflvl_info(struct nouveau_pm_level *perflvl, char *ptr, int len) +{ + char c[16], s[16], v[32], f[16], m[16]; + + c[0] = '\0'; + if (perflvl->core) + snprintf(c, sizeof(c), " core %dMHz", perflvl->core / 1000); + + s[0] = '\0'; + if (perflvl->shader) + snprintf(s, sizeof(s), " shader %dMHz", perflvl->shader / 1000); + + m[0] = '\0'; + if (perflvl->memory) + snprintf(m, sizeof(m), " memory %dMHz", perflvl->memory / 1000); + + v[0] = '\0'; + if (perflvl->volt_min && perflvl->volt_min != perflvl->volt_max) { + snprintf(v, sizeof(v), " voltage %dmV-%dmV", + perflvl->volt_min / 1000, perflvl->volt_max / 1000); + } else + if (perflvl->volt_min) { + snprintf(v, sizeof(v), " voltage %dmV", + perflvl->volt_min / 1000); + } + + f[0] = '\0'; + if (perflvl->fanspeed) + snprintf(f, sizeof(f), " fanspeed %d%%", perflvl->fanspeed); + + snprintf(ptr, len, "%s%s%s%s%s\n", c, s, m, v, f); +} + +static ssize_t +nouveau_pm_get_perflvl_info(struct device *d, + struct device_attribute *a, char *buf) +{ + struct nouveau_pm_level *perflvl = + container_of(a, struct nouveau_pm_level, dev_attr); + char *ptr = buf; + int len = PAGE_SIZE; + + snprintf(ptr, len, "%d:", perflvl->id); + ptr += strlen(buf); + len -= strlen(buf); + + nouveau_pm_perflvl_info(perflvl, ptr, len); + return strlen(buf); +} + +static ssize_t +nouveau_pm_get_perflvl(struct device *d, struct device_attribute *a, char *buf) +{ + struct drm_device *dev = pci_get_drvdata(to_pci_dev(d)); + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_pm_level cur; + int len = PAGE_SIZE, ret; + char *ptr = buf; + + snprintf(ptr, len, "profile: %s, %s\nc:", + pm->profile_ac->name, pm->profile_dc->name); + ptr += strlen(buf); + len -= strlen(buf); + + ret = nouveau_pm_perflvl_get(dev, &cur); + if (ret == 0) + nouveau_pm_perflvl_info(&cur, ptr, len); + return strlen(buf); +} + +static ssize_t +nouveau_pm_set_perflvl(struct device *d, struct device_attribute *a, + const char *buf, size_t count) +{ + struct drm_device *dev = pci_get_drvdata(to_pci_dev(d)); + int ret; + + ret = nouveau_pm_profile_set(dev, buf); + if (ret) + return ret; + return strlen(buf); +} + +static DEVICE_ATTR(performance_level, S_IRUGO | S_IWUSR, + nouveau_pm_get_perflvl, nouveau_pm_set_perflvl); + +static int +nouveau_sysfs_init(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_pm *pm = nouveau_pm(dev); + struct device *d = &dev->pdev->dev; + int ret, i; + + ret = device_create_file(d, &dev_attr_performance_level); + if (ret) + return ret; + + for (i = 0; i < pm->nr_perflvl; i++) { + struct nouveau_pm_level *perflvl = &pm->perflvl[i]; + + perflvl->dev_attr.attr.name = perflvl->name; + perflvl->dev_attr.attr.mode = S_IRUGO; + perflvl->dev_attr.show = nouveau_pm_get_perflvl_info; + perflvl->dev_attr.store = NULL; + sysfs_attr_init(&perflvl->dev_attr.attr); + + ret = device_create_file(d, &perflvl->dev_attr); + if (ret) { + NV_ERROR(drm, "failed pervlvl %d sysfs: %d\n", + perflvl->id, i); + perflvl->dev_attr.attr.name = NULL; + nouveau_pm_fini(dev); + return ret; + } + } + + return 0; +} + +static void +nouveau_sysfs_fini(struct drm_device *dev) +{ + struct nouveau_pm *pm = nouveau_pm(dev); + struct device *d = &dev->pdev->dev; + int i; + + device_remove_file(d, &dev_attr_performance_level); + for (i = 0; i < pm->nr_perflvl; i++) { + struct nouveau_pm_level *pl = &pm->perflvl[i]; + + if (!pl->dev_attr.attr.name) + break; + + device_remove_file(d, &pl->dev_attr); + } +} + #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) static ssize_t nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) @@ -421,6 +778,9 @@ nouveau_hwmon_set_pwm1(struct device *d, struct device_attribute *a, int ret = -ENODEV; long value; + if (nouveau_perflvl_wr != 7777) + return -EPERM; + if (kstrtol(buf, 10, &value) == -EINVAL) return -EINVAL; @@ -559,21 +919,17 @@ static const struct attribute_group hwmon_pwm_fan_attrgroup = { }; #endif -int +static int nouveau_hwmon_init(struct drm_device *dev) { + struct nouveau_pm *pm = nouveau_pm(dev); + #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_therm *therm = nouveau_therm(drm->device); - struct nouveau_hwmon *hwmon; struct device *hwmon_dev; int ret = 0; - hwmon = drm->hwmon = kzalloc(sizeof(*hwmon), GFP_KERNEL); - if (!hwmon) - return -ENOMEM; - hwmon->dev = dev; - if (!therm || !therm->temp_get || !therm->attr_get || !therm->attr_set) return -ENODEV; @@ -620,36 +976,199 @@ nouveau_hwmon_init(struct drm_device *dev) goto error; } - hwmon->hwmon = hwmon_dev; + pm->hwmon = hwmon_dev; return 0; error: NV_ERROR(drm, "Unable to create some hwmon sysfs files: %d\n", ret); hwmon_device_unregister(hwmon_dev); - hwmon->hwmon = NULL; + pm->hwmon = NULL; return ret; #else + pm->hwmon = NULL; return 0; #endif } -void +static void nouveau_hwmon_fini(struct drm_device *dev) { #if defined(CONFIG_HWMON) || (defined(MODULE) && defined(CONFIG_HWMON_MODULE)) - struct nouveau_hwmon *hwmon = nouveau_hwmon(dev); + struct nouveau_pm *pm = nouveau_pm(dev); - if (hwmon->hwmon) { - sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_default_attrgroup); - sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_temp_attrgroup); - sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_pwm_fan_attrgroup); - sysfs_remove_group(&hwmon->hwmon->kobj, &hwmon_fan_rpm_attrgroup); + if (pm->hwmon) { + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_default_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_temp_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_pwm_fan_attrgroup); + sysfs_remove_group(&pm->hwmon->kobj, &hwmon_fan_rpm_attrgroup); - hwmon_device_unregister(hwmon->hwmon); + hwmon_device_unregister(pm->hwmon); } +#endif +} + +#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) +static int +nouveau_pm_acpi_event(struct notifier_block *nb, unsigned long val, void *data) +{ + struct nouveau_pm *pm = container_of(nb, struct nouveau_pm, acpi_nb); + struct nouveau_drm *drm = nouveau_drm(pm->dev); + struct acpi_bus_event *entry = (struct acpi_bus_event *)data; + + if (strcmp(entry->device_class, "ac_adapter") == 0) { + bool ac = power_supply_is_system_supplied(); - nouveau_drm(dev)->hwmon = NULL; - kfree(hwmon); + NV_DEBUG(drm, "power supply changed: %s\n", ac ? "AC" : "DC"); + nouveau_pm_trigger(pm->dev); + } + + return NOTIFY_OK; +} #endif + +int +nouveau_pm_init(struct drm_device *dev) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_pm *pm; + char info[256]; + int ret, i; + + pm = drm->pm = kzalloc(sizeof(*pm), GFP_KERNEL); + if (!pm) + return -ENOMEM; + + pm->dev = dev; + + if (device->card_type < NV_40) { + pm->clocks_get = nv04_pm_clocks_get; + pm->clocks_pre = nv04_pm_clocks_pre; + pm->clocks_set = nv04_pm_clocks_set; + if (nouveau_gpio(drm->device)) { + pm->voltage_get = nouveau_voltage_gpio_get; + pm->voltage_set = nouveau_voltage_gpio_set; + } + } else + if (device->card_type < NV_50) { + pm->clocks_get = nv40_pm_clocks_get; + pm->clocks_pre = nv40_pm_clocks_pre; + pm->clocks_set = nv40_pm_clocks_set; + pm->voltage_get = nouveau_voltage_gpio_get; + pm->voltage_set = nouveau_voltage_gpio_set; + } else + if (device->card_type < NV_C0) { + if (device->chipset < 0xa3 || + device->chipset == 0xaa || + device->chipset == 0xac) { + pm->clocks_get = nv50_pm_clocks_get; + pm->clocks_pre = nv50_pm_clocks_pre; + pm->clocks_set = nv50_pm_clocks_set; + } else { + pm->clocks_get = nva3_pm_clocks_get; + pm->clocks_pre = nva3_pm_clocks_pre; + pm->clocks_set = nva3_pm_clocks_set; + } + pm->voltage_get = nouveau_voltage_gpio_get; + pm->voltage_set = nouveau_voltage_gpio_set; + } else + if (device->card_type < NV_E0) { + pm->clocks_get = nvc0_pm_clocks_get; + pm->clocks_pre = nvc0_pm_clocks_pre; + pm->clocks_set = nvc0_pm_clocks_set; + pm->voltage_get = nouveau_voltage_gpio_get; + pm->voltage_set = nouveau_voltage_gpio_set; + } + + + /* parse aux tables from vbios */ + nouveau_volt_init(dev); + + INIT_LIST_HEAD(&pm->profiles); + + /* determine current ("boot") performance level */ + ret = nouveau_pm_perflvl_get(dev, &pm->boot); + if (ret) { + NV_ERROR(drm, "failed to determine boot perflvl\n"); + return ret; + } + + strncpy(pm->boot.name, "boot", 4); + strncpy(pm->boot.profile.name, "boot", 4); + pm->boot.profile.func = &nouveau_pm_static_profile_func; + + list_add(&pm->boot.profile.head, &pm->profiles); + + pm->profile_ac = &pm->boot.profile; + pm->profile_dc = &pm->boot.profile; + pm->profile = &pm->boot.profile; + pm->cur = &pm->boot; + + /* add performance levels from vbios */ + nouveau_perf_init(dev); + + /* display available performance levels */ + NV_INFO(drm, "%d available performance level(s)\n", pm->nr_perflvl); + for (i = 0; i < pm->nr_perflvl; i++) { + nouveau_pm_perflvl_info(&pm->perflvl[i], info, sizeof(info)); + NV_INFO(drm, "%d:%s", pm->perflvl[i].id, info); + } + + nouveau_pm_perflvl_info(&pm->boot, info, sizeof(info)); + NV_INFO(drm, "c:%s", info); + + /* switch performance levels now if requested */ + if (nouveau_perflvl != NULL) + nouveau_pm_profile_set(dev, nouveau_perflvl); + + nouveau_sysfs_init(dev); + nouveau_hwmon_init(dev); +#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) + pm->acpi_nb.notifier_call = nouveau_pm_acpi_event; + register_acpi_notifier(&pm->acpi_nb); +#endif + + return 0; +} + +void +nouveau_pm_fini(struct drm_device *dev) +{ + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_pm_profile *profile, *tmp; + + list_for_each_entry_safe(profile, tmp, &pm->profiles, head) { + list_del(&profile->head); + profile->func->destroy(profile); + } + + if (pm->cur != &pm->boot) + nouveau_pm_perflvl_set(dev, &pm->boot); + + nouveau_perf_fini(dev); + nouveau_volt_fini(dev); + +#if defined(CONFIG_ACPI) && defined(CONFIG_POWER_SUPPLY) + unregister_acpi_notifier(&pm->acpi_nb); +#endif + nouveau_hwmon_fini(dev); + nouveau_sysfs_fini(dev); + + nouveau_drm(dev)->pm = NULL; + kfree(pm); +} + +void +nouveau_pm_resume(struct drm_device *dev) +{ + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_pm_level *perflvl; + + if (!pm->cur || pm->cur == &pm->boot) + return; + + perflvl = pm->cur; + pm->cur = &pm->boot; + nouveau_pm_perflvl_set(dev, perflvl); } diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.h b/drivers/gpu/drm/nouveau/nouveau_pm.h new file mode 100644 index 0000000..73b789c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_pm.h @@ -0,0 +1,283 @@ +/* + * Copyright 2010 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 + */ + +#ifndef __NOUVEAU_PM_H__ +#define __NOUVEAU_PM_H__ + +#include <subdev/bios/pll.h> +#include <subdev/clock.h> + +struct nouveau_pm_voltage_level { + u32 voltage; /* microvolts */ + u8 vid; +}; + +struct nouveau_pm_voltage { + bool supported; + u8 version; + u8 vid_mask; + + struct nouveau_pm_voltage_level *level; + int nr_level; +}; + +/* Exclusive upper limits */ +#define NV_MEM_CL_DDR2_MAX 8 +#define NV_MEM_WR_DDR2_MAX 9 +#define NV_MEM_CL_DDR3_MAX 17 +#define NV_MEM_WR_DDR3_MAX 17 +#define NV_MEM_CL_GDDR3_MAX 16 +#define NV_MEM_WR_GDDR3_MAX 18 +#define NV_MEM_CL_GDDR5_MAX 21 +#define NV_MEM_WR_GDDR5_MAX 20 + +struct nouveau_pm_memtiming { + int id; + + u32 reg[9]; + u32 mr[4]; + + u8 tCWL; + + u8 odt; + u8 drive_strength; +}; + +struct nouveau_pm_tbl_header { + u8 version; + u8 header_len; + u8 entry_cnt; + u8 entry_len; +}; + +struct nouveau_pm_tbl_entry { + u8 tWR; + u8 tWTR; + u8 tCL; + u8 tRC; + u8 empty_4; + u8 tRFC; /* Byte 5 */ + u8 empty_6; + u8 tRAS; /* Byte 7 */ + u8 empty_8; + u8 tRP; /* Byte 9 */ + u8 tRCDRD; + u8 tRCDWR; + u8 tRRD; + u8 tUNK_13; + u8 RAM_FT1; /* 14, a bitmask of random RAM features */ + u8 empty_15; + u8 tUNK_16; + u8 empty_17; + u8 tUNK_18; + u8 tCWL; + u8 tUNK_20, tUNK_21; +}; + +struct nouveau_pm_profile; +struct nouveau_pm_profile_func { + void (*destroy)(struct nouveau_pm_profile *); + void (*init)(struct nouveau_pm_profile *); + void (*fini)(struct nouveau_pm_profile *); + struct nouveau_pm_level *(*select)(struct nouveau_pm_profile *); +}; + +struct nouveau_pm_profile { + const struct nouveau_pm_profile_func *func; + struct list_head head; + char name[8]; +}; + +#define NOUVEAU_PM_MAX_LEVEL 8 +struct nouveau_pm_level { + struct nouveau_pm_profile profile; + struct device_attribute dev_attr; + char name[32]; + int id; + + struct nouveau_pm_memtiming timing; + u32 memory; + u16 memscript; + + u32 core; + u32 shader; + u32 rop; + u32 copy; + u32 daemon; + u32 vdec; + u32 dom6; + u32 unka0; /* nva3:nvc0 */ + u32 hub01; /* nvc0- */ + u32 hub06; /* nvc0- */ + u32 hub07; /* nvc0- */ + + u32 volt_min; /* microvolts */ + u32 volt_max; + u8 fanspeed; +}; + +struct nouveau_pm_temp_sensor_constants { + u16 offset_constant; + s16 offset_mult; + s16 offset_div; + s16 slope_mult; + s16 slope_div; +}; + +struct nouveau_pm_threshold_temp { + s16 critical; + s16 down_clock; +}; + +struct nouveau_pm { + struct drm_device *dev; + + struct nouveau_pm_voltage voltage; + struct nouveau_pm_level perflvl[NOUVEAU_PM_MAX_LEVEL]; + int nr_perflvl; + struct nouveau_pm_temp_sensor_constants sensor_constants; + struct nouveau_pm_threshold_temp threshold_temp; + + struct nouveau_pm_profile *profile_ac; + struct nouveau_pm_profile *profile_dc; + struct nouveau_pm_profile *profile; + struct list_head profiles; + + struct nouveau_pm_level boot; + struct nouveau_pm_level *cur; + + struct device *hwmon; + struct notifier_block acpi_nb; + + int (*clocks_get)(struct drm_device *, struct nouveau_pm_level *); + void *(*clocks_pre)(struct drm_device *, struct nouveau_pm_level *); + int (*clocks_set)(struct drm_device *, void *); + + int (*voltage_get)(struct drm_device *); + int (*voltage_set)(struct drm_device *, int voltage); +}; + +static inline struct nouveau_pm * +nouveau_pm(struct drm_device *dev) +{ + return nouveau_drm(dev)->pm; +} + +struct nouveau_mem_exec_func { + struct drm_device *dev; + void (*precharge)(struct nouveau_mem_exec_func *); + void (*refresh)(struct nouveau_mem_exec_func *); + void (*refresh_auto)(struct nouveau_mem_exec_func *, bool); + void (*refresh_self)(struct nouveau_mem_exec_func *, bool); + void (*wait)(struct nouveau_mem_exec_func *, u32 nsec); + u32 (*mrg)(struct nouveau_mem_exec_func *, int mr); + void (*mrs)(struct nouveau_mem_exec_func *, int mr, u32 data); + void (*clock_set)(struct nouveau_mem_exec_func *); + void (*timing_set)(struct nouveau_mem_exec_func *); + void *priv; +}; + +/* nouveau_mem.c */ +int nouveau_mem_exec(struct nouveau_mem_exec_func *, + struct nouveau_pm_level *); + +/* nouveau_pm.c */ +int nouveau_pm_init(struct drm_device *dev); +void nouveau_pm_fini(struct drm_device *dev); +void nouveau_pm_resume(struct drm_device *dev); +extern const struct nouveau_pm_profile_func nouveau_pm_static_profile_func; +void nouveau_pm_trigger(struct drm_device *dev); + +/* nouveau_volt.c */ +void nouveau_volt_init(struct drm_device *); +void nouveau_volt_fini(struct drm_device *); +int nouveau_volt_vid_lookup(struct drm_device *, int voltage); +int nouveau_volt_lvl_lookup(struct drm_device *, int vid); +int nouveau_voltage_gpio_get(struct drm_device *); +int nouveau_voltage_gpio_set(struct drm_device *, int voltage); + +/* nouveau_perf.c */ +void nouveau_perf_init(struct drm_device *); +void nouveau_perf_fini(struct drm_device *); +u8 *nouveau_perf_rammap(struct drm_device *, u32 freq, u8 *ver, + u8 *hdr, u8 *cnt, u8 *len); +u8 *nouveau_perf_ramcfg(struct drm_device *, u32 freq, u8 *ver, u8 *len); +u8 *nouveau_perf_timing(struct drm_device *, u32 freq, u8 *ver, u8 *len); + +/* nouveau_mem.c */ +void nouveau_mem_timing_init(struct drm_device *); +void nouveau_mem_timing_fini(struct drm_device *); + +/* nv04_pm.c */ +int nv04_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); +void *nv04_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); +int nv04_pm_clocks_set(struct drm_device *, void *); + +/* nv40_pm.c */ +int nv40_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); +void *nv40_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); +int nv40_pm_clocks_set(struct drm_device *, void *); +int nv40_pm_pwm_get(struct drm_device *, int, u32 *, u32 *); +int nv40_pm_pwm_set(struct drm_device *, int, u32, u32); + +/* nv50_pm.c */ +int nv50_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); +void *nv50_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); +int nv50_pm_clocks_set(struct drm_device *, void *); +int nv50_pm_pwm_get(struct drm_device *, int, u32 *, u32 *); +int nv50_pm_pwm_set(struct drm_device *, int, u32, u32); + +/* nva3_pm.c */ +int nva3_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); +void *nva3_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); +int nva3_pm_clocks_set(struct drm_device *, void *); + +/* nvc0_pm.c */ +int nvc0_pm_clocks_get(struct drm_device *, struct nouveau_pm_level *); +void *nvc0_pm_clocks_pre(struct drm_device *, struct nouveau_pm_level *); +int nvc0_pm_clocks_set(struct drm_device *, void *); + +/* nouveau_mem.c */ +int nouveau_mem_timing_calc(struct drm_device *, u32 freq, + struct nouveau_pm_memtiming *); +void nouveau_mem_timing_read(struct drm_device *, + struct nouveau_pm_memtiming *); + +static inline int +nva3_calc_pll(struct drm_device *dev, struct nvbios_pll *pll, u32 freq, + int *N, int *fN, int *M, int *P) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_clock *clk = nouveau_clock(device); + struct nouveau_pll_vals pv; + int ret; + + ret = clk->pll_calc(clk, pll, freq, &pv); + *N = pv.N1; + *M = pv.M1; + *P = pv.log2P; + return ret; +} + +#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c b/drivers/gpu/drm/nouveau/nouveau_prime.c index 51a2cb1..e90468d 100644 --- a/drivers/gpu/drm/nouveau/nouveau_prime.c +++ b/drivers/gpu/drm/nouveau/nouveau_prime.c @@ -71,16 +71,14 @@ struct drm_gem_object *nouveau_gem_prime_import_sg_table(struct drm_device *dev, return ERR_PTR(ret); nvbo->valid_domains = NOUVEAU_GEM_DOMAIN_GART; - - /* Initialize the embedded gem-object. We return a single gem-reference - * to the caller, instead of a normal nouveau_bo ttm reference. */ - ret = drm_gem_object_init(dev, &nvbo->gem, nvbo->bo.mem.size); - if (ret) { + nvbo->gem = drm_gem_object_alloc(dev, nvbo->bo.mem.size); + if (!nvbo->gem) { nouveau_bo_ref(NULL, &nvbo); return ERR_PTR(-ENOMEM); } - return &nvbo->gem; + nvbo->gem->driver_private = nvbo; + return nvbo->gem; } int nouveau_gem_prime_pin(struct drm_gem_object *obj) diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.c b/drivers/gpu/drm/nouveau/nouveau_sysfs.c deleted file mode 100644 index 89201a1..0000000 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.c +++ /dev/null @@ -1,162 +0,0 @@ -/* - * 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 "nouveau_sysfs.h" - -#include <core/object.h> -#include <core/class.h> - -static inline struct drm_device * -drm_device(struct device *d) -{ - return pci_get_drvdata(to_pci_dev(d)); -} - -#define snappendf(p,r,f,a...) do { \ - snprintf(p, r, f, ##a); \ - r -= strlen(p); \ - p += strlen(p); \ -} while(0) - -static ssize_t -nouveau_sysfs_pstate_get(struct device *d, struct device_attribute *a, char *b) -{ - struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); - struct nv_control_pstate_info info; - size_t cnt = PAGE_SIZE; - char *buf = b; - int ret, i; - - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_INFO, &info, sizeof(info)); - if (ret) - return ret; - - for (i = 0; i < info.count + 1; i++) { - const s32 state = i < info.count ? i : - NV_CONTROL_PSTATE_ATTR_STATE_CURRENT; - struct nv_control_pstate_attr attr = { - .state = state, - .index = 0, - }; - - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, - &attr, sizeof(attr)); - if (ret) - return ret; - - if (i < info.count) - snappendf(buf, cnt, "%02x:", attr.state); - else - snappendf(buf, cnt, "--:"); - - attr.index = 0; - do { - attr.state = state; - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_ATTR, - &attr, sizeof(attr)); - if (ret) - return ret; - - snappendf(buf, cnt, " %s %d", attr.name, attr.min); - if (attr.min != attr.max) - snappendf(buf, cnt, "-%d", attr.max); - snappendf(buf, cnt, " %s", attr.unit); - } while (attr.index); - - if ((state >= 0 && info.pstate == state) || - (state < 0 && info.ustate < 0)) - snappendf(buf, cnt, " *"); - snappendf(buf, cnt, "\n"); - } - - return strlen(b); -} - -static ssize_t -nouveau_sysfs_pstate_set(struct device *d, struct device_attribute *a, - const char *buf, size_t count) -{ - struct nouveau_sysfs *sysfs = nouveau_sysfs(drm_device(d)); - struct nv_control_pstate_user args; - long value, ret; - char *tmp; - - if ((tmp = strchr(buf, '\n'))) - *tmp = '\0'; - - if (!strcasecmp(buf, "none")) - args.state = NV_CONTROL_PSTATE_USER_STATE_UNKNOWN; - else - if (!strcasecmp(buf, "auto")) - args.state = NV_CONTROL_PSTATE_USER_STATE_PERFMON; - else { - ret = kstrtol(buf, 16, &value); - if (ret) - return ret; - args.state = value; - } - - ret = nv_exec(sysfs->ctrl, NV_CONTROL_PSTATE_USER, &args, sizeof(args)); - if (ret < 0) - return ret; - - return count; -} - -static DEVICE_ATTR(pstate, S_IRUGO | S_IWUSR, - nouveau_sysfs_pstate_get, nouveau_sysfs_pstate_set); - -void -nouveau_sysfs_fini(struct drm_device *dev) -{ - struct nouveau_sysfs *sysfs = nouveau_sysfs(dev); - struct nouveau_drm *drm = nouveau_drm(dev); - - if (sysfs->ctrl) { - device_remove_file(&dev->pdev->dev, &dev_attr_pstate); - nouveau_object_del(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL); - } - - drm->sysfs = NULL; - kfree(sysfs); -} - -int -nouveau_sysfs_init(struct drm_device *dev) -{ - struct nouveau_drm *drm = nouveau_drm(dev); - struct nouveau_sysfs *sysfs; - int ret; - - sysfs = drm->sysfs = kzalloc(sizeof(*sysfs), GFP_KERNEL); - if (!sysfs) - return -ENOMEM; - - ret = nouveau_object_new(nv_object(drm), NVDRM_DEVICE, NVDRM_CONTROL, - NV_CONTROL_CLASS, NULL, 0, &sysfs->ctrl); - if (ret == 0) - device_create_file(&dev->pdev->dev, &dev_attr_pstate); - - return 0; -} diff --git a/drivers/gpu/drm/nouveau/nouveau_sysfs.h b/drivers/gpu/drm/nouveau/nouveau_sysfs.h deleted file mode 100644 index 74b47f1..0000000 --- a/drivers/gpu/drm/nouveau/nouveau_sysfs.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef __NOUVEAU_SYSFS_H__ -#define __NOUVEAU_SYSFS_H__ - -#include "nouveau_drm.h" - -struct nouveau_sysfs { - struct nouveau_object *ctrl; -}; - -static inline struct nouveau_sysfs * -nouveau_sysfs(struct drm_device *dev) -{ - return nouveau_drm(dev)->sysfs; -} - -int nouveau_sysfs_init(struct drm_device *); -void nouveau_sysfs_fini(struct drm_device *); - -#endif diff --git a/drivers/gpu/drm/nouveau/nouveau_volt.c b/drivers/gpu/drm/nouveau/nouveau_volt.c new file mode 100644 index 0000000..9976414 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nouveau_volt.c @@ -0,0 +1,250 @@ +/* + * Copyright 2010 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 <drm/drmP.h> + +#include "nouveau_drm.h" +#include "nouveau_pm.h" + +#include <subdev/bios/gpio.h> +#include <subdev/gpio.h> + +static const enum dcb_gpio_func_name vidtag[] = { 0x04, 0x05, 0x06, 0x1a, 0x73 }; +static int nr_vidtag = sizeof(vidtag) / sizeof(vidtag[0]); + +int +nouveau_voltage_gpio_get(struct drm_device *dev) +{ + struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage; + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_gpio *gpio = nouveau_gpio(device); + u8 vid = 0; + int i; + + for (i = 0; i < nr_vidtag; i++) { + if (!(volt->vid_mask & (1 << i))) + continue; + + vid |= gpio->get(gpio, 0, vidtag[i], 0xff) << i; + } + + return nouveau_volt_lvl_lookup(dev, vid); +} + +int +nouveau_voltage_gpio_set(struct drm_device *dev, int voltage) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_gpio *gpio = nouveau_gpio(device); + struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage; + int vid, i; + + vid = nouveau_volt_vid_lookup(dev, voltage); + if (vid < 0) + return vid; + + for (i = 0; i < nr_vidtag; i++) { + if (!(volt->vid_mask & (1 << i))) + continue; + + gpio->set(gpio, 0, vidtag[i], 0xff, !!(vid & (1 << i))); + } + + return 0; +} + +int +nouveau_volt_vid_lookup(struct drm_device *dev, int voltage) +{ + struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage; + int i; + + for (i = 0; i < volt->nr_level; i++) { + if (volt->level[i].voltage == voltage) + return volt->level[i].vid; + } + + return -ENOENT; +} + +int +nouveau_volt_lvl_lookup(struct drm_device *dev, int vid) +{ + struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage; + int i; + + for (i = 0; i < volt->nr_level; i++) { + if (volt->level[i].vid == vid) + return volt->level[i].voltage; + } + + return -ENOENT; +} + +void +nouveau_volt_init(struct drm_device *dev) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_gpio *gpio = nouveau_gpio(drm->device); + struct nouveau_pm *pm = nouveau_pm(dev); + struct nouveau_pm_voltage *voltage = &pm->voltage; + struct nvbios *bios = &drm->vbios; + struct dcb_gpio_func func; + struct bit_entry P; + u8 *volt = NULL, *entry; + int i, headerlen, recordlen, entries, vidmask, vidshift; + + if (bios->type == NVBIOS_BIT) { + if (bit_table(dev, 'P', &P)) + return; + + if (P.version == 1) + volt = ROMPTR(dev, P.data[16]); + else + if (P.version == 2) + volt = ROMPTR(dev, P.data[12]); + else { + NV_WARN(drm, "unknown volt for BIT P %d\n", P.version); + } + } else { + if (bios->data[bios->offset + 6] < 0x27) { + NV_DEBUG(drm, "BMP version too old for voltage\n"); + return; + } + + volt = ROMPTR(dev, bios->data[bios->offset + 0x98]); + } + + if (!volt) { + NV_DEBUG(drm, "voltage table pointer invalid\n"); + return; + } + + switch (volt[0]) { + case 0x10: + case 0x11: + case 0x12: + headerlen = 5; + recordlen = volt[1]; + entries = volt[2]; + vidshift = 0; + vidmask = volt[4]; + break; + case 0x20: + headerlen = volt[1]; + recordlen = volt[3]; + entries = volt[2]; + vidshift = 0; /* could be vidshift like 0x30? */ + vidmask = volt[5]; + break; + case 0x30: + headerlen = volt[1]; + recordlen = volt[2]; + entries = volt[3]; + vidmask = volt[4]; + /* no longer certain what volt[5] is, if it's related to + * the vid shift then it's definitely not a function of + * how many bits are set. + * + * after looking at a number of nva3+ vbios images, they + * all seem likely to have a static shift of 2.. lets + * go with that for now until proven otherwise. + */ + vidshift = 2; + break; + case 0x40: + headerlen = volt[1]; + recordlen = volt[2]; + entries = volt[3]; /* not a clue what the entries are for.. */ + vidmask = volt[11]; /* guess.. */ + vidshift = 0; + break; + default: + NV_WARN(drm, "voltage table 0x%02x unknown\n", volt[0]); + return; + } + + /* validate vid mask */ + voltage->vid_mask = vidmask; + if (!voltage->vid_mask) + return; + + i = 0; + while (vidmask) { + if (i > nr_vidtag) { + NV_DEBUG(drm, "vid bit %d unknown\n", i); + return; + } + + if (gpio && gpio->find(gpio, 0, vidtag[i], 0xff, &func)) { + NV_DEBUG(drm, "vid bit %d has no gpio tag\n", i); + return; + } + + vidmask >>= 1; + i++; + } + + /* parse vbios entries into common format */ + voltage->version = volt[0]; + if (voltage->version < 0x40) { + voltage->nr_level = entries; + voltage->level = + kcalloc(entries, sizeof(*voltage->level), GFP_KERNEL); + if (!voltage->level) + return; + + entry = volt + headerlen; + for (i = 0; i < entries; i++, entry += recordlen) { + voltage->level[i].voltage = entry[0] * 10000; + voltage->level[i].vid = entry[1] >> vidshift; + } + } else { + u32 volt_uv = ROM32(volt[4]); + s16 step_uv = ROM16(volt[8]); + u8 vid; + + voltage->nr_level = voltage->vid_mask + 1; + voltage->level = kcalloc(voltage->nr_level, + sizeof(*voltage->level), GFP_KERNEL); + if (!voltage->level) + return; + + for (vid = 0; vid <= voltage->vid_mask; vid++) { + voltage->level[vid].voltage = volt_uv; + voltage->level[vid].vid = vid; + volt_uv += step_uv; + } + } + + voltage->supported = true; +} + +void +nouveau_volt_fini(struct drm_device *dev) +{ + struct nouveau_pm_voltage *volt = &nouveau_pm(dev)->voltage; + + kfree(volt->level); +} diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index 8fe32bb..77dcc9c 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c @@ -255,12 +255,6 @@ nv04_fbcon_accel_init(struct fb_info *info) OUT_RING(chan, NvCtxSurf2D); BEGIN_NV04(chan, NvSubImageBlit, 0x02fc, 1); OUT_RING(chan, 3); - if (device->chipset >= 0x11 /*XXX: oclass == 0x009f*/) { - BEGIN_NV04(chan, NvSubImageBlit, 0x0120, 3); - OUT_RING(chan, 0); - OUT_RING(chan, 1); - OUT_RING(chan, 2); - } BEGIN_NV04(chan, NvSubGdiRect, 0x0000, 1); OUT_RING(chan, NvGdiRect); diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c new file mode 100644 index 0000000..27afc0e --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv04_pm.c @@ -0,0 +1,146 @@ +/* + * Copyright 2010 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 <drm/drmP.h> +#include "nouveau_drm.h" +#include "nouveau_reg.h" +#include "dispnv04/hw.h" +#include "nouveau_pm.h" + +#include <subdev/bios/pll.h> +#include <subdev/clock.h> +#include <subdev/timer.h> + +int +nv04_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + int ret; + + ret = nouveau_hw_get_clock(dev, PLL_CORE); + if (ret < 0) + return ret; + perflvl->core = ret; + + ret = nouveau_hw_get_clock(dev, PLL_MEMORY); + if (ret < 0) + return ret; + perflvl->memory = ret; + + return 0; +} + +struct nv04_pm_clock { + struct nvbios_pll pll; + struct nouveau_pll_vals calc; +}; + +struct nv04_pm_state { + struct nv04_pm_clock core; + struct nv04_pm_clock memory; +}; + +static int +calc_pll(struct drm_device *dev, u32 id, int khz, struct nv04_pm_clock *clk) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_bios *bios = nouveau_bios(device); + struct nouveau_clock *pclk = nouveau_clock(device); + int ret; + + ret = nvbios_pll_parse(bios, id, &clk->pll); + if (ret) + return ret; + + ret = pclk->pll_calc(pclk, &clk->pll, khz, &clk->calc); + if (!ret) + return -EINVAL; + + return 0; +} + +void * +nv04_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nv04_pm_state *info; + int ret; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + + ret = calc_pll(dev, PLL_CORE, perflvl->core, &info->core); + if (ret) + goto error; + + if (perflvl->memory) { + ret = calc_pll(dev, PLL_MEMORY, perflvl->memory, &info->memory); + if (ret) + goto error; + } + + return info; +error: + kfree(info); + return ERR_PTR(ret); +} + +static void +prog_pll(struct drm_device *dev, struct nv04_pm_clock *clk) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_clock *pclk = nouveau_clock(device); + u32 reg = clk->pll.reg; + + /* thank the insane nouveau_hw_setpll() interface for this */ + if (device->card_type >= NV_40) + reg += 4; + + pclk->pll_prog(pclk, reg, &clk->calc); +} + +int +nv04_pm_clocks_set(struct drm_device *dev, void *pre_state) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_timer *ptimer = nouveau_timer(device); + struct nv04_pm_state *state = pre_state; + + prog_pll(dev, &state->core); + + if (state->memory.pll.reg) { + prog_pll(dev, &state->memory); + if (device->card_type < NV_30) { + if (device->card_type == NV_20) + nv_mask(device, 0x1002c4, 0, 1 << 20); + + /* Reset the DLLs */ + nv_mask(device, 0x1002c0, 0, 1 << 8); + } + } + + nv_ofuncs(ptimer)->init(nv_object(ptimer)); + + kfree(state); + return 0; +} diff --git a/drivers/gpu/drm/nouveau/nv40_pm.c b/drivers/gpu/drm/nouveau/nv40_pm.c new file mode 100644 index 0000000..625f80d --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv40_pm.c @@ -0,0 +1,353 @@ +/* + * Copyright 2011 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 <drm/drmP.h> +#include "nouveau_drm.h" +#include "nouveau_bios.h" +#include "nouveau_pm.h" +#include "dispnv04/hw.h" + +#include <subdev/bios/pll.h> +#include <subdev/clock.h> +#include <subdev/timer.h> + +#include <engine/fifo.h> + +#define min2(a,b) ((a) < (b) ? (a) : (b)) + +static u32 +read_pll_1(struct drm_device *dev, u32 reg) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 ctrl = nv_rd32(device, reg + 0x00); + int P = (ctrl & 0x00070000) >> 16; + int N = (ctrl & 0x0000ff00) >> 8; + int M = (ctrl & 0x000000ff) >> 0; + u32 ref = 27000, clk = 0; + + if (ctrl & 0x80000000) + clk = ref * N / M; + + return clk >> P; +} + +static u32 +read_pll_2(struct drm_device *dev, u32 reg) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 ctrl = nv_rd32(device, reg + 0x00); + u32 coef = nv_rd32(device, reg + 0x04); + int N2 = (coef & 0xff000000) >> 24; + int M2 = (coef & 0x00ff0000) >> 16; + int N1 = (coef & 0x0000ff00) >> 8; + int M1 = (coef & 0x000000ff) >> 0; + int P = (ctrl & 0x00070000) >> 16; + u32 ref = 27000, clk = 0; + + if ((ctrl & 0x80000000) && M1) { + clk = ref * N1 / M1; + if ((ctrl & 0x40000100) == 0x40000000) { + if (M2) + clk = clk * N2 / M2; + else + clk = 0; + } + } + + return clk >> P; +} + +static u32 +read_clk(struct drm_device *dev, u32 src) +{ + switch (src) { + case 3: + return read_pll_2(dev, 0x004000); + case 2: + return read_pll_1(dev, 0x004008); + default: + break; + } + + return 0; +} + +int +nv40_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 ctrl = nv_rd32(device, 0x00c040); + + perflvl->core = read_clk(dev, (ctrl & 0x00000003) >> 0); + perflvl->shader = read_clk(dev, (ctrl & 0x00000030) >> 4); + perflvl->memory = read_pll_2(dev, 0x4020); + return 0; +} + +struct nv40_pm_state { + u32 ctrl; + u32 npll_ctrl; + u32 npll_coef; + u32 spll; + u32 mpll_ctrl; + u32 mpll_coef; +}; + +static int +nv40_calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll, + u32 clk, int *N1, int *M1, int *N2, int *M2, int *log2P) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_bios *bios = nouveau_bios(device); + struct nouveau_clock *pclk = nouveau_clock(device); + struct nouveau_pll_vals coef; + int ret; + + ret = nvbios_pll_parse(bios, reg, pll); + if (ret) + return ret; + + if (clk < pll->vco1.max_freq) + pll->vco2.max_freq = 0; + + ret = pclk->pll_calc(pclk, pll, clk, &coef); + if (ret == 0) + return -ERANGE; + + *N1 = coef.N1; + *M1 = coef.M1; + if (N2 && M2) { + if (pll->vco2.max_freq) { + *N2 = coef.N2; + *M2 = coef.M2; + } else { + *N2 = 1; + *M2 = 1; + } + } + *log2P = coef.log2P; + return 0; +} + +void * +nv40_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nv40_pm_state *info; + struct nvbios_pll pll; + int N1, N2, M1, M2, log2P; + int ret; + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + + /* core/geometric clock */ + ret = nv40_calc_pll(dev, 0x004000, &pll, perflvl->core, + &N1, &M1, &N2, &M2, &log2P); + if (ret < 0) + goto out; + + if (N2 == M2) { + info->npll_ctrl = 0x80000100 | (log2P << 16); + info->npll_coef = (N1 << 8) | M1; + } else { + info->npll_ctrl = 0xc0000000 | (log2P << 16); + info->npll_coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1; + } + + /* use the second PLL for shader/rop clock, if it differs from core */ + if (perflvl->shader && perflvl->shader != perflvl->core) { + ret = nv40_calc_pll(dev, 0x004008, &pll, perflvl->shader, + &N1, &M1, NULL, NULL, &log2P); + if (ret < 0) + goto out; + + info->spll = 0xc0000000 | (log2P << 16) | (N1 << 8) | M1; + info->ctrl = 0x00000223; + } else { + info->spll = 0x00000000; + info->ctrl = 0x00000333; + } + + /* memory clock */ + if (!perflvl->memory) { + info->mpll_ctrl = 0x00000000; + goto out; + } + + ret = nv40_calc_pll(dev, 0x004020, &pll, perflvl->memory, + &N1, &M1, &N2, &M2, &log2P); + if (ret < 0) + goto out; + + info->mpll_ctrl = 0x80000000 | (log2P << 16); + info->mpll_ctrl |= min2(pll.bias_p + log2P, pll.max_p) << 20; + if (N2 == M2) { + info->mpll_ctrl |= 0x00000100; + info->mpll_coef = (N1 << 8) | M1; + } else { + info->mpll_ctrl |= 0x40000000; + info->mpll_coef = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1; + } + +out: + if (ret < 0) { + kfree(info); + info = ERR_PTR(ret); + } + return info; +} + +static bool +nv40_pm_gr_idle(void *data) +{ + struct drm_device *dev = data; + struct nouveau_device *device = nouveau_dev(dev); + + if ((nv_rd32(device, 0x400760) & 0x000000f0) >> 4 != + (nv_rd32(device, 0x400760) & 0x0000000f)) + return false; + + if (nv_rd32(device, 0x400700)) + return false; + + return true; +} + +int +nv40_pm_clocks_set(struct drm_device *dev, void *pre_state) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_fifo *pfifo = nouveau_fifo(device); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nv40_pm_state *info = pre_state; + unsigned long flags; + struct bit_entry M; + u32 crtc_mask = 0; + u8 sr1[2]; + int i, ret = -EAGAIN; + + /* determine which CRTCs are active, fetch VGA_SR1 for each */ + for (i = 0; i < 2; i++) { + u32 vbl = nv_rd32(device, 0x600808 + (i * 0x2000)); + u32 cnt = 0; + do { + if (vbl != nv_rd32(device, 0x600808 + (i * 0x2000))) { + nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01); + sr1[i] = nv_rd08(device, 0x0c03c5 + (i * 0x2000)); + if (!(sr1[i] & 0x20)) + crtc_mask |= (1 << i); + break; + } + udelay(1); + } while (cnt++ < 32); + } + + /* halt and idle engines */ + pfifo->pause(pfifo, &flags); + + if (!nv_wait_cb(device, nv40_pm_gr_idle, dev)) + goto resume; + + ret = 0; + + /* set engine clocks */ + nv_mask(device, 0x00c040, 0x00000333, 0x00000000); + nv_wr32(device, 0x004004, info->npll_coef); + nv_mask(device, 0x004000, 0xc0070100, info->npll_ctrl); + nv_mask(device, 0x004008, 0xc007ffff, info->spll); + mdelay(5); + nv_mask(device, 0x00c040, 0x00000333, info->ctrl); + + if (!info->mpll_ctrl) + goto resume; + + /* wait for vblank start on active crtcs, disable memory access */ + for (i = 0; i < 2; i++) { + if (!(crtc_mask & (1 << i))) + continue; + nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000); + nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000); + nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01); + nv_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20); + } + + /* prepare ram for reclocking */ + nv_wr32(device, 0x1002d4, 0x00000001); /* precharge */ + nv_wr32(device, 0x1002d0, 0x00000001); /* refresh */ + nv_wr32(device, 0x1002d0, 0x00000001); /* refresh */ + nv_mask(device, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */ + nv_wr32(device, 0x1002dc, 0x00000001); /* enable self-refresh */ + + /* change the PLL of each memory partition */ + nv_mask(device, 0x00c040, 0x0000c000, 0x00000000); + switch (nv_device(drm->device)->chipset) { + case 0x40: + case 0x45: + case 0x41: + case 0x42: + case 0x47: + nv_mask(device, 0x004044, 0xc0771100, info->mpll_ctrl); + nv_mask(device, 0x00402c, 0xc0771100, info->mpll_ctrl); + nv_wr32(device, 0x004048, info->mpll_coef); + nv_wr32(device, 0x004030, info->mpll_coef); + case 0x43: + case 0x49: + case 0x4b: + nv_mask(device, 0x004038, 0xc0771100, info->mpll_ctrl); + nv_wr32(device, 0x00403c, info->mpll_coef); + default: + nv_mask(device, 0x004020, 0xc0771100, info->mpll_ctrl); + nv_wr32(device, 0x004024, info->mpll_coef); + break; + } + udelay(100); + nv_mask(device, 0x00c040, 0x0000c000, 0x0000c000); + + /* re-enable normal operation of memory controller */ + nv_wr32(device, 0x1002dc, 0x00000000); + nv_mask(device, 0x100210, 0x80000000, 0x80000000); + udelay(100); + + /* execute memory reset script from vbios */ + if (!bit_table(dev, 'M', &M)) + nouveau_bios_run_init_table(dev, ROM16(M.data[0]), NULL, 0); + + /* make sure we're in vblank (hopefully the same one as before), and + * then re-enable crtc memory access + */ + for (i = 0; i < 2; i++) { + if (!(crtc_mask & (1 << i))) + continue; + nv_wait(device, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000); + nv_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01); + nv_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i]); + } + + /* resume engines */ +resume: + pfifo->start(pfifo, &flags); + kfree(info); + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 4e384a2..f8e66c0 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c @@ -1265,7 +1265,7 @@ nv50_crtc_gamma_set(struct drm_crtc *crtc, u16 *r, u16 *g, u16 *b, uint32_t start, uint32_t size) { struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); - u32 end = min_t(u32, start + size, 256); + u32 end = max(start + size, (u32)256); u32 i; for (i = start; i < end; i++) { diff --git a/drivers/gpu/drm/nouveau/nv50_pm.c b/drivers/gpu/drm/nouveau/nv50_pm.c new file mode 100644 index 0000000..4efc33f --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_pm.c @@ -0,0 +1,855 @@ +/* + * Copyright 2010 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 <drm/drmP.h> +#include "nouveau_drm.h" +#include "nouveau_bios.h" +#include "dispnv04/hw.h" +#include "nouveau_pm.h" +#include "nouveau_hwsq.h" + +#include "nv50_display.h" + +#include <subdev/bios/pll.h> +#include <subdev/clock.h> +#include <subdev/timer.h> +#include <subdev/fb.h> + +enum clk_src { + clk_src_crystal, + clk_src_href, + clk_src_hclk, + clk_src_hclkm3, + clk_src_hclkm3d2, + clk_src_host, + clk_src_nvclk, + clk_src_sclk, + clk_src_mclk, + clk_src_vdec, + clk_src_dom6 +}; + +static u32 read_clk(struct drm_device *, enum clk_src); + +static u32 +read_div(struct drm_device *dev) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + + switch (nv_device(drm->device)->chipset) { + case 0x50: /* it exists, but only has bit 31, not the dividers.. */ + case 0x84: + case 0x86: + case 0x98: + case 0xa0: + return nv_rd32(device, 0x004700); + case 0x92: + case 0x94: + case 0x96: + return nv_rd32(device, 0x004800); + default: + return 0x00000000; + } +} + +static u32 +read_pll_src(struct drm_device *dev, u32 base) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + u32 coef, ref = read_clk(dev, clk_src_crystal); + u32 rsel = nv_rd32(device, 0x00e18c); + int P, N, M, id; + + switch (nv_device(drm->device)->chipset) { + case 0x50: + case 0xa0: + switch (base) { + case 0x4020: + case 0x4028: id = !!(rsel & 0x00000004); break; + case 0x4008: id = !!(rsel & 0x00000008); break; + case 0x4030: id = 0; break; + default: + NV_ERROR(drm, "ref: bad pll 0x%06x\n", base); + return 0; + } + + coef = nv_rd32(device, 0x00e81c + (id * 0x0c)); + ref *= (coef & 0x01000000) ? 2 : 4; + P = (coef & 0x00070000) >> 16; + N = ((coef & 0x0000ff00) >> 8) + 1; + M = ((coef & 0x000000ff) >> 0) + 1; + break; + case 0x84: + case 0x86: + case 0x92: + coef = nv_rd32(device, 0x00e81c); + P = (coef & 0x00070000) >> 16; + N = (coef & 0x0000ff00) >> 8; + M = (coef & 0x000000ff) >> 0; + break; + case 0x94: + case 0x96: + case 0x98: + rsel = nv_rd32(device, 0x00c050); + switch (base) { + case 0x4020: rsel = (rsel & 0x00000003) >> 0; break; + case 0x4008: rsel = (rsel & 0x0000000c) >> 2; break; + case 0x4028: rsel = (rsel & 0x00001800) >> 11; break; + case 0x4030: rsel = 3; break; + default: + NV_ERROR(drm, "ref: bad pll 0x%06x\n", base); + return 0; + } + + switch (rsel) { + case 0: id = 1; break; + case 1: return read_clk(dev, clk_src_crystal); + case 2: return read_clk(dev, clk_src_href); + case 3: id = 0; break; + } + + coef = nv_rd32(device, 0x00e81c + (id * 0x28)); + P = (nv_rd32(device, 0x00e824 + (id * 0x28)) >> 16) & 7; + P += (coef & 0x00070000) >> 16; + N = (coef & 0x0000ff00) >> 8; + M = (coef & 0x000000ff) >> 0; + break; + default: + BUG_ON(1); + } + + if (M) + return (ref * N / M) >> P; + return 0; +} + +static u32 +read_pll_ref(struct drm_device *dev, u32 base) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + u32 src, mast = nv_rd32(device, 0x00c040); + + switch (base) { + case 0x004028: + src = !!(mast & 0x00200000); + break; + case 0x004020: + src = !!(mast & 0x00400000); + break; + case 0x004008: + src = !!(mast & 0x00010000); + break; + case 0x004030: + src = !!(mast & 0x02000000); + break; + case 0x00e810: + return read_clk(dev, clk_src_crystal); + default: + NV_ERROR(drm, "bad pll 0x%06x\n", base); + return 0; + } + + if (src) + return read_clk(dev, clk_src_href); + return read_pll_src(dev, base); +} + +static u32 +read_pll(struct drm_device *dev, u32 base) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + u32 mast = nv_rd32(device, 0x00c040); + u32 ctrl = nv_rd32(device, base + 0); + u32 coef = nv_rd32(device, base + 4); + u32 ref = read_pll_ref(dev, base); + u32 clk = 0; + int N1, N2, M1, M2; + + if (base == 0x004028 && (mast & 0x00100000)) { + /* wtf, appears to only disable post-divider on nva0 */ + if (nv_device(drm->device)->chipset != 0xa0) + return read_clk(dev, clk_src_dom6); + } + + N2 = (coef & 0xff000000) >> 24; + M2 = (coef & 0x00ff0000) >> 16; + N1 = (coef & 0x0000ff00) >> 8; + M1 = (coef & 0x000000ff); + if ((ctrl & 0x80000000) && M1) { + clk = ref * N1 / M1; + if ((ctrl & 0x40000100) == 0x40000000) { + if (M2) + clk = clk * N2 / M2; + else + clk = 0; + } + } + + return clk; +} + +static u32 +read_clk(struct drm_device *dev, enum clk_src src) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + u32 mast = nv_rd32(device, 0x00c040); + u32 P = 0; + + switch (src) { + case clk_src_crystal: + return device->crystal; + case clk_src_href: + return 100000; /* PCIE reference clock */ + case clk_src_hclk: + return read_clk(dev, clk_src_href) * 27778 / 10000; + case clk_src_hclkm3: + return read_clk(dev, clk_src_hclk) * 3; + case clk_src_hclkm3d2: + return read_clk(dev, clk_src_hclk) * 3 / 2; + case clk_src_host: + switch (mast & 0x30000000) { + case 0x00000000: return read_clk(dev, clk_src_href); + case 0x10000000: break; + case 0x20000000: /* !0x50 */ + case 0x30000000: return read_clk(dev, clk_src_hclk); + } + break; + case clk_src_nvclk: + if (!(mast & 0x00100000)) + P = (nv_rd32(device, 0x004028) & 0x00070000) >> 16; + switch (mast & 0x00000003) { + case 0x00000000: return read_clk(dev, clk_src_crystal) >> P; + case 0x00000001: return read_clk(dev, clk_src_dom6); + case 0x00000002: return read_pll(dev, 0x004020) >> P; + case 0x00000003: return read_pll(dev, 0x004028) >> P; + } + break; + case clk_src_sclk: + P = (nv_rd32(device, 0x004020) & 0x00070000) >> 16; + switch (mast & 0x00000030) { + case 0x00000000: + if (mast & 0x00000080) + return read_clk(dev, clk_src_host) >> P; + return read_clk(dev, clk_src_crystal) >> P; + case 0x00000010: break; + case 0x00000020: return read_pll(dev, 0x004028) >> P; + case 0x00000030: return read_pll(dev, 0x004020) >> P; + } + break; + case clk_src_mclk: + P = (nv_rd32(device, 0x004008) & 0x00070000) >> 16; + if (nv_rd32(device, 0x004008) & 0x00000200) { + switch (mast & 0x0000c000) { + case 0x00000000: + return read_clk(dev, clk_src_crystal) >> P; + case 0x00008000: + case 0x0000c000: + return read_clk(dev, clk_src_href) >> P; + } + } else { + return read_pll(dev, 0x004008) >> P; + } + break; + case clk_src_vdec: + P = (read_div(dev) & 0x00000700) >> 8; + switch (nv_device(drm->device)->chipset) { + case 0x84: + case 0x86: + case 0x92: + case 0x94: + case 0x96: + case 0xa0: + switch (mast & 0x00000c00) { + case 0x00000000: + if (nv_device(drm->device)->chipset == 0xa0) /* wtf?? */ + return read_clk(dev, clk_src_nvclk) >> P; + return read_clk(dev, clk_src_crystal) >> P; + case 0x00000400: + return 0; + case 0x00000800: + if (mast & 0x01000000) + return read_pll(dev, 0x004028) >> P; + return read_pll(dev, 0x004030) >> P; + case 0x00000c00: + return read_clk(dev, clk_src_nvclk) >> P; + } + break; + case 0x98: + switch (mast & 0x00000c00) { + case 0x00000000: + return read_clk(dev, clk_src_nvclk) >> P; + case 0x00000400: + return 0; + case 0x00000800: + return read_clk(dev, clk_src_hclkm3d2) >> P; + case 0x00000c00: + return read_clk(dev, clk_src_mclk) >> P; + } + break; + } + break; + case clk_src_dom6: + switch (nv_device(drm->device)->chipset) { + case 0x50: + case 0xa0: + return read_pll(dev, 0x00e810) >> 2; + case 0x84: + case 0x86: + case 0x92: + case 0x94: + case 0x96: + case 0x98: + P = (read_div(dev) & 0x00000007) >> 0; + switch (mast & 0x0c000000) { + case 0x00000000: return read_clk(dev, clk_src_href); + case 0x04000000: break; + case 0x08000000: return read_clk(dev, clk_src_hclk); + case 0x0c000000: + return read_clk(dev, clk_src_hclkm3) >> P; + } + break; + default: + break; + } + default: + break; + } + + NV_DEBUG(drm, "unknown clock source %d 0x%08x\n", src, mast); + return 0; +} + +int +nv50_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + if (nv_device(drm->device)->chipset == 0xaa || + nv_device(drm->device)->chipset == 0xac) + return 0; + + perflvl->core = read_clk(dev, clk_src_nvclk); + perflvl->shader = read_clk(dev, clk_src_sclk); + perflvl->memory = read_clk(dev, clk_src_mclk); + if (nv_device(drm->device)->chipset != 0x50) { + perflvl->vdec = read_clk(dev, clk_src_vdec); + perflvl->dom6 = read_clk(dev, clk_src_dom6); + } + + return 0; +} + +struct nv50_pm_state { + struct nouveau_pm_level *perflvl; + struct hwsq_ucode eclk_hwsq; + struct hwsq_ucode mclk_hwsq; + u32 mscript; + u32 mmast; + u32 mctrl; + u32 mcoef; +}; + +static u32 +calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll, + u32 clk, int *N1, int *M1, int *log2P) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_bios *bios = nouveau_bios(device); + struct nouveau_clock *pclk = nouveau_clock(device); + struct nouveau_pll_vals coef; + int ret; + + ret = nvbios_pll_parse(bios, reg, pll); + if (ret) + return 0; + + pll->vco2.max_freq = 0; + pll->refclk = read_pll_ref(dev, reg); + if (!pll->refclk) + return 0; + + ret = pclk->pll_calc(pclk, pll, clk, &coef); + if (ret == 0) + return 0; + + *N1 = coef.N1; + *M1 = coef.M1; + *log2P = coef.log2P; + return ret; +} + +static inline u32 +calc_div(u32 src, u32 target, int *div) +{ + u32 clk0 = src, clk1 = src; + for (*div = 0; *div <= 7; (*div)++) { + if (clk0 <= target) { + clk1 = clk0 << (*div ? 1 : 0); + break; + } + clk0 >>= 1; + } + + if (target - clk0 <= clk1 - target) + return clk0; + (*div)--; + return clk1; +} + +static inline u32 +clk_same(u32 a, u32 b) +{ + return ((a / 1000) == (b / 1000)); +} + +static void +mclk_precharge(struct nouveau_mem_exec_func *exec) +{ + struct nv50_pm_state *info = exec->priv; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + + hwsq_wr32(hwsq, 0x1002d4, 0x00000001); +} + +static void +mclk_refresh(struct nouveau_mem_exec_func *exec) +{ + struct nv50_pm_state *info = exec->priv; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + + hwsq_wr32(hwsq, 0x1002d0, 0x00000001); +} + +static void +mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable) +{ + struct nv50_pm_state *info = exec->priv; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + + hwsq_wr32(hwsq, 0x100210, enable ? 0x80000000 : 0x00000000); +} + +static void +mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable) +{ + struct nv50_pm_state *info = exec->priv; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + + hwsq_wr32(hwsq, 0x1002dc, enable ? 0x00000001 : 0x00000000); +} + +static void +mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec) +{ + struct nv50_pm_state *info = exec->priv; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + + if (nsec > 1000) + hwsq_usec(hwsq, (nsec + 500) / 1000); +} + +static u32 +mclk_mrg(struct nouveau_mem_exec_func *exec, int mr) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + if (mr <= 1) + return nv_rd32(device, 0x1002c0 + ((mr - 0) * 4)); + if (mr <= 3) + return nv_rd32(device, 0x1002e0 + ((mr - 2) * 4)); + return 0; +} + +static void +mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nouveau_fb *pfb = nouveau_fb(device); + struct nv50_pm_state *info = exec->priv; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + + if (mr <= 1) { + if (pfb->ram->ranks > 1) + hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data); + hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data); + } else + if (mr <= 3) { + if (pfb->ram->ranks > 1) + hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data); + hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data); + } +} + +static void +mclk_clock_set(struct nouveau_mem_exec_func *exec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nv50_pm_state *info = exec->priv; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + u32 ctrl = nv_rd32(device, 0x004008); + + info->mmast = nv_rd32(device, 0x00c040); + info->mmast &= ~0xc0000000; /* get MCLK_2 from HREF */ + info->mmast |= 0x0000c000; /* use MCLK_2 as MPLL_BYPASS clock */ + + hwsq_wr32(hwsq, 0xc040, info->mmast); + hwsq_wr32(hwsq, 0x4008, ctrl | 0x00000200); /* bypass MPLL */ + if (info->mctrl & 0x80000000) + hwsq_wr32(hwsq, 0x400c, info->mcoef); + hwsq_wr32(hwsq, 0x4008, info->mctrl); +} + +static void +mclk_timing_set(struct nouveau_mem_exec_func *exec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nv50_pm_state *info = exec->priv; + struct nouveau_pm_level *perflvl = info->perflvl; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + int i; + + for (i = 0; i < 9; i++) { + u32 reg = 0x100220 + (i * 4); + u32 val = nv_rd32(device, reg); + if (val != perflvl->timing.reg[i]) + hwsq_wr32(hwsq, reg, perflvl->timing.reg[i]); + } +} + +static int +calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl, + struct nv50_pm_state *info) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_device *device = nouveau_dev(dev); + u32 crtc_mask = 0; /*XXX: nv50_display_active_crtcs(dev); */ + struct nouveau_mem_exec_func exec = { + .dev = dev, + .precharge = mclk_precharge, + .refresh = mclk_refresh, + .refresh_auto = mclk_refresh_auto, + .refresh_self = mclk_refresh_self, + .wait = mclk_wait, + .mrg = mclk_mrg, + .mrs = mclk_mrs, + .clock_set = mclk_clock_set, + .timing_set = mclk_timing_set, + .priv = info + }; + struct hwsq_ucode *hwsq = &info->mclk_hwsq; + struct nvbios_pll pll; + int N, M, P; + int ret; + + /* use pcie refclock if possible, otherwise use mpll */ + info->mctrl = nv_rd32(device, 0x004008); + info->mctrl &= ~0x81ff0200; + if (clk_same(perflvl->memory, read_clk(dev, clk_src_href))) { + info->mctrl |= 0x00000200 | (pll.bias_p << 19); + } else { + ret = calc_pll(dev, 0x4008, &pll, perflvl->memory, &N, &M, &P); + if (ret == 0) + return -EINVAL; + + info->mctrl |= 0x80000000 | (P << 22) | (P << 16); + info->mctrl |= pll.bias_p << 19; + info->mcoef = (N << 8) | M; + } + + /* build the ucode which will reclock the memory for us */ + hwsq_init(hwsq); + if (crtc_mask) { + hwsq_op5f(hwsq, crtc_mask, 0x00); /* wait for scanout */ + hwsq_op5f(hwsq, crtc_mask, 0x01); /* wait for vblank */ + } + if (nv_device(drm->device)->chipset >= 0x92) + hwsq_wr32(hwsq, 0x611200, 0x00003300); /* disable scanout */ + hwsq_setf(hwsq, 0x10, 0); /* disable bus access */ + hwsq_op5f(hwsq, 0x00, 0x01); /* no idea :s */ + + ret = nouveau_mem_exec(&exec, perflvl); + if (ret) + return ret; + + hwsq_setf(hwsq, 0x10, 1); /* enable bus access */ + hwsq_op5f(hwsq, 0x00, 0x00); /* no idea, reverse of 0x00, 0x01? */ + if (nv_device(drm->device)->chipset >= 0x92) + hwsq_wr32(hwsq, 0x611200, 0x00003330); /* enable scanout */ + hwsq_fini(hwsq); + return 0; +} + +void * +nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nv50_pm_state *info; + struct hwsq_ucode *hwsq; + struct nvbios_pll pll; + u32 out, mast, divs, ctrl; + int clk, ret = -EINVAL; + int N, M, P1, P2; + + if (nv_device(drm->device)->chipset == 0xaa || + nv_device(drm->device)->chipset == 0xac) + return ERR_PTR(-ENODEV); + + info = kmalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + info->perflvl = perflvl; + + /* memory: build hwsq ucode which we'll use to reclock memory. + * use pcie refclock if possible, otherwise use mpll */ + info->mclk_hwsq.len = 0; + if (perflvl->memory) { + ret = calc_mclk(dev, perflvl, info); + if (ret) + goto error; + info->mscript = perflvl->memscript; + } + + divs = read_div(dev); + mast = info->mmast; + + /* start building HWSQ script for engine reclocking */ + hwsq = &info->eclk_hwsq; + hwsq_init(hwsq); + hwsq_setf(hwsq, 0x10, 0); /* disable bus access */ + hwsq_op5f(hwsq, 0x00, 0x01); /* wait for access disabled? */ + + /* vdec/dom6: switch to "safe" clocks temporarily */ + if (perflvl->vdec) { + mast &= ~0x00000c00; + divs &= ~0x00000700; + } + + if (perflvl->dom6) { + mast &= ~0x0c000000; + divs &= ~0x00000007; + } + + hwsq_wr32(hwsq, 0x00c040, mast); + + /* vdec: avoid modifying xpll until we know exactly how the other + * clock domains work, i suspect at least some of them can also be + * tied to xpll... + */ + if (perflvl->vdec) { + /* see how close we can get using nvclk as a source */ + clk = calc_div(perflvl->core, perflvl->vdec, &P1); + + /* see how close we can get using xpll/hclk as a source */ + if (nv_device(drm->device)->chipset != 0x98) + out = read_pll(dev, 0x004030); + else + out = read_clk(dev, clk_src_hclkm3d2); + out = calc_div(out, perflvl->vdec, &P2); + + /* select whichever gets us closest */ + if (abs((int)perflvl->vdec - clk) <= + abs((int)perflvl->vdec - out)) { + if (nv_device(drm->device)->chipset != 0x98) + mast |= 0x00000c00; + divs |= P1 << 8; + } else { + mast |= 0x00000800; + divs |= P2 << 8; + } + } + + /* dom6: nfi what this is, but we're limited to various combinations + * of the host clock frequency + */ + if (perflvl->dom6) { + if (clk_same(perflvl->dom6, read_clk(dev, clk_src_href))) { + mast |= 0x00000000; + } else + if (clk_same(perflvl->dom6, read_clk(dev, clk_src_hclk))) { + mast |= 0x08000000; + } else { + clk = read_clk(dev, clk_src_hclk) * 3; + clk = calc_div(clk, perflvl->dom6, &P1); + + mast |= 0x0c000000; + divs |= P1; + } + } + + /* vdec/dom6: complete switch to new clocks */ + switch (nv_device(drm->device)->chipset) { + case 0x92: + case 0x94: + case 0x96: + hwsq_wr32(hwsq, 0x004800, divs); + break; + default: + hwsq_wr32(hwsq, 0x004700, divs); + break; + } + + hwsq_wr32(hwsq, 0x00c040, mast); + + /* core/shader: make sure sclk/nvclk are disconnected from their + * PLLs (nvclk to dom6, sclk to hclk) + */ + if (nv_device(drm->device)->chipset < 0x92) + mast = (mast & ~0x001000b0) | 0x00100080; + else + mast = (mast & ~0x000000b3) | 0x00000081; + + hwsq_wr32(hwsq, 0x00c040, mast); + + /* core: for the moment at least, always use nvpll */ + clk = calc_pll(dev, 0x4028, &pll, perflvl->core, &N, &M, &P1); + if (clk == 0) + goto error; + + ctrl = nv_rd32(device, 0x004028) & ~0xc03f0100; + mast &= ~0x00100000; + mast |= 3; + + hwsq_wr32(hwsq, 0x004028, 0x80000000 | (P1 << 19) | (P1 << 16) | ctrl); + hwsq_wr32(hwsq, 0x00402c, (N << 8) | M); + + /* shader: tie to nvclk if possible, otherwise use spll. have to be + * very careful that the shader clock is at least twice the core, or + * some chipsets will be very unhappy. i expect most or all of these + * cases will be handled by tying to nvclk, but it's possible there's + * corners + */ + ctrl = nv_rd32(device, 0x004020) & ~0xc03f0100; + + if (P1-- && perflvl->shader == (perflvl->core << 1)) { + hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl); + hwsq_wr32(hwsq, 0x00c040, 0x00000020 | mast); + } else { + clk = calc_pll(dev, 0x4020, &pll, perflvl->shader, &N, &M, &P1); + if (clk == 0) + goto error; + ctrl |= 0x80000000; + + hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl); + hwsq_wr32(hwsq, 0x004024, (N << 8) | M); + hwsq_wr32(hwsq, 0x00c040, 0x00000030 | mast); + } + + hwsq_setf(hwsq, 0x10, 1); /* enable bus access */ + hwsq_op5f(hwsq, 0x00, 0x00); /* wait for access enabled? */ + hwsq_fini(hwsq); + + return info; +error: + kfree(info); + return ERR_PTR(ret); +} + +static int +prog_hwsq(struct drm_device *dev, struct hwsq_ucode *hwsq) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + u32 hwsq_data, hwsq_kick; + int i; + + if (nv_device(drm->device)->chipset < 0x94) { + hwsq_data = 0x001400; + hwsq_kick = 0x00000003; + } else { + hwsq_data = 0x080000; + hwsq_kick = 0x00000001; + } + /* upload hwsq ucode */ + nv_mask(device, 0x001098, 0x00000008, 0x00000000); + nv_wr32(device, 0x001304, 0x00000000); + if (nv_device(drm->device)->chipset >= 0x92) + nv_wr32(device, 0x001318, 0x00000000); + for (i = 0; i < hwsq->len / 4; i++) + nv_wr32(device, hwsq_data + (i * 4), hwsq->ptr.u32[i]); + nv_mask(device, 0x001098, 0x00000018, 0x00000018); + + /* launch, and wait for completion */ + nv_wr32(device, 0x00130c, hwsq_kick); + if (!nv_wait(device, 0x001308, 0x00000100, 0x00000000)) { + NV_ERROR(drm, "hwsq ucode exec timed out\n"); + NV_ERROR(drm, "0x001308: 0x%08x\n", nv_rd32(device, 0x001308)); + for (i = 0; i < hwsq->len / 4; i++) { + NV_ERROR(drm, "0x%06x: 0x%08x\n", 0x1400 + (i * 4), + nv_rd32(device, 0x001400 + (i * 4))); + } + + return -EIO; + } + + return 0; +} + +int +nv50_pm_clocks_set(struct drm_device *dev, void *data) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nv50_pm_state *info = data; + struct bit_entry M; + int ret = -EBUSY; + + /* halt and idle execution engines */ + nv_mask(device, 0x002504, 0x00000001, 0x00000001); + if (!nv_wait(device, 0x002504, 0x00000010, 0x00000010)) + goto resume; + if (!nv_wait(device, 0x00251c, 0x0000003f, 0x0000003f)) + goto resume; + + /* program memory clock, if necessary - must come before engine clock + * reprogramming due to how we construct the hwsq scripts in pre() + */ +#define nouveau_bios_init_exec(a,b) nouveau_bios_run_init_table((a), (b), NULL, 0) + if (info->mclk_hwsq.len) { + /* execute some scripts that do ??? from the vbios.. */ + if (!bit_table(dev, 'M', &M) && M.version == 1) { + if (M.length >= 6) + nouveau_bios_init_exec(dev, ROM16(M.data[5])); + if (M.length >= 8) + nouveau_bios_init_exec(dev, ROM16(M.data[7])); + if (M.length >= 10) + nouveau_bios_init_exec(dev, ROM16(M.data[9])); + nouveau_bios_init_exec(dev, info->mscript); + } + + ret = prog_hwsq(dev, &info->mclk_hwsq); + if (ret) + goto resume; + } + + /* program engine clocks */ + ret = prog_hwsq(dev, &info->eclk_hwsq); + +resume: + nv_mask(device, 0x002504, 0x00000001, 0x00000000); + kfree(info); + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c new file mode 100644 index 0000000..0d0ed59 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nva3_pm.c @@ -0,0 +1,624 @@ +/* + * Copyright 2010 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 <drm/drmP.h> +#include "nouveau_drm.h" +#include "nouveau_bios.h" +#include "nouveau_pm.h" + +#include <subdev/bios/pll.h> +#include <subdev/bios.h> +#include <subdev/clock.h> +#include <subdev/timer.h> +#include <subdev/fb.h> + +static u32 read_clk(struct drm_device *, int, bool); +static u32 read_pll(struct drm_device *, int, u32); + +static u32 +read_vco(struct drm_device *dev, int clk) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 sctl = nv_rd32(device, 0x4120 + (clk * 4)); + if ((sctl & 0x00000030) != 0x00000030) + return read_pll(dev, 0x41, 0x00e820); + return read_pll(dev, 0x42, 0x00e8a0); +} + +static u32 +read_clk(struct drm_device *dev, int clk, bool ignore_en) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + u32 sctl, sdiv, sclk; + + /* refclk for the 0xe8xx plls is a fixed frequency */ + if (clk >= 0x40) { + if (nv_device(drm->device)->chipset == 0xaf) { + /* no joke.. seriously.. sigh.. */ + return nv_rd32(device, 0x00471c) * 1000; + } + + return device->crystal; + } + + sctl = nv_rd32(device, 0x4120 + (clk * 4)); + if (!ignore_en && !(sctl & 0x00000100)) + return 0; + + switch (sctl & 0x00003000) { + case 0x00000000: + return device->crystal; + case 0x00002000: + if (sctl & 0x00000040) + return 108000; + return 100000; + case 0x00003000: + sclk = read_vco(dev, clk); + sdiv = ((sctl & 0x003f0000) >> 16) + 2; + return (sclk * 2) / sdiv; + default: + return 0; + } +} + +static u32 +read_pll(struct drm_device *dev, int clk, u32 pll) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 ctrl = nv_rd32(device, pll + 0); + u32 sclk = 0, P = 1, N = 1, M = 1; + + if (!(ctrl & 0x00000008)) { + if (ctrl & 0x00000001) { + u32 coef = nv_rd32(device, pll + 4); + M = (coef & 0x000000ff) >> 0; + N = (coef & 0x0000ff00) >> 8; + P = (coef & 0x003f0000) >> 16; + + /* no post-divider on these.. */ + if ((pll & 0x00ff00) == 0x00e800) + P = 1; + + sclk = read_clk(dev, 0x00 + clk, false); + } + } else { + sclk = read_clk(dev, 0x10 + clk, false); + } + + if (M * P) + return sclk * N / (M * P); + return 0; +} + +struct creg { + u32 clk; + u32 pll; +}; + +static int +calc_clk(struct drm_device *dev, int clk, u32 pll, u32 khz, struct creg *reg) +{ + struct nouveau_drm *drm = nouveau_drm(dev); + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_bios *bios = nouveau_bios(device); + struct nvbios_pll limits; + u32 oclk, sclk, sdiv; + int P, N, M, diff; + int ret; + + reg->pll = 0; + reg->clk = 0; + if (!khz) { + NV_DEBUG(drm, "no clock for 0x%04x/0x%02x\n", pll, clk); + return 0; + } + + switch (khz) { + case 27000: + reg->clk = 0x00000100; + return khz; + case 100000: + reg->clk = 0x00002100; + return khz; + case 108000: + reg->clk = 0x00002140; + return khz; + default: + sclk = read_vco(dev, clk); + sdiv = min((sclk * 2) / (khz - 2999), (u32)65); + /* if the clock has a PLL attached, and we can get a within + * [-2, 3) MHz of a divider, we'll disable the PLL and use + * the divider instead. + * + * divider can go as low as 2, limited here because NVIDIA + * and the VBIOS on my NVA8 seem to prefer using the PLL + * for 810MHz - is there a good reason? + */ + if (sdiv > 4) { + oclk = (sclk * 2) / sdiv; + diff = khz - oclk; + if (!pll || (diff >= -2000 && diff < 3000)) { + reg->clk = (((sdiv - 2) << 16) | 0x00003100); + return oclk; + } + } + + if (!pll) { + NV_ERROR(drm, "bad freq %02x: %d %d\n", clk, khz, sclk); + return -ERANGE; + } + + break; + } + + ret = nvbios_pll_parse(bios, pll, &limits); + if (ret) + return ret; + + limits.refclk = read_clk(dev, clk - 0x10, true); + if (!limits.refclk) + return -EINVAL; + + ret = nva3_calc_pll(dev, &limits, khz, &N, NULL, &M, &P); + if (ret >= 0) { + reg->clk = nv_rd32(device, 0x4120 + (clk * 4)); + reg->pll = (P << 16) | (N << 8) | M; + } + + return ret; +} + +static void +prog_pll(struct drm_device *dev, int clk, u32 pll, struct creg *reg) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + const u32 src0 = 0x004120 + (clk * 4); + const u32 src1 = 0x004160 + (clk * 4); + const u32 ctrl = pll + 0; + const u32 coef = pll + 4; + + if (!reg->clk && !reg->pll) { + NV_DEBUG(drm, "no clock for %02x\n", clk); + return; + } + + if (reg->pll) { + nv_mask(device, src0, 0x00000101, 0x00000101); + nv_wr32(device, coef, reg->pll); + nv_mask(device, ctrl, 0x00000015, 0x00000015); + nv_mask(device, ctrl, 0x00000010, 0x00000000); + nv_wait(device, ctrl, 0x00020000, 0x00020000); + nv_mask(device, ctrl, 0x00000010, 0x00000010); + nv_mask(device, ctrl, 0x00000008, 0x00000000); + nv_mask(device, src1, 0x00000100, 0x00000000); + nv_mask(device, src1, 0x00000001, 0x00000000); + } else { + nv_mask(device, src1, 0x003f3141, 0x00000101 | reg->clk); + nv_mask(device, ctrl, 0x00000018, 0x00000018); + udelay(20); + nv_mask(device, ctrl, 0x00000001, 0x00000000); + nv_mask(device, src0, 0x00000100, 0x00000000); + nv_mask(device, src0, 0x00000001, 0x00000000); + } +} + +static void +prog_clk(struct drm_device *dev, int clk, struct creg *reg) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + + if (!reg->clk) { + NV_DEBUG(drm, "no clock for %02x\n", clk); + return; + } + + nv_mask(device, 0x004120 + (clk * 4), 0x003f3141, 0x00000101 | reg->clk); +} + +int +nva3_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + perflvl->core = read_pll(dev, 0x00, 0x4200); + perflvl->shader = read_pll(dev, 0x01, 0x4220); + perflvl->memory = read_pll(dev, 0x02, 0x4000); + perflvl->unka0 = read_clk(dev, 0x20, false); + perflvl->vdec = read_clk(dev, 0x21, false); + perflvl->daemon = read_clk(dev, 0x25, false); + perflvl->copy = perflvl->core; + return 0; +} + +struct nva3_pm_state { + struct nouveau_pm_level *perflvl; + + struct creg nclk; + struct creg sclk; + struct creg vdec; + struct creg unka0; + + struct creg mclk; + u8 *rammap; + u8 rammap_ver; + u8 rammap_len; + u8 *ramcfg; + u8 ramcfg_len; + u32 r004018; + u32 r100760; +}; + +void * +nva3_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nva3_pm_state *info; + u8 ramcfg_cnt; + int ret; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + + ret = calc_clk(dev, 0x10, 0x4200, perflvl->core, &info->nclk); + if (ret < 0) + goto out; + + ret = calc_clk(dev, 0x11, 0x4220, perflvl->shader, &info->sclk); + if (ret < 0) + goto out; + + ret = calc_clk(dev, 0x12, 0x4000, perflvl->memory, &info->mclk); + if (ret < 0) + goto out; + + ret = calc_clk(dev, 0x20, 0x0000, perflvl->unka0, &info->unka0); + if (ret < 0) + goto out; + + ret = calc_clk(dev, 0x21, 0x0000, perflvl->vdec, &info->vdec); + if (ret < 0) + goto out; + + info->rammap = nouveau_perf_rammap(dev, perflvl->memory, + &info->rammap_ver, + &info->rammap_len, + &ramcfg_cnt, &info->ramcfg_len); + if (info->rammap_ver != 0x10 || info->rammap_len < 5) + info->rammap = NULL; + + info->ramcfg = nouveau_perf_ramcfg(dev, perflvl->memory, + &info->rammap_ver, + &info->ramcfg_len); + if (info->rammap_ver != 0x10) + info->ramcfg = NULL; + + info->perflvl = perflvl; +out: + if (ret < 0) { + kfree(info); + info = ERR_PTR(ret); + } + return info; +} + +static bool +nva3_pm_grcp_idle(void *data) +{ + struct drm_device *dev = data; + struct nouveau_device *device = nouveau_dev(dev); + + if (!(nv_rd32(device, 0x400304) & 0x00000001)) + return true; + if (nv_rd32(device, 0x400308) == 0x0050001c) + return true; + return false; +} + +static void +mclk_precharge(struct nouveau_mem_exec_func *exec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + nv_wr32(device, 0x1002d4, 0x00000001); +} + +static void +mclk_refresh(struct nouveau_mem_exec_func *exec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + nv_wr32(device, 0x1002d0, 0x00000001); +} + +static void +mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + nv_wr32(device, 0x100210, enable ? 0x80000000 : 0x00000000); +} + +static void +mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + nv_wr32(device, 0x1002dc, enable ? 0x00000001 : 0x00000000); +} + +static void +mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + volatile u32 post = nv_rd32(device, 0); (void)post; + udelay((nsec + 500) / 1000); +} + +static u32 +mclk_mrg(struct nouveau_mem_exec_func *exec, int mr) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + if (mr <= 1) + return nv_rd32(device, 0x1002c0 + ((mr - 0) * 4)); + if (mr <= 3) + return nv_rd32(device, 0x1002e0 + ((mr - 2) * 4)); + return 0; +} + +static void +mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nouveau_fb *pfb = nouveau_fb(device); + if (mr <= 1) { + if (pfb->ram->ranks > 1) + nv_wr32(device, 0x1002c8 + ((mr - 0) * 4), data); + nv_wr32(device, 0x1002c0 + ((mr - 0) * 4), data); + } else + if (mr <= 3) { + if (pfb->ram->ranks > 1) + nv_wr32(device, 0x1002e8 + ((mr - 2) * 4), data); + nv_wr32(device, 0x1002e0 + ((mr - 2) * 4), data); + } +} + +static void +mclk_clock_set(struct nouveau_mem_exec_func *exec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nva3_pm_state *info = exec->priv; + u32 ctrl; + + ctrl = nv_rd32(device, 0x004000); + if (!(ctrl & 0x00000008) && info->mclk.pll) { + nv_wr32(device, 0x004000, (ctrl |= 0x00000008)); + nv_mask(device, 0x1110e0, 0x00088000, 0x00088000); + nv_wr32(device, 0x004018, 0x00001000); + nv_wr32(device, 0x004000, (ctrl &= ~0x00000001)); + nv_wr32(device, 0x004004, info->mclk.pll); + nv_wr32(device, 0x004000, (ctrl |= 0x00000001)); + udelay(64); + nv_wr32(device, 0x004018, 0x00005000 | info->r004018); + udelay(20); + } else + if (!info->mclk.pll) { + nv_mask(device, 0x004168, 0x003f3040, info->mclk.clk); + nv_wr32(device, 0x004000, (ctrl |= 0x00000008)); + nv_mask(device, 0x1110e0, 0x00088000, 0x00088000); + nv_wr32(device, 0x004018, 0x0000d000 | info->r004018); + } + + if (info->rammap) { + if (info->ramcfg && (info->rammap[4] & 0x08)) { + u32 unk5a0 = (ROM16(info->ramcfg[5]) << 8) | + info->ramcfg[5]; + u32 unk5a4 = ROM16(info->ramcfg[7]); + u32 unk804 = (info->ramcfg[9] & 0xf0) << 16 | + (info->ramcfg[3] & 0x0f) << 16 | + (info->ramcfg[9] & 0x0f) | + 0x80000000; + nv_wr32(device, 0x1005a0, unk5a0); + nv_wr32(device, 0x1005a4, unk5a4); + nv_wr32(device, 0x10f804, unk804); + nv_mask(device, 0x10053c, 0x00001000, 0x00000000); + } else { + nv_mask(device, 0x10053c, 0x00001000, 0x00001000); + nv_mask(device, 0x10f804, 0x80000000, 0x00000000); + nv_mask(device, 0x100760, 0x22222222, info->r100760); + nv_mask(device, 0x1007a0, 0x22222222, info->r100760); + nv_mask(device, 0x1007e0, 0x22222222, info->r100760); + } + } + + if (info->mclk.pll) { + nv_mask(device, 0x1110e0, 0x00088000, 0x00011000); + nv_wr32(device, 0x004000, (ctrl &= ~0x00000008)); + } +} + +static void +mclk_timing_set(struct nouveau_mem_exec_func *exec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nva3_pm_state *info = exec->priv; + struct nouveau_pm_level *perflvl = info->perflvl; + int i; + + for (i = 0; i < 9; i++) + nv_wr32(device, 0x100220 + (i * 4), perflvl->timing.reg[i]); + + if (info->ramcfg) { + u32 data = (info->ramcfg[2] & 0x08) ? 0x00000000 : 0x00001000; + nv_mask(device, 0x100200, 0x00001000, data); + } + + if (info->ramcfg) { + u32 unk714 = nv_rd32(device, 0x100714) & ~0xf0000010; + u32 unk718 = nv_rd32(device, 0x100718) & ~0x00000100; + u32 unk71c = nv_rd32(device, 0x10071c) & ~0x00000100; + if ( (info->ramcfg[2] & 0x20)) + unk714 |= 0xf0000000; + if (!(info->ramcfg[2] & 0x04)) + unk714 |= 0x00000010; + nv_wr32(device, 0x100714, unk714); + + if (info->ramcfg[2] & 0x01) + unk71c |= 0x00000100; + nv_wr32(device, 0x10071c, unk71c); + + if (info->ramcfg[2] & 0x02) + unk718 |= 0x00000100; + nv_wr32(device, 0x100718, unk718); + + if (info->ramcfg[2] & 0x10) + nv_wr32(device, 0x111100, 0x48000000); /*XXX*/ + } +} + +static void +prog_mem(struct drm_device *dev, struct nva3_pm_state *info) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_mem_exec_func exec = { + .dev = dev, + .precharge = mclk_precharge, + .refresh = mclk_refresh, + .refresh_auto = mclk_refresh_auto, + .refresh_self = mclk_refresh_self, + .wait = mclk_wait, + .mrg = mclk_mrg, + .mrs = mclk_mrs, + .clock_set = mclk_clock_set, + .timing_set = mclk_timing_set, + .priv = info + }; + u32 ctrl; + + /* XXX: where the fuck does 750MHz come from? */ + if (info->perflvl->memory <= 750000) { + info->r004018 = 0x10000000; + info->r100760 = 0x22222222; + } + + ctrl = nv_rd32(device, 0x004000); + if (ctrl & 0x00000008) { + if (info->mclk.pll) { + nv_mask(device, 0x004128, 0x00000101, 0x00000101); + nv_wr32(device, 0x004004, info->mclk.pll); + nv_wr32(device, 0x004000, (ctrl |= 0x00000001)); + nv_wr32(device, 0x004000, (ctrl &= 0xffffffef)); + nv_wait(device, 0x004000, 0x00020000, 0x00020000); + nv_wr32(device, 0x004000, (ctrl |= 0x00000010)); + nv_wr32(device, 0x004018, 0x00005000 | info->r004018); + nv_wr32(device, 0x004000, (ctrl |= 0x00000004)); + } + } else { + u32 ssel = 0x00000101; + if (info->mclk.clk) + ssel |= info->mclk.clk; + else + ssel |= 0x00080000; /* 324MHz, shouldn't matter... */ + nv_mask(device, 0x004168, 0x003f3141, ctrl); + } + + if (info->ramcfg) { + if (info->ramcfg[2] & 0x10) { + nv_mask(device, 0x111104, 0x00000600, 0x00000000); + } else { + nv_mask(device, 0x111100, 0x40000000, 0x40000000); + nv_mask(device, 0x111104, 0x00000180, 0x00000000); + } + } + if (info->rammap && !(info->rammap[4] & 0x02)) + nv_mask(device, 0x100200, 0x00000800, 0x00000000); + nv_wr32(device, 0x611200, 0x00003300); + if (!(info->ramcfg[2] & 0x10)) + nv_wr32(device, 0x111100, 0x4c020000); /*XXX*/ + + nouveau_mem_exec(&exec, info->perflvl); + + nv_wr32(device, 0x611200, 0x00003330); + if (info->rammap && (info->rammap[4] & 0x02)) + nv_mask(device, 0x100200, 0x00000800, 0x00000800); + if (info->ramcfg) { + if (info->ramcfg[2] & 0x10) { + nv_mask(device, 0x111104, 0x00000180, 0x00000180); + nv_mask(device, 0x111100, 0x40000000, 0x00000000); + } else { + nv_mask(device, 0x111104, 0x00000600, 0x00000600); + } + } + + if (info->mclk.pll) { + nv_mask(device, 0x004168, 0x00000001, 0x00000000); + nv_mask(device, 0x004168, 0x00000100, 0x00000000); + } else { + nv_mask(device, 0x004000, 0x00000001, 0x00000000); + nv_mask(device, 0x004128, 0x00000001, 0x00000000); + nv_mask(device, 0x004128, 0x00000100, 0x00000000); + } +} + +int +nva3_pm_clocks_set(struct drm_device *dev, void *pre_state) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_drm *drm = nouveau_drm(dev); + struct nva3_pm_state *info = pre_state; + int ret = -EAGAIN; + + /* prevent any new grctx switches from starting */ + nv_wr32(device, 0x400324, 0x00000000); + nv_wr32(device, 0x400328, 0x0050001c); /* wait flag 0x1c */ + /* wait for any pending grctx switches to complete */ + if (!nv_wait_cb(device, nva3_pm_grcp_idle, dev)) { + NV_ERROR(drm, "pm: ctxprog didn't go idle\n"); + goto cleanup; + } + /* freeze PFIFO */ + nv_mask(device, 0x002504, 0x00000001, 0x00000001); + if (!nv_wait(device, 0x002504, 0x00000010, 0x00000010)) { + NV_ERROR(drm, "pm: fifo didn't go idle\n"); + goto cleanup; + } + + prog_pll(dev, 0x00, 0x004200, &info->nclk); + prog_pll(dev, 0x01, 0x004220, &info->sclk); + prog_clk(dev, 0x20, &info->unka0); + prog_clk(dev, 0x21, &info->vdec); + + if (info->mclk.clk || info->mclk.pll) + prog_mem(dev, info); + + ret = 0; + +cleanup: + /* unfreeze PFIFO */ + nv_mask(device, 0x002504, 0x00000001, 0x00000000); + /* restore ctxprog to normal */ + nv_wr32(device, 0x400324, 0x00000000); + nv_wr32(device, 0x400328, 0x0070009c); /* set flag 0x1c */ + /* unblock it if necessary */ + if (nv_rd32(device, 0x400308) == 0x0050001c) + nv_mask(device, 0x400824, 0x10000000, 0x10000000); + kfree(info); + return ret; +} diff --git a/drivers/gpu/drm/nouveau/nvc0_pm.c b/drivers/gpu/drm/nouveau/nvc0_pm.c new file mode 100644 index 0000000..3b7041c --- /dev/null +++ b/drivers/gpu/drm/nouveau/nvc0_pm.c @@ -0,0 +1,599 @@ +/* + * Copyright 2011 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 "nouveau_drm.h" +#include "nouveau_bios.h" +#include "nouveau_pm.h" + +#include <subdev/bios/pll.h> +#include <subdev/bios.h> +#include <subdev/clock.h> +#include <subdev/timer.h> +#include <subdev/fb.h> + +static u32 read_div(struct drm_device *, int, u32, u32); +static u32 read_pll(struct drm_device *, u32); + +static u32 +read_vco(struct drm_device *dev, u32 dsrc) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 ssrc = nv_rd32(device, dsrc); + if (!(ssrc & 0x00000100)) + return read_pll(dev, 0x00e800); + return read_pll(dev, 0x00e820); +} + +static u32 +read_pll(struct drm_device *dev, u32 pll) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 ctrl = nv_rd32(device, pll + 0); + u32 coef = nv_rd32(device, pll + 4); + u32 P = (coef & 0x003f0000) >> 16; + u32 N = (coef & 0x0000ff00) >> 8; + u32 M = (coef & 0x000000ff) >> 0; + u32 sclk, doff; + + if (!(ctrl & 0x00000001)) + return 0; + + switch (pll & 0xfff000) { + case 0x00e000: + sclk = 27000; + P = 1; + break; + case 0x137000: + doff = (pll - 0x137000) / 0x20; + sclk = read_div(dev, doff, 0x137120, 0x137140); + break; + case 0x132000: + switch (pll) { + case 0x132000: + sclk = read_pll(dev, 0x132020); + break; + case 0x132020: + sclk = read_div(dev, 0, 0x137320, 0x137330); + break; + default: + return 0; + } + break; + default: + return 0; + } + + return sclk * N / M / P; +} + +static u32 +read_div(struct drm_device *dev, int doff, u32 dsrc, u32 dctl) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 ssrc = nv_rd32(device, dsrc + (doff * 4)); + u32 sctl = nv_rd32(device, dctl + (doff * 4)); + + switch (ssrc & 0x00000003) { + case 0: + if ((ssrc & 0x00030000) != 0x00030000) + return 27000; + return 108000; + case 2: + return 100000; + case 3: + if (sctl & 0x80000000) { + u32 sclk = read_vco(dev, dsrc + (doff * 4)); + u32 sdiv = (sctl & 0x0000003f) + 2; + return (sclk * 2) / sdiv; + } + + return read_vco(dev, dsrc + (doff * 4)); + default: + return 0; + } +} + +static u32 +read_mem(struct drm_device *dev) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 ssel = nv_rd32(device, 0x1373f0); + if (ssel & 0x00000001) + return read_div(dev, 0, 0x137300, 0x137310); + return read_pll(dev, 0x132000); +} + +static u32 +read_clk(struct drm_device *dev, int clk) +{ + struct nouveau_device *device = nouveau_dev(dev); + u32 sctl = nv_rd32(device, 0x137250 + (clk * 4)); + u32 ssel = nv_rd32(device, 0x137100); + u32 sclk, sdiv; + + if (ssel & (1 << clk)) { + if (clk < 7) + sclk = read_pll(dev, 0x137000 + (clk * 0x20)); + else + sclk = read_pll(dev, 0x1370e0); + sdiv = ((sctl & 0x00003f00) >> 8) + 2; + } else { + sclk = read_div(dev, clk, 0x137160, 0x1371d0); + sdiv = ((sctl & 0x0000003f) >> 0) + 2; + } + + if (sctl & 0x80000000) + return (sclk * 2) / sdiv; + return sclk; +} + +int +nvc0_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + perflvl->shader = read_clk(dev, 0x00); + perflvl->core = perflvl->shader / 2; + perflvl->memory = read_mem(dev); + perflvl->rop = read_clk(dev, 0x01); + perflvl->hub07 = read_clk(dev, 0x02); + perflvl->hub06 = read_clk(dev, 0x07); + perflvl->hub01 = read_clk(dev, 0x08); + perflvl->copy = read_clk(dev, 0x09); + perflvl->daemon = read_clk(dev, 0x0c); + perflvl->vdec = read_clk(dev, 0x0e); + return 0; +} + +struct nvc0_pm_clock { + u32 freq; + u32 ssel; + u32 mdiv; + u32 dsrc; + u32 ddiv; + u32 coef; +}; + +struct nvc0_pm_state { + struct nouveau_pm_level *perflvl; + struct nvc0_pm_clock eng[16]; + struct nvc0_pm_clock mem; +}; + +static u32 +calc_div(struct drm_device *dev, int clk, u32 ref, u32 freq, u32 *ddiv) +{ + u32 div = min((ref * 2) / freq, (u32)65); + if (div < 2) + div = 2; + + *ddiv = div - 2; + return (ref * 2) / div; +} + +static u32 +calc_src(struct drm_device *dev, int clk, u32 freq, u32 *dsrc, u32 *ddiv) +{ + u32 sclk; + + /* use one of the fixed frequencies if possible */ + *ddiv = 0x00000000; + switch (freq) { + case 27000: + case 108000: + *dsrc = 0x00000000; + if (freq == 108000) + *dsrc |= 0x00030000; + return freq; + case 100000: + *dsrc = 0x00000002; + return freq; + default: + *dsrc = 0x00000003; + break; + } + + /* otherwise, calculate the closest divider */ + sclk = read_vco(dev, clk); + if (clk < 7) + sclk = calc_div(dev, clk, sclk, freq, ddiv); + return sclk; +} + +static u32 +calc_pll(struct drm_device *dev, int clk, u32 freq, u32 *coef) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_bios *bios = nouveau_bios(device); + struct nvbios_pll limits; + int N, M, P, ret; + + ret = nvbios_pll_parse(bios, 0x137000 + (clk * 0x20), &limits); + if (ret) + return 0; + + limits.refclk = read_div(dev, clk, 0x137120, 0x137140); + if (!limits.refclk) + return 0; + + ret = nva3_calc_pll(dev, &limits, freq, &N, NULL, &M, &P); + if (ret <= 0) + return 0; + + *coef = (P << 16) | (N << 8) | M; + return ret; +} + +/* A (likely rather simplified and incomplete) view of the clock tree + * + * Key: + * + * S: source select + * D: divider + * P: pll + * F: switch + * + * Engine clocks: + * + * 137250(D) ---- 137100(F0) ---- 137160(S)/1371d0(D) ------------------- ref + * (F1) ---- 1370X0(P) ---- 137120(S)/137140(D) ---- ref + * + * Not all registers exist for all clocks. For example: clocks >= 8 don't + * have their own PLL (all tied to clock 7's PLL when in PLL mode), nor do + * they have the divider at 1371d0, though the source selection at 137160 + * still exists. You must use the divider at 137250 for these instead. + * + * Memory clock: + * + * TBD, read_mem() above is likely very wrong... + * + */ + +static int +calc_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info, u32 freq) +{ + u32 src0, div0, div1D, div1P = 0; + u32 clk0, clk1 = 0; + + /* invalid clock domain */ + if (!freq) + return 0; + + /* first possible path, using only dividers */ + clk0 = calc_src(dev, clk, freq, &src0, &div0); + clk0 = calc_div(dev, clk, clk0, freq, &div1D); + + /* see if we can get any closer using PLLs */ + if (clk0 != freq && (0x00004387 & (1 << clk))) { + if (clk < 7) + clk1 = calc_pll(dev, clk, freq, &info->coef); + else + clk1 = read_pll(dev, 0x1370e0); + clk1 = calc_div(dev, clk, clk1, freq, &div1P); + } + + /* select the method which gets closest to target freq */ + if (abs((int)freq - clk0) <= abs((int)freq - clk1)) { + info->dsrc = src0; + if (div0) { + info->ddiv |= 0x80000000; + info->ddiv |= div0 << 8; + info->ddiv |= div0; + } + if (div1D) { + info->mdiv |= 0x80000000; + info->mdiv |= div1D; + } + info->ssel = 0; + info->freq = clk0; + } else { + if (div1P) { + info->mdiv |= 0x80000000; + info->mdiv |= div1P << 8; + } + info->ssel = (1 << clk); + info->freq = clk1; + } + + return 0; +} + +static int +calc_mem(struct drm_device *dev, struct nvc0_pm_clock *info, u32 freq) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_bios *bios = nouveau_bios(device); + struct nvbios_pll pll; + int N, M, P, ret; + u32 ctrl; + + /* mclk pll input freq comes from another pll, make sure it's on */ + ctrl = nv_rd32(device, 0x132020); + if (!(ctrl & 0x00000001)) { + /* if not, program it to 567MHz. nfi where this value comes + * from - it looks like it's in the pll limits table for + * 132000 but the binary driver ignores all my attempts to + * change this value. + */ + nv_wr32(device, 0x137320, 0x00000103); + nv_wr32(device, 0x137330, 0x81200606); + nv_wait(device, 0x132020, 0x00010000, 0x00010000); + nv_wr32(device, 0x132024, 0x0001150f); + nv_mask(device, 0x132020, 0x00000001, 0x00000001); + nv_wait(device, 0x137390, 0x00020000, 0x00020000); + nv_mask(device, 0x132020, 0x00000004, 0x00000004); + } + + /* for the moment, until the clock tree is better understood, use + * pll mode for all clock frequencies + */ + ret = nvbios_pll_parse(bios, 0x132000, &pll); + if (ret == 0) { + pll.refclk = read_pll(dev, 0x132020); + if (pll.refclk) { + ret = nva3_calc_pll(dev, &pll, freq, &N, NULL, &M, &P); + if (ret > 0) { + info->coef = (P << 16) | (N << 8) | M; + return 0; + } + } + } + + return -EINVAL; +} + +void * +nvc0_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nvc0_pm_state *info; + int ret; + + info = kzalloc(sizeof(*info), GFP_KERNEL); + if (!info) + return ERR_PTR(-ENOMEM); + + /* NFI why this is still in the performance table, the ROPCs appear + * to get their clock from clock 2 ("hub07", actually hub05 on this + * chip, but, anyway...) as well. nvatiming confirms hub05 and ROP + * are always the same freq with the binary driver even when the + * performance table says they should differ. + */ + if (device->chipset == 0xd9) + perflvl->rop = 0; + + if ((ret = calc_clk(dev, 0x00, &info->eng[0x00], perflvl->shader)) || + (ret = calc_clk(dev, 0x01, &info->eng[0x01], perflvl->rop)) || + (ret = calc_clk(dev, 0x02, &info->eng[0x02], perflvl->hub07)) || + (ret = calc_clk(dev, 0x07, &info->eng[0x07], perflvl->hub06)) || + (ret = calc_clk(dev, 0x08, &info->eng[0x08], perflvl->hub01)) || + (ret = calc_clk(dev, 0x09, &info->eng[0x09], perflvl->copy)) || + (ret = calc_clk(dev, 0x0c, &info->eng[0x0c], perflvl->daemon)) || + (ret = calc_clk(dev, 0x0e, &info->eng[0x0e], perflvl->vdec))) { + kfree(info); + return ERR_PTR(ret); + } + + if (perflvl->memory) { + ret = calc_mem(dev, &info->mem, perflvl->memory); + if (ret) { + kfree(info); + return ERR_PTR(ret); + } + } + + info->perflvl = perflvl; + return info; +} + +static void +prog_clk(struct drm_device *dev, int clk, struct nvc0_pm_clock *info) +{ + struct nouveau_device *device = nouveau_dev(dev); + + /* program dividers at 137160/1371d0 first */ + if (clk < 7 && !info->ssel) { + nv_mask(device, 0x1371d0 + (clk * 0x04), 0x80003f3f, info->ddiv); + nv_wr32(device, 0x137160 + (clk * 0x04), info->dsrc); + } + + /* switch clock to non-pll mode */ + nv_mask(device, 0x137100, (1 << clk), 0x00000000); + nv_wait(device, 0x137100, (1 << clk), 0x00000000); + + /* reprogram pll */ + if (clk < 7) { + /* make sure it's disabled first... */ + u32 base = 0x137000 + (clk * 0x20); + u32 ctrl = nv_rd32(device, base + 0x00); + if (ctrl & 0x00000001) { + nv_mask(device, base + 0x00, 0x00000004, 0x00000000); + nv_mask(device, base + 0x00, 0x00000001, 0x00000000); + } + /* program it to new values, if necessary */ + if (info->ssel) { + nv_wr32(device, base + 0x04, info->coef); + nv_mask(device, base + 0x00, 0x00000001, 0x00000001); + nv_wait(device, base + 0x00, 0x00020000, 0x00020000); + nv_mask(device, base + 0x00, 0x00020004, 0x00000004); + } + } + + /* select pll/non-pll mode, and program final clock divider */ + nv_mask(device, 0x137100, (1 << clk), info->ssel); + nv_wait(device, 0x137100, (1 << clk), info->ssel); + nv_mask(device, 0x137250 + (clk * 0x04), 0x00003f3f, info->mdiv); +} + +static void +mclk_precharge(struct nouveau_mem_exec_func *exec) +{ +} + +static void +mclk_refresh(struct nouveau_mem_exec_func *exec) +{ +} + +static void +mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + nv_wr32(device, 0x10f210, enable ? 0x80000000 : 0x00000000); +} + +static void +mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable) +{ +} + +static void +mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec) +{ + udelay((nsec + 500) / 1000); +} + +static u32 +mclk_mrg(struct nouveau_mem_exec_func *exec, int mr) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nouveau_fb *pfb = nouveau_fb(device); + if (pfb->ram->type != NV_MEM_TYPE_GDDR5) { + if (mr <= 1) + return nv_rd32(device, 0x10f300 + ((mr - 0) * 4)); + return nv_rd32(device, 0x10f320 + ((mr - 2) * 4)); + } else { + if (mr == 0) + return nv_rd32(device, 0x10f300 + (mr * 4)); + else + if (mr <= 7) + return nv_rd32(device, 0x10f32c + (mr * 4)); + return nv_rd32(device, 0x10f34c); + } +} + +static void +mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nouveau_fb *pfb = nouveau_fb(device); + if (pfb->ram->type != NV_MEM_TYPE_GDDR5) { + if (mr <= 1) { + nv_wr32(device, 0x10f300 + ((mr - 0) * 4), data); + if (pfb->ram->ranks > 1) + nv_wr32(device, 0x10f308 + ((mr - 0) * 4), data); + } else + if (mr <= 3) { + nv_wr32(device, 0x10f320 + ((mr - 2) * 4), data); + if (pfb->ram->ranks > 1) + nv_wr32(device, 0x10f328 + ((mr - 2) * 4), data); + } + } else { + if (mr == 0) nv_wr32(device, 0x10f300 + (mr * 4), data); + else if (mr <= 7) nv_wr32(device, 0x10f32c + (mr * 4), data); + else if (mr == 15) nv_wr32(device, 0x10f34c, data); + } +} + +static void +mclk_clock_set(struct nouveau_mem_exec_func *exec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nvc0_pm_state *info = exec->priv; + u32 ctrl = nv_rd32(device, 0x132000); + + nv_wr32(device, 0x137360, 0x00000001); + nv_wr32(device, 0x137370, 0x00000000); + nv_wr32(device, 0x137380, 0x00000000); + if (ctrl & 0x00000001) + nv_wr32(device, 0x132000, (ctrl &= ~0x00000001)); + + nv_wr32(device, 0x132004, info->mem.coef); + nv_wr32(device, 0x132000, (ctrl |= 0x00000001)); + nv_wait(device, 0x137390, 0x00000002, 0x00000002); + nv_wr32(device, 0x132018, 0x00005000); + + nv_wr32(device, 0x137370, 0x00000001); + nv_wr32(device, 0x137380, 0x00000001); + nv_wr32(device, 0x137360, 0x00000000); +} + +static void +mclk_timing_set(struct nouveau_mem_exec_func *exec) +{ + struct nouveau_device *device = nouveau_dev(exec->dev); + struct nvc0_pm_state *info = exec->priv; + struct nouveau_pm_level *perflvl = info->perflvl; + int i; + + for (i = 0; i < 5; i++) + nv_wr32(device, 0x10f290 + (i * 4), perflvl->timing.reg[i]); +} + +static void +prog_mem(struct drm_device *dev, struct nvc0_pm_state *info) +{ + struct nouveau_device *device = nouveau_dev(dev); + struct nouveau_mem_exec_func exec = { + .dev = dev, + .precharge = mclk_precharge, + .refresh = mclk_refresh, + .refresh_auto = mclk_refresh_auto, + .refresh_self = mclk_refresh_self, + .wait = mclk_wait, + .mrg = mclk_mrg, + .mrs = mclk_mrs, + .clock_set = mclk_clock_set, + .timing_set = mclk_timing_set, + .priv = info + }; + + if (device->chipset < 0xd0) + nv_wr32(device, 0x611200, 0x00003300); + else + nv_wr32(device, 0x62c000, 0x03030000); + + nouveau_mem_exec(&exec, info->perflvl); + + if (device->chipset < 0xd0) + nv_wr32(device, 0x611200, 0x00003330); + else + nv_wr32(device, 0x62c000, 0x03030300); +} +int +nvc0_pm_clocks_set(struct drm_device *dev, void *data) +{ + struct nvc0_pm_state *info = data; + int i; + + if (info->mem.coef) + prog_mem(dev, info); + + for (i = 0; i < 16; i++) { + if (!info->eng[i].freq) + continue; + prog_clk(dev, i, &info->eng[i]); + } + + kfree(info); + return 0; +} |