OSDN Git Service

Various changes for in-kernel modesetting:
[android-x86/external-libdrm.git] / shared-core / i915_init.c
1 #include "drmP.h"
2 #include "drm.h"
3 #include "drm_sarea.h"
4 #include "i915_drm.h"
5 #include "i915_drv.h"
6
7 /**
8  * i915_driver_load - setup chip and create an initial config
9  * @dev: DRM device
10  * @flags: startup flags
11  *
12  * The driver load routine has to do several things:
13  *   - drive output discovery via intel_modeset_init()
14  *   - initialize the memory manager
15  *   - allocate initial config memory
16  *   - setup the DRM framebuffer with the allocated memory
17  */
18 int i915_driver_load(drm_device_t *dev, unsigned long flags)
19 {
20         drm_i915_private_t *dev_priv;
21         drm_i915_init_t init;
22         drm_buffer_object_t *entry;
23         struct drm_framebuffer *fb;
24         int ret;
25
26         dev_priv = drm_alloc(sizeof(drm_i915_private_t), DRM_MEM_DRIVER);
27         if (dev_priv == NULL)
28                 return DRM_ERR(ENOMEM);
29
30         memset(dev_priv, 0, sizeof(drm_i915_private_t));
31         dev->dev_private = (void *)dev_priv;
32 //      dev_priv->flags = flags;
33
34         /* i915 has 4 more counters */
35         dev->counters += 4;
36         dev->types[6] = _DRM_STAT_IRQ;
37         dev->types[7] = _DRM_STAT_PRIMARY;
38         dev->types[8] = _DRM_STAT_SECONDARY;
39         dev->types[9] = _DRM_STAT_DMA;
40
41         if (IS_I9XX(dev)) {
42                 dev_priv->mmiobase = drm_get_resource_start(dev, 0);
43                 dev_priv->mmiolen = drm_get_resource_len(dev, 0);
44                 dev->mode_config.fb_base = dev_priv->baseaddr = drm_get_resource_start(dev, 2) & 0xff000000;
45         } else if (drm_get_resource_start(dev, 1)) {
46                 dev_priv->mmiobase = drm_get_resource_start(dev, 1);
47                 dev_priv->mmiolen = drm_get_resource_len(dev, 1);
48                 dev->mode_config.fb_base = dev_priv->baseaddr = drm_get_resource_start(dev, 0) & 0xff000000;
49         } else {
50                 DRM_ERROR("Unable to find MMIO registers\n");
51                 return -ENODEV;
52         }
53
54         ret = drm_addmap(dev, dev_priv->mmiobase, dev_priv->mmiolen,
55                          _DRM_REGISTERS, _DRM_READ_ONLY, &dev_priv->mmio_map);
56         if (ret != 0) {
57                 DRM_ERROR("Cannot add mapping for MMIO registers\n");
58                 return ret;
59         }
60
61         ret = drm_setup(dev);
62         if (ret) {
63                 DRM_ERROR("drm_setup failed\n");
64                 return ret;
65         }
66
67         DRM_GETSAREA();
68         if (!dev_priv->sarea) {
69                 DRM_ERROR("can not find sarea!\n");
70                 dev->dev_private = (void *)dev_priv;
71                 i915_dma_cleanup(dev);
72                 return DRM_ERR(EINVAL);
73         }
74
75         /* FIXME: assume sarea_priv is right after SAREA */
76         dev_priv->sarea_priv = dev_priv->sarea->handle + sizeof(drm_sarea_t);
77
78         /*
79          * Initialize the memory manager for local and AGP space
80          */
81         drm_bo_driver_init(dev);
82         /* FIXME: initial stolen area 8M init */
83 #define SCANOUT_SIZE 1024*1024*8 /* big enough for 2048x1024 32bpp */
84         drm_bo_init_mm(dev, DRM_BO_MEM_PRIV0, dev->mode_config.fb_base,
85                        SCANOUT_SIZE);
86
87         /* Allocate scanout buffer and command ring */
88         /* FIXME: types and other args correct? */
89         drm_buffer_object_create(dev, SCANOUT_SIZE, drm_bo_type_dc,
90                                  DRM_BO_FLAG_READ | DRM_BO_FLAG_WRITE |
91                                  DRM_BO_FLAG_MEM_PRIV0 | DRM_BO_FLAG_NO_MOVE,
92                                  0, PAGE_SIZE, 0,
93                                  &entry);
94
95         DRM_DEBUG("allocated bo, start: 0x%lx, offset: 0x%lx\n",
96                   entry->buffer_start, entry->offset);
97         intel_modeset_init(dev);
98
99         fb = drm_framebuffer_create(dev);
100         if (!fb) {
101                 DRM_ERROR("failed to allocate fb\n");
102                 return -EINVAL;
103         }
104
105         fb->width = 1024;
106         fb->height = 768;
107         fb->pitch = 1024;
108         fb->bits_per_pixel = 32;
109         fb->depth = 32;
110         fb->offset = entry->offset;
111         fb->bo = entry;
112
113         drm_initial_config(dev, fb, false);
114         drmfb_probe(dev, fb);
115         drm_set_desired_modes(dev);
116
117 #if 0
118         /* FIXME: command ring needs AGP space, do we own it at this point? */
119         dev_priv->ring.Start = dev_priv->baseaddr;
120         dev_priv->ring.End = 128*1024;
121         dev_priv->ring.Size = 128*1024;
122         dev_priv->ring.tail_mask = dev_priv->ring.Size - 1;
123
124         dev_priv->ring.map.offset = dev_priv->ring.Start;
125         dev_priv->ring.map.size = dev_priv->ring.Size;
126         dev_priv->ring.map.type = 0;
127         dev_priv->ring.map.flags = 0;
128         dev_priv->ring.map.mtrr = 0;
129
130         drm_core_ioremap(&dev_priv->ring.map, dev);
131
132         if (dev_priv->ring.map.handle == NULL) {
133                 dev->dev_private = (void *)dev_priv;
134                 i915_dma_cleanup(dev);
135                 DRM_ERROR("can not ioremap virtual address for"
136                           " ring buffer\n");
137                 return DRM_ERR(ENOMEM);
138         }
139
140         dev_priv->ring.virtual_start = dev_priv->ring.map.handle;
141         dev_priv->cpp = 4;
142         dev_priv->sarea_priv->pf_current_page = 0;
143
144         /* We are using separate values as placeholders for mechanisms for
145          * private backbuffer/depthbuffer usage.
146          */
147         dev_priv->use_mi_batchbuffer_start = 0;
148
149         /* Allow hardware batchbuffers unless told otherwise.
150          */
151         dev_priv->allow_batchbuffer = 1;
152
153         /* Program Hardware Status Page */
154         dev_priv->status_page_dmah = drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE, 
155             0xffffffff);
156
157         if (!dev_priv->status_page_dmah) {
158                 dev->dev_private = (void *)dev_priv;
159                 i915_dma_cleanup(dev);
160                 DRM_ERROR("Can not allocate hardware status page\n");
161                 return DRM_ERR(ENOMEM);
162         }
163         dev_priv->hw_status_page = dev_priv->status_page_dmah->vaddr;
164         dev_priv->dma_status_page = dev_priv->status_page_dmah->busaddr;
165         
166         memset(dev_priv->hw_status_page, 0, PAGE_SIZE);
167         DRM_DEBUG("hw status page @ %p\n", dev_priv->hw_status_page);
168
169         I915_WRITE(0x02080, dev_priv->dma_status_page);
170         DRM_DEBUG("Enabled hardware status page\n");
171 #endif
172
173         return 0;
174 }
175
176 int i915_driver_unload(drm_device_t *dev)
177 {
178         drm_i915_private_t *dev_priv = dev->dev_private;
179         struct drm_framebuffer *fb;
180
181         /* FIXME: remove framebuffer */
182         //intel_modeset_cleanup(dev);
183         drm_free(dev_priv, sizeof(*dev_priv), DRM_MEM_DRIVER);
184
185         dev->dev_private = NULL;
186         return 0;
187 }
188
189 void i915_driver_lastclose(drm_device_t * dev)
190 {
191         drm_i915_private_t *dev_priv = dev->dev_private;
192         
193         i915_mem_takedown(&(dev_priv->agp_heap));
194
195         i915_dma_cleanup(dev);
196
197         dev_priv->mmio_map = NULL;
198 }
199
200 void i915_driver_preclose(drm_device_t * dev, DRMFILE filp)
201 {
202         drm_i915_private_t *dev_priv = dev->dev_private;
203         i915_mem_release(dev, filp, dev_priv->agp_heap);
204 }
205