msm_drv.h 14.7 KB
Newer Older
1
/*
2
 * Copyright (c) 2016-2018, The Linux Foundation. All rights reserved.
3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
 * Copyright (C) 2013 Red Hat
 * Author: Rob Clark <robdclark@gmail.com>
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 as published by
 * the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along with
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 */

#ifndef __MSM_DRV_H__
#define __MSM_DRV_H__

#include <linux/kernel.h>
#include <linux/clk.h>
#include <linux/cpufreq.h>
#include <linux/module.h>
26
#include <linux/component.h>
27 28 29 30 31 32 33
#include <linux/platform_device.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/slab.h>
#include <linux/list.h>
#include <linux/iommu.h>
#include <linux/types.h>
34
#include <linux/of_graph.h>
35
#include <linux/of_device.h>
36
#include <asm/sizes.h>
37
#include <linux/kthread.h>
38 39

#include <drm/drmP.h>
R
Rob Clark 已提交
40 41
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
42
#include <drm/drm_crtc_helper.h>
R
Rob Clark 已提交
43
#include <drm/drm_plane_helper.h>
44
#include <drm/drm_fb_helper.h>
R
Rob Clark 已提交
45
#include <drm/msm_drm.h>
D
Daniel Vetter 已提交
46
#include <drm/drm_gem.h>
47 48

struct msm_kms;
R
Rob Clark 已提交
49
struct msm_gpu;
50
struct msm_mmu;
51
struct msm_mdss;
R
Rob Clark 已提交
52
struct msm_rd_state;
R
Rob Clark 已提交
53
struct msm_perf_state;
R
Rob Clark 已提交
54
struct msm_gem_submit;
R
Rob Clark 已提交
55
struct msm_fence_context;
56 57
struct msm_gem_address_space;
struct msm_gem_vma;
58

59
#define MAX_CRTCS      8
60
#define MAX_PLANES     20
61 62 63 64
#define MAX_ENCODERS   8
#define MAX_BRIDGES    8
#define MAX_CONNECTORS 8

R
Rob Clark 已提交
65
struct msm_file_private {
66 67 68
	rwlock_t queuelock;
	struct list_head submitqueues;
	int queueid;
R
Rob Clark 已提交
69
};
70

71 72 73 74 75 76 77
enum msm_mdp_plane_property {
	PLANE_PROP_ZPOS,
	PLANE_PROP_ALPHA,
	PLANE_PROP_PREMULTIPLIED,
	PLANE_PROP_MAX_NUM
};

78
struct msm_vblank_ctrl {
79
	struct kthread_work work;
80 81 82 83
	struct list_head event_list;
	spinlock_t lock;
};

84
#define MSM_GPU_MAX_RINGS 4
85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
#define MAX_H_TILES_PER_DISPLAY 2

/**
 * enum msm_display_caps - features/capabilities supported by displays
 * @MSM_DISPLAY_CAP_VID_MODE:           Video or "active" mode supported
 * @MSM_DISPLAY_CAP_CMD_MODE:           Command mode supported
 * @MSM_DISPLAY_CAP_HOT_PLUG:           Hot plug detection supported
 * @MSM_DISPLAY_CAP_EDID:               EDID supported
 */
enum msm_display_caps {
	MSM_DISPLAY_CAP_VID_MODE	= BIT(0),
	MSM_DISPLAY_CAP_CMD_MODE	= BIT(1),
	MSM_DISPLAY_CAP_HOT_PLUG	= BIT(2),
	MSM_DISPLAY_CAP_EDID		= BIT(3),
};

/**
 * enum msm_event_wait - type of HW events to wait for
 * @MSM_ENC_COMMIT_DONE - wait for the driver to flush the registers to HW
 * @MSM_ENC_TX_COMPLETE - wait for the HW to transfer the frame to panel
 * @MSM_ENC_VBLANK - wait for the HW VBLANK event (for driver-internal waiters)
 */
enum msm_event_wait {
	MSM_ENC_COMMIT_DONE = 0,
	MSM_ENC_TX_COMPLETE,
	MSM_ENC_VBLANK,
};

/**
 * struct msm_display_topology - defines a display topology pipeline
 * @num_lm:       number of layer mixers used
 * @num_enc:      number of compression encoder blocks used
 * @num_intf:     number of interfaces the panel is mounted on
 */
struct msm_display_topology {
	u32 num_lm;
	u32 num_enc;
	u32 num_intf;
};

/**
 * struct msm_display_info - defines display properties
 * @intf_type:          DRM_MODE_CONNECTOR_ display type
 * @capabilities:       Bitmask of display flags
 * @num_of_h_tiles:     Number of horizontal tiles in case of split interface
 * @h_tile_instance:    Controller instance used per tile. Number of elements is
 *                      based on num_of_h_tiles
 * @is_te_using_watchdog_timer:  Boolean to indicate watchdog TE is
 *				 used instead of panel TE in cmd mode panels
 */
struct msm_display_info {
	int intf_type;
	uint32_t capabilities;
	uint32_t num_of_h_tiles;
	uint32_t h_tile_instance[MAX_H_TILES_PER_DISPLAY];
	bool is_te_using_watchdog_timer;
};

/* Commit/Event thread specific structure */
struct msm_drm_thread {
	struct drm_device *dev;
	struct task_struct *thread;
	unsigned int crtc_id;
	struct kthread_worker worker;
};
150

151 152
struct msm_drm_private {

R
Rob Clark 已提交
153 154
	struct drm_device *dev;

155 156
	struct msm_kms *kms;

157
	/* subordinate devices, if present: */
R
Rob Clark 已提交
158 159
	struct platform_device *gpu_pdev;

160
	/* top level MDSS wrapper device (for MDP5/DPU only) */
161 162
	struct msm_mdss *mdss;

R
Rob Clark 已提交
163 164 165 166
	/* possibly this should be in the kms component, but it is
	 * shared by both mdp4 and mdp5..
	 */
	struct hdmi *hdmi;
167

168 169 170 171 172 173
	/* eDP is for mdp5 only, but kms has not been created
	 * when edp_bind() and edp_init() are called. Here is the only
	 * place to keep the edp instance.
	 */
	struct msm_edp *edp;

174 175 176
	/* DSI is shared by mdp4 and mdp5 */
	struct msm_dsi *dsi[2];

R
Rob Clark 已提交
177 178 179 180
	/* when we have more than one 'msm_gpu' these need to be an array: */
	struct msm_gpu *gpu;
	struct msm_file_private *lastctx;

181 182
	struct drm_fb_helper *fbdev;

R
Rob Clark 已提交
183 184
	struct msm_rd_state *rd;       /* debugfs to dump all submits */
	struct msm_rd_state *hangrd;   /* debugfs to dump hanging submits */
R
Rob Clark 已提交
185
	struct msm_perf_state *perf;
R
Rob Clark 已提交
186

187 188 189 190 191
	/* list of GEM objects: */
	struct list_head inactive_list;

	struct workqueue_struct *wq;

R
Rob Clark 已提交
192
	unsigned int num_planes;
193
	struct drm_plane *planes[MAX_PLANES];
R
Rob Clark 已提交
194

195
	unsigned int num_crtcs;
196
	struct drm_crtc *crtcs[MAX_CRTCS];
197

198 199 200
	struct msm_drm_thread disp_thread[MAX_CRTCS];
	struct msm_drm_thread event_thread[MAX_CRTCS];

201
	unsigned int num_encoders;
202
	struct drm_encoder *encoders[MAX_ENCODERS];
203

R
Rob Clark 已提交
204
	unsigned int num_bridges;
205
	struct drm_bridge *bridges[MAX_BRIDGES];
R
Rob Clark 已提交
206

207
	unsigned int num_connectors;
208
	struct drm_connector *connectors[MAX_CONNECTORS];
209

210 211 212
	/* Properties */
	struct drm_property *plane_property[PLANE_PROP_MAX_NUM];

213 214 215 216 217 218 219 220
	/* VRAM carveout, used when no IOMMU: */
	struct {
		unsigned long size;
		dma_addr_t paddr;
		/* NOTE: mm managed at the page level, size is in # of pages
		 * and position mm_node->start is in # of pages:
		 */
		struct drm_mm mm;
221
		spinlock_t lock; /* Protects drm_mm node allocation/removal */
222
	} vram;
223

R
Rob Clark 已提交
224
	struct notifier_block vmap_notifier;
R
Rob Clark 已提交
225 226
	struct shrinker shrinker;

227
	struct msm_vblank_ctrl vblank_ctrl;
228
	struct drm_atomic_state *pm_state;
229 230 231 232 233 234
};

struct msm_format {
	uint32_t pixel_format;
};

235 236
int msm_atomic_prepare_fb(struct drm_plane *plane,
			  struct drm_plane_state *new_state);
237
void msm_atomic_commit_tail(struct drm_atomic_state *state);
R
Rob Clark 已提交
238 239 240
struct drm_atomic_state *msm_atomic_state_alloc(struct drm_device *dev);
void msm_atomic_state_clear(struct drm_atomic_state *state);
void msm_atomic_state_free(struct drm_atomic_state *state);
R
Rob Clark 已提交
241

242 243 244 245 246
void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
		struct msm_gem_vma *vma, struct sg_table *sgt);
int msm_gem_map_vma(struct msm_gem_address_space *aspace,
		struct msm_gem_vma *vma, struct sg_table *sgt, int npages);

247 248
void msm_gem_address_space_put(struct msm_gem_address_space *aspace);

249 250 251
struct msm_gem_address_space *
msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
		const char *name);
252

253 254 255
int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu);
void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu);

256
void msm_gem_submit_free(struct msm_gem_submit *submit);
R
Rob Clark 已提交
257 258 259
int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
		struct drm_file *file);

R
Rob Clark 已提交
260 261 262
void msm_gem_shrinker_init(struct drm_device *dev);
void msm_gem_shrinker_cleanup(struct drm_device *dev);

263 264
int msm_gem_mmap_obj(struct drm_gem_object *obj,
			struct vm_area_struct *vma);
265
int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
266
int msm_gem_fault(struct vm_fault *vmf);
267
uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
268 269 270 271
int msm_gem_get_iova(struct drm_gem_object *obj,
		struct msm_gem_address_space *aspace, uint64_t *iova);
uint64_t msm_gem_iova(struct drm_gem_object *obj,
		struct msm_gem_address_space *aspace);
R
Rob Clark 已提交
272 273
struct page **msm_gem_get_pages(struct drm_gem_object *obj);
void msm_gem_put_pages(struct drm_gem_object *obj);
274 275
void msm_gem_put_iova(struct drm_gem_object *obj,
		struct msm_gem_address_space *aspace);
276 277 278 279
int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
		struct drm_mode_create_dumb *args);
int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
		uint32_t handle, uint64_t *offset);
R
Rob Clark 已提交
280 281 282
struct sg_table *msm_gem_prime_get_sg_table(struct drm_gem_object *obj);
void *msm_gem_prime_vmap(struct drm_gem_object *obj);
void msm_gem_prime_vunmap(struct drm_gem_object *obj, void *vaddr);
283
int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
284
struct reservation_object *msm_gem_prime_res_obj(struct drm_gem_object *obj);
R
Rob Clark 已提交
285
struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
286
		struct dma_buf_attachment *attach, struct sg_table *sg);
R
Rob Clark 已提交
287 288
int msm_gem_prime_pin(struct drm_gem_object *obj);
void msm_gem_prime_unpin(struct drm_gem_object *obj);
289
void *msm_gem_get_vaddr(struct drm_gem_object *obj);
290
void *msm_gem_get_vaddr_active(struct drm_gem_object *obj);
291
void msm_gem_put_vaddr(struct drm_gem_object *obj);
R
Rob Clark 已提交
292
int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv);
R
Rob Clark 已提交
293 294
int msm_gem_sync_object(struct drm_gem_object *obj,
		struct msm_fence_context *fctx, bool exclusive);
R
Rob Clark 已提交
295
void msm_gem_move_to_active(struct drm_gem_object *obj,
296
		struct msm_gpu *gpu, bool exclusive, struct dma_fence *fence);
R
Rob Clark 已提交
297
void msm_gem_move_to_inactive(struct drm_gem_object *obj);
R
Rob Clark 已提交
298
int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout);
R
Rob Clark 已提交
299
int msm_gem_cpu_fini(struct drm_gem_object *obj);
300 301 302 303 304
void msm_gem_free_object(struct drm_gem_object *obj);
int msm_gem_new_handle(struct drm_device *dev, struct drm_file *file,
		uint32_t size, uint32_t flags, uint32_t *handle);
struct drm_gem_object *msm_gem_new(struct drm_device *dev,
		uint32_t size, uint32_t flags);
305 306
struct drm_gem_object *msm_gem_new_locked(struct drm_device *dev,
		uint32_t size, uint32_t flags);
307 308 309 310 311 312
void *msm_gem_kernel_new(struct drm_device *dev, uint32_t size,
		uint32_t flags, struct msm_gem_address_space *aspace,
		struct drm_gem_object **bo, uint64_t *iova);
void *msm_gem_kernel_new_locked(struct drm_device *dev, uint32_t size,
		uint32_t flags, struct msm_gem_address_space *aspace,
		struct drm_gem_object **bo, uint64_t *iova);
R
Rob Clark 已提交
313
struct drm_gem_object *msm_gem_import(struct drm_device *dev,
314
		struct dma_buf *dmabuf, struct sg_table *sgt);
315

316 317 318 319 320 321
int msm_framebuffer_prepare(struct drm_framebuffer *fb,
		struct msm_gem_address_space *aspace);
void msm_framebuffer_cleanup(struct drm_framebuffer *fb,
		struct msm_gem_address_space *aspace);
uint32_t msm_framebuffer_iova(struct drm_framebuffer *fb,
		struct msm_gem_address_space *aspace, int plane);
322 323 324
struct drm_gem_object *msm_framebuffer_bo(struct drm_framebuffer *fb, int plane);
const struct msm_format *msm_framebuffer_format(struct drm_framebuffer *fb);
struct drm_framebuffer *msm_framebuffer_create(struct drm_device *dev,
325
		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
326 327
struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
		int w, int h, int p, uint32_t format);
328 329

struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
330
void msm_fbdev_free(struct drm_device *dev);
331

332
struct hdmi;
A
Arnd Bergmann 已提交
333
int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
R
Rob Clark 已提交
334
		struct drm_encoder *encoder);
A
Arnd Bergmann 已提交
335 336
void __init msm_hdmi_register(void);
void __exit msm_hdmi_unregister(void);
337

338 339 340 341 342 343
struct msm_edp;
void __init msm_edp_register(void);
void __exit msm_edp_unregister(void);
int msm_edp_modeset_init(struct msm_edp *edp, struct drm_device *dev,
		struct drm_encoder *encoder);

344 345 346 347 348
struct msm_dsi;
#ifdef CONFIG_DRM_MSM_DSI
void __init msm_dsi_register(void);
void __exit msm_dsi_unregister(void);
int msm_dsi_modeset_init(struct msm_dsi *msm_dsi, struct drm_device *dev,
349
			 struct drm_encoder *encoder);
350 351 352 353 354 355 356 357
#else
static inline void __init msm_dsi_register(void)
{
}
static inline void __exit msm_dsi_unregister(void)
{
}
static inline int msm_dsi_modeset_init(struct msm_dsi *msm_dsi,
358 359
				       struct drm_device *dev,
				       struct drm_encoder *encoder)
360 361 362 363 364
{
	return -EINVAL;
}
#endif

365 366
void __init msm_mdp_register(void);
void __exit msm_mdp_unregister(void);
367 368
void __init msm_dpu_register(void);
void __exit msm_dpu_unregister(void);
369

370 371 372 373
#ifdef CONFIG_DEBUG_FS
void msm_gem_describe(struct drm_gem_object *obj, struct seq_file *m);
void msm_gem_describe_objects(struct list_head *list, struct seq_file *m);
void msm_framebuffer_describe(struct drm_framebuffer *fb, struct seq_file *m);
R
Rob Clark 已提交
374 375
int msm_debugfs_late_init(struct drm_device *dev);
int msm_rd_debugfs_init(struct drm_minor *minor);
376
void msm_rd_debugfs_cleanup(struct msm_drm_private *priv);
377 378
void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
		const char *fmt, ...);
R
Rob Clark 已提交
379
int msm_perf_debugfs_init(struct drm_minor *minor);
380
void msm_perf_debugfs_cleanup(struct msm_drm_private *priv);
R
Rob Clark 已提交
381 382
#else
static inline int msm_debugfs_late_init(struct drm_device *dev) { return 0; }
383 384
static inline void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
		const char *fmt, ...) {}
385 386
static inline void msm_rd_debugfs_cleanup(struct msm_drm_private *priv) {}
static inline void msm_perf_debugfs_cleanup(struct msm_drm_private *priv) {}
387 388
#endif

389
struct clk *msm_clk_get(struct platform_device *pdev, const char *name);
390 391 392 393 394
void __iomem *msm_ioremap(struct platform_device *pdev, const char *name,
		const char *dbgname);
void msm_writel(u32 data, void __iomem *addr);
u32 msm_readl(const void __iomem *addr);

395
struct msm_gpu_submitqueue;
396
int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
397 398
struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
		u32 id);
399 400
int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx,
		u32 prio, u32 flags, u32 *id);
401 402 403 404 405 406
int msm_submitqueue_remove(struct msm_file_private *ctx, u32 id);
void msm_submitqueue_close(struct msm_file_private *ctx);

void msm_submitqueue_destroy(struct kref *kref);


R
Rob Clark 已提交
407 408
#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
409 410 411 412 413 414 415 416 417 418

static inline int align_pitch(int width, int bpp)
{
	int bytespp = (bpp + 7) / 8;
	/* adreno needs pitch aligned to 32 pixels: */
	return bytespp * ALIGN(width, 32);
}

/* for the generated headers: */
#define INVALID_IDX(idx) ({BUG(); 0;})
R
Rob Clark 已提交
419 420 421
#define fui(x)                ({BUG(); 0;})
#define util_float_to_half(x) ({BUG(); 0;})

422 423 424 425 426 427

#define FIELD(val, name) (((val) & name ## __MASK) >> name ## __SHIFT)

/* for conditionally setting boolean flag(s): */
#define COND(bool, val) ((bool) ? (val) : 0)

428 429 430 431 432 433 434 435 436 437 438 439 440 441 442
static inline unsigned long timeout_to_jiffies(const ktime_t *timeout)
{
	ktime_t now = ktime_get();
	unsigned long remaining_jiffies;

	if (ktime_compare(*timeout, now) < 0) {
		remaining_jiffies = 0;
	} else {
		ktime_t rem = ktime_sub(*timeout, now);
		struct timespec ts = ktime_to_timespec(rem);
		remaining_jiffies = timespec_to_jiffies(&ts);
	}

	return remaining_jiffies;
}
443 444

#endif /* __MSM_DRV_H__ */