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,
 226                                 struct drm_framebuffer *new_fb,
 227                                 int x, int y)
 228{
 229        struct vbox_private *vbox = crtc->dev->dev_private;
 230        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
 231        struct drm_gem_object *obj;
 232        struct vbox_framebuffer *vbox_fb;
 233        struct vbox_bo *bo;
 234        int ret;
 235        u64 gpu_addr;
 236
 237        /* Unpin the previous fb. */
 238        if (old_fb) {
 239                vbox_fb = to_vbox_framebuffer(old_fb);
 240                obj = vbox_fb->obj;
 241                bo = gem_to_vbox_bo(obj);
 242                ret = vbox_bo_reserve(bo, false);
 243                if (ret)
 244                        return ret;
 245
 246                vbox_bo_unpin(bo);
 247                vbox_bo_unreserve(bo);
 248        }
 249
 250        vbox_fb = to_vbox_framebuffer(new_fb);
 251        obj = vbox_fb->obj;
 252        bo = gem_to_vbox_bo(obj);
 253
 254        ret = vbox_bo_reserve(bo, false);
 255        if (ret)
 256                return ret;
 257
 258        ret = vbox_bo_pin(bo, TTM_PL_FLAG_VRAM, &gpu_addr);
 259        if (ret) {
 260                vbox_bo_unreserve(bo);
 261                return ret;
 262        }
 263
 264        if (&vbox->fbdev->afb == vbox_fb)
 265                vbox_fbdev_set_base(vbox, gpu_addr);
 266        vbox_bo_unreserve(bo);
 267
 268        /* vbox_set_start_address_crt1(crtc, (u32)gpu_addr); */
 269        vbox_crtc->fb_offset = gpu_addr;
 270        if (vbox_set_up_input_mapping(vbox)) {
 271                struct drm_crtc *crtci;
 272
 273                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
 274                                    head) {
 275                        vbox_set_view(crtc);
 276                        vbox_do_modeset(crtci, &crtci->mode);
 277                }
 278        }
 279
 280        return 0;
 281}
 282
 283static int vbox_crtc_mode_set_base(struct drm_crtc *crtc, int x, int y,
 284                                   struct drm_framebuffer *old_fb)
 285{
 286        return vbox_crtc_do_set_base(crtc, old_fb, CRTC_FB(crtc), x, y);
 287}
 288
 289static int vbox_crtc_mode_set(struct drm_crtc *crtc,
 290                              struct drm_display_mode *mode,
 291                              struct drm_display_mode *adjusted_mode,
 292                              int x, int y, struct drm_framebuffer *old_fb)
 293{
 294        struct vbox_private *vbox = crtc->dev->dev_private;
 295        int ret;
 296
 297        vbox_crtc_mode_set_base(crtc, x, y, old_fb);
 298
 299        mutex_lock(&vbox->hw_mutex);
 300        ret = vbox_set_view(crtc);
 301        if (!ret)
 302                vbox_do_modeset(crtc, mode);
 303        hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
 304                                   vbox->input_mapping_width,
 305                                   vbox->input_mapping_height);
 306        mutex_unlock(&vbox->hw_mutex);
 307
 308        return ret;
 309}
 310
 311static int vbox_crtc_page_flip(struct drm_crtc *crtc,
 312                               struct drm_framebuffer *fb,
 313                               struct drm_pending_vblank_event *event,
 314                               uint32_t page_flip_flags,
 315                               struct drm_modeset_acquire_ctx *ctx)
 316{
 317        struct vbox_private *vbox = crtc->dev->dev_private;
 318        struct drm_device *drm = vbox->dev;
 319        unsigned long flags;
 320        int rc;
 321
 322        rc = vbox_crtc_do_set_base(crtc, CRTC_FB(crtc), fb, 0, 0);
 323        if (rc)
 324                return rc;
 325
 326        mutex_lock(&vbox->hw_mutex);
 327        vbox_set_view(crtc);
 328        vbox_do_modeset(crtc, &crtc->mode);
 329        mutex_unlock(&vbox->hw_mutex);
 330
 331        spin_lock_irqsave(&drm->event_lock, flags);
 332
 333        if (event)
 334                drm_crtc_send_vblank_event(crtc, event);
 335
 336        spin_unlock_irqrestore(&drm->event_lock, flags);
 337
 338        return 0;
 339}
 340
 341static void vbox_crtc_disable(struct drm_crtc *crtc)
 342{
 343}
 344
 345static void vbox_crtc_prepare(struct drm_crtc *crtc)
 346{
 347}
 348
 349static void vbox_crtc_commit(struct drm_crtc *crtc)
 350{
 351}
 352
 353static const struct drm_crtc_helper_funcs vbox_crtc_helper_funcs = {
 354        .dpms = vbox_crtc_dpms,
 355        .mode_fixup = vbox_crtc_mode_fixup,
 356        .mode_set = vbox_crtc_mode_set,
 357        /* .mode_set_base = vbox_crtc_mode_set_base, */
 358        .disable = vbox_crtc_disable,
 359        .prepare = vbox_crtc_prepare,
 360        .commit = vbox_crtc_commit,
 361};
 362
 363static void vbox_crtc_reset(struct drm_crtc *crtc)
 364{
 365}
 366
 367static void vbox_crtc_destroy(struct drm_crtc *crtc)
 368{
 369        drm_crtc_cleanup(crtc);
 370        kfree(crtc);
 371}
 372
 373static const struct drm_crtc_funcs vbox_crtc_funcs = {
 374        .cursor_move = vbox_cursor_move,
 375        .cursor_set2 = vbox_cursor_set2,
 376        .reset = vbox_crtc_reset,
 377        .set_config = drm_crtc_helper_set_config,
 378        /* .gamma_set = vbox_crtc_gamma_set, */
 379        .page_flip = vbox_crtc_page_flip,
 380        .destroy = vbox_crtc_destroy,
 381};
 382
 383static struct vbox_crtc *vbox_crtc_init(struct drm_device *dev, unsigned int i)
 384{
 385        struct vbox_crtc *vbox_crtc;
 386
 387        vbox_crtc = kzalloc(sizeof(*vbox_crtc), GFP_KERNEL);
 388        if (!vbox_crtc)
 389                return NULL;
 390
 391        vbox_crtc->crtc_id = i;
 392
 393        drm_crtc_init(dev, &vbox_crtc->base, &vbox_crtc_funcs);
 394        drm_mode_crtc_set_gamma_size(&vbox_crtc->base, 256);
 395        drm_crtc_helper_add(&vbox_crtc->base, &vbox_crtc_helper_funcs);
 396
 397        return vbox_crtc;
 398}
 399
 400static void vbox_encoder_destroy(struct drm_encoder *encoder)
 401{
 402        drm_encoder_cleanup(encoder);
 403        kfree(encoder);
 404}
 405
 406static struct drm_encoder *vbox_best_single_encoder(struct drm_connector
 407                                                    *connector)
 408{
 409        int enc_id = connector->encoder_ids[0];
 410
 411        /* pick the encoder ids */
 412        if (enc_id)
 413                return drm_encoder_find(connector->dev, NULL, enc_id);
 414
 415        return NULL;
 416}
 417
 418static const struct drm_encoder_funcs vbox_enc_funcs = {
 419        .destroy = vbox_encoder_destroy,
 420};
 421
 422static void vbox_encoder_dpms(struct drm_encoder *encoder, int mode)
 423{
 424}
 425
 426static bool vbox_mode_fixup(struct drm_encoder *encoder,
 427                            const struct drm_display_mode *mode,
 428                            struct drm_display_mode *adjusted_mode)
 429{
 430        return true;
 431}
 432
 433static void vbox_encoder_mode_set(struct drm_encoder *encoder,
 434                                  struct drm_display_mode *mode,
 435                                  struct drm_display_mode *adjusted_mode)
 436{
 437}
 438
 439static void vbox_encoder_prepare(struct drm_encoder *encoder)
 440{
 441}
 442
 443static void vbox_encoder_commit(struct drm_encoder *encoder)
 444{
 445}
 446
 447static const struct drm_encoder_helper_funcs vbox_enc_helper_funcs = {
 448        .dpms = vbox_encoder_dpms,
 449        .mode_fixup = vbox_mode_fixup,
 450        .prepare = vbox_encoder_prepare,
 451        .commit = vbox_encoder_commit,
 452        .mode_set = vbox_encoder_mode_set,
 453};
 454
 455static struct drm_encoder *vbox_encoder_init(struct drm_device *dev,
 456                                             unsigned int i)
 457{
 458        struct vbox_encoder *vbox_encoder;
 459
 460        vbox_encoder = kzalloc(sizeof(*vbox_encoder), GFP_KERNEL);
 461        if (!vbox_encoder)
 462                return NULL;
 463
 464        drm_encoder_init(dev, &vbox_encoder->base, &vbox_enc_funcs,
 465                         DRM_MODE_ENCODER_DAC, NULL);
 466        drm_encoder_helper_add(&vbox_encoder->base, &vbox_enc_helper_funcs);
 467
 468        vbox_encoder->base.possible_crtcs = 1 << i;
 469        return &vbox_encoder->base;
 470}
 471
 472/**
 473 * Generate EDID data with a mode-unique serial number for the virtual
 474 *  monitor to try to persuade Unity that different modes correspond to
 475 *  different monitors and it should not try to force the same resolution on
 476 *  them.
 477 */
 478static void vbox_set_edid(struct drm_connector *connector, int width,
 479                          int height)
 480{
 481        enum { EDID_SIZE = 128 };
 482        unsigned char edid[EDID_SIZE] = {
 483                0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, /* header */
 484                0x58, 0x58,     /* manufacturer (VBX) */
 485                0x00, 0x00,     /* product code */
 486                0x00, 0x00, 0x00, 0x00, /* serial number goes here */
 487                0x01,           /* week of manufacture */
 488                0x00,           /* year of manufacture */
 489                0x01, 0x03,     /* EDID version */
 490                0x80,           /* capabilities - digital */
 491                0x00,           /* horiz. res in cm, zero for projectors */
 492                0x00,           /* vert. res in cm */
 493                0x78,           /* display gamma (120 == 2.2). */
 494                0xEE,           /* features (standby, suspend, off, RGB, std */
 495                                /* colour space, preferred timing mode) */
 496                0xEE, 0x91, 0xA3, 0x54, 0x4C, 0x99, 0x26, 0x0F, 0x50, 0x54,
 497                /* chromaticity for standard colour space. */
 498                0x00, 0x00, 0x00,       /* no default timings */
 499                0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
 500                    0x01, 0x01,
 501                0x01, 0x01, 0x01, 0x01, /* no standard timings */
 502                0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x06, 0x00, 0x02, 0x02,
 503                    0x02, 0x02,
 504                /* descriptor block 1 goes below */
 505                0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 506                /* descriptor block 2, monitor ranges */
 507                0x00, 0x00, 0x00, 0xFD, 0x00,
 508                0x00, 0xC8, 0x00, 0xC8, 0x64, 0x00, 0x0A, 0x20, 0x20, 0x20,
 509                    0x20, 0x20,
 510                /* 0-200Hz vertical, 0-200KHz horizontal, 1000MHz pixel clock */
 511                0x20,
 512                /* descriptor block 3, monitor name */
 513                0x00, 0x00, 0x00, 0xFC, 0x00,
 514                'V', 'B', 'O', 'X', ' ', 'm', 'o', 'n', 'i', 't', 'o', 'r',
 515                '\n',
 516                /* descriptor block 4: dummy data */
 517                0x00, 0x00, 0x00, 0x10, 0x00,
 518                0x0A, 0x20, 0x20, 0x20, 0x20, 0x20,
 519                0x20, 0x20, 0x20, 0x20, 0x20, 0x20,
 520                0x20,
 521                0x00,           /* number of extensions */
 522                0x00            /* checksum goes here */
 523        };
 524        int clock = (width + 6) * (height + 6) * 60 / 10000;
 525        unsigned int i, sum = 0;
 526
 527        edid[12] = width & 0xff;
 528        edid[13] = width >> 8;
 529        edid[14] = height & 0xff;
 530        edid[15] = height >> 8;
 531        edid[54] = clock & 0xff;
 532        edid[55] = clock >> 8;
 533        edid[56] = width & 0xff;
 534        edid[58] = (width >> 4) & 0xf0;
 535        edid[59] = height & 0xff;
 536        edid[61] = (height >> 4) & 0xf0;
 537        for (i = 0; i < EDID_SIZE - 1; ++i)
 538                sum += edid[i];
 539        edid[EDID_SIZE - 1] = (0x100 - (sum & 0xFF)) & 0xFF;
 540        drm_connector_update_edid_property(connector, (struct edid *)edid);
 541}
 542
 543static int vbox_get_modes(struct drm_connector *connector)
 544{
 545        struct vbox_connector *vbox_connector = NULL;
 546        struct drm_display_mode *mode = NULL;
 547        struct vbox_private *vbox = NULL;
 548        unsigned int num_modes = 0;
 549        int preferred_width, preferred_height;
 550
 551        vbox_connector = to_vbox_connector(connector);
 552        vbox = connector->dev->dev_private;
 553        /*
 554         * Heuristic: we do not want to tell the host that we support dynamic
 555         * resizing unless we feel confident that the user space client using
 556         * the video driver can handle hot-plug events.  So the first time modes
 557         * are queried after a "master" switch we tell the host that we do not,
 558         * and immediately after we send the client a hot-plug notification as
 559         * a test to see if they will respond and query again.
 560         * That is also the reason why capabilities are reported to the host at
 561         * this place in the code rather than elsewhere.
 562         * We need to report the flags location before reporting the IRQ
 563         * capability.
 564         */
 565        hgsmi_report_flags_location(vbox->guest_pool, GUEST_HEAP_OFFSET(vbox) +
 566                                    HOST_FLAGS_OFFSET);
 567        if (vbox_connector->vbox_crtc->crtc_id == 0)
 568                vbox_report_caps(vbox);
 569        if (!vbox->initial_mode_queried) {
 570                if (vbox_connector->vbox_crtc->crtc_id == 0) {
 571                        vbox->initial_mode_queried = true;
 572                        vbox_report_hotplug(vbox);
 573                }
 574                return drm_add_modes_noedid(connector, 800, 600);
 575        }
 576        num_modes = drm_add_modes_noedid(connector, 2560, 1600);
 577        preferred_width = vbox_connector->mode_hint.width ?
 578                          vbox_connector->mode_hint.width : 1024;
 579        preferred_height = vbox_connector->mode_hint.height ?
 580                           vbox_connector->mode_hint.height : 768;
 581        mode = drm_cvt_mode(connector->dev, preferred_width, preferred_height,
 582                            60, false, false, false);
 583        if (mode) {
 584                mode->type |= DRM_MODE_TYPE_PREFERRED;
 585                drm_mode_probed_add(connector, mode);
 586                ++num_modes;
 587        }
 588        vbox_set_edid(connector, preferred_width, preferred_height);
 589
 590        if (vbox_connector->vbox_crtc->x_hint != -1)
 591                drm_object_property_set_value(&connector->base,
 592                        vbox->dev->mode_config.suggested_x_property,
 593                        vbox_connector->vbox_crtc->x_hint);
 594        else
 595                drm_object_property_set_value(&connector->base,
 596                        vbox->dev->mode_config.suggested_x_property, 0);
 597
 598        if (vbox_connector->vbox_crtc->y_hint != -1)
 599                drm_object_property_set_value(&connector->base,
 600                        vbox->dev->mode_config.suggested_y_property,
 601                        vbox_connector->vbox_crtc->y_hint);
 602        else
 603                drm_object_property_set_value(&connector->base,
 604                        vbox->dev->mode_config.suggested_y_property, 0);
 605
 606        return num_modes;
 607}
 608
 609static enum drm_mode_status vbox_mode_valid(struct drm_connector *connector,
 610                           struct drm_display_mode *mode)
 611{
 612        return MODE_OK;
 613}
 614
 615static void vbox_connector_destroy(struct drm_connector *connector)
 616{
 617        drm_connector_unregister(connector);
 618        drm_connector_cleanup(connector);
 619        kfree(connector);
 620}
 621
 622static enum drm_connector_status
 623vbox_connector_detect(struct drm_connector *connector, bool force)
 624{
 625        struct vbox_connector *vbox_connector;
 626
 627        vbox_connector = to_vbox_connector(connector);
 628
 629        return vbox_connector->mode_hint.disconnected ?
 630            connector_status_disconnected : connector_status_connected;
 631}
 632
 633static int vbox_fill_modes(struct drm_connector *connector, u32 max_x,
 634                           u32 max_y)
 635{
 636        struct vbox_connector *vbox_connector;
 637        struct drm_device *dev;
 638        struct drm_display_mode *mode, *iterator;
 639
 640        vbox_connector = to_vbox_connector(connector);
 641        dev = vbox_connector->base.dev;
 642        list_for_each_entry_safe(mode, iterator, &connector->modes, head) {
 643                list_del(&mode->head);
 644                drm_mode_destroy(dev, mode);
 645        }
 646
 647        return drm_helper_probe_single_connector_modes(connector, max_x, max_y);
 648}
 649
 650static const struct drm_connector_helper_funcs vbox_connector_helper_funcs = {
 651        .mode_valid = vbox_mode_valid,
 652        .get_modes = vbox_get_modes,
 653        .best_encoder = vbox_best_single_encoder,
 654};
 655
 656static const struct drm_connector_funcs vbox_connector_funcs = {
 657        .dpms = drm_helper_connector_dpms,
 658        .detect = vbox_connector_detect,
 659        .fill_modes = vbox_fill_modes,
 660        .destroy = vbox_connector_destroy,
 661};
 662
 663static int vbox_connector_init(struct drm_device *dev,
 664                               struct vbox_crtc *vbox_crtc,
 665                               struct drm_encoder *encoder)
 666{
 667        struct vbox_connector *vbox_connector;
 668        struct drm_connector *connector;
 669
 670        vbox_connector = kzalloc(sizeof(*vbox_connector), GFP_KERNEL);
 671        if (!vbox_connector)
 672                return -ENOMEM;
 673
 674        connector = &vbox_connector->base;
 675        vbox_connector->vbox_crtc = vbox_crtc;
 676
 677        drm_connector_init(dev, connector, &vbox_connector_funcs,
 678                           DRM_MODE_CONNECTOR_VGA);
 679        drm_connector_helper_add(connector, &vbox_connector_helper_funcs);
 680
 681        connector->interlace_allowed = 0;
 682        connector->doublescan_allowed = 0;
 683
 684        drm_mode_create_suggested_offset_properties(dev);
 685        drm_object_attach_property(&connector->base,
 686                                   dev->mode_config.suggested_x_property, 0);
 687        drm_object_attach_property(&connector->base,
 688                                   dev->mode_config.suggested_y_property, 0);
 689        drm_connector_register(connector);
 690
 691        drm_connector_attach_encoder(connector, encoder);
 692
 693        return 0;
 694}
 695
 696int vbox_mode_init(struct drm_device *dev)
 697{
 698        struct vbox_private *vbox = dev->dev_private;
 699        struct drm_encoder *encoder;
 700        struct vbox_crtc *vbox_crtc;
 701        unsigned int i;
 702        int ret;
 703
 704        /* vbox_cursor_init(dev); */
 705        for (i = 0; i < vbox->num_crtcs; ++i) {
 706                vbox_crtc = vbox_crtc_init(dev, i);
 707                if (!vbox_crtc)
 708                        return -ENOMEM;
 709                encoder = vbox_encoder_init(dev, i);
 710                if (!encoder)
 711                        return -ENOMEM;
 712                ret = vbox_connector_init(dev, vbox_crtc, encoder);
 713                if (ret)
 714                        return ret;
 715        }
 716
 717        return 0;
 718}
 719
 720void vbox_mode_fini(struct drm_device *dev)
 721{
 722        /* vbox_cursor_fini(dev); */
 723}
 724
 725/**
 726 * Copy the ARGB image and generate the mask, which is needed in case the host
 727 * does not support ARGB cursors.  The mask is a 1BPP bitmap with the bit set
 728 * if the corresponding alpha value in the ARGB image is greater than 0xF0.
 729 */
 730static void copy_cursor_image(u8 *src, u8 *dst, u32 width, u32 height,
 731                              size_t mask_size)
 732{
 733        size_t line_size = (width + 7) / 8;
 734        u32 i, j;
 735
 736        memcpy(dst + mask_size, src, width * height * 4);
 737        for (i = 0; i < height; ++i)
 738                for (j = 0; j < width; ++j)
 739                        if (((u32 *)src)[i * width + j] > 0xf0000000)
 740                                dst[i * line_size + j / 8] |= (0x80 >> (j % 8));
 741}
 742
 743static int vbox_cursor_set2(struct drm_crtc *crtc, struct drm_file *file_priv,
 744                            u32 handle, u32 width, u32 height,
 745                            s32 hot_x, s32 hot_y)
 746{
 747        struct vbox_private *vbox = crtc->dev->dev_private;
 748        struct vbox_crtc *vbox_crtc = to_vbox_crtc(crtc);
 749        struct ttm_bo_kmap_obj uobj_map;
 750        size_t data_size, mask_size;
 751        struct drm_gem_object *obj;
 752        u32 flags, caps = 0;
 753        struct vbox_bo *bo;
 754        bool src_isiomem;
 755        u8 *dst = NULL;
 756        u8 *src;
 757        int ret;
 758
 759        /*
 760         * Re-set this regularly as in 5.0.20 and earlier the information was
 761         * lost on save and restore.
 762         */
 763        hgsmi_update_input_mapping(vbox->guest_pool, 0, 0,
 764                                   vbox->input_mapping_width,
 765                                   vbox->input_mapping_height);
 766        if (!handle) {
 767                bool cursor_enabled = false;
 768                struct drm_crtc *crtci;
 769
 770                /* Hide cursor. */
 771                vbox_crtc->cursor_enabled = false;
 772                list_for_each_entry(crtci, &vbox->dev->mode_config.crtc_list,
 773                                    head) {
 774                        if (to_vbox_crtc(crtci)->cursor_enabled)
 775                                cursor_enabled = true;
 776                }
 777
 778                if (!cursor_enabled)
 779                        hgsmi_update_pointer_shape(vbox->guest_pool, 0, 0, 0,
 780                                                   0, 0, NULL, 0);
 781                return 0;
 782        }
 783
 784        vbox_crtc->cursor_enabled = true;
 785
 786        if (width > VBOX_MAX_CURSOR_WIDTH || height > VBOX_MAX_CURSOR_HEIGHT ||
 787            width == 0 || height == 0)
 788                return -EINVAL;
 789
 790        ret = hgsmi_query_conf(vbox->guest_pool,
 791                               VBOX_VBVA_CONF32_CURSOR_CAPABILITIES, &caps);
 792        if (ret)
 793                return ret;
 794
 795        if (!(caps & VBOX_VBVA_CURSOR_CAPABILITY_HARDWARE)) {
 796                /*
 797                 * -EINVAL means cursor_set2() not supported, -EAGAIN means
 798                 * retry at once.
 799                 */
 800                return -EBUSY;
 801        }
 802
 803        obj = drm_gem_object_lookup(file_priv, handle);
 804        if (!obj) {
 805                DRM_ERROR("Cannot find cursor object %x for crtc\n", handle);
 806                return -ENOENT;
 807        }
 808
 809        bo = gem_to_vbox_bo(obj);
 810        ret = vbox_bo_reserve(bo, false);
 811        if (ret)
 812                goto out_unref_obj;
 813
 814        /*
 815         * The mask must be calculated based on the alpha
 816         * channel, one bit per ARGB word, and must be 32-bit
 817         * padded.
 818         */
 819        mask_size = ((width + 7) / 8 * height + 3) & ~3;
 820        data_size = width * height * 4 + mask_size;
 821        vbox->cursor_hot_x = min_t(u32, max(hot_x, 0), width);
 822        vbox->cursor_hot_y = min_t(u32, max(hot_y, 0), height);
 823        vbox->cursor_width = width;
 824        vbox->cursor_height = height;
 825        vbox->cursor_data_size = data_size;
 826        dst = vbox->cursor_data;
 827
 828        ret = ttm_bo_kmap(&bo->bo, 0, bo->bo.num_pages, &uobj_map);
 829        if (ret) {
 830                vbox->cursor_data_size = 0;
 831                goto out_unreserve_bo;
 832        }
 833
 834        src = ttm_kmap_obj_virtual(&uobj_map, &src_isiomem);
 835        if (src_isiomem) {
 836                DRM_ERROR("src cursor bo not in main memory\n");
 837                ret = -EIO;
 838                goto out_unmap_bo;
 839        }
 840
 841        copy_cursor_image(src, dst, width, height, mask_size);
 842
 843        flags = VBOX_MOUSE_POINTER_VISIBLE | VBOX_MOUSE_POINTER_SHAPE |
 844                VBOX_MOUSE_POINTER_ALPHA;
 845        ret = hgsmi_update_pointer_shape(vbox->guest_pool, flags,
 846                                         vbox->cursor_hot_x, vbox->cursor_hot_y,
 847                                         width, height, dst, data_size);
 848out_unmap_bo:
 849        ttm_bo_kunmap(&uobj_map);
 850out_unreserve_bo:
 851        vbox_bo_unreserve(bo);
 852out_unref_obj:
 853        drm_gem_object_put_unlocked(obj);
 854
 855        return ret;
 856}
 857
 858static int vbox_cursor_move(struct drm_crtc *crtc, int x, int y)
 859{
 860        struct vbox_private *vbox = crtc->dev->dev_private;
 861        u32 flags = VBOX_MOUSE_POINTER_VISIBLE |
 862            VBOX_MOUSE_POINTER_SHAPE | VBOX_MOUSE_POINTER_ALPHA;
 863        s32 crtc_x =
 864            vbox->single_framebuffer ? crtc->x : to_vbox_crtc(crtc)->x_hint;
 865        s32 crtc_y =
 866            vbox->single_framebuffer ? crtc->y : to_vbox_crtc(crtc)->y_hint;
 867        u32 host_x, host_y;
 868        u32 hot_x = 0;
 869        u32 hot_y = 0;
 870        int ret;
 871
 872        /*
 873         * We compare these to unsigned later and don't
 874         * need to handle negative.
 875         */
 876        if (x + crtc_x < 0 || y + crtc_y < 0 || vbox->cursor_data_size == 0)
 877                return 0;
 878
 879        ret = hgsmi_cursor_position(vbox->guest_pool, true, x + crtc_x,
 880                                    y + crtc_y, &host_x, &host_y);
 881
 882        /*
 883         * The only reason we have vbox_cursor_move() is that some older clients
 884         * might use DRM_IOCTL_MODE_CURSOR instead of DRM_IOCTL_MODE_CURSOR2 and
 885         * use DRM_MODE_CURSOR_MOVE to set the hot-spot.
 886         *
 887         * However VirtualBox 5.0.20 and earlier has a bug causing it to return
 888         * 0,0 as host cursor location after a save and restore.
 889         *
 890         * To work around this we ignore a 0, 0 return, since missing the odd
 891         * time when it legitimately happens is not going to hurt much.
 892         */
 893        if (ret || (host_x == 0 && host_y == 0))
 894                return ret;
 895
 896        if (x + crtc_x < host_x)
 897                hot_x = min(host_x - x - crtc_x, vbox->cursor_width);
 898        if (y + crtc_y < host_y)
 899                hot_y = min(host_y - y - crtc_y, vbox->cursor_height);
 900
 901        if (hot_x == vbox->cursor_hot_x && hot_y == vbox->cursor_hot_y)
 902                return 0;
 903
 904        vbox->cursor_hot_x = hot_x;
 905        vbox->cursor_hot_y = hot_y;
 906
 907        return hgsmi_update_pointer_shape(vbox->guest_pool, flags,
 908                        hot_x, hot_y, vbox->cursor_width, vbox->cursor_height,
 909                        vbox->cursor_data, vbox->cursor_data_size);
 910}
 911