diff options
Diffstat (limited to 'drivers/video')
28 files changed, 412 insertions, 2278 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 4ecc158..c841b99 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -4,7 +4,7 @@ menu "Graphics support" -config DM_VIDEO +config VIDEO bool "Enable driver model support for LCD/video" depends on DM help @@ -14,9 +14,10 @@ config DM_VIDEO option compiles in the video uclass and routes all LCD/video access through this. +if VIDEO + config VIDEO_LOGO bool "Show the U-Boot logo on the display" - depends on DM_VIDEO default y if !SPLASH_SCREEN select VIDEO_BMP_RLE8 help @@ -27,7 +28,6 @@ config VIDEO_LOGO config BACKLIGHT bool "Enable panel backlight uclass support" - depends on DM_VIDEO default y help This provides backlight uclass driver that enables basic panel @@ -35,7 +35,6 @@ config BACKLIGHT config VIDEO_PCI_DEFAULT_FB_SIZE hex "Default framebuffer size to use if no drivers request it" - depends on DM_VIDEO default 0x1000000 if X86 && PCI default 0 if !(X86 && PCI) help @@ -54,7 +53,6 @@ config VIDEO_PCI_DEFAULT_FB_SIZE config VIDEO_COPY bool "Enable copying the frame buffer to a hardware copy" - depends on DM_VIDEO help On some machines (e.g. x86), reading from the frame buffer is very slow because it is uncached. To improve performance, this feature @@ -85,17 +83,8 @@ config BACKLIGHT_GPIO it understands the standard device tree (leds/backlight/gpio-backlight.txt) -config CMD_VIDCONSOLE - bool "Enable vidconsole commands lcdputs and setcurs" - depends on DM_VIDEO - default y - help - Enabling this will provide 'setcurs' and 'lcdputs' commands which - support cursor positioning and drawing strings on video framebuffer. - config VIDEO_BPP8 bool "Support 8-bit-per-pixel displays" - depends on DM_VIDEO default y help Support drawing text and bitmaps onto a 8-bit-per-pixel display. @@ -105,7 +94,6 @@ config VIDEO_BPP8 config VIDEO_BPP16 bool "Support 16-bit-per-pixel displays" - depends on DM_VIDEO default y help Support drawing text and bitmaps onto a 16-bit-per-pixel display. @@ -115,7 +103,6 @@ config VIDEO_BPP16 config VIDEO_BPP32 bool "Support 32-bit-per-pixel displays" - depends on DM_VIDEO default y help Support drawing text and bitmaps onto a 32-bit-per-pixel display. @@ -125,7 +112,6 @@ config VIDEO_BPP32 config VIDEO_ANSI bool "Support ANSI escape sequences in video console" - depends on DM_VIDEO default y help Enable ANSI escape sequence decoding for a more fully functional @@ -133,7 +119,6 @@ config VIDEO_ANSI config VIDEO_MIPI_DSI bool "Support MIPI DSI interface" - depends on DM_VIDEO help Support MIPI DSI interface for driving a MIPI compatible device. The MIPI Display Serial Interface (MIPI DSI) defines a high-speed @@ -141,8 +126,7 @@ config VIDEO_MIPI_DSI config CONSOLE_NORMAL bool "Support a simple text console" - depends on DM_VIDEO - default y if DM_VIDEO + default y help Support drawing text on the frame buffer console so that it can be used as a console. Rotation is not supported by this driver (see @@ -151,7 +135,6 @@ config CONSOLE_NORMAL config CONSOLE_ROTATION bool "Support rotated displays" - depends on DM_VIDEO help Sometimes, for example if the display is mounted in portrait mode or even if it's mounted landscape but rotated by 180degree, @@ -164,23 +147,12 @@ config CONSOLE_ROTATION config CONSOLE_TRUETYPE bool "Support a console that uses TrueType fonts" - depends on DM_VIDEO help TrueTrype fonts can provide outline-drawing capability rather than needing to provide a bitmap for each font and size that is needed. With this option you can adjust the text size and use a variety of fonts. Note that this is noticeably slower than with normal console. -config DM_PANEL_HX8238D - bool "Enable Himax HX-8238D LCD driver" - depends on DM_VIDEO - help - Support for HX-8238D LCD Panel - The HX8238-D is a single chip controller and driver LSI that - integrates the power circuit. - It can drive a maximum 960x240 dot graphics on a-TFT panel - displays in 16M colors with dithering. - config CONSOLE_TRUETYPE_SIZE int "TrueType font size" depends on CONSOLE_TRUETYPE @@ -194,6 +166,21 @@ config CONSOLE_TRUETYPE_SIZE method to select the display's physical size, which would allow U-Boot to calculate the correct font size. +config CONSOLE_TRUETYPE_MAX_METRICS + int "TrueType maximum number of font / size combinations" + depends on CONSOLE_TRUETYPE + default 10 if EXPO + default 1 + help + This sets the number of font / size combinations which can be used by + the console. For simple console use a single font is enough. When + boot menus are in use, this may need to be increased. + + Note that a separate entry is needed for each font size, even if the + font itself is the same. This is because the entry caches various + font metrics which are expensive to regenerate each time the font + size changes. + config SYS_WHITE_ON_BLACK bool "Display console as white on a black background" default y if ARCH_AT91 || ARCH_EXYNOS || ARCH_ROCKCHIP || ARCH_TEGRA || X86 || ARCH_SUNXI @@ -213,7 +200,6 @@ config NO_FB_CLEAR config PANEL bool "Enable panel uclass support" - depends on DM_VIDEO default y help This provides panel uclass driver that enables basic panel support. @@ -226,11 +212,20 @@ config SIMPLE_PANEL This turns on a simple panel driver that enables a compatible video panel. +config PANEL_HX8238D + bool "Enable Himax HX-8238D LCD driver" + depends on PANEL + help + Support for HX-8238D LCD Panel + The HX8238-D is a single chip controller and driver LSI that + integrates the power circuit. + It can drive a maximum 960x240 dot graphics on a-TFT panel + displays in 16M colors with dithering. + source "drivers/video/fonts/Kconfig" config VIDCONSOLE_AS_LCD bool "Use 'vidconsole' when CONFIG_VIDCONSOLE_AS_NAME string is seen in stdout" - depends on DM_VIDEO help This is a work-around for boards which have 'lcd' or 'vga' in their stdout environment variable, but have moved to use driver model for @@ -423,7 +418,7 @@ config VIDEO_LCD_ANX9804 config ATMEL_LCD bool "Atmel LCD panel support" - depends on LCD && ARCH_AT91 + depends on ARCH_AT91 config ATMEL_LCD_BGR555 bool "Display in BGR555 mode" @@ -440,7 +435,6 @@ config VIDEO_BCM2835 config VIDEO_LCD_ORISETECH_OTM8009A bool "OTM8009A DSI LCD panel support" - depends on DM_VIDEO select VIDEO_MIPI_DSI help Say Y here if you want to enable support for Orise Technology @@ -448,7 +442,6 @@ config VIDEO_LCD_ORISETECH_OTM8009A config VIDEO_LCD_RAYDIUM_RM68200 bool "RM68200 DSI LCD panel support" - depends on DM_VIDEO select VIDEO_MIPI_DSI help Say Y here if you want to enable support for Raydium RM68200 @@ -484,7 +477,6 @@ config VIDEO_LCD_SSD2828_RESET config VIDEO_LCD_TDO_TL070WSH30 bool "TDO TL070WSH30 DSI LCD panel support" - depends on DM_VIDEO select VIDEO_MIPI_DSI help Say Y here if you want to enable support for TDO TL070WSH30 @@ -581,8 +573,6 @@ config ATMEL_HLCD help HLCDC supports video output to an attached LCD panel. -source "drivers/video/ti/Kconfig" - source "drivers/video/exynos/Kconfig" config LOGICORE_DP_TX @@ -624,7 +614,7 @@ source "drivers/video/rockchip/Kconfig" config VIDEO_ARM_MALIDP bool "Enable Arm Mali Display Processor support" - depends on DM_VIDEO && OF_CONTROL + depends on OF_CONTROL select VEXPRESS_CLK help This enables support for Arm Ltd Mali Display Processors from @@ -652,7 +642,6 @@ config VIDEO_TEGRA20 config VIDEO_TEGRA124 bool "Enable video support on Tegra124" - depends on DM_VIDEO help Tegra124 supports many video output options including eDP and HDMI. At present only eDP is supported by U-Boot. This option @@ -665,7 +654,6 @@ source "drivers/video/imx/Kconfig" config VIDEO_MXS bool "Enable video support on i.MX28/i.MX6UL/i.MX7 SoCs" - depends on DM_VIDEO help Enable framebuffer driver for i.MX28/i.MX6UL/i.MX7 processors @@ -679,14 +667,14 @@ config VIDEO_NX config VIDEO_SEPS525 bool "Enable video support for Seps525" - depends on DM_VIDEO && DM_GPIO + depends on DM_GPIO help Enable support for the Syncoam PM-OLED display driver (RGB 160x128). Currently driver is supporting only SPI interface. config VIDEO_ZYNQMP_DPSUB bool "Enable video support for ZynqMP Display Port" - depends on DM_VIDEO && ZYNQMP_POWER_DOMAIN + depends on ZYNQMP_POWER_DOMAIN help Enable support for Xilinx ZynqMP Display Port. Currently this file is used as placeholder for driver. The main reason is to record @@ -694,18 +682,8 @@ config VIDEO_ZYNQMP_DPSUB source "drivers/video/nexell/Kconfig" -config VIDEO - bool "Enable legacy video support" - depends on !DM_VIDEO - help - Define this for video support, without using driver model. Some - drivers use this because they are not yet converted to driver - model. Video drivers typically provide a colour text console and - cursor. - config CONSOLE_SCROLL_LINES int "Number of lines to scroll the console by" - depends on DM_VIDEO || LCD default 1 help When the console need to be scrolled, this is the number of @@ -713,26 +691,6 @@ config CONSOLE_SCROLL_LINES console jump but can help speed up operation when scrolling is slow. -config LCD - bool "Enable legacy LCD support" - help - Define this to enable LCD support (for output to LCD display). - You will also need to select an LCD driver using an additional - CONFIG option. See the README for details. Drives which have been - converted to driver model will instead used CONFIG_DM_VIDEO. - -config LCD_INFO - bool "Show LCD info on-screen" - depends on LCD - -config LCD_LOGO - bool "Show a logo on screen" - depends on LCD - -config LCD_INFO_BELOW_LOGO - bool "Show LCD info below the on-screen logo" - depends on LCD_INFO && LCD_LOGO - config VIDEO_DW_HDMI bool help @@ -783,7 +741,6 @@ config VIDEO_DT_SIMPLEFB config VIDEO_MCDE_SIMPLE bool "Simple driver for ST-Ericsson MCDE with preconfigured display" - depends on DM_VIDEO help Enables a simple display driver for ST-Ericsson MCDE (Multichannel Display Engine), which reads the configuration from @@ -831,23 +788,10 @@ config SPLASH_SCREEN image data before it is processed and sent to the frame buffer by U-Boot. Define your own version to use this feature. -config SPLASHIMAGE_GUARD - bool "Support unaligned BMP images" - depends on SPLASH_SCREEN - help - If this option is set, then U-Boot will prevent the environment - variable "splashimage" from being set to a problematic address - (see doc/README.displaying-bmps). - - This option is useful for targets where, due to alignment - restrictions, an improperly aligned BMP image will cause a data - abort. If you think you will not have problems with unaligned - accesses (for example because your toolchain prevents them) - there is no need to set this option. +if SPLASH_SCREEN config SPLASH_SCREEN_ALIGN bool "Allow positioning the splash image anywhere on the display" - depends on SPLASH_SCREEN || CMD_BMP help If this option is set the splash image can be freely positioned on the screen. Environment variable "splashpos" specifies the @@ -867,9 +811,17 @@ config SPLASH_SCREEN_ALIGN => vertically centered image at x = dspWidth - bmpWidth - 9 +config HIDE_LOGO_VERSION + bool "Hide the version information on the splash screen" + help + Normally the U-Boot version string is shown on the display when the + splash screen is enabled. This information is not otherwise visible + since video starts up after U-Boot has displayed the initial banner. + + Enable this option to hide this information. + config SPLASH_SOURCE bool "Control the source of the splash image" - depends on SPLASH_SCREEN help Use the splash_source.c library. This library provides facilities to declare board specific splash image locations, routines for loading @@ -900,6 +852,8 @@ config SPLASH_SOURCE In case the environment variable "splashfile" is not defined the default name 'splash.bmp' will be used. +endif # SPLASH_SCREEN + config VIDEO_BMP_GZIP bool "Gzip compressed BMP image support" depends on CMD_BMP || SPLASH_SCREEN @@ -908,35 +862,35 @@ config VIDEO_BMP_GZIP images, gzipped BMP images can be displayed via the splashscreen support or the bmp command. +config VIDEO_LOGO_MAX_SIZE + hex "Maximum size of the bitmap logo in bytes" + default 0x100000 + help + Sets the maximum uncompressed size of the logo. This is needed when + decompressing a BMP file using the gzip algorithm, since it cannot + read the size from the bitmap header. + config VIDEO_BMP_RLE8 bool "Run length encoded BMP image (RLE8) support" - depends on DM_VIDEO help If this option is set, the 8-bit RLE compressed BMP images is supported. config BMP_16BPP bool "16-bit-per-pixel BMP image support" - depends on DM_VIDEO || LCD help Support display of bitmaps file with 16-bit-per-pixel config BMP_24BPP bool "24-bit-per-pixel BMP image support" - depends on DM_VIDEO || LCD help Support display of bitmaps file with 24-bit-per-pixel. config BMP_32BPP bool "32-bit-per-pixel BMP image support" - depends on DM_VIDEO || LCD help Support display of bitmaps file with 32-bit-per-pixel. -config VIDEO_VCXK - bool "Enable VCXK video controller driver support" - help - This enables VCXK driver which can be used with VC2K, VC4K - and VC8K devices on various boards from BuS Elektronik GmbH. +endif # VIDEO endmenu diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 7019b26..40a871d 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -12,10 +12,10 @@ obj-$(CONFIG_CONSOLE_ROTATION) += console_rotate.o obj-$(CONFIG_CONSOLE_TRUETYPE) += console_truetype.o fonts/ obj-$(CONFIG_DISPLAY) += display-uclass.o obj-$(CONFIG_VIDEO_MIPI_DSI) += dsi-host-uclass.o -obj-$(CONFIG_DM_VIDEO) += video-uclass.o vidconsole-uclass.o -obj-$(CONFIG_DM_VIDEO) += video_bmp.o +obj-$(CONFIG_VIDEO) += video-uclass.o vidconsole-uclass.o +obj-$(CONFIG_VIDEO) += video_bmp.o obj-$(CONFIG_PANEL) += panel-uclass.o -obj-$(CONFIG_DM_PANEL_HX8238D) += hx8238d.o +obj-$(CONFIG_PANEL_HX8238D) += hx8238d.o obj-$(CONFIG_SIMPLE_PANEL) += simple_panel.o obj-$(CONFIG_VIDEO_LOGO) += u_boot_logo.o @@ -26,12 +26,10 @@ obj-${CONFIG_EXYNOS_FB} += exynos/ obj-${CONFIG_VIDEO_ROCKCHIP} += rockchip/ obj-${CONFIG_VIDEO_STM32} += stm32/ obj-${CONFIG_VIDEO_TEGRA124} += tegra124/ -obj-y += ti/ obj-$(CONFIG_ATMEL_HLCD) += atmel_hlcdfb.o obj-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o obj-$(CONFIG_IHS_VIDEO_OUT) += ihs_video_out.o -obj-$(CONFIG_LD9040) += ld9040.o obj-$(CONFIG_LG4573) += lg4573.o obj-$(CONFIG_LOGICORE_DP_TX) += logicore_dp_tx.o obj-$(CONFIG_NXP_TDA19988) += tda19988.o @@ -64,7 +62,6 @@ obj-$(CONFIG_VIDEO_DSI_HOST_SANDBOX) += sandbox_dsi_host.o obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o obj-$(CONFIG_VIDEO_SIMPLE) += simplefb.o obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o -obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o obj-$(CONFIG_VIDEO_VESA) += vesa.o obj-$(CONFIG_VIDEO_SEPS525) += seps525.o obj-$(CONFIG_VIDEO_ZYNQMP_DPSUB) += zynqmp_dpsub.o diff --git a/drivers/video/atmel_hlcdfb.c b/drivers/video/atmel_hlcdfb.c index c7b59b7..2bf19a6 100644 --- a/drivers/video/atmel_hlcdfb.c +++ b/drivers/video/atmel_hlcdfb.c @@ -17,238 +17,13 @@ #include <clk.h> #include <dm.h> #include <fdtdec.h> -#include <lcd.h> #include <video.h> #include <wait_bit.h> #include <atmel_hlcdc.h> #include <linux/bug.h> -#if defined(CONFIG_LCD_LOGO) -#include <bmp_logo.h> -#endif - DECLARE_GLOBAL_DATA_PTR; -#ifndef CONFIG_DM_VIDEO - -/* configurable parameters */ -#define ATMEL_LCDC_CVAL_DEFAULT 0xc8 -#define ATMEL_LCDC_DMA_BURST_LEN 8 -#ifndef ATMEL_LCDC_GUARD_TIME -#define ATMEL_LCDC_GUARD_TIME 1 -#endif - -#define ATMEL_LCDC_FIFO_SIZE 512 - -/* - * the CLUT register map as following - * RCLUT(24 ~ 16), GCLUT(15 ~ 8), BCLUT(7 ~ 0) - */ -void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) -{ - writel(panel_info.mmio + ATMEL_LCDC_LUT(regno), - ((red << LCDC_BASECLUT_RCLUT_Pos) & LCDC_BASECLUT_RCLUT_Msk) - | ((green << LCDC_BASECLUT_GCLUT_Pos) & LCDC_BASECLUT_GCLUT_Msk) - | ((blue << LCDC_BASECLUT_BCLUT_Pos) & LCDC_BASECLUT_BCLUT_Msk)); -} - -ushort *configuration_get_cmap(void) -{ -#if defined(CONFIG_LCD_LOGO) - return bmp_logo_palette; -#else - return NULL; -#endif -} - -void lcd_ctrl_init(void *lcdbase) -{ - unsigned long value; - struct lcd_dma_desc *desc; - struct atmel_hlcd_regs *regs; - int ret; - - if (!has_lcdc()) - return; /* No lcdc */ - - regs = (struct atmel_hlcd_regs *)panel_info.mmio; - - /* Disable DISP signal */ - writel(LCDC_LCDDIS_DISPDIS, ®s->lcdc_lcddis); - ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, - false, 1000, false); - if (ret) - printf("%s: %d: Timeout!\n", __func__, __LINE__); - /* Disable synchronization */ - writel(LCDC_LCDDIS_SYNCDIS, ®s->lcdc_lcddis); - ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, - false, 1000, false); - if (ret) - printf("%s: %d: Timeout!\n", __func__, __LINE__); - /* Disable pixel clock */ - writel(LCDC_LCDDIS_CLKDIS, ®s->lcdc_lcddis); - ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, - false, 1000, false); - if (ret) - printf("%s: %d: Timeout!\n", __func__, __LINE__); - /* Disable PWM */ - writel(LCDC_LCDDIS_PWMDIS, ®s->lcdc_lcddis); - ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, - false, 1000, false); - if (ret) - printf("%s: %d: Timeout!\n", __func__, __LINE__); - - /* Set pixel clock */ - value = get_lcdc_clk_rate(0) / panel_info.vl_clk; - if (get_lcdc_clk_rate(0) % panel_info.vl_clk) - value++; - - if (value < 1) { - /* Using system clock as pixel clock */ - writel(LCDC_LCDCFG0_CLKDIV(0) - | LCDC_LCDCFG0_CGDISHCR - | LCDC_LCDCFG0_CGDISHEO - | LCDC_LCDCFG0_CGDISOVR1 - | LCDC_LCDCFG0_CGDISBASE - | panel_info.vl_clk_pol - | LCDC_LCDCFG0_CLKSEL, - ®s->lcdc_lcdcfg0); - - } else { - writel(LCDC_LCDCFG0_CLKDIV(value - 2) - | LCDC_LCDCFG0_CGDISHCR - | LCDC_LCDCFG0_CGDISHEO - | LCDC_LCDCFG0_CGDISOVR1 - | LCDC_LCDCFG0_CGDISBASE - | panel_info.vl_clk_pol, - ®s->lcdc_lcdcfg0); - } - - /* Initialize control register 5 */ - value = 0; - - value |= panel_info.vl_sync; - -#ifndef LCD_OUTPUT_BPP - /* Output is 24bpp */ - value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; -#else - switch (LCD_OUTPUT_BPP) { - case 12: - value |= LCDC_LCDCFG5_MODE_OUTPUT_12BPP; - break; - case 16: - value |= LCDC_LCDCFG5_MODE_OUTPUT_16BPP; - break; - case 18: - value |= LCDC_LCDCFG5_MODE_OUTPUT_18BPP; - break; - case 24: - value |= LCDC_LCDCFG5_MODE_OUTPUT_24BPP; - break; - default: - BUG(); - break; - } -#endif - - value |= LCDC_LCDCFG5_GUARDTIME(ATMEL_LCDC_GUARD_TIME); - value |= (LCDC_LCDCFG5_DISPDLY | LCDC_LCDCFG5_VSPDLYS); - writel(value, ®s->lcdc_lcdcfg5); - - /* Vertical & Horizontal Timing */ - value = LCDC_LCDCFG1_VSPW(panel_info.vl_vsync_len - 1); - value |= LCDC_LCDCFG1_HSPW(panel_info.vl_hsync_len - 1); - writel(value, ®s->lcdc_lcdcfg1); - - value = LCDC_LCDCFG2_VBPW(panel_info.vl_upper_margin); - value |= LCDC_LCDCFG2_VFPW(panel_info.vl_lower_margin - 1); - writel(value, ®s->lcdc_lcdcfg2); - - value = LCDC_LCDCFG3_HBPW(panel_info.vl_left_margin - 1); - value |= LCDC_LCDCFG3_HFPW(panel_info.vl_right_margin - 1); - writel(value, ®s->lcdc_lcdcfg3); - - /* Display size */ - value = LCDC_LCDCFG4_RPF(panel_info.vl_row - 1); - value |= LCDC_LCDCFG4_PPL(panel_info.vl_col - 1); - writel(value, ®s->lcdc_lcdcfg4); - - writel(LCDC_BASECFG0_BLEN_AHB_INCR4 | LCDC_BASECFG0_DLBO, - ®s->lcdc_basecfg0); - - switch (NBITS(panel_info.vl_bpix)) { - case 16: - writel(LCDC_BASECFG1_RGBMODE_16BPP_RGB_565, - ®s->lcdc_basecfg1); - break; - case 32: - writel(LCDC_BASECFG1_RGBMODE_24BPP_RGB_888, - ®s->lcdc_basecfg1); - break; - default: - BUG(); - break; - } - - writel(LCDC_BASECFG2_XSTRIDE(0), ®s->lcdc_basecfg2); - writel(0, ®s->lcdc_basecfg3); - writel(LCDC_BASECFG4_DMA, ®s->lcdc_basecfg4); - - /* Disable all interrupts */ - writel(~0UL, ®s->lcdc_lcdidr); - writel(~0UL, ®s->lcdc_baseidr); - - /* Setup the DMA descriptor, this descriptor will loop to itself */ - desc = (struct lcd_dma_desc *)(lcdbase - 16); - - desc->address = (u32)lcdbase; - /* Disable DMA transfer interrupt & descriptor loaded interrupt. */ - desc->control = LCDC_BASECTRL_ADDIEN | LCDC_BASECTRL_DSCRIEN - | LCDC_BASECTRL_DMAIEN | LCDC_BASECTRL_DFETCH; - desc->next = (u32)desc; - - /* Flush the DMA descriptor if we enabled dcache */ - flush_dcache_range((u32)desc, (u32)desc + sizeof(*desc)); - - writel(desc->address, ®s->lcdc_baseaddr); - writel(desc->control, ®s->lcdc_basectrl); - writel(desc->next, ®s->lcdc_basenext); - writel(LCDC_BASECHER_CHEN | LCDC_BASECHER_UPDATEEN, - ®s->lcdc_basecher); - - /* Enable LCD */ - value = readl(®s->lcdc_lcden); - writel(value | LCDC_LCDEN_CLKEN, ®s->lcdc_lcden); - ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_CLKSTS, - true, 1000, false); - if (ret) - printf("%s: %d: Timeout!\n", __func__, __LINE__); - value = readl(®s->lcdc_lcden); - writel(value | LCDC_LCDEN_SYNCEN, ®s->lcdc_lcden); - ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_LCDSTS, - true, 1000, false); - if (ret) - printf("%s: %d: Timeout!\n", __func__, __LINE__); - value = readl(®s->lcdc_lcden); - writel(value | LCDC_LCDEN_DISPEN, ®s->lcdc_lcden); - ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_DISPSTS, - true, 1000, false); - if (ret) - printf("%s: %d: Timeout!\n", __func__, __LINE__); - value = readl(®s->lcdc_lcden); - writel(value | LCDC_LCDEN_PWMEN, ®s->lcdc_lcden); - ret = wait_for_bit_le32(®s->lcdc_lcdsr, LCDC_LCDSR_PWMSTS, - true, 1000, false); - if (ret) - printf("%s: %d: Timeout!\n", __func__, __LINE__); - - /* Enable flushing if we enabled dcache */ - lcd_set_flush_dcache(1); -} - -#else - enum { LCD_MAX_WIDTH = 1024, LCD_MAX_HEIGHT = 768, @@ -565,5 +340,3 @@ U_BOOT_DRIVER(atmel_hlcdfb) = { .of_to_plat = atmel_hlcdc_of_to_plat, .priv_auto = sizeof(struct atmel_hlcdc_priv), }; - -#endif diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/atmel_lcdfb.c index c38cac1..5a7a54a 100644 --- a/drivers/video/atmel_lcdfb.c +++ b/drivers/video/atmel_lcdfb.c @@ -16,21 +16,18 @@ #include <asm/io.h> #include <asm/arch/gpio.h> #include <asm/arch/clk.h> -#include <lcd.h> #include <bmp_layout.h> #include <atmel_lcdc.h> #include <linux/delay.h> DECLARE_GLOBAL_DATA_PTR; -#ifdef CONFIG_DM_VIDEO enum { /* Maximum LCD size we support */ LCD_MAX_WIDTH = 1366, LCD_MAX_HEIGHT = 768, LCD_MAX_LOG2_BPP = VIDEO_BPP16, }; -#endif struct atmel_fb_priv { struct display_timing timing; @@ -52,69 +49,6 @@ struct atmel_fb_priv { #define lcdc_readl(mmio, reg) __raw_readl((mmio)+(reg)) #define lcdc_writel(mmio, reg, val) __raw_writel((val), (mmio)+(reg)) -#ifndef CONFIG_DM_VIDEO -ushort *configuration_get_cmap(void) -{ - return (ushort *)(panel_info.mmio + ATMEL_LCDC_LUT(0)); -} - -#if defined(CONFIG_BMP_16BPP) && defined(CONFIG_ATMEL_LCD_BGR555) -void fb_put_word(uchar **fb, uchar **from) -{ - *(*fb)++ = (((*from)[0] & 0x1f) << 2) | ((*from)[1] & 0x03); - *(*fb)++ = ((*from)[0] & 0xe0) | (((*from)[1] & 0x7c) >> 2); - *from += 2; -} -#endif - -#ifdef CONFIG_LCD_LOGO -#include <bmp_logo.h> -void lcd_logo_set_cmap(void) -{ - int i; - uint lut_entry; - ushort colreg; - uint *cmap = (uint *)configuration_get_cmap(); - - for (i = 0; i < BMP_LOGO_COLORS; ++i) { - colreg = bmp_logo_palette[i]; -#ifdef CONFIG_ATMEL_LCD_BGR555 - lut_entry = ((colreg & 0x000F) << 11) | - ((colreg & 0x00F0) << 2) | - ((colreg & 0x0F00) >> 7); -#else - lut_entry = ((colreg & 0x000F) << 1) | - ((colreg & 0x00F0) << 3) | - ((colreg & 0x0F00) << 4); -#endif - *(cmap + BMP_LOGO_OFFSET) = lut_entry; - cmap++; - } -} -#endif - -void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) -{ -#if defined(CONFIG_ATMEL_LCD_BGR555) - lcdc_writel(panel_info.mmio, ATMEL_LCDC_LUT(regno), - (red >> 3) | ((green & 0xf8) << 2) | ((blue & 0xf8) << 7)); -#else - lcdc_writel(panel_info.mmio, ATMEL_LCDC_LUT(regno), - (blue >> 3) | ((green & 0xfc) << 3) | ((red & 0xf8) << 8)); -#endif -} - -void lcd_set_cmap(struct bmp_image *bmp, unsigned colors) -{ - int i; - - for (i = 0; i < colors; ++i) { - struct bmp_color_table_entry cte = bmp->color_table[i]; - lcd_setcolreg(i, cte.red, cte.green, cte.blue); - } -} -#endif - static void atmel_fb_init(ulong addr, struct display_timing *timing, int bpix, bool tft, bool cont_pol_low, ulong lcdbase) { @@ -209,41 +143,6 @@ static void atmel_fb_init(ulong addr, struct display_timing *timing, int bpix, (ATMEL_LCDC_GUARD_TIME << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR); } -#ifndef CONFIG_DM_VIDEO -void lcd_ctrl_init(void *lcdbase) -{ - struct display_timing timing; - - timing.flags = 0; - if (!(panel_info.vl_sync & ATMEL_LCDC_INVLINE_INVERTED)) - timing.flags |= DISPLAY_FLAGS_HSYNC_HIGH; - if (!(panel_info.vl_sync & ATMEL_LCDC_INVFRAME_INVERTED)) - timing.flags |= DISPLAY_FLAGS_VSYNC_LOW; - timing.pixelclock.typ = panel_info.vl_clk; - - timing.hactive.typ = panel_info.vl_col; - timing.hfront_porch.typ = panel_info.vl_right_margin; - timing.hback_porch.typ = panel_info.vl_left_margin; - timing.hsync_len.typ = panel_info.vl_hsync_len; - - timing.vactive.typ = panel_info.vl_row; - timing.vfront_porch.typ = panel_info.vl_clk; - timing.vback_porch.typ = panel_info.vl_clk; - timing.vsync_len.typ = panel_info.vl_clk; - - atmel_fb_init(panel_info.mmio, &timing, panel_info.vl_bpix, - panel_info.vl_tft, panel_info.vl_cont_pol_low, - (ulong)lcdbase); -} - -ulong calc_fbsize(void) -{ - return ((panel_info.vl_col * panel_info.vl_row * - NBITS(panel_info.vl_bpix)) / 8) + PAGE_SIZE; -} -#endif - -#ifdef CONFIG_DM_VIDEO static int atmel_fb_lcd_probe(struct udevice *dev) { struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); @@ -310,4 +209,3 @@ U_BOOT_DRIVER(atmel_fb) = { .plat_auto = sizeof(struct atmel_lcd_plat), .priv_auto = sizeof(struct atmel_fb_priv), }; -#endif diff --git a/drivers/video/bus_vcxk.c b/drivers/video/bus_vcxk.c deleted file mode 100644 index 3863662..0000000 --- a/drivers/video/bus_vcxk.c +++ /dev/null @@ -1,426 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * (C) Copyright 2005-2009 - * Jens Scharsig @ BuS Elektronik GmbH & Co. KG, <esw@bus-elektronik.de> - */ - -#include <common.h> -#include <bmp_layout.h> -#include <log.h> -#include <asm/io.h> - -vu_char *vcxk_bws = ((vu_char *) (CONFIG_SYS_VCXK_BASE)); -vu_short *vcxk_bws_word = ((vu_short *)(CONFIG_SYS_VCXK_BASE)); -vu_long *vcxk_bws_long = ((vu_long *) (CONFIG_SYS_VCXK_BASE)); - -#ifdef CONFIG_AT91RM9200 - #include <asm/arch/hardware.h> - #include <asm/arch/at91_pio.h> - - #ifndef VCBITMASK - #define VCBITMASK(bitno) (0x0001 << (bitno % 16)) - #endif -at91_pio_t *pio = (at91_pio_t *) AT91_PIO_BASE; -#define VCXK_INIT_PIN(PORT, PIN, DDR, I0O1) \ - do { \ - writel(PIN, &pio->PORT.per); \ - writel(PIN, &pio->PORT.DDR); \ - writel(PIN, &pio->PORT.mddr); \ - if (!I0O1) \ - writel(PIN, &pio->PORT.puer); \ - } while (0); - -#define VCXK_SET_PIN(PORT, PIN) writel(PIN, &pio->PORT.sodr); -#define VCXK_CLR_PIN(PORT, PIN) writel(PIN, &pio->PORT.codr); - -#define VCXK_ACKNOWLEDGE \ - (!(readl(&pio->CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT.pdsr) & \ - CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN)) -#elif defined(CONFIG_MCF52x2) - #include <asm/m5282.h> - #ifndef VCBITMASK - #define VCBITMASK(bitno) (0x8000 >> (bitno % 16)) - #endif - - #define VCXK_INIT_PIN(PORT, PIN, DDR, I0O1) \ - if (I0O1) DDR |= PIN; else DDR &= ~PIN; - - #define VCXK_SET_PIN(PORT, PIN) PORT |= PIN; - #define VCXK_CLR_PIN(PORT, PIN) PORT &= ~PIN; - - #define VCXK_ACKNOWLEDGE \ - (!(CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT & \ - CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN)) - -#else - #error no vcxk support for selected ARCH -#endif - -#define VCXK_DISABLE\ - VCXK_SET_PIN(CONFIG_SYS_VCXK_ENABLE_PORT, CONFIG_SYS_VCXK_ENABLE_PIN) -#define VCXK_ENABLE\ - VCXK_CLR_PIN(CONFIG_SYS_VCXK_ENABLE_PORT, CONFIG_SYS_VCXK_ENABLE_PIN) - -#ifndef CONFIG_SYS_VCXK_DOUBLEBUFFERED - #define VCXK_BWS(x, data) vcxk_bws[x] = data; - #define VCXK_BWS_WORD_SET(x, mask) vcxk_bws_word[x] |= mask; - #define VCXK_BWS_WORD_CLEAR(x, mask) vcxk_bws_word[x] &= ~mask; - #define VCXK_BWS_LONG(x, data) vcxk_bws_long[x] = data; -#else - u_char double_bws[16384]; - u_short *double_bws_word; - u_long *double_bws_long; - #define VCXK_BWS(x,data) \ - double_bws[x] = data; vcxk_bws[x] = data; - #define VCXK_BWS_WORD_SET(x,mask) \ - double_bws_word[x] |= mask; \ - vcxk_bws_word[x] = double_bws_word[x]; - #define VCXK_BWS_WORD_CLEAR(x,mask) \ - double_bws_word[x] &= ~mask; \ - vcxk_bws_word[x] = double_bws_word[x]; - #define VCXK_BWS_LONG(x,data) \ - double_bws_long[x] = data; vcxk_bws_long[x] = data; -#endif - -#define VC4K16_Bright1 vcxk_bws_word[0x20004 / 2] -#define VC4K16_Bright2 vcxk_bws_word[0x20006 / 2] -#define VC2K_Bright vcxk_bws[0x8000] -#define VC8K_BrightH vcxk_bws[0xC000] -#define VC8K_BrightL vcxk_bws[0xC001] - -vu_char VC4K16; - -u_long display_width; -u_long display_height; -u_long display_bwidth; - -ulong search_vcxk_driver(void); -void vcxk_cls(void); -void vcxk_setbrightness(unsigned int side, short brightness); -int vcxk_request(void); -int vcxk_acknowledge_wait(void); -void vcxk_clear(void); - -/* - ****f* bus_vcxk/vcxk_init - * FUNCTION - * initialalize Video Controller - * PARAMETERS - * width visible display width in pixel - * height visible display height in pixel - *** - */ - -int vcxk_init(unsigned long width, unsigned long height) -{ -#ifdef CONFIG_SYS_VCXK_RESET_PORT - VCXK_INIT_PIN(CONFIG_SYS_VCXK_RESET_PORT, - CONFIG_SYS_VCXK_RESET_PIN, CONFIG_SYS_VCXK_RESET_DDR, 1) - VCXK_SET_PIN(CONFIG_SYS_VCXK_RESET_PORT, CONFIG_SYS_VCXK_RESET_PIN); -#endif - -#ifdef CONFIG_SYS_VCXK_DOUBLEBUFFERED - double_bws_word = (u_short *)double_bws; - double_bws_long = (u_long *)double_bws; - debug("%px %px %px\n", double_bws, double_bws_word, double_bws_long); -#endif - display_width = width; - display_height = height; -#if (CONFIG_SYS_VCXK_DEFAULT_LINEALIGN == 4) - display_bwidth = ((width + 31) / 8) & ~0x3; -#elif (CONFIG_SYS_VCXK_DEFAULT_LINEALIGN == 2) - display_bwidth = ((width + 15) / 8) & ~0x1; -#else - #error CONFIG_SYS_VCXK_DEFAULT_LINEALIGN is invalid -#endif - debug("linesize ((%ld + 15) / 8 & ~0x1) = %ld\n", - display_width, display_bwidth); - -#ifdef CONFIG_SYS_VCXK_AUTODETECT - VC4K16 = 0; - vcxk_bws_long[1] = 0x0; - vcxk_bws_long[1] = 0x55AAAA55; - vcxk_bws_long[5] = 0x0; - if (vcxk_bws_long[1] == 0x55AAAA55) - VC4K16 = 1; -#else - VC4K16 = 1; - debug("No autodetect: use vc4k\n"); -#endif - - VCXK_INIT_PIN(CONFIG_SYS_VCXK_INVERT_PORT, - CONFIG_SYS_VCXK_INVERT_PIN, CONFIG_SYS_VCXK_INVERT_DDR, 1) - VCXK_SET_PIN(CONFIG_SYS_VCXK_INVERT_PORT, CONFIG_SYS_VCXK_INVERT_PIN) - - VCXK_SET_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, CONFIG_SYS_VCXK_REQUEST_PIN); - VCXK_INIT_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, - CONFIG_SYS_VCXK_REQUEST_PIN, CONFIG_SYS_VCXK_REQUEST_DDR, 1) - - VCXK_INIT_PIN(CONFIG_SYS_VCXK_ACKNOWLEDGE_PORT, - CONFIG_SYS_VCXK_ACKNOWLEDGE_PIN, - CONFIG_SYS_VCXK_ACKNOWLEDGE_DDR, 0) - - VCXK_DISABLE; - VCXK_INIT_PIN(CONFIG_SYS_VCXK_ENABLE_PORT, - CONFIG_SYS_VCXK_ENABLE_PIN, CONFIG_SYS_VCXK_ENABLE_DDR, 1) - - vcxk_cls(); - vcxk_cls(); /* clear second/hidden page */ - - vcxk_setbrightness(3, 1000); - VCXK_ENABLE; - return 1; -} - -/* - ****f* bus_vcxk/vcxk_setpixel - * FUNCTION - * set the pixel[x,y] with the given color - * PARAMETER - * x pixel colum - * y pixel row - * color <0x40 off/black - * >0x40 on - *** - */ - -void vcxk_setpixel(int x, int y, unsigned long color) -{ - vu_short dataptr; - - if ((x < display_width) && (y < display_height)) { - dataptr = ((x / 16)) + (y * (display_bwidth >> 1)); - - color = ((color >> 16) & 0xFF) | - ((color >> 8) & 0xFF) | (color & 0xFF); - - if (color > 0x40) { - VCXK_BWS_WORD_SET(dataptr, VCBITMASK(x)); - } else { - VCXK_BWS_WORD_CLEAR(dataptr, VCBITMASK(x)); - } - } -} - -/* - ****f* bus_vcxk/vcxk_loadimage - * FUNCTION - * copies a binary image to display memory - *** - */ - -void vcxk_loadimage(ulong source) -{ - int cnt; - vcxk_acknowledge_wait(); - if (VC4K16) { - for (cnt = 0; cnt < (16384 / 4); cnt++) { - VCXK_BWS_LONG(cnt, (*(ulong *) source)); - source = source + 4; - } - } else { - for (cnt = 0; cnt < 16384; cnt++) { - VCXK_BWS_LONG(cnt*2, (*(vu_char *) source)); - source++; - } - } - vcxk_request(); -} - -/* - ****f* bus_vcxk/vcxk_cls - * FUNCTION - * clear the display - *** - */ - -void vcxk_cls(void) -{ - vcxk_acknowledge_wait(); - vcxk_clear(); - vcxk_request(); -} - -/* - ****f* bus_vcxk/vcxk_clear(void) - * FUNCTION - * clear the display memory - *** - */ - -void vcxk_clear(void) -{ - int cnt; - - for (cnt = 0; cnt < (16384 / 4); cnt++) { - VCXK_BWS_LONG(cnt, 0) - } -} - -/* - ****f* bus_vcxk/vcxk_setbrightness - * FUNCTION - * set the display brightness - * PARAMETER - * side 1 set front side brightness - * 2 set back side brightness - * 3 set brightness for both sides - * brightness 0..1000 - *** - */ - -void vcxk_setbrightness(unsigned int side, short brightness) -{ - if (VC4K16) { - if ((side == 0) || (side & 0x1)) - VC4K16_Bright1 = brightness + 23; - if ((side == 0) || (side & 0x2)) - VC4K16_Bright2 = brightness + 23; - } else { - VC2K_Bright = (brightness >> 4) + 2; - VC8K_BrightH = (brightness + 23) >> 8; - VC8K_BrightL = (brightness + 23) & 0xFF; - } -} - -/* - ****f* bus_vcxk/vcxk_request - * FUNCTION - * requests viewing of display memory - *** - */ - -int vcxk_request(void) -{ - VCXK_CLR_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, - CONFIG_SYS_VCXK_REQUEST_PIN) - VCXK_SET_PIN(CONFIG_SYS_VCXK_REQUEST_PORT, - CONFIG_SYS_VCXK_REQUEST_PIN); - return 1; -} - -/* - ****f* bus_vcxk/vcxk_acknowledge_wait - * FUNCTION - * wait for acknowledge viewing requests - *** - */ - -int vcxk_acknowledge_wait(void) -{ - while (VCXK_ACKNOWLEDGE) - ; - return 1; -} - -/* - ****f* bus_vcxk/vcxk_draw_mono - * FUNCTION - * copies a monochrom bitmap (BMP-Format) from given memory - * PARAMETER - * dataptr pointer to bitmap - * x output bitmap @ columne - * y output bitmap @ row - *** - */ - -void vcxk_draw_mono(unsigned char *dataptr, unsigned long linewidth, - unsigned long cp_width, unsigned long cp_height) -{ - unsigned char *lineptr; - unsigned long xcnt, ycnt; - - for (ycnt = cp_height; ycnt > 0; ycnt--) { - lineptr = dataptr; - for (xcnt = 0; xcnt < cp_width; xcnt++) { - if ((*lineptr << (xcnt % 8)) & 0x80) - vcxk_setpixel(xcnt, ycnt - 1, 0xFFFFFF); - else - vcxk_setpixel(xcnt, ycnt-1, 0); - - if ((xcnt % 8) == 7) - lineptr++; - } /* endfor xcnt */ - dataptr = dataptr + linewidth; - } /* endfor ycnt */ -} - -/* - ****f* bus_vcxk/vcxk_display_bitmap - * FUNCTION - * copies a bitmap (BMP-Format) to the given position - * PARAMETER - * addr pointer to bitmap - * x output bitmap @ columne - * y output bitmap @ row - *** - */ - -int vcxk_display_bitmap(ulong addr, int x, int y) -{ - struct bmp_image *bmp; - unsigned long width; - unsigned long height; - unsigned long bpp; - - unsigned long lw; - - unsigned long c_width; - unsigned long c_height; - unsigned char *dataptr; - - bmp = (struct bmp_image *)addr; - if ((bmp->header.signature[0] == 'B') && - (bmp->header.signature[1] == 'M')) { - width = le32_to_cpu(bmp->header.width); - height = le32_to_cpu(bmp->header.height); - bpp = le16_to_cpu(bmp->header.bit_count); - - dataptr = (unsigned char *) bmp + - le32_to_cpu(bmp->header.data_offset); - - if (display_width < (width + x)) - c_width = display_width - x; - else - c_width = width; - if (display_height < (height + y)) - c_height = display_height - y; - else - c_height = height; - - lw = (((width + 7) / 8) + 3) & ~0x3; - - if (c_height < height) - dataptr = dataptr + lw * (height - c_height); - switch (bpp) { - case 1: - vcxk_draw_mono(dataptr, lw, c_width, c_height); - break; - default: - printf("Error: %ld bit per pixel " - "not supported by VCxK\n", bpp); - return 0; - } - } else { - printf("Error: no valid bmp at %lx\n", (ulong) bmp); - return 0; - } - return 1; -} - -/* - ****f* bus_vcxk/video_display_bitmap - *** - */ - -int video_display_bitmap(ulong addr, int x, int y) -{ - vcxk_acknowledge_wait(); - if (vcxk_display_bitmap(addr, x, y)) { - vcxk_request(); - return 0; - } - return 1; -} - -/* EOF */ diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c index c04b449..6859c9f 100644 --- a/drivers/video/console_truetype.c +++ b/drivers/video/console_truetype.c @@ -94,17 +94,16 @@ struct pos_info { #define POS_HISTORY_SIZE (CONFIG_SYS_CBSIZE * 11 / 10) /** - * struct console_tt_priv - Private data for this driver + * struct console_tt_metrics - Information about a font / size combination + * + * This caches various font metrics which are expensive to regenerate each time + * the font size changes. There is one of these for each font / size combination + * that is being used * + * @font_name: Name of the font * @font_size: Vertical font size in pixels * @font_data: Pointer to TrueType font file contents * @font: TrueType font information for the current font - * @pos: List of cursor positions for each character written. This is - * used to handle backspace. We clear the frame buffer between - * the last position and the current position, thus erasing the - * last character. We record enough characters to go back to the - * start of the current command line. - * @pos_ptr: Current position in the position history * @baseline: Pixel offset of the font's baseline from the cursor position. * This is the 'ascent' of the font, scaled to pixel coordinates. * It measures the distance from the baseline to the top of the @@ -113,25 +112,46 @@ struct pos_info { * of the font. It is used by the STB library to generate images * of the correct size. */ -struct console_tt_priv { +struct console_tt_metrics { + const char *font_name; int font_size; - u8 *font_data; + const u8 *font_data; stbtt_fontinfo font; - struct pos_info pos[POS_HISTORY_SIZE]; - int pos_ptr; int baseline; double scale; }; +/** + * struct console_tt_priv - Private data for this driver + * + * @cur_met: Current metrics being used + * @metrics: List metrics that can be used + * @num_metrics: Number of available metrics + * @pos: List of cursor positions for each character written. This is + * used to handle backspace. We clear the frame buffer between + * the last position and the current position, thus erasing the + * last character. We record enough characters to go back to the + * start of the current command line. + * @pos_ptr: Current position in the position history + */ +struct console_tt_priv { + struct console_tt_metrics *cur_met; + struct console_tt_metrics metrics[CONFIG_CONSOLE_TRUETYPE_MAX_METRICS]; + int num_metrics; + struct pos_info pos[POS_HISTORY_SIZE]; + int pos_ptr; +}; + static int console_truetype_set_row(struct udevice *dev, uint row, int clr) { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_metrics *met = priv->cur_met; void *end, *line; int ret; - line = vid_priv->fb + row * priv->font_size * vid_priv->line_length; - end = line + priv->font_size * vid_priv->line_length; + line = vid_priv->fb + row * met->font_size * vid_priv->line_length; + end = line + met->font_size * vid_priv->line_length; switch (vid_priv->bpix) { #ifdef CONFIG_VIDEO_BPP8 @@ -176,19 +196,20 @@ static int console_truetype_move_rows(struct udevice *dev, uint rowdst, { struct video_priv *vid_priv = dev_get_uclass_priv(dev->parent); struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_metrics *met = priv->cur_met; void *dst; void *src; int i, diff, ret; - dst = vid_priv->fb + rowdst * priv->font_size * vid_priv->line_length; - src = vid_priv->fb + rowsrc * priv->font_size * vid_priv->line_length; - ret = vidconsole_memmove(dev, dst, src, priv->font_size * + dst = vid_priv->fb + rowdst * met->font_size * vid_priv->line_length; + src = vid_priv->fb + rowsrc * met->font_size * vid_priv->line_length; + ret = vidconsole_memmove(dev, dst, src, met->font_size * vid_priv->line_length * count); if (ret) return ret; /* Scroll up our position history */ - diff = (rowsrc - rowdst) * priv->font_size; + diff = (rowsrc - rowdst) * met->font_size; for (i = 0; i < priv->pos_ptr; i++) priv->pos[i].ypos -= diff; @@ -202,7 +223,8 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, struct udevice *vid = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid); struct console_tt_priv *priv = dev_get_priv(dev); - stbtt_fontinfo *font = &priv->font; + struct console_tt_metrics *met = priv->cur_met; + stbtt_fontinfo *font = &met->font; int width, height, xoff, yoff; double xpos, x_shift; int lsb; @@ -222,7 +244,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, * this character */ xpos = frac(VID_TO_PIXEL((double)x)); if (vc_priv->last_ch) { - xpos += priv->scale * stbtt_GetCodepointKernAdvance(font, + xpos += met->scale * stbtt_GetCodepointKernAdvance(font, vc_priv->last_ch, ch); } @@ -233,7 +255,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, * it dictates how much the cursor will move forward on the line. */ x_shift = xpos - (double)tt_floor(xpos); - xpos += advance * priv->scale; + xpos += advance * met->scale; width_frac = (int)VID_TO_POS(xpos); if (x + width_frac >= vc_priv->xsize_frac) return -EAGAIN; @@ -252,7 +274,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, * image of the character. For empty characters, like ' ', data will * return NULL; */ - data = stbtt_GetCodepointBitmapSubpixel(font, priv->scale, priv->scale, + data = stbtt_GetCodepointBitmapSubpixel(font, met->scale, met->scale, x_shift, 0, ch, &width, &height, &xoff, &yoff); if (!data) @@ -262,7 +284,7 @@ static int console_truetype_putc_xy(struct udevice *dev, uint x, uint y, bits = data; start = vid_priv->fb + y * vid_priv->line_length + VID_TO_PIXEL(x) * VNBYTES(vid_priv->bpix); - linenum = priv->baseline + yoff; + linenum = met->baseline + yoff; if (linenum > 0) start += linenum * vid_priv->line_length; line = start; @@ -526,69 +548,210 @@ static struct font_info font_table[] = { {} /* sentinel */ }; -#define FONT_BEGIN(name) __ttf_ ## name ## _begin -#define FONT_END(name) __ttf_ ## name ## _end -#define FONT_IS_VALID(name) (abs(FONT_END(name) - FONT_BEGIN) > 4) +/** + * font_valid() - Check if a font-table entry is valid + * + * Depending on available files in the build system, fonts may end up being + * empty. + * + * @return true if the entry is valid + */ +static inline bool font_valid(struct font_info *tab) +{ + return abs(tab->begin - tab->end) > 4; +} /** * console_truetype_find_font() - Find a suitable font * - * This searched for the first available font. + * This searches for the first available font. * - * Return: pointer to the font, or NULL if none is found + * Return: pointer to the font-table entry, or NULL if none is found */ -static u8 *console_truetype_find_font(void) +static struct font_info *console_truetype_find_font(void) { struct font_info *tab; for (tab = font_table; tab->begin; tab++) { - if (abs(tab->begin - tab->end) > 4) { + if (font_valid(tab)) { debug("%s: Font '%s', at %p, size %lx\n", __func__, tab->name, tab->begin, (ulong)(tab->end - tab->begin)); - return tab->begin; + return tab; } } return NULL; } -static int console_truetype_probe(struct udevice *dev) +void vidconsole_list_fonts(void) +{ + struct font_info *tab; + + for (tab = font_table; tab->begin; tab++) { + if (abs(tab->begin - tab->end) > 4) + printf("%s\n", tab->name); + } +} + +/** + * vidconsole_add_metrics() - Add a new font/size combination + * + * @dev: Video console device to update + * @font_name: Name of font + * @font_size: Size of the font (norminal pixel height) + * @font_data: Pointer to the font data + * @return 0 if OK, -EPERM if stbtt failed, -E2BIG if the the metrics table is + * full + */ +static int vidconsole_add_metrics(struct udevice *dev, const char *font_name, + uint font_size, const void *font_data) +{ + struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_metrics *met; + stbtt_fontinfo *font; + int ascent; + + if (priv->num_metrics == CONFIG_CONSOLE_TRUETYPE_MAX_METRICS) + return log_msg_ret("num", -E2BIG); + + met = &priv->metrics[priv->num_metrics]; + met->font_name = font_name; + met->font_size = font_size; + met->font_data = font_data; + + font = &met->font; + if (!stbtt_InitFont(font, font_data, 0)) { + debug("%s: Font init failed\n", __func__); + return -EPERM; + } + + /* Pre-calculate some things we will need regularly */ + met->scale = stbtt_ScaleForPixelHeight(font, font_size); + stbtt_GetFontVMetrics(font, &ascent, 0, 0); + met->baseline = (int)(ascent * met->scale); + + return priv->num_metrics++; +} + +/** + * find_metrics() - Find the metrics for a given font and size + * + * @dev: Video console device to update + * @name: Name of font + * @size: Size of the font (norminal pixel height) + * @return metrics, if found, else NULL + */ +static struct console_tt_metrics *find_metrics(struct udevice *dev, + const char *name, uint size) +{ + struct console_tt_priv *priv = dev_get_priv(dev); + int i; + + for (i = 0; i < priv->num_metrics; i++) { + struct console_tt_metrics *met = &priv->metrics[i]; + + if (!strcmp(name, met->font_name) && met->font_size == size) + return met; + } + + return NULL; +} + +static void select_metrics(struct udevice *dev, struct console_tt_metrics *met) { struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); struct console_tt_priv *priv = dev_get_priv(dev); + struct udevice *vid_dev = dev_get_parent(dev); + struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); + + priv->cur_met = met; + vc_priv->x_charsize = met->font_size; + vc_priv->y_charsize = met->font_size; + vc_priv->xstart_frac = VID_TO_POS(2); + vc_priv->cols = vid_priv->xsize / met->font_size; + vc_priv->rows = vid_priv->ysize / met->font_size; + vc_priv->tab_width_frac = VID_TO_POS(met->font_size) * 8 / 2; +} + +int vidconsole_select_font(struct udevice *dev, const char *name, uint size) +{ + struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_metrics *met; + struct font_info *tab; + + if (name || size) { + if (!size) + size = CONFIG_CONSOLE_TRUETYPE_SIZE; + if (!name) + name = priv->cur_met->font_name; + + met = find_metrics(dev, name, size); + if (!met) { + for (tab = font_table; tab->begin; tab++) { + if (font_valid(tab) && + !strcmp(name, tab->name)) { + int ret; + + ret = vidconsole_add_metrics(dev, + tab->name, size, tab->begin); + if (ret < 0) + return log_msg_ret("add", ret); + + met = &priv->metrics[ret]; + break; + } + } + } + if (!met) + return log_msg_ret("find", -ENOENT); + } else { + /* Use the default font */ + met = priv->metrics; + } + + select_metrics(dev, met); + + return 0; +} + +const char *vidconsole_get_font(struct udevice *dev, uint *sizep) +{ + struct console_tt_priv *priv = dev_get_priv(dev); + struct console_tt_metrics *met = priv->cur_met; + + *sizep = met->font_size; + + return met->font_name; +} + +static int console_truetype_probe(struct udevice *dev) +{ + struct console_tt_priv *priv = dev_get_priv(dev); struct udevice *vid_dev = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); - stbtt_fontinfo *font = &priv->font; - int ascent; + struct font_info *tab; + uint font_size; + int ret; debug("%s: start\n", __func__); if (vid_priv->font_size) - priv->font_size = vid_priv->font_size; + font_size = vid_priv->font_size; else - priv->font_size = CONFIG_CONSOLE_TRUETYPE_SIZE; - priv->font_data = console_truetype_find_font(); - if (!priv->font_data) { + font_size = CONFIG_CONSOLE_TRUETYPE_SIZE; + tab = console_truetype_find_font(); + if (!tab) { debug("%s: Could not find any fonts\n", __func__); return -EBFONT; } - vc_priv->x_charsize = priv->font_size; - vc_priv->y_charsize = priv->font_size; - vc_priv->xstart_frac = VID_TO_POS(2); - vc_priv->cols = vid_priv->xsize / priv->font_size; - vc_priv->rows = vid_priv->ysize / priv->font_size; - vc_priv->tab_width_frac = VID_TO_POS(priv->font_size) * 8 / 2; + ret = vidconsole_add_metrics(dev, tab->name, font_size, tab->begin); + if (ret < 0) + return log_msg_ret("add", ret); + priv->cur_met = &priv->metrics[ret]; - if (!stbtt_InitFont(font, priv->font_data, 0)) { - debug("%s: Font init failed\n", __func__); - return -EPERM; - } + select_metrics(dev, &priv->metrics[ret]); - /* Pre-calculate some things we will need regularly */ - priv->scale = stbtt_ScaleForPixelHeight(font, priv->font_size); - stbtt_GetFontVMetrics(font, &ascent, 0, 0); - priv->baseline = (int)(ascent * priv->scale); debug("%s: ready\n", __func__); return 0; diff --git a/drivers/video/dw_mipi_dsi.c b/drivers/video/dw_mipi_dsi.c index a5b38ac..6d9c5a9 100644 --- a/drivers/video/dw_mipi_dsi.c +++ b/drivers/video/dw_mipi_dsi.c @@ -621,8 +621,8 @@ static void dw_mipi_dsi_line_timer_config(struct dw_mipi_dsi *dsi, htotal = timings->hactive.typ + timings->hfront_porch.typ + timings->hback_porch.typ + timings->hsync_len.typ; - hsa = timings->hback_porch.typ; - hbp = timings->hsync_len.typ; + hsa = timings->hsync_len.typ; + hbp = timings->hback_porch.typ; /* * TODO dw drv improvements @@ -644,9 +644,9 @@ static void dw_mipi_dsi_vertical_timing_config(struct dw_mipi_dsi *dsi, u32 vactive, vsa, vfp, vbp; vactive = timings->vactive.typ; - vsa = timings->vback_porch.typ; + vsa = timings->vsync_len.typ; vfp = timings->vfront_porch.typ; - vbp = timings->vsync_len.typ; + vbp = timings->vback_porch.typ; dsi_write(dsi, DSI_VID_VACTIVE_LINES, vactive); dsi_write(dsi, DSI_VID_VSA_LINES, vsa); diff --git a/drivers/video/exynos/Kconfig b/drivers/video/exynos/Kconfig index 37e661b..599d19d 100644 --- a/drivers/video/exynos/Kconfig +++ b/drivers/video/exynos/Kconfig @@ -1,7 +1,7 @@ menuconfig VIDEO_EXYNOS bool "Enable Exynos video support" - depends on DM_VIDEO + depends on VIDEO help Enable support for various video output options on Exynos SoCs. diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/exynos/exynos_mipi_dsi_common.c index ab7d61a..be67ceb 100644 --- a/drivers/video/exynos/exynos_mipi_dsi_common.c +++ b/drivers/video/exynos/exynos_mipi_dsi_common.c @@ -7,7 +7,6 @@ */ #include <common.h> -#include <lcd.h> #include <log.h> #include <linux/delay.h> #include <linux/err.h> diff --git a/drivers/video/imx/Kconfig b/drivers/video/imx/Kconfig index 78eb0f2..afe950b 100644 --- a/drivers/video/imx/Kconfig +++ b/drivers/video/imx/Kconfig @@ -1,7 +1,7 @@ config VIDEO_IPUV3 bool "i.MX IPUv3 Core video support" - depends on DM_VIDEO && (MX5 || MX6) + depends on VIDEO && (MX5 || MX6) help This enables framebuffer driver for i.MX processors working on the IPUv3(Image Processing Unit) internal graphic processor. diff --git a/drivers/video/ld9040.c b/drivers/video/ld9040.c deleted file mode 100644 index a36bc2f..0000000 --- a/drivers/video/ld9040.c +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * ld9040 AMOLED LCD panel driver. - * - * Copyright (C) 2012 Samsung Electronics - * Donghwa Lee <dh09.lee@samsung.com> - */ - -#include <common.h> -#include <spi.h> -#include <linux/delay.h> - -static const unsigned char SEQ_USER_SETTING[] = { - 0xF0, 0x5A, 0x5A -}; - -static const unsigned char SEQ_ELVSS_ON[] = { - 0xB1, 0x0D, 0x00, 0x16, -}; - -static const unsigned char SEQ_GTCON[] = { - 0xF7, 0x09, 0x00, 0x00, -}; - -static const unsigned char SEQ_PANEL_CONDITION[] = { - 0xF8, 0x05, 0x65, 0x96, 0x71, 0x7D, 0x19, 0x3B, - 0x0D, 0x19, 0x7E, 0x0D, 0xE2, 0x00, 0x00, 0x7E, - 0x7D, 0x07, 0x07, 0x20, 0x20, 0x20, 0x02, 0x02, -}; - -static const unsigned char SEQ_GAMMA_SET1[] = { - 0xF9, 0x00, 0xA7, 0xB4, 0xAE, 0xBF, 0x00, 0x91, - 0x00, 0xB2, 0xB4, 0xAA, 0xBB, 0x00, 0xAC, 0x00, - 0xB3, 0xB1, 0xAA, 0xBC, 0x00, 0xB3, -}; - -static const unsigned char SEQ_GAMMA_CTRL[] = { - 0xFB, 0x02, 0x5A, -}; - -static const unsigned char SEQ_DISPCTL[] = { - 0xF2, 0x02, 0x08, 0x08, 0x10, 0x10, -}; - -static const unsigned char SEQ_MANPWR[] = { - 0xB0, 0x04, -}; - -static const unsigned char SEQ_PWR_CTRL[] = { - 0xF4, 0x0A, 0x87, 0x25, 0x6A, 0x44, 0x02, 0x88, -}; - -static const unsigned char SEQ_SLPOUT[] = { - 0x11, -}; - -static const unsigned char SEQ_DISPON[] = { - 0x29, -}; - -static const unsigned char SEQ_DISPOFF[] = { - 0x28, -}; - -static void ld9040_spi_write(const unsigned char *wbuf, unsigned int size_cmd) -{ - int i = 0; - - /* - * Data are transmitted in 9-bit words: - * the first bit is command/parameter, the other are the value. - * The value's LSB is shifted to MSB position, to be sent as 9th bit - */ - - unsigned int data_out = 0, data_in = 0; - for (i = 0; i < size_cmd; i++) { - data_out = wbuf[i] >> 1; - if (i != 0) - data_out += 0x0080; - if (wbuf[i] & 0x01) - data_out += 0x8000; - spi_xfer(NULL, 9, &data_out, &data_in, SPI_XFER_BEGIN); - } -} - -void ld9040_cfg_ldo(void) -{ - udelay(10); - - ld9040_spi_write(SEQ_USER_SETTING, - ARRAY_SIZE(SEQ_USER_SETTING)); - ld9040_spi_write(SEQ_PANEL_CONDITION, - ARRAY_SIZE(SEQ_PANEL_CONDITION)); - ld9040_spi_write(SEQ_DISPCTL, ARRAY_SIZE(SEQ_DISPCTL)); - ld9040_spi_write(SEQ_MANPWR, ARRAY_SIZE(SEQ_MANPWR)); - ld9040_spi_write(SEQ_PWR_CTRL, ARRAY_SIZE(SEQ_PWR_CTRL)); - ld9040_spi_write(SEQ_ELVSS_ON, ARRAY_SIZE(SEQ_ELVSS_ON)); - ld9040_spi_write(SEQ_GTCON, ARRAY_SIZE(SEQ_GTCON)); - ld9040_spi_write(SEQ_GAMMA_SET1, ARRAY_SIZE(SEQ_GAMMA_SET1)); - ld9040_spi_write(SEQ_GAMMA_CTRL, ARRAY_SIZE(SEQ_GAMMA_CTRL)); - ld9040_spi_write(SEQ_SLPOUT, ARRAY_SIZE(SEQ_SLPOUT)); - - udelay(120); -} - -void ld9040_enable_ldo(unsigned int onoff) -{ - if (onoff) - ld9040_spi_write(SEQ_DISPON, ARRAY_SIZE(SEQ_DISPON)); - else - ld9040_spi_write(SEQ_DISPOFF, ARRAY_SIZE(SEQ_DISPOFF)); -} diff --git a/drivers/video/meson/Kconfig b/drivers/video/meson/Kconfig index 0c9ddeb..3c2d72d 100644 --- a/drivers/video/meson/Kconfig +++ b/drivers/video/meson/Kconfig @@ -6,7 +6,7 @@ config VIDEO_MESON bool "Enable Amlogic Meson video support" - depends on DM_VIDEO + depends on VIDEO select DISPLAY help Enable Amlogic Meson Video Processing Unit video support. diff --git a/drivers/video/nexell_display.c b/drivers/video/nexell_display.c index 090fd6e..5595796 100644 --- a/drivers/video/nexell_display.c +++ b/drivers/video/nexell_display.c @@ -16,7 +16,6 @@ #include <linux/compat.h> #include <linux/err.h> #include <video.h> /* For struct video_uc_plat */ -#include <lcd.h> #include <asm/global_data.h> #include <asm/io.h> #include <asm/arch/display.h> @@ -481,56 +480,6 @@ err_setup: return NULL; } -#if defined CONFIG_LCD - -/* default lcd */ -struct vidinfo panel_info = { - .vl_col = 320, .vl_row = 240, .vl_bpix = 32, -}; - -void lcd_ctrl_init(void *lcdbase) -{ - vidinfo_t *pi = &panel_info; - struct nx_display_dev *dp; - int bpix; - - dp = nx_display_setup(); - if (!dp) - return NULL; - - switch (dp->depth) { - case 2: - bpix = LCD_COLOR16; - break; - case 3: - case 4: - bpix = LCD_COLOR32; - break; - default: - printf("fail : not support LCD bit per pixel %d\n", - dp->depth * 8); - return NULL; - } - - dp->panel_info = pi; - - /* set resolution with config */ - pi->vl_bpix = bpix; - pi->vl_col = dp->fb_plane->width; - pi->vl_row = dp->fb_plane->height; - pi->priv = dp; - gd->fb_base = dp->fb_addr; -} - -void lcd_setcolreg(ushort regno, ushort red, ushort green, ushort blue) -{ -} - -__weak void lcd_enable(void) -{ -} -#endif - static int nx_display_probe(struct udevice *dev) { struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); @@ -593,7 +542,7 @@ static int nx_display_probe(struct udevice *dev) /* * set environment variable "fb_addr" (frame buffer address), required - * for splash image, which is not set if CONFIG_DM_VIDEO is enabled). + * for splash image, which is not set if CONFIG_VIDEO is enabled). */ sprintf(addr, "0x%x", dp->fb_addr); debug("%s(): env_set(\"fb_addr\", %s) ...\n", __func__, addr); diff --git a/drivers/video/rockchip/Kconfig b/drivers/video/rockchip/Kconfig index 0ade631..b038663 100644 --- a/drivers/video/rockchip/Kconfig +++ b/drivers/video/rockchip/Kconfig @@ -10,7 +10,7 @@ menuconfig VIDEO_ROCKCHIP bool "Enable Rockchip Video Support" - depends on DM_VIDEO + depends on VIDEO help Rockchip SoCs provide video output capabilities for High-Definition Multimedia Interface (HDMI), Low-voltage Differential Signalling diff --git a/drivers/video/simplefb.c b/drivers/video/simplefb.c index 2b0d883..235ec76 100644 --- a/drivers/video/simplefb.c +++ b/drivers/video/simplefb.c @@ -43,7 +43,11 @@ static int simple_video_probe(struct udevice *dev) uc_priv->xsize = fdtdec_get_uint(blob, node, "width", 0); uc_priv->ysize = fdtdec_get_uint(blob, node, "height", 0); - uc_priv->rot = 0; + uc_priv->rot = fdtdec_get_uint(blob, node, "rot", 0); + if (uc_priv->rot > 3) { + log_debug("%s: invalid rot\n", __func__); + return log_msg_ret("rot", -EINVAL); + } format = fdt_getprop(blob, node, "format", NULL); debug("%s: %dx%d@%s\n", __func__, uc_priv->xsize, uc_priv->ysize, format); diff --git a/drivers/video/stm32/Kconfig b/drivers/video/stm32/Kconfig index 95d51bb..4806606 100644 --- a/drivers/video/stm32/Kconfig +++ b/drivers/video/stm32/Kconfig @@ -7,7 +7,7 @@ menuconfig VIDEO_STM32 bool "Enable STM32 video support" - depends on DM_VIDEO + depends on VIDEO help STM32 supports many video output options including RGB and DSI. This option enables these supports which can be used on diff --git a/drivers/video/tegra124/display.c b/drivers/video/tegra124/display.c index f642b3b..78ab3f9 100644 --- a/drivers/video/tegra124/display.c +++ b/drivers/video/tegra124/display.c @@ -12,7 +12,6 @@ #include <errno.h> #include <display.h> #include <edid.h> -#include <lcd.h> #include <log.h> #include <part.h> #include <video.h> diff --git a/drivers/video/ti/Kconfig b/drivers/video/ti/Kconfig deleted file mode 100644 index 3081e9e..0000000 --- a/drivers/video/ti/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# Copyright (C) 2020 Dario Binacchi <dariobin@libero.it> -# -config AM335X_LCD - bool "Enable AM335x video support" - help - Supports video output to an attached LCD panel. diff --git a/drivers/video/ti/Makefile b/drivers/video/ti/Makefile deleted file mode 100644 index ddddd59..0000000 --- a/drivers/video/ti/Makefile +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0+ -# -# Copyright (C) 2020 Dario Binacchi <dariobin@libero.it> -# - -ifdef CONFIG_DM_VIDEO -obj-$(CONFIG_AM335X_LCD) += tilcdc.o tilcdc-panel.o -else -obj-$(CONFIG_AM335X_LCD) += am335x-fb.o -endif diff --git a/drivers/video/ti/am335x-fb.c b/drivers/video/ti/am335x-fb.c deleted file mode 100644 index 680ea47..0000000 --- a/drivers/video/ti/am335x-fb.c +++ /dev/null @@ -1,318 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2013-2018 Hannes Schmelzer <oe5hpm@oevsv.at> - * B&R Industrial Automation GmbH - http://www.br-automation.com - * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it> - * - * minimal framebuffer driver for TI's AM335x SoC to be compatible with - * Wolfgang Denk's LCD-Framework (CONFIG_LCD, common/lcd.c) - * - * - supporting 16/24/32bit RGB/TFT raster Mode (not using palette) - * - sets up LCD controller as in 'am335x_lcdpanel' struct given - * - starts output DMA from gd->fb_base buffer - */ -#include <common.h> -#include <lcd.h> -#include <log.h> -#include <asm/arch/clock.h> -#include <asm/arch/hardware.h> -#include <asm/arch/omap.h> -#include <asm/arch/sys_proto.h> -#include <asm/global_data.h> -#include <asm/io.h> -#include <linux/delay.h> -#include <linux/err.h> -#include "am335x-fb.h" - -#define LCDC_FMAX 200000000 - -/* LCD Control Register */ -#define LCDC_CTRL_CLK_DIVISOR_MASK GENMASK(15, 8) -#define LCDC_CTRL_RASTER_MODE BIT(0) -#define LCDC_CTRL_CLK_DIVISOR(x) (((x) & GENMASK(7, 0)) << 8) -/* LCD Clock Enable Register */ -#define LCDC_CLKC_ENABLE_CORECLKEN BIT(0) -#define LCDC_CLKC_ENABLE_LIDDCLKEN BIT(1) -#define LCDC_CLKC_ENABLE_DMACLKEN BIT(2) -/* LCD DMA Control Register */ -#define LCDC_DMA_CTRL_BURST_SIZE(x) (((x) & GENMASK(2, 0)) << 4) -#define LCDC_DMA_CTRL_BURST_1 0x0 -#define LCDC_DMA_CTRL_BURST_2 0x1 -#define LCDC_DMA_CTRL_BURST_4 0x2 -#define LCDC_DMA_CTRL_BURST_8 0x3 -#define LCDC_DMA_CTRL_BURST_16 0x4 -#define LCDC_DMA_CTRL_FIFO_TH(x) (((x) & GENMASK(2, 0)) << 8) -/* LCD Timing_0 Register */ -#define LCDC_RASTER_TIMING_0_HORMSB(x) ((((x) - 1) & BIT(10)) >> 7) -#define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & GENMASK(5, 0)) << 4) -#define LCDC_RASTER_TIMING_0_HSWLSB(x) ((((x) - 1) & GENMASK(5, 0)) << 10) -#define LCDC_RASTER_TIMING_0_HFPLSB(x) ((((x) - 1) & GENMASK(7, 0)) << 16) -#define LCDC_RASTER_TIMING_0_HBPLSB(x) ((((x) - 1) & GENMASK(7, 0)) << 24) -/* LCD Timing_1 Register */ -#define LCDC_RASTER_TIMING_1_VERLSB(x) (((x) - 1) & GENMASK(9, 0)) -#define LCDC_RASTER_TIMING_1_VSW(x) ((((x) - 1) & GENMASK(5, 0)) << 10) -#define LCDC_RASTER_TIMING_1_VFP(x) (((x) & GENMASK(7, 0)) << 16) -#define LCDC_RASTER_TIMING_1_VBP(x) (((x) & GENMASK(7, 0)) << 24) -/* LCD Timing_2 Register */ -#define LCDC_RASTER_TIMING_2_HFPMSB(x) ((((x) - 1) & GENMASK(9, 8)) >> 8) -#define LCDC_RASTER_TIMING_2_HBPMSB(x) ((((x) - 1) & GENMASK(9, 8)) >> 4) -#define LCDC_RASTER_TIMING_2_ACB(x) (((x) & GENMASK(7, 0)) << 8) -#define LCDC_RASTER_TIMING_2_ACBI(x) (((x) & GENMASK(3, 0)) << 16) -#define LCDC_RASTER_TIMING_2_VSYNC_INVERT BIT(20) -#define LCDC_RASTER_TIMING_2_HSYNC_INVERT BIT(21) -#define LCDC_RASTER_TIMING_2_PXCLK_INVERT BIT(22) -#define LCDC_RASTER_TIMING_2_DE_INVERT BIT(23) -#define LCDC_RASTER_TIMING_2_HSVS_RISEFALL BIT(24) -#define LCDC_RASTER_TIMING_2_HSVS_CONTROL BIT(25) -#define LCDC_RASTER_TIMING_2_VERMSB(x) ((((x) - 1) & BIT(10)) << 16) -#define LCDC_RASTER_TIMING_2_HSWMSB(x) ((((x) - 1) & GENMASK(9, 6)) << 21) -/* LCD Raster Ctrl Register */ -#define LCDC_RASTER_CTRL_ENABLE BIT(0) -#define LCDC_RASTER_CTRL_TFT_MODE BIT(7) -#define LCDC_RASTER_CTRL_DATA_ORDER BIT(8) -#define LCDC_RASTER_CTRL_REQDLY(x) (((x) & GENMASK(7, 0)) << 12) -#define LCDC_RASTER_CTRL_PALMODE_RAWDATA (0x02 << 20) -#define LCDC_RASTER_CTRL_TFT_ALT_ENABLE BIT(23) -#define LCDC_RASTER_CTRL_TFT_24BPP_MODE BIT(25) -#define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK BIT(26) - -struct am335x_lcdhw { - unsigned int pid; /* 0x00 */ - unsigned int ctrl; /* 0x04 */ - unsigned int gap0; /* 0x08 */ - unsigned int lidd_ctrl; /* 0x0C */ - unsigned int lidd_cs0_conf; /* 0x10 */ - unsigned int lidd_cs0_addr; /* 0x14 */ - unsigned int lidd_cs0_data; /* 0x18 */ - unsigned int lidd_cs1_conf; /* 0x1C */ - unsigned int lidd_cs1_addr; /* 0x20 */ - unsigned int lidd_cs1_data; /* 0x24 */ - unsigned int raster_ctrl; /* 0x28 */ - unsigned int raster_timing0; /* 0x2C */ - unsigned int raster_timing1; /* 0x30 */ - unsigned int raster_timing2; /* 0x34 */ - unsigned int raster_subpanel; /* 0x38 */ - unsigned int raster_subpanel2; /* 0x3C */ - unsigned int lcddma_ctrl; /* 0x40 */ - unsigned int lcddma_fb0_base; /* 0x44 */ - unsigned int lcddma_fb0_ceiling; /* 0x48 */ - unsigned int lcddma_fb1_base; /* 0x4C */ - unsigned int lcddma_fb1_ceiling; /* 0x50 */ - unsigned int sysconfig; /* 0x54 */ - unsigned int irqstatus_raw; /* 0x58 */ - unsigned int irqstatus; /* 0x5C */ - unsigned int irqenable_set; /* 0x60 */ - unsigned int irqenable_clear; /* 0x64 */ - unsigned int gap1; /* 0x68 */ - unsigned int clkc_enable; /* 0x6C */ - unsigned int clkc_reset; /* 0x70 */ -}; - -DECLARE_GLOBAL_DATA_PTR; - -#if !defined(LCD_CNTL_BASE) -#error "hw-base address of LCD-Controller (LCD_CNTL_BASE) not defined!" -#endif - -/* Macro definitions */ -#define FBSIZE(x) (((x)->hactive * (x)->vactive * (x)->bpp) >> 3) - -#define LCDC_RASTER_TIMING_2_INVMASK(x) ((x) & GENMASK(25, 20)) - -static struct am335x_lcdhw *lcdhw = (void *)LCD_CNTL_BASE; - -int lcd_get_size(int *line_length) -{ - *line_length = (panel_info.vl_col * NBITS(panel_info.vl_bpix)) / 8; - return *line_length * panel_info.vl_row + 0x20; -} - -struct dpll_data { - unsigned long rounded_rate; - u16 rounded_m; - u8 rounded_n; - u8 rounded_div; -}; - -/** - * am335x_dpll_round_rate() - Round a target rate for an OMAP DPLL - * - * @dpll_data: struct dpll_data pointer for the DPLL - * @rate: New DPLL clock rate - * Return: rounded rate and the computed m, n and div values in the dpll_data - * structure, or -ve error code. - */ -static ulong am335x_dpll_round_rate(struct dpll_data *dd, ulong rate) -{ - unsigned int m, n, d; - unsigned long rounded_rate; - int err, err_r; - - dd->rounded_rate = -EFAULT; - err = rate; - err_r = err; - - for (d = 2; err && d < 255; d++) { - for (m = 2; m < 2047; m++) { - if ((V_OSCK * m) < (rate * d)) - continue; - - n = (V_OSCK * m) / (rate * d); - if (n > 127) - break; - - if (((V_OSCK * m) / n) > LCDC_FMAX) - break; - - rounded_rate = (V_OSCK * m) / n / d; - err = abs(rounded_rate - rate); - if (err < err_r) { - err_r = err; - dd->rounded_rate = rounded_rate; - dd->rounded_m = m; - dd->rounded_n = n; - dd->rounded_div = d; - if (err == 0) - break; - } - } - } - - debug("DPLL display: best error %d Hz (M %d, N %d, DIV %d)\n", - err_r, dd->rounded_m, dd->rounded_n, dd->rounded_div); - - return dd->rounded_rate; -} - -/** - * am335x_fb_set_pixel_clk_rate() - Set pixel clock rate. - * - * @am335x_lcdhw: Base address of the LCD controller registers. - * @rate: New clock rate in Hz. - * Return: new rate, or -ve error code. - */ -static ulong am335x_fb_set_pixel_clk_rate(struct am335x_lcdhw *regs, ulong rate) -{ - struct dpll_params dpll_disp = { 1, 0, 1, -1, -1, -1, -1 }; - struct dpll_data dd; - ulong round_rate; - u32 reg; - - round_rate = am335x_dpll_round_rate(&dd, rate); - if (IS_ERR_VALUE(round_rate)) - return round_rate; - - dpll_disp.m = dd.rounded_m; - dpll_disp.n = dd.rounded_n; - do_setup_dpll(&dpll_disp_regs, &dpll_disp); - - reg = readl(®s->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK; - reg |= LCDC_CTRL_CLK_DIVISOR(dd.rounded_div); - writel(reg, ®s->ctrl); - return round_rate; -} - -int am335xfb_init(struct am335x_lcdpanel *panel) -{ - u32 raster_ctrl = 0; - struct cm_dpll *const cmdpll = (struct cm_dpll *)CM_DPLL; - ulong rate; - u32 reg; - - if (gd->fb_base == 0) { - printf("ERROR: no valid fb_base stored in GLOBAL_DATA_PTR!\n"); - return -1; - } - if (panel == NULL) { - printf("ERROR: missing ptr to am335x_lcdpanel!\n"); - return -1; - } - - /* We can already set the bits for the raster_ctrl in this check */ - switch (panel->bpp) { - case 16: - break; - case 32: - raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_UNPACK; - /* fallthrough */ - case 24: - raster_ctrl |= LCDC_RASTER_CTRL_TFT_24BPP_MODE; - break; - default: - pr_err("am335x-fb: invalid bpp value: %d\n", panel->bpp); - return -1; - } - - /* check given clock-frequency */ - if (panel->pxl_clk > (LCDC_FMAX / 2)) { - pr_err("am335x-fb: requested pxl-clk: %d not supported!\n", - panel->pxl_clk); - return -1; - } - - debug("setting up LCD-Controller for %dx%dx%d (hfp=%d,hbp=%d,hsw=%d / ", - panel->hactive, panel->vactive, panel->bpp, - panel->hfp, panel->hbp, panel->hsw); - debug("vfp=%d,vbp=%d,vsw=%d / clk=%d)\n", - panel->vfp, panel->vfp, panel->vsw, panel->pxl_clk); - debug("using frambuffer at 0x%08x with size %d.\n", - (unsigned int)gd->fb_base, FBSIZE(panel)); - - rate = am335x_fb_set_pixel_clk_rate(lcdhw, panel->pxl_clk); - if (IS_ERR_VALUE(rate)) - return rate; - - /* clock source for LCDC from dispPLL M2 */ - writel(0x0, &cmdpll->clklcdcpixelclk); - - /* palette default entry */ - memset((void *)gd->fb_base, 0, 0x20); - *(unsigned int *)gd->fb_base = 0x4000; - /* point fb behind palette */ - gd->fb_base += 0x20; - - /* turn ON display through powercontrol function if accessible */ - if (panel->panel_power_ctrl != NULL) - panel->panel_power_ctrl(1); - - debug("am335x-fb: wait for stable power ...\n"); - mdelay(panel->pup_delay); - lcdhw->clkc_enable = LCDC_CLKC_ENABLE_CORECLKEN | - LCDC_CLKC_ENABLE_LIDDCLKEN | LCDC_CLKC_ENABLE_DMACLKEN; - lcdhw->raster_ctrl = 0; - - reg = lcdhw->ctrl & LCDC_CTRL_CLK_DIVISOR_MASK; - reg |= LCDC_CTRL_RASTER_MODE; - lcdhw->ctrl = reg; - - lcdhw->lcddma_fb0_base = gd->fb_base; - lcdhw->lcddma_fb0_ceiling = gd->fb_base + FBSIZE(panel); - lcdhw->lcddma_fb1_base = gd->fb_base; - lcdhw->lcddma_fb1_ceiling = gd->fb_base + FBSIZE(panel); - lcdhw->lcddma_ctrl = LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16); - - lcdhw->raster_timing0 = LCDC_RASTER_TIMING_0_HORLSB(panel->hactive) | - LCDC_RASTER_TIMING_0_HORMSB(panel->hactive) | - LCDC_RASTER_TIMING_0_HFPLSB(panel->hfp) | - LCDC_RASTER_TIMING_0_HBPLSB(panel->hbp) | - LCDC_RASTER_TIMING_0_HSWLSB(panel->hsw); - lcdhw->raster_timing1 = LCDC_RASTER_TIMING_1_VBP(panel->vbp) | - LCDC_RASTER_TIMING_1_VFP(panel->vfp) | - LCDC_RASTER_TIMING_1_VSW(panel->vsw) | - LCDC_RASTER_TIMING_1_VERLSB(panel->vactive); - lcdhw->raster_timing2 = LCDC_RASTER_TIMING_2_HSWMSB(panel->hsw) | - LCDC_RASTER_TIMING_2_VERMSB(panel->vactive) | - LCDC_RASTER_TIMING_2_INVMASK(panel->pol) | - LCDC_RASTER_TIMING_2_HBPMSB(panel->hbp) | - LCDC_RASTER_TIMING_2_HFPMSB(panel->hfp) | - 0x0000FF00; /* clk cycles for ac-bias */ - lcdhw->raster_ctrl = raster_ctrl | - LCDC_RASTER_CTRL_PALMODE_RAWDATA | - LCDC_RASTER_CTRL_TFT_MODE | - LCDC_RASTER_CTRL_ENABLE; - - debug("am335x-fb: waiting picture to be stable.\n."); - mdelay(panel->pon_delay); - - return 0; -} diff --git a/drivers/video/ti/am335x-fb.h b/drivers/video/ti/am335x-fb.h deleted file mode 100644 index ad9b015..0000000 --- a/drivers/video/ti/am335x-fb.h +++ /dev/null @@ -1,71 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2013-2018 Hannes Schmelzer <oe5hpm@oevsv.at> - - * B&R Industrial Automation GmbH - http://www.br-automation.com - */ - -#ifndef AM335X_FB_H -#define AM335X_FB_H - -#define HSVS_CONTROL BIT(25) /* - * 0 = lcd_lp and lcd_fp are driven on - * opposite edges of pixel clock than - * the lcd_pixel_o - * 1 = lcd_lp and lcd_fp are driven - * according to bit 24 Note that this - * bit MUST be set to '0' for Passive - * Matrix displays the edge timing is - * fixed - */ -#define HSVS_RISEFALL BIT(24) /* - * 0 = lcd_lp and lcd_fp are driven on - * the rising edge of pixel clock (bit - * 25 must be set to 1) - * 1 = lcd_lp and lcd_fp are driven on - * the falling edge of pixel clock (bit - * 25 must be set to 1) - */ -#define DE_INVERT BIT(23) /* - * 0 = DE is low-active - * 1 = DE is high-active - */ -#define PXCLK_INVERT BIT(22) /* - * 0 = pix-clk is high-active - * 1 = pic-clk is low-active - */ -#define HSYNC_INVERT BIT(21) /* - * 0 = HSYNC is active high - * 1 = HSYNC is avtive low - */ -#define VSYNC_INVERT BIT(20) /* - * 0 = VSYNC is active high - * 1 = VSYNC is active low - */ - -struct am335x_lcdpanel { - unsigned int hactive; /* Horizontal active area */ - unsigned int vactive; /* Vertical active area */ - unsigned int bpp; /* bits per pixel */ - unsigned int hfp; /* Horizontal front porch */ - unsigned int hbp; /* Horizontal back porch */ - unsigned int hsw; /* Horizontal Sync Pulse Width */ - unsigned int vfp; /* Vertical front porch */ - unsigned int vbp; /* Vertical back porch */ - unsigned int vsw; /* Vertical Sync Pulse Width */ - unsigned int pxl_clk; /* Pixel clock */ - unsigned int pol; /* polarity of sync, clock signals */ - unsigned int pup_delay; /* - * time in ms after power on to - * initialization of lcd-controller - * (VCC ramp up time) - */ - unsigned int pon_delay; /* - * time in ms after initialization of - * lcd-controller (pic stabilization) - */ - void (*panel_power_ctrl)(int); /* fp for power on/off display */ -}; - -int am335xfb_init(struct am335x_lcdpanel *panel); - -#endif /* AM335X_FB_H */ diff --git a/drivers/video/ti/tilcdc-panel.c b/drivers/video/ti/tilcdc-panel.c deleted file mode 100644 index df95086..0000000 --- a/drivers/video/ti/tilcdc-panel.c +++ /dev/null @@ -1,172 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * OMAP panel support - * - * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it> - */ - -#include <common.h> -#include <backlight.h> -#include <clk.h> -#include <display.h> -#include <dm.h> -#include <dm/device_compat.h> -#include <log.h> -#include <panel.h> -#include <asm/gpio.h> -#include <linux/err.h> -#include "tilcdc.h" - -struct tilcdc_panel_priv { - struct tilcdc_panel_info info; - struct display_timing timing; - struct udevice *backlight; - struct gpio_desc enable; -}; - -static int tilcdc_panel_enable_backlight(struct udevice *dev) -{ - struct tilcdc_panel_priv *priv = dev_get_priv(dev); - - if (dm_gpio_is_valid(&priv->enable)) - dm_gpio_set_value(&priv->enable, 1); - - if (priv->backlight) - return backlight_enable(priv->backlight); - - return 0; -} - -static int tilcdc_panel_set_backlight(struct udevice *dev, int percent) -{ - struct tilcdc_panel_priv *priv = dev_get_priv(dev); - - if (dm_gpio_is_valid(&priv->enable)) - dm_gpio_set_value(&priv->enable, 1); - - if (priv->backlight) - return backlight_set_brightness(priv->backlight, percent); - - return 0; -} - -int tilcdc_panel_get_display_info(struct udevice *dev, - struct tilcdc_panel_info *info) -{ - struct tilcdc_panel_priv *priv = dev_get_priv(dev); - - memcpy(info, &priv->info, sizeof(*info)); - return 0; -} - -static int tilcdc_panel_get_display_timing(struct udevice *dev, - struct display_timing *timing) -{ - struct tilcdc_panel_priv *priv = dev_get_priv(dev); - - memcpy(timing, &priv->timing, sizeof(*timing)); - return 0; -} - -static int tilcdc_panel_remove(struct udevice *dev) -{ - struct tilcdc_panel_priv *priv = dev_get_priv(dev); - - if (dm_gpio_is_valid(&priv->enable)) - dm_gpio_free(dev, &priv->enable); - - return 0; -} - -static int tilcdc_panel_probe(struct udevice *dev) -{ - struct tilcdc_panel_priv *priv = dev_get_priv(dev); - int err; - - err = uclass_get_device_by_phandle(UCLASS_PANEL_BACKLIGHT, dev, - "backlight", &priv->backlight); - if (err) - dev_warn(dev, "failed to get backlight\n"); - - err = gpio_request_by_name(dev, "enable-gpios", 0, &priv->enable, - GPIOD_IS_OUT); - if (err) { - dev_warn(dev, "failed to get enable GPIO\n"); - if (err != -ENOENT) - return err; - } - - return 0; -} - -static int tilcdc_panel_of_to_plat(struct udevice *dev) -{ - struct tilcdc_panel_priv *priv = dev_get_priv(dev); - ofnode node; - int err; - - err = ofnode_decode_display_timing(dev_ofnode(dev), 0, &priv->timing); - if (err) { - dev_err(dev, "failed to get display timing\n"); - return err; - } - - node = dev_read_subnode(dev, "panel-info"); - if (!ofnode_valid(node)) { - dev_err(dev, "missing 'panel-info' node\n"); - return -ENXIO; - } - - err |= ofnode_read_u32(node, "ac-bias", &priv->info.ac_bias); - err |= ofnode_read_u32(node, "ac-bias-intrpt", - &priv->info.ac_bias_intrpt); - err |= ofnode_read_u32(node, "dma-burst-sz", &priv->info.dma_burst_sz); - err |= ofnode_read_u32(node, "bpp", &priv->info.bpp); - err |= ofnode_read_u32(node, "fdd", &priv->info.fdd); - err |= ofnode_read_u32(node, "sync-edge", &priv->info.sync_edge); - err |= ofnode_read_u32(node, "sync-ctrl", &priv->info.sync_ctrl); - err |= ofnode_read_u32(node, "raster-order", &priv->info.raster_order); - err |= ofnode_read_u32(node, "fifo-th", &priv->info.fifo_th); - if (err) { - dev_err(dev, "failed to get panel info\n"); - return err; - } - - /* optional */ - priv->info.tft_alt_mode = ofnode_read_bool(node, "tft-alt-mode"); - priv->info.invert_pxl_clk = ofnode_read_bool(node, "invert-pxl-clk"); - - dev_dbg(dev, "LCD: %dx%d, bpp=%d, clk=%d Hz\n", - priv->timing.hactive.typ, priv->timing.vactive.typ, - priv->info.bpp, priv->timing.pixelclock.typ); - dev_dbg(dev, " hbp=%d, hfp=%d, hsw=%d\n", - priv->timing.hback_porch.typ, priv->timing.hfront_porch.typ, - priv->timing.hsync_len.typ); - dev_dbg(dev, " vbp=%d, vfp=%d, vsw=%d\n", - priv->timing.vback_porch.typ, priv->timing.vfront_porch.typ, - priv->timing.vsync_len.typ); - - return 0; -} - -static const struct panel_ops tilcdc_panel_ops = { - .enable_backlight = tilcdc_panel_enable_backlight, - .set_backlight = tilcdc_panel_set_backlight, - .get_display_timing = tilcdc_panel_get_display_timing, -}; - -static const struct udevice_id tilcdc_panel_ids[] = { - {.compatible = "ti,tilcdc,panel"}, - {} -}; - -U_BOOT_DRIVER(tilcdc_panel) = { - .name = "tilcdc_panel", - .id = UCLASS_PANEL, - .of_match = tilcdc_panel_ids, - .ops = &tilcdc_panel_ops, - .of_to_plat = tilcdc_panel_of_to_plat, - .probe = tilcdc_panel_probe, - .remove = tilcdc_panel_remove, - .priv_auto = sizeof(struct tilcdc_panel_priv), -}; diff --git a/drivers/video/ti/tilcdc-panel.h b/drivers/video/ti/tilcdc-panel.h deleted file mode 100644 index 6bcfbf8..0000000 --- a/drivers/video/ti/tilcdc-panel.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it> - */ - -#ifndef _TILCDC_PANEL_H -#define _TILCDC_PANEL_H - -#include "tilcdc.h" - -int tilcdc_panel_get_display_info(struct udevice *dev, - struct tilcdc_panel_info *info); - -#endif /* _TILCDC_PANEL_H */ diff --git a/drivers/video/ti/tilcdc.c b/drivers/video/ti/tilcdc.c deleted file mode 100644 index 90c1edd..0000000 --- a/drivers/video/ti/tilcdc.c +++ /dev/null @@ -1,426 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0+ -/* - * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it> - */ - -#include <common.h> -#include <clk.h> -#include <dm.h> -#include <dm/device_compat.h> -#include <lcd.h> -#include <log.h> -#include <panel.h> -#include <video.h> -#include <asm/global_data.h> -#include <asm/io.h> -#include <asm/utils.h> -#include "tilcdc.h" -#include "tilcdc-panel.h" - -#define LCDC_FMAX 200000000 - -/* LCD Control Register */ -#define LCDC_CTRL_CLK_DIVISOR_MASK GENMASK(15, 8) -#define LCDC_CTRL_RASTER_MODE BIT(0) -#define LCDC_CTRL_CLK_DIVISOR(x) (((x) & GENMASK(7, 0)) << 8) -/* LCD Clock Enable Register */ -#define LCDC_CLKC_ENABLE_CORECLKEN BIT(0) -#define LCDC_CLKC_ENABLE_LIDDCLKEN BIT(1) -#define LCDC_CLKC_ENABLE_DMACLKEN BIT(2) -/* LCD DMA Control Register */ -#define LCDC_DMA_CTRL_BURST_SIZE(x) (((x) & GENMASK(2, 0)) << 4) -#define LCDC_DMA_CTRL_BURST_1 0x0 -#define LCDC_DMA_CTRL_BURST_2 0x1 -#define LCDC_DMA_CTRL_BURST_4 0x2 -#define LCDC_DMA_CTRL_BURST_8 0x3 -#define LCDC_DMA_CTRL_BURST_16 0x4 -#define LCDC_DMA_CTRL_FIFO_TH(x) (((x) & GENMASK(2, 0)) << 8) -/* LCD Timing_0 Register */ -#define LCDC_RASTER_TIMING_0_HORMSB(x) ((((x) - 1) & BIT(10)) >> 7) -#define LCDC_RASTER_TIMING_0_HORLSB(x) (((((x) >> 4) - 1) & GENMASK(5, 0)) << 4) -#define LCDC_RASTER_TIMING_0_HSWLSB(x) ((((x) - 1) & GENMASK(5, 0)) << 10) -#define LCDC_RASTER_TIMING_0_HFPLSB(x) ((((x) - 1) & GENMASK(7, 0)) << 16) -#define LCDC_RASTER_TIMING_0_HBPLSB(x) ((((x) - 1) & GENMASK(7, 0)) << 24) -/* LCD Timing_1 Register */ -#define LCDC_RASTER_TIMING_1_VERLSB(x) (((x) - 1) & GENMASK(9, 0)) -#define LCDC_RASTER_TIMING_1_VSW(x) ((((x) - 1) & GENMASK(5, 0)) << 10) -#define LCDC_RASTER_TIMING_1_VFP(x) (((x) & GENMASK(7, 0)) << 16) -#define LCDC_RASTER_TIMING_1_VBP(x) (((x) & GENMASK(7, 0)) << 24) -/* LCD Timing_2 Register */ -#define LCDC_RASTER_TIMING_2_HFPMSB(x) ((((x) - 1) & GENMASK(9, 8)) >> 8) -#define LCDC_RASTER_TIMING_2_HBPMSB(x) ((((x) - 1) & GENMASK(9, 8)) >> 4) -#define LCDC_RASTER_TIMING_2_ACB(x) (((x) & GENMASK(7, 0)) << 8) -#define LCDC_RASTER_TIMING_2_ACBI(x) (((x) & GENMASK(3, 0)) << 16) -#define LCDC_RASTER_TIMING_2_VSYNC_INVERT BIT(20) -#define LCDC_RASTER_TIMING_2_HSYNC_INVERT BIT(21) -#define LCDC_RASTER_TIMING_2_PXCLK_INVERT BIT(22) -#define LCDC_RASTER_TIMING_2_DE_INVERT BIT(23) -#define LCDC_RASTER_TIMING_2_HSVS_RISEFALL BIT(24) -#define LCDC_RASTER_TIMING_2_HSVS_CONTROL BIT(25) -#define LCDC_RASTER_TIMING_2_VERMSB(x) ((((x) - 1) & BIT(10)) << 16) -#define LCDC_RASTER_TIMING_2_HSWMSB(x) ((((x) - 1) & GENMASK(9, 6)) << 21) -/* LCD Raster Ctrl Register */ -#define LCDC_RASTER_CTRL_ENABLE BIT(0) -#define LCDC_RASTER_CTRL_TFT_MODE BIT(7) -#define LCDC_RASTER_CTRL_DATA_ORDER BIT(8) -#define LCDC_RASTER_CTRL_REQDLY(x) (((x) & GENMASK(7, 0)) << 12) -#define LCDC_RASTER_CTRL_PALMODE_RAWDATA (0x02 << 20) -#define LCDC_RASTER_CTRL_TFT_ALT_ENABLE BIT(23) -#define LCDC_RASTER_CTRL_TFT_24BPP_MODE BIT(25) -#define LCDC_RASTER_CTRL_TFT_24BPP_UNPACK BIT(26) - -enum { - LCDC_MAX_WIDTH = 2048, - LCDC_MAX_HEIGHT = 2048, - LCDC_MAX_LOG2_BPP = VIDEO_BPP32, -}; - -struct tilcdc_regs { - u32 pid; - u32 ctrl; - u32 gap0; - u32 lidd_ctrl; - u32 lidd_cs0_conf; - u32 lidd_cs0_addr; - u32 lidd_cs0_data; - u32 lidd_cs1_conf; - u32 lidd_cs1_addr; - u32 lidd_cs1_data; - u32 raster_ctrl; - u32 raster_timing0; - u32 raster_timing1; - u32 raster_timing2; - u32 raster_subpanel; - u32 raster_subpanel2; - u32 lcddma_ctrl; - u32 lcddma_fb0_base; - u32 lcddma_fb0_ceiling; - u32 lcddma_fb1_base; - u32 lcddma_fb1_ceiling; - u32 sysconfig; - u32 irqstatus_raw; - u32 irqstatus; - u32 irqenable_set; - u32 irqenable_clear; - u32 gap1; - u32 clkc_enable; - u32 clkc_reset; -}; - -struct tilcdc_priv { - struct tilcdc_regs *regs; - struct clk gclk; - struct clk dpll_m2_clk; -}; - -DECLARE_GLOBAL_DATA_PTR; - -static ulong tilcdc_set_pixel_clk_rate(struct udevice *dev, ulong rate) -{ - struct tilcdc_priv *priv = dev_get_priv(dev); - struct tilcdc_regs *regs = priv->regs; - ulong mult_rate, mult_round_rate, best_err, err; - u32 v; - int div, i; - - best_err = rate; - div = 0; - for (i = 2; i <= 255; i++) { - mult_rate = rate * i; - mult_round_rate = clk_round_rate(&priv->gclk, mult_rate); - if (IS_ERR_VALUE(mult_round_rate)) - return mult_round_rate; - - err = mult_rate - mult_round_rate; - if (err < best_err) { - best_err = err; - div = i; - if (err == 0) - break; - } - } - - if (div == 0) { - dev_err(dev, "failed to find a divisor\n"); - return -EFAULT; - } - - mult_rate = clk_set_rate(&priv->gclk, rate * div); - v = readl(®s->ctrl) & ~LCDC_CTRL_CLK_DIVISOR_MASK; - v |= LCDC_CTRL_CLK_DIVISOR(div); - writel(v, ®s->ctrl); - rate = mult_rate / div; - dev_dbg(dev, "rate=%ld, div=%d, err=%ld\n", rate, div, err); - return rate; -} - -static int tilcdc_remove(struct udevice *dev) -{ - struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); - struct tilcdc_priv *priv = dev_get_priv(dev); - - uc_plat->base -= 0x20; - uc_plat->size += 0x20; - clk_release_all(&priv->gclk, 1); - clk_release_all(&priv->dpll_m2_clk, 1); - return 0; -} - -static int tilcdc_probe(struct udevice *dev) -{ - struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); - struct video_priv *uc_priv = dev_get_uclass_priv(dev); - struct tilcdc_priv *priv = dev_get_priv(dev); - struct tilcdc_regs *regs = priv->regs; - struct udevice *panel, *clk_dev; - struct tilcdc_panel_info info; - struct display_timing timing; - ulong rate; - u32 reg; - int err; - - /* Before relocation we don't need to do anything */ - if (!(gd->flags & GD_FLG_RELOC)) - return 0; - - err = uclass_get_device(UCLASS_PANEL, 0, &panel); - if (err) { - dev_err(dev, "failed to get panel\n"); - return err; - } - - err = panel_get_display_timing(panel, &timing); - if (err) { - dev_err(dev, "failed to get display timing\n"); - return err; - } - - if (timing.pixelclock.typ > (LCDC_FMAX / 2)) { - dev_err(dev, "invalid display clock-frequency: %d Hz\n", - timing.pixelclock.typ); - return -EINVAL; - } - - if (timing.hactive.typ > LCDC_MAX_WIDTH) - timing.hactive.typ = LCDC_MAX_WIDTH; - - if (timing.vactive.typ > LCDC_MAX_HEIGHT) - timing.vactive.typ = LCDC_MAX_HEIGHT; - - err = tilcdc_panel_get_display_info(panel, &info); - if (err) { - dev_err(dev, "failed to get panel info\n"); - return err; - } - - switch (info.bpp) { - case 16: - case 24: - case 32: - break; - default: - dev_err(dev, "invalid seting, bpp: %d\n", info.bpp); - return -EINVAL; - } - - switch (info.dma_burst_sz) { - case 1: - case 2: - case 4: - case 8: - case 16: - break; - default: - dev_err(dev, "invalid setting, dma-burst-sz: %d\n", - info.dma_burst_sz); - return -EINVAL; - } - - err = uclass_get_device_by_name(UCLASS_CLK, "lcd_gclk@534", &clk_dev); - if (err) { - dev_err(dev, "failed to get lcd_gclk device\n"); - return err; - } - - err = clk_request(clk_dev, &priv->gclk); - if (err) { - dev_err(dev, "failed to get %s clock\n", clk_dev->name); - return err; - } - - rate = tilcdc_set_pixel_clk_rate(dev, timing.pixelclock.typ); - if (IS_ERR_VALUE(rate)) { - dev_err(dev, "failed to set pixel clock rate\n"); - return rate; - } - - err = uclass_get_device_by_name(UCLASS_CLK, "dpll_disp_m2_ck@4a4", - &clk_dev); - if (err) { - dev_err(dev, "failed to get dpll_disp_m2 clock device\n"); - return err; - } - - err = clk_request(clk_dev, &priv->dpll_m2_clk); - if (err) { - dev_err(dev, "failed to get %s clock\n", clk_dev->name); - return err; - } - - err = clk_set_parent(&priv->gclk, &priv->dpll_m2_clk); - if (err) { - dev_err(dev, "failed to set %s clock as %s's parent\n", - priv->dpll_m2_clk.dev->name, priv->gclk.dev->name); - return err; - } - - /* palette default entry */ - memset((void *)uc_plat->base, 0, 0x20); - *(unsigned int *)uc_plat->base = 0x4000; - /* point fb behind palette */ - uc_plat->base += 0x20; - uc_plat->size -= 0x20; - - writel(LCDC_CLKC_ENABLE_CORECLKEN | LCDC_CLKC_ENABLE_LIDDCLKEN | - LCDC_CLKC_ENABLE_DMACLKEN, ®s->clkc_enable); - writel(0, ®s->raster_ctrl); - - reg = readl(®s->ctrl) & LCDC_CTRL_CLK_DIVISOR_MASK; - reg |= LCDC_CTRL_RASTER_MODE; - writel(reg, ®s->ctrl); - - reg = (timing.hactive.typ * timing.vactive.typ * info.bpp) >> 3; - reg += uc_plat->base; - writel(uc_plat->base, ®s->lcddma_fb0_base); - writel(reg, ®s->lcddma_fb0_ceiling); - writel(uc_plat->base, ®s->lcddma_fb1_base); - writel(reg, ®s->lcddma_fb1_ceiling); - - reg = LCDC_DMA_CTRL_FIFO_TH(info.fifo_th); - switch (info.dma_burst_sz) { - case 1: - reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_1); - break; - case 2: - reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_2); - break; - case 4: - reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_4); - break; - case 8: - reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_8); - break; - case 16: - reg |= LCDC_DMA_CTRL_BURST_SIZE(LCDC_DMA_CTRL_BURST_16); - break; - } - - writel(reg, ®s->lcddma_ctrl); - - writel(LCDC_RASTER_TIMING_0_HORLSB(timing.hactive.typ) | - LCDC_RASTER_TIMING_0_HORMSB(timing.hactive.typ) | - LCDC_RASTER_TIMING_0_HFPLSB(timing.hfront_porch.typ) | - LCDC_RASTER_TIMING_0_HBPLSB(timing.hback_porch.typ) | - LCDC_RASTER_TIMING_0_HSWLSB(timing.hsync_len.typ), - ®s->raster_timing0); - - writel(LCDC_RASTER_TIMING_1_VBP(timing.vback_porch.typ) | - LCDC_RASTER_TIMING_1_VFP(timing.vfront_porch.typ) | - LCDC_RASTER_TIMING_1_VSW(timing.vsync_len.typ) | - LCDC_RASTER_TIMING_1_VERLSB(timing.vactive.typ), - ®s->raster_timing1); - - reg = LCDC_RASTER_TIMING_2_ACB(info.ac_bias) | - LCDC_RASTER_TIMING_2_ACBI(info.ac_bias_intrpt) | - LCDC_RASTER_TIMING_2_HSWMSB(timing.hsync_len.typ) | - LCDC_RASTER_TIMING_2_VERMSB(timing.vactive.typ) | - LCDC_RASTER_TIMING_2_HBPMSB(timing.hback_porch.typ) | - LCDC_RASTER_TIMING_2_HFPMSB(timing.hfront_porch.typ); - - if (timing.flags & DISPLAY_FLAGS_VSYNC_LOW) - reg |= LCDC_RASTER_TIMING_2_VSYNC_INVERT; - - if (timing.flags & DISPLAY_FLAGS_HSYNC_LOW) - reg |= LCDC_RASTER_TIMING_2_HSYNC_INVERT; - - if (info.invert_pxl_clk) - reg |= LCDC_RASTER_TIMING_2_PXCLK_INVERT; - - if (info.sync_edge) - reg |= LCDC_RASTER_TIMING_2_HSVS_RISEFALL; - - if (info.sync_ctrl) - reg |= LCDC_RASTER_TIMING_2_HSVS_CONTROL; - - writel(reg, ®s->raster_timing2); - - reg = LCDC_RASTER_CTRL_PALMODE_RAWDATA | LCDC_RASTER_CTRL_TFT_MODE | - LCDC_RASTER_CTRL_ENABLE | LCDC_RASTER_CTRL_REQDLY(info.fdd); - - if (info.tft_alt_mode) - reg |= LCDC_RASTER_CTRL_TFT_ALT_ENABLE; - - if (info.bpp == 24) - reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE; - else if (info.bpp == 32) - reg |= LCDC_RASTER_CTRL_TFT_24BPP_MODE | - LCDC_RASTER_CTRL_TFT_24BPP_UNPACK; - - if (info.raster_order) - reg |= LCDC_RASTER_CTRL_DATA_ORDER; - - writel(reg, ®s->raster_ctrl); - - uc_priv->xsize = timing.hactive.typ; - uc_priv->ysize = timing.vactive.typ; - uc_priv->bpix = log_2_n_round_up(info.bpp); - - err = panel_enable_backlight(panel); - if (err) { - dev_err(dev, "failed to enable panel backlight\n"); - return err; - } - - return 0; -} - -static int tilcdc_of_to_plat(struct udevice *dev) -{ - struct tilcdc_priv *priv = dev_get_priv(dev); - - priv->regs = (struct tilcdc_regs *)dev_read_addr(dev); - if ((fdt_addr_t)priv->regs == FDT_ADDR_T_NONE) { - dev_err(dev, "failed to get base address\n"); - return -EINVAL; - } - - dev_dbg(dev, "LCD: base address=0x%x\n", (unsigned int)priv->regs); - return 0; -} - -static int tilcdc_bind(struct udevice *dev) -{ - struct video_uc_plat *uc_plat = dev_get_uclass_plat(dev); - - uc_plat->size = ((LCDC_MAX_WIDTH * LCDC_MAX_HEIGHT * - (1 << LCDC_MAX_LOG2_BPP)) >> 3) + 0x20; - - dev_dbg(dev, "frame buffer size 0x%x\n", uc_plat->size); - return 0; -} - -static const struct udevice_id tilcdc_ids[] = { - {.compatible = "ti,am33xx-tilcdc"}, - {} -}; - -U_BOOT_DRIVER(tilcdc) = { - .name = "tilcdc", - .id = UCLASS_VIDEO, - .of_match = tilcdc_ids, - .bind = tilcdc_bind, - .of_to_plat = tilcdc_of_to_plat, - .probe = tilcdc_probe, - .remove = tilcdc_remove, - .priv_auto = sizeof(struct tilcdc_priv) -}; diff --git a/drivers/video/ti/tilcdc.h b/drivers/video/ti/tilcdc.h deleted file mode 100644 index 2645921..0000000 --- a/drivers/video/ti/tilcdc.h +++ /dev/null @@ -1,38 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0+ */ -/* - * Copyright (C) 2020 Dario Binacchi <dariobin@libero.it> - */ - -#ifndef _TILCDC_H -#define _TILCDC_H - -/** - * tilcdc_panel_info: Panel parameters - * - * @ac_bias: AC Bias Pin Frequency - * @ac_bias_intrpt: AC Bias Pin Transitions per Interrupt - * @dma_burst_sz: DMA burst size - * @bpp: Bits per pixel - * @fdd: FIFO DMA Request Delay - * @tft_alt_mode: TFT Alternative Signal Mapping (Only for active) - * @invert_pxl_clk: Invert pixel clock - * @sync_edge: Horizontal and Vertical Sync Edge: 0=rising 1=falling - * @sync_ctrl: Horizontal and Vertical Sync: Control: 0=ignore - * @raster_order: Raster Data Order Select: 1=Most-to-least 0=Least-to-most - * @fifo_th: DMA FIFO threshold - */ -struct tilcdc_panel_info { - u32 ac_bias; - u32 ac_bias_intrpt; - u32 dma_burst_sz; - u32 bpp; - u32 fdd; - bool tft_alt_mode; - bool invert_pxl_clk; - u32 sync_edge; - u32 sync_ctrl; - u32 raster_order; - u32 fifo_th; -}; - -#endif /* _TILCDC_H */ diff --git a/drivers/video/vidconsole-uclass.c b/drivers/video/vidconsole-uclass.c index f42db40..6bdfb6e 100644 --- a/drivers/video/vidconsole-uclass.c +++ b/drivers/video/vidconsole-uclass.c @@ -19,15 +19,6 @@ #include <video_font.h> /* Bitmap font for code page 437 */ #include <linux/ctype.h> -/* - * Structure to describe a console color - */ -struct vid_rgb { - u32 r; - u32 g; - u32 b; -}; - /* By default we scroll by a single line */ #ifndef CONFIG_CONSOLE_SCROLL_LINES #define CONFIG_CONSOLE_SCROLL_LINES 1 @@ -124,61 +115,6 @@ static void vidconsole_newline(struct udevice *dev) } } -static const struct vid_rgb colors[VID_COLOR_COUNT] = { - { 0x00, 0x00, 0x00 }, /* black */ - { 0xc0, 0x00, 0x00 }, /* red */ - { 0x00, 0xc0, 0x00 }, /* green */ - { 0xc0, 0x60, 0x00 }, /* brown */ - { 0x00, 0x00, 0xc0 }, /* blue */ - { 0xc0, 0x00, 0xc0 }, /* magenta */ - { 0x00, 0xc0, 0xc0 }, /* cyan */ - { 0xc0, 0xc0, 0xc0 }, /* light gray */ - { 0x80, 0x80, 0x80 }, /* gray */ - { 0xff, 0x00, 0x00 }, /* bright red */ - { 0x00, 0xff, 0x00 }, /* bright green */ - { 0xff, 0xff, 0x00 }, /* yellow */ - { 0x00, 0x00, 0xff }, /* bright blue */ - { 0xff, 0x00, 0xff }, /* bright magenta */ - { 0x00, 0xff, 0xff }, /* bright cyan */ - { 0xff, 0xff, 0xff }, /* white */ -}; - -u32 vid_console_color(struct video_priv *priv, unsigned int idx) -{ - switch (priv->bpix) { - case VIDEO_BPP16: - if (CONFIG_IS_ENABLED(VIDEO_BPP16)) { - return ((colors[idx].r >> 3) << 11) | - ((colors[idx].g >> 2) << 5) | - ((colors[idx].b >> 3) << 0); - } - break; - case VIDEO_BPP32: - if (CONFIG_IS_ENABLED(VIDEO_BPP32)) { - if (priv->format == VIDEO_X2R10G10B10) - return (colors[idx].r << 22) | - (colors[idx].g << 12) | - (colors[idx].b << 2); - else - return (colors[idx].r << 16) | - (colors[idx].g << 8) | - (colors[idx].b << 0); - } - break; - default: - break; - } - - /* - * For unknown bit arrangements just support - * black and white. - */ - if (idx) - return 0xffffff; /* white */ - - return 0x000000; /* black */ -} - static char *parsenum(char *s, int *num) { char *end; @@ -186,6 +122,15 @@ static char *parsenum(char *s, int *num) return end; } +void vidconsole_set_cursor_pos(struct udevice *dev, int x, int y) +{ + struct vidconsole_priv *priv = dev_get_uclass_priv(dev); + + priv->xcur_frac = VID_TO_POS(x); + priv->xstart_frac = priv->xcur_frac; + priv->ycur = y; +} + /** * set_cursor_position() - set cursor position * @@ -441,28 +386,28 @@ static void vidconsole_escape_char(struct udevice *dev, char ch) case 1: /* bold */ vid_priv->fg_col_idx |= 8; - vid_priv->colour_fg = vid_console_color( + vid_priv->colour_fg = video_index_to_colour( vid_priv, vid_priv->fg_col_idx); break; case 7: /* reverse video */ - vid_priv->colour_fg = vid_console_color( + vid_priv->colour_fg = video_index_to_colour( vid_priv, vid_priv->bg_col_idx); - vid_priv->colour_bg = vid_console_color( + vid_priv->colour_bg = video_index_to_colour( vid_priv, vid_priv->fg_col_idx); break; case 30 ... 37: /* foreground color */ vid_priv->fg_col_idx &= ~7; vid_priv->fg_col_idx |= val - 30; - vid_priv->colour_fg = vid_console_color( + vid_priv->colour_fg = video_index_to_colour( vid_priv, vid_priv->fg_col_idx); break; case 40 ... 47: /* background color, also mask the bold bit */ vid_priv->bg_col_idx &= ~0xf; vid_priv->bg_col_idx |= val - 40; - vid_priv->colour_bg = vid_console_color( + vid_priv->colour_bg = video_index_to_colour( vid_priv, vid_priv->bg_col_idx); break; default: @@ -672,64 +617,14 @@ int vidconsole_memmove(struct udevice *dev, void *dst, const void *src, } #endif -#if CONFIG_IS_ENABLED(CMD_VIDCONSOLE) void vidconsole_position_cursor(struct udevice *dev, unsigned col, unsigned row) { struct vidconsole_priv *priv = dev_get_uclass_priv(dev); struct udevice *vid_dev = dev->parent; struct video_priv *vid_priv = dev_get_uclass_priv(vid_dev); + short x, y; - col *= priv->x_charsize; - row *= priv->y_charsize; - priv->xcur_frac = VID_TO_POS(min_t(short, col, vid_priv->xsize - 1)); - priv->xstart_frac = priv->xcur_frac; - priv->ycur = min_t(short, row, vid_priv->ysize - 1); + x = min_t(short, col * priv->x_charsize, vid_priv->xsize - 1); + y = min_t(short, row * priv->y_charsize, vid_priv->ysize - 1); + vidconsole_set_cursor_pos(dev, x, y); } - -static int do_video_setcursor(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - unsigned int col, row; - struct udevice *dev; - - if (argc != 3) - return CMD_RET_USAGE; - - if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev)) - return CMD_RET_FAILURE; - col = dectoul(argv[1], NULL); - row = dectoul(argv[2], NULL); - vidconsole_position_cursor(dev, col, row); - - return 0; -} - -static int do_video_puts(struct cmd_tbl *cmdtp, int flag, int argc, - char *const argv[]) -{ - struct udevice *dev; - const char *s; - - if (argc != 2) - return CMD_RET_USAGE; - - if (uclass_first_device_err(UCLASS_VIDEO_CONSOLE, &dev)) - return CMD_RET_FAILURE; - for (s = argv[1]; *s; s++) - vidconsole_put_char(dev, *s); - - return video_sync(dev->parent, false); -} - -U_BOOT_CMD( - setcurs, 3, 1, do_video_setcursor, - "set cursor position within screen", - " <col> <row> in character" -); - -U_BOOT_CMD( - lcdputs, 2, 1, do_video_puts, - "print string on video framebuffer", - " <string>" -); -#endif /* CONFIG_IS_ENABLED(CMD_VIDCONSOLE) */ diff --git a/drivers/video/video-uclass.c b/drivers/video/video-uclass.c index 01e8af5..0ce376c 100644 --- a/drivers/video/video-uclass.c +++ b/drivers/video/video-uclass.c @@ -64,6 +64,13 @@ struct video_uc_priv { ulong video_ptr; }; +/** struct vid_rgb - Describes a video colour */ +struct vid_rgb { + u32 r; + u32 g; + u32 b; +}; + void video_set_flush_dcache(struct udevice *dev, bool flush) { struct video_priv *priv = dev_get_uclass_priv(dev); @@ -119,7 +126,7 @@ int video_reserve(ulong *addrp) return 0; } -int video_clear(struct udevice *dev) +int video_fill(struct udevice *dev, u32 colour) { struct video_priv *priv = dev_get_uclass_priv(dev); int ret; @@ -131,7 +138,7 @@ int video_clear(struct udevice *dev) u16 *end = priv->fb + priv->fb_size; while (ppix < end) - *ppix++ = priv->colour_bg; + *ppix++ = colour; break; } case VIDEO_BPP32: @@ -140,11 +147,11 @@ int video_clear(struct udevice *dev) u32 *end = priv->fb + priv->fb_size; while (ppix < end) - *ppix++ = priv->colour_bg; + *ppix++ = colour; break; } default: - memset(priv->fb, priv->colour_bg, priv->fb_size); + memset(priv->fb, colour, priv->fb_size); break; } ret = video_sync_copy(dev, priv->fb, priv->fb + priv->fb_size); @@ -154,6 +161,73 @@ int video_clear(struct udevice *dev) return video_sync(dev, false); } +int video_clear(struct udevice *dev) +{ + struct video_priv *priv = dev_get_uclass_priv(dev); + int ret; + + ret = video_fill(dev, priv->colour_bg); + if (ret) + return ret; + + return 0; +} + +static const struct vid_rgb colours[VID_COLOUR_COUNT] = { + { 0x00, 0x00, 0x00 }, /* black */ + { 0xc0, 0x00, 0x00 }, /* red */ + { 0x00, 0xc0, 0x00 }, /* green */ + { 0xc0, 0x60, 0x00 }, /* brown */ + { 0x00, 0x00, 0xc0 }, /* blue */ + { 0xc0, 0x00, 0xc0 }, /* magenta */ + { 0x00, 0xc0, 0xc0 }, /* cyan */ + { 0xc0, 0xc0, 0xc0 }, /* light gray */ + { 0x80, 0x80, 0x80 }, /* gray */ + { 0xff, 0x00, 0x00 }, /* bright red */ + { 0x00, 0xff, 0x00 }, /* bright green */ + { 0xff, 0xff, 0x00 }, /* yellow */ + { 0x00, 0x00, 0xff }, /* bright blue */ + { 0xff, 0x00, 0xff }, /* bright magenta */ + { 0x00, 0xff, 0xff }, /* bright cyan */ + { 0xff, 0xff, 0xff }, /* white */ +}; + +u32 video_index_to_colour(struct video_priv *priv, unsigned int idx) +{ + switch (priv->bpix) { + case VIDEO_BPP16: + if (CONFIG_IS_ENABLED(VIDEO_BPP16)) { + return ((colours[idx].r >> 3) << 11) | + ((colours[idx].g >> 2) << 5) | + ((colours[idx].b >> 3) << 0); + } + break; + case VIDEO_BPP32: + if (CONFIG_IS_ENABLED(VIDEO_BPP32)) { + if (priv->format == VIDEO_X2R10G10B10) + return (colours[idx].r << 22) | + (colours[idx].g << 12) | + (colours[idx].b << 2); + else + return (colours[idx].r << 16) | + (colours[idx].g << 8) | + (colours[idx].b << 0); + } + break; + default: + break; + } + + /* + * For unknown bit arrangements just support + * black and white. + */ + if (idx) + return 0xffffff; /* white */ + + return 0x000000; /* black */ +} + void video_set_default_colors(struct udevice *dev, bool invert) { struct video_priv *priv = dev_get_uclass_priv(dev); @@ -176,8 +250,8 @@ void video_set_default_colors(struct udevice *dev, bool invert) } priv->fg_col_idx = fore; priv->bg_col_idx = back; - priv->colour_fg = vid_console_color(priv, fore); - priv->colour_bg = vid_console_color(priv, back); + priv->colour_fg = video_index_to_colour(priv, fore); + priv->colour_bg = video_index_to_colour(priv, back); } /* Flush video activity to the caches */ @@ -332,6 +406,11 @@ int video_sync_copy_all(struct udevice *dev) SPLASH_DECL(u_boot_logo); +void *video_get_u_boot_logo(void) +{ + return SPLASH_START(u_boot_logo); +} + static int show_splash(struct udevice *dev) { u8 *data = SPLASH_START(u_boot_logo); @@ -342,6 +421,17 @@ static int show_splash(struct udevice *dev) return 0; } +int video_default_font_height(struct udevice *dev) +{ + struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev); + + if (IS_ENABLED(CONFIG_CONSOLE_TRUETYPE)) + return IF_ENABLED_INT(CONFIG_CONSOLE_TRUETYPE, + CONFIG_CONSOLE_TRUETYPE_SIZE); + + return vc_priv->y_charsize; +} + /* Set up the display ready for use */ static int video_post_probe(struct udevice *dev) { diff --git a/drivers/video/video_bmp.c b/drivers/video/video_bmp.c index 082895a..6188a13 100644 --- a/drivers/video/video_bmp.c +++ b/drivers/video/video_bmp.c @@ -229,6 +229,16 @@ static void video_splash_align_axis(int *axis, unsigned long panel_size, *axis = max(0, (int)axis_alignment); } +void video_bmp_get_info(void *bmp_image, ulong *widthp, ulong *heightp, + uint *bpixp) +{ + struct bmp_image *bmp = bmp_image; + + *widthp = get_unaligned_le32(&bmp->header.width); + *heightp = get_unaligned_le32(&bmp->header.height); + *bpixp = get_unaligned_le16(&bmp->header.bit_count); +} + int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, bool align) { @@ -253,9 +263,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, return -EINVAL; } - width = get_unaligned_le32(&bmp->header.width); - height = get_unaligned_le32(&bmp->header.height); - bmp_bpix = get_unaligned_le16(&bmp->header.bit_count); + video_bmp_get_info(bmp, &width, &height, &bmp_bpix); hdr_size = get_unaligned_le16(&bmp->header.size); debug("hdr_size=%d, bmp_bpix=%d\n", hdr_size, bmp_bpix); palette = (void *)bmp + 14 + hdr_size; @@ -283,7 +291,7 @@ int video_bmp_display(struct udevice *dev, ulong bmp_image, int x, int y, !(bmp_bpix == 24 && bpix == 16) && !(bmp_bpix == 24 && bpix == 32)) { printf("Error: %d bit/pixel mode, but BMP has %d bit/pixel\n", - bpix, get_unaligned_le16(&bmp->header.bit_count)); + bpix, colours); return -EPERM; } |