~ubuntu-branches/debian/wheezy/linux-2.6/wheezy

« back to all changes in this revision

Viewing changes to drivers/staging/gma500/psb_intel_display.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno
  • Date: 2011-06-07 12:14:05 UTC
  • mfrom: (43.1.9 sid)
  • Revision ID: james.westby@ubuntu.com-20110607121405-i3h1rd7nrnd2b73h
Tags: 2.6.39-2
[ Ben Hutchings ]
* [x86] Enable BACKLIGHT_APPLE, replacing BACKLIGHT_MBP_NVIDIA
  (Closes: #627492)
* cgroups: Disable memory resource controller by default. Allow it
  to be enabled using kernel parameter 'cgroup_enable=memory'.
* rt2800usb: Enable support for more USB devices including
  Linksys WUSB600N (Closes: #596626) (this change was accidentally
  omitted from 2.6.39-1)
* [x86] Remove Celeron from list of processors supporting PAE. Most
  'Celeron M' models do not.
* Update debconf template translations:
  - Swedish (Martin Bagge) (Closes: #628932)
  - French (David Prévot) (Closes: #628191)
* aufs: Update for 2.6.39 (Closes: #627837)
* Add stable 2.6.39.1, including:
  - ext4: dont set PageUptodate in ext4_end_bio()
  - pata_cmd64x: fix boot crash on parisc (Closes: #622997, #622745)
  - ext3: Fix fs corruption when make_indexed_dir() fails
  - netfilter: nf_ct_sip: validate Content-Length in TCP SIP messages
  - sctp: fix race between sctp_bind_addr_free() and
    sctp_bind_addr_conflict()
  - sctp: fix memory leak of the ASCONF queue when free asoc
  - md/bitmap: fix saving of events_cleared and other state
  - cdc_acm: Fix oops when Droids MuIn LCD is connected
  - cx88: Fix conversion from BKL to fine-grained locks (Closes: #619827)
  - keys: Set cred->user_ns in key_replace_session_keyring (CVE-2011-2184)
  - tmpfs: fix race between truncate and writepage
  - nfs41: Correct offset for LAYOUTCOMMIT
  - xen/mmu: fix a race window causing leave_mm BUG()
  - ext4: fix possible use-after-free in ext4_remove_li_request()
  For the complete list of changes, see:
   http://www.kernel.org/pub/linux/kernel/v2.6/ChangeLog-2.6.39.1
* Bump ABI to 2
* netfilter: Enable IP_SET, IP_SET_BITMAP_IP, IP_SET_BITMAP_IPMAC,
  IP_SET_BITMAP_PORT, IP_SET_HASH_IP, IP_SET_HASH_IPPORT,
  IP_SET_HASH_IPPORTIP, IP_SET_HASH_IPPORTNET, IP_SET_HASH_NET,
  IP_SET_HASH_NETPORT, IP_SET_LIST_SET, NETFILTER_XT_SET as modules
  (Closes: #629401)

[ Aurelien Jarno ]
* [mipsel/loongson-2f] Disable_SCSI_LPFC to workaround GCC ICE.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright Â© 2006-2007 Intel Corporation
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or modify it
 
5
 * under the terms and conditions of the GNU General Public License,
 
6
 * version 2, as published by the Free Software Foundation.
 
7
 *
 
8
 * This program is distributed in the hope it will be useful, but WITHOUT
 
9
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
10
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
11
 * more details.
 
12
 *
 
13
 * You should have received a copy of the GNU General Public License along with
 
14
 * this program; if not, write to the Free Software Foundation, Inc.,
 
15
 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
 
16
 *
 
17
 * Authors:
 
18
 *      Eric Anholt <eric@anholt.net>
 
19
 */
 
20
 
 
21
#include <linux/i2c.h>
 
22
#include <linux/pm_runtime.h>
 
23
 
 
24
#include <drm/drmP.h>
 
25
#include "psb_fb.h"
 
26
#include "psb_drv.h"
 
27
#include "psb_intel_drv.h"
 
28
#include "psb_intel_reg.h"
 
29
#include "psb_intel_display.h"
 
30
#include "psb_powermgmt.h"
 
31
 
 
32
 
 
33
struct psb_intel_clock_t {
 
34
        /* given values */
 
35
        int n;
 
36
        int m1, m2;
 
37
        int p1, p2;
 
38
        /* derived values */
 
39
        int dot;
 
40
        int vco;
 
41
        int m;
 
42
        int p;
 
43
};
 
44
 
 
45
struct psb_intel_range_t {
 
46
        int min, max;
 
47
};
 
48
 
 
49
struct psb_intel_p2_t {
 
50
        int dot_limit;
 
51
        int p2_slow, p2_fast;
 
52
};
 
53
 
 
54
#define INTEL_P2_NUM                  2
 
55
 
 
56
struct psb_intel_limit_t {
 
57
        struct psb_intel_range_t dot, vco, n, m, m1, m2, p, p1;
 
58
        struct psb_intel_p2_t p2;
 
59
};
 
60
 
 
61
#define I8XX_DOT_MIN              25000
 
62
#define I8XX_DOT_MAX             350000
 
63
#define I8XX_VCO_MIN             930000
 
64
#define I8XX_VCO_MAX            1400000
 
65
#define I8XX_N_MIN                    3
 
66
#define I8XX_N_MAX                   16
 
67
#define I8XX_M_MIN                   96
 
68
#define I8XX_M_MAX                  140
 
69
#define I8XX_M1_MIN                  18
 
70
#define I8XX_M1_MAX                  26
 
71
#define I8XX_M2_MIN                   6
 
72
#define I8XX_M2_MAX                  16
 
73
#define I8XX_P_MIN                    4
 
74
#define I8XX_P_MAX                  128
 
75
#define I8XX_P1_MIN                   2
 
76
#define I8XX_P1_MAX                  33
 
77
#define I8XX_P1_LVDS_MIN              1
 
78
#define I8XX_P1_LVDS_MAX              6
 
79
#define I8XX_P2_SLOW                  4
 
80
#define I8XX_P2_FAST                  2
 
81
#define I8XX_P2_LVDS_SLOW             14
 
82
#define I8XX_P2_LVDS_FAST             14        /* No fast option */
 
83
#define I8XX_P2_SLOW_LIMIT       165000
 
84
 
 
85
#define I9XX_DOT_MIN              20000
 
86
#define I9XX_DOT_MAX             400000
 
87
#define I9XX_VCO_MIN            1400000
 
88
#define I9XX_VCO_MAX            2800000
 
89
#define I9XX_N_MIN                    3
 
90
#define I9XX_N_MAX                    8
 
91
#define I9XX_M_MIN                   70
 
92
#define I9XX_M_MAX                  120
 
93
#define I9XX_M1_MIN                  10
 
94
#define I9XX_M1_MAX                  20
 
95
#define I9XX_M2_MIN                   5
 
96
#define I9XX_M2_MAX                   9
 
97
#define I9XX_P_SDVO_DAC_MIN           5
 
98
#define I9XX_P_SDVO_DAC_MAX          80
 
99
#define I9XX_P_LVDS_MIN               7
 
100
#define I9XX_P_LVDS_MAX              98
 
101
#define I9XX_P1_MIN                   1
 
102
#define I9XX_P1_MAX                   8
 
103
#define I9XX_P2_SDVO_DAC_SLOW                10
 
104
#define I9XX_P2_SDVO_DAC_FAST                 5
 
105
#define I9XX_P2_SDVO_DAC_SLOW_LIMIT      200000
 
106
#define I9XX_P2_LVDS_SLOW                    14
 
107
#define I9XX_P2_LVDS_FAST                     7
 
108
#define I9XX_P2_LVDS_SLOW_LIMIT          112000
 
109
 
 
110
#define INTEL_LIMIT_I8XX_DVO_DAC    0
 
111
#define INTEL_LIMIT_I8XX_LVDS       1
 
112
#define INTEL_LIMIT_I9XX_SDVO_DAC   2
 
113
#define INTEL_LIMIT_I9XX_LVDS       3
 
114
 
 
115
static const struct psb_intel_limit_t psb_intel_limits[] = {
 
116
        {                       /* INTEL_LIMIT_I8XX_DVO_DAC */
 
117
         .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
 
118
         .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
 
119
         .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
 
120
         .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
 
121
         .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
 
122
         .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
 
123
         .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
 
124
         .p1 = {.min = I8XX_P1_MIN, .max = I8XX_P1_MAX},
 
125
         .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
 
126
                .p2_slow = I8XX_P2_SLOW, .p2_fast = I8XX_P2_FAST},
 
127
         },
 
128
        {                       /* INTEL_LIMIT_I8XX_LVDS */
 
129
         .dot = {.min = I8XX_DOT_MIN, .max = I8XX_DOT_MAX},
 
130
         .vco = {.min = I8XX_VCO_MIN, .max = I8XX_VCO_MAX},
 
131
         .n = {.min = I8XX_N_MIN, .max = I8XX_N_MAX},
 
132
         .m = {.min = I8XX_M_MIN, .max = I8XX_M_MAX},
 
133
         .m1 = {.min = I8XX_M1_MIN, .max = I8XX_M1_MAX},
 
134
         .m2 = {.min = I8XX_M2_MIN, .max = I8XX_M2_MAX},
 
135
         .p = {.min = I8XX_P_MIN, .max = I8XX_P_MAX},
 
136
         .p1 = {.min = I8XX_P1_LVDS_MIN, .max = I8XX_P1_LVDS_MAX},
 
137
         .p2 = {.dot_limit = I8XX_P2_SLOW_LIMIT,
 
138
                .p2_slow = I8XX_P2_LVDS_SLOW, .p2_fast = I8XX_P2_LVDS_FAST},
 
139
         },
 
140
        {                       /* INTEL_LIMIT_I9XX_SDVO_DAC */
 
141
         .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
 
142
         .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
 
143
         .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
 
144
         .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
 
145
         .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
 
146
         .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
 
147
         .p = {.min = I9XX_P_SDVO_DAC_MIN, .max = I9XX_P_SDVO_DAC_MAX},
 
148
         .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
 
149
         .p2 = {.dot_limit = I9XX_P2_SDVO_DAC_SLOW_LIMIT,
 
150
                .p2_slow = I9XX_P2_SDVO_DAC_SLOW, .p2_fast =
 
151
                I9XX_P2_SDVO_DAC_FAST},
 
152
         },
 
153
        {                       /* INTEL_LIMIT_I9XX_LVDS */
 
154
         .dot = {.min = I9XX_DOT_MIN, .max = I9XX_DOT_MAX},
 
155
         .vco = {.min = I9XX_VCO_MIN, .max = I9XX_VCO_MAX},
 
156
         .n = {.min = I9XX_N_MIN, .max = I9XX_N_MAX},
 
157
         .m = {.min = I9XX_M_MIN, .max = I9XX_M_MAX},
 
158
         .m1 = {.min = I9XX_M1_MIN, .max = I9XX_M1_MAX},
 
159
         .m2 = {.min = I9XX_M2_MIN, .max = I9XX_M2_MAX},
 
160
         .p = {.min = I9XX_P_LVDS_MIN, .max = I9XX_P_LVDS_MAX},
 
161
         .p1 = {.min = I9XX_P1_MIN, .max = I9XX_P1_MAX},
 
162
         /* The single-channel range is 25-112Mhz, and dual-channel
 
163
          * is 80-224Mhz.  Prefer single channel as much as possible.
 
164
          */
 
165
         .p2 = {.dot_limit = I9XX_P2_LVDS_SLOW_LIMIT,
 
166
                .p2_slow = I9XX_P2_LVDS_SLOW, .p2_fast = I9XX_P2_LVDS_FAST},
 
167
         },
 
168
};
 
169
 
 
170
static const struct psb_intel_limit_t *psb_intel_limit(struct drm_crtc *crtc)
 
171
{
 
172
        const struct psb_intel_limit_t *limit;
 
173
 
 
174
        if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS))
 
175
                limit = &psb_intel_limits[INTEL_LIMIT_I9XX_LVDS];
 
176
        else
 
177
                limit = &psb_intel_limits[INTEL_LIMIT_I9XX_SDVO_DAC];
 
178
        return limit;
 
179
}
 
180
 
 
181
/** Derive the pixel clock for the given refclk and divisors for 8xx chips. */
 
182
 
 
183
static void i8xx_clock(int refclk, struct psb_intel_clock_t *clock)
 
184
{
 
185
        clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
 
186
        clock->p = clock->p1 * clock->p2;
 
187
        clock->vco = refclk * clock->m / (clock->n + 2);
 
188
        clock->dot = clock->vco / clock->p;
 
189
}
 
190
 
 
191
/** Derive the pixel clock for the given refclk and divisors for 9xx chips. */
 
192
 
 
193
static void i9xx_clock(int refclk, struct psb_intel_clock_t *clock)
 
194
{
 
195
        clock->m = 5 * (clock->m1 + 2) + (clock->m2 + 2);
 
196
        clock->p = clock->p1 * clock->p2;
 
197
        clock->vco = refclk * clock->m / (clock->n + 2);
 
198
        clock->dot = clock->vco / clock->p;
 
199
}
 
200
 
 
201
static void psb_intel_clock(struct drm_device *dev, int refclk,
 
202
                        struct psb_intel_clock_t *clock)
 
203
{
 
204
        return i9xx_clock(refclk, clock);
 
205
}
 
206
 
 
207
/**
 
208
 * Returns whether any output on the specified pipe is of the specified type
 
209
 */
 
210
bool psb_intel_pipe_has_type(struct drm_crtc *crtc, int type)
 
211
{
 
212
        struct drm_device *dev = crtc->dev;
 
213
        struct drm_mode_config *mode_config = &dev->mode_config;
 
214
        struct drm_connector *l_entry;
 
215
 
 
216
        list_for_each_entry(l_entry, &mode_config->connector_list, head) {
 
217
                if (l_entry->encoder && l_entry->encoder->crtc == crtc) {
 
218
                        struct psb_intel_output *psb_intel_output =
 
219
                            to_psb_intel_output(l_entry);
 
220
                        if (psb_intel_output->type == type)
 
221
                                return true;
 
222
                }
 
223
        }
 
224
        return false;
 
225
}
 
226
 
 
227
#define INTELPllInvalid(s)   { /* ErrorF (s) */; return false; }
 
228
/**
 
229
 * Returns whether the given set of divisors are valid for a given refclk with
 
230
 * the given connectors.
 
231
 */
 
232
 
 
233
static bool psb_intel_PLL_is_valid(struct drm_crtc *crtc,
 
234
                               struct psb_intel_clock_t *clock)
 
235
{
 
236
        const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
 
237
 
 
238
        if (clock->p1 < limit->p1.min || limit->p1.max < clock->p1)
 
239
                INTELPllInvalid("p1 out of range\n");
 
240
        if (clock->p < limit->p.min || limit->p.max < clock->p)
 
241
                INTELPllInvalid("p out of range\n");
 
242
        if (clock->m2 < limit->m2.min || limit->m2.max < clock->m2)
 
243
                INTELPllInvalid("m2 out of range\n");
 
244
        if (clock->m1 < limit->m1.min || limit->m1.max < clock->m1)
 
245
                INTELPllInvalid("m1 out of range\n");
 
246
        if (clock->m1 <= clock->m2)
 
247
                INTELPllInvalid("m1 <= m2\n");
 
248
        if (clock->m < limit->m.min || limit->m.max < clock->m)
 
249
                INTELPllInvalid("m out of range\n");
 
250
        if (clock->n < limit->n.min || limit->n.max < clock->n)
 
251
                INTELPllInvalid("n out of range\n");
 
252
        if (clock->vco < limit->vco.min || limit->vco.max < clock->vco)
 
253
                INTELPllInvalid("vco out of range\n");
 
254
        /* XXX: We may need to be checking "Dot clock"
 
255
         * depending on the multiplier, connector, etc.,
 
256
         * rather than just a single range.
 
257
         */
 
258
        if (clock->dot < limit->dot.min || limit->dot.max < clock->dot)
 
259
                INTELPllInvalid("dot out of range\n");
 
260
 
 
261
        return true;
 
262
}
 
263
 
 
264
/**
 
265
 * Returns a set of divisors for the desired target clock with the given
 
266
 * refclk, or FALSE.  The returned values represent the clock equation:
 
267
 * reflck * (5 * (m1 + 2) + (m2 + 2)) / (n + 2) / p1 / p2.
 
268
 */
 
269
static bool psb_intel_find_best_PLL(struct drm_crtc *crtc, int target,
 
270
                                int refclk,
 
271
                                struct psb_intel_clock_t *best_clock)
 
272
{
 
273
        struct drm_device *dev = crtc->dev;
 
274
        struct psb_intel_clock_t clock;
 
275
        const struct psb_intel_limit_t *limit = psb_intel_limit(crtc);
 
276
        int err = target;
 
277
 
 
278
        if (psb_intel_pipe_has_type(crtc, INTEL_OUTPUT_LVDS) &&
 
279
            (REG_READ(LVDS) & LVDS_PORT_EN) != 0) {
 
280
                /*
 
281
                 * For LVDS, if the panel is on, just rely on its current
 
282
                 * settings for dual-channel.  We haven't figured out how to
 
283
                 * reliably set up different single/dual channel state, if we
 
284
                 * even can.
 
285
                 */
 
286
                if ((REG_READ(LVDS) & LVDS_CLKB_POWER_MASK) ==
 
287
                    LVDS_CLKB_POWER_UP)
 
288
                        clock.p2 = limit->p2.p2_fast;
 
289
                else
 
290
                        clock.p2 = limit->p2.p2_slow;
 
291
        } else {
 
292
                if (target < limit->p2.dot_limit)
 
293
                        clock.p2 = limit->p2.p2_slow;
 
294
                else
 
295
                        clock.p2 = limit->p2.p2_fast;
 
296
        }
 
297
 
 
298
        memset(best_clock, 0, sizeof(*best_clock));
 
299
 
 
300
        for (clock.m1 = limit->m1.min; clock.m1 <= limit->m1.max;
 
301
             clock.m1++) {
 
302
                for (clock.m2 = limit->m2.min;
 
303
                     clock.m2 < clock.m1 && clock.m2 <= limit->m2.max;
 
304
                     clock.m2++) {
 
305
                        for (clock.n = limit->n.min;
 
306
                             clock.n <= limit->n.max; clock.n++) {
 
307
                                for (clock.p1 = limit->p1.min;
 
308
                                     clock.p1 <= limit->p1.max;
 
309
                                     clock.p1++) {
 
310
                                        int this_err;
 
311
 
 
312
                                        psb_intel_clock(dev, refclk, &clock);
 
313
 
 
314
                                        if (!psb_intel_PLL_is_valid
 
315
                                            (crtc, &clock))
 
316
                                                continue;
 
317
 
 
318
                                        this_err = abs(clock.dot - target);
 
319
                                        if (this_err < err) {
 
320
                                                *best_clock = clock;
 
321
                                                err = this_err;
 
322
                                        }
 
323
                                }
 
324
                        }
 
325
                }
 
326
        }
 
327
 
 
328
        return err != target;
 
329
}
 
330
 
 
331
void psb_intel_wait_for_vblank(struct drm_device *dev)
 
332
{
 
333
        /* Wait for 20ms, i.e. one cycle at 50hz. */
 
334
        udelay(20000);
 
335
}
 
336
 
 
337
int psb_intel_pipe_set_base(struct drm_crtc *crtc,
 
338
                            int x, int y, struct drm_framebuffer *old_fb)
 
339
{
 
340
        struct drm_device *dev = crtc->dev;
 
341
        /* struct drm_i915_master_private *master_priv; */
 
342
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
343
        struct psb_framebuffer *psbfb = to_psb_fb(crtc->fb);
 
344
        struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
 
345
        int pipe = psb_intel_crtc->pipe;
 
346
        unsigned long Start, Offset;
 
347
        int dspbase = (pipe == 0 ? DSPABASE : DSPBBASE);
 
348
        int dspsurf = (pipe == 0 ? DSPASURF : DSPBSURF);
 
349
        int dspstride = (pipe == 0) ? DSPASTRIDE : DSPBSTRIDE;
 
350
        int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 
351
        u32 dspcntr;
 
352
        int ret = 0;
 
353
 
 
354
        PSB_DEBUG_ENTRY("\n");
 
355
 
 
356
        /* no fb bound */
 
357
        if (!crtc->fb) {
 
358
                DRM_DEBUG("No FB bound\n");
 
359
                return 0;
 
360
        }
 
361
 
 
362
        if (!ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
 
363
                                       OSPM_UHB_FORCE_POWER_ON))
 
364
                return 0;
 
365
 
 
366
        Start = mode_dev->bo_offset(dev, psbfb);
 
367
        Offset = y * crtc->fb->pitch + x * (crtc->fb->bits_per_pixel / 8);
 
368
 
 
369
        REG_WRITE(dspstride, crtc->fb->pitch);
 
370
 
 
371
        dspcntr = REG_READ(dspcntr_reg);
 
372
        dspcntr &= ~DISPPLANE_PIXFORMAT_MASK;
 
373
 
 
374
        switch (crtc->fb->bits_per_pixel) {
 
375
        case 8:
 
376
                dspcntr |= DISPPLANE_8BPP;
 
377
                break;
 
378
        case 16:
 
379
                if (crtc->fb->depth == 15)
 
380
                        dspcntr |= DISPPLANE_15_16BPP;
 
381
                else
 
382
                        dspcntr |= DISPPLANE_16BPP;
 
383
                break;
 
384
        case 24:
 
385
        case 32:
 
386
                dspcntr |= DISPPLANE_32BPP_NO_ALPHA;
 
387
                break;
 
388
        default:
 
389
                DRM_ERROR("Unknown color depth\n");
 
390
                ret = -EINVAL;
 
391
                goto psb_intel_pipe_set_base_exit;
 
392
        }
 
393
        REG_WRITE(dspcntr_reg, dspcntr);
 
394
 
 
395
        DRM_DEBUG("Writing base %08lX %08lX %d %d\n", Start, Offset, x, y);
 
396
        if (0 /* FIXMEAC - check what PSB needs */) {
 
397
                REG_WRITE(dspbase, Offset);
 
398
                REG_READ(dspbase);
 
399
                REG_WRITE(dspsurf, Start);
 
400
                REG_READ(dspsurf);
 
401
        } else {
 
402
                REG_WRITE(dspbase, Start + Offset);
 
403
                REG_READ(dspbase);
 
404
        }
 
405
 
 
406
psb_intel_pipe_set_base_exit:
 
407
 
 
408
        ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 
409
 
 
410
        return ret;
 
411
}
 
412
 
 
413
/**
 
414
 * Sets the power management mode of the pipe and plane.
 
415
 *
 
416
 * This code should probably grow support for turning the cursor off and back
 
417
 * on appropriately at the same time as we're turning the pipe off/on.
 
418
 */
 
419
static void psb_intel_crtc_dpms(struct drm_crtc *crtc, int mode)
 
420
{
 
421
        struct drm_device *dev = crtc->dev;
 
422
        /* struct drm_i915_master_private *master_priv; */
 
423
        /* struct drm_i915_private *dev_priv = dev->dev_private; */
 
424
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
425
        int pipe = psb_intel_crtc->pipe;
 
426
        int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 
427
        int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 
428
        int dspbase_reg = (pipe == 0) ? DSPABASE : DSPBBASE;
 
429
        int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
 
430
        u32 temp;
 
431
        bool enabled;
 
432
 
 
433
        /* XXX: When our outputs are all unaware of DPMS modes other than off
 
434
         * and on, we should map those modes to DRM_MODE_DPMS_OFF in the CRTC.
 
435
         */
 
436
        switch (mode) {
 
437
        case DRM_MODE_DPMS_ON:
 
438
        case DRM_MODE_DPMS_STANDBY:
 
439
        case DRM_MODE_DPMS_SUSPEND:
 
440
                /* Enable the DPLL */
 
441
                temp = REG_READ(dpll_reg);
 
442
                if ((temp & DPLL_VCO_ENABLE) == 0) {
 
443
                        REG_WRITE(dpll_reg, temp);
 
444
                        REG_READ(dpll_reg);
 
445
                        /* Wait for the clocks to stabilize. */
 
446
                        udelay(150);
 
447
                        REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
 
448
                        REG_READ(dpll_reg);
 
449
                        /* Wait for the clocks to stabilize. */
 
450
                        udelay(150);
 
451
                        REG_WRITE(dpll_reg, temp | DPLL_VCO_ENABLE);
 
452
                        REG_READ(dpll_reg);
 
453
                        /* Wait for the clocks to stabilize. */
 
454
                        udelay(150);
 
455
                }
 
456
 
 
457
                /* Enable the pipe */
 
458
                temp = REG_READ(pipeconf_reg);
 
459
                if ((temp & PIPEACONF_ENABLE) == 0)
 
460
                        REG_WRITE(pipeconf_reg, temp | PIPEACONF_ENABLE);
 
461
 
 
462
                /* Enable the plane */
 
463
                temp = REG_READ(dspcntr_reg);
 
464
                if ((temp & DISPLAY_PLANE_ENABLE) == 0) {
 
465
                        REG_WRITE(dspcntr_reg,
 
466
                                  temp | DISPLAY_PLANE_ENABLE);
 
467
                        /* Flush the plane changes */
 
468
                        REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
 
469
                }
 
470
 
 
471
                psb_intel_crtc_load_lut(crtc);
 
472
 
 
473
                /* Give the overlay scaler a chance to enable
 
474
                 * if it's on this pipe */
 
475
                /* psb_intel_crtc_dpms_video(crtc, true); TODO */
 
476
                break;
 
477
        case DRM_MODE_DPMS_OFF:
 
478
                /* Give the overlay scaler a chance to disable
 
479
                 * if it's on this pipe */
 
480
                /* psb_intel_crtc_dpms_video(crtc, FALSE); TODO */
 
481
 
 
482
                /* Disable the VGA plane that we never use */
 
483
                REG_WRITE(VGACNTRL, VGA_DISP_DISABLE);
 
484
 
 
485
                /* Disable display plane */
 
486
                temp = REG_READ(dspcntr_reg);
 
487
                if ((temp & DISPLAY_PLANE_ENABLE) != 0) {
 
488
                        REG_WRITE(dspcntr_reg,
 
489
                                  temp & ~DISPLAY_PLANE_ENABLE);
 
490
                        /* Flush the plane changes */
 
491
                        REG_WRITE(dspbase_reg, REG_READ(dspbase_reg));
 
492
                        REG_READ(dspbase_reg);
 
493
                }
 
494
 
 
495
                /* Next, disable display pipes */
 
496
                temp = REG_READ(pipeconf_reg);
 
497
                if ((temp & PIPEACONF_ENABLE) != 0) {
 
498
                        REG_WRITE(pipeconf_reg, temp & ~PIPEACONF_ENABLE);
 
499
                        REG_READ(pipeconf_reg);
 
500
                }
 
501
 
 
502
                /* Wait for vblank for the disable to take effect. */
 
503
                psb_intel_wait_for_vblank(dev);
 
504
 
 
505
                temp = REG_READ(dpll_reg);
 
506
                if ((temp & DPLL_VCO_ENABLE) != 0) {
 
507
                        REG_WRITE(dpll_reg, temp & ~DPLL_VCO_ENABLE);
 
508
                        REG_READ(dpll_reg);
 
509
                }
 
510
 
 
511
                /* Wait for the clocks to turn off. */
 
512
                udelay(150);
 
513
                break;
 
514
        }
 
515
 
 
516
        enabled = crtc->enabled && mode != DRM_MODE_DPMS_OFF;
 
517
 
 
518
        /*Set FIFO Watermarks*/
 
519
        REG_WRITE(DSPARB, 0x3F3E);
 
520
}
 
521
 
 
522
static void psb_intel_crtc_prepare(struct drm_crtc *crtc)
 
523
{
 
524
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
525
        crtc_funcs->dpms(crtc, DRM_MODE_DPMS_OFF);
 
526
}
 
527
 
 
528
static void psb_intel_crtc_commit(struct drm_crtc *crtc)
 
529
{
 
530
        struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;
 
531
        crtc_funcs->dpms(crtc, DRM_MODE_DPMS_ON);
 
532
}
 
533
 
 
534
void psb_intel_encoder_prepare(struct drm_encoder *encoder)
 
535
{
 
536
        struct drm_encoder_helper_funcs *encoder_funcs =
 
537
            encoder->helper_private;
 
538
        /* lvds has its own version of prepare see psb_intel_lvds_prepare */
 
539
        encoder_funcs->dpms(encoder, DRM_MODE_DPMS_OFF);
 
540
}
 
541
 
 
542
void psb_intel_encoder_commit(struct drm_encoder *encoder)
 
543
{
 
544
        struct drm_encoder_helper_funcs *encoder_funcs =
 
545
            encoder->helper_private;
 
546
        /* lvds has its own version of commit see psb_intel_lvds_commit */
 
547
        encoder_funcs->dpms(encoder, DRM_MODE_DPMS_ON);
 
548
}
 
549
 
 
550
static bool psb_intel_crtc_mode_fixup(struct drm_crtc *crtc,
 
551
                                  struct drm_display_mode *mode,
 
552
                                  struct drm_display_mode *adjusted_mode)
 
553
{
 
554
        return true;
 
555
}
 
556
 
 
557
 
 
558
/**
 
559
 * Return the pipe currently connected to the panel fitter,
 
560
 * or -1 if the panel fitter is not present or not in use
 
561
 */
 
562
static int psb_intel_panel_fitter_pipe(struct drm_device *dev)
 
563
{
 
564
        u32 pfit_control;
 
565
 
 
566
        pfit_control = REG_READ(PFIT_CONTROL);
 
567
 
 
568
        /* See if the panel fitter is in use */
 
569
        if ((pfit_control & PFIT_ENABLE) == 0)
 
570
                return -1;
 
571
        /* Must be on PIPE 1 for PSB */
 
572
        return 1;
 
573
}
 
574
 
 
575
static int psb_intel_crtc_mode_set(struct drm_crtc *crtc,
 
576
                               struct drm_display_mode *mode,
 
577
                               struct drm_display_mode *adjusted_mode,
 
578
                               int x, int y,
 
579
                               struct drm_framebuffer *old_fb)
 
580
{
 
581
        struct drm_device *dev = crtc->dev;
 
582
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
583
        int pipe = psb_intel_crtc->pipe;
 
584
        int fp_reg = (pipe == 0) ? FPA0 : FPB0;
 
585
        int dpll_reg = (pipe == 0) ? DPLL_A : DPLL_B;
 
586
        int dspcntr_reg = (pipe == 0) ? DSPACNTR : DSPBCNTR;
 
587
        int pipeconf_reg = (pipe == 0) ? PIPEACONF : PIPEBCONF;
 
588
        int htot_reg = (pipe == 0) ? HTOTAL_A : HTOTAL_B;
 
589
        int hblank_reg = (pipe == 0) ? HBLANK_A : HBLANK_B;
 
590
        int hsync_reg = (pipe == 0) ? HSYNC_A : HSYNC_B;
 
591
        int vtot_reg = (pipe == 0) ? VTOTAL_A : VTOTAL_B;
 
592
        int vblank_reg = (pipe == 0) ? VBLANK_A : VBLANK_B;
 
593
        int vsync_reg = (pipe == 0) ? VSYNC_A : VSYNC_B;
 
594
        int dspsize_reg = (pipe == 0) ? DSPASIZE : DSPBSIZE;
 
595
        int dsppos_reg = (pipe == 0) ? DSPAPOS : DSPBPOS;
 
596
        int pipesrc_reg = (pipe == 0) ? PIPEASRC : PIPEBSRC;
 
597
        int refclk;
 
598
        struct psb_intel_clock_t clock;
 
599
        u32 dpll = 0, fp = 0, dspcntr, pipeconf;
 
600
        bool ok, is_sdvo = false, is_dvo = false;
 
601
        bool is_crt = false, is_lvds = false, is_tv = false;
 
602
        struct drm_mode_config *mode_config = &dev->mode_config;
 
603
        struct drm_connector *connector;
 
604
 
 
605
        list_for_each_entry(connector, &mode_config->connector_list, head) {
 
606
                struct psb_intel_output *psb_intel_output =
 
607
                    to_psb_intel_output(connector);
 
608
 
 
609
                if (!connector->encoder
 
610
                    || connector->encoder->crtc != crtc)
 
611
                        continue;
 
612
 
 
613
                switch (psb_intel_output->type) {
 
614
                case INTEL_OUTPUT_LVDS:
 
615
                        is_lvds = true;
 
616
                        break;
 
617
                case INTEL_OUTPUT_SDVO:
 
618
                        is_sdvo = true;
 
619
                        break;
 
620
                case INTEL_OUTPUT_DVO:
 
621
                        is_dvo = true;
 
622
                        break;
 
623
                case INTEL_OUTPUT_TVOUT:
 
624
                        is_tv = true;
 
625
                        break;
 
626
                case INTEL_OUTPUT_ANALOG:
 
627
                        is_crt = true;
 
628
                        break;
 
629
                }
 
630
        }
 
631
 
 
632
        refclk = 96000;
 
633
 
 
634
        ok = psb_intel_find_best_PLL(crtc, adjusted_mode->clock, refclk,
 
635
                                 &clock);
 
636
        if (!ok) {
 
637
                DRM_ERROR("Couldn't find PLL settings for mode!\n");
 
638
                return 0;
 
639
        }
 
640
 
 
641
        fp = clock.n << 16 | clock.m1 << 8 | clock.m2;
 
642
 
 
643
        dpll = DPLL_VGA_MODE_DIS;
 
644
        if (is_lvds) {
 
645
                dpll |= DPLLB_MODE_LVDS;
 
646
                dpll |= DPLL_DVO_HIGH_SPEED;
 
647
        } else
 
648
                dpll |= DPLLB_MODE_DAC_SERIAL;
 
649
        if (is_sdvo) {
 
650
                int sdvo_pixel_multiply =
 
651
                            adjusted_mode->clock / mode->clock;
 
652
                dpll |= DPLL_DVO_HIGH_SPEED;
 
653
                dpll |=
 
654
                    (sdvo_pixel_multiply - 1) << SDVO_MULTIPLIER_SHIFT_HIRES;
 
655
        }
 
656
 
 
657
        /* compute bitmask from p1 value */
 
658
        dpll |= (1 << (clock.p1 - 1)) << 16;
 
659
        switch (clock.p2) {
 
660
        case 5:
 
661
                dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_5;
 
662
                break;
 
663
        case 7:
 
664
                dpll |= DPLLB_LVDS_P2_CLOCK_DIV_7;
 
665
                break;
 
666
        case 10:
 
667
                dpll |= DPLL_DAC_SERIAL_P2_CLOCK_DIV_10;
 
668
                break;
 
669
        case 14:
 
670
                dpll |= DPLLB_LVDS_P2_CLOCK_DIV_14;
 
671
                break;
 
672
        }
 
673
 
 
674
        if (is_tv) {
 
675
                /* XXX: just matching BIOS for now */
 
676
/*      dpll |= PLL_REF_INPUT_TVCLKINBC; */
 
677
                dpll |= 3;
 
678
        }
 
679
        dpll |= PLL_REF_INPUT_DREFCLK;
 
680
 
 
681
        /* setup pipeconf */
 
682
        pipeconf = REG_READ(pipeconf_reg);
 
683
 
 
684
        /* Set up the display plane register */
 
685
        dspcntr = DISPPLANE_GAMMA_ENABLE;
 
686
 
 
687
        if (pipe == 0)
 
688
                dspcntr |= DISPPLANE_SEL_PIPE_A;
 
689
        else
 
690
                dspcntr |= DISPPLANE_SEL_PIPE_B;
 
691
 
 
692
        dspcntr |= DISPLAY_PLANE_ENABLE;
 
693
        pipeconf |= PIPEACONF_ENABLE;
 
694
        dpll |= DPLL_VCO_ENABLE;
 
695
 
 
696
 
 
697
        /* Disable the panel fitter if it was on our pipe */
 
698
        if (psb_intel_panel_fitter_pipe(dev) == pipe)
 
699
                REG_WRITE(PFIT_CONTROL, 0);
 
700
 
 
701
        DRM_DEBUG("Mode for pipe %c:\n", pipe == 0 ? 'A' : 'B');
 
702
        drm_mode_debug_printmodeline(mode);
 
703
 
 
704
        if (dpll & DPLL_VCO_ENABLE) {
 
705
                REG_WRITE(fp_reg, fp);
 
706
                REG_WRITE(dpll_reg, dpll & ~DPLL_VCO_ENABLE);
 
707
                REG_READ(dpll_reg);
 
708
                udelay(150);
 
709
        }
 
710
 
 
711
        /* The LVDS pin pair needs to be on before the DPLLs are enabled.
 
712
         * This is an exception to the general rule that mode_set doesn't turn
 
713
         * things on.
 
714
         */
 
715
        if (is_lvds) {
 
716
                u32 lvds = REG_READ(LVDS);
 
717
 
 
718
                lvds |=
 
719
                    LVDS_PORT_EN | LVDS_A0A2_CLKA_POWER_UP |
 
720
                    LVDS_PIPEB_SELECT;
 
721
                /* Set the B0-B3 data pairs corresponding to
 
722
                 * whether we're going to
 
723
                 * set the DPLLs for dual-channel mode or not.
 
724
                 */
 
725
                if (clock.p2 == 7)
 
726
                        lvds |= LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP;
 
727
                else
 
728
                        lvds &= ~(LVDS_B0B3_POWER_UP | LVDS_CLKB_POWER_UP);
 
729
 
 
730
                /* It would be nice to set 24 vs 18-bit mode (LVDS_A3_POWER_UP)
 
731
                 * appropriately here, but we need to look more
 
732
                 * thoroughly into how panels behave in the two modes.
 
733
                 */
 
734
 
 
735
                REG_WRITE(LVDS, lvds);
 
736
                REG_READ(LVDS);
 
737
        }
 
738
 
 
739
        REG_WRITE(fp_reg, fp);
 
740
        REG_WRITE(dpll_reg, dpll);
 
741
        REG_READ(dpll_reg);
 
742
        /* Wait for the clocks to stabilize. */
 
743
        udelay(150);
 
744
 
 
745
        /* write it again -- the BIOS does, after all */
 
746
        REG_WRITE(dpll_reg, dpll);
 
747
 
 
748
        REG_READ(dpll_reg);
 
749
        /* Wait for the clocks to stabilize. */
 
750
        udelay(150);
 
751
 
 
752
        REG_WRITE(htot_reg, (adjusted_mode->crtc_hdisplay - 1) |
 
753
                  ((adjusted_mode->crtc_htotal - 1) << 16));
 
754
        REG_WRITE(hblank_reg, (adjusted_mode->crtc_hblank_start - 1) |
 
755
                  ((adjusted_mode->crtc_hblank_end - 1) << 16));
 
756
        REG_WRITE(hsync_reg, (adjusted_mode->crtc_hsync_start - 1) |
 
757
                  ((adjusted_mode->crtc_hsync_end - 1) << 16));
 
758
        REG_WRITE(vtot_reg, (adjusted_mode->crtc_vdisplay - 1) |
 
759
                  ((adjusted_mode->crtc_vtotal - 1) << 16));
 
760
        REG_WRITE(vblank_reg, (adjusted_mode->crtc_vblank_start - 1) |
 
761
                  ((adjusted_mode->crtc_vblank_end - 1) << 16));
 
762
        REG_WRITE(vsync_reg, (adjusted_mode->crtc_vsync_start - 1) |
 
763
                  ((adjusted_mode->crtc_vsync_end - 1) << 16));
 
764
        /* pipesrc and dspsize control the size that is scaled from,
 
765
         * which should always be the user's requested size.
 
766
         */
 
767
        REG_WRITE(dspsize_reg,
 
768
                  ((mode->vdisplay - 1) << 16) | (mode->hdisplay - 1));
 
769
        REG_WRITE(dsppos_reg, 0);
 
770
        REG_WRITE(pipesrc_reg,
 
771
                  ((mode->hdisplay - 1) << 16) | (mode->vdisplay - 1));
 
772
        REG_WRITE(pipeconf_reg, pipeconf);
 
773
        REG_READ(pipeconf_reg);
 
774
 
 
775
        psb_intel_wait_for_vblank(dev);
 
776
 
 
777
        REG_WRITE(dspcntr_reg, dspcntr);
 
778
 
 
779
        /* Flush the plane changes */
 
780
        {
 
781
                struct drm_crtc_helper_funcs *crtc_funcs =
 
782
                    crtc->helper_private;
 
783
                crtc_funcs->mode_set_base(crtc, x, y, old_fb);
 
784
        }
 
785
 
 
786
        psb_intel_wait_for_vblank(dev);
 
787
 
 
788
        return 0;
 
789
}
 
790
 
 
791
/** Loads the palette/gamma unit for the CRTC with the prepared values */
 
792
void psb_intel_crtc_load_lut(struct drm_crtc *crtc)
 
793
{
 
794
        struct drm_device *dev = crtc->dev;
 
795
        struct drm_psb_private *dev_priv =
 
796
                                (struct drm_psb_private *)dev->dev_private;
 
797
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
798
        int palreg = PALETTE_A;
 
799
        int i;
 
800
 
 
801
        /* The clocks have to be on to load the palette. */
 
802
        if (!crtc->enabled)
 
803
                return;
 
804
 
 
805
        switch (psb_intel_crtc->pipe) {
 
806
        case 0:
 
807
                break;
 
808
        case 1:
 
809
                palreg = PALETTE_B;
 
810
                break;
 
811
        case 2:
 
812
                palreg = PALETTE_C;
 
813
                break;
 
814
        default:
 
815
                DRM_ERROR("Illegal Pipe Number.\n");
 
816
                return;
 
817
        }
 
818
 
 
819
        if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
 
820
                                      OSPM_UHB_ONLY_IF_ON)) {
 
821
                for (i = 0; i < 256; i++) {
 
822
                        REG_WRITE(palreg + 4 * i,
 
823
                                  ((psb_intel_crtc->lut_r[i] +
 
824
                                  psb_intel_crtc->lut_adj[i]) << 16) |
 
825
                                  ((psb_intel_crtc->lut_g[i] +
 
826
                                  psb_intel_crtc->lut_adj[i]) << 8) |
 
827
                                  (psb_intel_crtc->lut_b[i] +
 
828
                                  psb_intel_crtc->lut_adj[i]));
 
829
                }
 
830
                ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 
831
        } else {
 
832
                for (i = 0; i < 256; i++) {
 
833
                        dev_priv->save_palette_a[i] =
 
834
                                  ((psb_intel_crtc->lut_r[i] +
 
835
                                  psb_intel_crtc->lut_adj[i]) << 16) |
 
836
                                  ((psb_intel_crtc->lut_g[i] +
 
837
                                  psb_intel_crtc->lut_adj[i]) << 8) |
 
838
                                  (psb_intel_crtc->lut_b[i] +
 
839
                                  psb_intel_crtc->lut_adj[i]);
 
840
                }
 
841
 
 
842
        }
 
843
}
 
844
 
 
845
/**
 
846
 * Save HW states of giving crtc
 
847
 */
 
848
static void psb_intel_crtc_save(struct drm_crtc *crtc)
 
849
{
 
850
        struct drm_device *dev = crtc->dev;
 
851
        /* struct drm_psb_private *dev_priv =
 
852
                        (struct drm_psb_private *)dev->dev_private; */
 
853
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
854
        struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
 
855
        int pipeA = (psb_intel_crtc->pipe == 0);
 
856
        uint32_t paletteReg;
 
857
        int i;
 
858
 
 
859
        DRM_DEBUG("\n");
 
860
 
 
861
        if (!crtc_state) {
 
862
                DRM_DEBUG("No CRTC state found\n");
 
863
                return;
 
864
        }
 
865
 
 
866
        crtc_state->saveDSPCNTR = REG_READ(pipeA ? DSPACNTR : DSPBCNTR);
 
867
        crtc_state->savePIPECONF = REG_READ(pipeA ? PIPEACONF : PIPEBCONF);
 
868
        crtc_state->savePIPESRC = REG_READ(pipeA ? PIPEASRC : PIPEBSRC);
 
869
        crtc_state->saveFP0 = REG_READ(pipeA ? FPA0 : FPB0);
 
870
        crtc_state->saveFP1 = REG_READ(pipeA ? FPA1 : FPB1);
 
871
        crtc_state->saveDPLL = REG_READ(pipeA ? DPLL_A : DPLL_B);
 
872
        crtc_state->saveHTOTAL = REG_READ(pipeA ? HTOTAL_A : HTOTAL_B);
 
873
        crtc_state->saveHBLANK = REG_READ(pipeA ? HBLANK_A : HBLANK_B);
 
874
        crtc_state->saveHSYNC = REG_READ(pipeA ? HSYNC_A : HSYNC_B);
 
875
        crtc_state->saveVTOTAL = REG_READ(pipeA ? VTOTAL_A : VTOTAL_B);
 
876
        crtc_state->saveVBLANK = REG_READ(pipeA ? VBLANK_A : VBLANK_B);
 
877
        crtc_state->saveVSYNC = REG_READ(pipeA ? VSYNC_A : VSYNC_B);
 
878
        crtc_state->saveDSPSTRIDE = REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE);
 
879
 
 
880
        /*NOTE: DSPSIZE DSPPOS only for psb*/
 
881
        crtc_state->saveDSPSIZE = REG_READ(pipeA ? DSPASIZE : DSPBSIZE);
 
882
        crtc_state->saveDSPPOS = REG_READ(pipeA ? DSPAPOS : DSPBPOS);
 
883
 
 
884
        crtc_state->saveDSPBASE = REG_READ(pipeA ? DSPABASE : DSPBBASE);
 
885
 
 
886
        DRM_DEBUG("(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
 
887
                        crtc_state->saveDSPCNTR,
 
888
                        crtc_state->savePIPECONF,
 
889
                        crtc_state->savePIPESRC,
 
890
                        crtc_state->saveFP0,
 
891
                        crtc_state->saveFP1,
 
892
                        crtc_state->saveDPLL,
 
893
                        crtc_state->saveHTOTAL,
 
894
                        crtc_state->saveHBLANK,
 
895
                        crtc_state->saveHSYNC,
 
896
                        crtc_state->saveVTOTAL,
 
897
                        crtc_state->saveVBLANK,
 
898
                        crtc_state->saveVSYNC,
 
899
                        crtc_state->saveDSPSTRIDE,
 
900
                        crtc_state->saveDSPSIZE,
 
901
                        crtc_state->saveDSPPOS,
 
902
                        crtc_state->saveDSPBASE
 
903
                );
 
904
 
 
905
        paletteReg = pipeA ? PALETTE_A : PALETTE_B;
 
906
        for (i = 0; i < 256; ++i)
 
907
                crtc_state->savePalette[i] = REG_READ(paletteReg + (i << 2));
 
908
}
 
909
 
 
910
/**
 
911
 * Restore HW states of giving crtc
 
912
 */
 
913
static void psb_intel_crtc_restore(struct drm_crtc *crtc)
 
914
{
 
915
        struct drm_device *dev = crtc->dev;
 
916
        /* struct drm_psb_private * dev_priv =
 
917
                                (struct drm_psb_private *)dev->dev_private; */
 
918
        struct psb_intel_crtc *psb_intel_crtc =  to_psb_intel_crtc(crtc);
 
919
        struct psb_intel_crtc_state *crtc_state = psb_intel_crtc->crtc_state;
 
920
        /* struct drm_crtc_helper_funcs * crtc_funcs = crtc->helper_private; */
 
921
        int pipeA = (psb_intel_crtc->pipe == 0);
 
922
        uint32_t paletteReg;
 
923
        int i;
 
924
 
 
925
        DRM_DEBUG("\n");
 
926
 
 
927
        if (!crtc_state) {
 
928
                DRM_DEBUG("No crtc state\n");
 
929
                return;
 
930
        }
 
931
 
 
932
        DRM_DEBUG(
 
933
                "current:(%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
 
934
                REG_READ(pipeA ? DSPACNTR : DSPBCNTR),
 
935
                REG_READ(pipeA ? PIPEACONF : PIPEBCONF),
 
936
                REG_READ(pipeA ? PIPEASRC : PIPEBSRC),
 
937
                REG_READ(pipeA ? FPA0 : FPB0),
 
938
                REG_READ(pipeA ? FPA1 : FPB1),
 
939
                REG_READ(pipeA ? DPLL_A : DPLL_B),
 
940
                REG_READ(pipeA ? HTOTAL_A : HTOTAL_B),
 
941
                REG_READ(pipeA ? HBLANK_A : HBLANK_B),
 
942
                REG_READ(pipeA ? HSYNC_A : HSYNC_B),
 
943
                REG_READ(pipeA ? VTOTAL_A : VTOTAL_B),
 
944
                REG_READ(pipeA ? VBLANK_A : VBLANK_B),
 
945
                REG_READ(pipeA ? VSYNC_A : VSYNC_B),
 
946
                REG_READ(pipeA ? DSPASTRIDE : DSPBSTRIDE),
 
947
                REG_READ(pipeA ? DSPASIZE : DSPBSIZE),
 
948
                REG_READ(pipeA ? DSPAPOS : DSPBPOS),
 
949
                REG_READ(pipeA ? DSPABASE : DSPBBASE)
 
950
                );
 
951
 
 
952
        DRM_DEBUG(
 
953
                "saved: (%x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x)\n",
 
954
                crtc_state->saveDSPCNTR,
 
955
                crtc_state->savePIPECONF,
 
956
                crtc_state->savePIPESRC,
 
957
                crtc_state->saveFP0,
 
958
                crtc_state->saveFP1,
 
959
                crtc_state->saveDPLL,
 
960
                crtc_state->saveHTOTAL,
 
961
                crtc_state->saveHBLANK,
 
962
                crtc_state->saveHSYNC,
 
963
                crtc_state->saveVTOTAL,
 
964
                crtc_state->saveVBLANK,
 
965
                crtc_state->saveVSYNC,
 
966
                crtc_state->saveDSPSTRIDE,
 
967
                crtc_state->saveDSPSIZE,
 
968
                crtc_state->saveDSPPOS,
 
969
                crtc_state->saveDSPBASE
 
970
                );
 
971
 
 
972
 
 
973
        if (crtc_state->saveDPLL & DPLL_VCO_ENABLE) {
 
974
                REG_WRITE(pipeA ? DPLL_A : DPLL_B,
 
975
                        crtc_state->saveDPLL & ~DPLL_VCO_ENABLE);
 
976
                REG_READ(pipeA ? DPLL_A : DPLL_B);
 
977
                DRM_DEBUG("write dpll: %x\n",
 
978
                                REG_READ(pipeA ? DPLL_A : DPLL_B));
 
979
                udelay(150);
 
980
        }
 
981
 
 
982
        REG_WRITE(pipeA ? FPA0 : FPB0, crtc_state->saveFP0);
 
983
        REG_READ(pipeA ? FPA0 : FPB0);
 
984
 
 
985
        REG_WRITE(pipeA ? FPA1 : FPB1, crtc_state->saveFP1);
 
986
        REG_READ(pipeA ? FPA1 : FPB1);
 
987
 
 
988
        REG_WRITE(pipeA ? DPLL_A : DPLL_B, crtc_state->saveDPLL);
 
989
        REG_READ(pipeA ? DPLL_A : DPLL_B);
 
990
        udelay(150);
 
991
 
 
992
        REG_WRITE(pipeA ? HTOTAL_A : HTOTAL_B, crtc_state->saveHTOTAL);
 
993
        REG_WRITE(pipeA ? HBLANK_A : HBLANK_B, crtc_state->saveHBLANK);
 
994
        REG_WRITE(pipeA ? HSYNC_A : HSYNC_B, crtc_state->saveHSYNC);
 
995
        REG_WRITE(pipeA ? VTOTAL_A : VTOTAL_B, crtc_state->saveVTOTAL);
 
996
        REG_WRITE(pipeA ? VBLANK_A : VBLANK_B, crtc_state->saveVBLANK);
 
997
        REG_WRITE(pipeA ? VSYNC_A : VSYNC_B, crtc_state->saveVSYNC);
 
998
        REG_WRITE(pipeA ? DSPASTRIDE : DSPBSTRIDE, crtc_state->saveDSPSTRIDE);
 
999
 
 
1000
        REG_WRITE(pipeA ? DSPASIZE : DSPBSIZE, crtc_state->saveDSPSIZE);
 
1001
        REG_WRITE(pipeA ? DSPAPOS : DSPBPOS, crtc_state->saveDSPPOS);
 
1002
 
 
1003
        REG_WRITE(pipeA ? PIPEASRC : PIPEBSRC, crtc_state->savePIPESRC);
 
1004
        REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
 
1005
        REG_WRITE(pipeA ? PIPEACONF : PIPEBCONF, crtc_state->savePIPECONF);
 
1006
 
 
1007
        psb_intel_wait_for_vblank(dev);
 
1008
 
 
1009
        REG_WRITE(pipeA ? DSPACNTR : DSPBCNTR, crtc_state->saveDSPCNTR);
 
1010
        REG_WRITE(pipeA ? DSPABASE : DSPBBASE, crtc_state->saveDSPBASE);
 
1011
 
 
1012
        psb_intel_wait_for_vblank(dev);
 
1013
 
 
1014
        paletteReg = pipeA ? PALETTE_A : PALETTE_B;
 
1015
        for (i = 0; i < 256; ++i)
 
1016
                REG_WRITE(paletteReg + (i << 2), crtc_state->savePalette[i]);
 
1017
}
 
1018
 
 
1019
static int psb_intel_crtc_cursor_set(struct drm_crtc *crtc,
 
1020
                                 struct drm_file *file_priv,
 
1021
                                 uint32_t handle,
 
1022
                                 uint32_t width, uint32_t height)
 
1023
{
 
1024
        struct drm_device *dev = crtc->dev;
 
1025
        struct drm_psb_private *dev_priv =
 
1026
                                (struct drm_psb_private *)dev->dev_private;
 
1027
        struct psb_gtt *pg = dev_priv->pg;
 
1028
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
1029
        struct psb_intel_mode_device *mode_dev = psb_intel_crtc->mode_dev;
 
1030
        int pipe = psb_intel_crtc->pipe;
 
1031
        uint32_t control = (pipe == 0) ? CURACNTR : CURBCNTR;
 
1032
        uint32_t base = (pipe == 0) ? CURABASE : CURBBASE;
 
1033
        uint32_t temp;
 
1034
        size_t addr = 0;
 
1035
        uint32_t page_offset;
 
1036
        size_t size;
 
1037
        void *bo;
 
1038
        int ret;
 
1039
 
 
1040
        DRM_DEBUG("\n");
 
1041
 
 
1042
        /* if we want to turn of the cursor ignore width and height */
 
1043
        if (!handle) {
 
1044
                DRM_DEBUG("cursor off\n");
 
1045
                /* turn off the cursor */
 
1046
                temp = 0;
 
1047
                temp |= CURSOR_MODE_DISABLE;
 
1048
 
 
1049
                if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
 
1050
                                              OSPM_UHB_ONLY_IF_ON)) {
 
1051
                        REG_WRITE(control, temp);
 
1052
                        REG_WRITE(base, 0);
 
1053
                        ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 
1054
                }
 
1055
 
 
1056
                /* unpin the old bo */
 
1057
                if (psb_intel_crtc->cursor_bo) {
 
1058
                        mode_dev->bo_unpin_for_scanout(dev,
 
1059
                                                       psb_intel_crtc->
 
1060
                                                       cursor_bo);
 
1061
                        psb_intel_crtc->cursor_bo = NULL;
 
1062
                }
 
1063
 
 
1064
                return 0;
 
1065
        }
 
1066
 
 
1067
        /* Currently we only support 64x64 cursors */
 
1068
        if (width != 64 || height != 64) {
 
1069
                DRM_ERROR("we currently only support 64x64 cursors\n");
 
1070
                return -EINVAL;
 
1071
        }
 
1072
 
 
1073
        bo = mode_dev->bo_from_handle(dev, file_priv, handle);
 
1074
        if (!bo)
 
1075
                return -ENOENT;
 
1076
 
 
1077
        ret = mode_dev->bo_pin_for_scanout(dev, bo);
 
1078
        if (ret)
 
1079
                return ret;
 
1080
        size = mode_dev->bo_size(dev, bo);
 
1081
        if (size < width * height * 4) {
 
1082
                DRM_ERROR("buffer is to small\n");
 
1083
                return -ENOMEM;
 
1084
        }
 
1085
 
 
1086
        /*insert this bo into gtt*/
 
1087
        DRM_DEBUG("%s: map meminfo for hw cursor. handle %x\n",
 
1088
                                                __func__, handle);
 
1089
 
 
1090
        ret = psb_gtt_map_meminfo(dev, (void *)handle, &page_offset);
 
1091
        if (ret) {
 
1092
                DRM_ERROR("Can not map meminfo to GTT. handle 0x%x\n", handle);
 
1093
                return ret;
 
1094
        }
 
1095
 
 
1096
        addr = page_offset << PAGE_SHIFT;
 
1097
 
 
1098
        addr += pg->stolen_base;
 
1099
 
 
1100
        psb_intel_crtc->cursor_addr = addr;
 
1101
 
 
1102
        temp = 0;
 
1103
        /* set the pipe for the cursor */
 
1104
        temp |= (pipe << 28);
 
1105
        temp |= CURSOR_MODE_64_ARGB_AX | MCURSOR_GAMMA_ENABLE;
 
1106
 
 
1107
        if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
 
1108
                                      OSPM_UHB_ONLY_IF_ON)) {
 
1109
                REG_WRITE(control, temp);
 
1110
                REG_WRITE(base, addr);
 
1111
                ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 
1112
        }
 
1113
 
 
1114
        /* unpin the old bo */
 
1115
        if (psb_intel_crtc->cursor_bo && psb_intel_crtc->cursor_bo != bo) {
 
1116
                mode_dev->bo_unpin_for_scanout(dev, psb_intel_crtc->cursor_bo);
 
1117
                psb_intel_crtc->cursor_bo = bo;
 
1118
        }
 
1119
 
 
1120
        return 0;
 
1121
}
 
1122
 
 
1123
static int psb_intel_crtc_cursor_move(struct drm_crtc *crtc, int x, int y)
 
1124
{
 
1125
        struct drm_device *dev = crtc->dev;
 
1126
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
1127
        int pipe = psb_intel_crtc->pipe;
 
1128
        uint32_t temp = 0;
 
1129
        uint32_t adder;
 
1130
 
 
1131
 
 
1132
        if (x < 0) {
 
1133
                temp |= (CURSOR_POS_SIGN << CURSOR_X_SHIFT);
 
1134
                x = -x;
 
1135
        }
 
1136
        if (y < 0) {
 
1137
                temp |= (CURSOR_POS_SIGN << CURSOR_Y_SHIFT);
 
1138
                y = -y;
 
1139
        }
 
1140
 
 
1141
        temp |= ((x & CURSOR_POS_MASK) << CURSOR_X_SHIFT);
 
1142
        temp |= ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
 
1143
 
 
1144
        adder = psb_intel_crtc->cursor_addr;
 
1145
 
 
1146
        if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
 
1147
                                      OSPM_UHB_ONLY_IF_ON)) {
 
1148
                REG_WRITE((pipe == 0) ? CURAPOS : CURBPOS, temp);
 
1149
                REG_WRITE((pipe == 0) ? CURABASE : CURBBASE, adder);
 
1150
                ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 
1151
        }
 
1152
        return 0;
 
1153
}
 
1154
 
 
1155
static void psb_intel_crtc_gamma_set(struct drm_crtc *crtc, u16 *red,
 
1156
                         u16 *green, u16 *blue, uint32_t type, uint32_t size)
 
1157
{
 
1158
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
1159
        int i;
 
1160
 
 
1161
        if (size != 256)
 
1162
                return;
 
1163
 
 
1164
        for (i = 0; i < 256; i++) {
 
1165
                psb_intel_crtc->lut_r[i] = red[i] >> 8;
 
1166
                psb_intel_crtc->lut_g[i] = green[i] >> 8;
 
1167
                psb_intel_crtc->lut_b[i] = blue[i] >> 8;
 
1168
        }
 
1169
 
 
1170
        psb_intel_crtc_load_lut(crtc);
 
1171
}
 
1172
 
 
1173
static int psb_crtc_set_config(struct drm_mode_set *set)
 
1174
{
 
1175
        int ret;
 
1176
        struct drm_device *dev = set->crtc->dev;
 
1177
        struct drm_psb_private *dev_priv = dev->dev_private;
 
1178
 
 
1179
        if (!dev_priv->rpm_enabled)
 
1180
                return drm_crtc_helper_set_config(set);
 
1181
 
 
1182
        pm_runtime_forbid(&dev->pdev->dev);
 
1183
        ret = drm_crtc_helper_set_config(set);
 
1184
        pm_runtime_allow(&dev->pdev->dev);
 
1185
        return ret;
 
1186
}
 
1187
 
 
1188
/* Returns the clock of the currently programmed mode of the given pipe. */
 
1189
static int psb_intel_crtc_clock_get(struct drm_device *dev,
 
1190
                                struct drm_crtc *crtc)
 
1191
{
 
1192
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
1193
        int pipe = psb_intel_crtc->pipe;
 
1194
        u32 dpll;
 
1195
        u32 fp;
 
1196
        struct psb_intel_clock_t clock;
 
1197
        bool is_lvds;
 
1198
        struct drm_psb_private *dev_priv = dev->dev_private;
 
1199
 
 
1200
        if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
 
1201
                                      OSPM_UHB_ONLY_IF_ON)) {
 
1202
                dpll = REG_READ((pipe == 0) ? DPLL_A : DPLL_B);
 
1203
                if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
 
1204
                        fp = REG_READ((pipe == 0) ? FPA0 : FPB0);
 
1205
                else
 
1206
                        fp = REG_READ((pipe == 0) ? FPA1 : FPB1);
 
1207
                is_lvds = (pipe == 1) && (REG_READ(LVDS) & LVDS_PORT_EN);
 
1208
                ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 
1209
        } else {
 
1210
                dpll = (pipe == 0) ?
 
1211
                        dev_priv->saveDPLL_A : dev_priv->saveDPLL_B;
 
1212
 
 
1213
                if ((dpll & DISPLAY_RATE_SELECT_FPA1) == 0)
 
1214
                        fp = (pipe == 0) ?
 
1215
                                dev_priv->saveFPA0 :
 
1216
                                dev_priv->saveFPB0;
 
1217
                else
 
1218
                        fp = (pipe == 0) ?
 
1219
                                dev_priv->saveFPA1 :
 
1220
                                dev_priv->saveFPB1;
 
1221
 
 
1222
                is_lvds = (pipe == 1) && (dev_priv->saveLVDS & LVDS_PORT_EN);
 
1223
        }
 
1224
 
 
1225
        clock.m1 = (fp & FP_M1_DIV_MASK) >> FP_M1_DIV_SHIFT;
 
1226
        clock.m2 = (fp & FP_M2_DIV_MASK) >> FP_M2_DIV_SHIFT;
 
1227
        clock.n = (fp & FP_N_DIV_MASK) >> FP_N_DIV_SHIFT;
 
1228
 
 
1229
        if (is_lvds) {
 
1230
                clock.p1 =
 
1231
                    ffs((dpll &
 
1232
                         DPLL_FPA01_P1_POST_DIV_MASK_I830_LVDS) >>
 
1233
                        DPLL_FPA01_P1_POST_DIV_SHIFT);
 
1234
                clock.p2 = 14;
 
1235
 
 
1236
                if ((dpll & PLL_REF_INPUT_MASK) ==
 
1237
                    PLLB_REF_INPUT_SPREADSPECTRUMIN) {
 
1238
                        /* XXX: might not be 66MHz */
 
1239
                        i8xx_clock(66000, &clock);
 
1240
                } else
 
1241
                        i8xx_clock(48000, &clock);
 
1242
        } else {
 
1243
                if (dpll & PLL_P1_DIVIDE_BY_TWO)
 
1244
                        clock.p1 = 2;
 
1245
                else {
 
1246
                        clock.p1 =
 
1247
                            ((dpll &
 
1248
                              DPLL_FPA01_P1_POST_DIV_MASK_I830) >>
 
1249
                             DPLL_FPA01_P1_POST_DIV_SHIFT) + 2;
 
1250
                }
 
1251
                if (dpll & PLL_P2_DIVIDE_BY_4)
 
1252
                        clock.p2 = 4;
 
1253
                else
 
1254
                        clock.p2 = 2;
 
1255
 
 
1256
                i8xx_clock(48000, &clock);
 
1257
        }
 
1258
 
 
1259
        /* XXX: It would be nice to validate the clocks, but we can't reuse
 
1260
         * i830PllIsValid() because it relies on the xf86_config connector
 
1261
         * configuration being accurate, which it isn't necessarily.
 
1262
         */
 
1263
 
 
1264
        return clock.dot;
 
1265
}
 
1266
 
 
1267
/** Returns the currently programmed mode of the given pipe. */
 
1268
struct drm_display_mode *psb_intel_crtc_mode_get(struct drm_device *dev,
 
1269
                                             struct drm_crtc *crtc)
 
1270
{
 
1271
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
1272
        int pipe = psb_intel_crtc->pipe;
 
1273
        struct drm_display_mode *mode;
 
1274
        int htot;
 
1275
        int hsync;
 
1276
        int vtot;
 
1277
        int vsync;
 
1278
        struct drm_psb_private *dev_priv = dev->dev_private;
 
1279
 
 
1280
        if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND,
 
1281
                                      OSPM_UHB_ONLY_IF_ON)) {
 
1282
                htot = REG_READ((pipe == 0) ? HTOTAL_A : HTOTAL_B);
 
1283
                hsync = REG_READ((pipe == 0) ? HSYNC_A : HSYNC_B);
 
1284
                vtot = REG_READ((pipe == 0) ? VTOTAL_A : VTOTAL_B);
 
1285
                vsync = REG_READ((pipe == 0) ? VSYNC_A : VSYNC_B);
 
1286
                ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
 
1287
        } else {
 
1288
                htot = (pipe == 0) ?
 
1289
                        dev_priv->saveHTOTAL_A : dev_priv->saveHTOTAL_B;
 
1290
                hsync = (pipe == 0) ?
 
1291
                        dev_priv->saveHSYNC_A : dev_priv->saveHSYNC_B;
 
1292
                vtot = (pipe == 0) ?
 
1293
                        dev_priv->saveVTOTAL_A : dev_priv->saveVTOTAL_B;
 
1294
                vsync = (pipe == 0) ?
 
1295
                        dev_priv->saveVSYNC_A : dev_priv->saveVSYNC_B;
 
1296
        }
 
1297
 
 
1298
        mode = kzalloc(sizeof(*mode), GFP_KERNEL);
 
1299
        if (!mode)
 
1300
                return NULL;
 
1301
 
 
1302
        mode->clock = psb_intel_crtc_clock_get(dev, crtc);
 
1303
        mode->hdisplay = (htot & 0xffff) + 1;
 
1304
        mode->htotal = ((htot & 0xffff0000) >> 16) + 1;
 
1305
        mode->hsync_start = (hsync & 0xffff) + 1;
 
1306
        mode->hsync_end = ((hsync & 0xffff0000) >> 16) + 1;
 
1307
        mode->vdisplay = (vtot & 0xffff) + 1;
 
1308
        mode->vtotal = ((vtot & 0xffff0000) >> 16) + 1;
 
1309
        mode->vsync_start = (vsync & 0xffff) + 1;
 
1310
        mode->vsync_end = ((vsync & 0xffff0000) >> 16) + 1;
 
1311
 
 
1312
        drm_mode_set_name(mode);
 
1313
        drm_mode_set_crtcinfo(mode, 0);
 
1314
 
 
1315
        return mode;
 
1316
}
 
1317
 
 
1318
static void psb_intel_crtc_destroy(struct drm_crtc *crtc)
 
1319
{
 
1320
        struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
1321
 
 
1322
        kfree(psb_intel_crtc->crtc_state);
 
1323
        drm_crtc_cleanup(crtc);
 
1324
        kfree(psb_intel_crtc);
 
1325
}
 
1326
 
 
1327
static const struct drm_crtc_helper_funcs psb_intel_helper_funcs = {
 
1328
        .dpms = psb_intel_crtc_dpms,
 
1329
        .mode_fixup = psb_intel_crtc_mode_fixup,
 
1330
        .mode_set = psb_intel_crtc_mode_set,
 
1331
        .mode_set_base = psb_intel_pipe_set_base,
 
1332
        .prepare = psb_intel_crtc_prepare,
 
1333
        .commit = psb_intel_crtc_commit,
 
1334
};
 
1335
 
 
1336
static const struct drm_crtc_helper_funcs mrst_helper_funcs;
 
1337
static const struct drm_crtc_helper_funcs mdfld_helper_funcs;
 
1338
const struct drm_crtc_funcs mdfld_intel_crtc_funcs;
 
1339
 
 
1340
const struct drm_crtc_funcs psb_intel_crtc_funcs = {
 
1341
        .save = psb_intel_crtc_save,
 
1342
        .restore = psb_intel_crtc_restore,
 
1343
        .cursor_set = psb_intel_crtc_cursor_set,
 
1344
        .cursor_move = psb_intel_crtc_cursor_move,
 
1345
        .gamma_set = psb_intel_crtc_gamma_set,
 
1346
        .set_config = psb_crtc_set_config,
 
1347
        .destroy = psb_intel_crtc_destroy,
 
1348
};
 
1349
 
 
1350
void psb_intel_crtc_init(struct drm_device *dev, int pipe,
 
1351
                     struct psb_intel_mode_device *mode_dev)
 
1352
{
 
1353
        struct drm_psb_private *dev_priv = dev->dev_private;
 
1354
        struct psb_intel_crtc *psb_intel_crtc;
 
1355
        int i;
 
1356
        uint16_t *r_base, *g_base, *b_base;
 
1357
 
 
1358
        PSB_DEBUG_ENTRY("\n");
 
1359
 
 
1360
        /* We allocate a extra array of drm_connector pointers
 
1361
         * for fbdev after the crtc */
 
1362
        psb_intel_crtc =
 
1363
            kzalloc(sizeof(struct psb_intel_crtc) +
 
1364
                    (INTELFB_CONN_LIMIT * sizeof(struct drm_connector *)),
 
1365
                    GFP_KERNEL);
 
1366
        if (psb_intel_crtc == NULL)
 
1367
                return;
 
1368
 
 
1369
        psb_intel_crtc->crtc_state =
 
1370
                kzalloc(sizeof(struct psb_intel_crtc_state), GFP_KERNEL);
 
1371
        if (!psb_intel_crtc->crtc_state) {
 
1372
                DRM_INFO("Crtc state error: No memory\n");
 
1373
                kfree(psb_intel_crtc);
 
1374
                return;
 
1375
        }
 
1376
 
 
1377
        drm_crtc_init(dev, &psb_intel_crtc->base, &psb_intel_crtc_funcs);
 
1378
 
 
1379
        drm_mode_crtc_set_gamma_size(&psb_intel_crtc->base, 256);
 
1380
        psb_intel_crtc->pipe = pipe;
 
1381
        psb_intel_crtc->plane = pipe;
 
1382
 
 
1383
        r_base = psb_intel_crtc->base.gamma_store;
 
1384
        g_base = r_base + 256;
 
1385
        b_base = g_base + 256;
 
1386
        for (i = 0; i < 256; i++) {
 
1387
                psb_intel_crtc->lut_r[i] = i;
 
1388
                psb_intel_crtc->lut_g[i] = i;
 
1389
                psb_intel_crtc->lut_b[i] = i;
 
1390
                r_base[i] = i << 8;
 
1391
                g_base[i] = i << 8;
 
1392
                b_base[i] = i << 8;
 
1393
 
 
1394
                psb_intel_crtc->lut_adj[i] = 0;
 
1395
        }
 
1396
 
 
1397
        psb_intel_crtc->mode_dev = mode_dev;
 
1398
        psb_intel_crtc->cursor_addr = 0;
 
1399
 
 
1400
        drm_crtc_helper_add(&psb_intel_crtc->base,
 
1401
                                    &psb_intel_helper_funcs);
 
1402
 
 
1403
        /* Setup the array of drm_connector pointer array */
 
1404
        psb_intel_crtc->mode_set.crtc = &psb_intel_crtc->base;
 
1405
        BUG_ON(pipe >= ARRAY_SIZE(dev_priv->plane_to_crtc_mapping) ||
 
1406
               dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] != NULL);
 
1407
        dev_priv->plane_to_crtc_mapping[psb_intel_crtc->plane] =
 
1408
                                                        &psb_intel_crtc->base;
 
1409
        dev_priv->pipe_to_crtc_mapping[psb_intel_crtc->pipe] =
 
1410
                                                        &psb_intel_crtc->base;
 
1411
        psb_intel_crtc->mode_set.connectors =
 
1412
            (struct drm_connector **) (psb_intel_crtc + 1);
 
1413
        psb_intel_crtc->mode_set.num_connectors = 0;
 
1414
}
 
1415
 
 
1416
int psb_intel_get_pipe_from_crtc_id(struct drm_device *dev, void *data,
 
1417
                                struct drm_file *file_priv)
 
1418
{
 
1419
        struct drm_psb_private *dev_priv = dev->dev_private;
 
1420
        struct drm_psb_get_pipe_from_crtc_id_arg *pipe_from_crtc_id = data;
 
1421
        struct drm_mode_object *drmmode_obj;
 
1422
        struct psb_intel_crtc *crtc;
 
1423
 
 
1424
        if (!dev_priv) {
 
1425
                DRM_ERROR("called with no initialization\n");
 
1426
                return -EINVAL;
 
1427
        }
 
1428
 
 
1429
        drmmode_obj = drm_mode_object_find(dev, pipe_from_crtc_id->crtc_id,
 
1430
                        DRM_MODE_OBJECT_CRTC);
 
1431
 
 
1432
        if (!drmmode_obj) {
 
1433
                DRM_ERROR("no such CRTC id\n");
 
1434
                return -EINVAL;
 
1435
        }
 
1436
 
 
1437
        crtc = to_psb_intel_crtc(obj_to_crtc(drmmode_obj));
 
1438
        pipe_from_crtc_id->pipe = crtc->pipe;
 
1439
 
 
1440
        return 0;
 
1441
}
 
1442
 
 
1443
struct drm_crtc *psb_intel_get_crtc_from_pipe(struct drm_device *dev, int pipe)
 
1444
{
 
1445
        struct drm_crtc *crtc = NULL;
 
1446
 
 
1447
        list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) {
 
1448
                struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
 
1449
                if (psb_intel_crtc->pipe == pipe)
 
1450
                        break;
 
1451
        }
 
1452
        return crtc;
 
1453
}
 
1454
 
 
1455
int psb_intel_connector_clones(struct drm_device *dev, int type_mask)
 
1456
{
 
1457
        int index_mask = 0;
 
1458
        struct drm_connector *connector;
 
1459
        int entry = 0;
 
1460
 
 
1461
        list_for_each_entry(connector, &dev->mode_config.connector_list,
 
1462
                            head) {
 
1463
                struct psb_intel_output *psb_intel_output =
 
1464
                    to_psb_intel_output(connector);
 
1465
                if (type_mask & (1 << psb_intel_output->type))
 
1466
                        index_mask |= (1 << entry);
 
1467
                entry++;
 
1468
        }
 
1469
        return index_mask;
 
1470
}
 
1471
 
 
1472
 
 
1473
void psb_intel_modeset_cleanup(struct drm_device *dev)
 
1474
{
 
1475
        drm_mode_config_cleanup(dev);
 
1476
}
 
1477
 
 
1478
 
 
1479
/* current intel driver doesn't take advantage of encoders
 
1480
   always give back the encoder for the connector
 
1481
*/
 
1482
struct drm_encoder *psb_intel_best_encoder(struct drm_connector *connector)
 
1483
{
 
1484
        struct psb_intel_output *psb_intel_output =
 
1485
                                        to_psb_intel_output(connector);
 
1486
 
 
1487
        return &psb_intel_output->enc;
 
1488
}
 
1489