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

« back to all changes in this revision

Viewing changes to drivers/video/omap2/dss/rfbi.c

  • Committer: Bazaar Package Importer
  • Author(s): Ben Hutchings, Ben Hutchings, Aurelien Jarno, Martin Michlmayr
  • Date: 2011-04-06 13:53:30 UTC
  • mfrom: (43.1.5 sid)
  • Revision ID: james.westby@ubuntu.com-20110406135330-wjufxhd0tvn3zx4z
Tags: 2.6.38-3
[ Ben Hutchings ]
* [ppc64] Add to linux-tools package architectures (Closes: #620124)
* [amd64] Save cr4 to mmu_cr4_features at boot time (Closes: #620284)
* appletalk: Fix bugs introduced when removing use of BKL
* ALSA: Fix yet another race in disconnection
* cciss: Fix lost command issue
* ath9k: Fix kernel panic in AR2427
* ses: Avoid kernel panic when lun 0 is not mapped
* PCI/ACPI: Report ASPM support to BIOS if not disabled from command line

[ Aurelien Jarno ]
* rtlwifi: fix build when PCI is not enabled.

[ Martin Michlmayr ]
* rtlwifi: Eliminate udelay calls with too large values (Closes: #620204)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * linux/drivers/video/omap2/dss/rfbi.c
 
3
 *
 
4
 * Copyright (C) 2009 Nokia Corporation
 
5
 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
 
6
 *
 
7
 * Some code and ideas taken from drivers/video/omap/ driver
 
8
 * by Imre Deak.
 
9
 *
 
10
 * This program is free software; you can redistribute it and/or modify it
 
11
 * under the terms of the GNU General Public License version 2 as published by
 
12
 * the Free Software Foundation.
 
13
 *
 
14
 * This program is distributed in the hope that it will be useful, but WITHOUT
 
15
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 
16
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 
17
 * more details.
 
18
 *
 
19
 * You should have received a copy of the GNU General Public License along with
 
20
 * this program.  If not, see <http://www.gnu.org/licenses/>.
 
21
 */
 
22
 
 
23
#define DSS_SUBSYS_NAME "RFBI"
 
24
 
 
25
#include <linux/kernel.h>
 
26
#include <linux/dma-mapping.h>
 
27
#include <linux/vmalloc.h>
 
28
#include <linux/clk.h>
 
29
#include <linux/io.h>
 
30
#include <linux/delay.h>
 
31
#include <linux/kfifo.h>
 
32
#include <linux/ktime.h>
 
33
#include <linux/hrtimer.h>
 
34
#include <linux/seq_file.h>
 
35
 
 
36
#include <plat/display.h>
 
37
#include "dss.h"
 
38
 
 
39
#define RFBI_BASE               0x48050800
 
40
 
 
41
struct rfbi_reg { u16 idx; };
 
42
 
 
43
#define RFBI_REG(idx)           ((const struct rfbi_reg) { idx })
 
44
 
 
45
#define RFBI_REVISION           RFBI_REG(0x0000)
 
46
#define RFBI_SYSCONFIG          RFBI_REG(0x0010)
 
47
#define RFBI_SYSSTATUS          RFBI_REG(0x0014)
 
48
#define RFBI_CONTROL            RFBI_REG(0x0040)
 
49
#define RFBI_PIXEL_CNT          RFBI_REG(0x0044)
 
50
#define RFBI_LINE_NUMBER        RFBI_REG(0x0048)
 
51
#define RFBI_CMD                RFBI_REG(0x004c)
 
52
#define RFBI_PARAM              RFBI_REG(0x0050)
 
53
#define RFBI_DATA               RFBI_REG(0x0054)
 
54
#define RFBI_READ               RFBI_REG(0x0058)
 
55
#define RFBI_STATUS             RFBI_REG(0x005c)
 
56
 
 
57
#define RFBI_CONFIG(n)          RFBI_REG(0x0060 + (n)*0x18)
 
58
#define RFBI_ONOFF_TIME(n)      RFBI_REG(0x0064 + (n)*0x18)
 
59
#define RFBI_CYCLE_TIME(n)      RFBI_REG(0x0068 + (n)*0x18)
 
60
#define RFBI_DATA_CYCLE1(n)     RFBI_REG(0x006c + (n)*0x18)
 
61
#define RFBI_DATA_CYCLE2(n)     RFBI_REG(0x0070 + (n)*0x18)
 
62
#define RFBI_DATA_CYCLE3(n)     RFBI_REG(0x0074 + (n)*0x18)
 
63
 
 
64
#define RFBI_VSYNC_WIDTH        RFBI_REG(0x0090)
 
65
#define RFBI_HSYNC_WIDTH        RFBI_REG(0x0094)
 
66
 
 
67
#define REG_FLD_MOD(idx, val, start, end) \
 
68
        rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
 
69
 
 
70
/* To work around an RFBI transfer rate limitation */
 
71
#define OMAP_RFBI_RATE_LIMIT    1
 
72
 
 
73
enum omap_rfbi_cycleformat {
 
74
        OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
 
75
        OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
 
76
        OMAP_DSS_RFBI_CYCLEFORMAT_3_1 = 2,
 
77
        OMAP_DSS_RFBI_CYCLEFORMAT_3_2 = 3,
 
78
};
 
79
 
 
80
enum omap_rfbi_datatype {
 
81
        OMAP_DSS_RFBI_DATATYPE_12 = 0,
 
82
        OMAP_DSS_RFBI_DATATYPE_16 = 1,
 
83
        OMAP_DSS_RFBI_DATATYPE_18 = 2,
 
84
        OMAP_DSS_RFBI_DATATYPE_24 = 3,
 
85
};
 
86
 
 
87
enum omap_rfbi_parallelmode {
 
88
        OMAP_DSS_RFBI_PARALLELMODE_8 = 0,
 
89
        OMAP_DSS_RFBI_PARALLELMODE_9 = 1,
 
90
        OMAP_DSS_RFBI_PARALLELMODE_12 = 2,
 
91
        OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
 
92
};
 
93
 
 
94
enum update_cmd {
 
95
        RFBI_CMD_UPDATE = 0,
 
96
        RFBI_CMD_SYNC   = 1,
 
97
};
 
98
 
 
99
static int rfbi_convert_timings(struct rfbi_timings *t);
 
100
static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
 
101
 
 
102
static struct {
 
103
        void __iomem    *base;
 
104
 
 
105
        unsigned long   l4_khz;
 
106
 
 
107
        enum omap_rfbi_datatype datatype;
 
108
        enum omap_rfbi_parallelmode parallelmode;
 
109
 
 
110
        enum omap_rfbi_te_mode te_mode;
 
111
        int te_enabled;
 
112
 
 
113
        void (*framedone_callback)(void *data);
 
114
        void *framedone_callback_data;
 
115
 
 
116
        struct omap_dss_device *dssdev[2];
 
117
 
 
118
        struct kfifo      cmd_fifo;
 
119
        spinlock_t        cmd_lock;
 
120
        struct completion cmd_done;
 
121
        atomic_t          cmd_fifo_full;
 
122
        atomic_t          cmd_pending;
 
123
} rfbi;
 
124
 
 
125
struct update_region {
 
126
        u16     x;
 
127
        u16     y;
 
128
        u16     w;
 
129
        u16     h;
 
130
};
 
131
 
 
132
static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
 
133
{
 
134
        __raw_writel(val, rfbi.base + idx.idx);
 
135
}
 
136
 
 
137
static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
 
138
{
 
139
        return __raw_readl(rfbi.base + idx.idx);
 
140
}
 
141
 
 
142
static void rfbi_enable_clocks(bool enable)
 
143
{
 
144
        if (enable)
 
145
                dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
 
146
        else
 
147
                dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
 
148
}
 
149
 
 
150
void omap_rfbi_write_command(const void *buf, u32 len)
 
151
{
 
152
        rfbi_enable_clocks(1);
 
153
        switch (rfbi.parallelmode) {
 
154
        case OMAP_DSS_RFBI_PARALLELMODE_8:
 
155
        {
 
156
                const u8 *b = buf;
 
157
                for (; len; len--)
 
158
                        rfbi_write_reg(RFBI_CMD, *b++);
 
159
                break;
 
160
        }
 
161
 
 
162
        case OMAP_DSS_RFBI_PARALLELMODE_16:
 
163
        {
 
164
                const u16 *w = buf;
 
165
                BUG_ON(len & 1);
 
166
                for (; len; len -= 2)
 
167
                        rfbi_write_reg(RFBI_CMD, *w++);
 
168
                break;
 
169
        }
 
170
 
 
171
        case OMAP_DSS_RFBI_PARALLELMODE_9:
 
172
        case OMAP_DSS_RFBI_PARALLELMODE_12:
 
173
        default:
 
174
                BUG();
 
175
        }
 
176
        rfbi_enable_clocks(0);
 
177
}
 
178
EXPORT_SYMBOL(omap_rfbi_write_command);
 
179
 
 
180
void omap_rfbi_read_data(void *buf, u32 len)
 
181
{
 
182
        rfbi_enable_clocks(1);
 
183
        switch (rfbi.parallelmode) {
 
184
        case OMAP_DSS_RFBI_PARALLELMODE_8:
 
185
        {
 
186
                u8 *b = buf;
 
187
                for (; len; len--) {
 
188
                        rfbi_write_reg(RFBI_READ, 0);
 
189
                        *b++ = rfbi_read_reg(RFBI_READ);
 
190
                }
 
191
                break;
 
192
        }
 
193
 
 
194
        case OMAP_DSS_RFBI_PARALLELMODE_16:
 
195
        {
 
196
                u16 *w = buf;
 
197
                BUG_ON(len & ~1);
 
198
                for (; len; len -= 2) {
 
199
                        rfbi_write_reg(RFBI_READ, 0);
 
200
                        *w++ = rfbi_read_reg(RFBI_READ);
 
201
                }
 
202
                break;
 
203
        }
 
204
 
 
205
        case OMAP_DSS_RFBI_PARALLELMODE_9:
 
206
        case OMAP_DSS_RFBI_PARALLELMODE_12:
 
207
        default:
 
208
                BUG();
 
209
        }
 
210
        rfbi_enable_clocks(0);
 
211
}
 
212
EXPORT_SYMBOL(omap_rfbi_read_data);
 
213
 
 
214
void omap_rfbi_write_data(const void *buf, u32 len)
 
215
{
 
216
        rfbi_enable_clocks(1);
 
217
        switch (rfbi.parallelmode) {
 
218
        case OMAP_DSS_RFBI_PARALLELMODE_8:
 
219
        {
 
220
                const u8 *b = buf;
 
221
                for (; len; len--)
 
222
                        rfbi_write_reg(RFBI_PARAM, *b++);
 
223
                break;
 
224
        }
 
225
 
 
226
        case OMAP_DSS_RFBI_PARALLELMODE_16:
 
227
        {
 
228
                const u16 *w = buf;
 
229
                BUG_ON(len & 1);
 
230
                for (; len; len -= 2)
 
231
                        rfbi_write_reg(RFBI_PARAM, *w++);
 
232
                break;
 
233
        }
 
234
 
 
235
        case OMAP_DSS_RFBI_PARALLELMODE_9:
 
236
        case OMAP_DSS_RFBI_PARALLELMODE_12:
 
237
        default:
 
238
                BUG();
 
239
 
 
240
        }
 
241
        rfbi_enable_clocks(0);
 
242
}
 
243
EXPORT_SYMBOL(omap_rfbi_write_data);
 
244
 
 
245
void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
 
246
                u16 x, u16 y,
 
247
                u16 w, u16 h)
 
248
{
 
249
        int start_offset = scr_width * y + x;
 
250
        int horiz_offset = scr_width - w;
 
251
        int i;
 
252
 
 
253
        rfbi_enable_clocks(1);
 
254
 
 
255
        if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
 
256
           rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
 
257
                const u16 __iomem *pd = buf;
 
258
                pd += start_offset;
 
259
 
 
260
                for (; h; --h) {
 
261
                        for (i = 0; i < w; ++i) {
 
262
                                const u8 __iomem *b = (const u8 __iomem *)pd;
 
263
                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
 
264
                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
 
265
                                ++pd;
 
266
                        }
 
267
                        pd += horiz_offset;
 
268
                }
 
269
        } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_24 &&
 
270
           rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
 
271
                const u32 __iomem *pd = buf;
 
272
                pd += start_offset;
 
273
 
 
274
                for (; h; --h) {
 
275
                        for (i = 0; i < w; ++i) {
 
276
                                const u8 __iomem *b = (const u8 __iomem *)pd;
 
277
                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2));
 
278
                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
 
279
                                rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
 
280
                                ++pd;
 
281
                        }
 
282
                        pd += horiz_offset;
 
283
                }
 
284
        } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
 
285
           rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_16) {
 
286
                const u16 __iomem *pd = buf;
 
287
                pd += start_offset;
 
288
 
 
289
                for (; h; --h) {
 
290
                        for (i = 0; i < w; ++i) {
 
291
                                rfbi_write_reg(RFBI_PARAM, __raw_readw(pd));
 
292
                                ++pd;
 
293
                        }
 
294
                        pd += horiz_offset;
 
295
                }
 
296
        } else {
 
297
                BUG();
 
298
        }
 
299
 
 
300
        rfbi_enable_clocks(0);
 
301
}
 
302
EXPORT_SYMBOL(omap_rfbi_write_pixels);
 
303
 
 
304
void rfbi_transfer_area(struct omap_dss_device *dssdev, u16 width,
 
305
                u16 height, void (*callback)(void *data), void *data)
 
306
{
 
307
        u32 l;
 
308
 
 
309
        /*BUG_ON(callback == 0);*/
 
310
        BUG_ON(rfbi.framedone_callback != NULL);
 
311
 
 
312
        DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
 
313
 
 
314
        dispc_set_lcd_size(dssdev->manager->id, width, height);
 
315
 
 
316
        dispc_enable_channel(dssdev->manager->id, true);
 
317
 
 
318
        rfbi.framedone_callback = callback;
 
319
        rfbi.framedone_callback_data = data;
 
320
 
 
321
        rfbi_enable_clocks(1);
 
322
 
 
323
        rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
 
324
 
 
325
        l = rfbi_read_reg(RFBI_CONTROL);
 
326
        l = FLD_MOD(l, 1, 0, 0); /* enable */
 
327
        if (!rfbi.te_enabled)
 
328
                l = FLD_MOD(l, 1, 4, 4); /* ITE */
 
329
 
 
330
        rfbi_write_reg(RFBI_CONTROL, l);
 
331
}
 
332
 
 
333
static void framedone_callback(void *data, u32 mask)
 
334
{
 
335
        void (*callback)(void *data);
 
336
 
 
337
        DSSDBG("FRAMEDONE\n");
 
338
 
 
339
        REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
 
340
 
 
341
        rfbi_enable_clocks(0);
 
342
 
 
343
        callback = rfbi.framedone_callback;
 
344
        rfbi.framedone_callback = NULL;
 
345
 
 
346
        if (callback != NULL)
 
347
                callback(rfbi.framedone_callback_data);
 
348
 
 
349
        atomic_set(&rfbi.cmd_pending, 0);
 
350
}
 
351
 
 
352
#if 1 /* VERBOSE */
 
353
static void rfbi_print_timings(void)
 
354
{
 
355
        u32 l;
 
356
        u32 time;
 
357
 
 
358
        l = rfbi_read_reg(RFBI_CONFIG(0));
 
359
        time = 1000000000 / rfbi.l4_khz;
 
360
        if (l & (1 << 4))
 
361
                time *= 2;
 
362
 
 
363
        DSSDBG("Tick time %u ps\n", time);
 
364
        l = rfbi_read_reg(RFBI_ONOFF_TIME(0));
 
365
        DSSDBG("CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
 
366
                "REONTIME %d, REOFFTIME %d\n",
 
367
                l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
 
368
                (l >> 20) & 0x0f, (l >> 24) & 0x3f);
 
369
 
 
370
        l = rfbi_read_reg(RFBI_CYCLE_TIME(0));
 
371
        DSSDBG("WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
 
372
                "ACCESSTIME %d\n",
 
373
                (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
 
374
                (l >> 22) & 0x3f);
 
375
}
 
376
#else
 
377
static void rfbi_print_timings(void) {}
 
378
#endif
 
379
 
 
380
 
 
381
 
 
382
 
 
383
static u32 extif_clk_period;
 
384
 
 
385
static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
 
386
{
 
387
        int bus_tick = extif_clk_period * div;
 
388
        return (ps + bus_tick - 1) / bus_tick * bus_tick;
 
389
}
 
390
 
 
391
static int calc_reg_timing(struct rfbi_timings *t, int div)
 
392
{
 
393
        t->clk_div = div;
 
394
 
 
395
        t->cs_on_time = round_to_extif_ticks(t->cs_on_time, div);
 
396
 
 
397
        t->we_on_time = round_to_extif_ticks(t->we_on_time, div);
 
398
        t->we_off_time = round_to_extif_ticks(t->we_off_time, div);
 
399
        t->we_cycle_time = round_to_extif_ticks(t->we_cycle_time, div);
 
400
 
 
401
        t->re_on_time = round_to_extif_ticks(t->re_on_time, div);
 
402
        t->re_off_time = round_to_extif_ticks(t->re_off_time, div);
 
403
        t->re_cycle_time = round_to_extif_ticks(t->re_cycle_time, div);
 
404
 
 
405
        t->access_time = round_to_extif_ticks(t->access_time, div);
 
406
        t->cs_off_time = round_to_extif_ticks(t->cs_off_time, div);
 
407
        t->cs_pulse_width = round_to_extif_ticks(t->cs_pulse_width, div);
 
408
 
 
409
        DSSDBG("[reg]cson %d csoff %d reon %d reoff %d\n",
 
410
               t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
 
411
        DSSDBG("[reg]weon %d weoff %d recyc %d wecyc %d\n",
 
412
               t->we_on_time, t->we_off_time, t->re_cycle_time,
 
413
               t->we_cycle_time);
 
414
        DSSDBG("[reg]rdaccess %d cspulse %d\n",
 
415
               t->access_time, t->cs_pulse_width);
 
416
 
 
417
        return rfbi_convert_timings(t);
 
418
}
 
419
 
 
420
static int calc_extif_timings(struct rfbi_timings *t)
 
421
{
 
422
        u32 max_clk_div;
 
423
        int div;
 
424
 
 
425
        rfbi_get_clk_info(&extif_clk_period, &max_clk_div);
 
426
        for (div = 1; div <= max_clk_div; div++) {
 
427
                if (calc_reg_timing(t, div) == 0)
 
428
                        break;
 
429
        }
 
430
 
 
431
        if (div <= max_clk_div)
 
432
                return 0;
 
433
 
 
434
        DSSERR("can't setup timings\n");
 
435
        return -1;
 
436
}
 
437
 
 
438
 
 
439
void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
 
440
{
 
441
        int r;
 
442
 
 
443
        if (!t->converted) {
 
444
                r = calc_extif_timings(t);
 
445
                if (r < 0)
 
446
                        DSSERR("Failed to calc timings\n");
 
447
        }
 
448
 
 
449
        BUG_ON(!t->converted);
 
450
 
 
451
        rfbi_enable_clocks(1);
 
452
        rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
 
453
        rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
 
454
 
 
455
        /* TIMEGRANULARITY */
 
456
        REG_FLD_MOD(RFBI_CONFIG(rfbi_module),
 
457
                    (t->tim[2] ? 1 : 0), 4, 4);
 
458
 
 
459
        rfbi_print_timings();
 
460
        rfbi_enable_clocks(0);
 
461
}
 
462
 
 
463
static int ps_to_rfbi_ticks(int time, int div)
 
464
{
 
465
        unsigned long tick_ps;
 
466
        int ret;
 
467
 
 
468
        /* Calculate in picosecs to yield more exact results */
 
469
        tick_ps = 1000000000 / (rfbi.l4_khz) * div;
 
470
 
 
471
        ret = (time + tick_ps - 1) / tick_ps;
 
472
 
 
473
        return ret;
 
474
}
 
475
 
 
476
#ifdef OMAP_RFBI_RATE_LIMIT
 
477
unsigned long rfbi_get_max_tx_rate(void)
 
478
{
 
479
        unsigned long   l4_rate, dss1_rate;
 
480
        int             min_l4_ticks = 0;
 
481
        int             i;
 
482
 
 
483
        /* According to TI this can't be calculated so make the
 
484
         * adjustments for a couple of known frequencies and warn for
 
485
         * others.
 
486
         */
 
487
        static const struct {
 
488
                unsigned long l4_clk;           /* HZ */
 
489
                unsigned long dss1_clk;         /* HZ */
 
490
                unsigned long min_l4_ticks;
 
491
        } ftab[] = {
 
492
                { 55,   132,    7, },           /* 7.86 MPix/s */
 
493
                { 110,  110,    12, },          /* 9.16 MPix/s */
 
494
                { 110,  132,    10, },          /* 11   Mpix/s */
 
495
                { 120,  120,    10, },          /* 12   Mpix/s */
 
496
                { 133,  133,    10, },          /* 13.3 Mpix/s */
 
497
        };
 
498
 
 
499
        l4_rate = rfbi.l4_khz / 1000;
 
500
        dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000;
 
501
 
 
502
        for (i = 0; i < ARRAY_SIZE(ftab); i++) {
 
503
                /* Use a window instead of an exact match, to account
 
504
                 * for different DPLL multiplier / divider pairs.
 
505
                 */
 
506
                if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
 
507
                    abs(ftab[i].dss1_clk - dss1_rate) < 3) {
 
508
                        min_l4_ticks = ftab[i].min_l4_ticks;
 
509
                        break;
 
510
                }
 
511
        }
 
512
        if (i == ARRAY_SIZE(ftab)) {
 
513
                /* Can't be sure, return anyway the maximum not
 
514
                 * rate-limited. This might cause a problem only for the
 
515
                 * tearing synchronisation.
 
516
                 */
 
517
                DSSERR("can't determine maximum RFBI transfer rate\n");
 
518
                return rfbi.l4_khz * 1000;
 
519
        }
 
520
        return rfbi.l4_khz * 1000 / min_l4_ticks;
 
521
}
 
522
#else
 
523
int rfbi_get_max_tx_rate(void)
 
524
{
 
525
        return rfbi.l4_khz * 1000;
 
526
}
 
527
#endif
 
528
 
 
529
static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
 
530
{
 
531
        *clk_period = 1000000000 / rfbi.l4_khz;
 
532
        *max_clk_div = 2;
 
533
}
 
534
 
 
535
static int rfbi_convert_timings(struct rfbi_timings *t)
 
536
{
 
537
        u32 l;
 
538
        int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
 
539
        int actim, recyc, wecyc;
 
540
        int div = t->clk_div;
 
541
 
 
542
        if (div <= 0 || div > 2)
 
543
                return -1;
 
544
 
 
545
        /* Make sure that after conversion it still holds that:
 
546
         * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
 
547
         * csoff > cson, csoff >= max(weoff, reoff), actim > reon
 
548
         */
 
549
        weon = ps_to_rfbi_ticks(t->we_on_time, div);
 
550
        weoff = ps_to_rfbi_ticks(t->we_off_time, div);
 
551
        if (weoff <= weon)
 
552
                weoff = weon + 1;
 
553
        if (weon > 0x0f)
 
554
                return -1;
 
555
        if (weoff > 0x3f)
 
556
                return -1;
 
557
 
 
558
        reon = ps_to_rfbi_ticks(t->re_on_time, div);
 
559
        reoff = ps_to_rfbi_ticks(t->re_off_time, div);
 
560
        if (reoff <= reon)
 
561
                reoff = reon + 1;
 
562
        if (reon > 0x0f)
 
563
                return -1;
 
564
        if (reoff > 0x3f)
 
565
                return -1;
 
566
 
 
567
        cson = ps_to_rfbi_ticks(t->cs_on_time, div);
 
568
        csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
 
569
        if (csoff <= cson)
 
570
                csoff = cson + 1;
 
571
        if (csoff < max(weoff, reoff))
 
572
                csoff = max(weoff, reoff);
 
573
        if (cson > 0x0f)
 
574
                return -1;
 
575
        if (csoff > 0x3f)
 
576
                return -1;
 
577
 
 
578
        l =  cson;
 
579
        l |= csoff << 4;
 
580
        l |= weon  << 10;
 
581
        l |= weoff << 14;
 
582
        l |= reon  << 20;
 
583
        l |= reoff << 24;
 
584
 
 
585
        t->tim[0] = l;
 
586
 
 
587
        actim = ps_to_rfbi_ticks(t->access_time, div);
 
588
        if (actim <= reon)
 
589
                actim = reon + 1;
 
590
        if (actim > 0x3f)
 
591
                return -1;
 
592
 
 
593
        wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
 
594
        if (wecyc < weoff)
 
595
                wecyc = weoff;
 
596
        if (wecyc > 0x3f)
 
597
                return -1;
 
598
 
 
599
        recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
 
600
        if (recyc < reoff)
 
601
                recyc = reoff;
 
602
        if (recyc > 0x3f)
 
603
                return -1;
 
604
 
 
605
        cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
 
606
        if (cs_pulse > 0x3f)
 
607
                return -1;
 
608
 
 
609
        l =  wecyc;
 
610
        l |= recyc    << 6;
 
611
        l |= cs_pulse << 12;
 
612
        l |= actim    << 22;
 
613
 
 
614
        t->tim[1] = l;
 
615
 
 
616
        t->tim[2] = div - 1;
 
617
 
 
618
        t->converted = 1;
 
619
 
 
620
        return 0;
 
621
}
 
622
 
 
623
/* xxx FIX module selection missing */
 
624
int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
 
625
                             unsigned hs_pulse_time, unsigned vs_pulse_time,
 
626
                             int hs_pol_inv, int vs_pol_inv, int extif_div)
 
627
{
 
628
        int hs, vs;
 
629
        int min;
 
630
        u32 l;
 
631
 
 
632
        hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
 
633
        vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
 
634
        if (hs < 2)
 
635
                return -EDOM;
 
636
        if (mode == OMAP_DSS_RFBI_TE_MODE_2)
 
637
                min = 2;
 
638
        else /* OMAP_DSS_RFBI_TE_MODE_1 */
 
639
                min = 4;
 
640
        if (vs < min)
 
641
                return -EDOM;
 
642
        if (vs == hs)
 
643
                return -EINVAL;
 
644
        rfbi.te_mode = mode;
 
645
        DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
 
646
                mode, hs, vs, hs_pol_inv, vs_pol_inv);
 
647
 
 
648
        rfbi_enable_clocks(1);
 
649
        rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
 
650
        rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
 
651
 
 
652
        l = rfbi_read_reg(RFBI_CONFIG(0));
 
653
        if (hs_pol_inv)
 
654
                l &= ~(1 << 21);
 
655
        else
 
656
                l |= 1 << 21;
 
657
        if (vs_pol_inv)
 
658
                l &= ~(1 << 20);
 
659
        else
 
660
                l |= 1 << 20;
 
661
        rfbi_enable_clocks(0);
 
662
 
 
663
        return 0;
 
664
}
 
665
EXPORT_SYMBOL(omap_rfbi_setup_te);
 
666
 
 
667
/* xxx FIX module selection missing */
 
668
int omap_rfbi_enable_te(bool enable, unsigned line)
 
669
{
 
670
        u32 l;
 
671
 
 
672
        DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode);
 
673
        if (line > (1 << 11) - 1)
 
674
                return -EINVAL;
 
675
 
 
676
        rfbi_enable_clocks(1);
 
677
        l = rfbi_read_reg(RFBI_CONFIG(0));
 
678
        l &= ~(0x3 << 2);
 
679
        if (enable) {
 
680
                rfbi.te_enabled = 1;
 
681
                l |= rfbi.te_mode << 2;
 
682
        } else
 
683
                rfbi.te_enabled = 0;
 
684
        rfbi_write_reg(RFBI_CONFIG(0), l);
 
685
        rfbi_write_reg(RFBI_LINE_NUMBER, line);
 
686
        rfbi_enable_clocks(0);
 
687
 
 
688
        return 0;
 
689
}
 
690
EXPORT_SYMBOL(omap_rfbi_enable_te);
 
691
 
 
692
#if 0
 
693
static void rfbi_enable_config(int enable1, int enable2)
 
694
{
 
695
        u32 l;
 
696
        int cs = 0;
 
697
 
 
698
        if (enable1)
 
699
                cs |= 1<<0;
 
700
        if (enable2)
 
701
                cs |= 1<<1;
 
702
 
 
703
        rfbi_enable_clocks(1);
 
704
 
 
705
        l = rfbi_read_reg(RFBI_CONTROL);
 
706
 
 
707
        l = FLD_MOD(l, cs, 3, 2);
 
708
        l = FLD_MOD(l, 0, 1, 1);
 
709
 
 
710
        rfbi_write_reg(RFBI_CONTROL, l);
 
711
 
 
712
 
 
713
        l = rfbi_read_reg(RFBI_CONFIG(0));
 
714
        l = FLD_MOD(l, 0, 3, 2); /* TRIGGERMODE: ITE */
 
715
        /*l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
 
716
        /*l |= FLD_VAL(0, 8, 7); */ /* L4FORMAT, 1pix/L4 */
 
717
 
 
718
        l = FLD_MOD(l, 0, 16, 16); /* A0POLARITY */
 
719
        l = FLD_MOD(l, 1, 20, 20); /* TE_VSYNC_POLARITY */
 
720
        l = FLD_MOD(l, 1, 21, 21); /* HSYNCPOLARITY */
 
721
 
 
722
        l = FLD_MOD(l, OMAP_DSS_RFBI_PARALLELMODE_8, 1, 0);
 
723
        rfbi_write_reg(RFBI_CONFIG(0), l);
 
724
 
 
725
        rfbi_enable_clocks(0);
 
726
}
 
727
#endif
 
728
 
 
729
int rfbi_configure(int rfbi_module, int bpp, int lines)
 
730
{
 
731
        u32 l;
 
732
        int cycle1 = 0, cycle2 = 0, cycle3 = 0;
 
733
        enum omap_rfbi_cycleformat cycleformat;
 
734
        enum omap_rfbi_datatype datatype;
 
735
        enum omap_rfbi_parallelmode parallelmode;
 
736
 
 
737
        switch (bpp) {
 
738
        case 12:
 
739
                datatype = OMAP_DSS_RFBI_DATATYPE_12;
 
740
                break;
 
741
        case 16:
 
742
                datatype = OMAP_DSS_RFBI_DATATYPE_16;
 
743
                break;
 
744
        case 18:
 
745
                datatype = OMAP_DSS_RFBI_DATATYPE_18;
 
746
                break;
 
747
        case 24:
 
748
                datatype = OMAP_DSS_RFBI_DATATYPE_24;
 
749
                break;
 
750
        default:
 
751
                BUG();
 
752
                return 1;
 
753
        }
 
754
        rfbi.datatype = datatype;
 
755
 
 
756
        switch (lines) {
 
757
        case 8:
 
758
                parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8;
 
759
                break;
 
760
        case 9:
 
761
                parallelmode = OMAP_DSS_RFBI_PARALLELMODE_9;
 
762
                break;
 
763
        case 12:
 
764
                parallelmode = OMAP_DSS_RFBI_PARALLELMODE_12;
 
765
                break;
 
766
        case 16:
 
767
                parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16;
 
768
                break;
 
769
        default:
 
770
                BUG();
 
771
                return 1;
 
772
        }
 
773
        rfbi.parallelmode = parallelmode;
 
774
 
 
775
        if ((bpp % lines) == 0) {
 
776
                switch (bpp / lines) {
 
777
                case 1:
 
778
                        cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_1_1;
 
779
                        break;
 
780
                case 2:
 
781
                        cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_2_1;
 
782
                        break;
 
783
                case 3:
 
784
                        cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_1;
 
785
                        break;
 
786
                default:
 
787
                        BUG();
 
788
                        return 1;
 
789
                }
 
790
        } else if ((2 * bpp % lines) == 0) {
 
791
                if ((2 * bpp / lines) == 3)
 
792
                        cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_2;
 
793
                else {
 
794
                        BUG();
 
795
                        return 1;
 
796
                }
 
797
        } else {
 
798
                BUG();
 
799
                return 1;
 
800
        }
 
801
 
 
802
        switch (cycleformat) {
 
803
        case OMAP_DSS_RFBI_CYCLEFORMAT_1_1:
 
804
                cycle1 = lines;
 
805
                break;
 
806
 
 
807
        case OMAP_DSS_RFBI_CYCLEFORMAT_2_1:
 
808
                cycle1 = lines;
 
809
                cycle2 = lines;
 
810
                break;
 
811
 
 
812
        case OMAP_DSS_RFBI_CYCLEFORMAT_3_1:
 
813
                cycle1 = lines;
 
814
                cycle2 = lines;
 
815
                cycle3 = lines;
 
816
                break;
 
817
 
 
818
        case OMAP_DSS_RFBI_CYCLEFORMAT_3_2:
 
819
                cycle1 = lines;
 
820
                cycle2 = (lines / 2) | ((lines / 2) << 16);
 
821
                cycle3 = (lines << 16);
 
822
                break;
 
823
        }
 
824
 
 
825
        rfbi_enable_clocks(1);
 
826
 
 
827
        REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
 
828
 
 
829
        l = 0;
 
830
        l |= FLD_VAL(parallelmode, 1, 0);
 
831
        l |= FLD_VAL(0, 3, 2);          /* TRIGGERMODE: ITE */
 
832
        l |= FLD_VAL(0, 4, 4);          /* TIMEGRANULARITY */
 
833
        l |= FLD_VAL(datatype, 6, 5);
 
834
        /* l |= FLD_VAL(2, 8, 7); */    /* L4FORMAT, 2pix/L4 */
 
835
        l |= FLD_VAL(0, 8, 7);  /* L4FORMAT, 1pix/L4 */
 
836
        l |= FLD_VAL(cycleformat, 10, 9);
 
837
        l |= FLD_VAL(0, 12, 11);        /* UNUSEDBITS */
 
838
        l |= FLD_VAL(0, 16, 16);        /* A0POLARITY */
 
839
        l |= FLD_VAL(0, 17, 17);        /* REPOLARITY */
 
840
        l |= FLD_VAL(0, 18, 18);        /* WEPOLARITY */
 
841
        l |= FLD_VAL(0, 19, 19);        /* CSPOLARITY */
 
842
        l |= FLD_VAL(1, 20, 20);        /* TE_VSYNC_POLARITY */
 
843
        l |= FLD_VAL(1, 21, 21);        /* HSYNCPOLARITY */
 
844
        rfbi_write_reg(RFBI_CONFIG(rfbi_module), l);
 
845
 
 
846
        rfbi_write_reg(RFBI_DATA_CYCLE1(rfbi_module), cycle1);
 
847
        rfbi_write_reg(RFBI_DATA_CYCLE2(rfbi_module), cycle2);
 
848
        rfbi_write_reg(RFBI_DATA_CYCLE3(rfbi_module), cycle3);
 
849
 
 
850
 
 
851
        l = rfbi_read_reg(RFBI_CONTROL);
 
852
        l = FLD_MOD(l, rfbi_module+1, 3, 2); /* Select CSx */
 
853
        l = FLD_MOD(l, 0, 1, 1); /* clear bypass */
 
854
        rfbi_write_reg(RFBI_CONTROL, l);
 
855
 
 
856
 
 
857
        DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
 
858
               bpp, lines, cycle1, cycle2, cycle3);
 
859
 
 
860
        rfbi_enable_clocks(0);
 
861
 
 
862
        return 0;
 
863
}
 
864
EXPORT_SYMBOL(rfbi_configure);
 
865
 
 
866
int omap_rfbi_prepare_update(struct omap_dss_device *dssdev,
 
867
                u16 *x, u16 *y, u16 *w, u16 *h)
 
868
{
 
869
        u16 dw, dh;
 
870
 
 
871
        dssdev->driver->get_resolution(dssdev, &dw, &dh);
 
872
 
 
873
        if  (*x > dw || *y > dh)
 
874
                return -EINVAL;
 
875
 
 
876
        if (*x + *w > dw)
 
877
                return -EINVAL;
 
878
 
 
879
        if (*y + *h > dh)
 
880
                return -EINVAL;
 
881
 
 
882
        if (*w == 1)
 
883
                return -EINVAL;
 
884
 
 
885
        if (*w == 0 || *h == 0)
 
886
                return -EINVAL;
 
887
 
 
888
        if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
 
889
                dss_setup_partial_planes(dssdev, x, y, w, h, true);
 
890
                dispc_set_lcd_size(dssdev->manager->id, *w, *h);
 
891
        }
 
892
 
 
893
        return 0;
 
894
}
 
895
EXPORT_SYMBOL(omap_rfbi_prepare_update);
 
896
 
 
897
int omap_rfbi_update(struct omap_dss_device *dssdev,
 
898
                u16 x, u16 y, u16 w, u16 h,
 
899
                void (*callback)(void *), void *data)
 
900
{
 
901
        if (dssdev->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
 
902
                rfbi_transfer_area(dssdev, w, h, callback, data);
 
903
        } else {
 
904
                struct omap_overlay *ovl;
 
905
                void __iomem *addr;
 
906
                int scr_width;
 
907
 
 
908
                ovl = dssdev->manager->overlays[0];
 
909
                scr_width = ovl->info.screen_width;
 
910
                addr = ovl->info.vaddr;
 
911
 
 
912
                omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
 
913
 
 
914
                callback(data);
 
915
        }
 
916
 
 
917
        return 0;
 
918
}
 
919
EXPORT_SYMBOL(omap_rfbi_update);
 
920
 
 
921
void rfbi_dump_regs(struct seq_file *s)
 
922
{
 
923
#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
 
924
 
 
925
        dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
 
926
 
 
927
        DUMPREG(RFBI_REVISION);
 
928
        DUMPREG(RFBI_SYSCONFIG);
 
929
        DUMPREG(RFBI_SYSSTATUS);
 
930
        DUMPREG(RFBI_CONTROL);
 
931
        DUMPREG(RFBI_PIXEL_CNT);
 
932
        DUMPREG(RFBI_LINE_NUMBER);
 
933
        DUMPREG(RFBI_CMD);
 
934
        DUMPREG(RFBI_PARAM);
 
935
        DUMPREG(RFBI_DATA);
 
936
        DUMPREG(RFBI_READ);
 
937
        DUMPREG(RFBI_STATUS);
 
938
 
 
939
        DUMPREG(RFBI_CONFIG(0));
 
940
        DUMPREG(RFBI_ONOFF_TIME(0));
 
941
        DUMPREG(RFBI_CYCLE_TIME(0));
 
942
        DUMPREG(RFBI_DATA_CYCLE1(0));
 
943
        DUMPREG(RFBI_DATA_CYCLE2(0));
 
944
        DUMPREG(RFBI_DATA_CYCLE3(0));
 
945
 
 
946
        DUMPREG(RFBI_CONFIG(1));
 
947
        DUMPREG(RFBI_ONOFF_TIME(1));
 
948
        DUMPREG(RFBI_CYCLE_TIME(1));
 
949
        DUMPREG(RFBI_DATA_CYCLE1(1));
 
950
        DUMPREG(RFBI_DATA_CYCLE2(1));
 
951
        DUMPREG(RFBI_DATA_CYCLE3(1));
 
952
 
 
953
        DUMPREG(RFBI_VSYNC_WIDTH);
 
954
        DUMPREG(RFBI_HSYNC_WIDTH);
 
955
 
 
956
        dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
 
957
#undef DUMPREG
 
958
}
 
959
 
 
960
int rfbi_init(void)
 
961
{
 
962
        u32 rev;
 
963
        u32 l;
 
964
 
 
965
        spin_lock_init(&rfbi.cmd_lock);
 
966
 
 
967
        init_completion(&rfbi.cmd_done);
 
968
        atomic_set(&rfbi.cmd_fifo_full, 0);
 
969
        atomic_set(&rfbi.cmd_pending, 0);
 
970
 
 
971
        rfbi.base = ioremap(RFBI_BASE, SZ_256);
 
972
        if (!rfbi.base) {
 
973
                DSSERR("can't ioremap RFBI\n");
 
974
                return -ENOMEM;
 
975
        }
 
976
 
 
977
        rfbi_enable_clocks(1);
 
978
 
 
979
        msleep(10);
 
980
 
 
981
        rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
 
982
 
 
983
        /* Enable autoidle and smart-idle */
 
984
        l = rfbi_read_reg(RFBI_SYSCONFIG);
 
985
        l |= (1 << 0) | (2 << 3);
 
986
        rfbi_write_reg(RFBI_SYSCONFIG, l);
 
987
 
 
988
        rev = rfbi_read_reg(RFBI_REVISION);
 
989
        printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
 
990
               FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
 
991
 
 
992
        rfbi_enable_clocks(0);
 
993
 
 
994
        return 0;
 
995
}
 
996
 
 
997
void rfbi_exit(void)
 
998
{
 
999
        DSSDBG("rfbi_exit\n");
 
1000
 
 
1001
        iounmap(rfbi.base);
 
1002
}
 
1003
 
 
1004
int omapdss_rfbi_display_enable(struct omap_dss_device *dssdev)
 
1005
{
 
1006
        int r;
 
1007
 
 
1008
        r = omap_dss_start_device(dssdev);
 
1009
        if (r) {
 
1010
                DSSERR("failed to start device\n");
 
1011
                goto err0;
 
1012
        }
 
1013
 
 
1014
        r = omap_dispc_register_isr(framedone_callback, NULL,
 
1015
                        DISPC_IRQ_FRAMEDONE);
 
1016
        if (r) {
 
1017
                DSSERR("can't get FRAMEDONE irq\n");
 
1018
                goto err1;
 
1019
        }
 
1020
 
 
1021
        dispc_set_lcd_display_type(dssdev->manager->id,
 
1022
                        OMAP_DSS_LCD_DISPLAY_TFT);
 
1023
 
 
1024
        dispc_set_parallel_interface_mode(dssdev->manager->id,
 
1025
                        OMAP_DSS_PARALLELMODE_RFBI);
 
1026
 
 
1027
        dispc_set_tft_data_lines(dssdev->manager->id, dssdev->ctrl.pixel_size);
 
1028
 
 
1029
        rfbi_configure(dssdev->phy.rfbi.channel,
 
1030
                               dssdev->ctrl.pixel_size,
 
1031
                               dssdev->phy.rfbi.data_lines);
 
1032
 
 
1033
        rfbi_set_timings(dssdev->phy.rfbi.channel,
 
1034
                         &dssdev->ctrl.rfbi_timings);
 
1035
 
 
1036
 
 
1037
        return 0;
 
1038
err1:
 
1039
        omap_dss_stop_device(dssdev);
 
1040
err0:
 
1041
        return r;
 
1042
}
 
1043
EXPORT_SYMBOL(omapdss_rfbi_display_enable);
 
1044
 
 
1045
void omapdss_rfbi_display_disable(struct omap_dss_device *dssdev)
 
1046
{
 
1047
        omap_dispc_unregister_isr(framedone_callback, NULL,
 
1048
                        DISPC_IRQ_FRAMEDONE);
 
1049
        omap_dss_stop_device(dssdev);
 
1050
}
 
1051
EXPORT_SYMBOL(omapdss_rfbi_display_disable);
 
1052
 
 
1053
int rfbi_init_display(struct omap_dss_device *dssdev)
 
1054
{
 
1055
        rfbi.dssdev[dssdev->phy.rfbi.channel] = dssdev;
 
1056
        dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
 
1057
        return 0;
 
1058
}