fbdev changes for 3.17
* Much better HDMI infoframe support for OMAP * Cirrus Logic CLPS711X framebuffer driver * DT support for PL11x CLCD driver * Various small fixes -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJT5LUrAAoJEPo9qoy8lh71G2kP/RyomOV8mOPErkVgslJukMlW iJO/Y47GcnHzosKK+7u8MUXlpbBdZjyoaKJxuh+D1OL0vc/LrSar4IwicqqGcD2C l5N8b9NytOf+sjtYuD24xkGo9bLr8vkaVNC3cgPNjE/x1kgRrtHoap1NOlv8vvuT OnbSkRdg/oENrdzwWjwJeayvT5a3TxLJY5JM9IMTzw6CKROIYScEmHUsy0jH2h/g 60OrGPdzmPPutUKA/ZWe8Nu0Mhf4GcOeIl8CZ/u7ZyME7NKezyF0iATpMzn3+ylf 9GafGbsxwgNW2KwoF379w6CV49UNyQhx4qxlkg8/N2km6ot6s1WoJrb/32qPu05J Wydfbovxo9elM/144m47a89TR4xV6Ia35kbSDmwrR7gmKjIDUE34Ruc7RdCLdO8n SxIG5724pktKlP1bdOT6gCLFnDq6vFK0gNnWwlCRKWnwg0H+Cyg5S07BNEF7/dvO gOkRPuyWz3m4rlpl9dL+TW+jaQR/FQAAgf8pUdjBeUTogUTvWf2NBb3H1bKoAnaE 4fhLwE1qUxep3rhOqOpLbGzDmpvt0ebcNJzseypaSTO9c8QNbZJkxLLC1jchUjPj 6FP4/SocuySik3on6Qulj6xGrp4zskBnjsTXOIZzxXjByX6uf/DNWPHEcEM9zIEk u0trGuXxlx8JkRkV/7aE =gXX+ -----END PGP SIGNATURE----- Merge tag 'fbdev-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux Pull fbdev updates from Tomi Valkeinen: - much better HDMI infoframe support for OMAP - Cirrus Logic CLPS711X framebuffer driver - DT support for PL11x CLCD driver - various small fixes * tag 'fbdev-3.17' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (35 commits) OMAPDSS: DSI: fix depopulating dsi peripherals video: hyperv: hyperv_fb: refresh the VM screen by force on VM panic video: ARM CLCD: Fix DT-related build problems drivers: video: fbdev: atmel_lcdfb.c: Add ability to inverted backlight PWM. video: ARM CLCD: Add DT support drm/omap: Add infoframe & dvi/hdmi mode support OMAPDSS: HDMI: remove the unused code OMAPDSS: HDMI5: add support to set infoframe & HDMI mode OMAPDSS: HDMI4: add support to set infoframe & HDMI mode OMAPDSS: HDMI: add infoframe and hdmi_dvi_mode fields OMAPDSS: add hdmi ops to hdmi-connector and tpd12s015 OMAPDSS: add hdmi ops to hdmi_ops and omap_dss_driver OMAPDSS: HDMI: remove custom avi infoframe OMAPDSS: HDMI5: use common AVI infoframe support OMAPDSS: HDMI4: use common AVI infoframe support OMAPDSS: Kconfig: select HDMI OMAPDSS: HDMI: fix name conflict OMAPDSS: DISPC: clean up dispc_mgr_timings_ok OMAPDSS: DISPC: reject interlace for lcd out OMAPDSS: DISPC: fix debugfs reg dump ...
This commit is contained in:
commit
9e9ac89666
109
Documentation/devicetree/bindings/video/arm,pl11x.txt
Normal file
109
Documentation/devicetree/bindings/video/arm,pl11x.txt
Normal file
@ -0,0 +1,109 @@
|
||||
* ARM PrimeCell Color LCD Controller PL110/PL111
|
||||
|
||||
See also Documentation/devicetree/bindings/arm/primecell.txt
|
||||
|
||||
Required properties:
|
||||
|
||||
- compatible: must be one of:
|
||||
"arm,pl110", "arm,primecell"
|
||||
"arm,pl111", "arm,primecell"
|
||||
|
||||
- reg: base address and size of the control registers block
|
||||
|
||||
- interrupt-names: either the single entry "combined" representing a
|
||||
combined interrupt output (CLCDINTR), or the four entries
|
||||
"mbe", "vcomp", "lnbu", "fuf" representing the individual
|
||||
CLCDMBEINTR, CLCDVCOMPINTR, CLCDLNBUINTR, CLCDFUFINTR interrupts
|
||||
|
||||
- interrupts: contains an interrupt specifier for each entry in
|
||||
interrupt-names
|
||||
|
||||
- clock-names: should contain "clcdclk" and "apb_pclk"
|
||||
|
||||
- clocks: contains phandle and clock specifier pairs for the entries
|
||||
in the clock-names property. See
|
||||
Documentation/devicetree/binding/clock/clock-bindings.txt
|
||||
|
||||
Optional properties:
|
||||
|
||||
- memory-region: phandle to a node describing memory (see
|
||||
Documentation/devicetree/bindings/reserved-memory/reserved-memory.txt)
|
||||
to be used for the framebuffer; if not present, the framebuffer
|
||||
may be located anywhere in the memory
|
||||
|
||||
- max-memory-bandwidth: maximum bandwidth in bytes per second that the
|
||||
cell's memory interface can handle; if not present, the memory
|
||||
interface is fast enough to handle all possible video modes
|
||||
|
||||
Required sub-nodes:
|
||||
|
||||
- port: describes LCD panel signals, following the common binding
|
||||
for video transmitter interfaces; see
|
||||
Documentation/devicetree/bindings/media/video-interfaces.txt;
|
||||
when it is a TFT panel, the port's endpoint must define the
|
||||
following property:
|
||||
|
||||
- arm,pl11x,tft-r0g0b0-pads: an array of three 32-bit values,
|
||||
defining the way CLD pads are wired up; first value
|
||||
contains index of the "CLD" external pin (pad) used
|
||||
as R0 (first bit of the red component), second value
|
||||
index of the pad used as G0, third value index of the
|
||||
pad used as B0, see also "LCD panel signal multiplexing
|
||||
details" paragraphs in the PL110/PL111 Technical
|
||||
Reference Manuals; this implicitly defines available
|
||||
color modes, for example:
|
||||
- PL111 TFT 4:4:4 panel:
|
||||
arm,pl11x,tft-r0g0b0-pads = <4 15 20>;
|
||||
- PL110 TFT (1:)5:5:5 panel:
|
||||
arm,pl11x,tft-r0g0b0-pads = <1 7 13>;
|
||||
- PL111 TFT (1:)5:5:5 panel:
|
||||
arm,pl11x,tft-r0g0b0-pads = <3 11 19>;
|
||||
- PL111 TFT 5:6:5 panel:
|
||||
arm,pl11x,tft-r0g0b0-pads = <3 10 19>;
|
||||
- PL110 and PL111 TFT 8:8:8 panel:
|
||||
arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
|
||||
- PL110 and PL111 TFT 8:8:8 panel, R & B components swapped:
|
||||
arm,pl11x,tft-r0g0b0-pads = <16 8 0>;
|
||||
|
||||
|
||||
Example:
|
||||
|
||||
clcd@10020000 {
|
||||
compatible = "arm,pl111", "arm,primecell";
|
||||
reg = <0x10020000 0x1000>;
|
||||
interrupt-names = "combined";
|
||||
interrupts = <0 44 4>;
|
||||
clocks = <&oscclk1>, <&oscclk2>;
|
||||
clock-names = "clcdclk", "apb_pclk";
|
||||
max-memory-bandwidth = <94371840>; /* Bps, 1024x768@60 16bpp */
|
||||
|
||||
port {
|
||||
clcd_pads: endpoint {
|
||||
remote-endpoint = <&clcd_panel>;
|
||||
arm,pl11x,tft-r0g0b0-pads = <0 8 16>;
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
panel {
|
||||
compatible = "panel-dpi";
|
||||
|
||||
port {
|
||||
clcd_panel: endpoint {
|
||||
remote-endpoint = <&clcd_pads>;
|
||||
};
|
||||
};
|
||||
|
||||
panel-timing {
|
||||
clock-frequency = <25175000>;
|
||||
hactive = <640>;
|
||||
hback-porch = <40>;
|
||||
hfront-porch = <24>;
|
||||
hsync-len = <96>;
|
||||
vactive = <480>;
|
||||
vback-porch = <32>;
|
||||
vfront-porch = <11>;
|
||||
vsync-len = <2>;
|
||||
};
|
||||
};
|
@ -46,6 +46,7 @@ Required properties (as per of_videomode_helper):
|
||||
|
||||
Optional properties (as per of_videomode_helper):
|
||||
- atmel,lcdcon-backlight: enable backlight
|
||||
- atmel,lcdcon-backlight-inverted: invert backlight PWM polarity
|
||||
- atmel,lcd-wiring-mode: lcd wiring mode "RGB" or "BRG"
|
||||
- atmel,power-control-gpio: gpio to power on or off the LCD (as many as needed)
|
||||
|
||||
|
@ -0,0 +1,47 @@
|
||||
* Currus Logic CLPS711X Framebuffer
|
||||
|
||||
Required properties:
|
||||
- compatible: Shall contain "cirrus,clps711x-fb".
|
||||
- reg : Physical base address and length of the controller's registers +
|
||||
location and size of the framebuffer memory.
|
||||
- clocks : phandle + clock specifier pair of the FB reference clock.
|
||||
- display : phandle to a display node as described in
|
||||
Documentation/devicetree/bindings/video/display-timing.txt.
|
||||
Additionally, the display node has to define properties:
|
||||
- bits-per-pixel: Bits per pixel.
|
||||
- ac-prescale : LCD AC bias frequency. This frequency is the required
|
||||
AC bias frequency for a given manufacturer's LCD plate.
|
||||
- cmap-invert : Invert the color levels (Optional).
|
||||
|
||||
Optional properties:
|
||||
- lcd-supply: Regulator for LCD supply voltage.
|
||||
|
||||
Example:
|
||||
fb: fb@800002c0 {
|
||||
compatible = "cirrus,ep7312-fb", "cirrus,clps711x-fb";
|
||||
reg = <0x800002c0 0xd44>, <0x60000000 0xc000>;
|
||||
clocks = <&clks 2>;
|
||||
lcd-supply = <®5v0>;
|
||||
display = <&display>;
|
||||
};
|
||||
|
||||
display: display {
|
||||
model = "320x240x4";
|
||||
native-mode = <&timing0>;
|
||||
bits-per-pixel = <4>;
|
||||
ac-prescale = <17>;
|
||||
|
||||
display-timings {
|
||||
timing0: 320x240 {
|
||||
hactive = <320>;
|
||||
hback-porch = <0>;
|
||||
hfront-porch = <0>;
|
||||
hsync-len = <0>;
|
||||
vactive = <240>;
|
||||
vback-porch = <0>;
|
||||
vfront-porch = <0>;
|
||||
vsync-len = <0>;
|
||||
clock-frequency = <6500000>;
|
||||
};
|
||||
};
|
||||
};
|
74
MAINTAINERS
74
MAINTAINERS
@ -606,7 +606,7 @@ W: http://www.amd.com/us-en/ConnectivitySolutions/TechnicalResources/0,,50_2334_
|
||||
S: Supported
|
||||
F: drivers/char/hw_random/geode-rng.c
|
||||
F: drivers/crypto/geode*
|
||||
F: drivers/video/geode/
|
||||
F: drivers/video/fbdev/geode/
|
||||
F: arch/x86/include/asm/geode.h
|
||||
|
||||
AMD IOMMU (AMD-VI)
|
||||
@ -735,8 +735,8 @@ F: drivers/ata/pata_arasan_cf.c
|
||||
ARC FRAMEBUFFER DRIVER
|
||||
M: Jaya Kumar <jayalk@intworks.biz>
|
||||
S: Maintained
|
||||
F: drivers/video/arcfb.c
|
||||
F: drivers/video/fb_defio.c
|
||||
F: drivers/video/fbdev/arcfb.c
|
||||
F: drivers/video/fbdev/core/fb_defio.c
|
||||
|
||||
ARM MFM AND FLOPPY DRIVERS
|
||||
M: Ian Molton <spyro@f2s.com>
|
||||
@ -775,7 +775,7 @@ F: sound/arm/aaci.*
|
||||
ARM PRIMECELL CLCD PL110 DRIVER
|
||||
M: Russell King <linux@arm.linux.org.uk>
|
||||
S: Maintained
|
||||
F: drivers/video/amba-clcd.*
|
||||
F: drivers/video/fbdev/amba-clcd.*
|
||||
|
||||
ARM PRIMECELL KMI PL050 DRIVER
|
||||
M: Russell King <linux@arm.linux.org.uk>
|
||||
@ -1180,7 +1180,7 @@ M: Daniel Walker <dwalker@fifo99.com>
|
||||
M: Bryan Huntsman <bryanh@codeaurora.org>
|
||||
L: linux-arm-msm@vger.kernel.org
|
||||
F: arch/arm/mach-msm/
|
||||
F: drivers/video/msm/
|
||||
F: drivers/video/fbdev/msm/
|
||||
F: drivers/mmc/host/msm_sdcc.c
|
||||
F: drivers/mmc/host/msm_sdcc.h
|
||||
F: drivers/tty/serial/msm_serial.h
|
||||
@ -1414,7 +1414,7 @@ F: drivers/mtd/nand/nuc900_nand.c
|
||||
F: drivers/rtc/rtc-nuc900.c
|
||||
F: drivers/spi/spi-nuc900.c
|
||||
F: drivers/usb/host/ehci-w90x900.c
|
||||
F: drivers/video/nuc900fb.c
|
||||
F: drivers/video/fbdev/nuc900fb.c
|
||||
|
||||
ARM/U300 MACHINE SUPPORT
|
||||
M: Linus Walleij <linus.walleij@linaro.org>
|
||||
@ -1484,9 +1484,9 @@ F: drivers/rtc/rtc-vt8500.c
|
||||
F: drivers/tty/serial/vt8500_serial.c
|
||||
F: drivers/usb/host/ehci-platform.c
|
||||
F: drivers/usb/host/uhci-platform.c
|
||||
F: drivers/video/vt8500lcdfb.*
|
||||
F: drivers/video/wm8505fb*
|
||||
F: drivers/video/wmt_ge_rops.*
|
||||
F: drivers/video/fbdev/vt8500lcdfb.*
|
||||
F: drivers/video/fbdev/wm8505fb*
|
||||
F: drivers/video/fbdev/wmt_ge_rops.*
|
||||
|
||||
ARM/ZIPIT Z2 SUPPORT
|
||||
M: Marek Vasut <marek.vasut@gmail.com>
|
||||
@ -1676,7 +1676,7 @@ ATMEL LCDFB DRIVER
|
||||
M: Nicolas Ferre <nicolas.ferre@atmel.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/atmel_lcdfb.c
|
||||
F: drivers/video/fbdev/atmel_lcdfb.c
|
||||
F: include/video/atmel_lcdc.h
|
||||
|
||||
ATMEL MACB ETHERNET DRIVER
|
||||
@ -2703,7 +2703,7 @@ M: Russell King <linux@arm.linux.org.uk>
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
W: http://www.arm.linux.org.uk/
|
||||
S: Maintained
|
||||
F: drivers/video/cyber2000fb.*
|
||||
F: drivers/video/fbdev/cyber2000fb.*
|
||||
|
||||
CYCLADES ASYNC MUX DRIVER
|
||||
W: http://www.cyclades.com/
|
||||
@ -2941,7 +2941,7 @@ M: Bernie Thompson <bernie@plugable.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
W: http://plugable.com/category/projects/udlfb/
|
||||
F: drivers/video/udlfb.c
|
||||
F: drivers/video/fbdev/udlfb.c
|
||||
F: include/video/udlfb.h
|
||||
F: Documentation/fb/udlfb.txt
|
||||
|
||||
@ -3452,7 +3452,7 @@ EFIFB FRAMEBUFFER DRIVER
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
M: Peter Jones <pjones@redhat.com>
|
||||
S: Maintained
|
||||
F: drivers/video/efifb.c
|
||||
F: drivers/video/fbdev/efifb.c
|
||||
|
||||
EFS FILESYSTEM
|
||||
W: http://aeschi.ch.eu.org/efs/
|
||||
@ -3517,7 +3517,7 @@ EPSON S1D13XXX FRAMEBUFFER DRIVER
|
||||
M: Kristoffer Ericson <kristoffer.ericson@gmail.com>
|
||||
S: Maintained
|
||||
T: git git://git.kernel.org/pub/scm/linux/kernel/git/kristoffer/linux-hpc.git
|
||||
F: drivers/video/s1d13xxxfb.c
|
||||
F: drivers/video/fbdev/s1d13xxxfb.c
|
||||
F: include/video/s1d13xxxfb.h
|
||||
|
||||
ETHERNET BRIDGE
|
||||
@ -3595,7 +3595,7 @@ M: Donghwa Lee <dh09.lee@samsung.com>
|
||||
M: Kyungmin Park <kyungmin.park@samsung.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/exynos/exynos_mipi*
|
||||
F: drivers/video/fbdev/exynos/exynos_mipi*
|
||||
F: include/video/exynos_mipi*
|
||||
|
||||
F71805F HARDWARE MONITORING DRIVER
|
||||
@ -3774,7 +3774,7 @@ FREESCALE DIU FRAMEBUFFER DRIVER
|
||||
M: Timur Tabi <timur@tabi.org>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/fsl-diu-fb.*
|
||||
F: drivers/video/fbdev/fsl-diu-fb.*
|
||||
|
||||
FREESCALE DMA DRIVER
|
||||
M: Li Yang <leoli@freescale.com>
|
||||
@ -3796,7 +3796,7 @@ L: linux-fbdev@vger.kernel.org
|
||||
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
|
||||
S: Maintained
|
||||
F: include/linux/platform_data/video-imxfb.h
|
||||
F: drivers/video/imxfb.c
|
||||
F: drivers/video/fbdev/imxfb.c
|
||||
|
||||
FREESCALE SOC FS_ENET DRIVER
|
||||
M: Pantelis Antoniou <pantelis.antoniou@gmail.com>
|
||||
@ -4222,7 +4222,7 @@ M: Ferenc Bakonyi <fero@drama.obuda.kando.hu>
|
||||
L: linux-nvidia@lists.surfsouth.com
|
||||
W: http://drama.obuda.kando.hu/~fero/cgi-bin/hgafb.shtml
|
||||
S: Maintained
|
||||
F: drivers/video/hgafb.c
|
||||
F: drivers/video/fbdev/hgafb.c
|
||||
|
||||
HIBERNATION (aka Software Suspend, aka swsusp)
|
||||
M: "Rafael J. Wysocki" <rjw@rjwysocki.net>
|
||||
@ -4364,7 +4364,7 @@ F: drivers/hv/
|
||||
F: drivers/input/serio/hyperv-keyboard.c
|
||||
F: drivers/net/hyperv/
|
||||
F: drivers/scsi/storvsc_drv.c
|
||||
F: drivers/video/hyperv_fb.c
|
||||
F: drivers/video/fbdev/hyperv_fb.c
|
||||
F: include/linux/hyperv.h
|
||||
F: tools/hv/
|
||||
|
||||
@ -4620,7 +4620,7 @@ F: security/integrity/ima/
|
||||
IMS TWINTURBO FRAMEBUFFER DRIVER
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Orphan
|
||||
F: drivers/video/imsttfb.c
|
||||
F: drivers/video/fbdev/imsttfb.c
|
||||
|
||||
INFINIBAND SUBSYSTEM
|
||||
M: Roland Dreier <roland@kernel.org>
|
||||
@ -4687,13 +4687,13 @@ M: Maik Broemme <mbroemme@plusserver.de>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: Documentation/fb/intelfb.txt
|
||||
F: drivers/video/intelfb/
|
||||
F: drivers/video/fbdev/intelfb/
|
||||
|
||||
INTEL 810/815 FRAMEBUFFER DRIVER
|
||||
M: Antonino Daplas <adaplas@gmail.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/i810/
|
||||
F: drivers/video/fbdev/i810/
|
||||
|
||||
INTEL MENLOW THERMAL DRIVER
|
||||
M: Sujith Thomas <sujith.thomas@intel.com>
|
||||
@ -5758,7 +5758,7 @@ F: drivers/mmc/host/mvsdio.*
|
||||
MATROX FRAMEBUFFER DRIVER
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Orphan
|
||||
F: drivers/video/matrox/matroxfb_*
|
||||
F: drivers/video/fbdev/matrox/matroxfb_*
|
||||
F: include/uapi/linux/matroxfb.h
|
||||
|
||||
MAX16065 HARDWARE MONITOR DRIVER
|
||||
@ -6398,8 +6398,8 @@ NVIDIA (rivafb and nvidiafb) FRAMEBUFFER DRIVER
|
||||
M: Antonino Daplas <adaplas@gmail.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/riva/
|
||||
F: drivers/video/nvidia/
|
||||
F: drivers/video/fbdev/riva/
|
||||
F: drivers/video/fbdev/nvidia/
|
||||
|
||||
NVM EXPRESS DRIVER
|
||||
M: Matthew Wilcox <willy@linux.intel.com>
|
||||
@ -6469,14 +6469,14 @@ M: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
L: linux-omap@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/omap/
|
||||
F: drivers/video/fbdev/omap/
|
||||
|
||||
OMAP DISPLAY SUBSYSTEM and FRAMEBUFFER SUPPORT (DSS2)
|
||||
M: Tomi Valkeinen <tomi.valkeinen@ti.com>
|
||||
L: linux-omap@vger.kernel.org
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/omap2/
|
||||
F: drivers/video/fbdev/omap2/
|
||||
F: Documentation/arm/OMAP/DSS
|
||||
|
||||
OMAP HARDWARE SPINLOCK SUPPORT
|
||||
@ -6768,7 +6768,7 @@ F: drivers/char/agp/parisc-agp.c
|
||||
F: drivers/input/serio/gscps2.c
|
||||
F: drivers/parport/parport_gsc.*
|
||||
F: drivers/tty/serial/8250/8250_gsc.c
|
||||
F: drivers/video/sti*
|
||||
F: drivers/video/fbdev/sti*
|
||||
F: drivers/video/console/sti*
|
||||
F: drivers/video/logo/logo_parisc*
|
||||
|
||||
@ -7027,7 +7027,7 @@ S: Maintained
|
||||
T: git git://github.com/gxt/linux.git
|
||||
F: drivers/input/serio/i8042-unicore32io.h
|
||||
F: drivers/i2c/busses/i2c-puv3.c
|
||||
F: drivers/video/fb-puv3.c
|
||||
F: drivers/video/fbdev/fb-puv3.c
|
||||
F: drivers/rtc/rtc-puv3.c
|
||||
|
||||
PMBUS HARDWARE MONITORING DRIVERS
|
||||
@ -7407,7 +7407,7 @@ RADEON FRAMEBUFFER DISPLAY DRIVER
|
||||
M: Benjamin Herrenschmidt <benh@kernel.crashing.org>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/aty/radeon*
|
||||
F: drivers/video/fbdev/aty/radeon*
|
||||
F: include/uapi/linux/radeonfb.h
|
||||
|
||||
RADIOSHARK RADIO DRIVER
|
||||
@ -7429,7 +7429,7 @@ RAGE128 FRAMEBUFFER DISPLAY DRIVER
|
||||
M: Paul Mackerras <paulus@samba.org>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/aty/aty128fb.c
|
||||
F: drivers/video/fbdev/aty/aty128fb.c
|
||||
|
||||
RALINK RT2X00 WIRELESS LAN DRIVER
|
||||
P: rt2x00 project
|
||||
@ -7677,7 +7677,7 @@ S3 SAVAGE FRAMEBUFFER DRIVER
|
||||
M: Antonino Daplas <adaplas@gmail.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/savage/
|
||||
F: drivers/video/fbdev/savage/
|
||||
|
||||
S390
|
||||
M: Martin Schwidefsky <schwidefsky@de.ibm.com>
|
||||
@ -7800,7 +7800,7 @@ SAMSUNG FRAMEBUFFER DRIVER
|
||||
M: Jingoo Han <jg1.han@samsung.com>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/s3c-fb.c
|
||||
F: drivers/video/fbdev/s3c-fb.c
|
||||
|
||||
SAMSUNG MULTIFUNCTION DEVICE DRIVERS
|
||||
M: Sangbeom Kim <sbkim73@samsung.com>
|
||||
@ -8297,7 +8297,7 @@ M: Thomas Winischhofer <thomas@winischhofer.net>
|
||||
W: http://www.winischhofer.net/linuxsisvga.shtml
|
||||
S: Maintained
|
||||
F: Documentation/fb/sisfb.txt
|
||||
F: drivers/video/sis/
|
||||
F: drivers/video/fbdev/sis/
|
||||
F: include/video/sisfb.h
|
||||
|
||||
SIS USB2VGA DRIVER
|
||||
@ -8406,7 +8406,7 @@ SMSC UFX6000 and UFX7000 USB to VGA DRIVER
|
||||
M: Steve Glendinning <steve.glendinning@shawell.net>
|
||||
L: linux-fbdev@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/video/smscufx.c
|
||||
F: drivers/video/fbdev/smscufx.c
|
||||
|
||||
SOC-CAMERA V4L2 SUBSYSTEM
|
||||
M: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
|
||||
@ -9670,7 +9670,7 @@ L: linux-fbdev@vger.kernel.org
|
||||
W: http://dev.gentoo.org/~spock/projects/uvesafb/
|
||||
S: Maintained
|
||||
F: Documentation/fb/uvesafb.txt
|
||||
F: drivers/video/uvesafb.*
|
||||
F: drivers/video/fbdev/uvesafb.*
|
||||
|
||||
VFAT/FAT/MSDOS FILESYSTEM
|
||||
M: OGAWA Hirofumi <hirofumi@mail.parknet.co.jp>
|
||||
@ -9743,7 +9743,7 @@ S: Maintained
|
||||
F: include/linux/via-core.h
|
||||
F: include/linux/via-gpio.h
|
||||
F: include/linux/via_i2c.h
|
||||
F: drivers/video/via/
|
||||
F: drivers/video/fbdev/via/
|
||||
|
||||
VIA VELOCITY NETWORK DRIVER
|
||||
M: Francois Romieu <romieu@fr.zoreil.com>
|
||||
|
@ -32,8 +32,16 @@ struct omap_connector {
|
||||
struct drm_connector base;
|
||||
struct omap_dss_device *dssdev;
|
||||
struct drm_encoder *encoder;
|
||||
bool hdmi_mode;
|
||||
};
|
||||
|
||||
bool omap_connector_get_hdmi_mode(struct drm_connector *connector)
|
||||
{
|
||||
struct omap_connector *omap_connector = to_omap_connector(connector);
|
||||
|
||||
return omap_connector->hdmi_mode;
|
||||
}
|
||||
|
||||
void copy_timings_omap_to_drm(struct drm_display_mode *mode,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
@ -162,10 +170,14 @@ static int omap_connector_get_modes(struct drm_connector *connector)
|
||||
drm_mode_connector_update_edid_property(
|
||||
connector, edid);
|
||||
n = drm_add_edid_modes(connector, edid);
|
||||
|
||||
omap_connector->hdmi_mode =
|
||||
drm_detect_hdmi_monitor(edid);
|
||||
} else {
|
||||
drm_mode_connector_update_edid_property(
|
||||
connector, NULL);
|
||||
}
|
||||
|
||||
kfree(edid);
|
||||
} else {
|
||||
struct drm_display_mode *mode = drm_mode_create(dev);
|
||||
|
@ -187,6 +187,7 @@ struct drm_encoder *omap_connector_attached_encoder(
|
||||
struct drm_connector *connector);
|
||||
void omap_connector_flush(struct drm_connector *connector,
|
||||
int x, int y, int w, int h);
|
||||
bool omap_connector_get_hdmi_mode(struct drm_connector *connector);
|
||||
|
||||
void copy_timings_omap_to_drm(struct drm_display_mode *mode,
|
||||
struct omap_video_timings *timings);
|
||||
|
@ -17,6 +17,8 @@
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <drm/drm_edid.h>
|
||||
|
||||
#include "omap_drv.h"
|
||||
|
||||
#include "drm_crtc.h"
|
||||
@ -89,6 +91,31 @@ static void omap_encoder_mode_set(struct drm_encoder *encoder,
|
||||
struct drm_display_mode *mode,
|
||||
struct drm_display_mode *adjusted_mode)
|
||||
{
|
||||
struct drm_device *dev = encoder->dev;
|
||||
struct omap_encoder *omap_encoder = to_omap_encoder(encoder);
|
||||
struct omap_dss_device *dssdev = omap_encoder->dssdev;
|
||||
struct drm_connector *connector;
|
||||
bool hdmi_mode;
|
||||
int r;
|
||||
|
||||
hdmi_mode = false;
|
||||
list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
|
||||
if (connector->encoder == encoder) {
|
||||
hdmi_mode = omap_connector_get_hdmi_mode(connector);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (dssdev->driver->set_hdmi_mode)
|
||||
dssdev->driver->set_hdmi_mode(dssdev, hdmi_mode);
|
||||
|
||||
if (hdmi_mode && dssdev->driver->set_hdmi_infoframe) {
|
||||
struct hdmi_avi_infoframe avi;
|
||||
|
||||
r = drm_hdmi_avi_infoframe_from_display_mode(&avi, adjusted_mode);
|
||||
if (r == 0)
|
||||
dssdev->driver->set_hdmi_infoframe(dssdev, &avi);
|
||||
}
|
||||
}
|
||||
|
||||
static void omap_encoder_prepare(struct drm_encoder *encoder)
|
||||
|
@ -49,12 +49,6 @@
|
||||
#error wrong architecture for the MC68x328 frame buffer device
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_FB_68328_INVERT)
|
||||
#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO01
|
||||
#else
|
||||
#define MC68X328FB_MONO_VISUAL FB_VISUAL_MONO10
|
||||
#endif
|
||||
|
||||
static u_long videomemory;
|
||||
static u_long videomemorysize;
|
||||
|
||||
@ -462,7 +456,7 @@ int __init mc68x328fb_init(void)
|
||||
fb_info.fix.line_length =
|
||||
get_line_length(mc68x328fb_default.xres_virtual, mc68x328fb_default.bits_per_pixel);
|
||||
fb_info.fix.visual = (mc68x328fb_default.bits_per_pixel) == 1 ?
|
||||
MC68X328FB_MONO_VISUAL : FB_VISUAL_PSEUDOCOLOR;
|
||||
FB_VISUAL_MONO10 : FB_VISUAL_PSEUDOCOLOR;
|
||||
if (fb_info.var.bits_per_pixel == 1) {
|
||||
fb_info.var.red.length = fb_info.var.green.length = fb_info.var.blue.length = 1;
|
||||
fb_info.var.red.offset = fb_info.var.green.offset = fb_info.var.blue.offset = 0;
|
||||
|
@ -280,6 +280,8 @@ config FB_ARMCLCD
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
select FB_MODE_HELPERS if OF
|
||||
select VIDEOMODE_HELPERS if OF
|
||||
help
|
||||
This framebuffer device driver is for the ARM PrimeCell PL110
|
||||
Colour LCD controller. ARM PrimeCells provide the building
|
||||
@ -307,15 +309,26 @@ config FB_ACORN
|
||||
hardware found in Acorn RISC PCs and other ARM-based machines. If
|
||||
unsure, say N.
|
||||
|
||||
config FB_CLPS711X
|
||||
bool "CLPS711X LCD support"
|
||||
depends on (FB = y) && ARM && ARCH_CLPS711X
|
||||
config FB_CLPS711X_OLD
|
||||
tristate
|
||||
select FB_CFB_FILLRECT
|
||||
select FB_CFB_COPYAREA
|
||||
select FB_CFB_IMAGEBLIT
|
||||
|
||||
config FB_CLPS711X
|
||||
tristate "CLPS711X LCD support"
|
||||
depends on FB && (ARCH_CLPS711X || COMPILE_TEST)
|
||||
select FB_CLPS711X_OLD if ARCH_CLPS711X && !ARCH_MULTIPLATFORM
|
||||
select BACKLIGHT_LCD_SUPPORT
|
||||
select FB_MODE_HELPERS
|
||||
select FB_SYS_FILLRECT
|
||||
select FB_SYS_COPYAREA
|
||||
select FB_SYS_IMAGEBLIT
|
||||
select LCD_CLASS_DEVICE
|
||||
select VIDEOMODE_HELPERS
|
||||
help
|
||||
Say Y to enable the Framebuffer driver for the CLPS7111 and
|
||||
EP7212 processors.
|
||||
Say Y to enable the Framebuffer driver for the Cirrus Logic
|
||||
CLPS711X CPUs.
|
||||
|
||||
config FB_SA1100
|
||||
bool "SA-1100 LCD support"
|
||||
|
@ -14,7 +14,8 @@ obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
|
||||
# Hardware specific drivers go first
|
||||
obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
|
||||
obj-$(CONFIG_FB_ARC) += arcfb.o
|
||||
obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
|
||||
obj-$(CONFIG_FB_CLPS711X) += clps711x-fb.o
|
||||
obj-$(CONFIG_FB_CLPS711X_OLD) += clps711xfb.o
|
||||
obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
|
||||
obj-$(CONFIG_FB_GRVGA) += grvga.o
|
||||
obj-$(CONFIG_FB_PM2) += pm2fb.o
|
||||
|
@ -26,6 +26,13 @@
|
||||
#include <linux/amba/clcd.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/hardirq.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_address.h>
|
||||
#include <linux/of_graph.h>
|
||||
#include <video/display_timing.h>
|
||||
#include <video/of_display_timing.h>
|
||||
#include <video/videomode.h>
|
||||
|
||||
#include <asm/sizes.h>
|
||||
|
||||
@ -543,12 +550,268 @@ static int clcdfb_register(struct clcd_fb *fb)
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
static int clcdfb_of_get_dpi_panel_mode(struct device_node *node,
|
||||
struct fb_videomode *mode)
|
||||
{
|
||||
int err;
|
||||
struct display_timing timing;
|
||||
struct videomode video;
|
||||
|
||||
err = of_get_display_timing(node, "panel-timing", &timing);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
videomode_from_timing(&timing, &video);
|
||||
|
||||
err = fb_videomode_from_videomode(&video, mode);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clcdfb_snprintf_mode(char *buf, int size, struct fb_videomode *mode)
|
||||
{
|
||||
return snprintf(buf, size, "%ux%u@%u", mode->xres, mode->yres,
|
||||
mode->refresh);
|
||||
}
|
||||
|
||||
static int clcdfb_of_get_mode(struct device *dev, struct device_node *endpoint,
|
||||
struct fb_videomode *mode)
|
||||
{
|
||||
int err;
|
||||
struct device_node *panel;
|
||||
char *name;
|
||||
int len;
|
||||
|
||||
panel = of_graph_get_remote_port_parent(endpoint);
|
||||
if (!panel)
|
||||
return -ENODEV;
|
||||
|
||||
/* Only directly connected DPI panels supported for now */
|
||||
if (of_device_is_compatible(panel, "panel-dpi"))
|
||||
err = clcdfb_of_get_dpi_panel_mode(panel, mode);
|
||||
else
|
||||
err = -ENOENT;
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
len = clcdfb_snprintf_mode(NULL, 0, mode);
|
||||
name = devm_kzalloc(dev, len + 1, GFP_KERNEL);
|
||||
clcdfb_snprintf_mode(name, len + 1, mode);
|
||||
mode->name = name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clcdfb_of_init_tft_panel(struct clcd_fb *fb, u32 r0, u32 g0, u32 b0)
|
||||
{
|
||||
static struct {
|
||||
unsigned int part;
|
||||
u32 r0, g0, b0;
|
||||
u32 caps;
|
||||
} panels[] = {
|
||||
{ 0x110, 1, 7, 13, CLCD_CAP_5551 },
|
||||
{ 0x110, 0, 8, 16, CLCD_CAP_888 },
|
||||
{ 0x111, 4, 14, 20, CLCD_CAP_444 },
|
||||
{ 0x111, 3, 11, 19, CLCD_CAP_444 | CLCD_CAP_5551 },
|
||||
{ 0x111, 3, 10, 19, CLCD_CAP_444 | CLCD_CAP_5551 |
|
||||
CLCD_CAP_565 },
|
||||
{ 0x111, 0, 8, 16, CLCD_CAP_444 | CLCD_CAP_5551 |
|
||||
CLCD_CAP_565 | CLCD_CAP_888 },
|
||||
};
|
||||
int i;
|
||||
|
||||
/* Bypass pixel clock divider, data output on the falling edge */
|
||||
fb->panel->tim2 = TIM2_BCD | TIM2_IPC;
|
||||
|
||||
/* TFT display, vert. comp. interrupt at the start of the back porch */
|
||||
fb->panel->cntl |= CNTL_LCDTFT | CNTL_LCDVCOMP(1);
|
||||
|
||||
fb->panel->caps = 0;
|
||||
|
||||
/* Match the setup with known variants */
|
||||
for (i = 0; i < ARRAY_SIZE(panels) && !fb->panel->caps; i++) {
|
||||
if (amba_part(fb->dev) != panels[i].part)
|
||||
continue;
|
||||
if (g0 != panels[i].g0)
|
||||
continue;
|
||||
if (r0 == panels[i].r0 && b0 == panels[i].b0)
|
||||
fb->panel->caps = panels[i].caps & CLCD_CAP_RGB;
|
||||
if (r0 == panels[i].b0 && b0 == panels[i].r0)
|
||||
fb->panel->caps = panels[i].caps & CLCD_CAP_BGR;
|
||||
}
|
||||
|
||||
return fb->panel->caps ? 0 : -EINVAL;
|
||||
}
|
||||
|
||||
static int clcdfb_of_init_display(struct clcd_fb *fb)
|
||||
{
|
||||
struct device_node *endpoint;
|
||||
int err;
|
||||
u32 max_bandwidth;
|
||||
u32 tft_r0b0g0[3];
|
||||
|
||||
fb->panel = devm_kzalloc(&fb->dev->dev, sizeof(*fb->panel), GFP_KERNEL);
|
||||
if (!fb->panel)
|
||||
return -ENOMEM;
|
||||
|
||||
endpoint = of_graph_get_next_endpoint(fb->dev->dev.of_node, NULL);
|
||||
if (!endpoint)
|
||||
return -ENODEV;
|
||||
|
||||
err = clcdfb_of_get_mode(&fb->dev->dev, endpoint, &fb->panel->mode);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = of_property_read_u32(fb->dev->dev.of_node, "max-memory-bandwidth",
|
||||
&max_bandwidth);
|
||||
if (!err)
|
||||
fb->panel->bpp = 8 * max_bandwidth / (fb->panel->mode.xres *
|
||||
fb->panel->mode.yres * fb->panel->mode.refresh);
|
||||
else
|
||||
fb->panel->bpp = 32;
|
||||
|
||||
#ifdef CONFIG_CPU_BIG_ENDIAN
|
||||
fb->panel->cntl |= CNTL_BEBO;
|
||||
#endif
|
||||
fb->panel->width = -1;
|
||||
fb->panel->height = -1;
|
||||
|
||||
if (of_property_read_u32_array(endpoint,
|
||||
"arm,pl11x,tft-r0g0b0-pads",
|
||||
tft_r0b0g0, ARRAY_SIZE(tft_r0b0g0)) == 0)
|
||||
return clcdfb_of_init_tft_panel(fb, tft_r0b0g0[0],
|
||||
tft_r0b0g0[1], tft_r0b0g0[2]);
|
||||
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
static int clcdfb_of_vram_setup(struct clcd_fb *fb)
|
||||
{
|
||||
int err;
|
||||
struct device_node *memory;
|
||||
u64 size;
|
||||
|
||||
err = clcdfb_of_init_display(fb);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
memory = of_parse_phandle(fb->dev->dev.of_node, "memory-region", 0);
|
||||
if (!memory)
|
||||
return -ENODEV;
|
||||
|
||||
fb->fb.screen_base = of_iomap(memory, 0);
|
||||
if (!fb->fb.screen_base)
|
||||
return -ENOMEM;
|
||||
|
||||
fb->fb.fix.smem_start = of_translate_address(memory,
|
||||
of_get_address(memory, 0, &size, NULL));
|
||||
fb->fb.fix.smem_len = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clcdfb_of_vram_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
|
||||
{
|
||||
unsigned long off, user_size, kernel_size;
|
||||
|
||||
|
||||
off = vma->vm_pgoff << PAGE_SHIFT;
|
||||
user_size = vma->vm_end - vma->vm_start;
|
||||
kernel_size = fb->fb.fix.smem_len;
|
||||
|
||||
if (off >= kernel_size || user_size > (kernel_size - off))
|
||||
return -ENXIO;
|
||||
|
||||
return remap_pfn_range(vma, vma->vm_start,
|
||||
__phys_to_pfn(fb->fb.fix.smem_start) + vma->vm_pgoff,
|
||||
user_size,
|
||||
pgprot_writecombine(vma->vm_page_prot));
|
||||
}
|
||||
|
||||
static void clcdfb_of_vram_remove(struct clcd_fb *fb)
|
||||
{
|
||||
iounmap(fb->fb.screen_base);
|
||||
}
|
||||
|
||||
static int clcdfb_of_dma_setup(struct clcd_fb *fb)
|
||||
{
|
||||
unsigned long framesize;
|
||||
dma_addr_t dma;
|
||||
int err;
|
||||
|
||||
err = clcdfb_of_init_display(fb);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
framesize = fb->panel->mode.xres * fb->panel->mode.yres *
|
||||
fb->panel->bpp / 8;
|
||||
fb->fb.screen_base = dma_alloc_coherent(&fb->dev->dev, framesize,
|
||||
&dma, GFP_KERNEL);
|
||||
if (!fb->fb.screen_base)
|
||||
return -ENOMEM;
|
||||
|
||||
fb->fb.fix.smem_start = dma;
|
||||
fb->fb.fix.smem_len = framesize;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clcdfb_of_dma_mmap(struct clcd_fb *fb, struct vm_area_struct *vma)
|
||||
{
|
||||
return dma_mmap_writecombine(&fb->dev->dev, vma, fb->fb.screen_base,
|
||||
fb->fb.fix.smem_start, fb->fb.fix.smem_len);
|
||||
}
|
||||
|
||||
static void clcdfb_of_dma_remove(struct clcd_fb *fb)
|
||||
{
|
||||
dma_free_coherent(&fb->dev->dev, fb->fb.fix.smem_len,
|
||||
fb->fb.screen_base, fb->fb.fix.smem_start);
|
||||
}
|
||||
|
||||
static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
|
||||
{
|
||||
struct clcd_board *board = devm_kzalloc(&dev->dev, sizeof(*board),
|
||||
GFP_KERNEL);
|
||||
struct device_node *node = dev->dev.of_node;
|
||||
|
||||
if (!board)
|
||||
return NULL;
|
||||
|
||||
board->name = of_node_full_name(node);
|
||||
board->caps = CLCD_CAP_ALL;
|
||||
board->check = clcdfb_check;
|
||||
board->decode = clcdfb_decode;
|
||||
if (of_find_property(node, "memory-region", NULL)) {
|
||||
board->setup = clcdfb_of_vram_setup;
|
||||
board->mmap = clcdfb_of_vram_mmap;
|
||||
board->remove = clcdfb_of_vram_remove;
|
||||
} else {
|
||||
board->setup = clcdfb_of_dma_setup;
|
||||
board->mmap = clcdfb_of_dma_mmap;
|
||||
board->remove = clcdfb_of_dma_remove;
|
||||
}
|
||||
|
||||
return board;
|
||||
}
|
||||
#else
|
||||
static struct clcd_board *clcdfb_of_get_board(struct amba_device *dev)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int clcdfb_probe(struct amba_device *dev, const struct amba_id *id)
|
||||
{
|
||||
struct clcd_board *board = dev_get_platdata(&dev->dev);
|
||||
struct clcd_fb *fb;
|
||||
int ret;
|
||||
|
||||
if (!board)
|
||||
board = clcdfb_of_get_board(dev);
|
||||
|
||||
if (!board)
|
||||
return -EINVAL;
|
||||
|
||||
|
@ -290,7 +290,7 @@ static void init_contrast(struct atmel_lcdfb_info *sinfo)
|
||||
|
||||
/* contrast pwm can be 'inverted' */
|
||||
if (pdata->lcdcon_pol_negative)
|
||||
contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
|
||||
contrast_ctr &= ~(ATMEL_LCDC_POL_POSITIVE);
|
||||
|
||||
/* have some default contrast/backlight settings */
|
||||
lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, contrast_ctr);
|
||||
@ -1097,6 +1097,7 @@ static int atmel_lcdfb_of_init(struct atmel_lcdfb_info *sinfo)
|
||||
pdata->lcd_wiring_mode = ret;
|
||||
|
||||
pdata->lcdcon_is_backlight = of_property_read_bool(display_np, "atmel,lcdcon-backlight");
|
||||
pdata->lcdcon_pol_negative = of_property_read_bool(display_np, "atmel,lcdcon-backlight-inverted");
|
||||
|
||||
timings = of_get_display_timings(display_np);
|
||||
if (!timings) {
|
||||
|
397
drivers/video/fbdev/clps711x-fb.c
Normal file
397
drivers/video/fbdev/clps711x-fb.c
Normal file
@ -0,0 +1,397 @@
|
||||
/*
|
||||
* Cirrus Logic CLPS711X FB driver
|
||||
*
|
||||
* Copyright (C) 2014 Alexander Shiyan <shc_work@mail.ru>
|
||||
* Based on driver by Russell King <rmk@arm.linux.org.uk>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*/
|
||||
|
||||
#include <linux/clk.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/lcd.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/syscon.h>
|
||||
#include <linux/mfd/syscon/clps711x.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <video/of_display_timing.h>
|
||||
|
||||
#define CLPS711X_FB_NAME "clps711x-fb"
|
||||
#define CLPS711X_FB_BPP_MAX (4)
|
||||
|
||||
/* Registers relative to LCDCON */
|
||||
#define CLPS711X_LCDCON (0x0000)
|
||||
# define LCDCON_GSEN BIT(30)
|
||||
# define LCDCON_GSMD BIT(31)
|
||||
#define CLPS711X_PALLSW (0x0280)
|
||||
#define CLPS711X_PALMSW (0x02c0)
|
||||
#define CLPS711X_FBADDR (0x0d40)
|
||||
|
||||
struct clps711x_fb_info {
|
||||
struct clk *clk;
|
||||
void __iomem *base;
|
||||
struct regmap *syscon;
|
||||
resource_size_t buffsize;
|
||||
struct fb_videomode mode;
|
||||
struct regulator *lcd_pwr;
|
||||
u32 ac_prescale;
|
||||
bool cmap_invert;
|
||||
};
|
||||
|
||||
static int clps711x_fb_setcolreg(u_int regno, u_int red, u_int green,
|
||||
u_int blue, u_int transp, struct fb_info *info)
|
||||
{
|
||||
struct clps711x_fb_info *cfb = info->par;
|
||||
u32 level, mask, shift;
|
||||
|
||||
if (regno >= BIT(info->var.bits_per_pixel))
|
||||
return -EINVAL;
|
||||
|
||||
shift = 4 * (regno & 7);
|
||||
mask = 0xf << shift;
|
||||
/* gray = 0.30*R + 0.58*G + 0.11*B */
|
||||
level = (((red * 77 + green * 151 + blue * 28) >> 20) << shift) & mask;
|
||||
if (cfb->cmap_invert)
|
||||
level = 0xf - level;
|
||||
|
||||
regno = (regno < 8) ? CLPS711X_PALLSW : CLPS711X_PALMSW;
|
||||
|
||||
writel((readl(cfb->base + regno) & ~mask) | level, cfb->base + regno);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clps711x_fb_check_var(struct fb_var_screeninfo *var,
|
||||
struct fb_info *info)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
if (var->bits_per_pixel < 1 ||
|
||||
var->bits_per_pixel > CLPS711X_FB_BPP_MAX)
|
||||
return -EINVAL;
|
||||
|
||||
if (!var->pixclock)
|
||||
return -EINVAL;
|
||||
|
||||
val = DIV_ROUND_UP(var->xres, 16) - 1;
|
||||
if (val < 0x01 || val > 0x3f)
|
||||
return -EINVAL;
|
||||
|
||||
val = DIV_ROUND_UP(var->yres * var->xres * var->bits_per_pixel, 128);
|
||||
val--;
|
||||
if (val < 0x001 || val > 0x1fff)
|
||||
return -EINVAL;
|
||||
|
||||
var->transp.msb_right = 0;
|
||||
var->transp.offset = 0;
|
||||
var->transp.length = 0;
|
||||
var->red.msb_right = 0;
|
||||
var->red.offset = 0;
|
||||
var->red.length = var->bits_per_pixel;
|
||||
var->green = var->red;
|
||||
var->blue = var->red;
|
||||
var->grayscale = var->bits_per_pixel > 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clps711x_fb_set_par(struct fb_info *info)
|
||||
{
|
||||
struct clps711x_fb_info *cfb = info->par;
|
||||
resource_size_t size;
|
||||
u32 lcdcon, pps;
|
||||
|
||||
size = (info->var.xres * info->var.yres * info->var.bits_per_pixel) / 8;
|
||||
if (size > cfb->buffsize)
|
||||
return -EINVAL;
|
||||
|
||||
switch (info->var.bits_per_pixel) {
|
||||
case 1:
|
||||
info->fix.visual = FB_VISUAL_MONO01;
|
||||
break;
|
||||
case 2:
|
||||
case 4:
|
||||
info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
info->fix.line_length = info->var.xres * info->var.bits_per_pixel / 8;
|
||||
info->fix.smem_len = size;
|
||||
|
||||
lcdcon = (info->var.xres * info->var.yres *
|
||||
info->var.bits_per_pixel) / 128 - 1;
|
||||
lcdcon |= ((info->var.xres / 16) - 1) << 13;
|
||||
lcdcon |= (cfb->ac_prescale & 0x1f) << 25;
|
||||
|
||||
pps = clk_get_rate(cfb->clk) / (PICOS2KHZ(info->var.pixclock) * 1000);
|
||||
if (pps)
|
||||
pps--;
|
||||
lcdcon |= (pps & 0x3f) << 19;
|
||||
|
||||
if (info->var.bits_per_pixel == 4)
|
||||
lcdcon |= LCDCON_GSMD;
|
||||
if (info->var.bits_per_pixel >= 2)
|
||||
lcdcon |= LCDCON_GSEN;
|
||||
|
||||
/* LCDCON must only be changed while the LCD is disabled */
|
||||
regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
|
||||
writel(lcdcon, cfb->base + CLPS711X_LCDCON);
|
||||
regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
|
||||
SYSCON1_LCDEN, SYSCON1_LCDEN);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int clps711x_fb_blank(int blank, struct fb_info *info)
|
||||
{
|
||||
/* Return happy */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct fb_ops clps711x_fb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_setcolreg = clps711x_fb_setcolreg,
|
||||
.fb_check_var = clps711x_fb_check_var,
|
||||
.fb_set_par = clps711x_fb_set_par,
|
||||
.fb_blank = clps711x_fb_blank,
|
||||
.fb_fillrect = sys_fillrect,
|
||||
.fb_copyarea = sys_copyarea,
|
||||
.fb_imageblit = sys_imageblit,
|
||||
};
|
||||
|
||||
static int clps711x_lcd_check_fb(struct lcd_device *lcddev, struct fb_info *fi)
|
||||
{
|
||||
struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
|
||||
|
||||
return (!fi || fi->par == cfb) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int clps711x_lcd_get_power(struct lcd_device *lcddev)
|
||||
{
|
||||
struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
|
||||
|
||||
if (!IS_ERR_OR_NULL(cfb->lcd_pwr))
|
||||
if (!regulator_is_enabled(cfb->lcd_pwr))
|
||||
return FB_BLANK_NORMAL;
|
||||
|
||||
return FB_BLANK_UNBLANK;
|
||||
}
|
||||
|
||||
static int clps711x_lcd_set_power(struct lcd_device *lcddev, int blank)
|
||||
{
|
||||
struct clps711x_fb_info *cfb = dev_get_drvdata(&lcddev->dev);
|
||||
|
||||
if (!IS_ERR_OR_NULL(cfb->lcd_pwr)) {
|
||||
if (blank == FB_BLANK_UNBLANK) {
|
||||
if (!regulator_is_enabled(cfb->lcd_pwr))
|
||||
return regulator_enable(cfb->lcd_pwr);
|
||||
} else {
|
||||
if (regulator_is_enabled(cfb->lcd_pwr))
|
||||
return regulator_disable(cfb->lcd_pwr);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct lcd_ops clps711x_lcd_ops = {
|
||||
.check_fb = clps711x_lcd_check_fb,
|
||||
.get_power = clps711x_lcd_get_power,
|
||||
.set_power = clps711x_lcd_set_power,
|
||||
};
|
||||
|
||||
static int clps711x_fb_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct device *dev = &pdev->dev;
|
||||
struct device_node *disp, *np = dev->of_node;
|
||||
struct clps711x_fb_info *cfb;
|
||||
struct lcd_device *lcd;
|
||||
struct fb_info *info;
|
||||
struct resource *res;
|
||||
int ret = -ENOENT;
|
||||
u32 val;
|
||||
|
||||
if (fb_get_options(CLPS711X_FB_NAME, NULL))
|
||||
return -ENODEV;
|
||||
|
||||
info = framebuffer_alloc(sizeof(*cfb), dev);
|
||||
if (!info)
|
||||
return -ENOMEM;
|
||||
|
||||
cfb = info->par;
|
||||
platform_set_drvdata(pdev, info);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||
if (!res)
|
||||
goto out_fb_release;
|
||||
cfb->base = devm_ioremap(dev, res->start, resource_size(res));
|
||||
if (!cfb->base) {
|
||||
ret = -ENOMEM;
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
info->fix.mmio_start = res->start;
|
||||
info->fix.mmio_len = resource_size(res);
|
||||
|
||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
||||
info->screen_base = devm_ioremap_resource(dev, res);
|
||||
if (IS_ERR(info->screen_base)) {
|
||||
ret = PTR_ERR(info->screen_base);
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
/* Physical address should be aligned to 256 MiB */
|
||||
if (res->start & 0x0fffffff) {
|
||||
ret = -EINVAL;
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
info->apertures = alloc_apertures(1);
|
||||
if (!info->apertures) {
|
||||
ret = -ENOMEM;
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
cfb->buffsize = resource_size(res);
|
||||
info->fix.smem_start = res->start;
|
||||
info->apertures->ranges[0].base = info->fix.smem_start;
|
||||
info->apertures->ranges[0].size = cfb->buffsize;
|
||||
|
||||
cfb->clk = devm_clk_get(dev, NULL);
|
||||
if (IS_ERR(cfb->clk)) {
|
||||
ret = PTR_ERR(cfb->clk);
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
cfb->syscon =
|
||||
syscon_regmap_lookup_by_compatible("cirrus,clps711x-syscon1");
|
||||
if (IS_ERR(cfb->syscon)) {
|
||||
ret = PTR_ERR(cfb->syscon);
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
disp = of_parse_phandle(np, "display", 0);
|
||||
if (!disp) {
|
||||
dev_err(&pdev->dev, "No display defined\n");
|
||||
ret = -ENODATA;
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
ret = of_get_fb_videomode(disp, &cfb->mode, OF_USE_NATIVE_MODE);
|
||||
if (ret)
|
||||
goto out_fb_release;
|
||||
|
||||
of_property_read_u32(disp, "ac-prescale", &cfb->ac_prescale);
|
||||
cfb->cmap_invert = of_property_read_bool(disp, "cmap-invert");
|
||||
|
||||
ret = of_property_read_u32(disp, "bits-per-pixel",
|
||||
&info->var.bits_per_pixel);
|
||||
if (ret)
|
||||
goto out_fb_release;
|
||||
|
||||
/* Force disable LCD on any mismatch */
|
||||
if (info->fix.smem_start != (readb(cfb->base + CLPS711X_FBADDR) << 28))
|
||||
regmap_update_bits(cfb->syscon, SYSCON_OFFSET,
|
||||
SYSCON1_LCDEN, 0);
|
||||
|
||||
ret = regmap_read(cfb->syscon, SYSCON_OFFSET, &val);
|
||||
if (ret)
|
||||
goto out_fb_release;
|
||||
|
||||
if (!(val & SYSCON1_LCDEN)) {
|
||||
/* Setup start FB address */
|
||||
writeb(info->fix.smem_start >> 28, cfb->base + CLPS711X_FBADDR);
|
||||
/* Clean FB memory */
|
||||
memset_io(info->screen_base, 0, cfb->buffsize);
|
||||
}
|
||||
|
||||
cfb->lcd_pwr = devm_regulator_get(dev, "lcd");
|
||||
if (PTR_ERR(cfb->lcd_pwr) == -EPROBE_DEFER) {
|
||||
ret = -EPROBE_DEFER;
|
||||
goto out_fb_release;
|
||||
}
|
||||
|
||||
info->fbops = &clps711x_fb_ops;
|
||||
info->flags = FBINFO_DEFAULT;
|
||||
info->var.activate = FB_ACTIVATE_FORCE | FB_ACTIVATE_NOW;
|
||||
info->var.height = -1;
|
||||
info->var.width = -1;
|
||||
info->var.vmode = FB_VMODE_NONINTERLACED;
|
||||
info->fix.type = FB_TYPE_PACKED_PIXELS;
|
||||
info->fix.accel = FB_ACCEL_NONE;
|
||||
strlcpy(info->fix.id, CLPS711X_FB_NAME, sizeof(info->fix.id));
|
||||
fb_videomode_to_var(&info->var, &cfb->mode);
|
||||
|
||||
ret = fb_alloc_cmap(&info->cmap, BIT(CLPS711X_FB_BPP_MAX), 0);
|
||||
if (ret)
|
||||
goto out_fb_release;
|
||||
|
||||
ret = fb_set_var(info, &info->var);
|
||||
if (ret)
|
||||
goto out_fb_dealloc_cmap;
|
||||
|
||||
ret = register_framebuffer(info);
|
||||
if (ret)
|
||||
goto out_fb_dealloc_cmap;
|
||||
|
||||
lcd = devm_lcd_device_register(dev, "clps711x-lcd", dev, cfb,
|
||||
&clps711x_lcd_ops);
|
||||
if (!IS_ERR(lcd))
|
||||
return 0;
|
||||
|
||||
ret = PTR_ERR(lcd);
|
||||
unregister_framebuffer(info);
|
||||
|
||||
out_fb_dealloc_cmap:
|
||||
regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
|
||||
out_fb_release:
|
||||
framebuffer_release(info);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int clps711x_fb_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct fb_info *info = platform_get_drvdata(pdev);
|
||||
struct clps711x_fb_info *cfb = info->par;
|
||||
|
||||
regmap_update_bits(cfb->syscon, SYSCON_OFFSET, SYSCON1_LCDEN, 0);
|
||||
|
||||
unregister_framebuffer(info);
|
||||
fb_dealloc_cmap(&info->cmap);
|
||||
framebuffer_release(info);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id clps711x_fb_dt_ids[] = {
|
||||
{ .compatible = "cirrus,clps711x-fb", },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, clps711x_fb_dt_ids);
|
||||
|
||||
static struct platform_driver clps711x_fb_driver = {
|
||||
.driver = {
|
||||
.name = CLPS711X_FB_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = clps711x_fb_dt_ids,
|
||||
},
|
||||
.probe = clps711x_fb_probe,
|
||||
.remove = clps711x_fb_remove,
|
||||
};
|
||||
module_platform_driver(clps711x_fb_driver);
|
||||
|
||||
MODULE_AUTHOR("Alexander Shiyan <shc_work@mail.ru>");
|
||||
MODULE_DESCRIPTION("Cirrus Logic CLPS711X FB driver");
|
||||
MODULE_LICENSE("GPL");
|
@ -1447,18 +1447,15 @@ static int fb_probe(struct platform_device *device)
|
||||
da8xx_fb_fix.line_length - 1;
|
||||
|
||||
/* allocate palette buffer */
|
||||
par->v_palette_base = dma_alloc_coherent(NULL,
|
||||
PALETTE_SIZE,
|
||||
(resource_size_t *)
|
||||
&par->p_palette_base,
|
||||
GFP_KERNEL | GFP_DMA);
|
||||
par->v_palette_base = dma_zalloc_coherent(NULL, PALETTE_SIZE,
|
||||
(resource_size_t *)&par->p_palette_base,
|
||||
GFP_KERNEL | GFP_DMA);
|
||||
if (!par->v_palette_base) {
|
||||
dev_err(&device->dev,
|
||||
"GLCD: kmalloc for palette buffer failed\n");
|
||||
ret = -EINVAL;
|
||||
goto err_release_fb_mem;
|
||||
}
|
||||
memset(par->v_palette_base, 0, PALETTE_SIZE);
|
||||
|
||||
par->irq = platform_get_irq(device, 0);
|
||||
if (par->irq < 0) {
|
||||
|
@ -224,6 +224,11 @@ struct hvfb_par {
|
||||
u32 pseudo_palette[16];
|
||||
u8 init_buf[MAX_VMBUS_PKT_SIZE];
|
||||
u8 recv_buf[MAX_VMBUS_PKT_SIZE];
|
||||
|
||||
/* If true, the VSC notifies the VSP on every framebuffer change */
|
||||
bool synchronous_fb;
|
||||
|
||||
struct notifier_block hvfb_panic_nb;
|
||||
};
|
||||
|
||||
static uint screen_width = HVFB_WIDTH;
|
||||
@ -532,6 +537,19 @@ static void hvfb_update_work(struct work_struct *w)
|
||||
schedule_delayed_work(&par->dwork, HVFB_UPDATE_DELAY);
|
||||
}
|
||||
|
||||
static int hvfb_on_panic(struct notifier_block *nb,
|
||||
unsigned long e, void *p)
|
||||
{
|
||||
struct hvfb_par *par;
|
||||
struct fb_info *info;
|
||||
|
||||
par = container_of(nb, struct hvfb_par, hvfb_panic_nb);
|
||||
par->synchronous_fb = true;
|
||||
info = par->info;
|
||||
synthvid_update(info);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
/* Framebuffer operation handlers */
|
||||
|
||||
@ -582,14 +600,44 @@ static int hvfb_blank(int blank, struct fb_info *info)
|
||||
return 1; /* get fb_blank to set the colormap to all black */
|
||||
}
|
||||
|
||||
static void hvfb_cfb_fillrect(struct fb_info *p,
|
||||
const struct fb_fillrect *rect)
|
||||
{
|
||||
struct hvfb_par *par = p->par;
|
||||
|
||||
cfb_fillrect(p, rect);
|
||||
if (par->synchronous_fb)
|
||||
synthvid_update(p);
|
||||
}
|
||||
|
||||
static void hvfb_cfb_copyarea(struct fb_info *p,
|
||||
const struct fb_copyarea *area)
|
||||
{
|
||||
struct hvfb_par *par = p->par;
|
||||
|
||||
cfb_copyarea(p, area);
|
||||
if (par->synchronous_fb)
|
||||
synthvid_update(p);
|
||||
}
|
||||
|
||||
static void hvfb_cfb_imageblit(struct fb_info *p,
|
||||
const struct fb_image *image)
|
||||
{
|
||||
struct hvfb_par *par = p->par;
|
||||
|
||||
cfb_imageblit(p, image);
|
||||
if (par->synchronous_fb)
|
||||
synthvid_update(p);
|
||||
}
|
||||
|
||||
static struct fb_ops hvfb_ops = {
|
||||
.owner = THIS_MODULE,
|
||||
.fb_check_var = hvfb_check_var,
|
||||
.fb_set_par = hvfb_set_par,
|
||||
.fb_setcolreg = hvfb_setcolreg,
|
||||
.fb_fillrect = cfb_fillrect,
|
||||
.fb_copyarea = cfb_copyarea,
|
||||
.fb_imageblit = cfb_imageblit,
|
||||
.fb_fillrect = hvfb_cfb_fillrect,
|
||||
.fb_copyarea = hvfb_cfb_copyarea,
|
||||
.fb_imageblit = hvfb_cfb_imageblit,
|
||||
.fb_blank = hvfb_blank,
|
||||
};
|
||||
|
||||
@ -801,6 +849,11 @@ static int hvfb_probe(struct hv_device *hdev,
|
||||
|
||||
par->fb_ready = true;
|
||||
|
||||
par->synchronous_fb = false;
|
||||
par->hvfb_panic_nb.notifier_call = hvfb_on_panic;
|
||||
atomic_notifier_chain_register(&panic_notifier_list,
|
||||
&par->hvfb_panic_nb);
|
||||
|
||||
return 0;
|
||||
|
||||
error:
|
||||
@ -820,6 +873,9 @@ static int hvfb_remove(struct hv_device *hdev)
|
||||
struct fb_info *info = hv_get_drvdata(hdev);
|
||||
struct hvfb_par *par = info->par;
|
||||
|
||||
atomic_notifier_chain_unregister(&panic_notifier_list,
|
||||
&par->hvfb_panic_nb);
|
||||
|
||||
par->update = false;
|
||||
par->fb_ready = false;
|
||||
|
||||
|
@ -628,14 +628,14 @@ static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
|
||||
case MBXFB_IOCS_PLANEORDER:
|
||||
if (copy_from_user(&porder, (void __user*)arg,
|
||||
sizeof(struct mbxfb_planeorder)))
|
||||
return -EFAULT;
|
||||
return -EFAULT;
|
||||
|
||||
return mbxfb_ioctl_planeorder(&porder);
|
||||
|
||||
case MBXFB_IOCS_ALPHA:
|
||||
if (copy_from_user(&alpha, (void __user*)arg,
|
||||
sizeof(struct mbxfb_alphaCtl)))
|
||||
return -EFAULT;
|
||||
return -EFAULT;
|
||||
|
||||
return mbxfb_ioctl_alphactl(&alpha);
|
||||
|
||||
|
@ -15,6 +15,7 @@
|
||||
* GNU General Public License for more details.
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/kernel.h>
|
||||
@ -51,8 +52,7 @@ static int mddi_dummy_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct msm_mddi_client_data *client_data = pdev->dev.platform_data;
|
||||
struct panel_info *panel =
|
||||
kzalloc(sizeof(struct panel_info), GFP_KERNEL);
|
||||
int ret;
|
||||
devm_kzalloc(&pdev->dev, sizeof(struct panel_info), GFP_KERNEL);
|
||||
if (!panel)
|
||||
return -ENOMEM;
|
||||
platform_set_drvdata(pdev, panel);
|
||||
@ -67,24 +67,11 @@ static int mddi_dummy_probe(struct platform_device *pdev)
|
||||
client_data->fb_resource, 1);
|
||||
panel->panel_data.fb_data = client_data->private_client_data;
|
||||
panel->pdev.dev.platform_data = &panel->panel_data;
|
||||
ret = platform_device_register(&panel->pdev);
|
||||
if (ret) {
|
||||
kfree(panel);
|
||||
return ret;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mddi_dummy_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct panel_info *panel = platform_get_drvdata(pdev);
|
||||
kfree(panel);
|
||||
return 0;
|
||||
return platform_device_register(&panel->pdev);
|
||||
}
|
||||
|
||||
static struct platform_driver mddi_client_dummy = {
|
||||
.probe = mddi_dummy_probe,
|
||||
.remove = mddi_dummy_remove,
|
||||
.driver = { .name = "mddi_c_dummy" },
|
||||
};
|
||||
|
||||
|
@ -262,6 +262,23 @@ static int hdmic_audio_config(struct omap_dss_device *dssdev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmic_set_hdmi_mode(struct omap_dss_device *dssdev, bool hdmi_mode)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.hdmi->set_hdmi_mode(in, hdmi_mode);
|
||||
}
|
||||
|
||||
static int hdmic_set_infoframe(struct omap_dss_device *dssdev,
|
||||
const struct hdmi_avi_infoframe *avi)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.hdmi->set_infoframe(in, avi);
|
||||
}
|
||||
|
||||
static struct omap_dss_driver hdmic_driver = {
|
||||
.connect = hdmic_connect,
|
||||
.disconnect = hdmic_disconnect,
|
||||
@ -277,6 +294,8 @@ static struct omap_dss_driver hdmic_driver = {
|
||||
|
||||
.read_edid = hdmic_read_edid,
|
||||
.detect = hdmic_detect,
|
||||
.set_hdmi_mode = hdmic_set_hdmi_mode,
|
||||
.set_hdmi_infoframe = hdmic_set_infoframe,
|
||||
|
||||
.audio_enable = hdmic_audio_enable,
|
||||
.audio_disable = hdmic_audio_disable,
|
||||
|
@ -242,6 +242,24 @@ static int tpd_audio_config(struct omap_dss_device *dssdev,
|
||||
return in->ops.hdmi->audio_config(in, audio);
|
||||
}
|
||||
|
||||
static int tpd_set_infoframe(struct omap_dss_device *dssdev,
|
||||
const struct hdmi_avi_infoframe *avi)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.hdmi->set_infoframe(in, avi);
|
||||
}
|
||||
|
||||
static int tpd_set_hdmi_mode(struct omap_dss_device *dssdev,
|
||||
bool hdmi_mode)
|
||||
{
|
||||
struct panel_drv_data *ddata = to_panel_data(dssdev);
|
||||
struct omap_dss_device *in = ddata->in;
|
||||
|
||||
return in->ops.hdmi->set_hdmi_mode(in, hdmi_mode);
|
||||
}
|
||||
|
||||
static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
|
||||
.connect = tpd_connect,
|
||||
.disconnect = tpd_disconnect,
|
||||
@ -255,6 +273,8 @@ static const struct omapdss_hdmi_ops tpd_hdmi_ops = {
|
||||
|
||||
.read_edid = tpd_read_edid,
|
||||
.detect = tpd_detect,
|
||||
.set_infoframe = tpd_set_infoframe,
|
||||
.set_hdmi_mode = tpd_set_hdmi_mode,
|
||||
|
||||
.audio_enable = tpd_audio_enable,
|
||||
.audio_disable = tpd_audio_disable,
|
||||
|
@ -817,6 +817,10 @@ static int acx565akm_probe(struct spi_device *spi)
|
||||
|
||||
bldev = backlight_device_register("acx565akm", &ddata->spi->dev,
|
||||
ddata, &acx565akm_bl_ops, &props);
|
||||
if (IS_ERR(bldev)) {
|
||||
r = PTR_ERR(bldev);
|
||||
goto err_reg_bl;
|
||||
}
|
||||
ddata->bl_dev = bldev;
|
||||
if (ddata->has_cabc) {
|
||||
r = sysfs_create_group(&bldev->dev.kobj, &bldev_attr_group);
|
||||
@ -862,6 +866,7 @@ err_reg:
|
||||
sysfs_remove_group(&bldev->dev.kobj, &bldev_attr_group);
|
||||
err_sysfs:
|
||||
backlight_device_unregister(bldev);
|
||||
err_reg_bl:
|
||||
err_detect:
|
||||
err_gpio:
|
||||
omap_dss_put_device(ddata->in);
|
||||
|
@ -5,6 +5,7 @@ menuconfig OMAP2_DSS
|
||||
tristate "OMAP2+ Display Subsystem support"
|
||||
select VIDEOMODE_HELPERS
|
||||
select OMAP2_DSS_INIT
|
||||
select HDMI
|
||||
help
|
||||
OMAP2+ Display Subsystem support.
|
||||
|
||||
|
@ -2879,19 +2879,24 @@ static bool _dispc_mgr_pclk_ok(enum omap_channel channel,
|
||||
bool dispc_mgr_timings_ok(enum omap_channel channel,
|
||||
const struct omap_video_timings *timings)
|
||||
{
|
||||
bool timings_ok;
|
||||
if (!_dispc_mgr_size_ok(timings->x_res, timings->y_res))
|
||||
return false;
|
||||
|
||||
timings_ok = _dispc_mgr_size_ok(timings->x_res, timings->y_res);
|
||||
|
||||
timings_ok &= _dispc_mgr_pclk_ok(channel, timings->pixelclock);
|
||||
if (!_dispc_mgr_pclk_ok(channel, timings->pixelclock))
|
||||
return false;
|
||||
|
||||
if (dss_mgr_is_lcd(channel)) {
|
||||
timings_ok &= _dispc_lcd_timings_ok(timings->hsw, timings->hfp,
|
||||
/* TODO: OMAP4+ supports interlace for LCD outputs */
|
||||
if (timings->interlace)
|
||||
return false;
|
||||
|
||||
if (!_dispc_lcd_timings_ok(timings->hsw, timings->hfp,
|
||||
timings->hbp, timings->vsw, timings->vfp,
|
||||
timings->vbp);
|
||||
timings->vbp))
|
||||
return false;
|
||||
}
|
||||
|
||||
return timings_ok;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _dispc_mgr_set_lcd_timings(enum omap_channel channel, int hsw,
|
||||
@ -3257,13 +3262,10 @@ static void dispc_dump_regs(struct seq_file *s)
|
||||
if (i == OMAP_DSS_CHANNEL_DIGIT)
|
||||
continue;
|
||||
|
||||
DUMPREG(i, DISPC_DEFAULT_COLOR);
|
||||
DUMPREG(i, DISPC_TRANS_COLOR);
|
||||
DUMPREG(i, DISPC_TIMING_H);
|
||||
DUMPREG(i, DISPC_TIMING_V);
|
||||
DUMPREG(i, DISPC_POL_FREQ);
|
||||
DUMPREG(i, DISPC_DIVISORo);
|
||||
DUMPREG(i, DISPC_SIZE_MGR);
|
||||
|
||||
DUMPREG(i, DISPC_DATA_CYCLE1);
|
||||
DUMPREG(i, DISPC_DATA_CYCLE2);
|
||||
|
@ -5658,18 +5658,11 @@ err_runtime_get:
|
||||
return r;
|
||||
}
|
||||
|
||||
static int dsi_unregister_child(struct device *dev, void *data)
|
||||
{
|
||||
struct platform_device *pdev = to_platform_device(dev);
|
||||
platform_device_unregister(pdev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __exit omap_dsihw_remove(struct platform_device *dsidev)
|
||||
{
|
||||
struct dsi_data *dsi = dsi_get_dsidrv_data(dsidev);
|
||||
|
||||
device_for_each_child(&dsidev->dev, NULL, dsi_unregister_child);
|
||||
of_platform_depopulate(&dsidev->dev);
|
||||
|
||||
WARN_ON(dsi->scp_clk_refcount > 0);
|
||||
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/hdmi.h>
|
||||
#include <video/omapdss.h>
|
||||
|
||||
#include "dss.h"
|
||||
@ -142,7 +143,7 @@ enum hdmi_audio_samples_perword {
|
||||
HDMI_AUDIO_ONEWORD_TWOSAMPLES = 1
|
||||
};
|
||||
|
||||
enum hdmi_audio_sample_size {
|
||||
enum hdmi_audio_sample_size_omap {
|
||||
HDMI_AUDIO_SAMPLE_16BITS = 0,
|
||||
HDMI_AUDIO_SAMPLE_24BITS = 1
|
||||
};
|
||||
@ -178,59 +179,6 @@ enum hdmi_audio_mclk_mode {
|
||||
HDMI_AUDIO_MCLK_192FS = 7
|
||||
};
|
||||
|
||||
/* INFOFRAME_AVI_ and INFOFRAME_AUDIO_ definitions */
|
||||
enum hdmi_core_infoframe {
|
||||
HDMI_INFOFRAME_AVI_DB1Y_RGB = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV422 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1Y_YUV444 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_ON = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1B_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1B_VERT = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1B_HORI = 2,
|
||||
HDMI_INFOFRAME_AVI_DB1B_VERTHORI = 3,
|
||||
HDMI_INFOFRAME_AVI_DB1S_0 = 0,
|
||||
HDMI_INFOFRAME_AVI_DB1S_1 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB1S_2 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2C_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB2C_ITU601 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB2C_ITU709 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2C_EC_EXTENDED = 3,
|
||||
HDMI_INFOFRAME_AVI_DB2M_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB2M_43 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB2M_169 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB2R_SAME = 8,
|
||||
HDMI_INFOFRAME_AVI_DB2R_43 = 9,
|
||||
HDMI_INFOFRAME_AVI_DB2R_169 = 10,
|
||||
HDMI_INFOFRAME_AVI_DB2R_149 = 11,
|
||||
HDMI_INFOFRAME_AVI_DB3ITC_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3ITC_YES = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3EC_XVYUV601 = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3EC_XVYUV709 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_DEFAULT = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_LR = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3Q_FR = 2,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_HORI = 1,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_VERT = 2,
|
||||
HDMI_INFOFRAME_AVI_DB3SC_HORIVERT = 3,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_NO = 0,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_2 = 1,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_3 = 2,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_4 = 3,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_5 = 4,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_6 = 5,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_7 = 6,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_8 = 7,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_9 = 8,
|
||||
HDMI_INFOFRAME_AVI_DB5PR_10 = 9,
|
||||
};
|
||||
|
||||
struct hdmi_cm {
|
||||
int code;
|
||||
int mode;
|
||||
};
|
||||
|
||||
struct hdmi_video_format {
|
||||
enum hdmi_packing_mode packing_mode;
|
||||
u32 y_res; /* Line per panel */
|
||||
@ -239,7 +187,8 @@ struct hdmi_video_format {
|
||||
|
||||
struct hdmi_config {
|
||||
struct omap_video_timings timings;
|
||||
struct hdmi_cm cm;
|
||||
struct hdmi_avi_infoframe infoframe;
|
||||
enum hdmi_core_hdmi_dvi hdmi_dvi_mode;
|
||||
};
|
||||
|
||||
/* HDMI PLL structure */
|
||||
@ -260,7 +209,7 @@ struct hdmi_audio_format {
|
||||
enum hdmi_audio_justify justification;
|
||||
enum hdmi_audio_sample_order sample_order;
|
||||
enum hdmi_audio_samples_perword samples_per_word;
|
||||
enum hdmi_audio_sample_size sample_size;
|
||||
enum hdmi_audio_sample_size_omap sample_size;
|
||||
enum hdmi_audio_blk_strt_end_sig en_sig_blk_strt_end;
|
||||
};
|
||||
|
||||
@ -298,47 +247,6 @@ struct hdmi_core_audio_config {
|
||||
bool en_spdif;
|
||||
};
|
||||
|
||||
/*
|
||||
* Refer to section 8.2 in HDMI 1.3 specification for
|
||||
* details about infoframe databytes
|
||||
*/
|
||||
struct hdmi_core_infoframe_avi {
|
||||
/* Y0, Y1 rgb,yCbCr */
|
||||
u8 db1_format;
|
||||
/* A0 Active information Present */
|
||||
u8 db1_active_info;
|
||||
/* B0, B1 Bar info data valid */
|
||||
u8 db1_bar_info_dv;
|
||||
/* S0, S1 scan information */
|
||||
u8 db1_scan_info;
|
||||
/* C0, C1 colorimetry */
|
||||
u8 db2_colorimetry;
|
||||
/* M0, M1 Aspect ratio (4:3, 16:9) */
|
||||
u8 db2_aspect_ratio;
|
||||
/* R0...R3 Active format aspect ratio */
|
||||
u8 db2_active_fmt_ar;
|
||||
/* ITC IT content. */
|
||||
u8 db3_itc;
|
||||
/* EC0, EC1, EC2 Extended colorimetry */
|
||||
u8 db3_ec;
|
||||
/* Q1, Q0 Quantization range */
|
||||
u8 db3_q_range;
|
||||
/* SC1, SC0 Non-uniform picture scaling */
|
||||
u8 db3_nup_scaling;
|
||||
/* VIC0..6 Video format identification */
|
||||
u8 db4_videocode;
|
||||
/* PR0..PR3 Pixel repetition factor */
|
||||
u8 db5_pixel_repeat;
|
||||
/* Line number end of top bar */
|
||||
u16 db6_7_line_eoftop;
|
||||
/* Line number start of bottom bar */
|
||||
u16 db8_9_line_sofbottom;
|
||||
/* Pixel number end of left bar */
|
||||
u16 db10_11_pixel_eofleft;
|
||||
/* Pixel number start of right bar */
|
||||
u16 db12_13_pixel_sofright;
|
||||
};
|
||||
|
||||
struct hdmi_wp_data {
|
||||
void __iomem *base;
|
||||
};
|
||||
@ -358,8 +266,6 @@ struct hdmi_phy_data {
|
||||
|
||||
struct hdmi_core_data {
|
||||
void __iomem *base;
|
||||
|
||||
struct hdmi_core_infoframe_avi avi_cfg;
|
||||
};
|
||||
|
||||
static inline void hdmi_write_reg(void __iomem *base_addr, const u32 idx,
|
||||
@ -425,9 +331,6 @@ int hdmi_phy_init(struct platform_device *pdev, struct hdmi_phy_data *phy);
|
||||
int hdmi_phy_parse_lanes(struct hdmi_phy_data *phy, const u32 *lanes);
|
||||
|
||||
/* HDMI common funcs */
|
||||
const struct hdmi_config *hdmi_default_timing(void);
|
||||
const struct hdmi_config *hdmi_get_timings(int mode, int code);
|
||||
struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing);
|
||||
int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
|
||||
struct hdmi_phy_data *phy);
|
||||
|
||||
|
@ -281,29 +281,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct hdmi_cm cm;
|
||||
const struct hdmi_config *t;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
cm = hdmi_get_code(timings);
|
||||
hdmi.cfg.cm = cm;
|
||||
hdmi.cfg.timings = *timings;
|
||||
|
||||
t = hdmi_get_timings(cm.mode, cm.code);
|
||||
if (t != NULL) {
|
||||
hdmi.cfg = *t;
|
||||
|
||||
dispc_set_tv_pclk(t->timings.pixelclock);
|
||||
} else {
|
||||
hdmi.cfg.timings = *timings;
|
||||
hdmi.cfg.cm.code = 0;
|
||||
hdmi.cfg.cm.mode = HDMI_DVI;
|
||||
|
||||
dispc_set_tv_pclk(timings->pixelclock);
|
||||
}
|
||||
|
||||
DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
|
||||
"DVI" : "HDMI", hdmi.cfg.cm.code);
|
||||
dispc_set_tv_pclk(timings->pixelclock);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
@ -311,14 +293,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
const struct hdmi_config *cfg;
|
||||
struct hdmi_cm cm = hdmi.cfg.cm;
|
||||
|
||||
cfg = hdmi_get_timings(cm.mode, cm.code);
|
||||
if (cfg == NULL)
|
||||
cfg = hdmi_default_timing();
|
||||
|
||||
memcpy(timings, &cfg->timings, sizeof(cfg->timings));
|
||||
*timings = hdmi.cfg.timings;
|
||||
}
|
||||
|
||||
static void hdmi_dump_regs(struct seq_file *s)
|
||||
@ -516,7 +491,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev)
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
|
||||
r = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
@ -554,7 +529,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
r = hdmi_mode_has_audio(hdmi.cfg.cm.mode);
|
||||
r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
@ -568,7 +543,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
|
||||
r = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
@ -615,6 +590,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
|
||||
const struct hdmi_avi_infoframe *avi)
|
||||
{
|
||||
hdmi.cfg.infoframe = *avi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
|
||||
bool hdmi_mode)
|
||||
{
|
||||
hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct omapdss_hdmi_ops hdmi_ops = {
|
||||
.connect = hdmi_connect,
|
||||
.disconnect = hdmi_disconnect,
|
||||
@ -627,6 +616,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
|
||||
.get_timings = hdmi_display_get_timings,
|
||||
|
||||
.read_edid = hdmi_read_edid,
|
||||
.set_infoframe = hdmi_set_infoframe,
|
||||
.set_hdmi_mode = hdmi_set_hdmi_mode,
|
||||
|
||||
.audio_enable = hdmi_audio_enable,
|
||||
.audio_disable = hdmi_audio_disable,
|
||||
|
@ -197,9 +197,7 @@ int hdmi4_read_edid(struct hdmi_core_data *core, u8 *edid, int len)
|
||||
return l;
|
||||
}
|
||||
|
||||
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
|
||||
struct hdmi_core_infoframe_avi *avi_cfg,
|
||||
struct hdmi_core_packet_enable_repeat *repeat_cfg)
|
||||
static void hdmi_core_init(struct hdmi_core_video_config *video_cfg)
|
||||
{
|
||||
DSSDBG("Enter hdmi_core_init\n");
|
||||
|
||||
@ -210,35 +208,6 @@ static void hdmi_core_init(struct hdmi_core_video_config *video_cfg,
|
||||
video_cfg->pkt_mode = HDMI_PACKETMODERESERVEDVALUE;
|
||||
video_cfg->hdmi_dvi = HDMI_DVI;
|
||||
video_cfg->tclk_sel_clkmult = HDMI_FPLL10IDCK;
|
||||
|
||||
/* info frame */
|
||||
avi_cfg->db1_format = 0;
|
||||
avi_cfg->db1_active_info = 0;
|
||||
avi_cfg->db1_bar_info_dv = 0;
|
||||
avi_cfg->db1_scan_info = 0;
|
||||
avi_cfg->db2_colorimetry = 0;
|
||||
avi_cfg->db2_aspect_ratio = 0;
|
||||
avi_cfg->db2_active_fmt_ar = 0;
|
||||
avi_cfg->db3_itc = 0;
|
||||
avi_cfg->db3_ec = 0;
|
||||
avi_cfg->db3_q_range = 0;
|
||||
avi_cfg->db3_nup_scaling = 0;
|
||||
avi_cfg->db4_videocode = 0;
|
||||
avi_cfg->db5_pixel_repeat = 0;
|
||||
avi_cfg->db6_7_line_eoftop = 0;
|
||||
avi_cfg->db8_9_line_sofbottom = 0;
|
||||
avi_cfg->db10_11_pixel_eofleft = 0;
|
||||
avi_cfg->db12_13_pixel_sofright = 0;
|
||||
|
||||
/* packet enable and repeat */
|
||||
repeat_cfg->audio_pkt = 0;
|
||||
repeat_cfg->audio_pkt_repeat = 0;
|
||||
repeat_cfg->avi_infoframe = 0;
|
||||
repeat_cfg->avi_infoframe_repeat = 0;
|
||||
repeat_cfg->gen_cntrl_pkt = 0;
|
||||
repeat_cfg->gen_cntrl_pkt_repeat = 0;
|
||||
repeat_cfg->generic_pkt = 0;
|
||||
repeat_cfg->generic_pkt_repeat = 0;
|
||||
}
|
||||
|
||||
static void hdmi_core_powerdown_disable(struct hdmi_core_data *core)
|
||||
@ -303,80 +272,22 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,
|
||||
HDMI_CORE_SYS_TMDS_CTRL, cfg->tclk_sel_clkmult, 6, 5);
|
||||
}
|
||||
|
||||
static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)
|
||||
static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
|
||||
struct hdmi_avi_infoframe *frame)
|
||||
{
|
||||
u32 val;
|
||||
char sum = 0, checksum = 0;
|
||||
void __iomem *av_base = hdmi_av_base(core);
|
||||
struct hdmi_core_infoframe_avi info_avi = core->avi_cfg;
|
||||
u8 data[HDMI_INFOFRAME_SIZE(AVI)];
|
||||
int i;
|
||||
|
||||
sum += 0x82 + 0x002 + 0x00D;
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_TYPE, 0x082);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_VERS, 0x002);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_LEN, 0x00D);
|
||||
hdmi_avi_infoframe_pack(frame, data, sizeof(data));
|
||||
|
||||
val = (info_avi.db1_format << 5) |
|
||||
(info_avi.db1_active_info << 4) |
|
||||
(info_avi.db1_bar_info_dv << 2) |
|
||||
(info_avi.db1_scan_info);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(0), val);
|
||||
sum += val;
|
||||
print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
|
||||
HDMI_INFOFRAME_SIZE(AVI), false);
|
||||
|
||||
val = (info_avi.db2_colorimetry << 6) |
|
||||
(info_avi.db2_aspect_ratio << 4) |
|
||||
(info_avi.db2_active_fmt_ar);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(1), val);
|
||||
sum += val;
|
||||
|
||||
val = (info_avi.db3_itc << 7) |
|
||||
(info_avi.db3_ec << 4) |
|
||||
(info_avi.db3_q_range << 2) |
|
||||
(info_avi.db3_nup_scaling);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(2), val);
|
||||
sum += val;
|
||||
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(3),
|
||||
info_avi.db4_videocode);
|
||||
sum += info_avi.db4_videocode;
|
||||
|
||||
val = info_avi.db5_pixel_repeat;
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(4), val);
|
||||
sum += val;
|
||||
|
||||
val = info_avi.db6_7_line_eoftop & 0x00FF;
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(5), val);
|
||||
sum += val;
|
||||
|
||||
val = ((info_avi.db6_7_line_eoftop >> 8) & 0x00FF);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(6), val);
|
||||
sum += val;
|
||||
|
||||
val = info_avi.db8_9_line_sofbottom & 0x00FF;
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(7), val);
|
||||
sum += val;
|
||||
|
||||
val = ((info_avi.db8_9_line_sofbottom >> 8) & 0x00FF);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(8), val);
|
||||
sum += val;
|
||||
|
||||
val = info_avi.db10_11_pixel_eofleft & 0x00FF;
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(9), val);
|
||||
sum += val;
|
||||
|
||||
val = ((info_avi.db10_11_pixel_eofleft >> 8) & 0x00FF);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(10), val);
|
||||
sum += val;
|
||||
|
||||
val = info_avi.db12_13_pixel_sofright & 0x00FF;
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(11), val);
|
||||
sum += val;
|
||||
|
||||
val = ((info_avi.db12_13_pixel_sofright >> 8) & 0x00FF);
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_DBYTE(12), val);
|
||||
sum += val;
|
||||
|
||||
checksum = 0x100 - sum;
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_CHSUM, checksum);
|
||||
for (i = 0; i < sizeof(data); ++i) {
|
||||
hdmi_write_reg(av_base, HDMI_CORE_AV_AVI_BASE + i * 4,
|
||||
data[i]);
|
||||
}
|
||||
}
|
||||
|
||||
static void hdmi_core_av_packet_config(struct hdmi_core_data *core,
|
||||
@ -404,11 +315,10 @@ void hdmi4_configure(struct hdmi_core_data *core,
|
||||
struct omap_video_timings video_timing;
|
||||
struct hdmi_video_format video_format;
|
||||
/* HDMI core */
|
||||
struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
|
||||
struct hdmi_core_video_config v_core_cfg;
|
||||
struct hdmi_core_packet_enable_repeat repeat_cfg;
|
||||
struct hdmi_core_packet_enable_repeat repeat_cfg = { 0 };
|
||||
|
||||
hdmi_core_init(&v_core_cfg, avi_cfg, &repeat_cfg);
|
||||
hdmi_core_init(&v_core_cfg);
|
||||
|
||||
hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
|
||||
|
||||
@ -431,44 +341,24 @@ void hdmi4_configure(struct hdmi_core_data *core,
|
||||
hdmi_core_powerdown_disable(core);
|
||||
|
||||
v_core_cfg.pkt_mode = HDMI_PACKETMODE24BITPERPIXEL;
|
||||
v_core_cfg.hdmi_dvi = cfg->cm.mode;
|
||||
v_core_cfg.hdmi_dvi = cfg->hdmi_dvi_mode;
|
||||
|
||||
hdmi_core_video_config(core, &v_core_cfg);
|
||||
|
||||
/* release software reset in the core */
|
||||
hdmi_core_swreset_release(core);
|
||||
|
||||
/*
|
||||
* configure packet
|
||||
* info frame video see doc CEA861-D page 65
|
||||
*/
|
||||
avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
|
||||
avi_cfg->db1_active_info =
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
|
||||
avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
|
||||
avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
|
||||
avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
|
||||
avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
|
||||
avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
|
||||
avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
|
||||
avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
|
||||
avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
|
||||
avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
|
||||
avi_cfg->db4_videocode = cfg->cm.code;
|
||||
avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
|
||||
avi_cfg->db6_7_line_eoftop = 0;
|
||||
avi_cfg->db8_9_line_sofbottom = 0;
|
||||
avi_cfg->db10_11_pixel_eofleft = 0;
|
||||
avi_cfg->db12_13_pixel_sofright = 0;
|
||||
if (cfg->hdmi_dvi_mode == HDMI_HDMI) {
|
||||
hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
|
||||
|
||||
hdmi_core_aux_infoframe_avi_config(core);
|
||||
/* enable/repeat the infoframe */
|
||||
repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
|
||||
repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
|
||||
/* wakeup */
|
||||
repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
|
||||
repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
|
||||
}
|
||||
|
||||
/* enable/repeat the infoframe */
|
||||
repeat_cfg.avi_infoframe = HDMI_PACKETENABLE;
|
||||
repeat_cfg.avi_infoframe_repeat = HDMI_PACKETREPEATON;
|
||||
/* wakeup */
|
||||
repeat_cfg.audio_pkt = HDMI_PACKETENABLE;
|
||||
repeat_cfg.audio_pkt_repeat = HDMI_PACKETREPEATON;
|
||||
hdmi_core_av_packet_config(core, repeat_cfg);
|
||||
}
|
||||
|
||||
|
@ -145,6 +145,7 @@
|
||||
#define HDMI_CORE_AV_DPD 0xF4
|
||||
#define HDMI_CORE_AV_PB_CTRL1 0xF8
|
||||
#define HDMI_CORE_AV_PB_CTRL2 0xFC
|
||||
#define HDMI_CORE_AV_AVI_BASE 0x100
|
||||
#define HDMI_CORE_AV_AVI_TYPE 0x100
|
||||
#define HDMI_CORE_AV_AVI_VERS 0x104
|
||||
#define HDMI_CORE_AV_AVI_LEN 0x108
|
||||
|
@ -299,29 +299,11 @@ static int hdmi_display_check_timing(struct omap_dss_device *dssdev,
|
||||
static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
struct hdmi_cm cm;
|
||||
const struct hdmi_config *t;
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
cm = hdmi_get_code(timings);
|
||||
hdmi.cfg.cm = cm;
|
||||
hdmi.cfg.timings = *timings;
|
||||
|
||||
t = hdmi_get_timings(cm.mode, cm.code);
|
||||
if (t != NULL) {
|
||||
hdmi.cfg = *t;
|
||||
|
||||
dispc_set_tv_pclk(t->timings.pixelclock);
|
||||
} else {
|
||||
hdmi.cfg.timings = *timings;
|
||||
hdmi.cfg.cm.code = 0;
|
||||
hdmi.cfg.cm.mode = HDMI_DVI;
|
||||
|
||||
dispc_set_tv_pclk(timings->pixelclock);
|
||||
}
|
||||
|
||||
DSSDBG("using mode: %s, code %d\n", hdmi.cfg.cm.mode == HDMI_DVI ?
|
||||
"DVI" : "HDMI", hdmi.cfg.cm.code);
|
||||
dispc_set_tv_pclk(timings->pixelclock);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
}
|
||||
@ -329,14 +311,7 @@ static void hdmi_display_set_timing(struct omap_dss_device *dssdev,
|
||||
static void hdmi_display_get_timings(struct omap_dss_device *dssdev,
|
||||
struct omap_video_timings *timings)
|
||||
{
|
||||
const struct hdmi_config *cfg;
|
||||
struct hdmi_cm cm = hdmi.cfg.cm;
|
||||
|
||||
cfg = hdmi_get_timings(cm.mode, cm.code);
|
||||
if (cfg == NULL)
|
||||
cfg = hdmi_default_timing();
|
||||
|
||||
memcpy(timings, &cfg->timings, sizeof(cfg->timings));
|
||||
*timings = hdmi.cfg.timings;
|
||||
}
|
||||
|
||||
static void hdmi_dump_regs(struct seq_file *s)
|
||||
@ -541,7 +516,7 @@ static int hdmi_audio_enable(struct omap_dss_device *dssdev)
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
|
||||
r = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
@ -579,7 +554,7 @@ static bool hdmi_audio_supported(struct omap_dss_device *dssdev)
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
r = hdmi_mode_has_audio(hdmi.cfg.cm.mode);
|
||||
r = hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode);
|
||||
|
||||
mutex_unlock(&hdmi.lock);
|
||||
return r;
|
||||
@ -593,7 +568,7 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
|
||||
|
||||
mutex_lock(&hdmi.lock);
|
||||
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.cm.mode)) {
|
||||
if (!hdmi_mode_has_audio(hdmi.cfg.hdmi_dvi_mode)) {
|
||||
r = -EPERM;
|
||||
goto err;
|
||||
}
|
||||
@ -640,6 +615,20 @@ static int hdmi_audio_config(struct omap_dss_device *dssdev,
|
||||
}
|
||||
#endif
|
||||
|
||||
static int hdmi_set_infoframe(struct omap_dss_device *dssdev,
|
||||
const struct hdmi_avi_infoframe *avi)
|
||||
{
|
||||
hdmi.cfg.infoframe = *avi;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int hdmi_set_hdmi_mode(struct omap_dss_device *dssdev,
|
||||
bool hdmi_mode)
|
||||
{
|
||||
hdmi.cfg.hdmi_dvi_mode = hdmi_mode ? HDMI_HDMI : HDMI_DVI;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct omapdss_hdmi_ops hdmi_ops = {
|
||||
.connect = hdmi_connect,
|
||||
.disconnect = hdmi_disconnect,
|
||||
@ -652,6 +641,8 @@ static const struct omapdss_hdmi_ops hdmi_ops = {
|
||||
.get_timings = hdmi_display_get_timings,
|
||||
|
||||
.read_edid = hdmi_read_edid,
|
||||
.set_infoframe = hdmi_set_infoframe,
|
||||
.set_hdmi_mode = hdmi_set_hdmi_mode,
|
||||
|
||||
.audio_enable = hdmi_audio_enable,
|
||||
.audio_disable = hdmi_audio_disable,
|
||||
|
@ -290,7 +290,6 @@ void hdmi5_core_dump(struct hdmi_core_data *core, struct seq_file *s)
|
||||
}
|
||||
|
||||
static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
|
||||
struct hdmi_core_infoframe_avi *avi_cfg,
|
||||
struct hdmi_config *cfg)
|
||||
{
|
||||
DSSDBG("hdmi_core_init\n");
|
||||
@ -312,27 +311,8 @@ static void hdmi_core_init(struct hdmi_core_vid_config *video_cfg,
|
||||
video_cfg->vblank_osc = 0; /* Always 0 - need to confirm */
|
||||
video_cfg->vblank = cfg->timings.vsw +
|
||||
cfg->timings.vfp + cfg->timings.vbp;
|
||||
video_cfg->v_fc_config.cm.mode = cfg->cm.mode;
|
||||
video_cfg->v_fc_config.hdmi_dvi_mode = cfg->hdmi_dvi_mode;
|
||||
video_cfg->v_fc_config.timings.interlace = cfg->timings.interlace;
|
||||
|
||||
/* info frame */
|
||||
avi_cfg->db1_format = 0;
|
||||
avi_cfg->db1_active_info = 0;
|
||||
avi_cfg->db1_bar_info_dv = 0;
|
||||
avi_cfg->db1_scan_info = 0;
|
||||
avi_cfg->db2_colorimetry = 0;
|
||||
avi_cfg->db2_aspect_ratio = 0;
|
||||
avi_cfg->db2_active_fmt_ar = 0;
|
||||
avi_cfg->db3_itc = 0;
|
||||
avi_cfg->db3_ec = 0;
|
||||
avi_cfg->db3_q_range = 0;
|
||||
avi_cfg->db3_nup_scaling = 0;
|
||||
avi_cfg->db4_videocode = 0;
|
||||
avi_cfg->db5_pixel_repeat = 0;
|
||||
avi_cfg->db6_7_line_eoftop = 0;
|
||||
avi_cfg->db8_9_line_sofbottom = 0;
|
||||
avi_cfg->db10_11_pixel_eofleft = 0;
|
||||
avi_cfg->db12_13_pixel_sofright = 0;
|
||||
}
|
||||
|
||||
/* DSS_HDMI_CORE_VIDEO_CONFIG */
|
||||
@ -398,7 +378,7 @@ static void hdmi_core_video_config(struct hdmi_core_data *core,
|
||||
|
||||
/* select DVI mode */
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_INVIDCONF,
|
||||
cfg->v_fc_config.cm.mode, 3, 3);
|
||||
cfg->v_fc_config.hdmi_dvi_mode, 3, 3);
|
||||
}
|
||||
|
||||
static void hdmi_core_config_video_packetizer(struct hdmi_core_data *core)
|
||||
@ -438,24 +418,60 @@ static void hdmi_core_config_video_sampler(struct hdmi_core_data *core)
|
||||
REG_FLD_MOD(core->base, HDMI_CORE_TX_INVID0, video_mapping, 4, 0);
|
||||
}
|
||||
|
||||
static void hdmi_core_aux_infoframe_avi_config(struct hdmi_core_data *core)
|
||||
static void hdmi_core_write_avi_infoframe(struct hdmi_core_data *core,
|
||||
struct hdmi_avi_infoframe *frame)
|
||||
{
|
||||
void __iomem *base = core->base;
|
||||
struct hdmi_core_infoframe_avi avi = core->avi_cfg;
|
||||
u8 data[HDMI_INFOFRAME_SIZE(AVI)];
|
||||
u8 *ptr;
|
||||
unsigned y, a, b, s;
|
||||
unsigned c, m, r;
|
||||
unsigned itc, ec, q, sc;
|
||||
unsigned vic;
|
||||
unsigned yq, cn, pr;
|
||||
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_format, 1, 0);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_active_info, 6, 6);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_bar_info_dv, 3, 2);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF0, avi.db1_scan_info, 5, 4);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_colorimetry, 7, 6);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_aspect_ratio, 5, 4);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF1, avi.db2_active_fmt_ar, 3, 0);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_itc, 7, 7);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_ec, 6, 4);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_q_range, 3, 2);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVICONF2, avi.db3_nup_scaling, 1, 0);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_AVIVID, avi.db4_videocode, 6, 0);
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, avi.db5_pixel_repeat, 3, 0);
|
||||
hdmi_avi_infoframe_pack(frame, data, sizeof(data));
|
||||
|
||||
print_hex_dump_debug("AVI: ", DUMP_PREFIX_NONE, 16, 1, data,
|
||||
HDMI_INFOFRAME_SIZE(AVI), false);
|
||||
|
||||
ptr = data + HDMI_INFOFRAME_HEADER_SIZE;
|
||||
|
||||
y = (ptr[0] >> 5) & 0x3;
|
||||
a = (ptr[0] >> 4) & 0x1;
|
||||
b = (ptr[0] >> 2) & 0x3;
|
||||
s = (ptr[0] >> 0) & 0x3;
|
||||
|
||||
c = (ptr[1] >> 6) & 0x3;
|
||||
m = (ptr[1] >> 4) & 0x3;
|
||||
r = (ptr[1] >> 0) & 0x3;
|
||||
|
||||
itc = (ptr[2] >> 7) & 0x1;
|
||||
ec = (ptr[2] >> 4) & 0x7;
|
||||
q = (ptr[2] >> 2) & 0x3;
|
||||
sc = (ptr[2] >> 0) & 0x3;
|
||||
|
||||
vic = ptr[3];
|
||||
|
||||
yq = (ptr[4] >> 6) & 0x3;
|
||||
cn = (ptr[4] >> 4) & 0x3;
|
||||
pr = (ptr[4] >> 0) & 0xf;
|
||||
|
||||
hdmi_write_reg(base, HDMI_CORE_FC_AVICONF0,
|
||||
(a << 6) | (s << 4) | (b << 2) | (y << 0));
|
||||
|
||||
hdmi_write_reg(base, HDMI_CORE_FC_AVICONF1,
|
||||
(c << 6) | (m << 4) | (r << 0));
|
||||
|
||||
hdmi_write_reg(base, HDMI_CORE_FC_AVICONF2,
|
||||
(itc << 7) | (ec << 4) | (q << 2) | (sc << 0));
|
||||
|
||||
hdmi_write_reg(base, HDMI_CORE_FC_AVIVID, vic);
|
||||
|
||||
hdmi_write_reg(base, HDMI_CORE_FC_AVICONF3,
|
||||
(yq << 2) | (cn << 0));
|
||||
|
||||
REG_FLD_MOD(base, HDMI_CORE_FC_PRCONF, pr, 3, 0);
|
||||
}
|
||||
|
||||
static void hdmi_core_csc_config(struct hdmi_core_data *core,
|
||||
@ -497,10 +513,8 @@ static void hdmi_core_configure_range(struct hdmi_core_data *core)
|
||||
|
||||
/* support limited range with 24 bit color depth for now */
|
||||
csc_coeff = csc_table_deepcolor[0];
|
||||
core->avi_cfg.db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_LR;
|
||||
|
||||
hdmi_core_csc_config(core, csc_coeff);
|
||||
hdmi_core_aux_infoframe_avi_config(core);
|
||||
}
|
||||
|
||||
static void hdmi_core_enable_video_path(struct hdmi_core_data *core)
|
||||
@ -591,11 +605,10 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
struct omap_video_timings video_timing;
|
||||
struct hdmi_video_format video_format;
|
||||
struct hdmi_core_vid_config v_core_cfg;
|
||||
struct hdmi_core_infoframe_avi *avi_cfg = &core->avi_cfg;
|
||||
|
||||
hdmi_core_mask_interrupts(core);
|
||||
|
||||
hdmi_core_init(&v_core_cfg, avi_cfg, cfg);
|
||||
hdmi_core_init(&v_core_cfg, cfg);
|
||||
|
||||
hdmi_wp_init_vid_fmt_timings(&video_format, &video_timing, cfg);
|
||||
|
||||
@ -608,7 +621,9 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
|
||||
hdmi_wp_video_config_interface(wp, &video_timing);
|
||||
|
||||
/* support limited range with 24 bit color depth for now */
|
||||
hdmi_core_configure_range(core);
|
||||
cfg->infoframe.quantization_range = HDMI_QUANTIZATION_RANGE_LIMITED;
|
||||
|
||||
/*
|
||||
* configure core video part, set software reset in the core
|
||||
@ -621,29 +636,8 @@ void hdmi5_configure(struct hdmi_core_data *core, struct hdmi_wp_data *wp,
|
||||
hdmi_core_config_csc(core);
|
||||
hdmi_core_config_video_sampler(core);
|
||||
|
||||
/*
|
||||
* configure packet info frame video see doc CEA861-D page 65
|
||||
*/
|
||||
avi_cfg->db1_format = HDMI_INFOFRAME_AVI_DB1Y_RGB;
|
||||
avi_cfg->db1_active_info =
|
||||
HDMI_INFOFRAME_AVI_DB1A_ACTIVE_FORMAT_OFF;
|
||||
avi_cfg->db1_bar_info_dv = HDMI_INFOFRAME_AVI_DB1B_NO;
|
||||
avi_cfg->db1_scan_info = HDMI_INFOFRAME_AVI_DB1S_0;
|
||||
avi_cfg->db2_colorimetry = HDMI_INFOFRAME_AVI_DB2C_NO;
|
||||
avi_cfg->db2_aspect_ratio = HDMI_INFOFRAME_AVI_DB2M_NO;
|
||||
avi_cfg->db2_active_fmt_ar = HDMI_INFOFRAME_AVI_DB2R_SAME;
|
||||
avi_cfg->db3_itc = HDMI_INFOFRAME_AVI_DB3ITC_NO;
|
||||
avi_cfg->db3_ec = HDMI_INFOFRAME_AVI_DB3EC_XVYUV601;
|
||||
avi_cfg->db3_q_range = HDMI_INFOFRAME_AVI_DB3Q_DEFAULT;
|
||||
avi_cfg->db3_nup_scaling = HDMI_INFOFRAME_AVI_DB3SC_NO;
|
||||
avi_cfg->db4_videocode = cfg->cm.code;
|
||||
avi_cfg->db5_pixel_repeat = HDMI_INFOFRAME_AVI_DB5PR_NO;
|
||||
avi_cfg->db6_7_line_eoftop = 0;
|
||||
avi_cfg->db8_9_line_sofbottom = 0;
|
||||
avi_cfg->db10_11_pixel_eofleft = 0;
|
||||
avi_cfg->db12_13_pixel_sofright = 0;
|
||||
|
||||
hdmi_core_aux_infoframe_avi_config(core);
|
||||
if (cfg->hdmi_dvi_mode == HDMI_HDMI)
|
||||
hdmi_core_write_avi_infoframe(core, &cfg->infoframe);
|
||||
|
||||
hdmi_core_enable_video_path(core);
|
||||
|
||||
|
@ -1,18 +1,4 @@
|
||||
|
||||
/*
|
||||
* Logic for the below structure :
|
||||
* user enters the CEA or VESA timings by specifying the HDMI/DVI code.
|
||||
* There is a correspondence between CEA/VESA timing and code, please
|
||||
* refer to section 6.3 in HDMI 1.3 specification for timing code.
|
||||
*
|
||||
* In the below structure, cea_vesa_timings corresponds to all OMAP4
|
||||
* supported CEA and VESA timing values.code_cea corresponds to the CEA
|
||||
* code, It is used to get the timing from cea_vesa_timing array.Similarly
|
||||
* with code_vesa. Code_index is used for back mapping, that is once EDID
|
||||
* is read from the TV, EDID is parsed to find the timing values and then
|
||||
* map it to corresponding CEA or VESA index.
|
||||
*/
|
||||
|
||||
#define DSS_SUBSYS_NAME "HDMI"
|
||||
|
||||
#include <linux/kernel.h>
|
||||
@ -22,308 +8,6 @@
|
||||
|
||||
#include "hdmi.h"
|
||||
|
||||
static const struct hdmi_config cea_timings[] = {
|
||||
{
|
||||
{ 640, 480, 25200000, 96, 16, 48, 2, 10, 33,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 1, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 720, 480, 27027000, 62, 16, 60, 6, 9, 30,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 2, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 4, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 540, 74250000, 44, 88, 148, 5, 2, 15,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
true, },
|
||||
{ 5, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1440, 240, 27027000, 124, 38, 114, 3, 4, 15,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
true, },
|
||||
{ 6, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1080, 148500000, 44, 88, 148, 5, 4, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 16, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 720, 576, 27000000, 64, 12, 68, 5, 5, 39,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 17, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1280, 720, 74250000, 40, 440, 220, 5, 5, 20,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 19, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 540, 74250000, 44, 528, 148, 5, 2, 15,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
true, },
|
||||
{ 20, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1440, 288, 27000000, 126, 24, 138, 3, 2, 19,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
true, },
|
||||
{ 21, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1440, 576, 54000000, 128, 24, 136, 5, 5, 39,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 29, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1080, 148500000, 44, 528, 148, 5, 4, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 31, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1080, 74250000, 44, 638, 148, 5, 4, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 32, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 2880, 480, 108108000, 248, 64, 240, 6, 9, 30,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 35, HDMI_HDMI },
|
||||
},
|
||||
{
|
||||
{ 2880, 576, 108000000, 256, 48, 272, 5, 5, 39,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 37, HDMI_HDMI },
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hdmi_config vesa_timings[] = {
|
||||
/* VESA From Here */
|
||||
{
|
||||
{ 640, 480, 25175000, 96, 16, 48, 2, 11, 31,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 4, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 800, 600, 40000000, 128, 40, 88, 4, 1, 23,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 9, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 848, 480, 33750000, 112, 16, 112, 8, 6, 23,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0xE, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 768, 79500000, 128, 64, 192, 7, 3, 20,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x17, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 800, 83500000, 128, 72, 200, 6, 3, 22,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x1C, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1360, 768, 85500000, 112, 64, 256, 6, 3, 18,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x27, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 960, 108000000, 112, 96, 312, 3, 1, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x20, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 1024, 108000000, 112, 48, 248, 3, 1, 38,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x23, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1024, 768, 65000000, 136, 24, 160, 6, 3, 29,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x10, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1400, 1050, 121750000, 144, 88, 232, 4, 3, 32,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x2A, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1440, 900, 106500000, 152, 80, 232, 6, 3, 25,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x2F, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1680, 1050, 146250000, 176 , 104, 280, 6, 3, 30,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_LOW,
|
||||
false, },
|
||||
{ 0x3A, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1366, 768, 85500000, 143, 70, 213, 3, 3, 24,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x51, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1080, 148500000, 44, 148, 80, 5, 4, 36,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x52, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 768, 68250000, 32, 48, 80, 7, 3, 12,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x16, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1400, 1050, 101000000, 32, 48, 80, 4, 3, 23,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x29, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1680, 1050, 119000000, 32, 48, 80, 6, 3, 21,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x39, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 800, 79500000, 32, 48, 80, 6, 3, 14,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x1B, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1280, 720, 74250000, 40, 110, 220, 5, 5, 20,
|
||||
OMAPDSS_SIG_ACTIVE_HIGH, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x55, HDMI_DVI },
|
||||
},
|
||||
{
|
||||
{ 1920, 1200, 154000000, 32, 48, 80, 6, 3, 26,
|
||||
OMAPDSS_SIG_ACTIVE_LOW, OMAPDSS_SIG_ACTIVE_HIGH,
|
||||
false, },
|
||||
{ 0x44, HDMI_DVI },
|
||||
},
|
||||
};
|
||||
|
||||
const struct hdmi_config *hdmi_default_timing(void)
|
||||
{
|
||||
return &vesa_timings[0];
|
||||
}
|
||||
|
||||
static const struct hdmi_config *hdmi_find_timing(int code,
|
||||
const struct hdmi_config *timings_arr, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (timings_arr[i].cm.code == code)
|
||||
return &timings_arr[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const struct hdmi_config *hdmi_get_timings(int mode, int code)
|
||||
{
|
||||
const struct hdmi_config *arr;
|
||||
int len;
|
||||
|
||||
if (mode == HDMI_DVI) {
|
||||
arr = vesa_timings;
|
||||
len = ARRAY_SIZE(vesa_timings);
|
||||
} else {
|
||||
arr = cea_timings;
|
||||
len = ARRAY_SIZE(cea_timings);
|
||||
}
|
||||
|
||||
return hdmi_find_timing(code, arr, len);
|
||||
}
|
||||
|
||||
static bool hdmi_timings_compare(struct omap_video_timings *timing1,
|
||||
const struct omap_video_timings *timing2)
|
||||
{
|
||||
int timing1_vsync, timing1_hsync, timing2_vsync, timing2_hsync;
|
||||
|
||||
if ((DIV_ROUND_CLOSEST(timing2->pixelclock, 1000000) ==
|
||||
DIV_ROUND_CLOSEST(timing1->pixelclock, 1000000)) &&
|
||||
(timing2->x_res == timing1->x_res) &&
|
||||
(timing2->y_res == timing1->y_res)) {
|
||||
|
||||
timing2_hsync = timing2->hfp + timing2->hsw + timing2->hbp;
|
||||
timing1_hsync = timing1->hfp + timing1->hsw + timing1->hbp;
|
||||
timing2_vsync = timing2->vfp + timing2->vsw + timing2->vbp;
|
||||
timing1_vsync = timing1->vfp + timing1->vsw + timing1->vbp;
|
||||
|
||||
DSSDBG("timing1_hsync = %d timing1_vsync = %d"\
|
||||
"timing2_hsync = %d timing2_vsync = %d\n",
|
||||
timing1_hsync, timing1_vsync,
|
||||
timing2_hsync, timing2_vsync);
|
||||
|
||||
if ((timing1_hsync == timing2_hsync) &&
|
||||
(timing1_vsync == timing2_vsync)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct hdmi_cm hdmi_get_code(struct omap_video_timings *timing)
|
||||
{
|
||||
int i;
|
||||
struct hdmi_cm cm = {-1};
|
||||
DSSDBG("hdmi_get_code\n");
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(cea_timings); i++) {
|
||||
if (hdmi_timings_compare(timing, &cea_timings[i].timings)) {
|
||||
cm = cea_timings[i].cm;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < ARRAY_SIZE(vesa_timings); i++) {
|
||||
if (hdmi_timings_compare(timing, &vesa_timings[i].timings)) {
|
||||
cm = vesa_timings[i].cm;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
end:
|
||||
return cm;
|
||||
}
|
||||
|
||||
int hdmi_parse_lanes_of(struct platform_device *pdev, struct device_node *ep,
|
||||
struct hdmi_phy_data *phy)
|
||||
{
|
||||
|
@ -932,7 +932,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev,
|
||||
goto release_irq;
|
||||
}
|
||||
|
||||
clk_enable(info->clk);
|
||||
clk_prepare_enable(info->clk);
|
||||
dprintk("got and enabled clock\n");
|
||||
|
||||
usleep_range(1000, 1100);
|
||||
@ -996,7 +996,7 @@ static int s3c24xxfb_probe(struct platform_device *pdev,
|
||||
free_video_memory:
|
||||
s3c2410fb_unmap_video_memory(fbinfo);
|
||||
release_clock:
|
||||
clk_disable(info->clk);
|
||||
clk_disable_unprepare(info->clk);
|
||||
clk_put(info->clk);
|
||||
release_irq:
|
||||
free_irq(irq, info);
|
||||
@ -1038,7 +1038,7 @@ static int s3c2410fb_remove(struct platform_device *pdev)
|
||||
s3c2410fb_unmap_video_memory(fbinfo);
|
||||
|
||||
if (info->clk) {
|
||||
clk_disable(info->clk);
|
||||
clk_disable_unprepare(info->clk);
|
||||
clk_put(info->clk);
|
||||
info->clk = NULL;
|
||||
}
|
||||
@ -1070,7 +1070,7 @@ static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
|
||||
* before the clock goes off again (bjd) */
|
||||
|
||||
usleep_range(1000, 1100);
|
||||
clk_disable(info->clk);
|
||||
clk_disable_unprepare(info->clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1080,7 +1080,7 @@ static int s3c2410fb_resume(struct platform_device *dev)
|
||||
struct fb_info *fbinfo = platform_get_drvdata(dev);
|
||||
struct s3c2410fb_info *info = fbinfo->par;
|
||||
|
||||
clk_enable(info->clk);
|
||||
clk_prepare_enable(info->clk);
|
||||
usleep_range(1000, 1100);
|
||||
|
||||
s3c2410fb_init_registers(fbinfo);
|
||||
|
@ -1511,7 +1511,7 @@ SiS_Get310DRAMType(struct SiS_Private *SiS_Pr)
|
||||
} else if(SiS_Pr->ChipType >= SIS_340) {
|
||||
/* TODO */
|
||||
data = 0;
|
||||
} if(SiS_Pr->ChipType >= SIS_661) {
|
||||
} else if(SiS_Pr->ChipType >= SIS_661) {
|
||||
if(SiS_Pr->SiS_ROMNew) {
|
||||
data = ((SiS_GetReg(SiS_Pr->SiS_P3d4,0x78) & 0xc0) >> 6);
|
||||
} else {
|
||||
|
@ -1572,10 +1572,6 @@ sisfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
|
||||
/* Adapt RGB settings */
|
||||
sisfb_bpp_to_var(ivideo, var);
|
||||
|
||||
/* Sanity check for offsets */
|
||||
if(var->xoffset < 0) var->xoffset = 0;
|
||||
if(var->yoffset < 0) var->yoffset = 0;
|
||||
|
||||
if(var->xres > var->xres_virtual)
|
||||
var->xres_virtual = var->xres;
|
||||
|
||||
|
@ -553,7 +553,7 @@ static inline struct apertures_struct *alloc_apertures(unsigned int max_num) {
|
||||
#define fb_memcpy_fromfb sbus_memcpy_fromio
|
||||
#define fb_memcpy_tofb sbus_memcpy_toio
|
||||
|
||||
#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__)
|
||||
#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || defined(__avr32__) || defined(__bfin__) || defined(__arm__)
|
||||
|
||||
#define fb_readb __raw_readb
|
||||
#define fb_readw __raw_readw
|
||||
|
@ -61,6 +61,7 @@ struct omap_overlay_manager;
|
||||
struct dss_lcd_mgr_config;
|
||||
struct snd_aes_iec958;
|
||||
struct snd_cea_861_aud_if;
|
||||
struct hdmi_avi_infoframe;
|
||||
|
||||
enum omap_display_type {
|
||||
OMAP_DISPLAY_TYPE_NONE = 0,
|
||||
@ -631,6 +632,10 @@ struct omapdss_hdmi_ops {
|
||||
int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
|
||||
bool (*detect)(struct omap_dss_device *dssdev);
|
||||
|
||||
int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
|
||||
int (*set_infoframe)(struct omap_dss_device *dssdev,
|
||||
const struct hdmi_avi_infoframe *avi);
|
||||
|
||||
/*
|
||||
* Note: These functions might sleep. Do not call while
|
||||
* holding a spinlock/readlock.
|
||||
@ -850,6 +855,10 @@ struct omap_dss_driver {
|
||||
int (*read_edid)(struct omap_dss_device *dssdev, u8 *buf, int len);
|
||||
bool (*detect)(struct omap_dss_device *dssdev);
|
||||
|
||||
int (*set_hdmi_mode)(struct omap_dss_device *dssdev, bool hdmi_mode);
|
||||
int (*set_hdmi_infoframe)(struct omap_dss_device *dssdev,
|
||||
const struct hdmi_avi_infoframe *avi);
|
||||
|
||||
/*
|
||||
* For display drivers that support audio. This encompasses
|
||||
* HDMI and DisplayPort at the moment.
|
||||
|
Loading…
Reference in New Issue
Block a user