blob: fb995a57f12d3b21652d30ecf199d77780772396 [file] [log] [blame]
Rob Clark487687e2011-07-17 17:29:02 -05001/* -*- mode: C; c-file-style: "k&r"; tab-width 4; indent-tabs-mode: t; -*- */
2
3/*
4 * Copyright © 2011 Texas Instruments, Inc
5 *
6 * Permission is hereby granted, free of charge, to any person obtaining a
7 * copy of this software and associated documentation files (the "Software"),
8 * to deal in the Software without restriction, including without limitation
9 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
10 * and/or sell copies of the Software, and to permit persons to whom the
11 * Software is furnished to do so, subject to the following conditions:
12 *
13 * The above copyright notice and this permission notice (including the next
14 * paragraph) shall be included in all copies or substantial portions of the
15 * Software.
16 *
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23 * SOFTWARE.
24 *
25 * Authors:
26 * Ian Elliott <ianelliottus@yahoo.com>
27 * Rob Clark <rob@ti.com>
28 */
29
Raymond Smith41ecf3e2012-05-01 14:51:34 +010030#include <sys/types.h>
31#include <sys/stat.h>
32#include <fcntl.h>
Dave Barnish1a3dac32013-06-20 19:01:38 +010033#include <unistd.h>
David Garbettdccb73f2013-09-02 11:48:21 +010034#include <linux/fb.h>
35#include <sys/ioctl.h>
36#include <sys/mman.h>
37
38#include <pixman.h>
Raymond Smith41ecf3e2012-05-01 14:51:34 +010039
Rob Clark487687e2011-07-17 17:29:02 -050040#ifdef HAVE_CONFIG_H
41#include "config.h"
42#endif
43
Paul Gearyf8b99692013-04-15 10:55:17 +010044#include "armsoc_driver.h"
Dave Barnish257c6f12013-06-05 17:00:29 +010045
46#include "micmap.h"
47
48#include "xf86cmap.h"
49#include "xf86RandR12.h"
50
Cooper Yuana83caa62012-06-28 17:19:06 +020051#include "compat-api.h"
Rob Clark487687e2011-07-17 17:29:02 -050052
Ray Smith3c33c3d2013-03-26 16:06:37 +000053#include "drmmode_driver.h"
54
Dave Barnish1a3dac32013-06-20 19:01:38 +010055#define DRM_DEVICE "/dev/dri/card%d"
Dave Barnishf0952c12013-05-10 15:52:23 +010056
Dave Barnish2e998952013-06-11 16:31:10 +010057Bool armsocDebug;
Rob Clark487687e2011-07-17 17:29:02 -050058
59/*
60 * Forward declarations:
61 */
Paul Geary8ffd91c2013-04-11 16:03:15 +010062static const OptionInfoRec *ARMSOCAvailableOptions(int chipid, int busid);
63static void ARMSOCIdentify(int flags);
64static Bool ARMSOCProbe(DriverPtr drv, int flags);
65static Bool ARMSOCPreInit(ScrnInfoPtr pScrn, int flags);
66static Bool ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL);
67static void ARMSOCLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
Dave Barnish2e998952013-06-11 16:31:10 +010068 LOCO *colors, VisualPtr pVisual);
Paul Geary8ffd91c2013-04-11 16:03:15 +010069static Bool ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL);
70static Bool ARMSOCCreateScreenResources(ScreenPtr pScreen);
71static void ARMSOCBlockHandler(BLOCKHANDLER_ARGS_DECL);
72static Bool ARMSOCSwitchMode(SWITCH_MODE_ARGS_DECL);
73static void ARMSOCAdjustFrame(ADJUST_FRAME_ARGS_DECL);
74static Bool ARMSOCEnterVT(VT_FUNC_ARGS_DECL);
75static void ARMSOCLeaveVT(VT_FUNC_ARGS_DECL);
76static void ARMSOCFreeScreen(FREE_SCREEN_ARGS_DECL);
Rob Clark487687e2011-07-17 17:29:02 -050077
Rob Clark487687e2011-07-17 17:29:02 -050078/**
79 * A structure used by the XFree86 code when loading this driver, so that it
80 * can access the Probe() function, and other functions/info that it uses
81 * before it calls the Probe() function. The name of this structure must be
82 * the all-upper-case version of the driver name.
83 */
Paul Geary8ffd91c2013-04-11 16:03:15 +010084_X_EXPORT DriverRec ARMSOC = {
85 ARMSOC_VERSION,
86 (char *)ARMSOC_DRIVER_NAME,
87 ARMSOCIdentify,
88 ARMSOCProbe,
89 ARMSOCAvailableOptions,
Rob Clark487687e2011-07-17 17:29:02 -050090 NULL,
91 0,
92 NULL,
93#ifdef XSERVER_LIBPCIACCESS
94 NULL,
95 NULL
96#endif
97};
98
Dave Barnish01b5c172013-04-10 11:01:17 +010099#define MALI_4XX_CHIPSET_ID (0x0400)
100#define MALI_T6XX_CHIPSET_ID (0x0600)
101
Rob Clark487687e2011-07-17 17:29:02 -0500102/** Supported "chipsets." */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100103static SymTabRec ARMSOCChipsets[] = {
Dave Barnish01b5c172013-04-10 11:01:17 +0100104 { MALI_4XX_CHIPSET_ID, "Mali-4XX" },
105 { MALI_T6XX_CHIPSET_ID, "Mali-T6XX" },
Rob Clark487687e2011-07-17 17:29:02 -0500106 {-1, NULL }
107};
108
109/** Supported options, as enum values. */
Dave Barnish2e998952013-06-11 16:31:10 +0100110enum {
Rob Clark487687e2011-07-17 17:29:02 -0500111 OPTION_DEBUG,
Dave Barnishc50baf52012-11-29 14:39:36 +0000112 OPTION_NO_FLIP,
Dave Barnish1a3dac32013-06-20 19:01:38 +0100113 OPTION_CARD_NUM,
114 OPTION_BUSID,
115 OPTION_DRIVERNAME,
David Garbett4d37be32013-04-04 09:04:29 +0100116 OPTION_DRI_NUM_BUF,
David Garbettdccb73f2013-09-02 11:48:21 +0100117 OPTION_INIT_FROM_FBDEV,
Dave Barnish2e998952013-06-11 16:31:10 +0100118};
Rob Clark487687e2011-07-17 17:29:02 -0500119
120/** Supported options. */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100121static const OptionInfoRec ARMSOCOptions[] = {
Dave Barnish1a3dac32013-06-20 19:01:38 +0100122 { OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE },
123 { OPTION_NO_FLIP, "NoFlip", OPTV_BOOLEAN, {0}, FALSE },
124 { OPTION_CARD_NUM, "DRICard", OPTV_INTEGER, {0}, FALSE },
125 { OPTION_BUSID, "BusID", OPTV_STRING, {0}, FALSE },
126 { OPTION_DRIVERNAME, "DriverName", OPTV_STRING, {0}, FALSE },
David Garbett4d37be32013-04-04 09:04:29 +0100127 { OPTION_DRI_NUM_BUF, "DRI2MaxBuffers", OPTV_INTEGER, {-1}, FALSE },
David Garbettdccb73f2013-09-02 11:48:21 +0100128 { OPTION_INIT_FROM_FBDEV, "InitFromFBDev", OPTV_STRING, {0}, FALSE },
Dave Barnish1a3dac32013-06-20 19:01:38 +0100129 { -1, NULL, OPTV_NONE, {0}, FALSE }
Rob Clark487687e2011-07-17 17:29:02 -0500130};
131
132/**
Dave Barnishf0952c12013-05-10 15:52:23 +0100133 * Helper functions for sharing a DRM connection across screens.
Rob Clark487687e2011-07-17 17:29:02 -0500134 */
Dave Barnishf0952c12013-05-10 15:52:23 +0100135static struct ARMSOCConnection {
Ray Smithb31657f2013-06-25 11:47:36 +0100136 const char *driver_name;
137 const char *bus_id;
Dave Barnish1a3dac32013-06-20 19:01:38 +0100138 unsigned int card_num;
Dave Barnishf0952c12013-05-10 15:52:23 +0100139 int fd;
140 int open_count;
141 int master_count;
Dave Barnish1a3dac32013-06-20 19:01:38 +0100142} connection = {NULL, NULL, 0, -1, 0, 0};
Rob Clark487687e2011-07-17 17:29:02 -0500143
144static int
Dave Barnishf0952c12013-05-10 15:52:23 +0100145ARMSOCSetDRMMaster(void)
Rob Clark487687e2011-07-17 17:29:02 -0500146{
Dave Barnish2e998952013-06-11 16:31:10 +0100147 int ret = 0;
Dave Barnishf0952c12013-05-10 15:52:23 +0100148
Dave Barnish2e998952013-06-11 16:31:10 +0100149 assert(connection.fd >= 0);
Dave Barnishf0952c12013-05-10 15:52:23 +0100150
Dave Barnish2e998952013-06-11 16:31:10 +0100151 if (!connection.master_count)
Dave Barnishf0952c12013-05-10 15:52:23 +0100152 ret = drmSetMaster(connection.fd);
Dave Barnish2e998952013-06-11 16:31:10 +0100153
154 if (!ret)
Dave Barnishf0952c12013-05-10 15:52:23 +0100155 connection.master_count++;
Dave Barnish2e998952013-06-11 16:31:10 +0100156
Dave Barnishf0952c12013-05-10 15:52:23 +0100157 return ret;
158}
159
160static int
161ARMSOCDropDRMMaster(void)
162{
163 int ret = 0;
164
Dave Barnish2e998952013-06-11 16:31:10 +0100165 assert(connection.fd >= 0);
166 assert(connection.master_count > 0);
Dave Barnishf0952c12013-05-10 15:52:23 +0100167
Dave Barnish2e998952013-06-11 16:31:10 +0100168 if (1 == connection.master_count)
Dave Barnishf0952c12013-05-10 15:52:23 +0100169 ret = drmDropMaster(connection.fd);
Dave Barnish2e998952013-06-11 16:31:10 +0100170
171 if (!ret)
Dave Barnishf0952c12013-05-10 15:52:23 +0100172 connection.master_count--;
Dave Barnish2e998952013-06-11 16:31:10 +0100173
Dave Barnishf0952c12013-05-10 15:52:23 +0100174 return ret;
Rob Clark487687e2011-07-17 17:29:02 -0500175}
176
Dave Barnish1a3dac32013-06-20 19:01:38 +0100177static void
178ARMSOCShowDriverInfo(int fd)
179{
180 char *bus_id;
181 drmVersionPtr version;
182 char *deviceName;
183
184 EARLY_INFO_MSG("Opened DRM");
185 deviceName = drmGetDeviceNameFromFd(fd);
186 EARLY_INFO_MSG(" DeviceName is [%s]",
187 deviceName ? deviceName : "NULL");
188 drmFree(deviceName);
189 bus_id = drmGetBusid(fd);
190 EARLY_INFO_MSG(" bus_id is [%s]",
191 bus_id ? bus_id : "NULL");
192 drmFreeBusid(bus_id);
193 version = drmGetVersion(fd);
194 if (version) {
195 EARLY_INFO_MSG(" DriverName is [%s]",
196 version->name);
197 EARLY_INFO_MSG(" version is [%d.%d.%d]",
198 version->version_major,
199 version->version_minor,
200 version->version_patchlevel);
201 drmFreeVersion(version);
202 } else {
203 EARLY_INFO_MSG(" version is [NULL]");
204 }
205 return;
206}
207
208static int
209ARMSOCOpenDRMCard(void)
210{
211 int fd;
212
213 if ((connection.bus_id) || (connection.driver_name)) {
214 /* user specified bus ID or driver name - pass to drmOpen */
215 EARLY_INFO_MSG("Opening driver [%s], bus_id [%s]",
216 connection.driver_name ?
217 connection.driver_name : "NULL",
218 connection.bus_id ?
219 connection.bus_id : "NULL");
220 fd = drmOpen(connection.driver_name, connection.bus_id);
Dave Barnishdd948052013-06-25 16:52:37 +0100221 if (fd < 0)
Dave Barnish1a3dac32013-06-20 19:01:38 +0100222 goto fail2;
223 } else {
224 char filename[32];
225 int err;
226 drmSetVersion sv;
227 char *bus_id, *bus_id_copy;
228
229 /* open with card_num */
230 snprintf(filename, sizeof(filename),
231 DRM_DEVICE, connection.card_num);
232 EARLY_INFO_MSG(
233 "No BusID or DriverName specified - opening %s",
234 filename);
235 fd = open(filename, O_RDWR, 0);
236 if (-1 == fd)
237 goto fail2;
238 /* Set interface version to initialise bus id */
239 sv.drm_di_major = 1;
240 sv.drm_di_minor = 1;
241 sv.drm_dd_major = -1;
242 sv.drm_dd_minor = -1;
243 err = drmSetInterfaceVersion(fd, &sv);
244 if (err) {
245 EARLY_ERROR_MSG(
246 "Cannot set the DRM interface version.");
247 goto fail1;
248 }
249 /* get the bus id */
250 bus_id = drmGetBusid(fd);
251 if (!bus_id) {
252 EARLY_ERROR_MSG("Couldn't get BusID from %s",
253 filename);
254 goto fail1;
255 }
256 EARLY_INFO_MSG("Got BusID %s", bus_id);
257 bus_id_copy = malloc(strlen(bus_id)+1);
258 if (!bus_id_copy) {
259 EARLY_ERROR_MSG("Memory alloc failed");
260 goto fail1;
261 }
262 strcpy(bus_id_copy, bus_id);
263 drmFreeBusid(bus_id);
264 err = close(fd);
265 if (err) {
266 free(bus_id_copy);
Dave Barnishdd948052013-06-25 16:52:37 +0100267 EARLY_ERROR_MSG("Couldn't close %s", filename);
Dave Barnish1a3dac32013-06-20 19:01:38 +0100268 goto fail2;
269 }
270 /* use bus_id to open driver */
271 fd = drmOpen(NULL, bus_id_copy);
272 free(bus_id_copy);
Dave Barnishdd948052013-06-25 16:52:37 +0100273 if (fd < 0)
Dave Barnish1a3dac32013-06-20 19:01:38 +0100274 goto fail2;
275 }
276 ARMSOCShowDriverInfo(fd);
277 return fd;
278
279fail1:
280 close(fd);
281fail2:
Dave Barnishdd948052013-06-25 16:52:37 +0100282 EARLY_ERROR_MSG(
283 "Cannot open a connection with the DRM - %s",
284 strerror(errno));
Dave Barnish1a3dac32013-06-20 19:01:38 +0100285 return -1;
286}
287
Rob Clark487687e2011-07-17 17:29:02 -0500288static Bool
Dave Barnishf0952c12013-05-10 15:52:23 +0100289ARMSOCOpenDRM(ScrnInfoPtr pScrn)
Rob Clark487687e2011-07-17 17:29:02 -0500290{
Dave Barnish2e998952013-06-11 16:31:10 +0100291 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500292 drmSetVersion sv;
293 int err;
294
Dave Barnishdd948052013-06-25 16:52:37 +0100295 if (connection.fd < 0) {
Dave Barnishf0952c12013-05-10 15:52:23 +0100296 assert(!connection.open_count);
297 assert(!connection.master_count);
Dave Barnish1a3dac32013-06-20 19:01:38 +0100298 pARMSOC->drmFD = ARMSOCOpenDRMCard();
Dave Barnishdd948052013-06-25 16:52:37 +0100299 if (pARMSOC->drmFD < 0)
Dave Barnishf0952c12013-05-10 15:52:23 +0100300 return FALSE;
Dave Barnish2e998952013-06-11 16:31:10 +0100301 /* Check that what we are or can become drm master by
302 * attempting a drmSetInterfaceVersion(). If successful
303 * this leaves us as master.
Dave Barnishf0952c12013-05-10 15:52:23 +0100304 * (see DRIOpenDRMMaster() in DRI1)
305 */
306 sv.drm_di_major = 1;
307 sv.drm_di_minor = 1;
308 sv.drm_dd_major = -1;
309 sv.drm_dd_minor = -1;
310 err = drmSetInterfaceVersion(pARMSOC->drmFD, &sv);
311 if (err != 0) {
312 ERROR_MSG("Cannot set the DRM interface version.");
313 drmClose(pARMSOC->drmFD);
314 pARMSOC->drmFD = -1;
315 return FALSE;
316 }
317 connection.fd = pARMSOC->drmFD;
318 connection.open_count = 1;
319 connection.master_count = 1;
Ray Smith04af9992013-06-26 13:44:54 +0100320 drmmode_init_wakeup_handler(connection.fd);
Dave Barnish2e998952013-06-11 16:31:10 +0100321 } else {
Dave Barnishf0952c12013-05-10 15:52:23 +0100322 assert(connection.open_count);
323 connection.open_count++;
324 connection.master_count++;
325 pARMSOC->drmFD = connection.fd;
Rob Clark487687e2011-07-17 17:29:02 -0500326 }
Paul Geary8ffd91c2013-04-11 16:03:15 +0100327 pARMSOC->deviceName = drmGetDeviceNameFromFd(pARMSOC->drmFD);
Rob Clark4b8f30a2011-08-28 12:51:26 -0500328
Rob Clark487687e2011-07-17 17:29:02 -0500329 return TRUE;
330}
331
Rob Clark487687e2011-07-17 17:29:02 -0500332/**
333 * Helper function for closing a connection to the DRM.
334 */
335static void
Dave Barnishf0952c12013-05-10 15:52:23 +0100336ARMSOCCloseDRM(ScrnInfoPtr pScrn)
Rob Clark487687e2011-07-17 17:29:02 -0500337{
Dave Barnish2e998952013-06-11 16:31:10 +0100338 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500339
Dave Barnishf0952c12013-05-10 15:52:23 +0100340 if (pARMSOC && (pARMSOC->drmFD >= 0)) {
Paul Geary8ffd91c2013-04-11 16:03:15 +0100341 drmFree(pARMSOC->deviceName);
Dave Barnishf0952c12013-05-10 15:52:23 +0100342 connection.open_count--;
Dave Barnish2e998952013-06-11 16:31:10 +0100343 if (!connection.open_count) {
Dave Barnishf0952c12013-05-10 15:52:23 +0100344 assert(!connection.master_count);
Ray Smith04af9992013-06-26 13:44:54 +0100345 drmmode_fini_wakeup_handler(connection.fd);
Dave Barnishf0952c12013-05-10 15:52:23 +0100346 drmClose(pARMSOC->drmFD);
347 connection.fd = -1;
348 }
Paul Geary8ffd91c2013-04-11 16:03:15 +0100349 pARMSOC->drmFD = -1;
Rob Clark487687e2011-07-17 17:29:02 -0500350 }
351}
352
David Garbettdccb73f2013-09-02 11:48:21 +0100353static Bool ARMSOCCopyFB(ScrnInfoPtr pScrn, const char *fb_dev)
354{
355 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
356 int src_cpp;
357 uint32_t src_pitch;
358 int src_pixman_stride;
359 int dst_pixman_stride;
360 int dst_width, dst_height, dst_bpp, dst_pitch;
361 unsigned int src_size = 0;
362 unsigned char *src = NULL, *dst = NULL;
363 struct fb_var_screeninfo vinfo;
364 int fd = -1;
365 int width, height;
366 pixman_bool_t pixman_ret;
367 Bool ret = FALSE;
368
369 dst = armsoc_bo_map(pARMSOC->scanout);
370 if (!dst) {
371 ERROR_MSG("Couldn't map scanout bo");
372 goto exit;
373 }
374
375 fd = open(fb_dev, O_RDONLY | O_SYNC);
376 if (fd == -1) {
377 ERROR_MSG("Couldn't open %s", fb_dev);
378 goto exit;
379 }
380
381 if (ioctl(fd, FBIOGET_VSCREENINFO, &vinfo) < 0) {
382 ERROR_MSG("Vscreeninfo ioctl failed");
383 goto exit;
384 }
385
386 src_cpp = (vinfo.bits_per_pixel + 7) / 8;
387 src_pitch = vinfo.xres_virtual * src_cpp;
388 src_size = vinfo.yres_virtual * src_pitch;
389
390 src = mmap(NULL, src_size, PROT_READ, MAP_SHARED, fd, 0);
391 if (src == MAP_FAILED) {
392 ERROR_MSG("Couldn't mmap %s", fb_dev);
393 goto exit;
394 }
395
396 dst_width = armsoc_bo_width(pARMSOC->scanout);
397 dst_height = armsoc_bo_height(pARMSOC->scanout);
398 dst_bpp = armsoc_bo_bpp(pARMSOC->scanout);
399 dst_pitch = armsoc_bo_pitch(pARMSOC->scanout);
400
401 width = min(vinfo.xres, dst_width);
402 height = min(vinfo.yres, dst_height);
403
404 /* The stride parameters pixman takes are in multiples of uint32_t,
405 * which is the data type of the pointer passed */
406 src_pixman_stride = src_pitch/sizeof(uint32_t);
407 dst_pixman_stride = dst_pitch/sizeof(uint32_t);
408
409 /* We could handle the cases where stride is not a multiple of uint32_t,
410 * but they will be rare so not currently worth the added complexity */
411 if (src_pitch%sizeof(uint32_t) || dst_pitch%sizeof(uint32_t)) {
412 ERROR_MSG(
413 "Buffer strides need to be a multiple of 4 bytes to initialize from fbdev device");
414 goto exit;
415 }
416
417 /* similarly using pixman_blt doesn't allow for format conversion, so
418 * check if they don't match and print a message */
419 if (vinfo.bits_per_pixel != dst_bpp || vinfo.grayscale != 0 ||
420 vinfo.nonstd != 0 ||
421 vinfo.red.offset != pScrn->offset.red ||
422 vinfo.red.length != pScrn->weight.red ||
423 vinfo.red.msb_right != 0 ||
424 vinfo.green.offset != pScrn->offset.green ||
425 vinfo.green.length != pScrn->weight.green ||
426 vinfo.green.msb_right != 0 ||
427 vinfo.blue.offset != pScrn->offset.blue ||
428 vinfo.blue.length != pScrn->weight.blue ||
429 vinfo.blue.msb_right != 0) {
430 ERROR_MSG("Format of %s does not match scanout buffer", fb_dev);
431 goto exit;
432 }
433
434 armsoc_bo_cpu_prep(pARMSOC->scanout, ARMSOC_GEM_WRITE);
435
436 /* NB: We have to call pixman direct instead of wrapping the buffers as
437 * Pixmaps as this function is called from ScreenInit. Pixmaps cannot be
438 * created until X calls CreateScratchPixmapsForScreen(), and the screen
439 * pixmap is not initialized until X calls CreateScreenResources */
440 pixman_ret = pixman_blt((uint32_t *)src, (uint32_t *)dst,
441 src_pixman_stride, dst_pixman_stride,
442 vinfo.bits_per_pixel, dst_bpp, vinfo.xoffset,
443 vinfo.yoffset, 0, 0, width, height);
444 if (!pixman_ret) {
445 armsoc_bo_cpu_fini(pARMSOC->scanout, 0);
446 ERROR_MSG("Pixman failed to blit from %s to scanout buffer",
447 fb_dev);
448 goto exit;
449 }
450
451 /* fill any area not covered by the blit */
452 if (width < dst_width) {
453 pixman_ret = pixman_fill((uint32_t *)dst, dst_pixman_stride,
454 dst_bpp, width, 0, dst_width-width, dst_height,
455 0);
456 if (!pixman_ret) {
457 armsoc_bo_cpu_fini(pARMSOC->scanout, 0);
458 ERROR_MSG(
459 "Pixman failed to fill margin of scanout buffer");
460 goto exit;
461 }
462 }
463
464 if (height < dst_height) {
465 pixman_ret = pixman_fill((uint32_t *)dst, dst_pixman_stride,
466 dst_bpp, 0, height, width, dst_height-height,
467 0);
468 if (!pixman_ret) {
469 armsoc_bo_cpu_fini(pARMSOC->scanout, 0);
470 ERROR_MSG(
471 "Pixman failed to fill margin of scanout buffer");
472 goto exit;
473 }
474 }
475
476 armsoc_bo_cpu_fini(pARMSOC->scanout, 0);
477
478 ret = TRUE;
479
480exit:
481 if (src)
482 munmap(src, src_size);
483
484 if (fd >= 0)
485 close(fd);
486
487 return ret;
488}
489
490
491
Rob Clark487687e2011-07-17 17:29:02 -0500492/** Let the XFree86 code know the Setup() function. */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100493static MODULESETUPPROTO(ARMSOCSetup);
Rob Clark487687e2011-07-17 17:29:02 -0500494
495/** Provide basic version information to the XFree86 code. */
Dave Barnish2e998952013-06-11 16:31:10 +0100496static XF86ModuleVersionInfo ARMSOCVersRec = {
Paul Geary8ffd91c2013-04-11 16:03:15 +0100497 ARMSOC_DRIVER_NAME,
Rob Clark487687e2011-07-17 17:29:02 -0500498 MODULEVENDORSTRING,
499 MODINFOSTRING1,
500 MODINFOSTRING2,
501 XORG_VERSION_CURRENT,
Dave Barnish2e998952013-06-11 16:31:10 +0100502 PACKAGE_VERSION_MAJOR,
503 PACKAGE_VERSION_MINOR,
504 PACKAGE_VERSION_PATCHLEVEL,
Rob Clark487687e2011-07-17 17:29:02 -0500505 ABI_CLASS_VIDEODRV,
506 ABI_VIDEODRV_VERSION,
507 MOD_CLASS_VIDEODRV,
508 {0, 0, 0, 0}
509};
510
511/** Let the XFree86 code know about the VersRec and Setup() function. */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100512_X_EXPORT XF86ModuleData armsocModuleData = { &ARMSOCVersRec, ARMSOCSetup, NULL };
Rob Clark487687e2011-07-17 17:29:02 -0500513
514
515/**
516 * The first function that the XFree86 code calls, after loading this module.
517 */
518static pointer
Paul Geary8ffd91c2013-04-11 16:03:15 +0100519ARMSOCSetup(pointer module, pointer opts, int *errmaj, int *errmin)
Rob Clark487687e2011-07-17 17:29:02 -0500520{
521 static Bool setupDone = FALSE;
522
523 /* This module should be loaded only once, but check to be sure: */
524 if (!setupDone) {
525 setupDone = TRUE;
Paul Geary8ffd91c2013-04-11 16:03:15 +0100526 xf86AddDriver(&ARMSOC, module, 0);
Rob Clark487687e2011-07-17 17:29:02 -0500527
Dave Barnish2e998952013-06-11 16:31:10 +0100528 /* The return value must be non-NULL on success even
529 * though there is no TearDownProc.
Rob Clark487687e2011-07-17 17:29:02 -0500530 */
531 return (pointer) 1;
532 } else {
533 if (errmaj)
534 *errmaj = LDR_ONCEONLY;
535 return NULL;
536 }
537}
538
Rob Clark487687e2011-07-17 17:29:02 -0500539/**
540 * The mandatory AvailableOptions() function. It returns the available driver
541 * options to the "-configure" option, so that an xorg.conf file can be built
542 * and the user can see which options are available for them to use.
543 */
544static const OptionInfoRec *
Paul Geary8ffd91c2013-04-11 16:03:15 +0100545ARMSOCAvailableOptions(int chipid, int busid)
Rob Clark487687e2011-07-17 17:29:02 -0500546{
Paul Geary8ffd91c2013-04-11 16:03:15 +0100547 return ARMSOCOptions;
Rob Clark487687e2011-07-17 17:29:02 -0500548}
549
550
551
552/**
553 * The mandatory Identify() function. It is run before Probe(), and prints out
554 * an identifying message, which includes the chipset(s) the driver supports.
555 */
556static void
Paul Geary8ffd91c2013-04-11 16:03:15 +0100557ARMSOCIdentify(int flags)
Rob Clark487687e2011-07-17 17:29:02 -0500558{
Paul Geary8ffd91c2013-04-11 16:03:15 +0100559 xf86PrintChipsets(ARMSOC_NAME, "Driver for ARM compatible chipsets",
560 ARMSOCChipsets);
Rob Clark487687e2011-07-17 17:29:02 -0500561}
562
563
564
565/**
Paul Geary8ffd91c2013-04-11 16:03:15 +0100566 * The driver's Probe() function. This function finds all instances of
567 * ARM hardware that the driver supports (from within the "xorg.conf"
Rob Clark487687e2011-07-17 17:29:02 -0500568 * device sections), and for instances not already claimed by another driver,
569 * claim the instances, and allocate a ScrnInfoRec. Only minimal hardware
570 * probing is allowed here.
571 */
572static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +0100573ARMSOCProbe(DriverPtr drv, int flags)
Rob Clark487687e2011-07-17 17:29:02 -0500574{
575 int i;
576 ScrnInfoPtr pScrn;
Dave Barnish2e998952013-06-11 16:31:10 +0100577 GDevPtr *devSections = NULL;
Rob Clark487687e2011-07-17 17:29:02 -0500578 int numDevSections;
579 Bool foundScreen = FALSE;
580
Rob Clark487687e2011-07-17 17:29:02 -0500581 /* Get the "xorg.conf" file device sections that match this driver, and
582 * return (error out) if there are none:
583 */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100584 numDevSections = xf86MatchDevice(ARMSOC_DRIVER_NAME, &devSections);
Rob Clark487687e2011-07-17 17:29:02 -0500585 if (numDevSections <= 0) {
Dave Barnish2e998952013-06-11 16:31:10 +0100586 EARLY_ERROR_MSG(
587 "Did not find any matching device section in configuration file");
Rob Clark83f49e02012-01-08 17:31:59 -0600588 if (flags & PROBE_DETECT) {
589 /* if we are probing, assume one and lets see if we can
590 * open the device to confirm it is there:
591 */
592 numDevSections = 1;
593 } else {
594 return FALSE;
595 }
Rob Clark487687e2011-07-17 17:29:02 -0500596 }
597
598 for (i = 0; i < numDevSections; i++) {
Dave Barnish1a3dac32013-06-20 19:01:38 +0100599 int fd;
600
601 if (devSections) {
Ray Smithb31657f2013-06-25 11:47:36 +0100602 const char *busIdStr;
603 const char *driverNameStr;
604 const char *cardNumStr;
Dave Barnish1a3dac32013-06-20 19:01:38 +0100605
606 /* get the Bus ID */
607 busIdStr = xf86FindOptionValue(
608 devSections[i]->options,
609 "BusID");
610
611 /* get the DriverName */
612 driverNameStr = xf86FindOptionValue(
613 devSections[i]->options,
614 "DriverName");
615
616 /* get the card_num from xorg.conf if present */
617 cardNumStr = xf86FindOptionValue(
618 devSections[i]->options,
619 "DRICard");
620
621 if (busIdStr && driverNameStr) {
622 EARLY_WARNING_MSG(
623 "Option DriverName ignored (BusID is specified)");
624 }
625 if (busIdStr || driverNameStr) {
626 if (cardNumStr) {
627 EARLY_WARNING_MSG(
628 "Option DRICard ignored (BusID or DriverName are specified)");
629 }
630 }
631
632 if (busIdStr) {
633 if (0 == strlen(busIdStr)) {
634 EARLY_ERROR_MSG(
635 "Missing value for Option BusID");
636 return FALSE;
637 }
638 connection.bus_id = busIdStr;
639 } else if (driverNameStr) {
640 if (0 == strlen(driverNameStr)) {
641 EARLY_ERROR_MSG(
642 "Missing value for Option DriverName");
643 return FALSE;
644 }
Ray Smithb31657f2013-06-25 11:47:36 +0100645 connection.driver_name = driverNameStr;
Dave Barnish1a3dac32013-06-20 19:01:38 +0100646 } else if (cardNumStr) {
647 char *endptr;
648 errno = 0;
649 connection.card_num = strtol(cardNumStr,
650 &endptr, 10);
651 if (('\0' == *cardNumStr) ||
652 ('\0' != *endptr) ||
653 (errno != 0)) {
654 EARLY_ERROR_MSG(
655 "Bad Option DRICard value : %s",
656 cardNumStr);
657 return FALSE;
658 }
659 }
660 }
661 fd = ARMSOCOpenDRMCard();
Dave Barnishdd948052013-06-25 16:52:37 +0100662 if (fd >= 0) {
Dave Barnish2e998952013-06-11 16:31:10 +0100663 struct ARMSOCRec *pARMSOC;
Dave Barnishf0952c12013-05-10 15:52:23 +0100664
665 /* Allocate the ScrnInfoRec */
666 pScrn = xf86AllocateScreen(drv, 0);
667 if (!pScrn) {
Dave Barnish2e998952013-06-11 16:31:10 +0100668 EARLY_ERROR_MSG(
669 "Cannot allocate a ScrnInfoPtr");
Dave Barnishf0952c12013-05-10 15:52:23 +0100670 return FALSE;
671 }
Dave Barnish2e998952013-06-11 16:31:10 +0100672 /* Allocate the driver's Screen-specific, "private"
673 * data structure and hook it into the ScrnInfoRec's
674 * driverPrivate field.
675 */
676 pScrn->driverPrivate =
677 calloc(1, sizeof(struct ARMSOCRec));
Dave Barnishf0952c12013-05-10 15:52:23 +0100678 if (!pScrn->driverPrivate)
679 return FALSE;
680
681 pARMSOC = ARMSOCPTR(pScrn);
Dave Barnish1a3dac32013-06-20 19:01:38 +0100682 /* initially mark to use all DRM crtcs */
Dave Barnish2e998952013-06-11 16:31:10 +0100683 pARMSOC->crtcNum = -1;
Rob Clark83f49e02012-01-08 17:31:59 -0600684
685 if (flags & PROBE_DETECT) {
Dave Barnish2e998952013-06-11 16:31:10 +0100686 /* just add the device.. we aren't a PCI device,
687 * so call xf86AddBusDeviceToConfigure()
688 * directly
Rob Clark83f49e02012-01-08 17:31:59 -0600689 */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100690 xf86AddBusDeviceToConfigure(ARMSOC_DRIVER_NAME,
Rob Clark83f49e02012-01-08 17:31:59 -0600691 BUS_NONE, NULL, i);
692 foundScreen = TRUE;
Dave Barnishf0952c12013-05-10 15:52:23 +0100693 drmClose(fd);
Rob Clark83f49e02012-01-08 17:31:59 -0600694 continue;
695 }
Rob Clark487687e2011-07-17 17:29:02 -0500696
Rob Clark83f49e02012-01-08 17:31:59 -0600697 if (devSections) {
Dave Barnish2e998952013-06-11 16:31:10 +0100698 int entity = xf86ClaimNoSlot(drv, 0,
699 devSections[i], TRUE);
Rob Clark83f49e02012-01-08 17:31:59 -0600700 xf86AddEntityToScreen(pScrn, entity);
701 }
Rob Clark487687e2011-07-17 17:29:02 -0500702
Dave Barnish2e998952013-06-11 16:31:10 +0100703 /* if there are multiple screens, use a separate
704 * crtc for each one
705 */
706 if (numDevSections > 1)
Dave Barnishf0952c12013-05-10 15:52:23 +0100707 pARMSOC->crtcNum = i;
Dave Barnishf0952c12013-05-10 15:52:23 +0100708
Dave Barnish2e998952013-06-11 16:31:10 +0100709 xf86Msg(X_INFO, "Screen:%d, CRTC:%d\n",
710 pScrn->scrnIndex,
711 pARMSOC->crtcNum);
Dave Barnishf0952c12013-05-10 15:52:23 +0100712
Rob Clark487687e2011-07-17 17:29:02 -0500713 foundScreen = TRUE;
714
Paul Geary8ffd91c2013-04-11 16:03:15 +0100715 pScrn->driverVersion = ARMSOC_VERSION;
716 pScrn->driverName = (char *)ARMSOC_DRIVER_NAME;
717 pScrn->name = (char *)ARMSOC_NAME;
718 pScrn->Probe = ARMSOCProbe;
719 pScrn->PreInit = ARMSOCPreInit;
720 pScrn->ScreenInit = ARMSOCScreenInit;
721 pScrn->SwitchMode = ARMSOCSwitchMode;
722 pScrn->AdjustFrame = ARMSOCAdjustFrame;
723 pScrn->EnterVT = ARMSOCEnterVT;
724 pScrn->LeaveVT = ARMSOCLeaveVT;
725 pScrn->FreeScreen = ARMSOCFreeScreen;
Rob Clark487687e2011-07-17 17:29:02 -0500726
Dave Barnishf0952c12013-05-10 15:52:23 +0100727 /* would be nice to keep the connection open */
Rob Clark487687e2011-07-17 17:29:02 -0500728 drmClose(fd);
729 }
730 }
731 free(devSections);
732 return foundScreen;
733}
734
Rob Clark487687e2011-07-17 17:29:02 -0500735/**
736 * The driver's PreInit() function. Additional hardware probing is allowed
737 * now, including display configuration.
738 */
739static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +0100740ARMSOCPreInit(ScrnInfoPtr pScrn, int flags)
Rob Clark487687e2011-07-17 17:29:02 -0500741{
Dave Barnish2e998952013-06-11 16:31:10 +0100742 struct ARMSOCRec *pARMSOC;
Rob Clark487687e2011-07-17 17:29:02 -0500743 int default_depth, fbbpp;
744 rgb defaultWeight = { 0, 0, 0 };
745 rgb defaultMask = { 0, 0, 0 };
746 Gamma defaultGamma = { 0.0, 0.0, 0.0 };
Rob Clark487687e2011-07-17 17:29:02 -0500747 int i;
David Garbett4d37be32013-04-04 09:04:29 +0100748 int driNumBufs;
Rob Clark487687e2011-07-17 17:29:02 -0500749
750 TRACE_ENTER();
751
752 if (flags & PROBE_DETECT) {
Dave Barnish2e998952013-06-11 16:31:10 +0100753 ERROR_MSG(
754 "The %s driver does not support the \"-configure\" or \"-probe\" command line arguments.",
755 ARMSOC_NAME);
Rob Clark487687e2011-07-17 17:29:02 -0500756 return FALSE;
757 }
758
759 /* Check the number of entities, and fail if it isn't one. */
760 if (pScrn->numEntities != 1) {
Dave Barnish2e998952013-06-11 16:31:10 +0100761 ERROR_MSG(
762 "Driver expected 1 entity, but found %d for screen %d",
Rob Clark487687e2011-07-17 17:29:02 -0500763 pScrn->numEntities, pScrn->scrnIndex);
764 return FALSE;
765 }
766
Paul Geary8ffd91c2013-04-11 16:03:15 +0100767 pARMSOC = ARMSOCPTR(pScrn);
Paul Geary8ffd91c2013-04-11 16:03:15 +0100768 pARMSOC->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]);
Rob Clark487687e2011-07-17 17:29:02 -0500769
770 pScrn->monitor = pScrn->confScreen->monitor;
771
772 /* Get the current depth, and set it for XFree86: */
Dave Barnish2742d152013-03-13 13:36:58 +0000773 default_depth = 24; /* TODO: MIDEGL-1445: get from kernel */
774 fbbpp = 32; /* TODO: MIDEGL-1445: get from kernel */
Rob Clark487687e2011-07-17 17:29:02 -0500775
776 if (!xf86SetDepthBpp(pScrn, default_depth, 0, fbbpp, Support32bppFb)) {
777 /* The above function prints an error message. */
778 goto fail;
779 }
780 xf86PrintDepthBpp(pScrn);
781
782 /* Set the color weight: */
783 if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
784 /* The above function prints an error message. */
785 goto fail;
786 }
787
788 /* Set the gamma: */
789 if (!xf86SetGamma(pScrn, defaultGamma)) {
790 /* The above function prints an error message. */
791 goto fail;
792 }
793
794 /* Visual init: */
795 if (!xf86SetDefaultVisual(pScrn, -1)) {
796 /* The above function prints an error message. */
797 goto fail;
798 }
799
800 /* We don't support 8-bit depths: */
801 if (pScrn->depth < 16) {
Dave Barnish2e998952013-06-11 16:31:10 +0100802 ERROR_MSG(
803 "The requested default visual (%s) has an unsupported depth (%d).",
804 xf86GetVisualName(pScrn->defaultVisual),
805 pScrn->depth);
Rob Clark487687e2011-07-17 17:29:02 -0500806 goto fail;
807 }
808
809 /* Using a programmable clock: */
810 pScrn->progClock = TRUE;
811
Dave Barnish2e998952013-06-11 16:31:10 +0100812 /* Open a connection to the DRM, so we can communicate
813 * with the KMS code:
814 */
815 if (!ARMSOCOpenDRM(pScrn))
Rob Clark487687e2011-07-17 17:29:02 -0500816 goto fail;
Rob Clark487687e2011-07-17 17:29:02 -0500817
Dave Barnish2e998952013-06-11 16:31:10 +0100818 pARMSOC->drmmode_interface =
819 drmmode_interface_get_implementation(pARMSOC->drmFD);
Dave Barnishde45ed42013-06-05 13:47:56 +0100820 if (!pARMSOC->drmmode_interface)
Dave Barnishf0952c12013-05-10 15:52:23 +0100821 goto fail2;
Ray Smith3c33c3d2013-03-26 16:06:37 +0000822
Rob Clark487687e2011-07-17 17:29:02 -0500823 /* create DRM device instance: */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100824 pARMSOC->dev = armsoc_device_new(pARMSOC->drmFD,
Javier Martin981264d2013-08-21 16:48:07 +0100825 pARMSOC->drmmode_interface->create_custom_gem);
Rob Clark487687e2011-07-17 17:29:02 -0500826
Rob Clark487687e2011-07-17 17:29:02 -0500827 /* find matching chipset name: */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100828 for (i = 0; ARMSOCChipsets[i].name; i++) {
829 if (ARMSOCChipsets[i].token == MALI_T6XX_CHIPSET_ID) {
830 pScrn->chipset = (char *)ARMSOCChipsets[i].name;
Rob Clark487687e2011-07-17 17:29:02 -0500831 break;
832 }
833 }
834
Dave Barnish01b5c172013-04-10 11:01:17 +0100835 INFO_MSG("Chipset: %s", pScrn->chipset);
Rob Clark487687e2011-07-17 17:29:02 -0500836
837 /*
838 * Process the "xorg.conf" file options:
839 */
840 xf86CollectOptions(pScrn, NULL);
Dave Barnish2e998952013-06-11 16:31:10 +0100841 pARMSOC->pOptionInfo = calloc(1, sizeof(ARMSOCOptions));
842 if (!pARMSOC->pOptionInfo)
Dave Barnishf0952c12013-05-10 15:52:23 +0100843 goto fail2;
Dave Barnish2e998952013-06-11 16:31:10 +0100844
Paul Geary8ffd91c2013-04-11 16:03:15 +0100845 memcpy(pARMSOC->pOptionInfo, ARMSOCOptions, sizeof(ARMSOCOptions));
Dave Barnish2e998952013-06-11 16:31:10 +0100846 xf86ProcessOptions(pScrn->scrnIndex,
847 pARMSOC->pEntityInfo->device->options,
Paul Geary8ffd91c2013-04-11 16:03:15 +0100848 pARMSOC->pOptionInfo);
Rob Clark487687e2011-07-17 17:29:02 -0500849
850 /* Determine if the user wants debug messages turned on: */
Dave Barnish2e998952013-06-11 16:31:10 +0100851 armsocDebug = xf86ReturnOptValBool(pARMSOC->pOptionInfo,
852 OPTION_DEBUG, FALSE);
Rob Clark487687e2011-07-17 17:29:02 -0500853
David Garbett4d37be32013-04-04 09:04:29 +0100854 if (!xf86GetOptValInteger(pARMSOC->pOptionInfo, OPTION_DRI_NUM_BUF,
855 &driNumBufs)) {
856 /* Default to double buffering */
857 driNumBufs = 2;
858 }
859
860 if (driNumBufs < 2) {
861 ERROR_MSG(
862 "Invalid option for %s: %d. Must be greater than or equal to 2",
863 xf86TokenToOptName(pARMSOC->pOptionInfo,
864 OPTION_DRI_NUM_BUF),
865 driNumBufs);
866 return FALSE;
867 }
868 pARMSOC->driNumBufs = driNumBufs;
Dave Barnishc50baf52012-11-29 14:39:36 +0000869 /* Determine if user wants to disable buffer flipping: */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100870 pARMSOC->NoFlip = xf86ReturnOptValBool(pARMSOC->pOptionInfo,
Dave Barnishc50baf52012-11-29 14:39:36 +0000871 OPTION_NO_FLIP, FALSE);
Dave Barnish2e998952013-06-11 16:31:10 +0100872 INFO_MSG("Buffer Flipping is %s",
873 pARMSOC->NoFlip ? "Disabled" : "Enabled");
Dave Barnishc50baf52012-11-29 14:39:36 +0000874
Rob Clark487687e2011-07-17 17:29:02 -0500875 /*
876 * Select the video modes:
877 */
878 INFO_MSG("Setting the video modes ...");
879
880 /* Don't call drmCheckModesettingSupported() as its written only for
881 * PCI devices.
882 */
883
884 /* Do initial KMS setup: */
Dave Barnish2e998952013-06-11 16:31:10 +0100885 if (!drmmode_pre_init(pScrn, pARMSOC->drmFD,
886 (pScrn->bitsPerPixel >> 3))) {
Rob Clark487687e2011-07-17 17:29:02 -0500887 ERROR_MSG("Cannot get KMS resources");
Dave Barnishf0952c12013-05-10 15:52:23 +0100888 goto fail2;
Rob Clark487687e2011-07-17 17:29:02 -0500889 } else {
890 INFO_MSG("Got KMS resources");
891 }
892
893 xf86RandR12PreInit(pScrn);
894
895 /* Let XFree86 calculate or get (from command line) the display DPI: */
896 xf86SetDpi(pScrn, 0, 0);
897
898 /* Ensure we have a supported depth: */
899 switch (pScrn->bitsPerPixel) {
900 case 16:
901 case 24:
902 case 32:
903 break;
904 default:
Dave Barnish2e998952013-06-11 16:31:10 +0100905 ERROR_MSG(
906 "The requested number of bits per pixel (%d) is unsupported.",
Rob Clark487687e2011-07-17 17:29:02 -0500907 pScrn->bitsPerPixel);
Dave Barnishf0952c12013-05-10 15:52:23 +0100908 goto fail2;
Rob Clark487687e2011-07-17 17:29:02 -0500909 }
910
911
912 /* Load external sub-modules now: */
913
914 if (!(xf86LoadSubModule(pScrn, "dri2") &&
915 xf86LoadSubModule(pScrn, "exa") &&
916 xf86LoadSubModule(pScrn, "fb"))) {
Dave Barnishf0952c12013-05-10 15:52:23 +0100917 goto fail2;
Rob Clark487687e2011-07-17 17:29:02 -0500918 }
919
Rob Clark487687e2011-07-17 17:29:02 -0500920 TRACE_EXIT();
921 return TRUE;
922
Dave Barnishf0952c12013-05-10 15:52:23 +0100923fail2:
924 /* Cleanup here where we know whether we took a connection
925 * instead of in FreeScreen where we don't */
926 ARMSOCDropDRMMaster();
927 ARMSOCCloseDRM(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500928fail:
929 TRACE_EXIT();
Rob Clark487687e2011-07-17 17:29:02 -0500930 return FALSE;
931}
932
933
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600934/**
935 * Initialize EXA and DRI2
936 */
937static void
Paul Geary8ffd91c2013-04-11 16:03:15 +0100938ARMSOCAccelInit(ScreenPtr pScreen)
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600939{
Daniel Kurtz0361e002013-08-14 21:07:01 +0800940 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +0100941 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600942
Dave Barnish2e998952013-06-11 16:31:10 +0100943 if (!pARMSOC->pARMSOCEXA)
944 pARMSOC->pARMSOCEXA = InitNullEXA(pScreen, pScrn,
945 pARMSOC->drmFD);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600946
Dave Barnish2e998952013-06-11 16:31:10 +0100947 if (pARMSOC->pARMSOCEXA)
Paul Geary8ffd91c2013-04-11 16:03:15 +0100948 pARMSOC->dri = ARMSOCDRI2ScreenInit(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +0100949 else
Paul Geary8ffd91c2013-04-11 16:03:15 +0100950 pARMSOC->dri = FALSE;
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600951}
Rob Clark487687e2011-07-17 17:29:02 -0500952
953/**
Dave Barnishfd50b132013-05-16 15:00:02 +0100954 * The driver's ScreenInit() function, called at the start of each server
Dave Barnish2e998952013-06-11 16:31:10 +0100955 * generation. Fill in pScreen, map the frame buffer, save state,
Dave Barnishfd50b132013-05-16 15:00:02 +0100956 * initialize the mode, etc.
Rob Clark487687e2011-07-17 17:29:02 -0500957 */
958static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +0100959ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500960{
Daniel Kurtz0361e002013-08-14 21:07:01 +0800961 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Dave Barnishdd948052013-06-25 16:52:37 +0100962#ifndef XF86_SCRN_INTERFACE
963 int scrnIndex = pScrn->scrnIndex;
964#endif
Dave Barnish2e998952013-06-11 16:31:10 +0100965 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500966 VisualPtr visual;
967 xf86CrtcConfigPtr xf86_config;
David Garbett82b51832012-07-04 08:29:38 +0100968 int j;
David Garbettdccb73f2013-09-02 11:48:21 +0100969 char *fbdev;
Rob Clark487687e2011-07-17 17:29:02 -0500970
971 TRACE_ENTER();
972
Dave Barnish982518c2013-04-22 16:09:22 +0100973 /* set drm master before allocating scanout buffer */
Dave Barnish2e998952013-06-11 16:31:10 +0100974 if (ARMSOCSetDRMMaster()) {
Dave Barnish982518c2013-04-22 16:09:22 +0100975 ERROR_MSG("Cannot get DRM master: %s", strerror(errno));
Dave Barnishfd50b132013-05-16 15:00:02 +0100976 goto fail;
Dave Barnish982518c2013-04-22 16:09:22 +0100977 }
Dave Barnish52faee02013-04-22 13:28:42 +0100978 /* Allocate initial scanout buffer */
979 DEBUG_MSG("allocating new scanout buffer: %dx%d",
980 pScrn->virtualX, pScrn->virtualY);
Dave Barnish52faee02013-04-22 13:28:42 +0100981 assert(!pARMSOC->scanout);
982 pARMSOC->scanout = armsoc_bo_new_with_dim(pARMSOC->dev, pScrn->virtualX,
983 pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel,
Dave Barnish2e998952013-06-11 16:31:10 +0100984 ARMSOC_BO_SCANOUT);
Dave Barnish52faee02013-04-22 13:28:42 +0100985 if (!pARMSOC->scanout) {
Dave Barnishfd50b132013-05-16 15:00:02 +0100986 ERROR_MSG("Cannot allocate scanout buffer\n");
987 goto fail1;
Dave Barnish52faee02013-04-22 13:28:42 +0100988 }
Dave Barnish2e998952013-06-11 16:31:10 +0100989 pScrn->displayWidth = armsoc_bo_pitch(pARMSOC->scanout) /
990 ((pScrn->bitsPerPixel+7) / 8);
Rob Clark487687e2011-07-17 17:29:02 -0500991 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
992
993 /* need to point to new screen on server regeneration */
David Garbett82b51832012-07-04 08:29:38 +0100994 for (j = 0; j < xf86_config->num_crtc; j++)
995 xf86_config->crtc[j]->scrn = pScrn;
996 for (j = 0; j < xf86_config->num_output; j++)
997 xf86_config->output[j]->scrn = pScrn;
Rob Clark487687e2011-07-17 17:29:02 -0500998
999 /*
1000 * The next step is to setup the screen's visuals, and initialize the
1001 * framebuffer code. In cases where the framebuffer's default
1002 * choices for things like visual layouts and bits per RGB are OK,
1003 * this may be as simple as calling the framebuffer's ScreenInit()
1004 * function. If not, the visuals will need to be setup before calling
1005 * a fb ScreenInit() function and fixed up after.
1006 *
1007 * For most PC hardware at depths >= 8, the defaults that fb uses
1008 * are not appropriate. In this driver, we fixup the visuals after.
1009 */
1010
Dave Barnishfd50b132013-05-16 15:00:02 +01001011 /* Reset the visual list. */
Rob Clark487687e2011-07-17 17:29:02 -05001012 miClearVisualTypes();
Dave Barnish2e998952013-06-11 16:31:10 +01001013 if (!miSetVisualTypes(pScrn->bitsPerPixel,
1014 miGetDefaultVisualMask(pScrn->depth),
Rob Clark487687e2011-07-17 17:29:02 -05001015 pScrn->rgbBits, pScrn->defaultVisual)) {
Dave Barnish2e998952013-06-11 16:31:10 +01001016 ERROR_MSG(
1017 "Cannot initialize the visual type for %d bits per pixel!",
Rob Clark487687e2011-07-17 17:29:02 -05001018 pScrn->bitsPerPixel);
Dave Barnishfd50b132013-05-16 15:00:02 +01001019 goto fail2;
Rob Clark487687e2011-07-17 17:29:02 -05001020 }
1021
Dave Barnish2e998952013-06-11 16:31:10 +01001022 if (pScrn->bitsPerPixel == 32 && pScrn->depth == 24) {
David Garbettef4b7482012-09-26 14:09:01 +01001023 /* Also add a 24 bit depth visual */
1024 if (!miSetVisualTypes(24, miGetDefaultVisualMask(pScrn->depth),
1025 pScrn->rgbBits, pScrn->defaultVisual)) {
Dave Barnish2e998952013-06-11 16:31:10 +01001026 WARNING_MSG(
1027 "Cannot initialize a 24 depth visual for 32bpp");
1028 } else {
David Garbettef4b7482012-09-26 14:09:01 +01001029 INFO_MSG("Initialized a 24 depth visual for 32bpp");
1030 }
1031 }
1032
Rob Clark487687e2011-07-17 17:29:02 -05001033 if (!miSetPixmapDepths()) {
1034 ERROR_MSG("Cannot initialize the pixmap depth!");
Dave Barnishfd50b132013-05-16 15:00:02 +01001035 goto fail3;
Rob Clark487687e2011-07-17 17:29:02 -05001036 }
1037
1038 /* Initialize some generic 2D drawing functions: */
Paul Geary8ffd91c2013-04-11 16:03:15 +01001039 if (!fbScreenInit(pScreen, armsoc_bo_map(pARMSOC->scanout),
Rob Clark487687e2011-07-17 17:29:02 -05001040 pScrn->virtualX, pScrn->virtualY,
1041 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
1042 pScrn->bitsPerPixel)) {
1043 ERROR_MSG("fbScreenInit() failed!");
Dave Barnishfd50b132013-05-16 15:00:02 +01001044 goto fail3;
Rob Clark487687e2011-07-17 17:29:02 -05001045 }
1046
1047 /* Fixup RGB ordering: */
1048 visual = pScreen->visuals + pScreen->numVisuals;
1049 while (--visual >= pScreen->visuals) {
1050 if ((visual->class | DynamicClass) == DirectColor) {
1051 visual->offsetRed = pScrn->offset.red;
1052 visual->offsetGreen = pScrn->offset.green;
1053 visual->offsetBlue = pScrn->offset.blue;
1054 visual->redMask = pScrn->mask.red;
1055 visual->greenMask = pScrn->mask.green;
1056 visual->blueMask = pScrn->mask.blue;
David Garbett100928b2012-10-03 14:20:54 +01001057 visual->bitsPerRGBValue = pScrn->rgbBits;
1058 visual->ColormapEntries = 1 << pScrn->rgbBits;
Rob Clark487687e2011-07-17 17:29:02 -05001059 }
1060 }
1061
Dave Barnish2e998952013-06-11 16:31:10 +01001062 /* Continue initializing the generic 2D drawing functions after
1063 * fixing the RGB ordering:
Rob Clark487687e2011-07-17 17:29:02 -05001064 */
1065 if (!fbPictureInit(pScreen, NULL, 0)) {
1066 ERROR_MSG("fbPictureInit() failed!");
Dave Barnishfd50b132013-05-16 15:00:02 +01001067 goto fail4;
Rob Clark487687e2011-07-17 17:29:02 -05001068 }
1069
1070 /* Set the initial black & white colormap indices: */
1071 xf86SetBlackWhitePixels(pScreen);
1072
Rob Clarkdc9dfae2012-01-11 18:20:18 -06001073 /* Initialize external sub-modules for EXA now, this has to be before
1074 * miDCInitialize() otherwise stacking order for wrapped ScreenPtr fxns
1075 * ends up in the wrong order.
1076 */
Paul Geary8ffd91c2013-04-11 16:03:15 +01001077 ARMSOCAccelInit(pScreen);
Rob Clarkdc9dfae2012-01-11 18:20:18 -06001078
Rob Clark487687e2011-07-17 17:29:02 -05001079 /* Initialize backing store: */
Rob Clark487687e2011-07-17 17:29:02 -05001080 xf86SetBackingStore(pScreen);
1081
David Garbettdccb73f2013-09-02 11:48:21 +01001082 fbdev = xf86GetOptValString(pARMSOC->pOptionInfo,
1083 OPTION_INIT_FROM_FBDEV);
1084 if (fbdev && *fbdev != '\0') {
1085 if (ARMSOCCopyFB(pScrn, fbdev)) {
1086 /* Only allow None BG root if we initialized the scanout
1087 * buffer */
1088 pScreen->canDoBGNoneRoot = TRUE;
1089 }
1090 }
1091
Dave Barnish2e998952013-06-11 16:31:10 +01001092 /* Enable cursor position updates by mouse signal handler: */
Rob Clark687c6082012-01-08 19:33:18 -06001093 xf86SetSilkenMouse(pScreen);
1094
Rob Clark487687e2011-07-17 17:29:02 -05001095 /* Initialize the cursor: */
Dave Barnish2e998952013-06-11 16:31:10 +01001096 if (!miDCInitialize(pScreen, xf86GetPointerScreenFuncs())) {
Dave Barnishfd50b132013-05-16 15:00:02 +01001097 ERROR_MSG("miDCInitialize() failed!");
1098 goto fail5;
Rob Clark687c6082012-01-08 19:33:18 -06001099 }
Rob Clark487687e2011-07-17 17:29:02 -05001100
Dave Barnishfd50b132013-05-16 15:00:02 +01001101 /* ignore failures here as we will fall back to software cursor */
1102 (void)drmmode_cursor_init(pScreen);
1103
1104 /* TODO: MIDEGL-1458: Is this the right place for this?
1105 * The Intel i830 driver says:
Rob Clark487687e2011-07-17 17:29:02 -05001106 * "Must force it before EnterVT, so we are in control of VT..."
1107 */
1108 pScrn->vtSema = TRUE;
1109
Dave Barnish2e998952013-06-11 16:31:10 +01001110 /* Take over the virtual terminal from the console, set the
1111 * desired mode, etc.:
Rob Clark487687e2011-07-17 17:29:02 -05001112 */
Paul Geary8ffd91c2013-04-11 16:03:15 +01001113 if (!ARMSOCEnterVT(VT_FUNC_ARGS(0))) {
1114 ERROR_MSG("ARMSOCEnterVT() failed!");
Dave Barnishfd50b132013-05-16 15:00:02 +01001115 goto fail6;
Rob Clark487687e2011-07-17 17:29:02 -05001116 }
1117
Dave Barnishfd50b132013-05-16 15:00:02 +01001118 /* Do some XRandR initialization. Return value is not useful */
1119 (void)xf86CrtcScreenInit(pScreen);
Rob Clark487687e2011-07-17 17:29:02 -05001120
1121 if (!miCreateDefColormap(pScreen)) {
1122 ERROR_MSG("Cannot create colormap!");
Dave Barnishfd50b132013-05-16 15:00:02 +01001123 goto fail7;
Rob Clark487687e2011-07-17 17:29:02 -05001124 }
1125
David Garbett100928b2012-10-03 14:20:54 +01001126 if (!xf86HandleColormaps(pScreen, 1 << pScrn->rgbBits, pScrn->rgbBits,
Paul Geary8ffd91c2013-04-11 16:03:15 +01001127 ARMSOCLoadPalette, NULL, CMAP_PALETTED_TRUECOLOR)) {
Rob Clark487687e2011-07-17 17:29:02 -05001128 ERROR_MSG("xf86HandleColormaps() failed!");
Dave Barnishfd50b132013-05-16 15:00:02 +01001129 goto fail8;
Rob Clark487687e2011-07-17 17:29:02 -05001130 }
1131
1132 /* Setup power management: */
1133 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
1134
1135 pScreen->SaveScreen = xf86SaveScreen;
1136
1137 /* Wrap some screen functions: */
Paul Geary8ffd91c2013-04-11 16:03:15 +01001138 wrap(pARMSOC, pScreen, CloseScreen, ARMSOCCloseScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001139 wrap(pARMSOC, pScreen, CreateScreenResources,
1140 ARMSOCCreateScreenResources);
Paul Geary8ffd91c2013-04-11 16:03:15 +01001141 wrap(pARMSOC, pScreen, BlockHandler, ARMSOCBlockHandler);
Rob Clark4b8f30a2011-08-28 12:51:26 -05001142 drmmode_screen_init(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001143
1144 TRACE_EXIT();
1145 return TRUE;
1146
Dave Barnishfd50b132013-05-16 15:00:02 +01001147/* cleanup on failures */
1148fail8:
1149 /* uninstall the default colormap */
1150 miUninstallColormap(GetInstalledmiColormap(pScreen));
1151
1152fail7:
1153 ARMSOCLeaveVT(VT_FUNC_ARGS(0));
1154 pScrn->vtSema = FALSE;
1155
1156fail6:
1157 drmmode_cursor_fini(pScreen);
1158
1159fail5:
Dave Barnish2e998952013-06-11 16:31:10 +01001160 if (pARMSOC->dri)
Dave Barnishfd50b132013-05-16 15:00:02 +01001161 ARMSOCDRI2CloseScreen(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001162
1163 if (pARMSOC->pARMSOCEXA)
1164 if (pARMSOC->pARMSOCEXA->CloseScreen)
Dave Barnishdd948052013-06-25 16:52:37 +01001165 pARMSOC->pARMSOCEXA->CloseScreen(CLOSE_SCREEN_ARGS);
Dave Barnishfd50b132013-05-16 15:00:02 +01001166fail4:
1167 /* Call the CloseScreen functions for fbInitScreen, miDCInitialize,
Dave Barnish2e998952013-06-11 16:31:10 +01001168 * exaDriverInit & xf86CrtcScreenInit as appropriate via their
1169 * wrapped pointers.
Dave Barnishfd50b132013-05-16 15:00:02 +01001170 * exaDDXCloseScreen uses the XF86SCRNINFO macro so we must
1171 * set up the key for this before it gets called.
1172 */
1173 dixSetPrivate(&pScreen->devPrivates, xf86ScreenKey, pScrn);
Dave Barnishdd948052013-06-25 16:52:37 +01001174 (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
Dave Barnishfd50b132013-05-16 15:00:02 +01001175
1176fail3:
1177 /* reset the visual list */
1178 miClearVisualTypes();
1179
1180fail2:
1181 /* release the scanout buffer */
1182 armsoc_bo_unreference(pARMSOC->scanout);
1183 pARMSOC->scanout = NULL;
1184 pScrn->displayWidth = 0;
1185
1186fail1:
1187 /* drop drm master */
1188 (void)drmDropMaster(pARMSOC->drmFD);
1189
Rob Clark487687e2011-07-17 17:29:02 -05001190fail:
1191 TRACE_EXIT();
1192 return FALSE;
1193}
1194
1195
1196static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001197ARMSOCLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
Dave Barnish2e998952013-06-11 16:31:10 +01001198 LOCO *colors, VisualPtr pVisual)
Rob Clark487687e2011-07-17 17:29:02 -05001199{
1200 TRACE_ENTER();
1201 TRACE_EXIT();
1202}
1203
1204
1205/**
1206 * The driver's CloseScreen() function. This is called at the end of each
1207 * server generation. Restore state, unmap the frame buffer (and any other
1208 * mapped memory regions), and free per-Screen data structures (except those
1209 * held by pScrn).
1210 */
1211static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +01001212ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001213{
Cooper Yuana83caa62012-06-28 17:19:06 +02001214 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001215 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Daniel Kurtz22437e92013-07-30 13:28:46 +08001216 Bool ret;
Rob Clark487687e2011-07-17 17:29:02 -05001217
1218 TRACE_ENTER();
1219
Rob Clark4b8f30a2011-08-28 12:51:26 -05001220 drmmode_screen_fini(pScrn);
Dave Barnishcaed3a12013-11-14 08:52:10 +00001221 drmmode_cursor_fini(pScreen);
1222
1223 /* pScreen->devPrivate holds the root pixmap created around our bo by miCreateResources which is installed
1224 * by fbScreenInit() when called from ARMSOCScreenInit().
1225 * This pixmap should be destroyed in miScreenClose() but this isn't wrapped by fbScreenInit() so to prevent a leak
1226 * we do it here, before calling the CloseScreen chain which would just free pScreen->devPrivate in fbCloseScreen()
1227 */
1228 if (pScreen->devPrivate) {
1229 (void) (*pScreen->DestroyPixmap)(pScreen->devPrivate);
1230 pScreen->devPrivate = NULL;
1231 }
Rob Clark487687e2011-07-17 17:29:02 -05001232
Daniel Kurtz22437e92013-07-30 13:28:46 +08001233 unwrap(pARMSOC, pScreen, CloseScreen);
1234 unwrap(pARMSOC, pScreen, BlockHandler);
1235 unwrap(pARMSOC, pScreen, CreateScreenResources);
1236
Dave Barnishc0bf2302013-09-02 14:55:58 +01001237 ret = (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
Daniel Kurtz22437e92013-07-30 13:28:46 +08001238
Dave Barnish2e998952013-06-11 16:31:10 +01001239 if (pARMSOC->dri)
Dave Barnishfd50b132013-05-16 15:00:02 +01001240 ARMSOCDRI2CloseScreen(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001241
1242 if (pARMSOC->pARMSOCEXA)
1243 if (pARMSOC->pARMSOCEXA->CloseScreen)
Paul Geary8ffd91c2013-04-11 16:03:15 +01001244 pARMSOC->pARMSOCEXA->CloseScreen(CLOSE_SCREEN_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -05001245
Dave Barnishcaed3a12013-11-14 08:52:10 +00001246 /* scanout buffer is released when root pixmap is destroyed */
Dave Barnish52faee02013-04-22 13:28:42 +01001247 pARMSOC->scanout = NULL;
Dave Barnishcaed3a12013-11-14 08:52:10 +00001248
Dave Barnish52faee02013-04-22 13:28:42 +01001249 pScrn->displayWidth = 0;
Rob Clark487687e2011-07-17 17:29:02 -05001250
Dave Barnish2e998952013-06-11 16:31:10 +01001251 if (pScrn->vtSema == TRUE)
Dave Barnish982518c2013-04-22 16:09:22 +01001252 ARMSOCLeaveVT(VT_FUNC_ARGS(0));
Dave Barnish2e998952013-06-11 16:31:10 +01001253
Rob Clark487687e2011-07-17 17:29:02 -05001254 pScrn->vtSema = FALSE;
1255
Rob Clark487687e2011-07-17 17:29:02 -05001256 TRACE_EXIT();
1257
Daniel Kurtz22437e92013-07-30 13:28:46 +08001258 return ret;
Rob Clark487687e2011-07-17 17:29:02 -05001259}
1260
1261
1262
1263/**
1264 * Adjust the screen pixmap for the current location of the front buffer.
1265 * This is done at EnterVT when buffers are bound as long as the resources
1266 * have already been created, but the first EnterVT happens before
1267 * CreateScreenResources.
1268 */
1269static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +01001270ARMSOCCreateScreenResources(ScreenPtr pScreen)
Rob Clark487687e2011-07-17 17:29:02 -05001271{
Daniel Kurtz0361e002013-08-14 21:07:01 +08001272 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001273 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001274
Paul Geary8ffd91c2013-04-11 16:03:15 +01001275 swap(pARMSOC, pScreen, CreateScreenResources);
Rob Clark487687e2011-07-17 17:29:02 -05001276 if (!(*pScreen->CreateScreenResources) (pScreen))
1277 return FALSE;
Paul Geary8ffd91c2013-04-11 16:03:15 +01001278 swap(pARMSOC, pScreen, CreateScreenResources);
Rob Clark487687e2011-07-17 17:29:02 -05001279
1280 return TRUE;
1281}
1282
1283
1284static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001285ARMSOCBlockHandler(BLOCKHANDLER_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001286{
Cooper Yuana83caa62012-06-28 17:19:06 +02001287 SCREEN_PTR(arg);
1288 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001289 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001290
Paul Geary8ffd91c2013-04-11 16:03:15 +01001291 swap(pARMSOC, pScreen, BlockHandler);
Cooper Yuana83caa62012-06-28 17:19:06 +02001292 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
Paul Geary8ffd91c2013-04-11 16:03:15 +01001293 swap(pARMSOC, pScreen, BlockHandler);
Rob Clark487687e2011-07-17 17:29:02 -05001294}
1295
1296
1297
1298/**
1299 * The driver's SwitchMode() function. Initialize the new mode for the
1300 * Screen.
1301 */
1302static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +01001303ARMSOCSwitchMode(SWITCH_MODE_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001304{
Cooper Yuana83caa62012-06-28 17:19:06 +02001305 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -05001306 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
1307}
1308
1309
1310
1311/**
1312 * The driver's AdjustFrame() function. For cases where the frame buffer is
1313 * larger than the monitor resolution, this function can pan around the frame
1314 * buffer within the "viewport" of the monitor.
1315 */
1316static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001317ARMSOCAdjustFrame(ADJUST_FRAME_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001318{
Cooper Yuana83caa62012-06-28 17:19:06 +02001319 SCRN_INFO_PTR(arg);
1320 drmmode_adjust_frame(pScrn, x, y);
Rob Clark487687e2011-07-17 17:29:02 -05001321}
1322
1323
1324
1325/**
1326 * The driver's EnterVT() function. This is called at server startup time, and
1327 * when the X server takes over the virtual terminal from the console. As
1328 * such, it may need to save the current (i.e. console) HW state, and set the
1329 * HW state as needed by the X server.
1330 */
1331static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +01001332ARMSOCEnterVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001333{
Cooper Yuana83caa62012-06-28 17:19:06 +02001334 SCRN_INFO_PTR(arg);
Ray Smith6ae735f2013-03-21 15:57:18 +00001335 int i, ret;
abhinav.kd4bab322012-07-31 11:29:19 -07001336
Rob Clark487687e2011-07-17 17:29:02 -05001337 TRACE_ENTER();
1338
Ray Smith6ae735f2013-03-21 15:57:18 +00001339 for (i = 1; i < currentMaxClients; i++) {
1340 if (clients[i])
1341 AttendClient(clients[i]);
1342 }
1343
Dave Barnishf0952c12013-05-10 15:52:23 +01001344 ret = ARMSOCSetDRMMaster();
Rob Clark487687e2011-07-17 17:29:02 -05001345 if (ret) {
Daniel Kurtz92205962013-02-05 13:50:12 +08001346 ERROR_MSG("Cannot get DRM master: %s", strerror(errno));
Daniel Kurtz01a91f62013-02-05 10:19:51 +08001347 return FALSE;
Rob Clark487687e2011-07-17 17:29:02 -05001348 }
1349
1350 if (!xf86SetDesiredModes(pScrn)) {
1351 ERROR_MSG("xf86SetDesiredModes() failed!");
1352 return FALSE;
1353 }
1354
1355 TRACE_EXIT();
1356 return TRUE;
1357}
1358
1359
1360
1361/**
1362 * The driver's LeaveVT() function. This is called when the X server
1363 * temporarily gives up the virtual terminal to the console. As such, it may
1364 * need to restore the console's HW state.
1365 */
1366static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001367ARMSOCLeaveVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001368{
Cooper Yuana83caa62012-06-28 17:19:06 +02001369 SCRN_INFO_PTR(arg);
Ray Smith6ae735f2013-03-21 15:57:18 +00001370 int i, ret;
abhinav.kd4bab322012-07-31 11:29:19 -07001371
Rob Clark487687e2011-07-17 17:29:02 -05001372 TRACE_ENTER();
1373
Ray Smith6ae735f2013-03-21 15:57:18 +00001374 for (i = 1; i < currentMaxClients; i++) {
1375 if (clients[i])
1376 IgnoreClient(clients[i]);
1377 }
1378
Dave Barnishf0952c12013-05-10 15:52:23 +01001379 ret = ARMSOCDropDRMMaster();
Dave Barnish2e998952013-06-11 16:31:10 +01001380 if (ret)
Daniel Kurtz92205962013-02-05 13:50:12 +08001381 WARNING_MSG("drmDropMaster failed: %s", strerror(errno));
Rob Clark487687e2011-07-17 17:29:02 -05001382
1383 TRACE_EXIT();
1384}
1385
Rob Clark487687e2011-07-17 17:29:02 -05001386/**
Dave Barnish982518c2013-04-22 16:09:22 +01001387 * The driver's FreeScreen() function.
Dave Barnish2e998952013-06-11 16:31:10 +01001388 * Frees the ScrnInfoRec driverPrivate field when a screen is
1389 * deleted by the common layer.
Dave Barnish982518c2013-04-22 16:09:22 +01001390 * This function is not used in normal (error free) operation.
Rob Clark487687e2011-07-17 17:29:02 -05001391 */
1392static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001393ARMSOCFreeScreen(FREE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001394{
Cooper Yuana83caa62012-06-28 17:19:06 +02001395 SCRN_INFO_PTR(arg);
Dave Barnish2e998952013-06-11 16:31:10 +01001396 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001397
1398 TRACE_ENTER();
1399
Paul Geary8ffd91c2013-04-11 16:03:15 +01001400 if (!pARMSOC) {
Rob Clark487687e2011-07-17 17:29:02 -05001401 /* This can happen if a Screen is deleted after Probe(): */
1402 return;
1403 }
1404
Paul Geary8ffd91c2013-04-11 16:03:15 +01001405 if (pARMSOC->pARMSOCEXA) {
Dave Barnish2e998952013-06-11 16:31:10 +01001406 if (pARMSOC->pARMSOCEXA->FreeScreen)
1407 pARMSOC->pARMSOCEXA->FreeScreen(
1408 FREE_SCREEN_ARGS(pScrn));
Rob Clark487687e2011-07-17 17:29:02 -05001409 }
1410
Paul Geary8ffd91c2013-04-11 16:03:15 +01001411 armsoc_device_del(pARMSOC->dev);
Rob Clark487687e2011-07-17 17:29:02 -05001412
Dave Barnishf0952c12013-05-10 15:52:23 +01001413 /* Free the driver's Screen-specific, "private" data structure and
1414 * NULL-out the ScrnInfoRec's driverPrivate field.
1415 */
1416 if (pScrn->driverPrivate) {
1417 free(pScrn->driverPrivate);
1418 pScrn->driverPrivate = NULL;
1419 }
Rob Clark487687e2011-07-17 17:29:02 -05001420
1421 TRACE_EXIT();
1422}
1423