root/drivers/gpu/drm/tiny/gm12u320.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gm12u320_usb_alloc
  2. gm12u320_usb_free
  3. gm12u320_misc_request
  4. gm12u320_32bpp_to_24bpp_packed
  5. gm12u320_copy_fb_to_blocks
  6. gm12u320_fb_update_work
  7. gm12u320_fb_mark_dirty
  8. gm12u320_start_fb_update
  9. gm12u320_stop_fb_update
  10. gm12u320_set_ecomode
  11. gm12u320_conn_get_modes
  12. gm12u320_conn_init
  13. gm12u320_pipe_enable
  14. gm12u320_pipe_disable
  15. gm12u320_pipe_update
  16. gm12u320_driver_release
  17. gm12u320_usb_probe
  18. gm12u320_usb_disconnect
  19. gm12u320_suspend
  20. gm12u320_resume

   1 // SPDX-License-Identifier: GPL-2.0+
   2 /*
   3  * Copyright 2019 Hans de Goede <hdegoede@redhat.com>
   4  */
   5 
   6 #include <linux/dma-buf.h>
   7 #include <linux/module.h>
   8 #include <linux/usb.h>
   9 
  10 #include <drm/drm_atomic_helper.h>
  11 #include <drm/drm_atomic_state_helper.h>
  12 #include <drm/drm_connector.h>
  13 #include <drm/drm_damage_helper.h>
  14 #include <drm/drm_drv.h>
  15 #include <drm/drm_fb_helper.h>
  16 #include <drm/drm_file.h>
  17 #include <drm/drm_format_helper.h>
  18 #include <drm/drm_fourcc.h>
  19 #include <drm/drm_gem_shmem_helper.h>
  20 #include <drm/drm_gem_framebuffer_helper.h>
  21 #include <drm/drm_ioctl.h>
  22 #include <drm/drm_modeset_helper_vtables.h>
  23 #include <drm/drm_probe_helper.h>
  24 #include <drm/drm_simple_kms_helper.h>
  25 #include <drm/drm_vblank.h>
  26 
  27 static bool eco_mode;
  28 module_param(eco_mode, bool, 0644);
  29 MODULE_PARM_DESC(eco_mode, "Turn on Eco mode (less bright, more silent)");
  30 
  31 #define DRIVER_NAME             "gm12u320"
  32 #define DRIVER_DESC             "Grain Media GM12U320 USB projector display"
  33 #define DRIVER_DATE             "2019"
  34 #define DRIVER_MAJOR            1
  35 #define DRIVER_MINOR            0
  36 
  37 /*
  38  * The DLP has an actual width of 854 pixels, but that is not a multiple
  39  * of 8, breaking things left and right, so we export a width of 848.
  40  */
  41 #define GM12U320_USER_WIDTH             848
  42 #define GM12U320_REAL_WIDTH             854
  43 #define GM12U320_HEIGHT                 480
  44 
  45 #define GM12U320_BLOCK_COUNT            20
  46 
  47 #define GM12U320_ERR(fmt, ...) \
  48         DRM_DEV_ERROR(&gm12u320->udev->dev, fmt, ##__VA_ARGS__)
  49 
  50 #define MISC_RCV_EPT                    1
  51 #define DATA_RCV_EPT                    2
  52 #define DATA_SND_EPT                    3
  53 #define MISC_SND_EPT                    4
  54 
  55 #define DATA_BLOCK_HEADER_SIZE          84
  56 #define DATA_BLOCK_CONTENT_SIZE         64512
  57 #define DATA_BLOCK_FOOTER_SIZE          20
  58 #define DATA_BLOCK_SIZE                 (DATA_BLOCK_HEADER_SIZE + \
  59                                          DATA_BLOCK_CONTENT_SIZE + \
  60                                          DATA_BLOCK_FOOTER_SIZE)
  61 #define DATA_LAST_BLOCK_CONTENT_SIZE    4032
  62 #define DATA_LAST_BLOCK_SIZE            (DATA_BLOCK_HEADER_SIZE + \
  63                                          DATA_LAST_BLOCK_CONTENT_SIZE + \
  64                                          DATA_BLOCK_FOOTER_SIZE)
  65 
  66 #define CMD_SIZE                        31
  67 #define READ_STATUS_SIZE                13
  68 #define MISC_VALUE_SIZE                 4
  69 
  70 #define CMD_TIMEOUT                     msecs_to_jiffies(200)
  71 #define DATA_TIMEOUT                    msecs_to_jiffies(1000)
  72 #define IDLE_TIMEOUT                    msecs_to_jiffies(2000)
  73 #define FIRST_FRAME_TIMEOUT             msecs_to_jiffies(2000)
  74 
  75 #define MISC_REQ_GET_SET_ECO_A          0xff
  76 #define MISC_REQ_GET_SET_ECO_B          0x35
  77 /* Windows driver does once every second, with arg d = 1, other args 0 */
  78 #define MISC_REQ_UNKNOWN1_A             0xff
  79 #define MISC_REQ_UNKNOWN1_B             0x38
  80 /* Windows driver does this on init, with arg a, b = 0, c = 0xa0, d = 4 */
  81 #define MISC_REQ_UNKNOWN2_A             0xa5
  82 #define MISC_REQ_UNKNOWN2_B             0x00
  83 
  84 struct gm12u320_device {
  85         struct drm_device                dev;
  86         struct drm_simple_display_pipe   pipe;
  87         struct drm_connector             conn;
  88         struct usb_device               *udev;
  89         unsigned char                   *cmd_buf;
  90         unsigned char                   *data_buf[GM12U320_BLOCK_COUNT];
  91         bool                             pipe_enabled;
  92         struct {
  93                 bool                     run;
  94                 struct workqueue_struct *workq;
  95                 struct work_struct       work;
  96                 wait_queue_head_t        waitq;
  97                 struct mutex             lock;
  98                 struct drm_framebuffer  *fb;
  99                 struct drm_rect          rect;
 100         } fb_update;
 101 };
 102 
 103 static const char cmd_data[CMD_SIZE] = {
 104         0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
 105         0x68, 0xfc, 0x00, 0x00, 0x00, 0x00, 0x10, 0xff,
 106         0x00, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x80, 0x00,
 107         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 108 };
 109 
 110 static const char cmd_draw[CMD_SIZE] = {
 111         0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
 112         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0xfe,
 113         0x00, 0x00, 0x00, 0xc0, 0xd1, 0x05, 0x00, 0x40,
 114         0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00
 115 };
 116 
 117 static const char cmd_misc[CMD_SIZE] = {
 118         0x55, 0x53, 0x42, 0x43, 0x00, 0x00, 0x00, 0x00,
 119         0x04, 0x00, 0x00, 0x00, 0x80, 0x01, 0x10, 0xfd,
 120         0x00, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x00,
 121         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
 122 };
 123 
 124 static const char data_block_header[DATA_BLOCK_HEADER_SIZE] = {
 125         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 126         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 127         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 128         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 129         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 130         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 131         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 132         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 133         0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 134         0x00, 0x04, 0x15, 0x00, 0x00, 0xfc, 0x00, 0x00,
 135         0x01, 0x00, 0x00, 0xdb
 136 };
 137 
 138 static const char data_last_block_header[DATA_BLOCK_HEADER_SIZE] = {
 139         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 140         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 141         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 142         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 143         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 144         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 145         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 146         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 147         0xfb, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 148         0x2a, 0x00, 0x20, 0x00, 0xc0, 0x0f, 0x00, 0x00,
 149         0x01, 0x00, 0x00, 0xd7
 150 };
 151 
 152 static const char data_block_footer[DATA_BLOCK_FOOTER_SIZE] = {
 153         0xfb, 0x14, 0x02, 0x20, 0x00, 0x00, 0x00, 0x00,
 154         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
 155         0x80, 0x00, 0x00, 0x4f
 156 };
 157 
 158 static int gm12u320_usb_alloc(struct gm12u320_device *gm12u320)
 159 {
 160         int i, block_size;
 161         const char *hdr;
 162 
 163         gm12u320->cmd_buf = kmalloc(CMD_SIZE, GFP_KERNEL);
 164         if (!gm12u320->cmd_buf)
 165                 return -ENOMEM;
 166 
 167         for (i = 0; i < GM12U320_BLOCK_COUNT; i++) {
 168                 if (i == GM12U320_BLOCK_COUNT - 1) {
 169                         block_size = DATA_LAST_BLOCK_SIZE;
 170                         hdr = data_last_block_header;
 171                 } else {
 172                         block_size = DATA_BLOCK_SIZE;
 173                         hdr = data_block_header;
 174                 }
 175 
 176                 gm12u320->data_buf[i] = kzalloc(block_size, GFP_KERNEL);
 177                 if (!gm12u320->data_buf[i])
 178                         return -ENOMEM;
 179 
 180                 memcpy(gm12u320->data_buf[i], hdr, DATA_BLOCK_HEADER_SIZE);
 181                 memcpy(gm12u320->data_buf[i] +
 182                                 (block_size - DATA_BLOCK_FOOTER_SIZE),
 183                        data_block_footer, DATA_BLOCK_FOOTER_SIZE);
 184         }
 185 
 186         gm12u320->fb_update.workq = create_singlethread_workqueue(DRIVER_NAME);
 187         if (!gm12u320->fb_update.workq)
 188                 return -ENOMEM;
 189 
 190         return 0;
 191 }
 192 
 193 static void gm12u320_usb_free(struct gm12u320_device *gm12u320)
 194 {
 195         int i;
 196 
 197         if (gm12u320->fb_update.workq)
 198                 destroy_workqueue(gm12u320->fb_update.workq);
 199 
 200         for (i = 0; i < GM12U320_BLOCK_COUNT; i++)
 201                 kfree(gm12u320->data_buf[i]);
 202 
 203         kfree(gm12u320->cmd_buf);
 204 }
 205 
 206 static int gm12u320_misc_request(struct gm12u320_device *gm12u320,
 207                                  u8 req_a, u8 req_b,
 208                                  u8 arg_a, u8 arg_b, u8 arg_c, u8 arg_d)
 209 {
 210         int ret, len;
 211 
 212         memcpy(gm12u320->cmd_buf, &cmd_misc, CMD_SIZE);
 213         gm12u320->cmd_buf[20] = req_a;
 214         gm12u320->cmd_buf[21] = req_b;
 215         gm12u320->cmd_buf[22] = arg_a;
 216         gm12u320->cmd_buf[23] = arg_b;
 217         gm12u320->cmd_buf[24] = arg_c;
 218         gm12u320->cmd_buf[25] = arg_d;
 219 
 220         /* Send request */
 221         ret = usb_bulk_msg(gm12u320->udev,
 222                            usb_sndbulkpipe(gm12u320->udev, MISC_SND_EPT),
 223                            gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
 224         if (ret || len != CMD_SIZE) {
 225                 GM12U320_ERR("Misc. req. error %d\n", ret);
 226                 return -EIO;
 227         }
 228 
 229         /* Read value */
 230         ret = usb_bulk_msg(gm12u320->udev,
 231                            usb_rcvbulkpipe(gm12u320->udev, MISC_RCV_EPT),
 232                            gm12u320->cmd_buf, MISC_VALUE_SIZE, &len,
 233                            DATA_TIMEOUT);
 234         if (ret || len != MISC_VALUE_SIZE) {
 235                 GM12U320_ERR("Misc. value error %d\n", ret);
 236                 return -EIO;
 237         }
 238         /* cmd_buf[0] now contains the read value, which we don't use */
 239 
 240         /* Read status */
 241         ret = usb_bulk_msg(gm12u320->udev,
 242                            usb_rcvbulkpipe(gm12u320->udev, MISC_RCV_EPT),
 243                            gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
 244                            CMD_TIMEOUT);
 245         if (ret || len != READ_STATUS_SIZE) {
 246                 GM12U320_ERR("Misc. status error %d\n", ret);
 247                 return -EIO;
 248         }
 249 
 250         return 0;
 251 }
 252 
 253 static void gm12u320_32bpp_to_24bpp_packed(u8 *dst, u8 *src, int len)
 254 {
 255         while (len--) {
 256                 *dst++ = *src++;
 257                 *dst++ = *src++;
 258                 *dst++ = *src++;
 259                 src++;
 260         }
 261 }
 262 
 263 static void gm12u320_copy_fb_to_blocks(struct gm12u320_device *gm12u320)
 264 {
 265         int block, dst_offset, len, remain, ret, x1, x2, y1, y2;
 266         struct drm_framebuffer *fb;
 267         void *vaddr;
 268         u8 *src;
 269 
 270         mutex_lock(&gm12u320->fb_update.lock);
 271 
 272         if (!gm12u320->fb_update.fb)
 273                 goto unlock;
 274 
 275         fb = gm12u320->fb_update.fb;
 276         x1 = gm12u320->fb_update.rect.x1;
 277         x2 = gm12u320->fb_update.rect.x2;
 278         y1 = gm12u320->fb_update.rect.y1;
 279         y2 = gm12u320->fb_update.rect.y2;
 280 
 281         vaddr = drm_gem_shmem_vmap(fb->obj[0]);
 282         if (IS_ERR(vaddr)) {
 283                 GM12U320_ERR("failed to vmap fb: %ld\n", PTR_ERR(vaddr));
 284                 goto put_fb;
 285         }
 286 
 287         if (fb->obj[0]->import_attach) {
 288                 ret = dma_buf_begin_cpu_access(
 289                         fb->obj[0]->import_attach->dmabuf, DMA_FROM_DEVICE);
 290                 if (ret) {
 291                         GM12U320_ERR("dma_buf_begin_cpu_access err: %d\n", ret);
 292                         goto vunmap;
 293                 }
 294         }
 295 
 296         src = vaddr + y1 * fb->pitches[0] + x1 * 4;
 297 
 298         x1 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
 299         x2 += (GM12U320_REAL_WIDTH - GM12U320_USER_WIDTH) / 2;
 300 
 301         for (; y1 < y2; y1++) {
 302                 remain = 0;
 303                 len = (x2 - x1) * 3;
 304                 dst_offset = (y1 * GM12U320_REAL_WIDTH + x1) * 3;
 305                 block = dst_offset / DATA_BLOCK_CONTENT_SIZE;
 306                 dst_offset %= DATA_BLOCK_CONTENT_SIZE;
 307 
 308                 if ((dst_offset + len) > DATA_BLOCK_CONTENT_SIZE) {
 309                         remain = dst_offset + len - DATA_BLOCK_CONTENT_SIZE;
 310                         len = DATA_BLOCK_CONTENT_SIZE - dst_offset;
 311                 }
 312 
 313                 dst_offset += DATA_BLOCK_HEADER_SIZE;
 314                 len /= 3;
 315 
 316                 gm12u320_32bpp_to_24bpp_packed(
 317                         gm12u320->data_buf[block] + dst_offset,
 318                         src, len);
 319 
 320                 if (remain) {
 321                         block++;
 322                         dst_offset = DATA_BLOCK_HEADER_SIZE;
 323                         gm12u320_32bpp_to_24bpp_packed(
 324                                 gm12u320->data_buf[block] + dst_offset,
 325                                 src + len * 4, remain / 3);
 326                 }
 327                 src += fb->pitches[0];
 328         }
 329 
 330         if (fb->obj[0]->import_attach) {
 331                 ret = dma_buf_end_cpu_access(fb->obj[0]->import_attach->dmabuf,
 332                                              DMA_FROM_DEVICE);
 333                 if (ret)
 334                         GM12U320_ERR("dma_buf_end_cpu_access err: %d\n", ret);
 335         }
 336 vunmap:
 337         drm_gem_shmem_vunmap(fb->obj[0], vaddr);
 338 put_fb:
 339         drm_framebuffer_put(fb);
 340         gm12u320->fb_update.fb = NULL;
 341 unlock:
 342         mutex_unlock(&gm12u320->fb_update.lock);
 343 }
 344 
 345 static void gm12u320_fb_update_work(struct work_struct *work)
 346 {
 347         struct gm12u320_device *gm12u320 =
 348                 container_of(work, struct gm12u320_device, fb_update.work);
 349         int draw_status_timeout = FIRST_FRAME_TIMEOUT;
 350         int block, block_size, len;
 351         int frame = 0;
 352         int ret = 0;
 353 
 354         while (gm12u320->fb_update.run) {
 355                 gm12u320_copy_fb_to_blocks(gm12u320);
 356 
 357                 for (block = 0; block < GM12U320_BLOCK_COUNT; block++) {
 358                         if (block == GM12U320_BLOCK_COUNT - 1)
 359                                 block_size = DATA_LAST_BLOCK_SIZE;
 360                         else
 361                                 block_size = DATA_BLOCK_SIZE;
 362 
 363                         /* Send data command to device */
 364                         memcpy(gm12u320->cmd_buf, cmd_data, CMD_SIZE);
 365                         gm12u320->cmd_buf[8] = block_size & 0xff;
 366                         gm12u320->cmd_buf[9] = block_size >> 8;
 367                         gm12u320->cmd_buf[20] = 0xfc - block * 4;
 368                         gm12u320->cmd_buf[21] = block | (frame << 7);
 369 
 370                         ret = usb_bulk_msg(gm12u320->udev,
 371                                 usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
 372                                 gm12u320->cmd_buf, CMD_SIZE, &len,
 373                                 CMD_TIMEOUT);
 374                         if (ret || len != CMD_SIZE)
 375                                 goto err;
 376 
 377                         /* Send data block to device */
 378                         ret = usb_bulk_msg(gm12u320->udev,
 379                                 usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
 380                                 gm12u320->data_buf[block], block_size,
 381                                 &len, DATA_TIMEOUT);
 382                         if (ret || len != block_size)
 383                                 goto err;
 384 
 385                         /* Read status */
 386                         ret = usb_bulk_msg(gm12u320->udev,
 387                                 usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
 388                                 gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
 389                                 CMD_TIMEOUT);
 390                         if (ret || len != READ_STATUS_SIZE)
 391                                 goto err;
 392                 }
 393 
 394                 /* Send draw command to device */
 395                 memcpy(gm12u320->cmd_buf, cmd_draw, CMD_SIZE);
 396                 ret = usb_bulk_msg(gm12u320->udev,
 397                         usb_sndbulkpipe(gm12u320->udev, DATA_SND_EPT),
 398                         gm12u320->cmd_buf, CMD_SIZE, &len, CMD_TIMEOUT);
 399                 if (ret || len != CMD_SIZE)
 400                         goto err;
 401 
 402                 /* Read status */
 403                 ret = usb_bulk_msg(gm12u320->udev,
 404                         usb_rcvbulkpipe(gm12u320->udev, DATA_RCV_EPT),
 405                         gm12u320->cmd_buf, READ_STATUS_SIZE, &len,
 406                         draw_status_timeout);
 407                 if (ret || len != READ_STATUS_SIZE)
 408                         goto err;
 409 
 410                 draw_status_timeout = CMD_TIMEOUT;
 411                 frame = !frame;
 412 
 413                 /*
 414                  * We must draw a frame every 2s otherwise the projector
 415                  * switches back to showing its logo.
 416                  */
 417                 wait_event_timeout(gm12u320->fb_update.waitq,
 418                                    !gm12u320->fb_update.run ||
 419                                         gm12u320->fb_update.fb != NULL,
 420                                    IDLE_TIMEOUT);
 421         }
 422         return;
 423 err:
 424         /* Do not log errors caused by module unload or device unplug */
 425         if (ret != -ENODEV && ret != -ECONNRESET && ret != -ESHUTDOWN)
 426                 GM12U320_ERR("Frame update error: %d\n", ret);
 427 }
 428 
 429 static void gm12u320_fb_mark_dirty(struct drm_framebuffer *fb,
 430                                    struct drm_rect *dirty)
 431 {
 432         struct gm12u320_device *gm12u320 = fb->dev->dev_private;
 433         struct drm_framebuffer *old_fb = NULL;
 434         bool wakeup = false;
 435 
 436         mutex_lock(&gm12u320->fb_update.lock);
 437 
 438         if (gm12u320->fb_update.fb != fb) {
 439                 old_fb = gm12u320->fb_update.fb;
 440                 drm_framebuffer_get(fb);
 441                 gm12u320->fb_update.fb = fb;
 442                 gm12u320->fb_update.rect = *dirty;
 443                 wakeup = true;
 444         } else {
 445                 struct drm_rect *rect = &gm12u320->fb_update.rect;
 446 
 447                 rect->x1 = min(rect->x1, dirty->x1);
 448                 rect->y1 = min(rect->y1, dirty->y1);
 449                 rect->x2 = max(rect->x2, dirty->x2);
 450                 rect->y2 = max(rect->y2, dirty->y2);
 451         }
 452 
 453         mutex_unlock(&gm12u320->fb_update.lock);
 454 
 455         if (wakeup)
 456                 wake_up(&gm12u320->fb_update.waitq);
 457 
 458         if (old_fb)
 459                 drm_framebuffer_put(old_fb);
 460 }
 461 
 462 static void gm12u320_start_fb_update(struct gm12u320_device *gm12u320)
 463 {
 464         mutex_lock(&gm12u320->fb_update.lock);
 465         gm12u320->fb_update.run = true;
 466         mutex_unlock(&gm12u320->fb_update.lock);
 467 
 468         queue_work(gm12u320->fb_update.workq, &gm12u320->fb_update.work);
 469 }
 470 
 471 static void gm12u320_stop_fb_update(struct gm12u320_device *gm12u320)
 472 {
 473         mutex_lock(&gm12u320->fb_update.lock);
 474         gm12u320->fb_update.run = false;
 475         mutex_unlock(&gm12u320->fb_update.lock);
 476 
 477         wake_up(&gm12u320->fb_update.waitq);
 478         cancel_work_sync(&gm12u320->fb_update.work);
 479 
 480         mutex_lock(&gm12u320->fb_update.lock);
 481         if (gm12u320->fb_update.fb) {
 482                 drm_framebuffer_put(gm12u320->fb_update.fb);
 483                 gm12u320->fb_update.fb = NULL;
 484         }
 485         mutex_unlock(&gm12u320->fb_update.lock);
 486 }
 487 
 488 static int gm12u320_set_ecomode(struct gm12u320_device *gm12u320)
 489 {
 490         return gm12u320_misc_request(gm12u320, MISC_REQ_GET_SET_ECO_A,
 491                                      MISC_REQ_GET_SET_ECO_B, 0x01 /* set */,
 492                                      eco_mode ? 0x01 : 0x00, 0x00, 0x01);
 493 }
 494 
 495 /* ------------------------------------------------------------------ */
 496 /* gm12u320 connector                                                 */
 497 
 498 /*
 499  * We use fake EDID info so that userspace know that it is dealing with
 500  * an Acer projector, rather then listing this as an "unknown" monitor.
 501  * Note this assumes this driver is only ever used with the Acer C120, if we
 502  * add support for other devices the vendor and model should be parameterized.
 503  */
 504 static struct edid gm12u320_edid = {
 505         .header         = { 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 },
 506         .mfg_id         = { 0x04, 0x72 },       /* "ACR" */
 507         .prod_code      = { 0x20, 0xc1 },       /* C120h */
 508         .serial         = 0xaa55aa55,
 509         .mfg_week       = 1,
 510         .mfg_year       = 16,
 511         .version        = 1,                    /* EDID 1.3 */
 512         .revision       = 3,                    /* EDID 1.3 */
 513         .input          = 0x08,                 /* Analog input */
 514         .features       = 0x0a,                 /* Pref timing in DTD 1 */
 515         .standard_timings = { { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 },
 516                               { 1, 1 }, { 1, 1 }, { 1, 1 }, { 1, 1 } },
 517         .detailed_timings = { {
 518                 .pixel_clock = 3383,
 519                 /* hactive = 848, hblank = 256 */
 520                 .data.pixel_data.hactive_lo = 0x50,
 521                 .data.pixel_data.hblank_lo = 0x00,
 522                 .data.pixel_data.hactive_hblank_hi = 0x31,
 523                 /* vactive = 480, vblank = 28 */
 524                 .data.pixel_data.vactive_lo = 0xe0,
 525                 .data.pixel_data.vblank_lo = 0x1c,
 526                 .data.pixel_data.vactive_vblank_hi = 0x10,
 527                 /* hsync offset 40 pw 128, vsync offset 1 pw 4 */
 528                 .data.pixel_data.hsync_offset_lo = 0x28,
 529                 .data.pixel_data.hsync_pulse_width_lo = 0x80,
 530                 .data.pixel_data.vsync_offset_pulse_width_lo = 0x14,
 531                 .data.pixel_data.hsync_vsync_offset_pulse_width_hi = 0x00,
 532                 /* Digital separate syncs, hsync+, vsync+ */
 533                 .data.pixel_data.misc = 0x1e,
 534         }, {
 535                 .pixel_clock = 0,
 536                 .data.other_data.type = 0xfd, /* Monitor ranges */
 537                 .data.other_data.data.range.min_vfreq = 59,
 538                 .data.other_data.data.range.max_vfreq = 61,
 539                 .data.other_data.data.range.min_hfreq_khz = 29,
 540                 .data.other_data.data.range.max_hfreq_khz = 32,
 541                 .data.other_data.data.range.pixel_clock_mhz = 4, /* 40 MHz */
 542                 .data.other_data.data.range.flags = 0,
 543                 .data.other_data.data.range.formula.cvt = {
 544                         0xa0, 0x20, 0x20, 0x20, 0x20, 0x20, 0x20 },
 545         }, {
 546                 .pixel_clock = 0,
 547                 .data.other_data.type = 0xfc, /* Model string */
 548                 .data.other_data.data.str.str = {
 549                         'P', 'r', 'o', 'j', 'e', 'c', 't', 'o', 'r', '\n',
 550                         ' ', ' ',  ' ' },
 551         }, {
 552                 .pixel_clock = 0,
 553                 .data.other_data.type = 0xfe, /* Unspecified text / padding */
 554                 .data.other_data.data.str.str = {
 555                         '\n', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ',
 556                         ' ', ' ',  ' ' },
 557         } },
 558         .checksum = 0x13,
 559 };
 560 
 561 static int gm12u320_conn_get_modes(struct drm_connector *connector)
 562 {
 563         drm_connector_update_edid_property(connector, &gm12u320_edid);
 564         return drm_add_edid_modes(connector, &gm12u320_edid);
 565 }
 566 
 567 static const struct drm_connector_helper_funcs gm12u320_conn_helper_funcs = {
 568         .get_modes = gm12u320_conn_get_modes,
 569 };
 570 
 571 static const struct drm_connector_funcs gm12u320_conn_funcs = {
 572         .fill_modes = drm_helper_probe_single_connector_modes,
 573         .destroy = drm_connector_cleanup,
 574         .reset = drm_atomic_helper_connector_reset,
 575         .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
 576         .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 577 };
 578 
 579 static int gm12u320_conn_init(struct gm12u320_device *gm12u320)
 580 {
 581         drm_connector_helper_add(&gm12u320->conn, &gm12u320_conn_helper_funcs);
 582         return drm_connector_init(&gm12u320->dev, &gm12u320->conn,
 583                                   &gm12u320_conn_funcs, DRM_MODE_CONNECTOR_VGA);
 584 }
 585 
 586 /* ------------------------------------------------------------------ */
 587 /* gm12u320 (simple) display pipe                                     */
 588 
 589 static void gm12u320_pipe_enable(struct drm_simple_display_pipe *pipe,
 590                                  struct drm_crtc_state *crtc_state,
 591                                  struct drm_plane_state *plane_state)
 592 {
 593         struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
 594         struct drm_rect rect = { 0, 0, GM12U320_USER_WIDTH, GM12U320_HEIGHT };
 595 
 596         gm12u320_fb_mark_dirty(plane_state->fb, &rect);
 597         gm12u320_start_fb_update(gm12u320);
 598         gm12u320->pipe_enabled = true;
 599 }
 600 
 601 static void gm12u320_pipe_disable(struct drm_simple_display_pipe *pipe)
 602 {
 603         struct gm12u320_device *gm12u320 = pipe->crtc.dev->dev_private;
 604 
 605         gm12u320_stop_fb_update(gm12u320);
 606         gm12u320->pipe_enabled = false;
 607 }
 608 
 609 static void gm12u320_pipe_update(struct drm_simple_display_pipe *pipe,
 610                                  struct drm_plane_state *old_state)
 611 {
 612         struct drm_plane_state *state = pipe->plane.state;
 613         struct drm_crtc *crtc = &pipe->crtc;
 614         struct drm_rect rect;
 615 
 616         if (drm_atomic_helper_damage_merged(old_state, state, &rect))
 617                 gm12u320_fb_mark_dirty(pipe->plane.state->fb, &rect);
 618 
 619         if (crtc->state->event) {
 620                 spin_lock_irq(&crtc->dev->event_lock);
 621                 drm_crtc_send_vblank_event(crtc, crtc->state->event);
 622                 crtc->state->event = NULL;
 623                 spin_unlock_irq(&crtc->dev->event_lock);
 624         }
 625 }
 626 
 627 static const struct drm_simple_display_pipe_funcs gm12u320_pipe_funcs = {
 628         .enable     = gm12u320_pipe_enable,
 629         .disable    = gm12u320_pipe_disable,
 630         .update     = gm12u320_pipe_update,
 631 };
 632 
 633 static const uint32_t gm12u320_pipe_formats[] = {
 634         DRM_FORMAT_XRGB8888,
 635 };
 636 
 637 static const uint64_t gm12u320_pipe_modifiers[] = {
 638         DRM_FORMAT_MOD_LINEAR,
 639         DRM_FORMAT_MOD_INVALID
 640 };
 641 
 642 static void gm12u320_driver_release(struct drm_device *dev)
 643 {
 644         struct gm12u320_device *gm12u320 = dev->dev_private;
 645 
 646         gm12u320_usb_free(gm12u320);
 647         drm_mode_config_cleanup(dev);
 648         drm_dev_fini(dev);
 649         kfree(gm12u320);
 650 }
 651 
 652 DEFINE_DRM_GEM_SHMEM_FOPS(gm12u320_fops);
 653 
 654 static struct drm_driver gm12u320_drm_driver = {
 655         .driver_features = DRIVER_MODESET | DRIVER_GEM | DRIVER_ATOMIC,
 656 
 657         .name            = DRIVER_NAME,
 658         .desc            = DRIVER_DESC,
 659         .date            = DRIVER_DATE,
 660         .major           = DRIVER_MAJOR,
 661         .minor           = DRIVER_MINOR,
 662 
 663         .release         = gm12u320_driver_release,
 664         .fops            = &gm12u320_fops,
 665         DRM_GEM_SHMEM_DRIVER_OPS,
 666 };
 667 
 668 static const struct drm_mode_config_funcs gm12u320_mode_config_funcs = {
 669         .fb_create = drm_gem_fb_create_with_dirty,
 670         .atomic_check = drm_atomic_helper_check,
 671         .atomic_commit = drm_atomic_helper_commit,
 672 };
 673 
 674 static int gm12u320_usb_probe(struct usb_interface *interface,
 675                               const struct usb_device_id *id)
 676 {
 677         struct gm12u320_device *gm12u320;
 678         struct drm_device *dev;
 679         int ret;
 680 
 681         /*
 682          * The gm12u320 presents itself to the system as 2 usb mass-storage
 683          * interfaces, we only care about / need the first one.
 684          */
 685         if (interface->cur_altsetting->desc.bInterfaceNumber != 0)
 686                 return -ENODEV;
 687 
 688         gm12u320 = kzalloc(sizeof(*gm12u320), GFP_KERNEL);
 689         if (gm12u320 == NULL)
 690                 return -ENOMEM;
 691 
 692         gm12u320->udev = interface_to_usbdev(interface);
 693         INIT_WORK(&gm12u320->fb_update.work, gm12u320_fb_update_work);
 694         mutex_init(&gm12u320->fb_update.lock);
 695         init_waitqueue_head(&gm12u320->fb_update.waitq);
 696 
 697         dev = &gm12u320->dev;
 698         ret = drm_dev_init(dev, &gm12u320_drm_driver, &interface->dev);
 699         if (ret) {
 700                 kfree(gm12u320);
 701                 return ret;
 702         }
 703         dev->dev_private = gm12u320;
 704 
 705         drm_mode_config_init(dev);
 706         dev->mode_config.min_width = GM12U320_USER_WIDTH;
 707         dev->mode_config.max_width = GM12U320_USER_WIDTH;
 708         dev->mode_config.min_height = GM12U320_HEIGHT;
 709         dev->mode_config.max_height = GM12U320_HEIGHT;
 710         dev->mode_config.funcs = &gm12u320_mode_config_funcs;
 711 
 712         ret = gm12u320_usb_alloc(gm12u320);
 713         if (ret)
 714                 goto err_put;
 715 
 716         ret = gm12u320_set_ecomode(gm12u320);
 717         if (ret)
 718                 goto err_put;
 719 
 720         ret = gm12u320_conn_init(gm12u320);
 721         if (ret)
 722                 goto err_put;
 723 
 724         ret = drm_simple_display_pipe_init(&gm12u320->dev,
 725                                            &gm12u320->pipe,
 726                                            &gm12u320_pipe_funcs,
 727                                            gm12u320_pipe_formats,
 728                                            ARRAY_SIZE(gm12u320_pipe_formats),
 729                                            gm12u320_pipe_modifiers,
 730                                            &gm12u320->conn);
 731         if (ret)
 732                 goto err_put;
 733 
 734         drm_mode_config_reset(dev);
 735 
 736         usb_set_intfdata(interface, dev);
 737         ret = drm_dev_register(dev, 0);
 738         if (ret)
 739                 goto err_put;
 740 
 741         drm_fbdev_generic_setup(dev, 0);
 742 
 743         return 0;
 744 
 745 err_put:
 746         drm_dev_put(dev);
 747         return ret;
 748 }
 749 
 750 static void gm12u320_usb_disconnect(struct usb_interface *interface)
 751 {
 752         struct drm_device *dev = usb_get_intfdata(interface);
 753         struct gm12u320_device *gm12u320 = dev->dev_private;
 754 
 755         gm12u320_stop_fb_update(gm12u320);
 756         drm_dev_unplug(dev);
 757         drm_dev_put(dev);
 758 }
 759 
 760 static __maybe_unused int gm12u320_suspend(struct usb_interface *interface,
 761                                            pm_message_t message)
 762 {
 763         struct drm_device *dev = usb_get_intfdata(interface);
 764         struct gm12u320_device *gm12u320 = dev->dev_private;
 765 
 766         if (gm12u320->pipe_enabled)
 767                 gm12u320_stop_fb_update(gm12u320);
 768 
 769         return 0;
 770 }
 771 
 772 static __maybe_unused int gm12u320_resume(struct usb_interface *interface)
 773 {
 774         struct drm_device *dev = usb_get_intfdata(interface);
 775         struct gm12u320_device *gm12u320 = dev->dev_private;
 776 
 777         gm12u320_set_ecomode(gm12u320);
 778         if (gm12u320->pipe_enabled)
 779                 gm12u320_start_fb_update(gm12u320);
 780 
 781         return 0;
 782 }
 783 
 784 static const struct usb_device_id id_table[] = {
 785         { USB_DEVICE(0x1de1, 0xc102) },
 786         {},
 787 };
 788 MODULE_DEVICE_TABLE(usb, id_table);
 789 
 790 static struct usb_driver gm12u320_usb_driver = {
 791         .name = "gm12u320",
 792         .probe = gm12u320_usb_probe,
 793         .disconnect = gm12u320_usb_disconnect,
 794         .id_table = id_table,
 795 #ifdef CONFIG_PM
 796         .suspend = gm12u320_suspend,
 797         .resume = gm12u320_resume,
 798         .reset_resume = gm12u320_resume,
 799 #endif
 800 };
 801 
 802 module_usb_driver(gm12u320_usb_driver);
 803 MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
 804 MODULE_LICENSE("GPL");

/* [<][>][^][v][top][bottom][index][help] */