From 81e65296298c80c7fd510f4474bff2af698e0e8b Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Mon, 10 Feb 2014 17:53:33 +0000 Subject: [PATCH] vmwgfx: vmw alpha cursor git-svn-id: svn://kolibrios.org@4570 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/video/drm/vmwgfx/Makefile | 1 + drivers/video/drm/vmwgfx/main.c | 77 +++++++++++---------- drivers/video/drm/vmwgfx/vmwgfx_drv.c | 62 +++++++++-------- drivers/video/drm/vmwgfx/vmwgfx_fifo.c | 12 +++- drivers/video/drm/vmwgfx/vmwgfx_kms.c | 92 ++++++++++++++++---------- 5 files changed, 147 insertions(+), 97 deletions(-) diff --git a/drivers/video/drm/vmwgfx/Makefile b/drivers/video/drm/vmwgfx/Makefile index 2a3974ab4a..bd64888fda 100644 --- a/drivers/video/drm/vmwgfx/Makefile +++ b/drivers/video/drm/vmwgfx/Makefile @@ -62,6 +62,7 @@ NAME_SRC= \ ../ttm/ttm_bo.c \ ../ttm/ttm_bo_manager.c \ ../ttm/ttm_execbuf_util.c \ + ../ttm/ttm_lock.c \ ../ttm/ttm_memory.c \ ../ttm/ttm_object.c \ ../ttm/ttm_page_alloc.c \ diff --git a/drivers/video/drm/vmwgfx/main.c b/drivers/video/drm/vmwgfx/main.c index 32ec8a380c..06df5cb27e 100644 --- a/drivers/video/drm/vmwgfx/main.c +++ b/drivers/video/drm/vmwgfx/main.c @@ -98,19 +98,13 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline) if( cmdline && *cmdline ) parse_cmdline(cmdline, log); - if(!dbg_open(log)) + if( *log && !dbg_open(log)) { - strcpy(log, "/tmp1/1/vmw.log"); -// strcpy(log, "/RD/1/DRIVERS/VMW.log"); -// strcpy(log, "/HD0/1/vmw.log"); - - if(!dbg_open(log)) - { printf("Can't open %s\nExit\n", log); return 0; - }; } - dbgprintf(" vmw v3.12-rc6\n cmdline: %s\n", cmdline); + + dbgprintf(" vmw v3.14-rc1\n cmdline: %s\n", cmdline); cpu_detect(); dbgprintf("\ncache line size %d\n", x86_clflush_size); @@ -820,16 +814,10 @@ void print_hex_dump_bytes(const char *prefix_str, int prefix_type, - - - #include "vmwgfx_kms.h" void kms_update(); -//#define iowrite32(v, addr) writel((v), (addr)) - -//#include "bitmap.h" extern struct drm_device *main_device; @@ -842,7 +830,6 @@ typedef struct uint32_t hot_y; struct list_head list; -// struct drm_i915_gem_object *cobj; }cursor_t; #define CURSOR_WIDTH 64 @@ -893,6 +880,37 @@ static int count_connector_modes(struct drm_connector* connector) return count; }; +static void __stdcall restore_cursor(int x, int y){}; +static void disable_mouse(void) {}; + +static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) +{ + struct drm_crtc *crtc = os_display->crtc; + struct vmw_private *dev_priv = vmw_priv(crtc->dev); + struct vmw_display_unit *du = vmw_crtc_to_du(crtc); + + vmw_cursor_update_position(dev_priv, true, x,y); +}; + +static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) +{ + struct vmw_private *dev_priv = vmw_priv(os_display->ddev); + cursor_t *old; + + old = os_display->cursor; + os_display->cursor = cursor; + + vmw_cursor_update_image(dev_priv, cursor->data, + 64, 64, cursor->hot_x, cursor->hot_y); + +// vmw_cursor_update_position(dev_priv, true, +// du->cursor_x + du->hotspot_x, +// du->cursor_y + du->hotspot_y); + + return old; +}; + + int kms_init(struct drm_device *dev) { struct drm_connector *connector; @@ -943,27 +961,14 @@ int kms_init(struct drm_device *dev) os_display->connector = connector; os_display->crtc = crtc; os_display->supported_modes = mode_count; -// os_display->update = kms_update; -// struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); - -// list_for_each_entry(cursor, &os_display->cursors, list) -// { -// init_cursor(cursor); -// }; - -// os_display->restore_cursor(0,0); -// os_display->init_cursor = init_cursor; -// os_display->select_cursor = select_cursor_kms; -// os_display->show_cursor = NULL; -// os_display->move_cursor = move_cursor_kms; -// os_display->restore_cursor = restore_cursor; -// os_display->disable_mouse = disable_mouse; - -// intel_crtc->cursor_x = os_display->width/2; -// intel_crtc->cursor_y = os_display->height/2; - -// select_cursor_kms(os_display->cursor); + os_display->restore_cursor(0,0); + os_display->select_cursor = select_cursor_kms; + os_display->show_cursor = NULL; + os_display->move_cursor = move_cursor_kms; + os_display->restore_cursor = restore_cursor; + os_display->disable_mouse = disable_mouse; + select_cursor_kms(os_display->cursor); }; safe_sti(ifl); diff --git a/drivers/video/drm/vmwgfx/vmwgfx_drv.c b/drivers/video/drm/vmwgfx/vmwgfx_drv.c index 75c2856ba9..f566d804d8 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_drv.c @@ -390,8 +390,6 @@ int vmw_3d_resource_inc(struct vmw_private *dev_priv, { int ret = 0; - ENTER(); - mutex_lock(&dev_priv->release_mutex); if (unlikely(dev_priv->num_3d_resources++ == 0)) { ret = vmw_request_device(dev_priv); @@ -406,7 +404,6 @@ int vmw_3d_resource_inc(struct vmw_private *dev_priv, } mutex_unlock(&dev_priv->release_mutex); - LEAVE(); return ret; } @@ -475,6 +472,33 @@ static void vmw_get_initial_size(struct vmw_private *dev_priv) dev_priv->initial_height = height; } +/** + * vmw_dma_select_mode - Determine how DMA mappings should be set up for this + * system. + * + * @dev_priv: Pointer to a struct vmw_private + * + * This functions tries to determine the IOMMU setup and what actions + * need to be taken by the driver to make system pages visible to the + * device. + * If this function decides that DMA is not possible, it returns -EINVAL. + * The driver may then try to disable features of the device that require + * DMA. + */ +static int vmw_dma_select_mode(struct vmw_private *dev_priv) +{ + static const char *names[vmw_dma_map_max] = { + [vmw_dma_phys] = "Using physical TTM page addresses.", + [vmw_dma_alloc_coherent] = "Using coherent TTM pages.", + [vmw_dma_map_populate] = "Keeping DMA mappings.", + [vmw_dma_map_bind] = "Giving up DMA mappings early."}; + + dev_priv->map_mode = vmw_dma_phys; + DRM_INFO("DMA map mode: %s\n", names[dev_priv->map_mode]); + + return 0; +} + /** * vmw_dma_masks - set required page- and dma masks * @@ -510,7 +534,6 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) enum vmw_res_type i; bool refuse_dma = false; - ENTER(); dev_priv = kzalloc(sizeof(*dev_priv), GFP_KERNEL); @@ -564,11 +587,11 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) } dev_priv->capabilities = vmw_read(dev_priv, SVGA_REG_CAPABILITIES); -// ret = vmw_dma_select_mode(dev_priv); -// if (unlikely(ret != 0)) { -// DRM_INFO("Restricting capabilities due to IOMMU setup.\n"); -// refuse_dma = true; -// } + ret = vmw_dma_select_mode(dev_priv); + if (unlikely(ret != 0)) { + DRM_INFO("Restricting capabilities due to IOMMU setup.\n"); + refuse_dma = true; + } dev_priv->vram_size = vmw_read(dev_priv, SVGA_REG_VRAM_SIZE); dev_priv->mmio_size = vmw_read(dev_priv, SVGA_REG_MEM_SIZE); @@ -927,7 +950,7 @@ static void vmw_lastclose(struct drm_device *dev) static void vmw_master_init(struct vmw_master *vmaster) { -// ttm_lock_init(&vmaster->lock); + ttm_lock_init(&vmaster->lock); INIT_LIST_HEAD(&vmaster->fb_surf); mutex_init(&vmaster->fb_surf_mutex); } @@ -1176,14 +1199,12 @@ static int vmw_pm_prepare(struct device *kdev) #endif - static struct drm_driver driver = { .driver_features = DRIVER_HAVE_IRQ | DRIVER_IRQ_SHARED | DRIVER_MODESET, .load = vmw_driver_load, -// .unload = vmw_driver_unload, -// .firstopen = vmw_firstopen, -// .lastclose = vmw_lastclose, +// .unload = vmw_driver_unload, +// .lastclose = vmw_lastclose, .irq_preinstall = vmw_irq_preinstall, .irq_postinstall = vmw_irq_postinstall, // .irq_uninstall = vmw_irq_uninstall, @@ -1193,11 +1214,6 @@ static struct drm_driver driver = { // .disable_vblank = vmw_disable_vblank, // .ioctls = vmw_ioctls, // .num_ioctls = DRM_ARRAY_SIZE(vmw_ioctls), -// .dma_quiescent = NULL, /*vmw_dma_quiescent, */ -// .master_create = vmw_master_create, -// .master_destroy = vmw_master_destroy, -// .master_set = vmw_master_set, -// .master_drop = vmw_master_drop, .open = vmw_driver_open, // .preclose = vmw_preclose, // .postclose = vmw_postclose, @@ -1206,13 +1222,7 @@ static struct drm_driver driver = { // .dumb_map_offset = vmw_dumb_map_offset, // .dumb_destroy = vmw_dumb_destroy, -// .fops = &vmwgfx_driver_fops, -// .name = VMWGFX_DRIVER_NAME, -// .desc = VMWGFX_DRIVER_DESC, -// .date = VMWGFX_DRIVER_DATE, -// .major = VMWGFX_DRIVER_MAJOR, -// .minor = VMWGFX_DRIVER_MINOR, -// .patchlevel = VMWGFX_DRIVER_PATCHLEVEL + }; #if 0 diff --git a/drivers/video/drm/vmwgfx/vmwgfx_fifo.c b/drivers/video/drm/vmwgfx/vmwgfx_fifo.c index d8f7ae485d..b65426c8bf 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_fifo.c @@ -234,7 +234,7 @@ static int vmw_fifo_wait_noirq(struct vmw_private *dev_priv, { int ret = 0; unsigned long end_jiffies = GetTimerTicks() + timeout; - DEFINE_WAIT(__wait); +// DEFINE_WAIT(__wait); DRM_INFO("Fifo wait noirq.\n"); @@ -411,6 +411,8 @@ static void vmw_fifo_res_copy(struct vmw_fifo_state *fifo_state, uint32_t *buffer = (fifo_state->dynamic_buffer != NULL) ? fifo_state->dynamic_buffer : fifo_state->static_buffer; +ENTER(); + if (bytes < chunk_size) chunk_size = bytes; @@ -421,6 +423,8 @@ static void vmw_fifo_res_copy(struct vmw_fifo_state *fifo_state, if (rest) memcpy(fifo_mem + (min >> 2), buffer + (chunk_size >> 2), rest); +LEAVE(); + } static void vmw_fifo_slow_copy(struct vmw_fifo_state *fifo_state, @@ -430,6 +434,7 @@ static void vmw_fifo_slow_copy(struct vmw_fifo_state *fifo_state, { uint32_t *buffer = (fifo_state->dynamic_buffer != NULL) ? fifo_state->dynamic_buffer : fifo_state->static_buffer; +ENTER(); while (bytes > 0) { iowrite32(*buffer++, fifo_mem + (next_cmd >> 2)); @@ -441,6 +446,7 @@ static void vmw_fifo_slow_copy(struct vmw_fifo_state *fifo_state, mb(); bytes -= sizeof(uint32_t); } +LEAVE(); } void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) @@ -452,6 +458,8 @@ void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) uint32_t min = ioread32(fifo_mem + SVGA_FIFO_MIN); bool reserveable = fifo_state->capabilities & SVGA_FIFO_CAP_RESERVE; +// ENTER(); + BUG_ON((bytes & 3) != 0); BUG_ON(bytes > fifo_state->reserved_size); @@ -487,6 +495,8 @@ void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) // up_write(&fifo_state->rwsem); vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); mutex_unlock(&fifo_state->fifo_mutex); + +// LEAVE(); } int vmw_fifo_send_fence(struct vmw_private *dev_priv, uint32_t *seqno) diff --git a/drivers/video/drm/vmwgfx/vmwgfx_kms.c b/drivers/video/drm/vmwgfx/vmwgfx_kms.c index f05ffdb346..6b7d1d1a5f 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_kms.c @@ -40,7 +40,7 @@ struct vmw_clip_rect { * Clip @num_rects number of @rects against @clip storing the * results in @out_rects and the number of passed rects in @out_num. */ -void vmw_clip_cliprects(struct drm_clip_rect *rects, +static void vmw_clip_cliprects(struct drm_clip_rect *rects, int num_rects, struct vmw_clip_rect clip, SVGASignedRect *out_rects, @@ -80,7 +80,6 @@ void vmw_display_unit_cleanup(struct vmw_display_unit *du) drm_connector_cleanup(&du->connector); } -#if 0 /* * Display Unit Cursor functions */ @@ -95,6 +94,8 @@ int vmw_cursor_update_image(struct vmw_private *dev_priv, } *cmd; u32 image_size = width * height * 4; u32 cmd_size = sizeof(*cmd) + image_size; + u32 *dst; + int i, j; if (!image) return -EINVAL; @@ -107,7 +108,17 @@ int vmw_cursor_update_image(struct vmw_private *dev_priv, memset(cmd, 0, sizeof(*cmd)); - memcpy(&cmd[1], image, image_size); + dst = (u32*)&cmd[1]; + + for(i = 0; i < 32; i++) + { + for(j = 0; j < 32; j++) + *dst++ = *image++; + for( ; j < 64; j++) + *dst++ = 0; + } + for(i = 0; i < 64*(64-32); i++) + *image++ = 0; cmd->cmd = cpu_to_le32(SVGA_CMD_DEFINE_ALPHA_CURSOR); cmd->cursor.id = cpu_to_le32(0); @@ -121,6 +132,7 @@ int vmw_cursor_update_image(struct vmw_private *dev_priv, return 0; } +#if 0 int vmw_cursor_update_dmabuf(struct vmw_private *dev_priv, struct vmw_dma_buffer *dmabuf, u32 width, u32 height, @@ -156,7 +168,7 @@ err_unreserve: return ret; } - +#endif void vmw_cursor_update_position(struct vmw_private *dev_priv, bool show, int x, int y) @@ -171,6 +183,7 @@ void vmw_cursor_update_position(struct vmw_private *dev_priv, iowrite32(++count, fifo_mem + SVGA_FIFO_CURSOR_COUNT); } +#if 0 int vmw_du_crtc_cursor_set(struct drm_crtc *crtc, struct drm_file *file_priv, uint32_t handle, uint32_t width, uint32_t height) { @@ -424,21 +437,17 @@ struct vmw_framebuffer_surface { struct drm_master *master; }; -void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer) +static void vmw_framebuffer_surface_destroy(struct drm_framebuffer *framebuffer) { struct vmw_framebuffer_surface *vfbs = vmw_framebuffer_to_vfbs(framebuffer); -// struct vmw_master *vmaster = vmw_master(vfbs->master); + struct vmw_master *vmaster = vmw_master(vfbs->master); -// mutex_lock(&vmaster->fb_surf_mutex); -// list_del(&vfbs->head); -// mutex_unlock(&vmaster->fb_surf_mutex); + mutex_lock(&vmaster->fb_surf_mutex); + list_del(&vfbs->head); + mutex_unlock(&vmaster->fb_surf_mutex); -// drm_master_put(&vfbs->master); -// drm_framebuffer_cleanup(framebuffer); -// vmw_surface_unreference(&vfbs->surface); -// ttm_base_object_unref(&vfbs->base.user_obj); kfree(vfbs); } @@ -590,29 +599,33 @@ out_free_tmp: return ret; } -int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, +static int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, struct drm_file *file_priv, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips) { struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); -// struct vmw_master *vmaster = vmw_master(file_priv->master); + struct vmw_master *vmaster = vmw_master(file_priv->master); struct vmw_framebuffer_surface *vfbs = vmw_framebuffer_to_vfbs(framebuffer); struct drm_clip_rect norect; int ret, inc = 1; -// if (unlikely(vfbs->master != file_priv->master)) -// return -EINVAL; + if (unlikely(vfbs->master != file_priv->master)) + return -EINVAL; /* Require ScreenObject support for 3D */ if (!dev_priv->sou_priv) return -EINVAL; -// ret = ttm_read_lock(&vmaster->lock, true); -// if (unlikely(ret != 0)) -// return ret; + drm_modeset_lock_all(dev_priv->dev); + + ret = ttm_read_lock(&vmaster->lock, true); + if (unlikely(ret != 0)) { + drm_modeset_unlock_all(dev_priv->dev); + return ret; + } if (!num_clips) { num_clips = 1; @@ -629,7 +642,10 @@ int vmw_framebuffer_surface_dirty(struct drm_framebuffer *framebuffer, flags, color, clips, num_clips, inc, NULL); -// ttm_read_unlock(&vmaster->lock); + ttm_read_unlock(&vmaster->lock); + + drm_modeset_unlock_all(dev_priv->dev); + return 0; } @@ -649,7 +665,7 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, struct drm_device *dev = dev_priv->dev; struct vmw_framebuffer_surface *vfbs; enum SVGA3dSurfaceFormat format; -// struct vmw_master *vmaster = vmw_master(file_priv->master); + struct vmw_master *vmaster = vmw_master(file_priv->master); int ret; /* 3D is only supported on HWv8 hosts which supports screen objects */ @@ -722,9 +738,9 @@ static int vmw_kms_new_framebuffer_surface(struct vmw_private *dev_priv, vfbs->base.user_handle = mode_cmd->handle; // vfbs->master = drm_master_get(file_priv->master); -// mutex_lock(&vmaster->fb_surf_mutex); -// list_add_tail(&vfbs->head, &vmaster->fb_surf); -// mutex_unlock(&vmaster->fb_surf_mutex); + mutex_lock(&vmaster->fb_surf_mutex); + list_add_tail(&vfbs->head, &vmaster->fb_surf); + mutex_unlock(&vmaster->fb_surf_mutex); *out = &vfbs->base; @@ -755,7 +771,7 @@ struct vmw_framebuffer_dmabuf { struct vmw_dma_buffer *buffer; }; -void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer) +static void vmw_framebuffer_dmabuf_destroy(struct drm_framebuffer *framebuffer) { struct vmw_framebuffer_dmabuf *vfbd = vmw_framebuffer_to_vfbd(framebuffer); @@ -941,22 +957,26 @@ static int do_dmabuf_dirty_sou(struct drm_file *file_priv, return ret; } -int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, +static int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, struct drm_file *file_priv, unsigned flags, unsigned color, struct drm_clip_rect *clips, unsigned num_clips) { struct vmw_private *dev_priv = vmw_priv(framebuffer->dev); -// struct vmw_master *vmaster = vmw_master(file_priv->master); + struct vmw_master *vmaster = vmw_master(file_priv->master); struct vmw_framebuffer_dmabuf *vfbd = vmw_framebuffer_to_vfbd(framebuffer); struct drm_clip_rect norect; int ret, increment = 1; -// ret = ttm_read_lock(&vmaster->lock, true); -// if (unlikely(ret != 0)) -// return ret; + drm_modeset_lock_all(dev_priv->dev); + + ret = ttm_read_lock(&vmaster->lock, true); + if (unlikely(ret != 0)) { + drm_modeset_unlock_all(dev_priv->dev); + return ret; + } if (!num_clips) { num_clips = 1; @@ -979,7 +999,10 @@ int vmw_framebuffer_dmabuf_dirty(struct drm_framebuffer *framebuffer, clips, num_clips, increment, NULL); } -// ttm_read_unlock(&vmaster->lock); + ttm_read_unlock(&vmaster->lock); + + drm_modeset_unlock_all(dev_priv->dev); + return ret; } @@ -1672,7 +1695,7 @@ void vmw_disable_vblank(struct drm_device *dev, int crtc) * Small shared kms functions. */ -int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, +static int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, struct drm_vmw_rect *rects) { struct drm_device *dev = dev_priv->dev; @@ -1717,7 +1740,8 @@ int vmw_du_update_layout(struct vmw_private *dev_priv, unsigned num, #if 0 int vmw_du_page_flip(struct drm_crtc *crtc, struct drm_framebuffer *fb, - struct drm_pending_vblank_event *event) + struct drm_pending_vblank_event *event, + uint32_t page_flip_flags) { struct vmw_private *dev_priv = vmw_priv(crtc->dev); struct drm_framebuffer *old_fb = crtc->fb;