1c8b75bcaSEric Anholt /* 2c8b75bcaSEric Anholt * Copyright (C) 2015 Broadcom 3c8b75bcaSEric Anholt * 4c8b75bcaSEric Anholt * This program is free software; you can redistribute it and/or modify 5c8b75bcaSEric Anholt * it under the terms of the GNU General Public License version 2 as 6c8b75bcaSEric Anholt * published by the Free Software Foundation. 7c8b75bcaSEric Anholt */ 8c8b75bcaSEric Anholt 9c8b75bcaSEric Anholt #include "drmP.h" 10c8b75bcaSEric Anholt #include "drm_gem_cma_helper.h" 11c8b75bcaSEric Anholt 12*9338203cSLaurent Pinchart #include <drm/drm_encoder.h> 13*9338203cSLaurent Pinchart 14c8b75bcaSEric Anholt struct vc4_dev { 15c8b75bcaSEric Anholt struct drm_device *dev; 16c8b75bcaSEric Anholt 17c8b75bcaSEric Anholt struct vc4_hdmi *hdmi; 18c8b75bcaSEric Anholt struct vc4_hvs *hvs; 19c8b75bcaSEric Anholt struct vc4_crtc *crtc[3]; 20d3f5168aSEric Anholt struct vc4_v3d *v3d; 2108302c35SEric Anholt struct vc4_dpi *dpi; 22e4b81f8cSBoris Brezillon struct vc4_vec *vec; 2348666d56SDerek Foreman 2448666d56SDerek Foreman struct drm_fbdev_cma *fbdev; 25c826a6e1SEric Anholt 2621461365SEric Anholt struct vc4_hang_state *hang_state; 2721461365SEric Anholt 28c826a6e1SEric Anholt /* The kernel-space BO cache. Tracks buffers that have been 29c826a6e1SEric Anholt * unreferenced by all other users (refcounts of 0!) but not 30c826a6e1SEric Anholt * yet freed, so we can do cheap allocations. 31c826a6e1SEric Anholt */ 32c826a6e1SEric Anholt struct vc4_bo_cache { 33c826a6e1SEric Anholt /* Array of list heads for entries in the BO cache, 34c826a6e1SEric Anholt * based on number of pages, so we can do O(1) lookups 35c826a6e1SEric Anholt * in the cache when allocating. 36c826a6e1SEric Anholt */ 37c826a6e1SEric Anholt struct list_head *size_list; 38c826a6e1SEric Anholt uint32_t size_list_size; 39c826a6e1SEric Anholt 40c826a6e1SEric Anholt /* List of all BOs in the cache, ordered by age, so we 41c826a6e1SEric Anholt * can do O(1) lookups when trying to free old 42c826a6e1SEric Anholt * buffers. 43c826a6e1SEric Anholt */ 44c826a6e1SEric Anholt struct list_head time_list; 45c826a6e1SEric Anholt struct work_struct time_work; 46c826a6e1SEric Anholt struct timer_list time_timer; 47c826a6e1SEric Anholt } bo_cache; 48c826a6e1SEric Anholt 49c826a6e1SEric Anholt struct vc4_bo_stats { 50c826a6e1SEric Anholt u32 num_allocated; 51c826a6e1SEric Anholt u32 size_allocated; 52c826a6e1SEric Anholt u32 num_cached; 53c826a6e1SEric Anholt u32 size_cached; 54c826a6e1SEric Anholt } bo_stats; 55c826a6e1SEric Anholt 56c826a6e1SEric Anholt /* Protects bo_cache and the BO stats. */ 57c826a6e1SEric Anholt struct mutex bo_lock; 58d5b1a78aSEric Anholt 59ca26d28bSVarad Gautam /* Sequence number for the last job queued in bin_job_list. 60d5b1a78aSEric Anholt * Starts at 0 (no jobs emitted). 61d5b1a78aSEric Anholt */ 62d5b1a78aSEric Anholt uint64_t emit_seqno; 63d5b1a78aSEric Anholt 64d5b1a78aSEric Anholt /* Sequence number for the last completed job on the GPU. 65d5b1a78aSEric Anholt * Starts at 0 (no jobs completed). 66d5b1a78aSEric Anholt */ 67d5b1a78aSEric Anholt uint64_t finished_seqno; 68d5b1a78aSEric Anholt 69ca26d28bSVarad Gautam /* List of all struct vc4_exec_info for jobs to be executed in 70ca26d28bSVarad Gautam * the binner. The first job in the list is the one currently 71ca26d28bSVarad Gautam * programmed into ct0ca for execution. 72d5b1a78aSEric Anholt */ 73ca26d28bSVarad Gautam struct list_head bin_job_list; 74ca26d28bSVarad Gautam 75ca26d28bSVarad Gautam /* List of all struct vc4_exec_info for jobs that have 76ca26d28bSVarad Gautam * completed binning and are ready for rendering. The first 77ca26d28bSVarad Gautam * job in the list is the one currently programmed into ct1ca 78ca26d28bSVarad Gautam * for execution. 79ca26d28bSVarad Gautam */ 80ca26d28bSVarad Gautam struct list_head render_job_list; 81ca26d28bSVarad Gautam 82d5b1a78aSEric Anholt /* List of the finished vc4_exec_infos waiting to be freed by 83d5b1a78aSEric Anholt * job_done_work. 84d5b1a78aSEric Anholt */ 85d5b1a78aSEric Anholt struct list_head job_done_list; 86d5b1a78aSEric Anholt /* Spinlock used to synchronize the job_list and seqno 87d5b1a78aSEric Anholt * accesses between the IRQ handler and GEM ioctls. 88d5b1a78aSEric Anholt */ 89d5b1a78aSEric Anholt spinlock_t job_lock; 90d5b1a78aSEric Anholt wait_queue_head_t job_wait_queue; 91d5b1a78aSEric Anholt struct work_struct job_done_work; 92d5b1a78aSEric Anholt 93b501baccSEric Anholt /* List of struct vc4_seqno_cb for callbacks to be made from a 94b501baccSEric Anholt * workqueue when the given seqno is passed. 95b501baccSEric Anholt */ 96b501baccSEric Anholt struct list_head seqno_cb_list; 97b501baccSEric Anholt 98d5b1a78aSEric Anholt /* The binner overflow memory that's currently set up in 99d5b1a78aSEric Anholt * BPOA/BPOS registers. When overflow occurs and a new one is 100d5b1a78aSEric Anholt * allocated, the previous one will be moved to 101d5b1a78aSEric Anholt * vc4->current_exec's free list. 102d5b1a78aSEric Anholt */ 103d5b1a78aSEric Anholt struct vc4_bo *overflow_mem; 104d5b1a78aSEric Anholt struct work_struct overflow_mem_work; 105d5b1a78aSEric Anholt 10636cb6253SEric Anholt int power_refcount; 10736cb6253SEric Anholt 10836cb6253SEric Anholt /* Mutex controlling the power refcount. */ 10936cb6253SEric Anholt struct mutex power_lock; 11036cb6253SEric Anholt 111d5b1a78aSEric Anholt struct { 112d5b1a78aSEric Anholt struct timer_list timer; 113d5b1a78aSEric Anholt struct work_struct reset_work; 114d5b1a78aSEric Anholt } hangcheck; 115d5b1a78aSEric Anholt 116d5b1a78aSEric Anholt struct semaphore async_modeset; 117c8b75bcaSEric Anholt }; 118c8b75bcaSEric Anholt 119c8b75bcaSEric Anholt static inline struct vc4_dev * 120c8b75bcaSEric Anholt to_vc4_dev(struct drm_device *dev) 121c8b75bcaSEric Anholt { 122c8b75bcaSEric Anholt return (struct vc4_dev *)dev->dev_private; 123c8b75bcaSEric Anholt } 124c8b75bcaSEric Anholt 125c8b75bcaSEric Anholt struct vc4_bo { 126c8b75bcaSEric Anholt struct drm_gem_cma_object base; 127c826a6e1SEric Anholt 1287edabee0SEric Anholt /* seqno of the last job to render using this BO. */ 129d5b1a78aSEric Anholt uint64_t seqno; 130d5b1a78aSEric Anholt 1317edabee0SEric Anholt /* seqno of the last job to use the RCL to write to this BO. 1327edabee0SEric Anholt * 1337edabee0SEric Anholt * Note that this doesn't include binner overflow memory 1347edabee0SEric Anholt * writes. 1357edabee0SEric Anholt */ 1367edabee0SEric Anholt uint64_t write_seqno; 1377edabee0SEric Anholt 138c826a6e1SEric Anholt /* List entry for the BO's position in either 139c826a6e1SEric Anholt * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list 140c826a6e1SEric Anholt */ 141c826a6e1SEric Anholt struct list_head unref_head; 142c826a6e1SEric Anholt 143c826a6e1SEric Anholt /* Time in jiffies when the BO was put in vc4->bo_cache. */ 144c826a6e1SEric Anholt unsigned long free_time; 145c826a6e1SEric Anholt 146c826a6e1SEric Anholt /* List entry for the BO's position in vc4_dev->bo_cache.size_list */ 147c826a6e1SEric Anholt struct list_head size_head; 148463873d5SEric Anholt 149463873d5SEric Anholt /* Struct for shader validation state, if created by 150463873d5SEric Anholt * DRM_IOCTL_VC4_CREATE_SHADER_BO. 151463873d5SEric Anholt */ 152463873d5SEric Anholt struct vc4_validated_shader_info *validated_shader; 153c8b75bcaSEric Anholt }; 154c8b75bcaSEric Anholt 155c8b75bcaSEric Anholt static inline struct vc4_bo * 156c8b75bcaSEric Anholt to_vc4_bo(struct drm_gem_object *bo) 157c8b75bcaSEric Anholt { 158c8b75bcaSEric Anholt return (struct vc4_bo *)bo; 159c8b75bcaSEric Anholt } 160c8b75bcaSEric Anholt 161b501baccSEric Anholt struct vc4_seqno_cb { 162b501baccSEric Anholt struct work_struct work; 163b501baccSEric Anholt uint64_t seqno; 164b501baccSEric Anholt void (*func)(struct vc4_seqno_cb *cb); 165b501baccSEric Anholt }; 166b501baccSEric Anholt 167d3f5168aSEric Anholt struct vc4_v3d { 168001bdb55SEric Anholt struct vc4_dev *vc4; 169d3f5168aSEric Anholt struct platform_device *pdev; 170d3f5168aSEric Anholt void __iomem *regs; 171d3f5168aSEric Anholt }; 172d3f5168aSEric Anholt 173c8b75bcaSEric Anholt struct vc4_hvs { 174c8b75bcaSEric Anholt struct platform_device *pdev; 175c8b75bcaSEric Anholt void __iomem *regs; 176d8dbf44fSEric Anholt u32 __iomem *dlist; 177d8dbf44fSEric Anholt 178d8dbf44fSEric Anholt /* Memory manager for CRTCs to allocate space in the display 179d8dbf44fSEric Anholt * list. Units are dwords. 180d8dbf44fSEric Anholt */ 181d8dbf44fSEric Anholt struct drm_mm dlist_mm; 18221af94cfSEric Anholt /* Memory manager for the LBM memory used by HVS scaling. */ 18321af94cfSEric Anholt struct drm_mm lbm_mm; 184d8dbf44fSEric Anholt spinlock_t mm_lock; 18521af94cfSEric Anholt 18621af94cfSEric Anholt struct drm_mm_node mitchell_netravali_filter; 187c8b75bcaSEric Anholt }; 188c8b75bcaSEric Anholt 189c8b75bcaSEric Anholt struct vc4_plane { 190c8b75bcaSEric Anholt struct drm_plane base; 191c8b75bcaSEric Anholt }; 192c8b75bcaSEric Anholt 193c8b75bcaSEric Anholt static inline struct vc4_plane * 194c8b75bcaSEric Anholt to_vc4_plane(struct drm_plane *plane) 195c8b75bcaSEric Anholt { 196c8b75bcaSEric Anholt return (struct vc4_plane *)plane; 197c8b75bcaSEric Anholt } 198c8b75bcaSEric Anholt 199c8b75bcaSEric Anholt enum vc4_encoder_type { 200ab8df60eSBoris Brezillon VC4_ENCODER_TYPE_NONE, 201c8b75bcaSEric Anholt VC4_ENCODER_TYPE_HDMI, 202c8b75bcaSEric Anholt VC4_ENCODER_TYPE_VEC, 203c8b75bcaSEric Anholt VC4_ENCODER_TYPE_DSI0, 204c8b75bcaSEric Anholt VC4_ENCODER_TYPE_DSI1, 205c8b75bcaSEric Anholt VC4_ENCODER_TYPE_SMI, 206c8b75bcaSEric Anholt VC4_ENCODER_TYPE_DPI, 207c8b75bcaSEric Anholt }; 208c8b75bcaSEric Anholt 209c8b75bcaSEric Anholt struct vc4_encoder { 210c8b75bcaSEric Anholt struct drm_encoder base; 211c8b75bcaSEric Anholt enum vc4_encoder_type type; 212c8b75bcaSEric Anholt u32 clock_select; 213c8b75bcaSEric Anholt }; 214c8b75bcaSEric Anholt 215c8b75bcaSEric Anholt static inline struct vc4_encoder * 216c8b75bcaSEric Anholt to_vc4_encoder(struct drm_encoder *encoder) 217c8b75bcaSEric Anholt { 218c8b75bcaSEric Anholt return container_of(encoder, struct vc4_encoder, base); 219c8b75bcaSEric Anholt } 220c8b75bcaSEric Anholt 221d3f5168aSEric Anholt #define V3D_READ(offset) readl(vc4->v3d->regs + offset) 222d3f5168aSEric Anholt #define V3D_WRITE(offset, val) writel(val, vc4->v3d->regs + offset) 223c8b75bcaSEric Anholt #define HVS_READ(offset) readl(vc4->hvs->regs + offset) 224c8b75bcaSEric Anholt #define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset) 225c8b75bcaSEric Anholt 226d5b1a78aSEric Anholt struct vc4_exec_info { 227d5b1a78aSEric Anholt /* Sequence number for this bin/render job. */ 228d5b1a78aSEric Anholt uint64_t seqno; 229d5b1a78aSEric Anholt 2307edabee0SEric Anholt /* Latest write_seqno of any BO that binning depends on. */ 2317edabee0SEric Anholt uint64_t bin_dep_seqno; 2327edabee0SEric Anholt 233c4ce60dcSEric Anholt /* Last current addresses the hardware was processing when the 234c4ce60dcSEric Anholt * hangcheck timer checked on us. 235c4ce60dcSEric Anholt */ 236c4ce60dcSEric Anholt uint32_t last_ct0ca, last_ct1ca; 237c4ce60dcSEric Anholt 238d5b1a78aSEric Anholt /* Kernel-space copy of the ioctl arguments */ 239d5b1a78aSEric Anholt struct drm_vc4_submit_cl *args; 240d5b1a78aSEric Anholt 241d5b1a78aSEric Anholt /* This is the array of BOs that were looked up at the start of exec. 242d5b1a78aSEric Anholt * Command validation will use indices into this array. 243d5b1a78aSEric Anholt */ 244d5b1a78aSEric Anholt struct drm_gem_cma_object **bo; 245d5b1a78aSEric Anholt uint32_t bo_count; 246d5b1a78aSEric Anholt 2477edabee0SEric Anholt /* List of BOs that are being written by the RCL. Other than 2487edabee0SEric Anholt * the binner temporary storage, this is all the BOs written 2497edabee0SEric Anholt * by the job. 2507edabee0SEric Anholt */ 2517edabee0SEric Anholt struct drm_gem_cma_object *rcl_write_bo[4]; 2527edabee0SEric Anholt uint32_t rcl_write_bo_count; 2537edabee0SEric Anholt 254d5b1a78aSEric Anholt /* Pointers for our position in vc4->job_list */ 255d5b1a78aSEric Anholt struct list_head head; 256d5b1a78aSEric Anholt 257d5b1a78aSEric Anholt /* List of other BOs used in the job that need to be released 258d5b1a78aSEric Anholt * once the job is complete. 259d5b1a78aSEric Anholt */ 260d5b1a78aSEric Anholt struct list_head unref_list; 261d5b1a78aSEric Anholt 262d5b1a78aSEric Anholt /* Current unvalidated indices into @bo loaded by the non-hardware 263d5b1a78aSEric Anholt * VC4_PACKET_GEM_HANDLES. 264d5b1a78aSEric Anholt */ 265d5b1a78aSEric Anholt uint32_t bo_index[2]; 266d5b1a78aSEric Anholt 267d5b1a78aSEric Anholt /* This is the BO where we store the validated command lists, shader 268d5b1a78aSEric Anholt * records, and uniforms. 269d5b1a78aSEric Anholt */ 270d5b1a78aSEric Anholt struct drm_gem_cma_object *exec_bo; 271d5b1a78aSEric Anholt 272d5b1a78aSEric Anholt /** 273d5b1a78aSEric Anholt * This tracks the per-shader-record state (packet 64) that 274d5b1a78aSEric Anholt * determines the length of the shader record and the offset 275d5b1a78aSEric Anholt * it's expected to be found at. It gets read in from the 276d5b1a78aSEric Anholt * command lists. 277d5b1a78aSEric Anholt */ 278d5b1a78aSEric Anholt struct vc4_shader_state { 279d5b1a78aSEric Anholt uint32_t addr; 280d5b1a78aSEric Anholt /* Maximum vertex index referenced by any primitive using this 281d5b1a78aSEric Anholt * shader state. 282d5b1a78aSEric Anholt */ 283d5b1a78aSEric Anholt uint32_t max_index; 284d5b1a78aSEric Anholt } *shader_state; 285d5b1a78aSEric Anholt 286d5b1a78aSEric Anholt /** How many shader states the user declared they were using. */ 287d5b1a78aSEric Anholt uint32_t shader_state_size; 288d5b1a78aSEric Anholt /** How many shader state records the validator has seen. */ 289d5b1a78aSEric Anholt uint32_t shader_state_count; 290d5b1a78aSEric Anholt 291d5b1a78aSEric Anholt bool found_tile_binning_mode_config_packet; 292d5b1a78aSEric Anholt bool found_start_tile_binning_packet; 293d5b1a78aSEric Anholt bool found_increment_semaphore_packet; 294d5b1a78aSEric Anholt bool found_flush; 295d5b1a78aSEric Anholt uint8_t bin_tiles_x, bin_tiles_y; 296d5b1a78aSEric Anholt struct drm_gem_cma_object *tile_bo; 297d5b1a78aSEric Anholt uint32_t tile_alloc_offset; 298d5b1a78aSEric Anholt 299d5b1a78aSEric Anholt /** 300d5b1a78aSEric Anholt * Computed addresses pointing into exec_bo where we start the 301d5b1a78aSEric Anholt * bin thread (ct0) and render thread (ct1). 302d5b1a78aSEric Anholt */ 303d5b1a78aSEric Anholt uint32_t ct0ca, ct0ea; 304d5b1a78aSEric Anholt uint32_t ct1ca, ct1ea; 305d5b1a78aSEric Anholt 306d5b1a78aSEric Anholt /* Pointer to the unvalidated bin CL (if present). */ 307d5b1a78aSEric Anholt void *bin_u; 308d5b1a78aSEric Anholt 309d5b1a78aSEric Anholt /* Pointers to the shader recs. These paddr gets incremented as CL 310d5b1a78aSEric Anholt * packets are relocated in validate_gl_shader_state, and the vaddrs 311d5b1a78aSEric Anholt * (u and v) get incremented and size decremented as the shader recs 312d5b1a78aSEric Anholt * themselves are validated. 313d5b1a78aSEric Anholt */ 314d5b1a78aSEric Anholt void *shader_rec_u; 315d5b1a78aSEric Anholt void *shader_rec_v; 316d5b1a78aSEric Anholt uint32_t shader_rec_p; 317d5b1a78aSEric Anholt uint32_t shader_rec_size; 318d5b1a78aSEric Anholt 319d5b1a78aSEric Anholt /* Pointers to the uniform data. These pointers are incremented, and 320d5b1a78aSEric Anholt * size decremented, as each batch of uniforms is uploaded. 321d5b1a78aSEric Anholt */ 322d5b1a78aSEric Anholt void *uniforms_u; 323d5b1a78aSEric Anholt void *uniforms_v; 324d5b1a78aSEric Anholt uint32_t uniforms_p; 325d5b1a78aSEric Anholt uint32_t uniforms_size; 326d5b1a78aSEric Anholt }; 327d5b1a78aSEric Anholt 328d5b1a78aSEric Anholt static inline struct vc4_exec_info * 329ca26d28bSVarad Gautam vc4_first_bin_job(struct vc4_dev *vc4) 330d5b1a78aSEric Anholt { 33157b9f569SMasahiro Yamada return list_first_entry_or_null(&vc4->bin_job_list, 33257b9f569SMasahiro Yamada struct vc4_exec_info, head); 333ca26d28bSVarad Gautam } 334ca26d28bSVarad Gautam 335ca26d28bSVarad Gautam static inline struct vc4_exec_info * 336ca26d28bSVarad Gautam vc4_first_render_job(struct vc4_dev *vc4) 337ca26d28bSVarad Gautam { 33857b9f569SMasahiro Yamada return list_first_entry_or_null(&vc4->render_job_list, 339ca26d28bSVarad Gautam struct vc4_exec_info, head); 340d5b1a78aSEric Anholt } 341d5b1a78aSEric Anholt 3429326e6f2SEric Anholt static inline struct vc4_exec_info * 3439326e6f2SEric Anholt vc4_last_render_job(struct vc4_dev *vc4) 3449326e6f2SEric Anholt { 3459326e6f2SEric Anholt if (list_empty(&vc4->render_job_list)) 3469326e6f2SEric Anholt return NULL; 3479326e6f2SEric Anholt return list_last_entry(&vc4->render_job_list, 3489326e6f2SEric Anholt struct vc4_exec_info, head); 3499326e6f2SEric Anholt } 3509326e6f2SEric Anholt 351c8b75bcaSEric Anholt /** 352463873d5SEric Anholt * struct vc4_texture_sample_info - saves the offsets into the UBO for texture 353463873d5SEric Anholt * setup parameters. 354463873d5SEric Anholt * 355463873d5SEric Anholt * This will be used at draw time to relocate the reference to the texture 356463873d5SEric Anholt * contents in p0, and validate that the offset combined with 357463873d5SEric Anholt * width/height/stride/etc. from p1 and p2/p3 doesn't sample outside the BO. 358463873d5SEric Anholt * Note that the hardware treats unprovided config parameters as 0, so not all 359463873d5SEric Anholt * of them need to be set up for every texure sample, and we'll store ~0 as 360463873d5SEric Anholt * the offset to mark the unused ones. 361463873d5SEric Anholt * 362463873d5SEric Anholt * See the VC4 3D architecture guide page 41 ("Texture and Memory Lookup Unit 363463873d5SEric Anholt * Setup") for definitions of the texture parameters. 364463873d5SEric Anholt */ 365463873d5SEric Anholt struct vc4_texture_sample_info { 366463873d5SEric Anholt bool is_direct; 367463873d5SEric Anholt uint32_t p_offset[4]; 368463873d5SEric Anholt }; 369463873d5SEric Anholt 370463873d5SEric Anholt /** 371463873d5SEric Anholt * struct vc4_validated_shader_info - information about validated shaders that 372463873d5SEric Anholt * needs to be used from command list validation. 373463873d5SEric Anholt * 374463873d5SEric Anholt * For a given shader, each time a shader state record references it, we need 375463873d5SEric Anholt * to verify that the shader doesn't read more uniforms than the shader state 376463873d5SEric Anholt * record's uniform BO pointer can provide, and we need to apply relocations 377463873d5SEric Anholt * and validate the shader state record's uniforms that define the texture 378463873d5SEric Anholt * samples. 379463873d5SEric Anholt */ 380463873d5SEric Anholt struct vc4_validated_shader_info { 381463873d5SEric Anholt uint32_t uniforms_size; 382463873d5SEric Anholt uint32_t uniforms_src_size; 383463873d5SEric Anholt uint32_t num_texture_samples; 384463873d5SEric Anholt struct vc4_texture_sample_info *texture_samples; 3856d45c81dSEric Anholt 3866d45c81dSEric Anholt uint32_t num_uniform_addr_offsets; 3876d45c81dSEric Anholt uint32_t *uniform_addr_offsets; 388c778cc5dSJonas Pfeil 389c778cc5dSJonas Pfeil bool is_threaded; 390463873d5SEric Anholt }; 391463873d5SEric Anholt 392463873d5SEric Anholt /** 393c8b75bcaSEric Anholt * _wait_for - magic (register) wait macro 394c8b75bcaSEric Anholt * 395c8b75bcaSEric Anholt * Does the right thing for modeset paths when run under kdgb or similar atomic 396c8b75bcaSEric Anholt * contexts. Note that it's important that we check the condition again after 397c8b75bcaSEric Anholt * having timed out, since the timeout could be due to preemption or similar and 398c8b75bcaSEric Anholt * we've never had a chance to check the condition before the timeout. 399c8b75bcaSEric Anholt */ 400c8b75bcaSEric Anholt #define _wait_for(COND, MS, W) ({ \ 401c8b75bcaSEric Anholt unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \ 402c8b75bcaSEric Anholt int ret__ = 0; \ 403c8b75bcaSEric Anholt while (!(COND)) { \ 404c8b75bcaSEric Anholt if (time_after(jiffies, timeout__)) { \ 405c8b75bcaSEric Anholt if (!(COND)) \ 406c8b75bcaSEric Anholt ret__ = -ETIMEDOUT; \ 407c8b75bcaSEric Anholt break; \ 408c8b75bcaSEric Anholt } \ 409c8b75bcaSEric Anholt if (W && drm_can_sleep()) { \ 410c8b75bcaSEric Anholt msleep(W); \ 411c8b75bcaSEric Anholt } else { \ 412c8b75bcaSEric Anholt cpu_relax(); \ 413c8b75bcaSEric Anholt } \ 414c8b75bcaSEric Anholt } \ 415c8b75bcaSEric Anholt ret__; \ 416c8b75bcaSEric Anholt }) 417c8b75bcaSEric Anholt 418c8b75bcaSEric Anholt #define wait_for(COND, MS) _wait_for(COND, MS, 1) 419c8b75bcaSEric Anholt 420c8b75bcaSEric Anholt /* vc4_bo.c */ 421c826a6e1SEric Anholt struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); 422c8b75bcaSEric Anholt void vc4_free_object(struct drm_gem_object *gem_obj); 423c826a6e1SEric Anholt struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, 424c826a6e1SEric Anholt bool from_cache); 425c8b75bcaSEric Anholt int vc4_dumb_create(struct drm_file *file_priv, 426c8b75bcaSEric Anholt struct drm_device *dev, 427c8b75bcaSEric Anholt struct drm_mode_create_dumb *args); 428c8b75bcaSEric Anholt struct dma_buf *vc4_prime_export(struct drm_device *dev, 429c8b75bcaSEric Anholt struct drm_gem_object *obj, int flags); 430d5bc60f6SEric Anholt int vc4_create_bo_ioctl(struct drm_device *dev, void *data, 431d5bc60f6SEric Anholt struct drm_file *file_priv); 432463873d5SEric Anholt int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, 433463873d5SEric Anholt struct drm_file *file_priv); 434d5bc60f6SEric Anholt int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, 435d5bc60f6SEric Anholt struct drm_file *file_priv); 43621461365SEric Anholt int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, 43721461365SEric Anholt struct drm_file *file_priv); 438463873d5SEric Anholt int vc4_mmap(struct file *filp, struct vm_area_struct *vma); 439463873d5SEric Anholt int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); 440463873d5SEric Anholt void *vc4_prime_vmap(struct drm_gem_object *obj); 441c826a6e1SEric Anholt void vc4_bo_cache_init(struct drm_device *dev); 442c826a6e1SEric Anholt void vc4_bo_cache_destroy(struct drm_device *dev); 443c826a6e1SEric Anholt int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); 444c8b75bcaSEric Anholt 445c8b75bcaSEric Anholt /* vc4_crtc.c */ 446c8b75bcaSEric Anholt extern struct platform_driver vc4_crtc_driver; 4471f43710aSDave Airlie int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id); 4481f43710aSDave Airlie void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id); 44926fc78f6SDerek Foreman bool vc4_event_pending(struct drm_crtc *crtc); 450c8b75bcaSEric Anholt int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); 4511bf59f1dSMario Kleiner int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, 4521bf59f1dSMario Kleiner unsigned int flags, int *vpos, int *hpos, 4531bf59f1dSMario Kleiner ktime_t *stime, ktime_t *etime, 4541bf59f1dSMario Kleiner const struct drm_display_mode *mode); 4551bf59f1dSMario Kleiner int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, 4561bf59f1dSMario Kleiner int *max_error, struct timeval *vblank_time, 4571bf59f1dSMario Kleiner unsigned flags); 458c8b75bcaSEric Anholt 459c8b75bcaSEric Anholt /* vc4_debugfs.c */ 460c8b75bcaSEric Anholt int vc4_debugfs_init(struct drm_minor *minor); 461c8b75bcaSEric Anholt void vc4_debugfs_cleanup(struct drm_minor *minor); 462c8b75bcaSEric Anholt 463c8b75bcaSEric Anholt /* vc4_drv.c */ 464c8b75bcaSEric Anholt void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index); 465c8b75bcaSEric Anholt 46608302c35SEric Anholt /* vc4_dpi.c */ 46708302c35SEric Anholt extern struct platform_driver vc4_dpi_driver; 46808302c35SEric Anholt int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused); 46908302c35SEric Anholt 470d5b1a78aSEric Anholt /* vc4_gem.c */ 471d5b1a78aSEric Anholt void vc4_gem_init(struct drm_device *dev); 472d5b1a78aSEric Anholt void vc4_gem_destroy(struct drm_device *dev); 473d5b1a78aSEric Anholt int vc4_submit_cl_ioctl(struct drm_device *dev, void *data, 474d5b1a78aSEric Anholt struct drm_file *file_priv); 475d5b1a78aSEric Anholt int vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, 476d5b1a78aSEric Anholt struct drm_file *file_priv); 477d5b1a78aSEric Anholt int vc4_wait_bo_ioctl(struct drm_device *dev, void *data, 478d5b1a78aSEric Anholt struct drm_file *file_priv); 479ca26d28bSVarad Gautam void vc4_submit_next_bin_job(struct drm_device *dev); 480ca26d28bSVarad Gautam void vc4_submit_next_render_job(struct drm_device *dev); 481ca26d28bSVarad Gautam void vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec); 482d5b1a78aSEric Anholt int vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, 483d5b1a78aSEric Anholt uint64_t timeout_ns, bool interruptible); 484d5b1a78aSEric Anholt void vc4_job_handle_completed(struct vc4_dev *vc4); 485b501baccSEric Anholt int vc4_queue_seqno_cb(struct drm_device *dev, 486b501baccSEric Anholt struct vc4_seqno_cb *cb, uint64_t seqno, 487b501baccSEric Anholt void (*func)(struct vc4_seqno_cb *cb)); 488d5b1a78aSEric Anholt 489c8b75bcaSEric Anholt /* vc4_hdmi.c */ 490c8b75bcaSEric Anholt extern struct platform_driver vc4_hdmi_driver; 491c8b75bcaSEric Anholt int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused); 492c8b75bcaSEric Anholt 493e4b81f8cSBoris Brezillon /* vc4_hdmi.c */ 494e4b81f8cSBoris Brezillon extern struct platform_driver vc4_vec_driver; 495e4b81f8cSBoris Brezillon int vc4_vec_debugfs_regs(struct seq_file *m, void *unused); 496e4b81f8cSBoris Brezillon 497d5b1a78aSEric Anholt /* vc4_irq.c */ 498d5b1a78aSEric Anholt irqreturn_t vc4_irq(int irq, void *arg); 499d5b1a78aSEric Anholt void vc4_irq_preinstall(struct drm_device *dev); 500d5b1a78aSEric Anholt int vc4_irq_postinstall(struct drm_device *dev); 501d5b1a78aSEric Anholt void vc4_irq_uninstall(struct drm_device *dev); 502d5b1a78aSEric Anholt void vc4_irq_reset(struct drm_device *dev); 503d5b1a78aSEric Anholt 504c8b75bcaSEric Anholt /* vc4_hvs.c */ 505c8b75bcaSEric Anholt extern struct platform_driver vc4_hvs_driver; 506c8b75bcaSEric Anholt void vc4_hvs_dump_state(struct drm_device *dev); 507c8b75bcaSEric Anholt int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused); 508c8b75bcaSEric Anholt 509c8b75bcaSEric Anholt /* vc4_kms.c */ 510c8b75bcaSEric Anholt int vc4_kms_load(struct drm_device *dev); 511c8b75bcaSEric Anholt 512c8b75bcaSEric Anholt /* vc4_plane.c */ 513c8b75bcaSEric Anholt struct drm_plane *vc4_plane_init(struct drm_device *dev, 514c8b75bcaSEric Anholt enum drm_plane_type type); 515c8b75bcaSEric Anholt u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist); 5162f196b7cSDaniel Vetter u32 vc4_plane_dlist_size(const struct drm_plane_state *state); 517b501baccSEric Anholt void vc4_plane_async_set_fb(struct drm_plane *plane, 518b501baccSEric Anholt struct drm_framebuffer *fb); 519463873d5SEric Anholt 520d3f5168aSEric Anholt /* vc4_v3d.c */ 521d3f5168aSEric Anholt extern struct platform_driver vc4_v3d_driver; 522d3f5168aSEric Anholt int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused); 523d3f5168aSEric Anholt int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused); 524d5b1a78aSEric Anholt 525d5b1a78aSEric Anholt /* vc4_validate.c */ 526d5b1a78aSEric Anholt int 527d5b1a78aSEric Anholt vc4_validate_bin_cl(struct drm_device *dev, 528d5b1a78aSEric Anholt void *validated, 529d5b1a78aSEric Anholt void *unvalidated, 530d5b1a78aSEric Anholt struct vc4_exec_info *exec); 531d5b1a78aSEric Anholt 532d5b1a78aSEric Anholt int 533d5b1a78aSEric Anholt vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); 534d5b1a78aSEric Anholt 535d5b1a78aSEric Anholt struct drm_gem_cma_object *vc4_use_bo(struct vc4_exec_info *exec, 536d5b1a78aSEric Anholt uint32_t hindex); 537d5b1a78aSEric Anholt 538d5b1a78aSEric Anholt int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec); 539d5b1a78aSEric Anholt 540d5b1a78aSEric Anholt bool vc4_check_tex_size(struct vc4_exec_info *exec, 541d5b1a78aSEric Anholt struct drm_gem_cma_object *fbo, 542d5b1a78aSEric Anholt uint32_t offset, uint8_t tiling_format, 543d5b1a78aSEric Anholt uint32_t width, uint32_t height, uint8_t cpp); 544d3f5168aSEric Anholt 545463873d5SEric Anholt /* vc4_validate_shader.c */ 546463873d5SEric Anholt struct vc4_validated_shader_info * 547463873d5SEric Anholt vc4_validate_shader(struct drm_gem_cma_object *shader_obj); 548