c8709cf94b88ef9a0f0cda941bd61ef5845b955a
[profile/ivi/intel-emgd-kmod.git] / emgd / drm / emgd_drv.c
1 /*
2  *-----------------------------------------------------------------------------
3  * Filename: emgd_drv.c
4  * $Revision: 1.147 $
5  *-----------------------------------------------------------------------------
6  * Copyright (c) 2002-2010, Intel Corporation.
7  *
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:
14  *
15  * The above copyright notice and this permission notice shall be included in
16  * all copies or substantial portions of the Software.
17  *
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
24  * THE SOFTWARE.
25  *
26  *-----------------------------------------------------------------------------
27  * Description:
28  *  The main part of the kernel module.  This part gets everything going and
29  *  connected, and then the rest can function.
30  *-----------------------------------------------------------------------------
31  */
32
33 #define MODULE_NAME hal.oal
34
35 #include <drm/drmP.h>
36 #include <drm/drm.h>
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>
42 #include <intelpci.h>
43 #include "drm_emgd_private.h"
44 #include "user_config.h"
45 #include "emgd_drv.h"
46 #include "emgd_drm.h"
47 #include "memory.h"
48 #include "io.h"
49 #include "mode_dispatch.h"
50 #include "igd_debug.h"
51 #include "splash_screen.h"
52 #include "msvdx.h"
53 /*
54  * Imagination includes.
55  */
56 #include <img_types.h>
57 #include <pvr_drm.h>
58 #include <pvr_drm_shared.h>
59 #include <pvr_bridge.h>
60 #include <linkage.h>
61 #include <sysconfig.h>
62
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>
67 #endif
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);
72
73 /*------------------------------------------------------------------------------
74  * Formal Declaration
75  *------------------------------------------------------------------------------
76  */
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;
85
86 /* This must be defined whether debug or release build */
87 igd_debug_t emgd_debug_flag = {
88         {
89                 CONFIG_DEBUG_FLAGS
90         }
91 };
92 igd_debug_t *emgd_debug = &emgd_debug_flag;
93
94 #ifdef DEBUG_BUILD_TYPE
95
96 MODULE_PARM_DESC(debug_cmd, "Debug: cmd");
97 module_param_named(debug_cmd, emgd_debug_flag.hal.cmd, short, 0600);
98
99 MODULE_PARM_DESC(debug_dsp, "Debug: dsp");
100 module_param_named(debug_dsp, emgd_debug_flag.hal.dsp, short, 0600);
101
102 MODULE_PARM_DESC(debug_mode, "Debug: mode");
103 module_param_named(debug_mode, emgd_debug_flag.hal.mode, short, 0600);
104
105 MODULE_PARM_DESC(debug_init, "Debug: init");
106 module_param_named(debug_init, emgd_debug_flag.hal.init, short, 0600);
107
108 MODULE_PARM_DESC(debug_overlay, "Debug: overlay");
109 module_param_named(debug_overlay, emgd_debug_flag.hal.overlay, short, 0600);
110
111 MODULE_PARM_DESC(debug_power, "Debug: power");
112 module_param_named(debug_power, emgd_debug_flag.hal.power, short, 0600);
113
114 MODULE_PARM_DESC(debug_2D, "Debug: 2D");
115 module_param_named(debug_2D, emgd_debug_flag.hal._2d, short, 0600);
116
117 MODULE_PARM_DESC(debug_blend, "Debug: blend");
118 module_param_named(debug_blend, emgd_debug_flag.hal.blend, short, 0600);
119
120 MODULE_PARM_DESC(debug_state, "Debug: state");
121 module_param_named(debug_state, emgd_debug_flag.hal.state, short, 0600);
122
123 MODULE_PARM_DESC(debug_gmm, "Debug: GMM");
124 module_param_named(debug_gmm, emgd_debug_flag.hal.gmm, short, 0600);
125
126 MODULE_PARM_DESC(debug_gart, "Debug: GART");
127 module_param_named(debug_gart, emgd_debug_flag.hal.gart, short, 0600);
128
129 MODULE_PARM_DESC(debug_oal, "Debug: OAL");
130 module_param_named(debug_oal, emgd_debug_flag.hal.oal, short, 0600);
131
132 MODULE_PARM_DESC(debug_intr, "Debug: intr");
133 module_param_named(debug_intr, emgd_debug_flag.hal.intr, short, 0600);
134
135 MODULE_PARM_DESC(debug_dpd, "Debug: dpd");
136 module_param_named(debug_dpd, emgd_debug_flag.hal.dpd, short, 0600);
137
138 MODULE_PARM_DESC(debug_video, "Debug: video");
139 module_param_named(debug_video, emgd_debug_flag.hal.video, short, 0600);
140
141 MODULE_PARM_DESC(debug_pvr3dd, "Debug: PVR3DD");
142 module_param_named(debug_pvr3dd, emgd_debug_flag.hal.pvr3dd, short, 0600);
143
144 MODULE_PARM_DESC(debug_trace, "Global Debug: trace");
145 module_param_named(debug_trace, emgd_debug_flag.hal.trace, short, 0600);
146
147 MODULE_PARM_DESC(debug_instr, "Global Debug: instr");
148 module_param_named(debug_instr, emgd_debug_flag.hal.instr, short, 0600);
149
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);
152
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);
155
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);
158
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);
161
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);
164
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);
167
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);
170 #endif
171
172
173 static struct drm_driver driver;  /* TODO: what? */
174
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.
179  *
180  * Note: The initial values are all set to -1, so that we can tell if the user
181  * set them.
182  */
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. "
193         "\"1\")");
194 MODULE_PARM_DESC(init, "Whether to initialize the display at startup (1=yes, "
195         "0=no)");
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,
201         0600);
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);
208
209
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;
219
220 /**
221  * The primary fb_info to use when the DRM module [re-]initializes the display.
222  */
223 igd_framebuffer_info_t *primary_fb_info;
224 /**
225  * The secondary fb_info to use when the DRM module [re-]initializes the
226  * display.
227  */
228 igd_framebuffer_info_t *secondary_fb_info;
229 /**
230  * The primary display structure (filled in by alter_displays()) to use when
231  * the DRM module [re-]initializes the display.
232  */
233 igd_display_h primary;
234 /**
235  * The secondary display structure (filled in by alter_displays()) to use when
236  * the DRM module [re-]initializes the display.
237  */
238 igd_display_h secondary;
239 /**
240  * The display information to use when the DRM module [re-]initializes the
241  * display.
242  */
243 igd_display_info_t pt_info;
244 extern mode_context_t mode_context[1];
245
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;
250 #endif
251
252
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}, \
257     {0, 0, 0}
258
259 static struct pci_device_id pciidlist[] = {
260             emgd_PCI_IDS
261 };
262
263 /*
264  * To use DRM_IOCTL_DEF, the first arg should be the local (zero based)
265  * IOCTL number, not the global number.
266  */
267 #define EMGD_IOCTL_DEF(ioctl, _func, _flags) \
268         [DRM_IOCTL_NR(ioctl) - DRM_COMMAND_BASE] = \
269                 {.cmd = ioctl, .func = _func, .flags = _flags}
270
271 static struct drm_ioctl_desc emgd_ioctl[] = {
272         /*
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.
282          *
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,
286          * one by one.
287          */
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.
297          */
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.
309          */
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),
333         /*
334          * Externally handled IOCTL's. These are routed to the Imagination Tech
335          * kernel services.
336          *   function prototypes in services4/srvkm/env/linux/pvr_drm.h
337          */
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),
343
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),
364         /*
365          * For PDUMP
366          */
367 #if defined(PDUMP)
368         EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_6, dbgdrv_ioctl, 0),
369 #else
370         EMGD_IOCTL_DEF(DRM_IOCTL_IGD_RESERVED_6, NULL, 0),
371 #endif
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),
393
394         /*
395          * For VIDEO (MSVDX/TOPAZ
396          */
397         EMGD_IOCTL_DEF(DRM_IOCTL_IGD_VIDEO_CMD_BUF, emgd_video_cmd_buf,
398                         DRM_UNLOCKED),
399         EMGD_IOCTL_DEF(DRM_IOCTL_IGD_INIT_VIDEO, emgd_init_video,
400                         DRM_UNLOCKED),
401         EMGD_IOCTL_DEF(DRM_IOCTL_IGD_GET_DEVICE_INFO, emgd_get_device_info,
402                         DRM_UNLOCKED),
403         EMGD_IOCTL_DEF(DRM_IOCTL_IGD_VIDEO_GET_INFO, emgd_video_get_info,
404                         DRM_UNLOCKED),
405         EMGD_IOCTL_DEF(DRM_IOCTL_IGD_VIDEO_FLUSH_TLB, emgd_video_flush_tlb,
406                         DRM_UNLOCKED),
407
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),
423 };
424
425 static int emgd_max_ioctl = DRM_ARRAY_SIZE(emgd_ioctl);
426
427
428
429 /*
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:
432  */
433
434
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;
438
439
440 /**
441  * The driver handle for talking with the HAL, within the DRM/kernel code.
442  *
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
445  * handle.
446  */
447 static igd_driver_h drm_HAL_handle = NULL;
448
449 /**
450  * This is the drm_HAL_handle cast to an igd_context_t.  It is cached for quick
451  * access.
452  */
453 static igd_context_t *drm_HAL_context = NULL;
454
455 /**
456  * This is the dispatch table for the HAL.  It is cached for quick access.
457  */
458 static igd_dispatch_t *drm_HAL_dispatch = NULL;
459
460
461
462 /*!
463  * get_pre_driver_info
464  *
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
469  *        to "pre_drv_info"
470  *
471  * @param mode_context This is where fw_info is stored
472  *
473  * @return -IGD_INVAL on failure
474  * @return 0 on success
475  */
476 static int get_pre_driver_info(mode_context_t *mode_context)
477 {
478         int ret = 0;
479         int seamless = FALSE;
480         EMGD_TRACE_ENTER;
481
482         if(mode_context->fw_info != NULL) {
483                 seamless = TRUE;
484
485                 ret = mode_context->dispatch->full->get_plane_info();
486                 if(ret) {
487                         seamless = FALSE;
488                 }
489
490                 ret = mode_context->dispatch->full->get_pipe_info(primary);
491                 if(ret) {
492                         seamless = FALSE;
493                 }
494
495                 ret = mode_context->dispatch->full->get_port_info();
496                 if(ret) {
497                         seamless = FALSE;
498                 }
499
500         }
501
502         if(seamless == FALSE) {
503                 /* If one of these plane/pipe/port functions
504                  *  returns an error, we explicitly
505                  *  turn-off seamless.
506                  */
507                  mode_context->seamless = FALSE;
508
509         }
510         EMGD_TRACE_EXIT;
511         return 0;
512 }
513
514
515
516 /**
517  * A helper function that prints the igd_param_t struct.
518  *
519  * @param params (IN) The the igd_param_t struct to print
520  */
521 void emgd_print_params(igd_param_t *params)
522 {
523         int i;
524
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]);
536         }
537         EMGD_DEBUG(" display_params:");
538         for (i = 0 ; i < IGD_MAX_PORTS; i++) {
539                 int j;
540
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);
623                 }
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);
634                 }
635         }
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() */
644
645
646 /**
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().
651  *
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.
654  *
655  * @return 0 on Success
656  * @return <0 on Error
657  */
658 int emgd_startup_hal(struct drm_device *dev, igd_param_t *params)
659 {
660         drm_emgd_priv_t *priv = dev->dev_private;
661         int err = 0;
662
663         EMGD_TRACE_ENTER;
664
665
666         /* Initialize the various HAL modules: */
667         EMGD_DEBUG("Calling igd_module_init()");
668
669         err = igd_module_init(drm_HAL_handle, &drm_HAL_dispatch, params);
670         if (err != 0) {
671                 return -EIO;
672         }
673
674         /* Give the dispatch table to the ioctl-handling "bridge" code: */
675         emgd_set_real_dispatch(drm_HAL_dispatch);
676
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;
681
682         /* Since PVR services is running, we're restarting the HAL, which
683          * disabled the SGX & MSVDX interrupts.  Need to re-enable those
684          * interrupts:
685          */
686         SysReEnableInterrupts();
687
688         EMGD_TRACE_EXIT;
689
690         return 0;
691 } /* emgd_startup_hal() */
692
693
694
695 /**
696  * A helper function that initializes the display, and potentially merges the
697  * module parameters with the pre-compiled parameters.
698  *
699  * @param merge_mod_params (IN) non-zero if the module parameters should be
700  * merged with the pre-compiled parameters.
701  *
702  */
703 void emgd_init_display(int merge_mod_params, drm_emgd_priv_t *priv)
704 {
705         int                     err         = 0;
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;
713         int temp_dc;
714         EMGD_TRACE_ENTER;
715
716
717         if (merge_mod_params) {
718                 EMGD_DEBUG("Checking other module parameters before initializing the "
719                                 "display");
720
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 "
734                                                 "%d.", drm_emgd_dc);
735                                 EMGD_DEBUG("Overriding and making it 1 (single display).");
736                                 drm_emgd_dc = 1;
737                                 config_drm.dc = drm_emgd_dc;
738                         } else {
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).");
746
747                                         config_drm.dc = 1;
748                                 } else {
749                                         EMGD_ERROR("Will use compile-time setting %d instead "
750                                                 "of invalid value %d.\n", config_drm.dc, drm_emgd_dc);
751                                 }
752                                 drm_emgd_dc = config_drm.dc;
753                         }
754                 } else {
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).");
766                                 config_drm.dc = 1;
767                         } else {
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"
771                                                 " display).");
772                                 config_drm.dc = 1;
773                         }
774                         drm_emgd_dc = config_drm.dc;
775                 }
776
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\"",
783                                         drm_emgd_width);
784                         config_drm.width = drm_emgd_width;
785                 } else {
786                         /* Use the compile-time value: */
787                         drm_emgd_width = config_drm.width;
788                         EMGD_DEBUG("Using the compile-time \"width\" value: \"%d\"",
789                                         drm_emgd_width);
790                 }
791
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\"",
798                                         drm_emgd_height);
799                         config_drm.height = drm_emgd_height;
800                 } else {
801                         /* Use the compile-time value: */
802                         drm_emgd_height = config_drm.height;
803                         EMGD_DEBUG("Using the compile-time \"height\" value: \"%d\"",
804                                         drm_emgd_height);
805                 }
806
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\"",
813                                         drm_emgd_refresh);
814                         config_drm.refresh = drm_emgd_refresh;
815                 } else {
816                         /* Use the compile-time value: */
817                         drm_emgd_refresh = config_drm.refresh;
818                         EMGD_DEBUG("Using the compile-time \"refresh\" value: \"%d\"",
819                                         drm_emgd_refresh);
820                 }
821         }
822
823
824         if (config_drm.kms) {
825                 priv->num_crtc = 2;
826
827
828                 /*************************************
829                  * Initialize kernel mode setting functionality
830                  *************************************/
831                 emgd_modeset_init(priv->ddev);
832
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);
837
838
839                 /*************************************
840                  * Initialize primary_fb_info
841                  *************************************/
842                 framebuffer = list_entry(priv->ddev->mode_config.fb_list.next,
843                                 struct drm_framebuffer, head);
844                 if (!framebuffer) {
845                         EMGD_ERROR("Can't display splash screen/video as there is no fb.");
846                 } else {
847                         emgd_fb = container_of(framebuffer, emgd_framebuffer_t, base);
848                         primary_fb_info = &priv->initfb_info;
849                         if (priv->fbdev) {
850                                 fb = priv->fbdev->screen_base;
851                         }
852                 }
853
854
855                 /*
856                  * Update the private data structure
857                  */
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);
862         } else {
863
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
867                  * (2)
868                  *************************************************************************/
869                 temp_dc = drm_emgd_dc;
870                 if(IGD_DC_VEXT(drm_emgd_dc)) {
871                         temp_dc = IGD_DISPLAY_CONFIG_CLONE;
872                 }
873
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);
881                 if (err) {
882                         EMGD_ERROR_EXIT("Cannot initialize the display as requested.\n"
883                                         "The query_dc() function returned %d.", err);
884                         return;
885                 }
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;
892                 }
893
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);
901                 if (err) {
902                         EMGD_ERROR_EXIT("Cannot initialize the display as requested\n"
903                                         "The query_mode_list() function returned %d.", err);
904                         return;
905                 }
906
907
908                 /*************************************
909                  * Find the desired mode from the list:
910                  *************************************/
911                 EMGD_DEBUG("Comparing the mode list with the desired width, height, and"
912                         " refresh rate...");
913
914                 mode = mode_list;
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!");
922                                 desired_mode = mode;
923                                 break;
924                         }
925                         mode++;
926                 }
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);
932                         return;
933                 } else {
934                         /* Must set this in order to get the timings setup: */
935                         desired_mode->flags |= IGD_DISPLAY_ENABLE;
936                 }
937
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;
944
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;
950                 } else {
951                         primary_fb_info->height = desired_mode->height;
952                 }
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));
958
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,
963                                 *desired_dc, 0);
964                 EMGD_DEBUG("alter_displays() returned %d", err);
965                 if (err) {
966                         EMGD_ERROR_EXIT("Cannot initialize the display as requested.\n"
967                                         "The alter_displays() function returned %d.", err);
968                         return;
969                 }
970
971                 /*
972                  * Update the private data structure with the values we get
973                  * back from alter displays.
974                  */
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);
980
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);
987                 }
988
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);
996                 if (err) {
997                         EMGD_ERROR_EXIT("Cannot initialize the display as requested\n"
998                                         "The get_display() function returned %d.", err);
999                         return;
1000                 }
1001
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);
1008         }
1009
1010         if (fb) {
1011
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;
1019
1020                 /*************************************
1021                  * Display a splash screen if requested by user
1022                  *************************************/
1023                 if(config_drm.ss_data->width &&
1024                                 config_drm.ss_data->height) {
1025
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);
1030                 }
1031
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) {
1041
1042                         /* Display a splash video */
1043                         EMGD_DEBUG("Calling disp_splash_video()");
1044                         disp_splash_video(config_drm.sv_data);
1045                 }
1046         } else {
1047                 EMGD_ERROR("framebuffer base address is 0");
1048         }
1049
1050         if (!config_drm.kms) {
1051                 mode_context->context->dispatch.gmm_unmap(fb);
1052         }
1053         EMGD_TRACE_EXIT;
1054 } /* emgd_init_display() */
1055
1056
1057
1058 /**
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).
1063  *
1064  * @param sv_data (IN) a non null pointer to splash video information like
1065  * width, height etc.
1066  *
1067  * @return 0 on Success
1068  * @return <0 on Error
1069  */
1070 int disp_splash_video(emgd_drm_splash_video_t *sv_data)
1071 {
1072         igd_surface_t surface;
1073         igd_rect_t ovl_rect, surf_rect;
1074         igd_ovl_info_t ovl_info;
1075         unsigned int tmp;
1076
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;
1083
1084         /* Set the surface rect as big as the video frame size */
1085         surf_rect.x1 = 0;
1086         surf_rect.y1 = 0;
1087         surf_rect.x2 = sv_data->src_width;
1088         surf_rect.y2 = sv_data->src_height;
1089
1090
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;
1094
1095         /*
1096          *  NOTE: This for scaling if the hardware supports it.
1097          *  If no dest w x h values are set,set it the the
1098          *  src w x h
1099          */
1100         tmp = sv_data->dst_width ? sv_data->dst_width : sv_data->src_width;
1101
1102         ovl_rect.x2 = ovl_rect.x1 + tmp;
1103
1104         tmp = sv_data->dst_height?
1105                 sv_data->dst_height:
1106         sv_data->src_height;
1107
1108         ovl_rect.y2 = ovl_rect.y1 + tmp;
1109
1110         /*
1111          *  If no values are set, set it to default
1112          */
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;
1122
1123         /*
1124          * If any values are set for gamma, turn on the gamma flags
1125          */
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;
1129
1130         if(ovl_info.gamma.red || ovl_info.gamma.green || ovl_info.gamma.blue) {
1131
1132                 ovl_info.gamma.flags = IGD_OVL_GAMMA_ENABLE;
1133         }
1134
1135         drm_HAL_dispatch->alter_ovl(drm_HAL_handle, NULL,
1136                 &surface,
1137                 &surf_rect,
1138                 &ovl_rect,
1139                 &ovl_info, IGD_OVL_ALTER_ON);
1140
1141         return 0;
1142 }
1143
1144
1145
1146 /**
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).
1150  *
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).
1154  *
1155  * @return 0 on Success
1156  * @return <0 on Error
1157  */
1158 int emgd_driver_load(struct drm_device *dev, unsigned long flags)
1159 {
1160         int i, err = 0;
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]);
1166
1167
1168         EMGD_TRACE_ENTER;
1169
1170         mutex_lock(&dev->struct_mutex);
1171
1172         /**************************************************************************
1173          *
1174          * Get the compile-time/module-parameter "params" before initializing the
1175          * HAL:
1176          *
1177          **************************************************************************/
1178
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);
1186                 return -EINVAL;
1187         }
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);
1195                 return -EINVAL;
1196         }
1197
1198         /* Obtain the user-configurable set of parameter values: */
1199         if (drm_emgd_configid < 0) {
1200                 params = config_drm.hal_params[0];
1201         } else {
1202                 params = config_drm.hal_params[drm_emgd_configid-1];
1203         }
1204
1205
1206         /*************************************
1207          * Take into account the "portorder" module parameter:
1208          *************************************/
1209         err = 0;
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: */
1213                 err = 1;
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;
1220                 err = -EINVAL;
1221         }
1222         if (!err) {
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]);
1230                                 err = -EINVAL;
1231                         }
1232                 }
1233         }
1234         if (!err) {
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];
1238                 }
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]);
1243         } else {
1244                 /* Use the compile-time value: */
1245                 for (i = 0 ; i < drm_emgd_numports ; i++) {
1246                         drm_emgd_portorder[i] = params->port_order[i];
1247                 }
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]);
1252                 err = 0;
1253         }
1254
1255
1256         emgd_print_params(params);
1257
1258
1259         /**************************************************************************
1260          *
1261          * Minimally initialize and configure the driver, deferring as much as
1262          * possible until the X driver starts.:
1263          *
1264          **************************************************************************/
1265
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\"",
1274                                 drm_emgd_init);
1275                 } else {
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\"",
1279                                 drm_emgd_init);
1280                 }
1281         } else {
1282                 /* Use the compile-time value: */
1283                 drm_emgd_init = config_drm.init;
1284                 EMGD_DEBUG("Using the compile-time \"init\" value: \"%d\"",
1285                         drm_emgd_init);
1286         }
1287
1288
1289         /*
1290          * In order for some early ioctls (e.g. emgd_get_chipset_info()) to work,
1291          * we must do the following minimal initialization.
1292          */
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) {
1297                 OS_FREE(init_info);
1298                 mutex_unlock(&dev->struct_mutex);
1299                 return -ENOMEM;
1300         }
1301
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);
1305
1306         /* Save the drm dev pointer, it's needed by igd_module_init */
1307         drm_HAL_context->drm_dev = dev;
1308
1309         /* Create the private structure used to communicate to the IMG 3rd-party
1310          * display driver:
1311          */
1312         priv = OS_ALLOC(sizeof(drm_emgd_priv_t));
1313         if (NULL == priv) {
1314                 OS_FREE(init_info);
1315                 mutex_unlock(&dev->struct_mutex);
1316                 return -ENOMEM;
1317         }
1318
1319
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;
1326         priv->ddev        = dev;
1327         priv->kms_enabled = 0;
1328
1329
1330         /* Do basic driver initialization & configuration: */
1331         EMGD_DEBUG("Calling igd_driver_config()");
1332         err = igd_driver_config(drm_HAL_handle);
1333         if (err != 0) {
1334                 OS_FREE(init_info);
1335                 OS_FREE(priv);
1336                 OS_FREE(drm_HAL_handle);
1337                 mutex_unlock(&dev->struct_mutex);
1338                 return -EIO;
1339         }
1340
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().
1343
1344         /* Init MSVDX and load firmware */
1345         msvdx_pre_init_plb(dev);
1346
1347         /* Initialize the PVR services if not already initialized */
1348         printk(KERN_INFO "Initializing PVR Services.\n");
1349         PVRSRVDrmLoad(dev, 0);
1350
1351         /* Decide if we can defer the rest of the initialization */
1352         if (config_drm.init) {
1353
1354                 if (config_drm.kms) {
1355                         params->preserve_regs = 1;
1356                         priv->kms_enabled = 1;
1357                 }
1358
1359                 /* Initialize and configure the driver now */
1360                 err = emgd_startup_hal(dev, params);
1361                 if (err != 0) {
1362                         OS_FREE(init_info);
1363                         OS_FREE(priv);
1364                         OS_FREE(drm_HAL_handle);
1365                         mutex_unlock(&dev->struct_mutex);
1366                         return err;
1367                 }
1368
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
1372                  */
1373                 get_pre_driver_info(mode_context);
1374
1375                 /* Per the user's request, initialize the display: */
1376                 emgd_init_display(TRUE, priv);
1377         }
1378
1379
1380
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.
1384          */
1385         if (emgd_debug->hal.oal) {
1386                 drm_debug |= DRM_UT_KMS;
1387         }
1388 #endif
1389
1390         /* can not work out how to start PVRSRV */
1391         /* Load Buffer Class Module*/
1392         emgd_bc_ts_init();
1393
1394         mutex_unlock(&dev->struct_mutex);
1395         EMGD_TRACE_EXIT;
1396
1397         return 0;
1398 } /* emgd_driver_load() */
1399
1400
1401 /**
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.
1405  *
1406  * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1407  *
1408  * @return 0 on Success
1409  * @return <0 on Error
1410  */
1411 int emgd_driver_unload(struct drm_device *dev)
1412 {
1413         drm_emgd_priv_t *priv = dev->dev_private;
1414         unsigned long save_flags = 0;
1415
1416         EMGD_TRACE_ENTER;
1417
1418         mutex_lock(&dev->struct_mutex);
1419
1420         /* Unload Buffer Class Module*/
1421         emgd_bc_ts_uninit();
1422
1423         PVRSRVDrmUnload(dev);
1424
1425         /* KMS cleanup */
1426         if (config_drm.init && config_drm.kms) {
1427                 emgd_modeset_destroy(dev);
1428         }
1429
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().
1440                  */
1441                 if (priv->saved_registers == CONSOLE_STATE_SAVED) {
1442                         EMGD_DEBUG("Need to restore the console's saved register state");
1443
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;
1448                 }
1449                 igd_driver_shutdown_hal(drm_HAL_handle);
1450                 igd_driver_shutdown(drm_HAL_handle);
1451         } else {
1452                 /* Do safe cleanup that would've been done by igd_driver_shutdown() */
1453                 igd_driver_shutdown(drm_HAL_handle);
1454         }
1455
1456         if (!config_drm.kms) {
1457                 kfree(primary_fb_info);
1458                 kfree(secondary_fb_info);
1459         }
1460
1461         OS_FREE(priv->init_info);
1462         OS_FREE(priv);
1463
1464         /* Note: This macro is #define'd in "oal/os/memory.h" */
1465 #ifdef INSTRUMENT_KERNEL_ALLOCS
1466         emgd_report_unfreed_memory();
1467 #endif
1468
1469         mutex_unlock(&dev->struct_mutex);
1470
1471         EMGD_TRACE_EXIT;
1472
1473         return 0;
1474 } /* emgd_driver_unload() */
1475
1476
1477 /**
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.
1481  *
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")
1484  *
1485  * @return 0 on Success
1486  * @return <0 on Error
1487  */
1488 int emgd_driver_open(struct drm_device *dev, struct drm_file *priv)
1489 {
1490         int ret = 0;
1491         drm_emgd_priv_t *emgd_priv = dev->dev_private;
1492
1493         EMGD_TRACE_ENTER;
1494
1495         /*
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.
1503          *
1504          * FIXME: Should we do the same for other operations like suspend/resume/etc?
1505          */
1506         mutex_lock(&dev->struct_mutex);
1507
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;
1512         }
1513
1514         ret = PVRSRVOpen(dev, priv);
1515
1516         mutex_unlock(&dev->struct_mutex);
1517
1518         EMGD_TRACE_EXIT;
1519         return ret;
1520 } /* emgd_driver_open() */
1521
1522
1523 /**
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.
1528  *
1529  * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1530  */
1531 void emgd_driver_lastclose(struct drm_device *dev)
1532 {
1533         drm_emgd_priv_t *priv = dev->dev_private;
1534         igd_init_info_t *init_info = priv->init_info;
1535         int err = 0;
1536         unsigned long restore_flags = 0;
1537
1538         EMGD_TRACE_ENTER;
1539
1540         mutex_lock(&dev->struct_mutex);
1541
1542
1543         if (priv->hal_running) {
1544                 if (config_drm.init) {
1545                         if( x_started ) {
1546
1547                                 restore_flags = (IGD_REG_SAVE_ALL & ~IGD_REG_SAVE_GTT)
1548                                                                         | IGD_REG_SAVE_TYPE_REG;
1549
1550                                 if (!config_drm.kms) {
1551                                         restore_flags &= ~IGD_REG_SAVE_RB;
1552                                 }
1553
1554
1555                                 if (priv->saved_registers == CONSOLE_STATE_SAVED) {
1556                                         EMGD_DEBUG("Need to restore the console's saved "
1557                                                 "register state");
1558                                         drm_HAL_dispatch->driver_save_restore(drm_HAL_handle,
1559                                                                                                                         restore_flags);
1560                                         EMGD_DEBUG("State of saved registers is "
1561                                                 "X_SERVER_STATE_SAVED");
1562                                         priv->saved_registers = X_SERVER_STATE_SAVED;
1563                                 }
1564
1565                                 if (priv->saved_registers == X_SERVER_STATE_SAVED &&
1566                                         !config_drm.kms && !priv->qb_seamless) {
1567                                         emgd_init_display(FALSE, priv);
1568                                 }
1569
1570                                 if (priv->saved_registers == CONSOLE_STATE_SAVED) {
1571                                         EMGD_DEBUG("Need to restore the console's saved register "
1572                                                 "state");
1573                                         drm_HAL_dispatch->driver_save_restore(drm_HAL_handle,
1574                                                                                                                         restore_flags);
1575                                         EMGD_DEBUG("State of saved registers is X_SERVER_STATE_SAVED");
1576                                         priv->saved_registers = X_SERVER_STATE_SAVED;
1577                                 }
1578
1579                                 /* Since an alter_displays() was done, re-init the 3DD: */
1580                                 if (priv->reinit_3dd) {
1581                                         priv->reinit_3dd(dev);
1582                                 }
1583
1584                                 x_started = false;
1585                         }
1586                 } else {
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.
1590                          */
1591                         context_count = 0;
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 "
1595                                         "state");
1596                                 restore_flags = IGD_REG_SAVE_ALL;
1597
1598                                 drm_HAL_dispatch->driver_save_restore(drm_HAL_handle,
1599                                                                                                                 restore_flags);
1600                                 EMGD_DEBUG("State of saved registers is X_SERVER_STATE_SAVED");
1601                                 priv->saved_registers = X_SERVER_STATE_SAVED;
1602                         }
1603
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.
1610                          *
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).
1614                          *
1615                          * Also, keep the PVR services up and going, since it wasn't
1616                          * designed to be shutdown and restarted (without doing an
1617                          * rmmod/insmod).
1618                          ******************************************************************/
1619                         EMGD_DEBUG("Shutting down the HAL");
1620
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().
1630                          */
1631                         if (priv->saved_registers == X_SERVER_STATE_SAVED) {
1632                                 EMGD_DEBUG("Need to restore the console's saved register "
1633                                         "state");
1634                                 restore_flags = IGD_REG_SAVE_ALL;
1635                                 drm_HAL_dispatch->driver_save_restore(drm_HAL_handle,
1636                                                                                                                 restore_flags);
1637                                 EMGD_DEBUG("State of saved registers is X_SERVER_STATE_SAVED");
1638                                 priv->saved_registers = CONSOLE_STATE_SAVED;
1639                         }
1640                         msvdx_shutdown_plb(drm_HAL_handle);
1641                         igd_driver_shutdown_hal(drm_HAL_handle);
1642                         igd_driver_shutdown(drm_HAL_handle);
1643
1644                         EMGD_DEBUG("Minimally restarting the HAL--like load-time");
1645                         /*
1646                          * In order for some early ioctls (e.g. emgd_get_chipset_info()) to
1647                          * work, we must do the following minimal initialization.
1648                          */
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));
1652                         }
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
1657                                  * reboot:
1658                                  */
1659                                 OS_FREE(init_info);
1660                                 printk(KERN_ALERT "[EMGD] Failed to restart the EMGD graphics "
1661                                                 "HAL\n");
1662                                 mutex_unlock(&dev->struct_mutex);
1663                                 return;
1664                         }
1665
1666                         /* Get the HAL context and give it to the ioctl-handling "bridge"
1667                          * code:
1668                          */
1669                         drm_HAL_context = (igd_context_t *) drm_HAL_handle;
1670                         emgd_set_real_handle(drm_HAL_handle);
1671
1672                         /* Save the drm dev pointer, it's needed by igd_module_init */
1673                         drm_HAL_context->drm_dev = dev;
1674
1675                         /* Reset part of the private structure used to communicate to the
1676                          * IMG 3rd-party display driver:
1677                          */
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;
1690
1691
1692                         /* Do basic driver initialization & configuration: */
1693                         EMGD_DEBUG("Calling igd_driver_config()");
1694                         err = igd_driver_config(drm_HAL_handle);
1695                         if (err != 0) {
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
1698                                  * reboot:
1699                                  */
1700                                 OS_FREE(init_info);
1701                                 printk(KERN_ALERT "[EMGD] Failed to restart the EMGD graphics "
1702                                                 "HAL.\n");
1703                                 mutex_unlock(&dev->struct_mutex);
1704                                 return;
1705                         }
1706
1707                         /* To ensure the devinfo->interrupt_h is NULL, call the
1708                          * following:
1709                          */
1710                         if (priv->reinit_3dd) {
1711                                 priv->reinit_3dd(dev);
1712                         }
1713                 }
1714         }
1715
1716         mutex_unlock(&dev->struct_mutex );
1717
1718         EMGD_TRACE_EXIT;
1719
1720 } /* emgd_driver_lastclose() */
1721
1722
1723 /**
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).
1728  *
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")
1731  */
1732 void emgd_driver_preclose(struct drm_device *dev, struct drm_file *priv)
1733 {
1734         drm_emgd_priv_t *emgd_priv = dev->dev_private;
1735
1736         /* Notes on what to implement in this function.  What this
1737          * function does is largely influenced by when/why this can be called:
1738          *
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.
1741          *
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.
1745          *
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.
1749          *
1750          *   - We don't yet know what the IMG 3D code is going to need.
1751          *
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.
1754          */
1755
1756         EMGD_TRACE_ENTER;
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:
1765                  */
1766                 drm_HAL_dispatch->gmm_flush_cache();
1767
1768                 /* TODO - WRITE CODE THAT PUTS THE DISPLAY HW IN A KNOWN STATE/MODE */
1769         }
1770
1771         if (emgd_priv->drm_master_fd == priv)
1772                 emgd_priv->drm_master_fd = NULL;
1773
1774         mutex_unlock(&dev->struct_mutex);
1775         EMGD_TRACE_EXIT;
1776
1777         /* TODO -- ADD ANYTHING WE DISCOVER WE NEED AFTER THE IMG TRAINING */
1778
1779 } /* emgd_driver_preclose() */
1780
1781
1782 /**
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.
1787  *
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")
1790  */
1791 void emgd_driver_postclose(struct drm_device *dev, struct drm_file *priv)
1792 {
1793         int ret = 0;
1794         drm_emgd_priv_t *dev_priv = dev->dev_private;
1795         igd_context_t *context = dev_priv->context;
1796
1797         EMGD_TRACE_ENTER;
1798         mutex_lock(&dev->struct_mutex);
1799
1800         /* Calling the msvdx_postclose_check before PVRSRVRelease */
1801         if (priv) {
1802                 msvdx_postclose_check(context, (void *) priv);
1803         }
1804
1805         ret = PVRSRVRelease(dev, priv);
1806
1807         mutex_unlock(&dev->struct_mutex);
1808         EMGD_TRACE_EXIT;
1809 } /* emgd_driver_postclose() */
1810
1811
1812 /**
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)
1819  * feature set.
1820  *
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")
1823  *
1824  * @return 0 on Success
1825  * @return <0 on Error
1826  */
1827 int emgd_driver_suspend(struct drm_device *dev, pm_message_t state)
1828 {
1829         int ret;
1830         unsigned int pwr_state;
1831         drm_emgd_priv_t *priv = dev->dev_private;
1832
1833         EMGD_TRACE_ENTER;
1834
1835
1836         mutex_lock(&dev->struct_mutex);
1837
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.
1842          */
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,
1847                                 IGD_REG_SAVE_ALL);
1848                 if (priv->suspended_state) {
1849                         /*
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);
1854                                 }
1855                         }
1856                         */
1857                         drm_HAL_context->mod_dispatch.reg_save(drm_HAL_context,
1858                                 priv->suspended_state);
1859                 }
1860         }
1861
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;
1867                 break;
1868         case PM_EVENT_HIBERNATE:
1869                 pwr_state = IGD_POWERSTATE_D3;
1870                 break;
1871         case PM_EVENT_SUSPEND:
1872         default:
1873                 pwr_state = IGD_POWERSTATE_D2;
1874                 break;
1875         } /* switch (state) */
1876
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);
1880
1881         if (0 == ret) {
1882                 EMGD_DEBUG("Calling PVRSRVDriverSuspend()");
1883                 ret = PVRSRVDriverSuspend(dev, state);
1884                 EMGD_DEBUG("PVRSRVDriverSuspend() returned %d", ret);
1885         }
1886
1887         EMGD_DEBUG("Returning %d", ret);
1888         mutex_unlock(&dev->struct_mutex);
1889         EMGD_TRACE_EXIT;
1890         return ret;
1891
1892 } /* emgd_driver_suspend() */
1893
1894
1895 /**
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.
1902  *
1903  * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1904  *
1905  * @return 0 on Success
1906  * @return <0 on Error
1907  */
1908 int emgd_driver_resume(struct drm_device *dev)
1909 {
1910         int ret;
1911         drm_emgd_priv_t *priv = dev->dev_private;
1912
1913         EMGD_TRACE_ENTER;
1914
1915         mutex_lock(&dev->struct_mutex);
1916
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);
1920
1921         if (0 == ret) {
1922                 EMGD_DEBUG("Calling PVRSRVDriverResume()");
1923                 ret = PVRSRVDriverResume(dev);
1924                 EMGD_DEBUG("PVRSRVDriverResume() returned %d", ret);
1925         }
1926
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.
1929          */
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;
1938                 }
1939         }
1940
1941         EMGD_DEBUG("Returning %d", ret);
1942         mutex_unlock(&dev->struct_mutex);
1943         EMGD_TRACE_EXIT;
1944         return ret;
1945 } /* emgd_driver_resume() */
1946
1947
1948 /**
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").
1954  *
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.
1959  *
1960  * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
1961  *
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.
1965  */
1966 int emgd_driver_device_is_agp(struct drm_device *dev)
1967 {
1968         EMGD_DEBUG("[EMGD] Returning 0 from emgd_driver_device_is_agp()\n");
1969         return 0;
1970 } /* emgd_driver_device_is_agp() */
1971
1972
1973
1974 /**
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.
1978  *
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.
1984  *
1985  * @return raw vblank counter value
1986  */
1987 u32 emgd_driver_get_vblank_counter(struct drm_device *dev, int crtc_select)
1988 {
1989         struct drm_crtc *crtc;
1990         emgd_crtc_t     *cur_emgd_crtc, *selected_emgd_crtc = NULL;
1991
1992
1993         EMGD_TRACE_ENTER;
1994
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. */
1999                 EMGD_TRACE_EXIT;
2000                 return 0;
2001         }
2002
2003
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);
2007
2008                 if ((1 << crtc_select) == cur_emgd_crtc->crtc_id) {
2009                         selected_emgd_crtc = cur_emgd_crtc;
2010                         break;
2011                 }
2012         }
2013
2014         if (NULL == selected_emgd_crtc) {
2015                 EMGD_ERROR_EXIT("Invalid CRTC selected.");
2016                 return -EINVAL;
2017         }
2018
2019         EMGD_TRACE_EXIT;
2020
2021         return mode_context->kms_dispatch->kms_get_vblank_counter(
2022                                                                                 selected_emgd_crtc);
2023 } /* emgd_driver_get_vblank_counter() */
2024
2025
2026
2027 /**
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
2031  *
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.
2037  *
2038  * @return 0 on Success
2039  * @return <0 if the given crtc's vblank interrupt cannot be enabled
2040  */
2041 int emgd_driver_enable_vblank(struct drm_device *dev, int crtc_select)
2042 {
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;
2047         int              ret = 0;
2048
2049         EMGD_TRACE_ENTER;
2050
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. */
2057                 EMGD_TRACE_EXIT;
2058                 return 0;
2059         }
2060
2061
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);
2065
2066                 if ((1 << crtc_select) == cur_emgd_crtc->crtc_id) {
2067                         selected_emgd_crtc = cur_emgd_crtc;
2068                         break;
2069                 }
2070         }
2071
2072         if (NULL == selected_emgd_crtc) {
2073                 EMGD_ERROR_EXIT("Invalid CRTC selected.");
2074                 return -EINVAL;
2075         }
2076
2077
2078         switch (selected_emgd_crtc->igd_pipe->pipe_features & IGD_PORT_MASK) {
2079                 case IGD_PORT_SHARE_LVDS:
2080                         request_for = VBLANK_INT4_PORT4;
2081                         break;
2082
2083                 case IGD_PORT_SHARE_DIGITAL:
2084                         request_for = VBLANK_INT4_PORT2;
2085                         break;
2086
2087                 default:
2088                         EMGD_DEBUG("Unsupported port type");
2089                         request_for = 0;
2090                         ret         = -EINVAL;
2091                         break;
2092         }
2093
2094         if (0 == ret) {
2095                 mmio = EMGD_MMIO(mode_context->context->device_context.virt_mmadr);
2096                 ret  = mode_context->dispatch->full->request_vblanks(request_for, mmio);
2097
2098                 if (ret) {
2099                         EMGD_DEBUG("Failed to enable vblank");
2100                 }
2101         }
2102
2103         EMGD_TRACE_EXIT;
2104         return ret;
2105 } /* emgd_driver_enable_vblank() */
2106
2107
2108
2109 /**
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.
2112  *
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.
2118  */
2119 void emgd_driver_disable_vblank(struct drm_device *dev, int crtc_select)
2120 {
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;
2125         int              ret = 0;
2126
2127         EMGD_TRACE_ENTER;
2128
2129
2130         /* Only supported for KMS-enabled driver */
2131         if (!config_drm.kms) {
2132                 EMGD_TRACE_EXIT;
2133                 return;
2134         }
2135
2136
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);
2140
2141                 if ((1 << crtc_select) == cur_emgd_crtc->crtc_id) {
2142                         selected_emgd_crtc = cur_emgd_crtc;
2143                         break;
2144                 }
2145         }
2146
2147         if (NULL == selected_emgd_crtc) {
2148                 EMGD_ERROR_EXIT("Invalid CRTC selected.");
2149                 return;
2150         }
2151
2152
2153         switch (selected_emgd_crtc->igd_pipe->pipe_features & IGD_PORT_MASK) {
2154                 case IGD_PORT_SHARE_LVDS:
2155                         request_for = VBLANK_INT4_PORT4;
2156                         break;
2157
2158                 case IGD_PORT_SHARE_DIGITAL:
2159                         request_for = VBLANK_INT4_PORT2;
2160                         break;
2161
2162                 default:
2163                         EMGD_DEBUG("Unsupported port type");
2164                         request_for = 0;
2165                         ret         = -EINVAL;
2166                         break;
2167         }
2168
2169         if (0 == ret) {
2170                 mmio = EMGD_MMIO(mode_context->context->device_context.virt_mmadr);
2171                 ret  = mode_context->dispatch->full->end_request(request_for, mmio);
2172
2173                 if (ret) {
2174                         EMGD_DEBUG("Failed to disable vblank");
2175                 }
2176         }
2177
2178         EMGD_TRACE_EXIT;
2179         return;
2180 } /* emgd_driver_disable_vblank() */
2181
2182
2183
2184 /**
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()).
2188  *
2189  * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2190  */
2191 void emgd_driver_irq_preinstall(struct drm_device *dev)
2192 {
2193         /* Notes on what to implement in this function:
2194          *
2195          * - Ditto the notes in emgd_driver_enable_vblank().
2196          *
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:
2201          *
2202          *    - There are no "plb" versions of this code, only "alm", "nap" & "wht".
2203          *
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.
2207          *
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.
2211          *
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
2216          *   different?
2217          */
2218
2219         /* TODO -- REPLACE THIS STUB WITH A REAL IMPLEMENTATION  */
2220         printk(KERN_INFO "[EMGD] Inside of STUBBED %s()", __FUNCTION__);
2221
2222 } /* emgd_driver_irq_preinstall() */
2223
2224
2225 /**
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()).
2229  *
2230  * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2231  *
2232  * @return 0 on Success
2233  * @return <0 if the given crtc's vblank interrupt cannot be enabled
2234  */
2235 int emgd_driver_irq_postinstall(struct drm_device *dev)
2236 {
2237         return 0;
2238 } /* emgd_driver_irq_postinstall() */
2239
2240
2241 /**
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()).
2245  *
2246  * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2247  */
2248 void emgd_driver_irq_uninstall(struct drm_device *dev)
2249 {
2250         /* TODO -- REPLACE THIS STUB WITH A REAL IMPLEMENTATION THE IMG TRAINING */
2251         printk(KERN_INFO "[EMGD] Inside of STUBBED %s()", __FUNCTION__);
2252
2253 } /* emgd_driver_irq_uninstall() */
2254
2255
2256 /**
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").
2262  *
2263  * Our HAL will have already installed an IRQ handler, so we do nothing here.
2264  *
2265  * @param dev (IN) DRM per-device (e.g. one GMA) struct (in "drmP.h")
2266  *
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
2270  */
2271 irqreturn_t emgd_driver_irq_handler(int irq, void *arg)
2272 {
2273         /* TODO -- REPLACE THIS STUB WITH A REAL IMPLEMENTATION THE IMG TRAINING */
2274         printk(KERN_INFO "[EMGD] Inside of STUBBED %s()", __FUNCTION__);
2275
2276         return IRQ_NONE;
2277 } /* emgd_driver_irq_handler() */
2278
2279
2280 static int __devinit emgd_pci_probe(struct pci_dev *pdev,
2281                 const struct pci_device_id *ent)
2282 {
2283         if (PCI_FUNC(pdev->devfn)) {
2284                 return -ENODEV;
2285         }
2286
2287         /*
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.
2291          */
2292 #if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,35)
2293         return drm_get_pci_dev(pdev, ent, &driver);
2294 #else
2295         return drm_get_dev(pdev, ent, &driver);
2296 #endif
2297 }
2298
2299 static void emgd_pci_remove(struct pci_dev *pdev)
2300 {
2301         struct drm_device *dev = pci_get_drvdata(pdev);
2302
2303         drm_put_dev(dev);
2304 }
2305
2306 static int emgd_pm_suspend(struct device *dev)
2307 {
2308         return 0;
2309 }
2310
2311 static int emgd_pm_resume(struct device *dev)
2312 {
2313         return 0;
2314 }
2315
2316 static int emgd_pm_freeze(struct device *dev)
2317 {
2318         return 0;
2319 }
2320
2321 static int emgd_pm_thaw(struct device *dev)
2322 {
2323         return 0;
2324 }
2325
2326 static int emgd_pm_poweroff(struct device *dev)
2327 {
2328         return 0;
2329 }
2330
2331 static int emgd_pm_restore(struct device *dev)
2332 {
2333         return 0;
2334 }
2335
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,
2343 };
2344
2345 /*
2346  * NOTE: The remainder of this file is standard kernel module initialization
2347  * code:
2348  */
2349
2350
2351 /*
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.
2357  */
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, \
2364 }
2365
2366 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
2367 static struct pci_driver emgd_pci_driver = EMGD_PCI_DRIVER;
2368 #endif
2369
2370 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,32)
2371 #define IOCTL unlocked_ioctl
2372 #else
2373 #define IOCTL ioctl
2374 #endif
2375
2376 #define EMGD_FOPS { \
2377     .owner   = THIS_MODULE,        \
2378     .open    = drm_open,           \
2379     .release = drm_release,        \
2380         .IOCTL   = drm_ioctl,              \
2381     .mmap    = emgd_mmap,          \
2382     .poll    = drm_poll,           \
2383     .fasync  = drm_fasync,         \
2384     .read    = drm_read,           \
2385 }
2386
2387 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
2388 static const struct file_operations emgd_driver_fops = EMGD_FOPS;
2389 #endif
2390
2391 /**
2392  * DRM Sub driver entry points
2393  */
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,
2416 #endif
2417         .ioctls             = emgd_ioctl,
2418 #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
2419     .fops                = &emgd_driver_fops,
2420 #else
2421     .fops                = EMGD_FOPS,
2422 #endif
2423
2424 #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,38)
2425         .pci_driver          = EMGD_PCI_DRIVER,
2426 #endif
2427         .name                = DRIVER_NAME,
2428         .desc                = DRIVER_DESC,
2429         .date                = DRIVER_DATE,
2430         .major               = DRIVER_MAJOR,
2431         .minor               = DRIVER_MINOR,
2432         .patchlevel          = DRIVER_PATCHLEVEL,
2433 };
2434
2435 /**
2436  * Standard procedure to initialize this kernel module when it is loaded.
2437  */
2438 static int __init emgd_init(void) {
2439         int ret;
2440         struct pci_dev *our_device;
2441
2442         printk(KERN_INFO "[EMGD] Initializing Driver.\n");
2443         driver.num_ioctls = emgd_max_ioctl;
2444
2445         /* If init == 1 then we should always set KMS to 0 for US15 */
2446
2447         if(config_drm.init || drm_emgd_init == 1){
2448
2449                 /*  Detecting device */
2450
2451                 /*
2452                  * 0x8086 is the intel vendor id and 0x8108 is the
2453                  * US15 device id.
2454                  * pci_get_device returns NULL if it is not a PLB.
2455                  */
2456
2457                 our_device = pci_get_device(PCI_VENDOR_ID_INTEL,
2458                                         PCI_DEVICE_ID_VGA_PLB, NULL);
2459
2460                 if(our_device){
2461                         EMGD_ERROR("US15 detected. Setting KMS to 0 "
2462                                 "config_drm.kms = %d ", config_drm.kms);
2463                         config_drm.kms = 0;
2464                 }
2465         }
2466
2467         if (config_drm.kms && (config_drm.init || drm_emgd_init == 1)) {
2468                 driver.driver_features |= DRIVER_MODESET;
2469         }
2470
2471         PVRDPFInit();
2472
2473 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
2474         ret = drm_pci_init(&driver, &emgd_pci_driver);
2475 #else
2476         ret = drm_init(&driver);
2477 #endif
2478         printk(KERN_INFO "[EMGD] Driver Initialized.\n");
2479         EMGD_TRACE_EXIT;
2480         return ret;
2481 }
2482
2483 /**
2484  * Standard procedure to clean-up this kernel module before it exits & unloads.
2485  */
2486 static void __exit emgd_exit(void) {
2487         EMGD_TRACE_ENTER;
2488 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,38)
2489         drm_pci_exit(&driver, &emgd_pci_driver);
2490 #else
2491         drm_exit(&driver);
2492 #endif
2493         EMGD_TRACE_EXIT;
2494 }
2495
2496
2497 module_init(emgd_init);
2498 module_exit(emgd_exit);
2499
2500 MODULE_AUTHOR(DRIVER_AUTHOR);
2501 MODULE_DESCRIPTION(DRIVER_DESC);
2502 MODULE_LICENSE("GPL and additional rights");