diff --git a/drivers/video/drm/vmwgfx/Makefile b/drivers/video/drm/vmwgfx/Makefile index 9b7a7490c1..926af2a520 100644 --- a/drivers/video/drm/vmwgfx/Makefile +++ b/drivers/video/drm/vmwgfx/Makefile @@ -1,5 +1,4 @@ - CC = gcc LD = ld AS = as diff --git a/drivers/video/drm/vmwgfx/bitmap.h b/drivers/video/drm/vmwgfx/bitmap.h new file mode 100644 index 0000000000..45d9aeb16f --- /dev/null +++ b/drivers/video/drm/vmwgfx/bitmap.h @@ -0,0 +1,106 @@ + +typedef struct tag_object kobj_t; +typedef struct tag_display display_t; + + +struct tag_object +{ + uint32_t magic; + void *destroy; + kobj_t *fd; + kobj_t *bk; + uint32_t pid; +}; + +typedef struct +{ + kobj_t header; + + u32 handle; + char *uaddr; + + u32 pitch; + u32 gaddr; + + u32 width; + u32 height; + u32 max_width; + u32 max_height; + u32 page_count; + u32 max_count; + + u32 format; +// struct drm_i915_gem_object *obj; +}bitmap_t; + + +struct io_call_10 /* SRV_CREATE_SURFACE */ +{ + u32 handle; // ignored + void *data; // ignored + + u32 width; + u32 height; + u32 pitch; // ignored + + u32 max_width; + u32 max_height; + u32 format; // reserved mbz +}; + +struct io_call_12 /* SRV_LOCK_SURFACE */ +{ + u32 handle; + void *data; + u32 pitch; +}; + +struct io_call_14 /* SRV_RESIZE_SURFACE */ +{ + u32 handle; + void *data; + u32 new_width; + u32 new_height; + u32 pitch; +}; + +typedef struct +{ + uint32_t idx; + union + { + uint32_t opt[2]; + struct { + uint32_t max_tex_width; + uint32_t max_tex_height; + }cap1; + }; +}hwcaps_t; + +#define HW_BIT_BLIT (1<<0) /* BGRX blitter */ +#define HW_TEX_BLIT (1<<1) /* stretch blit */ +#define HW_VID_BLIT (1<<2) /* planar and packed video */ + /* 3 - 63 reserved */ +struct context +{ + kobj_t header; + +// struct drm_i915_gem_object *obj; + u32 cmd_buffer; + u32 cmd_offset; + + bitmap_t *mask; + u32 seqno; + int slot; + +}; + +int get_driver_caps(hwcaps_t *caps); +int create_surface(struct drm_device *dev, struct io_call_10 *pbitmap); +int lock_surface(struct io_call_12 *pbitmap); +int resize_surface(struct io_call_14 *pbitmap); + +struct context *get_context(struct drm_device *dev); + +int init_bitmaps(); + diff --git a/drivers/video/drm/vmwgfx/main.c b/drivers/video/drm/vmwgfx/main.c index f4d9c576bb..20c9364bb7 100644 --- a/drivers/video/drm/vmwgfx/main.c +++ b/drivers/video/drm/vmwgfx/main.c @@ -59,7 +59,7 @@ int driver_wq_state; int x86_clflush_size; unsigned int tsc_khz; -int i915_modeset = 1; +int kms_modeset = 1; u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline) { @@ -98,7 +98,6 @@ u32_t __attribute__((externally_visible)) drvEntry(int action, char *cmdline) enum_pci_devices(); err = vmw_init(); - if(err) { dbgprintf("Epic Fail :(\n"); @@ -187,24 +186,25 @@ int _stdcall display_handler(ioctl_t *io) *outp = DISPLAY_VERSION; retval = 0; break; -#if 0 + case SRV_ENUM_MODES: -// dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n", -// inp, io->inp_size, io->out_size ); + dbgprintf("SRV_ENUM_MODES inp %x inp_size %x out_size %x\n", + inp, io->inp_size, io->out_size ); check_output(4); // check_input(*outp * sizeof(videomode_t)); - if( i915_modeset) + if( kms_modeset) retval = get_videomodes((videomode_t*)inp, outp); break; case SRV_SET_MODE: -// dbgprintf("SRV_SET_MODE inp %x inp_size %x\n", -// inp, io->inp_size); + dbgprintf("SRV_SET_MODE inp %x inp_size %x\n", + inp, io->inp_size); check_input(sizeof(videomode_t)); - if( i915_modeset ) + if( kms_modeset ) retval = set_user_mode((videomode_t*)inp); break; +#if 0 case SRV_GET_CAPS: retval = get_driver_caps((hwcaps_t*)inp); break; @@ -810,3 +810,262 @@ 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; + +typedef struct +{ + kobj_t header; + + uint32_t *data; + uint32_t hot_x; + uint32_t hot_y; + + struct list_head list; +// struct drm_i915_gem_object *cobj; +}cursor_t; + +#define CURSOR_WIDTH 64 +#define CURSOR_HEIGHT 64 + +struct tag_display +{ + int x; + int y; + int width; + int height; + int bpp; + int vrefresh; + int pitch; + int lfb; + + int supported_modes; + struct drm_device *ddev; + struct drm_connector *connector; + struct drm_crtc *crtc; + + struct list_head cursors; + + cursor_t *cursor; + int (*init_cursor)(cursor_t*); + cursor_t* (__stdcall *select_cursor)(cursor_t*); + void (*show_cursor)(int show); + void (__stdcall *move_cursor)(cursor_t *cursor, int x, int y); + void (__stdcall *restore_cursor)(int x, int y); + void (*disable_mouse)(void); + u32 mask_seqno; + u32 check_mouse; + u32 check_m_pixel; + u32 dirty; + void (*update)(void); +}; + +static display_t *os_display; + +static int count_connector_modes(struct drm_connector* connector) +{ + struct drm_display_mode *mode; + int count = 0; + + list_for_each_entry(mode, &connector->modes, head) + { + count++; + }; + return count; +}; + +int kms_init(struct drm_device *dev) +{ + struct drm_connector *connector; + struct drm_connector_helper_funcs *connector_funcs; + struct drm_encoder *encoder; + struct drm_crtc *crtc = NULL; + struct drm_framebuffer *fb; + + cursor_t *cursor; + int mode_count; + u32_t ifl; + int err; + + ENTER(); + + crtc = list_entry(dev->mode_config.crtc_list.next, typeof(*crtc), head); + encoder = list_entry(dev->mode_config.encoder_list.next, typeof(*encoder), head); + connector = list_entry(dev->mode_config.connector_list.next, typeof(*connector), head); + connector->encoder = encoder; + + mode_count = count_connector_modes(connector); + if(mode_count == 0) + { + struct drm_display_mode *mode; + + connector->funcs->fill_modes(connector, + dev->mode_config.max_width, + dev->mode_config.max_height); + + list_for_each_entry(mode, &connector->modes, head) + mode_count++; + }; + + printf("%s %d\n",__FUNCTION__, mode_count); + + DRM_DEBUG_KMS("CONNECTOR %x ID:%d status:%d ENCODER %x CRTC %x ID:%d\n", + connector, connector->base.id, + connector->status, connector->encoder, + crtc, crtc->base.id ); + + DRM_DEBUG_KMS("[Select CRTC:%d]\n", crtc->base.id); + + os_display = GetDisplay(); + + ifl = safe_cli(); + { + os_display->ddev = 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); + }; + safe_sti(ifl); + + main_device = dev; + +#ifdef __HWA__ + err = init_bitmaps(); +#endif + + LEAVE(); + + return 0; +}; + + +void kms_update() +{ + struct vmw_private *dev_priv = vmw_priv(main_device); + size_t fifo_size; + int i; + + struct { + uint32_t header; + SVGAFifoCmdUpdate body; + } *cmd; + + fifo_size = sizeof(*cmd); + + cmd = vmw_fifo_reserve(dev_priv, fifo_size); + if (unlikely(cmd == NULL)) { + DRM_ERROR("Fifo reserve failed.\n"); + return; + } + + cmd->header = cpu_to_le32(SVGA_CMD_UPDATE); + cmd->body.x = 0; + cmd->body.y = 0; + cmd->body.width = os_display->width; //cpu_to_le32(clips->x2 - clips->x1); + cmd->body.height = os_display->height; //cpu_to_le32(clips->y2 - clips->y1); + + vmw_fifo_commit(dev_priv, fifo_size); +} + +int get_videomodes(videomode_t *mode, int *count) +{ + int err = -1; + + dbgprintf("mode %x count %d\n", mode, *count); + + if( *count == 0 ) + { + *count = os_display->supported_modes; + err = 0; + } + else if( mode != NULL ) + { + struct drm_display_mode *drmmode; + int i = 0; + + if( *count > os_display->supported_modes) + *count = os_display->supported_modes; + + list_for_each_entry(drmmode, &os_display->connector->modes, head) + { + if( i < *count) + { + mode->width = drm_mode_width(drmmode); + mode->height = drm_mode_height(drmmode); + mode->bpp = 32; + mode->freq = drm_mode_vrefresh(drmmode); + i++; + mode++; + } + else break; + }; + *count = i; + err = 0; + }; + return err; +}; + + +bool set_mode(struct drm_device *dev, struct drm_connector *connector, + videomode_t *reqmode, bool strict); + + +int set_user_mode(videomode_t *mode) +{ + int err = -1; + + dbgprintf("width %d height %d vrefresh %d\n", + mode->width, mode->height, mode->freq); + + if( (mode->width != 0) && + (mode->height != 0) && + (mode->freq != 0 ) && + ( (mode->width != os_display->width) || + (mode->height != os_display->height) || + (mode->freq != os_display->vrefresh) ) ) + { + if( set_mode(os_display->ddev, os_display->connector, mode, true) ) + err = 0; + }; + + return err; +}; + diff --git a/drivers/video/drm/vmwgfx/vmwgfx_drv.c b/drivers/video/drm/vmwgfx/vmwgfx_drv.c index 240356f5bd..65bf4ebf71 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_drv.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_drv.c @@ -627,13 +627,14 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset) if (unlikely(ret != 0)) goto out_no_kms; - if (dev_priv->enable_fb) { + if (dev_priv->enable_fb) { ret = vmw_3d_resource_inc(dev_priv, true); if (unlikely(ret != 0)) goto out_no_fifo; // vmw_fb_init(dev_priv); - } + } + LEAVE(); return 0; out_no_fifo: @@ -962,6 +963,122 @@ static void vmw_master_drop(struct drm_device *dev, vmw_fb_on(dev_priv); } + +static void vmw_remove(struct pci_dev *pdev) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + + drm_put_dev(dev); +} + +static int vmwgfx_pm_notifier(struct notifier_block *nb, unsigned long val, + void *ptr) +{ + struct vmw_private *dev_priv = + container_of(nb, struct vmw_private, pm_nb); + struct vmw_master *vmaster = dev_priv->active_master; + + switch (val) { + case PM_HIBERNATION_PREPARE: + case PM_SUSPEND_PREPARE: + ttm_suspend_lock(&vmaster->lock); + + /** + * This empties VRAM and unbinds all GMR bindings. + * Buffer contents is moved to swappable memory. + */ + vmw_execbuf_release_pinned_bo(dev_priv); + vmw_resource_evict_all(dev_priv); + ttm_bo_swapout_all(&dev_priv->bdev); + + break; + case PM_POST_HIBERNATION: + case PM_POST_SUSPEND: + case PM_POST_RESTORE: + ttm_suspend_unlock(&vmaster->lock); + + break; + case PM_RESTORE_PREPARE: + break; + default: + break; + } + return 0; +} + +/** + * These might not be needed with the virtual SVGA device. + */ + +static int vmw_pci_suspend(struct pci_dev *pdev, pm_message_t state) +{ + struct drm_device *dev = pci_get_drvdata(pdev); + struct vmw_private *dev_priv = vmw_priv(dev); + + if (dev_priv->num_3d_resources != 0) { + DRM_INFO("Can't suspend or hibernate " + "while 3D resources are active.\n"); + return -EBUSY; + } + + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, PCI_D3hot); + return 0; +} + +static int vmw_pci_resume(struct pci_dev *pdev) +{ + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + return pci_enable_device(pdev); +} + +static int vmw_pm_suspend(struct device *kdev) +{ + struct pci_dev *pdev = to_pci_dev(kdev); + struct pm_message dummy; + + dummy.event = 0; + + return vmw_pci_suspend(pdev, dummy); +} + +static int vmw_pm_resume(struct device *kdev) +{ + struct pci_dev *pdev = to_pci_dev(kdev); + + return vmw_pci_resume(pdev); +} + +static int vmw_pm_prepare(struct device *kdev) +{ + struct pci_dev *pdev = to_pci_dev(kdev); + struct drm_device *dev = pci_get_drvdata(pdev); + struct vmw_private *dev_priv = vmw_priv(dev); + + /** + * Release 3d reference held by fbdev and potentially + * stop fifo. + */ + dev_priv->suspended = true; + if (dev_priv->enable_fb) + vmw_3d_resource_dec(dev_priv, true); + + if (dev_priv->num_3d_resources != 0) { + + DRM_INFO("Can't suspend or hibernate " + "while 3D resources are active.\n"); + + if (dev_priv->enable_fb) + vmw_3d_resource_inc(dev_priv, true); + dev_priv->suspended = false; + return -EBUSY; + } + + return 0; +} + #endif @@ -1005,6 +1122,41 @@ static struct drm_driver driver = { // .patchlevel = VMWGFX_DRIVER_PATCHLEVEL }; + +int vmw_init(void) +{ + static pci_dev_t device; + const struct pci_device_id *ent; + int err; + + ENTER(); + + ent = find_pci_device(&device, vmw_pci_id_list); + if( unlikely(ent == NULL) ) + { + dbgprintf("device not found\n"); + return -ENODEV; + }; + + DRM_INFO("device %x:%x\n", device.pci_dev.vendor, + device.pci_dev.device); + drm_global_init(); + + err = drm_get_dev(&device.pci_dev, ent); + LEAVE(); + + return err; +} + + + +//module_init(vmwgfx_init); +//module_exit(vmwgfx_exit); + +MODULE_AUTHOR("VMware Inc. and others"); +MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device"); +MODULE_LICENSE("GPL and additional rights"); + int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) { static struct drm_device drm_dev; @@ -1066,7 +1218,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto err_g4; -// ret = init_display_kms(dev); + ret = kms_init(dev); if (ret) goto err_g4; @@ -1083,37 +1235,3 @@ err_g4: return ret; } - -int vmw_init(void) -{ - static pci_dev_t device; - const struct pci_device_id *ent; - int err; - - ent = find_pci_device(&device, vmw_pci_id_list); - if( unlikely(ent == NULL) ) - { - dbgprintf("device not found\n"); - return -ENODEV; - }; - - - DRM_INFO("device %x:%x\n", device.pci_dev.vendor, - device.pci_dev.device); - - drm_global_init(); - - err = drm_get_dev(&device.pci_dev, ent); - - return err; -} - - - -//module_init(vmwgfx_init); -//module_exit(vmwgfx_exit); - -MODULE_AUTHOR("VMware Inc. and others"); -MODULE_DESCRIPTION("Standalone drm driver for the VMware SVGA device"); -MODULE_LICENSE("GPL and additional rights"); - diff --git a/drivers/video/drm/vmwgfx/vmwgfx_drv.h b/drivers/video/drm/vmwgfx/vmwgfx_drv.h index aae2088e45..406405ac42 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_drv.h +++ b/drivers/video/drm/vmwgfx/vmwgfx_drv.h @@ -414,7 +414,6 @@ static inline uint32_t vmw_read(struct vmw_private *dev_priv, return val; } - int vmw_3d_resource_inc(struct vmw_private *dev_priv, bool unhide_svga); void vmw_3d_resource_dec(struct vmw_private *dev_priv, bool hide_svga); @@ -783,5 +782,12 @@ static inline struct ttm_mem_global *vmw_mem_glob(struct vmw_private *dev_priv) return (struct ttm_mem_global *) dev_priv->mem_global_ref.object; } +typedef struct +{ + int width; + int height; + int bpp; + int freq; +}videomode_t; #endif diff --git a/drivers/video/drm/vmwgfx/vmwgfx_fifo.c b/drivers/video/drm/vmwgfx/vmwgfx_fifo.c index 0863e7c103..ba50dac335 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_fifo.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_fifo.c @@ -25,9 +25,9 @@ * **************************************************************************/ #define mb() asm volatile("mfence" : : : "memory") -#define rmb() asm volatile("lfence" : : : "memory") -#define wmb() asm volatile("sfence" : : : "memory") - +#define rmb() asm volatile("lfence" : : : "memory") +#define wmb() asm volatile("sfence" : : : "memory") + #include "vmwgfx_drv.h" #include #include @@ -88,9 +88,9 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) uint32_t max; uint32_t min; uint32_t dummy; - + ENTER(); - + fifo->static_buffer_size = VMWGFX_FIFO_STATIC_SIZE; fifo->static_buffer = KernelAlloc(fifo->static_buffer_size); if (unlikely(fifo->static_buffer == NULL)) @@ -148,10 +148,10 @@ int vmw_fifo_init(struct vmw_private *dev_priv, struct vmw_fifo_state *fifo) atomic_set(&dev_priv->marker_seq, dev_priv->last_read_seqno); iowrite32(dev_priv->last_read_seqno, fifo_mem + SVGA_FIFO_FENCE); vmw_marker_queue_init(&fifo->marker_queue); - - int ret = 0; //vmw_fifo_send_fence(dev_priv, &dummy); - LEAVE(); - return ret; + + int ret = 0; //vmw_fifo_send_fence(dev_priv, &dummy); + LEAVE(); + return ret; } void vmw_fifo_ping_host(struct vmw_private *dev_priv, uint32_t reason) @@ -398,7 +398,7 @@ static void vmw_fifo_res_copy(struct vmw_fifo_state *fifo_state, chunk_size = bytes; iowrite32(bytes, fifo_mem + SVGA_FIFO_RESERVED); -// mb(); + mb(); memcpy(fifo_mem + (next_cmd >> 2), buffer, chunk_size); rest = bytes - chunk_size; if (rest) @@ -466,7 +466,7 @@ void vmw_fifo_commit(struct vmw_private *dev_priv, uint32_t bytes) if (reserveable) iowrite32(0, fifo_mem + SVGA_FIFO_RESERVED); -// mb(); + mb(); // up_write(&fifo_state->rwsem); vmw_fifo_ping_host(dev_priv, SVGA_SYNC_GENERIC); mutex_unlock(&fifo_state->fifo_mutex); diff --git a/drivers/video/drm/vmwgfx/vmwgfx_gmr.c b/drivers/video/drm/vmwgfx/vmwgfx_gmr.c index 26e9c8357c..07dd8a7f31 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_gmr.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_gmr.c @@ -28,10 +28,9 @@ #define rmb() asm volatile("lfence" : : : "memory") #define wmb() asm volatile("sfence" : : : "memory") +#include "vmwgfx_drv.h" #include #include -#include "vmwgfx_drv.h" - #define VMW_PPN_SIZE sizeof(unsigned long) diff --git a/drivers/video/drm/vmwgfx/vmwgfx_kms.c b/drivers/video/drm/vmwgfx/vmwgfx_kms.c index 7aa307e6b4..0f81699ff8 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_kms.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_kms.c @@ -1897,6 +1897,10 @@ static struct drm_display_mode vmw_kms_connector_builtin[] = { { DRM_MODE("1856x1392", DRM_MODE_TYPE_DRIVER, 218250, 1856, 1952, 2176, 2528, 0, 1392, 1393, 1396, 1439, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, + 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC), + .vrefresh = 60, }, /* 1920x1200@60Hz */ { DRM_MODE("1920x1200", DRM_MODE_TYPE_DRIVER, 193250, 1920, 2056, 2256, 2592, 0, 1200, 1203, 1209, 1245, 0, @@ -1906,9 +1910,9 @@ static struct drm_display_mode vmw_kms_connector_builtin[] = { 2256, 2600, 0, 1440, 1441, 1444, 1500, 0, DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, /* 2560x1600@60Hz */ - { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, +/* { DRM_MODE("2560x1600", DRM_MODE_TYPE_DRIVER, 348500, 2560, 2752, 3032, 3504, 0, 1600, 1603, 1609, 1658, 0, - DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_PVSYNC) }, */ /* Terminate */ { DRM_MODE("", 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0) }, }; diff --git a/drivers/video/drm/vmwgfx/vmwgfx_kms.h b/drivers/video/drm/vmwgfx/vmwgfx_kms.h index 6fa89c9d62..74d7b88e8d 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_kms.h +++ b/drivers/video/drm/vmwgfx/vmwgfx_kms.h @@ -32,7 +32,7 @@ #include #include "vmwgfx_drv.h" -#define VMWGFX_NUM_DISPLAY_UNITS 8 +#define VMWGFX_NUM_DISPLAY_UNITS 1 #define vmw_framebuffer_to_vfb(x) \ diff --git a/drivers/video/drm/vmwgfx/vmwgfx_scrn.c b/drivers/video/drm/vmwgfx/vmwgfx_scrn.c index f26d0e4af6..9ed7123da9 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_scrn.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_scrn.c @@ -100,7 +100,7 @@ static void vmw_sou_add_active(struct vmw_private *vmw_priv, /** * Send the fifo command to create a screen. */ -static int vmw_sou_fifo_create(struct vmw_private *dev_priv, +int vmw_sou_fifo_create(struct vmw_private *dev_priv, struct vmw_screen_object_unit *sou, uint32_t x, uint32_t y, struct drm_display_mode *mode) @@ -114,7 +114,9 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv, SVGAScreenObject obj; } *cmd; - BUG_ON(!sou->buffer); +// BUG_ON(!sou->buffer); + + ENTER(); fifo_size = sizeof(*cmd); cmd = vmw_fifo_reserve(dev_priv, fifo_size); @@ -141,13 +143,18 @@ static int vmw_sou_fifo_create(struct vmw_private *dev_priv, } /* Ok to assume that buffer is pinned in vram */ - vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr); +// vmw_bo_get_guest_ptr(&sou->buffer->base, &cmd->obj.backingStore.ptr); + + cmd->obj.backingStore.ptr.gmrId = SVGA_GMR_FRAMEBUFFER; + cmd->obj.backingStore.ptr.offset = 0; cmd->obj.backingStore.pitch = mode->hdisplay * 4; vmw_fifo_commit(dev_priv, fifo_size); sou->defined = true; + LEAVE(); + return 0; } @@ -437,6 +444,8 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) struct drm_encoder *encoder; struct drm_crtc *crtc; + ENTER(); + sou = kzalloc(sizeof(*sou), GFP_KERNEL); if (!sou) return -ENOMEM; @@ -471,7 +480,7 @@ static int vmw_sou_init(struct vmw_private *dev_priv, unsigned unit) drm_object_attach_property(&connector->base, dev->mode_config.dirty_info_property, 1); - + LEAVE(); return 0; } @@ -572,3 +581,164 @@ void vmw_kms_screen_object_update_implicit_fb(struct vmw_private *dev_priv, dev_priv->sou_priv->implicit_fb = vmw_framebuffer_to_vfb(sou->base.crtc.fb); } + +#include "bitmap.h" + +typedef struct +{ + kobj_t header; + + uint32_t *data; + uint32_t hot_x; + uint32_t hot_y; + + struct list_head list; +// struct drm_i915_gem_object *cobj; +}cursor_t; + + +struct tag_display +{ + int x; + int y; + int width; + int height; + int bpp; + int vrefresh; + int pitch; + int lfb; + + int supported_modes; + struct drm_device *ddev; + struct drm_connector *connector; + struct drm_crtc *crtc; + + struct list_head cursors; + + cursor_t *cursor; + int (*init_cursor)(cursor_t*); + cursor_t* (__stdcall *select_cursor)(cursor_t*); + void (*show_cursor)(int show); + void (__stdcall *move_cursor)(cursor_t *cursor, int x, int y); + void (__stdcall *restore_cursor)(int x, int y); + void (*disable_mouse)(void); + u32 mask_seqno; + u32 check_mouse; + u32 check_m_pixel; + u32 dirty; + void (*update)(void); +}; + +extern struct drm_device *main_device; + +bool set_mode(struct drm_device *dev, struct drm_connector *connector, + videomode_t *reqmode, bool strict) +{ + struct drm_display_mode *mode = NULL, *tmpmode; + struct vmw_private *dev_priv = vmw_priv(main_device); + struct vmw_screen_object_unit *sou; + display_t *os_display; + + bool ret = false; + + ENTER(); + +// dbgprintf("width %d height %d vrefresh %d\n", +// reqmode->width, reqmode->height, reqmode->freq); + + list_for_each_entry(tmpmode, &connector->modes, head) + { + if( (drm_mode_width(tmpmode) == reqmode->width) && + (drm_mode_height(tmpmode) == reqmode->height) && + (drm_mode_vrefresh(tmpmode) == reqmode->freq) ) + { + mode = tmpmode; + goto do_set; + } + }; + + if( (mode == NULL) && (strict == false) ) + { + list_for_each_entry(tmpmode, &connector->modes, head) + { + if( (drm_mode_width(tmpmode) == reqmode->width) && + (drm_mode_height(tmpmode) == reqmode->height) ) + { + mode = tmpmode; + goto do_set; + } + }; + }; + +do_set: + + if( mode != NULL ) + { + struct drm_framebuffer *fb; + struct drm_encoder *encoder; + struct drm_crtc *crtc; + +// char con_edid[128]; + const char *con_name; + const char *enc_name; + + encoder = connector->encoder; + crtc = encoder->crtc; + + +// fb = list_first_entry(&dev->mode_config.fb_kernel_list, +// struct drm_framebuffer, filp_head); + +// memcpy(con_edid, connector->edid_blob_ptr->data, 128); + +// dbgprintf("Manufacturer: %s Model %x Serial Number %u\n", +// manufacturer_name(con_edid + 0x08), +// (unsigned short)(con_edid[0x0A] + (con_edid[0x0B] << 8)), +// (unsigned int)(con_edid[0x0C] + (con_edid[0x0D] << 8) +// + (con_edid[0x0E] << 16) + (con_edid[0x0F] << 24))); + + con_name = drm_get_connector_name(connector); + enc_name = drm_get_encoder_name(encoder); + + dbgprintf("set mode %d %d connector %s encoder %s\n", + mode->hdisplay, mode->vdisplay, con_name, enc_name); + + os_display = GetDisplay(); + +#if 0 + sou = vmw_crtc_to_sou(crtc); + sou->defined = true; + + ret = vmw_sou_fifo_destroy(dev_priv, sou); + if (unlikely(ret != 0)) + return ret; + + ret = vmw_sou_fifo_create(dev_priv, sou, 0, 0, mode); + +#else /* sledgehammer */ + + vmw_write(dev_priv,SVGA_REG_WIDTH, mode->hdisplay); + vmw_write(dev_priv,SVGA_REG_HEIGHT, mode->vdisplay); + vmw_write(dev_priv,SVGA_REG_BITS_PER_PIXEL, 32); + ret = 0; +#endif + if (ret == 0) + { + os_display->width = mode->hdisplay; + os_display->height = mode->vdisplay; + os_display->pitch = mode->hdisplay*4; + os_display->vrefresh = drm_mode_vrefresh(mode); + + sysSetScreen(os_display->width, os_display->height, os_display->pitch); + + dbgprintf("new mode %d x %d pitch %d\n", + os_display->width, os_display->height, os_display->pitch); + } + else + DRM_ERROR("failed to set mode %d_%d on crtc %p\n", + os_display->width, os_display->height, crtc); + } + + LEAVE(); + return ret; +}; diff --git a/drivers/video/drm/vmwgfx/vmwgfx_ttm_glue.c b/drivers/video/drm/vmwgfx/vmwgfx_ttm_glue.c index 1d71a0aac8..0f4807000b 100644 --- a/drivers/video/drm/vmwgfx/vmwgfx_ttm_glue.c +++ b/drivers/video/drm/vmwgfx/vmwgfx_ttm_glue.c @@ -92,7 +92,6 @@ int vmw_ttm_global_init(struct vmw_private *dev_priv) LEAVE(); return 0; - out_no_bo: drm_global_item_unref(&dev_priv->mem_global_ref); return ret;