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" 11cdec4d36SEric Anholt #include "drm_gem_cma_helper.h" 12c8b75bcaSEric Anholt 13cdec4d36SEric Anholt #include <linux/reservation.h> 149338203cSLaurent Pinchart #include <drm/drm_encoder.h> 159338203cSLaurent Pinchart 16c8b75bcaSEric Anholt struct vc4_dev { 17c8b75bcaSEric Anholt struct drm_device *dev; 18c8b75bcaSEric Anholt 19c8b75bcaSEric Anholt struct vc4_hdmi *hdmi; 20c8b75bcaSEric Anholt struct vc4_hvs *hvs; 21d3f5168aSEric Anholt struct vc4_v3d *v3d; 2208302c35SEric Anholt struct vc4_dpi *dpi; 234078f575SEric Anholt struct vc4_dsi *dsi1; 24e4b81f8cSBoris Brezillon struct vc4_vec *vec; 2548666d56SDerek Foreman 2648666d56SDerek Foreman struct drm_fbdev_cma *fbdev; 27c826a6e1SEric Anholt 2821461365SEric Anholt struct vc4_hang_state *hang_state; 2921461365SEric Anholt 30c826a6e1SEric Anholt /* The kernel-space BO cache. Tracks buffers that have been 31c826a6e1SEric Anholt * unreferenced by all other users (refcounts of 0!) but not 32c826a6e1SEric Anholt * yet freed, so we can do cheap allocations. 33c826a6e1SEric Anholt */ 34c826a6e1SEric Anholt struct vc4_bo_cache { 35c826a6e1SEric Anholt /* Array of list heads for entries in the BO cache, 36c826a6e1SEric Anholt * based on number of pages, so we can do O(1) lookups 37c826a6e1SEric Anholt * in the cache when allocating. 38c826a6e1SEric Anholt */ 39c826a6e1SEric Anholt struct list_head *size_list; 40c826a6e1SEric Anholt uint32_t size_list_size; 41c826a6e1SEric Anholt 42c826a6e1SEric Anholt /* List of all BOs in the cache, ordered by age, so we 43c826a6e1SEric Anholt * can do O(1) lookups when trying to free old 44c826a6e1SEric Anholt * buffers. 45c826a6e1SEric Anholt */ 46c826a6e1SEric Anholt struct list_head time_list; 47c826a6e1SEric Anholt struct work_struct time_work; 48c826a6e1SEric Anholt struct timer_list time_timer; 49c826a6e1SEric Anholt } bo_cache; 50c826a6e1SEric Anholt 51c826a6e1SEric Anholt struct vc4_bo_stats { 52c826a6e1SEric Anholt u32 num_allocated; 53c826a6e1SEric Anholt u32 size_allocated; 54c826a6e1SEric Anholt u32 num_cached; 55c826a6e1SEric Anholt u32 size_cached; 56c826a6e1SEric Anholt } bo_stats; 57c826a6e1SEric Anholt 58c826a6e1SEric Anholt /* Protects bo_cache and the BO stats. */ 59c826a6e1SEric Anholt struct mutex bo_lock; 60d5b1a78aSEric Anholt 61cdec4d36SEric Anholt uint64_t dma_fence_context; 62cdec4d36SEric Anholt 63ca26d28bSVarad Gautam /* Sequence number for the last job queued in bin_job_list. 64d5b1a78aSEric Anholt * Starts at 0 (no jobs emitted). 65d5b1a78aSEric Anholt */ 66d5b1a78aSEric Anholt uint64_t emit_seqno; 67d5b1a78aSEric Anholt 68d5b1a78aSEric Anholt /* Sequence number for the last completed job on the GPU. 69d5b1a78aSEric Anholt * Starts at 0 (no jobs completed). 70d5b1a78aSEric Anholt */ 71d5b1a78aSEric Anholt uint64_t finished_seqno; 72d5b1a78aSEric Anholt 73ca26d28bSVarad Gautam /* List of all struct vc4_exec_info for jobs to be executed in 74ca26d28bSVarad Gautam * the binner. The first job in the list is the one currently 75ca26d28bSVarad Gautam * programmed into ct0ca for execution. 76d5b1a78aSEric Anholt */ 77ca26d28bSVarad Gautam struct list_head bin_job_list; 78ca26d28bSVarad Gautam 79ca26d28bSVarad Gautam /* List of all struct vc4_exec_info for jobs that have 80ca26d28bSVarad Gautam * completed binning and are ready for rendering. The first 81ca26d28bSVarad Gautam * job in the list is the one currently programmed into ct1ca 82ca26d28bSVarad Gautam * for execution. 83ca26d28bSVarad Gautam */ 84ca26d28bSVarad Gautam struct list_head render_job_list; 85ca26d28bSVarad Gautam 86d5b1a78aSEric Anholt /* List of the finished vc4_exec_infos waiting to be freed by 87d5b1a78aSEric Anholt * job_done_work. 88d5b1a78aSEric Anholt */ 89d5b1a78aSEric Anholt struct list_head job_done_list; 90d5b1a78aSEric Anholt /* Spinlock used to synchronize the job_list and seqno 91d5b1a78aSEric Anholt * accesses between the IRQ handler and GEM ioctls. 92d5b1a78aSEric Anholt */ 93d5b1a78aSEric Anholt spinlock_t job_lock; 94d5b1a78aSEric Anholt wait_queue_head_t job_wait_queue; 95d5b1a78aSEric Anholt struct work_struct job_done_work; 96d5b1a78aSEric Anholt 97b501baccSEric Anholt /* List of struct vc4_seqno_cb for callbacks to be made from a 98b501baccSEric Anholt * workqueue when the given seqno is passed. 99b501baccSEric Anholt */ 100b501baccSEric Anholt struct list_head seqno_cb_list; 101b501baccSEric Anholt 102*553c942fSEric Anholt /* The memory used for storing binner tile alloc, tile state, 103*553c942fSEric Anholt * and overflow memory allocations. This is freed when V3D 104*553c942fSEric Anholt * powers down. 105d5b1a78aSEric Anholt */ 106*553c942fSEric Anholt struct vc4_bo *bin_bo; 107*553c942fSEric Anholt 108*553c942fSEric Anholt /* Size of blocks allocated within bin_bo. */ 109*553c942fSEric Anholt uint32_t bin_alloc_size; 110*553c942fSEric Anholt 111*553c942fSEric Anholt /* Bitmask of the bin_alloc_size chunks in bin_bo that are 112*553c942fSEric Anholt * used. 113*553c942fSEric Anholt */ 114*553c942fSEric Anholt uint32_t bin_alloc_used; 115*553c942fSEric Anholt 116*553c942fSEric Anholt /* Bitmask of the current bin_alloc used for overflow memory. */ 117*553c942fSEric Anholt uint32_t bin_alloc_overflow; 118*553c942fSEric Anholt 119d5b1a78aSEric Anholt struct work_struct overflow_mem_work; 120d5b1a78aSEric Anholt 12136cb6253SEric Anholt int power_refcount; 12236cb6253SEric Anholt 12336cb6253SEric Anholt /* Mutex controlling the power refcount. */ 12436cb6253SEric Anholt struct mutex power_lock; 12536cb6253SEric Anholt 126d5b1a78aSEric Anholt struct { 127d5b1a78aSEric Anholt struct timer_list timer; 128d5b1a78aSEric Anholt struct work_struct reset_work; 129d5b1a78aSEric Anholt } hangcheck; 130d5b1a78aSEric Anholt 131d5b1a78aSEric Anholt struct semaphore async_modeset; 132c8b75bcaSEric Anholt }; 133c8b75bcaSEric Anholt 134c8b75bcaSEric Anholt static inline struct vc4_dev * 135c8b75bcaSEric Anholt to_vc4_dev(struct drm_device *dev) 136c8b75bcaSEric Anholt { 137c8b75bcaSEric Anholt return (struct vc4_dev *)dev->dev_private; 138c8b75bcaSEric Anholt } 139c8b75bcaSEric Anholt 140c8b75bcaSEric Anholt struct vc4_bo { 141c8b75bcaSEric Anholt struct drm_gem_cma_object base; 142c826a6e1SEric Anholt 1437edabee0SEric Anholt /* seqno of the last job to render using this BO. */ 144d5b1a78aSEric Anholt uint64_t seqno; 145d5b1a78aSEric Anholt 1467edabee0SEric Anholt /* seqno of the last job to use the RCL to write to this BO. 1477edabee0SEric Anholt * 1487edabee0SEric Anholt * Note that this doesn't include binner overflow memory 1497edabee0SEric Anholt * writes. 1507edabee0SEric Anholt */ 1517edabee0SEric Anholt uint64_t write_seqno; 1527edabee0SEric Anholt 153c826a6e1SEric Anholt /* List entry for the BO's position in either 154c826a6e1SEric Anholt * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list 155c826a6e1SEric Anholt */ 156c826a6e1SEric Anholt struct list_head unref_head; 157c826a6e1SEric Anholt 158c826a6e1SEric Anholt /* Time in jiffies when the BO was put in vc4->bo_cache. */ 159c826a6e1SEric Anholt unsigned long free_time; 160c826a6e1SEric Anholt 161c826a6e1SEric Anholt /* List entry for the BO's position in vc4_dev->bo_cache.size_list */ 162c826a6e1SEric Anholt struct list_head size_head; 163463873d5SEric Anholt 164463873d5SEric Anholt /* Struct for shader validation state, if created by 165463873d5SEric Anholt * DRM_IOCTL_VC4_CREATE_SHADER_BO. 166463873d5SEric Anholt */ 167463873d5SEric Anholt struct vc4_validated_shader_info *validated_shader; 168cdec4d36SEric Anholt 169cdec4d36SEric Anholt /* normally (resv == &_resv) except for imported bo's */ 170cdec4d36SEric Anholt struct reservation_object *resv; 171cdec4d36SEric Anholt struct reservation_object _resv; 172c8b75bcaSEric Anholt }; 173c8b75bcaSEric Anholt 174c8b75bcaSEric Anholt static inline struct vc4_bo * 175c8b75bcaSEric Anholt to_vc4_bo(struct drm_gem_object *bo) 176c8b75bcaSEric Anholt { 177c8b75bcaSEric Anholt return (struct vc4_bo *)bo; 178c8b75bcaSEric Anholt } 179c8b75bcaSEric Anholt 180cdec4d36SEric Anholt struct vc4_fence { 181cdec4d36SEric Anholt struct dma_fence base; 182cdec4d36SEric Anholt struct drm_device *dev; 183cdec4d36SEric Anholt /* vc4 seqno for signaled() test */ 184cdec4d36SEric Anholt uint64_t seqno; 185cdec4d36SEric Anholt }; 186cdec4d36SEric Anholt 187cdec4d36SEric Anholt static inline struct vc4_fence * 188cdec4d36SEric Anholt to_vc4_fence(struct dma_fence *fence) 189cdec4d36SEric Anholt { 190cdec4d36SEric Anholt return (struct vc4_fence *)fence; 191cdec4d36SEric Anholt } 192cdec4d36SEric Anholt 193b501baccSEric Anholt struct vc4_seqno_cb { 194b501baccSEric Anholt struct work_struct work; 195b501baccSEric Anholt uint64_t seqno; 196b501baccSEric Anholt void (*func)(struct vc4_seqno_cb *cb); 197b501baccSEric Anholt }; 198b501baccSEric Anholt 199d3f5168aSEric Anholt struct vc4_v3d { 200001bdb55SEric Anholt struct vc4_dev *vc4; 201d3f5168aSEric Anholt struct platform_device *pdev; 202d3f5168aSEric Anholt void __iomem *regs; 203d3f5168aSEric Anholt }; 204d3f5168aSEric Anholt 205c8b75bcaSEric Anholt struct vc4_hvs { 206c8b75bcaSEric Anholt struct platform_device *pdev; 207c8b75bcaSEric Anholt void __iomem *regs; 208d8dbf44fSEric Anholt u32 __iomem *dlist; 209d8dbf44fSEric Anholt 210d8dbf44fSEric Anholt /* Memory manager for CRTCs to allocate space in the display 211d8dbf44fSEric Anholt * list. Units are dwords. 212d8dbf44fSEric Anholt */ 213d8dbf44fSEric Anholt struct drm_mm dlist_mm; 21421af94cfSEric Anholt /* Memory manager for the LBM memory used by HVS scaling. */ 21521af94cfSEric Anholt struct drm_mm lbm_mm; 216d8dbf44fSEric Anholt spinlock_t mm_lock; 21721af94cfSEric Anholt 21821af94cfSEric Anholt struct drm_mm_node mitchell_netravali_filter; 219c8b75bcaSEric Anholt }; 220c8b75bcaSEric Anholt 221c8b75bcaSEric Anholt struct vc4_plane { 222c8b75bcaSEric Anholt struct drm_plane base; 223c8b75bcaSEric Anholt }; 224c8b75bcaSEric Anholt 225c8b75bcaSEric Anholt static inline struct vc4_plane * 226c8b75bcaSEric Anholt to_vc4_plane(struct drm_plane *plane) 227c8b75bcaSEric Anholt { 228c8b75bcaSEric Anholt return (struct vc4_plane *)plane; 229c8b75bcaSEric Anholt } 230c8b75bcaSEric Anholt 231c8b75bcaSEric Anholt enum vc4_encoder_type { 232ab8df60eSBoris Brezillon VC4_ENCODER_TYPE_NONE, 233c8b75bcaSEric Anholt VC4_ENCODER_TYPE_HDMI, 234c8b75bcaSEric Anholt VC4_ENCODER_TYPE_VEC, 235c8b75bcaSEric Anholt VC4_ENCODER_TYPE_DSI0, 236c8b75bcaSEric Anholt VC4_ENCODER_TYPE_DSI1, 237c8b75bcaSEric Anholt VC4_ENCODER_TYPE_SMI, 238c8b75bcaSEric Anholt VC4_ENCODER_TYPE_DPI, 239c8b75bcaSEric Anholt }; 240c8b75bcaSEric Anholt 241c8b75bcaSEric Anholt struct vc4_encoder { 242c8b75bcaSEric Anholt struct drm_encoder base; 243c8b75bcaSEric Anholt enum vc4_encoder_type type; 244c8b75bcaSEric Anholt u32 clock_select; 245c8b75bcaSEric Anholt }; 246c8b75bcaSEric Anholt 247c8b75bcaSEric Anholt static inline struct vc4_encoder * 248c8b75bcaSEric Anholt to_vc4_encoder(struct drm_encoder *encoder) 249c8b75bcaSEric Anholt { 250c8b75bcaSEric Anholt return container_of(encoder, struct vc4_encoder, base); 251c8b75bcaSEric Anholt } 252c8b75bcaSEric Anholt 253d3f5168aSEric Anholt #define V3D_READ(offset) readl(vc4->v3d->regs + offset) 254d3f5168aSEric Anholt #define V3D_WRITE(offset, val) writel(val, vc4->v3d->regs + offset) 255c8b75bcaSEric Anholt #define HVS_READ(offset) readl(vc4->hvs->regs + offset) 256c8b75bcaSEric Anholt #define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset) 257c8b75bcaSEric Anholt 258d5b1a78aSEric Anholt struct vc4_exec_info { 259d5b1a78aSEric Anholt /* Sequence number for this bin/render job. */ 260d5b1a78aSEric Anholt uint64_t seqno; 261d5b1a78aSEric Anholt 2627edabee0SEric Anholt /* Latest write_seqno of any BO that binning depends on. */ 2637edabee0SEric Anholt uint64_t bin_dep_seqno; 2647edabee0SEric Anholt 265cdec4d36SEric Anholt struct dma_fence *fence; 266cdec4d36SEric Anholt 267c4ce60dcSEric Anholt /* Last current addresses the hardware was processing when the 268c4ce60dcSEric Anholt * hangcheck timer checked on us. 269c4ce60dcSEric Anholt */ 270c4ce60dcSEric Anholt uint32_t last_ct0ca, last_ct1ca; 271c4ce60dcSEric Anholt 272d5b1a78aSEric Anholt /* Kernel-space copy of the ioctl arguments */ 273d5b1a78aSEric Anholt struct drm_vc4_submit_cl *args; 274d5b1a78aSEric Anholt 275d5b1a78aSEric Anholt /* This is the array of BOs that were looked up at the start of exec. 276d5b1a78aSEric Anholt * Command validation will use indices into this array. 277d5b1a78aSEric Anholt */ 278d5b1a78aSEric Anholt struct drm_gem_cma_object **bo; 279d5b1a78aSEric Anholt uint32_t bo_count; 280d5b1a78aSEric Anholt 2817edabee0SEric Anholt /* List of BOs that are being written by the RCL. Other than 2827edabee0SEric Anholt * the binner temporary storage, this is all the BOs written 2837edabee0SEric Anholt * by the job. 2847edabee0SEric Anholt */ 2857edabee0SEric Anholt struct drm_gem_cma_object *rcl_write_bo[4]; 2867edabee0SEric Anholt uint32_t rcl_write_bo_count; 2877edabee0SEric Anholt 288d5b1a78aSEric Anholt /* Pointers for our position in vc4->job_list */ 289d5b1a78aSEric Anholt struct list_head head; 290d5b1a78aSEric Anholt 291d5b1a78aSEric Anholt /* List of other BOs used in the job that need to be released 292d5b1a78aSEric Anholt * once the job is complete. 293d5b1a78aSEric Anholt */ 294d5b1a78aSEric Anholt struct list_head unref_list; 295d5b1a78aSEric Anholt 296d5b1a78aSEric Anholt /* Current unvalidated indices into @bo loaded by the non-hardware 297d5b1a78aSEric Anholt * VC4_PACKET_GEM_HANDLES. 298d5b1a78aSEric Anholt */ 299d5b1a78aSEric Anholt uint32_t bo_index[2]; 300d5b1a78aSEric Anholt 301d5b1a78aSEric Anholt /* This is the BO where we store the validated command lists, shader 302d5b1a78aSEric Anholt * records, and uniforms. 303d5b1a78aSEric Anholt */ 304d5b1a78aSEric Anholt struct drm_gem_cma_object *exec_bo; 305d5b1a78aSEric Anholt 306d5b1a78aSEric Anholt /** 307d5b1a78aSEric Anholt * This tracks the per-shader-record state (packet 64) that 308d5b1a78aSEric Anholt * determines the length of the shader record and the offset 309d5b1a78aSEric Anholt * it's expected to be found at. It gets read in from the 310d5b1a78aSEric Anholt * command lists. 311d5b1a78aSEric Anholt */ 312d5b1a78aSEric Anholt struct vc4_shader_state { 313d5b1a78aSEric Anholt uint32_t addr; 314d5b1a78aSEric Anholt /* Maximum vertex index referenced by any primitive using this 315d5b1a78aSEric Anholt * shader state. 316d5b1a78aSEric Anholt */ 317d5b1a78aSEric Anholt uint32_t max_index; 318d5b1a78aSEric Anholt } *shader_state; 319d5b1a78aSEric Anholt 320d5b1a78aSEric Anholt /** How many shader states the user declared they were using. */ 321d5b1a78aSEric Anholt uint32_t shader_state_size; 322d5b1a78aSEric Anholt /** How many shader state records the validator has seen. */ 323d5b1a78aSEric Anholt uint32_t shader_state_count; 324d5b1a78aSEric Anholt 325d5b1a78aSEric Anholt bool found_tile_binning_mode_config_packet; 326d5b1a78aSEric Anholt bool found_start_tile_binning_packet; 327d5b1a78aSEric Anholt bool found_increment_semaphore_packet; 328d5b1a78aSEric Anholt bool found_flush; 329d5b1a78aSEric Anholt uint8_t bin_tiles_x, bin_tiles_y; 330*553c942fSEric Anholt /* Physical address of the start of the tile alloc array 331*553c942fSEric Anholt * (where each tile's binned CL will start) 332*553c942fSEric Anholt */ 333d5b1a78aSEric Anholt uint32_t tile_alloc_offset; 334*553c942fSEric Anholt /* Bitmask of which binner slots are freed when this job completes. */ 335*553c942fSEric Anholt uint32_t bin_slots; 336d5b1a78aSEric Anholt 337d5b1a78aSEric Anholt /** 338d5b1a78aSEric Anholt * Computed addresses pointing into exec_bo where we start the 339d5b1a78aSEric Anholt * bin thread (ct0) and render thread (ct1). 340d5b1a78aSEric Anholt */ 341d5b1a78aSEric Anholt uint32_t ct0ca, ct0ea; 342d5b1a78aSEric Anholt uint32_t ct1ca, ct1ea; 343d5b1a78aSEric Anholt 344d5b1a78aSEric Anholt /* Pointer to the unvalidated bin CL (if present). */ 345d5b1a78aSEric Anholt void *bin_u; 346d5b1a78aSEric Anholt 347d5b1a78aSEric Anholt /* Pointers to the shader recs. These paddr gets incremented as CL 348d5b1a78aSEric Anholt * packets are relocated in validate_gl_shader_state, and the vaddrs 349d5b1a78aSEric Anholt * (u and v) get incremented and size decremented as the shader recs 350d5b1a78aSEric Anholt * themselves are validated. 351d5b1a78aSEric Anholt */ 352d5b1a78aSEric Anholt void *shader_rec_u; 353d5b1a78aSEric Anholt void *shader_rec_v; 354d5b1a78aSEric Anholt uint32_t shader_rec_p; 355d5b1a78aSEric Anholt uint32_t shader_rec_size; 356d5b1a78aSEric Anholt 357d5b1a78aSEric Anholt /* Pointers to the uniform data. These pointers are incremented, and 358d5b1a78aSEric Anholt * size decremented, as each batch of uniforms is uploaded. 359d5b1a78aSEric Anholt */ 360d5b1a78aSEric Anholt void *uniforms_u; 361d5b1a78aSEric Anholt void *uniforms_v; 362d5b1a78aSEric Anholt uint32_t uniforms_p; 363d5b1a78aSEric Anholt uint32_t uniforms_size; 364d5b1a78aSEric Anholt }; 365d5b1a78aSEric Anholt 366d5b1a78aSEric Anholt static inline struct vc4_exec_info * 367ca26d28bSVarad Gautam vc4_first_bin_job(struct vc4_dev *vc4) 368d5b1a78aSEric Anholt { 36957b9f569SMasahiro Yamada return list_first_entry_or_null(&vc4->bin_job_list, 37057b9f569SMasahiro Yamada struct vc4_exec_info, head); 371ca26d28bSVarad Gautam } 372ca26d28bSVarad Gautam 373ca26d28bSVarad Gautam static inline struct vc4_exec_info * 374ca26d28bSVarad Gautam vc4_first_render_job(struct vc4_dev *vc4) 375ca26d28bSVarad Gautam { 37657b9f569SMasahiro Yamada return list_first_entry_or_null(&vc4->render_job_list, 377ca26d28bSVarad Gautam struct vc4_exec_info, head); 378d5b1a78aSEric Anholt } 379d5b1a78aSEric Anholt 3809326e6f2SEric Anholt static inline struct vc4_exec_info * 3819326e6f2SEric Anholt vc4_last_render_job(struct vc4_dev *vc4) 3829326e6f2SEric Anholt { 3839326e6f2SEric Anholt if (list_empty(&vc4->render_job_list)) 3849326e6f2SEric Anholt return NULL; 3859326e6f2SEric Anholt return list_last_entry(&vc4->render_job_list, 3869326e6f2SEric Anholt struct vc4_exec_info, head); 3879326e6f2SEric Anholt } 3889326e6f2SEric Anholt 389c8b75bcaSEric Anholt /** 390463873d5SEric Anholt * struct vc4_texture_sample_info - saves the offsets into the UBO for texture 391463873d5SEric Anholt * setup parameters. 392463873d5SEric Anholt * 393463873d5SEric Anholt * This will be used at draw time to relocate the reference to the texture 394463873d5SEric Anholt * contents in p0, and validate that the offset combined with 395463873d5SEric Anholt * width/height/stride/etc. from p1 and p2/p3 doesn't sample outside the BO. 396463873d5SEric Anholt * Note that the hardware treats unprovided config parameters as 0, so not all 397463873d5SEric Anholt * of them need to be set up for every texure sample, and we'll store ~0 as 398463873d5SEric Anholt * the offset to mark the unused ones. 399463873d5SEric Anholt * 400463873d5SEric Anholt * See the VC4 3D architecture guide page 41 ("Texture and Memory Lookup Unit 401463873d5SEric Anholt * Setup") for definitions of the texture parameters. 402463873d5SEric Anholt */ 403463873d5SEric Anholt struct vc4_texture_sample_info { 404463873d5SEric Anholt bool is_direct; 405463873d5SEric Anholt uint32_t p_offset[4]; 406463873d5SEric Anholt }; 407463873d5SEric Anholt 408463873d5SEric Anholt /** 409463873d5SEric Anholt * struct vc4_validated_shader_info - information about validated shaders that 410463873d5SEric Anholt * needs to be used from command list validation. 411463873d5SEric Anholt * 412463873d5SEric Anholt * For a given shader, each time a shader state record references it, we need 413463873d5SEric Anholt * to verify that the shader doesn't read more uniforms than the shader state 414463873d5SEric Anholt * record's uniform BO pointer can provide, and we need to apply relocations 415463873d5SEric Anholt * and validate the shader state record's uniforms that define the texture 416463873d5SEric Anholt * samples. 417463873d5SEric Anholt */ 418463873d5SEric Anholt struct vc4_validated_shader_info { 419463873d5SEric Anholt uint32_t uniforms_size; 420463873d5SEric Anholt uint32_t uniforms_src_size; 421463873d5SEric Anholt uint32_t num_texture_samples; 422463873d5SEric Anholt struct vc4_texture_sample_info *texture_samples; 4236d45c81dSEric Anholt 4246d45c81dSEric Anholt uint32_t num_uniform_addr_offsets; 4256d45c81dSEric Anholt uint32_t *uniform_addr_offsets; 426c778cc5dSJonas Pfeil 427c778cc5dSJonas Pfeil bool is_threaded; 428463873d5SEric Anholt }; 429463873d5SEric Anholt 430463873d5SEric Anholt /** 431c8b75bcaSEric Anholt * _wait_for - magic (register) wait macro 432c8b75bcaSEric Anholt * 433c8b75bcaSEric Anholt * Does the right thing for modeset paths when run under kdgb or similar atomic 434c8b75bcaSEric Anholt * contexts. Note that it's important that we check the condition again after 435c8b75bcaSEric Anholt * having timed out, since the timeout could be due to preemption or similar and 436c8b75bcaSEric Anholt * we've never had a chance to check the condition before the timeout. 437c8b75bcaSEric Anholt */ 438c8b75bcaSEric Anholt #define _wait_for(COND, MS, W) ({ \ 439c8b75bcaSEric Anholt unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \ 440c8b75bcaSEric Anholt int ret__ = 0; \ 441c8b75bcaSEric Anholt while (!(COND)) { \ 442c8b75bcaSEric Anholt if (time_after(jiffies, timeout__)) { \ 443c8b75bcaSEric Anholt if (!(COND)) \ 444c8b75bcaSEric Anholt ret__ = -ETIMEDOUT; \ 445c8b75bcaSEric Anholt break; \ 446c8b75bcaSEric Anholt } \ 447c8b75bcaSEric Anholt if (W && drm_can_sleep()) { \ 448c8b75bcaSEric Anholt msleep(W); \ 449c8b75bcaSEric Anholt } else { \ 450c8b75bcaSEric Anholt cpu_relax(); \ 451c8b75bcaSEric Anholt } \ 452c8b75bcaSEric Anholt } \ 453c8b75bcaSEric Anholt ret__; \ 454c8b75bcaSEric Anholt }) 455c8b75bcaSEric Anholt 456c8b75bcaSEric Anholt #define wait_for(COND, MS) _wait_for(COND, MS, 1) 457c8b75bcaSEric Anholt 458c8b75bcaSEric Anholt /* vc4_bo.c */ 459c826a6e1SEric Anholt struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size); 460c8b75bcaSEric Anholt void vc4_free_object(struct drm_gem_object *gem_obj); 461c826a6e1SEric Anholt struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size, 462c826a6e1SEric Anholt bool from_cache); 463c8b75bcaSEric Anholt int vc4_dumb_create(struct drm_file *file_priv, 464c8b75bcaSEric Anholt struct drm_device *dev, 465c8b75bcaSEric Anholt struct drm_mode_create_dumb *args); 466c8b75bcaSEric Anholt struct dma_buf *vc4_prime_export(struct drm_device *dev, 467c8b75bcaSEric Anholt struct drm_gem_object *obj, int flags); 468d5bc60f6SEric Anholt int vc4_create_bo_ioctl(struct drm_device *dev, void *data, 469d5bc60f6SEric Anholt struct drm_file *file_priv); 470463873d5SEric Anholt int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data, 471463873d5SEric Anholt struct drm_file *file_priv); 472d5bc60f6SEric Anholt int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data, 473d5bc60f6SEric Anholt struct drm_file *file_priv); 47421461365SEric Anholt int vc4_get_hang_state_ioctl(struct drm_device *dev, void *data, 47521461365SEric Anholt struct drm_file *file_priv); 476463873d5SEric Anholt int vc4_mmap(struct file *filp, struct vm_area_struct *vma); 477cdec4d36SEric Anholt struct reservation_object *vc4_prime_res_obj(struct drm_gem_object *obj); 478463873d5SEric Anholt int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma); 479cdec4d36SEric Anholt struct drm_gem_object *vc4_prime_import_sg_table(struct drm_device *dev, 480cdec4d36SEric Anholt struct dma_buf_attachment *attach, 481cdec4d36SEric Anholt struct sg_table *sgt); 482463873d5SEric Anholt void *vc4_prime_vmap(struct drm_gem_object *obj); 483c826a6e1SEric Anholt void vc4_bo_cache_init(struct drm_device *dev); 484c826a6e1SEric Anholt void vc4_bo_cache_destroy(struct drm_device *dev); 485c826a6e1SEric Anholt int vc4_bo_stats_debugfs(struct seq_file *m, void *arg); 486c8b75bcaSEric Anholt 487c8b75bcaSEric Anholt /* vc4_crtc.c */ 488c8b75bcaSEric Anholt extern struct platform_driver vc4_crtc_driver; 48926fc78f6SDerek Foreman bool vc4_event_pending(struct drm_crtc *crtc); 490c8b75bcaSEric Anholt int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg); 4911bf59f1dSMario Kleiner int vc4_crtc_get_scanoutpos(struct drm_device *dev, unsigned int crtc_id, 4921bf59f1dSMario Kleiner unsigned int flags, int *vpos, int *hpos, 4931bf59f1dSMario Kleiner ktime_t *stime, ktime_t *etime, 4941bf59f1dSMario Kleiner const struct drm_display_mode *mode); 4951bf59f1dSMario Kleiner int vc4_crtc_get_vblank_timestamp(struct drm_device *dev, unsigned int crtc_id, 4961bf59f1dSMario Kleiner int *max_error, struct timeval *vblank_time, 4971bf59f1dSMario Kleiner unsigned flags); 498c8b75bcaSEric Anholt 499c8b75bcaSEric Anholt /* vc4_debugfs.c */ 500c8b75bcaSEric Anholt int vc4_debugfs_init(struct drm_minor *minor); 501c8b75bcaSEric Anholt 502c8b75bcaSEric Anholt /* vc4_drv.c */ 503c8b75bcaSEric Anholt void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index); 504c8b75bcaSEric Anholt 50508302c35SEric Anholt /* vc4_dpi.c */ 50608302c35SEric Anholt extern struct platform_driver vc4_dpi_driver; 50708302c35SEric Anholt int vc4_dpi_debugfs_regs(struct seq_file *m, void *unused); 50808302c35SEric Anholt 5094078f575SEric Anholt /* vc4_dsi.c */ 5104078f575SEric Anholt extern struct platform_driver vc4_dsi_driver; 5114078f575SEric Anholt int vc4_dsi_debugfs_regs(struct seq_file *m, void *unused); 5124078f575SEric Anholt 513cdec4d36SEric Anholt /* vc4_fence.c */ 514cdec4d36SEric Anholt extern const struct dma_fence_ops vc4_fence_ops; 515cdec4d36SEric Anholt 516d5b1a78aSEric Anholt /* vc4_gem.c */ 517d5b1a78aSEric Anholt void vc4_gem_init(struct drm_device *dev); 518d5b1a78aSEric Anholt void vc4_gem_destroy(struct drm_device *dev); 519d5b1a78aSEric Anholt int vc4_submit_cl_ioctl(struct drm_device *dev, void *data, 520d5b1a78aSEric Anholt struct drm_file *file_priv); 521d5b1a78aSEric Anholt int vc4_wait_seqno_ioctl(struct drm_device *dev, void *data, 522d5b1a78aSEric Anholt struct drm_file *file_priv); 523d5b1a78aSEric Anholt int vc4_wait_bo_ioctl(struct drm_device *dev, void *data, 524d5b1a78aSEric Anholt struct drm_file *file_priv); 525ca26d28bSVarad Gautam void vc4_submit_next_bin_job(struct drm_device *dev); 526ca26d28bSVarad Gautam void vc4_submit_next_render_job(struct drm_device *dev); 527ca26d28bSVarad Gautam void vc4_move_job_to_render(struct drm_device *dev, struct vc4_exec_info *exec); 528d5b1a78aSEric Anholt int vc4_wait_for_seqno(struct drm_device *dev, uint64_t seqno, 529d5b1a78aSEric Anholt uint64_t timeout_ns, bool interruptible); 530d5b1a78aSEric Anholt void vc4_job_handle_completed(struct vc4_dev *vc4); 531b501baccSEric Anholt int vc4_queue_seqno_cb(struct drm_device *dev, 532b501baccSEric Anholt struct vc4_seqno_cb *cb, uint64_t seqno, 533b501baccSEric Anholt void (*func)(struct vc4_seqno_cb *cb)); 534d5b1a78aSEric Anholt 535c8b75bcaSEric Anholt /* vc4_hdmi.c */ 536c8b75bcaSEric Anholt extern struct platform_driver vc4_hdmi_driver; 537c8b75bcaSEric Anholt int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused); 538c8b75bcaSEric Anholt 539e4b81f8cSBoris Brezillon /* vc4_hdmi.c */ 540e4b81f8cSBoris Brezillon extern struct platform_driver vc4_vec_driver; 541e4b81f8cSBoris Brezillon int vc4_vec_debugfs_regs(struct seq_file *m, void *unused); 542e4b81f8cSBoris Brezillon 543d5b1a78aSEric Anholt /* vc4_irq.c */ 544d5b1a78aSEric Anholt irqreturn_t vc4_irq(int irq, void *arg); 545d5b1a78aSEric Anholt void vc4_irq_preinstall(struct drm_device *dev); 546d5b1a78aSEric Anholt int vc4_irq_postinstall(struct drm_device *dev); 547d5b1a78aSEric Anholt void vc4_irq_uninstall(struct drm_device *dev); 548d5b1a78aSEric Anholt void vc4_irq_reset(struct drm_device *dev); 549d5b1a78aSEric Anholt 550c8b75bcaSEric Anholt /* vc4_hvs.c */ 551c8b75bcaSEric Anholt extern struct platform_driver vc4_hvs_driver; 552c8b75bcaSEric Anholt void vc4_hvs_dump_state(struct drm_device *dev); 553c8b75bcaSEric Anholt int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused); 554c8b75bcaSEric Anholt 555c8b75bcaSEric Anholt /* vc4_kms.c */ 556c8b75bcaSEric Anholt int vc4_kms_load(struct drm_device *dev); 557c8b75bcaSEric Anholt 558c8b75bcaSEric Anholt /* vc4_plane.c */ 559c8b75bcaSEric Anholt struct drm_plane *vc4_plane_init(struct drm_device *dev, 560c8b75bcaSEric Anholt enum drm_plane_type type); 561c8b75bcaSEric Anholt u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist); 5622f196b7cSDaniel Vetter u32 vc4_plane_dlist_size(const struct drm_plane_state *state); 563b501baccSEric Anholt void vc4_plane_async_set_fb(struct drm_plane *plane, 564b501baccSEric Anholt struct drm_framebuffer *fb); 565463873d5SEric Anholt 566d3f5168aSEric Anholt /* vc4_v3d.c */ 567d3f5168aSEric Anholt extern struct platform_driver vc4_v3d_driver; 568d3f5168aSEric Anholt int vc4_v3d_debugfs_ident(struct seq_file *m, void *unused); 569d3f5168aSEric Anholt int vc4_v3d_debugfs_regs(struct seq_file *m, void *unused); 570*553c942fSEric Anholt int vc4_v3d_get_bin_slot(struct vc4_dev *vc4); 571d5b1a78aSEric Anholt 572d5b1a78aSEric Anholt /* vc4_validate.c */ 573d5b1a78aSEric Anholt int 574d5b1a78aSEric Anholt vc4_validate_bin_cl(struct drm_device *dev, 575d5b1a78aSEric Anholt void *validated, 576d5b1a78aSEric Anholt void *unvalidated, 577d5b1a78aSEric Anholt struct vc4_exec_info *exec); 578d5b1a78aSEric Anholt 579d5b1a78aSEric Anholt int 580d5b1a78aSEric Anholt vc4_validate_shader_recs(struct drm_device *dev, struct vc4_exec_info *exec); 581d5b1a78aSEric Anholt 582d5b1a78aSEric Anholt struct drm_gem_cma_object *vc4_use_bo(struct vc4_exec_info *exec, 583d5b1a78aSEric Anholt uint32_t hindex); 584d5b1a78aSEric Anholt 585d5b1a78aSEric Anholt int vc4_get_rcl(struct drm_device *dev, struct vc4_exec_info *exec); 586d5b1a78aSEric Anholt 587d5b1a78aSEric Anholt bool vc4_check_tex_size(struct vc4_exec_info *exec, 588d5b1a78aSEric Anholt struct drm_gem_cma_object *fbo, 589d5b1a78aSEric Anholt uint32_t offset, uint8_t tiling_format, 590d5b1a78aSEric Anholt uint32_t width, uint32_t height, uint8_t cpp); 591d3f5168aSEric Anholt 592463873d5SEric Anholt /* vc4_validate_shader.c */ 593463873d5SEric Anholt struct vc4_validated_shader_info * 594463873d5SEric Anholt vc4_validate_shader(struct drm_gem_cma_object *shader_obj); 595