blob: 7b9986370fe195c02a38d8cec4b05fe230101b48 [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>
Raymond Smith41ecf3e2012-05-01 14:51:34 +010034
Rob Clark487687e2011-07-17 17:29:02 -050035#ifdef HAVE_CONFIG_H
36#include "config.h"
37#endif
38
Paul Gearyf8b99692013-04-15 10:55:17 +010039#include "armsoc_driver.h"
Dave Barnish257c6f12013-06-05 17:00:29 +010040
41#include "micmap.h"
42
43#include "xf86cmap.h"
44#include "xf86RandR12.h"
45
Cooper Yuana83caa62012-06-28 17:19:06 +020046#include "compat-api.h"
Rob Clark487687e2011-07-17 17:29:02 -050047
Ray Smith3c33c3d2013-03-26 16:06:37 +000048#include "drmmode_driver.h"
49
Dave Barnish1a3dac32013-06-20 19:01:38 +010050#define DRM_DEVICE "/dev/dri/card%d"
Dave Barnishf0952c12013-05-10 15:52:23 +010051
Dave Barnish2e998952013-06-11 16:31:10 +010052Bool armsocDebug;
Rob Clark487687e2011-07-17 17:29:02 -050053
54/*
55 * Forward declarations:
56 */
Paul Geary8ffd91c2013-04-11 16:03:15 +010057static const OptionInfoRec *ARMSOCAvailableOptions(int chipid, int busid);
58static void ARMSOCIdentify(int flags);
59static Bool ARMSOCProbe(DriverPtr drv, int flags);
60static Bool ARMSOCPreInit(ScrnInfoPtr pScrn, int flags);
61static Bool ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL);
62static void ARMSOCLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
Dave Barnish2e998952013-06-11 16:31:10 +010063 LOCO *colors, VisualPtr pVisual);
Paul Geary8ffd91c2013-04-11 16:03:15 +010064static Bool ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL);
65static Bool ARMSOCCreateScreenResources(ScreenPtr pScreen);
66static void ARMSOCBlockHandler(BLOCKHANDLER_ARGS_DECL);
67static Bool ARMSOCSwitchMode(SWITCH_MODE_ARGS_DECL);
68static void ARMSOCAdjustFrame(ADJUST_FRAME_ARGS_DECL);
69static Bool ARMSOCEnterVT(VT_FUNC_ARGS_DECL);
70static void ARMSOCLeaveVT(VT_FUNC_ARGS_DECL);
71static void ARMSOCFreeScreen(FREE_SCREEN_ARGS_DECL);
Rob Clark487687e2011-07-17 17:29:02 -050072
73
74
75/**
76 * A structure used by the XFree86 code when loading this driver, so that it
77 * can access the Probe() function, and other functions/info that it uses
78 * before it calls the Probe() function. The name of this structure must be
79 * the all-upper-case version of the driver name.
80 */
Paul Geary8ffd91c2013-04-11 16:03:15 +010081_X_EXPORT DriverRec ARMSOC = {
82 ARMSOC_VERSION,
83 (char *)ARMSOC_DRIVER_NAME,
84 ARMSOCIdentify,
85 ARMSOCProbe,
86 ARMSOCAvailableOptions,
Rob Clark487687e2011-07-17 17:29:02 -050087 NULL,
88 0,
89 NULL,
90#ifdef XSERVER_LIBPCIACCESS
91 NULL,
92 NULL
93#endif
94};
95
Dave Barnish01b5c172013-04-10 11:01:17 +010096#define MALI_4XX_CHIPSET_ID (0x0400)
97#define MALI_T6XX_CHIPSET_ID (0x0600)
98
Rob Clark487687e2011-07-17 17:29:02 -050099/** Supported "chipsets." */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100100static SymTabRec ARMSOCChipsets[] = {
Dave Barnish01b5c172013-04-10 11:01:17 +0100101 { MALI_4XX_CHIPSET_ID, "Mali-4XX" },
102 { MALI_T6XX_CHIPSET_ID, "Mali-T6XX" },
Rob Clark487687e2011-07-17 17:29:02 -0500103 {-1, NULL }
104};
105
106/** Supported options, as enum values. */
Dave Barnish2e998952013-06-11 16:31:10 +0100107enum {
Rob Clark487687e2011-07-17 17:29:02 -0500108 OPTION_DEBUG,
Dave Barnishc50baf52012-11-29 14:39:36 +0000109 OPTION_NO_FLIP,
Dave Barnish1a3dac32013-06-20 19:01:38 +0100110 OPTION_CARD_NUM,
111 OPTION_BUSID,
112 OPTION_DRIVERNAME,
David Garbett4d37be32013-04-04 09:04:29 +0100113 OPTION_DRI_NUM_BUF,
Dave Barnish2e998952013-06-11 16:31:10 +0100114};
Rob Clark487687e2011-07-17 17:29:02 -0500115
116/** Supported options. */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100117static const OptionInfoRec ARMSOCOptions[] = {
Dave Barnish1a3dac32013-06-20 19:01:38 +0100118 { OPTION_DEBUG, "Debug", OPTV_BOOLEAN, {0}, FALSE },
119 { OPTION_NO_FLIP, "NoFlip", OPTV_BOOLEAN, {0}, FALSE },
120 { OPTION_CARD_NUM, "DRICard", OPTV_INTEGER, {0}, FALSE },
121 { OPTION_BUSID, "BusID", OPTV_STRING, {0}, FALSE },
122 { OPTION_DRIVERNAME, "DriverName", OPTV_STRING, {0}, FALSE },
David Garbett4d37be32013-04-04 09:04:29 +0100123 { OPTION_DRI_NUM_BUF, "DRI2MaxBuffers", OPTV_INTEGER, {-1}, FALSE },
Dave Barnish1a3dac32013-06-20 19:01:38 +0100124 { -1, NULL, OPTV_NONE, {0}, FALSE }
Rob Clark487687e2011-07-17 17:29:02 -0500125};
126
127/**
Dave Barnishf0952c12013-05-10 15:52:23 +0100128 * Helper functions for sharing a DRM connection across screens.
Rob Clark487687e2011-07-17 17:29:02 -0500129 */
Dave Barnishf0952c12013-05-10 15:52:23 +0100130static struct ARMSOCConnection {
Ray Smithb31657f2013-06-25 11:47:36 +0100131 const char *driver_name;
132 const char *bus_id;
Dave Barnish1a3dac32013-06-20 19:01:38 +0100133 unsigned int card_num;
Dave Barnishf0952c12013-05-10 15:52:23 +0100134 int fd;
135 int open_count;
136 int master_count;
Dave Barnish1a3dac32013-06-20 19:01:38 +0100137} connection = {NULL, NULL, 0, -1, 0, 0};
Rob Clark487687e2011-07-17 17:29:02 -0500138
139static int
Dave Barnishf0952c12013-05-10 15:52:23 +0100140ARMSOCSetDRMMaster(void)
Rob Clark487687e2011-07-17 17:29:02 -0500141{
Dave Barnish2e998952013-06-11 16:31:10 +0100142 int ret = 0;
Dave Barnishf0952c12013-05-10 15:52:23 +0100143
Dave Barnish2e998952013-06-11 16:31:10 +0100144 assert(connection.fd >= 0);
Dave Barnishf0952c12013-05-10 15:52:23 +0100145
Dave Barnish2e998952013-06-11 16:31:10 +0100146 if (!connection.master_count)
Dave Barnishf0952c12013-05-10 15:52:23 +0100147 ret = drmSetMaster(connection.fd);
Dave Barnish2e998952013-06-11 16:31:10 +0100148
149 if (!ret)
Dave Barnishf0952c12013-05-10 15:52:23 +0100150 connection.master_count++;
Dave Barnish2e998952013-06-11 16:31:10 +0100151
Dave Barnishf0952c12013-05-10 15:52:23 +0100152 return ret;
153}
154
155static int
156ARMSOCDropDRMMaster(void)
157{
158 int ret = 0;
159
Dave Barnish2e998952013-06-11 16:31:10 +0100160 assert(connection.fd >= 0);
161 assert(connection.master_count > 0);
Dave Barnishf0952c12013-05-10 15:52:23 +0100162
Dave Barnish2e998952013-06-11 16:31:10 +0100163 if (1 == connection.master_count)
Dave Barnishf0952c12013-05-10 15:52:23 +0100164 ret = drmDropMaster(connection.fd);
Dave Barnish2e998952013-06-11 16:31:10 +0100165
166 if (!ret)
Dave Barnishf0952c12013-05-10 15:52:23 +0100167 connection.master_count--;
Dave Barnish2e998952013-06-11 16:31:10 +0100168
Dave Barnishf0952c12013-05-10 15:52:23 +0100169 return ret;
Rob Clark487687e2011-07-17 17:29:02 -0500170}
171
Dave Barnish1a3dac32013-06-20 19:01:38 +0100172static void
173ARMSOCShowDriverInfo(int fd)
174{
175 char *bus_id;
176 drmVersionPtr version;
177 char *deviceName;
178
179 EARLY_INFO_MSG("Opened DRM");
180 deviceName = drmGetDeviceNameFromFd(fd);
181 EARLY_INFO_MSG(" DeviceName is [%s]",
182 deviceName ? deviceName : "NULL");
183 drmFree(deviceName);
184 bus_id = drmGetBusid(fd);
185 EARLY_INFO_MSG(" bus_id is [%s]",
186 bus_id ? bus_id : "NULL");
187 drmFreeBusid(bus_id);
188 version = drmGetVersion(fd);
189 if (version) {
190 EARLY_INFO_MSG(" DriverName is [%s]",
191 version->name);
192 EARLY_INFO_MSG(" version is [%d.%d.%d]",
193 version->version_major,
194 version->version_minor,
195 version->version_patchlevel);
196 drmFreeVersion(version);
197 } else {
198 EARLY_INFO_MSG(" version is [NULL]");
199 }
200 return;
201}
202
203static int
204ARMSOCOpenDRMCard(void)
205{
206 int fd;
207
208 if ((connection.bus_id) || (connection.driver_name)) {
209 /* user specified bus ID or driver name - pass to drmOpen */
210 EARLY_INFO_MSG("Opening driver [%s], bus_id [%s]",
211 connection.driver_name ?
212 connection.driver_name : "NULL",
213 connection.bus_id ?
214 connection.bus_id : "NULL");
215 fd = drmOpen(connection.driver_name, connection.bus_id);
Dave Barnishdd948052013-06-25 16:52:37 +0100216 if (fd < 0)
Dave Barnish1a3dac32013-06-20 19:01:38 +0100217 goto fail2;
218 } else {
219 char filename[32];
220 int err;
221 drmSetVersion sv;
222 char *bus_id, *bus_id_copy;
223
224 /* open with card_num */
225 snprintf(filename, sizeof(filename),
226 DRM_DEVICE, connection.card_num);
227 EARLY_INFO_MSG(
228 "No BusID or DriverName specified - opening %s",
229 filename);
230 fd = open(filename, O_RDWR, 0);
231 if (-1 == fd)
232 goto fail2;
233 /* Set interface version to initialise bus id */
234 sv.drm_di_major = 1;
235 sv.drm_di_minor = 1;
236 sv.drm_dd_major = -1;
237 sv.drm_dd_minor = -1;
238 err = drmSetInterfaceVersion(fd, &sv);
239 if (err) {
240 EARLY_ERROR_MSG(
241 "Cannot set the DRM interface version.");
242 goto fail1;
243 }
244 /* get the bus id */
245 bus_id = drmGetBusid(fd);
246 if (!bus_id) {
247 EARLY_ERROR_MSG("Couldn't get BusID from %s",
248 filename);
249 goto fail1;
250 }
251 EARLY_INFO_MSG("Got BusID %s", bus_id);
252 bus_id_copy = malloc(strlen(bus_id)+1);
253 if (!bus_id_copy) {
254 EARLY_ERROR_MSG("Memory alloc failed");
255 goto fail1;
256 }
257 strcpy(bus_id_copy, bus_id);
258 drmFreeBusid(bus_id);
259 err = close(fd);
260 if (err) {
261 free(bus_id_copy);
Dave Barnishdd948052013-06-25 16:52:37 +0100262 EARLY_ERROR_MSG("Couldn't close %s", filename);
Dave Barnish1a3dac32013-06-20 19:01:38 +0100263 goto fail2;
264 }
265 /* use bus_id to open driver */
266 fd = drmOpen(NULL, bus_id_copy);
267 free(bus_id_copy);
Dave Barnishdd948052013-06-25 16:52:37 +0100268 if (fd < 0)
Dave Barnish1a3dac32013-06-20 19:01:38 +0100269 goto fail2;
270 }
271 ARMSOCShowDriverInfo(fd);
272 return fd;
273
274fail1:
275 close(fd);
276fail2:
Dave Barnishdd948052013-06-25 16:52:37 +0100277 EARLY_ERROR_MSG(
278 "Cannot open a connection with the DRM - %s",
279 strerror(errno));
Dave Barnish1a3dac32013-06-20 19:01:38 +0100280 return -1;
281}
282
Rob Clark487687e2011-07-17 17:29:02 -0500283static Bool
Dave Barnishf0952c12013-05-10 15:52:23 +0100284ARMSOCOpenDRM(ScrnInfoPtr pScrn)
Rob Clark487687e2011-07-17 17:29:02 -0500285{
Dave Barnish2e998952013-06-11 16:31:10 +0100286 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500287 drmSetVersion sv;
288 int err;
289
Dave Barnishdd948052013-06-25 16:52:37 +0100290 if (connection.fd < 0) {
Dave Barnishf0952c12013-05-10 15:52:23 +0100291 assert(!connection.open_count);
292 assert(!connection.master_count);
Dave Barnish1a3dac32013-06-20 19:01:38 +0100293 pARMSOC->drmFD = ARMSOCOpenDRMCard();
Dave Barnishdd948052013-06-25 16:52:37 +0100294 if (pARMSOC->drmFD < 0)
Dave Barnishf0952c12013-05-10 15:52:23 +0100295 return FALSE;
Dave Barnish2e998952013-06-11 16:31:10 +0100296 /* Check that what we are or can become drm master by
297 * attempting a drmSetInterfaceVersion(). If successful
298 * this leaves us as master.
Dave Barnishf0952c12013-05-10 15:52:23 +0100299 * (see DRIOpenDRMMaster() in DRI1)
300 */
301 sv.drm_di_major = 1;
302 sv.drm_di_minor = 1;
303 sv.drm_dd_major = -1;
304 sv.drm_dd_minor = -1;
305 err = drmSetInterfaceVersion(pARMSOC->drmFD, &sv);
306 if (err != 0) {
307 ERROR_MSG("Cannot set the DRM interface version.");
308 drmClose(pARMSOC->drmFD);
309 pARMSOC->drmFD = -1;
310 return FALSE;
311 }
312 connection.fd = pARMSOC->drmFD;
313 connection.open_count = 1;
314 connection.master_count = 1;
Ray Smith04af9992013-06-26 13:44:54 +0100315 drmmode_init_wakeup_handler(connection.fd);
Dave Barnish2e998952013-06-11 16:31:10 +0100316 } else {
Dave Barnishf0952c12013-05-10 15:52:23 +0100317 assert(connection.open_count);
318 connection.open_count++;
319 connection.master_count++;
320 pARMSOC->drmFD = connection.fd;
Rob Clark487687e2011-07-17 17:29:02 -0500321 }
Paul Geary8ffd91c2013-04-11 16:03:15 +0100322 pARMSOC->deviceName = drmGetDeviceNameFromFd(pARMSOC->drmFD);
Rob Clark4b8f30a2011-08-28 12:51:26 -0500323
Rob Clark487687e2011-07-17 17:29:02 -0500324 return TRUE;
325}
326
Rob Clark487687e2011-07-17 17:29:02 -0500327/**
328 * Helper function for closing a connection to the DRM.
329 */
330static void
Dave Barnishf0952c12013-05-10 15:52:23 +0100331ARMSOCCloseDRM(ScrnInfoPtr pScrn)
Rob Clark487687e2011-07-17 17:29:02 -0500332{
Dave Barnish2e998952013-06-11 16:31:10 +0100333 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500334
Dave Barnishf0952c12013-05-10 15:52:23 +0100335 if (pARMSOC && (pARMSOC->drmFD >= 0)) {
Paul Geary8ffd91c2013-04-11 16:03:15 +0100336 drmFree(pARMSOC->deviceName);
Dave Barnishf0952c12013-05-10 15:52:23 +0100337 connection.open_count--;
Dave Barnish2e998952013-06-11 16:31:10 +0100338 if (!connection.open_count) {
Dave Barnishf0952c12013-05-10 15:52:23 +0100339 assert(!connection.master_count);
Ray Smith04af9992013-06-26 13:44:54 +0100340 drmmode_fini_wakeup_handler(connection.fd);
Dave Barnishf0952c12013-05-10 15:52:23 +0100341 drmClose(pARMSOC->drmFD);
342 connection.fd = -1;
343 }
Paul Geary8ffd91c2013-04-11 16:03:15 +0100344 pARMSOC->drmFD = -1;
Rob Clark487687e2011-07-17 17:29:02 -0500345 }
346}
347
Rob Clark487687e2011-07-17 17:29:02 -0500348/** Let the XFree86 code know the Setup() function. */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100349static MODULESETUPPROTO(ARMSOCSetup);
Rob Clark487687e2011-07-17 17:29:02 -0500350
351/** Provide basic version information to the XFree86 code. */
Dave Barnish2e998952013-06-11 16:31:10 +0100352static XF86ModuleVersionInfo ARMSOCVersRec = {
Paul Geary8ffd91c2013-04-11 16:03:15 +0100353 ARMSOC_DRIVER_NAME,
Rob Clark487687e2011-07-17 17:29:02 -0500354 MODULEVENDORSTRING,
355 MODINFOSTRING1,
356 MODINFOSTRING2,
357 XORG_VERSION_CURRENT,
Dave Barnish2e998952013-06-11 16:31:10 +0100358 PACKAGE_VERSION_MAJOR,
359 PACKAGE_VERSION_MINOR,
360 PACKAGE_VERSION_PATCHLEVEL,
Rob Clark487687e2011-07-17 17:29:02 -0500361 ABI_CLASS_VIDEODRV,
362 ABI_VIDEODRV_VERSION,
363 MOD_CLASS_VIDEODRV,
364 {0, 0, 0, 0}
365};
366
367/** Let the XFree86 code know about the VersRec and Setup() function. */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100368_X_EXPORT XF86ModuleData armsocModuleData = { &ARMSOCVersRec, ARMSOCSetup, NULL };
Rob Clark487687e2011-07-17 17:29:02 -0500369
370
371/**
372 * The first function that the XFree86 code calls, after loading this module.
373 */
374static pointer
Paul Geary8ffd91c2013-04-11 16:03:15 +0100375ARMSOCSetup(pointer module, pointer opts, int *errmaj, int *errmin)
Rob Clark487687e2011-07-17 17:29:02 -0500376{
377 static Bool setupDone = FALSE;
378
379 /* This module should be loaded only once, but check to be sure: */
380 if (!setupDone) {
381 setupDone = TRUE;
Paul Geary8ffd91c2013-04-11 16:03:15 +0100382 xf86AddDriver(&ARMSOC, module, 0);
Rob Clark487687e2011-07-17 17:29:02 -0500383
Dave Barnish2e998952013-06-11 16:31:10 +0100384 /* The return value must be non-NULL on success even
385 * though there is no TearDownProc.
Rob Clark487687e2011-07-17 17:29:02 -0500386 */
387 return (pointer) 1;
388 } else {
389 if (errmaj)
390 *errmaj = LDR_ONCEONLY;
391 return NULL;
392 }
393}
394
Rob Clark487687e2011-07-17 17:29:02 -0500395/**
396 * The mandatory AvailableOptions() function. It returns the available driver
397 * options to the "-configure" option, so that an xorg.conf file can be built
398 * and the user can see which options are available for them to use.
399 */
400static const OptionInfoRec *
Paul Geary8ffd91c2013-04-11 16:03:15 +0100401ARMSOCAvailableOptions(int chipid, int busid)
Rob Clark487687e2011-07-17 17:29:02 -0500402{
Paul Geary8ffd91c2013-04-11 16:03:15 +0100403 return ARMSOCOptions;
Rob Clark487687e2011-07-17 17:29:02 -0500404}
405
406
407
408/**
409 * The mandatory Identify() function. It is run before Probe(), and prints out
410 * an identifying message, which includes the chipset(s) the driver supports.
411 */
412static void
Paul Geary8ffd91c2013-04-11 16:03:15 +0100413ARMSOCIdentify(int flags)
Rob Clark487687e2011-07-17 17:29:02 -0500414{
Paul Geary8ffd91c2013-04-11 16:03:15 +0100415 xf86PrintChipsets(ARMSOC_NAME, "Driver for ARM compatible chipsets",
416 ARMSOCChipsets);
Rob Clark487687e2011-07-17 17:29:02 -0500417}
418
419
420
421/**
Paul Geary8ffd91c2013-04-11 16:03:15 +0100422 * The driver's Probe() function. This function finds all instances of
423 * ARM hardware that the driver supports (from within the "xorg.conf"
Rob Clark487687e2011-07-17 17:29:02 -0500424 * device sections), and for instances not already claimed by another driver,
425 * claim the instances, and allocate a ScrnInfoRec. Only minimal hardware
426 * probing is allowed here.
427 */
428static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +0100429ARMSOCProbe(DriverPtr drv, int flags)
Rob Clark487687e2011-07-17 17:29:02 -0500430{
431 int i;
432 ScrnInfoPtr pScrn;
Dave Barnish2e998952013-06-11 16:31:10 +0100433 GDevPtr *devSections = NULL;
Rob Clark487687e2011-07-17 17:29:02 -0500434 int numDevSections;
435 Bool foundScreen = FALSE;
436
Rob Clark487687e2011-07-17 17:29:02 -0500437 /* Get the "xorg.conf" file device sections that match this driver, and
438 * return (error out) if there are none:
439 */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100440 numDevSections = xf86MatchDevice(ARMSOC_DRIVER_NAME, &devSections);
Rob Clark487687e2011-07-17 17:29:02 -0500441 if (numDevSections <= 0) {
Dave Barnish2e998952013-06-11 16:31:10 +0100442 EARLY_ERROR_MSG(
443 "Did not find any matching device section in configuration file");
Rob Clark83f49e02012-01-08 17:31:59 -0600444 if (flags & PROBE_DETECT) {
445 /* if we are probing, assume one and lets see if we can
446 * open the device to confirm it is there:
447 */
448 numDevSections = 1;
449 } else {
450 return FALSE;
451 }
Rob Clark487687e2011-07-17 17:29:02 -0500452 }
453
454 for (i = 0; i < numDevSections; i++) {
Dave Barnish1a3dac32013-06-20 19:01:38 +0100455 int fd;
456
457 if (devSections) {
Ray Smithb31657f2013-06-25 11:47:36 +0100458 const char *busIdStr;
459 const char *driverNameStr;
460 const char *cardNumStr;
Dave Barnish1a3dac32013-06-20 19:01:38 +0100461
462 /* get the Bus ID */
463 busIdStr = xf86FindOptionValue(
464 devSections[i]->options,
465 "BusID");
466
467 /* get the DriverName */
468 driverNameStr = xf86FindOptionValue(
469 devSections[i]->options,
470 "DriverName");
471
472 /* get the card_num from xorg.conf if present */
473 cardNumStr = xf86FindOptionValue(
474 devSections[i]->options,
475 "DRICard");
476
477 if (busIdStr && driverNameStr) {
478 EARLY_WARNING_MSG(
479 "Option DriverName ignored (BusID is specified)");
480 }
481 if (busIdStr || driverNameStr) {
482 if (cardNumStr) {
483 EARLY_WARNING_MSG(
484 "Option DRICard ignored (BusID or DriverName are specified)");
485 }
486 }
487
488 if (busIdStr) {
489 if (0 == strlen(busIdStr)) {
490 EARLY_ERROR_MSG(
491 "Missing value for Option BusID");
492 return FALSE;
493 }
494 connection.bus_id = busIdStr;
495 } else if (driverNameStr) {
496 if (0 == strlen(driverNameStr)) {
497 EARLY_ERROR_MSG(
498 "Missing value for Option DriverName");
499 return FALSE;
500 }
Ray Smithb31657f2013-06-25 11:47:36 +0100501 connection.driver_name = driverNameStr;
Dave Barnish1a3dac32013-06-20 19:01:38 +0100502 } else if (cardNumStr) {
503 char *endptr;
504 errno = 0;
505 connection.card_num = strtol(cardNumStr,
506 &endptr, 10);
507 if (('\0' == *cardNumStr) ||
508 ('\0' != *endptr) ||
509 (errno != 0)) {
510 EARLY_ERROR_MSG(
511 "Bad Option DRICard value : %s",
512 cardNumStr);
513 return FALSE;
514 }
515 }
516 }
517 fd = ARMSOCOpenDRMCard();
Dave Barnishdd948052013-06-25 16:52:37 +0100518 if (fd >= 0) {
Dave Barnish2e998952013-06-11 16:31:10 +0100519 struct ARMSOCRec *pARMSOC;
Dave Barnishf0952c12013-05-10 15:52:23 +0100520
521 /* Allocate the ScrnInfoRec */
522 pScrn = xf86AllocateScreen(drv, 0);
523 if (!pScrn) {
Dave Barnish2e998952013-06-11 16:31:10 +0100524 EARLY_ERROR_MSG(
525 "Cannot allocate a ScrnInfoPtr");
Dave Barnishf0952c12013-05-10 15:52:23 +0100526 return FALSE;
527 }
Dave Barnish2e998952013-06-11 16:31:10 +0100528 /* Allocate the driver's Screen-specific, "private"
529 * data structure and hook it into the ScrnInfoRec's
530 * driverPrivate field.
531 */
532 pScrn->driverPrivate =
533 calloc(1, sizeof(struct ARMSOCRec));
Dave Barnishf0952c12013-05-10 15:52:23 +0100534 if (!pScrn->driverPrivate)
535 return FALSE;
536
537 pARMSOC = ARMSOCPTR(pScrn);
Dave Barnish1a3dac32013-06-20 19:01:38 +0100538 /* initially mark to use all DRM crtcs */
Dave Barnish2e998952013-06-11 16:31:10 +0100539 pARMSOC->crtcNum = -1;
Rob Clark83f49e02012-01-08 17:31:59 -0600540
541 if (flags & PROBE_DETECT) {
Dave Barnish2e998952013-06-11 16:31:10 +0100542 /* just add the device.. we aren't a PCI device,
543 * so call xf86AddBusDeviceToConfigure()
544 * directly
Rob Clark83f49e02012-01-08 17:31:59 -0600545 */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100546 xf86AddBusDeviceToConfigure(ARMSOC_DRIVER_NAME,
Rob Clark83f49e02012-01-08 17:31:59 -0600547 BUS_NONE, NULL, i);
548 foundScreen = TRUE;
Dave Barnishf0952c12013-05-10 15:52:23 +0100549 drmClose(fd);
Rob Clark83f49e02012-01-08 17:31:59 -0600550 continue;
551 }
Rob Clark487687e2011-07-17 17:29:02 -0500552
Rob Clark83f49e02012-01-08 17:31:59 -0600553 if (devSections) {
Dave Barnish2e998952013-06-11 16:31:10 +0100554 int entity = xf86ClaimNoSlot(drv, 0,
555 devSections[i], TRUE);
Rob Clark83f49e02012-01-08 17:31:59 -0600556 xf86AddEntityToScreen(pScrn, entity);
557 }
Rob Clark487687e2011-07-17 17:29:02 -0500558
Dave Barnish2e998952013-06-11 16:31:10 +0100559 /* if there are multiple screens, use a separate
560 * crtc for each one
561 */
562 if (numDevSections > 1)
Dave Barnishf0952c12013-05-10 15:52:23 +0100563 pARMSOC->crtcNum = i;
Dave Barnishf0952c12013-05-10 15:52:23 +0100564
Dave Barnish2e998952013-06-11 16:31:10 +0100565 xf86Msg(X_INFO, "Screen:%d, CRTC:%d\n",
566 pScrn->scrnIndex,
567 pARMSOC->crtcNum);
Dave Barnishf0952c12013-05-10 15:52:23 +0100568
Rob Clark487687e2011-07-17 17:29:02 -0500569 foundScreen = TRUE;
570
Paul Geary8ffd91c2013-04-11 16:03:15 +0100571 pScrn->driverVersion = ARMSOC_VERSION;
572 pScrn->driverName = (char *)ARMSOC_DRIVER_NAME;
573 pScrn->name = (char *)ARMSOC_NAME;
574 pScrn->Probe = ARMSOCProbe;
575 pScrn->PreInit = ARMSOCPreInit;
576 pScrn->ScreenInit = ARMSOCScreenInit;
577 pScrn->SwitchMode = ARMSOCSwitchMode;
578 pScrn->AdjustFrame = ARMSOCAdjustFrame;
579 pScrn->EnterVT = ARMSOCEnterVT;
580 pScrn->LeaveVT = ARMSOCLeaveVT;
581 pScrn->FreeScreen = ARMSOCFreeScreen;
Rob Clark487687e2011-07-17 17:29:02 -0500582
Dave Barnishf0952c12013-05-10 15:52:23 +0100583 /* would be nice to keep the connection open */
Rob Clark487687e2011-07-17 17:29:02 -0500584 drmClose(fd);
585 }
586 }
587 free(devSections);
588 return foundScreen;
589}
590
Rob Clark487687e2011-07-17 17:29:02 -0500591/**
592 * The driver's PreInit() function. Additional hardware probing is allowed
593 * now, including display configuration.
594 */
595static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +0100596ARMSOCPreInit(ScrnInfoPtr pScrn, int flags)
Rob Clark487687e2011-07-17 17:29:02 -0500597{
Dave Barnish2e998952013-06-11 16:31:10 +0100598 struct ARMSOCRec *pARMSOC;
Rob Clark487687e2011-07-17 17:29:02 -0500599 int default_depth, fbbpp;
600 rgb defaultWeight = { 0, 0, 0 };
601 rgb defaultMask = { 0, 0, 0 };
602 Gamma defaultGamma = { 0.0, 0.0, 0.0 };
Rob Clark487687e2011-07-17 17:29:02 -0500603 int i;
David Garbett4d37be32013-04-04 09:04:29 +0100604 int driNumBufs;
Rob Clark487687e2011-07-17 17:29:02 -0500605
606 TRACE_ENTER();
607
608 if (flags & PROBE_DETECT) {
Dave Barnish2e998952013-06-11 16:31:10 +0100609 ERROR_MSG(
610 "The %s driver does not support the \"-configure\" or \"-probe\" command line arguments.",
611 ARMSOC_NAME);
Rob Clark487687e2011-07-17 17:29:02 -0500612 return FALSE;
613 }
614
615 /* Check the number of entities, and fail if it isn't one. */
616 if (pScrn->numEntities != 1) {
Dave Barnish2e998952013-06-11 16:31:10 +0100617 ERROR_MSG(
618 "Driver expected 1 entity, but found %d for screen %d",
Rob Clark487687e2011-07-17 17:29:02 -0500619 pScrn->numEntities, pScrn->scrnIndex);
620 return FALSE;
621 }
622
Paul Geary8ffd91c2013-04-11 16:03:15 +0100623 pARMSOC = ARMSOCPTR(pScrn);
Paul Geary8ffd91c2013-04-11 16:03:15 +0100624 pARMSOC->pEntityInfo = xf86GetEntityInfo(pScrn->entityList[0]);
Rob Clark487687e2011-07-17 17:29:02 -0500625
626 pScrn->monitor = pScrn->confScreen->monitor;
627
628 /* Get the current depth, and set it for XFree86: */
Dave Barnish2742d152013-03-13 13:36:58 +0000629 default_depth = 24; /* TODO: MIDEGL-1445: get from kernel */
630 fbbpp = 32; /* TODO: MIDEGL-1445: get from kernel */
Rob Clark487687e2011-07-17 17:29:02 -0500631
632 if (!xf86SetDepthBpp(pScrn, default_depth, 0, fbbpp, Support32bppFb)) {
633 /* The above function prints an error message. */
634 goto fail;
635 }
636 xf86PrintDepthBpp(pScrn);
637
638 /* Set the color weight: */
639 if (!xf86SetWeight(pScrn, defaultWeight, defaultMask)) {
640 /* The above function prints an error message. */
641 goto fail;
642 }
643
644 /* Set the gamma: */
645 if (!xf86SetGamma(pScrn, defaultGamma)) {
646 /* The above function prints an error message. */
647 goto fail;
648 }
649
650 /* Visual init: */
651 if (!xf86SetDefaultVisual(pScrn, -1)) {
652 /* The above function prints an error message. */
653 goto fail;
654 }
655
656 /* We don't support 8-bit depths: */
657 if (pScrn->depth < 16) {
Dave Barnish2e998952013-06-11 16:31:10 +0100658 ERROR_MSG(
659 "The requested default visual (%s) has an unsupported depth (%d).",
660 xf86GetVisualName(pScrn->defaultVisual),
661 pScrn->depth);
Rob Clark487687e2011-07-17 17:29:02 -0500662 goto fail;
663 }
664
665 /* Using a programmable clock: */
666 pScrn->progClock = TRUE;
667
Dave Barnish2e998952013-06-11 16:31:10 +0100668 /* Open a connection to the DRM, so we can communicate
669 * with the KMS code:
670 */
671 if (!ARMSOCOpenDRM(pScrn))
Rob Clark487687e2011-07-17 17:29:02 -0500672 goto fail;
Rob Clark487687e2011-07-17 17:29:02 -0500673
Dave Barnish2e998952013-06-11 16:31:10 +0100674 pARMSOC->drmmode_interface =
675 drmmode_interface_get_implementation(pARMSOC->drmFD);
Dave Barnishde45ed42013-06-05 13:47:56 +0100676 if (!pARMSOC->drmmode_interface)
Dave Barnishf0952c12013-05-10 15:52:23 +0100677 goto fail2;
Ray Smith3c33c3d2013-03-26 16:06:37 +0000678
Rob Clark487687e2011-07-17 17:29:02 -0500679 /* create DRM device instance: */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100680 pARMSOC->dev = armsoc_device_new(pARMSOC->drmFD,
Javier Martin981264d2013-08-21 16:48:07 +0100681 pARMSOC->drmmode_interface->create_custom_gem);
Rob Clark487687e2011-07-17 17:29:02 -0500682
Rob Clark487687e2011-07-17 17:29:02 -0500683 /* find matching chipset name: */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100684 for (i = 0; ARMSOCChipsets[i].name; i++) {
685 if (ARMSOCChipsets[i].token == MALI_T6XX_CHIPSET_ID) {
686 pScrn->chipset = (char *)ARMSOCChipsets[i].name;
Rob Clark487687e2011-07-17 17:29:02 -0500687 break;
688 }
689 }
690
Dave Barnish01b5c172013-04-10 11:01:17 +0100691 INFO_MSG("Chipset: %s", pScrn->chipset);
Rob Clark487687e2011-07-17 17:29:02 -0500692
693 /*
694 * Process the "xorg.conf" file options:
695 */
696 xf86CollectOptions(pScrn, NULL);
Dave Barnish2e998952013-06-11 16:31:10 +0100697 pARMSOC->pOptionInfo = calloc(1, sizeof(ARMSOCOptions));
698 if (!pARMSOC->pOptionInfo)
Dave Barnishf0952c12013-05-10 15:52:23 +0100699 goto fail2;
Dave Barnish2e998952013-06-11 16:31:10 +0100700
Paul Geary8ffd91c2013-04-11 16:03:15 +0100701 memcpy(pARMSOC->pOptionInfo, ARMSOCOptions, sizeof(ARMSOCOptions));
Dave Barnish2e998952013-06-11 16:31:10 +0100702 xf86ProcessOptions(pScrn->scrnIndex,
703 pARMSOC->pEntityInfo->device->options,
Paul Geary8ffd91c2013-04-11 16:03:15 +0100704 pARMSOC->pOptionInfo);
Rob Clark487687e2011-07-17 17:29:02 -0500705
706 /* Determine if the user wants debug messages turned on: */
Dave Barnish2e998952013-06-11 16:31:10 +0100707 armsocDebug = xf86ReturnOptValBool(pARMSOC->pOptionInfo,
708 OPTION_DEBUG, FALSE);
Rob Clark487687e2011-07-17 17:29:02 -0500709
David Garbett4d37be32013-04-04 09:04:29 +0100710 if (!xf86GetOptValInteger(pARMSOC->pOptionInfo, OPTION_DRI_NUM_BUF,
711 &driNumBufs)) {
712 /* Default to double buffering */
713 driNumBufs = 2;
714 }
715
716 if (driNumBufs < 2) {
717 ERROR_MSG(
718 "Invalid option for %s: %d. Must be greater than or equal to 2",
719 xf86TokenToOptName(pARMSOC->pOptionInfo,
720 OPTION_DRI_NUM_BUF),
721 driNumBufs);
722 return FALSE;
723 }
724 pARMSOC->driNumBufs = driNumBufs;
Dave Barnishc50baf52012-11-29 14:39:36 +0000725 /* Determine if user wants to disable buffer flipping: */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100726 pARMSOC->NoFlip = xf86ReturnOptValBool(pARMSOC->pOptionInfo,
Dave Barnishc50baf52012-11-29 14:39:36 +0000727 OPTION_NO_FLIP, FALSE);
Dave Barnish2e998952013-06-11 16:31:10 +0100728 INFO_MSG("Buffer Flipping is %s",
729 pARMSOC->NoFlip ? "Disabled" : "Enabled");
Dave Barnishc50baf52012-11-29 14:39:36 +0000730
Rob Clark487687e2011-07-17 17:29:02 -0500731 /*
732 * Select the video modes:
733 */
734 INFO_MSG("Setting the video modes ...");
735
736 /* Don't call drmCheckModesettingSupported() as its written only for
737 * PCI devices.
738 */
739
740 /* Do initial KMS setup: */
Dave Barnish2e998952013-06-11 16:31:10 +0100741 if (!drmmode_pre_init(pScrn, pARMSOC->drmFD,
742 (pScrn->bitsPerPixel >> 3))) {
Rob Clark487687e2011-07-17 17:29:02 -0500743 ERROR_MSG("Cannot get KMS resources");
Dave Barnishf0952c12013-05-10 15:52:23 +0100744 goto fail2;
Rob Clark487687e2011-07-17 17:29:02 -0500745 } else {
746 INFO_MSG("Got KMS resources");
747 }
748
749 xf86RandR12PreInit(pScrn);
750
751 /* Let XFree86 calculate or get (from command line) the display DPI: */
752 xf86SetDpi(pScrn, 0, 0);
753
754 /* Ensure we have a supported depth: */
755 switch (pScrn->bitsPerPixel) {
756 case 16:
757 case 24:
758 case 32:
759 break;
760 default:
Dave Barnish2e998952013-06-11 16:31:10 +0100761 ERROR_MSG(
762 "The requested number of bits per pixel (%d) is unsupported.",
Rob Clark487687e2011-07-17 17:29:02 -0500763 pScrn->bitsPerPixel);
Dave Barnishf0952c12013-05-10 15:52:23 +0100764 goto fail2;
Rob Clark487687e2011-07-17 17:29:02 -0500765 }
766
767
768 /* Load external sub-modules now: */
769
770 if (!(xf86LoadSubModule(pScrn, "dri2") &&
771 xf86LoadSubModule(pScrn, "exa") &&
772 xf86LoadSubModule(pScrn, "fb"))) {
Dave Barnishf0952c12013-05-10 15:52:23 +0100773 goto fail2;
Rob Clark487687e2011-07-17 17:29:02 -0500774 }
775
Rob Clark487687e2011-07-17 17:29:02 -0500776 TRACE_EXIT();
777 return TRUE;
778
Dave Barnishf0952c12013-05-10 15:52:23 +0100779fail2:
780 /* Cleanup here where we know whether we took a connection
781 * instead of in FreeScreen where we don't */
782 ARMSOCDropDRMMaster();
783 ARMSOCCloseDRM(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500784fail:
785 TRACE_EXIT();
Rob Clark487687e2011-07-17 17:29:02 -0500786 return FALSE;
787}
788
789
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600790/**
791 * Initialize EXA and DRI2
792 */
793static void
Paul Geary8ffd91c2013-04-11 16:03:15 +0100794ARMSOCAccelInit(ScreenPtr pScreen)
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600795{
796 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
Dave Barnish2e998952013-06-11 16:31:10 +0100797 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600798
Dave Barnish2e998952013-06-11 16:31:10 +0100799 if (!pARMSOC->pARMSOCEXA)
800 pARMSOC->pARMSOCEXA = InitNullEXA(pScreen, pScrn,
801 pARMSOC->drmFD);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600802
Dave Barnish2e998952013-06-11 16:31:10 +0100803 if (pARMSOC->pARMSOCEXA)
Paul Geary8ffd91c2013-04-11 16:03:15 +0100804 pARMSOC->dri = ARMSOCDRI2ScreenInit(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +0100805 else
Paul Geary8ffd91c2013-04-11 16:03:15 +0100806 pARMSOC->dri = FALSE;
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600807}
Rob Clark487687e2011-07-17 17:29:02 -0500808
809/**
Dave Barnishfd50b132013-05-16 15:00:02 +0100810 * The driver's ScreenInit() function, called at the start of each server
Dave Barnish2e998952013-06-11 16:31:10 +0100811 * generation. Fill in pScreen, map the frame buffer, save state,
Dave Barnishfd50b132013-05-16 15:00:02 +0100812 * initialize the mode, etc.
Rob Clark487687e2011-07-17 17:29:02 -0500813 */
814static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +0100815ARMSOCScreenInit(SCREEN_INIT_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -0500816{
817 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
Dave Barnishdd948052013-06-25 16:52:37 +0100818#ifndef XF86_SCRN_INTERFACE
819 int scrnIndex = pScrn->scrnIndex;
820#endif
Dave Barnish2e998952013-06-11 16:31:10 +0100821 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500822 VisualPtr visual;
823 xf86CrtcConfigPtr xf86_config;
David Garbett82b51832012-07-04 08:29:38 +0100824 int j;
Rob Clark487687e2011-07-17 17:29:02 -0500825
826 TRACE_ENTER();
827
Dave Barnish982518c2013-04-22 16:09:22 +0100828 /* set drm master before allocating scanout buffer */
Dave Barnish2e998952013-06-11 16:31:10 +0100829 if (ARMSOCSetDRMMaster()) {
Dave Barnish982518c2013-04-22 16:09:22 +0100830 ERROR_MSG("Cannot get DRM master: %s", strerror(errno));
Dave Barnishfd50b132013-05-16 15:00:02 +0100831 goto fail;
Dave Barnish982518c2013-04-22 16:09:22 +0100832 }
Dave Barnish52faee02013-04-22 13:28:42 +0100833 /* Allocate initial scanout buffer */
834 DEBUG_MSG("allocating new scanout buffer: %dx%d",
835 pScrn->virtualX, pScrn->virtualY);
Dave Barnish52faee02013-04-22 13:28:42 +0100836 assert(!pARMSOC->scanout);
837 pARMSOC->scanout = armsoc_bo_new_with_dim(pARMSOC->dev, pScrn->virtualX,
838 pScrn->virtualY, pScrn->depth, pScrn->bitsPerPixel,
Dave Barnish2e998952013-06-11 16:31:10 +0100839 ARMSOC_BO_SCANOUT);
Dave Barnish52faee02013-04-22 13:28:42 +0100840 if (!pARMSOC->scanout) {
Dave Barnishfd50b132013-05-16 15:00:02 +0100841 ERROR_MSG("Cannot allocate scanout buffer\n");
842 goto fail1;
Dave Barnish52faee02013-04-22 13:28:42 +0100843 }
Dave Barnish2e998952013-06-11 16:31:10 +0100844 pScrn->displayWidth = armsoc_bo_pitch(pARMSOC->scanout) /
845 ((pScrn->bitsPerPixel+7) / 8);
Rob Clark487687e2011-07-17 17:29:02 -0500846 xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
847
848 /* need to point to new screen on server regeneration */
David Garbett82b51832012-07-04 08:29:38 +0100849 for (j = 0; j < xf86_config->num_crtc; j++)
850 xf86_config->crtc[j]->scrn = pScrn;
851 for (j = 0; j < xf86_config->num_output; j++)
852 xf86_config->output[j]->scrn = pScrn;
Rob Clark487687e2011-07-17 17:29:02 -0500853
854 /*
855 * The next step is to setup the screen's visuals, and initialize the
856 * framebuffer code. In cases where the framebuffer's default
857 * choices for things like visual layouts and bits per RGB are OK,
858 * this may be as simple as calling the framebuffer's ScreenInit()
859 * function. If not, the visuals will need to be setup before calling
860 * a fb ScreenInit() function and fixed up after.
861 *
862 * For most PC hardware at depths >= 8, the defaults that fb uses
863 * are not appropriate. In this driver, we fixup the visuals after.
864 */
865
Dave Barnishfd50b132013-05-16 15:00:02 +0100866 /* Reset the visual list. */
Rob Clark487687e2011-07-17 17:29:02 -0500867 miClearVisualTypes();
Dave Barnish2e998952013-06-11 16:31:10 +0100868 if (!miSetVisualTypes(pScrn->bitsPerPixel,
869 miGetDefaultVisualMask(pScrn->depth),
Rob Clark487687e2011-07-17 17:29:02 -0500870 pScrn->rgbBits, pScrn->defaultVisual)) {
Dave Barnish2e998952013-06-11 16:31:10 +0100871 ERROR_MSG(
872 "Cannot initialize the visual type for %d bits per pixel!",
Rob Clark487687e2011-07-17 17:29:02 -0500873 pScrn->bitsPerPixel);
Dave Barnishfd50b132013-05-16 15:00:02 +0100874 goto fail2;
Rob Clark487687e2011-07-17 17:29:02 -0500875 }
876
Dave Barnish2e998952013-06-11 16:31:10 +0100877 if (pScrn->bitsPerPixel == 32 && pScrn->depth == 24) {
David Garbettef4b7482012-09-26 14:09:01 +0100878 /* Also add a 24 bit depth visual */
879 if (!miSetVisualTypes(24, miGetDefaultVisualMask(pScrn->depth),
880 pScrn->rgbBits, pScrn->defaultVisual)) {
Dave Barnish2e998952013-06-11 16:31:10 +0100881 WARNING_MSG(
882 "Cannot initialize a 24 depth visual for 32bpp");
883 } else {
David Garbettef4b7482012-09-26 14:09:01 +0100884 INFO_MSG("Initialized a 24 depth visual for 32bpp");
885 }
886 }
887
Rob Clark487687e2011-07-17 17:29:02 -0500888 if (!miSetPixmapDepths()) {
889 ERROR_MSG("Cannot initialize the pixmap depth!");
Dave Barnishfd50b132013-05-16 15:00:02 +0100890 goto fail3;
Rob Clark487687e2011-07-17 17:29:02 -0500891 }
892
893 /* Initialize some generic 2D drawing functions: */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100894 if (!fbScreenInit(pScreen, armsoc_bo_map(pARMSOC->scanout),
Rob Clark487687e2011-07-17 17:29:02 -0500895 pScrn->virtualX, pScrn->virtualY,
896 pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
897 pScrn->bitsPerPixel)) {
898 ERROR_MSG("fbScreenInit() failed!");
Dave Barnishfd50b132013-05-16 15:00:02 +0100899 goto fail3;
Rob Clark487687e2011-07-17 17:29:02 -0500900 }
901
902 /* Fixup RGB ordering: */
903 visual = pScreen->visuals + pScreen->numVisuals;
904 while (--visual >= pScreen->visuals) {
905 if ((visual->class | DynamicClass) == DirectColor) {
906 visual->offsetRed = pScrn->offset.red;
907 visual->offsetGreen = pScrn->offset.green;
908 visual->offsetBlue = pScrn->offset.blue;
909 visual->redMask = pScrn->mask.red;
910 visual->greenMask = pScrn->mask.green;
911 visual->blueMask = pScrn->mask.blue;
David Garbett100928b2012-10-03 14:20:54 +0100912 visual->bitsPerRGBValue = pScrn->rgbBits;
913 visual->ColormapEntries = 1 << pScrn->rgbBits;
Rob Clark487687e2011-07-17 17:29:02 -0500914 }
915 }
916
Dave Barnish2e998952013-06-11 16:31:10 +0100917 /* Continue initializing the generic 2D drawing functions after
918 * fixing the RGB ordering:
Rob Clark487687e2011-07-17 17:29:02 -0500919 */
920 if (!fbPictureInit(pScreen, NULL, 0)) {
921 ERROR_MSG("fbPictureInit() failed!");
Dave Barnishfd50b132013-05-16 15:00:02 +0100922 goto fail4;
Rob Clark487687e2011-07-17 17:29:02 -0500923 }
924
925 /* Set the initial black & white colormap indices: */
926 xf86SetBlackWhitePixels(pScreen);
927
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600928 /* Initialize external sub-modules for EXA now, this has to be before
929 * miDCInitialize() otherwise stacking order for wrapped ScreenPtr fxns
930 * ends up in the wrong order.
931 */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100932 ARMSOCAccelInit(pScreen);
Rob Clarkdc9dfae2012-01-11 18:20:18 -0600933
Rob Clark487687e2011-07-17 17:29:02 -0500934 /* Initialize backing store: */
Rob Clark487687e2011-07-17 17:29:02 -0500935 xf86SetBackingStore(pScreen);
936
Dave Barnish2e998952013-06-11 16:31:10 +0100937 /* Enable cursor position updates by mouse signal handler: */
Rob Clark687c6082012-01-08 19:33:18 -0600938 xf86SetSilkenMouse(pScreen);
939
Rob Clark487687e2011-07-17 17:29:02 -0500940 /* Initialize the cursor: */
Dave Barnish2e998952013-06-11 16:31:10 +0100941 if (!miDCInitialize(pScreen, xf86GetPointerScreenFuncs())) {
Dave Barnishfd50b132013-05-16 15:00:02 +0100942 ERROR_MSG("miDCInitialize() failed!");
943 goto fail5;
Rob Clark687c6082012-01-08 19:33:18 -0600944 }
Rob Clark487687e2011-07-17 17:29:02 -0500945
Dave Barnishfd50b132013-05-16 15:00:02 +0100946 /* ignore failures here as we will fall back to software cursor */
947 (void)drmmode_cursor_init(pScreen);
948
949 /* TODO: MIDEGL-1458: Is this the right place for this?
950 * The Intel i830 driver says:
Rob Clark487687e2011-07-17 17:29:02 -0500951 * "Must force it before EnterVT, so we are in control of VT..."
952 */
953 pScrn->vtSema = TRUE;
954
Dave Barnish2e998952013-06-11 16:31:10 +0100955 /* Take over the virtual terminal from the console, set the
956 * desired mode, etc.:
Rob Clark487687e2011-07-17 17:29:02 -0500957 */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100958 if (!ARMSOCEnterVT(VT_FUNC_ARGS(0))) {
959 ERROR_MSG("ARMSOCEnterVT() failed!");
Dave Barnishfd50b132013-05-16 15:00:02 +0100960 goto fail6;
Rob Clark487687e2011-07-17 17:29:02 -0500961 }
962
Dave Barnishfd50b132013-05-16 15:00:02 +0100963 /* Do some XRandR initialization. Return value is not useful */
964 (void)xf86CrtcScreenInit(pScreen);
Rob Clark487687e2011-07-17 17:29:02 -0500965
966 if (!miCreateDefColormap(pScreen)) {
967 ERROR_MSG("Cannot create colormap!");
Dave Barnishfd50b132013-05-16 15:00:02 +0100968 goto fail7;
Rob Clark487687e2011-07-17 17:29:02 -0500969 }
970
David Garbett100928b2012-10-03 14:20:54 +0100971 if (!xf86HandleColormaps(pScreen, 1 << pScrn->rgbBits, pScrn->rgbBits,
Paul Geary8ffd91c2013-04-11 16:03:15 +0100972 ARMSOCLoadPalette, NULL, CMAP_PALETTED_TRUECOLOR)) {
Rob Clark487687e2011-07-17 17:29:02 -0500973 ERROR_MSG("xf86HandleColormaps() failed!");
Dave Barnishfd50b132013-05-16 15:00:02 +0100974 goto fail8;
Rob Clark487687e2011-07-17 17:29:02 -0500975 }
976
977 /* Setup power management: */
978 xf86DPMSInit(pScreen, xf86DPMSSet, 0);
979
980 pScreen->SaveScreen = xf86SaveScreen;
981
982 /* Wrap some screen functions: */
Paul Geary8ffd91c2013-04-11 16:03:15 +0100983 wrap(pARMSOC, pScreen, CloseScreen, ARMSOCCloseScreen);
Dave Barnish2e998952013-06-11 16:31:10 +0100984 wrap(pARMSOC, pScreen, CreateScreenResources,
985 ARMSOCCreateScreenResources);
Paul Geary8ffd91c2013-04-11 16:03:15 +0100986 wrap(pARMSOC, pScreen, BlockHandler, ARMSOCBlockHandler);
Rob Clark4b8f30a2011-08-28 12:51:26 -0500987 drmmode_screen_init(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -0500988
989 TRACE_EXIT();
990 return TRUE;
991
Dave Barnishfd50b132013-05-16 15:00:02 +0100992/* cleanup on failures */
993fail8:
994 /* uninstall the default colormap */
995 miUninstallColormap(GetInstalledmiColormap(pScreen));
996
997fail7:
998 ARMSOCLeaveVT(VT_FUNC_ARGS(0));
999 pScrn->vtSema = FALSE;
1000
1001fail6:
1002 drmmode_cursor_fini(pScreen);
1003
1004fail5:
Dave Barnish2e998952013-06-11 16:31:10 +01001005 if (pARMSOC->dri)
Dave Barnishfd50b132013-05-16 15:00:02 +01001006 ARMSOCDRI2CloseScreen(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001007
1008 if (pARMSOC->pARMSOCEXA)
1009 if (pARMSOC->pARMSOCEXA->CloseScreen)
Dave Barnishdd948052013-06-25 16:52:37 +01001010 pARMSOC->pARMSOCEXA->CloseScreen(CLOSE_SCREEN_ARGS);
Dave Barnishfd50b132013-05-16 15:00:02 +01001011fail4:
1012 /* Call the CloseScreen functions for fbInitScreen, miDCInitialize,
Dave Barnish2e998952013-06-11 16:31:10 +01001013 * exaDriverInit & xf86CrtcScreenInit as appropriate via their
1014 * wrapped pointers.
Dave Barnishfd50b132013-05-16 15:00:02 +01001015 * exaDDXCloseScreen uses the XF86SCRNINFO macro so we must
1016 * set up the key for this before it gets called.
1017 */
1018 dixSetPrivate(&pScreen->devPrivates, xf86ScreenKey, pScrn);
Dave Barnishdd948052013-06-25 16:52:37 +01001019 (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
Dave Barnishfd50b132013-05-16 15:00:02 +01001020
1021fail3:
1022 /* reset the visual list */
1023 miClearVisualTypes();
1024
1025fail2:
1026 /* release the scanout buffer */
1027 armsoc_bo_unreference(pARMSOC->scanout);
1028 pARMSOC->scanout = NULL;
1029 pScrn->displayWidth = 0;
1030
1031fail1:
1032 /* drop drm master */
1033 (void)drmDropMaster(pARMSOC->drmFD);
1034
Rob Clark487687e2011-07-17 17:29:02 -05001035fail:
1036 TRACE_EXIT();
1037 return FALSE;
1038}
1039
1040
1041static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001042ARMSOCLoadPalette(ScrnInfoPtr pScrn, int numColors, int *indices,
Dave Barnish2e998952013-06-11 16:31:10 +01001043 LOCO *colors, VisualPtr pVisual)
Rob Clark487687e2011-07-17 17:29:02 -05001044{
1045 TRACE_ENTER();
1046 TRACE_EXIT();
1047}
1048
1049
1050/**
1051 * The driver's CloseScreen() function. This is called at the end of each
1052 * server generation. Restore state, unmap the frame buffer (and any other
1053 * mapped memory regions), and free per-Screen data structures (except those
1054 * held by pScrn).
1055 */
1056static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +01001057ARMSOCCloseScreen(CLOSE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001058{
Cooper Yuana83caa62012-06-28 17:19:06 +02001059 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001060 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Daniel Kurtz22437e92013-07-30 13:28:46 +08001061 Bool ret;
Rob Clark487687e2011-07-17 17:29:02 -05001062
1063 TRACE_ENTER();
1064
Rob Clark4b8f30a2011-08-28 12:51:26 -05001065 drmmode_screen_fini(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001066
Daniel Kurtz22437e92013-07-30 13:28:46 +08001067 unwrap(pARMSOC, pScreen, CloseScreen);
1068 unwrap(pARMSOC, pScreen, BlockHandler);
1069 unwrap(pARMSOC, pScreen, CreateScreenResources);
1070
1071 ret = (*pScreen->CloseScreen)(scrnIndex, pScreen);
1072
Dave Barnish2e998952013-06-11 16:31:10 +01001073 if (pARMSOC->dri)
Dave Barnishfd50b132013-05-16 15:00:02 +01001074 ARMSOCDRI2CloseScreen(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001075
1076 if (pARMSOC->pARMSOCEXA)
1077 if (pARMSOC->pARMSOCEXA->CloseScreen)
Paul Geary8ffd91c2013-04-11 16:03:15 +01001078 pARMSOC->pARMSOCEXA->CloseScreen(CLOSE_SCREEN_ARGS);
Rob Clark487687e2011-07-17 17:29:02 -05001079
Dave Barnish52faee02013-04-22 13:28:42 +01001080 /* release the scanout buffer */
1081 armsoc_bo_unreference(pARMSOC->scanout);
1082 pARMSOC->scanout = NULL;
1083 pScrn->displayWidth = 0;
Rob Clark487687e2011-07-17 17:29:02 -05001084
Dave Barnish2e998952013-06-11 16:31:10 +01001085 if (pScrn->vtSema == TRUE)
Dave Barnish982518c2013-04-22 16:09:22 +01001086 ARMSOCLeaveVT(VT_FUNC_ARGS(0));
Dave Barnish2e998952013-06-11 16:31:10 +01001087
Rob Clark487687e2011-07-17 17:29:02 -05001088 pScrn->vtSema = FALSE;
1089
Rob Clark487687e2011-07-17 17:29:02 -05001090 TRACE_EXIT();
1091
Daniel Kurtz22437e92013-07-30 13:28:46 +08001092 return ret;
Rob Clark487687e2011-07-17 17:29:02 -05001093}
1094
1095
1096
1097/**
1098 * Adjust the screen pixmap for the current location of the front buffer.
1099 * This is done at EnterVT when buffers are bound as long as the resources
1100 * have already been created, but the first EnterVT happens before
1101 * CreateScreenResources.
1102 */
1103static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +01001104ARMSOCCreateScreenResources(ScreenPtr pScreen)
Rob Clark487687e2011-07-17 17:29:02 -05001105{
1106 ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
Dave Barnish2e998952013-06-11 16:31:10 +01001107 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001108
Paul Geary8ffd91c2013-04-11 16:03:15 +01001109 swap(pARMSOC, pScreen, CreateScreenResources);
Rob Clark487687e2011-07-17 17:29:02 -05001110 if (!(*pScreen->CreateScreenResources) (pScreen))
1111 return FALSE;
Paul Geary8ffd91c2013-04-11 16:03:15 +01001112 swap(pARMSOC, pScreen, CreateScreenResources);
Rob Clark487687e2011-07-17 17:29:02 -05001113
1114 return TRUE;
1115}
1116
1117
1118static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001119ARMSOCBlockHandler(BLOCKHANDLER_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001120{
Cooper Yuana83caa62012-06-28 17:19:06 +02001121 SCREEN_PTR(arg);
1122 ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
Dave Barnish2e998952013-06-11 16:31:10 +01001123 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001124
Paul Geary8ffd91c2013-04-11 16:03:15 +01001125 swap(pARMSOC, pScreen, BlockHandler);
Cooper Yuana83caa62012-06-28 17:19:06 +02001126 (*pScreen->BlockHandler) (BLOCKHANDLER_ARGS);
Paul Geary8ffd91c2013-04-11 16:03:15 +01001127 swap(pARMSOC, pScreen, BlockHandler);
Rob Clark487687e2011-07-17 17:29:02 -05001128}
1129
1130
1131
1132/**
1133 * The driver's SwitchMode() function. Initialize the new mode for the
1134 * Screen.
1135 */
1136static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +01001137ARMSOCSwitchMode(SWITCH_MODE_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001138{
Cooper Yuana83caa62012-06-28 17:19:06 +02001139 SCRN_INFO_PTR(arg);
Rob Clark487687e2011-07-17 17:29:02 -05001140 return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
1141}
1142
1143
1144
1145/**
1146 * The driver's AdjustFrame() function. For cases where the frame buffer is
1147 * larger than the monitor resolution, this function can pan around the frame
1148 * buffer within the "viewport" of the monitor.
1149 */
1150static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001151ARMSOCAdjustFrame(ADJUST_FRAME_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001152{
Cooper Yuana83caa62012-06-28 17:19:06 +02001153 SCRN_INFO_PTR(arg);
1154 drmmode_adjust_frame(pScrn, x, y);
Rob Clark487687e2011-07-17 17:29:02 -05001155}
1156
1157
1158
1159/**
1160 * The driver's EnterVT() function. This is called at server startup time, and
1161 * when the X server takes over the virtual terminal from the console. As
1162 * such, it may need to save the current (i.e. console) HW state, and set the
1163 * HW state as needed by the X server.
1164 */
1165static Bool
Paul Geary8ffd91c2013-04-11 16:03:15 +01001166ARMSOCEnterVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001167{
Cooper Yuana83caa62012-06-28 17:19:06 +02001168 SCRN_INFO_PTR(arg);
Ray Smith6ae735f2013-03-21 15:57:18 +00001169 int i, ret;
abhinav.kd4bab322012-07-31 11:29:19 -07001170
Rob Clark487687e2011-07-17 17:29:02 -05001171 TRACE_ENTER();
1172
Ray Smith6ae735f2013-03-21 15:57:18 +00001173 for (i = 1; i < currentMaxClients; i++) {
1174 if (clients[i])
1175 AttendClient(clients[i]);
1176 }
1177
Dave Barnishf0952c12013-05-10 15:52:23 +01001178 ret = ARMSOCSetDRMMaster();
Rob Clark487687e2011-07-17 17:29:02 -05001179 if (ret) {
Daniel Kurtz92205962013-02-05 13:50:12 +08001180 ERROR_MSG("Cannot get DRM master: %s", strerror(errno));
Daniel Kurtz01a91f62013-02-05 10:19:51 +08001181 return FALSE;
Rob Clark487687e2011-07-17 17:29:02 -05001182 }
1183
1184 if (!xf86SetDesiredModes(pScrn)) {
1185 ERROR_MSG("xf86SetDesiredModes() failed!");
1186 return FALSE;
1187 }
1188
1189 TRACE_EXIT();
1190 return TRUE;
1191}
1192
1193
1194
1195/**
1196 * The driver's LeaveVT() function. This is called when the X server
1197 * temporarily gives up the virtual terminal to the console. As such, it may
1198 * need to restore the console's HW state.
1199 */
1200static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001201ARMSOCLeaveVT(VT_FUNC_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001202{
Cooper Yuana83caa62012-06-28 17:19:06 +02001203 SCRN_INFO_PTR(arg);
Ray Smith6ae735f2013-03-21 15:57:18 +00001204 int i, ret;
abhinav.kd4bab322012-07-31 11:29:19 -07001205
Rob Clark487687e2011-07-17 17:29:02 -05001206 TRACE_ENTER();
1207
Ray Smith6ae735f2013-03-21 15:57:18 +00001208 for (i = 1; i < currentMaxClients; i++) {
1209 if (clients[i])
1210 IgnoreClient(clients[i]);
1211 }
1212
Dave Barnishf0952c12013-05-10 15:52:23 +01001213 ret = ARMSOCDropDRMMaster();
Dave Barnish2e998952013-06-11 16:31:10 +01001214 if (ret)
Daniel Kurtz92205962013-02-05 13:50:12 +08001215 WARNING_MSG("drmDropMaster failed: %s", strerror(errno));
Rob Clark487687e2011-07-17 17:29:02 -05001216
1217 TRACE_EXIT();
1218}
1219
Rob Clark487687e2011-07-17 17:29:02 -05001220/**
Dave Barnish982518c2013-04-22 16:09:22 +01001221 * The driver's FreeScreen() function.
Dave Barnish2e998952013-06-11 16:31:10 +01001222 * Frees the ScrnInfoRec driverPrivate field when a screen is
1223 * deleted by the common layer.
Dave Barnish982518c2013-04-22 16:09:22 +01001224 * This function is not used in normal (error free) operation.
Rob Clark487687e2011-07-17 17:29:02 -05001225 */
1226static void
Paul Geary8ffd91c2013-04-11 16:03:15 +01001227ARMSOCFreeScreen(FREE_SCREEN_ARGS_DECL)
Rob Clark487687e2011-07-17 17:29:02 -05001228{
Cooper Yuana83caa62012-06-28 17:19:06 +02001229 SCRN_INFO_PTR(arg);
Dave Barnish2e998952013-06-11 16:31:10 +01001230 struct ARMSOCRec *pARMSOC = ARMSOCPTR(pScrn);
Rob Clark487687e2011-07-17 17:29:02 -05001231
1232 TRACE_ENTER();
1233
Paul Geary8ffd91c2013-04-11 16:03:15 +01001234 if (!pARMSOC) {
Rob Clark487687e2011-07-17 17:29:02 -05001235 /* This can happen if a Screen is deleted after Probe(): */
1236 return;
1237 }
1238
Paul Geary8ffd91c2013-04-11 16:03:15 +01001239 if (pARMSOC->pARMSOCEXA) {
Dave Barnish2e998952013-06-11 16:31:10 +01001240 if (pARMSOC->pARMSOCEXA->FreeScreen)
1241 pARMSOC->pARMSOCEXA->FreeScreen(
1242 FREE_SCREEN_ARGS(pScrn));
Rob Clark487687e2011-07-17 17:29:02 -05001243 }
1244
Paul Geary8ffd91c2013-04-11 16:03:15 +01001245 armsoc_device_del(pARMSOC->dev);
Rob Clark487687e2011-07-17 17:29:02 -05001246
Dave Barnishf0952c12013-05-10 15:52:23 +01001247 /* Free the driver's Screen-specific, "private" data structure and
1248 * NULL-out the ScrnInfoRec's driverPrivate field.
1249 */
1250 if (pScrn->driverPrivate) {
1251 free(pScrn->driverPrivate);
1252 pScrn->driverPrivate = NULL;
1253 }
Rob Clark487687e2011-07-17 17:29:02 -05001254
1255 TRACE_EXIT();
1256}
1257