sis_mm.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:7k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /* sis_mm.c -- Private header for Direct Rendering Manager -*- linux-c -*-
  2.  * Created: Mon Jan  4 10:05:05 1999 by sclin@sis.com.tw
  3.  *
  4.  * Copyright 2000 Silicon Integrated Systems Corp, Inc., HsinChu, Taiwan.
  5.  * All rights reserved.
  6.  *
  7.  * Permission is hereby granted, free of charge, to any person obtaining a
  8.  * copy of this software and associated documentation files (the "Software"),
  9.  * to deal in the Software without restriction, including without limitation
  10.  * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  11.  * and/or sell copies of the Software, and to permit persons to whom the
  12.  * Software is furnished to do so, subject to the following conditions:
  13.  * 
  14.  * The above copyright notice and this permission notice (including the next
  15.  * paragraph) shall be included in all copies or substantial portions of the
  16.  * Software.
  17.  * 
  18.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  19.  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  20.  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
  21.  * PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  22.  * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  23.  * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
  24.  * DEALINGS IN THE SOFTWARE.
  25.  * 
  26.  * Authors:
  27.  *    Sung-Ching Lin <sclin@sis.com.tw>
  28.  * 
  29.  */
  30. #include "sis.h"
  31. #include <linux/sisfb.h>
  32. #include "drmP.h"
  33. #include "sis_drm.h"
  34. #include "sis_drv.h"
  35. #include "sis_ds.h"
  36. #define MAX_CONTEXT 100
  37. #define VIDEO_TYPE 0 
  38. #define AGP_TYPE 1
  39. typedef struct {
  40.   int used;
  41.   int context;
  42.   set_t *sets[2]; /* 0 for video, 1 for AGP */
  43. } sis_context_t;
  44. static sis_context_t global_ppriv[MAX_CONTEXT];
  45. static int add_alloc_set(int context, int type, unsigned int val)
  46. {
  47.   int i, retval = 0;
  48.   
  49.   for(i = 0; i < MAX_CONTEXT; i++)
  50.     if(global_ppriv[i].used && global_ppriv[i].context == context){
  51.       retval = setAdd(global_ppriv[i].sets[type], val);
  52.       break;
  53.     }
  54.   return retval;
  55. }
  56. static int del_alloc_set(int context, int type, unsigned int val)
  57. {  
  58.   int i, retval = 0;
  59.   for(i = 0; i < MAX_CONTEXT; i++)
  60.     if(global_ppriv[i].used && global_ppriv[i].context == context){
  61.       retval = setDel(global_ppriv[i].sets[type], val);
  62.       break;
  63.     }
  64.   return retval;
  65. }
  66. /* fb management via fb device */ 
  67. #if 1
  68. int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
  69.   unsigned long arg)
  70. {
  71.   drm_sis_mem_t fb;
  72.   struct sis_memreq req;
  73.   int retval = 0;
  74.    
  75.   if (copy_from_user(&fb, (drm_sis_mem_t *)arg, sizeof(fb)))
  76.   return -EFAULT;
  77.   
  78.   req.size = fb.size;
  79.   sis_malloc(&req);
  80.   if(req.offset){
  81.     /* TODO */
  82.     fb.offset = req.offset;
  83.     fb.free = req.offset;
  84.     if(!add_alloc_set(fb.context, VIDEO_TYPE, fb.free)){
  85.       DRM_DEBUG("adding to allocation set failsn");
  86.       sis_free(req.offset);
  87.       retval = -1;
  88.     }
  89.   }
  90.   else{  
  91.     fb.offset = 0;
  92.     fb.size = 0;
  93.     fb.free = 0;
  94.   }
  95.    
  96.   if (copy_to_user((drm_sis_mem_t *)arg, &fb, sizeof(fb))) return -EFAULT;
  97.   DRM_DEBUG("alloc fb, size = %d, offset = %ldn", fb.size, req.offset);
  98.   return retval;
  99. }
  100. int sis_fb_free(struct inode *inode, struct file *filp, unsigned int cmd,
  101.   unsigned long arg)
  102. {
  103.   drm_sis_mem_t fb;
  104.   int retval = 0;
  105.     
  106.   if (copy_from_user(&fb, (drm_sis_mem_t *)arg, sizeof(fb)))
  107.   return -EFAULT;
  108.   
  109.   if(!fb.free){
  110.     return -1;
  111.   }
  112.   sis_free(fb.free);
  113.   if(!del_alloc_set(fb.context, VIDEO_TYPE, fb.free))
  114.     retval = -1;
  115.   DRM_DEBUG("free fb, offset = %ldn", fb.free);
  116.   
  117.   return retval;
  118. }
  119. #else
  120. int sis_fb_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
  121.   unsigned long arg)
  122. {
  123.   return -1;
  124. }
  125. int sis_fb_free(struct inode *inode, struct file *filp, unsigned int cmd,
  126.   unsigned long arg)
  127. {
  128.   return 0;
  129. }
  130. #endif
  131. /* agp memory management */ 
  132. #if 1
  133. static memHeap_t *AgpHeap = NULL;
  134. int sisp_agp_init(struct inode *inode, struct file *filp, unsigned int cmd,
  135.   unsigned long arg)
  136. {
  137.   drm_sis_agp_t agp;
  138.    
  139.   if (copy_from_user(&agp, (drm_sis_agp_t *)arg, sizeof(agp)))
  140.   return -EFAULT;
  141.   AgpHeap = mmInit(agp.offset, agp.size);
  142.   DRM_DEBUG("offset = %u, size = %u", agp.offset, agp.size);
  143.   
  144.   return 0;
  145. }
  146. int sisp_agp_alloc(struct inode *inode, struct file *filp, unsigned int cmd,
  147.   unsigned long arg)
  148. {
  149.   drm_sis_mem_t agp;
  150.   PMemBlock block;
  151.   int retval = 0;
  152.    
  153.   if(!AgpHeap)
  154.     return -1;
  155.   
  156.   if (copy_from_user(&agp, (drm_sis_mem_t *)arg, sizeof(agp)))
  157.   return -EFAULT;
  158.   
  159.   block = mmAllocMem(AgpHeap, agp.size, 0, 0);
  160.   if(block){
  161.     /* TODO */
  162.     agp.offset = block->ofs;
  163.     agp.free = (unsigned long)block;
  164.     if(!add_alloc_set(agp.context, AGP_TYPE, agp.free)){
  165.       DRM_DEBUG("adding to allocation set failsn");
  166.       mmFreeMem((PMemBlock)agp.free);
  167.       retval = -1;
  168.     }
  169.   }
  170.   else{  
  171.     agp.offset = 0;
  172.     agp.size = 0;
  173.     agp.free = 0;
  174.   }
  175.    
  176.   if (copy_to_user((drm_sis_mem_t *)arg, &agp, sizeof(agp))) return -EFAULT;
  177.   DRM_DEBUG("alloc agp, size = %d, offset = %dn", agp.size, agp.offset);
  178.   return retval;
  179. }
  180. int sisp_agp_free(struct inode *inode, struct file *filp, unsigned int cmd,
  181.   unsigned long arg)
  182. {
  183.   drm_sis_mem_t agp;
  184.   int retval = 0;
  185.   if(!AgpHeap)
  186.     return -1;
  187.     
  188.   if (copy_from_user(&agp, (drm_sis_mem_t *)arg, sizeof(agp)))
  189.   return -EFAULT;
  190.   
  191.   if(!agp.free){
  192.     return -1;
  193.   }
  194.   mmFreeMem((PMemBlock)agp.free);
  195.   if(!del_alloc_set(agp.context, AGP_TYPE, agp.free))
  196.     retval = -1;
  197.   DRM_DEBUG("free agp, free = %ldn", agp.free);
  198.   
  199.   return retval;
  200. }
  201. #endif
  202. int sis_init_context(int context)
  203. {
  204. int i;
  205. for(i = 0; i < MAX_CONTEXT ; i++)
  206.   if(global_ppriv[i].used && (global_ppriv[i].context == context))
  207.     break;
  208. if(i >= MAX_CONTEXT){
  209.   for(i = 0; i < MAX_CONTEXT ; i++){
  210.     if(!global_ppriv[i].used){
  211.       global_ppriv[i].context = context;
  212.       global_ppriv[i].used = 1;
  213.       global_ppriv[i].sets[0] = setInit();
  214.       global_ppriv[i].sets[1] = setInit();
  215.       DRM_DEBUG("init allocation set, socket=%d, context = %dn", 
  216.                  i, context);
  217.       break;
  218.     }
  219.   }
  220.   if((i >= MAX_CONTEXT) || (global_ppriv[i].sets[0] == NULL) ||
  221.      (global_ppriv[i].sets[1] == NULL)){
  222.     return 0;
  223.   }
  224. }
  225. return 1;
  226. }
  227. int sis_final_context(int context)
  228. {
  229. int i;
  230. for(i=0; i<MAX_CONTEXT; i++)
  231.   if(global_ppriv[i].used && (global_ppriv[i].context == context))
  232.     break;
  233.           
  234. if(i < MAX_CONTEXT){
  235.   set_t *set;
  236.   unsigned int item;
  237.   int retval;
  238.   
  239.      DRM_DEBUG("find socket %d, context = %dn", i, context);
  240.   /* Video Memory */
  241.   set = global_ppriv[i].sets[0];
  242.   retval = setFirst(set, &item);
  243.   while(retval){
  244.         DRM_DEBUG("free video memory 0x%xn", item);
  245.             sis_free(item);
  246.     retval = setNext(set, &item);
  247.   }
  248.   setDestroy(set);
  249.   /* AGP Memory */
  250.   set = global_ppriv[i].sets[1];
  251.   retval = setFirst(set, &item);
  252.   while(retval){
  253.         DRM_DEBUG("free agp memory 0x%xn", item);
  254.     mmFreeMem((PMemBlock)item);
  255.     retval = setNext(set, &item);
  256.   }
  257.   setDestroy(set);
  258.   
  259.   global_ppriv[i].used = 0;   
  260.         }
  261. /* turn-off auto-flip */
  262. /* TODO */
  263. #if defined(SIS_STEREO)
  264. flip_final();
  265. #endif
  266. return 1;
  267. }