msm_drv.h 15.4 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

65 66
#define FRAC_16_16(mult, div)    (((mult) << 16) / (div))

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

73 74 75 76 77 78 79
enum msm_mdp_plane_property {
	PLANE_PROP_ZPOS,
	PLANE_PROP_ALPHA,
	PLANE_PROP_PREMULTIPLIED,
	PLANE_PROP_MAX_NUM
};

80
struct msm_vblank_ctrl {
81
	struct kthread_work work;
82 83 84 85
	struct list_head event_list;
	spinlock_t lock;
};

86
#define MSM_GPU_MAX_RINGS 4
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 150 151
#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;
};
152

153 154
struct msm_drm_private {

R
Rob Clark 已提交
155 156
	struct drm_device *dev;

157 158
	struct msm_kms *kms;

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

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

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

170 171 172 173 174 175
	/* 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;

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

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

183 184
	struct drm_fb_helper *fbdev;

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

189 190 191 192 193
	/* list of GEM objects: */
	struct list_head inactive_list;

	struct workqueue_struct *wq;

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

197
	unsigned int num_crtcs;
198
	struct drm_crtc *crtcs[MAX_CRTCS];
199

200 201 202
	struct msm_drm_thread disp_thread[MAX_CRTCS];
	struct msm_drm_thread event_thread[MAX_CRTCS];

203
	unsigned int num_encoders;
204
	struct drm_encoder *encoders[MAX_ENCODERS];
205

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

209
	unsigned int num_connectors;
210
	struct drm_connector *connectors[MAX_CONNECTORS];
211

212 213 214
	/* Properties */
	struct drm_property *plane_property[PLANE_PROP_MAX_NUM];

215 216 217 218 219 220 221 222
	/* 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;
223
		spinlock_t lock; /* Protects drm_mm node allocation/removal */
224
	} vram;
225

R
Rob Clark 已提交
226
	struct notifier_block vmap_notifier;
R
Rob Clark 已提交
227 228
	struct shrinker shrinker;

229
	struct msm_vblank_ctrl vblank_ctrl;
230
	struct drm_atomic_state *pm_state;
231 232 233 234 235 236
};

struct msm_format {
	uint32_t pixel_format;
};

237 238
int msm_atomic_prepare_fb(struct drm_plane *plane,
			  struct drm_plane_state *new_state);
239
void msm_atomic_commit_tail(struct drm_atomic_state *state);
R
Rob Clark 已提交
240 241 242
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 已提交
243

244 245
int msm_gem_init_vma(struct msm_gem_address_space *aspace,
		struct msm_gem_vma *vma, int npages);
246 247
void msm_gem_purge_vma(struct msm_gem_address_space *aspace,
		struct msm_gem_vma *vma);
248
void msm_gem_unmap_vma(struct msm_gem_address_space *aspace,
249
		struct msm_gem_vma *vma);
250 251
int msm_gem_map_vma(struct msm_gem_address_space *aspace,
		struct msm_gem_vma *vma, struct sg_table *sgt, int npages);
252 253
void msm_gem_close_vma(struct msm_gem_address_space *aspace,
		struct msm_gem_vma *vma);
254

255 256
void msm_gem_address_space_put(struct msm_gem_address_space *aspace);

257 258 259
struct msm_gem_address_space *
msm_gem_address_space_create(struct device *dev, struct iommu_domain *domain,
		const char *name);
260

261 262 263
int msm_register_mmu(struct drm_device *dev, struct msm_mmu *mmu);
void msm_unregister_mmu(struct drm_device *dev, struct msm_mmu *mmu);

264
void msm_gem_submit_free(struct msm_gem_submit *submit);
R
Rob Clark 已提交
265 266 267
int msm_ioctl_gem_submit(struct drm_device *dev, void *data,
		struct drm_file *file);

R
Rob Clark 已提交
268 269 270
void msm_gem_shrinker_init(struct drm_device *dev);
void msm_gem_shrinker_cleanup(struct drm_device *dev);

271 272
int msm_gem_mmap_obj(struct drm_gem_object *obj,
			struct vm_area_struct *vma);
273
int msm_gem_mmap(struct file *filp, struct vm_area_struct *vma);
274
vm_fault_t msm_gem_fault(struct vm_fault *vmf);
275
uint64_t msm_gem_mmap_offset(struct drm_gem_object *obj);
276 277
int msm_gem_get_iova(struct drm_gem_object *obj,
		struct msm_gem_address_space *aspace, uint64_t *iova);
278 279
int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
		struct msm_gem_address_space *aspace, uint64_t *iova);
280 281
uint64_t msm_gem_iova(struct drm_gem_object *obj,
		struct msm_gem_address_space *aspace);
282 283
void msm_gem_unpin_iova(struct drm_gem_object *obj,
		struct msm_gem_address_space *aspace);
R
Rob Clark 已提交
284 285
struct page **msm_gem_get_pages(struct drm_gem_object *obj);
void msm_gem_put_pages(struct drm_gem_object *obj);
286 287 288 289
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 已提交
290 291 292
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);
293
int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma);
294
struct reservation_object *msm_gem_prime_res_obj(struct drm_gem_object *obj);
R
Rob Clark 已提交
295
struct drm_gem_object *msm_gem_prime_import_sg_table(struct drm_device *dev,
296
		struct dma_buf_attachment *attach, struct sg_table *sg);
R
Rob Clark 已提交
297 298
int msm_gem_prime_pin(struct drm_gem_object *obj);
void msm_gem_prime_unpin(struct drm_gem_object *obj);
299
void *msm_gem_get_vaddr(struct drm_gem_object *obj);
300
void *msm_gem_get_vaddr_active(struct drm_gem_object *obj);
301
void msm_gem_put_vaddr(struct drm_gem_object *obj);
R
Rob Clark 已提交
302
int msm_gem_madvise(struct drm_gem_object *obj, unsigned madv);
R
Rob Clark 已提交
303 304
int msm_gem_sync_object(struct drm_gem_object *obj,
		struct msm_fence_context *fctx, bool exclusive);
R
Rob Clark 已提交
305
void msm_gem_move_to_active(struct drm_gem_object *obj,
306
		struct msm_gpu *gpu, bool exclusive, struct dma_fence *fence);
R
Rob Clark 已提交
307
void msm_gem_move_to_inactive(struct drm_gem_object *obj);
R
Rob Clark 已提交
308
int msm_gem_cpu_prep(struct drm_gem_object *obj, uint32_t op, ktime_t *timeout);
R
Rob Clark 已提交
309
int msm_gem_cpu_fini(struct drm_gem_object *obj);
310 311 312 313 314
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);
315 316
struct drm_gem_object *msm_gem_new_locked(struct drm_device *dev,
		uint32_t size, uint32_t flags);
317 318 319 320 321 322
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);
323 324
void msm_gem_kernel_put(struct drm_gem_object *bo,
		struct msm_gem_address_space *aspace, bool locked);
R
Rob Clark 已提交
325
struct drm_gem_object *msm_gem_import(struct drm_device *dev,
326
		struct dma_buf *dmabuf, struct sg_table *sgt);
327

328 329 330 331 332 333
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);
334 335 336
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,
337
		struct drm_file *file, const struct drm_mode_fb_cmd2 *mode_cmd);
338 339
struct drm_framebuffer * msm_alloc_stolen_fb(struct drm_device *dev,
		int w, int h, int p, uint32_t format);
340 341

struct drm_fb_helper *msm_fbdev_init(struct drm_device *dev);
342
void msm_fbdev_free(struct drm_device *dev);
343

344
struct hdmi;
A
Arnd Bergmann 已提交
345
int msm_hdmi_modeset_init(struct hdmi *hdmi, struct drm_device *dev,
R
Rob Clark 已提交
346
		struct drm_encoder *encoder);
A
Arnd Bergmann 已提交
347 348
void __init msm_hdmi_register(void);
void __exit msm_hdmi_unregister(void);
349

350 351 352 353 354 355
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);

356 357 358 359 360
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,
361
			 struct drm_encoder *encoder);
362 363 364 365 366 367 368 369
#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,
370 371
				       struct drm_device *dev,
				       struct drm_encoder *encoder)
372 373 374 375 376
{
	return -EINVAL;
}
#endif

377 378
void __init msm_mdp_register(void);
void __exit msm_mdp_unregister(void);
379 380
void __init msm_dpu_register(void);
void __exit msm_dpu_unregister(void);
381

382 383 384 385
#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 已提交
386 387
int msm_debugfs_late_init(struct drm_device *dev);
int msm_rd_debugfs_init(struct drm_minor *minor);
388
void msm_rd_debugfs_cleanup(struct msm_drm_private *priv);
389 390
void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
		const char *fmt, ...);
R
Rob Clark 已提交
391
int msm_perf_debugfs_init(struct drm_minor *minor);
392
void msm_perf_debugfs_cleanup(struct msm_drm_private *priv);
R
Rob Clark 已提交
393 394
#else
static inline int msm_debugfs_late_init(struct drm_device *dev) { return 0; }
395 396
static inline void msm_rd_dump_submit(struct msm_rd_state *rd, struct msm_gem_submit *submit,
		const char *fmt, ...) {}
397 398
static inline void msm_rd_debugfs_cleanup(struct msm_drm_private *priv) {}
static inline void msm_perf_debugfs_cleanup(struct msm_drm_private *priv) {}
399 400
#endif

401
struct clk *msm_clk_get(struct platform_device *pdev, const char *name);
402 403 404 405
int msm_clk_bulk_get(struct device *dev, struct clk_bulk_data **bulk);

struct clk *msm_clk_bulk_get_clock(struct clk_bulk_data *bulk, int count,
	const char *name);
406 407 408 409 410
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);

411
struct msm_gpu_submitqueue;
412
int msm_submitqueue_init(struct drm_device *drm, struct msm_file_private *ctx);
413 414
struct msm_gpu_submitqueue *msm_submitqueue_get(struct msm_file_private *ctx,
		u32 id);
415 416
int msm_submitqueue_create(struct drm_device *drm, struct msm_file_private *ctx,
		u32 prio, u32 flags, u32 *id);
417 418 419 420 421 422
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 已提交
423 424
#define DBG(fmt, ...) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
#define VERB(fmt, ...) if (0) DRM_DEBUG_DRIVER(fmt"\n", ##__VA_ARGS__)
425 426 427 428 429 430 431 432 433 434

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 已提交
435 436 437
#define fui(x)                ({BUG(); 0;})
#define util_float_to_half(x) ({BUG(); 0;})

438 439 440 441 442 443

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

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

444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
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;
}
459 460

#endif /* __MSM_DRV_H__ */