From 352d259130b349fe9593b8dada641bd78a9659e5 Mon Sep 17 00:00:00 2001 From: Jean-Christophe PLAGNIOL-VILLARD Date: Tue, 20 Nov 2007 20:41:48 +0100 Subject: drivers/video : move video drivers to drivers/video Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD --- Makefile | 1 + drivers/Makefile | 8 - drivers/ati_ids.h | 211 ------- drivers/ati_radeon_fb.c | 488 ---------------- drivers/ati_radeon_fb.h | 282 --------- drivers/cfb_console.c | 1274 ---------------------------------------- drivers/ct69000.c | 1286 ----------------------------------------- drivers/sed13806.c | 310 ---------- drivers/sed156x.c | 566 ------------------ drivers/sm501.c | 150 ----- drivers/smiLynxEM.c | 858 --------------------------- drivers/video/Makefile | 53 ++ drivers/video/ati_ids.h | 211 +++++++ drivers/video/ati_radeon_fb.c | 488 ++++++++++++++++ drivers/video/ati_radeon_fb.h | 282 +++++++++ drivers/video/cfb_console.c | 1274 ++++++++++++++++++++++++++++++++++++++++ drivers/video/ct69000.c | 1286 +++++++++++++++++++++++++++++++++++++++++ drivers/video/sed13806.c | 310 ++++++++++ drivers/video/sed156x.c | 566 ++++++++++++++++++ drivers/video/sm501.c | 150 +++++ drivers/video/smiLynxEM.c | 858 +++++++++++++++++++++++++++ drivers/video/videomodes.c | 208 +++++++ drivers/video/videomodes.h | 88 +++ drivers/videomodes.c | 208 ------- drivers/videomodes.h | 88 --- 25 files changed, 5775 insertions(+), 5729 deletions(-) delete mode 100644 drivers/ati_ids.h delete mode 100644 drivers/ati_radeon_fb.c delete mode 100644 drivers/ati_radeon_fb.h delete mode 100644 drivers/cfb_console.c delete mode 100644 drivers/ct69000.c delete mode 100644 drivers/sed13806.c delete mode 100644 drivers/sed156x.c delete mode 100644 drivers/sm501.c delete mode 100644 drivers/smiLynxEM.c create mode 100644 drivers/video/Makefile create mode 100644 drivers/video/ati_ids.h create mode 100644 drivers/video/ati_radeon_fb.c create mode 100644 drivers/video/ati_radeon_fb.h create mode 100644 drivers/video/cfb_console.c create mode 100644 drivers/video/ct69000.c create mode 100644 drivers/video/sed13806.c create mode 100644 drivers/video/sed156x.c create mode 100644 drivers/video/sm501.c create mode 100644 drivers/video/smiLynxEM.c create mode 100644 drivers/video/videomodes.c create mode 100644 drivers/video/videomodes.h delete mode 100644 drivers/videomodes.c delete mode 100644 drivers/videomodes.h diff --git a/Makefile b/Makefile index 22eea65..8272965 100644 --- a/Makefile +++ b/Makefile @@ -210,6 +210,7 @@ LIBS += dtt/libdtt.a LIBS += drivers/i2c/libi2c.a LIBS += drivers/pci/libpci.a LIBS += drivers/pcmcia/libpcmcia.a +LIBS += drivers/video/libvideo.a LIBS += drivers/libdrivers.a LIBS += drivers/bios_emulator/libatibiosemu.a LIBS += drivers/nand/libnand.a diff --git a/drivers/Makefile b/drivers/Makefile index 5e31304..c7fc597 100755 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -48,10 +48,7 @@ COBJS-y += systemace.o # # Console Drivers # -COBJS-y += ati_radeon_fb.o COBJS-y += atmel_usart.o -COBJS-y += cfb_console.o -COBJS-y += ct69000.o COBJS-y += i8042.o COBJS-y += keyboard.o COBJS-y += netconsole.o @@ -60,15 +57,10 @@ COBJS-y += pc_keyb.o COBJS-y += ps2ser.o COBJS-y += ps2mult.o COBJS-y += s3c4510b_uart.o -COBJS-y += sed13806.o -COBJS-y += sed156x.o COBJS-y += serial.o COBJS-y += serial_max3100.o COBJS-y += serial_xuartlite.o -COBJS-y += sm501.o -COBJS-y += smiLynxEM.o COBJS-y += usbtty.o -COBJS-y += videomodes.o # # Network Drivers diff --git a/drivers/ati_ids.h b/drivers/ati_ids.h deleted file mode 100644 index 3e72a7d..0000000 --- a/drivers/ati_ids.h +++ /dev/null @@ -1,211 +0,0 @@ -/* - * ATI PCI IDs from XFree86, kept here to make sync'ing with - * XFree much simpler. Currently, this list is only used by - * radeonfb - */ - -#define PCI_CHIP_RV380_3150 0x3150 -#define PCI_CHIP_RV380_3151 0x3151 -#define PCI_CHIP_RV380_3152 0x3152 -#define PCI_CHIP_RV380_3153 0x3153 -#define PCI_CHIP_RV380_3154 0x3154 -#define PCI_CHIP_RV380_3156 0x3156 -#define PCI_CHIP_RV380_3E50 0x3E50 -#define PCI_CHIP_RV380_3E51 0x3E51 -#define PCI_CHIP_RV380_3E52 0x3E52 -#define PCI_CHIP_RV380_3E53 0x3E53 -#define PCI_CHIP_RV380_3E54 0x3E54 -#define PCI_CHIP_RV380_3E56 0x3E56 -#define PCI_CHIP_RS100_4136 0x4136 -#define PCI_CHIP_RS200_4137 0x4137 -#define PCI_CHIP_R300_AD 0x4144 -#define PCI_CHIP_R300_AE 0x4145 -#define PCI_CHIP_R300_AF 0x4146 -#define PCI_CHIP_R300_AG 0x4147 -#define PCI_CHIP_R350_AH 0x4148 -#define PCI_CHIP_R350_AI 0x4149 -#define PCI_CHIP_R350_AJ 0x414A -#define PCI_CHIP_R350_AK 0x414B -#define PCI_CHIP_RV350_AP 0x4150 -#define PCI_CHIP_RV350_AQ 0x4151 -#define PCI_CHIP_RV360_AR 0x4152 -#define PCI_CHIP_RV350_AS 0x4153 -#define PCI_CHIP_RV350_AT 0x4154 -#define PCI_CHIP_RV350_AV 0x4156 -#define PCI_CHIP_MACH32 0x4158 -#define PCI_CHIP_RS250_4237 0x4237 -#define PCI_CHIP_R200_BB 0x4242 -#define PCI_CHIP_R200_BC 0x4243 -#define PCI_CHIP_RS100_4336 0x4336 -#define PCI_CHIP_RS200_4337 0x4337 -#define PCI_CHIP_MACH64CT 0x4354 -#define PCI_CHIP_MACH64CX 0x4358 -#define PCI_CHIP_RS250_4437 0x4437 -#define PCI_CHIP_MACH64ET 0x4554 -#define PCI_CHIP_MACH64GB 0x4742 -#define PCI_CHIP_MACH64GD 0x4744 -#define PCI_CHIP_MACH64GI 0x4749 -#define PCI_CHIP_MACH64GL 0x474C -#define PCI_CHIP_MACH64GM 0x474D -#define PCI_CHIP_MACH64GN 0x474E -#define PCI_CHIP_MACH64GO 0x474F -#define PCI_CHIP_MACH64GP 0x4750 -#define PCI_CHIP_MACH64GQ 0x4751 -#define PCI_CHIP_MACH64GR 0x4752 -#define PCI_CHIP_MACH64GS 0x4753 -#define PCI_CHIP_MACH64GT 0x4754 -#define PCI_CHIP_MACH64GU 0x4755 -#define PCI_CHIP_MACH64GV 0x4756 -#define PCI_CHIP_MACH64GW 0x4757 -#define PCI_CHIP_MACH64GX 0x4758 -#define PCI_CHIP_MACH64GY 0x4759 -#define PCI_CHIP_MACH64GZ 0x475A -#define PCI_CHIP_RV250_Id 0x4964 -#define PCI_CHIP_RV250_Ie 0x4965 -#define PCI_CHIP_RV250_If 0x4966 -#define PCI_CHIP_RV250_Ig 0x4967 -#define PCI_CHIP_R420_JH 0x4A48 -#define PCI_CHIP_R420_JI 0x4A49 -#define PCI_CHIP_R420_JJ 0x4A4A -#define PCI_CHIP_R420_JK 0x4A4B -#define PCI_CHIP_R420_JL 0x4A4C -#define PCI_CHIP_R420_JM 0x4A4D -#define PCI_CHIP_R420_JN 0x4A4E -#define PCI_CHIP_R420_JP 0x4A50 -#define PCI_CHIP_MACH64LB 0x4C42 -#define PCI_CHIP_MACH64LD 0x4C44 -#define PCI_CHIP_RAGE128LE 0x4C45 -#define PCI_CHIP_RAGE128LF 0x4C46 -#define PCI_CHIP_MACH64LG 0x4C47 -#define PCI_CHIP_MACH64LI 0x4C49 -#define PCI_CHIP_MACH64LM 0x4C4D -#define PCI_CHIP_MACH64LN 0x4C4E -#define PCI_CHIP_MACH64LP 0x4C50 -#define PCI_CHIP_MACH64LQ 0x4C51 -#define PCI_CHIP_MACH64LR 0x4C52 -#define PCI_CHIP_MACH64LS 0x4C53 -#define PCI_CHIP_MACH64LT 0x4C54 -#define PCI_CHIP_RADEON_LW 0x4C57 -#define PCI_CHIP_RADEON_LX 0x4C58 -#define PCI_CHIP_RADEON_LY 0x4C59 -#define PCI_CHIP_RADEON_LZ 0x4C5A -#define PCI_CHIP_RV250_Ld 0x4C64 -#define PCI_CHIP_RV250_Le 0x4C65 -#define PCI_CHIP_RV250_Lf 0x4C66 -#define PCI_CHIP_RV250_Lg 0x4C67 -#define PCI_CHIP_RV250_Ln 0x4C6E -#define PCI_CHIP_RAGE128MF 0x4D46 -#define PCI_CHIP_RAGE128ML 0x4D4C -#define PCI_CHIP_R300_ND 0x4E44 -#define PCI_CHIP_R300_NE 0x4E45 -#define PCI_CHIP_R300_NF 0x4E46 -#define PCI_CHIP_R300_NG 0x4E47 -#define PCI_CHIP_R350_NH 0x4E48 -#define PCI_CHIP_R350_NI 0x4E49 -#define PCI_CHIP_R360_NJ 0x4E4A -#define PCI_CHIP_R350_NK 0x4E4B -#define PCI_CHIP_RV350_NP 0x4E50 -#define PCI_CHIP_RV350_NQ 0x4E51 -#define PCI_CHIP_RV350_NR 0x4E52 -#define PCI_CHIP_RV350_NS 0x4E53 -#define PCI_CHIP_RV350_NT 0x4E54 -#define PCI_CHIP_RV350_NV 0x4E56 -#define PCI_CHIP_RAGE128PA 0x5041 -#define PCI_CHIP_RAGE128PB 0x5042 -#define PCI_CHIP_RAGE128PC 0x5043 -#define PCI_CHIP_RAGE128PD 0x5044 -#define PCI_CHIP_RAGE128PE 0x5045 -#define PCI_CHIP_RAGE128PF 0x5046 -#define PCI_CHIP_RAGE128PG 0x5047 -#define PCI_CHIP_RAGE128PH 0x5048 -#define PCI_CHIP_RAGE128PI 0x5049 -#define PCI_CHIP_RAGE128PJ 0x504A -#define PCI_CHIP_RAGE128PK 0x504B -#define PCI_CHIP_RAGE128PL 0x504C -#define PCI_CHIP_RAGE128PM 0x504D -#define PCI_CHIP_RAGE128PN 0x504E -#define PCI_CHIP_RAGE128PO 0x504F -#define PCI_CHIP_RAGE128PP 0x5050 -#define PCI_CHIP_RAGE128PQ 0x5051 -#define PCI_CHIP_RAGE128PR 0x5052 -#define PCI_CHIP_RAGE128PS 0x5053 -#define PCI_CHIP_RAGE128PT 0x5054 -#define PCI_CHIP_RAGE128PU 0x5055 -#define PCI_CHIP_RAGE128PV 0x5056 -#define PCI_CHIP_RAGE128PW 0x5057 -#define PCI_CHIP_RAGE128PX 0x5058 -#define PCI_CHIP_RADEON_QD 0x5144 -#define PCI_CHIP_RADEON_QE 0x5145 -#define PCI_CHIP_RADEON_QF 0x5146 -#define PCI_CHIP_RADEON_QG 0x5147 -#define PCI_CHIP_R200_QH 0x5148 -#define PCI_CHIP_R200_QI 0x5149 -#define PCI_CHIP_R200_QJ 0x514A -#define PCI_CHIP_R200_QK 0x514B -#define PCI_CHIP_R200_QL 0x514C -#define PCI_CHIP_R200_QM 0x514D -#define PCI_CHIP_R200_QN 0x514E -#define PCI_CHIP_R200_QO 0x514F -#define PCI_CHIP_RV200_QW 0x5157 -#define PCI_CHIP_RV200_QX 0x5158 -#define PCI_CHIP_RV100_QY 0x5159 -#define PCI_CHIP_RV100_QZ 0x515A -#define PCI_CHIP_RN50 0x515E -#define PCI_CHIP_RAGE128RE 0x5245 -#define PCI_CHIP_RAGE128RF 0x5246 -#define PCI_CHIP_RAGE128RG 0x5247 -#define PCI_CHIP_RAGE128RK 0x524B -#define PCI_CHIP_RAGE128RL 0x524C -#define PCI_CHIP_RAGE128SE 0x5345 -#define PCI_CHIP_RAGE128SF 0x5346 -#define PCI_CHIP_RAGE128SG 0x5347 -#define PCI_CHIP_RAGE128SH 0x5348 -#define PCI_CHIP_RAGE128SK 0x534B -#define PCI_CHIP_RAGE128SL 0x534C -#define PCI_CHIP_RAGE128SM 0x534D -#define PCI_CHIP_RAGE128SN 0x534E -#define PCI_CHIP_RAGE128TF 0x5446 -#define PCI_CHIP_RAGE128TL 0x544C -#define PCI_CHIP_RAGE128TR 0x5452 -#define PCI_CHIP_RAGE128TS 0x5453 -#define PCI_CHIP_RAGE128TT 0x5454 -#define PCI_CHIP_RAGE128TU 0x5455 -#define PCI_CHIP_RV370_5460 0x5460 -#define PCI_CHIP_RV370_5461 0x5461 -#define PCI_CHIP_RV370_5462 0x5462 -#define PCI_CHIP_RV370_5463 0x5463 -#define PCI_CHIP_RV370_5464 0x5464 -#define PCI_CHIP_RV370_5465 0x5465 -#define PCI_CHIP_RV370_5466 0x5466 -#define PCI_CHIP_RV370_5467 0x5467 -#define PCI_CHIP_R423_UH 0x5548 -#define PCI_CHIP_R423_UI 0x5549 -#define PCI_CHIP_R423_UJ 0x554A -#define PCI_CHIP_R423_UK 0x554B -#define PCI_CHIP_R423_UQ 0x5551 -#define PCI_CHIP_R423_UR 0x5552 -#define PCI_CHIP_R423_UT 0x5554 -#define PCI_CHIP_MACH64VT 0x5654 -#define PCI_CHIP_MACH64VU 0x5655 -#define PCI_CHIP_MACH64VV 0x5656 -#define PCI_CHIP_RS300_5834 0x5834 -#define PCI_CHIP_RS300_5835 0x5835 -#define PCI_CHIP_RS300_5836 0x5836 -#define PCI_CHIP_RS300_5837 0x5837 -#define PCI_CHIP_RV370_5B60 0x5B60 -#define PCI_CHIP_RV370_5B61 0x5B61 -#define PCI_CHIP_RV370_5B62 0x5B62 -#define PCI_CHIP_RV370_5B63 0x5B63 -#define PCI_CHIP_RV370_5B64 0x5B64 -#define PCI_CHIP_RV370_5B65 0x5B65 -#define PCI_CHIP_RV370_5B66 0x5B66 -#define PCI_CHIP_RV370_5B67 0x5B67 -#define PCI_CHIP_RV280_5960 0x5960 -#define PCI_CHIP_RV280_5961 0x5961 -#define PCI_CHIP_RV280_5962 0x5962 -#define PCI_CHIP_RV280_5964 0x5964 -#define PCI_CHIP_RV280_5C61 0x5C61 -#define PCI_CHIP_RV280_5C63 0x5C63 -#define PCI_CHIP_R423_5D57 0x5D57 -#define PCI_CHIP_RS350_7834 0x7834 -#define PCI_CHIP_RS350_7835 0x7835 diff --git a/drivers/ati_radeon_fb.c b/drivers/ati_radeon_fb.c deleted file mode 100644 index 9613d80..0000000 --- a/drivers/ati_radeon_fb.c +++ /dev/null @@ -1,488 +0,0 @@ -/* - * ATI Radeon Video card Framebuffer driver. - * - * Copyright 2007 Freescale Semiconductor, Inc. - * Zhang Wei - * Jason Jin - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - * - * Some codes of this file is partly ported from Linux kernel - * ATI video framebuffer driver. - * - * Now the driver is tested on below ATI chips: - * 9200 - * X300 - * X700 - * - */ - -#include - -#ifdef CONFIG_ATI_RADEON_FB - -#include -#include -#include -#include -#include -#include -#include - -#include -#include "ati_ids.h" -#include "ati_radeon_fb.h" - -#undef DEBUG - -#ifdef DEBUG -#define DPRINT(x...) printf(x) -#else -#define DPRINT(x...) do{}while(0) -#endif - -#ifndef min_t -#define min_t(type,x,y) \ - ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) -#endif - -#define MAX_MAPPED_VRAM (2048*2048*4) -#define MIN_MAPPED_VRAM (1024*768*1) - -/*#define PCI_VENDOR_ID_ATI*/ -#define PCI_CHIP_RV280_5960 0x5960 -#define PCI_CHIP_RV280_5961 0x5961 -#define PCI_CHIP_RV280_5962 0x5962 -#define PCI_CHIP_RV280_5964 0x5964 -#define PCI_CHIP_RV370_5B60 0x5B60 -#define PCI_CHIP_RV380_5657 0x5657 -#define PCI_CHIP_R420_554d 0x554d - -static struct pci_device_id ati_radeon_pci_ids[] = { - {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960}, - {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961}, - {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962}, - {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964}, - {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60}, - {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657}, - {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d}, - {0, 0} -}; - -static u16 ati_radeon_id_family_table[][2] = { - {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280}, - {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280}, - {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280}, - {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280}, - {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380}, - {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380}, - {PCI_CHIP_R420_554d, CHIP_FAMILY_R420}, - {0, 0} -}; - -u16 get_radeon_id_family(u16 device) -{ - int i; - for (i=0; ati_radeon_id_family_table[0][i]; i+=2) - if (ati_radeon_id_family_table[0][i] == device) - return ati_radeon_id_family_table[0][i + 1]; - return 0; -} - -struct radeonfb_info *rinfo; - -static void radeon_identify_vram(struct radeonfb_info *rinfo) -{ - u32 tmp; - - /* framebuffer size */ - if ((rinfo->family == CHIP_FAMILY_RS100) || - (rinfo->family == CHIP_FAMILY_RS200) || - (rinfo->family == CHIP_FAMILY_RS300)) { - u32 tom = INREG(NB_TOM); - tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); - - radeon_fifo_wait(6); - OUTREG(MC_FB_LOCATION, tom); - OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); - OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); - OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16); - - /* This is supposed to fix the crtc2 noise problem. */ - OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000); - - if ((rinfo->family == CHIP_FAMILY_RS100) || - (rinfo->family == CHIP_FAMILY_RS200)) { - /* This is to workaround the asic bug for RMX, some versions - of BIOS dosen't have this register initialized correctly. - */ - OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN, - ~CRTC_H_CUTOFF_ACTIVE_EN); - } - } else { - tmp = INREG(CONFIG_MEMSIZE); - } - - /* mem size is bits [28:0], mask off the rest */ - rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; - - /* - * Hack to get around some busted production M6's - * reporting no ram - */ - if (rinfo->video_ram == 0) { - switch (rinfo->pdev.device) { - case PCI_CHIP_RADEON_LY: - case PCI_CHIP_RADEON_LZ: - rinfo->video_ram = 8192 * 1024; - break; - default: - break; - } - } - - /* - * Now try to identify VRAM type - */ - if ((rinfo->family >= CHIP_FAMILY_R300) || - (INREG(MEM_SDRAM_MODE_REG) & (1<<30))) - rinfo->vram_ddr = 1; - else - rinfo->vram_ddr = 0; - - tmp = INREG(MEM_CNTL); - if (IS_R300_VARIANT(rinfo)) { - tmp &= R300_MEM_NUM_CHANNELS_MASK; - switch (tmp) { - case 0: rinfo->vram_width = 64; break; - case 1: rinfo->vram_width = 128; break; - case 2: rinfo->vram_width = 256; break; - default: rinfo->vram_width = 128; break; - } - } else if ((rinfo->family == CHIP_FAMILY_RV100) || - (rinfo->family == CHIP_FAMILY_RS100) || - (rinfo->family == CHIP_FAMILY_RS200)){ - if (tmp & RV100_MEM_HALF_MODE) - rinfo->vram_width = 32; - else - rinfo->vram_width = 64; - } else { - if (tmp & MEM_NUM_CHANNELS_MASK) - rinfo->vram_width = 128; - else - rinfo->vram_width = 64; - } - - /* This may not be correct, as some cards can have half of channel disabled - * ToDo: identify these cases - */ - - DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n", - rinfo->video_ram / 1024, - rinfo->vram_ddr ? "DDR" : "SDRAM", - rinfo->vram_width); - -} - -static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode) -{ - int i; - - radeon_fifo_wait(20); - -#if 0 - /* Workaround from XFree */ - if (rinfo->is_mobility) { - /* A temporal workaround for the occational blanking on certain laptop - * panels. This appears to related to the PLL divider registers - * (fail to lock?). It occurs even when all dividers are the same - * with their old settings. In this case we really don't need to - * fiddle with PLL registers. By doing this we can avoid the blanking - * problem with some panels. - */ - if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) && - (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) & - (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) { - /* We still have to force a switch to selected PPLL div thanks to - * an XFree86 driver bug which will switch it away in some cases - * even when using UseFDev */ - OUTREGP(CLOCK_CNTL_INDEX, - mode->clk_cntl_index & PPLL_DIV_SEL_MASK, - ~PPLL_DIV_SEL_MASK); - radeon_pll_errata_after_index(rinfo); - radeon_pll_errata_after_data(rinfo); - return; - } - } -#endif - if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return; - - /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/ - OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK); - - /* Reset PPLL & enable atomic update */ - OUTPLLP(PPLL_CNTL, - PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN, - ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); - - /* Switch to selected PPLL divider */ - OUTREGP(CLOCK_CNTL_INDEX, - mode->clk_cntl_index & PPLL_DIV_SEL_MASK, - ~PPLL_DIV_SEL_MASK); - - /* Set PPLL ref. div */ - if (rinfo->family == CHIP_FAMILY_R300 || - rinfo->family == CHIP_FAMILY_RS300 || - rinfo->family == CHIP_FAMILY_R350 || - rinfo->family == CHIP_FAMILY_RV350) { - if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { - /* When restoring console mode, use saved PPLL_REF_DIV - * setting. - */ - OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0); - } else { - /* R300 uses ref_div_acc field as real ref divider */ - OUTPLLP(PPLL_REF_DIV, - (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT), - ~R300_PPLL_REF_DIV_ACC_MASK); - } - } else - OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK); - - /* Set PPLL divider 3 & post divider*/ - OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK); - OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK); - - /* Write update */ - while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R) - ; - OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W); - - /* Wait read update complete */ - /* FIXME: Certain revisions of R300 can't recover here. Not sure of - the cause yet, but this workaround will mask the problem for now. - Other chips usually will pass at the very first test, so the - workaround shouldn't have any effect on them. */ - for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++) - ; - - OUTPLL(HTOTAL_CNTL, 0); - - /* Clear reset & atomic update */ - OUTPLLP(PPLL_CNTL, 0, - ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); - - /* We may want some locking ... oh well */ - udelay(5000); - - /* Switch back VCLK source to PPLL */ - OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK); -} - -typedef struct { - u16 reg; - u32 val; -} reg_val; - -#if 0 /* unused ? -> scheduled for removal */ -/* these common regs are cleared before mode setting so they do not - * interfere with anything - */ -static reg_val common_regs[] = { - { OVR_CLR, 0 }, - { OVR_WID_LEFT_RIGHT, 0 }, - { OVR_WID_TOP_BOTTOM, 0 }, - { OV0_SCALE_CNTL, 0 }, - { SUBPIC_CNTL, 0 }, - { VIPH_CONTROL, 0 }, - { I2C_CNTL_1, 0 }, - { GEN_INT_CNTL, 0 }, - { CAP0_TRIG_CNTL, 0 }, - { CAP1_TRIG_CNTL, 0 }, -}; -#endif /* 0 */ - -void radeon_setmode(void) -{ - struct radeon_regs *mode = malloc(sizeof(struct radeon_regs)); - - mode->crtc_gen_cntl = 0x03000200; - mode->crtc_ext_cntl = 0x00008048; - mode->dac_cntl = 0xff002100; - mode->crtc_h_total_disp = 0x4f0063; - mode->crtc_h_sync_strt_wid = 0x8c02a2; - mode->crtc_v_total_disp = 0x01df020c; - mode->crtc_v_sync_strt_wid = 0x8201ea; - mode->crtc_pitch = 0x00500050; - - OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); - OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, - ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS)); - OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); - OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); - OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); - OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); - OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); - OUTREG(CRTC_OFFSET, 0); - OUTREG(CRTC_OFFSET_CNTL, 0); - OUTREG(CRTC_PITCH, mode->crtc_pitch); - - mode->clk_cntl_index = 0x300; - mode->ppll_ref_div = 0xc; - mode->ppll_div_3 = 0x00030059; - - radeon_write_pll_regs(rinfo, mode); -} - -#include "bios_emulator/include/biosemu.h" -extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp); - -int radeon_probe(struct radeonfb_info *rinfo) -{ - pci_dev_t pdev; - u16 did; - - pdev = pci_find_devices(ati_radeon_pci_ids, 0); - - if (pdev != -1) { - pci_read_config_word(pdev, PCI_DEVICE_ID, &did); - printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n", - PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff, - (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7); - - strcpy(rinfo->name, "ATI Radeon"); - rinfo->pdev.vendor = PCI_VENDOR_ID_ATI; - rinfo->pdev.device = did; - rinfo->family = get_radeon_id_family(rinfo->pdev.device); - pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, - &rinfo->fb_base_phys); - pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2, - &rinfo->mmio_base_phys); - rinfo->fb_base_phys &= 0xfffff000; - rinfo->mmio_base_phys &= ~0x04; - - rinfo->mmio_base = (void *)rinfo->mmio_base_phys; - DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base); - rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16; - DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base); - /* PostBIOS with x86 emulater */ - BootVideoCardBIOS(pdev, NULL, 0); - - /* - * Check for errata - * (These will be added in the future for the chipfamily - * R300, RV200, RS200, RV100, RS100.) - */ - - /* Get VRAM size and type */ - radeon_identify_vram(rinfo); - - rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, - rinfo->video_ram); - rinfo->fb_base = (void *)rinfo->fb_base_phys; - - DPRINT("Radeon: framebuffer base phy address 0x%08x," \ - "MMIO base phy address 0x%08x," \ - "framebuffer local base 0x%08x.\n ", - rinfo->fb_base_phys, rinfo->mmio_base_phys, - rinfo->fb_local_base); - - return 0; - } - return -1; -} - -/* - * The Graphic Device - */ -GraphicDevice ctfb; - -#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 */ - -void *video_hw_init(void) -{ - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - int i; - u32 *vm; - - rinfo = malloc(sizeof(struct radeonfb_info)); - - if(radeon_probe(rinfo)) { - printf("No radeon video card found!\n"); - return NULL; - } - - /* fill in Graphic device struct */ - sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640, - 480, 16, (1000 / 1000), - (2000 / 1000)); - printf ("%s\n", pGD->modeIdent); - - pGD->winSizeX = 640; - pGD->winSizeY = 480; - pGD->plnSizeX = 640; - pGD->plnSizeY = 480; - - pGD->gdfBytesPP = 1; - pGD->gdfIndex = GDF__8BIT_INDEX; - - pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS; - pGD->pciBase = rinfo->fb_base_phys; - pGD->frameAdrs = rinfo->fb_base_phys; - pGD->memSize = 64 * 1024 * 1024; - - /* Cursor Start Address */ - pGD->dprBase = - (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys; - if ((pGD->dprBase & 0x0fff) != 0) { - /* allign it */ - pGD->dprBase &= 0xfffff000; - pGD->dprBase += 0x00001000; - } - DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase, - PATTERN_ADR); - pGD->vprBase = rinfo->fb_base_phys; /* Dummy */ - pGD->cprBase = rinfo->fb_base_phys; /* Dummy */ - /* set up Hardware */ - - /* Clear video memory */ - i = pGD->memSize / 4; - vm = (unsigned int *) pGD->pciBase; - while (i--) - *vm++ = 0; - /*SetDrawingEngine (bits_per_pixel);*/ - - radeon_setmode(); - - return ((void *) pGD); -} - -void video_set_lut (unsigned int index, /* color number */ - unsigned char r, /* red */ - unsigned char g, /* green */ - unsigned char b /* blue */ - ) -{ - OUTREG(PALETTE_INDEX, index); - OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b); -} -#endif diff --git a/drivers/ati_radeon_fb.h b/drivers/ati_radeon_fb.h deleted file mode 100644 index b5c4b8b..0000000 --- a/drivers/ati_radeon_fb.h +++ /dev/null @@ -1,282 +0,0 @@ -#ifndef __ATI_RADEON_FB_H -#define __ATI_RADEON_FB_H - -/*************************************************************** - * Most of the definitions here are adapted right from XFree86 * - ***************************************************************/ - -/* - * Chip families. Must fit in the low 16 bits of a long word - */ -enum radeon_family { - CHIP_FAMILY_UNKNOW, - CHIP_FAMILY_LEGACY, - CHIP_FAMILY_RADEON, - CHIP_FAMILY_RV100, - CHIP_FAMILY_RS100, /* U1 (IGP320M) or A3 (IGP320)*/ - CHIP_FAMILY_RV200, - CHIP_FAMILY_RS200, /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350), - RS250 (IGP 7000) */ - CHIP_FAMILY_R200, - CHIP_FAMILY_RV250, - CHIP_FAMILY_RS300, /* Radeon 9000 IGP */ - CHIP_FAMILY_RV280, - CHIP_FAMILY_R300, - CHIP_FAMILY_R350, - CHIP_FAMILY_RV350, - CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ - CHIP_FAMILY_R420, /* R420/R423/M18 */ - CHIP_FAMILY_LAST, -}; - -#define IS_RV100_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_RV100) || \ - ((rinfo)->family == CHIP_FAMILY_RV200) || \ - ((rinfo)->family == CHIP_FAMILY_RS100) || \ - ((rinfo)->family == CHIP_FAMILY_RS200) || \ - ((rinfo)->family == CHIP_FAMILY_RV250) || \ - ((rinfo)->family == CHIP_FAMILY_RV280) || \ - ((rinfo)->family == CHIP_FAMILY_RS300)) - -#define IS_R300_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_R300) || \ - ((rinfo)->family == CHIP_FAMILY_RV350) || \ - ((rinfo)->family == CHIP_FAMILY_R350) || \ - ((rinfo)->family == CHIP_FAMILY_RV380) || \ - ((rinfo)->family == CHIP_FAMILY_R420)) - -struct radeonfb_info { - char name[20]; - - struct pci_device_id pdev; - u16 family; - - u32 fb_base_phys; - u32 mmio_base_phys; - - void *mmio_base; - void *fb_base; - - u32 video_ram; - u32 mapped_vram; - int vram_width; - int vram_ddr; - - u32 fb_local_base; -}; - -#define INREG8(addr) readb((rinfo->mmio_base)+addr) -#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) -#define INREG16(addr) readw((rinfo->mmio_base)+addr) -#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr) -#define INREG(addr) readl((rinfo->mmio_base)+addr) -#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) - -static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, - u32 val, u32 mask) -{ - unsigned int tmp; - - tmp = INREG(addr); - tmp &= (mask); - tmp |= (val); - OUTREG(addr, tmp); -} - -#define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask) - -/* - * 2D Engine helper routines - */ -static inline void radeon_engine_flush (struct radeonfb_info *rinfo) -{ - int i; - - /* initiate flush */ - OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, - ~RB2D_DC_FLUSH_ALL); - - for (i=0; i < 2000000; i++) { - if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) - return; - udelay(1); - } - printf("radeonfb: Flush Timeout !\n"); -} - -static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) -{ - int i; - - for (i=0; i<2000000; i++) { - if ((INREG(RBBM_STATUS) & 0x7f) >= entries) - return; - udelay(1); - } - printf("radeonfb: FIFO Timeout !\n"); -} - -static inline void _radeon_engine_idle(struct radeonfb_info *rinfo) -{ - int i; - - /* ensure FIFO is empty before waiting for idle */ - _radeon_fifo_wait (rinfo, 64); - - for (i=0; i<2000000; i++) { - if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { - radeon_engine_flush (rinfo); - return; - } - udelay(1); - } - printf("radeonfb: Idle Timeout !\n"); -} - -#define radeon_engine_idle() _radeon_engine_idle(rinfo) -#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) -#define radeon_msleep(ms) _radeon_msleep(rinfo,ms) - -/* - * This structure contains the various registers manipulated by this - * driver for setting or restoring a mode. It's mostly copied from - * XFree's RADEONSaveRec structure. A few chip settings might still be - * tweaked without beeing reflected or saved in these registers though - */ -struct radeon_regs { - /* Common registers */ - u32 ovr_clr; - u32 ovr_wid_left_right; - u32 ovr_wid_top_bottom; - u32 ov0_scale_cntl; - u32 mpp_tb_config; - u32 mpp_gp_config; - u32 subpic_cntl; - u32 viph_control; - u32 i2c_cntl_1; - u32 gen_int_cntl; - u32 cap0_trig_cntl; - u32 cap1_trig_cntl; - u32 bus_cntl; - u32 surface_cntl; - u32 bios_5_scratch; - - /* Other registers to save for VT switches or driver load/unload */ - u32 dp_datatype; - u32 rbbm_soft_reset; - u32 clock_cntl_index; - u32 amcgpio_en_reg; - u32 amcgpio_mask; - - /* Surface/tiling registers */ - u32 surf_lower_bound[8]; - u32 surf_upper_bound[8]; - u32 surf_info[8]; - - /* CRTC registers */ - u32 crtc_gen_cntl; - u32 crtc_ext_cntl; - u32 dac_cntl; - u32 crtc_h_total_disp; - u32 crtc_h_sync_strt_wid; - u32 crtc_v_total_disp; - u32 crtc_v_sync_strt_wid; - u32 crtc_offset; - u32 crtc_offset_cntl; - u32 crtc_pitch; - u32 disp_merge_cntl; - u32 grph_buffer_cntl; - u32 crtc_more_cntl; - - /* CRTC2 registers */ - u32 crtc2_gen_cntl; - u32 dac2_cntl; - u32 disp_output_cntl; - u32 disp_hw_debug; - u32 disp2_merge_cntl; - u32 grph2_buffer_cntl; - u32 crtc2_h_total_disp; - u32 crtc2_h_sync_strt_wid; - u32 crtc2_v_total_disp; - u32 crtc2_v_sync_strt_wid; - u32 crtc2_offset; - u32 crtc2_offset_cntl; - u32 crtc2_pitch; - - /* Flat panel regs */ - u32 fp_crtc_h_total_disp; - u32 fp_crtc_v_total_disp; - u32 fp_gen_cntl; - u32 fp2_gen_cntl; - u32 fp_h_sync_strt_wid; - u32 fp2_h_sync_strt_wid; - u32 fp_horz_stretch; - u32 fp_panel_cntl; - u32 fp_v_sync_strt_wid; - u32 fp2_v_sync_strt_wid; - u32 fp_vert_stretch; - u32 lvds_gen_cntl; - u32 lvds_pll_cntl; - u32 tmds_crc; - u32 tmds_transmitter_cntl; - - /* Computed values for PLL */ - u32 dot_clock_freq; - int feedback_div; - int post_div; - - /* PLL registers */ - u32 ppll_div_3; - u32 ppll_ref_div; - u32 vclk_ecp_cntl; - u32 clk_cntl_index; - - /* Computed values for PLL2 */ - u32 dot_clock_freq_2; - int feedback_div_2; - int post_div_2; - - /* PLL2 registers */ - u32 p2pll_ref_div; - u32 p2pll_div_0; - u32 htotal_cntl2; - - /* Palette */ - int palette_valid; -}; - -static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr) -{ - u32 data; - - OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); - /* radeon_pll_errata_after_index(rinfo); */ - data = INREG(CLOCK_CNTL_DATA); - /* radeon_pll_errata_after_data(rinfo); */ - return data; -} - -static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, - u32 val) -{ - - OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080); - /* radeon_pll_errata_after_index(rinfo); */ - OUTREG(CLOCK_CNTL_DATA, val); - /* radeon_pll_errata_after_data(rinfo); */ -} - -static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index, - u32 val, u32 mask) -{ - unsigned int tmp; - - tmp = __INPLL(rinfo, index); - tmp &= (mask); - tmp |= (val); - __OUTPLL(rinfo, index, tmp); -} - -#define INPLL(addr) __INPLL(rinfo, addr) -#define OUTPLL(index, val) __OUTPLL(rinfo, index, val) -#define OUTPLLP(index, val, mask) __OUTPLLP(rinfo, index, val, mask) - -#endif diff --git a/drivers/cfb_console.c b/drivers/cfb_console.c deleted file mode 100644 index bcf8771..0000000 --- a/drivers/cfb_console.c +++ /dev/null @@ -1,1274 +0,0 @@ -/* - * (C) Copyright 2002 ELTEC Elektronik AG - * Frank Gottschling - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * cfb_console.c - * - * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel. - * - * At the moment only the 8x16 font is tested and the font fore- and - * background color is limited to black/white/gray colors. The Linux - * logo can be placed in the upper left corner and additional board - * information strings (that normaly goes to serial port) can be drawed. - * - * The console driver can use the standard PC keyboard interface (i8042) - * for character input. Character output goes to a memory mapped video - * framebuffer with little or big-endian organisation. - * With environment setting 'console=serial' the console i/o can be - * forced to serial port. - - The driver uses graphic specific defines/parameters/functions: - - (for SMI LynxE graphic chip) - - CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810 - VIDEO_FB_LITTLE_ENDIAN - framebuffer organisation default: big endian - VIDEO_HW_RECTFILL - graphic driver supports hardware rectangle fill - VIDEO_HW_BITBLT - graphic driver supports hardware bit blt - - Console Parameters are set by graphic drivers global struct: - - VIDEO_VISIBLE_COLS - x resolution - VIDEO_VISIBLE_ROWS - y resolution - VIDEO_PIXEL_SIZE - storage size in byte per pixel - VIDEO_DATA_FORMAT - graphical data format GDF - VIDEO_FB_ADRS - start of video memory - - CONFIG_I8042_KBD - AT Keyboard driver for i8042 - VIDEO_KBD_INIT_FCT - init function for keyboard - VIDEO_TSTC_FCT - keyboard_tstc function - VIDEO_GETC_FCT - keyboard_getc function - - CONFIG_CONSOLE_CURSOR - on/off drawing cursor is done with delay - loop in VIDEO_TSTC_FCT (i8042) - CFG_CONSOLE_BLINK_COUNT - value for delay loop - blink rate - CONFIG_CONSOLE_TIME - display time/date in upper right corner, - needs CONFIG_CMD_DATE and CONFIG_CONSOLE_CURSOR - CONFIG_VIDEO_LOGO - display Linux Logo in upper left corner - CONFIG_VIDEO_BMP_LOGO - use bmp_logo instead of linux_logo - CONFIG_CONSOLE_EXTRA_INFO - display additional board information strings - that normaly goes to serial port. This define - requires a board specific function: - video_drawstring (VIDEO_INFO_X, - VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT, - info); - that fills a info buffer at i=row. - s.a: board/eltec/bab7xx. -CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be initialised - as an output only device. The Keyboard driver - will not be set-up. This may be used, if you - have none or more than one Keyboard devices - (USB Keyboard, AT Keyboard). - -CONFIG_VIDEO_SW_CURSOR: - Draws a cursor after the last character. No - blinking is provided. Uses the macros CURSOR_SET - and CURSOR_OFF. -CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the - graphic chip. Uses the macro CURSOR_SET. - ATTENTION: If booting an OS, the display driver - must disable the hardware register of the graphic - chip. Otherwise a blinking field is displayed -*/ - -#include - -#ifdef CONFIG_CFB_CONSOLE - -#include - -/*****************************************************************************/ -/* Console device defines with SMI graphic */ -/* Any other graphic must change this section */ -/*****************************************************************************/ - -#ifdef CONFIG_VIDEO_SMI_LYNXEM - -#define VIDEO_FB_LITTLE_ENDIAN -#define VIDEO_HW_RECTFILL -#define VIDEO_HW_BITBLT -#endif - -/*****************************************************************************/ -/* Defines for the CT69000 driver */ -/*****************************************************************************/ -#ifdef CONFIG_VIDEO_CT69000 - -#define VIDEO_FB_LITTLE_ENDIAN -#define VIDEO_HW_RECTFILL -#define VIDEO_HW_BITBLT -#endif - -/*****************************************************************************/ -/* Defines for the SED13806 driver */ -/*****************************************************************************/ -#ifdef CONFIG_VIDEO_SED13806 - -#ifndef CONFIG_TOTAL5200 -#define VIDEO_FB_LITTLE_ENDIAN -#endif -#define VIDEO_HW_RECTFILL -#define VIDEO_HW_BITBLT -#endif - -/*****************************************************************************/ -/* Defines for the SED13806 driver */ -/*****************************************************************************/ -#ifdef CONFIG_VIDEO_SM501 - -#ifdef CONFIG_HH405 -#define VIDEO_FB_LITTLE_ENDIAN -#endif -#endif - -/*****************************************************************************/ -/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc */ -/*****************************************************************************/ -#include - -/*****************************************************************************/ -/* some Macros */ -/*****************************************************************************/ -#define VIDEO_VISIBLE_COLS (pGD->winSizeX) -#define VIDEO_VISIBLE_ROWS (pGD->winSizeY) -#define VIDEO_PIXEL_SIZE (pGD->gdfBytesPP) -#define VIDEO_DATA_FORMAT (pGD->gdfIndex) -#define VIDEO_FB_ADRS (pGD->frameAdrs) - -/*****************************************************************************/ -/* Console device defines with i8042 keyboard controller */ -/* Any other keyboard controller must change this section */ -/*****************************************************************************/ - -#ifdef CONFIG_I8042_KBD -#include - -#define VIDEO_KBD_INIT_FCT i8042_kbd_init() -#define VIDEO_TSTC_FCT i8042_tstc -#define VIDEO_GETC_FCT i8042_getc -#endif - -/*****************************************************************************/ -/* Console device */ -/*****************************************************************************/ - -#include -#include -#include -#include - -#if defined(CONFIG_CMD_DATE) -#include -#endif - -#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) -#include -#include -#endif - -/*****************************************************************************/ -/* Cursor definition: */ -/* CONFIG_CONSOLE_CURSOR: Uses a timer function (see drivers/i8042.c) to */ -/* let the cursor blink. Uses the macros CURSOR_OFF */ -/* and CURSOR_ON. */ -/* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No */ -/* blinking is provided. Uses the macros CURSOR_SET */ -/* and CURSOR_OFF. */ -/* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the */ -/* graphic chip. Uses the macro CURSOR_SET. */ -/* ATTENTION: If booting an OS, the display driver */ -/* must disable the hardware register of the graphic */ -/* chip. Otherwise a blinking field is displayed */ -/*****************************************************************************/ -#if !defined(CONFIG_CONSOLE_CURSOR) && \ - !defined(CONFIG_VIDEO_SW_CURSOR) && \ - !defined(CONFIG_VIDEO_HW_CURSOR) -/* no Cursor defined */ -#define CURSOR_ON -#define CURSOR_OFF -#define CURSOR_SET -#endif - -#ifdef CONFIG_CONSOLE_CURSOR -#ifdef CURSOR_ON -#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined -#endif -void console_cursor (int state); -#define CURSOR_ON console_cursor(1); -#define CURSOR_OFF console_cursor(0); -#define CURSOR_SET -#ifndef CONFIG_I8042_KBD -#warning Cursor drawing on/off needs timer function s.a. drivers/i8042.c -#endif -#else -#ifdef CONFIG_CONSOLE_TIME -#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME -#endif -#endif /* CONFIG_CONSOLE_CURSOR */ - -#ifdef CONFIG_VIDEO_SW_CURSOR -#ifdef CURSOR_ON -#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined -#endif -#define CURSOR_ON -#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\ - console_row * VIDEO_FONT_HEIGHT, ' '); -#define CURSOR_SET video_set_cursor(); -#endif /* CONFIG_VIDEO_SW_CURSOR */ - - -#ifdef CONFIG_VIDEO_HW_CURSOR -#ifdef CURSOR_ON -#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined -#endif -#define CURSOR_ON -#define CURSOR_OFF -#define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \ - (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT); -#endif /* CONFIG_VIDEO_HW_CURSOR */ - -#ifdef CONFIG_VIDEO_LOGO -#ifdef CONFIG_VIDEO_BMP_LOGO -#include -#define VIDEO_LOGO_WIDTH BMP_LOGO_WIDTH -#define VIDEO_LOGO_HEIGHT BMP_LOGO_HEIGHT -#define VIDEO_LOGO_LUT_OFFSET BMP_LOGO_OFFSET -#define VIDEO_LOGO_COLORS BMP_LOGO_COLORS - -#else /* CONFIG_VIDEO_BMP_LOGO */ -#define LINUX_LOGO_WIDTH 80 -#define LINUX_LOGO_HEIGHT 80 -#define LINUX_LOGO_COLORS 214 -#define LINUX_LOGO_LUT_OFFSET 0x20 -#define __initdata -#include -#define VIDEO_LOGO_WIDTH LINUX_LOGO_WIDTH -#define VIDEO_LOGO_HEIGHT LINUX_LOGO_HEIGHT -#define VIDEO_LOGO_LUT_OFFSET LINUX_LOGO_LUT_OFFSET -#define VIDEO_LOGO_COLORS LINUX_LOGO_COLORS -#endif /* CONFIG_VIDEO_BMP_LOGO */ -#define VIDEO_INFO_X (VIDEO_LOGO_WIDTH) -#define VIDEO_INFO_Y (VIDEO_FONT_HEIGHT/2) -#else /* CONFIG_VIDEO_LOGO */ -#define VIDEO_LOGO_WIDTH 0 -#define VIDEO_LOGO_HEIGHT 0 -#endif /* CONFIG_VIDEO_LOGO */ - -#define VIDEO_COLS VIDEO_VISIBLE_COLS -#define VIDEO_ROWS VIDEO_VISIBLE_ROWS -#define VIDEO_SIZE (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE) -#define VIDEO_PIX_BLOCKS (VIDEO_SIZE >> 2) -#define VIDEO_LINE_LEN (VIDEO_COLS*VIDEO_PIXEL_SIZE) -#define VIDEO_BURST_LEN (VIDEO_COLS/8) - -#ifdef CONFIG_VIDEO_LOGO -#define CONSOLE_ROWS ((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT) -#else -#define CONSOLE_ROWS (VIDEO_ROWS / VIDEO_FONT_HEIGHT) -#endif - -#define CONSOLE_COLS (VIDEO_COLS / VIDEO_FONT_WIDTH) -#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN) -#define CONSOLE_ROW_FIRST (video_console_address) -#define CONSOLE_ROW_SECOND (video_console_address + CONSOLE_ROW_SIZE) -#define CONSOLE_ROW_LAST (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE) -#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS) -#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE) - -/* Macros */ -#ifdef VIDEO_FB_LITTLE_ENDIAN -#define SWAP16(x) ((((x) & 0x00ff) << 8) | ( (x) >> 8)) -#define SWAP32(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\ - (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) ) -#define SHORTSWAP32(x) ((((x) & 0x000000ff) << 8) | (((x) & 0x0000ff00) >> 8)|\ - (((x) & 0x00ff0000) << 8) | (((x) & 0xff000000) >> 8) ) -#else -#define SWAP16(x) (x) -#define SWAP32(x) (x) -#define SHORTSWAP32(x) (x) -#endif - -#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE) -#define PRINTD(x) printf(x) -#else -#define PRINTD(x) -#endif - - -#ifdef CONFIG_CONSOLE_EXTRA_INFO -extern void video_get_info_str ( /* setup a board string: type, speed, etc. */ - int line_number, /* location to place info string beside logo */ - char *info /* buffer for info string */ - ); - -#endif - -/* Locals */ -static GraphicDevice *pGD; /* Pointer to Graphic array */ - -static void *video_fb_address; /* frame buffer address */ -static void *video_console_address; /* console buffer start address */ - -static int console_col = 0; /* cursor col */ -static int console_row = 0; /* cursor row */ - -static u32 eorx, fgx, bgx; /* color pats */ - -static const int video_font_draw_table8[] = { - 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, - 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, - 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, - 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff }; - -static const int video_font_draw_table15[] = { - 0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff }; - -static const int video_font_draw_table16[] = { - 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff }; - -static const int video_font_draw_table24[16][3] = { - { 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00ffffff }, - { 0x00000000, 0x0000ffff, 0xff000000 }, - { 0x00000000, 0x0000ffff, 0xffffffff }, - { 0x000000ff, 0xffff0000, 0x00000000 }, - { 0x000000ff, 0xffff0000, 0x00ffffff }, - { 0x000000ff, 0xffffffff, 0xff000000 }, - { 0x000000ff, 0xffffffff, 0xffffffff }, - { 0xffffff00, 0x00000000, 0x00000000 }, - { 0xffffff00, 0x00000000, 0x00ffffff }, - { 0xffffff00, 0x0000ffff, 0xff000000 }, - { 0xffffff00, 0x0000ffff, 0xffffffff }, - { 0xffffffff, 0xffff0000, 0x00000000 }, - { 0xffffffff, 0xffff0000, 0x00ffffff }, - { 0xffffffff, 0xffffffff, 0xff000000 }, - { 0xffffffff, 0xffffffff, 0xffffffff } }; - -static const int video_font_draw_table32[16][4] = { - { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff }, - { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 }, - { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff }, - { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 }, - { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff }, - { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 }, - { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff }, - { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 }, - { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff }, - { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 }, - { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff }, - { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 }, - { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff }, - { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 }, - { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } }; - - -int gunzip(void *, int, unsigned char *, unsigned long *); - -/******************************************************************************/ - -static void video_drawchars (int xx, int yy, unsigned char *s, int count) -{ - u8 *cdat, *dest, *dest0; - int rows, offset, c; - - offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE; - dest0 = video_fb_address + offset; - - switch (VIDEO_DATA_FORMAT) { - case GDF__8BIT_INDEX: - case GDF__8BIT_332RGB: - while (count--) { - c = *s; - cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; - for (rows = VIDEO_FONT_HEIGHT, dest = dest0; - rows--; - dest += VIDEO_LINE_LEN) { - u8 bits = *cdat++; - - ((u32 *) dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx; - ((u32 *) dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx; - } - dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; - s++; - } - break; - - case GDF_15BIT_555RGB: - while (count--) { - c = *s; - cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; - for (rows = VIDEO_FONT_HEIGHT, dest = dest0; - rows--; - dest += VIDEO_LINE_LEN) { - u8 bits = *cdat++; - - ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 6] & eorx) ^ bgx); - ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 4 & 3] & eorx) ^ bgx); - ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 2 & 3] & eorx) ^ bgx); - ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table15 [bits & 3] & eorx) ^ bgx); - } - dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; - s++; - } - break; - - case GDF_16BIT_565RGB: - while (count--) { - c = *s; - cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; - for (rows = VIDEO_FONT_HEIGHT, dest = dest0; - rows--; - dest += VIDEO_LINE_LEN) { - u8 bits = *cdat++; - - ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 6] & eorx) ^ bgx); - ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 4 & 3] & eorx) ^ bgx); - ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 2 & 3] & eorx) ^ bgx); - ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table16 [bits & 3] & eorx) ^ bgx); - } - dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; - s++; - } - break; - - case GDF_32BIT_X888RGB: - while (count--) { - c = *s; - cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; - for (rows = VIDEO_FONT_HEIGHT, dest = dest0; - rows--; - dest += VIDEO_LINE_LEN) { - u8 bits = *cdat++; - - ((u32 *) dest)[0] = SWAP32 ((video_font_draw_table32 [bits >> 4][0] & eorx) ^ bgx); - ((u32 *) dest)[1] = SWAP32 ((video_font_draw_table32 [bits >> 4][1] & eorx) ^ bgx); - ((u32 *) dest)[2] = SWAP32 ((video_font_draw_table32 [bits >> 4][2] & eorx) ^ bgx); - ((u32 *) dest)[3] = SWAP32 ((video_font_draw_table32 [bits >> 4][3] & eorx) ^ bgx); - ((u32 *) dest)[4] = SWAP32 ((video_font_draw_table32 [bits & 15][0] & eorx) ^ bgx); - ((u32 *) dest)[5] = SWAP32 ((video_font_draw_table32 [bits & 15][1] & eorx) ^ bgx); - ((u32 *) dest)[6] = SWAP32 ((video_font_draw_table32 [bits & 15][2] & eorx) ^ bgx); - ((u32 *) dest)[7] = SWAP32 ((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx); - } - dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; - s++; - } - break; - - case GDF_24BIT_888RGB: - while (count--) { - c = *s; - cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; - for (rows = VIDEO_FONT_HEIGHT, dest = dest0; - rows--; - dest += VIDEO_LINE_LEN) { - u8 bits = *cdat++; - - ((u32 *) dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx; - ((u32 *) dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx; - ((u32 *) dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx; - ((u32 *) dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx; - ((u32 *) dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx; - ((u32 *) dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx; - } - dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; - s++; - } - break; - } -} - -/*****************************************************************************/ - -static inline void video_drawstring (int xx, int yy, unsigned char *s) -{ - video_drawchars (xx, yy, s, strlen ((char *)s)); -} - -/*****************************************************************************/ - -static void video_putchar (int xx, int yy, unsigned char c) -{ - video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1); -} - -/*****************************************************************************/ -#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR) -static void video_set_cursor (void) -{ - /* swap drawing colors */ - eorx = fgx; - fgx = bgx; - bgx = eorx; - eorx = fgx ^ bgx; - /* draw cursor */ - video_putchar (console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, - ' '); - /* restore drawing colors */ - eorx = fgx; - fgx = bgx; - bgx = eorx; - eorx = fgx ^ bgx; -} -#endif -/*****************************************************************************/ -#ifdef CONFIG_CONSOLE_CURSOR -void console_cursor (int state) -{ - static int last_state = 0; - -#ifdef CONFIG_CONSOLE_TIME - struct rtc_time tm; - char info[16]; - - /* time update only if cursor is on (faster scroll) */ - if (state) { - rtc_get (&tm); - - sprintf (info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min, - tm.tm_sec); - video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH, - VIDEO_INFO_Y, (uchar *)info); - - sprintf (info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon, - tm.tm_year); - video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH, - VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT, (uchar *)info); - } -#endif - - if (state && (last_state != state)) { - video_set_cursor (); - } - - if (!state && (last_state != state)) { - /* clear cursor */ - video_putchar (console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, - ' '); - } - - last_state = state; -} -#endif - -/*****************************************************************************/ - -#ifndef VIDEO_HW_RECTFILL -static void memsetl (int *p, int c, int v) -{ - while (c--) - *(p++) = v; -} -#endif - -/*****************************************************************************/ - -#ifndef VIDEO_HW_BITBLT -static void memcpyl (int *d, int *s, int c) -{ - while (c--) - *(d++) = *(s++); -} -#endif - -/*****************************************************************************/ - -static void console_scrollup (void) -{ - /* copy up rows ignoring the first one */ - -#ifdef VIDEO_HW_BITBLT - video_hw_bitblt (VIDEO_PIXEL_SIZE, /* bytes per pixel */ - 0, /* source pos x */ - VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */ - 0, /* dest pos x */ - VIDEO_LOGO_HEIGHT, /* dest pos y */ - VIDEO_VISIBLE_COLS, /* frame width */ - VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT /* frame height */ - ); -#else - memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, - CONSOLE_SCROLL_SIZE >> 2); -#endif - - /* clear the last one */ -#ifdef VIDEO_HW_RECTFILL - video_hw_rectfill (VIDEO_PIXEL_SIZE, /* bytes per pixel */ - 0, /* dest pos x */ - VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT, /* dest pos y */ - VIDEO_VISIBLE_COLS, /* frame width */ - VIDEO_FONT_HEIGHT, /* frame height */ - CONSOLE_BG_COL /* fill color */ - ); -#else - memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL); -#endif -} - -/*****************************************************************************/ - -static void console_back (void) -{ - CURSOR_OFF console_col--; - - if (console_col < 0) { - console_col = CONSOLE_COLS - 1; - console_row--; - if (console_row < 0) - console_row = 0; - } - video_putchar (console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, - ' '); -} - -/*****************************************************************************/ - -static void console_newline (void) -{ - CURSOR_OFF console_row++; - console_col = 0; - - /* Check if we need to scroll the terminal */ - if (console_row >= CONSOLE_ROWS) { - /* Scroll everything up */ - console_scrollup (); - - /* Decrement row number */ - console_row--; - } -} - -/*****************************************************************************/ - -void video_putc (const char c) -{ - switch (c) { - case 13: /* ignore */ - break; - - case '\n': /* next line */ - console_newline (); - break; - - case 9: /* tab 8 */ - CURSOR_OFF console_col |= 0x0008; - console_col &= ~0x0007; - - if (console_col >= CONSOLE_COLS) - console_newline (); - break; - - case 8: /* backspace */ - console_back (); - break; - - default: /* draw the char */ - video_putchar (console_col * VIDEO_FONT_WIDTH, - console_row * VIDEO_FONT_HEIGHT, - c); - console_col++; - - /* check for newline */ - if (console_col >= CONSOLE_COLS) - console_newline (); - } -CURSOR_SET} - - -/*****************************************************************************/ - -void video_puts (const char *s) -{ - int count = strlen (s); - - while (count--) - video_putc (*s++); -} - -/*****************************************************************************/ - -#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) - -#define FILL_8BIT_332RGB(r,g,b) { \ - *fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6); \ - fb ++; \ -} - -#define FILL_15BIT_555RGB(r,g,b) { \ - *(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \ - fb += 2; \ -} - -#define FILL_16BIT_565RGB(r,g,b) { \ - *(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \ - fb += 2; \ -} - -#define FILL_32BIT_X888RGB(r,g,b) { \ - *(unsigned long *)fb = SWAP32((unsigned long)(((r<<16) | (g<<8) | b))); \ - fb += 4; \ -} - -#ifdef VIDEO_FB_LITTLE_ENDIAN -#define FILL_24BIT_888RGB(r,g,b) { \ - fb[0] = b; \ - fb[1] = g; \ - fb[2] = r; \ - fb += 3; \ -} -#else -#define FILL_24BIT_888RGB(r,g,b) { \ - fb[0] = r; \ - fb[1] = g; \ - fb[2] = b; \ - fb += 3; \ -} -#endif - - -/* - * Display the BMP file located at address bmp_image. - * Only uncompressed - */ -int video_display_bitmap (ulong bmp_image, int x, int y) -{ - ushort xcount, ycount; - uchar *fb; - bmp_image_t *bmp = (bmp_image_t *) bmp_image; - uchar *bmap; - ushort padded_line; - unsigned long width, height, bpp; - unsigned colors; - unsigned long compression; - bmp_color_table_entry_t cte; -#ifdef CONFIG_VIDEO_BMP_GZIP - unsigned char *dst = NULL; - ulong len; -#endif - - WATCHDOG_RESET (); - - if (!((bmp->header.signature[0] == 'B') && - (bmp->header.signature[1] == 'M'))) { - -#ifdef CONFIG_VIDEO_BMP_GZIP - /* - * Could be a gzipped bmp image, try to decrompress... - */ - len = CFG_VIDEO_LOGO_MAX_SIZE; - dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE); - if (dst == NULL) { - printf("Error: malloc in gunzip failed!\n"); - return(1); - } - if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) { - printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image); - free(dst); - return 1; - } - if (len == CFG_VIDEO_LOGO_MAX_SIZE) { - printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n"); - } - - /* - * Set addr to decompressed image - */ - bmp = (bmp_image_t *)dst; - - if (!((bmp->header.signature[0] == 'B') && - (bmp->header.signature[1] == 'M'))) { - printf ("Error: no valid bmp.gz image at %lx\n", bmp_image); - return 1; - } -#else - printf ("Error: no valid bmp image at %lx\n", bmp_image); - return 1; -#endif /* CONFIG_VIDEO_BMP_GZIP */ - } - - width = le32_to_cpu (bmp->header.width); - height = le32_to_cpu (bmp->header.height); - bpp = le16_to_cpu (bmp->header.bit_count); - colors = le32_to_cpu (bmp->header.colors_used); - compression = le32_to_cpu (bmp->header.compression); - - debug ("Display-bmp: %d x %d with %d colors\n", - width, height, colors); - - if (compression != BMP_BI_RGB) { - printf ("Error: compression type %ld not supported\n", - compression); - return 1; - } - - padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3; - - if ((x + width) > VIDEO_VISIBLE_COLS) - width = VIDEO_VISIBLE_COLS - x; - if ((y + height) > VIDEO_VISIBLE_ROWS) - height = VIDEO_VISIBLE_ROWS - y; - - bmap = (uchar *) bmp + le32_to_cpu (bmp->header.data_offset); - fb = (uchar *) (video_fb_address + - ((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) + - x * VIDEO_PIXEL_SIZE); - - /* We handle only 8bpp or 24 bpp bitmap */ - switch (le16_to_cpu (bmp->header.bit_count)) { - case 8: - padded_line -= width; - if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) { - /* Copy colormap */ - for (xcount = 0; xcount < colors; ++xcount) { - cte = bmp->color_table[xcount]; - video_set_lut (xcount, cte.red, cte.green, cte.blue); - } - } - ycount = height; - switch (VIDEO_DATA_FORMAT) { - case GDF__8BIT_INDEX: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - *fb++ = *bmap++; - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF__8BIT_332RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - cte = bmp->color_table[*bmap++]; - FILL_8BIT_332RGB (cte.red, cte.green, cte.blue); - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF_15BIT_555RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - cte = bmp->color_table[*bmap++]; - FILL_15BIT_555RGB (cte.red, cte.green, cte.blue); - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF_16BIT_565RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - cte = bmp->color_table[*bmap++]; - FILL_16BIT_565RGB (cte.red, cte.green, cte.blue); - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF_32BIT_X888RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - cte = bmp->color_table[*bmap++]; - FILL_32BIT_X888RGB (cte.red, cte.green, cte.blue); - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF_24BIT_888RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - cte = bmp->color_table[*bmap++]; - FILL_24BIT_888RGB (cte.red, cte.green, cte.blue); - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - } - break; - case 24: - padded_line -= 3 * width; - ycount = height; - switch (VIDEO_DATA_FORMAT) { - case GDF__8BIT_332RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - FILL_8BIT_332RGB (bmap[2], bmap[1], bmap[0]); - bmap += 3; - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF_15BIT_555RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]); - bmap += 3; - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF_16BIT_565RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - FILL_16BIT_565RGB (bmap[2], bmap[1], bmap[0]); - bmap += 3; - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF_32BIT_X888RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - FILL_32BIT_X888RGB (bmap[2], bmap[1], bmap[0]); - bmap += 3; - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - case GDF_24BIT_888RGB: - while (ycount--) { - WATCHDOG_RESET (); - xcount = width; - while (xcount--) { - FILL_24BIT_888RGB (bmap[2], bmap[1], bmap[0]); - bmap += 3; - } - bmap += padded_line; - fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; - } - break; - default: - printf ("Error: 24 bits/pixel bitmap incompatible with current video mode\n"); - break; - } - break; - default: - printf ("Error: %d bit/pixel bitmaps not supported by U-Boot\n", - le16_to_cpu (bmp->header.bit_count)); - break; - } - -#ifdef CONFIG_VIDEO_BMP_GZIP - if (dst) { - free(dst); - } -#endif - - return (0); -} -#endif - -/*****************************************************************************/ - -#ifdef CONFIG_VIDEO_LOGO -void logo_plot (void *screen, int width, int x, int y) -{ - - int xcount, i; - int skip = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE; - int ycount = VIDEO_LOGO_HEIGHT; - unsigned char r, g, b, *logo_red, *logo_blue, *logo_green; - unsigned char *source; - unsigned char *dest = (unsigned char *)screen + ((y * width * VIDEO_PIXEL_SIZE) + x); - -#ifdef CONFIG_VIDEO_BMP_LOGO - source = bmp_logo_bitmap; - - /* Allocate temporary space for computing colormap */ - logo_red = malloc (BMP_LOGO_COLORS); - logo_green = malloc (BMP_LOGO_COLORS); - logo_blue = malloc (BMP_LOGO_COLORS); - /* Compute color map */ - for (i = 0; i < VIDEO_LOGO_COLORS; i++) { - logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4; - logo_green[i] = (bmp_logo_palette[i] & 0x00f0); - logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4; - } -#else - source = linux_logo; - logo_red = linux_logo_red; - logo_green = linux_logo_green; - logo_blue = linux_logo_blue; -#endif - - if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) { - for (i = 0; i < VIDEO_LOGO_COLORS; i++) { - video_set_lut (i + VIDEO_LOGO_LUT_OFFSET, - logo_red[i], logo_green[i], logo_blue[i]); - } - } - - while (ycount--) { - xcount = VIDEO_LOGO_WIDTH; - while (xcount--) { - r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET]; - g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET]; - b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET]; - - switch (VIDEO_DATA_FORMAT) { - case GDF__8BIT_INDEX: - *dest = *source; - break; - case GDF__8BIT_332RGB: - *dest = ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6); - break; - case GDF_15BIT_555RGB: - *(unsigned short *) dest = - SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3))); - break; - case GDF_16BIT_565RGB: - *(unsigned short *) dest = - SWAP16 ((unsigned short) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3))); - break; - case GDF_32BIT_X888RGB: - *(unsigned long *) dest = - SWAP32 ((unsigned long) ((r << 16) | (g << 8) | b)); - break; - case GDF_24BIT_888RGB: -#ifdef VIDEO_FB_LITTLE_ENDIAN - dest[0] = b; - dest[1] = g; - dest[2] = r; -#else - dest[0] = r; - dest[1] = g; - dest[2] = b; -#endif - break; - } - source++; - dest += VIDEO_PIXEL_SIZE; - } - dest += skip; - } -#ifdef CONFIG_VIDEO_BMP_LOGO - free (logo_red); - free (logo_green); - free (logo_blue); -#endif -} - -/*****************************************************************************/ - -static void *video_logo (void) -{ - char info[128]; - extern char version_string; - -#ifdef CONFIG_SPLASH_SCREEN - char *s; - ulong addr; - - if ((s = getenv ("splashimage")) != NULL) { - addr = simple_strtoul (s, NULL, 16); - - if (video_display_bitmap (addr, 0, 0) == 0) { - return ((void *) (video_fb_address)); - } - } -#endif /* CONFIG_SPLASH_SCREEN */ - - logo_plot (video_fb_address, VIDEO_COLS, 0, 0); - - sprintf (info, " %s", &version_string); - video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *)info); - -#ifdef CONFIG_CONSOLE_EXTRA_INFO - { - int i, n = ((VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT); - - for (i = 1; i < n; i++) { - video_get_info_str (i, info); - if (*info) - video_drawstring (VIDEO_INFO_X, - VIDEO_INFO_Y + i * VIDEO_FONT_HEIGHT, - (uchar *)info); - } - } -#endif - - return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN); -} -#endif - - -/*****************************************************************************/ - -static int video_init (void) -{ - unsigned char color8; - - if ((pGD = video_hw_init ()) == NULL) - return -1; - - video_fb_address = (void *) VIDEO_FB_ADRS; -#ifdef CONFIG_VIDEO_HW_CURSOR - video_init_hw_cursor (VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT); -#endif - - /* Init drawing pats */ - switch (VIDEO_DATA_FORMAT) { - case GDF__8BIT_INDEX: - video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL); - video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL); - fgx = 0x01010101; - bgx = 0x00000000; - break; - case GDF__8BIT_332RGB: - color8 = ((CONSOLE_FG_COL & 0xe0) | - ((CONSOLE_FG_COL >> 3) & 0x1c) | CONSOLE_FG_COL >> 6); - fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8; - color8 = ((CONSOLE_BG_COL & 0xe0) | - ((CONSOLE_BG_COL >> 3) & 0x1c) | CONSOLE_BG_COL >> 6); - bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8; - break; - case GDF_15BIT_555RGB: - fgx = (((CONSOLE_FG_COL >> 3) << 26) | - ((CONSOLE_FG_COL >> 3) << 21) | ((CONSOLE_FG_COL >> 3) << 16) | - ((CONSOLE_FG_COL >> 3) << 10) | ((CONSOLE_FG_COL >> 3) << 5) | - (CONSOLE_FG_COL >> 3)); - bgx = (((CONSOLE_BG_COL >> 3) << 26) | - ((CONSOLE_BG_COL >> 3) << 21) | ((CONSOLE_BG_COL >> 3) << 16) | - ((CONSOLE_BG_COL >> 3) << 10) | ((CONSOLE_BG_COL >> 3) << 5) | - (CONSOLE_BG_COL >> 3)); - break; - case GDF_16BIT_565RGB: - fgx = (((CONSOLE_FG_COL >> 3) << 27) | - ((CONSOLE_FG_COL >> 2) << 21) | ((CONSOLE_FG_COL >> 3) << 16) | - ((CONSOLE_FG_COL >> 3) << 11) | ((CONSOLE_FG_COL >> 2) << 5) | - (CONSOLE_FG_COL >> 3)); - bgx = (((CONSOLE_BG_COL >> 3) << 27) | - ((CONSOLE_BG_COL >> 2) << 21) | ((CONSOLE_BG_COL >> 3) << 16) | - ((CONSOLE_BG_COL >> 3) << 11) | ((CONSOLE_BG_COL >> 2) << 5) | - (CONSOLE_BG_COL >> 3)); - break; - case GDF_32BIT_X888RGB: - fgx = (CONSOLE_FG_COL << 16) | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL; - bgx = (CONSOLE_BG_COL << 16) | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL; - break; - case GDF_24BIT_888RGB: - fgx = (CONSOLE_FG_COL << 24) | (CONSOLE_FG_COL << 16) | - (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL; - bgx = (CONSOLE_BG_COL << 24) | (CONSOLE_BG_COL << 16) | - (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL; - break; - } - eorx = fgx ^ bgx; - -#ifdef CONFIG_VIDEO_LOGO - /* Plot the logo and get start point of console */ - PRINTD ("Video: Drawing the logo ...\n"); - video_console_address = video_logo (); -#else - video_console_address = video_fb_address; -#endif - - /* Initialize the console */ - console_col = 0; - console_row = 0; - - return 0; -} - - -/*****************************************************************************/ - -int drv_video_init (void) -{ - int skip_dev_init; - device_t console_dev; - - skip_dev_init = 0; - - /* Init video chip - returns with framebuffer cleared */ - if (video_init () == -1) - skip_dev_init = 1; - -#ifdef CONFIG_VGA_AS_SINGLE_DEVICE - /* Devices VGA and Keyboard will be assigned seperately */ - /* Init vga device */ - if (!skip_dev_init) { - memset (&console_dev, 0, sizeof (console_dev)); - strcpy (console_dev.name, "vga"); - console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */ - console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; - console_dev.putc = video_putc; /* 'putc' function */ - console_dev.puts = video_puts; /* 'puts' function */ - console_dev.tstc = NULL; /* 'tstc' function */ - console_dev.getc = NULL; /* 'getc' function */ - - if (device_register (&console_dev) == 0) - return 1; - } -#else - PRINTD ("KBD: Keyboard init ...\n"); - if (VIDEO_KBD_INIT_FCT == -1) - skip_dev_init = 1; - - /* Init console device */ - if (!skip_dev_init) { - memset (&console_dev, 0, sizeof (console_dev)); - strcpy (console_dev.name, "vga"); - console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */ - console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; - console_dev.putc = video_putc; /* 'putc' function */ - console_dev.puts = video_puts; /* 'puts' function */ - console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */ - console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */ - - if (device_register (&console_dev) == 0) - return 1; - } -#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */ - /* No console dev available */ - return 0; -} -#endif /* CONFIG_CFB_CONSOLE */ diff --git a/drivers/ct69000.c b/drivers/ct69000.c deleted file mode 100644 index 29d82e4..0000000 --- a/drivers/ct69000.c +++ /dev/null @@ -1,1286 +0,0 @@ -/* ported from ctfb.c (linux kernel): - * Created in Jan - July 2000 by Thomas Höhenleitner - * - * Ported to U-Boot: - * (C) Copyright 2002 Denis Peter, MPL AG Switzerland - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include - -#ifdef CONFIG_VIDEO - -#include -#include -#include "videomodes.h" - -#ifdef CONFIG_VIDEO_CT69000 - -/* debug */ -#undef VGA_DEBUG -#undef VGA_DUMP_REG -#ifdef VGA_DEBUG -#define PRINTF(fmt,args...) printf (fmt ,##args) -#else -#define PRINTF(fmt,args...) -#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}, -#ifdef CONFIG_USE_CPCIDVI - {PCI_DEVICE_ID_CT_69030, 0x400000, 1, 4, -2, 3, 257, 100, 220}, -#endif - {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(Dmn_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; - PRINTF ("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); - PRINTF ("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 - -#ifdef CONFIG_VIDEO_HW_CURSOR -/*************************************************************** - * Set Hardware Cursor in Pixel - */ -void -video_set_hw_cursor (int x, int y) -{ - int sig_x = 0, sig_y = 0; - if (x < 0) { - x *= -1; - sig_x = 1; - } - if (y < 0) { - y *= -1; - sig_y = 1; - } - ctWrite_i (CT_XR_O, 0xa4, x & 0xff); - ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7); - ctWrite_i (CT_XR_O, 0xa6, y & 0xff); - ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7); -} - -/*************************************************************** - * Init Hardware Cursor. To know the size of the Cursor, - * we have to know the Font size. - */ -void -video_init_hw_cursor (int font_width, int font_height) -{ - unsigned char xr_80; - unsigned long *curs, pattern; - int i; - int cursor_start; - GraphicDevice *pGD = (GraphicDevice *) & ctfb; - - cursor_start = pGD->dprBase; - xr_80 = ctRead_i (CT_XR_O, 0x80); - /* set start address */ - ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0); - ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f); - /* set cursor shape */ - curs = (unsigned long *) cursor_start; - i = 0; - while (i < 0x400) { - curs[i++] = 0xffffffff; /* AND mask */ - curs[i++] = 0xffffffff; /* AND mask */ - curs[i++] = 0; /* XOR mask */ - curs[i++] = 0; /* XOR mask */ - /* Transparent */ - } - pattern = 0xffffffff >> font_width; - i = 0; - while (i < (font_height * 2)) { - curs[i++] = pattern; /* AND mask */ - curs[i++] = pattern; /* AND mask */ - curs[i++] = 0; /* XOR mask */ - curs[i++] = 0; /* XOR mask */ - /* Cursor Color 0 */ - } - /* set blink rate */ - ctWrite_i (CT_FP_O, 0x19, 0xf); - - /* set cursors colors */ - xr_80 = ctRead_i (CT_XR_O, 0x80); - xr_80 |= 0x1; /* alternate palette select */ - ctWrite_i (CT_XR_O, 0x80, xr_80); - video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL); - /* position 4 is color 0 cursor 0 */ - xr_80 &= 0xfe; /* normal palette select */ - ctWrite_i (CT_XR_O, 0x80, xr_80); - /* cursor enable */ - ctWrite_i (CT_XR_O, 0xa0, 0x91); - xr_80 |= 0x10; /* enable hwcursor */ - ctWrite_i (CT_XR_O, 0x80, xr_80); - video_set_hw_cursor (0, 0); -} -#endif /* CONFIG_VIDEO_HW_CURSOR */ - -/*************************************************************** - * 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}, -#ifdef CONFIG_USE_CPCIDVI - {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030}, -#endif - {} -}; - -/******************************************************************************* -* -* 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 = CFG_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; - } - PRINTF ("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 */ - -#ifdef CONFIG_USE_CPCIDVI - if (device_id == PCI_DEVICE_ID_CT_69030) { - ctWrite (CT_MSR_W_O, 0x0b); - ctWrite (0x3cd, 0x13); - ctWrite_i (CT_FP_O, 0x02, 0x00); - ctWrite_i (CT_FP_O, 0x05, 0x00); - ctWrite_i (CT_FP_O, 0x06, 0x00); - ctWrite (0x3c2, 0x0b); - ctWrite_i (CT_FP_O, 0x02, 0x10); - ctWrite_i (CT_FP_O, 0x01, 0x09); - } else { - ctWrite (CT_MSR_W_O, 0x01); - } -#else - ctWrite (CT_MSR_W_O, 0x01); -#endif - - /* 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_CT69000 */ - -#endif /* CONFIG_VIDEO */ diff --git a/drivers/sed13806.c b/drivers/sed13806.c deleted file mode 100644 index 6996ca8..0000000 --- a/drivers/sed13806.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - - * Pierre AUBERT p.aubert@staubli.com - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ -/* Video support for Epson SED13806 chipset */ - -#include - -#ifdef CONFIG_VIDEO_SED13806 - -#include -#include - -#define readByte(ptrReg) \ - *(volatile unsigned char *)(sed13806.isaBase + ptrReg) - -#define writeByte(ptrReg,value) \ - *(volatile unsigned char *)(sed13806.isaBase + ptrReg) = value - -#ifdef CONFIG_TOTAL5200 -#define writeWord(ptrReg,value) \ - (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = value) -#else -#define writeWord(ptrReg,value) \ - (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = ((value >> 8 ) & 0xff) | ((value << 8) & 0xff00)) -#endif - -GraphicDevice sed13806; - -/*----------------------------------------------------------------------------- - * EpsonSetRegs -- - *----------------------------------------------------------------------------- - */ -static void EpsonSetRegs (void) -{ - /* the content of the chipset register depends on the board (clocks, ...)*/ - const S1D_REGS *preg = board_get_regs (); - while (preg -> Index) { - writeByte (preg -> Index, preg -> Value); - preg ++; - } -} - -/*----------------------------------------------------------------------------- - * video_hw_init -- - *----------------------------------------------------------------------------- - */ -void *video_hw_init (void) -{ - unsigned int *vm, i; - - memset (&sed13806, 0, sizeof (GraphicDevice)); - - /* Initialization of the access to the graphic chipset - Retreive base address of the chipset - (see board/RPXClassic/eccx.c) */ - if ((sed13806.isaBase = board_video_init ()) == 0) { - return (NULL); - } - - sed13806.frameAdrs = sed13806.isaBase + FRAME_BUFFER_OFFSET; - sed13806.winSizeX = board_get_width (); - sed13806.winSizeY = board_get_height (); - -#if defined(CONFIG_VIDEO_SED13806_8BPP) - sed13806.gdfIndex = GDF__8BIT_INDEX; - sed13806.gdfBytesPP = 1; - -#elif defined(CONFIG_VIDEO_SED13806_16BPP) - sed13806.gdfIndex = GDF_16BIT_565RGB; - sed13806.gdfBytesPP = 2; - -#else -#error Unsupported SED13806 BPP -#endif - - sed13806.memSize = sed13806.winSizeX * sed13806.winSizeY * sed13806.gdfBytesPP; - - /* Load SED registers */ - EpsonSetRegs (); - - /* (see board/RPXClassic/RPXClassic.c) */ - board_validate_screen (sed13806.isaBase); - - /* Clear video memory */ - i = sed13806.memSize/4; - vm = (unsigned int *)sed13806.frameAdrs; - while(i--) - *vm++ = 0; - - - return (&sed13806); -} -/*----------------------------------------------------------------------------- - * Epson_wait_idle -- Wait for hardware to become idle - *----------------------------------------------------------------------------- - */ -static void Epson_wait_idle (void) -{ - while (readByte (BLT_CTRL0) & 0x80); - - /* Read a word in the BitBLT memory area to shutdown the BitBLT engine */ - *(volatile unsigned short *)(sed13806.isaBase + BLT_REG); -} - -/*----------------------------------------------------------------------------- - * video_hw_bitblt -- - *----------------------------------------------------------------------------- - */ -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 */ - ) -{ - register GraphicDevice *pGD = (GraphicDevice *)&sed13806; - unsigned long srcAddr, dstAddr; - unsigned int stride = bpp * pGD -> winSizeX; - - srcAddr = (src_y * stride) + (src_x * bpp); - dstAddr = (dst_y * stride) + (dst_x * bpp); - - Epson_wait_idle (); - - writeByte(BLT_ROP,0x0C); /* source */ - writeByte(BLT_OP,0x02);/* move blit in positive direction with ROP */ - writeWord(BLT_MEM_OFF0, stride / 2); - if (pGD -> gdfIndex == GDF__8BIT_INDEX) { - writeByte(BLT_CTRL1,0x00); - } - else { - writeByte(BLT_CTRL1,0x01); - } - - writeWord(BLT_WIDTH0,(dim_x - 1)); - writeWord(BLT_HEIGHT0,(dim_y - 1)); - - /* set up blit registers */ - writeByte(BLT_SRC_ADDR0,srcAddr); - writeByte(BLT_SRC_ADDR1,srcAddr>>8); - writeByte(BLT_SRC_ADDR2,srcAddr>>16); - - writeByte(BLT_DST_ADDR0,dstAddr); - writeByte(BLT_DST_ADDR1,dstAddr>>8); - writeByte(BLT_DST_ADDR2,dstAddr>>16); - - /* Engage the blt engine */ - /* rectangular region for src and dst */ - writeByte(BLT_CTRL0,0x80); - - /* wait untill current blits finished */ - Epson_wait_idle (); -} -/*----------------------------------------------------------------------------- - * video_hw_rectfill -- - *----------------------------------------------------------------------------- - */ -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 */ - ) -{ - register GraphicDevice *pGD = (GraphicDevice *)&sed13806; - unsigned long dstAddr; - unsigned int stride = bpp * pGD -> winSizeX; - - dstAddr = (dst_y * stride) + (dst_x * bpp); - - Epson_wait_idle (); - - /* set up blit registers */ - writeByte(BLT_DST_ADDR0,dstAddr); - writeByte(BLT_DST_ADDR1,dstAddr>>8); - writeByte(BLT_DST_ADDR2,dstAddr>>16); - - writeWord(BLT_WIDTH0,(dim_x - 1)); - writeWord(BLT_HEIGHT0,(dim_y - 1)); - writeWord(BLT_FGCOLOR0,color); - - writeByte(BLT_OP,0x0C); /* solid fill */ - writeWord(BLT_MEM_OFF0,stride / 2); - - if (pGD -> gdfIndex == GDF__8BIT_INDEX) { - writeByte(BLT_CTRL1,0x00); - } - else { - writeByte(BLT_CTRL1,0x01); - } - - /* Engage the blt engine */ - /* rectangular region for src and dst */ - writeByte(BLT_CTRL0,0x80); - - /* wait untill current blits finished */ - Epson_wait_idle (); -} - -/*----------------------------------------------------------------------------- - * video_set_lut -- - *----------------------------------------------------------------------------- - */ -void video_set_lut ( - unsigned int index, /* color number */ - unsigned char r, /* red */ - unsigned char g, /* green */ - unsigned char b /* blue */ - ) -{ - writeByte(REG_LUT_ADDR, index ); - writeByte(REG_LUT_DATA, r); - writeByte(REG_LUT_DATA, g); - writeByte(REG_LUT_DATA, b); -} -#ifdef CONFIG_VIDEO_HW_CURSOR -/*----------------------------------------------------------------------------- - * video_set_hw_cursor -- - *----------------------------------------------------------------------------- - */ -void video_set_hw_cursor (int x, int y) -{ - writeByte (LCD_CURSOR_XL, (x & 0xff)); - writeByte (LCD_CURSOR_XM, (x >> 8)); - writeByte (LCD_CURSOR_YL, (y & 0xff)); - writeByte (LCD_CURSOR_YM, (y >> 8)); -} - -/*----------------------------------------------------------------------------- - * video_init_hw_cursor -- - *----------------------------------------------------------------------------- - */ -void video_init_hw_cursor (int font_width, int font_height) -{ - volatile unsigned char *ptr; - unsigned char pattern; - int i; - - - /* Init cursor content - Cursor size is 64x64 pixels - Start of the cursor memory depends on panel type (dual panel ...) */ - if ((i = readByte (LCD_CURSOR_START)) == 0) { - ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - HWCURSORSIZE); - } - else { - ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - (i * 8192)); - } - - /* Fill the first line and the first empty line after cursor */ - for (i = 0, pattern = 0; i < 64; i++) { - if (i < font_width) { - /* Invert background */ - pattern |= 0x3; - - } - else { - /* Background */ - pattern |= 0x2; - } - if ((i & 3) == 3) { - *ptr = pattern; - *(ptr + font_height * 16) = 0xaa; - ptr ++; - pattern = 0; - } - pattern <<= 2; - } - - /* Duplicate this line */ - for (i = 1; i < font_height; i++) { - memcpy ((void *)ptr, (void *)(ptr - 16), 16); - ptr += 16; - } - - for (; i < 64; i++) { - memcpy ((void *)(ptr + 16), (void *)ptr, 16); - ptr += 16; - } - - /* Select cursor mode */ - writeByte (LCD_CURSOR_CNTL, 1); -} -#endif -#endif diff --git a/drivers/sed156x.c b/drivers/sed156x.c deleted file mode 100644 index e9d5ed4..0000000 --- a/drivers/sed156x.c +++ /dev/null @@ -1,566 +0,0 @@ -/* - * (C) Copyright 2003 - * - * Pantelis Antoniou - * Intracom S.A. - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -#include -#include - -#include - -#ifdef CONFIG_SED156X - -/* 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 - -#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 */ -} - -#endif /* CONFIG_SED156X */ diff --git a/drivers/sm501.c b/drivers/sm501.c deleted file mode 100644 index 23db02c..0000000 --- a/drivers/sm501.c +++ /dev/null @@ -1,150 +0,0 @@ -/* - * (C) Copyright 2002 - * Stäubli Faverges - - * Pierre AUBERT p.aubert@staubli.com - * - * (C) Copyright 2005 - * Martin Krause TQ-Systems GmbH martin.krause@tqs.de - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * Basic video support for SMI SM501 "Voyager" graphic controller - */ - -#include - -#ifdef CONFIG_VIDEO_SM501 - -#include -#include - -#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; - -/*----------------------------------------------------------------------------- - * 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) { - write32 (preg->Index, preg->Value); - /* - * Insert a delay between - */ - udelay (1000); - preg ++; - } -} - -/*----------------------------------------------------------------------------- - * video_hw_init -- - *----------------------------------------------------------------------------- - */ -void *video_hw_init (void) -{ - unsigned int *vm, i; - - memset (&sm501, 0, sizeof (GraphicDevice)); - - /* - * Initialization of the access to the graphic chipset Retreive base - * address of the chipset (see board/RPXClassic/eccx.c) - */ - if ((sm501.isaBase = board_video_init ()) == 0) { - return (NULL); - } - - if ((sm501.frameAdrs = board_video_get_fb ()) == 0) { - 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); -} - -/*----------------------------------------------------------------------------- - * video_set_lut -- - *----------------------------------------------------------------------------- - */ -void video_set_lut ( - unsigned int index, /* color number */ - unsigned char r, /* red */ - unsigned char g, /* green */ - unsigned char b /* blue */ - ) -{ -} - -#endif /* CONFIG_VIDEO_SM501 */ diff --git a/drivers/smiLynxEM.c b/drivers/smiLynxEM.c deleted file mode 100644 index 20f9beb..0000000 --- a/drivers/smiLynxEM.c +++ /dev/null @@ -1,858 +0,0 @@ -/* - * (C) Copyright 1997-2002 ELTEC Elektronik AG - * Frank Gottschling - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/* - * smiLynxEM.c - * - * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator - * - * modification history - * -------------------- - * 04-18-2002 Rewritten for U-Boot . - * - * 18-03-2004 - Unify videomodes handling with the ct69000 - * - The video output can be set via the variable "videoout" - * in the environment. - * videoout=1 output on LCD - * videoout=2 output on CRT (default value) - * - */ - -#include - -#if defined(CONFIG_VIDEO_SMI_LYNXEM) - -#include -#include -#include "videomodes.h" -/* - * Export Graphic Device - */ -GraphicDevice smi; - -/* - * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external - */ -#define VIDEO_MEM_SIZE 0x400000 - - -/* - * ISA mapped regs - */ -#define SMI_INDX_C4 (pGD->isaBase + 0x03c4) /* index reg */ -#define SMI_DATA_C5 (pGD->isaBase + 0x03c5) /* data reg */ -#define SMI_INDX_D4 (pGD->isaBase + 0x03d4) /* index reg */ -#define SMI_DATA_D5 (pGD->isaBase + 0x03d5) /* data reg */ -#define SMI_ISR1 (pGD->isaBase + 0x03ca) -#define SMI_INDX_CE (pGD->isaBase + 0x03ce) /* index reg */ -#define SMI_DATA_CF (pGD->isaBase + 0x03cf) /* data reg */ -#define SMI_LOCK_REG (pGD->isaBase + 0x03c3) /* unlock/lock ext crt reg */ -#define SMI_MISC_REG (pGD->isaBase + 0x03c2) /* misc reg */ -#define SMI_LUT_MASK (pGD->isaBase + 0x03c6) /* lut mask reg */ -#define SMI_LUT_START (pGD->isaBase + 0x03c8) /* lut start index */ -#define SMI_LUT_RGB (pGD->isaBase + 0x03c9) /* lut colors auto incr.*/ -#define SMI_INDX_ATTR (pGD->isaBase + 0x03c0) /* attributes index reg */ - -/* - * Video processor control - */ -typedef struct { - unsigned int control; - unsigned int colorKey; - unsigned int colorKeyMask; - unsigned int start; - unsigned short offset; - unsigned short width; - unsigned int fifoPrio; - unsigned int fifoERL; - unsigned int YUVtoRGB; -} SmiVideoProc; - -/* - * Video window control - */ -typedef struct { - unsigned short top; - unsigned short left; - unsigned short bottom; - unsigned short right; - unsigned int srcStart; - unsigned short width; - unsigned short offset; - unsigned char hStretch; - unsigned char vStretch; -} SmiVideoWin; - -/* - * Capture port control - */ -typedef struct { - unsigned int control; - unsigned short topClip; - unsigned short leftClip; - unsigned short srcHeight; - unsigned short srcWidth; - unsigned int srcBufStart1; - unsigned int srcBufStart2; - unsigned short srcOffset; - unsigned short fifoControl; -} SmiCapturePort; - - -/* - * Register values for common video modes - */ -static char SMI_SCR[] = { - /* all modes */ - 0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x15, 0x90, - 0x17, 0x20, 0x18, 0xb1, 0x19, 0x00, -}; -static char SMI_EXT_CRT[] = { - 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, - 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, -}; -static char SMI_ATTR [] = { - 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, - 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, - 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x41, 0x11, 0x00, - 0x12, 0x0f, 0x13, 0x00, 0x14, 0x00, -}; -static char SMI_GCR[18] = { - 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40, - 0x06, 0x05, 0x07, 0x0f, 0x08, 0xff, -}; -static char SMI_SEQR[] = { - 0x00, 0x00, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e, 0x00, 0x03, -}; -static char SMI_PCR [] = { - 0x20, 0x04, 0x21, 0x30, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, -}; -static char SMI_MCR[] = { - 0x60, 0x01, 0x61, 0x00, -#ifdef CONFIG_HMI1001 - 0x62, 0x74, /* Memory type is not configured by pins on HMI1001 */ -#endif -}; - -static char SMI_HCR[] = { - 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00, - 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00, -}; - - -/******************************************************************************* - * - * Write SMI ISA register - */ -static void smiWrite (unsigned short index, char reg, char val) -{ - register GraphicDevice *pGD = (GraphicDevice *)&smi; - - out8 ((pGD->isaBase + index), reg); - out8 ((pGD->isaBase + index + 1), val); -} - -/******************************************************************************* - * - * Write a table of SMI ISA register - */ -static void smiLoadRegs ( - unsigned int iReg, - unsigned int dReg, - char *regTab, - unsigned int tabSize - ) -{ - register GraphicDevice *pGD = (GraphicDevice *)&smi; - register int i; - - for (i=0; icprBase + 0x0004), ((pCP->topClip<<16) | pCP->leftClip)); - out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth)); - out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8); - out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8); - out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8); - out32r ((pGD->cprBase + 0x0018), pCP->fifoControl); - out32r ((pGD->cprBase + 0x0000), pCP->control); -} - - -/******************************************************************************* - * - * Init video processor registers - */ -static void smiInitVideoProcessor (void) -{ - SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed }; - SmiVideoWin smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 }; - register GraphicDevice *pGD = (GraphicDevice *)&smi; - register SmiVideoProc *pVP = (SmiVideoProc *)&smiVP; - register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW; - - pVP->width = pGD->plnSizeX * pGD->gdfBytesPP; - pVP->control |= pGD->gdfIndex << 16; - pVWin->bottom = pGD->winSizeY - 1; - pVWin->right = pGD->winSizeX - 1; - pVWin->width = pVP->width; - - /* color key */ - out32r ((pGD->vprBase + 0x0004), pVP->colorKey); - - /* color key mask */ - out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask); - - /* data src start adrs */ - out32r ((pGD->vprBase + 0x000c), pVP->start / 8); - - /* data width and offset */ - out32r ((pGD->vprBase + 0x0010), - ((pVP->offset / 8 * pGD->gdfBytesPP) << 16) | - (pGD->plnSizeX / 8 * pGD->gdfBytesPP)); - - /* video window 1 */ - out32r ((pGD->vprBase + 0x0014), - ((pVWin->top << 16) | pVWin->left)); - - out32r ((pGD->vprBase + 0x0018), - ((pVWin->bottom << 16) | pVWin->right)); - - out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8); - - out32r ((pGD->vprBase + 0x0020), - (((pVWin->offset / 8) << 16) | (pVWin->width / 8))); - - out32r ((pGD->vprBase + 0x0024), - (((pVWin->hStretch) << 8) | pVWin->vStretch)); - - /* video window 2 */ - out32r ((pGD->vprBase + 0x0028), - ((pVWin->top << 16) | pVWin->left)); - - out32r ((pGD->vprBase + 0x002c), - ((pVWin->bottom << 16) | pVWin->right)); - - out32r ((pGD->vprBase + 0x0030), - pVWin->srcStart / 8); - - out32r ((pGD->vprBase + 0x0034), - (((pVWin->offset / 8) << 16) | (pVWin->width / 8))); - - out32r ((pGD->vprBase + 0x0038), - (((pVWin->hStretch) << 8) | pVWin->vStretch)); - - /* fifo prio control */ - out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio); - - /* fifo empty request levell */ - out32r ((pGD->vprBase + 0x0058), pVP->fifoERL); - - /* conversion constant */ - out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB); - - /* vpr control word */ - out32r ((pGD->vprBase + 0x0000), pVP->control); -} - -/****************************************************************************** - * - * Init drawing engine registers - */ -static void smiInitDrawingEngine (void) -{ - GraphicDevice *pGD = (GraphicDevice *)&smi; - unsigned int val; - - /* don't start now */ - out32r ((pGD->dprBase + 0x000c), 0x000f0000); - - /* set rop2 to copypen */ - val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c)); - out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c)); - - /* set clip rect */ - out32r ((pGD->dprBase + 0x002c), 0); - out32r ((pGD->dprBase + 0x0030), - ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP )); - - /* src row pitch */ - val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010))); - out32r ((pGD->dprBase + 0x0010), - (val | pGD->plnSizeX * pGD->gdfBytesPP)); - - /* dst row pitch */ - val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010))); - out32r ((pGD->dprBase + 0x0010), - (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val)); - - /* window width src/dst */ - out32r ((pGD->dprBase + 0x003c), - (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) | - (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff))); - out16r ((pGD->dprBase + 0x001e), 0x0000); - - /* src base adrs */ - out32r ((pGD->dprBase + 0x0040), - (((pGD->frameAdrs/8) & 0x000fffff))); - - /* dst base adrs */ - out32r ((pGD->dprBase + 0x0044), - (((pGD->frameAdrs/8) & 0x000fffff))); - - /* foreground color */ - out32r ((pGD->dprBase + 0x0014), pGD->fg); - - /* background color */ - out32r ((pGD->dprBase + 0x0018), pGD->bg); - - /* xcolor */ - out32r ((pGD->dprBase + 0x0020), 0x00ffffff); - - /* xcolor mask */ - out32r ((pGD->dprBase + 0x0024), 0x00ffffff); - - /* bit mask */ - out32r ((pGD->dprBase + 0x0028), 0x00ffffff); - - /* load mono pattern */ - out32r ((pGD->dprBase + 0x0034), 0); - out32r ((pGD->dprBase + 0x0038), 0); -} - -static struct pci_device_id supported[] = { - { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 }, - { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 }, - { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 }, - { } -}; - -/*****************************************************************************/ -static void smiLoadMsr (struct ctfb_res_modes *mode) -{ - unsigned char h_synch_high, v_synch_high; - register GraphicDevice *pGD = (GraphicDevice *)&smi; - - 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 */ - out8 (SMI_MISC_REG, (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 - */ -} -/*****************************************************************************/ -static void smiLoadCrt (struct ctfb_res_modes *var, int bits_per_pixel) -{ - unsigned char cr[0x7a]; - int i; - unsigned int hd, hs, he, ht, hbs, hbe; /* Horizontal. */ - unsigned int vd, vs, ve, vt, vbs, vbe; /* vertical */ - unsigned int bpp, wd, dblscan, interlaced; - - const int LineCompare = 0x3ff; - unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor */ - register GraphicDevice *pGD = (GraphicDevice *)&smi; - - /* Horizontal */ - 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 */ - /* Blank */ - hbs = hd; - hbe = 0; /* Blank end at 0 */ - - /* Vertical */ - 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 */ - vbs = vd; - vbe = 0; - - bpp = bits_per_pixel; - dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0; - interlaced = var->vmode & FB_VMODE_INTERLACED; - - - 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; - vbs >>= 1; - ve >>= 1; - vt >>= 1; - } - - memset (cr, 0, sizeof (cr)); - cr[0x00] = ht - 5; - cr[0x01] = hd - 1; - cr[0x02] = hbs - 1; - cr[0x03] = (hbe & 0x1F); - cr[0x04] = hs; - cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f); - - cr[0x06] = (vt - 2) & 0xFF; - cr[0x07] = (((vt - 2) & 0x100) >> 8) - | (((vd - 1) & 0x100) >> 7) - | ((vs & 0x100) >> 6) - | (((vbs - 1) & 0x100) >> 5) - | ((LineCompare & 0x100) >> 4) - | (((vt - 2) & 0x200) >> 4) - | (((vd - 1) & 0x200) >> 3) - | ((vs & 0x200) >> 2); - - cr[0x30] = ((vt - 2) & 0x400) >> 7 - | (((vd - 1) & 0x400) >> 8) - | (((vbs - 1) & 0x400) >> 9) - | ((vs & 0x400) >> 10) - | (interlaced) ? 0x80 : 0; - - - cr[0x08] = 0x00; - cr[0x09] = (dblscan << 7) - | ((LineCompare & 0x200) >> 3) - | (((vbs - 1) & 0x200) >> 4) - | (TextScanLines - 1); - - cr[0x10] = vs & 0xff; /* VSyncPulseStart */ - cr[0x11] = (ve & 0x0f); - cr[0x12] = (vd - 1) & 0xff; /* LineCount */ - cr[0x13] = wd & 0xff; - cr[0x14] = 0x40; - cr[0x15] = (vbs - 1) & 0xff; - cr[0x16] = vbe & 0xff; - cr[0x17] = 0xe3; /* but it does not work */ - cr[0x18] = 0xff & LineCompare; - cr[0x22] = 0x00; /* todo? */ - - - /* now set the registers */ - for (i = 0; i <= 0x18; i++) { /*CR00 .. CR18 */ - smiWrite (SMI_INDX_D4, i, cr[i]); - } - i = 0x22; /*CR22 */ - smiWrite (SMI_INDX_D4, i, cr[i]); - i = 0x30; /*CR30 */ - smiWrite (SMI_INDX_D4, i, cr[i]); -} - -/*****************************************************************************/ -#define REF_FREQ 14318180 -#define PMIN 1 -#define PMAX 255 -#define QMIN 1 -#define QMAX 63 - -static unsigned int FindPQ (unsigned int freq, unsigned int *pp, unsigned int *pq) -{ - unsigned int n = QMIN, m = 0; - long long int L = 0, P = freq, Q = REF_FREQ, H = P >> 1; - long long int D = 0x7ffffffffffffffLL; - - for (n = QMIN; n <= QMAX; n++) { - m = PMIN; /* p/q ~ freq/ref -> p*ref-freq*q ~ 0 */ - L = P * n - m * Q; - while (L > 0 && m < PMAX) { - L -= REF_FREQ; /* difference is greater as 0 subtract fref */ - m++; /* and increment m */ - } - /* difference is less or equal than 0 or m > maximum */ - if (m > PMAX) - break; /* no solution: if we increase n we get the same situation */ - /* L is <= 0 now */ - if (-L > H && m > PMIN) { /* if difference > the half fref */ - L += REF_FREQ; /* 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; - *pp = m; - *pq = n; /* keep improved data */ - if (D == 0) - break; /* best result we can get */ - } - return (unsigned int) (0xffffffff & D); -} - -/*****************************************************************************/ -static void smiLoadCcr (struct ctfb_res_modes *var, unsigned short device_id) -{ - unsigned int p = 0; - unsigned int q = 0; - long long freq; - register GraphicDevice *pGD = (GraphicDevice *)&smi; - - smiWrite (SMI_INDX_C4, 0x65, 0); - smiWrite (SMI_INDX_C4, 0x66, 0); - smiWrite (SMI_INDX_C4, 0x68, 0x50); - if (device_id == PCI_DEVICE_ID_SMI_810) { - smiWrite (SMI_INDX_C4, 0x69, 0x3); - } else { - smiWrite (SMI_INDX_C4, 0x69, 0x0); - } - - /* Memory clock */ - switch (device_id) { - case PCI_DEVICE_ID_SMI_710 : - smiWrite (SMI_INDX_C4, 0x6a, 0x75); - break; - case PCI_DEVICE_ID_SMI_712 : - smiWrite (SMI_INDX_C4, 0x6a, 0x80); - break; - default : - smiWrite (SMI_INDX_C4, 0x6a, 0x53); - break; - } - smiWrite (SMI_INDX_C4, 0x6b, 0x15); - - /* VCLK */ - freq = 1000000000000LL / var -> pixclock; - - FindPQ ((unsigned int)freq, &p, &q); - - smiWrite (SMI_INDX_C4, 0x6c, p); - smiWrite (SMI_INDX_C4, 0x6d, q); - -} - -/******************************************************************************* - * - * Init video chip with common Linux graphic modes (lilo) - */ -void *video_hw_init (void) -{ - GraphicDevice *pGD = (GraphicDevice *)&smi; - unsigned short device_id; - pci_dev_t devbusfn; - int videomode; - unsigned long t1, hsynch, vsynch; - unsigned int pci_mem_base, *vm; - char *penv; - int tmp, i, bits_per_pixel; - struct ctfb_res_modes *res_mode; - struct ctfb_res_modes var_mode; - unsigned char videoout; - - /* Search for video chip */ - printf("Video: "); - - if ((devbusfn = pci_find_devices(supported, 0)) < 0) - { - printf ("Controller not found !\n"); - 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); - - tmp = 0; - - videomode = CFG_DEFAULT_VIDEO_MODE; - /* 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 0x%x ", CFG_DEFAULT_VIDEO_MODE); - 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 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 = CFG_ISA_IO; - pGD->pciBase = pci_mem_base; - pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000); - pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000); - pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000); - pGD->frameAdrs = pci_mem_base; - pGD->memSize = VIDEO_MEM_SIZE; - - /* Set up hardware : select color mode, - set Register base to isa 3dx for 3?x regs*/ - out8 (SMI_MISC_REG, 0x01); - - /* Turn off display */ - smiWrite (SMI_INDX_C4, 0x01, 0x20); - - /* Unlock ext. crt regs */ - out8 (SMI_LOCK_REG, 0x40); - - /* Unlock crt regs 0-7 */ - smiWrite (SMI_INDX_D4, 0x11, 0x0e); - - /* Sytem Control Register */ - smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SCR, sizeof(SMI_SCR)); - - /* extented CRT Register */ - smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5, SMI_EXT_CRT, sizeof(SMI_EXT_CRT)); - - /* Attributes controller registers */ - smiLoadRegs (SMI_INDX_ATTR, SMI_INDX_ATTR, SMI_ATTR, sizeof(SMI_ATTR)); - - /* Graphics Controller Register */ - smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF, SMI_GCR, sizeof(SMI_GCR)); - - /* Sequencer Register */ - smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SEQR, sizeof(SMI_SEQR)); - - /* Power Control Register */ - smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_PCR, sizeof(SMI_PCR)); - - /* Memory Control Register */ - /* Register MSR62 is a power on configurable register. We don't */ - /* modify it */ - smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_MCR, sizeof(SMI_MCR)); - - /* Set misc output register */ - smiLoadMsr (res_mode); - - /* Set CRT and Clock control registers */ - smiLoadCrt (res_mode, bits_per_pixel); - - smiLoadCcr (res_mode, device_id); - - /* Hardware Cusor Register */ - smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_HCR, sizeof(SMI_HCR)); - - /* Enable Display */ - videoout = 2; /* Default output is CRT */ - if ((penv = getenv ("videoout")) != NULL) { - /* deceide if it is a string */ - videoout = (int) simple_strtoul (penv, NULL, 16); - } - smiWrite (SMI_INDX_C4, 0x31, videoout); - - /* Video processor default setup */ - smiInitVideoProcessor (); - - /* Capture port default setup */ - smiInitCapturePort (); - - /* Drawing engine default setup */ - smiInitDrawingEngine (); - - /* Turn on display */ - smiWrite (0x3c4, 0x01, 0x01); - - /* Clear video memory */ - i = pGD->memSize/4; - vm = (unsigned int *)pGD->pciBase; - while(i--) - *vm++ = 0; - return ((void*)&smi); -} - -/******************************************************************************* - * - * 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 */ - ) -{ - register GraphicDevice *pGD = (GraphicDevice *)&smi; - register unsigned int control; - - dim_x *= bpp; - - out32r ((pGD->dprBase + 0x0014), color); - out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y)); - out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y)); - - control = 0x0000ffff & in32r ((pGD->dprBase + 0x000c)); - - control |= 0x80010000; - - out32r ((pGD->dprBase + 0x000c), control); - - /* Wait for drawing processor */ - do - { - out8 ((pGD->isaBase + 0x3c4), 0x16); - } while (in8 (pGD->isaBase + 0x3c5) & 0x08); -} - -/******************************************************************************* - * - * 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 */ - ) -{ - register GraphicDevice *pGD = (GraphicDevice *)&smi; - register unsigned int control; - - dim_x *= bpp; - - if ((src_ydprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1))); - out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1))); - control = 0x88000000; - } else { - out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y)); - out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y)); - control = 0x80000000; - } - - out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y)); - control |= (0x0000ffff & in32r ((pGD->dprBase + 0x000c))); - out32r ((pGD->dprBase + 0x000c), control); - - /* Wait for drawing processor */ - do - { - out8 ((pGD->isaBase + 0x3c4), 0x16); - } while (in8 (pGD->isaBase + 0x3c5) & 0x08); -} - -/******************************************************************************* - * - * 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 */ - ) -{ - register GraphicDevice *pGD = (GraphicDevice *)&smi; - - out8 (SMI_LUT_MASK, 0xff); - - out8 (SMI_LUT_START, (char)index); - - out8 (SMI_LUT_RGB, r>>2); /* red */ - udelay (10); - out8 (SMI_LUT_RGB, g>>2); /* green */ - udelay (10); - out8 (SMI_LUT_RGB, b>>2); /* blue */ - udelay (10); -} - -#endif /* CONFIG_VIDEO_SMI_LYNXEM */ diff --git a/drivers/video/Makefile b/drivers/video/Makefile new file mode 100644 index 0000000..36611ec --- /dev/null +++ b/drivers/video/Makefile @@ -0,0 +1,53 @@ +# +# (C) Copyright 2000-2007 +# Wolfgang Denk, DENX Software Engineering, wd@denx.de. +# +# See file CREDITS for list of people who contributed to this +# project. +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License as +# published by the Free Software Foundation; either version 2 of +# the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, +# MA 02111-1307 USA +# + +include $(TOPDIR)/config.mk + +LIB := $(obj)libvideo.a + +COBJS-y += ati_radeon_fb.o +COBJS-y += cfb_console.o +COBJS-y += ct69000.o +COBJS-y += sed13806.o +COBJS-y += sed156x.o +COBJS-y += sm501.o +COBJS-y += smiLynxEM.o +COBJS-y += videomodes.o + +COBJS := $(COBJS-y) +SRCS := $(COBJS:.o=.c) +OBJS := $(addprefix $(obj),$(COBJS)) + +all: $(LIB) + +$(LIB): $(obj).depend $(OBJS) + $(AR) $(ARFLAGS) $@ $(OBJS) + +######################################################################### + +# defines $(obj).depend target +include $(SRCTREE)/rules.mk + +sinclude $(obj).depend + +######################################################################### diff --git a/drivers/video/ati_ids.h b/drivers/video/ati_ids.h new file mode 100644 index 0000000..3e72a7d --- /dev/null +++ b/drivers/video/ati_ids.h @@ -0,0 +1,211 @@ +/* + * ATI PCI IDs from XFree86, kept here to make sync'ing with + * XFree much simpler. Currently, this list is only used by + * radeonfb + */ + +#define PCI_CHIP_RV380_3150 0x3150 +#define PCI_CHIP_RV380_3151 0x3151 +#define PCI_CHIP_RV380_3152 0x3152 +#define PCI_CHIP_RV380_3153 0x3153 +#define PCI_CHIP_RV380_3154 0x3154 +#define PCI_CHIP_RV380_3156 0x3156 +#define PCI_CHIP_RV380_3E50 0x3E50 +#define PCI_CHIP_RV380_3E51 0x3E51 +#define PCI_CHIP_RV380_3E52 0x3E52 +#define PCI_CHIP_RV380_3E53 0x3E53 +#define PCI_CHIP_RV380_3E54 0x3E54 +#define PCI_CHIP_RV380_3E56 0x3E56 +#define PCI_CHIP_RS100_4136 0x4136 +#define PCI_CHIP_RS200_4137 0x4137 +#define PCI_CHIP_R300_AD 0x4144 +#define PCI_CHIP_R300_AE 0x4145 +#define PCI_CHIP_R300_AF 0x4146 +#define PCI_CHIP_R300_AG 0x4147 +#define PCI_CHIP_R350_AH 0x4148 +#define PCI_CHIP_R350_AI 0x4149 +#define PCI_CHIP_R350_AJ 0x414A +#define PCI_CHIP_R350_AK 0x414B +#define PCI_CHIP_RV350_AP 0x4150 +#define PCI_CHIP_RV350_AQ 0x4151 +#define PCI_CHIP_RV360_AR 0x4152 +#define PCI_CHIP_RV350_AS 0x4153 +#define PCI_CHIP_RV350_AT 0x4154 +#define PCI_CHIP_RV350_AV 0x4156 +#define PCI_CHIP_MACH32 0x4158 +#define PCI_CHIP_RS250_4237 0x4237 +#define PCI_CHIP_R200_BB 0x4242 +#define PCI_CHIP_R200_BC 0x4243 +#define PCI_CHIP_RS100_4336 0x4336 +#define PCI_CHIP_RS200_4337 0x4337 +#define PCI_CHIP_MACH64CT 0x4354 +#define PCI_CHIP_MACH64CX 0x4358 +#define PCI_CHIP_RS250_4437 0x4437 +#define PCI_CHIP_MACH64ET 0x4554 +#define PCI_CHIP_MACH64GB 0x4742 +#define PCI_CHIP_MACH64GD 0x4744 +#define PCI_CHIP_MACH64GI 0x4749 +#define PCI_CHIP_MACH64GL 0x474C +#define PCI_CHIP_MACH64GM 0x474D +#define PCI_CHIP_MACH64GN 0x474E +#define PCI_CHIP_MACH64GO 0x474F +#define PCI_CHIP_MACH64GP 0x4750 +#define PCI_CHIP_MACH64GQ 0x4751 +#define PCI_CHIP_MACH64GR 0x4752 +#define PCI_CHIP_MACH64GS 0x4753 +#define PCI_CHIP_MACH64GT 0x4754 +#define PCI_CHIP_MACH64GU 0x4755 +#define PCI_CHIP_MACH64GV 0x4756 +#define PCI_CHIP_MACH64GW 0x4757 +#define PCI_CHIP_MACH64GX 0x4758 +#define PCI_CHIP_MACH64GY 0x4759 +#define PCI_CHIP_MACH64GZ 0x475A +#define PCI_CHIP_RV250_Id 0x4964 +#define PCI_CHIP_RV250_Ie 0x4965 +#define PCI_CHIP_RV250_If 0x4966 +#define PCI_CHIP_RV250_Ig 0x4967 +#define PCI_CHIP_R420_JH 0x4A48 +#define PCI_CHIP_R420_JI 0x4A49 +#define PCI_CHIP_R420_JJ 0x4A4A +#define PCI_CHIP_R420_JK 0x4A4B +#define PCI_CHIP_R420_JL 0x4A4C +#define PCI_CHIP_R420_JM 0x4A4D +#define PCI_CHIP_R420_JN 0x4A4E +#define PCI_CHIP_R420_JP 0x4A50 +#define PCI_CHIP_MACH64LB 0x4C42 +#define PCI_CHIP_MACH64LD 0x4C44 +#define PCI_CHIP_RAGE128LE 0x4C45 +#define PCI_CHIP_RAGE128LF 0x4C46 +#define PCI_CHIP_MACH64LG 0x4C47 +#define PCI_CHIP_MACH64LI 0x4C49 +#define PCI_CHIP_MACH64LM 0x4C4D +#define PCI_CHIP_MACH64LN 0x4C4E +#define PCI_CHIP_MACH64LP 0x4C50 +#define PCI_CHIP_MACH64LQ 0x4C51 +#define PCI_CHIP_MACH64LR 0x4C52 +#define PCI_CHIP_MACH64LS 0x4C53 +#define PCI_CHIP_MACH64LT 0x4C54 +#define PCI_CHIP_RADEON_LW 0x4C57 +#define PCI_CHIP_RADEON_LX 0x4C58 +#define PCI_CHIP_RADEON_LY 0x4C59 +#define PCI_CHIP_RADEON_LZ 0x4C5A +#define PCI_CHIP_RV250_Ld 0x4C64 +#define PCI_CHIP_RV250_Le 0x4C65 +#define PCI_CHIP_RV250_Lf 0x4C66 +#define PCI_CHIP_RV250_Lg 0x4C67 +#define PCI_CHIP_RV250_Ln 0x4C6E +#define PCI_CHIP_RAGE128MF 0x4D46 +#define PCI_CHIP_RAGE128ML 0x4D4C +#define PCI_CHIP_R300_ND 0x4E44 +#define PCI_CHIP_R300_NE 0x4E45 +#define PCI_CHIP_R300_NF 0x4E46 +#define PCI_CHIP_R300_NG 0x4E47 +#define PCI_CHIP_R350_NH 0x4E48 +#define PCI_CHIP_R350_NI 0x4E49 +#define PCI_CHIP_R360_NJ 0x4E4A +#define PCI_CHIP_R350_NK 0x4E4B +#define PCI_CHIP_RV350_NP 0x4E50 +#define PCI_CHIP_RV350_NQ 0x4E51 +#define PCI_CHIP_RV350_NR 0x4E52 +#define PCI_CHIP_RV350_NS 0x4E53 +#define PCI_CHIP_RV350_NT 0x4E54 +#define PCI_CHIP_RV350_NV 0x4E56 +#define PCI_CHIP_RAGE128PA 0x5041 +#define PCI_CHIP_RAGE128PB 0x5042 +#define PCI_CHIP_RAGE128PC 0x5043 +#define PCI_CHIP_RAGE128PD 0x5044 +#define PCI_CHIP_RAGE128PE 0x5045 +#define PCI_CHIP_RAGE128PF 0x5046 +#define PCI_CHIP_RAGE128PG 0x5047 +#define PCI_CHIP_RAGE128PH 0x5048 +#define PCI_CHIP_RAGE128PI 0x5049 +#define PCI_CHIP_RAGE128PJ 0x504A +#define PCI_CHIP_RAGE128PK 0x504B +#define PCI_CHIP_RAGE128PL 0x504C +#define PCI_CHIP_RAGE128PM 0x504D +#define PCI_CHIP_RAGE128PN 0x504E +#define PCI_CHIP_RAGE128PO 0x504F +#define PCI_CHIP_RAGE128PP 0x5050 +#define PCI_CHIP_RAGE128PQ 0x5051 +#define PCI_CHIP_RAGE128PR 0x5052 +#define PCI_CHIP_RAGE128PS 0x5053 +#define PCI_CHIP_RAGE128PT 0x5054 +#define PCI_CHIP_RAGE128PU 0x5055 +#define PCI_CHIP_RAGE128PV 0x5056 +#define PCI_CHIP_RAGE128PW 0x5057 +#define PCI_CHIP_RAGE128PX 0x5058 +#define PCI_CHIP_RADEON_QD 0x5144 +#define PCI_CHIP_RADEON_QE 0x5145 +#define PCI_CHIP_RADEON_QF 0x5146 +#define PCI_CHIP_RADEON_QG 0x5147 +#define PCI_CHIP_R200_QH 0x5148 +#define PCI_CHIP_R200_QI 0x5149 +#define PCI_CHIP_R200_QJ 0x514A +#define PCI_CHIP_R200_QK 0x514B +#define PCI_CHIP_R200_QL 0x514C +#define PCI_CHIP_R200_QM 0x514D +#define PCI_CHIP_R200_QN 0x514E +#define PCI_CHIP_R200_QO 0x514F +#define PCI_CHIP_RV200_QW 0x5157 +#define PCI_CHIP_RV200_QX 0x5158 +#define PCI_CHIP_RV100_QY 0x5159 +#define PCI_CHIP_RV100_QZ 0x515A +#define PCI_CHIP_RN50 0x515E +#define PCI_CHIP_RAGE128RE 0x5245 +#define PCI_CHIP_RAGE128RF 0x5246 +#define PCI_CHIP_RAGE128RG 0x5247 +#define PCI_CHIP_RAGE128RK 0x524B +#define PCI_CHIP_RAGE128RL 0x524C +#define PCI_CHIP_RAGE128SE 0x5345 +#define PCI_CHIP_RAGE128SF 0x5346 +#define PCI_CHIP_RAGE128SG 0x5347 +#define PCI_CHIP_RAGE128SH 0x5348 +#define PCI_CHIP_RAGE128SK 0x534B +#define PCI_CHIP_RAGE128SL 0x534C +#define PCI_CHIP_RAGE128SM 0x534D +#define PCI_CHIP_RAGE128SN 0x534E +#define PCI_CHIP_RAGE128TF 0x5446 +#define PCI_CHIP_RAGE128TL 0x544C +#define PCI_CHIP_RAGE128TR 0x5452 +#define PCI_CHIP_RAGE128TS 0x5453 +#define PCI_CHIP_RAGE128TT 0x5454 +#define PCI_CHIP_RAGE128TU 0x5455 +#define PCI_CHIP_RV370_5460 0x5460 +#define PCI_CHIP_RV370_5461 0x5461 +#define PCI_CHIP_RV370_5462 0x5462 +#define PCI_CHIP_RV370_5463 0x5463 +#define PCI_CHIP_RV370_5464 0x5464 +#define PCI_CHIP_RV370_5465 0x5465 +#define PCI_CHIP_RV370_5466 0x5466 +#define PCI_CHIP_RV370_5467 0x5467 +#define PCI_CHIP_R423_UH 0x5548 +#define PCI_CHIP_R423_UI 0x5549 +#define PCI_CHIP_R423_UJ 0x554A +#define PCI_CHIP_R423_UK 0x554B +#define PCI_CHIP_R423_UQ 0x5551 +#define PCI_CHIP_R423_UR 0x5552 +#define PCI_CHIP_R423_UT 0x5554 +#define PCI_CHIP_MACH64VT 0x5654 +#define PCI_CHIP_MACH64VU 0x5655 +#define PCI_CHIP_MACH64VV 0x5656 +#define PCI_CHIP_RS300_5834 0x5834 +#define PCI_CHIP_RS300_5835 0x5835 +#define PCI_CHIP_RS300_5836 0x5836 +#define PCI_CHIP_RS300_5837 0x5837 +#define PCI_CHIP_RV370_5B60 0x5B60 +#define PCI_CHIP_RV370_5B61 0x5B61 +#define PCI_CHIP_RV370_5B62 0x5B62 +#define PCI_CHIP_RV370_5B63 0x5B63 +#define PCI_CHIP_RV370_5B64 0x5B64 +#define PCI_CHIP_RV370_5B65 0x5B65 +#define PCI_CHIP_RV370_5B66 0x5B66 +#define PCI_CHIP_RV370_5B67 0x5B67 +#define PCI_CHIP_RV280_5960 0x5960 +#define PCI_CHIP_RV280_5961 0x5961 +#define PCI_CHIP_RV280_5962 0x5962 +#define PCI_CHIP_RV280_5964 0x5964 +#define PCI_CHIP_RV280_5C61 0x5C61 +#define PCI_CHIP_RV280_5C63 0x5C63 +#define PCI_CHIP_R423_5D57 0x5D57 +#define PCI_CHIP_RS350_7834 0x7834 +#define PCI_CHIP_RS350_7835 0x7835 diff --git a/drivers/video/ati_radeon_fb.c b/drivers/video/ati_radeon_fb.c new file mode 100644 index 0000000..0bdaa1c --- /dev/null +++ b/drivers/video/ati_radeon_fb.c @@ -0,0 +1,488 @@ +/* + * ATI Radeon Video card Framebuffer driver. + * + * Copyright 2007 Freescale Semiconductor, Inc. + * Zhang Wei + * Jason Jin + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + * + * Some codes of this file is partly ported from Linux kernel + * ATI video framebuffer driver. + * + * Now the driver is tested on below ATI chips: + * 9200 + * X300 + * X700 + * + */ + +#include + +#ifdef CONFIG_ATI_RADEON_FB + +#include +#include +#include +#include +#include +#include +#include + +#include +#include "ati_ids.h" +#include "ati_radeon_fb.h" + +#undef DEBUG + +#ifdef DEBUG +#define DPRINT(x...) printf(x) +#else +#define DPRINT(x...) do{}while(0) +#endif + +#ifndef min_t +#define min_t(type,x,y) \ + ({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) +#endif + +#define MAX_MAPPED_VRAM (2048*2048*4) +#define MIN_MAPPED_VRAM (1024*768*1) + +/*#define PCI_VENDOR_ID_ATI*/ +#define PCI_CHIP_RV280_5960 0x5960 +#define PCI_CHIP_RV280_5961 0x5961 +#define PCI_CHIP_RV280_5962 0x5962 +#define PCI_CHIP_RV280_5964 0x5964 +#define PCI_CHIP_RV370_5B60 0x5B60 +#define PCI_CHIP_RV380_5657 0x5657 +#define PCI_CHIP_R420_554d 0x554d + +static struct pci_device_id ati_radeon_pci_ids[] = { + {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5960}, + {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5961}, + {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5962}, + {PCI_VENDOR_ID_ATI, PCI_CHIP_RV280_5964}, + {PCI_VENDOR_ID_ATI, PCI_CHIP_RV370_5B60}, + {PCI_VENDOR_ID_ATI, PCI_CHIP_RV380_5657}, + {PCI_VENDOR_ID_ATI, PCI_CHIP_R420_554d}, + {0, 0} +}; + +static u16 ati_radeon_id_family_table[][2] = { + {PCI_CHIP_RV280_5960, CHIP_FAMILY_RV280}, + {PCI_CHIP_RV280_5961, CHIP_FAMILY_RV280}, + {PCI_CHIP_RV280_5962, CHIP_FAMILY_RV280}, + {PCI_CHIP_RV280_5964, CHIP_FAMILY_RV280}, + {PCI_CHIP_RV370_5B60, CHIP_FAMILY_RV380}, + {PCI_CHIP_RV380_5657, CHIP_FAMILY_RV380}, + {PCI_CHIP_R420_554d, CHIP_FAMILY_R420}, + {0, 0} +}; + +u16 get_radeon_id_family(u16 device) +{ + int i; + for (i=0; ati_radeon_id_family_table[0][i]; i+=2) + if (ati_radeon_id_family_table[0][i] == device) + return ati_radeon_id_family_table[0][i + 1]; + return 0; +} + +struct radeonfb_info *rinfo; + +static void radeon_identify_vram(struct radeonfb_info *rinfo) +{ + u32 tmp; + + /* framebuffer size */ + if ((rinfo->family == CHIP_FAMILY_RS100) || + (rinfo->family == CHIP_FAMILY_RS200) || + (rinfo->family == CHIP_FAMILY_RS300)) { + u32 tom = INREG(NB_TOM); + tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); + + radeon_fifo_wait(6); + OUTREG(MC_FB_LOCATION, tom); + OUTREG(DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); + OUTREG(CRTC2_DISPLAY_BASE_ADDR, (tom & 0xffff) << 16); + OUTREG(OV0_BASE_ADDR, (tom & 0xffff) << 16); + + /* This is supposed to fix the crtc2 noise problem. */ + OUTREG(GRPH2_BUFFER_CNTL, INREG(GRPH2_BUFFER_CNTL) & ~0x7f0000); + + if ((rinfo->family == CHIP_FAMILY_RS100) || + (rinfo->family == CHIP_FAMILY_RS200)) { + /* This is to workaround the asic bug for RMX, some versions + of BIOS dosen't have this register initialized correctly. + */ + OUTREGP(CRTC_MORE_CNTL, CRTC_H_CUTOFF_ACTIVE_EN, + ~CRTC_H_CUTOFF_ACTIVE_EN); + } + } else { + tmp = INREG(CONFIG_MEMSIZE); + } + + /* mem size is bits [28:0], mask off the rest */ + rinfo->video_ram = tmp & CONFIG_MEMSIZE_MASK; + + /* + * Hack to get around some busted production M6's + * reporting no ram + */ + if (rinfo->video_ram == 0) { + switch (rinfo->pdev.device) { + case PCI_CHIP_RADEON_LY: + case PCI_CHIP_RADEON_LZ: + rinfo->video_ram = 8192 * 1024; + break; + default: + break; + } + } + + /* + * Now try to identify VRAM type + */ + if ((rinfo->family >= CHIP_FAMILY_R300) || + (INREG(MEM_SDRAM_MODE_REG) & (1<<30))) + rinfo->vram_ddr = 1; + else + rinfo->vram_ddr = 0; + + tmp = INREG(MEM_CNTL); + if (IS_R300_VARIANT(rinfo)) { + tmp &= R300_MEM_NUM_CHANNELS_MASK; + switch (tmp) { + case 0: rinfo->vram_width = 64; break; + case 1: rinfo->vram_width = 128; break; + case 2: rinfo->vram_width = 256; break; + default: rinfo->vram_width = 128; break; + } + } else if ((rinfo->family == CHIP_FAMILY_RV100) || + (rinfo->family == CHIP_FAMILY_RS100) || + (rinfo->family == CHIP_FAMILY_RS200)){ + if (tmp & RV100_MEM_HALF_MODE) + rinfo->vram_width = 32; + else + rinfo->vram_width = 64; + } else { + if (tmp & MEM_NUM_CHANNELS_MASK) + rinfo->vram_width = 128; + else + rinfo->vram_width = 64; + } + + /* This may not be correct, as some cards can have half of channel disabled + * ToDo: identify these cases + */ + + DPRINT("radeonfb: Found %ldk of %s %d bits wide videoram\n", + rinfo->video_ram / 1024, + rinfo->vram_ddr ? "DDR" : "SDRAM", + rinfo->vram_width); + +} + +static void radeon_write_pll_regs(struct radeonfb_info *rinfo, struct radeon_regs *mode) +{ + int i; + + radeon_fifo_wait(20); + +#if 0 + /* Workaround from XFree */ + if (rinfo->is_mobility) { + /* A temporal workaround for the occational blanking on certain laptop + * panels. This appears to related to the PLL divider registers + * (fail to lock?). It occurs even when all dividers are the same + * with their old settings. In this case we really don't need to + * fiddle with PLL registers. By doing this we can avoid the blanking + * problem with some panels. + */ + if ((mode->ppll_ref_div == (INPLL(PPLL_REF_DIV) & PPLL_REF_DIV_MASK)) && + (mode->ppll_div_3 == (INPLL(PPLL_DIV_3) & + (PPLL_POST3_DIV_MASK | PPLL_FB3_DIV_MASK)))) { + /* We still have to force a switch to selected PPLL div thanks to + * an XFree86 driver bug which will switch it away in some cases + * even when using UseFDev */ + OUTREGP(CLOCK_CNTL_INDEX, + mode->clk_cntl_index & PPLL_DIV_SEL_MASK, + ~PPLL_DIV_SEL_MASK); + radeon_pll_errata_after_index(rinfo); + radeon_pll_errata_after_data(rinfo); + return; + } + } +#endif + if(rinfo->pdev.device == PCI_CHIP_RV370_5B60) return; + + /* Swich VCKL clock input to CPUCLK so it stays fed while PPLL updates*/ + OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_CPUCLK, ~VCLK_SRC_SEL_MASK); + + /* Reset PPLL & enable atomic update */ + OUTPLLP(PPLL_CNTL, + PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN, + ~(PPLL_RESET | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); + + /* Switch to selected PPLL divider */ + OUTREGP(CLOCK_CNTL_INDEX, + mode->clk_cntl_index & PPLL_DIV_SEL_MASK, + ~PPLL_DIV_SEL_MASK); + + /* Set PPLL ref. div */ + if (rinfo->family == CHIP_FAMILY_R300 || + rinfo->family == CHIP_FAMILY_RS300 || + rinfo->family == CHIP_FAMILY_R350 || + rinfo->family == CHIP_FAMILY_RV350) { + if (mode->ppll_ref_div & R300_PPLL_REF_DIV_ACC_MASK) { + /* When restoring console mode, use saved PPLL_REF_DIV + * setting. + */ + OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, 0); + } else { + /* R300 uses ref_div_acc field as real ref divider */ + OUTPLLP(PPLL_REF_DIV, + (mode->ppll_ref_div << R300_PPLL_REF_DIV_ACC_SHIFT), + ~R300_PPLL_REF_DIV_ACC_MASK); + } + } else + OUTPLLP(PPLL_REF_DIV, mode->ppll_ref_div, ~PPLL_REF_DIV_MASK); + + /* Set PPLL divider 3 & post divider*/ + OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_FB3_DIV_MASK); + OUTPLLP(PPLL_DIV_3, mode->ppll_div_3, ~PPLL_POST3_DIV_MASK); + + /* Write update */ + while (INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R) + ; + OUTPLLP(PPLL_REF_DIV, PPLL_ATOMIC_UPDATE_W, ~PPLL_ATOMIC_UPDATE_W); + + /* Wait read update complete */ + /* FIXME: Certain revisions of R300 can't recover here. Not sure of + the cause yet, but this workaround will mask the problem for now. + Other chips usually will pass at the very first test, so the + workaround shouldn't have any effect on them. */ + for (i = 0; (i < 10000 && INPLL(PPLL_REF_DIV) & PPLL_ATOMIC_UPDATE_R); i++) + ; + + OUTPLL(HTOTAL_CNTL, 0); + + /* Clear reset & atomic update */ + OUTPLLP(PPLL_CNTL, 0, + ~(PPLL_RESET | PPLL_SLEEP | PPLL_ATOMIC_UPDATE_EN | PPLL_VGA_ATOMIC_UPDATE_EN)); + + /* We may want some locking ... oh well */ + udelay(5000); + + /* Switch back VCLK source to PPLL */ + OUTPLLP(VCLK_ECP_CNTL, VCLK_SRC_SEL_PPLLCLK, ~VCLK_SRC_SEL_MASK); +} + +typedef struct { + u16 reg; + u32 val; +} reg_val; + +#if 0 /* unused ? -> scheduled for removal */ +/* these common regs are cleared before mode setting so they do not + * interfere with anything + */ +static reg_val common_regs[] = { + { OVR_CLR, 0 }, + { OVR_WID_LEFT_RIGHT, 0 }, + { OVR_WID_TOP_BOTTOM, 0 }, + { OV0_SCALE_CNTL, 0 }, + { SUBPIC_CNTL, 0 }, + { VIPH_CONTROL, 0 }, + { I2C_CNTL_1, 0 }, + { GEN_INT_CNTL, 0 }, + { CAP0_TRIG_CNTL, 0 }, + { CAP1_TRIG_CNTL, 0 }, +}; +#endif /* 0 */ + +void radeon_setmode(void) +{ + struct radeon_regs *mode = malloc(sizeof(struct radeon_regs)); + + mode->crtc_gen_cntl = 0x03000200; + mode->crtc_ext_cntl = 0x00008048; + mode->dac_cntl = 0xff002100; + mode->crtc_h_total_disp = 0x4f0063; + mode->crtc_h_sync_strt_wid = 0x8c02a2; + mode->crtc_v_total_disp = 0x01df020c; + mode->crtc_v_sync_strt_wid = 0x8201ea; + mode->crtc_pitch = 0x00500050; + + OUTREG(CRTC_GEN_CNTL, mode->crtc_gen_cntl); + OUTREGP(CRTC_EXT_CNTL, mode->crtc_ext_cntl, + ~(CRTC_HSYNC_DIS | CRTC_VSYNC_DIS | CRTC_DISPLAY_DIS)); + OUTREGP(DAC_CNTL, mode->dac_cntl, DAC_RANGE_CNTL | DAC_BLANKING); + OUTREG(CRTC_H_TOTAL_DISP, mode->crtc_h_total_disp); + OUTREG(CRTC_H_SYNC_STRT_WID, mode->crtc_h_sync_strt_wid); + OUTREG(CRTC_V_TOTAL_DISP, mode->crtc_v_total_disp); + OUTREG(CRTC_V_SYNC_STRT_WID, mode->crtc_v_sync_strt_wid); + OUTREG(CRTC_OFFSET, 0); + OUTREG(CRTC_OFFSET_CNTL, 0); + OUTREG(CRTC_PITCH, mode->crtc_pitch); + + mode->clk_cntl_index = 0x300; + mode->ppll_ref_div = 0xc; + mode->ppll_div_3 = 0x00030059; + + radeon_write_pll_regs(rinfo, mode); +} + +#include "../bios_emulator/include/biosemu.h" +extern int BootVideoCardBIOS(pci_dev_t pcidev, BE_VGAInfo ** pVGAInfo, int cleanUp); + +int radeon_probe(struct radeonfb_info *rinfo) +{ + pci_dev_t pdev; + u16 did; + + pdev = pci_find_devices(ati_radeon_pci_ids, 0); + + if (pdev != -1) { + pci_read_config_word(pdev, PCI_DEVICE_ID, &did); + printf("ATI Radeon video card (%04x, %04x) found @(%d:%d:%d)\n", + PCI_VENDOR_ID_ATI, did, (pdev >> 16) & 0xff, + (pdev >> 11) & 0x1f, (pdev >> 8) & 0x7); + + strcpy(rinfo->name, "ATI Radeon"); + rinfo->pdev.vendor = PCI_VENDOR_ID_ATI; + rinfo->pdev.device = did; + rinfo->family = get_radeon_id_family(rinfo->pdev.device); + pci_read_config_dword(pdev, PCI_BASE_ADDRESS_0, + &rinfo->fb_base_phys); + pci_read_config_dword(pdev, PCI_BASE_ADDRESS_2, + &rinfo->mmio_base_phys); + rinfo->fb_base_phys &= 0xfffff000; + rinfo->mmio_base_phys &= ~0x04; + + rinfo->mmio_base = (void *)rinfo->mmio_base_phys; + DPRINT("rinfo->mmio_base = 0x%x\n",rinfo->mmio_base); + rinfo->fb_local_base = INREG(MC_FB_LOCATION) << 16; + DPRINT("rinfo->fb_local_base = 0x%x\n",rinfo->fb_local_base); + /* PostBIOS with x86 emulater */ + BootVideoCardBIOS(pdev, NULL, 0); + + /* + * Check for errata + * (These will be added in the future for the chipfamily + * R300, RV200, RS200, RV100, RS100.) + */ + + /* Get VRAM size and type */ + radeon_identify_vram(rinfo); + + rinfo->mapped_vram = min_t(unsigned long, MAX_MAPPED_VRAM, + rinfo->video_ram); + rinfo->fb_base = (void *)rinfo->fb_base_phys; + + DPRINT("Radeon: framebuffer base phy address 0x%08x," \ + "MMIO base phy address 0x%08x," \ + "framebuffer local base 0x%08x.\n ", + rinfo->fb_base_phys, rinfo->mmio_base_phys, + rinfo->fb_local_base); + + return 0; + } + return -1; +} + +/* + * The Graphic Device + */ +GraphicDevice ctfb; + +#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 */ + +void *video_hw_init(void) +{ + GraphicDevice *pGD = (GraphicDevice *) & ctfb; + int i; + u32 *vm; + + rinfo = malloc(sizeof(struct radeonfb_info)); + + if(radeon_probe(rinfo)) { + printf("No radeon video card found!\n"); + return NULL; + } + + /* fill in Graphic device struct */ + sprintf (pGD->modeIdent, "%dx%dx%d %ldkHz %ldHz", 640, + 480, 16, (1000 / 1000), + (2000 / 1000)); + printf ("%s\n", pGD->modeIdent); + + pGD->winSizeX = 640; + pGD->winSizeY = 480; + pGD->plnSizeX = 640; + pGD->plnSizeY = 480; + + pGD->gdfBytesPP = 1; + pGD->gdfIndex = GDF__8BIT_INDEX; + + pGD->isaBase = CFG_ISA_IO_BASE_ADDRESS; + pGD->pciBase = rinfo->fb_base_phys; + pGD->frameAdrs = rinfo->fb_base_phys; + pGD->memSize = 64 * 1024 * 1024; + + /* Cursor Start Address */ + pGD->dprBase = + (pGD->winSizeX * pGD->winSizeY * pGD->gdfBytesPP) + rinfo->fb_base_phys; + if ((pGD->dprBase & 0x0fff) != 0) { + /* allign it */ + pGD->dprBase &= 0xfffff000; + pGD->dprBase += 0x00001000; + } + DPRINT ("Cursor Start %x Pattern Start %x\n", pGD->dprBase, + PATTERN_ADR); + pGD->vprBase = rinfo->fb_base_phys; /* Dummy */ + pGD->cprBase = rinfo->fb_base_phys; /* Dummy */ + /* set up Hardware */ + + /* Clear video memory */ + i = pGD->memSize / 4; + vm = (unsigned int *) pGD->pciBase; + while (i--) + *vm++ = 0; + /*SetDrawingEngine (bits_per_pixel);*/ + + radeon_setmode(); + + return ((void *) pGD); +} + +void video_set_lut (unsigned int index, /* color number */ + unsigned char r, /* red */ + unsigned char g, /* green */ + unsigned char b /* blue */ + ) +{ + OUTREG(PALETTE_INDEX, index); + OUTREG(PALETTE_DATA, (r << 16) | (g << 8) | b); +} +#endif diff --git a/drivers/video/ati_radeon_fb.h b/drivers/video/ati_radeon_fb.h new file mode 100644 index 0000000..b5c4b8b --- /dev/null +++ b/drivers/video/ati_radeon_fb.h @@ -0,0 +1,282 @@ +#ifndef __ATI_RADEON_FB_H +#define __ATI_RADEON_FB_H + +/*************************************************************** + * Most of the definitions here are adapted right from XFree86 * + ***************************************************************/ + +/* + * Chip families. Must fit in the low 16 bits of a long word + */ +enum radeon_family { + CHIP_FAMILY_UNKNOW, + CHIP_FAMILY_LEGACY, + CHIP_FAMILY_RADEON, + CHIP_FAMILY_RV100, + CHIP_FAMILY_RS100, /* U1 (IGP320M) or A3 (IGP320)*/ + CHIP_FAMILY_RV200, + CHIP_FAMILY_RS200, /* U2 (IGP330M/340M/350M) or A4 (IGP330/340/345/350), + RS250 (IGP 7000) */ + CHIP_FAMILY_R200, + CHIP_FAMILY_RV250, + CHIP_FAMILY_RS300, /* Radeon 9000 IGP */ + CHIP_FAMILY_RV280, + CHIP_FAMILY_R300, + CHIP_FAMILY_R350, + CHIP_FAMILY_RV350, + CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ + CHIP_FAMILY_R420, /* R420/R423/M18 */ + CHIP_FAMILY_LAST, +}; + +#define IS_RV100_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_RV100) || \ + ((rinfo)->family == CHIP_FAMILY_RV200) || \ + ((rinfo)->family == CHIP_FAMILY_RS100) || \ + ((rinfo)->family == CHIP_FAMILY_RS200) || \ + ((rinfo)->family == CHIP_FAMILY_RV250) || \ + ((rinfo)->family == CHIP_FAMILY_RV280) || \ + ((rinfo)->family == CHIP_FAMILY_RS300)) + +#define IS_R300_VARIANT(rinfo) (((rinfo)->family == CHIP_FAMILY_R300) || \ + ((rinfo)->family == CHIP_FAMILY_RV350) || \ + ((rinfo)->family == CHIP_FAMILY_R350) || \ + ((rinfo)->family == CHIP_FAMILY_RV380) || \ + ((rinfo)->family == CHIP_FAMILY_R420)) + +struct radeonfb_info { + char name[20]; + + struct pci_device_id pdev; + u16 family; + + u32 fb_base_phys; + u32 mmio_base_phys; + + void *mmio_base; + void *fb_base; + + u32 video_ram; + u32 mapped_vram; + int vram_width; + int vram_ddr; + + u32 fb_local_base; +}; + +#define INREG8(addr) readb((rinfo->mmio_base)+addr) +#define OUTREG8(addr,val) writeb(val, (rinfo->mmio_base)+addr) +#define INREG16(addr) readw((rinfo->mmio_base)+addr) +#define OUTREG16(addr,val) writew(val, (rinfo->mmio_base)+addr) +#define INREG(addr) readl((rinfo->mmio_base)+addr) +#define OUTREG(addr,val) writel(val, (rinfo->mmio_base)+addr) + +static inline void _OUTREGP(struct radeonfb_info *rinfo, u32 addr, + u32 val, u32 mask) +{ + unsigned int tmp; + + tmp = INREG(addr); + tmp &= (mask); + tmp |= (val); + OUTREG(addr, tmp); +} + +#define OUTREGP(addr,val,mask) _OUTREGP(rinfo, addr, val,mask) + +/* + * 2D Engine helper routines + */ +static inline void radeon_engine_flush (struct radeonfb_info *rinfo) +{ + int i; + + /* initiate flush */ + OUTREGP(RB2D_DSTCACHE_CTLSTAT, RB2D_DC_FLUSH_ALL, + ~RB2D_DC_FLUSH_ALL); + + for (i=0; i < 2000000; i++) { + if (!(INREG(RB2D_DSTCACHE_CTLSTAT) & RB2D_DC_BUSY)) + return; + udelay(1); + } + printf("radeonfb: Flush Timeout !\n"); +} + +static inline void _radeon_fifo_wait(struct radeonfb_info *rinfo, int entries) +{ + int i; + + for (i=0; i<2000000; i++) { + if ((INREG(RBBM_STATUS) & 0x7f) >= entries) + return; + udelay(1); + } + printf("radeonfb: FIFO Timeout !\n"); +} + +static inline void _radeon_engine_idle(struct radeonfb_info *rinfo) +{ + int i; + + /* ensure FIFO is empty before waiting for idle */ + _radeon_fifo_wait (rinfo, 64); + + for (i=0; i<2000000; i++) { + if (((INREG(RBBM_STATUS) & GUI_ACTIVE)) == 0) { + radeon_engine_flush (rinfo); + return; + } + udelay(1); + } + printf("radeonfb: Idle Timeout !\n"); +} + +#define radeon_engine_idle() _radeon_engine_idle(rinfo) +#define radeon_fifo_wait(entries) _radeon_fifo_wait(rinfo,entries) +#define radeon_msleep(ms) _radeon_msleep(rinfo,ms) + +/* + * This structure contains the various registers manipulated by this + * driver for setting or restoring a mode. It's mostly copied from + * XFree's RADEONSaveRec structure. A few chip settings might still be + * tweaked without beeing reflected or saved in these registers though + */ +struct radeon_regs { + /* Common registers */ + u32 ovr_clr; + u32 ovr_wid_left_right; + u32 ovr_wid_top_bottom; + u32 ov0_scale_cntl; + u32 mpp_tb_config; + u32 mpp_gp_config; + u32 subpic_cntl; + u32 viph_control; + u32 i2c_cntl_1; + u32 gen_int_cntl; + u32 cap0_trig_cntl; + u32 cap1_trig_cntl; + u32 bus_cntl; + u32 surface_cntl; + u32 bios_5_scratch; + + /* Other registers to save for VT switches or driver load/unload */ + u32 dp_datatype; + u32 rbbm_soft_reset; + u32 clock_cntl_index; + u32 amcgpio_en_reg; + u32 amcgpio_mask; + + /* Surface/tiling registers */ + u32 surf_lower_bound[8]; + u32 surf_upper_bound[8]; + u32 surf_info[8]; + + /* CRTC registers */ + u32 crtc_gen_cntl; + u32 crtc_ext_cntl; + u32 dac_cntl; + u32 crtc_h_total_disp; + u32 crtc_h_sync_strt_wid; + u32 crtc_v_total_disp; + u32 crtc_v_sync_strt_wid; + u32 crtc_offset; + u32 crtc_offset_cntl; + u32 crtc_pitch; + u32 disp_merge_cntl; + u32 grph_buffer_cntl; + u32 crtc_more_cntl; + + /* CRTC2 registers */ + u32 crtc2_gen_cntl; + u32 dac2_cntl; + u32 disp_output_cntl; + u32 disp_hw_debug; + u32 disp2_merge_cntl; + u32 grph2_buffer_cntl; + u32 crtc2_h_total_disp; + u32 crtc2_h_sync_strt_wid; + u32 crtc2_v_total_disp; + u32 crtc2_v_sync_strt_wid; + u32 crtc2_offset; + u32 crtc2_offset_cntl; + u32 crtc2_pitch; + + /* Flat panel regs */ + u32 fp_crtc_h_total_disp; + u32 fp_crtc_v_total_disp; + u32 fp_gen_cntl; + u32 fp2_gen_cntl; + u32 fp_h_sync_strt_wid; + u32 fp2_h_sync_strt_wid; + u32 fp_horz_stretch; + u32 fp_panel_cntl; + u32 fp_v_sync_strt_wid; + u32 fp2_v_sync_strt_wid; + u32 fp_vert_stretch; + u32 lvds_gen_cntl; + u32 lvds_pll_cntl; + u32 tmds_crc; + u32 tmds_transmitter_cntl; + + /* Computed values for PLL */ + u32 dot_clock_freq; + int feedback_div; + int post_div; + + /* PLL registers */ + u32 ppll_div_3; + u32 ppll_ref_div; + u32 vclk_ecp_cntl; + u32 clk_cntl_index; + + /* Computed values for PLL2 */ + u32 dot_clock_freq_2; + int feedback_div_2; + int post_div_2; + + /* PLL2 registers */ + u32 p2pll_ref_div; + u32 p2pll_div_0; + u32 htotal_cntl2; + + /* Palette */ + int palette_valid; +}; + +static inline u32 __INPLL(struct radeonfb_info *rinfo, u32 addr) +{ + u32 data; + + OUTREG8(CLOCK_CNTL_INDEX, addr & 0x0000003f); + /* radeon_pll_errata_after_index(rinfo); */ + data = INREG(CLOCK_CNTL_DATA); + /* radeon_pll_errata_after_data(rinfo); */ + return data; +} + +static inline void __OUTPLL(struct radeonfb_info *rinfo, unsigned int index, + u32 val) +{ + + OUTREG8(CLOCK_CNTL_INDEX, (index & 0x0000003f) | 0x00000080); + /* radeon_pll_errata_after_index(rinfo); */ + OUTREG(CLOCK_CNTL_DATA, val); + /* radeon_pll_errata_after_data(rinfo); */ +} + +static inline void __OUTPLLP(struct radeonfb_info *rinfo, unsigned int index, + u32 val, u32 mask) +{ + unsigned int tmp; + + tmp = __INPLL(rinfo, index); + tmp &= (mask); + tmp |= (val); + __OUTPLL(rinfo, index, tmp); +} + +#define INPLL(addr) __INPLL(rinfo, addr) +#define OUTPLL(index, val) __OUTPLL(rinfo, index, val) +#define OUTPLLP(index, val, mask) __OUTPLLP(rinfo, index, val, mask) + +#endif diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c new file mode 100644 index 0000000..bcf8771 --- /dev/null +++ b/drivers/video/cfb_console.c @@ -0,0 +1,1274 @@ +/* + * (C) Copyright 2002 ELTEC Elektronik AG + * Frank Gottschling + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * cfb_console.c + * + * Color Framebuffer Console driver for 8/15/16/24/32 bits per pixel. + * + * At the moment only the 8x16 font is tested and the font fore- and + * background color is limited to black/white/gray colors. The Linux + * logo can be placed in the upper left corner and additional board + * information strings (that normaly goes to serial port) can be drawed. + * + * The console driver can use the standard PC keyboard interface (i8042) + * for character input. Character output goes to a memory mapped video + * framebuffer with little or big-endian organisation. + * With environment setting 'console=serial' the console i/o can be + * forced to serial port. + + The driver uses graphic specific defines/parameters/functions: + + (for SMI LynxE graphic chip) + + CONFIG_VIDEO_SMI_LYNXEM - use graphic driver for SMI 710,712,810 + VIDEO_FB_LITTLE_ENDIAN - framebuffer organisation default: big endian + VIDEO_HW_RECTFILL - graphic driver supports hardware rectangle fill + VIDEO_HW_BITBLT - graphic driver supports hardware bit blt + + Console Parameters are set by graphic drivers global struct: + + VIDEO_VISIBLE_COLS - x resolution + VIDEO_VISIBLE_ROWS - y resolution + VIDEO_PIXEL_SIZE - storage size in byte per pixel + VIDEO_DATA_FORMAT - graphical data format GDF + VIDEO_FB_ADRS - start of video memory + + CONFIG_I8042_KBD - AT Keyboard driver for i8042 + VIDEO_KBD_INIT_FCT - init function for keyboard + VIDEO_TSTC_FCT - keyboard_tstc function + VIDEO_GETC_FCT - keyboard_getc function + + CONFIG_CONSOLE_CURSOR - on/off drawing cursor is done with delay + loop in VIDEO_TSTC_FCT (i8042) + CFG_CONSOLE_BLINK_COUNT - value for delay loop - blink rate + CONFIG_CONSOLE_TIME - display time/date in upper right corner, + needs CONFIG_CMD_DATE and CONFIG_CONSOLE_CURSOR + CONFIG_VIDEO_LOGO - display Linux Logo in upper left corner + CONFIG_VIDEO_BMP_LOGO - use bmp_logo instead of linux_logo + CONFIG_CONSOLE_EXTRA_INFO - display additional board information strings + that normaly goes to serial port. This define + requires a board specific function: + video_drawstring (VIDEO_INFO_X, + VIDEO_INFO_Y + i*VIDEO_FONT_HEIGHT, + info); + that fills a info buffer at i=row. + s.a: board/eltec/bab7xx. +CONFIG_VGA_AS_SINGLE_DEVICE - If set the framebuffer device will be initialised + as an output only device. The Keyboard driver + will not be set-up. This may be used, if you + have none or more than one Keyboard devices + (USB Keyboard, AT Keyboard). + +CONFIG_VIDEO_SW_CURSOR: - Draws a cursor after the last character. No + blinking is provided. Uses the macros CURSOR_SET + and CURSOR_OFF. +CONFIG_VIDEO_HW_CURSOR: - Uses the hardware cursor capability of the + graphic chip. Uses the macro CURSOR_SET. + ATTENTION: If booting an OS, the display driver + must disable the hardware register of the graphic + chip. Otherwise a blinking field is displayed +*/ + +#include + +#ifdef CONFIG_CFB_CONSOLE + +#include + +/*****************************************************************************/ +/* Console device defines with SMI graphic */ +/* Any other graphic must change this section */ +/*****************************************************************************/ + +#ifdef CONFIG_VIDEO_SMI_LYNXEM + +#define VIDEO_FB_LITTLE_ENDIAN +#define VIDEO_HW_RECTFILL +#define VIDEO_HW_BITBLT +#endif + +/*****************************************************************************/ +/* Defines for the CT69000 driver */ +/*****************************************************************************/ +#ifdef CONFIG_VIDEO_CT69000 + +#define VIDEO_FB_LITTLE_ENDIAN +#define VIDEO_HW_RECTFILL +#define VIDEO_HW_BITBLT +#endif + +/*****************************************************************************/ +/* Defines for the SED13806 driver */ +/*****************************************************************************/ +#ifdef CONFIG_VIDEO_SED13806 + +#ifndef CONFIG_TOTAL5200 +#define VIDEO_FB_LITTLE_ENDIAN +#endif +#define VIDEO_HW_RECTFILL +#define VIDEO_HW_BITBLT +#endif + +/*****************************************************************************/ +/* Defines for the SED13806 driver */ +/*****************************************************************************/ +#ifdef CONFIG_VIDEO_SM501 + +#ifdef CONFIG_HH405 +#define VIDEO_FB_LITTLE_ENDIAN +#endif +#endif + +/*****************************************************************************/ +/* Include video_fb.h after definitions of VIDEO_HW_RECTFILL etc */ +/*****************************************************************************/ +#include + +/*****************************************************************************/ +/* some Macros */ +/*****************************************************************************/ +#define VIDEO_VISIBLE_COLS (pGD->winSizeX) +#define VIDEO_VISIBLE_ROWS (pGD->winSizeY) +#define VIDEO_PIXEL_SIZE (pGD->gdfBytesPP) +#define VIDEO_DATA_FORMAT (pGD->gdfIndex) +#define VIDEO_FB_ADRS (pGD->frameAdrs) + +/*****************************************************************************/ +/* Console device defines with i8042 keyboard controller */ +/* Any other keyboard controller must change this section */ +/*****************************************************************************/ + +#ifdef CONFIG_I8042_KBD +#include + +#define VIDEO_KBD_INIT_FCT i8042_kbd_init() +#define VIDEO_TSTC_FCT i8042_tstc +#define VIDEO_GETC_FCT i8042_getc +#endif + +/*****************************************************************************/ +/* Console device */ +/*****************************************************************************/ + +#include +#include +#include +#include + +#if defined(CONFIG_CMD_DATE) +#include +#endif + +#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) +#include +#include +#endif + +/*****************************************************************************/ +/* Cursor definition: */ +/* CONFIG_CONSOLE_CURSOR: Uses a timer function (see drivers/i8042.c) to */ +/* let the cursor blink. Uses the macros CURSOR_OFF */ +/* and CURSOR_ON. */ +/* CONFIG_VIDEO_SW_CURSOR: Draws a cursor after the last character. No */ +/* blinking is provided. Uses the macros CURSOR_SET */ +/* and CURSOR_OFF. */ +/* CONFIG_VIDEO_HW_CURSOR: Uses the hardware cursor capability of the */ +/* graphic chip. Uses the macro CURSOR_SET. */ +/* ATTENTION: If booting an OS, the display driver */ +/* must disable the hardware register of the graphic */ +/* chip. Otherwise a blinking field is displayed */ +/*****************************************************************************/ +#if !defined(CONFIG_CONSOLE_CURSOR) && \ + !defined(CONFIG_VIDEO_SW_CURSOR) && \ + !defined(CONFIG_VIDEO_HW_CURSOR) +/* no Cursor defined */ +#define CURSOR_ON +#define CURSOR_OFF +#define CURSOR_SET +#endif + +#ifdef CONFIG_CONSOLE_CURSOR +#ifdef CURSOR_ON +#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined +#endif +void console_cursor (int state); +#define CURSOR_ON console_cursor(1); +#define CURSOR_OFF console_cursor(0); +#define CURSOR_SET +#ifndef CONFIG_I8042_KBD +#warning Cursor drawing on/off needs timer function s.a. drivers/i8042.c +#endif +#else +#ifdef CONFIG_CONSOLE_TIME +#error CONFIG_CONSOLE_CURSOR must be defined for CONFIG_CONSOLE_TIME +#endif +#endif /* CONFIG_CONSOLE_CURSOR */ + +#ifdef CONFIG_VIDEO_SW_CURSOR +#ifdef CURSOR_ON +#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined +#endif +#define CURSOR_ON +#define CURSOR_OFF video_putchar(console_col * VIDEO_FONT_WIDTH,\ + console_row * VIDEO_FONT_HEIGHT, ' '); +#define CURSOR_SET video_set_cursor(); +#endif /* CONFIG_VIDEO_SW_CURSOR */ + + +#ifdef CONFIG_VIDEO_HW_CURSOR +#ifdef CURSOR_ON +#error only one of CONFIG_CONSOLE_CURSOR,CONFIG_VIDEO_SW_CURSOR,CONFIG_VIDEO_HW_CURSOR can be defined +#endif +#define CURSOR_ON +#define CURSOR_OFF +#define CURSOR_SET video_set_hw_cursor(console_col * VIDEO_FONT_WIDTH, \ + (console_row * VIDEO_FONT_HEIGHT) + VIDEO_LOGO_HEIGHT); +#endif /* CONFIG_VIDEO_HW_CURSOR */ + +#ifdef CONFIG_VIDEO_LOGO +#ifdef CONFIG_VIDEO_BMP_LOGO +#include +#define VIDEO_LOGO_WIDTH BMP_LOGO_WIDTH +#define VIDEO_LOGO_HEIGHT BMP_LOGO_HEIGHT +#define VIDEO_LOGO_LUT_OFFSET BMP_LOGO_OFFSET +#define VIDEO_LOGO_COLORS BMP_LOGO_COLORS + +#else /* CONFIG_VIDEO_BMP_LOGO */ +#define LINUX_LOGO_WIDTH 80 +#define LINUX_LOGO_HEIGHT 80 +#define LINUX_LOGO_COLORS 214 +#define LINUX_LOGO_LUT_OFFSET 0x20 +#define __initdata +#include +#define VIDEO_LOGO_WIDTH LINUX_LOGO_WIDTH +#define VIDEO_LOGO_HEIGHT LINUX_LOGO_HEIGHT +#define VIDEO_LOGO_LUT_OFFSET LINUX_LOGO_LUT_OFFSET +#define VIDEO_LOGO_COLORS LINUX_LOGO_COLORS +#endif /* CONFIG_VIDEO_BMP_LOGO */ +#define VIDEO_INFO_X (VIDEO_LOGO_WIDTH) +#define VIDEO_INFO_Y (VIDEO_FONT_HEIGHT/2) +#else /* CONFIG_VIDEO_LOGO */ +#define VIDEO_LOGO_WIDTH 0 +#define VIDEO_LOGO_HEIGHT 0 +#endif /* CONFIG_VIDEO_LOGO */ + +#define VIDEO_COLS VIDEO_VISIBLE_COLS +#define VIDEO_ROWS VIDEO_VISIBLE_ROWS +#define VIDEO_SIZE (VIDEO_ROWS*VIDEO_COLS*VIDEO_PIXEL_SIZE) +#define VIDEO_PIX_BLOCKS (VIDEO_SIZE >> 2) +#define VIDEO_LINE_LEN (VIDEO_COLS*VIDEO_PIXEL_SIZE) +#define VIDEO_BURST_LEN (VIDEO_COLS/8) + +#ifdef CONFIG_VIDEO_LOGO +#define CONSOLE_ROWS ((VIDEO_ROWS - VIDEO_LOGO_HEIGHT) / VIDEO_FONT_HEIGHT) +#else +#define CONSOLE_ROWS (VIDEO_ROWS / VIDEO_FONT_HEIGHT) +#endif + +#define CONSOLE_COLS (VIDEO_COLS / VIDEO_FONT_WIDTH) +#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * VIDEO_LINE_LEN) +#define CONSOLE_ROW_FIRST (video_console_address) +#define CONSOLE_ROW_SECOND (video_console_address + CONSOLE_ROW_SIZE) +#define CONSOLE_ROW_LAST (video_console_address + CONSOLE_SIZE - CONSOLE_ROW_SIZE) +#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS) +#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE) + +/* Macros */ +#ifdef VIDEO_FB_LITTLE_ENDIAN +#define SWAP16(x) ((((x) & 0x00ff) << 8) | ( (x) >> 8)) +#define SWAP32(x) ((((x) & 0x000000ff) << 24) | (((x) & 0x0000ff00) << 8)|\ + (((x) & 0x00ff0000) >> 8) | (((x) & 0xff000000) >> 24) ) +#define SHORTSWAP32(x) ((((x) & 0x000000ff) << 8) | (((x) & 0x0000ff00) >> 8)|\ + (((x) & 0x00ff0000) << 8) | (((x) & 0xff000000) >> 8) ) +#else +#define SWAP16(x) (x) +#define SWAP32(x) (x) +#define SHORTSWAP32(x) (x) +#endif + +#if defined(DEBUG) || defined(DEBUG_CFB_CONSOLE) +#define PRINTD(x) printf(x) +#else +#define PRINTD(x) +#endif + + +#ifdef CONFIG_CONSOLE_EXTRA_INFO +extern void video_get_info_str ( /* setup a board string: type, speed, etc. */ + int line_number, /* location to place info string beside logo */ + char *info /* buffer for info string */ + ); + +#endif + +/* Locals */ +static GraphicDevice *pGD; /* Pointer to Graphic array */ + +static void *video_fb_address; /* frame buffer address */ +static void *video_console_address; /* console buffer start address */ + +static int console_col = 0; /* cursor col */ +static int console_row = 0; /* cursor row */ + +static u32 eorx, fgx, bgx; /* color pats */ + +static const int video_font_draw_table8[] = { + 0x00000000, 0x000000ff, 0x0000ff00, 0x0000ffff, + 0x00ff0000, 0x00ff00ff, 0x00ffff00, 0x00ffffff, + 0xff000000, 0xff0000ff, 0xff00ff00, 0xff00ffff, + 0xffff0000, 0xffff00ff, 0xffffff00, 0xffffffff }; + +static const int video_font_draw_table15[] = { + 0x00000000, 0x00007fff, 0x7fff0000, 0x7fff7fff }; + +static const int video_font_draw_table16[] = { + 0x00000000, 0x0000ffff, 0xffff0000, 0xffffffff }; + +static const int video_font_draw_table24[16][3] = { + { 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00ffffff }, + { 0x00000000, 0x0000ffff, 0xff000000 }, + { 0x00000000, 0x0000ffff, 0xffffffff }, + { 0x000000ff, 0xffff0000, 0x00000000 }, + { 0x000000ff, 0xffff0000, 0x00ffffff }, + { 0x000000ff, 0xffffffff, 0xff000000 }, + { 0x000000ff, 0xffffffff, 0xffffffff }, + { 0xffffff00, 0x00000000, 0x00000000 }, + { 0xffffff00, 0x00000000, 0x00ffffff }, + { 0xffffff00, 0x0000ffff, 0xff000000 }, + { 0xffffff00, 0x0000ffff, 0xffffffff }, + { 0xffffffff, 0xffff0000, 0x00000000 }, + { 0xffffffff, 0xffff0000, 0x00ffffff }, + { 0xffffffff, 0xffffffff, 0xff000000 }, + { 0xffffffff, 0xffffffff, 0xffffffff } }; + +static const int video_font_draw_table32[16][4] = { + { 0x00000000, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00000000, 0x00ffffff }, + { 0x00000000, 0x00000000, 0x00ffffff, 0x00000000 }, + { 0x00000000, 0x00000000, 0x00ffffff, 0x00ffffff }, + { 0x00000000, 0x00ffffff, 0x00000000, 0x00000000 }, + { 0x00000000, 0x00ffffff, 0x00000000, 0x00ffffff }, + { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00000000 }, + { 0x00000000, 0x00ffffff, 0x00ffffff, 0x00ffffff }, + { 0x00ffffff, 0x00000000, 0x00000000, 0x00000000 }, + { 0x00ffffff, 0x00000000, 0x00000000, 0x00ffffff }, + { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00000000 }, + { 0x00ffffff, 0x00000000, 0x00ffffff, 0x00ffffff }, + { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00000000 }, + { 0x00ffffff, 0x00ffffff, 0x00000000, 0x00ffffff }, + { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00000000 }, + { 0x00ffffff, 0x00ffffff, 0x00ffffff, 0x00ffffff } }; + + +int gunzip(void *, int, unsigned char *, unsigned long *); + +/******************************************************************************/ + +static void video_drawchars (int xx, int yy, unsigned char *s, int count) +{ + u8 *cdat, *dest, *dest0; + int rows, offset, c; + + offset = yy * VIDEO_LINE_LEN + xx * VIDEO_PIXEL_SIZE; + dest0 = video_fb_address + offset; + + switch (VIDEO_DATA_FORMAT) { + case GDF__8BIT_INDEX: + case GDF__8BIT_332RGB: + while (count--) { + c = *s; + cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (rows = VIDEO_FONT_HEIGHT, dest = dest0; + rows--; + dest += VIDEO_LINE_LEN) { + u8 bits = *cdat++; + + ((u32 *) dest)[0] = (video_font_draw_table8[bits >> 4] & eorx) ^ bgx; + ((u32 *) dest)[1] = (video_font_draw_table8[bits & 15] & eorx) ^ bgx; + } + dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; + s++; + } + break; + + case GDF_15BIT_555RGB: + while (count--) { + c = *s; + cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (rows = VIDEO_FONT_HEIGHT, dest = dest0; + rows--; + dest += VIDEO_LINE_LEN) { + u8 bits = *cdat++; + + ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 6] & eorx) ^ bgx); + ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 4 & 3] & eorx) ^ bgx); + ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table15 [bits >> 2 & 3] & eorx) ^ bgx); + ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table15 [bits & 3] & eorx) ^ bgx); + } + dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; + s++; + } + break; + + case GDF_16BIT_565RGB: + while (count--) { + c = *s; + cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (rows = VIDEO_FONT_HEIGHT, dest = dest0; + rows--; + dest += VIDEO_LINE_LEN) { + u8 bits = *cdat++; + + ((u32 *) dest)[0] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 6] & eorx) ^ bgx); + ((u32 *) dest)[1] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 4 & 3] & eorx) ^ bgx); + ((u32 *) dest)[2] = SHORTSWAP32 ((video_font_draw_table16 [bits >> 2 & 3] & eorx) ^ bgx); + ((u32 *) dest)[3] = SHORTSWAP32 ((video_font_draw_table16 [bits & 3] & eorx) ^ bgx); + } + dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; + s++; + } + break; + + case GDF_32BIT_X888RGB: + while (count--) { + c = *s; + cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (rows = VIDEO_FONT_HEIGHT, dest = dest0; + rows--; + dest += VIDEO_LINE_LEN) { + u8 bits = *cdat++; + + ((u32 *) dest)[0] = SWAP32 ((video_font_draw_table32 [bits >> 4][0] & eorx) ^ bgx); + ((u32 *) dest)[1] = SWAP32 ((video_font_draw_table32 [bits >> 4][1] & eorx) ^ bgx); + ((u32 *) dest)[2] = SWAP32 ((video_font_draw_table32 [bits >> 4][2] & eorx) ^ bgx); + ((u32 *) dest)[3] = SWAP32 ((video_font_draw_table32 [bits >> 4][3] & eorx) ^ bgx); + ((u32 *) dest)[4] = SWAP32 ((video_font_draw_table32 [bits & 15][0] & eorx) ^ bgx); + ((u32 *) dest)[5] = SWAP32 ((video_font_draw_table32 [bits & 15][1] & eorx) ^ bgx); + ((u32 *) dest)[6] = SWAP32 ((video_font_draw_table32 [bits & 15][2] & eorx) ^ bgx); + ((u32 *) dest)[7] = SWAP32 ((video_font_draw_table32 [bits & 15][3] & eorx) ^ bgx); + } + dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; + s++; + } + break; + + case GDF_24BIT_888RGB: + while (count--) { + c = *s; + cdat = video_fontdata + c * VIDEO_FONT_HEIGHT; + for (rows = VIDEO_FONT_HEIGHT, dest = dest0; + rows--; + dest += VIDEO_LINE_LEN) { + u8 bits = *cdat++; + + ((u32 *) dest)[0] = (video_font_draw_table24[bits >> 4][0] & eorx) ^ bgx; + ((u32 *) dest)[1] = (video_font_draw_table24[bits >> 4][1] & eorx) ^ bgx; + ((u32 *) dest)[2] = (video_font_draw_table24[bits >> 4][2] & eorx) ^ bgx; + ((u32 *) dest)[3] = (video_font_draw_table24[bits & 15][0] & eorx) ^ bgx; + ((u32 *) dest)[4] = (video_font_draw_table24[bits & 15][1] & eorx) ^ bgx; + ((u32 *) dest)[5] = (video_font_draw_table24[bits & 15][2] & eorx) ^ bgx; + } + dest0 += VIDEO_FONT_WIDTH * VIDEO_PIXEL_SIZE; + s++; + } + break; + } +} + +/*****************************************************************************/ + +static inline void video_drawstring (int xx, int yy, unsigned char *s) +{ + video_drawchars (xx, yy, s, strlen ((char *)s)); +} + +/*****************************************************************************/ + +static void video_putchar (int xx, int yy, unsigned char c) +{ + video_drawchars (xx, yy + VIDEO_LOGO_HEIGHT, &c, 1); +} + +/*****************************************************************************/ +#if defined(CONFIG_CONSOLE_CURSOR) || defined(CONFIG_VIDEO_SW_CURSOR) +static void video_set_cursor (void) +{ + /* swap drawing colors */ + eorx = fgx; + fgx = bgx; + bgx = eorx; + eorx = fgx ^ bgx; + /* draw cursor */ + video_putchar (console_col * VIDEO_FONT_WIDTH, + console_row * VIDEO_FONT_HEIGHT, + ' '); + /* restore drawing colors */ + eorx = fgx; + fgx = bgx; + bgx = eorx; + eorx = fgx ^ bgx; +} +#endif +/*****************************************************************************/ +#ifdef CONFIG_CONSOLE_CURSOR +void console_cursor (int state) +{ + static int last_state = 0; + +#ifdef CONFIG_CONSOLE_TIME + struct rtc_time tm; + char info[16]; + + /* time update only if cursor is on (faster scroll) */ + if (state) { + rtc_get (&tm); + + sprintf (info, " %02d:%02d:%02d ", tm.tm_hour, tm.tm_min, + tm.tm_sec); + video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH, + VIDEO_INFO_Y, (uchar *)info); + + sprintf (info, "%02d.%02d.%04d", tm.tm_mday, tm.tm_mon, + tm.tm_year); + video_drawstring (VIDEO_VISIBLE_COLS - 10 * VIDEO_FONT_WIDTH, + VIDEO_INFO_Y + 1 * VIDEO_FONT_HEIGHT, (uchar *)info); + } +#endif + + if (state && (last_state != state)) { + video_set_cursor (); + } + + if (!state && (last_state != state)) { + /* clear cursor */ + video_putchar (console_col * VIDEO_FONT_WIDTH, + console_row * VIDEO_FONT_HEIGHT, + ' '); + } + + last_state = state; +} +#endif + +/*****************************************************************************/ + +#ifndef VIDEO_HW_RECTFILL +static void memsetl (int *p, int c, int v) +{ + while (c--) + *(p++) = v; +} +#endif + +/*****************************************************************************/ + +#ifndef VIDEO_HW_BITBLT +static void memcpyl (int *d, int *s, int c) +{ + while (c--) + *(d++) = *(s++); +} +#endif + +/*****************************************************************************/ + +static void console_scrollup (void) +{ + /* copy up rows ignoring the first one */ + +#ifdef VIDEO_HW_BITBLT + video_hw_bitblt (VIDEO_PIXEL_SIZE, /* bytes per pixel */ + 0, /* source pos x */ + VIDEO_LOGO_HEIGHT + VIDEO_FONT_HEIGHT, /* source pos y */ + 0, /* dest pos x */ + VIDEO_LOGO_HEIGHT, /* dest pos y */ + VIDEO_VISIBLE_COLS, /* frame width */ + VIDEO_VISIBLE_ROWS - VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT /* frame height */ + ); +#else + memcpyl (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, + CONSOLE_SCROLL_SIZE >> 2); +#endif + + /* clear the last one */ +#ifdef VIDEO_HW_RECTFILL + video_hw_rectfill (VIDEO_PIXEL_SIZE, /* bytes per pixel */ + 0, /* dest pos x */ + VIDEO_VISIBLE_ROWS - VIDEO_FONT_HEIGHT, /* dest pos y */ + VIDEO_VISIBLE_COLS, /* frame width */ + VIDEO_FONT_HEIGHT, /* frame height */ + CONSOLE_BG_COL /* fill color */ + ); +#else + memsetl (CONSOLE_ROW_LAST, CONSOLE_ROW_SIZE >> 2, CONSOLE_BG_COL); +#endif +} + +/*****************************************************************************/ + +static void console_back (void) +{ + CURSOR_OFF console_col--; + + if (console_col < 0) { + console_col = CONSOLE_COLS - 1; + console_row--; + if (console_row < 0) + console_row = 0; + } + video_putchar (console_col * VIDEO_FONT_WIDTH, + console_row * VIDEO_FONT_HEIGHT, + ' '); +} + +/*****************************************************************************/ + +static void console_newline (void) +{ + CURSOR_OFF console_row++; + console_col = 0; + + /* Check if we need to scroll the terminal */ + if (console_row >= CONSOLE_ROWS) { + /* Scroll everything up */ + console_scrollup (); + + /* Decrement row number */ + console_row--; + } +} + +/*****************************************************************************/ + +void video_putc (const char c) +{ + switch (c) { + case 13: /* ignore */ + break; + + case '\n': /* next line */ + console_newline (); + break; + + case 9: /* tab 8 */ + CURSOR_OFF console_col |= 0x0008; + console_col &= ~0x0007; + + if (console_col >= CONSOLE_COLS) + console_newline (); + break; + + case 8: /* backspace */ + console_back (); + break; + + default: /* draw the char */ + video_putchar (console_col * VIDEO_FONT_WIDTH, + console_row * VIDEO_FONT_HEIGHT, + c); + console_col++; + + /* check for newline */ + if (console_col >= CONSOLE_COLS) + console_newline (); + } +CURSOR_SET} + + +/*****************************************************************************/ + +void video_puts (const char *s) +{ + int count = strlen (s); + + while (count--) + video_putc (*s++); +} + +/*****************************************************************************/ + +#if defined(CONFIG_CMD_BMP) || defined(CONFIG_SPLASH_SCREEN) + +#define FILL_8BIT_332RGB(r,g,b) { \ + *fb = ((r>>5)<<5) | ((g>>5)<<2) | (b>>6); \ + fb ++; \ +} + +#define FILL_15BIT_555RGB(r,g,b) { \ + *(unsigned short *)fb = SWAP16((unsigned short)(((r>>3)<<10) | ((g>>3)<<5) | (b>>3))); \ + fb += 2; \ +} + +#define FILL_16BIT_565RGB(r,g,b) { \ + *(unsigned short *)fb = SWAP16((unsigned short)((((r)>>3)<<11) | (((g)>>2)<<5) | ((b)>>3))); \ + fb += 2; \ +} + +#define FILL_32BIT_X888RGB(r,g,b) { \ + *(unsigned long *)fb = SWAP32((unsigned long)(((r<<16) | (g<<8) | b))); \ + fb += 4; \ +} + +#ifdef VIDEO_FB_LITTLE_ENDIAN +#define FILL_24BIT_888RGB(r,g,b) { \ + fb[0] = b; \ + fb[1] = g; \ + fb[2] = r; \ + fb += 3; \ +} +#else +#define FILL_24BIT_888RGB(r,g,b) { \ + fb[0] = r; \ + fb[1] = g; \ + fb[2] = b; \ + fb += 3; \ +} +#endif + + +/* + * Display the BMP file located at address bmp_image. + * Only uncompressed + */ +int video_display_bitmap (ulong bmp_image, int x, int y) +{ + ushort xcount, ycount; + uchar *fb; + bmp_image_t *bmp = (bmp_image_t *) bmp_image; + uchar *bmap; + ushort padded_line; + unsigned long width, height, bpp; + unsigned colors; + unsigned long compression; + bmp_color_table_entry_t cte; +#ifdef CONFIG_VIDEO_BMP_GZIP + unsigned char *dst = NULL; + ulong len; +#endif + + WATCHDOG_RESET (); + + if (!((bmp->header.signature[0] == 'B') && + (bmp->header.signature[1] == 'M'))) { + +#ifdef CONFIG_VIDEO_BMP_GZIP + /* + * Could be a gzipped bmp image, try to decrompress... + */ + len = CFG_VIDEO_LOGO_MAX_SIZE; + dst = malloc(CFG_VIDEO_LOGO_MAX_SIZE); + if (dst == NULL) { + printf("Error: malloc in gunzip failed!\n"); + return(1); + } + if (gunzip(dst, CFG_VIDEO_LOGO_MAX_SIZE, (uchar *)bmp_image, &len) != 0) { + printf ("Error: no valid bmp or bmp.gz image at %lx\n", bmp_image); + free(dst); + return 1; + } + if (len == CFG_VIDEO_LOGO_MAX_SIZE) { + printf("Image could be truncated (increase CFG_VIDEO_LOGO_MAX_SIZE)!\n"); + } + + /* + * Set addr to decompressed image + */ + bmp = (bmp_image_t *)dst; + + if (!((bmp->header.signature[0] == 'B') && + (bmp->header.signature[1] == 'M'))) { + printf ("Error: no valid bmp.gz image at %lx\n", bmp_image); + return 1; + } +#else + printf ("Error: no valid bmp image at %lx\n", bmp_image); + return 1; +#endif /* CONFIG_VIDEO_BMP_GZIP */ + } + + width = le32_to_cpu (bmp->header.width); + height = le32_to_cpu (bmp->header.height); + bpp = le16_to_cpu (bmp->header.bit_count); + colors = le32_to_cpu (bmp->header.colors_used); + compression = le32_to_cpu (bmp->header.compression); + + debug ("Display-bmp: %d x %d with %d colors\n", + width, height, colors); + + if (compression != BMP_BI_RGB) { + printf ("Error: compression type %ld not supported\n", + compression); + return 1; + } + + padded_line = (((width * bpp + 7) / 8) + 3) & ~0x3; + + if ((x + width) > VIDEO_VISIBLE_COLS) + width = VIDEO_VISIBLE_COLS - x; + if ((y + height) > VIDEO_VISIBLE_ROWS) + height = VIDEO_VISIBLE_ROWS - y; + + bmap = (uchar *) bmp + le32_to_cpu (bmp->header.data_offset); + fb = (uchar *) (video_fb_address + + ((y + height - 1) * VIDEO_COLS * VIDEO_PIXEL_SIZE) + + x * VIDEO_PIXEL_SIZE); + + /* We handle only 8bpp or 24 bpp bitmap */ + switch (le16_to_cpu (bmp->header.bit_count)) { + case 8: + padded_line -= width; + if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) { + /* Copy colormap */ + for (xcount = 0; xcount < colors; ++xcount) { + cte = bmp->color_table[xcount]; + video_set_lut (xcount, cte.red, cte.green, cte.blue); + } + } + ycount = height; + switch (VIDEO_DATA_FORMAT) { + case GDF__8BIT_INDEX: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + *fb++ = *bmap++; + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF__8BIT_332RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + cte = bmp->color_table[*bmap++]; + FILL_8BIT_332RGB (cte.red, cte.green, cte.blue); + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF_15BIT_555RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + cte = bmp->color_table[*bmap++]; + FILL_15BIT_555RGB (cte.red, cte.green, cte.blue); + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF_16BIT_565RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + cte = bmp->color_table[*bmap++]; + FILL_16BIT_565RGB (cte.red, cte.green, cte.blue); + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF_32BIT_X888RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + cte = bmp->color_table[*bmap++]; + FILL_32BIT_X888RGB (cte.red, cte.green, cte.blue); + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF_24BIT_888RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + cte = bmp->color_table[*bmap++]; + FILL_24BIT_888RGB (cte.red, cte.green, cte.blue); + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + } + break; + case 24: + padded_line -= 3 * width; + ycount = height; + switch (VIDEO_DATA_FORMAT) { + case GDF__8BIT_332RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + FILL_8BIT_332RGB (bmap[2], bmap[1], bmap[0]); + bmap += 3; + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF_15BIT_555RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + FILL_15BIT_555RGB (bmap[2], bmap[1], bmap[0]); + bmap += 3; + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF_16BIT_565RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + FILL_16BIT_565RGB (bmap[2], bmap[1], bmap[0]); + bmap += 3; + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF_32BIT_X888RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + FILL_32BIT_X888RGB (bmap[2], bmap[1], bmap[0]); + bmap += 3; + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + case GDF_24BIT_888RGB: + while (ycount--) { + WATCHDOG_RESET (); + xcount = width; + while (xcount--) { + FILL_24BIT_888RGB (bmap[2], bmap[1], bmap[0]); + bmap += 3; + } + bmap += padded_line; + fb -= (VIDEO_VISIBLE_COLS + width) * VIDEO_PIXEL_SIZE; + } + break; + default: + printf ("Error: 24 bits/pixel bitmap incompatible with current video mode\n"); + break; + } + break; + default: + printf ("Error: %d bit/pixel bitmaps not supported by U-Boot\n", + le16_to_cpu (bmp->header.bit_count)); + break; + } + +#ifdef CONFIG_VIDEO_BMP_GZIP + if (dst) { + free(dst); + } +#endif + + return (0); +} +#endif + +/*****************************************************************************/ + +#ifdef CONFIG_VIDEO_LOGO +void logo_plot (void *screen, int width, int x, int y) +{ + + int xcount, i; + int skip = (width - VIDEO_LOGO_WIDTH) * VIDEO_PIXEL_SIZE; + int ycount = VIDEO_LOGO_HEIGHT; + unsigned char r, g, b, *logo_red, *logo_blue, *logo_green; + unsigned char *source; + unsigned char *dest = (unsigned char *)screen + ((y * width * VIDEO_PIXEL_SIZE) + x); + +#ifdef CONFIG_VIDEO_BMP_LOGO + source = bmp_logo_bitmap; + + /* Allocate temporary space for computing colormap */ + logo_red = malloc (BMP_LOGO_COLORS); + logo_green = malloc (BMP_LOGO_COLORS); + logo_blue = malloc (BMP_LOGO_COLORS); + /* Compute color map */ + for (i = 0; i < VIDEO_LOGO_COLORS; i++) { + logo_red[i] = (bmp_logo_palette[i] & 0x0f00) >> 4; + logo_green[i] = (bmp_logo_palette[i] & 0x00f0); + logo_blue[i] = (bmp_logo_palette[i] & 0x000f) << 4; + } +#else + source = linux_logo; + logo_red = linux_logo_red; + logo_green = linux_logo_green; + logo_blue = linux_logo_blue; +#endif + + if (VIDEO_DATA_FORMAT == GDF__8BIT_INDEX) { + for (i = 0; i < VIDEO_LOGO_COLORS; i++) { + video_set_lut (i + VIDEO_LOGO_LUT_OFFSET, + logo_red[i], logo_green[i], logo_blue[i]); + } + } + + while (ycount--) { + xcount = VIDEO_LOGO_WIDTH; + while (xcount--) { + r = logo_red[*source - VIDEO_LOGO_LUT_OFFSET]; + g = logo_green[*source - VIDEO_LOGO_LUT_OFFSET]; + b = logo_blue[*source - VIDEO_LOGO_LUT_OFFSET]; + + switch (VIDEO_DATA_FORMAT) { + case GDF__8BIT_INDEX: + *dest = *source; + break; + case GDF__8BIT_332RGB: + *dest = ((r >> 5) << 5) | ((g >> 5) << 2) | (b >> 6); + break; + case GDF_15BIT_555RGB: + *(unsigned short *) dest = + SWAP16 ((unsigned short) (((r >> 3) << 10) | ((g >> 3) << 5) | (b >> 3))); + break; + case GDF_16BIT_565RGB: + *(unsigned short *) dest = + SWAP16 ((unsigned short) (((r >> 3) << 11) | ((g >> 2) << 5) | (b >> 3))); + break; + case GDF_32BIT_X888RGB: + *(unsigned long *) dest = + SWAP32 ((unsigned long) ((r << 16) | (g << 8) | b)); + break; + case GDF_24BIT_888RGB: +#ifdef VIDEO_FB_LITTLE_ENDIAN + dest[0] = b; + dest[1] = g; + dest[2] = r; +#else + dest[0] = r; + dest[1] = g; + dest[2] = b; +#endif + break; + } + source++; + dest += VIDEO_PIXEL_SIZE; + } + dest += skip; + } +#ifdef CONFIG_VIDEO_BMP_LOGO + free (logo_red); + free (logo_green); + free (logo_blue); +#endif +} + +/*****************************************************************************/ + +static void *video_logo (void) +{ + char info[128]; + extern char version_string; + +#ifdef CONFIG_SPLASH_SCREEN + char *s; + ulong addr; + + if ((s = getenv ("splashimage")) != NULL) { + addr = simple_strtoul (s, NULL, 16); + + if (video_display_bitmap (addr, 0, 0) == 0) { + return ((void *) (video_fb_address)); + } + } +#endif /* CONFIG_SPLASH_SCREEN */ + + logo_plot (video_fb_address, VIDEO_COLS, 0, 0); + + sprintf (info, " %s", &version_string); + video_drawstring (VIDEO_INFO_X, VIDEO_INFO_Y, (uchar *)info); + +#ifdef CONFIG_CONSOLE_EXTRA_INFO + { + int i, n = ((VIDEO_LOGO_HEIGHT - VIDEO_FONT_HEIGHT) / VIDEO_FONT_HEIGHT); + + for (i = 1; i < n; i++) { + video_get_info_str (i, info); + if (*info) + video_drawstring (VIDEO_INFO_X, + VIDEO_INFO_Y + i * VIDEO_FONT_HEIGHT, + (uchar *)info); + } + } +#endif + + return (video_fb_address + VIDEO_LOGO_HEIGHT * VIDEO_LINE_LEN); +} +#endif + + +/*****************************************************************************/ + +static int video_init (void) +{ + unsigned char color8; + + if ((pGD = video_hw_init ()) == NULL) + return -1; + + video_fb_address = (void *) VIDEO_FB_ADRS; +#ifdef CONFIG_VIDEO_HW_CURSOR + video_init_hw_cursor (VIDEO_FONT_WIDTH, VIDEO_FONT_HEIGHT); +#endif + + /* Init drawing pats */ + switch (VIDEO_DATA_FORMAT) { + case GDF__8BIT_INDEX: + video_set_lut (0x01, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL); + video_set_lut (0x00, CONSOLE_BG_COL, CONSOLE_BG_COL, CONSOLE_BG_COL); + fgx = 0x01010101; + bgx = 0x00000000; + break; + case GDF__8BIT_332RGB: + color8 = ((CONSOLE_FG_COL & 0xe0) | + ((CONSOLE_FG_COL >> 3) & 0x1c) | CONSOLE_FG_COL >> 6); + fgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8; + color8 = ((CONSOLE_BG_COL & 0xe0) | + ((CONSOLE_BG_COL >> 3) & 0x1c) | CONSOLE_BG_COL >> 6); + bgx = (color8 << 24) | (color8 << 16) | (color8 << 8) | color8; + break; + case GDF_15BIT_555RGB: + fgx = (((CONSOLE_FG_COL >> 3) << 26) | + ((CONSOLE_FG_COL >> 3) << 21) | ((CONSOLE_FG_COL >> 3) << 16) | + ((CONSOLE_FG_COL >> 3) << 10) | ((CONSOLE_FG_COL >> 3) << 5) | + (CONSOLE_FG_COL >> 3)); + bgx = (((CONSOLE_BG_COL >> 3) << 26) | + ((CONSOLE_BG_COL >> 3) << 21) | ((CONSOLE_BG_COL >> 3) << 16) | + ((CONSOLE_BG_COL >> 3) << 10) | ((CONSOLE_BG_COL >> 3) << 5) | + (CONSOLE_BG_COL >> 3)); + break; + case GDF_16BIT_565RGB: + fgx = (((CONSOLE_FG_COL >> 3) << 27) | + ((CONSOLE_FG_COL >> 2) << 21) | ((CONSOLE_FG_COL >> 3) << 16) | + ((CONSOLE_FG_COL >> 3) << 11) | ((CONSOLE_FG_COL >> 2) << 5) | + (CONSOLE_FG_COL >> 3)); + bgx = (((CONSOLE_BG_COL >> 3) << 27) | + ((CONSOLE_BG_COL >> 2) << 21) | ((CONSOLE_BG_COL >> 3) << 16) | + ((CONSOLE_BG_COL >> 3) << 11) | ((CONSOLE_BG_COL >> 2) << 5) | + (CONSOLE_BG_COL >> 3)); + break; + case GDF_32BIT_X888RGB: + fgx = (CONSOLE_FG_COL << 16) | (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL; + bgx = (CONSOLE_BG_COL << 16) | (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL; + break; + case GDF_24BIT_888RGB: + fgx = (CONSOLE_FG_COL << 24) | (CONSOLE_FG_COL << 16) | + (CONSOLE_FG_COL << 8) | CONSOLE_FG_COL; + bgx = (CONSOLE_BG_COL << 24) | (CONSOLE_BG_COL << 16) | + (CONSOLE_BG_COL << 8) | CONSOLE_BG_COL; + break; + } + eorx = fgx ^ bgx; + +#ifdef CONFIG_VIDEO_LOGO + /* Plot the logo and get start point of console */ + PRINTD ("Video: Drawing the logo ...\n"); + video_console_address = video_logo (); +#else + video_console_address = video_fb_address; +#endif + + /* Initialize the console */ + console_col = 0; + console_row = 0; + + return 0; +} + + +/*****************************************************************************/ + +int drv_video_init (void) +{ + int skip_dev_init; + device_t console_dev; + + skip_dev_init = 0; + + /* Init video chip - returns with framebuffer cleared */ + if (video_init () == -1) + skip_dev_init = 1; + +#ifdef CONFIG_VGA_AS_SINGLE_DEVICE + /* Devices VGA and Keyboard will be assigned seperately */ + /* Init vga device */ + if (!skip_dev_init) { + memset (&console_dev, 0, sizeof (console_dev)); + strcpy (console_dev.name, "vga"); + console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */ + console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_SYSTEM; + console_dev.putc = video_putc; /* 'putc' function */ + console_dev.puts = video_puts; /* 'puts' function */ + console_dev.tstc = NULL; /* 'tstc' function */ + console_dev.getc = NULL; /* 'getc' function */ + + if (device_register (&console_dev) == 0) + return 1; + } +#else + PRINTD ("KBD: Keyboard init ...\n"); + if (VIDEO_KBD_INIT_FCT == -1) + skip_dev_init = 1; + + /* Init console device */ + if (!skip_dev_init) { + memset (&console_dev, 0, sizeof (console_dev)); + strcpy (console_dev.name, "vga"); + console_dev.ext = DEV_EXT_VIDEO; /* Video extensions */ + console_dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM; + console_dev.putc = video_putc; /* 'putc' function */ + console_dev.puts = video_puts; /* 'puts' function */ + console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */ + console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */ + + if (device_register (&console_dev) == 0) + return 1; + } +#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */ + /* No console dev available */ + return 0; +} +#endif /* CONFIG_CFB_CONSOLE */ diff --git a/drivers/video/ct69000.c b/drivers/video/ct69000.c new file mode 100644 index 0000000..29d82e4 --- /dev/null +++ b/drivers/video/ct69000.c @@ -0,0 +1,1286 @@ +/* ported from ctfb.c (linux kernel): + * Created in Jan - July 2000 by Thomas Höhenleitner + * + * Ported to U-Boot: + * (C) Copyright 2002 Denis Peter, MPL AG Switzerland + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include + +#ifdef CONFIG_VIDEO + +#include +#include +#include "videomodes.h" + +#ifdef CONFIG_VIDEO_CT69000 + +/* debug */ +#undef VGA_DEBUG +#undef VGA_DUMP_REG +#ifdef VGA_DEBUG +#define PRINTF(fmt,args...) printf (fmt ,##args) +#else +#define PRINTF(fmt,args...) +#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}, +#ifdef CONFIG_USE_CPCIDVI + {PCI_DEVICE_ID_CT_69030, 0x400000, 1, 4, -2, 3, 257, 100, 220}, +#endif + {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(Dmn_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; + PRINTF ("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); + PRINTF ("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 + +#ifdef CONFIG_VIDEO_HW_CURSOR +/*************************************************************** + * Set Hardware Cursor in Pixel + */ +void +video_set_hw_cursor (int x, int y) +{ + int sig_x = 0, sig_y = 0; + if (x < 0) { + x *= -1; + sig_x = 1; + } + if (y < 0) { + y *= -1; + sig_y = 1; + } + ctWrite_i (CT_XR_O, 0xa4, x & 0xff); + ctWrite_i (CT_XR_O, 0xa5, (x >> 8) & 0x7); + ctWrite_i (CT_XR_O, 0xa6, y & 0xff); + ctWrite_i (CT_XR_O, 0xa7, (y >> 8) & 0x7); +} + +/*************************************************************** + * Init Hardware Cursor. To know the size of the Cursor, + * we have to know the Font size. + */ +void +video_init_hw_cursor (int font_width, int font_height) +{ + unsigned char xr_80; + unsigned long *curs, pattern; + int i; + int cursor_start; + GraphicDevice *pGD = (GraphicDevice *) & ctfb; + + cursor_start = pGD->dprBase; + xr_80 = ctRead_i (CT_XR_O, 0x80); + /* set start address */ + ctWrite_i (CT_XR_O, 0xa2, (cursor_start >> 8) & 0xf0); + ctWrite_i (CT_XR_O, 0xa3, (cursor_start >> 16) & 0x3f); + /* set cursor shape */ + curs = (unsigned long *) cursor_start; + i = 0; + while (i < 0x400) { + curs[i++] = 0xffffffff; /* AND mask */ + curs[i++] = 0xffffffff; /* AND mask */ + curs[i++] = 0; /* XOR mask */ + curs[i++] = 0; /* XOR mask */ + /* Transparent */ + } + pattern = 0xffffffff >> font_width; + i = 0; + while (i < (font_height * 2)) { + curs[i++] = pattern; /* AND mask */ + curs[i++] = pattern; /* AND mask */ + curs[i++] = 0; /* XOR mask */ + curs[i++] = 0; /* XOR mask */ + /* Cursor Color 0 */ + } + /* set blink rate */ + ctWrite_i (CT_FP_O, 0x19, 0xf); + + /* set cursors colors */ + xr_80 = ctRead_i (CT_XR_O, 0x80); + xr_80 |= 0x1; /* alternate palette select */ + ctWrite_i (CT_XR_O, 0x80, xr_80); + video_set_lut (4, CONSOLE_FG_COL, CONSOLE_FG_COL, CONSOLE_FG_COL); + /* position 4 is color 0 cursor 0 */ + xr_80 &= 0xfe; /* normal palette select */ + ctWrite_i (CT_XR_O, 0x80, xr_80); + /* cursor enable */ + ctWrite_i (CT_XR_O, 0xa0, 0x91); + xr_80 |= 0x10; /* enable hwcursor */ + ctWrite_i (CT_XR_O, 0x80, xr_80); + video_set_hw_cursor (0, 0); +} +#endif /* CONFIG_VIDEO_HW_CURSOR */ + +/*************************************************************** + * 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}, +#ifdef CONFIG_USE_CPCIDVI + {PCI_VENDOR_ID_CT, PCI_DEVICE_ID_CT_69030}, +#endif + {} +}; + +/******************************************************************************* +* +* 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 = CFG_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; + } + PRINTF ("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 */ + +#ifdef CONFIG_USE_CPCIDVI + if (device_id == PCI_DEVICE_ID_CT_69030) { + ctWrite (CT_MSR_W_O, 0x0b); + ctWrite (0x3cd, 0x13); + ctWrite_i (CT_FP_O, 0x02, 0x00); + ctWrite_i (CT_FP_O, 0x05, 0x00); + ctWrite_i (CT_FP_O, 0x06, 0x00); + ctWrite (0x3c2, 0x0b); + ctWrite_i (CT_FP_O, 0x02, 0x10); + ctWrite_i (CT_FP_O, 0x01, 0x09); + } else { + ctWrite (CT_MSR_W_O, 0x01); + } +#else + ctWrite (CT_MSR_W_O, 0x01); +#endif + + /* 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_CT69000 */ + +#endif /* CONFIG_VIDEO */ diff --git a/drivers/video/sed13806.c b/drivers/video/sed13806.c new file mode 100644 index 0000000..6996ca8 --- /dev/null +++ b/drivers/video/sed13806.c @@ -0,0 +1,310 @@ +/* + * (C) Copyright 2002 + * Stäubli Faverges - + * Pierre AUBERT p.aubert@staubli.com + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ +/* Video support for Epson SED13806 chipset */ + +#include + +#ifdef CONFIG_VIDEO_SED13806 + +#include +#include + +#define readByte(ptrReg) \ + *(volatile unsigned char *)(sed13806.isaBase + ptrReg) + +#define writeByte(ptrReg,value) \ + *(volatile unsigned char *)(sed13806.isaBase + ptrReg) = value + +#ifdef CONFIG_TOTAL5200 +#define writeWord(ptrReg,value) \ + (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = value) +#else +#define writeWord(ptrReg,value) \ + (*(volatile unsigned short *)(sed13806.isaBase + ptrReg) = ((value >> 8 ) & 0xff) | ((value << 8) & 0xff00)) +#endif + +GraphicDevice sed13806; + +/*----------------------------------------------------------------------------- + * EpsonSetRegs -- + *----------------------------------------------------------------------------- + */ +static void EpsonSetRegs (void) +{ + /* the content of the chipset register depends on the board (clocks, ...)*/ + const S1D_REGS *preg = board_get_regs (); + while (preg -> Index) { + writeByte (preg -> Index, preg -> Value); + preg ++; + } +} + +/*----------------------------------------------------------------------------- + * video_hw_init -- + *----------------------------------------------------------------------------- + */ +void *video_hw_init (void) +{ + unsigned int *vm, i; + + memset (&sed13806, 0, sizeof (GraphicDevice)); + + /* Initialization of the access to the graphic chipset + Retreive base address of the chipset + (see board/RPXClassic/eccx.c) */ + if ((sed13806.isaBase = board_video_init ()) == 0) { + return (NULL); + } + + sed13806.frameAdrs = sed13806.isaBase + FRAME_BUFFER_OFFSET; + sed13806.winSizeX = board_get_width (); + sed13806.winSizeY = board_get_height (); + +#if defined(CONFIG_VIDEO_SED13806_8BPP) + sed13806.gdfIndex = GDF__8BIT_INDEX; + sed13806.gdfBytesPP = 1; + +#elif defined(CONFIG_VIDEO_SED13806_16BPP) + sed13806.gdfIndex = GDF_16BIT_565RGB; + sed13806.gdfBytesPP = 2; + +#else +#error Unsupported SED13806 BPP +#endif + + sed13806.memSize = sed13806.winSizeX * sed13806.winSizeY * sed13806.gdfBytesPP; + + /* Load SED registers */ + EpsonSetRegs (); + + /* (see board/RPXClassic/RPXClassic.c) */ + board_validate_screen (sed13806.isaBase); + + /* Clear video memory */ + i = sed13806.memSize/4; + vm = (unsigned int *)sed13806.frameAdrs; + while(i--) + *vm++ = 0; + + + return (&sed13806); +} +/*----------------------------------------------------------------------------- + * Epson_wait_idle -- Wait for hardware to become idle + *----------------------------------------------------------------------------- + */ +static void Epson_wait_idle (void) +{ + while (readByte (BLT_CTRL0) & 0x80); + + /* Read a word in the BitBLT memory area to shutdown the BitBLT engine */ + *(volatile unsigned short *)(sed13806.isaBase + BLT_REG); +} + +/*----------------------------------------------------------------------------- + * video_hw_bitblt -- + *----------------------------------------------------------------------------- + */ +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 */ + ) +{ + register GraphicDevice *pGD = (GraphicDevice *)&sed13806; + unsigned long srcAddr, dstAddr; + unsigned int stride = bpp * pGD -> winSizeX; + + srcAddr = (src_y * stride) + (src_x * bpp); + dstAddr = (dst_y * stride) + (dst_x * bpp); + + Epson_wait_idle (); + + writeByte(BLT_ROP,0x0C); /* source */ + writeByte(BLT_OP,0x02);/* move blit in positive direction with ROP */ + writeWord(BLT_MEM_OFF0, stride / 2); + if (pGD -> gdfIndex == GDF__8BIT_INDEX) { + writeByte(BLT_CTRL1,0x00); + } + else { + writeByte(BLT_CTRL1,0x01); + } + + writeWord(BLT_WIDTH0,(dim_x - 1)); + writeWord(BLT_HEIGHT0,(dim_y - 1)); + + /* set up blit registers */ + writeByte(BLT_SRC_ADDR0,srcAddr); + writeByte(BLT_SRC_ADDR1,srcAddr>>8); + writeByte(BLT_SRC_ADDR2,srcAddr>>16); + + writeByte(BLT_DST_ADDR0,dstAddr); + writeByte(BLT_DST_ADDR1,dstAddr>>8); + writeByte(BLT_DST_ADDR2,dstAddr>>16); + + /* Engage the blt engine */ + /* rectangular region for src and dst */ + writeByte(BLT_CTRL0,0x80); + + /* wait untill current blits finished */ + Epson_wait_idle (); +} +/*----------------------------------------------------------------------------- + * video_hw_rectfill -- + *----------------------------------------------------------------------------- + */ +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 */ + ) +{ + register GraphicDevice *pGD = (GraphicDevice *)&sed13806; + unsigned long dstAddr; + unsigned int stride = bpp * pGD -> winSizeX; + + dstAddr = (dst_y * stride) + (dst_x * bpp); + + Epson_wait_idle (); + + /* set up blit registers */ + writeByte(BLT_DST_ADDR0,dstAddr); + writeByte(BLT_DST_ADDR1,dstAddr>>8); + writeByte(BLT_DST_ADDR2,dstAddr>>16); + + writeWord(BLT_WIDTH0,(dim_x - 1)); + writeWord(BLT_HEIGHT0,(dim_y - 1)); + writeWord(BLT_FGCOLOR0,color); + + writeByte(BLT_OP,0x0C); /* solid fill */ + writeWord(BLT_MEM_OFF0,stride / 2); + + if (pGD -> gdfIndex == GDF__8BIT_INDEX) { + writeByte(BLT_CTRL1,0x00); + } + else { + writeByte(BLT_CTRL1,0x01); + } + + /* Engage the blt engine */ + /* rectangular region for src and dst */ + writeByte(BLT_CTRL0,0x80); + + /* wait untill current blits finished */ + Epson_wait_idle (); +} + +/*----------------------------------------------------------------------------- + * video_set_lut -- + *----------------------------------------------------------------------------- + */ +void video_set_lut ( + unsigned int index, /* color number */ + unsigned char r, /* red */ + unsigned char g, /* green */ + unsigned char b /* blue */ + ) +{ + writeByte(REG_LUT_ADDR, index ); + writeByte(REG_LUT_DATA, r); + writeByte(REG_LUT_DATA, g); + writeByte(REG_LUT_DATA, b); +} +#ifdef CONFIG_VIDEO_HW_CURSOR +/*----------------------------------------------------------------------------- + * video_set_hw_cursor -- + *----------------------------------------------------------------------------- + */ +void video_set_hw_cursor (int x, int y) +{ + writeByte (LCD_CURSOR_XL, (x & 0xff)); + writeByte (LCD_CURSOR_XM, (x >> 8)); + writeByte (LCD_CURSOR_YL, (y & 0xff)); + writeByte (LCD_CURSOR_YM, (y >> 8)); +} + +/*----------------------------------------------------------------------------- + * video_init_hw_cursor -- + *----------------------------------------------------------------------------- + */ +void video_init_hw_cursor (int font_width, int font_height) +{ + volatile unsigned char *ptr; + unsigned char pattern; + int i; + + + /* Init cursor content + Cursor size is 64x64 pixels + Start of the cursor memory depends on panel type (dual panel ...) */ + if ((i = readByte (LCD_CURSOR_START)) == 0) { + ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - HWCURSORSIZE); + } + else { + ptr = (unsigned char *)(sed13806.frameAdrs + DEFAULT_VIDEO_MEMORY_SIZE - (i * 8192)); + } + + /* Fill the first line and the first empty line after cursor */ + for (i = 0, pattern = 0; i < 64; i++) { + if (i < font_width) { + /* Invert background */ + pattern |= 0x3; + + } + else { + /* Background */ + pattern |= 0x2; + } + if ((i & 3) == 3) { + *ptr = pattern; + *(ptr + font_height * 16) = 0xaa; + ptr ++; + pattern = 0; + } + pattern <<= 2; + } + + /* Duplicate this line */ + for (i = 1; i < font_height; i++) { + memcpy ((void *)ptr, (void *)(ptr - 16), 16); + ptr += 16; + } + + for (; i < 64; i++) { + memcpy ((void *)(ptr + 16), (void *)ptr, 16); + ptr += 16; + } + + /* Select cursor mode */ + writeByte (LCD_CURSOR_CNTL, 1); +} +#endif +#endif diff --git a/drivers/video/sed156x.c b/drivers/video/sed156x.c new file mode 100644 index 0000000..e9d5ed4 --- /dev/null +++ b/drivers/video/sed156x.c @@ -0,0 +1,566 @@ +/* + * (C) Copyright 2003 + * + * Pantelis Antoniou + * Intracom S.A. + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +#include +#include + +#include + +#ifdef CONFIG_SED156X + +/* 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 + +#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 */ +} + +#endif /* CONFIG_SED156X */ diff --git a/drivers/video/sm501.c b/drivers/video/sm501.c new file mode 100644 index 0000000..23db02c --- /dev/null +++ b/drivers/video/sm501.c @@ -0,0 +1,150 @@ +/* + * (C) Copyright 2002 + * Stäubli Faverges - + * Pierre AUBERT p.aubert@staubli.com + * + * (C) Copyright 2005 + * Martin Krause TQ-Systems GmbH martin.krause@tqs.de + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * Basic video support for SMI SM501 "Voyager" graphic controller + */ + +#include + +#ifdef CONFIG_VIDEO_SM501 + +#include +#include + +#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; + +/*----------------------------------------------------------------------------- + * 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) { + write32 (preg->Index, preg->Value); + /* + * Insert a delay between + */ + udelay (1000); + preg ++; + } +} + +/*----------------------------------------------------------------------------- + * video_hw_init -- + *----------------------------------------------------------------------------- + */ +void *video_hw_init (void) +{ + unsigned int *vm, i; + + memset (&sm501, 0, sizeof (GraphicDevice)); + + /* + * Initialization of the access to the graphic chipset Retreive base + * address of the chipset (see board/RPXClassic/eccx.c) + */ + if ((sm501.isaBase = board_video_init ()) == 0) { + return (NULL); + } + + if ((sm501.frameAdrs = board_video_get_fb ()) == 0) { + 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); +} + +/*----------------------------------------------------------------------------- + * video_set_lut -- + *----------------------------------------------------------------------------- + */ +void video_set_lut ( + unsigned int index, /* color number */ + unsigned char r, /* red */ + unsigned char g, /* green */ + unsigned char b /* blue */ + ) +{ +} + +#endif /* CONFIG_VIDEO_SM501 */ diff --git a/drivers/video/smiLynxEM.c b/drivers/video/smiLynxEM.c new file mode 100644 index 0000000..20f9beb --- /dev/null +++ b/drivers/video/smiLynxEM.c @@ -0,0 +1,858 @@ +/* + * (C) Copyright 1997-2002 ELTEC Elektronik AG + * Frank Gottschling + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/* + * smiLynxEM.c + * + * Silicon Motion graphic interface for sm810/sm710/sm712 accelerator + * + * modification history + * -------------------- + * 04-18-2002 Rewritten for U-Boot . + * + * 18-03-2004 - Unify videomodes handling with the ct69000 + * - The video output can be set via the variable "videoout" + * in the environment. + * videoout=1 output on LCD + * videoout=2 output on CRT (default value) + * + */ + +#include + +#if defined(CONFIG_VIDEO_SMI_LYNXEM) + +#include +#include +#include "videomodes.h" +/* + * Export Graphic Device + */ +GraphicDevice smi; + +/* + * SMI 710/712 have 4MB internal RAM; SMI 810 2MB internal + 2MB external + */ +#define VIDEO_MEM_SIZE 0x400000 + + +/* + * ISA mapped regs + */ +#define SMI_INDX_C4 (pGD->isaBase + 0x03c4) /* index reg */ +#define SMI_DATA_C5 (pGD->isaBase + 0x03c5) /* data reg */ +#define SMI_INDX_D4 (pGD->isaBase + 0x03d4) /* index reg */ +#define SMI_DATA_D5 (pGD->isaBase + 0x03d5) /* data reg */ +#define SMI_ISR1 (pGD->isaBase + 0x03ca) +#define SMI_INDX_CE (pGD->isaBase + 0x03ce) /* index reg */ +#define SMI_DATA_CF (pGD->isaBase + 0x03cf) /* data reg */ +#define SMI_LOCK_REG (pGD->isaBase + 0x03c3) /* unlock/lock ext crt reg */ +#define SMI_MISC_REG (pGD->isaBase + 0x03c2) /* misc reg */ +#define SMI_LUT_MASK (pGD->isaBase + 0x03c6) /* lut mask reg */ +#define SMI_LUT_START (pGD->isaBase + 0x03c8) /* lut start index */ +#define SMI_LUT_RGB (pGD->isaBase + 0x03c9) /* lut colors auto incr.*/ +#define SMI_INDX_ATTR (pGD->isaBase + 0x03c0) /* attributes index reg */ + +/* + * Video processor control + */ +typedef struct { + unsigned int control; + unsigned int colorKey; + unsigned int colorKeyMask; + unsigned int start; + unsigned short offset; + unsigned short width; + unsigned int fifoPrio; + unsigned int fifoERL; + unsigned int YUVtoRGB; +} SmiVideoProc; + +/* + * Video window control + */ +typedef struct { + unsigned short top; + unsigned short left; + unsigned short bottom; + unsigned short right; + unsigned int srcStart; + unsigned short width; + unsigned short offset; + unsigned char hStretch; + unsigned char vStretch; +} SmiVideoWin; + +/* + * Capture port control + */ +typedef struct { + unsigned int control; + unsigned short topClip; + unsigned short leftClip; + unsigned short srcHeight; + unsigned short srcWidth; + unsigned int srcBufStart1; + unsigned int srcBufStart2; + unsigned short srcOffset; + unsigned short fifoControl; +} SmiCapturePort; + + +/* + * Register values for common video modes + */ +static char SMI_SCR[] = { + /* all modes */ + 0x10, 0xff, 0x11, 0xff, 0x12, 0xff, 0x13, 0xff, 0x15, 0x90, + 0x17, 0x20, 0x18, 0xb1, 0x19, 0x00, +}; +static char SMI_EXT_CRT[] = { + 0x31, 0x00, 0x32, 0x00, 0x33, 0x00, 0x34, 0x00, 0x35, 0x00, + 0x36, 0x00, 0x3b, 0x00, 0x3c, 0x00, 0x3d, 0x00, 0x3e, 0x00, 0x3f, 0x00, +}; +static char SMI_ATTR [] = { + 0x00, 0x00, 0x01, 0x01, 0x02, 0x02, 0x03, 0x03, 0x04, 0x04, 0x05, 0x05, + 0x06, 0x06, 0x07, 0x07, 0x08, 0x08, 0x09, 0x09, 0x0a, 0x0a, 0x0b, 0x0b, + 0x0c, 0x0c, 0x0d, 0x0d, 0x0e, 0x0e, 0x0f, 0x0f, 0x10, 0x41, 0x11, 0x00, + 0x12, 0x0f, 0x13, 0x00, 0x14, 0x00, +}; +static char SMI_GCR[18] = { + 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x40, + 0x06, 0x05, 0x07, 0x0f, 0x08, 0xff, +}; +static char SMI_SEQR[] = { + 0x00, 0x00, 0x01, 0x01, 0x02, 0x0f, 0x03, 0x03, 0x04, 0x0e, 0x00, 0x03, +}; +static char SMI_PCR [] = { + 0x20, 0x04, 0x21, 0x30, 0x22, 0x00, 0x23, 0x00, 0x24, 0x00, +}; +static char SMI_MCR[] = { + 0x60, 0x01, 0x61, 0x00, +#ifdef CONFIG_HMI1001 + 0x62, 0x74, /* Memory type is not configured by pins on HMI1001 */ +#endif +}; + +static char SMI_HCR[] = { + 0x80, 0xff, 0x81, 0x07, 0x82, 0x00, 0x83, 0xff, 0x84, 0xff, 0x88, 0x00, + 0x89, 0x02, 0x8a, 0x80, 0x8b, 0x01, 0x8c, 0xff, 0x8d, 0x00, +}; + + +/******************************************************************************* + * + * Write SMI ISA register + */ +static void smiWrite (unsigned short index, char reg, char val) +{ + register GraphicDevice *pGD = (GraphicDevice *)&smi; + + out8 ((pGD->isaBase + index), reg); + out8 ((pGD->isaBase + index + 1), val); +} + +/******************************************************************************* + * + * Write a table of SMI ISA register + */ +static void smiLoadRegs ( + unsigned int iReg, + unsigned int dReg, + char *regTab, + unsigned int tabSize + ) +{ + register GraphicDevice *pGD = (GraphicDevice *)&smi; + register int i; + + for (i=0; icprBase + 0x0004), ((pCP->topClip<<16) | pCP->leftClip)); + out32r ((pGD->cprBase + 0x0008), ((pCP->srcHeight<<16) | pCP->srcWidth)); + out32r ((pGD->cprBase + 0x000c), pCP->srcBufStart1/8); + out32r ((pGD->cprBase + 0x0010), pCP->srcBufStart2/8); + out32r ((pGD->cprBase + 0x0014), pCP->srcOffset/8); + out32r ((pGD->cprBase + 0x0018), pCP->fifoControl); + out32r ((pGD->cprBase + 0x0000), pCP->control); +} + + +/******************************************************************************* + * + * Init video processor registers + */ +static void smiInitVideoProcessor (void) +{ + SmiVideoProc smiVP = { 0x100000, 0, 0, 0, 0, 1600, 0x1200543, 4, 0xededed }; + SmiVideoWin smiVW = { 0, 0, 599, 799, 0, 1600, 0, 0, 0 }; + register GraphicDevice *pGD = (GraphicDevice *)&smi; + register SmiVideoProc *pVP = (SmiVideoProc *)&smiVP; + register SmiVideoWin *pVWin = (SmiVideoWin *)&smiVW; + + pVP->width = pGD->plnSizeX * pGD->gdfBytesPP; + pVP->control |= pGD->gdfIndex << 16; + pVWin->bottom = pGD->winSizeY - 1; + pVWin->right = pGD->winSizeX - 1; + pVWin->width = pVP->width; + + /* color key */ + out32r ((pGD->vprBase + 0x0004), pVP->colorKey); + + /* color key mask */ + out32r ((pGD->vprBase + 0x0008), pVP->colorKeyMask); + + /* data src start adrs */ + out32r ((pGD->vprBase + 0x000c), pVP->start / 8); + + /* data width and offset */ + out32r ((pGD->vprBase + 0x0010), + ((pVP->offset / 8 * pGD->gdfBytesPP) << 16) | + (pGD->plnSizeX / 8 * pGD->gdfBytesPP)); + + /* video window 1 */ + out32r ((pGD->vprBase + 0x0014), + ((pVWin->top << 16) | pVWin->left)); + + out32r ((pGD->vprBase + 0x0018), + ((pVWin->bottom << 16) | pVWin->right)); + + out32r ((pGD->vprBase + 0x001c), pVWin->srcStart / 8); + + out32r ((pGD->vprBase + 0x0020), + (((pVWin->offset / 8) << 16) | (pVWin->width / 8))); + + out32r ((pGD->vprBase + 0x0024), + (((pVWin->hStretch) << 8) | pVWin->vStretch)); + + /* video window 2 */ + out32r ((pGD->vprBase + 0x0028), + ((pVWin->top << 16) | pVWin->left)); + + out32r ((pGD->vprBase + 0x002c), + ((pVWin->bottom << 16) | pVWin->right)); + + out32r ((pGD->vprBase + 0x0030), + pVWin->srcStart / 8); + + out32r ((pGD->vprBase + 0x0034), + (((pVWin->offset / 8) << 16) | (pVWin->width / 8))); + + out32r ((pGD->vprBase + 0x0038), + (((pVWin->hStretch) << 8) | pVWin->vStretch)); + + /* fifo prio control */ + out32r ((pGD->vprBase + 0x0054), pVP->fifoPrio); + + /* fifo empty request levell */ + out32r ((pGD->vprBase + 0x0058), pVP->fifoERL); + + /* conversion constant */ + out32r ((pGD->vprBase + 0x005c), pVP->YUVtoRGB); + + /* vpr control word */ + out32r ((pGD->vprBase + 0x0000), pVP->control); +} + +/****************************************************************************** + * + * Init drawing engine registers + */ +static void smiInitDrawingEngine (void) +{ + GraphicDevice *pGD = (GraphicDevice *)&smi; + unsigned int val; + + /* don't start now */ + out32r ((pGD->dprBase + 0x000c), 0x000f0000); + + /* set rop2 to copypen */ + val = 0xffff3ff0 & in32r ((pGD->dprBase + 0x000c)); + out32r ((pGD->dprBase + 0x000c), (val | 0x8000 | 0x0c)); + + /* set clip rect */ + out32r ((pGD->dprBase + 0x002c), 0); + out32r ((pGD->dprBase + 0x0030), + ((pGD->winSizeY<<16) | pGD->winSizeX * pGD->gdfBytesPP )); + + /* src row pitch */ + val = 0xffff0000 & (in32r ((pGD->dprBase + 0x0010))); + out32r ((pGD->dprBase + 0x0010), + (val | pGD->plnSizeX * pGD->gdfBytesPP)); + + /* dst row pitch */ + val = 0x0000ffff & (in32r ((pGD->dprBase + 0x0010))); + out32r ((pGD->dprBase + 0x0010), + (((pGD->plnSizeX * pGD->gdfBytesPP)<<16) | val)); + + /* window width src/dst */ + out32r ((pGD->dprBase + 0x003c), + (((pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff)<<16) | + (pGD->plnSizeX * pGD->gdfBytesPP & 0x0fff))); + out16r ((pGD->dprBase + 0x001e), 0x0000); + + /* src base adrs */ + out32r ((pGD->dprBase + 0x0040), + (((pGD->frameAdrs/8) & 0x000fffff))); + + /* dst base adrs */ + out32r ((pGD->dprBase + 0x0044), + (((pGD->frameAdrs/8) & 0x000fffff))); + + /* foreground color */ + out32r ((pGD->dprBase + 0x0014), pGD->fg); + + /* background color */ + out32r ((pGD->dprBase + 0x0018), pGD->bg); + + /* xcolor */ + out32r ((pGD->dprBase + 0x0020), 0x00ffffff); + + /* xcolor mask */ + out32r ((pGD->dprBase + 0x0024), 0x00ffffff); + + /* bit mask */ + out32r ((pGD->dprBase + 0x0028), 0x00ffffff); + + /* load mono pattern */ + out32r ((pGD->dprBase + 0x0034), 0); + out32r ((pGD->dprBase + 0x0038), 0); +} + +static struct pci_device_id supported[] = { + { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_710 }, + { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_712 }, + { PCI_VENDOR_ID_SMI, PCI_DEVICE_ID_SMI_810 }, + { } +}; + +/*****************************************************************************/ +static void smiLoadMsr (struct ctfb_res_modes *mode) +{ + unsigned char h_synch_high, v_synch_high; + register GraphicDevice *pGD = (GraphicDevice *)&smi; + + 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 */ + out8 (SMI_MISC_REG, (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 + */ +} +/*****************************************************************************/ +static void smiLoadCrt (struct ctfb_res_modes *var, int bits_per_pixel) +{ + unsigned char cr[0x7a]; + int i; + unsigned int hd, hs, he, ht, hbs, hbe; /* Horizontal. */ + unsigned int vd, vs, ve, vt, vbs, vbe; /* vertical */ + unsigned int bpp, wd, dblscan, interlaced; + + const int LineCompare = 0x3ff; + unsigned int TextScanLines = 1; /* this is in fact a vertical zoom factor */ + register GraphicDevice *pGD = (GraphicDevice *)&smi; + + /* Horizontal */ + 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 */ + /* Blank */ + hbs = hd; + hbe = 0; /* Blank end at 0 */ + + /* Vertical */ + 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 */ + vbs = vd; + vbe = 0; + + bpp = bits_per_pixel; + dblscan = (var->vmode & FB_VMODE_DOUBLE) ? 1 : 0; + interlaced = var->vmode & FB_VMODE_INTERLACED; + + + 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; + vbs >>= 1; + ve >>= 1; + vt >>= 1; + } + + memset (cr, 0, sizeof (cr)); + cr[0x00] = ht - 5; + cr[0x01] = hd - 1; + cr[0x02] = hbs - 1; + cr[0x03] = (hbe & 0x1F); + cr[0x04] = hs; + cr[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f); + + cr[0x06] = (vt - 2) & 0xFF; + cr[0x07] = (((vt - 2) & 0x100) >> 8) + | (((vd - 1) & 0x100) >> 7) + | ((vs & 0x100) >> 6) + | (((vbs - 1) & 0x100) >> 5) + | ((LineCompare & 0x100) >> 4) + | (((vt - 2) & 0x200) >> 4) + | (((vd - 1) & 0x200) >> 3) + | ((vs & 0x200) >> 2); + + cr[0x30] = ((vt - 2) & 0x400) >> 7 + | (((vd - 1) & 0x400) >> 8) + | (((vbs - 1) & 0x400) >> 9) + | ((vs & 0x400) >> 10) + | (interlaced) ? 0x80 : 0; + + + cr[0x08] = 0x00; + cr[0x09] = (dblscan << 7) + | ((LineCompare & 0x200) >> 3) + | (((vbs - 1) & 0x200) >> 4) + | (TextScanLines - 1); + + cr[0x10] = vs & 0xff; /* VSyncPulseStart */ + cr[0x11] = (ve & 0x0f); + cr[0x12] = (vd - 1) & 0xff; /* LineCount */ + cr[0x13] = wd & 0xff; + cr[0x14] = 0x40; + cr[0x15] = (vbs - 1) & 0xff; + cr[0x16] = vbe & 0xff; + cr[0x17] = 0xe3; /* but it does not work */ + cr[0x18] = 0xff & LineCompare; + cr[0x22] = 0x00; /* todo? */ + + + /* now set the registers */ + for (i = 0; i <= 0x18; i++) { /*CR00 .. CR18 */ + smiWrite (SMI_INDX_D4, i, cr[i]); + } + i = 0x22; /*CR22 */ + smiWrite (SMI_INDX_D4, i, cr[i]); + i = 0x30; /*CR30 */ + smiWrite (SMI_INDX_D4, i, cr[i]); +} + +/*****************************************************************************/ +#define REF_FREQ 14318180 +#define PMIN 1 +#define PMAX 255 +#define QMIN 1 +#define QMAX 63 + +static unsigned int FindPQ (unsigned int freq, unsigned int *pp, unsigned int *pq) +{ + unsigned int n = QMIN, m = 0; + long long int L = 0, P = freq, Q = REF_FREQ, H = P >> 1; + long long int D = 0x7ffffffffffffffLL; + + for (n = QMIN; n <= QMAX; n++) { + m = PMIN; /* p/q ~ freq/ref -> p*ref-freq*q ~ 0 */ + L = P * n - m * Q; + while (L > 0 && m < PMAX) { + L -= REF_FREQ; /* difference is greater as 0 subtract fref */ + m++; /* and increment m */ + } + /* difference is less or equal than 0 or m > maximum */ + if (m > PMAX) + break; /* no solution: if we increase n we get the same situation */ + /* L is <= 0 now */ + if (-L > H && m > PMIN) { /* if difference > the half fref */ + L += REF_FREQ; /* 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; + *pp = m; + *pq = n; /* keep improved data */ + if (D == 0) + break; /* best result we can get */ + } + return (unsigned int) (0xffffffff & D); +} + +/*****************************************************************************/ +static void smiLoadCcr (struct ctfb_res_modes *var, unsigned short device_id) +{ + unsigned int p = 0; + unsigned int q = 0; + long long freq; + register GraphicDevice *pGD = (GraphicDevice *)&smi; + + smiWrite (SMI_INDX_C4, 0x65, 0); + smiWrite (SMI_INDX_C4, 0x66, 0); + smiWrite (SMI_INDX_C4, 0x68, 0x50); + if (device_id == PCI_DEVICE_ID_SMI_810) { + smiWrite (SMI_INDX_C4, 0x69, 0x3); + } else { + smiWrite (SMI_INDX_C4, 0x69, 0x0); + } + + /* Memory clock */ + switch (device_id) { + case PCI_DEVICE_ID_SMI_710 : + smiWrite (SMI_INDX_C4, 0x6a, 0x75); + break; + case PCI_DEVICE_ID_SMI_712 : + smiWrite (SMI_INDX_C4, 0x6a, 0x80); + break; + default : + smiWrite (SMI_INDX_C4, 0x6a, 0x53); + break; + } + smiWrite (SMI_INDX_C4, 0x6b, 0x15); + + /* VCLK */ + freq = 1000000000000LL / var -> pixclock; + + FindPQ ((unsigned int)freq, &p, &q); + + smiWrite (SMI_INDX_C4, 0x6c, p); + smiWrite (SMI_INDX_C4, 0x6d, q); + +} + +/******************************************************************************* + * + * Init video chip with common Linux graphic modes (lilo) + */ +void *video_hw_init (void) +{ + GraphicDevice *pGD = (GraphicDevice *)&smi; + unsigned short device_id; + pci_dev_t devbusfn; + int videomode; + unsigned long t1, hsynch, vsynch; + unsigned int pci_mem_base, *vm; + char *penv; + int tmp, i, bits_per_pixel; + struct ctfb_res_modes *res_mode; + struct ctfb_res_modes var_mode; + unsigned char videoout; + + /* Search for video chip */ + printf("Video: "); + + if ((devbusfn = pci_find_devices(supported, 0)) < 0) + { + printf ("Controller not found !\n"); + 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); + + tmp = 0; + + videomode = CFG_DEFAULT_VIDEO_MODE; + /* 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 0x%x ", CFG_DEFAULT_VIDEO_MODE); + 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 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 = CFG_ISA_IO; + pGD->pciBase = pci_mem_base; + pGD->dprBase = (pci_mem_base + 0x400000 + 0x8000); + pGD->vprBase = (pci_mem_base + 0x400000 + 0xc000); + pGD->cprBase = (pci_mem_base + 0x400000 + 0xe000); + pGD->frameAdrs = pci_mem_base; + pGD->memSize = VIDEO_MEM_SIZE; + + /* Set up hardware : select color mode, + set Register base to isa 3dx for 3?x regs*/ + out8 (SMI_MISC_REG, 0x01); + + /* Turn off display */ + smiWrite (SMI_INDX_C4, 0x01, 0x20); + + /* Unlock ext. crt regs */ + out8 (SMI_LOCK_REG, 0x40); + + /* Unlock crt regs 0-7 */ + smiWrite (SMI_INDX_D4, 0x11, 0x0e); + + /* Sytem Control Register */ + smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SCR, sizeof(SMI_SCR)); + + /* extented CRT Register */ + smiLoadRegs (SMI_INDX_D4, SMI_DATA_D5, SMI_EXT_CRT, sizeof(SMI_EXT_CRT)); + + /* Attributes controller registers */ + smiLoadRegs (SMI_INDX_ATTR, SMI_INDX_ATTR, SMI_ATTR, sizeof(SMI_ATTR)); + + /* Graphics Controller Register */ + smiLoadRegs (SMI_INDX_CE, SMI_DATA_CF, SMI_GCR, sizeof(SMI_GCR)); + + /* Sequencer Register */ + smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_SEQR, sizeof(SMI_SEQR)); + + /* Power Control Register */ + smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_PCR, sizeof(SMI_PCR)); + + /* Memory Control Register */ + /* Register MSR62 is a power on configurable register. We don't */ + /* modify it */ + smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_MCR, sizeof(SMI_MCR)); + + /* Set misc output register */ + smiLoadMsr (res_mode); + + /* Set CRT and Clock control registers */ + smiLoadCrt (res_mode, bits_per_pixel); + + smiLoadCcr (res_mode, device_id); + + /* Hardware Cusor Register */ + smiLoadRegs (SMI_INDX_C4, SMI_DATA_C5, SMI_HCR, sizeof(SMI_HCR)); + + /* Enable Display */ + videoout = 2; /* Default output is CRT */ + if ((penv = getenv ("videoout")) != NULL) { + /* deceide if it is a string */ + videoout = (int) simple_strtoul (penv, NULL, 16); + } + smiWrite (SMI_INDX_C4, 0x31, videoout); + + /* Video processor default setup */ + smiInitVideoProcessor (); + + /* Capture port default setup */ + smiInitCapturePort (); + + /* Drawing engine default setup */ + smiInitDrawingEngine (); + + /* Turn on display */ + smiWrite (0x3c4, 0x01, 0x01); + + /* Clear video memory */ + i = pGD->memSize/4; + vm = (unsigned int *)pGD->pciBase; + while(i--) + *vm++ = 0; + return ((void*)&smi); +} + +/******************************************************************************* + * + * 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 */ + ) +{ + register GraphicDevice *pGD = (GraphicDevice *)&smi; + register unsigned int control; + + dim_x *= bpp; + + out32r ((pGD->dprBase + 0x0014), color); + out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y)); + out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y)); + + control = 0x0000ffff & in32r ((pGD->dprBase + 0x000c)); + + control |= 0x80010000; + + out32r ((pGD->dprBase + 0x000c), control); + + /* Wait for drawing processor */ + do + { + out8 ((pGD->isaBase + 0x3c4), 0x16); + } while (in8 (pGD->isaBase + 0x3c5) & 0x08); +} + +/******************************************************************************* + * + * 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 */ + ) +{ + register GraphicDevice *pGD = (GraphicDevice *)&smi; + register unsigned int control; + + dim_x *= bpp; + + if ((src_ydprBase + 0x0000), (((src_x+dim_x-1)<<16) | (src_y+dim_y-1))); + out32r ((pGD->dprBase + 0x0004), (((dst_x+dim_x-1)<<16) | (dst_y+dim_y-1))); + control = 0x88000000; + } else { + out32r ((pGD->dprBase + 0x0000), ((src_x<<16) | src_y)); + out32r ((pGD->dprBase + 0x0004), ((dst_x<<16) | dst_y)); + control = 0x80000000; + } + + out32r ((pGD->dprBase + 0x0008), ((dim_x<<16) | dim_y)); + control |= (0x0000ffff & in32r ((pGD->dprBase + 0x000c))); + out32r ((pGD->dprBase + 0x000c), control); + + /* Wait for drawing processor */ + do + { + out8 ((pGD->isaBase + 0x3c4), 0x16); + } while (in8 (pGD->isaBase + 0x3c5) & 0x08); +} + +/******************************************************************************* + * + * 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 */ + ) +{ + register GraphicDevice *pGD = (GraphicDevice *)&smi; + + out8 (SMI_LUT_MASK, 0xff); + + out8 (SMI_LUT_START, (char)index); + + out8 (SMI_LUT_RGB, r>>2); /* red */ + udelay (10); + out8 (SMI_LUT_RGB, g>>2); /* green */ + udelay (10); + out8 (SMI_LUT_RGB, b>>2); /* blue */ + udelay (10); +} + +#endif /* CONFIG_VIDEO_SMI_LYNXEM */ diff --git a/drivers/video/videomodes.c b/drivers/video/videomodes.c new file mode 100644 index 0000000..c81e5bc --- /dev/null +++ b/drivers/video/videomodes.c @@ -0,0 +1,208 @@ +/* + * (C) Copyright 2004 + * Pierre Aubert, Staubli Faverges , + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + +/************************************************************************ + Get Parameters for the video mode: + The default video mode can be defined in CFG_DEFAULT_VIDEO_MODE. + If undefined, default video mode is set to 0x301 + Parameters can be set via the variable "videomode" in the environment. + 2 diferent ways are possible: + "videomode=301" - 301 is a hexadecimal number describing the VESA + mode. Following modes are implemented: + + 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 + --------+--------------------------------------------- + "videomode=bootargs" + - the parameters are parsed from the bootargs. + The format is "NAME:VALUE,NAME:VALUE" etc. + Ex.: + "bootargs=video=ctfb:x:800,y:600,depth:16,pclk:25000" + Parameters not included in the list will be taken from + the default mode, which is one of the following: + mode:0 640x480x24 + mode:1 800x600x16 + mode:2 1024x768x8 + mode:3 960x720x24 + mode:4 1152x864x16 + mode:5 1280x1024x8 + + if "mode" is not provided within the parameter list, + mode:0 is assumed. + Following parameters are supported: + x xres = visible resolution horizontal + y yres = visible resolution vertical + pclk pixelclocks in pico sec + le left_marging time from sync to picture in pixelclocks + ri right_marging time from picture to sync in pixelclocks + up upper_margin time from sync to picture + lo lower_margin + hs hsync_len length of horizontal sync + vs vsync_len length of vertical sync + sync see FB_SYNC_* + vmode see FB_VMODE_* + depth Color depth in bits per pixel + All other parameters in the variable bootargs are ignored. + It is also possible to set the parameters direct in the + variable "videomode", or in another variable i.e. + "myvideo" and setting the variable "videomode=myvideo".. +****************************************************************************/ + +#include +#include "videomodes.h" + +const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = { + {0x301, RES_MODE_640x480, 8}, + {0x310, RES_MODE_640x480, 15}, + {0x311, RES_MODE_640x480, 16}, + {0x312, RES_MODE_640x480, 24}, + {0x303, RES_MODE_800x600, 8}, + {0x313, RES_MODE_800x600, 15}, + {0x314, RES_MODE_800x600, 16}, + {0x315, RES_MODE_800x600, 24}, + {0x305, RES_MODE_1024x768, 8}, + {0x316, RES_MODE_1024x768, 15}, + {0x317, RES_MODE_1024x768, 16}, + {0x318, RES_MODE_1024x768, 24}, + {0x161, RES_MODE_1152x864, 8}, + {0x162, RES_MODE_1152x864, 15}, + {0x163, RES_MODE_1152x864, 16}, + {0x307, RES_MODE_1280x1024, 8}, + {0x319, RES_MODE_1280x1024, 15}, + {0x31A, RES_MODE_1280x1024, 16}, + {0x31B, RES_MODE_1280x1024, 24}, +}; +const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = { + /* x y pixclk le ri up lo hs vs s vmode */ + {640, 480, 39721, 40, 24, 32, 11, 96, 2, 0, FB_VMODE_NONINTERLACED}, + {800, 600, 27778, 64, 24, 22, 1, 72, 2, 0, FB_VMODE_NONINTERLACED}, + {1024, 768, 15384, 168, 8, 29, 3, 144, 4, 0, FB_VMODE_NONINTERLACED}, + {960, 720, 13100, 160, 40, 32, 8, 80, 4, 0, FB_VMODE_NONINTERLACED}, + {1152, 864, 12004, 200, 64, 32, 16, 80, 4, 0, FB_VMODE_NONINTERLACED}, + {1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 0, FB_VMODE_NONINTERLACED}, +}; + +/************************************************************************ + * Get Parameters for the video mode: + */ +/********************************************************************* + * returns the length to the next seperator + */ +static int +video_get_param_len (char *start, char sep) +{ + int i = 0; + while ((*start != 0) && (*start != sep)) { + start++; + i++; + } + return i; +} + +static int +video_search_param (char *start, char *param) +{ + int len, totallen, i; + char *p = start; + len = strlen (param); + totallen = len + strlen (start); + for (i = 0; i < totallen; i++) { + if (strncmp (p++, param, len) == 0) + return (i); + } + return -1; +} + +/*************************************************************** + * Get parameter via the environment as it is done for the + * linux kernel i.e: + * video=ctfb:x:800,xv:1280,y:600,yv:1024,depth:16,mode:0,pclk:25000, + * le:56,ri:48,up:26,lo:5,hs:152,vs:2,sync:0,vmode:0,accel:0 + * + * penv is a pointer to the environment, containing the string, or the name of + * another environment variable. It could even be the term "bootargs" + */ + +#define GET_OPTION(name,var) \ + if(strncmp(p,name,strlen(name))==0) { \ + val_s=p+strlen(name); \ + var=simple_strtoul(val_s, NULL, 10); \ + } + +int video_get_params (struct ctfb_res_modes *pPar, char *penv) +{ + char *p, *s, *val_s; + int i = 0, t; + int bpp; + int mode; + /* first search for the environment containing the real param string */ + s = penv; + if ((p = getenv (s)) != NULL) { + s = p; + } + /* in case of the bootargs line, we have to start + * after "video=ctfb:" + */ + i = video_search_param (s, "video=ctfb:"); + if (i >= 0) { + s += i; + s += strlen ("video=ctfb:"); + } + /* search for mode as a default value */ + p = s; + t = 0; + mode = 0; /* default */ + while ((i = video_get_param_len (p, ',')) != 0) { + GET_OPTION ("mode:", mode) + p += i; + if (*p != 0) + p++; /* skip ',' */ + } + if (mode >= RES_MODES_COUNT) + mode = 0; + *pPar = res_mode_init[mode]; /* copy default values */ + bpp = 24 - ((mode % 3) * 8); + p = s; /* restart */ + while ((i = video_get_param_len (p, ',')) != 0) { + GET_OPTION ("x:", pPar->xres) + GET_OPTION ("y:", pPar->yres) + GET_OPTION ("le:", pPar->left_margin) + GET_OPTION ("ri:", pPar->right_margin) + GET_OPTION ("up:", pPar->upper_margin) + GET_OPTION ("lo:", pPar->lower_margin) + GET_OPTION ("hs:", pPar->hsync_len) + GET_OPTION ("vs:", pPar->vsync_len) + GET_OPTION ("sync:", pPar->sync) + GET_OPTION ("vmode:", pPar->vmode) + GET_OPTION ("pclk:", pPar->pixclock) + GET_OPTION ("depth:", bpp) + p += i; + if (*p != 0) + p++; /* skip ',' */ + } + return bpp; +} diff --git a/drivers/video/videomodes.h b/drivers/video/videomodes.h new file mode 100644 index 0000000..e2dffe7 --- /dev/null +++ b/drivers/video/videomodes.h @@ -0,0 +1,88 @@ +/* + * (C) Copyright 2004 + * Pierre Aubert, Staubli Faverges , + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, + * MA 02111-1307 USA + */ + + +#ifndef CFG_DEFAULT_VIDEO_MODE +#define CFG_DEFAULT_VIDEO_MODE 0x301 +#endif + +/* 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 */ + + +/****************************************************************** + * Resolution Struct + ******************************************************************/ +struct ctfb_res_modes { + int xres; /* visible resolution */ + int yres; + /* Timing: All values in pixclocks, except pixclock (of course) */ + int pixclock; /* pixel clock in ps (pico seconds) */ + int left_margin; /* time from sync to picture */ + int right_margin; /* time from picture to sync */ + int upper_margin; /* time from sync to picture */ + int lower_margin; + int hsync_len; /* length of horizontal sync */ + int vsync_len; /* length of vertical sync */ + int sync; /* see FB_SYNC_* */ + int vmode; /* see FB_VMODE_* */ +}; + +/****************************************************************** + * Vesa Mode Struct + ******************************************************************/ +struct ctfb_vesa_modes { + int vesanr; /* Vesa number as in LILO (VESA Nr + 0x200} */ + int resindex; /* index to resolution struct */ + int bits_per_pixel; /* bpp */ +}; + +#define RES_MODE_640x480 0 +#define RES_MODE_800x600 1 +#define RES_MODE_1024x768 2 +#define RES_MODE_960_720 3 +#define RES_MODE_1152x864 4 +#define RES_MODE_1280x1024 5 +#define RES_MODES_COUNT 6 + +#define VESA_MODES_COUNT 19 + +extern const struct ctfb_vesa_modes vesa_modes[]; +extern const struct ctfb_res_modes res_mode_init[]; + +int video_get_params (struct ctfb_res_modes *pPar, char *penv); diff --git a/drivers/videomodes.c b/drivers/videomodes.c deleted file mode 100644 index c81e5bc..0000000 --- a/drivers/videomodes.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * (C) Copyright 2004 - * Pierre Aubert, Staubli Faverges , - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - -/************************************************************************ - Get Parameters for the video mode: - The default video mode can be defined in CFG_DEFAULT_VIDEO_MODE. - If undefined, default video mode is set to 0x301 - Parameters can be set via the variable "videomode" in the environment. - 2 diferent ways are possible: - "videomode=301" - 301 is a hexadecimal number describing the VESA - mode. Following modes are implemented: - - 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 - --------+--------------------------------------------- - "videomode=bootargs" - - the parameters are parsed from the bootargs. - The format is "NAME:VALUE,NAME:VALUE" etc. - Ex.: - "bootargs=video=ctfb:x:800,y:600,depth:16,pclk:25000" - Parameters not included in the list will be taken from - the default mode, which is one of the following: - mode:0 640x480x24 - mode:1 800x600x16 - mode:2 1024x768x8 - mode:3 960x720x24 - mode:4 1152x864x16 - mode:5 1280x1024x8 - - if "mode" is not provided within the parameter list, - mode:0 is assumed. - Following parameters are supported: - x xres = visible resolution horizontal - y yres = visible resolution vertical - pclk pixelclocks in pico sec - le left_marging time from sync to picture in pixelclocks - ri right_marging time from picture to sync in pixelclocks - up upper_margin time from sync to picture - lo lower_margin - hs hsync_len length of horizontal sync - vs vsync_len length of vertical sync - sync see FB_SYNC_* - vmode see FB_VMODE_* - depth Color depth in bits per pixel - All other parameters in the variable bootargs are ignored. - It is also possible to set the parameters direct in the - variable "videomode", or in another variable i.e. - "myvideo" and setting the variable "videomode=myvideo".. -****************************************************************************/ - -#include -#include "videomodes.h" - -const struct ctfb_vesa_modes vesa_modes[VESA_MODES_COUNT] = { - {0x301, RES_MODE_640x480, 8}, - {0x310, RES_MODE_640x480, 15}, - {0x311, RES_MODE_640x480, 16}, - {0x312, RES_MODE_640x480, 24}, - {0x303, RES_MODE_800x600, 8}, - {0x313, RES_MODE_800x600, 15}, - {0x314, RES_MODE_800x600, 16}, - {0x315, RES_MODE_800x600, 24}, - {0x305, RES_MODE_1024x768, 8}, - {0x316, RES_MODE_1024x768, 15}, - {0x317, RES_MODE_1024x768, 16}, - {0x318, RES_MODE_1024x768, 24}, - {0x161, RES_MODE_1152x864, 8}, - {0x162, RES_MODE_1152x864, 15}, - {0x163, RES_MODE_1152x864, 16}, - {0x307, RES_MODE_1280x1024, 8}, - {0x319, RES_MODE_1280x1024, 15}, - {0x31A, RES_MODE_1280x1024, 16}, - {0x31B, RES_MODE_1280x1024, 24}, -}; -const struct ctfb_res_modes res_mode_init[RES_MODES_COUNT] = { - /* x y pixclk le ri up lo hs vs s vmode */ - {640, 480, 39721, 40, 24, 32, 11, 96, 2, 0, FB_VMODE_NONINTERLACED}, - {800, 600, 27778, 64, 24, 22, 1, 72, 2, 0, FB_VMODE_NONINTERLACED}, - {1024, 768, 15384, 168, 8, 29, 3, 144, 4, 0, FB_VMODE_NONINTERLACED}, - {960, 720, 13100, 160, 40, 32, 8, 80, 4, 0, FB_VMODE_NONINTERLACED}, - {1152, 864, 12004, 200, 64, 32, 16, 80, 4, 0, FB_VMODE_NONINTERLACED}, - {1280, 1024, 9090, 200, 48, 26, 1, 184, 3, 0, FB_VMODE_NONINTERLACED}, -}; - -/************************************************************************ - * Get Parameters for the video mode: - */ -/********************************************************************* - * returns the length to the next seperator - */ -static int -video_get_param_len (char *start, char sep) -{ - int i = 0; - while ((*start != 0) && (*start != sep)) { - start++; - i++; - } - return i; -} - -static int -video_search_param (char *start, char *param) -{ - int len, totallen, i; - char *p = start; - len = strlen (param); - totallen = len + strlen (start); - for (i = 0; i < totallen; i++) { - if (strncmp (p++, param, len) == 0) - return (i); - } - return -1; -} - -/*************************************************************** - * Get parameter via the environment as it is done for the - * linux kernel i.e: - * video=ctfb:x:800,xv:1280,y:600,yv:1024,depth:16,mode:0,pclk:25000, - * le:56,ri:48,up:26,lo:5,hs:152,vs:2,sync:0,vmode:0,accel:0 - * - * penv is a pointer to the environment, containing the string, or the name of - * another environment variable. It could even be the term "bootargs" - */ - -#define GET_OPTION(name,var) \ - if(strncmp(p,name,strlen(name))==0) { \ - val_s=p+strlen(name); \ - var=simple_strtoul(val_s, NULL, 10); \ - } - -int video_get_params (struct ctfb_res_modes *pPar, char *penv) -{ - char *p, *s, *val_s; - int i = 0, t; - int bpp; - int mode; - /* first search for the environment containing the real param string */ - s = penv; - if ((p = getenv (s)) != NULL) { - s = p; - } - /* in case of the bootargs line, we have to start - * after "video=ctfb:" - */ - i = video_search_param (s, "video=ctfb:"); - if (i >= 0) { - s += i; - s += strlen ("video=ctfb:"); - } - /* search for mode as a default value */ - p = s; - t = 0; - mode = 0; /* default */ - while ((i = video_get_param_len (p, ',')) != 0) { - GET_OPTION ("mode:", mode) - p += i; - if (*p != 0) - p++; /* skip ',' */ - } - if (mode >= RES_MODES_COUNT) - mode = 0; - *pPar = res_mode_init[mode]; /* copy default values */ - bpp = 24 - ((mode % 3) * 8); - p = s; /* restart */ - while ((i = video_get_param_len (p, ',')) != 0) { - GET_OPTION ("x:", pPar->xres) - GET_OPTION ("y:", pPar->yres) - GET_OPTION ("le:", pPar->left_margin) - GET_OPTION ("ri:", pPar->right_margin) - GET_OPTION ("up:", pPar->upper_margin) - GET_OPTION ("lo:", pPar->lower_margin) - GET_OPTION ("hs:", pPar->hsync_len) - GET_OPTION ("vs:", pPar->vsync_len) - GET_OPTION ("sync:", pPar->sync) - GET_OPTION ("vmode:", pPar->vmode) - GET_OPTION ("pclk:", pPar->pixclock) - GET_OPTION ("depth:", bpp) - p += i; - if (*p != 0) - p++; /* skip ',' */ - } - return bpp; -} diff --git a/drivers/videomodes.h b/drivers/videomodes.h deleted file mode 100644 index e2dffe7..0000000 --- a/drivers/videomodes.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * (C) Copyright 2004 - * Pierre Aubert, Staubli Faverges , - * - * See file CREDITS for list of people who contributed to this - * project. - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License as - * published by the Free Software Foundation; either version 2 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, - * MA 02111-1307 USA - */ - - -#ifndef CFG_DEFAULT_VIDEO_MODE -#define CFG_DEFAULT_VIDEO_MODE 0x301 -#endif - -/* 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 */ - - -/****************************************************************** - * Resolution Struct - ******************************************************************/ -struct ctfb_res_modes { - int xres; /* visible resolution */ - int yres; - /* Timing: All values in pixclocks, except pixclock (of course) */ - int pixclock; /* pixel clock in ps (pico seconds) */ - int left_margin; /* time from sync to picture */ - int right_margin; /* time from picture to sync */ - int upper_margin; /* time from sync to picture */ - int lower_margin; - int hsync_len; /* length of horizontal sync */ - int vsync_len; /* length of vertical sync */ - int sync; /* see FB_SYNC_* */ - int vmode; /* see FB_VMODE_* */ -}; - -/****************************************************************** - * Vesa Mode Struct - ******************************************************************/ -struct ctfb_vesa_modes { - int vesanr; /* Vesa number as in LILO (VESA Nr + 0x200} */ - int resindex; /* index to resolution struct */ - int bits_per_pixel; /* bpp */ -}; - -#define RES_MODE_640x480 0 -#define RES_MODE_800x600 1 -#define RES_MODE_1024x768 2 -#define RES_MODE_960_720 3 -#define RES_MODE_1152x864 4 -#define RES_MODE_1280x1024 5 -#define RES_MODES_COUNT 6 - -#define VESA_MODES_COUNT 19 - -extern const struct ctfb_vesa_modes vesa_modes[]; -extern const struct ctfb_res_modes res_mode_init[]; - -int video_get_params (struct ctfb_res_modes *pPar, char *penv); -- cgit v1.1