Subversion Repositories Kolibri OS

Rev

Rev 1221 | Rev 1404 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1123 serge 1
/*
2
 * Copyright (c) 2006-2008 Intel Corporation
3
 * Copyright (c) 2007 Dave Airlie 
4
 * Copyright (c) 2008 Red Hat Inc.
5
 *
6
 * DRM core CRTC related functions
7
 *
8
 * Permission to use, copy, modify, distribute, and sell this software and its
9
 * documentation for any purpose is hereby granted without fee, provided that
10
 * the above copyright notice appear in all copies and that both that copyright
11
 * notice and this permission notice appear in supporting documentation, and
12
 * that the name of the copyright holders not be used in advertising or
13
 * publicity pertaining to distribution of the software without specific,
14
 * written prior permission.  The copyright holders make no representations
15
 * about the suitability of this software for any purpose.  It is provided "as
16
 * is" without express or implied warranty.
17
 *
18
 * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
19
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
20
 * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
21
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
22
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
23
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
24
 * OF THIS SOFTWARE.
25
 *
26
 * Authors:
27
 *      Keith Packard
28
 *	Eric Anholt 
29
 *      Dave Airlie 
30
 *      Jesse Barnes 
31
 */
1179 serge 32
#include 
1123 serge 33
#include "drm.h"
34
#include "drmP.h"
35
#include "drm_crtc.h"
36
 
37
struct drm_prop_enum_list {
38
	int type;
39
	char *name;
40
};
41
 
42
/* Avoid boilerplate.  I'm tired of typing. */
43
#define DRM_ENUM_NAME_FN(fnname, list)				\
44
	char *fnname(int val)					\
45
	{							\
46
		int i;						\
47
		for (i = 0; i < ARRAY_SIZE(list); i++) {	\
48
			if (list[i].type == val)		\
49
				return list[i].name;		\
50
		}						\
51
		return "(unknown)";				\
52
	}
53
 
54
/*
55
 * Global properties
56
 */
57
static struct drm_prop_enum_list drm_dpms_enum_list[] =
58
{	{ DRM_MODE_DPMS_ON, "On" },
59
	{ DRM_MODE_DPMS_STANDBY, "Standby" },
60
	{ DRM_MODE_DPMS_SUSPEND, "Suspend" },
61
	{ DRM_MODE_DPMS_OFF, "Off" }
62
};
63
 
64
DRM_ENUM_NAME_FN(drm_get_dpms_name, drm_dpms_enum_list)
65
 
66
/*
67
 * Optional properties
68
 */
69
static struct drm_prop_enum_list drm_scaling_mode_enum_list[] =
70
{
1179 serge 71
	{ DRM_MODE_SCALE_NONE, "None" },
72
	{ DRM_MODE_SCALE_FULLSCREEN, "Full" },
73
	{ DRM_MODE_SCALE_CENTER, "Center" },
74
	{ DRM_MODE_SCALE_ASPECT, "Full aspect" },
1123 serge 75
};
76
 
77
static struct drm_prop_enum_list drm_dithering_mode_enum_list[] =
78
{
79
	{ DRM_MODE_DITHERING_OFF, "Off" },
80
	{ DRM_MODE_DITHERING_ON, "On" },
81
};
82
 
83
/*
84
 * Non-global properties, but "required" for certain connectors.
85
 */
86
static struct drm_prop_enum_list drm_dvi_i_select_enum_list[] =
87
{
88
	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
89
	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
90
	{ DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
91
};
92
 
93
DRM_ENUM_NAME_FN(drm_get_dvi_i_select_name, drm_dvi_i_select_enum_list)
94
 
95
static struct drm_prop_enum_list drm_dvi_i_subconnector_enum_list[] =
96
{
97
	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
98
	{ DRM_MODE_SUBCONNECTOR_DVID,      "DVI-D"     }, /* DVI-I  */
99
	{ DRM_MODE_SUBCONNECTOR_DVIA,      "DVI-A"     }, /* DVI-I  */
100
};
101
 
102
DRM_ENUM_NAME_FN(drm_get_dvi_i_subconnector_name,
103
		 drm_dvi_i_subconnector_enum_list)
104
 
105
static struct drm_prop_enum_list drm_tv_select_enum_list[] =
106
{
107
	{ DRM_MODE_SUBCONNECTOR_Automatic, "Automatic" }, /* DVI-I and TV-out */
108
	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
109
	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
110
	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
1179 serge 111
	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
1123 serge 112
};
113
 
114
DRM_ENUM_NAME_FN(drm_get_tv_select_name, drm_tv_select_enum_list)
115
 
116
static struct drm_prop_enum_list drm_tv_subconnector_enum_list[] =
117
{
118
	{ DRM_MODE_SUBCONNECTOR_Unknown,   "Unknown"   }, /* DVI-I and TV-out */
119
	{ DRM_MODE_SUBCONNECTOR_Composite, "Composite" }, /* TV-out */
120
	{ DRM_MODE_SUBCONNECTOR_SVIDEO,    "SVIDEO"    }, /* TV-out */
121
	{ DRM_MODE_SUBCONNECTOR_Component, "Component" }, /* TV-out */
1179 serge 122
	{ DRM_MODE_SUBCONNECTOR_SCART,     "SCART"     }, /* TV-out */
1123 serge 123
};
124
 
125
DRM_ENUM_NAME_FN(drm_get_tv_subconnector_name,
126
		 drm_tv_subconnector_enum_list)
127
 
1321 serge 128
static struct drm_prop_enum_list drm_dirty_info_enum_list[] = {
129
	{ DRM_MODE_DIRTY_OFF,      "Off"      },
130
	{ DRM_MODE_DIRTY_ON,       "On"       },
131
	{ DRM_MODE_DIRTY_ANNOTATE, "Annotate" },
132
};
133
 
134
DRM_ENUM_NAME_FN(drm_get_dirty_info_name,
135
		 drm_dirty_info_enum_list)
136
 
1123 serge 137
struct drm_conn_prop_enum_list {
138
	int type;
139
	char *name;
140
	int count;
141
};
142
 
143
/*
144
 * Connector and encoder types.
145
 */
146
static struct drm_conn_prop_enum_list drm_connector_enum_list[] =
147
{	{ DRM_MODE_CONNECTOR_Unknown, "Unknown", 0 },
148
	{ DRM_MODE_CONNECTOR_VGA, "VGA", 0 },
149
	{ DRM_MODE_CONNECTOR_DVII, "DVI-I", 0 },
150
	{ DRM_MODE_CONNECTOR_DVID, "DVI-D", 0 },
151
	{ DRM_MODE_CONNECTOR_DVIA, "DVI-A", 0 },
152
	{ DRM_MODE_CONNECTOR_Composite, "Composite", 0 },
153
	{ DRM_MODE_CONNECTOR_SVIDEO, "SVIDEO", 0 },
154
	{ DRM_MODE_CONNECTOR_LVDS, "LVDS", 0 },
155
	{ DRM_MODE_CONNECTOR_Component, "Component", 0 },
156
	{ DRM_MODE_CONNECTOR_9PinDIN, "9-pin DIN", 0 },
157
	{ DRM_MODE_CONNECTOR_DisplayPort, "DisplayPort", 0 },
158
	{ DRM_MODE_CONNECTOR_HDMIA, "HDMI Type A", 0 },
159
	{ DRM_MODE_CONNECTOR_HDMIB, "HDMI Type B", 0 },
1179 serge 160
	{ DRM_MODE_CONNECTOR_TV, "TV", 0 },
1123 serge 161
};
162
 
163
static struct drm_prop_enum_list drm_encoder_enum_list[] =
164
{	{ DRM_MODE_ENCODER_NONE, "None" },
165
	{ DRM_MODE_ENCODER_DAC, "DAC" },
166
	{ DRM_MODE_ENCODER_TMDS, "TMDS" },
167
	{ DRM_MODE_ENCODER_LVDS, "LVDS" },
168
	{ DRM_MODE_ENCODER_TVDAC, "TV" },
169
};
170
 
171
char *drm_get_encoder_name(struct drm_encoder *encoder)
172
{
173
	static char buf[32];
174
 
175
	snprintf(buf, 32, "%s-%d",
176
		 drm_encoder_enum_list[encoder->encoder_type].name,
177
		 encoder->base.id);
178
	return buf;
179
}
1179 serge 180
EXPORT_SYMBOL(drm_get_encoder_name);
1123 serge 181
 
182
char *drm_get_connector_name(struct drm_connector *connector)
183
{
184
	static char buf[32];
185
 
186
	snprintf(buf, 32, "%s-%d",
187
		 drm_connector_enum_list[connector->connector_type].name,
188
		 connector->connector_type_id);
189
	return buf;
190
}
191
EXPORT_SYMBOL(drm_get_connector_name);
192
 
193
char *drm_get_connector_status_name(enum drm_connector_status status)
194
{
195
	if (status == connector_status_connected)
196
		return "connected";
197
	else if (status == connector_status_disconnected)
198
		return "disconnected";
199
	else
200
		return "unknown";
201
}
202
 
203
/**
204
 * drm_mode_object_get - allocate a new identifier
205
 * @dev: DRM device
206
 * @ptr: object pointer, used to generate unique ID
207
 * @type: object type
208
 *
209
 * LOCKING:
210
 *
211
 * Create a unique identifier based on @ptr in @dev's identifier space.  Used
212
 * for tracking modes, CRTCs and connectors.
213
 *
214
 * RETURNS:
215
 * New unique (relative to other objects in @dev) integer identifier for the
216
 * object.
217
 */
218
static int drm_mode_object_get(struct drm_device *dev,
219
			       struct drm_mode_object *obj, uint32_t obj_type)
220
{
221
	int new_id = 0;
222
	int ret;
223
 
224
again:
225
	if (idr_pre_get(&dev->mode_config.crtc_idr, GFP_KERNEL) == 0) {
226
		DRM_ERROR("Ran out memory getting a mode number\n");
227
		return -EINVAL;
228
	}
229
 
1179 serge 230
	mutex_lock(&dev->mode_config.idr_mutex);
1123 serge 231
	ret = idr_get_new_above(&dev->mode_config.crtc_idr, obj, 1, &new_id);
1179 serge 232
	mutex_unlock(&dev->mode_config.idr_mutex);
1123 serge 233
	if (ret == -EAGAIN)
1179 serge 234
        goto again;
1123 serge 235
 
236
	obj->id = new_id;
237
	obj->type = obj_type;
1179 serge 238
    return 0;
1123 serge 239
}
240
 
241
/**
242
 * drm_mode_object_put - free an identifer
243
 * @dev: DRM device
244
 * @id: ID to free
245
 *
246
 * LOCKING:
247
 * Caller must hold DRM mode_config lock.
248
 *
249
 * Free @id from @dev's unique identifier pool.
250
 */
251<