summaryrefslogtreecommitdiffstats
path: root/src/armada_drm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/armada_drm.c')
-rw-r--r--src/armada_drm.c839
1 files changed, 151 insertions, 688 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;