Subversion Repositories Kolibri OS

Rev

Rev 2327 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2326 Serge 1
/* i915_dma.c -- DMA support for the I915 -*- linux-c -*-
2
 */
3
/*
4
 * Copyright 2003 Tungsten Graphics, Inc., Cedar Park, Texas.
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
9
 * "Software"), to deal in the Software without restriction, including
10
 * without limitation the rights to use, copy, modify, merge, publish,
11
 * distribute, sub license, and/or sell copies of the Software, and to
12
 * permit persons to whom the Software is furnished to do so, subject to
13
 * the following conditions:
14
 *
15
 * The above copyright notice and this permission notice (including the
16
 * next paragraph) shall be included in all copies or substantial portions
17
 * of the Software.
18
 *
19
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
20
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21
 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
22
 * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR
23
 * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
24
 * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25
 * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26
 *
27
 */
28
 
29
#include "drmP.h"
30
#include "drm.h"
31
#include "drm_crtc_helper.h"
32
#include "drm_fb_helper.h"
33
#include "intel_drv.h"
34
//#include "i915_drm.h"
35
#include "i915_drv.h"
36
#include 
37
//#include "i915_trace.h"
38
//#include "../../../platform/x86/intel_ips.h"
39
#include 
40
//#include 
41
//#include 
42
//#include 
43
//#include 
44
//#include 
45
//#include 
46
 
47
void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen);
48
 
49
static void i915_write_hws_pga(struct drm_device *dev)
50
{
51
    drm_i915_private_t *dev_priv = dev->dev_private;
52
    u32 addr;
53
 
54
    addr = dev_priv->status_page_dmah->busaddr;
55
    if (INTEL_INFO(dev)->gen >= 4)
56
        addr |= (dev_priv->status_page_dmah->busaddr >> 28) & 0xf0;
57
    I915_WRITE(HWS_PGA, addr);
58
}
59
 
60
 
61
/**
62
 * Sets up the hardware status page for devices that need a physical address
63
 * in the register.
64
 */
65
static int i915_init_phys_hws(struct drm_device *dev)
66
{
67
    drm_i915_private_t *dev_priv = dev->dev_private;
68
 
69
    /* Program Hardware Status Page */
70
    dev_priv->status_page_dmah =
71
        drm_pci_alloc(dev, PAGE_SIZE, PAGE_SIZE);
72
 
73
    if (!dev_priv->status_page_dmah) {
74
        DRM_ERROR("Can not allocate hardware status page\n");
75
        return -ENOMEM;
76
    }
77
 
78
    i915_write_hws_pga(dev);
79
 
80
    dbgprintf("Enabled hardware status page\n");
81
    return 0;
82
}
83
 
84
static void i915_pineview_get_mem_freq(struct drm_device *dev)
85
{
86
    drm_i915_private_t *dev_priv = dev->dev_private;
87
    u32 tmp;
88
 
89
    tmp = I915_READ(CLKCFG);
90
 
91
    switch (tmp & CLKCFG_FSB_MASK) {
92
    case CLKCFG_FSB_533:
93
        dev_priv->fsb_freq = 533; /* 133*4 */
94
        break;
95
    case CLKCFG_FSB_800:
96
        dev_priv->fsb_freq = 800; /* 200*4 */
97
        break;
98
    case CLKCFG_FSB_667:
99
        dev_priv->fsb_freq =  667; /* 167*4 */
100
        break;
101
    case CLKCFG_FSB_400:
102
        dev_priv->fsb_freq = 400; /* 100*4 */
103
        break;
104
    }
105
 
106
    switch (tmp & CLKCFG_MEM_MASK) {
107
    case CLKCFG_MEM_533:
108
        dev_priv->mem_freq = 533;
109
        break;
110
    case CLKCFG_MEM_667:
111
        dev_priv->mem_freq = 667;
112
        break;
113
    case CLKCFG_MEM_800:
114
        dev_priv->mem_freq = 800;
115
        break;
116
    }
117
 
118
    /* detect pineview DDR3 setting */
119
    tmp = I915_READ(CSHRDDR3CTL);
120
    dev_priv->is_ddr3 = (tmp & CSHRDDR3CTL_DDR3) ? 1 : 0;
121
}
122
 
123
static void i915_ironlake_get_mem_freq(struct drm_device *dev)
124
{
125
    drm_i915_private_t *dev_priv = dev->dev_private;
126
    u16 ddrpll, csipll;
127
 
128
    ddrpll = I915_READ16(DDRMPLL1);
129
    csipll = I915_READ16(CSIPLL0);
130
 
131
    switch (ddrpll & 0xff) {
132
    case 0xc:
133
        dev_priv->mem_freq = 800;
134
        break;
135
    case 0x10:
136
        dev_priv->mem_freq = 1066;
137
        break;
138
    case 0x14:
139
        dev_priv->mem_freq = 1333;
140
        break;
141
    case 0x18:
142
        dev_priv->mem_freq = 1600;
143
        break;
144
    default:
145
        DRM_DEBUG_DRIVER("unknown memory frequency 0x%02x\n",
146
                 ddrpll & 0xff);
147
        dev_priv->mem_freq = 0;
148
        break;
149
    }
150
 
151
    dev_priv->r_t = dev_priv->mem_freq;
152
 
153
    switch (csipll & 0x3ff) {
154
    case 0x00c:
155
        dev_priv->fsb_freq = 3200;
156
        break;
157
    case 0x00e:
158
        dev_priv->fsb_freq = 3733;
159
        break;
160
    case 0x010:
161
        dev_priv->fsb_freq = 4266;
162
        break;
163
    case 0x012:
164
        dev_priv->fsb_freq = 4800;
165
        break;
166
    case 0x014:
167
        dev_priv->fsb_freq = 5333;
168
        break;
169
    case 0x016:
170
        dev_priv->fsb_freq = 5866;
171
        break;
172
    case 0x018:
173
        dev_priv->fsb_freq = 6400;
174
        break;
175
    default:
176
        DRM_DEBUG_DRIVER("unknown fsb frequency 0x%04x\n",
177
                 csipll & 0x3ff);
178
        dev_priv->fsb_freq = 0;
179
        break;
180
    }
181
 
182
    if (dev_priv->fsb_freq == 3200) {
183
        dev_priv->c_m = 0;
184
    } else if (dev_priv->fsb_freq > 3200 && dev_priv->fsb_freq <= 4800) {
185
        dev_priv->c_m = 1;
186
    } else {
187
        dev_priv->c_m = 2;
188
    }
189
}
190
 
191
static int i915_get_bridge_dev(struct drm_device *dev)
192
{
193
    struct drm_i915_private *dev_priv = dev->dev_private;
194
 
195
    dev_priv->bridge_dev = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
196
    if (!dev_priv->bridge_dev) {
197
        DRM_ERROR("bridge device not found\n");
198
        return -1;
199
    }
200
    return 0;
201
}
202
 
203
 
204
/* Global for IPS driver to get at the current i915 device */
205
static struct drm_i915_private *i915_mch_dev;
206
/*
207
 * Lock protecting IPS related data structures
208
 *   - i915_mch_dev
209
 *   - dev_priv->max_delay
210
 *   - dev_priv->min_delay
211
 *   - dev_priv->fmax
212
 *   - dev_priv->gpu_busy
213
 */
214
static DEFINE_SPINLOCK(mchdev_lock);
215
 
216
 
217
/**
218
 * i915_driver_load - setup chip and create an initial config
219
 * @dev: DRM device
220
 * @flags: startup flags
221
 *
222
 * The driver load routine has to do several things:
223
 *   - drive output discovery via intel_modeset_init()
224
 *   - initialize the memory manager
225
 *   - allocate initial config memory
226
 *   - setup the DRM framebuffer with the allocated memory
227
 */
228
int i915_driver_load(struct drm_device *dev, unsigned long flags)
229
{
230
    struct drm_i915_private *dev_priv;
231
    int ret = 0, mmio_bar;
232
    uint32_t agp_size;
233
 
234
    ENTER();
235
 
236
    dev_priv = kzalloc(sizeof(drm_i915_private_t), GFP_KERNEL);
237
    if (dev_priv == NULL)
238
        return -ENOMEM;
239
 
240
    dev->dev_private = (void *)dev_priv;
241
    dev_priv->dev = dev;
242
    dev_priv->info = (struct intel_device_info *) flags;
243
 
244
    if (i915_get_bridge_dev(dev)) {
245
        ret = -EIO;
246
        goto free_priv;
247
    }
248
 
249
    /* overlay on gen2 is broken and can't address above 1G */
250
//    if (IS_GEN2(dev))
251
//        dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(30));
252
 
253
    /* 965GM sometimes incorrectly writes to hardware status page (HWS)
254
     * using 32bit addressing, overwriting memory if HWS is located
255
     * above 4GB.
256
     *
257
     * The documentation also mentions an issue with undefined
258
     * behaviour if any general state is accessed within a page above 4GB,
259
     * which also needs to be handled carefully.
260
     */
261
//    if (IS_BROADWATER(dev) || IS_CRESTLINE(dev))
262
//        dma_set_coherent_mask(&dev->pdev->dev, DMA_BIT_MASK(32));
263
 
264
    mmio_bar = IS_GEN2(dev) ? 1 : 0;
265
    dev_priv->regs = pci_iomap(dev->pdev, mmio_bar, 0);
266
    if (!dev_priv->regs) {
267
        DRM_ERROR("failed to map registers\n");
268
        ret = -EIO;
269
        goto put_bridge;
270
    }
271
 
272
    dev_priv->mm.gtt = intel_gtt_get();