| .. | .. |
|---|
| 23 | 23 | * Alon Levy |
|---|
| 24 | 24 | */ |
|---|
| 25 | 25 | |
|---|
| 26 | | - |
|---|
| 27 | 26 | #ifndef QXL_DRV_H |
|---|
| 28 | 27 | #define QXL_DRV_H |
|---|
| 29 | 28 | |
|---|
| .. | .. |
|---|
| 32 | 31 | */ |
|---|
| 33 | 32 | |
|---|
| 34 | 33 | #include <linux/dma-fence.h> |
|---|
| 35 | | -#include <linux/workqueue.h> |
|---|
| 36 | 34 | #include <linux/firmware.h> |
|---|
| 37 | 35 | #include <linux/platform_device.h> |
|---|
| 36 | +#include <linux/workqueue.h> |
|---|
| 38 | 37 | |
|---|
| 39 | 38 | #include <drm/drm_crtc.h> |
|---|
| 40 | 39 | #include <drm/drm_encoder.h> |
|---|
| 40 | +#include <drm/drm_fb_helper.h> |
|---|
| 41 | +#include <drm/drm_gem_ttm_helper.h> |
|---|
| 42 | +#include <drm/drm_ioctl.h> |
|---|
| 41 | 43 | #include <drm/drm_gem.h> |
|---|
| 42 | | -#include <drm/drmP.h> |
|---|
| 44 | +#include <drm/qxl_drm.h> |
|---|
| 43 | 45 | #include <drm/ttm/ttm_bo_api.h> |
|---|
| 44 | 46 | #include <drm/ttm/ttm_bo_driver.h> |
|---|
| 45 | | -/* just for ttm_validate_buffer */ |
|---|
| 46 | 47 | #include <drm/ttm/ttm_execbuf_util.h> |
|---|
| 47 | 48 | #include <drm/ttm/ttm_module.h> |
|---|
| 48 | 49 | #include <drm/ttm/ttm_placement.h> |
|---|
| 49 | | -#include <drm/qxl_drm.h> |
|---|
| 50 | 50 | |
|---|
| 51 | 51 | #include "qxl_dev.h" |
|---|
| 52 | 52 | |
|---|
| .. | .. |
|---|
| 65 | 65 | extern int qxl_num_crtc; |
|---|
| 66 | 66 | extern int qxl_max_ioctls; |
|---|
| 67 | 67 | |
|---|
| 68 | | -#define DRM_FILE_OFFSET 0x100000000ULL |
|---|
| 69 | | -#define DRM_FILE_PAGE_OFFSET (DRM_FILE_OFFSET >> PAGE_SHIFT) |
|---|
| 70 | | - |
|---|
| 71 | 68 | #define QXL_INTERRUPT_MASK (\ |
|---|
| 72 | 69 | QXL_INTERRUPT_DISPLAY |\ |
|---|
| 73 | 70 | QXL_INTERRUPT_CURSOR |\ |
|---|
| .. | .. |
|---|
| 75 | 72 | QXL_INTERRUPT_CLIENT_MONITORS_CONFIG) |
|---|
| 76 | 73 | |
|---|
| 77 | 74 | struct qxl_bo { |
|---|
| 75 | + struct ttm_buffer_object tbo; |
|---|
| 76 | + |
|---|
| 78 | 77 | /* Protected by gem.mutex */ |
|---|
| 79 | 78 | struct list_head list; |
|---|
| 80 | 79 | /* Protected by tbo.reserved */ |
|---|
| 81 | 80 | struct ttm_place placements[3]; |
|---|
| 82 | 81 | struct ttm_placement placement; |
|---|
| 83 | | - struct ttm_buffer_object tbo; |
|---|
| 84 | 82 | struct ttm_bo_kmap_obj kmap; |
|---|
| 85 | | - unsigned pin_count; |
|---|
| 83 | + unsigned int pin_count; |
|---|
| 86 | 84 | void *kptr; |
|---|
| 85 | + unsigned int map_count; |
|---|
| 87 | 86 | int type; |
|---|
| 88 | 87 | |
|---|
| 89 | 88 | /* Constant after initialization */ |
|---|
| 90 | | - struct drm_gem_object gem_base; |
|---|
| 91 | | - bool is_primary; /* is this now a primary surface */ |
|---|
| 92 | | - bool is_dumb; |
|---|
| 89 | + unsigned int is_primary:1; /* is this now a primary surface */ |
|---|
| 90 | + unsigned int is_dumb:1; |
|---|
| 93 | 91 | struct qxl_bo *shadow; |
|---|
| 94 | | - bool hw_surf_alloc; |
|---|
| 92 | + unsigned int hw_surf_alloc:1; |
|---|
| 95 | 93 | struct qxl_surface surf; |
|---|
| 96 | 94 | uint32_t surface_id; |
|---|
| 97 | 95 | struct qxl_release *surf_create; |
|---|
| 98 | 96 | }; |
|---|
| 99 | | -#define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, gem_base) |
|---|
| 97 | +#define gem_to_qxl_bo(gobj) container_of((gobj), struct qxl_bo, tbo.base) |
|---|
| 100 | 98 | #define to_qxl_bo(tobj) container_of((tobj), struct qxl_bo, tbo) |
|---|
| 101 | 99 | |
|---|
| 102 | 100 | struct qxl_gem { |
|---|
| .. | .. |
|---|
| 121 | 119 | struct drm_encoder enc; |
|---|
| 122 | 120 | }; |
|---|
| 123 | 121 | |
|---|
| 124 | | -struct qxl_framebuffer { |
|---|
| 125 | | - struct drm_framebuffer base; |
|---|
| 126 | | - struct drm_gem_object *obj; |
|---|
| 127 | | -}; |
|---|
| 128 | | - |
|---|
| 129 | 122 | #define to_qxl_crtc(x) container_of(x, struct qxl_crtc, base) |
|---|
| 130 | 123 | #define drm_connector_to_qxl_output(x) container_of(x, struct qxl_output, base) |
|---|
| 131 | 124 | #define drm_encoder_to_qxl_output(x) container_of(x, struct qxl_output, enc) |
|---|
| 132 | | -#define to_qxl_framebuffer(x) container_of(x, struct qxl_framebuffer, base) |
|---|
| 133 | 125 | |
|---|
| 134 | 126 | struct qxl_mman { |
|---|
| 135 | | - struct ttm_bo_global_ref bo_global_ref; |
|---|
| 136 | | - struct drm_global_reference mem_global_ref; |
|---|
| 137 | | - bool mem_global_referenced; |
|---|
| 138 | 127 | struct ttm_bo_device bdev; |
|---|
| 139 | 128 | }; |
|---|
| 140 | 129 | |
|---|
| 141 | | -struct qxl_mode_info { |
|---|
| 142 | | - bool mode_config_initialized; |
|---|
| 143 | | - |
|---|
| 144 | | - /* pointer to fbdev info structure */ |
|---|
| 145 | | - struct qxl_fbdev *qfbdev; |
|---|
| 146 | | -}; |
|---|
| 147 | | - |
|---|
| 148 | | - |
|---|
| 149 | 130 | struct qxl_memslot { |
|---|
| 131 | + int index; |
|---|
| 132 | + const char *name; |
|---|
| 150 | 133 | uint8_t generation; |
|---|
| 151 | 134 | uint64_t start_phys_addr; |
|---|
| 152 | | - uint64_t end_phys_addr; |
|---|
| 135 | + uint64_t size; |
|---|
| 153 | 136 | uint64_t high_bits; |
|---|
| 154 | 137 | }; |
|---|
| 155 | 138 | |
|---|
| .. | .. |
|---|
| 203 | 186 | */ |
|---|
| 204 | 187 | struct qxl_debugfs { |
|---|
| 205 | 188 | struct drm_info_list *files; |
|---|
| 206 | | - unsigned num_files; |
|---|
| 189 | + unsigned int num_files; |
|---|
| 207 | 190 | }; |
|---|
| 208 | 191 | |
|---|
| 209 | | -int qxl_debugfs_add_files(struct qxl_device *rdev, |
|---|
| 210 | | - struct drm_info_list *files, |
|---|
| 211 | | - unsigned nfiles); |
|---|
| 212 | 192 | int qxl_debugfs_fence_init(struct qxl_device *rdev); |
|---|
| 213 | | - |
|---|
| 214 | | -struct qxl_device; |
|---|
| 215 | 193 | |
|---|
| 216 | 194 | struct qxl_device { |
|---|
| 217 | 195 | struct drm_device ddev; |
|---|
| .. | .. |
|---|
| 232 | 210 | void *ram; |
|---|
| 233 | 211 | struct qxl_mman mman; |
|---|
| 234 | 212 | struct qxl_gem gem; |
|---|
| 235 | | - struct qxl_mode_info mode_info; |
|---|
| 236 | 213 | |
|---|
| 237 | | - struct fb_info *fbdev_info; |
|---|
| 238 | | - struct qxl_framebuffer *fbdev_qfb; |
|---|
| 239 | 214 | void *ram_physical; |
|---|
| 240 | 215 | |
|---|
| 241 | 216 | struct qxl_ring *release_ring; |
|---|
| .. | .. |
|---|
| 244 | 219 | |
|---|
| 245 | 220 | struct qxl_ram_header *ram_header; |
|---|
| 246 | 221 | |
|---|
| 247 | | - bool primary_created; |
|---|
| 222 | + struct qxl_bo *primary_bo; |
|---|
| 223 | + struct qxl_bo *dumb_shadow_bo; |
|---|
| 224 | + struct qxl_head *dumb_heads; |
|---|
| 248 | 225 | |
|---|
| 249 | | - struct qxl_memslot *mem_slots; |
|---|
| 250 | | - uint8_t n_mem_slots; |
|---|
| 251 | | - |
|---|
| 252 | | - uint8_t main_mem_slot; |
|---|
| 253 | | - uint8_t surfaces_mem_slot; |
|---|
| 254 | | - uint8_t slot_id_bits; |
|---|
| 255 | | - uint8_t slot_gen_bits; |
|---|
| 256 | | - uint64_t va_slot_mask; |
|---|
| 226 | + struct qxl_memslot main_slot; |
|---|
| 227 | + struct qxl_memslot surfaces_slot; |
|---|
| 257 | 228 | |
|---|
| 258 | 229 | spinlock_t release_lock; |
|---|
| 259 | 230 | struct idr release_idr; |
|---|
| .. | .. |
|---|
| 267 | 238 | atomic_t irq_received_display; |
|---|
| 268 | 239 | atomic_t irq_received_cursor; |
|---|
| 269 | 240 | atomic_t irq_received_io_cmd; |
|---|
| 270 | | - unsigned irq_received_error; |
|---|
| 241 | + unsigned int irq_received_error; |
|---|
| 271 | 242 | wait_queue_head_t display_event; |
|---|
| 272 | 243 | wait_queue_head_t cursor_event; |
|---|
| 273 | 244 | wait_queue_head_t io_cmd_event; |
|---|
| .. | .. |
|---|
| 275 | 246 | |
|---|
| 276 | 247 | /* debugfs */ |
|---|
| 277 | 248 | struct qxl_debugfs debugfs[QXL_DEBUGFS_MAX_COMPONENTS]; |
|---|
| 278 | | - unsigned debugfs_count; |
|---|
| 249 | + unsigned int debugfs_count; |
|---|
| 279 | 250 | |
|---|
| 280 | 251 | struct mutex update_area_mutex; |
|---|
| 281 | 252 | |
|---|
| .. | .. |
|---|
| 299 | 270 | int monitors_config_height; |
|---|
| 300 | 271 | }; |
|---|
| 301 | 272 | |
|---|
| 273 | +#define to_qxl(dev) container_of(dev, struct qxl_device, ddev) |
|---|
| 274 | + |
|---|
| 302 | 275 | extern const struct drm_ioctl_desc qxl_ioctls[]; |
|---|
| 303 | 276 | extern int qxl_max_ioctl; |
|---|
| 304 | 277 | |
|---|
| 305 | | -int qxl_device_init(struct qxl_device *qdev, struct drm_driver *drv, |
|---|
| 306 | | - struct pci_dev *pdev); |
|---|
| 278 | +int qxl_device_init(struct qxl_device *qdev, struct pci_dev *pdev); |
|---|
| 307 | 279 | void qxl_device_fini(struct qxl_device *qdev); |
|---|
| 308 | 280 | |
|---|
| 309 | 281 | int qxl_modeset_init(struct qxl_device *qdev); |
|---|
| .. | .. |
|---|
| 326 | 298 | void qxl_ring_init_hdr(struct qxl_ring *ring); |
|---|
| 327 | 299 | int qxl_check_idle(struct qxl_ring *ring); |
|---|
| 328 | 300 | |
|---|
| 329 | | -static inline void * |
|---|
| 330 | | -qxl_fb_virtual_address(struct qxl_device *qdev, unsigned long physical) |
|---|
| 331 | | -{ |
|---|
| 332 | | - DRM_DEBUG_DRIVER("not implemented (%lu)\n", physical); |
|---|
| 333 | | - return 0; |
|---|
| 334 | | -} |
|---|
| 335 | | - |
|---|
| 336 | 301 | static inline uint64_t |
|---|
| 337 | 302 | qxl_bo_physical_address(struct qxl_device *qdev, struct qxl_bo *bo, |
|---|
| 338 | 303 | unsigned long offset) |
|---|
| 339 | 304 | { |
|---|
| 340 | | - int slot_id = bo->type == QXL_GEM_DOMAIN_VRAM ? qdev->main_mem_slot : qdev->surfaces_mem_slot; |
|---|
| 341 | | - struct qxl_memslot *slot = &(qdev->mem_slots[slot_id]); |
|---|
| 305 | + struct qxl_memslot *slot = |
|---|
| 306 | + (bo->tbo.mem.mem_type == TTM_PL_VRAM) |
|---|
| 307 | + ? &qdev->main_slot : &qdev->surfaces_slot; |
|---|
| 342 | 308 | |
|---|
| 343 | | - /* TODO - need to hold one of the locks to read tbo.offset */ |
|---|
| 344 | | - return slot->high_bits | (bo->tbo.offset + offset); |
|---|
| 309 | + /* TODO - need to hold one of the locks to read bo->tbo.mem.start */ |
|---|
| 310 | + |
|---|
| 311 | + return slot->high_bits | ((bo->tbo.mem.start << PAGE_SHIFT) + offset); |
|---|
| 345 | 312 | } |
|---|
| 346 | 313 | |
|---|
| 347 | | -/* qxl_fb.c */ |
|---|
| 348 | | -#define QXLFB_CONN_LIMIT 1 |
|---|
| 349 | | - |
|---|
| 350 | | -int qxl_fbdev_init(struct qxl_device *qdev); |
|---|
| 351 | | -void qxl_fbdev_fini(struct qxl_device *qdev); |
|---|
| 352 | | -int qxl_get_handle_for_primary_fb(struct qxl_device *qdev, |
|---|
| 353 | | - struct drm_file *file_priv, |
|---|
| 354 | | - uint32_t *handle); |
|---|
| 355 | | -void qxl_fbdev_set_suspend(struct qxl_device *qdev, int state); |
|---|
| 356 | | - |
|---|
| 357 | 314 | /* qxl_display.c */ |
|---|
| 358 | | -void qxl_user_framebuffer_destroy(struct drm_framebuffer *fb); |
|---|
| 359 | | -int |
|---|
| 360 | | -qxl_framebuffer_init(struct drm_device *dev, |
|---|
| 361 | | - struct qxl_framebuffer *rfb, |
|---|
| 362 | | - const struct drm_mode_fb_cmd2 *mode_cmd, |
|---|
| 363 | | - struct drm_gem_object *obj, |
|---|
| 364 | | - const struct drm_framebuffer_funcs *funcs); |
|---|
| 365 | 315 | void qxl_display_read_client_monitors_config(struct qxl_device *qdev); |
|---|
| 366 | 316 | int qxl_create_monitors_object(struct qxl_device *qdev); |
|---|
| 367 | 317 | int qxl_destroy_monitors_object(struct qxl_device *qdev); |
|---|
| .. | .. |
|---|
| 396 | 346 | struct drm_device *dev, |
|---|
| 397 | 347 | uint32_t handle, uint64_t *offset_p); |
|---|
| 398 | 348 | |
|---|
| 399 | | - |
|---|
| 400 | 349 | /* qxl ttm */ |
|---|
| 401 | 350 | int qxl_ttm_init(struct qxl_device *qdev); |
|---|
| 402 | 351 | void qxl_ttm_fini(struct qxl_device *qdev); |
|---|
| 403 | | -int qxl_mmap(struct file *filp, struct vm_area_struct *vma); |
|---|
| 352 | +int qxl_ttm_io_mem_reserve(struct ttm_bo_device *bdev, |
|---|
| 353 | + struct ttm_resource *mem); |
|---|
| 404 | 354 | |
|---|
| 405 | 355 | /* qxl image */ |
|---|
| 406 | 356 | |
|---|
| .. | .. |
|---|
| 422 | 372 | /* qxl io operations (qxl_cmd.c) */ |
|---|
| 423 | 373 | |
|---|
| 424 | 374 | void qxl_io_create_primary(struct qxl_device *qdev, |
|---|
| 425 | | - unsigned offset, |
|---|
| 426 | 375 | struct qxl_bo *bo); |
|---|
| 427 | 376 | void qxl_io_destroy_primary(struct qxl_device *qdev); |
|---|
| 428 | 377 | void qxl_io_memslot_add(struct qxl_device *qdev, uint8_t id); |
|---|
| .. | .. |
|---|
| 467 | 416 | struct qxl_bo **_bo); |
|---|
| 468 | 417 | /* qxl drawing commands */ |
|---|
| 469 | 418 | |
|---|
| 470 | | -void qxl_draw_opaque_fb(const struct qxl_fb_image *qxl_fb_image, |
|---|
| 471 | | - int stride /* filled in if 0 */); |
|---|
| 472 | | - |
|---|
| 473 | 419 | void qxl_draw_dirty_fb(struct qxl_device *qdev, |
|---|
| 474 | | - struct qxl_framebuffer *qxl_fb, |
|---|
| 420 | + struct drm_framebuffer *fb, |
|---|
| 475 | 421 | struct qxl_bo *bo, |
|---|
| 476 | | - unsigned flags, unsigned color, |
|---|
| 422 | + unsigned int flags, unsigned int color, |
|---|
| 477 | 423 | struct drm_clip_rect *clips, |
|---|
| 478 | | - unsigned num_clips, int inc); |
|---|
| 479 | | - |
|---|
| 480 | | -void qxl_draw_fill(struct qxl_draw_fill *qxl_draw_fill_rec); |
|---|
| 481 | | - |
|---|
| 482 | | -void qxl_draw_copyarea(struct qxl_device *qdev, |
|---|
| 483 | | - u32 width, u32 height, |
|---|
| 484 | | - u32 sx, u32 sy, |
|---|
| 485 | | - u32 dx, u32 dy); |
|---|
| 424 | + unsigned int num_clips, int inc, |
|---|
| 425 | + uint32_t dumb_shadow_offset); |
|---|
| 486 | 426 | |
|---|
| 487 | 427 | void qxl_release_free(struct qxl_device *qdev, |
|---|
| 488 | 428 | struct qxl_release *release); |
|---|
| .. | .. |
|---|
| 496 | 436 | |
|---|
| 497 | 437 | /* debugfs */ |
|---|
| 498 | 438 | |
|---|
| 499 | | -int qxl_debugfs_init(struct drm_minor *minor); |
|---|
| 500 | | -int qxl_ttm_debugfs_init(struct qxl_device *qdev); |
|---|
| 439 | +void qxl_debugfs_init(struct drm_minor *minor); |
|---|
| 440 | +void qxl_ttm_debugfs_init(struct qxl_device *qdev); |
|---|
| 501 | 441 | |
|---|
| 502 | 442 | /* qxl_prime.c */ |
|---|
| 503 | 443 | int qxl_gem_prime_pin(struct drm_gem_object *obj); |
|---|
| .. | .. |
|---|
| 515 | 455 | int qxl_irq_init(struct qxl_device *qdev); |
|---|
| 516 | 456 | irqreturn_t qxl_irq_handler(int irq, void *arg); |
|---|
| 517 | 457 | |
|---|
| 518 | | -/* qxl_fb.c */ |
|---|
| 519 | | -bool qxl_fbdev_qobj_is_fb(struct qxl_device *qdev, struct qxl_bo *qobj); |
|---|
| 520 | | - |
|---|
| 521 | | -int qxl_debugfs_add_files(struct qxl_device *qdev, |
|---|
| 522 | | - struct drm_info_list *files, |
|---|
| 523 | | - unsigned nfiles); |
|---|
| 458 | +void qxl_debugfs_add_files(struct qxl_device *qdev, |
|---|
| 459 | + struct drm_info_list *files, |
|---|
| 460 | + unsigned int nfiles); |
|---|
| 524 | 461 | |
|---|
| 525 | 462 | int qxl_surface_id_alloc(struct qxl_device *qdev, |
|---|
| 526 | 463 | struct qxl_bo *surf); |
|---|
| 527 | 464 | void qxl_surface_id_dealloc(struct qxl_device *qdev, |
|---|
| 528 | 465 | uint32_t surface_id); |
|---|
| 529 | 466 | int qxl_hw_surface_alloc(struct qxl_device *qdev, |
|---|
| 530 | | - struct qxl_bo *surf, |
|---|
| 531 | | - struct ttm_mem_reg *mem); |
|---|
| 467 | + struct qxl_bo *surf); |
|---|
| 532 | 468 | int qxl_hw_surface_dealloc(struct qxl_device *qdev, |
|---|
| 533 | 469 | struct qxl_bo *surf); |
|---|
| 534 | 470 | |
|---|