summaryrefslogtreecommitdiff
path: root/samsung/exynos_drm_drv.h
blob: 88ea0b8f181ce2dd026214df26ab05c8a8a2a1bb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
/* SPDX-License-Identifier: GPL-2.0-only
 * exynos_drm_drv.h
 *
 * Copyright (c) 2011 Samsung Electronics Co., Ltd.
 * Authors:
 *	Inki Dae <inki.dae@samsung.com>
 *	Joonyoung Shim <jy0922.shim@samsung.com>
 *	Seung-Woo Kim <sw0312.kim@samsung.com>
 *
 * This program is free software; you can redistribute  it and/or modify it
 * under  the terms of  the GNU General  Public License as published by the
 * Free Software Foundation;  either version 2 of the  License, or (at your
 * option) any later version.
 */

#ifndef _EXYNOS_DRM_DRV_H_
#define _EXYNOS_DRM_DRV_H_

#include <drm/drm_atomic.h>
#include <drm/drm_crtc.h>
#include <drm/drm_plane.h>
#include <drm/drm_property.h>
#include <drm/drm_file.h>
#include <drm/samsung_drm.h>
#include <linux/kthread.h>
#include <linux/module.h>

#include <decon_cal.h>

#include "exynos_drm_connector.h"
#include "exynos_drm_dqe.h"

#define MAX_CRTC	3
#define MAX_PLANE	MAX_WIN_PER_DECON
#define MAX_FB_BUFFER	4

#define DEFAULT_WIN	0


#define to_exynos_crtc(x)	container_of(x, struct exynos_drm_crtc, base)
#define to_exynos_plane(x)	container_of(x, struct exynos_drm_plane, base)

/* this enumerates display type. */
enum exynos_drm_output_type {
	EXYNOS_DISPLAY_TYPE_NONE = 0,
	/* RGB or CPU Interface. */
	EXYNOS_DISPLAY_TYPE_DSI0 = BIT(0),
	EXYNOS_DISPLAY_TYPE_DSI1 = BIT(1),
	EXYNOS_DISPLAY_TYPE_DSI  = EXYNOS_DISPLAY_TYPE_DSI0 |
					EXYNOS_DISPLAY_TYPE_DSI1,
	/* HDMI Interface. */
	EXYNOS_DISPLAY_TYPE_HDMI = BIT(2),
	/* Virtual Display Interface. */
	EXYNOS_DISPLAY_TYPE_VIDI = BIT(3),

	/* DP Interface. */
	EXYNOS_DISPLAY_TYPE_DP0_SST1  = BIT(4),
	EXYNOS_DISPLAY_TYPE_DP0_SST2  = BIT(5),
	EXYNOS_DISPLAY_TYPE_DP0_SST3  = BIT(6),
	EXYNOS_DISPLAY_TYPE_DP0_SST4  = BIT(7),
	EXYNOS_DISPLAY_TYPE_DP1_SST1  = BIT(8),
	EXYNOS_DISPLAY_TYPE_DP1_SST2  = BIT(9),
	EXYNOS_DISPLAY_TYPE_DP1_SST3  = BIT(10),
	EXYNOS_DISPLAY_TYPE_DP1_SST4  = BIT(11),
	EXYNOS_DISPLAY_TYPE_DP0   = EXYNOS_DISPLAY_TYPE_DP0_SST1 |
					EXYNOS_DISPLAY_TYPE_DP0_SST2 |
					EXYNOS_DISPLAY_TYPE_DP0_SST3 |
					EXYNOS_DISPLAY_TYPE_DP0_SST4,
	EXYNOS_DISPLAY_TYPE_DP1   = EXYNOS_DISPLAY_TYPE_DP1_SST1 |
					EXYNOS_DISPLAY_TYPE_DP1_SST2 |
					EXYNOS_DISPLAY_TYPE_DP1_SST3 |
					EXYNOS_DISPLAY_TYPE_DP1_SST4,
};


enum exynos_drm_writeback_type {
	EXYNOS_WB_NONE,
	EXYNOS_WB_CWB,
	EXYNOS_WB_SWB,
};

struct exynos_drm_rect {
	unsigned int x, y;
	unsigned int w, h;
};

struct exynos_hdr_state {
	struct hdr_eotf_lut *eotf_lut;
	struct hdr_oetf_lut *oetf_lut;
	struct hdr_gm_data *gm;
	struct hdr_tm_data *tm;
};

/*
 * Exynos drm plane state structure.
 *
 * @base: plane_state object (contains drm_framebuffer pointer)
 * @src: rectangle of the source image data to be displayed (clipped to
 *       visible part).
 * @crtc: rectangle of the target image position on hardware screen
 *       (clipped to visible part).
 * @h_ratio: horizontal scaling ratio, 16.16 fixed point
 * @v_ratio: vertical scaling ratio, 16.16 fixed point
 *
 * this structure consists plane state data that will be applied to hardware
 * specific overlay info.
 */

struct exynos_drm_plane_state {
	struct drm_plane_state base;
	uint32_t blob_id_restriction;
	uint32_t max_luminance;
	uint32_t min_luminance;
	uint32_t standard;
	uint32_t transfer;
	uint32_t range;
	uint32_t colormap;
	struct exynos_hdr_state hdr_state;
	struct drm_property_blob *eotf_lut;
	struct drm_property_blob *oetf_lut;
	struct drm_property_blob *gm;
	struct drm_property_blob *tm;
	struct drm_property_blob *block;
};

static inline struct exynos_drm_plane_state *
to_exynos_plane_state(const struct drm_plane_state *state)
{
	return container_of(state, struct exynos_drm_plane_state, base);
}

/*
 * Exynos drm common overlay structure.
 *
 * @base: plane object
 * @index: hardware index of the overlay layer
 *
 * this structure is common to exynos SoC and its contents would be copied
 * to hardware specific overlay info.
 */

struct exynos_drm_plane {
	struct drm_plane base;
	unsigned int index;
	struct dentry *debugfs_entry;

	struct {
		struct drm_property *restriction;
		struct drm_property *max_luminance;
		struct drm_property *min_luminance;
		struct drm_property *standard;
		struct drm_property *transfer;
		struct drm_property *range;
		struct drm_property *eotf_lut;
		struct drm_property *oetf_lut;
		struct drm_property *gm;
		struct drm_property *tm;
		struct drm_property *colormap;
		struct drm_property *block;
	} props;
};

#define EXYNOS_DRM_PLANE_CAP_DOUBLE	(1 << 0)
#define EXYNOS_DRM_PLANE_CAP_SCALE	(1 << 1)
#define EXYNOS_DRM_PLANE_CAP_ZPOS	(1 << 2)
#define EXYNOS_DRM_PLANE_CAP_TILE	(1 << 3)
#define EXYNOS_DRM_PLANE_CAP_AFBC	(1 << 4)

/*
 * Exynos DRM plane configuration structure.
 *
 * @zpos: initial z-position of the plane.
 * @type: type of the plane (primary, cursor or overlay).
 * @pixel_formats: supported pixel formats.
 * @num_pixel_formats: number of elements in 'pixel_formats'.
 * @capabilities: supported features (see EXYNOS_DRM_PLANE_CAP_*)
 */

struct exynos_drm_plane_config {
	unsigned int zpos;
	enum drm_plane_type type;
	const uint32_t *pixel_formats;
	unsigned int num_pixel_formats;
	unsigned int capabilities;
};

/*
 * Exynos drm crtc ops
 *
 * @enable: enable the device
 * @disable: disable the device
 * @enable_vblank: specific driver callback for enabling vblank interrupt.
 * @disable_vblank: specific driver callback for disabling vblank interrupt.
 * @mode_valid: specific driver callback for mode validation
 * @atomic_check: validate state
 * @atomic_begin: prepare device to receive an update
 * @atomic_flush: mark the end of device update
 * @update_plane: apply hardware specific overlay data to registers.
 * @disable_plane: disable hardware specific overlay.
 * @te_handler: trigger to transfer video image at the tearing effect
 *	synchronization signal if there is a page flip request.
 * @wait_for_flip_done: wait for active crtc flip to be done
 */
struct exynos_drm_crtc;
struct exynos_drm_crtc_ops {
	void (*enable)(struct exynos_drm_crtc *crtc, struct drm_crtc_state *old_state);
	void (*disable)(struct exynos_drm_crtc *crtc);
	int (*enable_vblank)(struct exynos_drm_crtc *crtc);
	void (*disable_vblank)(struct exynos_drm_crtc *crtc);
	u32 (*get_vblank_counter)(struct exynos_drm_crtc *crtc);
	enum drm_mode_status (*mode_valid)(struct exynos_drm_crtc *crtc,
		const struct drm_display_mode *mode);
	bool (*mode_fixup)(struct exynos_drm_crtc *crtc,
		const struct drm_display_mode *mode,
		struct drm_display_mode *adjusted_mode);
	void (*mode_set)(struct exynos_drm_crtc *crtc,
		const struct drm_display_mode *mode,
		const struct drm_display_mode *adjusted_mode);
	int (*atomic_check)(struct exynos_drm_crtc *crtc,
			    struct drm_crtc_state *state);
	void (*atomic_begin)(struct exynos_drm_crtc *crtc);
	void (*update_plane)(struct exynos_drm_crtc *crtc,
			     struct exynos_drm_plane *plane);
	void (*disable_plane)(struct exynos_drm_crtc *crtc,
			      struct exynos_drm_plane *plane);
	void (*atomic_flush)(struct exynos_drm_crtc *crtc,
			struct drm_crtc_state *old_crtc_state);
	void (*te_handler)(struct exynos_drm_crtc *crtc);
	void (*wait_for_flip_done)(struct exynos_drm_crtc *crtc,
			const struct drm_crtc_state *old_crtc_state,
			const struct drm_crtc_state *new_crtc_state);
};

struct exynos_drm_crtc_state {
	struct drm_crtc_state base;
	uint32_t color_mode;
	uint32_t in_bpc;
	uint32_t force_bpc; /* crtc(DECON) bpc mode */
	uint64_t expected_present_time;
	struct exynos_dqe_state dqe;
	struct drm_property_blob *cgc_lut;
	struct drm_property_blob *disp_dither;
	struct drm_property_blob *cgc_dither;
	struct drm_property_blob *linear_matrix;
	struct drm_property_blob *gamma_matrix;
	struct drm_property_blob *histogram_roi;
	struct drm_property_blob *histogram_weights;
	struct drm_gem_object *cgc_gem;
	enum exynos_drm_writeback_type wb_type;
	u8 seamless_mode_changed : 1;
	/**
	 * @bypass: when in this mode any DPU programming is bypassed but all
	 *          power/regulators are kept enabled
	 */
	u8 bypass : 1;

	/**
	 * @skip_update: if flag is set, most DPU updates should be skipped
	 *               and signaling of commit done should happen immediately
	 */
	u8 skip_update : 1;

	/**
	 * @planes_updated: this flag tracks whether planes were really changed, compared with
	 *                  crtc_state->planes_changed where it may be set if planes were added
	 *                  to atomic state due to any mode set (ex. self refresh change)
	 */
	u8 planes_updated : 1;

	/**
	 * @hibernation_exit: set when crtc is going out of hibernation, serves as
	 *		      potential optimization to avoid full updates
	 */
	u8 hibernation_exit : 1;

	unsigned int reserved_win_mask;
	unsigned int visible_win_mask;
	struct drm_rect partial_region;
	struct drm_property_blob *partial;
	bool needs_reconfigure;
};

static inline struct exynos_drm_crtc_state *
to_exynos_crtc_state(const struct drm_crtc_state *state)
{
	return container_of(state, struct exynos_drm_crtc_state, base);
}

/*
 * Exynos specific crtc structure.
 *
 * @base: crtc object.
 * @possible_type: what can connect connector types
 * @ops: pointer to callbacks for exynos drm specific functionality
 * @ctx: A pointer to the crtc's implementation specific context
 * @pipe_clk: A pointer to the crtc's pipeline clock.
 */
struct exynos_drm_crtc {
	struct drm_crtc			base;
	enum exynos_drm_output_type	possible_type;
	const struct exynos_drm_crtc_ops	*ops;
	void				*ctx;
	struct {
		struct drm_property *color_mode;
		struct drm_property *cgc_lut;
		struct drm_property *disp_dither;
		struct drm_property *cgc_dither;
		struct drm_property *force_bpc;
		struct drm_property *ppc;
		struct drm_property *max_disp_freq;
		struct drm_property *linear_matrix;
		struct drm_property *gamma_matrix;
		struct drm_property *dqe_enabled;
		struct drm_property *histogram_roi;
		struct drm_property *histogram_weights;
		struct drm_property *histogram_threshold;
		struct drm_property *histogram_pos;
		struct drm_property *partial;
		struct drm_property *cgc_lut_fd;
		struct drm_property *expected_present_time;
		struct drm_property *rcd_plane_id;
	} props;
	u8 active_state;
	u32 rcd_plane_mask;
};

struct drm_exynos_file_private {
	u32 dummy;
};

struct exynos_drm_pending_histogram_event {
	struct drm_pending_event base;
	struct exynos_drm_histogram_event event;
};

struct exynos_drm_priv_state {
	struct drm_private_state base;

	struct drm_atomic_state *old_state;
	struct kthread_work commit_work;

	unsigned int available_win_mask;
};

static inline struct exynos_drm_priv_state *
to_exynos_priv_state(const struct drm_private_state *state)
{
	return container_of(state, struct exynos_drm_priv_state, base);
}

/*
 * Exynos drm private structure.
 *
 * @da_start: start address to device address space.
 *	with iommu, device address space starts from this address
 *	otherwise default one.
 * @da_space_size: size of device address space.
 *	if 0 then default value is used for it.
 * @pending: the crtcs that have pending updates to finish
 * @lock: protect access to @pending
 * @wait: wait an atomic commit to finish
 */
struct exynos_drm_private {
	struct drm_device drm;
	struct drm_atomic_state *suspend_state;
	struct device *iommu_client;
	void *mapping;
	bool tui_enabled;
	u32 secured_dpp_mask;

	/* for atomic commit */
	u32			pending;
	spinlock_t		lock;
	wait_queue_head_t	wait;

	struct exynos_drm_connector_properties connector_props;
	struct drm_private_obj	obj;
};

#define drm_to_exynos_dev(dev) container_of(dev, struct exynos_drm_private, drm)

#ifdef CONFIG_DRM_EXYNOS_DPI
struct drm_encoder *exynos_dpi_probe(struct device *dev);
int exynos_dpi_remove(struct drm_encoder *encoder);
int exynos_dpi_bind(struct drm_device *dev, struct drm_encoder *encoder);
#else
static inline struct drm_encoder *
exynos_dpi_probe(struct device *dev) { return NULL; }
static inline int exynos_dpi_remove(struct drm_encoder *encoder)
{
	return 0;
}
static inline int exynos_dpi_bind(struct drm_device *dev,
				  struct drm_encoder *encoder)
{
	return 0;
}
#endif

int exynos_atomic_commit(struct drm_device *dev, struct drm_atomic_state *state,
			 bool nonblock);
int exynos_atomic_check(struct drm_device *dev, struct drm_atomic_state *state);
int exynos_atomic_enter_tui(void);
int exynos_atomic_exit_tui(void);

extern struct platform_driver decon_driver;
extern struct platform_driver dsim_driver;
extern struct platform_driver dp_driver;
extern struct platform_driver dpp_driver;
extern struct platform_driver writeback_driver;
extern struct platform_driver tui_driver;
#endif