From 92aec6604dde915dd649499e97e7cee832b2de50 Mon Sep 17 00:00:00 2001 From: "Sergey Semyonov (Serge)" Date: Mon, 30 Jan 2012 07:06:25 +0000 Subject: [PATCH] blitter git-svn-id: svn://kolibrios.org@2340 a494cfbc-eb01-0410-851d-a64ba20cac60 --- drivers/video/drm/i915/Gtt/intel-agp.c | 35 ++++ drivers/video/drm/i915/bitmap.c | 224 +++++++++++++++++++++ drivers/video/drm/i915/bitmap.h | 59 ++++++ drivers/video/drm/i915/i915_drv.c | 9 +- drivers/video/drm/i915/i915_drv.h | 16 +- drivers/video/drm/i915/i915_gem.c | 15 +- drivers/video/drm/i915/i915_gem_gtt.c | 3 +- drivers/video/drm/i915/intel_display.c | 11 +- drivers/video/drm/i915/intel_ringbuffer.c | 71 +++---- drivers/video/drm/i915/intel_sdvo.c | 21 ++ drivers/video/drm/i915/kms_display.c | 231 ++++++++++++++++------ drivers/video/drm/i915/main.c | 64 +++++- 12 files changed, 619 insertions(+), 140 deletions(-) create mode 100644 drivers/video/drm/i915/bitmap.c create mode 100644 drivers/video/drm/i915/bitmap.h diff --git a/drivers/video/drm/i915/Gtt/intel-agp.c b/drivers/video/drm/i915/Gtt/intel-agp.c index d47573858b..8848ed66c4 100644 --- a/drivers/video/drm/i915/Gtt/intel-agp.c +++ b/drivers/video/drm/i915/Gtt/intel-agp.c @@ -19,6 +19,10 @@ #define __devinit #define PCI_VENDOR_ID_INTEL 0x8086 +#define PCI_DEVICE_ID_INTEL_82915G_HB 0x2580 +#define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 +#define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 +#define PCI_DEVICE_ID_INTEL_82945GM_HB 0x27A0 int intel_gmch_probe(struct pci_dev *pdev, @@ -80,9 +84,40 @@ static struct pci_device_id agp_intel_pci_table[] = { .subvendor = PCI_ANY_ID, \ .subdevice = PCI_ANY_ID, \ } + ID(PCI_DEVICE_ID_INTEL_E7221_HB), + ID(PCI_DEVICE_ID_INTEL_82915G_HB), + ID(PCI_DEVICE_ID_INTEL_82915GM_HB), + ID(PCI_DEVICE_ID_INTEL_82945G_HB), + ID(PCI_DEVICE_ID_INTEL_82945GM_HB), + ID(PCI_DEVICE_ID_INTEL_82945GME_HB), + ID(PCI_DEVICE_ID_INTEL_PINEVIEW_M_HB), + ID(PCI_DEVICE_ID_INTEL_PINEVIEW_HB), + ID(PCI_DEVICE_ID_INTEL_82946GZ_HB), + ID(PCI_DEVICE_ID_INTEL_82G35_HB), + ID(PCI_DEVICE_ID_INTEL_82965Q_HB), + ID(PCI_DEVICE_ID_INTEL_82965G_HB), + ID(PCI_DEVICE_ID_INTEL_82965GM_HB), + ID(PCI_DEVICE_ID_INTEL_82965GME_HB), + ID(PCI_DEVICE_ID_INTEL_G33_HB), + ID(PCI_DEVICE_ID_INTEL_Q35_HB), + ID(PCI_DEVICE_ID_INTEL_Q33_HB), + ID(PCI_DEVICE_ID_INTEL_GM45_HB), + ID(PCI_DEVICE_ID_INTEL_EAGLELAKE_HB), + ID(PCI_DEVICE_ID_INTEL_Q45_HB), + ID(PCI_DEVICE_ID_INTEL_G45_HB), + ID(PCI_DEVICE_ID_INTEL_G41_HB), + ID(PCI_DEVICE_ID_INTEL_B43_HB), + ID(PCI_DEVICE_ID_INTEL_B43_1_HB), + ID(PCI_DEVICE_ID_INTEL_IRONLAKE_D_HB), + ID(PCI_DEVICE_ID_INTEL_IRONLAKE_M_HB), + ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MA_HB), + ID(PCI_DEVICE_ID_INTEL_IRONLAKE_MC2_HB), ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_HB), ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_M_HB), ID(PCI_DEVICE_ID_INTEL_SANDYBRIDGE_S_HB), + ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_HB), + ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_M_HB), + ID(PCI_DEVICE_ID_INTEL_IVYBRIDGE_S_HB), { } }; diff --git a/drivers/video/drm/i915/bitmap.c b/drivers/video/drm/i915/bitmap.c new file mode 100644 index 0000000000..9780fba3da --- /dev/null +++ b/drivers/video/drm/i915/bitmap.c @@ -0,0 +1,224 @@ + +#include +#include +#include "i915_drm.h" +#include "i915_drv.h" +#include "intel_drv.h" +#include "bitmap.h" + +extern struct drm_device *main_device; + +struct hman bm_man; + +int init_bitmaps() +{ + int ret; + + ret = init_hman(&bm_man, 1024); + + return ret; +}; + + +int create_bitmap(struct ubitmap *pbitmap, int width, int height) +{ + struct drm_i915_gem_object *obj; + + bitmap_t *bitmap; + u32 handle; + u32 size; + u32 pitch; + void *uaddr; + + int ret; + + pbitmap->handle = 0; + pbitmap->data = NULL; + + if((width==0)||(height==0)||(width>4096)||(height>4096)) + goto err1; + + handle = alloc_handle(&bm_man); + + if(handle == 0) + goto err1; + + bitmap = CreateObject(GetPid(), sizeof(*bitmap)); + if( bitmap == NULL) + goto err1; + + hman_set_data(&bm_man, handle, bitmap); + + pitch = ALIGN(width*4,64); + + size = roundup(pitch*height, PAGE_SIZE); + + obj = i915_gem_alloc_object(main_device, size); + if (obj == NULL) + goto err2; + + ret = i915_gem_object_pin(obj, 4096, true); + if (ret) + goto err3; + + uaddr = UserAlloc(size); + if( uaddr == NULL) + goto err4; + else + { + u32_t *src, *dst; + int count; + +#define page_tabs 0xFDC00000 /* really dirty hack */ + + src = (u32_t*)obj->pages; + dst = &((u32_t*)page_tabs)[(u32_t)uaddr >> 12]; + count = size/4096; + + while(count--) + { + *dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page + }; + } + + bitmap->handle = handle; + bitmap->width = width; + bitmap->height = height; + bitmap->pitch = pitch; + bitmap->gaddr = obj->gtt_offset; + bitmap->uaddr = uaddr; + bitmap->obj = obj; + + pbitmap->handle = handle; + pbitmap->data = uaddr; + return 0; + +err4: +// drm_gem_object_unpin; +err3: +// drm_gem_object_unreference(&obj->base); +err2: + free_handle(&bm_man, handle); + DestroyObject(bitmap); +err1: + return -1; + +}; + + +int create_video(int width, int height, u32_t *outp) +{ + struct drm_i915_gem_object *obj; + + size_t size; + size_t pitch; + void *uaddr; + + int ret; + + if((width==0)||(height==0)||(width>4096)||(height>4096)) + goto err1; + + pitch = ALIGN(width*4,64); + + size = roundup(pitch*height, PAGE_SIZE); + + obj = i915_gem_alloc_object(main_device, size); + if (obj == NULL) + goto err2; + + ret = i915_gem_object_pin(obj, 4096, true); + if (ret) + goto err3; + + uaddr = UserAlloc(size); + if( uaddr == NULL) + goto err4; + else + { + u32_t *src, *dst; + int count; + +#define page_tabs 0xFDC00000 /* really dirty hack */ + + src = (u32_t*)obj->pages; + dst = &((u32_t*)page_tabs)[(u32_t)uaddr >> 12]; + count = size/4096; + + while(count--) + { + *dst++ = (0xFFFFF000 & *src++) | 0x207 ; // map as shared page + }; + } + + outp[0] = obj->gtt_offset; + outp[2] = (u32)uaddr; + outp[3] = pitch; + + return 0; + +err4: +// drm_gem_object_unpin; +err3: +// drm_gem_object_unreference(&obj->base); +err2: +err1: + return -1; +}; + + +int init_hman(struct hman *man, u32 count) +{ + u32* data; + + data = malloc(count*sizeof(u32*)); + if(data) + { + int i; + + for(i=0;i < count-1;) + data[i] = ++i; + data[i] = 0; + + man->table = data; + man->next = 0; + man->avail = count; + man->count = count; + + return 0; + }; + return -ENOMEM; +}; + +u32 alloc_handle(struct hman *man) +{ + u32 handle = 0; + + if(man->avail) + { + handle = man->next; + man->next = man->table[handle]; + man->avail--; + handle++; + } + return handle; +}; + +int free_handle(struct hman *man, u32 handle) +{ + int ret = -1; + + handle--; + + if(handle < man->count) + { + man->table[handle] = man->next; + man->next = handle; + man->avail++; + ret = 0; + }; + + return ret; +}; + + diff --git a/drivers/video/drm/i915/bitmap.h b/drivers/video/drm/i915/bitmap.h new file mode 100644 index 0000000000..0bf7f7924c --- /dev/null +++ b/drivers/video/drm/i915/bitmap.h @@ -0,0 +1,59 @@ + +typedef struct tag_object kobj_t; +typedef struct tag_display display_t; + +struct hman +{ + u32 *table; + u32 next; + u32 avail; + u32 count; +}; + +extern struct hman bm_man; + +int init_hman(struct hman *man, u32 count); +u32 alloc_handle(struct hman *man); +int free_handle(struct hman *man, u32 handle); + +#define hman_get_data(man, handle) \ + ((man)->table[(handle)-1]) + +#define hman_set_data(man, handle, val) \ + ((man)->table[(handle)-1]) = (u32)(val) + + +struct tag_object +{ + uint32_t magic; + void *destroy; + kobj_t *fd; + kobj_t *bk; + uint32_t pid; +}; + +typedef struct +{ + kobj_t header; + + u32 handle; + u32 width; + u32 height; + u32 pitch; + u32 gaddr; + void *uaddr; + struct drm_i915_gem_object *obj; +}bitmap_t; + + +struct ubitmap +{ + u32 width; + u32 height; + u32 pitch; + u32 handle; + void *data; +}; + +int create_bitmap(struct ubitmap *pbitmap, int width, int height); + diff --git a/drivers/video/drm/i915/i915_drv.c b/drivers/video/drm/i915/i915_drv.c index c893d0e2ba..8b8d81848f 100644 --- a/drivers/video/drm/i915/i915_drv.c +++ b/drivers/video/drm/i915/i915_drv.c @@ -47,6 +47,7 @@ int init_display_kms(struct drm_device *dev); +struct drm_device *main_device; int i915_panel_ignore_lid __read_mostly = 0; @@ -375,7 +376,7 @@ int i915_init(void) int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) { - static struct drm_device *dev; + struct drm_device *dev; int ret; ENTER(); @@ -418,11 +419,7 @@ int drm_get_dev(struct pci_dev *pdev, const struct pci_device_id *ent) if (ret) goto err_g4; - -// if( radeon_modeset ) -// init_display_kms(dev->dev_private, &usermode); -// else -// init_display(dev->dev_private, &usermode); + main_device = dev; LEAVE(); diff --git a/drivers/video/drm/i915/i915_drv.h b/drivers/video/drm/i915/i915_drv.h index 3237e85141..121b26cf40 100644 --- a/drivers/video/drm/i915/i915_drv.h +++ b/drivers/video/drm/i915/i915_drv.h @@ -290,8 +290,8 @@ typedef struct drm_i915_private { uint32_t next_seqno; drm_dma_handle_t *status_page_dmah; -// uint32_t counter; -// drm_local_map_t hws_map; + uint32_t counter; + drm_local_map_t hws_map; struct drm_i915_gem_object *pwrctx; struct drm_i915_gem_object *renderctx; @@ -883,7 +883,6 @@ struct drm_i915_gem_object { atomic_t pending_flip; }; - #define to_intel_bo(x) container_of(x, struct drm_i915_gem_object, base) /** @@ -1147,11 +1146,11 @@ int i915_gem_dumb_destroy(struct drm_file *file_priv, struct drm_device *dev, /** * Returns true if seq1 is later than seq2. */ -//static inline bool -//i915_seqno_passed(uint32_t seq1, uint32_t seq2) -//{ -// return (int32_t)(seq1 - seq2) >= 0; -//} +static inline bool +i915_seqno_passed(uint32_t seq1, uint32_t seq2) +{ + return (int32_t)(seq1 - seq2) >= 0; +} static inline u32 i915_gem_next_request_seqno(struct intel_ring_buffer *ring) @@ -1206,7 +1205,6 @@ i915_gem_get_unfenced_gtt_alignment(struct drm_device *dev, int i915_gem_object_set_cache_level(struct drm_i915_gem_object *obj, enum i915_cache_level cache_level); - /* i915_gem_gtt.c */ void i915_gem_restore_gtt_mappings(struct drm_device *dev); int __must_check i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj); diff --git a/drivers/video/drm/i915/i915_gem.c b/drivers/video/drm/i915/i915_gem.c index 2291256871..7de82a75f7 100644 --- a/drivers/video/drm/i915/i915_gem.c +++ b/drivers/video/drm/i915/i915_gem.c @@ -727,8 +727,6 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, int page_count, i; struct page *page; - ENTER(); - /* Get the list of pages out of our struct file. They'll be pinned * at this point until we release them. */ @@ -750,7 +748,7 @@ i915_gem_object_get_pages_gtt(struct drm_i915_gem_object *obj, // if (obj->tiling_mode != I915_TILING_NONE) // i915_gem_object_do_bit_17_swizzle(obj); - LEAVE(); + return 0; @@ -1069,8 +1067,6 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, bool mappable, fenceable; int ret; - ENTER(); - if (obj->madv != I915_MADV_WILLNEED) { DRM_ERROR("Attempting to bind a purgeable object\n"); return -EINVAL; @@ -1197,7 +1193,6 @@ i915_gem_object_bind_to_gtt(struct drm_i915_gem_object *obj, obj->map_and_fenceable = mappable && fenceable; - LEAVE(); // trace_i915_gem_object_bind(obj, map_and_fenceable); return 0; } @@ -1497,8 +1492,6 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, struct drm_i915_private *dev_priv = dev->dev_private; int ret; - ENTER(); - BUG_ON(obj->pin_count == DRM_I915_GEM_OBJECT_MAX_PIN_COUNT); // WARN_ON(i915_verify_lists(dev)); @@ -1534,8 +1527,6 @@ i915_gem_object_pin(struct drm_i915_gem_object *obj, } obj->pin_mappable |= map_and_fenceable; - LEAVE(); - // WARN_ON(i915_verify_lists(dev)); return 0; } @@ -1586,7 +1577,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, { struct drm_i915_private *dev_priv = dev->dev_private; struct drm_i915_gem_object *obj; - ENTER(); + obj = kzalloc(sizeof(*obj), GFP_KERNEL); if (obj == NULL) return NULL; @@ -1629,7 +1620,7 @@ struct drm_i915_gem_object *i915_gem_alloc_object(struct drm_device *dev, obj->madv = I915_MADV_WILLNEED; /* Avoid an unnecessary call to unbind on the first bind. */ obj->map_and_fenceable = true; - LEAVE(); + return obj; } diff --git a/drivers/video/drm/i915/i915_gem_gtt.c b/drivers/video/drm/i915/i915_gem_gtt.c index 6a75e8ee97..5509921c29 100644 --- a/drivers/video/drm/i915/i915_gem_gtt.c +++ b/drivers/video/drm/i915/i915_gem_gtt.c @@ -80,7 +80,6 @@ int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj) unsigned int agp_type = cache_level_to_agp_type(dev, obj->cache_level); int ret; - ENTER(); // if (dev_priv->mm.gtt->needs_dmar) { // ret = intel_gtt_map_memory(obj->pages, // obj->base.size >> PAGE_SHIFT, @@ -98,7 +97,7 @@ int i915_gem_gtt_bind_object(struct drm_i915_gem_object *obj) obj->base.size >> PAGE_SHIFT, obj->pages, agp_type); - LEAVE(); + return 0; } diff --git a/drivers/video/drm/i915/intel_display.c b/drivers/video/drm/i915/intel_display.c index 690ef4b872..1e4d1b1267 100644 --- a/drivers/video/drm/i915/intel_display.c +++ b/drivers/video/drm/i915/intel_display.c @@ -2196,7 +2196,6 @@ intel_pipe_set_base(struct drm_crtc *crtc, int x, int y, return 0; #if 0 - if (!dev->primary->master) { LEAVE(); @@ -3203,6 +3202,7 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) dev_priv->display.dpms(crtc, mode); +#if 0 if (!dev->primary->master) return; @@ -3225,6 +3225,8 @@ static void intel_crtc_dpms(struct drm_crtc *crtc, int mode) DRM_ERROR("Can't update pipe %c in SAREA\n", pipe_name(pipe)); break; } +#endif + } static void intel_crtc_disable(struct drm_crtc *crtc) @@ -6365,8 +6367,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) struct intel_crtc *intel_crtc; int i; - ENTER(); - intel_crtc = kzalloc(sizeof(struct intel_crtc) + (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)), GFP_KERNEL); if (intel_crtc == NULL) return; @@ -6409,8 +6409,6 @@ static void intel_crtc_init(struct drm_device *dev, int pipe) intel_crtc->busy = false; - LEAVE(); - // setup_timer(&intel_crtc->idle_timer, intel_crtc_idle_timer, // (unsigned long)intel_crtc); } @@ -6736,9 +6734,6 @@ void ironlake_enable_drps(struct drm_device *dev) - - - static unsigned long intel_pxfreq(u32 vidfreq) { unsigned long freq; diff --git a/drivers/video/drm/i915/intel_ringbuffer.c b/drivers/video/drm/i915/intel_ringbuffer.c index d73de58b8f..b0a7128361 100644 --- a/drivers/video/drm/i915/intel_ringbuffer.c +++ b/drivers/video/drm/i915/intel_ringbuffer.c @@ -147,8 +147,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) struct drm_i915_gem_object *obj = ring->obj; u32 head; - ENTER(); - /* Stop the ring if it's running. */ I915_WRITE_CTL(ring, 0); I915_WRITE_HEAD(ring, 0); @@ -203,7 +201,6 @@ static int init_ring_common(struct intel_ring_buffer *ring) ring->tail = I915_READ_TAIL(ring) & TAIL_ADDR; ring->space = ring_space(ring); - LEAVE(); return 0; } @@ -285,9 +282,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) { struct drm_device *dev = ring->dev; struct drm_i915_private *dev_priv = dev->dev_private; - - ENTER(); - int ret = init_ring_common(ring); if (INTEL_INFO(dev)->gen > 3) { @@ -308,8 +302,6 @@ static int init_render_ring(struct intel_ring_buffer *ring) return ret; } - LEAVE(); - return ret; } @@ -561,6 +553,7 @@ render_ring_put_irq(struct intel_ring_buffer *ring) } spin_unlock(&ring->irq_lock); } +#endif void intel_ring_setup_status_page(struct intel_ring_buffer *ring) { @@ -592,7 +585,6 @@ void intel_ring_setup_status_page(struct intel_ring_buffer *ring) I915_WRITE(mmio, (u32)ring->status_page.gfx_addr); POSTING_READ(mmio); } -#endif static int bsd_ring_flush(struct intel_ring_buffer *ring, @@ -706,6 +698,7 @@ bsd_ring_put_irq(struct intel_ring_buffer *ring) } spin_unlock(&ring->irq_lock); } +#endif static int ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 length) @@ -793,7 +786,7 @@ static int init_status_page(struct intel_ring_buffer *ring) goto err; } -// i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); +// i915_gem_object_set_cache_level(obj, I915_CACHE_LLC); ret = i915_gem_object_pin(obj, 4096, true); if (ret != 0) { @@ -801,7 +794,7 @@ static int init_status_page(struct intel_ring_buffer *ring) } ring->status_page.gfx_addr = obj->gtt_offset; - ring->status_page.page_addr = kmap(obj->pages[0]); + ring->status_page.page_addr = MapIoMem(obj->pages[0], 4096, PG_SW); if (ring->status_page.page_addr == NULL) { memset(&dev_priv->hws_map, 0, sizeof(dev_priv->hws_map)); goto err_unpin; @@ -816,20 +809,19 @@ static int init_status_page(struct intel_ring_buffer *ring) return 0; err_unpin: - i915_gem_object_unpin(obj); + // i915_gem_object_unpin(obj); err_unref: - drm_gem_object_unreference(&obj->base); + // drm_gem_object_unreference(&obj->base); err: return ret; } -#endif int intel_init_ring_buffer(struct drm_device *dev, struct intel_ring_buffer *ring) { - struct drm_i915_gem_object *obj=NULL; + struct drm_i915_gem_object *obj; int ret; - ENTER(); + ring->dev = dev; INIT_LIST_HEAD(&ring->active_list); INIT_LIST_HEAD(&ring->request_list); @@ -840,9 +832,9 @@ int intel_init_ring_buffer(struct drm_device *dev, ring->irq_mask = ~0; if (I915_NEED_GFX_HWS(dev)) { -// ret = init_status_page(ring); -// if (ret) -// return ret; + ret = init_status_page(ring); + if (ret) + return ret; } obj = i915_gem_alloc_object(dev, ring->size); @@ -886,7 +878,7 @@ int intel_init_ring_buffer(struct drm_device *dev, ring->effective_size = ring->size; if (IS_I830(ring->dev)) ring->effective_size -= 128; - LEAVE(); + return 0; err_unmap: @@ -936,6 +928,8 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) unsigned int *virt; int rem = ring->size - ring->tail; + ENTER(); + if (ring->space < rem) { int ret = intel_wait_ring_buffer(ring, rem); if (ret) @@ -952,6 +946,7 @@ static int intel_wrap_ring_buffer(struct intel_ring_buffer *ring) ring->tail = 0; ring->space = ring_space(ring); + LEAVE(); return 0; } @@ -962,6 +957,8 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) unsigned long end; u32 head; + ENTER(); + /* If the reported head position has wrapped or hasn't advanced, * fallback to the slow and accurate path. */ @@ -970,7 +967,10 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) ring->head = head; ring->space = ring_space(ring); if (ring->space >= n) + { + LEAVE(); return 0; + }; } // trace_i915_ring_wait_begin(ring); @@ -980,20 +980,20 @@ int intel_wait_ring_buffer(struct intel_ring_buffer *ring, int n) ring->space = ring_space(ring); if (ring->space >= n) { // trace_i915_ring_wait_end(ring); + LEAVE(); return 0; } - if (dev->primary->master) { - struct drm_i915_master_private *master_priv = dev->primary->master->driver_priv; - if (master_priv->sarea_priv) - master_priv->sarea_priv->perf_boxes |= I915_BOX_WAIT; - } - msleep(1); if (atomic_read(&dev_priv->mm.wedged)) + { + LEAVE(); return -EAGAIN; + }; } while (!time_after(jiffies, end)); // trace_i915_ring_wait_end(ring); + LEAVE(); + return -EBUSY; } @@ -1004,8 +1004,8 @@ int intel_ring_begin(struct intel_ring_buffer *ring, int n = 4*num_dwords; int ret; - if (unlikely(atomic_read(&dev_priv->mm.wedged))) - return -EIO; +// if (unlikely(atomic_read(&dev_priv->mm.wedged))) +// return -EIO; if (unlikely(ring->tail + n > ring->effective_size)) { ret = intel_wrap_ring_buffer(ring); @@ -1041,7 +1041,7 @@ static const struct intel_ring_buffer render_ring = { // .get_seqno = ring_get_seqno, // .irq_get = render_ring_get_irq, // .irq_put = render_ring_put_irq, -// .dispatch_execbuffer = render_ring_dispatch_execbuffer, + .dispatch_execbuffer = render_ring_dispatch_execbuffer, // .cleanup = render_ring_cleanup, }; @@ -1059,7 +1059,7 @@ static const struct intel_ring_buffer bsd_ring = { // .get_seqno = ring_get_seqno, // .irq_get = bsd_ring_get_irq, // .irq_put = bsd_ring_put_irq, -// .dispatch_execbuffer = ring_dispatch_execbuffer, + .dispatch_execbuffer = ring_dispatch_execbuffer, }; @@ -1106,7 +1106,6 @@ static int gen6_ring_flush(struct intel_ring_buffer *ring, return 0; } -#if 0 static int gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, u32 offset, u32 len) @@ -1125,6 +1124,8 @@ gen6_ring_dispatch_execbuffer(struct intel_ring_buffer *ring, return 0; } +#if 0 + static bool gen6_render_ring_get_irq(struct intel_ring_buffer *ring) { @@ -1172,7 +1173,7 @@ static const struct intel_ring_buffer gen6_bsd_ring = { // .get_seqno = ring_get_seqno, // .irq_get = gen6_bsd_ring_get_irq, // .irq_put = gen6_bsd_ring_put_irq, -// .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, + .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, }; #if 0 @@ -1304,7 +1305,7 @@ static const struct intel_ring_buffer gen6_blt_ring = { // .get_seqno = ring_get_seqno, // .irq_get = blt_ring_get_irq, // .irq_put = blt_ring_put_irq, -// .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, + .dispatch_execbuffer = gen6_ring_dispatch_execbuffer, // .cleanup = blt_ring_cleanup, }; @@ -1312,7 +1313,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) { drm_i915_private_t *dev_priv = dev->dev_private; struct intel_ring_buffer *ring = &dev_priv->ring[RCS]; - ENTER(); + *ring = render_ring; if (INTEL_INFO(dev)->gen >= 6) { ring->add_request = gen6_add_request; @@ -1327,7 +1328,7 @@ int intel_init_render_ring_buffer(struct drm_device *dev) ring->status_page.page_addr = dev_priv->status_page_dmah->vaddr; memset(ring->status_page.page_addr, 0, PAGE_SIZE); } - LEAVE(); + return intel_init_ring_buffer(dev, ring); } diff --git a/drivers/video/drm/i915/intel_sdvo.c b/drivers/video/drm/i915/intel_sdvo.c index a5bc897eb3..c176e1079a 100644 --- a/drivers/video/drm/i915/intel_sdvo.c +++ b/drivers/video/drm/i915/intel_sdvo.c @@ -616,8 +616,29 @@ static bool intel_sdvo_set_active_outputs(struct intel_sdvo *intel_sdvo, &outputs, sizeof(outputs)); } +static bool intel_sdvo_set_encoder_power_state(struct intel_sdvo *intel_sdvo, + int mode) +{ + u8 state = SDVO_ENCODER_STATE_ON; + switch (mode) { + case DRM_MODE_DPMS_ON: + state = SDVO_ENCODER_STATE_ON; + break; + case DRM_MODE_DPMS_STANDBY: + state = SDVO_ENCODER_STATE_STANDBY; + break; + case DRM_MODE_DPMS_SUSPEND: + state = SDVO_ENCODER_STATE_SUSPEND; + break; + case DRM_MODE_DPMS_OFF: + state = SDVO_ENCODER_STATE_OFF; + break; + } + return intel_sdvo_set_value(intel_sdvo, + SDVO_CMD_SET_ENCODER_POWER_STATE, &state, sizeof(state)); +} static bool intel_sdvo_get_input_pixel_clock_range(struct intel_sdvo *intel_sdvo, int *clock_min, diff --git a/drivers/video/drm/i915/kms_display.c b/drivers/video/drm/i915/kms_display.c index e7026847e3..0458890b3a 100644 --- a/drivers/video/drm/i915/kms_display.c +++ b/drivers/video/drm/i915/kms_display.c @@ -1,10 +1,12 @@ + +#define iowrite32(v, addr) writel((v), (addr)) + #include "drmP.h" #include "drm.h" #include "i915_drm.h" #include "i915_drv.h" #include "intel_drv.h" - #include #include #include @@ -13,17 +15,8 @@ #include -typedef struct tag_object kobj_t; -typedef struct tag_display display_t; +#include "bitmap.h" -struct tag_object -{ - uint32_t magic; - void *destroy; - kobj_t *fd; - kobj_t *bk; - uint32_t pid; -}; typedef struct { @@ -71,6 +64,9 @@ struct tag_display static display_t *os_display; +u32_t cmd_buffer; +u32_t cmd_offset; + 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); @@ -195,6 +191,49 @@ int init_display_kms(struct drm_device *dev) }; safe_sti(ifl); + { +#define XY_COLOR_BLT ((2<<29)|(0x50<<22)|(0x4)) +#define BLT_WRITE_ALPHA (1<<21) +#define BLT_WRITE_RGB (1<<20) + + drm_i915_private_t *dev_priv = dev->dev_private; + struct drm_i915_gem_object *obj; + struct intel_ring_buffer *ring; + + u32_t br13, cmd, *b; + + int n=0; + + cmd = XY_COLOR_BLT | BLT_WRITE_ALPHA | BLT_WRITE_RGB; + br13 = os_display->pitch; + br13 |= 0xF0 << 16; + br13 |= 3 << 24; + + obj = i915_gem_alloc_object(dev, 4096); + i915_gem_object_pin(obj, 4096, true); + + cmd_buffer = MapIoMem(obj->pages[0], 4096, PG_SW|PG_NOCACHE); + cmd_offset = obj->gtt_offset; + + b = (u32_t*)cmd_buffer; + b[n++] = cmd; + b[n++] = br13; + b[n++] = 0; // top, left + b[n++] = (128 << 16) | 128; // bottom, right + b[n++] = 0; // dst + b[n++] = 0x0000FF00; + b[n++] = MI_BATCH_BUFFER_END; + if( n & 1) + b[n++] = MI_NOOP; + +// cmd_buffer = (u32_t)&b[n]; +// i915_gem_object_set_to_gtt_domain(obj, false); + + + ring = &dev_priv->ring[BCS]; + ring->dispatch_execbuffer(ring,cmd_offset, n*4); + + }; LEAVE(); @@ -433,7 +472,7 @@ int init_cursor(cursor_t *cursor) // release old cursor -// KernelFree(cursor->data); + KernelFree(cursor->data); cursor->data = bits; @@ -549,62 +588,138 @@ cursor_t* __stdcall select_cursor_kms(cursor_t *cursor) return old; }; -#if 0 -static void intel_crtc_update_cursor(struct drm_crtc *crtc, - bool on) +extern struct drm_device *main_device; + +#define XY_SRC_COPY_BLT_CMD ((2<<29)|(0x53<<22)|6) + +int video_blit(uint64_t src_offset, int x, int y, + int w, int h, int pitch) { - 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; + drm_i915_private_t *dev_priv = main_device->dev_private; + struct intel_ring_buffer *ring; - if (on && crtc->enabled && crtc->fb) { - base = intel_crtc->cursor_addr; - if (x > (int) crtc->fb->width) - base = 0; + u32_t br13, cmd, *b; + u32_t offset; - if (y > (int) crtc->fb->height) - base = 0; - } else - base = 0; + int n=0; - if (x < 0) { - if (x + intel_crtc->cursor_width < 0) - base = 0; +// if( cmd_buffer & 0xF80 ) +// cmd_buffer&= 0xFFFFF000; - pos |= CURSOR_POS_SIGN << CURSOR_X_SHIFT; - x = -x; - } - pos |= x << CURSOR_X_SHIFT; +// b = (u32_t*)ALIGN(cmd_buffer,16); - if (y < 0) { - if (y + intel_crtc->cursor_height < 0) - base = 0; +// offset = cmd_offset + ((u32_t)b & 0xFFF); - pos |= CURSOR_POS_SIGN << CURSOR_Y_SHIFT; - y = -y; - } - pos |= y << CURSOR_Y_SHIFT; + b = cmd_buffer; - visible = base != 0; - if (!visible && !intel_crtc->cursor_visible) - return; + cmd = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGB; + br13 = os_display->pitch; + br13 |= 0xCC << 16; + br13 |= 3 << 24; - I915_WRITE(CURPOS(pipe), pos); - if (IS_845G(dev) || IS_I865G(dev)) - i845_update_cursor(crtc, base); - else - i9xx_update_cursor(crtc, base); + b[n++] = cmd; + b[n++] = br13; + b[n++] = (y << 16) | x; + b[n++] = ( (y+h) << 16) | (x+w); // bottom, right + b[n++] = 0; // dst_offset + b[n++] = 0; //src_top|src_left - if (visible) - intel_mark_busy(dev, to_intel_framebuffer(crtc->fb)->obj); -} + b[n++] = pitch; + b[n++] = (u32_t)src_offset; -#endif + b[n++] = MI_BATCH_BUFFER_END; + if( n & 1) + b[n++] = MI_NOOP; +// i915_gem_object_set_to_gtt_domain(obj, false); + + ring = &dev_priv->ring[BCS]; + ring->dispatch_execbuffer(ring, cmd_offset, n*4); + + intel_ring_begin(ring, 4); +// if (ret) +// return ret; + +// cmd = MI_FLUSH_DW; +// if (invalidate & I915_GEM_GPU_DOMAINS) +// cmd |= MI_INVALIDATE_TLB | MI_INVALIDATE_BSD; + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + +fail: + return -1; +}; + + +int blit_video(u32 hbitmap, int dst_x, int dst_y, + int src_x, int src_y, u32 w, u32 h) +{ + drm_i915_private_t *dev_priv = main_device->dev_private; + struct intel_ring_buffer *ring; + + bitmap_t *bitmap; + u32_t br13, cmd, *b; + u32_t offset; + + int n=0; + + if(unlikely(hbitmap==0)) + return -1; + + bitmap = hman_get_data(&bm_man, hbitmap); + + if(unlikely(bitmap==NULL)) + return -1; + +// if( cmd_buffer & 0xF80 ) +// cmd_buffer&= 0xFFFFF000; + +// b = (u32_t*)ALIGN(cmd_buffer,16); + +// offset = cmd_offset + ((u32_t)b & 0xFFF); + + b = cmd_buffer; + + cmd = XY_SRC_COPY_BLT_CMD | BLT_WRITE_RGB; + br13 = os_display->pitch; + br13 |= 0xCC << 16; + br13 |= 3 << 24; + + b[n++] = cmd; + b[n++] = br13; + b[n++] = (dst_y << 16) | dst_x; + b[n++] = ( (dst_y+h) << 16) | (dst_x+w); // bottom, right + b[n++] = 0; // dst_offset + b[n++] = (src_y << 16) | src_x; + + b[n++] = bitmap->pitch; + b[n++] = bitmap->gaddr; + + b[n++] = MI_BATCH_BUFFER_END; + if( n & 1) + b[n++] = MI_NOOP; + +// i915_gem_object_set_to_gtt_domain(obj, false); + + ring = &dev_priv->ring[BCS]; + ring->dispatch_execbuffer(ring, cmd_offset, n*4); + + intel_ring_begin(ring, 4); +// if (ret) +// return ret; + + intel_ring_emit(ring, MI_FLUSH_DW); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, 0); + intel_ring_emit(ring, MI_NOOP); + intel_ring_advance(ring); + + return 0; +fail: + return -1; +}; diff --git a/drivers/video/drm/i915/main.c b/drivers/video/drm/i915/main.c index ec859449ef..6eb08b5eaf 100644 --- a/drivers/video/drm/i915/main.c +++ b/drivers/video/drm/i915/main.c @@ -12,9 +12,17 @@ #include #include +typedef struct bitmap bitmap_t; + +void parse_cmdline(char *cmdline, char *log); int _stdcall display_handler(ioctl_t *io); int init_agp(void); +int create_video(int width, int height, u32_t *outp); +int create_bitmap(bitmap_t **pbitmap, int width, int height); +int video_blit(uint64_t src_offset, int x, int y, + int w, int h, int pitch); + static char log[256]; int i915_modeset = 1; @@ -31,12 +39,12 @@ u32_t drvEntry(int action, char *cmdline) if( GetService("DISPLAY") != 0 ) return 0; -// if( cmdline && *cmdline ) -// parse_cmdline(cmdline, &usermode, log, &radeon_modeset); + if( cmdline && *cmdline ) + parse_cmdline(cmdline, log); if(!dbg_open(log)) { - strcpy(log, "/HD1/2/i915.log"); + strcpy(log, "/RD/1/DRIVERS/i915.log"); if(!dbg_open(log)) { @@ -44,7 +52,7 @@ u32_t drvEntry(int action, char *cmdline) return 0; }; } - dbgprintf("i915 RC01 cmdline %s\n", cmdline); + dbgprintf("i915_early_preview second edition\n cmdline: %s\n", cmdline); enum_pci_devices(); @@ -102,7 +110,7 @@ int _stdcall display_handler(ioctl_t *io) 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_output(4); // check_input(*outp * sizeof(videomode_t)); if( i915_modeset) retval = get_videomodes((videomode_t*)inp, outp); @@ -116,13 +124,14 @@ int _stdcall display_handler(ioctl_t *io) retval = set_user_mode((videomode_t*)inp); break; -/* case SRV_CREATE_VIDEO: - retval = r600_create_video(inp[0], inp[1], outp); + check_input(2); + check_output(4); + retval = create_video(inp[0], inp[1], outp); break; case SRV_BLIT_VIDEO: - r600_video_blit( ((uint64_t*)inp)[0], inp[2], inp[3], + video_blit( ((uint64_t*)inp)[0], inp[2], inp[3], inp[4], inp[5], inp[6]); retval = 0; @@ -131,9 +140,9 @@ int _stdcall display_handler(ioctl_t *io) case SRV_CREATE_BITMAP: check_input(8); check_output(4); - retval = create_bitmap(outp, inp[0], inp[1]); + retval = create_bitmap((bitmap_t**)outp, inp[0], inp[1]); break; -*/ + }; return retval; @@ -166,3 +175,38 @@ int pci_scan_filter(u32_t id, u32_t busnr, u32_t devfn) } return ret; }; + + +static char* parse_path(char *p, char *log) +{ + char c; + + while( (c = *p++) == ' '); + p--; + while( (c = *log++ = *p++) && (c != ' ')); + *log = 0; + + return p; +}; + +void parse_cmdline(char *cmdline, char *log) +{ + char *p = cmdline; + + char c = *p++; + + while( c ) + { + if( c == '-') + { + switch(*p++) + { + case 'l': + p = parse_path(p, log); + break; + }; + }; + c = *p++; + }; +}; +