Merge branch 'drm-fixes' of git://people.freedesktop.org/~airlied/linux
Pull drm fixes from Dave Airlie: "I'm briefly working between holidays and LCA, so this is close to a couple of weeks of fixes, Two sets of amdkfd fixes, this is a new feature this kernel, and this pull fixes a few issues since it got merged, ordering when built-in to kernel and also the iommu vs gpu ordering patch, it also reworks the ioctl before the initial release. Otherwise: - radeon: some misc fixes all over, hdmi, 4k, dpm - nouveau: mcp77 init fixes, oops fix, bug on fix, msi fix - i915: power fixes, revert VGACNTR patch Probably be quiteer next week since I'll be at LCA anyways" * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: (33 commits) drm/amdkfd: rewrite kfd_ioctl() according to drm_ioctl() drm/amdkfd: reformat IOCTL definitions to drm-style drm/amdkfd: Do copy_to/from_user in general kfd_ioctl() drm/radeon: integer underflow in radeon_cp_dispatch_texture() drm/radeon: adjust default bapm settings for KV drm/radeon: properly filter DP1.2 4k modes on non-DP1.2 hw drm/radeon: fix sad_count check for dce3 drm/radeon: KV has three PPLLs (v2) drm/amdkfd: unmap VMID<-->PASID when relesing VMID (non-HWS) drm/radeon: Init amdkfd only if it was compiled amdkfd: actually allocate longs for the pasid bitmask drm/nouveau/nouveau: Do not BUG_ON(!spin_is_locked()) on UP drm/nv4c/mc: disable msi drm/nouveau/fb/ram/mcp77: enable NISO poller drm/nouveau/fb/ram/mcp77: use carveout reg to determine size drm/nouveau/fb/ram/mcp77: subclass nouveau_ram drm/nouveau: wake up the card if necessary during gem callbacks drm/nouveau/device: Add support for GK208B, resolves bug 86935 drm/nouveau: fix missing return statement in nouveau_ttm_tt_unpopulate drm/nouveau/bios: fix oops on pre-nv50 chipsets ...
This commit is contained in:
Коммит
1dd34daa80
|
@ -50,7 +50,10 @@ obj-$(CONFIG_RESET_CONTROLLER) += reset/
|
|||
obj-y += tty/
|
||||
obj-y += char/
|
||||
|
||||
# gpu/ comes after char for AGP vs DRM startup
|
||||
# iommu/ comes before gpu as gpu are using iommu controllers
|
||||
obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
|
||||
|
||||
# gpu/ comes after char for AGP vs DRM startup and after iommu
|
||||
obj-y += gpu/
|
||||
|
||||
obj-$(CONFIG_CONNECTOR) += connector/
|
||||
|
@ -141,7 +144,6 @@ obj-y += clk/
|
|||
|
||||
obj-$(CONFIG_MAILBOX) += mailbox/
|
||||
obj-$(CONFIG_HWSPINLOCK) += hwspinlock/
|
||||
obj-$(CONFIG_IOMMU_SUPPORT) += iommu/
|
||||
obj-$(CONFIG_REMOTEPROC) += remoteproc/
|
||||
obj-$(CONFIG_RPMSG) += rpmsg/
|
||||
|
||||
|
|
|
@ -37,6 +37,7 @@ obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o
|
|||
obj-$(CONFIG_DRM_TTM) += ttm/
|
||||
obj-$(CONFIG_DRM_TDFX) += tdfx/
|
||||
obj-$(CONFIG_DRM_R128) += r128/
|
||||
obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
|
||||
obj-$(CONFIG_DRM_RADEON)+= radeon/
|
||||
obj-$(CONFIG_DRM_MGA) += mga/
|
||||
obj-$(CONFIG_DRM_I810) += i810/
|
||||
|
@ -67,4 +68,3 @@ obj-$(CONFIG_DRM_IMX) += imx/
|
|||
obj-y += i2c/
|
||||
obj-y += panel/
|
||||
obj-y += bridge/
|
||||
obj-$(CONFIG_HSA_AMD) += amd/amdkfd/
|
||||
|
|
|
@ -31,7 +31,6 @@
|
|||
#include <uapi/linux/kfd_ioctl.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <uapi/asm-generic/mman-common.h>
|
||||
#include <asm/processor.h>
|
||||
#include "kfd_priv.h"
|
||||
|
@ -127,17 +126,14 @@ static int kfd_open(struct inode *inode, struct file *filep)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p,
|
||||
void __user *arg)
|
||||
static int kfd_ioctl_get_version(struct file *filep, struct kfd_process *p,
|
||||
void *data)
|
||||
{
|
||||
struct kfd_ioctl_get_version_args args;
|
||||
struct kfd_ioctl_get_version_args *args = data;
|
||||
int err = 0;
|
||||
|
||||
args.major_version = KFD_IOCTL_MAJOR_VERSION;
|
||||
args.minor_version = KFD_IOCTL_MINOR_VERSION;
|
||||
|
||||
if (copy_to_user(arg, &args, sizeof(args)))
|
||||
err = -EFAULT;
|
||||
args->major_version = KFD_IOCTL_MAJOR_VERSION;
|
||||
args->minor_version = KFD_IOCTL_MINOR_VERSION;
|
||||
|
||||
return err;
|
||||
}
|
||||
|
@ -221,10 +217,10 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
|
||||
void __user *arg)
|
||||
static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
|
||||
void *data)
|
||||
{
|
||||
struct kfd_ioctl_create_queue_args args;
|
||||
struct kfd_ioctl_create_queue_args *args = data;
|
||||
struct kfd_dev *dev;
|
||||
int err = 0;
|
||||
unsigned int queue_id;
|
||||
|
@ -233,16 +229,13 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
|
|||
|
||||
memset(&q_properties, 0, sizeof(struct queue_properties));
|
||||
|
||||
if (copy_from_user(&args, arg, sizeof(args)))
|
||||
return -EFAULT;
|
||||
|
||||
pr_debug("kfd: creating queue ioctl\n");
|
||||
|
||||
err = set_queue_properties_from_user(&q_properties, &args);
|
||||
err = set_queue_properties_from_user(&q_properties, args);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
dev = kfd_device_by_id(args.gpu_id);
|
||||
dev = kfd_device_by_id(args->gpu_id);
|
||||
if (dev == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -250,7 +243,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
|
|||
|
||||
pdd = kfd_bind_process_to_device(dev, p);
|
||||
if (IS_ERR(pdd)) {
|
||||
err = PTR_ERR(pdd);
|
||||
err = -ESRCH;
|
||||
goto err_bind_process;
|
||||
}
|
||||
|
||||
|
@ -263,33 +256,26 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p,
|
|||
if (err != 0)
|
||||
goto err_create_queue;
|
||||
|
||||
args.queue_id = queue_id;
|
||||
args->queue_id = queue_id;
|
||||
|
||||
/* Return gpu_id as doorbell offset for mmap usage */
|
||||
args.doorbell_offset = args.gpu_id << PAGE_SHIFT;
|
||||
|
||||
if (copy_to_user(arg, &args, sizeof(args))) {
|
||||
err = -EFAULT;
|
||||
goto err_copy_args_out;
|
||||
}
|
||||
args->doorbell_offset = args->gpu_id << PAGE_SHIFT;
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
pr_debug("kfd: queue id %d was created successfully\n", args.queue_id);
|
||||
pr_debug("kfd: queue id %d was created successfully\n", args->queue_id);
|
||||
|
||||
pr_debug("ring buffer address == 0x%016llX\n",
|
||||
args.ring_base_address);
|
||||
args->ring_base_address);
|
||||
|
||||
pr_debug("read ptr address == 0x%016llX\n",
|
||||
args.read_pointer_address);
|
||||
args->read_pointer_address);
|
||||
|
||||
pr_debug("write ptr address == 0x%016llX\n",
|
||||
args.write_pointer_address);
|
||||
args->write_pointer_address);
|
||||
|
||||
return 0;
|
||||
|
||||
err_copy_args_out:
|
||||
pqm_destroy_queue(&p->pqm, queue_id);
|
||||
err_create_queue:
|
||||
err_bind_process:
|
||||
mutex_unlock(&p->mutex);
|
||||
|
@ -297,99 +283,90 @@ err_bind_process:
|
|||
}
|
||||
|
||||
static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p,
|
||||
void __user *arg)
|
||||
void *data)
|
||||
{
|
||||
int retval;
|
||||
struct kfd_ioctl_destroy_queue_args args;
|
||||
|
||||
if (copy_from_user(&args, arg, sizeof(args)))
|
||||
return -EFAULT;
|
||||
struct kfd_ioctl_destroy_queue_args *args = data;
|
||||
|
||||
pr_debug("kfd: destroying queue id %d for PASID %d\n",
|
||||
args.queue_id,
|
||||
args->queue_id,
|
||||
p->pasid);
|
||||
|
||||
mutex_lock(&p->mutex);
|
||||
|
||||
retval = pqm_destroy_queue(&p->pqm, args.queue_id);
|
||||
retval = pqm_destroy_queue(&p->pqm, args->queue_id);
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
return retval;
|
||||
}
|
||||
|
||||
static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p,
|
||||
void __user *arg)
|
||||
void *data)
|
||||
{
|
||||
int retval;
|
||||
struct kfd_ioctl_update_queue_args args;
|
||||
struct kfd_ioctl_update_queue_args *args = data;
|
||||
struct queue_properties properties;
|
||||
|
||||
if (copy_from_user(&args, arg, sizeof(args)))
|
||||
return -EFAULT;
|
||||
|
||||
if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
|
||||
if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) {
|
||||
pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) {
|
||||
if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) {
|
||||
pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if ((args.ring_base_address) &&
|
||||
if ((args->ring_base_address) &&
|
||||
(!access_ok(VERIFY_WRITE,
|
||||
(const void __user *) args.ring_base_address,
|
||||
(const void __user *) args->ring_base_address,
|
||||
sizeof(uint64_t)))) {
|
||||
pr_err("kfd: can't access ring base address\n");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) {
|
||||
if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) {
|
||||
pr_err("kfd: ring size must be a power of 2 or 0\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
properties.queue_address = args.ring_base_address;
|
||||
properties.queue_size = args.ring_size;
|
||||
properties.queue_percent = args.queue_percentage;
|
||||
properties.priority = args.queue_priority;
|
||||
properties.queue_address = args->ring_base_address;
|
||||
properties.queue_size = args->ring_size;
|
||||
properties.queue_percent = args->queue_percentage;
|
||||
properties.priority = args->queue_priority;
|
||||
|
||||
pr_debug("kfd: updating queue id %d for PASID %d\n",
|
||||
args.queue_id, p->pasid);
|
||||
args->queue_id, p->pasid);
|
||||
|
||||
mutex_lock(&p->mutex);
|
||||
|
||||
retval = pqm_update_queue(&p->pqm, args.queue_id, &properties);
|
||||
retval = pqm_update_queue(&p->pqm, args->queue_id, &properties);
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
static long kfd_ioctl_set_memory_policy(struct file *filep,
|
||||
struct kfd_process *p, void __user *arg)
|
||||
static int kfd_ioctl_set_memory_policy(struct file *filep,
|
||||
struct kfd_process *p, void *data)
|
||||
{
|
||||
struct kfd_ioctl_set_memory_policy_args args;
|
||||
struct kfd_ioctl_set_memory_policy_args *args = data;
|
||||
struct kfd_dev *dev;
|
||||
int err = 0;
|
||||
struct kfd_process_device *pdd;
|
||||
enum cache_policy default_policy, alternate_policy;
|
||||
|
||||
if (copy_from_user(&args, arg, sizeof(args)))
|
||||
return -EFAULT;
|
||||
|
||||
if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT
|
||||
&& args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
|
||||
if (args->default_policy != KFD_IOC_CACHE_POLICY_COHERENT
|
||||
&& args->default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT
|
||||
&& args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
|
||||
if (args->alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT
|
||||
&& args->alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
dev = kfd_device_by_id(args.gpu_id);
|
||||
dev = kfd_device_by_id(args->gpu_id);
|
||||
if (dev == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -397,23 +374,23 @@ static long kfd_ioctl_set_memory_policy(struct file *filep,
|
|||
|
||||
pdd = kfd_bind_process_to_device(dev, p);
|
||||
if (IS_ERR(pdd)) {
|
||||
err = PTR_ERR(pdd);
|
||||
err = -ESRCH;
|
||||
goto out;
|
||||
}
|
||||
|
||||
default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT)
|
||||
default_policy = (args->default_policy == KFD_IOC_CACHE_POLICY_COHERENT)
|
||||
? cache_policy_coherent : cache_policy_noncoherent;
|
||||
|
||||
alternate_policy =
|
||||
(args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
|
||||
(args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT)
|
||||
? cache_policy_coherent : cache_policy_noncoherent;
|
||||
|
||||
if (!dev->dqm->set_cache_memory_policy(dev->dqm,
|
||||
&pdd->qpd,
|
||||
default_policy,
|
||||
alternate_policy,
|
||||
(void __user *)args.alternate_aperture_base,
|
||||
args.alternate_aperture_size))
|
||||
(void __user *)args->alternate_aperture_base,
|
||||
args->alternate_aperture_size))
|
||||
err = -EINVAL;
|
||||
|
||||
out:
|
||||
|
@ -422,53 +399,44 @@ out:
|
|||
return err;
|
||||
}
|
||||
|
||||
static long kfd_ioctl_get_clock_counters(struct file *filep,
|
||||
struct kfd_process *p, void __user *arg)
|
||||
static int kfd_ioctl_get_clock_counters(struct file *filep,
|
||||
struct kfd_process *p, void *data)
|
||||
{
|
||||
struct kfd_ioctl_get_clock_counters_args args;
|
||||
struct kfd_ioctl_get_clock_counters_args *args = data;
|
||||
struct kfd_dev *dev;
|
||||
struct timespec time;
|
||||
|
||||
if (copy_from_user(&args, arg, sizeof(args)))
|
||||
return -EFAULT;
|
||||
|
||||
dev = kfd_device_by_id(args.gpu_id);
|
||||
dev = kfd_device_by_id(args->gpu_id);
|
||||
if (dev == NULL)
|
||||
return -EINVAL;
|
||||
|
||||
/* Reading GPU clock counter from KGD */
|
||||
args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);
|
||||
args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd);
|
||||
|
||||
/* No access to rdtsc. Using raw monotonic time */
|
||||
getrawmonotonic(&time);
|
||||
args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time);
|
||||
args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time);
|
||||
|
||||
get_monotonic_boottime(&time);
|
||||
args.system_clock_counter = (uint64_t)timespec_to_ns(&time);
|
||||
args->system_clock_counter = (uint64_t)timespec_to_ns(&time);
|
||||
|
||||
/* Since the counter is in nano-seconds we use 1GHz frequency */
|
||||
args.system_clock_freq = 1000000000;
|
||||
|
||||
if (copy_to_user(arg, &args, sizeof(args)))
|
||||
return -EFAULT;
|
||||
args->system_clock_freq = 1000000000;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int kfd_ioctl_get_process_apertures(struct file *filp,
|
||||
struct kfd_process *p, void __user *arg)
|
||||
struct kfd_process *p, void *data)
|
||||
{
|
||||
struct kfd_ioctl_get_process_apertures_args args;
|
||||
struct kfd_ioctl_get_process_apertures_args *args = data;
|
||||
struct kfd_process_device_apertures *pAperture;
|
||||
struct kfd_process_device *pdd;
|
||||
|
||||
dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid);
|
||||
|
||||
if (copy_from_user(&args, arg, sizeof(args)))
|
||||
return -EFAULT;
|
||||
|
||||
args.num_of_nodes = 0;
|
||||
args->num_of_nodes = 0;
|
||||
|
||||
mutex_lock(&p->mutex);
|
||||
|
||||
|
@ -477,7 +445,8 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
|
|||
/* Run over all pdd of the process */
|
||||
pdd = kfd_get_first_process_device_data(p);
|
||||
do {
|
||||
pAperture = &args.process_apertures[args.num_of_nodes];
|
||||
pAperture =
|
||||
&args->process_apertures[args->num_of_nodes];
|
||||
pAperture->gpu_id = pdd->dev->id;
|
||||
pAperture->lds_base = pdd->lds_base;
|
||||
pAperture->lds_limit = pdd->lds_limit;
|
||||
|
@ -487,7 +456,7 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
|
|||
pAperture->scratch_limit = pdd->scratch_limit;
|
||||
|
||||
dev_dbg(kfd_device,
|
||||
"node id %u\n", args.num_of_nodes);
|
||||
"node id %u\n", args->num_of_nodes);
|
||||
dev_dbg(kfd_device,
|
||||
"gpu id %u\n", pdd->dev->id);
|
||||
dev_dbg(kfd_device,
|
||||
|
@ -503,80 +472,131 @@ static int kfd_ioctl_get_process_apertures(struct file *filp,
|
|||
dev_dbg(kfd_device,
|
||||
"scratch_limit %llX\n", pdd->scratch_limit);
|
||||
|
||||
args.num_of_nodes++;
|
||||
args->num_of_nodes++;
|
||||
} while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL &&
|
||||
(args.num_of_nodes < NUM_OF_SUPPORTED_GPUS));
|
||||
(args->num_of_nodes < NUM_OF_SUPPORTED_GPUS));
|
||||
}
|
||||
|
||||
mutex_unlock(&p->mutex);
|
||||
|
||||
if (copy_to_user(arg, &args, sizeof(args)))
|
||||
return -EFAULT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \
|
||||
[_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl}
|
||||
|
||||
/** Ioctl table */
|
||||
static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = {
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION,
|
||||
kfd_ioctl_get_version, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE,
|
||||
kfd_ioctl_create_queue, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE,
|
||||
kfd_ioctl_destroy_queue, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY,
|
||||
kfd_ioctl_set_memory_policy, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS,
|
||||
kfd_ioctl_get_clock_counters, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES,
|
||||
kfd_ioctl_get_process_apertures, 0),
|
||||
|
||||
AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE,
|
||||
kfd_ioctl_update_queue, 0),
|
||||
};
|
||||
|
||||
#define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls)
|
||||
|
||||
static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg)
|
||||
{
|
||||
struct kfd_process *process;
|
||||
long err = -EINVAL;
|
||||
amdkfd_ioctl_t *func;
|
||||
const struct amdkfd_ioctl_desc *ioctl = NULL;
|
||||
unsigned int nr = _IOC_NR(cmd);
|
||||
char stack_kdata[128];
|
||||
char *kdata = NULL;
|
||||
unsigned int usize, asize;
|
||||
int retcode = -EINVAL;
|
||||
|
||||
dev_dbg(kfd_device,
|
||||
"ioctl cmd 0x%x (#%d), arg 0x%lx\n",
|
||||
cmd, _IOC_NR(cmd), arg);
|
||||
if (nr >= AMDKFD_CORE_IOCTL_COUNT)
|
||||
goto err_i1;
|
||||
|
||||
if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) {
|
||||
u32 amdkfd_size;
|
||||
|
||||
ioctl = &amdkfd_ioctls[nr];
|
||||
|
||||
amdkfd_size = _IOC_SIZE(ioctl->cmd);
|
||||
usize = asize = _IOC_SIZE(cmd);
|
||||
if (amdkfd_size > asize)
|
||||
asize = amdkfd_size;
|
||||
|
||||
cmd = ioctl->cmd;
|
||||
} else
|
||||
goto err_i1;
|
||||
|
||||
dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg);
|
||||
|
||||
process = kfd_get_process(current);
|
||||
if (IS_ERR(process))
|
||||
return PTR_ERR(process);
|
||||
|
||||
switch (cmd) {
|
||||
case KFD_IOC_GET_VERSION:
|
||||
err = kfd_ioctl_get_version(filep, process, (void __user *)arg);
|
||||
break;
|
||||
case KFD_IOC_CREATE_QUEUE:
|
||||
err = kfd_ioctl_create_queue(filep, process,
|
||||
(void __user *)arg);
|
||||
break;
|
||||
|
||||
case KFD_IOC_DESTROY_QUEUE:
|
||||
err = kfd_ioctl_destroy_queue(filep, process,
|
||||
(void __user *)arg);
|
||||
break;
|
||||
|
||||
case KFD_IOC_SET_MEMORY_POLICY:
|
||||
err = kfd_ioctl_set_memory_policy(filep, process,
|
||||
(void __user *)arg);
|
||||
break;
|
||||
|
||||
case KFD_IOC_GET_CLOCK_COUNTERS:
|
||||
err = kfd_ioctl_get_clock_counters(filep, process,
|
||||
(void __user *)arg);
|
||||
break;
|
||||
|
||||
case KFD_IOC_GET_PROCESS_APERTURES:
|
||||
err = kfd_ioctl_get_process_apertures(filep, process,
|
||||
(void __user *)arg);
|
||||
break;
|
||||
|
||||
case KFD_IOC_UPDATE_QUEUE:
|
||||
err = kfd_ioctl_update_queue(filep, process,
|
||||
(void __user *)arg);
|
||||
break;
|
||||
|
||||
default:
|
||||
dev_err(kfd_device,
|
||||
"unknown ioctl cmd 0x%x, arg 0x%lx)\n",
|
||||
cmd, arg);
|
||||
err = -EINVAL;
|
||||
break;
|
||||
if (IS_ERR(process)) {
|
||||
dev_dbg(kfd_device, "no process\n");
|
||||
goto err_i1;
|
||||
}
|
||||
|
||||
if (err < 0)
|
||||
dev_err(kfd_device,
|
||||
"ioctl error %ld for ioctl cmd 0x%x (#%d)\n",
|
||||
err, cmd, _IOC_NR(cmd));
|
||||
/* Do not trust userspace, use our own definition */
|
||||
func = ioctl->func;
|
||||
|
||||
return err;
|
||||
if (unlikely(!func)) {
|
||||
dev_dbg(kfd_device, "no function\n");
|
||||
retcode = -EINVAL;
|
||||
goto err_i1;
|
||||
}
|
||||
|
||||
if (cmd & (IOC_IN | IOC_OUT)) {
|
||||
if (asize <= sizeof(stack_kdata)) {
|
||||
kdata = stack_kdata;
|
||||
} else {
|
||||
kdata = kmalloc(asize, GFP_KERNEL);
|
||||
if (!kdata) {
|
||||
retcode = -ENOMEM;
|
||||
goto err_i1;
|
||||
}
|
||||
}
|
||||
if (asize > usize)
|
||||
memset(kdata + usize, 0, asize - usize);
|
||||
}
|
||||
|
||||
if (cmd & IOC_IN) {
|
||||
if (copy_from_user(kdata, (void __user *)arg, usize) != 0) {
|
||||
retcode = -EFAULT;
|
||||
goto err_i1;
|
||||
}
|
||||
} else if (cmd & IOC_OUT) {
|
||||
memset(kdata, 0, usize);
|
||||
}
|
||||
|
||||
retcode = func(filep, process, kdata);
|
||||
|
||||
if (cmd & IOC_OUT)
|
||||
if (copy_to_user((void __user *)arg, kdata, usize) != 0)
|
||||
retcode = -EFAULT;
|
||||
|
||||
err_i1:
|
||||
if (!ioctl)
|
||||
dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n",
|
||||
task_pid_nr(current), cmd, nr);
|
||||
|
||||
if (kdata != stack_kdata)
|
||||
kfree(kdata);
|
||||
|
||||
if (retcode)
|
||||
dev_dbg(kfd_device, "ret = %d\n", retcode);
|
||||
|
||||
return retcode;
|
||||
}
|
||||
|
||||
static int kfd_mmap(struct file *filp, struct vm_area_struct *vma)
|
||||
|
|
|
@ -161,6 +161,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm,
|
|||
{
|
||||
int bit = qpd->vmid - KFD_VMID_START_OFFSET;
|
||||
|
||||
/* Release the vmid mapping */
|
||||
set_pasid_vmid_mapping(dqm, 0, qpd->vmid);
|
||||
|
||||
set_bit(bit, (unsigned long *)&dqm->vmid_bitmap);
|
||||
qpd->vmid = 0;
|
||||
q->properties.vmid = 0;
|
||||
|
@ -272,6 +275,18 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm,
|
|||
return retval;
|
||||
}
|
||||
|
||||
pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n",
|
||||
q->pipe,
|
||||
q->queue);
|
||||
|
||||
retval = mqd->load_mqd(mqd, q->mqd, q->pipe,
|
||||
q->queue, q->properties.write_ptr);
|
||||
if (retval != 0) {
|
||||
deallocate_hqd(dqm, q);
|
||||
mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj);
|
||||
return retval;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -320,6 +335,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
|
|||
{
|
||||
int retval;
|
||||
struct mqd_manager *mqd;
|
||||
bool prev_active = false;
|
||||
|
||||
BUG_ON(!dqm || !q || !q->mqd);
|
||||
|
||||
|
@ -330,10 +346,18 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q)
|
|||
return -ENOMEM;
|
||||
}
|
||||
|
||||
retval = mqd->update_mqd(mqd, q->mqd, &q->properties);
|
||||
if (q->properties.is_active == true)
|
||||
prev_active = true;
|
||||
|
||||
/*
|
||||
*
|
||||
* check active state vs. the previous state
|
||||
* and modify counter accordingly
|
||||
*/
|
||||
retval = mqd->update_mqd(mqd, q->mqd, &q->properties);
|
||||
if ((q->properties.is_active == true) && (prev_active == false))
|
||||
dqm->queue_count++;
|
||||
else
|
||||
else if ((q->properties.is_active == false) && (prev_active == true))
|
||||
dqm->queue_count--;
|
||||
|
||||
if (sched_policy != KFD_SCHED_POLICY_NO_HWS)
|
||||
|
|
|
@ -184,7 +184,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd,
|
|||
uint32_t queue_id)
|
||||
{
|
||||
|
||||
return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address,
|
||||
return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address,
|
||||
pipe_id, queue_id);
|
||||
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ int kfd_pasid_init(void)
|
|||
{
|
||||
pasid_limit = max_num_of_processes;
|
||||
|
||||
pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL);
|
||||
pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL);
|
||||
if (!pasid_bitmap)
|
||||
return -ENOMEM;
|
||||
|
||||
|
|
|
@ -463,6 +463,24 @@ struct kfd_process {
|
|||
bool is_32bit_user_mode;
|
||||
};
|
||||
|
||||
/**
|
||||
* Ioctl function type.
|
||||
*
|
||||
* \param filep pointer to file structure.
|
||||
* \param p amdkfd process pointer.
|
||||
* \param data pointer to arg that was copied from user.
|
||||
*/
|
||||
typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p,
|
||||
void *data);
|
||||
|
||||
struct amdkfd_ioctl_desc {
|
||||
unsigned int cmd;
|
||||
int flags;
|
||||
amdkfd_ioctl_t *func;
|
||||
unsigned int cmd_drv;
|
||||
const char *name;
|
||||
};
|
||||
|
||||
void kfd_process_create_wq(void);
|
||||
void kfd_process_destroy_wq(void);
|
||||
struct kfd_process *kfd_create_process(const struct task_struct *);
|
||||
|
|
|
@ -921,7 +921,7 @@ static int kfd_build_sysfs_node_tree(void)
|
|||
uint32_t i = 0;
|
||||
|
||||
list_for_each_entry(dev, &topology_device_list, list) {
|
||||
ret = kfd_build_sysfs_node_entry(dev, 0);
|
||||
ret = kfd_build_sysfs_node_entry(dev, i);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
i++;
|
||||
|
|
|
@ -183,7 +183,7 @@ struct kfd2kgd_calls {
|
|||
int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
uint32_t queue_id, uint32_t __user *wptr);
|
||||
|
||||
bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address,
|
||||
bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address,
|
||||
uint32_t pipe_id, uint32_t queue_id);
|
||||
|
||||
int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type,
|
||||
|
|
|
@ -1756,8 +1756,6 @@ struct drm_i915_private {
|
|||
*/
|
||||
struct workqueue_struct *dp_wq;
|
||||
|
||||
uint32_t bios_vgacntr;
|
||||
|
||||
/* Abstract the submission mechanism (legacy ringbuffer or execlists) away */
|
||||
struct {
|
||||
int (*do_execbuf)(struct drm_device *dev, struct drm_file *file,
|
||||
|
|
|
@ -1048,6 +1048,7 @@ int
|
|||
i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
||||
struct drm_file *file)
|
||||
{
|
||||
struct drm_i915_private *dev_priv = dev->dev_private;
|
||||
struct drm_i915_gem_pwrite *args = data;
|
||||
struct drm_i915_gem_object *obj;
|
||||
int ret;
|
||||
|
@ -1067,9 +1068,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data,
|
|||
return -EFAULT;
|
||||
}
|
||||
|
||||
intel_runtime_pm_get(dev_priv);
|
||||
|
||||
ret = i915_mutex_lock_interruptible(dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto put_rpm;
|
||||
|
||||
obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle));
|
||||
if (&obj->base == NULL) {
|
||||
|
@ -1121,6 +1124,9 @@ out:
|
|||
drm_gem_object_unreference(&obj->base);
|
||||
unlock:
|
||||
mutex_unlock(&dev->struct_mutex);
|
||||
put_rpm:
|
||||
intel_runtime_pm_put(dev_priv);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -3725,8 +3725,6 @@ static bool i8xx_handle_vblank(struct drm_device *dev,
|
|||
if ((iir & flip_pending) == 0)
|
||||
goto check_page_flip;
|
||||
|
||||
intel_prepare_page_flip(dev, plane);
|
||||
|
||||
/* We detect FlipDone by looking for the change in PendingFlip from '1'
|
||||
* to '0' on the following vblank, i.e. IIR has the Pendingflip
|
||||
* asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
|
||||
|
@ -3736,6 +3734,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev,
|
|||
if (I915_READ16(ISR) & flip_pending)
|
||||
goto check_page_flip;
|
||||
|
||||
intel_prepare_page_flip(dev, plane);
|
||||
intel_finish_page_flip(dev, pipe);
|
||||
return true;
|
||||
|
||||
|
@ -3907,8 +3906,6 @@ static bool i915_handle_vblank(struct drm_device *dev,
|
|||
if ((iir & flip_pending) == 0)
|
||||
goto check_page_flip;
|
||||
|
||||
intel_prepare_page_flip(dev, plane);
|
||||
|
||||
/* We detect FlipDone by looking for the change in PendingFlip from '1'
|
||||
* to '0' on the following vblank, i.e. IIR has the Pendingflip
|
||||
* asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence
|
||||
|
@ -3918,6 +3915,7 @@ static bool i915_handle_vblank(struct drm_device *dev,
|
|||
if (I915_READ(ISR) & flip_pending)
|
||||
goto check_page_flip;
|
||||
|
||||
intel_prepare_page_flip(dev, plane);
|
||||
intel_finish_page_flip(dev, pipe);
|
||||
return true;
|
||||
|
||||
|
|
|
@ -13057,11 +13057,7 @@ static void i915_disable_vga(struct drm_device *dev)
|
|||
vga_put(dev->pdev, VGA_RSRC_LEGACY_IO);
|
||||
udelay(300);
|
||||
|
||||
/*
|
||||
* Fujitsu-Siemens Lifebook S6010 (830) has problems resuming
|
||||
* from S3 without preserving (some of?) the other bits.
|
||||
*/
|
||||
I915_WRITE(vga_reg, dev_priv->bios_vgacntr | VGA_DISP_DISABLE);
|
||||
I915_WRITE(vga_reg, VGA_DISP_DISABLE);
|
||||
POSTING_READ(vga_reg);
|
||||
}
|
||||
|
||||
|
@ -13146,8 +13142,6 @@ void intel_modeset_init(struct drm_device *dev)
|
|||
|
||||
intel_shared_dpll_init(dev);
|
||||
|
||||
/* save the BIOS value before clobbering it */
|
||||
dev_priv->bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev));
|
||||
/* Just disable it once at startup */
|
||||
i915_disable_vga(dev);
|
||||
intel_setup_outputs(dev);
|
||||
|
|
|
@ -615,29 +615,6 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv,
|
|||
vlv_power_sequencer_reset(dev_priv);
|
||||
}
|
||||
|
||||
static void check_power_well_state(struct drm_i915_private *dev_priv,
|
||||
struct i915_power_well *power_well)
|
||||
{
|
||||
bool enabled = power_well->ops->is_enabled(dev_priv, power_well);
|
||||
|
||||
if (power_well->always_on || !i915.disable_power_well) {
|
||||
if (!enabled)
|
||||
goto mismatch;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if (enabled != (power_well->count > 0))
|
||||
goto mismatch;
|
||||
|
||||
return;
|
||||
|
||||
mismatch:
|
||||
WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n",
|
||||
power_well->name, power_well->always_on, enabled,
|
||||
power_well->count, i915.disable_power_well);
|
||||
}
|
||||
|
||||
/**
|
||||
* intel_display_power_get - grab a power domain reference
|
||||
* @dev_priv: i915 device instance
|
||||
|
@ -669,8 +646,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv,
|
|||
power_well->ops->enable(dev_priv, power_well);
|
||||
power_well->hw_enabled = true;
|
||||
}
|
||||
|
||||
check_power_well_state(dev_priv, power_well);
|
||||
}
|
||||
|
||||
power_domains->domain_use_count[domain]++;
|
||||
|
@ -709,8 +684,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv,
|
|||
power_well->hw_enabled = false;
|
||||
power_well->ops->disable(dev_priv, power_well);
|
||||
}
|
||||
|
||||
check_power_well_state(dev_priv, power_well);
|
||||
}
|
||||
|
||||
mutex_unlock(&power_domains->lock);
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
void
|
||||
nvkm_event_put(struct nvkm_event *event, u32 types, int index)
|
||||
{
|
||||
BUG_ON(!spin_is_locked(&event->refs_lock));
|
||||
assert_spin_locked(&event->refs_lock);
|
||||
while (types) {
|
||||
int type = __ffs(types); types &= ~(1 << type);
|
||||
if (--event->refs[index * event->types_nr + type] == 0) {
|
||||
|
@ -39,7 +39,7 @@ nvkm_event_put(struct nvkm_event *event, u32 types, int index)
|
|||
void
|
||||
nvkm_event_get(struct nvkm_event *event, u32 types, int index)
|
||||
{
|
||||
BUG_ON(!spin_is_locked(&event->refs_lock));
|
||||
assert_spin_locked(&event->refs_lock);
|
||||
while (types) {
|
||||
int type = __ffs(types); types &= ~(1 << type);
|
||||
if (++event->refs[index * event->types_nr + type] == 1) {
|
||||
|
|
|
@ -98,7 +98,7 @@ nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size)
|
|||
struct nvkm_event *event = notify->event;
|
||||
unsigned long flags;
|
||||
|
||||
BUG_ON(!spin_is_locked(&event->list_lock));
|
||||
assert_spin_locked(&event->list_lock);
|
||||
BUG_ON(size != notify->size);
|
||||
|
||||
spin_lock_irqsave(&event->refs_lock, flags);
|
||||
|
|
|
@ -249,6 +249,39 @@ nve0_identify(struct nouveau_device *device)
|
|||
device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
|
||||
device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass;
|
||||
break;
|
||||
case 0x106:
|
||||
device->cname = "GK208B";
|
||||
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass;
|
||||
device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_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 ] = gk20a_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_LTC ] = gk104_ltc_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;
|
||||
device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
|
||||
device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
|
||||
device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass;
|
||||
device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass;
|
||||
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;
|
||||
break;
|
||||
case 0x108:
|
||||
device->cname = "GK208";
|
||||
device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
|
||||
|
|
|
@ -44,8 +44,10 @@ static void
|
|||
pramin_fini(void *data)
|
||||
{
|
||||
struct priv *priv = data;
|
||||
nv_wr32(priv->bios, 0x001700, priv->bar0);
|
||||
kfree(priv);
|
||||
if (priv) {
|
||||
nv_wr32(priv->bios, 0x001700, priv->bar0);
|
||||
kfree(priv);
|
||||
}
|
||||
}
|
||||
|
||||
static void *
|
||||
|
|
|
@ -24,34 +24,71 @@
|
|||
|
||||
#include "nv50.h"
|
||||
|
||||
struct nvaa_ram_priv {
|
||||
struct nouveau_ram base;
|
||||
u64 poller_base;
|
||||
};
|
||||
|
||||
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 */
|
||||
u32 rsvd_head = ( 256 * 1024); /* vga memory */
|
||||
u32 rsvd_tail = (1024 * 1024); /* vbios etc */
|
||||
struct nouveau_fb *pfb = nouveau_fb(parent);
|
||||
struct nouveau_ram *ram;
|
||||
struct nvaa_ram_priv *priv;
|
||||
int ret;
|
||||
|
||||
ret = nouveau_ram_create(parent, engine, oclass, &ram);
|
||||
*pobject = nv_object(ram);
|
||||
ret = nouveau_ram_create(parent, engine, oclass, &priv);
|
||||
*pobject = nv_object(priv);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ram->size = nv_rd32(pfb, 0x10020c);
|
||||
ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32);
|
||||
priv->base.type = NV_MEM_TYPE_STOLEN;
|
||||
priv->base.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12;
|
||||
priv->base.size = (u64)nv_rd32(pfb, 0x100e14) << 12;
|
||||
|
||||
ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) -
|
||||
(rsvd_head + rsvd_tail), 1);
|
||||
rsvd_tail += 0x1000;
|
||||
priv->poller_base = priv->base.size - rsvd_tail;
|
||||
|
||||
ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12,
|
||||
(priv->base.size - (rsvd_head + rsvd_tail)) >> 12,
|
||||
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;
|
||||
priv->base.get = nv50_ram_get;
|
||||
priv->base.put = nv50_ram_put;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
nvaa_ram_init(struct nouveau_object *object)
|
||||
{
|
||||
struct nouveau_fb *pfb = nouveau_fb(object);
|
||||
struct nvaa_ram_priv *priv = (void *)object;
|
||||
int ret;
|
||||
u64 dniso, hostnb, flush;
|
||||
|
||||
ret = nouveau_ram_init(&priv->base);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
dniso = ((priv->base.size - (priv->poller_base + 0x00)) >> 5) - 1;
|
||||
hostnb = ((priv->base.size - (priv->poller_base + 0x20)) >> 5) - 1;
|
||||
flush = ((priv->base.size - (priv->poller_base + 0x40)) >> 5) - 1;
|
||||
|
||||
/* Enable NISO poller for various clients and set their associated
|
||||
* read address, only for MCP77/78 and MCP79/7A. (fd#25701)
|
||||
*/
|
||||
nv_wr32(pfb, 0x100c18, dniso);
|
||||
nv_mask(pfb, 0x100c14, 0x00000000, 0x00000001);
|
||||
nv_wr32(pfb, 0x100c1c, hostnb);
|
||||
nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002);
|
||||
nv_wr32(pfb, 0x100c24, flush);
|
||||
nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -60,7 +97,7 @@ nvaa_ram_oclass = {
|
|||
.ofuncs = &(struct nouveau_ofuncs) {
|
||||
.ctor = nvaa_ram_ctor,
|
||||
.dtor = _nouveau_ram_dtor,
|
||||
.init = _nouveau_ram_init,
|
||||
.init = nvaa_ram_init,
|
||||
.fini = _nouveau_ram_fini,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -24,13 +24,6 @@
|
|||
|
||||
#include "nv04.h"
|
||||
|
||||
static void
|
||||
nv4c_mc_msi_rearm(struct nouveau_mc *pmc)
|
||||
{
|
||||
struct nv04_mc_priv *priv = (void *)pmc;
|
||||
nv_wr08(priv, 0x088050, 0xff);
|
||||
}
|
||||
|
||||
struct nouveau_oclass *
|
||||
nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
|
||||
.base.handle = NV_SUBDEV(MC, 0x4c),
|
||||
|
@ -41,5 +34,4 @@ nv4c_mc_oclass = &(struct nouveau_mc_oclass) {
|
|||
.fini = _nouveau_mc_fini,
|
||||
},
|
||||
.intr = nv04_mc_intr,
|
||||
.msi_rearm = nv4c_mc_msi_rearm,
|
||||
}.base;
|
||||
|
|
|
@ -1572,8 +1572,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm)
|
|||
* so use the DMA API for them.
|
||||
*/
|
||||
if (!nv_device_is_cpu_coherent(device) &&
|
||||
ttm->caching_state == tt_uncached)
|
||||
ttm->caching_state == tt_uncached) {
|
||||
ttm_dma_unpopulate(ttm_dma, dev->dev);
|
||||
return;
|
||||
}
|
||||
|
||||
#if __OS_HAS_AGP
|
||||
if (drm->agp.stat == ENABLED) {
|
||||
|
|
|
@ -36,7 +36,14 @@ void
|
|||
nouveau_gem_object_del(struct drm_gem_object *gem)
|
||||
{
|
||||
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
||||
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
|
||||
struct ttm_buffer_object *bo = &nvbo->bo;
|
||||
struct device *dev = drm->dev->dev;
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (WARN_ON(ret < 0 && ret != -EACCES))
|
||||
return;
|
||||
|
||||
if (gem->import_attach)
|
||||
drm_prime_gem_destroy(gem, nvbo->bo.sg);
|
||||
|
@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem)
|
|||
/* reset filp so nouveau_bo_del_ttm() can test for it */
|
||||
gem->filp = NULL;
|
||||
ttm_bo_unref(&bo);
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
|
|||
{
|
||||
struct nouveau_cli *cli = nouveau_cli(file_priv);
|
||||
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
||||
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
|
||||
struct nouveau_vma *vma;
|
||||
struct device *dev = drm->dev->dev;
|
||||
int ret;
|
||||
|
||||
if (!cli->vm)
|
||||
|
@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv)
|
|||
goto out;
|
||||
}
|
||||
|
||||
ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
|
||||
if (ret) {
|
||||
kfree(vma);
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (ret < 0 && ret != -EACCES)
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = nouveau_bo_vma_add(nvbo, cli->vm, vma);
|
||||
if (ret)
|
||||
kfree(vma);
|
||||
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
} else {
|
||||
vma->refcount++;
|
||||
}
|
||||
|
@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
|
|||
{
|
||||
struct nouveau_cli *cli = nouveau_cli(file_priv);
|
||||
struct nouveau_bo *nvbo = nouveau_gem_object(gem);
|
||||
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
|
||||
struct device *dev = drm->dev->dev;
|
||||
struct nouveau_vma *vma;
|
||||
int ret;
|
||||
|
||||
|
@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv)
|
|||
|
||||
vma = nouveau_bo_vma_find(nvbo, cli->vm);
|
||||
if (vma) {
|
||||
if (--vma->refcount == 0)
|
||||
nouveau_gem_object_unmap(nvbo, vma);
|
||||
if (--vma->refcount == 0) {
|
||||
ret = pm_runtime_get_sync(dev);
|
||||
if (!WARN_ON(ret < 0 && ret != -EACCES)) {
|
||||
nouveau_gem_object_unmap(nvbo, vma);
|
||||
pm_runtime_mark_last_busy(dev);
|
||||
pm_runtime_put_autosuspend(dev);
|
||||
}
|
||||
}
|
||||
}
|
||||
ttm_bo_unreserve(&nvbo->bo);
|
||||
}
|
||||
|
|
|
@ -1851,10 +1851,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
|||
return pll;
|
||||
}
|
||||
/* otherwise, pick one of the plls */
|
||||
if ((rdev->family == CHIP_KAVERI) ||
|
||||
(rdev->family == CHIP_KABINI) ||
|
||||
if ((rdev->family == CHIP_KABINI) ||
|
||||
(rdev->family == CHIP_MULLINS)) {
|
||||
/* KB/KV/ML has PPLL1 and PPLL2 */
|
||||
/* KB/ML has PPLL1 and PPLL2 */
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
|
@ -1863,7 +1862,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc)
|
|||
DRM_ERROR("unable to allocate a PPLL\n");
|
||||
return ATOM_PPLL_INVALID;
|
||||
} else {
|
||||
/* CI has PPLL0, PPLL1, and PPLL2 */
|
||||
/* CI/KV has PPLL0, PPLL1, and PPLL2 */
|
||||
pll_in_use = radeon_get_pll_use_mask(crtc);
|
||||
if (!(pll_in_use & (1 << ATOM_PPLL2)))
|
||||
return ATOM_PPLL2;
|
||||
|
@ -2155,6 +2154,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc)
|
|||
case ATOM_PPLL0:
|
||||
/* disable the ppll */
|
||||
if ((rdev->family == CHIP_ARUBA) ||
|
||||
(rdev->family == CHIP_KAVERI) ||
|
||||
(rdev->family == CHIP_BONAIRE) ||
|
||||
(rdev->family == CHIP_HAWAII))
|
||||
atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id,
|
||||
|
|
|
@ -492,6 +492,10 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector,
|
|||
struct radeon_connector_atom_dig *dig_connector;
|
||||
int dp_clock;
|
||||
|
||||
if ((mode->clock > 340000) &&
|
||||
(!radeon_connector_is_dp12_capable(connector)))
|
||||
return MODE_CLOCK_HIGH;
|
||||
|
||||
if (!radeon_connector->con_priv)
|
||||
return MODE_CLOCK_HIGH;
|
||||
dig_connector = radeon_connector->con_priv;
|
||||
|
|
|
@ -2156,4 +2156,6 @@
|
|||
#define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu
|
||||
#define ATC_VM_APERTURE1_LOW_ADDR 0x3304u
|
||||
|
||||
#define IH_VMID_0_LUT 0x3D40u
|
||||
|
||||
#endif
|
||||
|
|
|
@ -103,7 +103,7 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder)
|
|||
}
|
||||
|
||||
sad_count = drm_edid_to_sad(radeon_connector->edid, &sads);
|
||||
if (sad_count < 0) {
|
||||
if (sad_count <= 0) {
|
||||
DRM_ERROR("Couldn't read SADs: %d\n", sad_count);
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -2745,13 +2745,11 @@ int kv_dpm_init(struct radeon_device *rdev)
|
|||
pi->enable_auto_thermal_throttling = true;
|
||||
pi->disable_nb_ps3_in_battery = false;
|
||||
if (radeon_bapm == -1) {
|
||||
/* There are stability issues reported on with
|
||||
* bapm enabled on an asrock system.
|
||||
*/
|
||||
if (rdev->pdev->subsystem_vendor == 0x1849)
|
||||
pi->bapm_enable = false;
|
||||
else
|
||||
/* only enable bapm on KB, ML by default */
|
||||
if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS)
|
||||
pi->bapm_enable = true;
|
||||
else
|
||||
pi->bapm_enable = false;
|
||||
} else if (radeon_bapm == 0) {
|
||||
pi->bapm_enable = false;
|
||||
} else {
|
||||
|
|
|
@ -72,7 +72,7 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id,
|
|||
static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
||||
uint32_t queue_id, uint32_t __user *wptr);
|
||||
|
||||
static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address,
|
||||
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
|
||||
uint32_t pipe_id, uint32_t queue_id);
|
||||
|
||||
static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
||||
|
@ -92,7 +92,7 @@ static const struct kfd2kgd_calls kfd2kgd = {
|
|||
.init_memory = kgd_init_memory,
|
||||
.init_pipeline = kgd_init_pipeline,
|
||||
.hqd_load = kgd_hqd_load,
|
||||
.hqd_is_occupies = kgd_hqd_is_occupies,
|
||||
.hqd_is_occupied = kgd_hqd_is_occupied,
|
||||
.hqd_destroy = kgd_hqd_destroy,
|
||||
.get_fw_version = get_fw_version
|
||||
};
|
||||
|
@ -101,6 +101,7 @@ static const struct kgd2kfd_calls *kgd2kfd;
|
|||
|
||||
bool radeon_kfd_init(void)
|
||||
{
|
||||
#if defined(CONFIG_HSA_AMD_MODULE)
|
||||
bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*,
|
||||
const struct kgd2kfd_calls**);
|
||||
|
||||
|
@ -117,6 +118,17 @@ bool radeon_kfd_init(void)
|
|||
}
|
||||
|
||||
return true;
|
||||
#elif defined(CONFIG_HSA_AMD)
|
||||
if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) {
|
||||
kgd2kfd = NULL;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
void radeon_kfd_fini(void)
|
||||
|
@ -378,6 +390,10 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid,
|
|||
cpu_relax();
|
||||
write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid);
|
||||
|
||||
/* Mapping vmid to pasid also for IH block */
|
||||
write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t),
|
||||
pasid_mapping);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -517,7 +533,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address,
|
||||
static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address,
|
||||
uint32_t pipe_id, uint32_t queue_id)
|
||||
{
|
||||
uint32_t act;
|
||||
|
@ -556,6 +572,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type,
|
|||
if (timeout == 0) {
|
||||
pr_err("kfd: cp queue preemption time out (%dms)\n",
|
||||
temp);
|
||||
release_queue(kgd);
|
||||
return -ETIME;
|
||||
}
|
||||
msleep(20);
|
||||
|
|
|
@ -1703,7 +1703,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev,
|
|||
u32 format;
|
||||
u32 *buffer;
|
||||
const u8 __user *data;
|
||||
int size, dwords, tex_width, blit_width, spitch;
|
||||
unsigned int size, dwords, tex_width, blit_width, spitch;
|
||||
u32 height;
|
||||
int i;
|
||||
u32 texpitch, microtile;
|
||||
|
|
|
@ -128,27 +128,34 @@ struct kfd_ioctl_get_process_apertures_args {
|
|||
uint32_t pad;
|
||||
};
|
||||
|
||||
#define KFD_IOC_MAGIC 'K'
|
||||
#define AMDKFD_IOCTL_BASE 'K'
|
||||
#define AMDKFD_IO(nr) _IO(AMDKFD_IOCTL_BASE, nr)
|
||||
#define AMDKFD_IOR(nr, type) _IOR(AMDKFD_IOCTL_BASE, nr, type)
|
||||
#define AMDKFD_IOW(nr, type) _IOW(AMDKFD_IOCTL_BASE, nr, type)
|
||||
#define AMDKFD_IOWR(nr, type) _IOWR(AMDKFD_IOCTL_BASE, nr, type)
|
||||
|
||||
#define KFD_IOC_GET_VERSION \
|
||||
_IOR(KFD_IOC_MAGIC, 1, struct kfd_ioctl_get_version_args)
|
||||
#define AMDKFD_IOC_GET_VERSION \
|
||||
AMDKFD_IOR(0x01, struct kfd_ioctl_get_version_args)
|
||||
|
||||
#define KFD_IOC_CREATE_QUEUE \
|
||||
_IOWR(KFD_IOC_MAGIC, 2, struct kfd_ioctl_create_queue_args)
|
||||
#define AMDKFD_IOC_CREATE_QUEUE \
|
||||
AMDKFD_IOWR(0x02, struct kfd_ioctl_create_queue_args)
|
||||
|
||||
#define KFD_IOC_DESTROY_QUEUE \
|
||||
_IOWR(KFD_IOC_MAGIC, 3, struct kfd_ioctl_destroy_queue_args)
|
||||
#define AMDKFD_IOC_DESTROY_QUEUE \
|
||||
AMDKFD_IOWR(0x03, struct kfd_ioctl_destroy_queue_args)
|
||||
|
||||
#define KFD_IOC_SET_MEMORY_POLICY \
|
||||
_IOW(KFD_IOC_MAGIC, 4, struct kfd_ioctl_set_memory_policy_args)
|
||||
#define AMDKFD_IOC_SET_MEMORY_POLICY \
|
||||
AMDKFD_IOW(0x04, struct kfd_ioctl_set_memory_policy_args)
|
||||
|
||||
#define KFD_IOC_GET_CLOCK_COUNTERS \
|
||||
_IOWR(KFD_IOC_MAGIC, 5, struct kfd_ioctl_get_clock_counters_args)
|
||||
#define AMDKFD_IOC_GET_CLOCK_COUNTERS \
|
||||
AMDKFD_IOWR(0x05, struct kfd_ioctl_get_clock_counters_args)
|
||||
|
||||
#define KFD_IOC_GET_PROCESS_APERTURES \
|
||||
_IOR(KFD_IOC_MAGIC, 6, struct kfd_ioctl_get_process_apertures_args)
|
||||
#define AMDKFD_IOC_GET_PROCESS_APERTURES \
|
||||
AMDKFD_IOR(0x06, struct kfd_ioctl_get_process_apertures_args)
|
||||
|
||||
#define KFD_IOC_UPDATE_QUEUE \
|
||||
_IOW(KFD_IOC_MAGIC, 7, struct kfd_ioctl_update_queue_args)
|
||||
#define AMDKFD_IOC_UPDATE_QUEUE \
|
||||
AMDKFD_IOW(0x07, struct kfd_ioctl_update_queue_args)
|
||||
|
||||
#define AMDKFD_COMMAND_START 0x01
|
||||
#define AMDKFD_COMMAND_END 0x08
|
||||
|
||||
#endif
|
||||
|
|
Загрузка…
Ссылка в новой задаче