linux/drivers/staging/vboxvideo/vbox_mode.c
<<
>>
Prefs
   1/*
   2 * Copyright (C) 2013-2017 Oracle Corporation
   3 * This file is based on ast_mode.c
   4 * Copyright 2012 Red Hat Inc.
   5 * Parts based on xf86-video-ast
   6 * Copyright (c) 2005 ASPEED Technology Inc.
   7 *
   8 * Permission is hereby granted, free of charge, to any person obtaining a
   9 * copy of this software and associated documentation files (the
  10 * "Software"), to deal in the Software without restriction, including
  11 * without limitation the rights to use, copy, modify, merge, publish,
  12 * distribute, sub license, and/or sell copies of the Software, and to
  13 * permit persons to whom the Software is furnished to do so, subject to
  14 * the following conditions:
  15 *
  16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
  19 * THE COPYRIGHT HOLDERS, AUTHORS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM,
  20 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
  21 * OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
  22 * USE OR OTHER DEALINGS IN THE SOFTWARE.
  23 *
  24 * The above copyright notice and this permission notice (including the
  25 * next paragraph) shall be included in all copies or substantial portions
  26 * of the Software.
  27 *
  28 */
  29/*
  30 * Authors: Dave Airlie <airlied@redhat.com>
  31 *          Michael Thayer <michael.thayer@oracle.com,
  32 *          Hans de Goede <hdegoede@redhat.com>
  33 */
  34#include <linux/export.h>
  35#include <drm/drm_crtc_helper.h>
  36#include <drm/drm_plane_helper.h>
  37
  38#include "vbox_drv.h"
  39#include "vboxvideo.h"
  40#include "hgsmi_channels.h"
  41
  42static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
  43                            u32 handle, u32 width, u32 height,
  44                            s32 hot_x, s32 hot_y);
  45static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y);
  46
  47/**
  48 * Set a graphics mode.  Poke any required values into registers, do an HGSMI
  49 * mode set and tell the host we support advanced graphics functions.
  50 */
  51static void vbox_do_modeset(struct drm_crtc *crtc,
  52                            const struct drm_display_mode *mode)
  53{
  54        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
  55        struct vbox_private *vbox;
  56        int width, height, bpp, pitch;
  57        u16 flags;
  58        s32 x_offset, y_offset;
  59
  60        vbox = crtc->dev->dev_private;
  61        width = mode->hdisplay ? mode->hdisplay : 640;
  62        height = mode->vdisplay ? mode->vdisplay : 480;
  63        bpp = crtc->enabled ? CRTC_FB(crtc)->format->cpp[0] * 8 : 32;
  64        pitch = crtc->enabled ? CRTC_FB(crtc)->pitches[0] : width * bpp / 8;
  65        x_offset = vbox->single_framebuffer ? crtc->x : vbox_crtc->x_hint;
  66        y_offset = vbox->single_framebuffer ? crtc->y : vbox_crtc->y_hint;
  67
  68        /*
  69         * This is the old way of setting graphics modes.  It assumed one screen
  70         * and a frame-buffer at the start of video RAM.  On older versions of
  71         * VirtualBox, certain parts of the code still assume that the first
  72         * screen is programmed this way, so try to fake it.
  73         */
  74        if (vbox_crtc->crtc_id == 0 && crtc->enabled &&
  75            vbox_crtc->fb_offset / pitch < 0xffff - crtc->y &&
  76            vbox_crtc->fb_offset % (bpp / 8) == 0) {
  77                vbox_write_ioport(VBE_DISPI_INDEX_XRES, width);
  78                vbox_write_ioport(VBE_DISPI_INDEX_YRES, height);
  79                vbox_write_ioport(VBE_DISPI_INDEX_VIRT_WIDTH, pitch * 8 / bpp);
  80                vbox_write_ioport(VBE_DISPI_INDEX_BPP,
  81                                  CRTC_FB(crtc)->format->cpp[0] * 8);
  82                vbox_write_ioport(VBE_DISPI_INDEX_ENABLE, VBE_DISPI_ENABLED);
  83                vbox_write_ioport(
  84                        VBE_DISPI_INDEX_X_OFFSET,
  85                        vbox_crtc->fb_offset % pitch / bpp * 8 + crtc->x);
  86                vbox_write_ioport(VBE_DISPI_INDEX_Y_OFFSET,
  87                                  vbox_crtc->fb_offset / pitch + crtc->y);
  88        }
  89
  90        flags = VBVA_SCREEN_F_ACTIVE;
  91        flags |= (crtc->enabled && !vbox_crtc->blanked) ?
  92                 0 : VBVA_SCREEN_F_BLANK;
  93        flags |= vbox_crtc->disconnected ? VBVA_SCREEN_F_DISABLED : 0;
  94        hgsmi_process_display_info(vbox->guest_pool, vbox_crtc->crtc_id,
  95                                   x_offset, y_offset,
  96                                   crtc->x * bpp / 8 + crtc->y * pitch,
  97                                   pitch, width, height,
  98                                   vbox_crtc->blanked ? 0 : bpp, flags);
  99}
 100
 101static int vbox_set_view(struct drm_crtc *crtc)
 102{
 103        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
 104        struct vbox_private *vbox = crtc->dev->dev_private;
 105        struct vbva_infoview *p;
 106
 107        /*
 108         * Tell the host about the view.  This design originally targeted the
 109         * Windows XP driver architecture and assumed that each screen would
 110         * have a dedicated frame buffer with the command buffer following it,
 111         * the whole being a "view".  The host works out which screen a command
 112         * buffer belongs to by checking whether it is in the first view, then
 113         * whether it is in the second and so on.  The first match wins.  We
 114         * cheat around this by making the first view be the managed memory
 115         * plus the first command buffer, the second the same plus the second
 116         * buffer and so on.
 117         */
 118        p = hgsmi_buffer_alloc(vbox->guest_pool, sizeof(*p),
 119                               HGSMI_CH_VBVA, VBVA_INFO_VIEW);
 120        if (!p)
 121                return -ENOMEM;
 122
 123        p->view_index = vbox_crtc->crtc_id;
 124        p->view_offset = vbox_crtc->fb_offset;
 125        p->view_size = vbox->available_vram_size - vbox_crtc->fb_offset +
 126                       vbox_crtc->crtc_id * VBVA_MIN_BUFFER_SIZE;
 127        p->max_screen_size = vbox->available_vram_size - vbox_crtc->fb_offset;
 128
 129        hgsmi_buffer_submit(vbox->guest_pool, p);
 130        hgsmi_buffer_free(vbox->guest_pool, p);
 131
 132        return 0;
 133}
 134
 135static void vbox_crtc_dpms(struct drm_crtc *crtc, int mode)
 136{
 137        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
 138        struct vbox_private *vbox = crtc->dev->dev_private;
 139
 140        switch (mode) {
 141        case DRM_MODE_DPMS_ON:
 142                vbox_crtc->blanked = false;
 143                break;
 144        case DRM_MODE_DPMS_STANDBY:
 145        case DRM_MODE_DPMS_SUSPEND:
 146        case DRM_MODE_DPMS_OFF:
 147                vbox_crtc->blanked = true;
 148                break;
 149        }
 150
 151        mutex_lock(&vbox->hw_mutex);
 152        vbox_do_modeset(crtc, &crtc->hwmode);
 153        mutex_unlock(&vbox->hw_mutex);
 154}
 155
 156static bool vbox_crtc_mode_fixup(struct drm_crtc *crtc,
 157                                 const struct drm_display_mode *mode,
 158                                 struct drm_display_mode *adjusted_mode)
 159{
 160        return true;
 161}
 162
 163/*
 164 * Try to map the layout of virtual screens to the range of the input device.
 165 * Return true if we need to re-set the crtc modes due to screen offset
 166 * changes.
 167 */
 168static bool vbox_set_up_input_mapping(struct vbox_private *vbox)
 169{
 170        struct drm_crtc *crtci;
 171        struct drm_connector *connectori;
 172        struct drm_framebuffer *fb1 = NULL;
 173        bool single_framebuffer = true;
 174        bool old_single_framebuffer = vbox->single_framebuffer;
 175        u16 width = 0, height = 0;
 176
 177        /*
 178         * Are we using an X.Org-style single large frame-buffer for all crtcs?
 179         * If so then screen layout can be deduced from the crtc offsets.
 180         * Same fall-back if this is the fbdev frame-buffer.
 181         */
 182        list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list, head) {
 183                if (!fb1) {
 184                        fb1 = CRTC_FB(crtci);
 185                        if (to_vbox_framebuffer(fb1) == &vbox->fbdev->afb)
 186                                break;
 187                } else if (CRTC_FB(crtci) && fb1 != CRTC_FB(crtci)) {
 188                        single_framebuffer = false;
 189                }
 190        }
 191        if (single_framebuffer) {
 192                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
 193                                    head) {
 194                        if (to_vbox_crtc(crtci)->crtc_id != 0)
 195                                continue;
 196
 197                        vbox->single_framebuffer = true;
 198                        vbox->input_mapping_width = CRTC_FB(crtci)->width;
 199                        vbox->input_mapping_height = CRTC_FB(crtci)->height;
 200                        return old_single_framebuffer !=
 201                               vbox->single_framebuffer;
 202                }
 203        }
 204        /* Otherwise calculate the total span of all screens. */
 205        list_for_each_entry(connectori, &vbox->dev->mode_config.connector_list,
 206                            head) {
 207                struct vbox_connector *vbox_connector =
 208                    to_vbox_connector(connectori);
 209                struct vbox_crtc *vbox_crtc = vbox_connector->vbox_crtc;
 210
 211                width = max_t(u16, width, vbox_crtc->x_hint +
 212                                          vbox_connector->mode_hint.width);
 213                height = max_t(u16, height, vbox_crtc->y_hint +
 214                                            vbox_connector->mode_hint.height);
 215        }
 216
 217        vbox->single_framebuffer = false;
 218        vbox->input_mapping_width = width;
 219        vbox->input_mapping_height = height;
 220
 221        return old_single_framebuffer != vbox->single_framebuffer;
 222}
 223
 224static int vbox_crtc_do_set_base(struct drm_crtc *crtc,
 225                                 struct drm_framebuffer *old_fb, int x, int y)
 226{
 227        struct vbox_private *vbox = crtc->dev->dev_private;
 228        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
 229        struct drm_gem_object *obj;
 230        struct vbox_framebuffer *vbox_fb;
 231        struct vbox_bo *bo;
 232        int ret;
 233        u64 gpu_addr;
 234
 235        /* Unpin the previous fb. */
 236        if (old_fb) {
 237                vbox_fb = to_vbox_framebuffer(old_fb);
 238                obj = vbox_fb->obj;
 239                bo = gem_to_vbox_bo(obj);
 240                ret = vbox_bo_reserve(bo, false);
 241                if (ret)
 242                        return ret;
 243
 244                vbox_bo_unpin(bo);
 245                vbox_bo_unreserve(bo);
 246        }
 247
 248        vbox_fb = to_vbox_framebuffer(CRTC_FB(crtc));
 249        obj = vbox_fb->obj;
 250        bo = gem_to_vbox_bo(obj);
 251
 252        ret = vbox_bo_reserve(bo, false);
 253        if (ret)
 254                return ret;
 255
 256        ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
 257        if (ret) {
 258                vbox_bo_unreserve(bo);
 259                return ret;
 260        }
 261
 262        if (&vbox->fbdev->afb == vbox_fb)
 263                vbox_fbdev_set_base(vbox, gpu_addr);
 264        vbox_bo_unreserve(bo);
 265
 266        /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */
 267        vbox_crtc->fb_offset = gpu_addr;
 268        if (vbox_set_up_input_mapping(vbox)) {
 269                struct drm_crtc *crtci;
 270
 271                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
 272                                    head) {
 273                        vbox_set_view(crtc);
 274                        vbox_do_modeset(crtci, &crtci->mode);
 275                }
 276        }
 277
 278        return 0;
 279}
 280
 281static int vbox_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 282                                   struct drm_framebuffer *old_fb)
 283{
 284        return vbox_crtc_do_set_base(crtc, old_fb, x, y);
 285}
 286
 287static int vbox_crtc_mode_set(struct drm_crtc *crtc,
 288                              struct drm_display_mode *mode,
 289                              struct drm_display_mode *adjusted_mode,
 290                              int x, int y, struct drm_framebuffer *old_fb)
 291{
 292        struct vbox_private *vbox = crtc->dev->dev_private;
 293        int ret;
 294
 295        vbox_crtc_mode_set_base(crtc, x, y, old_fb);
 296
 297        mutex_lock(&vbox->hw_mutex);
 298        ret = vbox_set_view(crtc);
 299        if (!ret)
 300                vbox_do_modeset(crtc, mode);
 301        hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
 302                                   vbox->input_mapping_width,
 303                                   vbox->input_mapping_height);
 304        mutex_unlock(&vbox->hw_mutex);
 305
 306        return ret;
 307}
 308
 309static void vbox_crtc_disable(struct drm_crtc *crtc)
 310{
 311}
 312
 313static void vbox_crtc_prepare(struct drm_crtc *crtc)
 314{
 315}
 316
 317static void vbox_crtc_commit(struct drm_crtc *crtc)
 318{
 319}
 320
 321static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
 322        .dpms = vbox_crtc_dpms,
 323        .mode_fixup = vbox_crtc_mode_fixup,
 324        .mode_set = vbox_crtc_mode_set,
 325        /* .mode_set_base = vbox_crtc_mode_set_base, */
 326        .disable = vbox_crtc_disable,
 327        .prepare = vbox_crtc_prepare,
 328        .commit = vbox_crtc_commit,
 329};
 330
 331static void vbox_crtc_reset(struct drm_crtc *crtc)
 332{
 333}
 334
 335static void vbox_crtc_destroy(struct drm_crtc *crtc)
 336{
 337        drm_crtc_cleanup(crtc);
 338        kfree(crtc);
 339}
 340
 341static const struct drm_crtc_funcs vbox_crtc_funcs = {
 342        .cursor_move = vbox_cursor_move,
 343        .cursor_set2 = vbox_cursor_set2,
 344        .reset = vbox_crtc_reset,
 345        .set_config = drm_crtc_helper_set_config,
 346        /* .gamma_set = vbox_crtc_gamma_set, */
 347        .destroy = vbox_crtc_destroy,
 348};
 349
 350static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i)
 351{
 352        struct vbox_crtc *vbox_crtc;
 353
 354        vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL);
 355        if (!vbox_crtc)
 356                return NULL;
 357
 358        vbox_crtc->crtc_id = i;
 359
 360        drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs);
 361        drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256);
 362        drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
 363
 364        return vbox_crtc;
 365}
 366
 367static void vbox_encoder_destroy(struct drm_encoder *encoder)
 368{
 369        drm_encoder_cleanup(encoder);
 370        kfree(encoder);
 371}
 372
 373static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
 374                                                    *connector)
 375{
 376        int enc_id = connector->encoder_ids[0];
 377
 378        /* pick the encoder ids */
 379        if (enc_id)
 380                return drm_encoder_find(connector->dev, NULL, enc_id);
 381
 382        return NULL;
 383}
 384
 385static const struct drm_encoder_funcs vbox_enc_funcs = {
 386        .destroy = vbox_encoder_destroy,
 387};
 388
 389static void vbox_encoder_dpms(struct drm_encoder *encoder, int mode)
 390{
 391}
 392
 393static bool vbox_mode_fixup(struct drm_encoder *encoder,
 394                            const struct drm_display_mode *mode,
 395                            struct drm_display_mode *adjusted_mode)
 396{
 397        return true;
 398}
 399
 400static void vbox_encoder_mode_set(struct drm_encoder *encoder,
 401                                  struct drm_display_mode *mode,
 402                                  struct drm_display_mode *adjusted_mode)
 403{
 404}
 405
 406static void vbox_encoder_prepare(struct drm_encoder *encoder)
 407{
 408}
 409
 410static void vbox_encoder_commit(struct drm_encoder *encoder)
 411{
 412}
 413
 414static const struct drm_encoder_helper_funcs vbox_enc_helper_funcs = {
 415        .dpms = vbox_encoder_dpms,
 416        .mode_fixup = vbox_mode_fixup,
 417        .prepare = vbox_encoder_prepare,
 418        .commit = vbox_encoder_commit,
 419        .mode_set = vbox_encoder_mode_set,
 420};
 421
 422static struct drm_encoder *vbox_encoder_init(struct drm_device *dev,
 423                                             unsigned int i)
 424{
 425        struct vbox_encoder *vbox_encoder;
 426
 427        vbox_encoder = kzalloc(sizeof(*vbox_encoder), GFP_KERNEL);
 428        if (!vbox_encoder)
 429                return NULL;
 430
 431        drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
 432                         DRM_MODE_ENCODER_DAC, NULL);
 433        drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
 434
 435        vbox_encoder->base.possible_crtcs = 1 << i;
 436        return &vbox_encoder->base;
 437}
 438
 439/**
 440 * Generate EDID data with a mode-unique serial number for the virtual
 441 *  monitor to try to persuade Unity that different modes correspond to
 442 *  different monitors and it should not try to force the same resolution on
 443 *  them.
 444 */
 445static void vbox_set_edid(struct drm_connector *connector, int width,
 446                          int height)
 447{
 448        enum { EDID_SIZE = 128 };
 449        unsigned char edid[EDID_SIZE] = {
 450                0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
 451                0x58, 0x58,     /* manufacturer (VBX) */
 452                0x00, 0x00,     /* product code */
 453                0x00, 0x00, 0x00, 0x00, /* serial number goes here */
 454                0x01,           /* week of manufacture */
 455                0x00,           /* year of manufacture */
 456                0x01, 0x03,     /* EDID version */
 457                0x80,           /* capabilities - digital */
 458                0x00,           /* horiz. res in cm, zero for projectors */
 459                0x00,           /* vert. res in cm */
 460                0x78,           /* display gamma (120 == 2.2). */
 461                0xEE,           /* features (standby, suspend, off, RGB, std */
 462                                /* colour space, preferred timing mode) */
 463                0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
 464                /* chromaticity for standard colour space. */
 465                0x00, 0x00, 0x00,       /* no default timings */
 466                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 467                    0x01, 0x01,
 468                0x01, 0x01, 0x01, 0x01, /* no standard timings */
 469                0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x02, 0x02,
 470                    0x02, 0x02,
 471                /* descriptor block 1 goes below */
 472                0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 473                /* descriptor block 2, monitor ranges */
 474                0x00, 0x00, 0x00, 0xFD, 0x00,
 475                0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20,
 476                    0x20, 0x20,
 477                /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
 478                0x20,
 479                /* descriptor block 3, monitor name */
 480                0x00, 0x00, 0x00, 0xFC, 0x00,
 481                'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r',
 482                '\n',
 483                /* descriptor block 4: dummy data */
 484                0x00, 0x00, 0x00, 0x10, 0x00,
 485                0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
 486                0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 487                0x20,
 488                0x00,           /* number of extensions */
 489                0x00            /* checksum goes here */
 490        };
 491        int clock = (width + 6) * (height + 6) * 60 / 10000;
 492        unsigned int i, sum = 0;
 493
 494        edid[12] = width & 0xff;
 495        edid[13] = width >> 8;
 496        edid[14] = height & 0xff;
 497        edid[15] = height >> 8;
 498        edid[54] = clock & 0xff;
 499        edid[55] = clock >> 8;
 500        edid[56] = width & 0xff;
 501        edid[58] = (width >> 4) & 0xf0;
 502        edid[59] = height & 0xff;
 503        edid[61] = (height >> 4) & 0xf0;
 504        for (i = 0; i < EDID_SIZE - 1; ++i)
 505                sum += edid[i];
 506        edid[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF;
 507        drm_mode_connector_update_edid_property(connector, (struct edid *)edid);
 508}
 509
 510static int vbox_get_modes(struct drm_connector *connector)
 511{
 512        struct vbox_connector *vbox_connector = NULL;
 513        struct drm_display_mode *mode = NULL;
 514        struct vbox_private *vbox = NULL;
 515        unsigned int num_modes = 0;
 516        int preferred_width, preferred_height;
 517
 518        vbox_connector = to_vbox_connector(connector);
 519        vbox = connector->dev->dev_private;
 520        /*
 521         * Heuristic: we do not want to tell the host that we support dynamic
 522         * resizing unless we feel confident that the user space client using
 523         * the video driver can handle hot-plug events.  So the first time modes
 524         * are queried after a "master" switch we tell the host that we do not,
 525         * and immediately after we send the client a hot-plug notification as
 526         * a test to see if they will respond and query again.
 527         * That is also the reason why capabilities are reported to the host at
 528         * this place in the code rather than elsewhere.
 529         * We need to report the flags location before reporting the IRQ
 530         * capability.
 531         */
 532        hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) +
 533                                    HOST_FLAGS_OFFSET);
 534        if (vbox_connector->vbox_crtc->crtc_id == 0)
 535                vbox_report_caps(vbox);
 536        if (!vbox->initial_mode_queried) {
 537                if (vbox_connector->vbox_crtc->crtc_id == 0) {
 538                        vbox->initial_mode_queried = true;
 539                        vbox_report_hotplug(vbox);
 540                }
 541                return drm_add_modes_noedid(connector, 800, 600);
 542        }
 543        num_modes = drm_add_modes_noedid(connector, 2560, 1600);
 544        preferred_width = vbox_connector->mode_hint.width ?
 545                          vbox_connector->mode_hint.width : 1024;
 546        preferred_height = vbox_connector->mode_hint.height ?
 547                           vbox_connector->mode_hint.height : 768;
 548        mode = drm_cvt_mode(connector->dev, preferred_width, preferred_height,
 549                            60, false, false, false);
 550        if (mode) {
 551                mode->type |= DRM_MODE_TYPE_PREFERRED;
 552                drm_mode_probed_add(connector, mode);
 553                ++num_modes;
 554        }
 555        vbox_set_edid(connector, preferred_width, preferred_height);
 556
 557        if (vbox_connector->vbox_crtc->x_hint != -1)
 558                drm_object_property_set_value(&connector->base,
 559                        vbox->dev->mode_config.suggested_x_property,
 560                        vbox_connector->vbox_crtc->x_hint);
 561        else
 562                drm_object_property_set_value(&connector->base,
 563                        vbox->dev->mode_config.suggested_x_property, 0);
 564
 565        if (vbox_connector->vbox_crtc->y_hint != -1)
 566                drm_object_property_set_value(&connector->base,
 567                        vbox->dev->mode_config.suggested_y_property,
 568                        vbox_connector->vbox_crtc->y_hint);
 569        else
 570                drm_object_property_set_value(&connector->base,
 571                        vbox->dev->mode_config.suggested_y_property, 0);
 572
 573        return num_modes;
 574}
 575
 576static int vbox_mode_valid(struct drm_connector *connector,
 577                           struct drm_display_mode *mode)
 578{
 579        return MODE_OK;
 580}
 581
 582static void vbox_connector_destroy(struct drm_connector *connector)
 583{
 584        drm_connector_unregister(connector);
 585        drm_connector_cleanup(connector);
 586        kfree(connector);
 587}
 588
 589static enum drm_connector_status
 590vbox_connector_detect(struct drm_connector *connector, bool force)
 591{
 592        struct vbox_connector *vbox_connector;
 593
 594        vbox_connector = to_vbox_connector(connector);
 595
 596        return vbox_connector->mode_hint.disconnected ?
 597            connector_status_disconnected : connector_status_connected;
 598}
 599
 600static int vbox_fill_modes(struct drm_connector *connector, u32 max_x,
 601                           u32 max_y)
 602{
 603        struct vbox_connector *vbox_connector;
 604        struct drm_device *dev;
 605        struct drm_display_mode *mode, *iterator;
 606
 607        vbox_connector = to_vbox_connector(connector);
 608        dev = vbox_connector->base.dev;
 609        list_for_each_entry_safe(mode, iterator, &connector->modes, head) {
 610                list_del(&mode->head);
 611                drm_mode_destroy(dev, mode);
 612        }
 613
 614        return drm_helper_probe_single_connector_modes(connector, max_x, max_y);
 615}
 616
 617static const struct drm_connector_helper_funcs vbox_connector_helper_funcs = {
 618        .mode_valid = vbox_mode_valid,
 619        .get_modes = vbox_get_modes,
 620        .best_encoder = vbox_best_single_encoder,
 621};
 622
 623static const struct drm_connector_funcs vbox_connector_funcs = {
 624        .dpms = drm_helper_connector_dpms,
 625        .detect = vbox_connector_detect,
 626        .fill_modes = vbox_fill_modes,
 627        .destroy = vbox_connector_destroy,
 628};
 629
 630static int vbox_connector_init(struct drm_device *dev,
 631                               struct vbox_crtc *vbox_crtc,
 632                               struct drm_encoder *encoder)
 633{
 634        struct vbox_connector *vbox_connector;
 635        struct drm_connector *connector;
 636
 637        vbox_connector = kzalloc(sizeof(*vbox_connector), GFP_KERNEL);
 638        if (!vbox_connector)
 639                return -ENOMEM;
 640
 641        connector = &vbox_connector->base;
 642        vbox_connector->vbox_crtc = vbox_crtc;
 643
 644        drm_connector_init(dev, connector, &vbox_connector_funcs,
 645                           DRM_MODE_CONNECTOR_VGA);
 646        drm_connector_helper_add(connector, &vbox_connector_helper_funcs);
 647
 648        connector->interlace_allowed = 0;
 649        connector->doublescan_allowed = 0;
 650
 651        drm_mode_create_suggested_offset_properties(dev);
 652        drm_object_attach_property(&connector->base,
 653                                   dev->mode_config.suggested_x_property, 0);
 654        drm_object_attach_property(&connector->base,
 655                                   dev->mode_config.suggested_y_property, 0);
 656        drm_connector_register(connector);
 657
 658        drm_mode_connector_attach_encoder(connector, encoder);
 659
 660        return 0;
 661}
 662
 663int vbox_mode_init(struct drm_device *dev)
 664{
 665        struct vbox_private *vbox = dev->dev_private;
 666        struct drm_encoder *encoder;
 667        struct vbox_crtc *vbox_crtc;
 668        unsigned int i;
 669        int ret;
 670
 671        /* vbox_cursor_init(dev); */
 672        for (i = 0; i < vbox->num_crtcs; ++i) {
 673                vbox_crtc = vbox_crtc_init(dev, i);
 674                if (!vbox_crtc)
 675                        return -ENOMEM;
 676                encoder = vbox_encoder_init(dev, i);
 677                if (!encoder)
 678                        return -ENOMEM;
 679                ret = vbox_connector_init(dev, vbox_crtc, encoder);
 680                if (ret)
 681                        return ret;
 682        }
 683
 684        return 0;
 685}
 686
 687void vbox_mode_fini(struct drm_device *dev)
 688{
 689        /* vbox_cursor_fini(dev); */
 690}
 691
 692/**
 693 * Copy the ARGB image and generate the mask, which is needed in case the host
 694 * does not support ARGB cursors.  The mask is a 1BPP bitmap with the bit set
 695 * if the corresponding alpha value in the ARGB image is greater than 0xF0.
 696 */
 697static void copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height,
 698                              size_t mask_size)
 699{
 700        size_t line_size = (width + 7) / 8;
 701        u32 i, j;
 702
 703        memcpy(dst + mask_size, src, width * height * 4);
 704        for (i = 0; i < height; ++i)
 705                for (j = 0; j < width; ++j)
 706                        if (((u32 *)src)[i * width + j] > 0xf0000000)
 707                                dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
 708}
 709
 710static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
 711                            u32 handle, u32 width, u32 height,
 712                            s32 hot_x, s32 hot_y)
 713{
 714        struct vbox_private *vbox = crtc->dev->dev_private;
 715        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
 716        struct ttm_bo_kmap_obj uobj_map;
 717        size_t data_size, mask_size;
 718        struct drm_gem_object *obj;
 719        u32 flags, caps = 0;
 720        struct vbox_bo *bo;
 721        bool src_isiomem;
 722        u8 *dst = NULL;
 723        u8 *src;
 724        int ret;
 725
 726        /*
 727         * Re-set this regularly as in 5.0.20 and earlier the information was
 728         * lost on save and restore.
 729         */
 730        hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
 731                                   vbox->input_mapping_width,
 732                                   vbox->input_mapping_height);
 733        if (!handle) {
 734                bool cursor_enabled = false;
 735                struct drm_crtc *crtci;
 736
 737                /* Hide cursor. */
 738                vbox_crtc->cursor_enabled = false;
 739                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
 740                                    head) {
 741                        if (to_vbox_crtc(crtci)->cursor_enabled)
 742                                cursor_enabled = true;
 743                }
 744
 745                if (!cursor_enabled)
 746                        hgsmi_update_pointer_shape(vbox->guest_pool, 0, 0, 0,
 747                                                   0, 0, NULL, 0);
 748                return 0;
 749        }
 750
 751        vbox_crtc->cursor_enabled = true;
 752
 753        if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT ||
 754            width == 0 || height == 0)
 755                return -EINVAL;
 756
 757        ret = hgsmi_query_conf(vbox->guest_pool,
 758                               VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
 759        if (ret)
 760                return ret;
 761
 762        if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) {
 763                /*
 764                 * -EINVAL means cursor_set2() not supported, -EAGAIN means
 765                 * retry at once.
 766                 */
 767                return -EBUSY;
 768        }
 769
 770        obj = drm_gem_object_lookup(file_priv, handle);
 771        if (!obj) {
 772                DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
 773                return -ENOENT;
 774        }
 775
 776        bo = gem_to_vbox_bo(obj);
 777        ret = vbox_bo_reserve(bo, false);
 778        if (ret)
 779                goto out_unref_obj;
 780
 781        /*
 782         * The mask must be calculated based on the alpha
 783         * channel, one bit per ARGB word, and must be 32-bit
 784         * padded.
 785         */
 786        mask_size = ((width + 7) / 8 * height + 3) & ~3;
 787        data_size = width * height * 4 + mask_size;
 788        vbox->cursor_hot_x = min_t(u32, max(hot_x, 0), width);
 789        vbox->cursor_hot_y = min_t(u32, max(hot_y, 0), height);
 790        vbox->cursor_width = width;
 791        vbox->cursor_height = height;
 792        vbox->cursor_data_size = data_size;
 793        dst = vbox->cursor_data;
 794
 795        ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
 796        if (ret) {
 797                vbox->cursor_data_size = 0;
 798                goto out_unreserve_bo;
 799        }
 800
 801        src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
 802        if (src_isiomem) {
 803                DRM_ERROR("src cursor bo not in main memory\n");
 804                ret = -EIO;
 805                goto out_unmap_bo;
 806        }
 807
 808        copy_cursor_image(src, dst, width, height, mask_size);
 809
 810        flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
 811                VBOX_MOUSE_POINTER_ALPHA;
 812        ret = hgsmi_update_pointer_shape(vbox->guest_pool, flags,
 813                                         vbox->cursor_hot_x, vbox->cursor_hot_y,
 814                                         width, height, dst, data_size);
 815out_unmap_bo:
 816        ttm_bo_kunmap(&uobj_map);
 817out_unreserve_bo:
 818        vbox_bo_unreserve(bo);
 819out_unref_obj:
 820        drm_gem_object_put_unlocked(obj);
 821
 822        return ret;
 823}
 824
 825static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y)
 826{
 827        struct vbox_private *vbox = crtc->dev->dev_private;
 828        u32 flags = VBOX_MOUSE_POINTER_VISIBLE |
 829            VBOX_MOUSE_POINTER_SHAPE | VBOX_MOUSE_POINTER_ALPHA;
 830        s32 crtc_x =
 831            vbox->single_framebuffer ? crtc->x : to_vbox_crtc(crtc)->x_hint;
 832        s32 crtc_y =
 833            vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint;
 834        u32 host_x, host_y;
 835        u32 hot_x = 0;
 836        u32 hot_y = 0;
 837        int ret;
 838
 839        /*
 840         * We compare these to unsigned later and don't
 841         * need to handle negative.
 842         */
 843        if (x + crtc_x < 0 || y + crtc_y < 0 || vbox->cursor_data_size == 0)
 844                return 0;
 845
 846        ret = hgsmi_cursor_position(vbox->guest_pool, true, x + crtc_x,
 847                                    y + crtc_y, &host_x, &host_y);
 848
 849        /*
 850         * The only reason we have vbox_cursor_move() is that some older clients
 851         * might use DRM_IOCTL_MODE_CURSOR instead of DRM_IOCTL_MODE_CURSOR2 and
 852         * use DRM_MODE_CURSOR_MOVE to set the hot-spot.
 853         *
 854         * However VirtualBox 5.0.20 and earlier has a bug causing it to return
 855         * 0,0 as host cursor location after a save and restore.
 856         *
 857         * To work around this we ignore a 0, 0 return, since missing the odd
 858         * time when it legitimately happens is not going to hurt much.
 859         */
 860        if (ret || (host_x == 0 && host_y == 0))
 861                return ret;
 862
 863        if (x + crtc_x < host_x)
 864                hot_x = min(host_x - x - crtc_x, vbox->cursor_width);
 865        if (y + crtc_y < host_y)
 866                hot_y = min(host_y - y - crtc_y, vbox->cursor_height);
 867
 868        if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y)
 869                return 0;
 870
 871        vbox->cursor_hot_x = hot_x;
 872        vbox->cursor_hot_y = hot_y;
 873
 874        return hgsmi_update_pointer_shape(vbox->guest_pool, flags,
 875                        hot_x, hot_y, vbox->cursor_width, vbox->cursor_height,
 876                        vbox->cursor_data, vbox->cursor_data_size);
 877}
 878