summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/sysfb/drm_sysfb_helper.h
blob: cb08a88242cc1365f774b24ca29cda8ef816892a (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
/* SPDX-License-Identifier: GPL-2.0-only */

#ifndef DRM_SYSFB_HELPER_H
#define DRM_SYSFB_HELPER_H

#include <linux/container_of.h>
#include <linux/iosys-map.h>

#include <video/pixel_format.h>

#include <drm/drm_crtc.h>
#include <drm/drm_device.h>
#include <drm/drm_modes.h>

struct drm_format_info;
struct drm_scanout_buffer;
struct screen_info;

/*
 * Input parsing
 */

struct drm_sysfb_format {
	struct pixel_format pixel;
	u32 fourcc;
};

int drm_sysfb_get_validated_int(struct drm_device *dev, const char *name,
				u64 value, u32 max);
int drm_sysfb_get_validated_int0(struct drm_device *dev, const char *name,
				 u64 value, u32 max);

#if defined(CONFIG_SCREEN_INFO)
int drm_sysfb_get_width_si(struct drm_device *dev, const struct screen_info *si);
int drm_sysfb_get_height_si(struct drm_device *dev, const struct screen_info *si);
struct resource *drm_sysfb_get_memory_si(struct drm_device *dev,
					 const struct screen_info *si,
					 struct resource *res);
int drm_sysfb_get_stride_si(struct drm_device *dev, const struct screen_info *si,
			    const struct drm_format_info *format,
			    unsigned int width, unsigned int height, u64 size);
u64 drm_sysfb_get_visible_size_si(struct drm_device *dev, const struct screen_info *si,
				  unsigned int height, unsigned int stride, u64 size);
const struct drm_format_info *drm_sysfb_get_format_si(struct drm_device *dev,
						      const struct drm_sysfb_format *formats,
						      size_t nformats,
						      const struct screen_info *si);
#endif

/*
 * Input parsing
 */

int drm_sysfb_get_validated_int(struct drm_device *dev, const char *name,
				u64 value, u32 max);
int drm_sysfb_get_validated_int0(struct drm_device *dev, const char *name,
				 u64 value, u32 max);

/*
 * Display modes
 */

struct drm_display_mode drm_sysfb_mode(unsigned int width,
				       unsigned int height,
				       unsigned int width_mm,
				       unsigned int height_mm);

/*
 * Device
 */

struct drm_sysfb_device {
	struct drm_device dev;

	const u8 *edid; /* can be NULL */

	/* hardware settings */
	struct drm_display_mode fb_mode;
	const struct drm_format_info *fb_format;
	unsigned int fb_pitch;
	unsigned int fb_gamma_lut_size;

	/* hardware-framebuffer kernel address */
	struct iosys_map fb_addr;
};

static inline struct drm_sysfb_device *to_drm_sysfb_device(struct drm_device *dev)
{
	return container_of(dev, struct drm_sysfb_device, dev);
}

/*
 * Plane
 */

int drm_sysfb_plane_helper_atomic_check(struct drm_plane *plane,
					struct drm_atomic_state *new_state);
void drm_sysfb_plane_helper_atomic_update(struct drm_plane *plane,
					  struct drm_atomic_state *state);
void drm_sysfb_plane_helper_atomic_disable(struct drm_plane *plane,
					   struct drm_atomic_state *state);
int drm_sysfb_plane_helper_get_scanout_buffer(struct drm_plane *plane,
					      struct drm_scanout_buffer *sb);

#define DRM_SYSFB_PLANE_NFORMATS(_num_native) \
	((_num_native) + 1)

#define DRM_SYSFB_PLANE_FORMAT_MODIFIERS \
	DRM_FORMAT_MOD_LINEAR, \
	DRM_FORMAT_MOD_INVALID

#define DRM_SYSFB_PLANE_HELPER_FUNCS \
	DRM_GEM_SHADOW_PLANE_HELPER_FUNCS, \
	.atomic_check = drm_sysfb_plane_helper_atomic_check, \
	.atomic_update = drm_sysfb_plane_helper_atomic_update, \
	.atomic_disable = drm_sysfb_plane_helper_atomic_disable, \
	.get_scanout_buffer = drm_sysfb_plane_helper_get_scanout_buffer

#define DRM_SYSFB_PLANE_FUNCS \
	.update_plane = drm_atomic_helper_update_plane, \
	.disable_plane = drm_atomic_helper_disable_plane, \
	DRM_GEM_SHADOW_PLANE_FUNCS

/*
 * CRTC
 */

struct drm_sysfb_crtc_state {
	struct drm_crtc_state base;

	/* Primary-plane format; required for color mgmt. */
	const struct drm_format_info *format;
};

static inline struct drm_sysfb_crtc_state *
to_drm_sysfb_crtc_state(struct drm_crtc_state *base)
{
	return container_of(base, struct drm_sysfb_crtc_state, base);
}

enum drm_mode_status drm_sysfb_crtc_helper_mode_valid(struct drm_crtc *crtc,
						      const struct drm_display_mode *mode);
int drm_sysfb_crtc_helper_atomic_check(struct drm_crtc *crtc, struct drm_atomic_state *new_state);

#define DRM_SYSFB_CRTC_HELPER_FUNCS \
	.mode_valid = drm_sysfb_crtc_helper_mode_valid, \
	.atomic_check = drm_sysfb_crtc_helper_atomic_check

void drm_sysfb_crtc_reset(struct drm_crtc *crtc);
struct drm_crtc_state *drm_sysfb_crtc_atomic_duplicate_state(struct drm_crtc *crtc);
void drm_sysfb_crtc_atomic_destroy_state(struct drm_crtc *crtc, struct drm_crtc_state *crtc_state);

#define DRM_SYSFB_CRTC_FUNCS \
	.reset = drm_sysfb_crtc_reset, \
	.set_config = drm_atomic_helper_set_config, \
	.page_flip = drm_atomic_helper_page_flip, \
	.atomic_duplicate_state = drm_sysfb_crtc_atomic_duplicate_state, \
	.atomic_destroy_state = drm_sysfb_crtc_atomic_destroy_state

/*
 * Connector
 */

int drm_sysfb_connector_helper_get_modes(struct drm_connector *connector);

#define DRM_SYSFB_CONNECTOR_HELPER_FUNCS \
	.get_modes = drm_sysfb_connector_helper_get_modes

#define DRM_SYSFB_CONNECTOR_FUNCS \
	.reset = drm_atomic_helper_connector_reset, \
	.fill_modes = drm_helper_probe_single_connector_modes, \
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state

/*
 * Mode config
 */

#define DRM_SYSFB_MODE_CONFIG_FUNCS \
	.fb_create = drm_gem_fb_create_with_dirty, \
	.atomic_check = drm_atomic_helper_check, \
	.atomic_commit = drm_atomic_helper_commit

#endif