|  | OMAP2/3 Display Subsystem | 
|  | ------------------------- | 
|  |  | 
|  | This is an almost total rewrite of the OMAP FB driver in drivers/video/omap | 
|  | (let's call it DSS1). The main differences between DSS1 and DSS2 are DSI, | 
|  | TV-out and multiple display support, but there are lots of small improvements | 
|  | also. | 
|  |  | 
|  | The DSS2 driver (omapdss module) is in arch/arm/plat-omap/dss/, and the FB, | 
|  | panel and controller drivers are in drivers/video/omap2/. DSS1 and DSS2 live | 
|  | currently side by side, you can choose which one to use. | 
|  |  | 
|  | Features | 
|  | -------- | 
|  |  | 
|  | Working and tested features include: | 
|  |  | 
|  | - MIPI DPI (parallel) output | 
|  | - MIPI DSI output in command mode | 
|  | - MIPI DBI (RFBI) output | 
|  | - SDI output | 
|  | - TV output | 
|  | - All pieces can be compiled as a module or inside kernel | 
|  | - Use DISPC to update any of the outputs | 
|  | - Use CPU to update RFBI or DSI output | 
|  | - OMAP DISPC planes | 
|  | - RGB16, RGB24 packed, RGB24 unpacked | 
|  | - YUV2, UYVY | 
|  | - Scaling | 
|  | - Adjusting DSS FCK to find a good pixel clock | 
|  | - Use DSI DPLL to create DSS FCK | 
|  |  | 
|  | Tested boards include: | 
|  | - OMAP3 SDP board | 
|  | - Beagle board | 
|  | - N810 | 
|  |  | 
|  | omapdss driver | 
|  | -------------- | 
|  |  | 
|  | The DSS driver does not itself have any support for Linux framebuffer, V4L or | 
|  | such like the current ones, but it has an internal kernel API that upper level | 
|  | drivers can use. | 
|  |  | 
|  | The DSS driver models OMAP's overlays, overlay managers and displays in a | 
|  | flexible way to enable non-common multi-display configuration. In addition to | 
|  | modelling the hardware overlays, omapdss supports virtual overlays and overlay | 
|  | managers. These can be used when updating a display with CPU or system DMA. | 
|  |  | 
|  | omapdss driver support for audio | 
|  | -------------------------------- | 
|  | There exist several display technologies and standards that support audio as | 
|  | well. Hence, it is relevant to update the DSS device driver to provide an audio | 
|  | interface that may be used by an audio driver or any other driver interested in | 
|  | the functionality. | 
|  |  | 
|  | The audio_enable function is intended to prepare the relevant | 
|  | IP for playback (e.g., enabling an audio FIFO, taking in/out of reset | 
|  | some IP, enabling companion chips, etc). It is intended to be called before | 
|  | audio_start. The audio_disable function performs the reverse operation and is | 
|  | intended to be called after audio_stop. | 
|  |  | 
|  | While a given DSS device driver may support audio, it is possible that for | 
|  | certain configurations audio is not supported (e.g., an HDMI display using a | 
|  | VESA video timing). The audio_supported function is intended to query whether | 
|  | the current configuration of the display supports audio. | 
|  |  | 
|  | The audio_config function is intended to configure all the relevant audio | 
|  | parameters of the display. In order to make the function independent of any | 
|  | specific DSS device driver, a struct omap_dss_audio is defined. Its purpose | 
|  | is to contain all the required parameters for audio configuration. At the | 
|  | moment, such structure contains pointers to IEC-60958 channel status word | 
|  | and CEA-861 audio infoframe structures. This should be enough to support | 
|  | HDMI and DisplayPort, as both are based on CEA-861 and IEC-60958. | 
|  |  | 
|  | The audio_enable/disable, audio_config and audio_supported functions could be | 
|  | implemented as functions that may sleep. Hence, they should not be called | 
|  | while holding a spinlock or a readlock. | 
|  |  | 
|  | The audio_start/audio_stop function is intended to effectively start/stop audio | 
|  | playback after the configuration has taken place. These functions are designed | 
|  | to be used in an atomic context. Hence, audio_start should return quickly and be | 
|  | called only after all the needed resources for audio playback (audio FIFOs, | 
|  | DMA channels, companion chips, etc) have been enabled to begin data transfers. | 
|  | audio_stop is designed to only stop the audio transfers. The resources used | 
|  | for playback are released using audio_disable. | 
|  |  | 
|  | The enum omap_dss_audio_state may be used to help the implementations of | 
|  | the interface to keep track of the audio state. The initial state is _DISABLED; | 
|  | then, the state transitions to _CONFIGURED, and then, when it is ready to | 
|  | play audio, to _ENABLED. The state _PLAYING is used when the audio is being | 
|  | rendered. | 
|  |  | 
|  |  | 
|  | Panel and controller drivers | 
|  | ---------------------------- | 
|  |  | 
|  | The drivers implement panel or controller specific functionality and are not | 
|  | usually visible to users except through omapfb driver.  They register | 
|  | themselves to the DSS driver. | 
|  |  | 
|  | omapfb driver | 
|  | ------------- | 
|  |  | 
|  | The omapfb driver implements arbitrary number of standard linux framebuffers. | 
|  | These framebuffers can be routed flexibly to any overlays, thus allowing very | 
|  | dynamic display architecture. | 
|  |  | 
|  | The driver exports some omapfb specific ioctls, which are compatible with the | 
|  | ioctls in the old driver. | 
|  |  | 
|  | The rest of the non standard features are exported via sysfs. Whether the final | 
|  | implementation will use sysfs, or ioctls, is still open. | 
|  |  | 
|  | V4L2 drivers | 
|  | ------------ | 
|  |  | 
|  | V4L2 is being implemented in TI. | 
|  |  | 
|  | From omapdss point of view the V4L2 drivers should be similar to framebuffer | 
|  | driver. | 
|  |  | 
|  | Architecture | 
|  | -------------------- | 
|  |  | 
|  | Some clarification what the different components do: | 
|  |  | 
|  | - Framebuffer is a memory area inside OMAP's SRAM/SDRAM that contains the | 
|  | pixel data for the image. Framebuffer has width and height and color | 
|  | depth. | 
|  | - Overlay defines where the pixels are read from and where they go on the | 
|  | screen. The overlay may be smaller than framebuffer, thus displaying only | 
|  | part of the framebuffer. The position of the overlay may be changed if | 
|  | the overlay is smaller than the display. | 
|  | - Overlay manager combines the overlays in to one image and feeds them to | 
|  | display. | 
|  | - Display is the actual physical display device. | 
|  |  | 
|  | A framebuffer can be connected to multiple overlays to show the same pixel data | 
|  | on all of the overlays. Note that in this case the overlay input sizes must be | 
|  | the same, but, in case of video overlays, the output size can be different. Any | 
|  | framebuffer can be connected to any overlay. | 
|  |  | 
|  | An overlay can be connected to one overlay manager. Also DISPC overlays can be | 
|  | connected only to DISPC overlay managers, and virtual overlays can be only | 
|  | connected to virtual overlays. | 
|  |  | 
|  | An overlay manager can be connected to one display. There are certain | 
|  | restrictions which kinds of displays an overlay manager can be connected: | 
|  |  | 
|  | - DISPC TV overlay manager can be only connected to TV display. | 
|  | - Virtual overlay managers can only be connected to DBI or DSI displays. | 
|  | - DISPC LCD overlay manager can be connected to all displays, except TV | 
|  | display. | 
|  |  | 
|  | Sysfs | 
|  | ----- | 
|  | The sysfs interface is mainly used for testing. I don't think sysfs | 
|  | interface is the best for this in the final version, but I don't quite know | 
|  | what would be the best interfaces for these things. | 
|  |  | 
|  | The sysfs interface is divided to two parts: DSS and FB. | 
|  |  | 
|  | /sys/class/graphics/fb? directory: | 
|  | mirror		0=off, 1=on | 
|  | rotate		Rotation 0-3 for 0, 90, 180, 270 degrees | 
|  | rotate_type	0 = DMA rotation, 1 = VRFB rotation | 
|  | overlays	List of overlay numbers to which framebuffer pixels go | 
|  | phys_addr	Physical address of the framebuffer | 
|  | virt_addr	Virtual address of the framebuffer | 
|  | size		Size of the framebuffer | 
|  |  | 
|  | /sys/devices/platform/omapdss/overlay? directory: | 
|  | enabled		0=off, 1=on | 
|  | input_size	width,height (ie. the framebuffer size) | 
|  | manager		Destination overlay manager name | 
|  | name | 
|  | output_size	width,height | 
|  | position	x,y | 
|  | screen_width	width | 
|  | global_alpha   	global alpha 0-255 0=transparent 255=opaque | 
|  |  | 
|  | /sys/devices/platform/omapdss/manager? directory: | 
|  | display				Destination display | 
|  | name | 
|  | alpha_blending_enabled		0=off, 1=on | 
|  | trans_key_enabled		0=off, 1=on | 
|  | trans_key_type			gfx-destination, video-source | 
|  | trans_key_value			transparency color key (RGB24) | 
|  | default_color			default background color (RGB24) | 
|  |  | 
|  | /sys/devices/platform/omapdss/display? directory: | 
|  | ctrl_name	Controller name | 
|  | mirror		0=off, 1=on | 
|  | update_mode	0=off, 1=auto, 2=manual | 
|  | enabled		0=off, 1=on | 
|  | name | 
|  | rotate		Rotation 0-3 for 0, 90, 180, 270 degrees | 
|  | timings		Display timings (pixclock,xres/hfp/hbp/hsw,yres/vfp/vbp/vsw) | 
|  | When writing, two special timings are accepted for tv-out: | 
|  | "pal" and "ntsc" | 
|  | panel_name | 
|  | tear_elim	Tearing elimination 0=off, 1=on | 
|  | output_type	Output type (video encoder only): "composite" or "svideo" | 
|  |  | 
|  | There are also some debugfs files at <debugfs>/omapdss/ which show information | 
|  | about clocks and registers. | 
|  |  | 
|  | Examples | 
|  | -------- | 
|  |  | 
|  | The following definitions have been made for the examples below: | 
|  |  | 
|  | ovl0=/sys/devices/platform/omapdss/overlay0 | 
|  | ovl1=/sys/devices/platform/omapdss/overlay1 | 
|  | ovl2=/sys/devices/platform/omapdss/overlay2 | 
|  |  | 
|  | mgr0=/sys/devices/platform/omapdss/manager0 | 
|  | mgr1=/sys/devices/platform/omapdss/manager1 | 
|  |  | 
|  | lcd=/sys/devices/platform/omapdss/display0 | 
|  | dvi=/sys/devices/platform/omapdss/display1 | 
|  | tv=/sys/devices/platform/omapdss/display2 | 
|  |  | 
|  | fb0=/sys/class/graphics/fb0 | 
|  | fb1=/sys/class/graphics/fb1 | 
|  | fb2=/sys/class/graphics/fb2 | 
|  |  | 
|  | Default setup on OMAP3 SDP | 
|  | -------------------------- | 
|  |  | 
|  | Here's the default setup on OMAP3 SDP board. All planes go to LCD. DVI | 
|  | and TV-out are not in use. The columns from left to right are: | 
|  | framebuffers, overlays, overlay managers, displays. Framebuffers are | 
|  | handled by omapfb, and the rest by the DSS. | 
|  |  | 
|  | FB0 --- GFX  -\            DVI | 
|  | FB1 --- VID1 --+- LCD ---- LCD | 
|  | FB2 --- VID2 -/   TV ----- TV | 
|  |  | 
|  | Example: Switch from LCD to DVI | 
|  | ---------------------- | 
|  |  | 
|  | w=`cat $dvi/timings | cut -d "," -f 2 | cut -d "/" -f 1` | 
|  | h=`cat $dvi/timings | cut -d "," -f 3 | cut -d "/" -f 1` | 
|  |  | 
|  | echo "0" > $lcd/enabled | 
|  | echo "" > $mgr0/display | 
|  | fbset -fb /dev/fb0 -xres $w -yres $h -vxres $w -vyres $h | 
|  | # at this point you have to switch the dvi/lcd dip-switch from the omap board | 
|  | echo "dvi" > $mgr0/display | 
|  | echo "1" > $dvi/enabled | 
|  |  | 
|  | After this the configuration looks like: | 
|  |  | 
|  | FB0 --- GFX  -\         -- DVI | 
|  | FB1 --- VID1 --+- LCD -/   LCD | 
|  | FB2 --- VID2 -/   TV ----- TV | 
|  |  | 
|  | Example: Clone GFX overlay to LCD and TV | 
|  | ------------------------------- | 
|  |  | 
|  | w=`cat $tv/timings | cut -d "," -f 2 | cut -d "/" -f 1` | 
|  | h=`cat $tv/timings | cut -d "," -f 3 | cut -d "/" -f 1` | 
|  |  | 
|  | echo "0" > $ovl0/enabled | 
|  | echo "0" > $ovl1/enabled | 
|  |  | 
|  | echo "" > $fb1/overlays | 
|  | echo "0,1" > $fb0/overlays | 
|  |  | 
|  | echo "$w,$h" > $ovl1/output_size | 
|  | echo "tv" > $ovl1/manager | 
|  |  | 
|  | echo "1" > $ovl0/enabled | 
|  | echo "1" > $ovl1/enabled | 
|  |  | 
|  | echo "1" > $tv/enabled | 
|  |  | 
|  | After this the configuration looks like (only relevant parts shown): | 
|  |  | 
|  | FB0 +-- GFX  ---- LCD ---- LCD | 
|  | \- VID1 ---- TV  ---- TV | 
|  |  | 
|  | Misc notes | 
|  | ---------- | 
|  |  | 
|  | OMAP FB allocates the framebuffer memory using the standard dma allocator. You | 
|  | can enable Contiguous Memory Allocator (CONFIG_CMA) to improve the dma | 
|  | allocator, and if CMA is enabled, you use "cma=" kernel parameter to increase | 
|  | the global memory area for CMA. | 
|  |  | 
|  | Using DSI DPLL to generate pixel clock it is possible produce the pixel clock | 
|  | of 86.5MHz (max possible), and with that you get 1280x1024@57 output from DVI. | 
|  |  | 
|  | Rotation and mirroring currently only supports RGB565 and RGB8888 modes. VRFB | 
|  | does not support mirroring. | 
|  |  | 
|  | VRFB rotation requires much more memory than non-rotated framebuffer, so you | 
|  | probably need to increase your vram setting before using VRFB rotation. Also, | 
|  | many applications may not work with VRFB if they do not pay attention to all | 
|  | framebuffer parameters. | 
|  |  | 
|  | Kernel boot arguments | 
|  | --------------------- | 
|  |  | 
|  | omapfb.mode=<display>:<mode>[,...] | 
|  | - Default video mode for specified displays. For example, | 
|  | "dvi:800x400MR-24@60".  See drivers/video/modedb.c. | 
|  | There are also two special modes: "pal" and "ntsc" that | 
|  | can be used to tv out. | 
|  |  | 
|  | omapfb.vram=<fbnum>:<size>[@<physaddr>][,...] | 
|  | - VRAM allocated for a framebuffer. Normally omapfb allocates vram | 
|  | depending on the display size. With this you can manually allocate | 
|  | more or define the physical address of each framebuffer. For example, | 
|  | "1:4M" to allocate 4M for fb1. | 
|  |  | 
|  | omapfb.debug=<y|n> | 
|  | - Enable debug printing. You have to have OMAPFB debug support enabled | 
|  | in kernel config. | 
|  |  | 
|  | omapfb.test=<y|n> | 
|  | - Draw test pattern to framebuffer whenever framebuffer settings change. | 
|  | You need to have OMAPFB debug support enabled in kernel config. | 
|  |  | 
|  | omapfb.vrfb=<y|n> | 
|  | - Use VRFB rotation for all framebuffers. | 
|  |  | 
|  | omapfb.rotate=<angle> | 
|  | - Default rotation applied to all framebuffers. | 
|  | 0 - 0 degree rotation | 
|  | 1 - 90 degree rotation | 
|  | 2 - 180 degree rotation | 
|  | 3 - 270 degree rotation | 
|  |  | 
|  | omapfb.mirror=<y|n> | 
|  | - Default mirror for all framebuffers. Only works with DMA rotation. | 
|  |  | 
|  | omapdss.def_disp=<display> | 
|  | - Name of default display, to which all overlays will be connected. | 
|  | Common examples are "lcd" or "tv". | 
|  |  | 
|  | omapdss.debug=<y|n> | 
|  | - Enable debug printing. You have to have DSS debug support enabled in | 
|  | kernel config. | 
|  |  | 
|  | TODO | 
|  | ---- | 
|  |  | 
|  | DSS locking | 
|  |  | 
|  | Error checking | 
|  | - Lots of checks are missing or implemented just as BUG() | 
|  |  | 
|  | System DMA update for DSI | 
|  | - Can be used for RGB16 and RGB24P modes. Probably not for RGB24U (how | 
|  | to skip the empty byte?) | 
|  |  | 
|  | OMAP1 support | 
|  | - Not sure if needed | 
|  |  |