2 *-----------------------------------------------------------------------------
5 *-----------------------------------------------------------------------------
6 * Copyright (c) 2002-2010, Intel Corporation.
8 * Permission is hereby granted, free of charge, to any person obtaining a copy
9 * of this software and associated documentation files (the "Software"), to deal
10 * in the Software without restriction, including without limitation the rights
11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 * copies of the Software, and to permit persons to whom the Software is
13 * furnished to do so, subject to the following conditions:
15 * The above copyright notice and this permission notice shall be included in
16 * all copies or substantial portions of the Software.
18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26 *-----------------------------------------------------------------------------
28 * The main part of the kernel module. This part gets everything going and
29 * connected, and then the rest can function.
30 *-----------------------------------------------------------------------------
33 #define MODULE_NAME hal.oal
37 #include <drm/drm_crtc.h>
38 #include <drm/drm_crtc_helper.h>
39 #include <linux/version.h>
40 #include <linux/device.h>
41 #include <drm/drm_pciids.h>
43 #include "drm_emgd_private.h"
44 #include "user_config.h"
49 #include "mode_dispatch.h"
50 #include "igd_debug.h"
51 #include "splash_screen.h"
54 * Imagination includes.
56 #include <img_types.h>
58 #include <pvr_drm_shared.h>
59 #include <pvr_bridge.h>
61 #include <sysconfig.h>
63 #include <linux/version.h>
64 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,2,0))
65 #include <linux/module.h>
66 #include <linux/export.h>
68 /* For Buffer Class of Texture Stream*/
69 /* pvr/services4/3rdparty/emgd_bufferclass/emgd_bc_linux.c */
70 extern int emgd_bc_ts_init(void);
71 extern int emgd_bc_ts_uninit(void);
73 /*------------------------------------------------------------------------------
75 *------------------------------------------------------------------------------
77 extern void emgd_set_real_handle(igd_driver_h drm_handle);
78 extern void emgd_set_real_dispatch(igd_dispatch_t *drm_dispatch);
79 extern void emgd_modeset_init(struct drm_device *dev);
80 extern void emgd_modeset_destroy(struct drm_device *dev);
81 extern int msvdx_pre_init_plb(struct drm_device *dev);
82 extern int msvdx_shutdown_plb(igd_context_t *context);
83 extern emgd_drm_config_t config_drm;
84 extern int context_count;
86 /* This must be defined whether debug or release build */
87 igd_debug_t emgd_debug_flag = {
92 igd_debug_t *emgd_debug = &emgd_debug_flag;
94 #ifdef DEBUG_BUILD_TYPE
96 MODULE_PARM_DESC(debug_cmd, "Debug: cmd");
97 module_param_named(debug_cmd, emgd_debug_flag.hal.cmd, short, 0600);
99 MODULE_PARM_DESC(debug_dsp, "Debug: dsp");
100 module_param_named(debug_dsp, emgd_debug_flag.hal.dsp, short, 0600);
102 MODULE_PARM_DESC(debug_mode, "Debug: mode");
103 module_param_named(debug_mode, emgd_debug_flag.hal.mode, short, 0600);
105 MODULE_PARM_DESC(debug_init, "Debug: init");
106 module_param_named(debug_init, emgd_debug_flag.hal.init, short, 0600);
108 MODULE_PARM_DESC(debug_overlay, "Debug: overlay");
109 module_param_named(debug_overlay, emgd_debug_flag.hal.overlay, short, 0600);
111 MODULE_PARM_DESC(debug_power, "Debug: power");
112 module_param_named(debug_power, emgd_debug_flag.hal.power, short, 0600);
114 MODULE_PARM_DESC(debug_2D, "Debug: 2D");
115 module_param_named(debug_2D, emgd_debug_flag.hal._2d, short, 0600);
117 MODULE_PARM_DESC(debug_blend, "Debug: blend");
118 module_param_named(debug_blend, emgd_debug_flag.hal.blend, short, 0600);
120 MODULE_PARM_DESC(debug_state, "Debug: state");
121 module_param_named(debug_state, emgd_debug_flag.hal.state, short, 0600);
123 MODULE_PARM_DESC(debug_gmm, "Debug: GMM");
124 module_param_named(debug_gmm, emgd_debug_flag.hal.gmm, short, 0600);
126 MODULE_PARM_DESC(debug_gart, "Debug: GART");
127 module_param_named(debug_gart, emgd_debug_flag.hal.gart, short, 0600);
129 MODULE_PARM_DESC(debug_oal, "Debug: OAL");
130 module_param_named(debug_oal, emgd_debug_flag.hal.oal, short, 0600);
132 MODULE_PARM_DESC(debug_intr, "Debug: intr");
133 module_param_named(debug_intr, emgd_debug_flag.hal.intr, short, 0600);
135 MODULE_PARM_DESC(debug_dpd, "Debug: dpd");
136 module_param_named(debug_dpd, emgd_debug_flag.hal.dpd, short, 0600);
138 MODULE_PARM_DESC(debug_video, "Debug: video");
139 module_param_named(debug_video, emgd_debug_flag.hal.video, short, 0600);
141 MODULE_PARM_DESC(debug_pvr3dd, "Debug: PVR3DD");
142 module_param_named(debug_pvr3dd, emgd_debug_flag.hal.pvr3dd, short, 0600);
144 MODULE_PARM_DESC(debug_trace, "Global Debug: trace");
145 module_param_named(debug_trace, emgd_debug_flag.hal.trace, short, 0600);
147 MODULE_PARM_DESC(debug_instr, "Global Debug: instr");
148 module_param_named(debug_instr, emgd_debug_flag.hal.instr, short, 0600);
150 MODULE_PARM_DESC(debug_debug, "Global Debug: Debug with no associated module ");
151 module_param_named(debug_debug, emgd_debug_flag.hal.debug, short, 0600);
153 MODULE_PARM_DESC(debug_blend_stats, "Verbose Debug: Blend stats");
154 module_param_named(debug_blend_stats, emgd_debug_flag.hal.blend_stats, short, 0600);
156 MODULE_PARM_DESC(debug_dump_overlay_regs, "Verbose Debug: Dump overlay regs");
157 module_param_named(debug_dump_overlay_regs, emgd_debug_flag.hal.dump_overlay_regs, short, 0600);
159 MODULE_PARM_DESC(debug_dump_command_queue, "Verbose Debug: dump command queue");
160 module_param_named(debug_dump_command_queue, emgd_debug_flag.hal.dump_command_queue, short, 0600);
162 MODULE_PARM_DESC(debug_dump_gmm_on_fail, "Verbose Debug: dump gmm on fail");
163 module_param_named(debug_dump_gmm_on_fail, emgd_debug_flag.hal.dump_gmm_on_fail, short, 0600);
165 MODULE_PARM_DESC(debug_dump_shaders, "Verbose Debug: dump shaders");
166 module_param_named(debug_dump_shaders, emgd_debug_flag.hal.dump_shaders, short, 0600);
168 MODULE_PARM_DESC(debug_bc_ts, "Debug: Texture Stream");
169 module_param_named(debug_bc_ts, emgd_debug_flag.hal.buf_class, short, 0600);
173 static struct drm_driver driver; /* TODO: what? */
175 /* Note: The following module paramter values are advertised to the root user,
176 * via the files in the /sys/module/emgd/parameters directory (e.g. the "init"
177 * file contains the value of the "init" module parameter), and so we keep
178 * these values up to date.
180 * Note: The initial values are all set to -1, so that we can tell if the user
183 int drm_emgd_portorder[IGD_MAX_PORTS] = {-1, -1, -1, -1, -1};
184 int drm_emgd_numports;
185 int drm_emgd_configid = -1;
186 int drm_emgd_init = -1;
187 int drm_emgd_dc = -1;
188 int drm_emgd_width = -1;
189 int drm_emgd_height = -1;
190 int drm_emgd_refresh = -1;
191 MODULE_PARM_DESC(portorder, "Display port order (e.g. \"4,2,0,0,0\")");
192 MODULE_PARM_DESC(configid, "Which defined configuration number to use (e.g. "
194 MODULE_PARM_DESC(init, "Whether to initialize the display at startup (1=yes, "
196 MODULE_PARM_DESC(dc, "Display configuration (i.e. 1=single, 2=clone)");
197 MODULE_PARM_DESC(width, "Display resolution's width (e.g. \"1024\")");
198 MODULE_PARM_DESC(height, "Display resolution's height (e.g. \"768\")");
199 MODULE_PARM_DESC(refresh, "Monitor refresh rate (e.g. 60, as in 60Hz)");
200 module_param_array_named(portorder, drm_emgd_portorder, int, &drm_emgd_numports,
202 module_param_named(configid, drm_emgd_configid, int, 0600);
203 module_param_named(init, drm_emgd_init, int, 0600);
204 module_param_named(dc, drm_emgd_dc, int, 0600);
205 module_param_named(width, drm_emgd_width, int, 0600);
206 module_param_named(height, drm_emgd_height, int, 0600);
207 module_param_named(refresh, drm_emgd_refresh, int, 0600);
210 /** The DC to use when the DRM module [re-]initializes the display. */
211 static unsigned long *desired_dc = NULL;
212 /** The DC to use when the DRM module [re-]initializes the display. */
213 static unsigned short port_number = 0;
214 /** The mode to use when the DRM module [re-]initializes the display. */
215 static igd_display_info_t *desired_mode = NULL;
216 /** Set to true when we know X is initialized. This flag should be set
217 ** earlier, but right now we're setting it in emgd_driver_preclose() */
218 unsigned x_started = false;
221 * The primary fb_info to use when the DRM module [re-]initializes the display.
223 igd_framebuffer_info_t *primary_fb_info;
225 * The secondary fb_info to use when the DRM module [re-]initializes the
228 igd_framebuffer_info_t *secondary_fb_info;
230 * The primary display structure (filled in by alter_displays()) to use when
231 * the DRM module [re-]initializes the display.
233 igd_display_h primary;
235 * The secondary display structure (filled in by alter_displays()) to use when
236 * the DRM module [re-]initializes the display.
238 igd_display_h secondary;
240 * The display information to use when the DRM module [re-]initializes the
243 igd_display_info_t pt_info;
244 extern mode_context_t mode_context[1];
246 /* Note: This macro is #define'd in "oal/os/memory.h" */
247 #ifdef INSTRUMENT_KERNEL_ALLOCS
248 os_allocd_mem *list_head = NULL;
249 os_allocd_mem *list_tail = NULL;
253 #define emgd_PCI_IDS \
254 {0x8086, 0x8108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8108}, \
255 {0x8086, 0x8109, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_PSB_8109}, \
256 {0x8086, 0x4108, PCI_ANY_ID, PCI_ANY_ID, 0, 0, CHIP_TC_4108}, \
259 static struct pci_device_id pciidlist[] = {
264 * To use DRM_IOCTL_DEF, the first arg should be the local (zero based)
265 * IOCTL number, not the global number.
267 #define EMGD_IOCTL_DEF(ioctl, _func, _flags) \
268 [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = \
269 {.cmd = ioctl, .func = _func, .flags = _flags}
271 static struct drm_ioctl_desc emgd_ioctl[] = {
273 * NOTE: The flag "DRM_MASTER" for the final parameter indicates an ioctl
274 * can only be used by the DRM master process. In an X environment, the
275 * X server will be the master, in a Wayland environment, the Wayland
276 * compositor will be master, and if just running standalone GBM apps,
277 * they'll gain master. For ioctl's that we want to run from an X
278 * client app or a Wayland client app, we instead use DRM_AUTH; these
279 * clients will get the DRM master to authenticate them, after which
280 * they'll be able to call the ioctl's. Random programs that haven't
281 * authenticated with the DRM master won't be able to call them.
283 * For all private EMGD ioctl's added declaration DRM_UNLOCKED,
284 * now ioctl's can run in parallel. Before it, without declaration
285 * DRM_UNLOCKED private EMGD ioctl's can run/work in serial mode only,
288 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_ALTER_CURSOR, emgd_alter_cursor,
289 DRM_MASTER|DRM_UNLOCKED),
290 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_ALTER_CURSOR_POS, emgd_alter_cursor_pos,
291 DRM_MASTER|DRM_UNLOCKED),
292 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_ALTER_DISPLAYS, emgd_alter_displays,
293 DRM_MASTER|DRM_UNLOCKED),
294 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_ALTER_OVL, emgd_alter_ovl, DRM_MASTER|DRM_UNLOCKED),
295 /* Making DRM_IOCTL_IGD_ALTER_OVL2 DRM_AUTH so that libva wayland can
296 * call alter_ovl without going through X server.
298 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_ALTER_OVL2, emgd_alter_ovl2, DRM_AUTH|DRM_UNLOCKED),
299 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_APPCTX_ALLOC, emgd_appcontext_alloc,
300 DRM_MASTER|DRM_UNLOCKED),
301 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_APPCTX_FREE, emgd_appcontext_free,
302 DRM_MASTER|DRM_UNLOCKED),
303 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_DRIVER_SAVE_RESTORE, emgd_driver_save_restore,
304 DRM_MASTER|DRM_UNLOCKED),
305 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_ENABLE_PORT, emgd_enable_port, DRM_MASTER|DRM_UNLOCKED),
306 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_ATTRS, emgd_get_attrs, DRM_MASTER|DRM_UNLOCKED),
307 /* Making DRM_IOCTL_IGD_GET_DISPLAY DRM_AUTH so that libva wayland can
308 * obtain the display handle without going through x server.
310 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_DISPLAY, emgd_get_display, DRM_AUTH|DRM_UNLOCKED),
311 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_DRM_CONFIG, emgd_get_drm_config,
312 DRM_MASTER|DRM_UNLOCKED),
313 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_EDID_BLOCK, emgd_get_EDID_block,
314 DRM_MASTER|DRM_UNLOCKED),
315 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_EDID_INFO, emgd_get_EDID_info,
316 DRM_MASTER|DRM_UNLOCKED),
317 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_PIXELFORMATS, emgd_get_pixelformats,
318 DRM_MASTER|DRM_UNLOCKED),
319 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_PORT_INFO, emgd_get_port_info,
320 DRM_MASTER|DRM_UNLOCKED),
321 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GMM_ALLOC_REGION, emgd_gmm_alloc_region,
322 DRM_MASTER|DRM_UNLOCKED),
323 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GMM_ALLOC_SURFACE, emgd_gmm_alloc_surface,
324 DRM_MASTER|DRM_UNLOCKED),
325 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GMM_GET_NUM_SURFACE, emgd_gmm_get_num_surface,
326 DRM_MASTER|DRM_UNLOCKED),
327 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GMM_GET_SURFACE_LIST,emgd_gmm_get_surface_list,
328 DRM_MASTER|DRM_UNLOCKED),
329 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GMM_FREE, emgd_gmm_free,
330 DRM_MASTER|DRM_UNLOCKED),
331 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GMM_FLUSH_CACHE, emgd_gmm_flush_cache,
332 DRM_MASTER|DRM_UNLOCKED),
334 * Externally handled IOCTL's. These are routed to the Imagination Tech
336 * function prototypes in services4/srvkm/env/linux/pvr_drm.h
338 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_1, PVRSRV_BridgeDispatchKM, DRM_UNLOCKED),
339 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_2, PVRDRM_Dummy_ioctl, DRM_UNLOCKED),
340 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_3, PVRDRM_Dummy_ioctl, DRM_UNLOCKED),
341 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_4, PVRDRMIsMaster, DRM_MASTER|DRM_UNLOCKED),
342 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_5, PVRDRMUnprivCmd, DRM_UNLOCKED),
344 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_PAN_DISPLAY, emgd_pan_display,
345 DRM_MASTER|DRM_UNLOCKED),
346 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_POWER_DISPLAY, emgd_power_display,
347 DRM_MASTER|DRM_UNLOCKED),
348 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_PWR_ALTER, emgd_pwr_alter, DRM_MASTER|DRM_UNLOCKED),
349 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_QUERY_DC, emgd_query_dc,
350 DRM_MASTER|DRM_UNLOCKED),
351 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_QUERY_MAX_SIZE_OVL, emgd_query_max_size_ovl,
352 DRM_MASTER|DRM_UNLOCKED),
353 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_QUERY_OVL, emgd_query_ovl, DRM_MASTER|DRM_UNLOCKED),
354 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_QUERY_MODE_LIST, emgd_query_mode_list,
355 DRM_MASTER|DRM_UNLOCKED),
356 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_GOLDEN_HTOTAL, emgd_get_golden_htotal,
357 DRM_MASTER|DRM_UNLOCKED),
358 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_CONTROL_PLANE_FORMAT, emgd_control_plane_format,
359 DRM_MASTER|DRM_UNLOCKED),
360 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_SET_OVERLAY_DISPLAY, emgd_set_overlay_display,
361 DRM_MASTER|DRM_UNLOCKED),
362 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_QUERY_2D_CAPS_HWHINT, emgd_query_2d_caps_hwhint,
363 DRM_MASTER|DRM_UNLOCKED),
368 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_6, dbgdrv_ioctl, 0),
370 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_6, NULL, 0),
372 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_SET_ATTRS, emgd_set_attrs, DRM_MASTER|DRM_UNLOCKED),
373 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_SET_PALETTE_ENTRY, emgd_set_palette_entry,
374 DRM_MASTER|DRM_UNLOCKED),
375 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_SET_SURFACE, emgd_set_surface, DRM_MASTER|DRM_UNLOCKED),
376 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_SYNC, emgd_sync, DRM_MASTER|DRM_UNLOCKED),
377 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_DRIVER_PRE_INIT, emgd_driver_pre_init,
378 DRM_MASTER|DRM_UNLOCKED),
379 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_DRIVER_GET_PORTS, emgd_driver_get_ports,
380 DRM_MASTER|DRM_UNLOCKED),
381 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_OVL_INIT_PARAMS, emgd_get_ovl_init_params,
382 DRM_MASTER|DRM_UNLOCKED),
383 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_PAGE_LIST, emgd_get_page_list,
384 DRM_MASTER|DRM_UNLOCKED),
385 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_START_PVRSRV, emgd_start_pvrsrv,
386 DRM_MASTER|DRM_UNLOCKED),
387 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_TEST_PVRSRV, emgd_test_pvrsrv,
388 DRM_MASTER|DRM_UNLOCKED),
389 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_CHIPSET_INFO, emgd_get_chipset_info,
390 DRM_MASTER|DRM_UNLOCKED),
391 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_DIHCLONE_SET_SURFACE, emgd_dihclone_set_surface, DRM_MASTER|DRM_UNLOCKED),
392 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_PREINIT_MMU, emgd_preinit_mmu, DRM_MASTER|DRM_UNLOCKED),
395 * For VIDEO (MSVDX/TOPAZ
397 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_VIDEO_CMD_BUF, emgd_video_cmd_buf,
399 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_INIT_VIDEO, emgd_init_video,
401 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_DEVICE_INFO, emgd_get_device_info,
403 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_VIDEO_GET_INFO, emgd_video_get_info,
405 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_VIDEO_FLUSH_TLB, emgd_video_flush_tlb,
408 /* For Buffer Class of Texture Stream */
409 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_INIT, emgd_bc_ts_cmd_init,
410 DRM_AUTH|DRM_UNLOCKED),
411 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_UNINIT, emgd_bc_ts_cmd_uninit,
412 DRM_AUTH|DRM_UNLOCKED),
413 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_REQUEST_BUFFERS, emgd_bc_ts_cmd_request_buffers,
414 DRM_AUTH|DRM_UNLOCKED),
415 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_RELEASE_BUFFERS, emgd_bc_ts_cmd_release_buffers,
416 DRM_AUTH|DRM_UNLOCKED),
417 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_SET_BUFFER_INFO, emgd_bc_ts_set_buffer_info,
418 DRM_AUTH|DRM_UNLOCKED),
419 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_GET_BUFFERS_COUNT, emgd_bc_ts_get_buffers_count,
420 DRM_AUTH|DRM_UNLOCKED),
421 EMGD_IOCTL_DEF(DRM_IOCTL_IGD_BC_TS_GET_BUFFER_INDEX, emgd_bc_ts_get_buffer_index,
422 DRM_AUTH|DRM_UNLOCKED),
425 static int emgd_max_ioctl = DRM_ARRAY_SIZE(emgd_ioctl);
430 * NOTE: The next part of this file are EMGD-specific DRM functions, exported to
431 * the generic DRM code via the drm_driver struct:
435 extern igd_driver_h handle;
436 /** This is the dispatch table for the HAL. It is cached for quick access. */
437 extern igd_dispatch_t *dispatch;
441 * The driver handle for talking with the HAL, within the DRM/kernel code.
443 * This is a "real handle" as opposed to the "fake handle" in user-space.
444 * Notice that there's only one handle, as the secondary device shares this
447 static igd_driver_h drm_HAL_handle = NULL;
450 * This is the drm_HAL_handle cast to an igd_context_t. It is cached for quick
453 static igd_context_t *drm_HAL_context = NULL;
456 * This is the dispatch table for the HAL. It is cached for quick access.
458 static igd_dispatch_t *drm_HAL_dispatch = NULL;
463 * get_pre_driver_info
465 * Gets the mode information before the user-mode driver changes it.
466 * This information can either come from the firmware or the DRM.
467 * Note: Prior to EMGD this information can only come from the firmware
468 * thus the field "fw_info." This should really be changed
471 * @param mode_context This is where fw_info is stored
473 * @return -IGD_INVAL on failure
474 * @return 0 on success
476 static int get_pre_driver_info(mode_context_t *mode_context)
479 int seamless = FALSE;
482 if(mode_context->fw_info != NULL) {
485 ret = mode_context->dispatch->full->get_plane_info();
490 ret = mode_context->dispatch->full->get_pipe_info(primary);
495 ret = mode_context->dispatch->full->get_port_info();
502 if(seamless == FALSE) {
503 /* If one of these plane/pipe/port functions
504 * returns an error, we explicitly
507 mode_context->seamless = FALSE;
517 * A helper function that prints the igd_param_t struct.
519 * @param params (IN) The the igd_param_t struct to print
521 void emgd_print_params(igd_param_t *params)
525 EMGD_DEBUG("Values of params:");
526 EMGD_DEBUG(" page_request = %lu = 0x%lx", params->page_request,
527 params->page_request);
528 EMGD_DEBUG(" max_fb_size = %lu = 0x%lx", params->max_fb_size,
529 params->max_fb_size);
530 EMGD_DEBUG(" preserve_regs = %u", params->preserve_regs);
531 EMGD_DEBUG(" display_flags = %lu = 0x%lx", params->display_flags,
532 params->display_flags);
533 EMGD_DEBUG(" port_order:");
534 for (i = 0 ; i < IGD_MAX_PORTS; i++) {
535 EMGD_DEBUG(" port number %d = %lu", i, params->port_order[i]);
537 EMGD_DEBUG(" display_params:");
538 for (i = 0 ; i < IGD_MAX_PORTS; i++) {
541 EMGD_DEBUG(" port_number = %lu",
542 params->display_params[i].port_number);
543 EMGD_DEBUG(" present_params = %lu = 0x%lx",
544 params->display_params[i].present_params,
545 params->display_params[i].present_params);
546 EMGD_DEBUG(" flags = %lu = 0x%lx",
547 params->display_params[i].flags,
548 params->display_params[i].flags);
549 EMGD_DEBUG(" edid_avail = %u = 0x%x",
550 params->display_params[i].edid_avail,
551 params->display_params[i].edid_avail);
552 EMGD_DEBUG(" edid_not_avail = %u = 0x%x",
553 params->display_params[i].edid_not_avail,
554 params->display_params[i].edid_not_avail);
555 EMGD_DEBUG(" ddc_gpio = %lu", params->display_params[i].ddc_gpio);
556 EMGD_DEBUG(" ddc_speed = %lu", params->display_params[i].ddc_speed);
557 EMGD_DEBUG(" ddc_dab = %lu", params->display_params[i].ddc_dab);
558 EMGD_DEBUG(" i2c_gpio = %lu", params->display_params[i].i2c_gpio);
559 EMGD_DEBUG(" i2c_speed = %lu", params->display_params[i].i2c_speed);
560 EMGD_DEBUG(" i2c_dab = %lu", params->display_params[i].i2c_dab);
561 EMGD_DEBUG(" fp_info.fp_width = %lu",
562 params->display_params[i].fp_info.fp_width);
563 EMGD_DEBUG(" fp_info.fp_height = %lu",
564 params->display_params[i].fp_info.fp_height);
565 EMGD_DEBUG(" fp_info.fp_pwr_method = %lu",
566 params->display_params[i].fp_info.fp_pwr_method);
567 EMGD_DEBUG(" fp_info.fp_pwr_t1 = %lu",
568 params->display_params[i].fp_info.fp_pwr_t1);
569 EMGD_DEBUG(" fp_info.fp_pwr_t2 = %lu",
570 params->display_params[i].fp_info.fp_pwr_t2);
571 EMGD_DEBUG(" fp_info.fp_pwr_t3 = %lu",
572 params->display_params[i].fp_info.fp_pwr_t3);
573 EMGD_DEBUG(" fp_info.fp_pwr_t4 = %lu",
574 params->display_params[i].fp_info.fp_pwr_t4);
575 EMGD_DEBUG(" fp_info.fp_pwr_t5 = %lu",
576 params->display_params[i].fp_info.fp_pwr_t5);
577 EMGD_DEBUG(" dtd_list:");
578 EMGD_DEBUG(" num_dtds = %lu",
579 params->display_params[i].dtd_list.num_dtds);
580 for (j = 0 ; j < params->display_params[i].dtd_list.num_dtds; j++) {
581 EMGD_DEBUG(" *dtd[%d].width = %u", j,
582 params->display_params[i].dtd_list.dtd[j].width);
583 EMGD_DEBUG(" dtd[%d].height = %u", j,
584 params->display_params[i].dtd_list.dtd[j].height);
585 EMGD_DEBUG(" dtd[%d].refresh = %u", j,
586 params->display_params[i].dtd_list.dtd[j].refresh);
587 EMGD_DEBUG(" dtd[%d].dclk = %lu = 0x%lx", j,
588 params->display_params[i].dtd_list.dtd[j].dclk,
589 params->display_params[i].dtd_list.dtd[j].dclk);
590 EMGD_DEBUG(" dtd[%d].htotal = %u", j,
591 params->display_params[i].dtd_list.dtd[j].htotal);
592 EMGD_DEBUG(" dtd[%d].hblank_start = %u", j,
593 params->display_params[i].dtd_list.dtd[j].hblank_start);
594 EMGD_DEBUG(" dtd[%d].hblank_end = %u", j,
595 params->display_params[i].dtd_list.dtd[j].hblank_end);
596 EMGD_DEBUG(" dtd[%d].hsync_start = %u", j,
597 params->display_params[i].dtd_list.dtd[j].hsync_start);
598 EMGD_DEBUG(" dtd[%d].hsync_end = %u", j,
599 params->display_params[i].dtd_list.dtd[j].hsync_end);
600 EMGD_DEBUG(" dtd[%d].vtotal = %u", j,
601 params->display_params[i].dtd_list.dtd[j].vtotal);
602 EMGD_DEBUG(" dtd[%d].vblank_start = %u", j,
603 params->display_params[i].dtd_list.dtd[j].vblank_start);
604 EMGD_DEBUG(" dtd[%d].vblank_end = %u", j,
605 params->display_params[i].dtd_list.dtd[j].vblank_end);
606 EMGD_DEBUG(" dtd[%d].vsync_start = %u", j,
607 params->display_params[i].dtd_list.dtd[j].vsync_start);
608 EMGD_DEBUG(" dtd[%d].vsync_end = %u", j,
609 params->display_params[i].dtd_list.dtd[j].vsync_end);
610 EMGD_DEBUG(" dtd[%d].mode_number = %d", j,
611 params->display_params[i].dtd_list.dtd[j].mode_number);
612 EMGD_DEBUG(" dtd[%d].flags = %lu = 0x%lx", j,
613 params->display_params[i].dtd_list.dtd[j].flags,
614 params->display_params[i].dtd_list.dtd[j].flags);
615 EMGD_DEBUG(" dtd[%d].x_offset = %u", j,
616 params->display_params[i].dtd_list.dtd[j].x_offset);
617 EMGD_DEBUG(" dtd[%d].y_offset = %u", j,
618 params->display_params[i].dtd_list.dtd[j].y_offset);
619 /*EMGD_DEBUG(" dtd[%d].pd_private_ptr = 0x%p", j,
620 params->display_params[i].dtd_list.dtd[j].pd_private_ptr); */
621 EMGD_DEBUG(" dtd[%d].private_ptr = 0x%p", j,
622 params->display_params[i].dtd_list.dtd[j].private_ptr);
624 EMGD_DEBUG(" attr_list:");
625 EMGD_DEBUG(" num_attrs = %lu",
626 params->display_params[i].attr_list.num_attrs);
627 for (j = 0 ; j < params->display_params[i].attr_list.num_attrs; j++) {
628 EMGD_DEBUG(" attr[%d].id = %lu = 0x%lx", j,
629 params->display_params[i].attr_list.attr[j].id,
630 params->display_params[i].attr_list.attr[j].id);
631 EMGD_DEBUG(" attr[%d].value = %lu = 0x%lx", j,
632 params->display_params[i].attr_list.attr[j].value,
633 params->display_params[i].attr_list.attr[j].value);
636 EMGD_DEBUG(" display_color = %lu = 0x%lx", params->display_color,
637 params->display_color);
638 EMGD_DEBUG(" quickboot = %lu", params->quickboot);
639 EMGD_DEBUG(" qb_seamless = %d", params->qb_seamless);
640 EMGD_DEBUG(" qb_video_input = %lu", params->qb_video_input);
641 EMGD_DEBUG(" qb_splash = %d", params->qb_splash);
642 EMGD_DEBUG(" polling = %d", params->polling);
643 } /* emgd_print_params() */
647 * A helper function that starts, initializes and configures the HAL. This
648 * will be called during emgd_driver_load() if the display is to be initialized
649 * at module load time. Otherwise, this is deferred till the X driver loads
650 * and calls emgd_driver_pre_init().
652 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h").
653 * @param params (IN) The the igd_param_t struct to give to the HAL.
655 * @return 0 on Success
656 * @return <0 on Error
658 int emgd_startup_hal(struct drm_device *dev, igd_param_t *params)
660 drm_emgd_priv_t *priv = dev->dev_private;
666 /* Initialize the various HAL modules: */
667 EMGD_DEBUG("Calling igd_module_init()");
669 err = igd_module_init(drm_HAL_handle, &drm_HAL_dispatch, params);
674 /* Give the dispatch table to the ioctl-handling "bridge" code: */
675 emgd_set_real_dispatch(drm_HAL_dispatch);
677 /* Record that the HAL is running now: */
678 priv->hal_running = 1;
679 /* Record that the console's state is saved: */
680 priv->saved_registers = CONSOLE_STATE_SAVED;
682 /* Since PVR services is running, we're restarting the HAL, which
683 * disabled the SGX & MSVDX interrupts. Need to re-enable those
686 SysReEnableInterrupts();
691 } /* emgd_startup_hal() */
696 * A helper function that initializes the display, and potentially merges the
697 * module parameters with the pre-compiled parameters.
699 * @param merge_mod_params (IN) non-zero if the module parameters should be
700 * merged with the pre-compiled parameters.
703 void emgd_init_display(int merge_mod_params, drm_emgd_priv_t *priv)
706 igd_display_info_t *mode_list = NULL;
707 igd_display_info_t *mode = NULL;
708 struct drm_framebuffer *framebuffer = NULL;
709 emgd_framebuffer_t *emgd_fb = NULL;
710 unsigned char *fb = NULL;
711 int mode_flags = IGD_QUERY_LIVE_MODES;
712 unsigned long temp_bg_color;
717 if (merge_mod_params) {
718 EMGD_DEBUG("Checking other module parameters before initializing the "
721 /*************************************
722 * Get the desired display display config:
723 *************************************/
724 if (-1 != drm_emgd_dc) {
725 /* Validate and potentially use the module parameter: */
726 EMGD_DEBUG("Value of module parameter \"dc\" = \"%d\"", drm_emgd_dc);
727 if (IGD_DC_SINGLE(drm_emgd_dc) || IGD_DC_CLONE(drm_emgd_dc) ||
728 IGD_DC_VEXT(drm_emgd_dc) || IGD_DC_EXTENDED(drm_emgd_dc)) {
729 /* Use validated value to override compile-time value: */
730 config_drm.dc = drm_emgd_dc;
731 } else if (IGD_DC_TWIN(drm_emgd_dc)) {
732 /* Use validated value to override compile-time value: */
733 EMGD_DEBUG("Module parameter \"dc\" contains unsupported value "
735 EMGD_DEBUG("Overriding and making it 1 (single display).");
737 config_drm.dc = drm_emgd_dc;
739 /* Use compile-time value: */
740 EMGD_ERROR("Module parameter \"dc\" contains invalid value "
741 "%d (must be 1, 2, 5 or 8).", drm_emgd_dc);
742 if (config_drm.dc == 4) {
743 EMGD_DEBUG("Compile-time setting for module parameter "
744 "\"dc\" contains unsupported value %d.", config_drm.dc);
745 EMGD_DEBUG("Overriding and making it 1 (single display).");
749 EMGD_ERROR("Will use compile-time setting %d instead "
750 "of invalid value %d.\n", config_drm.dc, drm_emgd_dc);
752 drm_emgd_dc = config_drm.dc;
755 /* Check and potentially use the compile-time value: */
756 if (IGD_DC_SINGLE(config_drm.dc) || IGD_DC_CLONE(config_drm.dc) ||
757 IGD_DC_VEXT(config_drm.dc) ||
758 IGD_DC_EXTENDED(config_drm.dc)) {
759 /* Report the compile-time value: */
760 EMGD_DEBUG("Using compile-time setting for the module parameter"
761 " \"dc\" = \"%d\"", config_drm.dc);
762 } else if (IGD_DC_TWIN(config_drm.dc)) {
763 EMGD_DEBUG("Compile-time setting for module parameter "
764 "\"dc\" contains unsupported value %d.", config_drm.dc);
765 EMGD_DEBUG("Overriding and making it 1 (single display).");
768 EMGD_DEBUG("Compile-time setting for module parameter "
769 "\"dc\" contains invalid value %d.", config_drm.dc);
770 EMGD_DEBUG("Must be 1, 2, 5 or 8. Making it 1 (single"
774 drm_emgd_dc = config_drm.dc;
777 /*************************************
778 * Get the desired display "width":
779 *************************************/
780 if (-1 != drm_emgd_width) {
781 /* Override the compile-time value with the module parameter: */
782 EMGD_DEBUG("Using the \"width\" module parameter: \"%d\"",
784 config_drm.width = drm_emgd_width;
786 /* Use the compile-time value: */
787 drm_emgd_width = config_drm.width;
788 EMGD_DEBUG("Using the compile-time \"width\" value: \"%d\"",
792 /*************************************
793 * Get the desired display "height":
794 *************************************/
795 if (-1 != drm_emgd_height) {
796 /* Override the compile-time value with the module parameter: */
797 EMGD_DEBUG("Using the \"height\" module parameter: \"%d\"",
799 config_drm.height = drm_emgd_height;
801 /* Use the compile-time value: */
802 drm_emgd_height = config_drm.height;
803 EMGD_DEBUG("Using the compile-time \"height\" value: \"%d\"",
807 /*************************************
808 * Get the desired display "refresh":
809 *************************************/
810 if (-1 != drm_emgd_refresh) {
811 /* Override the compile-time value with the module parameter: */
812 EMGD_DEBUG("Using the \"refresh\" module parameter: \"%d\"",
814 config_drm.refresh = drm_emgd_refresh;
816 /* Use the compile-time value: */
817 drm_emgd_refresh = config_drm.refresh;
818 EMGD_DEBUG("Using the compile-time \"refresh\" value: \"%d\"",
824 if (config_drm.kms) {
828 /*************************************
829 * Initialize kernel mode setting functionality
830 *************************************/
831 emgd_modeset_init(priv->ddev);
833 /* Get Display context */
834 drm_HAL_context->mod_dispatch.dsp_get_dc(NULL,
835 (igd_display_context_t **) &primary,
836 (igd_display_context_t **) &secondary);
839 /*************************************
840 * Initialize primary_fb_info
841 *************************************/
842 framebuffer = list_entry(priv->ddev->mode_config.fb_list.next,
843 struct drm_framebuffer, head);
845 EMGD_ERROR("Can't display splash screen/video as there is no fb.");
847 emgd_fb = container_of(framebuffer, emgd_framebuffer_t, base);
848 primary_fb_info = &priv->initfb_info;
850 fb = priv->fbdev->screen_base;
856 * Update the private data structure
858 priv->primary = primary;
859 priv->secondary = secondary;
860 priv->primary_port_number = IGD_DC_PRIMARY(priv->dc);
861 priv->secondary_port_number = IGD_DC_SECONDARY(priv->dc);
864 /**************************************************************************
865 * Special case handling: Since HAL doesn't know anything about Vertical
866 * extended mode, if we are in Vertical Extended (5), send HAL asking for
868 *************************************************************************/
869 temp_dc = drm_emgd_dc;
870 if(IGD_DC_VEXT(drm_emgd_dc)) {
871 temp_dc = IGD_DISPLAY_CONFIG_CLONE;
874 /*************************************
875 * Query the DC list (use first one):
876 *************************************/
877 EMGD_DEBUG("Calling query_dc()");
878 err = drm_HAL_dispatch->query_dc(drm_HAL_handle, temp_dc,
879 &desired_dc, IGD_QUERY_DC_INIT);
880 EMGD_DEBUG("query_dc() returned %d", err);
882 EMGD_ERROR_EXIT("Cannot initialize the display as requested.\n"
883 "The query_dc() function returned %d.", err);
886 port_number = (*desired_dc & 0xf0) >> 4;
887 EMGD_DEBUG("Using DC 0x%lx with port number %d",
888 *desired_dc, port_number);
889 if(IGD_DC_VEXT(drm_emgd_dc)) {
890 drm_emgd_dc = (*desired_dc & ~IGD_DISPLAY_CONFIG_CLONE) |
891 IGD_DISPLAY_CONFIG_VEXT;
894 /*************************************
895 * Query the mode list:
896 *************************************/
897 EMGD_DEBUG("Calling query_mode_list()");
898 err = drm_HAL_dispatch->query_mode_list(drm_HAL_handle, *desired_dc,
899 &mode_list, mode_flags);
900 EMGD_DEBUG("query_mode_list() returned %d", err);
902 EMGD_ERROR_EXIT("Cannot initialize the display as requested\n"
903 "The query_mode_list() function returned %d.", err);
908 /*************************************
909 * Find the desired mode from the list:
910 *************************************/
911 EMGD_DEBUG("Comparing the mode list with the desired width, height, and"
915 while (mode && (mode->width != IGD_TIMING_TABLE_END)) {
916 EMGD_DEBUG(" ...Found a mode with width=%d, height=%d, refresh=%d;",
917 mode->width, mode->height, mode->refresh);
918 if ((mode->width == drm_emgd_width) &&
919 (mode->height == drm_emgd_height) &&
920 (mode->refresh == drm_emgd_refresh)) {
921 EMGD_DEBUG(" ... This mode is a match!");
927 if (NULL == desired_mode) {
928 EMGD_ERROR("Cannot initialize the display as requested.");
929 EMGD_ERROR("No mode matching the desired width (%d), height "
930 "(%d), and refresh rate (%d) was found.",
931 drm_emgd_width, drm_emgd_height, drm_emgd_refresh);
934 /* Must set this in order to get the timings setup: */
935 desired_mode->flags |= IGD_DISPLAY_ENABLE;
938 /*************************************
939 * Call alter_displays():
940 *************************************/
941 primary_fb_info = kzalloc(sizeof(igd_framebuffer_info_t), GFP_KERNEL);
942 secondary_fb_info = kzalloc(sizeof(igd_framebuffer_info_t), GFP_KERNEL);
943 primary_fb_info->width = desired_mode->width;
945 /*************************************
946 * Special for Vertical Extended, double the height
947 *************************************/
948 if(IGD_DC_VEXT(drm_emgd_dc)) {
949 primary_fb_info->height = desired_mode->height * 2;
951 primary_fb_info->height = desired_mode->height;
953 primary_fb_info->pixel_format = IGD_PF_ARGB32;
954 primary_fb_info->flags = 0;
955 primary_fb_info->allocated = 0;
956 memcpy(secondary_fb_info, primary_fb_info,
957 sizeof(igd_framebuffer_info_t));
959 EMGD_DEBUG("Calling alter_displays()");
960 err = drm_HAL_dispatch->alter_displays(drm_HAL_handle,
961 &primary, desired_mode, primary_fb_info,
962 &secondary, desired_mode, secondary_fb_info,
964 EMGD_DEBUG("alter_displays() returned %d", err);
966 EMGD_ERROR_EXIT("Cannot initialize the display as requested.\n"
967 "The alter_displays() function returned %d.", err);
972 * Update the private data structure with the values we get
973 * back from alter displays.
975 priv->dc = *desired_dc;
976 priv->primary = primary;
977 priv->secondary = secondary;
978 priv->primary_port_number = IGD_DC_PRIMARY(*desired_dc);
979 priv->secondary_port_number = IGD_DC_SECONDARY(*desired_dc);
981 /*************************************
982 * Special for Vertical Extended, pan the second display
983 *************************************/
984 if(IGD_DC_VEXT(drm_emgd_dc)) {
985 drm_HAL_dispatch->pan_display(secondary, 0,
986 secondary_fb_info->height / 2);
989 /*************************************
990 * Call get_display():
991 *************************************/
992 EMGD_DEBUG("Calling get_display()");
993 err = drm_HAL_dispatch->get_display(primary, port_number,
994 primary_fb_info, &pt_info, 0);
995 EMGD_DEBUG("get_display() returned %d", err);
997 EMGD_ERROR_EXIT("Cannot initialize the display as requested\n"
998 "The get_display() function returned %d.", err);
1002 /*************************************
1003 * Get FB virtual address
1004 *************************************/
1005 EMGD_DEBUG("Calling full_clear_fb()");
1006 fb = mode_context->context->dispatch.gmm_map(
1007 primary_fb_info->fb_base_offset);
1012 /*************************************
1013 * Set the framebuffer to the background color:
1014 *************************************/
1015 temp_bg_color = mode_context->display_color;
1016 mode_context->display_color = config_drm.ss_data->bg_color;
1017 full_clear_fb(mode_context, primary_fb_info, fb);
1018 mode_context->display_color = temp_bg_color;
1020 /*************************************
1021 * Display a splash screen if requested by user
1022 *************************************/
1023 if(config_drm.ss_data->width &&
1024 config_drm.ss_data->height) {
1026 /* Display a splash screen */
1027 printk(KERN_ERR "[EMGD] Display splash screen image.\n");
1028 EMGD_DEBUG("Calling disp_splash_screen()");
1029 display_splash_screen(primary_fb_info, fb, config_drm.ss_data);
1032 /*************************************
1033 * Display a splash video if requested by user
1034 *************************************/
1035 if(config_drm.sv_data->pixel_format &&
1036 config_drm.sv_data->src_width &&
1037 config_drm.sv_data->src_height &&
1038 config_drm.sv_data->src_pitch &&
1039 config_drm.sv_data->dst_width &&
1040 config_drm.sv_data->dst_height) {
1042 /* Display a splash video */
1043 EMGD_DEBUG("Calling disp_splash_video()");
1044 disp_splash_video(config_drm.sv_data);
1047 EMGD_ERROR("framebuffer base address is 0");
1050 if (!config_drm.kms) {
1051 mode_context->context->dispatch.gmm_unmap(fb);
1054 } /* emgd_init_display() */
1059 * Function to display a splash video to the user. The splash video data must be
1060 * provided to the kernel mode driver by another entity (like a driver or FPGA
1061 * HW). Splash video will be display after setting the mode (if requested by
1062 * the user through config options).
1064 * @param sv_data (IN) a non null pointer to splash video information like
1065 * width, height etc.
1067 * @return 0 on Success
1068 * @return <0 on Error
1070 int disp_splash_video(emgd_drm_splash_video_t *sv_data)
1072 igd_surface_t surface;
1073 igd_rect_t ovl_rect, surf_rect;
1074 igd_ovl_info_t ovl_info;
1077 surface.offset = sv_data->offset;
1078 surface.pitch = sv_data->src_pitch;
1079 surface.width = sv_data->src_width;
1080 surface.height = sv_data->src_height;
1081 surface.pixel_format = sv_data->pixel_format;
1082 surface.flags = IGD_SURFACE_OVERLAY;
1084 /* Set the surface rect as big as the video frame size */
1087 surf_rect.x2 = sv_data->src_width;
1088 surf_rect.y2 = sv_data->src_height;
1091 /* The x,y postion of the sprite c */
1092 ovl_rect.x1 = sv_data->dst_x;
1093 ovl_rect.y1 = sv_data->dst_y;
1096 * NOTE: This for scaling if the hardware supports it.
1097 * If no dest w x h values are set,set it the the
1100 tmp = sv_data->dst_width ? sv_data->dst_width : sv_data->src_width;
1102 ovl_rect.x2 = ovl_rect.x1 + tmp;
1104 tmp = sv_data->dst_height?
1105 sv_data->dst_height:
1106 sv_data->src_height;
1108 ovl_rect.y2 = ovl_rect.y1 + tmp;
1111 * If no values are set, set it to default
1113 ovl_info.video_quality.brightness =
1114 config_drm.ovl_brightness ?
1115 config_drm.ovl_brightness : 0x8000;
1116 ovl_info.video_quality.contrast =
1117 config_drm.ovl_contrast ?
1118 config_drm.ovl_contrast : 0x8000;
1119 ovl_info.video_quality.saturation =
1120 config_drm.ovl_saturation ?
1121 config_drm.ovl_saturation : 0x8000;
1124 * If any values are set for gamma, turn on the gamma flags
1126 ovl_info.gamma.red = config_drm.ovl_gamma_red;
1127 ovl_info.gamma.green = config_drm.ovl_gamma_green;
1128 ovl_info.gamma.blue = config_drm.ovl_gamma_blue;
1130 if(ovl_info.gamma.red || ovl_info.gamma.green || ovl_info.gamma.blue) {
1132 ovl_info.gamma.flags = IGD_OVL_GAMMA_ENABLE;
1135 drm_HAL_dispatch->alter_ovl(drm_HAL_handle, NULL,
1139 &ovl_info, IGD_OVL_ALTER_ON);
1147 * This is the drm_driver.load() function. It is called when the DRM "loads"
1148 * (i.e. when our driver loads, it calls drm_init(), which eventually causes
1149 * this driver function to be called).
1151 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1152 * @param flags (IN) The last member of the pci_device_id struct that we
1153 * fill-in at the top of this file (e.g. CHIP_PSB_8108).
1155 * @return 0 on Success
1156 * @return <0 on Error
1158 int emgd_driver_load(struct drm_device *dev, unsigned long flags)
1161 igd_param_t *params;
1162 drm_emgd_priv_t *priv = NULL;
1163 igd_init_info_t *init_info;
1164 int num_hal_params =
1165 sizeof(config_drm.hal_params) / sizeof(config_drm.hal_params[0]);
1170 mutex_lock(&dev->struct_mutex);
1172 /**************************************************************************
1174 * Get the compile-time/module-parameter "params" before initializing the
1177 **************************************************************************/
1179 /*************************************
1180 * Take into account the "configid" module parameter:
1181 *************************************/
1182 if (num_hal_params <= 0) {
1183 EMGD_ERROR("The compile-time configuration (in \"user_config.c\")\n"
1184 "contains no igd_param_t structures. Please fix and recompile.");
1185 mutex_unlock(&dev->struct_mutex);
1188 if ((drm_emgd_configid == 0) ||
1189 (drm_emgd_configid > num_hal_params)) {
1190 EMGD_ERROR("Module parameter \"configid\" contains invalid value "
1191 "%d.\nMust specify a compile-time configuration (in "
1192 "\"user_config.c\"),\nnumbered between 1 and %d.\n",
1193 drm_emgd_configid, num_hal_params);
1194 mutex_unlock(&dev->struct_mutex);
1198 /* Obtain the user-configurable set of parameter values: */
1199 if (drm_emgd_configid < 0) {
1200 params = config_drm.hal_params[0];
1202 params = config_drm.hal_params[drm_emgd_configid-1];
1206 /*************************************
1207 * Take into account the "portorder" module parameter:
1208 *************************************/
1210 EMGD_DEBUG("Determining desired port order:");
1211 if (0 == drm_emgd_numports) {
1212 /* Set this to 1 so we use the compile-time value below: */
1214 drm_emgd_numports = IGD_MAX_PORTS;
1215 } else if (drm_emgd_numports != IGD_MAX_PORTS) {
1216 EMGD_ERROR("Module parameter \"portorder\" specifies %d ports "
1217 "(must specify %d in a comma-separated list).",
1218 drm_emgd_numports, IGD_MAX_PORTS);
1219 drm_emgd_numports = IGD_MAX_PORTS;
1223 /* Validate each port within the module parameter: */
1224 for (i = 0 ; i < drm_emgd_numports ; i++) {
1225 if ((drm_emgd_portorder[i] < 0) ||
1226 (drm_emgd_portorder[i] > 5)) {
1227 EMGD_ERROR("Item %d in module parameter \"portorder\" "
1228 "contains invalid value %d (must be between 0 and 5).",
1229 i, drm_emgd_portorder[i]);
1235 /* Override the compile-time value with the module parameter: */
1236 for (i = 0 ; i < drm_emgd_numports ; i++) {
1237 params->port_order[i] = drm_emgd_portorder[i];
1239 EMGD_DEBUG("Using the \"portorder\" module parameter: \"%d, %d, %d, "
1240 "%d, %d\"", drm_emgd_portorder[0], drm_emgd_portorder[1],
1241 drm_emgd_portorder[2], drm_emgd_portorder[3],
1242 drm_emgd_portorder[4]);
1244 /* Use the compile-time value: */
1245 for (i = 0 ; i < drm_emgd_numports ; i++) {
1246 drm_emgd_portorder[i] = params->port_order[i];
1248 EMGD_DEBUG("Using the compile-time \"portorder\" value: \"%d, %d, "
1249 "%d, %d, %d\"", drm_emgd_portorder[0], drm_emgd_portorder[1],
1250 drm_emgd_portorder[2], drm_emgd_portorder[3],
1251 drm_emgd_portorder[4]);
1256 emgd_print_params(params);
1259 /**************************************************************************
1261 * Minimally initialize and configure the driver, deferring as much as
1262 * possible until the X driver starts.:
1264 **************************************************************************/
1266 /* Determine whether display initialization is desired: */
1267 if (-1 != drm_emgd_init) {
1268 /* Validate and potentially use the module parameter: */
1269 if (!((drm_emgd_init == 1) || (drm_emgd_init == 0))) {
1270 EMGD_ERROR("Module parameter \"init\" contains invalid "
1271 "value %d (must be 0 or 1).", drm_emgd_init);
1272 drm_emgd_init = config_drm.init;
1273 EMGD_ERROR("Using the compile-time \"init\" value: \"%d\"",
1276 /* Override the compile-time value with the module parameter: */
1277 config_drm.init = drm_emgd_init;
1278 EMGD_DEBUG("Using the \"init\" module parameter: \"%d\"",
1282 /* Use the compile-time value: */
1283 drm_emgd_init = config_drm.init;
1284 EMGD_DEBUG("Using the compile-time \"init\" value: \"%d\"",
1290 * In order for some early ioctls (e.g. emgd_get_chipset_info()) to work,
1291 * we must do the following minimal initialization.
1293 EMGD_DEBUG("Calling igd_driver_init()");
1294 init_info = (igd_init_info_t *)OS_ALLOC(sizeof(igd_init_info_t));
1295 drm_HAL_handle = igd_driver_init(init_info);
1296 if (drm_HAL_handle == NULL) {
1298 mutex_unlock(&dev->struct_mutex);
1302 /* Get the HAL context and give it to the ioctl-handling "bridge" code: */
1303 drm_HAL_context = (igd_context_t *) drm_HAL_handle;
1304 emgd_set_real_handle(drm_HAL_handle);
1306 /* Save the drm dev pointer, it's needed by igd_module_init */
1307 drm_HAL_context->drm_dev = dev;
1309 /* Create the private structure used to communicate to the IMG 3rd-party
1312 priv = OS_ALLOC(sizeof(drm_emgd_priv_t));
1315 mutex_unlock(&dev->struct_mutex);
1320 OS_MEMSET(priv, 0, sizeof(drm_emgd_priv_t));
1321 priv->hal_running = 0;
1322 priv->context = drm_HAL_context;
1323 priv->init_info = init_info;
1324 priv->qb_seamless = params->qb_seamless;
1325 dev->dev_private = priv;
1327 priv->kms_enabled = 0;
1330 /* Do basic driver initialization & configuration: */
1331 EMGD_DEBUG("Calling igd_driver_config()");
1332 err = igd_driver_config(drm_HAL_handle);
1336 OS_FREE(drm_HAL_handle);
1337 mutex_unlock(&dev->struct_mutex);
1341 // PVRSRVDrmLoad() sets up an ISR routine with a pointer to drm_device to be passed every time. This variable (gpDrmDevice) is initialized in msvdx_pre_init_plb only.
1342 // Due to this reason, msvdx_pre_init_plb() is moved before PVRSRVDrmLoad().
1344 /* Init MSVDX and load firmware */
1345 msvdx_pre_init_plb(dev);
1347 /* Initialize the PVR services if not already initialized */
1348 printk(KERN_INFO "Initializing PVR Services.\n");
1349 PVRSRVDrmLoad(dev, 0);
1351 /* Decide if we can defer the rest of the initialization */
1352 if (config_drm.init) {
1354 if (config_drm.kms) {
1355 params->preserve_regs = 1;
1356 priv->kms_enabled = 1;
1359 /* Initialize and configure the driver now */
1360 err = emgd_startup_hal(dev, params);
1364 OS_FREE(drm_HAL_handle);
1365 mutex_unlock(&dev->struct_mutex);
1369 /* This will get the plane, pipe and port register values and fill up the
1370 * fw_info data structure. This needs to be done at INIT time before the
1371 * user-mode driver loads
1373 get_pre_driver_info(mode_context);
1375 /* Per the user's request, initialize the display: */
1376 emgd_init_display(TRUE, priv);
1381 #ifdef DEBUG_BUILD_TYPE
1382 /* Turn on KMS debug messages in the general DRM module if our OAL
1383 * messages are on and it's a debug driver.
1385 if (emgd_debug->hal.oal) {
1386 drm_debug |= DRM_UT_KMS;
1390 /* can not work out how to start PVRSRV */
1391 /* Load Buffer Class Module*/
1394 mutex_unlock(&dev->struct_mutex);
1398 } /* emgd_driver_load() */
1402 * This is the drm_driver.unload() function. It is called when the DRM
1403 * "unloads." That is, drm_put_dev() (in "drm_stub.c"), which is called by
1404 * drm_exit() (in "drm_drv.c"), calls this function.
1406 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1408 * @return 0 on Success
1409 * @return <0 on Error
1411 int emgd_driver_unload(struct drm_device *dev)
1413 drm_emgd_priv_t *priv = dev->dev_private;
1414 unsigned long save_flags = 0;
1418 mutex_lock(&dev->struct_mutex);
1420 /* Unload Buffer Class Module*/
1421 emgd_bc_ts_uninit();
1423 PVRSRVDrmUnload(dev);
1426 if (config_drm.init && config_drm.kms) {
1427 emgd_modeset_destroy(dev);
1430 if (priv->hal_running) {
1431 /* igd_driver_shutdown() will restore the then-currently-saved register
1432 * state. We can't rely on any save_restore() calls before that time,
1433 * because igd_driver_shutdown() does things that mess up the register
1434 * state. Thus, we must allow it to do a restore. The only way to
1435 * control the final state of the hardware is to potentially do a
1436 * save_restore now. Thus, if the X server's state is currently saved
1437 * (i.e. the console's state is currently active), we must do a
1438 * save_restore now, so that this state will still exist after
1439 * igd_driver_shutdown().
1441 if (priv->saved_registers == CONSOLE_STATE_SAVED) {
1442 EMGD_DEBUG("Need to restore the console's saved register state");
1444 save_flags = IGD_REG_SAVE_ALL;
1445 drm_HAL_dispatch->driver_save_restore(drm_HAL_handle, save_flags);
1446 EMGD_DEBUG("State of saved registers is X_SERVER_STATE_SAVED");
1447 priv->saved_registers = X_SERVER_STATE_SAVED;
1449 igd_driver_shutdown_hal(drm_HAL_handle);
1450 igd_driver_shutdown(drm_HAL_handle);
1452 /* Do safe cleanup that would've been done by igd_driver_shutdown() */
1453 igd_driver_shutdown(drm_HAL_handle);
1456 if (!config_drm.kms) {
1457 kfree(primary_fb_info);
1458 kfree(secondary_fb_info);
1461 OS_FREE(priv->init_info);
1464 /* Note: This macro is #define'd in "oal/os/memory.h" */
1465 #ifdef INSTRUMENT_KERNEL_ALLOCS
1466 emgd_report_unfreed_memory();
1469 mutex_unlock(&dev->struct_mutex);
1474 } /* emgd_driver_unload() */
1478 * This is the drm_driver.open() function. It is called when a user-space
1479 * process opens the DRM device file. The DRM drm_open() (in "drm_fops.c")
1480 * calls drm_open_helper(), which calls this function.
1482 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1483 * @param priv (IN) DRM's file private data struct (in "drmP.h")
1485 * @return 0 on Success
1486 * @return <0 on Error
1488 int emgd_driver_open(struct drm_device *dev, struct drm_file *priv)
1491 drm_emgd_priv_t *emgd_priv = dev->dev_private;
1496 * Under the latest MeeGo images, something is trying to open the DRM device
1497 * while we're still inside the the load() function (possibly an updated
1498 * copy of udev?). Don't let open() calls through here until
1499 * initialization is finished. If userspace can overlap load() and open(),
1500 * then it stands to reason that we might also wind up racing with close()
1501 * and unload() as well, so let's protect all of those operations by
1502 * grabbing the mutex.
1504 * FIXME: Should we do the same for other operations like suspend/resume/etc?
1506 mutex_lock(&dev->struct_mutex);
1508 /* The is_master flag is set after the call to this function, so there needs
1509 * to be manual check to determine the DRM master */
1510 if(priv->is_master || (!priv->minor->master && !emgd_priv->drm_master_fd)) {
1511 emgd_priv->drm_master_fd = priv;
1514 ret = PVRSRVOpen(dev, priv);
1516 mutex_unlock(&dev->struct_mutex);
1520 } /* emgd_driver_open() */
1524 * This is the drm_driver.lastclose() function. It is called when the last
1525 * user-space process closes/releases the DRM device file. At end of DRM
1526 * drm_release() (in "drm_fops.c"), it calls drm_lastclose() (in "drm_drv.c"),
1527 * which calls this function.
1529 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1531 void emgd_driver_lastclose(struct drm_device *dev)
1533 drm_emgd_priv_t *priv = dev->dev_private;
1534 igd_init_info_t *init_info = priv->init_info;
1536 unsigned long restore_flags = 0;
1540 mutex_lock(&dev->struct_mutex);
1543 if (priv->hal_running) {
1544 if (config_drm.init) {
1547 restore_flags = (IGD_REG_SAVE_ALL & ~IGD_REG_SAVE_GTT)
1548 | IGD_REG_SAVE_TYPE_REG;
1550 if (!config_drm.kms) {
1551 restore_flags &= ~IGD_REG_SAVE_RB;
1555 if (priv->saved_registers == CONSOLE_STATE_SAVED) {
1556 EMGD_DEBUG("Need to restore the console's saved "
1558 drm_HAL_dispatch->driver_save_restore(drm_HAL_handle,
1560 EMGD_DEBUG("State of saved registers is "
1561 "X_SERVER_STATE_SAVED");
1562 priv->saved_registers = X_SERVER_STATE_SAVED;
1565 if (priv->saved_registers == X_SERVER_STATE_SAVED &&
1566 !config_drm.kms && !priv->qb_seamless) {
1567 emgd_init_display(FALSE, priv);
1570 if (priv->saved_registers == CONSOLE_STATE_SAVED) {
1571 EMGD_DEBUG("Need to restore the console's saved register "
1573 drm_HAL_dispatch->driver_save_restore(drm_HAL_handle,
1575 EMGD_DEBUG("State of saved registers is X_SERVER_STATE_SAVED");
1576 priv->saved_registers = X_SERVER_STATE_SAVED;
1579 /* Since an alter_displays() was done, re-init the 3DD: */
1580 if (priv->reinit_3dd) {
1581 priv->reinit_3dd(dev);
1587 /* The X server has quit/crashed. If the console's state is
1588 * currently saved (likely) restore that state, so that the console
1589 * can be seen and work.
1592 priv->dc = 0; /* Don't let the 3DD re-init too early: */
1593 if (priv->saved_registers == CONSOLE_STATE_SAVED) {
1594 EMGD_DEBUG("Need to restore the console's saved register "
1596 restore_flags = IGD_REG_SAVE_ALL;
1598 drm_HAL_dispatch->driver_save_restore(drm_HAL_handle,
1600 EMGD_DEBUG("State of saved registers is X_SERVER_STATE_SAVED");
1601 priv->saved_registers = X_SERVER_STATE_SAVED;
1604 /******************************************************************
1605 * Shutdown and minimally-restart the HAL, so that if/when the X
1606 * server starts again, the HAL will be started again. This will
1607 * allow the necessary port drivers to be loaded, all configuration
1608 * parameters to be used, the EDID to be read again (e.g. because
1609 * the user may have switched monitors), etc.
1611 * However, keeep the DRM driver state around, so that the driver
1612 * can continue to work (i.e. re-enter the state when the DRM
1613 * driver was first loaded).
1615 * Also, keep the PVR services up and going, since it wasn't
1616 * designed to be shutdown and restarted (without doing an
1618 ******************************************************************/
1619 EMGD_DEBUG("Shutting down the HAL");
1621 /* igd_driver_shutdown() will restore the then-currently-saved
1622 * register state. We can't rely on any save_restore() calls
1623 * before that time, because igd_driver_shutdown() does things that
1624 * mess up the register state. Thus, we must allow it to do a
1625 * restore. The only way to control the final state of the
1626 * hardware is to potentially do a save_restore now. Thus, if the
1627 * X server's state is currently saved (i.e. the console's state is
1628 * currently active), we must do a save_restore now, so that this
1629 * state will still exist after igd_driver_shutdown().
1631 if (priv->saved_registers == X_SERVER_STATE_SAVED) {
1632 EMGD_DEBUG("Need to restore the console's saved register "
1634 restore_flags = IGD_REG_SAVE_ALL;
1635 drm_HAL_dispatch->driver_save_restore(drm_HAL_handle,
1637 EMGD_DEBUG("State of saved registers is X_SERVER_STATE_SAVED");
1638 priv->saved_registers = CONSOLE_STATE_SAVED;
1640 msvdx_shutdown_plb(drm_HAL_handle);
1641 igd_driver_shutdown_hal(drm_HAL_handle);
1642 igd_driver_shutdown(drm_HAL_handle);
1644 EMGD_DEBUG("Minimally restarting the HAL--like load-time");
1646 * In order for some early ioctls (e.g. emgd_get_chipset_info()) to
1647 * work, we must do the following minimal initialization.
1649 EMGD_DEBUG("Calling igd_driver_init()");
1650 if(init_info == NULL){
1651 init_info = (igd_init_info_t *)OS_ALLOC(sizeof(igd_init_info_t));
1653 drm_HAL_handle = igd_driver_init(init_info);
1654 if (drm_HAL_handle == NULL) {
1655 /* This shouldn't happen, but if it does, alert the user, as
1656 * the only thing to do is to rmmod/insmod emgd.ko, or to
1660 printk(KERN_ALERT "[EMGD] Failed to restart the EMGD graphics "
1662 mutex_unlock(&dev->struct_mutex);
1666 /* Get the HAL context and give it to the ioctl-handling "bridge"
1669 drm_HAL_context = (igd_context_t *) drm_HAL_handle;
1670 emgd_set_real_handle(drm_HAL_handle);
1672 /* Save the drm dev pointer, it's needed by igd_module_init */
1673 drm_HAL_context->drm_dev = dev;
1675 /* Reset part of the private structure used to communicate to the
1676 * IMG 3rd-party display driver:
1678 priv->saved_registers = 0;
1679 priv->suspended_state = NULL;
1680 priv->must_power_on_ports = 0;
1681 priv->xserver_running = 0;
1682 priv->primary_port_number = 0;
1683 priv->primary = NULL;
1684 priv->secondary_port_number = 0;
1685 priv->secondary = NULL;
1686 priv->msvdx_private = NULL;
1687 priv->hal_running = 0;
1688 priv->context = drm_HAL_context;
1689 priv->init_info = init_info;
1692 /* Do basic driver initialization & configuration: */
1693 EMGD_DEBUG("Calling igd_driver_config()");
1694 err = igd_driver_config(drm_HAL_handle);
1696 /* This shouldn't happen, but if it does, alert the user, as
1697 * the only thing to do is to rmmod/insmod emgd.ko, or to
1701 printk(KERN_ALERT "[EMGD] Failed to restart the EMGD graphics "
1703 mutex_unlock(&dev->struct_mutex);
1707 /* To ensure the devinfo->interrupt_h is NULL, call the
1710 if (priv->reinit_3dd) {
1711 priv->reinit_3dd(dev);
1716 mutex_unlock(&dev->struct_mutex );
1720 } /* emgd_driver_lastclose() */
1724 * This is the drm_driver.preclose() function. It is called when a user-space
1725 * process closes/releases the DRM device file. At the very start of DRM
1726 * drm_release() (in "drm_fops.c"), it calls this function, before it does any
1727 * real work (other than get the lock).
1729 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1730 * @param priv (IN) DRM's file private data struct (in "drmP.h")
1732 void emgd_driver_preclose(struct drm_device *dev, struct drm_file *priv)
1734 drm_emgd_priv_t *emgd_priv = dev->dev_private;
1736 /* Notes on what to implement in this function. What this
1737 * function does is largely influenced by when/why this can be called:
1739 * - We can determine whether the connection was for the X driver vs. for a
1740 * 3D application, because the X driver should be the master.
1742 * - If there's any state management we need to take care of (e.g. if the
1743 * X server crashes while there are still 3D app's running), this is
1744 * probably a good place to do it.
1746 * - Normal 3D app shutdown is probably best done here too (simply
1747 * because we can tell it's a 3D connection, and do our work before the
1748 * general drm_release() code does its work.
1750 * - We don't yet know what the IMG 3D code is going to need.
1752 * We don't yet know what we need to do for the IMG code. Thus, I'm
1753 * inclined to leave this function a stub for now.
1757 mutex_lock(&dev->struct_mutex);
1758 if ((emgd_priv->hal_running) && priv->is_master && drm_HAL_dispatch) {
1759 /* The X server can't call gmm_cache_flush() nor igd_driver_shutdown()
1760 * after DRICloseScreen() closes the connection with the DRM. However,
1761 * we can tell on this side of the connection (because the X server is
1762 * the master) that it is closing down. There is no need to truly shut
1763 * down the HAL, but we can flush the GMM cache and reset the display
1764 * hardware to a known state/mode:
1766 drm_HAL_dispatch->gmm_flush_cache();
1768 /* TODO - WRITE CODE THAT PUTS THE DISPLAY HW IN A KNOWN STATE/MODE */
1771 if (emgd_priv->drm_master_fd == priv)
1772 emgd_priv->drm_master_fd = NULL;
1774 mutex_unlock(&dev->struct_mutex);
1777 /* TODO -- ADD ANYTHING WE DISCOVER WE NEED AFTER THE IMG TRAINING */
1779 } /* emgd_driver_preclose() */
1783 * This is the drm_driver.postclose() function. It is called when a user-space
1784 * process closes/releases the DRM device file. At the end of DRM
1785 * drm_release() (in "drm_fops.c"), but before drm_lastclose is optionally
1786 * called, it calls this function.
1788 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1789 * @param priv (IN) DRM's file private data struct (in "drmP.h")
1791 void emgd_driver_postclose(struct drm_device *dev, struct drm_file *priv)
1794 drm_emgd_priv_t *dev_priv = dev->dev_private;
1795 igd_context_t *context = dev_priv->context;
1798 mutex_lock(&dev->struct_mutex);
1800 /* Calling the msvdx_postclose_check before PVRSRVRelease */
1802 msvdx_postclose_check(context, (void *) priv);
1805 ret = PVRSRVRelease(dev, priv);
1807 mutex_unlock(&dev->struct_mutex);
1809 } /* emgd_driver_postclose() */
1813 * This is the drm_driver.suspend() function. It appears to support what the
1814 * Linux "pm.h" file calls "the legacy suspend framework." The DRM
1815 * drm_class_suspend() (in "drm_sysfs.c", which implements the Linux
1816 * class.suspend() function defined in "device.h") calls this function if
1817 * conditions are met, such as drm_minor->type is DRM_MINOR_LEGACY and the
1818 * driver doesn't have the DRIVER_MODESET (i.e. KMS--Kernel Mode Setting)
1821 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1822 * @param state (IN) What power state to put the device in (in "pm.h")
1824 * @return 0 on Success
1825 * @return <0 on Error
1827 int emgd_driver_suspend(struct drm_device *dev, pm_message_t state)
1830 unsigned int pwr_state;
1831 drm_emgd_priv_t *priv = dev->dev_private;
1836 mutex_lock(&dev->struct_mutex);
1838 /* When the system is suspended, the X server does a VT switch, which saves
1839 * the register state of the X server, and restores the console's register
1840 * state. This code saves the console's register state, so that after the
1841 * system resumes, VT switches to the console can occur.
1843 if (priv->hal_running) {
1844 EMGD_DEBUG("Saving the console's register state");
1845 priv->suspended_state =
1846 drm_HAL_context->mod_dispatch.reg_alloc(drm_HAL_context,
1848 if (priv->suspended_state) {
1850 //Flag CDVO is not needed
1851 if (state.event == PM_EVENT_SUSPEND){
1852 if (drm_HAL_context->mod_dispatch.flag_cdvo!= NULL){
1853 drm_HAL_context->mod_dispatch.flag_cdvo(drm_HAL_context);
1857 drm_HAL_context->mod_dispatch.reg_save(drm_HAL_context,
1858 priv->suspended_state);
1862 /* Map the pm_message_t event states to HAL states: */
1863 switch (state.event) {
1864 case PM_EVENT_PRETHAW:
1865 case PM_EVENT_FREEZE:
1866 pwr_state = IGD_POWERSTATE_D1;
1868 case PM_EVENT_HIBERNATE:
1869 pwr_state = IGD_POWERSTATE_D3;
1871 case PM_EVENT_SUSPEND:
1873 pwr_state = IGD_POWERSTATE_D2;
1875 } /* switch (state) */
1877 EMGD_DEBUG("Calling pwr_alter()");
1878 ret = drm_HAL_dispatch->pwr_alter(drm_HAL_handle, pwr_state);
1879 EMGD_DEBUG("pwr_alter() returned %d", ret);
1882 EMGD_DEBUG("Calling PVRSRVDriverSuspend()");
1883 ret = PVRSRVDriverSuspend(dev, state);
1884 EMGD_DEBUG("PVRSRVDriverSuspend() returned %d", ret);
1887 EMGD_DEBUG("Returning %d", ret);
1888 mutex_unlock(&dev->struct_mutex);
1892 } /* emgd_driver_suspend() */
1896 * This is the drm_driver.resume() function. It appears to support what the
1897 * Linux "pm.h" file calls "the legacy suspend framework." The DRM
1898 * drm_class_resume() (in "drm_sysfs.c", which implements the Linux
1899 * class.suspend() function defined in "device.h") calls this function if
1900 * conditions are met, such as drm_minor->type is DRM_MINOR_LEGACY and the
1901 * driver doesn't have the DRIVER_MODESET feature set.
1903 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1905 * @return 0 on Success
1906 * @return <0 on Error
1908 int emgd_driver_resume(struct drm_device *dev)
1911 drm_emgd_priv_t *priv = dev->dev_private;
1915 mutex_lock(&dev->struct_mutex);
1917 EMGD_DEBUG("Calling pwr_alter()");
1918 ret = drm_HAL_dispatch->pwr_alter(drm_HAL_handle, IGD_POWERSTATE_D0);
1919 EMGD_DEBUG("pwr_alter() returned %d", ret);
1922 EMGD_DEBUG("Calling PVRSRVDriverResume()");
1923 ret = PVRSRVDriverResume(dev);
1924 EMGD_DEBUG("PVRSRVDriverResume() returned %d", ret);
1927 /* Restore the register state of the console, so that after the X server is
1928 * back up, VT switches to the console can occur.
1930 if (priv->hal_running) {
1931 EMGD_DEBUG("Restoring the console's register state");
1932 if (priv->suspended_state) {
1933 drm_HAL_context->mod_dispatch.reg_restore(drm_HAL_context,
1934 priv->suspended_state);
1935 drm_HAL_context->mod_dispatch.reg_free(drm_HAL_context,
1936 priv->suspended_state);
1937 priv->suspended_state = NULL;
1941 EMGD_DEBUG("Returning %d", ret);
1942 mutex_unlock(&dev->struct_mutex);
1945 } /* emgd_driver_resume() */
1949 * This is the drm_driver.device_is_agp() function. It is called as a part of
1950 * drm_init() (before the drm_driver.load() function), and is "typically used
1951 * to determine if a card is really attached to AGP or not" (see the Doxygen
1952 * comment for this function in "drmP.h"). It is actually called by the
1953 * inline'd DRM procedure, drm_device_is_agp() (in "drmP.h").
1955 * The Intel open source driver states that all Intel graphics devices are
1956 * treated as AGP. However, the EMGD driver provides its own management of the
1957 * GTT tables, and so doesn't need AGP GART driver support. Thus, this
1958 * function always returns 0.
1960 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1962 * @return 0 the graphics "card" is absolutely not AGP.
1963 * @return 1 the graphics "card" is AGP.
1964 * @return 2 the graphics "card" may or may not be AGP.
1966 int emgd_driver_device_is_agp(struct drm_device *dev)
1968 EMGD_DEBUG("[EMGD] Returning 0 from emgd_driver_device_is_agp()\n");
1970 } /* emgd_driver_device_is_agp() */
1975 * This is the drm_driver.get_vblank_counter() function. It is called to get
1976 * the raw hardware vblank counter. There are 4 places within "drm_irq.c" that
1977 * call this function.
1979 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1980 * @param crtc_select (IN) Exactly how this is derived is unclear, but
1981 * for now we are assuming that it is the order
1982 * in which the CRTCs were creatd. So 0 for
1983 * the first CRTC, 1 for the second, and so on.
1985 * @return raw vblank counter value
1987 u32 emgd_driver_get_vblank_counter(struct drm_device *dev, int crtc_select)
1989 struct drm_crtc *crtc;
1990 emgd_crtc_t *cur_emgd_crtc, *selected_emgd_crtc = NULL;
1995 /* Only supported for KMS-enabled driver */
1996 if (!config_drm.kms) {
1997 /* Since we have previously returned 0 for our non-KMS driver,
1998 * this is left in to prevent any unforeseen problems. */
2004 /* Find the CRTC associated with the */
2005 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2006 cur_emgd_crtc = container_of(crtc, emgd_crtc_t, base);
2008 if ((1 << crtc_select) == cur_emgd_crtc->crtc_id) {
2009 selected_emgd_crtc = cur_emgd_crtc;
2014 if (NULL == selected_emgd_crtc) {
2015 EMGD_ERROR_EXIT("Invalid CRTC selected.");
2021 return mode_context->kms_dispatch->kms_get_vblank_counter(
2022 selected_emgd_crtc);
2023 } /* emgd_driver_get_vblank_counter() */
2028 * This is the drm_driver.enable_vblank() function. It is called by
2029 * drm_vblank_get() (in "drm_irq.c") to enable vblank interrupt events.
2030 * This function is only available for KMS
2032 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2033 * @param crtc_select (IN) Exactly how this is derived is unclear, but
2034 * for now we are assuming that it is the order
2035 * in which the CRTCs were creatd. So 0 for
2036 * the first CRTC, 1 for the second, and so on.
2038 * @return 0 on Success
2039 * @return <0 if the given crtc's vblank interrupt cannot be enabled
2041 int emgd_driver_enable_vblank(struct drm_device *dev, int crtc_select)
2043 struct drm_crtc *crtc;
2044 unsigned char *mmio;
2045 emgd_crtc_t *cur_emgd_crtc, *selected_emgd_crtc = NULL;
2046 unsigned long request_for;
2051 /* Only supported for KMS-enabled driver */
2052 if (!config_drm.kms) {
2053 /* We should return an error here since this is not
2054 * supported. However, since we have previously returned 0
2055 * for our non-KMS driver, this is left in to prevent any
2056 * unforeseen problems. */
2062 /* Find the CRTC associated with the */
2063 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2064 cur_emgd_crtc = container_of(crtc, emgd_crtc_t, base);
2066 if ((1 << crtc_select) == cur_emgd_crtc->crtc_id) {
2067 selected_emgd_crtc = cur_emgd_crtc;
2072 if (NULL == selected_emgd_crtc) {
2073 EMGD_ERROR_EXIT("Invalid CRTC selected.");
2078 switch (selected_emgd_crtc->igd_pipe->pipe_features & IGD_PORT_MASK) {
2079 case IGD_PORT_SHARE_LVDS:
2080 request_for = VBLANK_INT4_PORT4;
2083 case IGD_PORT_SHARE_DIGITAL:
2084 request_for = VBLANK_INT4_PORT2;
2088 EMGD_DEBUG("Unsupported port type");
2095 mmio = EMGD_MMIO(mode_context->context->device_context.virt_mmadr);
2096 ret = mode_context->dispatch->full->request_vblanks(request_for, mmio);
2099 EMGD_DEBUG("Failed to enable vblank");
2105 } /* emgd_driver_enable_vblank() */
2110 * This is the drm_driver.disable_vblank() function. It is called by
2111 * vblank_disable_fn() (in "drm_irq.c") to disable vblank interrupt events.
2113 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2114 * @param crtc_select (IN) Exactly how this is derived is unclear, but
2115 * for now we are assuming that it is the order
2116 * in which the CRTCs were creatd. So 0 for
2117 * the first CRTC, 1 for the second, and so on.
2119 void emgd_driver_disable_vblank(struct drm_device *dev, int crtc_select)
2121 struct drm_crtc *crtc;
2122 unsigned char *mmio;
2123 emgd_crtc_t *cur_emgd_crtc, *selected_emgd_crtc = NULL;
2124 unsigned long request_for;
2130 /* Only supported for KMS-enabled driver */
2131 if (!config_drm.kms) {
2137 /* Find the CRTC associated with the */
2138 list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
2139 cur_emgd_crtc = container_of(crtc, emgd_crtc_t, base);
2141 if ((1 << crtc_select) == cur_emgd_crtc->crtc_id) {
2142 selected_emgd_crtc = cur_emgd_crtc;
2147 if (NULL == selected_emgd_crtc) {
2148 EMGD_ERROR_EXIT("Invalid CRTC selected.");
2153 switch (selected_emgd_crtc->igd_pipe->pipe_features & IGD_PORT_MASK) {
2154 case IGD_PORT_SHARE_LVDS:
2155 request_for = VBLANK_INT4_PORT4;
2158 case IGD_PORT_SHARE_DIGITAL:
2159 request_for = VBLANK_INT4_PORT2;
2163 EMGD_DEBUG("Unsupported port type");
2170 mmio = EMGD_MMIO(mode_context->context->device_context.virt_mmadr);
2171 ret = mode_context->dispatch->full->end_request(request_for, mmio);
2174 EMGD_DEBUG("Failed to disable vblank");
2180 } /* emgd_driver_disable_vblank() */
2185 * This is the drm_driver.irq_preinstall() function. It is called by
2186 * drm_irq_install() (in "drm_irq.c") before it installs this driver's IRQ
2187 * handler (i.e. emgd_driver_irq_handler()).
2189 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2191 void emgd_driver_irq_preinstall(struct drm_device *dev)
2193 /* Notes on what to implement in this function:
2195 * - Ditto the notes in emgd_driver_enable_vblank().
2197 * - In addition, I'll note that I see a HAL interface that roughly
2198 * corresponds to this functionality--the interrupt_install() and
2199 * interrupt_uninstall() entry points in igd_dispatch_t (in "igd.h" and
2200 * better defined in "igd_interrupt.h"). However:
2202 * - There are no "plb" versions of this code, only "alm", "nap" & "wht".
2204 * - These install a passed-in interrupt handler. As far as I can see
2205 * in the ssigd tree, these routines are never called, and no
2206 * interrupt handlers exist.
2208 * - Koheo doesn't contain the hal/core/interrupt code. I'm not sure
2209 * what that does, but grep'ing through the source shows a number of
2210 * lines about irq's.
2212 * - The open source Intel driver has some code that implements this. It's
2213 * not small, so I haven't really studied it yet. Can/should we go with
2214 * a similar approach, or keep like the current HAL approach and
2215 * structure some new entrypoints that allow future hardware to be
2219 /* TODO -- REPLACE THIS STUB WITH A REAL IMPLEMENTATION */
2220 printk(KERN_INFO "[EMGD] Inside of STUBBED %s()", __FUNCTION__);
2222 } /* emgd_driver_irq_preinstall() */
2226 * This is the drm_driver.irq_postinstall() function. It is called by
2227 * drm_irq_install() (in "drm_irq.c") after it installs this driver's IRQ
2228 * handler (i.e. emgd_driver_irq_handler()).
2230 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2232 * @return 0 on Success
2233 * @return <0 if the given crtc's vblank interrupt cannot be enabled
2235 int emgd_driver_irq_postinstall(struct drm_device *dev)
2238 } /* emgd_driver_irq_postinstall() */
2242 * This is the drm_driver.irq_uninstall() function. It is called by
2243 * drm_irq_install() (in "drm_irq.c") as a part of uninstalling this driver's
2244 * IRQ handler (i.e. emgd_driver_irq_handler()).
2246 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2248 void emgd_driver_irq_uninstall(struct drm_device *dev)
2250 /* TODO -- REPLACE THIS STUB WITH A REAL IMPLEMENTATION THE IMG TRAINING */
2251 printk(KERN_INFO "[EMGD] Inside of STUBBED %s()", __FUNCTION__);
2253 } /* emgd_driver_irq_uninstall() */
2257 * This is the drm_driver.irq_handler() function, and is a Linux IRQ interrupt
2258 * handler (see the irq_handler_t in the Linux header "interrupt.h"). It is
2259 * installed by drm_irq_install() (in "drm_irq.c") by calling request_irq()
2260 * (implemented in "interrupt.h") with this function as the 2nd parameter. The
2261 * return type is an enum (see the Linux header "irqreturn.h").
2263 * Our HAL will have already installed an IRQ handler, so we do nothing here.
2265 * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2267 * @return IRQ_NONE if the interrupt was not from this device
2268 * @return IRQ_HANDLED if the interrupt was handled by this device
2269 * @return IRQ_WAKE_THREAD if this handler requests to wake the handler thread
2271 irqreturn_t emgd_driver_irq_handler(int irq, void *arg)
2273 /* TODO -- REPLACE THIS STUB WITH A REAL IMPLEMENTATION THE IMG TRAINING */
2274 printk(KERN_INFO "[EMGD] Inside of STUBBED %s()", __FUNCTION__);
2277 } /* emgd_driver_irq_handler() */
2280 static int __devinit emgd_pci_probe(struct pci_dev *pdev,
2281 const struct pci_device_id *ent)
2283 if (PCI_FUNC(pdev->devfn)) {
2288 * Name changed at some point in time. 2.6.35 uses drm_get_dev
2289 * and 2.6.38 uses drm_get_pci_dev Need to figure what kernel
2290 * version this changed.
2292 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
2293 return drm_get_pci_dev(pdev, ent, &driver);
2295 return drm_get_dev(pdev, ent, &driver);
2299 static void emgd_pci_remove(struct pci_dev *pdev)
2301 struct drm_device *dev = pci_get_drvdata(pdev);
2306 static int emgd_pm_suspend(struct device *dev)
2311 static int emgd_pm_resume(struct device *dev)
2316 static int emgd_pm_freeze(struct device *dev)
2321 static int emgd_pm_thaw(struct device *dev)
2326 static int emgd_pm_poweroff(struct device *dev)
2331 static int emgd_pm_restore(struct device *dev)
2336 static const struct dev_pm_ops emgd_pm_ops = {
2337 .suspend = emgd_pm_suspend,
2338 .resume = emgd_pm_resume,
2339 .freeze = emgd_pm_freeze,
2340 .thaw = emgd_pm_thaw,
2341 .poweroff = emgd_pm_poweroff,
2342 .restore = emgd_pm_restore,
2346 * NOTE: The remainder of this file is standard kernel module initialization
2352 * Older kernels kept the PCI driver information directly in the
2353 * DRM driver structure. Newer kernels (2.6.38-rc3 and beyond)
2354 * move it outside of the DRM driver structure and pass it to
2355 * drm_pci_init instead in order to help pave the way for
2356 * USB graphics devices.
2358 #define EMGD_PCI_DRIVER { \
2359 .name = DRIVER_NAME, \
2360 .id_table = pciidlist, \
2361 .probe = emgd_pci_probe, \
2362 .remove = emgd_pci_remove, \
2363 .driver.pm = &emgd_pm_ops, \
2366 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
2367 static struct pci_driver emgd_pci_driver = EMGD_PCI_DRIVER;
2370 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
2371 #define IOCTL unlocked_ioctl
2376 #define EMGD_FOPS { \
2377 .owner = THIS_MODULE, \
2379 .release = drm_release, \
2380 .IOCTL = drm_ioctl, \
2381 .mmap = emgd_mmap, \
2383 .fasync = drm_fasync, \
2387 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
2388 static const struct file_operations emgd_driver_fops = EMGD_FOPS;
2392 * DRM Sub driver entry points
2394 static struct drm_driver driver = {
2395 .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED,
2396 .load = emgd_driver_load,
2397 .unload = emgd_driver_unload,
2398 .open = emgd_driver_open,
2399 .lastclose = emgd_driver_lastclose,
2400 .preclose = emgd_driver_preclose,
2401 .postclose = emgd_driver_postclose,
2402 .suspend = emgd_driver_suspend,
2403 .resume = emgd_driver_resume,
2404 .device_is_agp = emgd_driver_device_is_agp,
2405 .get_vblank_counter = emgd_driver_get_vblank_counter,
2406 .enable_vblank = emgd_driver_enable_vblank,
2407 .disable_vblank = emgd_driver_disable_vblank,
2408 .irq_preinstall = emgd_driver_irq_preinstall,
2409 .irq_postinstall = emgd_driver_irq_postinstall,
2410 .irq_uninstall = emgd_driver_irq_uninstall,
2411 .irq_handler = emgd_driver_irq_handler,
2412 .reclaim_buffers = drm_core_reclaim_buffers,
2413 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,37)
2414 .get_map_ofs = drm_core_get_map_ofs,
2415 .get_reg_ofs = drm_core_get_reg_ofs,
2417 .ioctls = emgd_ioctl,
2418 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
2419 .fops = &emgd_driver_fops,
2424 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
2425 .pci_driver = EMGD_PCI_DRIVER,
2427 .name = DRIVER_NAME,
2428 .desc = DRIVER_DESC,
2429 .date = DRIVER_DATE,
2430 .major = DRIVER_MAJOR,
2431 .minor = DRIVER_MINOR,
2432 .patchlevel = DRIVER_PATCHLEVEL,
2436 * Standard procedure to initialize this kernel module when it is loaded.
2438 static int __init emgd_init(void) {
2440 struct pci_dev *our_device;
2442 printk(KERN_INFO "[EMGD] Initializing Driver.\n");
2443 driver.num_ioctls = emgd_max_ioctl;
2445 /* If init == 1 then we should always set KMS to 0 for US15 */
2447 if(config_drm.init || drm_emgd_init == 1){
2449 /* Detecting device */
2452 * 0x8086 is the intel vendor id and 0x8108 is the
2454 * pci_get_device returns NULL if it is not a PLB.
2457 our_device = pci_get_device(PCI_VENDOR_ID_INTEL,
2458 PCI_DEVICE_ID_VGA_PLB, NULL);
2461 EMGD_ERROR("US15 detected. Setting KMS to 0 "
2462 "config_drm.kms = %d ", config_drm.kms);
2467 if (config_drm.kms && (config_drm.init || drm_emgd_init == 1)) {
2468 driver.driver_features |= DRIVER_MODESET;
2473 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
2474 ret = drm_pci_init(&driver, &emgd_pci_driver);
2476 ret = drm_init(&driver);
2478 printk(KERN_INFO "[EMGD] Driver Initialized.\n");
2484 * Standard procedure to clean-up this kernel module before it exits & unloads.
2486 static void __exit emgd_exit(void) {
2488 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
2489 drm_pci_exit(&driver, &emgd_pci_driver);
2497 module_init(emgd_init);
2498 module_exit(emgd_exit);
2500 MODULE_AUTHOR(DRIVER_AUTHOR);
2501 MODULE_DESCRIPTION(DRIVER_DESC);
2502 MODULE_LICENSE("GPL and additional rights");