diff options
Diffstat (limited to 'drivers/gpu/drm')
28 files changed, 387 insertions, 244 deletions
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 66e40398b3d3..e620807418ea 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile | |||
@@ -37,6 +37,7 @@ obj-$(CONFIG_DRM_MIPI_DSI) += drm_mipi_dsi.o | |||
37 | obj-$(CONFIG_DRM_TTM) += ttm/ | 37 | obj-$(CONFIG_DRM_TTM) += ttm/ |
38 | obj-$(CONFIG_DRM_TDFX) += tdfx/ | 38 | obj-$(CONFIG_DRM_TDFX) += tdfx/ |
39 | obj-$(CONFIG_DRM_R128) += r128/ | 39 | obj-$(CONFIG_DRM_R128) += r128/ |
40 | obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ | ||
40 | obj-$(CONFIG_DRM_RADEON)+= radeon/ | 41 | obj-$(CONFIG_DRM_RADEON)+= radeon/ |
41 | obj-$(CONFIG_DRM_MGA) += mga/ | 42 | obj-$(CONFIG_DRM_MGA) += mga/ |
42 | obj-$(CONFIG_DRM_I810) += i810/ | 43 | obj-$(CONFIG_DRM_I810) += i810/ |
@@ -67,4 +68,3 @@ obj-$(CONFIG_DRM_IMX) += imx/ | |||
67 | obj-y += i2c/ | 68 | obj-y += i2c/ |
68 | obj-y += panel/ | 69 | obj-y += panel/ |
69 | obj-y += bridge/ | 70 | obj-y += bridge/ |
70 | obj-$(CONFIG_HSA_AMD) += amd/amdkfd/ | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c index 7d4974b83af7..fcfdf23e1913 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_chardev.c | |||
@@ -31,7 +31,6 @@ | |||
31 | #include <uapi/linux/kfd_ioctl.h> | 31 | #include <uapi/linux/kfd_ioctl.h> |
32 | #include <linux/time.h> | 32 | #include <linux/time.h> |
33 | #include <linux/mm.h> | 33 | #include <linux/mm.h> |
34 | #include <linux/uaccess.h> | ||
35 | #include <uapi/asm-generic/mman-common.h> | 34 | #include <uapi/asm-generic/mman-common.h> |
36 | #include <asm/processor.h> | 35 | #include <asm/processor.h> |
37 | #include "kfd_priv.h" | 36 | #include "kfd_priv.h" |
@@ -127,17 +126,14 @@ static int kfd_open(struct inode *inode, struct file *filep) | |||
127 | return 0; | 126 | return 0; |
128 | } | 127 | } |
129 | 128 | ||
130 | static long kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, | 129 | static int kfd_ioctl_get_version(struct file *filep, struct kfd_process *p, |
131 | void __user *arg) | 130 | void *data) |
132 | { | 131 | { |
133 | struct kfd_ioctl_get_version_args args; | 132 | struct kfd_ioctl_get_version_args *args = data; |
134 | int err = 0; | 133 | int err = 0; |
135 | 134 | ||
136 | args.major_version = KFD_IOCTL_MAJOR_VERSION; | 135 | args->major_version = KFD_IOCTL_MAJOR_VERSION; |
137 | args.minor_version = KFD_IOCTL_MINOR_VERSION; | 136 | args->minor_version = KFD_IOCTL_MINOR_VERSION; |
138 | |||
139 | if (copy_to_user(arg, &args, sizeof(args))) | ||
140 | err = -EFAULT; | ||
141 | 137 | ||
142 | return err; | 138 | return err; |
143 | } | 139 | } |
@@ -221,10 +217,10 @@ static int set_queue_properties_from_user(struct queue_properties *q_properties, | |||
221 | return 0; | 217 | return 0; |
222 | } | 218 | } |
223 | 219 | ||
224 | static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | 220 | static int kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, |
225 | void __user *arg) | 221 | void *data) |
226 | { | 222 | { |
227 | struct kfd_ioctl_create_queue_args args; | 223 | struct kfd_ioctl_create_queue_args *args = data; |
228 | struct kfd_dev *dev; | 224 | struct kfd_dev *dev; |
229 | int err = 0; | 225 | int err = 0; |
230 | unsigned int queue_id; | 226 | unsigned int queue_id; |
@@ -233,16 +229,13 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | |||
233 | 229 | ||
234 | memset(&q_properties, 0, sizeof(struct queue_properties)); | 230 | memset(&q_properties, 0, sizeof(struct queue_properties)); |
235 | 231 | ||
236 | if (copy_from_user(&args, arg, sizeof(args))) | ||
237 | return -EFAULT; | ||
238 | |||
239 | pr_debug("kfd: creating queue ioctl\n"); | 232 | pr_debug("kfd: creating queue ioctl\n"); |
240 | 233 | ||
241 | err = set_queue_properties_from_user(&q_properties, &args); | 234 | err = set_queue_properties_from_user(&q_properties, args); |
242 | if (err) | 235 | if (err) |
243 | return err; | 236 | return err; |
244 | 237 | ||
245 | dev = kfd_device_by_id(args.gpu_id); | 238 | dev = kfd_device_by_id(args->gpu_id); |
246 | if (dev == NULL) | 239 | if (dev == NULL) |
247 | return -EINVAL; | 240 | return -EINVAL; |
248 | 241 | ||
@@ -250,7 +243,7 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | |||
250 | 243 | ||
251 | pdd = kfd_bind_process_to_device(dev, p); | 244 | pdd = kfd_bind_process_to_device(dev, p); |
252 | if (IS_ERR(pdd)) { | 245 | if (IS_ERR(pdd)) { |
253 | err = PTR_ERR(pdd); | 246 | err = -ESRCH; |
254 | goto err_bind_process; | 247 | goto err_bind_process; |
255 | } | 248 | } |
256 | 249 | ||
@@ -263,33 +256,26 @@ static long kfd_ioctl_create_queue(struct file *filep, struct kfd_process *p, | |||
263 | if (err != 0) | 256 | if (err != 0) |
264 | goto err_create_queue; | 257 | goto err_create_queue; |
265 | 258 | ||
266 | args.queue_id = queue_id; | 259 | args->queue_id = queue_id; |
267 | 260 | ||
268 | /* Return gpu_id as doorbell offset for mmap usage */ | 261 | /* Return gpu_id as doorbell offset for mmap usage */ |
269 | args.doorbell_offset = args.gpu_id << PAGE_SHIFT; | 262 | args->doorbell_offset = args->gpu_id << PAGE_SHIFT; |
270 | |||
271 | if (copy_to_user(arg, &args, sizeof(args))) { | ||
272 | err = -EFAULT; | ||
273 | goto err_copy_args_out; | ||
274 | } | ||
275 | 263 | ||
276 | mutex_unlock(&p->mutex); | 264 | mutex_unlock(&p->mutex); |
277 | 265 | ||
278 | pr_debug("kfd: queue id %d was created successfully\n", args.queue_id); | 266 | pr_debug("kfd: queue id %d was created successfully\n", args->queue_id); |
279 | 267 | ||
280 | pr_debug("ring buffer address == 0x%016llX\n", | 268 | pr_debug("ring buffer address == 0x%016llX\n", |
281 | args.ring_base_address); | 269 | args->ring_base_address); |
282 | 270 | ||
283 | pr_debug("read ptr address == 0x%016llX\n", | 271 | pr_debug("read ptr address == 0x%016llX\n", |
284 | args.read_pointer_address); | 272 | args->read_pointer_address); |
285 | 273 | ||
286 | pr_debug("write ptr address == 0x%016llX\n", | 274 | pr_debug("write ptr address == 0x%016llX\n", |
287 | args.write_pointer_address); | 275 | args->write_pointer_address); |
288 | 276 | ||
289 | return 0; | 277 | return 0; |
290 | 278 | ||
291 | err_copy_args_out: | ||
292 | pqm_destroy_queue(&p->pqm, queue_id); | ||
293 | err_create_queue: | 279 | err_create_queue: |
294 | err_bind_process: | 280 | err_bind_process: |
295 | mutex_unlock(&p->mutex); | 281 | mutex_unlock(&p->mutex); |
@@ -297,99 +283,90 @@ err_bind_process: | |||
297 | } | 283 | } |
298 | 284 | ||
299 | static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, | 285 | static int kfd_ioctl_destroy_queue(struct file *filp, struct kfd_process *p, |
300 | void __user *arg) | 286 | void *data) |
301 | { | 287 | { |
302 | int retval; | 288 | int retval; |
303 | struct kfd_ioctl_destroy_queue_args args; | 289 | struct kfd_ioctl_destroy_queue_args *args = data; |
304 | |||
305 | if (copy_from_user(&args, arg, sizeof(args))) | ||
306 | return -EFAULT; | ||
307 | 290 | ||
308 | pr_debug("kfd: destroying queue id %d for PASID %d\n", | 291 | pr_debug("kfd: destroying queue id %d for PASID %d\n", |
309 | args.queue_id, | 292 | args->queue_id, |
310 | p->pasid); | 293 | p->pasid); |
311 | 294 | ||
312 | mutex_lock(&p->mutex); | 295 | mutex_lock(&p->mutex); |
313 | 296 | ||
314 | retval = pqm_destroy_queue(&p->pqm, args.queue_id); | 297 | retval = pqm_destroy_queue(&p->pqm, args->queue_id); |
315 | 298 | ||
316 | mutex_unlock(&p->mutex); | 299 | mutex_unlock(&p->mutex); |
317 | return retval; | 300 | return retval; |
318 | } | 301 | } |
319 | 302 | ||
320 | static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, | 303 | static int kfd_ioctl_update_queue(struct file *filp, struct kfd_process *p, |
321 | void __user *arg) | 304 | void *data) |
322 | { | 305 | { |
323 | int retval; | 306 | int retval; |
324 | struct kfd_ioctl_update_queue_args args; | 307 | struct kfd_ioctl_update_queue_args *args = data; |
325 | struct queue_properties properties; | 308 | struct queue_properties properties; |
326 | 309 | ||
327 | if (copy_from_user(&args, arg, sizeof(args))) | 310 | if (args->queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { |
328 | return -EFAULT; | ||
329 | |||
330 | if (args.queue_percentage > KFD_MAX_QUEUE_PERCENTAGE) { | ||
331 | pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); | 311 | pr_err("kfd: queue percentage must be between 0 to KFD_MAX_QUEUE_PERCENTAGE\n"); |
332 | return -EINVAL; | 312 | return -EINVAL; |
333 | } | 313 | } |
334 | 314 | ||
335 | if (args.queue_priority > KFD_MAX_QUEUE_PRIORITY) { | 315 | if (args->queue_priority > KFD_MAX_QUEUE_PRIORITY) { |
336 | pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); | 316 | pr_err("kfd: queue priority must be between 0 to KFD_MAX_QUEUE_PRIORITY\n"); |
337 | return -EINVAL; | 317 | return -EINVAL; |
338 | } | 318 | } |
339 | 319 | ||
340 | if ((args.ring_base_address) && | 320 | if ((args->ring_base_address) && |
341 | (!access_ok(VERIFY_WRITE, | 321 | (!access_ok(VERIFY_WRITE, |
342 | (const void __user *) args.ring_base_address, | 322 | (const void __user *) args->ring_base_address, |
343 | sizeof(uint64_t)))) { | 323 | sizeof(uint64_t)))) { |
344 | pr_err("kfd: can't access ring base address\n"); | 324 | pr_err("kfd: can't access ring base address\n"); |
345 | return -EFAULT; | 325 | return -EFAULT; |
346 | } | 326 | } |
347 | 327 | ||
348 | if (!is_power_of_2(args.ring_size) && (args.ring_size != 0)) { | 328 | if (!is_power_of_2(args->ring_size) && (args->ring_size != 0)) { |
349 | pr_err("kfd: ring size must be a power of 2 or 0\n"); | 329 | pr_err("kfd: ring size must be a power of 2 or 0\n"); |
350 | return -EINVAL; | 330 | return -EINVAL; |
351 | } | 331 | } |
352 | 332 | ||
353 | properties.queue_address = args.ring_base_address; | 333 | properties.queue_address = args->ring_base_address; |
354 | properties.queue_size = args.ring_size; | 334 | properties.queue_size = args->ring_size; |
355 | properties.queue_percent = args.queue_percentage; | 335 | properties.queue_percent = args->queue_percentage; |
356 | properties.priority = args.queue_priority; | 336 | properties.priority = args->queue_priority; |
357 | 337 | ||
358 | pr_debug("kfd: updating queue id %d for PASID %d\n", | 338 | pr_debug("kfd: updating queue id %d for PASID %d\n", |
359 | args.queue_id, p->pasid); | 339 | args->queue_id, p->pasid); |
360 | 340 | ||
361 | mutex_lock(&p->mutex); | 341 | mutex_lock(&p->mutex); |
362 | 342 | ||
363 | retval = pqm_update_queue(&p->pqm, args.queue_id, &properties); | 343 | retval = pqm_update_queue(&p->pqm, args->queue_id, &properties); |
364 | 344 | ||
365 | mutex_unlock(&p->mutex); | 345 | mutex_unlock(&p->mutex); |
366 | 346 | ||
367 | return retval; | 347 | return retval; |
368 | } | 348 | } |
369 | 349 | ||
370 | static long kfd_ioctl_set_memory_policy(struct file *filep, | 350 | static int kfd_ioctl_set_memory_policy(struct file *filep, |
371 | struct kfd_process *p, void __user *arg) | 351 | struct kfd_process *p, void *data) |
372 | { | 352 | { |
373 | struct kfd_ioctl_set_memory_policy_args args; | 353 | struct kfd_ioctl_set_memory_policy_args *args = data; |
374 | struct kfd_dev *dev; | 354 | struct kfd_dev *dev; |
375 | int err = 0; | 355 | int err = 0; |
376 | struct kfd_process_device *pdd; | 356 | struct kfd_process_device *pdd; |
377 | enum cache_policy default_policy, alternate_policy; | 357 | enum cache_policy default_policy, alternate_policy; |
378 | 358 | ||
379 | if (copy_from_user(&args, arg, sizeof(args))) | 359 | if (args->default_policy != KFD_IOC_CACHE_POLICY_COHERENT |
380 | return -EFAULT; | 360 | && args->default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { |
381 | |||
382 | if (args.default_policy != KFD_IOC_CACHE_POLICY_COHERENT | ||
383 | && args.default_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { | ||
384 | return -EINVAL; | 361 | return -EINVAL; |
385 | } | 362 | } |
386 | 363 | ||
387 | if (args.alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT | 364 | if (args->alternate_policy != KFD_IOC_CACHE_POLICY_COHERENT |
388 | && args.alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { | 365 | && args->alternate_policy != KFD_IOC_CACHE_POLICY_NONCOHERENT) { |
389 | return -EINVAL; | 366 | return -EINVAL; |
390 | } | 367 | } |
391 | 368 | ||
392 | dev = kfd_device_by_id(args.gpu_id); | 369 | dev = kfd_device_by_id(args->gpu_id); |
393 | if (dev == NULL) | 370 | if (dev == NULL) |
394 | return -EINVAL; | 371 | return -EINVAL; |
395 | 372 | ||
@@ -397,23 +374,23 @@ static long kfd_ioctl_set_memory_policy(struct file *filep, | |||
397 | 374 | ||
398 | pdd = kfd_bind_process_to_device(dev, p); | 375 | pdd = kfd_bind_process_to_device(dev, p); |
399 | if (IS_ERR(pdd)) { | 376 | if (IS_ERR(pdd)) { |
400 | err = PTR_ERR(pdd); | 377 | err = -ESRCH; |
401 | goto out; | 378 | goto out; |
402 | } | 379 | } |
403 | 380 | ||
404 | default_policy = (args.default_policy == KFD_IOC_CACHE_POLICY_COHERENT) | 381 | default_policy = (args->default_policy == KFD_IOC_CACHE_POLICY_COHERENT) |
405 | ? cache_policy_coherent : cache_policy_noncoherent; | 382 | ? cache_policy_coherent : cache_policy_noncoherent; |
406 | 383 | ||
407 | alternate_policy = | 384 | alternate_policy = |
408 | (args.alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) | 385 | (args->alternate_policy == KFD_IOC_CACHE_POLICY_COHERENT) |
409 | ? cache_policy_coherent : cache_policy_noncoherent; | 386 | ? cache_policy_coherent : cache_policy_noncoherent; |
410 | 387 | ||
411 | if (!dev->dqm->set_cache_memory_policy(dev->dqm, | 388 | if (!dev->dqm->set_cache_memory_policy(dev->dqm, |
412 | &pdd->qpd, | 389 | &pdd->qpd, |
413 | default_policy, | 390 | default_policy, |
414 | alternate_policy, | 391 | alternate_policy, |
415 | (void __user *)args.alternate_aperture_base, | 392 | (void __user *)args->alternate_aperture_base, |
416 | args.alternate_aperture_size)) | 393 | args->alternate_aperture_size)) |
417 | err = -EINVAL; | 394 | err = -EINVAL; |
418 | 395 | ||
419 | out: | 396 | out: |
@@ -422,53 +399,44 @@ out: | |||
422 | return err; | 399 | return err; |
423 | } | 400 | } |
424 | 401 | ||
425 | static long kfd_ioctl_get_clock_counters(struct file *filep, | 402 | static int kfd_ioctl_get_clock_counters(struct file *filep, |
426 | struct kfd_process *p, void __user *arg) | 403 | struct kfd_process *p, void *data) |
427 | { | 404 | { |
428 | struct kfd_ioctl_get_clock_counters_args args; | 405 | struct kfd_ioctl_get_clock_counters_args *args = data; |
429 | struct kfd_dev *dev; | 406 | struct kfd_dev *dev; |
430 | struct timespec time; | 407 | struct timespec time; |
431 | 408 | ||
432 | if (copy_from_user(&args, arg, sizeof(args))) | 409 | dev = kfd_device_by_id(args->gpu_id); |
433 | return -EFAULT; | ||
434 | |||
435 | dev = kfd_device_by_id(args.gpu_id); | ||
436 | if (dev == NULL) | 410 | if (dev == NULL) |
437 | return -EINVAL; | 411 | return -EINVAL; |
438 | 412 | ||
439 | /* Reading GPU clock counter from KGD */ | 413 | /* Reading GPU clock counter from KGD */ |
440 | args.gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); | 414 | args->gpu_clock_counter = kfd2kgd->get_gpu_clock_counter(dev->kgd); |
441 | 415 | ||
442 | /* No access to rdtsc. Using raw monotonic time */ | 416 | /* No access to rdtsc. Using raw monotonic time */ |
443 | getrawmonotonic(&time); | 417 | getrawmonotonic(&time); |
444 | args.cpu_clock_counter = (uint64_t)timespec_to_ns(&time); | 418 | args->cpu_clock_counter = (uint64_t)timespec_to_ns(&time); |
445 | 419 | ||
446 | get_monotonic_boottime(&time); | 420 | get_monotonic_boottime(&time); |
447 | args.system_clock_counter = (uint64_t)timespec_to_ns(&time); | 421 | args->system_clock_counter = (uint64_t)timespec_to_ns(&time); |
448 | 422 | ||
449 | /* Since the counter is in nano-seconds we use 1GHz frequency */ | 423 | /* Since the counter is in nano-seconds we use 1GHz frequency */ |
450 | args.system_clock_freq = 1000000000; | 424 | args->system_clock_freq = 1000000000; |
451 | |||
452 | if (copy_to_user(arg, &args, sizeof(args))) | ||
453 | return -EFAULT; | ||
454 | 425 | ||
455 | return 0; | 426 | return 0; |
456 | } | 427 | } |
457 | 428 | ||
458 | 429 | ||
459 | static int kfd_ioctl_get_process_apertures(struct file *filp, | 430 | static int kfd_ioctl_get_process_apertures(struct file *filp, |
460 | struct kfd_process *p, void __user *arg) | 431 | struct kfd_process *p, void *data) |
461 | { | 432 | { |
462 | struct kfd_ioctl_get_process_apertures_args args; | 433 | struct kfd_ioctl_get_process_apertures_args *args = data; |
463 | struct kfd_process_device_apertures *pAperture; | 434 | struct kfd_process_device_apertures *pAperture; |
464 | struct kfd_process_device *pdd; | 435 | struct kfd_process_device *pdd; |
465 | 436 | ||
466 | dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); | 437 | dev_dbg(kfd_device, "get apertures for PASID %d", p->pasid); |
467 | 438 | ||
468 | if (copy_from_user(&args, arg, sizeof(args))) | 439 | args->num_of_nodes = 0; |
469 | return -EFAULT; | ||
470 | |||
471 | args.num_of_nodes = 0; | ||
472 | 440 | ||
473 | mutex_lock(&p->mutex); | 441 | mutex_lock(&p->mutex); |
474 | 442 | ||
@@ -477,7 +445,8 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, | |||
477 | /* Run over all pdd of the process */ | 445 | /* Run over all pdd of the process */ |
478 | pdd = kfd_get_first_process_device_data(p); | 446 | pdd = kfd_get_first_process_device_data(p); |
479 | do { | 447 | do { |
480 | pAperture = &args.process_apertures[args.num_of_nodes]; | 448 | pAperture = |
449 | &args->process_apertures[args->num_of_nodes]; | ||
481 | pAperture->gpu_id = pdd->dev->id; | 450 | pAperture->gpu_id = pdd->dev->id; |
482 | pAperture->lds_base = pdd->lds_base; | 451 | pAperture->lds_base = pdd->lds_base; |
483 | pAperture->lds_limit = pdd->lds_limit; | 452 | pAperture->lds_limit = pdd->lds_limit; |
@@ -487,7 +456,7 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, | |||
487 | pAperture->scratch_limit = pdd->scratch_limit; | 456 | pAperture->scratch_limit = pdd->scratch_limit; |
488 | 457 | ||
489 | dev_dbg(kfd_device, | 458 | dev_dbg(kfd_device, |
490 | "node id %u\n", args.num_of_nodes); | 459 | "node id %u\n", args->num_of_nodes); |
491 | dev_dbg(kfd_device, | 460 | dev_dbg(kfd_device, |
492 | "gpu id %u\n", pdd->dev->id); | 461 | "gpu id %u\n", pdd->dev->id); |
493 | dev_dbg(kfd_device, | 462 | dev_dbg(kfd_device, |
@@ -503,80 +472,131 @@ static int kfd_ioctl_get_process_apertures(struct file *filp, | |||
503 | dev_dbg(kfd_device, | 472 | dev_dbg(kfd_device, |
504 | "scratch_limit %llX\n", pdd->scratch_limit); | 473 | "scratch_limit %llX\n", pdd->scratch_limit); |
505 | 474 | ||
506 | args.num_of_nodes++; | 475 | args->num_of_nodes++; |
507 | } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && | 476 | } while ((pdd = kfd_get_next_process_device_data(p, pdd)) != NULL && |
508 | (args.num_of_nodes < NUM_OF_SUPPORTED_GPUS)); | 477 | (args->num_of_nodes < NUM_OF_SUPPORTED_GPUS)); |
509 | } | 478 | } |
510 | 479 | ||
511 | mutex_unlock(&p->mutex); | 480 | mutex_unlock(&p->mutex); |
512 | 481 | ||
513 | if (copy_to_user(arg, &args, sizeof(args))) | ||
514 | return -EFAULT; | ||
515 | |||
516 | return 0; | 482 | return 0; |
517 | } | 483 | } |
518 | 484 | ||
485 | #define AMDKFD_IOCTL_DEF(ioctl, _func, _flags) \ | ||
486 | [_IOC_NR(ioctl)] = {.cmd = ioctl, .func = _func, .flags = _flags, .cmd_drv = 0, .name = #ioctl} | ||
487 | |||
488 | /** Ioctl table */ | ||
489 | static const struct amdkfd_ioctl_desc amdkfd_ioctls[] = { | ||
490 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_VERSION, | ||
491 | kfd_ioctl_get_version, 0), | ||
492 | |||
493 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_CREATE_QUEUE, | ||
494 | kfd_ioctl_create_queue, 0), | ||
495 | |||
496 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_DESTROY_QUEUE, | ||
497 | kfd_ioctl_destroy_queue, 0), | ||
498 | |||
499 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_SET_MEMORY_POLICY, | ||
500 | kfd_ioctl_set_memory_policy, 0), | ||
501 | |||
502 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_CLOCK_COUNTERS, | ||
503 | kfd_ioctl_get_clock_counters, 0), | ||
504 | |||
505 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_GET_PROCESS_APERTURES, | ||
506 | kfd_ioctl_get_process_apertures, 0), | ||
507 | |||
508 | AMDKFD_IOCTL_DEF(AMDKFD_IOC_UPDATE_QUEUE, | ||
509 | kfd_ioctl_update_queue, 0), | ||
510 | }; | ||
511 | |||
512 | #define AMDKFD_CORE_IOCTL_COUNT ARRAY_SIZE(amdkfd_ioctls) | ||
513 | |||
519 | static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) | 514 | static long kfd_ioctl(struct file *filep, unsigned int cmd, unsigned long arg) |
520 | { | 515 | { |
521 | struct kfd_process *process; | 516 | struct kfd_process *process; |
522 | long err = -EINVAL; | 517 | amdkfd_ioctl_t *func; |
518 | const struct amdkfd_ioctl_desc *ioctl = NULL; | ||
519 | unsigned int nr = _IOC_NR(cmd); | ||
520 | char stack_kdata[128]; | ||
521 | char *kdata = NULL; | ||
522 | unsigned int usize, asize; | ||
523 | int retcode = -EINVAL; | ||
523 | 524 | ||
524 | dev_dbg(kfd_device, | 525 | if (nr >= AMDKFD_CORE_IOCTL_COUNT) |
525 | "ioctl cmd 0x%x (#%d), arg 0x%lx\n", | 526 | goto err_i1; |
526 | cmd, _IOC_NR(cmd), arg); | 527 | |
528 | if ((nr >= AMDKFD_COMMAND_START) && (nr < AMDKFD_COMMAND_END)) { | ||
529 | u32 amdkfd_size; | ||
530 | |||
531 | ioctl = &amdkfd_ioctls[nr]; | ||
532 | |||
533 | amdkfd_size = _IOC_SIZE(ioctl->cmd); | ||
534 | usize = asize = _IOC_SIZE(cmd); | ||
535 | if (amdkfd_size > asize) | ||
536 | asize = amdkfd_size; | ||
537 | |||
538 | cmd = ioctl->cmd; | ||
539 | } else | ||
540 | goto err_i1; | ||
541 | |||
542 | dev_dbg(kfd_device, "ioctl cmd 0x%x (#%d), arg 0x%lx\n", cmd, nr, arg); | ||
527 | 543 | ||
528 | process = kfd_get_process(current); | 544 | process = kfd_get_process(current); |
529 | if (IS_ERR(process)) | 545 | if (IS_ERR(process)) { |
530 | return PTR_ERR(process); | 546 | dev_dbg(kfd_device, "no process\n"); |
547 | goto err_i1; | ||
548 | } | ||
531 | 549 | ||
532 | switch (cmd) { | 550 | /* Do not trust userspace, use our own definition */ |
533 | case KFD_IOC_GET_VERSION: | 551 | func = ioctl->func; |
534 | err = kfd_ioctl_get_version(filep, process, (void __user *)arg); | 552 | |
535 | break; | 553 | if (unlikely(!func)) { |
536 | case KFD_IOC_CREATE_QUEUE: | 554 | dev_dbg(kfd_device, "no function\n"); |
537 | err = kfd_ioctl_create_queue(filep, process, | 555 | retcode = -EINVAL; |
538 | (void __user *)arg); | 556 | goto err_i1; |
539 | break; | ||
540 | |||
541 | case KFD_IOC_DESTROY_QUEUE: | ||
542 | err = kfd_ioctl_destroy_queue(filep, process, | ||
543 | (void __user *)arg); | ||
544 | break; | ||
545 | |||
546 | case KFD_IOC_SET_MEMORY_POLICY: | ||
547 | err = kfd_ioctl_set_memory_policy(filep, process, | ||
548 | (void __user *)arg); | ||
549 | break; | ||
550 | |||
551 | case KFD_IOC_GET_CLOCK_COUNTERS: | ||
552 | err = kfd_ioctl_get_clock_counters(filep, process, | ||
553 | (void __user *)arg); | ||
554 | break; | ||
555 | |||
556 | case KFD_IOC_GET_PROCESS_APERTURES: | ||
557 | err = kfd_ioctl_get_process_apertures(filep, process, | ||
558 | (void __user *)arg); | ||
559 | break; | ||
560 | |||
561 | case KFD_IOC_UPDATE_QUEUE: | ||
562 | err = kfd_ioctl_update_queue(filep, process, | ||
563 | (void __user *)arg); | ||
564 | break; | ||
565 | |||
566 | default: | ||
567 | dev_err(kfd_device, | ||
568 | "unknown ioctl cmd 0x%x, arg 0x%lx)\n", | ||
569 | cmd, arg); | ||
570 | err = -EINVAL; | ||
571 | break; | ||
572 | } | 557 | } |
573 | 558 | ||
574 | if (err < 0) | 559 | if (cmd & (IOC_IN | IOC_OUT)) { |
575 | dev_err(kfd_device, | 560 | if (asize <= sizeof(stack_kdata)) { |
576 | "ioctl error %ld for ioctl cmd 0x%x (#%d)\n", | 561 | kdata = stack_kdata; |
577 | err, cmd, _IOC_NR(cmd)); | 562 | } else { |
563 | kdata = kmalloc(asize, GFP_KERNEL); | ||
564 | if (!kdata) { | ||
565 | retcode = -ENOMEM; | ||
566 | goto err_i1; | ||
567 | } | ||
568 | } | ||
569 | if (asize > usize) | ||
570 | memset(kdata + usize, 0, asize - usize); | ||
571 | } | ||
578 | 572 | ||
579 | return err; | 573 | if (cmd & IOC_IN) { |
574 | if (copy_from_user(kdata, (void __user *)arg, usize) != 0) { | ||
575 | retcode = -EFAULT; | ||
576 | goto err_i1; | ||
577 | } | ||
578 | } else if (cmd & IOC_OUT) { | ||
579 | memset(kdata, 0, usize); | ||
580 | } | ||
581 | |||
582 | retcode = func(filep, process, kdata); | ||
583 | |||
584 | if (cmd & IOC_OUT) | ||
585 | if (copy_to_user((void __user *)arg, kdata, usize) != 0) | ||
586 | retcode = -EFAULT; | ||
587 | |||
588 | err_i1: | ||
589 | if (!ioctl) | ||
590 | dev_dbg(kfd_device, "invalid ioctl: pid=%d, cmd=0x%02x, nr=0x%02x\n", | ||
591 | task_pid_nr(current), cmd, nr); | ||
592 | |||
593 | if (kdata != stack_kdata) | ||
594 | kfree(kdata); | ||
595 | |||
596 | if (retcode) | ||
597 | dev_dbg(kfd_device, "ret = %d\n", retcode); | ||
598 | |||
599 | return retcode; | ||
580 | } | 600 | } |
581 | 601 | ||
582 | static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) | 602 | static int kfd_mmap(struct file *filp, struct vm_area_struct *vma) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c index 924e90c072e5..9c8961d22360 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_device_queue_manager.c | |||
@@ -161,6 +161,9 @@ static void deallocate_vmid(struct device_queue_manager *dqm, | |||
161 | { | 161 | { |
162 | int bit = qpd->vmid - KFD_VMID_START_OFFSET; | 162 | int bit = qpd->vmid - KFD_VMID_START_OFFSET; |
163 | 163 | ||
164 | /* Release the vmid mapping */ | ||
165 | set_pasid_vmid_mapping(dqm, 0, qpd->vmid); | ||
166 | |||
164 | set_bit(bit, (unsigned long *)&dqm->vmid_bitmap); | 167 | set_bit(bit, (unsigned long *)&dqm->vmid_bitmap); |
165 | qpd->vmid = 0; | 168 | qpd->vmid = 0; |
166 | q->properties.vmid = 0; | 169 | q->properties.vmid = 0; |
@@ -272,6 +275,18 @@ static int create_compute_queue_nocpsch(struct device_queue_manager *dqm, | |||
272 | return retval; | 275 | return retval; |
273 | } | 276 | } |
274 | 277 | ||
278 | pr_debug("kfd: loading mqd to hqd on pipe (%d) queue (%d)\n", | ||
279 | q->pipe, | ||
280 | q->queue); | ||
281 | |||
282 | retval = mqd->load_mqd(mqd, q->mqd, q->pipe, | ||
283 | q->queue, q->properties.write_ptr); | ||
284 | if (retval != 0) { | ||
285 | deallocate_hqd(dqm, q); | ||
286 | mqd->uninit_mqd(mqd, q->mqd, q->mqd_mem_obj); | ||
287 | return retval; | ||
288 | } | ||
289 | |||
275 | return 0; | 290 | return 0; |
276 | } | 291 | } |
277 | 292 | ||
@@ -320,6 +335,7 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) | |||
320 | { | 335 | { |
321 | int retval; | 336 | int retval; |
322 | struct mqd_manager *mqd; | 337 | struct mqd_manager *mqd; |
338 | bool prev_active = false; | ||
323 | 339 | ||
324 | BUG_ON(!dqm || !q || !q->mqd); | 340 | BUG_ON(!dqm || !q || !q->mqd); |
325 | 341 | ||
@@ -330,10 +346,18 @@ static int update_queue(struct device_queue_manager *dqm, struct queue *q) | |||
330 | return -ENOMEM; | 346 | return -ENOMEM; |
331 | } | 347 | } |
332 | 348 | ||
333 | retval = mqd->update_mqd(mqd, q->mqd, &q->properties); | ||
334 | if (q->properties.is_active == true) | 349 | if (q->properties.is_active == true) |
350 | prev_active = true; | ||
351 | |||
352 | /* | ||
353 | * | ||
354 | * check active state vs. the previous state | ||
355 | * and modify counter accordingly | ||
356 | */ | ||
357 | retval = mqd->update_mqd(mqd, q->mqd, &q->properties); | ||
358 | if ((q->properties.is_active == true) && (prev_active == false)) | ||
335 | dqm->queue_count++; | 359 | dqm->queue_count++; |
336 | else | 360 | else if ((q->properties.is_active == false) && (prev_active == true)) |
337 | dqm->queue_count--; | 361 | dqm->queue_count--; |
338 | 362 | ||
339 | if (sched_policy != KFD_SCHED_POLICY_NO_HWS) | 363 | if (sched_policy != KFD_SCHED_POLICY_NO_HWS) |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c index adc31474e786..4c3828cf45bf 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_mqd_manager.c | |||
@@ -184,7 +184,7 @@ static bool is_occupied(struct mqd_manager *mm, void *mqd, | |||
184 | uint32_t queue_id) | 184 | uint32_t queue_id) |
185 | { | 185 | { |
186 | 186 | ||
187 | return kfd2kgd->hqd_is_occupies(mm->dev->kgd, queue_address, | 187 | return kfd2kgd->hqd_is_occupied(mm->dev->kgd, queue_address, |
188 | pipe_id, queue_id); | 188 | pipe_id, queue_id); |
189 | 189 | ||
190 | } | 190 | } |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c index 71699ad97d74..4c25ef504f79 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_pasid.c | |||
@@ -32,7 +32,7 @@ int kfd_pasid_init(void) | |||
32 | { | 32 | { |
33 | pasid_limit = max_num_of_processes; | 33 | pasid_limit = max_num_of_processes; |
34 | 34 | ||
35 | pasid_bitmap = kzalloc(BITS_TO_LONGS(pasid_limit), GFP_KERNEL); | 35 | pasid_bitmap = kcalloc(BITS_TO_LONGS(pasid_limit), sizeof(long), GFP_KERNEL); |
36 | if (!pasid_bitmap) | 36 | if (!pasid_bitmap) |
37 | return -ENOMEM; | 37 | return -ENOMEM; |
38 | 38 | ||
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h index f9fb81e3bb09..a5edb29507e3 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_priv.h +++ b/drivers/gpu/drm/amd/amdkfd/kfd_priv.h | |||
@@ -463,6 +463,24 @@ struct kfd_process { | |||
463 | bool is_32bit_user_mode; | 463 | bool is_32bit_user_mode; |
464 | }; | 464 | }; |
465 | 465 | ||
466 | /** | ||
467 | * Ioctl function type. | ||
468 | * | ||
469 | * \param filep pointer to file structure. | ||
470 | * \param p amdkfd process pointer. | ||
471 | * \param data pointer to arg that was copied from user. | ||
472 | */ | ||
473 | typedef int amdkfd_ioctl_t(struct file *filep, struct kfd_process *p, | ||
474 | void *data); | ||
475 | |||
476 | struct amdkfd_ioctl_desc { | ||
477 | unsigned int cmd; | ||
478 | int flags; | ||
479 | amdkfd_ioctl_t *func; | ||
480 | unsigned int cmd_drv; | ||
481 | const char *name; | ||
482 | }; | ||
483 | |||
466 | void kfd_process_create_wq(void); | 484 | void kfd_process_create_wq(void); |
467 | void kfd_process_destroy_wq(void); | 485 | void kfd_process_destroy_wq(void); |
468 | struct kfd_process *kfd_create_process(const struct task_struct *); | 486 | struct kfd_process *kfd_create_process(const struct task_struct *); |
diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c index b11792d7e70e..cca1708fd811 100644 --- a/drivers/gpu/drm/amd/amdkfd/kfd_topology.c +++ b/drivers/gpu/drm/amd/amdkfd/kfd_topology.c | |||
@@ -921,7 +921,7 @@ static int kfd_build_sysfs_node_tree(void) | |||
921 | uint32_t i = 0; | 921 | uint32_t i = 0; |
922 | 922 | ||
923 | list_for_each_entry(dev, &topology_device_list, list) { | 923 | list_for_each_entry(dev, &topology_device_list, list) { |
924 | ret = kfd_build_sysfs_node_entry(dev, 0); | 924 | ret = kfd_build_sysfs_node_entry(dev, i); |
925 | if (ret < 0) | 925 | if (ret < 0) |
926 | return ret; | 926 | return ret; |
927 | i++; | 927 | i++; |
diff --git a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h index 47b551970a14..96a512208fad 100644 --- a/drivers/gpu/drm/amd/include/kgd_kfd_interface.h +++ b/drivers/gpu/drm/amd/include/kgd_kfd_interface.h | |||
@@ -183,7 +183,7 @@ struct kfd2kgd_calls { | |||
183 | int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | 183 | int (*hqd_load)(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, |
184 | uint32_t queue_id, uint32_t __user *wptr); | 184 | uint32_t queue_id, uint32_t __user *wptr); |
185 | 185 | ||
186 | bool (*hqd_is_occupies)(struct kgd_dev *kgd, uint64_t queue_address, | 186 | bool (*hqd_is_occupied)(struct kgd_dev *kgd, uint64_t queue_address, |
187 | uint32_t pipe_id, uint32_t queue_id); | 187 | uint32_t pipe_id, uint32_t queue_id); |
188 | 188 | ||
189 | int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, | 189 | int (*hqd_destroy)(struct kgd_dev *kgd, uint32_t reset_type, |
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 70d0f0f06f1a..e9f891c432f8 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h | |||
@@ -1756,8 +1756,6 @@ struct drm_i915_private { | |||
1756 | */ | 1756 | */ |
1757 | struct workqueue_struct *dp_wq; | 1757 | struct workqueue_struct *dp_wq; |
1758 | 1758 | ||
1759 | uint32_t bios_vgacntr; | ||
1760 | |||
1761 | /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ | 1759 | /* Abstract the submission mechanism (legacy ringbuffer or execlists) away */ |
1762 | struct { | 1760 | struct { |
1763 | int (*do_execbuf)(struct drm_device *dev, struct drm_file *file, | 1761 | int (*do_execbuf)(struct drm_device *dev, struct drm_file *file, |
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c index 52adcb680be3..c11603b4cf1d 100644 --- a/drivers/gpu/drm/i915/i915_gem.c +++ b/drivers/gpu/drm/i915/i915_gem.c | |||
@@ -1048,6 +1048,7 @@ int | |||
1048 | i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | 1048 | i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, |
1049 | struct drm_file *file) | 1049 | struct drm_file *file) |
1050 | { | 1050 | { |
1051 | struct drm_i915_private *dev_priv = dev->dev_private; | ||
1051 | struct drm_i915_gem_pwrite *args = data; | 1052 | struct drm_i915_gem_pwrite *args = data; |
1052 | struct drm_i915_gem_object *obj; | 1053 | struct drm_i915_gem_object *obj; |
1053 | int ret; | 1054 | int ret; |
@@ -1067,9 +1068,11 @@ i915_gem_pwrite_ioctl(struct drm_device *dev, void *data, | |||
1067 | return -EFAULT; | 1068 | return -EFAULT; |
1068 | } | 1069 | } |
1069 | 1070 | ||
1071 | intel_runtime_pm_get(dev_priv); | ||
1072 | |||
1070 | ret = i915_mutex_lock_interruptible(dev); | 1073 | ret = i915_mutex_lock_interruptible(dev); |
1071 | if (ret) | 1074 | if (ret) |
1072 | return ret; | 1075 | goto put_rpm; |
1073 | 1076 | ||
1074 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); | 1077 | obj = to_intel_bo(drm_gem_object_lookup(dev, file, args->handle)); |
1075 | if (&obj->base == NULL) { | 1078 | if (&obj->base == NULL) { |
@@ -1121,6 +1124,9 @@ out: | |||
1121 | drm_gem_object_unreference(&obj->base); | 1124 | drm_gem_object_unreference(&obj->base); |
1122 | unlock: | 1125 | unlock: |
1123 | mutex_unlock(&dev->struct_mutex); | 1126 | mutex_unlock(&dev->struct_mutex); |
1127 | put_rpm: | ||
1128 | intel_runtime_pm_put(dev_priv); | ||
1129 | |||
1124 | return ret; | 1130 | return ret; |
1125 | } | 1131 | } |
1126 | 1132 | ||
diff --git a/drivers/gpu/drm/i915/i915_irq.c b/drivers/gpu/drm/i915/i915_irq.c index 996c2931c499..d0d3dfbe6d2a 100644 --- a/drivers/gpu/drm/i915/i915_irq.c +++ b/drivers/gpu/drm/i915/i915_irq.c | |||
@@ -3725,8 +3725,6 @@ static bool i8xx_handle_vblank(struct drm_device *dev, | |||
3725 | if ((iir & flip_pending) == 0) | 3725 | if ((iir & flip_pending) == 0) |
3726 | goto check_page_flip; | 3726 | goto check_page_flip; |
3727 | 3727 | ||
3728 | intel_prepare_page_flip(dev, plane); | ||
3729 | |||
3730 | /* We detect FlipDone by looking for the change in PendingFlip from '1' | 3728 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
3731 | * to '0' on the following vblank, i.e. IIR has the Pendingflip | 3729 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
3732 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence | 3730 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence |
@@ -3736,6 +3734,7 @@ static bool i8xx_handle_vblank(struct drm_device *dev, | |||
3736 | if (I915_READ16(ISR) & flip_pending) | 3734 | if (I915_READ16(ISR) & flip_pending) |
3737 | goto check_page_flip; | 3735 | goto check_page_flip; |
3738 | 3736 | ||
3737 | intel_prepare_page_flip(dev, plane); | ||
3739 | intel_finish_page_flip(dev, pipe); | 3738 | intel_finish_page_flip(dev, pipe); |
3740 | return true; | 3739 | return true; |
3741 | 3740 | ||
@@ -3907,8 +3906,6 @@ static bool i915_handle_vblank(struct drm_device *dev, | |||
3907 | if ((iir & flip_pending) == 0) | 3906 | if ((iir & flip_pending) == 0) |
3908 | goto check_page_flip; | 3907 | goto check_page_flip; |
3909 | 3908 | ||
3910 | intel_prepare_page_flip(dev, plane); | ||
3911 | |||
3912 | /* We detect FlipDone by looking for the change in PendingFlip from '1' | 3909 | /* We detect FlipDone by looking for the change in PendingFlip from '1' |
3913 | * to '0' on the following vblank, i.e. IIR has the Pendingflip | 3910 | * to '0' on the following vblank, i.e. IIR has the Pendingflip |
3914 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence | 3911 | * asserted following the MI_DISPLAY_FLIP, but ISR is deasserted, hence |
@@ -3918,6 +3915,7 @@ static bool i915_handle_vblank(struct drm_device *dev, | |||
3918 | if (I915_READ(ISR) & flip_pending) | 3915 | if (I915_READ(ISR) & flip_pending) |
3919 | goto check_page_flip; | 3916 | goto check_page_flip; |
3920 | 3917 | ||
3918 | intel_prepare_page_flip(dev, plane); | ||
3921 | intel_finish_page_flip(dev, pipe); | 3919 | intel_finish_page_flip(dev, pipe); |
3922 | return true; | 3920 | return true; |
3923 | 3921 | ||
diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c index fb3e3d429191..e2af1383b179 100644 --- a/drivers/gpu/drm/i915/intel_display.c +++ b/drivers/gpu/drm/i915/intel_display.c | |||
@@ -13057,11 +13057,7 @@ static void i915_disable_vga(struct drm_device *dev) | |||
13057 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); | 13057 | vga_put(dev->pdev, VGA_RSRC_LEGACY_IO); |
13058 | udelay(300); | 13058 | udelay(300); |
13059 | 13059 | ||
13060 | /* | 13060 | I915_WRITE(vga_reg, VGA_DISP_DISABLE); |
13061 | * Fujitsu-Siemens Lifebook S6010 (830) has problems resuming | ||
13062 | * from S3 without preserving (some of?) the other bits. | ||
13063 | */ | ||
13064 | I915_WRITE(vga_reg, dev_priv->bios_vgacntr | VGA_DISP_DISABLE); | ||
13065 | POSTING_READ(vga_reg); | 13061 | POSTING_READ(vga_reg); |
13066 | } | 13062 | } |
13067 | 13063 | ||
@@ -13146,8 +13142,6 @@ void intel_modeset_init(struct drm_device *dev) | |||
13146 | 13142 | ||
13147 | intel_shared_dpll_init(dev); | 13143 | intel_shared_dpll_init(dev); |
13148 | 13144 | ||
13149 | /* save the BIOS value before clobbering it */ | ||
13150 | dev_priv->bios_vgacntr = I915_READ(i915_vgacntrl_reg(dev)); | ||
13151 | /* Just disable it once at startup */ | 13145 | /* Just disable it once at startup */ |
13152 | i915_disable_vga(dev); | 13146 | i915_disable_vga(dev); |
13153 | intel_setup_outputs(dev); | 13147 | intel_setup_outputs(dev); |
diff --git a/drivers/gpu/drm/i915/intel_runtime_pm.c b/drivers/gpu/drm/i915/intel_runtime_pm.c index f5a78d53e297..ac6da7102fbb 100644 --- a/drivers/gpu/drm/i915/intel_runtime_pm.c +++ b/drivers/gpu/drm/i915/intel_runtime_pm.c | |||
@@ -615,29 +615,6 @@ static void chv_pipe_power_well_disable(struct drm_i915_private *dev_priv, | |||
615 | vlv_power_sequencer_reset(dev_priv); | 615 | vlv_power_sequencer_reset(dev_priv); |
616 | } | 616 | } |
617 | 617 | ||
618 | static void check_power_well_state(struct drm_i915_private *dev_priv, | ||
619 | struct i915_power_well *power_well) | ||
620 | { | ||
621 | bool enabled = power_well->ops->is_enabled(dev_priv, power_well); | ||
622 | |||
623 | if (power_well->always_on || !i915.disable_power_well) { | ||
624 | if (!enabled) | ||
625 | goto mismatch; | ||
626 | |||
627 | return; | ||
628 | } | ||
629 | |||
630 | if (enabled != (power_well->count > 0)) | ||
631 | goto mismatch; | ||
632 | |||
633 | return; | ||
634 | |||
635 | mismatch: | ||
636 | WARN(1, "state mismatch for '%s' (always_on %d hw state %d use-count %d disable_power_well %d\n", | ||
637 | power_well->name, power_well->always_on, enabled, | ||
638 | power_well->count, i915.disable_power_well); | ||
639 | } | ||
640 | |||
641 | /** | 618 | /** |
642 | * intel_display_power_get - grab a power domain reference | 619 | * intel_display_power_get - grab a power domain reference |
643 | * @dev_priv: i915 device instance | 620 | * @dev_priv: i915 device instance |
@@ -669,8 +646,6 @@ void intel_display_power_get(struct drm_i915_private *dev_priv, | |||
669 | power_well->ops->enable(dev_priv, power_well); | 646 | power_well->ops->enable(dev_priv, power_well); |
670 | power_well->hw_enabled = true; | 647 | power_well->hw_enabled = true; |
671 | } | 648 | } |
672 | |||
673 | check_power_well_state(dev_priv, power_well); | ||
674 | } | 649 | } |
675 | 650 | ||
676 | power_domains->domain_use_count[domain]++; | 651 | power_domains->domain_use_count[domain]++; |
@@ -709,8 +684,6 @@ void intel_display_power_put(struct drm_i915_private *dev_priv, | |||
709 | power_well->hw_enabled = false; | 684 | power_well->hw_enabled = false; |
710 | power_well->ops->disable(dev_priv, power_well); | 685 | power_well->ops->disable(dev_priv, power_well); |
711 | } | 686 | } |
712 | |||
713 | check_power_well_state(dev_priv, power_well); | ||
714 | } | 687 | } |
715 | 688 | ||
716 | mutex_unlock(&power_domains->lock); | 689 | mutex_unlock(&power_domains->lock); |
diff --git a/drivers/gpu/drm/nouveau/core/core/event.c b/drivers/gpu/drm/nouveau/core/core/event.c index ff2b434b3db4..760947e380c9 100644 --- a/drivers/gpu/drm/nouveau/core/core/event.c +++ b/drivers/gpu/drm/nouveau/core/core/event.c | |||
@@ -26,7 +26,7 @@ | |||
26 | void | 26 | void |
27 | nvkm_event_put(struct nvkm_event *event, u32 types, int index) | 27 | nvkm_event_put(struct nvkm_event *event, u32 types, int index) |
28 | { | 28 | { |
29 | BUG_ON(!spin_is_locked(&event->refs_lock)); | 29 | assert_spin_locked(&event->refs_lock); |
30 | while (types) { | 30 | while (types) { |
31 | int type = __ffs(types); types &= ~(1 << type); | 31 | int type = __ffs(types); types &= ~(1 << type); |
32 | if (--event->refs[index * event->types_nr + type] == 0) { | 32 | if (--event->refs[index * event->types_nr + type] == 0) { |
@@ -39,7 +39,7 @@ nvkm_event_put(struct nvkm_event *event, u32 types, int index) | |||
39 | void | 39 | void |
40 | nvkm_event_get(struct nvkm_event *event, u32 types, int index) | 40 | nvkm_event_get(struct nvkm_event *event, u32 types, int index) |
41 | { | 41 | { |
42 | BUG_ON(!spin_is_locked(&event->refs_lock)); | 42 | assert_spin_locked(&event->refs_lock); |
43 | while (types) { | 43 | while (types) { |
44 | int type = __ffs(types); types &= ~(1 << type); | 44 | int type = __ffs(types); types &= ~(1 << type); |
45 | if (++event->refs[index * event->types_nr + type] == 1) { | 45 | if (++event->refs[index * event->types_nr + type] == 1) { |
diff --git a/drivers/gpu/drm/nouveau/core/core/notify.c b/drivers/gpu/drm/nouveau/core/core/notify.c index d1bcde55e9d7..839a32577680 100644 --- a/drivers/gpu/drm/nouveau/core/core/notify.c +++ b/drivers/gpu/drm/nouveau/core/core/notify.c | |||
@@ -98,7 +98,7 @@ nvkm_notify_send(struct nvkm_notify *notify, void *data, u32 size) | |||
98 | struct nvkm_event *event = notify->event; | 98 | struct nvkm_event *event = notify->event; |
99 | unsigned long flags; | 99 | unsigned long flags; |
100 | 100 | ||
101 | BUG_ON(!spin_is_locked(&event->list_lock)); | 101 | assert_spin_locked(&event->list_lock); |
102 | BUG_ON(size != notify->size); | 102 | BUG_ON(size != notify->size); |
103 | 103 | ||
104 | spin_lock_irqsave(&event->refs_lock, flags); | 104 | spin_lock_irqsave(&event->refs_lock, flags); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c index 674da1f095b2..732922690653 100644 --- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c | |||
@@ -249,6 +249,39 @@ nve0_identify(struct nouveau_device *device) | |||
249 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | 249 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; |
250 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; | 250 | device->oclass[NVDEV_ENGINE_PERFMON] = &nvf0_perfmon_oclass; |
251 | break; | 251 | break; |
252 | case 0x106: | ||
253 | device->cname = "GK208B"; | ||
254 | device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; | ||
255 | device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass; | ||
256 | device->oclass[NVDEV_SUBDEV_I2C ] = nve0_i2c_oclass; | ||
257 | device->oclass[NVDEV_SUBDEV_FUSE ] = &gf100_fuse_oclass; | ||
258 | device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass; | ||
259 | device->oclass[NVDEV_SUBDEV_THERM ] = &nvd0_therm_oclass; | ||
260 | device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass; | ||
261 | device->oclass[NVDEV_SUBDEV_DEVINIT] = nvc0_devinit_oclass; | ||
262 | device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass; | ||
263 | device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass; | ||
264 | device->oclass[NVDEV_SUBDEV_TIMER ] = &nv04_timer_oclass; | ||
265 | device->oclass[NVDEV_SUBDEV_FB ] = nve0_fb_oclass; | ||
266 | device->oclass[NVDEV_SUBDEV_LTC ] = gk104_ltc_oclass; | ||
267 | device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass; | ||
268 | device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass; | ||
269 | device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass; | ||
270 | device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass; | ||
271 | device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass; | ||
272 | device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass; | ||
273 | device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass; | ||
274 | device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass; | ||
275 | device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass; | ||
276 | device->oclass[NVDEV_ENGINE_GR ] = nv108_graph_oclass; | ||
277 | device->oclass[NVDEV_ENGINE_DISP ] = nvf0_disp_oclass; | ||
278 | device->oclass[NVDEV_ENGINE_COPY0 ] = &nve0_copy0_oclass; | ||
279 | device->oclass[NVDEV_ENGINE_COPY1 ] = &nve0_copy1_oclass; | ||
280 | device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; | ||
281 | device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass; | ||
282 | device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass; | ||
283 | device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; | ||
284 | break; | ||
252 | case 0x108: | 285 | case 0x108: |
253 | device->cname = "GK208"; | 286 | device->cname = "GK208"; |
254 | device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; | 287 | device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c index 5e58bba0dd5c..a7a890fad1e5 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c | |||
@@ -44,8 +44,10 @@ static void | |||
44 | pramin_fini(void *data) | 44 | pramin_fini(void *data) |
45 | { | 45 | { |
46 | struct priv *priv = data; | 46 | struct priv *priv = data; |
47 | nv_wr32(priv->bios, 0x001700, priv->bar0); | 47 | if (priv) { |
48 | kfree(priv); | 48 | nv_wr32(priv->bios, 0x001700, priv->bar0); |
49 | kfree(priv); | ||
50 | } | ||
49 | } | 51 | } |
50 | 52 | ||
51 | static void * | 53 | static void * |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c index 00f2ca7e44a5..033a8e999497 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c +++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnvaa.c | |||
@@ -24,34 +24,71 @@ | |||
24 | 24 | ||
25 | #include "nv50.h" | 25 | #include "nv50.h" |
26 | 26 | ||
27 | struct nvaa_ram_priv { | ||
28 | struct nouveau_ram base; | ||
29 | u64 poller_base; | ||
30 | }; | ||
31 | |||
27 | static int | 32 | static int |
28 | nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | 33 | nvaa_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine, |
29 | struct nouveau_oclass *oclass, void *data, u32 datasize, | 34 | struct nouveau_oclass *oclass, void *data, u32 datasize, |
30 | struct nouveau_object **pobject) | 35 | struct nouveau_object **pobject) |
31 | { | 36 | { |
32 | const u32 rsvd_head = ( 256 * 1024) >> 12; /* vga memory */ | 37 | u32 rsvd_head = ( 256 * 1024); /* vga memory */ |
33 | const u32 rsvd_tail = (1024 * 1024) >> 12; /* vbios etc */ | 38 | u32 rsvd_tail = (1024 * 1024); /* vbios etc */ |
34 | struct nouveau_fb *pfb = nouveau_fb(parent); | 39 | struct nouveau_fb *pfb = nouveau_fb(parent); |
35 | struct nouveau_ram *ram; | 40 | struct nvaa_ram_priv *priv; |
36 | int ret; | 41 | int ret; |
37 | 42 | ||
38 | ret = nouveau_ram_create(parent, engine, oclass, &ram); | 43 | ret = nouveau_ram_create(parent, engine, oclass, &priv); |
39 | *pobject = nv_object(ram); | 44 | *pobject = nv_object(priv); |
40 | if (ret) | 45 | if (ret) |
41 | return ret; | 46 | return ret; |
42 | 47 | ||
43 | ram->size = nv_rd32(pfb, 0x10020c); | 48 | priv->base.type = NV_MEM_TYPE_STOLEN; |
44 | ram->size = (ram->size & 0xffffff00) | ((ram->size & 0x000000ff) << 32); | 49 | priv->base.stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; |
50 | priv->base.size = (u64)nv_rd32(pfb, 0x100e14) << 12; | ||
45 | 51 | ||
46 | ret = nouveau_mm_init(&pfb->vram, rsvd_head, (ram->size >> 12) - | 52 | rsvd_tail += 0x1000; |
47 | (rsvd_head + rsvd_tail), 1); | 53 | priv->poller_base = priv->base.size - rsvd_tail; |
54 | |||
55 | ret = nouveau_mm_init(&pfb->vram, rsvd_head >> 12, | ||
56 | (priv->base.size - (rsvd_head + rsvd_tail)) >> 12, | ||
57 | 1); | ||
48 | if (ret) | 58 | if (ret) |
49 | return ret; | 59 | return ret; |
50 | 60 | ||
51 | ram->type = NV_MEM_TYPE_STOLEN; | 61 | priv->base.get = nv50_ram_get; |
52 | ram->stolen = (u64)nv_rd32(pfb, 0x100e10) << 12; | 62 | priv->base.put = nv50_ram_put; |
53 | ram->get = nv50_ram_get; | 63 | return 0; |
54 | ram->put = nv50_ram_put; | 64 | } |
65 | |||
66 | static int | ||
67 | nvaa_ram_init(struct nouveau_object *object) | ||
68 | { | ||
69 | struct nouveau_fb *pfb = nouveau_fb(object); | ||
70 | struct nvaa_ram_priv *priv = (void *)object; | ||
71 | int ret; | ||
72 | u64 dniso, hostnb, flush; | ||
73 | |||
74 | ret = nouveau_ram_init(&priv->base); | ||
75 | if (ret) | ||
76 | return ret; | ||
77 | |||
78 | dniso = ((priv->base.size - (priv->poller_base + 0x00)) >> 5) - 1; | ||
79 | hostnb = ((priv->base.size - (priv->poller_base + 0x20)) >> 5) - 1; | ||
80 | flush = ((priv->base.size - (priv->poller_base + 0x40)) >> 5) - 1; | ||
81 | |||
82 | /* Enable NISO poller for various clients and set their associated | ||
83 | * read address, only for MCP77/78 and MCP79/7A. (fd#25701) | ||
84 | */ | ||
85 | nv_wr32(pfb, 0x100c18, dniso); | ||
86 | nv_mask(pfb, 0x100c14, 0x00000000, 0x00000001); | ||
87 | nv_wr32(pfb, 0x100c1c, hostnb); | ||
88 | nv_mask(pfb, 0x100c14, 0x00000000, 0x00000002); | ||
89 | nv_wr32(pfb, 0x100c24, flush); | ||
90 | nv_mask(pfb, 0x100c14, 0x00000000, 0x00010000); | ||
91 | |||
55 | return 0; | 92 | return 0; |
56 | } | 93 | } |
57 | 94 | ||
@@ -60,7 +97,7 @@ nvaa_ram_oclass = { | |||
60 | .ofuncs = &(struct nouveau_ofuncs) { | 97 | .ofuncs = &(struct nouveau_ofuncs) { |
61 | .ctor = nvaa_ram_ctor, | 98 | .ctor = nvaa_ram_ctor, |
62 | .dtor = _nouveau_ram_dtor, | 99 | .dtor = _nouveau_ram_dtor, |
63 | .init = _nouveau_ram_init, | 100 | .init = nvaa_ram_init, |
64 | .fini = _nouveau_ram_fini, | 101 | .fini = _nouveau_ram_fini, |
65 | }, | 102 | }, |
66 | }; | 103 | }; |
diff --git a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c index a75c35ccf25c..165401c4045c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c +++ b/drivers/gpu/drm/nouveau/core/subdev/mc/nv4c.c | |||
@@ -24,13 +24,6 @@ | |||
24 | 24 | ||
25 | #include "nv04.h" | 25 | #include "nv04.h" |
26 | 26 | ||
27 | static void | ||
28 | nv4c_mc_msi_rearm(struct nouveau_mc *pmc) | ||
29 | { | ||
30 | struct nv04_mc_priv *priv = (void *)pmc; | ||
31 | nv_wr08(priv, 0x088050, 0xff); | ||
32 | } | ||
33 | |||
34 | struct nouveau_oclass * | 27 | struct nouveau_oclass * |
35 | nv4c_mc_oclass = &(struct nouveau_mc_oclass) { | 28 | nv4c_mc_oclass = &(struct nouveau_mc_oclass) { |
36 | .base.handle = NV_SUBDEV(MC, 0x4c), | 29 | .base.handle = NV_SUBDEV(MC, 0x4c), |
@@ -41,5 +34,4 @@ nv4c_mc_oclass = &(struct nouveau_mc_oclass) { | |||
41 | .fini = _nouveau_mc_fini, | 34 | .fini = _nouveau_mc_fini, |
42 | }, | 35 | }, |
43 | .intr = nv04_mc_intr, | 36 | .intr = nv04_mc_intr, |
44 | .msi_rearm = nv4c_mc_msi_rearm, | ||
45 | }.base; | 37 | }.base; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 21ec561edc99..bba2960d3dfb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
@@ -1572,8 +1572,10 @@ nouveau_ttm_tt_unpopulate(struct ttm_tt *ttm) | |||
1572 | * so use the DMA API for them. | 1572 | * so use the DMA API for them. |
1573 | */ | 1573 | */ |
1574 | if (!nv_device_is_cpu_coherent(device) && | 1574 | if (!nv_device_is_cpu_coherent(device) && |
1575 | ttm->caching_state == tt_uncached) | 1575 | ttm->caching_state == tt_uncached) { |
1576 | ttm_dma_unpopulate(ttm_dma, dev->dev); | 1576 | ttm_dma_unpopulate(ttm_dma, dev->dev); |
1577 | return; | ||
1578 | } | ||
1577 | 1579 | ||
1578 | #if __OS_HAS_AGP | 1580 | #if __OS_HAS_AGP |
1579 | if (drm->agp.stat == ENABLED) { | 1581 | if (drm->agp.stat == ENABLED) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 42c34babc2e5..bf0f9e21d714 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -36,7 +36,14 @@ void | |||
36 | nouveau_gem_object_del(struct drm_gem_object *gem) | 36 | nouveau_gem_object_del(struct drm_gem_object *gem) |
37 | { | 37 | { |
38 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); | 38 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
39 | struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | ||
39 | struct ttm_buffer_object *bo = &nvbo->bo; | 40 | struct ttm_buffer_object *bo = &nvbo->bo; |
41 | struct device *dev = drm->dev->dev; | ||
42 | int ret; | ||
43 | |||
44 | ret = pm_runtime_get_sync(dev); | ||
45 | if (WARN_ON(ret < 0 && ret != -EACCES)) | ||
46 | return; | ||
40 | 47 | ||
41 | if (gem->import_attach) | 48 | if (gem->import_attach) |
42 | drm_prime_gem_destroy(gem, nvbo->bo.sg); | 49 | drm_prime_gem_destroy(gem, nvbo->bo.sg); |
@@ -46,6 +53,9 @@ nouveau_gem_object_del(struct drm_gem_object *gem) | |||
46 | /* reset filp so nouveau_bo_del_ttm() can test for it */ | 53 | /* reset filp so nouveau_bo_del_ttm() can test for it */ |
47 | gem->filp = NULL; | 54 | gem->filp = NULL; |
48 | ttm_bo_unref(&bo); | 55 | ttm_bo_unref(&bo); |
56 | |||
57 | pm_runtime_mark_last_busy(dev); | ||
58 | pm_runtime_put_autosuspend(dev); | ||
49 | } | 59 | } |
50 | 60 | ||
51 | int | 61 | int |
@@ -53,7 +63,9 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) | |||
53 | { | 63 | { |
54 | struct nouveau_cli *cli = nouveau_cli(file_priv); | 64 | struct nouveau_cli *cli = nouveau_cli(file_priv); |
55 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); | 65 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
66 | struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | ||
56 | struct nouveau_vma *vma; | 67 | struct nouveau_vma *vma; |
68 | struct device *dev = drm->dev->dev; | ||
57 | int ret; | 69 | int ret; |
58 | 70 | ||
59 | if (!cli->vm) | 71 | if (!cli->vm) |
@@ -71,11 +83,16 @@ nouveau_gem_object_open(struct drm_gem_object *gem, struct drm_file *file_priv) | |||
71 | goto out; | 83 | goto out; |
72 | } | 84 | } |
73 | 85 | ||
86 | ret = pm_runtime_get_sync(dev); | ||
87 | if (ret < 0 && ret != -EACCES) | ||
88 | goto out; | ||
89 | |||
74 | ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); | 90 | ret = nouveau_bo_vma_add(nvbo, cli->vm, vma); |
75 | if (ret) { | 91 | if (ret) |
76 | kfree(vma); | 92 | kfree(vma); |
77 | goto out; | 93 | |
78 | } | 94 | pm_runtime_mark_last_busy(dev); |
95 | pm_runtime_put_autosuspend(dev); | ||
79 | } else { | 96 | } else { |
80 | vma->refcount++; | 97 | vma->refcount++; |
81 | } | 98 | } |
@@ -129,6 +146,8 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) | |||
129 | { | 146 | { |
130 | struct nouveau_cli *cli = nouveau_cli(file_priv); | 147 | struct nouveau_cli *cli = nouveau_cli(file_priv); |
131 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); | 148 | struct nouveau_bo *nvbo = nouveau_gem_object(gem); |
149 | struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev); | ||
150 | struct device *dev = drm->dev->dev; | ||
132 | struct nouveau_vma *vma; | 151 | struct nouveau_vma *vma; |
133 | int ret; | 152 | int ret; |
134 | 153 | ||
@@ -141,8 +160,14 @@ nouveau_gem_object_close(struct drm_gem_object *gem, struct drm_file *file_priv) | |||
141 | 160 | ||
142 | vma = nouveau_bo_vma_find(nvbo, cli->vm); | 161 | vma = nouveau_bo_vma_find(nvbo, cli->vm); |
143 | if (vma) { | 162 | if (vma) { |
144 | if (--vma->refcount == 0) | 163 | if (--vma->refcount == 0) { |
145 | nouveau_gem_object_unmap(nvbo, vma); | 164 | ret = pm_runtime_get_sync(dev); |
165 | if (!WARN_ON(ret < 0 && ret != -EACCES)) { | ||
166 | nouveau_gem_object_unmap(nvbo, vma); | ||
167 | pm_runtime_mark_last_busy(dev); | ||
168 | pm_runtime_put_autosuspend(dev); | ||
169 | } | ||
170 | } | ||
146 | } | 171 | } |
147 | ttm_bo_unreserve(&nvbo->bo); | 172 | ttm_bo_unreserve(&nvbo->bo); |
148 | } | 173 | } |
diff --git a/drivers/gpu/drm/radeon/atombios_crtc.c b/drivers/gpu/drm/radeon/atombios_crtc.c index d59ec491dbb9..ed644a4f6f57 100644 --- a/drivers/gpu/drm/radeon/atombios_crtc.c +++ b/drivers/gpu/drm/radeon/atombios_crtc.c | |||
@@ -1851,10 +1851,9 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1851 | return pll; | 1851 | return pll; |
1852 | } | 1852 | } |
1853 | /* otherwise, pick one of the plls */ | 1853 | /* otherwise, pick one of the plls */ |
1854 | if ((rdev->family == CHIP_KAVERI) || | 1854 | if ((rdev->family == CHIP_KABINI) || |
1855 | (rdev->family == CHIP_KABINI) || | ||
1856 | (rdev->family == CHIP_MULLINS)) { | 1855 | (rdev->family == CHIP_MULLINS)) { |
1857 | /* KB/KV/ML has PPLL1 and PPLL2 */ | 1856 | /* KB/ML has PPLL1 and PPLL2 */ |
1858 | pll_in_use = radeon_get_pll_use_mask(crtc); | 1857 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1859 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | 1858 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
1860 | return ATOM_PPLL2; | 1859 | return ATOM_PPLL2; |
@@ -1863,7 +1862,7 @@ static int radeon_atom_pick_pll(struct drm_crtc *crtc) | |||
1863 | DRM_ERROR("unable to allocate a PPLL\n"); | 1862 | DRM_ERROR("unable to allocate a PPLL\n"); |
1864 | return ATOM_PPLL_INVALID; | 1863 | return ATOM_PPLL_INVALID; |
1865 | } else { | 1864 | } else { |
1866 | /* CI has PPLL0, PPLL1, and PPLL2 */ | 1865 | /* CI/KV has PPLL0, PPLL1, and PPLL2 */ |
1867 | pll_in_use = radeon_get_pll_use_mask(crtc); | 1866 | pll_in_use = radeon_get_pll_use_mask(crtc); |
1868 | if (!(pll_in_use & (1 << ATOM_PPLL2))) | 1867 | if (!(pll_in_use & (1 << ATOM_PPLL2))) |
1869 | return ATOM_PPLL2; | 1868 | return ATOM_PPLL2; |
@@ -2155,6 +2154,7 @@ static void atombios_crtc_disable(struct drm_crtc *crtc) | |||
2155 | case ATOM_PPLL0: | 2154 | case ATOM_PPLL0: |
2156 | /* disable the ppll */ | 2155 | /* disable the ppll */ |
2157 | if ((rdev->family == CHIP_ARUBA) || | 2156 | if ((rdev->family == CHIP_ARUBA) || |
2157 | (rdev->family == CHIP_KAVERI) || | ||
2158 | (rdev->family == CHIP_BONAIRE) || | 2158 | (rdev->family == CHIP_BONAIRE) || |
2159 | (rdev->family == CHIP_HAWAII)) | 2159 | (rdev->family == CHIP_HAWAII)) |
2160 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, | 2160 | atombios_crtc_program_pll(crtc, radeon_crtc->crtc_id, radeon_crtc->pll_id, |
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c index 11ba9d21b89b..db42a670f995 100644 --- a/drivers/gpu/drm/radeon/atombios_dp.c +++ b/drivers/gpu/drm/radeon/atombios_dp.c | |||
@@ -492,6 +492,10 @@ int radeon_dp_mode_valid_helper(struct drm_connector *connector, | |||
492 | struct radeon_connector_atom_dig *dig_connector; | 492 | struct radeon_connector_atom_dig *dig_connector; |
493 | int dp_clock; | 493 | int dp_clock; |
494 | 494 | ||
495 | if ((mode->clock > 340000) && | ||
496 | (!radeon_connector_is_dp12_capable(connector))) | ||
497 | return MODE_CLOCK_HIGH; | ||
498 | |||
495 | if (!radeon_connector->con_priv) | 499 | if (!radeon_connector->con_priv) |
496 | return MODE_CLOCK_HIGH; | 500 | return MODE_CLOCK_HIGH; |
497 | dig_connector = radeon_connector->con_priv; | 501 | dig_connector = radeon_connector->con_priv; |
diff --git a/drivers/gpu/drm/radeon/cikd.h b/drivers/gpu/drm/radeon/cikd.h index ba85986febea..03003f8a6de6 100644 --- a/drivers/gpu/drm/radeon/cikd.h +++ b/drivers/gpu/drm/radeon/cikd.h | |||
@@ -2156,4 +2156,6 @@ | |||
2156 | #define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu | 2156 | #define ATC_VM_APERTURE1_HIGH_ADDR 0x330Cu |
2157 | #define ATC_VM_APERTURE1_LOW_ADDR 0x3304u | 2157 | #define ATC_VM_APERTURE1_LOW_ADDR 0x3304u |
2158 | 2158 | ||
2159 | #define IH_VMID_0_LUT 0x3D40u | ||
2160 | |||
2159 | #endif | 2161 | #endif |
diff --git a/drivers/gpu/drm/radeon/dce3_1_afmt.c b/drivers/gpu/drm/radeon/dce3_1_afmt.c index 2fe8cfc966d9..bafdf92a5732 100644 --- a/drivers/gpu/drm/radeon/dce3_1_afmt.c +++ b/drivers/gpu/drm/radeon/dce3_1_afmt.c | |||
@@ -103,7 +103,7 @@ static void dce3_2_afmt_write_sad_regs(struct drm_encoder *encoder) | |||
103 | } | 103 | } |
104 | 104 | ||
105 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); | 105 | sad_count = drm_edid_to_sad(radeon_connector->edid, &sads); |
106 | if (sad_count < 0) { | 106 | if (sad_count <= 0) { |
107 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); | 107 | DRM_ERROR("Couldn't read SADs: %d\n", sad_count); |
108 | return; | 108 | return; |
109 | } | 109 | } |
diff --git a/drivers/gpu/drm/radeon/kv_dpm.c b/drivers/gpu/drm/radeon/kv_dpm.c index 9b42001295ba..e3e9c10cfba9 100644 --- a/drivers/gpu/drm/radeon/kv_dpm.c +++ b/drivers/gpu/drm/radeon/kv_dpm.c | |||
@@ -2745,13 +2745,11 @@ int kv_dpm_init(struct radeon_device *rdev) | |||
2745 | pi->enable_auto_thermal_throttling = true; | 2745 | pi->enable_auto_thermal_throttling = true; |
2746 | pi->disable_nb_ps3_in_battery = false; | 2746 | pi->disable_nb_ps3_in_battery = false; |
2747 | if (radeon_bapm == -1) { | 2747 | if (radeon_bapm == -1) { |
2748 | /* There are stability issues reported on with | 2748 | /* only enable bapm on KB, ML by default */ |
2749 | * bapm enabled on an asrock system. | 2749 | if (rdev->family == CHIP_KABINI || rdev->family == CHIP_MULLINS) |
2750 | */ | ||
2751 | if (rdev->pdev->subsystem_vendor == 0x1849) | ||
2752 | pi->bapm_enable = false; | ||
2753 | else | ||
2754 | pi->bapm_enable = true; | 2750 | pi->bapm_enable = true; |
2751 | else | ||
2752 | pi->bapm_enable = false; | ||
2755 | } else if (radeon_bapm == 0) { | 2753 | } else if (radeon_bapm == 0) { |
2756 | pi->bapm_enable = false; | 2754 | pi->bapm_enable = false; |
2757 | } else { | 2755 | } else { |
diff --git a/drivers/gpu/drm/radeon/radeon_kfd.c b/drivers/gpu/drm/radeon/radeon_kfd.c index 242fd8b1b221..8bf87f1203cc 100644 --- a/drivers/gpu/drm/radeon/radeon_kfd.c +++ b/drivers/gpu/drm/radeon/radeon_kfd.c | |||
@@ -72,7 +72,7 @@ static int kgd_init_pipeline(struct kgd_dev *kgd, uint32_t pipe_id, | |||
72 | static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | 72 | static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, |
73 | uint32_t queue_id, uint32_t __user *wptr); | 73 | uint32_t queue_id, uint32_t __user *wptr); |
74 | 74 | ||
75 | static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, | 75 | static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, |
76 | uint32_t pipe_id, uint32_t queue_id); | 76 | uint32_t pipe_id, uint32_t queue_id); |
77 | 77 | ||
78 | static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, | 78 | static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, |
@@ -92,7 +92,7 @@ static const struct kfd2kgd_calls kfd2kgd = { | |||
92 | .init_memory = kgd_init_memory, | 92 | .init_memory = kgd_init_memory, |
93 | .init_pipeline = kgd_init_pipeline, | 93 | .init_pipeline = kgd_init_pipeline, |
94 | .hqd_load = kgd_hqd_load, | 94 | .hqd_load = kgd_hqd_load, |
95 | .hqd_is_occupies = kgd_hqd_is_occupies, | 95 | .hqd_is_occupied = kgd_hqd_is_occupied, |
96 | .hqd_destroy = kgd_hqd_destroy, | 96 | .hqd_destroy = kgd_hqd_destroy, |
97 | .get_fw_version = get_fw_version | 97 | .get_fw_version = get_fw_version |
98 | }; | 98 | }; |
@@ -101,6 +101,7 @@ static const struct kgd2kfd_calls *kgd2kfd; | |||
101 | 101 | ||
102 | bool radeon_kfd_init(void) | 102 | bool radeon_kfd_init(void) |
103 | { | 103 | { |
104 | #if defined(CONFIG_HSA_AMD_MODULE) | ||
104 | bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*, | 105 | bool (*kgd2kfd_init_p)(unsigned, const struct kfd2kgd_calls*, |
105 | const struct kgd2kfd_calls**); | 106 | const struct kgd2kfd_calls**); |
106 | 107 | ||
@@ -117,6 +118,17 @@ bool radeon_kfd_init(void) | |||
117 | } | 118 | } |
118 | 119 | ||
119 | return true; | 120 | return true; |
121 | #elif defined(CONFIG_HSA_AMD) | ||
122 | if (!kgd2kfd_init(KFD_INTERFACE_VERSION, &kfd2kgd, &kgd2kfd)) { | ||
123 | kgd2kfd = NULL; | ||
124 | |||
125 | return false; | ||
126 | } | ||
127 | |||
128 | return true; | ||
129 | #else | ||
130 | return false; | ||
131 | #endif | ||
120 | } | 132 | } |
121 | 133 | ||
122 | void radeon_kfd_fini(void) | 134 | void radeon_kfd_fini(void) |
@@ -378,6 +390,10 @@ static int kgd_set_pasid_vmid_mapping(struct kgd_dev *kgd, unsigned int pasid, | |||
378 | cpu_relax(); | 390 | cpu_relax(); |
379 | write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); | 391 | write_register(kgd, ATC_VMID_PASID_MAPPING_UPDATE_STATUS, 1U << vmid); |
380 | 392 | ||
393 | /* Mapping vmid to pasid also for IH block */ | ||
394 | write_register(kgd, IH_VMID_0_LUT + vmid * sizeof(uint32_t), | ||
395 | pasid_mapping); | ||
396 | |||
381 | return 0; | 397 | return 0; |
382 | } | 398 | } |
383 | 399 | ||
@@ -517,7 +533,7 @@ static int kgd_hqd_load(struct kgd_dev *kgd, void *mqd, uint32_t pipe_id, | |||
517 | return 0; | 533 | return 0; |
518 | } | 534 | } |
519 | 535 | ||
520 | static bool kgd_hqd_is_occupies(struct kgd_dev *kgd, uint64_t queue_address, | 536 | static bool kgd_hqd_is_occupied(struct kgd_dev *kgd, uint64_t queue_address, |
521 | uint32_t pipe_id, uint32_t queue_id) | 537 | uint32_t pipe_id, uint32_t queue_id) |
522 | { | 538 | { |
523 | uint32_t act; | 539 | uint32_t act; |
@@ -556,6 +572,7 @@ static int kgd_hqd_destroy(struct kgd_dev *kgd, uint32_t reset_type, | |||
556 | if (timeout == 0) { | 572 | if (timeout == 0) { |
557 | pr_err("kfd: cp queue preemption time out (%dms)\n", | 573 | pr_err("kfd: cp queue preemption time out (%dms)\n", |
558 | temp); | 574 | temp); |
575 | release_queue(kgd); | ||
559 | return -ETIME; | 576 | return -ETIME; |
560 | } | 577 | } |
561 | msleep(20); | 578 | msleep(20); |
diff --git a/drivers/gpu/drm/radeon/radeon_state.c b/drivers/gpu/drm/radeon/radeon_state.c index 535403e0c8a2..15aee723db77 100644 --- a/drivers/gpu/drm/radeon/radeon_state.c +++ b/drivers/gpu/drm/radeon/radeon_state.c | |||
@@ -1703,7 +1703,7 @@ static int radeon_cp_dispatch_texture(struct drm_device * dev, | |||
1703 | u32 format; | 1703 | u32 format; |
1704 | u32 *buffer; | 1704 | u32 *buffer; |
1705 | const u8 __user *data; | 1705 | const u8 __user *data; |
1706 | int size, dwords, tex_width, blit_width, spitch; | 1706 | unsigned int size, dwords, tex_width, blit_width, spitch; |
1707 | u32 height; | 1707 | u32 height; |
1708 | int i; | 1708 | int i; |
1709 | u32 texpitch, microtile; | 1709 | u32 texpitch, microtile; |