summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRussell King <rmk@arm.linux.org.uk>2013-12-03 23:43:50 +0000
committerRussell King <rmk@arm.linux.org.uk>2013-12-04 23:07:22 +0000
commit383e3445afd2a37194e5903dcf095d451955869b (patch)
treefba1172818e474fbec0e2b296b02cf17d6e83d7e
parent62ec1b4bcd6f952909e33b2c3db3e8d69cc38bc2 (diff)
downloadxf86-video-armada-383e3445afd2a37194e5903dcf095d451955869b.tar.gz
Convert Armada DRM CRTC into a set of library functions
Convert much more of the Armada DRM driver to be a set of library Armada independent DRM functions. Signed-off-by: Russell King <rmk@arm.linux.org.uk>
-rw-r--r--src/armada_drm.c839
-rw-r--r--src/armada_drm.h58
-rw-r--r--src/armada_drm_xv.c44
-rw-r--r--src/common_drm.c700
-rw-r--r--src/common_drm.h74
-rw-r--r--src/vivante_utils.h1
6 files changed, 939 insertions, 777 deletions
diff --git a/src/armada_drm.c b/src/armada_drm.c
index 7f6ff11..c3df7a4 100644
--- a/src/armada_drm.c
+++ b/src/armada_drm.c
@@ -25,10 +25,6 @@
#include <X11/extensions/dpmsconst.h>
#include <X11/Xatom.h>
-#ifdef HAVE_UDEV
-#include <libudev.h>
-#endif
-
#include "compat-api.h"
#include "vivante.h"
#include "vivante_dri2.h"
@@ -39,55 +35,37 @@
#define DRM_MODULE_NAME "armada-drm"
#define DRM_DEFAULT_BUS_ID NULL
+enum {
+ OPTION_XV_ACCEL,
+ OPTION_USE_GPU,
+};
+
const OptionInfoRec armada_drm_options[] = {
- { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_XV_ACCEL, "XvAccel", OPTV_BOOLEAN, {0}, FALSE },
{ OPTION_USE_GPU, "UseGPU", OPTV_BOOLEAN, {0}, FALSE },
- { OPTION_HOTPLUG, "HotPlug", OPTV_BOOLEAN, {0}, TRUE },
{ -1, NULL, OPTV_NONE, {0}, FALSE }
};
static void armada_drm_ModifyScreenPixmap(ScreenPtr pScreen,
- struct armada_drm_info *drm, int width, int height, int depth, int bpp,
+ struct armada_drm_info *arm, int width, int height, int depth, int bpp,
struct drm_armada_bo *bo)
{
PixmapPtr pixmap = pScreen->GetScreenPixmap(pScreen);
pScreen->ModifyPixmapHeader(pixmap, width, height, depth, bpp,
bo->pitch, bo->ptr);
- if (drm->accel)
+ if (arm->accel)
vivante_set_pixmap_bo(pixmap, bo);
}
-static void drmmode_ConvertToKMode(drmModeModeInfoPtr kmode, DisplayModePtr mode)
-{
- memset(kmode, 0, sizeof(*kmode));
-
- kmode->clock = mode->Clock;
- kmode->hdisplay = mode->HDisplay;
- kmode->hsync_start = mode->HSyncStart;
- kmode->hsync_end = mode->HSyncEnd;
- kmode->htotal = mode->HTotal;
- kmode->hskew = mode->HSkew;
- kmode->vdisplay = mode->VDisplay;
- kmode->vsync_start = mode->VSyncStart;
- kmode->vsync_end = mode->VSyncEnd;
- kmode->vtotal = mode->VTotal;
- kmode->vscan = mode->VScan;
- kmode->flags = mode->Flags;
- if (mode->name)
- strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
- kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
-}
-
static struct drm_armada_bo *armada_bo_alloc_framebuffer(ScrnInfoPtr pScrn,
int width, int height, int bpp)
{
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
struct drm_armada_bo *bo;
int ret;
- bo = drm_armada_bo_dumb_create(drm->bufmgr, width, height, bpp);
+ bo = drm_armada_bo_dumb_create(arm->bufmgr, width, height, bpp);
if (!bo) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] failed to allocate new bo: %s\n",
@@ -113,100 +91,20 @@ static struct drm_armada_bo *armada_bo_alloc_framebuffer(ScrnInfoPtr pScrn,
/*
* CRTC support
*/
-static Bool armada_drm_crtc_apply(xf86CrtcPtr crtc, drmModeModeInfoPtr kmode)
-{
- ScrnInfoPtr pScrn = crtc->scrn;
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- struct armada_crtc_info *drmc = armada_crtc(crtc);
- uint32_t fb_id, *output_ids;
- int x, y, i, ret, output_num;
-
- if (!kmode)
- kmode = &drmc->kmode;
-
- output_ids = calloc(xf86_config->num_output, sizeof *output_ids);
- if (!output_ids)
- return FALSE;
-
- for (output_num = i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
- struct armada_conn_info *conn;
-
- if (output->crtc == crtc) {
- conn = output->driver_private;
- output_ids[output_num++] = conn->mode_output->connector_id;
- }
- }
-
- if (!xf86CrtcRotate(crtc)) {
- ret = FALSE;
- goto done;
- }
-
- crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
- crtc->gamma_blue, crtc->gamma_size);
-
- if (drmc->rotate_fb_id) {
- fb_id = drmc->rotate_fb_id;
- x = y = 0;
- } else {
- fb_id = drmc->drm->fb_id;
- x = crtc->x;
- y = crtc->y;
- }
-
- ret = drmModeSetCrtc(drmc->drm_fd, drmc->mode_crtc->crtc_id, fb_id,
- x, y, output_ids, output_num, kmode);
- if (ret) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] failed to set mode on crtc %u: %s\n",
- drmc->mode_crtc->crtc_id, strerror(errno));
- ret = FALSE;
- } else {
- ret = TRUE;
-
- for (i = 0; i < xf86_config->num_output; i++) {
- xf86OutputPtr output = xf86_config->output[i];
-
- if (output->crtc != crtc)
- continue;
-
- output->funcs->dpms(output, DPMSModeOn);
- }
- }
-
- /* Work around stricter checks in X */
- if (pScrn->pScreen && drmc->drm->hw_cursor)
- xf86_reload_cursors(pScrn->pScreen);
-
-done:
- free(output_ids);
- return ret;
-}
-
-static void armada_drm_crtc_dpms(xf86CrtcPtr crtc, int mode)
-{
-}
-
static Bool
armada_drm_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
Rotation rotation, int x, int y)
{
ScrnInfoPtr pScrn = crtc->scrn;
- struct armada_crtc_info *drmc = armada_crtc(crtc);
- struct armada_drm_info *drm = drmc->drm;
- drmModeModeInfo kmode;
- DisplayModeRec saved_mode;
- Rotation saved_rotation;
- int ret, saved_x, saved_y;
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
if (drm->fb_id == 0) {
- ret = drmModeAddFB(drmc->drm_fd,
- pScrn->virtualX, pScrn->virtualY,
- pScrn->depth, pScrn->bitsPerPixel,
- drm->front_bo->pitch, drm->front_bo->handle,
- &drm->fb_id);
- if (ret < 0) {
+ if (drmModeAddFB(drm->fd,
+ pScrn->virtualX, pScrn->virtualY,
+ pScrn->depth, pScrn->bitsPerPixel,
+ arm->front_bo->pitch, arm->front_bo->handle,
+ &drm->fb_id) < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] failed to add fb: %s\n",
strerror(errno));
@@ -214,73 +112,23 @@ armada_drm_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
}
}
- saved_mode = crtc->mode;
- saved_x = crtc->x;
- saved_y = crtc->y;
- saved_rotation = crtc->rotation;
- crtc->mode = *mode;
- crtc->x = x;
- crtc->y = y;
- crtc->rotation = rotation;
-
- drmmode_ConvertToKMode(&kmode, mode);
-
- ret = armada_drm_crtc_apply(crtc, &kmode);
- if (!ret) {
- crtc->mode = saved_mode;
- crtc->x = saved_x;
- crtc->y = saved_y;
- crtc->rotation = saved_rotation;
- } else
- drmc->kmode = kmode;
- return ret;
-}
-
-static void armada_drm_crtc_gamma_set(xf86CrtcPtr crtc, CARD16 *red,
- CARD16 *green, CARD16 *blue, int size)
-{
- struct armada_crtc_info *drmc = armada_crtc(crtc);
-
- drmModeCrtcSetGamma(drmc->drm_fd, drmc->mode_crtc->crtc_id,
- size, red, green, blue);
-}
-
-static void armada_drm_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
-{
- struct armada_crtc_info *drmc = armada_crtc(crtc);
-
- drmModeMoveCursor(drmc->drm_fd, drmc->mode_crtc->crtc_id, x, y);
-}
-
-static void armada_drm_crtc_show_cursor(xf86CrtcPtr crtc)
-{
- struct armada_crtc_info *drmc = armada_crtc(crtc);
-
- drmModeSetCursor(drmc->drm_fd, drmc->mode_crtc->crtc_id,
- drmc->cursor_bo->handle,
- drmc->cursor_max_width, drmc->cursor_max_height);
-}
-
-static void armada_drm_crtc_hide_cursor(xf86CrtcPtr crtc)
-{
- struct armada_crtc_info *drmc = armada_crtc(crtc);
-
- drmModeSetCursor(drmc->drm_fd, drmc->mode_crtc->crtc_id, 0, 0, 0);
+ return common_drm_crtc_set_mode_major(crtc, mode, rotation, x, y);
}
static void armada_drm_crtc_load_cursor_argb(xf86CrtcPtr crtc, CARD32 *image)
{
- struct armada_crtc_info *drmc = armada_crtc(crtc);
+ struct common_crtc_info *drmc = common_crtc(crtc);
+ struct common_drm_info *drm = GET_DRM_INFO(crtc->scrn);
- drm_armada_bo_subdata(drmc->cursor_bo, 0,
- drmc->cursor_max_width *
- drmc->cursor_max_height * 4, image);
+ drm_armada_bo_subdata(drmc->cursor_data, 0,
+ drm->cursor_max_width *
+ drm->cursor_max_height * 4, image);
}
static void *
armada_drm_crtc_shadow_allocate(xf86CrtcPtr crtc, int width, int height)
{
- struct armada_crtc_info *drmc = armada_crtc(crtc);
+ struct common_crtc_info *drmc = common_crtc(crtc);
ScrnInfoPtr pScrn = crtc->scrn;
struct drm_armada_bo *bo;
int ret;
@@ -311,31 +159,31 @@ static PixmapPtr
armada_drm_crtc_shadow_create(xf86CrtcPtr crtc, void *data,
int width, int height)
{
- struct armada_crtc_info *drmc = armada_crtc(crtc);
- ScrnInfoPtr scrn = crtc->scrn;
+ ScrnInfoPtr pScrn = crtc->scrn;
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
PixmapPtr rotate_pixmap;
struct drm_armada_bo *bo;
if (!data)
data = armada_drm_crtc_shadow_allocate(crtc, width, height);
if (!data) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to allocate shadow pixmap data for rotated CRTC\n");
return NULL;
}
bo = data;
- rotate_pixmap = GetScratchPixmapHeader(scrn->pScreen, width, height,
- scrn->depth, scrn->bitsPerPixel,
+ rotate_pixmap = GetScratchPixmapHeader(pScrn->pScreen, width, height,
+ pScrn->depth, pScrn->bitsPerPixel,
bo->pitch, bo->ptr);
if (!rotate_pixmap) {
- xf86DrvMsg(scrn->scrnIndex, X_ERROR,
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"Failed to allocate shadow pixmap for rotated CRTC\n");
return NULL;
}
- if (drmc->drm->accel)
+ if (arm->accel)
vivante_set_pixmap_bo(rotate_pixmap, bo);
return rotate_pixmap;
@@ -346,13 +194,13 @@ armada_drm_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rot_pixmap,
void *data)
{
if (rot_pixmap) {
- struct armada_drm_info *drm = GET_DRM_INFO(crtc->scrn);
- if (drm->accel)
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(crtc->scrn);
+ if (arm->accel)
vivante_free_pixmap(rot_pixmap);
FreeScratchPixmapHeader(rot_pixmap);
}
if (data) {
- struct armada_crtc_info *drmc = armada_crtc(crtc);
+ struct common_crtc_info *drmc = common_crtc(crtc);
drmModeRmFB(drmc->drm_fd, drmc->rotate_fb_id);
drmc->rotate_fb_id = 0;
@@ -363,12 +211,12 @@ armada_drm_crtc_shadow_destroy(xf86CrtcPtr crtc, PixmapPtr rot_pixmap,
static void armada_drm_crtc_destroy(xf86CrtcPtr crtc)
{
- struct armada_crtc_info *drmc = armada_crtc(crtc);
+ struct common_crtc_info *drmc = common_crtc(crtc);
- if (drmc->cursor_bo) {
+ if (drmc->cursor_data) {
drmModeSetCursor(drmc->drm_fd, drmc->mode_crtc->crtc_id,
0, 0, 0);
- drm_armada_bo_put(drmc->cursor_bo);
+ drm_armada_bo_put(drmc->cursor_data);
}
drmModeFreeCrtc(drmc->mode_crtc);
@@ -376,12 +224,12 @@ static void armada_drm_crtc_destroy(xf86CrtcPtr crtc)
}
static const xf86CrtcFuncsRec drm_crtc_funcs = {
- .dpms = armada_drm_crtc_dpms,
- .gamma_set = armada_drm_crtc_gamma_set,
+ .dpms = common_drm_crtc_dpms,
+ .gamma_set = common_drm_crtc_gamma_set,
.set_mode_major = armada_drm_crtc_set_mode_major,
- .set_cursor_position = armada_drm_crtc_set_cursor_position,
- .show_cursor = armada_drm_crtc_show_cursor,
- .hide_cursor = armada_drm_crtc_hide_cursor,
+ .set_cursor_position = common_drm_crtc_set_cursor_position,
+ .show_cursor = common_drm_crtc_show_cursor,
+ .hide_cursor = common_drm_crtc_hide_cursor,
.load_cursor_argb = armada_drm_crtc_load_cursor_argb,
.shadow_create = armada_drm_crtc_shadow_create,
.shadow_allocate = armada_drm_crtc_shadow_allocate,
@@ -389,52 +237,41 @@ static const xf86CrtcFuncsRec drm_crtc_funcs = {
.destroy = armada_drm_crtc_destroy,
};
-static Bool
-armada_drm_crtc_init(ScrnInfoPtr pScrn, struct armada_drm_info *drm,
- unsigned num)
+static void armada_drm_crtc_alloc_cursors(ScrnInfoPtr pScrn)
{
- struct armada_crtc_info *drmc;
- xf86CrtcPtr crtc;
- uint32_t id;
-
- id = drm->mode_res->crtcs[num];
-
- crtc = xf86CrtcCreate(pScrn, &drm_crtc_funcs);
- if (!crtc)
- return FALSE;
-
- drmc = xnfcalloc(1, sizeof *drmc);
- if (!drmc)
- return FALSE;
-
- drmc->drm_fd = drm->fd;
- drmc->drm = drm;
- drmc->num = num;
- drmc->cursor_max_width = CURSOR_MAX_WIDTH;
- drmc->cursor_max_height = CURSOR_MAX_HEIGHT;
- drmc->mode_crtc = drmModeGetCrtc(drmc->drm_fd, id);
- crtc->driver_private = drmc;
-
- /* Test whether hardware cursor is supported */
- if (drmModeSetCursor(drmc->drm_fd, id, 0, 0, 0))
- drm->has_hw_cursor = FALSE;
-
- drmc->cursor_bo = drm_armada_bo_dumb_create(drm->bufmgr,
- drmc->cursor_max_width,
- drmc->cursor_max_height,
- 32);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
- return TRUE;
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+ struct common_crtc_info *drmc = common_crtc(crtc);
+ struct drm_armada_bo *bo;
+
+ bo = drm_armada_bo_dumb_create(arm->bufmgr,
+ drm->cursor_max_width,
+ drm->cursor_max_height,
+ 32);
+
+ if (bo) {
+ drmc->cursor_handle = bo->handle;
+ drmc->cursor_data = bo;
+ } else {
+ drm->has_hw_cursor = FALSE;
+ break;
+ }
+ }
}
static Bool armada_drm_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
{
ScreenPtr screen = screenInfo.screens[pScrn->scrnIndex];
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
struct drm_armada_bo *bo, *old_bo;
- uint32_t old_fb_id;
- int ret, i;
+ uint32_t fb_id;
+ int ret, displayWidth;
if (pScrn->virtualX == width && pScrn->virtualY == height)
return TRUE;
@@ -444,10 +281,9 @@ static Bool armada_drm_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
if (!bo)
return FALSE;
- old_fb_id = drm->fb_id;
ret = drmModeAddFB(drm->fd, width, height,
pScrn->depth, pScrn->bitsPerPixel,
- bo->pitch, bo->handle, &drm->fb_id);
+ bo->pitch, bo->handle, &fb_id);
if (ret) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] failed to add fb: %s\n", strerror(errno));
@@ -455,25 +291,14 @@ static Bool armada_drm_xf86crtc_resize(ScrnInfoPtr pScrn, int width, int height)
return FALSE;
}
- /* Okay, now switch everything */
- pScrn->virtualX = width;
- pScrn->virtualY = height;
- pScrn->displayWidth = bo->pitch / drm->cpp;
- old_bo = drm->front_bo;
- drm->front_bo = bo;
+ old_bo = arm->front_bo;
+ arm->front_bo = bo;
- armada_drm_ModifyScreenPixmap(screen, drm, width, height, -1, -1, bo);
+ armada_drm_ModifyScreenPixmap(screen, arm, width, height, -1, -1, bo);
- for (i = 0; i < xf86_config->num_crtc; i++) {
- xf86CrtcPtr crtc = xf86_config->crtc[i];
-
- if (!crtc->enabled)
- continue;
-
- armada_drm_crtc_apply(crtc, NULL);
- }
+ displayWidth = bo->pitch / arm->cpp;
+ common_drm_crtc_resize(pScrn, width, height, displayWidth, fb_id);
- drmModeRmFB(drm->fd, old_fb_id);
drm_armada_bo_put(old_bo);
return TRUE;
}
@@ -482,174 +307,6 @@ static const xf86CrtcConfigFuncsRec armada_drm_config_funcs = {
armada_drm_xf86crtc_resize,
};
-#ifdef HAVE_UDEV
-static void armada_drm_handle_uevent(int fd, pointer data)
-{
- ScrnInfoPtr pScrn = data;
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
- struct udev_device *ud;
-
- ud = udev_monitor_receive_device(drm->udev.monitor);
- if (ud) {
- dev_t dev = udev_device_get_devnum(ud);
- const char *hp = udev_device_get_property_value(ud, "HOTPLUG");
-
- if (dev == drm->udev.drm_dev && hp && strtol(hp, NULL, 10) == 1)
- RRGetInfo(screenInfo.screens[pScrn->scrnIndex], TRUE);
-
- udev_device_unref(ud);
- }
-}
-
-static Bool armada_drm_udev_init(ScrnInfoPtr pScrn)
-{
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
- struct udev_monitor *udev_mon;
- struct udev *udev;
- struct stat st;
- MessageType from = X_CONFIG;
- Bool hotplug;
-
- if (!xf86GetOptValBool(drm->Options, OPTION_HOTPLUG, &hotplug)) {
- from = X_DEFAULT;
- hotplug = TRUE;
- }
-
- xf86DrvMsg(pScrn->scrnIndex, from, "hotplug detection %sabled\n",
- hotplug ? "en" : "dis");
- if (!hotplug)
- return TRUE;
-
- if (fstat(drm->fd, &st) || !S_ISCHR(st.st_mode))
- return FALSE;
-
- drm->udev.drm_dev = st.st_rdev;
-
- udev = udev_new();
- if (!udev)
- return FALSE;
-
- udev_mon = udev_monitor_new_from_netlink(udev, "udev");
- if (!udev_mon) {
- udev_unref(udev);
- return FALSE;
- }
-
- if (udev_monitor_filter_add_match_subsystem_devtype(udev_mon,
- "drm", "drm_minor") ||
- udev_monitor_enable_receiving(udev_mon)) {
- udev_monitor_unref(udev_mon);
- udev_unref(udev);
- return FALSE;
- }
-
- drm->udev.monitor = udev_mon;
- drm->udev.handler = xf86AddGeneralHandler(udev_monitor_get_fd(udev_mon),
- armada_drm_handle_uevent,
- pScrn);
-
- return TRUE;
-}
-
-static void armada_drm_udev_fini(ScrnInfoPtr pScrn, struct armada_drm_info *drm)
-{
- if (drm->udev.monitor) {
- struct udev *udev = udev_monitor_get_udev(drm->udev.monitor);
-
- xf86RemoveGeneralHandler(drm->udev.handler);
- udev_monitor_unref(drm->udev.monitor);
- udev_unref(udev);
- }
-}
-#endif
-
-static void armada_drm_LoadPalette(ScrnInfoPtr pScrn, int num, int *indices,
- LOCO *colors, VisualPtr pVisual)
-{
- xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
- uint16_t lut_r[256], lut_g[256], lut_b[256];
- int i, p;
-
- for (i = 0; i < num; i++) {
- int index = indices[i];
- lut_r[index] = colors[index].red << 8;
- lut_g[index] = colors[index].green << 8;
- lut_b[index] = colors[index].blue << 8;
- }
-
- for (p = 0; p < xf86_config->num_crtc; p++) {
- xf86CrtcPtr crtc = xf86_config->crtc[p];
-
-#ifdef RANDR_12_INTERFACE
- RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
-#else
- crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
-#endif
- }
-}
-
-static void armada_drm_AdjustFrame(ADJUST_FRAME_ARGS_DECL)
-{
- SCRN_INFO_PTR(arg);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- xf86OutputPtr output = config->output[config->compat_output];
- xf86CrtcPtr crtc = output->crtc;
-
- if (crtc && crtc->enabled) {
- int saved_x = crtc->x;
- int saved_y = crtc->y;
- int ret;
-
- crtc->x = x;
- crtc->y = y;
-
- ret = crtc->funcs->set_mode_major(crtc, &crtc->mode,
- crtc->rotation, x, y);
- if (!ret) {
- crtc->x = saved_x;
- crtc->y = saved_y;
- }
- }
-}
-
-static Bool armada_drm_EnterVT(VT_FUNC_ARGS_DECL)
-{
- SCRN_INFO_PTR(arg);
- xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
- int i;
-
- if (drmSetMaster(drm->fd))
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "[drm] set master failed: %s\n", strerror(errno));
-
- if (!xf86SetDesiredModes(pScrn))
- return FALSE;
-
- /* Disable unused CRTCs */
- for (i = 0; i < config->num_crtc; i++) {
- xf86CrtcPtr crtc = config->crtc[i];
- struct armada_crtc_info *drmc = armada_crtc(crtc);
- if (!crtc->enabled)
- drmModeSetCrtc(drm->fd, drmc->mode_crtc->crtc_id,
- 0, 0, 0, NULL, 0, NULL);
- }
-
- return TRUE;
-}
-
-static void armada_drm_LeaveVT(VT_FUNC_ARGS_DECL)
-{
- SCRN_INFO_PTR(arg);
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
-
- xf86RotateFreeShadow(pScrn);
-
- xf86_hide_cursors(pScrn);
-
- drmDropMaster(drm->fd);
-}
-
static ModeStatus
armada_drm_ValidMode(SCRN_ARG_TYPE arg1, DisplayModePtr mode, Bool verbose,
int flags)
@@ -667,84 +324,47 @@ armada_drm_ValidMode(SCRN_ARG_TYPE arg1, DisplayModePtr mode, Bool verbose,
return MODE_OK;
}
-static Bool armada_drm_SwitchMode(SWITCH_MODE_ARGS_DECL)
-{
- SCRN_INFO_PTR(arg);
-
- return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
-}
-
static Bool armada_drm_CloseScreen(CLOSE_SCREEN_ARGS_DECL)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
PixmapPtr pixmap = pScreen->GetScreenPixmap(pScreen);
- Bool ret;
-
-#ifdef HAVE_UDEV
- armada_drm_udev_fini(pScrn, drm);
-#endif
- if (drm->fb_id) {
- drmModeRmFB(drm->fd, drm->fb_id);
- drm->fb_id = 0;
+ if (arm->front_bo) {
+ drm_armada_bo_put(arm->front_bo);
+ arm->front_bo = NULL;
}
- if (drm->front_bo) {
- drm_armada_bo_put(drm->front_bo);
- drm->front_bo = NULL;
- }
- if (drm->accel)
- vivante_free_pixmap(pixmap);
-
- if (drm->hw_cursor)
- xf86_cursors_fini(pScreen);
-
- pScreen->CloseScreen = drm->CloseScreen;
- ret = (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
- if (pScrn->vtSema)
- armada_drm_LeaveVT(VT_FUNC_ARGS(0));
+ if (arm->accel)
+ vivante_free_pixmap(pixmap);
- pScrn->vtSema = FALSE;
+ pScreen->CloseScreen = arm->CloseScreen;
- return ret;
+ return pScreen->CloseScreen(CLOSE_SCREEN_ARGS);
}
static Bool armada_drm_CreateScreenResources(ScreenPtr pScreen)
{
ScrnInfoPtr pScrn = xf86Screens[pScreen->myNum];
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
Bool ret;
- pScreen->CreateScreenResources = drm->CreateScreenResources;
+ pScreen->CreateScreenResources = arm->CreateScreenResources;
ret = pScreen->CreateScreenResources(pScreen);
if (ret) {
- struct drm_armada_bo *bo = drm->front_bo;
+ struct drm_armada_bo *bo = arm->front_bo;
- armada_drm_ModifyScreenPixmap(pScreen, drm, -1, -1, -1, -1, bo);
+ armada_drm_ModifyScreenPixmap(pScreen, arm, -1, -1, -1, -1, bo);
}
return ret;
}
-static void armada_drm_wakeup_handler(pointer data, int err, pointer p)
-{
- struct armada_drm_info *drm = data;
- fd_set *read_mask = p;
-
- if (data == NULL || err < 0)
- return;
-
- if (FD_ISSET(drm->fd, read_mask))
- drmHandleEvent(drm->fd, &drm->event_context);
-}
-
-static Bool
-armada_drm_ScreenInit(SCREEN_INIT_ARGS_DECL)
+static Bool armada_drm_ScreenInit(SCREEN_INIT_ARGS_DECL)
{
ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
struct drm_armada_bo *bo;
- int visuals, preferredCVC;
if (drmSetMaster(drm->fd)) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
@@ -752,239 +372,70 @@ armada_drm_ScreenInit(SCREEN_INIT_ARGS_DECL)
return FALSE;
}
- drm->accel = xf86ReturnOptValBool(drm->Options, OPTION_USE_GPU, TRUE);
+ arm->accel = xf86ReturnOptValBool(arm->Options, OPTION_USE_GPU, TRUE);
bo = armada_bo_alloc_framebuffer(pScrn, pScrn->virtualX,
pScrn->virtualY, pScrn->bitsPerPixel);
if (!bo)
return FALSE;
- drm->front_bo = bo;
- pScrn->displayWidth = bo->pitch / drm->cpp;
+ arm->front_bo = bo;
+ pScrn->displayWidth = bo->pitch / arm->cpp;
- miClearVisualTypes();
- if (pScrn->bitsPerPixel > 8) {
- visuals = TrueColorMask;
- preferredCVC = TrueColor;
- } else {
- visuals = miGetDefaultVisualMask(pScrn->depth);
- preferredCVC = pScrn->defaultVisual;
- }
-
- if (!miSetVisualTypes(pScrn->depth, visuals, pScrn->rgbBits, preferredCVC)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] failed to set visual types for %d bpp depth %d\n",
- pScrn->bitsPerPixel, pScrn->depth);
+ if (!common_drm_PreScreenInit(pScreen))
return FALSE;
- }
-
- if (!miSetPixmapDepths()) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] failed to set pixmap depths\n");
- return FALSE;
- }
-
- if (!fbScreenInit(pScreen, NULL, pScrn->virtualX, pScrn->virtualY,
- pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
- pScrn->bitsPerPixel)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] fbScreenInit failed\n");
- return FALSE;
- }
-
- if (pScrn->bitsPerPixel > 8) {
- /* Fixup RGB ordering */
- VisualPtr visual = pScreen->visuals + pScreen->numVisuals;
- while (--visual >= pScreen->visuals) {
- if ((visual->class | DynamicClass) == DirectColor) {
- visual->offsetRed = pScrn->offset.red;
- visual->offsetGreen = pScrn->offset.green;
- visual->offsetBlue = pScrn->offset.blue;
- visual->redMask = pScrn->mask.red;
- visual->greenMask = pScrn->mask.green;
- visual->blueMask = pScrn->mask.blue;
- }
- }
- }
-
- if (!fbPictureInit(pScreen, NULL, 0)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] fbPictureInit failed\n");
- return FALSE;
- }
-
- xf86SetBlackWhitePixels(pScreen);
-
- if (drm->accel && !vivante_ScreenInit(pScreen, drm->bufmgr)) {
- xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
- "[drm] Vivante initialization failed, running unaccelerated\n");
- drm->accel = FALSE;
- }
-
- xf86SetBackingStore(pScreen);
- xf86SetSilkenMouse(pScreen);
-
- /* software cursor */
- miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
-
- drm->hw_cursor = xf86ReturnOptValBool(drm->Options, OPTION_HW_CURSOR,
- drm->has_hw_cursor);
- if (drm->hw_cursor && !drm->has_hw_cursor) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "No hardware cursor support - disabling hardware cursors\n");
- drm->hw_cursor = FALSE;
- }
- if (drm->hw_cursor &&
- xf86_cursors_init(pScreen,
- CURSOR_MAX_WIDTH, CURSOR_MAX_HEIGHT,
- HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
- HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
- HARDWARE_CURSOR_INVERT_MASK |
- HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
- HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
- HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
- HARDWARE_CURSOR_UPDATE_UNHIDDEN |
- HARDWARE_CURSOR_ARGB)) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO,
- "Using hardware cursors\n");
- } else {
- drm->hw_cursor = FALSE;
- }
- pScreen->SaveScreen = xf86SaveScreen;
- drm->CloseScreen = pScreen->CloseScreen;
+ arm->CloseScreen = pScreen->CloseScreen;
pScreen->CloseScreen = armada_drm_CloseScreen;
- drm->CreateScreenResources = pScreen->CreateScreenResources;
+ arm->CreateScreenResources = pScreen->CreateScreenResources;
pScreen->CreateScreenResources = armada_drm_CreateScreenResources;
- if (!xf86CrtcScreenInit(pScreen)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] failed to initialize screen\n");
- return FALSE;
+ if (arm->accel && !vivante_ScreenInit(pScreen, arm->bufmgr)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[drm] Vivante initialization failed, running unaccelerated\n");
+ arm->accel = FALSE;
}
- if (!miCreateDefColormap(pScreen)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] failed to initialize default colormap\n");
+ if (!common_drm_PostScreenInit(pScreen))
return FALSE;
- }
- if (!xf86HandleColormaps(pScreen, 256, 8, armada_drm_LoadPalette, NULL,
- CMAP_RELOAD_ON_MODE_SWITCH |
- CMAP_PALETTED_TRUECOLOR)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] failed to initialize colormap handler\n");
- return FALSE;
- }
-
- xf86DPMSInit(pScreen, xf86DPMSSet, 0);
-
- if (xf86ReturnOptValBool(drm->Options, OPTION_XV_ACCEL, TRUE))
+ if (xf86ReturnOptValBool(arm->Options, OPTION_XV_ACCEL, TRUE))
armada_drm_XvInit(pScrn);
- /* Setup the synchronisation feedback */
- AddGeneralSocket(drm->fd);
- RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
- armada_drm_wakeup_handler, drm);
-
-#ifdef HAVE_UDEV
- if (!armada_drm_udev_init(pScrn)) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "[drm] failed to connect with udev: %s\n",
- strerror(errno));
- return FALSE;
- }
-#endif
-
pScrn->vtSema = TRUE;
- return armada_drm_EnterVT(VT_FUNC_ARGS(0));
+ return common_drm_EnterVT(VT_FUNC_ARGS(0));
}
static Bool armada_drm_pre_init(ScrnInfoPtr pScrn)
{
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
- drmVersionPtr version;
- Gamma zeros = { 0.0, 0.0, 0.0 };
- int i;
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
xf86CollectOptions(pScrn, NULL);
- drm->Options = malloc(sizeof(armada_drm_options));
- if (!drm->Options)
+ arm->Options = malloc(sizeof(armada_drm_options));
+ if (!arm->Options)
return FALSE;
- memcpy(drm->Options, armada_drm_options, sizeof(armada_drm_options));
- xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, drm->Options);
-
- version = drmGetVersion(drm->fd);
- if (version) {
- xf86DrvMsg(pScrn->scrnIndex, X_INFO, "hardware: %s\n",
- version->name);
- drmFreeVersion(version);
- }
+ memcpy(arm->Options, armada_drm_options, sizeof(armada_drm_options));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, arm->Options);
- drm->cpp = (pScrn->bitsPerPixel + 7) / 8;
+ arm->cpp = (pScrn->bitsPerPixel + 7) / 8;
xf86CrtcConfigInit(pScrn, &armada_drm_config_funcs);
- drm->mode_res = drmModeGetResources(drm->fd);
- if (!drm->mode_res) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
- "failed to get resources: %s\n", strerror(errno));
+ if (!common_drm_init_mode_resources(pScrn, &drm_crtc_funcs))
return FALSE;
- }
-
- xf86CrtcSetSizeRange(pScrn, drm->mode_res->min_width,
- drm->mode_res->min_height,
- drm->mode_res->max_width,
- drm->mode_res->max_height);
-
- drm->has_hw_cursor = TRUE;
- for (i = 0; i < drm->mode_res->count_crtcs; i++)
- if (!armada_drm_crtc_init(pScrn, drm, i))
- return FALSE;
-
- for (i = 0; i < drm->mode_res->count_connectors; i++)
- common_drm_conn_init(pScrn, drm->fd,
- drm->mode_res->connectors[i]);
- xf86InitialConfiguration(pScrn, TRUE);
-
- /* Limit the maximum framebuffer size to 16MB */
- pScrn->videoRam = 16 * 1048576;
-
- drm->event_context.version = DRM_EVENT_CONTEXT_VERSION;
-#ifdef HAVE_DRI2
- drm->event_context.vblank_handler = vivante_dri2_vblank;
-#else
- drm->event_context.vblank_handler = NULL;
-#endif
- drm->event_context.page_flip_handler = NULL;
-
- if (!xf86SetGamma(pScrn, zeros))
- return FALSE;
-
- if (pScrn->modes == NULL) {
- xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
- return FALSE;
- }
-
- pScrn->currentMode = pScrn->modes;
-
- /* Set display resolution */
- xf86SetDpi(pScrn, 0, 0);
-
- if (!xf86LoadSubModule(pScrn, "fb"))
- return FALSE;
+ armada_drm_crtc_alloc_cursors(pScrn);
return TRUE;
}
-static int armada_get_cap(struct armada_drm_info *drm, uint64_t cap,
- uint64_t *val, int scrnIndex, const char *name)
+static int armada_get_cap(int fd, uint64_t cap, uint64_t *val, int scrnIndex,
+ const char *name)
{
int err;
- err = drmGetCap(drm->fd, cap, val);
+ err = drmGetCap(fd, cap, val);
if (err)
xf86DrvMsg(scrnIndex, X_ERROR,
"[drm] failed to get %s capability: %s\n",
@@ -995,9 +446,10 @@ static int armada_get_cap(struct armada_drm_info *drm, uint64_t cap,
static Bool armada_drm_open_master(ScrnInfoPtr pScrn)
{
- struct armada_drm_info *drm;
+ struct all_drm_info *drm;
EntityInfoPtr pEnt;
drmSetVersion sv;
+ drmVersionPtr version;
const char *busid = DRM_DEFAULT_BUS_ID;
uint64_t val;
int err;
@@ -1017,8 +469,16 @@ static Bool armada_drm_open_master(ScrnInfoPtr pScrn)
if (!drm)
return FALSE;
- drm->fd = drmOpen(DRM_MODULE_NAME, busid);
- if (drm->fd < 0) {
+ drm->common.cursor_max_width = CURSOR_MAX_WIDTH;
+ drm->common.cursor_max_height = CURSOR_MAX_HEIGHT;
+ drm->common.private = &drm->armada;
+ drm->common.event_context.version = DRM_EVENT_CONTEXT_VERSION;
+#ifdef HAVE_DRI2
+ drm->common.event_context.vblank_handler = vivante_dri2_vblank;
+#endif
+
+ drm->common.fd = drmOpen(DRM_MODULE_NAME, busid);
+ if (drm->common.fd < 0) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] Failed to open DRM device for %s: %s\n",
busid, strerror(errno));
@@ -1033,7 +493,7 @@ static Bool armada_drm_open_master(ScrnInfoPtr pScrn)
sv.drm_di_minor = 1;
sv.drm_dd_major = -1;
sv.drm_dd_minor = -1;
- err = drmSetInterfaceVersion(drm->fd, &sv);
+ err = drmSetInterfaceVersion(drm->common.fd, &sv);
if (err) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] failed to set DRM interface version: %s\n",
@@ -1041,7 +501,7 @@ static Bool armada_drm_open_master(ScrnInfoPtr pScrn)
goto err_drm_close;
}
- if (armada_get_cap(drm, DRM_CAP_PRIME, &val,
+ if (armada_get_cap(drm->common.fd, DRM_CAP_PRIME, &val,
pScrn->scrnIndex, "DRM_CAP_PRIME"))
goto err_drm_close;
if (!(val & DRM_PRIME_CAP_EXPORT)) {
@@ -1050,7 +510,7 @@ static Bool armada_drm_open_master(ScrnInfoPtr pScrn)
goto err_drm_close;
}
- if (armada_get_cap(drm, DRM_CAP_DUMB_BUFFER, &val,
+ if (armada_get_cap(drm->common.fd, DRM_CAP_DUMB_BUFFER, &val,
pScrn->scrnIndex, "DRM_CAP_DUMB_BUFFER"))
goto err_drm_close;
if (!val) {
@@ -1059,41 +519,42 @@ static Bool armada_drm_open_master(ScrnInfoPtr pScrn)
goto err_drm_close;
}
- err = drm_armada_init(drm->fd, &drm->bufmgr);
+ err = drm_armada_init(drm->common.fd, &drm->armada.bufmgr);
if (err) {
xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
"[drm] failed to initialize Armada DRM manager.\n");
goto err_drm_close;
}
- SET_DRM_INFO(pScrn, drm);
+ SET_DRM_INFO(pScrn, &drm->common);
+
+ version = drmGetVersion(drm->common.fd);
+ if (version) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO, "hardware: %s\n",
+ version->name);
+ drmFreeVersion(version);
+ }
return TRUE;
err_drm_close:
- drmClose(drm->fd);
+ drmClose(drm->common.fd);
err_free:
free(drm);
return FALSE;
}
-static void armada_drm_close_master(ScrnInfoPtr pScrn)
-{
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
-
- if (drm) {
- drm_armada_fini(drm->bufmgr);
- drmClose(drm->fd);
- SET_DRM_INFO(pScrn, NULL);
- free(drm);
- }
-}
-
static void armada_drm_FreeScreen(FREE_SCREEN_ARGS_DECL)
{
SCRN_INFO_PTR(arg);
- armada_drm_close_master(pScrn);
+ if (pScrn->driverPrivate) {
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
+
+ drm_armada_fini(arm->bufmgr);
+ }
+
+ common_drm_FreeScreen(FREE_SCREEN_ARGS(pScrn));
}
static Bool armada_drm_PreInit(ScrnInfoPtr pScrn, int flags)
@@ -1113,6 +574,8 @@ static Bool armada_drm_PreInit(ScrnInfoPtr pScrn, int flags)
return FALSE;
}
+ /* Limit the maximum framebuffer size to 16MB */
+ pScrn->videoRam = 16 * 1048576;
pScrn->monitor = pScrn->confScreen->monitor;
pScrn->progClock = TRUE;
pScrn->rgbBits = 8;
@@ -1165,10 +628,10 @@ Bool armada_drm_init_screen(ScrnInfoPtr pScrn)
{
pScrn->PreInit = armada_drm_PreInit;
pScrn->ScreenInit = armada_drm_ScreenInit;
- pScrn->SwitchMode = armada_drm_SwitchMode;
- pScrn->AdjustFrame = armada_drm_AdjustFrame;
- pScrn->EnterVT = armada_drm_EnterVT;
- pScrn->LeaveVT = armada_drm_LeaveVT;
+ pScrn->SwitchMode = common_drm_SwitchMode;
+ pScrn->AdjustFrame = common_drm_AdjustFrame;
+ pScrn->EnterVT = common_drm_EnterVT;
+ pScrn->LeaveVT = common_drm_LeaveVT;
pScrn->FreeScreen = armada_drm_FreeScreen;
pScrn->ValidMode = armada_drm_ValidMode;
diff --git a/src/armada_drm.h b/src/armada_drm.h
index 0f765cf..a7a9824 100644
--- a/src/armada_drm.h
+++ b/src/armada_drm.h
@@ -11,63 +11,25 @@
#include <xf86drm.h>
#include <xf86drmMode.h>
-struct drm_armada_bo;
-
-struct armada_crtc_info {
- int drm_fd;
- struct armada_drm_info *drm;
- unsigned num;
- unsigned short cursor_max_width;
- unsigned short cursor_max_height;
- drmModeModeInfo kmode;
- drmModeCrtcPtr mode_crtc;
-
- struct drm_armada_bo *cursor_bo;
-
- uint32_t rotate_fb_id;
-};
-#define armada_crtc(crtc) \
- ((struct armada_crtc_info *)(crtc)->driver_private)
-
-struct drm_udev_info {
- struct udev_monitor *monitor;
- pointer *handler;
- dev_t drm_dev;
-};
+#include "common_drm.h"
struct armada_drm_info {
- int fd;
+ OptionInfoPtr Options;
+ CloseScreenProcPtr CloseScreen;
+ CreateScreenResourcesProcPtr CreateScreenResources;
struct drm_armada_bufmgr *bufmgr;
- drmEventContext event_context;
-
- unsigned cpp;
-
struct drm_armada_bo *front_bo;
- uint32_t fb_id;
- drmModeResPtr mode_res;
-
- Bool has_hw_cursor;
- Bool hw_cursor;
Bool accel;
-
-#ifdef HAVE_UDEV
- struct drm_udev_info udev;
-#endif
-
- CloseScreenProcPtr CloseScreen;
- CreateScreenResourcesProcPtr CreateScreenResources;
- OptionInfoPtr Options;
+ unsigned cpp;
};
-enum {
- OPTION_HW_CURSOR,
- OPTION_XV_ACCEL,
- OPTION_USE_GPU,
- OPTION_HOTPLUG,
+struct all_drm_info {
+ struct common_drm_info common;
+ struct armada_drm_info armada;
};
-#define GET_DRM_INFO(pScrn) ((struct armada_drm_info *)(pScrn)->driverPrivate)
-#define SET_DRM_INFO(pScrn, ptr) ((pScrn)->driverPrivate = (ptr))
+#define GET_ARMADA_DRM_INFO(pScrn) \
+ ((struct armada_drm_info *)GET_DRM_INFO(pScrn)->private)
/* DRM core support */
Bool armada_drm_init_screen(ScrnInfoPtr pScrn);
diff --git a/src/armada_drm_xv.c b/src/armada_drm_xv.c
index 94257f6..b3e545b 100644
--- a/src/armada_drm_xv.c
+++ b/src/armada_drm_xv.c
@@ -15,6 +15,7 @@
#include <armada_bufmgr.h>
#include "armada_drm.h"
+#include "common_drm.h"
#include "drm_fourcc.h"
#include "xf86Crtc.h"
#include "xf86xv.h"
@@ -55,7 +56,8 @@ struct armada_format {
};
struct drm_xv {
- struct armada_drm_info *drm;
+ int fd;
+ struct drm_armada_bufmgr *bufmgr;
/* Common information */
xf86CrtcPtr desired_crtc;
@@ -123,7 +125,7 @@ static int armada_drm_prop_set(ScrnInfoPtr pScrn, struct drm_xv *drmxv,
if (!drmxv->planes[i])
continue;
- drmModeObjectSetProperty(drmxv->drm->fd,
+ drmModeObjectSetProperty(drmxv->fd,
drmxv->planes[i]->plane_id,
DRM_MODE_OBJECT_PLANE, prop_id,
value);
@@ -144,7 +146,7 @@ static int armada_drm_old_update_attr(struct drm_xv *drmxv)
arg = drmxv->attrs;
arg.flags = ARMADA_OVERLAY_UPDATE_ATTRS;
- drmIoctl(drmxv->drm->fd, DRM_IOCTL_ARMADA_OVERLAY_ATTRS, &arg);
+ drmIoctl(drmxv->fd, DRM_IOCTL_ARMADA_OVERLAY_ATTRS, &arg);
return Success;
}
@@ -384,7 +386,7 @@ static void armada_drm_bufs_free(struct drm_xv *drmxv)
if (drmxv->bufs[i].fb_id) {
if (drmxv->bufs[i].fb_id == drmxv->plane_fb_id)
drmxv->plane_fb_id = 0;
- drmModeRmFB(drmxv->drm->fd, drmxv->bufs[i].fb_id);
+ drmModeRmFB(drmxv->fd, drmxv->bufs[i].fb_id);
drmxv->bufs[i].fb_id = 0;
}
if (drmxv->bufs[i].bo) {
@@ -394,7 +396,7 @@ static void armada_drm_bufs_free(struct drm_xv *drmxv)
}
if (drmxv->plane_fb_id) {
- drmModeRmFB(drmxv->drm->fd, drmxv->plane_fb_id);
+ drmModeRmFB(drmxv->fd, drmxv->plane_fb_id);
drmxv->plane_fb_id = 0;
}
@@ -416,7 +418,7 @@ armada_drm_create_fbid(struct drm_xv *drmxv, struct drm_armada_bo *bo,
handles[2] = bo->handle;
/* Create the framebuffer object for this buffer */
- if (drmModeAddFB2(drmxv->drm->fd, drmxv->width, drmxv->height,
+ if (drmModeAddFB2(drmxv->fd, drmxv->width, drmxv->height,
drmxv->plane_format->drm_format, handles,
drmxv->pitches, drmxv->offsets, id, 0))
return FALSE;
@@ -426,7 +428,7 @@ armada_drm_create_fbid(struct drm_xv *drmxv, struct drm_armada_bo *bo,
static int armada_drm_bufs_alloc(struct drm_xv *drmxv)
{
- struct drm_armada_bufmgr *bufmgr = drmxv->drm->bufmgr;
+ struct drm_armada_bufmgr *bufmgr = drmxv->bufmgr;
uint32_t width = drmxv->width;
uint32_t height = drmxv->image_size / width / 4;
unsigned i;
@@ -505,7 +507,7 @@ armada_drm_get_xvbo(ScrnInfoPtr pScrn, struct drm_xv *drmxv, unsigned char *buf,
uint32_t name = ((uint32_t *)buf)[1];
/* Lookup the bo for the global name */
- bo = drm_armada_bo_create_from_name(drmxv->drm->bufmgr, name);
+ bo = drm_armada_bo_create_from_name(drmxv->bufmgr, name);
if (!bo)
return BadAlloc;
@@ -733,7 +735,7 @@ armada_drm_plane_StopVideo(ScrnInfoPtr pScrn, pointer data, Bool cleanup)
RegionEmpty(&drmxv->clipBoxes);
- ret = drmModeSetPlane(drmxv->drm->fd, drmxv->plane->plane_id,
+ ret = drmModeSetPlane(drmxv->fd, drmxv->plane->plane_id,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
if (ret)
xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -759,7 +761,7 @@ static Bool armada_drm_check_plane(ScrnInfoPtr pScrn, struct drm_xv *drmxv,
return FALSE;
}
- crtc_mask = 1 << armada_crtc(crtc)->num;
+ crtc_mask = 1 << common_crtc(crtc)->num;
plane = drmxv->plane;
if (plane && !(plane->possible_crtcs & crtc_mask)) {
@@ -814,8 +816,8 @@ armada_drm_plane_Put(ScrnInfoPtr pScrn, struct drm_xv *drmxv, uint32_t fb_id,
crtc_y = dst->y1 - crtc->y;
plane = drmxv->plane;
- drmModeSetPlane(drmxv->drm->fd, plane->plane_id,
- armada_crtc(crtc)->mode_crtc->crtc_id, fb_id, 0,
+ drmModeSetPlane(drmxv->fd, plane->plane_id,
+ common_crtc(crtc)->mode_crtc->crtc_id, fb_id, 0,
crtc_x, crtc_y, dst->x2 - dst->x1, dst->y2 - dst->y1,
x1, y1, x2 - x1, y2 - y1);
@@ -859,7 +861,7 @@ static int armada_drm_plane_PutImage(ScrnInfoPtr pScrn,
/* If there was a previous fb, release it. */
if (drmxv->is_bmm &&
drmxv->plane_fb_id && drmxv->plane_fb_id != fb_id) {
- drmModeRmFB(drmxv->drm->fd, drmxv->plane_fb_id);
+ drmModeRmFB(drmxv->fd, drmxv->plane_fb_id);
drmxv->plane_fb_id = 0;
}
@@ -984,7 +986,8 @@ static Bool armada_drm_init_atoms(ScrnInfoPtr pScrn)
Bool armada_drm_XvInit(ScrnInfoPtr pScrn)
{
ScreenPtr scrn = screenInfo.screens[pScrn->scrnIndex];
- struct armada_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct armada_drm_info *arm = GET_ARMADA_DRM_INFO(pScrn);
XF86VideoAdaptorPtr xv[2], plane;
drmModePlaneResPtr res;
struct drm_xv *drmxv;
@@ -1000,11 +1003,12 @@ Bool armada_drm_XvInit(ScrnInfoPtr pScrn)
if (!drmxv)
return FALSE;
- drmxv->drm = drm;
+ drmxv->fd = drm->fd;
+ drmxv->bufmgr = arm->bufmgr;
drmxv->autopaint_colorkey = TRUE;
/* Get the plane resources and the overlay planes */
- res = drmModeGetPlaneResources(drm->fd);
+ res = drmModeGetPlaneResources(drmxv->fd);
if (!res)
goto err_free;
@@ -1014,8 +1018,8 @@ Bool armada_drm_XvInit(ScrnInfoPtr pScrn)
uint32_t plane_id = res->planes[i];
unsigned j;
- drmxv->planes[i] = drmModeGetPlane(drm->fd, plane_id);
- props = drmModeObjectGetProperties(drm->fd, plane_id,
+ drmxv->planes[i] = drmModeGetPlane(drmxv->fd, plane_id);
+ props = drmModeObjectGetProperties(drmxv->fd, plane_id,
DRM_MODE_OBJECT_PLANE);
if (!drmxv->planes[i] || !props) {
drmModeFreePlaneResources(res);
@@ -1026,7 +1030,7 @@ Bool armada_drm_XvInit(ScrnInfoPtr pScrn)
drmModePropertyPtr prop;
unsigned k;
- prop = drmModeGetProperty(drm->fd, props->props[j]);
+ prop = drmModeGetProperty(drmxv->fd, props->props[j]);
if (!prop)
continue;
@@ -1052,7 +1056,7 @@ Bool armada_drm_XvInit(ScrnInfoPtr pScrn)
/* Done with the plane resources */
drmModeFreePlaneResources(res);
- drmIoctl(drm->fd, DRM_IOCTL_ARMADA_OVERLAY_ATTRS, &drmxv->attrs);
+ drmIoctl(drmxv->fd, DRM_IOCTL_ARMADA_OVERLAY_ATTRS, &drmxv->attrs);
if (drmxv->prop_values[PROP_DRM_COLORKEY]) {
drmxv->attrs.color_key = drmxv->prop_values[PROP_DRM_COLORKEY];
armada_drm_old_update_attr(drmxv);
diff --git a/src/common_drm.c b/src/common_drm.c
index ad98db4..0771b49 100644
--- a/src/common_drm.c
+++ b/src/common_drm.c
@@ -29,6 +29,17 @@
#include <libudev.h>
#endif
+enum {
+ OPTION_HW_CURSOR,
+ OPTION_HOTPLUG,
+};
+
+static const OptionInfoRec common_drm_options[] = {
+ { OPTION_HW_CURSOR, "HWcursor", OPTV_BOOLEAN, {0}, FALSE },
+ { OPTION_HOTPLUG, "HotPlug", OPTV_BOOLEAN, {0}, TRUE },
+ { -1, NULL, OPTV_NONE, {0}, FALSE }
+};
+
struct common_drm_property {
drmModePropertyPtr mode_prop;
uint64_t value;
@@ -36,6 +47,16 @@ struct common_drm_property {
Atom *atoms;
};
+struct common_conn_info {
+ int drm_fd;
+ int drm_id;
+ int dpms_mode;
+ int nprops;
+ struct common_drm_property *props;
+ drmModeConnectorPtr mode_output;
+ drmModeEncoderPtr mode_encoder;
+};
+
static void drmmode_ConvertFromKMode(ScrnInfoPtr pScrn,
drmModeModeInfoPtr kmode, DisplayModePtr mode)
{
@@ -63,7 +84,7 @@ static void drmmode_ConvertFromKMode(ScrnInfoPtr pScrn,
}
static drmModePropertyPtr common_drm_conn_find_property(
- struct armada_conn_info *conn, const char *name, uint32_t *blob)
+ struct common_conn_info *conn, const char *name, uint32_t *blob)
{
drmModeConnectorPtr koutput = conn->mode_output;
int i;
@@ -88,7 +109,7 @@ static drmModePropertyPtr common_drm_conn_find_property(
static void common_drm_conn_create_resources(xf86OutputPtr output)
{
- struct armada_conn_info *conn = output->driver_private;
+ struct common_conn_info *conn = output->driver_private;
drmModeConnectorPtr mop = conn->mode_output;
int i, j, n, err;
@@ -195,7 +216,7 @@ static void common_drm_conn_create_resources(xf86OutputPtr output)
static void common_drm_conn_dpms(xf86OutputPtr output, int mode)
{
- struct armada_conn_info *conn = output->driver_private;
+ struct common_conn_info *conn = output->driver_private;
drmModePropertyPtr p = common_drm_conn_find_property(conn, "DPMS", NULL);
if (p) {
@@ -208,7 +229,7 @@ static void common_drm_conn_dpms(xf86OutputPtr output, int mode)
static xf86OutputStatus common_drm_conn_detect(xf86OutputPtr output)
{
- struct armada_conn_info *conn = output->driver_private;
+ struct common_conn_info *conn = output->driver_private;
xf86OutputStatus status = XF86OutputStatusUnknown;
drmModeConnectorPtr koutput;
@@ -241,7 +262,7 @@ common_drm_conn_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
static DisplayModePtr common_drm_conn_get_modes(xf86OutputPtr output)
{
ScrnInfoPtr pScrn = output->scrn;
- struct armada_conn_info *conn = output->driver_private;
+ struct common_conn_info *conn = output->driver_private;
drmModePropertyBlobPtr edid = NULL;
DisplayModePtr modes = NULL;
drmModePropertyPtr p;
@@ -275,7 +296,7 @@ static DisplayModePtr common_drm_conn_get_modes(xf86OutputPtr output)
static Bool common_drm_conn_set_property(xf86OutputPtr output, Atom property,
RRPropertyValuePtr value)
{
- struct armada_conn_info *conn = output->driver_private;
+ struct common_conn_info *conn = output->driver_private;
int i;
for (i = 0; i < conn->nprops; i++) {
@@ -330,7 +351,7 @@ static Bool common_drm_conn_get_property(xf86OutputPtr output, Atom property)
static void common_drm_conn_destroy(xf86OutputPtr output)
{
- struct armada_conn_info *conn = output->driver_private;
+ struct common_conn_info *conn = output->driver_private;
drmModeFreeConnector(conn->mode_output);
drmModeFreeEncoder(conn->mode_encoder);
@@ -364,19 +385,20 @@ static const int subpixel_conv_table[] = {
SubPixelVerticalRGB, SubPixelVerticalBGR, SubPixelNone
};
-void common_drm_conn_init(ScrnInfoPtr pScrn, int fd, uint32_t id)
+static void common_drm_conn_init(ScrnInfoPtr pScrn, uint32_t id)
{
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
drmModeConnectorPtr koutput;
drmModeEncoderPtr kencoder;
xf86OutputPtr output;
- struct armada_conn_info *conn;
+ struct common_conn_info *conn;
char name[32];
- koutput = drmModeGetConnector(fd, id);
+ koutput = drmModeGetConnector(drm->fd, id);
if (!koutput)
return;
- kencoder = drmModeGetEncoder(fd, koutput->encoders[0]);
+ kencoder = drmModeGetEncoder(drm->fd, koutput->encoders[0]);
if (!kencoder) {
drmModeFreeConnector(koutput);
return;
@@ -401,7 +423,7 @@ void common_drm_conn_init(ScrnInfoPtr pScrn, int fd, uint32_t id)
return;
}
- conn->drm_fd = fd;
+ conn->drm_fd = drm->fd;
conn->drm_id = id;
conn->mode_output = koutput;
conn->mode_encoder = kencoder;
@@ -415,3 +437,657 @@ void common_drm_conn_init(ScrnInfoPtr pScrn, int fd, uint32_t id)
output->interlaceAllowed = 1; /* wish there was a way to read that */
output->doubleScanAllowed = 0;
}
+
+/*
+ * CRTC support
+ */
+static void common_drm_reload_hw_cursors(ScrnInfoPtr pScrn)
+{
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+
+ /* Work around stricter checks in X */
+ if (pScrn->pScreen && drm->hw_cursor)
+ xf86_reload_cursors(pScrn->pScreen);
+}
+
+static void drmmode_ConvertToKMode(drmModeModeInfoPtr kmode,
+ DisplayModePtr mode)
+{
+ memset(kmode, 0, sizeof(*kmode));
+
+ kmode->clock = mode->Clock;
+ kmode->hdisplay = mode->HDisplay;
+ kmode->hsync_start = mode->HSyncStart;
+ kmode->hsync_end = mode->HSyncEnd;
+ kmode->htotal = mode->HTotal;
+ kmode->hskew = mode->HSkew;
+ kmode->vdisplay = mode->VDisplay;
+ kmode->vsync_start = mode->VSyncStart;
+ kmode->vsync_end = mode->VSyncEnd;
+ kmode->vtotal = mode->VTotal;
+ kmode->vscan = mode->VScan;
+ kmode->flags = mode->Flags;
+ if (mode->name)
+ strncpy(kmode->name, mode->name, DRM_DISPLAY_MODE_LEN);
+ kmode->name[DRM_DISPLAY_MODE_LEN-1] = 0;
+}
+
+static Bool common_drm_crtc_apply(xf86CrtcPtr crtc, uint32_t front_fb_id)
+{
+ ScrnInfoPtr pScrn = crtc->scrn;
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ struct common_crtc_info *drmc = common_crtc(crtc);
+ drmModeModeInfo kmode;
+ uint32_t fb_id, *output_ids;
+ int x, y, i, ret, output_num;
+
+ output_ids = calloc(xf86_config->num_output, sizeof *output_ids);
+ if (!output_ids)
+ return FALSE;
+
+ for (output_num = i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+ struct common_conn_info *conn;
+
+ if (output->crtc == crtc) {
+ conn = output->driver_private;
+ output_ids[output_num++] = conn->mode_output->connector_id;
+ }
+ }
+
+ if (!xf86CrtcRotate(crtc)) {
+ ret = FALSE;
+ goto done;
+ }
+
+ crtc->funcs->gamma_set(crtc, crtc->gamma_red, crtc->gamma_green,
+ crtc->gamma_blue, crtc->gamma_size);
+
+ if (drmc->rotate_fb_id) {
+ fb_id = drmc->rotate_fb_id;
+ x = y = 0;
+ } else {
+ fb_id = front_fb_id;
+ x = crtc->x;
+ y = crtc->y;
+ }
+
+ drmmode_ConvertToKMode(&kmode, &crtc->mode);
+
+ ret = drmModeSetCrtc(drmc->drm_fd, drmc->mode_crtc->crtc_id, fb_id,
+ x, y, output_ids, output_num, &kmode);
+ if (ret) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to set mode on crtc %u: %s\n",
+ drmc->mode_crtc->crtc_id, strerror(errno));
+ ret = FALSE;
+ } else {
+ ret = TRUE;
+
+ for (i = 0; i < xf86_config->num_output; i++) {
+ xf86OutputPtr output = xf86_config->output[i];
+
+ if (output->crtc != crtc)
+ continue;
+
+ output->funcs->dpms(output, DPMSModeOn);
+ }
+ }
+
+done:
+ free(output_ids);
+ return ret;
+}
+
+void common_drm_crtc_dpms(xf86CrtcPtr crtc, int mode)
+{
+}
+
+Bool common_drm_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+ Rotation rotation, int x, int y)
+{
+ struct common_drm_info *drm = GET_DRM_INFO(crtc->scrn);
+ DisplayModeRec saved_mode;
+ Rotation saved_rotation;
+ int ret, saved_x, saved_y;
+
+ saved_mode = crtc->mode;
+ saved_x = crtc->x;
+ saved_y = crtc->y;
+ saved_rotation = crtc->rotation;
+ crtc->mode = *mode;
+ crtc->x = x;
+ crtc->y = y;
+ crtc->rotation = rotation;
+
+ ret = common_drm_crtc_apply(crtc, drm->fb_id);
+ if (!ret) {
+ crtc->mode = saved_mode;
+ crtc->x = saved_x;
+ crtc->y = saved_y;
+ crtc->rotation = saved_rotation;
+ }
+
+ common_drm_reload_hw_cursors(crtc->scrn);
+
+ return ret;
+}
+
+void common_drm_crtc_resize(ScrnInfoPtr pScrn, int width, int height,
+ int displayWidth, uint32_t fb_id)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ uint32_t old_fb_id;
+ int i;
+
+ pScrn->virtualX = width;
+ pScrn->virtualY = height;
+ pScrn->displayWidth = displayWidth;
+
+ old_fb_id = drm->fb_id;
+ drm->fb_id = fb_id;
+
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+
+ if (!crtc->enabled)
+ continue;
+
+ common_drm_crtc_apply(crtc, fb_id);
+ }
+
+ common_drm_reload_hw_cursors(pScrn);
+
+ drmModeRmFB(drm->fd, old_fb_id);
+}
+
+void common_drm_crtc_gamma_set(xf86CrtcPtr crtc,
+ CARD16 *red, CARD16 *green, CARD16 *blue, int size)
+{
+ struct common_crtc_info *drmc = common_crtc(crtc);
+
+ drmModeCrtcSetGamma(drmc->drm_fd, drmc->mode_crtc->crtc_id,
+ size, red, green, blue);
+}
+
+void common_drm_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y)
+{
+ struct common_crtc_info *drmc = common_crtc(crtc);
+
+ drmModeMoveCursor(drmc->drm_fd, drmc->mode_crtc->crtc_id, x, y);
+}
+
+void common_drm_crtc_show_cursor(xf86CrtcPtr crtc)
+{
+ struct common_drm_info *drm = GET_DRM_INFO(crtc->scrn);
+ struct common_crtc_info *drmc = common_crtc(crtc);
+
+ drmModeSetCursor(drmc->drm_fd, drmc->mode_crtc->crtc_id,
+ drmc->cursor_handle,
+ drm->cursor_max_width, drm->cursor_max_height);
+}
+
+void common_drm_crtc_hide_cursor(xf86CrtcPtr crtc)
+{
+ struct common_crtc_info *drmc = common_crtc(crtc);
+
+ drmModeSetCursor(drmc->drm_fd, drmc->mode_crtc->crtc_id, 0, 0, 0);
+}
+
+static Bool common_drm_crtc_init(ScrnInfoPtr pScrn, unsigned num,
+ const xf86CrtcFuncsRec *funcs)
+{
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct common_crtc_info *drmc;
+ xf86CrtcPtr crtc;
+ uint32_t id;
+
+ id = drm->mode_res->crtcs[num];
+
+ crtc = xf86CrtcCreate(pScrn, funcs);
+ if (!crtc)
+ return FALSE;
+
+ drmc = xnfcalloc(1, sizeof *drmc);
+ drmc->drm_fd = drm->fd;
+ drmc->num = num;
+ drmc->mode_crtc = drmModeGetCrtc(drmc->drm_fd, id);
+ crtc->driver_private = drmc;
+
+ /* Test whether hardware cursor is supported */
+ if (drmModeSetCursor(drmc->drm_fd, id, 0, 0, 0))
+ drm->has_hw_cursor = FALSE;
+
+ return TRUE;
+}
+
+Bool common_drm_init_mode_resources(ScrnInfoPtr pScrn,
+ const xf86CrtcFuncsRec *funcs)
+{
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ Gamma zeros = { 0.0, 0.0, 0.0 };
+ int i;
+
+ drm->mode_res = drmModeGetResources(drm->fd);
+ if (!drm->mode_res) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "failed to get resources: %s\n", strerror(errno));
+ return FALSE;
+ }
+
+ xf86CrtcSetSizeRange(pScrn, drm->mode_res->min_width,
+ drm->mode_res->min_height,
+ drm->mode_res->max_width,
+ drm->mode_res->max_height);
+
+ drm->has_hw_cursor = TRUE;
+ for (i = 0; i < drm->mode_res->count_crtcs; i++)
+ if (!common_drm_crtc_init(pScrn, i, funcs))
+ return FALSE;
+
+ for (i = 0; i < drm->mode_res->count_connectors; i++)
+ common_drm_conn_init(pScrn, drm->mode_res->connectors[i]);
+
+ xf86InitialConfiguration(pScrn, TRUE);
+
+ if (!xf86SetGamma(pScrn, zeros))
+ return FALSE;
+
+ if (pScrn->modes == NULL) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No modes.\n");
+ return FALSE;
+ }
+
+ pScrn->currentMode = pScrn->modes;
+
+ /* Set display resolution */
+ xf86SetDpi(pScrn, 0, 0);
+
+ if (!xf86LoadSubModule(pScrn, "fb"))
+ return FALSE;
+
+ return TRUE;
+}
+
+void common_drm_LoadPalette(ScrnInfoPtr pScrn, int num, int *indices,
+ LOCO *colors, VisualPtr pVisual)
+{
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ uint16_t lut_r[256], lut_g[256], lut_b[256];
+ int i, p;
+
+ for (i = 0; i < num; i++) {
+ int index = indices[i];
+ lut_r[index] = colors[index].red << 8;
+ lut_g[index] = colors[index].green << 8;
+ lut_b[index] = colors[index].blue << 8;
+ }
+
+ for (p = 0; p < xf86_config->num_crtc; p++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[p];
+
+#ifdef RANDR_12_INTERFACE
+ RRCrtcGammaSet(crtc->randr_crtc, lut_r, lut_g, lut_b);
+#else
+ crtc->funcs->gamma_set(crtc, lut_r, lut_g, lut_b, 256);
+#endif
+ }
+}
+
+#ifdef HAVE_UDEV
+static void common_drm_handle_uevent(int fd, pointer data)
+{
+ ScrnInfoPtr pScrn = data;
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ struct udev_device *ud;
+
+ ud = udev_monitor_receive_device(drm->udev.monitor);
+ if (ud) {
+ dev_t dev = udev_device_get_devnum(ud);
+ const char *hp = udev_device_get_property_value(ud, "HOTPLUG");
+
+ if (dev == drm->udev.drm_dev && hp && strtol(hp, NULL, 10) == 1)
+ RRGetInfo(screenInfo.screens[pScrn->scrnIndex], TRUE);
+
+ udev_device_unref(ud);
+ }
+}
+
+static Bool common_drm_udev_CloseScreen(CLOSE_SCREEN_ARGS_DECL)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+
+ if (drm->udev.monitor) {
+ struct udev *udev = udev_monitor_get_udev(drm->udev.monitor);
+
+ xf86RemoveGeneralHandler(drm->udev.handler);
+ udev_monitor_unref(drm->udev.monitor);
+ udev_unref(udev);
+ }
+
+ pScreen->CloseScreen = drm->udev.CloseScreen;
+
+ return pScreen->CloseScreen(CLOSE_SCREEN_ARGS);
+}
+
+static Bool common_drm_udev_init(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ MessageType from = X_CONFIG;
+ struct udev_monitor *udev_mon;
+ struct udev *udev;
+ struct stat st;
+ Bool hotplug;
+
+ if (!xf86GetOptValBool(drm->Options, OPTION_HOTPLUG, &hotplug)) {
+ from = X_DEFAULT;
+ hotplug = TRUE;
+ }
+
+ xf86DrvMsg(pScrn->scrnIndex, from, "hotplug detection %sabled\n",
+ hotplug ? "en" : "dis");
+ if (!hotplug)
+ return TRUE;
+
+ if (fstat(drm->fd, &st) || !S_ISCHR(st.st_mode))
+ return FALSE;
+
+ drm->udev.drm_dev = st.st_rdev;
+
+ udev = udev_new();
+ if (!udev)
+ return FALSE;
+
+ udev_mon = udev_monitor_new_from_netlink(udev, "udev");
+ if (!udev_mon) {
+ udev_unref(udev);
+ return FALSE;
+ }
+
+ if (udev_monitor_filter_add_match_subsystem_devtype(udev_mon,
+ "drm", "drm_minor") ||
+ udev_monitor_enable_receiving(udev_mon)) {
+ udev_monitor_unref(udev_mon);
+ udev_unref(udev);
+ return FALSE;
+ }
+
+ drm->udev.monitor = udev_mon;
+ drm->udev.handler = xf86AddGeneralHandler(udev_monitor_get_fd(udev_mon),
+ common_drm_handle_uevent,
+ pScrn);
+
+ drm->udev.CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = common_drm_udev_CloseScreen;
+
+ return TRUE;
+}
+#endif
+
+static Bool common_drm_CloseScreen(CLOSE_SCREEN_ARGS_DECL)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ Bool ret;
+
+ if (drm->fb_id) {
+ drmModeRmFB(drm->fd, drm->fb_id);
+ drm->fb_id = 0;
+ }
+
+ if (drm->hw_cursor)
+ xf86_cursors_fini(pScreen);
+
+ pScreen->CloseScreen = drm->CloseScreen;
+ ret = (*pScreen->CloseScreen)(CLOSE_SCREEN_ARGS);
+
+ if (pScrn->vtSema)
+ common_drm_LeaveVT(VT_FUNC_ARGS(0));
+
+ pScrn->vtSema = FALSE;
+
+ return ret;
+}
+
+Bool common_drm_PreScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ int visuals, preferredCVC;
+
+ drm->Options = xnfalloc(sizeof(common_drm_options));
+ memcpy(drm->Options, common_drm_options, sizeof(common_drm_options));
+ xf86ProcessOptions(pScrn->scrnIndex, pScrn->options, drm->Options);
+
+ miClearVisualTypes();
+ if (pScrn->bitsPerPixel > 8) {
+ visuals = TrueColorMask;
+ preferredCVC = TrueColor;
+ } else {
+ visuals = miGetDefaultVisualMask(pScrn->depth);
+ preferredCVC = pScrn->defaultVisual;
+ }
+
+ if (!miSetVisualTypes(pScrn->depth, visuals, pScrn->rgbBits, preferredCVC)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to set visual types for %d bpp depth %d\n",
+ pScrn->bitsPerPixel, pScrn->depth);
+ return FALSE;
+ }
+
+ if (!miSetPixmapDepths()) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to set pixmap depths\n");
+ return FALSE;
+ }
+
+ if (!fbScreenInit(pScreen, NULL, pScrn->virtualX, pScrn->virtualY,
+ pScrn->xDpi, pScrn->yDpi, pScrn->displayWidth,
+ pScrn->bitsPerPixel)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] fbScreenInit failed\n");
+ return FALSE;
+ }
+
+ if (pScrn->bitsPerPixel > 8) {
+ /* Fixup RGB ordering */
+ VisualPtr visual = pScreen->visuals + pScreen->numVisuals;
+ while (--visual >= pScreen->visuals) {
+ if ((visual->class | DynamicClass) == DirectColor) {
+ visual->offsetRed = pScrn->offset.red;
+ visual->offsetGreen = pScrn->offset.green;
+ visual->offsetBlue = pScrn->offset.blue;
+ visual->redMask = pScrn->mask.red;
+ visual->greenMask = pScrn->mask.green;
+ visual->blueMask = pScrn->mask.blue;
+ }
+ }
+ }
+
+ if (!fbPictureInit(pScreen, NULL, 0)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] fbPictureInit failed\n");
+ return FALSE;
+ }
+
+ xf86SetBlackWhitePixels(pScreen);
+
+ xf86SetBackingStore(pScreen);
+ xf86SetSilkenMouse(pScreen);
+
+ drm->CloseScreen = pScreen->CloseScreen;
+ pScreen->CloseScreen = common_drm_CloseScreen;
+
+ return TRUE;
+}
+
+static void common_drm_wakeup_handler(pointer data, int err, pointer p)
+{
+ struct common_drm_info *drm = data;
+ fd_set *read_mask = p;
+
+ if (data == NULL || err < 0)
+ return;
+
+ if (FD_ISSET(drm->fd, read_mask))
+ drmHandleEvent(drm->fd, &drm->event_context);
+}
+
+Bool common_drm_PostScreenInit(ScreenPtr pScreen)
+{
+ ScrnInfoPtr pScrn = xf86ScreenToScrn(pScreen);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+
+ pScreen->SaveScreen = xf86SaveScreen;
+
+ /* software cursor */
+ miDCInitialize(pScreen, xf86GetPointerScreenFuncs());
+
+ drm->hw_cursor = xf86ReturnOptValBool(drm->Options,
+ OPTION_HW_CURSOR,
+ drm->has_hw_cursor);
+ if (drm->hw_cursor && !drm->has_hw_cursor) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "No hardware cursor support - disabling hardware cursors\n");
+ drm->hw_cursor = FALSE;
+ }
+ if (drm->hw_cursor &&
+ xf86_cursors_init(pScreen,
+ drm->cursor_max_width, drm->cursor_max_height,
+ HARDWARE_CURSOR_TRUECOLOR_AT_8BPP |
+ HARDWARE_CURSOR_BIT_ORDER_MSBFIRST |
+ HARDWARE_CURSOR_INVERT_MASK |
+ HARDWARE_CURSOR_SWAP_SOURCE_AND_MASK |
+ HARDWARE_CURSOR_AND_SOURCE_WITH_MASK |
+ HARDWARE_CURSOR_SOURCE_MASK_INTERLEAVE_64 |
+ HARDWARE_CURSOR_UPDATE_UNHIDDEN |
+ HARDWARE_CURSOR_ARGB)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_INFO,
+ "Using hardware cursors\n");
+ } else {
+ drm->hw_cursor = FALSE;
+ }
+
+ if (!xf86CrtcScreenInit(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to initialize screen\n");
+ return FALSE;
+ }
+
+ if (!miCreateDefColormap(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to initialize default colormap\n");
+ return FALSE;
+ }
+
+ if (!xf86HandleColormaps(pScreen, 256, 8, common_drm_LoadPalette, NULL,
+ CMAP_RELOAD_ON_MODE_SWITCH |
+ CMAP_PALETTED_TRUECOLOR)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to initialize colormap handler\n");
+ return FALSE;
+ }
+
+ xf86DPMSInit(pScreen, xf86DPMSSet, 0);
+
+ /* Setup the synchronisation feedback */
+ AddGeneralSocket(drm->fd);
+ RegisterBlockAndWakeupHandlers((BlockHandlerProcPtr)NoopDDA,
+ common_drm_wakeup_handler, drm);
+
+#ifdef HAVE_UDEV
+ if (!common_drm_udev_init(pScreen)) {
+ xf86DrvMsg(pScrn->scrnIndex, X_ERROR,
+ "[drm] failed to connect with udev: %s\n",
+ strerror(errno));
+ return FALSE;
+ }
+#endif
+
+ return TRUE;
+}
+
+Bool common_drm_SwitchMode(SWITCH_MODE_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+
+ return xf86SetSingleMode(pScrn, mode, RR_Rotate_0);
+}
+
+void common_drm_AdjustFrame(ADJUST_FRAME_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ xf86OutputPtr output = xf86_config->output[xf86_config->compat_output];
+ xf86CrtcPtr crtc = output->crtc;
+
+ if (crtc && crtc->enabled) {
+ int saved_x = crtc->x;
+ int saved_y = crtc->y;
+ int ret;
+
+ crtc->x = x;
+ crtc->y = y;
+
+ ret = crtc->funcs->set_mode_major(crtc, &crtc->mode,
+ crtc->rotation, x, y);
+ if (!ret) {
+ crtc->x = saved_x;
+ crtc->y = saved_y;
+ }
+ }
+}
+
+Bool common_drm_EnterVT(VT_FUNC_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+ xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);
+ int i;
+
+ if (drmSetMaster(drm->fd))
+ xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
+ "[drm] set master failed: %s\n", strerror(errno));
+
+ if (!xf86SetDesiredModes(pScrn))
+ return FALSE;
+
+ /* Disable unused CRTCs */
+ for (i = 0; i < xf86_config->num_crtc; i++) {
+ xf86CrtcPtr crtc = xf86_config->crtc[i];
+ struct common_crtc_info *drmc = common_crtc(crtc);
+
+ if (!crtc->enabled)
+ drmModeSetCrtc(drmc->drm_fd, drmc->mode_crtc->crtc_id,
+ 0, 0, 0, NULL, 0, NULL);
+ }
+
+ return TRUE;
+}
+
+void common_drm_LeaveVT(VT_FUNC_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+
+ xf86RotateFreeShadow(pScrn);
+
+ xf86_hide_cursors(pScrn);
+
+ drmDropMaster(drm->fd);
+}
+
+void common_drm_FreeScreen(FREE_SCREEN_ARGS_DECL)
+{
+ SCRN_INFO_PTR(arg);
+ struct common_drm_info *drm = GET_DRM_INFO(pScrn);
+
+ if (drm) {
+ drmClose(drm->fd);
+ SET_DRM_INFO(pScrn, NULL);
+ free(drm);
+ }
+}
diff --git a/src/common_drm.h b/src/common_drm.h
index a23cd6e..b0c3cd4 100644
--- a/src/common_drm.h
+++ b/src/common_drm.h
@@ -1,18 +1,74 @@
#ifndef COMMON_DRM_H
#define COMMON_DRM_H
-struct common_drm_property;
+#include "compat-api.h"
+#include "xf86Crtc.h"
-struct armada_conn_info {
+struct common_crtc_info {
int drm_fd;
- int drm_id;
- int dpms_mode;
- int nprops;
- struct common_drm_property *props;
- drmModeConnectorPtr mode_output;
- drmModeEncoderPtr mode_encoder;
+ unsigned num;
+ drmModeCrtcPtr mode_crtc;
+ void *cursor_data;
+ uint32_t cursor_handle;
+ uint32_t rotate_fb_id;
};
+#define common_crtc(crtc) \
+ ((struct common_crtc_info *)(crtc)->driver_private)
-void common_drm_conn_init(ScrnInfoPtr pScrn, int fd, uint32_t id);
+struct drm_udev_info {
+ struct udev_monitor *monitor;
+ pointer *handler;
+ dev_t drm_dev;
+ CloseScreenProcPtr CloseScreen;
+};
+
+struct common_drm_info {
+ int fd;
+ drmEventContext event_context;
+ uint32_t fb_id;
+ drmModeResPtr mode_res;
+
+ Bool has_hw_cursor;
+ Bool hw_cursor;
+ unsigned short cursor_max_width;
+ unsigned short cursor_max_height;
+
+#ifdef HAVE_UDEV
+ struct drm_udev_info udev;
+#endif
+
+ OptionInfoPtr Options;
+ CloseScreenProcPtr CloseScreen;
+
+ void *private;
+};
+
+#define GET_DRM_INFO(pScrn) ((struct common_drm_info *)(pScrn)->driverPrivate)
+#define SET_DRM_INFO(pScrn, ptr) ((pScrn)->driverPrivate = (ptr))
+
+void common_drm_crtc_dpms(xf86CrtcPtr crtc, int mode);
+Bool common_drm_crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
+ Rotation rotation, int x, int y);
+void common_drm_crtc_resize(ScrnInfoPtr pScrn, int width, int height,
+ int displayWidth, uint32_t fb_id);
+void common_drm_crtc_gamma_set(xf86CrtcPtr crtc,
+ CARD16 *red, CARD16 *green, CARD16 *blue, int size);
+void common_drm_crtc_set_cursor_position(xf86CrtcPtr crtc, int x, int y);
+void common_drm_crtc_show_cursor(xf86CrtcPtr crtc);
+void common_drm_crtc_hide_cursor(xf86CrtcPtr crtc);
+
+Bool common_drm_init_mode_resources(ScrnInfoPtr pScrn,
+ const xf86CrtcFuncsRec *funcs);
+
+void common_drm_LoadPalette(ScrnInfoPtr pScrn, int num, int *indices,
+ LOCO *colors, VisualPtr pVisual);
+Bool common_drm_PreScreenInit(ScreenPtr pScreen);
+Bool common_drm_PostScreenInit(ScreenPtr pScreen);
+Bool common_drm_SwitchMode(SWITCH_MODE_ARGS_DECL);
+void common_drm_AdjustFrame(ADJUST_FRAME_ARGS_DECL);
+Bool common_drm_EnterVT(VT_FUNC_ARGS_DECL);
+void common_drm_LeaveVT(VT_FUNC_ARGS_DECL);
+
+void common_drm_FreeScreen(FREE_SCREEN_ARGS_DECL);
#endif
diff --git a/src/vivante_utils.h b/src/vivante_utils.h
index e7bd2d4..da8ef2c 100644
--- a/src/vivante_utils.h
+++ b/src/vivante_utils.h
@@ -10,6 +10,7 @@
/* Needed for gcsRECT */
#include <gc_hal_base.h>
+struct drm_armada_bo;
struct vivante;
struct vivante_pixmap;