====== liteSOM and LCD display ====== {{:github-mark-32px.png?nolink |}} Example available on [[https://github.com/grinn-pub/examples|GitHub]]. Check [[https://github.com/grinn-pub/examples/blob/master/configs/grinn_liteboard_lcd_res_defconfig|liteboard LCD + touchscreen]]. title LCD display and i.MX6UL\nblock diagram node "i.MX6UL" { package "LCD controller" { [LCD data] [LCD sync] } [Backlight] [Touchscreen] } [LCD data] --> RGB888 RGB888 --> [LCD panel] interface "VSYNC, HSYNC\nCLK, EN" as sync [LCD sync] --> sync sync --> [LCD panel] [Backlight] --> PWM PWM --> [LCD panel] [Touchscreen] <-- ADC ADC <-- [LCD panel] ''i.MX6UL'' has several built-in peripherals which can be used to build complete graphical interface: * ''eLCDIF'' - Enhanced LCD Interface, * ''TSC'' - Touch Screen Controller, * ''PWM'' - Pulse Width Modulation. Below you can see how to configure [[litesom:liteboard]] to support [[devices:lcd]] module. Complete example for [[litesom:liteboard]] and [[devices:lcd]] you can find on our [[https://github.com/grinn-pub/examples|GitHub examples repository]]. On [[evm:lcd]] we are using [[https://riverdi.com/product/rvt7-0a800480tnwr00/|RVT7.0A800480TNWR00]] TFT display produced by [[https://riverdi.com/|Riverdi]]. Below you can find short details about this device: * type: TFT/Transmissive/Normally white, * size: 7 inch, * resolution: 800 x 600, * backlight: 21 LEDs, * interface: 24-bit RGB, * touchscreen: resistive. ===== eLCDIF - Enhanced LCD Interface ===== The ''eLCDIF'' can be used to drive a wide range of display devices. It supports: * displays with resolution up to 1366 x 768, * 8/16/18/24 bit LCD TFT displays, * ITU-R BT.656 mode including progressive-to-interlace feature and RGB to YCbCr 4:2:2 color space conversion to support 525/60 and 625/50 operation. {{ :emv:evm_lcd_lcd_zoom.png?direct |}} Basic configuration for ''eLCDIF'' is defined in [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/arch/arm/boot/dts/imx6ul.dtsi|imx6ul.dtsi]] file. lcdif: lcdif@021c8000 { compatible = "fsl,imx6ul-lcdif", "fsl,imx28-lcdif"; reg = <0x021c8000 0x4000>; interrupts = ; clocks = <&clks IMX6UL_CLK_LCDIF_PIX>, <&clks IMX6UL_CLK_LCDIF_APB>, <&clks IMX6UL_CLK_DUMMY>; clock-names = "pix", "axi", "disp_axi"; status = "disabled"; }; which is used by [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/video/fbdev/mxsfb.c|mxsfb driver]]. In the [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/mxsfb.txt|mxsfb.txt]] file you can find documentation with information how to configure ''eLCDIF'' via //device tree// file. In addition please check [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/display/panel/display-timing.txt|display-timing.txt]] file with information how to configure display timings. &iomuxc { pinctrl_lcdif_ctrl: lcdifctrlgrp { fsl,pins = < MX6UL_PAD_LCD_CLK__LCDIF_CLK 0x79 MX6UL_PAD_LCD_ENABLE__LCDIF_ENABLE 0x79 MX6UL_PAD_LCD_HSYNC__LCDIF_HSYNC 0x79 MX6UL_PAD_LCD_VSYNC__LCDIF_VSYNC 0x79 >; }; pinctrl_lcdif_dat: lcdifdatgrp { fsl,pins = < MX6UL_PAD_LCD_DATA00__LCDIF_DATA00 0x79 MX6UL_PAD_LCD_DATA01__LCDIF_DATA01 0x79 [...] MX6UL_PAD_LCD_DATA23__LCDIF_DATA23 0x79 >; }; }; &lcdif { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_lcdif_dat &pinctrl_lcdif_ctrl>; display = <&display0>; status = "okay"; display0: display { bits-per-pixel = <32>; bus-width = <24>; display-timings { native-mode = <&timing0>; timing0: timing0 { clock-frequency = <30000000>; hactive = <800>; vactive = <480>; hfront-porch = <210>; hsync-len = <2>; hback-porch = <46>; vfront-porch = <22>; vsync-len = <2>; vback-porch = <23>; hsync-active = <1>; vsync-active = <1>; de-active = <1>; pixelclk-active = <0>; }; }; }; }; In our case we have to connect ''eLCDIF'' with LCD display via 24-bits (RGB888) data bus. In addition ''eLCDIF'' should generate vertical and horizontal synchronization signals, data enable strobe and main clock signal for display controller. Nodes ''pinctrl_lcdif_ctrl'' and ''pinctrl_lcdif_dat'' are used to configure ''IOMUX Controller''. [[litesom:devicetree#IOMUX configuration|Here]] you can read more about ''IOMUX Conctroller'' configuration via //device tree//. Node ''lcdif'' contains complete configuration for used LCD display. Most of configuration values are self-explaining. To help you to understand timing configuration please check following image. +----------+---------------------------------+----------+-------+ | | ↑ | | | | | | 46 lines | | | | | ↓ | | | +----------###################################----------+-------+ | # ↑ # | | | 46 # | # 210 | 2 | | pixels # | 800 pixels # pixels | pixels| |<-------->#<-------+----------------------->#<-------->|<----->| | # | # | | | # | 480 pixels # | | | # ↓ # | | +----------###################################----------+-------+ | | ↑ | | | | | | 22 lines | | | | | ↓ | | | +----------+---------------------------------+----------+-------+ | | ↑ | | | | | | 2 lines | | | | | ↓ | | | +----------+---------------------------------+----------+-------+ ;;# (based on: Documentation/devicetree/bindings/video/display-timing.txt) ;;# In addition to //device tree// please remember to enable ''mxsfb'' driver (via ''CONFIG_FB_MXS'') located in -> Device Drivers -> Graphics support -> Frame buffer Devices -> MXS LCD framebuffer support ===== TSC - Touch Screen Controller ===== ''i.MX6UL'' touchscreen controller can be used with 4-wire and 5-wire resistive touchscreens. Built-in A/D converter has 8-bit/10-bit/12-bit resolution. Parameters like pre-charge or de-glitch are fully configurable. From software point of view ''TSC'' is controlled via ''imx6ul-tsc'' driver (see [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/input/touchscreen/imx6ul_tsc.c|imx6ul_tsc.c]]). In [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt|imx6ul_tsc.txt]] file you can find information how to configure //device tree// for this peripheral. &iomuxc { pinctrl_tsc: tscgrp { fsl,pins = < MX6UL_PAD_GPIO1_IO01__GPIO1_IO01 0xb0 MX6UL_PAD_GPIO1_IO02__GPIO1_IO02 0xb0 MX6UL_PAD_GPIO1_IO03__GPIO1_IO03 0xb0 MX6UL_PAD_GPIO1_IO04__GPIO1_IO04 0xb0 >; }; }; &tsc { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_tsc>; status = "okay"; xnur-gpio = <&gpio1 4 GPIO_ACTIVE_LOW>; measure_delay_time = <0xffff>; pre_charge_time = <0xfff>; }; Node ''pinctrl_tsc'' is of course ''IOMUX Controller'' configuration. ''tsc'' node is used to configure ''imx6ul-tsc'' driver. In most cases it's using default settings from [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/input/touchscreen/imx6ul_tsc.txt|imx6ul-tsc documentation]]. ''xnur-gpio'' parameter is adjusted to the configuration required by [[litesom:liteboard]] design. {{ :litesom:devicetree:liteboard_tsc.png?direct |}} To compile [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/input/touchscreen/imx6ul_tsc.c|imx6ul_tsc.c]] driver please select ''CONFIG_TOUCHSCREEN_IMX6UL_TSC'' option located in -> Device Drivers -> Input device support -> Generic input layer (needed for keyboard, mouse, ...) -> Touchscreens -> Freescale i.MX6UL touchscreen controller ===== Backlight ===== package "liteboard" { [PWM backlight driver] -> [PWM] } package "Display" { [PWM] -> [Backlight] } / { backlight { compatible = "pwm-backlight"; pwms = <&pwm2 0 5000000>; brightness-levels = <0 4 8 16 32 64 128 255>; default-brightness-level = <6>; status = "okay"; }; }; &iomuxc { pinctrl_pwm2: pwm2 { fsl,pins = < MX6UL_PAD_GPIO1_IO09__PWM2_OUT 0x110b0 >; }; }; &pwm2 { pinctrl-names = "default"; pinctrl-0 = <&pinctrl_pwm2>; status = "okay"; clocks = <&clks IMX6UL_CLK_PWM2>, <&clks IMX6UL_CLK_PWM2>; }; On [[litesom:liteboard]] you can find dedicated LCD backlight boot converter (see [[https://www.ti.com/product/TPS61042|TPS61042]]) controlled by [[:litesom]] via ''PWM2 output'' pin. {{ :litesom:devicetree:litesom_backlight_driver.png?500 |}} Backlight can be controlled directly via ''PWM driver'' but additional ''PWM backlight driver'' will simplify backlight configuration. Node ''backlight'' is documented in [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/leds/backlight/pwm-backlight.txt|pwm-backlight.txt]] file. Backlight configured as presented here will: * generate PWM with 200Hz frequency (period 5000000 ns), * use ''PWM2'' peripheral as backlight controller, * define eight allowed backlight levels: 0%, 2%, 3%, 6%, 13%, 25%, 50%, 100%, * use 50% as default backlight level. Node ''pinctrl_pwm2'' is information for ''IOMUX controller'' how to configure ''PWM2'' output. On [[litesom:liteboard]] we are using ''GPIO1__IO09''. {{ :litesom:devicetree:litesom_backlight.png?400 |}} Node ''pwm2'' is configured as documented in [[https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/devicetree/bindings/pwm/pwm.txt|pwm.txt]].