diff options
-rw-r--r-- | configs/evb-rk3288_defconfig | 5 | ||||
-rw-r--r-- | configs/evb-rk3399_defconfig | 1 | ||||
-rw-r--r-- | drivers/video/Kconfig | 31 | ||||
-rw-r--r-- | drivers/video/Makefile | 4 | ||||
-rw-r--r-- | drivers/video/cfb_console.c | 10 | ||||
-rw-r--r-- | drivers/video/ct69000.c | 1168 | ||||
-rw-r--r-- | drivers/video/l5f31188.c | 192 | ||||
-rw-r--r-- | drivers/video/rockchip/Makefile | 4 | ||||
-rw-r--r-- | drivers/video/rockchip/rk3288_mipi.c | 191 | ||||
-rw-r--r-- | drivers/video/rockchip/rk3399_mipi.c | 182 | ||||
-rw-r--r-- | drivers/video/rockchip/rk_mipi.c | 170 | ||||
-rw-r--r-- | drivers/video/rockchip/rk_mipi.h | 32 | ||||
-rw-r--r-- | drivers/video/sed156x.c | 546 | ||||
-rw-r--r-- | drivers/video/sm501.c | 225 | ||||
-rw-r--r-- | include/sed156x.h | 26 | ||||
-rw-r--r-- | include/sm501.h | 35 | ||||
-rw-r--r-- | scripts/config_whitelist.txt | 1 |
17 files changed, 422 insertions, 2401 deletions
diff --git a/configs/evb-rk3288_defconfig b/configs/evb-rk3288_defconfig index 98addee484..a87ffb9abc 100644 --- a/configs/evb-rk3288_defconfig +++ b/configs/evb-rk3288_defconfig @@ -62,6 +62,11 @@ CONFIG_DEBUG_UART_CLOCK=24000000 CONFIG_DEBUG_UART_SHIFT=2 CONFIG_SYS_NS16550=y CONFIG_SYSRESET=y +CONFIG_DM_VIDEO=y +CONFIG_DISPLAY=y +CONFIG_VIDEO_ROCKCHIP=y +CONFIG_VIDEO_ROCKCHIP_MAX_YRES=1200 +CONFIG_DISPLAY_ROCKCHIP_MIPI=y CONFIG_USE_TINY_PRINTF=y CONFIG_CMD_DHRYSTONE=y CONFIG_ERRNO_STR=y diff --git a/configs/evb-rk3399_defconfig b/configs/evb-rk3399_defconfig index 6081411105..55757d2f73 100644 --- a/configs/evb-rk3399_defconfig +++ b/configs/evb-rk3399_defconfig @@ -66,6 +66,7 @@ CONFIG_USB_STORAGE=y CONFIG_DM_VIDEO=y CONFIG_DISPLAY=y CONFIG_VIDEO_ROCKCHIP=y +CONFIG_VIDEO_ROCKCHIP_MAX_YRES=1200 CONFIG_DISPLAY_ROCKCHIP_MIPI=y CONFIG_USE_TINY_PRINTF=y CONFIG_ERRNO_STR=y diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 61dfed8c06..082cc4a528 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -562,36 +562,9 @@ config CONSOLE_SCROLL_LINES console jump but can help speed up operation when scrolling is slow. -config VIDEO_CT69000 - bool "Enable Chips & Technologies 69000 video driver" - depends on VIDEO - help - This enables a frame buffer driver for the Chips & Technologies - ct69000, a fairly old graphics device (circa 2000) which is used - on some hardware. It operates over the ISA bus, and supports - some acceleration features. - - For the CT69000 and SMI_LYNXEM drivers, videomode is - selected via environment 'videomode'. Two different ways - are possible: - - "videomode=num" 'num' is a standard LiLo mode numbers. - Following standard modes are supported (* is default): - - Colors 640x480 800x600 1024x768 1152x864 1280x1024 - -------------+--------------------------------------------- - 8 bits | 0x301* 0x303 0x305 0x161 0x307 - 15 bits | 0x310 0x313 0x316 0x162 0x319 - 16 bits | 0x311 0x314 0x317 0x163 0x31A - 24 bits | 0x312 0x315 0x318 ? 0x31B - -------------+--------------------------------------------- - (i.e. setenv videomode 317; saveenv; reset;) - - - "videomode=bootargs" all the video parameters are parsed - from the bootargs. (See drivers/video/videomodes.c) - config SYS_CONSOLE_BG_COL hex "Background colour" - depends on CFB_CONSOLE || VIDEO_CT69000 + depends on CFB_CONSOLE default 0x00 help Defines the background colour for the console. The value is from @@ -602,7 +575,7 @@ config SYS_CONSOLE_BG_COL config SYS_CONSOLE_FG_COL hex "Foreground colour" - depends on CFB_CONSOLE || VIDEO_CT69000 + depends on CFB_CONSOLE default 0xa0 help Defines the foreground colour for the console. The value is from diff --git a/drivers/video/Makefile b/drivers/video/Makefile index ac5371f2ae..5cf8909295 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile @@ -28,16 +28,13 @@ obj-$(CONFIG_ATMEL_LCD) += atmel_lcdfb.o obj-$(CONFIG_CFB_CONSOLE) += cfb_console.o obj-$(CONFIG_FSL_DIU_FB) += fsl_diu_fb.o videomodes.o obj-$(CONFIG_VIDEO_FSL_DCU_FB) += fsl_dcu_fb.o videomodes.o -obj-$(CONFIG_L5F31188) += l5f31188.o obj-$(CONFIG_PXA_LCD) += pxa_lcd.o obj-$(CONFIG_SCF0403_LCD) += scf0403_lcd.o obj-$(CONFIG_S6E8AX0) += s6e8ax0.o obj-$(CONFIG_S6E63D6) += s6e63d6.o obj-$(CONFIG_LD9040) += ld9040.o -obj-$(CONFIG_SED156X) += sed156x.o obj-$(CONFIG_VIDEO_BCM2835) += bcm2835.o obj-$(CONFIG_VIDEO_COREBOOT) += coreboot.o -obj-$(CONFIG_VIDEO_CT69000) += ct69000.o videomodes.o obj-$(CONFIG_VIDEO_DA8XX) += da8xx-fb.o videomodes.o obj-$(CONFIG_VIDEO_LCD_ANX9804) += anx9804.o obj-$(CONFIG_VIDEO_LCD_HITACHI_TX18D42VM) += hitachi_tx18d42vm_lcd.o @@ -49,7 +46,6 @@ obj-$(CONFIG_VIDEO_MVEBU) += mvebu_lcd.o obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o obj-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o -obj-$(CONFIG_VIDEO_SM501) += sm501.o obj-$(CONFIG_VIDEO_TEGRA20) += tegra.o obj-$(CONFIG_VIDEO_VCXK) += bus_vcxk.o obj-$(CONFIG_VIDEO_VESA) += vesa.o diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c index f54802052e..b6fc7e145b 100644 --- a/drivers/video/cfb_console.c +++ b/drivers/video/cfb_console.c @@ -72,16 +72,6 @@ #include <video.h> #include <linux/compiler.h> -/* - * Defines for the CT69000 driver - */ -#ifdef CONFIG_VIDEO_CT69000 - -#define VIDEO_FB_LITTLE_ENDIAN -#define VIDEO_HW_RECTFILL -#define VIDEO_HW_BITBLT -#endif - #if defined(CONFIG_VIDEO_MXS) #define VIDEO_FB_16BPP_WORD_SWAP #endif diff --git a/drivers/video/ct69000.c b/drivers/video/ct69000.c deleted file mode 100644 index a74e4e6868..0000000000 --- a/drivers/video/ct69000.c +++ /dev/null @@ -1,1168 +0,0 @@ -/* ported from ctfb.c (linux kernel): - * Created in Jan - July 2000 by Thomas Höhenleitner <th@visuelle-maschinen.de> - * - * Ported to U-Boot: - * (C) Copyright 2002 Denis Peter, MPL AG Switzerland - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> - -#ifdef CONFIG_VIDEO - -#include <pci.h> -#include <video_fb.h> -#include "videomodes.h" - -/* debug */ -#undef VGA_DEBUG -#undef VGA_DUMP_REG -#ifdef VGA_DEBUG -#undef _DEBUG -#define _DEBUG 1 -#else -#undef _DEBUG -#define _DEBUG 0 -#endif - -/* Macros */ -#ifndef min -#define min( a, b ) ( ( a ) < ( b ) ) ? ( a ) : ( b ) -#endif -#ifndef max -#define max( a, b ) ( ( a ) > ( b ) ) ? ( a ) : ( b ) -#endif -#ifdef minmax -#error "term minmax already used." -#endif -#define minmax( a, x, b ) max( ( a ), min( ( x ), ( b ) ) ) -#define N_ELTS( x ) ( sizeof( x ) / sizeof( x[ 0 ] ) ) - -/* CT Register Offsets */ -#define CT_AR_O 0x3c0 /* Index and Data write port of the attribute Registers */ -#define CT_GR_O 0x3ce /* Index port of the Graphic Controller Registers */ -#define CT_SR_O 0x3c4 /* Index port of the Sequencer Controller */ -#define CT_CR_O 0x3d4 /* Index port of the CRT Controller */ -#define CT_XR_O 0x3d6 /* Extended Register index */ -#define CT_MSR_W_O 0x3c2 /* Misc. Output Register (write only) */ -#define CT_LUT_MASK_O 0x3c6 /* Color Palette Mask */ -#define CT_LUT_START_O 0x3c8 /* Color Palette Write Mode Index */ -#define CT_LUT_RGB_O 0x3c9 /* Color Palette Data Port */ -#define CT_STATUS_REG0_O 0x3c2 /* Status Register 0 (read only) */ -#define CT_STATUS_REG1_O 0x3da /* Input Status Register 1 (read only) */ - -#define CT_FP_O 0x3d0 /* Index port of the Flat panel Registers */ -#define CT_MR_O 0x3d2 /* Index Port of the Multimedia Extension */ - -/* defines for the memory mapped registers */ -#define BR00_o 0x400000 /* Source and Destination Span Register */ -#define BR01_o 0x400004 /* Pattern/Source Expansion Background Color & Transparency Key Register */ -#define BR02_o 0x400008 /* Pattern/Source Expansion Foreground Color Register */ -#define BR03_o 0x40000C /* Monochrome Source Control Register */ -#define BR04_o 0x400010 /* BitBLT Control Register */ -#define BR05_o 0x400014 /* Pattern Address Registe */ -#define BR06_o 0x400018 /* Source Address Register */ -#define BR07_o 0x40001C /* Destination Address Register */ -#define BR08_o 0x400020 /* Destination Width & Height Register */ -#define BR09_o 0x400024 /* Source Expansion Background Color & Transparency Key Register */ -#define BR0A_o 0x400028 /* Source Expansion Foreground Color Register */ - -#define CURSOR_SIZE 0x1000 /* in KByte for HW Cursor */ -#define PATTERN_ADR (pGD->dprBase + CURSOR_SIZE) /* pattern Memory after Cursor Memory */ -#define PATTERN_SIZE 8*8*4 /* 4 Bytes per Pixel 8 x 8 Pixel */ -#define ACCELMEMORY (CURSOR_SIZE + PATTERN_SIZE) /* reserved Memory for BITBlt and hw cursor */ - -/* Some Mode definitions */ -#define FB_SYNC_HOR_HIGH_ACT 1 /* horizontal sync high active */ -#define FB_SYNC_VERT_HIGH_ACT 2 /* vertical sync high active */ -#define FB_SYNC_EXT 4 /* external sync */ -#define FB_SYNC_COMP_HIGH_ACT 8 /* composite sync high active */ -#define FB_SYNC_BROADCAST 16 /* broadcast video timings */ - /* vtotal = 144d/288n/576i => PAL */ - /* vtotal = 121d/242n/484i => NTSC */ -#define FB_SYNC_ON_GREEN 32 /* sync on green */ - -#define FB_VMODE_NONINTERLACED 0 /* non interlaced */ -#define FB_VMODE_INTERLACED 1 /* interlaced */ -#define FB_VMODE_DOUBLE 2 /* double scan */ -#define FB_VMODE_MASK 255 - -#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */ -#define FB_VMODE_SMOOTH_XPAN 512 /* smooth xpan possible (internally used) */ -#define FB_VMODE_CONUPDATE 512 /* don't update x/yoffset */ - -#define text 0 -#define fntwidth 8 - -/* table for VGA Initialization */ -typedef struct { - const unsigned char reg; - const unsigned char val; -} CT_CFG_TABLE; - -/* this table provides some basic initialisations such as Memory Clock etc */ -static CT_CFG_TABLE xreg[] = { - {0x09, 0x01}, /* CRT Controller Extensions Enable */ - {0x0A, 0x02}, /* Frame Buffer Mapping */ - {0x0B, 0x01}, /* PCI Write Burst support */ - {0x20, 0x00}, /* BitBLT Configuration */ - {0x40, 0x03}, /* Memory Access Control */ - {0x60, 0x00}, /* Video Pin Control */ - {0x61, 0x00}, /* DPMS Synch control */ - {0x62, 0x00}, /* GPIO Pin Control */ - {0x63, 0xBD}, /* GPIO Pin Data */ - {0x67, 0x00}, /* Pin Tri-State */ - {0x80, 0x80}, /* Pixel Pipeline Config 0 register */ - {0xA0, 0x00}, /* Cursor 1 Control Reg */ - {0xA1, 0x00}, /* Cursor 1 Vertical Extension Reg */ - {0xA2, 0x00}, /* Cursor 1 Base Address Low */ - {0xA3, 0x00}, /* Cursor 1 Base Address High */ - {0xA4, 0x00}, /* Cursor 1 X-Position Low */ - {0xA5, 0x00}, /* Cursor 1 X-Position High */ - {0xA6, 0x00}, /* Cursor 1 Y-Position Low */ - {0xA7, 0x00}, /* Cursor 1 Y-Position High */ - {0xA8, 0x00}, /* Cursor 2 Control Reg */ - {0xA9, 0x00}, /* Cursor 2 Vertical Extension Reg */ - {0xAA, 0x00}, /* Cursor 2 Base Address Low */ - {0xAB, 0x00}, /* Cursor 2 Base Address High */ - {0xAC, 0x00}, /* Cursor 2 X-Position Low */ - {0xAD, 0x00}, /* Cursor 2 X-Position High */ - {0xAE, 0x00}, /* Cursor 2 Y-Position Low */ - {0xAF, 0x00}, /* Cursor 2 Y-Position High */ - {0xC0, 0x7D}, /* Dot Clock 0 VCO M-Divisor */ - {0xC1, 0x07}, /* Dot Clock 0 VCO N-Divisor */ - {0xC3, 0x34}, /* Dot Clock 0 Divisor select */ - {0xC4, 0x55}, /* Dot Clock 1 VCO M-Divisor */ - {0xC5, 0x09}, /* Dot Clock 1 VCO N-Divisor */ - {0xC7, 0x24}, /* Dot Clock 1 Divisor select */ - {0xC8, 0x7D}, /* Dot Clock 2 VCO M-Divisor */ - {0xC9, 0x07}, /* Dot Clock 2 VCO N-Divisor */ - {0xCB, 0x34}, /* Dot Clock 2 Divisor select */ - {0xCC, 0x38}, /* Memory Clock 0 VCO M-Divisor */ - {0xCD, 0x03}, /* Memory Clock 0 VCO N-Divisor */ - {0xCE, 0x90}, /* Memory Clock 0 Divisor select */ - {0xCF, 0x06}, /* Clock Config */ - {0xD0, 0x0F}, /* Power Down */ - {0xD1, 0x01}, /* Power Down BitBLT */ - {0xFF, 0xFF} /* end of table */ -}; -/* Clock Config: - * ============= - * - * PD Registers: - * ------------- - * Bit2 and Bit4..6 are used for the Loop Divisor and Post Divisor. - * They are encoded as follows: - * - * +---+--------------+ - * | 2 | Loop Divisor | - * +---+--------------+ - * | 1 | 1 | - * +---+--------------+ - * | 0 | 4 | - * +---+--------------+ - * Note: The Memory Clock does not have a Loop Divisor. - * +---+---+---+--------------+ - * | 6 | 5 | 4 | Post Divisor | - * +---+---+---+--------------+ - * | 0 | 0 | 0 | 1 | - * +---+---+---+--------------+ - * | 0 | 0 | 1 | 2 | - * +---+---+---+--------------+ - * | 0 | 1 | 0 | 4 | - * +---+---+---+--------------+ - * | 0 | 1 | 1 | 8 | - * +---+---+---+--------------+ - * | 1 | 0 | 0 | 16 | - * +---+---+---+--------------+ - * | 1 | 0 | 1 | 32 | - * +---+---+---+--------------+ - * | 1 | 1 | X | reserved | - * +---+---+---+--------------+ - * - * All other bits are reserved in these registers. - * - * Clock VCO M Registers: - * ---------------------- - * These Registers contain the M Value -2. - * - * Clock VCO N Registers: - * ---------------------- - * These Registers contain the N Value -2. - * - * Formulas: - * --------- - * Fvco = (Fref * Loop Divisor * M/N), whereas 100MHz < Fvco < 220MHz - * Fout = Fvco / Post Divisor - * - * Dot Clk0 (default 25MHz): - * ------------------------- - * Fvco = 14.318 * 127 / 9 = 202.045MHz - * Fout = 202.045MHz / 8 = 25.25MHz - * Post Divisor = 8 - * Loop Divisor = 1 - * XRC0 = (M - 2) = 125 = 0x7D - * XRC1 = (N - 2) = 7 = 0x07 - * XRC3 = 0x34 - * - * Dot Clk1 (default 28MHz): - * ------------------------- - * Fvco = 14.318 * 87 / 11 = 113.24MHz - * Fout = 113.24MHz / 4 = 28.31MHz - * Post Divisor = 4 - * Loop Divisor = 1 - * XRC4 = (M - 2) = 85 = 0x55 - * XRC5 = (N - 2) = 9 = 0x09 - * XRC7 = 0x24 - * - * Dot Clk2 (variable for extended modes set to 25MHz): - * ---------------------------------------------------- - * Fvco = 14.318 * 127 / 9 = 202.045MHz - * Fout = 202.045MHz / 8 = 25.25MHz - * Post Divisor = 8 - * Loop Divisor = 1 - * XRC8 = (M - 2) = 125 = 0x7D - * XRC9 = (N - 2) = 7 = 0x07 - * XRCB = 0x34 - * - * Memory Clk for most modes >50MHz: - * ---------------------------------- - * Fvco = 14.318 * 58 / 5 = 166MHz - * Fout = 166MHz / 2 = 83MHz - * Post Divisor = 2 - * XRCC = (M - 2) = 57 = 0x38 - * XRCD = (N - 2) = 3 = 0x03 - * XRCE = 0x90 - * - * Note Bit7 enables the clock source from the VCO - * - */ - -/******************************************************************* - * Chips struct - *******************************************************************/ -struct ctfb_chips_properties { - int device_id; /* PCI Device ID */ - unsigned long max_mem; /* memory for frame buffer */ - int vld_set; /* value of VLD if bit2 in clock control is set */ - int vld_not_set; /* value of VLD if bit2 in clock control is set */ - int mn_diff; /* difference between M/N Value + mn_diff = M/N Register */ - int mn_min; /* min value of M/N Value */ - int mn_max; /* max value of M/N Value */ - int vco_min; /* VCO Min in MHz */ - int vco_max; /* VCO Max in MHz */ -}; - -static const struct ctfb_chips_properties chips[] = { - {PCI_DEVICE_ID_CT_69000, 0x200000, 1, 4, -2, 3, 257, 100, 220}, - {PCI_DEVICE_ID_CT_65555, 0x100000, 16, 4, 0, 1, 255, 48, 220}, /* NOT TESTED */ - {0, 0, 0, 0, 0, 0, 0, 0, 0} /* Terminator */ -}; - -/* - * The Graphic Device - */ -GraphicDevice ctfb; - -/******************************************************************************* -* -* Low Level Routines -*/ - -/******************************************************************************* -* -* Read CT ISA register -*/ -#ifdef VGA_DEBUG -static unsigned char -ctRead (unsigned short index) -{ - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - if (index == CT_AR_O) - /* synch the Flip Flop */ - in8 (pGD->isaBase + CT_STATUS_REG1_O); - - return (in8 (pGD->isaBase + index)); -} -#endif -/******************************************************************************* -* -* Write CT ISA register -*/ -static void -ctWrite (unsigned short index, unsigned char val) -{ - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - - out8 ((pGD->isaBase + index), val); -} - -/******************************************************************************* -* -* Read CT ISA register indexed -*/ -static unsigned char -ctRead_i (unsigned short index, char reg) -{ - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - if (index == CT_AR_O) - /* synch the Flip Flop */ - in8 (pGD->isaBase + CT_STATUS_REG1_O); - out8 ((pGD->isaBase + index), reg); - return (in8 (pGD->isaBase + index + 1)); -} - -/******************************************************************************* -* -* Write CT ISA register indexed -*/ -static void -ctWrite_i (unsigned short index, char reg, char val) -{ - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - if (index == CT_AR_O) { - /* synch the Flip Flop */ - in8 (pGD->isaBase + CT_STATUS_REG1_O); - out8 ((pGD->isaBase + index), reg); - out8 ((pGD->isaBase + index), val); - } else { - out8 ((pGD->isaBase + index), reg); - out8 ((pGD->isaBase + index + 1), val); - } -} - -/******************************************************************************* -* -* Write a table of CT ISA register -*/ -static void -ctLoadRegs (unsigned short index, CT_CFG_TABLE * regTab) -{ - while (regTab->reg != 0xFF) { - ctWrite_i (index, regTab->reg, regTab->val); - regTab++; - } -} - -/*****************************************************************************/ -static void -SetArRegs (void) -{ - int i, tmp; - - for (i = 0; i < 0x10; i++) - ctWrite_i (CT_AR_O, i, i); - if (text) - tmp = 0x04; - else - tmp = 0x41; - - ctWrite_i (CT_AR_O, 0x10, tmp); /* Mode Control Register */ - ctWrite_i (CT_AR_O, 0x11, 0x00); /* Overscan Color Register */ - ctWrite_i (CT_AR_O, 0x12, 0x0f); /* Memory Plane Enable Register */ - if (fntwidth == 9) - tmp = 0x08; - else - tmp = 0x00; - ctWrite_i (CT_AR_O, 0x13, tmp); /* Horizontal Pixel Panning */ - ctWrite_i (CT_AR_O, 0x14, 0x00); /* Color Select Register */ - ctWrite (CT_AR_O, 0x20); /* enable video */ -} - -/*****************************************************************************/ -static void -SetGrRegs (void) -{ /* Set Graphics Mode */ - int i; - - for (i = 0; i < 0x05; i++) - ctWrite_i (CT_GR_O, i, 0); - if (text) { - ctWrite_i (CT_GR_O, 0x05, 0x10); - ctWrite_i (CT_GR_O, 0x06, 0x02); - } else { - ctWrite_i (CT_GR_O, 0x05, 0x40); - ctWrite_i (CT_GR_O, 0x06, 0x05); - } - ctWrite_i (CT_GR_O, 0x07, 0x0f); - ctWrite_i (CT_GR_O, 0x08, 0xff); -} - -/*****************************************************************************/ -static void -SetSrRegs (void) -{ - int tmp = 0; - - ctWrite_i (CT_SR_O, 0x00, 0x00); /* reset */ - /*rr( sr, 0x01, tmp ); - if( fntwidth == 8 ) tmp |= 0x01; else tmp &= ~0x01; - wr( sr, 0x01, tmp ); */ - if (fntwidth == 8) - ctWrite_i (CT_SR_O, 0x01, 0x01); /* Clocking Mode Register */ - else - ctWrite_i (CT_SR_O, 0x01, 0x00); /* Clocking Mode Register */ - ctWrite_i (CT_SR_O, 0x02, 0x0f); /* Enable CPU wr access to given memory plane */ - ctWrite_i (CT_SR_O, 0x03, 0x00); /* Character Map Select Register */ - if (text) - tmp = 0x02; - else - tmp = 0x0e; - ctWrite_i (CT_SR_O, 0x04, tmp); /* Enable CPU accesses to the rest of the 256KB - total VGA memory beyond the first 64KB and set - fb mapping mode. */ - ctWrite_i (CT_SR_O, 0x00, 0x03); /* enable */ -} - -/*****************************************************************************/ -static void -SetBitsPerPixelIntoXrRegs (int bpp) -{ - unsigned int n = (bpp >> 3), tmp; /* only for 15, 8, 16, 24 bpp */ - static char md[4] = { 0x04, 0x02, 0x05, 0x06 }; /* DisplayColorMode */ - static char off[4] = { ~0x20, ~0x30, ~0x20, ~0x10 }; /* mask */ - static char on[4] = { 0x10, 0x00, 0x10, 0x20 }; /* mask */ - if (bpp == 15) - n = 0; - tmp = ctRead_i (CT_XR_O, 0x20); - tmp &= off[n]; - tmp |= on[n]; - ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */ - ctWrite_i (CT_XR_O, 0x81, md[n]); -} - -/*****************************************************************************/ -static void -SetCrRegs (struct ctfb_res_modes *var, int bits_per_pixel) -{ /* he -le- ht|0 hd -ri- hs -h- he */ - unsigned char cr[0x7a]; - int i, tmp; - unsigned int hd, hs, he, ht, hbe; /* Horizontal. */ - unsigned int vd, vs, ve, vt; /* vertical */ - unsigned int bpp, wd, dblscan, interlaced, bcast, CrtHalfLine; - unsigned int CompSyncCharClkDelay, CompSyncPixelClkDelay; - unsigned int NTSC_PAL_HorizontalPulseWidth, BlDelayCtrl; - unsigned int HorizontalEqualizationPulses; - unsigned int HorizontalSerration1Start, HorizontalSerration2Start; - - const int LineCompare = 0x3ff; - unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor */ - unsigned int RAMDAC_BlankPedestalEnable = 0; /* 1=en-, 0=disable, see XR82 */ - - hd = (var->xres) / 8; /* HDisp. */ - hs = (var->xres + var->right_margin) / 8; /* HsStrt */ - he = (var->xres + var->right_margin + var->hsync_len) / 8; /* HsEnd */ - ht = (var->left_margin + var->xres + var->right_margin + var->hsync_len) / 8; /* HTotal */ - hbe = ht - 1; /* HBlankEnable todo docu wants ht here, but it does not work */ - /* ve -up- vt|0 vd -lo- vs -v- ve */ - vd = var->yres; /* VDisplay */ - vs = var->yres + var->lower_margin; /* VSyncStart */ - ve = var->yres + var->lower_margin + var->vsync_len; /* VSyncEnd */ - vt = var->upper_margin + var->yres + var->lower_margin + var->vsync_len; /* VTotal */ - bpp = bits_per_pixel; - dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0; - interlaced = var->vmode & FB_VMODE_INTERLACED; - bcast = var->sync & FB_SYNC_BROADCAST; - CrtHalfLine = bcast ? (hd >> 1) : 0; - BlDelayCtrl = bcast ? 1 : 0; - CompSyncCharClkDelay = 0; /* 2 bit */ - CompSyncPixelClkDelay = 0; /* 3 bit */ - if (bcast) { - NTSC_PAL_HorizontalPulseWidth = 7; /*( var->hsync_len >> 1 ) + 1 */ - HorizontalEqualizationPulses = 0; /* inverse value */ - HorizontalSerration1Start = 31; /* ( ht >> 1 ) */ - HorizontalSerration2Start = 89; /* ( ht >> 1 ) */ - } else { - NTSC_PAL_HorizontalPulseWidth = 0; - /* 4 bit: hsync pulse width = ( ( CR74[4:0] - CR74[5] ) - * / 2 ) + 1 --> CR74[4:0] = 2*(hs-1) + CR74[5] */ - HorizontalEqualizationPulses = 1; /* inverse value */ - HorizontalSerration1Start = 0; /* ( ht >> 1 ) */ - HorizontalSerration2Start = 0; /* ( ht >> 1 ) */ - } - - if (bpp == 15) - bpp = 16; - wd = var->xres * bpp / 64; /* double words per line */ - if (interlaced) { /* we divide all vertical timings, exept vd */ - vs >>= 1; - ve >>= 1; - vt >>= 1; - } - memset (cr, 0, sizeof (cr)); - cr[0x00] = 0xff & (ht - 5); - cr[0x01] = hd - 1; /* soll:4f ist 59 */ - cr[0x02] = hd; - cr[0x03] = (hbe & 0x1F) | 0x80; /* hd + ht - hd */ - cr[0x04] = hs; - cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f); - cr[0x06] = (vt - 2) & 0xFF; - cr[0x30] = (vt - 2) >> 8; - cr[0x07] = ((vt & 0x100) >> 8) - | ((vd & 0x100) >> 7) - | ((vs & 0x100) >> 6) - | ((vs & 0x100) >> 5) - | ((LineCompare & 0x100) >> 4) - | ((vt & 0x200) >> 4) - | ((vd & 0x200) >> 3) - | ((vs & 0x200) >> 2); - cr[0x08] = 0x00; - cr[0x09] = (dblscan << 7) - | ((LineCompare & 0x200) >> 3) - | ((vs & 0x200) >> 4) - | (TextScanLines - 1); - cr[0x10] = vs & 0xff; /* VSyncPulseStart */ - cr[0x32] = (vs & 0xf00) >> 8; /* VSyncPulseStart */ - cr[0x11] = (ve & 0x0f); /* | 0x20; */ - cr[0x12] = (vd - 1) & 0xff; /* LineCount */ - cr[0x31] = ((vd - 1) & 0xf00) >> 8; /* LineCount */ - cr[0x13] = wd & 0xff; - cr[0x41] = (wd & 0xf00) >> 8; - cr[0x15] = vs & 0xff; - cr[0x33] = (vs & 0xf00) >> 8; - cr[0x38] = (0x100 & (ht - 5)) >> 8; - cr[0x3C] = 0xc0 & hbe; - cr[0x16] = (vt - 1) & 0xff; /* vbe - docu wants vt here, */ - cr[0x17] = 0xe3; /* but it does not work */ - cr[0x18] = 0xff & LineCompare; - cr[0x22] = 0xff; /* todo? */ - cr[0x70] = interlaced ? (0x80 | CrtHalfLine) : 0x00; /* check:0xa6 */ - cr[0x71] = 0x80 | (RAMDAC_BlankPedestalEnable << 6) - | (BlDelayCtrl << 5) - | ((0x03 & CompSyncCharClkDelay) << 3) - | (0x07 & CompSyncPixelClkDelay); /* todo: see XR82 */ - cr[0x72] = HorizontalSerration1Start; - cr[0x73] = HorizontalSerration2Start; - cr[0x74] = (HorizontalEqualizationPulses << 5) - | NTSC_PAL_HorizontalPulseWidth; - /* todo: ct69000 has also 0x75-79 */ - /* now set the registers */ - for (i = 0; i <= 0x0d; i++) { /*CR00 .. CR0D */ - ctWrite_i (CT_CR_O, i, cr[i]); - } - for (i = 0x10; i <= 0x18; i++) { /*CR10 .. CR18 */ - ctWrite_i (CT_CR_O, i, cr[i]); - } - i = 0x22; /*CR22 */ - ctWrite_i (CT_CR_O, i, cr[i]); - for (i = 0x30; i <= 0x33; i++) { /*CR30 .. CR33 */ - ctWrite_i (CT_CR_O, i, cr[i]); - } - i = 0x38; /*CR38 */ - ctWrite_i (CT_CR_O, i, cr[i]); - i = 0x3C; /*CR3C */ - ctWrite_i (CT_CR_O, i, cr[i]); - for (i = 0x40; i <= 0x41; i++) { /*CR40 .. CR41 */ - ctWrite_i (CT_CR_O, i, cr[i]); - } - for (i = 0x70; i <= 0x74; i++) { /*CR70 .. CR74 */ - ctWrite_i (CT_CR_O, i, cr[i]); - } - tmp = ctRead_i (CT_CR_O, 0x40); - tmp &= 0x0f; - tmp |= 0x80; - ctWrite_i (CT_CR_O, 0x40, tmp); /* StartAddressEnable */ -} - -/* pixelclock control */ - -/***************************************************************************** - We have a rational number p/q and need an m/n which is very close to p/q - but has m and n within mnmin and mnmax. We have no floating point in the - kernel. We can use long long without divide. And we have time to compute... -******************************************************************************/ -static unsigned int -FindBestPQFittingMN (unsigned int p, unsigned int q, unsigned int mnmin, - unsigned int mnmax, unsigned int *pm, unsigned int *pn) -{ - /* this code is not for general purpose usable but good for our number ranges */ - unsigned int n = mnmin, m = 0; - long long int L = 0, P = p, Q = q, H = P >> 1; - long long int D = 0x7ffffffffffffffLL; - for (n = mnmin; n <= mnmax; n++) { - m = mnmin; /* p/q ~ m/n -> p*n ~ m*q -> p*n-x*q ~ 0 */ - L = P * n - m * Q; /* n * vco - m * fref should be near 0 */ - while (L > 0 && m < mnmax) { - L -= q; /* difference is greater as 0 subtract fref */ - m++; /* and increment m */ - } - /* difference is less or equal than 0 or m > maximum */ - if (m > mnmax) - break; /* no solution: if we increase n we get the same situation */ - /* L is <= 0 now */ - if (-L > H && m > mnmin) { /* if difference > the half fref */ - L += q; /* we take the situation before */ - m--; /* because its closer to 0 */ - } - L = (L < 0) ? -L : +L; /* absolute value */ - if (D < L) /* if last difference was better take next n */ - continue; - D = L; - *pm = m; - *pn = n; /* keep improved data */ - if (D == 0) - break; /* best result we can get */ - } - return (unsigned int) (0xffffffff & D); -} - -/* that is the hardware < 69000 we have to manage - +---------+ +-------------------+ +----------------------+ +--+ - | REFCLK |__|NTSC Divisor Select|__|FVCO Reference Divisor|__|÷N|__ - | 14.3MHz | |(NTSCDS) (÷1, ÷5) | |Select (RDS) (÷1, ÷4) | | | | - +---------+ +-------------------+ +----------------------+ +--+ | - ___________________________________________________________________| - | - | fvco fout - | +--------+ +------------+ +-----+ +-------------------+ +----+ - +-| Phase |__|Charge Pump |__| VCO |_____|Post Divisor (PD) |___|CLK |---> - +-| Detect | |& Filter VCO| | | | |÷1, 2, 4, 8, 16, 32| | | - | +--------+ +------------+ +-----+ | +-------------------+ +----+ - | | - | +--+ +---------------+ | - |____|÷M|___|VCO Loop Divide|__________| - | | |(VLD)(÷4, ÷16) | - +--+ +---------------+ -**************************************************************************** - that is the hardware >= 69000 we have to manage - +---------+ +--+ - | REFCLK |__|÷N|__ - | 14.3MHz | | | | - +---------+ +--+ | - __________________| - | - | fvco fout - | +--------+ +------------+ +-----+ +-------------------+ +----+ - +-| Phase |__|Charge Pump |__| VCO |_____|Post Divisor (PD) |___|CLK |---> - +-| Detect | |& Filter VCO| | | | |÷1, 2, 4, 8, 16, 32| | | - | +--------+ +------------+ +-----+ | +-------------------+ +----+ - | | - | +--+ +---------------+ | - |____|÷M|___|VCO Loop Divide|__________| - | | |(VLD)(÷1, ÷4) | - +--+ +---------------+ - - -*/ - -#define VIDEO_FREF 14318180; /* Hz */ -/*****************************************************************************/ -static int -ReadPixClckFromXrRegsBack (struct ctfb_chips_properties *param) -{ - unsigned int m, n, vld, pd, PD, fref, xr_cb, i, pixclock; - i = 0; - pixclock = -1; - fref = VIDEO_FREF; - m = ctRead_i (CT_XR_O, 0xc8); - n = ctRead_i (CT_XR_O, 0xc9); - m -= param->mn_diff; - n -= param->mn_diff; - xr_cb = ctRead_i (CT_XR_O, 0xcb); - PD = (0x70 & xr_cb) >> 4; - pd = 1; - for (i = 0; i < PD; i++) { - pd *= 2; - } - vld = (0x04 & xr_cb) ? param->vld_set : param->vld_not_set; - if (n * vld * m) { - unsigned long long p = 1000000000000LL * pd * n; - unsigned long long q = (long long) fref * vld * m; - while ((p > 0xffffffffLL) || (q > 0xffffffffLL)) { - p >>= 1; /* can't divide with long long so we scale down */ - q >>= 1; - } - pixclock = (unsigned) p / (unsigned) q; - } else - printf ("Invalid data in xr regs.\n"); - return pixclock; -} - -/*****************************************************************************/ -static void -FindAndSetPllParamIntoXrRegs (unsigned int pixelclock, - struct ctfb_chips_properties *param) -{ - unsigned int m, n, vld, pd, PD, fref, xr_cb; - unsigned int fvcomin, fvcomax, pclckmin, pclckmax, pclk; - unsigned int pfreq, fvco, new_pixclock; - unsigned int D,nback,mback; - - fref = VIDEO_FREF; - pd = 1; - PD = 0; - fvcomin = param->vco_min; - fvcomax = param->vco_max; /* MHz */ - pclckmin = 1000000 / fvcomax + 1; /* 4546 */ - pclckmax = 32000000 / fvcomin - 1; /* 666665 */ - pclk = minmax (pclckmin, pixelclock, pclckmax); /* ps pp */ - pfreq = 250 * (4000000000U / pclk); - fvco = pfreq; /* Hz */ - new_pixclock = 0; - while (fvco < fvcomin * 1000000) { - /* double VCO starting with the pixelclock frequency - * as long as it is lower than the minimal VCO frequency */ - fvco *= 2; - pd *= 2; - PD++; - } - /* fvco is exactly pd * pixelclock and higher than the ninmal VCO frequency */ - /* first try */ - vld = param->vld_set; - D=FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n); /* rds = 1 */ - mback=m; - nback=n; - /* second try */ - vld = param->vld_not_set; - if(D<FindBestPQFittingMN (fvco / vld, fref, param->mn_min, param->mn_max, &m, &n)) { /* rds = 1 */ - /* first try was better */ - m=mback; - n=nback; - vld = param->vld_set; - } - m += param->mn_diff; - n += param->mn_diff; - debug("VCO %d, pd %d, m %d n %d vld %d\n", fvco, pd, m, n, vld); - xr_cb = ((0x7 & PD) << 4) | (vld == param->vld_set ? 0x04 : 0); - /* All four of the registers used for dot clock 2 (XRC8 - XRCB) must be - * written, and in order from XRC8 to XRCB, before the hardware will - * update the synthesizer s settings. - */ - ctWrite_i (CT_XR_O, 0xc8, m); - ctWrite_i (CT_XR_O, 0xc9, n); /* xrca does not exist in CT69000 and CT69030 */ - ctWrite_i (CT_XR_O, 0xca, 0); /* because of a hw bug I guess, but we write */ - ctWrite_i (CT_XR_O, 0xcb, xr_cb); /* 0 to it for savety */ - new_pixclock = ReadPixClckFromXrRegsBack (param); - debug("pixelclock.set = %d, pixelclock.real = %d\n", - pixelclock, new_pixclock); -} - -/*****************************************************************************/ -static void -SetMsrRegs (struct ctfb_res_modes *mode) -{ - unsigned char h_synch_high, v_synch_high; - - h_synch_high = (mode->sync & FB_SYNC_HOR_HIGH_ACT) ? 0 : 0x40; /* horizontal Synch High active */ - v_synch_high = (mode->sync & FB_SYNC_VERT_HIGH_ACT) ? 0 : 0x80; /* vertical Synch High active */ - ctWrite (CT_MSR_W_O, (h_synch_high | v_synch_high | 0x29)); - /* upper64K==0x20, CLC2select==0x08, RAMenable==0x02!(todo), CGA==0x01 - * Selects the upper 64KB page.Bit5=1 - * CLK2 (left reserved in standard VGA) Bit3|2=1|0 - * Disables CPU access to frame buffer. Bit1=0 - * Sets the I/O address decode for ST01, FCR, and all CR registers - * to the 3Dx I/O address range (CGA emulation). Bit0=1 - */ -} - -/************************************************************************************/ -#ifdef VGA_DUMP_REG - -static void -ctDispRegs (unsigned short index, int from, int to) -{ - unsigned char status; - int i; - - for (i = from; i < to; i++) { - status = ctRead_i (index, i); - printf ("%02X: is %02X\n", i, status); - } -} - -void -video_dump_reg (void) -{ - int i; - - printf ("Extended Regs:\n"); - ctDispRegs (CT_XR_O, 0, 0xC); - ctDispRegs (CT_XR_O, 0xe, 0xf); - ctDispRegs (CT_XR_O, 0x20, 0x21); - ctDispRegs (CT_XR_O, 0x40, 0x50); - ctDispRegs (CT_XR_O, 0x60, 0x64); - ctDispRegs (CT_XR_O, 0x67, 0x68); - ctDispRegs (CT_XR_O, 0x70, 0x72); - ctDispRegs (CT_XR_O, 0x80, 0x83); - ctDispRegs (CT_XR_O, 0xA0, 0xB0); - ctDispRegs (CT_XR_O, 0xC0, 0xD3); - printf ("Sequencer Regs:\n"); - ctDispRegs (CT_SR_O, 0, 0x8); - printf ("Graphic Regs:\n"); - ctDispRegs (CT_GR_O, 0, 0x9); - printf ("CRT Regs:\n"); - ctDispRegs (CT_CR_O, 0, 0x19); - ctDispRegs (CT_CR_O, 0x22, 0x23); - ctDispRegs (CT_CR_O, 0x30, 0x34); - ctDispRegs (CT_CR_O, 0x38, 0x39); - ctDispRegs (CT_CR_O, 0x3C, 0x3D); - ctDispRegs (CT_CR_O, 0x40, 0x42); - ctDispRegs (CT_CR_O, 0x70, 0x80); - /* don't display the attributes */ -} - -#endif - -/*************************************************************** - * Wait for BitBlt ready - */ -static int -video_wait_bitblt (unsigned long addr) -{ - unsigned long br04; - int i = 0; - br04 = in32r (addr); - while (br04 & 0x80000000) { - udelay (1); - br04 = in32r (addr); - if (i++ > 1000000) { - printf ("ERROR Timeout %lx\n", br04); - return 1; - } - } - return 0; -} - -/*************************************************************** - * Set up BitBlt Registrs - */ -static void -SetDrawingEngine (int bits_per_pixel) -{ - unsigned long br04, br00; - unsigned char tmp; - - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - - tmp = ctRead_i (CT_XR_O, 0x20); /* BitBLT Configuration */ - tmp |= 0x02; /* reset BitBLT */ - ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */ - udelay (10); - tmp &= 0xfd; /* release reset BitBLT */ - ctWrite_i (CT_XR_O, 0x20, tmp); /* BitBLT Configuration */ - video_wait_bitblt (pGD->pciBase + BR04_o); - - /* set pattern Address */ - out32r (pGD->pciBase + BR05_o, PATTERN_ADR & 0x003ffff8); - br04 = 0; - if (bits_per_pixel == 1) { - br04 |= 0x00040000; /* monochome Pattern */ - br04 |= 0x00001000; /* monochome source */ - } - br00 = ((pGD->winSizeX * pGD->gdfBytesPP) << 16) + (pGD->winSizeX * pGD->gdfBytesPP); /* bytes per scanline */ - out32r (pGD->pciBase + BR00_o, br00); /* */ - out32r (pGD->pciBase + BR08_o, (10 << 16) + 10); /* dummy */ - out32r (pGD->pciBase + BR04_o, br04); /* write all 0 */ - out32r (pGD->pciBase + BR07_o, 0); /* destination */ - video_wait_bitblt (pGD->pciBase + BR04_o); -} - -/**************************************************************************** -* supported Video Chips -*/ -static struct pci_device_id supported[] = { - {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69000}, - {} -}; - -/******************************************************************************* -* -* Init video chip -*/ -void * -video_hw_init (void) -{ - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - unsigned short device_id; - pci_dev_t devbusfn; - int videomode; - unsigned long t1, hsynch, vsynch; - unsigned int pci_mem_base, *vm; - int tmp, i, bits_per_pixel; - char *penv; - struct ctfb_res_modes *res_mode; - struct ctfb_res_modes var_mode; - struct ctfb_chips_properties *chips_param; - /* Search for video chip */ - - if ((devbusfn = pci_find_devices (supported, 0)) < 0) { -#ifdef CONFIG_VIDEO_ONBOARD - printf ("Video: Controller not found !\n"); -#endif - return (NULL); - } - - /* PCI setup */ - pci_write_config_dword (devbusfn, PCI_COMMAND, - (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); - pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id); - pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base); - pci_mem_base = pci_mem_to_phys (devbusfn, pci_mem_base); - - /* get chips params */ - for (chips_param = (struct ctfb_chips_properties *) &chips[0]; - chips_param->device_id != 0; chips_param++) { - if (chips_param->device_id == device_id) - break; - } - if (chips_param->device_id == 0) { -#ifdef CONFIG_VIDEO_ONBOARD - printf ("Video: controller 0x%X not supported\n", device_id); -#endif - return NULL; - } - /* supported Video controller found */ - printf ("Video: "); - - tmp = 0; - videomode = 0x301; - /* get video mode via environment */ - if ((penv = getenv ("videomode")) != NULL) { - /* deceide if it is a string */ - if (penv[0] <= '9') { - videomode = (int) simple_strtoul (penv, NULL, 16); - tmp = 1; - } - } else { - tmp = 1; - } - if (tmp) { - /* parameter are vesa modes */ - /* search params */ - for (i = 0; i < VESA_MODES_COUNT; i++) { - if (vesa_modes[i].vesanr == videomode) - break; - } - if (i == VESA_MODES_COUNT) { - printf ("no VESA Mode found, switching to mode 0x301 "); - i = 0; - } - res_mode = - (struct ctfb_res_modes *) &res_mode_init[vesa_modes[i]. - resindex]; - bits_per_pixel = vesa_modes[i].bits_per_pixel; - } else { - - res_mode = (struct ctfb_res_modes *) &var_mode; - bits_per_pixel = video_get_params (res_mode, penv); - } - - /* calculate available color depth for controller memory */ - if (bits_per_pixel == 15) - tmp = 2; - else - tmp = bits_per_pixel >> 3; /* /8 */ - if (((chips_param->max_mem - - ACCELMEMORY) / (res_mode->xres * res_mode->yres)) < tmp) { - tmp = - ((chips_param->max_mem - - ACCELMEMORY) / (res_mode->xres * res_mode->yres)); - if (tmp == 0) { - printf - ("No matching videomode found .-> reduce resolution\n"); - return NULL; - } else { - printf ("Switching back to %d Bits per Pixel ", - tmp << 3); - bits_per_pixel = tmp << 3; - } - } - - /* calculate hsynch and vsynch freq (info only) */ - t1 = (res_mode->left_margin + res_mode->xres + - res_mode->right_margin + res_mode->hsync_len) / 8; - t1 *= 8; - t1 *= res_mode->pixclock; - t1 /= 1000; - hsynch = 1000000000L / t1; - t1 *= - (res_mode->upper_margin + res_mode->yres + - res_mode->lower_margin + res_mode->vsync_len); - t1 /= 1000; - vsynch = 1000000000L / t1; - - /* fill in Graphic device struct */ - sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", res_mode->xres, - res_mode->yres, bits_per_pixel, (hsynch / 1000), - (vsynch / 1000)); - printf ("%s\n", pGD->modeIdent); - pGD->winSizeX = res_mode->xres; - pGD->winSizeY = res_mode->yres; - pGD->plnSizeX = res_mode->xres; - pGD->plnSizeY = res_mode->yres; - switch (bits_per_pixel) { - case 8: - pGD->gdfBytesPP = 1; - pGD->gdfIndex = GDF__8BIT_INDEX; - break; - case 15: - pGD->gdfBytesPP = 2; - pGD->gdfIndex = GDF_15BIT_555RGB; - break; - case 16: - pGD->gdfBytesPP = 2; - pGD->gdfIndex = GDF_16BIT_565RGB; - break; - case 24: - pGD->gdfBytesPP = 3; - pGD->gdfIndex = GDF_24BIT_888RGB; - break; - } - pGD->isaBase = CONFIG_SYS_ISA_IO_BASE_ADDRESS; - pGD->pciBase = pci_mem_base; - pGD->frameAdrs = pci_mem_base; - pGD->memSize = chips_param->max_mem; - /* Cursor Start Address */ - pGD->dprBase = - (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + pci_mem_base; - if ((pGD->dprBase & 0x0fff) != 0) { - /* allign it */ - pGD->dprBase &= 0xfffff000; - pGD->dprBase += 0x00001000; - } - debug("Cursor Start %x Pattern Start %x\n", pGD->dprBase, - PATTERN_ADR); - pGD->vprBase = pci_mem_base; /* Dummy */ - pGD->cprBase = pci_mem_base; /* Dummy */ - /* set up Hardware */ - - ctWrite (CT_MSR_W_O, 0x01); - - /* set the extended Registers */ - ctLoadRegs (CT_XR_O, xreg); - /* set atribute registers */ - SetArRegs (); - /* set Graphics register */ - SetGrRegs (); - /* set sequencer */ - SetSrRegs (); - - /* set msr */ - SetMsrRegs (res_mode); - - /* set CRT Registers */ - SetCrRegs (res_mode, bits_per_pixel); - /* set color mode */ - SetBitsPerPixelIntoXrRegs (bits_per_pixel); - - /* set PLL */ - FindAndSetPllParamIntoXrRegs (res_mode->pixclock, chips_param); - - ctWrite_i (CT_SR_O, 0, 0x03); /* clear synchronous reset */ - /* Clear video memory */ - i = pGD->memSize / 4; - vm = (unsigned int *) pGD->pciBase; - while (i--) - *vm++ = 0; - SetDrawingEngine (bits_per_pixel); -#ifdef VGA_DUMP_REG - video_dump_reg (); -#endif - - return ((void *) &ctfb); -} - - /******************************************************************************* -* -* Set a RGB color in the LUT (8 bit index) -*/ -void -video_set_lut (unsigned int index, /* color number */ - unsigned char r, /* red */ - unsigned char g, /* green */ - unsigned char b /* blue */ - ) -{ - - ctWrite (CT_LUT_MASK_O, 0xff); - - ctWrite (CT_LUT_START_O, (char) index); - - ctWrite (CT_LUT_RGB_O, r); /* red */ - ctWrite (CT_LUT_RGB_O, g); /* green */ - ctWrite (CT_LUT_RGB_O, b); /* blue */ - udelay (1); - ctWrite (CT_LUT_MASK_O, 0xff); -} - -/******************************************************************************* -* -* Drawing engine fill on screen region -*/ -void -video_hw_rectfill (unsigned int bpp, /* bytes per pixel */ - unsigned int dst_x, /* dest pos x */ - unsigned int dst_y, /* dest pos y */ - unsigned int dim_x, /* frame width */ - unsigned int dim_y, /* frame height */ - unsigned int color /* fill color */ - ) -{ - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - unsigned long *p, br04; - - video_wait_bitblt (pGD->pciBase + BR04_o); - - p = (unsigned long *) PATTERN_ADR; - dim_x *= bpp; - if (bpp == 3) - bpp++; /* 24Bit needs a 32bit pattern */ - memset (p, color, (bpp * sizeof (unsigned char) * 8 * 8)); /* 8 x 8 pattern data */ - out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP); /* destination */ - br04 = in32r (pGD->pciBase + BR04_o) & 0xffffff00; - br04 |= 0xF0; /* write Pattern P -> D */ - out32r (pGD->pciBase + BR04_o, br04); /* */ - out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x); /* starts the BITBlt */ - video_wait_bitblt (pGD->pciBase + BR04_o); -} - -/******************************************************************************* -* -* Drawing engine bitblt with screen region -*/ -void -video_hw_bitblt (unsigned int bpp, /* bytes per pixel */ - unsigned int src_x, /* source pos x */ - unsigned int src_y, /* source pos y */ - unsigned int dst_x, /* dest pos x */ - unsigned int dst_y, /* dest pos y */ - unsigned int dim_x, /* frame width */ - unsigned int dim_y /* frame height */ - ) -{ - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - unsigned long br04; - - br04 = in32r (pGD->pciBase + BR04_o); - - /* to prevent data corruption due to overlap, we have to - * find out if, and how the frames overlaps */ - if (src_x < dst_x) { - /* src is more left than dest - * the frame may overlap -> start from right to left */ - br04 |= 0x00000100; /* set bit 8 */ - src_x += dim_x; - dst_x += dim_x; - } else { - br04 &= 0xfffffeff; /* clear bit 8 left to right */ - } - if (src_y < dst_y) { - /* src is higher than dst - * the frame may overlap => start from bottom */ - br04 |= 0x00000200; /* set bit 9 */ - src_y += dim_y; - dst_y += dim_y; - } else { - br04 &= 0xfffffdff; /* clear bit 9 top to bottom */ - } - dim_x *= bpp; - out32r (pGD->pciBase + BR06_o, ((pGD->winSizeX * src_y) + src_x) * pGD->gdfBytesPP); /* source */ - out32r (pGD->pciBase + BR07_o, ((pGD->winSizeX * dst_y) + dst_x) * pGD->gdfBytesPP); /* destination */ - br04 &= 0xffffff00; - br04 |= 0x000000CC; /* S -> D */ - out32r (pGD->pciBase + BR04_o, br04); /* */ - out32r (pGD->pciBase + BR08_o, (dim_y << 16) + dim_x); /* start the BITBlt */ - video_wait_bitblt (pGD->pciBase + BR04_o); -} -#endif /* CONFIG_VIDEO */ diff --git a/drivers/video/l5f31188.c b/drivers/video/l5f31188.c deleted file mode 100644 index 3312dcfb31..0000000000 --- a/drivers/video/l5f31188.c +++ /dev/null @@ -1,192 +0,0 @@ -/* - * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved. - * Hyungwon Hwang <human.hwang@samsung.com> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <asm/arch/mipi_dsim.h> - -#define SCAN_FROM_LEFT_TO_RIGHT 0 -#define SCAN_FROM_RIGHT_TO_LEFT 1 -#define SCAN_FROM_TOP_TO_BOTTOM 0 -#define SCAN_FROM_BOTTOM_TO_TOP 1 - -static void l5f31188_sleep_in(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE, 0x10, 0x00); -} - -static void l5f31188_sleep_out(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE, 0x11, 0x00); -} - -static void l5f31188_set_gamma(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE, 0x26, 0x00); -} - -static void l5f31188_display_off(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE, 0x28, 0x00); -} - -static void l5f31188_display_on(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE, 0x29, 0x00); -} - -static void l5f31188_ctl_memory_access(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops, - int h_direction, int v_direction) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0x36, - (((h_direction & 0x1) << 1) | (v_direction & 0x1))); -} - -static void l5f31188_set_pixel_format(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0x3A, 0x70); -} - -static void l5f31188_write_disbv(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops, unsigned int brightness) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0x51, brightness); -} - -static void l5f31188_write_ctrld(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0x53, 0x2C); -} - -static void l5f31188_write_cabc(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops, - unsigned int wm_mode) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0x55, wm_mode); -} - -static void l5f31188_write_cabcmb(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops, unsigned int min_brightness) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0x5E, - min_brightness); -} - -static void l5f31188_set_extension(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - const unsigned char data_to_send[] = { - 0xB9, 0xFF, 0x83, 0x94 - }; - - ops->cmd_write(dev, MIPI_DSI_DCS_LONG_WRITE, - (unsigned int)data_to_send, ARRAY_SIZE(data_to_send)); -} - -static void l5f31188_set_dgc_lut(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - const unsigned char data_to_send[] = { - 0xC1, 0x01, 0x00, 0x04, 0x0E, 0x18, 0x1E, 0x26, - 0x2F, 0x36, 0x3E, 0x47, 0x4E, 0x56, 0x5D, 0x65, - 0x6D, 0x75, 0x7D, 0x84, 0x8C, 0x94, 0x9C, 0xA4, - 0xAD, 0xB5, 0xBD, 0xC5, 0xCC, 0xD4, 0xDE, 0xE5, - 0xEE, 0xF7, 0xFF, 0x3F, 0x9A, 0xCE, 0xD4, 0x21, - 0xA1, 0x26, 0x54, 0x00, 0x00, 0x04, 0x0E, 0x19, - 0x1F, 0x27, 0x30, 0x37, 0x40, 0x48, 0x50, 0x58, - 0x60, 0x67, 0x6F, 0x77, 0x7F, 0x87, 0x8F, 0x97, - 0x9F, 0xA7, 0xB0, 0xB8, 0xC0, 0xC8, 0xCE, 0xD8, - 0xE0, 0xE7, 0xF0, 0xF7, 0xFF, 0x3C, 0xEB, 0xFD, - 0x2F, 0x66, 0xA8, 0x2C, 0x46, 0x00, 0x00, 0x04, - 0x0E, 0x18, 0x1E, 0x26, 0x30, 0x38, 0x41, 0x4A, - 0x52, 0x5A, 0x62, 0x6B, 0x73, 0x7B, 0x83, 0x8C, - 0x94, 0x9C, 0xA5, 0xAD, 0xB6, 0xBD, 0xC5, 0xCC, - 0xD4, 0xDD, 0xE3, 0xEB, 0xF2, 0xF9, 0xFF, 0x3F, - 0xA4, 0x8A, 0x8F, 0xC7, 0x33, 0xF5, 0xE9, 0x00 - }; - ops->cmd_write(dev, MIPI_DSI_DCS_LONG_WRITE, - (unsigned int)data_to_send, ARRAY_SIZE(data_to_send)); -} - -static void l5f31188_set_tcon(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - const unsigned char data_to_send[] = { - 0xC7, 0x00, 0x20 - }; - ops->cmd_write(dev, MIPI_DSI_DCS_LONG_WRITE, - (unsigned int)data_to_send, ARRAY_SIZE(data_to_send)); -} - -static void l5f31188_set_ptba(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - const unsigned char data_to_send[] = { - 0xBF, 0x06, 0x10 - }; - ops->cmd_write(dev, MIPI_DSI_DCS_LONG_WRITE, - (unsigned int)data_to_send, ARRAY_SIZE(data_to_send)); -} - -static void l5f31188_set_eco(struct mipi_dsim_device *dev, - struct mipi_dsim_master_ops *ops) -{ - ops->cmd_write(dev, MIPI_DSI_DCS_SHORT_WRITE_PARAM, 0xC6, 0x0C); -} - -static int l5f31188_panel_init(struct mipi_dsim_device *dev) -{ - struct mipi_dsim_master_ops *ops = dev->master_ops; - - l5f31188_set_extension(dev, ops); - l5f31188_set_dgc_lut(dev, ops); - - l5f31188_set_eco(dev, ops); - l5f31188_set_tcon(dev, ops); - l5f31188_set_ptba(dev, ops); - l5f31188_set_gamma(dev, ops); - l5f31188_ctl_memory_access(dev, ops, - SCAN_FROM_LEFT_TO_RIGHT, SCAN_FROM_TOP_TO_BOTTOM); - l5f31188_set_pixel_format(dev, ops); - l5f31188_write_disbv(dev, ops, 0xFF); - l5f31188_write_ctrld(dev, ops); - l5f31188_write_cabc(dev, ops, 0x0); - l5f31188_write_cabcmb(dev, ops, 0x0); - - l5f31188_sleep_out(dev, ops); - - /* 120 msec */ - udelay(120 * 1000); - - return 0; -} - -static void l5f31188_display_enable(struct mipi_dsim_device *dev) -{ - struct mipi_dsim_master_ops *ops = dev->master_ops; - l5f31188_display_on(dev, ops); -} - -static struct mipi_dsim_lcd_driver l5f31188_dsim_ddi_driver = { - .name = "l5f31188", - .id = -1, - - .mipi_panel_init = l5f31188_panel_init, - .mipi_display_on = l5f31188_display_enable, -}; - -void l5f31188_init(void) -{ - exynos_mipi_dsi_register_lcd_driver(&l5f31188_dsim_ddi_driver); -} diff --git a/drivers/video/rockchip/Makefile b/drivers/video/rockchip/Makefile index 872dc0f653..800500327c 100644 --- a/drivers/video/rockchip/Makefile +++ b/drivers/video/rockchip/Makefile @@ -14,5 +14,7 @@ obj-$(CONFIG_DISPLAY_ROCKCHIP_LVDS) += rk_lvds.o obj-hdmi-$(CONFIG_ROCKCHIP_RK3288) += rk3288_hdmi.o obj-hdmi-$(CONFIG_ROCKCHIP_RK3399) += rk3399_hdmi.o obj-$(CONFIG_DISPLAY_ROCKCHIP_HDMI) += rk_hdmi.o $(obj-hdmi-y) -obj-$(CONFIG_DISPLAY_ROCKCHIP_MIPI) += rk_mipi.o +obj-mipi-$(CONFIG_ROCKCHIP_RK3288) += rk3288_mipi.o +obj-mipi-$(CONFIG_ROCKCHIP_RK3399) += rk3399_mipi.o +obj-$(CONFIG_DISPLAY_ROCKCHIP_MIPI) += rk_mipi.o $(obj-mipi-y) endif diff --git a/drivers/video/rockchip/rk3288_mipi.c b/drivers/video/rockchip/rk3288_mipi.c new file mode 100644 index 0000000000..953b47fb8c --- /dev/null +++ b/drivers/video/rockchip/rk3288_mipi.c @@ -0,0 +1,191 @@ +/* + * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd + * Author: Eric Gao <eric.gao@rock-chips.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <clk.h> +#include <display.h> +#include <dm.h> +#include <fdtdec.h> +#include <panel.h> +#include <regmap.h> +#include "rk_mipi.h" +#include <syscon.h> +#include <asm/gpio.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <dm/uclass-internal.h> +#include <linux/kernel.h> +#include <asm/arch/clock.h> +#include <asm/arch/cru_rk3288.h> +#include <asm/arch/grf_rk3288.h> +#include <asm/arch/rockchip_mipi_dsi.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define MHz 1000000 + +/* Select mipi dsi source, big or little vop */ +static int rk_mipi_dsi_source_select(struct udevice *dev) +{ + struct rk_mipi_priv *priv = dev_get_priv(dev); + struct rk3288_grf *grf = priv->grf; + struct display_plat *disp_uc_plat = dev_get_uclass_platdata(dev); + + /* Select the video source */ + switch (disp_uc_plat->source_id) { + case VOP_B: + rk_clrsetreg(&grf->soc_con6, RK3288_DSI0_LCDC_SEL_MASK, + RK3288_DSI0_LCDC_SEL_BIG + << RK3288_DSI0_LCDC_SEL_SHIFT); + break; + case VOP_L: + rk_clrsetreg(&grf->soc_con6, RK3288_DSI0_LCDC_SEL_MASK, + RK3288_DSI0_LCDC_SEL_LIT + << RK3288_DSI0_LCDC_SEL_SHIFT); + break; + default: + debug("%s: Invalid VOP id\n", __func__); + return -EINVAL; + } + + return 0; +} + +/* Setup mipi dphy working mode */ +static void rk_mipi_dphy_mode_set(struct udevice *dev) +{ + struct rk_mipi_priv *priv = dev_get_priv(dev); + struct rk3288_grf *grf = priv->grf; + int val; + + /* Set Controller as TX mode */ + val = RK3288_DPHY_TX0_RXMODE_DIS << RK3288_DPHY_TX0_RXMODE_SHIFT; + rk_clrsetreg(&grf->soc_con8, RK3288_DPHY_TX0_RXMODE_MASK, val); + + /* Exit tx stop mode */ + val |= RK3288_DPHY_TX0_TXSTOPMODE_EN + << RK3288_DPHY_TX0_TXSTOPMODE_SHIFT; + rk_clrsetreg(&grf->soc_con8, + RK3288_DPHY_TX0_TXSTOPMODE_MASK, val); + + /* Disable turnequest */ + val |= RK3288_DPHY_TX0_TURNREQUEST_EN + << RK3288_DPHY_TX0_TURNREQUEST_SHIFT; + rk_clrsetreg(&grf->soc_con8, + RK3288_DPHY_TX0_TURNREQUEST_MASK, val); +} + +/* + * This function is called by rk_display_init() using rk_mipi_dsi_enable() and + * rk_mipi_phy_enable() to initialize mipi controller and dphy. If success, + * enable backlight. + */ +static int rk_mipi_enable(struct udevice *dev, int panel_bpp, + const struct display_timing *timing) +{ + int ret; + struct rk_mipi_priv *priv = dev_get_priv(dev); + + /* Fill the mipi controller parameter */ + priv->ref_clk = 24 * MHz; + priv->sys_clk = priv->ref_clk; + priv->pix_clk = timing->pixelclock.typ; + priv->phy_clk = priv->pix_clk * 6; + priv->txbyte_clk = priv->phy_clk / 8; + priv->txesc_clk = 20 * MHz; + + /* Select vop port, big or little */ + rk_mipi_dsi_source_select(dev); + + /* Set mipi dphy work mode */ + rk_mipi_dphy_mode_set(dev); + + /* Config and enable mipi dsi according to timing */ + ret = rk_mipi_dsi_enable(dev, timing); + if (ret) { + debug("%s: rk_mipi_dsi_enable() failed (err=%d)\n", + __func__, ret); + return ret; + } + + /* Config and enable mipi phy */ + ret = rk_mipi_phy_enable(dev); + if (ret) { + debug("%s: rk_mipi_phy_enable() failed (err=%d)\n", + __func__, ret); + return ret; + } + + /* Enable backlight */ + ret = panel_enable_backlight(priv->panel); + if (ret) { + debug("%s: panel_enable_backlight() failed (err=%d)\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int rk_mipi_ofdata_to_platdata(struct udevice *dev) +{ + struct rk_mipi_priv *priv = dev_get_priv(dev); + + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + if (IS_ERR(priv->grf)) { + debug("%s: Get syscon grf failed (ret=%p)\n", + __func__, priv->grf); + return -ENXIO; + } + priv->regs = dev_read_addr(dev); + if (priv->regs == FDT_ADDR_T_NONE) { + debug("%s: Get MIPI dsi address failed (ret=%lu)\n", __func__, + priv->regs); + return -ENXIO; + } + + return 0; +} + +/* + * Probe function: check panel existence and readingit's timing. Then config + * mipi dsi controller and enable it according to the timing parameter. + */ +static int rk_mipi_probe(struct udevice *dev) +{ + int ret; + struct rk_mipi_priv *priv = dev_get_priv(dev); + + ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "rockchip,panel", + &priv->panel); + if (ret) { + debug("%s: Can not find panel (err=%d)\n", __func__, ret); + return ret; + } + + return 0; +} + +static const struct dm_display_ops rk_mipi_dsi_ops = { + .read_timing = rk_mipi_read_timing, + .enable = rk_mipi_enable, +}; + +static const struct udevice_id rk_mipi_dsi_ids[] = { + { .compatible = "rockchip,rk3288_mipi_dsi" }, + { } +}; + +U_BOOT_DRIVER(rk_mipi_dsi) = { + .name = "rk_mipi_dsi", + .id = UCLASS_DISPLAY, + .of_match = rk_mipi_dsi_ids, + .ofdata_to_platdata = rk_mipi_ofdata_to_platdata, + .probe = rk_mipi_probe, + .ops = &rk_mipi_dsi_ops, + .priv_auto_alloc_size = sizeof(struct rk_mipi_priv), +}; diff --git a/drivers/video/rockchip/rk3399_mipi.c b/drivers/video/rockchip/rk3399_mipi.c new file mode 100644 index 0000000000..9ef202bf09 --- /dev/null +++ b/drivers/video/rockchip/rk3399_mipi.c @@ -0,0 +1,182 @@ +/* + * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd + * Author: Eric Gao <eric.gao@rock-chips.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <clk.h> +#include <display.h> +#include <dm.h> +#include <fdtdec.h> +#include <panel.h> +#include <regmap.h> +#include "rk_mipi.h" +#include <syscon.h> +#include <asm/gpio.h> +#include <asm/hardware.h> +#include <asm/io.h> +#include <dm/uclass-internal.h> +#include <linux/kernel.h> +#include <asm/arch/clock.h> +#include <asm/arch/cru_rk3399.h> +#include <asm/arch/grf_rk3399.h> +#include <asm/arch/rockchip_mipi_dsi.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* Select mipi dsi source, big or little vop */ +static int rk_mipi_dsi_source_select(struct udevice *dev) +{ + struct rk_mipi_priv *priv = dev_get_priv(dev); + struct rk3399_grf_regs *grf = priv->grf; + struct display_plat *disp_uc_plat = dev_get_uclass_platdata(dev); + + /* Select the video source */ + switch (disp_uc_plat->source_id) { + case VOP_B: + rk_clrsetreg(&grf->soc_con20, GRF_DSI0_VOP_SEL_MASK, + GRF_DSI0_VOP_SEL_B << GRF_DSI0_VOP_SEL_SHIFT); + break; + case VOP_L: + rk_clrsetreg(&grf->soc_con20, GRF_DSI0_VOP_SEL_MASK, + GRF_DSI0_VOP_SEL_L << GRF_DSI0_VOP_SEL_SHIFT); + break; + default: + debug("%s: Invalid VOP id\n", __func__); + return -EINVAL; + } + + return 0; +} + +/* Setup mipi dphy working mode */ +static void rk_mipi_dphy_mode_set(struct udevice *dev) +{ + struct rk_mipi_priv *priv = dev_get_priv(dev); + struct rk3399_grf_regs *grf = priv->grf; + int val; + + /* Set Controller as TX mode */ + val = GRF_DPHY_TX0_RXMODE_DIS << GRF_DPHY_TX0_RXMODE_SHIFT; + rk_clrsetreg(&grf->soc_con22, GRF_DPHY_TX0_RXMODE_MASK, val); + + /* Exit tx stop mode */ + val |= GRF_DPHY_TX0_TXSTOPMODE_DIS << GRF_DPHY_TX0_TXSTOPMODE_SHIFT; + rk_clrsetreg(&grf->soc_con22, GRF_DPHY_TX0_TXSTOPMODE_MASK, val); + + /* Disable turnequest */ + val |= GRF_DPHY_TX0_TURNREQUEST_DIS << GRF_DPHY_TX0_TURNREQUEST_SHIFT; + rk_clrsetreg(&grf->soc_con22, GRF_DPHY_TX0_TURNREQUEST_MASK, val); +} + +/* + * This function is called by rk_display_init() using rk_mipi_dsi_enable() and + * rk_mipi_phy_enable() to initialize mipi controller and dphy. If success, + * enable backlight. + */ +static int rk_display_enable(struct udevice *dev, int panel_bpp, + const struct display_timing *timing) +{ + int ret; + struct rk_mipi_priv *priv = dev_get_priv(dev); + + /* Fill the mipi controller parameter */ + priv->ref_clk = 24 * MHz; + priv->sys_clk = priv->ref_clk; + priv->pix_clk = timing->pixelclock.typ; + priv->phy_clk = priv->pix_clk * 6; + priv->txbyte_clk = priv->phy_clk / 8; + priv->txesc_clk = 20 * MHz; + + /* Select vop port, big or little */ + rk_mipi_dsi_source_select(dev); + + /* Set mipi dphy work mode */ + rk_mipi_dphy_mode_set(dev); + + /* Config and enable mipi dsi according to timing */ + ret = rk_mipi_dsi_enable(dev, timing); + if (ret) { + debug("%s: rk_mipi_dsi_enable() failed (err=%d)\n", + __func__, ret); + return ret; + } + + /* Config and enable mipi phy */ + ret = rk_mipi_phy_enable(dev); + if (ret) { + debug("%s: rk_mipi_phy_enable() failed (err=%d)\n", + __func__, ret); + return ret; + } + + /* Enable backlight */ + ret = panel_enable_backlight(priv->panel); + if (ret) { + debug("%s: panel_enable_backlight() failed (err=%d)\n", + __func__, ret); + return ret; + } + + return 0; +} + +static int rk_mipi_ofdata_to_platdata(struct udevice *dev) +{ + struct rk_mipi_priv *priv = dev_get_priv(dev); + + priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); + if (priv->grf <= 0) { + debug("%s: Get syscon grf failed (ret=%p)\n", + __func__, priv->grf); + return -ENXIO; + } + priv->regs = dev_read_addr(dev); + if (priv->regs == FDT_ADDR_T_NONE) { + debug("%s: Get MIPI dsi address failed\n", __func__); + return -ENXIO; + } + + return 0; +} + +/* + * Probe function: check panel existence and readingit's timing. Then config + * mipi dsi controller and enable it according to the timing parameter. + */ +static int rk_mipi_probe(struct udevice *dev) +{ + int ret; + struct rk_mipi_priv *priv = dev_get_priv(dev); + + ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "rockchip,panel", + &priv->panel); + if (ret) { + debug("%s: Can not find panel (err=%d)\n", __func__, ret); + return ret; + } + + return 0; +} + +static const struct dm_display_ops rk_mipi_dsi_ops = { + .read_timing = rk_mipi_read_timing, + .enable = rk_display_enable, +}; + +static const struct udevice_id rk_mipi_dsi_ids[] = { + { .compatible = "rockchip,rk3399_mipi_dsi" }, + { } +}; + +U_BOOT_DRIVER(rk_mipi_dsi) = { + .name = "rk_mipi_dsi", + .id = UCLASS_DISPLAY, + .of_match = rk_mipi_dsi_ids, + .ofdata_to_platdata = rk_mipi_ofdata_to_platdata, + .probe = rk_mipi_probe, + .ops = &rk_mipi_dsi_ops, + .priv_auto_alloc_size = sizeof(struct rk_mipi_priv), +}; diff --git a/drivers/video/rockchip/rk_mipi.c b/drivers/video/rockchip/rk_mipi.c index 1199a30c1a..d5377558a1 100644 --- a/drivers/video/rockchip/rk_mipi.c +++ b/drivers/video/rockchip/rk_mipi.c @@ -12,6 +12,7 @@ #include <fdtdec.h> #include <panel.h> #include <regmap.h> +#include "rk_mipi.h" #include <syscon.h> #include <asm/gpio.h> #include <asm/hardware.h> @@ -22,38 +23,11 @@ #include <asm/arch/cru_rk3399.h> #include <asm/arch/grf_rk3399.h> #include <asm/arch/rockchip_mipi_dsi.h> -#include <dt-bindings/clock/rk3288-cru.h> DECLARE_GLOBAL_DATA_PTR; -/* - * Private information for rk mipi - * - * @regs: mipi controller address - * @grf: GRF register - * @panel: panel assined by device tree - * @ref_clk: reference clock for mipi dsi pll - * @sysclk: config clock for mipi dsi register - * @pix_clk: pixel clock for vop->dsi data transmission - * @phy_clk: mipi dphy output clock - * @txbyte_clk: clock for dsi->dphy high speed data transmission - * @txesc_clk: clock for tx esc mode - */ -struct rk_mipi_priv { - uintptr_t regs; - struct rk3399_grf_regs *grf; - struct udevice *panel; - struct mipi_dsi *dsi; - u32 ref_clk; - u32 sys_clk; - u32 pix_clk; - u32 phy_clk; - u32 txbyte_clk; - u32 txesc_clk; -}; - -static int rk_mipi_read_timing(struct udevice *dev, - struct display_timing *timing) +int rk_mipi_read_timing(struct udevice *dev, + struct display_timing *timing) { int ret; @@ -102,46 +76,18 @@ static void rk_mipi_dsi_write(uintptr_t regs, u32 reg, u32 val) writel(dat, addr); } -static int rk_mipi_dsi_enable(struct udevice *dev, - const struct display_timing *timing) +int rk_mipi_dsi_enable(struct udevice *dev, + const struct display_timing *timing) { int node, timing_node; int val; struct rk_mipi_priv *priv = dev_get_priv(dev); uintptr_t regs = priv->regs; - struct display_plat *disp_uc_plat = dev_get_uclass_platdata(dev); u32 txbyte_clk = priv->txbyte_clk; u32 txesc_clk = priv->txesc_clk; txesc_clk = txbyte_clk/(txbyte_clk/txesc_clk + 1); - /* Select the video source */ - switch (disp_uc_plat->source_id) { - case VOP_B: - rk_clrsetreg(&priv->grf->soc_con20, GRF_DSI0_VOP_SEL_MASK, - GRF_DSI0_VOP_SEL_B << GRF_DSI0_VOP_SEL_SHIFT); - break; - case VOP_L: - rk_clrsetreg(&priv->grf->soc_con20, GRF_DSI0_VOP_SEL_MASK, - GRF_DSI0_VOP_SEL_L << GRF_DSI0_VOP_SEL_SHIFT); - break; - default: - debug("%s: Invalid VOP id\n", __func__); - return -EINVAL; - } - - /* Set Controller as TX mode */ - val = GRF_DPHY_TX0_RXMODE_DIS << GRF_DPHY_TX0_RXMODE_SHIFT; - rk_clrsetreg(&priv->grf->soc_con22, GRF_DPHY_TX0_RXMODE_MASK, val); - - /* Exit tx stop mode */ - val |= GRF_DPHY_TX0_TXSTOPMODE_DIS << GRF_DPHY_TX0_TXSTOPMODE_SHIFT; - rk_clrsetreg(&priv->grf->soc_con22, GRF_DPHY_TX0_TXSTOPMODE_MASK, val); - - /* Disable turnequest */ - val |= GRF_DPHY_TX0_TURNREQUEST_DIS << GRF_DPHY_TX0_TURNREQUEST_SHIFT; - rk_clrsetreg(&priv->grf->soc_con22, GRF_DPHY_TX0_TURNREQUEST_MASK, val); - /* Set Display timing parameter */ rk_mipi_dsi_write(regs, VID_HSA_TIME, timing->hsync_len.typ); rk_mipi_dsi_write(regs, VID_HBP_TIME, timing->hback_porch.typ); @@ -249,7 +195,7 @@ static void rk_mipi_phy_write(uintptr_t regs, unsigned char test_code, * fsfreqrang value ,cap ,lpf and so on according to the given pix clk rate, * and then enable phy. */ -static int rk_mipi_phy_enable(struct udevice *dev) +int rk_mipi_phy_enable(struct udevice *dev) { int i; struct rk_mipi_priv *priv = dev_get_priv(dev); @@ -385,107 +331,3 @@ static int rk_mipi_phy_enable(struct udevice *dev) return 0; } -/* - * This function is called by rk_display_init() using rk_mipi_dsi_enable() and - * rk_mipi_phy_enable() to initialize mipi controller and dphy. If success, - * enable backlight. - */ -static int rk_display_enable(struct udevice *dev, int panel_bpp, - const struct display_timing *timing) -{ - int ret; - struct rk_mipi_priv *priv = dev_get_priv(dev); - - /* Fill the mipi controller parameter */ - priv->ref_clk = 24 * MHz; - priv->sys_clk = priv->ref_clk; - priv->pix_clk = timing->pixelclock.typ; - priv->phy_clk = priv->pix_clk * 6; - priv->txbyte_clk = priv->phy_clk / 8; - priv->txesc_clk = 20 * MHz; - - /* Config and enable mipi dsi according to timing */ - ret = rk_mipi_dsi_enable(dev, timing); - if (ret) { - debug("%s: rk_mipi_dsi_enable() failed (err=%d)\n", - __func__, ret); - return ret; - } - - /* Config and enable mipi phy */ - ret = rk_mipi_phy_enable(dev); - if (ret) { - debug("%s: rk_mipi_phy_enable() failed (err=%d)\n", - __func__, ret); - return ret; - } - - /* Enable backlight */ - ret = panel_enable_backlight(priv->panel); - if (ret) { - debug("%s: panel_enable_backlight() failed (err=%d)\n", - __func__, ret); - return ret; - } - - return 0; -} - -static int rk_mipi_ofdata_to_platdata(struct udevice *dev) -{ - struct rk_mipi_priv *priv = dev_get_priv(dev); - - priv->grf = syscon_get_first_range(ROCKCHIP_SYSCON_GRF); - if (priv->grf <= 0) { - debug("%s: Get syscon grf failed (ret=%p)\n", - __func__, priv->grf); - return -ENXIO; - } - priv->regs = devfdt_get_addr(dev); - if (priv->regs <= 0) { - debug("%s: Get MIPI dsi address failed (ret=%lu)\n", __func__, - priv->regs); - return -ENXIO; - } - - return 0; -} - -/* - * Probe function: check panel existence and readingit's timing. Then config - * mipi dsi controller and enable it according to the timing parameter. - */ -static int rk_mipi_probe(struct udevice *dev) -{ - int ret; - struct rk_mipi_priv *priv = dev_get_priv(dev); - - ret = uclass_get_device_by_phandle(UCLASS_PANEL, dev, "rockchip,panel", - &priv->panel); - if (ret) { - debug("%s: Can not find panel (err=%d)\n", __func__, ret); - return ret; - } - - return 0; -} - -static const struct dm_display_ops rk_mipi_dsi_ops = { - .read_timing = rk_mipi_read_timing, - .enable = rk_display_enable, -}; - -static const struct udevice_id rk_mipi_dsi_ids[] = { - { .compatible = "rockchip,rk3399_mipi_dsi" }, - { } -}; - -U_BOOT_DRIVER(rk_mipi_dsi) = { - .name = "rk_mipi_dsi", - .id = UCLASS_DISPLAY, - .of_match = rk_mipi_dsi_ids, - .ofdata_to_platdata = rk_mipi_ofdata_to_platdata, - .probe = rk_mipi_probe, - .ops = &rk_mipi_dsi_ops, - .priv_auto_alloc_size = sizeof(struct rk_mipi_priv), -}; diff --git a/drivers/video/rockchip/rk_mipi.h b/drivers/video/rockchip/rk_mipi.h new file mode 100644 index 0000000000..de6ac52eb3 --- /dev/null +++ b/drivers/video/rockchip/rk_mipi.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2017, Fuzhou Rockchip Electronics Co., Ltd + * Author: Eric Gao <eric.gao@rock-chips.com> + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef __RK_MIPI_H +#define __RK_MIPI_H + +struct rk_mipi_priv { + uintptr_t regs; + void *grf; + struct udevice *panel; + struct mipi_dsi *dsi; + u32 ref_clk; + u32 sys_clk; + u32 pix_clk; + u32 phy_clk; + u32 txbyte_clk; + u32 txesc_clk; +}; + +int rk_mipi_read_timing(struct udevice *dev, + struct display_timing *timing); + +int rk_mipi_dsi_enable(struct udevice *dev, + const struct display_timing *timing); + +int rk_mipi_phy_enable(struct udevice *dev); + + +#endif diff --git a/drivers/video/sed156x.c b/drivers/video/sed156x.c deleted file mode 100644 index 2c906ecf1e..0000000000 --- a/drivers/video/sed156x.c +++ /dev/null @@ -1,546 +0,0 @@ -/* - * (C) Copyright 2003 - * - * Pantelis Antoniou <panto@intracom.gr> - * Intracom S.A. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <watchdog.h> - -#include <sed156x.h> - -/* configure according to the selected display */ -#if defined(CONFIG_SED156X_PG12864Q) -#define LCD_WIDTH 128 -#define LCD_HEIGHT 64 -#define LCD_LINES 64 -#define LCD_PAGES 9 -#define LCD_COLUMNS 132 -#else -#error Unsupported SED156x configuration -#endif - -/* include the font data */ -#include <video_font.h> - -#if VIDEO_FONT_WIDTH != 8 || VIDEO_FONT_HEIGHT != 16 -#error Expecting VIDEO_FONT_WIDTH == 8 && VIDEO_FONT_HEIGHT == 16 -#endif - -#define LCD_BYTE_WIDTH (LCD_WIDTH / 8) -#define VIDEO_FONT_BYTE_WIDTH (VIDEO_FONT_WIDTH / 8) - -#define LCD_TEXT_WIDTH (LCD_WIDTH / VIDEO_FONT_WIDTH) -#define LCD_TEXT_HEIGHT (LCD_HEIGHT / VIDEO_FONT_HEIGHT) - -#define LCD_BYTE_LINESZ (LCD_BYTE_WIDTH * VIDEO_FONT_HEIGHT) - -const int sed156x_text_width = LCD_TEXT_WIDTH; -const int sed156x_text_height = LCD_TEXT_HEIGHT; - -/**************************************************************************************/ - -#define SED156X_SPI_RXD() (SED156X_SPI_RXD_PORT & SED156X_SPI_RXD_MASK) - -#define SED156X_SPI_TXD(x) \ - do { \ - if (x) \ - SED156X_SPI_TXD_PORT |= SED156X_SPI_TXD_MASK; \ - else \ - SED156X_SPI_TXD_PORT &= ~SED156X_SPI_TXD_MASK; \ - } while(0) - -#define SED156X_SPI_CLK(x) \ - do { \ - if (x) \ - SED156X_SPI_CLK_PORT |= SED156X_SPI_CLK_MASK; \ - else \ - SED156X_SPI_CLK_PORT &= ~SED156X_SPI_CLK_MASK; \ - } while(0) - -#define SED156X_SPI_CLK_TOGGLE() (SED156X_SPI_CLK_PORT ^= SED156X_SPI_CLK_MASK) - -#define SED156X_SPI_BIT_DELAY() /* no delay */ - -#define SED156X_CS(x) \ - do { \ - if (x) \ - SED156X_CS_PORT |= SED156X_CS_MASK; \ - else \ - SED156X_CS_PORT &= ~SED156X_CS_MASK; \ - } while(0) - -#define SED156X_A0(x) \ - do { \ - if (x) \ - SED156X_A0_PORT |= SED156X_A0_MASK; \ - else \ - SED156X_A0_PORT &= ~SED156X_A0_MASK; \ - } while(0) - -/**************************************************************************************/ - -/*** LCD Commands ***/ - -#define LCD_ON 0xAF /* Display ON */ -#define LCD_OFF 0xAE /* Display OFF */ -#define LCD_LADDR 0x40 /* Display start line set + (6-bit) address */ -#define LCD_PADDR 0xB0 /* Page address set + (4-bit) page */ -#define LCD_CADRH 0x10 /* Column address set upper + (4-bit) column hi */ -#define LCD_CADRL 0x00 /* Column address set lower + (4-bit) column lo */ -#define LCD_ADC_NRM 0xA0 /* ADC select Normal */ -#define LCD_ADC_REV 0xA1 /* ADC select Reverse */ -#define LCD_DSP_NRM 0xA6 /* LCD display Normal */ -#define LCD_DSP_REV 0xA7 /* LCD display Reverse */ -#define LCD_DPT_NRM 0xA4 /* Display all points Normal */ -#define LCD_DPT_ALL 0xA5 /* Display all points ON */ -#define LCD_BIAS9 0xA2 /* LCD bias set 1/9 */ -#define LCD_BIAS7 0xA3 /* LCD bias set 1/7 */ -#define LCD_CAINC 0xE0 /* Read/modify/write */ -#define LCD_CAEND 0xEE /* End */ -#define LCD_RESET 0xE2 /* Reset */ -#define LCD_C_NRM 0xC0 /* Common output mode select Normal direction */ -#define LCD_C_RVS 0xC8 /* Common output mode select Reverse direction */ -#define LCD_PWRMD 0x28 /* Power control set + (3-bit) mode */ -#define LCD_RESRT 0x20 /* V5 v. reg. int. resistor ratio set + (3-bit) ratio */ -#define LCD_EVSET 0x81 /* Electronic volume mode set + byte = (6-bit) volume */ -#define LCD_SIOFF 0xAC /* Static indicator OFF */ -#define LCD_SION 0xAD /* Static indicator ON + byte = (2-bit) mode */ -#define LCD_NOP 0xE3 /* NOP */ -#define LCD_TEST 0xF0 /* Test/Test mode reset (Note: *DO NOT USE*) */ - -/*------------------------------------------------------------------------------- - Compound commands - ------------------------------------------------------------------------------- - Command Description Commands - ---------- ------------------------ ------------------------------------- - POWS_ON POWER SAVER ON command LCD_OFF, LCD_D_ALL - POWS_OFF POWER SAVER OFF command LCD_D_NRM - SLEEPON SLEEP mode LCD_SIOFF, POWS_ON - SLEEPOFF SLEEP mode cancel LCD_D_NRM, LCD_SION, LCD_SIS_??? - STDBYON STAND BY mode LCD_SION, POWS_ON - STDBYOFF STAND BY mode cancel LCD_D_NRM - -------------------------------------------------------------------------------*/ - -/*** LCD various parameters ***/ -#define LCD_PPB 8 /* Pixels per byte (display is B/W, 1 bit per pixel) */ - -/*** LCD Status byte masks ***/ -#define LCD_S_BUSY 0x80 /* Status Read - BUSY mask */ -#define LCD_S_ADC 0x40 /* Status Read - ADC mask */ -#define LCD_S_ONOFF 0x20 /* Status Read - ON/OFF mask */ -#define LCD_S_RESET 0x10 /* Status Read - RESET mask */ - -/*** LCD commands parameter masks ***/ -#define LCD_M_LADDR 0x3F /* Display start line (6-bit) address mask */ -#define LCD_M_PADDR 0x0F /* Page address (4-bit) page mask */ -#define LCD_M_CADRH 0x0F /* Column address upper (4-bit) column hi mask */ -#define LCD_M_CADRL 0x0F /* Column address lower (4-bit) column lo mask */ -#define LCD_M_PWRMD 0x07 /* Power control (3-bit) mode mask */ -#define LCD_M_RESRT 0x07 /* V5 v. reg. int. resistor ratio (3-bit) ratio mask */ -#define LCD_M_EVSET 0x3F /* Electronic volume mode byte (6-bit) volume mask */ -#define LCD_M_SION 0x03 /* Static indicator ON (2-bit) mode mask */ - -/*** LCD Power control cirquits control masks ***/ -#define LCD_PWRBSTR 0x04 /* Power control mode - Booster cirquit ON */ -#define LCD_PWRVREG 0x02 /* Power control mode - Voltage regulator cirquit ON */ -#define LCD_PWRVFOL 0x01 /* Power control mode - Voltage follower cirquit ON */ - -/*** LCD Static indicator states ***/ -#define LCD_SIS_OFF 0x00 /* Static indicator register set - OFF state */ -#define LCD_SIS_BL 0x01 /* Static indicator register set - 1s blink state */ -#define LCD_SIS_RBL 0x02 /* Static indicator register set - .5s rapid blink state */ -#define LCD_SIS_ON 0x03 /* Static indicator register set - constantly on state */ - -/*** LCD functions special parameters (commands) ***/ -#define LCD_PREVP 0x80 /* Page number for moving to previous */ -#define LCD_NEXTP 0x81 /* or next page */ -#define LCD_ERR_P 0xFF /* Error in page number */ - -/*** LCD initialization settings ***/ -#define LCD_BIAS LCD_BIAS9 /* Bias: 1/9 */ -#define LCD_ADCMODE LCD_ADC_NRM /* ADC mode: normal */ -#define LCD_COMDIR LCD_C_NRM /* Common output mode: normal */ -#define LCD_RRATIO 0 /* Resistor ratio: 0 */ -#define LCD_CNTRST 0x1C /* electronic volume: 1Ch */ -#define LCD_POWERM (LCD_PWRBSTR | LCD_PWRVREG | LCD_PWRVFOL) /* Power mode: All on */ - -/**************************************************************************************/ - -static inline unsigned int sed156x_transfer(unsigned int val) -{ - unsigned int rx; - int b; - - rx = 0; b = 8; - while (--b >= 0) { - SED156X_SPI_TXD(val & 0x80); - val <<= 1; - SED156X_SPI_CLK_TOGGLE(); - SED156X_SPI_BIT_DELAY(); - rx <<= 1; - if (SED156X_SPI_RXD()) - rx |= 1; - SED156X_SPI_CLK_TOGGLE(); - SED156X_SPI_BIT_DELAY(); - } - - return rx; -} - -unsigned int sed156x_data_transfer(unsigned int val) -{ - unsigned int rx; - - SED156X_SPI_CLK(1); - SED156X_CS(0); - SED156X_A0(1); - - rx = sed156x_transfer(val); - - SED156X_CS(1); - - return rx; -} - -void sed156x_data_block_transfer(const u8 *p, int size) -{ - SED156X_SPI_CLK(1); - SED156X_CS(0); - SED156X_A0(1); - - while (--size >= 0) - sed156x_transfer(*p++); - - SED156X_CS(1); -} - -unsigned int sed156x_cmd_transfer(unsigned int val) -{ - unsigned int rx; - - SED156X_SPI_CLK(1); - SED156X_CS(0); - SED156X_A0(0); - - rx = sed156x_transfer(val); - - SED156X_CS(1); - SED156X_A0(1); - - return rx; -} - -/******************************************************************************/ - -static u8 hw_screen[LCD_PAGES][LCD_COLUMNS]; -static u8 last_hw_screen[LCD_PAGES][LCD_COLUMNS]; -static u8 sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT]; - -void sed156x_sync(void) -{ - int i, j, last_page; - u8 *d; - const u8 *s, *e, *b, *r; - u8 v0, v1, v2, v3, v4, v5, v6, v7; - - /* copy and rotate sw_screen to hw_screen */ - for (i = 0; i < LCD_HEIGHT / 8; i++) { - - d = &hw_screen[i][0]; - s = &sw_screen[LCD_BYTE_WIDTH * 8 * i + LCD_BYTE_WIDTH - 1]; - - for (j = 0; j < LCD_WIDTH / 8; j++) { - - v0 = s[0 * LCD_BYTE_WIDTH]; - v1 = s[1 * LCD_BYTE_WIDTH]; - v2 = s[2 * LCD_BYTE_WIDTH]; - v3 = s[3 * LCD_BYTE_WIDTH]; - v4 = s[4 * LCD_BYTE_WIDTH]; - v5 = s[5 * LCD_BYTE_WIDTH]; - v6 = s[6 * LCD_BYTE_WIDTH]; - v7 = s[7 * LCD_BYTE_WIDTH]; - - d[0] = ((v7 & 0x01) << 7) | - ((v6 & 0x01) << 6) | - ((v5 & 0x01) << 5) | - ((v4 & 0x01) << 4) | - ((v3 & 0x01) << 3) | - ((v2 & 0x01) << 2) | - ((v1 & 0x01) << 1) | - (v0 & 0x01) ; - - d[1] = ((v7 & 0x02) << 6) | - ((v6 & 0x02) << 5) | - ((v5 & 0x02) << 4) | - ((v4 & 0x02) << 3) | - ((v3 & 0x02) << 2) | - ((v2 & 0x02) << 1) | - ((v1 & 0x02) << 0) | - ((v0 & 0x02) >> 1) ; - - d[2] = ((v7 & 0x04) << 5) | - ((v6 & 0x04) << 4) | - ((v5 & 0x04) << 3) | - ((v4 & 0x04) << 2) | - ((v3 & 0x04) << 1) | - (v2 & 0x04) | - ((v1 & 0x04) >> 1) | - ((v0 & 0x04) >> 2) ; - - d[3] = ((v7 & 0x08) << 4) | - ((v6 & 0x08) << 3) | - ((v5 & 0x08) << 2) | - ((v4 & 0x08) << 1) | - (v3 & 0x08) | - ((v2 & 0x08) >> 1) | - ((v1 & 0x08) >> 2) | - ((v0 & 0x08) >> 3) ; - - d[4] = ((v7 & 0x10) << 3) | - ((v6 & 0x10) << 2) | - ((v5 & 0x10) << 1) | - (v4 & 0x10) | - ((v3 & 0x10) >> 1) | - ((v2 & 0x10) >> 2) | - ((v1 & 0x10) >> 3) | - ((v0 & 0x10) >> 4) ; - - d[5] = ((v7 & 0x20) << 2) | - ((v6 & 0x20) << 1) | - (v5 & 0x20) | - ((v4 & 0x20) >> 1) | - ((v3 & 0x20) >> 2) | - ((v2 & 0x20) >> 3) | - ((v1 & 0x20) >> 4) | - ((v0 & 0x20) >> 5) ; - - d[6] = ((v7 & 0x40) << 1) | - (v6 & 0x40) | - ((v5 & 0x40) >> 1) | - ((v4 & 0x40) >> 2) | - ((v3 & 0x40) >> 3) | - ((v2 & 0x40) >> 4) | - ((v1 & 0x40) >> 5) | - ((v0 & 0x40) >> 6) ; - - d[7] = (v7 & 0x80) | - ((v6 & 0x80) >> 1) | - ((v5 & 0x80) >> 2) | - ((v4 & 0x80) >> 3) | - ((v3 & 0x80) >> 4) | - ((v2 & 0x80) >> 5) | - ((v1 & 0x80) >> 6) | - ((v0 & 0x80) >> 7) ; - - d += 8; - s--; - } - } - - /* and now output only the differences */ - for (i = 0; i < LCD_PAGES; i++) { - - b = &hw_screen[i][0]; - e = &hw_screen[i][LCD_COLUMNS]; - - d = &last_hw_screen[i][0]; - s = b; - - last_page = -1; - - /* update only the differences */ - do { - while (s < e && *s == *d) { - s++; - d++; - } - if (s == e) - break; - r = s; - while (s < e && *s != *d) - *d++ = *s++; - - j = r - b; - - if (i != last_page) { - sed156x_cmd_transfer(LCD_PADDR | i); - last_page = i; - } - - sed156x_cmd_transfer(LCD_CADRH | ((j >> 4) & 0x0F)); - sed156x_cmd_transfer(LCD_CADRL | (j & 0x0F)); - sed156x_data_block_transfer(r, s - r); - - } while (s < e); - } - -/******** - for (i = 0; i < LCD_PAGES; i++) { - sed156x_cmd_transfer(LCD_PADDR | i); - sed156x_cmd_transfer(LCD_CADRH | 0); - sed156x_cmd_transfer(LCD_CADRL | 0); - sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS); - } - memcpy(last_hw_screen, hw_screen, sizeof(last_hw_screen)); -********/ -} - -void sed156x_clear(void) -{ - memset(sw_screen, 0, sizeof(sw_screen)); -} - -void sed156x_output_at(int x, int y, const char *str, int size) -{ - int i, j; - u8 *p; - const u8 *s; - - if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH) - return; - - p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH]; - - while (--size >= 0) { - - s = &video_fontdata[((int)*str++ & 0xff) * VIDEO_FONT_BYTE_WIDTH * VIDEO_FONT_HEIGHT]; - for (i = 0; i < VIDEO_FONT_HEIGHT; i++) { - for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++) - *p++ = *s++; - p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH; - } - p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH); - - if (x >= LCD_TEXT_WIDTH) - break; - x++; - } -} - -void sed156x_reverse_at(int x, int y, int size) -{ - int i, j; - u8 *p; - - if ((unsigned int)y >= LCD_TEXT_HEIGHT || (unsigned int)x >= LCD_TEXT_WIDTH) - return; - - p = &sw_screen[y * VIDEO_FONT_HEIGHT * LCD_BYTE_WIDTH + x * VIDEO_FONT_BYTE_WIDTH]; - - while (--size >= 0) { - - for (i = 0; i < VIDEO_FONT_HEIGHT; i++) { - for (j = 0; j < VIDEO_FONT_BYTE_WIDTH; j++, p++) - *p = ~*p; - p += LCD_BYTE_WIDTH - VIDEO_FONT_BYTE_WIDTH; - } - p -= (LCD_BYTE_LINESZ - VIDEO_FONT_BYTE_WIDTH); - - if (x >= LCD_TEXT_WIDTH) - break; - x++; - } -} - -void sed156x_scroll_line(void) -{ - memmove(&sw_screen[0], - &sw_screen[LCD_BYTE_LINESZ], - LCD_BYTE_WIDTH * (LCD_HEIGHT - VIDEO_FONT_HEIGHT)); -} - -void sed156x_scroll(int dx, int dy) -{ - u8 *p1 = NULL, *p2 = NULL, *p3 = NULL; /* pacify gcc */ - int adx, ady, i, sz; - - adx = dx > 0 ? dx : -dx; - ady = dy > 0 ? dy : -dy; - - /* overscroll? erase everything */ - if (adx >= LCD_TEXT_WIDTH || ady >= LCD_TEXT_HEIGHT) { - memset(sw_screen, 0, sizeof(sw_screen)); - return; - } - - sz = LCD_BYTE_LINESZ * ady; - if (dy > 0) { - p1 = &sw_screen[0]; - p2 = &sw_screen[sz]; - p3 = &sw_screen[LCD_BYTE_WIDTH * LCD_HEIGHT - sz]; - } else if (dy < 0) { - p1 = &sw_screen[sz]; - p2 = &sw_screen[0]; - p3 = &sw_screen[0]; - } - - if (ady > 0) { - memmove(p1, p2, LCD_BYTE_WIDTH * LCD_HEIGHT - sz); - memset(p3, 0, sz); - } - - sz = VIDEO_FONT_BYTE_WIDTH * adx; - if (dx > 0) { - p1 = &sw_screen[0]; - p2 = &sw_screen[0] + sz; - p3 = &sw_screen[0] + LCD_BYTE_WIDTH - sz; - } else if (dx < 0) { - p1 = &sw_screen[0] + sz; - p2 = &sw_screen[0]; - p3 = &sw_screen[0]; - } - - /* xscroll */ - if (adx > 0) { - for (i = 0; i < LCD_HEIGHT; i++) { - memmove(p1, p2, LCD_BYTE_WIDTH - sz); - memset(p3, 0, sz); - p1 += LCD_BYTE_WIDTH; - p2 += LCD_BYTE_WIDTH; - p3 += LCD_BYTE_WIDTH; - } - } -} - -void sed156x_init(void) -{ - int i; - - SED156X_CS(1); - SED156X_A0(1); - - /* Send initialization commands to the LCD */ - sed156x_cmd_transfer(LCD_OFF); /* Turn display OFF */ - sed156x_cmd_transfer(LCD_BIAS); /* set the LCD Bias, */ - sed156x_cmd_transfer(LCD_ADCMODE); /* ADC mode, */ - sed156x_cmd_transfer(LCD_COMDIR); /* common output mode, */ - sed156x_cmd_transfer(LCD_RESRT | LCD_RRATIO); /* resistor ratio, */ - sed156x_cmd_transfer(LCD_EVSET); /* electronic volume, */ - sed156x_cmd_transfer(LCD_CNTRST); - sed156x_cmd_transfer(LCD_PWRMD | LCD_POWERM); /* and power mode */ - sed156x_cmd_transfer(LCD_PADDR | 0); /* cursor home */ - sed156x_cmd_transfer(LCD_CADRH | 0); - sed156x_cmd_transfer(LCD_CADRL | 0); - sed156x_cmd_transfer(LCD_LADDR | 0); /* and display start line */ - sed156x_cmd_transfer(LCD_DSP_NRM); /* LCD display Normal */ - - /* clear everything */ - memset(sw_screen, 0, sizeof(sw_screen)); - memset(hw_screen, 0, sizeof(hw_screen)); - memset(last_hw_screen, 0, sizeof(last_hw_screen)); - - for (i = 0; i < LCD_PAGES; i++) { - sed156x_cmd_transfer(LCD_PADDR | i); - sed156x_cmd_transfer(LCD_CADRH | 0); - sed156x_cmd_transfer(LCD_CADRL | 0); - sed156x_data_block_transfer(&hw_screen[i][0], LCD_COLUMNS); - } - - sed156x_clear(); - sed156x_sync(); - sed156x_cmd_transfer(LCD_ON); /* Turn display ON */ -} diff --git a/drivers/video/sm501.c b/drivers/video/sm501.c deleted file mode 100644 index a468bd96ad..0000000000 --- a/drivers/video/sm501.c +++ /dev/null @@ -1,225 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * (C) Copyright 2005 - * Martin Krause TQ-Systems GmbH martin.krause@tqs.de - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Basic video support for SMI SM501 "Voyager" graphic controller - */ - -#include <common.h> - -#include <asm/io.h> -#include <pci.h> -#include <video_fb.h> -#include <sm501.h> - -#define read8(ptrReg) \ - *(volatile unsigned char *)(sm501.isaBase + ptrReg) - -#define write8(ptrReg,value) \ - *(volatile unsigned char *)(sm501.isaBase + ptrReg) = value - -#define read16(ptrReg) \ - (*(volatile unsigned short *)(sm501.isaBase + ptrReg)) - -#define write16(ptrReg,value) \ - (*(volatile unsigned short *)(sm501.isaBase + ptrReg) = value) - -#define read32(ptrReg) \ - (*(volatile unsigned int *)(sm501.isaBase + ptrReg)) - -#define write32(ptrReg, value) \ - (*(volatile unsigned int *)(sm501.isaBase + ptrReg) = value) - -GraphicDevice sm501; - -void write_be32(int off, unsigned int val) -{ - out_be32((unsigned __iomem *)(sm501.isaBase + off), val); -} - -void write_le32(int off, unsigned int val) -{ - out_le32((unsigned __iomem *)(sm501.isaBase + off), val); -} - -void (*write_reg32)(int off, unsigned int val) = write_be32; - -/*----------------------------------------------------------------------------- - * SmiSetRegs -- - *----------------------------------------------------------------------------- - */ -static void SmiSetRegs (void) -{ - /* - * The content of the chipset register depends on the board (clocks, - * ...) - */ - const SMI_REGS *preg = board_get_regs (); - while (preg->Index) { - write_reg32 (preg->Index, preg->Value); - /* - * Insert a delay between - */ - udelay (1000); - preg ++; - } -} - -#ifdef CONFIG_VIDEO_SM501_PCI -static struct pci_device_id sm501_pci_tbl[] = { - { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_501 }, - {} -}; -#endif - -/* - * We do not enforce board code to provide empty/unused - * functions for this driver and define weak default - * functions here. - */ -unsigned int __board_video_init (void) -{ - return 0; -} - -unsigned int board_video_init (void) - __attribute__((weak, alias("__board_video_init"))); - -unsigned int __board_video_get_fb (void) -{ - return 0; -} - -unsigned int board_video_get_fb (void) - __attribute__((weak, alias("__board_video_get_fb"))); - -void __board_validate_screen (unsigned int base) -{ -} - -void board_validate_screen (unsigned int base) - __attribute__((weak, alias("__board_validate_screen"))); - -/*----------------------------------------------------------------------------- - * video_hw_init -- - *----------------------------------------------------------------------------- - */ -void *video_hw_init (void) -{ -#ifdef CONFIG_VIDEO_SM501_PCI - unsigned int pci_mem_base, pci_mmio_base; - unsigned int id; - unsigned short device_id; - pci_dev_t devbusfn; - int mem; -#endif - unsigned int *vm, i; - - memset (&sm501, 0, sizeof (GraphicDevice)); - -#ifdef CONFIG_VIDEO_SM501_PCI - printf("Video: "); - - /* Look for SM501/SM502 chips */ - devbusfn = pci_find_devices(sm501_pci_tbl, 0); - if (devbusfn < 0) { - printf ("PCI Controller not found.\n"); - goto not_pci; - } - - /* Setup */ - pci_write_config_dword (devbusfn, PCI_COMMAND, - (PCI_COMMAND_MEMORY | PCI_COMMAND_IO)); - pci_read_config_word (devbusfn, PCI_DEVICE_ID, &device_id); - pci_read_config_dword (devbusfn, PCI_REVISION_ID, &id); - pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_0, &pci_mem_base); - pci_read_config_dword (devbusfn, PCI_BASE_ADDRESS_1, &pci_mmio_base); - sm501.frameAdrs = pci_mem_to_phys (devbusfn, pci_mem_base); - sm501.isaBase = pci_mem_to_phys (devbusfn, pci_mmio_base); - - if (sm501.isaBase) - write_reg32 = write_le32; - - mem = in_le32 ((unsigned __iomem *)(sm501.isaBase + 0x10)); - mem = (mem & 0x0000e000) >> 13; - switch (mem) { - case 1: - mem = 8; - break; - case 2: - mem = 16; - break; - case 3: - mem = 32; - break; - case 4: - mem = 64; - break; - case 5: - mem = 2; - break; - case 0: - default: - mem = 4; - } - printf ("PCI SM50%d %d MB\n", ((id & 0xff) == 0xC0) ? 2 : 1, mem); -not_pci: -#endif - /* - * Initialization of the access to the graphic chipset Retreive base - * address of the chipset (see board/RPXClassic/eccx.c) - */ - if (!sm501.isaBase) { - sm501.isaBase = board_video_init (); - if (!sm501.isaBase) - return NULL; - } - - if (!sm501.frameAdrs) { - sm501.frameAdrs = board_video_get_fb (); - if (!sm501.frameAdrs) - return NULL; - } - - sm501.winSizeX = board_get_width (); - sm501.winSizeY = board_get_height (); - -#if defined(CONFIG_VIDEO_SM501_8BPP) - sm501.gdfIndex = GDF__8BIT_INDEX; - sm501.gdfBytesPP = 1; - -#elif defined(CONFIG_VIDEO_SM501_16BPP) - sm501.gdfIndex = GDF_16BIT_565RGB; - sm501.gdfBytesPP = 2; - -#elif defined(CONFIG_VIDEO_SM501_32BPP) - sm501.gdfIndex = GDF_32BIT_X888RGB; - sm501.gdfBytesPP = 4; -#else -#error Unsupported SM501 BPP -#endif - - sm501.memSize = sm501.winSizeX * sm501.winSizeY * sm501.gdfBytesPP; - - /* Load Smi registers */ - SmiSetRegs (); - - /* (see board/RPXClassic/RPXClassic.c) */ - board_validate_screen (sm501.isaBase); - - /* Clear video memory */ - i = sm501.memSize/4; - vm = (unsigned int *)sm501.frameAdrs; - while(i--) - *vm++ = 0; - - return (&sm501); -} diff --git a/include/sed156x.h b/include/sed156x.h deleted file mode 100644 index 4e24e01d4b..0000000000 --- a/include/sed156x.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * (C) Copyright 2004 - * - * Pantelis Antoniou <panto@intracom.gr> - * Intracom S.A. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* Video support for Epson SED156x chipset(s) */ - -#ifndef SED156X_H -#define SED156X_H - -void sed156x_init(void); -void sed156x_clear(void); -void sed156x_output_at(int x, int y, const char *str, int size); -void sed156x_reverse_at(int x, int y, int size); -void sed156x_sync(void); -void sed156x_scroll(int dx, int dy); - -/* export display */ -extern const int sed156x_text_width; -extern const int sed156x_text_height; - -#endif /* SED156X_H */ diff --git a/include/sm501.h b/include/sm501.h deleted file mode 100644 index 34ce350e6a..0000000000 --- a/include/sm501.h +++ /dev/null @@ -1,35 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - <www.staubli.com> - * Pierre AUBERT p.aubert@staubli.com - * - * (C) Copyright 2005 - * Martin Krause TQ-Systems GmbH martin.krause@tqs.de - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Basic video support for SMI SM501 "Voyager" graphic controller - */ - -#ifndef _SM501_H_ -#define _SM501_H_ - -#define PCI_VENDOR_SM 0x126f -#define PCI_DEVICE_SM501 0x0501 - -typedef struct { - unsigned int Index; - unsigned int Value; -} SMI_REGS; - -/* Board specific functions */ -unsigned int board_video_init (void); -void board_validate_screen (unsigned int base); -const SMI_REGS *board_get_regs (void); -int board_get_width (void); -int board_get_height (void); -unsigned int board_video_get_fb (void); - -#endif /* _SM501_H_ */ diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 2d77ff80eb..2dacf7961a 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -5201,7 +5201,6 @@ CONFIG_VIDEO_MXS CONFIG_VIDEO_MXS_MODE_SYSTEM CONFIG_VIDEO_OMAP3 CONFIG_VIDEO_ONBOARD -CONFIG_VIDEO_SM501_PCI CONFIG_VIDEO_STD_TIMINGS CONFIG_VIDEO_SUNXI CONFIG_VIDEO_VCXK |