Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright © 2008-2012 Intel Corporation
  3.  *
  4.  * Permission is hereby granted, free of charge, to any person obtaining a
  5.  * copy of this software and associated documentation files (the "Software"),
  6.  * to deal in the Software without restriction, including without limitation
  7.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  8.  * and/or sell copies of the Software, and to permit persons to whom the
  9.  * Software is furnished to do so, subject to the following conditions:
  10.  *
  11.  * The above copyright notice and this permission notice (including the next
  12.  * paragraph) shall be included in all copies or substantial portions of the
  13.  * Software.
  14.  *
  15.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  18.  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19.  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
  20.  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  21.  * IN THE SOFTWARE.
  22.  *
  23.  * Authors:
  24.  *    Eric Anholt <eric@anholt.net>
  25.  *    Chris Wilson <chris@chris-wilson.co.uk>
  26.  *
  27.  */
  28.  
  29. #include <drm/drmP.h>
  30. #include <drm/i915_drm.h>
  31. #include <display.h>
  32. #include "intel_drv.h"
  33. #include "i915_drv.h"
  34.  
  35. static addr_t dummy_fb_page;
  36. static struct kos_framebuffer *fake_fb;
  37.  
  38. int fake_framebuffer_create()
  39. {
  40.     struct kos_framebuffer *kfb;
  41.     addr_t dummy_table;
  42.     addr_t *pt_addr;
  43.     int pde, pte;
  44.  
  45.     kfb = kzalloc(sizeof(struct kos_framebuffer),0);
  46.     if(kfb == NULL)
  47.         goto err_0;
  48.  
  49.     dummy_fb_page = AllocPage();
  50.     if(dummy_fb_page == 0)
  51.         goto err_1;
  52.  
  53.     for(pde = 0; pde < 8; pde++)
  54.     {
  55.         dummy_table = AllocPage();
  56.         if(dummy_table == 0)
  57.             goto err_2;
  58.  
  59.         kfb->pde[pde] = dummy_table|PG_UW;
  60.  
  61.         pt_addr = kmap_atomic((struct page*)dummy_table);
  62.         for(pte = 0; pte < 1024; pte++)
  63.             pt_addr[pte] = dummy_fb_page|PG_UW;
  64.         kunmap_atomic(pt_addr);
  65.     };
  66.  
  67.     fake_fb = kfb;
  68.  
  69.     return 0;
  70.  
  71. err_2:
  72.     for(pte = 0; pte < pde; pte++)
  73.         FreePage(kfb->pde[pte]);
  74.     FreePage(dummy_fb_page);
  75. err_1:
  76.     kfree(kfb);
  77. err_0:
  78.     return -ENOMEM;
  79. };
  80.  
  81. int kolibri_framebuffer_init(void *param)
  82. {
  83.     struct intel_framebuffer *intel_fb = param;
  84.     struct kos_framebuffer *kfb;
  85.     addr_t dummy_table;
  86.     addr_t *pt_addr = NULL;
  87.     int pde, pte;
  88.  
  89.     kfb = kzalloc(sizeof(struct kos_framebuffer),0);
  90.     if(kfb == NULL)
  91.         goto err_0;
  92.  
  93.     kfb->private = intel_fb;
  94.  
  95.     for(pde = 0; pde < 8; pde++)
  96.     {
  97.         dummy_table = AllocPage();
  98.         if(dummy_table == 0)
  99.             goto err_1;
  100.  
  101.         kfb->pde[pde] = dummy_table|PG_UW;
  102.  
  103.         pt_addr = kmap_atomic((struct page*)dummy_table);
  104.         for(pte = 0; pte < 1024; pte++)
  105.             pt_addr[pte] = dummy_fb_page|PG_UW;
  106.         kunmap_atomic(pt_addr);
  107.     };
  108.  
  109.     intel_fb->private = kfb;
  110.  
  111.     return 0;
  112. err_1:
  113.     for(pte = 0; pte < pde; pte++)
  114.         FreePage(kfb->pde[pte]);
  115.     kfree(kfb);
  116. err_0:
  117.     return -ENOMEM;
  118. };
  119.  
  120. void kolibri_framebuffer_update(struct drm_device *dev, struct kos_framebuffer *kfb)
  121. {
  122.     struct drm_i915_private *dev_priv = dev->dev_private;
  123.     struct intel_framebuffer *intel_fb = kfb->private;
  124.     addr_t *pt_addr = NULL;
  125.     int pte = 0;
  126.     int pde = 0;
  127.     int num_pages;
  128.     addr_t pfn;
  129.  
  130.     num_pages = intel_fb->obj->base.size/4096;
  131.     pfn = dev_priv->gtt.mappable_base + i915_gem_obj_ggtt_offset(intel_fb->obj);
  132.  
  133.     while(num_pages)
  134.     {
  135.         if (pt_addr == NULL)
  136.         {
  137.             addr_t pt = kfb->pde[pde] & 0xFFFFF000;
  138.             pde++;
  139.             pt_addr = kmap_atomic((struct page*)pt);
  140.         }
  141.         pt_addr[pte] = pfn|PG_UW|PG_WRITEC;
  142.         pfn+= 4096;
  143.         num_pages--;
  144.         if (++pte == 1024)
  145.         {
  146.             kunmap_atomic(pt_addr);
  147.             pt_addr = NULL;
  148.             if (pde == 8)
  149.                 break;
  150.             pte = 0;
  151.         }
  152.     }
  153.  
  154.     if(pt_addr)
  155.     {
  156.         for(; pte < 1024; pte++)
  157.             pt_addr[pte] = dummy_fb_page|PG_UW;
  158.         kunmap_atomic(pt_addr);
  159.     };
  160.  
  161.     for(; pde < 8; pde++)
  162.     {
  163.         addr_t pt = kfb->pde[pde] & 0xFFFFF000;
  164.         pt_addr = kmap_atomic((struct page*)pt);
  165.         for(pte = 0; pte < 1024; pte++)
  166.             pt_addr[pte] = dummy_fb_page|PG_UW;
  167.         kunmap_atomic(pt_addr);
  168.     }
  169. };
  170.  
  171. void set_fake_framebuffer()
  172. {
  173.     sysSetFramebuffer(fake_fb);
  174. }
  175.