blob: fddb0a06ed3a415cff2a86d1534c7188f9a7a607 [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 Anholtc8b75bc2015-03-02 13:01:12 -080072};
73
74static inline struct vc4_bo *
75to_vc4_bo(struct drm_gem_object *bo)
76{
77 return (struct vc4_bo *)bo;
78}
79
80struct vc4_hvs {
81 struct platform_device *pdev;
82 void __iomem *regs;
83 void __iomem *dlist;
84};
85
86struct vc4_plane {
87 struct drm_plane base;
88};
89
90static inline struct vc4_plane *
91to_vc4_plane(struct drm_plane *plane)
92{
93 return (struct vc4_plane *)plane;
94}
95
96enum vc4_encoder_type {
97 VC4_ENCODER_TYPE_HDMI,
98 VC4_ENCODER_TYPE_VEC,
99 VC4_ENCODER_TYPE_DSI0,
100 VC4_ENCODER_TYPE_DSI1,
101 VC4_ENCODER_TYPE_SMI,
102 VC4_ENCODER_TYPE_DPI,
103};
104
105struct vc4_encoder {
106 struct drm_encoder base;
107 enum vc4_encoder_type type;
108 u32 clock_select;
109};
110
111static inline struct vc4_encoder *
112to_vc4_encoder(struct drm_encoder *encoder)
113{
114 return container_of(encoder, struct vc4_encoder, base);
115}
116
117#define HVS_READ(offset) readl(vc4->hvs->regs + offset)
118#define HVS_WRITE(offset, val) writel(val, vc4->hvs->regs + offset)
119
120/**
121 * _wait_for - magic (register) wait macro
122 *
123 * Does the right thing for modeset paths when run under kdgb or similar atomic
124 * contexts. Note that it's important that we check the condition again after
125 * having timed out, since the timeout could be due to preemption or similar and
126 * we've never had a chance to check the condition before the timeout.
127 */
128#define _wait_for(COND, MS, W) ({ \
129 unsigned long timeout__ = jiffies + msecs_to_jiffies(MS) + 1; \
130 int ret__ = 0; \
131 while (!(COND)) { \
132 if (time_after(jiffies, timeout__)) { \
133 if (!(COND)) \
134 ret__ = -ETIMEDOUT; \
135 break; \
136 } \
137 if (W && drm_can_sleep()) { \
138 msleep(W); \
139 } else { \
140 cpu_relax(); \
141 } \
142 } \
143 ret__; \
144})
145
146#define wait_for(COND, MS) _wait_for(COND, MS, 1)
147
148/* vc4_bo.c */
Eric Anholtc826a6e2015-10-09 20:25:07 -0700149struct drm_gem_object *vc4_create_object(struct drm_device *dev, size_t size);
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800150void vc4_free_object(struct drm_gem_object *gem_obj);
Eric Anholtc826a6e2015-10-09 20:25:07 -0700151struct vc4_bo *vc4_bo_create(struct drm_device *dev, size_t size,
152 bool from_cache);
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800153int vc4_dumb_create(struct drm_file *file_priv,
154 struct drm_device *dev,
155 struct drm_mode_create_dumb *args);
156struct dma_buf *vc4_prime_export(struct drm_device *dev,
157 struct drm_gem_object *obj, int flags);
Eric Anholtd5bc60f2015-01-18 09:33:17 +1300158int vc4_create_bo_ioctl(struct drm_device *dev, void *data,
159 struct drm_file *file_priv);
160int vc4_mmap_bo_ioctl(struct drm_device *dev, void *data,
161 struct drm_file *file_priv);
Eric Anholtc826a6e2015-10-09 20:25:07 -0700162void vc4_bo_cache_init(struct drm_device *dev);
163void vc4_bo_cache_destroy(struct drm_device *dev);
164int vc4_bo_stats_debugfs(struct seq_file *m, void *arg);
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800165
166/* vc4_crtc.c */
167extern struct platform_driver vc4_crtc_driver;
Dave Airlie1f437102015-10-22 10:23:31 +1000168int vc4_enable_vblank(struct drm_device *dev, unsigned int crtc_id);
169void vc4_disable_vblank(struct drm_device *dev, unsigned int crtc_id);
Eric Anholtc8b75bc2015-03-02 13:01:12 -0800170void vc4_cancel_page_flip(struct drm_crtc *crtc, struct drm_file *file);
171int vc4_crtc_debugfs_regs(struct seq_file *m, void *arg);
172
173/* vc4_debugfs.c */
174int vc4_debugfs_init(struct drm_minor *minor);
175void vc4_debugfs_cleanup(struct drm_minor *minor);
176
177/* vc4_drv.c */
178void __iomem *vc4_ioremap_regs(struct platform_device *dev, int index);
179
180/* vc4_hdmi.c */
181extern struct platform_driver vc4_hdmi_driver;
182int vc4_hdmi_debugfs_regs(struct seq_file *m, void *unused);
183
184/* vc4_hvs.c */
185extern struct platform_driver vc4_hvs_driver;
186void vc4_hvs_dump_state(struct drm_device *dev);
187int vc4_hvs_debugfs_regs(struct seq_file *m, void *unused);
188
189/* vc4_kms.c */
190int vc4_kms_load(struct drm_device *dev);
191
192/* vc4_plane.c */
193struct drm_plane *vc4_plane_init(struct drm_device *dev,
194 enum drm_plane_type type);
195u32 vc4_plane_write_dlist(struct drm_plane *plane, u32 __iomem *dlist);
196u32 vc4_plane_dlist_size(struct drm_plane_state *state);