~ubuntu-branches/ubuntu/trusty/linux-armadaxp/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Michael Casadevall, Bryan Wu, Dann Frazier, Michael Casadeall
  • Date: 2012-03-10 15:00:54 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20120310150054-flugb39zon8vvgwe
Tags: 3.2.0-1600.1
[ Bryan Wu ]
* UBUNTU: import debian/debian.env and debian.armadaxp

[ Dann Frazier ]
* ARM: Armada XP: remove trailing '/' in dirnames in mvRules.mk

[ Michael Casadeall ]
* tools: add some tools for Marvell Armada XP processor
* kernel: timer tick hacking from Marvell
* kernel: Sheeva Errata: add delay on Sheeva when powering down
* net: add Marvell NFP netfilter
* net: socket and skb modifications made by Marvell
* miscdevice: add minor IDs for some Marvell Armada drivers
* fs: introduce memory pool for splice()
* video: EDID detection updates from Marvell Armada XP patchset
* video: backlight: add Marvell Dove LCD backlight driver
* video: display: add THS8200 display driver
* video: framebuffer: add Marvell Dove and Armada XP processor onchip LCD controller driver
* usbtest: add Interrupt transfer testing by Marvell Armada XP code
* usb: ehci: add support for Marvell EHCI controler
* tty/serial: 8250: add support for Marvell Armada XP processor and DeviceTree work
* rtc: add support for Marvell Armada XP onchip RTC controller
* net: pppoe: add Marvell ethernet NFP hook in PPPoE networking driver
* mtd: nand: add support for Marvell Armada XP Nand Flash Controller
* mtd: maps: add Marvell Armada XP specific map driver
* mmc: add support for Marvell Armada XP MMC/SD host controller
* i2c: add support for Marvell Armada XP onchip i2c bus controller
* hwmon: add Kconfig option for Armada XP onchip thermal sensor driver
* dmaengine: add Net DMA support for splice and update Marvell XOR DMA engine driver
* ata: add support for Marvell Armada XP SATA controller and update some quirks
* ARM: add Marvell Armada XP machine to mach-types
* ARM: oprofile: add support for Marvell PJ4B core
* ARM: mm: more ARMv6 switches for Marvell Armada XP
* ARM: remove static declaration to allow compilation
* ARM: alignment access fault trick
* ARM: mm: skip some fault fixing when run on NONE SMP ARMv6 mode during early abort event
* ARM: mm: add Marvell Sheeva CPU Architecture for PJ4B
* ARM: introduce optimized copy operation for Marvell Armada XP
* ARM: SAUCE: hardware breakpoint trick for Marvell Armada XP
* ARM: big endian and little endian tricks for Marvell Armada XP
* ARM: SAUCE: Add Marvell Armada XP build rules to arch/arm/kernel/Makefile
* ARM: vfp: add special handling for Marvell Armada XP
* ARM: add support for Marvell U-Boot
* ARM: add mv_controller_num for ARM PCI drivers
* ARM: add support for local PMUs, general SMP tweaks and cache flushing
* ARM: add Marvell device identifies in glue-proc.h
* ARM: add IPC driver support for Marvell platforms
* ARM: add DMA mapping for Marvell platforms
* ARM: add Sheeva errata and PJ4B code for booting
* ARM: update Kconfig and Makefile to include Marvell Armada XP platforms
* ARM: Armada XP: import LSP from Marvell for Armada XP 3.2 kernel enablement

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright © 2010 Intel Corporation
 
3
 *
 
4
 * Permission is hereby granted, free of charge, to any person obtaining a
 
5
 * copy of this software and associated documentation files (the "Software"),
 
6
 * to deal in the Software without restriction, including without limitation
 
7
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
8
 * and/or sell copies of the Software, and to permit persons to whom the
 
9
 * Software is furnished to do so, subject to the following conditions:
 
10
 *
 
11
 * The above copyright notice and this permission notice (including the next
 
12
 * paragraph) shall be included in all copies or substantial portions of the
 
13
 * Software.
 
14
 *
 
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
21
 * DEALINGS IN THE SOFTWARE.
 
22
 *
 
23
 * Authors:
 
24
 * jim liu <jim.liu@intel.com>
 
25
 * Jackie Li<yaodong.li@intel.com>
 
26
 */
 
27
 
 
28
#include "mdfld_dsi_dpi.h"
 
29
#include "mdfld_output.h"
 
30
#include "mdfld_dsi_pkg_sender.h"
 
31
 
 
32
 
 
33
static void mdfld_wait_for_HS_DATA_FIFO(struct drm_device *dev, u32 pipe)
 
34
{
 
35
        u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
 
36
        int timeout = 0;
 
37
 
 
38
        if (pipe == 2)
 
39
                gen_fifo_stat_reg += MIPIC_REG_OFFSET;
 
40
 
 
41
        udelay(500);
 
42
 
 
43
        /* This will time out after approximately 2+ seconds */
 
44
        while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_DATA_FULL)) {
 
45
                udelay(100);
 
46
                timeout++;
 
47
        }
 
48
 
 
49
        if (timeout == 20000)
 
50
                dev_warn(dev->dev, "MIPI: HS Data FIFO was never cleared!\n");
 
51
}
 
52
 
 
53
static void mdfld_wait_for_HS_CTRL_FIFO(struct drm_device *dev, u32 pipe)
 
54
{
 
55
        u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
 
56
        int timeout = 0;
 
57
 
 
58
        if (pipe == 2)
 
59
                gen_fifo_stat_reg += MIPIC_REG_OFFSET;
 
60
 
 
61
        udelay(500);
 
62
 
 
63
        /* This will time out after approximately 2+ seconds */
 
64
        while ((timeout < 20000) && (REG_READ(gen_fifo_stat_reg) & DSI_FIFO_GEN_HS_CTRL_FULL)) {
 
65
                udelay(100);
 
66
                timeout++;
 
67
        }
 
68
        if (timeout == 20000)
 
69
                dev_warn(dev->dev, "MIPI: HS CMD FIFO was never cleared!\n");
 
70
}
 
71
 
 
72
static void mdfld_wait_for_DPI_CTRL_FIFO(struct drm_device *dev, u32 pipe)
 
73
{
 
74
        u32 gen_fifo_stat_reg = MIPIA_GEN_FIFO_STAT_REG;
 
75
        int timeout = 0;
 
76
 
 
77
        if (pipe == 2)
 
78
                gen_fifo_stat_reg += MIPIC_REG_OFFSET;
 
79
 
 
80
        udelay(500);
 
81
 
 
82
        /* This will time out after approximately 2+ seconds */
 
83
        while ((timeout < 20000) && ((REG_READ(gen_fifo_stat_reg) & DPI_FIFO_EMPTY)
 
84
                                                        != DPI_FIFO_EMPTY)) {
 
85
                udelay(100);
 
86
                timeout++;
 
87
        }
 
88
 
 
89
        if (timeout == 20000)
 
90
                dev_warn(dev->dev, "MIPI: DPI FIFO was never cleared!\n");
 
91
}
 
92
 
 
93
static void mdfld_wait_for_SPL_PKG_SENT(struct drm_device *dev, u32 pipe)
 
94
{
 
95
        u32 intr_stat_reg = MIPIA_INTR_STAT_REG;
 
96
        int timeout = 0;
 
97
 
 
98
        if (pipe == 2)
 
99
                intr_stat_reg += MIPIC_REG_OFFSET;
 
100
 
 
101
        udelay(500);
 
102
 
 
103
        /* This will time out after approximately 2+ seconds */
 
104
        while ((timeout < 20000) && (!(REG_READ(intr_stat_reg) & DSI_INTR_STATE_SPL_PKG_SENT))) {
 
105
                udelay(100);
 
106
                timeout++;
 
107
        }
 
108
 
 
109
        if (timeout == 20000)
 
110
                dev_warn(dev->dev, "MIPI: SPL_PKT_SENT_INTERRUPT was not sent successfully!\n");
 
111
}
 
112
 
 
113
 
 
114
/* ************************************************************************* *\
 
115
 * FUNCTION: mdfld_dsi_tpo_ic_init
 
116
 *
 
117
 * DESCRIPTION:  This function is called only by mrst_dsi_mode_set and
 
118
 *               restore_display_registers.  since this function does not
 
119
 *               acquire the mutex, it is important that the calling function
 
120
 *               does!
 
121
\* ************************************************************************* */
 
122
void mdfld_dsi_tpo_ic_init(struct mdfld_dsi_config *dsi_config, u32 pipe)
 
123
{
 
124
        struct drm_device *dev = dsi_config->dev;
 
125
        u32 dcsChannelNumber = dsi_config->channel_num;
 
126
        u32 gen_data_reg = MIPIA_HS_GEN_DATA_REG; 
 
127
        u32 gen_ctrl_reg = MIPIA_HS_GEN_CTRL_REG;
 
128
        u32 gen_ctrl_val = GEN_LONG_WRITE;
 
129
 
 
130
        if (pipe == 2) {
 
131
                gen_data_reg = HS_GEN_DATA_REG + MIPIC_REG_OFFSET; 
 
132
                gen_ctrl_reg = HS_GEN_CTRL_REG + MIPIC_REG_OFFSET;
 
133
        }
 
134
 
 
135
        gen_ctrl_val |= dcsChannelNumber << DCS_CHANNEL_NUMBER_POS;
 
136
 
 
137
        /* Flip page order */
 
138
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
139
        REG_WRITE(gen_data_reg, 0x00008036);
 
140
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
141
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
 
142
 
 
143
        /* 0xF0 */
 
144
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
145
        REG_WRITE(gen_data_reg, 0x005a5af0);
 
146
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
147
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 
148
 
 
149
        /* Write protection key */
 
150
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
151
        REG_WRITE(gen_data_reg, 0x005a5af1);
 
152
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
153
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 
154
 
 
155
        /* 0xFC */
 
156
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
157
        REG_WRITE(gen_data_reg, 0x005a5afc);
 
158
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
159
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 
160
 
 
161
        /* 0xB7 */
 
162
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
163
        REG_WRITE(gen_data_reg, 0x770000b7);
 
164
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
165
        REG_WRITE(gen_data_reg, 0x00000044);
 
166
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
167
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x05 << WORD_COUNTS_POS));
 
168
 
 
169
        /* 0xB6 */
 
170
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
171
        REG_WRITE(gen_data_reg, 0x000a0ab6);
 
172
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
173
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 
174
 
 
175
        /* 0xF2 */
 
176
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
177
        REG_WRITE(gen_data_reg, 0x081010f2);
 
178
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
179
        REG_WRITE(gen_data_reg, 0x4a070708);
 
180
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
181
        REG_WRITE(gen_data_reg, 0x000000c5);
 
182
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
183
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
 
184
 
 
185
        /* 0xF8 */
 
186
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
187
        REG_WRITE(gen_data_reg, 0x024003f8);
 
188
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
189
        REG_WRITE(gen_data_reg, 0x01030a04);
 
190
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
191
        REG_WRITE(gen_data_reg, 0x0e020220);
 
192
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
193
        REG_WRITE(gen_data_reg, 0x00000004);
 
194
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
195
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x0d << WORD_COUNTS_POS));
 
196
 
 
197
        /* 0xE2 */
 
198
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
199
        REG_WRITE(gen_data_reg, 0x398fc3e2);
 
200
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
201
        REG_WRITE(gen_data_reg, 0x0000916f);
 
202
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
203
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x06 << WORD_COUNTS_POS));
 
204
 
 
205
        /* 0xB0 */
 
206
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
207
        REG_WRITE(gen_data_reg, 0x000000b0);
 
208
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
209
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x02 << WORD_COUNTS_POS));
 
210
 
 
211
        /* 0xF4 */
 
212
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
213
        REG_WRITE(gen_data_reg, 0x240242f4);
 
214
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
215
        REG_WRITE(gen_data_reg, 0x78ee2002);
 
216
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
217
        REG_WRITE(gen_data_reg, 0x2a071050);
 
218
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
219
        REG_WRITE(gen_data_reg, 0x507fee10);
 
220
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
221
        REG_WRITE(gen_data_reg, 0x10300710);
 
222
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
223
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x14 << WORD_COUNTS_POS));
 
224
 
 
225
        /* 0xBA */
 
226
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
227
        REG_WRITE(gen_data_reg, 0x19fe07ba);
 
228
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
229
        REG_WRITE(gen_data_reg, 0x101c0a31);
 
230
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
231
        REG_WRITE(gen_data_reg, 0x00000010);
 
232
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
233
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
 
234
 
 
235
        /* 0xBB */
 
236
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
237
        REG_WRITE(gen_data_reg, 0x28ff07bb);
 
238
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
239
        REG_WRITE(gen_data_reg, 0x24280a31);
 
240
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
241
        REG_WRITE(gen_data_reg, 0x00000034);
 
242
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
243
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x09 << WORD_COUNTS_POS));
 
244
 
 
245
        /* 0xFB */
 
246
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
247
        REG_WRITE(gen_data_reg, 0x535d05fb);
 
248
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
249
        REG_WRITE(gen_data_reg, 0x1b1a2130);
 
250
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
251
        REG_WRITE(gen_data_reg, 0x221e180e);
 
252
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
253
        REG_WRITE(gen_data_reg, 0x131d2120);
 
254
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
255
        REG_WRITE(gen_data_reg, 0x535d0508);
 
256
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
257
        REG_WRITE(gen_data_reg, 0x1c1a2131);
 
258
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
259
        REG_WRITE(gen_data_reg, 0x231f160d);
 
260
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
261
        REG_WRITE(gen_data_reg, 0x111b2220);
 
262
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
263
        REG_WRITE(gen_data_reg, 0x535c2008);
 
264
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
265
        REG_WRITE(gen_data_reg, 0x1f1d2433);
 
266
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
267
        REG_WRITE(gen_data_reg, 0x2c251a10);
 
268
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
269
        REG_WRITE(gen_data_reg, 0x2c34372d);
 
270
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
271
        REG_WRITE(gen_data_reg, 0x00000023);
 
272
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
273
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
 
274
 
 
275
        /* 0xFA */
 
276
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
277
        REG_WRITE(gen_data_reg, 0x525c0bfa);
 
278
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
279
        REG_WRITE(gen_data_reg, 0x1c1c232f);
 
280
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
281
        REG_WRITE(gen_data_reg, 0x2623190e);
 
282
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
283
        REG_WRITE(gen_data_reg, 0x18212625);
 
284
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
285
        REG_WRITE(gen_data_reg, 0x545d0d0e);
 
286
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
287
        REG_WRITE(gen_data_reg, 0x1e1d2333);
 
288
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
289
        REG_WRITE(gen_data_reg, 0x26231a10);
 
290
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
291
        REG_WRITE(gen_data_reg, 0x1a222725);
 
292
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
293
        REG_WRITE(gen_data_reg, 0x545d280f);
 
294
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
295
        REG_WRITE(gen_data_reg, 0x21202635);
 
296
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
297
        REG_WRITE(gen_data_reg, 0x31292013);
 
298
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
299
        REG_WRITE(gen_data_reg, 0x31393d33);
 
300
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
301
        REG_WRITE(gen_data_reg, 0x00000029);
 
302
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
303
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x31 << WORD_COUNTS_POS));
 
304
 
 
305
        /* Set DM */
 
306
        mdfld_wait_for_HS_DATA_FIFO(dev, pipe);
 
307
        REG_WRITE(gen_data_reg, 0x000100f7);
 
308
        mdfld_wait_for_HS_CTRL_FIFO(dev, pipe);
 
309
        REG_WRITE(gen_ctrl_reg, gen_ctrl_val | (0x03 << WORD_COUNTS_POS));
 
310
}
 
311
 
 
312
static u16 mdfld_dsi_dpi_to_byte_clock_count(int pixel_clock_count,
 
313
                                                int num_lane, int bpp)
 
314
{
 
315
        return (u16)((pixel_clock_count * bpp) / (num_lane * 8)); 
 
316
}
 
317
 
 
318
/*
 
319
 * Calculate the dpi time basing on a given drm mode @mode
 
320
 * return 0 on success.
 
321
 * FIXME: I was using proposed mode value for calculation, may need to 
 
322
 * use crtc mode values later 
 
323
 */
 
324
int mdfld_dsi_dpi_timing_calculation(struct drm_display_mode *mode, 
 
325
                        struct mdfld_dsi_dpi_timing *dpi_timing,
 
326
                        int num_lane, int bpp)
 
327
{
 
328
        int pclk_hsync, pclk_hfp, pclk_hbp, pclk_hactive;
 
329
        int pclk_vsync, pclk_vfp, pclk_vbp, pclk_vactive;
 
330
        
 
331
        if(!mode || !dpi_timing) {
 
332
                DRM_ERROR("Invalid parameter\n");
 
333
                return -EINVAL;
 
334
        }
 
335
        
 
336
        pclk_hactive = mode->hdisplay;
 
337
        pclk_hfp = mode->hsync_start - mode->hdisplay;
 
338
        pclk_hsync = mode->hsync_end - mode->hsync_start;
 
339
        pclk_hbp = mode->htotal - mode->hsync_end;
 
340
        
 
341
        pclk_vactive = mode->vdisplay;
 
342
        pclk_vfp = mode->vsync_start - mode->vdisplay;
 
343
        pclk_vsync = mode->vsync_end - mode->vsync_start;
 
344
        pclk_vbp = mode->vtotal - mode->vsync_end;
 
345
 
 
346
        /*
 
347
         * byte clock counts were calculated by following formula
 
348
         * bclock_count = pclk_count * bpp / num_lane / 8
 
349
         */
 
350
        dpi_timing->hsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hsync, num_lane, bpp);
 
351
        dpi_timing->hbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hbp, num_lane, bpp);
 
352
        dpi_timing->hfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hfp, num_lane, bpp);
 
353
        dpi_timing->hactive_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_hactive, num_lane, bpp);
 
354
        dpi_timing->vsync_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vsync, num_lane, bpp);
 
355
        dpi_timing->vbp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vbp, num_lane, bpp);
 
356
        dpi_timing->vfp_count = mdfld_dsi_dpi_to_byte_clock_count(pclk_vfp, num_lane, bpp);
 
357
 
 
358
        return 0; 
 
359
}
 
360
 
 
361
void mdfld_dsi_dpi_controller_init(struct mdfld_dsi_config *dsi_config, int pipe)
 
362
{
 
363
        struct drm_device *dev = dsi_config->dev;
 
364
        u32 reg_offset = pipe ? MIPIC_REG_OFFSET : 0;
 
365
        int lane_count = dsi_config->lane_count;
 
366
        struct mdfld_dsi_dpi_timing dpi_timing;
 
367
        struct drm_display_mode *mode = dsi_config->mode;
 
368
        u32 val = 0;
 
369
        
 
370
        /*un-ready device*/
 
371
        REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000000);
 
372
        
 
373
        /*init dsi adapter before kicking off*/
 
374
        REG_WRITE((MIPIA_CONTROL_REG + reg_offset), 0x00000018);
 
375
        
 
376
        /*enable all interrupts*/
 
377
        REG_WRITE((MIPIA_INTR_EN_REG + reg_offset), 0xffffffff);
 
378
        
 
379
 
 
380
        /*set up func_prg*/
 
381
        val |= lane_count;
 
382
        val |= dsi_config->channel_num << DSI_DPI_VIRT_CHANNEL_OFFSET;
 
383
                
 
384
        switch(dsi_config->bpp) {
 
385
        case 16:
 
386
                val |= DSI_DPI_COLOR_FORMAT_RGB565;
 
387
                break;
 
388
        case 18:
 
389
                val |= DSI_DPI_COLOR_FORMAT_RGB666;
 
390
                break;
 
391
        case 24:
 
392
                val |= DSI_DPI_COLOR_FORMAT_RGB888;
 
393
                break;
 
394
        default:
 
395
                DRM_ERROR("unsupported color format, bpp = %d\n", dsi_config->bpp);
 
396
        }
 
397
        REG_WRITE((MIPIA_DSI_FUNC_PRG_REG + reg_offset), val);
 
398
        
 
399
        REG_WRITE((MIPIA_HS_TX_TIMEOUT_REG + reg_offset), 
 
400
                        (mode->vtotal * mode->htotal * dsi_config->bpp / (8 * lane_count)) & DSI_HS_TX_TIMEOUT_MASK);
 
401
        REG_WRITE((MIPIA_LP_RX_TIMEOUT_REG + reg_offset), 0xffff & DSI_LP_RX_TIMEOUT_MASK);
 
402
        
 
403
        /*max value: 20 clock cycles of txclkesc*/
 
404
        REG_WRITE((MIPIA_TURN_AROUND_TIMEOUT_REG + reg_offset), 0x14 & DSI_TURN_AROUND_TIMEOUT_MASK);
 
405
        
 
406
        /*min 21 txclkesc, max: ffffh*/
 
407
        REG_WRITE((MIPIA_DEVICE_RESET_TIMER_REG + reg_offset), 0xffff & DSI_RESET_TIMER_MASK);
 
408
 
 
409
        REG_WRITE((MIPIA_DPI_RESOLUTION_REG + reg_offset), mode->vdisplay << 16 | mode->hdisplay);
 
410
        
 
411
        /*set DPI timing registers*/
 
412
        mdfld_dsi_dpi_timing_calculation(mode, &dpi_timing, dsi_config->lane_count, dsi_config->bpp);
 
413
        
 
414
        REG_WRITE((MIPIA_HSYNC_COUNT_REG + reg_offset), dpi_timing.hsync_count & DSI_DPI_TIMING_MASK);
 
415
        REG_WRITE((MIPIA_HBP_COUNT_REG + reg_offset), dpi_timing.hbp_count & DSI_DPI_TIMING_MASK);
 
416
        REG_WRITE((MIPIA_HFP_COUNT_REG + reg_offset), dpi_timing.hfp_count & DSI_DPI_TIMING_MASK);
 
417
        REG_WRITE((MIPIA_HACTIVE_COUNT_REG + reg_offset), dpi_timing.hactive_count & DSI_DPI_TIMING_MASK);
 
418
        REG_WRITE((MIPIA_VSYNC_COUNT_REG + reg_offset), dpi_timing.vsync_count & DSI_DPI_TIMING_MASK);
 
419
        REG_WRITE((MIPIA_VBP_COUNT_REG + reg_offset), dpi_timing.vbp_count & DSI_DPI_TIMING_MASK);
 
420
        REG_WRITE((MIPIA_VFP_COUNT_REG + reg_offset), dpi_timing.vfp_count & DSI_DPI_TIMING_MASK);
 
421
        
 
422
        REG_WRITE((MIPIA_HIGH_LOW_SWITCH_COUNT_REG + reg_offset), 0x46);
 
423
        
 
424
        /*min: 7d0 max: 4e20*/
 
425
        REG_WRITE((MIPIA_INIT_COUNT_REG + reg_offset), 0x000007d0);
 
426
        
 
427
        /*set up video mode*/
 
428
        val = 0;
 
429
        val = dsi_config->video_mode | DSI_DPI_COMPLETE_LAST_LINE;
 
430
        REG_WRITE((MIPIA_VIDEO_MODE_FORMAT_REG + reg_offset), val);
 
431
        
 
432
        REG_WRITE((MIPIA_EOT_DISABLE_REG + reg_offset), 0x00000000);
 
433
        
 
434
        REG_WRITE((MIPIA_LP_BYTECLK_REG + reg_offset), 0x00000004);
 
435
        
 
436
        /*TODO: figure out how to setup these registers*/
 
437
        REG_WRITE((MIPIA_DPHY_PARAM_REG + reg_offset), 0x150c3408);
 
438
        
 
439
        REG_WRITE((MIPIA_CLK_LANE_SWITCH_TIME_CNT_REG + reg_offset), (0xa << 16) | 0x14);
 
440
        /*set device ready*/
 
441
        REG_WRITE((MIPIA_DEVICE_READY_REG + reg_offset), 0x00000001);
 
442
}
 
443
 
 
444
void mdfld_dsi_dpi_turn_on(struct mdfld_dsi_dpi_output *output, int pipe)
 
445
{
 
446
        struct drm_device *dev = output->dev;
 
447
        u32 reg_offset = 0;
 
448
        
 
449
        if(output->panel_on) 
 
450
                return;
 
451
                
 
452
        if(pipe) 
 
453
                reg_offset = MIPIC_REG_OFFSET;
 
454
 
 
455
        /* clear special packet sent bit */
 
456
        if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
 
457
                REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
 
458
        }
 
459
                
 
460
        /*send turn on package*/
 
461
        REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_TURN_ON);
 
462
        
 
463
        /*wait for SPL_PKG_SENT interrupt*/
 
464
        mdfld_wait_for_SPL_PKG_SENT(dev, pipe);
 
465
        
 
466
        if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
 
467
                REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
 
468
        }
 
469
 
 
470
        output->panel_on = 1;
 
471
 
 
472
        /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
 
473
        /* if(pipe == 2) */
 
474
        /*      dev_priv->dpi_panel_on2 = true; */
 
475
        /* else if (pipe == 0) */
 
476
        /*      dev_priv->dpi_panel_on = true; */
 
477
}
 
478
 
 
479
static void mdfld_dsi_dpi_shut_down(struct mdfld_dsi_dpi_output *output, int pipe)
 
480
{
 
481
        struct drm_device *dev = output->dev;
 
482
        u32 reg_offset = 0;
 
483
        
 
484
        /*if output is on, or mode setting didn't happen, ignore this*/
 
485
        if((!output->panel_on) || output->first_boot) {
 
486
                output->first_boot = 0; 
 
487
                return;
 
488
        }
 
489
        
 
490
        if(pipe)
 
491
                reg_offset = MIPIC_REG_OFFSET;
 
492
 
 
493
        /* Wait for dpi fifo to empty */
 
494
        mdfld_wait_for_DPI_CTRL_FIFO(dev, pipe);
 
495
 
 
496
        /* Clear the special packet interrupt bit if set */
 
497
        if(REG_READ(MIPIA_INTR_STAT_REG + reg_offset) & DSI_INTR_STATE_SPL_PKG_SENT) {
 
498
                REG_WRITE((MIPIA_INTR_STAT_REG + reg_offset), DSI_INTR_STATE_SPL_PKG_SENT);
 
499
        }
 
500
        
 
501
        if(REG_READ(MIPIA_DPI_CONTROL_REG + reg_offset) == DSI_DPI_CTRL_HS_SHUTDOWN) {
 
502
                dev_warn(dev->dev, "try to send the same package again, abort!");
 
503
                goto shutdown_out;
 
504
        }
 
505
        
 
506
        REG_WRITE((MIPIA_DPI_CONTROL_REG + reg_offset), DSI_DPI_CTRL_HS_SHUTDOWN);
 
507
 
 
508
shutdown_out:
 
509
        output->panel_on = 0;
 
510
        output->first_boot = 0;
 
511
 
 
512
        /* FIXME the following is disabled to WA the X slow start issue for TMD panel */
 
513
        /* if(pipe == 2) */
 
514
        /*      dev_priv->dpi_panel_on2 = false; */
 
515
        /* else if (pipe == 0) */
 
516
        /*      dev_priv->dpi_panel_on = false;  */
 
517
        /* #ifdef CONFIG_PM_RUNTIME*/ 
 
518
        /*      if (drm_psb_ospm && !enable_gfx_rtpm) { */
 
519
        /*              pm_runtime_allow(&gpDrmDevice->pdev->dev); */
 
520
        /*      schedule_delayed_work(&dev_priv->rtpm_work, 30 * 1000); */
 
521
        /* } */
 
522
        /*if (enable_gfx_rtpm) */
 
523
        /*              pm_schedule_suspend(&dev->pdev->dev, gfxrtdelay); */
 
524
        /* #endif */
 
525
}
 
526
 
 
527
void mdfld_dsi_dpi_set_power(struct drm_encoder *encoder, bool on)
 
528
{
 
529
        struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
 
530
        struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
 
531
        struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
 
532
        int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
 
533
        struct drm_device *dev = dsi_config->dev;
 
534
        struct drm_psb_private *dev_priv = dev->dev_private;
 
535
        u32 mipi_reg = MIPI;
 
536
        u32 pipeconf_reg = PIPEACONF;
 
537
        
 
538
        if(pipe) {
 
539
                mipi_reg = MIPI_C;
 
540
                pipeconf_reg = PIPECCONF;
 
541
        }
 
542
        
 
543
        /* Start up display island if it was shutdown */
 
544
        if (!gma_power_begin(dev, true))
 
545
                return;
 
546
 
 
547
        if(on) {
 
548
                if (mdfld_get_panel_type(dev, pipe) == TMD_VID){
 
549
                        mdfld_dsi_dpi_turn_on(dpi_output, pipe);
 
550
                } else {
 
551
                        /* Enable mipi port */
 
552
                        REG_WRITE(mipi_reg, (REG_READ(mipi_reg) | (1 << 31)));
 
553
                        REG_READ(mipi_reg);
 
554
 
 
555
                        mdfld_dsi_dpi_turn_on(dpi_output, pipe);
 
556
                        mdfld_dsi_tpo_ic_init(dsi_config, pipe);
 
557
                }
 
558
 
 
559
                if(pipe == 2) {
 
560
                        dev_priv->dpi_panel_on2 = true;
 
561
                }
 
562
                else {
 
563
                        dev_priv->dpi_panel_on  = true;
 
564
                }
 
565
 
 
566
        } else {
 
567
                if (mdfld_get_panel_type(dev, pipe) == TMD_VID) {
 
568
                        mdfld_dsi_dpi_shut_down(dpi_output, pipe);
 
569
                } else {
 
570
                        mdfld_dsi_dpi_shut_down(dpi_output, pipe);
 
571
                        /* Disable mipi port */
 
572
                        REG_WRITE(mipi_reg, (REG_READ(mipi_reg) & ~(1<<31)));
 
573
                        REG_READ(mipi_reg);
 
574
                }
 
575
 
 
576
                if(pipe == 2)
 
577
                        dev_priv->dpi_panel_on2 = false;
 
578
                else
 
579
                        dev_priv->dpi_panel_on  = false;
 
580
        }
 
581
        gma_power_end(dev);
 
582
}
 
583
 
 
584
void mdfld_dsi_dpi_dpms(struct drm_encoder *encoder, int mode)
 
585
{
 
586
        dev_dbg(encoder->dev->dev, "DPMS %s\n",
 
587
                        (mode == DRM_MODE_DPMS_ON ? "on":"off"));
 
588
 
 
589
        if (mode == DRM_MODE_DPMS_ON)
 
590
                mdfld_dsi_dpi_set_power(encoder, true);
 
591
        else {
 
592
                mdfld_dsi_dpi_set_power(encoder, false);
 
593
#if 0 /* FIXME */
 
594
#ifdef CONFIG_PM_RUNTIME
 
595
                if (enable_gfx_rtpm)
 
596
                        pm_schedule_suspend(&gpDrmDevice->pdev->dev, gfxrtdelay);
 
597
#endif
 
598
#endif
 
599
        }
 
600
}
 
601
 
 
602
bool mdfld_dsi_dpi_mode_fixup(struct drm_encoder *encoder,
 
603
                                     struct drm_display_mode *mode,
 
604
                                     struct drm_display_mode *adjusted_mode)
 
605
{
 
606
        struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
 
607
        struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
 
608
        struct drm_display_mode *fixed_mode = dsi_config->fixed_mode;
 
609
 
 
610
        if(fixed_mode) {
 
611
                adjusted_mode->hdisplay = fixed_mode->hdisplay;
 
612
                adjusted_mode->hsync_start = fixed_mode->hsync_start;
 
613
                adjusted_mode->hsync_end = fixed_mode->hsync_end;
 
614
                adjusted_mode->htotal = fixed_mode->htotal;
 
615
                adjusted_mode->vdisplay = fixed_mode->vdisplay;
 
616
                adjusted_mode->vsync_start = fixed_mode->vsync_start;
 
617
                adjusted_mode->vsync_end = fixed_mode->vsync_end;
 
618
                adjusted_mode->vtotal = fixed_mode->vtotal;
 
619
                adjusted_mode->clock = fixed_mode->clock;
 
620
                drm_mode_set_crtcinfo(adjusted_mode, CRTC_INTERLACE_HALVE_V);
 
621
        }
 
622
        
 
623
        return true;
 
624
}
 
625
 
 
626
void mdfld_dsi_dpi_prepare(struct drm_encoder *encoder) 
 
627
{
 
628
        mdfld_dsi_dpi_set_power(encoder, false);
 
629
}
 
630
 
 
631
void mdfld_dsi_dpi_commit(struct drm_encoder *encoder) 
 
632
{
 
633
        mdfld_dsi_dpi_set_power(encoder, true);
 
634
}
 
635
 
 
636
void mdfld_dsi_dpi_mode_set(struct drm_encoder *encoder,
 
637
                                   struct drm_display_mode *mode,
 
638
                                   struct drm_display_mode *adjusted_mode)
 
639
{
 
640
        struct mdfld_dsi_encoder *dsi_encoder = MDFLD_DSI_ENCODER(encoder);
 
641
        struct mdfld_dsi_dpi_output *dpi_output = MDFLD_DSI_DPI_OUTPUT(dsi_encoder);
 
642
        struct mdfld_dsi_config *dsi_config = mdfld_dsi_encoder_get_config(dsi_encoder);
 
643
        struct drm_device *dev = dsi_config->dev;
 
644
        struct drm_psb_private *dev_priv = dev->dev_private;
 
645
        int pipe = mdfld_dsi_encoder_get_pipe(dsi_encoder);
 
646
        
 
647
        u32 pipeconf_reg = PIPEACONF;
 
648
        u32 dspcntr_reg = DSPACNTR;
 
649
        u32 mipi_reg = MIPI;
 
650
        u32 reg_offset = 0;
 
651
        
 
652
        u32 pipeconf = dev_priv->pipeconf;
 
653
        u32 dspcntr = dev_priv->dspcntr;
 
654
        u32 mipi = MIPI_PORT_EN | PASS_FROM_SPHY_TO_AFE | SEL_FLOPPED_HSTX;
 
655
        
 
656
        dev_dbg(dev->dev, "set mode %dx%d on pipe %d\n",
 
657
                                mode->hdisplay, mode->vdisplay, pipe);
 
658
 
 
659
        if(pipe) {
 
660
                pipeconf_reg = PIPECCONF;
 
661
                dspcntr_reg = DSPCCNTR;
 
662
                mipi_reg = MIPI_C;
 
663
                reg_offset = MIPIC_REG_OFFSET;
 
664
        } else {
 
665
                mipi |= 2;
 
666
        }
 
667
        
 
668
        if (!gma_power_begin(dev, true))
 
669
                return;
 
670
 
 
671
        /* Set up mipi port FIXME: do at init time */
 
672
        REG_WRITE(mipi_reg, mipi);
 
673
        REG_READ(mipi_reg);
 
674
 
 
675
        /* Set up DSI controller DPI interface */
 
676
        mdfld_dsi_dpi_controller_init(dsi_config, pipe);
 
677
 
 
678
        if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
 
679
                /* Turn on DPI interface */
 
680
                mdfld_dsi_dpi_turn_on(dpi_output, pipe);
 
681
        }
 
682
        
 
683
        /* Set up pipe */
 
684
        REG_WRITE(pipeconf_reg, pipeconf);
 
685
        REG_READ(pipeconf_reg);
 
686
        
 
687
        /* Set up display plane */
 
688
        REG_WRITE(dspcntr_reg, dspcntr);
 
689
        REG_READ(dspcntr_reg);
 
690
        
 
691
        msleep(20); /* FIXME: this should wait for vblank */
 
692
        
 
693
        dev_dbg(dev->dev, "State %x, power %d\n",
 
694
                REG_READ(MIPIA_INTR_STAT_REG + reg_offset),
 
695
                dpi_output->panel_on);
 
696
 
 
697
        if (mdfld_get_panel_type(dev, pipe) != TMD_VID) {
 
698
                /* Init driver ic */
 
699
                mdfld_dsi_tpo_ic_init(dsi_config, pipe);
 
700
                /* Init backlight */
 
701
                mdfld_dsi_brightness_init(dsi_config, pipe);
 
702
        }
 
703
        gma_power_end(dev);
 
704
}
 
705
 
 
706
 
 
707
/*
 
708
 * Init DSI DPI encoder. 
 
709
 * Allocate an mdfld_dsi_encoder and attach it to given @dsi_connector
 
710
 * return pointer of newly allocated DPI encoder, NULL on error
 
711
 */ 
 
712
struct mdfld_dsi_encoder *mdfld_dsi_dpi_init(struct drm_device *dev, 
 
713
                                struct mdfld_dsi_connector *dsi_connector,
 
714
                                struct panel_funcs *p_funcs)
 
715
{
 
716
        struct mdfld_dsi_dpi_output *dpi_output = NULL;
 
717
        struct mdfld_dsi_config *dsi_config;
 
718
        struct drm_connector *connector = NULL;
 
719
        struct drm_encoder *encoder = NULL;
 
720
        struct drm_display_mode *fixed_mode = NULL;
 
721
        int pipe;
 
722
        u32 data;
 
723
        int ret;
 
724
 
 
725
        if (!dsi_connector || !p_funcs) {
 
726
                WARN_ON(1);
 
727
                return NULL;
 
728
        }
 
729
 
 
730
        dsi_config = mdfld_dsi_get_config(dsi_connector);
 
731
        pipe = dsi_connector->pipe;
 
732
 
 
733
        /* Panel hard-reset */
 
734
        if (p_funcs->reset) {
 
735
                ret = p_funcs->reset(pipe);
 
736
                if (ret) {
 
737
                        DRM_ERROR("Panel %d hard-reset failed\n", pipe);
 
738
                        return NULL;
 
739
                }
 
740
        }
 
741
 
 
742
        /* Panel drvIC init */
 
743
        if (p_funcs->drv_ic_init)
 
744
                p_funcs->drv_ic_init(dsi_config, pipe);
 
745
 
 
746
        /* Panel power mode detect */
 
747
        ret = mdfld_dsi_get_power_mode(dsi_config,
 
748
                                        &data,
 
749
                                        MDFLD_DSI_LP_TRANSMISSION);
 
750
        if (ret) {
 
751
                DRM_ERROR("Panel %d get power mode failed\n", pipe);
 
752
                dsi_connector->status = connector_status_disconnected;
 
753
        } else {
 
754
                DRM_INFO("pipe %d power mode 0x%x\n", pipe, data);
 
755
                dsi_connector->status = connector_status_connected;
 
756
        }
 
757
 
 
758
        dpi_output = kzalloc(sizeof(struct mdfld_dsi_dpi_output), GFP_KERNEL);
 
759
        if(!dpi_output) {
 
760
                dev_err(dev->dev, "No memory for dsi_dpi_output\n");
 
761
                return NULL;
 
762
        }
 
763
 
 
764
        if(dsi_connector->pipe) 
 
765
                dpi_output->panel_on = 0;
 
766
        else
 
767
                dpi_output->panel_on = 0;
 
768
        
 
769
        dpi_output->dev = dev;
 
770
        dpi_output->p_funcs = p_funcs;
 
771
        dpi_output->first_boot = 1;
 
772
        
 
773
        /* Get fixed mode */
 
774
        dsi_config = mdfld_dsi_get_config(dsi_connector);
 
775
        fixed_mode = dsi_config->fixed_mode;
 
776
        
 
777
        /* Create drm encoder object */
 
778
        connector = &dsi_connector->base.base;
 
779
        encoder = &dpi_output->base.base;
 
780
        /*
 
781
         * On existing hardware this will be a panel of some form,
 
782
         * if future devices also have HDMI bridges this will need
 
783
         * revisiting
 
784
         */
 
785
        drm_encoder_init(dev,
 
786
                        encoder,
 
787
                        p_funcs->encoder_funcs,
 
788
                        DRM_MODE_ENCODER_LVDS);
 
789
        drm_encoder_helper_add(encoder,
 
790
                                p_funcs->encoder_helper_funcs);
 
791
        
 
792
        /* Attach to given connector */
 
793
        drm_mode_connector_attach_encoder(connector, encoder);
 
794
        
 
795
        /* Set possible crtcs and clones */
 
796
        if(dsi_connector->pipe) {
 
797
                encoder->possible_crtcs = (1 << 2);
 
798
                encoder->possible_clones = (1 << 1);
 
799
        } else {
 
800
                encoder->possible_crtcs = (1 << 0);
 
801
                encoder->possible_clones = (1 << 0);
 
802
        }
 
803
        return &dpi_output->base;
 
804
}
 
805