From 62bf46860340f07261dfe4391f08720a4dd8f1cf Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Wed, 25 Jan 2012 04:04:03 +0000 Subject: [PATCH] beautiful world of hardware accelerated cursors. git-svn-id: svn://kolibrios.org@2338 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/video/drm/i915/i915_drv.c | 163 +----- drivers/video/drm/i915/i915_drv.h | 7 + drivers/video/drm/i915/intel_bios.c | 4 - drivers/video/drm/i915/intel_ringbuffer.c | 6 - drivers/video/drm/i915/kms_display.c | 610 ++++++++++++++++++++++ drivers/video/drm/i915/main.c | 98 +++- 6 files changed, 718 insertions(+), 170 deletions(-) create mode 100644 drivers/video/drm/i915/kms_display.c diff --git a/drivers/video/drm/i915/i915_drv.c b/drivers/video/drm/i915/i915_drv.c index 9c15b17dcd..ff899e85db 100644 --- a/drivers/video/drm/i915/i915_drv.c +++ b/drivers/video/drm/i915/i915_drv.c @@ -46,6 +46,8 @@ #define __read_mostly +int init_display_kms(struct drm_device *dev); + int i915_panel_ignore_lid __read_mostly = 0; @@ -270,165 +272,14 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) ret = i915_driver_load(dev, ent->driver_data ); - { - struct drm_connector *connector; - struct drm_connector_helper_funcs *connector_funcs; + if (ret) + goto err_g4; - struct drm_connector *def_connector = NULL; - struct drm_encoder *encoder; - struct drm_crtc *crtc; + ret = init_display_kms(dev); - struct drm_framebuffer *fb; - char *con_name; - char *enc_name; + if (ret) + goto err_g4; - list_for_each_entry(connector, &dev->mode_config.connector_list, head) - { - if( connector->status != connector_status_connected) - continue; - - connector_funcs = connector->helper_private; - encoder = connector_funcs->best_encoder(connector); - if( encoder == NULL) - { - dbgprintf("CONNECTOR %x ID: %d no active encoders\n", - connector, connector->base.id); - continue; - } - connector->encoder = encoder; - - dbgprintf("CONNECTOR %x ID: %d status %d encoder %x\n crtc %x\n", - connector, connector->base.id, - connector->status, connector->encoder, - encoder->crtc); - - def_connector = connector; - crtc = encoder->crtc; - - break; - }; - - - if(crtc == NULL) - { - struct drm_crtc *tmp_crtc; - int crtc_mask = 1; - - list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) - { - if (encoder->possible_crtcs & crtc_mask) - { - crtc = tmp_crtc; - encoder->crtc = crtc; - break; - }; - crtc_mask <<= 1; - }; - - if(crtc == NULL) - { - dbgprintf("No CRTC for encoder %d\n", encoder->base.id); - goto out; - } - }; - DRM_DEBUG_KMS("[CRTC:%d]\n", crtc->base.id); - - drm_i915_private_t *dev_priv = dev->dev_private; - struct drm_fb_helper *fb_helper = &dev_priv->fbdev->helper; - struct drm_display_mode *mode = NULL, *tmpmode; - - list_for_each_entry(tmpmode, &connector->modes, head) - { - if( (drm_mode_width(tmpmode) == 1024) && - (drm_mode_height(tmpmode) == 768) && - (drm_mode_vrefresh(tmpmode) == 60) ) - { - mode = tmpmode; - goto do_set; - } - }; - if( (mode == NULL) ) - { - list_for_each_entry(tmpmode, &connector->modes, head) - { - if( (drm_mode_width(tmpmode) == 1024) && - (drm_mode_height(tmpmode) == 768) ) - { - mode = tmpmode; - goto do_set; - } - }; - }; - goto out; - -do_set: - { - - typedef struct tag_display display_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; - -}; - - display_t *rdisplay; - - rdisplay = GetDisplay(); - - con_name = drm_get_connector_name(connector); - enc_name = drm_get_encoder_name(encoder); - - dbgprintf("set mode %d %d connector %s encoder %s\n", - 1024, 768, con_name, enc_name); - - fb = fb_helper->fb; - - fb->width = 1024; - fb->height = 768; - fb->pitch = ALIGN(1024* ((32 + 7) / 8), 64); - fb->bits_per_pixel = 32; - fb->depth == 24; - - crtc->fb = fb; - crtc->enabled = true; - - ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb); - - if (ret == true) - { - rdisplay->width = fb->width; - rdisplay->height = fb->height; - rdisplay->pitch = fb->pitch; - rdisplay->vrefresh = drm_mode_vrefresh(mode); - - sysSetScreen(fb->width, fb->height, fb->pitch); - - dbgprintf("new mode %d x %d pitch %d\n", - fb->width, fb->height, fb->pitch); - } - else - DRM_ERROR("failed to set mode %d_%d on crtc %p\n", - fb->width, fb->height, crtc); - }; - }; - -out: - -// if (ret) -// goto err_g4; // if( radeon_modeset ) // init_display_kms(dev->dev_private, &usermode); diff --git a/drivers/video/drm/i915/i915_drv.h b/drivers/video/drm/i915/i915_drv.h index 19bac2e225..3237e85141 100644 --- a/drivers/video/drm/i915/i915_drv.h +++ b/drivers/video/drm/i915/i915_drv.h @@ -1403,5 +1403,12 @@ __i915_write(64, q) #define POSTING_READ(reg) (void)I915_READ_NOTRACE(reg) #define POSTING_READ16(reg) (void)I915_READ16_NOTRACE(reg) +typedef struct +{ + int width; + int height; + int bpp; + int freq; +}videomode_t; #endif diff --git a/drivers/video/drm/i915/intel_bios.c b/drivers/video/drm/i915/intel_bios.c index 86821f7df8..b663781abc 100644 --- a/drivers/video/drm/i915/intel_bios.c +++ b/drivers/video/drm/i915/intel_bios.c @@ -633,8 +633,6 @@ intel_parse_bios(struct drm_device *dev) struct bdb_header *bdb = NULL; u8 __iomem *bios = NULL; - ENTER(); - init_vbt_defaults(dev_priv); /* XXX Should this validation be moved to intel_opregion.c? */ @@ -687,8 +685,6 @@ intel_parse_bios(struct drm_device *dev) if (bios) pci_unmap_rom(pdev, bios); - LEAVE(); - return 0; } diff --git a/drivers/video/drm/i915/intel_ringbuffer.c b/drivers/video/drm/i915/intel_ringbuffer.c index 03b59e0245..c3d1aa45fa 100644 --- a/drivers/video/drm/i915/intel_ringbuffer.c +++ b/drivers/video/drm/i915/intel_ringbuffer.c @@ -141,7 +141,6 @@ u32 intel_ring_get_active_head(struct intel_ring_buffer *ring) return I915_READ(acthd_reg); } - static int init_ring_common(struct intel_ring_buffer *ring) { drm_i915_private_t *dev_priv = ring->dev->dev_private; @@ -295,7 +294,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) int ret = init_ring_common(ring); - if (INTEL_INFO(dev)->gen > 3) { int mode = VS_TIMER_DISPATCH << 16 | VS_TIMER_DISPATCH; if (IS_GEN6(dev) || IS_GEN7(dev)) @@ -1369,7 +1367,3 @@ int intel_init_blt_ring_buffer(struct drm_device *dev) return intel_init_ring_buffer(dev, ring); } - - - - diff --git a/drivers/video/drm/i915/kms_display.c b/drivers/video/drm/i915/kms_display.c new file mode 100644 index 0000000000..e7026847e3 --- /dev/null +++ b/drivers/video/drm/i915/kms_display.c @@ -0,0 +1,610 @@ +#include "drmP.h" +#include "drm.h" +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" + + +#include +#include +#include +#include +#include + +#include + +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; + + 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); +}; + + +static display_t *os_display; + +int init_cursor(cursor_t *cursor); +static cursor_t* __stdcall select_cursor_kms(cursor_t *cursor); +static void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y); + +void __stdcall restore_cursor(int x, int y) +{}; + +void disable_mouse(void) +{}; + +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 init_display_kms(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; + u32_t ifl; + + ENTER(); + + list_for_each_entry(connector, &dev->mode_config.connector_list, head) + { + if( connector->status != connector_status_connected) + continue; + + connector_funcs = connector->helper_private; + encoder = connector_funcs->best_encoder(connector); + if( encoder == NULL) + { + dbgprintf("CONNECTOR %x ID: %d no active encoders\n", + connector, connector->base.id); + continue; + } + connector->encoder = encoder; + + dbgprintf("CONNECTOR %x ID: %d status %d encoder %x\n crtc %x\n", + connector, connector->base.id, + connector->status, connector->encoder, + encoder->crtc); + + crtc = encoder->crtc; + break; + }; + + if(connector == NULL) + { + dbgprintf("No active connectors!\n"); + return -1; + }; + + if(crtc == NULL) + { + struct drm_crtc *tmp_crtc; + int crtc_mask = 1; + + list_for_each_entry(tmp_crtc, &dev->mode_config.crtc_list, head) + { + if (encoder->possible_crtcs & crtc_mask) + { + crtc = tmp_crtc; + encoder->crtc = crtc; + break; + }; + crtc_mask <<= 1; + }; + }; + + if(crtc == NULL) + { + dbgprintf("No CRTC for encoder %d\n", encoder->base.id); + return -1; + }; + + + DRM_DEBUG_KMS("[Select CRTC:%d]\n", crtc->base.id); + + os_display = GetDisplay(); + + os_display->ddev = dev; + os_display->connector = connector; + os_display->crtc = crtc; + + os_display->supported_modes = count_connector_modes(connector); + + + ifl = safe_cli(); + { + 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); + + + LEAVE(); + + return 0; +}; + + +bool set_mode(struct drm_device *dev, struct drm_connector *connector, + videomode_t *reqmode, bool strict) +{ + struct drm_display_mode *mode = NULL, *tmpmode; + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_fb_helper *fb_helper = &dev_priv->fbdev->helper; + + 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_name; + char *enc_name; + + encoder = connector->encoder; + crtc = encoder->crtc; + + con_name = drm_get_connector_name(connector); + enc_name = drm_get_encoder_name(encoder); + + dbgprintf("set mode %d %d connector %s encoder %s\n", + reqmode->width, reqmode->height, con_name, enc_name); + + fb = fb_helper->fb; + + fb->width = reqmode->width; + fb->height = reqmode->height; + fb->pitch = ALIGN(reqmode->width * 4, 64); + fb->bits_per_pixel = 32; + fb->depth == 24; + + crtc->fb = fb; + crtc->enabled = true; + os_display->crtc = crtc; + + ret = drm_crtc_helper_set_mode(crtc, mode, 0, 0, fb); + +// select_cursor_kms(rdisplay->cursor); +// radeon_show_cursor_kms(crtc); + + if (ret == true) + { + os_display->width = fb->width; + os_display->height = fb->height; + os_display->pitch = fb->pitch; + os_display->vrefresh = drm_mode_vrefresh(mode); + + sysSetScreen(fb->width, fb->height, fb->pitch); + + dbgprintf("new mode %d x %d pitch %d\n", + fb->width, fb->height, fb->pitch); + } + else + DRM_ERROR("failed to set mode %d_%d on crtc %p\n", + fb->width, fb->height, crtc); + } + + LEAVE(); + return ret; +}; + + + +int get_videomodes(videomode_t *mode, int *count) +{ + int err = -1; + + ENTER(); + + 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; + }; + LEAVE(); + return err; +}; + +int set_user_mode(videomode_t *mode) +{ + int err = -1; + + ENTER(); + + 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; + }; + + LEAVE(); + return err; +}; + +void __attribute__((regparm(1))) destroy_cursor(cursor_t *cursor) +{ + list_del(&cursor->list); +// radeon_bo_unpin(cursor->robj); +// KernelFree(cursor->data); + __DestroyObject(cursor); +}; + +int init_cursor(cursor_t *cursor) +{ + struct drm_i915_private *dev_priv = os_display->ddev->dev_private; + struct drm_i915_gem_object *obj; + uint32_t *bits; + uint32_t *src; + + int i,j; + int ret; + + ENTER(); + + if (dev_priv->info->cursor_needs_physical) + { + bits = (uint32_t*)KernelAlloc(CURSOR_WIDTH*CURSOR_HEIGHT*4); + if (unlikely(bits == NULL)) + return ENOMEM; + cursor->cobj = (struct drm_i915_gem_object *)GetPgAddr(bits); + } + else + { + obj = i915_gem_alloc_object(os_display->ddev, CURSOR_WIDTH*CURSOR_HEIGHT*4); + if (unlikely(obj == NULL)) + return -ENOMEM; + + ret = i915_gem_object_pin(obj, CURSOR_WIDTH*CURSOR_HEIGHT*4, true); + if (ret) { +// drm_gem_object_unreference(&obj->base); + return ret; + } + +/* You don't need to worry about fragmentation issues. + * GTT space is continuous. I guarantee it. */ + + bits = (u32*)MapIoMem(get_bus_addr() + obj->gtt_offset, + CURSOR_WIDTH*CURSOR_HEIGHT*4, PG_SW); + + if (unlikely(bits == NULL)) + { +// i915_gem_object_unpin(obj); +// drm_gem_object_unreference(&obj->base); + return -ENOMEM; + }; + cursor->cobj = obj; + }; + + src = cursor->data; + + for(i = 0; i < 32; i++) + { + for(j = 0; j < 32; j++) + *bits++ = *src++; + for(j = 32; j < CURSOR_WIDTH; j++) + *bits++ = 0; + } + for(i = 0; i < CURSOR_WIDTH*(CURSOR_HEIGHT-32); i++) + *bits++ = 0; + +// release old cursor + +// KernelFree(cursor->data); + + cursor->data = bits; + + cursor->header.destroy = destroy_cursor; + LEAVE(); + + return 0; +} + + +static void i9xx_update_cursor(struct drm_crtc *crtc, u32 base) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + bool visible = base != 0; + + if (intel_crtc->cursor_visible != visible) { + uint32_t cntl = I915_READ(CURCNTR(pipe)); + if (base) { + cntl &= ~(CURSOR_MODE | MCURSOR_PIPE_SELECT); + cntl |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE; + cntl |= pipe << 28; /* Connect to correct pipe */ + } else { + cntl &= ~(CURSOR_MODE | MCURSOR_GAMMA_ENABLE); + cntl |= CURSOR_MODE_DISABLE; + } + I915_WRITE(CURCNTR(pipe), cntl); + + intel_crtc->cursor_visible = visible; + } + /* and commit changes on next vblank */ + I915_WRITE(CURBASE(pipe), base); +} + +void __stdcall move_cursor_kms(cursor_t *cursor, int x, int y) +{ + struct drm_i915_private *dev_priv = os_display->ddev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); + u32 base, pos; + bool visible; + + int pipe = intel_crtc->pipe; + + intel_crtc->cursor_x = x; + intel_crtc->cursor_y = y; + + x = x - cursor->hot_x; + y = y - cursor->hot_y; + + + pos = 0; + + base = intel_crtc->cursor_addr; + if (x >= os_display->width) + base = 0; + + if (y >= os_display->height) + base = 0; + + if (x < 0) + { + if (x + intel_crtc->cursor_width < 0) + base = 0; + + pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; + x = -x; + } + pos |= x << CURSOR_X_SHIFT; + + if (y < 0) + { + if (y + intel_crtc->cursor_height < 0) + base = 0; + + pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; + y = -y; + } + pos |= y << CURSOR_Y_SHIFT; + + visible = base != 0; + if (!visible && !intel_crtc->cursor_visible) + return; + + I915_WRITE(CURPOS(pipe), pos); +// if (IS_845G(dev) || IS_I865G(dev)) +// i845_update_cursor(crtc, base); +// else + i9xx_update_cursor(os_display->crtc, base); + +}; + + +cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) +{ + struct drm_i915_private *dev_priv = os_display->ddev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(os_display->crtc); + cursor_t *old; + + old = os_display->cursor; + os_display->cursor = cursor; + + if (!dev_priv->info->cursor_needs_physical) + intel_crtc->cursor_addr = cursor->cobj->gtt_offset; + else + intel_crtc->cursor_addr = cursor->cobj; + + intel_crtc->cursor_width = 32; + intel_crtc->cursor_height = 32; + + move_cursor_kms(cursor, intel_crtc->cursor_x, intel_crtc->cursor_y); + return old; +}; + +#if 0 +static void intel_crtc_update_cursor(struct drm_crtc *crtc, + bool on) +{ + struct drm_device *dev = crtc->dev; + struct drm_i915_private *dev_priv = dev->dev_private; + struct intel_crtc *intel_crtc = to_intel_crtc(crtc); + int pipe = intel_crtc->pipe; + int x = intel_crtc->cursor_x; + int y = intel_crtc->cursor_y; + u32 base, pos; + bool visible; + + pos = 0; + + if (on && crtc->enabled && crtc->fb) { + base = intel_crtc->cursor_addr; + if (x > (int) crtc->fb->width) + base = 0; + + if (y > (int) crtc->fb->height) + base = 0; + } else + base = 0; + + if (x < 0) { + if (x + intel_crtc->cursor_width < 0) + base = 0; + + pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; + x = -x; + } + pos |= x << CURSOR_X_SHIFT; + + if (y < 0) { + if (y + intel_crtc->cursor_height < 0) + base = 0; + + pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; + y = -y; + } + pos |= y << CURSOR_Y_SHIFT; + + visible = base != 0; + if (!visible && !intel_crtc->cursor_visible) + return; + + I915_WRITE(CURPOS(pipe), pos); + if (IS_845G(dev) || IS_I865G(dev)) + i845_update_cursor(crtc, base); + else + i9xx_update_cursor(crtc, base); + + if (visible) + intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); +} + +#endif + diff --git a/drivers/video/drm/i915/main.c b/drivers/video/drm/i915/main.c index 655ffe7794..ec859449ef 100644 --- a/drivers/video/drm/i915/main.c +++ b/drivers/video/drm/i915/main.c @@ -1,3 +1,10 @@ +#include "drmP.h" +#include "drm.h" +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" + + #include #include #include @@ -5,10 +12,13 @@ #include #include +int _stdcall display_handler(ioctl_t *io); int init_agp(void); static char log[256]; +int i915_modeset = 1; + u32_t drvEntry(int action, char *cmdline) { struct pci_device_id *ent; @@ -40,16 +50,96 @@ u32_t drvEntry(int action, char *cmdline) err = i915_init(); -// rdev = rdisplay->ddev->dev_private; + if(err) + { + dbgprintf("Epic Fail :(/n"); -// err = RegService("DISPLAY", display_handler); + }; -// if( err != 0) -// dbgprintf("Set DISPLAY handler\n"); + err = RegService("DISPLAY", display_handler); + + if( err != 0) + dbgprintf("Set DISPLAY handler\n"); return err; }; +#define API_VERSION 0x01000100 + +#define SRV_GETVERSION 0 +#define SRV_ENUM_MODES 1 +#define SRV_SET_MODE 2 + +#define SRV_CREATE_VIDEO 9 +#define SRV_BLIT_VIDEO 10 +#define SRV_CREATE_BITMAP 11 + +#define check_input(size) \ + if( unlikely((inp==NULL)||(io->inp_size != (size))) ) \ + break; + +#define check_output(size) \ + if( unlikely((outp==NULL)||(io->out_size != (size))) ) \ + break; + +int _stdcall display_handler(ioctl_t *io) +{ + int retval = -1; + u32_t *inp; + u32_t *outp; + + inp = io->input; + outp = io->output; + + switch(io->io_code) + { + case SRV_GETVERSION: + check_output(4); + *outp = API_VERSION; + retval = 0; + break; + + case SRV_ENUM_MODES: + 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) + 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); + check_input(sizeof(videomode_t)); + if( i915_modeset ) + retval = set_user_mode((videomode_t*)inp); + break; + +/* + case SRV_CREATE_VIDEO: + retval = r600_create_video(inp[0], inp[1], outp); + break; + + case SRV_BLIT_VIDEO: + r600_video_blit( ((uint64_t*)inp)[0], inp[2], inp[3], + inp[4], inp[5], inp[6]); + + retval = 0; + break; + + case SRV_CREATE_BITMAP: + check_input(8); + check_output(4); + retval = create_bitmap(outp, inp[0], inp[1]); + break; +*/ + }; + + return retval; +} + + #define PCI_CLASS_REVISION 0x08 #define PCI_CLASS_DISPLAY_VGA 0x0300 #define PCI_CLASS_BRIDGE_HOST 0x0600