ti-ocf-crypto-module: add crypto module for hw accel
[openembedded.git] / recipes / linux / linux-omap / DSS2.diff
blob17617548ca19d4171cc4e784d66787a070162423
1 arch/arm/plat-omap/include/mach/omapfb.h | 398 -
2 b/Documentation/arm/OMAP/DSS | 311 +
3 b/arch/arm/configs/dss_omap3_beagle_defconfig | 1369 ++++
4 b/arch/arm/configs/dss_overo_defconfig | 1826 +++++
5 b/arch/arm/mach-omap1/board-nokia770.c | 2
6 b/arch/arm/mach-omap2/board-3430sdp.c | 218
7 b/arch/arm/mach-omap2/board-n800.c | 217
8 b/arch/arm/mach-omap2/board-omap3beagle.c | 91
9 b/arch/arm/mach-omap2/board-omap3evm.c | 203
10 b/arch/arm/mach-omap2/board-overo.c | 98
11 b/arch/arm/mach-omap2/io.c | 2
12 b/arch/arm/plat-omap/Makefile | 2
13 b/arch/arm/plat-omap/fb.c | 30
14 b/arch/arm/plat-omap/include/mach/display.h | 520 +
15 b/arch/arm/plat-omap/include/mach/vram.h | 33
16 b/arch/arm/plat-omap/include/mach/vrfb.h | 47
17 b/arch/arm/plat-omap/vram.c | 615 +
18 b/arch/arm/plat-omap/vrfb.c | 159
19 b/drivers/video/Kconfig | 1
20 b/drivers/video/Makefile | 1
21 b/drivers/video/omap/Kconfig | 5
22 b/drivers/video/omap/blizzard.c | 2
23 b/drivers/video/omap/dispc.c | 2
24 b/drivers/video/omap/hwa742.c | 2
25 b/drivers/video/omap/lcd_2430sdp.c | 2
26 b/drivers/video/omap/lcd_ams_delta.c | 2
27 b/drivers/video/omap/lcd_apollon.c | 2
28 b/drivers/video/omap/lcd_h3.c | 2
29 b/drivers/video/omap/lcd_h4.c | 3
30 b/drivers/video/omap/lcd_inn1510.c | 2
31 b/drivers/video/omap/lcd_inn1610.c | 2
32 b/drivers/video/omap/lcd_ldp.c | 2
33 b/drivers/video/omap/lcd_mipid.c | 2
34 b/drivers/video/omap/lcd_omap2evm.c | 2
35 b/drivers/video/omap/lcd_omap3beagle.c | 2
36 b/drivers/video/omap/lcd_omap3evm.c | 2
37 b/drivers/video/omap/lcd_osk.c | 2
38 b/drivers/video/omap/lcd_overo.c | 2
39 b/drivers/video/omap/lcd_p2.c | 2
40 b/drivers/video/omap/lcd_palmte.c | 2
41 b/drivers/video/omap/lcd_palmtt.c | 2
42 b/drivers/video/omap/lcd_palmz71.c | 3
43 b/drivers/video/omap/lcdc.c | 2
44 b/drivers/video/omap/omapfb_main.c | 2
45 b/drivers/video/omap/rfbi.c | 3
46 b/drivers/video/omap/sossi.c | 2
47 b/drivers/video/omap2/Kconfig | 3
48 b/drivers/video/omap2/Makefile | 4
49 b/drivers/video/omap2/displays/Kconfig | 32
50 b/drivers/video/omap2/displays/Makefile | 6
51 b/drivers/video/omap2/displays/ctrl-blizzard.c | 279
52 b/drivers/video/omap2/displays/panel-generic.c | 96
53 b/drivers/video/omap2/displays/panel-n800.c | 435 +
54 b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c | 108
55 b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c | 112
56 b/drivers/video/omap2/dss/Kconfig | 89
57 b/drivers/video/omap2/dss/Makefile | 6
58 b/drivers/video/omap2/dss/core.c | 641 ++
59 b/drivers/video/omap2/dss/dispc.c | 2781 +++++++++
60 b/drivers/video/omap2/dss/display.c | 687 ++
61 b/drivers/video/omap2/dss/dpi.c | 379 +
62 b/drivers/video/omap2/dss/dsi.c | 3693 ++++++++++++
63 b/drivers/video/omap2/dss/dss.c | 345 +
64 b/drivers/video/omap2/dss/dss.h | 326 +
65 b/drivers/video/omap2/dss/manager.c | 463 +
66 b/drivers/video/omap2/dss/overlay.c | 587 +
67 b/drivers/video/omap2/dss/rfbi.c | 1304 ++++
68 b/drivers/video/omap2/dss/sdi.c | 245
69 b/drivers/video/omap2/dss/venc.c | 600 +
70 b/drivers/video/omap2/omapfb/Kconfig | 35
71 b/drivers/video/omap2/omapfb/Makefile | 2
72 b/drivers/video/omap2/omapfb/omapfb-ioctl.c | 656 ++
73 b/drivers/video/omap2/omapfb/omapfb-main.c | 1944 ++++++
74 b/drivers/video/omap2/omapfb/omapfb-sysfs.c | 371 +
75 b/drivers/video/omap2/omapfb/omapfb.h | 143
76 b/include/linux/omapfb.h | 418 +
77 76 files changed, 22501 insertions(+), 490 deletions(-)
78 diff --git a/Documentation/arm/OMAP/DSS b/Documentation/arm/OMAP/DSS
79 new file mode 100644
80 index 0000000..9e902a2
81 --- /dev/null
82 +++ b/Documentation/arm/OMAP/DSS
83 @@ -0,0 +1,311 @@
84 +OMAP2/3 Display Subsystem
85 +-------------------------
87 +This is an almost total rewrite of the OMAP FB driver in drivers/video/omap
88 +(let's call it DSS1). The main differences between DSS1 and DSS2 are DSI,
89 +TV-out and multiple display support, but there are lots of small improvements
90 +also.
92 +The DSS2 driver (omapdss module) is in arch/arm/plat-omap/dss/, and the FB,
93 +panel and controller drivers are in drivers/video/omap2/. DSS1 and DSS2 live
94 +currently side by side, you can choose which one to use.
96 +Features
97 +--------
99 +Working and tested features include:
101 +- MIPI DPI (parallel) output
102 +- MIPI DSI output in command mode
103 +- MIPI DBI (RFBI) output
104 +- SDI output
105 +- TV output
106 +- All pieces can be compiled as a module or inside kernel
107 +- Use DISPC to update any of the outputs
108 +- Use CPU to update RFBI or DSI output
109 +- OMAP DISPC planes
110 +- RGB16, RGB24 packed, RGB24 unpacked
111 +- YUV2, UYVY
112 +- Scaling
113 +- Adjusting DSS FCK to find a good pixel clock
114 +- Use DSI DPLL to create DSS FCK
116 +Tested boards include:
117 +- OMAP3 SDP board
118 +- Beagle board
119 +- N810
121 +omapdss driver
122 +--------------
124 +The DSS driver does not itself have any support for Linux framebuffer, V4L or
125 +such like the current ones, but it has an internal kernel API that upper level
126 +drivers can use.
128 +The DSS driver models OMAP's overlays, overlay managers and displays in a
129 +flexible way to enable non-common multi-display configuration. In addition to
130 +modelling the hardware overlays, omapdss supports virtual overlays and overlay
131 +managers. These can be used when updating a display with CPU or system DMA.
133 +Panel and controller drivers
134 +----------------------------
136 +The drivers implement panel or controller specific functionality and are not
137 +usually visible to users except through omapfb driver. They register
138 +themselves to the DSS driver.
140 +omapfb driver
141 +-------------
143 +The omapfb driver implements arbitrary number of standard linux framebuffers.
144 +These framebuffers can be routed flexibly to any overlays, thus allowing very
145 +dynamic display architecture.
147 +The driver exports some omapfb specific ioctls, which are compatible with the
148 +ioctls in the old driver.
150 +The rest of the non standard features are exported via sysfs. Whether the final
151 +implementation will use sysfs, or ioctls, is still open.
153 +V4L2 drivers
154 +------------
156 +V4L2 is being implemented in TI.
158 +From omapdss point of view the V4L2 drivers should be similar to framebuffer
159 +driver.
161 +Architecture
162 +--------------------
164 +Some clarification what the different components do:
166 + - Framebuffer is a memory area inside OMAP's SRAM/SDRAM that contains the
167 + pixel data for the image. Framebuffer has width and height and color
168 + depth.
169 + - Overlay defines where the pixels are read from and where they go on the
170 + screen. The overlay may be smaller than framebuffer, thus displaying only
171 + part of the framebuffer. The position of the overlay may be changed if
172 + the overlay is smaller than the display.
173 + - Overlay manager combines the overlays in to one image and feeds them to
174 + display.
175 + - Display is the actual physical display device.
177 +A framebuffer can be connected to multiple overlays to show the same pixel data
178 +on all of the overlays. Note that in this case the overlay input sizes must be
179 +the same, but, in case of video overlays, the output size can be different. Any
180 +framebuffer can be connected to any overlay.
182 +An overlay can be connected to one overlay manager. Also DISPC overlays can be
183 +connected only to DISPC overlay managers, and virtual overlays can be only
184 +connected to virtual overlays.
186 +An overlay manager can be connected to one display. There are certain
187 +restrictions which kinds of displays an overlay manager can be connected:
189 + - DISPC TV overlay manager can be only connected to TV display.
190 + - Virtual overlay managers can only be connected to DBI or DSI displays.
191 + - DISPC LCD overlay manager can be connected to all displays, except TV
192 + display.
194 +Sysfs
195 +-----
196 +The sysfs interface is mainly used for testing. I don't think sysfs
197 +interface is the best for this in the final version, but I don't quite know
198 +what would be the best interfaces for these things.
200 +The sysfs interface is divided to two parts: DSS and FB.
202 +/sys/class/graphics/fb? directory:
203 +mirror 0=off, 1=on
204 +rotate Rotation 0-3 for 0, 90, 180, 270 degrees
205 +rotate_type 0 = DMA rotation, 1 = VRFB rotation
206 +overlays List of overlay numbers to which framebuffer pixels go
207 +phys_addr Physical address of the framebuffer
208 +virt_addr Virtual address of the framebuffer
209 +size Size of the framebuffer
211 +/sys/devices/platform/omapdss/overlay? directory:
212 +enabled 0=off, 1=on
213 +input_size width,height (ie. the framebuffer size)
214 +manager Destination overlay manager name
215 +name
216 +output_size width,height
217 +position x,y
218 +screen_width width
220 +/sys/devices/platform/omapdss/manager? directory:
221 +display Destination display
222 +name
224 +/sys/devices/platform/omapdss/display? directory:
225 +ctrl_name Controller name
226 +mirror 0=off, 1=on
227 +update_mode 0=off, 1=auto, 2=manual
228 +enabled 0=off, 1=on
229 +name
230 +rotate Rotation 0-3 for 0, 90, 180, 270 degrees
231 +timings Display timings (pixclock,xres/hfp/hbp/hsw,yres/vfp/vbp/vsw)
232 + When writing, two special timings are accepted for tv-out:
233 + "pal" and "ntsc"
234 +panel_name
235 +tear_elim Tearing elimination 0=off, 1=on
237 +There are also some debugfs files at <debugfs>/omapdss/ which show information
238 +about clocks and registers.
240 +Examples
241 +--------
243 +The following definitions have been made for the examples below:
245 +ovl0=/sys/devices/platform/omapdss/overlay0
246 +ovl1=/sys/devices/platform/omapdss/overlay1
247 +ovl2=/sys/devices/platform/omapdss/overlay2
249 +mgr0=/sys/devices/platform/omapdss/manager0
250 +mgr1=/sys/devices/platform/omapdss/manager1
252 +lcd=/sys/devices/platform/omapdss/display0
253 +dvi=/sys/devices/platform/omapdss/display1
254 +tv=/sys/devices/platform/omapdss/display2
256 +fb0=/sys/class/graphics/fb0
257 +fb1=/sys/class/graphics/fb1
258 +fb2=/sys/class/graphics/fb2
260 +Default setup on OMAP3 SDP
261 +--------------------------
263 +Here's the default setup on OMAP3 SDP board. All planes go to LCD. DVI
264 +and TV-out are not in use. The columns from left to right are:
265 +framebuffers, overlays, overlay managers, displays. Framebuffers are
266 +handled by omapfb, and the rest by the DSS.
268 +FB0 --- GFX -\ DVI
269 +FB1 --- VID1 --+- LCD ---- LCD
270 +FB2 --- VID2 -/ TV ----- TV
272 +Example: Switch from LCD to DVI
273 +----------------------
275 +w=`cat $dvi/horizontal | cut -d "," -f 1`
276 +h=`cat $dvi/vertical | cut -d "," -f 1`
278 +echo "0" > $lcd/enabled
279 +echo "" > $mgr0/display
280 +fbset -fb /dev/fb0 -xres $w -yres $h -vxres $w -vyres $h
281 +# at this point you have to switch the dvi/lcd dip-switch from the omap board
282 +echo "dvi" > $mgr0/display
283 +echo "1" > $dvi/enabled
285 +After this the configuration looks like:
287 +FB0 --- GFX -\ -- DVI
288 +FB1 --- VID1 --+- LCD -/ LCD
289 +FB2 --- VID2 -/ TV ----- TV
291 +Example: Clone GFX overlay to LCD and TV
292 +-------------------------------
294 +w=`cat $tv/horizontal | cut -d "," -f 1`
295 +h=`cat $tv/vertical | cut -d "," -f 1`
297 +echo "0" > $ovl0/enabled
298 +echo "0" > $ovl1/enabled
300 +echo "" > $fb1/overlays
301 +echo "0,1" > $fb0/overlays
303 +echo "$w,$h" > $ovl1/output_size
304 +echo "tv" > $ovl1/manager
306 +echo "1" > $ovl0/enabled
307 +echo "1" > $ovl1/enabled
309 +echo "1" > $tv/enabled
311 +After this the configuration looks like (only relevant parts shown):
313 +FB0 +-- GFX ---- LCD ---- LCD
314 + \- VID1 ---- TV ---- TV
316 +Misc notes
317 +----------
319 +OMAP FB allocates the framebuffer memory using the OMAP VRAM allocator.
321 +Using DSI DPLL to generate pixel clock it is possible produce the pixel clock
322 +of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI.
324 +Rotation and mirroring currently only supports RGB565 and RGB8888 modes. VRFB
325 +does not support mirroring.
327 +VRFB rotation requires much more memory than non-rotated framebuffer, so you
328 +probably need to increase your vram setting before using VRFB rotation. Also,
329 +many applications may not work with VRFB if they do not pay attention to all
330 +framebuffer parameters.
332 +Kernel boot arguments
333 +---------------------
335 +vram=<size>
336 + - Amount of total VRAM to preallocate. For example, "10M". omapfb
337 + allocates memory for framebuffers from VRAM.
339 +omapfb.mode=<display>:<mode>[,...]
340 + - Default video mode for specified displays. For example,
341 + "dvi:800x400MR-24@60". See drivers/video/modedb.c.
342 + There are also two special modes: "pal" and "ntsc" that
343 + can be used to tv out.
345 +omapfb.vram=<fbnum>:<size>[@<physaddr>][,...]
346 + - VRAM allocated for a framebuffer. Normally omapfb allocates vram
347 + depending on the display size. With this you can manually allocate
348 + more or define the physical address of each framebuffer. For example,
349 + "1:4M" to allocate 4M for fb1.
351 +omapfb.debug=<y|n>
352 + - Enable debug printing. You have to have OMAPFB debug support enabled
353 + in kernel config.
355 +omapfb.test=<y|n>
356 + - Draw test pattern to framebuffer whenever framebuffer settings change.
357 + You need to have OMAPFB debug support enabled in kernel config.
359 +omapfb.vrfb=<y|n>
360 + - Use VRFB rotation for all framebuffers.
362 +omapfb.rotate=<angle>
363 + - Default rotation applied to all framebuffers.
364 + 0 - 0 degree rotation
365 + 1 - 90 degree rotation
366 + 2 - 180 degree rotation
367 + 3 - 270 degree rotation
369 +omapfb.mirror=<y|n>
370 + - Default mirror for all framebuffers. Only works with DMA rotation.
372 +omapdss.def_disp=<display>
373 + - Name of default display, to which all overlays will be connected.
374 + Common examples are "lcd" or "tv".
376 +omapdss.debug=<y|n>
377 + - Enable debug printing. You have to have DSS debug support enabled in
378 + kernel config.
380 +TODO
381 +----
383 +DSS locking
385 +Error checking
386 +- Lots of checks are missing or implemented just as BUG()
388 +System DMA update for DSI
389 +- Can be used for RGB16 and RGB24P modes. Probably not for RGB24U (how
390 + to skip the empty byte?)
392 +OMAP1 support
393 +- Not sure if needed
395 diff --git a/arch/arm/configs/dss_omap3_beagle_defconfig b/arch/arm/configs/dss_omap3_beagle_defconfig
396 new file mode 100644
397 index 0000000..8a428db
398 --- /dev/null
399 +++ b/arch/arm/configs/dss_omap3_beagle_defconfig
400 @@ -0,0 +1,1369 @@
402 +# Automatically generated make config: don't edit
403 +# Linux kernel version: 2.6.29-rc3-omap1
404 +# Mon Feb 2 12:09:46 2009
406 +CONFIG_ARM=y
407 +CONFIG_SYS_SUPPORTS_APM_EMULATION=y
408 +CONFIG_GENERIC_GPIO=y
409 +CONFIG_GENERIC_TIME=y
410 +CONFIG_GENERIC_CLOCKEVENTS=y
411 +CONFIG_MMU=y
412 +# CONFIG_NO_IOPORT is not set
413 +CONFIG_GENERIC_HARDIRQS=y
414 +CONFIG_STACKTRACE_SUPPORT=y
415 +CONFIG_HAVE_LATENCYTOP_SUPPORT=y
416 +CONFIG_LOCKDEP_SUPPORT=y
417 +CONFIG_TRACE_IRQFLAGS_SUPPORT=y
418 +CONFIG_HARDIRQS_SW_RESEND=y
419 +CONFIG_GENERIC_IRQ_PROBE=y
420 +CONFIG_RWSEM_GENERIC_SPINLOCK=y
421 +# CONFIG_ARCH_HAS_ILOG2_U32 is not set
422 +# CONFIG_ARCH_HAS_ILOG2_U64 is not set
423 +CONFIG_GENERIC_HWEIGHT=y
424 +CONFIG_GENERIC_CALIBRATE_DELAY=y
425 +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
426 +CONFIG_VECTORS_BASE=0xffff0000
427 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
430 +# General setup
432 +CONFIG_EXPERIMENTAL=y
433 +CONFIG_BROKEN_ON_SMP=y
434 +CONFIG_INIT_ENV_ARG_LIMIT=32
435 +CONFIG_LOCALVERSION=""
436 +# CONFIG_LOCALVERSION_AUTO is not set
437 +CONFIG_SWAP=y
438 +CONFIG_SYSVIPC=y
439 +CONFIG_SYSVIPC_SYSCTL=y
440 +# CONFIG_POSIX_MQUEUE is not set
441 +CONFIG_BSD_PROCESS_ACCT=y
442 +# CONFIG_BSD_PROCESS_ACCT_V3 is not set
443 +# CONFIG_TASKSTATS is not set
444 +# CONFIG_AUDIT is not set
447 +# RCU Subsystem
449 +CONFIG_CLASSIC_RCU=y
450 +# CONFIG_TREE_RCU is not set
451 +# CONFIG_PREEMPT_RCU is not set
452 +# CONFIG_TREE_RCU_TRACE is not set
453 +# CONFIG_PREEMPT_RCU_TRACE is not set
454 +# CONFIG_IKCONFIG is not set
455 +CONFIG_LOG_BUF_SHIFT=14
456 +CONFIG_GROUP_SCHED=y
457 +CONFIG_FAIR_GROUP_SCHED=y
458 +# CONFIG_RT_GROUP_SCHED is not set
459 +CONFIG_USER_SCHED=y
460 +# CONFIG_CGROUP_SCHED is not set
461 +# CONFIG_CGROUPS is not set
462 +CONFIG_SYSFS_DEPRECATED=y
463 +CONFIG_SYSFS_DEPRECATED_V2=y
464 +# CONFIG_RELAY is not set
465 +# CONFIG_NAMESPACES is not set
466 +CONFIG_BLK_DEV_INITRD=y
467 +CONFIG_INITRAMFS_SOURCE=""
468 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
469 +CONFIG_SYSCTL=y
470 +CONFIG_EMBEDDED=y
471 +CONFIG_UID16=y
472 +# CONFIG_SYSCTL_SYSCALL is not set
473 +CONFIG_KALLSYMS=y
474 +# CONFIG_KALLSYMS_ALL is not set
475 +CONFIG_KALLSYMS_EXTRA_PASS=y
476 +CONFIG_HOTPLUG=y
477 +CONFIG_PRINTK=y
478 +CONFIG_BUG=y
479 +CONFIG_ELF_CORE=y
480 +CONFIG_COMPAT_BRK=y
481 +CONFIG_BASE_FULL=y
482 +CONFIG_FUTEX=y
483 +CONFIG_ANON_INODES=y
484 +CONFIG_EPOLL=y
485 +CONFIG_SIGNALFD=y
486 +CONFIG_TIMERFD=y
487 +CONFIG_EVENTFD=y
488 +CONFIG_SHMEM=y
489 +CONFIG_AIO=y
490 +CONFIG_VM_EVENT_COUNTERS=y
491 +CONFIG_SLAB=y
492 +# CONFIG_SLUB is not set
493 +# CONFIG_SLOB is not set
494 +# CONFIG_PROFILING is not set
495 +CONFIG_HAVE_OPROFILE=y
496 +# CONFIG_KPROBES is not set
497 +CONFIG_HAVE_KPROBES=y
498 +CONFIG_HAVE_KRETPROBES=y
499 +CONFIG_HAVE_CLK=y
500 +CONFIG_HAVE_GENERIC_DMA_COHERENT=y
501 +CONFIG_SLABINFO=y
502 +CONFIG_RT_MUTEXES=y
503 +CONFIG_BASE_SMALL=0
504 +CONFIG_MODULES=y
505 +# CONFIG_MODULE_FORCE_LOAD is not set
506 +CONFIG_MODULE_UNLOAD=y
507 +# CONFIG_MODULE_FORCE_UNLOAD is not set
508 +CONFIG_MODVERSIONS=y
509 +CONFIG_MODULE_SRCVERSION_ALL=y
510 +CONFIG_BLOCK=y
511 +# CONFIG_LBD is not set
512 +# CONFIG_BLK_DEV_IO_TRACE is not set
513 +# CONFIG_BLK_DEV_BSG is not set
514 +# CONFIG_BLK_DEV_INTEGRITY is not set
517 +# IO Schedulers
519 +CONFIG_IOSCHED_NOOP=y
520 +CONFIG_IOSCHED_AS=y
521 +CONFIG_IOSCHED_DEADLINE=y
522 +CONFIG_IOSCHED_CFQ=y
523 +CONFIG_DEFAULT_AS=y
524 +# CONFIG_DEFAULT_DEADLINE is not set
525 +# CONFIG_DEFAULT_CFQ is not set
526 +# CONFIG_DEFAULT_NOOP is not set
527 +CONFIG_DEFAULT_IOSCHED="anticipatory"
528 +# CONFIG_FREEZER is not set
531 +# System Type
533 +# CONFIG_ARCH_AAEC2000 is not set
534 +# CONFIG_ARCH_INTEGRATOR is not set
535 +# CONFIG_ARCH_REALVIEW is not set
536 +# CONFIG_ARCH_VERSATILE is not set
537 +# CONFIG_ARCH_AT91 is not set
538 +# CONFIG_ARCH_CLPS711X is not set
539 +# CONFIG_ARCH_EBSA110 is not set
540 +# CONFIG_ARCH_EP93XX is not set
541 +# CONFIG_ARCH_FOOTBRIDGE is not set
542 +# CONFIG_ARCH_NETX is not set
543 +# CONFIG_ARCH_H720X is not set
544 +# CONFIG_ARCH_IMX is not set
545 +# CONFIG_ARCH_IOP13XX is not set
546 +# CONFIG_ARCH_IOP32X is not set
547 +# CONFIG_ARCH_IOP33X is not set
548 +# CONFIG_ARCH_IXP23XX is not set
549 +# CONFIG_ARCH_IXP2000 is not set
550 +# CONFIG_ARCH_IXP4XX is not set
551 +# CONFIG_ARCH_L7200 is not set
552 +# CONFIG_ARCH_KIRKWOOD is not set
553 +# CONFIG_ARCH_KS8695 is not set
554 +# CONFIG_ARCH_NS9XXX is not set
555 +# CONFIG_ARCH_LOKI is not set
556 +# CONFIG_ARCH_MV78XX0 is not set
557 +# CONFIG_ARCH_MXC is not set
558 +# CONFIG_ARCH_ORION5X is not set
559 +# CONFIG_ARCH_PNX4008 is not set
560 +# CONFIG_ARCH_PXA is not set
561 +# CONFIG_ARCH_RPC is not set
562 +# CONFIG_ARCH_SA1100 is not set
563 +# CONFIG_ARCH_S3C2410 is not set
564 +# CONFIG_ARCH_S3C64XX is not set
565 +# CONFIG_ARCH_SHARK is not set
566 +# CONFIG_ARCH_LH7A40X is not set
567 +# CONFIG_ARCH_DAVINCI is not set
568 +CONFIG_ARCH_OMAP=y
569 +# CONFIG_ARCH_MSM is not set
570 +# CONFIG_ARCH_W90X900 is not set
573 +# TI OMAP Implementations
575 +CONFIG_ARCH_OMAP_OTG=y
576 +# CONFIG_ARCH_OMAP1 is not set
577 +# CONFIG_ARCH_OMAP2 is not set
578 +CONFIG_ARCH_OMAP3=y
581 +# OMAP Feature Selections
583 +# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
584 +# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
585 +# CONFIG_OMAP_SMARTREFLEX is not set
586 +# CONFIG_OMAP_RESET_CLOCKS is not set
587 +CONFIG_OMAP_BOOT_TAG=y
588 +CONFIG_OMAP_BOOT_REASON=y
589 +# CONFIG_OMAP_COMPONENT_VERSION is not set
590 +# CONFIG_OMAP_GPIO_SWITCH is not set
591 +# CONFIG_OMAP_MUX is not set
592 +# CONFIG_OMAP_MCBSP is not set
593 +# CONFIG_OMAP_MBOX_FWK is not set
594 +# CONFIG_OMAP_MPU_TIMER is not set
595 +CONFIG_OMAP_32K_TIMER=y
596 +CONFIG_OMAP_32K_TIMER_HZ=128
597 +CONFIG_OMAP_TICK_GPTIMER=12
598 +CONFIG_OMAP_DM_TIMER=y
599 +# CONFIG_OMAP_LL_DEBUG_UART1 is not set
600 +# CONFIG_OMAP_LL_DEBUG_UART2 is not set
601 +CONFIG_OMAP_LL_DEBUG_UART3=y
602 +CONFIG_ARCH_OMAP34XX=y
603 +CONFIG_ARCH_OMAP3430=y
606 +# OMAP Board Type
608 +# CONFIG_MACH_NOKIA_RX51 is not set
609 +# CONFIG_MACH_OMAP_LDP is not set
610 +# CONFIG_MACH_OMAP_3430SDP is not set
611 +# CONFIG_MACH_OMAP3EVM is not set
612 +CONFIG_MACH_OMAP3_BEAGLE=y
613 +# CONFIG_MACH_OVERO is not set
614 +# CONFIG_MACH_OMAP3_PANDORA is not set
617 +# Processor Type
619 +CONFIG_CPU_32=y
620 +CONFIG_CPU_32v6K=y
621 +CONFIG_CPU_V7=y
622 +CONFIG_CPU_32v7=y
623 +CONFIG_CPU_ABRT_EV7=y
624 +CONFIG_CPU_PABRT_IFAR=y
625 +CONFIG_CPU_CACHE_V7=y
626 +CONFIG_CPU_CACHE_VIPT=y
627 +CONFIG_CPU_COPY_V6=y
628 +CONFIG_CPU_TLB_V7=y
629 +CONFIG_CPU_HAS_ASID=y
630 +CONFIG_CPU_CP15=y
631 +CONFIG_CPU_CP15_MMU=y
634 +# Processor Features
636 +CONFIG_ARM_THUMB=y
637 +# CONFIG_ARM_THUMBEE is not set
638 +# CONFIG_CPU_ICACHE_DISABLE is not set
639 +# CONFIG_CPU_DCACHE_DISABLE is not set
640 +# CONFIG_CPU_BPREDICT_DISABLE is not set
641 +CONFIG_HAS_TLS_REG=y
642 +# CONFIG_OUTER_CACHE is not set
645 +# Bus support
647 +# CONFIG_PCI_SYSCALL is not set
648 +# CONFIG_ARCH_SUPPORTS_MSI is not set
649 +# CONFIG_PCCARD is not set
652 +# Kernel Features
654 +CONFIG_TICK_ONESHOT=y
655 +CONFIG_NO_HZ=y
656 +CONFIG_HIGH_RES_TIMERS=y
657 +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
658 +CONFIG_VMSPLIT_3G=y
659 +# CONFIG_VMSPLIT_2G is not set
660 +# CONFIG_VMSPLIT_1G is not set
661 +CONFIG_PAGE_OFFSET=0xC0000000
662 +# CONFIG_PREEMPT is not set
663 +CONFIG_HZ=128
664 +CONFIG_AEABI=y
665 +CONFIG_OABI_COMPAT=y
666 +CONFIG_ARCH_FLATMEM_HAS_HOLES=y
667 +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
668 +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
669 +CONFIG_SELECT_MEMORY_MODEL=y
670 +CONFIG_FLATMEM_MANUAL=y
671 +# CONFIG_DISCONTIGMEM_MANUAL is not set
672 +# CONFIG_SPARSEMEM_MANUAL is not set
673 +CONFIG_FLATMEM=y
674 +CONFIG_FLAT_NODE_MEM_MAP=y
675 +CONFIG_PAGEFLAGS_EXTENDED=y
676 +CONFIG_SPLIT_PTLOCK_CPUS=4
677 +# CONFIG_PHYS_ADDR_T_64BIT is not set
678 +CONFIG_ZONE_DMA_FLAG=0
679 +CONFIG_VIRT_TO_BUS=y
680 +CONFIG_UNEVICTABLE_LRU=y
681 +# CONFIG_LEDS is not set
682 +CONFIG_ALIGNMENT_TRAP=y
685 +# Boot options
687 +CONFIG_ZBOOT_ROM_TEXT=0x0
688 +CONFIG_ZBOOT_ROM_BSS=0x0
689 +CONFIG_CMDLINE="root=/dev/nfs nfsroot=192.168.0.1:/home/user/buildroot ip=192.168.0.2:192.168.0.1:192.168.0.1:255.255.255.0:tgt:eth0:off rw console=ttyS2,115200n8"
690 +# CONFIG_XIP_KERNEL is not set
691 +# CONFIG_KEXEC is not set
694 +# CPU Power Management
696 +# CONFIG_CPU_FREQ is not set
697 +# CONFIG_CPU_IDLE is not set
700 +# Floating point emulation
704 +# At least one emulation must be selected
706 +CONFIG_FPE_NWFPE=y
707 +# CONFIG_FPE_NWFPE_XP is not set
708 +# CONFIG_FPE_FASTFPE is not set
709 +CONFIG_VFP=y
710 +CONFIG_VFPv3=y
711 +# CONFIG_NEON is not set
714 +# Userspace binary formats
716 +CONFIG_BINFMT_ELF=y
717 +# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set
718 +CONFIG_HAVE_AOUT=y
719 +# CONFIG_BINFMT_AOUT is not set
720 +CONFIG_BINFMT_MISC=y
723 +# Power management options
725 +CONFIG_PM=y
726 +CONFIG_PM_DEBUG=y
727 +# CONFIG_PM_VERBOSE is not set
728 +# CONFIG_SUSPEND is not set
729 +# CONFIG_APM_EMULATION is not set
730 +CONFIG_ARCH_SUSPEND_POSSIBLE=y
731 +CONFIG_NET=y
734 +# Networking options
736 +CONFIG_COMPAT_NET_DEV_OPS=y
737 +CONFIG_PACKET=y
738 +# CONFIG_PACKET_MMAP is not set
739 +CONFIG_UNIX=y
740 +CONFIG_XFRM=y
741 +# CONFIG_XFRM_USER is not set
742 +# CONFIG_XFRM_SUB_POLICY is not set
743 +# CONFIG_XFRM_MIGRATE is not set
744 +# CONFIG_XFRM_STATISTICS is not set
745 +CONFIG_NET_KEY=y
746 +# CONFIG_NET_KEY_MIGRATE is not set
747 +CONFIG_INET=y
748 +# CONFIG_IP_MULTICAST is not set
749 +# CONFIG_IP_ADVANCED_ROUTER is not set
750 +CONFIG_IP_FIB_HASH=y
751 +CONFIG_IP_PNP=y
752 +CONFIG_IP_PNP_DHCP=y
753 +CONFIG_IP_PNP_BOOTP=y
754 +CONFIG_IP_PNP_RARP=y
755 +# CONFIG_NET_IPIP is not set
756 +# CONFIG_NET_IPGRE is not set
757 +# CONFIG_ARPD is not set
758 +# CONFIG_SYN_COOKIES is not set
759 +# CONFIG_INET_AH is not set
760 +# CONFIG_INET_ESP is not set
761 +# CONFIG_INET_IPCOMP is not set
762 +# CONFIG_INET_XFRM_TUNNEL is not set
763 +# CONFIG_INET_TUNNEL is not set
764 +CONFIG_INET_XFRM_MODE_TRANSPORT=y
765 +CONFIG_INET_XFRM_MODE_TUNNEL=y
766 +CONFIG_INET_XFRM_MODE_BEET=y
767 +# CONFIG_INET_LRO is not set
768 +CONFIG_INET_DIAG=y
769 +CONFIG_INET_TCP_DIAG=y
770 +# CONFIG_TCP_CONG_ADVANCED is not set
771 +CONFIG_TCP_CONG_CUBIC=y
772 +CONFIG_DEFAULT_TCP_CONG="cubic"
773 +# CONFIG_TCP_MD5SIG is not set
774 +# CONFIG_IPV6 is not set
775 +# CONFIG_NETWORK_SECMARK is not set
776 +# CONFIG_NETFILTER is not set
777 +# CONFIG_IP_DCCP is not set
778 +# CONFIG_IP_SCTP is not set
779 +# CONFIG_TIPC is not set
780 +# CONFIG_ATM is not set
781 +# CONFIG_BRIDGE is not set
782 +# CONFIG_NET_DSA is not set
783 +# CONFIG_VLAN_8021Q is not set
784 +# CONFIG_DECNET is not set
785 +# CONFIG_LLC2 is not set
786 +# CONFIG_IPX is not set
787 +# CONFIG_ATALK is not set
788 +# CONFIG_X25 is not set
789 +# CONFIG_LAPB is not set
790 +# CONFIG_ECONET is not set
791 +# CONFIG_WAN_ROUTER is not set
792 +# CONFIG_NET_SCHED is not set
793 +# CONFIG_DCB is not set
796 +# Network testing
798 +# CONFIG_NET_PKTGEN is not set
799 +# CONFIG_HAMRADIO is not set
800 +# CONFIG_CAN is not set
801 +# CONFIG_IRDA is not set
802 +# CONFIG_BT is not set
803 +# CONFIG_AF_RXRPC is not set
804 +# CONFIG_PHONET is not set
805 +CONFIG_WIRELESS=y
806 +# CONFIG_CFG80211 is not set
807 +CONFIG_WIRELESS_OLD_REGULATORY=y
808 +# CONFIG_WIRELESS_EXT is not set
809 +# CONFIG_LIB80211 is not set
810 +# CONFIG_MAC80211 is not set
811 +# CONFIG_WIMAX is not set
812 +# CONFIG_RFKILL is not set
813 +# CONFIG_NET_9P is not set
816 +# Device Drivers
820 +# Generic Driver Options
822 +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
823 +CONFIG_STANDALONE=y
824 +CONFIG_PREVENT_FIRMWARE_BUILD=y
825 +# CONFIG_FW_LOADER is not set
826 +# CONFIG_DEBUG_DRIVER is not set
827 +# CONFIG_DEBUG_DEVRES is not set
828 +# CONFIG_SYS_HYPERVISOR is not set
829 +# CONFIG_CONNECTOR is not set
830 +CONFIG_MTD=y
831 +# CONFIG_MTD_DEBUG is not set
832 +# CONFIG_MTD_CONCAT is not set
833 +CONFIG_MTD_PARTITIONS=y
834 +# CONFIG_MTD_TESTS is not set
835 +# CONFIG_MTD_REDBOOT_PARTS is not set
836 +# CONFIG_MTD_CMDLINE_PARTS is not set
837 +# CONFIG_MTD_AFS_PARTS is not set
838 +# CONFIG_MTD_AR7_PARTS is not set
841 +# User Modules And Translation Layers
843 +CONFIG_MTD_CHAR=y
844 +CONFIG_MTD_BLKDEVS=y
845 +CONFIG_MTD_BLOCK=y
846 +# CONFIG_FTL is not set
847 +# CONFIG_NFTL is not set
848 +# CONFIG_INFTL is not set
849 +# CONFIG_RFD_FTL is not set
850 +# CONFIG_SSFDC is not set
851 +# CONFIG_MTD_OOPS is not set
854 +# RAM/ROM/Flash chip drivers
856 +# CONFIG_MTD_CFI is not set
857 +# CONFIG_MTD_JEDECPROBE is not set
858 +CONFIG_MTD_MAP_BANK_WIDTH_1=y
859 +CONFIG_MTD_MAP_BANK_WIDTH_2=y
860 +CONFIG_MTD_MAP_BANK_WIDTH_4=y
861 +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
862 +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
863 +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
864 +CONFIG_MTD_CFI_I1=y
865 +CONFIG_MTD_CFI_I2=y
866 +# CONFIG_MTD_CFI_I4 is not set
867 +# CONFIG_MTD_CFI_I8 is not set
868 +# CONFIG_MTD_RAM is not set
869 +# CONFIG_MTD_ROM is not set
870 +# CONFIG_MTD_ABSENT is not set
873 +# Mapping drivers for chip access
875 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
876 +# CONFIG_MTD_PLATRAM is not set
879 +# Self-contained MTD device drivers
881 +# CONFIG_MTD_SLRAM is not set
882 +# CONFIG_MTD_PHRAM is not set
883 +# CONFIG_MTD_MTDRAM is not set
884 +# CONFIG_MTD_BLOCK2MTD is not set
887 +# Disk-On-Chip Device Drivers
889 +# CONFIG_MTD_DOC2000 is not set
890 +# CONFIG_MTD_DOC2001 is not set
891 +# CONFIG_MTD_DOC2001PLUS is not set
892 +CONFIG_MTD_NAND=y
893 +# CONFIG_MTD_NAND_VERIFY_WRITE is not set
894 +# CONFIG_MTD_NAND_ECC_SMC is not set
895 +# CONFIG_MTD_NAND_MUSEUM_IDS is not set
896 +# CONFIG_MTD_NAND_GPIO is not set
897 +CONFIG_MTD_NAND_OMAP2=y
898 +CONFIG_MTD_NAND_IDS=y
899 +# CONFIG_MTD_NAND_DISKONCHIP is not set
900 +# CONFIG_MTD_NAND_NANDSIM is not set
901 +# CONFIG_MTD_NAND_PLATFORM is not set
902 +# CONFIG_MTD_ONENAND is not set
905 +# LPDDR flash memory drivers
907 +# CONFIG_MTD_LPDDR is not set
908 +# CONFIG_MTD_QINFO_PROBE is not set
911 +# UBI - Unsorted block images
913 +# CONFIG_MTD_UBI is not set
914 +# CONFIG_PARPORT is not set
915 +CONFIG_BLK_DEV=y
916 +# CONFIG_BLK_DEV_COW_COMMON is not set
917 +CONFIG_BLK_DEV_LOOP=y
918 +# CONFIG_BLK_DEV_CRYPTOLOOP is not set
919 +# CONFIG_BLK_DEV_NBD is not set
920 +CONFIG_BLK_DEV_RAM=y
921 +CONFIG_BLK_DEV_RAM_COUNT=16
922 +CONFIG_BLK_DEV_RAM_SIZE=16384
923 +# CONFIG_BLK_DEV_XIP is not set
924 +# CONFIG_CDROM_PKTCDVD is not set
925 +# CONFIG_ATA_OVER_ETH is not set
926 +# CONFIG_MISC_DEVICES is not set
927 +CONFIG_HAVE_IDE=y
928 +# CONFIG_IDE is not set
931 +# SCSI device support
933 +# CONFIG_RAID_ATTRS is not set
934 +CONFIG_SCSI=y
935 +CONFIG_SCSI_DMA=y
936 +# CONFIG_SCSI_TGT is not set
937 +# CONFIG_SCSI_NETLINK is not set
938 +CONFIG_SCSI_PROC_FS=y
941 +# SCSI support type (disk, tape, CD-ROM)
943 +CONFIG_BLK_DEV_SD=y
944 +# CONFIG_CHR_DEV_ST is not set
945 +# CONFIG_CHR_DEV_OSST is not set
946 +# CONFIG_BLK_DEV_SR is not set
947 +# CONFIG_CHR_DEV_SG is not set
948 +# CONFIG_CHR_DEV_SCH is not set
951 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
953 +# CONFIG_SCSI_MULTI_LUN is not set
954 +# CONFIG_SCSI_CONSTANTS is not set
955 +# CONFIG_SCSI_LOGGING is not set
956 +# CONFIG_SCSI_SCAN_ASYNC is not set
957 +CONFIG_SCSI_WAIT_SCAN=m
960 +# SCSI Transports
962 +# CONFIG_SCSI_SPI_ATTRS is not set
963 +# CONFIG_SCSI_FC_ATTRS is not set
964 +# CONFIG_SCSI_ISCSI_ATTRS is not set
965 +# CONFIG_SCSI_SAS_LIBSAS is not set
966 +# CONFIG_SCSI_SRP_ATTRS is not set
967 +CONFIG_SCSI_LOWLEVEL=y
968 +# CONFIG_ISCSI_TCP is not set
969 +# CONFIG_LIBFC is not set
970 +# CONFIG_SCSI_DEBUG is not set
971 +# CONFIG_SCSI_DH is not set
972 +# CONFIG_ATA is not set
973 +# CONFIG_MD is not set
974 +CONFIG_NETDEVICES=y
975 +# CONFIG_DUMMY is not set
976 +# CONFIG_BONDING is not set
977 +# CONFIG_MACVLAN is not set
978 +# CONFIG_EQUALIZER is not set
979 +# CONFIG_TUN is not set
980 +# CONFIG_VETH is not set
981 +# CONFIG_NET_ETHERNET is not set
982 +# CONFIG_NETDEV_1000 is not set
983 +# CONFIG_NETDEV_10000 is not set
986 +# Wireless LAN
988 +# CONFIG_WLAN_PRE80211 is not set
989 +# CONFIG_WLAN_80211 is not set
990 +# CONFIG_IWLWIFI_LEDS is not set
993 +# Enable WiMAX (Networking options) to see the WiMAX drivers
995 +# CONFIG_WAN is not set
996 +# CONFIG_PPP is not set
997 +# CONFIG_SLIP is not set
998 +# CONFIG_NETCONSOLE is not set
999 +# CONFIG_NETPOLL is not set
1000 +# CONFIG_NET_POLL_CONTROLLER is not set
1001 +# CONFIG_ISDN is not set
1004 +# Input device support
1006 +CONFIG_INPUT=y
1007 +# CONFIG_INPUT_FF_MEMLESS is not set
1008 +# CONFIG_INPUT_POLLDEV is not set
1011 +# Userland interfaces
1013 +# CONFIG_INPUT_MOUSEDEV is not set
1014 +# CONFIG_INPUT_JOYDEV is not set
1015 +# CONFIG_INPUT_EVDEV is not set
1016 +# CONFIG_INPUT_EVBUG is not set
1019 +# Input Device Drivers
1021 +# CONFIG_INPUT_KEYBOARD is not set
1022 +# CONFIG_INPUT_MOUSE is not set
1023 +# CONFIG_INPUT_JOYSTICK is not set
1024 +# CONFIG_INPUT_TABLET is not set
1025 +# CONFIG_INPUT_TOUCHSCREEN is not set
1026 +# CONFIG_INPUT_MISC is not set
1029 +# Hardware I/O ports
1031 +# CONFIG_SERIO is not set
1032 +# CONFIG_GAMEPORT is not set
1035 +# Character devices
1037 +CONFIG_VT=y
1038 +CONFIG_CONSOLE_TRANSLATIONS=y
1039 +CONFIG_VT_CONSOLE=y
1040 +CONFIG_HW_CONSOLE=y
1041 +# CONFIG_VT_HW_CONSOLE_BINDING is not set
1042 +CONFIG_DEVKMEM=y
1043 +# CONFIG_SERIAL_NONSTANDARD is not set
1046 +# Serial drivers
1048 +CONFIG_SERIAL_8250=y
1049 +CONFIG_SERIAL_8250_CONSOLE=y
1050 +CONFIG_SERIAL_8250_NR_UARTS=32
1051 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4
1052 +CONFIG_SERIAL_8250_EXTENDED=y
1053 +CONFIG_SERIAL_8250_MANY_PORTS=y
1054 +CONFIG_SERIAL_8250_SHARE_IRQ=y
1055 +CONFIG_SERIAL_8250_DETECT_IRQ=y
1056 +CONFIG_SERIAL_8250_RSA=y
1059 +# Non-8250 serial port support
1061 +CONFIG_SERIAL_CORE=y
1062 +CONFIG_SERIAL_CORE_CONSOLE=y
1063 +CONFIG_UNIX98_PTYS=y
1064 +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
1065 +# CONFIG_LEGACY_PTYS is not set
1066 +# CONFIG_IPMI_HANDLER is not set
1067 +CONFIG_HW_RANDOM=y
1068 +# CONFIG_NVRAM is not set
1069 +# CONFIG_R3964 is not set
1070 +# CONFIG_RAW_DRIVER is not set
1071 +# CONFIG_TCG_TPM is not set
1072 +CONFIG_I2C=y
1073 +CONFIG_I2C_BOARDINFO=y
1074 +CONFIG_I2C_CHARDEV=y
1075 +CONFIG_I2C_HELPER_AUTO=y
1078 +# I2C Hardware Bus support
1082 +# I2C system bus drivers (mostly embedded / system-on-chip)
1084 +# CONFIG_I2C_GPIO is not set
1085 +# CONFIG_I2C_OCORES is not set
1086 +CONFIG_I2C_OMAP=y
1087 +# CONFIG_I2C2_OMAP_BEAGLE is not set
1088 +# CONFIG_I2C_SIMTEC is not set
1091 +# External I2C/SMBus adapter drivers
1093 +# CONFIG_I2C_PARPORT_LIGHT is not set
1094 +# CONFIG_I2C_TAOS_EVM is not set
1097 +# Other I2C/SMBus bus drivers
1099 +# CONFIG_I2C_PCA_PLATFORM is not set
1100 +# CONFIG_I2C_STUB is not set
1103 +# Miscellaneous I2C Chip support
1105 +# CONFIG_DS1682 is not set
1106 +# CONFIG_SENSORS_PCF8574 is not set
1107 +# CONFIG_PCF8575 is not set
1108 +# CONFIG_SENSORS_PCA9539 is not set
1109 +# CONFIG_SENSORS_PCF8591 is not set
1110 +# CONFIG_TWL4030_MADC is not set
1111 +# CONFIG_TWL4030_PWRBUTTON is not set
1112 +# CONFIG_TWL4030_POWEROFF is not set
1113 +# CONFIG_SENSORS_MAX6875 is not set
1114 +# CONFIG_SENSORS_TSL2550 is not set
1115 +# CONFIG_LP5521 is not set
1116 +# CONFIG_I2C_DEBUG_CORE is not set
1117 +# CONFIG_I2C_DEBUG_ALGO is not set
1118 +# CONFIG_I2C_DEBUG_BUS is not set
1119 +# CONFIG_I2C_DEBUG_CHIP is not set
1120 +# CONFIG_SPI is not set
1121 +CONFIG_ARCH_REQUIRE_GPIOLIB=y
1122 +CONFIG_GPIOLIB=y
1123 +# CONFIG_DEBUG_GPIO is not set
1124 +# CONFIG_GPIO_SYSFS is not set
1127 +# Memory mapped GPIO expanders:
1131 +# I2C GPIO expanders:
1133 +# CONFIG_GPIO_MAX732X is not set
1134 +# CONFIG_GPIO_PCA953X is not set
1135 +# CONFIG_GPIO_PCF857X is not set
1136 +CONFIG_GPIO_TWL4030=y
1139 +# PCI GPIO expanders:
1143 +# SPI GPIO expanders:
1145 +# CONFIG_W1 is not set
1146 +# CONFIG_POWER_SUPPLY is not set
1147 +# CONFIG_HWMON is not set
1148 +# CONFIG_THERMAL is not set
1149 +# CONFIG_THERMAL_HWMON is not set
1150 +# CONFIG_WATCHDOG is not set
1151 +CONFIG_SSB_POSSIBLE=y
1154 +# Sonics Silicon Backplane
1156 +# CONFIG_SSB is not set
1159 +# Multifunction device drivers
1161 +# CONFIG_MFD_CORE is not set
1162 +# CONFIG_MFD_SM501 is not set
1163 +# CONFIG_MFD_ASIC3 is not set
1164 +# CONFIG_HTC_EGPIO is not set
1165 +# CONFIG_HTC_PASIC3 is not set
1166 +# CONFIG_TPS65010 is not set
1167 +CONFIG_TWL4030_CORE=y
1168 +# CONFIG_TWL4030_POWER is not set
1169 +# CONFIG_MFD_TMIO is not set
1170 +# CONFIG_MFD_T7L66XB is not set
1171 +# CONFIG_MFD_TC6387XB is not set
1172 +# CONFIG_MFD_TC6393XB is not set
1173 +# CONFIG_PMIC_DA903X is not set
1174 +# CONFIG_MFD_WM8400 is not set
1175 +# CONFIG_MFD_WM8350_I2C is not set
1176 +# CONFIG_MFD_PCF50633 is not set
1179 +# Multimedia devices
1183 +# Multimedia core support
1185 +# CONFIG_VIDEO_DEV is not set
1186 +# CONFIG_DVB_CORE is not set
1187 +# CONFIG_VIDEO_MEDIA is not set
1190 +# Multimedia drivers
1192 +CONFIG_DAB=y
1195 +# Graphics support
1197 +# CONFIG_VGASTATE is not set
1198 +# CONFIG_VIDEO_OUTPUT_CONTROL is not set
1199 +CONFIG_FB=y
1200 +# CONFIG_FIRMWARE_EDID is not set
1201 +# CONFIG_FB_DDC is not set
1202 +# CONFIG_FB_BOOT_VESA_SUPPORT is not set
1203 +CONFIG_FB_CFB_FILLRECT=m
1204 +CONFIG_FB_CFB_COPYAREA=m
1205 +CONFIG_FB_CFB_IMAGEBLIT=m
1206 +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
1207 +# CONFIG_FB_SYS_FILLRECT is not set
1208 +# CONFIG_FB_SYS_COPYAREA is not set
1209 +# CONFIG_FB_SYS_IMAGEBLIT is not set
1210 +# CONFIG_FB_FOREIGN_ENDIAN is not set
1211 +# CONFIG_FB_SYS_FOPS is not set
1212 +# CONFIG_FB_SVGALIB is not set
1213 +# CONFIG_FB_MACMODES is not set
1214 +# CONFIG_FB_BACKLIGHT is not set
1215 +# CONFIG_FB_MODE_HELPERS is not set
1216 +# CONFIG_FB_TILEBLITTING is not set
1219 +# Frame buffer hardware drivers
1221 +# CONFIG_FB_S1D13XXX is not set
1222 +# CONFIG_FB_VIRTUAL is not set
1223 +# CONFIG_FB_METRONOME is not set
1224 +# CONFIG_FB_MB862XX is not set
1225 +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
1226 +CONFIG_OMAP2_DSS=m
1227 +CONFIG_OMAP2_DSS_VRAM_SIZE=4
1228 +CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
1229 +# CONFIG_OMAP2_DSS_RFBI is not set
1230 +CONFIG_OMAP2_DSS_VENC=y
1231 +# CONFIG_OMAP2_DSS_SDI is not set
1232 +# CONFIG_OMAP2_DSS_DSI is not set
1233 +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
1234 +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
1235 +CONFIG_FB_OMAP2=m
1236 +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
1237 +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
1238 +CONFIG_FB_OMAP2_NUM_FBS=3
1241 +# OMAP2/3 Display Device Drivers
1243 +CONFIG_PANEL_GENERIC=m
1244 +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
1245 +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
1248 +# Display device support
1250 +# CONFIG_DISPLAY_SUPPORT is not set
1253 +# Console display driver support
1255 +# CONFIG_VGA_CONSOLE is not set
1256 +CONFIG_DUMMY_CONSOLE=y
1257 +# CONFIG_FRAMEBUFFER_CONSOLE is not set
1258 +# CONFIG_LOGO is not set
1259 +# CONFIG_SOUND is not set
1260 +# CONFIG_HID_SUPPORT is not set
1261 +CONFIG_USB_SUPPORT=y
1262 +CONFIG_USB_ARCH_HAS_HCD=y
1263 +CONFIG_USB_ARCH_HAS_OHCI=y
1264 +CONFIG_USB_ARCH_HAS_EHCI=y
1265 +# CONFIG_USB is not set
1266 +# CONFIG_USB_OTG_WHITELIST is not set
1267 +# CONFIG_USB_OTG_BLACKLIST_HUB is not set
1268 +CONFIG_USB_MUSB_HDRC=y
1269 +CONFIG_USB_MUSB_SOC=y
1272 +# OMAP 343x high speed USB support
1274 +# CONFIG_USB_MUSB_HOST is not set
1275 +CONFIG_USB_MUSB_PERIPHERAL=y
1276 +# CONFIG_USB_MUSB_OTG is not set
1277 +CONFIG_USB_GADGET_MUSB_HDRC=y
1278 +# CONFIG_MUSB_PIO_ONLY is not set
1279 +CONFIG_USB_INVENTRA_DMA=y
1280 +# CONFIG_USB_TI_CPPI_DMA is not set
1281 +# CONFIG_USB_MUSB_DEBUG is not set
1284 +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
1286 +CONFIG_USB_GADGET=y
1287 +# CONFIG_USB_GADGET_DEBUG is not set
1288 +# CONFIG_USB_GADGET_DEBUG_FILES is not set
1289 +# CONFIG_USB_GADGET_DEBUG_FS is not set
1290 +CONFIG_USB_GADGET_VBUS_DRAW=2
1291 +CONFIG_USB_GADGET_SELECTED=y
1292 +# CONFIG_USB_GADGET_AT91 is not set
1293 +# CONFIG_USB_GADGET_ATMEL_USBA is not set
1294 +# CONFIG_USB_GADGET_FSL_USB2 is not set
1295 +# CONFIG_USB_GADGET_LH7A40X is not set
1296 +# CONFIG_USB_GADGET_OMAP is not set
1297 +# CONFIG_USB_GADGET_PXA25X is not set
1298 +# CONFIG_USB_GADGET_PXA27X is not set
1299 +# CONFIG_USB_GADGET_S3C2410 is not set
1300 +# CONFIG_USB_GADGET_IMX is not set
1301 +# CONFIG_USB_GADGET_M66592 is not set
1302 +# CONFIG_USB_GADGET_AMD5536UDC is not set
1303 +# CONFIG_USB_GADGET_FSL_QE is not set
1304 +# CONFIG_USB_GADGET_CI13XXX is not set
1305 +# CONFIG_USB_GADGET_NET2280 is not set
1306 +# CONFIG_USB_GADGET_GOKU is not set
1307 +# CONFIG_USB_GADGET_DUMMY_HCD is not set
1308 +CONFIG_USB_GADGET_DUALSPEED=y
1309 +# CONFIG_USB_ZERO is not set
1310 +CONFIG_USB_ETH=y
1311 +CONFIG_USB_ETH_RNDIS=y
1312 +# CONFIG_USB_GADGETFS is not set
1313 +# CONFIG_USB_FILE_STORAGE is not set
1314 +# CONFIG_USB_G_SERIAL is not set
1315 +# CONFIG_USB_MIDI_GADGET is not set
1316 +# CONFIG_USB_G_PRINTER is not set
1317 +# CONFIG_USB_CDC_COMPOSITE is not set
1320 +# OTG and related infrastructure
1322 +CONFIG_USB_OTG_UTILS=y
1323 +# CONFIG_USB_GPIO_VBUS is not set
1324 +# CONFIG_ISP1301_OMAP is not set
1325 +CONFIG_TWL4030_USB=y
1326 +CONFIG_MMC=y
1327 +# CONFIG_MMC_DEBUG is not set
1328 +# CONFIG_MMC_UNSAFE_RESUME is not set
1331 +# MMC/SD/SDIO Card Drivers
1333 +CONFIG_MMC_BLOCK=y
1334 +CONFIG_MMC_BLOCK_BOUNCE=y
1335 +# CONFIG_SDIO_UART is not set
1336 +# CONFIG_MMC_TEST is not set
1339 +# MMC/SD/SDIO Host Controller Drivers
1341 +# CONFIG_MMC_SDHCI is not set
1342 +CONFIG_MMC_OMAP_HS=y
1343 +# CONFIG_MEMSTICK is not set
1344 +# CONFIG_ACCESSIBILITY is not set
1345 +# CONFIG_NEW_LEDS is not set
1346 +CONFIG_RTC_LIB=y
1347 +CONFIG_RTC_CLASS=y
1348 +CONFIG_RTC_HCTOSYS=y
1349 +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1350 +# CONFIG_RTC_DEBUG is not set
1353 +# RTC interfaces
1355 +CONFIG_RTC_INTF_SYSFS=y
1356 +CONFIG_RTC_INTF_PROC=y
1357 +CONFIG_RTC_INTF_DEV=y
1358 +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1359 +# CONFIG_RTC_DRV_TEST is not set
1362 +# I2C RTC drivers
1364 +# CONFIG_RTC_DRV_DS1307 is not set
1365 +# CONFIG_RTC_DRV_DS1374 is not set
1366 +# CONFIG_RTC_DRV_DS1672 is not set
1367 +# CONFIG_RTC_DRV_MAX6900 is not set
1368 +# CONFIG_RTC_DRV_RS5C372 is not set
1369 +# CONFIG_RTC_DRV_ISL1208 is not set
1370 +# CONFIG_RTC_DRV_X1205 is not set
1371 +# CONFIG_RTC_DRV_PCF8563 is not set
1372 +# CONFIG_RTC_DRV_PCF8583 is not set
1373 +# CONFIG_RTC_DRV_M41T80 is not set
1374 +CONFIG_RTC_DRV_TWL4030=y
1375 +# CONFIG_RTC_DRV_S35390A is not set
1376 +# CONFIG_RTC_DRV_FM3130 is not set
1377 +# CONFIG_RTC_DRV_RX8581 is not set
1380 +# SPI RTC drivers
1384 +# Platform RTC drivers
1386 +# CONFIG_RTC_DRV_CMOS is not set
1387 +# CONFIG_RTC_DRV_DS1286 is not set
1388 +# CONFIG_RTC_DRV_DS1511 is not set
1389 +# CONFIG_RTC_DRV_DS1553 is not set
1390 +# CONFIG_RTC_DRV_DS1742 is not set
1391 +# CONFIG_RTC_DRV_STK17TA8 is not set
1392 +# CONFIG_RTC_DRV_M48T86 is not set
1393 +# CONFIG_RTC_DRV_M48T35 is not set
1394 +# CONFIG_RTC_DRV_M48T59 is not set
1395 +# CONFIG_RTC_DRV_BQ4802 is not set
1396 +# CONFIG_RTC_DRV_V3020 is not set
1399 +# on-CPU RTC drivers
1401 +# CONFIG_DMADEVICES is not set
1402 +# CONFIG_REGULATOR is not set
1403 +# CONFIG_UIO is not set
1404 +# CONFIG_STAGING is not set
1407 +# CBUS support
1409 +# CONFIG_CBUS is not set
1412 +# File systems
1414 +CONFIG_EXT2_FS=y
1415 +# CONFIG_EXT2_FS_XATTR is not set
1416 +# CONFIG_EXT2_FS_XIP is not set
1417 +CONFIG_EXT3_FS=y
1418 +# CONFIG_EXT3_FS_XATTR is not set
1419 +# CONFIG_EXT4_FS is not set
1420 +CONFIG_JBD=y
1421 +# CONFIG_JBD_DEBUG is not set
1422 +# CONFIG_REISERFS_FS is not set
1423 +# CONFIG_JFS_FS is not set
1424 +# CONFIG_FS_POSIX_ACL is not set
1425 +CONFIG_FILE_LOCKING=y
1426 +# CONFIG_XFS_FS is not set
1427 +# CONFIG_OCFS2_FS is not set
1428 +# CONFIG_BTRFS_FS is not set
1429 +CONFIG_DNOTIFY=y
1430 +CONFIG_INOTIFY=y
1431 +CONFIG_INOTIFY_USER=y
1432 +CONFIG_QUOTA=y
1433 +# CONFIG_QUOTA_NETLINK_INTERFACE is not set
1434 +CONFIG_PRINT_QUOTA_WARNING=y
1435 +CONFIG_QUOTA_TREE=y
1436 +# CONFIG_QFMT_V1 is not set
1437 +CONFIG_QFMT_V2=y
1438 +CONFIG_QUOTACTL=y
1439 +# CONFIG_AUTOFS_FS is not set
1440 +# CONFIG_AUTOFS4_FS is not set
1441 +# CONFIG_FUSE_FS is not set
1444 +# CD-ROM/DVD Filesystems
1446 +# CONFIG_ISO9660_FS is not set
1447 +# CONFIG_UDF_FS is not set
1450 +# DOS/FAT/NT Filesystems
1452 +CONFIG_FAT_FS=y
1453 +CONFIG_MSDOS_FS=y
1454 +CONFIG_VFAT_FS=y
1455 +CONFIG_FAT_DEFAULT_CODEPAGE=437
1456 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1457 +# CONFIG_NTFS_FS is not set
1460 +# Pseudo filesystems
1462 +CONFIG_PROC_FS=y
1463 +CONFIG_PROC_SYSCTL=y
1464 +CONFIG_PROC_PAGE_MONITOR=y
1465 +CONFIG_SYSFS=y
1466 +CONFIG_TMPFS=y
1467 +# CONFIG_TMPFS_POSIX_ACL is not set
1468 +# CONFIG_HUGETLB_PAGE is not set
1469 +# CONFIG_CONFIGFS_FS is not set
1470 +CONFIG_MISC_FILESYSTEMS=y
1471 +# CONFIG_ADFS_FS is not set
1472 +# CONFIG_AFFS_FS is not set
1473 +# CONFIG_HFS_FS is not set
1474 +# CONFIG_HFSPLUS_FS is not set
1475 +# CONFIG_BEFS_FS is not set
1476 +# CONFIG_BFS_FS is not set
1477 +# CONFIG_EFS_FS is not set
1478 +CONFIG_JFFS2_FS=y
1479 +CONFIG_JFFS2_FS_DEBUG=0
1480 +CONFIG_JFFS2_FS_WRITEBUFFER=y
1481 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
1482 +# CONFIG_JFFS2_SUMMARY is not set
1483 +# CONFIG_JFFS2_FS_XATTR is not set
1484 +# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1485 +CONFIG_JFFS2_ZLIB=y
1486 +# CONFIG_JFFS2_LZO is not set
1487 +CONFIG_JFFS2_RTIME=y
1488 +# CONFIG_JFFS2_RUBIN is not set
1489 +# CONFIG_CRAMFS is not set
1490 +# CONFIG_SQUASHFS is not set
1491 +# CONFIG_VXFS_FS is not set
1492 +# CONFIG_MINIX_FS is not set
1493 +# CONFIG_OMFS_FS is not set
1494 +# CONFIG_HPFS_FS is not set
1495 +# CONFIG_QNX4FS_FS is not set
1496 +# CONFIG_ROMFS_FS is not set
1497 +# CONFIG_SYSV_FS is not set
1498 +# CONFIG_UFS_FS is not set
1499 +CONFIG_NETWORK_FILESYSTEMS=y
1500 +CONFIG_NFS_FS=y
1501 +CONFIG_NFS_V3=y
1502 +# CONFIG_NFS_V3_ACL is not set
1503 +CONFIG_NFS_V4=y
1504 +CONFIG_ROOT_NFS=y
1505 +# CONFIG_NFSD is not set
1506 +CONFIG_LOCKD=y
1507 +CONFIG_LOCKD_V4=y
1508 +CONFIG_NFS_COMMON=y
1509 +CONFIG_SUNRPC=y
1510 +CONFIG_SUNRPC_GSS=y
1511 +# CONFIG_SUNRPC_REGISTER_V4 is not set
1512 +CONFIG_RPCSEC_GSS_KRB5=y
1513 +# CONFIG_RPCSEC_GSS_SPKM3 is not set
1514 +# CONFIG_SMB_FS is not set
1515 +# CONFIG_CIFS is not set
1516 +# CONFIG_NCP_FS is not set
1517 +# CONFIG_CODA_FS is not set
1518 +# CONFIG_AFS_FS is not set
1521 +# Partition Types
1523 +CONFIG_PARTITION_ADVANCED=y
1524 +# CONFIG_ACORN_PARTITION is not set
1525 +# CONFIG_OSF_PARTITION is not set
1526 +# CONFIG_AMIGA_PARTITION is not set
1527 +# CONFIG_ATARI_PARTITION is not set
1528 +# CONFIG_MAC_PARTITION is not set
1529 +CONFIG_MSDOS_PARTITION=y
1530 +# CONFIG_BSD_DISKLABEL is not set
1531 +# CONFIG_MINIX_SUBPARTITION is not set
1532 +# CONFIG_SOLARIS_X86_PARTITION is not set
1533 +# CONFIG_UNIXWARE_DISKLABEL is not set
1534 +# CONFIG_LDM_PARTITION is not set
1535 +# CONFIG_SGI_PARTITION is not set
1536 +# CONFIG_ULTRIX_PARTITION is not set
1537 +# CONFIG_SUN_PARTITION is not set
1538 +# CONFIG_KARMA_PARTITION is not set
1539 +# CONFIG_EFI_PARTITION is not set
1540 +# CONFIG_SYSV68_PARTITION is not set
1541 +CONFIG_NLS=y
1542 +CONFIG_NLS_DEFAULT="iso8859-1"
1543 +CONFIG_NLS_CODEPAGE_437=y
1544 +# CONFIG_NLS_CODEPAGE_737 is not set
1545 +# CONFIG_NLS_CODEPAGE_775 is not set
1546 +# CONFIG_NLS_CODEPAGE_850 is not set
1547 +# CONFIG_NLS_CODEPAGE_852 is not set
1548 +# CONFIG_NLS_CODEPAGE_855 is not set
1549 +# CONFIG_NLS_CODEPAGE_857 is not set
1550 +# CONFIG_NLS_CODEPAGE_860 is not set
1551 +# CONFIG_NLS_CODEPAGE_861 is not set
1552 +# CONFIG_NLS_CODEPAGE_862 is not set
1553 +# CONFIG_NLS_CODEPAGE_863 is not set
1554 +# CONFIG_NLS_CODEPAGE_864 is not set
1555 +# CONFIG_NLS_CODEPAGE_865 is not set
1556 +# CONFIG_NLS_CODEPAGE_866 is not set
1557 +# CONFIG_NLS_CODEPAGE_869 is not set
1558 +# CONFIG_NLS_CODEPAGE_936 is not set
1559 +# CONFIG_NLS_CODEPAGE_950 is not set
1560 +# CONFIG_NLS_CODEPAGE_932 is not set
1561 +# CONFIG_NLS_CODEPAGE_949 is not set
1562 +# CONFIG_NLS_CODEPAGE_874 is not set
1563 +# CONFIG_NLS_ISO8859_8 is not set
1564 +# CONFIG_NLS_CODEPAGE_1250 is not set
1565 +# CONFIG_NLS_CODEPAGE_1251 is not set
1566 +# CONFIG_NLS_ASCII is not set
1567 +CONFIG_NLS_ISO8859_1=y
1568 +# CONFIG_NLS_ISO8859_2 is not set
1569 +# CONFIG_NLS_ISO8859_3 is not set
1570 +# CONFIG_NLS_ISO8859_4 is not set
1571 +# CONFIG_NLS_ISO8859_5 is not set
1572 +# CONFIG_NLS_ISO8859_6 is not set
1573 +# CONFIG_NLS_ISO8859_7 is not set
1574 +# CONFIG_NLS_ISO8859_9 is not set
1575 +# CONFIG_NLS_ISO8859_13 is not set
1576 +# CONFIG_NLS_ISO8859_14 is not set
1577 +# CONFIG_NLS_ISO8859_15 is not set
1578 +# CONFIG_NLS_KOI8_R is not set
1579 +# CONFIG_NLS_KOI8_U is not set
1580 +# CONFIG_NLS_UTF8 is not set
1581 +# CONFIG_DLM is not set
1584 +# Kernel hacking
1586 +# CONFIG_PRINTK_TIME is not set
1587 +CONFIG_ENABLE_WARN_DEPRECATED=y
1588 +CONFIG_ENABLE_MUST_CHECK=y
1589 +CONFIG_FRAME_WARN=1024
1590 +CONFIG_MAGIC_SYSRQ=y
1591 +# CONFIG_UNUSED_SYMBOLS is not set
1592 +CONFIG_DEBUG_FS=y
1593 +# CONFIG_HEADERS_CHECK is not set
1594 +CONFIG_DEBUG_KERNEL=y
1595 +# CONFIG_DEBUG_SHIRQ is not set
1596 +CONFIG_DETECT_SOFTLOCKUP=y
1597 +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
1598 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
1599 +CONFIG_SCHED_DEBUG=y
1600 +# CONFIG_SCHEDSTATS is not set
1601 +# CONFIG_TIMER_STATS is not set
1602 +# CONFIG_DEBUG_OBJECTS is not set
1603 +# CONFIG_DEBUG_SLAB is not set
1604 +# CONFIG_DEBUG_RT_MUTEXES is not set
1605 +# CONFIG_RT_MUTEX_TESTER is not set
1606 +# CONFIG_DEBUG_SPINLOCK is not set
1607 +CONFIG_DEBUG_MUTEXES=y
1608 +# CONFIG_DEBUG_LOCK_ALLOC is not set
1609 +# CONFIG_PROVE_LOCKING is not set
1610 +# CONFIG_LOCK_STAT is not set
1611 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1612 +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1613 +# CONFIG_DEBUG_KOBJECT is not set
1614 +CONFIG_DEBUG_BUGVERBOSE=y
1615 +CONFIG_DEBUG_INFO=y
1616 +# CONFIG_DEBUG_VM is not set
1617 +# CONFIG_DEBUG_WRITECOUNT is not set
1618 +# CONFIG_DEBUG_MEMORY_INIT is not set
1619 +# CONFIG_DEBUG_LIST is not set
1620 +# CONFIG_DEBUG_SG is not set
1621 +# CONFIG_DEBUG_NOTIFIERS is not set
1622 +CONFIG_FRAME_POINTER=y
1623 +# CONFIG_BOOT_PRINTK_DELAY is not set
1624 +# CONFIG_RCU_TORTURE_TEST is not set
1625 +# CONFIG_RCU_CPU_STALL_DETECTOR is not set
1626 +# CONFIG_BACKTRACE_SELF_TEST is not set
1627 +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
1628 +# CONFIG_FAULT_INJECTION is not set
1629 +# CONFIG_LATENCYTOP is not set
1630 +CONFIG_HAVE_FUNCTION_TRACER=y
1633 +# Tracers
1635 +# CONFIG_FUNCTION_TRACER is not set
1636 +# CONFIG_IRQSOFF_TRACER is not set
1637 +# CONFIG_SCHED_TRACER is not set
1638 +# CONFIG_CONTEXT_SWITCH_TRACER is not set
1639 +# CONFIG_BOOT_TRACER is not set
1640 +# CONFIG_TRACE_BRANCH_PROFILING is not set
1641 +# CONFIG_STACK_TRACER is not set
1642 +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
1643 +# CONFIG_SAMPLES is not set
1644 +CONFIG_HAVE_ARCH_KGDB=y
1645 +# CONFIG_KGDB is not set
1646 +CONFIG_DEBUG_USER=y
1647 +CONFIG_DEBUG_ERRORS=y
1648 +# CONFIG_DEBUG_STACK_USAGE is not set
1649 +# CONFIG_DEBUG_LL is not set
1652 +# Security options
1654 +# CONFIG_KEYS is not set
1655 +# CONFIG_SECURITY is not set
1656 +# CONFIG_SECURITYFS is not set
1657 +# CONFIG_SECURITY_FILE_CAPABILITIES is not set
1658 +CONFIG_CRYPTO=y
1661 +# Crypto core or helper
1663 +# CONFIG_CRYPTO_FIPS is not set
1664 +CONFIG_CRYPTO_ALGAPI=y
1665 +CONFIG_CRYPTO_ALGAPI2=y
1666 +CONFIG_CRYPTO_AEAD2=y
1667 +CONFIG_CRYPTO_BLKCIPHER=y
1668 +CONFIG_CRYPTO_BLKCIPHER2=y
1669 +CONFIG_CRYPTO_HASH=y
1670 +CONFIG_CRYPTO_HASH2=y
1671 +CONFIG_CRYPTO_RNG2=y
1672 +CONFIG_CRYPTO_MANAGER=y
1673 +CONFIG_CRYPTO_MANAGER2=y
1674 +# CONFIG_CRYPTO_GF128MUL is not set
1675 +# CONFIG_CRYPTO_NULL is not set
1676 +# CONFIG_CRYPTO_CRYPTD is not set
1677 +# CONFIG_CRYPTO_AUTHENC is not set
1678 +# CONFIG_CRYPTO_TEST is not set
1681 +# Authenticated Encryption with Associated Data
1683 +# CONFIG_CRYPTO_CCM is not set
1684 +# CONFIG_CRYPTO_GCM is not set
1685 +# CONFIG_CRYPTO_SEQIV is not set
1688 +# Block modes
1690 +CONFIG_CRYPTO_CBC=y
1691 +# CONFIG_CRYPTO_CTR is not set
1692 +# CONFIG_CRYPTO_CTS is not set
1693 +CONFIG_CRYPTO_ECB=m
1694 +# CONFIG_CRYPTO_LRW is not set
1695 +CONFIG_CRYPTO_PCBC=m
1696 +# CONFIG_CRYPTO_XTS is not set
1699 +# Hash modes
1701 +# CONFIG_CRYPTO_HMAC is not set
1702 +# CONFIG_CRYPTO_XCBC is not set
1705 +# Digest
1707 +CONFIG_CRYPTO_CRC32C=y
1708 +# CONFIG_CRYPTO_MD4 is not set
1709 +CONFIG_CRYPTO_MD5=y
1710 +# CONFIG_CRYPTO_MICHAEL_MIC is not set
1711 +# CONFIG_CRYPTO_RMD128 is not set
1712 +# CONFIG_CRYPTO_RMD160 is not set
1713 +# CONFIG_CRYPTO_RMD256 is not set
1714 +# CONFIG_CRYPTO_RMD320 is not set
1715 +# CONFIG_CRYPTO_SHA1 is not set
1716 +# CONFIG_CRYPTO_SHA256 is not set
1717 +# CONFIG_CRYPTO_SHA512 is not set
1718 +# CONFIG_CRYPTO_TGR192 is not set
1719 +# CONFIG_CRYPTO_WP512 is not set
1722 +# Ciphers
1724 +# CONFIG_CRYPTO_AES is not set
1725 +# CONFIG_CRYPTO_ANUBIS is not set
1726 +# CONFIG_CRYPTO_ARC4 is not set
1727 +# CONFIG_CRYPTO_BLOWFISH is not set
1728 +# CONFIG_CRYPTO_CAMELLIA is not set
1729 +# CONFIG_CRYPTO_CAST5 is not set
1730 +# CONFIG_CRYPTO_CAST6 is not set
1731 +CONFIG_CRYPTO_DES=y
1732 +# CONFIG_CRYPTO_FCRYPT is not set
1733 +# CONFIG_CRYPTO_KHAZAD is not set
1734 +# CONFIG_CRYPTO_SALSA20 is not set
1735 +# CONFIG_CRYPTO_SEED is not set
1736 +# CONFIG_CRYPTO_SERPENT is not set
1737 +# CONFIG_CRYPTO_TEA is not set
1738 +# CONFIG_CRYPTO_TWOFISH is not set
1741 +# Compression
1743 +# CONFIG_CRYPTO_DEFLATE is not set
1744 +# CONFIG_CRYPTO_LZO is not set
1747 +# Random Number Generation
1749 +# CONFIG_CRYPTO_ANSI_CPRNG is not set
1750 +CONFIG_CRYPTO_HW=y
1753 +# Library routines
1755 +CONFIG_BITREVERSE=y
1756 +CONFIG_GENERIC_FIND_LAST_BIT=y
1757 +CONFIG_CRC_CCITT=y
1758 +# CONFIG_CRC16 is not set
1759 +# CONFIG_CRC_T10DIF is not set
1760 +# CONFIG_CRC_ITU_T is not set
1761 +CONFIG_CRC32=y
1762 +# CONFIG_CRC7 is not set
1763 +CONFIG_LIBCRC32C=y
1764 +CONFIG_ZLIB_INFLATE=y
1765 +CONFIG_ZLIB_DEFLATE=y
1766 +CONFIG_PLIST=y
1767 +CONFIG_HAS_IOMEM=y
1768 +CONFIG_HAS_IOPORT=y
1769 +CONFIG_HAS_DMA=y
1770 diff --git a/arch/arm/configs/dss_overo_defconfig b/arch/arm/configs/dss_overo_defconfig
1771 new file mode 100644
1772 index 0000000..bf7dbe1
1773 --- /dev/null
1774 +++ b/arch/arm/configs/dss_overo_defconfig
1775 @@ -0,0 +1,1826 @@
1777 +# Automatically generated make config: don't edit
1778 +# Linux kernel version: 2.6.29-rc3-omap1
1779 +# Sat Feb 14 12:23:43 2009
1781 +CONFIG_ARM=y
1782 +CONFIG_SYS_SUPPORTS_APM_EMULATION=y
1783 +CONFIG_GENERIC_GPIO=y
1784 +CONFIG_GENERIC_TIME=y
1785 +CONFIG_GENERIC_CLOCKEVENTS=y
1786 +CONFIG_MMU=y
1787 +# CONFIG_NO_IOPORT is not set
1788 +CONFIG_GENERIC_HARDIRQS=y
1789 +CONFIG_STACKTRACE_SUPPORT=y
1790 +CONFIG_HAVE_LATENCYTOP_SUPPORT=y
1791 +CONFIG_LOCKDEP_SUPPORT=y
1792 +CONFIG_TRACE_IRQFLAGS_SUPPORT=y
1793 +CONFIG_HARDIRQS_SW_RESEND=y
1794 +CONFIG_GENERIC_IRQ_PROBE=y
1795 +CONFIG_RWSEM_GENERIC_SPINLOCK=y
1796 +# CONFIG_ARCH_HAS_ILOG2_U32 is not set
1797 +# CONFIG_ARCH_HAS_ILOG2_U64 is not set
1798 +CONFIG_GENERIC_HWEIGHT=y
1799 +CONFIG_GENERIC_CALIBRATE_DELAY=y
1800 +CONFIG_GENERIC_HARDIRQS_NO__DO_IRQ=y
1801 +CONFIG_OPROFILE_ARMV7=y
1802 +CONFIG_VECTORS_BASE=0xffff0000
1803 +CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
1806 +# General setup
1808 +CONFIG_EXPERIMENTAL=y
1809 +CONFIG_BROKEN_ON_SMP=y
1810 +CONFIG_INIT_ENV_ARG_LIMIT=32
1811 +CONFIG_LOCALVERSION=""
1812 +CONFIG_LOCALVERSION_AUTO=y
1813 +CONFIG_SWAP=y
1814 +CONFIG_SYSVIPC=y
1815 +CONFIG_SYSVIPC_SYSCTL=y
1816 +# CONFIG_POSIX_MQUEUE is not set
1817 +CONFIG_BSD_PROCESS_ACCT=y
1818 +# CONFIG_BSD_PROCESS_ACCT_V3 is not set
1819 +# CONFIG_TASKSTATS is not set
1820 +# CONFIG_AUDIT is not set
1823 +# RCU Subsystem
1825 +CONFIG_CLASSIC_RCU=y
1826 +# CONFIG_TREE_RCU is not set
1827 +# CONFIG_PREEMPT_RCU is not set
1828 +# CONFIG_TREE_RCU_TRACE is not set
1829 +# CONFIG_PREEMPT_RCU_TRACE is not set
1830 +CONFIG_IKCONFIG=y
1831 +CONFIG_IKCONFIG_PROC=y
1832 +CONFIG_LOG_BUF_SHIFT=14
1833 +CONFIG_GROUP_SCHED=y
1834 +CONFIG_FAIR_GROUP_SCHED=y
1835 +# CONFIG_RT_GROUP_SCHED is not set
1836 +CONFIG_USER_SCHED=y
1837 +# CONFIG_CGROUP_SCHED is not set
1838 +# CONFIG_CGROUPS is not set
1839 +CONFIG_SYSFS_DEPRECATED=y
1840 +CONFIG_SYSFS_DEPRECATED_V2=y
1841 +# CONFIG_RELAY is not set
1842 +# CONFIG_NAMESPACES is not set
1843 +CONFIG_BLK_DEV_INITRD=y
1844 +CONFIG_INITRAMFS_SOURCE=""
1845 +CONFIG_CC_OPTIMIZE_FOR_SIZE=y
1846 +CONFIG_SYSCTL=y
1847 +CONFIG_EMBEDDED=y
1848 +CONFIG_UID16=y
1849 +# CONFIG_SYSCTL_SYSCALL is not set
1850 +CONFIG_KALLSYMS=y
1851 +# CONFIG_KALLSYMS_ALL is not set
1852 +# CONFIG_KALLSYMS_EXTRA_PASS is not set
1853 +CONFIG_HOTPLUG=y
1854 +CONFIG_PRINTK=y
1855 +CONFIG_BUG=y
1856 +# CONFIG_ELF_CORE is not set
1857 +# CONFIG_COMPAT_BRK is not set
1858 +CONFIG_BASE_FULL=y
1859 +CONFIG_FUTEX=y
1860 +CONFIG_ANON_INODES=y
1861 +CONFIG_EPOLL=y
1862 +CONFIG_SIGNALFD=y
1863 +CONFIG_TIMERFD=y
1864 +CONFIG_EVENTFD=y
1865 +CONFIG_SHMEM=y
1866 +CONFIG_AIO=y
1867 +CONFIG_VM_EVENT_COUNTERS=y
1868 +CONFIG_SLUB_DEBUG=y
1869 +# CONFIG_SLAB is not set
1870 +CONFIG_SLUB=y
1871 +# CONFIG_SLOB is not set
1872 +CONFIG_PROFILING=y
1873 +CONFIG_TRACEPOINTS=y
1874 +# CONFIG_MARKERS is not set
1875 +CONFIG_OPROFILE=y
1876 +CONFIG_HAVE_OPROFILE=y
1877 +# CONFIG_KPROBES is not set
1878 +CONFIG_HAVE_KPROBES=y
1879 +CONFIG_HAVE_KRETPROBES=y
1880 +CONFIG_HAVE_CLK=y
1881 +CONFIG_HAVE_GENERIC_DMA_COHERENT=y
1882 +CONFIG_SLABINFO=y
1883 +CONFIG_RT_MUTEXES=y
1884 +CONFIG_BASE_SMALL=0
1885 +CONFIG_MODULES=y
1886 +# CONFIG_MODULE_FORCE_LOAD is not set
1887 +CONFIG_MODULE_UNLOAD=y
1888 +CONFIG_MODULE_FORCE_UNLOAD=y
1889 +CONFIG_MODVERSIONS=y
1890 +CONFIG_MODULE_SRCVERSION_ALL=y
1891 +CONFIG_BLOCK=y
1892 +CONFIG_LBD=y
1893 +# CONFIG_BLK_DEV_IO_TRACE is not set
1894 +# CONFIG_BLK_DEV_BSG is not set
1895 +# CONFIG_BLK_DEV_INTEGRITY is not set
1898 +# IO Schedulers
1900 +CONFIG_IOSCHED_NOOP=y
1901 +CONFIG_IOSCHED_AS=y
1902 +CONFIG_IOSCHED_DEADLINE=y
1903 +CONFIG_IOSCHED_CFQ=y
1904 +# CONFIG_DEFAULT_AS is not set
1905 +# CONFIG_DEFAULT_DEADLINE is not set
1906 +CONFIG_DEFAULT_CFQ=y
1907 +# CONFIG_DEFAULT_NOOP is not set
1908 +CONFIG_DEFAULT_IOSCHED="cfq"
1909 +CONFIG_FREEZER=y
1912 +# System Type
1914 +# CONFIG_ARCH_AAEC2000 is not set
1915 +# CONFIG_ARCH_INTEGRATOR is not set
1916 +# CONFIG_ARCH_REALVIEW is not set
1917 +# CONFIG_ARCH_VERSATILE is not set
1918 +# CONFIG_ARCH_AT91 is not set
1919 +# CONFIG_ARCH_CLPS711X is not set
1920 +# CONFIG_ARCH_EBSA110 is not set
1921 +# CONFIG_ARCH_EP93XX is not set
1922 +# CONFIG_ARCH_FOOTBRIDGE is not set
1923 +# CONFIG_ARCH_NETX is not set
1924 +# CONFIG_ARCH_H720X is not set
1925 +# CONFIG_ARCH_IMX is not set
1926 +# CONFIG_ARCH_IOP13XX is not set
1927 +# CONFIG_ARCH_IOP32X is not set
1928 +# CONFIG_ARCH_IOP33X is not set
1929 +# CONFIG_ARCH_IXP23XX is not set
1930 +# CONFIG_ARCH_IXP2000 is not set
1931 +# CONFIG_ARCH_IXP4XX is not set
1932 +# CONFIG_ARCH_L7200 is not set
1933 +# CONFIG_ARCH_KIRKWOOD is not set
1934 +# CONFIG_ARCH_KS8695 is not set
1935 +# CONFIG_ARCH_NS9XXX is not set
1936 +# CONFIG_ARCH_LOKI is not set
1937 +# CONFIG_ARCH_MV78XX0 is not set
1938 +# CONFIG_ARCH_MXC is not set
1939 +# CONFIG_ARCH_ORION5X is not set
1940 +# CONFIG_ARCH_PNX4008 is not set
1941 +# CONFIG_ARCH_PXA is not set
1942 +# CONFIG_ARCH_RPC is not set
1943 +# CONFIG_ARCH_SA1100 is not set
1944 +# CONFIG_ARCH_S3C2410 is not set
1945 +# CONFIG_ARCH_S3C64XX is not set
1946 +# CONFIG_ARCH_SHARK is not set
1947 +# CONFIG_ARCH_LH7A40X is not set
1948 +# CONFIG_ARCH_DAVINCI is not set
1949 +CONFIG_ARCH_OMAP=y
1950 +# CONFIG_ARCH_MSM is not set
1951 +# CONFIG_ARCH_W90X900 is not set
1954 +# TI OMAP Implementations
1956 +CONFIG_ARCH_OMAP_OTG=y
1957 +# CONFIG_ARCH_OMAP1 is not set
1958 +# CONFIG_ARCH_OMAP2 is not set
1959 +CONFIG_ARCH_OMAP3=y
1962 +# OMAP Feature Selections
1964 +# CONFIG_OMAP_DEBUG_POWERDOMAIN is not set
1965 +# CONFIG_OMAP_DEBUG_CLOCKDOMAIN is not set
1966 +CONFIG_OMAP_SMARTREFLEX=y
1967 +# CONFIG_OMAP_SMARTREFLEX_TESTING is not set
1968 +# CONFIG_OMAP_RESET_CLOCKS is not set
1969 +CONFIG_OMAP_BOOT_TAG=y
1970 +CONFIG_OMAP_BOOT_REASON=y
1971 +# CONFIG_OMAP_COMPONENT_VERSION is not set
1972 +# CONFIG_OMAP_GPIO_SWITCH is not set
1973 +# CONFIG_OMAP_MUX is not set
1974 +CONFIG_OMAP_MCBSP=y
1975 +# CONFIG_OMAP_MBOX_FWK is not set
1976 +# CONFIG_OMAP_MPU_TIMER is not set
1977 +CONFIG_OMAP_32K_TIMER=y
1978 +CONFIG_OMAP_32K_TIMER_HZ=128
1979 +CONFIG_OMAP_TICK_GPTIMER=1
1980 +CONFIG_OMAP_DM_TIMER=y
1981 +# CONFIG_OMAP_LL_DEBUG_UART1 is not set
1982 +# CONFIG_OMAP_LL_DEBUG_UART2 is not set
1983 +CONFIG_OMAP_LL_DEBUG_UART3=y
1984 +CONFIG_ARCH_OMAP34XX=y
1985 +CONFIG_ARCH_OMAP3430=y
1988 +# OMAP Board Type
1990 +# CONFIG_MACH_NOKIA_RX51 is not set
1991 +# CONFIG_MACH_OMAP_LDP is not set
1992 +# CONFIG_MACH_OMAP_3430SDP is not set
1993 +# CONFIG_MACH_OMAP3EVM is not set
1994 +# CONFIG_MACH_OMAP3_BEAGLE is not set
1995 +CONFIG_MACH_OVERO=y
1996 +# CONFIG_MACH_OMAP3_PANDORA is not set
1999 +# Processor Type
2001 +CONFIG_CPU_32=y
2002 +CONFIG_CPU_32v6K=y
2003 +CONFIG_CPU_V7=y
2004 +CONFIG_CPU_32v7=y
2005 +CONFIG_CPU_ABRT_EV7=y
2006 +CONFIG_CPU_PABRT_IFAR=y
2007 +CONFIG_CPU_CACHE_V7=y
2008 +CONFIG_CPU_CACHE_VIPT=y
2009 +CONFIG_CPU_COPY_V6=y
2010 +CONFIG_CPU_TLB_V7=y
2011 +CONFIG_CPU_HAS_ASID=y
2012 +CONFIG_CPU_CP15=y
2013 +CONFIG_CPU_CP15_MMU=y
2016 +# Processor Features
2018 +CONFIG_ARM_THUMB=y
2019 +CONFIG_ARM_THUMBEE=y
2020 +# CONFIG_CPU_ICACHE_DISABLE is not set
2021 +# CONFIG_CPU_DCACHE_DISABLE is not set
2022 +# CONFIG_CPU_BPREDICT_DISABLE is not set
2023 +CONFIG_HAS_TLS_REG=y
2024 +# CONFIG_OUTER_CACHE is not set
2027 +# Bus support
2029 +# CONFIG_PCI_SYSCALL is not set
2030 +# CONFIG_ARCH_SUPPORTS_MSI is not set
2031 +# CONFIG_PCCARD is not set
2034 +# Kernel Features
2036 +CONFIG_TICK_ONESHOT=y
2037 +CONFIG_NO_HZ=y
2038 +CONFIG_HIGH_RES_TIMERS=y
2039 +CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
2040 +CONFIG_VMSPLIT_3G=y
2041 +# CONFIG_VMSPLIT_2G is not set
2042 +# CONFIG_VMSPLIT_1G is not set
2043 +CONFIG_PAGE_OFFSET=0xC0000000
2044 +# CONFIG_PREEMPT is not set
2045 +CONFIG_HZ=128
2046 +CONFIG_AEABI=y
2047 +# CONFIG_OABI_COMPAT is not set
2048 +CONFIG_ARCH_FLATMEM_HAS_HOLES=y
2049 +# CONFIG_ARCH_SPARSEMEM_DEFAULT is not set
2050 +# CONFIG_ARCH_SELECT_MEMORY_MODEL is not set
2051 +CONFIG_SELECT_MEMORY_MODEL=y
2052 +CONFIG_FLATMEM_MANUAL=y
2053 +# CONFIG_DISCONTIGMEM_MANUAL is not set
2054 +# CONFIG_SPARSEMEM_MANUAL is not set
2055 +CONFIG_FLATMEM=y
2056 +CONFIG_FLAT_NODE_MEM_MAP=y
2057 +CONFIG_PAGEFLAGS_EXTENDED=y
2058 +CONFIG_SPLIT_PTLOCK_CPUS=4
2059 +# CONFIG_PHYS_ADDR_T_64BIT is not set
2060 +CONFIG_ZONE_DMA_FLAG=0
2061 +CONFIG_VIRT_TO_BUS=y
2062 +CONFIG_UNEVICTABLE_LRU=y
2063 +CONFIG_LEDS=y
2064 +CONFIG_ALIGNMENT_TRAP=y
2067 +# Boot options
2069 +CONFIG_ZBOOT_ROM_TEXT=0x0
2070 +CONFIG_ZBOOT_ROM_BSS=0x0
2071 +CONFIG_CMDLINE=" debug "
2072 +# CONFIG_XIP_KERNEL is not set
2073 +CONFIG_KEXEC=y
2074 +CONFIG_ATAGS_PROC=y
2077 +# CPU Power Management
2079 +CONFIG_CPU_FREQ=y
2080 +CONFIG_CPU_FREQ_TABLE=y
2081 +# CONFIG_CPU_FREQ_DEBUG is not set
2082 +CONFIG_CPU_FREQ_STAT=y
2083 +CONFIG_CPU_FREQ_STAT_DETAILS=y
2084 +CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
2085 +# CONFIG_CPU_FREQ_DEFAULT_GOV_POWERSAVE is not set
2086 +# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
2087 +# CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND is not set
2088 +# CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE is not set
2089 +CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
2090 +# CONFIG_CPU_FREQ_GOV_POWERSAVE is not set
2091 +CONFIG_CPU_FREQ_GOV_USERSPACE=y
2092 +CONFIG_CPU_FREQ_GOV_ONDEMAND=y
2093 +# CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set
2094 +# CONFIG_CPU_IDLE is not set
2097 +# Floating point emulation
2101 +# At least one emulation must be selected
2103 +CONFIG_VFP=y
2104 +CONFIG_VFPv3=y
2105 +CONFIG_NEON=y
2108 +# Userspace binary formats
2110 +CONFIG_BINFMT_ELF=y
2111 +CONFIG_HAVE_AOUT=y
2112 +CONFIG_BINFMT_AOUT=m
2113 +CONFIG_BINFMT_MISC=y
2116 +# Power management options
2118 +CONFIG_PM=y
2119 +CONFIG_PM_DEBUG=y
2120 +# CONFIG_PM_VERBOSE is not set
2121 +CONFIG_CAN_PM_TRACE=y
2122 +CONFIG_PM_SLEEP=y
2123 +CONFIG_SUSPEND=y
2124 +# CONFIG_PM_TEST_SUSPEND is not set
2125 +CONFIG_SUSPEND_FREEZER=y
2126 +# CONFIG_APM_EMULATION is not set
2127 +CONFIG_ARCH_SUSPEND_POSSIBLE=y
2128 +CONFIG_NET=y
2131 +# Networking options
2133 +CONFIG_COMPAT_NET_DEV_OPS=y
2134 +CONFIG_PACKET=y
2135 +CONFIG_PACKET_MMAP=y
2136 +CONFIG_UNIX=y
2137 +CONFIG_XFRM=y
2138 +# CONFIG_XFRM_USER is not set
2139 +# CONFIG_XFRM_SUB_POLICY is not set
2140 +# CONFIG_XFRM_MIGRATE is not set
2141 +# CONFIG_XFRM_STATISTICS is not set
2142 +CONFIG_NET_KEY=y
2143 +# CONFIG_NET_KEY_MIGRATE is not set
2144 +CONFIG_INET=y
2145 +# CONFIG_IP_MULTICAST is not set
2146 +# CONFIG_IP_ADVANCED_ROUTER is not set
2147 +CONFIG_IP_FIB_HASH=y
2148 +CONFIG_IP_PNP=y
2149 +CONFIG_IP_PNP_DHCP=y
2150 +CONFIG_IP_PNP_BOOTP=y
2151 +CONFIG_IP_PNP_RARP=y
2152 +# CONFIG_NET_IPIP is not set
2153 +# CONFIG_NET_IPGRE is not set
2154 +# CONFIG_ARPD is not set
2155 +# CONFIG_SYN_COOKIES is not set
2156 +# CONFIG_INET_AH is not set
2157 +# CONFIG_INET_ESP is not set
2158 +# CONFIG_INET_IPCOMP is not set
2159 +# CONFIG_INET_XFRM_TUNNEL is not set
2160 +CONFIG_INET_TUNNEL=m
2161 +CONFIG_INET_XFRM_MODE_TRANSPORT=y
2162 +CONFIG_INET_XFRM_MODE_TUNNEL=y
2163 +CONFIG_INET_XFRM_MODE_BEET=y
2164 +# CONFIG_INET_LRO is not set
2165 +CONFIG_INET_DIAG=y
2166 +CONFIG_INET_TCP_DIAG=y
2167 +# CONFIG_TCP_CONG_ADVANCED is not set
2168 +CONFIG_TCP_CONG_CUBIC=y
2169 +CONFIG_DEFAULT_TCP_CONG="cubic"
2170 +# CONFIG_TCP_MD5SIG is not set
2171 +CONFIG_IPV6=m
2172 +# CONFIG_IPV6_PRIVACY is not set
2173 +# CONFIG_IPV6_ROUTER_PREF is not set
2174 +# CONFIG_IPV6_OPTIMISTIC_DAD is not set
2175 +# CONFIG_INET6_AH is not set
2176 +# CONFIG_INET6_ESP is not set
2177 +# CONFIG_INET6_IPCOMP is not set
2178 +# CONFIG_IPV6_MIP6 is not set
2179 +# CONFIG_INET6_XFRM_TUNNEL is not set
2180 +# CONFIG_INET6_TUNNEL is not set
2181 +CONFIG_INET6_XFRM_MODE_TRANSPORT=m
2182 +CONFIG_INET6_XFRM_MODE_TUNNEL=m
2183 +CONFIG_INET6_XFRM_MODE_BEET=m
2184 +# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
2185 +CONFIG_IPV6_SIT=m
2186 +CONFIG_IPV6_NDISC_NODETYPE=y
2187 +# CONFIG_IPV6_TUNNEL is not set
2188 +# CONFIG_IPV6_MULTIPLE_TABLES is not set
2189 +# CONFIG_IPV6_MROUTE is not set
2190 +# CONFIG_NETWORK_SECMARK is not set
2191 +# CONFIG_NETFILTER is not set
2192 +# CONFIG_IP_DCCP is not set
2193 +# CONFIG_IP_SCTP is not set
2194 +# CONFIG_TIPC is not set
2195 +# CONFIG_ATM is not set
2196 +# CONFIG_BRIDGE is not set
2197 +# CONFIG_NET_DSA is not set
2198 +# CONFIG_VLAN_8021Q is not set
2199 +# CONFIG_DECNET is not set
2200 +# CONFIG_LLC2 is not set
2201 +# CONFIG_IPX is not set
2202 +# CONFIG_ATALK is not set
2203 +# CONFIG_X25 is not set
2204 +# CONFIG_LAPB is not set
2205 +# CONFIG_ECONET is not set
2206 +# CONFIG_WAN_ROUTER is not set
2207 +# CONFIG_NET_SCHED is not set
2208 +# CONFIG_DCB is not set
2211 +# Network testing
2213 +# CONFIG_NET_PKTGEN is not set
2214 +# CONFIG_HAMRADIO is not set
2215 +# CONFIG_CAN is not set
2216 +# CONFIG_IRDA is not set
2217 +CONFIG_BT=y
2218 +CONFIG_BT_L2CAP=y
2219 +CONFIG_BT_SCO=y
2220 +CONFIG_BT_RFCOMM=y
2221 +CONFIG_BT_RFCOMM_TTY=y
2222 +CONFIG_BT_BNEP=y
2223 +CONFIG_BT_BNEP_MC_FILTER=y
2224 +CONFIG_BT_BNEP_PROTO_FILTER=y
2225 +CONFIG_BT_HIDP=y
2228 +# Bluetooth device drivers
2230 +# CONFIG_BT_HCIBTSDIO is not set
2231 +CONFIG_BT_HCIUART=y
2232 +CONFIG_BT_HCIUART_H4=y
2233 +CONFIG_BT_HCIUART_BCSP=y
2234 +# CONFIG_BT_HCIUART_LL is not set
2235 +# CONFIG_BT_HCIBRF6150 is not set
2236 +# CONFIG_BT_HCIH4P is not set
2237 +# CONFIG_BT_HCIVHCI is not set
2238 +# CONFIG_AF_RXRPC is not set
2239 +# CONFIG_PHONET is not set
2240 +CONFIG_WIRELESS=y
2241 +CONFIG_CFG80211=y
2242 +# CONFIG_CFG80211_REG_DEBUG is not set
2243 +CONFIG_NL80211=y
2244 +CONFIG_WIRELESS_OLD_REGULATORY=y
2245 +CONFIG_WIRELESS_EXT=y
2246 +CONFIG_WIRELESS_EXT_SYSFS=y
2247 +CONFIG_LIB80211=y
2248 +CONFIG_LIB80211_CRYPT_WEP=m
2249 +CONFIG_LIB80211_CRYPT_CCMP=m
2250 +CONFIG_LIB80211_CRYPT_TKIP=m
2251 +CONFIG_MAC80211=y
2254 +# Rate control algorithm selection
2256 +CONFIG_MAC80211_RC_PID=y
2257 +CONFIG_MAC80211_RC_MINSTREL=y
2258 +CONFIG_MAC80211_RC_DEFAULT_PID=y
2259 +# CONFIG_MAC80211_RC_DEFAULT_MINSTREL is not set
2260 +CONFIG_MAC80211_RC_DEFAULT="pid"
2261 +# CONFIG_MAC80211_MESH is not set
2262 +CONFIG_MAC80211_LEDS=y
2263 +# CONFIG_MAC80211_DEBUGFS is not set
2264 +# CONFIG_MAC80211_DEBUG_MENU is not set
2265 +# CONFIG_WIMAX is not set
2266 +# CONFIG_RFKILL is not set
2267 +# CONFIG_NET_9P is not set
2270 +# Device Drivers
2274 +# Generic Driver Options
2276 +CONFIG_UEVENT_HELPER_PATH="/sbin/hotplug"
2277 +CONFIG_STANDALONE=y
2278 +CONFIG_PREVENT_FIRMWARE_BUILD=y
2279 +CONFIG_FW_LOADER=y
2280 +CONFIG_FIRMWARE_IN_KERNEL=y
2281 +CONFIG_EXTRA_FIRMWARE=""
2282 +# CONFIG_DEBUG_DRIVER is not set
2283 +# CONFIG_DEBUG_DEVRES is not set
2284 +# CONFIG_SYS_HYPERVISOR is not set
2285 +# CONFIG_CONNECTOR is not set
2286 +CONFIG_MTD=y
2287 +# CONFIG_MTD_DEBUG is not set
2288 +CONFIG_MTD_CONCAT=y
2289 +CONFIG_MTD_PARTITIONS=y
2290 +# CONFIG_MTD_TESTS is not set
2291 +# CONFIG_MTD_REDBOOT_PARTS is not set
2292 +# CONFIG_MTD_CMDLINE_PARTS is not set
2293 +# CONFIG_MTD_AFS_PARTS is not set
2294 +# CONFIG_MTD_AR7_PARTS is not set
2297 +# User Modules And Translation Layers
2299 +CONFIG_MTD_CHAR=y
2300 +CONFIG_MTD_BLKDEVS=y
2301 +CONFIG_MTD_BLOCK=y
2302 +# CONFIG_FTL is not set
2303 +# CONFIG_NFTL is not set
2304 +# CONFIG_INFTL is not set
2305 +# CONFIG_RFD_FTL is not set
2306 +# CONFIG_SSFDC is not set
2307 +# CONFIG_MTD_OOPS is not set
2310 +# RAM/ROM/Flash chip drivers
2312 +# CONFIG_MTD_CFI is not set
2313 +# CONFIG_MTD_JEDECPROBE is not set
2314 +CONFIG_MTD_MAP_BANK_WIDTH_1=y
2315 +CONFIG_MTD_MAP_BANK_WIDTH_2=y
2316 +CONFIG_MTD_MAP_BANK_WIDTH_4=y
2317 +# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
2318 +# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
2319 +# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
2320 +CONFIG_MTD_CFI_I1=y
2321 +CONFIG_MTD_CFI_I2=y
2322 +# CONFIG_MTD_CFI_I4 is not set
2323 +# CONFIG_MTD_CFI_I8 is not set
2324 +# CONFIG_MTD_RAM is not set
2325 +# CONFIG_MTD_ROM is not set
2326 +# CONFIG_MTD_ABSENT is not set
2329 +# Mapping drivers for chip access
2331 +# CONFIG_MTD_COMPLEX_MAPPINGS is not set
2332 +# CONFIG_MTD_PLATRAM is not set
2335 +# Self-contained MTD device drivers
2337 +# CONFIG_MTD_DATAFLASH is not set
2338 +# CONFIG_MTD_M25P80 is not set
2339 +# CONFIG_MTD_SLRAM is not set
2340 +# CONFIG_MTD_PHRAM is not set
2341 +# CONFIG_MTD_MTDRAM is not set
2342 +# CONFIG_MTD_BLOCK2MTD is not set
2345 +# Disk-On-Chip Device Drivers
2347 +# CONFIG_MTD_DOC2000 is not set
2348 +# CONFIG_MTD_DOC2001 is not set
2349 +# CONFIG_MTD_DOC2001PLUS is not set
2350 +CONFIG_MTD_NAND=y
2351 +# CONFIG_MTD_NAND_VERIFY_WRITE is not set
2352 +# CONFIG_MTD_NAND_ECC_SMC is not set
2353 +# CONFIG_MTD_NAND_MUSEUM_IDS is not set
2354 +# CONFIG_MTD_NAND_GPIO is not set
2355 +CONFIG_MTD_NAND_OMAP2=y
2356 +CONFIG_MTD_NAND_IDS=y
2357 +# CONFIG_MTD_NAND_DISKONCHIP is not set
2358 +# CONFIG_MTD_NAND_NANDSIM is not set
2359 +# CONFIG_MTD_NAND_PLATFORM is not set
2360 +# CONFIG_MTD_ONENAND is not set
2363 +# LPDDR flash memory drivers
2365 +# CONFIG_MTD_LPDDR is not set
2366 +# CONFIG_MTD_QINFO_PROBE is not set
2369 +# UBI - Unsorted block images
2371 +# CONFIG_MTD_UBI is not set
2372 +# CONFIG_PARPORT is not set
2373 +CONFIG_BLK_DEV=y
2374 +# CONFIG_BLK_DEV_COW_COMMON is not set
2375 +CONFIG_BLK_DEV_LOOP=y
2376 +CONFIG_BLK_DEV_CRYPTOLOOP=m
2377 +# CONFIG_BLK_DEV_NBD is not set
2378 +CONFIG_BLK_DEV_RAM=y
2379 +CONFIG_BLK_DEV_RAM_COUNT=16
2380 +CONFIG_BLK_DEV_RAM_SIZE=16384
2381 +# CONFIG_BLK_DEV_XIP is not set
2382 +CONFIG_CDROM_PKTCDVD=m
2383 +CONFIG_CDROM_PKTCDVD_BUFFERS=8
2384 +# CONFIG_CDROM_PKTCDVD_WCACHE is not set
2385 +# CONFIG_ATA_OVER_ETH is not set
2386 +CONFIG_MISC_DEVICES=y
2387 +# CONFIG_ICS932S401 is not set
2388 +# CONFIG_OMAP_STI is not set
2389 +# CONFIG_ENCLOSURE_SERVICES is not set
2390 +# CONFIG_C2PORT is not set
2393 +# EEPROM support
2395 +# CONFIG_EEPROM_AT24 is not set
2396 +# CONFIG_EEPROM_AT25 is not set
2397 +# CONFIG_EEPROM_LEGACY is not set
2398 +CONFIG_EEPROM_93CX6=m
2399 +CONFIG_HAVE_IDE=y
2400 +# CONFIG_IDE is not set
2403 +# SCSI device support
2405 +CONFIG_RAID_ATTRS=m
2406 +CONFIG_SCSI=y
2407 +CONFIG_SCSI_DMA=y
2408 +# CONFIG_SCSI_TGT is not set
2409 +# CONFIG_SCSI_NETLINK is not set
2410 +CONFIG_SCSI_PROC_FS=y
2413 +# SCSI support type (disk, tape, CD-ROM)
2415 +CONFIG_BLK_DEV_SD=y
2416 +# CONFIG_CHR_DEV_ST is not set
2417 +# CONFIG_CHR_DEV_OSST is not set
2418 +# CONFIG_BLK_DEV_SR is not set
2419 +CONFIG_CHR_DEV_SG=m
2420 +# CONFIG_CHR_DEV_SCH is not set
2423 +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
2425 +CONFIG_SCSI_MULTI_LUN=y
2426 +# CONFIG_SCSI_CONSTANTS is not set
2427 +# CONFIG_SCSI_LOGGING is not set
2428 +# CONFIG_SCSI_SCAN_ASYNC is not set
2429 +CONFIG_SCSI_WAIT_SCAN=m
2432 +# SCSI Transports
2434 +# CONFIG_SCSI_SPI_ATTRS is not set
2435 +# CONFIG_SCSI_FC_ATTRS is not set
2436 +# CONFIG_SCSI_ISCSI_ATTRS is not set
2437 +# CONFIG_SCSI_SAS_LIBSAS is not set
2438 +# CONFIG_SCSI_SRP_ATTRS is not set
2439 +CONFIG_SCSI_LOWLEVEL=y
2440 +# CONFIG_ISCSI_TCP is not set
2441 +# CONFIG_LIBFC is not set
2442 +# CONFIG_SCSI_DEBUG is not set
2443 +# CONFIG_SCSI_DH is not set
2444 +# CONFIG_ATA is not set
2445 +CONFIG_MD=y
2446 +CONFIG_BLK_DEV_MD=m
2447 +CONFIG_MD_LINEAR=m
2448 +CONFIG_MD_RAID0=m
2449 +CONFIG_MD_RAID1=m
2450 +CONFIG_MD_RAID10=m
2451 +CONFIG_MD_RAID456=m
2452 +CONFIG_MD_RAID5_RESHAPE=y
2453 +CONFIG_MD_MULTIPATH=m
2454 +CONFIG_MD_FAULTY=m
2455 +CONFIG_BLK_DEV_DM=m
2456 +# CONFIG_DM_DEBUG is not set
2457 +CONFIG_DM_CRYPT=m
2458 +CONFIG_DM_SNAPSHOT=m
2459 +CONFIG_DM_MIRROR=m
2460 +CONFIG_DM_ZERO=m
2461 +CONFIG_DM_MULTIPATH=m
2462 +CONFIG_DM_DELAY=m
2463 +# CONFIG_DM_UEVENT is not set
2464 +CONFIG_NETDEVICES=y
2465 +CONFIG_DUMMY=m
2466 +# CONFIG_BONDING is not set
2467 +# CONFIG_MACVLAN is not set
2468 +# CONFIG_EQUALIZER is not set
2469 +CONFIG_TUN=m
2470 +# CONFIG_VETH is not set
2471 +# CONFIG_NET_ETHERNET is not set
2472 +# CONFIG_NETDEV_1000 is not set
2473 +# CONFIG_NETDEV_10000 is not set
2476 +# Wireless LAN
2478 +# CONFIG_WLAN_PRE80211 is not set
2479 +CONFIG_WLAN_80211=y
2480 +CONFIG_LIBERTAS=y
2481 +CONFIG_LIBERTAS_SDIO=y
2482 +CONFIG_LIBERTAS_DEBUG=y
2483 +# CONFIG_LIBERTAS_THINFIRM is not set
2484 +# CONFIG_MAC80211_HWSIM is not set
2485 +CONFIG_P54_COMMON=m
2486 +# CONFIG_IWLWIFI_LEDS is not set
2487 +CONFIG_HOSTAP=m
2488 +CONFIG_HOSTAP_FIRMWARE=y
2489 +CONFIG_HOSTAP_FIRMWARE_NVRAM=y
2490 +# CONFIG_B43 is not set
2491 +# CONFIG_B43LEGACY is not set
2492 +# CONFIG_RT2X00 is not set
2495 +# Enable WiMAX (Networking options) to see the WiMAX drivers
2497 +# CONFIG_WAN is not set
2498 +CONFIG_PPP=m
2499 +# CONFIG_PPP_MULTILINK is not set
2500 +# CONFIG_PPP_FILTER is not set
2501 +CONFIG_PPP_ASYNC=m
2502 +CONFIG_PPP_SYNC_TTY=m
2503 +CONFIG_PPP_DEFLATE=m
2504 +CONFIG_PPP_BSDCOMP=m
2505 +CONFIG_PPP_MPPE=m
2506 +CONFIG_PPPOE=m
2507 +# CONFIG_PPPOL2TP is not set
2508 +# CONFIG_SLIP is not set
2509 +CONFIG_SLHC=m
2510 +# CONFIG_NETCONSOLE is not set
2511 +# CONFIG_NETPOLL is not set
2512 +# CONFIG_NET_POLL_CONTROLLER is not set
2513 +# CONFIG_ISDN is not set
2516 +# Input device support
2518 +CONFIG_INPUT=y
2519 +# CONFIG_INPUT_FF_MEMLESS is not set
2520 +# CONFIG_INPUT_POLLDEV is not set
2523 +# Userland interfaces
2525 +CONFIG_INPUT_MOUSEDEV=y
2526 +CONFIG_INPUT_MOUSEDEV_PSAUX=y
2527 +CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
2528 +CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
2529 +# CONFIG_INPUT_JOYDEV is not set
2530 +CONFIG_INPUT_EVDEV=y
2531 +# CONFIG_INPUT_EVBUG is not set
2534 +# Input Device Drivers
2536 +CONFIG_INPUT_KEYBOARD=y
2537 +# CONFIG_KEYBOARD_ATKBD is not set
2538 +# CONFIG_KEYBOARD_SUNKBD is not set
2539 +# CONFIG_KEYBOARD_LKKBD is not set
2540 +# CONFIG_KEYBOARD_XTKBD is not set
2541 +# CONFIG_KEYBOARD_NEWTON is not set
2542 +# CONFIG_KEYBOARD_STOWAWAY is not set
2543 +# CONFIG_KEYBOARD_TWL4030 is not set
2544 +# CONFIG_KEYBOARD_LM8323 is not set
2545 +# CONFIG_KEYBOARD_GPIO is not set
2546 +CONFIG_INPUT_MOUSE=y
2547 +CONFIG_MOUSE_PS2=y
2548 +CONFIG_MOUSE_PS2_ALPS=y
2549 +CONFIG_MOUSE_PS2_LOGIPS2PP=y
2550 +CONFIG_MOUSE_PS2_SYNAPTICS=y
2551 +CONFIG_MOUSE_PS2_LIFEBOOK=y
2552 +CONFIG_MOUSE_PS2_TRACKPOINT=y
2553 +# CONFIG_MOUSE_PS2_ELANTECH is not set
2554 +# CONFIG_MOUSE_PS2_TOUCHKIT is not set
2555 +# CONFIG_MOUSE_SERIAL is not set
2556 +# CONFIG_MOUSE_APPLETOUCH is not set
2557 +# CONFIG_MOUSE_BCM5974 is not set
2558 +# CONFIG_MOUSE_VSXXXAA is not set
2559 +# CONFIG_MOUSE_GPIO is not set
2560 +# CONFIG_INPUT_JOYSTICK is not set
2561 +# CONFIG_INPUT_TABLET is not set
2562 +# CONFIG_INPUT_TOUCHSCREEN is not set
2563 +# CONFIG_INPUT_MISC is not set
2566 +# Hardware I/O ports
2568 +CONFIG_SERIO=y
2569 +CONFIG_SERIO_SERPORT=y
2570 +CONFIG_SERIO_LIBPS2=y
2571 +# CONFIG_SERIO_RAW is not set
2572 +# CONFIG_GAMEPORT is not set
2575 +# Character devices
2577 +CONFIG_VT=y
2578 +CONFIG_CONSOLE_TRANSLATIONS=y
2579 +CONFIG_VT_CONSOLE=y
2580 +CONFIG_HW_CONSOLE=y
2581 +CONFIG_VT_HW_CONSOLE_BINDING=y
2582 +CONFIG_DEVKMEM=y
2583 +# CONFIG_SERIAL_NONSTANDARD is not set
2586 +# Serial drivers
2588 +CONFIG_SERIAL_8250=y
2589 +CONFIG_SERIAL_8250_CONSOLE=y
2590 +CONFIG_SERIAL_8250_NR_UARTS=32
2591 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4
2592 +CONFIG_SERIAL_8250_EXTENDED=y
2593 +CONFIG_SERIAL_8250_MANY_PORTS=y
2594 +CONFIG_SERIAL_8250_SHARE_IRQ=y
2595 +CONFIG_SERIAL_8250_DETECT_IRQ=y
2596 +CONFIG_SERIAL_8250_RSA=y
2599 +# Non-8250 serial port support
2601 +CONFIG_SERIAL_CORE=y
2602 +CONFIG_SERIAL_CORE_CONSOLE=y
2603 +CONFIG_UNIX98_PTYS=y
2604 +# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
2605 +# CONFIG_LEGACY_PTYS is not set
2606 +# CONFIG_IPMI_HANDLER is not set
2607 +CONFIG_HW_RANDOM=y
2608 +# CONFIG_NVRAM is not set
2609 +# CONFIG_R3964 is not set
2610 +# CONFIG_RAW_DRIVER is not set
2611 +# CONFIG_TCG_TPM is not set
2612 +CONFIG_I2C=y
2613 +CONFIG_I2C_BOARDINFO=y
2614 +CONFIG_I2C_CHARDEV=y
2615 +CONFIG_I2C_HELPER_AUTO=y
2618 +# I2C Hardware Bus support
2622 +# I2C system bus drivers (mostly embedded / system-on-chip)
2624 +# CONFIG_I2C_GPIO is not set
2625 +# CONFIG_I2C_OCORES is not set
2626 +CONFIG_I2C_OMAP=y
2627 +# CONFIG_I2C_SIMTEC is not set
2630 +# External I2C/SMBus adapter drivers
2632 +# CONFIG_I2C_PARPORT_LIGHT is not set
2633 +# CONFIG_I2C_TAOS_EVM is not set
2636 +# Other I2C/SMBus bus drivers
2638 +# CONFIG_I2C_PCA_PLATFORM is not set
2639 +# CONFIG_I2C_STUB is not set
2642 +# Miscellaneous I2C Chip support
2644 +# CONFIG_DS1682 is not set
2645 +# CONFIG_SENSORS_PCF8574 is not set
2646 +# CONFIG_PCF8575 is not set
2647 +# CONFIG_SENSORS_PCA9539 is not set
2648 +# CONFIG_SENSORS_PCF8591 is not set
2649 +CONFIG_TWL4030_MADC=m
2650 +CONFIG_TWL4030_PWRBUTTON=y
2651 +CONFIG_TWL4030_POWEROFF=y
2652 +# CONFIG_SENSORS_MAX6875 is not set
2653 +# CONFIG_SENSORS_TSL2550 is not set
2654 +# CONFIG_SENSORS_TSL2563 is not set
2655 +# CONFIG_LP5521 is not set
2656 +# CONFIG_I2C_DEBUG_CORE is not set
2657 +# CONFIG_I2C_DEBUG_ALGO is not set
2658 +# CONFIG_I2C_DEBUG_BUS is not set
2659 +# CONFIG_I2C_DEBUG_CHIP is not set
2660 +CONFIG_SPI=y
2661 +# CONFIG_SPI_DEBUG is not set
2662 +CONFIG_SPI_MASTER=y
2665 +# SPI Master Controller Drivers
2667 +# CONFIG_SPI_BITBANG is not set
2668 +# CONFIG_SPI_GPIO is not set
2669 +CONFIG_SPI_OMAP24XX=y
2672 +# SPI Protocol Masters
2674 +# CONFIG_SPI_TSC210X is not set
2675 +# CONFIG_SPI_TSC2301 is not set
2676 +# CONFIG_SPI_SPIDEV is not set
2677 +# CONFIG_SPI_TLE62X0 is not set
2678 +CONFIG_ARCH_REQUIRE_GPIOLIB=y
2679 +CONFIG_GPIOLIB=y
2680 +CONFIG_DEBUG_GPIO=y
2681 +CONFIG_GPIO_SYSFS=y
2684 +# Memory mapped GPIO expanders:
2688 +# I2C GPIO expanders:
2690 +# CONFIG_GPIO_MAX732X is not set
2691 +# CONFIG_GPIO_PCA953X is not set
2692 +# CONFIG_GPIO_PCF857X is not set
2693 +CONFIG_GPIO_TWL4030=y
2696 +# PCI GPIO expanders:
2700 +# SPI GPIO expanders:
2702 +# CONFIG_GPIO_MAX7301 is not set
2703 +# CONFIG_GPIO_MCP23S08 is not set
2704 +# CONFIG_W1 is not set
2705 +CONFIG_POWER_SUPPLY=m
2706 +# CONFIG_POWER_SUPPLY_DEBUG is not set
2707 +# CONFIG_PDA_POWER is not set
2708 +# CONFIG_BATTERY_DS2760 is not set
2709 +# CONFIG_TWL4030_BCI_BATTERY is not set
2710 +# CONFIG_BATTERY_BQ27x00 is not set
2711 +CONFIG_HWMON=y
2712 +# CONFIG_HWMON_VID is not set
2713 +# CONFIG_SENSORS_AD7414 is not set
2714 +# CONFIG_SENSORS_AD7418 is not set
2715 +# CONFIG_SENSORS_ADCXX is not set
2716 +# CONFIG_SENSORS_ADM1021 is not set
2717 +# CONFIG_SENSORS_ADM1025 is not set
2718 +# CONFIG_SENSORS_ADM1026 is not set
2719 +# CONFIG_SENSORS_ADM1029 is not set
2720 +# CONFIG_SENSORS_ADM1031 is not set
2721 +# CONFIG_SENSORS_ADM9240 is not set
2722 +# CONFIG_SENSORS_ADT7462 is not set
2723 +# CONFIG_SENSORS_ADT7470 is not set
2724 +# CONFIG_SENSORS_ADT7473 is not set
2725 +# CONFIG_SENSORS_ADT7475 is not set
2726 +# CONFIG_SENSORS_ATXP1 is not set
2727 +# CONFIG_SENSORS_DS1621 is not set
2728 +# CONFIG_SENSORS_F71805F is not set
2729 +# CONFIG_SENSORS_F71882FG is not set
2730 +# CONFIG_SENSORS_F75375S is not set
2731 +# CONFIG_SENSORS_GL518SM is not set
2732 +# CONFIG_SENSORS_GL520SM is not set
2733 +# CONFIG_SENSORS_IT87 is not set
2734 +# CONFIG_SENSORS_LM63 is not set
2735 +# CONFIG_SENSORS_LM70 is not set
2736 +# CONFIG_SENSORS_LM75 is not set
2737 +# CONFIG_SENSORS_LM77 is not set
2738 +# CONFIG_SENSORS_LM78 is not set
2739 +# CONFIG_SENSORS_LM80 is not set
2740 +# CONFIG_SENSORS_LM83 is not set
2741 +# CONFIG_SENSORS_LM85 is not set
2742 +# CONFIG_SENSORS_LM87 is not set
2743 +# CONFIG_SENSORS_LM90 is not set
2744 +# CONFIG_SENSORS_LM92 is not set
2745 +# CONFIG_SENSORS_LM93 is not set
2746 +# CONFIG_SENSORS_LTC4245 is not set
2747 +# CONFIG_SENSORS_MAX1111 is not set
2748 +# CONFIG_SENSORS_MAX1619 is not set
2749 +# CONFIG_SENSORS_MAX6650 is not set
2750 +# CONFIG_SENSORS_PC87360 is not set
2751 +# CONFIG_SENSORS_PC87427 is not set
2752 +# CONFIG_SENSORS_DME1737 is not set
2753 +# CONFIG_SENSORS_SMSC47M1 is not set
2754 +# CONFIG_SENSORS_SMSC47M192 is not set
2755 +# CONFIG_SENSORS_SMSC47B397 is not set
2756 +# CONFIG_SENSORS_ADS7828 is not set
2757 +# CONFIG_SENSORS_THMC50 is not set
2758 +# CONFIG_SENSORS_VT1211 is not set
2759 +# CONFIG_SENSORS_W83781D is not set
2760 +# CONFIG_SENSORS_W83791D is not set
2761 +# CONFIG_SENSORS_W83792D is not set
2762 +# CONFIG_SENSORS_W83793 is not set
2763 +# CONFIG_SENSORS_W83L785TS is not set
2764 +# CONFIG_SENSORS_W83L786NG is not set
2765 +# CONFIG_SENSORS_W83627HF is not set
2766 +# CONFIG_SENSORS_W83627EHF is not set
2767 +# CONFIG_SENSORS_TSC210X is not set
2768 +CONFIG_SENSORS_OMAP34XX=y
2769 +# CONFIG_HWMON_DEBUG_CHIP is not set
2770 +# CONFIG_THERMAL is not set
2771 +# CONFIG_THERMAL_HWMON is not set
2772 +CONFIG_WATCHDOG=y
2773 +CONFIG_WATCHDOG_NOWAYOUT=y
2776 +# Watchdog Device Drivers
2778 +# CONFIG_SOFT_WATCHDOG is not set
2779 +CONFIG_OMAP_WATCHDOG=y
2780 +CONFIG_SSB_POSSIBLE=y
2783 +# Sonics Silicon Backplane
2785 +# CONFIG_SSB is not set
2788 +# Multifunction device drivers
2790 +# CONFIG_MFD_CORE is not set
2791 +# CONFIG_MFD_SM501 is not set
2792 +# CONFIG_MFD_ASIC3 is not set
2793 +# CONFIG_HTC_EGPIO is not set
2794 +# CONFIG_HTC_PASIC3 is not set
2795 +# CONFIG_TPS65010 is not set
2796 +CONFIG_TWL4030_CORE=y
2797 +# CONFIG_TWL4030_POWER is not set
2798 +# CONFIG_MFD_TMIO is not set
2799 +# CONFIG_MFD_T7L66XB is not set
2800 +# CONFIG_MFD_TC6387XB is not set
2801 +# CONFIG_MFD_TC6393XB is not set
2802 +# CONFIG_PMIC_DA903X is not set
2803 +# CONFIG_MFD_WM8400 is not set
2804 +# CONFIG_MFD_WM8350_I2C is not set
2805 +# CONFIG_MFD_PCF50633 is not set
2808 +# Multimedia devices
2812 +# Multimedia core support
2814 +CONFIG_VIDEO_DEV=m
2815 +CONFIG_VIDEO_V4L2_COMMON=m
2816 +CONFIG_VIDEO_ALLOW_V4L1=y
2817 +CONFIG_VIDEO_V4L1_COMPAT=y
2818 +CONFIG_DVB_CORE=m
2819 +CONFIG_VIDEO_MEDIA=m
2822 +# Multimedia drivers
2824 +CONFIG_MEDIA_ATTACH=y
2825 +CONFIG_MEDIA_TUNER=m
2826 +# CONFIG_MEDIA_TUNER_CUSTOMIZE is not set
2827 +CONFIG_MEDIA_TUNER_SIMPLE=m
2828 +CONFIG_MEDIA_TUNER_TDA8290=m
2829 +CONFIG_MEDIA_TUNER_TDA9887=m
2830 +CONFIG_MEDIA_TUNER_TEA5761=m
2831 +CONFIG_MEDIA_TUNER_TEA5767=m
2832 +CONFIG_MEDIA_TUNER_MT20XX=m
2833 +CONFIG_MEDIA_TUNER_XC2028=m
2834 +CONFIG_MEDIA_TUNER_XC5000=m
2835 +CONFIG_VIDEO_V4L2=m
2836 +CONFIG_VIDEO_V4L1=m
2837 +CONFIG_VIDEO_CAPTURE_DRIVERS=y
2838 +# CONFIG_VIDEO_ADV_DEBUG is not set
2839 +# CONFIG_VIDEO_FIXED_MINOR_RANGES is not set
2840 +CONFIG_VIDEO_HELPER_CHIPS_AUTO=y
2841 +# CONFIG_VIDEO_VIVI is not set
2842 +# CONFIG_VIDEO_CPIA is not set
2843 +# CONFIG_VIDEO_SAA5246A is not set
2844 +# CONFIG_VIDEO_SAA5249 is not set
2845 +# CONFIG_SOC_CAMERA is not set
2846 +CONFIG_RADIO_ADAPTERS=y
2847 +# CONFIG_RADIO_TEA5764 is not set
2848 +# CONFIG_DVB_DYNAMIC_MINORS is not set
2849 +CONFIG_DVB_CAPTURE_DRIVERS=y
2850 +# CONFIG_TTPCI_EEPROM is not set
2851 +# CONFIG_DVB_B2C2_FLEXCOP is not set
2854 +# Supported DVB Frontends
2858 +# Customise DVB Frontends
2860 +# CONFIG_DVB_FE_CUSTOMISE is not set
2863 +# Multistandard (satellite) frontends
2865 +# CONFIG_DVB_STB0899 is not set
2866 +# CONFIG_DVB_STB6100 is not set
2869 +# DVB-S (satellite) frontends
2871 +CONFIG_DVB_CX24110=m
2872 +CONFIG_DVB_CX24123=m
2873 +CONFIG_DVB_MT312=m
2874 +CONFIG_DVB_S5H1420=m
2875 +# CONFIG_DVB_STV0288 is not set
2876 +# CONFIG_DVB_STB6000 is not set
2877 +CONFIG_DVB_STV0299=m
2878 +CONFIG_DVB_TDA8083=m
2879 +CONFIG_DVB_TDA10086=m
2880 +# CONFIG_DVB_TDA8261 is not set
2881 +CONFIG_DVB_VES1X93=m
2882 +CONFIG_DVB_TUNER_ITD1000=m
2883 +# CONFIG_DVB_TUNER_CX24113 is not set
2884 +CONFIG_DVB_TDA826X=m
2885 +CONFIG_DVB_TUA6100=m
2886 +# CONFIG_DVB_CX24116 is not set
2887 +# CONFIG_DVB_SI21XX is not set
2890 +# DVB-T (terrestrial) frontends
2892 +CONFIG_DVB_SP8870=m
2893 +CONFIG_DVB_SP887X=m
2894 +CONFIG_DVB_CX22700=m
2895 +CONFIG_DVB_CX22702=m
2896 +# CONFIG_DVB_DRX397XD is not set
2897 +CONFIG_DVB_L64781=m
2898 +CONFIG_DVB_TDA1004X=m
2899 +CONFIG_DVB_NXT6000=m
2900 +CONFIG_DVB_MT352=m
2901 +CONFIG_DVB_ZL10353=m
2902 +CONFIG_DVB_DIB3000MB=m
2903 +CONFIG_DVB_DIB3000MC=m
2904 +CONFIG_DVB_DIB7000M=m
2905 +CONFIG_DVB_DIB7000P=m
2906 +CONFIG_DVB_TDA10048=m
2909 +# DVB-C (cable) frontends
2911 +CONFIG_DVB_VES1820=m
2912 +CONFIG_DVB_TDA10021=m
2913 +CONFIG_DVB_TDA10023=m
2914 +CONFIG_DVB_STV0297=m
2917 +# ATSC (North American/Korean Terrestrial/Cable DTV) frontends
2919 +CONFIG_DVB_NXT200X=m
2920 +# CONFIG_DVB_OR51211 is not set
2921 +# CONFIG_DVB_OR51132 is not set
2922 +CONFIG_DVB_BCM3510=m
2923 +CONFIG_DVB_LGDT330X=m
2924 +# CONFIG_DVB_LGDT3304 is not set
2925 +CONFIG_DVB_S5H1409=m
2926 +CONFIG_DVB_AU8522=m
2927 +CONFIG_DVB_S5H1411=m
2930 +# ISDB-T (terrestrial) frontends
2932 +# CONFIG_DVB_S921 is not set
2935 +# Digital terrestrial only tuners/PLL
2937 +CONFIG_DVB_PLL=m
2938 +CONFIG_DVB_TUNER_DIB0070=m
2941 +# SEC control devices for DVB-S
2943 +CONFIG_DVB_LNBP21=m
2944 +# CONFIG_DVB_ISL6405 is not set
2945 +CONFIG_DVB_ISL6421=m
2946 +# CONFIG_DVB_LGS8GL5 is not set
2949 +# Tools to develop new frontends
2951 +# CONFIG_DVB_DUMMY_FE is not set
2952 +# CONFIG_DVB_AF9013 is not set
2953 +# CONFIG_DAB is not set
2956 +# Graphics support
2958 +# CONFIG_VGASTATE is not set
2959 +# CONFIG_VIDEO_OUTPUT_CONTROL is not set
2960 +CONFIG_FB=y
2961 +# CONFIG_FIRMWARE_EDID is not set
2962 +# CONFIG_FB_DDC is not set
2963 +# CONFIG_FB_BOOT_VESA_SUPPORT is not set
2964 +CONFIG_FB_CFB_FILLRECT=m
2965 +CONFIG_FB_CFB_COPYAREA=m
2966 +CONFIG_FB_CFB_IMAGEBLIT=m
2967 +# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set
2968 +# CONFIG_FB_SYS_FILLRECT is not set
2969 +# CONFIG_FB_SYS_COPYAREA is not set
2970 +# CONFIG_FB_SYS_IMAGEBLIT is not set
2971 +# CONFIG_FB_FOREIGN_ENDIAN is not set
2972 +# CONFIG_FB_SYS_FOPS is not set
2973 +# CONFIG_FB_SVGALIB is not set
2974 +# CONFIG_FB_MACMODES is not set
2975 +# CONFIG_FB_BACKLIGHT is not set
2976 +# CONFIG_FB_MODE_HELPERS is not set
2977 +# CONFIG_FB_TILEBLITTING is not set
2980 +# Frame buffer hardware drivers
2982 +# CONFIG_FB_S1D13XXX is not set
2983 +# CONFIG_FB_VIRTUAL is not set
2984 +# CONFIG_FB_METRONOME is not set
2985 +# CONFIG_FB_MB862XX is not set
2986 +# CONFIG_FB_OMAP_BOOTLOADER_INIT is not set
2987 +CONFIG_OMAP2_DSS=m
2988 +CONFIG_OMAP2_DSS_VRAM_SIZE=8
2989 +CONFIG_OMAP2_DSS_DEBUG_SUPPORT=y
2990 +# CONFIG_OMAP2_DSS_RFBI is not set
2991 +CONFIG_OMAP2_DSS_VENC=y
2992 +# CONFIG_OMAP2_DSS_SDI is not set
2993 +# CONFIG_OMAP2_DSS_DSI is not set
2994 +# CONFIG_OMAP2_DSS_FAKE_VSYNC is not set
2995 +CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK=0
2998 +# OMAP2/3 Display Device Drivers
3000 +CONFIG_PANEL_GENERIC=m
3001 +CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C=m
3002 +# CONFIG_PANEL_SHARP_LS037V7DW01 is not set
3003 +# CONFIG_PANEL_N800 is not set
3004 +# CONFIG_CTRL_BLIZZARD is not set
3005 +CONFIG_FB_OMAP2=m
3006 +CONFIG_FB_OMAP2_DEBUG_SUPPORT=y
3007 +# CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE is not set
3008 +CONFIG_FB_OMAP2_NUM_FBS=3
3009 +# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
3012 +# Display device support
3014 +CONFIG_DISPLAY_SUPPORT=y
3017 +# Display hardware drivers
3021 +# Console display driver support
3023 +# CONFIG_VGA_CONSOLE is not set
3024 +CONFIG_DUMMY_CONSOLE=y
3025 +# CONFIG_FRAMEBUFFER_CONSOLE is not set
3026 +# CONFIG_LOGO is not set
3027 +# CONFIG_SOUND is not set
3028 +CONFIG_HID_SUPPORT=y
3029 +CONFIG_HID=y
3030 +CONFIG_HID_DEBUG=y
3031 +# CONFIG_HIDRAW is not set
3032 +# CONFIG_HID_PID is not set
3035 +# Special HID drivers
3037 +CONFIG_HID_COMPAT=y
3038 +# CONFIG_HID_APPLE is not set
3039 +CONFIG_USB_SUPPORT=y
3040 +CONFIG_USB_ARCH_HAS_HCD=y
3041 +CONFIG_USB_ARCH_HAS_OHCI=y
3042 +CONFIG_USB_ARCH_HAS_EHCI=y
3043 +# CONFIG_USB is not set
3044 +# CONFIG_USB_OTG_WHITELIST is not set
3045 +# CONFIG_USB_OTG_BLACKLIST_HUB is not set
3046 +CONFIG_USB_MUSB_HDRC=y
3047 +CONFIG_USB_MUSB_SOC=y
3050 +# OMAP 343x high speed USB support
3052 +# CONFIG_USB_MUSB_HOST is not set
3053 +CONFIG_USB_MUSB_PERIPHERAL=y
3054 +# CONFIG_USB_MUSB_OTG is not set
3055 +CONFIG_USB_GADGET_MUSB_HDRC=y
3056 +CONFIG_MUSB_PIO_ONLY=y
3057 +# CONFIG_USB_MUSB_DEBUG is not set
3060 +# NOTE: USB_STORAGE depends on SCSI but BLK_DEV_SD may also be needed;
3062 +CONFIG_USB_GADGET=y
3063 +# CONFIG_USB_GADGET_DEBUG is not set
3064 +# CONFIG_USB_GADGET_DEBUG_FILES is not set
3065 +# CONFIG_USB_GADGET_DEBUG_FS is not set
3066 +CONFIG_USB_GADGET_VBUS_DRAW=2
3067 +CONFIG_USB_GADGET_SELECTED=y
3068 +# CONFIG_USB_GADGET_AT91 is not set
3069 +# CONFIG_USB_GADGET_ATMEL_USBA is not set
3070 +# CONFIG_USB_GADGET_FSL_USB2 is not set
3071 +# CONFIG_USB_GADGET_LH7A40X is not set
3072 +# CONFIG_USB_GADGET_OMAP is not set
3073 +# CONFIG_USB_GADGET_PXA25X is not set
3074 +# CONFIG_USB_GADGET_PXA27X is not set
3075 +# CONFIG_USB_GADGET_S3C2410 is not set
3076 +# CONFIG_USB_GADGET_IMX is not set
3077 +# CONFIG_USB_GADGET_M66592 is not set
3078 +# CONFIG_USB_GADGET_AMD5536UDC is not set
3079 +# CONFIG_USB_GADGET_FSL_QE is not set
3080 +# CONFIG_USB_GADGET_CI13XXX is not set
3081 +# CONFIG_USB_GADGET_NET2280 is not set
3082 +# CONFIG_USB_GADGET_GOKU is not set
3083 +# CONFIG_USB_GADGET_DUMMY_HCD is not set
3084 +CONFIG_USB_GADGET_DUALSPEED=y
3085 +# CONFIG_USB_ZERO is not set
3086 +CONFIG_USB_ETH=y
3087 +CONFIG_USB_ETH_RNDIS=y
3088 +# CONFIG_USB_GADGETFS is not set
3089 +# CONFIG_USB_FILE_STORAGE is not set
3090 +# CONFIG_USB_G_SERIAL is not set
3091 +# CONFIG_USB_MIDI_GADGET is not set
3092 +# CONFIG_USB_G_PRINTER is not set
3093 +# CONFIG_USB_CDC_COMPOSITE is not set
3096 +# OTG and related infrastructure
3098 +CONFIG_USB_OTG_UTILS=y
3099 +# CONFIG_USB_GPIO_VBUS is not set
3100 +# CONFIG_ISP1301_OMAP is not set
3101 +CONFIG_TWL4030_USB=y
3102 +CONFIG_MMC=y
3103 +# CONFIG_MMC_DEBUG is not set
3104 +CONFIG_MMC_UNSAFE_RESUME=y
3107 +# MMC/SD/SDIO Card Drivers
3109 +CONFIG_MMC_BLOCK=y
3110 +CONFIG_MMC_BLOCK_BOUNCE=y
3111 +CONFIG_SDIO_UART=y
3112 +# CONFIG_MMC_TEST is not set
3115 +# MMC/SD/SDIO Host Controller Drivers
3117 +# CONFIG_MMC_SDHCI is not set
3118 +CONFIG_MMC_OMAP_HS=y
3119 +# CONFIG_MMC_SPI is not set
3120 +# CONFIG_MEMSTICK is not set
3121 +# CONFIG_ACCESSIBILITY is not set
3122 +CONFIG_NEW_LEDS=y
3123 +CONFIG_LEDS_CLASS=y
3126 +# LED drivers
3128 +# CONFIG_LEDS_OMAP_DEBUG is not set
3129 +# CONFIG_LEDS_OMAP is not set
3130 +# CONFIG_LEDS_OMAP_PWM is not set
3131 +# CONFIG_LEDS_PCA9532 is not set
3132 +CONFIG_LEDS_GPIO=y
3133 +# CONFIG_LEDS_PCA955X is not set
3136 +# LED Triggers
3138 +CONFIG_LEDS_TRIGGERS=y
3139 +CONFIG_LEDS_TRIGGER_TIMER=y
3140 +CONFIG_LEDS_TRIGGER_HEARTBEAT=y
3141 +# CONFIG_LEDS_TRIGGER_BACKLIGHT is not set
3142 +# CONFIG_LEDS_TRIGGER_DEFAULT_ON is not set
3143 +CONFIG_RTC_LIB=y
3144 +CONFIG_RTC_CLASS=y
3145 +CONFIG_RTC_HCTOSYS=y
3146 +CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
3147 +# CONFIG_RTC_DEBUG is not set
3150 +# RTC interfaces
3152 +CONFIG_RTC_INTF_SYSFS=y
3153 +CONFIG_RTC_INTF_PROC=y
3154 +CONFIG_RTC_INTF_DEV=y
3155 +# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
3156 +# CONFIG_RTC_DRV_TEST is not set
3159 +# I2C RTC drivers
3161 +# CONFIG_RTC_DRV_DS1307 is not set
3162 +# CONFIG_RTC_DRV_DS1374 is not set
3163 +# CONFIG_RTC_DRV_DS1672 is not set
3164 +# CONFIG_RTC_DRV_MAX6900 is not set
3165 +# CONFIG_RTC_DRV_RS5C372 is not set
3166 +# CONFIG_RTC_DRV_ISL1208 is not set
3167 +# CONFIG_RTC_DRV_X1205 is not set
3168 +# CONFIG_RTC_DRV_PCF8563 is not set
3169 +# CONFIG_RTC_DRV_PCF8583 is not set
3170 +# CONFIG_RTC_DRV_M41T80 is not set
3171 +CONFIG_RTC_DRV_TWL4030=y
3172 +# CONFIG_RTC_DRV_S35390A is not set
3173 +# CONFIG_RTC_DRV_FM3130 is not set
3174 +# CONFIG_RTC_DRV_RX8581 is not set
3177 +# SPI RTC drivers
3179 +# CONFIG_RTC_DRV_M41T94 is not set
3180 +# CONFIG_RTC_DRV_DS1305 is not set
3181 +# CONFIG_RTC_DRV_DS1390 is not set
3182 +# CONFIG_RTC_DRV_MAX6902 is not set
3183 +# CONFIG_RTC_DRV_R9701 is not set
3184 +# CONFIG_RTC_DRV_RS5C348 is not set
3185 +# CONFIG_RTC_DRV_DS3234 is not set
3188 +# Platform RTC drivers
3190 +# CONFIG_RTC_DRV_CMOS is not set
3191 +# CONFIG_RTC_DRV_DS1286 is not set
3192 +# CONFIG_RTC_DRV_DS1511 is not set
3193 +# CONFIG_RTC_DRV_DS1553 is not set
3194 +# CONFIG_RTC_DRV_DS1742 is not set
3195 +# CONFIG_RTC_DRV_STK17TA8 is not set
3196 +# CONFIG_RTC_DRV_M48T86 is not set
3197 +# CONFIG_RTC_DRV_M48T35 is not set
3198 +# CONFIG_RTC_DRV_M48T59 is not set
3199 +# CONFIG_RTC_DRV_BQ4802 is not set
3200 +# CONFIG_RTC_DRV_V3020 is not set
3203 +# on-CPU RTC drivers
3205 +# CONFIG_DMADEVICES is not set
3206 +# CONFIG_REGULATOR is not set
3207 +# CONFIG_UIO is not set
3208 +# CONFIG_STAGING is not set
3211 +# CBUS support
3213 +# CONFIG_CBUS is not set
3216 +# File systems
3218 +CONFIG_EXT2_FS=y
3219 +# CONFIG_EXT2_FS_XATTR is not set
3220 +# CONFIG_EXT2_FS_XIP is not set
3221 +CONFIG_EXT3_FS=y
3222 +# CONFIG_EXT3_FS_XATTR is not set
3223 +# CONFIG_EXT4_FS is not set
3224 +CONFIG_JBD=y
3225 +# CONFIG_JBD_DEBUG is not set
3226 +# CONFIG_REISERFS_FS is not set
3227 +# CONFIG_JFS_FS is not set
3228 +CONFIG_FS_POSIX_ACL=y
3229 +CONFIG_FILE_LOCKING=y
3230 +CONFIG_XFS_FS=m
3231 +# CONFIG_XFS_QUOTA is not set
3232 +# CONFIG_XFS_POSIX_ACL is not set
3233 +# CONFIG_XFS_RT is not set
3234 +# CONFIG_XFS_DEBUG is not set
3235 +# CONFIG_GFS2_FS is not set
3236 +# CONFIG_OCFS2_FS is not set
3237 +# CONFIG_BTRFS_FS is not set
3238 +CONFIG_DNOTIFY=y
3239 +CONFIG_INOTIFY=y
3240 +CONFIG_INOTIFY_USER=y
3241 +CONFIG_QUOTA=y
3242 +# CONFIG_QUOTA_NETLINK_INTERFACE is not set
3243 +CONFIG_PRINT_QUOTA_WARNING=y
3244 +CONFIG_QUOTA_TREE=y
3245 +# CONFIG_QFMT_V1 is not set
3246 +CONFIG_QFMT_V2=y
3247 +CONFIG_QUOTACTL=y
3248 +# CONFIG_AUTOFS_FS is not set
3249 +# CONFIG_AUTOFS4_FS is not set
3250 +CONFIG_FUSE_FS=m
3253 +# CD-ROM/DVD Filesystems
3255 +CONFIG_ISO9660_FS=m
3256 +CONFIG_JOLIET=y
3257 +CONFIG_ZISOFS=y
3258 +CONFIG_UDF_FS=m
3259 +CONFIG_UDF_NLS=y
3262 +# DOS/FAT/NT Filesystems
3264 +CONFIG_FAT_FS=y
3265 +CONFIG_MSDOS_FS=y
3266 +CONFIG_VFAT_FS=y
3267 +CONFIG_FAT_DEFAULT_CODEPAGE=437
3268 +CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
3269 +# CONFIG_NTFS_FS is not set
3272 +# Pseudo filesystems
3274 +CONFIG_PROC_FS=y
3275 +CONFIG_PROC_SYSCTL=y
3276 +CONFIG_PROC_PAGE_MONITOR=y
3277 +CONFIG_SYSFS=y
3278 +CONFIG_TMPFS=y
3279 +# CONFIG_TMPFS_POSIX_ACL is not set
3280 +# CONFIG_HUGETLB_PAGE is not set
3281 +# CONFIG_CONFIGFS_FS is not set
3282 +CONFIG_MISC_FILESYSTEMS=y
3283 +# CONFIG_ADFS_FS is not set
3284 +# CONFIG_AFFS_FS is not set
3285 +# CONFIG_HFS_FS is not set
3286 +# CONFIG_HFSPLUS_FS is not set
3287 +# CONFIG_BEFS_FS is not set
3288 +# CONFIG_BFS_FS is not set
3289 +# CONFIG_EFS_FS is not set
3290 +CONFIG_JFFS2_FS=y
3291 +CONFIG_JFFS2_FS_DEBUG=0
3292 +CONFIG_JFFS2_FS_WRITEBUFFER=y
3293 +# CONFIG_JFFS2_FS_WBUF_VERIFY is not set
3294 +CONFIG_JFFS2_SUMMARY=y
3295 +CONFIG_JFFS2_FS_XATTR=y
3296 +CONFIG_JFFS2_FS_POSIX_ACL=y
3297 +CONFIG_JFFS2_FS_SECURITY=y
3298 +CONFIG_JFFS2_COMPRESSION_OPTIONS=y
3299 +CONFIG_JFFS2_ZLIB=y
3300 +CONFIG_JFFS2_LZO=y
3301 +CONFIG_JFFS2_RTIME=y
3302 +CONFIG_JFFS2_RUBIN=y
3303 +# CONFIG_JFFS2_CMODE_NONE is not set
3304 +CONFIG_JFFS2_CMODE_PRIORITY=y
3305 +# CONFIG_JFFS2_CMODE_SIZE is not set
3306 +# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
3307 +# CONFIG_CRAMFS is not set
3308 +# CONFIG_SQUASHFS is not set
3309 +# CONFIG_VXFS_FS is not set
3310 +# CONFIG_MINIX_FS is not set
3311 +# CONFIG_OMFS_FS is not set
3312 +# CONFIG_HPFS_FS is not set
3313 +# CONFIG_QNX4FS_FS is not set
3314 +# CONFIG_ROMFS_FS is not set
3315 +# CONFIG_SYSV_FS is not set
3316 +# CONFIG_UFS_FS is not set
3317 +CONFIG_NETWORK_FILESYSTEMS=y
3318 +CONFIG_NFS_FS=y
3319 +CONFIG_NFS_V3=y
3320 +# CONFIG_NFS_V3_ACL is not set
3321 +CONFIG_NFS_V4=y
3322 +CONFIG_ROOT_NFS=y
3323 +# CONFIG_NFSD is not set
3324 +CONFIG_LOCKD=y
3325 +CONFIG_LOCKD_V4=y
3326 +CONFIG_EXPORTFS=m
3327 +CONFIG_NFS_COMMON=y
3328 +CONFIG_SUNRPC=y
3329 +CONFIG_SUNRPC_GSS=y
3330 +# CONFIG_SUNRPC_REGISTER_V4 is not set
3331 +CONFIG_RPCSEC_GSS_KRB5=y
3332 +# CONFIG_RPCSEC_GSS_SPKM3 is not set
3333 +# CONFIG_SMB_FS is not set
3334 +# CONFIG_CIFS is not set
3335 +# CONFIG_NCP_FS is not set
3336 +# CONFIG_CODA_FS is not set
3337 +# CONFIG_AFS_FS is not set
3340 +# Partition Types
3342 +CONFIG_PARTITION_ADVANCED=y
3343 +# CONFIG_ACORN_PARTITION is not set
3344 +# CONFIG_OSF_PARTITION is not set
3345 +# CONFIG_AMIGA_PARTITION is not set
3346 +# CONFIG_ATARI_PARTITION is not set
3347 +# CONFIG_MAC_PARTITION is not set
3348 +CONFIG_MSDOS_PARTITION=y
3349 +# CONFIG_BSD_DISKLABEL is not set
3350 +# CONFIG_MINIX_SUBPARTITION is not set
3351 +# CONFIG_SOLARIS_X86_PARTITION is not set
3352 +# CONFIG_UNIXWARE_DISKLABEL is not set
3353 +# CONFIG_LDM_PARTITION is not set
3354 +# CONFIG_SGI_PARTITION is not set
3355 +# CONFIG_ULTRIX_PARTITION is not set
3356 +# CONFIG_SUN_PARTITION is not set
3357 +# CONFIG_KARMA_PARTITION is not set
3358 +# CONFIG_EFI_PARTITION is not set
3359 +# CONFIG_SYSV68_PARTITION is not set
3360 +CONFIG_NLS=y
3361 +CONFIG_NLS_DEFAULT="iso8859-1"
3362 +CONFIG_NLS_CODEPAGE_437=y
3363 +# CONFIG_NLS_CODEPAGE_737 is not set
3364 +# CONFIG_NLS_CODEPAGE_775 is not set
3365 +# CONFIG_NLS_CODEPAGE_850 is not set
3366 +# CONFIG_NLS_CODEPAGE_852 is not set
3367 +# CONFIG_NLS_CODEPAGE_855 is not set
3368 +# CONFIG_NLS_CODEPAGE_857 is not set
3369 +# CONFIG_NLS_CODEPAGE_860 is not set
3370 +# CONFIG_NLS_CODEPAGE_861 is not set
3371 +# CONFIG_NLS_CODEPAGE_862 is not set
3372 +# CONFIG_NLS_CODEPAGE_863 is not set
3373 +# CONFIG_NLS_CODEPAGE_864 is not set
3374 +# CONFIG_NLS_CODEPAGE_865 is not set
3375 +# CONFIG_NLS_CODEPAGE_866 is not set
3376 +# CONFIG_NLS_CODEPAGE_869 is not set
3377 +# CONFIG_NLS_CODEPAGE_936 is not set
3378 +# CONFIG_NLS_CODEPAGE_950 is not set
3379 +# CONFIG_NLS_CODEPAGE_932 is not set
3380 +# CONFIG_NLS_CODEPAGE_949 is not set
3381 +# CONFIG_NLS_CODEPAGE_874 is not set
3382 +# CONFIG_NLS_ISO8859_8 is not set
3383 +# CONFIG_NLS_CODEPAGE_1250 is not set
3384 +# CONFIG_NLS_CODEPAGE_1251 is not set
3385 +# CONFIG_NLS_ASCII is not set
3386 +CONFIG_NLS_ISO8859_1=y
3387 +# CONFIG_NLS_ISO8859_2 is not set
3388 +# CONFIG_NLS_ISO8859_3 is not set
3389 +# CONFIG_NLS_ISO8859_4 is not set
3390 +# CONFIG_NLS_ISO8859_5 is not set
3391 +# CONFIG_NLS_ISO8859_6 is not set
3392 +# CONFIG_NLS_ISO8859_7 is not set
3393 +# CONFIG_NLS_ISO8859_9 is not set
3394 +# CONFIG_NLS_ISO8859_13 is not set
3395 +# CONFIG_NLS_ISO8859_14 is not set
3396 +# CONFIG_NLS_ISO8859_15 is not set
3397 +# CONFIG_NLS_KOI8_R is not set
3398 +# CONFIG_NLS_KOI8_U is not set
3399 +# CONFIG_NLS_UTF8 is not set
3400 +# CONFIG_DLM is not set
3403 +# Kernel hacking
3405 +# CONFIG_PRINTK_TIME is not set
3406 +CONFIG_ENABLE_WARN_DEPRECATED=y
3407 +CONFIG_ENABLE_MUST_CHECK=y
3408 +CONFIG_FRAME_WARN=1024
3409 +CONFIG_MAGIC_SYSRQ=y
3410 +# CONFIG_UNUSED_SYMBOLS is not set
3411 +CONFIG_DEBUG_FS=y
3412 +# CONFIG_HEADERS_CHECK is not set
3413 +CONFIG_DEBUG_KERNEL=y
3414 +# CONFIG_DEBUG_SHIRQ is not set
3415 +CONFIG_DETECT_SOFTLOCKUP=y
3416 +# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set
3417 +CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0
3418 +CONFIG_SCHED_DEBUG=y
3419 +CONFIG_SCHEDSTATS=y
3420 +CONFIG_TIMER_STATS=y
3421 +# CONFIG_DEBUG_OBJECTS is not set
3422 +# CONFIG_SLUB_DEBUG_ON is not set
3423 +# CONFIG_SLUB_STATS is not set
3424 +# CONFIG_DEBUG_RT_MUTEXES is not set
3425 +# CONFIG_RT_MUTEX_TESTER is not set
3426 +# CONFIG_DEBUG_SPINLOCK is not set
3427 +CONFIG_DEBUG_MUTEXES=y
3428 +# CONFIG_DEBUG_LOCK_ALLOC is not set
3429 +# CONFIG_PROVE_LOCKING is not set
3430 +# CONFIG_LOCK_STAT is not set
3431 +# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
3432 +# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
3433 +CONFIG_STACKTRACE=y
3434 +# CONFIG_DEBUG_KOBJECT is not set
3435 +# CONFIG_DEBUG_BUGVERBOSE is not set
3436 +# CONFIG_DEBUG_INFO is not set
3437 +# CONFIG_DEBUG_VM is not set
3438 +# CONFIG_DEBUG_WRITECOUNT is not set
3439 +# CONFIG_DEBUG_MEMORY_INIT is not set
3440 +# CONFIG_DEBUG_LIST is not set
3441 +# CONFIG_DEBUG_SG is not set
3442 +# CONFIG_DEBUG_NOTIFIERS is not set
3443 +CONFIG_FRAME_POINTER=y
3444 +# CONFIG_BOOT_PRINTK_DELAY is not set
3445 +# CONFIG_RCU_TORTURE_TEST is not set
3446 +# CONFIG_RCU_CPU_STALL_DETECTOR is not set
3447 +# CONFIG_BACKTRACE_SELF_TEST is not set
3448 +# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set
3449 +# CONFIG_FAULT_INJECTION is not set
3450 +# CONFIG_LATENCYTOP is not set
3451 +CONFIG_NOP_TRACER=y
3452 +CONFIG_HAVE_FUNCTION_TRACER=y
3453 +CONFIG_RING_BUFFER=y
3454 +CONFIG_TRACING=y
3457 +# Tracers
3459 +# CONFIG_FUNCTION_TRACER is not set
3460 +# CONFIG_IRQSOFF_TRACER is not set
3461 +# CONFIG_SCHED_TRACER is not set
3462 +# CONFIG_CONTEXT_SWITCH_TRACER is not set
3463 +# CONFIG_BOOT_TRACER is not set
3464 +# CONFIG_TRACE_BRANCH_PROFILING is not set
3465 +# CONFIG_STACK_TRACER is not set
3466 +# CONFIG_FTRACE_STARTUP_TEST is not set
3467 +# CONFIG_DYNAMIC_PRINTK_DEBUG is not set
3468 +# CONFIG_SAMPLES is not set
3469 +CONFIG_HAVE_ARCH_KGDB=y
3470 +# CONFIG_KGDB is not set
3471 +# CONFIG_DEBUG_USER is not set
3472 +# CONFIG_DEBUG_ERRORS is not set
3473 +# CONFIG_DEBUG_STACK_USAGE is not set
3474 +# CONFIG_DEBUG_LL is not set
3477 +# Security options
3479 +# CONFIG_KEYS is not set
3480 +# CONFIG_SECURITY is not set
3481 +# CONFIG_SECURITYFS is not set
3482 +# CONFIG_SECURITY_FILE_CAPABILITIES is not set
3483 +CONFIG_XOR_BLOCKS=m
3484 +CONFIG_ASYNC_CORE=m
3485 +CONFIG_ASYNC_MEMCPY=m
3486 +CONFIG_ASYNC_XOR=m
3487 +CONFIG_CRYPTO=y
3490 +# Crypto core or helper
3492 +# CONFIG_CRYPTO_FIPS is not set
3493 +CONFIG_CRYPTO_ALGAPI=y
3494 +CONFIG_CRYPTO_ALGAPI2=y
3495 +CONFIG_CRYPTO_AEAD2=y
3496 +CONFIG_CRYPTO_BLKCIPHER=y
3497 +CONFIG_CRYPTO_BLKCIPHER2=y
3498 +CONFIG_CRYPTO_HASH=y
3499 +CONFIG_CRYPTO_HASH2=y
3500 +CONFIG_CRYPTO_RNG2=y
3501 +CONFIG_CRYPTO_MANAGER=y
3502 +CONFIG_CRYPTO_MANAGER2=y
3503 +CONFIG_CRYPTO_GF128MUL=m
3504 +CONFIG_CRYPTO_NULL=m
3505 +CONFIG_CRYPTO_CRYPTD=m
3506 +# CONFIG_CRYPTO_AUTHENC is not set
3507 +CONFIG_CRYPTO_TEST=m
3510 +# Authenticated Encryption with Associated Data
3512 +# CONFIG_CRYPTO_CCM is not set
3513 +# CONFIG_CRYPTO_GCM is not set
3514 +# CONFIG_CRYPTO_SEQIV is not set
3517 +# Block modes
3519 +CONFIG_CRYPTO_CBC=y
3520 +# CONFIG_CRYPTO_CTR is not set
3521 +# CONFIG_CRYPTO_CTS is not set
3522 +CONFIG_CRYPTO_ECB=y
3523 +CONFIG_CRYPTO_LRW=m
3524 +CONFIG_CRYPTO_PCBC=m
3525 +# CONFIG_CRYPTO_XTS is not set
3528 +# Hash modes
3530 +CONFIG_CRYPTO_HMAC=m
3531 +CONFIG_CRYPTO_XCBC=m
3534 +# Digest
3536 +CONFIG_CRYPTO_CRC32C=y
3537 +CONFIG_CRYPTO_MD4=m
3538 +CONFIG_CRYPTO_MD5=y
3539 +CONFIG_CRYPTO_MICHAEL_MIC=y
3540 +# CONFIG_CRYPTO_RMD128 is not set
3541 +# CONFIG_CRYPTO_RMD160 is not set
3542 +# CONFIG_CRYPTO_RMD256 is not set
3543 +# CONFIG_CRYPTO_RMD320 is not set
3544 +CONFIG_CRYPTO_SHA1=m
3545 +CONFIG_CRYPTO_SHA256=m
3546 +CONFIG_CRYPTO_SHA512=m
3547 +CONFIG_CRYPTO_TGR192=m
3548 +CONFIG_CRYPTO_WP512=m
3551 +# Ciphers
3553 +CONFIG_CRYPTO_AES=y
3554 +CONFIG_CRYPTO_ANUBIS=m
3555 +CONFIG_CRYPTO_ARC4=y
3556 +CONFIG_CRYPTO_BLOWFISH=m
3557 +CONFIG_CRYPTO_CAMELLIA=m
3558 +CONFIG_CRYPTO_CAST5=m
3559 +CONFIG_CRYPTO_CAST6=m
3560 +CONFIG_CRYPTO_DES=y
3561 +CONFIG_CRYPTO_FCRYPT=m
3562 +CONFIG_CRYPTO_KHAZAD=m
3563 +# CONFIG_CRYPTO_SALSA20 is not set
3564 +# CONFIG_CRYPTO_SEED is not set
3565 +CONFIG_CRYPTO_SERPENT=m
3566 +CONFIG_CRYPTO_TEA=m
3567 +CONFIG_CRYPTO_TWOFISH=m
3568 +CONFIG_CRYPTO_TWOFISH_COMMON=m
3571 +# Compression
3573 +CONFIG_CRYPTO_DEFLATE=m
3574 +# CONFIG_CRYPTO_LZO is not set
3577 +# Random Number Generation
3579 +# CONFIG_CRYPTO_ANSI_CPRNG is not set
3580 +CONFIG_CRYPTO_HW=y
3583 +# Library routines
3585 +CONFIG_BITREVERSE=y
3586 +CONFIG_GENERIC_FIND_LAST_BIT=y
3587 +CONFIG_CRC_CCITT=y
3588 +CONFIG_CRC16=m
3589 +CONFIG_CRC_T10DIF=y
3590 +CONFIG_CRC_ITU_T=y
3591 +CONFIG_CRC32=y
3592 +CONFIG_CRC7=y
3593 +CONFIG_LIBCRC32C=y
3594 +CONFIG_ZLIB_INFLATE=y
3595 +CONFIG_ZLIB_DEFLATE=y
3596 +CONFIG_LZO_COMPRESS=y
3597 +CONFIG_LZO_DECOMPRESS=y
3598 +CONFIG_PLIST=y
3599 +CONFIG_HAS_IOMEM=y
3600 +CONFIG_HAS_IOPORT=y
3601 +CONFIG_HAS_DMA=y
3602 diff --git a/arch/arm/mach-omap1/board-nokia770.c b/arch/arm/mach-omap1/board-nokia770.c
3603 index 8780ca6..ca4680a 100644
3604 --- a/arch/arm/mach-omap1/board-nokia770.c
3605 +++ b/arch/arm/mach-omap1/board-nokia770.c
3606 @@ -18,6 +18,7 @@
3607 #include <linux/spi/spi.h>
3608 #include <linux/spi/ads7846.h>
3609 #include <linux/workqueue.h>
3610 +#include <linux/omapfb.h>
3611 #include <linux/delay.h>
3613 #include <mach/hardware.h>
3614 @@ -32,7 +33,6 @@
3615 #include <mach/keypad.h>
3616 #include <mach/common.h>
3617 #include <mach/dsp_common.h>
3618 -#include <mach/omapfb.h>
3619 #include <mach/lcd_mipid.h>
3620 #include <mach/mmc.h>
3621 #include <mach/usb.h>
3622 diff --git a/arch/arm/mach-omap2/board-3430sdp.c b/arch/arm/mach-omap2/board-3430sdp.c
3623 index 0a1099e..2bba94d 100644
3624 --- a/arch/arm/mach-omap2/board-3430sdp.c
3625 +++ b/arch/arm/mach-omap2/board-3430sdp.c
3626 @@ -255,8 +255,226 @@ static struct regulator_consumer_supply sdp3430_vdac_supply = {
3627 static struct regulator_consumer_supply sdp3430_vdvi_supply = {
3628 .supply = "vdvi",
3629 .dev = &sdp3430_lcd_device.dev,
3631 +#define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
3632 +#define SDP2430_LCD_PANEL_ENABLE_GPIO 154
3633 +#if 0
3634 +#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 24
3635 +#define SDP3430_LCD_PANEL_ENABLE_GPIO 28
3636 +#else
3637 +#define SDP3430_LCD_PANEL_BACKLIGHT_GPIO 8
3638 +#define SDP3430_LCD_PANEL_ENABLE_GPIO 5
3639 +#endif
3641 +#define PM_RECEIVER TWL4030_MODULE_PM_RECEIVER
3642 +#define ENABLE_VAUX2_DEDICATED 0x09
3643 +#define ENABLE_VAUX2_DEV_GRP 0x20
3644 +#define ENABLE_VAUX3_DEDICATED 0x03
3645 +#define ENABLE_VAUX3_DEV_GRP 0x20
3647 +#define ENABLE_VPLL2_DEDICATED 0x05
3648 +#define ENABLE_VPLL2_DEV_GRP 0xE0
3649 +#define TWL4030_VPLL2_DEV_GRP 0x33
3650 +#define TWL4030_VPLL2_DEDICATED 0x36
3652 +#define t2_out(c, r, v) twl4030_i2c_write_u8(c, r, v)
3654 +static unsigned backlight_gpio;
3655 +static unsigned enable_gpio;
3656 +static int lcd_enabled;
3657 +static int dvi_enabled;
3659 +static void enable_vpll2(int enable)
3661 + u8 ded_val, grp_val;
3663 + if (enable) {
3664 + ded_val = ENABLE_VPLL2_DEDICATED;
3665 + grp_val = ENABLE_VPLL2_DEV_GRP;
3666 + } else {
3667 + ded_val = 0;
3668 + grp_val = 0;
3671 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
3672 + ded_val, TWL4030_VPLL2_DEDICATED);
3673 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
3674 + grp_val, TWL4030_VPLL2_DEV_GRP);
3677 +static int sdp3430_dsi_power_up(void)
3679 + if (omap_rev() > OMAP3430_REV_ES1_0)
3680 + enable_vpll2(1);
3681 + return 0;
3684 +static void sdp3430_dsi_power_down(void)
3686 + if (omap_rev() > OMAP3430_REV_ES1_0)
3687 + enable_vpll2(0);
3690 +static void __init sdp3430_display_init(void)
3692 + int r;
3694 + enable_gpio = SDP3430_LCD_PANEL_ENABLE_GPIO;
3695 + backlight_gpio = SDP3430_LCD_PANEL_BACKLIGHT_GPIO;
3697 + r = gpio_request(enable_gpio, "LCD reset");
3698 + if (r) {
3699 + printk(KERN_ERR "failed to get LCD reset GPIO\n");
3700 + goto err0;
3703 + r = gpio_request(backlight_gpio, "LCD Backlight");
3704 + if (r) {
3705 + printk(KERN_ERR "failed to get LCD backlight GPIO\n");
3706 + goto err1;
3709 + gpio_direction_output(enable_gpio, 0);
3710 + gpio_direction_output(backlight_gpio, 0);
3712 + return;
3713 +err1:
3714 + gpio_free(enable_gpio);
3715 +err0:
3716 + return;
3720 +static int sdp3430_panel_enable_lcd(struct omap_display *display)
3722 + u8 ded_val, ded_reg;
3723 + u8 grp_val, grp_reg;
3725 + if (dvi_enabled) {
3726 + printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
3727 + return -EINVAL;
3730 + ded_reg = TWL4030_VAUX3_DEDICATED;
3731 + ded_val = ENABLE_VAUX3_DEDICATED;
3732 + grp_reg = TWL4030_VAUX3_DEV_GRP;
3733 + grp_val = ENABLE_VAUX3_DEV_GRP;
3735 + gpio_direction_output(enable_gpio, 1);
3736 + gpio_direction_output(backlight_gpio, 1);
3738 + if (0 != t2_out(PM_RECEIVER, ded_val, ded_reg))
3739 + return -EIO;
3740 + if (0 != t2_out(PM_RECEIVER, grp_val, grp_reg))
3741 + return -EIO;
3743 + sdp3430_dsi_power_up();
3745 + lcd_enabled = 1;
3747 + return 0;
3750 +static void sdp3430_panel_disable_lcd(struct omap_display *display)
3752 + lcd_enabled = 0;
3754 + sdp3430_dsi_power_down();
3756 + gpio_direction_output(enable_gpio, 0);
3757 + gpio_direction_output(backlight_gpio, 0);
3760 +static struct omap_dss_display_config sdp3430_display_data = {
3761 + .type = OMAP_DISPLAY_TYPE_DPI,
3762 + .name = "lcd",
3763 + .panel_name = "sharp-ls037v7dw01",
3764 + .u.dpi.data_lines = 16,
3765 + .panel_enable = sdp3430_panel_enable_lcd,
3766 + .panel_disable = sdp3430_panel_disable_lcd,
3769 +static int sdp3430_panel_enable_dvi(struct omap_display *display)
3771 + if (lcd_enabled) {
3772 + printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
3773 + return -EINVAL;
3776 + sdp3430_dsi_power_up();
3778 + dvi_enabled = 1;
3780 + return 0;
3783 +static void sdp3430_panel_disable_dvi(struct omap_display *display)
3785 + sdp3430_dsi_power_down();
3787 + dvi_enabled = 0;
3791 +static struct omap_dss_display_config sdp3430_display_data_dvi = {
3792 + .type = OMAP_DISPLAY_TYPE_DPI,
3793 + .name = "dvi",
3794 + .panel_name = "panel-generic",
3795 + .u.dpi.data_lines = 24,
3796 + .panel_enable = sdp3430_panel_enable_dvi,
3797 + .panel_disable = sdp3430_panel_disable_dvi,
3800 +static int sdp3430_panel_enable_tv(struct omap_display *display)
3802 +#define ENABLE_VDAC_DEDICATED 0x03
3803 +#define ENABLE_VDAC_DEV_GRP 0x20
3805 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
3806 + ENABLE_VDAC_DEDICATED,
3807 + TWL4030_VDAC_DEDICATED);
3808 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
3809 + ENABLE_VDAC_DEV_GRP, TWL4030_VDAC_DEV_GRP);
3811 + return 0;
3814 +static void sdp3430_panel_disable_tv(struct omap_display *display)
3816 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
3817 + TWL4030_VDAC_DEDICATED);
3818 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
3819 + TWL4030_VDAC_DEV_GRP);
3822 +static struct omap_dss_display_config sdp3430_display_data_tv = {
3823 + .type = OMAP_DISPLAY_TYPE_VENC,
3824 + .name = "tv",
3825 + .u.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
3826 + .panel_enable = sdp3430_panel_enable_tv,
3827 + .panel_disable = sdp3430_panel_disable_tv,
3830 +static struct omap_dss_board_info sdp3430_dss_data = {
3831 + .dsi_power_up = sdp3430_dsi_power_up,
3832 + .dsi_power_down = sdp3430_dsi_power_down,
3833 + .num_displays = 3,
3834 + .displays = {
3835 + &sdp3430_display_data,
3836 + &sdp3430_display_data_dvi,
3837 + &sdp3430_display_data_tv,
3841 +static struct platform_device sdp3430_dss_device = {
3842 + .name = "omapdss",
3843 + .id = -1,
3844 + .dev = {
3845 + .platform_data = &sdp3430_dss_data,
3846 + },
3850 static struct platform_device *sdp3430_devices[] __initdata = {
3851 &sdp3430_smc91x_device,
3852 &sdp3430_lcd_device,
3853 diff --git a/arch/arm/mach-omap2/board-n800.c b/arch/arm/mach-omap2/board-n800.c
3854 index 60a414c..6abfdb4 100644
3855 --- a/arch/arm/mach-omap2/board-n800.c
3856 +++ b/arch/arm/mach-omap2/board-n800.c
3857 @@ -27,6 +27,7 @@
3858 #include <linux/i2c/lm8323.h>
3859 #include <linux/i2c/menelaus.h>
3860 #include <linux/i2c/lp5521.h>
3861 +#include <linux/omapfb.h>
3862 #include <mach/hardware.h>
3863 #include <asm/mach-types.h>
3864 #include <asm/mach/arch.h>
3865 @@ -39,8 +40,8 @@
3866 #include <mach/lcd_mipid.h>
3867 #include <mach/clock.h>
3868 #include <mach/gpio-switch.h>
3869 -#include <mach/omapfb.h>
3870 #include <mach/blizzard.h>
3871 +#include <mach/display.h>
3873 #include <../drivers/cbus/tahvo.h>
3874 #include <../drivers/media/video/tcm825x.h>
3875 @@ -161,23 +162,176 @@ static struct omap_uart_config n800_uart_config __initdata = {
3877 #include "../../../drivers/cbus/retu.h"
3879 -static struct omap_fbmem_config n800_fbmem0_config __initdata = {
3880 - .size = 752 * 1024,
3881 +static struct omap_tmp105_config n800_tmp105_config __initdata = {
3882 + .tmp105_irq_pin = 125,
3883 + .set_power = n800_tmp105_set_power,
3886 -static struct omap_fbmem_config n800_fbmem1_config __initdata = {
3887 - .size = 752 * 1024,
3890 -static struct omap_fbmem_config n800_fbmem2_config __initdata = {
3891 - .size = 752 * 1024,
3894 +/* DISPLAY */
3895 +static struct {
3896 + struct clk *sys_ck;
3897 +} blizzard;
3899 +static int blizzard_get_clocks(void)
3901 + blizzard.sys_ck = clk_get(0, "osc_ck");
3902 + if (IS_ERR(blizzard.sys_ck)) {
3903 + printk(KERN_ERR "can't get Blizzard clock\n");
3904 + return PTR_ERR(blizzard.sys_ck);
3906 + return 0;
3909 +static unsigned long blizzard_get_clock_rate(void)
3911 + return clk_get_rate(blizzard.sys_ck);
3914 +static int n800_pn800_enable(struct omap_display *display)
3916 + if (display->hw_config.panel_reset_gpio != -1) {
3917 + printk("enabling panel gpio\n");
3918 + gpio_direction_output(display->hw_config.panel_reset_gpio, 1);
3921 + return 0;
3924 +static void n800_pn800_disable(struct omap_display *display)
3926 + if (display->hw_config.panel_reset_gpio != -1) {
3927 + printk("disabling panel gpio\n");
3928 + gpio_direction_output(display->hw_config.panel_reset_gpio, 0);
3929 + msleep(120);
3933 +static int n800_blizzard_enable(struct omap_display *display)
3935 + printk("enabling bliz powers\n");
3937 + /* Vcore to 1.475V */
3938 + tahvo_set_clear_reg_bits(0x07, 0, 0xf);
3939 + msleep(10);
3941 + clk_enable(blizzard.sys_ck);
3943 + if (display->hw_config.ctrl_reset_gpio != -1)
3944 + gpio_direction_output(display->hw_config.ctrl_reset_gpio, 1);
3946 + printk("osc_ck %lu\n", blizzard_get_clock_rate());
3948 + return 0;
3951 +static void n800_blizzard_disable(struct omap_display *display)
3953 + printk("disabling bliz powers\n");
3955 + if (display->hw_config.ctrl_reset_gpio != -1)
3956 + gpio_direction_output(display->hw_config.ctrl_reset_gpio, 0);
3958 + clk_disable(blizzard.sys_ck);
3960 + /* Vcore to 1.005V */
3961 + tahvo_set_clear_reg_bits(0x07, 0xf, 0);
3964 +static int n800_set_backlight_level(struct omap_display *display, int level)
3966 + return 0;
3969 +static struct omap_dss_display_config n800_dsi_display_data = {
3970 + .type = OMAP_DISPLAY_TYPE_DBI,
3971 + .name = "lcd",
3972 + .ctrl_name = "ctrl-blizzard",
3973 + .panel_name = "panel-pn800",
3974 + .panel_reset_gpio = -1,
3975 + .ctrl_reset_gpio = N800_BLIZZARD_POWERDOWN_GPIO,
3976 + .panel_enable = n800_pn800_enable,
3977 + .panel_disable = n800_pn800_disable,
3978 + .ctrl_enable = n800_blizzard_enable,
3979 + .ctrl_disable = n800_blizzard_disable,
3980 + .set_backlight = n800_set_backlight_level,
3981 + .u.rfbi = {
3982 + .channel = 0,
3983 + /* 8 for cmd mode, 16 for pixel data. ctrl-blizzard handles switching */
3984 + .data_lines = 8,
3985 + },
3986 + .panel_data = 0, // XXX used for panel datalines
3988 +static struct omap_dss_board_info n800_dss_data = {
3989 + .num_displays = 1,
3990 + .displays = {
3991 + &n800_dsi_display_data,
3992 + },
3995 -static struct omap_tmp105_config n800_tmp105_config __initdata = {
3996 - .tmp105_irq_pin = 125,
3997 - .set_power = n800_tmp105_set_power,
3998 +static struct platform_device n800_dss_device = {
3999 + .name = "omapdss",
4000 + .id = -1,
4001 + .dev = {
4002 + .platform_data = &n800_dss_data,
4003 + },
4006 +static void __init n800_display_init(void)
4008 + int r;
4009 + const struct omap_lcd_config *conf;
4011 + conf = omap_get_config(OMAP_TAG_LCD, struct omap_lcd_config);
4012 + if (conf != NULL) {
4013 + n800_dsi_display_data.panel_reset_gpio = conf->nreset_gpio;
4014 + n800_dsi_display_data.panel_data =
4015 + (void*)(u32)conf->data_lines; // XXX
4016 + //printk("\n\nTULI %d\n\n", conf->data_lines);
4017 + } else {
4018 + printk("\n\nEI TULLU MIOTÄÄÄ\n\n");
4021 + blizzard_get_clocks();
4022 + clk_enable(blizzard.sys_ck); // XXX always enable
4024 + //omapfb_set_ctrl_platform_data(&n800_blizzard_data);
4025 + //
4026 + if (n800_dsi_display_data.ctrl_reset_gpio != -1) {
4027 + r = gpio_request(n800_dsi_display_data.ctrl_reset_gpio,
4028 + "Blizzard pd");
4029 + if (r < 0) {
4030 + n800_dsi_display_data.ctrl_reset_gpio = -1;
4031 + printk(KERN_ERR "Unable to get Blizzard GPIO\n");
4032 + } else {
4033 + gpio_direction_output(n800_dsi_display_data.ctrl_reset_gpio,
4034 + 1);
4035 + // XXX always enable
4039 + if (n800_dsi_display_data.panel_reset_gpio != -1) {
4040 + r = gpio_request(n800_dsi_display_data.panel_reset_gpio,
4041 + "panel reset");
4042 + if (r < 0) {
4043 + n800_dsi_display_data.panel_reset_gpio = -1;
4044 + printk(KERN_ERR "Unable to get pn800 GPIO\n");
4045 + } else {
4046 + gpio_direction_output(n800_dsi_display_data.panel_reset_gpio,
4047 + 1);
4048 + // XXX always enable
4053 +/* DISPLAY END */
4059 static void mipid_shutdown(struct mipid_platform_data *pdata)
4061 if (pdata->nreset_gpio != -1) {
4062 @@ -191,6 +345,7 @@ static struct mipid_platform_data n800_mipid_platform_data = {
4063 .shutdown = mipid_shutdown,
4066 +#if 0
4067 static void __init mipid_dev_init(void)
4069 const struct omap_lcd_config *conf;
4070 @@ -201,26 +356,9 @@ static void __init mipid_dev_init(void)
4071 n800_mipid_platform_data.data_lines = conf->data_lines;
4074 +#endif
4076 -static struct {
4077 - struct clk *sys_ck;
4078 -} blizzard;
4080 -static int blizzard_get_clocks(void)
4082 - blizzard.sys_ck = clk_get(0, "osc_ck");
4083 - if (IS_ERR(blizzard.sys_ck)) {
4084 - printk(KERN_ERR "can't get Blizzard clock\n");
4085 - return PTR_ERR(blizzard.sys_ck);
4087 - return 0;
4090 -static unsigned long blizzard_get_clock_rate(struct device *dev)
4092 - return clk_get_rate(blizzard.sys_ck);
4095 +#if 0
4096 static void blizzard_enable_clocks(int enable)
4098 if (enable)
4099 @@ -265,14 +403,12 @@ static void __init blizzard_dev_init(void)
4100 gpio_direction_output(N800_BLIZZARD_POWERDOWN_GPIO, 1);
4102 blizzard_get_clocks();
4103 - omapfb_set_ctrl_platform_data(&n800_blizzard_data);
4104 + //omapfb_set_ctrl_platform_data(&n800_blizzard_data);
4106 +#endif
4108 static struct omap_board_config_kernel n800_config[] __initdata = {
4109 { OMAP_TAG_UART, &n800_uart_config },
4110 - { OMAP_TAG_FBMEM, &n800_fbmem0_config },
4111 - { OMAP_TAG_FBMEM, &n800_fbmem1_config },
4112 - { OMAP_TAG_FBMEM, &n800_fbmem2_config },
4113 { OMAP_TAG_TMP105, &n800_tmp105_config },
4116 @@ -379,7 +515,7 @@ static struct omap2_mcspi_device_config tsc2005_mcspi_config = {
4118 static struct spi_board_info n800_spi_board_info[] __initdata = {
4120 - .modalias = "lcd_mipid",
4121 + .modalias = "panel-n800",
4122 .bus_num = 1,
4123 .chip_select = 1,
4124 .max_speed_hz = 4000000,
4125 @@ -404,7 +540,7 @@ static struct spi_board_info n800_spi_board_info[] __initdata = {
4127 static struct spi_board_info n810_spi_board_info[] __initdata = {
4129 - .modalias = "lcd_mipid",
4130 + .modalias = "panel-n800",
4131 .bus_num = 1,
4132 .chip_select = 1,
4133 .max_speed_hz = 4000000,
4134 @@ -572,6 +708,7 @@ static struct platform_device *n800_devices[] __initdata = {
4135 #if defined(CONFIG_CBUS_RETU) && defined(CONFIG_LEDS_OMAP_PWM)
4136 &n800_keypad_led_device,
4137 #endif
4138 + &n800_dss_device,
4141 #ifdef CONFIG_MENELAUS
4142 @@ -703,9 +840,10 @@ void __init nokia_n800_common_init(void)
4143 if (machine_is_nokia_n810())
4144 i2c_register_board_info(2, n810_i2c_board_info_2,
4145 ARRAY_SIZE(n810_i2c_board_info_2));
4147 - mipid_dev_init();
4148 - blizzard_dev_init();
4150 + //mipid_dev_init();
4151 + //blizzard_dev_init();
4152 + n800_display_init();
4155 static void __init nokia_n800_init(void)
4156 @@ -726,6 +864,7 @@ void __init nokia_n800_map_io(void)
4157 omap_board_config_size = ARRAY_SIZE(n800_config);
4159 omap2_set_globals_242x();
4160 + omap2_set_sdram_vram(800 * 480 * 2 * 3, 0);
4161 omap2_map_common_io();
4164 diff --git a/arch/arm/mach-omap2/board-omap3beagle.c b/arch/arm/mach-omap2/board-omap3beagle.c
4165 index 346351e..7d2716b 100644
4166 --- a/arch/arm/mach-omap2/board-omap3beagle.c
4167 +++ b/arch/arm/mach-omap2/board-omap3beagle.c
4168 @@ -30,6 +30,7 @@
4170 #include <linux/regulator/machine.h>
4171 #include <linux/i2c/twl4030.h>
4172 +#include <linux/omapfb.h>
4174 #include <mach/hardware.h>
4175 #include <asm/mach-types.h>
4176 @@ -43,6 +44,7 @@
4177 #include <mach/gpmc.h>
4178 #include <mach/nand.h>
4179 #include <mach/mux.h>
4180 +#include <mach/display.h>
4182 #include "twl4030-generic-scripts.h"
4183 #include "mmc-twl4030.h"
4184 @@ -369,13 +371,94 @@ static struct platform_device keys_gpio = {
4188 +/* DSS */
4190 +static int beagle_enable_dvi(struct omap_display *display)
4192 + if (display->hw_config.panel_reset_gpio != -1)
4193 + gpio_direction_output(display->hw_config.panel_reset_gpio, 1);
4195 + return 0;
4198 +static void beagle_disable_dvi(struct omap_display *display)
4200 + if (display->hw_config.panel_reset_gpio != -1)
4201 + gpio_direction_output(display->hw_config.panel_reset_gpio, 0);
4204 +static struct omap_dss_display_config beagle_display_data_dvi = {
4205 + .type = OMAP_DISPLAY_TYPE_DPI,
4206 + .name = "dvi",
4207 + .panel_name = "panel-generic",
4208 + .u.dpi.data_lines = 24,
4209 + .panel_reset_gpio = 170,
4210 + .panel_enable = beagle_enable_dvi,
4211 + .panel_disable = beagle_disable_dvi,
4215 +static int beagle_panel_enable_tv(struct omap_display *display)
4217 +#define ENABLE_VDAC_DEDICATED 0x03
4218 +#define ENABLE_VDAC_DEV_GRP 0x20
4220 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
4221 + ENABLE_VDAC_DEDICATED,
4222 + TWL4030_VDAC_DEDICATED);
4223 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
4224 + ENABLE_VDAC_DEV_GRP, TWL4030_VDAC_DEV_GRP);
4226 + return 0;
4229 +static void beagle_panel_disable_tv(struct omap_display *display)
4231 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
4232 + TWL4030_VDAC_DEDICATED);
4233 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
4234 + TWL4030_VDAC_DEV_GRP);
4237 +static struct omap_dss_display_config beagle_display_data_tv = {
4238 + .type = OMAP_DISPLAY_TYPE_VENC,
4239 + .name = "tv",
4240 + .u.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
4241 + .panel_enable = beagle_panel_enable_tv,
4242 + .panel_disable = beagle_panel_disable_tv,
4245 +static struct omap_dss_board_info beagle_dss_data = {
4246 + .num_displays = 2,
4247 + .displays = {
4248 + &beagle_display_data_dvi,
4249 + &beagle_display_data_tv,
4253 +static struct platform_device beagle_dss_device = {
4254 + .name = "omapdss",
4255 + .id = -1,
4256 + .dev = {
4257 + .platform_data = &beagle_dss_data,
4258 + },
4261 +static void __init beagle_display_init(void)
4263 + int r;
4265 + r = gpio_request(beagle_display_data_dvi.panel_reset_gpio, "DVI reset");
4266 + if (r < 0)
4267 + printk(KERN_ERR "Unable to get DVI reset GPIO\n");
4270 static struct omap_board_config_kernel omap3_beagle_config[] __initdata = {
4271 { OMAP_TAG_UART, &omap3_beagle_uart_config },
4272 - { OMAP_TAG_LCD, &omap3_beagle_lcd_config },
4275 static struct platform_device *omap3_beagle_devices[] __initdata = {
4276 - &omap3_beagle_lcd_device,
4277 + &beagle_dss_device,
4278 &leds_gpio,
4279 &keys_gpio,
4281 @@ -428,13 +511,11 @@ static void __init omap3_beagle_init(void)
4282 omap_serial_init();
4284 omap_cfg_reg(J25_34XX_GPIO170);
4285 - gpio_request(170, "DVI_nPD");
4286 - /* REVISIT leave DVI powered down until it's needed ... */
4287 - gpio_direction_output(170, true);
4289 usb_musb_init();
4290 usb_ehci_init();
4291 omap3beagle_flash_init();
4292 + beagle_display_init();
4295 static void __init omap3_beagle_map_io(void)
4296 diff --git a/arch/arm/mach-omap2/board-omap3evm.c b/arch/arm/mach-omap2/board-omap3evm.c
4297 index 024d7c4..7a720ec 100644
4298 --- a/arch/arm/mach-omap2/board-omap3evm.c
4299 +++ b/arch/arm/mach-omap2/board-omap3evm.c
4300 @@ -36,6 +36,7 @@
4301 #include <mach/usb.h>
4302 #include <mach/common.h>
4303 #include <mach/mcspi.h>
4304 +#include <mach/display.h>
4306 #include "sdram-micron-mt46h32m32lf-6.h"
4307 #include "twl4030-generic-scripts.h"
4308 @@ -216,13 +217,201 @@ static int __init omap3_evm_i2c_init(void)
4309 return 0;
4312 -static struct platform_device omap3_evm_lcd_device = {
4313 - .name = "omap3evm_lcd",
4314 - .id = -1,
4315 +#define LCD_PANEL_LR 2
4316 +#define LCD_PANEL_UD 3
4317 +#define LCD_PANEL_INI 152
4318 +#define LCD_PANEL_ENABLE_GPIO 153
4319 +#define LCD_PANEL_QVGA 154
4320 +#define LCD_PANEL_RESB 155
4322 +#define ENABLE_VDAC_DEDICATED 0x03
4323 +#define ENABLE_VDAC_DEV_GRP 0x20
4324 +#define ENABLE_VPLL2_DEDICATED 0x05
4325 +#define ENABLE_VPLL2_DEV_GRP 0xE0
4327 +#define TWL4030_GPIODATA_IN3 0x03
4328 +#define TWL4030_GPIODATA_DIR3 0x06
4329 +#define TWL4030_VPLL2_DEV_GRP 0x33
4330 +#define TWL4030_VPLL2_DEDICATED 0x36
4332 +static int lcd_enabled;
4333 +static int dvi_enabled;
4335 +static void __init omap3_evm_display_init(void)
4337 + int r;
4338 + r = gpio_request(LCD_PANEL_LR, "lcd_panel_lr");
4339 + if (r) {
4340 + printk(KERN_ERR "failed to get LCD_PANEL_LR\n");
4341 + return;
4343 + r = gpio_request(LCD_PANEL_UD, "lcd_panel_ud");
4344 + if (r) {
4345 + printk(KERN_ERR "failed to get LCD_PANEL_UD\n");
4346 + goto err_1;
4349 + r = gpio_request(LCD_PANEL_INI, "lcd_panel_ini");
4350 + if (r) {
4351 + printk(KERN_ERR "failed to get LCD_PANEL_INI\n");
4352 + goto err_2;
4354 + r = gpio_request(LCD_PANEL_RESB, "lcd_panel_resb");
4355 + if (r) {
4356 + printk(KERN_ERR "failed to get LCD_PANEL_RESB\n");
4357 + goto err_3;
4359 + r = gpio_request(LCD_PANEL_QVGA, "lcd_panel_qvga");
4360 + if (r) {
4361 + printk(KERN_ERR "failed to get LCD_PANEL_QVGA\n");
4362 + goto err_4;
4365 + gpio_direction_output(LCD_PANEL_LR, 0);
4366 + gpio_direction_output(LCD_PANEL_UD, 0);
4367 + gpio_direction_output(LCD_PANEL_INI, 0);
4368 + gpio_direction_output(LCD_PANEL_RESB, 0);
4369 + gpio_direction_output(LCD_PANEL_QVGA, 0);
4371 +#define TWL_LED_LEDEN 0x00
4372 +#define TWL_PWMA_PWMAON 0x00
4373 +#define TWL_PWMA_PWMAOFF 0x01
4375 + twl4030_i2c_write_u8(TWL4030_MODULE_LED, 0x11, TWL_LED_LEDEN);
4376 + twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x01, TWL_PWMA_PWMAON);
4377 + twl4030_i2c_write_u8(TWL4030_MODULE_PWMA, 0x02, TWL_PWMA_PWMAOFF);
4379 + gpio_direction_output(LCD_PANEL_RESB, 1);
4380 + gpio_direction_output(LCD_PANEL_INI, 1);
4381 + gpio_direction_output(LCD_PANEL_QVGA, 0);
4382 + gpio_direction_output(LCD_PANEL_LR, 1);
4383 + gpio_direction_output(LCD_PANEL_UD, 1);
4385 + return;
4387 +err_4:
4388 + gpio_free(LCD_PANEL_RESB);
4389 +err_3:
4390 + gpio_free(LCD_PANEL_INI);
4391 +err_2:
4392 + gpio_free(LCD_PANEL_UD);
4393 +err_1:
4394 + gpio_free(LCD_PANEL_LR);
4398 +static int omap3_evm_panel_enable_lcd(struct omap_display *display)
4400 + if (dvi_enabled) {
4401 + printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
4402 + return -EINVAL;
4404 + if (omap_rev() > OMAP3430_REV_ES1_0) {
4405 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
4406 + ENABLE_VPLL2_DEDICATED, TWL4030_VPLL2_DEDICATED);
4407 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
4408 + ENABLE_VPLL2_DEV_GRP, TWL4030_VPLL2_DEV_GRP);
4410 + gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 0);
4411 + lcd_enabled = 1;
4412 + return 0;
4415 +static void omap3_evm_panel_disable_lcd(struct omap_display *display)
4417 + if (omap_rev() > OMAP3430_REV_ES1_0) {
4418 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x0,
4419 + TWL4030_VPLL2_DEDICATED);
4420 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x0,
4421 + TWL4030_VPLL2_DEV_GRP);
4423 + gpio_direction_output(LCD_PANEL_ENABLE_GPIO, 1);
4424 + lcd_enabled = 0;
4427 +static struct omap_display_data omap3_evm_display_data = {
4428 + .type = OMAP_DISPLAY_TYPE_DPI,
4429 + .name = "lcd",
4430 + .panel_name = "sharp-ls037v7dw01",
4431 + .u.dpi.data_lines = 18,
4432 + .panel_enable = omap3_evm_panel_enable_lcd,
4433 + .panel_disable = omap3_evm_panel_disable_lcd,
4436 -static struct omap_lcd_config omap3_evm_lcd_config __initdata = {
4437 - .ctrl_name = "internal",
4438 +static int omap3_evm_panel_enable_tv(struct omap_display *display)
4440 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
4441 + ENABLE_VDAC_DEDICATED, TWL4030_VDAC_DEDICATED);
4442 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER,
4443 + ENABLE_VDAC_DEV_GRP, TWL4030_VDAC_DEV_GRP);
4444 + return 0;
4447 +static void omap3_evm_panel_disable_tv(struct omap_display *display)
4449 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
4450 + TWL4030_VDAC_DEDICATED);
4451 + twl4030_i2c_write_u8(TWL4030_MODULE_PM_RECEIVER, 0x00,
4452 + TWL4030_VDAC_DEV_GRP);
4455 +static struct omap_display_data omap3_evm_display_data_tv = {
4456 + .type = OMAP_DISPLAY_TYPE_VENC,
4457 + .name = "tv",
4458 + .u.venc.type = OMAP_DSS_VENC_TYPE_SVIDEO,
4459 + .panel_enable = omap3_evm_panel_enable_tv,
4460 + .panel_disable = omap3_evm_panel_disable_tv,
4464 +static int omap3_evm_panel_enable_dvi(struct omap_display *display)
4466 + if (lcd_enabled) {
4467 + printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
4468 + return -EINVAL;
4470 + twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80,
4471 + TWL4030_GPIODATA_IN3);
4472 + twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x80,
4473 + TWL4030_GPIODATA_DIR3);
4474 + dvi_enabled = 1;
4476 + return 0;
4479 +static void omap3_evm_panel_disable_dvi(struct omap_display *display)
4481 + twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x00,
4482 + TWL4030_GPIODATA_IN3);
4483 + twl4030_i2c_write_u8(TWL4030_MODULE_GPIO, 0x00,
4484 + TWL4030_GPIODATA_DIR3);
4485 + dvi_enabled = 0;
4489 +static struct omap_display_data omap3_evm_display_data_dvi = {
4490 + .type = OMAP_DISPLAY_TYPE_DPI,
4491 + .name = "dvi",
4492 + .panel_name = "panel-generic",
4493 + .u.dpi.data_lines = 24,
4494 + .panel_enable = omap3_evm_panel_enable_dvi,
4495 + .panel_disable = omap3_evm_panel_disable_dvi,
4498 +static struct omap_dss_platform_data omap3_evm_dss_data = {
4499 + .num_displays = 3,
4500 + .displays = {
4501 + &omap3_evm_display_data,
4502 + &omap3_evm_display_data_dvi,
4503 + &omap3_evm_display_data_tv,
4506 +static struct platform_device omap3_evm_dss_device = {
4507 + .name = "omapdss",
4508 + .id = -1,
4509 + .dev = {
4510 + .platform_data = &omap3_evm_dss_data,
4511 + },
4514 static void ads7846_dev_init(void)
4515 @@ -281,11 +470,10 @@ static void __init omap3_evm_init_irq(void)
4517 static struct omap_board_config_kernel omap3_evm_config[] __initdata = {
4518 { OMAP_TAG_UART, &omap3_evm_uart_config },
4519 - { OMAP_TAG_LCD, &omap3_evm_lcd_config },
4522 static struct platform_device *omap3_evm_devices[] __initdata = {
4523 - &omap3_evm_lcd_device,
4524 + &omap3_evm_dss_device,
4525 &omap3evm_smc911x_device,
4528 @@ -305,6 +493,7 @@ static void __init omap3_evm_init(void)
4529 usb_ehci_init();
4530 omap3evm_flash_init();
4531 ads7846_dev_init();
4532 + omap3_evm_display_init();
4535 static void __init omap3_evm_map_io(void)
4536 diff --git a/arch/arm/mach-omap2/board-overo.c b/arch/arm/mach-omap2/board-overo.c
4537 index 071f4b0..267bb6b 100644
4538 --- a/arch/arm/mach-omap2/board-overo.c
4539 +++ b/arch/arm/mach-omap2/board-overo.c
4540 @@ -41,6 +41,7 @@
4541 #include <mach/board-overo.h>
4542 #include <mach/board.h>
4543 #include <mach/common.h>
4544 +#include <mach/display.h>
4545 #include <mach/gpio.h>
4546 #include <mach/gpmc.h>
4547 #include <mach/hardware.h>
4548 @@ -176,6 +177,9 @@ static void __init overo_ads7846_init(void)
4549 static inline void __init overo_ads7846_init(void) { return; }
4550 #endif
4552 +static int lcd_enabled;
4553 +static int dvi_enabled;
4555 static struct mtd_partition overo_nand_partitions[] = {
4557 .name = "xloader",
4558 @@ -360,22 +364,101 @@ static void __init overo_init_irq(void)
4559 omap_gpio_init();
4562 -static struct platform_device overo_lcd_device = {
4563 - .name = "overo_lcd",
4564 - .id = -1,
4565 +/* DSS */
4567 +#define OVERO_GPIO_LCD_EN 144
4569 +static void __init overo_display_init(void)
4571 + int r;
4573 + r = gpio_request(OVERO_GPIO_LCD_EN, "display enable");
4574 + if (r)
4575 + printk("fail1\n");
4576 + r = gpio_direction_output(OVERO_GPIO_LCD_EN, 1);
4577 + if (r)
4578 + printk("fail2\n");
4579 + gpio_export(OVERO_GPIO_LCD_EN, 0);
4582 +static int overo_panel_enable_dvi(struct omap_display *display)
4584 + if (lcd_enabled) {
4585 + printk(KERN_ERR "cannot enable DVI, LCD is enabled\n");
4586 + return -EINVAL;
4588 + dvi_enabled = 1;
4590 + gpio_set_value(OVERO_GPIO_LCD_EN, 1);
4592 + return 0;
4595 +static void overo_panel_disable_dvi(struct omap_display *display)
4597 + gpio_set_value(OVERO_GPIO_LCD_EN, 0);
4599 + dvi_enabled = 0;
4602 +static struct omap_dss_display_config overo_display_data_dvi = {
4603 + .type = OMAP_DISPLAY_TYPE_DPI,
4604 + .name = "dvi",
4605 + .panel_name = "panel-generic",
4606 + .u.dpi.data_lines = 24,
4607 + .panel_enable = overo_panel_enable_dvi,
4608 + .panel_disable = overo_panel_disable_dvi,
4611 -static struct omap_lcd_config overo_lcd_config __initdata = {
4612 - .ctrl_name = "internal",
4613 +static int overo_panel_enable_lcd(struct omap_display *display)
4615 + if (dvi_enabled) {
4616 + printk(KERN_ERR "cannot enable LCD, DVI is enabled\n");
4617 + return -EINVAL;
4620 + gpio_set_value(OVERO_GPIO_LCD_EN, 1);
4621 + lcd_enabled = 1;
4622 + return 0;
4625 +static void overo_panel_disable_lcd(struct omap_display *display)
4627 + gpio_set_value(OVERO_GPIO_LCD_EN, 0);
4628 + lcd_enabled = 0;
4631 +static struct omap_dss_display_config overo_display_data_lcd = {
4632 + .type = OMAP_DISPLAY_TYPE_DPI,
4633 + .name = "lcd",
4634 + .panel_name = "samsung-lte430wq-f0c",
4635 + .u.dpi.data_lines = 24,
4636 + .panel_enable = overo_panel_enable_lcd,
4637 + .panel_disable = overo_panel_disable_lcd,
4638 + };
4640 +static struct omap_dss_board_info overo_dss_data = {
4641 + .num_displays = 2,
4642 + .displays = {
4643 + &overo_display_data_dvi,
4644 + &overo_display_data_lcd,
4648 +static struct platform_device overo_dss_device = {
4649 + .name = "omapdss",
4650 + .id = -1,
4651 + .dev = {
4652 + .platform_data = &overo_dss_data,
4653 + },
4656 static struct omap_board_config_kernel overo_config[] __initdata = {
4657 { OMAP_TAG_UART, &overo_uart_config },
4658 - { OMAP_TAG_LCD, &overo_lcd_config },
4661 static struct platform_device *overo_devices[] __initdata = {
4662 - &overo_lcd_device,
4663 + &overo_dss_device,
4666 static void __init overo_init(void)
4667 @@ -390,6 +473,7 @@ static void __init overo_init(void)
4668 overo_flash_init();
4669 overo_init_smsc911x();
4670 overo_ads7846_init();
4671 + overo_display_init();
4673 if ((gpio_request(OVERO_GPIO_W2W_NRESET,
4674 "OVERO_GPIO_W2W_NRESET") == 0) &&
4675 diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c
4676 index adbe21f..a04e3ee 100644
4677 --- a/arch/arm/mach-omap2/io.c
4678 +++ b/arch/arm/mach-omap2/io.c
4679 @@ -18,13 +18,13 @@
4680 #include <linux/module.h>
4681 #include <linux/kernel.h>
4682 #include <linux/init.h>
4683 +#include <linux/omapfb.h>
4684 #include <linux/io.h>
4686 #include <asm/tlb.h>
4688 #include <asm/mach/map.h>
4689 #include <mach/mux.h>
4690 -#include <mach/omapfb.h>
4691 #include <mach/sram.h>
4692 #include <mach/sdrc.h>
4693 #include <mach/gpmc.h>
4694 diff --git a/arch/arm/plat-omap/Makefile b/arch/arm/plat-omap/Makefile
4695 index 3ebc09e..e6146b2 100644
4696 --- a/arch/arm/plat-omap/Makefile
4697 +++ b/arch/arm/plat-omap/Makefile
4698 @@ -4,7 +4,7 @@
4700 # Common support
4701 obj-y := common.o sram.o clock.o devices.o dma.o mux.o gpio.o \
4702 - usb.o fb.o io.o
4703 + usb.o fb.o vram.o vrfb.o io.o
4704 obj-m :=
4705 obj-n :=
4706 obj- :=
4707 diff --git a/arch/arm/plat-omap/fb.c b/arch/arm/plat-omap/fb.c
4708 index 3746222..1dc3415 100644
4709 --- a/arch/arm/plat-omap/fb.c
4710 +++ b/arch/arm/plat-omap/fb.c
4711 @@ -28,13 +28,13 @@
4712 #include <linux/platform_device.h>
4713 #include <linux/bootmem.h>
4714 #include <linux/io.h>
4715 +#include <linux/omapfb.h>
4717 #include <mach/hardware.h>
4718 #include <asm/mach/map.h>
4720 #include <mach/board.h>
4721 #include <mach/sram.h>
4722 -#include <mach/omapfb.h>
4724 #if defined(CONFIG_FB_OMAP) || defined(CONFIG_FB_OMAP_MODULE)
4726 @@ -327,6 +327,34 @@ static inline int omap_init_fb(void)
4728 arch_initcall(omap_init_fb);
4730 +#elif defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
4732 +static u64 omap_fb_dma_mask = ~(u32)0;
4733 +static struct omapfb_platform_data omapfb_config;
4735 +static struct platform_device omap_fb_device = {
4736 + .name = "omapfb",
4737 + .id = -1,
4738 + .dev = {
4739 + .dma_mask = &omap_fb_dma_mask,
4740 + .coherent_dma_mask = ~(u32)0,
4741 + .platform_data = &omapfb_config,
4742 + },
4743 + .num_resources = 0,
4746 +void omapfb_set_platform_data(struct omapfb_platform_data *data)
4748 + omapfb_config = *data;
4751 +static inline int omap_init_fb(void)
4753 + return platform_device_register(&omap_fb_device);
4756 +arch_initcall(omap_init_fb);
4758 #else
4760 void omapfb_reserve_sdram(void) {}
4761 diff --git a/arch/arm/plat-omap/include/mach/display.h b/arch/arm/plat-omap/include/mach/display.h
4762 new file mode 100644
4763 index 0000000..6288353
4764 --- /dev/null
4765 +++ b/arch/arm/plat-omap/include/mach/display.h
4766 @@ -0,0 +1,520 @@
4768 + * linux/include/asm-arm/arch-omap/display.h
4770 + * Copyright (C) 2008 Nokia Corporation
4771 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
4773 + * This program is free software; you can redistribute it and/or modify it
4774 + * under the terms of the GNU General Public License version 2 as published by
4775 + * the Free Software Foundation.
4777 + * This program is distributed in the hope that it will be useful, but WITHOUT
4778 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
4779 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
4780 + * more details.
4782 + * You should have received a copy of the GNU General Public License along with
4783 + * this program. If not, see <http://www.gnu.org/licenses/>.
4784 + */
4786 +#ifndef __ASM_ARCH_OMAP_DISPLAY_H
4787 +#define __ASM_ARCH_OMAP_DISPLAY_H
4789 +#include <linux/list.h>
4790 +#include <linux/kobject.h>
4791 +#include <asm/atomic.h>
4793 +#define DISPC_IRQ_FRAMEDONE (1 << 0)
4794 +#define DISPC_IRQ_VSYNC (1 << 1)
4795 +#define DISPC_IRQ_EVSYNC_EVEN (1 << 2)
4796 +#define DISPC_IRQ_EVSYNC_ODD (1 << 3)
4797 +#define DISPC_IRQ_ACBIAS_COUNT_STAT (1 << 4)
4798 +#define DISPC_IRQ_PROG_LINE_NUM (1 << 5)
4799 +#define DISPC_IRQ_GFX_FIFO_UNDERFLOW (1 << 6)
4800 +#define DISPC_IRQ_GFX_END_WIN (1 << 7)
4801 +#define DISPC_IRQ_PAL_GAMMA_MASK (1 << 8)
4802 +#define DISPC_IRQ_OCP_ERR (1 << 9)
4803 +#define DISPC_IRQ_VID1_FIFO_UNDERFLOW (1 << 10)
4804 +#define DISPC_IRQ_VID1_END_WIN (1 << 11)
4805 +#define DISPC_IRQ_VID2_FIFO_UNDERFLOW (1 << 12)
4806 +#define DISPC_IRQ_VID2_END_WIN (1 << 13)
4807 +#define DISPC_IRQ_SYNC_LOST (1 << 14)
4808 +#define DISPC_IRQ_SYNC_LOST_DIGIT (1 << 15)
4809 +#define DISPC_IRQ_WAKEUP (1 << 16)
4811 +enum omap_display_type {
4812 + OMAP_DISPLAY_TYPE_NONE = 0,
4813 + OMAP_DISPLAY_TYPE_DPI = 1 << 0,
4814 + OMAP_DISPLAY_TYPE_DBI = 1 << 1,
4815 + OMAP_DISPLAY_TYPE_SDI = 1 << 2,
4816 + OMAP_DISPLAY_TYPE_DSI = 1 << 3,
4817 + OMAP_DISPLAY_TYPE_VENC = 1 << 4,
4820 +enum omap_plane {
4821 + OMAP_DSS_GFX = 0,
4822 + OMAP_DSS_VIDEO1 = 1,
4823 + OMAP_DSS_VIDEO2 = 2
4826 +enum omap_channel {
4827 + OMAP_DSS_CHANNEL_LCD = 0,
4828 + OMAP_DSS_CHANNEL_DIGIT = 1,
4831 +enum omap_color_mode {
4832 + OMAP_DSS_COLOR_CLUT1 = 1 << 0, /* BITMAP 1 */
4833 + OMAP_DSS_COLOR_CLUT2 = 1 << 1, /* BITMAP 2 */
4834 + OMAP_DSS_COLOR_CLUT4 = 1 << 2, /* BITMAP 4 */
4835 + OMAP_DSS_COLOR_CLUT8 = 1 << 3, /* BITMAP 8 */
4836 + OMAP_DSS_COLOR_RGB12U = 1 << 4, /* RGB12, 16-bit container */
4837 + OMAP_DSS_COLOR_ARGB16 = 1 << 5, /* ARGB16 */
4838 + OMAP_DSS_COLOR_RGB16 = 1 << 6, /* RGB16 */
4839 + OMAP_DSS_COLOR_RGB24U = 1 << 7, /* RGB24, 32-bit container */
4840 + OMAP_DSS_COLOR_RGB24P = 1 << 8, /* RGB24, 24-bit container */
4841 + OMAP_DSS_COLOR_YUV2 = 1 << 9, /* YUV2 4:2:2 co-sited */
4842 + OMAP_DSS_COLOR_UYVY = 1 << 10, /* UYVY 4:2:2 co-sited */
4843 + OMAP_DSS_COLOR_ARGB32 = 1 << 11, /* ARGB32 */
4844 + OMAP_DSS_COLOR_RGBA32 = 1 << 12, /* RGBA32 */
4845 + OMAP_DSS_COLOR_RGBX32 = 1 << 13, /* RGBx32 */
4847 + OMAP_DSS_COLOR_GFX_OMAP3 =
4848 + OMAP_DSS_COLOR_CLUT1 | OMAP_DSS_COLOR_CLUT2 |
4849 + OMAP_DSS_COLOR_CLUT4 | OMAP_DSS_COLOR_CLUT8 |
4850 + OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
4851 + OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
4852 + OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
4853 + OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32,
4855 + OMAP_DSS_COLOR_VID_OMAP3 =
4856 + OMAP_DSS_COLOR_RGB12U | OMAP_DSS_COLOR_ARGB16 |
4857 + OMAP_DSS_COLOR_RGB16 | OMAP_DSS_COLOR_RGB24U |
4858 + OMAP_DSS_COLOR_RGB24P | OMAP_DSS_COLOR_ARGB32 |
4859 + OMAP_DSS_COLOR_RGBA32 | OMAP_DSS_COLOR_RGBX32 |
4860 + OMAP_DSS_COLOR_YUV2 | OMAP_DSS_COLOR_UYVY,
4863 +enum omap_lcd_display_type {
4864 + OMAP_DSS_LCD_DISPLAY_STN,
4865 + OMAP_DSS_LCD_DISPLAY_TFT,
4868 +enum omap_dss_load_mode {
4869 + OMAP_DSS_LOAD_CLUT_AND_FRAME = 0,
4870 + OMAP_DSS_LOAD_CLUT_ONLY = 1,
4871 + OMAP_DSS_LOAD_FRAME_ONLY = 2,
4872 + OMAP_DSS_LOAD_CLUT_ONCE_FRAME = 3,
4875 +enum omap_dss_color_key_type {
4876 + OMAP_DSS_COLOR_KEY_GFX_DST = 0,
4877 + OMAP_DSS_COLOR_KEY_VID_SRC = 1,
4880 +enum omap_rfbi_te_mode {
4881 + OMAP_DSS_RFBI_TE_MODE_1 = 1,
4882 + OMAP_DSS_RFBI_TE_MODE_2 = 2,
4885 +enum omap_panel_config {
4886 + OMAP_DSS_LCD_IVS = 1<<0,
4887 + OMAP_DSS_LCD_IHS = 1<<1,
4888 + OMAP_DSS_LCD_IPC = 1<<2,
4889 + OMAP_DSS_LCD_IEO = 1<<3,
4890 + OMAP_DSS_LCD_RF = 1<<4,
4891 + OMAP_DSS_LCD_ONOFF = 1<<5,
4893 + OMAP_DSS_LCD_TFT = 1<<20,
4896 +enum omap_dss_venc_type {
4897 + OMAP_DSS_VENC_TYPE_COMPOSITE,
4898 + OMAP_DSS_VENC_TYPE_SVIDEO,
4901 +struct omap_display;
4902 +struct omap_panel;
4903 +struct omap_ctrl;
4905 +/* RFBI */
4907 +struct rfbi_timings {
4908 + int cs_on_time;
4909 + int cs_off_time;
4910 + int we_on_time;
4911 + int we_off_time;
4912 + int re_on_time;
4913 + int re_off_time;
4914 + int we_cycle_time;
4915 + int re_cycle_time;
4916 + int cs_pulse_width;
4917 + int access_time;
4919 + int clk_div;
4921 + u32 tim[5]; /* set by rfbi_convert_timings() */
4923 + int converted;
4926 +void omap_rfbi_write_command(const void *buf, u32 len);
4927 +void omap_rfbi_read_data(void *buf, u32 len);
4928 +void omap_rfbi_write_data(const void *buf, u32 len);
4929 +void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
4930 + u16 x, u16 y,
4931 + u16 w, u16 h);
4932 +int omap_rfbi_enable_te(bool enable, unsigned line);
4933 +int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
4934 + unsigned hs_pulse_time, unsigned vs_pulse_time,
4935 + int hs_pol_inv, int vs_pol_inv, int extif_div);
4937 +/* DSI */
4938 +int dsi_vc_dcs_write(int channel, u8 *data, int len);
4939 +int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len);
4940 +int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen);
4941 +int dsi_vc_set_max_rx_packet_size(int channel, u16 len);
4942 +int dsi_vc_send_null(int channel);
4944 +/* Board specific data */
4945 +struct omap_dss_display_config {
4946 + enum omap_display_type type;
4948 + union {
4949 + struct {
4950 + u8 data_lines;
4951 + } dpi;
4953 + struct {
4954 + u8 channel;
4955 + u8 data_lines;
4956 + } rfbi;
4958 + struct {
4959 + u8 datapairs;
4960 + } sdi;
4962 + struct {
4963 + u8 clk_lane;
4964 + u8 clk_pol;
4965 + u8 data1_lane;
4966 + u8 data1_pol;
4967 + u8 data2_lane;
4968 + u8 data2_pol;
4969 + unsigned long ddr_clk_hz;
4970 + } dsi;
4972 + struct {
4973 + enum omap_dss_venc_type type;
4974 + } venc;
4975 + } u;
4977 + int panel_reset_gpio;
4978 + int ctrl_reset_gpio;
4980 + const char *name; /* for debug */
4981 + const char *ctrl_name;
4982 + const char *panel_name;
4984 + void *panel_data;
4985 + void *ctrl_data;
4987 + /* platform specific enable/disable */
4988 + int (*panel_enable)(struct omap_display *display);
4989 + void (*panel_disable)(struct omap_display *display);
4990 + int (*ctrl_enable)(struct omap_display *display);
4991 + void (*ctrl_disable)(struct omap_display *display);
4992 + int (*set_backlight)(struct omap_display *display,
4993 + int level);
4996 +struct device;
4998 +/* Board specific data */
4999 +struct omap_dss_board_info {
5000 + unsigned (*get_last_off_on_transaction_id)(struct device *dev);
5001 + int (*dsi_power_up)(void);
5002 + void (*dsi_power_down)(void);
5003 + int num_displays;
5004 + struct omap_dss_display_config *displays[];
5007 +struct omap_ctrl {
5008 + struct module *owner;
5010 + const char *name;
5012 + int (*init)(struct omap_display *display);
5013 + void (*cleanup)(struct omap_display *display);
5014 + int (*enable)(struct omap_display *display);
5015 + void (*disable)(struct omap_display *display);
5016 + int (*suspend)(struct omap_display *display);
5017 + int (*resume)(struct omap_display *display);
5018 + void (*setup_update)(struct omap_display *display,
5019 + u16 x, u16 y, u16 w, u16 h);
5021 + int (*enable_te)(struct omap_display *display, bool enable);
5023 + u8 (*get_rotate)(struct omap_display *display);
5024 + int (*set_rotate)(struct omap_display *display, u8 rotate);
5026 + bool (*get_mirror)(struct omap_display *display);
5027 + int (*set_mirror)(struct omap_display *display, bool enable);
5029 + int (*run_test)(struct omap_display *display, int test);
5030 + int (*memory_read)(struct omap_display *display,
5031 + void *buf, size_t size,
5032 + u16 x, u16 y, u16 w, u16 h);
5034 + u8 pixel_size;
5036 + struct rfbi_timings timings;
5038 + void *priv;
5041 +struct omap_video_timings {
5042 + /* Unit: pixels */
5043 + u16 x_res;
5044 + /* Unit: pixels */
5045 + u16 y_res;
5046 + /* Unit: KHz */
5047 + u32 pixel_clock;
5048 + /* Unit: pixel clocks */
5049 + u16 hsw; /* Horizontal synchronization pulse width */
5050 + /* Unit: pixel clocks */
5051 + u16 hfp; /* Horizontal front porch */
5052 + /* Unit: pixel clocks */
5053 + u16 hbp; /* Horizontal back porch */
5054 + /* Unit: line clocks */
5055 + u16 vsw; /* Vertical synchronization pulse width */
5056 + /* Unit: line clocks */
5057 + u16 vfp; /* Vertical front porch */
5058 + /* Unit: line clocks */
5059 + u16 vbp; /* Vertical back porch */
5063 +#ifdef CONFIG_OMAP2_DSS_VENC
5064 +/* Hardcoded timings for tv modes. Venc only uses these to
5065 + * identify the mode, and does not actually use the configs
5066 + * itself. However, the configs should be something that
5067 + * a normal monitor can also show */
5068 +const extern struct omap_video_timings omap_dss_pal_timings;
5069 +const extern struct omap_video_timings omap_dss_ntsc_timings;
5070 +#endif
5072 +struct omap_panel {
5073 + struct module *owner;
5075 + const char *name;
5077 + int (*init)(struct omap_display *display);
5078 + void (*cleanup)(struct omap_display *display);
5079 + int (*remove)(struct omap_display *display);
5080 + int (*enable)(struct omap_display *display);
5081 + void (*disable)(struct omap_display *display);
5082 + int (*suspend)(struct omap_display *display);
5083 + int (*resume)(struct omap_display *display);
5084 + int (*run_test)(struct omap_display *display, int test);
5086 + struct omap_video_timings timings;
5088 + int acbi; /* ac-bias pin transitions per interrupt */
5089 + /* Unit: line clocks */
5090 + int acb; /* ac-bias pin frequency */
5092 + enum omap_panel_config config;
5094 + u8 recommended_bpp;
5096 + void *priv;
5099 +/* XXX perhaps this should be removed */
5100 +enum omap_dss_overlay_managers {
5101 + OMAP_DSS_OVL_MGR_LCD,
5102 + OMAP_DSS_OVL_MGR_TV,
5105 +struct omap_overlay_manager;
5107 +struct omap_overlay_info {
5108 + bool enabled;
5110 + u32 paddr;
5111 + void __iomem *vaddr;
5112 + u16 screen_width;
5113 + u16 width;
5114 + u16 height;
5115 + enum omap_color_mode color_mode;
5116 + u8 rotation;
5117 + bool mirror;
5119 + u16 pos_x;
5120 + u16 pos_y;
5121 + u16 out_width; /* if 0, out_width == width */
5122 + u16 out_height; /* if 0, out_height == height */
5125 +enum omap_overlay_caps {
5126 + OMAP_DSS_OVL_CAP_SCALE = 1 << 0,
5127 + OMAP_DSS_OVL_CAP_DISPC = 1 << 1,
5130 +struct omap_overlay {
5131 + struct kobject kobj;
5132 + struct list_head list;
5134 + const char *name;
5135 + int id;
5136 + struct omap_overlay_manager *manager;
5137 + enum omap_color_mode supported_modes;
5138 + struct omap_overlay_info info;
5139 + enum omap_overlay_caps caps;
5141 + int (*set_manager)(struct omap_overlay *ovl,
5142 + struct omap_overlay_manager *mgr);
5143 + int (*unset_manager)(struct omap_overlay *ovl);
5145 + int (*set_overlay_info)(struct omap_overlay *ovl,
5146 + struct omap_overlay_info *info);
5147 + void (*get_overlay_info)(struct omap_overlay *ovl,
5148 + struct omap_overlay_info *info);
5151 +enum omap_overlay_manager_caps {
5152 + OMAP_DSS_OVL_MGR_CAP_DISPC = 1 << 0,
5155 +struct omap_overlay_manager {
5156 + struct kobject kobj;
5157 + struct list_head list;
5159 + const char *name;
5160 + int id;
5161 + enum omap_overlay_manager_caps caps;
5162 + struct omap_display *display;
5163 + int num_overlays;
5164 + struct omap_overlay **overlays;
5165 + enum omap_display_type supported_displays;
5167 + int (*set_display)(struct omap_overlay_manager *mgr,
5168 + struct omap_display *display);
5169 + int (*unset_display)(struct omap_overlay_manager *mgr);
5171 + int (*apply)(struct omap_overlay_manager *mgr);
5173 + void (*set_default_color)(struct omap_overlay_manager *mgr, u32 color);
5174 + void (*set_trans_key)(struct omap_overlay_manager *mgr,
5175 + enum omap_dss_color_key_type type,
5176 + u32 trans_key);
5177 + void (*enable_trans_key)(struct omap_overlay_manager *mgr,
5178 + bool enable);
5181 +enum omap_display_caps {
5182 + OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE = 1 << 0,
5185 +enum omap_dss_update_mode {
5186 + OMAP_DSS_UPDATE_DISABLED = 0,
5187 + OMAP_DSS_UPDATE_AUTO,
5188 + OMAP_DSS_UPDATE_MANUAL,
5191 +enum omap_dss_display_state {
5192 + OMAP_DSS_DISPLAY_DISABLED = 0,
5193 + OMAP_DSS_DISPLAY_ACTIVE,
5194 + OMAP_DSS_DISPLAY_SUSPENDED,
5197 +struct omap_display {
5198 + struct kobject kobj;
5199 + struct list_head list;
5201 + /*atomic_t ref_count;*/
5202 + int ref_count;
5203 + /* helper variable for driver suspend/resume */
5204 + int activate_after_resume;
5206 + enum omap_display_type type;
5207 + const char *name;
5209 + enum omap_display_caps caps;
5211 + struct omap_overlay_manager *manager;
5213 + enum omap_dss_display_state state;
5215 + struct omap_dss_display_config hw_config; /* board specific data */
5216 + struct omap_ctrl *ctrl; /* static common data */
5217 + struct omap_panel *panel; /* static common data */
5219 + int (*enable)(struct omap_display *display);
5220 + void (*disable)(struct omap_display *display);
5222 + int (*suspend)(struct omap_display *display);
5223 + int (*resume)(struct omap_display *display);
5225 + void (*get_resolution)(struct omap_display *display,
5226 + u16 *xres, u16 *yres);
5227 + int (*get_recommended_bpp)(struct omap_display *display);
5229 + int (*check_timings)(struct omap_display *display,
5230 + struct omap_video_timings *timings);
5231 + void (*set_timings)(struct omap_display *display,
5232 + struct omap_video_timings *timings);
5233 + void (*get_timings)(struct omap_display *display,
5234 + struct omap_video_timings *timings);
5235 + int (*update)(struct omap_display *display,
5236 + u16 x, u16 y, u16 w, u16 h);
5237 + int (*sync)(struct omap_display *display);
5238 + int (*wait_vsync)(struct omap_display *display);
5240 + int (*set_update_mode)(struct omap_display *display,
5241 + enum omap_dss_update_mode);
5242 + enum omap_dss_update_mode (*get_update_mode)
5243 + (struct omap_display *display);
5245 + int (*enable_te)(struct omap_display *display, bool enable);
5246 + int (*get_te)(struct omap_display *display);
5248 + u8 (*get_rotate)(struct omap_display *display);
5249 + int (*set_rotate)(struct omap_display *display, u8 rotate);
5251 + bool (*get_mirror)(struct omap_display *display);
5252 + int (*set_mirror)(struct omap_display *display, bool enable);
5254 + int (*run_test)(struct omap_display *display, int test);
5255 + int (*memory_read)(struct omap_display *display,
5256 + void *buf, size_t size,
5257 + u16 x, u16 y, u16 w, u16 h);
5259 + void (*configure_overlay)(struct omap_overlay *overlay);
5262 +int omap_dss_get_num_displays(void);
5263 +struct omap_display *omap_dss_get_display(int no);
5264 +void omap_dss_put_display(struct omap_display *display);
5266 +void omap_dss_register_ctrl(struct omap_ctrl *ctrl);
5267 +void omap_dss_unregister_ctrl(struct omap_ctrl *ctrl);
5269 +void omap_dss_register_panel(struct omap_panel *panel);
5270 +void omap_dss_unregister_panel(struct omap_panel *panel);
5272 +int omap_dss_get_num_overlay_managers(void);
5273 +struct omap_overlay_manager *omap_dss_get_overlay_manager(int num);
5275 +int omap_dss_get_num_overlays(void);
5276 +struct omap_overlay *omap_dss_get_overlay(int num);
5278 +typedef void (*omap_dispc_isr_t) (void *arg, u32 mask);
5279 +int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
5280 +int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask);
5282 +int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout);
5283 +int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
5284 + unsigned long timeout);
5286 +#endif
5287 diff --git a/arch/arm/plat-omap/include/mach/omapfb.h b/arch/arm/plat-omap/include/mach/omapfb.h
5288 deleted file mode 100644
5289 index b226bdf..0000000
5290 --- a/arch/arm/plat-omap/include/mach/omapfb.h
5291 +++ /dev/null
5292 @@ -1,398 +0,0 @@
5294 - * File: arch/arm/plat-omap/include/mach/omapfb.h
5296 - * Framebuffer driver for TI OMAP boards
5298 - * Copyright (C) 2004 Nokia Corporation
5299 - * Author: Imre Deak <imre.deak@nokia.com>
5301 - * This program is free software; you can redistribute it and/or modify it
5302 - * under the terms of the GNU General Public License as published by the
5303 - * Free Software Foundation; either version 2 of the License, or (at your
5304 - * option) any later version.
5306 - * This program is distributed in the hope that it will be useful, but
5307 - * WITHOUT ANY WARRANTY; without even the implied warranty of
5308 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5309 - * General Public License for more details.
5311 - * You should have received a copy of the GNU General Public License along
5312 - * with this program; if not, write to the Free Software Foundation, Inc.,
5313 - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5314 - */
5316 -#ifndef __OMAPFB_H
5317 -#define __OMAPFB_H
5319 -#include <asm/ioctl.h>
5320 -#include <asm/types.h>
5322 -/* IOCTL commands. */
5324 -#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
5325 -#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
5326 -#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
5327 -#define OMAP_IO(num) _IO('O', num)
5329 -#define OMAPFB_MIRROR OMAP_IOW(31, int)
5330 -#define OMAPFB_SYNC_GFX OMAP_IO(37)
5331 -#define OMAPFB_VSYNC OMAP_IO(38)
5332 -#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
5333 -#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps)
5334 -#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
5335 -#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
5336 -#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
5337 -#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
5338 -#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
5339 -#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
5340 -#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
5341 -#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
5342 -#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
5343 -#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
5344 -#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
5346 -#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
5347 -#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
5348 -#define OMAPFB_CAPS_PANEL_MASK 0xff000000
5350 -#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
5351 -#define OMAPFB_CAPS_TEARSYNC 0x00002000
5352 -#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000
5353 -#define OMAPFB_CAPS_PLANE_SCALE 0x00008000
5354 -#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
5355 -#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
5356 -#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
5357 -#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
5358 -#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
5360 -/* Values from DSP must map to lower 16-bits */
5361 -#define OMAPFB_FORMAT_MASK 0x00ff
5362 -#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
5363 -#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
5364 -#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400
5365 -#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800
5366 -#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000
5368 -#define OMAPFB_EVENT_READY 1
5369 -#define OMAPFB_EVENT_DISABLED 2
5371 -#define OMAPFB_MEMTYPE_SDRAM 0
5372 -#define OMAPFB_MEMTYPE_SRAM 1
5373 -#define OMAPFB_MEMTYPE_MAX 1
5375 -enum omapfb_color_format {
5376 - OMAPFB_COLOR_RGB565 = 0,
5377 - OMAPFB_COLOR_YUV422,
5378 - OMAPFB_COLOR_YUV420,
5379 - OMAPFB_COLOR_CLUT_8BPP,
5380 - OMAPFB_COLOR_CLUT_4BPP,
5381 - OMAPFB_COLOR_CLUT_2BPP,
5382 - OMAPFB_COLOR_CLUT_1BPP,
5383 - OMAPFB_COLOR_RGB444,
5384 - OMAPFB_COLOR_YUY422,
5387 -struct omapfb_update_window {
5388 - __u32 x, y;
5389 - __u32 width, height;
5390 - __u32 format;
5391 - __u32 out_x, out_y;
5392 - __u32 out_width, out_height;
5393 - __u32 reserved[8];
5396 -struct omapfb_update_window_old {
5397 - __u32 x, y;
5398 - __u32 width, height;
5399 - __u32 format;
5402 -enum omapfb_plane {
5403 - OMAPFB_PLANE_GFX = 0,
5404 - OMAPFB_PLANE_VID1,
5405 - OMAPFB_PLANE_VID2,
5408 -enum omapfb_channel_out {
5409 - OMAPFB_CHANNEL_OUT_LCD = 0,
5410 - OMAPFB_CHANNEL_OUT_DIGIT,
5413 -struct omapfb_plane_info {
5414 - __u32 pos_x;
5415 - __u32 pos_y;
5416 - __u8 enabled;
5417 - __u8 channel_out;
5418 - __u8 mirror;
5419 - __u8 reserved1;
5420 - __u32 out_width;
5421 - __u32 out_height;
5422 - __u32 reserved2[12];
5425 -struct omapfb_mem_info {
5426 - __u32 size;
5427 - __u8 type;
5428 - __u8 reserved[3];
5431 -struct omapfb_caps {
5432 - __u32 ctrl;
5433 - __u32 plane_color;
5434 - __u32 wnd_color;
5437 -enum omapfb_color_key_type {
5438 - OMAPFB_COLOR_KEY_DISABLED = 0,
5439 - OMAPFB_COLOR_KEY_GFX_DST,
5440 - OMAPFB_COLOR_KEY_VID_SRC,
5443 -struct omapfb_color_key {
5444 - __u8 channel_out;
5445 - __u32 background;
5446 - __u32 trans_key;
5447 - __u8 key_type;
5450 -enum omapfb_update_mode {
5451 - OMAPFB_UPDATE_DISABLED = 0,
5452 - OMAPFB_AUTO_UPDATE,
5453 - OMAPFB_MANUAL_UPDATE
5456 -#ifdef __KERNEL__
5458 -#include <linux/completion.h>
5459 -#include <linux/interrupt.h>
5460 -#include <linux/fb.h>
5461 -#include <linux/mutex.h>
5463 -#include <mach/board.h>
5465 -#define OMAP_LCDC_INV_VSYNC 0x0001
5466 -#define OMAP_LCDC_INV_HSYNC 0x0002
5467 -#define OMAP_LCDC_INV_PIX_CLOCK 0x0004
5468 -#define OMAP_LCDC_INV_OUTPUT_EN 0x0008
5469 -#define OMAP_LCDC_HSVS_RISING_EDGE 0x0010
5470 -#define OMAP_LCDC_HSVS_OPPOSITE 0x0020
5472 -#define OMAP_LCDC_SIGNAL_MASK 0x003f
5474 -#define OMAP_LCDC_PANEL_TFT 0x0100
5476 -#define OMAPFB_PLANE_XRES_MIN 8
5477 -#define OMAPFB_PLANE_YRES_MIN 8
5479 -#ifdef CONFIG_ARCH_OMAP1
5480 -#define OMAPFB_PLANE_NUM 1
5481 -#else
5482 -#define OMAPFB_PLANE_NUM 3
5483 -#endif
5485 -struct omapfb_device;
5487 -struct lcd_panel {
5488 - const char *name;
5489 - int config; /* TFT/STN, signal inversion */
5490 - int bpp; /* Pixel format in fb mem */
5491 - int data_lines; /* Lines on LCD HW interface */
5493 - int x_res, y_res;
5494 - int pixel_clock; /* In kHz */
5495 - int hsw; /* Horizontal synchronization
5496 - pulse width */
5497 - int hfp; /* Horizontal front porch */
5498 - int hbp; /* Horizontal back porch */
5499 - int vsw; /* Vertical synchronization
5500 - pulse width */
5501 - int vfp; /* Vertical front porch */
5502 - int vbp; /* Vertical back porch */
5503 - int acb; /* ac-bias pin frequency */
5504 - int pcd; /* pixel clock divider.
5505 - Obsolete use pixel_clock instead */
5507 - int (*init) (struct lcd_panel *panel,
5508 - struct omapfb_device *fbdev);
5509 - void (*cleanup) (struct lcd_panel *panel);
5510 - int (*enable) (struct lcd_panel *panel);
5511 - void (*disable) (struct lcd_panel *panel);
5512 - unsigned long (*get_caps) (struct lcd_panel *panel);
5513 - int (*set_bklight_level)(struct lcd_panel *panel,
5514 - unsigned int level);
5515 - unsigned int (*get_bklight_level)(struct lcd_panel *panel);
5516 - unsigned int (*get_bklight_max) (struct lcd_panel *panel);
5517 - int (*run_test) (struct lcd_panel *panel, int test_num);
5520 -struct extif_timings {
5521 - int cs_on_time;
5522 - int cs_off_time;
5523 - int we_on_time;
5524 - int we_off_time;
5525 - int re_on_time;
5526 - int re_off_time;
5527 - int we_cycle_time;
5528 - int re_cycle_time;
5529 - int cs_pulse_width;
5530 - int access_time;
5532 - int clk_div;
5534 - u32 tim[5]; /* set by extif->convert_timings */
5536 - int converted;
5539 -struct lcd_ctrl_extif {
5540 - int (*init) (struct omapfb_device *fbdev);
5541 - void (*cleanup) (void);
5542 - void (*get_clk_info) (u32 *clk_period, u32 *max_clk_div);
5543 - unsigned long (*get_max_tx_rate)(void);
5544 - int (*convert_timings) (struct extif_timings *timings);
5545 - void (*set_timings) (const struct extif_timings *timings);
5546 - void (*set_bits_per_cycle)(int bpc);
5547 - void (*write_command) (const void *buf, unsigned int len);
5548 - void (*read_data) (void *buf, unsigned int len);
5549 - void (*write_data) (const void *buf, unsigned int len);
5550 - void (*transfer_area) (int width, int height,
5551 - void (callback)(void * data), void *data);
5552 - int (*setup_tearsync) (unsigned pin_cnt,
5553 - unsigned hs_pulse_time, unsigned vs_pulse_time,
5554 - int hs_pol_inv, int vs_pol_inv, int div);
5555 - int (*enable_tearsync) (int enable, unsigned line);
5557 - unsigned long max_transmit_size;
5560 -struct omapfb_notifier_block {
5561 - struct notifier_block nb;
5562 - void *data;
5563 - int plane_idx;
5566 -typedef int (*omapfb_notifier_callback_t)(struct notifier_block *,
5567 - unsigned long event,
5568 - void *fbi);
5570 -struct omapfb_mem_region {
5571 - u32 paddr;
5572 - void __iomem *vaddr;
5573 - unsigned long size;
5574 - u8 type; /* OMAPFB_PLANE_MEM_* */
5575 - unsigned alloc:1; /* allocated by the driver */
5576 - unsigned map:1; /* kernel mapped by the driver */
5579 -struct omapfb_mem_desc {
5580 - int region_cnt;
5581 - struct omapfb_mem_region region[OMAPFB_PLANE_NUM];
5584 -struct lcd_ctrl {
5585 - const char *name;
5586 - void *data;
5588 - int (*init) (struct omapfb_device *fbdev,
5589 - int ext_mode,
5590 - struct omapfb_mem_desc *req_md);
5591 - void (*cleanup) (void);
5592 - void (*bind_client) (struct omapfb_notifier_block *nb);
5593 - void (*get_caps) (int plane, struct omapfb_caps *caps);
5594 - int (*set_update_mode)(enum omapfb_update_mode mode);
5595 - enum omapfb_update_mode (*get_update_mode)(void);
5596 - int (*setup_plane) (int plane, int channel_out,
5597 - unsigned long offset,
5598 - int screen_width,
5599 - int pos_x, int pos_y, int width,
5600 - int height, int color_mode);
5601 - int (*set_rotate) (int angle);
5602 - int (*setup_mem) (int plane, size_t size,
5603 - int mem_type, unsigned long *paddr);
5604 - int (*mmap) (struct fb_info *info,
5605 - struct vm_area_struct *vma);
5606 - int (*set_scale) (int plane,
5607 - int orig_width, int orig_height,
5608 - int out_width, int out_height);
5609 - int (*enable_plane) (int plane, int enable);
5610 - int (*update_window) (struct fb_info *fbi,
5611 - struct omapfb_update_window *win,
5612 - void (*callback)(void *),
5613 - void *callback_data);
5614 - void (*sync) (void);
5615 - void (*suspend) (void);
5616 - void (*resume) (void);
5617 - int (*run_test) (int test_num);
5618 - int (*setcolreg) (u_int regno, u16 red, u16 green,
5619 - u16 blue, u16 transp,
5620 - int update_hw_mem);
5621 - int (*set_color_key) (struct omapfb_color_key *ck);
5622 - int (*get_color_key) (struct omapfb_color_key *ck);
5625 -enum omapfb_state {
5626 - OMAPFB_DISABLED = 0,
5627 - OMAPFB_SUSPENDED= 99,
5628 - OMAPFB_ACTIVE = 100
5631 -struct omapfb_plane_struct {
5632 - int idx;
5633 - struct omapfb_plane_info info;
5634 - enum omapfb_color_format color_mode;
5635 - struct omapfb_device *fbdev;
5638 -struct omapfb_device {
5639 - int state;
5640 - int ext_lcdc; /* Using external
5641 - LCD controller */
5642 - struct mutex rqueue_mutex;
5644 - int palette_size;
5645 - u32 pseudo_palette[17];
5647 - struct lcd_panel *panel; /* LCD panel */
5648 - const struct lcd_ctrl *ctrl; /* LCD controller */
5649 - const struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */
5650 - struct lcd_ctrl_extif *ext_if; /* LCD ctrl external
5651 - interface */
5652 - struct device *dev;
5653 - struct fb_var_screeninfo new_var; /* for mode changes */
5655 - struct omapfb_mem_desc mem_desc;
5656 - struct fb_info *fb_info[OMAPFB_PLANE_NUM];
5659 -struct omapfb_platform_data {
5660 - struct omap_lcd_config lcd;
5661 - struct omapfb_mem_desc mem_desc;
5662 - void *ctrl_platform_data;
5665 -#ifdef CONFIG_ARCH_OMAP1
5666 -extern struct lcd_ctrl omap1_lcd_ctrl;
5667 -#else
5668 -extern struct lcd_ctrl omap2_disp_ctrl;
5669 -#endif
5671 -extern void omapfb_reserve_sdram(void);
5672 -extern void omapfb_register_panel(struct lcd_panel *panel);
5673 -extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
5674 -extern void omapfb_notify_clients(struct omapfb_device *fbdev,
5675 - unsigned long event);
5676 -extern int omapfb_register_client(struct omapfb_notifier_block *nb,
5677 - omapfb_notifier_callback_t callback,
5678 - void *callback_data);
5679 -extern int omapfb_unregister_client(struct omapfb_notifier_block *nb);
5680 -extern int omapfb_update_window_async(struct fb_info *fbi,
5681 - struct omapfb_update_window *win,
5682 - void (*callback)(void *),
5683 - void *callback_data);
5685 -/* in arch/arm/plat-omap/fb.c */
5686 -extern void omapfb_set_ctrl_platform_data(void *pdata);
5688 -#endif /* __KERNEL__ */
5690 -#endif /* __OMAPFB_H */
5691 diff --git a/arch/arm/plat-omap/include/mach/vram.h b/arch/arm/plat-omap/include/mach/vram.h
5692 new file mode 100644
5693 index 0000000..f176562
5694 --- /dev/null
5695 +++ b/arch/arm/plat-omap/include/mach/vram.h
5696 @@ -0,0 +1,33 @@
5698 + * File: arch/arm/plat-omap/include/mach/vram.h
5700 + * Copyright (C) 2009 Nokia Corporation
5701 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
5703 + * This program is free software; you can redistribute it and/or modify it
5704 + * under the terms of the GNU General Public License as published by the
5705 + * Free Software Foundation; either version 2 of the License, or (at your
5706 + * option) any later version.
5708 + * This program is distributed in the hope that it will be useful, but
5709 + * WITHOUT ANY WARRANTY; without even the implied warranty of
5710 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5711 + * General Public License for more details.
5713 + * You should have received a copy of the GNU General Public License along
5714 + * with this program; if not, write to the Free Software Foundation, Inc.,
5715 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5716 + */
5718 +#ifndef __OMAPVRAM_H
5719 +#define __OMAPVRAM_H
5721 +#include <asm/types.h>
5723 +extern int omap_vram_free(unsigned long paddr, size_t size);
5724 +extern int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr);
5725 +extern int omap_vram_reserve(unsigned long paddr, size_t size);
5726 +extern void omap2_set_sdram_vram(u32 size, u32 start);
5727 +extern void omap2_set_sram_vram(u32 size, u32 start);
5729 +#endif
5730 diff --git a/arch/arm/plat-omap/include/mach/vrfb.h b/arch/arm/plat-omap/include/mach/vrfb.h
5731 new file mode 100644
5732 index 0000000..2047862
5733 --- /dev/null
5734 +++ b/arch/arm/plat-omap/include/mach/vrfb.h
5735 @@ -0,0 +1,47 @@
5737 + * File: arch/arm/plat-omap/include/mach/vrfb.h
5739 + * VRFB
5741 + * Copyright (C) 2009 Nokia Corporation
5742 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
5744 + * This program is free software; you can redistribute it and/or modify it
5745 + * under the terms of the GNU General Public License as published by the
5746 + * Free Software Foundation; either version 2 of the License, or (at your
5747 + * option) any later version.
5749 + * This program is distributed in the hope that it will be useful, but
5750 + * WITHOUT ANY WARRANTY; without even the implied warranty of
5751 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5752 + * General Public License for more details.
5754 + * You should have received a copy of the GNU General Public License along
5755 + * with this program; if not, write to the Free Software Foundation, Inc.,
5756 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
5757 + */
5759 +#ifndef __VRFB_H
5760 +#define __VRFB_H
5762 +#define OMAP_VRFB_LINE_LEN 2048
5764 +struct vrfb
5766 + u8 context;
5767 + void __iomem *vaddr[4];
5768 + unsigned long paddr[4];
5769 + u16 xoffset;
5770 + u16 yoffset;
5771 + u8 bytespp;
5774 +extern int omap_vrfb_request_ctx(struct vrfb *vrfb);
5775 +extern void omap_vrfb_release_ctx(struct vrfb *vrfb);
5776 +extern void omap_vrfb_adjust_size(u16 *width, u16 *height,
5777 + u8 bytespp);
5778 +extern void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
5779 + u16 width, u16 height,
5780 + u8 bytespp);
5782 +#endif /* __VRFB_H */
5783 diff --git a/arch/arm/plat-omap/vram.c b/arch/arm/plat-omap/vram.c
5784 new file mode 100644
5785 index 0000000..f24a110
5786 --- /dev/null
5787 +++ b/arch/arm/plat-omap/vram.c
5788 @@ -0,0 +1,615 @@
5790 + * linux/arch/arm/plat-omap/vram.c
5792 + * Copyright (C) 2008 Nokia Corporation
5793 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
5795 + * Some code and ideas taken from drivers/video/omap/ driver
5796 + * by Imre Deak.
5798 + * This program is free software; you can redistribute it and/or modify it
5799 + * under the terms of the GNU General Public License version 2 as published by
5800 + * the Free Software Foundation.
5802 + * This program is distributed in the hope that it will be useful, but WITHOUT
5803 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
5804 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
5805 + * more details.
5807 + * You should have received a copy of the GNU General Public License along with
5808 + * this program. If not, see <http://www.gnu.org/licenses/>.
5809 + */
5811 +/*#define DEBUG*/
5813 +#include <linux/vmalloc.h>
5814 +#include <linux/kernel.h>
5815 +#include <linux/mm.h>
5816 +#include <linux/list.h>
5817 +#include <linux/dma-mapping.h>
5818 +#include <linux/proc_fs.h>
5819 +#include <linux/seq_file.h>
5820 +#include <linux/bootmem.h>
5821 +#include <linux/omapfb.h>
5823 +#include <asm/setup.h>
5825 +#include <mach/sram.h>
5826 +#include <mach/vram.h>
5828 +#ifdef DEBUG
5829 +#define DBG(format, ...) printk(KERN_DEBUG "VRAM: " format, ## __VA_ARGS__)
5830 +#else
5831 +#define DBG(format, ...)
5832 +#endif
5834 +#define OMAP2_SRAM_START 0x40200000
5835 +/* Maximum size, in reality this is smaller if SRAM is partially locked. */
5836 +#define OMAP2_SRAM_SIZE 0xa0000 /* 640k */
5838 +#define REG_MAP_SIZE(_page_cnt) \
5839 + ((_page_cnt + (sizeof(unsigned long) * 8) - 1) / 8)
5840 +#define REG_MAP_PTR(_rg, _page_nr) \
5841 + (((_rg)->map) + (_page_nr) / (sizeof(unsigned long) * 8))
5842 +#define REG_MAP_MASK(_page_nr) \
5843 + (1 << ((_page_nr) & (sizeof(unsigned long) * 8 - 1)))
5845 +#if defined(CONFIG_FB_OMAP2) || defined(CONFIG_FB_OMAP2_MODULE)
5847 +/* postponed regions are used to temporarily store region information at boot
5848 + * time when we cannot yet allocate the region list */
5849 +#define MAX_POSTPONED_REGIONS 10
5851 +static int postponed_cnt __initdata;
5852 +static struct {
5853 + unsigned long paddr;
5854 + size_t size;
5855 +} postponed_regions[MAX_POSTPONED_REGIONS] __initdata;
5857 +struct vram_alloc {
5858 + struct list_head list;
5859 + unsigned long paddr;
5860 + unsigned pages;
5863 +struct vram_region {
5864 + struct list_head list;
5865 + struct list_head alloc_list;
5866 + unsigned long paddr;
5867 + unsigned pages;
5870 +static DEFINE_MUTEX(region_mutex);
5871 +static LIST_HEAD(region_list);
5873 +static inline int region_mem_type(unsigned long paddr)
5875 + if (paddr >= OMAP2_SRAM_START &&
5876 + paddr < OMAP2_SRAM_START + OMAP2_SRAM_SIZE)
5877 + return OMAPFB_MEMTYPE_SRAM;
5878 + else
5879 + return OMAPFB_MEMTYPE_SDRAM;
5882 +static struct vram_region *omap_vram_create_region(unsigned long paddr,
5883 + unsigned pages)
5885 + struct vram_region *rm;
5887 + rm = kzalloc(sizeof(*rm), GFP_KERNEL);
5889 + if (rm) {
5890 + INIT_LIST_HEAD(&rm->alloc_list);
5891 + rm->paddr = paddr;
5892 + rm->pages = pages;
5895 + return rm;
5898 +#if 0
5899 +static void omap_vram_free_region(struct vram_region *vr)
5901 + list_del(&vr->list);
5902 + kfree(vr);
5904 +#endif
5906 +static struct vram_alloc *omap_vram_create_allocation(struct vram_region *vr,
5907 + unsigned long paddr, unsigned pages)
5909 + struct vram_alloc *va;
5910 + struct vram_alloc *new;
5912 + new = kzalloc(sizeof(*va), GFP_KERNEL);
5914 + if (!new)
5915 + return NULL;
5917 + new->paddr = paddr;
5918 + new->pages = pages;
5920 + list_for_each_entry(va, &vr->alloc_list, list) {
5921 + if (va->paddr > new->paddr)
5922 + break;
5925 + list_add_tail(&new->list, &va->list);
5927 + return new;
5930 +static void omap_vram_free_allocation(struct vram_alloc *va)
5932 + list_del(&va->list);
5933 + kfree(va);
5936 +static __init int omap_vram_add_region_postponed(unsigned long paddr,
5937 + size_t size)
5939 + if (postponed_cnt == MAX_POSTPONED_REGIONS)
5940 + return -ENOMEM;
5942 + postponed_regions[postponed_cnt].paddr = paddr;
5943 + postponed_regions[postponed_cnt].size = size;
5945 + ++postponed_cnt;
5947 + return 0;
5950 +/* add/remove_region can be exported if there's need to add/remove regions
5951 + * runtime */
5952 +static int omap_vram_add_region(unsigned long paddr, size_t size)
5954 + struct vram_region *rm;
5955 + unsigned pages;
5957 + DBG("adding region paddr %08lx size %d\n",
5958 + paddr, size);
5960 + size &= PAGE_MASK;
5961 + pages = size >> PAGE_SHIFT;
5963 + rm = omap_vram_create_region(paddr, pages);
5964 + if (rm == NULL)
5965 + return -ENOMEM;
5967 + list_add(&rm->list, &region_list);
5969 + return 0;
5972 +int omap_vram_free(unsigned long paddr, size_t size)
5974 + struct vram_region *rm;
5975 + struct vram_alloc *alloc;
5976 + unsigned start, end;
5978 + DBG("free mem paddr %08lx size %d\n", paddr, size);
5980 + size = PAGE_ALIGN(size);
5982 + mutex_lock(&region_mutex);
5984 + list_for_each_entry(rm, &region_list, list) {
5985 + list_for_each_entry(alloc, &rm->alloc_list, list) {
5986 + start = alloc->paddr;
5987 + end = alloc->paddr + (alloc->pages >> PAGE_SHIFT);
5989 + if (start >= paddr && end < paddr + size)
5990 + goto found;
5994 + mutex_unlock(&region_mutex);
5995 + return -EINVAL;
5997 +found:
5998 + omap_vram_free_allocation(alloc);
6000 + mutex_unlock(&region_mutex);
6001 + return 0;
6003 +EXPORT_SYMBOL(omap_vram_free);
6005 +static int _omap_vram_reserve(unsigned long paddr, unsigned pages)
6007 + struct vram_region *rm;
6008 + struct vram_alloc *alloc;
6009 + size_t size;
6011 + size = pages << PAGE_SHIFT;
6013 + list_for_each_entry(rm, &region_list, list) {
6014 + unsigned long start, end;
6016 + DBG("checking region %lx %d\n", rm->paddr, rm->pages);
6018 + if (region_mem_type(rm->paddr) != region_mem_type(paddr))
6019 + continue;
6021 + start = rm->paddr;
6022 + end = start + (rm->pages << PAGE_SHIFT) - 1;
6023 + if (start > paddr || end < paddr + size - 1)
6024 + continue;
6026 + DBG("block ok, checking allocs\n");
6028 + list_for_each_entry(alloc, &rm->alloc_list, list) {
6029 + end = alloc->paddr - 1;
6031 + if (start <= paddr && end >= paddr + size - 1)
6032 + goto found;
6034 + start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
6037 + end = rm->paddr + (rm->pages << PAGE_SHIFT) - 1;
6039 + if (!(start <= paddr && end >= paddr + size - 1))
6040 + continue;
6041 +found:
6042 + DBG("FOUND area start %lx, end %lx\n", start, end);
6044 + if (omap_vram_create_allocation(rm, paddr, pages) == NULL)
6045 + return -ENOMEM;
6047 + return 0;
6050 + return -ENOMEM;
6053 +int omap_vram_reserve(unsigned long paddr, size_t size)
6055 + unsigned pages;
6056 + int r;
6058 + DBG("reserve mem paddr %08lx size %d\n", paddr, size);
6060 + size = PAGE_ALIGN(size);
6061 + pages = size >> PAGE_SHIFT;
6063 + mutex_lock(&region_mutex);
6065 + r = _omap_vram_reserve(paddr, pages);
6067 + mutex_unlock(&region_mutex);
6069 + return r;
6071 +EXPORT_SYMBOL(omap_vram_reserve);
6073 +static int _omap_vram_alloc(int mtype, unsigned pages, unsigned long *paddr)
6075 + struct vram_region *rm;
6076 + struct vram_alloc *alloc;
6078 + list_for_each_entry(rm, &region_list, list) {
6079 + unsigned long start, end;
6081 + DBG("checking region %lx %d\n", rm->paddr, rm->pages);
6083 + if (region_mem_type(rm->paddr) != mtype)
6084 + continue;
6086 + start = rm->paddr;
6088 + list_for_each_entry(alloc, &rm->alloc_list, list) {
6089 + end = alloc->paddr;
6091 + if (end - start >= pages << PAGE_SHIFT)
6092 + goto found;
6094 + start = alloc->paddr + (alloc->pages << PAGE_SHIFT);
6097 + end = rm->paddr + (rm->pages << PAGE_SHIFT);
6098 +found:
6099 + if (end - start < pages << PAGE_SHIFT)
6100 + continue;
6102 + DBG("FOUND %lx, end %lx\n", start, end);
6104 + alloc = omap_vram_create_allocation(rm, start, pages);
6105 + if (alloc == NULL)
6106 + return -ENOMEM;
6108 + *paddr = start;
6110 + return 0;
6113 + return -ENOMEM;
6116 +int omap_vram_alloc(int mtype, size_t size, unsigned long *paddr)
6118 + unsigned pages;
6119 + int r;
6121 + BUG_ON(mtype > OMAPFB_MEMTYPE_MAX || !size);
6123 + DBG("alloc mem type %d size %d\n", mtype, size);
6125 + size = PAGE_ALIGN(size);
6126 + pages = size >> PAGE_SHIFT;
6128 + mutex_lock(&region_mutex);
6130 + r = _omap_vram_alloc(mtype, pages, paddr);
6132 + mutex_unlock(&region_mutex);
6134 + return r;
6136 +EXPORT_SYMBOL(omap_vram_alloc);
6138 +#ifdef CONFIG_PROC_FS
6139 +static void *r_next(struct seq_file *m, void *v, loff_t *pos)
6141 + struct list_head *l = v;
6143 + (*pos)++;
6145 + if (list_is_last(l, &region_list))
6146 + return NULL;
6148 + return l->next;
6151 +static void *r_start(struct seq_file *m, loff_t *pos)
6153 + loff_t p = *pos;
6154 + struct list_head *l = &region_list;
6156 + mutex_lock(&region_mutex);
6158 + do {
6159 + l = l->next;
6160 + if (l == &region_list)
6161 + return NULL;
6162 + } while (p--);
6164 + return l;
6167 +static void r_stop(struct seq_file *m, void *v)
6169 + mutex_unlock(&region_mutex);
6172 +static int r_show(struct seq_file *m, void *v)
6174 + struct vram_region *vr;
6175 + struct vram_alloc *va;
6176 + unsigned size;
6178 + vr = list_entry(v, struct vram_region, list);
6180 + size = vr->pages << PAGE_SHIFT;
6182 + seq_printf(m, "%08lx-%08lx (%d bytes)\n",
6183 + vr->paddr, vr->paddr + size - 1,
6184 + size);
6186 + list_for_each_entry(va, &vr->alloc_list, list) {
6187 + size = va->pages << PAGE_SHIFT;
6188 + seq_printf(m, " %08lx-%08lx (%d bytes)\n",
6189 + va->paddr, va->paddr + size - 1,
6190 + size);
6195 + return 0;
6198 +static const struct seq_operations resource_op = {
6199 + .start = r_start,
6200 + .next = r_next,
6201 + .stop = r_stop,
6202 + .show = r_show,
6205 +static int vram_open(struct inode *inode, struct file *file)
6207 + return seq_open(file, &resource_op);
6210 +static const struct file_operations proc_vram_operations = {
6211 + .open = vram_open,
6212 + .read = seq_read,
6213 + .llseek = seq_lseek,
6214 + .release = seq_release,
6217 +static int __init omap_vram_create_proc(void)
6219 + proc_create("omap-vram", 0, NULL, &proc_vram_operations);
6221 + return 0;
6223 +#endif
6225 +static __init int omap_vram_init(void)
6227 + int i, r;
6229 + for (i = 0; i < postponed_cnt; i++)
6230 + omap_vram_add_region(postponed_regions[i].paddr,
6231 + postponed_regions[i].size);
6233 +#ifdef CONFIG_PROC_FS
6234 + r = omap_vram_create_proc();
6235 + if (r)
6236 + return -ENOMEM;
6237 +#endif
6239 + return 0;
6242 +arch_initcall(omap_vram_init);
6244 +/* boottime vram alloc stuff */
6246 +/* set from board file */
6247 +static u32 omapfb_sram_vram_start __initdata;
6248 +static u32 omapfb_sram_vram_size __initdata;
6250 +/* set from board file */
6251 +static u32 omapfb_sdram_vram_start __initdata;
6252 +static u32 omapfb_sdram_vram_size __initdata;
6254 +/* set from kernel cmdline */
6255 +static u32 omapfb_def_sdram_vram_size __initdata;
6256 +static u32 omapfb_def_sdram_vram_start __initdata;
6258 +static void __init omapfb_early_vram(char **p)
6260 + omapfb_def_sdram_vram_size = memparse(*p, p);
6261 + if (**p == ',')
6262 + omapfb_def_sdram_vram_start = simple_strtoul((*p) + 1, p, 16);
6264 + printk("omapfb_early_vram, %d, 0x%x\n",
6265 + omapfb_def_sdram_vram_size,
6266 + omapfb_def_sdram_vram_start);
6268 +__early_param("vram=", omapfb_early_vram);
6271 + * Called from map_io. We need to call to this early enough so that we
6272 + * can reserve the fixed SDRAM regions before VM could get hold of them.
6273 + */
6274 +void __init omapfb_reserve_sdram(void)
6276 + struct bootmem_data *bdata;
6277 + unsigned long sdram_start, sdram_size;
6278 + u32 paddr;
6279 + u32 size = 0;
6281 + /* cmdline arg overrides the board file definition */
6282 + if (omapfb_def_sdram_vram_size) {
6283 + size = omapfb_def_sdram_vram_size;
6284 + paddr = omapfb_def_sdram_vram_start;
6287 + if (!size) {
6288 + size = omapfb_sdram_vram_size;
6289 + paddr = omapfb_sdram_vram_start;
6292 +#ifdef CONFIG_OMAP2_DSS_VRAM_SIZE
6293 + if (!size) {
6294 + size = CONFIG_OMAP2_DSS_VRAM_SIZE * 1024 * 1024;
6295 + paddr = 0;
6297 +#endif
6299 + if (!size)
6300 + return;
6302 + size = PAGE_ALIGN(size);
6304 + bdata = NODE_DATA(0)->bdata;
6305 + sdram_start = bdata->node_min_pfn << PAGE_SHIFT;
6306 + sdram_size = (bdata->node_low_pfn << PAGE_SHIFT) - sdram_start;
6308 + if (paddr) {
6309 + if ((paddr & ~PAGE_MASK) || paddr < sdram_start ||
6310 + paddr + size > sdram_start + sdram_size) {
6311 + printk(KERN_ERR "Illegal SDRAM region for VRAM\n");
6312 + return;
6315 + reserve_bootmem(paddr, size, BOOTMEM_DEFAULT);
6316 + } else {
6317 + if (size > sdram_size) {
6318 + printk(KERN_ERR "Illegal SDRAM size for VRAM\n");
6319 + return;
6322 + paddr = virt_to_phys(alloc_bootmem_pages(size));
6323 + BUG_ON(paddr & ~PAGE_MASK);
6326 + omap_vram_add_region_postponed(paddr, size);
6328 + pr_info("Reserving %u bytes SDRAM for VRAM\n", size);
6332 + * Called at sram init time, before anything is pushed to the SRAM stack.
6333 + * Because of the stack scheme, we will allocate everything from the
6334 + * start of the lowest address region to the end of SRAM. This will also
6335 + * include padding for page alignment and possible holes between regions.
6337 + * As opposed to the SDRAM case, we'll also do any dynamic allocations at
6338 + * this point, since the driver built as a module would have problem with
6339 + * freeing / reallocating the regions.
6340 + */
6341 +unsigned long __init omapfb_reserve_sram(unsigned long sram_pstart,
6342 + unsigned long sram_vstart,
6343 + unsigned long sram_size,
6344 + unsigned long pstart_avail,
6345 + unsigned long size_avail)
6347 + unsigned long pend_avail;
6348 + unsigned long reserved;
6349 + u32 paddr;
6350 + u32 size;
6352 + paddr = omapfb_sram_vram_start;
6353 + size = omapfb_sram_vram_size;
6355 + if (!size)
6356 + return 0;
6358 + reserved = 0;
6359 + pend_avail = pstart_avail + size_avail;
6361 + if (!paddr) {
6362 + /* Dynamic allocation */
6363 + if ((size_avail & PAGE_MASK) < size) {
6364 + printk(KERN_ERR "Not enough SRAM for VRAM\n");
6365 + return 0;
6367 + size_avail = (size_avail - size) & PAGE_MASK;
6368 + paddr = pstart_avail + size_avail;
6371 + if (paddr < sram_pstart ||
6372 + paddr + size > sram_pstart + sram_size) {
6373 + printk(KERN_ERR "Illegal SRAM region for VRAM\n");
6374 + return 0;
6377 + /* Reserve everything above the start of the region. */
6378 + if (pend_avail - paddr > reserved)
6379 + reserved = pend_avail - paddr;
6380 + size_avail = pend_avail - reserved - pstart_avail;
6382 + omap_vram_add_region_postponed(paddr, size);
6384 + if (reserved)
6385 + pr_info("Reserving %lu bytes SRAM for VRAM\n", reserved);
6387 + return reserved;
6390 +void __init omap2_set_sdram_vram(u32 size, u32 start)
6392 + omapfb_sdram_vram_start = start;
6393 + omapfb_sdram_vram_size = size;
6396 +void __init omap2_set_sram_vram(u32 size, u32 start)
6398 + omapfb_sram_vram_start = start;
6399 + omapfb_sram_vram_size = size;
6402 +#endif
6404 diff --git a/arch/arm/plat-omap/vrfb.c b/arch/arm/plat-omap/vrfb.c
6405 new file mode 100644
6406 index 0000000..7e0f8fc
6407 --- /dev/null
6408 +++ b/arch/arm/plat-omap/vrfb.c
6409 @@ -0,0 +1,159 @@
6410 +#include <linux/kernel.h>
6411 +#include <linux/module.h>
6412 +#include <linux/ioport.h>
6413 +#include <asm/io.h>
6415 +#include <mach/io.h>
6416 +#include <mach/vrfb.h>
6418 +/*#define DEBUG*/
6420 +#ifdef DEBUG
6421 +#define DBG(format, ...) printk(KERN_DEBUG "VRFB: " format, ## __VA_ARGS__)
6422 +#else
6423 +#define DBG(format, ...)
6424 +#endif
6426 +#define SMS_ROT_VIRT_BASE(context, rot) \
6427 + (((context >= 4) ? 0xD0000000 : 0x70000000) \
6428 + | 0x4000000 * (context) \
6429 + | 0x1000000 * (rot))
6431 +#define OMAP_VRFB_SIZE (2048 * 2048 * 4)
6433 +#define VRFB_PAGE_WIDTH_EXP 5 /* Assuming SDRAM pagesize= 1024 */
6434 +#define VRFB_PAGE_HEIGHT_EXP 5 /* 1024 = 2^5 * 2^5 */
6435 +#define VRFB_PAGE_WIDTH (1 << VRFB_PAGE_WIDTH_EXP)
6436 +#define VRFB_PAGE_HEIGHT (1 << VRFB_PAGE_HEIGHT_EXP)
6437 +#define SMS_IMAGEHEIGHT_OFFSET 16
6438 +#define SMS_IMAGEWIDTH_OFFSET 0
6439 +#define SMS_PH_OFFSET 8
6440 +#define SMS_PW_OFFSET 4
6441 +#define SMS_PS_OFFSET 0
6443 +#define OMAP_SMS_BASE 0x6C000000
6444 +#define SMS_ROT_CONTROL(context) (OMAP_SMS_BASE + 0x180 + 0x10 * context)
6445 +#define SMS_ROT_SIZE(context) (OMAP_SMS_BASE + 0x184 + 0x10 * context)
6446 +#define SMS_ROT_PHYSICAL_BA(context) (OMAP_SMS_BASE + 0x188 + 0x10 * context)
6448 +#define VRFB_NUM_CTXS 12
6449 +/* bitmap of reserved contexts */
6450 +static unsigned ctx_map;
6452 +void omap_vrfb_adjust_size(u16 *width, u16 *height,
6453 + u8 bytespp)
6455 + *width = ALIGN(*width * bytespp, VRFB_PAGE_WIDTH) / bytespp;
6456 + *height = ALIGN(*height, VRFB_PAGE_HEIGHT);
6458 +EXPORT_SYMBOL(omap_vrfb_adjust_size);
6460 +void omap_vrfb_setup(struct vrfb *vrfb, unsigned long paddr,
6461 + u16 width, u16 height,
6462 + u8 bytespp)
6464 + unsigned pixel_size_exp;
6465 + u16 vrfb_width;
6466 + u16 vrfb_height;
6467 + u8 ctx = vrfb->context;
6469 + DBG("omapfb_set_vrfb(%d, %lx, %dx%d, %d)\n", ctx, paddr,
6470 + width, height, bytespp);
6472 + if (bytespp == 4)
6473 + pixel_size_exp = 2;
6474 + else if (bytespp == 2)
6475 + pixel_size_exp = 1;
6476 + else
6477 + BUG();
6479 + vrfb_width = ALIGN(width * bytespp, VRFB_PAGE_WIDTH) / bytespp;
6480 + vrfb_height = ALIGN(height, VRFB_PAGE_HEIGHT);
6482 + DBG("vrfb w %u, h %u\n", vrfb_width, vrfb_height);
6484 + omap_writel(paddr, SMS_ROT_PHYSICAL_BA(ctx));
6485 + omap_writel((vrfb_width << SMS_IMAGEWIDTH_OFFSET) |
6486 + (vrfb_height << SMS_IMAGEHEIGHT_OFFSET),
6487 + SMS_ROT_SIZE(ctx));
6489 + omap_writel(pixel_size_exp << SMS_PS_OFFSET |
6490 + VRFB_PAGE_WIDTH_EXP << SMS_PW_OFFSET |
6491 + VRFB_PAGE_HEIGHT_EXP << SMS_PH_OFFSET,
6492 + SMS_ROT_CONTROL(ctx));
6494 + DBG("vrfb offset pixels %d, %d\n",
6495 + vrfb_width - width, vrfb_height - height);
6497 + vrfb->xoffset = vrfb_width - width;
6498 + vrfb->yoffset = vrfb_height - height;
6499 + vrfb->bytespp = bytespp;
6501 +EXPORT_SYMBOL(omap_vrfb_setup);
6503 +void omap_vrfb_release_ctx(struct vrfb *vrfb)
6505 + int rot;
6507 + if (vrfb->context == 0xff)
6508 + return;
6510 + DBG("release ctx %d\n", vrfb->context);
6512 + ctx_map &= ~(1 << vrfb->context);
6514 + for (rot = 0; rot < 4; ++rot) {
6515 + if(vrfb->paddr[rot]) {
6516 + release_mem_region(vrfb->paddr[rot], OMAP_VRFB_SIZE);
6517 + vrfb->paddr[rot] = 0;
6521 + vrfb->context = 0xff;
6523 +EXPORT_SYMBOL(omap_vrfb_release_ctx);
6525 +int omap_vrfb_request_ctx(struct vrfb *vrfb)
6527 + int rot;
6528 + u32 paddr;
6529 + u8 ctx;
6531 + DBG("request ctx\n");
6533 + for (ctx = 0; ctx < VRFB_NUM_CTXS; ++ctx)
6534 + if ((ctx_map & (1 << ctx)) == 0)
6535 + break;
6537 + if (ctx == VRFB_NUM_CTXS) {
6538 + printk(KERN_ERR "vrfb: no free contexts\n");
6539 + return -EBUSY;
6542 + DBG("found free ctx %d\n", ctx);
6544 + ctx_map |= 1 << ctx;
6546 + memset(vrfb, 0, sizeof(*vrfb));
6548 + vrfb->context = ctx;
6550 + for (rot = 0; rot < 4; ++rot) {
6551 + paddr = SMS_ROT_VIRT_BASE(ctx, rot);
6552 + if (!request_mem_region(paddr, OMAP_VRFB_SIZE, "vrfb")) {
6553 + printk(KERN_ERR "vrfb: failed to reserve VRFB "
6554 + "area for ctx %d, rotation %d\n",
6555 + ctx, rot * 90);
6556 + omap_vrfb_release_ctx(vrfb);
6557 + return -ENOMEM;
6560 + vrfb->paddr[rot] = paddr;
6562 + DBG("VRFB %d/%d: %lx\n", ctx, rot*90, vrfb->paddr[rot]);
6565 + return 0;
6567 +EXPORT_SYMBOL(omap_vrfb_request_ctx);
6569 diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
6570 index fb19803..8b3752b 100644
6571 --- a/drivers/video/Kconfig
6572 +++ b/drivers/video/Kconfig
6573 @@ -2132,6 +2132,7 @@ config FB_MX3
6574 an LCD display with your i.MX31 system, say Y here.
6576 source "drivers/video/omap/Kconfig"
6577 +source "drivers/video/omap2/Kconfig"
6579 source "drivers/video/backlight/Kconfig"
6580 source "drivers/video/display/Kconfig"
6581 diff --git a/drivers/video/Makefile b/drivers/video/Makefile
6582 index 2a998ca..1db8dd4 100644
6583 --- a/drivers/video/Makefile
6584 +++ b/drivers/video/Makefile
6585 @@ -120,6 +120,7 @@ obj-$(CONFIG_FB_SM501) += sm501fb.o
6586 obj-$(CONFIG_FB_XILINX) += xilinxfb.o
6587 obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
6588 obj-$(CONFIG_FB_OMAP) += omap/
6589 +obj-$(CONFIG_OMAP2_DSS) += omap2/
6590 obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
6591 obj-$(CONFIG_FB_CARMINE) += carminefb.o
6592 obj-$(CONFIG_FB_MB862XX) += mb862xx/
6593 diff --git a/drivers/video/omap/Kconfig b/drivers/video/omap/Kconfig
6594 index c355b59..a1c10de 100644
6595 --- a/drivers/video/omap/Kconfig
6596 +++ b/drivers/video/omap/Kconfig
6597 @@ -1,6 +1,7 @@
6598 config FB_OMAP
6599 tristate "OMAP frame buffer support (EXPERIMENTAL)"
6600 - depends on FB && ARCH_OMAP
6601 + depends on FB && ARCH_OMAP && (OMAP2_DSS = "n")
6603 select FB_CFB_FILLRECT
6604 select FB_CFB_COPYAREA
6605 select FB_CFB_IMAGEBLIT
6606 @@ -72,7 +73,7 @@ config FB_OMAP_LCD_MIPID
6608 config FB_OMAP_BOOTLOADER_INIT
6609 bool "Check bootloader initialization"
6610 - depends on FB_OMAP
6611 + depends on FB_OMAP || FB_OMAP2
6612 help
6613 Say Y here if you want to enable checking if the bootloader has
6614 already initialized the display controller. In this case the
6615 diff --git a/drivers/video/omap/blizzard.c b/drivers/video/omap/blizzard.c
6616 index f60a233..8121c09 100644
6617 --- a/drivers/video/omap/blizzard.c
6618 +++ b/drivers/video/omap/blizzard.c
6619 @@ -25,9 +25,9 @@
6620 #include <linux/fb.h>
6621 #include <linux/delay.h>
6622 #include <linux/clk.h>
6623 +#include <linux/omapfb.h>
6625 #include <mach/dma.h>
6626 -#include <mach/omapfb.h>
6627 #include <mach/blizzard.h>
6629 #include "dispc.h"
6630 diff --git a/drivers/video/omap/dispc.c b/drivers/video/omap/dispc.c
6631 index c140c21..1915af5 100644
6632 --- a/drivers/video/omap/dispc.c
6633 +++ b/drivers/video/omap/dispc.c
6634 @@ -24,9 +24,9 @@
6635 #include <linux/vmalloc.h>
6636 #include <linux/clk.h>
6637 #include <linux/io.h>
6638 +#include <linux/omapfb.h>
6640 #include <mach/sram.h>
6641 -#include <mach/omapfb.h>
6642 #include <mach/board.h>
6644 #include "dispc.h"
6645 diff --git a/drivers/video/omap/hwa742.c b/drivers/video/omap/hwa742.c
6646 index f24df0b..9b4c506 100644
6647 --- a/drivers/video/omap/hwa742.c
6648 +++ b/drivers/video/omap/hwa742.c
6649 @@ -25,9 +25,9 @@
6650 #include <linux/fb.h>
6651 #include <linux/delay.h>
6652 #include <linux/clk.h>
6653 +#include <linux/omapfb.h>
6655 #include <mach/dma.h>
6656 -#include <mach/omapfb.h>
6657 #include <mach/hwa742.h>
6659 #define HWA742_REV_CODE_REG 0x0
6660 diff --git a/drivers/video/omap/lcd_2430sdp.c b/drivers/video/omap/lcd_2430sdp.c
6661 index a22b452..1252cc3 100644
6662 --- a/drivers/video/omap/lcd_2430sdp.c
6663 +++ b/drivers/video/omap/lcd_2430sdp.c
6664 @@ -26,9 +26,9 @@
6665 #include <linux/delay.h>
6666 #include <linux/gpio.h>
6667 #include <linux/i2c/twl4030.h>
6668 +#include <linux/omapfb.h>
6670 #include <mach/mux.h>
6671 -#include <mach/omapfb.h>
6672 #include <asm/mach-types.h>
6674 #define SDP2430_LCD_PANEL_BACKLIGHT_GPIO 91
6675 diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/omap/lcd_ams_delta.c
6676 index 3fd5342..4d54725 100644
6677 --- a/drivers/video/omap/lcd_ams_delta.c
6678 +++ b/drivers/video/omap/lcd_ams_delta.c
6679 @@ -24,13 +24,13 @@
6681 #include <linux/module.h>
6682 #include <linux/platform_device.h>
6683 +#include <linux/omapfb.h>
6685 #include <asm/delay.h>
6686 #include <asm/io.h>
6688 #include <mach/board-ams-delta.h>
6689 #include <mach/hardware.h>
6690 -#include <mach/omapfb.h>
6692 #define AMS_DELTA_DEFAULT_CONTRAST 112
6694 diff --git a/drivers/video/omap/lcd_apollon.c b/drivers/video/omap/lcd_apollon.c
6695 index beae5d9..e3b2224 100644
6696 --- a/drivers/video/omap/lcd_apollon.c
6697 +++ b/drivers/video/omap/lcd_apollon.c
6698 @@ -23,10 +23,10 @@
6700 #include <linux/module.h>
6701 #include <linux/platform_device.h>
6702 +#include <linux/omapfb.h>
6704 #include <mach/gpio.h>
6705 #include <mach/mux.h>
6706 -#include <mach/omapfb.h>
6708 /* #define USE_35INCH_LCD 1 */
6710 diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/omap/lcd_h3.c
6711 index 2486237..f7264ea 100644
6712 --- a/drivers/video/omap/lcd_h3.c
6713 +++ b/drivers/video/omap/lcd_h3.c
6714 @@ -22,9 +22,9 @@
6715 #include <linux/module.h>
6716 #include <linux/platform_device.h>
6717 #include <linux/i2c/tps65010.h>
6718 +#include <linux/omapfb.h>
6720 #include <mach/gpio.h>
6721 -#include <mach/omapfb.h>
6723 #define MODULE_NAME "omapfb-lcd_h3"
6725 diff --git a/drivers/video/omap/lcd_h4.c b/drivers/video/omap/lcd_h4.c
6726 index 6ff5643..d72df0c 100644
6727 --- a/drivers/video/omap/lcd_h4.c
6728 +++ b/drivers/video/omap/lcd_h4.c
6729 @@ -21,8 +21,7 @@
6731 #include <linux/module.h>
6732 #include <linux/platform_device.h>
6734 -#include <mach/omapfb.h>
6735 +#include <linux/omapfb.h>
6737 static int h4_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
6739 diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/omap/lcd_inn1510.c
6740 index 6953ed4..f6e05d7 100644
6741 --- a/drivers/video/omap/lcd_inn1510.c
6742 +++ b/drivers/video/omap/lcd_inn1510.c
6743 @@ -22,9 +22,9 @@
6744 #include <linux/module.h>
6745 #include <linux/platform_device.h>
6746 #include <linux/io.h>
6747 +#include <linux/omapfb.h>
6749 #include <mach/fpga.h>
6750 -#include <mach/omapfb.h>
6752 static int innovator1510_panel_init(struct lcd_panel *panel,
6753 struct omapfb_device *fbdev)
6754 diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/omap/lcd_inn1610.c
6755 index 4c4f7ee..c599e41 100644
6756 --- a/drivers/video/omap/lcd_inn1610.c
6757 +++ b/drivers/video/omap/lcd_inn1610.c
6758 @@ -21,9 +21,9 @@
6760 #include <linux/module.h>
6761 #include <linux/platform_device.h>
6762 +#include <linux/omapfb.h>
6764 #include <mach/gpio.h>
6765 -#include <mach/omapfb.h>
6767 #define MODULE_NAME "omapfb-lcd_h3"
6769 diff --git a/drivers/video/omap/lcd_ldp.c b/drivers/video/omap/lcd_ldp.c
6770 index 8925230..1c25186 100644
6771 --- a/drivers/video/omap/lcd_ldp.c
6772 +++ b/drivers/video/omap/lcd_ldp.c
6773 @@ -25,10 +25,10 @@
6774 #include <linux/platform_device.h>
6775 #include <linux/delay.h>
6776 #include <linux/i2c/twl4030.h>
6777 +#include <linux/omapfb.h>
6779 #include <mach/gpio.h>
6780 #include <mach/mux.h>
6781 -#include <mach/omapfb.h>
6782 #include <asm/mach-types.h>
6784 #define LCD_PANEL_BACKLIGHT_GPIO (15 + OMAP_MAX_GPIO_LINES)
6785 diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/omap/lcd_mipid.c
6786 index 1895997..4b28005 100644
6787 --- a/drivers/video/omap/lcd_mipid.c
6788 +++ b/drivers/video/omap/lcd_mipid.c
6789 @@ -22,8 +22,8 @@
6790 #include <linux/delay.h>
6791 #include <linux/workqueue.h>
6792 #include <linux/spi/spi.h>
6793 +#include <linux/omapfb.h>
6795 -#include <mach/omapfb.h>
6796 #include <mach/lcd_mipid.h>
6798 #include "../../cbus/tahvo.h"
6799 diff --git a/drivers/video/omap/lcd_omap2evm.c b/drivers/video/omap/lcd_omap2evm.c
6800 index 2fc46c2..1908a2b 100644
6801 --- a/drivers/video/omap/lcd_omap2evm.c
6802 +++ b/drivers/video/omap/lcd_omap2evm.c
6803 @@ -25,9 +25,9 @@
6804 #include <linux/platform_device.h>
6805 #include <linux/gpio.h>
6806 #include <linux/i2c/twl4030.h>
6807 +#include <linux/omapfb.h>
6809 #include <mach/mux.h>
6810 -#include <mach/omapfb.h>
6811 #include <asm/mach-types.h>
6813 #define LCD_PANEL_ENABLE_GPIO 154
6814 diff --git a/drivers/video/omap/lcd_omap3beagle.c b/drivers/video/omap/lcd_omap3beagle.c
6815 index eae43e4..6be117e 100644
6816 --- a/drivers/video/omap/lcd_omap3beagle.c
6817 +++ b/drivers/video/omap/lcd_omap3beagle.c
6818 @@ -24,9 +24,9 @@
6819 #include <linux/platform_device.h>
6820 #include <linux/gpio.h>
6821 #include <linux/i2c/twl4030.h>
6822 +#include <linux/omapfb.h>
6824 #include <mach/mux.h>
6825 -#include <mach/omapfb.h>
6826 #include <asm/mach-types.h>
6828 #define LCD_PANEL_ENABLE_GPIO 170
6829 diff --git a/drivers/video/omap/lcd_omap3evm.c b/drivers/video/omap/lcd_omap3evm.c
6830 index 1c3d814..10ba48c 100644
6831 --- a/drivers/video/omap/lcd_omap3evm.c
6832 +++ b/drivers/video/omap/lcd_omap3evm.c
6833 @@ -24,9 +24,9 @@
6834 #include <linux/platform_device.h>
6835 #include <linux/gpio.h>
6836 #include <linux/i2c/twl4030.h>
6837 +#include <linux/omapfb.h>
6839 #include <mach/mux.h>
6840 -#include <mach/omapfb.h>
6841 #include <asm/mach-types.h>
6843 #define LCD_PANEL_ENABLE_GPIO 153
6844 diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/omap/lcd_osk.c
6845 index 379c96d..d6b193e 100644
6846 --- a/drivers/video/omap/lcd_osk.c
6847 +++ b/drivers/video/omap/lcd_osk.c
6848 @@ -22,10 +22,10 @@
6850 #include <linux/module.h>
6851 #include <linux/platform_device.h>
6852 +#include <linux/omapfb.h>
6854 #include <mach/gpio.h>
6855 #include <mach/mux.h>
6856 -#include <mach/omapfb.h>
6858 static int osk_panel_init(struct lcd_panel *panel, struct omapfb_device *fbdev)
6860 diff --git a/drivers/video/omap/lcd_overo.c b/drivers/video/omap/lcd_overo.c
6861 index 2bc5c92..40c2026 100644
6862 --- a/drivers/video/omap/lcd_overo.c
6863 +++ b/drivers/video/omap/lcd_overo.c
6864 @@ -22,10 +22,10 @@
6865 #include <linux/module.h>
6866 #include <linux/platform_device.h>
6867 #include <linux/i2c/twl4030.h>
6868 +#include <linux/omapfb.h>
6870 #include <mach/gpio.h>
6871 #include <mach/mux.h>
6872 -#include <mach/omapfb.h>
6873 #include <asm/mach-types.h>
6875 #define LCD_ENABLE 144
6876 diff --git a/drivers/video/omap/lcd_p2.c b/drivers/video/omap/lcd_p2.c
6877 index dd40fd7..bc5abef 100644
6878 --- a/drivers/video/omap/lcd_p2.c
6879 +++ b/drivers/video/omap/lcd_p2.c
6880 @@ -24,10 +24,10 @@
6881 #include <linux/module.h>
6882 #include <linux/delay.h>
6883 #include <linux/platform_device.h>
6884 +#include <linux/omapfb.h>
6886 #include <mach/mux.h>
6887 #include <mach/gpio.h>
6888 -#include <mach/omapfb.h>
6891 * File: epson-md-tft.h
6892 diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/omap/lcd_palmte.c
6893 index 2183173..dcb456c 100644
6894 --- a/drivers/video/omap/lcd_palmte.c
6895 +++ b/drivers/video/omap/lcd_palmte.c
6896 @@ -22,9 +22,9 @@
6897 #include <linux/module.h>
6898 #include <linux/platform_device.h>
6899 #include <linux/io.h>
6900 +#include <linux/omapfb.h>
6902 #include <mach/fpga.h>
6903 -#include <mach/omapfb.h>
6905 static int palmte_panel_init(struct lcd_panel *panel,
6906 struct omapfb_device *fbdev)
6907 diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/omap/lcd_palmtt.c
6908 index 57b0f6c..e8adab8 100644
6909 --- a/drivers/video/omap/lcd_palmtt.c
6910 +++ b/drivers/video/omap/lcd_palmtt.c
6911 @@ -28,9 +28,9 @@ GPIO13 - screen blanking
6912 #include <linux/platform_device.h>
6913 #include <linux/module.h>
6914 #include <linux/io.h>
6915 +#include <linux/omapfb.h>
6917 #include <mach/gpio.h>
6918 -#include <mach/omapfb.h>
6920 static int palmtt_panel_init(struct lcd_panel *panel,
6921 struct omapfb_device *fbdev)
6922 diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/omap/lcd_palmz71.c
6923 index d33d78b..d5b3f82 100644
6924 --- a/drivers/video/omap/lcd_palmz71.c
6925 +++ b/drivers/video/omap/lcd_palmz71.c
6926 @@ -23,8 +23,7 @@
6927 #include <linux/module.h>
6928 #include <linux/platform_device.h>
6929 #include <linux/io.h>
6931 -#include <mach/omapfb.h>
6932 +#include <linux/omapfb.h>
6934 static int palmz71_panel_init(struct lcd_panel *panel,
6935 struct omapfb_device *fbdev)
6936 diff --git a/drivers/video/omap/lcdc.c b/drivers/video/omap/lcdc.c
6937 index ab39492..633e33c 100644
6938 --- a/drivers/video/omap/lcdc.c
6939 +++ b/drivers/video/omap/lcdc.c
6940 @@ -28,9 +28,9 @@
6941 #include <linux/dma-mapping.h>
6942 #include <linux/vmalloc.h>
6943 #include <linux/clk.h>
6944 +#include <linux/omapfb.h>
6946 #include <mach/dma.h>
6947 -#include <mach/omapfb.h>
6949 #include <asm/mach-types.h>
6951 diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/omap/omapfb_main.c
6952 index 3bb4247..c6306af 100644
6953 --- a/drivers/video/omap/omapfb_main.c
6954 +++ b/drivers/video/omap/omapfb_main.c
6955 @@ -27,9 +27,9 @@
6956 #include <linux/platform_device.h>
6957 #include <linux/mm.h>
6958 #include <linux/uaccess.h>
6959 +#include <linux/omapfb.h>
6961 #include <mach/dma.h>
6962 -#include <mach/omapfb.h>
6964 #include "lcdc.h"
6965 #include "dispc.h"
6966 diff --git a/drivers/video/omap/rfbi.c b/drivers/video/omap/rfbi.c
6967 index 29fa368..118cfa9 100644
6968 --- a/drivers/video/omap/rfbi.c
6969 +++ b/drivers/video/omap/rfbi.c
6970 @@ -26,8 +26,7 @@
6971 #include <linux/interrupt.h>
6972 #include <linux/clk.h>
6973 #include <linux/io.h>
6975 -#include <mach/omapfb.h>
6976 +#include <linux/omapfb.h>
6978 #include "dispc.h"
6980 diff --git a/drivers/video/omap/sossi.c b/drivers/video/omap/sossi.c
6981 index cc697cc..ff9dd71 100644
6982 --- a/drivers/video/omap/sossi.c
6983 +++ b/drivers/video/omap/sossi.c
6984 @@ -23,9 +23,9 @@
6985 #include <linux/clk.h>
6986 #include <linux/irq.h>
6987 #include <linux/io.h>
6988 +#include <linux/omapfb.h>
6990 #include <mach/dma.h>
6991 -#include <mach/omapfb.h>
6993 #include "lcdc.h"
6995 diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
6996 new file mode 100644
6997 index 0000000..89bf210
6998 --- /dev/null
6999 +++ b/drivers/video/omap2/Kconfig
7000 @@ -0,0 +1,3 @@
7001 +source "drivers/video/omap2/dss/Kconfig"
7002 +source "drivers/video/omap2/displays/Kconfig"
7003 +source "drivers/video/omap2/omapfb/Kconfig"
7004 diff --git a/drivers/video/omap2/Makefile b/drivers/video/omap2/Makefile
7005 new file mode 100644
7006 index 0000000..72134db
7007 --- /dev/null
7008 +++ b/drivers/video/omap2/Makefile
7009 @@ -0,0 +1,4 @@
7010 +# OMAP2/3 Display Subsystem
7011 +obj-y += dss/
7012 +obj-y += displays/
7013 +obj-y += omapfb/
7014 diff --git a/drivers/video/omap2/displays/Kconfig b/drivers/video/omap2/displays/Kconfig
7015 new file mode 100644
7016 index 0000000..35e4bee
7017 --- /dev/null
7018 +++ b/drivers/video/omap2/displays/Kconfig
7019 @@ -0,0 +1,32 @@
7020 +menu "OMAP2/3 Display Device Drivers"
7021 + depends on OMAP2_DSS
7023 +config PANEL_GENERIC
7024 + tristate "Generic Panel"
7025 + help
7026 + Generic panel driver.
7027 + Used for DVI output for Beagle and OMAP3 SDP.
7029 +config PANEL_SAMSUNG_LTE430WQ_F0C
7030 + tristate "Samsung LTE430WQ-F0C LCD Panel"
7031 + depends on OMAP2_DSS
7032 + help
7033 + LCD Panel used on Overo Palo43
7035 +config PANEL_SHARP_LS037V7DW01
7036 + tristate "Sharp LS037V7DW01 LCD Panel"
7037 + depends on OMAP2_DSS
7038 + help
7039 + LCD Panel used in TI's SDP3430 and EVM boards
7041 +config PANEL_N800
7042 + tristate "Panel N8x0"
7043 + help
7044 + N8x0 LCD (hack)
7046 +config CTRL_BLIZZARD
7047 + tristate "Blizzard Controller"
7048 + help
7049 + Blizzard Controller (hack)
7051 +endmenu
7052 diff --git a/drivers/video/omap2/displays/Makefile b/drivers/video/omap2/displays/Makefile
7053 new file mode 100644
7054 index 0000000..1b74b7e
7055 --- /dev/null
7056 +++ b/drivers/video/omap2/displays/Makefile
7057 @@ -0,0 +1,6 @@
7058 +obj-$(CONFIG_PANEL_GENERIC) += panel-generic.o
7059 +obj-$(CONFIG_PANEL_SAMSUNG_LTE430WQ_F0C) += panel-samsung-lte430wq-f0c.o
7060 +obj-$(CONFIG_PANEL_SHARP_LS037V7DW01) += panel-sharp-ls037v7dw01.o
7062 +obj-$(CONFIG_CTRL_BLIZZARD) += ctrl-blizzard.o
7063 +obj-$(CONFIG_PANEL_N800) += panel-n800.o
7064 diff --git a/drivers/video/omap2/displays/ctrl-blizzard.c b/drivers/video/omap2/displays/ctrl-blizzard.c
7065 new file mode 100644
7066 index 0000000..6698e4d
7067 --- /dev/null
7068 +++ b/drivers/video/omap2/displays/ctrl-blizzard.c
7069 @@ -0,0 +1,279 @@
7071 +//#define DEBUG
7073 +#include <linux/kernel.h>
7074 +#include <linux/module.h>
7075 +#include <linux/clk.h>
7076 +#include <linux/delay.h>
7077 +#include <linux/err.h>
7079 +#include <mach/display.h>
7080 +#include <mach/dma.h>
7082 +#ifdef DEBUG
7083 +#define DBG(format, ...) printk(KERN_DEBUG "Blizzard: " format, ## __VA_ARGS__)
7084 +#else
7085 +#define DBG(format, ...)
7086 +#endif
7088 +#define BLIZZARD_REV_CODE 0x00
7089 +#define BLIZZARD_CONFIG 0x02
7090 +#define BLIZZARD_PLL_DIV 0x04
7091 +#define BLIZZARD_PLL_LOCK_RANGE 0x06
7092 +#define BLIZZARD_PLL_CLOCK_SYNTH_0 0x08
7093 +#define BLIZZARD_PLL_CLOCK_SYNTH_1 0x0a
7094 +#define BLIZZARD_PLL_MODE 0x0c
7095 +#define BLIZZARD_CLK_SRC 0x0e
7096 +#define BLIZZARD_MEM_BANK0_ACTIVATE 0x10
7097 +#define BLIZZARD_MEM_BANK0_STATUS 0x14
7098 +#define BLIZZARD_PANEL_CONFIGURATION 0x28
7099 +#define BLIZZARD_HDISP 0x2a
7100 +#define BLIZZARD_HNDP 0x2c
7101 +#define BLIZZARD_VDISP0 0x2e
7102 +#define BLIZZARD_VDISP1 0x30
7103 +#define BLIZZARD_VNDP 0x32
7104 +#define BLIZZARD_HSW 0x34
7105 +#define BLIZZARD_VSW 0x38
7106 +#define BLIZZARD_DISPLAY_MODE 0x68
7107 +#define BLIZZARD_INPUT_WIN_X_START_0 0x6c
7108 +#define BLIZZARD_DATA_SOURCE_SELECT 0x8e
7109 +#define BLIZZARD_DISP_MEM_DATA_PORT 0x90
7110 +#define BLIZZARD_DISP_MEM_READ_ADDR0 0x92
7111 +#define BLIZZARD_POWER_SAVE 0xE6
7112 +#define BLIZZARD_NDISP_CTRL_STATUS 0xE8
7114 +/* Data source select */
7115 +/* For S1D13745 */
7116 +#define BLIZZARD_SRC_WRITE_LCD_BACKGROUND 0x00
7117 +#define BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE 0x01
7118 +#define BLIZZARD_SRC_WRITE_OVERLAY_ENABLE 0x04
7119 +#define BLIZZARD_SRC_DISABLE_OVERLAY 0x05
7120 +/* For S1D13744 */
7121 +#define BLIZZARD_SRC_WRITE_LCD 0x00
7122 +#define BLIZZARD_SRC_BLT_LCD 0x06
7124 +#define BLIZZARD_COLOR_RGB565 0x01
7125 +#define BLIZZARD_COLOR_YUV420 0x09
7127 +#define BLIZZARD_VERSION_S1D13745 0x01 /* Hailstorm */
7128 +#define BLIZZARD_VERSION_S1D13744 0x02 /* Blizzard */
7130 +#define BLIZZARD_AUTO_UPDATE_TIME (HZ / 20)
7134 +static struct {
7135 + int version;
7136 +} blizzard;
7139 +static inline void blizzard_cmd(u8 cmd)
7141 + omap_rfbi_write_command(&cmd, 1);
7144 +static inline void blizzard_write(u8 cmd, const u8 *buf, int len)
7146 + omap_rfbi_write_command(&cmd, 1);
7147 + omap_rfbi_write_data(buf, len);
7150 +static inline void blizzard_read(u8 cmd, u8 *buf, int len)
7152 + omap_rfbi_write_command(&cmd, 1);
7153 + omap_rfbi_read_data(buf, len);
7156 +static u8 blizzard_read_reg(u8 cmd)
7158 + u8 data;
7159 + blizzard_read(cmd, &data, 1);
7160 + return data;
7163 +static int blizzard_ctrl_init(struct omap_display *display)
7165 + DBG("blizzard_ctrl_init\n");
7167 + return 0;
7171 +static int blizzard_ctrl_enable(struct omap_display *display)
7173 + int r = 0;
7174 + u8 rev, conf;
7176 + DBG("blizzard_ctrl_enable\n");
7178 + if (display->hw_config.ctrl_enable) {
7179 + r = display->hw_config.ctrl_enable(display);
7180 + if (r)
7181 + return r;
7184 + msleep(100);
7186 + rev = blizzard_read_reg(BLIZZARD_CLK_SRC);
7187 + printk("CLK_SRC %x\n", rev);
7189 + rev = blizzard_read_reg(BLIZZARD_PLL_DIV);
7190 + printk("PLLDIV %x\n", rev);
7192 + rev = blizzard_read_reg(BLIZZARD_REV_CODE);
7193 + conf = blizzard_read_reg(BLIZZARD_CONFIG);
7195 + printk("rev %x, conf %x\n", rev, conf);
7197 + switch (rev & 0xfc) {
7198 + case 0x9c:
7199 + blizzard.version = BLIZZARD_VERSION_S1D13744;
7200 + pr_info("omapfb: s1d13744 LCD controller rev %d "
7201 + "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
7202 + break;
7203 + case 0xa4:
7204 + blizzard.version = BLIZZARD_VERSION_S1D13745;
7205 + pr_info("omapfb: s1d13745 LCD controller rev %d "
7206 + "initialized (CNF pins %x)\n", rev & 0x03, conf & 0x07);
7207 + break;
7208 + default:
7209 + printk("invalid s1d1374x revision %02x\n",
7210 + rev);
7211 + r = -ENODEV;
7214 + return r;
7217 +static void blizzard_ctrl_disable(struct omap_display *display)
7219 + DBG("blizzard_ctrl_disable\n");
7221 + if (display->hw_config.ctrl_disable)
7222 + display->hw_config.ctrl_disable(display);
7225 +int rfbi_configure(int rfbi_module, int bpp, int lines);
7227 +static void blizzard_ctrl_setup_update(struct omap_display *display,
7228 + u16 x, u16 y, u16 w, u16 h)
7230 + u8 tmp[18];
7231 + int x_end, y_end;
7233 + DBG("blizzard_ctrl_setup_update\n");
7235 + x_end = x + w - 1;
7236 + y_end = y + h - 1;
7238 + tmp[0] = x;
7239 + tmp[1] = x >> 8;
7240 + tmp[2] = y;
7241 + tmp[3] = y >> 8;
7242 + tmp[4] = x_end;
7243 + tmp[5] = x_end >> 8;
7244 + tmp[6] = y_end;
7245 + tmp[7] = y_end >> 8;
7247 + /* scaling? */
7248 + tmp[8] = x;
7249 + tmp[9] = x >> 8;
7250 + tmp[10] = y;
7251 + tmp[11] = y >> 8;
7252 + tmp[12] = x_end;
7253 + tmp[13] = x_end >> 8;
7254 + tmp[14] = y_end;
7255 + tmp[15] = y_end >> 8;
7257 + tmp[16] = BLIZZARD_COLOR_RGB565; //color_mode;
7259 + if (blizzard.version == BLIZZARD_VERSION_S1D13745)
7260 + tmp[17] = BLIZZARD_SRC_WRITE_LCD_BACKGROUND;
7261 + else
7262 + tmp[17] = blizzard.version == BLIZZARD_VERSION_S1D13744 ?
7263 + BLIZZARD_SRC_WRITE_LCD :
7264 + BLIZZARD_SRC_WRITE_LCD_DESTRUCTIVE;
7266 + rfbi_configure(display->hw_config.u.rfbi.channel,
7267 + 16,
7268 + 8);
7270 + blizzard_write(BLIZZARD_INPUT_WIN_X_START_0, tmp, 18);
7272 + rfbi_configure(display->hw_config.u.rfbi.channel,
7273 + 16,
7274 + 16);
7277 +static int blizzard_ctrl_enable_te(struct omap_display *display, bool enable)
7279 + return 0;
7282 +static int blizzard_ctrl_rotate(struct omap_display *display, u8 rotate)
7284 + return 0;
7287 +static int blizzard_ctrl_mirror(struct omap_display *display, bool enable)
7289 + return 0;
7292 +static int blizzard_run_test(struct omap_display *display, int test_num)
7294 + return 0;
7297 +static struct omap_ctrl blizzard_ctrl = {
7298 + .owner = THIS_MODULE,
7299 + .name = "ctrl-blizzard",
7300 + .init = blizzard_ctrl_init,
7301 + .enable = blizzard_ctrl_enable,
7302 + .disable = blizzard_ctrl_disable,
7303 + .setup_update = blizzard_ctrl_setup_update,
7304 + .enable_te = blizzard_ctrl_enable_te,
7305 + .set_rotate = blizzard_ctrl_rotate,
7306 + .set_mirror = blizzard_ctrl_mirror,
7307 + .run_test = blizzard_run_test,
7308 + .pixel_size = 16,
7310 + .timings = {
7311 + .cs_on_time = 0,
7313 + .we_on_time = 9000,
7314 + .we_off_time = 18000,
7315 + .we_cycle_time = 36000,
7317 + .re_on_time = 9000,
7318 + .re_off_time = 27000,
7319 + .re_cycle_time = 36000,
7321 + .access_time = 27000,
7322 + .cs_off_time = 36000,
7324 + .cs_pulse_width = 0,
7325 + },
7329 +static int __init blizzard_init(void)
7331 + DBG("blizzard_init\n");
7332 + omap_dss_register_ctrl(&blizzard_ctrl);
7333 + return 0;
7336 +static void __exit blizzard_exit(void)
7338 + DBG("blizzard_exit\n");
7340 + omap_dss_unregister_ctrl(&blizzard_ctrl);
7343 +module_init(blizzard_init);
7344 +module_exit(blizzard_exit);
7346 +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
7347 +MODULE_DESCRIPTION("Blizzard Driver");
7348 +MODULE_LICENSE("GPL");
7349 diff --git a/drivers/video/omap2/displays/panel-generic.c b/drivers/video/omap2/displays/panel-generic.c
7350 new file mode 100644
7351 index 0000000..8382acb
7352 --- /dev/null
7353 +++ b/drivers/video/omap2/displays/panel-generic.c
7354 @@ -0,0 +1,96 @@
7356 + * Generic panel support
7358 + * Copyright (C) 2008 Nokia Corporation
7359 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
7361 + * This program is free software; you can redistribute it and/or modify it
7362 + * under the terms of the GNU General Public License version 2 as published by
7363 + * the Free Software Foundation.
7365 + * This program is distributed in the hope that it will be useful, but WITHOUT
7366 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7367 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
7368 + * more details.
7370 + * You should have received a copy of the GNU General Public License along with
7371 + * this program. If not, see <http://www.gnu.org/licenses/>.
7372 + */
7374 +#include <linux/module.h>
7375 +#include <linux/delay.h>
7377 +#include <mach/display.h>
7379 +static int generic_panel_init(struct omap_display *display)
7381 + return 0;
7384 +static int generic_panel_enable(struct omap_display *display)
7386 + int r = 0;
7388 + if (display->hw_config.panel_enable)
7389 + r = display->hw_config.panel_enable(display);
7391 + return r;
7394 +static void generic_panel_disable(struct omap_display *display)
7396 + if (display->hw_config.panel_disable)
7397 + display->hw_config.panel_disable(display);
7400 +static int generic_panel_suspend(struct omap_display *display)
7402 + generic_panel_disable(display);
7403 + return 0;
7406 +static int generic_panel_resume(struct omap_display *display)
7408 + return generic_panel_enable(display);
7411 +static struct omap_panel generic_panel = {
7412 + .owner = THIS_MODULE,
7413 + .name = "panel-generic",
7414 + .init = generic_panel_init,
7415 + .enable = generic_panel_enable,
7416 + .disable = generic_panel_disable,
7417 + .suspend = generic_panel_suspend,
7418 + .resume = generic_panel_resume,
7420 + .timings = {
7421 + /* 640 x 480 @ 60 Hz Reduced blanking VESA CVT 0.31M3-R */
7422 + .x_res = 640,
7423 + .y_res = 480,
7424 + .pixel_clock = 23500,
7425 + .hfp = 48,
7426 + .hsw = 32,
7427 + .hbp = 80,
7428 + .vfp = 3,
7429 + .vsw = 4,
7430 + .vbp = 7,
7431 + },
7433 + .config = OMAP_DSS_LCD_TFT,
7437 +static int __init generic_panel_drv_init(void)
7439 + omap_dss_register_panel(&generic_panel);
7440 + return 0;
7443 +static void __exit generic_panel_drv_exit(void)
7445 + omap_dss_unregister_panel(&generic_panel);
7448 +module_init(generic_panel_drv_init);
7449 +module_exit(generic_panel_drv_exit);
7450 +MODULE_LICENSE("GPL");
7451 diff --git a/drivers/video/omap2/displays/panel-n800.c b/drivers/video/omap2/displays/panel-n800.c
7452 new file mode 100644
7453 index 0000000..91d3e37
7454 --- /dev/null
7455 +++ b/drivers/video/omap2/displays/panel-n800.c
7456 @@ -0,0 +1,435 @@
7458 +/*#define DEBUG*/
7460 +#include <linux/kernel.h>
7461 +#include <linux/module.h>
7462 +#include <linux/clk.h>
7463 +#include <linux/platform_device.h>
7464 +#include <linux/delay.h>
7465 +#include <linux/spi/spi.h>
7466 +#include <linux/jiffies.h>
7467 +#include <linux/sched.h>
7468 +#include <linux/backlight.h>
7469 +#include <linux/fb.h>
7471 +#include <mach/display.h>
7472 +#include <mach/dma.h>
7474 +#define MIPID_CMD_READ_DISP_ID 0x04
7475 +#define MIPID_CMD_READ_RED 0x06
7476 +#define MIPID_CMD_READ_GREEN 0x07
7477 +#define MIPID_CMD_READ_BLUE 0x08
7478 +#define MIPID_CMD_READ_DISP_STATUS 0x09
7479 +#define MIPID_CMD_RDDSDR 0x0F
7480 +#define MIPID_CMD_SLEEP_IN 0x10
7481 +#define MIPID_CMD_SLEEP_OUT 0x11
7482 +#define MIPID_CMD_DISP_OFF 0x28
7483 +#define MIPID_CMD_DISP_ON 0x29
7485 +#define MIPID_VER_LPH8923 3
7486 +#define MIPID_VER_LS041Y3 4
7488 +#define MIPID_ESD_CHECK_PERIOD msecs_to_jiffies(5000)
7490 +#ifdef DEBUG
7491 +#define DBG(format, ...) printk(KERN_DEBUG "PN800: " format, ## __VA_ARGS__)
7492 +#else
7493 +#define DBG(format, ...)
7494 +#endif
7496 +struct pn800_device {
7497 + struct backlight_device *bl_dev;
7498 + int enabled;
7499 + int model;
7500 + int revision;
7501 + u8 display_id[3];
7502 + unsigned int saved_bklight_level;
7503 + unsigned long hw_guard_end; /* next value of jiffies
7504 + when we can issue the
7505 + next sleep in/out command */
7506 + unsigned long hw_guard_wait; /* max guard time in jiffies */
7508 + struct spi_device *spi;
7509 + struct mutex mutex;
7510 + struct omap_panel panel;
7511 + struct omap_display *display;
7515 +static void pn800_transfer(struct pn800_device *md, int cmd,
7516 + const u8 *wbuf, int wlen, u8 *rbuf, int rlen)
7518 + struct spi_message m;
7519 + struct spi_transfer *x, xfer[4];
7520 + u16 w;
7521 + int r;
7523 + BUG_ON(md->spi == NULL);
7525 + spi_message_init(&m);
7527 + memset(xfer, 0, sizeof(xfer));
7528 + x = &xfer[0];
7530 + cmd &= 0xff;
7531 + x->tx_buf = &cmd;
7532 + x->bits_per_word = 9;
7533 + x->len = 2;
7534 + spi_message_add_tail(x, &m);
7536 + if (wlen) {
7537 + x++;
7538 + x->tx_buf = wbuf;
7539 + x->len = wlen;
7540 + x->bits_per_word = 9;
7541 + spi_message_add_tail(x, &m);
7544 + if (rlen) {
7545 + x++;
7546 + x->rx_buf = &w;
7547 + x->len = 1;
7548 + spi_message_add_tail(x, &m);
7550 + if (rlen > 1) {
7551 + /* Arrange for the extra clock before the first
7552 + * data bit.
7553 + */
7554 + x->bits_per_word = 9;
7555 + x->len = 2;
7557 + x++;
7558 + x->rx_buf = &rbuf[1];
7559 + x->len = rlen - 1;
7560 + spi_message_add_tail(x, &m);
7564 + r = spi_sync(md->spi, &m);
7565 + if (r < 0)
7566 + dev_dbg(&md->spi->dev, "spi_sync %d\n", r);
7568 + if (rlen)
7569 + rbuf[0] = w & 0xff;
7572 +static inline void pn800_cmd(struct pn800_device *md, int cmd)
7574 + pn800_transfer(md, cmd, NULL, 0, NULL, 0);
7577 +static inline void pn800_write(struct pn800_device *md,
7578 + int reg, const u8 *buf, int len)
7580 + pn800_transfer(md, reg, buf, len, NULL, 0);
7583 +static inline void pn800_read(struct pn800_device *md,
7584 + int reg, u8 *buf, int len)
7586 + pn800_transfer(md, reg, NULL, 0, buf, len);
7589 +static void set_data_lines(struct pn800_device *md, int data_lines)
7591 + u16 par;
7593 + switch (data_lines) {
7594 + case 16:
7595 + par = 0x150;
7596 + break;
7597 + case 18:
7598 + par = 0x160;
7599 + break;
7600 + case 24:
7601 + par = 0x170;
7602 + break;
7604 + pn800_write(md, 0x3a, (u8 *)&par, 2);
7607 +static void send_init_string(struct pn800_device *md)
7609 + u16 initpar[] = { 0x0102, 0x0100, 0x0100 };
7610 + int data_lines;
7612 + pn800_write(md, 0xc2, (u8 *)initpar, sizeof(initpar));
7614 + data_lines = (int)md->display->hw_config.panel_data; // XXX
7616 + set_data_lines(md, data_lines);
7619 +static void hw_guard_start(struct pn800_device *md, int guard_msec)
7621 + md->hw_guard_wait = msecs_to_jiffies(guard_msec);
7622 + md->hw_guard_end = jiffies + md->hw_guard_wait;
7625 +static void hw_guard_wait(struct pn800_device *md)
7627 + unsigned long wait = md->hw_guard_end - jiffies;
7629 + if ((long)wait > 0 && wait <= md->hw_guard_wait) {
7630 + set_current_state(TASK_UNINTERRUPTIBLE);
7631 + schedule_timeout(wait);
7635 +static void set_sleep_mode(struct pn800_device *md, int on)
7637 + int cmd, sleep_time = 50;
7639 + if (on)
7640 + cmd = MIPID_CMD_SLEEP_IN;
7641 + else
7642 + cmd = MIPID_CMD_SLEEP_OUT;
7643 + hw_guard_wait(md);
7644 + pn800_cmd(md, cmd);
7645 + hw_guard_start(md, 120);
7646 + /*
7647 + * When we enable the panel, it seems we _have_ to sleep
7648 + * 120 ms before sending the init string. When disabling the
7649 + * panel we'll sleep for the duration of 2 frames, so that the
7650 + * controller can still provide the PCLK,HS,VS signals. */
7651 + if (!on)
7652 + sleep_time = 120;
7653 + msleep(sleep_time);
7656 +static void set_display_state(struct pn800_device *md, int enabled)
7658 + int cmd = enabled ? MIPID_CMD_DISP_ON : MIPID_CMD_DISP_OFF;
7660 + pn800_cmd(md, cmd);
7663 +static int panel_enabled(struct pn800_device *md)
7665 + u32 disp_status;
7666 + int enabled;
7668 + pn800_read(md, MIPID_CMD_READ_DISP_STATUS, (u8 *)&disp_status, 4);
7669 + disp_status = __be32_to_cpu(disp_status);
7670 + enabled = (disp_status & (1 << 17)) && (disp_status & (1 << 10));
7671 + dev_dbg(&md->spi->dev,
7672 + "LCD panel %s enabled by bootloader (status 0x%04x)\n",
7673 + enabled ? "" : "not ", disp_status);
7674 + DBG("status %#08x\n", disp_status);
7675 + return enabled;
7678 +static int panel_detect(struct pn800_device *md)
7680 + pn800_read(md, MIPID_CMD_READ_DISP_ID, md->display_id, 3);
7681 + dev_dbg(&md->spi->dev, "MIPI display ID: %02x%02x%02x\n",
7682 + md->display_id[0], md->display_id[1], md->display_id[2]);
7684 + switch (md->display_id[0]) {
7685 + case 0x45:
7686 + md->model = MIPID_VER_LPH8923;
7687 + md->panel.name = "lph8923";
7688 + break;
7689 + case 0x83:
7690 + md->model = MIPID_VER_LS041Y3;
7691 + md->panel.name = "ls041y3";
7692 + //md->esd_check = ls041y3_esd_check;
7693 + break;
7694 + default:
7695 + md->panel.name = "unknown";
7696 + dev_err(&md->spi->dev, "invalid display ID\n");
7697 + return -ENODEV;
7700 + md->revision = md->display_id[1];
7701 + pr_info("omapfb: %s rev %02x LCD detected\n",
7702 + md->panel.name, md->revision);
7704 + return 0;
7709 +static int pn800_panel_enable(struct omap_display *display)
7711 + int r;
7712 + struct pn800_device *md =
7713 + (struct pn800_device *)display->panel->priv;
7715 + DBG("pn800_panel_enable\n");
7717 + mutex_lock(&md->mutex);
7719 + if (display->hw_config.panel_enable)
7720 + display->hw_config.panel_enable(display);
7722 + msleep(50); // wait for power up
7724 + r = panel_detect(md);
7725 + if (r) {
7726 + mutex_unlock(&md->mutex);
7727 + return r;
7730 + md->enabled = panel_enabled(md);
7732 + if (md->enabled) {
7733 + DBG("panel already enabled\n");
7734 + ; /*pn800_esd_start_check(md);*/
7735 + } else {
7736 + ; /*md->saved_bklight_level = pn800_get_bklight_level(panel);*/
7740 + if (md->enabled) {
7741 + mutex_unlock(&md->mutex);
7742 + return 0;
7745 + set_sleep_mode(md, 0);
7746 + md->enabled = 1;
7747 + send_init_string(md);
7748 + set_display_state(md, 1);
7749 + //mipid_set_bklight_level(panel, md->saved_bklight_level);
7750 + //mipid_esd_start_check(md);
7752 + mutex_unlock(&md->mutex);
7753 + return 0;
7756 +static void pn800_panel_disable(struct omap_display *display)
7758 + struct pn800_device *md =
7759 + (struct pn800_device *)display->panel->priv;
7761 + DBG("pn800_panel_disable\n");
7763 + mutex_lock(&md->mutex);
7765 + if (!md->enabled) {
7766 + mutex_unlock(&md->mutex);
7767 + return;
7769 + /*md->saved_bklight_level = pn800_get_bklight_level(panel);*/
7770 + /*pn800_set_bklight_level(panel, 0);*/
7772 + set_display_state(md, 0);
7773 + set_sleep_mode(md, 1);
7774 + md->enabled = 0;
7777 + if (display->hw_config.panel_disable)
7778 + display->hw_config.panel_disable(display);
7780 + mutex_unlock(&md->mutex);
7783 +static int pn800_panel_init(struct omap_display *display)
7785 + struct pn800_device *md =
7786 + (struct pn800_device *)display->panel->priv;
7788 + DBG("pn800_panel_init\n");
7790 + mutex_init(&md->mutex);
7791 + md->display = display;
7793 + return 0;
7796 +static int pn800_run_test(struct omap_display *display, int test_num)
7798 + return 0;
7801 +static struct omap_panel pn800_panel = {
7802 + .owner = THIS_MODULE,
7803 + .name = "panel-pn800",
7804 + .init = pn800_panel_init,
7805 + /*.remove = pn800_cleanup,*/
7806 + .enable = pn800_panel_enable,
7807 + .disable = pn800_panel_disable,
7808 + //.set_mode = pn800_set_mode,
7809 + .run_test = pn800_run_test,
7811 + .timings = {
7812 + .x_res = 800,
7813 + .y_res = 480,
7815 + .pixel_clock = 21940,
7816 + .hsw = 50,
7817 + .hfp = 20,
7818 + .hbp = 15,
7820 + .vsw = 2,
7821 + .vfp = 1,
7822 + .vbp = 3,
7823 + },
7824 + .config = OMAP_DSS_LCD_TFT,
7827 +static int pn800_spi_probe(struct spi_device *spi)
7829 + struct pn800_device *md;
7831 + DBG("pn800_spi_probe\n");
7833 + md = kzalloc(sizeof(*md), GFP_KERNEL);
7834 + if (md == NULL) {
7835 + dev_err(&spi->dev, "out of memory\n");
7836 + return -ENOMEM;
7839 + spi->mode = SPI_MODE_0;
7840 + md->spi = spi;
7841 + dev_set_drvdata(&spi->dev, md);
7842 + md->panel = pn800_panel;
7843 + pn800_panel.priv = md;
7845 + omap_dss_register_panel(&pn800_panel);
7847 + return 0;
7850 +static int pn800_spi_remove(struct spi_device *spi)
7852 + struct pn800_device *md = dev_get_drvdata(&spi->dev);
7854 + DBG("pn800_spi_remove\n");
7856 + omap_dss_unregister_panel(&pn800_panel);
7858 + /*pn800_disable(&md->panel);*/
7859 + kfree(md);
7861 + return 0;
7864 +static struct spi_driver pn800_spi_driver = {
7865 + .driver = {
7866 + .name = "panel-n800",
7867 + .bus = &spi_bus_type,
7868 + .owner = THIS_MODULE,
7869 + },
7870 + .probe = pn800_spi_probe,
7871 + .remove = __devexit_p(pn800_spi_remove),
7874 +static int __init pn800_init(void)
7876 + DBG("pn800_init\n");
7877 + return spi_register_driver(&pn800_spi_driver);
7880 +static void __exit pn800_exit(void)
7882 + DBG("pn800_exit\n");
7883 + spi_unregister_driver(&pn800_spi_driver);
7886 +module_init(pn800_init);
7887 +module_exit(pn800_exit);
7889 +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
7890 +MODULE_DESCRIPTION("N800 LCD Driver");
7891 +MODULE_LICENSE("GPL");
7892 diff --git a/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c
7893 new file mode 100644
7894 index 0000000..e4bb781
7895 --- /dev/null
7896 +++ b/drivers/video/omap2/displays/panel-samsung-lte430wq-f0c.c
7897 @@ -0,0 +1,108 @@
7899 + * LCD panel driver for Samsung LTE430WQ-F0C
7901 + * Author: Steve Sakoman <steve@sakoman.com>
7903 + * This program is free software; you can redistribute it and/or modify it
7904 + * under the terms of the GNU General Public License version 2 as published by
7905 + * the Free Software Foundation.
7907 + * This program is distributed in the hope that it will be useful, but WITHOUT
7908 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
7909 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
7910 + * more details.
7912 + * You should have received a copy of the GNU General Public License along with
7913 + * this program. If not, see <http://www.gnu.org/licenses/>.
7914 + */
7916 +#include <linux/module.h>
7917 +#include <linux/delay.h>
7919 +#include <mach/display.h>
7921 +static int samsung_lte_panel_init(struct omap_display *display)
7923 + return 0;
7926 +static void samsung_lte_panel_cleanup(struct omap_display *display)
7930 +static int samsung_lte_panel_enable(struct omap_display *display)
7932 + int r = 0;
7934 + /* wait couple of vsyncs until enabling the LCD */
7935 + msleep(50);
7937 + if (display->hw_config.panel_enable)
7938 + r = display->hw_config.panel_enable(display);
7940 + return r;
7943 +static void samsung_lte_panel_disable(struct omap_display *display)
7945 + if (display->hw_config.panel_disable)
7946 + display->hw_config.panel_disable(display);
7948 + /* wait at least 5 vsyncs after disabling the LCD */
7949 + msleep(100);
7952 +static int samsung_lte_panel_suspend(struct omap_display *display)
7954 + samsung_lte_panel_disable(display);
7955 + return 0;
7958 +static int samsung_lte_panel_resume(struct omap_display *display)
7960 + return samsung_lte_panel_enable(display);
7963 +static struct omap_panel samsung_lte_panel = {
7964 + .owner = THIS_MODULE,
7965 + .name = "samsung-lte430wq-f0c",
7966 + .init = samsung_lte_panel_init,
7967 + .cleanup = samsung_lte_panel_cleanup,
7968 + .enable = samsung_lte_panel_enable,
7969 + .disable = samsung_lte_panel_disable,
7970 + .suspend = samsung_lte_panel_suspend,
7971 + .resume = samsung_lte_panel_resume,
7973 + .timings = {
7974 + .x_res = 480,
7975 + .y_res = 272,
7977 + .pixel_clock = 9200,
7979 + .hsw = 41,
7980 + .hfp = 8,
7981 + .hbp = 45-41,
7983 + .vsw = 10,
7984 + .vfp = 4,
7985 + .vbp = 12-10,
7986 + },
7988 + .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IHS | OMAP_DSS_LCD_IVS,
7992 +static int __init samsung_lte_panel_drv_init(void)
7994 + omap_dss_register_panel(&samsung_lte_panel);
7995 + return 0;
7998 +static void __exit samsung_lte_panel_drv_exit(void)
8000 + omap_dss_unregister_panel(&samsung_lte_panel);
8003 +module_init(samsung_lte_panel_drv_init);
8004 +module_exit(samsung_lte_panel_drv_exit);
8005 +MODULE_LICENSE("GPL");
8006 diff --git a/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
8007 new file mode 100644
8008 index 0000000..1f99150
8009 --- /dev/null
8010 +++ b/drivers/video/omap2/displays/panel-sharp-ls037v7dw01.c
8011 @@ -0,0 +1,112 @@
8013 + * LCD panel driver for Sharp LS037V7DW01
8015 + * Copyright (C) 2008 Nokia Corporation
8016 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
8018 + * This program is free software; you can redistribute it and/or modify it
8019 + * under the terms of the GNU General Public License version 2 as published by
8020 + * the Free Software Foundation.
8022 + * This program is distributed in the hope that it will be useful, but WITHOUT
8023 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8024 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
8025 + * more details.
8027 + * You should have received a copy of the GNU General Public License along with
8028 + * this program. If not, see <http://www.gnu.org/licenses/>.
8029 + */
8031 +#include <linux/module.h>
8032 +#include <linux/delay.h>
8034 +#include <mach/display.h>
8036 +static int sharp_ls_panel_init(struct omap_display *display)
8038 + return 0;
8041 +static void sharp_ls_panel_cleanup(struct omap_display *display)
8045 +static int sharp_ls_panel_enable(struct omap_display *display)
8047 + int r = 0;
8049 + /* wait couple of vsyncs until enabling the LCD */
8050 + msleep(50);
8052 + if (display->hw_config.panel_enable)
8053 + r = display->hw_config.panel_enable(display);
8055 + return r;
8058 +static void sharp_ls_panel_disable(struct omap_display *display)
8060 + if (display->hw_config.panel_disable)
8061 + display->hw_config.panel_disable(display);
8063 + /* wait at least 5 vsyncs after disabling the LCD */
8065 + msleep(100);
8068 +static int sharp_ls_panel_suspend(struct omap_display *display)
8070 + sharp_ls_panel_disable(display);
8071 + return 0;
8074 +static int sharp_ls_panel_resume(struct omap_display *display)
8076 + return sharp_ls_panel_enable(display);
8079 +static struct omap_panel sharp_ls_panel = {
8080 + .owner = THIS_MODULE,
8081 + .name = "sharp-ls037v7dw01",
8082 + .init = sharp_ls_panel_init,
8083 + .cleanup = sharp_ls_panel_cleanup,
8084 + .enable = sharp_ls_panel_enable,
8085 + .disable = sharp_ls_panel_disable,
8086 + .suspend = sharp_ls_panel_suspend,
8087 + .resume = sharp_ls_panel_resume,
8089 + .timings = {
8090 + .x_res = 480,
8091 + .y_res = 640,
8093 + .pixel_clock = 19200,
8095 + .hsw = 2,
8096 + .hfp = 1,
8097 + .hbp = 28,
8099 + .vsw = 1,
8100 + .vfp = 1,
8101 + .vbp = 1,
8102 + },
8104 + .acb = 0x28,
8106 + .config = OMAP_DSS_LCD_TFT | OMAP_DSS_LCD_IVS | OMAP_DSS_LCD_IHS,
8110 +static int __init sharp_ls_panel_drv_init(void)
8112 + omap_dss_register_panel(&sharp_ls_panel);
8113 + return 0;
8116 +static void __exit sharp_ls_panel_drv_exit(void)
8118 + omap_dss_unregister_panel(&sharp_ls_panel);
8121 +module_init(sharp_ls_panel_drv_init);
8122 +module_exit(sharp_ls_panel_drv_exit);
8123 +MODULE_LICENSE("GPL");
8124 diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/omap2/dss/Kconfig
8125 new file mode 100644
8126 index 0000000..f2ce068
8127 --- /dev/null
8128 +++ b/drivers/video/omap2/dss/Kconfig
8129 @@ -0,0 +1,89 @@
8130 +menuconfig OMAP2_DSS
8131 + tristate "OMAP2/3 Display Subsystem support (EXPERIMENTAL)"
8132 + depends on ARCH_OMAP2 || ARCH_OMAP3
8133 + help
8134 + OMAP2/3 Display Subsystem support.
8136 +if OMAP2_DSS
8138 +config OMAP2_DSS_VRAM_SIZE
8139 + int "VRAM size (MB)"
8140 + range 0 32
8141 + default 4
8142 + help
8143 + The amount of SDRAM to reserve at boot time for video RAM use.
8144 + This VRAM will be used by omapfb and other drivers that need
8145 + large continuous RAM area for video use.
8147 + You can also set this with "vram=<bytes>" kernel argument, or
8148 + in the board file.
8150 +config OMAP2_DSS_DEBUG_SUPPORT
8151 + bool "Debug support"
8152 + default y
8153 + help
8154 + This enables debug messages. You need to enable printing
8155 + with 'debug' module parameter.
8157 +config OMAP2_DSS_RFBI
8158 + bool "RFBI support"
8159 + default n
8160 + help
8161 + MIPI DBI, or RFBI (Remote Framebuffer Interface), support.
8163 +config OMAP2_DSS_VENC
8164 + bool "VENC support"
8165 + default y
8166 + help
8167 + OMAP Video Encoder support.
8169 +config OMAP2_DSS_SDI
8170 + bool "SDI support"
8171 + depends on ARCH_OMAP3
8172 + default n
8173 + help
8174 + SDI (Serial Display Interface) support.
8176 +config OMAP2_DSS_DSI
8177 + bool "DSI support"
8178 + depends on ARCH_OMAP3
8179 + default n
8180 + help
8181 + MIPI DSI support.
8183 +config OMAP2_DSS_USE_DSI_PLL
8184 + bool "Use DSI PLL for PCLK (EXPERIMENTAL)"
8185 + default n
8186 + depends on OMAP2_DSS_DSI
8187 + help
8188 + Use DSI PLL to generate pixel clock. Currently only for DPI output.
8189 + DSI PLL can be used to generate higher and more precise pixel clocks.
8191 +config OMAP2_DSS_FAKE_VSYNC
8192 + bool "Fake VSYNC irq from manual update displays"
8193 + default n
8194 + help
8195 + If this is selected, DSI will generate a fake DISPC VSYNC interrupt
8196 + when DSI has sent a frame. This is only needed with DSI or RFBI
8197 + displays using manual mode, and you want VSYNC to, for example,
8198 + time animation.
8200 +config OMAP2_DSS_MIN_FCK_PER_PCK
8201 + int "Minimum FCK/PCK ratio (for scaling)"
8202 + range 0 32
8203 + default 0
8204 + help
8205 + This can be used to adjust the minimum FCK/PCK ratio.
8207 + With this you can make sure that DISPC FCK is at least
8208 + n x PCK. Video plane scaling requires higher FCK than
8209 + normally.
8211 + If this is set to 0, there's no extra constraint on the
8212 + DISPC FCK. However, the FCK will at minimum be
8213 + 2xPCK (if active matrix) or 3xPCK (if passive matrix).
8215 + Max FCK is 173MHz, so this doesn't work if your PCK
8216 + is very high.
8218 +endif
8219 diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/omap2/dss/Makefile
8220 new file mode 100644
8221 index 0000000..980c72c
8222 --- /dev/null
8223 +++ b/drivers/video/omap2/dss/Makefile
8224 @@ -0,0 +1,6 @@
8225 +obj-$(CONFIG_OMAP2_DSS) += omapdss.o
8226 +omapdss-y := core.o dss.o dispc.o dpi.o display.o manager.o overlay.o
8227 +omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
8228 +omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
8229 +omapdss-$(CONFIG_OMAP2_DSS_SDI) += sdi.o
8230 +omapdss-$(CONFIG_OMAP2_DSS_DSI) += dsi.o
8231 diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
8232 new file mode 100644
8233 index 0000000..ae7cd06
8234 --- /dev/null
8235 +++ b/drivers/video/omap2/dss/core.c
8236 @@ -0,0 +1,641 @@
8238 + * linux/drivers/video/omap2/dss/core.c
8240 + * Copyright (C) 2009 Nokia Corporation
8241 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
8243 + * Some code and ideas taken from drivers/video/omap/ driver
8244 + * by Imre Deak.
8246 + * This program is free software; you can redistribute it and/or modify it
8247 + * under the terms of the GNU General Public License version 2 as published by
8248 + * the Free Software Foundation.
8250 + * This program is distributed in the hope that it will be useful, but WITHOUT
8251 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8252 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
8253 + * more details.
8255 + * You should have received a copy of the GNU General Public License along with
8256 + * this program. If not, see <http://www.gnu.org/licenses/>.
8257 + */
8259 +#define DSS_SUBSYS_NAME "CORE"
8261 +#include <linux/kernel.h>
8262 +#include <linux/module.h>
8263 +#include <linux/clk.h>
8264 +#include <linux/err.h>
8265 +#include <linux/platform_device.h>
8266 +#include <linux/seq_file.h>
8267 +#include <linux/debugfs.h>
8268 +#include <linux/io.h>
8270 +#include <mach/display.h>
8271 +#include <mach/clock.h>
8273 +#include "dss.h"
8275 +static struct {
8276 + struct platform_device *pdev;
8277 + unsigned ctx_id;
8279 + struct clk *dss_ick;
8280 + struct clk *dss1_fck;
8281 + struct clk *dss2_fck;
8282 + struct clk *dss_54m_fck;
8283 + struct clk *dss_96m_fck;
8284 + unsigned num_clks_enabled;
8285 +} core;
8287 +static void dss_clk_enable_all_no_ctx(void);
8288 +static void dss_clk_disable_all_no_ctx(void);
8289 +static void dss_clk_enable_no_ctx(enum dss_clock clks);
8290 +static void dss_clk_disable_no_ctx(enum dss_clock clks);
8292 +static char *def_disp_name;
8293 +module_param_named(def_disp, def_disp_name, charp, 0);
8294 +MODULE_PARM_DESC(def_disp_name, "default display name");
8296 +#ifdef DEBUG
8297 +unsigned int dss_debug;
8298 +module_param_named(debug, dss_debug, bool, 0644);
8299 +#endif
8301 +/* CONTEXT */
8302 +static unsigned dss_get_ctx_id(void)
8304 + struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
8306 + if (!pdata->get_last_off_on_transaction_id)
8307 + return 0;
8309 + return pdata->get_last_off_on_transaction_id(&core.pdev->dev);
8312 +int dss_need_ctx_restore(void)
8314 + int id = dss_get_ctx_id();
8316 + if (id != core.ctx_id) {
8317 + DSSDBG("ctx id %u -> id %u\n",
8318 + core.ctx_id, id);
8319 + core.ctx_id = id;
8320 + return 1;
8321 + } else {
8322 + return 0;
8326 +static void save_all_ctx(void)
8328 + DSSDBG("save context\n");
8330 + dss_clk_enable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
8332 + dss_save_context();
8333 + dispc_save_context();
8334 +#ifdef CONFIG_OMAP2_DSS_DSI
8335 + dsi_save_context();
8336 +#endif
8338 + dss_clk_disable_no_ctx(DSS_CLK_ICK | DSS_CLK_FCK1);
8341 +static void restore_all_ctx(void)
8343 + DSSDBG("restore context\n");
8345 + dss_clk_enable_all_no_ctx();
8347 + dss_restore_context();
8348 + dispc_restore_context();
8349 +#ifdef CONFIG_OMAP2_DSS_DSI
8350 + dsi_restore_context();
8351 +#endif
8353 + dss_clk_disable_all_no_ctx();
8356 +/* CLOCKS */
8357 +void dss_dump_clocks(struct seq_file *s)
8359 + int i;
8360 + struct clk *clocks[5] = {
8361 + core.dss_ick,
8362 + core.dss1_fck,
8363 + core.dss2_fck,
8364 + core.dss_54m_fck,
8365 + core.dss_96m_fck
8366 + };
8368 + seq_printf(s, "- dss -\n");
8370 + seq_printf(s, "internal clk count\t%u\n", core.num_clks_enabled);
8372 + for (i = 0; i < 5; i++) {
8373 + if (!clocks[i])
8374 + continue;
8375 + seq_printf(s, "%-15s\t%lu\t%d\n",
8376 + clocks[i]->name,
8377 + clk_get_rate(clocks[i]),
8378 + clocks[i]->usecount);
8382 +static int dss_get_clocks(void)
8384 + const struct {
8385 + struct clk **clock;
8386 + char *omap2_name;
8387 + char *omap3_name;
8388 + } clocks[5] = {
8389 + { &core.dss_ick, "dss_ick", "dss_ick" }, /* L3 & L4 ick */
8390 + { &core.dss1_fck, "dss1_fck", "dss1_alwon_fck" },
8391 + { &core.dss2_fck, "dss2_fck", "dss2_alwon_fck" },
8392 + { &core.dss_54m_fck, "dss_54m_fck", "dss_tv_fck" },
8393 + { &core.dss_96m_fck, NULL, "dss_96m_fck" },
8394 + };
8396 + int r = 0;
8397 + int i;
8398 + const int num_clocks = 5;
8400 + for (i = 0; i < num_clocks; i++)
8401 + *clocks[i].clock = NULL;
8403 + for (i = 0; i < num_clocks; i++) {
8404 + struct clk *clk;
8405 + const char *clk_name;
8407 + clk_name = cpu_is_omap34xx() ? clocks[i].omap3_name
8408 + : clocks[i].omap2_name;
8410 + if (!clk_name)
8411 + continue;
8413 + clk = clk_get(NULL, clk_name);
8415 + if (IS_ERR(clk)) {
8416 + DSSERR("can't get clock %s", clk_name);
8417 + r = PTR_ERR(clk);
8418 + goto err;
8421 + DSSDBG("clk %s, rate %ld\n",
8422 + clk_name, clk_get_rate(clk));
8424 + *clocks[i].clock = clk;
8427 + return 0;
8429 +err:
8430 + for (i = 0; i < num_clocks; i++) {
8431 + if (!IS_ERR(*clocks[i].clock))
8432 + clk_put(*clocks[i].clock);
8435 + return r;
8438 +static void dss_put_clocks(void)
8440 + if (core.dss_96m_fck)
8441 + clk_put(core.dss_96m_fck);
8442 + clk_put(core.dss_54m_fck);
8443 + clk_put(core.dss1_fck);
8444 + clk_put(core.dss2_fck);
8445 + clk_put(core.dss_ick);
8448 +unsigned long dss_clk_get_rate(enum dss_clock clk)
8450 + switch (clk) {
8451 + case DSS_CLK_ICK:
8452 + return clk_get_rate(core.dss_ick);
8453 + case DSS_CLK_FCK1:
8454 + return clk_get_rate(core.dss1_fck);
8455 + case DSS_CLK_FCK2:
8456 + return clk_get_rate(core.dss2_fck);
8457 + case DSS_CLK_54M:
8458 + return clk_get_rate(core.dss_54m_fck);
8459 + case DSS_CLK_96M:
8460 + return clk_get_rate(core.dss_96m_fck);
8463 + BUG();
8464 + return 0;
8467 +static unsigned count_clk_bits(enum dss_clock clks)
8469 + unsigned num_clks = 0;
8471 + if (clks & DSS_CLK_ICK)
8472 + ++num_clks;
8473 + if (clks & DSS_CLK_FCK1)
8474 + ++num_clks;
8475 + if (clks & DSS_CLK_FCK2)
8476 + ++num_clks;
8477 + if (clks & DSS_CLK_54M)
8478 + ++num_clks;
8479 + if (clks & DSS_CLK_96M)
8480 + ++num_clks;
8482 + return num_clks;
8485 +static void dss_clk_enable_no_ctx(enum dss_clock clks)
8487 + unsigned num_clks = count_clk_bits(clks);
8489 + if (clks & DSS_CLK_ICK)
8490 + clk_enable(core.dss_ick);
8491 + if (clks & DSS_CLK_FCK1)
8492 + clk_enable(core.dss1_fck);
8493 + if (clks & DSS_CLK_FCK2)
8494 + clk_enable(core.dss2_fck);
8495 + if (clks & DSS_CLK_54M)
8496 + clk_enable(core.dss_54m_fck);
8497 + if (clks & DSS_CLK_96M)
8498 + clk_enable(core.dss_96m_fck);
8500 + core.num_clks_enabled += num_clks;
8503 +void dss_clk_enable(enum dss_clock clks)
8505 + dss_clk_enable_no_ctx(clks);
8507 + if (cpu_is_omap34xx() && dss_need_ctx_restore())
8508 + restore_all_ctx();
8511 +static void dss_clk_disable_no_ctx(enum dss_clock clks)
8513 + unsigned num_clks = count_clk_bits(clks);
8515 + if (clks & DSS_CLK_ICK)
8516 + clk_disable(core.dss_ick);
8517 + if (clks & DSS_CLK_FCK1)
8518 + clk_disable(core.dss1_fck);
8519 + if (clks & DSS_CLK_FCK2)
8520 + clk_disable(core.dss2_fck);
8521 + if (clks & DSS_CLK_54M)
8522 + clk_disable(core.dss_54m_fck);
8523 + if (clks & DSS_CLK_96M)
8524 + clk_disable(core.dss_96m_fck);
8526 + core.num_clks_enabled -= num_clks;
8529 +void dss_clk_disable(enum dss_clock clks)
8531 + if (cpu_is_omap34xx()) {
8532 + unsigned num_clks = count_clk_bits(clks);
8534 + BUG_ON(core.num_clks_enabled < num_clks);
8536 + if (core.num_clks_enabled == num_clks)
8537 + save_all_ctx();
8540 + dss_clk_disable_no_ctx(clks);
8543 +static void dss_clk_enable_all_no_ctx(void)
8545 + enum dss_clock clks;
8547 + clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
8548 + if (cpu_is_omap34xx())
8549 + clks |= DSS_CLK_96M;
8550 + dss_clk_enable_no_ctx(clks);
8553 +static void dss_clk_disable_all_no_ctx(void)
8555 + enum dss_clock clks;
8557 + clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
8558 + if (cpu_is_omap34xx())
8559 + clks |= DSS_CLK_96M;
8560 + dss_clk_disable_no_ctx(clks);
8563 +static void dss_clk_disable_all(void)
8565 + enum dss_clock clks;
8567 + clks = DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_FCK2 | DSS_CLK_54M;
8568 + if (cpu_is_omap34xx())
8569 + clks |= DSS_CLK_96M;
8570 + dss_clk_disable(clks);
8573 +/* DEBUGFS */
8574 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
8575 +static void dss_debug_dump_clocks(struct seq_file *s)
8577 + dss_dump_clocks(s);
8578 + dispc_dump_clocks(s);
8579 +#ifdef CONFIG_OMAP2_DSS_DSI
8580 + dsi_dump_clocks(s);
8581 +#endif
8584 +static int dss_debug_show(struct seq_file *s, void *unused)
8586 + void (*func)(struct seq_file *) = s->private;
8587 + func(s);
8588 + return 0;
8591 +static int dss_debug_open(struct inode *inode, struct file *file)
8593 + return single_open(file, dss_debug_show, inode->i_private);
8596 +static const struct file_operations dss_debug_fops = {
8597 + .open = dss_debug_open,
8598 + .read = seq_read,
8599 + .llseek = seq_lseek,
8600 + .release = single_release,
8603 +static struct dentry *dss_debugfs_dir;
8605 +static int dss_initialize_debugfs(void)
8607 + dss_debugfs_dir = debugfs_create_dir("omapdss", NULL);
8608 + if (IS_ERR(dss_debugfs_dir)) {
8609 + int err = PTR_ERR(dss_debugfs_dir);
8610 + dss_debugfs_dir = NULL;
8611 + return err;
8614 + debugfs_create_file("clk", S_IRUGO, dss_debugfs_dir,
8615 + &dss_debug_dump_clocks, &dss_debug_fops);
8617 + debugfs_create_file("dss", S_IRUGO, dss_debugfs_dir,
8618 + &dss_dump_regs, &dss_debug_fops);
8619 + debugfs_create_file("dispc", S_IRUGO, dss_debugfs_dir,
8620 + &dispc_dump_regs, &dss_debug_fops);
8621 +#ifdef CONFIG_OMAP2_DSS_RFBI
8622 + debugfs_create_file("rfbi", S_IRUGO, dss_debugfs_dir,
8623 + &rfbi_dump_regs, &dss_debug_fops);
8624 +#endif
8625 +#ifdef CONFIG_OMAP2_DSS_DSI
8626 + debugfs_create_file("dsi", S_IRUGO, dss_debugfs_dir,
8627 + &dsi_dump_regs, &dss_debug_fops);
8628 +#endif
8629 + return 0;
8632 +static void dss_uninitialize_debugfs(void)
8634 + if (dss_debugfs_dir)
8635 + debugfs_remove_recursive(dss_debugfs_dir);
8637 +#endif /* CONFIG_DEBUG_FS && CONFIG_OMAP2_DSS_DEBUG_SUPPORT */
8640 +/* DSI powers */
8641 +int dss_dsi_power_up(void)
8643 + struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
8645 + if (!pdata->dsi_power_up)
8646 + return 0; /* presume power is always on then */
8648 + return pdata->dsi_power_up();
8651 +void dss_dsi_power_down(void)
8653 + struct omap_dss_board_info *pdata = core.pdev->dev.platform_data;
8655 + if (!pdata->dsi_power_down)
8656 + return;
8658 + pdata->dsi_power_down();
8663 +/* PLATFORM DEVICE */
8664 +static int omap_dss_probe(struct platform_device *pdev)
8666 + int skip_init = 0;
8667 + int r;
8669 + core.pdev = pdev;
8671 + r = dss_get_clocks();
8672 + if (r)
8673 + goto fail0;
8675 + dss_clk_enable_all_no_ctx();
8677 + core.ctx_id = dss_get_ctx_id();
8678 + DSSDBG("initial ctx id %u\n", core.ctx_id);
8680 +#ifdef CONFIG_FB_OMAP_BOOTLOADER_INIT
8681 + /* DISPC_CONTROL */
8682 + if (omap_readl(0x48050440) & 1) /* LCD enabled? */
8683 + skip_init = 1;
8684 +#endif
8686 + r = dss_init(skip_init);
8687 + if (r) {
8688 + DSSERR("Failed to initialize DSS\n");
8689 + goto fail0;
8692 +#ifdef CONFIG_OMAP2_DSS_RFBI
8693 + r = rfbi_init();
8694 + if (r) {
8695 + DSSERR("Failed to initialize rfbi\n");
8696 + goto fail0;
8698 +#endif
8700 + r = dpi_init();
8701 + if (r) {
8702 + DSSERR("Failed to initialize dpi\n");
8703 + goto fail0;
8706 + r = dispc_init();
8707 + if (r) {
8708 + DSSERR("Failed to initialize dispc\n");
8709 + goto fail0;
8711 +#ifdef CONFIG_OMAP2_DSS_VENC
8712 + r = venc_init();
8713 + if (r) {
8714 + DSSERR("Failed to initialize venc\n");
8715 + goto fail0;
8717 +#endif
8718 + if (cpu_is_omap34xx()) {
8719 +#ifdef CONFIG_OMAP2_DSS_SDI
8720 + r = sdi_init(skip_init);
8721 + if (r) {
8722 + DSSERR("Failed to initialize SDI\n");
8723 + goto fail0;
8725 +#endif
8726 +#ifdef CONFIG_OMAP2_DSS_DSI
8727 + r = dsi_init();
8728 + if (r) {
8729 + DSSERR("Failed to initialize DSI\n");
8730 + goto fail0;
8732 +#endif
8735 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
8736 + r = dss_initialize_debugfs();
8737 + if (r)
8738 + goto fail0;
8739 +#endif
8741 + dss_init_displays(pdev);
8742 + dss_init_overlay_managers(pdev);
8743 + dss_init_overlays(pdev, def_disp_name);
8745 + dss_clk_disable_all();
8747 + return 0;
8749 + /* XXX fail correctly */
8750 +fail0:
8751 + return r;
8754 +static int omap_dss_remove(struct platform_device *pdev)
8756 + int c;
8758 + dss_uninit_overlays(pdev);
8759 + dss_uninit_overlay_managers(pdev);
8760 + dss_uninit_displays(pdev);
8762 +#if defined(CONFIG_DEBUG_FS) && defined(CONFIG_OMAP2_DSS_DEBUG_SUPPORT)
8763 + dss_uninitialize_debugfs();
8764 +#endif
8766 +#ifdef CONFIG_OMAP2_DSS_VENC
8767 + venc_exit();
8768 +#endif
8769 + dispc_exit();
8770 + dpi_exit();
8771 +#ifdef CONFIG_OMAP2_DSS_RFBI
8772 + rfbi_exit();
8773 +#endif
8774 + if (cpu_is_omap34xx()) {
8775 +#ifdef CONFIG_OMAP2_DSS_DSI
8776 + dsi_exit();
8777 +#endif
8778 +#ifdef CONFIG_OMAP2_DSS_SDI
8779 + sdi_exit();
8780 +#endif
8783 + dss_exit();
8785 + /* these should be removed at some point */
8786 + c = core.dss_ick->usecount;
8787 + if (c > 0) {
8788 + DSSERR("warning: dss_ick usecount %d, disabling\n", c);
8789 + while (c-- > 0)
8790 + clk_disable(core.dss_ick);
8793 + c = core.dss1_fck->usecount;
8794 + if (c > 0) {
8795 + DSSERR("warning: dss1_fck usecount %d, disabling\n", c);
8796 + while (c-- > 0)
8797 + clk_disable(core.dss1_fck);
8800 + c = core.dss2_fck->usecount;
8801 + if (c > 0) {
8802 + DSSERR("warning: dss2_fck usecount %d, disabling\n", c);
8803 + while (c-- > 0)
8804 + clk_disable(core.dss2_fck);
8807 + c = core.dss_54m_fck->usecount;
8808 + if (c > 0) {
8809 + DSSERR("warning: dss_54m_fck usecount %d, disabling\n", c);
8810 + while (c-- > 0)
8811 + clk_disable(core.dss_54m_fck);
8814 + if (core.dss_96m_fck) {
8815 + c = core.dss_96m_fck->usecount;
8816 + if (c > 0) {
8817 + DSSERR("warning: dss_96m_fck usecount %d, disabling\n",
8818 + c);
8819 + while (c-- > 0)
8820 + clk_disable(core.dss_96m_fck);
8824 + dss_put_clocks();
8826 + return 0;
8829 +static void omap_dss_shutdown(struct platform_device *pdev)
8831 + DSSDBG("shutdown\n");
8834 +static int omap_dss_suspend(struct platform_device *pdev, pm_message_t state)
8836 + DSSDBG("suspend %d\n", state.event);
8838 + return dss_suspend_all_displays();
8841 +static int omap_dss_resume(struct platform_device *pdev)
8843 + DSSDBG("resume\n");
8845 + return dss_resume_all_displays();
8848 +static struct platform_driver omap_dss_driver = {
8849 + .probe = omap_dss_probe,
8850 + .remove = omap_dss_remove,
8851 + .shutdown = omap_dss_shutdown,
8852 + .suspend = omap_dss_suspend,
8853 + .resume = omap_dss_resume,
8854 + .driver = {
8855 + .name = "omapdss",
8856 + .owner = THIS_MODULE,
8857 + },
8860 +static int __init omap_dss_init(void)
8862 + return platform_driver_register(&omap_dss_driver);
8865 +static void __exit omap_dss_exit(void)
8867 + platform_driver_unregister(&omap_dss_driver);
8870 +subsys_initcall(omap_dss_init);
8871 +module_exit(omap_dss_exit);
8874 +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
8875 +MODULE_DESCRIPTION("OMAP2/3 Display Subsystem");
8876 +MODULE_LICENSE("GPL v2");
8878 diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/omap2/dss/dispc.c
8879 new file mode 100644
8880 index 0000000..ae3e9d0
8881 --- /dev/null
8882 +++ b/drivers/video/omap2/dss/dispc.c
8883 @@ -0,0 +1,2781 @@
8885 + * linux/drivers/video/omap2/dss/dispc.c
8887 + * Copyright (C) 2009 Nokia Corporation
8888 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
8890 + * Some code and ideas taken from drivers/video/omap/ driver
8891 + * by Imre Deak.
8893 + * This program is free software; you can redistribute it and/or modify it
8894 + * under the terms of the GNU General Public License version 2 as published by
8895 + * the Free Software Foundation.
8897 + * This program is distributed in the hope that it will be useful, but WITHOUT
8898 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
8899 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
8900 + * more details.
8902 + * You should have received a copy of the GNU General Public License along with
8903 + * this program. If not, see <http://www.gnu.org/licenses/>.
8904 + */
8906 +#define DSS_SUBSYS_NAME "DISPC"
8908 +#include <linux/kernel.h>
8909 +#include <linux/dma-mapping.h>
8910 +#include <linux/vmalloc.h>
8911 +#include <linux/clk.h>
8912 +#include <linux/io.h>
8913 +#include <linux/jiffies.h>
8914 +#include <linux/seq_file.h>
8916 +#include <mach/sram.h>
8917 +#include <mach/board.h>
8918 +#include <mach/clock.h>
8920 +#include <mach/display.h>
8922 +#include "dss.h"
8924 +/* DISPC */
8925 +#define DISPC_BASE 0x48050400
8927 +#define DISPC_SZ_REGS SZ_1K
8929 +struct dispc_reg { u16 idx; };
8931 +#define DISPC_REG(idx) ((const struct dispc_reg) { idx })
8933 +/* DISPC common */
8934 +#define DISPC_REVISION DISPC_REG(0x0000)
8935 +#define DISPC_SYSCONFIG DISPC_REG(0x0010)
8936 +#define DISPC_SYSSTATUS DISPC_REG(0x0014)
8937 +#define DISPC_IRQSTATUS DISPC_REG(0x0018)
8938 +#define DISPC_IRQENABLE DISPC_REG(0x001C)
8939 +#define DISPC_CONTROL DISPC_REG(0x0040)
8940 +#define DISPC_CONFIG DISPC_REG(0x0044)
8941 +#define DISPC_CAPABLE DISPC_REG(0x0048)
8942 +#define DISPC_DEFAULT_COLOR0 DISPC_REG(0x004C)
8943 +#define DISPC_DEFAULT_COLOR1 DISPC_REG(0x0050)
8944 +#define DISPC_TRANS_COLOR0 DISPC_REG(0x0054)
8945 +#define DISPC_TRANS_COLOR1 DISPC_REG(0x0058)
8946 +#define DISPC_LINE_STATUS DISPC_REG(0x005C)
8947 +#define DISPC_LINE_NUMBER DISPC_REG(0x0060)
8948 +#define DISPC_TIMING_H DISPC_REG(0x0064)
8949 +#define DISPC_TIMING_V DISPC_REG(0x0068)
8950 +#define DISPC_POL_FREQ DISPC_REG(0x006C)
8951 +#define DISPC_DIVISOR DISPC_REG(0x0070)
8952 +#define DISPC_GLOBAL_ALPHA DISPC_REG(0x0074)
8953 +#define DISPC_SIZE_DIG DISPC_REG(0x0078)
8954 +#define DISPC_SIZE_LCD DISPC_REG(0x007C)
8956 +/* DISPC GFX plane */
8957 +#define DISPC_GFX_BA0 DISPC_REG(0x0080)
8958 +#define DISPC_GFX_BA1 DISPC_REG(0x0084)
8959 +#define DISPC_GFX_POSITION DISPC_REG(0x0088)
8960 +#define DISPC_GFX_SIZE DISPC_REG(0x008C)
8961 +#define DISPC_GFX_ATTRIBUTES DISPC_REG(0x00A0)
8962 +#define DISPC_GFX_FIFO_THRESHOLD DISPC_REG(0x00A4)
8963 +#define DISPC_GFX_FIFO_SIZE_STATUS DISPC_REG(0x00A8)
8964 +#define DISPC_GFX_ROW_INC DISPC_REG(0x00AC)
8965 +#define DISPC_GFX_PIXEL_INC DISPC_REG(0x00B0)
8966 +#define DISPC_GFX_WINDOW_SKIP DISPC_REG(0x00B4)
8967 +#define DISPC_GFX_TABLE_BA DISPC_REG(0x00B8)
8969 +#define DISPC_DATA_CYCLE1 DISPC_REG(0x01D4)
8970 +#define DISPC_DATA_CYCLE2 DISPC_REG(0x01D8)
8971 +#define DISPC_DATA_CYCLE3 DISPC_REG(0x01DC)
8973 +#define DISPC_CPR_COEF_R DISPC_REG(0x0220)
8974 +#define DISPC_CPR_COEF_G DISPC_REG(0x0224)
8975 +#define DISPC_CPR_COEF_B DISPC_REG(0x0228)
8977 +#define DISPC_GFX_PRELOAD DISPC_REG(0x022C)
8979 +/* DISPC Video plane, n = 0 for VID1 and n = 1 for VID2 */
8980 +#define DISPC_VID_REG(n, idx) DISPC_REG(0x00BC + (n)*0x90 + idx)
8982 +#define DISPC_VID_BA0(n) DISPC_VID_REG(n, 0x0000)
8983 +#define DISPC_VID_BA1(n) DISPC_VID_REG(n, 0x0004)
8984 +#define DISPC_VID_POSITION(n) DISPC_VID_REG(n, 0x0008)
8985 +#define DISPC_VID_SIZE(n) DISPC_VID_REG(n, 0x000C)
8986 +#define DISPC_VID_ATTRIBUTES(n) DISPC_VID_REG(n, 0x0010)
8987 +#define DISPC_VID_FIFO_THRESHOLD(n) DISPC_VID_REG(n, 0x0014)
8988 +#define DISPC_VID_FIFO_SIZE_STATUS(n) DISPC_VID_REG(n, 0x0018)
8989 +#define DISPC_VID_ROW_INC(n) DISPC_VID_REG(n, 0x001C)
8990 +#define DISPC_VID_PIXEL_INC(n) DISPC_VID_REG(n, 0x0020)
8991 +#define DISPC_VID_FIR(n) DISPC_VID_REG(n, 0x0024)
8992 +#define DISPC_VID_PICTURE_SIZE(n) DISPC_VID_REG(n, 0x0028)
8993 +#define DISPC_VID_ACCU0(n) DISPC_VID_REG(n, 0x002C)
8994 +#define DISPC_VID_ACCU1(n) DISPC_VID_REG(n, 0x0030)
8996 +/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
8997 +#define DISPC_VID_FIR_COEF_H(n, i) DISPC_REG(0x00F0 + (n)*0x90 + (i)*0x8)
8998 +/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
8999 +#define DISPC_VID_FIR_COEF_HV(n, i) DISPC_REG(0x00F4 + (n)*0x90 + (i)*0x8)
9000 +/* coef index i = {0, 1, 2, 3, 4} */
9001 +#define DISPC_VID_CONV_COEF(n, i) DISPC_REG(0x0130 + (n)*0x90 + (i)*0x4)
9002 +/* coef index i = {0, 1, 2, 3, 4, 5, 6, 7} */
9003 +#define DISPC_VID_FIR_COEF_V(n, i) DISPC_REG(0x01E0 + (n)*0x20 + (i)*0x4)
9005 +#define DISPC_VID_PRELOAD(n) DISPC_REG(0x230 + (n)*0x04)
9008 +#define DISPC_IRQ_MASK_ERROR (DISPC_IRQ_GFX_FIFO_UNDERFLOW | \
9009 + DISPC_IRQ_OCP_ERR | \
9010 + DISPC_IRQ_VID1_FIFO_UNDERFLOW | \
9011 + DISPC_IRQ_VID2_FIFO_UNDERFLOW | \
9012 + DISPC_IRQ_SYNC_LOST | \
9013 + DISPC_IRQ_SYNC_LOST_DIGIT)
9015 +#define DISPC_MAX_NR_ISRS 8
9017 +struct omap_dispc_isr_data {
9018 + omap_dispc_isr_t isr;
9019 + void *arg;
9020 + u32 mask;
9023 +#define REG_GET(idx, start, end) \
9024 + FLD_GET(dispc_read_reg(idx), start, end)
9026 +#define REG_FLD_MOD(idx, val, start, end) \
9027 + dispc_write_reg(idx, FLD_MOD(dispc_read_reg(idx), val, start, end))
9029 +static const struct dispc_reg dispc_reg_att[] = { DISPC_GFX_ATTRIBUTES,
9030 + DISPC_VID_ATTRIBUTES(0),
9031 + DISPC_VID_ATTRIBUTES(1) };
9033 +static struct {
9034 + void __iomem *base;
9036 + struct clk *dpll4_m4_ck;
9038 + spinlock_t irq_lock;
9040 + unsigned long cache_req_pck;
9041 + unsigned long cache_prate;
9042 + struct dispc_clock_info cache_cinfo;
9044 + u32 irq_error_mask;
9045 + struct omap_dispc_isr_data registered_isr[DISPC_MAX_NR_ISRS];
9047 + u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
9048 +} dispc;
9050 +static void omap_dispc_set_irqs(void);
9052 +static inline void dispc_write_reg(const struct dispc_reg idx, u32 val)
9054 + __raw_writel(val, dispc.base + idx.idx);
9057 +static inline u32 dispc_read_reg(const struct dispc_reg idx)
9059 + return __raw_readl(dispc.base + idx.idx);
9062 +#define SR(reg) \
9063 + dispc.ctx[(DISPC_##reg).idx / sizeof(u32)] = dispc_read_reg(DISPC_##reg)
9064 +#define RR(reg) \
9065 + dispc_write_reg(DISPC_##reg, dispc.ctx[(DISPC_##reg).idx / sizeof(u32)])
9067 +void dispc_save_context(void)
9069 + if (cpu_is_omap24xx())
9070 + return;
9072 + SR(SYSCONFIG);
9073 + SR(IRQENABLE);
9074 + SR(CONTROL);
9075 + SR(CONFIG);
9076 + SR(DEFAULT_COLOR0);
9077 + SR(DEFAULT_COLOR1);
9078 + SR(TRANS_COLOR0);
9079 + SR(TRANS_COLOR1);
9080 + SR(LINE_NUMBER);
9081 + SR(TIMING_H);
9082 + SR(TIMING_V);
9083 + SR(POL_FREQ);
9084 + SR(DIVISOR);
9085 + SR(GLOBAL_ALPHA);
9086 + SR(SIZE_DIG);
9087 + SR(SIZE_LCD);
9089 + SR(GFX_BA0);
9090 + SR(GFX_BA1);
9091 + SR(GFX_POSITION);
9092 + SR(GFX_SIZE);
9093 + SR(GFX_ATTRIBUTES);
9094 + SR(GFX_FIFO_THRESHOLD);
9095 + SR(GFX_ROW_INC);
9096 + SR(GFX_PIXEL_INC);
9097 + SR(GFX_WINDOW_SKIP);
9098 + SR(GFX_TABLE_BA);
9100 + SR(DATA_CYCLE1);
9101 + SR(DATA_CYCLE2);
9102 + SR(DATA_CYCLE3);
9104 + SR(CPR_COEF_R);
9105 + SR(CPR_COEF_G);
9106 + SR(CPR_COEF_B);
9108 + SR(GFX_PRELOAD);
9110 + /* VID1 */
9111 + SR(VID_BA0(0));
9112 + SR(VID_BA1(0));
9113 + SR(VID_POSITION(0));
9114 + SR(VID_SIZE(0));
9115 + SR(VID_ATTRIBUTES(0));
9116 + SR(VID_FIFO_THRESHOLD(0));
9117 + SR(VID_ROW_INC(0));
9118 + SR(VID_PIXEL_INC(0));
9119 + SR(VID_FIR(0));
9120 + SR(VID_PICTURE_SIZE(0));
9121 + SR(VID_ACCU0(0));
9122 + SR(VID_ACCU1(0));
9124 + SR(VID_FIR_COEF_H(0, 0));
9125 + SR(VID_FIR_COEF_H(0, 1));
9126 + SR(VID_FIR_COEF_H(0, 2));
9127 + SR(VID_FIR_COEF_H(0, 3));
9128 + SR(VID_FIR_COEF_H(0, 4));
9129 + SR(VID_FIR_COEF_H(0, 5));
9130 + SR(VID_FIR_COEF_H(0, 6));
9131 + SR(VID_FIR_COEF_H(0, 7));
9133 + SR(VID_FIR_COEF_HV(0, 0));
9134 + SR(VID_FIR_COEF_HV(0, 1));
9135 + SR(VID_FIR_COEF_HV(0, 2));
9136 + SR(VID_FIR_COEF_HV(0, 3));
9137 + SR(VID_FIR_COEF_HV(0, 4));
9138 + SR(VID_FIR_COEF_HV(0, 5));
9139 + SR(VID_FIR_COEF_HV(0, 6));
9140 + SR(VID_FIR_COEF_HV(0, 7));
9142 + SR(VID_CONV_COEF(0, 0));
9143 + SR(VID_CONV_COEF(0, 1));
9144 + SR(VID_CONV_COEF(0, 2));
9145 + SR(VID_CONV_COEF(0, 3));
9146 + SR(VID_CONV_COEF(0, 4));
9148 + SR(VID_FIR_COEF_V(0, 0));
9149 + SR(VID_FIR_COEF_V(0, 1));
9150 + SR(VID_FIR_COEF_V(0, 2));
9151 + SR(VID_FIR_COEF_V(0, 3));
9152 + SR(VID_FIR_COEF_V(0, 4));
9153 + SR(VID_FIR_COEF_V(0, 5));
9154 + SR(VID_FIR_COEF_V(0, 6));
9155 + SR(VID_FIR_COEF_V(0, 7));
9157 + SR(VID_PRELOAD(0));
9159 + /* VID2 */
9160 + SR(VID_BA0(1));
9161 + SR(VID_BA1(1));
9162 + SR(VID_POSITION(1));
9163 + SR(VID_SIZE(1));
9164 + SR(VID_ATTRIBUTES(1));
9165 + SR(VID_FIFO_THRESHOLD(1));
9166 + SR(VID_ROW_INC(1));
9167 + SR(VID_PIXEL_INC(1));
9168 + SR(VID_FIR(1));
9169 + SR(VID_PICTURE_SIZE(1));
9170 + SR(VID_ACCU0(1));
9171 + SR(VID_ACCU1(1));
9173 + SR(VID_FIR_COEF_H(1, 0));
9174 + SR(VID_FIR_COEF_H(1, 1));
9175 + SR(VID_FIR_COEF_H(1, 2));
9176 + SR(VID_FIR_COEF_H(1, 3));
9177 + SR(VID_FIR_COEF_H(1, 4));
9178 + SR(VID_FIR_COEF_H(1, 5));
9179 + SR(VID_FIR_COEF_H(1, 6));
9180 + SR(VID_FIR_COEF_H(1, 7));
9182 + SR(VID_FIR_COEF_HV(1, 0));
9183 + SR(VID_FIR_COEF_HV(1, 1));
9184 + SR(VID_FIR_COEF_HV(1, 2));
9185 + SR(VID_FIR_COEF_HV(1, 3));
9186 + SR(VID_FIR_COEF_HV(1, 4));
9187 + SR(VID_FIR_COEF_HV(1, 5));
9188 + SR(VID_FIR_COEF_HV(1, 6));
9189 + SR(VID_FIR_COEF_HV(1, 7));
9191 + SR(VID_CONV_COEF(1, 0));
9192 + SR(VID_CONV_COEF(1, 1));
9193 + SR(VID_CONV_COEF(1, 2));
9194 + SR(VID_CONV_COEF(1, 3));
9195 + SR(VID_CONV_COEF(1, 4));
9197 + SR(VID_FIR_COEF_V(1, 0));
9198 + SR(VID_FIR_COEF_V(1, 1));
9199 + SR(VID_FIR_COEF_V(1, 2));
9200 + SR(VID_FIR_COEF_V(1, 3));
9201 + SR(VID_FIR_COEF_V(1, 4));
9202 + SR(VID_FIR_COEF_V(1, 5));
9203 + SR(VID_FIR_COEF_V(1, 6));
9204 + SR(VID_FIR_COEF_V(1, 7));
9206 + SR(VID_PRELOAD(1));
9209 +void dispc_restore_context(void)
9211 + RR(SYSCONFIG);
9212 + RR(IRQENABLE);
9213 + /*RR(CONTROL);*/
9214 + RR(CONFIG);
9215 + RR(DEFAULT_COLOR0);
9216 + RR(DEFAULT_COLOR1);
9217 + RR(TRANS_COLOR0);
9218 + RR(TRANS_COLOR1);
9219 + RR(LINE_NUMBER);
9220 + RR(TIMING_H);
9221 + RR(TIMING_V);
9222 + RR(POL_FREQ);
9223 + RR(DIVISOR);
9224 + RR(GLOBAL_ALPHA);
9225 + RR(SIZE_DIG);
9226 + RR(SIZE_LCD);
9228 + RR(GFX_BA0);
9229 + RR(GFX_BA1);
9230 + RR(GFX_POSITION);
9231 + RR(GFX_SIZE);
9232 + RR(GFX_ATTRIBUTES);
9233 + RR(GFX_FIFO_THRESHOLD);
9234 + RR(GFX_ROW_INC);
9235 + RR(GFX_PIXEL_INC);
9236 + RR(GFX_WINDOW_SKIP);
9237 + RR(GFX_TABLE_BA);
9239 + RR(DATA_CYCLE1);
9240 + RR(DATA_CYCLE2);
9241 + RR(DATA_CYCLE3);
9243 + RR(CPR_COEF_R);
9244 + RR(CPR_COEF_G);
9245 + RR(CPR_COEF_B);
9247 + RR(GFX_PRELOAD);
9249 + /* VID1 */
9250 + RR(VID_BA0(0));
9251 + RR(VID_BA1(0));
9252 + RR(VID_POSITION(0));
9253 + RR(VID_SIZE(0));
9254 + RR(VID_ATTRIBUTES(0));
9255 + RR(VID_FIFO_THRESHOLD(0));
9256 + RR(VID_ROW_INC(0));
9257 + RR(VID_PIXEL_INC(0));
9258 + RR(VID_FIR(0));
9259 + RR(VID_PICTURE_SIZE(0));
9260 + RR(VID_ACCU0(0));
9261 + RR(VID_ACCU1(0));
9263 + RR(VID_FIR_COEF_H(0, 0));
9264 + RR(VID_FIR_COEF_H(0, 1));
9265 + RR(VID_FIR_COEF_H(0, 2));
9266 + RR(VID_FIR_COEF_H(0, 3));
9267 + RR(VID_FIR_COEF_H(0, 4));
9268 + RR(VID_FIR_COEF_H(0, 5));
9269 + RR(VID_FIR_COEF_H(0, 6));
9270 + RR(VID_FIR_COEF_H(0, 7));
9272 + RR(VID_FIR_COEF_HV(0, 0));
9273 + RR(VID_FIR_COEF_HV(0, 1));
9274 + RR(VID_FIR_COEF_HV(0, 2));
9275 + RR(VID_FIR_COEF_HV(0, 3));
9276 + RR(VID_FIR_COEF_HV(0, 4));
9277 + RR(VID_FIR_COEF_HV(0, 5));
9278 + RR(VID_FIR_COEF_HV(0, 6));
9279 + RR(VID_FIR_COEF_HV(0, 7));
9281 + RR(VID_CONV_COEF(0, 0));
9282 + RR(VID_CONV_COEF(0, 1));
9283 + RR(VID_CONV_COEF(0, 2));
9284 + RR(VID_CONV_COEF(0, 3));
9285 + RR(VID_CONV_COEF(0, 4));
9287 + RR(VID_FIR_COEF_V(0, 0));
9288 + RR(VID_FIR_COEF_V(0, 1));
9289 + RR(VID_FIR_COEF_V(0, 2));
9290 + RR(VID_FIR_COEF_V(0, 3));
9291 + RR(VID_FIR_COEF_V(0, 4));
9292 + RR(VID_FIR_COEF_V(0, 5));
9293 + RR(VID_FIR_COEF_V(0, 6));
9294 + RR(VID_FIR_COEF_V(0, 7));
9296 + RR(VID_PRELOAD(0));
9298 + /* VID2 */
9299 + RR(VID_BA0(1));
9300 + RR(VID_BA1(1));
9301 + RR(VID_POSITION(1));
9302 + RR(VID_SIZE(1));
9303 + RR(VID_ATTRIBUTES(1));
9304 + RR(VID_FIFO_THRESHOLD(1));
9305 + RR(VID_ROW_INC(1));
9306 + RR(VID_PIXEL_INC(1));
9307 + RR(VID_FIR(1));
9308 + RR(VID_PICTURE_SIZE(1));
9309 + RR(VID_ACCU0(1));
9310 + RR(VID_ACCU1(1));
9312 + RR(VID_FIR_COEF_H(1, 0));
9313 + RR(VID_FIR_COEF_H(1, 1));
9314 + RR(VID_FIR_COEF_H(1, 2));
9315 + RR(VID_FIR_COEF_H(1, 3));
9316 + RR(VID_FIR_COEF_H(1, 4));
9317 + RR(VID_FIR_COEF_H(1, 5));
9318 + RR(VID_FIR_COEF_H(1, 6));
9319 + RR(VID_FIR_COEF_H(1, 7));
9321 + RR(VID_FIR_COEF_HV(1, 0));
9322 + RR(VID_FIR_COEF_HV(1, 1));
9323 + RR(VID_FIR_COEF_HV(1, 2));
9324 + RR(VID_FIR_COEF_HV(1, 3));
9325 + RR(VID_FIR_COEF_HV(1, 4));
9326 + RR(VID_FIR_COEF_HV(1, 5));
9327 + RR(VID_FIR_COEF_HV(1, 6));
9328 + RR(VID_FIR_COEF_HV(1, 7));
9330 + RR(VID_CONV_COEF(1, 0));
9331 + RR(VID_CONV_COEF(1, 1));
9332 + RR(VID_CONV_COEF(1, 2));
9333 + RR(VID_CONV_COEF(1, 3));
9334 + RR(VID_CONV_COEF(1, 4));
9336 + RR(VID_FIR_COEF_V(1, 0));
9337 + RR(VID_FIR_COEF_V(1, 1));
9338 + RR(VID_FIR_COEF_V(1, 2));
9339 + RR(VID_FIR_COEF_V(1, 3));
9340 + RR(VID_FIR_COEF_V(1, 4));
9341 + RR(VID_FIR_COEF_V(1, 5));
9342 + RR(VID_FIR_COEF_V(1, 6));
9343 + RR(VID_FIR_COEF_V(1, 7));
9345 + RR(VID_PRELOAD(1));
9347 + /* enable last, because LCD & DIGIT enable are here */
9348 + RR(CONTROL);
9351 +#undef SR
9352 +#undef RR
9354 +static inline void enable_clocks(bool enable)
9356 + if (enable)
9357 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
9358 + else
9359 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
9362 +void dispc_go(enum omap_channel channel)
9364 + int bit;
9365 + unsigned long tmo;
9367 + enable_clocks(1);
9369 + if (channel == OMAP_DSS_CHANNEL_LCD)
9370 + bit = 0; /* LCDENABLE */
9371 + else
9372 + bit = 1; /* DIGITALENABLE */
9374 + /* if the channel is not enabled, we don't need GO */
9375 + if (REG_GET(DISPC_CONTROL, bit, bit) == 0)
9376 + goto end;
9378 + if (channel == OMAP_DSS_CHANNEL_LCD)
9379 + bit = 5; /* GOLCD */
9380 + else
9381 + bit = 6; /* GODIGIT */
9383 + tmo = jiffies + msecs_to_jiffies(200);
9384 + while (REG_GET(DISPC_CONTROL, bit, bit) == 1) {
9385 + if (time_after(jiffies, tmo)) {
9386 + DSSERR("timeout waiting GO flag\n");
9387 + goto end;
9389 + cpu_relax();
9392 + DSSDBG("GO %s\n", channel == OMAP_DSS_CHANNEL_LCD ? "LCD" : "DIGIT");
9394 + REG_FLD_MOD(DISPC_CONTROL, 1, bit, bit);
9395 +end:
9396 + enable_clocks(0);
9399 +static void _dispc_write_firh_reg(enum omap_plane plane, int reg, u32 value)
9401 + BUG_ON(plane == OMAP_DSS_GFX);
9403 + dispc_write_reg(DISPC_VID_FIR_COEF_H(plane-1, reg), value);
9406 +static void _dispc_write_firhv_reg(enum omap_plane plane, int reg, u32 value)
9408 + BUG_ON(plane == OMAP_DSS_GFX);
9410 + dispc_write_reg(DISPC_VID_FIR_COEF_HV(plane-1, reg), value);
9413 +static void _dispc_write_firv_reg(enum omap_plane plane, int reg, u32 value)
9415 + BUG_ON(plane == OMAP_DSS_GFX);
9417 + dispc_write_reg(DISPC_VID_FIR_COEF_V(plane-1, reg), value);
9420 +static void _dispc_set_scale_coef(enum omap_plane plane, int hscaleup,
9421 + int vscaleup, int five_taps)
9423 + /* Coefficients for horizontal up-sampling */
9424 + static const u32 coef_hup[8] = {
9425 + 0x00800000,
9426 + 0x0D7CF800,
9427 + 0x1E70F5FF,
9428 + 0x335FF5FE,
9429 + 0xF74949F7,
9430 + 0xF55F33FB,
9431 + 0xF5701EFE,
9432 + 0xF87C0DFF,
9433 + };
9435 + /* Coefficients for horizontal down-sampling */
9436 + static const u32 coef_hdown[8] = {
9437 + 0x24382400,
9438 + 0x28371FFE,
9439 + 0x2C361BFB,
9440 + 0x303516F9,
9441 + 0x11343311,
9442 + 0x1635300C,
9443 + 0x1B362C08,
9444 + 0x1F372804,
9445 + };
9447 + /* Coefficients for horizontal and vertical up-sampling */
9448 + static const u32 coef_hvup[2][8] = {
9450 + 0x00800000,
9451 + 0x037B02FF,
9452 + 0x0C6F05FE,
9453 + 0x205907FB,
9454 + 0x00404000,
9455 + 0x075920FE,
9456 + 0x056F0CFF,
9457 + 0x027B0300,
9458 + },
9460 + 0x00800000,
9461 + 0x0D7CF8FF,
9462 + 0x1E70F5FE,
9463 + 0x335FF5FB,
9464 + 0xF7404000,
9465 + 0xF55F33FE,
9466 + 0xF5701EFF,
9467 + 0xF87C0D00,
9468 + },
9469 + };
9471 + /* Coefficients for horizontal and vertical down-sampling */
9472 + static const u32 coef_hvdown[2][8] = {
9474 + 0x24382400,
9475 + 0x28391F04,
9476 + 0x2D381B08,
9477 + 0x3237170C,
9478 + 0x123737F7,
9479 + 0x173732F9,
9480 + 0x1B382DFB,
9481 + 0x1F3928FE,
9482 + },
9484 + 0x24382400,
9485 + 0x28371F04,
9486 + 0x2C361B08,
9487 + 0x3035160C,
9488 + 0x113433F7,
9489 + 0x163530F9,
9490 + 0x1B362CFB,
9491 + 0x1F3728FE,
9492 + },
9493 + };
9495 + /* Coefficients for vertical up-sampling */
9496 + static const u32 coef_vup[8] = {
9497 + 0x00000000,
9498 + 0x0000FF00,
9499 + 0x0000FEFF,
9500 + 0x0000FBFE,
9501 + 0x000000F7,
9502 + 0x0000FEFB,
9503 + 0x0000FFFE,
9504 + 0x000000FF,
9505 + };
9508 + /* Coefficients for vertical down-sampling */
9509 + static const u32 coef_vdown[8] = {
9510 + 0x00000000,
9511 + 0x000004FE,
9512 + 0x000008FB,
9513 + 0x00000CF9,
9514 + 0x0000F711,
9515 + 0x0000F90C,
9516 + 0x0000FB08,
9517 + 0x0000FE04,
9518 + };
9520 + const u32 *h_coef;
9521 + const u32 *hv_coef;
9522 + const u32 *hv_coef_mod;
9523 + const u32 *v_coef;
9524 + int i;
9526 + if (hscaleup)
9527 + h_coef = coef_hup;
9528 + else
9529 + h_coef = coef_hdown;
9531 + if (vscaleup) {
9532 + hv_coef = coef_hvup[five_taps];
9533 + v_coef = coef_vup;
9535 + if (hscaleup)
9536 + hv_coef_mod = NULL;
9537 + else
9538 + hv_coef_mod = coef_hvdown[five_taps];
9539 + } else {
9540 + hv_coef = coef_hvdown[five_taps];
9541 + v_coef = coef_vdown;
9543 + if (hscaleup)
9544 + hv_coef_mod = coef_hvup[five_taps];
9545 + else
9546 + hv_coef_mod = NULL;
9549 + for (i = 0; i < 8; i++) {
9550 + u32 h, hv;
9552 + h = h_coef[i];
9554 + hv = hv_coef[i];
9556 + if (hv_coef_mod) {
9557 + hv &= 0xffffff00;
9558 + hv |= (hv_coef_mod[i] & 0xff);
9561 + _dispc_write_firh_reg(plane, i, h);
9562 + _dispc_write_firhv_reg(plane, i, hv);
9565 + if (!five_taps)
9566 + return;
9568 + for (i = 0; i < 8; i++) {
9569 + u32 v;
9570 + v = v_coef[i];
9571 + _dispc_write_firv_reg(plane, i, v);
9575 +static void _dispc_setup_color_conv_coef(void)
9577 + const struct color_conv_coef {
9578 + int ry, rcr, rcb, gy, gcr, gcb, by, bcr, bcb;
9579 + int full_range;
9580 + } ctbl_bt601_5 = {
9581 + 298, 409, 0, 298, -208, -100, 298, 0, 517, 0,
9582 + };
9584 + const struct color_conv_coef *ct;
9586 +#define CVAL(x, y) (FLD_VAL(x, 26, 16) | FLD_VAL(y, 10, 0))
9588 + ct = &ctbl_bt601_5;
9590 + dispc_write_reg(DISPC_VID_CONV_COEF(0, 0), CVAL(ct->rcr, ct->ry));
9591 + dispc_write_reg(DISPC_VID_CONV_COEF(0, 1), CVAL(ct->gy, ct->rcb));
9592 + dispc_write_reg(DISPC_VID_CONV_COEF(0, 2), CVAL(ct->gcb, ct->gcr));
9593 + dispc_write_reg(DISPC_VID_CONV_COEF(0, 3), CVAL(ct->bcr, ct->by));
9594 + dispc_write_reg(DISPC_VID_CONV_COEF(0, 4), CVAL(0, ct->bcb));
9596 + dispc_write_reg(DISPC_VID_CONV_COEF(1, 0), CVAL(ct->rcr, ct->ry));
9597 + dispc_write_reg(DISPC_VID_CONV_COEF(1, 1), CVAL(ct->gy, ct->rcb));
9598 + dispc_write_reg(DISPC_VID_CONV_COEF(1, 2), CVAL(ct->gcb, ct->gcr));
9599 + dispc_write_reg(DISPC_VID_CONV_COEF(1, 3), CVAL(ct->bcr, ct->by));
9600 + dispc_write_reg(DISPC_VID_CONV_COEF(1, 4), CVAL(0, ct->bcb));
9602 +#undef CVAL
9604 + REG_FLD_MOD(DISPC_VID_ATTRIBUTES(0), ct->full_range, 11, 11);
9605 + REG_FLD_MOD(DISPC_VID_ATTRIBUTES(1), ct->full_range, 11, 11);
9609 +static void _dispc_set_plane_ba0(enum omap_plane plane, u32 paddr)
9611 + const struct dispc_reg ba0_reg[] = { DISPC_GFX_BA0,
9612 + DISPC_VID_BA0(0),
9613 + DISPC_VID_BA0(1) };
9615 + dispc_write_reg(ba0_reg[plane], paddr);
9618 +static void _dispc_set_plane_ba1(enum omap_plane plane, u32 paddr)
9620 + const struct dispc_reg ba1_reg[] = { DISPC_GFX_BA1,
9621 + DISPC_VID_BA1(0),
9622 + DISPC_VID_BA1(1) };
9624 + dispc_write_reg(ba1_reg[plane], paddr);
9627 +static void _dispc_set_plane_pos(enum omap_plane plane, int x, int y)
9629 + const struct dispc_reg pos_reg[] = { DISPC_GFX_POSITION,
9630 + DISPC_VID_POSITION(0),
9631 + DISPC_VID_POSITION(1) };
9633 + u32 val = FLD_VAL(y, 26, 16) | FLD_VAL(x, 10, 0);
9634 + dispc_write_reg(pos_reg[plane], val);
9637 +static void _dispc_set_pic_size(enum omap_plane plane, int width, int height)
9639 + const struct dispc_reg siz_reg[] = { DISPC_GFX_SIZE,
9640 + DISPC_VID_PICTURE_SIZE(0),
9641 + DISPC_VID_PICTURE_SIZE(1) };
9642 + u32 val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
9643 + dispc_write_reg(siz_reg[plane], val);
9646 +static void _dispc_set_vid_size(enum omap_plane plane, int width, int height)
9648 + u32 val;
9649 + const struct dispc_reg vsi_reg[] = { DISPC_VID_SIZE(0),
9650 + DISPC_VID_SIZE(1) };
9652 + BUG_ON(plane == OMAP_DSS_GFX);
9654 + val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
9655 + dispc_write_reg(vsi_reg[plane-1], val);
9658 +static void _dispc_set_pix_inc(enum omap_plane plane, u16 inc)
9660 + const struct dispc_reg ri_reg[] = { DISPC_GFX_PIXEL_INC,
9661 + DISPC_VID_PIXEL_INC(0),
9662 + DISPC_VID_PIXEL_INC(1) };
9664 + dispc_write_reg(ri_reg[plane], inc);
9667 +static void _dispc_set_row_inc(enum omap_plane plane, u16 inc)
9669 + const struct dispc_reg ri_reg[] = { DISPC_GFX_ROW_INC,
9670 + DISPC_VID_ROW_INC(0),
9671 + DISPC_VID_ROW_INC(1) };
9673 + dispc_write_reg(ri_reg[plane], inc);
9676 +static void _dispc_set_color_mode(enum omap_plane plane,
9677 + enum omap_color_mode color_mode)
9679 + u32 m = 0;
9681 + switch (color_mode) {
9682 + case OMAP_DSS_COLOR_CLUT1:
9683 + m = 0x0; break;
9684 + case OMAP_DSS_COLOR_CLUT2:
9685 + m = 0x1; break;
9686 + case OMAP_DSS_COLOR_CLUT4:
9687 + m = 0x2; break;
9688 + case OMAP_DSS_COLOR_CLUT8:
9689 + m = 0x3; break;
9690 + case OMAP_DSS_COLOR_RGB12U:
9691 + m = 0x4; break;
9692 + case OMAP_DSS_COLOR_ARGB16:
9693 + m = 0x5; break;
9694 + case OMAP_DSS_COLOR_RGB16:
9695 + m = 0x6; break;
9696 + case OMAP_DSS_COLOR_RGB24U:
9697 + m = 0x8; break;
9698 + case OMAP_DSS_COLOR_RGB24P:
9699 + m = 0x9; break;
9700 + case OMAP_DSS_COLOR_YUV2:
9701 + m = 0xa; break;
9702 + case OMAP_DSS_COLOR_UYVY:
9703 + m = 0xb; break;
9704 + case OMAP_DSS_COLOR_ARGB32:
9705 + m = 0xc; break;
9706 + case OMAP_DSS_COLOR_RGBA32:
9707 + m = 0xd; break;
9708 + case OMAP_DSS_COLOR_RGBX32:
9709 + m = 0xe; break;
9710 + default:
9711 + BUG(); break;
9714 + REG_FLD_MOD(dispc_reg_att[plane], m, 4, 1);
9717 +static void _dispc_set_channel_out(enum omap_plane plane,
9718 + enum omap_channel channel)
9720 + int shift;
9721 + u32 val;
9723 + switch (plane) {
9724 + case OMAP_DSS_GFX:
9725 + shift = 8;
9726 + break;
9727 + case OMAP_DSS_VIDEO1:
9728 + case OMAP_DSS_VIDEO2:
9729 + shift = 16;
9730 + break;
9731 + default:
9732 + BUG();
9733 + return;
9736 + val = dispc_read_reg(dispc_reg_att[plane]);
9737 + val = FLD_MOD(val, channel, shift, shift);
9738 + dispc_write_reg(dispc_reg_att[plane], val);
9741 +void dispc_set_burst_size(enum omap_plane plane,
9742 + enum omap_burst_size burst_size)
9744 + int shift;
9745 + u32 val;
9747 + enable_clocks(1);
9749 + switch (plane) {
9750 + case OMAP_DSS_GFX:
9751 + shift = 6;
9752 + break;
9753 + case OMAP_DSS_VIDEO1:
9754 + case OMAP_DSS_VIDEO2:
9755 + shift = 14;
9756 + break;
9757 + default:
9758 + BUG();
9759 + return;
9762 + val = dispc_read_reg(dispc_reg_att[plane]);
9763 + val = FLD_MOD(val, burst_size, shift+1, shift);
9764 + dispc_write_reg(dispc_reg_att[plane], val);
9766 + enable_clocks(0);
9769 +static void _dispc_set_vid_color_conv(enum omap_plane plane, bool enable)
9771 + u32 val;
9773 + BUG_ON(plane == OMAP_DSS_GFX);
9775 + val = dispc_read_reg(dispc_reg_att[plane]);
9776 + val = FLD_MOD(val, enable, 9, 9);
9777 + dispc_write_reg(dispc_reg_att[plane], val);
9780 +void dispc_set_lcd_size(u16 width, u16 height)
9782 + u32 val;
9783 + BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
9784 + val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
9785 + enable_clocks(1);
9786 + dispc_write_reg(DISPC_SIZE_LCD, val);
9787 + enable_clocks(0);
9790 +void dispc_set_digit_size(u16 width, u16 height)
9792 + u32 val;
9793 + BUG_ON((width > (1 << 11)) || (height > (1 << 11)));
9794 + val = FLD_VAL(height - 1, 26, 16) | FLD_VAL(width - 1, 10, 0);
9795 + enable_clocks(1);
9796 + dispc_write_reg(DISPC_SIZE_DIG, val);
9797 + enable_clocks(0);
9800 +u32 dispc_get_plane_fifo_size(enum omap_plane plane)
9802 + const struct dispc_reg fsz_reg[] = { DISPC_GFX_FIFO_SIZE_STATUS,
9803 + DISPC_VID_FIFO_SIZE_STATUS(0),
9804 + DISPC_VID_FIFO_SIZE_STATUS(1) };
9805 + u32 size;
9807 + enable_clocks(1);
9809 + if (cpu_is_omap24xx())
9810 + size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 8, 0);
9811 + else if (cpu_is_omap34xx())
9812 + size = FLD_GET(dispc_read_reg(fsz_reg[plane]), 10, 0);
9813 + else
9814 + BUG();
9816 + if (cpu_is_omap34xx()) {
9817 + /* FIFOMERGE */
9818 + if (REG_GET(DISPC_CONFIG, 14, 14))
9819 + size *= 3;
9822 + enable_clocks(0);
9824 + return size;
9827 +void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high)
9829 + const struct dispc_reg ftrs_reg[] = { DISPC_GFX_FIFO_THRESHOLD,
9830 + DISPC_VID_FIFO_THRESHOLD(0),
9831 + DISPC_VID_FIFO_THRESHOLD(1) };
9832 + u32 size;
9834 + enable_clocks(1);
9836 + size = dispc_get_plane_fifo_size(plane);
9838 + BUG_ON(low > size || high > size);
9840 + DSSDBG("fifo(%d) size %d, low/high old %u/%u, new %u/%u\n",
9841 + plane, size,
9842 + REG_GET(ftrs_reg[plane], 11, 0),
9843 + REG_GET(ftrs_reg[plane], 27, 16),
9844 + low, high);
9846 + if (cpu_is_omap24xx())
9847 + dispc_write_reg(ftrs_reg[plane],
9848 + FLD_VAL(high, 24, 16) | FLD_VAL(low, 8, 0));
9849 + else
9850 + dispc_write_reg(ftrs_reg[plane],
9851 + FLD_VAL(high, 27, 16) | FLD_VAL(low, 11, 0));
9853 + enable_clocks(0);
9856 +void dispc_enable_fifomerge(bool enable)
9858 + enable_clocks(1);
9860 + DSSDBG("FIFO merge %s\n", enable ? "enabled" : "disabled");
9861 + REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 14, 14);
9863 + enable_clocks(0);
9866 +static void _dispc_set_fir(enum omap_plane plane, int hinc, int vinc)
9868 + u32 val;
9869 + const struct dispc_reg fir_reg[] = { DISPC_VID_FIR(0),
9870 + DISPC_VID_FIR(1) };
9872 + BUG_ON(plane == OMAP_DSS_GFX);
9874 + val = FLD_VAL(vinc, 27, 16) | FLD_VAL(hinc, 11, 0);
9875 + dispc_write_reg(fir_reg[plane-1], val);
9878 +static void _dispc_set_vid_accu0(enum omap_plane plane, int haccu, int vaccu)
9880 + u32 val;
9881 + const struct dispc_reg ac0_reg[] = { DISPC_VID_ACCU0(0),
9882 + DISPC_VID_ACCU0(1) };
9884 + BUG_ON(plane == OMAP_DSS_GFX);
9886 + val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0);
9887 + dispc_write_reg(ac0_reg[plane-1], val);
9890 +static void _dispc_set_vid_accu1(enum omap_plane plane, int haccu, int vaccu)
9892 + u32 val;
9893 + const struct dispc_reg ac1_reg[] = { DISPC_VID_ACCU1(0),
9894 + DISPC_VID_ACCU1(1) };
9896 + BUG_ON(plane == OMAP_DSS_GFX);
9898 + val = FLD_VAL(vaccu, 25, 16) | FLD_VAL(haccu, 9, 0);
9899 + dispc_write_reg(ac1_reg[plane-1], val);
9903 +static void _dispc_set_scaling(enum omap_plane plane,
9904 + u16 orig_width, u16 orig_height,
9905 + u16 out_width, u16 out_height,
9906 + bool ilace)
9908 + int fir_hinc;
9909 + int fir_vinc;
9910 + int hscaleup, vscaleup, five_taps;
9911 + int fieldmode = 0;
9912 + int accu0 = 0;
9913 + int accu1 = 0;
9914 + u32 l;
9916 + BUG_ON(plane == OMAP_DSS_GFX);
9918 + hscaleup = orig_width <= out_width;
9919 + vscaleup = orig_height <= out_height;
9920 + five_taps = orig_height > out_height * 2;
9922 + _dispc_set_scale_coef(plane, hscaleup, vscaleup, five_taps);
9924 + if (!orig_width || orig_width == out_width)
9925 + fir_hinc = 0;
9926 + else
9927 + fir_hinc = 1024 * orig_width / out_width;
9929 + if (!orig_height || orig_height == out_height)
9930 + fir_vinc = 0;
9931 + else
9932 + fir_vinc = 1024 * orig_height / out_height;
9934 + _dispc_set_fir(plane, fir_hinc, fir_vinc);
9936 + l = dispc_read_reg(dispc_reg_att[plane]);
9937 + l &= ~((0x0f << 5) | (0x3 << 21));
9939 + l |= fir_hinc ? (1 << 5) : 0;
9940 + l |= fir_vinc ? (1 << 6) : 0;
9942 + l |= hscaleup ? 0 : (1 << 7);
9943 + l |= vscaleup ? 0 : (1 << 8);
9945 + l |= five_taps ? (1 << 21) : 0;
9946 + l |= five_taps ? (1 << 22) : 0;
9948 + dispc_write_reg(dispc_reg_att[plane], l);
9950 + if (ilace) {
9951 + if (fieldmode) {
9952 + accu0 = fir_vinc / 2;
9953 + accu1 = 0;
9954 + } else {
9955 + accu0 = 0;
9956 + accu1 = fir_vinc / 2;
9957 + if (accu1 >= 1024/2) {
9958 + accu0 = 1024/2;
9959 + accu1 -= accu0;
9964 + _dispc_set_vid_accu0(plane, 0, accu0);
9965 + _dispc_set_vid_accu1(plane, 0, accu1);
9968 +static void _dispc_set_rotation_attrs(enum omap_plane plane, u8 rotation,
9969 + bool mirroring, enum omap_color_mode color_mode)
9971 + if (color_mode == OMAP_DSS_COLOR_YUV2 ||
9972 + color_mode == OMAP_DSS_COLOR_UYVY) {
9973 + int vidrot = 0;
9975 + if (mirroring) {
9976 + switch (rotation) {
9977 + case 0: vidrot = 2; break;
9978 + case 1: vidrot = 3; break;
9979 + case 2: vidrot = 0; break;
9980 + case 3: vidrot = 1; break;
9982 + } else {
9983 + switch (rotation) {
9984 + case 0: vidrot = 0; break;
9985 + case 1: vidrot = 1; break;
9986 + case 2: vidrot = 2; break;
9987 + case 3: vidrot = 1; break;
9991 + REG_FLD_MOD(dispc_reg_att[plane], vidrot, 13, 12);
9993 + if (rotation == 1 || rotation == 3)
9994 + REG_FLD_MOD(dispc_reg_att[plane], 0x1, 18, 18);
9995 + else
9996 + REG_FLD_MOD(dispc_reg_att[plane], 0x0, 18, 18);
9997 + } else {
9998 + REG_FLD_MOD(dispc_reg_att[plane], 0, 13, 12);
9999 + REG_FLD_MOD(dispc_reg_att[plane], 0, 18, 18);
10003 +static int pixinc(int pixels, u8 ps)
10005 + if (pixels == 1)
10006 + return 1;
10007 + else if (pixels > 1)
10008 + return 1 + (pixels - 1) * ps;
10009 + else if (pixels < 0)
10010 + return 1 - (-pixels + 1) * ps;
10011 + else
10012 + BUG();
10015 +static void calc_rotation_offset(u8 rotation, bool mirror,
10016 + u16 screen_width,
10017 + u16 width, u16 height,
10018 + enum omap_color_mode color_mode, bool fieldmode,
10019 + unsigned *offset0, unsigned *offset1,
10020 + u16 *row_inc, u16 *pix_inc)
10022 + u8 ps;
10023 + u16 fbw, fbh;
10025 + switch (color_mode) {
10026 + case OMAP_DSS_COLOR_RGB16:
10027 + case OMAP_DSS_COLOR_ARGB16:
10028 + ps = 2;
10029 + break;
10031 + case OMAP_DSS_COLOR_RGB24P:
10032 + ps = 3;
10033 + break;
10035 + case OMAP_DSS_COLOR_RGB24U:
10036 + case OMAP_DSS_COLOR_ARGB32:
10037 + case OMAP_DSS_COLOR_RGBA32:
10038 + case OMAP_DSS_COLOR_RGBX32:
10039 + ps = 4;
10040 + break;
10042 + case OMAP_DSS_COLOR_YUV2:
10043 + case OMAP_DSS_COLOR_UYVY:
10044 + ps = 2;
10045 + break;
10046 + default:
10047 + BUG();
10048 + return;
10051 + DSSDBG("calc_rot(%d): scrw %d, %dx%d\n", rotation, screen_width,
10052 + width, height);
10054 + /* width & height are overlay sizes, convert to fb sizes */
10056 + if (rotation == 0 || rotation == 2) {
10057 + fbw = width;
10058 + fbh = height;
10059 + } else {
10060 + fbw = height;
10061 + fbh = width;
10064 + switch (rotation + mirror * 4) {
10065 + case 0:
10066 + *offset0 = 0;
10067 + if (fieldmode)
10068 + *offset1 = screen_width * ps;
10069 + else
10070 + *offset1 = 0;
10071 + *row_inc = pixinc(1 + (screen_width - fbw) +
10072 + (fieldmode ? screen_width : 0),
10073 + ps);
10074 + *pix_inc = pixinc(1, ps);
10075 + break;
10076 + case 1:
10077 + *offset0 = screen_width * (fbh - 1) * ps;
10078 + if (fieldmode)
10079 + *offset1 = *offset0 + ps;
10080 + else
10081 + *offset1 = *offset0;
10082 + *row_inc = pixinc(screen_width * (fbh - 1) + 1 +
10083 + (fieldmode ? 1 : 0), ps);
10084 + *pix_inc = pixinc(-screen_width, ps);
10085 + break;
10086 + case 2:
10087 + *offset0 = (screen_width * (fbh - 1) + fbw - 1) * ps;
10088 + if (fieldmode)
10089 + *offset1 = *offset0 - screen_width * ps;
10090 + else
10091 + *offset1 = *offset0;
10092 + *row_inc = pixinc(-1 -
10093 + (screen_width - fbw) -
10094 + (fieldmode ? screen_width : 0),
10095 + ps);
10096 + *pix_inc = pixinc(-1, ps);
10097 + break;
10098 + case 3:
10099 + *offset0 = (fbw - 1) * ps;
10100 + if (fieldmode)
10101 + *offset1 = *offset0 - ps;
10102 + else
10103 + *offset1 = *offset0;
10104 + *row_inc = pixinc(-screen_width * (fbh - 1) - 1 -
10105 + (fieldmode ? 1 : 0), ps);
10106 + *pix_inc = pixinc(screen_width, ps);
10107 + break;
10109 + /* mirroring */
10110 + case 0 + 4:
10111 + *offset0 = (fbw - 1) * ps;
10112 + if (fieldmode)
10113 + *offset1 = *offset0 + screen_width * ps;
10114 + else
10115 + *offset1 = *offset0;
10116 + *row_inc = pixinc(screen_width * 2 - 1 +
10117 + (fieldmode ? screen_width : 0),
10118 + ps);
10119 + *pix_inc = pixinc(-1, ps);
10120 + break;
10122 + case 1 + 4:
10123 + *offset0 = 0;
10124 + if (fieldmode)
10125 + *offset1 = *offset0 + screen_width * ps;
10126 + else
10127 + *offset1 = *offset0;
10128 + *row_inc = pixinc(-screen_width * (fbh - 1) + 1 +
10129 + (fieldmode ? 1 : 0),
10130 + ps);
10131 + *pix_inc = pixinc(screen_width, ps);
10132 + break;
10134 + case 2 + 4:
10135 + *offset0 = screen_width * (fbh - 1) * ps;
10136 + if (fieldmode)
10137 + *offset1 = *offset0 + screen_width * ps;
10138 + else
10139 + *offset1 = *offset0;
10140 + *row_inc = pixinc(1 - screen_width * 2 -
10141 + (fieldmode ? screen_width : 0),
10142 + ps);
10143 + *pix_inc = pixinc(1, ps);
10144 + break;
10146 + case 3 + 4:
10147 + *offset0 = (screen_width * (fbh - 1) + fbw - 1) * ps;
10148 + if (fieldmode)
10149 + *offset1 = *offset0 + screen_width * ps;
10150 + else
10151 + *offset1 = *offset0;
10152 + *row_inc = pixinc(screen_width * (fbh - 1) - 1 -
10153 + (fieldmode ? 1 : 0),
10154 + ps);
10155 + *pix_inc = pixinc(-screen_width, ps);
10156 + break;
10158 + default:
10159 + BUG();
10163 +static int _dispc_setup_plane(enum omap_plane plane,
10164 + enum omap_channel channel_out,
10165 + u32 paddr, u16 screen_width,
10166 + u16 pos_x, u16 pos_y,
10167 + u16 width, u16 height,
10168 + u16 out_width, u16 out_height,
10169 + enum omap_color_mode color_mode,
10170 + bool ilace,
10171 + u8 rotation, int mirror)
10173 + const int maxdownscale = cpu_is_omap34xx() ? 4 : 2;
10174 + bool five_taps = height > out_height * 2;
10175 + bool fieldmode = 0;
10176 + int cconv;
10177 + unsigned offset0, offset1;
10178 + u16 row_inc;
10179 + u16 pix_inc;
10181 + if (plane == OMAP_DSS_GFX) {
10182 + if (width != out_width || height != out_height)
10183 + return -EINVAL;
10184 + } else {
10185 + /* video plane */
10186 + if (width > (2048 >> five_taps))
10187 + return -EINVAL;
10189 + if (out_width < width / maxdownscale ||
10190 + out_width > width * 8)
10191 + return -EINVAL;
10193 + if (out_height < height / maxdownscale ||
10194 + out_height > height * 8)
10195 + return -EINVAL;
10197 + switch (color_mode) {
10198 + case OMAP_DSS_COLOR_RGB16:
10199 + case OMAP_DSS_COLOR_RGB24U:
10200 + case OMAP_DSS_COLOR_YUV2:
10201 + case OMAP_DSS_COLOR_UYVY:
10202 + break;
10204 + default:
10205 + return -EINVAL;
10210 + switch (color_mode) {
10211 + case OMAP_DSS_COLOR_RGB16:
10212 + case OMAP_DSS_COLOR_ARGB16:
10213 + case OMAP_DSS_COLOR_RGB24P:
10214 + case OMAP_DSS_COLOR_RGB24U:
10215 + case OMAP_DSS_COLOR_ARGB32:
10216 + case OMAP_DSS_COLOR_RGBA32:
10217 + case OMAP_DSS_COLOR_RGBX32:
10218 + cconv = 0;
10219 + break;
10221 + case OMAP_DSS_COLOR_YUV2:
10222 + case OMAP_DSS_COLOR_UYVY:
10223 + BUG_ON(plane == OMAP_DSS_GFX);
10224 + cconv = 1;
10225 + break;
10227 + default:
10228 + BUG();
10229 + return 1;
10232 + if (ilace && height >= out_height)
10233 + fieldmode = 1;
10235 + calc_rotation_offset(rotation, mirror,
10236 + screen_width, width, height, color_mode,
10237 + fieldmode,
10238 + &offset0, &offset1, &row_inc, &pix_inc);
10240 + DSSDBG("offset0 %u, offset1 %u, row_inc %d, pix_inc %d\n",
10241 + offset0, offset1, row_inc, pix_inc);
10243 + if (ilace) {
10244 + if (fieldmode)
10245 + height /= 2;
10246 + pos_y /= 2;
10247 + out_height /= 2;
10249 + DSSDBG("adjusting for ilace: height %d, pos_y %d, "
10250 + "out_height %d\n",
10251 + height, pos_y, out_height);
10254 + _dispc_set_channel_out(plane, channel_out);
10255 + _dispc_set_color_mode(plane, color_mode);
10257 + _dispc_set_plane_ba0(plane, paddr + offset0);
10258 + _dispc_set_plane_ba1(plane, paddr + offset1);
10260 + _dispc_set_row_inc(plane, row_inc);
10261 + _dispc_set_pix_inc(plane, pix_inc);
10263 + DSSDBG("%d,%d %dx%d -> %dx%d\n", pos_x, pos_y, width, height,
10264 + out_width, out_height);
10266 + _dispc_set_plane_pos(plane, pos_x, pos_y);
10268 + _dispc_set_pic_size(plane, width, height);
10270 + if (plane != OMAP_DSS_GFX) {
10271 + _dispc_set_scaling(plane, width, height,
10272 + out_width, out_height,
10273 + ilace);
10274 + _dispc_set_vid_size(plane, out_width, out_height);
10275 + _dispc_set_vid_color_conv(plane, cconv);
10278 + _dispc_set_rotation_attrs(plane, rotation, mirror, color_mode);
10280 + return 0;
10283 +static void _dispc_enable_plane(enum omap_plane plane, bool enable)
10285 + REG_FLD_MOD(dispc_reg_att[plane], enable ? 1 : 0, 0, 0);
10288 +static void dispc_disable_isr(void *data, u32 mask)
10290 + struct completion *compl = data;
10291 + complete(compl);
10294 +static void _enable_lcd_out(bool enable)
10296 + REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 0, 0);
10299 +void dispc_enable_lcd_out(bool enable)
10301 + struct completion frame_done_completion;
10302 + bool is_on;
10303 + int r;
10305 + enable_clocks(1);
10307 + /* When we disable LCD output, we need to wait until frame is done.
10308 + * Otherwise the DSS is still working, and turning off the clocks
10309 + * prevents DSS from going to OFF mode */
10310 + is_on = REG_GET(DISPC_CONTROL, 0, 0);
10312 + if (!enable && is_on) {
10313 + init_completion(&frame_done_completion);
10315 + r = omap_dispc_register_isr(dispc_disable_isr,
10316 + &frame_done_completion,
10317 + DISPC_IRQ_FRAMEDONE);
10319 + if (r)
10320 + DSSERR("failed to register FRAMEDONE isr\n");
10323 + _enable_lcd_out(enable);
10325 + if (!enable && is_on) {
10326 + if (!wait_for_completion_timeout(&frame_done_completion,
10327 + msecs_to_jiffies(100)))
10328 + DSSERR("timeout waiting for FRAME DONE\n");
10330 + r = omap_dispc_unregister_isr(dispc_disable_isr,
10331 + &frame_done_completion,
10332 + DISPC_IRQ_FRAMEDONE);
10334 + if (r)
10335 + DSSERR("failed to unregister FRAMEDONE isr\n");
10338 + enable_clocks(0);
10341 +static void _enable_digit_out(bool enable)
10343 + REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 1, 1);
10346 +void dispc_enable_digit_out(bool enable)
10348 + struct completion frame_done_completion;
10349 + int r;
10351 + enable_clocks(1);
10353 + if (REG_GET(DISPC_CONTROL, 1, 1) == enable) {
10354 + enable_clocks(0);
10355 + return;
10358 + if (enable) {
10359 + /* When we enable digit output, we'll get an extra digit
10360 + * sync lost interrupt, that we need to ignore */
10361 + dispc.irq_error_mask &= ~DISPC_IRQ_SYNC_LOST_DIGIT;
10362 + omap_dispc_set_irqs();
10365 + /* When we disable digit output, we need to wait until fields are done.
10366 + * Otherwise the DSS is still working, and turning off the clocks
10367 + * prevents DSS from going to OFF mode. And when enabling, we need to
10368 + * wait for the extra sync losts */
10369 + init_completion(&frame_done_completion);
10371 + r = omap_dispc_register_isr(dispc_disable_isr, &frame_done_completion,
10372 + DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD);
10373 + if (r)
10374 + DSSERR("failed to register EVSYNC isr\n");
10376 + _enable_digit_out(enable);
10378 + /* XXX I understand from TRM that we should only wait for the
10379 + * current field to complete. But it seems we have to wait
10380 + * for both fields */
10381 + if (!wait_for_completion_timeout(&frame_done_completion,
10382 + msecs_to_jiffies(100)))
10383 + DSSERR("timeout waiting for EVSYNC\n");
10385 + if (!wait_for_completion_timeout(&frame_done_completion,
10386 + msecs_to_jiffies(100)))
10387 + DSSERR("timeout waiting for EVSYNC\n");
10389 + r = omap_dispc_unregister_isr(dispc_disable_isr,
10390 + &frame_done_completion,
10391 + DISPC_IRQ_EVSYNC_EVEN | DISPC_IRQ_EVSYNC_ODD);
10392 + if (r)
10393 + DSSERR("failed to unregister EVSYNC isr\n");
10395 + if (enable) {
10396 + dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
10397 + dispc_write_reg(DISPC_IRQSTATUS, DISPC_IRQ_SYNC_LOST_DIGIT);
10398 + omap_dispc_set_irqs();
10401 + enable_clocks(0);
10404 +void dispc_lcd_enable_signal_polarity(bool act_high)
10406 + enable_clocks(1);
10407 + REG_FLD_MOD(DISPC_CONTROL, act_high ? 1 : 0, 29, 29);
10408 + enable_clocks(0);
10411 +void dispc_lcd_enable_signal(bool enable)
10413 + enable_clocks(1);
10414 + REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 28, 28);
10415 + enable_clocks(0);
10418 +void dispc_pck_free_enable(bool enable)
10420 + enable_clocks(1);
10421 + REG_FLD_MOD(DISPC_CONTROL, enable ? 1 : 0, 27, 27);
10422 + enable_clocks(0);
10425 +void dispc_enable_fifohandcheck(bool enable)
10427 + enable_clocks(1);
10428 + REG_FLD_MOD(DISPC_CONFIG, enable ? 1 : 0, 16, 16);
10429 + enable_clocks(0);
10433 +void dispc_set_lcd_display_type(enum omap_lcd_display_type type)
10435 + int mode;
10437 + switch (type) {
10438 + case OMAP_DSS_LCD_DISPLAY_STN:
10439 + mode = 0;
10440 + break;
10442 + case OMAP_DSS_LCD_DISPLAY_TFT:
10443 + mode = 1;
10444 + break;
10446 + default:
10447 + BUG();
10448 + return;
10451 + enable_clocks(1);
10452 + REG_FLD_MOD(DISPC_CONTROL, mode, 3, 3);
10453 + enable_clocks(0);
10456 +void dispc_set_loadmode(enum omap_dss_load_mode mode)
10458 + enable_clocks(1);
10459 + REG_FLD_MOD(DISPC_CONFIG, mode, 2, 1);
10460 + enable_clocks(0);
10464 +void dispc_set_default_color(enum omap_channel channel, u32 color)
10466 + const struct dispc_reg def_reg[] = { DISPC_DEFAULT_COLOR0,
10467 + DISPC_DEFAULT_COLOR1 };
10469 + enable_clocks(1);
10470 + dispc_write_reg(def_reg[channel], color);
10471 + enable_clocks(0);
10474 +void dispc_set_trans_key(enum omap_channel ch,
10475 + enum omap_dss_color_key_type type,
10476 + u32 trans_key)
10478 + const struct dispc_reg tr_reg[] = {
10479 + DISPC_TRANS_COLOR0, DISPC_TRANS_COLOR1 };
10481 + enable_clocks(1);
10482 + if (ch == OMAP_DSS_CHANNEL_LCD)
10483 + REG_FLD_MOD(DISPC_CONFIG, type, 11, 11);
10484 + else /* OMAP_DSS_CHANNEL_DIGIT */
10485 + REG_FLD_MOD(DISPC_CONFIG, type, 13, 13);
10487 + dispc_write_reg(tr_reg[ch], trans_key);
10488 + enable_clocks(0);
10491 +void dispc_enable_trans_key(enum omap_channel ch, bool enable)
10493 + enable_clocks(1);
10494 + if (ch == OMAP_DSS_CHANNEL_LCD)
10495 + REG_FLD_MOD(DISPC_CONFIG, enable, 10, 10);
10496 + else /* OMAP_DSS_CHANNEL_DIGIT */
10497 + REG_FLD_MOD(DISPC_CONFIG, enable, 12, 12);
10498 + enable_clocks(0);
10501 +void dispc_set_tft_data_lines(u8 data_lines)
10503 + int code;
10505 + switch (data_lines) {
10506 + case 12:
10507 + code = 0;
10508 + break;
10509 + case 16:
10510 + code = 1;
10511 + break;
10512 + case 18:
10513 + code = 2;
10514 + break;
10515 + case 24:
10516 + code = 3;
10517 + break;
10518 + default:
10519 + BUG();
10520 + return;
10523 + enable_clocks(1);
10524 + REG_FLD_MOD(DISPC_CONTROL, code, 9, 8);
10525 + enable_clocks(0);
10528 +void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode)
10530 + u32 l;
10531 + int stallmode;
10532 + int gpout0 = 1;
10533 + int gpout1;
10535 + switch (mode) {
10536 + case OMAP_DSS_PARALLELMODE_BYPASS:
10537 + stallmode = 0;
10538 + gpout1 = 1;
10539 + break;
10541 + case OMAP_DSS_PARALLELMODE_RFBI:
10542 + stallmode = 1;
10543 + gpout1 = 0;
10544 + break;
10546 + case OMAP_DSS_PARALLELMODE_DSI:
10547 + stallmode = 1;
10548 + gpout1 = 1;
10549 + break;
10551 + default:
10552 + BUG();
10553 + return;
10556 + enable_clocks(1);
10558 + l = dispc_read_reg(DISPC_CONTROL);
10560 + l = FLD_MOD(l, stallmode, 11, 11);
10561 + l = FLD_MOD(l, gpout0, 15, 15);
10562 + l = FLD_MOD(l, gpout1, 16, 16);
10564 + dispc_write_reg(DISPC_CONTROL, l);
10566 + enable_clocks(0);
10569 +static void _dispc_set_lcd_timings(int hsw, int hfp, int hbp,
10570 + int vsw, int vfp, int vbp)
10572 + u32 timing_h, timing_v;
10574 + BUG_ON(hsw < 1 || hsw > 64);
10575 + BUG_ON(hfp < 1 || hfp > 256);
10576 + BUG_ON(hbp < 1 || hbp > 256);
10578 + BUG_ON(vsw < 1 || vsw > 64);
10579 + BUG_ON(vfp < 0 || vfp > 255);
10580 + BUG_ON(vbp < 0 || vbp > 255);
10582 + timing_h = FLD_VAL(hsw-1, 5, 0) | FLD_VAL(hfp-1, 15, 8) |
10583 + FLD_VAL(hbp-1, 27, 20);
10585 + timing_v = FLD_VAL(vsw-1, 5, 0) | FLD_VAL(vfp, 15, 8) |
10586 + FLD_VAL(vbp, 27, 20);
10588 + enable_clocks(1);
10589 + dispc_write_reg(DISPC_TIMING_H, timing_h);
10590 + dispc_write_reg(DISPC_TIMING_V, timing_v);
10591 + enable_clocks(0);
10594 +/* change name to mode? */
10595 +void dispc_set_lcd_timings(struct omap_video_timings *timings)
10597 + unsigned xtot, ytot;
10598 + unsigned long ht, vt;
10600 + _dispc_set_lcd_timings(timings->hsw, timings->hfp, timings->hbp,
10601 + timings->vsw, timings->vfp, timings->vbp);
10603 + dispc_set_lcd_size(timings->x_res, timings->y_res);
10605 + xtot = timings->x_res + timings->hfp + timings->hsw + timings->hbp;
10606 + ytot = timings->y_res + timings->vfp + timings->vsw + timings->vbp;
10608 + ht = (timings->pixel_clock * 1000) / xtot;
10609 + vt = (timings->pixel_clock * 1000) / xtot / ytot;
10611 + DSSDBG("xres %u yres %u\n", timings->x_res, timings->y_res);
10612 + DSSDBG("pck %u\n", timings->pixel_clock);
10613 + DSSDBG("hsw %d hfp %d hbp %d vsw %d vfp %d vbp %d\n",
10614 + timings->hsw, timings->hfp, timings->hbp,
10615 + timings->vsw, timings->vfp, timings->vbp);
10617 + DSSDBG("hsync %luHz, vsync %luHz\n", ht, vt);
10620 +void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div)
10622 + BUG_ON(lck_div < 1);
10623 + BUG_ON(pck_div < 2);
10625 + enable_clocks(1);
10626 + dispc_write_reg(DISPC_DIVISOR,
10627 + FLD_VAL(lck_div, 23, 16) | FLD_VAL(pck_div, 7, 0));
10628 + enable_clocks(0);
10631 +static void dispc_get_lcd_divisor(int *lck_div, int *pck_div)
10633 + u32 l;
10634 + l = dispc_read_reg(DISPC_DIVISOR);
10635 + *lck_div = FLD_GET(l, 23, 16);
10636 + *pck_div = FLD_GET(l, 7, 0);
10639 +unsigned long dispc_fclk_rate(void)
10641 + unsigned long r = 0;
10643 + if (dss_get_dispc_clk_source() == 0)
10644 + r = dss_clk_get_rate(DSS_CLK_FCK1);
10645 + else
10646 +#ifdef CONFIG_OMAP2_DSS_DSI
10647 + r = dsi_get_dsi1_pll_rate();
10648 +#else
10649 + BUG();
10650 +#endif
10651 + return r;
10654 +unsigned long dispc_pclk_rate(void)
10656 + int lcd, pcd;
10657 + unsigned long r;
10658 + u32 l;
10660 + l = dispc_read_reg(DISPC_DIVISOR);
10662 + lcd = FLD_GET(l, 23, 16);
10663 + pcd = FLD_GET(l, 7, 0);
10665 + r = dispc_fclk_rate();
10667 + return r / lcd / pcd;
10670 +void dispc_dump_clocks(struct seq_file *s)
10672 + int lcd, pcd;
10674 + enable_clocks(1);
10676 + dispc_get_lcd_divisor(&lcd, &pcd);
10678 + seq_printf(s, "- dispc -\n");
10680 + seq_printf(s, "dispc fclk source = %s\n",
10681 + dss_get_dispc_clk_source() == 0 ?
10682 + "dss1_alwon_fclk" : "dsi1_pll_fclk");
10684 + seq_printf(s, "pixel clk = %lu / %d / %d = %lu\n",
10685 + dispc_fclk_rate(),
10686 + lcd, pcd,
10687 + dispc_pclk_rate());
10689 + enable_clocks(0);
10692 +void dispc_dump_regs(struct seq_file *s)
10694 +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dispc_read_reg(r))
10696 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
10698 + DUMPREG(DISPC_REVISION);
10699 + DUMPREG(DISPC_SYSCONFIG);
10700 + DUMPREG(DISPC_SYSSTATUS);
10701 + DUMPREG(DISPC_IRQSTATUS);
10702 + DUMPREG(DISPC_IRQENABLE);
10703 + DUMPREG(DISPC_CONTROL);
10704 + DUMPREG(DISPC_CONFIG);
10705 + DUMPREG(DISPC_CAPABLE);
10706 + DUMPREG(DISPC_DEFAULT_COLOR0);
10707 + DUMPREG(DISPC_DEFAULT_COLOR1);
10708 + DUMPREG(DISPC_TRANS_COLOR0);
10709 + DUMPREG(DISPC_TRANS_COLOR1);
10710 + DUMPREG(DISPC_LINE_STATUS);
10711 + DUMPREG(DISPC_LINE_NUMBER);
10712 + DUMPREG(DISPC_TIMING_H);
10713 + DUMPREG(DISPC_TIMING_V);
10714 + DUMPREG(DISPC_POL_FREQ);
10715 + DUMPREG(DISPC_DIVISOR);
10716 + DUMPREG(DISPC_GLOBAL_ALPHA);
10717 + DUMPREG(DISPC_SIZE_DIG);
10718 + DUMPREG(DISPC_SIZE_LCD);
10720 + DUMPREG(DISPC_GFX_BA0);
10721 + DUMPREG(DISPC_GFX_BA1);
10722 + DUMPREG(DISPC_GFX_POSITION);
10723 + DUMPREG(DISPC_GFX_SIZE);
10724 + DUMPREG(DISPC_GFX_ATTRIBUTES);
10725 + DUMPREG(DISPC_GFX_FIFO_THRESHOLD);
10726 + DUMPREG(DISPC_GFX_FIFO_SIZE_STATUS);
10727 + DUMPREG(DISPC_GFX_ROW_INC);
10728 + DUMPREG(DISPC_GFX_PIXEL_INC);
10729 + DUMPREG(DISPC_GFX_WINDOW_SKIP);
10730 + DUMPREG(DISPC_GFX_TABLE_BA);
10732 + DUMPREG(DISPC_DATA_CYCLE1);
10733 + DUMPREG(DISPC_DATA_CYCLE2);
10734 + DUMPREG(DISPC_DATA_CYCLE3);
10736 + DUMPREG(DISPC_CPR_COEF_R);
10737 + DUMPREG(DISPC_CPR_COEF_G);
10738 + DUMPREG(DISPC_CPR_COEF_B);
10740 + DUMPREG(DISPC_GFX_PRELOAD);
10742 + DUMPREG(DISPC_VID_BA0(0));
10743 + DUMPREG(DISPC_VID_BA1(0));
10744 + DUMPREG(DISPC_VID_POSITION(0));
10745 + DUMPREG(DISPC_VID_SIZE(0));
10746 + DUMPREG(DISPC_VID_ATTRIBUTES(0));
10747 + DUMPREG(DISPC_VID_FIFO_THRESHOLD(0));
10748 + DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(0));
10749 + DUMPREG(DISPC_VID_ROW_INC(0));
10750 + DUMPREG(DISPC_VID_PIXEL_INC(0));
10751 + DUMPREG(DISPC_VID_FIR(0));
10752 + DUMPREG(DISPC_VID_PICTURE_SIZE(0));
10753 + DUMPREG(DISPC_VID_ACCU0(0));
10754 + DUMPREG(DISPC_VID_ACCU1(0));
10756 + DUMPREG(DISPC_VID_BA0(1));
10757 + DUMPREG(DISPC_VID_BA1(1));
10758 + DUMPREG(DISPC_VID_POSITION(1));
10759 + DUMPREG(DISPC_VID_SIZE(1));
10760 + DUMPREG(DISPC_VID_ATTRIBUTES(1));
10761 + DUMPREG(DISPC_VID_FIFO_THRESHOLD(1));
10762 + DUMPREG(DISPC_VID_FIFO_SIZE_STATUS(1));
10763 + DUMPREG(DISPC_VID_ROW_INC(1));
10764 + DUMPREG(DISPC_VID_PIXEL_INC(1));
10765 + DUMPREG(DISPC_VID_FIR(1));
10766 + DUMPREG(DISPC_VID_PICTURE_SIZE(1));
10767 + DUMPREG(DISPC_VID_ACCU0(1));
10768 + DUMPREG(DISPC_VID_ACCU1(1));
10770 + DUMPREG(DISPC_VID_FIR_COEF_H(0, 0));
10771 + DUMPREG(DISPC_VID_FIR_COEF_H(0, 1));
10772 + DUMPREG(DISPC_VID_FIR_COEF_H(0, 2));
10773 + DUMPREG(DISPC_VID_FIR_COEF_H(0, 3));
10774 + DUMPREG(DISPC_VID_FIR_COEF_H(0, 4));
10775 + DUMPREG(DISPC_VID_FIR_COEF_H(0, 5));
10776 + DUMPREG(DISPC_VID_FIR_COEF_H(0, 6));
10777 + DUMPREG(DISPC_VID_FIR_COEF_H(0, 7));
10778 + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 0));
10779 + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 1));
10780 + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 2));
10781 + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 3));
10782 + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 4));
10783 + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 5));
10784 + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 6));
10785 + DUMPREG(DISPC_VID_FIR_COEF_HV(0, 7));
10786 + DUMPREG(DISPC_VID_CONV_COEF(0, 0));
10787 + DUMPREG(DISPC_VID_CONV_COEF(0, 1));
10788 + DUMPREG(DISPC_VID_CONV_COEF(0, 2));
10789 + DUMPREG(DISPC_VID_CONV_COEF(0, 3));
10790 + DUMPREG(DISPC_VID_CONV_COEF(0, 4));
10791 + DUMPREG(DISPC_VID_FIR_COEF_V(0, 0));
10792 + DUMPREG(DISPC_VID_FIR_COEF_V(0, 1));
10793 + DUMPREG(DISPC_VID_FIR_COEF_V(0, 2));
10794 + DUMPREG(DISPC_VID_FIR_COEF_V(0, 3));
10795 + DUMPREG(DISPC_VID_FIR_COEF_V(0, 4));
10796 + DUMPREG(DISPC_VID_FIR_COEF_V(0, 5));
10797 + DUMPREG(DISPC_VID_FIR_COEF_V(0, 6));
10798 + DUMPREG(DISPC_VID_FIR_COEF_V(0, 7));
10800 + DUMPREG(DISPC_VID_FIR_COEF_H(1, 0));
10801 + DUMPREG(DISPC_VID_FIR_COEF_H(1, 1));
10802 + DUMPREG(DISPC_VID_FIR_COEF_H(1, 2));
10803 + DUMPREG(DISPC_VID_FIR_COEF_H(1, 3));
10804 + DUMPREG(DISPC_VID_FIR_COEF_H(1, 4));
10805 + DUMPREG(DISPC_VID_FIR_COEF_H(1, 5));
10806 + DUMPREG(DISPC_VID_FIR_COEF_H(1, 6));
10807 + DUMPREG(DISPC_VID_FIR_COEF_H(1, 7));
10808 + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 0));
10809 + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 1));
10810 + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 2));
10811 + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 3));
10812 + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 4));
10813 + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 5));
10814 + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 6));
10815 + DUMPREG(DISPC_VID_FIR_COEF_HV(1, 7));
10816 + DUMPREG(DISPC_VID_CONV_COEF(1, 0));
10817 + DUMPREG(DISPC_VID_CONV_COEF(1, 1));
10818 + DUMPREG(DISPC_VID_CONV_COEF(1, 2));
10819 + DUMPREG(DISPC_VID_CONV_COEF(1, 3));
10820 + DUMPREG(DISPC_VID_CONV_COEF(1, 4));
10821 + DUMPREG(DISPC_VID_FIR_COEF_V(1, 0));
10822 + DUMPREG(DISPC_VID_FIR_COEF_V(1, 1));
10823 + DUMPREG(DISPC_VID_FIR_COEF_V(1, 2));
10824 + DUMPREG(DISPC_VID_FIR_COEF_V(1, 3));
10825 + DUMPREG(DISPC_VID_FIR_COEF_V(1, 4));
10826 + DUMPREG(DISPC_VID_FIR_COEF_V(1, 5));
10827 + DUMPREG(DISPC_VID_FIR_COEF_V(1, 6));
10828 + DUMPREG(DISPC_VID_FIR_COEF_V(1, 7));
10830 + DUMPREG(DISPC_VID_PRELOAD(0));
10831 + DUMPREG(DISPC_VID_PRELOAD(1));
10833 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
10834 +#undef DUMPREG
10837 +static void _dispc_set_pol_freq(bool onoff, bool rf, bool ieo, bool ipc,
10838 + bool ihs, bool ivs, u8 acbi, u8 acb)
10840 + u32 l = 0;
10842 + DSSDBG("onoff %d rf %d ieo %d ipc %d ihs %d ivs %d acbi %d acb %d\n",
10843 + onoff, rf, ieo, ipc, ihs, ivs, acbi, acb);
10845 + l |= FLD_VAL(onoff, 17, 17);
10846 + l |= FLD_VAL(rf, 16, 16);
10847 + l |= FLD_VAL(ieo, 15, 15);
10848 + l |= FLD_VAL(ipc, 14, 14);
10849 + l |= FLD_VAL(ihs, 13, 13);
10850 + l |= FLD_VAL(ivs, 12, 12);
10851 + l |= FLD_VAL(acbi, 11, 8);
10852 + l |= FLD_VAL(acb, 7, 0);
10854 + enable_clocks(1);
10855 + dispc_write_reg(DISPC_POL_FREQ, l);
10856 + enable_clocks(0);
10859 +void dispc_set_pol_freq(struct omap_panel *panel)
10861 + _dispc_set_pol_freq((panel->config & OMAP_DSS_LCD_ONOFF) != 0,
10862 + (panel->config & OMAP_DSS_LCD_RF) != 0,
10863 + (panel->config & OMAP_DSS_LCD_IEO) != 0,
10864 + (panel->config & OMAP_DSS_LCD_IPC) != 0,
10865 + (panel->config & OMAP_DSS_LCD_IHS) != 0,
10866 + (panel->config & OMAP_DSS_LCD_IVS) != 0,
10867 + panel->acbi, panel->acb);
10870 +void find_lck_pck_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
10871 + u16 *lck_div, u16 *pck_div)
10873 + u16 pcd_min = is_tft ? 2 : 3;
10874 + unsigned long best_pck;
10875 + u16 best_ld, cur_ld;
10876 + u16 best_pd, cur_pd;
10878 + best_pck = 0;
10879 + best_ld = 0;
10880 + best_pd = 0;
10882 + for (cur_ld = 1; cur_ld <= 255; ++cur_ld) {
10883 + unsigned long lck = fck / cur_ld;
10885 + for (cur_pd = pcd_min; cur_pd <= 255; ++cur_pd) {
10886 + unsigned long pck = lck / cur_pd;
10887 + long old_delta = abs(best_pck - req_pck);
10888 + long new_delta = abs(pck - req_pck);
10890 + if (best_pck == 0 || new_delta < old_delta) {
10891 + best_pck = pck;
10892 + best_ld = cur_ld;
10893 + best_pd = cur_pd;
10895 + if (pck == req_pck)
10896 + goto found;
10899 + if (pck < req_pck)
10900 + break;
10903 + if (lck / pcd_min < req_pck)
10904 + break;
10907 +found:
10908 + *lck_div = best_ld;
10909 + *pck_div = best_pd;
10912 +int dispc_calc_clock_div(bool is_tft, unsigned long req_pck,
10913 + struct dispc_clock_info *cinfo)
10915 + unsigned long prate;
10916 + struct dispc_clock_info cur, best;
10917 + int match = 0;
10918 + int min_fck_per_pck;
10919 + unsigned long fck_rate = dss_clk_get_rate(DSS_CLK_FCK1);
10921 + if (cpu_is_omap34xx())
10922 + prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck));
10923 + else
10924 + prate = 0;
10926 + if (req_pck == dispc.cache_req_pck &&
10927 + ((cpu_is_omap34xx() && prate == dispc.cache_prate) ||
10928 + dispc.cache_cinfo.fck == fck_rate)) {
10929 + DSSDBG("dispc clock info found from cache.\n");
10930 + *cinfo = dispc.cache_cinfo;
10931 + return 0;
10934 + min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
10936 + if (min_fck_per_pck &&
10937 + req_pck * min_fck_per_pck > DISPC_MAX_FCK) {
10938 + DSSERR("Requested pixel clock not possible with the current "
10939 + "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
10940 + "the constraint off.\n");
10941 + min_fck_per_pck = 0;
10944 +retry:
10945 + memset(&cur, 0, sizeof(cur));
10946 + memset(&best, 0, sizeof(best));
10948 + if (cpu_is_omap24xx()) {
10949 + /* XXX can we change the clock on omap2? */
10950 + cur.fck = dss_clk_get_rate(DSS_CLK_FCK1);
10951 + cur.fck_div = 1;
10953 + match = 1;
10955 + find_lck_pck_divs(is_tft, req_pck, cur.fck,
10956 + &cur.lck_div, &cur.pck_div);
10958 + cur.lck = cur.fck / cur.lck_div;
10959 + cur.pck = cur.lck / cur.pck_div;
10961 + best = cur;
10963 + goto found;
10964 + } else if (cpu_is_omap34xx()) {
10965 + for (cur.fck_div = 16; cur.fck_div > 0; --cur.fck_div) {
10966 + cur.fck = prate / cur.fck_div * 2;
10968 + if (cur.fck > DISPC_MAX_FCK)
10969 + continue;
10971 + if (min_fck_per_pck &&
10972 + cur.fck < req_pck * min_fck_per_pck)
10973 + continue;
10975 + match = 1;
10977 + find_lck_pck_divs(is_tft, req_pck, cur.fck,
10978 + &cur.lck_div, &cur.pck_div);
10980 + cur.lck = cur.fck / cur.lck_div;
10981 + cur.pck = cur.lck / cur.pck_div;
10983 + if (abs(cur.pck - req_pck) < abs(best.pck - req_pck)) {
10984 + best = cur;
10986 + if (cur.pck == req_pck)
10987 + goto found;
10990 + } else {
10991 + BUG();
10994 +found:
10995 + if (!match) {
10996 + if (min_fck_per_pck) {
10997 + DSSERR("Could not find suitable clock settings.\n"
10998 + "Turning FCK/PCK constraint off and"
10999 + "trying again.\n");
11000 + min_fck_per_pck = 0;
11001 + goto retry;
11004 + DSSERR("Could not find suitable clock settings.\n");
11006 + return -EINVAL;
11009 + if (cinfo)
11010 + *cinfo = best;
11012 + dispc.cache_req_pck = req_pck;
11013 + dispc.cache_prate = prate;
11014 + dispc.cache_cinfo = best;
11016 + return 0;
11019 +int dispc_set_clock_div(struct dispc_clock_info *cinfo)
11021 + unsigned long prate;
11022 + int r;
11024 + if (cpu_is_omap34xx()) {
11025 + prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck));
11026 + DSSDBG("dpll4_m4 = %ld\n", prate);
11029 + DSSDBG("fck = %ld (%d)\n", cinfo->fck, cinfo->fck_div);
11030 + DSSDBG("lck = %ld (%d)\n", cinfo->lck, cinfo->lck_div);
11031 + DSSDBG("pck = %ld (%d)\n", cinfo->pck, cinfo->pck_div);
11033 + if (cpu_is_omap34xx()) {
11034 + r = clk_set_rate(dispc.dpll4_m4_ck, prate / cinfo->fck_div);
11035 + if (r)
11036 + return r;
11039 + dispc_set_lcd_divisor(cinfo->lck_div, cinfo->pck_div);
11041 + return 0;
11044 +int dispc_get_clock_div(struct dispc_clock_info *cinfo)
11046 + cinfo->fck = dss_clk_get_rate(DSS_CLK_FCK1);
11048 + if (cpu_is_omap34xx()) {
11049 + unsigned long prate;
11050 + prate = clk_get_rate(clk_get_parent(dispc.dpll4_m4_ck));
11051 + cinfo->fck_div = prate / (cinfo->fck / 2);
11052 + } else {
11053 + cinfo->fck_div = 0;
11056 + cinfo->lck_div = REG_GET(DISPC_DIVISOR, 23, 16);
11057 + cinfo->pck_div = REG_GET(DISPC_DIVISOR, 7, 0);
11059 + cinfo->lck = cinfo->fck / cinfo->lck_div;
11060 + cinfo->pck = cinfo->lck / cinfo->pck_div;
11062 + return 0;
11065 +static void omap_dispc_set_irqs(void)
11067 + unsigned long flags;
11068 + u32 mask = dispc.irq_error_mask | DISPC_IRQ_WAKEUP;
11069 + int i;
11070 + struct omap_dispc_isr_data *isr_data;
11072 + spin_lock_irqsave(&dispc.irq_lock, flags);
11074 + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
11075 + isr_data = &dispc.registered_isr[i];
11077 + if (isr_data->isr == NULL)
11078 + continue;
11080 + mask |= isr_data->mask;
11083 + enable_clocks(1);
11084 + dispc_write_reg(DISPC_IRQENABLE, mask);
11085 + enable_clocks(0);
11087 + spin_unlock_irqrestore(&dispc.irq_lock, flags);
11090 +int omap_dispc_register_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
11092 + int i;
11093 + int ret;
11094 + unsigned long flags;
11095 + struct omap_dispc_isr_data *isr_data;
11097 + if (isr == NULL)
11098 + return -EINVAL;
11100 + spin_lock_irqsave(&dispc.irq_lock, flags);
11102 + /* check for duplicate entry */
11103 + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
11104 + isr_data = &dispc.registered_isr[i];
11105 + if (isr_data->isr == isr && isr_data->arg == arg &&
11106 + isr_data->mask == mask) {
11107 + ret = -EINVAL;
11108 + goto err;
11112 + isr_data = NULL;
11113 + ret = -EBUSY;
11115 + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
11116 + isr_data = &dispc.registered_isr[i];
11118 + if (isr_data->isr != NULL)
11119 + continue;
11121 + isr_data->isr = isr;
11122 + isr_data->arg = arg;
11123 + isr_data->mask = mask;
11124 + ret = 0;
11126 + break;
11128 +err:
11129 + spin_unlock_irqrestore(&dispc.irq_lock, flags);
11131 + if (ret == 0)
11132 + omap_dispc_set_irqs();
11134 + return ret;
11136 +EXPORT_SYMBOL(omap_dispc_register_isr);
11138 +int omap_dispc_unregister_isr(omap_dispc_isr_t isr, void *arg, u32 mask)
11140 + int i;
11141 + unsigned long flags;
11142 + int ret = -EINVAL;
11143 + struct omap_dispc_isr_data *isr_data;
11145 + spin_lock_irqsave(&dispc.irq_lock, flags);
11147 + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
11148 + isr_data = &dispc.registered_isr[i];
11149 + if (isr_data->isr != isr || isr_data->arg != arg ||
11150 + isr_data->mask != mask)
11151 + continue;
11153 + /* found the correct isr */
11155 + isr_data->isr = NULL;
11156 + isr_data->arg = NULL;
11157 + isr_data->mask = 0;
11159 + ret = 0;
11160 + break;
11163 + spin_unlock_irqrestore(&dispc.irq_lock, flags);
11165 + if (ret == 0)
11166 + omap_dispc_set_irqs();
11168 + return ret;
11170 +EXPORT_SYMBOL(omap_dispc_unregister_isr);
11172 +#ifdef DEBUG
11173 +static void print_irq_status(u32 status)
11175 + if ((status & dispc.irq_error_mask) == 0)
11176 + return;
11178 + printk(KERN_DEBUG "DISPC IRQ: 0x%x: ", status);
11180 +#define PIS(x) \
11181 + if (status & DISPC_IRQ_##x) \
11182 + printk(#x " ");
11183 + PIS(GFX_FIFO_UNDERFLOW);
11184 + PIS(OCP_ERR);
11185 + PIS(VID1_FIFO_UNDERFLOW);
11186 + PIS(VID2_FIFO_UNDERFLOW);
11187 + PIS(SYNC_LOST);
11188 + PIS(SYNC_LOST_DIGIT);
11189 +#undef PIS
11191 + printk("\n");
11193 +#endif
11195 +/* Called from dss.c. Note that we don't touch clocks here,
11196 + * but we presume they are on because we got an IRQ. However,
11197 + * an irq handler may turn the clocks off, so we may not have
11198 + * clock later in the function. */
11199 +void dispc_irq_handler(void)
11201 + int i;
11202 + u32 irqstatus = dispc_read_reg(DISPC_IRQSTATUS);
11203 + static int errors;
11204 + u32 handledirqs = 0;
11205 + struct omap_dispc_isr_data *isr_data;
11207 +#ifdef DEBUG
11208 + if (dss_debug)
11209 + print_irq_status(irqstatus);
11210 +#endif
11211 + /* Ack the interrupt. Do it here before clocks are possibly turned
11212 + * off */
11213 + dispc_write_reg(DISPC_IRQSTATUS, irqstatus);
11215 + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
11216 + isr_data = &dispc.registered_isr[i];
11218 + if (!isr_data->isr)
11219 + continue;
11221 + if (isr_data->mask & irqstatus) {
11222 + isr_data->isr(isr_data->arg, irqstatus);
11223 + handledirqs |= isr_data->mask;
11227 + if (irqstatus & ~handledirqs & dispc.irq_error_mask) {
11228 + if (printk_ratelimit()) {
11229 + DSSERR("dispc irq error status %04x\n",
11230 + irqstatus);
11232 + if (errors++ > 100) {
11233 + DSSERR("Excessive DISPC errors\n"
11234 + "Turning off lcd and digit\n");
11235 + _enable_lcd_out(0);
11236 + _enable_digit_out(0);
11242 +int omap_dispc_wait_for_irq_timeout(u32 irqmask, unsigned long timeout)
11244 + void dispc_irq_wait_handler(void *data, u32 mask)
11246 + complete((struct completion *)data);
11249 + int r;
11250 + DECLARE_COMPLETION_ONSTACK(completion);
11252 + r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
11253 + irqmask);
11255 + if (r)
11256 + return r;
11258 + timeout = wait_for_completion_timeout(&completion, timeout);
11260 + omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
11262 + if (timeout == 0)
11263 + return -ETIMEDOUT;
11265 + if (timeout == -ERESTARTSYS)
11266 + return -ERESTARTSYS;
11268 + return 0;
11271 +int omap_dispc_wait_for_irq_interruptible_timeout(u32 irqmask,
11272 + unsigned long timeout)
11274 + void dispc_irq_wait_handler(void *data, u32 mask)
11276 + complete((struct completion *)data);
11279 + int r;
11280 + DECLARE_COMPLETION_ONSTACK(completion);
11282 + r = omap_dispc_register_isr(dispc_irq_wait_handler, &completion,
11283 + irqmask);
11285 + if (r)
11286 + return r;
11288 + timeout = wait_for_completion_interruptible_timeout(&completion,
11289 + timeout);
11291 + omap_dispc_unregister_isr(dispc_irq_wait_handler, &completion, irqmask);
11293 + if (timeout == 0)
11294 + return -ETIMEDOUT;
11296 + if (timeout == -ERESTARTSYS)
11297 + return -ERESTARTSYS;
11299 + return 0;
11302 +#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
11303 +void dispc_fake_vsync_irq(void)
11305 + u32 irqstatus = DISPC_IRQ_VSYNC;
11306 + int i;
11308 + for (i = 0; i < DISPC_MAX_NR_ISRS; i++) {
11309 + struct omap_dispc_isr_data *isr_data;
11310 + isr_data = &dispc.registered_isr[i];
11312 + if (!isr_data->isr)
11313 + continue;
11315 + if (isr_data->mask & irqstatus)
11316 + isr_data->isr(isr_data->arg, irqstatus);
11319 +#endif
11321 +static void _omap_dispc_initialize_irq(void)
11323 + memset(dispc.registered_isr, 0, sizeof(dispc.registered_isr));
11325 + dispc.irq_error_mask = DISPC_IRQ_MASK_ERROR;
11327 + /* there's SYNC_LOST_DIGIT waiting after enabling the DSS,
11328 + * so clear it */
11329 + dispc_write_reg(DISPC_IRQSTATUS, dispc_read_reg(DISPC_IRQSTATUS));
11331 + omap_dispc_set_irqs();
11334 +static void _omap_dispc_initial_config(void)
11336 + u32 l;
11338 + l = dispc_read_reg(DISPC_SYSCONFIG);
11339 + l = FLD_MOD(l, 2, 13, 12); /* MIDLEMODE: smart standby */
11340 + l = FLD_MOD(l, 2, 4, 3); /* SIDLEMODE: smart idle */
11341 + l = FLD_MOD(l, 1, 2, 2); /* ENWAKEUP */
11342 + l = FLD_MOD(l, 1, 0, 0); /* AUTOIDLE */
11343 + dispc_write_reg(DISPC_SYSCONFIG, l);
11345 + /* FUNCGATED */
11346 + REG_FLD_MOD(DISPC_CONFIG, 1, 9, 9);
11348 + /* L3 firewall setting: enable access to OCM RAM */
11349 + if (cpu_is_omap24xx())
11350 + __raw_writel(0x402000b0, IO_ADDRESS(0x680050a0));
11352 + _dispc_setup_color_conv_coef();
11354 + dispc_set_loadmode(OMAP_DSS_LOAD_FRAME_ONLY);
11357 +int dispc_init(void)
11359 + u32 rev;
11361 + spin_lock_init(&dispc.irq_lock);
11363 + dispc.base = ioremap(DISPC_BASE, DISPC_SZ_REGS);
11364 + if (!dispc.base) {
11365 + DSSERR("can't ioremap DISPC\n");
11366 + return -ENOMEM;
11369 + if (cpu_is_omap34xx()) {
11370 + dispc.dpll4_m4_ck = clk_get(NULL, "dpll4_m4_ck");
11371 + if (IS_ERR(dispc.dpll4_m4_ck)) {
11372 + DSSERR("Failed to get dpll4_m4_ck\n");
11373 + return -ENODEV;
11377 + enable_clocks(1);
11379 + _omap_dispc_initial_config();
11381 + _omap_dispc_initialize_irq();
11383 + dispc_save_context();
11385 + rev = dispc_read_reg(DISPC_REVISION);
11386 + printk(KERN_INFO "OMAP DISPC rev %d.%d\n",
11387 + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
11389 + enable_clocks(0);
11391 + return 0;
11394 +void dispc_exit(void)
11396 + if (cpu_is_omap34xx())
11397 + clk_put(dispc.dpll4_m4_ck);
11398 + iounmap(dispc.base);
11401 +int dispc_enable_plane(enum omap_plane plane, bool enable)
11403 + DSSDBG("dispc_enable_plane %d, %d\n", plane, enable);
11405 + enable_clocks(1);
11406 + _dispc_enable_plane(plane, enable);
11407 + enable_clocks(0);
11409 + return 0;
11412 +int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
11413 + u32 paddr, u16 screen_width,
11414 + u16 pos_x, u16 pos_y,
11415 + u16 width, u16 height,
11416 + u16 out_width, u16 out_height,
11417 + enum omap_color_mode color_mode,
11418 + bool ilace,
11419 + u8 rotation, bool mirror)
11421 + int r = 0;
11423 + DSSDBG("dispc_setup_plane %d, ch %d, pa %x, sw %d, %d,%d, %dx%d -> "
11424 + "%dx%d, ilace %d, cmode %x, rot %d, mir %d\n",
11425 + plane, channel_out, paddr, screen_width, pos_x, pos_y,
11426 + width, height,
11427 + out_width, out_height,
11428 + ilace, color_mode,
11429 + rotation, mirror);
11431 + enable_clocks(1);
11433 + r = _dispc_setup_plane(plane, channel_out,
11434 + paddr, screen_width,
11435 + pos_x, pos_y,
11436 + width, height,
11437 + out_width, out_height,
11438 + color_mode, ilace,
11439 + rotation, mirror);
11441 + enable_clocks(0);
11443 + return r;
11446 +static int dispc_is_intersecting(int x1, int y1, int w1, int h1,
11447 + int x2, int y2, int w2, int h2)
11449 + if (x1 >= (x2+w2))
11450 + return 0;
11452 + if ((x1+w1) <= x2)
11453 + return 0;
11455 + if (y1 >= (y2+h2))
11456 + return 0;
11458 + if ((y1+h1) <= y2)
11459 + return 0;
11461 + return 1;
11464 +static int dispc_is_overlay_scaled(struct omap_overlay_info *pi)
11466 + if (pi->width != pi->out_width)
11467 + return 1;
11469 + if (pi->height != pi->out_height)
11470 + return 1;
11472 + return 0;
11475 +/* returns the area that needs updating */
11476 +void dispc_setup_partial_planes(struct omap_display *display,
11477 + u16 *xi, u16 *yi, u16 *wi, u16 *hi)
11479 + struct omap_overlay_manager *mgr;
11480 + int i;
11482 + int x, y, w, h;
11484 + x = *xi;
11485 + y = *yi;
11486 + w = *wi;
11487 + h = *hi;
11489 + DSSDBG("dispc_setup_partial_planes %d,%d %dx%d\n",
11490 + *xi, *yi, *wi, *hi);
11493 + mgr = display->manager;
11495 + if (!mgr) {
11496 + DSSDBG("no manager\n");
11497 + return;
11500 + for (i = 0; i < mgr->num_overlays; i++) {
11501 + struct omap_overlay *ovl;
11502 + struct omap_overlay_info *pi;
11503 + ovl = mgr->overlays[i];
11505 + if (ovl->manager != mgr)
11506 + continue;
11508 + if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0)
11509 + continue;
11511 + pi = &ovl->info;
11513 + if (!pi->enabled)
11514 + continue;
11515 + /*
11516 + * If the plane is intersecting and scaled, we
11517 + * enlarge the update region to accomodate the
11518 + * whole area
11519 + */
11521 + if (dispc_is_intersecting(x, y, w, h,
11522 + pi->pos_x, pi->pos_y,
11523 + pi->out_width, pi->out_height)) {
11524 + if (dispc_is_overlay_scaled(pi)) {
11526 + int x1, y1, x2, y2;
11528 + if (x > pi->pos_x)
11529 + x1 = pi->pos_x;
11530 + else
11531 + x1 = x;
11533 + if (y > pi->pos_y)
11534 + y1 = pi->pos_y;
11535 + else
11536 + y1 = y;
11538 + if ((x + w) < (pi->pos_x + pi->out_width))
11539 + x2 = pi->pos_x + pi->out_width;
11540 + else
11541 + x2 = x + w;
11543 + if ((y + h) < (pi->pos_y + pi->out_height))
11544 + y2 = pi->pos_y + pi->out_height;
11545 + else
11546 + y2 = y + h;
11548 + x = x1;
11549 + y = y1;
11550 + w = x2 - x1;
11551 + h = y2 - y1;
11553 + DSSDBG("Update area after enlarge due to "
11554 + "scaling %d, %d %dx%d\n",
11555 + x, y, w, h);
11560 + for (i = 0; i < mgr->num_overlays; i++) {
11561 + struct omap_overlay *ovl = mgr->overlays[i];
11562 + struct omap_overlay_info *pi = &ovl->info;
11564 + int px = pi->pos_x;
11565 + int py = pi->pos_y;
11566 + int pw = pi->width;
11567 + int ph = pi->height;
11568 + int pow = pi->out_width;
11569 + int poh = pi->out_height;
11570 + u32 pa = pi->paddr;
11571 + int psw = pi->screen_width;
11572 + int bpp;
11574 + if (ovl->manager != mgr)
11575 + continue;
11577 + /*
11578 + * If plane is not enabled or the update region
11579 + * does not intersect with the plane in question,
11580 + * we really disable the plane from hardware
11581 + */
11583 + if (!pi->enabled ||
11584 + !dispc_is_intersecting(x, y, w, h,
11585 + px, py, pow, poh)) {
11586 + dispc_enable_plane(ovl->id, 0);
11587 + continue;
11590 + switch (pi->color_mode) {
11591 + case OMAP_DSS_COLOR_RGB16:
11592 + case OMAP_DSS_COLOR_ARGB16:
11593 + case OMAP_DSS_COLOR_YUV2:
11594 + case OMAP_DSS_COLOR_UYVY:
11595 + bpp = 16;
11596 + break;
11598 + case OMAP_DSS_COLOR_RGB24P:
11599 + bpp = 24;
11600 + break;
11602 + case OMAP_DSS_COLOR_RGB24U:
11603 + case OMAP_DSS_COLOR_ARGB32:
11604 + case OMAP_DSS_COLOR_RGBA32:
11605 + case OMAP_DSS_COLOR_RGBX32:
11606 + bpp = 32;
11607 + break;
11609 + default:
11610 + BUG();
11611 + return;
11614 + if (x > pi->pos_x) {
11615 + px = 0;
11616 + pw -= (x - pi->pos_x);
11617 + pa += (x - pi->pos_x) * bpp / 8;
11618 + } else {
11619 + px = pi->pos_x - x;
11622 + if (y > pi->pos_y) {
11623 + py = 0;
11624 + ph -= (y - pi->pos_y);
11625 + pa += (y - pi->pos_y) * psw * bpp / 8;
11626 + } else {
11627 + py = pi->pos_y - y;
11630 + if (w < (px+pw))
11631 + pw -= (px+pw) - (w);
11633 + if (h < (py+ph))
11634 + ph -= (py+ph) - (h);
11636 + /* Can't scale the GFX plane */
11637 + if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0 ||
11638 + dispc_is_overlay_scaled(pi) == 0) {
11639 + pow = pw;
11640 + poh = ph;
11643 + DSSDBG("calc plane %d, %x, sw %d, %d,%d, %dx%d -> %dx%d\n",
11644 + ovl->id, pa, psw, px, py, pw, ph, pow, poh);
11646 + dispc_setup_plane(ovl->id, mgr->id,
11647 + pa, psw,
11648 + px, py,
11649 + pw, ph,
11650 + pow, poh,
11651 + pi->color_mode, 0,
11652 + pi->rotation, // XXX rotation probably wrong
11653 + pi->mirror);
11655 + dispc_enable_plane(ovl->id, 1);
11658 + *xi = x;
11659 + *yi = y;
11660 + *wi = w;
11661 + *hi = h;
11665 diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
11666 new file mode 100644
11667 index 0000000..1a55010
11668 --- /dev/null
11669 +++ b/drivers/video/omap2/dss/display.c
11670 @@ -0,0 +1,687 @@
11672 + * linux/drivers/video/omap2/dss/display.c
11674 + * Copyright (C) 2009 Nokia Corporation
11675 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
11677 + * Some code and ideas taken from drivers/video/omap/ driver
11678 + * by Imre Deak.
11680 + * This program is free software; you can redistribute it and/or modify it
11681 + * under the terms of the GNU General Public License version 2 as published by
11682 + * the Free Software Foundation.
11684 + * This program is distributed in the hope that it will be useful, but WITHOUT
11685 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11686 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
11687 + * more details.
11689 + * You should have received a copy of the GNU General Public License along with
11690 + * this program. If not, see <http://www.gnu.org/licenses/>.
11691 + */
11693 +#define DSS_SUBSYS_NAME "DISPLAY"
11695 +#include <linux/kernel.h>
11696 +#include <linux/module.h>
11697 +#include <linux/jiffies.h>
11698 +#include <linux/list.h>
11699 +#include <linux/platform_device.h>
11701 +#include <mach/display.h>
11702 +#include "dss.h"
11704 +static int num_displays;
11705 +static LIST_HEAD(display_list);
11707 +static ssize_t display_name_show(struct omap_display *display, char *buf)
11709 + return snprintf(buf, PAGE_SIZE, "%s\n", display->name);
11712 +static ssize_t display_enabled_show(struct omap_display *display, char *buf)
11714 + bool enabled = display->state != OMAP_DSS_DISPLAY_DISABLED;
11716 + return snprintf(buf, PAGE_SIZE, "%d\n", enabled);
11719 +static ssize_t display_enabled_store(struct omap_display *display,
11720 + const char *buf, size_t size)
11722 + bool enabled, r;
11724 + enabled = simple_strtoul(buf, NULL, 10);
11726 + if (enabled != (display->state != OMAP_DSS_DISPLAY_DISABLED)) {
11727 + if (enabled) {
11728 + r = display->enable(display);
11729 + if (r)
11730 + return r;
11731 + } else {
11732 + display->disable(display);
11736 + return size;
11739 +static ssize_t display_upd_mode_show(struct omap_display *display, char *buf)
11741 + enum omap_dss_update_mode mode = OMAP_DSS_UPDATE_AUTO;
11742 + if (display->get_update_mode)
11743 + mode = display->get_update_mode(display);
11744 + return snprintf(buf, PAGE_SIZE, "%d\n", mode);
11747 +static ssize_t display_upd_mode_store(struct omap_display *display,
11748 + const char *buf, size_t size)
11750 + int val, r;
11751 + enum omap_dss_update_mode mode;
11753 + val = simple_strtoul(buf, NULL, 10);
11755 + switch (val) {
11756 + case OMAP_DSS_UPDATE_DISABLED:
11757 + case OMAP_DSS_UPDATE_AUTO:
11758 + case OMAP_DSS_UPDATE_MANUAL:
11759 + mode = (enum omap_dss_update_mode)val;
11760 + break;
11761 + default:
11762 + return -EINVAL;
11765 + if ((r = display->set_update_mode(display, mode)))
11766 + return r;
11768 + return size;
11771 +static ssize_t display_tear_show(struct omap_display *display, char *buf)
11773 + return snprintf(buf, PAGE_SIZE, "%d\n",
11774 + display->get_te ? display->get_te(display) : 0);
11777 +static ssize_t display_tear_store(struct omap_display *display,
11778 + const char *buf, size_t size)
11780 + unsigned long te;
11781 + int r;
11783 + if (!display->enable_te || !display->get_te)
11784 + return -ENOENT;
11786 + te = simple_strtoul(buf, NULL, 0);
11788 + if ((r = display->enable_te(display, te)))
11789 + return r;
11791 + return size;
11794 +static ssize_t display_timings_show(struct omap_display *display, char *buf)
11796 + struct omap_video_timings t;
11798 + if (!display->get_timings)
11799 + return -ENOENT;
11801 + display->get_timings(display, &t);
11803 + return snprintf(buf, PAGE_SIZE, "%u,%u/%u/%u/%u,%u/%u/%u/%u\n",
11804 + t.pixel_clock,
11805 + t.x_res, t.hsw, t.hfp, t.hbp,
11806 + t.y_res, t.vsw, t.vfp, t.vbp);
11809 +static ssize_t display_timings_store(struct omap_display *display,
11810 + const char *buf, size_t size)
11812 + struct omap_video_timings t;
11813 + int r;
11815 + if (!display->set_timings || !display->check_timings)
11816 + return -ENOENT;
11818 + if (strncmp("pal", buf, 3) == 0) {
11819 + t = omap_dss_pal_timings;
11820 + } else if (strncmp("ntsc", buf, 4) == 0) {
11821 + t = omap_dss_ntsc_timings;
11822 + } else if (sscanf(buf, "%u,%hu/%hu/%hu/%hu,%hu/%hu/%hu/%hu",
11823 + &t.pixel_clock,
11824 + &t.x_res, &t.hsw, &t.hfp, &t.hbp,
11825 + &t.y_res, &t.vsw, &t.vfp, &t.vbp) != 9)
11826 + return -EINVAL;
11828 + if ((r = display->check_timings(display, &t)))
11829 + return r;
11831 + display->set_timings(display, &t);
11833 + return size;
11836 +static ssize_t display_rotate_show(struct omap_display *display, char *buf)
11838 + int rotate;
11839 + if (!display->get_rotate)
11840 + return -ENOENT;
11841 + rotate = display->get_rotate(display);
11842 + return snprintf(buf, PAGE_SIZE, "%u\n", rotate);
11845 +static ssize_t display_rotate_store(struct omap_display *display,
11846 + const char *buf, size_t size)
11848 + unsigned long rot;
11849 + int r;
11851 + if (!display->set_rotate || !display->get_rotate)
11852 + return -ENOENT;
11854 + rot = simple_strtoul(buf, NULL, 0);
11856 + if ((r = display->set_rotate(display, rot)))
11857 + return r;
11859 + return size;
11862 +static ssize_t display_mirror_show(struct omap_display *display, char *buf)
11864 + int mirror;
11865 + if (!display->get_mirror)
11866 + return -ENOENT;
11867 + mirror = display->get_mirror(display);
11868 + return snprintf(buf, PAGE_SIZE, "%u\n", mirror);
11871 +static ssize_t display_mirror_store(struct omap_display *display,
11872 + const char *buf, size_t size)
11874 + unsigned long mirror;
11875 + int r;
11877 + if (!display->set_mirror || !display->get_mirror)
11878 + return -ENOENT;
11880 + mirror = simple_strtoul(buf, NULL, 0);
11882 + if ((r = display->set_mirror(display, mirror)))
11883 + return r;
11885 + return size;
11888 +static ssize_t display_panel_name_show(struct omap_display *display, char *buf)
11890 + return snprintf(buf, PAGE_SIZE, "%s\n",
11891 + display->panel ? display->panel->name : "");
11894 +static ssize_t display_ctrl_name_show(struct omap_display *display, char *buf)
11896 + return snprintf(buf, PAGE_SIZE, "%s\n",
11897 + display->ctrl ? display->ctrl->name : "");
11900 +struct display_attribute {
11901 + struct attribute attr;
11902 + ssize_t (*show)(struct omap_display *, char *);
11903 + ssize_t (*store)(struct omap_display *, const char *, size_t);
11906 +#define DISPLAY_ATTR(_name, _mode, _show, _store) \
11907 + struct display_attribute display_attr_##_name = \
11908 + __ATTR(_name, _mode, _show, _store)
11910 +static DISPLAY_ATTR(name, S_IRUGO, display_name_show, NULL);
11911 +static DISPLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
11912 + display_enabled_show, display_enabled_store);
11913 +static DISPLAY_ATTR(update_mode, S_IRUGO|S_IWUSR,
11914 + display_upd_mode_show, display_upd_mode_store);
11915 +static DISPLAY_ATTR(tear_elim, S_IRUGO|S_IWUSR,
11916 + display_tear_show, display_tear_store);
11917 +static DISPLAY_ATTR(timings, S_IRUGO|S_IWUSR,
11918 + display_timings_show, display_timings_store);
11919 +static DISPLAY_ATTR(rotate, S_IRUGO|S_IWUSR,
11920 + display_rotate_show, display_rotate_store);
11921 +static DISPLAY_ATTR(mirror, S_IRUGO|S_IWUSR,
11922 + display_mirror_show, display_mirror_store);
11923 +static DISPLAY_ATTR(panel_name, S_IRUGO, display_panel_name_show, NULL);
11924 +static DISPLAY_ATTR(ctrl_name, S_IRUGO, display_ctrl_name_show, NULL);
11926 +static struct attribute *display_sysfs_attrs[] = {
11927 + &display_attr_name.attr,
11928 + &display_attr_enabled.attr,
11929 + &display_attr_update_mode.attr,
11930 + &display_attr_tear_elim.attr,
11931 + &display_attr_timings.attr,
11932 + &display_attr_rotate.attr,
11933 + &display_attr_mirror.attr,
11934 + &display_attr_panel_name.attr,
11935 + &display_attr_ctrl_name.attr,
11936 + NULL
11939 +static ssize_t display_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
11941 + struct omap_display *display;
11942 + struct display_attribute *display_attr;
11944 + display = container_of(kobj, struct omap_display, kobj);
11945 + display_attr = container_of(attr, struct display_attribute, attr);
11947 + if (!display_attr->show)
11948 + return -ENOENT;
11950 + return display_attr->show(display, buf);
11953 +static ssize_t display_attr_store(struct kobject *kobj, struct attribute *attr,
11954 + const char *buf, size_t size)
11956 + struct omap_display *display;
11957 + struct display_attribute *display_attr;
11959 + display = container_of(kobj, struct omap_display, kobj);
11960 + display_attr = container_of(attr, struct display_attribute, attr);
11962 + if (!display_attr->store)
11963 + return -ENOENT;
11965 + return display_attr->store(display, buf, size);
11968 +static struct sysfs_ops display_sysfs_ops = {
11969 + .show = display_attr_show,
11970 + .store = display_attr_store,
11973 +static struct kobj_type display_ktype = {
11974 + .sysfs_ops = &display_sysfs_ops,
11975 + .default_attrs = display_sysfs_attrs,
11978 +static void default_get_resolution(struct omap_display *display,
11979 + u16 *xres, u16 *yres)
11981 + *xres = display->panel->timings.x_res;
11982 + *yres = display->panel->timings.y_res;
11985 +static void default_configure_overlay(struct omap_overlay *ovl)
11987 + unsigned low, high, size;
11988 + enum omap_burst_size burst;
11989 + enum omap_plane plane = ovl->id;
11991 + burst = OMAP_DSS_BURST_16x32;
11992 + size = 16 * 32 / 8;
11994 + dispc_set_burst_size(plane, burst);
11996 + high = dispc_get_plane_fifo_size(plane) - 1;
11997 + low = dispc_get_plane_fifo_size(plane) - size;
11999 + dispc_setup_plane_fifo(plane, low, high);
12002 +static int default_wait_vsync(struct omap_display *display)
12004 + unsigned long timeout = msecs_to_jiffies(500);
12005 + u32 irq;
12007 + if (display->type == OMAP_DISPLAY_TYPE_VENC)
12008 + irq = DISPC_IRQ_EVSYNC_ODD;
12009 + else
12010 + irq = DISPC_IRQ_VSYNC;
12012 + return omap_dispc_wait_for_irq_interruptible_timeout(irq, timeout);
12015 +static int default_get_recommended_bpp(struct omap_display *display)
12017 + if (display->panel->recommended_bpp)
12018 + return display->panel->recommended_bpp;
12020 + switch (display->type) {
12021 + case OMAP_DISPLAY_TYPE_DPI:
12022 + if (display->hw_config.u.dpi.data_lines == 24)
12023 + return 24;
12024 + else
12025 + return 16;
12027 + case OMAP_DISPLAY_TYPE_DBI:
12028 + case OMAP_DISPLAY_TYPE_DSI:
12029 + if (display->ctrl->pixel_size == 24)
12030 + return 24;
12031 + else
12032 + return 16;
12033 + case OMAP_DISPLAY_TYPE_VENC:
12034 + case OMAP_DISPLAY_TYPE_SDI:
12035 + return 24;
12036 + return 24;
12037 + default:
12038 + BUG();
12042 +void dss_init_displays(struct platform_device *pdev)
12044 + struct omap_dss_board_info *pdata = pdev->dev.platform_data;
12045 + int i, r;
12047 + INIT_LIST_HEAD(&display_list);
12049 + num_displays = 0;
12051 + for (i = 0; i < pdata->num_displays; ++i) {
12052 + struct omap_display *display;
12054 + switch (pdata->displays[i]->type) {
12055 + case OMAP_DISPLAY_TYPE_DPI:
12056 +#ifdef CONFIG_OMAP2_DSS_RFBI
12057 + case OMAP_DISPLAY_TYPE_DBI:
12058 +#endif
12059 +#ifdef CONFIG_OMAP2_DSS_SDI
12060 + case OMAP_DISPLAY_TYPE_SDI:
12061 +#endif
12062 +#ifdef CONFIG_OMAP2_DSS_DSI
12063 + case OMAP_DISPLAY_TYPE_DSI:
12064 +#endif
12065 +#ifdef CONFIG_OMAP2_DSS_VENC
12066 + case OMAP_DISPLAY_TYPE_VENC:
12067 +#endif
12068 + break;
12069 + default:
12070 + DSSERR("Support for display '%s' not compiled in.\n",
12071 + pdata->displays[i]->name);
12072 + continue;
12075 + display = kzalloc(sizeof(*display), GFP_KERNEL);
12077 + /*atomic_set(&display->ref_count, 0);*/
12078 + display->ref_count = 0;
12080 + display->hw_config = *pdata->displays[i];
12081 + display->type = pdata->displays[i]->type;
12082 + display->name = pdata->displays[i]->name;
12084 + display->get_resolution = default_get_resolution;
12085 + display->get_recommended_bpp = default_get_recommended_bpp;
12086 + display->configure_overlay = default_configure_overlay;
12087 + display->wait_vsync = default_wait_vsync;
12089 + switch (display->type) {
12090 + case OMAP_DISPLAY_TYPE_DPI:
12091 + dpi_init_display(display);
12092 + break;
12093 +#ifdef CONFIG_OMAP2_DSS_RFBI
12094 + case OMAP_DISPLAY_TYPE_DBI:
12095 + rfbi_init_display(display);
12096 + break;
12097 +#endif
12098 +#ifdef CONFIG_OMAP2_DSS_VENC
12099 + case OMAP_DISPLAY_TYPE_VENC:
12100 + venc_init_display(display);
12101 + break;
12102 +#endif
12103 +#ifdef CONFIG_OMAP2_DSS_SDI
12104 + case OMAP_DISPLAY_TYPE_SDI:
12105 + sdi_init_display(display);
12106 + break;
12107 +#endif
12108 +#ifdef CONFIG_OMAP2_DSS_DSI
12109 + case OMAP_DISPLAY_TYPE_DSI:
12110 + dsi_init_display(display);
12111 + break;
12112 +#endif
12113 + default:
12114 + BUG();
12117 + r = kobject_init_and_add(&display->kobj, &display_ktype,
12118 + &pdev->dev.kobj, "display%d", num_displays);
12120 + if (r) {
12121 + DSSERR("failed to create sysfs file\n");
12122 + continue;
12125 + num_displays++;
12127 + list_add_tail(&display->list, &display_list);
12131 +void dss_uninit_displays(struct platform_device *pdev)
12133 + struct omap_display *display;
12135 + while (!list_empty(&display_list)) {
12136 + display = list_first_entry(&display_list,
12137 + struct omap_display, list);
12138 + list_del(&display->list);
12139 + kobject_del(&display->kobj);
12140 + kobject_put(&display->kobj);
12141 + kfree(display);
12144 + num_displays = 0;
12147 +int dss_suspend_all_displays(void)
12149 + int r;
12150 + struct omap_display *display;
12152 + list_for_each_entry(display, &display_list, list) {
12153 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE) {
12154 + display->activate_after_resume = 0;
12155 + continue;
12158 + if (!display->suspend) {
12159 + DSSERR("display '%s' doesn't implement suspend\n",
12160 + display->name);
12161 + r = -ENOSYS;
12162 + goto err;
12165 + r = display->suspend(display);
12167 + if (r)
12168 + goto err;
12170 + display->activate_after_resume = 1;
12173 + return 0;
12174 +err:
12175 + /* resume all displays that were suspended */
12176 + dss_resume_all_displays();
12177 + return r;
12180 +int dss_resume_all_displays(void)
12182 + int r;
12183 + struct omap_display *display;
12185 + list_for_each_entry(display, &display_list, list) {
12186 + if (display->activate_after_resume && display->resume) {
12187 + r = display->resume(display);
12188 + if (r)
12189 + return r;
12192 + display->activate_after_resume = 0;
12195 + return 0;
12198 +int omap_dss_get_num_displays(void)
12200 + return num_displays;
12202 +EXPORT_SYMBOL(omap_dss_get_num_displays);
12204 +struct omap_display *dss_get_display(int no)
12206 + int i = 0;
12207 + struct omap_display *display;
12209 + list_for_each_entry(display, &display_list, list) {
12210 + if (i++ == no)
12211 + return display;
12214 + return NULL;
12217 +struct omap_display *omap_dss_get_display(int no)
12219 + struct omap_display *display;
12221 + display = dss_get_display(no);
12223 + if (!display)
12224 + return NULL;
12226 + switch (display->type) {
12227 + case OMAP_DISPLAY_TYPE_VENC:
12228 + break;
12230 + case OMAP_DISPLAY_TYPE_DPI:
12231 + case OMAP_DISPLAY_TYPE_SDI:
12232 + if (display->panel == NULL)
12233 + return NULL;
12234 + break;
12236 + case OMAP_DISPLAY_TYPE_DBI:
12237 + case OMAP_DISPLAY_TYPE_DSI:
12238 + if (display->panel == NULL || display->ctrl == NULL)
12239 + return NULL;
12240 + break;
12242 + default:
12243 + return NULL;
12246 + if (display->ctrl) {
12247 + if (!try_module_get(display->ctrl->owner))
12248 + goto err0;
12250 + if (display->ctrl->init)
12251 + if (display->ctrl->init(display) != 0)
12252 + goto err1;
12255 + if (display->panel) {
12256 + if (!try_module_get(display->panel->owner))
12257 + goto err2;
12259 + if (display->panel->init)
12260 + if (display->panel->init(display) != 0)
12261 + goto err3;
12264 + display->ref_count++;
12265 + /*
12266 + if (atomic_cmpxchg(&display->ref_count, 0, 1) != 0)
12267 + return 0;
12270 + return display;
12271 +err3:
12272 + if (display->panel)
12273 + module_put(display->panel->owner);
12274 +err2:
12275 + if (display->ctrl && display->ctrl->cleanup)
12276 + display->ctrl->cleanup(display);
12277 +err1:
12278 + if (display->ctrl)
12279 + module_put(display->ctrl->owner);
12280 +err0:
12281 + return NULL;
12283 +EXPORT_SYMBOL(omap_dss_get_display);
12285 +void omap_dss_put_display(struct omap_display *display)
12287 + if (--display->ref_count > 0)
12288 + return;
12290 + if (atomic_cmpxchg(&display->ref_count, 1, 0) != 1)
12291 + return;
12293 + if (display->ctrl) {
12294 + if (display->ctrl->cleanup)
12295 + display->ctrl->cleanup(display);
12296 + module_put(display->ctrl->owner);
12299 + if (display->panel) {
12300 + if (display->panel->cleanup)
12301 + display->panel->cleanup(display);
12302 + module_put(display->panel->owner);
12305 +EXPORT_SYMBOL(omap_dss_put_display);
12307 +void omap_dss_register_ctrl(struct omap_ctrl *ctrl)
12309 + struct omap_display *display;
12311 + list_for_each_entry(display, &display_list, list) {
12312 + if (display->hw_config.ctrl_name &&
12313 + strcmp(display->hw_config.ctrl_name, ctrl->name) == 0) {
12314 + display->ctrl = ctrl;
12315 + DSSDBG("ctrl '%s' registered\n", ctrl->name);
12319 +EXPORT_SYMBOL(omap_dss_register_ctrl);
12321 +void omap_dss_register_panel(struct omap_panel *panel)
12323 + struct omap_display *display;
12325 + list_for_each_entry(display, &display_list, list) {
12326 + if (display->hw_config.panel_name &&
12327 + strcmp(display->hw_config.panel_name, panel->name) == 0) {
12328 + display->panel = panel;
12329 + DSSDBG("panel '%s' registered\n", panel->name);
12333 +EXPORT_SYMBOL(omap_dss_register_panel);
12335 +void omap_dss_unregister_ctrl(struct omap_ctrl *ctrl)
12337 + struct omap_display *display;
12339 + list_for_each_entry(display, &display_list, list) {
12340 + if (display->hw_config.ctrl_name &&
12341 + strcmp(display->hw_config.ctrl_name, ctrl->name) == 0)
12342 + display->ctrl = NULL;
12345 +EXPORT_SYMBOL(omap_dss_unregister_ctrl);
12347 +void omap_dss_unregister_panel(struct omap_panel *panel)
12349 + struct omap_display *display;
12351 + list_for_each_entry(display, &display_list, list) {
12352 + if (display->hw_config.panel_name &&
12353 + strcmp(display->hw_config.panel_name, panel->name) == 0)
12354 + display->panel = NULL;
12357 +EXPORT_SYMBOL(omap_dss_unregister_panel);
12358 diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/omap2/dss/dpi.c
12359 new file mode 100644
12360 index 0000000..b41b07e
12361 --- /dev/null
12362 +++ b/drivers/video/omap2/dss/dpi.c
12363 @@ -0,0 +1,379 @@
12365 + * linux/drivers/video/omap2/dss/dpi.c
12367 + * Copyright (C) 2009 Nokia Corporation
12368 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
12370 + * Some code and ideas taken from drivers/video/omap/ driver
12371 + * by Imre Deak.
12373 + * This program is free software; you can redistribute it and/or modify it
12374 + * under the terms of the GNU General Public License version 2 as published by
12375 + * the Free Software Foundation.
12377 + * This program is distributed in the hope that it will be useful, but WITHOUT
12378 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12379 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12380 + * more details.
12382 + * You should have received a copy of the GNU General Public License along with
12383 + * this program. If not, see <http://www.gnu.org/licenses/>.
12384 + */
12386 +#include <linux/kernel.h>
12387 +#include <linux/clk.h>
12388 +#include <linux/delay.h>
12389 +#include <linux/errno.h>
12391 +#include <mach/board.h>
12392 +#include <mach/display.h>
12393 +#include "dss.h"
12396 +static struct {
12397 + int update_enabled;
12398 +} dpi;
12400 +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
12401 +static int dpi_set_dsi_clk(bool is_tft, unsigned long pck_req,
12402 + unsigned long *fck, int *lck_div, int *pck_div)
12404 + struct dsi_clock_info cinfo;
12405 + int r;
12407 + r = dsi_pll_calc_pck(is_tft, pck_req, &cinfo);
12408 + if (r)
12409 + return r;
12411 + r = dsi_pll_program(&cinfo);
12412 + if (r)
12413 + return r;
12415 + dss_select_clk_source(0, 1);
12417 + dispc_set_lcd_divisor(cinfo.lck_div, cinfo.pck_div);
12419 + *fck = cinfo.dsi1_pll_fclk;
12420 + *lck_div = cinfo.lck_div;
12421 + *pck_div = cinfo.pck_div;
12423 + return 0;
12425 +#else
12426 +static int dpi_set_dispc_clk(bool is_tft, unsigned long pck_req,
12427 + unsigned long *fck, int *lck_div, int *pck_div)
12429 + struct dispc_clock_info cinfo;
12430 + int r;
12432 + r = dispc_calc_clock_div(is_tft, pck_req, &cinfo);
12433 + if (r)
12434 + return r;
12436 + r = dispc_set_clock_div(&cinfo);
12437 + if (r)
12438 + return r;
12440 + *fck = cinfo.fck;
12441 + *lck_div = cinfo.lck_div;
12442 + *pck_div = cinfo.pck_div;
12444 + return 0;
12446 +#endif
12448 +static int dpi_set_mode(struct omap_display *display)
12450 + struct omap_panel *panel = display->panel;
12451 + int lck_div, pck_div;
12452 + unsigned long fck;
12453 + unsigned long pck;
12454 + bool is_tft;
12455 + int r = 0;
12457 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
12459 + dispc_set_pol_freq(panel);
12461 + is_tft = (display->panel->config & OMAP_DSS_LCD_TFT) != 0;
12463 +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
12464 + r = dpi_set_dsi_clk(is_tft, panel->timings.pixel_clock * 1000,
12465 + &fck, &lck_div, &pck_div);
12466 +#else
12467 + r = dpi_set_dispc_clk(is_tft, panel->timings.pixel_clock * 1000,
12468 + &fck, &lck_div, &pck_div);
12469 +#endif
12470 + if (r)
12471 + goto err0;
12473 + pck = fck / lck_div / pck_div / 1000;
12475 + if (pck != panel->timings.pixel_clock) {
12476 + DSSWARN("Could not find exact pixel clock. "
12477 + "Requested %d kHz, got %lu kHz\n",
12478 + panel->timings.pixel_clock, pck);
12480 + panel->timings.pixel_clock = pck;
12483 + dispc_set_lcd_timings(&panel->timings);
12485 +err0:
12486 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
12487 + return r;
12490 +static int dpi_basic_init(struct omap_display *display)
12492 + bool is_tft;
12494 + is_tft = (display->panel->config & OMAP_DSS_LCD_TFT) != 0;
12496 + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS);
12497 + dispc_set_lcd_display_type(is_tft ? OMAP_DSS_LCD_DISPLAY_TFT :
12498 + OMAP_DSS_LCD_DISPLAY_STN);
12499 + dispc_set_tft_data_lines(display->hw_config.u.dpi.data_lines);
12501 + return 0;
12504 +static int dpi_display_enable(struct omap_display *display)
12506 + struct omap_panel *panel = display->panel;
12507 + int r;
12509 + if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
12510 + DSSERR("display already enabled\n");
12511 + return -EINVAL;
12514 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
12516 + r = dpi_basic_init(display);
12517 + if (r)
12518 + goto err0;
12520 +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
12521 + dss_clk_enable(DSS_CLK_FCK2);
12522 + r = dsi_pll_init(0, 1);
12523 + if (r)
12524 + goto err1;
12525 +#endif
12526 + r = dpi_set_mode(display);
12527 + if (r)
12528 + goto err2;
12530 + mdelay(2);
12532 + dispc_enable_lcd_out(1);
12534 + r = panel->enable(display);
12535 + if (r)
12536 + goto err3;
12538 + display->state = OMAP_DSS_DISPLAY_ACTIVE;
12540 + return 0;
12542 +err3:
12543 + dispc_enable_lcd_out(0);
12544 +err2:
12545 +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
12546 + dsi_pll_uninit();
12547 +err1:
12548 + dss_clk_disable(DSS_CLK_FCK2);
12549 +#endif
12550 +err0:
12551 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
12552 + return r;
12555 +static int dpi_display_resume(struct omap_display *display);
12557 +static void dpi_display_disable(struct omap_display *display)
12559 + if (display->state == OMAP_DSS_DISPLAY_DISABLED)
12560 + return;
12562 + if (display->state == OMAP_DSS_DISPLAY_SUSPENDED)
12563 + dpi_display_resume(display);
12565 + display->panel->disable(display);
12567 + dispc_enable_lcd_out(0);
12569 +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
12570 + dss_select_clk_source(0, 0);
12571 + dsi_pll_uninit();
12572 + dss_clk_disable(DSS_CLK_FCK2);
12573 +#endif
12575 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
12577 + display->state = OMAP_DSS_DISPLAY_DISABLED;
12580 +static int dpi_display_suspend(struct omap_display *display)
12582 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
12583 + return -EINVAL;
12585 + DSSDBG("dpi_display_suspend\n");
12587 + if (display->panel->suspend)
12588 + display->panel->suspend(display);
12590 + dispc_enable_lcd_out(0);
12592 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
12594 + display->state = OMAP_DSS_DISPLAY_SUSPENDED;
12596 + return 0;
12599 +static int dpi_display_resume(struct omap_display *display)
12601 + if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
12602 + return -EINVAL;
12604 + DSSDBG("dpi_display_resume\n");
12606 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
12608 + dispc_enable_lcd_out(1);
12610 + if (display->panel->resume)
12611 + display->panel->resume(display);
12613 + display->state = OMAP_DSS_DISPLAY_ACTIVE;
12615 + return 0;
12618 +static void dpi_set_timings(struct omap_display *display,
12619 + struct omap_video_timings *timings)
12621 + DSSDBG("dpi_set_timings\n");
12622 + display->panel->timings = *timings;
12623 + if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
12624 + dpi_set_mode(display);
12625 + dispc_go(OMAP_DSS_CHANNEL_LCD);
12629 +static int dpi_check_timings(struct omap_display *display,
12630 + struct omap_video_timings *timings)
12632 + bool is_tft;
12633 + int r;
12634 + int lck_div, pck_div;
12635 + unsigned long fck;
12636 + unsigned long pck;
12638 + if (timings->hsw < 1 || timings->hsw > 64 ||
12639 + timings->hfp < 1 || timings->hfp > 256 ||
12640 + timings->hbp < 1 || timings->hbp > 256) {
12641 + return -EINVAL;
12644 + if (timings->vsw < 1 || timings->vsw > 64 ||
12645 + timings->vfp > 256 || timings->vbp > 256) {
12646 + return -EINVAL;
12649 + if (timings->pixel_clock == 0)
12650 + return -EINVAL;
12652 + is_tft = (display->panel->config & OMAP_DSS_LCD_TFT) != 0;
12654 +#ifdef CONFIG_OMAP2_DSS_USE_DSI_PLL
12656 + struct dsi_clock_info cinfo;
12657 + r = dsi_pll_calc_pck(is_tft, timings->pixel_clock * 1000,
12658 + &cinfo);
12660 + if (r)
12661 + return r;
12663 + fck = cinfo.dsi1_pll_fclk;
12664 + lck_div = cinfo.lck_div;
12665 + pck_div = cinfo.pck_div;
12667 +#else
12669 + struct dispc_clock_info cinfo;
12670 + r = dispc_calc_clock_div(is_tft, timings->pixel_clock * 1000,
12671 + &cinfo);
12673 + if (r)
12674 + return r;
12676 + fck = cinfo.fck;
12677 + lck_div = cinfo.lck_div;
12678 + pck_div = cinfo.pck_div;
12680 +#endif
12682 + pck = fck / lck_div / pck_div / 1000;
12684 + timings->pixel_clock = pck;
12686 + return 0;
12689 +static void dpi_get_timings(struct omap_display *display,
12690 + struct omap_video_timings *timings)
12692 + *timings = display->panel->timings;
12695 +static int dpi_display_set_update_mode(struct omap_display *display,
12696 + enum omap_dss_update_mode mode)
12698 + if (mode == OMAP_DSS_UPDATE_MANUAL)
12699 + return -EINVAL;
12701 + if (mode == OMAP_DSS_UPDATE_DISABLED) {
12702 + dispc_enable_lcd_out(0);
12703 + dpi.update_enabled = 0;
12704 + } else {
12705 + dispc_enable_lcd_out(1);
12706 + dpi.update_enabled = 1;
12709 + return 0;
12712 +static enum omap_dss_update_mode dpi_display_get_update_mode(
12713 + struct omap_display *display)
12715 + return dpi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
12716 + OMAP_DSS_UPDATE_DISABLED;
12719 +void dpi_init_display(struct omap_display *display)
12721 + DSSDBG("DPI init_display\n");
12723 + display->enable = dpi_display_enable;
12724 + display->disable = dpi_display_disable;
12725 + display->suspend = dpi_display_suspend;
12726 + display->resume = dpi_display_resume;
12727 + display->set_timings = dpi_set_timings;
12728 + display->check_timings = dpi_check_timings;
12729 + display->get_timings = dpi_get_timings;
12730 + display->set_update_mode = dpi_display_set_update_mode;
12731 + display->get_update_mode = dpi_display_get_update_mode;
12734 +int dpi_init(void)
12736 + return 0;
12739 +void dpi_exit(void)
12743 diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/omap2/dss/dsi.c
12744 new file mode 100644
12745 index 0000000..ea5a58e
12746 --- /dev/null
12747 +++ b/drivers/video/omap2/dss/dsi.c
12748 @@ -0,0 +1,3693 @@
12750 + * linux/drivers/video/omap2/dss/dsi.c
12752 + * Copyright (C) 2009 Nokia Corporation
12753 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
12755 + * This program is free software; you can redistribute it and/or modify it
12756 + * under the terms of the GNU General Public License version 2 as published by
12757 + * the Free Software Foundation.
12759 + * This program is distributed in the hope that it will be useful, but WITHOUT
12760 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12761 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12762 + * more details.
12764 + * You should have received a copy of the GNU General Public License along with
12765 + * this program. If not, see <http://www.gnu.org/licenses/>.
12766 + */
12768 +#define DSS_SUBSYS_NAME "DSI"
12770 +#include <linux/kernel.h>
12771 +#include <linux/io.h>
12772 +#include <linux/clk.h>
12773 +#include <linux/device.h>
12774 +#include <linux/err.h>
12775 +#include <linux/interrupt.h>
12776 +#include <linux/delay.h>
12777 +#include <linux/workqueue.h>
12778 +#include <linux/mutex.h>
12779 +#include <linux/seq_file.h>
12780 +#include <linux/kfifo.h>
12782 +#include <mach/board.h>
12783 +#include <mach/display.h>
12784 +#include <mach/clock.h>
12786 +#include "dss.h"
12788 +/*#define VERBOSE_IRQ*/
12790 +#define DSI_BASE 0x4804FC00
12792 +struct dsi_reg { u16 idx; };
12794 +#define DSI_REG(idx) ((const struct dsi_reg) { idx })
12796 +#define DSI_SZ_REGS SZ_1K
12797 +/* DSI Protocol Engine */
12799 +#define DSI_REVISION DSI_REG(0x0000)
12800 +#define DSI_SYSCONFIG DSI_REG(0x0010)
12801 +#define DSI_SYSSTATUS DSI_REG(0x0014)
12802 +#define DSI_IRQSTATUS DSI_REG(0x0018)
12803 +#define DSI_IRQENABLE DSI_REG(0x001C)
12804 +#define DSI_CTRL DSI_REG(0x0040)
12805 +#define DSI_COMPLEXIO_CFG1 DSI_REG(0x0048)
12806 +#define DSI_COMPLEXIO_IRQ_STATUS DSI_REG(0x004C)
12807 +#define DSI_COMPLEXIO_IRQ_ENABLE DSI_REG(0x0050)
12808 +#define DSI_CLK_CTRL DSI_REG(0x0054)
12809 +#define DSI_TIMING1 DSI_REG(0x0058)
12810 +#define DSI_TIMING2 DSI_REG(0x005C)
12811 +#define DSI_VM_TIMING1 DSI_REG(0x0060)
12812 +#define DSI_VM_TIMING2 DSI_REG(0x0064)
12813 +#define DSI_VM_TIMING3 DSI_REG(0x0068)
12814 +#define DSI_CLK_TIMING DSI_REG(0x006C)
12815 +#define DSI_TX_FIFO_VC_SIZE DSI_REG(0x0070)
12816 +#define DSI_RX_FIFO_VC_SIZE DSI_REG(0x0074)
12817 +#define DSI_COMPLEXIO_CFG2 DSI_REG(0x0078)
12818 +#define DSI_RX_FIFO_VC_FULLNESS DSI_REG(0x007C)
12819 +#define DSI_VM_TIMING4 DSI_REG(0x0080)
12820 +#define DSI_TX_FIFO_VC_EMPTINESS DSI_REG(0x0084)
12821 +#define DSI_VM_TIMING5 DSI_REG(0x0088)
12822 +#define DSI_VM_TIMING6 DSI_REG(0x008C)
12823 +#define DSI_VM_TIMING7 DSI_REG(0x0090)
12824 +#define DSI_STOPCLK_TIMING DSI_REG(0x0094)
12825 +#define DSI_VC_CTRL(n) DSI_REG(0x0100 + (n * 0x20))
12826 +#define DSI_VC_TE(n) DSI_REG(0x0104 + (n * 0x20))
12827 +#define DSI_VC_LONG_PACKET_HEADER(n) DSI_REG(0x0108 + (n * 0x20))
12828 +#define DSI_VC_LONG_PACKET_PAYLOAD(n) DSI_REG(0x010C + (n * 0x20))
12829 +#define DSI_VC_SHORT_PACKET_HEADER(n) DSI_REG(0x0110 + (n * 0x20))
12830 +#define DSI_VC_IRQSTATUS(n) DSI_REG(0x0118 + (n * 0x20))
12831 +#define DSI_VC_IRQENABLE(n) DSI_REG(0x011C + (n * 0x20))
12833 +/* DSIPHY_SCP */
12835 +#define DSI_DSIPHY_CFG0 DSI_REG(0x200 + 0x0000)
12836 +#define DSI_DSIPHY_CFG1 DSI_REG(0x200 + 0x0004)
12837 +#define DSI_DSIPHY_CFG2 DSI_REG(0x200 + 0x0008)
12838 +#define DSI_DSIPHY_CFG5 DSI_REG(0x200 + 0x0014)
12840 +/* DSI_PLL_CTRL_SCP */
12842 +#define DSI_PLL_CONTROL DSI_REG(0x300 + 0x0000)
12843 +#define DSI_PLL_STATUS DSI_REG(0x300 + 0x0004)
12844 +#define DSI_PLL_GO DSI_REG(0x300 + 0x0008)
12845 +#define DSI_PLL_CONFIGURATION1 DSI_REG(0x300 + 0x000C)
12846 +#define DSI_PLL_CONFIGURATION2 DSI_REG(0x300 + 0x0010)
12848 +#define REG_GET(idx, start, end) \
12849 + FLD_GET(dsi_read_reg(idx), start, end)
12851 +#define REG_FLD_MOD(idx, val, start, end) \
12852 + dsi_write_reg(idx, FLD_MOD(dsi_read_reg(idx), val, start, end))
12854 +/* Global interrupts */
12855 +#define DSI_IRQ_VC0 (1 << 0)
12856 +#define DSI_IRQ_VC1 (1 << 1)
12857 +#define DSI_IRQ_VC2 (1 << 2)
12858 +#define DSI_IRQ_VC3 (1 << 3)
12859 +#define DSI_IRQ_WAKEUP (1 << 4)
12860 +#define DSI_IRQ_RESYNC (1 << 5)
12861 +#define DSI_IRQ_PLL_LOCK (1 << 7)
12862 +#define DSI_IRQ_PLL_UNLOCK (1 << 8)
12863 +#define DSI_IRQ_PLL_RECALL (1 << 9)
12864 +#define DSI_IRQ_COMPLEXIO_ERR (1 << 10)
12865 +#define DSI_IRQ_HS_TX_TIMEOUT (1 << 14)
12866 +#define DSI_IRQ_LP_RX_TIMEOUT (1 << 15)
12867 +#define DSI_IRQ_TE_TRIGGER (1 << 16)
12868 +#define DSI_IRQ_ACK_TRIGGER (1 << 17)
12869 +#define DSI_IRQ_SYNC_LOST (1 << 18)
12870 +#define DSI_IRQ_LDO_POWER_GOOD (1 << 19)
12871 +#define DSI_IRQ_TA_TIMEOUT (1 << 20)
12872 +#define DSI_IRQ_ERROR_MASK \
12873 + (DSI_IRQ_HS_TX_TIMEOUT | DSI_IRQ_LP_RX_TIMEOUT | DSI_IRQ_SYNC_LOST | \
12874 + DSI_IRQ_TA_TIMEOUT)
12875 +#define DSI_IRQ_CHANNEL_MASK 0xf
12877 +/* Virtual channel interrupts */
12878 +#define DSI_VC_IRQ_CS (1 << 0)
12879 +#define DSI_VC_IRQ_ECC_CORR (1 << 1)
12880 +#define DSI_VC_IRQ_PACKET_SENT (1 << 2)
12881 +#define DSI_VC_IRQ_FIFO_TX_OVF (1 << 3)
12882 +#define DSI_VC_IRQ_FIFO_RX_OVF (1 << 4)
12883 +#define DSI_VC_IRQ_BTA (1 << 5)
12884 +#define DSI_VC_IRQ_ECC_NO_CORR (1 << 6)
12885 +#define DSI_VC_IRQ_FIFO_TX_UDF (1 << 7)
12886 +#define DSI_VC_IRQ_PP_BUSY_CHANGE (1 << 8)
12887 +#define DSI_VC_IRQ_ERROR_MASK \
12888 + (DSI_VC_IRQ_CS | DSI_VC_IRQ_ECC_CORR | DSI_VC_IRQ_FIFO_TX_OVF | \
12889 + DSI_VC_IRQ_FIFO_RX_OVF | DSI_VC_IRQ_ECC_NO_CORR | \
12890 + DSI_VC_IRQ_FIFO_TX_UDF)
12892 +/* ComplexIO interrupts */
12893 +#define DSI_CIO_IRQ_ERRSYNCESC1 (1 << 0)
12894 +#define DSI_CIO_IRQ_ERRSYNCESC2 (1 << 1)
12895 +#define DSI_CIO_IRQ_ERRSYNCESC3 (1 << 2)
12896 +#define DSI_CIO_IRQ_ERRESC1 (1 << 5)
12897 +#define DSI_CIO_IRQ_ERRESC2 (1 << 6)
12898 +#define DSI_CIO_IRQ_ERRESC3 (1 << 7)
12899 +#define DSI_CIO_IRQ_ERRCONTROL1 (1 << 10)
12900 +#define DSI_CIO_IRQ_ERRCONTROL2 (1 << 11)
12901 +#define DSI_CIO_IRQ_ERRCONTROL3 (1 << 12)
12902 +#define DSI_CIO_IRQ_STATEULPS1 (1 << 15)
12903 +#define DSI_CIO_IRQ_STATEULPS2 (1 << 16)
12904 +#define DSI_CIO_IRQ_STATEULPS3 (1 << 17)
12905 +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_1 (1 << 20)
12906 +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_1 (1 << 21)
12907 +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_2 (1 << 22)
12908 +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_2 (1 << 23)
12909 +#define DSI_CIO_IRQ_ERRCONTENTIONLP0_3 (1 << 24)
12910 +#define DSI_CIO_IRQ_ERRCONTENTIONLP1_3 (1 << 25)
12911 +#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL0 (1 << 30)
12912 +#define DSI_CIO_IRQ_ULPSACTIVENOT_ALL1 (1 << 31)
12914 +#define DSI_DT_DCS_SHORT_WRITE_0 0x05
12915 +#define DSI_DT_DCS_SHORT_WRITE_1 0x15
12916 +#define DSI_DT_DCS_READ 0x06
12917 +#define DSI_DT_SET_MAX_RET_PKG_SIZE 0x37
12918 +#define DSI_DT_NULL_PACKET 0x09
12919 +#define DSI_DT_DCS_LONG_WRITE 0x39
12921 +#define DSI_DT_RX_ACK_WITH_ERR 0x02
12922 +#define DSI_DT_RX_DCS_LONG_READ 0x1c
12923 +#define DSI_DT_RX_SHORT_READ_1 0x21
12924 +#define DSI_DT_RX_SHORT_READ_2 0x22
12926 +#define FINT_MAX 2100000
12927 +#define FINT_MIN 750000
12928 +#define REGN_MAX (1 << 7)
12929 +#define REGM_MAX ((1 << 11) - 1)
12930 +#define REGM3_MAX (1 << 4)
12931 +#define REGM4_MAX (1 << 4)
12933 +enum fifo_size {
12934 + DSI_FIFO_SIZE_0 = 0,
12935 + DSI_FIFO_SIZE_32 = 1,
12936 + DSI_FIFO_SIZE_64 = 2,
12937 + DSI_FIFO_SIZE_96 = 3,
12938 + DSI_FIFO_SIZE_128 = 4,
12941 +#define DSI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct dsi_cmd_item))
12943 +struct dsi_cmd_update {
12944 + int bytespp;
12945 + u16 x;
12946 + u16 y;
12947 + u16 w;
12948 + u16 h;
12951 +struct dsi_cmd_mem_read {
12952 + void *buf;
12953 + size_t size;
12954 + u16 x;
12955 + u16 y;
12956 + u16 w;
12957 + u16 h;
12958 + size_t *ret_size;
12959 + struct completion *completion;
12962 +struct dsi_cmd_test {
12963 + int test_num;
12964 + int *result;
12965 + struct completion *completion;
12968 +enum dsi_cmd {
12969 + DSI_CMD_UPDATE,
12970 + DSI_CMD_SYNC,
12971 + DSI_CMD_MEM_READ,
12972 + DSI_CMD_TEST,
12973 + DSI_CMD_SET_TE,
12974 + DSI_CMD_SET_UPDATE_MODE,
12975 + DSI_CMD_SET_ROTATE,
12976 + DSI_CMD_SET_MIRROR,
12979 +struct dsi_cmd_item {
12980 + struct omap_display *display;
12982 + enum dsi_cmd cmd;
12984 + union {
12985 + struct dsi_cmd_update r;
12986 + struct completion *sync;
12987 + struct dsi_cmd_mem_read mem_read;
12988 + struct dsi_cmd_test test;
12989 + int te;
12990 + enum omap_dss_update_mode update_mode;
12991 + int rotate;
12992 + int mirror;
12993 + } u;
12996 +static struct
12998 + void __iomem *base;
13000 + unsigned long dsi1_pll_fclk; /* Hz */
13001 + unsigned long dsi2_pll_fclk; /* Hz */
13002 + unsigned long dsiphy; /* Hz */
13003 + unsigned long ddr_clk; /* Hz */
13005 + struct {
13006 + enum fifo_size fifo_size;
13007 + int dest_per; /* destination peripheral 0-3 */
13008 + } vc[4];
13010 + struct mutex lock;
13012 + unsigned pll_locked;
13014 + struct completion bta_completion;
13016 + struct work_struct framedone_work;
13017 + struct workqueue_struct *framedone_workqueue;
13019 + enum omap_dss_update_mode user_update_mode;
13020 + enum omap_dss_update_mode target_update_mode;
13021 + enum omap_dss_update_mode update_mode;
13022 + int use_te;
13023 + int framedone_scheduled; /* helps to catch strange framedone bugs */
13026 + struct {
13027 + struct omap_display *display;
13028 + int x, y, w, h;
13029 + int bytespp;
13030 + } update_region;
13032 + unsigned long cache_req_pck;
13033 + unsigned long cache_clk_freq;
13034 + struct dsi_clock_info cache_cinfo;
13036 + struct kfifo *cmd_fifo;
13037 + spinlock_t cmd_lock;
13038 + struct completion cmd_done;
13039 + atomic_t cmd_fifo_full;
13040 + atomic_t cmd_pending;
13042 +#ifdef DEBUG
13043 + ktime_t perf_setup_time;
13044 + ktime_t perf_start_time;
13045 + int perf_measure_frames;
13046 +#endif
13047 + int debug_process;
13048 + int debug_read;
13049 + int debug_write;
13050 +} dsi;
13052 +#ifdef DEBUG
13053 +static unsigned int dsi_perf;
13054 +module_param_named(dsi_perf, dsi_perf, bool, 0644);
13055 +#endif
13057 +static void dsi_process_cmd_fifo(void);
13058 +static void dsi_push_update(struct omap_display *display,
13059 + int x, int y, int w, int h);
13061 +static inline void dsi_write_reg(const struct dsi_reg idx, u32 val)
13063 + __raw_writel(val, dsi.base + idx.idx);
13066 +static inline u32 dsi_read_reg(const struct dsi_reg idx)
13068 + return __raw_readl(dsi.base + idx.idx);
13072 +void dsi_save_context(void)
13076 +void dsi_restore_context(void)
13080 +static inline int wait_for_bit_change(const struct dsi_reg idx, int bitnum,
13081 + int value)
13083 + int t = 100000;
13085 + while (REG_GET(idx, bitnum, bitnum) != value) {
13086 + if (--t == 0)
13087 + return !value;
13090 + return value;
13093 +#ifdef DEBUG
13094 +static void perf_mark_setup(void)
13096 + dsi.perf_setup_time = ktime_get();
13099 +static void perf_mark_start(void)
13101 + dsi.perf_start_time = ktime_get();
13104 +static void perf_show(const char *name)
13106 + ktime_t t, setup_time, trans_time;
13107 + u32 total_bytes;
13108 + u32 setup_us, trans_us, total_us;
13109 + const int numframes = 100;
13110 + static u32 s_trans_us, s_min_us = 0xffffffff, s_max_us;
13112 + if (!dsi_perf)
13113 + return;
13115 + if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
13116 + return;
13118 + t = ktime_get();
13120 + setup_time = ktime_sub(dsi.perf_start_time, dsi.perf_setup_time);
13121 + setup_us = (u32)ktime_to_us(setup_time);
13122 + if (setup_us == 0)
13123 + setup_us = 1;
13125 + trans_time = ktime_sub(t, dsi.perf_start_time);
13126 + trans_us = (u32)ktime_to_us(trans_time);
13127 + if (trans_us == 0)
13128 + trans_us = 1;
13130 + total_us = setup_us + trans_us;
13132 + total_bytes = dsi.update_region.w *
13133 + dsi.update_region.h *
13134 + dsi.update_region.bytespp;
13136 + if (dsi.update_mode == OMAP_DSS_UPDATE_AUTO) {
13137 + dsi.perf_measure_frames++;
13139 + if (trans_us < s_min_us)
13140 + s_min_us = trans_us;
13142 + if (trans_us > s_max_us)
13143 + s_max_us = trans_us;
13145 + s_trans_us += trans_us;
13147 + if (dsi.perf_measure_frames < numframes)
13148 + return;
13150 + DSSINFO("%s update: %d frames in %u us "
13151 + "(min/max/avg %u/%u/%u), %u fps\n",
13152 + name, numframes,
13153 + s_trans_us,
13154 + s_min_us,
13155 + s_max_us,
13156 + s_trans_us / numframes,
13157 + 1000*1000 / (s_trans_us / numframes));
13159 + dsi.perf_measure_frames = 0;
13160 + s_trans_us = 0;
13161 + s_min_us = 0xffffffff;
13162 + s_max_us = 0;
13163 + } else {
13164 + DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, "
13165 + "%u kbytes/sec\n",
13166 + name,
13167 + setup_us,
13168 + trans_us,
13169 + total_us,
13170 + 1000*1000 / total_us,
13171 + total_bytes,
13172 + total_bytes * 1000 / total_us);
13175 +#else
13176 +#define perf_mark_setup()
13177 +#define perf_mark_start()
13178 +#define perf_show(x)
13179 +#endif
13181 +static void print_irq_status(u32 status)
13183 +#ifndef VERBOSE_IRQ
13184 + if ((status & ~DSI_IRQ_CHANNEL_MASK) == 0)
13185 + return;
13186 +#endif
13187 + printk(KERN_DEBUG "DSI IRQ: 0x%x: ", status);
13189 +#define PIS(x) \
13190 + if (status & DSI_IRQ_##x) \
13191 + printk(#x " ");
13192 +#ifdef VERBOSE_IRQ
13193 + PIS(VC0);
13194 + PIS(VC1);
13195 + PIS(VC2);
13196 + PIS(VC3);
13197 +#endif
13198 + PIS(WAKEUP);
13199 + PIS(RESYNC);
13200 + PIS(PLL_LOCK);
13201 + PIS(PLL_UNLOCK);
13202 + PIS(PLL_RECALL);
13203 + PIS(COMPLEXIO_ERR);
13204 + PIS(HS_TX_TIMEOUT);
13205 + PIS(LP_RX_TIMEOUT);
13206 + PIS(TE_TRIGGER);
13207 + PIS(ACK_TRIGGER);
13208 + PIS(SYNC_LOST);
13209 + PIS(LDO_POWER_GOOD);
13210 + PIS(TA_TIMEOUT);
13211 +#undef PIS
13213 + printk("\n");
13216 +static void print_irq_status_vc(int channel, u32 status)
13218 +#ifndef VERBOSE_IRQ
13219 + if ((status & ~DSI_VC_IRQ_PACKET_SENT) == 0)
13220 + return;
13221 +#endif
13222 + printk(KERN_DEBUG "DSI VC(%d) IRQ 0x%x: ", channel, status);
13224 +#define PIS(x) \
13225 + if (status & DSI_VC_IRQ_##x) \
13226 + printk(#x " ");
13227 + PIS(CS);
13228 + PIS(ECC_CORR);
13229 +#ifdef VERBOSE_IRQ
13230 + PIS(PACKET_SENT);
13231 +#endif
13232 + PIS(FIFO_TX_OVF);
13233 + PIS(FIFO_RX_OVF);
13234 + PIS(BTA);
13235 + PIS(ECC_NO_CORR);
13236 + PIS(FIFO_TX_UDF);
13237 + PIS(PP_BUSY_CHANGE);
13238 +#undef PIS
13239 + printk("\n");
13242 +static void print_irq_status_cio(u32 status)
13244 + printk(KERN_DEBUG "DSI CIO IRQ 0x%x: ", status);
13246 +#define PIS(x) \
13247 + if (status & DSI_CIO_IRQ_##x) \
13248 + printk(#x " ");
13249 + PIS(ERRSYNCESC1);
13250 + PIS(ERRSYNCESC2);
13251 + PIS(ERRSYNCESC3);
13252 + PIS(ERRESC1);
13253 + PIS(ERRESC2);
13254 + PIS(ERRESC3);
13255 + PIS(ERRCONTROL1);
13256 + PIS(ERRCONTROL2);
13257 + PIS(ERRCONTROL3);
13258 + PIS(STATEULPS1);
13259 + PIS(STATEULPS2);
13260 + PIS(STATEULPS3);
13261 + PIS(ERRCONTENTIONLP0_1);
13262 + PIS(ERRCONTENTIONLP1_1);
13263 + PIS(ERRCONTENTIONLP0_2);
13264 + PIS(ERRCONTENTIONLP1_2);
13265 + PIS(ERRCONTENTIONLP0_3);
13266 + PIS(ERRCONTENTIONLP1_3);
13267 + PIS(ULPSACTIVENOT_ALL0);
13268 + PIS(ULPSACTIVENOT_ALL1);
13269 +#undef PIS
13271 + printk("\n");
13274 +static int debug_irq;
13276 +/* called from dss */
13277 +void dsi_irq_handler(void)
13279 + u32 irqstatus, vcstatus, ciostatus;
13280 + int i;
13282 + irqstatus = dsi_read_reg(DSI_IRQSTATUS);
13284 + if (irqstatus & DSI_IRQ_ERROR_MASK) {
13285 + DSSERR("DSI error, irqstatus %x\n", irqstatus);
13286 + print_irq_status(irqstatus);
13287 + } else if (debug_irq) {
13288 + print_irq_status(irqstatus);
13291 + for (i = 0; i < 4; ++i) {
13292 + if ((irqstatus & (1<<i)) == 0)
13293 + continue;
13295 + vcstatus = dsi_read_reg(DSI_VC_IRQSTATUS(i));
13297 + if (vcstatus & DSI_VC_IRQ_BTA)
13298 + complete(&dsi.bta_completion);
13300 + if (vcstatus & DSI_VC_IRQ_ERROR_MASK) {
13301 + DSSERR("DSI VC(%d) error, vc irqstatus %x\n",
13302 + i, vcstatus);
13303 + print_irq_status_vc(i, vcstatus);
13304 + } else if (debug_irq) {
13305 + print_irq_status_vc(i, vcstatus);
13308 + dsi_write_reg(DSI_VC_IRQSTATUS(i), vcstatus);
13311 + if (irqstatus & DSI_IRQ_COMPLEXIO_ERR) {
13312 + ciostatus = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
13314 + dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, ciostatus);
13316 + DSSERR("DSI CIO error, cio irqstatus %x\n", ciostatus);
13317 + print_irq_status_cio(ciostatus);
13320 + dsi_write_reg(DSI_IRQSTATUS, irqstatus & ~DSI_IRQ_CHANNEL_MASK);
13324 +static void _dsi_initialize_irq(void)
13326 + u32 l;
13327 + int i;
13329 + /* disable all interrupts */
13330 + dsi_write_reg(DSI_IRQENABLE, 0);
13331 + for (i = 0; i < 4; ++i)
13332 + dsi_write_reg(DSI_VC_IRQENABLE(i), 0);
13333 + dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE, 0);
13335 + /* clear interrupt status */
13336 + l = dsi_read_reg(DSI_IRQSTATUS);
13337 + dsi_write_reg(DSI_IRQSTATUS, l & ~DSI_IRQ_CHANNEL_MASK);
13339 + for (i = 0; i < 4; ++i) {
13340 + l = dsi_read_reg(DSI_VC_IRQSTATUS(i));
13341 + dsi_write_reg(DSI_VC_IRQSTATUS(i), l);
13344 + l = dsi_read_reg(DSI_COMPLEXIO_IRQ_STATUS);
13345 + dsi_write_reg(DSI_COMPLEXIO_IRQ_STATUS, l);
13347 + /* enable error irqs */
13348 + l = DSI_IRQ_ERROR_MASK;
13349 + dsi_write_reg(DSI_IRQENABLE, l);
13351 + l = DSI_VC_IRQ_ERROR_MASK;
13352 + for (i = 0; i < 4; ++i)
13353 + dsi_write_reg(DSI_VC_IRQENABLE(i), l);
13355 + /* XXX zonda responds incorrectly, causing control error:
13356 + Exit from LP-ESC mode to LP11 uses wrong transition states on the
13357 + data lines LP0 and LN0. */
13358 + dsi_write_reg(DSI_COMPLEXIO_IRQ_ENABLE,
13359 + -1 & (~DSI_CIO_IRQ_ERRCONTROL2));
13362 +static void dsi_vc_enable_bta_irq(int channel)
13364 + u32 l;
13366 + l = dsi_read_reg(DSI_VC_IRQENABLE(channel));
13367 + l |= DSI_VC_IRQ_BTA;
13368 + dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
13371 +static void dsi_vc_disable_bta_irq(int channel)
13373 + u32 l;
13375 + l = dsi_read_reg(DSI_VC_IRQENABLE(channel));
13376 + l &= ~DSI_VC_IRQ_BTA;
13377 + dsi_write_reg(DSI_VC_IRQENABLE(channel), l);
13380 +/* DSI func clock. this could also be DSI2_PLL_FCLK */
13381 +static inline void enable_clocks(bool enable)
13383 + if (enable)
13384 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
13385 + else
13386 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
13389 +/* source clock for DSI PLL. this could also be PCLKFREE */
13390 +static inline void dsi_enable_pll_clock(bool enable)
13392 + if (enable)
13393 + dss_clk_enable(DSS_CLK_FCK2);
13394 + else
13395 + dss_clk_disable(DSS_CLK_FCK2);
13397 + if (enable && dsi.pll_locked) {
13398 + if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1)
13399 + DSSERR("cannot lock PLL when enabling clocks\n");
13403 +#ifdef DEBUG
13404 +static void _dsi_print_reset_status(void)
13406 + u32 l;
13408 + if (!dss_debug)
13409 + return;
13411 + /* A dummy read using the SCP interface to any DSIPHY register is
13412 + * required after DSIPHY reset to complete the reset of the DSI complex
13413 + * I/O. */
13414 + l = dsi_read_reg(DSI_DSIPHY_CFG5);
13416 + printk(KERN_DEBUG "DSI resets: ");
13418 + l = dsi_read_reg(DSI_PLL_STATUS);
13419 + printk("PLL (%d) ", FLD_GET(l, 0, 0));
13421 + l = dsi_read_reg(DSI_COMPLEXIO_CFG1);
13422 + printk("CIO (%d) ", FLD_GET(l, 29, 29));
13424 + l = dsi_read_reg(DSI_DSIPHY_CFG5);
13425 + printk("PHY (%x, %d, %d, %d)\n",
13426 + FLD_GET(l, 28, 26),
13427 + FLD_GET(l, 29, 29),
13428 + FLD_GET(l, 30, 30),
13429 + FLD_GET(l, 31, 31));
13431 +#else
13432 +#define _dsi_print_reset_status()
13433 +#endif
13435 +static inline int dsi_if_enable(bool enable)
13437 + DSSDBG("dsi_if_enable(%d)\n", enable);
13439 + enable = enable ? 1 : 0;
13440 + REG_FLD_MOD(DSI_CTRL, enable, 0, 0); /* IF_EN */
13442 + if (wait_for_bit_change(DSI_CTRL, 0, enable) != enable) {
13443 + DSSERR("Failed to set dsi_if_enable to %d\n", enable);
13444 + return -EIO;
13447 + return 0;
13450 +static unsigned long dsi_fclk_rate(void)
13452 + unsigned long r;
13454 + if (dss_get_dsi_clk_source() == 0) {
13455 + /* DSI FCLK source is DSS1_ALWON_FCK, which is dss1_fck */
13456 + r = dss_clk_get_rate(DSS_CLK_FCK1);
13457 + } else {
13458 + /* DSI FCLK source is DSI2_PLL_FCLK */
13459 + r = dsi.dsi2_pll_fclk;
13462 + return r;
13465 +static int dsi_set_lp_clk_divisor(void)
13467 + int n;
13468 + unsigned long dsi_fclk;
13469 + unsigned long mhz;
13471 + /* LP_CLK_DIVISOR, DSI fclk/n, should be 20MHz - 32kHz */
13473 + dsi_fclk = dsi_fclk_rate();
13475 + for (n = 1; n < (1 << 13) - 1; ++n) {
13476 + mhz = dsi_fclk / n;
13477 + if (mhz <= 20*1000*1000)
13478 + break;
13481 + if (n == (1 << 13) - 1) {
13482 + DSSERR("Failed to find LP_CLK_DIVISOR\n");
13483 + return -EINVAL;
13486 + DSSDBG("LP_CLK_DIV %d, LP_CLK %ld\n", n, mhz);
13488 + REG_FLD_MOD(DSI_CLK_CTRL, n, 12, 0); /* LP_CLK_DIVISOR */
13489 + if (dsi_fclk > 30*1000*1000)
13490 + REG_FLD_MOD(DSI_CLK_CTRL, 1, 21, 21); /* LP_RX_SYNCHRO_ENABLE */
13492 + return 0;
13496 +enum dsi_pll_power_state {
13497 + DSI_PLL_POWER_OFF = 0x0,
13498 + DSI_PLL_POWER_ON_HSCLK = 0x1,
13499 + DSI_PLL_POWER_ON_ALL = 0x2,
13500 + DSI_PLL_POWER_ON_DIV = 0x3,
13503 +static int dsi_pll_power(enum dsi_pll_power_state state)
13505 + int t = 0;
13507 + REG_FLD_MOD(DSI_CLK_CTRL, state, 31, 30); /* PLL_PWR_CMD */
13509 + /* PLL_PWR_STATUS */
13510 + while (FLD_GET(dsi_read_reg(DSI_CLK_CTRL), 29, 28) != state) {
13511 + udelay(1);
13512 + if (t++ > 1000) {
13513 + DSSERR("Failed to set DSI PLL power mode to %d\n",
13514 + state);
13515 + return -ENODEV;
13519 + return 0;
13522 +int dsi_pll_calc_pck(bool is_tft, unsigned long req_pck,
13523 + struct dsi_clock_info *cinfo)
13525 + struct dsi_clock_info cur, best;
13526 + int min_fck_per_pck;
13527 + int match = 0;
13529 + if (req_pck == dsi.cache_req_pck &&
13530 + dsi.cache_cinfo.clkin == dss_clk_get_rate(DSS_CLK_FCK2)) {
13531 + DSSDBG("DSI clock info found from cache\n");
13532 + *cinfo = dsi.cache_cinfo;
13533 + return 0;
13536 + min_fck_per_pck = CONFIG_OMAP2_DSS_MIN_FCK_PER_PCK;
13538 + if (min_fck_per_pck &&
13539 + req_pck * min_fck_per_pck > DISPC_MAX_FCK) {
13540 + DSSERR("Requested pixel clock not possible with the current "
13541 + "OMAP2_DSS_MIN_FCK_PER_PCK setting. Turning "
13542 + "the constraint off.\n");
13543 + min_fck_per_pck = 0;
13546 + DSSDBG("dsi_pll_calc\n");
13548 +retry:
13549 + memset(&best, 0, sizeof(best));
13551 + memset(&cur, 0, sizeof(cur));
13552 + cur.clkin = dss_clk_get_rate(DSS_CLK_FCK2);
13553 + cur.use_dss2_fck = 1;
13554 + cur.highfreq = 0;
13556 + /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
13557 + /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
13558 + /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
13559 + for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) {
13560 + if (cur.highfreq == 0)
13561 + cur.fint = cur.clkin / cur.regn;
13562 + else
13563 + cur.fint = cur.clkin / (2 * cur.regn);
13565 + if (cur.fint > FINT_MAX || cur.fint < FINT_MIN)
13566 + continue;
13568 + /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
13569 + for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) {
13570 + unsigned long a, b;
13572 + a = 2 * cur.regm * (cur.clkin/1000);
13573 + b = cur.regn * (cur.highfreq + 1);
13574 + cur.dsiphy = a / b * 1000;
13576 + if (cur.dsiphy > 1800 * 1000 * 1000)
13577 + break;
13579 + /* DSI1_PLL_FCLK(MHz) = DSIPHY(MHz) / regm3 < 173MHz */
13580 + for (cur.regm3 = 1; cur.regm3 < REGM3_MAX;
13581 + ++cur.regm3) {
13582 + cur.dsi1_pll_fclk = cur.dsiphy / cur.regm3;
13584 + /* this will narrow down the search a bit,
13585 + * but still give pixclocks below what was
13586 + * requested */
13587 + if (cur.dsi1_pll_fclk < req_pck)
13588 + break;
13590 + if (cur.dsi1_pll_fclk > DISPC_MAX_FCK)
13591 + continue;
13593 + if (min_fck_per_pck &&
13594 + cur.dsi1_pll_fclk <
13595 + req_pck * min_fck_per_pck)
13596 + continue;
13598 + match = 1;
13600 + find_lck_pck_divs(is_tft, req_pck,
13601 + cur.dsi1_pll_fclk,
13602 + &cur.lck_div,
13603 + &cur.pck_div);
13605 + cur.lck = cur.dsi1_pll_fclk / cur.lck_div;
13606 + cur.pck = cur.lck / cur.pck_div;
13608 + if (abs(cur.pck - req_pck) <
13609 + abs(best.pck - req_pck)) {
13610 + best = cur;
13612 + if (cur.pck == req_pck)
13613 + goto found;
13618 +found:
13619 + if (!match) {
13620 + if (min_fck_per_pck) {
13621 + DSSERR("Could not find suitable clock settings.\n"
13622 + "Turning FCK/PCK constraint off and"
13623 + "trying again.\n");
13624 + min_fck_per_pck = 0;
13625 + goto retry;
13628 + DSSERR("Could not find suitable clock settings.\n");
13630 + return -EINVAL;
13633 + /* DSI2_PLL_FCLK (regm4) is not used. Set it to something sane. */
13634 + best.regm4 = best.dsiphy / 48000000;
13635 + if (best.regm4 > REGM4_MAX)
13636 + best.regm4 = REGM4_MAX;
13637 + else if (best.regm4 == 0)
13638 + best.regm4 = 1;
13639 + best.dsi2_pll_fclk = best.dsiphy / best.regm4;
13641 + if (cinfo)
13642 + *cinfo = best;
13644 + dsi.cache_req_pck = req_pck;
13645 + dsi.cache_clk_freq = 0;
13646 + dsi.cache_cinfo = best;
13648 + return 0;
13651 +static int dsi_pll_calc_ddrfreq(unsigned long clk_freq,
13652 + struct dsi_clock_info *cinfo)
13654 + struct dsi_clock_info cur, best;
13655 + const bool use_dss2_fck = 1;
13656 + unsigned long datafreq;
13658 + DSSDBG("dsi_pll_calc_ddrfreq\n");
13660 + if (clk_freq == dsi.cache_clk_freq &&
13661 + dsi.cache_cinfo.clkin == dss_clk_get_rate(DSS_CLK_FCK2)) {
13662 + DSSDBG("DSI clock info found from cache\n");
13663 + *cinfo = dsi.cache_cinfo;
13664 + return 0;
13667 + datafreq = clk_freq * 4;
13669 + memset(&best, 0, sizeof(best));
13671 + memset(&cur, 0, sizeof(cur));
13672 + cur.use_dss2_fck = use_dss2_fck;
13673 + if (use_dss2_fck) {
13674 + cur.clkin = dss_clk_get_rate(DSS_CLK_FCK2);
13675 + cur.highfreq = 0;
13676 + } else {
13677 + cur.clkin = dispc_pclk_rate();
13678 + if (cur.clkin < 32000000)
13679 + cur.highfreq = 0;
13680 + else
13681 + cur.highfreq = 1;
13684 + /* no highfreq: 0.75MHz < Fint = clkin / regn < 2.1MHz */
13685 + /* highfreq: 0.75MHz < Fint = clkin / (2*regn) < 2.1MHz */
13686 + /* To reduce PLL lock time, keep Fint high (around 2 MHz) */
13687 + for (cur.regn = 1; cur.regn < REGN_MAX; ++cur.regn) {
13688 + if (cur.highfreq == 0)
13689 + cur.fint = cur.clkin / cur.regn;
13690 + else
13691 + cur.fint = cur.clkin / (2 * cur.regn);
13693 + if (cur.fint > FINT_MAX || cur.fint < FINT_MIN)
13694 + continue;
13696 + /* DSIPHY(MHz) = (2 * regm / regn) * (clkin / (highfreq + 1)) */
13697 + for (cur.regm = 1; cur.regm < REGM_MAX; ++cur.regm) {
13698 + unsigned long a, b;
13700 + a = 2 * cur.regm * (cur.clkin/1000);
13701 + b = cur.regn * (cur.highfreq + 1);
13702 + cur.dsiphy = a / b * 1000;
13704 + if (cur.dsiphy > 1800 * 1000 * 1000)
13705 + break;
13707 + if (abs(cur.dsiphy - datafreq) <
13708 + abs(best.dsiphy - datafreq)) {
13709 + best = cur;
13710 + /* DSSDBG("best %ld\n", best.dsiphy); */
13713 + if (cur.dsiphy == datafreq)
13714 + goto found;
13717 +found:
13718 + /* DSI1_PLL_FCLK (regm3) is not used. Set it to something sane. */
13719 + best.regm3 = best.dsiphy / 48000000;
13720 + if (best.regm3 > REGM3_MAX)
13721 + best.regm3 = REGM3_MAX;
13722 + else if (best.regm3 == 0)
13723 + best.regm3 = 1;
13724 + best.dsi1_pll_fclk = best.dsiphy / best.regm3;
13726 + /* DSI2_PLL_FCLK (regm4) is not used. Set it to something sane. */
13727 + best.regm4 = best.dsiphy / 48000000;
13728 + if (best.regm4 > REGM4_MAX)
13729 + best.regm4 = REGM4_MAX;
13730 + else if (best.regm4 == 0)
13731 + best.regm4 = 1;
13732 + best.dsi2_pll_fclk = best.dsiphy / best.regm4;
13734 + if (cinfo)
13735 + *cinfo = best;
13737 + dsi.cache_clk_freq = clk_freq;
13738 + dsi.cache_req_pck = 0;
13739 + dsi.cache_cinfo = best;
13741 + return 0;
13744 +int dsi_pll_program(struct dsi_clock_info *cinfo)
13746 + int r = 0;
13747 + u32 l;
13749 + DSSDBG("dsi_pll_program\n");
13751 + dsi.dsiphy = cinfo->dsiphy;
13752 + dsi.ddr_clk = dsi.dsiphy / 4;
13753 + dsi.dsi1_pll_fclk = cinfo->dsi1_pll_fclk;
13754 + dsi.dsi2_pll_fclk = cinfo->dsi2_pll_fclk;
13756 + DSSDBG("DSI Fint %ld\n", cinfo->fint);
13758 + DSSDBG("clkin (%s) rate %ld, highfreq %d\n",
13759 + cinfo->use_dss2_fck ? "dss2_fck" : "pclkfree",
13760 + cinfo->clkin,
13761 + cinfo->highfreq);
13763 + /* DSIPHY == CLKIN4DDR */
13764 + DSSDBG("DSIPHY = 2 * %d / %d * %lu / %d = %lu\n",
13765 + cinfo->regm,
13766 + cinfo->regn,
13767 + cinfo->clkin,
13768 + cinfo->highfreq + 1,
13769 + cinfo->dsiphy);
13771 + DSSDBG("Data rate on 1 DSI lane %ld Mbps\n",
13772 + dsi.dsiphy / 1000 / 1000 / 2);
13774 + DSSDBG("Clock lane freq %ld Hz\n", dsi.ddr_clk);
13776 + DSSDBG("regm3 = %d, dsi1_pll_fclk = %lu\n",
13777 + cinfo->regm3, cinfo->dsi1_pll_fclk);
13778 + DSSDBG("regm4 = %d, dsi2_pll_fclk = %lu\n",
13779 + cinfo->regm4, cinfo->dsi2_pll_fclk);
13781 + REG_FLD_MOD(DSI_PLL_CONTROL, 0, 0, 0); /* DSI_PLL_AUTOMODE = manual */
13783 + l = dsi_read_reg(DSI_PLL_CONFIGURATION1);
13784 + l = FLD_MOD(l, 1, 0, 0); /* DSI_PLL_STOPMODE */
13785 + l = FLD_MOD(l, cinfo->regn - 1, 7, 1); /* DSI_PLL_REGN */
13786 + l = FLD_MOD(l, cinfo->regm, 18, 8); /* DSI_PLL_REGM */
13787 + l = FLD_MOD(l, cinfo->regm3 - 1, 22, 19); /* DSI_CLOCK_DIV */
13788 + l = FLD_MOD(l, cinfo->regm4 - 1, 26, 23); /* DSIPROTO_CLOCK_DIV */
13789 + dsi_write_reg(DSI_PLL_CONFIGURATION1, l);
13791 + l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
13792 + l = FLD_MOD(l, 7, 4, 1); /* DSI_PLL_FREQSEL */
13793 + /* DSI_PLL_CLKSEL */
13794 + l = FLD_MOD(l, cinfo->use_dss2_fck ? 0 : 1, 11, 11);
13795 + l = FLD_MOD(l, cinfo->highfreq, 12, 12); /* DSI_PLL_HIGHFREQ */
13796 + l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
13797 + l = FLD_MOD(l, 0, 14, 14); /* DSIPHY_CLKINEN */
13798 + l = FLD_MOD(l, 1, 20, 20); /* DSI_HSDIVBYPASS */
13799 + dsi_write_reg(DSI_PLL_CONFIGURATION2, l);
13801 + REG_FLD_MOD(DSI_PLL_GO, 1, 0, 0); /* DSI_PLL_GO */
13803 + if (wait_for_bit_change(DSI_PLL_GO, 0, 0) != 0) {
13804 + DSSERR("dsi pll go bit not going down.\n");
13805 + r = -EIO;
13806 + goto err;
13809 + if (wait_for_bit_change(DSI_PLL_STATUS, 1, 1) != 1) {
13810 + DSSERR("cannot lock PLL\n");
13811 + r = -EIO;
13812 + goto err;
13815 + dsi.pll_locked = 1;
13817 + l = dsi_read_reg(DSI_PLL_CONFIGURATION2);
13818 + l = FLD_MOD(l, 0, 0, 0); /* DSI_PLL_IDLE */
13819 + l = FLD_MOD(l, 0, 5, 5); /* DSI_PLL_PLLLPMODE */
13820 + l = FLD_MOD(l, 0, 6, 6); /* DSI_PLL_LOWCURRSTBY */
13821 + l = FLD_MOD(l, 0, 7, 7); /* DSI_PLL_TIGHTPHASELOCK */
13822 + l = FLD_MOD(l, 0, 8, 8); /* DSI_PLL_DRIFTGUARDEN */
13823 + l = FLD_MOD(l, 0, 10, 9); /* DSI_PLL_LOCKSEL */
13824 + l = FLD_MOD(l, 1, 13, 13); /* DSI_PLL_REFEN */
13825 + l = FLD_MOD(l, 1, 14, 14); /* DSIPHY_CLKINEN */
13826 + l = FLD_MOD(l, 0, 15, 15); /* DSI_BYPASSEN */
13827 + l = FLD_MOD(l, 1, 16, 16); /* DSS_CLOCK_EN */
13828 + l = FLD_MOD(l, 0, 17, 17); /* DSS_CLOCK_PWDN */
13829 + l = FLD_MOD(l, 1, 18, 18); /* DSI_PROTO_CLOCK_EN */
13830 + l = FLD_MOD(l, 0, 19, 19); /* DSI_PROTO_CLOCK_PWDN */
13831 + l = FLD_MOD(l, 0, 20, 20); /* DSI_HSDIVBYPASS */
13832 + dsi_write_reg(DSI_PLL_CONFIGURATION2, l);
13834 + DSSDBG("PLL config done\n");
13835 +err:
13836 + return r;
13839 +int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv)
13841 + int r = 0;
13842 + enum dsi_pll_power_state pwstate;
13843 + struct dispc_clock_info cinfo;
13845 + DSSDBG("PLL init\n");
13847 + enable_clocks(1);
13848 + dsi_enable_pll_clock(1);
13850 + /* configure dispc fck and pixel clock to something sane */
13851 + r = dispc_calc_clock_div(1, 48 * 1000 * 1000, &cinfo);
13852 + if (r)
13853 + goto err0;
13855 + r = dispc_set_clock_div(&cinfo);
13856 + if (r) {
13857 + DSSERR("Failed to set basic clocks\n");
13858 + goto err0;
13861 + r = dss_dsi_power_up();
13862 + if (r)
13863 + goto err0;
13865 + /* PLL does not come out of reset without this... */
13866 + dispc_pck_free_enable(1);
13868 + if (wait_for_bit_change(DSI_PLL_STATUS, 0, 1) != 1) {
13869 + DSSERR("PLL not coming out of reset.\n");
13870 + r = -ENODEV;
13871 + goto err1;
13874 + /* ... but if left on, we get problems when planes do not
13875 + * fill the whole display. No idea about this XXX */
13876 + dispc_pck_free_enable(0);
13878 + if (enable_hsclk && enable_hsdiv)
13879 + pwstate = DSI_PLL_POWER_ON_ALL;
13880 + else if (enable_hsclk)
13881 + pwstate = DSI_PLL_POWER_ON_HSCLK;
13882 + else if (enable_hsdiv)
13883 + pwstate = DSI_PLL_POWER_ON_DIV;
13884 + else
13885 + pwstate = DSI_PLL_POWER_OFF;
13887 + r = dsi_pll_power(pwstate);
13889 + if (r)
13890 + goto err1;
13892 + DSSDBG("PLL init done\n");
13894 + return 0;
13895 +err1:
13896 + dss_dsi_power_down();
13897 +err0:
13898 + enable_clocks(0);
13899 + dsi_enable_pll_clock(0);
13900 + return r;
13903 +void dsi_pll_uninit(void)
13905 + enable_clocks(0);
13906 + dsi_enable_pll_clock(0);
13908 + dsi.pll_locked = 0;
13909 + dsi_pll_power(DSI_PLL_POWER_OFF);
13910 + dss_dsi_power_down();
13911 + DSSDBG("PLL uninit done\n");
13914 +unsigned long dsi_get_dsi1_pll_rate(void)
13916 + return dsi.dsi1_pll_fclk;
13919 +unsigned long dsi_get_dsi2_pll_rate(void)
13921 + return dsi.dsi2_pll_fclk;
13924 +void dsi_dump_clocks(struct seq_file *s)
13926 + int clksel;
13928 + enable_clocks(1);
13930 + clksel = REG_GET(DSI_PLL_CONFIGURATION2, 11, 11);
13932 + seq_printf(s, "- dsi -\n");
13934 + seq_printf(s, "dsi fclk source = %s\n",
13935 + dss_get_dsi_clk_source() == 0 ?
13936 + "dss1_alwon_fclk" : "dsi2_pll_fclk");
13938 + seq_printf(s, "dsi pll source = %s\n",
13939 + clksel == 0 ?
13940 + "dss2_alwon_fclk" : "pclkfree");
13942 + seq_printf(s, "DSIPHY\t\t%lu\nDDR_CLK\t\t%lu\n",
13943 + dsi.dsiphy, dsi.ddr_clk);
13945 + seq_printf(s, "dsi1_pll_fck\t%lu (%s)\n"
13946 + "dsi2_pll_fck\t%lu (%s)\n",
13947 + dsi.dsi1_pll_fclk,
13948 + dss_get_dispc_clk_source() == 0 ? "off" : "on",
13949 + dsi.dsi2_pll_fclk,
13950 + dss_get_dsi_clk_source() == 0 ? "off" : "on");
13952 + enable_clocks(0);
13955 +void dsi_dump_regs(struct seq_file *s)
13957 +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dsi_read_reg(r))
13959 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
13961 + DUMPREG(DSI_REVISION);
13962 + DUMPREG(DSI_SYSCONFIG);
13963 + DUMPREG(DSI_SYSSTATUS);
13964 + DUMPREG(DSI_IRQSTATUS);
13965 + DUMPREG(DSI_IRQENABLE);
13966 + DUMPREG(DSI_CTRL);
13967 + DUMPREG(DSI_COMPLEXIO_CFG1);
13968 + DUMPREG(DSI_COMPLEXIO_IRQ_STATUS);
13969 + DUMPREG(DSI_COMPLEXIO_IRQ_ENABLE);
13970 + DUMPREG(DSI_CLK_CTRL);
13971 + DUMPREG(DSI_TIMING1);
13972 + DUMPREG(DSI_TIMING2);
13973 + DUMPREG(DSI_VM_TIMING1);
13974 + DUMPREG(DSI_VM_TIMING2);
13975 + DUMPREG(DSI_VM_TIMING3);
13976 + DUMPREG(DSI_CLK_TIMING);
13977 + DUMPREG(DSI_TX_FIFO_VC_SIZE);
13978 + DUMPREG(DSI_RX_FIFO_VC_SIZE);
13979 + DUMPREG(DSI_COMPLEXIO_CFG2);
13980 + DUMPREG(DSI_RX_FIFO_VC_FULLNESS);
13981 + DUMPREG(DSI_VM_TIMING4);
13982 + DUMPREG(DSI_TX_FIFO_VC_EMPTINESS);
13983 + DUMPREG(DSI_VM_TIMING5);
13984 + DUMPREG(DSI_VM_TIMING6);
13985 + DUMPREG(DSI_VM_TIMING7);
13986 + DUMPREG(DSI_STOPCLK_TIMING);
13988 + DUMPREG(DSI_VC_CTRL(0));
13989 + DUMPREG(DSI_VC_TE(0));
13990 + DUMPREG(DSI_VC_LONG_PACKET_HEADER(0));
13991 + DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(0));
13992 + DUMPREG(DSI_VC_SHORT_PACKET_HEADER(0));
13993 + DUMPREG(DSI_VC_IRQSTATUS(0));
13994 + DUMPREG(DSI_VC_IRQENABLE(0));
13996 + DUMPREG(DSI_VC_CTRL(1));
13997 + DUMPREG(DSI_VC_TE(1));
13998 + DUMPREG(DSI_VC_LONG_PACKET_HEADER(1));
13999 + DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(1));
14000 + DUMPREG(DSI_VC_SHORT_PACKET_HEADER(1));
14001 + DUMPREG(DSI_VC_IRQSTATUS(1));
14002 + DUMPREG(DSI_VC_IRQENABLE(1));
14004 + DUMPREG(DSI_VC_CTRL(2));
14005 + DUMPREG(DSI_VC_TE(2));
14006 + DUMPREG(DSI_VC_LONG_PACKET_HEADER(2));
14007 + DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(2));
14008 + DUMPREG(DSI_VC_SHORT_PACKET_HEADER(2));
14009 + DUMPREG(DSI_VC_IRQSTATUS(2));
14010 + DUMPREG(DSI_VC_IRQENABLE(2));
14012 + DUMPREG(DSI_VC_CTRL(3));
14013 + DUMPREG(DSI_VC_TE(3));
14014 + DUMPREG(DSI_VC_LONG_PACKET_HEADER(3));
14015 + DUMPREG(DSI_VC_LONG_PACKET_PAYLOAD(3));
14016 + DUMPREG(DSI_VC_SHORT_PACKET_HEADER(3));
14017 + DUMPREG(DSI_VC_IRQSTATUS(3));
14018 + DUMPREG(DSI_VC_IRQENABLE(3));
14020 + DUMPREG(DSI_DSIPHY_CFG0);
14021 + DUMPREG(DSI_DSIPHY_CFG1);
14022 + DUMPREG(DSI_DSIPHY_CFG2);
14023 + DUMPREG(DSI_DSIPHY_CFG5);
14025 + DUMPREG(DSI_PLL_CONTROL);
14026 + DUMPREG(DSI_PLL_STATUS);
14027 + DUMPREG(DSI_PLL_GO);
14028 + DUMPREG(DSI_PLL_CONFIGURATION1);
14029 + DUMPREG(DSI_PLL_CONFIGURATION2);
14031 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
14032 +#undef DUMPREG
14035 +enum dsi_complexio_power_state {
14036 + DSI_COMPLEXIO_POWER_OFF = 0x0,
14037 + DSI_COMPLEXIO_POWER_ON = 0x1,
14038 + DSI_COMPLEXIO_POWER_ULPS = 0x2,
14041 +static int dsi_complexio_power(enum dsi_complexio_power_state state)
14043 + int t = 0;
14045 + /* PWR_CMD */
14046 + REG_FLD_MOD(DSI_COMPLEXIO_CFG1, state, 28, 27);
14048 + /* PWR_STATUS */
14049 + while (FLD_GET(dsi_read_reg(DSI_COMPLEXIO_CFG1), 26, 25) != state) {
14050 + udelay(1);
14051 + if (t++ > 1000) {
14052 + DSSERR("failed to set complexio power state to "
14053 + "%d\n", state);
14054 + return -ENODEV;
14058 + return 0;
14061 +static void dsi_complexio_config(struct omap_display *display)
14063 + u32 r;
14065 + int clk_lane = display->hw_config.u.dsi.clk_lane;
14066 + int data1_lane = display->hw_config.u.dsi.data1_lane;
14067 + int data2_lane = display->hw_config.u.dsi.data2_lane;
14068 + int clk_pol = display->hw_config.u.dsi.clk_pol;
14069 + int data1_pol = display->hw_config.u.dsi.data1_pol;
14070 + int data2_pol = display->hw_config.u.dsi.data2_pol;
14072 + r = dsi_read_reg(DSI_COMPLEXIO_CFG1);
14073 + r = FLD_MOD(r, clk_lane, 2, 0);
14074 + r = FLD_MOD(r, clk_pol, 3, 3);
14075 + r = FLD_MOD(r, data1_lane, 6, 4);
14076 + r = FLD_MOD(r, data1_pol, 7, 7);
14077 + r = FLD_MOD(r, data2_lane, 10, 8);
14078 + r = FLD_MOD(r, data2_pol, 11, 11);
14079 + dsi_write_reg(DSI_COMPLEXIO_CFG1, r);
14081 + /* The configuration of the DSI complex I/O (number of data lanes,
14082 + position, differential order) should not be changed while
14083 + DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. In order for
14084 + the hardware to take into account a new configuration of the complex
14085 + I/O (done in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to
14086 + follow this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1,
14087 + then reset the DSS.DSI_CTRL[0] IF_EN to 0, then set
14088 + DSS.DSI_CLK_CTRL[20] LP_CLK_ENABLE to 1 and finally set again the
14089 + DSS.DSI_CTRL[0] IF_EN bit to 1. If the sequence is not followed, the
14090 + DSI complex I/O configuration is unknown. */
14092 + /*
14093 + REG_FLD_MOD(DSI_CTRL, 1, 0, 0);
14094 + REG_FLD_MOD(DSI_CTRL, 0, 0, 0);
14095 + REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20);
14096 + REG_FLD_MOD(DSI_CTRL, 1, 0, 0);
14097 + */
14100 +static inline unsigned ns2ddr(unsigned ns)
14102 + /* convert time in ns to ddr ticks, rounding up */
14103 + return (ns * (dsi.ddr_clk/1000/1000) + 999) / 1000;
14106 +static inline unsigned ddr2ns(unsigned ddr)
14108 + return ddr * 1000 * 1000 / (dsi.ddr_clk / 1000);
14111 +static void dsi_complexio_timings(void)
14113 + u32 r;
14114 + u32 ths_prepare, ths_prepare_ths_zero, ths_trail, ths_exit;
14115 + u32 tlpx_half, tclk_trail, tclk_zero;
14116 + u32 tclk_prepare;
14118 + /* calculate timings */
14120 + /* 1 * DDR_CLK = 2 * UI */
14122 + /* min 40ns + 4*UI max 85ns + 6*UI */
14123 + ths_prepare = ns2ddr(59) + 2;
14125 + /* min 145ns + 10*UI */
14126 + ths_prepare_ths_zero = ns2ddr(145) + 5;
14128 + /* min max(8*UI, 60ns+4*UI) */
14129 + ths_trail = max((unsigned)4, ns2ddr(60) + 2);
14131 + /* min 100ns */
14132 + ths_exit = ns2ddr(100);
14134 + /* tlpx min 50n */
14135 + tlpx_half = ns2ddr(25);
14137 + /* min 60ns */
14138 + tclk_trail = ns2ddr(60);
14140 + /* min 38ns, max 95ns */
14141 + tclk_prepare = ns2ddr(38);
14143 + /* min tclk-prepare + tclk-zero = 300ns */
14144 + tclk_zero = ns2ddr(300 - 38);
14146 + DSSDBG("ths_prepare %u (%uns), ths_prepare_ths_zero %u (%uns)\n",
14147 + ths_prepare, ddr2ns(ths_prepare),
14148 + ths_prepare_ths_zero, ddr2ns(ths_prepare_ths_zero));
14149 + DSSDBG("ths_trail %u (%uns), ths_exit %u (%uns)\n",
14150 + ths_trail, ddr2ns(ths_trail),
14151 + ths_exit, ddr2ns(ths_exit));
14153 + DSSDBG("tlpx_half %u (%uns), tclk_trail %u (%uns), "
14154 + "tclk_zero %u (%uns)\n",
14155 + tlpx_half, ddr2ns(tlpx_half),
14156 + tclk_trail, ddr2ns(tclk_trail),
14157 + tclk_zero, ddr2ns(tclk_zero));
14158 + DSSDBG("tclk_prepare %u (%uns)\n",
14159 + tclk_prepare, ddr2ns(tclk_prepare));
14161 + /* program timings */
14163 + r = dsi_read_reg(DSI_DSIPHY_CFG0);
14164 + r = FLD_MOD(r, ths_prepare, 31, 24);
14165 + r = FLD_MOD(r, ths_prepare_ths_zero, 23, 16);
14166 + r = FLD_MOD(r, ths_trail, 15, 8);
14167 + r = FLD_MOD(r, ths_exit, 7, 0);
14168 + dsi_write_reg(DSI_DSIPHY_CFG0, r);
14170 + r = dsi_read_reg(DSI_DSIPHY_CFG1);
14171 + r = FLD_MOD(r, tlpx_half, 22, 16);
14172 + r = FLD_MOD(r, tclk_trail, 15, 8);
14173 + r = FLD_MOD(r, tclk_zero, 7, 0);
14174 + dsi_write_reg(DSI_DSIPHY_CFG1, r);
14176 + r = dsi_read_reg(DSI_DSIPHY_CFG2);
14177 + r = FLD_MOD(r, tclk_prepare, 7, 0);
14178 + dsi_write_reg(DSI_DSIPHY_CFG2, r);
14182 +static int dsi_complexio_init(struct omap_display *display)
14184 + int r = 0;
14186 + DSSDBG("dsi_complexio_init\n");
14188 + /* CIO_CLK_ICG, enable L3 clk to CIO */
14189 + REG_FLD_MOD(DSI_CLK_CTRL, 1, 14, 14);
14191 + /* A dummy read using the SCP interface to any DSIPHY register is
14192 + * required after DSIPHY reset to complete the reset of the DSI complex
14193 + * I/O. */
14194 + dsi_read_reg(DSI_DSIPHY_CFG5);
14196 + if (wait_for_bit_change(DSI_DSIPHY_CFG5, 30, 1) != 1) {
14197 + DSSERR("ComplexIO PHY not coming out of reset.\n");
14198 + r = -ENODEV;
14199 + goto err;
14202 + dsi_complexio_config(display);
14204 + r = dsi_complexio_power(DSI_COMPLEXIO_POWER_ON);
14206 + if (r)
14207 + goto err;
14209 + if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 29, 1) != 1) {
14210 + DSSERR("ComplexIO not coming out of reset.\n");
14211 + r = -ENODEV;
14212 + goto err;
14215 + if (wait_for_bit_change(DSI_COMPLEXIO_CFG1, 21, 1) != 1) {
14216 + DSSERR("ComplexIO LDO power down.\n");
14217 + r = -ENODEV;
14218 + goto err;
14221 + dsi_complexio_timings();
14223 + /*
14224 + The configuration of the DSI complex I/O (number of data lanes,
14225 + position, differential order) should not be changed while
14226 + DSS.DSI_CLK_CRTRL[20] LP_CLK_ENABLE bit is set to 1. For the
14227 + hardware to recognize a new configuration of the complex I/O (done
14228 + in DSS.DSI_COMPLEXIO_CFG1 register), it is recommended to follow
14229 + this sequence: First set the DSS.DSI_CTRL[0] IF_EN bit to 1, next
14230 + reset the DSS.DSI_CTRL[0] IF_EN to 0, then set DSS.DSI_CLK_CTRL[20]
14231 + LP_CLK_ENABLE to 1, and finally, set again the DSS.DSI_CTRL[0] IF_EN
14232 + bit to 1. If the sequence is not followed, the DSi complex I/O
14233 + configuration is undetermined.
14234 + */
14235 + dsi_if_enable(1);
14236 + dsi_if_enable(0);
14237 + REG_FLD_MOD(DSI_CLK_CTRL, 1, 20, 20); /* LP_CLK_ENABLE */
14238 + dsi_if_enable(1);
14239 + dsi_if_enable(0);
14241 + DSSDBG("CIO init done\n");
14242 +err:
14243 + return r;
14246 +static void dsi_complexio_uninit(void)
14248 + dsi_complexio_power(DSI_COMPLEXIO_POWER_OFF);
14251 +static int _dsi_wait_reset(void)
14253 + int i = 0;
14255 + while (REG_GET(DSI_SYSSTATUS, 0, 0) == 0) {
14256 + if (i++ > 5) {
14257 + DSSERR("soft reset failed\n");
14258 + return -ENODEV;
14260 + udelay(1);
14263 + return 0;
14266 +static int _dsi_reset(void)
14268 + /* Soft reset */
14269 + REG_FLD_MOD(DSI_SYSCONFIG, 1, 1, 1);
14270 + return _dsi_wait_reset();
14274 +static void dsi_config_tx_fifo(enum fifo_size size1, enum fifo_size size2,
14275 + enum fifo_size size3, enum fifo_size size4)
14277 + u32 r = 0;
14278 + int add = 0;
14279 + int i;
14281 + dsi.vc[0].fifo_size = size1;
14282 + dsi.vc[1].fifo_size = size2;
14283 + dsi.vc[2].fifo_size = size3;
14284 + dsi.vc[3].fifo_size = size4;
14286 + for (i = 0; i < 4; i++) {
14287 + u8 v;
14288 + int size = dsi.vc[i].fifo_size;
14290 + if (add + size > 4) {
14291 + DSSERR("Illegal FIFO configuration\n");
14292 + BUG();
14295 + v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4);
14296 + r |= v << (8 * i);
14297 + /*DSSDBG("TX FIFO vc %d: size %d, add %d\n", i, size, add); */
14298 + add += size;
14301 + dsi_write_reg(DSI_TX_FIFO_VC_SIZE, r);
14304 +static void dsi_config_rx_fifo(enum fifo_size size1, enum fifo_size size2,
14305 + enum fifo_size size3, enum fifo_size size4)
14307 + u32 r = 0;
14308 + int add = 0;
14309 + int i;
14311 + dsi.vc[0].fifo_size = size1;
14312 + dsi.vc[1].fifo_size = size2;
14313 + dsi.vc[2].fifo_size = size3;
14314 + dsi.vc[3].fifo_size = size4;
14316 + for (i = 0; i < 4; i++) {
14317 + u8 v;
14318 + int size = dsi.vc[i].fifo_size;
14320 + if (add + size > 4) {
14321 + DSSERR("Illegal FIFO configuration\n");
14322 + BUG();
14325 + v = FLD_VAL(add, 2, 0) | FLD_VAL(size, 7, 4);
14326 + r |= v << (8 * i);
14327 + /*DSSDBG("RX FIFO vc %d: size %d, add %d\n", i, size, add); */
14328 + add += size;
14331 + dsi_write_reg(DSI_RX_FIFO_VC_SIZE, r);
14334 +static int dsi_force_tx_stop_mode_io(void)
14336 + u32 r;
14338 + r = dsi_read_reg(DSI_TIMING1);
14339 + r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
14340 + dsi_write_reg(DSI_TIMING1, r);
14342 + if (wait_for_bit_change(DSI_TIMING1, 15, 0) != 0) {
14343 + DSSERR("TX_STOP bit not going down\n");
14344 + return -EIO;
14347 + return 0;
14350 +static void dsi_vc_print_status(int channel)
14352 + u32 r;
14354 + r = dsi_read_reg(DSI_VC_CTRL(channel));
14355 + DSSDBG("vc %d: TX_FIFO_NOT_EMPTY %d, BTA_EN %d, VC_BUSY %d, "
14356 + "TX_FIFO_FULL %d, RX_FIFO_NOT_EMPTY %d, ",
14357 + channel,
14358 + FLD_GET(r, 5, 5),
14359 + FLD_GET(r, 6, 6),
14360 + FLD_GET(r, 15, 15),
14361 + FLD_GET(r, 16, 16),
14362 + FLD_GET(r, 20, 20));
14364 + r = dsi_read_reg(DSI_TX_FIFO_VC_EMPTINESS);
14365 + DSSDBG("EMPTINESS %d\n", (r >> (8 * channel)) & 0xff);
14368 +static void dsi_vc_config(int channel)
14370 + u32 r;
14372 + DSSDBG("dsi_vc_config %d\n", channel);
14374 + r = dsi_read_reg(DSI_VC_CTRL(channel));
14376 + r = FLD_MOD(r, 0, 1, 1); /* SOURCE, 0 = L4 */
14377 + r = FLD_MOD(r, 0, 2, 2); /* BTA_SHORT_EN */
14378 + r = FLD_MOD(r, 0, 3, 3); /* BTA_LONG_EN */
14379 + r = FLD_MOD(r, 0, 4, 4); /* MODE, 0 = command */
14380 + r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */
14381 + r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
14382 + r = FLD_MOD(r, 0, 9, 9); /* MODE_SPEED, high speed on/off */
14384 + r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
14385 + r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
14387 + dsi_write_reg(DSI_VC_CTRL(channel), r);
14390 +static void dsi_vc_config_vp(int channel)
14392 + u32 r;
14394 + DSSDBG("dsi_vc_config_vp\n");
14396 + r = dsi_read_reg(DSI_VC_CTRL(channel));
14398 + r = FLD_MOD(r, 1, 1, 1); /* SOURCE, 1 = video port */
14399 + r = FLD_MOD(r, 0, 2, 2); /* BTA_SHORT_EN */
14400 + r = FLD_MOD(r, 0, 3, 3); /* BTA_LONG_EN */
14401 + r = FLD_MOD(r, 0, 4, 4); /* MODE, 0 = command */
14402 + r = FLD_MOD(r, 1, 7, 7); /* CS_TX_EN */
14403 + r = FLD_MOD(r, 1, 8, 8); /* ECC_TX_EN */
14404 + r = FLD_MOD(r, 1, 9, 9); /* MODE_SPEED, high speed on/off */
14406 + r = FLD_MOD(r, 4, 29, 27); /* DMA_RX_REQ_NB = no dma */
14407 + r = FLD_MOD(r, 4, 23, 21); /* DMA_TX_REQ_NB = no dma */
14409 + dsi_write_reg(DSI_VC_CTRL(channel), r);
14413 +static int dsi_vc_enable(int channel, bool enable)
14415 + DSSDBG("dsi_vc_enable channel %d, enable %d\n", channel, enable);
14417 + enable = enable ? 1 : 0;
14419 + REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 0, 0);
14421 + if (wait_for_bit_change(DSI_VC_CTRL(channel), 0, enable) != enable) {
14422 + DSSERR("Failed to set dsi_vc_enable to %d\n", enable);
14423 + return -EIO;
14426 + return 0;
14429 +static void dsi_vc_enable_hs(int channel, bool enable)
14431 + DSSDBG("dsi_vc_enable_hs(%d, %d)\n", channel, enable);
14433 + dsi_vc_enable(channel, 0);
14434 + dsi_if_enable(0);
14436 + REG_FLD_MOD(DSI_VC_CTRL(channel), enable, 9, 9);
14438 + dsi_vc_enable(channel, 1);
14439 + dsi_if_enable(1);
14441 + dsi_force_tx_stop_mode_io();
14444 +static void dsi_vc_flush_long_data(int channel)
14446 + while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
14447 + u32 val;
14448 + val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
14449 + DSSDBG("\t\tb1 %#02x b2 %#02x b3 %#02x b4 %#02x\n",
14450 + (val >> 0) & 0xff,
14451 + (val >> 8) & 0xff,
14452 + (val >> 16) & 0xff,
14453 + (val >> 24) & 0xff);
14457 +static void dsi_show_rx_ack_with_err(u16 err)
14459 + DSSERR("\tACK with ERROR (%#x):\n", err);
14460 + if (err & (1 << 0))
14461 + DSSERR("\t\tSoT Error\n");
14462 + if (err & (1 << 1))
14463 + DSSERR("\t\tSoT Sync Error\n");
14464 + if (err & (1 << 2))
14465 + DSSERR("\t\tEoT Sync Error\n");
14466 + if (err & (1 << 3))
14467 + DSSERR("\t\tEscape Mode Entry Command Error\n");
14468 + if (err & (1 << 4))
14469 + DSSERR("\t\tLP Transmit Sync Error\n");
14470 + if (err & (1 << 5))
14471 + DSSERR("\t\tHS Receive Timeout Error\n");
14472 + if (err & (1 << 6))
14473 + DSSERR("\t\tFalse Control Error\n");
14474 + if (err & (1 << 7))
14475 + DSSERR("\t\t(reserved7)\n");
14476 + if (err & (1 << 8))
14477 + DSSERR("\t\tECC Error, single-bit (corrected)\n");
14478 + if (err & (1 << 9))
14479 + DSSERR("\t\tECC Error, multi-bit (not corrected)\n");
14480 + if (err & (1 << 10))
14481 + DSSERR("\t\tChecksum Error\n");
14482 + if (err & (1 << 11))
14483 + DSSERR("\t\tData type not recognized\n");
14484 + if (err & (1 << 12))
14485 + DSSERR("\t\tInvalid VC ID\n");
14486 + if (err & (1 << 13))
14487 + DSSERR("\t\tInvalid Transmission Length\n");
14488 + if (err & (1 << 14))
14489 + DSSERR("\t\t(reserved14)\n");
14490 + if (err & (1 << 15))
14491 + DSSERR("\t\tDSI Protocol Violation\n");
14494 +static u16 dsi_vc_flush_receive_data(int channel)
14496 + /* RX_FIFO_NOT_EMPTY */
14497 + while (REG_GET(DSI_VC_CTRL(channel), 20, 20)) {
14498 + u32 val;
14499 + u8 dt;
14500 + val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
14501 + DSSDBG("\trawval %#08x\n", val);
14502 + dt = FLD_GET(val, 5, 0);
14503 + if (dt == DSI_DT_RX_ACK_WITH_ERR) {
14504 + u16 err = FLD_GET(val, 23, 8);
14505 + dsi_show_rx_ack_with_err(err);
14506 + } else if (dt == DSI_DT_RX_SHORT_READ_1) {
14507 + DSSDBG("\tDCS short response, 1 byte: %#x\n",
14508 + FLD_GET(val, 23, 8));
14509 + } else if (dt == DSI_DT_RX_SHORT_READ_2) {
14510 + DSSDBG("\tDCS short response, 2 byte: %#x\n",
14511 + FLD_GET(val, 23, 8));
14512 + } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
14513 + DSSDBG("\tDCS long response, len %d\n",
14514 + FLD_GET(val, 23, 8));
14515 + dsi_vc_flush_long_data(channel);
14516 + } else {
14517 + DSSERR("\tunknown datatype 0x%02x\n", dt);
14520 + return 0;
14523 +static int dsi_vc_send_bta(int channel)
14525 + unsigned long tmo;
14527 + /*DSSDBG("dsi_vc_send_bta_sync %d\n", channel); */
14529 + if (REG_GET(DSI_VC_CTRL(channel), 20, 20)) { /* RX_FIFO_NOT_EMPTY */
14530 + DSSERR("rx fifo not empty when sending BTA, dumping data:\n");
14531 + dsi_vc_flush_receive_data(channel);
14534 + REG_FLD_MOD(DSI_VC_CTRL(channel), 1, 6, 6); /* BTA_EN */
14536 + tmo = jiffies + msecs_to_jiffies(10);
14537 + while (REG_GET(DSI_VC_CTRL(channel), 6, 6) == 1) {
14538 + if (time_after(jiffies, tmo)) {
14539 + DSSERR("Failed to send BTA\n");
14540 + return -EIO;
14544 + return 0;
14547 +static int dsi_vc_send_bta_sync(int channel)
14549 + int r = 0;
14551 + init_completion(&dsi.bta_completion);
14553 + dsi_vc_enable_bta_irq(channel);
14555 + r = dsi_vc_send_bta(channel);
14556 + if (r)
14557 + goto err;
14559 + if (wait_for_completion_timeout(&dsi.bta_completion,
14560 + msecs_to_jiffies(500)) == 0) {
14561 + DSSERR("Failed to receive BTA\n");
14562 + r = -EIO;
14563 + goto err;
14565 +err:
14566 + dsi_vc_disable_bta_irq(channel);
14568 + return r;
14571 +static inline void dsi_vc_write_long_header(int channel, u8 data_type,
14572 + u16 len, u8 ecc)
14574 + u32 val;
14575 + u8 data_id;
14577 + /*data_id = data_type | channel << 6; */
14578 + data_id = data_type | dsi.vc[channel].dest_per << 6;
14580 + val = FLD_VAL(data_id, 7, 0) | FLD_VAL(len, 23, 8) |
14581 + FLD_VAL(ecc, 31, 24);
14583 + dsi_write_reg(DSI_VC_LONG_PACKET_HEADER(channel), val);
14586 +static inline void dsi_vc_write_long_payload(int channel,
14587 + u8 b1, u8 b2, u8 b3, u8 b4)
14589 + u32 val;
14591 + val = b4 << 24 | b3 << 16 | b2 << 8 | b1 << 0;
14593 +/* DSSDBG("\twriting %02x, %02x, %02x, %02x (%#010x)\n",
14594 + b1, b2, b3, b4, val); */
14596 + dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(channel), val);
14599 +static int dsi_vc_send_long(int channel, u8 data_type, u8 *data, u16 len,
14600 + u8 ecc)
14602 + /*u32 val; */
14603 + int i;
14604 + u8 *p;
14605 + int r = 0;
14606 + u8 b1, b2, b3, b4;
14608 + if (dsi.debug_write)
14609 + DSSDBG("dsi_vc_send_long, %d bytes\n", len);
14611 + /* len + header */
14612 + if (dsi.vc[channel].fifo_size * 32 * 4 < len + 4) {
14613 + DSSERR("unable to send long packet: packet too long.\n");
14614 + return -EINVAL;
14617 + dsi_vc_write_long_header(channel, data_type, len, ecc);
14619 + /*dsi_vc_print_status(0); */
14621 + p = data;
14622 + for (i = 0; i < len >> 2; i++) {
14623 + if (dsi.debug_write)
14624 + DSSDBG("\tsending full packet %d\n", i);
14625 + /*dsi_vc_print_status(0); */
14627 + b1 = *p++;
14628 + b2 = *p++;
14629 + b3 = *p++;
14630 + b4 = *p++;
14632 + dsi_vc_write_long_payload(channel, b1, b2, b3, b4);
14635 + i = len % 4;
14636 + if (i) {
14637 + b1 = 0; b2 = 0; b3 = 0;
14639 + if (dsi.debug_write)
14640 + DSSDBG("\tsending remainder bytes %d\n", i);
14642 + switch (i) {
14643 + case 3:
14644 + b1 = *p++;
14645 + b2 = *p++;
14646 + b3 = *p++;
14647 + break;
14648 + case 2:
14649 + b1 = *p++;
14650 + b2 = *p++;
14651 + break;
14652 + case 1:
14653 + b1 = *p++;
14654 + break;
14657 + dsi_vc_write_long_payload(channel, b1, b2, b3, 0);
14660 + return r;
14663 +static int dsi_vc_send_short(int channel, u8 data_type, u16 data, u8 ecc)
14665 + u32 r;
14666 + u8 data_id;
14668 + if (dsi.debug_write)
14669 + DSSDBG("dsi_vc_send_short(ch%d, dt %#x, b1 %#x, b2 %#x)\n",
14670 + channel,
14671 + data_type, data & 0xff, (data >> 8) & 0xff);
14673 + if (FLD_GET(dsi_read_reg(DSI_VC_CTRL(channel)), 16, 16)) {
14674 + DSSERR("ERROR FIFO FULL, aborting transfer\n");
14675 + return -EINVAL;
14678 + data_id = data_type | channel << 6;
14680 + r = (data_id << 0) | (data << 8) | (ecc << 24);
14682 + dsi_write_reg(DSI_VC_SHORT_PACKET_HEADER(channel), r);
14684 + return 0;
14687 +int dsi_vc_send_null(int channel)
14689 + u8 nullpkg[] = {0, 0, 0, 0};
14690 + return dsi_vc_send_long(0, DSI_DT_NULL_PACKET, nullpkg, 4, 0);
14692 +EXPORT_SYMBOL(dsi_vc_send_null);
14694 +int dsi_vc_dcs_write_nosync(int channel, u8 *data, int len)
14696 + int r;
14698 + BUG_ON(len == 0);
14700 + if (len == 1) {
14701 + r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_0,
14702 + data[0], 0);
14703 + } else if (len == 2) {
14704 + r = dsi_vc_send_short(channel, DSI_DT_DCS_SHORT_WRITE_1,
14705 + data[0] | (data[1] << 8), 0);
14706 + } else {
14707 + /* 0x39 = DCS Long Write */
14708 + r = dsi_vc_send_long(channel, DSI_DT_DCS_LONG_WRITE,
14709 + data, len, 0);
14712 + return r;
14714 +EXPORT_SYMBOL(dsi_vc_dcs_write_nosync);
14716 +int dsi_vc_dcs_write(int channel, u8 *data, int len)
14718 + int r;
14720 + r = dsi_vc_dcs_write_nosync(channel, data, len);
14721 + if (r)
14722 + return r;
14724 + /* Some devices need time to process the msg in low power mode.
14725 + This also makes the write synchronous, and checks that
14726 + the peripheral is still alive */
14727 + r = dsi_vc_send_bta_sync(channel);
14729 + return r;
14731 +EXPORT_SYMBOL(dsi_vc_dcs_write);
14733 +int dsi_vc_dcs_read(int channel, u8 dcs_cmd, u8 *buf, int buflen)
14735 + u32 val;
14736 + u8 dt;
14737 + int r;
14739 + if (dsi.debug_read)
14740 + DSSDBG("dsi_vc_dcs_read\n");
14742 + r = dsi_vc_send_short(channel, DSI_DT_DCS_READ, dcs_cmd, 0);
14743 + if (r)
14744 + return r;
14746 + r = dsi_vc_send_bta_sync(channel);
14747 + if (r)
14748 + return r;
14750 + if (REG_GET(DSI_VC_CTRL(channel), 20, 20) == 0) { /* RX_FIFO_NOT_EMPTY */
14751 + DSSERR("RX fifo empty when trying to read.\n");
14752 + return -EIO;
14755 + val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
14756 + if (dsi.debug_read)
14757 + DSSDBG("\theader: %08x\n", val);
14758 + dt = FLD_GET(val, 5, 0);
14759 + if (dt == DSI_DT_RX_ACK_WITH_ERR) {
14760 + u16 err = FLD_GET(val, 23, 8);
14761 + dsi_show_rx_ack_with_err(err);
14762 + return -1;
14764 + } else if (dt == DSI_DT_RX_SHORT_READ_1) {
14765 + u8 data = FLD_GET(val, 15, 8);
14766 + if (dsi.debug_read)
14767 + DSSDBG("\tDCS short response, 1 byte: %02x\n", data);
14769 + if (buflen < 1)
14770 + return -1;
14772 + buf[0] = data;
14774 + return 1;
14775 + } else if (dt == DSI_DT_RX_SHORT_READ_2) {
14776 + u16 data = FLD_GET(val, 23, 8);
14777 + if (dsi.debug_read)
14778 + DSSDBG("\tDCS short response, 2 byte: %04x\n", data);
14780 + if (buflen < 2)
14781 + return -1;
14783 + buf[0] = data & 0xff;
14784 + buf[1] = (data >> 8) & 0xff;
14786 + return 2;
14787 + } else if (dt == DSI_DT_RX_DCS_LONG_READ) {
14788 + int w;
14789 + int len = FLD_GET(val, 23, 8);
14790 + if (dsi.debug_read)
14791 + DSSDBG("\tDCS long response, len %d\n", len);
14793 + if (len > buflen)
14794 + return -1;
14796 + /* two byte checksum ends the packet, not included in len */
14797 + for (w = 0; w < len + 2;) {
14798 + int b;
14799 + val = dsi_read_reg(DSI_VC_SHORT_PACKET_HEADER(channel));
14800 + if (dsi.debug_read)
14801 + DSSDBG("\t\t%02x %02x %02x %02x\n",
14802 + (val >> 0) & 0xff,
14803 + (val >> 8) & 0xff,
14804 + (val >> 16) & 0xff,
14805 + (val >> 24) & 0xff);
14807 + for (b = 0; b < 4; ++b) {
14808 + if (w < len)
14809 + buf[w] = (val >> (b * 8)) & 0xff;
14810 + /* we discard the 2 byte checksum */
14811 + ++w;
14815 + return len;
14817 + } else {
14818 + DSSERR("\tunknown datatype 0x%02x\n", dt);
14819 + return -1;
14822 +EXPORT_SYMBOL(dsi_vc_dcs_read);
14825 +int dsi_vc_set_max_rx_packet_size(int channel, u16 len)
14827 + return dsi_vc_send_short(channel, DSI_DT_SET_MAX_RET_PKG_SIZE,
14828 + len, 0);
14830 +EXPORT_SYMBOL(dsi_vc_set_max_rx_packet_size);
14833 +static int dsi_set_lp_rx_timeout(int ns, int x4, int x16)
14835 + u32 r;
14836 + unsigned long fck;
14837 + int ticks;
14839 + /* ticks in DSI_FCK */
14841 + fck = dsi_fclk_rate();
14842 + ticks = (fck / 1000 / 1000) * ns / 1000;
14844 + if (ticks > 0x1fff) {
14845 + DSSERR("LP_TX_TO too high\n");
14846 + return -EINVAL;
14849 + r = dsi_read_reg(DSI_TIMING2);
14850 + r = FLD_MOD(r, 1, 15, 15); /* LP_RX_TO */
14851 + r = FLD_MOD(r, x16, 14, 14); /* LP_RX_TO_X16 */
14852 + r = FLD_MOD(r, x4, 13, 13); /* LP_RX_TO_X4 */
14853 + r = FLD_MOD(r, ticks, 12, 0); /* LP_RX_COUNTER */
14854 + dsi_write_reg(DSI_TIMING2, r);
14856 + DSSDBG("LP_RX_TO %ld ns (%#x ticks)\n",
14857 + (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) /
14858 + (fck / 1000 / 1000),
14859 + ticks);
14861 + return 0;
14864 +static int dsi_set_ta_timeout(int ns, int x8, int x16)
14866 + u32 r;
14867 + unsigned long fck;
14868 + int ticks;
14870 + /* ticks in DSI_FCK */
14872 + fck = dsi_fclk_rate();
14873 + ticks = (fck / 1000 / 1000) * ns / 1000;
14875 + if (ticks > 0x1fff) {
14876 + DSSERR("TA_TO too high\n");
14877 + return -EINVAL;
14880 + r = dsi_read_reg(DSI_TIMING1);
14881 + r = FLD_MOD(r, 1, 31, 31); /* TA_TO */
14882 + r = FLD_MOD(r, x16, 30, 30); /* TA_TO_X16 */
14883 + r = FLD_MOD(r, x8, 29, 29); /* TA_TO_X8 */
14884 + r = FLD_MOD(r, ticks, 28, 16); /* TA_TO_COUNTER */
14885 + dsi_write_reg(DSI_TIMING1, r);
14887 + DSSDBG("TA_TO %ld ns (%#x ticks)\n",
14888 + (ticks * (x16 ? 16 : 1) * (x8 ? 8 : 1) * 1000) /
14889 + (fck / 1000 / 1000),
14890 + ticks);
14892 + return 0;
14895 +static int dsi_set_stop_state_counter(int ns, int x4, int x16)
14897 + u32 r;
14898 + unsigned long fck;
14899 + int ticks;
14901 + /* ticks in DSI_FCK */
14903 + fck = dsi_fclk_rate();
14904 + ticks = (fck / 1000 / 1000) * ns / 1000;
14906 + if (ticks > 0x1fff) {
14907 + DSSERR("STOP_STATE_COUNTER_IO too high\n");
14908 + return -EINVAL;
14911 + r = dsi_read_reg(DSI_TIMING1);
14912 + r = FLD_MOD(r, 1, 15, 15); /* FORCE_TX_STOP_MODE_IO */
14913 + r = FLD_MOD(r, x16, 14, 14); /* STOP_STATE_X16_IO */
14914 + r = FLD_MOD(r, x4, 13, 13); /* STOP_STATE_X4_IO */
14915 + r = FLD_MOD(r, ticks, 12, 0); /* STOP_STATE_COUNTER_IO */
14916 + dsi_write_reg(DSI_TIMING1, r);
14918 + DSSDBG("STOP_STATE_COUNTER %ld ns (%#x ticks)\n",
14919 + (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) /
14920 + (fck / 1000 / 1000),
14921 + ticks);
14923 + return 0;
14926 +static int dsi_set_hs_tx_timeout(int ns, int x4, int x16)
14928 + u32 r;
14929 + unsigned long fck;
14930 + int ticks;
14932 + /* ticks in TxByteClkHS */
14934 + fck = dsi.ddr_clk / 4;
14935 + ticks = (fck / 1000 / 1000) * ns / 1000;
14937 + if (ticks > 0x1fff) {
14938 + DSSERR("HS_TX_TO too high\n");
14939 + return -EINVAL;
14942 + r = dsi_read_reg(DSI_TIMING2);
14943 + r = FLD_MOD(r, 1, 31, 31); /* HS_TX_TO */
14944 + r = FLD_MOD(r, x16, 30, 30); /* HS_TX_TO_X16 */
14945 + r = FLD_MOD(r, x4, 29, 29); /* HS_TX_TO_X8 (4 really) */
14946 + r = FLD_MOD(r, ticks, 28, 16); /* HS_TX_TO_COUNTER */
14947 + dsi_write_reg(DSI_TIMING2, r);
14949 + DSSDBG("HS_TX_TO %ld ns (%#x ticks)\n",
14950 + (ticks * (x16 ? 16 : 1) * (x4 ? 4 : 1) * 1000) /
14951 + (fck / 1000 / 1000),
14952 + ticks);
14954 + return 0;
14956 +static int dsi_proto_config(struct omap_display *display)
14958 + u32 r;
14959 + int buswidth = 0;
14961 + dsi_config_tx_fifo(DSI_FIFO_SIZE_128,
14962 + DSI_FIFO_SIZE_0,
14963 + DSI_FIFO_SIZE_0,
14964 + DSI_FIFO_SIZE_0);
14966 + dsi_config_rx_fifo(DSI_FIFO_SIZE_128,
14967 + DSI_FIFO_SIZE_0,
14968 + DSI_FIFO_SIZE_0,
14969 + DSI_FIFO_SIZE_0);
14971 + /* XXX what values for the timeouts? */
14972 + dsi_set_stop_state_counter(1000, 0, 0);
14974 + dsi_set_ta_timeout(50000, 1, 1);
14976 + /* 3000ns * 16 */
14977 + dsi_set_lp_rx_timeout(3000, 0, 1);
14979 + /* 10000ns * 4 */
14980 + dsi_set_hs_tx_timeout(10000, 1, 0);
14982 + switch (display->ctrl->pixel_size) {
14983 + case 16:
14984 + buswidth = 0;
14985 + break;
14986 + case 18:
14987 + buswidth = 1;
14988 + break;
14989 + case 24:
14990 + buswidth = 2;
14991 + break;
14992 + default:
14993 + BUG();
14996 + r = dsi_read_reg(DSI_CTRL);
14997 + r = FLD_MOD(r, 1, 1, 1); /* CS_RX_EN */
14998 + r = FLD_MOD(r, 1, 2, 2); /* ECC_RX_EN */
14999 + r = FLD_MOD(r, 1, 3, 3); /* TX_FIFO_ARBITRATION */
15000 + /* XXX what should the ratio be */
15001 + r = FLD_MOD(r, 0, 4, 4); /* VP_CLK_RATIO, VP_PCLK = VP_CLK/2 */
15002 + r = FLD_MOD(r, buswidth, 7, 6); /* VP_DATA_BUS_WIDTH */
15003 + r = FLD_MOD(r, 0, 8, 8); /* VP_CLK_POL */
15004 + r = FLD_MOD(r, 2, 13, 12); /* LINE_BUFFER, 2 lines */
15005 + r = FLD_MOD(r, 1, 14, 14); /* TRIGGER_RESET_MODE */
15006 + r = FLD_MOD(r, 1, 19, 19); /* EOT_ENABLE */
15007 + r = FLD_MOD(r, 1, 24, 24); /* DCS_CMD_ENABLE */
15008 + r = FLD_MOD(r, 0, 25, 25); /* DCS_CMD_CODE, 1=start, 0=continue */
15010 + dsi_write_reg(DSI_CTRL, r);
15012 + /* we configure vc0 for L4 communication, and
15013 + * vc1 for dispc */
15014 + dsi_vc_config(0);
15015 + dsi_vc_config_vp(1);
15017 + /* set all vc targets to peripheral 0 */
15018 + dsi.vc[0].dest_per = 0;
15019 + dsi.vc[1].dest_per = 0;
15020 + dsi.vc[2].dest_per = 0;
15021 + dsi.vc[3].dest_per = 0;
15023 + return 0;
15026 +static void dsi_proto_timings(void)
15028 + int tlpx_half, tclk_zero, tclk_prepare, tclk_trail;
15029 + int tclk_pre, tclk_post;
15030 + int ddr_clk_pre, ddr_clk_post;
15031 + u32 r;
15033 + r = dsi_read_reg(DSI_DSIPHY_CFG1);
15034 + tlpx_half = FLD_GET(r, 22, 16);
15035 + tclk_trail = FLD_GET(r, 15, 8);
15036 + tclk_zero = FLD_GET(r, 7, 0);
15038 + r = dsi_read_reg(DSI_DSIPHY_CFG2);
15039 + tclk_prepare = FLD_GET(r, 7, 0);
15041 + /* min 8*UI */
15042 + tclk_pre = 20;
15043 + /* min 60ns + 52*UI */
15044 + tclk_post = ns2ddr(60) + 26;
15046 + ddr_clk_pre = (tclk_pre + tlpx_half*2 + tclk_zero + tclk_prepare) / 4;
15047 + ddr_clk_post = (tclk_post + tclk_trail) / 4;
15049 + r = dsi_read_reg(DSI_CLK_TIMING);
15050 + r = FLD_MOD(r, ddr_clk_pre, 15, 8);
15051 + r = FLD_MOD(r, ddr_clk_post, 7, 0);
15052 + dsi_write_reg(DSI_CLK_TIMING, r);
15054 + DSSDBG("ddr_clk_pre %d, ddr_clk_post %d\n",
15055 + ddr_clk_pre,
15056 + ddr_clk_post);
15060 +#define DSI_DECL_VARS \
15061 + int __dsi_cb = 0; u32 __dsi_cv = 0;
15063 +#define DSI_FLUSH(ch) \
15064 + if (__dsi_cb > 0) { \
15065 + /*DSSDBG("sending long packet %#010x\n", __dsi_cv);*/ \
15066 + dsi_write_reg(DSI_VC_LONG_PACKET_PAYLOAD(ch), __dsi_cv); \
15067 + __dsi_cb = __dsi_cv = 0; \
15070 +#define DSI_PUSH(ch, data) \
15071 + do { \
15072 + __dsi_cv |= (data) << (__dsi_cb * 8); \
15073 + /*DSSDBG("cv = %#010x, cb = %d\n", __dsi_cv, __dsi_cb);*/ \
15074 + if (++__dsi_cb > 3) \
15075 + DSI_FLUSH(ch); \
15076 + } while (0)
15078 +static int dsi_update_screen_l4(struct omap_display *display,
15079 + int x, int y, int w, int h)
15081 + /* Note: supports only 24bit colors in 32bit container */
15082 + int first = 1;
15083 + int fifo_stalls = 0;
15084 + int max_dsi_packet_size;
15085 + int max_data_per_packet;
15086 + int max_pixels_per_packet;
15087 + int pixels_left;
15088 + int bytespp = 3;
15089 + int scr_width;
15090 + u32 __iomem *data;
15091 + int start_offset;
15092 + int horiz_inc;
15093 + int current_x;
15094 + struct omap_overlay *ovl;
15096 + debug_irq = 0;
15098 + DSSDBG("dsi_update_screen_l4 (%d,%d %dx%d)\n",
15099 + x, y, w, h);
15101 + ovl = display->manager->overlays[0];
15103 + if (ovl->info.color_mode != OMAP_DSS_COLOR_RGB24U)
15104 + return -EINVAL;
15106 + if (display->ctrl->pixel_size != 24)
15107 + return -EINVAL;
15109 + scr_width = ovl->info.screen_width;
15110 + data = ovl->info.vaddr;
15112 + start_offset = scr_width * y + x;
15113 + horiz_inc = scr_width - w;
15114 + current_x = x;
15116 + /* We need header(4) + DCSCMD(1) + pixels(numpix*bytespp) bytes
15117 + * in fifo */
15119 + /* When using CPU, max long packet size is TX buffer size */
15120 + max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4;
15122 + /* we seem to get better perf if we divide the tx fifo to half,
15123 + and while the other half is being sent, we fill the other half
15124 + max_dsi_packet_size /= 2; */
15126 + max_data_per_packet = max_dsi_packet_size - 4 - 1;
15128 + max_pixels_per_packet = max_data_per_packet / bytespp;
15130 + DSSDBG("max_pixels_per_packet %d\n", max_pixels_per_packet);
15132 + display->ctrl->setup_update(display, x, y, w, h);
15134 + pixels_left = w * h;
15136 + DSSDBG("total pixels %d\n", pixels_left);
15138 + data += start_offset;
15140 + dsi.update_region.x = x;
15141 + dsi.update_region.y = y;
15142 + dsi.update_region.w = w;
15143 + dsi.update_region.h = h;
15144 + dsi.update_region.bytespp = bytespp;
15146 + perf_mark_start();
15148 + while (pixels_left > 0) {
15149 + /* 0x2c = write_memory_start */
15150 + /* 0x3c = write_memory_continue */
15151 + u8 dcs_cmd = first ? 0x2c : 0x3c;
15152 + int pixels;
15153 + DSI_DECL_VARS;
15154 + first = 0;
15156 +#if 1
15157 + /* using fifo not empty */
15158 + /* TX_FIFO_NOT_EMPTY */
15159 + while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) {
15160 + udelay(1);
15161 + fifo_stalls++;
15162 + if (fifo_stalls > 0xfffff) {
15163 + DSSERR("fifo stalls overflow, pixels left %d\n",
15164 + pixels_left);
15165 + dsi_if_enable(0);
15166 + return -EIO;
15169 +#elif 1
15170 + /* using fifo emptiness */
15171 + while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 <
15172 + max_dsi_packet_size) {
15173 + fifo_stalls++;
15174 + if (fifo_stalls > 0xfffff) {
15175 + DSSERR("fifo stalls overflow, pixels left %d\n",
15176 + pixels_left);
15177 + dsi_if_enable(0);
15178 + return -EIO;
15181 +#else
15182 + while ((REG_GET(DSI_TX_FIFO_VC_EMPTINESS, 7, 0)+1)*4 == 0) {
15183 + fifo_stalls++;
15184 + if (fifo_stalls > 0xfffff) {
15185 + DSSERR("fifo stalls overflow, pixels left %d\n",
15186 + pixels_left);
15187 + dsi_if_enable(0);
15188 + return -EIO;
15191 +#endif
15192 + pixels = min(max_pixels_per_packet, pixels_left);
15194 + pixels_left -= pixels;
15196 + dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE,
15197 + 1 + pixels * bytespp, 0);
15199 + DSI_PUSH(0, dcs_cmd);
15201 + while (pixels-- > 0) {
15202 + u32 pix = __raw_readl(data++);
15204 + DSI_PUSH(0, (pix >> 16) & 0xff);
15205 + DSI_PUSH(0, (pix >> 8) & 0xff);
15206 + DSI_PUSH(0, (pix >> 0) & 0xff);
15208 + current_x++;
15209 + if (current_x == x+w) {
15210 + current_x = x;
15211 + data += horiz_inc;
15215 + DSI_FLUSH(0);
15218 + perf_show("L4");
15220 + return 0;
15223 +#if 0
15224 +static void dsi_clear_screen_l4(struct omap_display *display,
15225 + int x, int y, int w, int h)
15227 + int first = 1;
15228 + int fifo_stalls = 0;
15229 + int max_dsi_packet_size;
15230 + int max_data_per_packet;
15231 + int max_pixels_per_packet;
15232 + int pixels_left;
15233 + int bytespp = 3;
15234 + int pixnum;
15236 + debug_irq = 0;
15238 + DSSDBG("dsi_clear_screen_l4 (%d,%d %dx%d)\n",
15239 + x, y, w, h);
15241 + if (display->ctrl->bpp != 24)
15242 + return -EINVAL;
15244 + /* We need header(4) + DCSCMD(1) + pixels(numpix*bytespp)
15245 + * bytes in fifo */
15247 + /* When using CPU, max long packet size is TX buffer size */
15248 + max_dsi_packet_size = dsi.vc[0].fifo_size * 32 * 4;
15250 + max_data_per_packet = max_dsi_packet_size - 4 - 1;
15252 + max_pixels_per_packet = max_data_per_packet / bytespp;
15254 + enable_clocks(1);
15256 + display->ctrl->setup_update(display, x, y, w, h);
15258 + pixels_left = w * h;
15260 + dsi.update_region.x = x;
15261 + dsi.update_region.y = y;
15262 + dsi.update_region.w = w;
15263 + dsi.update_region.h = h;
15264 + dsi.update_region.bytespp = bytespp;
15266 + start_measuring();
15268 + pixnum = 0;
15270 + while (pixels_left > 0) {
15271 + /* 0x2c = write_memory_start */
15272 + /* 0x3c = write_memory_continue */
15273 + u8 dcs_cmd = first ? 0x2c : 0x3c;
15274 + int pixels;
15275 + DSI_DECL_VARS;
15276 + first = 0;
15278 + /* TX_FIFO_NOT_EMPTY */
15279 + while (FLD_GET(dsi_read_reg(DSI_VC_CTRL(0)), 5, 5)) {
15280 + fifo_stalls++;
15281 + if (fifo_stalls > 0xfffff) {
15282 + DSSERR("fifo stalls overflow\n");
15283 + dsi_if_enable(0);
15284 + enable_clocks(0);
15285 + return;
15289 + pixels = min(max_pixels_per_packet, pixels_left);
15291 + pixels_left -= pixels;
15293 + dsi_vc_write_long_header(0, DSI_DT_DCS_LONG_WRITE,
15294 + 1 + pixels * bytespp, 0);
15296 + DSI_PUSH(0, dcs_cmd);
15298 + while (pixels-- > 0) {
15299 + u32 pix;
15301 + pix = 0x000000;
15303 + DSI_PUSH(0, (pix >> 16) & 0xff);
15304 + DSI_PUSH(0, (pix >> 8) & 0xff);
15305 + DSI_PUSH(0, (pix >> 0) & 0xff);
15308 + DSI_FLUSH(0);
15311 + enable_clocks(0);
15313 + end_measuring("L4 CLEAR");
15315 +#endif
15317 +static void dsi_setup_update_dispc(struct omap_display *display,
15318 + u16 x, u16 y, u16 w, u16 h)
15320 + int bytespp = 3;
15322 + DSSDBG("dsi_setup_update_dispc(%d,%d %dx%d)\n",
15323 + x, y, w, h);
15325 + dsi.update_region.display = display;
15326 + dsi.update_region.x = x;
15327 + dsi.update_region.y = y;
15328 + dsi.update_region.w = w;
15329 + dsi.update_region.h = h;
15330 + dsi.update_region.bytespp = bytespp;
15332 + dispc_setup_partial_planes(display, &x, &y, &w, &h);
15334 + dispc_set_lcd_size(w, h);
15337 +static void dsi_update_screen_dispc(struct omap_display *display)
15339 + int bytespp = 3;
15340 + int total_len;
15341 + int line_packet_len;
15342 + u16 x, y, w, h;
15343 + u32 l;
15345 + x = dsi.update_region.x;
15346 + y = dsi.update_region.y;
15347 + w = dsi.update_region.w;
15348 + h = dsi.update_region.h;
15350 + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL)
15351 + DSSDBG("dsi_update_screen_dispc(%d,%d %dx%d)\n",
15352 + x, y, w, h);
15354 + /* TODO: one packet could be longer, I think? Max is the line buffer */
15355 + line_packet_len = w * bytespp + 1; /* 1 byte for DCS cmd */
15356 + total_len = line_packet_len * h;
15358 + display->ctrl->setup_update(display, x, y, w, h);
15360 + if (0)
15361 + dsi_vc_print_status(1);
15363 + perf_mark_start();
15365 + l = FLD_VAL(total_len, 23, 0); /* TE_SIZE */
15366 + dsi_write_reg(DSI_VC_TE(1), l);
15368 + dsi_vc_write_long_header(1, DSI_DT_DCS_LONG_WRITE, line_packet_len, 0);
15370 + if (dsi.use_te)
15371 + l = FLD_MOD(l, 1, 30, 30); /* TE_EN */
15372 + else
15373 + l = FLD_MOD(l, 1, 31, 31); /* TE_START */
15374 + dsi_write_reg(DSI_VC_TE(1), l);
15376 + dispc_enable_lcd_out(1);
15378 + if (dsi.use_te)
15379 + dsi_vc_send_bta(1);
15382 +static void framedone_callback(void *data, u32 mask)
15384 + if (dsi.framedone_scheduled) {
15385 + DSSERR("Framedone already scheduled. Bogus FRAMEDONE IRQ?\n");
15386 + return;
15389 + dsi.framedone_scheduled = 1;
15391 + /* We get FRAMEDONE when DISPC has finished sending pixels and turns
15392 + * itself off. However, DSI still has the pixels in its buffers, and
15393 + * is sending the data. Thus we have to wait until we can do a new
15394 + * transfer or turn the clocks off. We do that in a separate work
15395 + * func. */
15396 + queue_work(dsi.framedone_workqueue, &dsi.framedone_work);
15399 +static void framedone_worker(struct work_struct *work)
15401 + u32 l;
15402 + unsigned long tmo;
15403 + int i = 0;
15405 + l = REG_GET(DSI_VC_TE(1), 23, 0); /* TE_SIZE */
15407 + /* There shouldn't be much stuff in DSI buffers, if any, so we'll
15408 + * just busyloop */
15409 + if (l > 0) {
15410 + tmo = jiffies + msecs_to_jiffies(50);
15411 + while (REG_GET(DSI_VC_TE(1), 23, 0) > 0) { /* TE_SIZE */
15412 + i++;
15413 + if (time_after(jiffies, tmo)) {
15414 + DSSERR("timeout waiting TE_SIZE to zero\n");
15415 + break;
15417 + cpu_relax();
15421 + if (REG_GET(DSI_VC_TE(1), 30, 30))
15422 + DSSERR("TE_EN not zero\n");
15424 + if (REG_GET(DSI_VC_TE(1), 31, 31))
15425 + DSSERR("TE_START not zero\n");
15427 + perf_show("DISPC");
15429 + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL)
15430 + DSSDBG("FRAMEDONE\n");
15432 +#if 0
15433 + if (l)
15434 + DSSWARN("FRAMEDONE irq too early, %d bytes, %d loops\n", l, i);
15435 +#else
15436 + if (l > 1024*3)
15437 + DSSWARN("FRAMEDONE irq too early, %d bytes, %d loops\n", l, i);
15438 +#endif
15440 +#ifdef CONFIG_OMAP2_DSS_FAKE_VSYNC
15441 + dispc_fake_vsync_irq();
15442 +#endif
15443 + dsi.framedone_scheduled = 0;
15445 + /* XXX check that fifo is not full. otherwise we would sleep and never
15446 + * get to process_cmd_fifo below */
15447 + /* We check for target_update_mode, not update_mode. No reason to push
15448 + * new updates if we're turning auto update off */
15449 + if (dsi.target_update_mode == OMAP_DSS_UPDATE_AUTO)
15450 + dsi_push_update(dsi.update_region.display,
15451 + dsi.update_region.x,
15452 + dsi.update_region.y,
15453 + dsi.update_region.w,
15454 + dsi.update_region.h);
15456 + atomic_set(&dsi.cmd_pending, 0);
15457 + dsi_process_cmd_fifo();
15460 +static void dsi_start_auto_update(struct omap_display *display)
15462 + int bytespp = 3;
15463 + u16 w, h;
15465 + DSSDBG("starting auto update\n");
15467 + display->get_resolution(display, &w, &h);
15469 + dsi.update_region.display = display;
15470 + dsi.update_region.x = 0;
15471 + dsi.update_region.y = 0;
15472 + dsi.update_region.w = w;
15473 + dsi.update_region.h = h;
15474 + dsi.update_region.bytespp = bytespp;
15476 + /* the overlay settings may not have been applied, if we were in manual
15477 + * mode earlier, so do it here */
15478 + display->manager->apply(display->manager);
15480 + dispc_set_lcd_size(w, h);
15482 + dsi_push_update(dsi.update_region.display,
15483 + dsi.update_region.x,
15484 + dsi.update_region.y,
15485 + dsi.update_region.w,
15486 + dsi.update_region.h);
15501 +/* FIFO functions */
15503 +static void dsi_signal_fifo_waiters(void)
15505 + if (atomic_read(&dsi.cmd_fifo_full) > 0) {
15506 + DSSDBG("SIGNALING: Fifo not full for waiter!\n");
15507 + complete(&dsi.cmd_done);
15508 + atomic_dec(&dsi.cmd_fifo_full);
15512 +/* returns 1 for async op, and 0 for sync op */
15513 +static int dsi_do_update(struct omap_display *display,
15514 + struct dsi_cmd_update *upd)
15516 + int r;
15517 + u16 x = upd->x, y = upd->y, w = upd->w, h = upd->h;
15518 + u16 dw, dh;
15520 + if (dsi.update_mode == OMAP_DSS_UPDATE_DISABLED)
15521 + return 0;
15523 + display->get_resolution(display, &dw, &dh);
15524 + if (x > dw || y > dh)
15525 + return 0;
15527 + if (x + w > dw)
15528 + w = dw - x;
15530 + if (y + h > dh)
15531 + h = dh - y;
15533 + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL)
15534 + DSSDBGF("%d,%d %dx%d", x, y, w, h);
15536 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
15537 + return 0;
15539 + perf_mark_setup();
15541 + if (display->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
15542 + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL)
15543 + dsi_setup_update_dispc(display, x, y, w, h);
15544 + dsi_update_screen_dispc(display);
15545 + return 1;
15546 + } else {
15547 + r = dsi_update_screen_l4(display, x, y, w, h);
15548 + if (r)
15549 + DSSERR("L4 update failed\n");
15550 + return 0;
15554 +static void dsi_do_cmd_mem_read(struct omap_display *display,
15555 + struct dsi_cmd_mem_read *mem_read)
15557 + int r;
15558 + r = display->ctrl->memory_read(display,
15559 + mem_read->buf,
15560 + mem_read->size,
15561 + mem_read->x,
15562 + mem_read->y,
15563 + mem_read->w,
15564 + mem_read->h);
15566 + *mem_read->ret_size = (size_t)r;
15567 + complete(mem_read->completion);
15570 +static void dsi_do_cmd_test(struct omap_display *display,
15571 + struct dsi_cmd_test *test)
15573 + int r = 0;
15575 + DSSDBGF("");
15577 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
15578 + return;
15580 + /* run test first in low speed mode */
15581 + dsi_vc_enable_hs(0, 0);
15583 + if (display->ctrl->run_test) {
15584 + r = display->ctrl->run_test(display, test->test_num);
15585 + if (r)
15586 + goto end;
15589 + if (display->panel->run_test) {
15590 + r = display->panel->run_test(display, test->test_num);
15591 + if (r)
15592 + goto end;
15595 + /* then in high speed */
15596 + dsi_vc_enable_hs(0, 1);
15598 + if (display->ctrl->run_test) {
15599 + r = display->ctrl->run_test(display, test->test_num);
15600 + if (r)
15601 + goto end;
15604 + if (display->panel->run_test)
15605 + r = display->panel->run_test(display, test->test_num);
15607 +end:
15608 + dsi_vc_enable_hs(0, 1);
15610 + *test->result = r;
15611 + complete(test->completion);
15613 + DSSDBG("test end\n");
15616 +static void dsi_do_cmd_set_te(struct omap_display *display, bool enable)
15618 + dsi.use_te = enable;
15620 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
15621 + return;
15623 + display->ctrl->enable_te(display, enable);
15625 + if (enable) {
15626 + /* disable LP_RX_TO, so that we can receive TE.
15627 + * Time to wait for TE is longer than the timer allows */
15628 + REG_FLD_MOD(DSI_TIMING2, 0, 15, 15); /* LP_RX_TO */
15629 + } else {
15630 + REG_FLD_MOD(DSI_TIMING2, 1, 15, 15); /* LP_RX_TO */
15634 +static void dsi_do_cmd_set_update_mode(struct omap_display *display,
15635 + enum omap_dss_update_mode mode)
15637 + dsi.update_mode = mode;
15639 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
15640 + return;
15642 + if (mode == OMAP_DSS_UPDATE_AUTO)
15643 + dsi_start_auto_update(display);
15646 +static void dsi_process_cmd_fifo(void)
15648 + int len;
15649 + struct dsi_cmd_item p;
15650 + unsigned long flags;
15651 + struct omap_display *display;
15652 + int exit = 0;
15654 + if (dsi.debug_process)
15655 + DSSDBGF("");
15657 + if (atomic_cmpxchg(&dsi.cmd_pending, 0, 1) == 1) {
15658 + if (dsi.debug_process)
15659 + DSSDBG("cmd pending, skip process\n");
15660 + return;
15663 + while (!exit) {
15664 + spin_lock_irqsave(dsi.cmd_fifo->lock, flags);
15666 + len = __kfifo_get(dsi.cmd_fifo, (unsigned char *)&p,
15667 + sizeof(p));
15668 + if (len == 0) {
15669 + if (dsi.debug_process)
15670 + DSSDBG("nothing more in fifo, atomic clear\n");
15671 + atomic_set(&dsi.cmd_pending, 0);
15672 + spin_unlock_irqrestore(dsi.cmd_fifo->lock, flags);
15673 + break;
15676 + spin_unlock_irqrestore(dsi.cmd_fifo->lock, flags);
15678 + BUG_ON(len != sizeof(p));
15680 + display = p.display;
15682 + switch (p.cmd) {
15683 + case DSI_CMD_UPDATE:
15684 + if (dsi_do_update(display, &p.u.r)) {
15685 + if (dsi.debug_process)
15686 + DSSDBG("async update\n");
15687 + exit = 1;
15688 + } else {
15689 + if (dsi.debug_process)
15690 + DSSDBG("sync update\n");
15692 + break;
15694 + case DSI_CMD_SYNC:
15695 + if (dsi.debug_process)
15696 + DSSDBG("Signaling SYNC done!\n");
15697 + complete(p.u.sync);
15698 + break;
15700 + case DSI_CMD_MEM_READ:
15701 + dsi_do_cmd_mem_read(display, &p.u.mem_read);
15702 + break;
15704 + case DSI_CMD_TEST:
15705 + dsi_do_cmd_test(display, &p.u.test);
15706 + break;
15708 + case DSI_CMD_SET_TE:
15709 + dsi_do_cmd_set_te(display, p.u.te);
15710 + break;
15712 + case DSI_CMD_SET_UPDATE_MODE:
15713 + dsi_do_cmd_set_update_mode(display, p.u.update_mode);
15714 + break;
15716 + case DSI_CMD_SET_ROTATE:
15717 + display->ctrl->set_rotate(display, p.u.rotate);
15718 + break;
15720 + case DSI_CMD_SET_MIRROR:
15721 + display->ctrl->set_mirror(display, p.u.mirror);
15722 + break;
15724 + default:
15725 + BUG();
15729 + if (dsi.debug_process)
15730 + DSSDBG("exit dsi_process_cmd_fifo\n");
15732 + dsi_signal_fifo_waiters();
15735 +static void dsi_push_cmd(struct dsi_cmd_item *p)
15737 + int ret;
15739 + if (dsi.debug_process)
15740 + DSSDBGF("");
15742 + while (1) {
15743 + unsigned long flags;
15744 + int available;
15746 + spin_lock_irqsave(dsi.cmd_fifo->lock, flags);
15747 + available = DSI_CMD_FIFO_LEN_BYTES - __kfifo_len(dsi.cmd_fifo);
15749 + if (dsi.debug_process)
15750 + DSSDBG("%d items left in fifo\n",
15751 + available / sizeof(*p));
15752 + if (available < sizeof(*p)) {
15753 + if (dsi.debug_process)
15754 + DSSDBG("cmd fifo full, waiting...\n");
15755 + spin_unlock_irqrestore(dsi.cmd_fifo->lock, flags);
15756 + atomic_inc(&dsi.cmd_fifo_full);
15757 + wait_for_completion(&dsi.cmd_done);
15758 + if (dsi.debug_process)
15759 + DSSDBG("cmd fifo not full, woke up\n");
15760 + continue;
15763 + ret = __kfifo_put(dsi.cmd_fifo, (unsigned char *)p,
15764 + sizeof(*p));
15766 + spin_unlock_irqrestore(dsi.cmd_fifo->lock, flags);
15768 + BUG_ON(ret != sizeof(*p));
15770 + break;
15773 + dsi_process_cmd_fifo();
15776 +static void dsi_push_update(struct omap_display *display,
15777 + int x, int y, int w, int h)
15779 + struct dsi_cmd_item p;
15781 + p.display = display;
15782 + p.cmd = DSI_CMD_UPDATE;
15784 + p.u.r.x = x;
15785 + p.u.r.y = y;
15786 + p.u.r.w = w;
15787 + p.u.r.h = h;
15789 + if (dsi.update_mode == OMAP_DSS_UPDATE_MANUAL)
15790 + DSSDBG("pushing UPDATE %d,%d %dx%d\n", x, y, w, h);
15792 + dsi_push_cmd(&p);
15795 +static void dsi_push_sync(struct omap_display *display,
15796 + struct completion *sync_comp)
15798 + struct dsi_cmd_item p;
15800 + p.display = display;
15801 + p.cmd = DSI_CMD_SYNC;
15802 + p.u.sync = sync_comp;
15804 + DSSDBG("pushing SYNC\n");
15806 + dsi_push_cmd(&p);
15809 +static void dsi_push_mem_read(struct omap_display *display,
15810 + struct dsi_cmd_mem_read *mem_read)
15812 + struct dsi_cmd_item p;
15814 + p.display = display;
15815 + p.cmd = DSI_CMD_MEM_READ;
15816 + p.u.mem_read = *mem_read;
15818 + DSSDBG("pushing MEM_READ\n");
15820 + dsi_push_cmd(&p);
15823 +static void dsi_push_test(struct omap_display *display, int test_num,
15824 + int *result, struct completion *completion)
15826 + struct dsi_cmd_item p;
15828 + p.display = display;
15829 + p.cmd = DSI_CMD_TEST;
15830 + p.u.test.test_num = test_num;
15831 + p.u.test.result = result;
15832 + p.u.test.completion = completion;
15834 + DSSDBG("pushing TEST\n");
15836 + dsi_push_cmd(&p);
15839 +static void dsi_push_set_te(struct omap_display *display, bool enable)
15841 + struct dsi_cmd_item p;
15843 + p.display = display;
15844 + p.cmd = DSI_CMD_SET_TE;
15845 + p.u.te = enable;
15847 + DSSDBG("pushing SET_TE\n");
15849 + dsi_push_cmd(&p);
15852 +static void dsi_push_set_update_mode(struct omap_display *display,
15853 + enum omap_dss_update_mode mode)
15855 + struct dsi_cmd_item p;
15857 + p.display = display;
15858 + p.cmd = DSI_CMD_SET_UPDATE_MODE;
15859 + p.u.update_mode = mode;
15861 + DSSDBG("pushing SET_UPDATE_MODE\n");
15863 + dsi_push_cmd(&p);
15866 +static void dsi_push_set_rotate(struct omap_display *display, int rotate)
15868 + struct dsi_cmd_item p;
15870 + p.display = display;
15871 + p.cmd = DSI_CMD_SET_ROTATE;
15872 + p.u.rotate = rotate;
15874 + DSSDBG("pushing SET_ROTATE\n");
15876 + dsi_push_cmd(&p);
15879 +static void dsi_push_set_mirror(struct omap_display *display, int mirror)
15881 + struct dsi_cmd_item p;
15883 + p.display = display;
15884 + p.cmd = DSI_CMD_SET_MIRROR;
15885 + p.u.mirror = mirror;
15887 + DSSDBG("pushing SET_MIRROR\n");
15889 + dsi_push_cmd(&p);
15892 +static int dsi_wait_sync(struct omap_display *display)
15894 + long wait = msecs_to_jiffies(60000);
15895 + struct completion compl;
15897 + DSSDBGF("");
15899 + init_completion(&compl);
15900 + dsi_push_sync(display, &compl);
15902 + DSSDBG("Waiting for SYNC to happen...\n");
15903 + wait = wait_for_completion_timeout(&compl, wait);
15904 + DSSDBG("Released from SYNC\n");
15906 + if (wait == 0) {
15907 + DSSERR("timeout waiting sync\n");
15908 + return -ETIME;
15911 + return 0;
15925 +/* Display funcs */
15927 +static int dsi_display_init_dispc(struct omap_display *display)
15929 + int r;
15931 + r = omap_dispc_register_isr(framedone_callback, NULL,
15932 + DISPC_IRQ_FRAMEDONE);
15933 + if (r) {
15934 + DSSERR("can't get FRAMEDONE irq\n");
15935 + return r;
15938 + dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT);
15940 + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_DSI);
15941 + dispc_enable_fifohandcheck(1);
15943 + dispc_set_tft_data_lines(display->ctrl->pixel_size);
15946 + struct omap_video_timings timings = {
15947 + .hsw = 1,
15948 + .hfp = 1,
15949 + .hbp = 1,
15950 + .vsw = 1,
15951 + .vfp = 0,
15952 + .vbp = 0,
15953 + };
15955 + dispc_set_lcd_timings(&timings);
15958 + return 0;
15961 +static void dsi_display_uninit_dispc(struct omap_display *display)
15963 + omap_dispc_unregister_isr(framedone_callback, NULL,
15964 + DISPC_IRQ_FRAMEDONE);
15967 +static int dsi_display_init_dsi(struct omap_display *display)
15969 + struct dsi_clock_info cinfo;
15970 + int r;
15972 + _dsi_print_reset_status();
15974 + r = dsi_pll_init(1, 0);
15975 + if (r)
15976 + goto err0;
15978 + r = dsi_pll_calc_ddrfreq(display->hw_config.u.dsi.ddr_clk_hz, &cinfo);
15979 + if (r)
15980 + goto err1;
15982 + r = dsi_pll_program(&cinfo);
15983 + if (r)
15984 + goto err1;
15986 + DSSDBG("PLL OK\n");
15988 + r = dsi_complexio_init(display);
15989 + if (r)
15990 + goto err1;
15992 + _dsi_print_reset_status();
15994 + dsi_proto_timings();
15995 + dsi_set_lp_clk_divisor();
15997 + if (1)
15998 + _dsi_print_reset_status();
16000 + r = dsi_proto_config(display);
16001 + if (r)
16002 + goto err2;
16004 + /* enable interface */
16005 + dsi_vc_enable(0, 1);
16006 + dsi_vc_enable(1, 1);
16007 + dsi_if_enable(1);
16008 + dsi_force_tx_stop_mode_io();
16010 + if (display->ctrl && display->ctrl->enable) {
16011 + r = display->ctrl->enable(display);
16012 + if (r)
16013 + goto err3;
16016 + if (display->panel && display->panel->enable) {
16017 + r = display->panel->enable(display);
16018 + if (r)
16019 + goto err4;
16022 + /* enable high-speed after initial config */
16023 + dsi_vc_enable_hs(0, 1);
16025 + return 0;
16026 +err4:
16027 + if (display->ctrl && display->ctrl->disable)
16028 + display->ctrl->disable(display);
16029 +err3:
16030 + dsi_if_enable(0);
16031 +err2:
16032 + dsi_complexio_uninit();
16033 +err1:
16034 + dsi_pll_uninit();
16035 +err0:
16036 + return r;
16039 +static void dsi_display_uninit_dsi(struct omap_display *display)
16041 + if (display->panel && display->panel->disable)
16042 + display->panel->disable(display);
16043 + if (display->ctrl && display->ctrl->disable)
16044 + display->ctrl->disable(display);
16046 + dsi_complexio_uninit();
16047 + dsi_pll_uninit();
16050 +static int dsi_core_init(void)
16052 + /* Autoidle */
16053 + REG_FLD_MOD(DSI_SYSCONFIG, 1, 0, 0);
16055 + /* ENWAKEUP */
16056 + REG_FLD_MOD(DSI_SYSCONFIG, 1, 2, 2);
16058 + /* SIDLEMODE smart-idle */
16059 + REG_FLD_MOD(DSI_SYSCONFIG, 2, 4, 3);
16061 + _dsi_initialize_irq();
16063 + return 0;
16066 +static int dsi_display_enable(struct omap_display *display)
16068 + int r = 0;
16070 + DSSDBG("dsi_display_enable\n");
16072 + mutex_lock(&dsi.lock);
16074 + if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
16075 + DSSERR("display already enabled\n");
16076 + r = -EINVAL;
16077 + goto err0;
16080 + enable_clocks(1);
16081 + dsi_enable_pll_clock(1);
16083 + r = _dsi_reset();
16084 + if (r)
16085 + return r;
16087 + dsi_core_init();
16089 + r = dsi_display_init_dispc(display);
16090 + if (r)
16091 + goto err1;
16093 + r = dsi_display_init_dsi(display);
16094 + if (r)
16095 + goto err2;
16097 + display->state = OMAP_DSS_DISPLAY_ACTIVE;
16099 + if (dsi.use_te)
16100 + dsi_push_set_te(display, 1);
16102 + dsi_push_set_update_mode(display, dsi.user_update_mode);
16103 + dsi.target_update_mode = dsi.user_update_mode;
16105 + mutex_unlock(&dsi.lock);
16107 + return 0;
16109 +err2:
16110 + dsi_display_uninit_dispc(display);
16111 +err1:
16112 + enable_clocks(0);
16113 + dsi_enable_pll_clock(0);
16114 +err0:
16115 + mutex_unlock(&dsi.lock);
16116 + DSSDBG("dsi_display_enable FAILED\n");
16117 + return r;
16120 +static void dsi_display_disable(struct omap_display *display)
16122 + DSSDBG("dsi_display_disable\n");
16124 + mutex_lock(&dsi.lock);
16126 + if (display->state == OMAP_DSS_DISPLAY_DISABLED ||
16127 + display->state == OMAP_DSS_DISPLAY_SUSPENDED)
16128 + goto end;
16130 + if (dsi.target_update_mode != OMAP_DSS_UPDATE_DISABLED) {
16131 + dsi_push_set_update_mode(display, OMAP_DSS_UPDATE_DISABLED);
16132 + dsi.target_update_mode = OMAP_DSS_UPDATE_DISABLED;
16135 + dsi_wait_sync(display);
16137 + display->state = OMAP_DSS_DISPLAY_DISABLED;
16139 + dsi_display_uninit_dispc(display);
16141 + dsi_display_uninit_dsi(display);
16143 + enable_clocks(0);
16144 + dsi_enable_pll_clock(0);
16145 +end:
16146 + mutex_unlock(&dsi.lock);
16149 +static int dsi_display_suspend(struct omap_display *display)
16151 + DSSDBG("dsi_display_suspend\n");
16153 + dsi_display_disable(display);
16155 + display->state = OMAP_DSS_DISPLAY_SUSPENDED;
16157 + return 0;
16160 +static int dsi_display_resume(struct omap_display *display)
16162 + DSSDBG("dsi_display_resume\n");
16164 + display->state = OMAP_DSS_DISPLAY_DISABLED;
16165 + return dsi_display_enable(display);
16168 +static int dsi_display_update(struct omap_display *display,
16169 + u16 x, u16 y, u16 w, u16 h)
16171 + DSSDBG("dsi_display_update(%d,%d %dx%d)\n", x, y, w, h);
16173 + if (w == 0 || h == 0)
16174 + return 0;
16176 + mutex_lock(&dsi.lock);
16178 + if (dsi.target_update_mode == OMAP_DSS_UPDATE_MANUAL)
16179 + dsi_push_update(display, x, y, w, h);
16180 + /* XXX else return error? */
16182 + mutex_unlock(&dsi.lock);
16184 + return 0;
16187 +static int dsi_display_sync(struct omap_display *display)
16189 + DSSDBGF("");
16190 + return dsi_wait_sync(display);
16193 +static int dsi_display_set_update_mode(struct omap_display *display,
16194 + enum omap_dss_update_mode mode)
16196 + DSSDBGF("%d", mode);
16198 + mutex_lock(&dsi.lock);
16200 + if (dsi.target_update_mode != mode) {
16201 + dsi_push_set_update_mode(display, mode);
16203 + dsi.target_update_mode = mode;
16204 + dsi.user_update_mode = mode;
16207 + mutex_unlock(&dsi.lock);
16209 + return 0;
16212 +static enum omap_dss_update_mode dsi_display_get_update_mode(
16213 + struct omap_display *display)
16215 + return dsi.update_mode;
16218 +static int dsi_display_enable_te(struct omap_display *display, bool enable)
16220 + DSSDBGF("%d", enable);
16222 + if (!display->ctrl->enable_te)
16223 + return -ENOENT;
16225 + dsi_push_set_te(display, enable);
16227 + return 0;
16230 +static int dsi_display_get_te(struct omap_display *display)
16232 + return dsi.use_te;
16237 +static int dsi_display_set_rotate(struct omap_display *display, u8 rotate)
16239 + DSSDBGF("%d", rotate);
16241 + if (!display->ctrl->set_rotate || !display->ctrl->get_rotate)
16242 + return -EINVAL;
16244 + dsi_push_set_rotate(display, rotate);
16246 + return 0;
16249 +static u8 dsi_display_get_rotate(struct omap_display *display)
16251 + if (!display->ctrl->set_rotate || !display->ctrl->get_rotate)
16252 + return 0;
16254 + return display->ctrl->get_rotate(display);
16257 +static int dsi_display_set_mirror(struct omap_display *display, bool mirror)
16259 + DSSDBGF("%d", mirror);
16261 + if (!display->ctrl->set_mirror || !display->ctrl->get_mirror)
16262 + return -EINVAL;
16264 + dsi_push_set_mirror(display, mirror);
16266 + return 0;
16269 +static bool dsi_display_get_mirror(struct omap_display *display)
16271 + if (!display->ctrl->set_mirror || !display->ctrl->get_mirror)
16272 + return 0;
16274 + return display->ctrl->get_mirror(display);
16277 +static int dsi_display_run_test(struct omap_display *display, int test_num)
16279 + long wait = msecs_to_jiffies(60000);
16280 + struct completion compl;
16281 + int result;
16283 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
16284 + return -EIO;
16286 + DSSDBGF("%d", test_num);
16288 + init_completion(&compl);
16290 + dsi_push_test(display, test_num, &result, &compl);
16292 + DSSDBG("Waiting for SYNC to happen...\n");
16293 + wait = wait_for_completion_timeout(&compl, wait);
16294 + DSSDBG("Released from SYNC\n");
16296 + if (wait == 0) {
16297 + DSSERR("timeout waiting test sync\n");
16298 + return -ETIME;
16301 + return result;
16304 +static int dsi_display_memory_read(struct omap_display *display,
16305 + void *buf, size_t size,
16306 + u16 x, u16 y, u16 w, u16 h)
16308 + long wait = msecs_to_jiffies(60000);
16309 + struct completion compl;
16310 + struct dsi_cmd_mem_read mem_read;
16311 + size_t ret_size;
16313 + DSSDBGF("");
16315 + if (!display->ctrl->memory_read)
16316 + return -EINVAL;
16318 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
16319 + return -EIO;
16321 + init_completion(&compl);
16323 + mem_read.x = x;
16324 + mem_read.y = y;
16325 + mem_read.w = w;
16326 + mem_read.h = h;
16327 + mem_read.buf = buf;
16328 + mem_read.size = size;
16329 + mem_read.ret_size = &ret_size;
16330 + mem_read.completion = &compl;
16332 + dsi_push_mem_read(display, &mem_read);
16334 + DSSDBG("Waiting for SYNC to happen...\n");
16335 + wait = wait_for_completion_timeout(&compl, wait);
16336 + DSSDBG("Released from SYNC\n");
16338 + if (wait == 0) {
16339 + DSSERR("timeout waiting mem read sync\n");
16340 + return -ETIME;
16343 + return ret_size;
16346 +static void dsi_configure_overlay(struct omap_overlay *ovl)
16348 + unsigned low, high, size;
16349 + enum omap_burst_size burst;
16350 + enum omap_plane plane = ovl->id;
16352 + burst = OMAP_DSS_BURST_16x32;
16353 + size = 16 * 32 / 8;
16355 + dispc_set_burst_size(plane, burst);
16357 + high = dispc_get_plane_fifo_size(plane) - size;
16358 + low = 0;
16359 + dispc_setup_plane_fifo(plane, low, high);
16362 +void dsi_init_display(struct omap_display *display)
16364 + DSSDBG("DSI init\n");
16366 + display->enable = dsi_display_enable;
16367 + display->disable = dsi_display_disable;
16368 + display->suspend = dsi_display_suspend;
16369 + display->resume = dsi_display_resume;
16370 + display->update = dsi_display_update;
16371 + display->sync = dsi_display_sync;
16372 + display->set_update_mode = dsi_display_set_update_mode;
16373 + display->get_update_mode = dsi_display_get_update_mode;
16374 + display->enable_te = dsi_display_enable_te;
16375 + display->get_te = dsi_display_get_te;
16377 + display->get_rotate = dsi_display_get_rotate;
16378 + display->set_rotate = dsi_display_set_rotate;
16380 + display->get_mirror = dsi_display_get_mirror;
16381 + display->set_mirror = dsi_display_set_mirror;
16383 + display->run_test = dsi_display_run_test;
16384 + display->memory_read = dsi_display_memory_read;
16386 + display->configure_overlay = dsi_configure_overlay;
16388 + display->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
16391 +int dsi_init(void)
16393 + u32 rev;
16395 + spin_lock_init(&dsi.cmd_lock);
16396 + dsi.cmd_fifo = kfifo_alloc(DSI_CMD_FIFO_LEN_BYTES, GFP_KERNEL,
16397 + &dsi.cmd_lock);
16399 + init_completion(&dsi.cmd_done);
16400 + atomic_set(&dsi.cmd_fifo_full, 0);
16401 + atomic_set(&dsi.cmd_pending, 0);
16403 + init_completion(&dsi.bta_completion);
16405 + dsi.framedone_workqueue = create_singlethread_workqueue("dsi");
16406 + INIT_WORK(&dsi.framedone_work, framedone_worker);
16408 + mutex_init(&dsi.lock);
16410 + dsi.target_update_mode = OMAP_DSS_UPDATE_DISABLED;
16411 + dsi.user_update_mode = OMAP_DSS_UPDATE_DISABLED;
16413 + dsi.base = ioremap(DSI_BASE, DSI_SZ_REGS);
16414 + if (!dsi.base) {
16415 + DSSERR("can't ioremap DSI\n");
16416 + return -ENOMEM;
16419 + enable_clocks(1);
16421 + rev = dsi_read_reg(DSI_REVISION);
16422 + printk(KERN_INFO "OMAP DSI rev %d.%d\n",
16423 + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
16425 + enable_clocks(0);
16427 + return 0;
16430 +void dsi_exit(void)
16432 + flush_workqueue(dsi.framedone_workqueue);
16433 + destroy_workqueue(dsi.framedone_workqueue);
16435 + iounmap(dsi.base);
16437 + kfifo_free(dsi.cmd_fifo);
16439 + DSSDBG("omap_dsi_exit\n");
16442 diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/omap2/dss/dss.c
16443 new file mode 100644
16444 index 0000000..adc1f34
16445 --- /dev/null
16446 +++ b/drivers/video/omap2/dss/dss.c
16447 @@ -0,0 +1,345 @@
16449 + * linux/drivers/video/omap2/dss/dss.c
16451 + * Copyright (C) 2009 Nokia Corporation
16452 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
16454 + * Some code and ideas taken from drivers/video/omap/ driver
16455 + * by Imre Deak.
16457 + * This program is free software; you can redistribute it and/or modify it
16458 + * under the terms of the GNU General Public License version 2 as published by
16459 + * the Free Software Foundation.
16461 + * This program is distributed in the hope that it will be useful, but WITHOUT
16462 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16463 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16464 + * more details.
16466 + * You should have received a copy of the GNU General Public License along with
16467 + * this program. If not, see <http://www.gnu.org/licenses/>.
16468 + */
16470 +#define DSS_SUBSYS_NAME "DSS"
16472 +#include <linux/kernel.h>
16473 +#include <linux/io.h>
16474 +#include <linux/err.h>
16475 +#include <linux/delay.h>
16476 +#include <linux/interrupt.h>
16477 +#include <linux/seq_file.h>
16479 +#include <mach/display.h>
16480 +#include "dss.h"
16482 +#define DSS_BASE 0x48050000
16484 +#define DSS_SZ_REGS SZ_512
16486 +struct dss_reg {
16487 + u16 idx;
16490 +#define DSS_REG(idx) ((const struct dss_reg) { idx })
16492 +#define DSS_REVISION DSS_REG(0x0000)
16493 +#define DSS_SYSCONFIG DSS_REG(0x0010)
16494 +#define DSS_SYSSTATUS DSS_REG(0x0014)
16495 +#define DSS_IRQSTATUS DSS_REG(0x0018)
16496 +#define DSS_CONTROL DSS_REG(0x0040)
16497 +#define DSS_SDI_CONTROL DSS_REG(0x0044)
16498 +#define DSS_PLL_CONTROL DSS_REG(0x0048)
16499 +#define DSS_SDI_STATUS DSS_REG(0x005C)
16501 +#define REG_GET(idx, start, end) \
16502 + FLD_GET(dss_read_reg(idx), start, end)
16504 +#define REG_FLD_MOD(idx, val, start, end) \
16505 + dss_write_reg(idx, FLD_MOD(dss_read_reg(idx), val, start, end))
16507 +static struct {
16508 + void __iomem *base;
16510 + u32 ctx[DSS_SZ_REGS / sizeof(u32)];
16511 +} dss;
16513 +static int _omap_dss_wait_reset(void);
16515 +static inline void dss_write_reg(const struct dss_reg idx, u32 val)
16517 + __raw_writel(val, dss.base + idx.idx);
16520 +static inline u32 dss_read_reg(const struct dss_reg idx)
16522 + return __raw_readl(dss.base + idx.idx);
16525 +#define SR(reg) \
16526 + dss.ctx[(DSS_##reg).idx / sizeof(u32)] = dss_read_reg(DSS_##reg)
16527 +#define RR(reg) \
16528 + dss_write_reg(DSS_##reg, dss.ctx[(DSS_##reg).idx / sizeof(u32)])
16530 +void dss_save_context(void)
16532 + if (cpu_is_omap24xx())
16533 + return;
16535 + SR(SYSCONFIG);
16536 + SR(CONTROL);
16538 +#ifdef CONFIG_OMAP2_DSS_SDI
16539 + SR(SDI_CONTROL);
16540 + SR(PLL_CONTROL);
16541 +#endif
16544 +void dss_restore_context(void)
16546 + if (_omap_dss_wait_reset())
16547 + DSSERR("DSS not coming out of reset after sleep\n");
16549 + RR(SYSCONFIG);
16550 + RR(CONTROL);
16552 +#ifdef CONFIG_OMAP2_DSS_SDI
16553 + RR(SDI_CONTROL);
16554 + RR(PLL_CONTROL);
16555 +#endif
16558 +#undef SR
16559 +#undef RR
16561 +void dss_sdi_init(u8 datapairs)
16563 + u32 l;
16565 + BUG_ON(datapairs > 3 || datapairs < 1);
16567 + l = dss_read_reg(DSS_SDI_CONTROL);
16568 + l = FLD_MOD(l, 0xf, 19, 15); /* SDI_PDIV */
16569 + l = FLD_MOD(l, datapairs-1, 3, 2); /* SDI_PRSEL */
16570 + l = FLD_MOD(l, 2, 1, 0); /* SDI_BWSEL */
16571 + dss_write_reg(DSS_SDI_CONTROL, l);
16573 + l = dss_read_reg(DSS_PLL_CONTROL);
16574 + l = FLD_MOD(l, 0x7, 25, 22); /* SDI_PLL_FREQSEL */
16575 + l = FLD_MOD(l, 0xb, 16, 11); /* SDI_PLL_REGN */
16576 + l = FLD_MOD(l, 0xb4, 10, 1); /* SDI_PLL_REGM */
16577 + dss_write_reg(DSS_PLL_CONTROL, l);
16580 +void dss_sdi_enable(void)
16582 + dispc_pck_free_enable(1);
16584 + /* Reset SDI PLL */
16585 + REG_FLD_MOD(DSS_PLL_CONTROL, 1, 18, 18); /* SDI_PLL_SYSRESET */
16586 + udelay(1); /* wait 2x PCLK */
16588 + /* Lock SDI PLL */
16589 + REG_FLD_MOD(DSS_PLL_CONTROL, 1, 28, 28); /* SDI_PLL_GOBIT */
16591 + /* Waiting for PLL lock request to complete */
16592 + while (dss_read_reg(DSS_SDI_STATUS) & (1 << 6))
16595 + /* Clearing PLL_GO bit */
16596 + REG_FLD_MOD(DSS_PLL_CONTROL, 0, 28, 28);
16598 + /* Waiting for PLL to lock */
16599 + while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 5)))
16602 + dispc_lcd_enable_signal(1);
16604 + /* Waiting for SDI reset to complete */
16605 + while (!(dss_read_reg(DSS_SDI_STATUS) & (1 << 2)))
16609 +void dss_sdi_disable(void)
16611 + dispc_lcd_enable_signal(0);
16613 + dispc_pck_free_enable(0);
16615 + /* Reset SDI PLL */
16616 + REG_FLD_MOD(DSS_PLL_CONTROL, 0, 18, 18); /* SDI_PLL_SYSRESET */
16619 +void dss_dump_regs(struct seq_file *s)
16621 +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, dss_read_reg(r))
16623 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
16625 + DUMPREG(DSS_REVISION);
16626 + DUMPREG(DSS_SYSCONFIG);
16627 + DUMPREG(DSS_SYSSTATUS);
16628 + DUMPREG(DSS_IRQSTATUS);
16629 + DUMPREG(DSS_CONTROL);
16630 + DUMPREG(DSS_SDI_CONTROL);
16631 + DUMPREG(DSS_PLL_CONTROL);
16632 + DUMPREG(DSS_SDI_STATUS);
16634 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
16635 +#undef DUMPREG
16638 +void dss_select_clk_source(bool dsi, bool dispc)
16640 + u32 r;
16641 + r = dss_read_reg(DSS_CONTROL);
16642 + r = FLD_MOD(r, dsi, 1, 1); /* DSI_CLK_SWITCH */
16643 + r = FLD_MOD(r, dispc, 0, 0); /* DISPC_CLK_SWITCH */
16644 + dss_write_reg(DSS_CONTROL, r);
16647 +int dss_get_dsi_clk_source(void)
16649 + return FLD_GET(dss_read_reg(DSS_CONTROL), 1, 1);
16652 +int dss_get_dispc_clk_source(void)
16654 + return FLD_GET(dss_read_reg(DSS_CONTROL), 0, 0);
16657 +static irqreturn_t dss_irq_handler_omap2(int irq, void *arg)
16659 + dispc_irq_handler();
16661 + return IRQ_HANDLED;
16664 +static irqreturn_t dss_irq_handler_omap3(int irq, void *arg)
16666 + u32 irqstatus;
16668 + irqstatus = dss_read_reg(DSS_IRQSTATUS);
16670 + if (irqstatus & (1<<0)) /* DISPC_IRQ */
16671 + dispc_irq_handler();
16672 +#ifdef CONFIG_OMAP2_DSS_DSI
16673 + if (irqstatus & (1<<1)) /* DSI_IRQ */
16674 + dsi_irq_handler();
16675 +#endif
16677 + return IRQ_HANDLED;
16680 +static int _omap_dss_wait_reset(void)
16682 + unsigned timeout = 1000;
16684 + while (REG_GET(DSS_SYSSTATUS, 0, 0) == 0) {
16685 + udelay(1);
16686 + if (!--timeout) {
16687 + DSSERR("soft reset failed\n");
16688 + return -ENODEV;
16692 + return 0;
16695 +static int _omap_dss_reset(void)
16697 + /* Soft reset */
16698 + REG_FLD_MOD(DSS_SYSCONFIG, 1, 1, 1);
16699 + return _omap_dss_wait_reset();
16702 +void dss_set_venc_output(enum omap_dss_venc_type type)
16704 + int l = 0;
16706 + if (type == OMAP_DSS_VENC_TYPE_COMPOSITE)
16707 + l = 0;
16708 + else if (type == OMAP_DSS_VENC_TYPE_SVIDEO)
16709 + l = 1;
16710 + else
16711 + BUG();
16713 + /* venc out selection. 0 = comp, 1 = svideo */
16714 + REG_FLD_MOD(DSS_CONTROL, l, 6, 6);
16717 +void dss_set_dac_pwrdn_bgz(bool enable)
16719 + REG_FLD_MOD(DSS_CONTROL, enable, 5, 5); /* DAC Power-Down Control */
16722 +int dss_init(bool skip_init)
16724 + int r;
16725 + u32 rev;
16727 + dss.base = ioremap(DSS_BASE, DSS_SZ_REGS);
16728 + if (!dss.base) {
16729 + DSSERR("can't ioremap DSS\n");
16730 + r = -ENOMEM;
16731 + goto fail0;
16734 + if (!skip_init) {
16735 + /* We need to wait here a bit, otherwise we sometimes start to
16736 + * get synclost errors, and after that only power cycle will
16737 + * restore DSS functionality. I have no idea why this happens.
16738 + * And we have to wait _before_ resetting the DSS, but after
16739 + * enabling clocks.
16740 + */
16741 + msleep(50);
16743 + _omap_dss_reset();
16746 + else
16747 + printk("DSS SKIP RESET\n");
16749 + /* autoidle */
16750 + REG_FLD_MOD(DSS_SYSCONFIG, 1, 0, 0);
16752 + /* Select DPLL */
16753 + REG_FLD_MOD(DSS_CONTROL, 0, 0, 0);
16755 +#ifdef CONFIG_OMAP2_DSS_VENC
16756 + REG_FLD_MOD(DSS_CONTROL, 1, 4, 4); /* venc dac demen */
16757 + REG_FLD_MOD(DSS_CONTROL, 1, 3, 3); /* venc clock 4x enable */
16758 + REG_FLD_MOD(DSS_CONTROL, 0, 2, 2); /* venc clock mode = normal */
16759 +#endif
16761 + r = request_irq(INT_24XX_DSS_IRQ,
16762 + cpu_is_omap24xx()
16763 + ? dss_irq_handler_omap2
16764 + : dss_irq_handler_omap3,
16765 + 0, "OMAP DSS", NULL);
16767 + if (r < 0) {
16768 + DSSERR("omap2 dss: request_irq failed\n");
16769 + goto fail1;
16772 + dss_save_context();
16774 + rev = dss_read_reg(DSS_REVISION);
16775 + printk(KERN_INFO "OMAP DSS rev %d.%d\n",
16776 + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
16778 + return 0;
16780 +fail1:
16781 + iounmap(dss.base);
16782 +fail0:
16783 + return r;
16786 +void dss_exit(void)
16788 + free_irq(INT_24XX_DSS_IRQ, NULL);
16790 + iounmap(dss.base);
16793 diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/omap2/dss/dss.h
16794 new file mode 100644
16795 index 0000000..2013ae4
16796 --- /dev/null
16797 +++ b/drivers/video/omap2/dss/dss.h
16798 @@ -0,0 +1,326 @@
16800 + * linux/drivers/video/omap2/dss/dss.h
16802 + * Copyright (C) 2009 Nokia Corporation
16803 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
16805 + * Some code and ideas taken from drivers/video/omap/ driver
16806 + * by Imre Deak.
16808 + * This program is free software; you can redistribute it and/or modify it
16809 + * under the terms of the GNU General Public License version 2 as published by
16810 + * the Free Software Foundation.
16812 + * This program is distributed in the hope that it will be useful, but WITHOUT
16813 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16814 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16815 + * more details.
16817 + * You should have received a copy of the GNU General Public License along with
16818 + * this program. If not, see <http://www.gnu.org/licenses/>.
16819 + */
16821 +#ifndef __OMAP2_DSS_H
16822 +#define __OMAP2_DSS_H
16824 +#ifdef CONFIG_OMAP2_DSS_DEBUG_SUPPORT
16825 +#define DEBUG
16826 +#endif
16828 +#ifdef DEBUG
16829 +extern unsigned int dss_debug;
16830 +#ifdef DSS_SUBSYS_NAME
16831 +#define DSSDBG(format, ...) \
16832 + if (dss_debug) \
16833 + printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME ": " format, \
16834 + ## __VA_ARGS__)
16835 +#else
16836 +#define DSSDBG(format, ...) \
16837 + if (dss_debug) \
16838 + printk(KERN_DEBUG "omapdss: " format, ## __VA_ARGS__)
16839 +#endif
16841 +#ifdef DSS_SUBSYS_NAME
16842 +#define DSSDBGF(format, ...) \
16843 + if (dss_debug) \
16844 + printk(KERN_DEBUG "omapdss " DSS_SUBSYS_NAME \
16845 + ": %s(" format ")\n", \
16846 + __func__, \
16847 + ## __VA_ARGS__)
16848 +#else
16849 +#define DSSDBGF(format, ...) \
16850 + if (dss_debug) \
16851 + printk(KERN_DEBUG "omapdss: " \
16852 + ": %s(" format ")\n", \
16853 + __func__, \
16854 + ## __VA_ARGS__)
16855 +#endif
16857 +#else /* DEBUG */
16858 +#define DSSDBG(format, ...)
16859 +#define DSSDBGF(format, ...)
16860 +#endif
16863 +#ifdef DSS_SUBSYS_NAME
16864 +#define DSSERR(format, ...) \
16865 + printk(KERN_ERR "omapdss " DSS_SUBSYS_NAME " error: " format, \
16866 + ## __VA_ARGS__)
16867 +#else
16868 +#define DSSERR(format, ...) \
16869 + printk(KERN_ERR "omapdss error: " format, ## __VA_ARGS__)
16870 +#endif
16872 +#ifdef DSS_SUBSYS_NAME
16873 +#define DSSINFO(format, ...) \
16874 + printk(KERN_INFO "omapdss " DSS_SUBSYS_NAME ": " format, \
16875 + ## __VA_ARGS__)
16876 +#else
16877 +#define DSSINFO(format, ...) \
16878 + printk(KERN_INFO "omapdss: " format, ## __VA_ARGS__)
16879 +#endif
16881 +#ifdef DSS_SUBSYS_NAME
16882 +#define DSSWARN(format, ...) \
16883 + printk(KERN_WARNING "omapdss " DSS_SUBSYS_NAME ": " format, \
16884 + ## __VA_ARGS__)
16885 +#else
16886 +#define DSSWARN(format, ...) \
16887 + printk(KERN_WARNING "omapdss: " format, ## __VA_ARGS__)
16888 +#endif
16890 +/* OMAP TRM gives bitfields as start:end, where start is the higher bit
16891 + number. For example 7:0 */
16892 +#define FLD_MASK(start, end) (((1 << (start - end + 1)) - 1) << (end))
16893 +#define FLD_VAL(val, start, end) (((val) << end) & FLD_MASK(start, end))
16894 +#define FLD_GET(val, start, end) (((val) & FLD_MASK(start, end)) >> (end))
16895 +#define FLD_MOD(orig, val, start, end) \
16896 + (((orig) & ~FLD_MASK(start, end)) | FLD_VAL(val, start, end))
16898 +#define DISPC_MAX_FCK 173000000
16900 +enum omap_burst_size {
16901 + OMAP_DSS_BURST_4x32 = 0,
16902 + OMAP_DSS_BURST_8x32 = 1,
16903 + OMAP_DSS_BURST_16x32 = 2,
16906 +enum omap_parallel_interface_mode {
16907 + OMAP_DSS_PARALLELMODE_BYPASS, /* MIPI DPI */
16908 + OMAP_DSS_PARALLELMODE_RFBI, /* MIPI DBI */
16909 + OMAP_DSS_PARALLELMODE_DSI,
16912 +enum dss_clock {
16913 + DSS_CLK_ICK = 1 << 0,
16914 + DSS_CLK_FCK1 = 1 << 1,
16915 + DSS_CLK_FCK2 = 1 << 2,
16916 + DSS_CLK_54M = 1 << 3,
16917 + DSS_CLK_96M = 1 << 4,
16920 +struct dispc_clock_info {
16921 + /* rates that we get with dividers below */
16922 + unsigned long fck;
16923 + unsigned long lck;
16924 + unsigned long pck;
16926 + /* dividers */
16927 + u16 fck_div;
16928 + u16 lck_div;
16929 + u16 pck_div;
16932 +struct dsi_clock_info {
16933 + /* rates that we get with dividers below */
16934 + unsigned long fint;
16935 + unsigned long dsiphy;
16936 + unsigned long clkin;
16937 + unsigned long dsi1_pll_fclk;
16938 + unsigned long dsi2_pll_fclk;
16939 + unsigned long lck;
16940 + unsigned long pck;
16942 + /* dividers */
16943 + u16 regn;
16944 + u16 regm;
16945 + u16 regm3;
16946 + u16 regm4;
16948 + u16 lck_div;
16949 + u16 pck_div;
16951 + u8 highfreq;
16952 + bool use_dss2_fck;
16955 +struct seq_file;
16956 +struct platform_device;
16958 +/* core */
16959 +void dss_clk_enable(enum dss_clock clks);
16960 +void dss_clk_disable(enum dss_clock clks);
16961 +unsigned long dss_clk_get_rate(enum dss_clock clk);
16962 +int dss_need_ctx_restore(void);
16963 +void dss_dump_clocks(struct seq_file *s);
16965 +int dss_dsi_power_up(void);
16966 +void dss_dsi_power_down(void);
16968 +/* display */
16969 +void dss_init_displays(struct platform_device *pdev);
16970 +void dss_uninit_displays(struct platform_device *pdev);
16971 +int dss_suspend_all_displays(void);
16972 +int dss_resume_all_displays(void);
16973 +struct omap_display *dss_get_display(int no);
16975 +/* manager */
16976 +int dss_init_overlay_managers(struct platform_device *pdev);
16977 +void dss_uninit_overlay_managers(struct platform_device *pdev);
16979 +/* overlay */
16980 +void dss_init_overlays(struct platform_device *pdev, const char *def_disp_name);
16981 +void dss_uninit_overlays(struct platform_device *pdev);
16982 +int dss_check_overlay(struct omap_overlay *ovl, struct omap_display *display);
16983 +void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr);
16985 +/* DSS */
16986 +int dss_init(bool skip_init);
16987 +void dss_exit(void);
16989 +void dss_save_context(void);
16990 +void dss_restore_context(void);
16992 +void dss_dump_regs(struct seq_file *s);
16994 +void dss_sdi_init(u8 datapairs);
16995 +void dss_sdi_enable(void);
16996 +void dss_sdi_disable(void);
16998 +void dss_select_clk_source(bool dsi, bool dispc);
16999 +int dss_get_dsi_clk_source(void);
17000 +int dss_get_dispc_clk_source(void);
17001 +void dss_set_venc_output(enum omap_dss_venc_type type);
17002 +void dss_set_dac_pwrdn_bgz(bool enable);
17004 +/* SDI */
17005 +int sdi_init(bool skip_init);
17006 +void sdi_exit(void);
17007 +void sdi_init_display(struct omap_display *display);
17009 +/* DSI */
17010 +int dsi_init(void);
17011 +void dsi_exit(void);
17013 +void dsi_dump_clocks(struct seq_file *s);
17014 +void dsi_dump_regs(struct seq_file *s);
17016 +void dsi_save_context(void);
17017 +void dsi_restore_context(void);
17019 +void dsi_init_display(struct omap_display *display);
17020 +void dsi_irq_handler(void);
17021 +unsigned long dsi_get_dsi1_pll_rate(void);
17022 +unsigned long dsi_get_dsi2_pll_rate(void);
17023 +int dsi_pll_calc_pck(bool is_tft, unsigned long req_pck,
17024 + struct dsi_clock_info *cinfo);
17025 +int dsi_pll_program(struct dsi_clock_info *cinfo);
17026 +int dsi_pll_init(bool enable_hsclk, bool enable_hsdiv);
17027 +void dsi_pll_uninit(void);
17029 +/* DPI */
17030 +int dpi_init(void);
17031 +void dpi_exit(void);
17032 +void dpi_init_display(struct omap_display *display);
17034 +/* DISPC */
17035 +int dispc_init(void);
17036 +void dispc_exit(void);
17037 +void dispc_dump_clocks(struct seq_file *s);
17038 +void dispc_dump_regs(struct seq_file *s);
17039 +void dispc_irq_handler(void);
17040 +void dispc_fake_vsync_irq(void);
17042 +void dispc_save_context(void);
17043 +void dispc_restore_context(void);
17045 +void dispc_lcd_enable_signal_polarity(bool act_high);
17046 +void dispc_lcd_enable_signal(bool enable);
17047 +void dispc_pck_free_enable(bool enable);
17048 +void dispc_enable_fifohandcheck(bool enable);
17050 +void dispc_set_lcd_size(u16 width, u16 height);
17051 +void dispc_set_digit_size(u16 width, u16 height);
17052 +u32 dispc_get_plane_fifo_size(enum omap_plane plane);
17053 +void dispc_setup_plane_fifo(enum omap_plane plane, u32 low, u32 high);
17054 +void dispc_enable_fifomerge(bool enable);
17055 +void dispc_set_burst_size(enum omap_plane plane,
17056 + enum omap_burst_size burst_size);
17058 +void dispc_set_plane_ba0(enum omap_plane plane, u32 paddr);
17059 +void dispc_set_plane_ba1(enum omap_plane plane, u32 paddr);
17060 +void dispc_set_plane_pos(enum omap_plane plane, u16 x, u16 y);
17061 +void dispc_set_plane_size(enum omap_plane plane, u16 width, u16 height);
17063 +int dispc_setup_plane(enum omap_plane plane, enum omap_channel channel_out,
17064 + u32 paddr, u16 screen_width,
17065 + u16 pos_x, u16 pos_y,
17066 + u16 width, u16 height,
17067 + u16 out_width, u16 out_height,
17068 + enum omap_color_mode color_mode,
17069 + bool ilace,
17070 + u8 rotation, bool mirror);
17072 +void dispc_go(enum omap_channel channel);
17073 +void dispc_enable_lcd_out(bool enable);
17074 +void dispc_enable_digit_out(bool enable);
17075 +int dispc_enable_plane(enum omap_plane plane, bool enable);
17077 +void dispc_set_parallel_interface_mode(enum omap_parallel_interface_mode mode);
17078 +void dispc_set_tft_data_lines(u8 data_lines);
17079 +void dispc_set_lcd_display_type(enum omap_lcd_display_type type);
17080 +void dispc_set_loadmode(enum omap_dss_load_mode mode);
17082 +void dispc_set_default_color(enum omap_channel channel, u32 color);
17083 +void dispc_set_trans_key(enum omap_channel ch,
17084 + enum omap_dss_color_key_type type,
17085 + u32 trans_key);
17086 +void dispc_enable_trans_key(enum omap_channel ch, bool enable);
17088 +void dispc_set_lcd_timings(struct omap_video_timings *timings);
17089 +unsigned long dispc_fclk_rate(void);
17090 +unsigned long dispc_pclk_rate(void);
17091 +void dispc_set_pol_freq(struct omap_panel *panel);
17092 +void find_lck_pck_divs(bool is_tft, unsigned long req_pck, unsigned long fck,
17093 + u16 *lck_div, u16 *pck_div);
17094 +int dispc_calc_clock_div(bool is_tft, unsigned long req_pck,
17095 + struct dispc_clock_info *cinfo);
17096 +int dispc_set_clock_div(struct dispc_clock_info *cinfo);
17097 +int dispc_get_clock_div(struct dispc_clock_info *cinfo);
17098 +void dispc_set_lcd_divisor(u16 lck_div, u16 pck_div);
17100 +void dispc_setup_partial_planes(struct omap_display *display,
17101 + u16 *x, u16 *y, u16 *w, u16 *h);
17102 +void dispc_draw_partial_planes(struct omap_display *display);
17105 +/* VENC */
17106 +int venc_init(void);
17107 +void venc_exit(void);
17108 +void venc_dump_regs(struct seq_file *s);
17109 +void venc_init_display(struct omap_display *display);
17111 +/* RFBI */
17112 +int rfbi_init(void);
17113 +void rfbi_exit(void);
17114 +void rfbi_dump_regs(struct seq_file *s);
17116 +int rfbi_configure(int rfbi_module, int bpp, int lines);
17117 +void rfbi_enable_rfbi(bool enable);
17118 +void rfbi_transfer_area(u16 width, u16 height,
17119 + void (callback)(void *data), void *data);
17120 +void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t);
17121 +unsigned long rfbi_get_max_tx_rate(void);
17122 +void rfbi_init_display(struct omap_display *display);
17124 +#endif
17125 diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/omap2/dss/manager.c
17126 new file mode 100644
17127 index 0000000..7c25146
17128 --- /dev/null
17129 +++ b/drivers/video/omap2/dss/manager.c
17130 @@ -0,0 +1,463 @@
17132 + * linux/drivers/video/omap2/dss/manager.c
17134 + * Copyright (C) 2009 Nokia Corporation
17135 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
17137 + * Some code and ideas taken from drivers/video/omap/ driver
17138 + * by Imre Deak.
17140 + * This program is free software; you can redistribute it and/or modify it
17141 + * under the terms of the GNU General Public License version 2 as published by
17142 + * the Free Software Foundation.
17144 + * This program is distributed in the hope that it will be useful, but WITHOUT
17145 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17146 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17147 + * more details.
17149 + * You should have received a copy of the GNU General Public License along with
17150 + * this program. If not, see <http://www.gnu.org/licenses/>.
17151 + */
17153 +#define DSS_SUBSYS_NAME "MANAGER"
17155 +#include <linux/kernel.h>
17156 +#include <linux/module.h>
17157 +#include <linux/platform_device.h>
17159 +#include <mach/display.h>
17161 +#include "dss.h"
17163 +static int num_managers;
17164 +static struct list_head manager_list;
17166 +static ssize_t manager_name_show(struct omap_overlay_manager *mgr, char *buf)
17168 + return snprintf(buf, PAGE_SIZE, "%s\n", mgr->name);
17171 +static ssize_t manager_display_show(struct omap_overlay_manager *mgr, char *buf)
17173 + return snprintf(buf, PAGE_SIZE, "%s\n",
17174 + mgr->display ? mgr->display->name : "<none>");
17177 +static ssize_t manager_display_store(struct omap_overlay_manager *mgr, const char *buf, size_t size)
17179 + int r, i;
17180 + int len = size;
17181 + struct omap_display *display = NULL;
17183 + if (buf[size-1] == '\n')
17184 + --len;
17186 + if (len > 0) {
17187 + for (i = 0; i < omap_dss_get_num_displays(); ++i) {
17188 + display = dss_get_display(i);
17190 + if (strncmp(buf, display->name, len) == 0)
17191 + break;
17193 + display = NULL;
17197 + if (len > 0 && display == NULL)
17198 + return -EINVAL;
17200 + if (display)
17201 + DSSDBG("display %s found\n", display->name);
17203 + if (mgr->display) {
17204 + r = mgr->unset_display(mgr);
17205 + if (r) {
17206 + DSSERR("failed to unset display\n");
17207 + return r;
17211 + if (display) {
17212 + r = mgr->set_display(mgr, display);
17213 + if (r) {
17214 + DSSERR("failed to set manager\n");
17215 + return r;
17218 + r = mgr->apply(mgr);
17219 + if (r) {
17220 + DSSERR("failed to apply dispc config\n");
17221 + return r;
17225 + return size;
17228 +struct manager_attribute {
17229 + struct attribute attr;
17230 + ssize_t (*show)(struct omap_overlay_manager *, char *);
17231 + ssize_t (*store)(struct omap_overlay_manager *, const char *, size_t);
17234 +#define OVERLAY_ATTR(_name, _mode, _show, _store) \
17235 + struct manager_attribute manager_attr_##_name = \
17236 + __ATTR(_name, _mode, _show, _store)
17238 +static OVERLAY_ATTR(name, S_IRUGO, manager_name_show, NULL);
17239 +static OVERLAY_ATTR(display, S_IRUGO|S_IWUSR,
17240 + manager_display_show, manager_display_store);
17242 +static struct attribute *manager_sysfs_attrs[] = {
17243 + &manager_attr_name.attr,
17244 + &manager_attr_display.attr,
17245 + NULL
17248 +static ssize_t manager_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
17250 + struct omap_overlay_manager *manager;
17251 + struct manager_attribute *manager_attr;
17253 + manager = container_of(kobj, struct omap_overlay_manager, kobj);
17254 + manager_attr = container_of(attr, struct manager_attribute, attr);
17256 + if (!manager_attr->show)
17257 + return -ENOENT;
17259 + return manager_attr->show(manager, buf);
17262 +static ssize_t manager_attr_store(struct kobject *kobj, struct attribute *attr,
17263 + const char *buf, size_t size)
17265 + struct omap_overlay_manager *manager;
17266 + struct manager_attribute *manager_attr;
17268 + manager = container_of(kobj, struct omap_overlay_manager, kobj);
17269 + manager_attr = container_of(attr, struct manager_attribute, attr);
17271 + if (!manager_attr->store)
17272 + return -ENOENT;
17274 + return manager_attr->store(manager, buf, size);
17277 +static struct sysfs_ops manager_sysfs_ops = {
17278 + .show = manager_attr_show,
17279 + .store = manager_attr_store,
17282 +static struct kobj_type manager_ktype = {
17283 + .sysfs_ops = &manager_sysfs_ops,
17284 + .default_attrs = manager_sysfs_attrs,
17287 +static int omap_dss_set_display(struct omap_overlay_manager *mgr,
17288 + struct omap_display *display)
17290 + int i;
17291 + int r;
17293 + if (display->manager) {
17294 + DSSERR("display '%s' already has a manager '%s'\n",
17295 + display->name, display->manager->name);
17296 + return -EINVAL;
17299 + if ((mgr->supported_displays & display->type) == 0) {
17300 + DSSERR("display '%s' does not support manager '%s'\n",
17301 + display->name, mgr->name);
17302 + return -EINVAL;
17305 + for (i = 0; i < mgr->num_overlays; i++) {
17306 + struct omap_overlay *ovl = mgr->overlays[i];
17308 + if (ovl->manager != mgr || !ovl->info.enabled)
17309 + continue;
17311 + r = dss_check_overlay(ovl, display);
17312 + if (r)
17313 + return r;
17316 + display->manager = mgr;
17317 + mgr->display = display;
17319 + return 0;
17322 +static int omap_dss_unset_display(struct omap_overlay_manager *mgr)
17324 + if (!mgr->display) {
17325 + DSSERR("failed to unset display, display not set.\n");
17326 + return -EINVAL;
17329 + mgr->display->manager = NULL;
17330 + mgr->display = NULL;
17332 + return 0;
17336 +static int overlay_enabled(struct omap_overlay *ovl)
17338 + return ovl->info.enabled && ovl->manager && ovl->manager->display;
17341 +/* We apply settings to both managers here so that we can use optimizations
17342 + * like fifomerge. Shadow registers can be changed first and the non-shadowed
17343 + * should be changed last, at the same time with GO */
17344 +static int omap_dss_mgr_apply(struct omap_overlay_manager *mgr)
17346 + int i;
17347 + int ret = 0;
17348 + enum omap_dss_update_mode mode;
17349 + struct omap_display *display;
17350 + struct omap_overlay *ovl;
17351 + bool ilace = 0;
17352 + int outw, outh;
17353 + int r;
17354 + int num_planes_enabled = 0;
17356 + DSSDBG("omap_dss_mgr_apply(%s)\n", mgr->name);
17358 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
17360 + /* Configure normal overlay parameters and disable unused overlays */
17361 + for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
17362 + ovl = omap_dss_get_overlay(i);
17364 + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
17365 + continue;
17367 + if (!overlay_enabled(ovl)) {
17368 + dispc_enable_plane(ovl->id, 0);
17369 + continue;
17372 + display = ovl->manager->display;
17374 + if (dss_check_overlay(ovl, display)) {
17375 + dispc_enable_plane(ovl->id, 0);
17376 + continue;
17379 + ++num_planes_enabled;
17381 + /* On a manual update display, in manual update mode, update()
17382 + * handles configuring planes */
17383 + mode = OMAP_DSS_UPDATE_AUTO;
17384 + if (display->get_update_mode)
17385 + mode = display->get_update_mode(mgr->display);
17387 + if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE &&
17388 + mode != OMAP_DSS_UPDATE_AUTO)
17389 + continue;
17391 + if (display->type == OMAP_DISPLAY_TYPE_VENC)
17392 + ilace = 1;
17394 + if (ovl->info.out_width == 0)
17395 + outw = ovl->info.width;
17396 + else
17397 + outw = ovl->info.out_width;
17399 + if (ovl->info.out_height == 0)
17400 + outh = ovl->info.height;
17401 + else
17402 + outh = ovl->info.out_height;
17404 + r = dispc_setup_plane(ovl->id, ovl->manager->id,
17405 + ovl->info.paddr,
17406 + ovl->info.screen_width,
17407 + ovl->info.pos_x,
17408 + ovl->info.pos_y,
17409 + ovl->info.width,
17410 + ovl->info.height,
17411 + outw,
17412 + outh,
17413 + ovl->info.color_mode,
17414 + ilace,
17415 + ovl->info.rotation,
17416 + ovl->info.mirror);
17418 + if (r) {
17419 + DSSERR("dispc_setup_plane failed for ovl %d\n",
17420 + ovl->id);
17421 + dispc_enable_plane(ovl->id, 0);
17422 + continue;
17425 + dispc_enable_plane(ovl->id, 1);
17428 + /* Enable fifo merge if possible */
17429 + dispc_enable_fifomerge(num_planes_enabled == 1);
17431 + /* Go through overlays again. This time we configure fifos. We have to
17432 + * do this after enabling/disabling fifomerge so that we have correct
17433 + * knowledge of fifo sizes */
17434 + for (i = 0; i < omap_dss_get_num_overlays(); ++i) {
17435 + ovl = omap_dss_get_overlay(i);
17437 + if (!(ovl->caps & OMAP_DSS_OVL_CAP_DISPC))
17438 + continue;
17440 + if (!overlay_enabled(ovl)) {
17441 + continue;
17444 + ovl->manager->display->configure_overlay(ovl);
17447 + /* Issue GO for managers */
17448 + list_for_each_entry(mgr, &manager_list, list) {
17449 + if (!(mgr->caps & OMAP_DSS_OVL_MGR_CAP_DISPC))
17450 + continue;
17452 + display = mgr->display;
17454 + if (!display)
17455 + continue;
17457 + /* We don't need GO with manual update display. LCD iface will
17458 + * always be turned off after frame, and new settings will
17459 + * be taken in to use at next update */
17460 + if (display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE)
17461 + continue;
17463 + dispc_go(mgr->id);
17466 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
17468 + return ret;
17471 +static void omap_dss_mgr_set_def_color(struct omap_overlay_manager *mgr,
17472 + u32 color)
17474 + dispc_set_default_color(mgr->id, color);
17477 +static void omap_dss_mgr_set_trans_key(struct omap_overlay_manager *mgr,
17478 + enum omap_dss_color_key_type type,
17479 + u32 trans_key)
17481 + dispc_set_trans_key(mgr->id, type, trans_key);
17484 +static void omap_dss_mgr_enable_trans_key(struct omap_overlay_manager *mgr,
17485 + bool enable)
17487 + dispc_enable_trans_key(mgr->id, enable);
17490 +static void omap_dss_add_overlay_manager(struct omap_overlay_manager *manager)
17492 + ++num_managers;
17493 + list_add_tail(&manager->list, &manager_list);
17496 +int dss_init_overlay_managers(struct platform_device *pdev)
17498 + int i, r;
17500 + INIT_LIST_HEAD(&manager_list);
17502 + num_managers = 0;
17504 + for (i = 0; i < 2; ++i) {
17505 + struct omap_overlay_manager *mgr;
17506 + mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
17508 + BUG_ON(mgr == NULL);
17510 + switch (i) {
17511 + case 0:
17512 + mgr->name = "lcd";
17513 + mgr->id = OMAP_DSS_CHANNEL_LCD;
17514 + mgr->supported_displays =
17515 + OMAP_DISPLAY_TYPE_DPI | OMAP_DISPLAY_TYPE_DBI |
17516 + OMAP_DISPLAY_TYPE_SDI | OMAP_DISPLAY_TYPE_DSI;
17517 + break;
17518 + case 1:
17519 + mgr->name = "tv";
17520 + mgr->id = OMAP_DSS_CHANNEL_DIGIT;
17521 + mgr->supported_displays = OMAP_DISPLAY_TYPE_VENC;
17522 + break;
17525 + mgr->set_display = &omap_dss_set_display,
17526 + mgr->unset_display = &omap_dss_unset_display,
17527 + mgr->apply = &omap_dss_mgr_apply,
17528 + mgr->set_default_color = &omap_dss_mgr_set_def_color,
17529 + mgr->set_trans_key = &omap_dss_mgr_set_trans_key,
17530 + mgr->enable_trans_key = &omap_dss_mgr_enable_trans_key,
17531 + mgr->caps = OMAP_DSS_OVL_MGR_CAP_DISPC,
17533 + dss_overlay_setup_dispc_manager(mgr);
17535 + omap_dss_add_overlay_manager(mgr);
17537 + r = kobject_init_and_add(&mgr->kobj, &manager_ktype,
17538 + &pdev->dev.kobj, "manager%d", i);
17540 + if (r) {
17541 + DSSERR("failed to create sysfs file\n");
17542 + continue;
17546 + return 0;
17549 +void dss_uninit_overlay_managers(struct platform_device *pdev)
17551 + struct omap_overlay_manager *mgr;
17553 + while (!list_empty(&manager_list)) {
17554 + mgr = list_first_entry(&manager_list,
17555 + struct omap_overlay_manager, list);
17556 + list_del(&mgr->list);
17557 + kobject_del(&mgr->kobj);
17558 + kobject_put(&mgr->kobj);
17559 + kfree(mgr);
17562 + num_managers = 0;
17565 +int omap_dss_get_num_overlay_managers(void)
17567 + return num_managers;
17569 +EXPORT_SYMBOL(omap_dss_get_num_overlay_managers);
17571 +struct omap_overlay_manager *omap_dss_get_overlay_manager(int num)
17573 + int i = 0;
17574 + struct omap_overlay_manager *mgr;
17576 + list_for_each_entry(mgr, &manager_list, list) {
17577 + if (i++ == num)
17578 + return mgr;
17581 + return NULL;
17583 +EXPORT_SYMBOL(omap_dss_get_overlay_manager);
17585 +#ifdef L4_EXAMPLE
17586 +static int ovl_mgr_apply_l4(struct omap_overlay_manager *mgr)
17588 + DSSDBG("omap_dss_mgr_apply_l4(%s)\n", mgr->name);
17590 + return 0;
17592 +#endif
17594 diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/omap2/dss/overlay.c
17595 new file mode 100644
17596 index 0000000..968edbe
17597 --- /dev/null
17598 +++ b/drivers/video/omap2/dss/overlay.c
17599 @@ -0,0 +1,587 @@
17601 + * linux/drivers/video/omap2/dss/overlay.c
17603 + * Copyright (C) 2009 Nokia Corporation
17604 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
17606 + * Some code and ideas taken from drivers/video/omap/ driver
17607 + * by Imre Deak.
17609 + * This program is free software; you can redistribute it and/or modify it
17610 + * under the terms of the GNU General Public License version 2 as published by
17611 + * the Free Software Foundation.
17613 + * This program is distributed in the hope that it will be useful, but WITHOUT
17614 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17615 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17616 + * more details.
17618 + * You should have received a copy of the GNU General Public License along with
17619 + * this program. If not, see <http://www.gnu.org/licenses/>.
17620 + */
17622 +#define DSS_SUBSYS_NAME "OVERLAY"
17624 +#include <linux/kernel.h>
17625 +#include <linux/module.h>
17626 +#include <linux/err.h>
17627 +#include <linux/sysfs.h>
17628 +#include <linux/kobject.h>
17629 +#include <linux/platform_device.h>
17631 +#include <mach/display.h>
17633 +#include "dss.h"
17635 +static int num_overlays;
17636 +static struct list_head overlay_list;
17638 +static ssize_t overlay_name_show(struct omap_overlay *ovl, char *buf)
17640 + return snprintf(buf, PAGE_SIZE, "%s\n", ovl->name);
17643 +static ssize_t overlay_manager_show(struct omap_overlay *ovl, char *buf)
17645 + return snprintf(buf, PAGE_SIZE, "%s\n",
17646 + ovl->manager ? ovl->manager->name : "<none>");
17649 +static ssize_t overlay_manager_store(struct omap_overlay *ovl, const char *buf, size_t size)
17651 + int i, r;
17652 + struct omap_overlay_manager *mgr = NULL;
17653 + int len = size;
17655 + if (buf[size-1] == '\n')
17656 + --len;
17658 + if (len > 0) {
17659 + for (i = 0; i < omap_dss_get_num_overlay_managers(); ++i) {
17660 + mgr = omap_dss_get_overlay_manager(i);
17662 + if (strncmp(buf, mgr->name, len) == 0)
17663 + break;
17665 + mgr = NULL;
17669 + if (len > 0 && mgr == NULL)
17670 + return -EINVAL;
17672 + if (mgr)
17673 + DSSDBG("manager %s found\n", mgr->name);
17675 + if (mgr != ovl->manager) {
17676 + /* detach old manager */
17677 + if (ovl->manager) {
17678 + r = ovl->unset_manager(ovl);
17679 + if (r) {
17680 + DSSERR("detach failed\n");
17681 + return r;
17685 + if (mgr) {
17686 + r = ovl->set_manager(ovl, mgr);
17687 + if (r) {
17688 + DSSERR("Failed to attach overlay\n");
17689 + return r;
17694 + if (ovl->manager && (r = ovl->manager->apply(ovl->manager)))
17695 + return r;
17697 + return size;
17700 +static ssize_t overlay_input_size_show(struct omap_overlay *ovl, char *buf)
17702 + return snprintf(buf, PAGE_SIZE, "%d,%d\n",
17703 + ovl->info.width, ovl->info.height);
17706 +static ssize_t overlay_screen_width_show(struct omap_overlay *ovl, char *buf)
17708 + return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.screen_width);
17711 +static ssize_t overlay_position_show(struct omap_overlay *ovl, char *buf)
17713 + return snprintf(buf, PAGE_SIZE, "%d,%d\n",
17714 + ovl->info.pos_x, ovl->info.pos_y);
17717 +static ssize_t overlay_position_store(struct omap_overlay *ovl,
17718 + const char *buf, size_t size)
17720 + int r;
17721 + char *last;
17722 + struct omap_overlay_info info;
17724 + ovl->get_overlay_info(ovl, &info);
17726 + info.pos_x = simple_strtoul(buf, &last, 10);
17727 + ++last;
17728 + if (last - buf >= size)
17729 + return -EINVAL;
17731 + info.pos_y = simple_strtoul(last, &last, 10);
17733 + if ((r = ovl->set_overlay_info(ovl, &info)))
17734 + return r;
17736 + if (ovl->manager && (r = ovl->manager->apply(ovl->manager)))
17737 + return r;
17739 + return size;
17742 +static ssize_t overlay_output_size_show(struct omap_overlay *ovl, char *buf)
17744 + return snprintf(buf, PAGE_SIZE, "%d,%d\n",
17745 + ovl->info.out_width, ovl->info.out_height);
17748 +static ssize_t overlay_output_size_store(struct omap_overlay *ovl,
17749 + const char *buf, size_t size)
17751 + int r;
17752 + char *last;
17753 + struct omap_overlay_info info;
17755 + ovl->get_overlay_info(ovl, &info);
17757 + info.out_width = simple_strtoul(buf, &last, 10);
17758 + ++last;
17759 + if (last - buf >= size)
17760 + return -EINVAL;
17762 + info.out_height = simple_strtoul(last, &last, 10);
17764 + if ((r = ovl->set_overlay_info(ovl, &info)))
17765 + return r;
17767 + if (ovl->manager && (r = ovl->manager->apply(ovl->manager)))
17768 + return r;
17770 + return size;
17773 +static ssize_t overlay_enabled_show(struct omap_overlay *ovl, char *buf)
17775 + return snprintf(buf, PAGE_SIZE, "%d\n", ovl->info.enabled);
17778 +static ssize_t overlay_enabled_store(struct omap_overlay *ovl, const char *buf, size_t size)
17780 + int r;
17781 + struct omap_overlay_info info;
17783 + ovl->get_overlay_info(ovl, &info);
17785 + info.enabled = simple_strtoul(buf, NULL, 10);
17787 + if ((r = ovl->set_overlay_info(ovl, &info)))
17788 + return r;
17790 + if (ovl->manager && (r = ovl->manager->apply(ovl->manager)))
17791 + return r;
17793 + return size;
17796 +struct overlay_attribute {
17797 + struct attribute attr;
17798 + ssize_t (*show)(struct omap_overlay *, char *);
17799 + ssize_t (*store)(struct omap_overlay *, const char *, size_t);
17802 +#define OVERLAY_ATTR(_name, _mode, _show, _store) \
17803 + struct overlay_attribute overlay_attr_##_name = \
17804 + __ATTR(_name, _mode, _show, _store)
17806 +static OVERLAY_ATTR(name, S_IRUGO, overlay_name_show, NULL);
17807 +static OVERLAY_ATTR(manager, S_IRUGO|S_IWUSR,
17808 + overlay_manager_show, overlay_manager_store);
17809 +static OVERLAY_ATTR(input_size, S_IRUGO, overlay_input_size_show, NULL);
17810 +static OVERLAY_ATTR(screen_width, S_IRUGO, overlay_screen_width_show, NULL);
17811 +static OVERLAY_ATTR(position, S_IRUGO|S_IWUSR,
17812 + overlay_position_show, overlay_position_store);
17813 +static OVERLAY_ATTR(output_size, S_IRUGO|S_IWUSR,
17814 + overlay_output_size_show, overlay_output_size_store);
17815 +static OVERLAY_ATTR(enabled, S_IRUGO|S_IWUSR,
17816 + overlay_enabled_show, overlay_enabled_store);
17818 +static struct attribute *overlay_sysfs_attrs[] = {
17819 + &overlay_attr_name.attr,
17820 + &overlay_attr_manager.attr,
17821 + &overlay_attr_input_size.attr,
17822 + &overlay_attr_screen_width.attr,
17823 + &overlay_attr_position.attr,
17824 + &overlay_attr_output_size.attr,
17825 + &overlay_attr_enabled.attr,
17826 + NULL
17829 +static ssize_t overlay_attr_show(struct kobject *kobj, struct attribute *attr, char *buf)
17831 + struct omap_overlay *overlay;
17832 + struct overlay_attribute *overlay_attr;
17834 + overlay = container_of(kobj, struct omap_overlay, kobj);
17835 + overlay_attr = container_of(attr, struct overlay_attribute, attr);
17837 + if (!overlay_attr->show)
17838 + return -ENOENT;
17840 + return overlay_attr->show(overlay, buf);
17843 +static ssize_t overlay_attr_store(struct kobject *kobj, struct attribute *attr,
17844 + const char *buf, size_t size)
17846 + struct omap_overlay *overlay;
17847 + struct overlay_attribute *overlay_attr;
17849 + overlay = container_of(kobj, struct omap_overlay, kobj);
17850 + overlay_attr = container_of(attr, struct overlay_attribute, attr);
17852 + if (!overlay_attr->store)
17853 + return -ENOENT;
17855 + return overlay_attr->store(overlay, buf, size);
17858 +static struct sysfs_ops overlay_sysfs_ops = {
17859 + .show = overlay_attr_show,
17860 + .store = overlay_attr_store,
17863 +static struct kobj_type overlay_ktype = {
17864 + .sysfs_ops = &overlay_sysfs_ops,
17865 + .default_attrs = overlay_sysfs_attrs,
17868 +/* Check if overlay parameters are compatible with display */
17869 +int dss_check_overlay(struct omap_overlay *ovl, struct omap_display *display)
17871 + struct omap_overlay_info *info;
17872 + u16 outw, outh;
17873 + u16 dw, dh;
17875 + if (!display)
17876 + return 0;
17878 + if (!ovl->info.enabled)
17879 + return 0;
17881 + info = &ovl->info;
17883 + display->get_resolution(display, &dw, &dh);
17885 + DSSDBG("check_overlay %d: (%d,%d %dx%d -> %dx%d) disp (%dx%d)\n",
17886 + ovl->id,
17887 + info->pos_x, info->pos_y,
17888 + info->width, info->height,
17889 + info->out_width, info->out_height,
17890 + dw, dh);
17892 + if ((ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
17893 + outw = info->width;
17894 + outh = info->height;
17895 + } else {
17896 + if (info->out_width == 0)
17897 + outw = info->width;
17898 + else
17899 + outw = info->out_width;
17901 + if (info->out_height == 0)
17902 + outh = info->height;
17903 + else
17904 + outh = info->out_height;
17907 + if (dw < info->pos_x + outw) {
17908 + DSSDBG("check_overlay failed 1: %d < %d + %d\n",
17909 + dw, info->pos_x, outw);
17910 + return -EINVAL;
17913 + if (dh < info->pos_y + outh) {
17914 + DSSDBG("check_overlay failed 2: %d < %d + %d\n",
17915 + dh, info->pos_y, outh);
17916 + return -EINVAL;
17919 + if ((ovl->supported_modes & info->color_mode) == 0) {
17920 + DSSERR("overlay doesn't support mode %d\n", info->color_mode);
17921 + return -EINVAL;
17924 + return 0;
17927 +static int dss_ovl_set_overlay_info(struct omap_overlay *ovl,
17928 + struct omap_overlay_info *info)
17930 + int r;
17931 + struct omap_overlay_info old_info;
17933 + old_info = ovl->info;
17934 + ovl->info = *info;
17936 + if (ovl->manager) {
17937 + r = dss_check_overlay(ovl, ovl->manager->display);
17938 + if (r) {
17939 + ovl->info = old_info;
17940 + return r;
17944 + return 0;
17947 +static void dss_ovl_get_overlay_info(struct omap_overlay *ovl,
17948 + struct omap_overlay_info *info)
17950 + *info = ovl->info;
17953 +static int omap_dss_set_manager(struct omap_overlay *ovl,
17954 + struct omap_overlay_manager *mgr)
17956 + int r;
17958 + if (ovl->manager) {
17959 + DSSERR("overlay '%s' already has a manager '%s'\n",
17960 + ovl->name, ovl->manager->name);
17963 + r = dss_check_overlay(ovl, mgr->display);
17964 + if (r)
17965 + return r;
17967 + ovl->manager = mgr;
17969 + return 0;
17972 +static int omap_dss_unset_manager(struct omap_overlay *ovl)
17974 + if (!ovl->manager) {
17975 + DSSERR("failed to detach overlay: manager not set\n");
17976 + return -EINVAL;
17979 + ovl->manager = NULL;
17981 + return 0;
17984 +int omap_dss_get_num_overlays(void)
17986 + return num_overlays;
17988 +EXPORT_SYMBOL(omap_dss_get_num_overlays);
17990 +struct omap_overlay *omap_dss_get_overlay(int num)
17992 + int i = 0;
17993 + struct omap_overlay *ovl;
17995 + list_for_each_entry(ovl, &overlay_list, list) {
17996 + if (i++ == num)
17997 + return ovl;
18000 + return NULL;
18002 +EXPORT_SYMBOL(omap_dss_get_overlay);
18004 +static void omap_dss_add_overlay(struct omap_overlay *overlay)
18006 + ++num_overlays;
18007 + list_add_tail(&overlay->list, &overlay_list);
18010 +static struct omap_overlay *dispc_overlays[3];
18012 +void dss_overlay_setup_dispc_manager(struct omap_overlay_manager *mgr)
18014 + mgr->num_overlays = 3;
18015 + mgr->overlays = dispc_overlays;
18018 +void dss_init_overlays(struct platform_device *pdev, const char *def_disp_name)
18020 + int i, r;
18021 + struct omap_overlay_manager *lcd_mgr;
18022 + struct omap_overlay_manager *tv_mgr;
18023 + struct omap_overlay_manager *def_mgr = NULL;
18025 + INIT_LIST_HEAD(&overlay_list);
18027 + num_overlays = 0;
18029 + for (i = 0; i < 3; ++i) {
18030 + struct omap_overlay *ovl;
18031 + ovl = kzalloc(sizeof(*ovl), GFP_KERNEL);
18033 + BUG_ON(ovl == NULL);
18035 + switch (i) {
18036 + case 0:
18037 + ovl->name = "gfx";
18038 + ovl->id = OMAP_DSS_GFX;
18039 + ovl->supported_modes = OMAP_DSS_COLOR_GFX_OMAP3;
18040 + ovl->caps = OMAP_DSS_OVL_CAP_DISPC;
18041 + break;
18042 + case 1:
18043 + ovl->name = "vid1";
18044 + ovl->id = OMAP_DSS_VIDEO1;
18045 + ovl->supported_modes = OMAP_DSS_COLOR_VID_OMAP3;
18046 + ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
18047 + OMAP_DSS_OVL_CAP_DISPC;
18048 + break;
18049 + case 2:
18050 + ovl->name = "vid2";
18051 + ovl->id = OMAP_DSS_VIDEO2;
18052 + ovl->supported_modes = OMAP_DSS_COLOR_VID_OMAP3;
18053 + ovl->caps = OMAP_DSS_OVL_CAP_SCALE |
18054 + OMAP_DSS_OVL_CAP_DISPC;
18055 + break;
18058 + ovl->set_manager = &omap_dss_set_manager;
18059 + ovl->unset_manager = &omap_dss_unset_manager;
18060 + ovl->set_overlay_info = &dss_ovl_set_overlay_info;
18061 + ovl->get_overlay_info = &dss_ovl_get_overlay_info;
18063 + omap_dss_add_overlay(ovl);
18065 + r = kobject_init_and_add(&ovl->kobj, &overlay_ktype,
18066 + &pdev->dev.kobj, "overlay%d", i);
18068 + if (r) {
18069 + DSSERR("failed to create sysfs file\n");
18070 + continue;
18073 + dispc_overlays[i] = ovl;
18076 + lcd_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_LCD);
18077 + tv_mgr = omap_dss_get_overlay_manager(OMAP_DSS_OVL_MGR_TV);
18079 + if (def_disp_name) {
18080 + for (i = 0; i < omap_dss_get_num_displays() ; i++) {
18081 + struct omap_display *display = dss_get_display(i);
18083 + if (strcmp(display->name, def_disp_name) == 0) {
18084 + if (display->type != OMAP_DISPLAY_TYPE_VENC) {
18085 + lcd_mgr->set_display(lcd_mgr, display);
18086 + def_mgr = lcd_mgr;
18087 + } else {
18088 + lcd_mgr->set_display(tv_mgr, display);
18089 + def_mgr = tv_mgr;
18092 + break;
18096 + if (!def_mgr)
18097 + DSSWARN("default display %s not found\n",
18098 + def_disp_name);
18101 + if (def_mgr != lcd_mgr) {
18102 + /* connect lcd manager to first non-VENC display found */
18103 + for (i = 0; i < omap_dss_get_num_displays(); i++) {
18104 + struct omap_display *display = dss_get_display(i);
18105 + if (display->type != OMAP_DISPLAY_TYPE_VENC) {
18106 + lcd_mgr->set_display(lcd_mgr, display);
18108 + if (!def_mgr)
18109 + def_mgr = lcd_mgr;
18111 + break;
18116 + if (def_mgr != tv_mgr) {
18117 + /* connect tv manager to first VENC display found */
18118 + for (i = 0; i < omap_dss_get_num_displays(); i++) {
18119 + struct omap_display *display = dss_get_display(i);
18120 + if (display->type == OMAP_DISPLAY_TYPE_VENC) {
18121 + tv_mgr->set_display(tv_mgr, display);
18123 + if (!def_mgr)
18124 + def_mgr = tv_mgr;
18126 + break;
18131 + /* connect all dispc overlays to def_mgr */
18132 + if (def_mgr) {
18133 + for (i = 0; i < 3; i++) {
18134 + struct omap_overlay *ovl;
18135 + ovl = omap_dss_get_overlay(i);
18136 + omap_dss_set_manager(ovl, def_mgr);
18140 +#ifdef L4_EXAMPLE
18141 + /* setup L4 overlay as an example */
18143 + static struct omap_overlay ovl = {
18144 + .name = "l4-ovl",
18145 + .supported_modes = OMAP_DSS_COLOR_RGB24U,
18146 + .set_manager = &omap_dss_set_manager,
18147 + .unset_manager = &omap_dss_unset_manager,
18148 + .setup_input = &omap_dss_setup_overlay_input,
18149 + .setup_output = &omap_dss_setup_overlay_output,
18150 + .enable = &omap_dss_enable_overlay,
18151 + };
18153 + static struct omap_overlay_manager mgr = {
18154 + .name = "l4",
18155 + .num_overlays = 1,
18156 + .overlays = &ovl,
18157 + .set_display = &omap_dss_set_display,
18158 + .unset_display = &omap_dss_unset_display,
18159 + .apply = &ovl_mgr_apply_l4,
18160 + .supported_displays =
18161 + OMAP_DISPLAY_TYPE_DBI | OMAP_DISPLAY_TYPE_DSI,
18162 + };
18164 + omap_dss_add_overlay(&ovl);
18165 + omap_dss_add_overlay_manager(&mgr);
18166 + omap_dss_set_manager(&ovl, &mgr);
18168 +#endif
18171 +void dss_uninit_overlays(struct platform_device *pdev)
18173 + struct omap_overlay *ovl;
18175 + while (!list_empty(&overlay_list)) {
18176 + ovl = list_first_entry(&overlay_list,
18177 + struct omap_overlay, list);
18178 + list_del(&ovl->list);
18179 + kobject_del(&ovl->kobj);
18180 + kobject_put(&ovl->kobj);
18181 + kfree(ovl);
18184 + num_overlays = 0;
18187 diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/omap2/dss/rfbi.c
18188 new file mode 100644
18189 index 0000000..3e9ae1e
18190 --- /dev/null
18191 +++ b/drivers/video/omap2/dss/rfbi.c
18192 @@ -0,0 +1,1304 @@
18194 + * linux/drivers/video/omap2/dss/rfbi.c
18196 + * Copyright (C) 2009 Nokia Corporation
18197 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
18199 + * Some code and ideas taken from drivers/video/omap/ driver
18200 + * by Imre Deak.
18202 + * This program is free software; you can redistribute it and/or modify it
18203 + * under the terms of the GNU General Public License version 2 as published by
18204 + * the Free Software Foundation.
18206 + * This program is distributed in the hope that it will be useful, but WITHOUT
18207 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
18208 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18209 + * more details.
18211 + * You should have received a copy of the GNU General Public License along with
18212 + * this program. If not, see <http://www.gnu.org/licenses/>.
18213 + */
18215 +#define DSS_SUBSYS_NAME "RFBI"
18217 +#include <linux/kernel.h>
18218 +#include <linux/dma-mapping.h>
18219 +#include <linux/vmalloc.h>
18220 +#include <linux/clk.h>
18221 +#include <linux/io.h>
18222 +#include <linux/delay.h>
18223 +#include <linux/kfifo.h>
18224 +#include <linux/ktime.h>
18225 +#include <linux/hrtimer.h>
18226 +#include <linux/seq_file.h>
18228 +#include <mach/board.h>
18229 +#include <mach/display.h>
18230 +#include "dss.h"
18232 +/*#define MEASURE_PERF*/
18234 +#define RFBI_BASE 0x48050800
18236 +struct rfbi_reg { u16 idx; };
18238 +#define RFBI_REG(idx) ((const struct rfbi_reg) { idx })
18240 +#define RFBI_REVISION RFBI_REG(0x0000)
18241 +#define RFBI_SYSCONFIG RFBI_REG(0x0010)
18242 +#define RFBI_SYSSTATUS RFBI_REG(0x0014)
18243 +#define RFBI_CONTROL RFBI_REG(0x0040)
18244 +#define RFBI_PIXEL_CNT RFBI_REG(0x0044)
18245 +#define RFBI_LINE_NUMBER RFBI_REG(0x0048)
18246 +#define RFBI_CMD RFBI_REG(0x004c)
18247 +#define RFBI_PARAM RFBI_REG(0x0050)
18248 +#define RFBI_DATA RFBI_REG(0x0054)
18249 +#define RFBI_READ RFBI_REG(0x0058)
18250 +#define RFBI_STATUS RFBI_REG(0x005c)
18252 +#define RFBI_CONFIG(n) RFBI_REG(0x0060 + (n)*0x18)
18253 +#define RFBI_ONOFF_TIME(n) RFBI_REG(0x0064 + (n)*0x18)
18254 +#define RFBI_CYCLE_TIME(n) RFBI_REG(0x0068 + (n)*0x18)
18255 +#define RFBI_DATA_CYCLE1(n) RFBI_REG(0x006c + (n)*0x18)
18256 +#define RFBI_DATA_CYCLE2(n) RFBI_REG(0x0070 + (n)*0x18)
18257 +#define RFBI_DATA_CYCLE3(n) RFBI_REG(0x0074 + (n)*0x18)
18259 +#define RFBI_VSYNC_WIDTH RFBI_REG(0x0090)
18260 +#define RFBI_HSYNC_WIDTH RFBI_REG(0x0094)
18262 +#define RFBI_CMD_FIFO_LEN_BYTES (16 * sizeof(struct update_param))
18264 +#define REG_FLD_MOD(idx, val, start, end) \
18265 + rfbi_write_reg(idx, FLD_MOD(rfbi_read_reg(idx), val, start, end))
18267 +/* To work around an RFBI transfer rate limitation */
18268 +#define OMAP_RFBI_RATE_LIMIT 1
18270 +enum omap_rfbi_cycleformat {
18271 + OMAP_DSS_RFBI_CYCLEFORMAT_1_1 = 0,
18272 + OMAP_DSS_RFBI_CYCLEFORMAT_2_1 = 1,
18273 + OMAP_DSS_RFBI_CYCLEFORMAT_3_1 = 2,
18274 + OMAP_DSS_RFBI_CYCLEFORMAT_3_2 = 3,
18277 +enum omap_rfbi_datatype {
18278 + OMAP_DSS_RFBI_DATATYPE_12 = 0,
18279 + OMAP_DSS_RFBI_DATATYPE_16 = 1,
18280 + OMAP_DSS_RFBI_DATATYPE_18 = 2,
18281 + OMAP_DSS_RFBI_DATATYPE_24 = 3,
18284 +enum omap_rfbi_parallelmode {
18285 + OMAP_DSS_RFBI_PARALLELMODE_8 = 0,
18286 + OMAP_DSS_RFBI_PARALLELMODE_9 = 1,
18287 + OMAP_DSS_RFBI_PARALLELMODE_12 = 2,
18288 + OMAP_DSS_RFBI_PARALLELMODE_16 = 3,
18291 +enum update_cmd {
18292 + RFBI_CMD_UPDATE = 0,
18293 + RFBI_CMD_SYNC = 1,
18296 +static int rfbi_convert_timings(struct rfbi_timings *t);
18297 +static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div);
18298 +static void process_cmd_fifo(void);
18300 +static struct {
18301 + void __iomem *base;
18303 + unsigned long l4_khz;
18305 + enum omap_rfbi_datatype datatype;
18306 + enum omap_rfbi_parallelmode parallelmode;
18308 + enum omap_rfbi_te_mode te_mode;
18309 + int te_enabled;
18311 + void (*framedone_callback)(void *data);
18312 + void *framedone_callback_data;
18314 + struct omap_display *display[2];
18316 + struct kfifo *cmd_fifo;
18317 + spinlock_t cmd_lock;
18318 + struct completion cmd_done;
18319 + atomic_t cmd_fifo_full;
18320 + atomic_t cmd_pending;
18321 +#ifdef MEASURE_PERF
18322 + unsigned perf_bytes;
18323 + ktime_t perf_setup_time;
18324 + ktime_t perf_start_time;
18325 +#endif
18326 +} rfbi;
18328 +struct update_region {
18329 + u16 x;
18330 + u16 y;
18331 + u16 w;
18332 + u16 h;
18335 +struct update_param {
18336 + u8 rfbi_module;
18337 + u8 cmd;
18339 + union {
18340 + struct update_region r;
18341 + struct completion *sync;
18342 + } par;
18345 +static inline void rfbi_write_reg(const struct rfbi_reg idx, u32 val)
18347 + __raw_writel(val, rfbi.base + idx.idx);
18350 +static inline u32 rfbi_read_reg(const struct rfbi_reg idx)
18352 + return __raw_readl(rfbi.base + idx.idx);
18355 +static void rfbi_enable_clocks(bool enable)
18357 + if (enable)
18358 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
18359 + else
18360 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
18363 +void omap_rfbi_write_command(const void *buf, u32 len)
18365 + rfbi_enable_clocks(1);
18366 + switch (rfbi.parallelmode) {
18367 + case OMAP_DSS_RFBI_PARALLELMODE_8:
18369 + const u8 *b = buf;
18370 + for (; len; len--)
18371 + rfbi_write_reg(RFBI_CMD, *b++);
18372 + break;
18375 + case OMAP_DSS_RFBI_PARALLELMODE_16:
18377 + const u16 *w = buf;
18378 + BUG_ON(len & 1);
18379 + for (; len; len -= 2)
18380 + rfbi_write_reg(RFBI_CMD, *w++);
18381 + break;
18384 + case OMAP_DSS_RFBI_PARALLELMODE_9:
18385 + case OMAP_DSS_RFBI_PARALLELMODE_12:
18386 + default:
18387 + BUG();
18389 + rfbi_enable_clocks(0);
18391 +EXPORT_SYMBOL(omap_rfbi_write_command);
18393 +void omap_rfbi_read_data(void *buf, u32 len)
18395 + rfbi_enable_clocks(1);
18396 + switch (rfbi.parallelmode) {
18397 + case OMAP_DSS_RFBI_PARALLELMODE_8:
18399 + u8 *b = buf;
18400 + for (; len; len--) {
18401 + rfbi_write_reg(RFBI_READ, 0);
18402 + *b++ = rfbi_read_reg(RFBI_READ);
18404 + break;
18407 + case OMAP_DSS_RFBI_PARALLELMODE_16:
18409 + u16 *w = buf;
18410 + BUG_ON(len & ~1);
18411 + for (; len; len -= 2) {
18412 + rfbi_write_reg(RFBI_READ, 0);
18413 + *w++ = rfbi_read_reg(RFBI_READ);
18415 + break;
18418 + case OMAP_DSS_RFBI_PARALLELMODE_9:
18419 + case OMAP_DSS_RFBI_PARALLELMODE_12:
18420 + default:
18421 + BUG();
18423 + rfbi_enable_clocks(0);
18425 +EXPORT_SYMBOL(omap_rfbi_read_data);
18427 +void omap_rfbi_write_data(const void *buf, u32 len)
18429 + rfbi_enable_clocks(1);
18430 + switch (rfbi.parallelmode) {
18431 + case OMAP_DSS_RFBI_PARALLELMODE_8:
18433 + const u8 *b = buf;
18434 + for (; len; len--)
18435 + rfbi_write_reg(RFBI_PARAM, *b++);
18436 + break;
18439 + case OMAP_DSS_RFBI_PARALLELMODE_16:
18441 + const u16 *w = buf;
18442 + BUG_ON(len & 1);
18443 + for (; len; len -= 2)
18444 + rfbi_write_reg(RFBI_PARAM, *w++);
18445 + break;
18448 + case OMAP_DSS_RFBI_PARALLELMODE_9:
18449 + case OMAP_DSS_RFBI_PARALLELMODE_12:
18450 + default:
18451 + BUG();
18454 + rfbi_enable_clocks(0);
18456 +EXPORT_SYMBOL(omap_rfbi_write_data);
18458 +void omap_rfbi_write_pixels(const void __iomem *buf, int scr_width,
18459 + u16 x, u16 y,
18460 + u16 w, u16 h)
18462 + int start_offset = scr_width * y + x;
18463 + int horiz_offset = scr_width - w;
18464 + int i;
18466 + rfbi_enable_clocks(1);
18468 + if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
18469 + rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
18470 + const u16 __iomem *pd = buf;
18471 + pd += start_offset;
18473 + for (; h; --h) {
18474 + for (i = 0; i < w; ++i) {
18475 + const u8 __iomem *b = (const u8 __iomem *)pd;
18476 + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
18477 + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
18478 + ++pd;
18480 + pd += horiz_offset;
18482 + } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_24 &&
18483 + rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_8) {
18484 + const u32 __iomem *pd = buf;
18485 + pd += start_offset;
18487 + for (; h; --h) {
18488 + for (i = 0; i < w; ++i) {
18489 + const u8 __iomem *b = (const u8 __iomem *)pd;
18490 + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+2));
18491 + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+1));
18492 + rfbi_write_reg(RFBI_PARAM, __raw_readb(b+0));
18493 + ++pd;
18495 + pd += horiz_offset;
18497 + } else if (rfbi.datatype == OMAP_DSS_RFBI_DATATYPE_16 &&
18498 + rfbi.parallelmode == OMAP_DSS_RFBI_PARALLELMODE_16) {
18499 + const u16 __iomem *pd = buf;
18500 + pd += start_offset;
18502 + for (; h; --h) {
18503 + for (i = 0; i < w; ++i) {
18504 + rfbi_write_reg(RFBI_PARAM, __raw_readw(pd));
18505 + ++pd;
18507 + pd += horiz_offset;
18509 + } else {
18510 + BUG();
18513 + rfbi_enable_clocks(0);
18515 +EXPORT_SYMBOL(omap_rfbi_write_pixels);
18517 +#ifdef MEASURE_PERF
18518 +static void perf_mark_setup(void)
18520 + rfbi.perf_setup_time = ktime_get();
18523 +static void perf_mark_start(void)
18525 + rfbi.perf_start_time = ktime_get();
18528 +static void perf_show(const char *name)
18530 + ktime_t t, setup_time, trans_time;
18531 + u32 total_bytes;
18532 + u32 setup_us, trans_us, total_us;
18534 + t = ktime_get();
18536 + setup_time = ktime_sub(rfbi.perf_start_time, rfbi.perf_setup_time);
18537 + setup_us = (u32)ktime_to_us(setup_time);
18538 + if (setup_us == 0)
18539 + setup_us = 1;
18541 + trans_time = ktime_sub(t, rfbi.perf_start_time);
18542 + trans_us = (u32)ktime_to_us(trans_time);
18543 + if (trans_us == 0)
18544 + trans_us = 1;
18546 + total_us = setup_us + trans_us;
18548 + total_bytes = rfbi.perf_bytes;
18550 + DSSINFO("%s update %u us + %u us = %u us (%uHz), %u bytes, "
18551 + "%u kbytes/sec\n",
18552 + name,
18553 + setup_us,
18554 + trans_us,
18555 + total_us,
18556 + 1000*1000 / total_us,
18557 + total_bytes,
18558 + total_bytes * 1000 / total_us);
18560 +#else
18561 +#define perf_mark_setup()
18562 +#define perf_mark_start()
18563 +#define perf_show(x)
18564 +#endif
18566 +void rfbi_transfer_area(u16 width, u16 height,
18567 + void (callback)(void *data), void *data)
18569 + u32 l;
18571 + /*BUG_ON(callback == 0);*/
18572 + BUG_ON(rfbi.framedone_callback != NULL);
18574 + DSSDBG("rfbi_transfer_area %dx%d\n", width, height);
18576 + dispc_set_lcd_size(width, height);
18578 + dispc_enable_lcd_out(1);
18580 + rfbi.framedone_callback = callback;
18581 + rfbi.framedone_callback_data = data;
18583 + rfbi_enable_clocks(1);
18585 + rfbi_write_reg(RFBI_PIXEL_CNT, width * height);
18587 + l = rfbi_read_reg(RFBI_CONTROL);
18588 + l = FLD_MOD(l, 1, 0, 0); /* enable */
18589 + if (!rfbi.te_enabled)
18590 + l = FLD_MOD(l, 1, 4, 4); /* ITE */
18592 + perf_mark_start();
18594 + rfbi_write_reg(RFBI_CONTROL, l);
18597 +static void framedone_callback(void *data, u32 mask)
18599 + void (*callback)(void *data);
18601 + DSSDBG("FRAMEDONE\n");
18603 + perf_show("DISPC");
18605 + REG_FLD_MOD(RFBI_CONTROL, 0, 0, 0);
18607 + rfbi_enable_clocks(0);
18609 + callback = rfbi.framedone_callback;
18610 + rfbi.framedone_callback = NULL;
18612 + /*callback(rfbi.framedone_callback_data);*/
18614 + atomic_set(&rfbi.cmd_pending, 0);
18616 + process_cmd_fifo();
18619 +#if 1 /* VERBOSE */
18620 +static void rfbi_print_timings(void)
18622 + u32 l;
18623 + u32 time;
18625 + l = rfbi_read_reg(RFBI_CONFIG(0));
18626 + time = 1000000000 / rfbi.l4_khz;
18627 + if (l & (1 << 4))
18628 + time *= 2;
18630 + DSSDBG("Tick time %u ps\n", time);
18631 + l = rfbi_read_reg(RFBI_ONOFF_TIME(0));
18632 + DSSDBG("CSONTIME %d, CSOFFTIME %d, WEONTIME %d, WEOFFTIME %d, "
18633 + "REONTIME %d, REOFFTIME %d\n",
18634 + l & 0x0f, (l >> 4) & 0x3f, (l >> 10) & 0x0f, (l >> 14) & 0x3f,
18635 + (l >> 20) & 0x0f, (l >> 24) & 0x3f);
18637 + l = rfbi_read_reg(RFBI_CYCLE_TIME(0));
18638 + DSSDBG("WECYCLETIME %d, RECYCLETIME %d, CSPULSEWIDTH %d, "
18639 + "ACCESSTIME %d\n",
18640 + (l & 0x3f), (l >> 6) & 0x3f, (l >> 12) & 0x3f,
18641 + (l >> 22) & 0x3f);
18643 +#else
18644 +static void rfbi_print_timings(void) {}
18645 +#endif
18650 +static u32 extif_clk_period;
18652 +static inline unsigned long round_to_extif_ticks(unsigned long ps, int div)
18654 + int bus_tick = extif_clk_period * div;
18655 + return (ps + bus_tick - 1) / bus_tick * bus_tick;
18658 +static int calc_reg_timing(struct rfbi_timings *t, int div)
18660 + t->clk_div = div;
18662 + t->cs_on_time = round_to_extif_ticks(t->cs_on_time, div);
18664 + t->we_on_time = round_to_extif_ticks(t->we_on_time, div);
18665 + t->we_off_time = round_to_extif_ticks(t->we_off_time, div);
18666 + t->we_cycle_time = round_to_extif_ticks(t->we_cycle_time, div);
18668 + t->re_on_time = round_to_extif_ticks(t->re_on_time, div);
18669 + t->re_off_time = round_to_extif_ticks(t->re_off_time, div);
18670 + t->re_cycle_time = round_to_extif_ticks(t->re_cycle_time, div);
18672 + t->access_time = round_to_extif_ticks(t->access_time, div);
18673 + t->cs_off_time = round_to_extif_ticks(t->cs_off_time, div);
18674 + t->cs_pulse_width = round_to_extif_ticks(t->cs_pulse_width, div);
18676 + DSSDBG("[reg]cson %d csoff %d reon %d reoff %d\n",
18677 + t->cs_on_time, t->cs_off_time, t->re_on_time, t->re_off_time);
18678 + DSSDBG("[reg]weon %d weoff %d recyc %d wecyc %d\n",
18679 + t->we_on_time, t->we_off_time, t->re_cycle_time,
18680 + t->we_cycle_time);
18681 + DSSDBG("[reg]rdaccess %d cspulse %d\n",
18682 + t->access_time, t->cs_pulse_width);
18684 + return rfbi_convert_timings(t);
18687 +static int calc_extif_timings(struct rfbi_timings *t)
18689 + u32 max_clk_div;
18690 + int div;
18692 + rfbi_get_clk_info(&extif_clk_period, &max_clk_div);
18693 + for (div = 1; div <= max_clk_div; div++) {
18694 + if (calc_reg_timing(t, div) == 0)
18695 + break;
18698 + if (div <= max_clk_div)
18699 + return 0;
18701 + DSSERR("can't setup timings\n");
18702 + return -1;
18706 +void rfbi_set_timings(int rfbi_module, struct rfbi_timings *t)
18708 + int r;
18710 + if (!t->converted) {
18711 + r = calc_extif_timings(t);
18712 + if (r < 0)
18713 + DSSERR("Failed to calc timings\n");
18716 + BUG_ON(!t->converted);
18718 + rfbi_enable_clocks(1);
18719 + rfbi_write_reg(RFBI_ONOFF_TIME(rfbi_module), t->tim[0]);
18720 + rfbi_write_reg(RFBI_CYCLE_TIME(rfbi_module), t->tim[1]);
18722 + /* TIMEGRANULARITY */
18723 + REG_FLD_MOD(RFBI_CONFIG(rfbi_module),
18724 + (t->tim[2] ? 1 : 0), 4, 4);
18726 + rfbi_print_timings();
18727 + rfbi_enable_clocks(0);
18730 +static int ps_to_rfbi_ticks(int time, int div)
18732 + unsigned long tick_ps;
18733 + int ret;
18735 + /* Calculate in picosecs to yield more exact results */
18736 + tick_ps = 1000000000 / (rfbi.l4_khz) * div;
18738 + ret = (time + tick_ps - 1) / tick_ps;
18740 + return ret;
18743 +#ifdef OMAP_RFBI_RATE_LIMIT
18744 +unsigned long rfbi_get_max_tx_rate(void)
18746 + unsigned long l4_rate, dss1_rate;
18747 + int min_l4_ticks = 0;
18748 + int i;
18750 + /* According to TI this can't be calculated so make the
18751 + * adjustments for a couple of known frequencies and warn for
18752 + * others.
18753 + */
18754 + static const struct {
18755 + unsigned long l4_clk; /* HZ */
18756 + unsigned long dss1_clk; /* HZ */
18757 + unsigned long min_l4_ticks;
18758 + } ftab[] = {
18759 + { 55, 132, 7, }, /* 7.86 MPix/s */
18760 + { 110, 110, 12, }, /* 9.16 MPix/s */
18761 + { 110, 132, 10, }, /* 11 Mpix/s */
18762 + { 120, 120, 10, }, /* 12 Mpix/s */
18763 + { 133, 133, 10, }, /* 13.3 Mpix/s */
18764 + };
18766 + l4_rate = rfbi.l4_khz / 1000;
18767 + dss1_rate = dss_clk_get_rate(DSS_CLK_FCK1) / 1000000;
18769 + for (i = 0; i < ARRAY_SIZE(ftab); i++) {
18770 + /* Use a window instead of an exact match, to account
18771 + * for different DPLL multiplier / divider pairs.
18772 + */
18773 + if (abs(ftab[i].l4_clk - l4_rate) < 3 &&
18774 + abs(ftab[i].dss1_clk - dss1_rate) < 3) {
18775 + min_l4_ticks = ftab[i].min_l4_ticks;
18776 + break;
18779 + if (i == ARRAY_SIZE(ftab)) {
18780 + /* Can't be sure, return anyway the maximum not
18781 + * rate-limited. This might cause a problem only for the
18782 + * tearing synchronisation.
18783 + */
18784 + DSSERR("can't determine maximum RFBI transfer rate\n");
18785 + return rfbi.l4_khz * 1000;
18787 + return rfbi.l4_khz * 1000 / min_l4_ticks;
18789 +#else
18790 +int rfbi_get_max_tx_rate(void)
18792 + return rfbi.l4_khz * 1000;
18794 +#endif
18796 +static void rfbi_get_clk_info(u32 *clk_period, u32 *max_clk_div)
18798 + *clk_period = 1000000000 / rfbi.l4_khz;
18799 + *max_clk_div = 2;
18802 +static int rfbi_convert_timings(struct rfbi_timings *t)
18804 + u32 l;
18805 + int reon, reoff, weon, weoff, cson, csoff, cs_pulse;
18806 + int actim, recyc, wecyc;
18807 + int div = t->clk_div;
18809 + if (div <= 0 || div > 2)
18810 + return -1;
18812 + /* Make sure that after conversion it still holds that:
18813 + * weoff > weon, reoff > reon, recyc >= reoff, wecyc >= weoff,
18814 + * csoff > cson, csoff >= max(weoff, reoff), actim > reon
18815 + */
18816 + weon = ps_to_rfbi_ticks(t->we_on_time, div);
18817 + weoff = ps_to_rfbi_ticks(t->we_off_time, div);
18818 + if (weoff <= weon)
18819 + weoff = weon + 1;
18820 + if (weon > 0x0f)
18821 + return -1;
18822 + if (weoff > 0x3f)
18823 + return -1;
18825 + reon = ps_to_rfbi_ticks(t->re_on_time, div);
18826 + reoff = ps_to_rfbi_ticks(t->re_off_time, div);
18827 + if (reoff <= reon)
18828 + reoff = reon + 1;
18829 + if (reon > 0x0f)
18830 + return -1;
18831 + if (reoff > 0x3f)
18832 + return -1;
18834 + cson = ps_to_rfbi_ticks(t->cs_on_time, div);
18835 + csoff = ps_to_rfbi_ticks(t->cs_off_time, div);
18836 + if (csoff <= cson)
18837 + csoff = cson + 1;
18838 + if (csoff < max(weoff, reoff))
18839 + csoff = max(weoff, reoff);
18840 + if (cson > 0x0f)
18841 + return -1;
18842 + if (csoff > 0x3f)
18843 + return -1;
18845 + l = cson;
18846 + l |= csoff << 4;
18847 + l |= weon << 10;
18848 + l |= weoff << 14;
18849 + l |= reon << 20;
18850 + l |= reoff << 24;
18852 + t->tim[0] = l;
18854 + actim = ps_to_rfbi_ticks(t->access_time, div);
18855 + if (actim <= reon)
18856 + actim = reon + 1;
18857 + if (actim > 0x3f)
18858 + return -1;
18860 + wecyc = ps_to_rfbi_ticks(t->we_cycle_time, div);
18861 + if (wecyc < weoff)
18862 + wecyc = weoff;
18863 + if (wecyc > 0x3f)
18864 + return -1;
18866 + recyc = ps_to_rfbi_ticks(t->re_cycle_time, div);
18867 + if (recyc < reoff)
18868 + recyc = reoff;
18869 + if (recyc > 0x3f)
18870 + return -1;
18872 + cs_pulse = ps_to_rfbi_ticks(t->cs_pulse_width, div);
18873 + if (cs_pulse > 0x3f)
18874 + return -1;
18876 + l = wecyc;
18877 + l |= recyc << 6;
18878 + l |= cs_pulse << 12;
18879 + l |= actim << 22;
18881 + t->tim[1] = l;
18883 + t->tim[2] = div - 1;
18885 + t->converted = 1;
18887 + return 0;
18890 +/* xxx FIX module selection missing */
18891 +int omap_rfbi_setup_te(enum omap_rfbi_te_mode mode,
18892 + unsigned hs_pulse_time, unsigned vs_pulse_time,
18893 + int hs_pol_inv, int vs_pol_inv, int extif_div)
18895 + int hs, vs;
18896 + int min;
18897 + u32 l;
18899 + hs = ps_to_rfbi_ticks(hs_pulse_time, 1);
18900 + vs = ps_to_rfbi_ticks(vs_pulse_time, 1);
18901 + if (hs < 2)
18902 + return -EDOM;
18903 + if (mode == OMAP_DSS_RFBI_TE_MODE_2)
18904 + min = 2;
18905 + else /* OMAP_DSS_RFBI_TE_MODE_1 */
18906 + min = 4;
18907 + if (vs < min)
18908 + return -EDOM;
18909 + if (vs == hs)
18910 + return -EINVAL;
18911 + rfbi.te_mode = mode;
18912 + DSSDBG("setup_te: mode %d hs %d vs %d hs_inv %d vs_inv %d\n",
18913 + mode, hs, vs, hs_pol_inv, vs_pol_inv);
18915 + rfbi_enable_clocks(1);
18916 + rfbi_write_reg(RFBI_HSYNC_WIDTH, hs);
18917 + rfbi_write_reg(RFBI_VSYNC_WIDTH, vs);
18919 + l = rfbi_read_reg(RFBI_CONFIG(0));
18920 + if (hs_pol_inv)
18921 + l &= ~(1 << 21);
18922 + else
18923 + l |= 1 << 21;
18924 + if (vs_pol_inv)
18925 + l &= ~(1 << 20);
18926 + else
18927 + l |= 1 << 20;
18928 + rfbi_enable_clocks(0);
18930 + return 0;
18932 +EXPORT_SYMBOL(omap_rfbi_setup_te);
18934 +/* xxx FIX module selection missing */
18935 +int omap_rfbi_enable_te(bool enable, unsigned line)
18937 + u32 l;
18939 + DSSDBG("te %d line %d mode %d\n", enable, line, rfbi.te_mode);
18940 + if (line > (1 << 11) - 1)
18941 + return -EINVAL;
18943 + rfbi_enable_clocks(1);
18944 + l = rfbi_read_reg(RFBI_CONFIG(0));
18945 + l &= ~(0x3 << 2);
18946 + if (enable) {
18947 + rfbi.te_enabled = 1;
18948 + l |= rfbi.te_mode << 2;
18949 + } else
18950 + rfbi.te_enabled = 0;
18951 + rfbi_write_reg(RFBI_CONFIG(0), l);
18952 + rfbi_write_reg(RFBI_LINE_NUMBER, line);
18953 + rfbi_enable_clocks(0);
18955 + return 0;
18957 +EXPORT_SYMBOL(omap_rfbi_enable_te);
18959 +#if 0
18960 +static void rfbi_enable_config(int enable1, int enable2)
18962 + u32 l;
18963 + int cs = 0;
18965 + if (enable1)
18966 + cs |= 1<<0;
18967 + if (enable2)
18968 + cs |= 1<<1;
18970 + rfbi_enable_clocks(1);
18972 + l = rfbi_read_reg(RFBI_CONTROL);
18974 + l = FLD_MOD(l, cs, 3, 2);
18975 + l = FLD_MOD(l, 0, 1, 1);
18977 + rfbi_write_reg(RFBI_CONTROL, l);
18980 + l = rfbi_read_reg(RFBI_CONFIG(0));
18981 + l = FLD_MOD(l, 0, 3, 2); /* TRIGGERMODE: ITE */
18982 + /*l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
18983 + /*l |= FLD_VAL(0, 8, 7); */ /* L4FORMAT, 1pix/L4 */
18985 + l = FLD_MOD(l, 0, 16, 16); /* A0POLARITY */
18986 + l = FLD_MOD(l, 1, 20, 20); /* TE_VSYNC_POLARITY */
18987 + l = FLD_MOD(l, 1, 21, 21); /* HSYNCPOLARITY */
18989 + l = FLD_MOD(l, OMAP_DSS_RFBI_PARALLELMODE_8, 1, 0);
18990 + rfbi_write_reg(RFBI_CONFIG(0), l);
18992 + rfbi_enable_clocks(0);
18994 +#endif
18996 +int rfbi_configure(int rfbi_module, int bpp, int lines)
18998 + u32 l;
18999 + int cycle1 = 0, cycle2 = 0, cycle3 = 0;
19000 + enum omap_rfbi_cycleformat cycleformat;
19001 + enum omap_rfbi_datatype datatype;
19002 + enum omap_rfbi_parallelmode parallelmode;
19004 + switch (bpp) {
19005 + case 12:
19006 + datatype = OMAP_DSS_RFBI_DATATYPE_12;
19007 + break;
19008 + case 16:
19009 + datatype = OMAP_DSS_RFBI_DATATYPE_16;
19010 + break;
19011 + case 18:
19012 + datatype = OMAP_DSS_RFBI_DATATYPE_18;
19013 + break;
19014 + case 24:
19015 + datatype = OMAP_DSS_RFBI_DATATYPE_24;
19016 + break;
19017 + default:
19018 + BUG();
19019 + return 1;
19021 + rfbi.datatype = datatype;
19023 + switch (lines) {
19024 + case 8:
19025 + parallelmode = OMAP_DSS_RFBI_PARALLELMODE_8;
19026 + break;
19027 + case 9:
19028 + parallelmode = OMAP_DSS_RFBI_PARALLELMODE_9;
19029 + break;
19030 + case 12:
19031 + parallelmode = OMAP_DSS_RFBI_PARALLELMODE_12;
19032 + break;
19033 + case 16:
19034 + parallelmode = OMAP_DSS_RFBI_PARALLELMODE_16;
19035 + break;
19036 + default:
19037 + BUG();
19038 + return 1;
19040 + rfbi.parallelmode = parallelmode;
19042 + if ((bpp % lines) == 0) {
19043 + switch (bpp / lines) {
19044 + case 1:
19045 + cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_1_1;
19046 + break;
19047 + case 2:
19048 + cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_2_1;
19049 + break;
19050 + case 3:
19051 + cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_1;
19052 + break;
19053 + default:
19054 + BUG();
19055 + return 1;
19057 + } else if ((2 * bpp % lines) == 0) {
19058 + if ((2 * bpp / lines) == 3)
19059 + cycleformat = OMAP_DSS_RFBI_CYCLEFORMAT_3_2;
19060 + else {
19061 + BUG();
19062 + return 1;
19064 + } else {
19065 + BUG();
19066 + return 1;
19069 + switch (cycleformat) {
19070 + case OMAP_DSS_RFBI_CYCLEFORMAT_1_1:
19071 + cycle1 = lines;
19072 + break;
19074 + case OMAP_DSS_RFBI_CYCLEFORMAT_2_1:
19075 + cycle1 = lines;
19076 + cycle2 = lines;
19077 + break;
19079 + case OMAP_DSS_RFBI_CYCLEFORMAT_3_1:
19080 + cycle1 = lines;
19081 + cycle2 = lines;
19082 + cycle3 = lines;
19083 + break;
19085 + case OMAP_DSS_RFBI_CYCLEFORMAT_3_2:
19086 + cycle1 = lines;
19087 + cycle2 = (lines / 2) | ((lines / 2) << 16);
19088 + cycle3 = (lines << 16);
19089 + break;
19092 + rfbi_enable_clocks(1);
19094 + REG_FLD_MOD(RFBI_CONTROL, 0, 3, 2); /* clear CS */
19096 + l = 0;
19097 + l |= FLD_VAL(parallelmode, 1, 0);
19098 + l |= FLD_VAL(0, 3, 2); /* TRIGGERMODE: ITE */
19099 + l |= FLD_VAL(0, 4, 4); /* TIMEGRANULARITY */
19100 + l |= FLD_VAL(datatype, 6, 5);
19101 + /* l |= FLD_VAL(2, 8, 7); */ /* L4FORMAT, 2pix/L4 */
19102 + l |= FLD_VAL(0, 8, 7); /* L4FORMAT, 1pix/L4 */
19103 + l |= FLD_VAL(cycleformat, 10, 9);
19104 + l |= FLD_VAL(0, 12, 11); /* UNUSEDBITS */
19105 + l |= FLD_VAL(0, 16, 16); /* A0POLARITY */
19106 + l |= FLD_VAL(0, 17, 17); /* REPOLARITY */
19107 + l |= FLD_VAL(0, 18, 18); /* WEPOLARITY */
19108 + l |= FLD_VAL(0, 19, 19); /* CSPOLARITY */
19109 + l |= FLD_VAL(1, 20, 20); /* TE_VSYNC_POLARITY */
19110 + l |= FLD_VAL(1, 21, 21); /* HSYNCPOLARITY */
19111 + rfbi_write_reg(RFBI_CONFIG(rfbi_module), l);
19113 + rfbi_write_reg(RFBI_DATA_CYCLE1(rfbi_module), cycle1);
19114 + rfbi_write_reg(RFBI_DATA_CYCLE2(rfbi_module), cycle2);
19115 + rfbi_write_reg(RFBI_DATA_CYCLE3(rfbi_module), cycle3);
19118 + l = rfbi_read_reg(RFBI_CONTROL);
19119 + l = FLD_MOD(l, rfbi_module+1, 3, 2); /* Select CSx */
19120 + l = FLD_MOD(l, 0, 1, 1); /* clear bypass */
19121 + rfbi_write_reg(RFBI_CONTROL, l);
19124 + DSSDBG("RFBI config: bpp %d, lines %d, cycles: 0x%x 0x%x 0x%x\n",
19125 + bpp, lines, cycle1, cycle2, cycle3);
19127 + rfbi_enable_clocks(0);
19129 + return 0;
19131 +EXPORT_SYMBOL(rfbi_configure);
19133 +static int rfbi_find_display(struct omap_display *disp)
19135 + if (disp == rfbi.display[0])
19136 + return 0;
19138 + if (disp == rfbi.display[1])
19139 + return 1;
19141 + BUG();
19142 + return -1;
19146 +static void signal_fifo_waiters(void)
19148 + if (atomic_read(&rfbi.cmd_fifo_full) > 0) {
19149 + /* DSSDBG("SIGNALING: Fifo not full for waiter!\n"); */
19150 + complete(&rfbi.cmd_done);
19151 + atomic_dec(&rfbi.cmd_fifo_full);
19155 +/* returns 1 for async op, and 0 for sync op */
19156 +static int do_update(struct omap_display *display, struct update_region *upd)
19158 + u16 x = upd->x;
19159 + u16 y = upd->y;
19160 + u16 w = upd->w;
19161 + u16 h = upd->h;
19163 + perf_mark_setup();
19165 + if (display->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
19166 + /*display->ctrl->enable_te(display, 1); */
19167 + dispc_setup_partial_planes(display, &x, &y, &w, &h);
19170 +#ifdef MEASURE_PERF
19171 + rfbi.perf_bytes = w * h * 2; /* XXX always 16bit */
19172 +#endif
19174 + display->ctrl->setup_update(display, x, y, w, h);
19176 + if (display->manager->caps & OMAP_DSS_OVL_MGR_CAP_DISPC) {
19177 + rfbi_transfer_area(w, h, NULL, NULL);
19178 + return 1;
19179 + } else {
19180 + struct omap_overlay *ovl;
19181 + void __iomem *addr;
19182 + int scr_width;
19184 + ovl = display->manager->overlays[0];
19185 + scr_width = ovl->info.screen_width;
19186 + addr = ovl->info.vaddr;
19188 + omap_rfbi_write_pixels(addr, scr_width, x, y, w, h);
19190 + perf_show("L4");
19192 + return 0;
19196 +static void process_cmd_fifo(void)
19198 + int len;
19199 + struct update_param p;
19200 + struct omap_display *display;
19201 + unsigned long flags;
19203 + if (atomic_inc_return(&rfbi.cmd_pending) != 1)
19204 + return;
19206 + while (true) {
19207 + spin_lock_irqsave(rfbi.cmd_fifo->lock, flags);
19209 + len = __kfifo_get(rfbi.cmd_fifo, (unsigned char *)&p,
19210 + sizeof(struct update_param));
19211 + if (len == 0) {
19212 + DSSDBG("nothing more in fifo\n");
19213 + atomic_set(&rfbi.cmd_pending, 0);
19214 + spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
19215 + break;
19218 + /* DSSDBG("fifo full %d\n", rfbi.cmd_fifo_full.counter);*/
19220 + spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
19222 + BUG_ON(len != sizeof(struct update_param));
19223 + BUG_ON(p.rfbi_module > 1);
19225 + display = rfbi.display[p.rfbi_module];
19227 + if (p.cmd == RFBI_CMD_UPDATE) {
19228 + if (do_update(display, &p.par.r))
19229 + break; /* async op */
19230 + } else if (p.cmd == RFBI_CMD_SYNC) {
19231 + DSSDBG("Signaling SYNC done!\n");
19232 + complete(p.par.sync);
19233 + } else
19234 + BUG();
19237 + signal_fifo_waiters();
19240 +static void rfbi_push_cmd(struct update_param *p)
19242 + int ret;
19244 + while (1) {
19245 + unsigned long flags;
19246 + int available;
19248 + spin_lock_irqsave(rfbi.cmd_fifo->lock, flags);
19249 + available = RFBI_CMD_FIFO_LEN_BYTES -
19250 + __kfifo_len(rfbi.cmd_fifo);
19252 +/* DSSDBG("%d bytes left in fifo\n", available); */
19253 + if (available < sizeof(struct update_param)) {
19254 + DSSDBG("Going to wait because FIFO FULL..\n");
19255 + spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
19256 + atomic_inc(&rfbi.cmd_fifo_full);
19257 + wait_for_completion(&rfbi.cmd_done);
19258 + /*DSSDBG("Woke up because fifo not full anymore\n");*/
19259 + continue;
19262 + ret = __kfifo_put(rfbi.cmd_fifo, (unsigned char *)p,
19263 + sizeof(struct update_param));
19264 +/* DSSDBG("pushed %d bytes\n", ret);*/
19266 + spin_unlock_irqrestore(rfbi.cmd_fifo->lock, flags);
19268 + BUG_ON(ret != sizeof(struct update_param));
19270 + break;
19274 +static void rfbi_push_update(int rfbi_module, int x, int y, int w, int h)
19276 + struct update_param p;
19278 + p.rfbi_module = rfbi_module;
19279 + p.cmd = RFBI_CMD_UPDATE;
19281 + p.par.r.x = x;
19282 + p.par.r.y = y;
19283 + p.par.r.w = w;
19284 + p.par.r.h = h;
19286 + DSSDBG("RFBI pushed %d,%d %dx%d\n", x, y, w, h);
19288 + rfbi_push_cmd(&p);
19290 + process_cmd_fifo();
19293 +static void rfbi_push_sync(int rfbi_module, struct completion *sync_comp)
19295 + struct update_param p;
19297 + p.rfbi_module = rfbi_module;
19298 + p.cmd = RFBI_CMD_SYNC;
19299 + p.par.sync = sync_comp;
19301 + rfbi_push_cmd(&p);
19303 + DSSDBG("RFBI sync pushed to cmd fifo\n");
19305 + process_cmd_fifo();
19308 +void rfbi_dump_regs(struct seq_file *s)
19310 +#define DUMPREG(r) seq_printf(s, "%-35s %08x\n", #r, rfbi_read_reg(r))
19312 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
19314 + DUMPREG(RFBI_REVISION);
19315 + DUMPREG(RFBI_SYSCONFIG);
19316 + DUMPREG(RFBI_SYSSTATUS);
19317 + DUMPREG(RFBI_CONTROL);
19318 + DUMPREG(RFBI_PIXEL_CNT);
19319 + DUMPREG(RFBI_LINE_NUMBER);
19320 + DUMPREG(RFBI_CMD);
19321 + DUMPREG(RFBI_PARAM);
19322 + DUMPREG(RFBI_DATA);
19323 + DUMPREG(RFBI_READ);
19324 + DUMPREG(RFBI_STATUS);
19326 + DUMPREG(RFBI_CONFIG(0));
19327 + DUMPREG(RFBI_ONOFF_TIME(0));
19328 + DUMPREG(RFBI_CYCLE_TIME(0));
19329 + DUMPREG(RFBI_DATA_CYCLE1(0));
19330 + DUMPREG(RFBI_DATA_CYCLE2(0));
19331 + DUMPREG(RFBI_DATA_CYCLE3(0));
19333 + DUMPREG(RFBI_CONFIG(1));
19334 + DUMPREG(RFBI_ONOFF_TIME(1));
19335 + DUMPREG(RFBI_CYCLE_TIME(1));
19336 + DUMPREG(RFBI_DATA_CYCLE1(1));
19337 + DUMPREG(RFBI_DATA_CYCLE2(1));
19338 + DUMPREG(RFBI_DATA_CYCLE3(1));
19340 + DUMPREG(RFBI_VSYNC_WIDTH);
19341 + DUMPREG(RFBI_HSYNC_WIDTH);
19343 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
19344 +#undef DUMPREG
19347 +int rfbi_init(void)
19349 + u32 rev;
19350 + u32 l;
19352 + spin_lock_init(&rfbi.cmd_lock);
19353 + rfbi.cmd_fifo = kfifo_alloc(RFBI_CMD_FIFO_LEN_BYTES, GFP_KERNEL,
19354 + &rfbi.cmd_lock);
19355 + if (IS_ERR(rfbi.cmd_fifo))
19356 + return -ENOMEM;
19358 + init_completion(&rfbi.cmd_done);
19359 + atomic_set(&rfbi.cmd_fifo_full, 0);
19360 + atomic_set(&rfbi.cmd_pending, 0);
19362 + rfbi.base = ioremap(RFBI_BASE, SZ_256);
19363 + if (!rfbi.base) {
19364 + DSSERR("can't ioremap RFBI\n");
19365 + return -ENOMEM;
19368 + rfbi_enable_clocks(1);
19370 + msleep(10);
19372 + rfbi.l4_khz = dss_clk_get_rate(DSS_CLK_ICK) / 1000;
19374 + /* Enable autoidle and smart-idle */
19375 + l = rfbi_read_reg(RFBI_SYSCONFIG);
19376 + l |= (1 << 0) | (2 << 3);
19377 + rfbi_write_reg(RFBI_SYSCONFIG, l);
19379 + rev = rfbi_read_reg(RFBI_REVISION);
19380 + printk(KERN_INFO "OMAP RFBI rev %d.%d\n",
19381 + FLD_GET(rev, 7, 4), FLD_GET(rev, 3, 0));
19383 + rfbi_enable_clocks(0);
19385 + return 0;
19388 +void rfbi_exit(void)
19390 + DSSDBG("rfbi_exit\n");
19392 + kfifo_free(rfbi.cmd_fifo);
19394 + iounmap(rfbi.base);
19397 +/* struct omap_display support */
19398 +static int rfbi_display_update(struct omap_display *display,
19399 + u16 x, u16 y, u16 w, u16 h)
19401 + int rfbi_module;
19403 + if (w == 0 || h == 0)
19404 + return 0;
19406 + rfbi_module = rfbi_find_display(display);
19408 + rfbi_push_update(rfbi_module, x, y, w, h);
19410 + return 0;
19413 +static int rfbi_display_sync(struct omap_display *display)
19415 + struct completion sync_comp;
19416 + int rfbi_module;
19418 + rfbi_module = rfbi_find_display(display);
19420 + init_completion(&sync_comp);
19421 + rfbi_push_sync(rfbi_module, &sync_comp);
19422 + DSSDBG("Waiting for SYNC to happen...\n");
19423 + wait_for_completion(&sync_comp);
19424 + DSSDBG("Released from SYNC\n");
19425 + return 0;
19428 +static int rfbi_display_enable_te(struct omap_display *display, bool enable)
19430 + display->ctrl->enable_te(display, enable);
19431 + return 0;
19434 +static int rfbi_display_enable(struct omap_display *display)
19436 + int r;
19438 + BUG_ON(display->panel == NULL || display->ctrl == NULL);
19440 + r = omap_dispc_register_isr(framedone_callback, NULL,
19441 + DISPC_IRQ_FRAMEDONE);
19442 + if (r) {
19443 + DSSERR("can't get FRAMEDONE irq\n");
19444 + return r;
19447 + dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT);
19449 + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_RFBI);
19451 + dispc_set_tft_data_lines(display->ctrl->pixel_size);
19453 + rfbi_configure(display->hw_config.u.rfbi.channel,
19454 + display->ctrl->pixel_size,
19455 + display->hw_config.u.rfbi.data_lines);
19457 + rfbi_set_timings(display->hw_config.u.rfbi.channel,
19458 + &display->ctrl->timings);
19461 + if (display->ctrl && display->ctrl->enable) {
19462 + r = display->ctrl->enable(display);
19463 + if (r)
19464 + goto err;
19467 + if (display->panel && display->panel->enable) {
19468 + r = display->panel->enable(display);
19469 + if (r)
19470 + goto err;
19473 + return 0;
19474 +err:
19475 + return -ENODEV;
19478 +static void rfbi_display_disable(struct omap_display *display)
19480 + display->ctrl->disable(display);
19481 + omap_dispc_unregister_isr(framedone_callback, NULL,
19482 + DISPC_IRQ_FRAMEDONE);
19485 +void rfbi_init_display(struct omap_display *display)
19487 + display->enable = rfbi_display_enable;
19488 + display->disable = rfbi_display_disable;
19489 + display->update = rfbi_display_update;
19490 + display->sync = rfbi_display_sync;
19491 + display->enable_te = rfbi_display_enable_te;
19493 + rfbi.display[display->hw_config.u.rfbi.channel] = display;
19495 + display->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE;
19497 diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/omap2/dss/sdi.c
19498 new file mode 100644
19499 index 0000000..fbff2b2
19500 --- /dev/null
19501 +++ b/drivers/video/omap2/dss/sdi.c
19502 @@ -0,0 +1,245 @@
19504 + * linux/drivers/video/omap2/dss/sdi.c
19506 + * Copyright (C) 2009 Nokia Corporation
19507 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
19509 + * This program is free software; you can redistribute it and/or modify it
19510 + * under the terms of the GNU General Public License version 2 as published by
19511 + * the Free Software Foundation.
19513 + * This program is distributed in the hope that it will be useful, but WITHOUT
19514 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19515 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19516 + * more details.
19518 + * You should have received a copy of the GNU General Public License along with
19519 + * this program. If not, see <http://www.gnu.org/licenses/>.
19520 + */
19522 +#define DSS_SUBSYS_NAME "SDI"
19524 +#include <linux/kernel.h>
19525 +#include <linux/clk.h>
19526 +#include <linux/delay.h>
19527 +#include <linux/err.h>
19529 +#include <mach/board.h>
19530 +#include <mach/display.h>
19531 +#include "dss.h"
19534 +static struct {
19535 + bool skip_init;
19536 + bool update_enabled;
19537 +} sdi;
19539 +static void sdi_basic_init(void)
19541 + dispc_set_parallel_interface_mode(OMAP_DSS_PARALLELMODE_BYPASS);
19543 + dispc_set_lcd_display_type(OMAP_DSS_LCD_DISPLAY_TFT);
19544 + dispc_set_tft_data_lines(24);
19545 + dispc_lcd_enable_signal_polarity(1);
19548 +static int sdi_display_enable(struct omap_display *display)
19550 + struct dispc_clock_info cinfo;
19551 + u16 lck_div, pck_div;
19552 + unsigned long fck;
19553 + struct omap_panel *panel = display->panel;
19554 + unsigned long pck;
19555 + int r;
19557 + if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
19558 + DSSERR("display already enabled\n");
19559 + return -EINVAL;
19562 + /* In case of skip_init sdi_init has already enabled the clocks */
19563 + if (!sdi.skip_init)
19564 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
19566 + sdi_basic_init();
19568 + /* 15.5.9.1.2 */
19569 + panel->config |= OMAP_DSS_LCD_RF | OMAP_DSS_LCD_ONOFF;
19571 + dispc_set_pol_freq(panel);
19573 + if (!sdi.skip_init)
19574 + r = dispc_calc_clock_div(1, panel->timings.pixel_clock * 1000,
19575 + &cinfo);
19576 + else
19577 + r = dispc_get_clock_div(&cinfo);
19579 + if (r)
19580 + goto err0;
19582 + fck = cinfo.fck;
19583 + lck_div = cinfo.lck_div;
19584 + pck_div = cinfo.pck_div;
19586 + pck = fck / lck_div / pck_div / 1000;
19588 + if (pck != panel->timings.pixel_clock) {
19589 + DSSWARN("Could not find exact pixel clock. Requested %d kHz, "
19590 + "got %lu kHz\n",
19591 + panel->timings.pixel_clock, pck);
19593 + panel->timings.pixel_clock = pck;
19597 + dispc_set_lcd_timings(&panel->timings);
19599 + r = dispc_set_clock_div(&cinfo);
19600 + if (r)
19601 + goto err1;
19603 + if (!sdi.skip_init) {
19604 + dss_sdi_init(display->hw_config.u.sdi.datapairs);
19605 + dss_sdi_enable();
19606 + mdelay(2);
19609 + dispc_enable_lcd_out(1);
19611 + r = panel->enable(display);
19612 + if (r)
19613 + goto err2;
19615 + display->state = OMAP_DSS_DISPLAY_ACTIVE;
19617 + sdi.skip_init = 0;
19619 + return 0;
19620 +err2:
19621 + dispc_enable_lcd_out(0);
19622 +err1:
19623 +err0:
19624 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
19625 + return r;
19628 +static int sdi_display_resume(struct omap_display *display);
19630 +static void sdi_display_disable(struct omap_display *display)
19632 + if (display->state == OMAP_DSS_DISPLAY_DISABLED)
19633 + return;
19635 + if (display->state == OMAP_DSS_DISPLAY_SUSPENDED)
19636 + sdi_display_resume(display);
19638 + display->panel->disable(display);
19640 + dispc_enable_lcd_out(0);
19642 + dss_sdi_disable();
19644 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
19646 + display->state = OMAP_DSS_DISPLAY_DISABLED;
19649 +static int sdi_display_suspend(struct omap_display *display)
19651 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
19652 + return -EINVAL;
19654 + if (display->panel->suspend)
19655 + display->panel->suspend(display);
19657 + dispc_enable_lcd_out(0);
19659 + dss_sdi_disable();
19661 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1);
19663 + display->state = OMAP_DSS_DISPLAY_SUSPENDED;
19665 + return 0;
19668 +static int sdi_display_resume(struct omap_display *display)
19670 + if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
19671 + return -EINVAL;
19673 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
19675 + dss_sdi_enable();
19676 + mdelay(2);
19678 + dispc_enable_lcd_out(1);
19680 + if (display->panel->resume)
19681 + display->panel->resume(display);
19683 + display->state = OMAP_DSS_DISPLAY_ACTIVE;
19685 + return 0;
19688 +static int sdi_display_set_update_mode(struct omap_display *display,
19689 + enum omap_dss_update_mode mode)
19691 + if (mode == OMAP_DSS_UPDATE_MANUAL)
19692 + return -EINVAL;
19694 + if (mode == OMAP_DSS_UPDATE_DISABLED) {
19695 + dispc_enable_lcd_out(0);
19696 + sdi.update_enabled = 0;
19697 + } else {
19698 + dispc_enable_lcd_out(1);
19699 + sdi.update_enabled = 1;
19702 + return 0;
19705 +static enum omap_dss_update_mode sdi_display_get_update_mode(
19706 + struct omap_display *display)
19708 + return sdi.update_enabled ? OMAP_DSS_UPDATE_AUTO :
19709 + OMAP_DSS_UPDATE_DISABLED;
19712 +static void sdi_get_timings(struct omap_display *display,
19713 + struct omap_video_timings *timings)
19715 + *timings = display->panel->timings;
19718 +void sdi_init_display(struct omap_display *display)
19720 + DSSDBG("SDI init\n");
19722 + display->enable = sdi_display_enable;
19723 + display->disable = sdi_display_disable;
19724 + display->suspend = sdi_display_suspend;
19725 + display->resume = sdi_display_resume;
19726 + display->set_update_mode = sdi_display_set_update_mode;
19727 + display->get_update_mode = sdi_display_get_update_mode;
19728 + display->get_timings = sdi_get_timings;
19731 +int sdi_init(bool skip_init)
19733 + /* we store this for first display enable, then clear it */
19734 + sdi.skip_init = skip_init;
19736 + /*
19737 + * Enable clocks already here, otherwise there would be a toggle
19738 + * of them until sdi_display_enable is called.
19739 + */
19740 + if (skip_init)
19741 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1);
19742 + return 0;
19745 +void sdi_exit(void)
19748 diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/omap2/dss/venc.c
19749 new file mode 100644
19750 index 0000000..aceed9f
19751 --- /dev/null
19752 +++ b/drivers/video/omap2/dss/venc.c
19753 @@ -0,0 +1,600 @@
19755 + * linux/drivers/video/omap2/dss/venc.c
19757 + * Copyright (C) 2009 Nokia Corporation
19758 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
19760 + * VENC settings from TI's DSS driver
19762 + * This program is free software; you can redistribute it and/or modify it
19763 + * under the terms of the GNU General Public License version 2 as published by
19764 + * the Free Software Foundation.
19766 + * This program is distributed in the hope that it will be useful, but WITHOUT
19767 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
19768 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
19769 + * more details.
19771 + * You should have received a copy of the GNU General Public License along with
19772 + * this program. If not, see <http://www.gnu.org/licenses/>.
19773 + */
19775 +#define DSS_SUBSYS_NAME "VENC"
19777 +#include <linux/kernel.h>
19778 +#include <linux/module.h>
19779 +#include <linux/clk.h>
19780 +#include <linux/err.h>
19781 +#include <linux/io.h>
19782 +#include <linux/mutex.h>
19783 +#include <linux/completion.h>
19784 +#include <linux/delay.h>
19785 +#include <linux/string.h>
19787 +#include <mach/display.h>
19788 +#include <mach/cpu.h>
19790 +#include "dss.h"
19792 +#define VENC_BASE 0x48050C00
19794 +/* Venc registers */
19795 +#define VENC_REV_ID 0x00
19796 +#define VENC_STATUS 0x04
19797 +#define VENC_F_CONTROL 0x08
19798 +#define VENC_VIDOUT_CTRL 0x10
19799 +#define VENC_SYNC_CTRL 0x14
19800 +#define VENC_LLEN 0x1C
19801 +#define VENC_FLENS 0x20
19802 +#define VENC_HFLTR_CTRL 0x24
19803 +#define VENC_CC_CARR_WSS_CARR 0x28
19804 +#define VENC_C_PHASE 0x2C
19805 +#define VENC_GAIN_U 0x30
19806 +#define VENC_GAIN_V 0x34
19807 +#define VENC_GAIN_Y 0x38
19808 +#define VENC_BLACK_LEVEL 0x3C
19809 +#define VENC_BLANK_LEVEL 0x40
19810 +#define VENC_X_COLOR 0x44
19811 +#define VENC_M_CONTROL 0x48
19812 +#define VENC_BSTAMP_WSS_DATA 0x4C
19813 +#define VENC_S_CARR 0x50
19814 +#define VENC_LINE21 0x54
19815 +#define VENC_LN_SEL 0x58
19816 +#define VENC_L21__WC_CTL 0x5C
19817 +#define VENC_HTRIGGER_VTRIGGER 0x60
19818 +#define VENC_SAVID__EAVID 0x64
19819 +#define VENC_FLEN__FAL 0x68
19820 +#define VENC_LAL__PHASE_RESET 0x6C
19821 +#define VENC_HS_INT_START_STOP_X 0x70
19822 +#define VENC_HS_EXT_START_STOP_X 0x74
19823 +#define VENC_VS_INT_START_X 0x78
19824 +#define VENC_VS_INT_STOP_X__VS_INT_START_Y 0x7C
19825 +#define VENC_VS_INT_STOP_Y__VS_EXT_START_X 0x80
19826 +#define VENC_VS_EXT_STOP_X__VS_EXT_START_Y 0x84
19827 +#define VENC_VS_EXT_STOP_Y 0x88
19828 +#define VENC_AVID_START_STOP_X 0x90
19829 +#define VENC_AVID_START_STOP_Y 0x94
19830 +#define VENC_FID_INT_START_X__FID_INT_START_Y 0xA0
19831 +#define VENC_FID_INT_OFFSET_Y__FID_EXT_START_X 0xA4
19832 +#define VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y 0xA8
19833 +#define VENC_TVDETGP_INT_START_STOP_X 0xB0
19834 +#define VENC_TVDETGP_INT_START_STOP_Y 0xB4
19835 +#define VENC_GEN_CTRL 0xB8
19836 +#define VENC_OUTPUT_CONTROL 0xC4
19837 +#define VENC_DAC_B__DAC_C 0xC8
19839 +struct venc_config {
19840 + u32 f_control;
19841 + u32 vidout_ctrl;
19842 + u32 sync_ctrl;
19843 + u32 llen;
19844 + u32 flens;
19845 + u32 hfltr_ctrl;
19846 + u32 cc_carr_wss_carr;
19847 + u32 c_phase;
19848 + u32 gain_u;
19849 + u32 gain_v;
19850 + u32 gain_y;
19851 + u32 black_level;
19852 + u32 blank_level;
19853 + u32 x_color;
19854 + u32 m_control;
19855 + u32 bstamp_wss_data;
19856 + u32 s_carr;
19857 + u32 line21;
19858 + u32 ln_sel;
19859 + u32 l21__wc_ctl;
19860 + u32 htrigger_vtrigger;
19861 + u32 savid__eavid;
19862 + u32 flen__fal;
19863 + u32 lal__phase_reset;
19864 + u32 hs_int_start_stop_x;
19865 + u32 hs_ext_start_stop_x;
19866 + u32 vs_int_start_x;
19867 + u32 vs_int_stop_x__vs_int_start_y;
19868 + u32 vs_int_stop_y__vs_ext_start_x;
19869 + u32 vs_ext_stop_x__vs_ext_start_y;
19870 + u32 vs_ext_stop_y;
19871 + u32 avid_start_stop_x;
19872 + u32 avid_start_stop_y;
19873 + u32 fid_int_start_x__fid_int_start_y;
19874 + u32 fid_int_offset_y__fid_ext_start_x;
19875 + u32 fid_ext_start_y__fid_ext_offset_y;
19876 + u32 tvdetgp_int_start_stop_x;
19877 + u32 tvdetgp_int_start_stop_y;
19878 + u32 gen_ctrl;
19881 +/* from TRM */
19882 +static const struct venc_config venc_config_pal_trm = {
19883 + .f_control = 0,
19884 + .vidout_ctrl = 1,
19885 + .sync_ctrl = 0x40,
19886 + .llen = 0x35F, /* 863 */
19887 + .flens = 0x270, /* 624 */
19888 + .hfltr_ctrl = 0,
19889 + .cc_carr_wss_carr = 0x2F7225ED,
19890 + .c_phase = 0,
19891 + .gain_u = 0x111,
19892 + .gain_v = 0x181,
19893 + .gain_y = 0x140,
19894 + .black_level = 0x3B,
19895 + .blank_level = 0x3B,
19896 + .x_color = 0x7,
19897 + .m_control = 0x2,
19898 + .bstamp_wss_data = 0x3F,
19899 + .s_carr = 0x2A098ACB,
19900 + .line21 = 0,
19901 + .ln_sel = 0x01290015,
19902 + .l21__wc_ctl = 0x0000F603,
19903 + .htrigger_vtrigger = 0,
19905 + .savid__eavid = 0x06A70108,
19906 + .flen__fal = 0x00180270,
19907 + .lal__phase_reset = 0x00040135,
19908 + .hs_int_start_stop_x = 0x00880358,
19909 + .hs_ext_start_stop_x = 0x000F035F,
19910 + .vs_int_start_x = 0x01A70000,
19911 + .vs_int_stop_x__vs_int_start_y = 0x000001A7,
19912 + .vs_int_stop_y__vs_ext_start_x = 0x01AF0000,
19913 + .vs_ext_stop_x__vs_ext_start_y = 0x000101AF,
19914 + .vs_ext_stop_y = 0x00000025,
19915 + .avid_start_stop_x = 0x03530083,
19916 + .avid_start_stop_y = 0x026C002E,
19917 + .fid_int_start_x__fid_int_start_y = 0x0001008A,
19918 + .fid_int_offset_y__fid_ext_start_x = 0x002E0138,
19919 + .fid_ext_start_y__fid_ext_offset_y = 0x01380001,
19921 + .tvdetgp_int_start_stop_x = 0x00140001,
19922 + .tvdetgp_int_start_stop_y = 0x00010001,
19923 + .gen_ctrl = 0x00FF0000,
19926 +/* from TRM */
19927 +static const struct venc_config venc_config_ntsc_trm = {
19928 + .f_control = 0,
19929 + .vidout_ctrl = 1,
19930 + .sync_ctrl = 0x8040,
19931 + .llen = 0x359,
19932 + .flens = 0x20C,
19933 + .hfltr_ctrl = 0,
19934 + .cc_carr_wss_carr = 0x043F2631,
19935 + .c_phase = 0,
19936 + .gain_u = 0x102,
19937 + .gain_v = 0x16C,
19938 + .gain_y = 0x12F,
19939 + .black_level = 0x43,
19940 + .blank_level = 0x38,
19941 + .x_color = 0x7,
19942 + .m_control = 0x1,
19943 + .bstamp_wss_data = 0x38,
19944 + .s_carr = 0x21F07C1F,
19945 + .line21 = 0,
19946 + .ln_sel = 0x01310011,
19947 + .l21__wc_ctl = 0x0000F003,
19948 + .htrigger_vtrigger = 0,
19950 + .savid__eavid = 0x069300F4,
19951 + .flen__fal = 0x0016020C,
19952 + .lal__phase_reset = 0x00060107,
19953 + .hs_int_start_stop_x = 0x008E0350,
19954 + .hs_ext_start_stop_x = 0x000F0359,
19955 + .vs_int_start_x = 0x01A00000,
19956 + .vs_int_stop_x__vs_int_start_y = 0x020701A0,
19957 + .vs_int_stop_y__vs_ext_start_x = 0x01AC0024,
19958 + .vs_ext_stop_x__vs_ext_start_y = 0x020D01AC,
19959 + .vs_ext_stop_y = 0x00000006,
19960 + .avid_start_stop_x = 0x03480078,
19961 + .avid_start_stop_y = 0x02060024,
19962 + .fid_int_start_x__fid_int_start_y = 0x0001008A,
19963 + .fid_int_offset_y__fid_ext_start_x = 0x01AC0106,
19964 + .fid_ext_start_y__fid_ext_offset_y = 0x01060006,
19966 + .tvdetgp_int_start_stop_x = 0x00140001,
19967 + .tvdetgp_int_start_stop_y = 0x00010001,
19968 + .gen_ctrl = 0x00F90000,
19971 +static const struct venc_config venc_config_pal_bdghi = {
19972 + .f_control = 0,
19973 + .vidout_ctrl = 0,
19974 + .sync_ctrl = 0,
19975 + .hfltr_ctrl = 0,
19976 + .x_color = 0,
19977 + .line21 = 0,
19978 + .ln_sel = 21,
19979 + .htrigger_vtrigger = 0,
19980 + .tvdetgp_int_start_stop_x = 0x00140001,
19981 + .tvdetgp_int_start_stop_y = 0x00010001,
19982 + .gen_ctrl = 0x00FB0000,
19984 + .llen = 864-1,
19985 + .flens = 625-1,
19986 + .cc_carr_wss_carr = 0x2F7625ED,
19987 + .c_phase = 0xDF,
19988 + .gain_u = 0x111,
19989 + .gain_v = 0x181,
19990 + .gain_y = 0x140,
19991 + .black_level = 0x3e,
19992 + .blank_level = 0x3e,
19993 + .m_control = 0<<2 | 1<<1,
19994 + .bstamp_wss_data = 0x42,
19995 + .s_carr = 0x2a098acb,
19996 + .l21__wc_ctl = 0<<13 | 0x16<<8 | 0<<0,
19997 + .savid__eavid = 0x06A70108,
19998 + .flen__fal = 23<<16 | 624<<0,
19999 + .lal__phase_reset = 2<<17 | 310<<0,
20000 + .hs_int_start_stop_x = 0x00920358,
20001 + .hs_ext_start_stop_x = 0x000F035F,
20002 + .vs_int_start_x = 0x1a7<<16,
20003 + .vs_int_stop_x__vs_int_start_y = 0x000601A7,
20004 + .vs_int_stop_y__vs_ext_start_x = 0x01AF0036,
20005 + .vs_ext_stop_x__vs_ext_start_y = 0x27101af,
20006 + .vs_ext_stop_y = 0x05,
20007 + .avid_start_stop_x = 0x03530082,
20008 + .avid_start_stop_y = 0x0270002E,
20009 + .fid_int_start_x__fid_int_start_y = 0x0005008A,
20010 + .fid_int_offset_y__fid_ext_start_x = 0x002E0138,
20011 + .fid_ext_start_y__fid_ext_offset_y = 0x01380005,
20014 +const struct omap_video_timings omap_dss_pal_timings = {
20015 + .x_res = 720,
20016 + .y_res = 574,
20017 + .pixel_clock = 26181,
20018 + .hsw = 32,
20019 + .hfp = 80,
20020 + .hbp = 48,
20021 + .vsw = 7,
20022 + .vfp = 3,
20023 + .vbp = 6,
20025 +EXPORT_SYMBOL(omap_dss_pal_timings);
20027 +const struct omap_video_timings omap_dss_ntsc_timings = {
20028 + .x_res = 720,
20029 + .y_res = 482,
20030 + .pixel_clock = 22153,
20031 + .hsw = 32,
20032 + .hfp = 80,
20033 + .hbp = 48,
20034 + .vsw = 10,
20035 + .vfp = 3,
20036 + .vbp = 6,
20038 +EXPORT_SYMBOL(omap_dss_ntsc_timings);
20040 +static struct {
20041 + void __iomem *base;
20042 + struct mutex venc_lock;
20043 +} venc;
20045 +static struct omap_panel venc_panel = {
20046 + .name = "tv-out",
20049 +static inline void venc_write_reg(int idx, u32 val)
20051 + __raw_writel(val, venc.base + idx);
20054 +static inline u32 venc_read_reg(int idx)
20056 + u32 l = __raw_readl(venc.base + idx);
20057 + return l;
20060 +static void venc_write_config(const struct venc_config *config)
20062 + DSSDBG("write venc conf\n");
20064 + venc_write_reg(VENC_LLEN, config->llen);
20065 + venc_write_reg(VENC_FLENS, config->flens);
20066 + venc_write_reg(VENC_CC_CARR_WSS_CARR, config->cc_carr_wss_carr);
20067 + venc_write_reg(VENC_C_PHASE, config->c_phase);
20068 + venc_write_reg(VENC_GAIN_U, config->gain_u);
20069 + venc_write_reg(VENC_GAIN_V, config->gain_v);
20070 + venc_write_reg(VENC_GAIN_Y, config->gain_y);
20071 + venc_write_reg(VENC_BLACK_LEVEL, config->black_level);
20072 + venc_write_reg(VENC_BLANK_LEVEL, config->blank_level);
20073 + venc_write_reg(VENC_M_CONTROL, config->m_control);
20074 + venc_write_reg(VENC_BSTAMP_WSS_DATA, config->bstamp_wss_data);
20075 + venc_write_reg(VENC_S_CARR, config->s_carr);
20076 + venc_write_reg(VENC_L21__WC_CTL, config->l21__wc_ctl);
20077 + venc_write_reg(VENC_SAVID__EAVID, config->savid__eavid);
20078 + venc_write_reg(VENC_FLEN__FAL, config->flen__fal);
20079 + venc_write_reg(VENC_LAL__PHASE_RESET, config->lal__phase_reset);
20080 + venc_write_reg(VENC_HS_INT_START_STOP_X, config->hs_int_start_stop_x);
20081 + venc_write_reg(VENC_HS_EXT_START_STOP_X, config->hs_ext_start_stop_x);
20082 + venc_write_reg(VENC_VS_INT_START_X, config->vs_int_start_x);
20083 + venc_write_reg(VENC_VS_INT_STOP_X__VS_INT_START_Y,
20084 + config->vs_int_stop_x__vs_int_start_y);
20085 + venc_write_reg(VENC_VS_INT_STOP_Y__VS_EXT_START_X,
20086 + config->vs_int_stop_y__vs_ext_start_x);
20087 + venc_write_reg(VENC_VS_EXT_STOP_X__VS_EXT_START_Y,
20088 + config->vs_ext_stop_x__vs_ext_start_y);
20089 + venc_write_reg(VENC_VS_EXT_STOP_Y, config->vs_ext_stop_y);
20090 + venc_write_reg(VENC_AVID_START_STOP_X, config->avid_start_stop_x);
20091 + venc_write_reg(VENC_AVID_START_STOP_Y, config->avid_start_stop_y);
20092 + venc_write_reg(VENC_FID_INT_START_X__FID_INT_START_Y,
20093 + config->fid_int_start_x__fid_int_start_y);
20094 + venc_write_reg(VENC_FID_INT_OFFSET_Y__FID_EXT_START_X,
20095 + config->fid_int_offset_y__fid_ext_start_x);
20096 + venc_write_reg(VENC_FID_EXT_START_Y__FID_EXT_OFFSET_Y,
20097 + config->fid_ext_start_y__fid_ext_offset_y);
20099 + venc_write_reg(VENC_DAC_B__DAC_C, venc_read_reg(VENC_DAC_B__DAC_C));
20100 + venc_write_reg(VENC_VIDOUT_CTRL, config->vidout_ctrl);
20101 + venc_write_reg(VENC_HFLTR_CTRL, config->hfltr_ctrl);
20102 + venc_write_reg(VENC_X_COLOR, config->x_color);
20103 + venc_write_reg(VENC_LINE21, config->line21);
20104 + venc_write_reg(VENC_LN_SEL, config->ln_sel);
20105 + venc_write_reg(VENC_HTRIGGER_VTRIGGER, config->htrigger_vtrigger);
20106 + venc_write_reg(VENC_TVDETGP_INT_START_STOP_X,
20107 + config->tvdetgp_int_start_stop_x);
20108 + venc_write_reg(VENC_TVDETGP_INT_START_STOP_Y,
20109 + config->tvdetgp_int_start_stop_y);
20110 + venc_write_reg(VENC_GEN_CTRL, config->gen_ctrl);
20111 + venc_write_reg(VENC_F_CONTROL, config->f_control);
20112 + venc_write_reg(VENC_SYNC_CTRL, config->sync_ctrl);
20115 +static void venc_reset(void)
20117 + int t = 1000;
20119 + venc_write_reg(VENC_F_CONTROL, 1<<8);
20120 + while (venc_read_reg(VENC_F_CONTROL) & (1<<8)) {
20121 + if (--t == 0) {
20122 + DSSERR("Failed to reset venc\n");
20123 + return;
20127 + /* the magical sleep that makes things work */
20128 + msleep(20);
20131 +static void venc_enable_clocks(int enable)
20133 + if (enable)
20134 + dss_clk_enable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M |
20135 + DSS_CLK_96M);
20136 + else
20137 + dss_clk_disable(DSS_CLK_ICK | DSS_CLK_FCK1 | DSS_CLK_54M |
20138 + DSS_CLK_96M);
20141 +static const struct venc_config *venc_timings_to_config(
20142 + struct omap_video_timings *timings)
20144 + if (memcmp(&omap_dss_pal_timings, timings, sizeof(*timings)) == 0)
20145 + return &venc_config_pal_trm;
20147 + if (memcmp(&omap_dss_ntsc_timings, timings, sizeof(*timings)) == 0)
20148 + return &venc_config_ntsc_trm;
20150 + BUG();
20153 +int venc_init(void)
20155 + u8 rev_id;
20157 + mutex_init(&venc.venc_lock);
20159 + venc_panel.timings = omap_dss_pal_timings;
20161 + venc.base = ioremap(VENC_BASE, SZ_1K);
20162 + if (!venc.base) {
20163 + DSSERR("can't ioremap VENC\n");
20164 + return -ENOMEM;
20167 + venc_enable_clocks(1);
20169 + rev_id = (u8)(venc_read_reg(VENC_REV_ID) & 0xff);
20170 + printk(KERN_INFO "OMAP VENC rev %d\n", rev_id);
20172 + venc_enable_clocks(0);
20174 + return 0;
20177 +void venc_exit(void)
20179 + iounmap(venc.base);
20182 +static void venc_power_on(struct omap_display *display)
20184 + venc_enable_clocks(1);
20186 + venc_reset();
20187 + venc_write_config(venc_timings_to_config(&display->panel->timings));
20189 + dss_set_venc_output(display->hw_config.u.venc.type);
20190 + dss_set_dac_pwrdn_bgz(1);
20192 + if (display->hw_config.u.venc.type == OMAP_DSS_VENC_TYPE_COMPOSITE) {
20193 + if (cpu_is_omap24xx())
20194 + venc_write_reg(VENC_OUTPUT_CONTROL, 0x2);
20195 + else
20196 + venc_write_reg(VENC_OUTPUT_CONTROL, 0xa);
20197 + } else { /* S-Video */
20198 + venc_write_reg(VENC_OUTPUT_CONTROL, 0xd);
20201 + dispc_set_digit_size(display->panel->timings.x_res,
20202 + display->panel->timings.y_res/2);
20204 + if (display->hw_config.panel_enable)
20205 + display->hw_config.panel_enable(display);
20207 + dispc_enable_digit_out(1);
20210 +static void venc_power_off(struct omap_display *display)
20212 + venc_write_reg(VENC_OUTPUT_CONTROL, 0);
20213 + dss_set_dac_pwrdn_bgz(0);
20215 + dispc_enable_digit_out(0);
20217 + if (display->hw_config.panel_disable)
20218 + display->hw_config.panel_disable(display);
20220 + venc_enable_clocks(0);
20223 +static int venc_enable_display(struct omap_display *display)
20225 + int r = 0;
20227 + DSSDBG("venc_enable_display\n");
20229 + mutex_lock(&venc.venc_lock);
20231 + if (display->state != OMAP_DSS_DISPLAY_DISABLED) {
20232 + r = -EINVAL;
20233 + goto err;
20236 + venc_power_on(display);
20238 + display->state = OMAP_DSS_DISPLAY_ACTIVE;
20239 +err:
20240 + mutex_unlock(&venc.venc_lock);
20242 + return r;
20245 +static void venc_disable_display(struct omap_display *display)
20247 + DSSDBG("venc_disable_display\n");
20249 + mutex_lock(&venc.venc_lock);
20251 + if (display->state == OMAP_DSS_DISPLAY_DISABLED)
20252 + goto end;
20254 + if (display->state == OMAP_DSS_DISPLAY_SUSPENDED) {
20255 + /* suspended is the same as disabled with venc */
20256 + display->state = OMAP_DSS_DISPLAY_DISABLED;
20257 + goto end;
20260 + venc_power_off(display);
20262 + display->state = OMAP_DSS_DISPLAY_DISABLED;
20263 +end:
20264 + mutex_unlock(&venc.venc_lock);
20267 +static int venc_display_suspend(struct omap_display *display)
20269 + int r = 0;
20271 + DSSDBG("venc_display_suspend\n");
20273 + mutex_lock(&venc.venc_lock);
20275 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE) {
20276 + r = -EINVAL;
20277 + goto err;
20280 + venc_power_off(display);
20282 + display->state = OMAP_DSS_DISPLAY_SUSPENDED;
20283 +err:
20284 + mutex_unlock(&venc.venc_lock);
20286 + return r;
20289 +static int venc_display_resume(struct omap_display *display)
20291 + int r = 0;
20293 + DSSDBG("venc_display_resume\n");
20295 + mutex_lock(&venc.venc_lock);
20297 + if (display->state != OMAP_DSS_DISPLAY_SUSPENDED) {
20298 + r = -EINVAL;
20299 + goto err;
20302 + venc_power_on(display);
20304 + display->state = OMAP_DSS_DISPLAY_ACTIVE;
20305 +err:
20306 + mutex_unlock(&venc.venc_lock);
20308 + return r;
20311 +static void venc_get_timings(struct omap_display *display,
20312 + struct omap_video_timings *timings)
20314 + *timings = venc_panel.timings;
20317 +static void venc_set_timings(struct omap_display *display,
20318 + struct omap_video_timings *timings)
20320 + DSSDBG("venc_set_timings\n");
20321 + display->panel->timings = *timings;
20322 + if (display->state == OMAP_DSS_DISPLAY_ACTIVE) {
20323 + /* turn the venc off and on to get new timings to use */
20324 + venc_disable_display(display);
20325 + venc_enable_display(display);
20329 +static int venc_check_timings(struct omap_display *display,
20330 + struct omap_video_timings *timings)
20332 + DSSDBG("venc_check_timings\n");
20334 + if (memcmp(&omap_dss_pal_timings, timings, sizeof(*timings)) == 0)
20335 + return 0;
20337 + if (memcmp(&omap_dss_ntsc_timings, timings, sizeof(*timings)) == 0)
20338 + return 0;
20340 + return -EINVAL;
20343 +void venc_init_display(struct omap_display *display)
20345 + display->panel = &venc_panel;
20346 + display->enable = venc_enable_display;
20347 + display->disable = venc_disable_display;
20348 + display->suspend = venc_display_suspend;
20349 + display->resume = venc_display_resume;
20350 + display->get_timings = venc_get_timings;
20351 + display->set_timings = venc_set_timings;
20352 + display->check_timings = venc_check_timings;
20354 diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/omap2/omapfb/Kconfig
20355 new file mode 100644
20356 index 0000000..4f66033
20357 --- /dev/null
20358 +++ b/drivers/video/omap2/omapfb/Kconfig
20359 @@ -0,0 +1,35 @@
20360 +menuconfig FB_OMAP2
20361 + tristate "OMAP2/3 frame buffer support (EXPERIMENTAL)"
20362 + depends on FB && OMAP2_DSS
20364 + select FB_CFB_FILLRECT
20365 + select FB_CFB_COPYAREA
20366 + select FB_CFB_IMAGEBLIT
20367 + help
20368 + Frame buffer driver for OMAP2/3 based boards.
20370 +config FB_OMAP2_DEBUG_SUPPORT
20371 + bool "Debug support for OMAP2/3 FB"
20372 + default y
20373 + depends on FB_OMAP2
20374 + help
20375 + Support for debug output. You have to enable the actual printing
20376 + with debug module parameter.
20378 +config FB_OMAP2_FORCE_AUTO_UPDATE
20379 + bool "Force main display to automatic update mode"
20380 + depends on FB_OMAP2
20381 + help
20382 + Forces main display to automatic update mode (if possible),
20383 + and also enables tearsync (if possible). By default
20384 + displays that support manual update are started in manual
20385 + update mode.
20387 +config FB_OMAP2_NUM_FBS
20388 + int "Number of framebuffers"
20389 + range 1 10
20390 + default 3
20391 + depends on FB_OMAP2
20392 + help
20393 + Select the number of framebuffers created. OMAP2/3 has 3 overlays
20394 + so normally this would be 3.
20395 diff --git a/drivers/video/omap2/omapfb/Makefile b/drivers/video/omap2/omapfb/Makefile
20396 new file mode 100644
20397 index 0000000..51c2e00
20398 --- /dev/null
20399 +++ b/drivers/video/omap2/omapfb/Makefile
20400 @@ -0,0 +1,2 @@
20401 +obj-$(CONFIG_FB_OMAP2) += omapfb.o
20402 +omapfb-y := omapfb-main.o omapfb-sysfs.o omapfb-ioctl.o
20403 diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/omap2/omapfb/omapfb-ioctl.c
20404 new file mode 100644
20405 index 0000000..7f18d2a
20406 --- /dev/null
20407 +++ b/drivers/video/omap2/omapfb/omapfb-ioctl.c
20408 @@ -0,0 +1,656 @@
20410 + * linux/drivers/video/omap2/omapfb-ioctl.c
20412 + * Copyright (C) 2008 Nokia Corporation
20413 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
20415 + * Some code and ideas taken from drivers/video/omap/ driver
20416 + * by Imre Deak.
20418 + * This program is free software; you can redistribute it and/or modify it
20419 + * under the terms of the GNU General Public License version 2 as published by
20420 + * the Free Software Foundation.
20422 + * This program is distributed in the hope that it will be useful, but WITHOUT
20423 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20424 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20425 + * more details.
20427 + * You should have received a copy of the GNU General Public License along with
20428 + * this program. If not, see <http://www.gnu.org/licenses/>.
20429 + */
20431 +#include <linux/fb.h>
20432 +#include <linux/device.h>
20433 +#include <linux/uaccess.h>
20434 +#include <linux/platform_device.h>
20435 +#include <linux/mm.h>
20436 +#include <linux/omapfb.h>
20437 +#include <linux/vmalloc.h>
20439 +#include <mach/display.h>
20440 +#include <mach/vrfb.h>
20442 +#include "omapfb.h"
20444 +static int omapfb_setup_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
20446 + struct omapfb_info *ofbi = FB2OFB(fbi);
20447 + struct omapfb2_device *fbdev = ofbi->fbdev;
20448 + struct omap_display *display = fb2display(fbi);
20449 + struct omap_overlay *ovl;
20450 + struct omap_overlay_info info;
20451 + int r = 0;
20453 + DBG("omapfb_setup_plane\n");
20455 + omapfb_lock(fbdev);
20457 + if (ofbi->num_overlays != 1) {
20458 + r = -EINVAL;
20459 + goto out;
20462 + /* XXX uses only the first overlay */
20463 + ovl = ofbi->overlays[0];
20465 + if (pi->enabled && !ofbi->region.size) {
20466 + /*
20467 + * This plane's memory was freed, can't enable it
20468 + * until it's reallocated.
20469 + */
20470 + r = -EINVAL;
20471 + goto out;
20474 + ovl->get_overlay_info(ovl, &info);
20476 + info.pos_x = pi->pos_x;
20477 + info.pos_y = pi->pos_y;
20478 + info.out_width = pi->out_width;
20479 + info.out_height = pi->out_height;
20480 + info.enabled = pi->enabled;
20482 + r = ovl->set_overlay_info(ovl, &info);
20483 + if (r)
20484 + goto out;
20486 + if (ovl->manager) {
20487 + r = ovl->manager->apply(ovl->manager);
20488 + if (r)
20489 + goto out;
20492 + if (display) {
20493 + u16 w, h;
20495 + if (display->sync)
20496 + display->sync(display);
20498 + display->get_resolution(display, &w, &h);
20500 + if (display->update)
20501 + display->update(display, 0, 0, w, h);
20504 +out:
20505 + omapfb_unlock(fbdev);
20506 + if (r)
20507 + dev_err(fbdev->dev, "setup_plane failed\n");
20508 + return r;
20511 +static int omapfb_query_plane(struct fb_info *fbi, struct omapfb_plane_info *pi)
20513 + struct omapfb_info *ofbi = FB2OFB(fbi);
20514 + struct omapfb2_device *fbdev = ofbi->fbdev;
20516 + omapfb_lock(fbdev);
20518 + if (ofbi->num_overlays != 1) {
20519 + memset(pi, 0, sizeof(*pi));
20520 + } else {
20521 + struct omap_overlay_info *ovli;
20522 + struct omap_overlay *ovl;
20524 + ovl = ofbi->overlays[0];
20525 + ovli = &ovl->info;
20527 + pi->pos_x = ovli->pos_x;
20528 + pi->pos_y = ovli->pos_y;
20529 + pi->enabled = ovli->enabled;
20530 + pi->channel_out = 0; /* xxx */
20531 + pi->mirror = 0;
20532 + pi->out_width = ovli->out_width;
20533 + pi->out_height = ovli->out_height;
20536 + omapfb_unlock(fbdev);
20538 + return 0;
20541 +static int omapfb_setup_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
20543 + struct omapfb_info *ofbi = FB2OFB(fbi);
20544 + struct omapfb2_device *fbdev = ofbi->fbdev;
20545 + struct omapfb2_mem_region *rg;
20546 + int r, i;
20547 + size_t size;
20549 + if (mi->type > OMAPFB_MEMTYPE_MAX)
20550 + return -EINVAL;
20552 + size = PAGE_ALIGN(mi->size);
20554 + rg = &ofbi->region;
20556 + omapfb_lock(fbdev);
20558 + for (i = 0; i < ofbi->num_overlays; i++) {
20559 + if (ofbi->overlays[i]->info.enabled) {
20560 + r = -EBUSY;
20561 + goto out;
20565 + if (rg->size != size || rg->type != mi->type) {
20566 + r = omapfb_realloc_fbmem(fbi, size, mi->type);
20567 + if (r) {
20568 + dev_err(fbdev->dev, "realloc fbmem failed\n");
20569 + goto out;
20573 + r = 0;
20574 +out:
20575 + omapfb_unlock(fbdev);
20577 + return r;
20580 +static int omapfb_query_mem(struct fb_info *fbi, struct omapfb_mem_info *mi)
20582 + struct omapfb_info *ofbi = FB2OFB(fbi);
20583 + struct omapfb2_device *fbdev = ofbi->fbdev;
20584 + struct omapfb2_mem_region *rg;
20586 + rg = &ofbi->region;
20587 + memset(mi, 0, sizeof(*mi));
20589 + omapfb_lock(fbdev);
20590 + mi->size = rg->size;
20591 + mi->type = rg->type;
20592 + omapfb_unlock(fbdev);
20594 + return 0;
20597 +static int omapfb_update_window(struct fb_info *fbi,
20598 + u32 x, u32 y, u32 w, u32 h)
20600 + struct omapfb_info *ofbi = FB2OFB(fbi);
20601 + struct omapfb2_device *fbdev = ofbi->fbdev;
20602 + struct omap_display *display = fb2display(fbi);
20603 + u16 dw, dh;
20605 + if (!display)
20606 + return 0;
20608 + if (w == 0 || h == 0)
20609 + return 0;
20611 + display->get_resolution(display, &dw, &dh);
20613 + if (x + w > dw || y + h > dh)
20614 + return -EINVAL;
20616 + omapfb_lock(fbdev);
20617 + display->update(display, x, y, w, h);
20618 + omapfb_unlock(fbdev);
20620 + return 0;
20623 +static int omapfb_set_update_mode(struct fb_info *fbi,
20624 + enum omapfb_update_mode mode)
20626 + struct omapfb_info *ofbi = FB2OFB(fbi);
20627 + struct omapfb2_device *fbdev = ofbi->fbdev;
20628 + struct omap_display *display = fb2display(fbi);
20629 + enum omap_dss_update_mode um;
20630 + int r;
20632 + if (!display || !display->set_update_mode)
20633 + return -EINVAL;
20635 + switch (mode) {
20636 + case OMAPFB_UPDATE_DISABLED:
20637 + um = OMAP_DSS_UPDATE_DISABLED;
20638 + break;
20640 + case OMAPFB_AUTO_UPDATE:
20641 + um = OMAP_DSS_UPDATE_AUTO;
20642 + break;
20644 + case OMAPFB_MANUAL_UPDATE:
20645 + um = OMAP_DSS_UPDATE_MANUAL;
20646 + break;
20648 + default:
20649 + return -EINVAL;
20652 + omapfb_lock(fbdev);
20653 + r = display->set_update_mode(display, um);
20654 + omapfb_unlock(fbdev);
20656 + return r;
20659 +static int omapfb_get_update_mode(struct fb_info *fbi,
20660 + enum omapfb_update_mode *mode)
20662 + struct omapfb_info *ofbi = FB2OFB(fbi);
20663 + struct omapfb2_device *fbdev = ofbi->fbdev;
20664 + struct omap_display *display = fb2display(fbi);
20665 + enum omap_dss_update_mode m;
20667 + if (!display || !display->get_update_mode)
20668 + return -EINVAL;
20670 + omapfb_lock(fbdev);
20671 + m = display->get_update_mode(display);
20672 + omapfb_unlock(fbdev);
20674 + switch (m) {
20675 + case OMAP_DSS_UPDATE_DISABLED:
20676 + *mode = OMAPFB_UPDATE_DISABLED;
20677 + break;
20678 + case OMAP_DSS_UPDATE_AUTO:
20679 + *mode = OMAPFB_AUTO_UPDATE;
20680 + break;
20681 + case OMAP_DSS_UPDATE_MANUAL:
20682 + *mode = OMAPFB_MANUAL_UPDATE;
20683 + break;
20684 + default:
20685 + BUG();
20688 + return 0;
20691 +/* XXX this color key handling is a hack... */
20692 +static struct omapfb_color_key omapfb_color_keys[2];
20694 +static int _omapfb_set_color_key(struct omap_overlay_manager *mgr,
20695 + struct omapfb_color_key *ck)
20697 + enum omap_dss_color_key_type kt;
20699 + if(!mgr->set_default_color || !mgr->set_trans_key ||
20700 + !mgr->enable_trans_key)
20701 + return 0;
20703 + if (ck->key_type == OMAPFB_COLOR_KEY_DISABLED) {
20704 + mgr->enable_trans_key(mgr, 0);
20705 + omapfb_color_keys[mgr->id] = *ck;
20706 + return 0;
20709 + switch(ck->key_type) {
20710 + case OMAPFB_COLOR_KEY_GFX_DST:
20711 + kt = OMAP_DSS_COLOR_KEY_GFX_DST;
20712 + break;
20713 + case OMAPFB_COLOR_KEY_VID_SRC:
20714 + kt = OMAP_DSS_COLOR_KEY_VID_SRC;
20715 + break;
20716 + default:
20717 + return -EINVAL;
20720 + mgr->set_default_color(mgr, ck->background);
20721 + mgr->set_trans_key(mgr, kt, ck->trans_key);
20722 + mgr->enable_trans_key(mgr, 1);
20724 + omapfb_color_keys[mgr->id] = *ck;
20726 + return 0;
20729 +static int omapfb_set_color_key(struct fb_info *fbi,
20730 + struct omapfb_color_key *ck)
20732 + struct omapfb_info *ofbi = FB2OFB(fbi);
20733 + struct omapfb2_device *fbdev = ofbi->fbdev;
20734 + int r;
20735 + int i;
20736 + struct omap_overlay_manager *mgr = NULL;
20738 + omapfb_lock(fbdev);
20740 + for (i = 0; i < ofbi->num_overlays; i++) {
20741 + if (ofbi->overlays[i]->manager) {
20742 + mgr = ofbi->overlays[i]->manager;
20743 + break;
20747 + if (!mgr) {
20748 + r = -EINVAL;
20749 + goto err;
20752 + if(!mgr->set_default_color || !mgr->set_trans_key ||
20753 + !mgr->enable_trans_key) {
20754 + r = -ENODEV;
20755 + goto err;
20758 + r = _omapfb_set_color_key(mgr, ck);
20759 +err:
20760 + omapfb_unlock(fbdev);
20762 + return r;
20765 +static int omapfb_get_color_key(struct fb_info *fbi,
20766 + struct omapfb_color_key *ck)
20768 + struct omapfb_info *ofbi = FB2OFB(fbi);
20769 + struct omapfb2_device *fbdev = ofbi->fbdev;
20770 + struct omap_overlay_manager *mgr = NULL;
20771 + int r = 0;
20772 + int i;
20774 + omapfb_lock(fbdev);
20776 + for (i = 0; i < ofbi->num_overlays; i++) {
20777 + if (ofbi->overlays[i]->manager) {
20778 + mgr = ofbi->overlays[i]->manager;
20779 + break;
20783 + if (!mgr) {
20784 + r = -EINVAL;
20785 + goto err;
20788 + if(!mgr->set_default_color || !mgr->set_trans_key ||
20789 + !mgr->enable_trans_key) {
20790 + r = -ENODEV;
20791 + goto err;
20794 + *ck = omapfb_color_keys[mgr->id];
20795 +err:
20796 + omapfb_unlock(fbdev);
20798 + return r;
20801 +static int omapfb_memory_read(struct fb_info *fbi,
20802 + struct omapfb_memory_read *mr)
20804 + struct omap_display *display = fb2display(fbi);
20805 + struct omapfb_info *ofbi = FB2OFB(fbi);
20806 + struct omapfb2_device *fbdev = ofbi->fbdev;
20807 + void *buf;
20808 + int r;
20810 + if (!display || !display->memory_read)
20811 + return -ENOENT;
20813 + if (!access_ok(VERIFY_WRITE, mr->buffer, mr->buffer_size))
20814 + return -EFAULT;
20816 + if (mr->w * mr->h * 3 > mr->buffer_size)
20817 + return -EINVAL;
20819 + buf = vmalloc(mr->buffer_size);
20820 + if (!buf) {
20821 + DBG("vmalloc failed\n");
20822 + return -ENOMEM;
20825 + omapfb_lock(fbdev);
20827 + r = display->memory_read(display, buf, mr->buffer_size,
20828 + mr->x, mr->y, mr->w, mr->h);
20830 + if (r > 0) {
20831 + if (copy_to_user(mr->buffer, buf, mr->buffer_size))
20832 + r = -EFAULT;
20835 + vfree(buf);
20837 + omapfb_unlock(fbdev);
20839 + return r;
20842 +int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
20844 + struct omapfb_info *ofbi = FB2OFB(fbi);
20845 + struct omapfb2_device *fbdev = ofbi->fbdev;
20846 + struct omap_display *display = fb2display(fbi);
20848 + union {
20849 + struct omapfb_update_window_old uwnd_o;
20850 + struct omapfb_update_window uwnd;
20851 + struct omapfb_plane_info plane_info;
20852 + struct omapfb_caps caps;
20853 + struct omapfb_mem_info mem_info;
20854 + struct omapfb_color_key color_key;
20855 + enum omapfb_update_mode update_mode;
20856 + int test_num;
20857 + struct omapfb_memory_read memory_read;
20858 + } p;
20860 + int r = 0;
20862 + switch (cmd) {
20863 + case OMAPFB_SYNC_GFX:
20864 + DBG("ioctl SYNC_GFX\n");
20865 + if (!display || !display->sync) {
20866 + /* DSS1 never returns an error here, so we neither */
20867 + /*r = -EINVAL;*/
20868 + break;
20871 + omapfb_lock(fbdev);
20872 + r = display->sync(display);
20873 + omapfb_unlock(fbdev);
20874 + break;
20876 + case OMAPFB_UPDATE_WINDOW_OLD:
20877 + DBG("ioctl UPDATE_WINDOW_OLD\n");
20878 + if (!display || !display->update) {
20879 + r = -EINVAL;
20880 + break;
20883 + if (copy_from_user(&p.uwnd_o,
20884 + (void __user *)arg,
20885 + sizeof(p.uwnd_o))) {
20886 + r = -EFAULT;
20887 + break;
20890 + r = omapfb_update_window(fbi, p.uwnd_o.x, p.uwnd_o.y,
20891 + p.uwnd_o.width, p.uwnd_o.height);
20892 + break;
20894 + case OMAPFB_UPDATE_WINDOW:
20895 + DBG("ioctl UPDATE_WINDOW\n");
20896 + if (!display || !display->update) {
20897 + r = -EINVAL;
20898 + break;
20901 + if (copy_from_user(&p.uwnd, (void __user *)arg,
20902 + sizeof(p.uwnd))) {
20903 + r = -EFAULT;
20904 + break;
20907 + r = omapfb_update_window(fbi, p.uwnd.x, p.uwnd.y,
20908 + p.uwnd.width, p.uwnd.height);
20909 + break;
20911 + case OMAPFB_SETUP_PLANE:
20912 + DBG("ioctl SETUP_PLANE\n");
20913 + if (copy_from_user(&p.plane_info, (void __user *)arg,
20914 + sizeof(p.plane_info)))
20915 + r = -EFAULT;
20916 + else
20917 + r = omapfb_setup_plane(fbi, &p.plane_info);
20918 + break;
20920 + case OMAPFB_QUERY_PLANE:
20921 + DBG("ioctl QUERY_PLANE\n");
20922 + r = omapfb_query_plane(fbi, &p.plane_info);
20923 + if (r < 0)
20924 + break;
20925 + if (copy_to_user((void __user *)arg, &p.plane_info,
20926 + sizeof(p.plane_info)))
20927 + r = -EFAULT;
20928 + break;
20930 + case OMAPFB_SETUP_MEM:
20931 + DBG("ioctl SETUP_MEM\n");
20932 + if (copy_from_user(&p.mem_info, (void __user *)arg,
20933 + sizeof(p.mem_info)))
20934 + r = -EFAULT;
20935 + else
20936 + r = omapfb_setup_mem(fbi, &p.mem_info);
20937 + break;
20939 + case OMAPFB_QUERY_MEM:
20940 + DBG("ioctl QUERY_MEM\n");
20941 + r = omapfb_query_mem(fbi, &p.mem_info);
20942 + if (r < 0)
20943 + break;
20944 + if (copy_to_user((void __user *)arg, &p.mem_info,
20945 + sizeof(p.mem_info)))
20946 + r = -EFAULT;
20947 + break;
20949 + case OMAPFB_GET_CAPS:
20950 + DBG("ioctl GET_CAPS\n");
20951 + if (!display) {
20952 + r = -EINVAL;
20953 + break;
20956 + p.caps.ctrl = display->caps;
20958 + if (copy_to_user((void __user *)arg, &p.caps, sizeof(p.caps)))
20959 + r = -EFAULT;
20960 + break;
20962 + case OMAPFB_SET_UPDATE_MODE:
20963 + DBG("ioctl SET_UPDATE_MODE\n");
20964 + if (get_user(p.update_mode, (int __user *)arg))
20965 + r = -EFAULT;
20966 + else
20967 + r = omapfb_set_update_mode(fbi, p.update_mode);
20968 + break;
20970 + case OMAPFB_GET_UPDATE_MODE:
20971 + DBG("ioctl GET_UPDATE_MODE\n");
20972 + r = omapfb_get_update_mode(fbi, &p.update_mode);
20973 + if (r)
20974 + break;
20975 + if (put_user(p.update_mode,
20976 + (enum omapfb_update_mode __user *)arg))
20977 + r = -EFAULT;
20978 + break;
20980 + case OMAPFB_SET_COLOR_KEY:
20981 + DBG("ioctl SET_COLOR_KEY\n");
20982 + if (copy_from_user(&p.color_key, (void __user *)arg,
20983 + sizeof(p.color_key)))
20984 + r = -EFAULT;
20985 + else
20986 + r = omapfb_set_color_key(fbi, &p.color_key);
20987 + break;
20989 + case OMAPFB_GET_COLOR_KEY:
20990 + DBG("ioctl GET_COLOR_KEY\n");
20991 + if ((r = omapfb_get_color_key(fbi, &p.color_key)) < 0)
20992 + break;
20993 + if (copy_to_user((void __user *)arg, &p.color_key,
20994 + sizeof(p.color_key)))
20995 + r = -EFAULT;
20996 + break;
20998 + case OMAPFB_WAITFORVSYNC:
20999 + DBG("ioctl WAITFORVSYNC\n");
21000 + if (!display) {
21001 + r = -EINVAL;
21002 + break;
21005 + r = display->wait_vsync(display);
21006 + break;
21008 + /* LCD and CTRL tests do the same thing for backward
21009 + * compatibility */
21010 + case OMAPFB_LCD_TEST:
21011 + DBG("ioctl LCD_TEST\n");
21012 + if (get_user(p.test_num, (int __user *)arg)) {
21013 + r = -EFAULT;
21014 + break;
21016 + if (!display || !display->run_test) {
21017 + r = -EINVAL;
21018 + break;
21021 + r = display->run_test(display, p.test_num);
21023 + break;
21025 + case OMAPFB_CTRL_TEST:
21026 + DBG("ioctl CTRL_TEST\n");
21027 + if (get_user(p.test_num, (int __user *)arg)) {
21028 + r = -EFAULT;
21029 + break;
21031 + if (!display || !display->run_test) {
21032 + r = -EINVAL;
21033 + break;
21036 + r = display->run_test(display, p.test_num);
21038 + break;
21040 + case OMAPFB_MEMORY_READ:
21041 + DBG("ioctl MEMORY_READ\n");
21043 + if (copy_from_user(&p.memory_read, (void __user *)arg,
21044 + sizeof(p.memory_read))) {
21045 + r = -EFAULT;
21046 + break;
21049 + r = omapfb_memory_read(fbi, &p.memory_read);
21051 + break;
21053 + default:
21054 + dev_err(fbdev->dev, "Unknown ioctl 0x%x\n", cmd);
21055 + r = -EINVAL;
21058 + if (r < 0)
21059 + DBG("ioctl failed: %d\n", r);
21061 + return r;
21065 diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/omap2/omapfb/omapfb-main.c
21066 new file mode 100644
21067 index 0000000..e4186ec
21068 --- /dev/null
21069 +++ b/drivers/video/omap2/omapfb/omapfb-main.c
21070 @@ -0,0 +1,1944 @@
21072 + * linux/drivers/video/omap2/omapfb-main.c
21074 + * Copyright (C) 2008 Nokia Corporation
21075 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
21077 + * Some code and ideas taken from drivers/video/omap/ driver
21078 + * by Imre Deak.
21080 + * This program is free software; you can redistribute it and/or modify it
21081 + * under the terms of the GNU General Public License version 2 as published by
21082 + * the Free Software Foundation.
21084 + * This program is distributed in the hope that it will be useful, but WITHOUT
21085 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
21086 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
21087 + * more details.
21089 + * You should have received a copy of the GNU General Public License along with
21090 + * this program. If not, see <http://www.gnu.org/licenses/>.
21091 + */
21093 +#include <linux/module.h>
21094 +#include <linux/delay.h>
21095 +#include <linux/fb.h>
21096 +#include <linux/dma-mapping.h>
21097 +#include <linux/vmalloc.h>
21098 +#include <linux/device.h>
21099 +#include <linux/platform_device.h>
21100 +#include <linux/omapfb.h>
21102 +#include <mach/display.h>
21103 +#include <mach/vram.h>
21104 +#include <mach/vrfb.h>
21106 +#include "omapfb.h"
21108 +#define MODULE_NAME "omapfb"
21110 +static char *def_mode;
21111 +static char *def_vram;
21112 +static int def_vrfb;
21113 +static int def_rotate;
21114 +static int def_mirror;
21116 +#ifdef DEBUG
21117 +unsigned int omapfb_debug;
21118 +module_param_named(debug, omapfb_debug, bool, 0644);
21119 +static unsigned int omapfb_test_pattern;
21120 +module_param_named(test, omapfb_test_pattern, bool, 0644);
21121 +#endif
21123 +#ifdef DEBUG
21124 +static void draw_pixel(struct fb_info *fbi, int x, int y, unsigned color)
21126 + struct fb_var_screeninfo *var = &fbi->var;
21127 + struct fb_fix_screeninfo *fix = &fbi->fix;
21128 + void __iomem *addr = fbi->screen_base;
21129 + const unsigned bytespp = var->bits_per_pixel >> 3;
21130 + const unsigned line_len = fix->line_length / bytespp;
21132 + int r = (color >> 16) & 0xff;
21133 + int g = (color >> 8) & 0xff;
21134 + int b = (color >> 0) & 0xff;
21136 + if (var->bits_per_pixel == 16) {
21137 + u16 __iomem *p = (u16 __iomem *)addr;
21138 + p += y * line_len + x;
21140 + r = r * 32 / 256;
21141 + g = g * 64 / 256;
21142 + b = b * 32 / 256;
21144 + __raw_writew((r << 11) | (g << 5) | (b << 0), p);
21145 + } else if (var->bits_per_pixel == 24) {
21146 + u8 __iomem *p = (u8 __iomem *)addr;
21147 + p += (y * line_len + x) * 3;
21149 + __raw_writeb(b, p + 0);
21150 + __raw_writeb(g, p + 1);
21151 + __raw_writeb(r, p + 2);
21152 + } else if (var->bits_per_pixel == 32) {
21153 + u32 __iomem *p = (u32 __iomem *)addr;
21154 + p += y * line_len + x;
21155 + __raw_writel(color, p);
21159 +static void fill_fb(struct fb_info *fbi)
21161 + struct fb_var_screeninfo *var = &fbi->var;
21162 + const short w = var->xres_virtual;
21163 + const short h = var->yres_virtual;
21164 + void __iomem *addr = fbi->screen_base;
21165 + int y, x;
21167 + if (!addr)
21168 + return;
21170 + DBG("fill_fb %dx%d, line_len %d bytes\n", w, h, fbi->fix.line_length);
21172 + for (y = 0; y < h; y++) {
21173 + for (x = 0; x < w; x++) {
21174 + if (x < 20 && y < 20)
21175 + draw_pixel(fbi, x, y, 0xffffff);
21176 + else if (x < 20 && (y > 20 && y < h - 20))
21177 + draw_pixel(fbi, x, y, 0xff);
21178 + else if (y < 20 && (x > 20 && x < w - 20))
21179 + draw_pixel(fbi, x, y, 0xff00);
21180 + else if (x > w - 20 && (y > 20 && y < h - 20))
21181 + draw_pixel(fbi, x, y, 0xff0000);
21182 + else if (y > h - 20 && (x > 20 && x < w - 20))
21183 + draw_pixel(fbi, x, y, 0xffff00);
21184 + else if (x == 20 || x == w - 20 ||
21185 + y == 20 || y == h - 20)
21186 + draw_pixel(fbi, x, y, 0xffffff);
21187 + else if (x == y || w - x == h - y)
21188 + draw_pixel(fbi, x, y, 0xff00ff);
21189 + else if (w - x == y || x == h - y)
21190 + draw_pixel(fbi, x, y, 0x00ffff);
21191 + else if (x > 20 && y > 20 && x < w - 20 && y < h - 20) {
21192 + int t = x * 3 / w;
21193 + unsigned r = 0, g = 0, b = 0;
21194 + unsigned c;
21195 + if (var->bits_per_pixel == 16) {
21196 + if (t == 0)
21197 + b = (y % 32) * 256 / 32;
21198 + else if (t == 1)
21199 + g = (y % 64) * 256 / 64;
21200 + else if (t == 2)
21201 + r = (y % 32) * 256 / 32;
21202 + } else {
21203 + if (t == 0)
21204 + b = (y % 256);
21205 + else if (t == 1)
21206 + g = (y % 256);
21207 + else if (t == 2)
21208 + r = (y % 256);
21210 + c = (r << 16) | (g << 8) | (b << 0);
21211 + draw_pixel(fbi, x, y, c);
21212 + } else {
21213 + draw_pixel(fbi, x, y, 0);
21218 +#endif
21220 +static unsigned omapfb_get_vrfb_offset(struct omapfb_info *ofbi, int rot)
21222 + struct vrfb *vrfb = &ofbi->region.vrfb;
21223 + unsigned offset;
21225 + switch (rot) {
21226 + case FB_ROTATE_UR:
21227 + offset = 0;
21228 + break;
21229 + case FB_ROTATE_CW:
21230 + offset = vrfb->yoffset;
21231 + break;
21232 + case FB_ROTATE_UD:
21233 + offset = vrfb->yoffset * OMAP_VRFB_LINE_LEN + vrfb->xoffset;
21234 + break;
21235 + case FB_ROTATE_CCW:
21236 + offset = vrfb->xoffset * OMAP_VRFB_LINE_LEN;
21237 + break;
21238 + default:
21239 + BUG();
21242 + offset *= vrfb->bytespp;
21244 + return offset;
21247 +static u32 omapfb_get_region_rot_paddr(struct omapfb_info *ofbi)
21249 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
21250 + unsigned offset;
21251 + int rot;
21253 + rot = ofbi->rotation;
21255 + offset = omapfb_get_vrfb_offset(ofbi, rot);
21257 + return ofbi->region.vrfb.paddr[rot] + offset;
21258 + } else {
21259 + return ofbi->region.paddr;
21263 +u32 omapfb_get_region_paddr(struct omapfb_info *ofbi)
21265 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
21266 + return ofbi->region.vrfb.paddr[0];
21267 + else
21268 + return ofbi->region.paddr;
21271 +void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi)
21273 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
21274 + return ofbi->region.vrfb.vaddr[0];
21275 + else
21276 + return ofbi->region.vaddr;
21279 +static enum omap_color_mode fb_mode_to_dss_mode(struct fb_var_screeninfo *var)
21281 + switch (var->nonstd) {
21282 + case 0:
21283 + break;
21284 + case OMAPFB_COLOR_YUV422:
21285 + return OMAP_DSS_COLOR_UYVY;
21287 + case OMAPFB_COLOR_YUY422:
21288 + return OMAP_DSS_COLOR_YUV2;
21290 + case OMAPFB_COLOR_ARGB16:
21291 + return OMAP_DSS_COLOR_ARGB16;
21293 + case OMAPFB_COLOR_ARGB32:
21294 + return OMAP_DSS_COLOR_ARGB32;
21296 + case OMAPFB_COLOR_RGBA32:
21297 + return OMAP_DSS_COLOR_RGBA32;
21299 + case OMAPFB_COLOR_RGBX32:
21300 + return OMAP_DSS_COLOR_RGBX32;
21302 + default:
21303 + return -EINVAL;
21306 + switch (var->bits_per_pixel) {
21307 + case 1:
21308 + return OMAP_DSS_COLOR_CLUT1;
21309 + case 2:
21310 + return OMAP_DSS_COLOR_CLUT2;
21311 + case 4:
21312 + return OMAP_DSS_COLOR_CLUT4;
21313 + case 8:
21314 + return OMAP_DSS_COLOR_CLUT8;
21315 + case 12:
21316 + return OMAP_DSS_COLOR_RGB12U;
21317 + case 16:
21318 + return OMAP_DSS_COLOR_RGB16;
21319 + case 24:
21320 + return OMAP_DSS_COLOR_RGB24P;
21321 + case 32:
21322 + return OMAP_DSS_COLOR_RGB24U;
21323 + default:
21324 + return -EINVAL;
21327 + return -EINVAL;
21330 +void set_fb_fix(struct fb_info *fbi)
21332 + struct fb_fix_screeninfo *fix = &fbi->fix;
21333 + struct fb_var_screeninfo *var = &fbi->var;
21334 + struct omapfb_info *ofbi = FB2OFB(fbi);
21335 + struct omapfb2_mem_region *rg = &ofbi->region;
21337 + DBG("set_fb_fix\n");
21339 + /* used by open/write in fbmem.c */
21340 + fbi->screen_base = (char __iomem *)omapfb_get_region_vaddr(ofbi);
21342 + /* used by mmap in fbmem.c */
21343 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
21344 + fix->line_length =
21345 + (OMAP_VRFB_LINE_LEN * var->bits_per_pixel) >> 3;
21346 + else
21347 + fix->line_length =
21348 + (var->xres_virtual * var->bits_per_pixel) >> 3;
21349 + fix->smem_start = omapfb_get_region_paddr(ofbi);
21350 + fix->smem_len = rg->size;
21352 + fix->type = FB_TYPE_PACKED_PIXELS;
21354 + if (var->nonstd)
21355 + fix->visual = FB_VISUAL_PSEUDOCOLOR;
21356 + else {
21357 + switch (var->bits_per_pixel) {
21358 + case 32:
21359 + case 24:
21360 + case 16:
21361 + case 12:
21362 + fix->visual = FB_VISUAL_TRUECOLOR;
21363 + /* 12bpp is stored in 16 bits */
21364 + break;
21365 + case 1:
21366 + case 2:
21367 + case 4:
21368 + case 8:
21369 + fix->visual = FB_VISUAL_PSEUDOCOLOR;
21370 + break;
21374 + fix->accel = FB_ACCEL_NONE;
21376 + fix->xpanstep = 1;
21377 + fix->ypanstep = 1;
21379 + if (rg->size) {
21380 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
21381 + omap_vrfb_setup(&rg->vrfb, rg->paddr,
21382 + var->xres_virtual, var->yres_virtual,
21383 + var->bits_per_pixel >> 3);
21387 +/* check new var and possibly modify it to be ok */
21388 +int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var)
21390 + struct omapfb_info *ofbi = FB2OFB(fbi);
21391 + struct omap_display *display = fb2display(fbi);
21392 + unsigned long max_frame_size;
21393 + unsigned long line_size;
21394 + int xres_min, yres_min;
21395 + int xres_max, yres_max;
21396 + enum omap_color_mode mode = 0;
21397 + int i;
21398 + int bytespp;
21400 + DBG("check_fb_var %d\n", ofbi->id);
21402 + if (ofbi->region.size == 0)
21403 + return 0;
21405 + /* if we are using non standard mode, fix the bpp first */
21406 + switch (var->nonstd) {
21407 + case 0:
21408 + break;
21409 + case OMAPFB_COLOR_YUV422:
21410 + case OMAPFB_COLOR_YUY422:
21411 + case OMAPFB_COLOR_ARGB16:
21412 + var->bits_per_pixel = 16;
21413 + break;
21414 + case OMAPFB_COLOR_ARGB32:
21415 + case OMAPFB_COLOR_RGBA32:
21416 + case OMAPFB_COLOR_RGBX32:
21417 + var->bits_per_pixel = 32;
21418 + break;
21419 + default:
21420 + DBG("invalid nonstd mode\n");
21421 + return -EINVAL;
21424 + mode = fb_mode_to_dss_mode(var);
21425 + if (mode < 0) {
21426 + DBG("cannot convert var to omap dss mode\n");
21427 + return -EINVAL;
21430 + for (i = 0; i < ofbi->num_overlays; ++i) {
21431 + if ((ofbi->overlays[i]->supported_modes & mode) == 0) {
21432 + DBG("invalid mode\n");
21433 + return -EINVAL;
21437 + if (var->rotate < 0 || var->rotate > 3)
21438 + return -EINVAL;
21440 + if (var->rotate != fbi->var.rotate) {
21441 + DBG("rotation changing\n");
21443 + ofbi->rotation = var->rotate;
21445 + if (abs(var->rotate - fbi->var.rotate) != 2) {
21446 + int tmp;
21447 + DBG("rotate changing 90/270 degrees. "
21448 + "swapping x/y res\n");
21450 + tmp = var->yres;
21451 + var->yres = var->xres;
21452 + var->xres = tmp;
21454 + tmp = var->yres_virtual;
21455 + var->yres_virtual = var->xres_virtual;
21456 + var->xres_virtual = tmp;
21460 + xres_min = OMAPFB_PLANE_XRES_MIN;
21461 + xres_max = 2048;
21462 + yres_min = OMAPFB_PLANE_YRES_MIN;
21463 + yres_max = 2048;
21465 + bytespp = var->bits_per_pixel >> 3;
21467 + /* XXX: some applications seem to set virtual res to 0. */
21468 + if (var->xres_virtual == 0)
21469 + var->xres_virtual = var->xres;
21471 + if (var->yres_virtual == 0)
21472 + var->yres_virtual = var->yres;
21474 + if (var->xres_virtual < xres_min || var->yres_virtual < yres_min)
21475 + return -EINVAL;
21477 + if (var->xres < xres_min)
21478 + var->xres = xres_min;
21479 + if (var->yres < yres_min)
21480 + var->yres = yres_min;
21481 + if (var->xres > xres_max)
21482 + var->xres = xres_max;
21483 + if (var->yres > yres_max)
21484 + var->yres = yres_max;
21486 + if (var->xres > var->xres_virtual)
21487 + var->xres = var->xres_virtual;
21488 + if (var->yres > var->yres_virtual)
21489 + var->yres = var->yres_virtual;
21491 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
21492 + line_size = OMAP_VRFB_LINE_LEN * bytespp;
21493 + else
21494 + line_size = var->xres_virtual * bytespp;
21496 + max_frame_size = ofbi->region.size;
21498 + DBG("max frame size %lu, line size %lu\n", max_frame_size, line_size);
21500 + if (line_size * var->yres_virtual > max_frame_size) {
21501 + DBG("can't fit FB into memory, reducing y\n");
21502 + var->yres_virtual = max_frame_size / line_size;
21504 + if (var->yres_virtual < yres_min)
21505 + var->yres_virtual = yres_min;
21507 + if (var->yres > var->yres_virtual)
21508 + var->yres = var->yres_virtual;
21511 + if (line_size * var->yres_virtual > max_frame_size) {
21512 + DBG("can't fit FB into memory, reducing x\n");
21513 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB)
21514 + return -EINVAL;
21516 + var->xres_virtual = max_frame_size / var->yres_virtual /
21517 + bytespp;
21519 + if (var->xres_virtual < xres_min)
21520 + var->xres_virtual = xres_min;
21522 + if (var->xres > var->xres_virtual)
21523 + var->xres = var->xres_virtual;
21525 + line_size = var->xres_virtual * bytespp;
21528 + if (line_size * var->yres_virtual > max_frame_size) {
21529 + DBG("cannot fit FB to memory\n");
21530 + return -EINVAL;
21533 + if (var->xres + var->xoffset > var->xres_virtual)
21534 + var->xoffset = var->xres_virtual - var->xres;
21535 + if (var->yres + var->yoffset > var->yres_virtual)
21536 + var->yoffset = var->yres_virtual - var->yres;
21538 + if (var->bits_per_pixel == 16) {
21539 + var->red.offset = 11; var->red.length = 5;
21540 + var->red.msb_right = 0;
21541 + var->green.offset = 5; var->green.length = 6;
21542 + var->green.msb_right = 0;
21543 + var->blue.offset = 0; var->blue.length = 5;
21544 + var->blue.msb_right = 0;
21545 + } else if (var->bits_per_pixel == 24) {
21546 + var->red.offset = 16; var->red.length = 8;
21547 + var->red.msb_right = 0;
21548 + var->green.offset = 8; var->green.length = 8;
21549 + var->green.msb_right = 0;
21550 + var->blue.offset = 0; var->blue.length = 8;
21551 + var->blue.msb_right = 0;
21552 + var->transp.offset = 0; var->transp.length = 0;
21553 + } else if (var->bits_per_pixel == 32) {
21554 + var->red.offset = 16; var->red.length = 8;
21555 + var->red.msb_right = 0;
21556 + var->green.offset = 8; var->green.length = 8;
21557 + var->green.msb_right = 0;
21558 + var->blue.offset = 0; var->blue.length = 8;
21559 + var->blue.msb_right = 0;
21560 + var->transp.offset = 0; var->transp.length = 0;
21561 + } else {
21562 + DBG("failed to setup fb color mask\n");
21563 + return -EINVAL;
21566 + DBG("xres = %d, yres = %d, vxres = %d, vyres = %d\n",
21567 + var->xres, var->yres,
21568 + var->xres_virtual, var->yres_virtual);
21570 + var->height = -1;
21571 + var->width = -1;
21572 + var->grayscale = 0;
21574 + if (display && display->get_timings) {
21575 + struct omap_video_timings timings;
21576 + display->get_timings(display, &timings);
21578 + /* pixclock in ps, the rest in pixclock */
21579 + var->pixclock = timings.pixel_clock != 0 ?
21580 + KHZ2PICOS(timings.pixel_clock) :
21581 + 0;
21582 + var->left_margin = timings.hfp;
21583 + var->right_margin = timings.hbp;
21584 + var->upper_margin = timings.vfp;
21585 + var->lower_margin = timings.vbp;
21586 + var->hsync_len = timings.hsw;
21587 + var->vsync_len = timings.vsw;
21588 + } else {
21589 + var->pixclock = 0;
21590 + var->left_margin = 0;
21591 + var->right_margin = 0;
21592 + var->upper_margin = 0;
21593 + var->lower_margin = 0;
21594 + var->hsync_len = 0;
21595 + var->vsync_len = 0;
21598 + /* TODO: get these from panel->config */
21599 + var->vmode = FB_VMODE_NONINTERLACED;
21600 + var->sync = 0;
21602 + return 0;
21606 + * ---------------------------------------------------------------------------
21607 + * fbdev framework callbacks
21608 + * ---------------------------------------------------------------------------
21609 + */
21610 +static int omapfb_open(struct fb_info *fbi, int user)
21612 + return 0;
21615 +static int omapfb_release(struct fb_info *fbi, int user)
21617 + struct omapfb_info *ofbi = FB2OFB(fbi);
21618 + struct omapfb2_device *fbdev = ofbi->fbdev;
21619 + struct omap_display *display = fb2display(fbi);
21621 + DBG("Closing fb with plane index %d\n", ofbi->id);
21623 + omapfb_lock(fbdev);
21624 +#if 1
21625 + if (display && display->get_update_mode && display->update) {
21626 + /* XXX this update should be removed, I think. But it's
21627 + * good for debugging */
21628 + if (display->get_update_mode(display) ==
21629 + OMAP_DSS_UPDATE_MANUAL) {
21630 + u16 w, h;
21632 + if (display->sync)
21633 + display->sync(display);
21635 + display->get_resolution(display, &w, &h);
21636 + display->update(display, 0, 0, w, h);
21639 +#endif
21641 + if (display && display->sync)
21642 + display->sync(display);
21644 + omapfb_unlock(fbdev);
21646 + return 0;
21649 +/* setup overlay according to the fb */
21650 +static int omapfb_setup_overlay(struct fb_info *fbi, struct omap_overlay *ovl,
21651 + u16 posx, u16 posy, u16 outw, u16 outh)
21653 + int r = 0;
21654 + struct omapfb_info *ofbi = FB2OFB(fbi);
21655 + struct fb_var_screeninfo *var = &fbi->var;
21656 + struct fb_fix_screeninfo *fix = &fbi->fix;
21657 + enum omap_color_mode mode = 0;
21658 + int offset;
21659 + u32 data_start_p;
21660 + void __iomem *data_start_v;
21661 + struct omap_overlay_info info;
21662 + int xres, yres;
21663 + int screen_width;
21664 + int rot, mirror;
21666 + DBG("setup_overlay %d, posx %d, posy %d, outw %d, outh %d\n", ofbi->id,
21667 + posx, posy, outw, outh);
21669 + if (ofbi->rotation == FB_ROTATE_CW || ofbi->rotation == FB_ROTATE_CCW) {
21670 + xres = var->yres;
21671 + yres = var->xres;
21672 + } else {
21673 + xres = var->xres;
21674 + yres = var->yres;
21677 + offset = ((var->yoffset * var->xres_virtual +
21678 + var->xoffset) * var->bits_per_pixel) >> 3;
21680 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
21681 + data_start_p = omapfb_get_region_rot_paddr(ofbi);
21682 + data_start_v = NULL;
21683 + } else {
21684 + data_start_p = omapfb_get_region_paddr(ofbi);
21685 + data_start_v = omapfb_get_region_vaddr(ofbi);
21688 + data_start_p += offset;
21689 + data_start_v += offset;
21691 + mode = fb_mode_to_dss_mode(var);
21693 + if (mode == -EINVAL) {
21694 + DBG("fb_mode_to_dss_mode failed");
21695 + r = -EINVAL;
21696 + goto err;
21699 + screen_width = fix->line_length / (var->bits_per_pixel >> 3);
21701 + ovl->get_overlay_info(ovl, &info);
21703 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
21704 + rot = 0;
21705 + mirror = 0;
21706 + } else {
21707 + rot = ofbi->rotation;
21708 + mirror = ofbi->mirror;
21711 + info.paddr = data_start_p;
21712 + info.vaddr = data_start_v;
21713 + info.screen_width = screen_width;
21714 + info.width = xres;
21715 + info.height = yres;
21716 + info.color_mode = mode;
21717 + info.rotation = rot;
21718 + info.mirror = mirror;
21720 + info.pos_x = posx;
21721 + info.pos_y = posy;
21722 + info.out_width = outw;
21723 + info.out_height = outh;
21725 + r = ovl->set_overlay_info(ovl, &info);
21726 + if (r) {
21727 + DBG("ovl->setup_overlay_info failed\n");
21728 + goto err;
21731 + return 0;
21733 +err:
21734 + DBG("setup_overlay failed\n");
21735 + return r;
21738 +/* apply var to the overlay */
21739 +int omapfb_apply_changes(struct fb_info *fbi, int init)
21741 + int r = 0;
21742 + struct omapfb_info *ofbi = FB2OFB(fbi);
21743 + struct fb_var_screeninfo *var = &fbi->var;
21744 + struct omap_overlay *ovl;
21745 + u16 posx, posy;
21746 + u16 outw, outh;
21747 + int i;
21749 +#ifdef DEBUG
21750 + if (omapfb_test_pattern)
21751 + fill_fb(fbi);
21752 +#endif
21754 + for (i = 0; i < ofbi->num_overlays; i++) {
21755 + ovl = ofbi->overlays[i];
21757 + DBG("apply_changes, fb %d, ovl %d\n", ofbi->id, ovl->id);
21759 + if (ofbi->region.size == 0) {
21760 + /* the fb is not available. disable the overlay */
21761 + omapfb_overlay_enable(ovl, 0);
21762 + if (!init && ovl->manager)
21763 + ovl->manager->apply(ovl->manager);
21764 + continue;
21767 + if (init || (ovl->caps & OMAP_DSS_OVL_CAP_SCALE) == 0) {
21768 + if (ofbi->rotation == FB_ROTATE_CW ||
21769 + ofbi->rotation == FB_ROTATE_CCW) {
21770 + outw = var->yres;
21771 + outh = var->xres;
21772 + } else {
21773 + outw = var->xres;
21774 + outh = var->yres;
21776 + } else {
21777 + outw = ovl->info.out_width;
21778 + outh = ovl->info.out_height;
21781 + if (init) {
21782 + posx = 0;
21783 + posy = 0;
21784 + } else {
21785 + posx = ovl->info.pos_x;
21786 + posy = ovl->info.pos_y;
21789 + r = omapfb_setup_overlay(fbi, ovl, posx, posy, outw, outh);
21790 + if (r)
21791 + goto err;
21793 + if (!init && ovl->manager)
21794 + ovl->manager->apply(ovl->manager);
21796 + return 0;
21797 +err:
21798 + DBG("apply_changes failed\n");
21799 + return r;
21802 +/* checks var and eventually tweaks it to something supported,
21803 + * DO NOT MODIFY PAR */
21804 +static int omapfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fbi)
21806 + int r;
21808 + DBG("check_var(%d)\n", FB2OFB(fbi)->id);
21810 + r = check_fb_var(fbi, var);
21812 + return r;
21815 +/* set the video mode according to info->var */
21816 +static int omapfb_set_par(struct fb_info *fbi)
21818 + int r;
21820 + DBG("set_par(%d)\n", FB2OFB(fbi)->id);
21822 + set_fb_fix(fbi);
21823 + r = omapfb_apply_changes(fbi, 0);
21825 + return r;
21828 +static int omapfb_pan_display(struct fb_var_screeninfo *var,
21829 + struct fb_info *fbi)
21831 + struct omapfb_info *ofbi = FB2OFB(fbi);
21832 + struct omapfb2_device *fbdev = ofbi->fbdev;
21833 + int r = 0;
21835 + DBG("pan_display(%d)\n", ofbi->id);
21837 + omapfb_lock(fbdev);
21839 + if (var->xoffset != fbi->var.xoffset ||
21840 + var->yoffset != fbi->var.yoffset) {
21841 + struct fb_var_screeninfo new_var;
21843 + new_var = fbi->var;
21844 + new_var.xoffset = var->xoffset;
21845 + new_var.yoffset = var->yoffset;
21847 + r = check_fb_var(fbi, &new_var);
21849 + if (r == 0) {
21850 + fbi->var = new_var;
21851 + set_fb_fix(fbi);
21852 + r = omapfb_apply_changes(fbi, 0);
21856 + omapfb_unlock(fbdev);
21858 + return r;
21861 +static void mmap_user_open(struct vm_area_struct *vma)
21863 + struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data;
21865 + atomic_inc(&ofbi->map_count);
21868 +static void mmap_user_close(struct vm_area_struct *vma)
21870 + struct omapfb_info *ofbi = (struct omapfb_info *)vma->vm_private_data;
21872 + atomic_dec(&ofbi->map_count);
21875 +static struct vm_operations_struct mmap_user_ops = {
21876 + .open = mmap_user_open,
21877 + .close = mmap_user_close,
21880 +static int omapfb_mmap(struct fb_info *fbi, struct vm_area_struct *vma)
21882 + struct omapfb_info *ofbi = FB2OFB(fbi);
21883 + struct fb_fix_screeninfo *fix = &fbi->fix;
21884 + unsigned long off;
21885 + unsigned long start;
21886 + u32 len;
21888 + if (vma->vm_end - vma->vm_start == 0)
21889 + return 0;
21890 + if (vma->vm_pgoff > (~0UL >> PAGE_SHIFT))
21891 + return -EINVAL;
21892 + off = vma->vm_pgoff << PAGE_SHIFT;
21894 + start = omapfb_get_region_paddr(ofbi);
21895 + len = fix->smem_len;
21896 + if (off >= len)
21897 + return -EINVAL;
21898 + if ((vma->vm_end - vma->vm_start + off) > len)
21899 + return -EINVAL;
21901 + off += start;
21903 + DBG("user mmap region start %lx, len %d, off %lx\n", start, len, off);
21905 + vma->vm_pgoff = off >> PAGE_SHIFT;
21906 + vma->vm_flags |= VM_IO | VM_RESERVED;
21907 + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
21908 + vma->vm_ops = &mmap_user_ops;
21909 + vma->vm_private_data = ofbi;
21910 + if (io_remap_pfn_range(vma, vma->vm_start, off >> PAGE_SHIFT,
21911 + vma->vm_end - vma->vm_start, vma->vm_page_prot))
21912 + return -EAGAIN;
21913 + /* vm_ops.open won't be called for mmap itself. */
21914 + atomic_inc(&ofbi->map_count);
21915 + return 0;
21918 +/* Store a single color palette entry into a pseudo palette or the hardware
21919 + * palette if one is available. For now we support only 16bpp and thus store
21920 + * the entry only to the pseudo palette.
21921 + */
21922 +static int _setcolreg(struct fb_info *fbi, u_int regno, u_int red, u_int green,
21923 + u_int blue, u_int transp, int update_hw_pal)
21925 + /*struct omapfb_info *ofbi = FB2OFB(fbi);*/
21926 + /*struct omapfb2_device *fbdev = ofbi->fbdev;*/
21927 + struct fb_var_screeninfo *var = &fbi->var;
21928 + int r = 0;
21930 + enum omapfb_color_format mode = OMAPFB_COLOR_RGB24U; /* XXX */
21932 + /*switch (plane->color_mode) {*/
21933 + switch (mode) {
21934 + case OMAPFB_COLOR_YUV422:
21935 + case OMAPFB_COLOR_YUV420:
21936 + case OMAPFB_COLOR_YUY422:
21937 + r = -EINVAL;
21938 + break;
21939 + case OMAPFB_COLOR_CLUT_8BPP:
21940 + case OMAPFB_COLOR_CLUT_4BPP:
21941 + case OMAPFB_COLOR_CLUT_2BPP:
21942 + case OMAPFB_COLOR_CLUT_1BPP:
21943 + /*
21944 + if (fbdev->ctrl->setcolreg)
21945 + r = fbdev->ctrl->setcolreg(regno, red, green, blue,
21946 + transp, update_hw_pal);
21947 + */
21948 + /* Fallthrough */
21949 + r = -EINVAL;
21950 + break;
21951 + case OMAPFB_COLOR_RGB565:
21952 + case OMAPFB_COLOR_RGB444:
21953 + case OMAPFB_COLOR_RGB24P:
21954 + case OMAPFB_COLOR_RGB24U:
21955 + if (r != 0)
21956 + break;
21958 + if (regno < 0) {
21959 + r = -EINVAL;
21960 + break;
21963 + if (regno < 16) {
21964 + u16 pal;
21965 + pal = ((red >> (16 - var->red.length)) <<
21966 + var->red.offset) |
21967 + ((green >> (16 - var->green.length)) <<
21968 + var->green.offset) |
21969 + (blue >> (16 - var->blue.length));
21970 + ((u32 *)(fbi->pseudo_palette))[regno] = pal;
21972 + break;
21973 + default:
21974 + BUG();
21976 + return r;
21979 +static int omapfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
21980 + u_int transp, struct fb_info *info)
21982 + DBG("setcolreg\n");
21984 + return _setcolreg(info, regno, red, green, blue, transp, 1);
21987 +static int omapfb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
21989 + int count, index, r;
21990 + u16 *red, *green, *blue, *transp;
21991 + u16 trans = 0xffff;
21993 + DBG("setcmap\n");
21995 + red = cmap->red;
21996 + green = cmap->green;
21997 + blue = cmap->blue;
21998 + transp = cmap->transp;
21999 + index = cmap->start;
22001 + for (count = 0; count < cmap->len; count++) {
22002 + if (transp)
22003 + trans = *transp++;
22004 + r = _setcolreg(info, index++, *red++, *green++, *blue++, trans,
22005 + count == cmap->len - 1);
22006 + if (r != 0)
22007 + return r;
22010 + return 0;
22013 +static int omapfb_blank(int blank, struct fb_info *fbi)
22015 + struct omapfb_info *ofbi = FB2OFB(fbi);
22016 + struct omapfb2_device *fbdev = ofbi->fbdev;
22017 + struct omap_display *display = fb2display(fbi);
22018 + int do_update = 0;
22019 + int r = 0;
22021 + omapfb_lock(fbdev);
22023 + switch (blank) {
22024 + case FB_BLANK_UNBLANK:
22025 + if (display->state != OMAP_DSS_DISPLAY_SUSPENDED)
22026 + goto exit;
22028 + if (display->resume)
22029 + r = display->resume(display);
22031 + if (r == 0 && display->get_update_mode &&
22032 + display->get_update_mode(display) ==
22033 + OMAP_DSS_UPDATE_MANUAL)
22034 + do_update = 1;
22036 + break;
22038 + case FB_BLANK_NORMAL:
22039 + /* FB_BLANK_NORMAL could be implemented.
22040 + * Needs DSS additions. */
22041 + case FB_BLANK_VSYNC_SUSPEND:
22042 + case FB_BLANK_HSYNC_SUSPEND:
22043 + case FB_BLANK_POWERDOWN:
22044 + if (display->state != OMAP_DSS_DISPLAY_ACTIVE)
22045 + goto exit;
22047 + if (display->suspend)
22048 + r = display->suspend(display);
22050 + break;
22052 + default:
22053 + r = -EINVAL;
22056 +exit:
22057 + omapfb_unlock(fbdev);
22059 + if (r == 0 && do_update && display->update) {
22060 + u16 w, h;
22061 + display->get_resolution(display, &w, &h);
22063 + r = display->update(display, 0, 0, w, h);
22066 + return r;
22069 +#if 0
22070 +/* XXX fb_read and fb_write are needed for VRFB */
22071 +ssize_t omapfb_write(struct fb_info *info, const char __user *buf,
22072 + size_t count, loff_t *ppos)
22074 + DBG("omapfb_write %d, %lu\n", count, (unsigned long)*ppos);
22075 + // XXX needed for VRFB
22076 + return count;
22078 +#endif
22080 +static struct fb_ops omapfb_ops = {
22081 + .owner = THIS_MODULE,
22082 + .fb_open = omapfb_open,
22083 + .fb_release = omapfb_release,
22084 + .fb_fillrect = cfb_fillrect,
22085 + .fb_copyarea = cfb_copyarea,
22086 + .fb_imageblit = cfb_imageblit,
22087 + .fb_blank = omapfb_blank,
22088 + .fb_ioctl = omapfb_ioctl,
22089 + .fb_check_var = omapfb_check_var,
22090 + .fb_set_par = omapfb_set_par,
22091 + .fb_pan_display = omapfb_pan_display,
22092 + .fb_mmap = omapfb_mmap,
22093 + .fb_setcolreg = omapfb_setcolreg,
22094 + .fb_setcmap = omapfb_setcmap,
22095 + //.fb_write = omapfb_write,
22098 +static void omapfb_free_fbmem(struct fb_info *fbi)
22100 + struct omapfb_info *ofbi = FB2OFB(fbi);
22101 + struct omapfb2_device *fbdev = ofbi->fbdev;
22102 + struct omapfb2_mem_region *rg;
22104 + rg = &ofbi->region;
22106 + if (rg->paddr)
22107 + if (omap_vram_free(rg->paddr, rg->size))
22108 + dev_err(fbdev->dev, "VRAM FREE failed\n");
22110 + if (rg->vaddr)
22111 + iounmap(rg->vaddr);
22113 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
22114 + /* unmap the 0 angle rotation */
22115 + if (rg->vrfb.vaddr[0]) {
22116 + iounmap(rg->vrfb.vaddr[0]);
22117 + omap_vrfb_release_ctx(&rg->vrfb);
22121 + rg->vaddr = NULL;
22122 + rg->paddr = 0;
22123 + rg->alloc = 0;
22124 + rg->size = 0;
22127 +static int omapfb_free_all_fbmem(struct omapfb2_device *fbdev)
22129 + int i;
22131 + DBG("free all fbmem\n");
22133 + for (i = 0; i < fbdev->num_fbs; i++) {
22134 + struct fb_info *fbi = fbdev->fbs[i];
22135 + omapfb_free_fbmem(fbi);
22136 + memset(&fbi->fix, 0, sizeof(fbi->fix));
22137 + memset(&fbi->var, 0, sizeof(fbi->var));
22140 + return 0;
22143 +static int omapfb_alloc_fbmem(struct fb_info *fbi, unsigned long size,
22144 + unsigned long paddr)
22146 + struct omapfb_info *ofbi = FB2OFB(fbi);
22147 + struct omapfb2_device *fbdev = ofbi->fbdev;
22148 + struct omapfb2_mem_region *rg;
22149 + void __iomem *vaddr;
22150 + int r;
22151 + int clear = 0;
22153 + rg = &ofbi->region;
22154 + memset(rg, 0, sizeof(*rg));
22156 + size = PAGE_ALIGN(size);
22158 + if (!paddr) {
22159 + DBG("allocating %lu bytes for fb %d\n", size, ofbi->id);
22160 + r = omap_vram_alloc(OMAPFB_MEMTYPE_SDRAM, size, &paddr);
22161 + clear = 1;
22162 + } else {
22163 + DBG("reserving %lu bytes at %lx for fb %d\n", size, paddr,
22164 + ofbi->id);
22165 + r = omap_vram_reserve(paddr, size);
22168 + if (r) {
22169 + dev_err(fbdev->dev, "failed to allocate framebuffer\n");
22170 + return -ENOMEM;
22173 + if (ofbi->rotation_type != OMAPFB_ROT_VRFB) {
22174 + vaddr = ioremap_wc(paddr, size);
22176 + if (!vaddr) {
22177 + dev_err(fbdev->dev, "failed to ioremap framebuffer\n");
22178 + omap_vram_free(paddr, size);
22179 + return -ENOMEM;
22182 + DBG("allocated VRAM paddr %lx, vaddr %p\n", paddr, vaddr);
22184 + if (clear)
22185 + memset_io(vaddr, 0, size);
22186 + } else {
22187 + void __iomem *va;
22189 + r = omap_vrfb_request_ctx(&rg->vrfb);
22190 + if (r) {
22191 + dev_err(fbdev->dev, "vrfb create ctx failed\n");
22192 + return r;
22195 + /* only ioremap the 0 angle view */
22196 + va = ioremap_wc(rg->vrfb.paddr[0], size);
22198 + if(!va) {
22199 + printk(KERN_ERR "vrfb: ioremap failed\n");
22200 + return -ENOMEM;
22203 + DBG("ioremapped vrfb area 0 to %p\n", va);
22205 + rg->vrfb.vaddr[0] = va;
22207 + vaddr = NULL;
22209 + if (clear)
22210 + memset_io(va, 0, size);
22213 + rg->paddr = paddr;
22214 + rg->vaddr = vaddr;
22215 + rg->size = size;
22216 + rg->alloc = 1;
22218 + return 0;
22221 +/* allocate fbmem using display resolution as reference */
22222 +static int omapfb_alloc_fbmem_display(struct fb_info *fbi, unsigned long size,
22223 + unsigned long paddr)
22225 + struct omapfb_info *ofbi = FB2OFB(fbi);
22226 + struct omap_display *display;
22227 + int bytespp;
22229 + display = fb2display(fbi);
22231 + if (!display)
22232 + return 0;
22234 + switch (display->get_recommended_bpp(display)) {
22235 + case 16:
22236 + bytespp = 2;
22237 + break;
22238 + case 24:
22239 + bytespp = 4;
22240 + break;
22241 + default:
22242 + bytespp = 4;
22243 + break;
22246 + if (!size) {
22247 + u16 w, h;
22249 + display->get_resolution(display, &w, &h);
22251 + if (ofbi->rotation_type == OMAPFB_ROT_VRFB) {
22252 + int oldw = w, oldh = h;
22254 + omap_vrfb_adjust_size(&w, &h, bytespp);
22256 + /* Because we change the resolution of the 0 degree view,
22257 + * we need to alloc max(w, h) for height */
22258 + h = max(w, h);
22259 + w = OMAP_VRFB_LINE_LEN;
22261 + DBG("adjusting fb mem size for VRFB, %dx%d -> %dx%d\n",
22262 + oldw, oldh, w, h);
22265 + size = w * h * bytespp;
22268 + return omapfb_alloc_fbmem(fbi, size, paddr);
22271 +static int omapfb_parse_vram_param(const char *param, int max_entries,
22272 + unsigned long *sizes, unsigned long *paddrs)
22274 + int fbnum;
22275 + unsigned long size;
22276 + unsigned long paddr = 0;
22277 + char *p, *start;
22279 + start = (char *)param;
22281 + while (1) {
22282 + p = start;
22284 + fbnum = simple_strtoul(p, &p, 10);
22286 + if (p == param)
22287 + return -EINVAL;
22289 + if (*p != ':')
22290 + return -EINVAL;
22292 + if (fbnum >= max_entries)
22293 + return -EINVAL;
22295 + size = memparse(p + 1, &p);
22297 + if (!size)
22298 + return -EINVAL;
22300 + paddr = 0;
22302 + if (*p == '@') {
22303 + paddr = simple_strtoul(p + 1, &p, 16);
22305 + if (!paddr)
22306 + return -EINVAL;
22310 + paddrs[fbnum] = paddr;
22311 + sizes[fbnum] = size;
22313 + if (*p == 0)
22314 + break;
22316 + if (*p != ',')
22317 + return -EINVAL;
22319 + ++p;
22321 + start = p;
22324 + return 0;
22327 +static int omapfb_allocate_all_fbs(struct omapfb2_device *fbdev)
22329 + int i, r;
22330 + unsigned long vram_sizes[10];
22331 + unsigned long vram_paddrs[10];
22333 + memset(&vram_sizes, 0, sizeof(vram_sizes));
22334 + memset(&vram_paddrs, 0, sizeof(vram_paddrs));
22336 + if (def_vram && omapfb_parse_vram_param(def_vram, 10,
22337 + vram_sizes, vram_paddrs)) {
22338 + dev_err(fbdev->dev, "failed to parse vram parameter\n");
22340 + memset(&vram_sizes, 0, sizeof(vram_sizes));
22341 + memset(&vram_paddrs, 0, sizeof(vram_paddrs));
22344 + if (fbdev->dev->platform_data) {
22345 + struct omapfb_platform_data *opd;
22346 + opd = fbdev->dev->platform_data;
22347 + for (i = 0; i < opd->mem_desc.region_cnt; ++i) {
22348 + if (!vram_sizes[i]) {
22349 + unsigned long size;
22350 + unsigned long paddr;
22352 + size = opd->mem_desc.region[i].size;
22353 + paddr = opd->mem_desc.region[i].paddr;
22355 + vram_sizes[i] = size;
22356 + vram_paddrs[i] = paddr;
22361 + for (i = 0; i < fbdev->num_fbs; i++) {
22362 + /* allocate memory automatically only for fb0, or if
22363 + * excplicitly defined with vram or plat data option */
22364 + if (i == 0 || vram_sizes[i] != 0) {
22365 + r = omapfb_alloc_fbmem_display(fbdev->fbs[i],
22366 + vram_sizes[i], vram_paddrs[i]);
22368 + if (r)
22369 + return r;
22373 + for (i = 0; i < fbdev->num_fbs; i++) {
22374 + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
22375 + struct omapfb2_mem_region *rg;
22376 + rg = &ofbi->region;
22378 + DBG("region%d phys %08x virt %p size=%lu\n",
22379 + i,
22380 + rg->paddr,
22381 + rg->vaddr,
22382 + rg->size);
22385 + return 0;
22388 +int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type)
22390 + struct omapfb_info *ofbi = FB2OFB(fbi);
22391 + struct omapfb2_device *fbdev = ofbi->fbdev;
22392 + struct omap_display *display = fb2display(fbi);
22393 + struct omapfb2_mem_region *rg = &ofbi->region;
22394 + unsigned long old_size = rg->size;
22395 + unsigned long old_paddr = rg->paddr;
22396 + int old_type = rg->type;
22397 + int r;
22399 + if (type > OMAPFB_MEMTYPE_MAX)
22400 + return -EINVAL;
22402 + size = PAGE_ALIGN(size);
22404 + if (old_size == size && old_type == type)
22405 + return 0;
22407 + if (display && display->sync)
22408 + display->sync(display);
22410 + omapfb_free_fbmem(fbi);
22412 + if (size == 0) {
22413 + memset(&fbi->fix, 0, sizeof(fbi->fix));
22414 + memset(&fbi->var, 0, sizeof(fbi->var));
22415 + return 0;
22418 + r = omapfb_alloc_fbmem(fbi, size, 0);
22420 + if (r) {
22421 + if (old_size)
22422 + omapfb_alloc_fbmem(fbi, old_size, old_paddr);
22424 + if (rg->size == 0) {
22425 + memset(&fbi->fix, 0, sizeof(fbi->fix));
22426 + memset(&fbi->var, 0, sizeof(fbi->var));
22429 + return r;
22432 + if (old_size == size)
22433 + return 0;
22435 + if (old_size == 0) {
22436 + DBG("initializing fb %d\n", ofbi->id);
22437 + r = omapfb_fb_init(fbdev, fbi);
22438 + if (r) {
22439 + DBG("omapfb_fb_init failed\n");
22440 + goto err;
22442 + r = omapfb_apply_changes(fbi, 1);
22443 + if (r) {
22444 + DBG("omapfb_apply_changes failed\n");
22445 + goto err;
22447 + } else {
22448 + struct fb_var_screeninfo new_var;
22449 + memcpy(&new_var, &fbi->var, sizeof(new_var));
22450 + r = check_fb_var(fbi, &new_var);
22451 + if (r)
22452 + goto err;
22453 + memcpy(&fbi->var, &new_var, sizeof(fbi->var));
22454 + set_fb_fix(fbi);
22457 + return 0;
22458 +err:
22459 + omapfb_free_fbmem(fbi);
22460 + memset(&fbi->fix, 0, sizeof(fbi->fix));
22461 + memset(&fbi->var, 0, sizeof(fbi->var));
22462 + return r;
22465 +/* initialize fb_info, var, fix to something sane based on the display */
22466 +int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi)
22468 + struct fb_var_screeninfo *var = &fbi->var;
22469 + struct fb_fix_screeninfo *fix = &fbi->fix;
22470 + struct omap_display *display = fb2display(fbi);
22471 + struct omapfb_info *ofbi = FB2OFB(fbi);
22472 + int r = 0;
22474 + fbi->fbops = &omapfb_ops;
22475 + fbi->flags = FBINFO_FLAG_DEFAULT;
22476 + fbi->pseudo_palette = fbdev->pseudo_palette;
22478 + strncpy(fix->id, MODULE_NAME, sizeof(fix->id));
22480 + if (ofbi->region.size == 0) {
22481 + memset(&fbi->fix, 0, sizeof(fbi->fix));
22482 + memset(&fbi->var, 0, sizeof(fbi->var));
22483 + return 0;
22486 + var->nonstd = 0;
22488 + var->rotate = ofbi->rotation;
22490 + if (display) {
22491 + u16 w, h;
22492 + display->get_resolution(display, &w, &h);
22494 + if (ofbi->rotation == FB_ROTATE_CW ||
22495 + ofbi->rotation == FB_ROTATE_CCW) {
22496 + var->xres = h;
22497 + var->yres = w;
22498 + } else {
22499 + var->xres = w;
22500 + var->yres = h;
22503 + var->xres_virtual = var->xres;
22504 + var->yres_virtual = var->yres;
22506 + switch (display->get_recommended_bpp(display)) {
22507 + case 16:
22508 + var->bits_per_pixel = 16;
22509 + break;
22510 + case 24:
22511 + var->bits_per_pixel = 32;
22512 + break;
22513 + default:
22514 + dev_err(fbdev->dev, "illegal display bpp\n");
22515 + return -EINVAL;
22517 + } else {
22518 + /* if there's no display, let's just guess some basic values */
22519 + var->xres = 320;
22520 + var->yres = 240;
22521 + var->xres_virtual = var->xres;
22522 + var->yres_virtual = var->yres;
22523 + var->bits_per_pixel = 16;
22526 + r = check_fb_var(fbi, var);
22527 + if (r)
22528 + goto err;
22530 + set_fb_fix(fbi);
22531 +err:
22532 + return r;
22535 +static void fbinfo_cleanup(struct omapfb2_device *fbdev, struct fb_info *fbi)
22537 + fb_dealloc_cmap(&fbi->cmap);
22541 +static void omapfb_free_resources(struct omapfb2_device *fbdev)
22543 + int i;
22545 + DBG("free_resources\n");
22547 + if (fbdev == NULL)
22548 + return;
22550 + for (i = 0; i < fbdev->num_fbs; i++)
22551 + unregister_framebuffer(fbdev->fbs[i]);
22553 + /* free the reserved fbmem */
22554 + omapfb_free_all_fbmem(fbdev);
22556 + for (i = 0; i < fbdev->num_fbs; i++) {
22557 + fbinfo_cleanup(fbdev, fbdev->fbs[i]);
22558 + framebuffer_release(fbdev->fbs[i]);
22561 + for (i = 0; i < fbdev->num_displays; i++) {
22562 + if (fbdev->displays[i]->state != OMAP_DSS_DISPLAY_DISABLED)
22563 + fbdev->displays[i]->disable(fbdev->displays[i]);
22565 + omap_dss_put_display(fbdev->displays[i]);
22568 + dev_set_drvdata(fbdev->dev, NULL);
22569 + kfree(fbdev);
22572 +static int omapfb_create_framebuffers(struct omapfb2_device *fbdev)
22574 + int r, i;
22576 + fbdev->num_fbs = 0;
22578 + DBG("create %d framebuffers\n", CONFIG_FB_OMAP2_NUM_FBS);
22580 + /* allocate fb_infos */
22581 + for (i = 0; i < CONFIG_FB_OMAP2_NUM_FBS; i++) {
22582 + struct fb_info *fbi;
22583 + struct omapfb_info *ofbi;
22585 + fbi = framebuffer_alloc(sizeof(struct omapfb_info),
22586 + fbdev->dev);
22588 + if (fbi == NULL) {
22589 + dev_err(fbdev->dev,
22590 + "unable to allocate memory for plane info\n");
22591 + return -ENOMEM;
22594 + fbdev->fbs[i] = fbi;
22596 + ofbi = FB2OFB(fbi);
22597 + ofbi->fbdev = fbdev;
22598 + ofbi->id = i;
22600 + /* assign these early, so that fb alloc can use them */
22601 + ofbi->rotation_type = def_vrfb ? OMAPFB_ROT_VRFB :
22602 + OMAPFB_ROT_DMA;
22603 + ofbi->rotation = def_rotate;
22604 + ofbi->mirror = def_mirror;
22606 + fbdev->num_fbs++;
22609 + DBG("fb_infos allocated\n");
22611 + /* assign overlays for the fbs */
22612 + for (i = 0; i < min(fbdev->num_fbs, fbdev->num_overlays); i++) {
22613 + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
22615 + ofbi->overlays[0] = fbdev->overlays[i];
22616 + ofbi->num_overlays = 1;
22619 + /* allocate fb memories */
22620 + r = omapfb_allocate_all_fbs(fbdev);
22621 + if (r) {
22622 + dev_err(fbdev->dev, "failed to allocate fbmem\n");
22623 + return r;
22626 + DBG("fbmems allocated\n");
22628 + /* setup fb_infos */
22629 + for (i = 0; i < fbdev->num_fbs; i++) {
22630 + r = omapfb_fb_init(fbdev, fbdev->fbs[i]);
22631 + if (r) {
22632 + dev_err(fbdev->dev, "failed to setup fb_info\n");
22633 + return r;
22637 + DBG("fb_infos initialized\n");
22639 + for (i = 0; i < fbdev->num_fbs; i++) {
22640 + r = register_framebuffer(fbdev->fbs[i]);
22641 + if (r != 0) {
22642 + dev_err(fbdev->dev,
22643 + "registering framebuffer %d failed\n", i);
22644 + return r;
22648 + DBG("framebuffers registered\n");
22650 + for (i = 0; i < fbdev->num_fbs; i++) {
22651 + r = omapfb_apply_changes(fbdev->fbs[i], 1);
22652 + if (r) {
22653 + dev_err(fbdev->dev, "failed to change mode\n");
22654 + return r;
22658 + DBG("create sysfs for fbs\n");
22659 + r = omapfb_create_sysfs(fbdev);
22660 + if (r) {
22661 + dev_err(fbdev->dev, "failed to create sysfs entries\n");
22662 + return r;
22665 + /* Enable fb0 */
22666 + if (fbdev->num_fbs > 0) {
22667 + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[0]);
22669 + if (ofbi->num_overlays > 0 ) {
22670 + struct omap_overlay *ovl = ofbi->overlays[0];
22672 + r = omapfb_overlay_enable(ovl, 1);
22674 + if (r) {
22675 + dev_err(fbdev->dev,
22676 + "failed to enable overlay\n");
22677 + return r;
22682 + DBG("create_framebuffers done\n");
22684 + return 0;
22687 +int omapfb_mode_to_timings(const char *mode_str,
22688 + struct omap_video_timings *timings, u8 *bpp)
22690 + struct fb_info fbi;
22691 + struct fb_var_screeninfo var;
22692 + struct fb_ops fbops;
22693 + int r;
22695 +#ifdef CONFIG_OMAP2_DSS_VENC
22696 + if (strcmp(mode_str, "pal") == 0) {
22697 + *timings = omap_dss_pal_timings;
22698 + *bpp = 0;
22699 + return 0;
22700 + } else if (strcmp(mode_str, "ntsc") == 0) {
22701 + *timings = omap_dss_ntsc_timings;
22702 + *bpp = 0;
22703 + return 0;
22705 +#endif
22707 + /* this is quite a hack, but I wanted to use the modedb and for
22708 + * that we need fb_info and var, so we create dummy ones */
22710 + memset(&fbi, 0, sizeof(fbi));
22711 + memset(&var, 0, sizeof(var));
22712 + memset(&fbops, 0, sizeof(fbops));
22713 + fbi.fbops = &fbops;
22715 + r = fb_find_mode(&var, &fbi, mode_str, NULL, 0, NULL, 24);
22717 + if (r != 0) {
22718 + timings->pixel_clock = PICOS2KHZ(var.pixclock);
22719 + timings->hfp = var.left_margin;
22720 + timings->hbp = var.right_margin;
22721 + timings->vfp = var.upper_margin;
22722 + timings->vbp = var.lower_margin;
22723 + timings->hsw = var.hsync_len;
22724 + timings->vsw = var.vsync_len;
22725 + timings->x_res = var.xres;
22726 + timings->y_res = var.yres;
22728 + switch (var.bits_per_pixel) {
22729 + case 16:
22730 + *bpp = 16;
22731 + break;
22732 + case 24:
22733 + case 32:
22734 + default:
22735 + *bpp = 24;
22736 + break;
22739 + return 0;
22740 + } else {
22741 + return -EINVAL;
22745 +static int omapfb_set_def_mode(struct omap_display *display, char *mode_str)
22747 + int r;
22748 + u8 bpp;
22749 + struct omap_video_timings timings;
22751 + r = omapfb_mode_to_timings(mode_str, &timings, &bpp);
22752 + if (r)
22753 + return r;
22755 + display->panel->recommended_bpp = bpp;
22757 + if (!display->check_timings || !display->set_timings)
22758 + return -EINVAL;
22760 + r = display->check_timings(display, &timings);
22761 + if (r)
22762 + return r;
22764 + display->set_timings(display, &timings);
22766 + return 0;
22769 +static int omapfb_parse_def_modes(struct omapfb2_device *fbdev)
22771 + char *str, *options, *this_opt;
22772 + int r = 0;
22774 + str = kmalloc(strlen(def_mode) + 1, GFP_KERNEL);
22775 + strcpy(str, def_mode);
22776 + options = str;
22778 + while (!r && (this_opt = strsep(&options, ",")) != NULL) {
22779 + char *p, *display_str, *mode_str;
22780 + struct omap_display *display;
22781 + int i;
22783 + p = strchr(this_opt, ':');
22784 + if (!p) {
22785 + r = -EINVAL;
22786 + break;
22789 + *p = 0;
22790 + display_str = this_opt;
22791 + mode_str = p + 1;
22793 + display = NULL;
22794 + for (i = 0; i < fbdev->num_displays; ++i) {
22795 + if (strcmp(fbdev->displays[i]->name,
22796 + display_str) == 0) {
22797 + display = fbdev->displays[i];
22798 + break;
22802 + if (!display) {
22803 + r = -EINVAL;
22804 + break;
22807 + r = omapfb_set_def_mode(display, mode_str);
22808 + if (r)
22809 + break;
22812 + kfree(str);
22814 + return r;
22817 +static int omapfb_probe(struct platform_device *pdev)
22819 + struct omapfb2_device *fbdev = NULL;
22820 + int r = 0;
22821 + int i, t;
22822 + struct omap_overlay *ovl;
22823 + struct omap_display *def_display;
22825 + DBG("omapfb_probe\n");
22827 + if (pdev->num_resources != 0) {
22828 + dev_err(&pdev->dev, "probed for an unknown device\n");
22829 + r = -ENODEV;
22830 + goto err0;
22833 + fbdev = kzalloc(sizeof(struct omapfb2_device), GFP_KERNEL);
22834 + if (fbdev == NULL) {
22835 + r = -ENOMEM;
22836 + goto err0;
22839 + mutex_init(&fbdev->mtx);
22841 + fbdev->dev = &pdev->dev;
22842 + platform_set_drvdata(pdev, fbdev);
22844 + fbdev->num_displays = 0;
22845 + t = omap_dss_get_num_displays();
22846 + for (i = 0; i < t; i++) {
22847 + struct omap_display *display;
22848 + display = omap_dss_get_display(i);
22849 + if (!display) {
22850 + dev_err(&pdev->dev, "can't get display %d\n", i);
22851 + r = -EINVAL;
22852 + goto cleanup;
22855 + fbdev->displays[fbdev->num_displays++] = display;
22858 + if (fbdev->num_displays == 0) {
22859 + dev_err(&pdev->dev, "no displays\n");
22860 + r = -EINVAL;
22861 + goto cleanup;
22864 + fbdev->num_overlays = omap_dss_get_num_overlays();
22865 + for (i = 0; i < fbdev->num_overlays; i++)
22866 + fbdev->overlays[i] = omap_dss_get_overlay(i);
22868 + fbdev->num_managers = omap_dss_get_num_overlay_managers();
22869 + for (i = 0; i < fbdev->num_managers; i++)
22870 + fbdev->managers[i] = omap_dss_get_overlay_manager(i);
22873 + /* gfx overlay should be the default one. find a display
22874 + * connected to that, and use it as default display */
22875 + ovl = omap_dss_get_overlay(0);
22876 + if (ovl->manager && ovl->manager->display) {
22877 + def_display = ovl->manager->display;
22878 + } else {
22879 + dev_err(&pdev->dev, "cannot find default display\n");
22880 + r = -EINVAL;
22881 + goto cleanup;
22884 + if (def_mode && strlen(def_mode) > 0) {
22885 + if (omapfb_parse_def_modes(fbdev))
22886 + dev_err(&pdev->dev, "cannot parse default modes\n");
22889 + r = omapfb_create_framebuffers(fbdev);
22890 + if (r)
22891 + goto cleanup;
22893 + for (i = 0; i < fbdev->num_managers; i++) {
22894 + struct omap_overlay_manager *mgr;
22895 + mgr = fbdev->managers[i];
22896 + r = mgr->apply(mgr);
22897 + if (r) {
22898 + dev_err(fbdev->dev, "failed to apply dispc config\n");
22899 + goto cleanup;
22903 + DBG("mgr->apply'ed\n");
22905 + r = def_display->enable(def_display);
22906 + if (r) {
22907 + dev_err(fbdev->dev, "Failed to enable display '%s'\n",
22908 + def_display->name);
22909 + goto cleanup;
22912 + /* set the update mode */
22913 + if (def_display->caps & OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE) {
22914 +#ifdef CONFIG_FB_OMAP2_FORCE_AUTO_UPDATE
22915 + if (def_display->set_update_mode)
22916 + def_display->set_update_mode(def_display,
22917 + OMAP_DSS_UPDATE_AUTO);
22918 + if (def_display->enable_te)
22919 + def_display->enable_te(def_display, 1);
22920 +#else
22921 + if (def_display->set_update_mode)
22922 + def_display->set_update_mode(def_display,
22923 + OMAP_DSS_UPDATE_MANUAL);
22924 + if (def_display->enable_te)
22925 + def_display->enable_te(def_display, 0);
22926 +#endif
22927 + } else {
22928 + if (def_display->set_update_mode)
22929 + def_display->set_update_mode(def_display,
22930 + OMAP_DSS_UPDATE_AUTO);
22933 + for (i = 0; i < fbdev->num_displays; i++) {
22934 + struct omap_display *display = fbdev->displays[i];
22935 + u16 w, h;
22937 + if (!display->get_update_mode || !display->update)
22938 + continue;
22940 + if (display->get_update_mode(display) ==
22941 + OMAP_DSS_UPDATE_MANUAL) {
22943 + display->get_resolution(display, &w, &h);
22944 + display->update(display, 0, 0, w, h);
22948 + DBG("display->updated\n");
22950 + return 0;
22952 +cleanup:
22953 + omapfb_free_resources(fbdev);
22954 +err0:
22955 + dev_err(&pdev->dev, "failed to setup omapfb\n");
22956 + return r;
22959 +static int omapfb_remove(struct platform_device *pdev)
22961 + struct omapfb2_device *fbdev = platform_get_drvdata(pdev);
22963 + /* FIXME: wait till completion of pending events */
22965 + omapfb_remove_sysfs(fbdev);
22967 + omapfb_free_resources(fbdev);
22969 + return 0;
22972 +static struct platform_driver omapfb_driver = {
22973 + .probe = omapfb_probe,
22974 + .remove = omapfb_remove,
22975 + .driver = {
22976 + .name = "omapfb",
22977 + .owner = THIS_MODULE,
22978 + },
22981 +static int __init omapfb_init(void)
22983 + DBG("omapfb_init\n");
22985 + if (platform_driver_register(&omapfb_driver)) {
22986 + printk(KERN_ERR "failed to register omapfb driver\n");
22987 + return -ENODEV;
22990 + return 0;
22993 +static void __exit omapfb_exit(void)
22995 + DBG("omapfb_exit\n");
22996 + platform_driver_unregister(&omapfb_driver);
22999 +module_param_named(mode, def_mode, charp, 0);
23000 +module_param_named(vram, def_vram, charp, 0);
23001 +module_param_named(rotate, def_rotate, int, 0);
23002 +module_param_named(vrfb, def_vrfb, bool, 0);
23003 +module_param_named(mirror, def_mirror, bool, 0);
23005 +/* late_initcall to let panel/ctrl drivers loaded first.
23006 + * I guess better option would be a more dynamic approach,
23007 + * so that omapfb reacts to new panels when they are loaded */
23008 +late_initcall(omapfb_init);
23009 +/*module_init(omapfb_init);*/
23010 +module_exit(omapfb_exit);
23012 +MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@nokia.com>");
23013 +MODULE_DESCRIPTION("OMAP2/3 Framebuffer");
23014 +MODULE_LICENSE("GPL v2");
23015 diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/omap2/omapfb/omapfb-sysfs.c
23016 new file mode 100644
23017 index 0000000..2c88718
23018 --- /dev/null
23019 +++ b/drivers/video/omap2/omapfb/omapfb-sysfs.c
23020 @@ -0,0 +1,371 @@
23022 + * linux/drivers/video/omap2/omapfb-sysfs.c
23024 + * Copyright (C) 2008 Nokia Corporation
23025 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
23027 + * Some code and ideas taken from drivers/video/omap/ driver
23028 + * by Imre Deak.
23030 + * This program is free software; you can redistribute it and/or modify it
23031 + * under the terms of the GNU General Public License version 2 as published by
23032 + * the Free Software Foundation.
23034 + * This program is distributed in the hope that it will be useful, but WITHOUT
23035 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23036 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
23037 + * more details.
23039 + * You should have received a copy of the GNU General Public License along with
23040 + * this program. If not, see <http://www.gnu.org/licenses/>.
23041 + */
23043 +#include <linux/fb.h>
23044 +#include <linux/sysfs.h>
23045 +#include <linux/device.h>
23046 +#include <linux/uaccess.h>
23047 +#include <linux/platform_device.h>
23048 +#include <linux/kernel.h>
23049 +#include <linux/mm.h>
23050 +#include <linux/omapfb.h>
23052 +#include <mach/display.h>
23053 +#include <mach/vrfb.h>
23055 +#include "omapfb.h"
23057 +static ssize_t show_rotate_type(struct device *dev,
23058 + struct device_attribute *attr, char *buf)
23060 + struct fb_info *fbi = dev_get_drvdata(dev);
23061 + struct omapfb_info *ofbi = FB2OFB(fbi);
23063 + return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->rotation_type);
23066 +static ssize_t show_mirror(struct device *dev,
23067 + struct device_attribute *attr, char *buf)
23069 + struct fb_info *fbi = dev_get_drvdata(dev);
23070 + struct omapfb_info *ofbi = FB2OFB(fbi);
23072 + return snprintf(buf, PAGE_SIZE, "%d\n", ofbi->mirror);
23075 +static ssize_t store_mirror(struct device *dev,
23076 + struct device_attribute *attr,
23077 + const char *buf, size_t count)
23079 + struct fb_info *fbi = dev_get_drvdata(dev);
23080 + struct omapfb_info *ofbi = FB2OFB(fbi);
23081 + struct omapfb2_device *fbdev = ofbi->fbdev;
23082 + bool mirror;
23083 + int r;
23084 + struct fb_var_screeninfo new_var;
23086 + mirror = simple_strtoul(buf, NULL, 0);
23088 + if (mirror != 0 && mirror != 1)
23089 + return -EINVAL;
23091 + omapfb_lock(fbdev);
23093 + ofbi->mirror = mirror;
23095 + memcpy(&new_var, &fbi->var, sizeof(new_var));
23096 + r = check_fb_var(fbi, &new_var);
23097 + if (r)
23098 + goto out;
23099 + memcpy(&fbi->var, &new_var, sizeof(fbi->var));
23101 + set_fb_fix(fbi);
23103 + r = omapfb_apply_changes(fbi, 0);
23104 + if (r)
23105 + goto out;
23107 + r = count;
23108 +out:
23109 + omapfb_unlock(fbdev);
23111 + return r;
23114 +static ssize_t show_overlays(struct device *dev,
23115 + struct device_attribute *attr, char *buf)
23117 + struct fb_info *fbi = dev_get_drvdata(dev);
23118 + struct omapfb_info *ofbi = FB2OFB(fbi);
23119 + struct omapfb2_device *fbdev = ofbi->fbdev;
23120 + ssize_t l = 0;
23121 + int t;
23123 + for (t = 0; t < ofbi->num_overlays; t++) {
23124 + struct omap_overlay *ovl = ofbi->overlays[t];
23125 + int ovlnum;
23127 + for (ovlnum = 0; ovlnum < fbdev->num_overlays; ++ovlnum)
23128 + if (ovl == fbdev->overlays[ovlnum])
23129 + break;
23131 + l += snprintf(buf + l, PAGE_SIZE - l, "%s%d",
23132 + t == 0 ? "" : ",", ovlnum);
23135 + l += snprintf(buf + l, PAGE_SIZE - l, "\n");
23137 + return l;
23140 +static struct omapfb_info *get_overlay_fb(struct omapfb2_device *fbdev,
23141 + struct omap_overlay *ovl)
23143 + int i, t;
23145 + for (i = 0; i < fbdev->num_fbs; i++) {
23146 + struct omapfb_info *ofbi = FB2OFB(fbdev->fbs[i]);
23148 + for (t = 0; t < ofbi->num_overlays; t++) {
23149 + if (ofbi->overlays[t] == ovl)
23150 + return ofbi;
23154 + return NULL;
23157 +static ssize_t store_overlays(struct device *dev, struct device_attribute *attr,
23158 + const char *buf, size_t count)
23160 + struct fb_info *fbi = dev_get_drvdata(dev);
23161 + struct omapfb_info *ofbi = FB2OFB(fbi);
23162 + struct omapfb2_device *fbdev = ofbi->fbdev;
23163 + struct omap_overlay *ovls[OMAPFB_MAX_OVL_PER_FB];
23164 + struct omap_overlay *ovl;
23165 + int num_ovls, r, i;
23166 + int len;
23168 + num_ovls = 0;
23170 + len = strlen(buf);
23171 + if (buf[len - 1] == '\n')
23172 + len = len - 1;
23174 + omapfb_lock(fbdev);
23176 + if (len > 0) {
23177 + char *p = (char *)buf;
23178 + int ovlnum;
23180 + while (p < buf + len) {
23181 + int found;
23182 + if (num_ovls == OMAPFB_MAX_OVL_PER_FB) {
23183 + r = -EINVAL;
23184 + goto out;
23187 + ovlnum = simple_strtoul(p, &p, 0);
23188 + if (ovlnum > fbdev->num_overlays) {
23189 + r = -EINVAL;
23190 + goto out;
23193 + found = 0;
23194 + for (i = 0; i < num_ovls; ++i) {
23195 + if (ovls[i] == fbdev->overlays[ovlnum]) {
23196 + found = 1;
23197 + break;
23201 + if (!found)
23202 + ovls[num_ovls++] = fbdev->overlays[ovlnum];
23204 + p++;
23208 + for (i = 0; i < num_ovls; ++i) {
23209 + struct omapfb_info *ofbi2 = get_overlay_fb(fbdev, ovls[i]);
23210 + if (ofbi2 && ofbi2 != ofbi) {
23211 + dev_err(fbdev->dev, "overlay already in use\n");
23212 + r = -EINVAL;
23213 + goto out;
23217 + /* detach unused overlays */
23218 + for (i = 0; i < ofbi->num_overlays; ++i) {
23219 + int t, found;
23221 + ovl = ofbi->overlays[i];
23223 + found = 0;
23225 + for (t = 0; t < num_ovls; ++t) {
23226 + if (ovl == ovls[t]) {
23227 + found = 1;
23228 + break;
23232 + if (found)
23233 + continue;
23235 + DBG("detaching %d\n", ofbi->overlays[i]->id);
23237 + omapfb_overlay_enable(ovl, 0);
23239 + if (ovl->manager)
23240 + ovl->manager->apply(ovl->manager);
23242 + for (t = i + 1; t < ofbi->num_overlays; t++)
23243 + ofbi->overlays[t-1] = ofbi->overlays[t];
23245 + ofbi->num_overlays--;
23246 + i--;
23249 + for (i = 0; i < num_ovls; ++i) {
23250 + int t, found;
23252 + ovl = ovls[i];
23254 + found = 0;
23256 + for (t = 0; t < ofbi->num_overlays; ++t) {
23257 + if (ovl == ofbi->overlays[t]) {
23258 + found = 1;
23259 + break;
23263 + if (found)
23264 + continue;
23266 + ofbi->overlays[ofbi->num_overlays++] = ovl;
23268 + r = omapfb_apply_changes(fbi, 1);
23269 + if (r)
23270 + goto out;
23272 + if (ovl->manager) {
23273 + r = ovl->manager->apply(ovl->manager);
23274 + if (r)
23275 + goto out;
23279 + r = count;
23280 +out:
23281 + omapfb_unlock(fbdev);
23283 + return r;
23286 +static ssize_t show_size(struct device *dev,
23287 + struct device_attribute *attr, char *buf)
23289 + struct fb_info *fbi = dev_get_drvdata(dev);
23290 + struct omapfb_info *ofbi = FB2OFB(fbi);
23292 + return snprintf(buf, PAGE_SIZE, "%lu\n", ofbi->region.size);
23295 +static ssize_t store_size(struct device *dev, struct device_attribute *attr,
23296 + const char *buf, size_t count)
23298 + struct fb_info *fbi = dev_get_drvdata(dev);
23299 + struct omapfb_info *ofbi = FB2OFB(fbi);
23300 + struct omapfb2_device *fbdev = ofbi->fbdev;
23301 + unsigned long size;
23302 + int r;
23303 + int i;
23305 + size = PAGE_ALIGN(simple_strtoul(buf, NULL, 0));
23307 + omapfb_lock(fbdev);
23309 + for (i = 0; i < ofbi->num_overlays; i++) {
23310 + if (ofbi->overlays[i]->info.enabled) {
23311 + r = -EBUSY;
23312 + goto out;
23316 + if (size != ofbi->region.size) {
23317 + r = omapfb_realloc_fbmem(fbi, size, ofbi->region.type);
23318 + if (r) {
23319 + dev_err(dev, "realloc fbmem failed\n");
23320 + goto out;
23324 + r = count;
23325 +out:
23326 + omapfb_unlock(fbdev);
23328 + return r;
23331 +static ssize_t show_phys(struct device *dev,
23332 + struct device_attribute *attr, char *buf)
23334 + struct fb_info *fbi = dev_get_drvdata(dev);
23335 + struct omapfb_info *ofbi = FB2OFB(fbi);
23337 + return snprintf(buf, PAGE_SIZE, "%0x\n", ofbi->region.paddr);
23340 +static ssize_t show_virt(struct device *dev,
23341 + struct device_attribute *attr, char *buf)
23343 + struct fb_info *fbi = dev_get_drvdata(dev);
23344 + struct omapfb_info *ofbi = FB2OFB(fbi);
23346 + return snprintf(buf, PAGE_SIZE, "%p\n", ofbi->region.vaddr);
23349 +static struct device_attribute omapfb_attrs[] = {
23350 + __ATTR(rotate_type, S_IRUGO, show_rotate_type, NULL),
23351 + __ATTR(mirror, S_IRUGO | S_IWUSR, show_mirror, store_mirror),
23352 + __ATTR(size, S_IRUGO | S_IWUSR, show_size, store_size),
23353 + __ATTR(overlays, S_IRUGO | S_IWUSR, show_overlays, store_overlays),
23354 + __ATTR(phys_addr, S_IRUGO, show_phys, NULL),
23355 + __ATTR(virt_addr, S_IRUGO, show_virt, NULL),
23358 +int omapfb_create_sysfs(struct omapfb2_device *fbdev)
23360 + int i;
23361 + int r;
23363 + DBG("create sysfs for fbs\n");
23364 + for (i = 0; i < fbdev->num_fbs; i++) {
23365 + int t;
23366 + for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++) {
23367 + r = device_create_file(fbdev->fbs[i]->dev,
23368 + &omapfb_attrs[t]);
23370 + if (r) {
23371 + dev_err(fbdev->dev, "failed to create sysfs file\n");
23372 + return r;
23377 + return 0;
23380 +void omapfb_remove_sysfs(struct omapfb2_device *fbdev)
23382 + int i, t;
23384 + DBG("remove sysfs for fbs\n");
23385 + for (i = 0; i < fbdev->num_fbs; i++) {
23386 + for (t = 0; t < ARRAY_SIZE(omapfb_attrs); t++)
23387 + device_remove_file(fbdev->fbs[i]->dev,
23388 + &omapfb_attrs[t]);
23392 diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/omap2/omapfb/omapfb.h
23393 new file mode 100644
23394 index 0000000..d130e48
23395 --- /dev/null
23396 +++ b/drivers/video/omap2/omapfb/omapfb.h
23397 @@ -0,0 +1,143 @@
23399 + * linux/drivers/video/omap2/omapfb.h
23401 + * Copyright (C) 2008 Nokia Corporation
23402 + * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
23404 + * Some code and ideas taken from drivers/video/omap/ driver
23405 + * by Imre Deak.
23407 + * This program is free software; you can redistribute it and/or modify it
23408 + * under the terms of the GNU General Public License version 2 as published by
23409 + * the Free Software Foundation.
23411 + * This program is distributed in the hope that it will be useful, but WITHOUT
23412 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
23413 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
23414 + * more details.
23416 + * You should have received a copy of the GNU General Public License along with
23417 + * this program. If not, see <http://www.gnu.org/licenses/>.
23418 + */
23420 +#ifndef __DRIVERS_VIDEO_OMAP2_OMAPFB_H__
23421 +#define __DRIVERS_VIDEO_OMAP2_OMAPFB_H__
23423 +#ifdef CONFIG_FB_OMAP2_DEBUG_SUPPORT
23424 +#define DEBUG
23425 +#endif
23427 +#ifdef DEBUG
23428 +extern unsigned int omapfb_debug;
23429 +#define DBG(format, ...) \
23430 + if (omapfb_debug) \
23431 + printk(KERN_DEBUG "OMAPFB: " format, ## __VA_ARGS__)
23432 +#else
23433 +#define DBG(format, ...)
23434 +#endif
23436 +#define FB2OFB(fb_info) ((struct omapfb_info *)(fb_info->par))
23438 +/* max number of overlays to which a framebuffer data can be direct */
23439 +#define OMAPFB_MAX_OVL_PER_FB 3
23441 +struct omapfb2_mem_region {
23442 + u32 paddr;
23443 + void __iomem *vaddr;
23444 + struct vrfb vrfb;
23445 + unsigned long size;
23446 + u8 type; /* OMAPFB_PLANE_MEM_* */
23447 + bool alloc; /* allocated by the driver */
23448 + bool map; /* kernel mapped by the driver */
23451 +enum omapfb_rotation_type {
23452 + OMAPFB_ROT_DMA = 0,
23453 + OMAPFB_ROT_VRFB = 1,
23456 +/* appended to fb_info */
23457 +struct omapfb_info {
23458 + int id;
23459 + struct omapfb2_mem_region region;
23460 + atomic_t map_count;
23461 + int num_overlays;
23462 + struct omap_overlay *overlays[OMAPFB_MAX_OVL_PER_FB];
23463 + struct omapfb2_device *fbdev;
23464 + enum omapfb_rotation_type rotation_type;
23465 + u8 rotation;
23466 + bool mirror;
23469 +struct omapfb2_device {
23470 + struct device *dev;
23471 + struct mutex mtx;
23473 + u32 pseudo_palette[17];
23475 + int state;
23477 + unsigned num_fbs;
23478 + struct fb_info *fbs[10];
23480 + unsigned num_displays;
23481 + struct omap_display *displays[10];
23482 + unsigned num_overlays;
23483 + struct omap_overlay *overlays[10];
23484 + unsigned num_managers;
23485 + struct omap_overlay_manager *managers[10];
23488 +u32 omapfb_get_region_paddr(struct omapfb_info *ofbi);
23489 +void __iomem *omapfb_get_region_vaddr(struct omapfb_info *ofbi);
23491 +void set_fb_fix(struct fb_info *fbi);
23492 +int check_fb_var(struct fb_info *fbi, struct fb_var_screeninfo *var);
23493 +int omapfb_realloc_fbmem(struct fb_info *fbi, unsigned long size, int type);
23494 +int omapfb_apply_changes(struct fb_info *fbi, int init);
23495 +int omapfb_fb_init(struct omapfb2_device *fbdev, struct fb_info *fbi);
23497 +int omapfb_create_sysfs(struct omapfb2_device *fbdev);
23498 +void omapfb_remove_sysfs(struct omapfb2_device *fbdev);
23500 +int omapfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg);
23502 +int omapfb_mode_to_timings(const char *mode_str,
23503 + struct omap_video_timings *timings, u8 *bpp);
23505 +/* find the display connected to this fb, if any */
23506 +static inline struct omap_display *fb2display(struct fb_info *fbi)
23508 + struct omapfb_info *ofbi = FB2OFB(fbi);
23509 + int i;
23511 + /* XXX: returns the display connected to first attached overlay */
23512 + for (i = 0; i < ofbi->num_overlays; i++) {
23513 + if (ofbi->overlays[i]->manager)
23514 + return ofbi->overlays[i]->manager->display;
23517 + return NULL;
23520 +static inline void omapfb_lock(struct omapfb2_device *fbdev)
23522 + mutex_lock(&fbdev->mtx);
23525 +static inline void omapfb_unlock(struct omapfb2_device *fbdev)
23527 + mutex_unlock(&fbdev->mtx);
23530 +static inline int omapfb_overlay_enable(struct omap_overlay *ovl,
23531 + int enable)
23533 + struct omap_overlay_info info;
23535 + ovl->get_overlay_info(ovl, &info);
23536 + info.enabled = enable;
23537 + return ovl->set_overlay_info(ovl, &info);
23540 +#endif
23541 diff --git a/include/linux/omapfb.h b/include/linux/omapfb.h
23542 new file mode 100644
23543 index 0000000..96190b2
23544 --- /dev/null
23545 +++ b/include/linux/omapfb.h
23546 @@ -0,0 +1,418 @@
23548 + * File: arch/arm/plat-omap/include/mach/omapfb.h
23550 + * Framebuffer driver for TI OMAP boards
23552 + * Copyright (C) 2004 Nokia Corporation
23553 + * Author: Imre Deak <imre.deak@nokia.com>
23555 + * This program is free software; you can redistribute it and/or modify it
23556 + * under the terms of the GNU General Public License as published by the
23557 + * Free Software Foundation; either version 2 of the License, or (at your
23558 + * option) any later version.
23560 + * This program is distributed in the hope that it will be useful, but
23561 + * WITHOUT ANY WARRANTY; without even the implied warranty of
23562 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23563 + * General Public License for more details.
23565 + * You should have received a copy of the GNU General Public License along
23566 + * with this program; if not, write to the Free Software Foundation, Inc.,
23567 + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
23568 + */
23570 +#ifndef __OMAPFB_H
23571 +#define __OMAPFB_H
23573 +#include <asm/ioctl.h>
23574 +#include <asm/types.h>
23576 +/* IOCTL commands. */
23578 +#define OMAP_IOW(num, dtype) _IOW('O', num, dtype)
23579 +#define OMAP_IOR(num, dtype) _IOR('O', num, dtype)
23580 +#define OMAP_IOWR(num, dtype) _IOWR('O', num, dtype)
23581 +#define OMAP_IO(num) _IO('O', num)
23583 +#define OMAPFB_MIRROR OMAP_IOW(31, int)
23584 +#define OMAPFB_SYNC_GFX OMAP_IO(37)
23585 +#define OMAPFB_VSYNC OMAP_IO(38)
23586 +#define OMAPFB_SET_UPDATE_MODE OMAP_IOW(40, int)
23587 +#define OMAPFB_GET_CAPS OMAP_IOR(42, struct omapfb_caps)
23588 +#define OMAPFB_GET_UPDATE_MODE OMAP_IOW(43, int)
23589 +#define OMAPFB_LCD_TEST OMAP_IOW(45, int)
23590 +#define OMAPFB_CTRL_TEST OMAP_IOW(46, int)
23591 +#define OMAPFB_UPDATE_WINDOW_OLD OMAP_IOW(47, struct omapfb_update_window_old)
23592 +#define OMAPFB_SET_COLOR_KEY OMAP_IOW(50, struct omapfb_color_key)
23593 +#define OMAPFB_GET_COLOR_KEY OMAP_IOW(51, struct omapfb_color_key)
23594 +#define OMAPFB_SETUP_PLANE OMAP_IOW(52, struct omapfb_plane_info)
23595 +#define OMAPFB_QUERY_PLANE OMAP_IOW(53, struct omapfb_plane_info)
23596 +#define OMAPFB_UPDATE_WINDOW OMAP_IOW(54, struct omapfb_update_window)
23597 +#define OMAPFB_SETUP_MEM OMAP_IOW(55, struct omapfb_mem_info)
23598 +#define OMAPFB_QUERY_MEM OMAP_IOW(56, struct omapfb_mem_info)
23599 +#define OMAPFB_WAITFORVSYNC OMAP_IO(57)
23600 +#define OMAPFB_MEMORY_READ OMAP_IOR(58, struct omapfb_memory_read)
23602 +#define OMAPFB_CAPS_GENERIC_MASK 0x00000fff
23603 +#define OMAPFB_CAPS_LCDC_MASK 0x00fff000
23604 +#define OMAPFB_CAPS_PANEL_MASK 0xff000000
23606 +#define OMAPFB_CAPS_MANUAL_UPDATE 0x00001000
23607 +#define OMAPFB_CAPS_TEARSYNC 0x00002000
23608 +#define OMAPFB_CAPS_PLANE_RELOCATE_MEM 0x00004000
23609 +#define OMAPFB_CAPS_PLANE_SCALE 0x00008000
23610 +#define OMAPFB_CAPS_WINDOW_PIXEL_DOUBLE 0x00010000
23611 +#define OMAPFB_CAPS_WINDOW_SCALE 0x00020000
23612 +#define OMAPFB_CAPS_WINDOW_OVERLAY 0x00040000
23613 +#define OMAPFB_CAPS_WINDOW_ROTATE 0x00080000
23614 +#define OMAPFB_CAPS_SET_BACKLIGHT 0x01000000
23616 +/* Values from DSP must map to lower 16-bits */
23617 +#define OMAPFB_FORMAT_MASK 0x00ff
23618 +#define OMAPFB_FORMAT_FLAG_DOUBLE 0x0100
23619 +#define OMAPFB_FORMAT_FLAG_TEARSYNC 0x0200
23620 +#define OMAPFB_FORMAT_FLAG_FORCE_VSYNC 0x0400
23621 +#define OMAPFB_FORMAT_FLAG_ENABLE_OVERLAY 0x0800
23622 +#define OMAPFB_FORMAT_FLAG_DISABLE_OVERLAY 0x1000
23624 +#define OMAPFB_EVENT_READY 1
23625 +#define OMAPFB_EVENT_DISABLED 2
23627 +#define OMAPFB_MEMTYPE_SDRAM 0
23628 +#define OMAPFB_MEMTYPE_SRAM 1
23629 +#define OMAPFB_MEMTYPE_MAX 1
23631 +enum omapfb_color_format {
23632 + OMAPFB_COLOR_RGB565 = 0,
23633 + OMAPFB_COLOR_YUV422,
23634 + OMAPFB_COLOR_YUV420,
23635 + OMAPFB_COLOR_CLUT_8BPP,
23636 + OMAPFB_COLOR_CLUT_4BPP,
23637 + OMAPFB_COLOR_CLUT_2BPP,
23638 + OMAPFB_COLOR_CLUT_1BPP,
23639 + OMAPFB_COLOR_RGB444,
23640 + OMAPFB_COLOR_YUY422,
23642 + OMAPFB_COLOR_ARGB16,
23643 + OMAPFB_COLOR_RGB24U, /* RGB24, 32-bit container */
23644 + OMAPFB_COLOR_RGB24P, /* RGB24, 24-bit container */
23645 + OMAPFB_COLOR_ARGB32,
23646 + OMAPFB_COLOR_RGBA32,
23647 + OMAPFB_COLOR_RGBX32,
23650 +struct omapfb_update_window {
23651 + __u32 x, y;
23652 + __u32 width, height;
23653 + __u32 format;
23654 + __u32 out_x, out_y;
23655 + __u32 out_width, out_height;
23656 + __u32 reserved[8];
23659 +struct omapfb_update_window_old {
23660 + __u32 x, y;
23661 + __u32 width, height;
23662 + __u32 format;
23665 +enum omapfb_plane {
23666 + OMAPFB_PLANE_GFX = 0,
23667 + OMAPFB_PLANE_VID1,
23668 + OMAPFB_PLANE_VID2,
23671 +enum omapfb_channel_out {
23672 + OMAPFB_CHANNEL_OUT_LCD = 0,
23673 + OMAPFB_CHANNEL_OUT_DIGIT,
23676 +struct omapfb_plane_info {
23677 + __u32 pos_x;
23678 + __u32 pos_y;
23679 + __u8 enabled;
23680 + __u8 channel_out;
23681 + __u8 mirror;
23682 + __u8 reserved1;
23683 + __u32 out_width;
23684 + __u32 out_height;
23685 + __u32 reserved2[12];
23688 +struct omapfb_mem_info {
23689 + __u32 size;
23690 + __u8 type;
23691 + __u8 reserved[3];
23694 +struct omapfb_caps {
23695 + __u32 ctrl;
23696 + __u32 plane_color;
23697 + __u32 wnd_color;
23700 +enum omapfb_color_key_type {
23701 + OMAPFB_COLOR_KEY_DISABLED = 0,
23702 + OMAPFB_COLOR_KEY_GFX_DST,
23703 + OMAPFB_COLOR_KEY_VID_SRC,
23706 +struct omapfb_color_key {
23707 + __u8 channel_out;
23708 + __u32 background;
23709 + __u32 trans_key;
23710 + __u8 key_type;
23713 +enum omapfb_update_mode {
23714 + OMAPFB_UPDATE_DISABLED = 0,
23715 + OMAPFB_AUTO_UPDATE,
23716 + OMAPFB_MANUAL_UPDATE
23719 +struct omapfb_memory_read {
23720 + __u16 x;
23721 + __u16 y;
23722 + __u16 w;
23723 + __u16 h;
23724 + size_t buffer_size;
23725 + void __user *buffer;
23728 +#ifdef __KERNEL__
23730 +#include <linux/completion.h>
23731 +#include <linux/interrupt.h>
23732 +#include <linux/fb.h>
23733 +#include <linux/mutex.h>
23735 +#include <mach/board.h>
23737 +#define OMAP_LCDC_INV_VSYNC 0x0001
23738 +#define OMAP_LCDC_INV_HSYNC 0x0002
23739 +#define OMAP_LCDC_INV_PIX_CLOCK 0x0004
23740 +#define OMAP_LCDC_INV_OUTPUT_EN 0x0008
23741 +#define OMAP_LCDC_HSVS_RISING_EDGE 0x0010
23742 +#define OMAP_LCDC_HSVS_OPPOSITE 0x0020
23744 +#define OMAP_LCDC_SIGNAL_MASK 0x003f
23746 +#define OMAP_LCDC_PANEL_TFT 0x0100
23748 +#define OMAPFB_PLANE_XRES_MIN 8
23749 +#define OMAPFB_PLANE_YRES_MIN 8
23751 +#ifdef CONFIG_ARCH_OMAP1
23752 +#define OMAPFB_PLANE_NUM 1
23753 +#else
23754 +#define OMAPFB_PLANE_NUM 3
23755 +#endif
23757 +struct omapfb_device;
23759 +struct lcd_panel {
23760 + const char *name;
23761 + int config; /* TFT/STN, signal inversion */
23762 + int bpp; /* Pixel format in fb mem */
23763 + int data_lines; /* Lines on LCD HW interface */
23765 + int x_res, y_res;
23766 + int pixel_clock; /* In kHz */
23767 + int hsw; /* Horizontal synchronization
23768 + pulse width */
23769 + int hfp; /* Horizontal front porch */
23770 + int hbp; /* Horizontal back porch */
23771 + int vsw; /* Vertical synchronization
23772 + pulse width */
23773 + int vfp; /* Vertical front porch */
23774 + int vbp; /* Vertical back porch */
23775 + int acb; /* ac-bias pin frequency */
23776 + int pcd; /* pixel clock divider.
23777 + Obsolete use pixel_clock instead */
23779 + int (*init) (struct lcd_panel *panel,
23780 + struct omapfb_device *fbdev);
23781 + void (*cleanup) (struct lcd_panel *panel);
23782 + int (*enable) (struct lcd_panel *panel);
23783 + void (*disable) (struct lcd_panel *panel);
23784 + unsigned long (*get_caps) (struct lcd_panel *panel);
23785 + int (*set_bklight_level)(struct lcd_panel *panel,
23786 + unsigned int level);
23787 + unsigned int (*get_bklight_level)(struct lcd_panel *panel);
23788 + unsigned int (*get_bklight_max) (struct lcd_panel *panel);
23789 + int (*run_test) (struct lcd_panel *panel, int test_num);
23792 +struct extif_timings {
23793 + int cs_on_time;
23794 + int cs_off_time;
23795 + int we_on_time;
23796 + int we_off_time;
23797 + int re_on_time;
23798 + int re_off_time;
23799 + int we_cycle_time;
23800 + int re_cycle_time;
23801 + int cs_pulse_width;
23802 + int access_time;
23804 + int clk_div;
23806 + u32 tim[5]; /* set by extif->convert_timings */
23808 + int converted;
23811 +struct lcd_ctrl_extif {
23812 + int (*init) (struct omapfb_device *fbdev);
23813 + void (*cleanup) (void);
23814 + void (*get_clk_info) (u32 *clk_period, u32 *max_clk_div);
23815 + unsigned long (*get_max_tx_rate)(void);
23816 + int (*convert_timings) (struct extif_timings *timings);
23817 + void (*set_timings) (const struct extif_timings *timings);
23818 + void (*set_bits_per_cycle)(int bpc);
23819 + void (*write_command) (const void *buf, unsigned int len);
23820 + void (*read_data) (void *buf, unsigned int len);
23821 + void (*write_data) (const void *buf, unsigned int len);
23822 + void (*transfer_area) (int width, int height,
23823 + void (callback)(void * data), void *data);
23824 + int (*setup_tearsync) (unsigned pin_cnt,
23825 + unsigned hs_pulse_time, unsigned vs_pulse_time,
23826 + int hs_pol_inv, int vs_pol_inv, int div);
23827 + int (*enable_tearsync) (int enable, unsigned line);
23829 + unsigned long max_transmit_size;
23832 +struct omapfb_notifier_block {
23833 + struct notifier_block nb;
23834 + void *data;
23835 + int plane_idx;
23838 +typedef int (*omapfb_notifier_callback_t)(struct notifier_block *,
23839 + unsigned long event,
23840 + void *fbi);
23842 +struct omapfb_mem_region {
23843 + u32 paddr;
23844 + void __iomem *vaddr;
23845 + unsigned long size;
23846 + u8 type; /* OMAPFB_PLANE_MEM_* */
23847 + unsigned alloc:1; /* allocated by the driver */
23848 + unsigned map:1; /* kernel mapped by the driver */
23851 +struct omapfb_mem_desc {
23852 + int region_cnt;
23853 + struct omapfb_mem_region region[OMAPFB_PLANE_NUM];
23856 +struct lcd_ctrl {
23857 + const char *name;
23858 + void *data;
23860 + int (*init) (struct omapfb_device *fbdev,
23861 + int ext_mode,
23862 + struct omapfb_mem_desc *req_md);
23863 + void (*cleanup) (void);
23864 + void (*bind_client) (struct omapfb_notifier_block *nb);
23865 + void (*get_caps) (int plane, struct omapfb_caps *caps);
23866 + int (*set_update_mode)(enum omapfb_update_mode mode);
23867 + enum omapfb_update_mode (*get_update_mode)(void);
23868 + int (*setup_plane) (int plane, int channel_out,
23869 + unsigned long offset,
23870 + int screen_width,
23871 + int pos_x, int pos_y, int width,
23872 + int height, int color_mode);
23873 + int (*set_rotate) (int angle);
23874 + int (*setup_mem) (int plane, size_t size,
23875 + int mem_type, unsigned long *paddr);
23876 + int (*mmap) (struct fb_info *info,
23877 + struct vm_area_struct *vma);
23878 + int (*set_scale) (int plane,
23879 + int orig_width, int orig_height,
23880 + int out_width, int out_height);
23881 + int (*enable_plane) (int plane, int enable);
23882 + int (*update_window) (struct fb_info *fbi,
23883 + struct omapfb_update_window *win,
23884 + void (*callback)(void *),
23885 + void *callback_data);
23886 + void (*sync) (void);
23887 + void (*suspend) (void);
23888 + void (*resume) (void);
23889 + int (*run_test) (int test_num);
23890 + int (*setcolreg) (u_int regno, u16 red, u16 green,
23891 + u16 blue, u16 transp,
23892 + int update_hw_mem);
23893 + int (*set_color_key) (struct omapfb_color_key *ck);
23894 + int (*get_color_key) (struct omapfb_color_key *ck);
23897 +enum omapfb_state {
23898 + OMAPFB_DISABLED = 0,
23899 + OMAPFB_SUSPENDED= 99,
23900 + OMAPFB_ACTIVE = 100
23903 +struct omapfb_plane_struct {
23904 + int idx;
23905 + struct omapfb_plane_info info;
23906 + enum omapfb_color_format color_mode;
23907 + struct omapfb_device *fbdev;
23910 +struct omapfb_device {
23911 + int state;
23912 + int ext_lcdc; /* Using external
23913 + LCD controller */
23914 + struct mutex rqueue_mutex;
23916 + int palette_size;
23917 + u32 pseudo_palette[17];
23919 + struct lcd_panel *panel; /* LCD panel */
23920 + const struct lcd_ctrl *ctrl; /* LCD controller */
23921 + const struct lcd_ctrl *int_ctrl; /* internal LCD ctrl */
23922 + struct lcd_ctrl_extif *ext_if; /* LCD ctrl external
23923 + interface */
23924 + struct device *dev;
23925 + struct fb_var_screeninfo new_var; /* for mode changes */
23927 + struct omapfb_mem_desc mem_desc;
23928 + struct fb_info *fb_info[OMAPFB_PLANE_NUM];
23931 +struct omapfb_platform_data {
23932 + struct omap_lcd_config lcd;
23933 + struct omapfb_mem_desc mem_desc;
23934 + void *ctrl_platform_data;
23937 +#ifdef CONFIG_ARCH_OMAP1
23938 +extern struct lcd_ctrl omap1_lcd_ctrl;
23939 +#else
23940 +extern struct lcd_ctrl omap2_disp_ctrl;
23941 +#endif
23943 +extern void omapfb_set_platform_data(struct omapfb_platform_data *data);
23945 +extern void omapfb_reserve_sdram(void);
23946 +extern void omapfb_register_panel(struct lcd_panel *panel);
23947 +extern void omapfb_write_first_pixel(struct omapfb_device *fbdev, u16 pixval);
23948 +extern void omapfb_notify_clients(struct omapfb_device *fbdev,
23949 + unsigned long event);
23950 +extern int omapfb_register_client(struct omapfb_notifier_block *nb,
23951 + omapfb_notifier_callback_t callback,
23952 + void *callback_data);
23953 +extern int omapfb_unregister_client(struct omapfb_notifier_block *nb);
23954 +extern int omapfb_update_window_async(struct fb_info *fbi,
23955 + struct omapfb_update_window *win,
23956 + void (*callback)(void *),
23957 + void *callback_data);
23959 +/* in arch/arm/plat-omap/fb.c */
23960 +extern void omapfb_set_ctrl_platform_data(void *pdata);
23962 +#endif /* __KERNEL__ */
23964 +#endif /* __OMAPFB_H */