blob: bd77d5574e30b7b1d95c14590c571ed4b429f925 [file] [log] [blame]
Eric Anholtc8b75bc2015-03-02 13:01:12 -08001/*
2 * Copyright (C) 2015 Broadcom
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
7 */
8
9#include "drmP.h"
10#include "drm_gem_cma_helper.h"
11
12struct vc4_dev {
13 struct drm_device *dev;
14
15 struct vc4_hdmi *hdmi;
16 struct vc4_hvs *hvs;
17 struct vc4_crtc *crtc[3];
Derek Foreman48666d52015-07-02 11:19:54 -050018
19 struct drm_fbdev_cma *fbdev;
Eric Anholtc826a6e2015-10-09 20:25:07 -070020
21 /* The kernel-space BO cache. Tracks buffers that have been
22 * unreferenced by all other users (refcounts of 0!) but not
23 * yet freed, so we can do cheap allocations.
24 */
25 struct vc4_bo_cache {
26 /* Array of list heads for entries in the BO cache,
27 * based on number of pages, so we can do O(1) lookups
28 * in the cache when allocating.
29 */
30 struct list_head *size_list;
31 uint32_t size_list_size;
32
33 /* List of all BOs in the cache, ordered by age, so we
34 * can do O(1) lookups when trying to free old
35 * buffers.
36 */
37 struct list_head time_list;
38 struct work_struct time_work;
39 struct timer_list time_timer;
40 } bo_cache;
41
42 struct vc4_bo_stats {
43 u32 num_allocated;
44 u32 size_allocated;
45 u32 num_cached;
46 u32 size_cached;
47 } bo_stats;
48
49 /* Protects bo_cache and the BO stats. */
50 struct mutex bo_lock;
Eric Anholtc8b75bc2015-03-02 13:01:12 -080051};
52
53static inline struct vc4_dev *
54to_vc4_dev(struct drm_device *dev)
55{
56 return (struct vc4_dev *)dev->dev_private;
57}
58
59struct vc4_bo {
60 struct drm_gem_cma_object base;
Eric Anholtc826a6e2015-10-09 20:25:07 -070061
62 /* List entry for the BO's position in either
63 * vc4_exec_info->unref_list or vc4_dev->bo_cache.time_list
64 */
65 struct list_head unref_head;
66
67 /* Time in jiffies when the BO was put in vc4->bo_cache. */
68 unsigned long free_time;
69
70 /* List entry for the BO's position in vc4_dev->bo_cache.size_list */
71 struct list_head size_head;
Eric Anholt463873d2015-11-30 11:41:40 -080072
73 /* Struct for shader validation state, if created by
74 * DRM_IOCTL_VC4_CREATE_SHADER_BO.
75 */
76 struct vc4_validated_shader_info *validated_shader;
Eric Anholtc8b75bc2015-03-02 13:01:12 -080077};
78
79static inline struct vc4_bo *
80to_vc4_bo(struct drm_gem_object *bo)
81{
82 return (struct vc4_bo *)bo;
83}
84
85struct vc4_hvs {
86 struct platform_device *pdev;
87 void __iomem *regs;
88 void __iomem *dlist;
89};
90
91struct vc4_plane {
92 struct drm_plane base;
93};
94
95static inline struct vc4_plane *
96to_vc4_plane(struct drm_plane *plane)
97{
98 return (struct vc4_plane *)plane;
99}
100
101enum vc4_encoder_type {
102 VC4_ENCODER_TYPE_HDMI,
103 VC4_ENCODER_TYPE_VEC,
104 VC4_ENCODER_TYPE_DSI0,
105 VC4_ENCODER_TYPE_DSI1,
106 VC4_ENCODER_TYPE_SMI,
107 VC4_ENCODER_TYPE_DPI,
108};
109
110struct vc4_encoder {
111 struct drm_encoder base;
112 enum vc4_encoder_type type;
113 u32 clock_select;
114};
115
116static inline struct vc4_encoder *
117to_vc4_encoder(struct drm_encoder *encoder)
118{
119 return container_of(encoder, struct vc4_encoder, base);
120}
121
122#define HVS_READ(offset) readl(vc4->hvs->regs + offset)
123#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
124
125/**
Eric Anholt463873d2015-11-30 11:41:40 -0800126 * struct vc4_texture_sample_info - saves the offsets into the UBO for texture
127 * setup parameters.
128 *
129 * This will be used at draw time to relocate the reference to the texture
130 * contents in p0, and validate that the offset combined with
131 * width/height/stride/etc. from p1 and p2/p3 doesn't sample outside the BO.
132 * Note that the hardware treats unprovided config parameters as 0, so not all
133 * of them need to be set up for every texure sample, and we'll store ~0 as
134 * the offset to mark the unused ones.
135 *
136 * See the VC4 3D architecture guide page 41 ("Texture and Memory Lookup Unit
137 * Setup") for definitions of the texture parameters.
138 */
139struct vc4_texture_sample_info {
140 bool is_direct;
141 uint32_t p_offset[4];
142};
143
144/**
145 * struct vc4_validated_shader_info - information about validated shaders that
146 * needs to be used from command list validation.
147 *
148 * For a given shader, each time a shader state record references it, we need
149 * to verify that the shader doesn't read more uniforms than the shader state
150 * record's uniform BO pointer can provide, and we need to apply relocations
151 * and validate the shader state record's uniforms that define the texture
152 * samples.
153 */
154struct vc4_validated_shader_info {
155 uint32_t uniforms_size;
156 uint32_t uniforms_src_size;
157 uint32_t num_texture_samples;
158 struct vc4_texture_sample_info *texture_samples;
159};
160
161/**
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800162 * _wait_for - magic (register) wait macro
163 *
164 * Does the right thing for modeset paths when run under kdgb or similar atomic
165 * contexts. Note that it's important that we check the condition again after
166 * having timed out, since the timeout could be due to preemption or similar and
167 * we've never had a chance to check the condition before the timeout.
168 */
169#define _wait_for(COND, MS, W) ({ \
170 unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \
171 int ret__ = 0; \
172 while (!(COND)) { \
173 if (time_after(jiffies, timeout__)) { \
174 if (!(COND)) \
175 ret__ = -ETIMEDOUT; \
176 break; \
177 } \
178 if (W && drm_can_sleep()) { \
179 msleep(W); \
180 } else { \
181 cpu_relax(); \
182 } \
183 } \
184 ret__; \
185})
186
187#define wait_for(COND, MS) _wait_for(COND, MS, 1)
188
189/* vc4_bo.c */
Eric Anholtc826a6e2015-10-09 20:25:07 -0700190struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800191void vc4_free_object(struct drm_gem_object *gem_obj);
Eric Anholtc826a6e2015-10-09 20:25:07 -0700192struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size,
193 bool from_cache);
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800194int vc4_dumb_create(struct drm_file *file_priv,
195 struct drm_device *dev,
196 struct drm_mode_create_dumb *args);
197struct dma_buf *vc4_prime_export(struct drm_device *dev,
198 struct drm_gem_object *obj, int flags);
Eric Anholtd5bc60f2015-01-18 09:33:17 +1300199int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
200 struct drm_file *file_priv);
Eric Anholt463873d2015-11-30 11:41:40 -0800201int vc4_create_shader_bo_ioctl(struct drm_device *dev, void *data,
202 struct drm_file *file_priv);
Eric Anholtd5bc60f2015-01-18 09:33:17 +1300203int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
204 struct drm_file *file_priv);
Eric Anholt463873d2015-11-30 11:41:40 -0800205int vc4_mmap(struct file *filp, struct vm_area_struct *vma);
206int vc4_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
207void *vc4_prime_vmap(struct drm_gem_object *obj);
Eric Anholtc826a6e2015-10-09 20:25:07 -0700208void vc4_bo_cache_init(struct drm_device *dev);
209void vc4_bo_cache_destroy(struct drm_device *dev);
210int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800211
212/* vc4_crtc.c */
213extern struct platform_driver vc4_crtc_driver;
Dave Airlie1f437102015-10-22 10:23:31 +1000214int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id);
215void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id);
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800216void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
217int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
218
219/* vc4_debugfs.c */
220int vc4_debugfs_init(struct drm_minor *minor);
221void vc4_debugfs_cleanup(struct drm_minor *minor);
222
223/* vc4_drv.c */
224void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
225
226/* vc4_hdmi.c */
227extern struct platform_driver vc4_hdmi_driver;
228int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);
229
230/* vc4_hvs.c */
231extern struct platform_driver vc4_hvs_driver;
232void vc4_hvs_dump_state(struct drm_device *dev);
233int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused);
234
235/* vc4_kms.c */
236int vc4_kms_load(struct drm_device *dev);
237
238/* vc4_plane.c */
239struct drm_plane *vc4_plane_init(struct drm_device *dev,
240 enum drm_plane_type type);
241u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
242u32 vc4_plane_dlist_size(struct drm_plane_state *state);
Eric Anholt463873d2015-11-30 11:41:40 -0800243
244/* vc4_validate_shader.c */
245struct vc4_validated_shader_info *
246vc4_validate_shader(struct drm_gem_cma_object *shader_obj);