mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-12-26 12:34:41 +08:00
drm/nouveau/pwr: initial implementation
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
This commit is contained in:
parent
682b1fc793
commit
ff4b42c753
@ -129,6 +129,12 @@ 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
|
||||
|
@ -75,6 +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_FIFO] = NV_DEVICE_DISABLE_FIFO,
|
||||
[NVDEV_ENGINE_SW] = NV_DEVICE_DISABLE_FIFO,
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include <subdev/instmem.h>
|
||||
#include <subdev/vm.h>
|
||||
#include <subdev/bar.h>
|
||||
#include <subdev/pwr.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
@ -327,6 +328,7 @@ nv50_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
|
||||
@ -354,6 +356,7 @@ nv50_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
|
||||
@ -380,6 +383,7 @@ nv50_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
|
||||
@ -406,6 +410,7 @@ nv50_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nv50_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nv84_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nv50_software_oclass;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <subdev/instmem.h>
|
||||
#include <subdev/vm.h>
|
||||
#include <subdev/bar.h>
|
||||
#include <subdev/pwr.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
@ -72,6 +73,7 @@ nvc0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -101,6 +103,7 @@ nvc0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -130,6 +133,7 @@ nvc0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -158,6 +162,7 @@ nvc0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -187,6 +192,7 @@ nvc0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -216,6 +222,7 @@ nvc0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -244,6 +251,7 @@ nvc0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvc0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -273,6 +281,7 @@ nvc0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nvc0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
|
@ -38,6 +38,7 @@
|
||||
#include <subdev/instmem.h>
|
||||
#include <subdev/vm.h>
|
||||
#include <subdev/bar.h>
|
||||
#include <subdev/pwr.h>
|
||||
|
||||
#include <engine/device.h>
|
||||
#include <engine/dmaobj.h>
|
||||
@ -72,6 +73,7 @@ nve0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -102,6 +104,7 @@ nve0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -132,6 +135,7 @@ nve0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -162,6 +166,7 @@ nve0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
@ -194,6 +199,7 @@ nve0_identify(struct nouveau_device *device)
|
||||
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_ENGINE_DMAOBJ ] = &nvd0_dmaeng_oclass;
|
||||
#if 0
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nve0_fifo_oclass;
|
||||
|
80
drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
Normal file
80
drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
Normal file
@ -0,0 +1,80 @@
|
||||
#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
|
@ -32,6 +32,7 @@ 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 },
|
||||
|
@ -37,6 +37,7 @@ 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 },
|
||||
|
247
drivers/gpu/drm/nouveau/core/subdev/pwr/base.c
Normal file
247
drivers/gpu/drm/nouveau/core/subdev/pwr/base.c
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* wait for a free slot in the fifo */
|
||||
addr = nv_rd32(ppwr, 0x10a4a0);
|
||||
if (!nv_wait_ne(ppwr, 0x10a4b0, 0xffffffff, addr ^ 8))
|
||||
return -EBUSY;
|
||||
|
||||
/* 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;
|
||||
}
|
151
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc
Normal file
151
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/host.fuc
Normal file
@ -0,0 +1,151 @@
|
||||
/*
|
||||
* 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
|
84
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc
Normal file
84
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/idle.fuc
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* 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
|
452
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc
Normal file
452
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/kernel.fuc
Normal file
@ -0,0 +1,452 @@
|
||||
/*
|
||||
* 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
|
199
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc
Normal file
199
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/macros.fuc
Normal file
@ -0,0 +1,199 @@
|
||||
/*
|
||||
* 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
|
219
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
Normal file
219
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
Normal file
@ -0,0 +1,219 @@
|
||||
/*
|
||||
* 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
|
63
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc
Normal file
63
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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
|
1165
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
Normal file
1165
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
Normal file
File diff suppressed because it is too large
Load Diff
63
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc
Normal file
63
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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
|
1229
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
Normal file
1229
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
Normal file
File diff suppressed because it is too large
Load Diff
63
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc
Normal file
63
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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
|
1229
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
Normal file
1229
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
Normal file
File diff suppressed because it is too large
Load Diff
63
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc
Normal file
63
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc
Normal file
@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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
|
1229
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
Normal file
1229
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
Normal file
File diff suppressed because it is too large
Load Diff
27
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
Normal file
27
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
Normal file
@ -0,0 +1,27 @@
|
||||
#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
|
57
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc
Normal file
57
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/perf.fuc
Normal file
@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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
|
64
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc
Normal file
64
drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/test.fuc
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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
|
121
drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
Normal file
121
drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
Normal file
@ -0,0 +1,121 @@
|
||||
#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
|
62
drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c
Normal file
62
drivers/gpu/drm/nouveau/core/subdev/pwr/nv108.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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,
|
||||
},
|
||||
};
|
71
drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c
Normal file
71
drivers/gpu/drm/nouveau/core/subdev/pwr/nva3.c
Normal file
@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2013 Red Hat Inc.
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||
* copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation
|
||||
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
* and/or sell copies of the Software, and to permit persons to whom the
|
||||
* Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
|
||||
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
|
||||
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
||||
* OTHER DEALINGS IN THE SOFTWARE.
|
||||
*
|
||||
* Authors: Ben Skeggs
|
||||
*/
|
||||
|
||||
#include <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,
|
||||
},
|
||||
};
|
62
drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c
Normal file
62
drivers/gpu/drm/nouveau/core/subdev/pwr/nvc0.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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,
|
||||
},
|
||||
};
|
62
drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c
Normal file
62
drivers/gpu/drm/nouveau/core/subdev/pwr/nvd0.c
Normal file
@ -0,0 +1,62 @@
|
||||
/*
|
||||
* 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,
|
||||
},
|
||||
};
|
Loading…
Reference in New Issue
Block a user