VMware SVGA II: almost useful
git-svn-id: svn://kolibrios.org@4080 a494cfbc-eb01-0410-851d-a64ba20cac60
This commit is contained in:
parent
7097b85f50
commit
a32ea3f480
@ -1,5 +1,4 @@
|
||||
|
||||
|
||||
CC = gcc
|
||||
LD = ld
|
||||
AS = as
|
||||
|
106
drivers/video/drm/vmwgfx/bitmap.h
Normal file
106
drivers/video/drm/vmwgfx/bitmap.h
Normal file
@ -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();
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -634,6 +634,7 @@ static int vmw_driver_load(struct drm_device *dev, unsigned long chipset)
|
||||
// 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");
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -28,10 +28,9 @@
|
||||
#define rmb() asm volatile("lfence" : : : "memory")
|
||||
#define wmb() asm volatile("sfence" : : : "memory")
|
||||
|
||||
#include "vmwgfx_drv.h"
|
||||
#include <drm/drmP.h>
|
||||
#include <drm/ttm/ttm_bo_driver.h>
|
||||
#include "vmwgfx_drv.h"
|
||||
|
||||
|
||||
#define VMW_PPN_SIZE sizeof(unsigned long)
|
||||
|
||||
|
@ -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) },
|
||||
};
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include "vmwgfx_drv.h"
|
||||
|
||||
#define VMWGFX_NUM_DISPLAY_UNITS 8
|
||||
#define VMWGFX_NUM_DISPLAY_UNITS 1
|
||||
|
||||
|
||||
#define vmw_framebuffer_to_vfb(x) \
|
||||
|
@ -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;
|
||||
};
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user